summaryrefslogtreecommitdiffstats
path: root/src/widgets/font-selector.cpp
diff options
context:
space:
mode:
authorMarkus Engel <markus.engel@tum.de>2013-03-29 23:52:42 +0000
committerMarkus Engel <markus.engel@tum.de>2013-03-29 23:52:42 +0000
commita168040d5a452544328a1e6ad35aaac351f94d44 (patch)
treefae1ba829f543a473da281bd5fa6e4deabbf6912 /src/widgets/font-selector.cpp
parentRemoved function pointers from SPObject and subclasses. (diff)
parentDutch translation update (diff)
downloadinkscape-a168040d5a452544328a1e6ad35aaac351f94d44.tar.gz
inkscape-a168040d5a452544328a1e6ad35aaac351f94d44.zip
merged from trunk
(bzr r11608.1.56)
Diffstat (limited to 'src/widgets/font-selector.cpp')
-rw-r--r--src/widgets/font-selector.cpp294
1 files changed, 118 insertions, 176 deletions
diff --git a/src/widgets/font-selector.cpp b/src/widgets/font-selector.cpp
index 0244621bf..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
*/
@@ -51,11 +52,9 @@ struct SPFontSelector
NRNameList families;
NRStyleList styles;
- int familyidx;
- int styleidx;
gfloat fontsize;
bool fontsize_dirty;
- font_instance *font;
+ Glib::ustring *fontspec;
};
@@ -63,7 +62,7 @@ struct SPFontSelectorClass
{
GtkHBoxClass parent_class;
- void (* font_set) (SPFontSelector *fsel, font_instance *font);
+ void (* font_set) (SPFontSelector *fsel, gchar *fontspec);
};
enum {
@@ -113,7 +112,7 @@ GType sp_font_selector_get_type()
static void sp_font_selector_class_init(SPFontSelectorClass *c)
{
- GObjectClass *object_class = (GObjectClass *) c;
+ GObjectClass *object_class = G_OBJECT_CLASS(c);
fs_parent_class = (GtkHBoxClass* )g_type_class_peek_parent (c);
@@ -129,15 +128,18 @@ static void sp_font_selector_class_init(SPFontSelectorClass *c)
object_class->dispose = sp_font_selector_dispose;
}
-void sp_font_selector_set_size_tooltip(SPFontSelector *fsel)
+static void sp_font_selector_set_size_tooltip(SPFontSelector *fsel)
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT);
- Glib::ustring tooltip = Glib::ustring::format("Font size (", sp_style_get_css_unit_string(unit), ")");
+ Glib::ustring tooltip = Glib::ustring::format(_("Font size"), " (", sp_style_get_css_unit_string(unit), ")");
gtk_widget_set_tooltip_text (fsel->size, _(tooltip.c_str()));
}
+/*
+ * 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);
@@ -155,15 +157,27 @@ 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 ();
gtk_tree_view_column_pack_start (column, cell, FALSE);
gtk_tree_view_column_set_attributes (column, cell, "text", 0, NULL);
+ gtk_tree_view_column_set_cell_data_func (column, cell,
+ GtkTreeCellDataFunc (font_lister_cell_data_func),
+ NULL, NULL );
gtk_tree_view_append_column (GTK_TREE_VIEW(fsel->family_treeview), column);
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(fsel->family_treeview), FALSE);
+ gtk_tree_view_set_row_separator_func( GTK_TREE_VIEW(fsel->family_treeview),
+ GtkTreeViewRowSeparatorFunc ((gpointer)font_lister_separator_func),
+ NULL, NULL );
+
+ /* Muck with style, see text-toolbar.cpp */
+ gtk_widget_set_name( GTK_WIDGET(fsel->family_treeview), "font_selector_family" );
+ gtk_rc_parse_string (
+ "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);
@@ -218,16 +232,8 @@ static void sp_font_selector_init(SPFontSelector *fsel)
gtk_widget_show(hb);
gtk_box_pack_start(GTK_BOX(vb), hb, FALSE, FALSE, 0);
-/*
-This would introduce dependency on gtk version 2.24 which is currently not available in
-Trisquel GNU/Linux 4.5.1 (released on May 25th, 2011)
-This conditional and its #else block can be deleted in the future.
-*/
-#if GTK_CHECK_VERSION(2, 24,0)
+ // Font-size
fsel->size = gtk_combo_box_text_new_with_entry ();
-#else
- fsel->size = gtk_combo_box_entry_new_text ();
-#endif
sp_font_selector_set_size_tooltip(fsel);
gtk_widget_set_size_request(fsel->size, 90, -1);
@@ -242,20 +248,20 @@ This conditional and its #else block can be deleted in the future.
gtk_widget_show_all (fsel->size);
- fsel->familyidx = 0;
- fsel->styleidx = 0;
- fsel->fontsize = 10.0;
+ // 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,49 +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);
- fsel->familyidx = gtk_tree_path_get_indices (path)[0];
- fsel->styleidx = 0;
+ // 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, (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);
- fsel->styleidx = gtk_tree_path_get_indices (path)[0];
-
if (!fsel->block_emit)
{
sp_font_selector_emit_set (fsel);
@@ -325,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 )
{
@@ -346,23 +366,16 @@ static void sp_font_selector_set_sizes( SPFontSelector *fsel )
{
double size = sizes[n] / ratios[unit];
-#if GTK_CHECK_VERSION(2, 24,0)
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(fsel->size), Glib::ustring::format(size).c_str());
-#else
- gtk_combo_box_append_text (GTK_COMBO_BOX(fsel->size), size);
-#endif
}
}
+// Callback when size changed
static void sp_font_selector_size_changed( GtkComboBox */*cbox*/, SPFontSelector *fsel )
{
char *text = NULL;
-#if GTK_CHECK_VERSION(2, 24,0)
text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (fsel->size));
-#else
- text = gtk_combo_box_get_active_text (GTK_COMBO_BOX (fsel->size));
-#endif
gfloat old_size = fsel->fontsize;
gchar *endptr;
@@ -392,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;
@@ -409,154 +426,83 @@ 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()
{
- SPFontSelector *fsel = (SPFontSelector*) g_object_new(SP_TYPE_FONT_SELECTOR, NULL);
+ SPFontSelector *fsel = SP_FONT_SELECTOR(g_object_new(SP_TYPE_FONT_SELECTOR, NULL));
- return (GtkWidget *) fsel;
+ 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)
{
- 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(), (char*)list->data);
-
- PangoFontDescription *bestMatchForFont = NULL;
- if (tempFont) {
- bestMatchForFont = pango_font_description_copy(tempFont->descr);
- tempFont->Unref();
- tempFont = 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(), (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 (!fontspec.empty())
+ {
- if (bestMatchForFont)
- pango_font_description_free(bestMatchForFont);
- if (incomingFont)
- pango_font_description_free(incomingFont);
- g_free(incomingFontString);
+ 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;
- return bestStyleNumber;
-}
-
-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];
@@ -570,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);
}
/*