freetype-commit
[Top][All Lists]
Advanced

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

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


From: Werner Lemberg (@wl)
Subject: [Git][freetype/freetype-demos][wl/freetype-demos-support-ot-svg-glyphs-new] 17 commits: [graph/win32] Improve surface initialization.
Date: Tue, 11 Jan 2022 08:56:30 +0000

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

Commits:

11 changed files:

Changes:

  • Makefile
    ... ... @@ -125,6 +125,16 @@ else
    125 125
         SRC_DIR := $(TOP_DIR_2)/src
    
    126 126
       endif
    
    127 127
     
    
    128
    +  ifeq ($(PLATFORM),unixdev)
    
    129
    +    # `FT_DEMO_CFLAGS` comes from FreeType's `configure` script (via
    
    130
    +    # `builds/unix/unix-cc.mk`), holding additional flags to compile the
    
    131
    +    # FreeType demo programs.
    
    132
    +    #
    
    133
    +    # For the pure `make` call (without using `configure`) we have to add
    
    134
    +    # all needed cflags manually.
    
    135
    +    FT_DEMO_CFLAGS := $(shell pkg-config --cflags librsvg-2.0)
    
    136
    +  endif
    
    137
    +
    
    128 138
       FT_INCLUDES := $(OBJ_BUILD) \
    
    129 139
                      $(DEVEL_DIR) \
    
    130 140
                      $(TOP_DIR)/include \
    
    ... ... @@ -133,7 +143,8 @@ else
    133 143
       COMPILE = $(CC) $(ANSIFLAGS) \
    
    134 144
                       $(INCLUDES:%=$I%) \
    
    135 145
                       $(CPPFLAGS) \
    
    136
    -                  $(CFLAGS)
    
    146
    +                  $(CFLAGS) \
    
    147
    +                  $(FT_DEMO_CFLAGS)
    
    137 148
     
    
    138 149
       # Enable C99 for gcc to avoid warnings.
    
    139 150
       # Note that clang++ aborts with an error if we use `-std=C99',
    
    ... ... @@ -164,17 +175,27 @@ else
    164 175
       LINK_ITEMS = $T$(subst /,$(COMPILER_SEP),$@ $<)
    
    165 176
     
    
    166 177
       ifeq ($(PLATFORM),unix)
    
    178
    +    # `LDFLAGS` comes from the `configure` script (via FreeType's
    
    179
    +    # `builds/unix/unix-cc.mk`), holding all linker flags necessary to
    
    180
    +    # link the FreeType library.
    
    181
    +    #
    
    182
    +    # `FT_DEMO_LDFLAGS` has been set in `unix-cc.mk`, too.
    
    167 183
         override CC = $(CCraw)
    
    168 184
         LINK_CMD    = $(LIBTOOL) --mode=link $(CC) \
    
    169 185
                       $(subst /,$(COMPILER_SEP),$(LDFLAGS))
    
    170
    -    LINK_LIBS   = $(subst /,$(COMPILER_SEP),$(FTLIB) $(EFENCE)) $(LIB_CLOCK_GETTIME)
    
    186
    +    LINK_LIBS   = $(subst /,$(COMPILER_SEP),$(FTLIB) $(EFENCE)) \
    
    187
    +                  $(FT_DEMO_LDFLAGS)
    
    171 188
       else
    
    172 189
         LINK_CMD = $(CC) $(subst /,$(COMPILER_SEP),$(LDFLAGS))
    
    173 190
         ifeq ($(PLATFORM),unixdev)
    
    174
    -      LINK_LIBS := $(subst /,$(COMPILER_SEP),$(FTLIB) $(EFENCE)) -lm -lrt -lz -lbz2 -lpthread
    
    191
    +      # For the pure `make` call (without using `configure`) we have to add
    
    192
    +      # all needed libraries manually.
    
    193
    +      LINK_LIBS := $(subst /,$(COMPILER_SEP),$(FTLIB) $(EFENCE)) \
    
    194
    +                   -lm -lrt -lz -lbz2 -lpthread
    
    175 195
           LINK_LIBS += $(shell pkg-config --libs libpng)
    
    176 196
           LINK_LIBS += $(shell pkg-config --libs harfbuzz)
    
    177 197
           LINK_LIBS += $(shell pkg-config --libs libbrotlidec)
    
    198
    +      LINK_LIBS += $(shell pkg-config --libs librsvg-2.0)
    
    178 199
         else
    
    179 200
           LINK_LIBS = $(subst /,$(COMPILER_SEP),$(FTLIB) $(EFENCE))
    
    180 201
         endif
    
    ... ... @@ -349,6 +370,7 @@ else
    349 370
       $(OBJ_DIR_2)/mlgetopt.$(SO): $(SRC_DIR)/mlgetopt.c
    
    350 371
       COMMON_OBJ := $(OBJ_DIR_2)/common.$(SO) \
    
    351 372
                     $(OBJ_DIR_2)/strbuf.$(SO) \
    
    373
    +                $(OBJ_DIR_2)/rsvg-port.$(SO) \
    
    352 374
                     $(OBJ_DIR_2)/output.$(SO) \
    
    353 375
                     $(OBJ_DIR_2)/md5.$(SO) \
    
    354 376
                     $(OBJ_DIR_2)/mlgetopt.$(SO)
    
    ... ... @@ -361,6 +383,9 @@ else
    361 383
     	  $(COMPILE) $(GRAPH_INCLUDES:%=$I%) \
    
    362 384
                          $T$(subst /,$(COMPILER_SEP),$@ $<)
    
    363 385
     
    
    386
    +  $(OBJ_DIR_2)/rsvg-port.$(SO): $(SRC_DIR)/rsvg-port.c $(SRC_DIR)/rsvg-port.h
    
    387
    +	  $(COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
    
    388
    +
    
    364 389
       FTCOMMON_OBJ := $(OBJ_DIR_2)/ftcommon.$(SO) \
    
    365 390
                       $(OBJ_DIR_2)/ftpngout.$(SO)
    
    366 391
     
    

  • graph/gblblit.c
    ... ... @@ -237,17 +237,6 @@
    237 237
     
    
    238 238
     /* */
    
    239 239
     
    
    240
    -static const GBlenderBlitFunc*
    
    241
    -blit_funcs[GBLENDER_TARGET_MAX] =
    
    242
    -{
    
    243
    -  blit_funcs_gray8,
    
    244
    -  blit_funcs_rgb32,
    
    245
    -  blit_funcs_rgb24,
    
    246
    -  blit_funcs_rgb565,
    
    247
    -  blit_funcs_rgb555
    
    248
    -};
    
    249
    -
    
    250
    -
    
    251 240
     static int
    
    252 241
     gblender_blit_init( GBlenderBlit           blit,
    
    253 242
                         int                    dst_x,
    
    ... ... @@ -263,14 +252,13 @@ gblender_blit_init( GBlenderBlit blit,
    263 252
     
    
    264 253
       GBlenderSourceFormat   src_format;
    
    265 254
       const unsigned char*   src_buffer = glyph->buffer;
    
    266
    -  int                    src_pitch  = glyph->pitch;
    
    255
    +  const int              src_pitch  = glyph->pitch;
    
    267 256
       int                    src_width  = glyph->width;
    
    268 257
       int                    src_height = glyph->rows;
    
    269
    -  GBlenderTargetFormat   dst_format;
    
    270 258
       unsigned char*         dst_buffer = target->buffer;
    
    271
    -  int                    dst_pitch  = target->pitch;
    
    272
    -  int                    dst_width  = target->width;
    
    273
    -  int                    dst_height = target->rows;
    
    259
    +  const int              dst_pitch  = target->pitch;
    
    260
    +  const int              dst_width  = target->width;
    
    261
    +  const int              dst_height = target->rows;
    
    274 262
     
    
    275 263
     
    
    276 264
       switch ( glyph->mode )
    
    ... ... @@ -305,18 +293,27 @@ gblender_blit_init( GBlenderBlit blit,
    305 293
     
    
    306 294
       switch ( target->mode )
    
    307 295
       {
    
    308
    -  case gr_pixel_mode_gray:   dst_format = GBLENDER_TARGET_GRAY8; break;
    
    309
    -  case gr_pixel_mode_rgb32:  dst_format = GBLENDER_TARGET_RGB32; break;
    
    310
    -  case gr_pixel_mode_rgb24:  dst_format = GBLENDER_TARGET_RGB24; break;
    
    311
    -  case gr_pixel_mode_rgb565: dst_format = GBLENDER_TARGET_RGB565; break;
    
    312
    -  case gr_pixel_mode_rgb555: dst_format = GBLENDER_TARGET_RGB555; break;
    
    296
    +  case gr_pixel_mode_gray:
    
    297
    +    blit->blit_func = blit_funcs_gray8[src_format];
    
    298
    +    break;
    
    299
    +  case gr_pixel_mode_rgb32:
    
    300
    +    blit->blit_func = blit_funcs_rgb32[src_format];
    
    301
    +    break;
    
    302
    +  case gr_pixel_mode_rgb24:
    
    303
    +    blit->blit_func = blit_funcs_rgb24[src_format];
    
    304
    +    break;
    
    305
    +  case gr_pixel_mode_rgb565:
    
    306
    +    blit->blit_func = blit_funcs_rgb565[src_format];
    
    307
    +    break;
    
    308
    +  case gr_pixel_mode_rgb555:
    
    309
    +    blit->blit_func = blit_funcs_rgb555[src_format];
    
    310
    +    break;
    
    313 311
       default:
    
    314 312
         grError = gr_err_bad_target_depth;
    
    315 313
         return -2;
    
    316 314
       }
    
    317 315
     
    
    318 316
       blit->blender   = surface->gblender;
    
    319
    -  blit->blit_func = blit_funcs[dst_format][src_format];
    
    320 317
     
    
    321 318
       if ( dst_x < 0 )
    
    322 319
       {
    
    ... ... @@ -345,24 +342,20 @@ gblender_blit_init( GBlenderBlit blit,
    345 342
       if ( src_width <= 0 || src_height <= 0 )
    
    346 343
         return -1;
    
    347 344
     
    
    348
    -  blit->width      = src_width;
    
    349
    -  blit->height     = src_height;
    
    350
    -  blit->src_format = src_format;
    
    351
    -  blit->dst_format = dst_format;
    
    345
    +  blit->width     = src_width;
    
    346
    +  blit->height    = src_height;
    
    352 347
     
    
    353
    -  blit->src_x     = src_x;
    
    354
    -  blit->src_y     = src_y;
    
    355
    -  blit->src_line  = src_buffer + src_pitch*src_y;
    
    356 348
       blit->src_pitch = src_pitch;
    
    357 349
       if ( src_pitch < 0 )
    
    358
    -    blit->src_line -= (src_height-1)*src_pitch;
    
    350
    +    src_y -= glyph->rows - 1;
    
    351
    +  blit->src_line  = src_buffer + src_pitch * src_y;
    
    352
    +  blit->src_x     = src_x;
    
    359 353
     
    
    360
    -  blit->dst_x     = dst_x;
    
    361
    -  blit->dst_y     = dst_y;
    
    362
    -  blit->dst_line  = dst_buffer + dst_pitch*dst_y;
    
    363 354
       blit->dst_pitch = dst_pitch;
    
    364 355
       if ( dst_pitch < 0 )
    
    365
    -    blit->dst_line -= (dst_height-1)*dst_pitch;
    
    356
    +    dst_y -= dst_height - 1;
    
    357
    +  blit->dst_line  = dst_buffer + dst_pitch * dst_y;
    
    358
    +  blit->dst_x     = dst_x;
    
    366 359
     
    
    367 360
       return 0;
    
    368 361
     }
    

  • graph/gblblit.h
    ... ... @@ -48,13 +48,9 @@ typedef struct GBlenderBlitRec_
    48 48
       const unsigned char*  src_line;
    
    49 49
       int                   src_pitch;
    
    50 50
       int                   src_x;
    
    51
    -  int                   src_y;
    
    52 51
       unsigned char*        dst_line;
    
    53 52
       int                   dst_pitch;
    
    54 53
       int                   dst_x;
    
    55
    -  int                   dst_y;
    
    56
    -  GBlenderSourceFormat  src_format;
    
    57
    -  GBlenderTargetFormat  dst_format;
    
    58 54
     
    
    59 55
       GBlender              blender;
    
    60 56
       GBlenderBlitFunc      blit_func;
    

  • graph/gblender.h
    ... ... @@ -145,7 +145,7 @@
    145 145
       GBLENDER_API( void )
    
    146 146
       gblender_dump_stats( GBlender  blender );
    
    147 147
     #else
    
    148
    -# define gblender_dump_stats(b)  do { } while (0);
    
    148
    +# define gblender_dump_stats(b)  do { } while (0)
    
    149 149
     #endif
    
    150 150
     
    
    151 151
     #ifdef GBLENDER_STATS
    

  • graph/grobjs.c
    ... ... @@ -14,31 +14,32 @@
    14 14
       {
    
    15 15
         grColor  color;
    
    16 16
     
    
    17
    +
    
    17 18
         color.value = 0;
    
    18 19
     
    
    19
    -    switch (target->mode)
    
    20
    +    switch ( target->mode )
    
    20 21
         {
    
    21 22
           case gr_pixel_mode_mono:
    
    22
    -        if ( (red|green|blue) )
    
    23
    +        if ( ( red | green | blue ) )
    
    23 24
               color.value = 1;
    
    24 25
             break;
    
    25 26
     
    
    26 27
           case gr_pixel_mode_gray:
    
    27
    -        color.value = ( 3*(red   & 0xFF) +
    
    28
    -                        6*(green & 0xFF) +
    
    29
    -                          (blue  & 0xFF) ) / 10;
    
    28
    +        color.value = ( 3 * ( red   & 0xFF ) +
    
    29
    +                        6 * ( green & 0xFF ) +
    
    30
    +                            ( blue  & 0xFF ) ) / 10;
    
    30 31
             break;
    
    31 32
     
    
    32 33
           case gr_pixel_mode_rgb555:
    
    33
    -        color.value = (uint32_t)( ( red   & 0xF8 ) << 7 ) |
    
    34
    -                      (uint32_t)( ( green & 0xF8 ) << 2 ) |
    
    35
    -                      (uint32_t)( ( blue  & 0xF8 ) >> 3 );
    
    34
    +        color.value = ( ( (uint32_t)red   & 0xF8 ) << 7 ) |
    
    35
    +                      ( ( (uint32_t)green & 0xF8 ) << 2 ) |
    
    36
    +                      ( ( (uint32_t)blue  & 0xF8 ) >> 3 );
    
    36 37
             break;
    
    37 38
     
    
    38 39
           case gr_pixel_mode_rgb565:
    
    39
    -        color.value = (uint32_t)( ( red   & 0xF8 ) << 8 ) |
    
    40
    -                      (uint32_t)( ( green & 0xFC ) << 3 ) |
    
    41
    -                      (uint32_t)( ( blue  & 0xF8 ) >> 3 );
    
    40
    +        color.value = ( ( (uint32_t)red   & 0xF8 ) << 8 ) |
    
    41
    +                      ( ( (uint32_t)green & 0xFC ) << 3 ) |
    
    42
    +                      ( ( (uint32_t)blue  & 0xF8 ) >> 3 );
    
    42 43
             break;
    
    43 44
     
    
    44 45
           case gr_pixel_mode_rgb24:
    
    ... ... @@ -48,15 +49,16 @@
    48 49
             break;
    
    49 50
     
    
    50 51
           case gr_pixel_mode_rgb32:
    
    51
    -        color.value = (uint32_t)( ( alpha & 0xFF ) << 24 ) |
    
    52
    -                      (uint32_t)( ( red   & 0xFF ) << 16 ) |
    
    53
    -                      (uint32_t)( ( green & 0xFF ) <<  8 ) |
    
    54
    -                      (uint32_t)( ( blue  & 0xFF )       );
    
    52
    +        color.value = ( ( (uint32_t)alpha & 0xFF ) << 24 ) |
    
    53
    +                      ( ( (uint32_t)red   & 0xFF ) << 16 ) |
    
    54
    +                      ( ( (uint32_t)green & 0xFF ) <<  8 ) |
    
    55
    +                      ( ( (uint32_t)blue  & 0xFF )       );
    
    55 56
             break;
    
    56 57
     
    
    57 58
           default:
    
    58 59
             ;
    
    59 60
         }
    
    61
    +
    
    60 62
         return color;
    
    61 63
       }
    
    62 64
     
    

  • graph/win32/grwin32.c
    ... ... @@ -57,6 +57,7 @@
    57 57
     #endif
    
    58 58
     
    
    59 59
     /*  Custom messages. */
    
    60
    +#define WM_STATUS  WM_USER+512
    
    60 61
     #define WM_RESIZE  WM_USER+517
    
    61 62
     
    
    62 63
     
    
    ... ... @@ -99,6 +100,7 @@
    99 100
       typedef struct grWin32SurfaceRec_
    
    100 101
       {
    
    101 102
         grSurface     root;
    
    103
    +    DWORD         host;
    
    102 104
         HWND          window;
    
    103 105
         HICON         sIcon;
    
    104 106
         HICON         bIcon;
    
    ... ... @@ -148,7 +150,7 @@ gr_win32_surface_refresh_rectangle(
    148 150
       grBitmap*  bitmap = &surface->root.bitmap;
    
    149 151
     
    
    150 152
       LOG(( "gr_win32_surface_refresh_rectangle: ( %p, %d, %d, %d, %d )\n",
    
    151
    -        (long)surface, x, y, w, h ));
    
    153
    +        surface->root.bitmap.buffer, x, y, w, h ));
    
    152 154
     
    
    153 155
       /* clip update rectangle */
    
    154 156
     
    
    ... ... @@ -305,8 +307,6 @@ gr_win32_surface_set_icon( grWin32Surface* surface,
    305 307
         return 0;
    
    306 308
       case ICON_BIG:
    
    307 309
         surface->bIcon = hIcon;
    
    308
    -    SetClassLongPtr( surface->window, GCLP_HBRBACKGROUND,
    
    309
    -                     (LONG_PTR)CreatePatternBrush( ici.hbmColor ) );
    
    310 310
         return s[0];
    
    311 311
       default:
    
    312 312
         return 0;  /* should not happen */
    
    ... ... @@ -373,11 +373,14 @@ gr_win32_surface_listen_event( grWin32Surface* surface,
    373 373
     
    
    374 374
       event_mask=event_mask;  /* unused parameter */
    
    375 375
     
    
    376
    -  while ( GetMessage( &msg, NULL, 0, 0 ) > 0 )
    
    376
    +  while ( GetMessage( &msg, (HWND)-1, 0, 0 ) > 0 )
    
    377 377
       {
    
    378 378
         switch ( msg.message )
    
    379 379
         {
    
    380 380
         case WM_RESIZE:
    
    381
    +      while( PeekMessage( &msg, (HWND)-1, WM_RESIZE, WM_RESIZE, PM_REMOVE ) )
    
    382
    +        continue;
    
    383
    +
    
    381 384
           {
    
    382 385
             int  width  = LOWORD(msg.lParam);
    
    383 386
             int  height = HIWORD(msg.lParam);
    
    ... ... @@ -423,16 +426,63 @@ gr_win32_surface_listen_event( grWin32Surface* surface,
    423 426
           }
    
    424 427
           break;
    
    425 428
         }
    
    429
    +  }
    
    430
    +}
    
    431
    +
    
    426 432
     
    
    433
    +DWORD WINAPI Window_ThreadProc( LPVOID lpParameter )
    
    434
    +{
    
    435
    +  grWin32Surface*  surface = (grWin32Surface*)lpParameter;
    
    436
    +  DWORD            style   = WS_OVERLAPPEDWINDOW;
    
    437
    +  RECT             WndRect;
    
    438
    +  MSG              msg;
    
    439
    +
    
    440
    +  WndRect.left   = 0;
    
    441
    +  WndRect.top    = 0;
    
    442
    +  WndRect.right  = surface->root.bitmap.width;
    
    443
    +  WndRect.bottom = surface->root.bitmap.rows;
    
    444
    +
    
    445
    +  AdjustWindowRect( &WndRect, style, FALSE );
    
    446
    +
    
    447
    +  surface->window = CreateWindow(
    
    448
    +       /* LPCSTR lpszClassName;    */ "FreeTypeTestGraphicDriver",
    
    449
    +       /* LPCSTR lpszWindowName;   */ "FreeType Test Graphic Driver",
    
    450
    +       /* DWORD dwStyle;           */  style,
    
    451
    +       /* int x;                   */  CW_USEDEFAULT,
    
    452
    +       /* int y;                   */  CW_USEDEFAULT,
    
    453
    +       /* int nWidth;              */  WndRect.right - WndRect.left,
    
    454
    +       /* int nHeight;             */  WndRect.bottom - WndRect.top,
    
    455
    +       /* HWND hwndParent;         */  HWND_DESKTOP,
    
    456
    +       /* HMENU hmenu;             */  0,
    
    457
    +       /* HINSTANCE hinst;         */  GetModuleHandle( NULL ),
    
    458
    +       /* void FAR* lpvParam;      */  surface );
    
    459
    +
    
    460
    +  PostThreadMessage( surface->host, WM_STATUS, (WPARAM)surface->window, 0 );
    
    461
    +
    
    462
    +  if ( surface->window == 0 )
    
    463
    +    return -1;
    
    464
    +
    
    465
    +  ShowWindow( surface->window, SW_SHOWNORMAL );
    
    466
    +
    
    467
    +  while ( GetMessage( &msg, surface->window, 0, 0 ) > 0 )
    
    468
    +  {
    
    427 469
         TranslateMessage( &msg );
    
    428 470
         DispatchMessage( &msg );
    
    429 471
       }
    
    472
    +
    
    473
    +  LOG(("Window thread done.\n"));
    
    474
    +  return 0;
    
    430 475
     }
    
    431 476
     
    
    477
    +
    
    432 478
     static grWin32Surface*
    
    433 479
     gr_win32_surface_init( grWin32Surface*  surface,
    
    434 480
                            grBitmap*        bitmap )
    
    435 481
     {
    
    482
    +  MSG  msg;
    
    483
    +
    
    484
    +  surface->root.bitmap.grays = bitmap->grays;
    
    485
    +
    
    436 486
       /* Set default mode */
    
    437 487
       if ( bitmap->mode == gr_pixel_mode_none )
    
    438 488
       {
    
    ... ... @@ -446,64 +496,29 @@ gr_win32_surface_init( grWin32Surface* surface,
    446 496
         switch ( bpp )
    
    447 497
         {
    
    448 498
         case 8:
    
    449
    -      bitmap->mode = gr_pixel_mode_gray;
    
    499
    +      surface->root.bitmap.mode = gr_pixel_mode_gray;
    
    450 500
           break;
    
    451 501
         case 16:
    
    452
    -      bitmap->mode = gr_pixel_mode_rgb565;
    
    502
    +      surface->root.bitmap.mode = gr_pixel_mode_rgb565;
    
    453 503
           break;
    
    454 504
         case 24:
    
    455
    -      bitmap->mode = gr_pixel_mode_rgb24;
    
    505
    +      surface->root.bitmap.mode = gr_pixel_mode_rgb24;
    
    456 506
           break;
    
    457 507
         case 32:
    
    458 508
         default:
    
    459
    -      bitmap->mode = gr_pixel_mode_rgb32;
    
    509
    +      surface->root.bitmap.mode = gr_pixel_mode_rgb32;
    
    460 510
         }
    
    461 511
       }
    
    512
    +  else
    
    513
    +    surface->root.bitmap.mode  = bitmap->mode;
    
    462 514
     
    
    463
    -  LOG(( "Win32: init_surface( %p, %p )\n", surface, bitmap ));
    
    464
    -
    
    465
    -  LOG(( "       --   mode   = %d\n", bitmap->mode ));
    
    466
    -  LOG(( "       --   grays  = %d\n", bitmap->grays ));
    
    467
    -  LOG(( "       --   width  = %d\n", bitmap->width ));
    
    468
    -  LOG(( "       --   height = %d\n", bitmap->rows ));
    
    469
    -
    
    470
    -  /* create the bitmap - under Win32, we support all modes as the GDI */
    
    471
    -  /* handles all conversions automatically..                          */
    
    472
    -  if ( grNewBitmap( bitmap->mode,
    
    473
    -                    bitmap->grays,
    
    474
    -                    bitmap->width,
    
    475
    -                    bitmap->rows,
    
    476
    -                    bitmap ) )
    
    515
    +  if ( !gr_win32_surface_resize( surface, bitmap->width, bitmap->rows ) )
    
    477 516
         return 0;
    
    478 517
     
    
    479
    -  /* allocate the BGR shadow bitmap */
    
    480
    -  if ( bitmap->mode == gr_pixel_mode_rgb24 )
    
    481
    -  {
    
    482
    -    if ( grNewBitmap( bitmap->mode,
    
    483
    -                      bitmap->grays,
    
    484
    -                      bitmap->width,
    
    485
    -                      bitmap->rows,
    
    486
    -                      &surface->shadow_bitmap ) )
    
    487
    -      return 0;
    
    488
    -
    
    489
    -#ifdef SWIZZLE
    
    490
    -    if ( grNewBitmap( bitmap->mode,
    
    491
    -                      bitmap->grays,
    
    492
    -                      bitmap->width,
    
    493
    -                      bitmap->rows,
    
    494
    -                      &surface->swizzle_bitmap ) )
    
    495
    -      return 0;
    
    496
    -#endif
    
    497
    -  }
    
    498
    -  else
    
    499
    -    surface->shadow_bitmap.buffer = bitmap->buffer;
    
    500
    -
    
    501 518
       surface->bmiHeader.biSize   = sizeof( BITMAPINFOHEADER );
    
    502
    -  surface->bmiHeader.biWidth  = bitmap->width;
    
    503
    -  surface->bmiHeader.biHeight = -bitmap->rows;
    
    504 519
       surface->bmiHeader.biPlanes = 1;
    
    505 520
     
    
    506
    -  switch ( bitmap->mode )
    
    521
    +  switch ( surface->root.bitmap.mode )
    
    507 522
       {
    
    508 523
       case gr_pixel_mode_mono:
    
    509 524
         surface->bmiHeader.biBitCount = 1;
    
    ... ... @@ -565,43 +580,28 @@ gr_win32_surface_init( grWin32Surface* surface,
    565 580
         return 0;         /* Unknown mode */
    
    566 581
       }
    
    567 582
     
    
    568
    -  {
    
    569
    -    DWORD  style = WS_OVERLAPPEDWINDOW;
    
    570
    -    RECT   WndRect;
    
    571
    -
    
    572
    -    WndRect.left   = 0;
    
    573
    -    WndRect.top    = 0;
    
    574
    -    WndRect.right  = bitmap->width;
    
    575
    -    WndRect.bottom = bitmap->rows;
    
    576
    -
    
    577
    -    AdjustWindowRect( &WndRect, style, FALSE );
    
    578
    -
    
    579
    -    surface->window = CreateWindow(
    
    580
    -            /* LPCSTR lpszClassName;    */ "FreeTypeTestGraphicDriver",
    
    581
    -            /* LPCSTR lpszWindowName;   */ "FreeType Test Graphic Driver",
    
    582
    -            /* DWORD dwStyle;           */  style,
    
    583
    -            /* int x;                   */  CW_USEDEFAULT,
    
    584
    -            /* int y;                   */  CW_USEDEFAULT,
    
    585
    -            /* int nWidth;              */  WndRect.right - WndRect.left,
    
    586
    -            /* int nHeight;             */  WndRect.bottom - WndRect.top,
    
    587
    -            /* HWND hwndParent;         */  HWND_DESKTOP,
    
    588
    -            /* HMENU hmenu;             */  0,
    
    589
    -            /* HINSTANCE hinst;         */  GetModuleHandle( NULL ),
    
    590
    -            /* void FAR* lpvParam;      */  surface );
    
    591
    -  }
    
    583
    +  /* set up the main message queue and spin off the window thread */
    
    584
    +  PeekMessage( &msg, (HWND)-1, WM_USER, WM_USER, PM_NOREMOVE );
    
    585
    +  surface->host = GetCurrentThreadId();
    
    592 586
     
    
    593
    -  if ( surface->window == 0 )
    
    594
    -    return  0;
    
    587
    +  CreateThread( NULL, 0, Window_ThreadProc, (LPVOID)surface, 0, NULL );
    
    595 588
     
    
    596
    -  ShowWindow( surface->window, SW_SHOWNORMAL );
    
    589
    +  /* listen if window is created */
    
    590
    +  if ( GetMessage ( &msg, (HWND)-1, WM_STATUS, WM_STATUS ) < 0 ||
    
    591
    +       !msg.wParam )
    
    592
    +    return 0;
    
    597 593
     
    
    598
    -  surface->root.bitmap       = *bitmap;
    
    594
    +  /* wrap up */
    
    599 595
       surface->root.done         = (grDoneSurfaceFunc) gr_win32_surface_done;
    
    600 596
       surface->root.refresh_rect = (grRefreshRectFunc) gr_win32_surface_refresh_rectangle;
    
    601 597
       surface->root.set_title    = (grSetTitleFunc)    gr_win32_surface_set_title;
    
    602 598
       surface->root.set_icon     = (grSetIconFunc)     gr_win32_surface_set_icon;
    
    603 599
       surface->root.listen_event = (grListenEventFunc) gr_win32_surface_listen_event;
    
    604 600
     
    
    601
    +  LOG(( "Surface initialized: %dx%dx%d\n",
    
    602
    +        surface->root.bitmap.width, surface->root.bitmap.rows,
    
    603
    +        surface->bmiHeader.biBitCount ));
    
    604
    +
    
    605 605
       return surface;
    
    606 606
     }
    
    607 607
     
    
    ... ... @@ -637,15 +637,14 @@ LRESULT CALLBACK Message_Process( HWND handle, UINT mess,
    637 637
         {
    
    638 638
         case WM_CLOSE:
    
    639 639
           /* warn the main thread to quit if it didn't know */
    
    640
    -      PostMessage( handle, WM_CHAR, (WPARAM)grKeyEsc, 0 );
    
    640
    +      PostThreadMessage( surface->host, WM_CHAR, (WPARAM)grKeyEsc, 0 );
    
    641 641
           break;
    
    642 642
     
    
    643 643
         case WM_SIZE:
    
    644 644
           if ( wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED )
    
    645
    -        PostMessage( handle, WM_RESIZE, wParam, lParam );
    
    645
    +        PostThreadMessage( surface->host, WM_RESIZE, wParam, lParam );
    
    646 646
           break;
    
    647 647
     
    
    648
    -#ifdef DEBUG
    
    649 648
         case WM_SIZING:
    
    650 649
           {
    
    651 650
             PRECT  r = (PRECT)lParam;
    
    ... ... @@ -664,27 +663,34 @@ LRESULT CALLBACK Message_Process( HWND handle, UINT mess,
    664 663
                   y, x, r->left, r->top, r->right, r->bottom,
    
    665 664
                   WndRect.right, WndRect.bottom ));
    
    666 665
     
    
    667
    -        /* XXX: We cannot simply interrupt here and resize the image. */
    
    666
    +        PostThreadMessage( surface->host, WM_RESIZE, SIZE_RESTORED,
    
    667
    +                           MAKELPARAM( WndRect.right, WndRect.bottom ) );
    
    668 668
           }
    
    669 669
           break;
    
    670
    -#endif
    
    671 670
     
    
    672 671
         case WM_EXITSIZEMOVE:
    
    673 672
           {
    
    674 673
             RECT  WndRect;
    
    675 674
     
    
    676 675
             GetClientRect( handle, &WndRect );
    
    677
    -        PostMessage( handle, WM_RESIZE, SIZE_RESTORED,
    
    678
    -                     MAKELPARAM( WndRect.right, WndRect.bottom ) );
    
    676
    +        PostThreadMessage( surface->host, WM_RESIZE, SIZE_RESTORED,
    
    677
    +                           MAKELPARAM( WndRect.right, WndRect.bottom ) );
    
    679 678
           }
    
    680 679
           break;
    
    681 680
     
    
    681
    +    case WM_KEYDOWN:
    
    682
    +    case WM_SYSKEYDOWN:
    
    683
    +    case WM_CHAR:
    
    684
    +      /* repost to the main thread */
    
    685
    +      PostThreadMessage( surface->host, mess, wParam, lParam );
    
    686
    +      break;
    
    687
    +
    
    682 688
         case WM_PAINT:
    
    683 689
           {
    
    684
    -        HDC           hDC;
    
    685
    -        PAINTSTRUCT   ps;
    
    690
    +        HDC          hDC;
    
    691
    +        PAINTSTRUCT  ps;
    
    686 692
     
    
    687
    -        hDC   = BeginPaint ( handle, &ps );
    
    693
    +        hDC = BeginPaint ( handle, &ps );
    
    688 694
             SetDIBitsToDevice( hDC, 0, 0,
    
    689 695
                                surface->root.bitmap.width,
    
    690 696
                                surface->root.bitmap.rows,
    

  • src/ftcommon.c
    ... ... @@ -27,6 +27,8 @@
    27 27
     
    
    28 28
     #include FT_BITMAP_H
    
    29 29
     #include FT_FONT_FORMATS_H
    
    30
    +#include FT_OTSVG_H
    
    31
    +
    
    30 32
     
    
    31 33
       /* error messages */
    
    32 34
     #undef FTERRORS_H_
    
    ... ... @@ -37,6 +39,7 @@
    37 39
     #include "common.h"
    
    38 40
     #include "strbuf.h"
    
    39 41
     #include "ftcommon.h"
    
    42
    +#include "rsvg-port.h"
    
    40 43
     
    
    41 44
     #include <stdio.h>
    
    42 45
     #include <stdlib.h>
    
    ... ... @@ -337,6 +340,12 @@
    337 340
       {
    
    338 341
         FTDemo_Handle*  handle;
    
    339 342
     
    
    343
    +    SVG_RendererHooks  hooks = {
    
    344
    +                         (SVG_Lib_Init_Func)rsvg_port_init,
    
    345
    +                         (SVG_Lib_Free_Func)rsvg_port_free,
    
    346
    +                         (SVG_Lib_Render_Func)rsvg_port_render,
    
    347
    +                         (SVG_Lib_Preset_Slot_Func)rsvg_port_preset_slot };
    
    348
    +
    
    340 349
     
    
    341 350
         handle = (FTDemo_Handle *)malloc( sizeof ( FTDemo_Handle ) );
    
    342 351
         if ( !handle )
    
    ... ... @@ -348,6 +357,9 @@
    348 357
         if ( error )
    
    349 358
           PanicZ( "could not initialize FreeType" );
    
    350 359
     
    
    360
    +    /* XXX error handling? */
    
    361
    +    FT_Property_Set( handle->library, "ot-svg", "svg_hooks", &hooks );
    
    362
    +
    
    351 363
         error = FTC_Manager_New( handle->library, 0, 0, 0,
    
    352 364
                                  my_face_requester, 0, &handle->cache_manager );
    
    353 365
         if ( error )
    
    ... ... @@ -424,6 +436,8 @@
    424 436
         FT_Done_FreeType( handle->library );
    
    425 437
     
    
    426 438
         free( handle );
    
    439
    +
    
    440
    +    fflush( stdout );  /* clean mintty pipes */
    
    427 441
       }
    
    428 442
     
    
    429 443
     
    
    ... ... @@ -466,7 +480,7 @@
    466 480
     
    
    467 481
         for ( ; count--; spans++ )
    
    468 482
           for ( dst = dst_line + spans->x, w = spans->len; w--; dst++ )
    
    469
    -        *dst = (FT_UInt32)( spans->coverage << 24 ) | color;
    
    483
    +        *dst = ( (FT_UInt32)spans->coverage << 24 ) | color;
    
    470 484
       }
    
    471 485
     
    
    472 486
     
    
    ... ... @@ -1331,7 +1345,8 @@
    1331 1345
     
    
    1332 1346
         error = FT_Err_Ok;
    
    1333 1347
     
    
    1334
    -    if ( glyf->format == FT_GLYPH_FORMAT_OUTLINE )
    
    1348
    +    if ( glyf->format == FT_GLYPH_FORMAT_OUTLINE ||
    
    1349
    +         glyf->format == FT_GLYPH_FORMAT_SVG     )
    
    1335 1350
         {
    
    1336 1351
           FT_Render_Mode  render_mode;
    
    1337 1352
     
    

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

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

  • subprojects/libpng.wrap
    ... ... @@ -3,9 +3,10 @@ directory = libpng-1.6.37
    3 3
     source_url = https://github.com/glennrp/libpng/archive/v1.6.37.tar.gz
    
    4 4
     source_filename = libpng-1.6.37.tar.gz
    
    5 5
     source_hash = ca74a0dace179a8422187671aee97dd3892b53e168627145271cad5b5ac81307
    
    6
    -patch_url = "">libpng/1.6.37/3/get_zip
    
    7
    -patch_filename = libpng-1.6.37-3-wrap.zip
    
    8
    -patch_hash = 6c9f32fd9150b3a96ab89be52af664e32207e10aa9f5fb9aa015989ee2dd7100
    
    6
    +patch_filename = libpng_1.6.37-5_patch.zip
    
    7
    +patch_url = "">libpng_1.6.37-5/get_patch
    
    8
    +patch_hash = 822200906ad2e82dc8b44e79fe960e980ccad96263548c35eef721086a9926f1
    
    9 9
     
    
    10 10
     [provide]
    
    11 11
     libpng = libpng_dep
    
    12
    +

  • subprojects/zlib.wrap
    ... ... @@ -3,7 +3,7 @@ directory = zlib-1.2.11
    3 3
     source_url = http://zlib.net/fossils/zlib-1.2.11.tar.gz
    
    4 4
     source_filename = zlib-1.2.11.tar.gz
    
    5 5
     source_hash = c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1
    
    6
    -patch_url = https://wrapdb.mesonbuild.com/v1/projects/zlib/1.2.11/5/get_zip
    
    6
    +patch_url = https://wrapdb.mesonbuild.com/v2/zlib_1.2.11-5/get_patch
    
    7 7
     patch_filename = zlib-1.2.11-5-wrap.zip
    
    8 8
     patch_hash = 728c8e24acbc2e6682fbd950fec39e2fc77528af361adb87259f8a8511434004
    
    9 9
     
    


  • reply via email to

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