LCOV - code coverage report
Current view: top level - gfx/cairo/cairo/src - cairo-type3-glyph-surface.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 191 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 15 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
       2             : /* cairo - a vector graphics library with display and print output
       3             :  *
       4             :  * Copyright © 2008 Adrian Johnson
       5             :  *
       6             :  * This library is free software; you can redistribute it and/or
       7             :  * modify it either under the terms of the GNU Lesser General Public
       8             :  * License version 2.1 as published by the Free Software Foundation
       9             :  * (the "LGPL") or, at your option, under the terms of the Mozilla
      10             :  * Public License Version 1.1 (the "MPL"). If you do not alter this
      11             :  * notice, a recipient may use your version of this file under either
      12             :  * the MPL or the LGPL.
      13             :  *
      14             :  * You should have received a copy of the LGPL along with this library
      15             :  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
      16             :  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
      17             :  * You should have received a copy of the MPL along with this library
      18             :  * in the file COPYING-MPL-1.1
      19             :  *
      20             :  * The contents of this file are subject to the Mozilla Public License
      21             :  * Version 1.1 (the "License"); you may not use this file except in
      22             :  * compliance with the License. You may obtain a copy of the License at
      23             :  * http://www.mozilla.org/MPL/
      24             :  *
      25             :  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
      26             :  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
      27             :  * the specific language governing rights and limitations.
      28             :  *
      29             :  * The Original Code is the cairo graphics library.
      30             :  *
      31             :  * The Initial Developer of the Original Code is Adrian Johnson.
      32             :  *
      33             :  * Contributor(s):
      34             :  *      Adrian Johnson <ajohnson@redneon.com>
      35             :  */
      36             : 
      37             : #include "cairoint.h"
      38             : 
      39             : #if CAIRO_HAS_FONT_SUBSET
      40             : 
      41             : #include "cairo-type3-glyph-surface-private.h"
      42             : #include "cairo-output-stream-private.h"
      43             : #include "cairo-recording-surface-private.h"
      44             : #include "cairo-analysis-surface-private.h"
      45             : #include "cairo-error-private.h"
      46             : #include "cairo-surface-clipper-private.h"
      47             : 
      48             : static const cairo_surface_backend_t cairo_type3_glyph_surface_backend;
      49             : 
      50             : static cairo_status_t
      51           0 : _cairo_type3_glyph_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper,
      52             :                                                         cairo_path_fixed_t *path,
      53             :                                                         cairo_fill_rule_t   fill_rule,
      54             :                                                         double              tolerance,
      55             :                                                         cairo_antialias_t   antialias)
      56             : {
      57           0 :     cairo_type3_glyph_surface_t *surface = cairo_container_of (clipper,
      58             :                                                                cairo_type3_glyph_surface_t,
      59             :                                                                clipper);
      60             : 
      61           0 :     if (path == NULL) {
      62           0 :         _cairo_output_stream_printf (surface->stream, "Q q\n");
      63           0 :         return CAIRO_STATUS_SUCCESS;
      64             :     }
      65             : 
      66           0 :     return _cairo_pdf_operators_clip (&surface->pdf_operators,
      67             :                                       path,
      68             :                                       fill_rule);
      69             : }
      70             : 
      71             : cairo_surface_t *
      72           0 : _cairo_type3_glyph_surface_create (cairo_scaled_font_t                   *scaled_font,
      73             :                                    cairo_output_stream_t                 *stream,
      74             :                                    cairo_type3_glyph_surface_emit_image_t emit_image,
      75             :                                    cairo_scaled_font_subsets_t           *font_subsets)
      76             : {
      77             :     cairo_type3_glyph_surface_t *surface;
      78             :     cairo_matrix_t invert_y_axis;
      79             : 
      80           0 :     if (unlikely (stream != NULL && stream->status))
      81           0 :         return _cairo_surface_create_in_error (stream->status);
      82             : 
      83           0 :     surface = malloc (sizeof (cairo_type3_glyph_surface_t));
      84           0 :     if (unlikely (surface == NULL))
      85           0 :         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
      86             : 
      87           0 :     _cairo_surface_init (&surface->base,
      88             :                          &cairo_type3_glyph_surface_backend,
      89             :                          NULL, /* device */
      90             :                          CAIRO_CONTENT_COLOR_ALPHA);
      91             : 
      92           0 :     surface->scaled_font = scaled_font;
      93           0 :     surface->stream = stream;
      94           0 :     surface->emit_image = emit_image;
      95             : 
      96             :     /* Setup the transform from the user-font device space to Type 3
      97             :      * font space. The Type 3 font space is defined by the FontMatrix
      98             :      * entry in the Type 3 dictionary. In the PDF backend this is an
      99             :      * identity matrix. */
     100           0 :     surface->cairo_to_pdf = scaled_font->scale_inverse;
     101           0 :     cairo_matrix_init_scale (&invert_y_axis, 1, -1);
     102           0 :     cairo_matrix_multiply (&surface->cairo_to_pdf, &surface->cairo_to_pdf, &invert_y_axis);
     103             : 
     104           0 :     _cairo_pdf_operators_init (&surface->pdf_operators,
     105             :                                surface->stream,
     106             :                                &surface->cairo_to_pdf,
     107             :                                font_subsets);
     108             : 
     109           0 :     _cairo_surface_clipper_init (&surface->clipper,
     110             :                                  _cairo_type3_glyph_surface_clipper_intersect_clip_path);
     111             : 
     112           0 :     return &surface->base;
     113             : }
     114             : 
     115             : static cairo_status_t
     116           0 : _cairo_type3_glyph_surface_emit_image (cairo_type3_glyph_surface_t *surface,
     117             :                                        cairo_image_surface_t       *image,
     118             :                                        cairo_matrix_t              *image_matrix)
     119             : {
     120             :     cairo_status_t status;
     121             : 
     122             :     /* The only image type supported by Type 3 fonts are 1-bit masks */
     123           0 :     image = _cairo_image_surface_coerce_to_format (image, CAIRO_FORMAT_A1);
     124           0 :     status = image->base.status;
     125           0 :     if (unlikely (status))
     126           0 :         return status;
     127             : 
     128           0 :     _cairo_output_stream_printf (surface->stream,
     129             :                                  "q %f %f %f %f %f %f cm\n",
     130             :                                  image_matrix->xx,
     131             :                                  image_matrix->xy,
     132             :                                  image_matrix->yx,
     133             :                                  image_matrix->yy,
     134             :                                  image_matrix->x0,
     135             :                                  image_matrix->y0);
     136             : 
     137           0 :     status = surface->emit_image (image, surface->stream);
     138           0 :     cairo_surface_destroy (&image->base);
     139             : 
     140           0 :     _cairo_output_stream_printf (surface->stream,
     141             :                                  "Q\n");
     142             : 
     143           0 :     return status;
     144             : }
     145             : 
     146             : static cairo_status_t
     147           0 : _cairo_type3_glyph_surface_emit_image_pattern (cairo_type3_glyph_surface_t *surface,
     148             :                                                cairo_image_surface_t       *image,
     149             :                                                const cairo_matrix_t              *pattern_matrix)
     150             : {
     151             :     cairo_matrix_t mat, upside_down;
     152             :     cairo_status_t status;
     153             : 
     154           0 :     if (image->width == 0 || image->height == 0)
     155           0 :         return CAIRO_STATUS_SUCCESS;
     156             : 
     157           0 :     mat = *pattern_matrix;
     158             : 
     159             :     /* Get the pattern space to user space matrix  */
     160           0 :     status = cairo_matrix_invert (&mat);
     161             : 
     162             :     /* cairo_pattern_set_matrix ensures the matrix is invertible */
     163           0 :     assert (status == CAIRO_STATUS_SUCCESS);
     164             : 
     165             :     /* Make this a pattern space to Type 3 font space matrix */
     166           0 :     cairo_matrix_multiply (&mat, &mat, &surface->cairo_to_pdf);
     167             : 
     168             :     /* PDF images are in a 1 unit by 1 unit image space. Turn the 1 by
     169             :      * 1 image upside down to convert to flip the Y-axis going from
     170             :      * cairo to PDF. Then scale the image up to the required size. */
     171           0 :     cairo_matrix_scale (&mat, image->width, image->height);
     172           0 :     cairo_matrix_init (&upside_down, 1, 0, 0, -1, 0, 1);
     173           0 :     cairo_matrix_multiply (&mat, &upside_down, &mat);
     174             : 
     175           0 :     return _cairo_type3_glyph_surface_emit_image (surface, image, &mat);
     176             : }
     177             : 
     178             : static cairo_status_t
     179           0 : _cairo_type3_glyph_surface_finish (void *abstract_surface)
     180             : {
     181           0 :     cairo_type3_glyph_surface_t *surface = abstract_surface;
     182             : 
     183           0 :     return _cairo_pdf_operators_fini (&surface->pdf_operators);
     184             : }
     185             : 
     186             : static cairo_int_status_t
     187           0 : _cairo_type3_glyph_surface_paint (void                  *abstract_surface,
     188             :                                   cairo_operator_t       op,
     189             :                                   const cairo_pattern_t *source,
     190             :                                   cairo_clip_t          *clip)
     191             : {
     192           0 :     cairo_type3_glyph_surface_t *surface = abstract_surface;
     193             :     const cairo_surface_pattern_t *pattern;
     194             :     cairo_image_surface_t *image;
     195             :     void *image_extra;
     196             :     cairo_status_t status;
     197             : 
     198           0 :     if (source->type != CAIRO_PATTERN_TYPE_SURFACE)
     199           0 :         return CAIRO_INT_STATUS_IMAGE_FALLBACK;
     200             : 
     201           0 :     status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
     202           0 :     if (unlikely (status))
     203           0 :         return status;
     204             : 
     205           0 :     pattern = (const cairo_surface_pattern_t *) source;
     206           0 :     status = _cairo_surface_acquire_source_image (pattern->surface,
     207             :                                                   &image, &image_extra);
     208           0 :     if (unlikely (status))
     209           0 :         goto fail;
     210             : 
     211           0 :     status = _cairo_type3_glyph_surface_emit_image_pattern (surface,
     212             :                                                             image,
     213             :                                                             &pattern->base.matrix);
     214             : 
     215             : fail:
     216           0 :     _cairo_surface_release_source_image (pattern->surface, image, image_extra);
     217             : 
     218           0 :     return status;
     219             : }
     220             : 
     221             : static cairo_int_status_t
     222           0 : _cairo_type3_glyph_surface_mask (void                   *abstract_surface,
     223             :                                  cairo_operator_t        op,
     224             :                                  const cairo_pattern_t  *source,
     225             :                                  const cairo_pattern_t  *mask,
     226             :                                  cairo_clip_t           *clip)
     227             : {
     228           0 :     return _cairo_type3_glyph_surface_paint (abstract_surface,
     229             :                                              op, mask,
     230             :                                              clip);
     231             : }
     232             : 
     233             : static cairo_int_status_t
     234           0 : _cairo_type3_glyph_surface_stroke (void                 *abstract_surface,
     235             :                                    cairo_operator_t      op,
     236             :                                    const cairo_pattern_t *source,
     237             :                                    cairo_path_fixed_t   *path,
     238             :                                    const cairo_stroke_style_t   *style,
     239             :                                    const cairo_matrix_t *ctm,
     240             :                                    const cairo_matrix_t *ctm_inverse,
     241             :                                    double                tolerance,
     242             :                                    cairo_antialias_t     antialias,
     243             :                                    cairo_clip_t         *clip)
     244             : {
     245           0 :     cairo_type3_glyph_surface_t *surface = abstract_surface;
     246             :     cairo_int_status_t status;
     247             : 
     248           0 :     status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
     249           0 :     if (unlikely (status))
     250           0 :         return status;
     251             : 
     252           0 :     return _cairo_pdf_operators_stroke (&surface->pdf_operators,
     253             :                                         path,
     254             :                                         style,
     255             :                                         ctm,
     256             :                                         ctm_inverse);
     257             : }
     258             : 
     259             : static cairo_int_status_t
     260           0 : _cairo_type3_glyph_surface_fill (void                   *abstract_surface,
     261             :                                  cairo_operator_t        op,
     262             :                                  const cairo_pattern_t  *source,
     263             :                                  cairo_path_fixed_t     *path,
     264             :                                  cairo_fill_rule_t       fill_rule,
     265             :                                  double                  tolerance,
     266             :                                  cairo_antialias_t       antialias,
     267             :                                  cairo_clip_t           *clip)
     268             : {
     269           0 :     cairo_type3_glyph_surface_t *surface = abstract_surface;
     270             :     cairo_int_status_t status;
     271             : 
     272           0 :     status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
     273           0 :     if (unlikely (status))
     274           0 :         return status;
     275             : 
     276           0 :     return _cairo_pdf_operators_fill (&surface->pdf_operators,
     277             :                                       path,
     278             :                                       fill_rule);
     279             : }
     280             : 
     281             : static cairo_int_status_t
     282           0 : _cairo_type3_glyph_surface_show_glyphs (void                 *abstract_surface,
     283             :                                         cairo_operator_t      op,
     284             :                                         const cairo_pattern_t *source,
     285             :                                         cairo_glyph_t        *glyphs,
     286             :                                         int                   num_glyphs,
     287             :                                         cairo_scaled_font_t  *scaled_font,
     288             :                                         cairo_clip_t         *clip,
     289             :                                         int                  *remaining_glyphs)
     290             : {
     291           0 :     cairo_type3_glyph_surface_t *surface = abstract_surface;
     292             :     cairo_int_status_t status;
     293             :     cairo_scaled_font_t *font;
     294             :     cairo_matrix_t new_ctm, invert_y_axis;
     295             : 
     296           0 :     status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
     297           0 :     if (unlikely (status))
     298           0 :         return status;
     299             : 
     300           0 :     cairo_matrix_init_scale (&invert_y_axis, 1, -1);
     301           0 :     cairo_matrix_multiply (&new_ctm, &invert_y_axis, &scaled_font->ctm);
     302           0 :     cairo_matrix_multiply (&new_ctm, &surface->cairo_to_pdf, &new_ctm);
     303           0 :     font = cairo_scaled_font_create (scaled_font->font_face,
     304           0 :                                      &scaled_font->font_matrix,
     305             :                                      &new_ctm,
     306           0 :                                      &scaled_font->options);
     307           0 :     if (unlikely (font->status))
     308           0 :         return font->status;
     309             : 
     310           0 :     status = _cairo_pdf_operators_show_text_glyphs (&surface->pdf_operators,
     311             :                                                     NULL, 0,
     312             :                                                     glyphs, num_glyphs,
     313             :                                                     NULL, 0,
     314             :                                                     FALSE,
     315             :                                                     font);
     316             : 
     317           0 :     cairo_scaled_font_destroy (font);
     318             : 
     319           0 :     return status;
     320             : }
     321             : 
     322             : static const cairo_surface_backend_t cairo_type3_glyph_surface_backend = {
     323             :     CAIRO_INTERNAL_SURFACE_TYPE_TYPE3_GLYPH,
     324             :     NULL, /* _cairo_type3_glyph_surface_create_similar */
     325             :     _cairo_type3_glyph_surface_finish,
     326             :     NULL, /* acquire_source_image */
     327             :     NULL, /* release_source_image */
     328             :     NULL, /* acquire_dest_image */
     329             :     NULL, /* release_dest_image */
     330             :     NULL, /* clone_similar */
     331             :     NULL, /* composite */
     332             :     NULL, /* fill_rectangles */
     333             :     NULL, /* composite_trapezoids */
     334             :     NULL, /* create_span_renderer */
     335             :     NULL, /* check_span_renderer */
     336             :     NULL, /* cairo_type3_glyph_surface_copy_page */
     337             :     NULL, /* _cairo_type3_glyph_surface_show_page */
     338             :     NULL, /* _cairo_type3_glyph_surface_get_extents */
     339             :     NULL, /* old_show_glyphs */
     340             :     NULL, /* _cairo_type3_glyph_surface_get_font_options */
     341             :     NULL, /* flush */
     342             :     NULL, /* mark_dirty_rectangle */
     343             :     NULL, /* scaled_font_fini */
     344             :     NULL, /* scaled_glyph_fini */
     345             :     _cairo_type3_glyph_surface_paint,
     346             :     _cairo_type3_glyph_surface_mask,
     347             :     _cairo_type3_glyph_surface_stroke,
     348             :     _cairo_type3_glyph_surface_fill,
     349             :     _cairo_type3_glyph_surface_show_glyphs,
     350             :     NULL, /* snapshot */
     351             : };
     352             : 
     353             : static void
     354           0 : _cairo_type3_glyph_surface_set_stream (cairo_type3_glyph_surface_t *surface,
     355             :                                        cairo_output_stream_t       *stream)
     356             : {
     357           0 :     surface->stream = stream;
     358           0 :     _cairo_pdf_operators_set_stream (&surface->pdf_operators, stream);
     359           0 : }
     360             : 
     361             : static cairo_status_t
     362           0 : _cairo_type3_glyph_surface_emit_fallback_image (cairo_type3_glyph_surface_t *surface,
     363             :                                                 unsigned long                glyph_index)
     364             : {
     365             :     cairo_scaled_glyph_t *scaled_glyph;
     366             :     cairo_status_t status;
     367             :     cairo_image_surface_t *image;
     368             :     cairo_matrix_t mat;
     369             :     double x, y;
     370             : 
     371           0 :     status = _cairo_scaled_glyph_lookup (surface->scaled_font,
     372             :                                          glyph_index,
     373             :                                          CAIRO_SCALED_GLYPH_INFO_METRICS |
     374             :                                          CAIRO_SCALED_GLYPH_INFO_SURFACE,
     375             :                                          &scaled_glyph);
     376           0 :     if (unlikely (status))
     377           0 :         return status;
     378             : 
     379           0 :     image = scaled_glyph->surface;
     380           0 :     if (image->width == 0 || image->height == 0)
     381           0 :         return CAIRO_STATUS_SUCCESS;
     382             : 
     383           0 :     x = _cairo_fixed_to_double (scaled_glyph->bbox.p1.x);
     384           0 :     y = _cairo_fixed_to_double (scaled_glyph->bbox.p2.y);
     385           0 :     mat.xx = image->width;
     386           0 :     mat.xy = 0;
     387           0 :     mat.yx = 0;
     388           0 :     mat.yy = image->height;
     389           0 :     mat.x0 = x;
     390           0 :     mat.y0 = y;
     391           0 :     cairo_matrix_multiply (&mat, &mat, &surface->scaled_font->scale_inverse);
     392           0 :     mat.y0 *= -1;
     393             : 
     394           0 :     return _cairo_type3_glyph_surface_emit_image (surface, image, &mat);
     395             : }
     396             : 
     397             : void
     398           0 : _cairo_type3_glyph_surface_set_font_subsets_callback (void                                  *abstract_surface,
     399             :                                                       cairo_pdf_operators_use_font_subset_t  use_font_subset,
     400             :                                                       void                                  *closure)
     401             : {
     402           0 :     cairo_type3_glyph_surface_t *surface = abstract_surface;
     403             : 
     404           0 :     if (unlikely (surface->base.status))
     405           0 :         return;
     406             : 
     407           0 :     _cairo_pdf_operators_set_font_subsets_callback (&surface->pdf_operators,
     408             :                                                     use_font_subset,
     409             :                                                     closure);
     410             : }
     411             : 
     412             : cairo_status_t
     413           0 : _cairo_type3_glyph_surface_analyze_glyph (void               *abstract_surface,
     414             :                                           unsigned long       glyph_index)
     415             : {
     416           0 :     cairo_type3_glyph_surface_t *surface = abstract_surface;
     417             :     cairo_scaled_glyph_t *scaled_glyph;
     418             :     cairo_status_t status, status2;
     419             :     cairo_output_stream_t *null_stream;
     420             : 
     421           0 :     if (unlikely (surface->base.status))
     422           0 :         return surface->base.status;
     423             : 
     424           0 :     null_stream = _cairo_null_stream_create ();
     425           0 :     if (unlikely (null_stream->status))
     426           0 :         return null_stream->status;
     427             : 
     428           0 :     _cairo_type3_glyph_surface_set_stream (surface, null_stream);
     429             : 
     430           0 :     _cairo_scaled_font_freeze_cache (surface->scaled_font);
     431           0 :     status = _cairo_scaled_glyph_lookup (surface->scaled_font,
     432             :                                          glyph_index,
     433             :                                          CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE,
     434             :                                          &scaled_glyph);
     435             : 
     436           0 :     if (_cairo_status_is_error (status))
     437           0 :         goto cleanup;
     438             : 
     439           0 :     if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
     440           0 :         status = CAIRO_STATUS_SUCCESS;
     441           0 :         goto cleanup;
     442             :     }
     443             : 
     444           0 :     status = _cairo_recording_surface_replay (scaled_glyph->recording_surface,
     445             :                                               &surface->base);
     446           0 :     if (unlikely (status))
     447           0 :         goto cleanup;
     448             : 
     449           0 :     status = _cairo_pdf_operators_flush (&surface->pdf_operators);
     450           0 :     if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK)
     451           0 :         status = CAIRO_STATUS_SUCCESS;
     452             : 
     453             : cleanup:
     454           0 :     _cairo_scaled_font_thaw_cache (surface->scaled_font);
     455             : 
     456           0 :     status2 = _cairo_output_stream_destroy (null_stream);
     457           0 :     if (status == CAIRO_STATUS_SUCCESS)
     458           0 :         status = status2;
     459             : 
     460           0 :     return status;
     461             : }
     462             : 
     463             : cairo_status_t
     464           0 : _cairo_type3_glyph_surface_emit_glyph (void                  *abstract_surface,
     465             :                                        cairo_output_stream_t *stream,
     466             :                                        unsigned long          glyph_index,
     467             :                                        cairo_box_t           *bbox,
     468             :                                        double                *width)
     469             : {
     470           0 :     cairo_type3_glyph_surface_t *surface = abstract_surface;
     471             :     cairo_scaled_glyph_t *scaled_glyph;
     472             :     cairo_status_t status, status2;
     473             :     double x_advance, y_advance;
     474             :     cairo_matrix_t font_matrix_inverse;
     475             : 
     476           0 :     if (unlikely (surface->base.status))
     477           0 :         return surface->base.status;
     478             : 
     479           0 :     _cairo_type3_glyph_surface_set_stream (surface, stream);
     480             : 
     481           0 :     _cairo_scaled_font_freeze_cache (surface->scaled_font);
     482           0 :     status = _cairo_scaled_glyph_lookup (surface->scaled_font,
     483             :                                          glyph_index,
     484             :                                          CAIRO_SCALED_GLYPH_INFO_METRICS |
     485             :                                          CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE,
     486             :                                          &scaled_glyph);
     487           0 :     if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
     488           0 :         status = _cairo_scaled_glyph_lookup (surface->scaled_font,
     489             :                                              glyph_index,
     490             :                                              CAIRO_SCALED_GLYPH_INFO_METRICS,
     491             :                                              &scaled_glyph);
     492           0 :         if (status == CAIRO_STATUS_SUCCESS)
     493           0 :             status = CAIRO_INT_STATUS_IMAGE_FALLBACK;
     494             :     }
     495           0 :     if (_cairo_status_is_error (status)) {
     496           0 :         _cairo_scaled_font_thaw_cache (surface->scaled_font);
     497           0 :         return status;
     498             :     }
     499             : 
     500           0 :     x_advance = scaled_glyph->metrics.x_advance;
     501           0 :     y_advance = scaled_glyph->metrics.y_advance;
     502           0 :     font_matrix_inverse = surface->scaled_font->font_matrix;
     503           0 :     status2 = cairo_matrix_invert (&font_matrix_inverse);
     504             : 
     505             :     /* The invertability of font_matrix is tested in
     506             :      * pdf_operators_show_glyphs before any glyphs are mapped to the
     507             :      * subset. */
     508           0 :     assert (status2 == CAIRO_STATUS_SUCCESS);
     509             : 
     510           0 :     cairo_matrix_transform_distance (&font_matrix_inverse, &x_advance, &y_advance);
     511           0 :     *width = x_advance;
     512             : 
     513           0 :     *bbox = scaled_glyph->bbox;
     514           0 :     _cairo_matrix_transform_bounding_box_fixed (&surface->scaled_font->scale_inverse,
     515             :                                                 bbox, NULL);
     516             : 
     517           0 :     _cairo_output_stream_printf (surface->stream,
     518             :                                  "%f 0 %f %f %f %f d1\n",
     519             :                                  x_advance,
     520             :                                  _cairo_fixed_to_double (bbox->p1.x),
     521           0 :                                  - _cairo_fixed_to_double (bbox->p2.y),
     522             :                                  _cairo_fixed_to_double (bbox->p2.x),
     523           0 :                                  - _cairo_fixed_to_double (bbox->p1.y));
     524             : 
     525           0 :     if (status == CAIRO_STATUS_SUCCESS) {
     526             :         cairo_output_stream_t *mem_stream;
     527             : 
     528           0 :         mem_stream = _cairo_memory_stream_create ();
     529           0 :         status = mem_stream->status;
     530           0 :         if (unlikely (status))
     531           0 :             goto FAIL;
     532             : 
     533           0 :         _cairo_type3_glyph_surface_set_stream (surface, mem_stream);
     534             : 
     535           0 :         _cairo_output_stream_printf (surface->stream, "q\n");
     536           0 :         status = _cairo_recording_surface_replay (scaled_glyph->recording_surface,
     537             :                                                   &surface->base);
     538             : 
     539           0 :         status2 = _cairo_pdf_operators_flush (&surface->pdf_operators);
     540           0 :         if (status == CAIRO_STATUS_SUCCESS)
     541           0 :             status = status2;
     542             : 
     543           0 :         _cairo_output_stream_printf (surface->stream, "Q\n");
     544             : 
     545           0 :         _cairo_type3_glyph_surface_set_stream (surface, stream);
     546           0 :         if (status == CAIRO_STATUS_SUCCESS)
     547           0 :             _cairo_memory_stream_copy (mem_stream, stream);
     548             : 
     549           0 :         status2 = _cairo_output_stream_destroy (mem_stream);
     550           0 :         if (status == CAIRO_STATUS_SUCCESS)
     551           0 :             status = status2;
     552             :     }
     553             : 
     554           0 :     if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK)
     555           0 :         status = _cairo_type3_glyph_surface_emit_fallback_image (surface, glyph_index);
     556             : 
     557             :   FAIL:
     558           0 :     _cairo_scaled_font_thaw_cache (surface->scaled_font);
     559             : 
     560           0 :     return status;
     561             : }
     562             : 
     563             : #endif /* CAIRO_HAS_FONT_SUBSET */

Generated by: LCOV version 1.13