mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-02-06 19:50:35 +01:00
Reimplement cairo-quartz-font with Core Text.
This commit is contained in:
parent
77a8d0f9e4
commit
cf351a8a0a
2 changed files with 62 additions and 38 deletions
|
|
@ -47,12 +47,9 @@
|
||||||
/**
|
/**
|
||||||
* SECTION:cairo-quartz-fonts
|
* SECTION:cairo-quartz-fonts
|
||||||
* @Title: Quartz (CGFont) Fonts
|
* @Title: Quartz (CGFont) Fonts
|
||||||
* @Short_Description: Font support via CGFont on OS X
|
* @Short_Description: Font support via Core Text on Apple operating systems.
|
||||||
* @See_Also: #cairo_font_face_t
|
* @See_Also: #cairo_font_face_t
|
||||||
*
|
*
|
||||||
* The Quartz font backend is primarily used to render text on Apple
|
|
||||||
* MacOS X systems. The CGFont API is used for the internal
|
|
||||||
* implementation of the font backend methods.
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -99,6 +96,8 @@ struct _cairo_quartz_font_face {
|
||||||
cairo_font_face_t base;
|
cairo_font_face_t base;
|
||||||
|
|
||||||
CGFontRef cgFont;
|
CGFontRef cgFont;
|
||||||
|
CTFontRef ctFont;
|
||||||
|
double ctFont_scale;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -111,8 +110,8 @@ _cairo_quartz_font_face_create_for_toy (cairo_toy_font_face_t *toy_face,
|
||||||
{
|
{
|
||||||
const char *family;
|
const char *family;
|
||||||
char *full_name;
|
char *full_name;
|
||||||
CFStringRef cgFontName = NULL;
|
CFStringRef FontName = NULL;
|
||||||
CGFontRef cgFont = NULL;
|
CTFontRef ctFont = NULL;
|
||||||
int loop;
|
int loop;
|
||||||
|
|
||||||
family = toy_face->family;
|
family = toy_face->family;
|
||||||
|
|
@ -141,31 +140,31 @@ _cairo_quartz_font_face_create_for_toy (cairo_toy_font_face_t *toy_face,
|
||||||
|
|
||||||
if (loop < 3 && (loop & 1) == 0) {
|
if (loop < 3 && (loop & 1) == 0) {
|
||||||
if (toy_face->weight == CAIRO_FONT_WEIGHT_BOLD)
|
if (toy_face->weight == CAIRO_FONT_WEIGHT_BOLD)
|
||||||
strcat (full_name, " Bold");
|
strcat (full_name, "-Bold");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loop < 3 && (loop & 2) == 0) {
|
if (loop < 3 && (loop & 2) == 0) {
|
||||||
if (toy_face->slant == CAIRO_FONT_SLANT_ITALIC)
|
if (toy_face->slant == CAIRO_FONT_SLANT_ITALIC)
|
||||||
strcat (full_name, " Italic");
|
strcat (full_name, "-Italic");
|
||||||
else if (toy_face->slant == CAIRO_FONT_SLANT_OBLIQUE)
|
else if (toy_face->slant == CAIRO_FONT_SLANT_OBLIQUE)
|
||||||
strcat (full_name, " Oblique");
|
strcat (full_name, "-Oblique");
|
||||||
}
|
}
|
||||||
|
|
||||||
cgFontName = CFStringCreateWithCString (NULL, full_name, kCFStringEncodingASCII);
|
FontName = CFStringCreateWithCString (NULL, full_name, kCFStringEncodingASCII);
|
||||||
cgFont = CGFontCreateWithFontName (cgFontName);
|
ctFont = CTFontCreateWithName (FontName, 1.0, NULL);
|
||||||
CFRelease (cgFontName);
|
CFRelease (FontName);
|
||||||
|
|
||||||
if (cgFont)
|
if (ctFont)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cgFont) {
|
if (!ctFont) {
|
||||||
/* Give up */
|
/* Give up */
|
||||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
*font_face = cairo_quartz_font_face_create_for_cgfont (cgFont);
|
*font_face = _cairo_quartz_font_face_create_for_ctfont (ctFont);
|
||||||
CGFontRelease (cgFont);
|
CFRelease (ctFont);
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -176,6 +175,7 @@ _cairo_quartz_font_face_destroy (void *abstract_face)
|
||||||
cairo_quartz_font_face_t *font_face = (cairo_quartz_font_face_t*) abstract_face;
|
cairo_quartz_font_face_t *font_face = (cairo_quartz_font_face_t*) abstract_face;
|
||||||
|
|
||||||
CGFontRelease (font_face->cgFont);
|
CGFontRelease (font_face->cgFont);
|
||||||
|
CFRelease (font_face->ctFont);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -238,6 +238,23 @@ const cairo_font_face_backend_t _cairo_quartz_font_face_backend = {
|
||||||
_cairo_quartz_font_face_scaled_font_create
|
_cairo_quartz_font_face_scaled_font_create
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline cairo_quartz_font_face_t*
|
||||||
|
_cairo_quartz_font_face_create ()
|
||||||
|
{
|
||||||
|
cairo_quartz_font_face_t *font_face =
|
||||||
|
_cairo_malloc (sizeof (cairo_quartz_font_face_t));
|
||||||
|
|
||||||
|
if (!font_face) {
|
||||||
|
cairo_status_t ignore_status;
|
||||||
|
ignore_status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
return (cairo_quartz_font_face_t *)&_cairo_font_face_nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
_cairo_font_face_init (&font_face->base, &_cairo_quartz_font_face_backend);
|
||||||
|
|
||||||
|
return font_face;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cairo_quartz_font_face_create_for_cgfont:
|
* cairo_quartz_font_face_create_for_cgfont:
|
||||||
* @font: a #CGFontRef obtained through a method external to cairo.
|
* @font: a #CGFontRef obtained through a method external to cairo.
|
||||||
|
|
@ -254,18 +271,30 @@ const cairo_font_face_backend_t _cairo_quartz_font_face_backend = {
|
||||||
cairo_font_face_t *
|
cairo_font_face_t *
|
||||||
cairo_quartz_font_face_create_for_cgfont (CGFontRef font)
|
cairo_quartz_font_face_create_for_cgfont (CGFontRef font)
|
||||||
{
|
{
|
||||||
cairo_quartz_font_face_t *font_face =
|
cairo_quartz_font_face_t* font_face = _cairo_quartz_font_face_create ();
|
||||||
_cairo_malloc (sizeof (cairo_quartz_font_face_t));
|
double font_scale = 1.0; /* 1.0 produces glyphs of the right size to pass tests. */
|
||||||
|
|
||||||
if (!font_face) {
|
if (cairo_font_face_status (&font_face->base))
|
||||||
cairo_status_t ignore_status;
|
return &font_face->base;
|
||||||
ignore_status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
|
||||||
return (cairo_font_face_t *)&_cairo_font_face_nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
font_face->cgFont = CGFontRetain (font);
|
font_face->cgFont = CGFontRetain (font);
|
||||||
|
font_face->ctFont = CTFontCreateWithGraphicsFont (font, font_scale, NULL, NULL);
|
||||||
|
font_face->ctFont_scale = CTFontGetUnitsPerEm(font_face->ctFont);
|
||||||
|
|
||||||
_cairo_font_face_init (&font_face->base, &_cairo_quartz_font_face_backend);
|
return &font_face->base;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_font_face_t *
|
||||||
|
_cairo_quartz_font_face_create_for_ctfont (CTFontRef font)
|
||||||
|
{
|
||||||
|
cairo_quartz_font_face_t* font_face = _cairo_quartz_font_face_create ();
|
||||||
|
|
||||||
|
if (cairo_font_face_status (&font_face->base))
|
||||||
|
return &font_face->base;
|
||||||
|
|
||||||
|
font_face->ctFont = CFRetain (font);
|
||||||
|
font_face->cgFont = CTFontCopyGraphicsFont (font, NULL);
|
||||||
|
font_face->ctFont_scale = CTFontGetUnitsPerEm(font_face->ctFont);
|
||||||
|
|
||||||
return &font_face->base;
|
return &font_face->base;
|
||||||
}
|
}
|
||||||
|
|
@ -439,7 +468,6 @@ _cairo_quartz_init_glyph_path (cairo_quartz_scaled_font_t *font,
|
||||||
cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
|
cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
|
||||||
CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
|
CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
|
||||||
CGAffineTransform textMatrix;
|
CGAffineTransform textMatrix;
|
||||||
CTFontRef ctFont;
|
|
||||||
CGPathRef glyphPath;
|
CGPathRef glyphPath;
|
||||||
cairo_path_fixed_t *path;
|
cairo_path_fixed_t *path;
|
||||||
|
|
||||||
|
|
@ -455,9 +483,7 @@ _cairo_quartz_init_glyph_path (cairo_quartz_scaled_font_t *font,
|
||||||
-font->base.scale.yy,
|
-font->base.scale.yy,
|
||||||
0, 0);
|
0, 0);
|
||||||
|
|
||||||
ctFont = CTFontCreateWithGraphicsFont (font_face->cgFont, 1.0, NULL, NULL);
|
glyphPath = CTFontCreatePathForGlyph (font_face->ctFont, glyph, &textMatrix);
|
||||||
glyphPath = CTFontCreatePathForGlyph (ctFont, glyph, &textMatrix);
|
|
||||||
CFRelease (ctFont);
|
|
||||||
|
|
||||||
if (!glyphPath)
|
if (!glyphPath)
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
@ -517,11 +543,7 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CGFontGetGlyphAdvances (font_face->cgFont, &glyph, 1, &advance) ||
|
CTFontGetBoundingRectsForGlyphs (font_face->ctFont, FONT_ORIENTATION_HORIZONTAL, &glyph, &bbox, 1);
|
||||||
!CGFontGetGlyphBBoxes (font_face->cgFont, &glyph, 1, &bbox))
|
|
||||||
{
|
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* scale(1,-1) * font->base.scale * scale(1,-1) */
|
/* scale(1,-1) * font->base.scale * scale(1,-1) */
|
||||||
textMatrix = CGAffineTransformMake (font->base.scale.xx,
|
textMatrix = CGAffineTransformMake (font->base.scale.xx,
|
||||||
|
|
@ -646,13 +668,11 @@ _cairo_quartz_ucs4_to_index (void *abstract_font,
|
||||||
{
|
{
|
||||||
cairo_quartz_scaled_font_t *font = (cairo_quartz_scaled_font_t*) abstract_font;
|
cairo_quartz_scaled_font_t *font = (cairo_quartz_scaled_font_t*) abstract_font;
|
||||||
cairo_quartz_font_face_t *ffont = _cairo_quartz_scaled_to_face(font);
|
cairo_quartz_font_face_t *ffont = _cairo_quartz_scaled_to_face(font);
|
||||||
CTFontRef ctFont;
|
|
||||||
CGGlyph glyph[2];
|
CGGlyph glyph[2];
|
||||||
UniChar utf16[2];
|
UniChar utf16[2];
|
||||||
|
|
||||||
int len = _cairo_ucs4_to_utf16 (ucs4, utf16);
|
int len = _cairo_ucs4_to_utf16 (ucs4, utf16);
|
||||||
ctFont = CTFontCreateWithGraphicsFont(ffont->cgFont, 10.0, NULL, NULL);
|
CTFontGetGlyphsForCharacters (ffont->ctFont, utf16, glyph, len);
|
||||||
CTFontGetGlyphsForCharacters (ctFont, utf16, glyph, len);
|
|
||||||
return glyph[0];
|
return glyph[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -693,8 +713,8 @@ static const cairo_scaled_font_backend_t _cairo_quartz_scaled_font_backend = {
|
||||||
NULL, /* text_to_glyphs */
|
NULL, /* text_to_glyphs */
|
||||||
_cairo_quartz_ucs4_to_index,
|
_cairo_quartz_ucs4_to_index,
|
||||||
_cairo_quartz_load_truetype_table,
|
_cairo_quartz_load_truetype_table,
|
||||||
NULL, /* map_glyphs_to_unicode */
|
NULL, /*index_to_ucs4*/
|
||||||
};
|
}; /* is_synthetic, index_to_glyph_name, load_type1_data, has_color_glyphs */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* private methods that the quartz surface uses
|
* private methods that the quartz surface uses
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,10 @@ CairoQuartzCreateCGImage (cairo_format_t format,
|
||||||
|
|
||||||
cairo_private CGFontRef
|
cairo_private CGFontRef
|
||||||
_cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *sfont);
|
_cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *sfont);
|
||||||
|
cairo_private CTFontRef
|
||||||
|
_cairo_quartz_scaled_font_get_ct_font (cairo_scaled_font_t *sfont);
|
||||||
|
cairo_private cairo_font_face_t*
|
||||||
|
_cairo_quartz_font_face_create_for_ctfont (CTFontRef ctFont);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue