📄 pangowin32-fontmap.c
字号:
codeset = "UTF-16BE"; else codeset = "UCS-4BE"; else if (name_ix == mac_ix) codeset = "MacRoman"; else /* name_ix == unicode_ix */ codeset = "UCS-4BE"; name = g_convert (string, record.string_length, "UTF-8", codeset, NULL, &nbytes, NULL); if (name == NULL) goto fail2; g_free (string); PING(("%s", name)); SelectObject (_pango_win32_hdc, oldhfont); DeleteObject (hfont); return name; fail2: g_free (string); SelectObject (_pango_win32_hdc, oldhfont); fail1: DeleteObject (hfont); fail0: return g_utf16_to_utf8 (lfp->lfFaceName, -1, NULL, NULL, NULL);}/** * pango_win32_font_description_from_logfontw: * @lfp: a LOGFONTW * * Creates a #PangoFontDescription that matches the specified LOGFONTW. * * The face name, italicness and weight fields in the LOGFONTW are used * to set up the resulting #PangoFontDescription. If the face name in * the LOGFONTW contains non-ASCII characters the font is temporarily * loaded (using CreateFontIndirect()) and an ASCII (usually English) * name for it is looked up from the font name tables in the font * data. If that doesn't work, the face name is converted from UTF-16 * to UTF-8 and that is used. * * Return value: the newly allocated #PangoFontDescription, which * should be freed using pango_font_description_free() * * Since: 1.16 */PangoFontDescription *pango_win32_font_description_from_logfontw (const LOGFONTW *lfp){ PangoFontDescription *description; gchar *family; PangoStyle style; PangoVariant variant; PangoWeight weight; PangoStretch stretch; family = get_family_nameW (lfp); if (!lfp->lfItalic) style = PANGO_STYLE_NORMAL; else style = PANGO_STYLE_ITALIC; variant = PANGO_VARIANT_NORMAL; /* The PangoWeight values PANGO_WEIGHT_* map exactly do Windows FW_* * values. Is this on purpose? Quantize the weight to exact * PANGO_WEIGHT_* values. Is this a good idea? */ if (lfp->lfWeight == FW_DONTCARE) weight = PANGO_WEIGHT_NORMAL; else if (lfp->lfWeight <= (FW_ULTRALIGHT + FW_LIGHT) / 2) weight = PANGO_WEIGHT_ULTRALIGHT; else if (lfp->lfWeight <= (FW_LIGHT + FW_NORMAL) / 2) weight = PANGO_WEIGHT_LIGHT; else if (lfp->lfWeight <= (FW_NORMAL + FW_BOLD) / 2) weight = PANGO_WEIGHT_NORMAL; else if (lfp->lfWeight <= (FW_BOLD + FW_ULTRABOLD) / 2) weight = PANGO_WEIGHT_BOLD; else if (lfp->lfWeight <= (FW_ULTRABOLD + FW_HEAVY) / 2) weight = PANGO_WEIGHT_ULTRABOLD; else weight = PANGO_WEIGHT_HEAVY; /* XXX No idea how to figure out the stretch */ stretch = PANGO_STRETCH_NORMAL; description = pango_font_description_new (); pango_font_description_set_family (description, family); pango_font_description_set_style (description, style); pango_font_description_set_weight (description, weight); pango_font_description_set_stretch (description, stretch); pango_font_description_set_variant (description, variant); return description;}/* This inserts the given font into the size_infos table. If a * SizeInfo already exists with the same typeface name, italicness and * weight, then the font is added to the SizeInfo's list, else a * new SizeInfo is created and inserted in the table. */static voidpango_win32_insert_font (PangoWin32FontMap *win32fontmap, LOGFONTW *lfp, gboolean is_synthetic){ LOGFONTW *lfp2 = NULL; PangoFontDescription *description; PangoWin32Family *font_family; PangoWin32Face *win32face; PangoWin32SizeInfo *size_info; GSList *tmp_list; gint i; gchar *p; PING(("face=%S,charset=%d,it=%d,wt=%ld,ht=%ld",lfp->lfFaceName,lfp->lfCharSet,lfp->lfItalic,lfp->lfWeight,lfp->lfHeight)); /* Ignore Symbol fonts (which don't have any Unicode mapping * table). We could also be fancy and use the PostScript glyph name * table for such if present, and build a Unicode map by mapping * each PostScript glyph name to Unicode character. Oh well. */ if (lfp->lfCharSet == SYMBOL_CHARSET) return; /* First insert the LOGFONTW into the list of LOGFONTWs for the * typeface name, italicness and weight. */ size_info = g_hash_table_lookup (win32fontmap->size_infos, lfp); if (!size_info) { PING(("SizeInfo not found")); size_info = g_new (PangoWin32SizeInfo, 1); size_info->logfontws = NULL; lfp2 = g_new (LOGFONTW, 1); *lfp2 = *lfp; g_hash_table_insert (win32fontmap->size_infos, lfp2, size_info); } else { /* Don't store LOGFONTWs that differ only in charset */ tmp_list = size_info->logfontws; while (tmp_list) { LOGFONTW *rover = tmp_list->data; /* We know that lfWeight, lfItalic and lfFaceName match. We * don't check lfHeight and lfWidth, those are used * when creating a font. */ if (rover->lfEscapement == lfp->lfEscapement && rover->lfOrientation == lfp->lfOrientation && rover->lfUnderline == lfp->lfUnderline && rover->lfStrikeOut == lfp->lfStrikeOut) { PING(("already have it")); return; } tmp_list = tmp_list->next; } } if (lfp2 == NULL) { lfp2 = g_new (LOGFONTW, 1); *lfp2 = *lfp; } size_info->logfontws = g_slist_prepend (size_info->logfontws, lfp2); PING(("g_slist_length(size_info->logfontws)=%d", g_slist_length(size_info->logfontws))); description = pango_win32_font_description_from_logfontw (lfp2); /* In some cases, extracting a name for a font can fail; such fonts * aren't usable for us */ if (!pango_font_description_get_family (description)) { pango_font_description_free (description); return; } win32face = g_object_new (PANGO_WIN32_TYPE_FACE, NULL); win32face->logfontw = *lfp; win32face->description = description; for (i = 0; i < PANGO_WIN32_N_COVERAGES; i++) win32face->coverages[i] = NULL; win32face->is_synthetic = is_synthetic; win32face->cmap_format = 0; win32face->cmap = NULL; win32face->cached_fonts = NULL; font_family = pango_win32_get_font_family (win32fontmap, pango_font_description_get_family (win32face->description)); font_family->font_entries = g_slist_append (font_family->font_entries, win32face); PING(("g_slist_length(font_family->font_entries)=%d", g_slist_length(font_family->font_entries))); win32fontmap->n_fonts++;#if 1 /* Thought pango.aliases would make this code unnecessary, but no. */ /* * There are magic family names coming from the X implementation. * They can be simply mapped to lfPitchAndFamily flag of the logfont * struct. These additional entries should probably only be references * to the respective entry created above. Thy are simply using the * same entry at the moment and it isn't crashing on g_free () ??? * Maybe a memory leak ... */ switch (lfp->lfPitchAndFamily & 0xF0) { case FF_MODERN : /* monospace */ PING(("monospace")); font_family->is_monospace = TRUE; /* modify before reuse */ font_family = pango_win32_get_font_family (win32fontmap, "monospace"); font_family->font_entries = g_slist_append (font_family->font_entries, win32face); win32fontmap->n_fonts++; break; case FF_ROMAN : /* serif */ PING(("serif")); font_family = pango_win32_get_font_family (win32fontmap, "serif"); font_family->font_entries = g_slist_append (font_family->font_entries, win32face); win32fontmap->n_fonts++; break; case FF_SWISS : /* sans */ PING(("sans")); font_family = pango_win32_get_font_family (win32fontmap, "sans"); font_family->font_entries = g_slist_append (font_family->font_entries, win32face); win32fontmap->n_fonts++; break; } /* Some other magic names */ /* Recognize just "courier" for "courier new" */ p = g_utf16_to_utf8 (win32face->logfontw.lfFaceName, -1, NULL, NULL, NULL); if (p && g_ascii_strcasecmp (p, "courier new") == 0) { font_family = pango_win32_get_font_family (win32fontmap, "courier"); font_family->font_entries = g_slist_append (font_family->font_entries, win32face); win32fontmap->n_fonts++; } g_free (p);#endif}/* Given a LOGFONTW and size, make a matching LOGFONTW corresponding to * an installed font. */void_pango_win32_make_matching_logfontw (PangoFontMap *fontmap, const LOGFONTW *lfp, int size, LOGFONTW *out){ PangoWin32FontMap *win32fontmap; GSList *tmp_list; PangoWin32SizeInfo *size_info; LOGFONTW *closest_match = NULL; gint match_distance = 0; PING(("lfp.face=%S,wt=%ld,ht=%ld,size:%d",lfp->lfFaceName,lfp->lfWeight,lfp->lfHeight,size)); win32fontmap = PANGO_WIN32_FONT_MAP (fontmap); size_info = g_hash_table_lookup (win32fontmap->size_infos, lfp); if (!size_info) { PING(("SizeInfo not found")); return; } tmp_list = size_info->logfontws; while (tmp_list) { LOGFONTW *tmp_logfontw = tmp_list->data; int font_size = abs (tmp_logfontw->lfHeight); if (size != -1) { int new_distance = (font_size == 0) ? 0 : abs (font_size - size); if (!closest_match || new_distance < match_distance || (new_distance < PANGO_SCALE && font_size != 0)) { closest_match = tmp_logfontw; match_distance = new_distance; } } tmp_list = tmp_list->next; } if (closest_match) { /* OK, we have a match; let's modify it to fit this size */ *out = *closest_match; out->lfHeight = -(int)((double)size / win32fontmap->resolution + 0.5); out->lfWidth = 0; } else *out = *lfp; /* Whatever. We need to pass something... */}static PangoFontDescription *pango_win32_face_describe (PangoFontFace *face){ PangoWin32Face *win32face = PANGO_WIN32_FACE (face); return pango_font_description_copy (win32face->description);}static const char *pango_win32_face_get_face_name (PangoFontFace *face){ PangoWin32Face *win32face = PANGO_WIN32_FACE (face); if (!win32face->face_name) { PangoFontDescription *desc = pango_font_face_describe (face); pango_font_description_unset_fields (desc, PANGO_FONT_MASK_FAMILY | PANGO_FONT_MASK_SIZE); win32face->face_name = pango_font_description_to_string (desc); pango_font_description_free (desc); } return win32face->face_name;}static gbooleanpango_win32_face_is_synthesized (PangoFontFace *face){ PangoWin32Face *win32face = PANGO_WIN32_FACE (face); return win32face->is_synthetic;}static voidpango_win32_face_class_init (PangoFontFaceClass *class){ class->describe = pango_win32_face_describe; class->get_face_name = pango_win32_face_get_face_name; class->list_sizes = pango_win32_face_list_sizes; class->is_synthesized = pango_win32_face_is_synthesized;}static voidpango_win32_face_list_sizes (PangoFontFace *face, int **sizes, int *n_sizes){ /* * for scalable fonts it's simple, and currently we only have such * see : pango_win32_enum_proc(), TRUETYPE_FONTTYPE */ *sizes = NULL; *n_sizes = 0;}static GTypepango_win32_face_get_type (void){ static GType object_type = 0; if (G_UNLIKELY (!object_type)) { static const GTypeInfo object_info = { sizeof (PangoFontFaceClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) pango_win32_face_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (PangoWin32Face), 0, /* n_preallocs */ (GInstanceInitFunc) NULL, }; object_type = g_type_register_static (PANGO_TYPE_FONT_FACE, I_("PangoWin32Face"), &object_info, 0); } return object_type;}/** * pango_win32_font_map_get_font_cache: * @font_map: a #PangoWin32FontMap. * * Obtains the font cache associated with the given font map. * * Return value: the #PangoWin32FontCache of @font_map. **/PangoWin32FontCache *pango_win32_font_map_get_font_cache (PangoFontMap *font_map){ g_return_val_if_fail (font_map != NULL, NULL); g_return_val_if_fail (PANGO_WIN32_IS_FONT_MAP (font_map), NULL); return PANGO_WIN32_FONT_MAP (font_map)->font_cache;}void_pango_win32_fontmap_cache_remove (PangoFontMap *fontmap, PangoWin32Font *win32font){ PangoWin32FontMap *win32fontmap = PANGO_WIN32_FONT_MAP (fontmap); GList *link = g_queue_find (win32fontmap->freed_fonts, win32font); if (link) g_queue_delete_link (win32fontmap->freed_fonts, link); win32font->in_cache = FALSE; g_object_unref (win32font);}static voidpango_win32_fontmap_cache_clear (PangoWin32FontMap *win32fontmap){ g_list_foreach (win32fontmap->freed_fonts->head, (GFunc)g_object_unref, NULL); g_queue_free (win32fontmap->freed_fonts); win32fontmap->freed_fonts = g_queue_new ();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -