freetype-commit
[Top][All Lists]
Advanced

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

[Git][freetype/freetype][gsoc-anurag-2022-final] 32 commits: Add files f


From: Anurag Thakur (@AdbhutDev)
Subject: [Git][freetype/freetype][gsoc-anurag-2022-final] 32 commits: Add files for new 'dense' module
Date: Mon, 14 Nov 2022 04:49:21 +0000

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

Commits:

  • ae6966db
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Add files for new 'dense' module
    
  • a45b23b1
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Populate errors header for 'dense' renderer
    
  • 2dde8369
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Added things
    
  • 2675e079
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Finish importing code, integration pending
    
  • 15ad393e
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Compilation fix attempt #1
    
  • be75f776
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Trying to get it to work attempt #1
    
  • 3b6e6d75
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Integration prototype successful
    
  • 383cad3c
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Remove printfs
    
  • ef24dbfd
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Added cmake build
    
  • c79689fd
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Added commentary
    
  • 8cb431d7
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Logging for testing
    
  • dba1c48f
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Temp fix for upside-down bitmap
    
  • fb5e6cd3
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Partially move parameters to existing types
    
  • 662e1611
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Fix quadratic rendering
    
  • a5bf2446
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Use inbuilt data-types
    
  • 5dee8bc7
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Revert unrelated changes
    
  • e7bc58a3
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Insert newline at end
    
  • 66070d67
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Rebase and cleanup
    
  • 7328477b
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Fix antialiasing
    
  • f5feae75
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Free memory after use
    
  • dbd1a4c6
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Invert bitmap pitch
    
  • 2d5d1e25
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Remove redundant code
    
  • 4a1586ad
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Almost fix rendering
    
  • b0be2703
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Add SIMD
    
  • 807b57f2
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    lkw
    
  • cd85e3bc
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Fixed first pass
    
  • 47aa9405
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Fixed point working now
    
  • 59a97a74
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Add comments to raster algorithm and cleanup
    
  • 3160af77
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    SIMD with Fixed-Point
    
  • 33e1fecf
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Add fontdue optimization
    
  • 9ab279d5
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Optimize Division
    
  • fd4757d4
    by Anurag Thakur at 2022-11-14T10:18:41+05:30
    Fix monochrome crash
    

13 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
    +        "tmmintrin.h": "c"
    
    7
    +    }
    
    8
    +}

  • CMakeLists.txt
    ... ... @@ -405,6 +405,7 @@ set(BASE_SRCS
    405 405
       src/cache/ftcache.c
    
    406 406
       src/cff/cff.c
    
    407 407
       src/cid/type1cid.c
    
    408
    +  src/dense/dense.c
    
    408 409
       src/gzip/ftgzip.c
    
    409 410
       src/lzw/ftlzw.c
    
    410 411
       src/pcf/pcf.c
    

  • 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/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 <immintrin.h>
    
    15
    +#include "ftdenseerrs.h"
    
    16
    +
    
    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
    +// TODO: Fix types
    
    26
    +#define FT_UDIVPREP( c, b )                                \
    
    27
    +  FT26D6  b ## _r = c ? (FT26D6)0xFFFFFFFF / ( b ) : 0
    
    28
    +#define FT_UDIV( a, b )                                           \
    
    29
    +  (FT26D6)( ( (FT26D6)( a ) * (FT26D6)( b ## _r ) ) >> 32 )
    
    30
    +
    
    31
    +typedef struct dense_TRaster_
    
    32
    +{
    
    33
    +  void* memory;
    
    34
    +
    
    35
    +} dense_TRaster, *dense_PRaster;
    
    36
    +
    
    37
    +static FT_Vector
    
    38
    +Lerp( float aT, FT_Vector aP0, FT_Vector aP1 )
    
    39
    +{
    
    40
    +  FT_Vector p;
    
    41
    +  p.x = aP0.x + aT * ( aP1.x - aP0.x );
    
    42
    +  p.y = aP0.y + aT * ( aP1.y - aP0.y );
    
    43
    +  return p;
    
    44
    +}
    
    45
    +
    
    46
    +static int
    
    47
    +dense_move_to( const FT_Vector* to, dense_worker* worker )
    
    48
    +{
    
    49
    +  TPos x, y;
    
    50
    +
    
    51
    +  x              = UPSCALE( to->x );
    
    52
    +  y              = UPSCALE( to->y );
    
    53
    +  worker->prev_x = x;
    
    54
    +  worker->prev_y = y;
    
    55
    +  // printf( "last point is {%f, %f}", lp.m_x, lp.m_y );
    
    56
    +  return 0;
    
    57
    +}
    
    58
    +
    
    59
    +static int
    
    60
    +dense_line_to( const FT_Vector* to, dense_worker* worker )
    
    61
    +{
    
    62
    +  //printf( "dense_line_to: %d, %d\n", to->x, to->y );
    
    63
    +  dense_render_line( worker, UPSCALE( to->x ), UPSCALE( to->y ) );
    
    64
    +  dense_move_to( to, worker );
    
    65
    +  return 0;
    
    66
    +}
    
    67
    +
    
    68
    +FT26D6 max(FT26D6 x, FT26D6 y){
    
    69
    +  if(x > y)
    
    70
    +    return x;
    
    71
    +  return y;
    
    72
    +}
    
    73
    +
    
    74
    +FT26D6 min(FT26D6 x, FT26D6 y){
    
    75
    +  if(x < y)
    
    76
    +    return x;
    
    77
    +  return y;
    
    78
    +}
    
    79
    +
    
    80
    +void
    
    81
    +swap( long int* a, long int* b )
    
    82
    +{
    
    83
    +  long int temp = *a;
    
    84
    +  *a            = *b;
    
    85
    +  *b            = temp;
    
    86
    +}
    
    87
    +
    
    88
    +
    
    89
    +void
    
    90
    +dense_render_line( dense_worker* worker, TPos tox, TPos toy )
    
    91
    +{
    
    92
    +
    
    93
    +  FT26D6 fx = worker->prev_x>>2;
    
    94
    +  FT26D6 fy = worker->prev_y>>2;
    
    95
    +    
    
    96
    +  FT26D6 from_x = fx;
    
    97
    +  FT26D6 from_y = fy;
    
    98
    +
    
    99
    +  FT26D6 tx = tox>>2;
    
    100
    +  FT26D6 ty = toy>>2;
    
    101
    +
    
    102
    +  FT26D6 to_x = tx;
    
    103
    +  FT26D6 to_y = ty;
    
    104
    +
    
    105
    +  // from_x/y and to_x/y are coordinates in 26.6 format
    
    106
    +  if ( from_y == to_y )
    
    107
    +    return;
    
    108
    +
    
    109
    +  //printf("line from: %f, %f to %f, %f\n", from_x, from_y, to_x, to_y);
    
    110
    +
    
    111
    +  int dir = 1;
    
    112
    +  if ( from_y >= to_y )
    
    113
    +  {
    
    114
    +    dir = -1;
    
    115
    +    swap( &from_x, &to_x );
    
    116
    +    swap( &from_y, &to_y );
    
    117
    +  }
    
    118
    +
    
    119
    +  // Clip to the height.
    
    120
    +  if ( from_y >= worker->m_h<<6 || to_y <= 0 )
    
    121
    +    return;
    
    122
    +
    
    123
    +
    
    124
    +  FT26D6 deltax,deltay;
    
    125
    +  deltax = to_x - from_x;
    
    126
    +  deltay = to_y - from_y;
    
    127
    +
    
    128
    +    FT_UDIVPREP(from_x != to_x, deltax);
    
    129
    +
    
    130
    +    FT_UDIVPREP(from_y != to_y, deltay);
    
    131
    +
    
    132
    +
    
    133
    +  if ( from_y < 0 )
    
    134
    +  {
    
    135
    +    from_x -= from_y * deltax/deltay;
    
    136
    +    from_y = 0;
    
    137
    +  }
    
    138
    +
    
    139
    +  // This condition is important apparently
    
    140
    +  if ( to_y > worker->m_h<<6 )
    
    141
    +  {
    
    142
    +    to_x -= (( to_y - worker->m_h<<6 ) * deltax/deltay);
    
    143
    +    to_y = worker->m_h<<6;
    
    144
    +  }
    
    145
    +
    
    146
    +
    
    147
    +  if(deltax == 0){
    
    148
    +      FT26D6 x       = from_x;
    
    149
    +      int   x0i    = x>>6;
    
    150
    +      FT26D6 x0floor = x0i<<6;
    
    151
    +
    
    152
    +      // y-coordinate of first pixel of line
    
    153
    +      int    y0      = from_y>>6;
    
    154
    +
    
    155
    +      // y-coordinate of last pixel of line
    
    156
    +      int    y_limit = (to_y + 0x3f)>>6;
    
    157
    +      FT20D12* m_a   = worker->m_a;
    
    158
    +
    
    159
    +
    
    160
    +
    
    161
    +    for ( int y = y0; y < y_limit; y++ )
    
    162
    +    {
    
    163
    +      int linestart = y * worker->m_w;
    
    164
    +
    
    165
    +     FT26D6 dy   = min( (y + 1)<<6, to_y ) - max( y<<6, from_y );
    
    166
    +
    
    167
    +      m_a[linestart + x0i] += dir*dy*(64 - x + x0floor);
    
    168
    +      m_a[linestart + ( x0i + 1 )] += dir*dy*(x-x0floor);
    
    169
    +
    
    170
    +    }
    
    171
    +
    
    172
    +    // int y = y0;
    
    173
    +
    
    174
    +    // int linestart = y * worker->m_w;
    
    175
    +
    
    176
    +    //  FT26D6 dy1   = min( (y + 1)<<6, to_y ) - max( y<<6, from_y );
    
    177
    +    //  m_a[linestart + x0i] += dir*dy1*(64 - x + x0floor);
    
    178
    +    //   m_a[linestart + ( x0i + 1 )] += dir*dy1*(x-x0floor);
    
    179
    +
    
    180
    +    // y = y_limit -1;
    
    181
    +
    
    182
    +    //  linestart = y * worker->m_w;
    
    183
    +
    
    184
    +    //  FT26D6 dy2   = min( (y + 1)<<6, to_y ) - max( y<<6, from_y );
    
    185
    +    //  m_a[linestart + x0i] += dir*dy2*(64 - x + x0floor);
    
    186
    +    //   m_a[linestart + ( x0i + 1 )] += dir*dy2*(x-x0floor);
    
    187
    +
    
    188
    +
    
    189
    +
    
    190
    +  }else{
    
    191
    +
    
    192
    +  FT26D6 x       = from_x;
    
    193
    +
    
    194
    +  // y-coordinate of first pixel of line
    
    195
    +  int    y0      = from_y>>6;
    
    196
    +
    
    197
    +  // y-coordinate of last pixel of line
    
    198
    +  int    y_limit = (to_y + 0x3f)>>6;
    
    199
    +  FT20D12* m_a   = worker->m_a;
    
    200
    +
    
    201
    +
    
    202
    +  for ( int y = y0; y < y_limit; y++ )
    
    203
    +  {
    
    204
    +    int   linestart = y * worker->m_w;
    
    205
    +
    
    206
    +    // dy is the height of the line present in the current scanline
    
    207
    +    FT26D6 dy        = min( (y + 1)<<6, to_y ) - max( y<<6, from_y );
    
    208
    +
    
    209
    +    //  x coordinate where the line leaves the current scanline
    
    210
    +    FT26D6 xnext     = x + FT_UDIV((dy*deltax), deltay);
    
    211
    +
    
    212
    +
    
    213
    +    // height with sign
    
    214
    +    FT26D6 d         = dy * dir;
    
    215
    +
    
    216
    +    // x0 is the x coordinate of the start of line in current scanline
    
    217
    +    // x1 is the x coordinate of the end of line in current scanline
    
    218
    +    FT26D6 x0, x1;
    
    219
    +    if ( x < xnext )
    
    220
    +    {
    
    221
    +      x0 = x;
    
    222
    +      x1 = xnext;
    
    223
    +    }
    
    224
    +    else
    
    225
    +    {
    
    226
    +      x0 = xnext;
    
    227
    +      x1 = x;
    
    228
    +    }
    
    229
    +
    
    230
    +    // x coordinate of the leftmost intersected pixel in the scanline
    
    231
    +    int   x0i    = x0>>6;
    
    232
    +    FT26D6 x0floor = x0i<<6;
    
    233
    +
    
    234
    +
    
    235
    +    // float x1ceil = (float)ceil( x1 );
    
    236
    +    // x coordinate of the rightmost intersected pixel in the scanline
    
    237
    +    int   x1i    = (x1+0x3f)>>6;
    
    238
    +    FT26D6 x1ceil =  x1i <<6;
    
    239
    +
    
    240
    +    if ( x1i <= x0i + 1 )
    
    241
    +    {
    
    242
    +      // average of x coordinates of trapezium with origin at left of pixel
    
    243
    +      FT26D6 xmf = ( ( x + xnext )>>1) - x0floor;
    
    244
    +
    
    245
    +      // average of x coordinates of trapezium with origin at right of pixel
    
    246
    +      m_a[linestart + x0i] += d * ((1<<6) - xmf);
    
    247
    +      m_a[linestart + ( x0i + 1 )] += d * xmf;
    
    248
    +    }
    
    249
    +    else
    
    250
    +    {
    
    251
    +      // total horizontal length of line in current scanline, might be replaced by deltax
    
    252
    +      FT26D6 oneOverS = x1 - x0;
    
    253
    +
    
    254
    +      FT_UDIVPREP(x1 != x0, oneOverS);
    
    255
    +
    
    256
    +      FT26D6 x0f = x0 - x0floor;
    
    257
    +
    
    258
    +      // 64 - x0f is the horizontal length of line in first pixel
    
    259
    +      FT26D6 oneMinusX0f = (1<<6) - x0f;
    
    260
    +
    
    261
    +      // Stores area of triangle in first pixel divided by d
    
    262
    +			FT26D6 a0 = FT_UDIV(((oneMinusX0f * oneMinusX0f) >> 1), oneOverS);
    
    263
    +
    
    264
    +      // x1f is the horizontal length in the last pixel
    
    265
    +			FT26D6 x1f = x1 - x1ceil + (1<<6);
    
    266
    +			FT26D6 am =  FT_UDIV(((x1f * x1f) >> 1) , oneOverS);
    
    267
    +
    
    268
    +      // d * a0 is area of triangle in first pixel
    
    269
    +      m_a[linestart + x0i] += d * a0;
    
    270
    +      if ( x1i == x0i + 2 )
    
    271
    +        m_a[linestart + ( x0i + 1 )] += d * ( (1<<6) - a0 - am );
    
    272
    +      else
    
    273
    +      {
    
    274
    +
    
    275
    +        FT26D6 a1 =  FT_UDIV((((1<<6) + (1<<5) - x0f) << 6) , oneOverS);
    
    276
    +
    
    277
    +        m_a[linestart + ( x0i + 1 )] += d * ( a1 - a0 );
    
    278
    +
    
    279
    +        FT26D6 dTimesS =  FT_UDIV((d << 12) , oneOverS);
    
    280
    +
    
    281
    +        for ( FT26D6 xi = x0i + 2; xi < x1i - 1; xi++ ){
    
    282
    +          // Increase area for successive pixels by dy/dx
    
    283
    +          m_a[linestart + xi] += dTimesS;
    
    284
    +        }
    
    285
    +
    
    286
    +
    
    287
    +        FT26D6 a2 = a1 +  FT_UDIV((( x1i - x0i - 3 )<<12),oneOverS);
    
    288
    +        m_a[linestart + ( x1i - 1 )] += d * ( (1<<6) - a2 - am );
    
    289
    +      }
    
    290
    +      // Area in last pixel of scanline
    
    291
    +      m_a[linestart + x1i] += d * am;
    
    292
    +    }
    
    293
    +    
    
    294
    +    x = xnext;
    
    295
    +  }
    
    296
    +  }
    
    297
    +}
    
    298
    +
    
    299
    +static int
    
    300
    +dense_conic_to( const FT_Vector* control,
    
    301
    +                const FT_Vector* to,
    
    302
    +                dense_worker*    worker )
    
    303
    +{
    
    304
    +  //printf( "dense_conic_to: %d, %d\n", to->x, to->y );
    
    305
    +  dense_render_quadratic( worker, control, to );
    
    306
    +  return 0;
    
    307
    +}
    
    308
    +
    
    309
    +void
    
    310
    +dense_render_quadratic( dense_worker*    worker,
    
    311
    +                        const FT_Vector* control,
    
    312
    +                        const FT_Vector* to )
    
    313
    +{
    
    314
    +  /*
    
    315
    +  Calculate devsq as the square of four times the
    
    316
    +  distance from the control point to the midpoint of the curve.
    
    317
    +  This is the place at which the curve is furthest from the
    
    318
    +  line joining the control points.
    
    319
    +
    
    320
    +  4 x point on curve = p0 + 2p1 + p2
    
    321
    +  4 x midpoint = 4p1
    
    322
    +
    
    323
    +  The division by four is omitted to save time.
    
    324
    +  */
    
    325
    +
    
    326
    +  FT_Vector aP0 = { DOWNSCALE( worker->prev_x ), DOWNSCALE( worker->prev_y ) };
    
    327
    +  FT_Vector aP1 = { control->x, control->y };
    
    328
    +  FT_Vector aP2 = { to->x, to->y };
    
    329
    +
    
    330
    +  float devx  = aP0.x - aP1.x - aP1.x + aP2.x;
    
    331
    +  float devy  = aP0.y - aP1.y - aP1.y + aP2.y;
    
    332
    +  float devsq = devx * devx + devy * devy;
    
    333
    +
    
    334
    +  if ( devsq < 0.333f )
    
    335
    +  {
    
    336
    +    dense_line_to( &aP2, worker );
    
    337
    +    return;
    
    338
    +  }
    
    339
    +
    
    340
    +  /*
    
    341
    +  According to Raph Levien, the reason for the subdivision by n (instead of
    
    342
    +  recursive division by the Casteljau system) is that "I expect the flatness
    
    343
    +  computation to be semi-expensive (it's done once rather than on each potential
    
    344
    +  subdivision) and also because you'll often get fewer subdivisions. Taking a
    
    345
    +  circular arc as a simplifying assumption, where I get n, a recursive approach
    
    346
    +  would get 2^ceil(lg n), which, if I haven't made any horrible mistakes, is
    
    347
    +  expected to be 33% more in the limit".
    
    348
    +  */
    
    349
    +
    
    350
    +  const float tol = 3.0f;
    
    351
    +  int         n   = (int)floor( sqrt( sqrt( tol * devsq ) ) )/8;
    
    352
    +  //printf( "n is %d\n", n );
    
    353
    +  FT_Vector p      = aP0;
    
    354
    +  float     nrecip = 1.0f / ( n + 1.0f );
    
    355
    +  float     t      = 0.0f;
    
    356
    +  for ( int i = 0; i < n; i++ )
    
    357
    +  {
    
    358
    +    t += nrecip;
    
    359
    +    FT_Vector next = Lerp( t, Lerp( t, aP0, aP1 ), Lerp( t, aP1, aP2 ) );
    
    360
    +    dense_line_to(&next, worker );
    
    361
    +    p              = next;
    
    362
    +  }
    
    363
    +
    
    364
    +  dense_line_to( &aP2, worker );
    
    365
    +  // worker->prev_x = aP2.x;
    
    366
    +  // worker->prev_y = aP2.y;
    
    367
    +}
    
    368
    +
    
    369
    +static int
    
    370
    +dense_cubic_to( const FT_Vector* control1,
    
    371
    +                const FT_Vector* control2,
    
    372
    +                const FT_Vector* to,
    
    373
    +                dense_worker*    worker )
    
    374
    +{
    
    375
    +  dense_render_cubic( worker, control1, control2, to );
    
    376
    +  return 0;
    
    377
    +}
    
    378
    +
    
    379
    +void
    
    380
    +dense_render_cubic( dense_worker* worker,
    
    381
    +                    FT_Vector*    aP1,
    
    382
    +                    FT_Vector*    aP2,
    
    383
    +                    FT_Vector*    aP3 )
    
    384
    +{
    
    385
    +  // assert( worker );
    
    386
    +  FT_Vector aP0    = { worker->prev_x, worker->prev_y };
    
    387
    +  float     devx   = aP0.x - aP1->x - aP1->x + aP2->x;
    
    388
    +  float     devy   = aP0.y - aP1->y - aP1->y + aP2->y;
    
    389
    +  float     devsq0 = devx * devx + devy * devy;
    
    390
    +  devx             = aP1->x - aP2->x - aP2->x + aP3->x;
    
    391
    +  devy             = aP1->y - aP2->y - aP2->y + aP3->y;
    
    392
    +  float devsq1     = devx * devx + devy * devy;
    
    393
    +  float devsq      = fmax( devsq0, devsq1 );
    
    394
    +
    
    395
    +  if ( devsq < 0.333f )
    
    396
    +  {
    
    397
    +    dense_render_line( worker, aP3->x, aP3->y );
    
    398
    +    return;
    
    399
    +  }
    
    400
    +
    
    401
    +  const float tol    = 3.0f;
    
    402
    +  int         n      = (int)floor( sqrt( sqrt( tol * devsq ) ) );
    
    403
    +  FT_Vector   p      = aP0;
    
    404
    +  float       nrecip = 1.0f / ( n + 1.0f );
    
    405
    +  float       t      = 0.0f;
    
    406
    +  for ( int i = 0; i < n; i++ )
    
    407
    +  {
    
    408
    +    t += nrecip;
    
    409
    +    FT_Vector a    = Lerp( t, Lerp( t, aP0, *aP1 ), Lerp( t, *aP1, *aP2 ) );
    
    410
    +    FT_Vector b    = Lerp( t, Lerp( t, *aP1, *aP2 ), Lerp( t, *aP2, *aP3 ) );
    
    411
    +    FT_Vector next = Lerp( t, a, b );
    
    412
    +    dense_render_line( worker, next.x, next.y );
    
    413
    +    worker->prev_x = next.x;
    
    414
    +    worker->prev_y = next.y;
    
    415
    +    p              = next;
    
    416
    +  }
    
    417
    +
    
    418
    +  dense_render_line( worker, aP3->x, aP3->y );
    
    419
    +  worker->prev_x = aP3->x;
    
    420
    +  worker->prev_y = aP3->y;
    
    421
    +}
    
    422
    +
    
    423
    +static int
    
    424
    +dense_raster_new( FT_Memory memory, dense_PRaster* araster )
    
    425
    +{
    
    426
    +  FT_Error      error;
    
    427
    +  dense_PRaster raster;
    
    428
    +
    
    429
    +  if ( !FT_NEW( raster ) )
    
    430
    +    raster->memory = memory;
    
    431
    +
    
    432
    +  *araster = raster;
    
    433
    +  return error;
    
    434
    +}
    
    435
    +
    
    436
    +static void
    
    437
    +dense_raster_done( FT_Raster raster )
    
    438
    +{
    
    439
    +  FT_Memory memory = (FT_Memory)( (dense_PRaster)raster )->memory;
    
    440
    +
    
    441
    +  FT_FREE( raster );
    
    442
    +}
    
    443
    +
    
    444
    +static void
    
    445
    +dense_raster_reset( FT_Raster      raster,
    
    446
    +                    unsigned char* pool_base,
    
    447
    +                    unsigned long  pool_size )
    
    448
    +{
    
    449
    +  FT_UNUSED( raster );
    
    450
    +  FT_UNUSED( pool_base );
    
    451
    +  FT_UNUSED( pool_size );
    
    452
    +}
    
    453
    +
    
    454
    +static int
    
    455
    +dense_raster_set_mode( FT_Raster raster, unsigned long mode, void* args )
    
    456
    +{
    
    457
    +  FT_UNUSED( raster );
    
    458
    +  FT_UNUSED( mode );
    
    459
    +  FT_UNUSED( args );
    
    460
    +
    
    461
    +  return 0; /* nothing to do */
    
    462
    +}
    
    463
    +
    
    464
    +FT_DEFINE_OUTLINE_FUNCS( dense_decompose_funcs,
    
    465
    +
    
    466
    +                         (FT_Outline_MoveTo_Func)dense_move_to,   /* move_to  */
    
    467
    +                         (FT_Outline_LineTo_Func)dense_line_to,   /* line_to  */
    
    468
    +                         (FT_Outline_ConicTo_Func)dense_conic_to, /* conic_to */
    
    469
    +                         (FT_Outline_CubicTo_Func)dense_cubic_to, /* cubic_to */
    
    470
    +
    
    471
    +                         0, /* shift    */
    
    472
    +                         0  /* delta    */
    
    473
    +)
    
    474
    +
    
    475
    +static int
    
    476
    +dense_render_glyph( dense_worker* worker, const FT_Bitmap* target )
    
    477
    +{
    
    478
    +  FT_Error error = FT_Outline_Decompose( &( worker->outline ),
    
    479
    +                                         &dense_decompose_funcs, worker );
    
    480
    +  // Render into bitmap
    
    481
    +  const FT20D12* source = worker->m_a;
    
    482
    +
    
    483
    +  unsigned char* dest     = target->buffer;
    
    484
    +  unsigned char* dest_end = target->buffer + worker->m_w * worker->m_h;
    
    485
    +
    
    486
    +   __m128i offset = _mm_setzero_si128();
    
    487
    +  __m128i mask   = _mm_set1_epi32( 0x0c080400 );
    
    488
    +
    
    489
    +  for (int i = 0; i < worker->m_h*worker->m_w; i += 4)
    
    490
    +  {
    
    491
    +    // load 4 floats from source
    
    492
    +
    
    493
    +    __m128i x = _mm_load_si128( (__m128i*)&source[i] );
    
    494
    +
    
    495
    +    // bkc
    
    496
    +    x = _mm_add_epi32( x, _mm_slli_si128( x, 4 ) );
    
    497
    +
    
    498
    +    // more bkc
    
    499
    +    x = _mm_add_epi32(
    
    500
    +        x, _mm_castps_si128( _mm_shuffle_ps( _mm_setzero_ps(),
    
    501
    +                                             _mm_castsi128_ps( x ), 0x40 ) ) );
    
    502
    +
    
    503
    +    // add the prefsum of previous 4 floats to all current floats
    
    504
    +    x = _mm_add_epi32( x, offset );
    
    505
    +
    
    506
    +    // take absolute value
    
    507
    +    __m128i y = _mm_abs_epi32( x );  // fabs(x)
    
    508
    +
    
    509
    +    // cap max value to 1
    
    510
    +    y = _mm_min_epi32( y, _mm_set1_epi32( 4080 ) );
    
    511
    +
    
    512
    +    // reduce to 255
    
    513
    +    y = _mm_srli_epi32( y, 4 );
    
    514
    +
    
    515
    +    // black magic
    
    516
    +    y = _mm_shuffle_epi8( y, mask );
    
    517
    +
    
    518
    +    // for some reason, storing float in an unsigned char array works fine lol
    
    519
    +    _mm_store_ss( (float*)&dest[i], (__m128)y );
    
    520
    +
    
    521
    +    // store the current prefix sum in offset
    
    522
    +    offset = _mm_castps_si128( _mm_shuffle_ps( _mm_castsi128_ps( x ),
    
    523
    +                                               _mm_castsi128_ps( x ),
    
    524
    +                                               _MM_SHUFFLE( 3, 3, 3, 3 ) ) );
    
    525
    +  }
    
    526
    +  
    
    527
    +
    
    528
    +    // FT20D12 valnew = 0;
    
    529
    +    // //float          value    = 0.0f;
    
    530
    +    // while ( dest < dest_end )
    
    531
    +    // {
    
    532
    +    //   valnew += *source++;
    
    533
    +
    
    534
    +    //  // printf("%d\n", *source);
    
    535
    +
    
    536
    +    //   if(valnew > 0){
    
    537
    +    //     int nnew = valnew >>4;
    
    538
    +
    
    539
    +    //     if(nnew>255)nnew=255;
    
    540
    +    //     *dest = (unsigned char)nnew;
    
    541
    +    //   }else{
    
    542
    +    //     *dest = 0;
    
    543
    +    //   }
    
    544
    +    //   dest++;
    
    545
    +    // }
    
    546
    +
    
    547
    +  free(worker->m_a);
    
    548
    +  return error;
    
    549
    +}
    
    550
    +
    
    551
    +static int
    
    552
    +dense_raster_render( FT_Raster raster, const FT_Raster_Params* params )
    
    553
    +{
    
    554
    +  const FT_Outline* outline    = (const FT_Outline*)params->source;
    
    555
    +  FT_Bitmap*  target_map = params->target;
    
    556
    +
    
    557
    +  // dense_worker* worker = malloc( sizeof( dense_worker ) );
    
    558
    +  dense_worker worker[1];
    
    559
    +
    
    560
    +  if ( !raster )
    
    561
    +    return FT_THROW( Invalid_Argument );
    
    562
    +
    
    563
    +  if ( !outline )
    
    564
    +    return FT_THROW( Invalid_Outline );
    
    565
    +
    
    566
    +  worker->outline = *outline;
    
    567
    +
    
    568
    +  if ( !target_map )
    
    569
    +    return FT_THROW( Invalid_Argument );
    
    570
    +
    
    571
    +  /* nothing to do */
    
    572
    +  if ( !target_map->width || !target_map->rows )
    
    573
    +    return 0;
    
    574
    +
    
    575
    +  if ( !target_map->buffer )
    
    576
    +    return FT_THROW( Invalid_Argument );
    
    577
    +
    
    578
    +  worker->m_origin_x = 0;
    
    579
    +  worker->m_origin_y = 0;
    
    580
    +  worker->m_w = target_map->pitch;
    
    581
    +  worker->m_h = target_map->rows;
    
    582
    +
    
    583
    +  int size = worker->m_w * worker->m_h + 4;
    
    584
    +
    
    585
    +  worker->m_a      = malloc( sizeof( FT20D12 ) * size );
    
    586
    +  worker->m_a_size = size;
    
    587
    +
    
    588
    +  memset( worker->m_a, 0, ( sizeof( FT20D12 ) * size ) );
    
    589
    +  /* exit if nothing to do */
    
    590
    +  if ( worker->m_w <= worker->m_origin_x || worker->m_h <= worker->m_origin_y )
    
    591
    +  {
    
    592
    +    return 0;
    
    593
    +  }
    
    594
    +
    
    595
    +  // Invert the pitch to account for different +ve y-axis direction in dense array
    
    596
    +  // (maybe temporary solution)
    
    597
    +  target_map->pitch *= -1;
    
    598
    +  return dense_render_glyph( worker, target_map );
    
    599
    +}
    
    600
    +
    
    601
    +FT_DEFINE_RASTER_FUNCS(
    
    602
    +    ft_dense_raster,
    
    603
    +
    
    604
    +    FT_GLYPH_FORMAT_OUTLINE,
    
    605
    +
    
    606
    +    (FT_Raster_New_Func)dense_raster_new,           /* raster_new      */
    
    607
    +    (FT_Raster_Reset_Func)dense_raster_reset,       /* raster_reset    */
    
    608
    +    (FT_Raster_Set_Mode_Func)dense_raster_set_mode, /* raster_set_mode */
    
    609
    +    (FT_Raster_Render_Func)dense_raster_render,     /* raster_render   */
    
    610
    +    (FT_Raster_Done_Func)dense_raster_done          /* raster_done     */
    
    611
    +)
    
    612
    +
    
    613
    +/* 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 signed long TPos;
    
    44
    +  typedef signed long FT26D6;
    
    45
    +  typedef signed int FT20D12;
    
    46
    +
    
    47
    +  typedef struct
    
    48
    +  {
    
    49
    +    /** The array used to store signed area differences. */
    
    50
    +    FT20D12* m_a;
    
    51
    +    /** The number of elements in m_a. */
    
    52
    +    int m_a_size;
    
    53
    +    /** The width of the current raster in pixels. */
    
    54
    +    int m_w;
    
    55
    +    /** The height of the current raster in pixels. */
    
    56
    +    int m_h;
    
    57
    +    /** The x origin of the raster. */
    
    58
    +    int m_origin_x;
    
    59
    +    /** The y origin of the raster. */
    
    60
    +    int m_origin_y;
    
    61
    +
    
    62
    +    FT_Pos prev_x, prev_y;
    
    63
    +
    
    64
    +    FT_Outline outline;
    
    65
    +  } dense_worker;
    
    66
    +
    
    67
    +  void dense_render_line( dense_worker* aRasterFP, TPos to_x, TPos to_y );
    
    68
    +  void dense_render_quadratic( dense_worker*    aRasterFP,
    
    69
    +                               const FT_Vector* control,
    
    70
    +                               const FT_Vector* to );
    
    71
    +  void dense_render_cubic( dense_worker* aRasterFP,
    
    72
    +                           FT_Vector*    aP1,
    
    73
    +                           FT_Vector*    aP2,
    
    74
    +                           FT_Vector*    aP3 );
    
    75
    +
    
    76
    +#ifdef __cplusplus
    
    77
    +}  // extern "C"
    
    78
    +#endif
    
    79
    +
    
    80
    +FT_END_HEADER
    
    81
    +
    
    82
    +#endif /* FTDENSE_H_ */
    
    83
    +
    
    84
    +/* 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
    + // printf("ft_dense_render\n");
    
    58
    +  FT_Error    error   = FT_Err_Ok;
    
    59
    +  FT_Outline* outline = &slot->outline;
    
    60
    +  FT_Bitmap*  bitmap  = &slot->bitmap;
    
    61
    +
    
    62
    +/* @QUES: You know, it should be a bit more clear that FT_FREE and FT_ALLOC_MULT macros
    
    63
    +take a variable named `memory`. It can only be known if you follow the macros 3 level deep.*/
    
    64
    +  FT_Memory   memory  = render->root.memory;
    
    65
    +
    
    66
    +  FT_Pos x_shift = 0;
    
    67
    +  FT_Pos y_shift = 0;
    
    68
    +
    
    69
    +  FT_Raster_Params params;
    
    70
    +
    
    71
    +  /* check whether slot format is correct before rendering */
    
    72
    +  if ( slot->format != render->glyph_format )
    
    73
    +  {
    
    74
    +    error = FT_THROW( Invalid_Glyph_Format );
    
    75
    +    goto Exit;
    
    76
    +  }
    
    77
    +
    
    78
    +      /* check mode */
    
    79
    +    if ( mode != FT_RENDER_MODE_NORMAL &&
    
    80
    +         mode != FT_RENDER_MODE_LIGHT  &&
    
    81
    +         mode != FT_RENDER_MODE_LCD    &&
    
    82
    +         mode != FT_RENDER_MODE_LCD_V  )
    
    83
    +    {
    
    84
    +      error = FT_THROW( Cannot_Render_Glyph );
    
    85
    +      goto Exit;
    
    86
    +    }
    
    87
    +
    
    88
    +  /* deallocate the previously allocated bitmap */
    
    89
    +  if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
    
    90
    +  {
    
    91
    +    FT_FREE( bitmap->buffer );
    
    92
    +    slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
    
    93
    +  }
    
    94
    +
    
    95
    +  /* preset the bitmap using the glyph's outline;         */
    
    96
    +  if ( ft_glyphslot_preset_bitmap( slot, mode, origin ) )
    
    97
    +  {
    
    98
    +    error = FT_THROW( Raster_Overflow );
    
    99
    +    goto Exit;
    
    100
    +  }
    
    101
    +
    
    102
    +  if ( !bitmap->rows || !bitmap->pitch )
    
    103
    +    goto Exit;
    
    104
    +
    
    105
    +
    
    106
    +  /* allocate new one */
    
    107
    +  if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) )
    
    108
    +    goto Exit;
    
    109
    +
    
    110
    +    /* @QUES: What does this flag mean ?*/
    
    111
    +  slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
    
    112
    +  
    
    113
    +  /* @QUES: Where can I read more about why x and y shift are required */
    
    114
    +  x_shift = 64 * -slot->bitmap_left;
    
    115
    +  y_shift = 64 * -slot->bitmap_top;
    
    116
    +
    
    117
    +  if ( bitmap->pixel_mode == FT_PIXEL_MODE_LCD_V )
    
    118
    +     y_shift += 64 * (FT_Int)bitmap->rows / 3;
    
    119
    +   else
    
    120
    +     y_shift += 64 * (FT_Int)bitmap->rows;
    
    121
    +
    
    122
    +
    
    123
    +  if ( origin )
    
    124
    +  {
    
    125
    +    x_shift += origin->x;
    
    126
    +    y_shift += origin->y;
    
    127
    +  }
    
    128
    +
    
    129
    +  /* translate outline to render it into the bitmap */
    
    130
    +  if ( x_shift || y_shift )
    
    131
    +    FT_Outline_Translate( outline, x_shift, y_shift );
    
    132
    +
    
    133
    +  /* set up parameters */
    
    134
    +  params.target = bitmap;
    
    135
    +  params.source = outline;
    
    136
    +
    
    137
    +  /* @QUES: Why is my final bitmap upside down ??🤔*/
    
    138
    +
    
    139
    +  /* render the outline */
    
    140
    +  error =
    
    141
    +      render->raster_render( render->raster, (const FT_Raster_Params*)&params );
    
    142
    +
    
    143
    +Exit:
    
    144
    +  if ( !error )
    
    145
    +  {
    
    146
    +    /* the glyph is successfully rendered to a bitmap */
    
    147
    +    slot->format = FT_GLYPH_FORMAT_BITMAP;
    
    148
    +  }
    
    149
    +  else if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
    
    150
    +  {
    
    151
    +    FT_FREE( bitmap->buffer );
    
    152
    +    slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
    
    153
    +  }
    
    154
    +
    
    155
    +  if ( x_shift || y_shift )
    
    156
    +    FT_Outline_Translate( outline, -x_shift, -y_shift );
    
    157
    +
    
    158
    +  return error;
    
    159
    +}
    
    160
    +
    
    161
    +/* transform the glyph using matrix and/or delta */
    
    162
    +/* @QUES: This mthod isn't called, atleast in normal ftlint execution.
    
    163
    +What is it for ?*/
    
    164
    +static FT_Error
    
    165
    +ft_dense_transform( FT_Renderer      render,
    
    166
    +                    FT_GlyphSlot     slot,
    
    167
    +                    const FT_Matrix* matrix,
    
    168
    +                    const FT_Vector* delta )
    
    169
    +{
    
    170
    +
    
    171
    +  FT_Error error = FT_Err_Ok;
    
    172
    +
    
    173
    +  if ( slot->format != render->glyph_format )
    
    174
    +  {
    
    175
    +    error = FT_THROW( Invalid_Argument );
    
    176
    +    goto Exit;
    
    177
    +  }
    
    178
    +
    
    179
    +  if ( matrix )
    
    180
    +    FT_Outline_Transform( &slot->outline, matrix );
    
    181
    +
    
    182
    +  if ( delta )
    
    183
    +    FT_Outline_Translate( &slot->outline, delta->x, delta->y );
    
    184
    +
    
    185
    +Exit:
    
    186
    +  return error;
    
    187
    +}
    
    188
    +
    
    189
    +/* return the control box of a glyph's outline */
    
    190
    +/* @QUES: This method isn't called either in normal ftlint execution*/
    
    191
    +static void
    
    192
    +ft_dense_get_cbox( FT_Renderer render, FT_GlyphSlot slot, FT_BBox* cbox )
    
    193
    +{
    
    194
    +
    
    195
    +  FT_ZERO( cbox );
    
    196
    +
    
    197
    +  if ( slot->format == render->glyph_format )
    
    198
    +    FT_Outline_Get_CBox( &slot->outline, cbox );
    
    199
    +}
    
    200
    +
    
    201
    +/* set render specific modes or attributes */
    
    202
    +/* @QUES: Isn't called in normal ftlint execution*/
    
    203
    +static FT_Error
    
    204
    +ft_dense_set_mode( FT_Renderer render, FT_ULong mode_tag, FT_Pointer data )
    
    205
    +{
    
    206
    +  /* pass it to the rasterizer */
    
    207
    +  return render->clazz->raster_class->raster_set_mode( render->raster, mode_tag,
    
    208
    +                                                       data );
    
    209
    +}
    
    210
    +
    
    211
    +FT_DEFINE_RENDERER(
    
    212
    +    ft_dense_renderer_class,
    
    213
    +
    
    214
    +    FT_MODULE_RENDERER,
    
    215
    +    sizeof( FT_RendererRec ),
    
    216
    +
    
    217
    +    "dense",
    
    218
    +    0x10000L,
    
    219
    +    0x20000L,
    
    220
    +
    
    221
    +    NULL,
    
    222
    +
    
    223
    +    (FT_Module_Constructor)ft_dense_init,
    
    224
    +    (FT_Module_Destructor)ft_dense_done,
    
    225
    +    (FT_Module_Requester)NULL,
    
    226
    +
    
    227
    +    FT_GLYPH_FORMAT_OUTLINE,
    
    228
    +
    
    229
    +    (FT_Renderer_RenderFunc)ft_dense_render,       /* render_glyph    */
    
    230
    +    (FT_Renderer_TransformFunc)ft_dense_transform, /* transform_glyph */
    
    231
    +    (FT_Renderer_GetCBoxFunc)ft_dense_get_cbox,    /* get_glyph_cbox  */
    
    232
    +    (FT_Renderer_SetModeFunc)ft_dense_set_mode,    /* set_mode        */
    
    233
    +
    
    234
    +    (FT_Raster_Funcs*)&ft_dense_raster /* raster_class    */
    
    235
    +)
    
    236
    +
    
    237
    +/* 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
    +                        "-msse4.1"
    
    28
    +
    
    29
    +
    
    30
    +# DENSE driver sources (i.e., C files)
    
    31
    +#
    
    32
    +DENSE_DRV_SRC := $(DENSE_DIR)/ftdense.c  \
    
    33
    +                  $(DENSE_DIR)/ftdenserend.c
    
    34
    +
    
    35
    +
    
    36
    +# DENSE driver headers
    
    37
    +#
    
    38
    +DENSE_DRV_H := $(DENSE_DRV_SRC:%c=%h)  \
    
    39
    +                $(DENSE_DIR)/ftdenseerrs.h
    
    40
    +
    
    41
    +
    
    42
    +# DENSE driver object(s)
    
    43
    +#
    
    44
    +#   DENSE_DRV_OBJ_M is used during `multi' builds.
    
    45
    +#   DENSE_DRV_OBJ_S is used during `single' builds.
    
    46
    +#
    
    47
    +DENSE_DRV_OBJ_M := $(DENSE_DRV_SRC:$(DENSE_DIR)/%.c=$(OBJ_DIR)/%.$O)
    
    48
    +DENSE_DRV_OBJ_S := $(OBJ_DIR)/dense.$O
    
    49
    +
    
    50
    +# DENSE driver source file for single build
    
    51
    +#
    
    52
    +DENSE_DRV_SRC_S := $(DENSE_DIR)/dense.c
    
    53
    +
    
    54
    +
    
    55
    +# DENSE driver - single object
    
    56
    +#
    
    57
    +$(DENSE_DRV_OBJ_S): $(DENSE_DRV_SRC_S) $(DENSE_DRV_SRC) \
    
    58
    +                     $(FREETYPE_H) $(DENSE_DRV_H)
    
    59
    +	$(DENSE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(DENSE_DRV_SRC_S))
    
    60
    +
    
    61
    +
    
    62
    +# DENSE driver - multiple objects
    
    63
    +#
    
    64
    +$(OBJ_DIR)/%.$O: $(DENSE_DIR)/%.c $(FREETYPE_H) $(DENSE_DRV_H)
    
    65
    +	$(DENSE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
    
    66
    +
    
    67
    +
    
    68
    +# update main driver object lists
    
    69
    +#
    
    70
    +DRV_OBJS_S += $(DENSE_DRV_OBJ_S)
    
    71
    +DRV_OBJS_M += $(DENSE_DRV_OBJ_M)
    
    72
    +
    
    73
    +
    
    74
    +# EOF


  • reply via email to

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