Change cairo_font_backend_t to use a void * for the abstract font. Put create, copy, and destroy as the first functions in the list. Fix text_path and glyph_path so that the path to be returned is the last argument. Add x,y arguments to text_path.

Compute x,y now needed by cairo_font_text_path. (_cairo_gstate_glyph_path): Track change in cairo_font_text/glyph_path (path argument is now last).
Switch to new macro-based mechanism for including freetype headers. (cairo_ft_font_face): (cairo_ft_font_pattern): Minor cleanup. (_cairo_ft_font_copy): (_cairo_ft_font_destroy): (_utf8_to_glyphs): (_cairo_ft_font_font_extents): (_cairo_ft_font_glyph_extents): (_cairo_ft_font_text_extents): (_cairo_ft_font_show_glyphs): (_cairo_ft_font_show_text): Track changes to cairo_font_backend_t interface.
Track changes to cairo_font_backend_t interface.
This commit is contained in:
Carl Worth 2003-12-16 06:50:37 +00:00
parent c18a81e252
commit 368b4d269b
8 changed files with 298 additions and 215 deletions

View file

@ -1,3 +1,34 @@
2003-12-16 Carl Worth <cworth@isi.edu>
* src/cairoint.h: Change cairo_font_backend_t to use a void * for
the abstract font. Put create, copy, and destroy as the first
functions in the list. Fix text_path and glyph_path so that the
path to be returned is the last argument. Add x,y arguments to
text_path.
* src/cairo_gstate.c (_cairo_gstate_text_path): Compute x,y now
needed by cairo_font_text_path.
(_cairo_gstate_glyph_path): Track change in
cairo_font_text/glyph_path (path argument is now last).
* src/cairo_ft_font.c: Switch to new macro-based mechanism for
including freetype headers.
(cairo_ft_font_face):
(cairo_ft_font_pattern): Minor cleanup.
(_cairo_ft_font_copy):
(_cairo_ft_font_destroy):
(_utf8_to_glyphs):
(_cairo_ft_font_font_extents):
(_cairo_ft_font_glyph_extents):
(_cairo_ft_font_text_extents):
(_cairo_ft_font_show_glyphs):
(_cairo_ft_font_show_text): Track changes to cairo_font_backend_t
interface.
* src/cairo_font.c (_cairo_font_text_path):
(_cairo_font_glyph_path): Track changes to cairo_font_backend_t
interface.
2003-12-16 Carl Worth <cworth@isi.edu>
* TODO: Change instances of Cairo to cairo where necessary. Add

View file

@ -133,20 +133,21 @@ _cairo_font_show_glyphs (cairo_font_t *font,
cairo_status_t
_cairo_font_text_path (cairo_font_t *font,
cairo_path_t *path,
const unsigned char *utf8)
double x,
double y,
const unsigned char *utf8,
cairo_path_t *path)
{
return font->backend->text_path(font, path, utf8);
return font->backend->text_path(font, x, y, utf8, path);
}
cairo_status_t
_cairo_font_glyph_path (cairo_font_t *font,
cairo_path_t *path,
cairo_glyph_t *glyphs,
int num_glyphs)
int num_glyphs,
cairo_path_t *path)
{
return font->backend->glyph_path(font, path,
glyphs, num_glyphs);
return font->backend->glyph_path(font, glyphs, num_glyphs, path);
}
cairo_status_t

View file

@ -25,7 +25,10 @@
#include "cairoint.h"
#include <fontconfig/fontconfig.h>
#include <fontconfig/fcfreetype.h>
#include <freetype/freetype.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_OUTLINE_H
typedef struct {
cairo_font_t base;
@ -39,7 +42,6 @@ typedef struct {
FcPattern *pattern;
} cairo_ft_font_t;
#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0))
#define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
#define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
@ -99,25 +101,27 @@ cairo_ft_font_create (FT_Library ft_library, FcPattern *pattern)
}
FT_Face
cairo_ft_font_face (cairo_font_t *font)
cairo_ft_font_face (cairo_font_t *abstract_font)
{
cairo_ft_font_t *font = (cairo_ft_font_t *) abstract_font;
if (font == NULL)
return NULL;
return ((cairo_ft_font_t *) font)->face;
return font->face;
}
FcPattern *
cairo_ft_font_pattern (cairo_font_t *font)
cairo_ft_font_pattern (cairo_font_t *abstract_font)
{
cairo_ft_font_t *font = (cairo_ft_font_t *) abstract_font;
if (font == NULL)
return NULL;
return ((cairo_ft_font_t *) font)->pattern;
return font->pattern;
}
/* implement the backend interface */
static cairo_font_t *
@ -189,45 +193,43 @@ _cairo_ft_font_create (const char *family,
return font;
}
static cairo_font_t *
_cairo_ft_font_copy (cairo_font_t *font)
_cairo_ft_font_copy (void *abstract_font)
{
cairo_ft_font_t * ft_font_new = NULL;
cairo_ft_font_t * ft_font = NULL;
cairo_ft_font_t * font_new = NULL;
cairo_ft_font_t * font = abstract_font;
ft_font = (cairo_ft_font_t *)font;
if (font->base.backend != &cairo_ft_font_backend)
return NULL;
ft_font_new = (cairo_ft_font_t *)cairo_ft_font_create_for_ft_face (ft_font->face);
if (ft_font_new == NULL)
font_new = (cairo_ft_font_t *) cairo_ft_font_create_for_ft_face (font->face);
if (font_new == NULL)
return NULL;
if (ft_font_new != NULL && ft_font->pattern != NULL)
ft_font_new->pattern = FcPatternDuplicate (ft_font->pattern);
if (font_new != NULL && font->pattern != NULL)
font_new->pattern = FcPatternDuplicate (font->pattern);
return (cairo_font_t *)ft_font_new;
return (cairo_font_t *) font_new;
}
static void
_cairo_ft_font_destroy (cairo_font_t *font)
_cairo_ft_font_destroy (void *abstract_font)
{
cairo_ft_font_t * ft_font = NULL;
cairo_ft_font_t * font = abstract_font;
if (font == NULL)
return;
ft_font = (cairo_ft_font_t *)font;
if (font->face != NULL && font->owns_face)
FT_Done_Face (font->face);
if (ft_font->face != NULL && ft_font->owns_face)
FT_Done_Face (ft_font->face);
if (ft_font->pattern != NULL)
FcPatternDestroy (ft_font->pattern);
if (font->pattern != NULL)
FcPatternDestroy (font->pattern);
if (ft_font->ft_library && ft_font->owns_ft_library)
FT_Done_FreeType (ft_font->ft_library);
if (font->ft_library && font->owns_ft_library)
FT_Done_FreeType (font->ft_library);
free (ft_font);
free (font);
}
static void
@ -301,25 +303,19 @@ _install_font_matrix(cairo_matrix_t *matrix, FT_Face face)
0, 0);
}
static int
_utf8_to_glyphs (cairo_font_t *font,
const unsigned char *utf8,
double x0,
double y0,
cairo_glyph_t **glyphs,
size_t *nglyphs)
_utf8_to_glyphs (cairo_ft_font_t *font,
const unsigned char *utf8,
double x0,
double y0,
cairo_glyph_t **glyphs,
size_t *nglyphs)
{
cairo_ft_font_t *ft;
FT_Face face = font->face;
double x = 0., y = 0.;
size_t i;
FT_ULong *ucs4 = NULL;
if (font == NULL)
return 0;
ft = (cairo_ft_font_t *)font;
_utf8_to_ucs4 (utf8, &ucs4, nglyphs);
if (ucs4 == NULL)
@ -332,18 +328,18 @@ _utf8_to_glyphs (cairo_font_t *font,
return 0;
}
_install_font_matrix (&font->matrix, ft->face);
_install_font_matrix (&font->base.matrix, face);
for (i = 0; i < *nglyphs; i++)
{
(*glyphs)[i].index = FT_Get_Char_Index (ft->face, ucs4[i]);
(*glyphs)[i].index = FT_Get_Char_Index (face, ucs4[i]);
(*glyphs)[i].x = x0 + x;
(*glyphs)[i].y = y0 + y;
FT_Load_Glyph (ft->face, (*glyphs)[i].index, FT_LOAD_DEFAULT);
FT_Load_Glyph (face, (*glyphs)[i].index, FT_LOAD_DEFAULT);
x += DOUBLE_FROM_26_6 (ft->face->glyph->advance.x);
y -= DOUBLE_FROM_26_6 (ft->face->glyph->advance.y);
x += DOUBLE_FROM_26_6 (face->glyph->advance.x);
y -= DOUBLE_FROM_26_6 (face->glyph->advance.y);
}
free (ucs4);
@ -351,15 +347,16 @@ _utf8_to_glyphs (cairo_font_t *font,
}
static cairo_status_t
_cairo_ft_font_font_extents (cairo_font_t *font,
cairo_font_extents_t *extents)
_cairo_ft_font_font_extents (void *abstract_font,
cairo_font_extents_t *extents)
{
FT_Face face;
cairo_ft_font_t *font = abstract_font;
FT_Face face = font->face;
double scale_x, scale_y;
face = ((cairo_ft_font_t *)font)->face;
double upm = face->units_per_EM;
_cairo_matrix_compute_scale_factors (&font->matrix, &scale_x, &scale_y);
_cairo_matrix_compute_scale_factors (&font->base.matrix, &scale_x, &scale_y);
extents->ascent = face->ascender / upm * scale_y;
extents->descent = face->descender / upm * scale_y;
@ -371,17 +368,18 @@ _cairo_ft_font_font_extents (cairo_font_t *font,
}
static cairo_status_t
_cairo_ft_font_glyph_extents (cairo_font_t *font,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_text_extents_t *extents)
_cairo_ft_font_glyph_extents (void *abstract_font,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_text_extents_t *extents)
{
int i;
cairo_ft_font_t *font = abstract_font;
cairo_point_double_t origin;
cairo_point_double_t glyph_min, glyph_max;
cairo_point_double_t total_min, total_max;
FT_Error error;
FT_Face face = ((cairo_ft_font_t *)font)->face;
FT_Face face = font->face;
FT_GlyphSlot glyph = face->glyph;
FT_Glyph_Metrics *metrics = &glyph->metrics;
@ -400,7 +398,7 @@ _cairo_ft_font_glyph_extents (cairo_font_t *font,
origin.x = glyphs[0].x;
origin.y = glyphs[0].y;
_install_font_matrix (&font->matrix, face);
_install_font_matrix (&font->base.matrix, face);
for (i = 0; i < num_glyphs; i++)
{
@ -447,10 +445,11 @@ _cairo_ft_font_glyph_extents (cairo_font_t *font,
static cairo_status_t
_cairo_ft_font_text_extents (cairo_font_t *font,
const unsigned char *utf8,
cairo_text_extents_t *extents)
_cairo_ft_font_text_extents (void *abstract_font,
const unsigned char *utf8,
cairo_text_extents_t *extents)
{
cairo_ft_font_t *font = abstract_font;
cairo_glyph_t *glyphs;
size_t nglyphs;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
@ -463,17 +462,16 @@ _cairo_ft_font_text_extents (cairo_font_t *font,
}
return status;
}
static cairo_status_t
_cairo_ft_font_show_glyphs (cairo_font_t *font,
_cairo_ft_font_show_glyphs (void *abstract_font,
cairo_operator_t operator,
cairo_surface_t *source,
cairo_surface_t *surface,
const cairo_glyph_t *glyphs,
int num_glyphs)
{
cairo_ft_font_t *font = abstract_font;
cairo_status_t status;
int i;
cairo_ft_font_t *ft = NULL;
@ -491,7 +489,7 @@ _cairo_ft_font_show_glyphs (cairo_font_t *font,
ft = (cairo_ft_font_t *)font;
glyphslot = ft->face->glyph;
_install_font_matrix (&font->matrix, ft->face);
_install_font_matrix (&font->base.matrix, ft->face);
for (i = 0; i < num_glyphs; i++)
{
@ -566,7 +564,7 @@ _cairo_ft_font_show_glyphs (cairo_font_t *font,
}
static cairo_status_t
_cairo_ft_font_show_text (cairo_font_t *font,
_cairo_ft_font_show_text (void *abstract_font,
cairo_operator_t operator,
cairo_surface_t *source,
cairo_surface_t *surface,
@ -574,6 +572,7 @@ _cairo_ft_font_show_text (cairo_font_t *font,
double y0,
const unsigned char *utf8)
{
cairo_ft_font_t *font = abstract_font;
cairo_glyph_t *glyphs;
int num_glyphs;
@ -608,17 +607,20 @@ _cairo_ft_font_glyph_path (cairo_font_t *font,
}
static cairo_status_t
_cairo_ft_font_text_path (cairo_font_t *font,
cairo_path_t *path,
_cairo_ft_font_text_path (void *abstract_font,
cairo_path_t *path,
double x,
double y,
const unsigned char *utf8)
{
cairo_ft_font_t *font = abstract_font;
cairo_glyph_t *glyphs;
size_t nglyphs;
if (_utf8_to_glyphs (font, utf8, 0, 0, &glyphs, &nglyphs))
if (_utf8_to_glyphs (font, utf8, x, y, &glyphs, &nglyphs))
{
cairo_status_t res;
res = _cairo_ft_font_glyph_path (font, path, glyphs, nglyphs);
res = _cairo_ft_font_glyph_path (font, glyphs, nglyphs, path);
free (glyphs);
return res;
}
@ -651,6 +653,9 @@ cairo_ft_font_create_for_ft_face (FT_Face face)
const struct cairo_font_backend cairo_ft_font_backend = {
_cairo_ft_font_create,
_cairo_ft_font_copy,
_cairo_ft_font_destroy,
_cairo_ft_font_font_extents,
_cairo_ft_font_text_extents,
_cairo_ft_font_glyph_extents,
@ -658,7 +663,4 @@ const struct cairo_font_backend cairo_ft_font_backend = {
_cairo_ft_font_show_glyphs,
_cairo_ft_font_text_path,
_cairo_ft_font_glyph_path,
_cairo_ft_font_create,
_cairo_ft_font_copy,
_cairo_ft_font_destroy
};

View file

@ -1797,16 +1797,38 @@ _cairo_gstate_text_path (cairo_gstate_t *gstate,
const unsigned char *utf8)
{
cairo_status_t status;
cairo_matrix_t user_to_source;
cairo_matrix_t saved_font_matrix;
double x, y;
status = setup_text_rendering_context (gstate, &user_to_source);
if (status)
return status;
/* XXX: I believe this is correct, but it would be much more clear
to have some explicit current_point accesor functions, (one for
user- and one for device-space). */
if (gstate->has_current_point) {
x = gstate->current_point.x;
y = gstate->current_point.y;
} else {
x = 0;
y = 0;
cairo_matrix_transform_point (&gstate->ctm, &x, &y);
}
cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix);
cairo_matrix_multiply (&gstate->font->matrix, &gstate->ctm, &gstate->font->matrix);
status = _cairo_font_text_path (gstate->font,
&gstate->path,
utf8);
x, y,
utf8,
&gstate->path);
cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix);
restore_text_rendering_context (gstate, &user_to_source);
return status;
}
@ -1837,8 +1859,8 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate,
cairo_matrix_multiply (&gstate->font->matrix, &gstate->ctm, &gstate->font->matrix);
status = _cairo_font_glyph_path (gstate->font,
&gstate->path,
transformed_glyphs, num_glyphs);
transformed_glyphs, num_glyphs,
&gstate->path);
cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix);

View file

@ -133,20 +133,21 @@ _cairo_font_show_glyphs (cairo_font_t *font,
cairo_status_t
_cairo_font_text_path (cairo_font_t *font,
cairo_path_t *path,
const unsigned char *utf8)
double x,
double y,
const unsigned char *utf8,
cairo_path_t *path)
{
return font->backend->text_path(font, path, utf8);
return font->backend->text_path(font, x, y, utf8, path);
}
cairo_status_t
_cairo_font_glyph_path (cairo_font_t *font,
cairo_path_t *path,
cairo_glyph_t *glyphs,
int num_glyphs)
int num_glyphs,
cairo_path_t *path)
{
return font->backend->glyph_path(font, path,
glyphs, num_glyphs);
return font->backend->glyph_path(font, glyphs, num_glyphs, path);
}
cairo_status_t

View file

@ -25,7 +25,10 @@
#include "cairoint.h"
#include <fontconfig/fontconfig.h>
#include <fontconfig/fcfreetype.h>
#include <freetype/freetype.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_OUTLINE_H
typedef struct {
cairo_font_t base;
@ -39,7 +42,6 @@ typedef struct {
FcPattern *pattern;
} cairo_ft_font_t;
#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0))
#define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
#define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
@ -99,25 +101,27 @@ cairo_ft_font_create (FT_Library ft_library, FcPattern *pattern)
}
FT_Face
cairo_ft_font_face (cairo_font_t *font)
cairo_ft_font_face (cairo_font_t *abstract_font)
{
cairo_ft_font_t *font = (cairo_ft_font_t *) abstract_font;
if (font == NULL)
return NULL;
return ((cairo_ft_font_t *) font)->face;
return font->face;
}
FcPattern *
cairo_ft_font_pattern (cairo_font_t *font)
cairo_ft_font_pattern (cairo_font_t *abstract_font)
{
cairo_ft_font_t *font = (cairo_ft_font_t *) abstract_font;
if (font == NULL)
return NULL;
return ((cairo_ft_font_t *) font)->pattern;
return font->pattern;
}
/* implement the backend interface */
static cairo_font_t *
@ -189,45 +193,43 @@ _cairo_ft_font_create (const char *family,
return font;
}
static cairo_font_t *
_cairo_ft_font_copy (cairo_font_t *font)
_cairo_ft_font_copy (void *abstract_font)
{
cairo_ft_font_t * ft_font_new = NULL;
cairo_ft_font_t * ft_font = NULL;
cairo_ft_font_t * font_new = NULL;
cairo_ft_font_t * font = abstract_font;
ft_font = (cairo_ft_font_t *)font;
if (font->base.backend != &cairo_ft_font_backend)
return NULL;
ft_font_new = (cairo_ft_font_t *)cairo_ft_font_create_for_ft_face (ft_font->face);
if (ft_font_new == NULL)
font_new = (cairo_ft_font_t *) cairo_ft_font_create_for_ft_face (font->face);
if (font_new == NULL)
return NULL;
if (ft_font_new != NULL && ft_font->pattern != NULL)
ft_font_new->pattern = FcPatternDuplicate (ft_font->pattern);
if (font_new != NULL && font->pattern != NULL)
font_new->pattern = FcPatternDuplicate (font->pattern);
return (cairo_font_t *)ft_font_new;
return (cairo_font_t *) font_new;
}
static void
_cairo_ft_font_destroy (cairo_font_t *font)
_cairo_ft_font_destroy (void *abstract_font)
{
cairo_ft_font_t * ft_font = NULL;
cairo_ft_font_t * font = abstract_font;
if (font == NULL)
return;
ft_font = (cairo_ft_font_t *)font;
if (font->face != NULL && font->owns_face)
FT_Done_Face (font->face);
if (ft_font->face != NULL && ft_font->owns_face)
FT_Done_Face (ft_font->face);
if (ft_font->pattern != NULL)
FcPatternDestroy (ft_font->pattern);
if (font->pattern != NULL)
FcPatternDestroy (font->pattern);
if (ft_font->ft_library && ft_font->owns_ft_library)
FT_Done_FreeType (ft_font->ft_library);
if (font->ft_library && font->owns_ft_library)
FT_Done_FreeType (font->ft_library);
free (ft_font);
free (font);
}
static void
@ -301,25 +303,19 @@ _install_font_matrix(cairo_matrix_t *matrix, FT_Face face)
0, 0);
}
static int
_utf8_to_glyphs (cairo_font_t *font,
const unsigned char *utf8,
double x0,
double y0,
cairo_glyph_t **glyphs,
size_t *nglyphs)
_utf8_to_glyphs (cairo_ft_font_t *font,
const unsigned char *utf8,
double x0,
double y0,
cairo_glyph_t **glyphs,
size_t *nglyphs)
{
cairo_ft_font_t *ft;
FT_Face face = font->face;
double x = 0., y = 0.;
size_t i;
FT_ULong *ucs4 = NULL;
if (font == NULL)
return 0;
ft = (cairo_ft_font_t *)font;
_utf8_to_ucs4 (utf8, &ucs4, nglyphs);
if (ucs4 == NULL)
@ -332,18 +328,18 @@ _utf8_to_glyphs (cairo_font_t *font,
return 0;
}
_install_font_matrix (&font->matrix, ft->face);
_install_font_matrix (&font->base.matrix, face);
for (i = 0; i < *nglyphs; i++)
{
(*glyphs)[i].index = FT_Get_Char_Index (ft->face, ucs4[i]);
(*glyphs)[i].index = FT_Get_Char_Index (face, ucs4[i]);
(*glyphs)[i].x = x0 + x;
(*glyphs)[i].y = y0 + y;
FT_Load_Glyph (ft->face, (*glyphs)[i].index, FT_LOAD_DEFAULT);
FT_Load_Glyph (face, (*glyphs)[i].index, FT_LOAD_DEFAULT);
x += DOUBLE_FROM_26_6 (ft->face->glyph->advance.x);
y -= DOUBLE_FROM_26_6 (ft->face->glyph->advance.y);
x += DOUBLE_FROM_26_6 (face->glyph->advance.x);
y -= DOUBLE_FROM_26_6 (face->glyph->advance.y);
}
free (ucs4);
@ -351,15 +347,16 @@ _utf8_to_glyphs (cairo_font_t *font,
}
static cairo_status_t
_cairo_ft_font_font_extents (cairo_font_t *font,
cairo_font_extents_t *extents)
_cairo_ft_font_font_extents (void *abstract_font,
cairo_font_extents_t *extents)
{
FT_Face face;
cairo_ft_font_t *font = abstract_font;
FT_Face face = font->face;
double scale_x, scale_y;
face = ((cairo_ft_font_t *)font)->face;
double upm = face->units_per_EM;
_cairo_matrix_compute_scale_factors (&font->matrix, &scale_x, &scale_y);
_cairo_matrix_compute_scale_factors (&font->base.matrix, &scale_x, &scale_y);
extents->ascent = face->ascender / upm * scale_y;
extents->descent = face->descender / upm * scale_y;
@ -371,17 +368,18 @@ _cairo_ft_font_font_extents (cairo_font_t *font,
}
static cairo_status_t
_cairo_ft_font_glyph_extents (cairo_font_t *font,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_text_extents_t *extents)
_cairo_ft_font_glyph_extents (void *abstract_font,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_text_extents_t *extents)
{
int i;
cairo_ft_font_t *font = abstract_font;
cairo_point_double_t origin;
cairo_point_double_t glyph_min, glyph_max;
cairo_point_double_t total_min, total_max;
FT_Error error;
FT_Face face = ((cairo_ft_font_t *)font)->face;
FT_Face face = font->face;
FT_GlyphSlot glyph = face->glyph;
FT_Glyph_Metrics *metrics = &glyph->metrics;
@ -400,7 +398,7 @@ _cairo_ft_font_glyph_extents (cairo_font_t *font,
origin.x = glyphs[0].x;
origin.y = glyphs[0].y;
_install_font_matrix (&font->matrix, face);
_install_font_matrix (&font->base.matrix, face);
for (i = 0; i < num_glyphs; i++)
{
@ -447,10 +445,11 @@ _cairo_ft_font_glyph_extents (cairo_font_t *font,
static cairo_status_t
_cairo_ft_font_text_extents (cairo_font_t *font,
const unsigned char *utf8,
cairo_text_extents_t *extents)
_cairo_ft_font_text_extents (void *abstract_font,
const unsigned char *utf8,
cairo_text_extents_t *extents)
{
cairo_ft_font_t *font = abstract_font;
cairo_glyph_t *glyphs;
size_t nglyphs;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
@ -463,17 +462,16 @@ _cairo_ft_font_text_extents (cairo_font_t *font,
}
return status;
}
static cairo_status_t
_cairo_ft_font_show_glyphs (cairo_font_t *font,
_cairo_ft_font_show_glyphs (void *abstract_font,
cairo_operator_t operator,
cairo_surface_t *source,
cairo_surface_t *surface,
const cairo_glyph_t *glyphs,
int num_glyphs)
{
cairo_ft_font_t *font = abstract_font;
cairo_status_t status;
int i;
cairo_ft_font_t *ft = NULL;
@ -491,7 +489,7 @@ _cairo_ft_font_show_glyphs (cairo_font_t *font,
ft = (cairo_ft_font_t *)font;
glyphslot = ft->face->glyph;
_install_font_matrix (&font->matrix, ft->face);
_install_font_matrix (&font->base.matrix, ft->face);
for (i = 0; i < num_glyphs; i++)
{
@ -566,7 +564,7 @@ _cairo_ft_font_show_glyphs (cairo_font_t *font,
}
static cairo_status_t
_cairo_ft_font_show_text (cairo_font_t *font,
_cairo_ft_font_show_text (void *abstract_font,
cairo_operator_t operator,
cairo_surface_t *source,
cairo_surface_t *surface,
@ -574,6 +572,7 @@ _cairo_ft_font_show_text (cairo_font_t *font,
double y0,
const unsigned char *utf8)
{
cairo_ft_font_t *font = abstract_font;
cairo_glyph_t *glyphs;
int num_glyphs;
@ -608,17 +607,20 @@ _cairo_ft_font_glyph_path (cairo_font_t *font,
}
static cairo_status_t
_cairo_ft_font_text_path (cairo_font_t *font,
cairo_path_t *path,
_cairo_ft_font_text_path (void *abstract_font,
cairo_path_t *path,
double x,
double y,
const unsigned char *utf8)
{
cairo_ft_font_t *font = abstract_font;
cairo_glyph_t *glyphs;
size_t nglyphs;
if (_utf8_to_glyphs (font, utf8, 0, 0, &glyphs, &nglyphs))
if (_utf8_to_glyphs (font, utf8, x, y, &glyphs, &nglyphs))
{
cairo_status_t res;
res = _cairo_ft_font_glyph_path (font, path, glyphs, nglyphs);
res = _cairo_ft_font_glyph_path (font, glyphs, nglyphs, path);
free (glyphs);
return res;
}
@ -651,6 +653,9 @@ cairo_ft_font_create_for_ft_face (FT_Face face)
const struct cairo_font_backend cairo_ft_font_backend = {
_cairo_ft_font_create,
_cairo_ft_font_copy,
_cairo_ft_font_destroy,
_cairo_ft_font_font_extents,
_cairo_ft_font_text_extents,
_cairo_ft_font_glyph_extents,
@ -658,7 +663,4 @@ const struct cairo_font_backend cairo_ft_font_backend = {
_cairo_ft_font_show_glyphs,
_cairo_ft_font_text_path,
_cairo_ft_font_glyph_path,
_cairo_ft_font_create,
_cairo_ft_font_copy,
_cairo_ft_font_destroy
};

View file

@ -1797,16 +1797,38 @@ _cairo_gstate_text_path (cairo_gstate_t *gstate,
const unsigned char *utf8)
{
cairo_status_t status;
cairo_matrix_t user_to_source;
cairo_matrix_t saved_font_matrix;
double x, y;
status = setup_text_rendering_context (gstate, &user_to_source);
if (status)
return status;
/* XXX: I believe this is correct, but it would be much more clear
to have some explicit current_point accesor functions, (one for
user- and one for device-space). */
if (gstate->has_current_point) {
x = gstate->current_point.x;
y = gstate->current_point.y;
} else {
x = 0;
y = 0;
cairo_matrix_transform_point (&gstate->ctm, &x, &y);
}
cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix);
cairo_matrix_multiply (&gstate->font->matrix, &gstate->ctm, &gstate->font->matrix);
status = _cairo_font_text_path (gstate->font,
&gstate->path,
utf8);
x, y,
utf8,
&gstate->path);
cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix);
restore_text_rendering_context (gstate, &user_to_source);
return status;
}
@ -1837,8 +1859,8 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate,
cairo_matrix_multiply (&gstate->font->matrix, &gstate->ctm, &gstate->font->matrix);
status = _cairo_font_glyph_path (gstate->font,
&gstate->path,
transformed_glyphs, num_glyphs);
transformed_glyphs, num_glyphs,
&gstate->path);
cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix);

View file

@ -250,51 +250,52 @@ typedef struct cairo_pen {
typedef struct cairo_color cairo_color_t;
typedef struct cairo_font_backend {
cairo_status_t (*font_extents) (cairo_font_t *font,
cairo_font_extents_t *extents);
cairo_status_t (*text_extents) (cairo_font_t *font,
const unsigned char *utf8,
cairo_text_extents_t *extents);
cairo_status_t (*glyph_extents) (cairo_font_t *font,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_text_extents_t *extents);
cairo_status_t (*show_text) (cairo_font_t *font,
cairo_operator_t operator,
cairo_surface_t *source,
cairo_surface_t *surface,
double x,
double y,
const unsigned char *utf8);
cairo_status_t (*show_glyphs) (cairo_font_t *font,
cairo_operator_t operator,
cairo_surface_t *source,
cairo_surface_t *surface,
const cairo_glyph_t *glyphs,
int num_glyphs);
cairo_status_t (*text_path) (cairo_font_t *font,
cairo_path_t *path,
const unsigned char *utf8);
cairo_status_t (*glyph_path) (cairo_font_t *font,
cairo_path_t *path,
cairo_glyph_t *glyphs,
int num_glyphs);
cairo_font_t *(*create) (const char *family,
cairo_font_slant_t slant,
cairo_font_weight_t weight);
cairo_font_t *(*create) (const char *family,
cairo_font_slant_t slant,
cairo_font_weight_t weight);
cairo_font_t *(*copy) (cairo_font_t *other);
cairo_font_t *(*copy) (void *font);
void (*destroy) (cairo_font_t *font);
void (*destroy) (void *font);
cairo_status_t (*font_extents) (void *font,
cairo_font_extents_t *extents);
cairo_status_t (*text_extents) (void *font,
const unsigned char *utf8,
cairo_text_extents_t *extents);
cairo_status_t (*glyph_extents) (void *font,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_text_extents_t *extents);
cairo_status_t (*show_text) (void *font,
cairo_operator_t operator,
cairo_surface_t *source,
cairo_surface_t *surface,
double x,
double y,
const unsigned char *utf8);
cairo_status_t (*show_glyphs) (void *font,
cairo_operator_t operator,
cairo_surface_t *source,
cairo_surface_t *surface,
const cairo_glyph_t *glyphs,
int num_glyphs);
cairo_status_t (*text_path) (void *font,
double x,
double y,
const unsigned char *utf8,
cairo_path_t *path);
cairo_status_t (*glyph_path) (void *font,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_path_t *path);
} cairo_font_backend_t;
/* concrete font backends */
@ -885,15 +886,16 @@ _cairo_font_show_glyphs (cairo_font_t *font,
extern cairo_int_status_t __internal_linkage
_cairo_font_text_path (cairo_font_t *font,
cairo_path_t *path,
const unsigned char *utf8);
double x,
double y,
const unsigned char *utf8,
cairo_path_t *path);
extern cairo_int_status_t __internal_linkage
_cairo_font_glyph_path (cairo_font_t *font,
cairo_path_t *path,
cairo_glyph_t *glyphs,
int num_glyphs);
int num_glyphs,
cairo_path_t *path);
/* cairo_hull.c */
extern cairo_status_t