summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTavmjong Bah <tavmjong@free.fr>2015-06-25 11:46:43 +0000
committertavmjong-free <tavmjong@free.fr>2015-06-25 11:46:43 +0000
commit1eaf9e7e7321f8d1ae98be9beb6afaa75a688dff (patch)
tree43e630d04a0dbf47ca718b7d72f63b9a43d8669d /src
parentXAML. Fix for bug #1457891 (FillRule property values are case sensitive). (diff)
downloadinkscape-1eaf9e7e7321f8d1ae98be9beb6afaa75a688dff.tar.gz
inkscape-1eaf9e7e7321f8d1ae98be9beb6afaa75a688dff.zip
Set sensitivty of font-variant buttons according to available OpenType tables.
(bzr r14215)
Diffstat (limited to 'src')
-rw-r--r--src/libnrtype/FontFactory.cpp88
-rw-r--r--src/libnrtype/font-instance.h5
-rw-r--r--src/ui/dialog/text-edit.cpp2
-rw-r--r--src/ui/dialog/text-edit.h2
-rw-r--r--src/ui/widget/font-variants.cpp167
-rw-r--r--src/ui/widget/font-variants.h2
6 files changed, 261 insertions, 5 deletions
diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp
index c8f5e1fef..65eb62dda 100644
--- a/src/libnrtype/FontFactory.cpp
+++ b/src/libnrtype/FontFactory.cpp
@@ -18,9 +18,11 @@
#include <glibmm/i18n.h>
#include <pango/pangoft2.h>
+#include <pango/pango-ot.h>
#include "libnrtype/FontFactory.h"
#include "libnrtype/font-instance.h"
#include "util/unordered-containers.h"
+#include <map>
typedef INK_UNORDERED_MAP<PangoFontDescription*, font_instance*, font_descr_hash, font_descr_equal> FaceMapType;
@@ -591,7 +593,23 @@ font_instance* font_factory::FaceFromFontSpecification(char const *fontSpecifica
return font;
}
+void dump_tag( guint32 *tag, Glib::ustring prefix = "" ) {
+ std::cout << prefix
+ << ((char)((*tag & 0xff000000)>>24))
+ << ((char)((*tag & 0x00ff0000)>>16))
+ << ((char)((*tag & 0x0000ff00)>>8))
+ << ((char)((*tag & 0x000000ff)>>0))
+ << std::endl;
+}
+Glib::ustring extract_tag( guint32 *tag ) {
+ Glib::ustring tag_name;
+ tag_name += ((char)((*tag & 0xff000000)>>24));
+ tag_name += ((char)((*tag & 0x00ff0000)>>16));
+ tag_name += ((char)((*tag & 0x0000ff00)>>8));
+ tag_name += ((char)((*tag & 0x000000ff)>>0));
+ return tag_name;
+}
font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail)
{
@@ -657,6 +675,76 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail)
pango_font_description_free(descr);
}
}
+
+ // Extract which OpenType tables are in the font. We'll make a list of all tables
+ // regardless of which script and langauge they are in. These functions are deprecated but
+ // will eventually be replaced by newer functions (according to Behdad).
+ PangoOTInfo* info = pango_ot_info_get( res->theFace );
+
+ PangoOTTag* scripts = pango_ot_info_list_scripts( info, PANGO_OT_TABLE_GSUB );
+ // std::cout << " scripts: " << std::endl;
+ for( unsigned i = 0; scripts[i] != 0; ++i ) {
+ // dump_tag( &scripts[i], " " );
+
+ guint script_index = -1;
+ if( pango_ot_info_find_script( info, PANGO_OT_TABLE_GSUB, scripts[i], &script_index )) {
+
+ PangoOTTag* languages =
+ pango_ot_info_list_languages( info, PANGO_OT_TABLE_GSUB, script_index, NULL);
+ // if( languages[0] != 0 )
+ // std::cout << " languages: " << std::endl;
+
+ for( unsigned j = 0; languages[j] != 0; ++j ) {
+ // dump_tag( &languages[j], " lang: ");
+
+ guint language_index = -1;
+ if( pango_ot_info_find_language(info, PANGO_OT_TABLE_GSUB, script_index, languages[j], &language_index, NULL)) {
+
+ PangoOTTag* features =
+ pango_ot_info_list_features( info, PANGO_OT_TABLE_GSUB, 0, i, j );
+ if( features[0] != 0 )
+ // std::cout << " features: " << std::endl;
+
+ for( unsigned k = 0; features[k] != 0; ++k ) {
+ // dump_tag( &features[k], " feature: ");
+ ++(res->openTypeTables[ extract_tag(&features[k])]);
+ }
+ g_free( features );
+ } else {
+ // std::cout << " No languages defined" << std::endl;
+ PangoOTTag* features =
+ pango_ot_info_list_features( info, PANGO_OT_TABLE_GSUB, 0, i, PANGO_OT_DEFAULT_LANGUAGE );
+ // if( features[0] != 0 )
+ // std::cout << " default features: " << std::endl;
+
+ for( unsigned k = 0; features[k] != 0; ++k ) {
+ // dump_tag( &features[k], " feature: " );
+ ++(res->openTypeTables[ extract_tag(&features[k])]);
+ }
+ g_free( features );
+ }
+ }
+ g_free( languages );
+ } else {
+ // std::cout << " No scripts defined! " << std::endl;
+ }
+ }
+ g_free( scripts );
+
+ PangoOTTag* features =
+ pango_ot_info_list_features( info, PANGO_OT_TABLE_GSUB, 0, 0, PANGO_OT_DEFAULT_LANGUAGE );
+ // if( features[0] != 0 )
+ // std::cout << " DFTL DFTL features: " << std::endl;
+ for( unsigned i = 0; features[i] != 0; ++i ) {
+ // dump_tag( &features[i], " feature: " );
+ ++(res->openTypeTables[ extract_tag(&features[i])]);
+ }
+ // std::map<Glib::ustring,int>::iterator it;
+ // for( it = res->openTypeTables.begin(); it != res->openTypeTables.end(); ++it) {
+ // std::cout << "Table: " << it->first << " Occurances: " << it->second << std::endl;
+ // }
+ g_free( features );
+
} else {
// already here
res = loadedFaces[descr];
diff --git a/src/libnrtype/font-instance.h b/src/libnrtype/font-instance.h
index 2c7d1ce46..5a71e353b 100644
--- a/src/libnrtype/font-instance.h
+++ b/src/libnrtype/font-instance.h
@@ -36,6 +36,9 @@ public:
int nbGlyph, maxGlyph;
font_glyph* glyphs;
+ // Map of OpenType tables found in font (convert to std::set?)
+ std::map<Glib::ustring, int> openTypeTables;
+
font_instance(void);
virtual ~font_instance(void);
@@ -68,6 +71,8 @@ public:
private:
void FreeTheFace();
+ // Temp: make public
+public:
#ifdef USE_PANGO_WIN32
HFONT theFace;
#else
diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp
index b850b2453..7575cc854 100644
--- a/src/ui/dialog/text-edit.cpp
+++ b/src/ui/dialog/text-edit.cpp
@@ -393,7 +393,7 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ )
sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTVARIANTS);
int result_features =
sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTFEATURESETTINGS);
- vari_vbox.update( &query, result_features == QUERY_STYLE_MULTIPLE_DIFFERENT );
+ vari_vbox.update( &query, result_features == QUERY_STYLE_MULTIPLE_DIFFERENT, fontspec );
}
blocked = false;
diff --git a/src/ui/dialog/text-edit.h b/src/ui/dialog/text-edit.h
index 41f89b3e7..cfe612268 100644
--- a/src/ui/dialog/text-edit.h
+++ b/src/ui/dialog/text-edit.h
@@ -36,7 +36,7 @@
class SPItem;
struct SPFontSelector;
-class FontVariants;
+//class FontVariants;
class font_instance;
class SPCSSAttr;
diff --git a/src/ui/widget/font-variants.cpp b/src/ui/widget/font-variants.cpp
index 7a1e02839..5d1e40971 100644
--- a/src/ui/widget/font-variants.cpp
+++ b/src/ui/widget/font-variants.cpp
@@ -13,7 +13,7 @@
#include <gtkmm.h>
#include <glibmm/i18n.h>
-
+#include <libnrtype/font-instance.h>
#include <iostream>
#include "font-variants.h"
@@ -315,7 +315,7 @@ namespace Widget {
// Update GUI based on query.
void
- FontVariants::update( SPStyle const *query, bool different_features ) {
+ FontVariants::update( SPStyle const *query, bool different_features, Glib::ustring& font_spec ) {
_ligatures_all = query->font_variant_ligatures.computed;
_ligatures_mix = query->font_variant_ligatures.value;
@@ -408,6 +408,169 @@ namespace Widget {
_feature_label.hide();
}
+
+ // Disable/Enable based on available OpenType tables.
+ font_instance* res = font_factory::Default()->FaceFromFontSpecification( font_spec.c_str() );
+ if( res ) {
+
+ std::map<Glib::ustring,int>::iterator it;
+
+ if((it = res->openTypeTables.find("liga"))!= res->openTypeTables.end() ||
+ (it = res->openTypeTables.find("clig"))!= res->openTypeTables.end()) {
+ _ligatures_common.set_sensitive();
+ } else {
+ _ligatures_common.set_sensitive( false );
+ }
+
+ if((it = res->openTypeTables.find("dlig"))!= res->openTypeTables.end()) {
+ _ligatures_discretionary.set_sensitive();
+ } else {
+ _ligatures_discretionary.set_sensitive( false );
+ }
+
+ if((it = res->openTypeTables.find("hlig"))!= res->openTypeTables.end()) {
+ _ligatures_historical.set_sensitive();
+ } else {
+ _ligatures_historical.set_sensitive( false );
+ }
+
+ if((it = res->openTypeTables.find("calt"))!= res->openTypeTables.end()) {
+ _ligatures_contextual.set_sensitive();
+ } else {
+ _ligatures_contextual.set_sensitive( false );
+ }
+
+ if((it = res->openTypeTables.find("subs"))!= res->openTypeTables.end()) {
+ _position_sub.set_sensitive();
+ } else {
+ _position_sub.set_sensitive( false );
+ }
+
+ if((it = res->openTypeTables.find("sups"))!= res->openTypeTables.end()) {
+ _position_super.set_sensitive();
+ } else {
+ _position_super.set_sensitive( false );
+ }
+
+ if((it = res->openTypeTables.find("smcp"))!= res->openTypeTables.end()) {
+ _caps_small.set_sensitive();
+ } else {
+ _caps_small.set_sensitive( false );
+ }
+
+ if((it = res->openTypeTables.find("c2sc"))!= res->openTypeTables.end() &&
+ (it = res->openTypeTables.find("smcp"))!= res->openTypeTables.end()) {
+ _caps_all_small.set_sensitive();
+ } else {
+ _caps_all_small.set_sensitive( false );
+ }
+
+ if((it = res->openTypeTables.find("pcap"))!= res->openTypeTables.end()) {
+ _caps_petite.set_sensitive();
+ } else {
+ _caps_petite.set_sensitive( false );
+ }
+
+ if((it = res->openTypeTables.find("c2sc"))!= res->openTypeTables.end() &&
+ (it = res->openTypeTables.find("pcap"))!= res->openTypeTables.end()) {
+ _caps_all_petite.set_sensitive();
+ } else {
+ _caps_all_petite.set_sensitive( false );
+ }
+
+ if((it = res->openTypeTables.find("unic"))!= res->openTypeTables.end()) {
+ _caps_unicase.set_sensitive();
+ } else {
+ _caps_unicase.set_sensitive( false );
+ }
+
+ if((it = res->openTypeTables.find("titl"))!= res->openTypeTables.end()) {
+ _caps_titling.set_sensitive();
+ } else {
+ _caps_titling.set_sensitive( false );
+ }
+
+ if((it = res->openTypeTables.find("lnum"))!= res->openTypeTables.end()) {
+ _numeric_lining.set_sensitive();
+ } else {
+ _numeric_lining.set_sensitive( false );
+ }
+
+ if((it = res->openTypeTables.find("onum"))!= res->openTypeTables.end()) {
+ _numeric_old_style.set_sensitive();
+ } else {
+ _numeric_old_style.set_sensitive( false );
+ }
+
+ if((it = res->openTypeTables.find("pnum"))!= res->openTypeTables.end()) {
+ _numeric_proportional.set_sensitive();
+ } else {
+ _numeric_proportional.set_sensitive( false );
+ }
+
+ if((it = res->openTypeTables.find("tnum"))!= res->openTypeTables.end()) {
+ _numeric_tabular.set_sensitive();
+ } else {
+ _numeric_tabular.set_sensitive( false );
+ }
+
+ if((it = res->openTypeTables.find("frac"))!= res->openTypeTables.end()) {
+ _numeric_diagonal.set_sensitive();
+ } else {
+ _numeric_diagonal.set_sensitive( false );
+ }
+
+ if((it = res->openTypeTables.find("afrac"))!= res->openTypeTables.end()) {
+ _numeric_stacked.set_sensitive();
+ } else {
+ _numeric_stacked.set_sensitive( false );
+ }
+
+ if((it = res->openTypeTables.find("ordn"))!= res->openTypeTables.end()) {
+ _numeric_ordinal.set_sensitive();
+ } else {
+ _numeric_ordinal.set_sensitive( false );
+ }
+
+ if((it = res->openTypeTables.find("zero"))!= res->openTypeTables.end()) {
+ _numeric_slashed_zero.set_sensitive();
+ } else {
+ _numeric_slashed_zero.set_sensitive( false );
+ }
+
+ // Make list of tables not handled above... eventually add Gtk::Label with
+ // this info.
+ // std::map<Glib::ustring,int> table_copy = res->openTypeTables;
+ // if( (it = table_copy.find("liga")) != table_copy.end() ) table_copy.erase( it );
+ // if( (it = table_copy.find("clig")) != table_copy.end() ) table_copy.erase( it );
+ // if( (it = table_copy.find("dlig")) != table_copy.end() ) table_copy.erase( it );
+ // if( (it = table_copy.find("hlig")) != table_copy.end() ) table_copy.erase( it );
+ // if( (it = table_copy.find("calt")) != table_copy.end() ) table_copy.erase( it );
+ // if( (it = table_copy.find("subs")) != table_copy.end() ) table_copy.erase( it );
+ // if( (it = table_copy.find("sups")) != table_copy.end() ) table_copy.erase( it );
+ // if( (it = table_copy.find("smcp")) != table_copy.end() ) table_copy.erase( it );
+ // if( (it = table_copy.find("c2sc")) != table_copy.end() ) table_copy.erase( it );
+ // if( (it = table_copy.find("pcap")) != table_copy.end() ) table_copy.erase( it );
+ // if( (it = table_copy.find("unic")) != table_copy.end() ) table_copy.erase( it );
+ // if( (it = table_copy.find("titl")) != table_copy.end() ) table_copy.erase( it );
+ // if( (it = table_copy.find("lnum")) != table_copy.end() ) table_copy.erase( it );
+ // if( (it = table_copy.find("onum")) != table_copy.end() ) table_copy.erase( it );
+ // if( (it = table_copy.find("pnum")) != table_copy.end() ) table_copy.erase( it );
+ // if( (it = table_copy.find("tnum")) != table_copy.end() ) table_copy.erase( it );
+ // if( (it = table_copy.find("frac")) != table_copy.end() ) table_copy.erase( it );
+ // if( (it = table_copy.find("afrc")) != table_copy.end() ) table_copy.erase( it );
+ // if( (it = table_copy.find("ordn")) != table_copy.end() ) table_copy.erase( it );
+ // if( (it = table_copy.find("zero")) != table_copy.end() ) table_copy.erase( it );
+ // for(it = table_copy.begin(); it != table_copy.end(); ++it) {
+ // std::cout << "Other: " << it->first << " Occurances: " << it->second << std::endl;
+ // }
+
+ } else {
+ std::cerr << "FontVariants::update(): Couldn't find font_instance for: "
+ << font_spec << std::endl;
+ }
+
+
_ligatures_changed = false;
_position_changed = false;
_caps_changed = false;
diff --git a/src/ui/widget/font-variants.h b/src/ui/widget/font-variants.h
index ca41c050b..d4329feff 100644
--- a/src/ui/widget/font-variants.h
+++ b/src/ui/widget/font-variants.h
@@ -127,7 +127,7 @@ public:
/**
* Update GUI based on query results.
*/
- void update( SPStyle const *query, bool different_features );
+ void update( SPStyle const *query, bool different_features, Glib::ustring& font_spec );
/**
* Fill SPCSSAttr based on settings of buttons.