📄 pangowin32.c
字号:
info = g_new0 (PangoWin32GlyphInfo, 1); memset (&gm, 0, sizeof (gm)); hfont = pango_win32_get_hfont (font); SelectObject (_pango_win32_hdc, hfont); /* FIXME: (Alex) This constant reuse of _pango_win32_hdc is not thread-safe */ res = GetGlyphOutlineA (_pango_win32_hdc, glyph_index, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, NULL, &m); if (res == GDI_ERROR) { gchar *error = g_win32_error_message (GetLastError ()); g_warning ("GetGlyphOutline(%04X) failed: %s\n", glyph_index, error); g_free (error); /* Don't just return now, use the still zeroed out gm */ } info->ink_rect.x = PANGO_SCALE * gm.gmptGlyphOrigin.x; info->ink_rect.width = PANGO_SCALE * gm.gmBlackBoxX; info->ink_rect.y = - PANGO_SCALE * gm.gmptGlyphOrigin.y; info->ink_rect.height = PANGO_SCALE * gm.gmBlackBoxY; info->logical_rect.x = 0; info->logical_rect.width = PANGO_SCALE * gm.gmCellIncX; info->logical_rect.y = - PANGO_SCALE * win32font->tm_ascent; info->logical_rect.height = PANGO_SCALE * (win32font->tm_ascent + win32font->tm_descent); g_hash_table_insert (win32font->glyph_info, GUINT_TO_POINTER(glyph), info); } if (ink_rect) *ink_rect = info->ink_rect; if (logical_rect) *logical_rect = info->logical_rect;}static intmax_glyph_width (PangoLayout *layout){ int max_width = 0; GSList *l, *r; for (l = pango_layout_get_lines_readonly (layout); l; l = l->next) { PangoLayoutLine *line = l->data; for (r = line->runs; r; r = r->next) { PangoGlyphString *glyphs = ((PangoGlyphItem *)r->data)->glyphs; int i; for (i = 0; i < glyphs->num_glyphs; i++) if (glyphs->glyphs[i].geometry.width > max_width) max_width = glyphs->glyphs[i].geometry.width; } } return max_width;}static PangoFontMetrics *pango_win32_font_get_metrics (PangoFont *font, PangoLanguage *language){ PangoWin32MetricsInfo *info = NULL; /* Quiet gcc */ PangoWin32Font *win32font = (PangoWin32Font *)font; GSList *tmp_list; const char *sample_str = pango_language_get_sample_string (language); tmp_list = win32font->metrics_by_lang; while (tmp_list) { info = tmp_list->data; if (info->sample_str == sample_str) /* We _don't_ need strcmp */ break; tmp_list = tmp_list->next; } if (!tmp_list) { HFONT hfont; PangoFontMetrics *metrics; info = g_new (PangoWin32MetricsInfo, 1); win32font->metrics_by_lang = g_slist_prepend (win32font->metrics_by_lang, info); info->sample_str = sample_str; info->metrics = metrics = pango_font_metrics_new (); hfont = pango_win32_get_hfont (font); if (hfont != NULL) { PangoCoverage *coverage; TEXTMETRIC tm; SelectObject (_pango_win32_hdc, hfont); GetTextMetrics (_pango_win32_hdc, &tm); metrics->ascent = tm.tmAscent * PANGO_SCALE; metrics->descent = tm.tmDescent * PANGO_SCALE; metrics->approximate_char_width = tm.tmAveCharWidth * PANGO_SCALE; coverage = pango_win32_font_get_coverage (font, language); if (pango_coverage_get (coverage, '0') != PANGO_COVERAGE_NONE && pango_coverage_get (coverage, '9') != PANGO_COVERAGE_NONE) { PangoContext *context; PangoFontDescription *font_desc; PangoLayout *layout; /* Get the average width of the chars in "0123456789" */ context = pango_win32_get_context (); pango_context_set_language (context, language); font_desc = pango_font_describe_with_absolute_size (font); pango_context_set_font_description (context, font_desc); layout = pango_layout_new (context); pango_layout_set_text (layout, "0123456789", -1); metrics->approximate_digit_width = max_glyph_width (layout); pango_font_description_free (font_desc); g_object_unref (layout); g_object_unref (context); } else metrics->approximate_digit_width = metrics->approximate_char_width; pango_coverage_unref (coverage); /* FIXME: Should get the real values from the TrueType font file */ metrics->underline_position = -2 * PANGO_SCALE; metrics->underline_thickness = 1 * PANGO_SCALE; metrics->strikethrough_thickness = metrics->underline_thickness; /* Really really wild guess */ metrics->strikethrough_position = metrics->ascent / 3; } } return pango_font_metrics_ref (info->metrics);}static PangoFontMap *pango_win32_font_get_font_map (PangoFont *font){ PangoWin32Font *win32font = (PangoWin32Font *)font; return win32font->fontmap;}static gbooleanpango_win32_font_real_select_font (PangoFont *font, HDC hdc){ HFONT hfont = pango_win32_get_hfont (font); if (!hfont) return FALSE; if (!SelectObject (hdc, hfont)) { g_warning ("pango_win32_font_real_select_font: Cannot select font\n"); return FALSE; } return TRUE;}static voidpango_win32_font_real_done_font (PangoFont *font){}static doublepango_win32_font_real_get_metrics_factor (PangoFont *font){ return PANGO_SCALE;}/** * pango_win32_font_logfont: * @font: a #PangoFont which must be from the Win32 backend * * Determine the LOGFONTA struct for the specified font. Note that * Pango internally uses LOGFONTW structs, so if converting the UTF-16 * face name in the LOGFONTW struct to system codepage fails, the * returned LOGFONTA will have an emppty face name. To get the * LOGFONTW of a PangoFont, use pango_win32_font_logfontw(). It * is recommended to do that always even if you don't expect * to come across fonts with odd names. * * Return value: A newly allocated LOGFONTA struct. It must be * freed with g_free(). **/LOGFONTA *pango_win32_font_logfont (PangoFont *font){ PangoWin32Font *win32font = (PangoWin32Font *)font; LOGFONTA *lfp; g_return_val_if_fail (font != NULL, NULL); g_return_val_if_fail (PANGO_WIN32_IS_FONT (font), NULL); lfp = g_new (LOGFONTA, 1); *lfp = *(LOGFONTA*) &win32font->logfontw; if (!WideCharToMultiByte (CP_ACP, 0, win32font->logfontw.lfFaceName, -1, lfp->lfFaceName, G_N_ELEMENTS (lfp->lfFaceName), NULL, NULL)) lfp->lfFaceName[0] = '\0'; return lfp;}/** * pango_win32_font_logfontw: * @font: a #PangoFont which must be from the Win32 backend * * Determine the LOGFONTW struct for the specified font. * * Return value: A newly allocated LOGFONTW struct. It must be * freed with g_free(). * * Since: 1.16 **/LOGFONTW *pango_win32_font_logfontw (PangoFont *font){ PangoWin32Font *win32font = (PangoWin32Font *)font; LOGFONTW *lfp; g_return_val_if_fail (font != NULL, NULL); g_return_val_if_fail (PANGO_WIN32_IS_FONT (font), NULL); lfp = g_new (LOGFONTW, 1); *lfp = win32font->logfontw; return lfp;}/** * pango_win32_font_select_font: * @font: a #PangoFont from the Win32 backend * @hdc: a windows device context * * Selects the font into the specified DC and changes the mapping mode * and world transformation of the DC appropriately for the font. * You may want to surround the use of this function with calls * to SaveDC() and RestoreDC(). Call pango_win32_font_done_font() when * you are done using the DC to release allocated resources. * * See pango_win32_font_get_metrics_factor() for information about * converting from the coordinate space used by this function * into Pango units. * * Return value: %TRUE if the operation succeeded. **/gbooleanpango_win32_font_select_font (PangoFont *font, HDC hdc){ g_return_val_if_fail (PANGO_WIN32_IS_FONT (font), FALSE); return PANGO_WIN32_FONT_GET_CLASS (font)->select_font (font, hdc);}/** * pango_win32_font_done_font: * @font: a #PangoFont from the win32 backend * * Releases any resources allocated by pango_win32_font_done_font() **/voidpango_win32_font_done_font (PangoFont *font){ g_return_if_fail (PANGO_WIN32_IS_FONT (font)); PANGO_WIN32_FONT_GET_CLASS (font)->done_font (font);}/** * pango_win32_font_get_metrics_factor: * @font: a #PangoFont from the win32 backend * * Returns the scale factor from logical units in the coordinate * space used by pango_win32_font_select_font() to Pango units * in user space. * * Return value: factor to multiply logical units by to get Pango * units. **/doublepango_win32_font_get_metrics_factor (PangoFont *font){ g_return_val_if_fail (PANGO_WIN32_IS_FONT (font), 1.); return PANGO_WIN32_FONT_GET_CLASS (font)->get_metrics_factor (font);}static voidpango_win32_fontmap_cache_add (PangoFontMap *fontmap, PangoWin32Font *win32font){ PangoWin32FontMap *win32fontmap = PANGO_WIN32_FONT_MAP (fontmap); if (win32fontmap->freed_fonts->length == MAX_FREED_FONTS) { PangoWin32Font *old_font = g_queue_pop_tail (win32fontmap->freed_fonts); g_object_unref (old_font); } g_object_ref (win32font); g_queue_push_head (win32fontmap->freed_fonts, win32font); win32font->in_cache = TRUE;}static voidpango_win32_font_dispose (GObject *object){ PangoWin32Font *win32font = PANGO_WIN32_FONT (object); /* If the font is not already in the freed-fonts cache, add it, * if it is already there, do nothing and the font will be * freed. */ if (!win32font->in_cache && win32font->fontmap) pango_win32_fontmap_cache_add (win32font->fontmap, win32font); G_OBJECT_CLASS (_pango_win32_font_parent_class)->dispose (object);}static voidfree_metrics_info (PangoWin32MetricsInfo *info){ pango_font_metrics_unref (info->metrics); g_free (info);}static voidpango_win32_font_entry_remove (PangoWin32Face *face, PangoFont *font){ face->cached_fonts = g_slist_remove (face->cached_fonts, font);}static voidpango_win32_font_finalize (GObject *object){ PangoWin32Font *win32font = (PangoWin32Font *)object; PangoWin32FontCache *cache = pango_win32_font_map_get_font_cache (win32font->fontmap); if (win32font->hfont != NULL) pango_win32_font_cache_unload (cache, win32font->hfont); g_slist_foreach (win32font->metrics_by_lang, (GFunc)free_metrics_info, NULL); g_slist_free (win32font->metrics_by_lang); if (win32font->win32face) pango_win32_font_entry_remove (win32font->win32face, PANGO_FONT (win32font)); g_hash_table_destroy (win32font->glyph_info); g_object_unref (win32font->fontmap); G_OBJECT_CLASS (_pango_win32_font_parent_class)->finalize (object);}static PangoFontDescription *pango_win32_font_describe (PangoFont *font){ PangoFontDescription *desc; PangoWin32Font *win32font = PANGO_WIN32_FONT (font); desc = pango_font_description_copy (win32font->win32face->description); pango_font_description_set_size (desc, win32font->size / (PANGO_SCALE / PANGO_WIN32_FONT_MAP (win32font->fontmap)->resolution)); return desc;}static PangoFontDescription *pango_win32_font_describe_absolute (PangoFont *font){ PangoFontDescription *desc; PangoWin32Font *win32font = PANGO_WIN32_FONT (font); desc = pango_font_description_copy (win32font->win32face->description); pango_font_description_set_absolute_size (desc, win32font->size); return desc;}static PangoMap *pango_win32_get_shaper_map (PangoLanguage *lang){ static guint engine_type_id = 0; static guint render_type_id = 0; if (engine_type_id == 0) { engine_type_id = g_quark_from_static_string (PANGO_ENGINE_TYPE_SHAPE); render_type_id = g_quark_from_static_string (PANGO_RENDER_TYPE_WIN32); } return pango_find_map (lang, engine_type_id, render_type_id);}static gintpango_win32_coverage_language_classify (PangoLanguage *lang){ if (pango_language_matches (lang, "zh-tw")) return PANGO_WIN32_COVERAGE_ZH_TW; else if (pango_language_matches (lang, "zh-cn")) return PANGO_WIN32_COVERAGE_ZH_CN; else if (pango_language_matches (lang, "ja")) return PANGO_WIN32_COVERAGE_JA; else if (pango_language_matches (lang, "ko")) return PANGO_WIN32_COVERAGE_KO; else if (pango_language_matches (lang, "vi")) return PANGO_WIN32_COVERAGE_VI; else return PANGO_WIN32_COVERAGE_UNSPEC;}static PangoCoverage *pango_win32_font_entry_get_coverage (PangoWin32Face *face, PangoLanguage *lang){ gint i = pango_win32_coverage_language_classify (lang); if (face->coverages[i]) { pango_coverage_ref (face->coverages[i]); return face->coverages[i]; } return NULL;}static voidpango_win32_font_entry_set_coverage (PangoWin32Face *face, PangoCoverage *coverage, PangoLanguage *lang){ face->coverages[pango_win32_coverage_language_classify (lang)] = pango_coverage_ref (coverage);}static PangoCoverage *pango_win32_font_get_coverage (PangoFont *font, PangoLanguage *lang){ PangoCoverage *coverage; PangoWin32Font *win32font = (PangoWin32Font *)font; coverage = pango_win32_font_entry_get_coverage (win32font->win32face, lang);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -