diff options
Diffstat (limited to 'src/cairo-gstate.c')
-rw-r--r-- | src/cairo-gstate.c | 556 |
1 files changed, 315 insertions, 241 deletions
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 563f84b4f..9f9de69e1 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -1,22 +1,37 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * 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. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * 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 * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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/ * - * Author: Carl D. Worth <cworth@isi.edu> + * 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 University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth <cworth@isi.edu> */ #include <stdlib.h> @@ -62,9 +77,9 @@ _cairo_gstate_init (cairo_gstate_t *gstate) gstate->num_dashes = 0; gstate->dash_offset = 0.0; - gstate->font = _cairo_font_create (CAIRO_FONT_FAMILY_DEFAULT, - CAIRO_FONT_SLANT_DEFAULT, - CAIRO_FONT_WEIGHT_DEFAULT); + gstate->font = _cairo_unscaled_font_create (CAIRO_FONT_FAMILY_DEFAULT, + CAIRO_FONT_SLANT_DEFAULT, + CAIRO_FONT_WEIGHT_DEFAULT); gstate->surface = NULL; @@ -104,11 +119,8 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other) } if (other->font) { - gstate->font = _cairo_font_copy (other->font); - if (!gstate->font) { - status = CAIRO_STATUS_NO_MEMORY; - goto CLEANUP_DASHES; - } + gstate->font = other->font; + _cairo_unscaled_font_reference (gstate->font); } if (other->clip.region) @@ -134,9 +146,10 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other) CLEANUP_PATH: _cairo_path_fini (&gstate->path); + CLEANUP_FONT: - cairo_font_destroy (gstate->font); - CLEANUP_DASHES: + _cairo_unscaled_font_destroy (gstate->font); + free (gstate->dash); gstate->dash = NULL; @@ -146,7 +159,7 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other) void _cairo_gstate_fini (cairo_gstate_t *gstate) { - cairo_font_destroy (gstate->font); + _cairo_unscaled_font_destroy (gstate->font); if (gstate->surface) cairo_surface_destroy (gstate->surface); @@ -162,6 +175,8 @@ _cairo_gstate_fini (cairo_gstate_t *gstate) cairo_pattern_destroy (gstate->pattern); + _cairo_matrix_fini (&gstate->font_matrix); + _cairo_matrix_fini (&gstate->ctm); _cairo_matrix_fini (&gstate->ctm_inverse); @@ -612,6 +627,8 @@ _cairo_gstate_default_matrix (cairo_gstate_t *gstate) if (scale == 0) scale = 1; + cairo_matrix_set_identity (&gstate->font_matrix); + cairo_matrix_set_identity (&gstate->ctm); cairo_matrix_scale (&gstate->ctm, scale, scale); cairo_matrix_copy (&gstate->ctm_inverse, &gstate->ctm); @@ -1968,16 +1985,28 @@ _cairo_gstate_show_surface (cairo_gstate_t *gstate, return CAIRO_STATUS_SUCCESS; } + cairo_status_t _cairo_gstate_select_font (cairo_gstate_t *gstate, const char *family, cairo_font_slant_t slant, cairo_font_weight_t weight) { - if (gstate->font != NULL) - cairo_font_destroy (gstate->font); + cairo_unscaled_font_t *tmp; + + tmp = _cairo_unscaled_font_create (family, slant, weight); + + if (tmp == NULL) + return CAIRO_STATUS_NO_MEMORY; - gstate->font = _cairo_font_create (family, slant, weight); + if (gstate->font != tmp) + { + if (gstate->font != NULL) + _cairo_unscaled_font_destroy (gstate->font); + + cairo_matrix_set_identity (&gstate->font_matrix); + gstate->font = tmp; + } return CAIRO_STATUS_SUCCESS; } @@ -1986,212 +2015,294 @@ cairo_status_t _cairo_gstate_scale_font (cairo_gstate_t *gstate, double scale) { - return _cairo_font_scale (gstate->font, scale); + return cairo_matrix_scale (&gstate->font_matrix, scale, scale); } cairo_status_t _cairo_gstate_transform_font (cairo_gstate_t *gstate, cairo_matrix_t *matrix) { - return _cairo_font_transform (gstate->font, matrix); + cairo_matrix_t tmp; + double a, b, c, d, tx, ty; + cairo_matrix_get_affine (matrix, &a, &b, &c, &d, &tx, &ty); + cairo_matrix_set_affine (&tmp, a, b, c, d, 0, 0); + return cairo_matrix_multiply (&gstate->font_matrix, &gstate->font_matrix, &tmp); } + cairo_status_t _cairo_gstate_current_font (cairo_gstate_t *gstate, cairo_font_t **font) { - *font = gstate->font; + cairo_font_scale_t scale; + cairo_font_t *scaled; + double dummy; + + scaled = malloc (sizeof (cairo_font_t)); + if (scaled == NULL) + return CAIRO_STATUS_NO_MEMORY; + + cairo_matrix_get_affine (&gstate->font_matrix, + &scale.matrix[0][0], + &scale.matrix[0][1], + &scale.matrix[1][0], + &scale.matrix[1][1], + &dummy, &dummy); + + _cairo_font_init (scaled, &scale, gstate->font); + _cairo_unscaled_font_reference (gstate->font); + + *font = scaled; return CAIRO_STATUS_SUCCESS; } -cairo_status_t -_cairo_gstate_current_font_extents (cairo_gstate_t *gstate, - cairo_font_extents_t *extents) +void +_cairo_gstate_set_font_transform (cairo_gstate_t *gstate, + cairo_matrix_t *matrix) { - cairo_int_status_t status; - cairo_matrix_t saved_font_matrix; - - cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix); - cairo_matrix_multiply (&gstate->font->matrix, &gstate->ctm, &gstate->font->matrix); - - status = _cairo_font_font_extents (gstate->font, extents); - - cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix); + cairo_matrix_copy (&gstate->font_matrix, matrix); +} - return status; +void +_cairo_gstate_current_font_transform (cairo_gstate_t *gstate, + cairo_matrix_t *matrix) +{ + cairo_matrix_copy (matrix, &gstate->font_matrix); } +/* + * Like everything else in this file, fonts involve Too Many Coordinate Spaces; + * it is easy to get confused about what's going on. + * + * The user's view + * --------------- + * + * Users ask for things in user space. When cairo starts, a user space unit + * is about 1/96 inch, which is similar to (but importantly different from) + * the normal "point" units most users think in terms of. When a user + * selects a font, its scale is set to "one user unit". The user can then + * independently scale the user coordinate system *or* the font matrix, in + * order to adjust the rendered size of the font. + * + * If the user asks for a permanent reference to "a font", they are given a + * handle to a structure holding a scale matrix and an unscaled font. This + * effectively decouples the font from further changes to user space. Even + * if the user then "sets" the current cairo_t font to the handle they were + * passed, further changes to the cairo_t CTM will not affect externally + * held references to the font. + * + * + * The font's view + * --------------- + * + * Fonts are designed and stored (in say .ttf files) in "font space", which + * describes an "EM Square" (a design tile) and has some abstract number + * such as 1000, 1024, or 2048 units per "EM". This is basically an + * uninteresting space for us, but we need to remember that it exists. + * + * Font resources (from libraries or operating systems) render themselves + * to a particular device. Since they do not want to make most programmers + * worry about the font design space, the scaling API is simplified to + * involve just telling the font the required pixel size of the EM square + * (that is, in device space). + * + * + * Cairo's gstate view + * ------------------- + * + * In addition to the CTM and CTM inverse, we keep a matrix in the gstate + * called the "font matrix" which describes the user's most recent + * font-scaling or font-transforming request. This is kept in terms of an + * abstract scale factor, composed with the CTM and used to set the font's + * pixel size. So if the user asks to "scale the font by 12", the matrix + * is: + * + * [ 12.0, 0.0, 0.0, 12.0, 0.0, 0.0 ] + * + * It is an affine matrix, like all cairo matrices, but its tx and ty + * components are always set to zero; we don't permit "nudging" fonts + * around. + * + * In order to perform any action on a font, we must build an object + * called a cairo_font_scale_t; this contains the central 2x2 matrix + * resulting from "font matrix * CTM". + * + * We pass this to the font when making requests of it, which causes it to + * reply for a particular [user request, device] combination, under the CTM + * (to accomodate the "zoom in" == "bigger fonts" issue above). + * + * The other terms in our communication with the font are therefore in + * device space. When we ask it to perform text->glyph conversion, it will + * produce a glyph string in device space. Glyph vectors we pass to it for + * measuring or rendering should be in device space. The metrics which we + * get back from the font will be in device space. The contents of the + * global glyph image cache will be in device space. + * + * + * Cairo's public view + * ------------------- + * + * Since the values entering and leaving via public API calls are in user + * space, the gstate functions typically need to multiply argumens by the + * CTM (for user-input glyph vectors), and return values by the CTM inverse + * (for font responses such as metrics or glyph vectors). + * + */ -cairo_status_t -_cairo_gstate_set_font (cairo_gstate_t *gstate, - cairo_font_t *font) +static void +_build_font_scale (cairo_gstate_t *gstate, + cairo_font_scale_t *sc) { - if (gstate->font != NULL) - cairo_font_destroy (gstate->font); - gstate->font = font; - cairo_font_reference (gstate->font); - return CAIRO_STATUS_SUCCESS; + cairo_matrix_t tmp; + double dummy; + cairo_matrix_multiply (&tmp, &gstate->font_matrix, &gstate->ctm); + cairo_matrix_get_affine (&tmp, + &sc->matrix[0][0], + &sc->matrix[0][1], + &sc->matrix[1][0], + &sc->matrix[1][1], + &dummy, &dummy); } cairo_status_t -_cairo_gstate_text_extents (cairo_gstate_t *gstate, - const unsigned char *utf8, - cairo_text_extents_t *extents) +_cairo_gstate_current_font_extents (cairo_gstate_t *gstate, + cairo_font_extents_t *extents) { - cairo_matrix_t saved_font_matrix; - cairo_status_t status; - double scale_x, scale_y; - - cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix); - _cairo_matrix_compute_scale_factors (&gstate->ctm, &scale_x, &scale_y); - cairo_matrix_scale (&gstate->font->matrix, scale_x, scale_y); - - status = _cairo_font_text_extents (gstate->font, - utf8, extents); - - cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix); + cairo_int_status_t status; + cairo_font_scale_t sc; + double dummy = 0.0; - extents->x_bearing /= scale_x; - extents->y_bearing /= scale_y; - extents->width /= scale_x; - extents->height /= scale_y; - extents->x_advance /= scale_x; - extents->y_advance /= scale_y; + _build_font_scale (gstate, &sc); - return status; -} + status = _cairo_unscaled_font_font_extents (gstate->font, &sc, extents); -cairo_status_t -_cairo_gstate_glyph_extents (cairo_gstate_t *gstate, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_text_extents_t *extents) -{ - cairo_status_t status; - cairo_matrix_t saved_font_matrix; - double scale_x, scale_y; + /* The font responded in device space; convert to user space. */ - cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix); - _cairo_matrix_compute_scale_factors (&gstate->ctm, &scale_x, &scale_y); - cairo_matrix_scale (&gstate->font->matrix, scale_x, scale_y); + cairo_matrix_transform_distance (&gstate->ctm_inverse, + &dummy, + &extents->ascent); - status = _cairo_font_glyph_extents (gstate->font, - glyphs, num_glyphs, - extents); + cairo_matrix_transform_distance (&gstate->ctm_inverse, + &dummy, + &extents->descent); - cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix); + cairo_matrix_transform_distance (&gstate->ctm_inverse, + &dummy, + &extents->height); - extents->x_bearing /= scale_x; - extents->y_bearing /= scale_y; - extents->width /= scale_x; - extents->height /= scale_y; - extents->x_advance /= scale_x; - extents->y_advance /= scale_y; + cairo_matrix_transform_distance (&gstate->ctm_inverse, + &extents->max_x_advance, + &extents->max_y_advance); return status; } cairo_status_t -_cairo_gstate_show_text (cairo_gstate_t *gstate, - const unsigned char *utf8) +_cairo_gstate_text_to_glyphs (cairo_gstate_t *gstate, + const unsigned char *utf8, + cairo_glyph_t **glyphs, + int *nglyphs) { cairo_status_t status; - cairo_point_t point; - double x, y; - cairo_matrix_t saved_font_matrix; - cairo_pattern_t pattern; - cairo_box_t bbox; + cairo_font_scale_t sc; + + cairo_point_t point; + double dev_x, dev_y; + int i; + + _build_font_scale (gstate, &sc); status = _cairo_path_current_point (&gstate->path, &point); if (status == CAIRO_STATUS_NO_CURRENT_POINT) { - x = 0; - y = 0; - cairo_matrix_transform_point (&gstate->ctm, &x, &y); + dev_x = 0.0; + dev_y = 0.0; } else { - x = _cairo_fixed_to_double (point.x); - y = _cairo_fixed_to_double (point.y); + dev_x = _cairo_fixed_to_double (point.x); + dev_y = _cairo_fixed_to_double (point.y); } - - cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix); - cairo_matrix_multiply (&gstate->font->matrix, &gstate->ctm, &gstate->font->matrix); - _cairo_pattern_init_copy (&pattern, gstate->pattern); - - status = _cairo_font_text_bbox (gstate->font, gstate->surface, - x, y, utf8, &bbox); - if (status) - return status; - - status = _cairo_gstate_create_pattern (gstate, &pattern, &bbox); - if (status) + status = _cairo_unscaled_font_text_to_glyphs (gstate->font, + &sc, utf8, glyphs, nglyphs); + + if (status || !glyphs || !nglyphs || !(*glyphs) || !(nglyphs)) return status; - - if (gstate->clip.surface) - { - cairo_surface_t *intermediate; - cairo_color_t empty_color; - _cairo_color_init (&empty_color); - _cairo_color_set_alpha (&empty_color, .0); - intermediate = _cairo_surface_create_similar_solid (gstate->clip.surface, - CAIRO_FORMAT_A8, - gstate->clip.width, - gstate->clip.height, - &empty_color); + /* The font responded in device space, starting from (0,0); add any + current point offset in device space, and convert to user space. */ - status = _cairo_font_show_text (gstate->font, - CAIRO_OPERATOR_ADD, pattern.source, - intermediate, - gstate->clip.x - pattern.source_offset.x, - gstate->clip.y - pattern.source_offset.y, - x - gstate->clip.x, - y - gstate->clip.y, utf8); + for (i = 0; i < *nglyphs; ++i) { + (*glyphs)[i].x += dev_x; + (*glyphs)[i].y += dev_y; + cairo_matrix_transform_point (&gstate->ctm_inverse, + &((*glyphs)[i].x), + &((*glyphs)[i].y)); + } + + return CAIRO_STATUS_SUCCESS; +} - if (status) - goto BAIL; - - status = _cairo_surface_composite (CAIRO_OPERATOR_IN, - gstate->clip.surface, - NULL, - intermediate, - 0, 0, - 0, 0, - 0, 0, - gstate->clip.width, - gstate->clip.height); +cairo_status_t +_cairo_gstate_set_font (cairo_gstate_t *gstate, + cairo_font_t *font) +{ + if (gstate->font != NULL) + _cairo_unscaled_font_destroy (gstate->font); + gstate->font = font->unscaled; + _cairo_unscaled_font_reference (gstate->font); + cairo_matrix_set_affine (&gstate->font_matrix, + font->scale.matrix[0][0], + font->scale.matrix[0][1], + font->scale.matrix[1][0], + font->scale.matrix[1][1], + 0, 0); + return CAIRO_STATUS_SUCCESS; +} - if (status) - goto BAIL; +cairo_status_t +_cairo_gstate_glyph_extents (cairo_gstate_t *gstate, + cairo_glyph_t *glyphs, + int num_glyphs, + cairo_text_extents_t *extents) +{ + cairo_status_t status; + cairo_glyph_t *transformed_glyphs; + cairo_font_scale_t sc; + int i; - status = _cairo_surface_composite (gstate->operator, - pattern.source, - intermediate, - gstate->surface, - 0, 0, - 0, 0, - gstate->clip.x, - gstate->clip.y, - gstate->clip.width, - gstate->clip.height); + _build_font_scale (gstate, &sc); - BAIL: - cairo_surface_destroy (intermediate); - - } - else + transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t)); + if (transformed_glyphs == NULL) + return CAIRO_STATUS_NO_MEMORY; + + for (i = 0; i < num_glyphs; ++i) { - status = _cairo_font_show_text (gstate->font, - gstate->operator, pattern.source, - gstate->surface, - -pattern.source_offset.x, - -pattern.source_offset.y, - x, y, utf8); + transformed_glyphs[i] = glyphs[i]; + cairo_matrix_transform_point (&gstate->ctm, + &transformed_glyphs[i].x, + &transformed_glyphs[i].y); } - - cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix); - _cairo_pattern_fini (&pattern); + status = _cairo_unscaled_font_glyph_extents (gstate->font, &sc, + transformed_glyphs, num_glyphs, + extents); + + /* The font responded in device space; convert to user space. */ + + cairo_matrix_transform_distance (&gstate->ctm_inverse, + &extents->x_bearing, + &extents->y_bearing); + + cairo_matrix_transform_distance (&gstate->ctm_inverse, + &extents->width, + &extents->height); + + cairo_matrix_transform_distance (&gstate->ctm_inverse, + &extents->x_advance, + &extents->y_advance); + + free (transformed_glyphs); return status; } @@ -2202,12 +2313,14 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, int num_glyphs) { cairo_status_t status; - cairo_matrix_t saved_font_matrix; int i; cairo_glyph_t *transformed_glyphs = NULL; + cairo_font_scale_t sc; cairo_pattern_t pattern; cairo_box_t bbox; + _build_font_scale (gstate, &sc); + transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t)); if (transformed_glyphs == NULL) return CAIRO_STATUS_NO_MEMORY; @@ -2216,16 +2329,14 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, { transformed_glyphs[i] = glyphs[i]; cairo_matrix_transform_point (&gstate->ctm, - &(transformed_glyphs[i].x), - &(transformed_glyphs[i].y)); + &transformed_glyphs[i].x, + &transformed_glyphs[i].y); } - cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix); - cairo_matrix_multiply (&gstate->font->matrix, &gstate->ctm, &gstate->font->matrix); - _cairo_pattern_init_copy (&pattern, gstate->pattern); - status = _cairo_font_glyph_bbox (gstate->font, gstate->surface, - transformed_glyphs, num_glyphs, &bbox); + status = _cairo_unscaled_font_glyph_bbox (gstate->font, &sc, + transformed_glyphs, num_glyphs, + &bbox); if (status) return status; @@ -2253,12 +2364,13 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, transformed_glyphs[i].y -= gstate->clip.y; } - status = _cairo_font_show_glyphs (gstate->font, - CAIRO_OPERATOR_ADD, - pattern.source, intermediate, - gstate->clip.x - pattern.source_offset.x, - gstate->clip.y - pattern.source_offset.y, - transformed_glyphs, num_glyphs); + status = _cairo_unscaled_font_show_glyphs (gstate->font, + &sc, + CAIRO_OPERATOR_ADD, + pattern.source, intermediate, + gstate->clip.x - pattern.source_offset.x, + gstate->clip.y - pattern.source_offset.y, + transformed_glyphs, num_glyphs); if (status) goto BAIL; @@ -2293,16 +2405,15 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, } else { - status = _cairo_font_show_glyphs (gstate->font, - gstate->operator, pattern.source, - gstate->surface, - -pattern.source_offset.x, - -pattern.source_offset.y, - transformed_glyphs, num_glyphs); + status = _cairo_unscaled_font_show_glyphs (gstate->font, + &sc, + gstate->operator, pattern.source, + gstate->surface, + -pattern.source_offset.x, + -pattern.source_offset.y, + transformed_glyphs, num_glyphs); } - cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix); - _cairo_pattern_fini (&pattern); free (transformed_glyphs); @@ -2310,40 +2421,6 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, return status; } - -cairo_status_t -_cairo_gstate_text_path (cairo_gstate_t *gstate, - const unsigned char *utf8) -{ - cairo_status_t status; - cairo_matrix_t saved_font_matrix; - cairo_point_t point; - double x, y; - - status = _cairo_path_current_point (&gstate->path, &point); - if (status == CAIRO_STATUS_NO_CURRENT_POINT) { - x = 0; - y = 0; - cairo_matrix_transform_point (&gstate->ctm, &x, &y); - } else { - x = _cairo_fixed_to_double (point.x); - y = _cairo_fixed_to_double (point.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, - x, y, - utf8, - &gstate->path); - - cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix); - - return status; -} - - cairo_status_t _cairo_gstate_glyph_path (cairo_gstate_t *gstate, cairo_glyph_t *glyphs, @@ -2352,7 +2429,9 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate, cairo_status_t status; int i; cairo_glyph_t *transformed_glyphs = NULL; - cairo_matrix_t saved_font_matrix; + cairo_font_scale_t sc; + + _build_font_scale (gstate, &sc); transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t)); if (transformed_glyphs == NULL) @@ -2366,14 +2445,9 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate, &(transformed_glyphs[i].y)); } - cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix); - cairo_matrix_multiply (&gstate->font->matrix, &gstate->ctm, &gstate->font->matrix); - - status = _cairo_font_glyph_path (gstate->font, - transformed_glyphs, num_glyphs, - &gstate->path); - - cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix); + status = _cairo_unscaled_font_glyph_path (gstate->font, &sc, + transformed_glyphs, num_glyphs, + &gstate->path); free (transformed_glyphs); return status; |