freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Git][freetype/freetype-demos][wl/freetype-demos-support-ot-svg-glyphs-n


From: Werner Lemberg (@wl)
Subject: [Git][freetype/freetype-demos][wl/freetype-demos-support-ot-svg-glyphs-new] More corrections, reformulations, formatting.
Date: Wed, 30 Mar 2022 12:51:35 +0000

Werner Lemberg pushed to branch wl/freetype-demos-support-ot-svg-glyphs-new at FreeType / FreeType Demo Programs

Commits:

3 changed files:

Changes:

  • src/ftcommon.c
    ... ... @@ -29,7 +29,6 @@
    29 29
     #include FT_FONT_FORMATS_H
    
    30 30
     #include FT_OTSVG_H
    
    31 31
     
    
    32
    -#include <rsvg-port.h>
    
    33 32
     
    
    34 33
       /* error messages */
    
    35 34
     #undef FTERRORS_H_
    
    ... ... @@ -40,6 +39,7 @@
    40 39
     #include "common.h"
    
    41 40
     #include "strbuf.h"
    
    42 41
     #include "ftcommon.h"
    
    42
    +#include "rsvg-port.h"
    
    43 43
     
    
    44 44
     #include <stdio.h>
    
    45 45
     #include <stdlib.h>
    
    ... ... @@ -340,10 +340,12 @@
    340 340
       {
    
    341 341
         FTDemo_Handle*  handle;
    
    342 342
     
    
    343
    -    SVG_RendererHooks  hooks = {(SVG_Lib_Init_Func)rsvg_port_init,
    
    344
    -                                (SVG_Lib_Free_Func)rsvg_port_free,
    
    345
    -                                (SVG_Lib_Render_Func)rsvg_port_render,
    
    346
    -                                (SVG_Lib_Preset_Slot_Func)rsvg_port_preset_slot};
    
    343
    +    SVG_RendererHooks  hooks = {
    
    344
    +                         (SVG_Lib_Init_Func)rsvg_port_init,
    
    345
    +                         (SVG_Lib_Free_Func)rsvg_port_free,
    
    346
    +                         (SVG_Lib_Render_Func)rsvg_port_render,
    
    347
    +                         (SVG_Lib_Preset_Slot_Func)rsvg_port_preset_slot };
    
    348
    +
    
    347 349
     
    
    348 350
         handle = (FTDemo_Handle *)malloc( sizeof ( FTDemo_Handle ) );
    
    349 351
         if ( !handle )
    
    ... ... @@ -355,6 +357,7 @@
    355 357
         if ( error )
    
    356 358
           PanicZ( "could not initialize FreeType" );
    
    357 359
     
    
    360
    +    /* XXX error handling? */
    
    358 361
         FT_Property_Set( handle->library, "ot-svg", "svg_hooks", &hooks );
    
    359 362
     
    
    360 363
         error = FTC_Manager_New( handle->library, 0, 0, 0,
    

  • src/rsvg-port.c
    ... ... @@ -2,11 +2,11 @@
    2 2
      *
    
    3 3
      * rsvg-port.c
    
    4 4
      *
    
    5
    - *   Librsvg based hook functions for OT-SVG rendering in FreeType.
    
    6
    - *   (implementation)
    
    5
    + *   Librsvg-based hook functions for OT-SVG rendering in FreeType
    
    6
    + *   (implementation).
    
    7 7
      *
    
    8
    - * Copyright (C) 1996-2021 by
    
    9
    - * David Turner, Robert Wilhelm, Werner Lemberg and Moazin Khatti.
    
    8
    + * Copyright (C) 2021 by
    
    9
    + * David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti.
    
    10 10
      *
    
    11 11
      * This file is part of the FreeType project, and may only be used,
    
    12 12
      * modified, and distributed under the terms of the FreeType project
    
    ... ... @@ -18,19 +18,21 @@
    18 18
     
    
    19 19
     #include <cairo.h>
    
    20 20
     #include <librsvg/rsvg.h>
    
    21
    -#include <rsvg-port.h>
    
    22
    -#include <ft2build.h>
    
    23 21
     #include <stdlib.h>
    
    24 22
     #include <math.h>
    
    23
    +
    
    24
    +#include <ft2build.h>
    
    25 25
     #include <freetype/freetype.h>
    
    26 26
     #include <freetype/ftbbox.h>
    
    27 27
     #include <freetype/otsvg.h>
    
    28 28
     
    
    29
    +#include "rsvg-port.h"
    
    29 30
     
    
    30
    -  /**
    
    31
    -   * The init hook is called when the first OT-SVG glyph is rendered.
    
    32
    -   * All we do is allocate an internal state structure and set the pointer
    
    33
    -   * in `library->svg_renderer_state`.  This state structure becomes very
    
    31
    +
    
    32
    +  /*
    
    33
    +   * The init hook is called when the first OT-SVG glyph is rendered.  All
    
    34
    +   * we do is to allocate an internal state structure and set the pointer in
    
    35
    +   * `library->svg_renderer_state`.  This state structure becomes very
    
    34 36
        * useful to cache some of the results obtained by one hook function that
    
    35 37
        * the other one might use.
    
    36 38
        */
    
    ... ... @@ -38,48 +40,49 @@
    38 40
       rsvg_port_init( FT_Pointer  *state )
    
    39 41
       {
    
    40 42
         /* allocate the memory upon initialization */
    
    41
    -    *state = malloc( sizeof( Rsvg_Port_StateRec ) );
    
    43
    +    *state = malloc( sizeof( Rsvg_Port_StateRec ) ); /* XXX error handling */
    
    44
    +
    
    42 45
         return FT_Err_Ok;
    
    43 46
       }
    
    44 47
     
    
    45 48
     
    
    46
    -  /**
    
    47
    -   * Freeing up the state structure.
    
    49
    +  /*
    
    50
    +   * Deallocate the state structure.
    
    48 51
        */
    
    49 52
       void
    
    50
    -  rsvg_port_free( FT_Pointer  *state)
    
    53
    +  rsvg_port_free( FT_Pointer  *state )
    
    51 54
       {
    
    52
    -    /* free the memory of the state structure */
    
    53 55
         free( *state );
    
    54 56
       }
    
    55 57
     
    
    56
    -  /**
    
    57
    -   * The render hook that's called to render.  The job of this hook is to
    
    58
    -   * simply render the glyph in the buffer that has been allocated on
    
    59
    -   * the FreeType side.  Here we simply use the recording surface by playing
    
    60
    -   * it back against the surface.
    
    58
    +
    
    59
    +  /*
    
    60
    +   * The render hook.  The job of this hook is to simply render the glyph in
    
    61
    +   * the buffer that has been allocated on the FreeType side.  Here we
    
    62
    +   * simply use the recording surface by playing it back against the
    
    63
    +   * surface.
    
    61 64
        */
    
    62 65
       FT_Error
    
    63
    -  rsvg_port_render( FT_GlyphSlot slot,
    
    64
    -                    FT_Pointer * _state )
    
    66
    +  rsvg_port_render( FT_GlyphSlot  slot,
    
    67
    +                    FT_Pointer   *_state )
    
    65 68
       {
    
    66
    -    FT_Error         error = FT_Err_Ok;
    
    69
    +    FT_Error  error = FT_Err_Ok;
    
    70
    +
    
    71
    +    Rsvg_Port_State   state;
    
    72
    +    cairo_status_t    status;
    
    73
    +    cairo_t          *cr;
    
    74
    +    cairo_surface_t  *surface;
    
    67 75
     
    
    68
    -    Rsvg_Port_State    state;
    
    69
    -    cairo_status_t     status;
    
    70
    -    cairo_t            *cr;
    
    71
    -    cairo_surface_t    *surface;
    
    72 76
     
    
    73 77
         state = *(Rsvg_Port_State*)_state;
    
    74 78
     
    
    75
    -    /* create an image surface to store the rendered image, however,
    
    76
    -     * don't allocate memory, instead use the space already provided
    
    77
    -     * in `slot->bitmap.buffer'.
    
    78
    -     */
    
    79
    +    /* Create an image surface to store the rendered image.  However,   */
    
    80
    +    /* don't allocate memory; instead use the space already provided in */
    
    81
    +    /* `slot->bitmap.buffer`.                                           */
    
    79 82
         surface = cairo_image_surface_create_for_data( slot->bitmap.buffer,
    
    80 83
                                                        CAIRO_FORMAT_ARGB32,
    
    81
    -                                                   slot->bitmap.width,
    
    82
    -                                                   slot->bitmap.rows,
    
    84
    +                                                   (int)slot->bitmap.width,
    
    85
    +                                                   (int)slot->bitmap.rows,
    
    83 86
                                                        slot->bitmap.pitch );
    
    84 87
         status = cairo_surface_status( surface );
    
    85 88
     
    
    ... ... @@ -102,12 +105,13 @@
    102 105
             return FT_Err_Invalid_Outline;
    
    103 106
         }
    
    104 107
     
    
    105
    -    /* set a translate transform that translates the points in such
    
    106
    -     * a way that we get a tight rendering with least redundant white
    
    107
    -     * space */
    
    108
    -    cairo_translate( cr, -1 * (state->x), -1 * (state->y) );
    
    109
    -    /* replay from the recorded surface.  Saves us from parsing the document
    
    110
    -     * again and redoing this already done in the preset hook. */
    
    108
    +    /* Set a translate transform that translates the points in such a way */
    
    109
    +    /* that we get a tight rendering with least redundant white spac.     */
    
    110
    +    cairo_translate( cr, -state->x, -state->y );
    
    111
    +
    
    112
    +    /* Replay from the recorded surface.  This saves us from parsing the */
    
    113
    +    /* document again and redoing what was already done in the preset    */
    
    114
    +    /* hook.                                                             */
    
    111 115
         cairo_set_source_surface( cr, state->rec_surface, 0.0, 0.0 );
    
    112 116
         cairo_paint( cr );
    
    113 117
     
    
    ... ... @@ -115,87 +119,88 @@
    115 119
     
    
    116 120
         slot->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA;
    
    117 121
         slot->bitmap.num_grays  = 256;
    
    118
    -    slot->format = FT_GLYPH_FORMAT_BITMAP;
    
    122
    +    slot->format            = FT_GLYPH_FORMAT_BITMAP;
    
    119 123
     
    
    120
    -    /* clean everything */
    
    124
    +    /* Clean up everything. */
    
    121 125
         cairo_surface_destroy( surface );
    
    122 126
         cairo_destroy( cr );
    
    123 127
         cairo_surface_destroy( state->rec_surface );
    
    128
    +
    
    124 129
         return error;
    
    125 130
       }
    
    126 131
     
    
    127
    -  /**
    
    132
    +
    
    133
    +  /*
    
    128 134
        * This hook is called at two different locations.  Firstly, it is called
    
    129
    -   * when presetting the glyphslot when FT_Load_Glyph is called.  Secondly,
    
    130
    -   * it is called right before the render hook is called.  When `cache` is
    
    131
    -   * false, it's the former while when `cache` is true, it's the latter.
    
    135
    +   * when presetting the glyphslot when `FT_Load_Glyph` is called.
    
    136
    +   * Secondly, it is called right before the render hook is called.  When
    
    137
    +   * `cache` is false, it is the former, when `cache` is true, it is the
    
    138
    +   * latter.
    
    132 139
        *
    
    133
    -   * The job of this function is to preset the slot setting the width, height,
    
    134
    -   * pitch, bitmap.left and bitmap.top.  These are all necessary for appropriate
    
    135
    -   * memory allocation as well as ultimately compositing the glyph later on by
    
    136
    -   * client applications.
    
    140
    +   * The job of this function is to preset the slot setting the width,
    
    141
    +   * height, pitch, `bitmap.left`, and `bitmap.top`.  These are all
    
    142
    +   * necessary for appropriate memory allocation, as well as ultimately
    
    143
    +   * compositing the glyph later on by client applications.
    
    137 144
        */
    
    138 145
       FT_Error
    
    139
    -  rsvg_port_preset_slot( FT_GlyphSlot  slot, FT_Bool  cache, FT_Pointer *_state )
    
    146
    +  rsvg_port_preset_slot( FT_GlyphSlot  slot,
    
    147
    +                         FT_Bool       cache,
    
    148
    +                         FT_Pointer   *_state )
    
    140 149
       {
    
    141
    -    /* FreeType variables */
    
    142
    -    FT_Error         error          = FT_Err_Ok;
    
    143
    -    FT_SVG_Document  document       = (FT_SVG_Document)slot->other;
    
    144
    -    FT_Size_Metrics  metrics        = document->metrics;
    
    145
    -    FT_UShort        units_per_EM   = document->units_per_EM;
    
    146
    -    FT_UShort        end_glyph_id   = document->end_glyph_id;
    
    147
    -    FT_UShort        start_glyph_id = document->start_glyph_id;
    
    148
    -
    
    149
    -    /* Librsvg variables */
    
    150
    -    GError             *gerror = NULL;
    
    151
    -    gboolean           ret;
    
    152
    -    gboolean           out_has_width;
    
    153
    -    gboolean           out_has_height;
    
    154
    -    gboolean           out_has_viewbox;
    
    150
    +    /* FreeType variables. */
    
    151
    +    FT_Error  error = FT_Err_Ok;
    
    152
    +
    
    153
    +    FT_SVG_Document  document = (FT_SVG_Document)slot->other;
    
    154
    +    FT_Size_Metrics  metrics  = document->metrics;
    
    155
    +
    
    156
    +    FT_UShort  units_per_EM   = document->units_per_EM;
    
    157
    +    FT_UShort  end_glyph_id   = document->end_glyph_id;
    
    158
    +    FT_UShort  start_glyph_id = document->start_glyph_id;
    
    159
    +
    
    160
    +    /* Librsvg variables. */
    
    161
    +    GError   *gerror = NULL;
    
    162
    +    gboolean  ret;
    
    163
    +
    
    164
    +    gboolean  out_has_width;
    
    165
    +    gboolean  out_has_height;
    
    166
    +    gboolean  out_has_viewbox;
    
    167
    +
    
    155 168
         RsvgHandle         *handle;
    
    156 169
         RsvgLength         out_width;
    
    157 170
         RsvgLength         out_height;
    
    158 171
         RsvgRectangle      out_viewbox;
    
    159 172
         RsvgDimensionData  dimension_svg;
    
    160
    -    cairo_t            *rec_cr;
    
    161
    -    cairo_matrix_t     transform_matrix;
    
    162 173
     
    
    163
    -    /* Rendering port's state */
    
    174
    +    cairo_t        *rec_cr;
    
    175
    +    cairo_matrix_t  transform_matrix;
    
    176
    +
    
    177
    +    /* Rendering port's state. */
    
    164 178
         Rsvg_Port_State     state;
    
    165 179
         Rsvg_Port_StateRec  state_dummy;
    
    166 180
     
    
    167
    -    /* general variables */
    
    168
    -    double  x;
    
    169
    -    double  y;
    
    170
    -    double  xx;
    
    171
    -    double  xy;
    
    172
    -    double  yx;
    
    173
    -    double  yy;
    
    174
    -    double  x0;
    
    175
    -    double  y0;
    
    176
    -    double  width;
    
    177
    -    double  height;
    
    178
    -    double  x_svg_to_out;
    
    179
    -    double  y_svg_to_out;
    
    180
    -
    
    181
    -    float metrics_width;
    
    182
    -    float metrics_height;
    
    183
    -    float horiBearingX;
    
    184
    -    float horiBearingY;
    
    185
    -    float vertBearingX;
    
    186
    -    float vertBearingY;
    
    187
    -    float vertical_advance;
    
    188
    -
    
    189
    -    /* if cache is `TRUE` we store calculations in the actual port
    
    190
    -     * state variable, otherwise we just create a dummy variable and
    
    191
    -     * store there.  This saves from too many if statements.
    
    192
    -     */
    
    181
    +    /* General variables. */
    
    182
    +    double  x, y;
    
    183
    +    double  xx, xy, yx, yy;
    
    184
    +    double  x0, y0;
    
    185
    +    double  width, height;
    
    186
    +    double  x_svg_to_out, y_svg_to_out;
    
    187
    +    double  tmpd;
    
    188
    +
    
    189
    +    float metrics_width, metrics_height;
    
    190
    +    float horiBearingX, horiBearingY;
    
    191
    +    float vertBearingX, vertBearingY;
    
    192
    +    float tmpf;
    
    193
    +
    
    194
    +
    
    195
    +    /* If `cache` is `TRUE` we store calculations in the actual port */
    
    196
    +    /* state variable, otherwise we just create a dummy variable and */
    
    197
    +    /* store there.  This saves us from too many 'if' statements.    */
    
    193 198
         if ( cache )
    
    194 199
           state = *(Rsvg_Port_State*)_state;
    
    195 200
         else
    
    196 201
           state = &state_dummy;
    
    197 202
     
    
    198
    -    /* form an RsvgHandle by loading the SVG document */
    
    203
    +    /* Form an `RsvgHandle` by loading the SVG document. */
    
    199 204
         handle = rsvg_handle_new_from_data( document->svg_document,
    
    200 205
                                             document->svg_document_length,
    
    201 206
                                             &gerror );
    
    ... ... @@ -205,7 +210,7 @@
    205 210
           goto CleanLibrsvg;
    
    206 211
         }
    
    207 212
     
    
    208
    -    /* get attributes like `viewBox` and `width/height`. */
    
    213
    +    /* Get attributes like `viewBox` and `width`/`height`. */
    
    209 214
         rsvg_handle_get_intrinsic_dimensions( handle,
    
    210 215
                                               &out_has_width,
    
    211 216
                                               &out_width,
    
    ... ... @@ -214,70 +219,71 @@
    214 219
                                               &out_has_viewbox,
    
    215 220
                                               &out_viewbox );
    
    216 221
     
    
    217
    -    /**
    
    222
    +    /*
    
    218 223
          * Figure out the units in the EM square in the SVG document.  This is
    
    219
    -     * specified by the ViewBox or the width/height attributes, if present,
    
    220
    -     * otherwise it should be assumed that the units in the EM square are
    
    221
    -     * the same as in the TTF/CFF outlines.
    
    224
    +     * specified by the `ViewBox` or the `width`/`height` attributes, if
    
    225
    +     * present, otherwise it should be assumed that the units in the EM
    
    226
    +     * square are the same as in the TTF/CFF outlines.
    
    222 227
          *
    
    223 228
          * TODO: I'm not sure what the standard says about the situation if
    
    224
    -     * the ViewBox as well as width/height are present, however, I've never
    
    225
    -     * seen that situation in real fonts.
    
    229
    +     * `ViewBox` as well as `width`/`height` are present; however, I've
    
    230
    +     * never seen that situation in real fonts.
    
    226 231
          */
    
    227 232
         if ( out_has_viewbox == TRUE )
    
    228 233
         {
    
    229
    -      dimension_svg.width  = out_viewbox.width;
    
    230
    -      dimension_svg.height = out_viewbox.height;
    
    234
    +      dimension_svg.width  = (int)out_viewbox.width; /* XXX rounding? */
    
    235
    +      dimension_svg.height = (int)out_viewbox.height;
    
    231 236
         }
    
    232
    -    else if ( ( out_has_width == TRUE ) && ( out_has_height == TRUE ) )
    
    237
    +    else if ( out_has_width == TRUE && out_has_height == TRUE )
    
    233 238
         {
    
    234
    -      dimension_svg.width  = out_width.length;
    
    235
    -      dimension_svg.height = out_height.length;
    
    239
    +      dimension_svg.width  = (int)out_width.length; /* XXX rounding? */
    
    240
    +      dimension_svg.height = (int)out_height.length;
    
    236 241
         }
    
    237 242
         else
    
    238 243
         {
    
    239
    -      /* if no `viewBox` and `width/height` are present, the `units_per_EM`
    
    240
    -       * in SVG coordinates must be the same as `units_per_EM` of the TTF/CFF
    
    241
    -       * outlines.
    
    242
    -       */
    
    244
    +      /* If neither `ViewBox` nor `width`/`height` are present, the */
    
    245
    +      /* `units_per_EM` in SVG coordinates must be the same as      */
    
    246
    +      /* `units_per_EM` of the TTF/CFF outlines.                    */
    
    243 247
           dimension_svg.width  = units_per_EM;
    
    244 248
           dimension_svg.height = units_per_EM;
    
    245 249
         }
    
    246 250
     
    
    247
    -    /* scale factors from SVG coordinates to the output size needed */
    
    248
    -    x_svg_to_out = (float)metrics.x_ppem/(float)dimension_svg.width;
    
    249
    -    y_svg_to_out = (float)metrics.y_ppem/(float)dimension_svg.height;
    
    251
    +    /* Scale factors from SVG coordinates to the needed output size. */
    
    252
    +    x_svg_to_out = (float)metrics.x_ppem / dimension_svg.width;
    
    253
    +    y_svg_to_out = (float)metrics.y_ppem / dimension_svg.height;
    
    250 254
     
    
    251
    -    /* create a cairo recording surface.  This is done for two reasons.
    
    255
    +    /*
    
    256
    +     * Create a cairo recording surface.  This is done for two reasons.
    
    252 257
          * Firstly, it is required to get the bounding box of the final drawing
    
    253
    -     * so we can use appropriate translate transform to get a tight rendering.
    
    254
    -     * Secondly, if `cache` is true, we can save this surface and later
    
    255
    -     * replay it against an image surface for the final rendering.  This save
    
    256
    -     * us from loading and parsing the document again.
    
    258
    +     * so we can use an appropriate translate transform to get a tight
    
    259
    +     * rendering.  Secondly, if `cache` is true, we can save this surface
    
    260
    +     * and later replay it against an image surface for the final rendering.
    
    261
    +     * This saves us from loading and parsing the document again.
    
    257 262
          */
    
    258
    -    state->rec_surface = cairo_recording_surface_create( CAIRO_CONTENT_COLOR_ALPHA,
    
    259
    -                                                         NULL );
    
    263
    +    state->rec_surface =
    
    264
    +      cairo_recording_surface_create( CAIRO_CONTENT_COLOR_ALPHA, NULL );
    
    260 265
     
    
    261 266
         rec_cr = cairo_create( state->rec_surface );
    
    262 267
     
    
    263
    -
    
    264
    -    /* we need to take into account any transformations applied.  The end
    
    268
    +    /*
    
    269
    +     * We need to take into account any transformations applied.  The end
    
    265 270
          * user who applied the transformation doesn't know the internal details
    
    266 271
          * of the SVG document.  Thus, we expect that the end user should just
    
    267
    -     * write the transformation as if the glyph is a traditional one.  We then,
    
    268
    -     * do some maths on this to get the equivalent transformation in SVG
    
    269
    -     * coordinates.
    
    272
    +     * write the transformation as if the glyph is a traditional one.  We
    
    273
    +     * then do some maths on this to get the equivalent transformation in
    
    274
    +     * SVG coordinates.
    
    270 275
          */
    
    271
    -    xx =  1 * (((double)document->transform.xx)/((double)(1 << 16 )));
    
    272
    -    xy = -1 * (((double)document->transform.xy)/((double)(1 << 16 )));
    
    273
    -    yx = -1 * (((double)document->transform.yx)/((double)(1 << 16 )));
    
    274
    -    yy =  1 * (((double)document->transform.yy)/((double)(1 << 16 )));
    
    275
    -    x0 =  1 * ((double)document->delta.x/(double)(1 << 6)) *
    
    276
    -              ((double)dimension_svg.width/(double)metrics.x_ppem);
    
    277
    -    y0 = -1 * ((double)document->delta.y/(double)(1 << 6)) *
    
    278
    -              ((double)dimension_svg.height/(double)metrics.y_ppem);
    
    279
    -
    
    280
    -    /* cairo stores transformation and translate both in one matrix */
    
    276
    +    xx =  (double)document->transform.xx / ( 1 << 16 );
    
    277
    +    xy = -(double)document->transform.xy / ( 1 << 16 );
    
    278
    +    yx = -(double)document->transform.yx / ( 1 << 16 );
    
    279
    +    yy =  (double)document->transform.yy / ( 1 << 16 );
    
    280
    +
    
    281
    +    x0 =  (double)document->delta.x / 64 *
    
    282
    +            dimension_svg.width / metrics.x_ppem;
    
    283
    +    y0 = -(double)document->delta.y / 64 *
    
    284
    +            dimension_svg.height / metrics.y_ppem;
    
    285
    +
    
    286
    +    /* Cairo stores both transformation and translation in one matrix. */
    
    281 287
         transform_matrix.xx = xx;
    
    282 288
         transform_matrix.yx = yx;
    
    283 289
         transform_matrix.xy = xy;
    
    ... ... @@ -285,18 +291,18 @@
    285 291
         transform_matrix.x0 = x0;
    
    286 292
         transform_matrix.y0 = y0;
    
    287 293
     
    
    288
    -    /* set up a scale transfromation to scale up the document to the
    
    289
    -     * required output size */
    
    294
    +    /* Set up a scale transformation to scale up the document to the */
    
    295
    +    /* required output size.                                         */
    
    290 296
         cairo_scale( rec_cr, x_svg_to_out, y_svg_to_out );
    
    291
    -    /* set up a transformation matrix */
    
    297
    +    /* Set up a transformation matrix. */
    
    292 298
         cairo_transform( rec_cr, &transform_matrix );
    
    293 299
     
    
    294
    -    /* if the document contains only one glyph, `start_glyph_id' and
    
    295
    -     * `end_glyph_id' will have the same value, else, `end_glyph_id'
    
    296
    -     * will be higher. */
    
    300
    +    /* If the document contains only one glyph, `start_glyph_id` and */
    
    301
    +    /* `end_glyph_id` have the same value.  Otherwise `end_glyph_id` */
    
    302
    +    /* is larger.                                                    */
    
    297 303
         if ( start_glyph_id == end_glyph_id )
    
    298 304
         {
    
    299
    -      /* render the whole document to the recording surface */
    
    305
    +      /* Render the whole document to the recording surface. */
    
    300 306
           ret = rsvg_handle_render_cairo ( handle, rec_cr );
    
    301 307
           if ( ret == FALSE )
    
    302 308
           {
    
    ... ... @@ -306,16 +312,12 @@
    306 312
         }
    
    307 313
         else if ( start_glyph_id < end_glyph_id )
    
    308 314
         {
    
    309
    -      int    length;
    
    310
    -      char*  str;
    
    311
    -
    
    312
    -      length = snprintf( NULL, 0, "%u", slot->glyph_index );
    
    313
    -      str    = (char*)malloc( 6 + length + 1 );
    
    314
    -      strcpy( str, "#glyph");
    
    315
    -      snprintf( str + 6, length + 1, "%u", slot->glyph_index );
    
    316
    -      /* render only the element with `id' equal to `glyph<ID>' */
    
    315
    +      char  str[32] = "#glyph";
    
    316
    +
    
    317
    +
    
    318
    +      /* Render only the element with its ID equal to `glyph<ID>`. */
    
    319
    +      sprintf( str + 6, "%u", slot->glyph_index );
    
    317 320
           ret = rsvg_handle_render_cairo_sub( handle, rec_cr, str );
    
    318
    -      free(str);
    
    319 321
           if ( ret == FALSE )
    
    320 322
           {
    
    321 323
             error = FT_Err_Invalid_SVG_Document;
    
    ... ... @@ -323,60 +325,76 @@
    323 325
           }
    
    324 326
         }
    
    325 327
     
    
    326
    -    /* get the bounding box of the drawing */
    
    328
    +    /* Get the bounding box of the drawing. */
    
    327 329
         cairo_recording_surface_ink_extents( state->rec_surface, &x, &y,
    
    328
    -                                         &width, &height);
    
    330
    +                                         &width, &height );
    
    329 331
     
    
    330
    -    /* we store the bounding box's `x` and `y` so that the render hook
    
    331
    -     * can apply a translation to get a tight rendering.
    
    332
    -     */
    
    332
    +    /* We store the bounding box's `x` and `y` values so that the render */
    
    333
    +    /* hook can apply a translation to get a tight rendering.            */
    
    333 334
         state->x = x;
    
    334 335
         state->y = y;
    
    335 336
     
    
    336
    -    /* preset the values */
    
    337
    -    slot->bitmap_left   = state->x ;
    
    338
    -    slot->bitmap_top    = (state->y) * -1;
    
    339
    -    slot->bitmap.rows   = ceil( height );
    
    340
    -    slot->bitmap.width  = ceil( width );
    
    341
    -    slot->bitmap.pitch  = slot->bitmap.width * 4;
    
    337
    +    /* Preset the values. */
    
    338
    +    slot->bitmap_left = (FT_Int) state->x;  /* XXX rounding? */
    
    339
    +    slot->bitmap_top  = (FT_Int)-state->y;
    
    340
    +
    
    341
    +    /* Do conversion in two steps to avoid 'bad function cast' warning. */
    
    342
    +    tmpd               = ceil( height );
    
    343
    +    slot->bitmap.rows  = (unsigned int)tmpd;
    
    344
    +    tmpd               = ceil( width );
    
    345
    +    slot->bitmap.width = (unsigned int)tmpd;
    
    346
    +
    
    347
    +    slot->bitmap.pitch = (int)slot->bitmap.width * 4;
    
    342 348
     
    
    343 349
         slot->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA;
    
    344 350
     
    
    345
    -    /* let's compute all the bearings and set them correctly.
    
    346
    -     * The outline is scaled already, we just need to use the
    
    347
    -     * bounding box now.
    
    348
    -     */
    
    349
    -    metrics_width = width;
    
    350
    -    metrics_height = height;
    
    351
    -    horiBearingX = state->x;
    
    352
    -    horiBearingY = state->y * -1;
    
    353
    -    vertBearingX = (slot->metrics.horiBearingX / (1 << 6)) - ((slot->metrics.horiAdvance / (1 << 6)) / 2.0);
    
    354
    -    vertBearingY = ((slot->metrics.vertAdvance / (1 << 6)) - (slot->metrics.height / (1 << 6)))/2.0;
    
    355
    -    slot->metrics.width =  round(metrics_width * (1 << 6));
    
    356
    -    slot->metrics.height = round(metrics_height * (1 << 6));
    
    357
    -    slot->metrics.horiBearingX = horiBearingX * (1 << 6);
    
    358
    -    slot->metrics.horiBearingY = horiBearingY * (1 << 6);
    
    359
    -    slot->metrics.vertBearingX = vertBearingX * (1 << 6);
    
    360
    -    slot->metrics.vertBearingY = vertBearingY * (1 << 6);
    
    361
    -    if(slot->metrics.vertAdvance == 0)
    
    362
    -        slot->metrics.vertAdvance = metrics_height * 1.2 * (1 << 6);
    
    363
    -
    
    364
    -    /* if a render call is to follow, just destroy the context for the
    
    365
    -     * recording surface, since no more drawing will be done on it, but,
    
    366
    -     * keep the surface itself for use by the render hook.
    
    367
    -     */
    
    351
    +    /* Compute all the bearings and set them correctly.  The outline is */
    
    352
    +    /* scaled already, we just need to use the bounding box.            */
    
    353
    +    metrics_width  = (float)width;
    
    354
    +    metrics_height = (float)height;
    
    355
    +
    
    356
    +    horiBearingX = (float) state->x;
    
    357
    +    horiBearingY = (float)-state->y;
    
    358
    +
    
    359
    +    vertBearingX = slot->metrics.horiBearingX / 64.0f -
    
    360
    +                     slot->metrics.horiAdvance / 64.0f / 2;
    
    361
    +    vertBearingY = ( slot->metrics.vertAdvance / 64.0f -
    
    362
    +                       slot->metrics.height / 64.0f ) / 2; /* XXX parentheses correct? */
    
    363
    +
    
    364
    +    /* Do conversion in two steps to avoid 'bad function cast' warning. */
    
    365
    +    tmpf                 = roundf( metrics_width * 64 );
    
    366
    +    slot->metrics.width  = (FT_Pos)tmpf;
    
    367
    +    tmpf                 = roundf( metrics_height * 64 );
    
    368
    +    slot->metrics.height = (FT_Pos)tmpf;
    
    369
    +
    
    370
    +    slot->metrics.horiBearingX = (FT_Pos)( horiBearingX * 64 ); /* XXX rounding? */
    
    371
    +    slot->metrics.horiBearingY = (FT_Pos)( horiBearingY * 64 );
    
    372
    +    slot->metrics.vertBearingX = (FT_Pos)( vertBearingX * 64 );
    
    373
    +    slot->metrics.vertBearingY = (FT_Pos)( vertBearingY * 64 );
    
    374
    +
    
    375
    +    if ( slot->metrics.vertAdvance == 0 )
    
    376
    +      slot->metrics.vertAdvance = (FT_Pos)( metrics_height * 1.2 * 64 );
    
    377
    +
    
    378
    +    /* If a render call is to follow, just destroy the context for the */
    
    379
    +    /* recording surface since no more drawing will be done on it.     */
    
    380
    +    /* However, keep the surface itself for use by the render hook.    */
    
    368 381
         if ( cache == TRUE )
    
    369 382
         {
    
    370 383
           cairo_destroy( rec_cr );
    
    371 384
           goto CleanLibrsvg;
    
    372 385
         }
    
    373 386
     
    
    374
    -    /* destroy the recording surface as well as the context */
    
    387
    +    /* Destroy the recording surface as well as the context. */
    
    375 388
       CleanCairo:
    
    376 389
         cairo_surface_destroy( state->rec_surface );
    
    377 390
         cairo_destroy( rec_cr );
    
    391
    +
    
    378 392
       CleanLibrsvg:
    
    379
    -    /* destroy the handle */
    
    393
    +    /* Destroy the handle. */
    
    380 394
         g_object_unref( handle );
    
    395
    +
    
    381 396
         return error;
    
    382 397
       }
    
    398
    +
    
    399
    +
    
    400
    +/* End */

  • src/rsvg-port.h
    ... ... @@ -2,10 +2,11 @@
    2 2
      *
    
    3 3
      * rsvg-port.h
    
    4 4
      *
    
    5
    - *   Librsvg based hook functions for OT-SVG rendering in FreeType. (headers)
    
    5
    + *   Librsvg based hook functions for OT-SVG rendering in FreeType
    
    6
    + *   (headers).
    
    6 7
      *
    
    7
    - * Copyright (C) 1996-2021 by
    
    8
    - * David Turner, Robert Wilhelm, Werner Lemberg and Moazin Khatti.
    
    8
    + * Copyright (C) 2021 by
    
    9
    + * David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti.
    
    9 10
      *
    
    10 11
      * This file is part of the FreeType project, and may only be used,
    
    11 12
      * modified, and distributed under the terms of the FreeType project
    
    ... ... @@ -23,32 +24,40 @@
    23 24
     #include <ft2build.h>
    
    24 25
     #include <freetype/freetype.h>
    
    25 26
     
    
    26
    -  /* Different hook functions can persist data by creating a state structure
    
    27
    -   * and putting its address in `library->svg_renderer_state`.  Functions can
    
    28
    -   * store and retrieve data from this structure
    
    27
    +
    
    28
    +  /*
    
    29
    +   * Different hook functions can access persisting data by creating a state
    
    30
    +   * structure and putting its address in `library->svg_renderer_state`.
    
    31
    +   * Functions can then store and retrieve data from this structure.
    
    29 32
        */
    
    30
    -  typedef struct Rsvg_Port_StateRec_
    
    33
    +  typedef struct  Rsvg_Port_StateRec_
    
    31 34
       {
    
    32
    -    cairo_surface_t    *rec_surface;
    
    33
    -    double             x;
    
    34
    -    double             y;
    
    35
    +    cairo_surface_t  *rec_surface;
    
    36
    +
    
    37
    +    double  x;
    
    38
    +    double  y;
    
    39
    +
    
    35 40
       } Rsvg_Port_StateRec;
    
    36 41
     
    
    37 42
       typedef struct Rsvg_Port_StateRec_*  Rsvg_Port_State;
    
    38 43
     
    
    44
    +
    
    39 45
       FT_Error
    
    40
    -  rsvg_port_init( FT_Pointer *state);
    
    46
    +  rsvg_port_init( FT_Pointer  *state );
    
    41 47
     
    
    42 48
       void
    
    43
    -  rsvg_port_free( FT_Pointer *state );
    
    49
    +  rsvg_port_free( FT_Pointer  *state );
    
    44 50
     
    
    45 51
       FT_Error
    
    46
    -  rsvg_port_render( FT_GlyphSlot slot,
    
    47
    -                    FT_Pointer *state );
    
    52
    +  rsvg_port_render( FT_GlyphSlot  slot,
    
    53
    +                    FT_Pointer   *state );
    
    48 54
     
    
    49 55
       FT_Error
    
    50 56
       rsvg_port_preset_slot( FT_GlyphSlot  slot,
    
    51
    -                         FT_Bool  cache,
    
    52
    -                         FT_Pointer *state);
    
    57
    +                         FT_Bool       cache,
    
    58
    +                         FT_Pointer   *state );
    
    59
    +
    
    60
    +#endif /* RSVG_PORT_H */
    
    61
    +
    
    53 62
     
    
    54
    -#endif
    63
    +/* End */


  • reply via email to

    [Prev in Thread] Current Thread [Next in Thread]