/** * SECTION:cairo-win32-fonts * @Title: Win32 GDI Fonts * @Short_Description: Font support for Microsoft Windows * @See_Also: #cairo_font_face_t * * The Microsoft Windows font backend is primarily used to render text on * Microsoft Windows systems. * * Note: Win32 GDI fonts do not support color fonts. Use DWrite fonts * if color font support is required.
**/
/** * CAIRO_HAS_WIN32_FONT: * * Defined if the Microsoft Windows font backend is available. * This macro can be used to conditionally compile backend-specific code. * * Since: 1.8
**/
/* 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;
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;
/* 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) {
status = _cairo_matrix_compute_basis_scale_factors (&scaled_font->logical_to_device,
&scaled_font->x_scale, &scaled_font->y_scale, TRUE); /* XXX: Handle vertical text */ if (status) return status;
/* If face_hfont is non-%NULL then font_matrix must be a simple scale by some * factor S, ctm must be the identity, logfont->lfHeight must be -S, * logfont->lfWidth, logfont->lfEscapement, logfont->lfOrientation must * all be 0, and face_hfont is the result of calling CreateFontIndirectW on * logfont.
*/ static cairo_status_t
_win32_scaled_font_create (LOGFONTW *logfont,
HFONT face_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_scaled_font_t **font_out)
{
HDC hdc;
cairo_win32_scaled_font_t *f;
cairo_matrix_t scale;
cairo_status_t status;
f = _cairo_malloc (sizeof(cairo_win32_scaled_font_t)); if (f == NULL) return _cairo_error (CAIRO_STATUS_NO_MEMORY);
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 = cairo_win32_get_system_text_quality (); else { switch (options->antialias) { case CAIRO_ANTIALIAS_NONE:
f->quality = NONANTIALIASED_QUALITY; break; case CAIRO_ANTIALIAS_GRAY: case CAIRO_ANTIALIAS_FAST: case CAIRO_ANTIALIAS_GOOD:
f->quality = ANTIALIASED_QUALITY; break; case CAIRO_ANTIALIAS_SUBPIXEL: case CAIRO_ANTIALIAS_BEST: if (_have_cleartype_quality ())
f->quality = CLEARTYPE_QUALITY; else
f->quality = ANTIALIASED_QUALITY; break; case CAIRO_ANTIALIAS_DEFAULT:
ASSERT_NOT_REACHED;
}
}
if (f->quality == logfont->lfQuality ||
(logfont->lfQuality == DEFAULT_QUALITY &&
options->antialias == CAIRO_ANTIALIAS_DEFAULT)) { /* If face_hfont is non-NULL, then we can use it to avoid creating our * own --- because the constraints on face_hfont mentioned above * guarantee it was created in exactly the same way that * _win32_scaled_font_get_scaled_hfont would create it.
*/
f->scaled_hfont = face_hfont;
} /* don't delete the hfont if we're using the one passed in to us */
f->delete_scaled_hfont = !f->scaled_hfont;
cairo_matrix_multiply (&scale, font_matrix, ctm);
status = _compute_transform (f, &scale); if (status) goto FAIL;
status = _cairo_scaled_font_init (&f->base, font_face,
font_matrix, ctm, options,
&_cairo_win32_scaled_font_backend); if (status) goto FAIL;
status = _cairo_win32_scaled_font_set_metrics (f); if (status) {
_cairo_scaled_font_fini (&f->base); goto FAIL;
}
logfont.lfHeight = 0; /* filled in later */
logfont.lfWidth = 0; /* filled in later */
logfont.lfEscapement = 0; /* filled in later */
logfont.lfOrientation = 0; /* filled in later */
switch (toy_face->weight) { case CAIRO_FONT_WEIGHT_NORMAL: default:
logfont.lfWeight = FW_NORMAL; break; case CAIRO_FONT_WEIGHT_BOLD:
logfont.lfWeight = FW_BOLD; break;
}
switch (toy_face->slant) { case CAIRO_FONT_SLANT_NORMAL: default:
logfont.lfItalic = FALSE; break; case CAIRO_FONT_SLANT_ITALIC: case CAIRO_FONT_SLANT_OBLIQUE:
logfont.lfItalic = TRUE; break;
}
logfont.lfUnderline = FALSE;
logfont.lfStrikeOut = FALSE; /* The docs for LOGFONT discourage using this, since the * interpretation is locale-specific, but it's not clear what * would be a better alternative.
*/
logfont.lfCharSet = DEFAULT_CHARSET;
logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
logfont.lfQuality = DEFAULT_QUALITY; /* filled in later */
logfont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
if (scaled_font->preserve_axes || scaled_font->base.options.hint_metrics == CAIRO_HINT_METRICS_OFF) { /* For 90-degree rotations (including 0), we get the metrics * from the GDI in logical space, then convert back to font space
*/
status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc); if (status) return status;
if (!GetTextMetrics (hdc, &metrics)) {
status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_set_metrics:GetTextMetrics");
}
cairo_win32_scaled_font_done_font (&scaled_font->base); if (status) return status;
} else { /* For all other transformations, we use the design metrics * of the font. The GDI results from GetTextMetrics() on a * transformed font are inexplicably large and we want to * avoid them.
*/
status = _cairo_win32_scaled_font_select_unscaled_font (&scaled_font->base, hdc); if (status) return status;
GetTextMetrics (hdc, &metrics);
_cairo_win32_scaled_font_done_unscaled_font (&scaled_font->base);
/* Need to determine if this is a Type 1 font for the special * handling in _text_to_glyphs. Unlike TrueType or OpenType, * Type1 fonts do not have a "cmap" table (or any other table). * However GetFontData() will retrieve a Type1 font when * requesting that GetFontData() retrieve data from the start of * the file. This is to distinguish Type1 from stroke fonts such * as "Script" and "Modern". The TMPF_TRUETYPE test is redundant * but improves performance for the most common fonts.
*/
scaled_font->is_type1 = FALSE; if (!(metrics.tmPitchAndFamily & TMPF_TRUETYPE) &&
(metrics.tmPitchAndFamily & TMPF_VECTOR))
{ if ((GetFontData (hdc, CMAP_TAG, 0, NULL, 0) == GDI_ERROR) &&
(GetFontData (hdc, 0, 0, NULL, 0) != GDI_ERROR))
{
scaled_font->is_type1 = TRUE;
}
}
if (scaled_font->is_bitmap) { /* GetGlyphOutline will not work. Assume that the glyph does not extend outside the font box. */
cairo_font_extents_t font_extents; INT width = 0;
UINT charIndex = _cairo_scaled_glyph_index (scaled_glyph);
status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc); if (status) return status;
if (!GetCharWidth32(hdc, charIndex, charIndex, &width)) {
status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_init_glyph_metrics:GetCharWidth32");
width = 0;
}
cairo_win32_scaled_font_done_font (&scaled_font->base); if (status) return status;
extents.x_bearing = 0;
extents.y_bearing = scaled_font->base.ctm.yy * (-font_extents.ascent / scaled_font->y_scale);
extents.width = width / (WIN32_FONT_LOGICAL_SCALE * scaled_font->x_scale);
extents.height = scaled_font->base.ctm.yy * (font_extents.ascent + font_extents.descent) / scaled_font->y_scale;
extents.x_advance = extents.width;
extents.y_advance = 0;
} elseif (scaled_font->preserve_axes && scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF) { /* If we aren't rotating / skewing the axes, then we get the metrics * from the GDI in device space and convert to font space.
*/
status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc); if (status) return status;
if (GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph),
GGO_METRICS | GGO_GLYPH_INDEX,
&metrics, 0, NULL, &matrix) == GDI_ERROR) {
memset (&metrics, 0, sizeof (GLYPHMETRICS));
} else { if (metrics.gmBlackBoxX > 0 && scaled_font->base.options.antialias != CAIRO_ANTIALIAS_NONE) { /* The bounding box reported by Windows supposedly contains the glyph's "black" area; * however, antialiasing (especially with ClearType) means that the actual image that * needs to be rendered may "bleed" into the adjacent pixels, mainly on the right side. * To avoid clipping the glyphs when drawn by _cairo_surface_fallback_show_glyphs, * for example, or other code that uses glyph extents to determine the area to update, * we add a pixel of "slop" to left side of the nominal "black" area returned by GDI, * and two pixels to the right (as tests show some glyphs bleed into this column).
*/
metrics.gmptGlyphOrigin.x -= 1;
metrics.gmBlackBoxX += 3;
}
}
cairo_win32_scaled_font_done_font (&scaled_font->base);
if (scaled_font->swap_y) {
extents.y_bearing = (- extents.y_bearing - extents.height);
extents.y_advance = - extents.y_advance;
}
} else { /* For all other transformations, we use the design metrics * of the font.
*/
status = _cairo_win32_scaled_font_select_unscaled_font (&scaled_font->base, hdc); if (status) return status;
/* Not currently used code, but may be useful in the future if we add * back the capability to the scaled font backend interface to get the * actual device space bbox rather than computing it from the * font-space metrics.
*/ #if 0 static cairo_status_t
_cairo_win32_scaled_font_glyph_bbox (void *abstract_font, const cairo_glyph_t *glyphs, int num_glyphs,
cairo_box_t *bbox)
{ staticconst MAT2 matrix = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 1 } };
cairo_win32_scaled_font_t *scaled_font = abstract_font; int x1 = 0, x2 = 0, y1 = 0, y2 = 0;
if (num_glyphs > 0) {
HDC hdc;
GLYPHMETRICS metrics;
cairo_status_t status; int i;
if (i == 0 || x1 > x + metrics.gmptGlyphOrigin.x)
x1 = x + metrics.gmptGlyphOrigin.x; if (i == 0 || y1 > y - metrics.gmptGlyphOrigin.y)
y1 = y - metrics.gmptGlyphOrigin.y; if (i == 0 || x2 < x + metrics.gmptGlyphOrigin.x + (int)metrics.gmBlackBoxX)
x2 = x + metrics.gmptGlyphOrigin.x + (int)metrics.gmBlackBoxX; if (i == 0 || y2 < y - metrics.gmptGlyphOrigin.y + (int)metrics.gmBlackBoxY)
y2 = y - metrics.gmptGlyphOrigin.y + (int)metrics.gmBlackBoxY;
}
for (i = 0; i < num_glyphs; i++) {
status = _add_glyph (&state, glyphs[i].index,
glyphs[i].x - x_offset, glyphs[i].y - y_offset); if (status) goto FAIL2;
}
FAIL2:
status2 = _finish_glyphs (&state); if (status == CAIRO_STATUS_SUCCESS)
status = status2;
if (info & CAIRO_SCALED_GLYPH_INFO_SURFACE) {
status = _cairo_win32_scaled_font_init_glyph_surface (scaled_font, scaled_glyph); if (status) return status;
}
if ((info & CAIRO_SCALED_GLYPH_INFO_PATH) != 0) {
status = _cairo_win32_scaled_font_init_glyph_path (scaled_font, scaled_glyph); if (status) return status;
}
*is_synthetic = FALSE;
status = _cairo_truetype_get_style (&scaled_font->base,
&weight,
&bold,
&italic); /* If this doesn't work assume it is not synthetic to avoid
* unnecessary subsetting fallbacks. */ if (status != CAIRO_STATUS_SUCCESS) return CAIRO_STATUS_SUCCESS;
static cairo_int_status_t
_cairo_win32_scaled_font_index_to_glyph_name (void *abstract_font, char **glyph_names, int num_glyph_names, unsignedlong glyph_index, unsignedlong *glyph_array_index)
{
cairo_win32_scaled_font_t *scaled_font = abstract_font; int i;
/* Windows puts .notdef at index 0 then numbers the remaining
* glyphs starting from 1 in the order they appear in the font. */
/* Find the position of .notdef in the list of glyph names. We
* only need to do this once per scaled font. */ if (! scaled_font->has_type1_notdef_index) { for (i = 0; i < num_glyph_names; i++) { if (strcmp (glyph_names[i], ".notdef") == 0) {
scaled_font->type1_notdef_index = i;
scaled_font->has_type1_notdef_index = TRUE; break;
}
} if (! scaled_font->has_type1_notdef_index) return CAIRO_INT_STATUS_UNSUPPORTED;
}
/* Once we know the position of .notdef the position of any glyph
* in the font can easily be obtained. */ if (glyph_index == 0)
*glyph_array_index = scaled_font->type1_notdef_index; elseif (glyph_index <= scaled_font->type1_notdef_index)
*glyph_array_index = glyph_index - 1; elseif (glyph_index < (unsignedlong)num_glyph_names)
*glyph_array_index = glyph_index; else return CAIRO_INT_STATUS_UNSUPPORTED;
if (! scaled_font->is_type1) return CAIRO_INT_STATUS_UNSUPPORTED;
/* Using the tag 0 retrieves the entire font file. This works with
* Type 1 fonts as well as TTF/OTF fonts. */ return _cairo_win32_scaled_font_load_truetype_table (scaled_font,
0,
offset,
buffer,
length);
}
cairo_surface_t *
_cairo_compute_glyph_mask (cairo_surface_t *surface, int quality)
{
cairo_image_surface_t *glyph;
cairo_image_surface_t *mask; int i, j;
if (quality == CLEARTYPE_QUALITY) { /* Duplicate the green channel of a 4-channel mask into the * alpha channel, then invert the whole mask.
*/
mask = (cairo_image_surface_t *)
cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
glyph->width, glyph->height); if (likely (mask->base.status == CAIRO_STATUS_SUCCESS)) { for (i = 0; i < glyph->height; i++) {
uint32_t *p = (uint32_t *) (glyph->data + i * glyph->stride);
uint32_t *q = (uint32_t *) (mask->data + i * mask->stride);
for (j = 0; j < glyph->width; j++) {
*q++ = 0xffffffff ^ (*p | ((*p & 0x0000ff00) << 16));
p++;
}
}
}
} else { /* Compute an alpha-mask from a using the green channel of a * (presumed monochrome) RGB24 image.
*/
mask = (cairo_image_surface_t *)
cairo_image_surface_create (CAIRO_FORMAT_A8,
glyph->width, glyph->height); if (likely (mask->base.status == CAIRO_STATUS_SUCCESS)) { for (i = 0; i < glyph->height; i++) {
uint32_t *p = (uint32_t *) (glyph->data + i * glyph->stride);
uint8_t *q = (uint8_t *) (mask->data + i * mask->stride);
/* If hfont is non-%NULL then logfont->lfHeight must be -S for some S, * logfont->lfWidth, logfont->lfEscapement, logfont->lfOrientation must * all be 0, and hfont is the result of calling CreateFontIndirectW on * logfont.
*/ struct _cairo_win32_font_face {
cairo_font_face_t base;
LOGFONTW logfont;
HFONT hfont;
};
/* We maintain a hash table from LOGFONT,HFONT => #cairo_font_face_t. * The primary purpose of this mapping is to provide unique * #cairo_font_face_t values so that our cache and mapping from * #cairo_font_face_t => #cairo_scaled_font_t works. Once the * corresponding #cairo_font_face_t objects fall out of downstream * caches, we don't need them in this hash table anymore. * * Modifications to this hash table are protected by * _cairo_win32_font_face_mutex.
*/
/* We manually acquire the lock rather than calling * _cairo_win32_font_face_hash_table_lock simply to avoid creating
* the table only to destroy it again. */
CAIRO_MUTEX_LOCK (_cairo_win32_font_face_mutex);
hash_table = cairo_win32_font_face_hash_table;
cairo_win32_font_face_hash_table = NULL;
CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
if (hash_table != NULL)
_cairo_hash_table_destroy (hash_table);
}
hash_table = _cairo_win32_font_face_hash_table_lock (); /* All created objects must have been mapped in the hash table. */
assert (hash_table != NULL);
if (! _cairo_reference_count_dec_and_test (&font_face->base.ref_count)) { /* somebody recreated the font whilst we waited for the lock */
_cairo_win32_font_face_hash_table_unlock (); returnFALSE;
}
/* Font faces in SUCCESS status are guaranteed to be in the * hashtable. Font faces in an error status are removed from the * hashtable if they are found during a lookup, thus they should
* only be removed if they are in the hashtable. */ if (likely (font_face->base.status == CAIRO_STATUS_SUCCESS) ||
_cairo_hash_table_lookup (hash_table, &font_face->base.hash_entry) == font_face)
_cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
if (font_face->hfont) { /* Check whether it's OK to go ahead and use the font-face's HFONT. */ if (_is_scale (ctm, 1.) &&
_is_scale (font_matrix, -font_face->logfont.lfHeight * WIN32_FONT_LOGICAL_SCALE)) {
hfont = font_face->hfont;
}
}
/** * cairo_win32_font_face_create_for_logfontw_hfont: * @logfont: A #LOGFONTW structure specifying the font to use. * If @font is %NULL then the lfHeight, lfWidth, lfOrientation and lfEscapement * fields of this structure are ignored. Otherwise lfWidth, lfOrientation and * lfEscapement must be zero. * @font: An #HFONT that can be used when the font matrix is a scale by * -lfHeight and the CTM is identity. * * 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. * * Since: 1.6
**/
cairo_font_face_t *
cairo_win32_font_face_create_for_logfontw_hfont (LOGFONTW *logfont, HFONT font)
{
cairo_win32_font_face_t *font_face, key;
cairo_hash_table_t *hash_table;
cairo_status_t status;
/* Return existing unscaled font if it exists in the hash table. */
font_face = _cairo_hash_table_lookup (hash_table,
&key.base.hash_entry); if (font_face != NULL) { if (font_face->base.status == CAIRO_STATUS_SUCCESS) {
cairo_font_face_reference (&font_face->base);
_cairo_win32_font_face_hash_table_unlock (); return &font_face->base;
}
/* remove the bad font from the hash table */
_cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
}
/* Otherwise create it and insert into hash table. */
font_face = _cairo_malloc (sizeof (cairo_win32_font_face_t)); if (!font_face) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); goto FAIL;
}
/** * 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. * * Since: 1.0
**/
cairo_font_face_t *
cairo_win32_font_face_create_for_logfontw (LOGFONTW *logfont)
{ return cairo_win32_font_face_create_for_logfontw_hfont (logfont, NULL);
}
/** * 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. * * Since: 1.2
**/
cairo_font_face_t *
cairo_win32_font_face_create_for_hfont (HFONT font)
{
LOGFONTW logfont;
GetObjectW (font, sizeof(logfont), &logfont);
if (logfont.lfEscapement != 0 || logfont.lfOrientation != 0 ||
logfont.lfWidth != 0) { /* We can't use this font because that optimization requires that
* lfEscapement, lfOrientation and lfWidth be zero. */
font = NULL;
}
/** * 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_font_face_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. * * Since: 1.0
**/
cairo_status_t
cairo_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 (! _cairo_scaled_font_is_win32 (scaled_font)) { return _cairo_error (CAIRO_STATUS_FONT_TYPE_MISMATCH);
}
if (scaled_font->status) return scaled_font->status;
status = _win32_scaled_font_get_scaled_hfont ((cairo_win32_scaled_font_t *)scaled_font, &hfont); if (status) return status;
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 scaled font from the Win32 font backend. * * Releases any resources allocated by cairo_win32_scaled_font_select_font() * * Since: 1.0
**/ void
cairo_win32_scaled_font_done_font (cairo_scaled_font_t *scaled_font)
{ if (! _cairo_scaled_font_is_win32 (scaled_font)) {
_cairo_error_throw (CAIRO_STATUS_FONT_TYPE_MISMATCH);
}
}
/** * cairo_win32_scaled_font_get_metrics_factor: * @scaled_font: a scaled font 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. * * Since: 1.0
**/ double
cairo_win32_scaled_font_get_metrics_factor (cairo_scaled_font_t *scaled_font)
{ if (! _cairo_scaled_font_is_win32 (scaled_font)) {
_cairo_error_throw (CAIRO_STATUS_FONT_TYPE_MISMATCH); return 1.;
} return 1. / ((cairo_win32_scaled_font_t *)scaled_font)->logical_scale;
}
/** * cairo_win32_scaled_font_get_logical_to_device: * @scaled_font: a scaled font from the Win32 font backend
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5
¤ Dauer der Verarbeitung: 0.54 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.