diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/libnrtype/font-lister.cpp | 76 | ||||
| -rw-r--r-- | src/libnrtype/font-lister.h | 52 | ||||
| -rw-r--r-- | src/ui/dialog/glyphs.cpp | 15 | ||||
| -rw-r--r-- | src/ui/dialog/glyphs.h | 2 | ||||
| -rw-r--r-- | src/ui/dialog/text-edit.cpp | 103 | ||||
| -rw-r--r-- | src/ui/dialog/text-edit.h | 15 | ||||
| -rw-r--r-- | src/widgets/font-selector.cpp | 253 | ||||
| -rw-r--r-- | src/widgets/font-selector.h | 27 | ||||
| -rw-r--r-- | src/widgets/text-toolbar.cpp | 6 |
9 files changed, 256 insertions, 293 deletions
diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 5e67c5991..97d3c66d4 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -82,7 +82,6 @@ namespace Inkscape font_list_store->thaw_notify(); style_list_store = Gtk::ListStore::create (FontStyleList); - style_list_store_trial = Gtk::ListStore::create (FontStyleList); } // Example of how to use "foreach_iter" @@ -375,6 +374,24 @@ namespace Inkscape } + // Set fontspec. If check is false, best style match will not be done. + void + FontLister::set_fontspec (Glib::ustring new_fontspec, gboolean check) { + + std::pair<Glib::ustring,Glib::ustring> ui = ui_from_fontspec( new_fontspec ); + Glib::ustring new_family = ui.first; + Glib::ustring new_style = ui.second; + +#ifdef DEBUG_FONT + std::cout << "FontLister::set_fontspec: family: " << new_family + << " style:" << new_style << std::endl; +#endif + + set_font_family( new_family, false ); + set_font_style( new_style ); + } + + // TODO: use to determine font-selector best style std::pair<Glib::ustring, Glib::ustring> FontLister::new_font_family (Glib::ustring new_family, gboolean check_style ) { @@ -419,7 +436,6 @@ namespace Inkscape } // Update style list. - // TODO: create a second "temporary" style_list_store for font_selector. style_list_store->freeze_notify(); style_list_store->clear(); @@ -524,11 +540,6 @@ namespace Inkscape } - // void - // FontLister::new_font_style (Glib::ustring new_style) { - // // Is this needed? What do we do? - // } - void FontLister::set_font_style (Glib::ustring new_style) { @@ -554,27 +565,22 @@ namespace Inkscape #endif } - // For use by font-selector where we already know that the style is valid - void - FontLister::set_font (Glib::ustring new_family, Glib::ustring new_style) { - -#ifdef DEBUG_FONT - std::cout << "FonLister::set_font: " << new_family << " " << new_style << std::endl; -#endif - set_font_family( new_family, false ); - set_font_style( new_style ); - } // We do this ourselves as we can't rely on FontFactory. void - FontLister::set_css( SPCSSAttr *css ) { + FontLister::fill_css( SPCSSAttr *css, Glib::ustring fontspec ) { + + if( fontspec.empty() ) { + fontspec = current_fontspec; + } + std::pair<Glib::ustring,Glib::ustring> ui = ui_from_fontspec( fontspec ); - //std::cout << "FontLister:set_css: " << std::endl; + Glib::ustring family = ui.first; - sp_repr_css_set_property (css, "-inkscape-font-specification", current_fontspec.c_str() ); - sp_repr_css_set_property (css, "font-family", current_family.c_str() ); //Canonized w/ spaces + sp_repr_css_set_property (css, "-inkscape-font-specification", fontspec.c_str() ); + sp_repr_css_set_property (css, "font-family", family.c_str() ); //Canonized w/ spaces - PangoFontDescription *desc = pango_font_description_from_string( current_fontspec.c_str() ); + PangoFontDescription *desc = pango_font_description_from_string( fontspec.c_str() ); PangoWeight weight = pango_font_description_get_weight( desc ); switch ( weight ) { case PANGO_WEIGHT_THIN: @@ -837,6 +843,26 @@ namespace Inkscape return font_list_store->get_path( get_row_for_font ( family ) ); } + Gtk::TreeModel::Row + FontLister::get_row_for_style (Glib::ustring style) + { + Gtk::TreePath path; + + Gtk::TreeModel::iterator iter = style_list_store->get_iter( "0" ); + while( iter != style_list_store->children().end() ) { + + Gtk::TreeModel::Row row = *iter; + + if( style.compare( row[FontStyleList.styles] ) == 0 ) { + return row; + } + + ++iter; + } + + throw STYLE_NOT_FOUND; + } + /* Returns style string */ // TODO: Remove or turn into function to be used by new_font_family. Glib::ustring @@ -905,12 +931,6 @@ namespace Inkscape { return style_list_store; } - - const Glib::RefPtr<Gtk::ListStore> - FontLister::get_style_list_trial () const - { - return style_list_store_trial; - } } // Helper functions diff --git a/src/libnrtype/font-lister.h b/src/libnrtype/font-lister.h index aaa996247..5c48bf7a8 100644 --- a/src/libnrtype/font-lister.h +++ b/src/libnrtype/font-lister.h @@ -111,7 +111,6 @@ namespace Inkscape }; FontStyleListClass FontStyleList; - FontStyleListClass FontStyleListTrial; /** Returns the ListStore with the family names * @@ -128,12 +127,6 @@ namespace Inkscape const Glib::RefPtr<Gtk::ListStore> get_style_list () const; - /** Returns the ListStore with the styles - trial - * - */ - const Glib::RefPtr<Gtk::ListStore> - get_style_list_trial () const; - /** Updates font list to include fonts in document * */ @@ -173,6 +166,19 @@ namespace Inkscape std::pair<Glib::ustring, Glib::ustring> selection_update (); + /** Sets current_fontspec, etc. If check is false, won't + * try to find best style match (assumes style in fontspec + * valid for given font-family). + */ + void + set_fontspec (Glib::ustring fontspec, gboolean check=true); + + Glib::ustring + get_fontspec () + { + return current_fontspec; + } + /** Changes font-family, updating style list and attempting to find * closest style to current_style style (if check_style is true). * New font-family and style returned. @@ -215,10 +221,6 @@ namespace Inkscape return current_family_row; } - /* Not Used */ - void - new_font_style (Glib::ustring style); - /** Sets style. Does not validate style for family. */ void @@ -230,32 +232,13 @@ namespace Inkscape return current_style; } - /** Sets both family and style. Does not attempt to find - * best match for style (assume that style is already valid - * for family). - */ - void - set_font (Glib::ustring family, Glib::ustring style); - - /** Sets both family and style. Does not attempt to find - * best match for style (assume that style is already valid - * for family). - */ - void - new_font (Glib::ustring family, Glib::ustring style); - - std::pair<Glib::ustring, Glib::ustring> - get_try_font () { - return ( std::make_pair( try_family, try_style ) ); - } - Glib::ustring fontspec_from_style (SPStyle* style); /** Fill css using current_fontspec. */ void - set_css( SPCSSAttr *css ); + fill_css( SPCSSAttr *css, Glib::ustring fontspec = "" ); Gtk::TreeModel::Row get_row_for_font (Glib::ustring family); @@ -292,7 +275,6 @@ namespace Inkscape Glib::RefPtr<Gtk::ListStore> font_list_store; Glib::RefPtr<Gtk::ListStore> style_list_store; - Glib::RefPtr<Gtk::ListStore> style_list_store_trial; /** Info for currently selected font (what is shown in the UI). * May include font-family lists and fonts not on system. @@ -307,12 +289,6 @@ namespace Inkscape */ Glib::ustring current_fontspec_system; - /** Info for proposed font (what is shown in the font-selection UI). - * May include font-family lists and fonts not on system. - */ - Glib::ustring try_family; - Glib::ustring try_style; - /** If a font-family is not on system, this list of styles is used. */ GList *default_styles; diff --git a/src/ui/dialog/glyphs.cpp b/src/ui/dialog/glyphs.cpp index eec904ee4..be44794d0 100644 --- a/src/ui/dialog/glyphs.cpp +++ b/src/ui/dialog/glyphs.cpp @@ -1,6 +1,7 @@ /* Authors: * Jon A. Cruz * Abhishek Sharma + * Tavmjong Bah * * Copyright (C) 2010 Jon A. Cruz * Released under GNU GPL, read the file 'COPYING' for more information @@ -343,7 +344,8 @@ GlyphsPanel::GlyphsPanel(gchar const *prefsPath) : GtkWidget *fontsel = sp_font_selector_new(); fsel = SP_FONT_SELECTOR(fontsel); - sp_font_selector_set_font(fsel, sp_font_selector_get_font(fsel), 12.0); + sp_font_selector_set_fontspec( fsel, sp_font_selector_get_fontspec(fsel), 12.0 ); + gtk_widget_set_size_request (fontsel, 0, 150); g_signal_connect( G_OBJECT(fontsel), "font_set", G_CALLBACK(fontChangeCB), this ); @@ -520,6 +522,7 @@ void GlyphsPanel::setTargetDesktop(SPDesktop *desktop) } } +// Append selected glyphs to selected text void GlyphsPanel::insertText() { SPItem *textItem = 0; @@ -611,7 +614,7 @@ void GlyphsPanel::glyphSelectionChanged() calcCanInsert(); } -void GlyphsPanel::fontChangeCB(SPFontSelector * /*fontsel*/, font_instance * /*font*/, GlyphsPanel *self) +void GlyphsPanel::fontChangeCB(SPFontSelector * /*fontsel*/, Glib::ustring /*fontspec*/, GlyphsPanel *self) { if (self) { self->rebuild(); @@ -667,7 +670,13 @@ void GlyphsPanel::readSelection( bool updateStyle, bool /*updateContent*/ ) void GlyphsPanel::rebuild() { - font_instance *font = fsel ? sp_font_selector_get_font(fsel) : 0; + Glib::ustring fontspec = fsel ? sp_font_selector_get_fontspec(fsel) : ""; + + font_instance* font = 0; + if( !fontspec.empty() ) { + font = font_factory::Default()->FaceFromFontSpecification( fontspec.c_str() ); + } + if (font) { //double sp_font_selector_get_size (SPFontSelector *fsel); diff --git a/src/ui/dialog/glyphs.h b/src/ui/dialog/glyphs.h index 162c7b296..6571af0a4 100644 --- a/src/ui/dialog/glyphs.h +++ b/src/ui/dialog/glyphs.h @@ -54,7 +54,7 @@ private: static GlyphColumns *getColumns(); - static void fontChangeCB(SPFontSelector *fontsel, font_instance *font, GlyphsPanel *self); + static void fontChangeCB(SPFontSelector *fontsel, Glib::ustring fontspec, GlyphsPanel *self); void rebuild(); diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index 97cd28cdd..a71227861 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -8,8 +8,9 @@ * Johan Engelen <goejendaagh@zonnet.nl> * Abhishek Sharma * John Smith + * Tavmjong Bah * - * Copyright (C) 1999-2012 Authors + * Copyright (C) 1999-2013 Authors * Copyright (C) 2000-2001 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information @@ -32,6 +33,7 @@ extern "C" { #include <gtkmm/stock.h> #include <libnrtype/font-instance.h> #include <libnrtype/font-style-to-pos.h> +#include <libnrtype/font-lister.h> #include <xml/repr.h> #include "macros.h" @@ -305,18 +307,20 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ ) // FIXME: process result_family/style == QUERY_STYLE_MULTIPLE_DIFFERENT by showing "Many" in the lists - // Get a font_instance using the font-specification attribute stored in SPStyle if available - font_instance *font = font_factory::Default()->FaceFromStyle(query); + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - if (font) { + // This is done for us by text-toolbar. No need to do it twice. + // fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); + // fontlister->selection_update(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); - sp_font_selector_set_font (fsel, font, sp_style_css_size_px_to_units(query->font_size.computed, unit) ); - setPreviewText(font, phrase); - font->Unref(); - font=NULL; - } + Glib::ustring fontspec = fontlister->get_fontspec(); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); + double size = sp_style_css_size_px_to_units(query->font_size.computed, unit); + sp_font_selector_set_fontspec(fsel, fontspec, size ); + + setPreviewText (fontspec, phrase); if (query->text_anchor.computed == SP_CSS_TEXT_ANCHOR_START) { if (query->text_align.computed == SP_CSS_TEXT_ALIGN_JUSTIFY) { @@ -351,30 +355,31 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ ) blocked = false; } -void TextEdit::setPreviewText (font_instance *font, Glib::ustring phrase) + +void TextEdit::setPreviewText (Glib::ustring font_spec, Glib::ustring phrase) { - if (!font) { + if (font_spec.empty()) { return; } - char *desc = pango_font_description_to_string(font->descr); + Glib::ustring phrase_escaped = Glib::Markup::escape_text( phrase ); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); double pt_size = sp_style_css_size_units_to_px(sp_font_selector_get_size(fsel), unit) * PT_PER_PX; - gchar *const phrase_escaped = g_markup_escape_text(phrase.c_str(), -1); - // Pango font size is in 1024ths of a point - gchar *markup = g_strdup_printf("<span font=\"%s\" size=\"%d\">%s</span>", - desc, (int) (pt_size * PANGO_SCALE ), phrase_escaped); + // C++11: Glib::ustring size = std::to_string( pt_size * PANGO_SCALE ); + std::ostringstream size_st; + size_st << pt_size * PANGO_SCALE; - preview_label.set_markup(markup); + Glib::ustring markup = "<span font=\"" + font_spec + + "\" size=\"" + size_st.str() + "\">" + phrase_escaped + "</span>"; - g_free(desc); - g_free(phrase_escaped); - g_free(markup); + preview_label.set_markup(markup.c_str()); } + SPItem *TextEdit::getSelectedTextItem (void) { if (!SP_ACTIVE_DESKTOP) @@ -430,34 +435,18 @@ void TextEdit::updateObjectText ( SPItem *text ) } } -SPCSSAttr *TextEdit::getTextStyle () +SPCSSAttr *TextEdit::fillTextStyle () { SPCSSAttr *css = sp_repr_css_attr_new (); - // font - font_instance *font = sp_font_selector_get_font (fsel); - - if ( font ) { - Glib::ustring fontName = font_factory::Default()->ConstructFontSpecification(font); - sp_repr_css_set_property (css, "-inkscape-font-specification", fontName.c_str()); - - gchar c[256]; - - font->Family(c, 256); - sp_repr_css_set_property (css, "font-family", c); - - font->Attribute( "weight", c, 256); - sp_repr_css_set_property (css, "font-weight", c); + Glib::ustring fontspec = sp_font_selector_get_fontspec (fsel); - font->Attribute("style", c, 256); - sp_repr_css_set_property (css, "font-style", c); + if( !fontspec.empty() ) { - font->Attribute("stretch", c, 256); - sp_repr_css_set_property (css, "font-stretch", c); - - font->Attribute("variant", c, 256); - sp_repr_css_set_property (css, "font-variant", c); + Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance(); + fontlister->fill_css( css, fontspec ); + // TODO, possibly move this to FontLister::set_css to be shared. Inkscape::CSSOStringStream os; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); @@ -467,9 +456,6 @@ SPCSSAttr *TextEdit::getTextStyle () os << sp_font_selector_get_size (fsel) << sp_style_get_css_unit_string(unit); } sp_repr_css_set_property (css, "font-size", os.str().c_str()); - - font->Unref(); - font=NULL; } // Layout @@ -505,7 +491,7 @@ SPCSSAttr *TextEdit::getTextStyle () void TextEdit::onSetDefault() { - SPCSSAttr *css = getTextStyle (); + SPCSSAttr *css = fillTextStyle (); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); blocked = true; @@ -525,7 +511,7 @@ void TextEdit::onApply() unsigned items = 0; const GSList *item_list = sp_desktop_selection(desktop)->itemList(); - SPCSSAttr *css = getTextStyle (); + SPCSSAttr *css = fillTextStyle (); sp_desktop_set_style(desktop, css, true); for (; item_list != NULL; item_list = item_list->next) { @@ -556,6 +542,13 @@ void TextEdit::onApply() } } + // Update FontLister + Glib::ustring fontspec = sp_font_selector_get_fontspec (fsel); + if( !fontspec.empty() ) { + Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance(); + fontlister->set_fontspec( fontspec, false ); + } + // complete the transaction DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, _("Set text style")); @@ -577,11 +570,11 @@ void TextEdit::onTextChange (GtkTextBuffer *text_buffer, TextEdit *self) GtkTextIter end; gtk_text_buffer_get_bounds (text_buffer, &start, &end); gchar *str = gtk_text_buffer_get_text(text_buffer, &start, &end, TRUE); - font_instance *font = sp_font_selector_get_font(self->fsel); + Glib::ustring fontspec = sp_font_selector_get_fontspec(self->fsel); - if (font) { + if( !fontspec.empty() ) { const gchar *phrase = str && *str ? str : self->samplephrase.c_str(); - self->setPreviewText(font, phrase); + self->setPreviewText(fontspec, phrase); } else { self->preview_label.set_markup(""); } @@ -594,7 +587,7 @@ void TextEdit::onTextChange (GtkTextBuffer *text_buffer, TextEdit *self) self->setasdefault_button.set_sensitive ( true); } -void TextEdit::onFontChange(SPFontSelector * /*fontsel*/, font_instance * font, TextEdit *self) +void TextEdit::onFontChange(SPFontSelector * /*fontsel*/, gchar* fontspec, TextEdit *self) { GtkTextIter start, end; gchar *str; @@ -607,9 +600,9 @@ void TextEdit::onFontChange(SPFontSelector * /*fontsel*/, font_instance * font, gtk_text_buffer_get_bounds (self->text_buffer, &start, &end); str = gtk_text_buffer_get_text (self->text_buffer, &start, &end, TRUE); - if (font) { + if (fontspec) { const gchar *phrase = str && *str ? str : self->samplephrase.c_str(); - self->setPreviewText(font, phrase); + self->setPreviewText(fontspec, phrase); } else { self->preview_label.set_markup(""); } diff --git a/src/ui/dialog/text-edit.h b/src/ui/dialog/text-edit.h index bca6cee90..3fdeea05d 100644 --- a/src/ui/dialog/text-edit.h +++ b/src/ui/dialog/text-edit.h @@ -7,8 +7,9 @@ * Johan Engelen <goejendaagh@zonnet.nl> * John Smith * Kris De Gussem <Kris.DeGussem@gmail.com> + * Tavmjong Bah * - * Copyright (C) 1999-2012 Authors + * Copyright (C) 1999-2013 Authors * Copyright (C) 2000-2001 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information @@ -100,10 +101,10 @@ protected: * onFontChange updates the dialog UI. The subfunction setPreviewText updates the preview label. * * @param fontsel pointer to SPFontSelector (currently not used). - * @param font pointer to the font instance for the text to be previewed + * @param fontspec for the text to be previewed. * @param self pointer to the current instance of the dialog. */ - static void onFontChange (SPFontSelector *fontsel, font_instance *font, TextEdit *self); + static void onFontChange (SPFontSelector *fontsel, gchar* fontspec, TextEdit *self); /** * Get the selected text off the main canvas. @@ -118,15 +119,15 @@ protected: unsigned getSelectedTextCount (void); /** - * Helper function to create markup from a font definition and display in the preview label. + * Helper function to create markup from a fontspec and display in the preview label. * - * @param font pointer to the font instance for the text to be previewed + * @param fontspec for the text to be previewed * @param phrase text to be shown */ - void setPreviewText (font_instance *font, Glib::ustring phrase); + void setPreviewText (Glib::ustring font_spec, Glib::ustring phrase); void updateObjectText ( SPItem *text ); - SPCSSAttr *getTextStyle (); + SPCSSAttr *fillTextStyle (); /** * Helper function to style radio buttons with icons, tooltips. diff --git a/src/widgets/font-selector.cpp b/src/widgets/font-selector.cpp index 59fe25fa1..453ef683f 100644 --- a/src/widgets/font-selector.cpp +++ b/src/widgets/font-selector.cpp @@ -8,10 +8,11 @@ * Lauris Kaplinski <lauris@kaplinski.com> * bulia byak <buliabyak@users.sf.net> * Johan Engelen <j.b.c.engelen@ewi.utwente.nl> + * Tavmjong Bah <tavmjong@free.fr> * * Copyright (C) 1999-2001 Ximian, Inc. * Copyright (C) 2002 Lauris Kaplinski - * Copyright (C) -2007 Authors + * Copyright (C) -2013 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -53,7 +54,7 @@ struct SPFontSelector NRStyleList styles; gfloat fontsize; bool fontsize_dirty; - font_instance *font; + Glib::ustring *fontspec; }; @@ -61,7 +62,7 @@ struct SPFontSelectorClass { GtkHBoxClass parent_class; - void (* font_set) (SPFontSelector *fsel, font_instance *font); + void (* font_set) (SPFontSelector *fsel, gchar *fontspec); }; enum { @@ -136,6 +137,9 @@ static void sp_font_selector_set_size_tooltip(SPFontSelector *fsel) } +/* + * Create a widget with children for selecting font-family, font-style, and font-size. + */ static void sp_font_selector_init(SPFontSelector *fsel) { gtk_box_set_homogeneous(GTK_BOX(fsel), TRUE); @@ -153,8 +157,6 @@ static void sp_font_selector_init(SPFontSelector *fsel) gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN); gtk_container_add(GTK_CONTAINER(f), sw); - Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - fsel->family_treeview = gtk_tree_view_new (); GtkTreeViewColumn *column = gtk_tree_view_column_new (); GtkCellRenderer *cell = gtk_cell_renderer_text_new (); @@ -175,6 +177,7 @@ static void sp_font_selector_init(SPFontSelector *fsel) "widget \"*font_selector_family\" style \"fontfamily-separator-style\""); + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); Glib::RefPtr<Gtk::ListStore> store = fontlister->get_font_list(); gtk_tree_view_set_model (GTK_TREE_VIEW(fsel->family_treeview), GTK_TREE_MODEL (Glib::unwrap (store))); gtk_container_add(GTK_CONTAINER(sw), fsel->family_treeview); @@ -229,6 +232,7 @@ static void sp_font_selector_init(SPFontSelector *fsel) gtk_widget_show(hb); gtk_box_pack_start(GTK_BOX(vb), hb, FALSE, FALSE, 0); + // Font-size fsel->size = gtk_combo_box_text_new_with_entry (); sp_font_selector_set_size_tooltip(fsel); @@ -244,18 +248,20 @@ static void sp_font_selector_init(SPFontSelector *fsel) gtk_widget_show_all (fsel->size); + // Set default size... next two lines must match + gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(fsel->size))), "18.0"); fsel->fontsize = 18.0; fsel->fontsize_dirty = false; - fsel->font = NULL; + + fsel->fontspec = new Glib::ustring; } static void sp_font_selector_dispose(GObject *object) { SPFontSelector *fsel = SP_FONT_SELECTOR (object); - if (fsel->font) { - fsel->font->Unref(); - fsel->font = NULL; + if (fsel->fontspec) { + delete fsel->fontspec; } if (fsel->families.length > 0) { @@ -273,46 +279,62 @@ static void sp_font_selector_dispose(GObject *object) } } +// Callback when family changed, updates style list for new family. static void sp_font_selector_family_select_row(GtkTreeSelection *selection, SPFontSelector *fsel) { - GtkTreeIter iter; - GtkTreeModel *model; - GtkListStore *store; - GtkTreePath *path; - GList *list=0; + // We need our own copy of the style list store since the font-family + // may not be the same in the font-selector as stored in the font-lister + // TODO: use font-lister class for this by modifying new_font_family to accept an optional style list + // TODO: add store to SPFontSelector struct and reuse. + + // Start by getting iterator to selected font + GtkTreeModel *model; + GtkTreeIter iter; if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return; - path = gtk_tree_model_get_path (model, &iter); - gtk_tree_model_get (model, &iter, 1, &list, -1); + // Next get family name with its style list + gchar *family; + GList *list=0; + gtk_tree_model_get (model, &iter, 0, &family, 1, &list, -1); - store = gtk_list_store_new (1, G_TYPE_STRING); + // Find best style match for selected family with current style (e.g. of selected text). + Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance(); + Glib::ustring style = fontlister->get_font_style(); + Glib::ustring best = fontlister->get_best_style_match (family, style); + // Create our own store of styles for selected font-family and find index of best style match + int path_index = 0; + int index = 0; + GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING); // Where is this deleted? for ( ; list ; list = list->next ) { gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, static_cast<char*>(list->data), -1); + gtk_list_store_set (store, &iter, 0, (char*)list->data, -1); + + if( best.compare( (char*)list->data ) == 0 ) { + path_index = index; + } + ++index; } + // Attach store to tree view. Can trigger style changed signal (but not FONT_SET): gtk_tree_view_set_model (GTK_TREE_VIEW (fsel->style_treeview), GTK_TREE_MODEL (store)); - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, 0); + + // Get path to best style + GtkTreePath *path = gtk_tree_path_new (); + gtk_tree_path_append_index (path, path_index); + + // Highlight best style. Triggers style changed signal: gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview)), path); gtk_tree_path_free (path); } +// Callback when row changed static void sp_font_selector_style_select_row (GtkTreeSelection *selection, SPFontSelector *fsel) { - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - - if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return; - - path = gtk_tree_model_get_path (model, &iter); - if (!fsel->block_emit) { sp_font_selector_emit_set (fsel); @@ -322,6 +344,7 @@ static void sp_font_selector_style_select_row (GtkTreeSelection *selection, /* * Set the default list of font sizes, scaled to the users preferred unit + * TODO: This routine occurs both here and in text-toolbar. Move to font-lister? */ static void sp_font_selector_set_sizes( SPFontSelector *fsel ) { @@ -348,6 +371,7 @@ static void sp_font_selector_set_sizes( SPFontSelector *fsel ) } +// Callback when size changed static void sp_font_selector_size_changed( GtkComboBox */*cbox*/, SPFontSelector *fsel ) { char *text = NULL; @@ -381,9 +405,13 @@ static void sp_font_selector_size_changed( GtkComboBox */*cbox*/, SPFontSelector sp_font_selector_emit_set (fsel); } + +// Called from sp_font_selector_style_select_row +// Called from sp_font_selector_size_changed +// Called indirectly for sp_font_selector_family_select_row (since style changes). +// Emits FONT_SET signal (handled by TextEdit::onFontChange, GlyphsPanel::fontChangeCB). static void sp_font_selector_emit_set (SPFontSelector *fsel) { - font_instance *font; GtkTreeSelection *selection_family; GtkTreeSelection *selection_style; @@ -398,41 +426,27 @@ static void sp_font_selector_emit_set (SPFontSelector *fsel) model_family = gtk_tree_view_get_model (GTK_TREE_VIEW (fsel->family_treeview)); if (!model_family) return; - model_style = gtk_tree_view_get_model (GTK_TREE_VIEW (fsel->style_treeview)); - if (!model_style) return; + model_style = gtk_tree_view_get_model (GTK_TREE_VIEW (fsel->style_treeview)); + if (!model_style ) return; selection_family = gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->family_treeview)); - selection_style = gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview)); + selection_style = gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview )); if (!gtk_tree_selection_get_selected (selection_family, NULL, &iter_family)) return; - if (!gtk_tree_selection_get_selected (selection_style, NULL, &iter_style)) return; + if (!gtk_tree_selection_get_selected (selection_style, NULL, &iter_style )) return; gtk_tree_model_get (model_family, &iter_family, 0, &family, -1); - gtk_tree_model_get (model_style, &iter_style, 0, &style, -1); + gtk_tree_model_get (model_style, &iter_style, 0, &style, -1); if ((!family) || (!style)) return; - font = (font_factory::Default())->FaceFromUIStrings (family, style); + Glib::ustring fontspec = family; + fontspec += ", "; + fontspec += style; - // FIXME: when a text object uses non-available font, font==NULL and we can't set size - // (and the size shown in the widget is invalid). To fix, here we must always get some - // default font, exactly the same as sptext uses for on-canvas display, so that - // font!=NULL ever. - if (font != fsel->font || ( font && fsel->fontsize_dirty ) ) { - if ( font ) { - font->Ref(); - } - if ( fsel->font ) { - fsel->font->Unref(); - } - fsel->font = font; - g_signal_emit(fsel, fs_signals[FONT_SET], 0, fsel->font); - } - fsel->fontsize_dirty = false; - if (font) { - font->Unref(); - } - font = NULL; + *(fsel->fontspec) = fontspec; + + g_signal_emit(fsel, fs_signals[FONT_SET], 0, fontspec.c_str()); } GtkWidget *sp_font_selector_new() @@ -442,116 +456,53 @@ GtkWidget *sp_font_selector_new() return GTK_WIDGET(fsel); } + /* - * Returns the index of the fonts closest style match from the provided list of styles - * Used in both the Text dialog and the Text toolbar to set the style combo on selection change + * Sets the values displayed in the font-selector from a fontspec. + * It is only called from TextEdit with a new selection and from GlyphsPanel */ -unsigned int sp_font_selector_get_best_style (font_instance *font, GList *list) +void sp_font_selector_set_fontspec (SPFontSelector *fsel, Glib::ustring fontspec, double size) { - if ( !font || !list) { - return 0; - } - - font_instance *tempFont = NULL; - unsigned int currentStyleNumber = 0; - unsigned int bestStyleNumber = 0; - - Glib::ustring family = font_factory::Default()->GetUIFamilyString(font->descr); - - PangoFontDescription *incomingFont = pango_font_description_copy(font->descr); - pango_font_description_unset_fields(incomingFont, PANGO_FONT_MASK_SIZE); - - char *incomingFontString = pango_font_description_to_string(incomingFont); - - tempFont = (font_factory::Default())->FaceFromUIStrings(family.c_str(), static_cast<char*>(list->data)); - - PangoFontDescription *bestMatchForFont = NULL; - if (tempFont) { - bestMatchForFont = pango_font_description_copy(tempFont->descr); - tempFont->Unref(); - tempFont = NULL; - } - - if( bestMatchForFont != NULL ) { - pango_font_description_unset_fields(bestMatchForFont, PANGO_FONT_MASK_SIZE); - } - - list = list->next; - - while (list) { - currentStyleNumber++; - - tempFont = font_factory::Default()->FaceFromUIStrings(family.c_str(), static_cast<char*>(list->data)); - - PangoFontDescription *currentMatchForFont = NULL; - if (tempFont) { - currentMatchForFont = pango_font_description_copy(tempFont->descr); - tempFont->Unref(); - tempFont = NULL; - } - - if (currentMatchForFont) { - pango_font_description_unset_fields(currentMatchForFont, PANGO_FONT_MASK_SIZE); - - char *currentMatchString = pango_font_description_to_string(currentMatchForFont); - - if (!strcmp(incomingFontString, currentMatchString) - || pango_font_description_better_match(incomingFont, bestMatchForFont, currentMatchForFont)) { - // Found a better match for the font we are looking for - pango_font_description_free(bestMatchForFont); - bestMatchForFont = pango_font_description_copy(currentMatchForFont); - bestStyleNumber = currentStyleNumber; - } - - g_free(currentMatchString); - - pango_font_description_free(currentMatchForFont); - } - - list = list->next; - } - - if (bestMatchForFont) - pango_font_description_free(bestMatchForFont); - if (incomingFont) - pango_font_description_free(incomingFont); - g_free(incomingFontString); + if (!fontspec.empty()) + { - return bestStyleNumber; -} + Inkscape::FontLister *font_lister = Inkscape::FontLister::get_instance(); + std::pair<Glib::ustring, Glib::ustring> ui = font_lister->ui_from_fontspec( fontspec ); + Glib::ustring family = ui.first; + Glib::ustring style = ui.second; -void sp_font_selector_set_font (SPFontSelector *fsel, font_instance *font, double size) -{ - if (font) - { Gtk::TreePath path; - - Glib::ustring family = font_factory::Default()->GetUIFamilyString(font->descr); - try { - path = Inkscape::FontLister::get_instance()->get_row_for_font (family); + path = font_lister->get_row_for_font (family); } catch (...) { + g_warning( "Couldn't find row for font-family: %s", family.c_str() ); return; } + // High light selected family and scroll so it is in view. fsel->block_emit = TRUE; gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->family_treeview)), path.gobj()); gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fsel->family_treeview), path.gobj(), NULL, TRUE, 0.5, 0.5); - fsel->block_emit = FALSE; + fsel->block_emit = FALSE; // TODO: Should this be moved to the end? - GList *list = 0; - GtkTreeIter iter; - GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW(fsel->family_treeview)); - gtk_tree_model_get_iter (model, &iter, path.gobj()); - gtk_tree_model_get (model, &iter, 1, &list, -1); - unsigned int bestStyleNumber = sp_font_selector_get_best_style(font, list); + // We don't need to get best style since this is only called on a new + // selection where we already know the "best" style. + // Glib::ustring bestStyle = font_lister->get_best_style_match (family, style); + // std::cout << "Best: " << bestStyle << std::endl; + + // The "trial" style list and the regular list are the same in this case. + Gtk::TreePath path_c; + try { + path_c = font_lister->get_row_for_style( style ); + } catch (...) { + g_warning( "Couldn't find row for style: %s (%s)", style.c_str(), family.c_str() ); + return; + } + + gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview)), path_c.gobj()); + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fsel->style_treeview), path_c.gobj(), NULL, TRUE, 0.5, 0.5); - GtkTreePath *path_c = gtk_tree_path_new (); - gtk_tree_path_append_index (path_c, bestStyleNumber); - gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview)), path_c); - gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fsel->style_treeview), path_c, NULL, TRUE, 0.5, 0.5); - if (size != fsel->fontsize) { gchar s[8]; @@ -565,13 +516,9 @@ void sp_font_selector_set_font (SPFontSelector *fsel, font_instance *font, doubl } -font_instance* sp_font_selector_get_font(SPFontSelector *fsel) +Glib::ustring sp_font_selector_get_fontspec(SPFontSelector *fsel) { - if (fsel->font) { - fsel->font->Ref(); - } - - return fsel->font; + return *(fsel->fontspec); } /* diff --git a/src/widgets/font-selector.h b/src/widgets/font-selector.h index 80e8b1e4d..66715f048 100644 --- a/src/widgets/font-selector.h +++ b/src/widgets/font-selector.h @@ -7,9 +7,11 @@ * Authors: * Chris Lahey <clahey@ximian.com> * Lauris Kaplinski <lauris@kaplinski.com> + * Tavmjong Bah <tavmjong@free.fr> * * Copyright (C) 1999-2001 Ximian, Inc. * Copyright (C) 2002 Lauris Kaplinski + * Copyright (C) 1999-2013 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -22,7 +24,24 @@ struct SPFontSelector; #define SP_FONT_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_FONT_SELECTOR, SPFontSelector)) #define SP_IS_FONT_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_FONT_SELECTOR)) -class font_instance; +/* + * The routines here create and manage a font selector widget with three parts, + * one each for font-family, font-style, and font-size. + * + * It is used by the TextEdit and Glyphs panel dialogs. The FontLister class is used + * to access the list of font-families and their associated styles for fonts either + * on the system or in the document. The FontLister class is also used by the Text + * toolbar. Fonts are kept track of by their "fontspecs" which are the same as the + * strings that Pango generates. + * + * The main functions are: + * Create the font-seletor widget. + * Update the lists when a new text selection is made. + * Update the Style list when a new font-family is selected, highlighting the + * best match to the original font style (as not all fonts have the same style options). + * Emit a signal when any change is made so that the Text Preview can be updated. + * Provide the currently selected values. + */ /* SPFontSelector */ @@ -30,13 +49,11 @@ GType sp_font_selector_get_type (void); GtkWidget *sp_font_selector_new (void); -void sp_font_selector_set_font (SPFontSelector *fsel, font_instance *font, double size); +void sp_font_selector_set_fontspec (SPFontSelector *fsel, Glib::ustring fontspec, double size); +Glib::ustring sp_font_selector_get_fontspec (SPFontSelector *fsel); -font_instance *sp_font_selector_get_font (SPFontSelector *fsel); double sp_font_selector_get_size (SPFontSelector *fsel); -unsigned int sp_font_selector_get_best_style (font_instance *font, GList *list); - #endif // SP_FONT_SELECTOR_H /* diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index cc6d02ea8..ef7d31d76 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -18,8 +18,8 @@ * * Copyright (C) 2004 David Turner * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2013 authors * Copyright (C) 2001-2002 Ximian, Inc. + * Copyright (C) 1999-2013 authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -170,7 +170,7 @@ static void sp_text_fontfamily_value_changed( Ink_ComboBoxEntry_Action *act, GOb // active text set in sp_text_toolbox_selection_changed() SPCSSAttr *css = sp_repr_css_attr_new (); - fontlister->set_css( css ); + fontlister->fill_css( css ); SPDesktop *desktop = SP_ACTIVE_DESKTOP; sp_desktop_set_style (desktop, css, true, true); // Results in selection change called twice. @@ -272,7 +272,7 @@ static void sp_text_fontstyle_value_changed( Ink_ComboBoxEntry_Action *act, GObj // active text set in sp_text_toolbox_seletion_changed() SPCSSAttr *css = sp_repr_css_attr_new (); - fontlister->set_css( css ); + fontlister->fill_css( css ); SPDesktop *desktop = SP_ACTIVE_DESKTOP; sp_desktop_set_style (desktop, css, true, true); |
