📄 pangowin32-fontmap.c
字号:
pango_win32_font_map_list_families (PangoFontMap *fontmap, PangoFontFamily ***families, int *n_families){ GSList *family_list = NULL; GSList *tmp_list; PangoWin32FontMap *win32fontmap = (PangoWin32FontMap *)fontmap; if (!n_families) return; g_hash_table_foreach (win32fontmap->families, list_families_foreach, &family_list); *n_families = g_slist_length (family_list); if (families) { int i = 0; *families = g_new (PangoFontFamily *, *n_families); tmp_list = family_list; while (tmp_list) { (*families)[i] = tmp_list->data; i++; tmp_list = tmp_list->next; } } g_slist_free (family_list);}static PangoWin32Family *pango_win32_get_font_family (PangoWin32FontMap *win32fontmap, const char *family_name){ PangoWin32Family *win32family = g_hash_table_lookup (win32fontmap->families, family_name); if (!win32family) { win32family = g_object_new (PANGO_WIN32_TYPE_FAMILY, NULL); win32family->family_name = g_strdup (family_name); win32family->font_entries = NULL; g_hash_table_insert (win32fontmap->families, win32family->family_name, win32family); } return win32family;}static PangoFont *pango_win32_font_map_load_font (PangoFontMap *fontmap, PangoContext *context, const PangoFontDescription *description){ PangoWin32FontMap *win32fontmap = (PangoWin32FontMap *)fontmap; PangoWin32Family *win32family; PangoFont *result = NULL; GSList *tmp_list; g_return_val_if_fail (description != NULL, NULL); PING(("name=%s", pango_font_description_get_family (description))); win32family = g_hash_table_lookup (win32fontmap->families, pango_font_description_get_family (description)); if (win32family) { PangoWin32Face *best_match = NULL; PING (("got win32family")); tmp_list = win32family->font_entries; while (tmp_list) { PangoWin32Face *face = tmp_list->data; if (pango_font_description_better_match (description, best_match ? best_match->description : NULL, face->description)) best_match = face; tmp_list = tmp_list->next; } if (best_match) result = PANGO_WIN32_FONT_MAP_GET_CLASS (win32fontmap)->find_font (win32fontmap, context, best_match, description); /* TODO: Handle the case that result == NULL. */ else PING(("no best match!")); } return result;}static PangoWin32Font *pango_win32_font_neww (PangoFontMap *fontmap, const LOGFONTW *lfp, int size){ PangoWin32Font *result; g_return_val_if_fail (fontmap != NULL, NULL); g_return_val_if_fail (lfp != NULL, NULL); result = (PangoWin32Font *)g_object_new (PANGO_TYPE_WIN32_FONT, NULL); result->fontmap = fontmap; g_object_ref (fontmap); result->size = size; _pango_win32_make_matching_logfontw (fontmap, lfp, size, &result->logfontw); return result;}static PangoFont *pango_win32_font_map_real_find_font (PangoWin32FontMap *win32fontmap, PangoContext *context, PangoWin32Face *face, const PangoFontDescription *description){ PangoFontMap *fontmap = PANGO_FONT_MAP (win32fontmap); PangoWin32Font *win32font; GSList *tmp_list = face->cached_fonts; int size = pango_font_description_get_size (description); if (pango_font_description_get_size_is_absolute (description)) size = (int) 0.5 + (size * win32fontmap->resolution) / PANGO_SCALE; PING(("got best match:%S size=%d",face->logfontw.lfFaceName,size)); while (tmp_list) { win32font = tmp_list->data; if (win32font->size == size) { PING (("size matches")); g_object_ref (win32font); if (win32font->in_cache) _pango_win32_fontmap_cache_remove (fontmap, win32font); return (PangoFont *)win32font; } tmp_list = tmp_list->next; } win32font = pango_win32_font_neww (fontmap, &face->logfontw, size); if (!win32font) return NULL; win32font->fontmap = fontmap; win32font->win32face = face; face->cached_fonts = g_slist_prepend (face->cached_fonts, win32font); return (PangoFont *)win32font;}static gchar *get_family_nameA (const LOGFONTA *lfp){ HFONT hfont; HFONT oldhfont; struct name_header header; struct name_record record; gint unicode_ix = -1, mac_ix = -1, microsoft_ix = -1; gint name_ix; gchar *codeset; gchar *string = NULL; gchar *name; gint i, l; gsize nbytes; /* If lfFaceName is ASCII, assume it is the common (English) name * for the font. Is this valid? Do some TrueType fonts have * different names in French, German, etc, and does the system * return these if the locale is set to use French, German, etc? */ l = strlen (lfp->lfFaceName); for (i = 0; i < l; i++) if (lfp->lfFaceName[i] < ' ' || lfp->lfFaceName[i] > '~') break; if (i == l) return g_strdup (lfp->lfFaceName); if ((hfont = CreateFontIndirect (lfp)) == NULL) goto fail0; if ((oldhfont = SelectObject (_pango_win32_hdc, hfont)) == NULL) goto fail1; if (!_pango_win32_get_name_header (_pango_win32_hdc, &header)) goto fail2; PING (("%d name records", header.num_records)); for (i = 0; i < header.num_records; i++) { if (!_pango_win32_get_name_record (_pango_win32_hdc, i, &record)) goto fail2; if ((record.name_id != 1 && record.name_id != 16) || record.string_length <= 0) continue; PING(("platform:%d encoding:%d language:%04x name_id:%d", record.platform_id, record.encoding_id, record.language_id, record.name_id)); if (record.platform_id == APPLE_UNICODE_PLATFORM_ID || record.platform_id == ISO_PLATFORM_ID) unicode_ix = i; else if (record.platform_id == MACINTOSH_PLATFORM_ID && record.encoding_id == 0 && /* Roman */ record.language_id == 0) /* English */ mac_ix = i; else if (record.platform_id == MICROSOFT_PLATFORM_ID) if ((microsoft_ix == -1 || PRIMARYLANGID (record.language_id) == LANG_ENGLISH) && (record.encoding_id == SYMBOL_ENCODING_ID || record.encoding_id == UNICODE_ENCODING_ID || record.encoding_id == UCS4_ENCODING_ID)) microsoft_ix = i; } if (microsoft_ix >= 0) name_ix = microsoft_ix; else if (mac_ix >= 0) name_ix = mac_ix; else if (unicode_ix >= 0) name_ix = unicode_ix; else goto fail2; if (!_pango_win32_get_name_record (_pango_win32_hdc, name_ix, &record)) goto fail2; string = g_malloc (record.string_length + 1); if (GetFontData (_pango_win32_hdc, NAME, header.string_storage_offset + record.string_offset, string, record.string_length) != record.string_length) goto fail2; string[record.string_length] = '\0'; if (name_ix == microsoft_ix) if (record.encoding_id == SYMBOL_ENCODING_ID || record.encoding_id == UNICODE_ENCODING_ID || record.encoding_id == UCS4_ENCODING_ID) 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_locale_to_utf8 (lfp->lfFaceName, -1, NULL, NULL, NULL);}/** * pango_win32_font_description_from_logfont: * @lfp: a LOGFONTA * * Creates a #PangoFontDescription that matches the specified LOGFONTA. * * The face name, italicness and weight fields in the LOGFONTA are used * to set up the resulting #PangoFontDescription. If the face name in * the LOGFONTA 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 the * system codepage to UTF-8 and that is used. * * Return value: the newly allocated #PangoFontDescription, which * should be freed using pango_font_description_free() * * Since: 1.12 */PangoFontDescription *pango_win32_font_description_from_logfont (const LOGFONT *lfp){ PangoFontDescription *description; gchar *family; PangoStyle style; PangoVariant variant; PangoWeight weight; PangoStretch stretch; family = get_family_nameA (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); g_free(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;}static gchar *get_family_nameW (const LOGFONTW *lfp){ HFONT hfont; HFONT oldhfont; struct name_header header; struct name_record record; gint unicode_ix = -1, mac_ix = -1, microsoft_ix = -1; gint name_ix; gchar *codeset; gchar *string = NULL; gchar *name; gint i, l; gsize nbytes; /* If lfFaceName is ASCII, assume it is the common (English) name * for the font. Is this valid? Do some TrueType fonts have * different names in French, German, etc, and does the system * return these if the locale is set to use French, German, etc? */ l = wcslen (lfp->lfFaceName); for (i = 0; i < l; i++) if (lfp->lfFaceName[i] < ' ' || lfp->lfFaceName[i] > '~') break; if (i == l) return g_utf16_to_utf8 (lfp->lfFaceName, -1, NULL, NULL, NULL); if ((hfont = CreateFontIndirectW (lfp)) == NULL) goto fail0; if ((oldhfont = SelectObject (_pango_win32_hdc, hfont)) == NULL) goto fail1; if (!_pango_win32_get_name_header (_pango_win32_hdc, &header)) goto fail2; PING (("%d name records", header.num_records)); for (i = 0; i < header.num_records; i++) { if (!_pango_win32_get_name_record (_pango_win32_hdc, i, &record)) goto fail2; if ((record.name_id != 1 && record.name_id != 16) || record.string_length <= 0) continue; PING(("platform:%d encoding:%d language:%04x name_id:%d", record.platform_id, record.encoding_id, record.language_id, record.name_id)); if (record.platform_id == APPLE_UNICODE_PLATFORM_ID || record.platform_id == ISO_PLATFORM_ID) unicode_ix = i; else if (record.platform_id == MACINTOSH_PLATFORM_ID && record.encoding_id == 0 && /* Roman */ record.language_id == 0) /* English */ mac_ix = i; else if (record.platform_id == MICROSOFT_PLATFORM_ID) if ((microsoft_ix == -1 || PRIMARYLANGID (record.language_id) == LANG_ENGLISH) && (record.encoding_id == SYMBOL_ENCODING_ID || record.encoding_id == UNICODE_ENCODING_ID || record.encoding_id == UCS4_ENCODING_ID)) microsoft_ix = i; } if (microsoft_ix >= 0) name_ix = microsoft_ix; else if (mac_ix >= 0) name_ix = mac_ix; else if (unicode_ix >= 0) name_ix = unicode_ix; else goto fail2; if (!_pango_win32_get_name_record (_pango_win32_hdc, name_ix, &record)) goto fail2; string = g_malloc (record.string_length + 1); if (GetFontData (_pango_win32_hdc, NAME, header.string_storage_offset + record.string_offset, string, record.string_length) != record.string_length) goto fail2; string[record.string_length] = '\0'; if (name_ix == microsoft_ix) if (record.encoding_id == SYMBOL_ENCODING_ID || record.encoding_id == UNICODE_ENCODING_ID ||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -