📄 cairo-win32-font.c
字号:
if (scaled_font->quality == CLEARTYPE_QUALITY) { /* For ClearType, we need a 4-channel mask. If we are compositing on * a surface with alpha, we need to compute the alpha channel of * the mask (we just copy the green channel). But for a destination * surface without alpha the alpha channel of the mask is ignored */ if (surface->format != CAIRO_FORMAT_RGB24) _compute_argb32_mask_alpha (tmp_surface); else _invert_argb32_mask (tmp_surface); mask_surface = &tmp_surface->base; /* XXX: Hacky, should expose this in cairo_image_surface */ pixman_image_set_component_alpha (((cairo_image_surface_t *)tmp_surface->image)->pixman_image, TRUE); } else { mask_surface = _compute_a8_mask (tmp_surface); cairo_surface_destroy (&tmp_surface->base); if (!mask_surface) return CAIRO_STATUS_NO_MEMORY; } /* For op == OVER, no-cleartype, a possible optimization here is to * draw onto an intermediate ARGB32 surface and alpha-blend that with the * destination */ _cairo_pattern_init_for_surface (&mask, mask_surface); status = _cairo_surface_composite (op, pattern, &mask.base, &surface->base, source_x, source_y, 0, 0, dest_x, dest_y, width, height); _cairo_pattern_fini (&mask.base); cairo_surface_destroy (mask_surface); return status; }}static cairo_fixed_t_cairo_fixed_from_FIXED (FIXED f){ return *((cairo_fixed_t *)&f);}static cairo_status_t_cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font, cairo_scaled_glyph_t *scaled_glyph){ static const MAT2 matrix = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, -1 } }; cairo_status_t status; GLYPHMETRICS metrics; HDC hdc; DWORD bytesGlyph; unsigned char *buffer, *ptr; cairo_path_fixed_t *path; hdc = _get_global_font_dc (); if (!hdc) return CAIRO_STATUS_NO_MEMORY; path = _cairo_path_fixed_create (); if (!path) return CAIRO_STATUS_NO_MEMORY; status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc); if (status) goto CLEANUP_PATH; bytesGlyph = GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph), GGO_NATIVE | GGO_GLYPH_INDEX, &metrics, 0, NULL, &matrix); if (bytesGlyph == GDI_ERROR) { status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_glyph_path"); goto CLEANUP_FONT; } ptr = buffer = malloc (bytesGlyph); if (!buffer) { status = CAIRO_STATUS_NO_MEMORY; goto CLEANUP_FONT; } if (GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph), GGO_NATIVE | GGO_GLYPH_INDEX, &metrics, bytesGlyph, buffer, &matrix) == GDI_ERROR) { status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_glyph_path"); free (buffer); goto CLEANUP_FONT; } while (ptr < buffer + bytesGlyph) { TTPOLYGONHEADER *header = (TTPOLYGONHEADER *)ptr; unsigned char *endPoly = ptr + header->cb; ptr += sizeof (TTPOLYGONHEADER); _cairo_path_fixed_move_to (path, _cairo_fixed_from_FIXED (header->pfxStart.x), _cairo_fixed_from_FIXED (header->pfxStart.y)); while (ptr < endPoly) { TTPOLYCURVE *curve = (TTPOLYCURVE *)ptr; POINTFX *points = curve->apfx; int i; switch (curve->wType) { case TT_PRIM_LINE: for (i = 0; i < curve->cpfx; i++) { _cairo_path_fixed_line_to (path, _cairo_fixed_from_FIXED (points[i].x), _cairo_fixed_from_FIXED (points[i].y)); } break; case TT_PRIM_QSPLINE: for (i = 0; i < curve->cpfx - 1; i++) { cairo_fixed_t p1x, p1y, p2x, p2y, cx, cy, c1x, c1y, c2x, c2y; _cairo_path_fixed_get_current_point (path, &p1x, &p1y); cx = _cairo_fixed_from_FIXED (points[i].x); cy = _cairo_fixed_from_FIXED (points[i].y); if (i + 1 == curve->cpfx - 1) { p2x = _cairo_fixed_from_FIXED (points[i + 1].x); p2y = _cairo_fixed_from_FIXED (points[i + 1].y); } else { /* records with more than one curve use interpolation for control points, per http://support.microsoft.com/kb/q87115/ */ p2x = (cx + _cairo_fixed_from_FIXED (points[i + 1].x)) / 2; p2y = (cy + _cairo_fixed_from_FIXED (points[i + 1].y)) / 2; } c1x = 2 * cx / 3 + p1x / 3; c1y = 2 * cy / 3 + p1y / 3; c2x = 2 * cx / 3 + p2x / 3; c2y = 2 * cy / 3 + p2y / 3; _cairo_path_fixed_curve_to (path, c1x, c1y, c2x, c2y, p2x, p2y); } break; case TT_PRIM_CSPLINE: for (i = 0; i < curve->cpfx - 2; i += 2) { _cairo_path_fixed_curve_to (path, _cairo_fixed_from_FIXED (points[i].x), _cairo_fixed_from_FIXED (points[i].y), _cairo_fixed_from_FIXED (points[i + 1].x), _cairo_fixed_from_FIXED (points[i + 1].y), _cairo_fixed_from_FIXED (points[i + 2].x), _cairo_fixed_from_FIXED (points[i + 2].y)); } break; } ptr += sizeof(TTPOLYCURVE) + sizeof (POINTFX) * (curve->cpfx - 1); } _cairo_path_fixed_close_path (path); } free(buffer);CLEANUP_FONT: _cairo_scaled_glyph_set_path (scaled_glyph, &scaled_font->base, path); cairo_win32_scaled_font_done_font (&scaled_font->base); CLEANUP_PATH: if (status != CAIRO_STATUS_SUCCESS) _cairo_path_fixed_destroy (path); return status;}const cairo_scaled_font_backend_t cairo_win32_scaled_font_backend = { CAIRO_FONT_TYPE_WIN32, _cairo_win32_scaled_font_create_toy, _cairo_win32_scaled_font_fini, _cairo_win32_scaled_font_glyph_init, _cairo_win32_scaled_font_text_to_glyphs, NULL, /* ucs4_to_index */ _cairo_win32_scaled_font_show_glyphs,};/* cairo_win32_font_face_t */typedef struct _cairo_win32_font_face cairo_win32_font_face_t;struct _cairo_win32_font_face { cairo_font_face_t base; LOGFONTW logfont; HFONT hfont;};/* implement the platform-specific interface */static void_cairo_win32_font_face_destroy (void *abstract_face){}static cairo_status_t_cairo_win32_font_face_scaled_font_create (void *abstract_face, const cairo_matrix_t *font_matrix, const cairo_matrix_t *ctm, const cairo_font_options_t *options, cairo_scaled_font_t **font){ cairo_win32_font_face_t *font_face = abstract_face; *font = _win32_scaled_font_create (&font_face->logfont, font_face->hfont, &font_face->base, font_matrix, ctm, options); if (*font) return CAIRO_STATUS_SUCCESS; else return CAIRO_STATUS_NO_MEMORY;}static const cairo_font_face_backend_t _cairo_win32_font_face_backend = { CAIRO_FONT_TYPE_WIN32, _cairo_win32_font_face_destroy, _cairo_win32_font_face_scaled_font_create};/** * cairo_win32_font_face_create_for_logfontw: * @logfont: A #LOGFONTW structure specifying the font to use. * The lfHeight, lfWidth, lfOrientation and lfEscapement * fields of this structure are ignored. * * Creates a new font for the Win32 font backend based on a * #LOGFONT. This font can then be used with * cairo_set_font_face() or cairo_scaled_font_create(). * The #cairo_scaled_font_t * returned from cairo_scaled_font_create() is also for the Win32 backend * and can be used with functions such as cairo_win32_scaled_font_select_font(). * * Return value: a newly created #cairo_font_face_t. Free with * cairo_font_face_destroy() when you are done using it. **/cairo_font_face_t *cairo_win32_font_face_create_for_logfontw (LOGFONTW *logfont){ cairo_win32_font_face_t *font_face; font_face = malloc (sizeof (cairo_win32_font_face_t)); if (!font_face) { _cairo_error (CAIRO_STATUS_NO_MEMORY); return (cairo_font_face_t *)&_cairo_font_face_nil; } font_face->logfont = *logfont; font_face->hfont = NULL; _cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend); return &font_face->base;}/** * cairo_win32_font_face_create_for_hfont: * @font: An #HFONT structure specifying the font to use. * * Creates a new font for the Win32 font backend based on a * #HFONT. This font can then be used with * cairo_set_font_face() or cairo_scaled_font_create(). * The #cairo_scaled_font_t * returned from cairo_scaled_font_create() is also for the Win32 backend * and can be used with functions such as cairo_win32_scaled_font_select_font(). * * Return value: a newly created #cairo_font_face_t. Free with * cairo_font_face_destroy() when you are done using it. **/cairo_font_face_t *cairo_win32_font_face_create_for_hfont (HFONT font){ cairo_win32_font_face_t *font_face; font_face = malloc (sizeof (cairo_win32_font_face_t)); if (!font_face) { _cairo_error (CAIRO_STATUS_NO_MEMORY); return (cairo_font_face_t *)&_cairo_font_face_nil; } font_face->hfont = font; _cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend); return &font_face->base;}/** * cairo_win32_scaled_font_select_font: * @scaled_font: A #cairo_scaled_font_t from the Win32 font backend. Such an * object can be created with cairo_win32_scaled_font_create_for_logfontw(). * @hdc: a device context * * Selects the font into the given device context and changes the * map mode and world transformation of the device context to match * that of the font. This function is intended for use when using * layout APIs such as Uniscribe to do text layout with the * cairo font. After finishing using the device context, you must call * cairo_win32_scaled_font_done_font() to release any resources allocated * by this function. * * See cairo_win32_scaled_font_get_metrics_factor() for converting logical * coordinates from the device context to font space. * * Normally, calls to SaveDC() and RestoreDC() would be made around * the use of this function to preserve the original graphics state. * * Return value: %CAIRO_STATUS_SUCCESS if the operation succeeded. * otherwise an error such as %CAIRO_STATUS_NO_MEMORY and * the device context is unchanged. **/cairo_status_tcairo_win32_scaled_font_select_font (cairo_scaled_font_t *scaled_font, HDC hdc){ cairo_status_t status; HFONT hfont; HFONT old_hfont = NULL; int old_mode; if (scaled_font->status) return scaled_font->status; hfont = _win32_scaled_font_get_scaled_hfont ((cairo_win32_scaled_font_t *)scaled_font); if (!hfont) return CAIRO_STATUS_NO_MEMORY; old_hfont = SelectObject (hdc, hfont); if (!old_hfont) return _cairo_win32_print_gdi_error ("cairo_win32_scaled_font_select_font:SelectObject"); old_mode = SetGraphicsMode (hdc, GM_ADVANCED); if (!old_mode) { status = _cairo_win32_print_gdi_error ("cairo_win32_scaled_font_select_font:SetGraphicsMode"); SelectObject (hdc, old_hfont); return status; } status = _win32_scaled_font_set_world_transform ((cairo_win32_scaled_font_t *)scaled_font, hdc); if (status) { SetGraphicsMode (hdc, old_mode); SelectObject (hdc, old_hfont); return status; } SetMapMode (hdc, MM_TEXT); return CAIRO_STATUS_SUCCESS;}/** * cairo_win32_scaled_font_done_font: * @scaled_font: A #cairo_scaled_font_t from the Win32 font backend. * * Releases any resources allocated by cairo_win32_scaled_font_select_font() **/voidcairo_win32_scaled_font_done_font (cairo_scaled_font_t *scaled_font){}/** * cairo_win32_scaled_font_get_metrics_factor: * @scaled_font: a #cairo_scaled_font_t from the Win32 font backend * * Gets a scale factor between logical coordinates in the coordinate * space used by cairo_win32_scaled_font_select_font() (that is, the * coordinate system used by the Windows functions to return metrics) and * font space coordinates. * * Return value: factor to multiply logical units by to get font space * coordinates. **/doublecairo_win32_scaled_font_get_metrics_factor (cairo_scaled_font_t *scaled_font){ return 1. / ((cairo_win32_scaled_font_t *)scaled_font)->logical_scale;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -