freetype-commit
[Top][All Lists]
Advanced

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

[Git][freetype/freetype][gsoc-anurag-2022] 19 commits: [base] Build outl


From: Anurag Thakur (@AdbhutDev)
Subject: [Git][freetype/freetype][gsoc-anurag-2022] 19 commits: [base] Build outlines in amortized constant time.
Date: Mon, 25 Jul 2022 20:00:28 +0000

Anurag Thakur pushed to branch gsoc-anurag-2022 at FreeType / FreeType

Commits:

  • 0417e54b
    by Ben Wagner at 2022-07-23T23:30:22+02:00
    [base] Build outlines in amortized constant time.
    
    When resizing the loader's points and contours, resize them to at least 1.5
    times their current size.  The code currently only reserves as much space as
    is currently required, leading to O(n^2) runtime when adding points one at a
    time.
    
    This change does not attempt to ever shrink the loader's point and contour
    storage since this was not attempted previously either.  The 1.5 multiple
    was chosen as a trade-off between potentially unused space and the runtime.
    
    * src/base/ftgloader.c (FT_GlyphLoader_CheckPoints): Implement it.
    
    Fixes #1173.
    
  • 9a00282e
    by Werner Lemberg at 2022-07-24T19:49:56+02:00
    * configure: s/egrep/grep -E/
    
    `egrep` is deprecated.
    
  • ad2c6a8a
    by Anurag Thakur at 2022-07-26T01:28:12+05:30
    Add files for new 'dense' module
    
  • b2ec4a9e
    by Anurag Thakur at 2022-07-26T01:28:12+05:30
    Populate errors header for 'dense' renderer
    
  • 63c7c627
    by Anurag Thakur at 2022-07-26T01:28:12+05:30
    Added things
    
  • 94fdeb11
    by Anurag Thakur at 2022-07-26T01:28:12+05:30
    Finish importing code, integration pending
    
  • b0797c36
    by Anurag Thakur at 2022-07-26T01:28:12+05:30
    Compilation fix attempt #1
    
  • 2949e255
    by Anurag Thakur at 2022-07-26T01:28:12+05:30
    Trying to get it to work attempt #1
    
  • 9630cb3d
    by Anurag Thakur at 2022-07-26T01:28:12+05:30
    Integration prototype successful
    
  • 916ceae3
    by Anurag Thakur at 2022-07-26T01:28:12+05:30
    Remove printfs
    
  • 2dd338e4
    by Anurag Thakur at 2022-07-26T01:28:12+05:30
    Added cmake build
    
  • 72378867
    by Anurag Thakur at 2022-07-26T01:28:12+05:30
    Added commentary
    
  • a172a761
    by Anurag Thakur at 2022-07-26T01:28:12+05:30
    Logging for testing
    
  • 61d7042b
    by Anurag Thakur at 2022-07-26T01:28:12+05:30
    Temp fix for upside-down bitmap
    
  • 4e157695
    by Anurag Thakur at 2022-07-26T01:28:12+05:30
    Partially move parameters to existing types
    
  • 60da5c4c
    by Anurag Thakur at 2022-07-26T01:28:12+05:30
    Fix quadratic rendering
    
  • 48e8106a
    by Anurag Thakur at 2022-07-26T01:28:12+05:30
    Use inbuilt data-types
    
  • 841b7efc
    by Anurag Thakur at 2022-07-26T01:28:12+05:30
    Revert unrelated changes
    
  • 84fa8a96
    by Anurag Thakur at 2022-07-26T01:28:12+05:30
    Insert newline at end
    

16 changed files:

Changes:

  • .gitignore
    ... ... @@ -5,3 +5,5 @@ src/dlg/dlg.c
    5 5
     subprojects/*
    
    6 6
     !subprojects/*.wrap
    
    7 7
     /tests/data/*
    
    8
    +.cache/*
    
    9
    +compile_commands.json

  • .vscode/settings.json
    1
    +{
    
    2
    +    "files.associations": {
    
    3
    +        "ftoutln.h": "c",
    
    4
    +        "svprop.h": "c",
    
    5
    +        "ftdebug.h": "c"
    
    6
    +    }
    
    7
    +}
    \ No newline at end of file

  • CMakeLists.txt
    ... ... @@ -395,6 +395,7 @@ set(BASE_SRCS
    395 395
       src/cache/ftcache.c
    
    396 396
       src/cff/cff.c
    
    397 397
       src/cid/type1cid.c
    
    398
    +  src/dense/dense.c
    
    398 399
       src/gzip/ftgzip.c
    
    399 400
       src/lzw/ftlzw.c
    
    400 401
       src/pcf/pcf.c
    

  • configure
    ... ... @@ -18,7 +18,7 @@ rm -f config.mk builds/unix/unix-def.mk builds/unix/unix-cc.mk
    18 18
     # respect GNUMAKE environment variable for backward compatibility
    
    19 19
     if test "x$GNUMAKE" = x; then
    
    20 20
       if test "x$MAKE" = x; then
    
    21
    -    if test "x`make -v 2>/dev/null | egrep 'GNU|makepp'`" = x; then
    
    21
    +    if test "x`make -v 2>/dev/null | grep -E 'GNU|makepp'`" = x; then
    
    22 22
           MAKE=gmake
    
    23 23
         else
    
    24 24
           MAKE=make
    
    ... ... @@ -28,7 +28,7 @@ else
    28 28
       MAKE=$GNUMAKE
    
    29 29
     fi
    
    30 30
     
    
    31
    -if test "x`$MAKE -v 2>/dev/null | egrep 'GNU|makepp'`" = x; then
    
    31
    +if test "x`$MAKE -v 2>/dev/null | grep -E 'GNU|makepp'`" = x; then
    
    32 32
       echo "GNU make (>= 3.81) or makepp (>= 2.0) is required to build FreeType2." >&2
    
    33 33
       echo "Please try" >&2
    
    34 34
       echo >&2
    

  • include/freetype/config/ftmodule.h
    ... ... @@ -24,6 +24,7 @@ FT_USE_MODULE( FT_Module_Class, psaux_module_class )
    24 24
     FT_USE_MODULE( FT_Module_Class, psnames_module_class )
    
    25 25
     FT_USE_MODULE( FT_Module_Class, pshinter_module_class )
    
    26 26
     FT_USE_MODULE( FT_Module_Class, sfnt_module_class )
    
    27
    +FT_USE_MODULE( FT_Renderer_Class, ft_dense_renderer_class )
    
    27 28
     FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class )
    
    28 29
     FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class )
    
    29 30
     FT_USE_MODULE( FT_Renderer_Class, ft_sdf_renderer_class )
    

  • modules.cfg
    ... ... @@ -93,9 +93,12 @@ HINTING_MODULES += pshinter
    93 93
     #### raster modules -- at least one is required for vector font formats
    
    94 94
     ####
    
    95 95
     
    
    96
    +RASTER_MODULES += dense
    
    96 97
     # Anti-aliasing rasterizer.
    
    97 98
     RASTER_MODULES += smooth
    
    98 99
     
    
    100
    +#RASTER_MODULES += dense
    
    101
    +
    
    99 102
     # Monochrome rasterizer.
    
    100 103
     RASTER_MODULES += raster
    
    101 104
     
    

  • src/base/ftgloadr.c
    ... ... @@ -212,7 +212,7 @@
    212 212
         FT_Outline*  current = &loader->current.outline;
    
    213 213
         FT_Bool      adjust  = 0;
    
    214 214
     
    
    215
    -    FT_UInt      new_max, old_max;
    
    215
    +    FT_UInt  new_max, old_max, min_new_max;
    
    216 216
     
    
    217 217
     
    
    218 218
         error = FT_GlyphLoader_CreateExtra( loader );
    
    ... ... @@ -226,14 +226,19 @@
    226 226
     
    
    227 227
         if ( new_max > old_max )
    
    228 228
         {
    
    229
    -      new_max = FT_PAD_CEIL( new_max, 8 );
    
    230
    -
    
    231 229
           if ( new_max > FT_OUTLINE_POINTS_MAX )
    
    232 230
           {
    
    233 231
             error = FT_THROW( Array_Too_Large );
    
    234 232
             goto Exit;
    
    235 233
           }
    
    236 234
     
    
    235
    +      min_new_max = old_max + ( old_max >> 1 );
    
    236
    +      if ( new_max < min_new_max )
    
    237
    +        new_max = min_new_max;
    
    238
    +      new_max = FT_PAD_CEIL( new_max, 8 );
    
    239
    +      if ( new_max > FT_OUTLINE_POINTS_MAX )
    
    240
    +        new_max = FT_OUTLINE_POINTS_MAX;
    
    241
    +
    
    237 242
           if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) ||
    
    238 243
                FT_RENEW_ARRAY( base->tags,   old_max, new_max ) )
    
    239 244
             goto Exit;
    
    ... ... @@ -265,14 +270,19 @@
    265 270
                   n_contours;
    
    266 271
         if ( new_max > old_max )
    
    267 272
         {
    
    268
    -      new_max = FT_PAD_CEIL( new_max, 4 );
    
    269
    -
    
    270 273
           if ( new_max > FT_OUTLINE_CONTOURS_MAX )
    
    271 274
           {
    
    272 275
             error = FT_THROW( Array_Too_Large );
    
    273 276
             goto Exit;
    
    274 277
           }
    
    275 278
     
    
    279
    +      min_new_max = old_max + ( old_max >> 1 );
    
    280
    +      if ( new_max < min_new_max )
    
    281
    +        new_max = min_new_max;
    
    282
    +      new_max = FT_PAD_CEIL( new_max, 4 );
    
    283
    +      if ( new_max > FT_OUTLINE_CONTOURS_MAX )
    
    284
    +        new_max = FT_OUTLINE_CONTOURS_MAX;
    
    285
    +
    
    276 286
           if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) )
    
    277 287
             goto Exit;
    
    278 288
     
    

  • src/dense/dense.c
    1
    +/** For building a single object of the entire module */
    
    2
    +#define FT_MAKE_OPTION_SINGLE_OBJECT
    
    3
    +
    
    4
    +#include "ftdense.c"
    
    5
    +#include "ftdenserend.c"
    
    6
    +/* END */

  • src/dense/ftdense.c
    1
    +/** The rasterizer for the 'dense' renderer */
    
    2
    +
    
    3
    +#include <stdio.h>
    
    4
    +#undef FT_COMPONENT
    
    5
    +#define FT_COMPONENT dense
    
    6
    +
    
    7
    +#include <freetype/ftoutln.h>
    
    8
    +#include <freetype/internal/ftcalc.h>
    
    9
    +#include <freetype/internal/ftdebug.h>
    
    10
    +#include <freetype/internal/ftobjs.h>
    
    11
    +#include "ftdense.h"
    
    12
    +
    
    13
    +#include <math.h>
    
    14
    +#include "ftdenseerrs.h"
    
    15
    +
    
    16
    +/* @QUES: Please explain all these defines. Why is PIXEL_BITS 8??*/
    
    17
    +#define PIXEL_BITS 8
    
    18
    +
    
    19
    +#define ONE_PIXEL  ( 1 << PIXEL_BITS )
    
    20
    +#define TRUNC( x ) (int)( ( x ) >> PIXEL_BITS )
    
    21
    +
    
    22
    +#define UPSCALE( x )   ( ( x ) * ( ONE_PIXEL >> 6 ) )
    
    23
    +#define DOWNSCALE( x ) ( ( x ) >> ( PIXEL_BITS - 6 ) )
    
    24
    +
    
    25
    +typedef struct dense_TRaster_
    
    26
    +{
    
    27
    +  void* memory;
    
    28
    +
    
    29
    +} dense_TRaster, *dense_PRaster;
    
    30
    +
    
    31
    +static FT_Vector
    
    32
    +Lerp( float aT, FT_Vector aP0, FT_Vector aP1 )
    
    33
    +{
    
    34
    +  FT_Vector p;
    
    35
    +  p.x = aP0.x + aT * ( aP1.x - aP0.x );
    
    36
    +  p.y = aP0.y + aT * ( aP1.y - aP0.y );
    
    37
    +  return p;
    
    38
    +}
    
    39
    +
    
    40
    +static int
    
    41
    +dense_move_to( const FT_Vector* to, dense_worker* worker )
    
    42
    +{
    
    43
    +  TPos x, y;
    
    44
    +
    
    45
    +  x              = UPSCALE( to->x );
    
    46
    +  y              = UPSCALE( to->y );
    
    47
    +  worker->prev_x = x;
    
    48
    +  worker->prev_y = y;
    
    49
    +  // printf( "last point is {%f, %f}", lp.m_x, lp.m_y );
    
    50
    +  return 0;
    
    51
    +}
    
    52
    +
    
    53
    +static int
    
    54
    +dense_line_to( const FT_Vector* to, dense_worker* worker )
    
    55
    +{
    
    56
    +  // printf( "dense_line_to: %d, %d\n", to->x, to->y );
    
    57
    +  dense_render_line( worker, UPSCALE( to->x ), UPSCALE( to->y ) );
    
    58
    +  dense_move_to( to, worker );
    
    59
    +  return 0;
    
    60
    +}
    
    61
    +void
    
    62
    +swap( long int* a, long int* b )
    
    63
    +{
    
    64
    +  long int temp = *a;
    
    65
    +  *a            = *b;
    
    66
    +  *b            = temp;
    
    67
    +}
    
    68
    +
    
    69
    +void
    
    70
    +swapold( unsigned char* a, unsigned char* b )
    
    71
    +{
    
    72
    +  unsigned char temp = *a;
    
    73
    +  *a                 = *b;
    
    74
    +  *b                 = temp;
    
    75
    +}
    
    76
    +
    
    77
    +void
    
    78
    +dense_render_line( dense_worker* worker, TPos to_x, TPos to_y )
    
    79
    +{
    
    80
    +  TPos from_x = worker->prev_x;
    
    81
    +  TPos from_y = worker->prev_y;
    
    82
    +  if ( from_y == to_y )
    
    83
    +    return;
    
    84
    +
    
    85
    +  /* @QUES: What is this code that I commented out, supposed to do?*/
    
    86
    +  // aP0.m_x -= worker->m_origin_x;
    
    87
    +  // aP0.m_y -= worker->m_origin_y;
    
    88
    +  // aP1.m_x -= worker->m_origin_x;
    
    89
    +  // aP1.m_y -= worker->m_origin_y;
    
    90
    +
    
    91
    +  from_x = TRUNC( (int)from_x );
    
    92
    +  from_y = TRUNC( (int)from_y );
    
    93
    +  to_x   = TRUNC( (int)to_x );
    
    94
    +  to_y   = TRUNC( (int)to_y );
    
    95
    +
    
    96
    +  float dir;
    
    97
    +  if ( from_y < to_y )
    
    98
    +    dir = 1;
    
    99
    +  else
    
    100
    +  {
    
    101
    +    dir = -1;
    
    102
    +    swap( &from_x, &to_x );
    
    103
    +    swap( &from_y, &to_y );
    
    104
    +  }
    
    105
    +
    
    106
    +  // Clip to the height.
    
    107
    +  if ( from_y >= worker->m_h || to_y <= 0 )
    
    108
    +    return;
    
    109
    +
    
    110
    +  float dxdy = ( to_x - from_x ) / (float)( to_y - from_y );
    
    111
    +  if ( from_y < 0 )
    
    112
    +  {
    
    113
    +    from_x -= from_y * dxdy;
    
    114
    +    from_y = 0;
    
    115
    +  }
    
    116
    +  if ( to_y > worker->m_h )
    
    117
    +  {
    
    118
    +    to_x -= ( to_y - worker->m_h ) * dxdy;
    
    119
    +    to_y = (float)worker->m_h;
    
    120
    +  }
    
    121
    +
    
    122
    +  /**
    
    123
    +  Handle parts of the line outside the clip rectangle by
    
    124
    +  snapping them to the left or right edge, or, if they intersect the clip area,
    
    125
    +  by recursive calls.
    
    126
    +  */
    
    127
    +
    
    128
    +  /* @QUES: This code isn't present in font-rs. It was added later by graham
    
    129
    +  asher I have a very strong feeling that this isn't necessary. Since probably
    
    130
    +  the outline is already fitted in the bounding box. I tested this code a
    
    131
    +  little, removing it doesn't seem to make any difference*/
    
    132
    +  FT_Vector intersect = { 0, 0 };
    
    133
    +  int       recursive = 0;
    
    134
    +  if ( from_x >= worker->m_w && to_x >= worker->m_w )
    
    135
    +  {
    
    136
    +    from_x = to_x = (float)worker->m_w;
    
    137
    +    dxdy          = 0;
    
    138
    +  }
    
    139
    +  else if ( from_x <= 0 && to_x <= 0 )
    
    140
    +  {
    
    141
    +    from_x = to_x = 0;
    
    142
    +    dxdy          = 0;
    
    143
    +  }
    
    144
    +  else if ( ( from_x < 0 ) != ( to_x < 0 ) )
    
    145
    +  {
    
    146
    +    intersect.x = 0;
    
    147
    +    intersect.y = to_y - to_x / dxdy;
    
    148
    +    recursive   = 1;
    
    149
    +  }
    
    150
    +  else if ( ( from_x > worker->m_w ) != ( to_x > worker->m_w ) )
    
    151
    +  {
    
    152
    +    intersect.x = worker->m_w;
    
    153
    +    intersect.y = from_y + ( worker->m_w - from_x ) / dxdy;
    
    154
    +    recursive   = 1;
    
    155
    +  }
    
    156
    +  if ( recursive )
    
    157
    +  {
    
    158
    +    from_x += worker->m_origin_x;
    
    159
    +    from_y += worker->m_origin_y;
    
    160
    +    to_x += worker->m_origin_x;
    
    161
    +    to_y += worker->m_origin_y;
    
    162
    +    intersect.x += worker->m_origin_x;
    
    163
    +    intersect.y += worker->m_origin_y;
    
    164
    +    if ( dir == 1 )
    
    165
    +    {
    
    166
    +      dense_render_line( worker, intersect.x, intersect.y );
    
    167
    +      dense_render_line( worker, to_x, to_y );
    
    168
    +    }
    
    169
    +    else
    
    170
    +    {
    
    171
    +      dense_render_line( worker, intersect.x, intersect.y );
    
    172
    +      dense_render_line( worker, from_x, from_y );
    
    173
    +    }
    
    174
    +    return;
    
    175
    +  }
    
    176
    +
    
    177
    +  /* @QUES: I am still trying to understand this code */
    
    178
    +  float  x       = from_x;
    
    179
    +  int    y0      = (int)from_y;
    
    180
    +  int    y_limit = (int)ceil( to_y );
    
    181
    +  float* m_a     = worker->m_a;
    
    182
    +
    
    183
    +  for ( int y = y0; y < y_limit; y++ )
    
    184
    +  {
    
    185
    +    int   linestart = y * worker->m_w;
    
    186
    +    float dy        = fmin( y + 1.0f, to_y ) - fmax( (float)y, from_y );
    
    187
    +    float xnext     = x + dxdy * dy;
    
    188
    +    float d         = dy * dir;
    
    189
    +
    
    190
    +    float x0, x1;
    
    191
    +    if ( x < xnext )
    
    192
    +    {
    
    193
    +      x0 = x;
    
    194
    +      x1 = xnext;
    
    195
    +    }
    
    196
    +    else
    
    197
    +    {
    
    198
    +      x0 = xnext;
    
    199
    +      x1 = x;
    
    200
    +    }
    
    201
    +
    
    202
    +    /*
    
    203
    +    It's possible for x0 to be negative on the last scanline because of
    
    204
    +    floating-point inaccuracy That would cause an out-of-bounds array access at
    
    205
    +    index -1.
    
    206
    +    */
    
    207
    +    float x0floor = x0 <= 0.0f ? 0.0f : (float)floor( x0 );
    
    208
    +
    
    209
    +    int   x0i    = (int)x0floor;
    
    210
    +    float x1ceil = (float)ceil( x1 );
    
    211
    +    int   x1i    = (int)x1ceil;
    
    212
    +    if ( x1i <= x0i + 1 )
    
    213
    +    {
    
    214
    +      float xmf = 0.5f * ( x + xnext ) - x0floor;
    
    215
    +      m_a[linestart + x0i] += d - d * xmf;
    
    216
    +      m_a[linestart + ( x0i + 1 )] += d * xmf;
    
    217
    +    }
    
    218
    +    else
    
    219
    +    {
    
    220
    +      float s   = 1.0f / ( x1 - x0 );
    
    221
    +      float x0f = x0 - x0floor;
    
    222
    +      float a0  = 0.5f * s * ( 1.0f - x0f ) * ( 1.0f - x0f );
    
    223
    +      float x1f = x1 - x1ceil + 1.0f;
    
    224
    +      float am  = 0.5f * s * x1f * x1f;
    
    225
    +      m_a[linestart + x0i] += d * a0;
    
    226
    +      if ( x1i == x0i + 2 )
    
    227
    +        m_a[linestart + ( x0i + 1 )] += d * ( 1.0f - a0 - am );
    
    228
    +      else
    
    229
    +      {
    
    230
    +        float a1 = s * ( 1.5f - x0f );
    
    231
    +        m_a[linestart + ( x0i + 1 )] += d * ( a1 - a0 );
    
    232
    +        for ( int xi = x0i + 2; xi < x1i - 1; xi++ )
    
    233
    +          m_a[linestart + xi] += d * s;
    
    234
    +        float a2 = a1 + ( x1i - x0i - 3 ) * s;
    
    235
    +        m_a[linestart + ( x1i - 1 )] += d * ( 1.0f - a2 - am );
    
    236
    +      }
    
    237
    +      m_a[linestart + x1i] += d * am;
    
    238
    +    }
    
    239
    +    x = xnext;
    
    240
    +  }
    
    241
    +}
    
    242
    +
    
    243
    +static int
    
    244
    +dense_conic_to( const FT_Vector* control,
    
    245
    +                const FT_Vector* to,
    
    246
    +                dense_worker*    worker )
    
    247
    +{
    
    248
    +  dense_render_quadratic( worker, control, to );
    
    249
    +  return 0;
    
    250
    +}
    
    251
    +
    
    252
    +void
    
    253
    +dense_render_quadratic( dense_worker*    worker,
    
    254
    +                        const FT_Vector* control,
    
    255
    +                        const FT_Vector* to )
    
    256
    +{
    
    257
    +  /*
    
    258
    +  Calculate devsq as the square of four times the
    
    259
    +  distance from the control point to the midpoint of the curve.
    
    260
    +  This is the place at which the curve is furthest from the
    
    261
    +  line joining the control points.
    
    262
    +
    
    263
    +  4 x point on curve = p0 + 2p1 + p2
    
    264
    +  4 x midpoint = 4p1
    
    265
    +
    
    266
    +  The division by four is omitted to save time.
    
    267
    +  */
    
    268
    +
    
    269
    +  FT_Vector aP0 = { worker->prev_x, worker->prev_y };
    
    270
    +  FT_Vector aP1 = { UPSCALE( control->x ), UPSCALE( control->y ) };
    
    271
    +  FT_Vector aP2 = { UPSCALE( to->x ), UPSCALE( to->y ) };
    
    272
    +
    
    273
    +  float devx  = aP0.x - aP1.x - aP1.x + aP2.x;
    
    274
    +  float devy  = aP0.y - aP1.y - aP1.y + aP2.y;
    
    275
    +  float devsq = devx * devx + devy * devy;
    
    276
    +
    
    277
    +  if ( devsq < 0.333f )
    
    278
    +  {
    
    279
    +    dense_render_line( worker, aP2.x, aP2.y );
    
    280
    +    worker->prev_x = aP2.x;
    
    281
    +    worker->prev_y = aP2.y;
    
    282
    +    return;
    
    283
    +  }
    
    284
    +
    
    285
    +  /*
    
    286
    +  According to Raph Levien, the reason for the subdivision by n (instead of
    
    287
    +  recursive division by the Casteljau system) is that "I expect the flatness
    
    288
    +  computation to be semi-expensive (it's done once rather than on each potential
    
    289
    +  subdivision) and also because you'll often get fewer subdivisions. Taking a
    
    290
    +  circular arc as a simplifying assumption, where I get n, a recursive approach
    
    291
    +  would get 2^ceil(lg n), which, if I haven't made any horrible mistakes, is
    
    292
    +  expected to be 33% more in the limit".
    
    293
    +  */
    
    294
    +
    
    295
    +  const float tol    = 3.0f;
    
    296
    +  int         n      = (int)floor( sqrt( sqrt( tol * devsq ) ) );
    
    297
    +  FT_Vector   p      = aP0;
    
    298
    +  float       nrecip = 1.0f / ( n + 1.0f );
    
    299
    +  float       t      = 0.0f;
    
    300
    +  for ( int i = 0; i < n; i++ )
    
    301
    +  {
    
    302
    +    t += nrecip;
    
    303
    +    FT_Vector next = Lerp( t, Lerp( t, aP0, aP1 ), Lerp( t, aP1, aP2 ) );
    
    304
    +    dense_render_line( worker, next.x, next.y );
    
    305
    +    worker->prev_x = next.x;
    
    306
    +    worker->prev_y = next.y;
    
    307
    +    p              = next;
    
    308
    +  }
    
    309
    +
    
    310
    +  dense_render_line( worker, aP2.x, aP2.y );
    
    311
    +  worker->prev_x = aP2.x;
    
    312
    +  worker->prev_y = aP2.y;
    
    313
    +}
    
    314
    +
    
    315
    +static int
    
    316
    +dense_cubic_to( const FT_Vector* control1,
    
    317
    +                const FT_Vector* control2,
    
    318
    +                const FT_Vector* to,
    
    319
    +                dense_worker*    worker )
    
    320
    +{
    
    321
    +  dense_render_cubic( worker, control1, control2, to );
    
    322
    +  return 0;
    
    323
    +}
    
    324
    +
    
    325
    +void
    
    326
    +dense_render_cubic( dense_worker* worker,
    
    327
    +                    FT_Vector*    aP1,
    
    328
    +                    FT_Vector*    aP2,
    
    329
    +                    FT_Vector*    aP3 )
    
    330
    +{
    
    331
    +  // assert( worker );
    
    332
    +  FT_Vector aP0    = { worker->prev_x, worker->prev_y };
    
    333
    +  float     devx   = aP0.x - aP1->x - aP1->x + aP2->x;
    
    334
    +  float     devy   = aP0.y - aP1->y - aP1->y + aP2->y;
    
    335
    +  float     devsq0 = devx * devx + devy * devy;
    
    336
    +  devx             = aP1->x - aP2->x - aP2->x + aP3->x;
    
    337
    +  devy             = aP1->y - aP2->y - aP2->y + aP3->y;
    
    338
    +  float devsq1     = devx * devx + devy * devy;
    
    339
    +  float devsq      = fmax( devsq0, devsq1 );
    
    340
    +
    
    341
    +  if ( devsq < 0.333f )
    
    342
    +  {
    
    343
    +    dense_render_line( worker, aP3->x, aP3->y );
    
    344
    +    return;
    
    345
    +  }
    
    346
    +
    
    347
    +  const float tol    = 3.0f;
    
    348
    +  int         n      = (int)floor( sqrt( sqrt( tol * devsq ) ) );
    
    349
    +  FT_Vector   p      = aP0;
    
    350
    +  float       nrecip = 1.0f / ( n + 1.0f );
    
    351
    +  float       t      = 0.0f;
    
    352
    +  for ( int i = 0; i < n; i++ )
    
    353
    +  {
    
    354
    +    t += nrecip;
    
    355
    +    FT_Vector a    = Lerp( t, Lerp( t, aP0, *aP1 ), Lerp( t, *aP1, *aP2 ) );
    
    356
    +    FT_Vector b    = Lerp( t, Lerp( t, *aP1, *aP2 ), Lerp( t, *aP2, *aP3 ) );
    
    357
    +    FT_Vector next = Lerp( t, a, b );
    
    358
    +    dense_render_line( worker, next.x, next.y );
    
    359
    +    worker->prev_x = next.x;
    
    360
    +    worker->prev_y = next.y;
    
    361
    +    p              = next;
    
    362
    +  }
    
    363
    +
    
    364
    +  dense_render_line( worker, aP3->x, aP3->y );
    
    365
    +  worker->prev_x = aP3->x;
    
    366
    +  worker->prev_y = aP3->y;
    
    367
    +}
    
    368
    +
    
    369
    +/* @QUES: This is the first method called on the module. I suspect
    
    370
    +this only initializes the memory for it*/
    
    371
    +static int
    
    372
    +dense_raster_new( FT_Memory memory, dense_PRaster* araster )
    
    373
    +{
    
    374
    +  FT_Error      error;
    
    375
    +  dense_PRaster raster;
    
    376
    +
    
    377
    +  if ( !FT_NEW( raster ) )
    
    378
    +    raster->memory = memory;
    
    379
    +
    
    380
    +  *araster = raster;
    
    381
    +  return error;
    
    382
    +}
    
    383
    +
    
    384
    +/* @QUES: This is a simple method, only frees memory*/
    
    385
    +static void
    
    386
    +dense_raster_done( FT_Raster raster )
    
    387
    +{
    
    388
    +
    
    389
    +  FT_Memory memory = (FT_Memory)( (dense_PRaster)raster )->memory;
    
    390
    +
    
    391
    +  FT_FREE( raster );
    
    392
    +}
    
    393
    +
    
    394
    +static void
    
    395
    +dense_raster_reset( FT_Raster      raster,
    
    396
    +                    unsigned char* pool_base,
    
    397
    +                    unsigned long  pool_size )
    
    398
    +{
    
    399
    +  FT_UNUSED( raster );
    
    400
    +  FT_UNUSED( pool_base );
    
    401
    +  FT_UNUSED( pool_size );
    
    402
    +}
    
    403
    +
    
    404
    +/* @QUES: This methodisnt't called in normal ftlint execution*/
    
    405
    +static int
    
    406
    +dense_raster_set_mode( FT_Raster raster, unsigned long mode, void* args )
    
    407
    +{
    
    408
    +  FT_UNUSED( raster );
    
    409
    +  FT_UNUSED( mode );
    
    410
    +  FT_UNUSED( args );
    
    411
    +
    
    412
    +  return 0; /* nothing to do */
    
    413
    +}
    
    414
    +
    
    415
    +FT_DEFINE_OUTLINE_FUNCS( dense_decompose_funcs,
    
    416
    +
    
    417
    +                         (FT_Outline_MoveTo_Func)dense_move_to,   /* move_to  */
    
    418
    +                         (FT_Outline_LineTo_Func)dense_line_to,   /* line_to  */
    
    419
    +                         (FT_Outline_ConicTo_Func)dense_conic_to, /* conic_to */
    
    420
    +                         (FT_Outline_CubicTo_Func)dense_cubic_to, /* cubic_to */
    
    421
    +
    
    422
    +                         0, /* shift    */
    
    423
    +                         0  /* delta    */
    
    424
    +)
    
    425
    +
    
    426
    +/* @QUES: So, this calls FT_Outline_Decompose, that calls the move to,
    
    427
    +line to, conic to, cubic to interface methods. The worker structure stores
    
    428
    +the well, stuff in its m_a and finally renders it to the target->buffer*/
    
    429
    +static int
    
    430
    +dense_render_glyph( dense_worker* worker, const FT_Bitmap* target )
    
    431
    +{
    
    432
    +  FT_Error error = FT_Outline_Decompose( &( worker->outline ),
    
    433
    +                                         &dense_decompose_funcs, worker );
    
    434
    +  // Render into bitmap
    
    435
    +  const float* source = worker->m_a;
    
    436
    +
    
    437
    +  unsigned char* dest     = target->buffer;
    
    438
    +  unsigned char* dest_end = target->buffer + worker->m_w * worker->m_h;
    
    439
    +  float          value    = 0.0f;
    
    440
    +  while ( dest < dest_end )
    
    441
    +  {
    
    442
    +    value += *source++;
    
    443
    +    if ( value > 0.0f )
    
    444
    +    {
    
    445
    +      int n = (int)( fabs( value ) * 255.0f + 0.5f );
    
    446
    +      if ( n > 255 )
    
    447
    +        n = 255;
    
    448
    +      *dest = (unsigned char)n;
    
    449
    +    }
    
    450
    +    else
    
    451
    +      *dest = 0;
    
    452
    +    dest++;
    
    453
    +  }
    
    454
    +
    
    455
    +  for ( int col = 0; col < worker->m_w; col++ )
    
    456
    +  {
    
    457
    +    for ( int row = 0; row < worker->m_h / 2; row++ )
    
    458
    +    {
    
    459
    +      // printf("Swapping position: %d, %d with %d, %d with rows = %d, cols =
    
    460
    +      // %d",row,col, worker->m_h-row, col, worker->m_h, worker->m_w);
    
    461
    +      swapold( target->buffer + worker->m_w * row + col,
    
    462
    +               target->buffer + ( worker->m_h - row - 1 ) * worker->m_w + col );
    
    463
    +    }
    
    464
    +  }
    
    465
    +
    
    466
    +  return error;
    
    467
    +}
    
    468
    +
    
    469
    +/* @QUES: The main rasterizing method, params.->target->buffer gets the
    
    470
    +rendered pixels*/
    
    471
    +static int
    
    472
    +dense_raster_render( FT_Raster raster, const FT_Raster_Params* params )
    
    473
    +{
    
    474
    +
    
    475
    +  const FT_Outline* outline    = (const FT_Outline*)params->source;
    
    476
    +  const FT_Bitmap*  target_map = params->target;
    
    477
    +
    
    478
    +  //dense_worker* worker = malloc( sizeof( dense_worker ) );
    
    479
    +  dense_worker worker[1];
    
    480
    +
    
    481
    +  if ( !raster )
    
    482
    +    return FT_THROW( Invalid_Argument );
    
    483
    +
    
    484
    +  if ( !outline )
    
    485
    +    return FT_THROW( Invalid_Outline );
    
    486
    +
    
    487
    +  worker->outline = *outline;
    
    488
    +
    
    489
    +  if ( !target_map )
    
    490
    +    return FT_THROW( Invalid_Argument );
    
    491
    +
    
    492
    +  /* nothing to do */
    
    493
    +  if ( !target_map->width || !target_map->rows )
    
    494
    +    return 0;
    
    495
    +
    
    496
    +  if ( !target_map->buffer )
    
    497
    +    return FT_THROW( Invalid_Argument );
    
    498
    +
    
    499
    +  worker->m_origin_x = 0;
    
    500
    +  worker->m_origin_y = 0;
    
    501
    +  /* @QUES: Why are my bitmaps upsied down 😭*/
    
    502
    +  worker->m_w = target_map->pitch;
    
    503
    +  worker->m_h = target_map->rows;
    
    504
    +
    
    505
    +  int size = worker->m_w * worker->m_h + 4;
    
    506
    +
    
    507
    +  worker->m_a      = malloc( sizeof( float ) * size );
    
    508
    +  worker->m_a_size = size;
    
    509
    +
    
    510
    +  memset( worker->m_a, 0, ( sizeof( float ) * size ) );
    
    511
    +  /* exit if nothing to do */
    
    512
    +  if ( worker->m_w <= worker->m_origin_x || worker->m_h <= worker->m_origin_y )
    
    513
    +  {
    
    514
    +    return 0;
    
    515
    +  }
    
    516
    +  return dense_render_glyph( worker, target_map );
    
    517
    +}
    
    518
    +
    
    519
    +FT_DEFINE_RASTER_FUNCS(
    
    520
    +    ft_dense_raster,
    
    521
    +
    
    522
    +    FT_GLYPH_FORMAT_OUTLINE,
    
    523
    +
    
    524
    +    (FT_Raster_New_Func)dense_raster_new,           /* raster_new      */
    
    525
    +    (FT_Raster_Reset_Func)dense_raster_reset,       /* raster_reset    */
    
    526
    +    (FT_Raster_Set_Mode_Func)dense_raster_set_mode, /* raster_set_mode */
    
    527
    +    (FT_Raster_Render_Func)dense_raster_render,     /* raster_render   */
    
    528
    +    (FT_Raster_Done_Func)dense_raster_done          /* raster_done     */
    
    529
    +)
    
    530
    +
    
    531
    +/* END */

  • src/dense/ftdense.h
    1
    +
    
    2
    +#ifndef FTDENSE_H_
    
    3
    +#define FTDENSE_H_
    
    4
    +
    
    5
    +#include <ft2build.h>
    
    6
    +#include FT_CONFIG_CONFIG_H
    
    7
    +#include <freetype/ftimage.h>
    
    8
    +
    
    9
    +FT_BEGIN_HEADER
    
    10
    +
    
    11
    +#ifndef FT_EXPORT_VAR
    
    12
    +#define FT_EXPORT_VAR( x ) extern x
    
    13
    +#endif
    
    14
    +FT_EXPORT_VAR( const FT_Raster_Funcs ) ft_dense_raster;
    
    15
    +
    
    16
    +/**
    
    17
    +RASTER_FP
    
    18
    +
    
    19
    +A floating-point anti-aliasing renderer.
    
    20
    +Graham Asher, August 2016.
    
    21
    +
    
    22
    +Most of this code is derived from Raph Levien's font-rs code in the Rust
    
    23
    +language, which is licensed under the Apache License, version 2.0.
    
    24
    +
    
    25
    +Licensed under the Apache License, Version 2.0 (the "License");
    
    26
    +you may not use this file except in compliance with the License.
    
    27
    +You may obtain a copy of the License at
    
    28
    +
    
    29
    +    http://www.apache.org/licenses/LICENSE-2.0
    
    30
    +
    
    31
    +Unless required by applicable law or agreed to in writing, software
    
    32
    +distributed under the License is distributed on an "AS IS" BASIS,
    
    33
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    
    34
    +See the License for the specific language governing permissions and
    
    35
    +limitations under the License.
    
    36
    +*/
    
    37
    +
    
    38
    +#ifdef __cplusplus
    
    39
    +extern "C"
    
    40
    +{
    
    41
    +#endif
    
    42
    +
    
    43
    +  typedef long TPos;
    
    44
    +
    
    45
    +  typedef struct
    
    46
    +  {
    
    47
    +    /** The array used to store signed area differences. */
    
    48
    +    float* m_a;
    
    49
    +    /** The number of elements in m_a. */
    
    50
    +    int m_a_size;
    
    51
    +    /** The width of the current raster in pixels. */
    
    52
    +    int m_w;
    
    53
    +    /** The height of the current raster in pixels. */
    
    54
    +    int m_h;
    
    55
    +    /** The x origin of the raster. */
    
    56
    +    int m_origin_x;
    
    57
    +    /** The y origin of the raster. */
    
    58
    +    int m_origin_y;
    
    59
    +
    
    60
    +    FT_Pos prev_x, prev_y;
    
    61
    +
    
    62
    +    FT_Outline outline;
    
    63
    +  } dense_worker;
    
    64
    +
    
    65
    +  void dense_render_line( dense_worker* aRasterFP, TPos to_x, TPos to_y );
    
    66
    +  void dense_render_quadratic( dense_worker*    aRasterFP,
    
    67
    +                               const FT_Vector* control,
    
    68
    +                               const FT_Vector* to );
    
    69
    +  void dense_render_cubic( dense_worker* aRasterFP,
    
    70
    +                           FT_Vector*    aP1,
    
    71
    +                           FT_Vector*    aP2,
    
    72
    +                           FT_Vector*    aP3 );
    
    73
    +
    
    74
    +#ifdef __cplusplus
    
    75
    +}  // extern "C"
    
    76
    +#endif
    
    77
    +
    
    78
    +FT_END_HEADER
    
    79
    +
    
    80
    +#endif /* FTDENSE_H_ */
    
    81
    +
    
    82
    +/* END */

  • src/dense/ftdenseerrs.h
    1
    +
    
    2
    +#ifndef FTDENSEERRS_H_
    
    3
    +#define FTDENSEERRS_H_
    
    4
    +
    
    5
    +#include <freetype/ftmoderr.h>
    
    6
    +
    
    7
    +#undef FTERRORS_H_
    
    8
    +
    
    9
    +#undef FT_ERR_PREFIX
    
    10
    +#define FT_ERR_PREFIX Dense_Err_
    
    11
    +#define FT_ERR_BASE   FT_Mod_Err_Dense
    
    12
    +
    
    13
    +#include <freetype/fterrors.h>
    
    14
    +
    
    15
    +#endif /* FTDENSEERRS_H_ */
    
    16
    +
    
    17
    +/* END */

  • src/dense/ftdenserend.c
    1
    +/** The 'dense' renderer */
    
    2
    +
    
    3
    +#include "ftdenserend.h"
    
    4
    +#include <freetype/ftbitmap.h>
    
    5
    +#include <freetype/ftoutln.h>
    
    6
    +#include <freetype/internal/ftdebug.h>
    
    7
    +#include <freetype/internal/ftobjs.h>
    
    8
    +#include <freetype/internal/services/svprop.h>
    
    9
    +#include "ftdense.h"
    
    10
    +
    
    11
    +#include "ftdenseerrs.h"
    
    12
    +
    
    13
    +/**************************************************************************
    
    14
    + *
    
    15
    + * The macro FT_COMPONENT is used in trace mode.  It is an implicit
    
    16
    + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
    
    17
    + * messages during execution.
    
    18
    + */
    
    19
    +#undef FT_COMPONENT
    
    20
    +#define FT_COMPONENT dense
    
    21
    +
    
    22
    +
    
    23
    +
    
    24
    +/**************************************************************************
    
    25
    + *
    
    26
    + * interface functions
    
    27
    + *
    
    28
    + */
    
    29
    +
    
    30
    +/* @QUES: So, I think this is used for setting up the
    
    31
    +initial properties of the renderer ??? */
    
    32
    +static FT_Error
    
    33
    +ft_dense_init( FT_Renderer render )
    
    34
    +{
    
    35
    +  return FT_Err_Ok;
    
    36
    +}
    
    37
    +
    
    38
    +/* @QUES: A destructor probably. The smooth renderer doesn't have this
    
    39
    +so, I guess this is unnecessary ??? */
    
    40
    +static void
    
    41
    +ft_dense_done( FT_Renderer render )
    
    42
    +{
    
    43
    +  FT_UNUSED( render );
    
    44
    +}
    
    45
    +
    
    46
    +/* generate bitmap from a glyph's slot image */
    
    47
    +
    
    48
    +/* @QUES: This method allocates the bitmap buffer, shifts the outlines
    
    49
    +as required (Why exactly is shifting required?), and finally calls 
    
    50
    +raster_render interface methods with correct params */
    
    51
    +static FT_Error
    
    52
    +ft_dense_render( FT_Renderer      render,
    
    53
    +                 FT_GlyphSlot     slot,
    
    54
    +                 FT_Render_Mode   mode,
    
    55
    +                 const FT_Vector* origin )
    
    56
    +{
    
    57
    +  FT_Error    error   = FT_Err_Ok;
    
    58
    +  FT_Outline* outline = &slot->outline;
    
    59
    +  FT_Bitmap*  bitmap  = &slot->bitmap;
    
    60
    +
    
    61
    +/* @QUES: You know, it should be a bit more clear that FT_FREE and FT_ALLOC_MULT macros
    
    62
    +take a variable named `memory`. It can only be known if you follow the macros 3 level deep.*/
    
    63
    +  FT_Memory   memory  = render->root.memory;
    
    64
    +
    
    65
    +  FT_Pos x_shift = 0;
    
    66
    +  FT_Pos y_shift = 0;
    
    67
    +
    
    68
    +  FT_Raster_Params params;
    
    69
    +
    
    70
    +  /* check whether slot format is correct before rendering */
    
    71
    +  if ( slot->format != render->glyph_format )
    
    72
    +  {
    
    73
    +    error = FT_THROW( Invalid_Glyph_Format );
    
    74
    +    goto Exit;
    
    75
    +  }
    
    76
    +
    
    77
    +
    
    78
    +  /* deallocate the previously allocated bitmap */
    
    79
    +  if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
    
    80
    +  {
    
    81
    +    FT_FREE( bitmap->buffer );
    
    82
    +    slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
    
    83
    +  }
    
    84
    +
    
    85
    +  /* preset the bitmap using the glyph's outline;         */
    
    86
    +  if ( ft_glyphslot_preset_bitmap( slot, mode, origin ) )
    
    87
    +  {
    
    88
    +    error = FT_THROW( Raster_Overflow );
    
    89
    +    goto Exit;
    
    90
    +  }
    
    91
    +
    
    92
    +  if ( !bitmap->rows || !bitmap->pitch )
    
    93
    +    goto Exit;
    
    94
    +
    
    95
    +
    
    96
    +  /* allocate new one */
    
    97
    +  if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) )
    
    98
    +    goto Exit;
    
    99
    +
    
    100
    +  /* @QUES: Where can I read more about why x and y shift are required */
    
    101
    +  x_shift = 64 * -slot->bitmap_left;
    
    102
    +  y_shift = 64 * -slot->bitmap_top;
    
    103
    +
    
    104
    +  /* @QUES: What does this flag mean ?*/
    
    105
    +  slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
    
    106
    +  y_shift += 64 * (FT_Int)bitmap->rows;
    
    107
    +
    
    108
    +  if ( origin )
    
    109
    +  {
    
    110
    +    x_shift += origin->x;
    
    111
    +    y_shift += origin->y;
    
    112
    +  }
    
    113
    +
    
    114
    +  /* translate outline to render it into the bitmap */
    
    115
    +  if ( x_shift || y_shift )
    
    116
    +    FT_Outline_Translate( outline, x_shift, y_shift );
    
    117
    +
    
    118
    +  /* set up parameters */
    
    119
    +  params.target = bitmap;
    
    120
    +  params.source = outline;
    
    121
    +
    
    122
    +  /* @QUES: Why is my final bitmap upside down ??🤔*/
    
    123
    +
    
    124
    +  /* render the outline */
    
    125
    +  error =
    
    126
    +      render->raster_render( render->raster, (const FT_Raster_Params*)&params );
    
    127
    +
    
    128
    +Exit:
    
    129
    +  if ( !error )
    
    130
    +  {
    
    131
    +    /* the glyph is successfully rendered to a bitmap */
    
    132
    +    slot->format = FT_GLYPH_FORMAT_BITMAP;
    
    133
    +  }
    
    134
    +  else if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
    
    135
    +  {
    
    136
    +    FT_FREE( bitmap->buffer );
    
    137
    +    slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
    
    138
    +  }
    
    139
    +
    
    140
    +  if ( x_shift || y_shift )
    
    141
    +    FT_Outline_Translate( outline, -x_shift, -y_shift );
    
    142
    +
    
    143
    +  return error;
    
    144
    +}
    
    145
    +
    
    146
    +/* transform the glyph using matrix and/or delta */
    
    147
    +/* @QUES: This mthod isn't called, atleast in normal ftlint execution.
    
    148
    +What is it for ?*/
    
    149
    +static FT_Error
    
    150
    +ft_dense_transform( FT_Renderer      render,
    
    151
    +                    FT_GlyphSlot     slot,
    
    152
    +                    const FT_Matrix* matrix,
    
    153
    +                    const FT_Vector* delta )
    
    154
    +{
    
    155
    +
    
    156
    +  FT_Error error = FT_Err_Ok;
    
    157
    +
    
    158
    +  if ( slot->format != render->glyph_format )
    
    159
    +  {
    
    160
    +    error = FT_THROW( Invalid_Argument );
    
    161
    +    goto Exit;
    
    162
    +  }
    
    163
    +
    
    164
    +  if ( matrix )
    
    165
    +    FT_Outline_Transform( &slot->outline, matrix );
    
    166
    +
    
    167
    +  if ( delta )
    
    168
    +    FT_Outline_Translate( &slot->outline, delta->x, delta->y );
    
    169
    +
    
    170
    +Exit:
    
    171
    +  return error;
    
    172
    +}
    
    173
    +
    
    174
    +/* return the control box of a glyph's outline */
    
    175
    +/* @QUES: This method isn't called either in normal ftlint execution*/
    
    176
    +static void
    
    177
    +ft_dense_get_cbox( FT_Renderer render, FT_GlyphSlot slot, FT_BBox* cbox )
    
    178
    +{
    
    179
    +
    
    180
    +  FT_ZERO( cbox );
    
    181
    +
    
    182
    +  if ( slot->format == render->glyph_format )
    
    183
    +    FT_Outline_Get_CBox( &slot->outline, cbox );
    
    184
    +}
    
    185
    +
    
    186
    +/* set render specific modes or attributes */
    
    187
    +/* @QUES: Isn't called in normal ftlint execution*/
    
    188
    +static FT_Error
    
    189
    +ft_dense_set_mode( FT_Renderer render, FT_ULong mode_tag, FT_Pointer data )
    
    190
    +{
    
    191
    +  /* pass it to the rasterizer */
    
    192
    +  return render->clazz->raster_class->raster_set_mode( render->raster, mode_tag,
    
    193
    +                                                       data );
    
    194
    +}
    
    195
    +
    
    196
    +FT_DEFINE_RENDERER(
    
    197
    +    ft_dense_renderer_class,
    
    198
    +
    
    199
    +    FT_MODULE_RENDERER,
    
    200
    +    sizeof( FT_RendererRec ),
    
    201
    +
    
    202
    +    "dense",
    
    203
    +    0x10000L,
    
    204
    +    0x20000L,
    
    205
    +
    
    206
    +    NULL,
    
    207
    +
    
    208
    +    (FT_Module_Constructor)ft_dense_init,
    
    209
    +    (FT_Module_Destructor)ft_dense_done,
    
    210
    +    (FT_Module_Requester)NULL,
    
    211
    +
    
    212
    +    FT_GLYPH_FORMAT_OUTLINE,
    
    213
    +
    
    214
    +    (FT_Renderer_RenderFunc)ft_dense_render,       /* render_glyph    */
    
    215
    +    (FT_Renderer_TransformFunc)ft_dense_transform, /* transform_glyph */
    
    216
    +    (FT_Renderer_GetCBoxFunc)ft_dense_get_cbox,    /* get_glyph_cbox  */
    
    217
    +    (FT_Renderer_SetModeFunc)ft_dense_set_mode,    /* set_mode        */
    
    218
    +
    
    219
    +    (FT_Raster_Funcs*)&ft_dense_raster /* raster_class    */
    
    220
    +)
    
    221
    +
    
    222
    +/* END */

  • src/dense/ftdenserend.h
    1
    +
    
    2
    +#ifndef FTDENSEREND_H_
    
    3
    +#define FTDENSEREND_H_
    
    4
    +
    
    5
    +
    
    6
    +#include <freetype/ftmodapi.h>
    
    7
    +#include <freetype/ftrender.h>
    
    8
    +#include <freetype/internal/ftobjs.h>
    
    9
    +
    
    10
    +FT_BEGIN_HEADER
    
    11
    +
    
    12
    +/**************************************************************************
    
    13
    + *
    
    14
    + * @renderer:
    
    15
    + *   ft_dense_renderer_class
    
    16
    + *
    
    17
    + * @description:
    
    18
    + *   Renderer to convert @FT_Outline to bitmaps.
    
    19
    + *
    
    20
    + */
    
    21
    +FT_DECLARE_RENDERER( ft_dense_renderer_class )
    
    22
    +
    
    23
    +FT_END_HEADER
    
    24
    +
    
    25
    +#endif /* FTDENSEREND_H_ */
    
    26
    +
    
    27
    +/* END */

  • src/dense/module.mk
    1
    +#
    
    2
    +# FreeType 2 smooth renderer module definition
    
    3
    +#
    
    4
    +
    
    5
    +
    
    6
    +# Copyright (C) 1996-2021 by
    
    7
    +# David Turner, Robert Wilhelm, and Werner Lemberg.
    
    8
    +#
    
    9
    +# This file is part of the FreeType project, and may only be used, modified,
    
    10
    +# and distributed under the terms of the FreeType project license,
    
    11
    +# LICENSE.TXT.  By continuing to use, modify, or distribute this file you
    
    12
    +# indicate that you have read the license and understand and accept it
    
    13
    +# fully.
    
    14
    +
    
    15
    +
    
    16
    +FTMODULE_H_COMMANDS += DENSE_RENDERER
    
    17
    +
    
    18
    +define DENSE_RENDERER
    
    19
    +$(OPEN_DRIVER) FT_Renderer_Class, ft_dense_renderer_class $(CLOSE_DRIVER)
    
    20
    +$(ECHO_DRIVER)dense     $(ECHO_DRIVER_DESC)anti-aliased dense renderer$(ECHO_DRIVER_DONE)
    
    21
    +endef
    
    22
    +
    
    23
    +# EOF

  • src/dense/rules.mk
    1
    +#
    
    2
    +# FreeType 2 DENSE renderer module build rules
    
    3
    +#
    
    4
    +
    
    5
    +
    
    6
    +# Copyright (C) 1996-2021 by
    
    7
    +# David Turner, Robert Wilhelm, and Werner Lemberg.
    
    8
    +#
    
    9
    +# This file is part of the FreeType project, and may only be used, modified,
    
    10
    +# and distributed under the terms of the FreeType project license,
    
    11
    +# LICENSE.TXT.  By continuing to use, modify, or distribute this file you
    
    12
    +# indicate that you have read the license and understand and accept it
    
    13
    +# fully.
    
    14
    +
    
    15
    +
    
    16
    +# DENSE driver directory
    
    17
    +#
    
    18
    +DENSE_DIR := $(SRC_DIR)/dense
    
    19
    +
    
    20
    +
    
    21
    +# compilation flags for the driver
    
    22
    +#
    
    23
    +DENSE_COMPILE := $(CC) $(ANSIFLAGS)                               \
    
    24
    +                        $I$(subst /,$(COMPILER_SEP),$(DENSE_DIR)) \
    
    25
    +                        $(INCLUDE_FLAGS)                           \
    
    26
    +                        $(FT_CFLAGS)
    
    27
    +
    
    28
    +
    
    29
    +# DENSE driver sources (i.e., C files)
    
    30
    +#
    
    31
    +DENSE_DRV_SRC := $(DENSE_DIR)/ftdense.c  \
    
    32
    +                  $(DENSE_DIR)/ftdenserend.c
    
    33
    +
    
    34
    +
    
    35
    +# DENSE driver headers
    
    36
    +#
    
    37
    +DENSE_DRV_H := $(DENSE_DRV_SRC:%c=%h)  \
    
    38
    +                $(DENSE_DIR)/ftdenseerrs.h
    
    39
    +
    
    40
    +
    
    41
    +# DENSE driver object(s)
    
    42
    +#
    
    43
    +#   DENSE_DRV_OBJ_M is used during `multi' builds.
    
    44
    +#   DENSE_DRV_OBJ_S is used during `single' builds.
    
    45
    +#
    
    46
    +DENSE_DRV_OBJ_M := $(DENSE_DRV_SRC:$(DENSE_DIR)/%.c=$(OBJ_DIR)/%.$O)
    
    47
    +DENSE_DRV_OBJ_S := $(OBJ_DIR)/dense.$O
    
    48
    +
    
    49
    +# DENSE driver source file for single build
    
    50
    +#
    
    51
    +DENSE_DRV_SRC_S := $(DENSE_DIR)/dense.c
    
    52
    +
    
    53
    +
    
    54
    +# DENSE driver - single object
    
    55
    +#
    
    56
    +$(DENSE_DRV_OBJ_S): $(DENSE_DRV_SRC_S) $(DENSE_DRV_SRC) \
    
    57
    +                     $(FREETYPE_H) $(DENSE_DRV_H)
    
    58
    +	$(DENSE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(DENSE_DRV_SRC_S))
    
    59
    +
    
    60
    +
    
    61
    +# DENSE driver - multiple objects
    
    62
    +#
    
    63
    +$(OBJ_DIR)/%.$O: $(DENSE_DIR)/%.c $(FREETYPE_H) $(DENSE_DRV_H)
    
    64
    +	$(DENSE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
    
    65
    +
    
    66
    +
    
    67
    +# update main driver object lists
    
    68
    +#
    
    69
    +DRV_OBJS_S += $(DENSE_DRV_OBJ_S)
    
    70
    +DRV_OBJS_M += $(DENSE_DRV_OBJ_M)
    
    71
    +
    
    72
    +
    
    73
    +# EOF

  • src/smooth/ftgrays.c
    ... ... @@ -876,10 +876,10 @@ typedef ptrdiff_t FT_PtrDist;
    876 876
         TCoord  fx1, fy1, fx2, fy2;
    
    877 877
         TCoord  ex1, ey1, ex2, ey2;
    
    878 878
     
    
    879
    -
    
    880 879
         ey1 = TRUNC( ras.y );
    
    881 880
         ey2 = TRUNC( to_y );
    
    882 881
     
    
    882
    +
    
    883 883
         /* perform vertical clipping */
    
    884 884
         if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) ||
    
    885 885
              ( ey1 <  ras.min_ey && ey2 <  ras.min_ey ) )
    


  • reply via email to

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