⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cairo-win32-font.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 4 页
字号:
/* cairo - a vector graphics library with display and print output * * Copyright © 2005 Red Hat, Inc * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public * License version 2.1 as published by the Free Software Foundation * (the "LGPL") or, at your option, under the terms of the Mozilla * Public License Version 1.1 (the "MPL"). If you do not alter this * notice, a recipient may use your version of this file under either * the MPL or the LGPL. * * You should have received a copy of the LGPL along with this library * in the file COPYING-LGPL-2.1; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * You should have received a copy of the MPL along with this library * in the file COPYING-MPL-1.1 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY * OF ANY KIND, either express or implied. See the LGPL or the MPL for * the specific language governing rights and limitations. * * The Original Code is the cairo graphics library. * * The Initial Developer of the Original Code is Red Hat, Inc. * * Contributor(s): */#include <string.h>#include <stdio.h>#include "cairoint.h"#include "cairo-win32-private.h"#ifndef SPI_GETFONTSMOOTHINGTYPE#define SPI_GETFONTSMOOTHINGTYPE 0x200a#endif#ifndef FE_FONTSMOOTHINGCLEARTYPE#define FE_FONTSMOOTHINGCLEARTYPE 2#endif#ifndef CLEARTYPE_QUALITY#define CLEARTYPE_QUALITY 5#endif#ifndef TT_PRIM_CSPLINE#define TT_PRIM_CSPLINE 3#endifconst cairo_scaled_font_backend_t cairo_win32_scaled_font_backend;typedef struct {    cairo_scaled_font_t base;    LOGFONTW logfont;    BYTE quality;    /* We do drawing and metrics computation in a "logical space" which     * is similar to font space, except that it is scaled by a factor     * of the (desired font size) * (WIN32_FONT_LOGICAL_SCALE). The multiplication     * by WIN32_FONT_LOGICAL_SCALE allows for sub-pixel precision.     */    double logical_scale;    /* The size we should actually request the font at from Windows; differs     * from the logical_scale because it is quantized for orthogonal     * transformations     */    double logical_size;    /* Transformations from device <=> logical space     */    cairo_matrix_t logical_to_device;    cairo_matrix_t device_to_logical;    /* We special case combinations of 90-degree-rotations, scales and     * flips ... that is transformations that take the axes to the     * axes. If preserve_axes is true, then swap_axes/swap_x/swap_y     * encode the 8 possibilities for orientation (4 rotation angles with     * and without a flip), and scale_x, scale_y the scale components.     */    cairo_bool_t preserve_axes;    cairo_bool_t swap_axes;    cairo_bool_t swap_x;    cairo_bool_t swap_y;    double x_scale;    double y_scale;    /* The size of the design unit of the font     */    int em_square;    HFONT scaled_hfont;    HFONT unscaled_hfont;    cairo_bool_t delete_scaled_hfont;} cairo_win32_scaled_font_t;static cairo_status_t_cairo_win32_scaled_font_set_metrics (cairo_win32_scaled_font_t *scaled_font);static cairo_status_t_cairo_win32_scaled_font_init_glyph_metrics (cairo_win32_scaled_font_t *scaled_font,					     cairo_scaled_glyph_t      *scaled_glyph);static cairo_status_t_cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font,					  cairo_scaled_glyph_t      *scaled_glyph);#define NEARLY_ZERO(d) (fabs(d) < (1. / 65536.))static void_compute_transform (cairo_win32_scaled_font_t *scaled_font,		    cairo_matrix_t            *sc){    cairo_status_t status;    if (NEARLY_ZERO (sc->yx) && NEARLY_ZERO (sc->xy)) {	scaled_font->preserve_axes = TRUE;	scaled_font->x_scale = sc->xx;	scaled_font->swap_x = (sc->xx < 0);	scaled_font->y_scale = sc->yy;	scaled_font->swap_y = (sc->yy < 0);	scaled_font->swap_axes = FALSE;    } else if (NEARLY_ZERO (sc->xx) && NEARLY_ZERO (sc->yy)) {	scaled_font->preserve_axes = TRUE;	scaled_font->x_scale = sc->yx;	scaled_font->swap_x = (sc->yx < 0);	scaled_font->y_scale = sc->xy;	scaled_font->swap_y = (sc->xy < 0);	scaled_font->swap_axes = TRUE;    } else {	scaled_font->preserve_axes = FALSE;	scaled_font->swap_x = scaled_font->swap_y = scaled_font->swap_axes = FALSE;    }    if (scaled_font->preserve_axes) {	if (scaled_font->swap_x)	    scaled_font->x_scale = - scaled_font->x_scale;	if (scaled_font->swap_y)	    scaled_font->y_scale = - scaled_font->y_scale;	scaled_font->logical_scale = WIN32_FONT_LOGICAL_SCALE * scaled_font->y_scale;	scaled_font->logical_size = WIN32_FONT_LOGICAL_SCALE * floor (scaled_font->y_scale + 0.5);    }    /* The font matrix has x and y "scale" components which we extract and     * use as character scale values.     */    cairo_matrix_init (&scaled_font->logical_to_device,		       sc->xx, sc->yx, sc->xy, sc->yy, 0, 0);    if (!scaled_font->preserve_axes) {	_cairo_matrix_compute_scale_factors (&scaled_font->logical_to_device,					     &scaled_font->x_scale, &scaled_font->y_scale,					     TRUE);	/* XXX: Handle vertical text */	scaled_font->logical_size = floor (WIN32_FONT_LOGICAL_SCALE * scaled_font->y_scale + 0.5);	scaled_font->logical_scale = WIN32_FONT_LOGICAL_SCALE * scaled_font->y_scale;    }    cairo_matrix_scale (&scaled_font->logical_to_device,			1.0 / scaled_font->logical_scale, 1.0 / scaled_font->logical_scale);    scaled_font->device_to_logical = scaled_font->logical_to_device;    status = cairo_matrix_invert (&scaled_font->device_to_logical);    if (status)	cairo_matrix_init_identity (&scaled_font->device_to_logical);}static cairo_bool_t_have_cleartype_quality (void){    OSVERSIONINFO version_info;    version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);    if (!GetVersionEx (&version_info)) {	_cairo_win32_print_gdi_error ("_have_cleartype_quality");	return FALSE;    }    return (version_info.dwMajorVersion > 5 ||	    (version_info.dwMajorVersion == 5 &&	     version_info.dwMinorVersion >= 1));	/* XP or newer */}static BYTE_get_system_quality (void){    BOOL font_smoothing;    UINT smoothing_type;    if (!SystemParametersInfo (SPI_GETFONTSMOOTHING, 0, &font_smoothing, 0)) {	_cairo_win32_print_gdi_error ("_get_system_quality");	return DEFAULT_QUALITY;    }    if (font_smoothing) {	if (_have_cleartype_quality ()) {	    if (!SystemParametersInfo (SPI_GETFONTSMOOTHINGTYPE,				       0, &smoothing_type, 0)) {		_cairo_win32_print_gdi_error ("_get_system_quality");		return DEFAULT_QUALITY;	    }	    if (smoothing_type == FE_FONTSMOOTHINGCLEARTYPE)		return CLEARTYPE_QUALITY;	}	return ANTIALIASED_QUALITY;    } else {	return DEFAULT_QUALITY;    }}static cairo_scaled_font_t *_win32_scaled_font_create (LOGFONTW                   *logfont,			   HFONT                      hfont,			   cairo_font_face_t	      *font_face,			   const cairo_matrix_t       *font_matrix,			   const cairo_matrix_t       *ctm,			   const cairo_font_options_t *options){    cairo_win32_scaled_font_t *f;    cairo_matrix_t scale;    cairo_status_t status;    f = malloc (sizeof(cairo_win32_scaled_font_t));    if (f == NULL)	return NULL;    f->logfont = *logfont;    /* We don't have any control over the hinting style or subpixel     * order in the Win32 font API, so we ignore those parts of     * cairo_font_options_t. We use the 'antialias' field to set     * the 'quality'.     *     * XXX: The other option we could pay attention to, but don't     *      here is the hint_metrics options.     */    if (options->antialias == CAIRO_ANTIALIAS_DEFAULT)	f->quality = _get_system_quality ();    else {	switch (options->antialias) {	case CAIRO_ANTIALIAS_NONE:	    f->quality = NONANTIALIASED_QUALITY;	    break;	case CAIRO_ANTIALIAS_GRAY:	    f->quality = ANTIALIASED_QUALITY;	    break;	case CAIRO_ANTIALIAS_SUBPIXEL:	    if (_have_cleartype_quality ())		f->quality = CLEARTYPE_QUALITY;	    else		f->quality = ANTIALIASED_QUALITY;	    break;	case CAIRO_ANTIALIAS_DEFAULT:	    ASSERT_NOT_REACHED;	}    }    f->em_square = 0;    f->scaled_hfont = hfont;    f->unscaled_hfont = NULL;    /* don't delete the hfont if it was passed in to us */    f->delete_scaled_hfont = !hfont;    cairo_matrix_multiply (&scale, font_matrix, ctm);    _compute_transform (f, &scale);    _cairo_scaled_font_init (&f->base, font_face,			     font_matrix, ctm, options,			     &cairo_win32_scaled_font_backend);    status = _cairo_win32_scaled_font_set_metrics (f);    if (status) {	cairo_scaled_font_destroy (&f->base);	return NULL;    }    return &f->base;}static cairo_status_t_win32_scaled_font_set_world_transform (cairo_win32_scaled_font_t *scaled_font,					HDC                        hdc){    XFORM xform;    xform.eM11 = scaled_font->logical_to_device.xx;    xform.eM21 = scaled_font->logical_to_device.xy;    xform.eM12 = scaled_font->logical_to_device.yx;    xform.eM22 = scaled_font->logical_to_device.yy;    xform.eDx = scaled_font->logical_to_device.x0;    xform.eDy = scaled_font->logical_to_device.y0;    if (!SetWorldTransform (hdc, &xform))	return _cairo_win32_print_gdi_error ("_win32_scaled_font_set_world_transform");    return CAIRO_STATUS_SUCCESS;}static cairo_status_t_win32_scaled_font_set_identity_transform (HDC hdc){    if (!ModifyWorldTransform (hdc, NULL, MWT_IDENTITY))	return _cairo_win32_print_gdi_error ("_win32_scaled_font_set_identity_transform");    return CAIRO_STATUS_SUCCESS;}static HDC_get_global_font_dc (void){    static HDC hdc;    if (!hdc) {	hdc = CreateCompatibleDC (NULL);	if (!hdc) {	    _cairo_win32_print_gdi_error ("_get_global_font_dc");	    return NULL;	}	if (!SetGraphicsMode (hdc, GM_ADVANCED)) {	    _cairo_win32_print_gdi_error ("_get_global_font_dc");	    DeleteDC (hdc);	    return NULL;	}    }    return hdc;}static HFONT_win32_scaled_font_get_scaled_hfont (cairo_win32_scaled_font_t *scaled_font){    if (!scaled_font->scaled_hfont) {	LOGFONTW logfont = scaled_font->logfont;	logfont.lfHeight = -scaled_font->logical_size;	logfont.lfWidth = 0;	logfont.lfEscapement = 0;	logfont.lfOrientation = 0;	logfont.lfQuality = scaled_font->quality;	scaled_font->scaled_hfont = CreateFontIndirectW (&logfont);	if (!scaled_font->scaled_hfont) {	    _cairo_win32_print_gdi_error ("_win32_scaled_font_get_scaled_hfont");	    return NULL;	}    }    return scaled_font->scaled_hfont;}static HFONT_win32_scaled_font_get_unscaled_hfont (cairo_win32_scaled_font_t *scaled_font,				       HDC                        hdc){    if (!scaled_font->unscaled_hfont) {	OUTLINETEXTMETRIC *otm;	unsigned int otm_size;	HFONT scaled_hfont;	LOGFONTW logfont;	scaled_hfont = _win32_scaled_font_get_scaled_hfont (scaled_font);	if (!scaled_hfont)	    return NULL;	if (!SelectObject (hdc, scaled_hfont)) {	    _cairo_win32_print_gdi_error ("_win32_scaled_font_get_unscaled_hfont:SelectObject");	    return NULL;	}	otm_size = GetOutlineTextMetrics (hdc, 0, NULL);	if (!otm_size) {	    _cairo_win32_print_gdi_error ("_win32_scaled_font_get_unscaled_hfont:GetOutlineTextMetrics");	    return NULL;	}	otm = malloc (otm_size);	if (!otm)	    return NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -