diff options
| author | Tavmjong Bah <tavmjong@free.fr> | 2018-04-05 13:05:17 +0000 |
|---|---|---|
| committer | Tavmjong Bah <tavmjong@free.fr> | 2018-04-05 13:05:17 +0000 |
| commit | c2fbc03b37ca44ad31db6503046a99c47a520313 (patch) | |
| tree | 67df8583465fd6ef4c5bf0abf6d02edcf7a023d1 /src | |
| parent | Reduce error messages. (diff) | |
| download | inkscape-c2fbc03b37ca44ad31db6503046a99c47a520313.tar.gz inkscape-c2fbc03b37ca44ad31db6503046a99c47a520313.zip | |
Extract and display ligatures in a font.
Diffstat (limited to 'src')
| -rw-r--r-- | src/libnrtype/FontFactory.cpp | 2 | ||||
| -rw-r--r-- | src/libnrtype/OpenTypeUtil.cpp | 71 | ||||
| -rw-r--r-- | src/libnrtype/OpenTypeUtil.h | 3 | ||||
| -rw-r--r-- | src/libnrtype/font-instance.h | 3 | ||||
| -rw-r--r-- | src/ui/widget/font-variants.cpp | 44 | ||||
| -rw-r--r-- | src/ui/widget/font-variants.h | 9 |
6 files changed, 101 insertions, 31 deletions
diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 8cccd6ff3..98c9fa69f 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -705,7 +705,7 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) #ifndef USE_PANGO_WIN32 if (res) { - readOpenTypeGsubTable( res->theFace, res->openTypeTables, res->openTypeSubstitutions ); + readOpenTypeGsubTable( res->theFace, res->openTypeTables, res->openTypeStylistic, res->openTypeLigatures ); std::map<Glib::ustring, OTVarAxis> axes; std::map<Glib::ustring, OTVarNamed> named; readOpenTypeFvarTable( res->theFace, axes, named ); diff --git a/src/libnrtype/OpenTypeUtil.cpp b/src/libnrtype/OpenTypeUtil.cpp index ba6fe8ec7..38b60c212 100644 --- a/src/libnrtype/OpenTypeUtil.cpp +++ b/src/libnrtype/OpenTypeUtil.cpp @@ -39,14 +39,17 @@ Glib::ustring extract_tag( guint32 *tag ) { } -// Make a list of all tables fount in the GSUB +// Make a list of all tables found in the GSUB // This list includes all tables regardless of script or language. void readOpenTypeGsubTable (const FT_Face ft_face, std::map<Glib::ustring, int>& tables, - std::map<Glib::ustring, Glib::ustring>& substitutions) { + std::map<Glib::ustring, Glib::ustring>& stylistic, + std::map<Glib::ustring, Glib::ustring>& ligatures + ) { tables.clear(); - substitutions.clear(); + stylistic.clear(); + ligatures.clear(); // Use Harfbuzz, Pango's equivalent calls are deprecated. auto const hb_face = hb_ft_face_create(ft_face, NULL); @@ -109,11 +112,16 @@ void readOpenTypeGsubTable (const FT_Face ft_face, for (auto table: tables) { // Only look at style substitution tables ('salt', 'ss01', etc. but not 'ssty'). - if (table.first == "salt" || - (table.first[0] == 's' && table.first[1] == 's' && !(table.first[2] == 't') ) ) { - // std::cout << " Table: " << table.first << std::endl; + bool style = table.first == "salt" || + (table.first[0] == 's' && table.first[1] == 's' && !(table.first[2] == 't')); - Glib::ustring unicode_characters; + bool ligature = ( table.first == "liga" || // Standard ligatures + table.first == "clig" || // Common ligatures + table.first == "dlig" || // Discretionary ligatures + table.first == "hlig" || // Historical ligatures + table.first == "calt" ); // Contextual alternatives + + if (style || ligature ) { unsigned int feature_index; if ( hb_ot_layout_language_find_feature (hb_face, HB_OT_TAG_GSUB, @@ -137,9 +145,9 @@ void readOpenTypeGsubTable (const FT_Face ft_face, if (count > 0) { hb_set_t* glyphs_before = NULL; // hb_set_create(); - hb_set_t* glyphs_input = hb_set_create(); + hb_set_t* glyphs_input = hb_set_create(); // For stylistic hb_set_t* glyphs_after = NULL; // hb_set_create(); - hb_set_t* glyphs_output = NULL; // hb_set_create(); + hb_set_t* glyphs_output = hb_set_create(); // For ligatures // For now, just look at first index hb_ot_layout_lookup_collect_glyphs (hb_face, HB_OT_TAG_GSUB, @@ -154,20 +162,44 @@ void readOpenTypeGsubTable (const FT_Face ft_face, // Without this, all functions return 0, etc. hb_ft_font_set_funcs (hb_font); + Glib::ustring unicode_characters; + hb_codepoint_t codepoint = -1; - while (hb_set_next (glyphs_input, &codepoint)) { - - // There is a unicode to glyph mapping function but not the inverse! - for (hb_codepoint_t unicode_i = 0; unicode_i < 0xffff; ++unicode_i) { - hb_codepoint_t glyph = 0; - hb_font_get_nominal_glyph (hb_font, unicode_i, &glyph); - if ( glyph == codepoint) { - unicode_characters += (gunichar)unicode_i; - continue; + + if (style) { + while (hb_set_next (glyphs_input, &codepoint)) { + + // There is a unicode to glyph mapping function but not the inverse! + for (hb_codepoint_t unicode_i = 0; unicode_i < 0xffff; ++unicode_i) { + hb_codepoint_t glyph = 0; + hb_font_get_nominal_glyph (hb_font, unicode_i, &glyph); + if ( glyph == codepoint) { + unicode_characters += (gunichar)unicode_i; + continue; + } + } + } + stylistic[table.first] = unicode_characters; + } + + // Don't know how to extract all input glyphs... + // glyphs_input contains last input glyph, so just use output. + if (ligature) { + while (hb_set_next (glyphs_output, &codepoint)) { + + // There is a unicode to glyph mapping function but not the inverse! + for (hb_codepoint_t unicode_i = 0; unicode_i < 0xffff; ++unicode_i) { + hb_codepoint_t glyph = 0; + hb_font_get_nominal_glyph (hb_font, unicode_i, &glyph); + if ( glyph == codepoint) { + unicode_characters += (gunichar)unicode_i; + unicode_characters += " "; // Add space + continue; + } } } + ligatures[table.first] = unicode_characters; } - substitutions[table.first] = unicode_characters; hb_set_destroy (glyphs_input); hb_font_destroy (hb_font); @@ -176,6 +208,7 @@ void readOpenTypeGsubTable (const FT_Face ft_face, // std::cout << " Did not find '" << table.first << "'!" << std::endl; } } + } // for (auto table: res->openTypeSubstitutions) { // std::cout << table.first << ": " << table.second << std::endl; diff --git a/src/libnrtype/OpenTypeUtil.h b/src/libnrtype/OpenTypeUtil.h index 5c0780492..b4f7593dd 100644 --- a/src/libnrtype/OpenTypeUtil.h +++ b/src/libnrtype/OpenTypeUtil.h @@ -50,7 +50,8 @@ inline FT_Fixed FTDoubleToFixed (double value) { void readOpenTypeGsubTable (const FT_Face ft_face, std::map<Glib::ustring, int>& tables, - std::map<Glib::ustring, Glib::ustring>& substitutions); + std::map<Glib::ustring, Glib::ustring>& stylistic, + std::map<Glib::ustring, Glib::ustring>& ligatures); void readOpenTypeFvarTable (const FT_Face ft_face, std::map<Glib::ustring, OTVarAxis>& axes, diff --git a/src/libnrtype/font-instance.h b/src/libnrtype/font-instance.h index ee23ff62d..f6408eccb 100644 --- a/src/libnrtype/font-instance.h +++ b/src/libnrtype/font-instance.h @@ -39,7 +39,8 @@ public: std::map<Glib::ustring, int> openTypeTables; // Map of substitutions indexed by table - std::map<Glib::ustring, Glib::ustring> openTypeSubstitutions; + std::map<Glib::ustring, Glib::ustring> openTypeStylistic; + std::map<Glib::ustring, Glib::ustring> openTypeLigatures; font_instance(void); virtual ~font_instance(void); diff --git a/src/ui/widget/font-variants.cpp b/src/ui/widget/font-variants.cpp index 6d072602f..ac464e1d6 100644 --- a/src/ui/widget/font-variants.cpp +++ b/src/ui/widget/font-variants.cpp @@ -2,7 +2,7 @@ * Author: * Tavmjong Bah <tavmjong@free.fr> * - * Copyright (C) 2015 Tavmong Bah + * Copyright (C) 2015, 2018 Tavmong Bah * * Released under GNU GPL. Read the file 'COPYING' for more information. */ @@ -90,11 +90,15 @@ namespace Widget { _ligatures_contextual.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::ligatures_callback) ); // Add to frame - _ligatures_vbox.pack_start( _ligatures_common ); - _ligatures_vbox.pack_start( _ligatures_discretionary ); - _ligatures_vbox.pack_start( _ligatures_historical ); - _ligatures_vbox.pack_start( _ligatures_contextual ); - _ligatures_frame.add( _ligatures_vbox ); + _ligatures_grid.attach( _ligatures_common, 0, 0, 1, 1); + _ligatures_grid.attach( _ligatures_discretionary, 0, 1, 1, 1); + _ligatures_grid.attach( _ligatures_historical, 0, 2, 1, 1); + _ligatures_grid.attach( _ligatures_contextual, 0, 3, 1, 1); + _ligatures_grid.attach( _ligatures_label_common, 1, 0, 1, 1); + _ligatures_grid.attach( _ligatures_label_discretionary, 1, 1, 1, 1); + _ligatures_grid.attach( _ligatures_label_historical, 1, 2, 1, 1); + _ligatures_grid.attach( _ligatures_label_contextual, 1, 3, 1, 1); + _ligatures_frame.add( _ligatures_grid ); pack_start( _ligatures_frame, Gtk::PACK_SHRINK ); ligatures_init(); @@ -539,6 +543,32 @@ namespace Widget { _numeric_slashed_zero.set_sensitive( false ); } + // List available ligatures + Glib::ustring markup_liga; + Glib::ustring markup_dlig; + Glib::ustring markup_hlig; + Glib::ustring markup_calt; + for (auto table: res->openTypeLigatures) { + + Glib::ustring markup; + markup += "<span font_family='"; + markup += sp_font_description_get_family(res->descr); + markup += "'>"; + markup += Glib::Markup::escape_text(table.second); + markup += "</span>"; + + if (table.first == "liga") markup_liga += markup; + if (table.first == "clig") markup_liga += markup; + if (table.first == "dlig") markup_dlig += markup; + if (table.first == "hlig") markup_hlig += markup; + if (table.first == "calt") markup_calt += markup; + } + + _ligatures_label_common.set_markup ( markup_liga.c_str() ); + _ligatures_label_discretionary.set_markup ( markup_dlig.c_str() ); + _ligatures_label_historical.set_markup ( markup_hlig.c_str() ); + _ligatures_label_contextual.set_markup ( markup_calt.c_str() ); + // Make list of tables not handled above... eventually add Gtk::Label with // this info. std::map<Glib::ustring,int> table_copy = res->openTypeTables; @@ -574,7 +604,7 @@ namespace Widget { // "<span foreground='darkblue'>"; Glib::ustring markup; - for (auto table: res->openTypeSubstitutions) { + for (auto table: res->openTypeStylistic) { markup += table.first; markup += ": "; diff --git a/src/ui/widget/font-variants.h b/src/ui/widget/font-variants.h index 96cab91b2..e7330b6cc 100644 --- a/src/ui/widget/font-variants.h +++ b/src/ui/widget/font-variants.h @@ -2,7 +2,7 @@ * Author: * Tavmjong Bah <tavmjong@free.fr> * - * Copyright (C) 2015 Tavmong Bah + * Copyright (C) 2015, 2018 Tavmong Bah * * Released under GNU GPL. Read the file 'COPYING' for more information. */ @@ -14,6 +14,7 @@ #include <gtkmm/checkbutton.h> #include <gtkmm/radiobutton.h> #include <gtkmm/entry.h> +#include <gtkmm/grid.h> class SPDesktop; class SPObject; @@ -40,11 +41,15 @@ public: protected: // To start, use four check buttons. Gtk::Expander _ligatures_frame; - Gtk::VBox _ligatures_vbox; + Gtk::Grid _ligatures_grid; Gtk::CheckButton _ligatures_common; Gtk::CheckButton _ligatures_discretionary; Gtk::CheckButton _ligatures_historical; Gtk::CheckButton _ligatures_contextual; + Gtk::Label _ligatures_label_common; + Gtk::Label _ligatures_label_discretionary; + Gtk::Label _ligatures_label_historical; + Gtk::Label _ligatures_label_contextual; // Exclusive options Gtk::Expander _position_frame; |
