summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTavmjong Bah <tavmjong@free.fr>2017-06-05 19:32:59 +0000
committertavmjong-free <tavmjong@free.fr>2017-06-05 19:32:59 +0000
commit443ab0f809b848675fe5a74fe2290c7dc7ca16b0 (patch)
treee675cb7da3aefcf4dacfdf36edb3e8fe705097c0 /src
parent[Bug #1695016] Xaml export misses some radialGradients. (diff)
downloadinkscape-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.cpp97
-rw-r--r--src/libnrtype/font-instance.h3
-rw-r--r--src/ui/widget/font-variants.cpp34
-rw-r--r--src/ui/widget/font-variants.h1
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();