📄 pangowin32.c
字号:
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 LOGFONT struct for the specified font. * * Return value: A newly allocated LOGFONT struct. It must be * freed with g_free(). **/LOGFONT *pango_win32_font_logfont (PangoFont *font){ PangoWin32Font *win32font = (PangoWin32Font *)font; LOGFONT *lfp; g_return_val_if_fail (font != NULL, NULL); g_return_val_if_fail (PANGO_WIN32_IS_FONT (font), NULL); lfp = g_new (LOGFONT, 1); *lfp = win32font->logfont; 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_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_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;}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 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); if (!coverage) { coverage = pango_coverage_new (); pango_win32_font_calc_coverage (font, coverage, lang); pango_win32_font_entry_set_coverage (win32font->win32face, coverage, lang); } return coverage;}static PangoEngineShape *pango_win32_font_find_shaper (PangoFont *font, PangoLanguage *lang, guint32 ch){ PangoMap *shape_map = NULL; PangoScript script; shape_map = pango_win32_get_shaper_map (lang); script = pango_script_for_unichar (ch); return (PangoEngineShape *)pango_map_get_engine (shape_map, script);}/* Utility functions *//** * pango_win32_get_unknown_glyph: * @font: a #PangoFont * @wc: the Unicode character for which a glyph is needed. * * Returns the index of a glyph suitable for drawing @wc as an * unknown character. * * Use PANGO_GET_UNKNOWN_GLYPH() instead. * * Return value: a glyph index into @font **/PangoGlyphpango_win32_get_unknown_glyph (PangoFont *font, gunichar wc){ return PANGO_GET_UNKNOWN_GLYPH (wc);}/** * pango_win32_render_layout_line: * @hdc: DC to use for uncolored drawing * @line: a #PangoLayoutLine * @x: the x position of start of string (in pixels) * @y: the y position of baseline (in pixels) * * Render a #PangoLayoutLine onto a device context. For underlining to * work property the text alignment of the DC should have TA_BASELINE * and TA_LEFT. */voidpango_win32_render_layout_line (HDC hdc, PangoLayoutLine *line, int x, int y){ GSList *tmp_list = line->runs; PangoRectangle overall_rect; PangoRectangle logical_rect; PangoRectangle ink_rect; int x_off = 0; pango_layout_line_get_extents (line,NULL, &overall_rect); while (tmp_list) { HBRUSH oldfg = NULL; HBRUSH brush = NULL; POINT points[2]; PangoUnderline uline = PANGO_UNDERLINE_NONE; PangoLayoutRun *run = tmp_list->data; PangoAttrColor fg_color, bg_color; gboolean fg_set, bg_set; tmp_list = tmp_list->next; pango_win32_get_item_properties (run->item, &uline, &fg_color, &fg_set, &bg_color, &bg_set); if (uline == PANGO_UNDERLINE_NONE) pango_glyph_string_extents (run->glyphs, run->item->analysis.font, NULL, &logical_rect); else pango_glyph_string_extents (run->glyphs, run->item->analysis.font, &ink_rect, &logical_rect); if (bg_set) { HBRUSH oldbrush; brush = CreateSolidBrush (RGB ((bg_color.color.red + 128) >> 8, (bg_color.color.green + 128) >> 8, (bg_color.color.blue + 128) >> 8)); oldbrush = SelectObject (hdc, brush); Rectangle (hdc, x + PANGO_PIXELS (x_off + logical_rect.x), y + PANGO_PIXELS (overall_rect.y), PANGO_PIXELS (logical_rect.width), PANGO_PIXELS (overall_rect.height)); SelectObject (hdc, oldbrush); DeleteObject (brush); } if (fg_set) { brush = CreateSolidBrush (RGB ((fg_color.color.red + 128) >> 8, (fg_color.color.green + 128) >> 8, (fg_color.color.blue + 128) >> 8)); oldfg = SelectObject (hdc, brush); } pango_win32_render (hdc, run->item->analysis.font, run->glyphs, x + PANGO_PIXELS (x_off), y); switch (uline) { case PANGO_UNDERLINE_NONE: break; case PANGO_UNDERLINE_DOUBLE: points[0].x = x + PANGO_PIXELS (x_off + ink_rect.x) - 1; points[0].y = points[1].y = y + 4; points[1].x = x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width); Polyline (hdc, points, 2); points[0].y = points[1].y = y + 2; Polyline (hdc, points, 2); break; case PANGO_UNDERLINE_SINGLE: points[0].x = x + PANGO_PIXELS (x_off + ink_rect.x) - 1; points[0].y = points[1].y = y + 2; points[1].x = x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width); Polyline (hdc, points, 2); break; case PANGO_UNDERLINE_ERROR: { int point_x; int counter = 0; int end_x = x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width); for (point_x = x + PANGO_PIXELS (x_off + ink_rect.x) - 1; point_x <= end_x; point_x += 2) { points[0].x = point_x; points[1].x = MAX (point_x + 1, end_x); if (counter) points[0].y = points[1].y = y + 2; else points[0].y = points[1].y = y + 3; Polyline (hdc, points, 2); counter = (counter + 1) % 2; } } break; case PANGO_UNDERLINE_LOW: points[0].x = x + PANGO_PIXELS (x_off + ink_rect.x) - 1; points[0].y = points[1].y = y + PANGO_PIXELS (ink_rect.y + ink_rect.height) + 2; points[1].x = x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width); Polyline (hdc, points, 2); break; } if (fg_set) { SelectObject (hdc, oldfg); DeleteObject (brush); } x_off += logical_rect.width; }}/** * pango_win32_render_layout: * @hdc: HDC to use for uncolored drawing * @layout: a #PangoLayout * @x: the X position of the left of the layout (in pixels) * @y: the Y position of the top of the layout (in pixels) * * Render a #PangoLayoutLine onto an X drawable */voidpango_win32_render_layout (HDC hdc, PangoLayout *layout, int x, int y){ PangoLayoutIter *iter; g_return_if_fail (hdc != NULL); g_return_if_fail (PANGO_IS_LAYOUT (layout)); iter = pango_layout_get_iter (layout); do { PangoRectangle logical_rect; PangoLayoutLine *line; int baseline; line = pango_layout_iter_get_line_readonly (iter); pango_layout_iter_get_line_extents (iter, NULL, &logical_rect); baseline = pango_layout_iter_get_baseline (iter); pango_win32_render_layout_line (hdc, line, x + PANGO_PIXELS (logical_rect.x), y + PANGO_PIXELS (baseline)); } while (pango_layout_iter_next_line (iter)); pango_layout_iter_free (iter);}/* This utility function is duplicated here and in pango-layout.c; should it be * public? Trouble is - what is the appropriate set of properties? */static voidpango_win32_get_item_properties (PangoItem *item, PangoUnderline *uline, PangoAttrColor *fg_color, gboolean *fg_set, PangoAttrColor *bg_color, gboolean *bg_set){ GSList *tmp_list = item->analysis.extra_attrs; if (fg_set) *fg_set = FALSE; if (bg_set) *bg_set = FALSE; while (tmp_list) { PangoAttribute *attr = tmp_list->data; switch (attr->klass->type) { case PANGO_ATTR_UNDERLINE: if (uline) *uline = ((PangoAttrInt *)attr)->value; break; case PANGO_ATTR_FOREGROUND: if (fg_color) *fg_color = *((PangoAttrColor *)attr); if (fg_set) *fg_set = TRUE; break; case PANGO_ATTR_BACKGROUND: if (bg_color) *bg_color = *((PangoAttrColor *)attr); if (bg_set) *bg_set = TRUE; break; default: break; } tmp_list = tmp_list->next; }}static guintget_cmap_offset (HDC hdc, guint16 encoding_id){ guint16 n_tables; struct cmap_encoding_subtable *table; gint32 res; int i; guint32 offset; /* Get The number of encoding tables, at offset 2 */ res = GetFontData (hdc, CMAP, 2, &n_tables, 2); if (res != 2) return 0; n_tables = GUINT16_FROM_BE (n_tables);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -