diff options
| author | Tavmjong Bah <tavmjong@free.fr> | 2017-06-05 19:32:59 +0000 |
|---|---|---|
| committer | tavmjong-free <tavmjong@free.fr> | 2017-06-05 19:32:59 +0000 |
| commit | 443ab0f809b848675fe5a74fe2290c7dc7ca16b0 (patch) | |
| tree | e675cb7da3aefcf4dacfdf36edb3e8fe705097c0 /src | |
| parent | [Bug #1695016] Xaml export misses some radialGradients. (diff) | |
| download | inkscape-443ab0f809b848675fe5a74fe2290c7dc7ca16b0.tar.gz inkscape-443ab0f809b848675fe5a74fe2290c7dc7ca16b0.zip | |
Show glyphs with alternative styles in "Feature Settings" section of "Variants" tab of "Text and Font" dialog.
(bzr r15703.1.28)
Diffstat (limited to 'src')
| -rw-r--r-- | src/libnrtype/FontFactory.cpp | 97 | ||||
| -rw-r--r-- | src/libnrtype/font-instance.h | 3 | ||||
| -rw-r--r-- | src/ui/widget/font-variants.cpp | 34 | ||||
| -rw-r--r-- | src/ui/widget/font-variants.h | 1 |
4 files changed, 126 insertions, 9 deletions
diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 770616ae7..8d66904e0 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -699,26 +699,26 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) // Empty map... bitmap fonts seem to be loaded multiple times. res->openTypeTables.clear(); - auto const hb_face = hb_ft_face_create(res->theFace, NULL); + auto const face = hb_ft_face_create(res->theFace, NULL); // First time to get size of array - auto script_count = hb_ot_layout_table_get_script_tags(hb_face, HB_OT_TAG_GSUB, 0, NULL, NULL); + auto script_count = hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, NULL, NULL); auto const scripts_hb = g_new(hb_tag_t, script_count + 1); // Second time to fill array (this two step process was not necessary with Pango). - hb_ot_layout_table_get_script_tags(hb_face, HB_OT_TAG_GSUB, 0, &script_count, scripts_hb); + hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, &script_count, scripts_hb); for(unsigned int i = 0; i < script_count; ++i) { - auto language_count = hb_ot_layout_script_get_language_tags(hb_face, HB_OT_TAG_GSUB, i, 0, NULL, NULL); + auto language_count = hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, i, 0, NULL, NULL); if(language_count > 0) { auto const languages_hb = g_new(hb_tag_t, language_count + 1); - hb_ot_layout_script_get_language_tags(hb_face, HB_OT_TAG_GSUB, i, 0, &language_count, languages_hb); + hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, i, 0, &language_count, languages_hb); for(unsigned int j = 0; j < language_count; ++j) { - auto feature_count = hb_ot_layout_language_get_feature_tags(hb_face, HB_OT_TAG_GSUB, i, j, 0, NULL, NULL); + auto feature_count = hb_ot_layout_language_get_feature_tags(face, HB_OT_TAG_GSUB, i, j, 0, NULL, NULL); auto const features_hb = g_new(hb_tag_t, feature_count + 1); - hb_ot_layout_language_get_feature_tags(hb_face, HB_OT_TAG_GSUB, i, j, 0, &feature_count, features_hb); + hb_ot_layout_language_get_feature_tags(face, HB_OT_TAG_GSUB, i, j, 0, &feature_count, features_hb); for(unsigned int k = 0; k < feature_count; ++k) { ++(res->openTypeTables[ extract_tag(&features_hb[k])]); @@ -731,11 +731,11 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) } else { // Even if no languages are present there is still the default. - auto feature_count = hb_ot_layout_language_get_feature_tags(hb_face, HB_OT_TAG_GSUB, i, + auto feature_count = hb_ot_layout_language_get_feature_tags(face, HB_OT_TAG_GSUB, i, HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, 0, NULL, NULL); auto const features_hb = g_new(hb_tag_t, feature_count + 1); - hb_ot_layout_language_get_feature_tags(hb_face, HB_OT_TAG_GSUB, i, + hb_ot_layout_language_get_feature_tags(face, HB_OT_TAG_GSUB, i, HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, 0, &feature_count, features_hb); @@ -747,6 +747,85 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) } } + // Find glyphs in OpenType substitution tables ('gsub'). + // Note that pango's functions are just dummies. Must use harfbuzz. + + // Loop over all tables + for (auto table: res->openTypeTables) { + + // 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; + + Glib::ustring unicode_characters; + + unsigned int feature_index; + if ( hb_ot_layout_language_find_feature (face, HB_OT_TAG_GSUB, + 0, // Assume one script exists with index 0 + HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, + HB_TAG(table.first[0], + table.first[1], + table.first[2], + table.first[3]), + &feature_index ) ) { + + // std::cout << " Found feature, number: " << feature_index << std::endl; + unsigned int lookup_indexes[32]; + unsigned int lookup_count = 32; + int count = hb_ot_layout_feature_get_lookups (face, HB_OT_TAG_GSUB, + feature_index, + 0, // Start + &lookup_count, + lookup_indexes ); + // std::cout << " Lookup count: " << count << " total: " << lookup_count << std::endl; + + if (count > 0) { + hb_set_t* glyphs_before = NULL; // hb_set_create(); + hb_set_t* glyphs_input = hb_set_create(); + hb_set_t* glyphs_after = NULL; // hb_set_create(); + hb_set_t* glyphs_output = NULL; // hb_set_create(); + + // For now, just look at first index + hb_ot_layout_lookup_collect_glyphs (face, HB_OT_TAG_GSUB, + lookup_indexes[0], + glyphs_before, + glyphs_input, + glyphs_after, + glyphs_output ); + + hb_font_t *font = hb_font_create (face); + + // Without this, all functions return 0, etc. + hb_ft_font_set_funcs (font); + + 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 (font, unicode_i, &glyph); + if ( glyph == codepoint) { + unicode_characters += (gunichar)unicode_i; + continue; + } + } + } + res->openTypeSubstitutions[table.first] = unicode_characters; + + hb_set_destroy (glyphs_input); + hb_font_destroy (font); + } + } else { + // std::cout << " Did not find '" << table.first << "'!" << std::endl; + } + } + } + // for (auto table: res->openTypeSubstitutions) { + // std::cout << table.first << ": " << table.second << std::endl; + // } + hb_face_destroy (face); g_free(scripts_hb); } else { // already here diff --git a/src/libnrtype/font-instance.h b/src/libnrtype/font-instance.h index 2fac7c19b..52c921403 100644 --- a/src/libnrtype/font-instance.h +++ b/src/libnrtype/font-instance.h @@ -39,6 +39,9 @@ public: // Map of OpenType tables found in font (convert to std::set?) std::map<Glib::ustring, int> openTypeTables; + // Map of substitutions indexed by table + std::map<Glib::ustring, Glib::ustring> openTypeSubstitutions; + font_instance(void); virtual ~font_instance(void); diff --git a/src/ui/widget/font-variants.cpp b/src/ui/widget/font-variants.cpp index 6753bbc7a..e7645b620 100644 --- a/src/ui/widget/font-variants.cpp +++ b/src/ui/widget/font-variants.cpp @@ -234,10 +234,14 @@ namespace Widget { _feature_list.set_justify( Gtk::JUSTIFY_LEFT ); _feature_list.set_line_wrap( true ); + _feature_substitutions.set_justify( Gtk::JUSTIFY_LEFT ); + _feature_substitutions.set_line_wrap( true ); + // Add to frame _feature_vbox.add( _feature_entry ); _feature_vbox.add( _feature_label ); _feature_vbox.add( _feature_list ); + _feature_vbox.add( _feature_substitutions ); _feature_frame.add( _feature_vbox ); add( _feature_frame ); @@ -566,6 +570,36 @@ namespace Widget { _feature_list.set_text( ott_list.c_str() ); + // "<span foreground='darkblue'>"; + Glib::ustring markup; + + for (auto table: res->openTypeSubstitutions) { + + markup += table.first; + markup += ": "; + + markup += "<span font_family='"; + markup += sp_font_description_get_family(res->descr); + markup += "'>"; + markup += Glib::Markup::escape_text(table.second); + markup += "</span>"; + + markup += " → "; + + markup += "<span font_family='"; + markup += sp_font_description_get_family(res->descr); + markup += "'>"; + markup += "<span font_features='"; + markup += table.first; + markup += "'>"; + markup += Glib::Markup::escape_text(table.second); + markup += "</span>"; + markup += "</span>\n"; + + } + + _feature_substitutions.set_markup ( markup.c_str() ); + } else { std::cerr << "FontVariants::update(): Couldn't find font_instance for: " << font_spec << std::endl; diff --git a/src/ui/widget/font-variants.h b/src/ui/widget/font-variants.h index 507e5fb91..cf8e476a9 100644 --- a/src/ui/widget/font-variants.h +++ b/src/ui/widget/font-variants.h @@ -87,6 +87,7 @@ protected: Gtk::Entry _feature_entry; Gtk::Label _feature_label; Gtk::Label _feature_list; + Gtk::Label _feature_substitutions; private: void ligatures_init(); |
