font_factory::font_factory(void) : nbEnt(0), // Note: this "ents" cache only keeps fonts from being unreffed, does not speed up access maxEnt(32), ents(static_cast<font_entry*>(g_malloc(maxEnt*sizeof(font_entry)))), #ifdef USE_PANGO_WIN32 fontServer(pango_win32_font_map_for_display()), fontContext(pango_win32_get_context()), pangoFontCache(pango_win32_font_map_get_font_cache(fontServer)), hScreenDC(pango_win32_get_dc()), #else fontServer(pango_ft2_font_map_new()), fontContext(0), #endif fontSize(512), loadedPtr(new FaceMapType()) { #ifdef USE_PANGO_WIN32 #else pango_ft2_font_map_set_resolution(PANGO_FT2_FONT_MAP(fontServer), 72, 72); fontContext = pango_font_map_create_context(fontServer); pango_ft2_font_map_set_default_substitute(PANGO_FT2_FONT_MAP(fontServer), FactorySubstituteFunc, this, NULL); #endif }
static void init_uniscribe (void) { #ifdef HAVE_USP10_H HMODULE usp10_dll; have_uniscribe = FALSE; if ((usp10_dll = LoadLibrary ("usp10.dll")) != NULL) { (script_get_properties = (pScriptGetProperties) GetProcAddress (usp10_dll, "ScriptGetProperties")) && (script_itemize = (pScriptItemize) GetProcAddress (usp10_dll, "ScriptItemize")) && (script_shape = (pScriptShape) GetProcAddress (usp10_dll, "ScriptShape")) && (script_place = (pScriptPlace) GetProcAddress (usp10_dll, "ScriptPlace")) && (script_free_cache = (pScriptFreeCache) GetProcAddress (usp10_dll, "ScriptFreeCache")) && (script_is_complex = (pScriptIsComplex) GetProcAddress (usp10_dll, "ScriptIsComplex")) && (have_uniscribe = TRUE); } if (have_uniscribe) { #ifdef BASIC_WIN32_DEBUGGING (*script_get_properties) (&scripts, &nscripts); #endif hdc = pango_win32_get_dc (); } #endif }
PangoFontDescription *Layout::InputStreamTextSource::styleGetFontDescription() const { if (style->text == NULL) return NULL; PangoFontDescription *descr = pango_font_description_new(); // Pango can't cope with spaces before or after the commas - let's remove them. // this code is not exactly unicode-safe, but it's similar to what's done in // pango, so it's not the limiting factor Glib::ustring family; if (style->text->font_family.value == NULL) { family = "Sans"; } else { gchar **families = g_strsplit(style->text->font_family.value, ",", -1); if (families) { for (gchar **f = families ; *f ; ++f) { g_strstrip(*f); if (!family.empty()) family += ','; family += *f; } } g_strfreev(families); } pango_font_description_set_family(descr,family.c_str()); pango_font_description_set_weight(descr,(PangoWeight)_enum_converter(style->font_weight.computed, enum_convert_spstyle_weight_to_pango_weight, sizeof(enum_convert_spstyle_weight_to_pango_weight)/sizeof(enum_convert_spstyle_weight_to_pango_weight[0]))); pango_font_description_set_style(descr,(PangoStyle)_enum_converter(style->font_style.computed, enum_convert_spstyle_style_to_pango_style, sizeof(enum_convert_spstyle_style_to_pango_style)/sizeof(enum_convert_spstyle_style_to_pango_style[0]))); pango_font_description_set_variant(descr,(PangoVariant)_enum_converter(style->font_variant.computed, enum_convert_spstyle_variant_to_pango_variant, sizeof(enum_convert_spstyle_variant_to_pango_variant)/sizeof(enum_convert_spstyle_variant_to_pango_variant[0]))); #ifdef USE_PANGO_WIN32 // damn Pango fudges the size, so we need to unfudge. See source of pango_win32_font_map_init() pango_font_description_set_size(descr, (int) ((font_factory::Default())->fontSize*PANGO_SCALE*72/GetDeviceCaps(pango_win32_get_dc(),LOGPIXELSY))); // mandatory huge size (hinting workaround) // we don't set stretch on Win32, because pango-win32 has no concept of it // (Windows doesn't really provide any useful field it could use). // If we did set stretch, then any text with a font-stretch attribute would // end up falling back to Arial. #else pango_font_description_set_size(descr, (int) ((font_factory::Default())->fontSize*PANGO_SCALE)); // mandatory huge size (hinting workaround) pango_font_description_set_stretch(descr,(PangoStretch)_enum_converter(style->font_stretch.computed, enum_convert_spstyle_stretch_to_pango_stretch, sizeof(enum_convert_spstyle_stretch_to_pango_stretch)/sizeof(enum_convert_spstyle_stretch_to_pango_stretch[0]))); #endif return descr; }
font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) { #ifdef USE_PANGO_WIN32 // damn Pango fudges the size, so we need to unfudge. See source of pango_win32_font_map_init() pango_font_description_set_size(descr, (int) (fontSize*PANGO_SCALE*72/GetDeviceCaps(pango_win32_get_dc(),LOGPIXELSY))); // mandatory huge size (hinting workaround) #else pango_font_description_set_size(descr, (int) (fontSize*PANGO_SCALE)); // mandatory huge size (hinting workaround) #endif font_instance *res = NULL; FaceMapType& loadedFaces = *static_cast<FaceMapType*>(loadedPtr); if ( loadedFaces.find(descr) == loadedFaces.end() ) { // not yet loaded PangoFont *nFace = NULL; // workaround for bug #1025565. // fonts without families blow up Pango. if (sp_font_description_get_family(descr) != NULL) { nFace = pango_font_map_load_font(fontServer,fontContext,descr); } else { g_warning("%s", _("Ignoring font without family that will crash Pango")); } if ( nFace ) { // duplicate FcPattern, the hard way res = new font_instance(); // store the descr of the font we asked for, since this is the key where we intend // to put the font_instance at in the unordered_map. the descr of the returned // pangofont may differ from what was asked, so we don't know (at this // point) whether loadedFaces[that_descr] is free or not (and overwriting // an entry will bring deallocation problems) res->descr = pango_font_description_copy(descr); res->parent = this; res->InstallFace(nFace); if ( res->pFont == NULL ) { // failed to install face -> bitmap font // printf("face failed\n"); res->parent = NULL; delete res; res = NULL; if ( canFail ) { char *tc = pango_font_description_to_string(descr); PANGO_DEBUG("falling back from %s to 'sans-serif' because InstallFace failed\n",tc); g_free(tc); pango_font_description_set_family(descr,"sans-serif"); res = Face(descr,false); } } else { loadedFaces[res->descr]=res; res->Ref(); AddInCache(res); } } else { // no match if ( canFail ) { PANGO_DEBUG("falling back to 'sans-serif'\n"); descr = pango_font_description_new(); pango_font_description_set_family(descr,"sans-serif"); res = Face(descr,false); pango_font_description_free(descr); } } } else { // already here res = loadedFaces[descr]; res->Ref(); AddInCache(res); } if (res) { res->InitTheFace(); } return res; }