📄 pangowin32.c
字号:
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); table = g_malloc (ENCODING_TABLE_SIZE*n_tables); res = GetFontData (hdc, CMAP, CMAP_HEADER_SIZE, table, ENCODING_TABLE_SIZE*n_tables); if (res != ENCODING_TABLE_SIZE*n_tables) return 0; for (i = 0; i < n_tables; i++) { if (table[i].platform_id == GUINT16_TO_BE (MICROSOFT_PLATFORM_ID) && table[i].encoding_id == GUINT16_TO_BE (encoding_id)) { offset = GUINT32_FROM_BE (table[i].offset); g_free (table); return offset; } } g_free (table); return 0;}static gpointerget_format_4_cmap (HDC hdc){ guint32 offset; guint32 res; guint16 length; guint16 *tbl, *tbl_end; struct format_4_cmap *table; /* FIXME: Could look here at the CRC for the font in the DC and return a cached copy if the same */ offset = get_cmap_offset (hdc, UNICODE_ENCODING_ID); if (offset == 0) return NULL; res = GetFontData (hdc, CMAP, offset + 2, &length, 2); if (res != 2) return NULL; length = GUINT16_FROM_BE (length); table = g_malloc (length); res = GetFontData (hdc, CMAP, offset, table, length); if (res != length || GUINT16_FROM_BE (table->format) != 4 || (GUINT16_FROM_BE (table->length) % 2) != 0) { g_free (table); return NULL; } table->format = GUINT16_FROM_BE (table->format); table->length = GUINT16_FROM_BE (table->length); table->language = GUINT16_FROM_BE (table->language); table->seg_count_x_2 = GUINT16_FROM_BE (table->seg_count_x_2); table->search_range = GUINT16_FROM_BE (table->search_range); table->entry_selector = GUINT16_FROM_BE (table->entry_selector); table->range_shift = GUINT16_FROM_BE (table->range_shift); tbl_end = (guint16 *)((char *)table + length); tbl = &table->reserved; while (tbl < tbl_end) { *tbl = GUINT16_FROM_BE (*tbl); tbl++; } return table;}static guint16 *get_id_range_offset (struct format_4_cmap *table){ gint32 seg_count = table->seg_count_x_2/2; return &table->arrays[seg_count*3];}static guint16 *get_id_delta (struct format_4_cmap *table){ gint32 seg_count = table->seg_count_x_2/2; return &table->arrays[seg_count*2];}static guint16 *get_start_count (struct format_4_cmap *table){ gint32 seg_count = table->seg_count_x_2/2; return &table->arrays[seg_count*1];}static guint16 *get_end_count (struct format_4_cmap *table){ gint32 seg_count = table->seg_count_x_2/2; /* Apparently the reseved spot is not reserved for the end_count array!? */ return (&table->arrays[seg_count*0])-1;}static gbooleanfind_segment (struct format_4_cmap *table, guint16 wc, guint16 *segment){ guint16 start, end, i; guint16 seg_count = table->seg_count_x_2/2; guint16 *end_count = get_end_count (table); guint16 *start_count = get_start_count (table); static guint last = 0; /* Cache of one */ if (last < seg_count && wc >= start_count[last] && wc <= end_count[last]) { *segment = last; return TRUE; } /* Binary search for the segment */ start = 0; /* inclusive */ end = seg_count; /* not inclusive */ while (start < end) { /* Look at middle pos */ i = (start + end)/2; if (i == start) { /* We made no progress. Look if this is the one. */ if (wc >= start_count[i] && wc <= end_count[i]) { *segment = i; last = i; return TRUE; } else return FALSE; } else if (wc < start_count[i]) { end = i; } else if (wc > end_count[i]) { start = i; } else { /* Found it! */ *segment = i; last = i; return TRUE; } } return FALSE;}static gpointerget_format_12_cmap (HDC hdc){ guint32 offset; guint32 res; guint32 length; guint32 *tbl, *tbl_end; struct format_12_cmap *table; offset = get_cmap_offset (hdc, UCS4_ENCODING_ID); if (offset == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -