1 /**************************************************************************** 2 * 3 * ttcolr.c 4 * 5 * TrueType and OpenType colored glyph layer support (body). 6 * 7 * Copyright (C) 2018-2021 by 8 * David Turner, Robert Wilhelm, Dominik Röttsches, and Werner Lemberg. 9 * 10 * Originally written by Shao Yu Zhang <shaozhang@fb.com>. 11 * 12 * This file is part of the FreeType project, and may only be used, 13 * modified, and distributed under the terms of the FreeType project 14 * license, LICENSE.TXT. By continuing to use, modify, or distribute 15 * this file you indicate that you have read the license and 16 * understand and accept it fully. 17 * 18 */ 19 20 21 /************************************************************************** 22 * 23 * `COLR' table specification: 24 * 25 * https://www.microsoft.com/typography/otspec/colr.htm 26 * 27 */ 28 29 30 #include <freetype/internal/ftcalc.h> 31 #include <freetype/internal/ftdebug.h> 32 #include <freetype/internal/ftstream.h> 33 #include <freetype/tttags.h> 34 #include <freetype/ftcolor.h> 35 #include <freetype/config/integer-types.h> 36 37 38 #ifdef TT_CONFIG_OPTION_COLOR_LAYERS 39 40 #include "ttcolr.h" 41 42 43 /* NOTE: These are the table sizes calculated through the specs. */ 44 #define BASE_GLYPH_SIZE 6U 45 #define BASE_GLYPH_PAINT_RECORD_SIZE 6U 46 #define LAYER_V1_LIST_PAINT_OFFSET_SIZE 4U 47 #define LAYER_V1_LIST_NUM_LAYERS_SIZE 4U 48 #define COLOR_STOP_SIZE 6U 49 #define LAYER_SIZE 4U 50 #define COLR_HEADER_SIZE 14U 51 52 53 typedef enum FT_PaintFormat_Internal_ 54 { 55 FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER = 18, 56 FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM = 20, 57 FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER = 22, 58 FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER = 26, 59 FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER = 30 60 61 } FT_PaintFormat_Internal; 62 63 64 typedef struct BaseGlyphRecord_ 65 { 66 FT_UShort gid; 67 FT_UShort first_layer_index; 68 FT_UShort num_layers; 69 70 } BaseGlyphRecord; 71 72 73 typedef struct BaseGlyphV1Record_ 74 { 75 FT_UShort gid; 76 /* Offset from start of BaseGlyphV1List, i.e., from base_glyphs_v1. */ 77 FT_ULong paint_offset; 78 79 } BaseGlyphV1Record; 80 81 82 typedef struct Colr_ 83 { 84 FT_UShort version; 85 FT_UShort num_base_glyphs; 86 FT_UShort num_layers; 87 88 FT_Byte* base_glyphs; 89 FT_Byte* layers; 90 91 FT_ULong num_base_glyphs_v1; 92 /* Points at beginning of BaseGlyphV1List. */ 93 FT_Byte* base_glyphs_v1; 94 95 FT_ULong num_layers_v1; 96 FT_Byte* layers_v1; 97 98 FT_Byte* clip_list; 99 100 /* 101 * Paint tables start at the minimum of the end of the LayerList and the 102 * end of the BaseGlyphList. Record this location in a field here for 103 * safety checks when accessing paint tables. 104 */ 105 FT_Byte* paints_start_v1; 106 107 /* The memory that backs up the `COLR' table. */ 108 void* table; 109 FT_ULong table_size; 110 111 } Colr; 112 113 114 /************************************************************************** 115 * 116 * The macro FT_COMPONENT is used in trace mode. It is an implicit 117 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log 118 * messages during execution. 119 */ 120 #undef FT_COMPONENT 121 #define FT_COMPONENT ttcolr 122 123 124 FT_LOCAL_DEF( FT_Error ) tt_face_load_colr(TT_Face face,FT_Stream stream)125 tt_face_load_colr( TT_Face face, 126 FT_Stream stream ) 127 { 128 FT_Error error; 129 FT_Memory memory = face->root.memory; 130 131 FT_Byte* table = NULL; 132 FT_Byte* p = NULL; 133 /* Needed for reading array lengths in referenced tables. */ 134 FT_Byte* p1 = NULL; 135 136 Colr* colr = NULL; 137 138 FT_ULong base_glyph_offset, layer_offset; 139 FT_ULong base_glyphs_offset_v1, num_base_glyphs_v1; 140 FT_ULong layer_offset_v1, num_layers_v1, clip_list_offset; 141 FT_ULong table_size; 142 143 144 /* `COLR' always needs `CPAL' */ 145 if ( !face->cpal ) 146 return FT_THROW( Invalid_File_Format ); 147 148 error = face->goto_table( face, TTAG_COLR, stream, &table_size ); 149 if ( error ) 150 goto NoColr; 151 152 if ( table_size < COLR_HEADER_SIZE ) 153 goto InvalidTable; 154 155 if ( FT_FRAME_EXTRACT( table_size, table ) ) 156 goto NoColr; 157 158 p = table; 159 160 if ( FT_NEW( colr ) ) 161 goto NoColr; 162 163 colr->version = FT_NEXT_USHORT( p ); 164 if ( colr->version != 0 && colr->version != 1 ) 165 goto InvalidTable; 166 167 colr->num_base_glyphs = FT_NEXT_USHORT( p ); 168 base_glyph_offset = FT_NEXT_ULONG( p ); 169 170 if ( base_glyph_offset >= table_size ) 171 goto InvalidTable; 172 if ( colr->num_base_glyphs * BASE_GLYPH_SIZE > 173 table_size - base_glyph_offset ) 174 goto InvalidTable; 175 176 layer_offset = FT_NEXT_ULONG( p ); 177 colr->num_layers = FT_NEXT_USHORT( p ); 178 179 if ( layer_offset >= table_size ) 180 goto InvalidTable; 181 if ( colr->num_layers * LAYER_SIZE > table_size - layer_offset ) 182 goto InvalidTable; 183 184 if ( colr->version == 1 ) 185 { 186 base_glyphs_offset_v1 = FT_NEXT_ULONG( p ); 187 188 if ( base_glyphs_offset_v1 >= table_size ) 189 goto InvalidTable; 190 191 p1 = (FT_Byte*)( table + base_glyphs_offset_v1 ); 192 num_base_glyphs_v1 = FT_PEEK_ULONG( p1 ); 193 194 if ( num_base_glyphs_v1 * BASE_GLYPH_PAINT_RECORD_SIZE > 195 table_size - base_glyphs_offset_v1 ) 196 goto InvalidTable; 197 198 colr->num_base_glyphs_v1 = num_base_glyphs_v1; 199 colr->base_glyphs_v1 = p1; 200 201 layer_offset_v1 = FT_NEXT_ULONG( p ); 202 203 if ( layer_offset_v1 >= table_size ) 204 goto InvalidTable; 205 206 if ( layer_offset_v1 ) 207 { 208 p1 = (FT_Byte*)( table + layer_offset_v1 ); 209 num_layers_v1 = FT_PEEK_ULONG( p1 ); 210 211 if ( num_layers_v1 * LAYER_V1_LIST_PAINT_OFFSET_SIZE > 212 table_size - layer_offset_v1 ) 213 goto InvalidTable; 214 215 colr->num_layers_v1 = num_layers_v1; 216 colr->layers_v1 = p1; 217 218 colr->paints_start_v1 = 219 FT_MIN( colr->base_glyphs_v1 + 220 colr->num_base_glyphs_v1 * BASE_GLYPH_PAINT_RECORD_SIZE, 221 colr->layers_v1 + 222 colr->num_layers_v1 * LAYER_V1_LIST_PAINT_OFFSET_SIZE ); 223 } 224 else 225 { 226 colr->num_layers_v1 = 0; 227 colr->layers_v1 = 0; 228 colr->paints_start_v1 = 229 colr->base_glyphs_v1 + 230 colr->num_base_glyphs_v1 * BASE_GLYPH_PAINT_RECORD_SIZE; 231 } 232 233 clip_list_offset = FT_NEXT_ULONG( p ); 234 235 if ( clip_list_offset >= table_size ) 236 goto InvalidTable; 237 238 if ( clip_list_offset ) 239 colr->clip_list = (FT_Byte*)( table + clip_list_offset ); 240 else 241 colr->clip_list = 0; 242 } 243 244 colr->base_glyphs = (FT_Byte*)( table + base_glyph_offset ); 245 colr->layers = (FT_Byte*)( table + layer_offset ); 246 colr->table = table; 247 colr->table_size = table_size; 248 249 face->colr = colr; 250 251 return FT_Err_Ok; 252 253 InvalidTable: 254 error = FT_THROW( Invalid_Table ); 255 256 NoColr: 257 FT_FRAME_RELEASE( table ); 258 FT_FREE( colr ); 259 260 return error; 261 } 262 263 264 FT_LOCAL_DEF( void ) tt_face_free_colr(TT_Face face)265 tt_face_free_colr( TT_Face face ) 266 { 267 FT_Stream stream = face->root.stream; 268 FT_Memory memory = face->root.memory; 269 270 Colr* colr = (Colr*)face->colr; 271 272 273 if ( colr ) 274 { 275 FT_FRAME_RELEASE( colr->table ); 276 FT_FREE( colr ); 277 } 278 } 279 280 281 static FT_Bool find_base_glyph_record(FT_Byte * base_glyph_begin,FT_UInt num_base_glyph,FT_UInt glyph_id,BaseGlyphRecord * record)282 find_base_glyph_record( FT_Byte* base_glyph_begin, 283 FT_UInt num_base_glyph, 284 FT_UInt glyph_id, 285 BaseGlyphRecord* record ) 286 { 287 FT_UInt min = 0; 288 FT_UInt max = num_base_glyph; 289 290 291 while ( min < max ) 292 { 293 FT_UInt mid = min + ( max - min ) / 2; 294 FT_Byte* p = base_glyph_begin + mid * BASE_GLYPH_SIZE; 295 296 FT_UShort gid = FT_NEXT_USHORT( p ); 297 298 299 if ( gid < glyph_id ) 300 min = mid + 1; 301 else if (gid > glyph_id ) 302 max = mid; 303 else 304 { 305 record->gid = gid; 306 record->first_layer_index = FT_NEXT_USHORT( p ); 307 record->num_layers = FT_NEXT_USHORT( p ); 308 309 return 1; 310 } 311 } 312 313 return 0; 314 } 315 316 317 FT_LOCAL_DEF( FT_Bool ) tt_face_get_colr_layer(TT_Face face,FT_UInt base_glyph,FT_UInt * aglyph_index,FT_UInt * acolor_index,FT_LayerIterator * iterator)318 tt_face_get_colr_layer( TT_Face face, 319 FT_UInt base_glyph, 320 FT_UInt *aglyph_index, 321 FT_UInt *acolor_index, 322 FT_LayerIterator* iterator ) 323 { 324 Colr* colr = (Colr*)face->colr; 325 BaseGlyphRecord glyph_record; 326 327 328 if ( !colr ) 329 return 0; 330 331 if ( !iterator->p ) 332 { 333 FT_ULong offset; 334 335 336 /* first call to function */ 337 iterator->layer = 0; 338 339 if ( !find_base_glyph_record( colr->base_glyphs, 340 colr->num_base_glyphs, 341 base_glyph, 342 &glyph_record ) ) 343 return 0; 344 345 if ( glyph_record.num_layers ) 346 iterator->num_layers = glyph_record.num_layers; 347 else 348 return 0; 349 350 offset = LAYER_SIZE * glyph_record.first_layer_index; 351 if ( offset + LAYER_SIZE * glyph_record.num_layers > colr->table_size ) 352 return 0; 353 354 iterator->p = colr->layers + offset; 355 } 356 357 if ( iterator->layer >= iterator->num_layers ) 358 return 0; 359 360 *aglyph_index = FT_NEXT_USHORT( iterator->p ); 361 *acolor_index = FT_NEXT_USHORT( iterator->p ); 362 363 if ( *aglyph_index >= (FT_UInt)( FT_FACE( face )->num_glyphs ) || 364 ( *acolor_index != 0xFFFF && 365 *acolor_index >= face->palette_data.num_palette_entries ) ) 366 return 0; 367 368 iterator->layer++; 369 370 return 1; 371 } 372 373 374 static FT_Bool read_color_line(FT_Byte * color_line_p,FT_ColorLine * colorline)375 read_color_line( FT_Byte* color_line_p, 376 FT_ColorLine *colorline ) 377 { 378 FT_Byte* p = color_line_p; 379 FT_PaintExtend paint_extend; 380 381 382 paint_extend = (FT_PaintExtend)FT_NEXT_BYTE( p ); 383 if ( paint_extend > FT_COLR_PAINT_EXTEND_REFLECT ) 384 return 0; 385 386 colorline->extend = paint_extend; 387 388 colorline->color_stop_iterator.num_color_stops = FT_NEXT_USHORT( p ); 389 colorline->color_stop_iterator.p = p; 390 colorline->color_stop_iterator.current_color_stop = 0; 391 392 return 1; 393 } 394 395 396 /* 397 * Read a paint offset for `FT_Paint*` objects that have them and check 398 * whether it is within reasonable limits within the font and the COLR 399 * table. 400 * 401 * Return 1 on success, 0 on failure. 402 */ 403 static FT_Bool get_child_table_pointer(Colr * colr,FT_Byte * paint_base,FT_Byte ** p,FT_Byte ** child_table_pointer)404 get_child_table_pointer ( Colr* colr, 405 FT_Byte* paint_base, 406 FT_Byte** p, 407 FT_Byte** child_table_pointer ) 408 { 409 FT_UInt32 paint_offset; 410 FT_Byte* child_table_p; 411 412 413 if ( !child_table_pointer ) 414 return 0; 415 416 paint_offset = FT_NEXT_UOFF3( *p ); 417 if ( !paint_offset ) 418 return 0; 419 420 child_table_p = (FT_Byte*)( paint_base + paint_offset ); 421 422 if ( child_table_p < colr->paints_start_v1 || 423 child_table_p >= ( (FT_Byte*)colr->table + colr->table_size ) ) 424 return 0; 425 426 *child_table_pointer = child_table_p; 427 return 1; 428 } 429 430 431 static FT_Bool read_paint(Colr * colr,FT_Byte * p,FT_COLR_Paint * apaint)432 read_paint( Colr* colr, 433 FT_Byte* p, 434 FT_COLR_Paint* apaint ) 435 { 436 FT_Byte* paint_base = p; 437 FT_Byte* child_table_p = NULL; 438 439 440 if ( !p || !colr || !colr->table ) 441 return 0; 442 443 if ( p < colr->paints_start_v1 || 444 p >= ( (FT_Byte*)colr->table + colr->table_size ) ) 445 return 0; 446 447 apaint->format = (FT_PaintFormat)FT_NEXT_BYTE( p ); 448 449 if ( apaint->format >= FT_COLR_PAINT_FORMAT_MAX ) 450 return 0; 451 452 if ( apaint->format == FT_COLR_PAINTFORMAT_COLR_LAYERS ) 453 { 454 /* Initialize layer iterator/ */ 455 FT_Byte num_layers; 456 FT_UInt32 first_layer_index; 457 458 459 num_layers = FT_NEXT_BYTE( p ); 460 if ( num_layers > colr->num_layers_v1 ) 461 return 0; 462 463 first_layer_index = FT_NEXT_ULONG( p ); 464 if ( first_layer_index + num_layers > colr->num_layers_v1 ) 465 return 0; 466 467 apaint->u.colr_layers.layer_iterator.num_layers = num_layers; 468 apaint->u.colr_layers.layer_iterator.layer = 0; 469 /* TODO: Check whether pointer is outside colr? */ 470 apaint->u.colr_layers.layer_iterator.p = 471 colr->layers_v1 + 472 LAYER_V1_LIST_NUM_LAYERS_SIZE + 473 LAYER_V1_LIST_PAINT_OFFSET_SIZE * first_layer_index; 474 475 return 1; 476 } 477 478 else if ( apaint->format == FT_COLR_PAINTFORMAT_SOLID ) 479 { 480 apaint->u.solid.color.palette_index = FT_NEXT_USHORT( p ); 481 apaint->u.solid.color.alpha = FT_NEXT_SHORT( p ); 482 483 return 1; 484 } 485 486 else if ( apaint->format == FT_COLR_PAINTFORMAT_COLR_GLYPH ) 487 { 488 apaint->u.colr_glyph.glyphID = FT_NEXT_USHORT( p ); 489 490 return 1; 491 } 492 493 /* 494 * Grouped below here are all paint formats that have an offset to a 495 * child paint table as the first entry (for example, a color line or a 496 * child paint table). Retrieve that and determine whether that paint 497 * offset is valid first. 498 */ 499 500 if ( !get_child_table_pointer( colr, paint_base, &p, &child_table_p ) ) 501 return 0; 502 503 if ( apaint->format == FT_COLR_PAINTFORMAT_LINEAR_GRADIENT ) 504 { 505 if ( !read_color_line( child_table_p, 506 &apaint->u.linear_gradient.colorline ) ) 507 return 0; 508 509 /* 510 * In order to support variations expose these as FT_Fixed 16.16 values so 511 * that we can support fractional values after interpolation. 512 */ 513 apaint->u.linear_gradient.p0.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); 514 apaint->u.linear_gradient.p0.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); 515 apaint->u.linear_gradient.p1.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); 516 apaint->u.linear_gradient.p1.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); 517 apaint->u.linear_gradient.p2.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); 518 apaint->u.linear_gradient.p2.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); 519 520 return 1; 521 } 522 523 else if ( apaint->format == FT_COLR_PAINTFORMAT_RADIAL_GRADIENT ) 524 { 525 if ( !read_color_line( child_table_p, 526 &apaint->u.radial_gradient.colorline ) ) 527 return 0; 528 529 apaint->u.radial_gradient.c0.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); 530 apaint->u.radial_gradient.c0.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); 531 532 apaint->u.radial_gradient.r0 = FT_NEXT_USHORT( p ) << 16; 533 534 apaint->u.radial_gradient.c1.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); 535 apaint->u.radial_gradient.c1.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); 536 537 apaint->u.radial_gradient.r1 = FT_NEXT_USHORT( p ) << 16; 538 539 return 1; 540 } 541 542 else if ( apaint->format == FT_COLR_PAINTFORMAT_SWEEP_GRADIENT ) 543 { 544 if ( !read_color_line( child_table_p, 545 &apaint->u.sweep_gradient.colorline ) ) 546 return 0; 547 548 apaint->u.sweep_gradient.center.x = 549 INT_TO_FIXED( FT_NEXT_SHORT( p ) ); 550 apaint->u.sweep_gradient.center.y = 551 INT_TO_FIXED( FT_NEXT_SHORT( p ) ); 552 553 apaint->u.sweep_gradient.start_angle = 554 F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) ); 555 apaint->u.sweep_gradient.end_angle = 556 F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) ); 557 558 return 1; 559 } 560 561 if ( apaint->format == FT_COLR_PAINTFORMAT_GLYPH ) 562 { 563 apaint->u.glyph.paint.p = child_table_p; 564 apaint->u.glyph.paint.insert_root_transform = 0; 565 apaint->u.glyph.glyphID = FT_NEXT_USHORT( p ); 566 567 return 1; 568 } 569 570 else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSFORM ) 571 { 572 apaint->u.transform.paint.p = child_table_p; 573 apaint->u.transform.paint.insert_root_transform = 0; 574 575 if ( !get_child_table_pointer( colr, paint_base, &p, &child_table_p ) ) 576 return 0; 577 578 p = child_table_p; 579 580 /* 581 * The following matrix coefficients are encoded as 582 * OpenType 16.16 fixed-point values. 583 */ 584 apaint->u.transform.affine.xx = FT_NEXT_LONG( p ); 585 apaint->u.transform.affine.yx = FT_NEXT_LONG( p ); 586 apaint->u.transform.affine.xy = FT_NEXT_LONG( p ); 587 apaint->u.transform.affine.yy = FT_NEXT_LONG( p ); 588 apaint->u.transform.affine.dx = FT_NEXT_LONG( p ); 589 apaint->u.transform.affine.dy = FT_NEXT_LONG( p ); 590 591 return 1; 592 } 593 594 else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSLATE ) 595 { 596 apaint->u.translate.paint.p = child_table_p; 597 apaint->u.translate.paint.insert_root_transform = 0; 598 599 apaint->u.translate.dx = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); 600 apaint->u.translate.dy = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); 601 602 return 1; 603 } 604 605 else if ( apaint->format == 606 FT_COLR_PAINTFORMAT_SCALE || 607 (FT_PaintFormat_Internal)apaint->format == 608 FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER || 609 (FT_PaintFormat_Internal)apaint->format == 610 FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM || 611 (FT_PaintFormat_Internal)apaint->format == 612 FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER ) 613 { 614 apaint->u.scale.paint.p = child_table_p; 615 apaint->u.scale.paint.insert_root_transform = 0; 616 617 /* All scale paints get at least one scale value. */ 618 apaint->u.scale.scale_x = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) ); 619 620 /* Non-uniform ones read an extra y value. */ 621 if ( apaint->format == 622 FT_COLR_PAINTFORMAT_SCALE || 623 (FT_PaintFormat_Internal)apaint->format == 624 FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER ) 625 apaint->u.scale.scale_y = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) ); 626 else 627 apaint->u.scale.scale_y = apaint->u.scale.scale_x; 628 629 /* Scale paints that have a center read center coordinates, */ 630 /* otherwise the center is (0,0). */ 631 if ( (FT_PaintFormat_Internal)apaint->format == 632 FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER || 633 (FT_PaintFormat_Internal)apaint->format == 634 FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER ) 635 { 636 apaint->u.scale.center_x = INT_TO_FIXED( FT_NEXT_SHORT ( p ) ); 637 apaint->u.scale.center_y = INT_TO_FIXED( FT_NEXT_SHORT ( p ) ); 638 } 639 else 640 { 641 apaint->u.scale.center_x = 0; 642 apaint->u.scale.center_y = 0; 643 } 644 645 /* FT 'COLR' v1 API output format always returns fully defined */ 646 /* structs; we thus set the format to the public API value. */ 647 apaint->format = FT_COLR_PAINTFORMAT_SCALE; 648 649 return 1; 650 } 651 652 else if ( apaint->format == FT_COLR_PAINTFORMAT_ROTATE || 653 (FT_PaintFormat_Internal)apaint->format == 654 FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER ) 655 { 656 apaint->u.rotate.paint.p = child_table_p; 657 apaint->u.rotate.paint.insert_root_transform = 0; 658 659 apaint->u.rotate.angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) ); 660 661 if ( (FT_PaintFormat_Internal)apaint->format == 662 FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER ) 663 { 664 apaint->u.rotate.center_x = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); 665 apaint->u.rotate.center_y = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); 666 } 667 else 668 { 669 apaint->u.rotate.center_x = 0; 670 apaint->u.rotate.center_y = 0; 671 } 672 673 apaint->format = FT_COLR_PAINTFORMAT_ROTATE; 674 675 return 1; 676 } 677 678 else if ( apaint->format == FT_COLR_PAINTFORMAT_SKEW || 679 (FT_PaintFormat_Internal)apaint->format == 680 FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER ) 681 { 682 apaint->u.skew.paint.p = child_table_p; 683 apaint->u.skew.paint.insert_root_transform = 0; 684 685 apaint->u.skew.x_skew_angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) ); 686 apaint->u.skew.y_skew_angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) ); 687 688 if ( (FT_PaintFormat_Internal)apaint->format == 689 FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER ) 690 { 691 apaint->u.skew.center_x = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); 692 apaint->u.skew.center_y = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); 693 } 694 else 695 { 696 apaint->u.skew.center_x = 0; 697 apaint->u.skew.center_y = 0; 698 } 699 700 apaint->format = FT_COLR_PAINTFORMAT_SKEW; 701 702 return 1; 703 } 704 705 else if ( apaint->format == FT_COLR_PAINTFORMAT_COMPOSITE ) 706 { 707 FT_UInt composite_mode; 708 709 710 apaint->u.composite.source_paint.p = child_table_p; 711 apaint->u.composite.source_paint.insert_root_transform = 0; 712 713 composite_mode = FT_NEXT_BYTE( p ); 714 if ( composite_mode >= FT_COLR_COMPOSITE_MAX ) 715 return 0; 716 717 apaint->u.composite.composite_mode = (FT_Composite_Mode)composite_mode; 718 719 if ( !get_child_table_pointer( colr, paint_base, &p, &child_table_p ) ) 720 return 0; 721 722 apaint->u.composite.backdrop_paint.p = 723 child_table_p; 724 apaint->u.composite.backdrop_paint.insert_root_transform = 725 0; 726 727 return 1; 728 } 729 730 return 0; 731 } 732 733 734 static FT_Bool find_base_glyph_v1_record(FT_Byte * base_glyph_begin,FT_UInt num_base_glyph,FT_UInt glyph_id,BaseGlyphV1Record * record)735 find_base_glyph_v1_record( FT_Byte * base_glyph_begin, 736 FT_UInt num_base_glyph, 737 FT_UInt glyph_id, 738 BaseGlyphV1Record *record ) 739 { 740 FT_UInt min = 0; 741 FT_UInt max = num_base_glyph; 742 743 744 while ( min < max ) 745 { 746 FT_UInt mid = min + ( max - min ) / 2; 747 748 /* 749 * `base_glyph_begin` is the beginning of `BaseGlyphV1List`; 750 * skip `numBaseGlyphV1Records` by adding 4 to start binary search 751 * in the array of `BaseGlyphV1Record`. 752 */ 753 FT_Byte *p = base_glyph_begin + 4 + mid * BASE_GLYPH_PAINT_RECORD_SIZE; 754 755 FT_UShort gid = FT_NEXT_USHORT( p ); 756 757 758 if ( gid < glyph_id ) 759 min = mid + 1; 760 else if (gid > glyph_id ) 761 max = mid; 762 else 763 { 764 record->gid = gid; 765 record->paint_offset = FT_NEXT_ULONG ( p ); 766 return 1; 767 } 768 } 769 770 return 0; 771 } 772 773 774 FT_LOCAL_DEF( FT_Bool ) tt_face_get_colr_glyph_paint(TT_Face face,FT_UInt base_glyph,FT_Color_Root_Transform root_transform,FT_OpaquePaint * opaque_paint)775 tt_face_get_colr_glyph_paint( TT_Face face, 776 FT_UInt base_glyph, 777 FT_Color_Root_Transform root_transform, 778 FT_OpaquePaint* opaque_paint ) 779 { 780 Colr* colr = (Colr*)face->colr; 781 BaseGlyphV1Record base_glyph_v1_record; 782 FT_Byte* p; 783 784 if ( !colr || !colr->table ) 785 return 0; 786 787 if ( colr->version < 1 || !colr->num_base_glyphs_v1 || 788 !colr->base_glyphs_v1 ) 789 return 0; 790 791 if ( opaque_paint->p ) 792 return 0; 793 794 if ( !find_base_glyph_v1_record( colr->base_glyphs_v1, 795 colr->num_base_glyphs_v1, 796 base_glyph, 797 &base_glyph_v1_record ) ) 798 return 0; 799 800 if ( !base_glyph_v1_record.paint_offset || 801 base_glyph_v1_record.paint_offset > colr->table_size ) 802 return 0; 803 804 p = (FT_Byte*)( colr->base_glyphs_v1 + 805 base_glyph_v1_record.paint_offset ); 806 if ( p >= ( (FT_Byte*)colr->table + colr->table_size ) ) 807 return 0; 808 809 opaque_paint->p = p; 810 811 if ( root_transform == FT_COLOR_INCLUDE_ROOT_TRANSFORM ) 812 opaque_paint->insert_root_transform = 1; 813 else 814 opaque_paint->insert_root_transform = 0; 815 816 return 1; 817 } 818 819 820 FT_LOCAL_DEF( FT_Bool ) tt_face_get_color_glyph_clipbox(TT_Face face,FT_UInt base_glyph,FT_ClipBox * clip_box)821 tt_face_get_color_glyph_clipbox( TT_Face face, 822 FT_UInt base_glyph, 823 FT_ClipBox* clip_box ) 824 { 825 Colr* colr; 826 827 FT_Byte *p, *p1, *clip_base; 828 829 FT_Byte clip_list_format; 830 FT_ULong num_clip_boxes, i; 831 FT_UShort gid_start, gid_end; 832 FT_UInt32 clip_box_offset; 833 FT_Byte format; 834 835 const FT_Byte num_corners = 4; 836 FT_Vector corners[4]; 837 FT_Byte j; 838 FT_BBox font_clip_box; 839 840 841 colr = (Colr*)face->colr; 842 if ( !colr ) 843 return 0; 844 845 if ( !colr->clip_list ) 846 return 0; 847 848 p = colr->clip_list; 849 850 clip_base = p; 851 clip_list_format = FT_NEXT_BYTE ( p ); 852 853 /* Format byte used here to be able to upgrade ClipList for >16bit */ 854 /* glyph ids; for now we can expect it to be 0. */ 855 if ( !( clip_list_format == 1 ) ) 856 return 0; 857 858 num_clip_boxes = FT_NEXT_ULONG( p ); 859 860 for ( i = 0; i < num_clip_boxes; ++i ) 861 { 862 gid_start = FT_NEXT_USHORT( p ); 863 gid_end = FT_NEXT_USHORT( p ); 864 clip_box_offset = FT_NEXT_UOFF3( p ); 865 866 if ( base_glyph >= gid_start && base_glyph <= gid_end ) 867 { 868 p1 = (FT_Byte*)( clip_base + clip_box_offset ); 869 870 if ( p1 >= ( (FT_Byte*)colr->table + colr->table_size ) ) 871 return 0; 872 873 format = FT_NEXT_BYTE( p1 ); 874 875 if ( format > 1 ) 876 return 0; 877 878 /* `face->root.size->metrics.x_scale` and `y_scale` are factors */ 879 /* that scale a font unit value in integers to a 26.6 fixed value */ 880 /* according to the requested size, see for example */ 881 /* `ft_recompute_scaled_metrics`. */ 882 font_clip_box.xMin = FT_MulFix( FT_NEXT_SHORT( p1 ), 883 face->root.size->metrics.x_scale ); 884 font_clip_box.yMin = FT_MulFix( FT_NEXT_SHORT( p1 ), 885 face->root.size->metrics.x_scale ); 886 font_clip_box.xMax = FT_MulFix( FT_NEXT_SHORT( p1 ), 887 face->root.size->metrics.x_scale ); 888 font_clip_box.yMax = FT_MulFix( FT_NEXT_SHORT( p1 ), 889 face->root.size->metrics.x_scale ); 890 891 /* Make 4 corner points (xMin, yMin), (xMax, yMax) and transform */ 892 /* them. If we we would only transform two corner points and */ 893 /* span a rectangle based on those, the rectangle may become too */ 894 /* small to cover the glyph. */ 895 corners[0].x = font_clip_box.xMin; 896 corners[1].x = font_clip_box.xMin; 897 corners[2].x = font_clip_box.xMax; 898 corners[3].x = font_clip_box.xMax; 899 900 corners[0].y = font_clip_box.yMin; 901 corners[1].y = font_clip_box.yMax; 902 corners[2].y = font_clip_box.yMax; 903 corners[3].y = font_clip_box.yMin; 904 905 for ( j = 0; j < num_corners; ++j ) 906 { 907 if ( face->root.internal->transform_flags & 1 ) 908 FT_Vector_Transform( &corners[j], 909 &face->root.internal->transform_matrix ); 910 911 if ( face->root.internal->transform_flags & 2 ) 912 { 913 corners[j].x += face->root.internal->transform_delta.x; 914 corners[j].y += face->root.internal->transform_delta.y; 915 } 916 } 917 918 clip_box->bottom_left = corners[0]; 919 clip_box->top_left = corners[1]; 920 clip_box->top_right = corners[2]; 921 clip_box->bottom_right = corners[3]; 922 923 return 1; 924 } 925 } 926 927 return 0; 928 } 929 930 931 FT_LOCAL_DEF( FT_Bool ) tt_face_get_paint_layers(TT_Face face,FT_LayerIterator * iterator,FT_OpaquePaint * opaque_paint)932 tt_face_get_paint_layers( TT_Face face, 933 FT_LayerIterator* iterator, 934 FT_OpaquePaint* opaque_paint ) 935 { 936 FT_Byte* p = NULL; 937 FT_Byte* p_first_layer = NULL; 938 FT_Byte* p_paint = NULL; 939 FT_UInt32 paint_offset; 940 941 Colr* colr; 942 943 944 if ( iterator->layer == iterator->num_layers ) 945 return 0; 946 947 colr = (Colr*)face->colr; 948 if ( !colr ) 949 return 0; 950 951 /* 952 * We have an iterator pointing at a paint offset as part of the 953 * `paintOffset` array in `LayerV1List`. 954 */ 955 p = iterator->p; 956 957 /* 958 * First ensure that p is within COLRv1. 959 */ 960 if ( p < colr->layers_v1 || 961 p >= ( (FT_Byte*)colr->table + colr->table_size ) ) 962 return 0; 963 964 /* 965 * Do a cursor sanity check of the iterator. Counting backwards from 966 * where it stands, we need to end up at a position after the beginning 967 * of the `LayerV1List` table and not after the end of the 968 * `LayerV1List`. 969 */ 970 p_first_layer = p - 971 iterator->layer * LAYER_V1_LIST_PAINT_OFFSET_SIZE - 972 LAYER_V1_LIST_NUM_LAYERS_SIZE; 973 if ( p_first_layer < (FT_Byte*)colr->layers_v1 ) 974 return 0; 975 if ( p_first_layer >= (FT_Byte*)( 976 colr->layers_v1 + LAYER_V1_LIST_NUM_LAYERS_SIZE + 977 colr->num_layers_v1 * LAYER_V1_LIST_PAINT_OFFSET_SIZE ) ) 978 return 0; 979 980 paint_offset = 981 FT_NEXT_ULONG( p ); 982 opaque_paint->insert_root_transform = 983 0; 984 985 p_paint = (FT_Byte*)( colr->layers_v1 + paint_offset ); 986 987 if ( p_paint < colr->paints_start_v1 || 988 p_paint >= ( (FT_Byte*)colr->table + colr->table_size ) ) 989 return 0; 990 991 opaque_paint->p = p_paint; 992 993 iterator->p = p; 994 995 iterator->layer++; 996 997 return 1; 998 } 999 1000 1001 FT_LOCAL_DEF( FT_Bool ) tt_face_get_colorline_stops(TT_Face face,FT_ColorStop * color_stop,FT_ColorStopIterator * iterator)1002 tt_face_get_colorline_stops( TT_Face face, 1003 FT_ColorStop* color_stop, 1004 FT_ColorStopIterator *iterator ) 1005 { 1006 Colr* colr = (Colr*)face->colr; 1007 1008 FT_Byte* p; 1009 1010 1011 if ( !colr || !colr->table ) 1012 return 0; 1013 1014 if ( iterator->current_color_stop >= iterator->num_color_stops ) 1015 return 0; 1016 1017 if ( iterator->p + 1018 ( ( iterator->num_color_stops - iterator->current_color_stop ) * 1019 COLOR_STOP_SIZE ) > 1020 ( (FT_Byte *)colr->table + colr->table_size ) ) 1021 return 0; 1022 1023 /* Iterator points at first `ColorStop` of `ColorLine`. */ 1024 p = iterator->p; 1025 1026 color_stop->stop_offset = FT_NEXT_SHORT( p ); 1027 1028 color_stop->color.palette_index = FT_NEXT_USHORT( p ); 1029 1030 color_stop->color.alpha = FT_NEXT_SHORT( p ); 1031 1032 iterator->p = p; 1033 iterator->current_color_stop++; 1034 1035 return 1; 1036 } 1037 1038 1039 FT_LOCAL_DEF( FT_Bool ) tt_face_get_paint(TT_Face face,FT_OpaquePaint opaque_paint,FT_COLR_Paint * paint)1040 tt_face_get_paint( TT_Face face, 1041 FT_OpaquePaint opaque_paint, 1042 FT_COLR_Paint* paint ) 1043 { 1044 Colr* colr = (Colr*)face->colr; 1045 FT_OpaquePaint next_paint; 1046 FT_Matrix ft_root_scale; 1047 1048 if ( !colr || !colr->base_glyphs_v1 || !colr->table ) 1049 return 0; 1050 1051 if ( opaque_paint.insert_root_transform ) 1052 { 1053 /* 'COLR' v1 glyph information is returned in unscaled coordinates, 1054 * i.e., `FT_Size` is not applied or multiplied into the values. When 1055 * client applications draw color glyphs, they can request to include 1056 * a top-level transform, which includes the active `x_scale` and 1057 * `y_scale` information for scaling the glyph, as well the additional 1058 * transform and translate configured through `FT_Set_Transform`. 1059 * This allows client applications to apply this top-level transform 1060 * to the graphics context first and only once, then have gradient and 1061 * contour scaling applied correctly when performing the additional 1062 * drawing operations for subsequenct paints. Prepare this initial 1063 * transform here. 1064 */ 1065 paint->format = FT_COLR_PAINTFORMAT_TRANSFORM; 1066 1067 next_paint.p = opaque_paint.p; 1068 next_paint.insert_root_transform = 0; 1069 paint->u.transform.paint = next_paint; 1070 1071 /* `x_scale` and `y_scale` are in 26.6 format, representing the scale 1072 * factor to get from font units to requested size. However, expected 1073 * return values are in 16.16, so we shift accordingly with rounding. 1074 */ 1075 ft_root_scale.xx = ( face->root.size->metrics.x_scale + 32 ) >> 6; 1076 ft_root_scale.xy = 0; 1077 ft_root_scale.yx = 0; 1078 ft_root_scale.yy = ( face->root.size->metrics.y_scale + 32 ) >> 6; 1079 1080 if ( face->root.internal->transform_flags & 1 ) 1081 FT_Matrix_Multiply( &face->root.internal->transform_matrix, 1082 &ft_root_scale ); 1083 1084 paint->u.transform.affine.xx = ft_root_scale.xx; 1085 paint->u.transform.affine.xy = ft_root_scale.xy; 1086 paint->u.transform.affine.yx = ft_root_scale.yx; 1087 paint->u.transform.affine.yy = ft_root_scale.yy; 1088 1089 /* The translation is specified in 26.6 format and, according to the 1090 * documentation of `FT_Set_Translate`, is performed on the character 1091 * size given in the last call to `FT_Set_Char_Size`. The 1092 * 'PaintTransform' paint table's `FT_Affine23` format expects 1093 * values in 16.16 format, thus we need to shift by 10 bits. 1094 */ 1095 if ( face->root.internal->transform_flags & 2 ) 1096 { 1097 paint->u.transform.affine.dx = 1098 face->root.internal->transform_delta.x * ( 1 << 10 ); 1099 paint->u.transform.affine.dy = 1100 face->root.internal->transform_delta.y * ( 1 << 10 ); 1101 } 1102 else 1103 { 1104 paint->u.transform.affine.dx = 0; 1105 paint->u.transform.affine.dy = 0; 1106 } 1107 1108 return 1; 1109 } 1110 1111 return read_paint( colr, opaque_paint.p, paint ); 1112 } 1113 1114 1115 FT_LOCAL_DEF( FT_Error ) tt_face_colr_blend_layer(TT_Face face,FT_UInt color_index,FT_GlyphSlot dstSlot,FT_GlyphSlot srcSlot)1116 tt_face_colr_blend_layer( TT_Face face, 1117 FT_UInt color_index, 1118 FT_GlyphSlot dstSlot, 1119 FT_GlyphSlot srcSlot ) 1120 { 1121 FT_Error error; 1122 1123 FT_UInt x, y; 1124 FT_Byte b, g, r, alpha; 1125 1126 FT_ULong size; 1127 FT_Byte* src; 1128 FT_Byte* dst; 1129 1130 1131 if ( !dstSlot->bitmap.buffer ) 1132 { 1133 /* Initialize destination of color bitmap */ 1134 /* with the size of first component. */ 1135 dstSlot->bitmap_left = srcSlot->bitmap_left; 1136 dstSlot->bitmap_top = srcSlot->bitmap_top; 1137 1138 dstSlot->bitmap.width = srcSlot->bitmap.width; 1139 dstSlot->bitmap.rows = srcSlot->bitmap.rows; 1140 dstSlot->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA; 1141 dstSlot->bitmap.pitch = (int)dstSlot->bitmap.width * 4; 1142 dstSlot->bitmap.num_grays = 256; 1143 1144 size = dstSlot->bitmap.rows * (unsigned int)dstSlot->bitmap.pitch; 1145 1146 error = ft_glyphslot_alloc_bitmap( dstSlot, size ); 1147 if ( error ) 1148 return error; 1149 1150 FT_MEM_ZERO( dstSlot->bitmap.buffer, size ); 1151 } 1152 else 1153 { 1154 /* Resize destination if needed such that new component fits. */ 1155 FT_Int x_min, x_max, y_min, y_max; 1156 1157 1158 x_min = FT_MIN( dstSlot->bitmap_left, srcSlot->bitmap_left ); 1159 x_max = FT_MAX( dstSlot->bitmap_left + (FT_Int)dstSlot->bitmap.width, 1160 srcSlot->bitmap_left + (FT_Int)srcSlot->bitmap.width ); 1161 1162 y_min = FT_MIN( dstSlot->bitmap_top - (FT_Int)dstSlot->bitmap.rows, 1163 srcSlot->bitmap_top - (FT_Int)srcSlot->bitmap.rows ); 1164 y_max = FT_MAX( dstSlot->bitmap_top, srcSlot->bitmap_top ); 1165 1166 if ( x_min != dstSlot->bitmap_left || 1167 x_max != dstSlot->bitmap_left + (FT_Int)dstSlot->bitmap.width || 1168 y_min != dstSlot->bitmap_top - (FT_Int)dstSlot->bitmap.rows || 1169 y_max != dstSlot->bitmap_top ) 1170 { 1171 FT_Memory memory = face->root.memory; 1172 1173 FT_UInt width = (FT_UInt)( x_max - x_min ); 1174 FT_UInt rows = (FT_UInt)( y_max - y_min ); 1175 FT_UInt pitch = width * 4; 1176 1177 FT_Byte* buf = NULL; 1178 FT_Byte* p; 1179 FT_Byte* q; 1180 1181 1182 size = rows * pitch; 1183 if ( FT_ALLOC( buf, size ) ) 1184 return error; 1185 1186 p = dstSlot->bitmap.buffer; 1187 q = buf + 1188 (int)pitch * ( y_max - dstSlot->bitmap_top ) + 1189 4 * ( dstSlot->bitmap_left - x_min ); 1190 1191 for ( y = 0; y < dstSlot->bitmap.rows; y++ ) 1192 { 1193 FT_MEM_COPY( q, p, dstSlot->bitmap.width * 4 ); 1194 1195 p += dstSlot->bitmap.pitch; 1196 q += pitch; 1197 } 1198 1199 ft_glyphslot_set_bitmap( dstSlot, buf ); 1200 1201 dstSlot->bitmap_top = y_max; 1202 dstSlot->bitmap_left = x_min; 1203 1204 dstSlot->bitmap.width = width; 1205 dstSlot->bitmap.rows = rows; 1206 dstSlot->bitmap.pitch = (int)pitch; 1207 1208 dstSlot->internal->flags |= FT_GLYPH_OWN_BITMAP; 1209 dstSlot->format = FT_GLYPH_FORMAT_BITMAP; 1210 } 1211 } 1212 1213 if ( color_index == 0xFFFF ) 1214 { 1215 if ( face->have_foreground_color ) 1216 { 1217 b = face->foreground_color.blue; 1218 g = face->foreground_color.green; 1219 r = face->foreground_color.red; 1220 alpha = face->foreground_color.alpha; 1221 } 1222 else 1223 { 1224 if ( face->palette_data.palette_flags && 1225 ( face->palette_data.palette_flags[face->palette_index] & 1226 FT_PALETTE_FOR_DARK_BACKGROUND ) ) 1227 { 1228 /* white opaque */ 1229 b = 0xFF; 1230 g = 0xFF; 1231 r = 0xFF; 1232 alpha = 0xFF; 1233 } 1234 else 1235 { 1236 /* black opaque */ 1237 b = 0x00; 1238 g = 0x00; 1239 r = 0x00; 1240 alpha = 0xFF; 1241 } 1242 } 1243 } 1244 else 1245 { 1246 b = face->palette[color_index].blue; 1247 g = face->palette[color_index].green; 1248 r = face->palette[color_index].red; 1249 alpha = face->palette[color_index].alpha; 1250 } 1251 1252 /* XXX Convert if srcSlot.bitmap is not grey? */ 1253 src = srcSlot->bitmap.buffer; 1254 dst = dstSlot->bitmap.buffer + 1255 dstSlot->bitmap.pitch * ( dstSlot->bitmap_top - srcSlot->bitmap_top ) + 1256 4 * ( srcSlot->bitmap_left - dstSlot->bitmap_left ); 1257 1258 for ( y = 0; y < srcSlot->bitmap.rows; y++ ) 1259 { 1260 for ( x = 0; x < srcSlot->bitmap.width; x++ ) 1261 { 1262 int aa = src[x]; 1263 int fa = alpha * aa / 255; 1264 1265 int fb = b * fa / 255; 1266 int fg = g * fa / 255; 1267 int fr = r * fa / 255; 1268 1269 int ba2 = 255 - fa; 1270 1271 int bb = dst[4 * x + 0]; 1272 int bg = dst[4 * x + 1]; 1273 int br = dst[4 * x + 2]; 1274 int ba = dst[4 * x + 3]; 1275 1276 1277 dst[4 * x + 0] = (FT_Byte)( bb * ba2 / 255 + fb ); 1278 dst[4 * x + 1] = (FT_Byte)( bg * ba2 / 255 + fg ); 1279 dst[4 * x + 2] = (FT_Byte)( br * ba2 / 255 + fr ); 1280 dst[4 * x + 3] = (FT_Byte)( ba * ba2 / 255 + fa ); 1281 } 1282 1283 src += srcSlot->bitmap.pitch; 1284 dst += dstSlot->bitmap.pitch; 1285 } 1286 1287 return FT_Err_Ok; 1288 } 1289 1290 #else /* !TT_CONFIG_OPTION_COLOR_LAYERS */ 1291 1292 /* ANSI C doesn't like empty source files */ 1293 typedef int _tt_colr_dummy; 1294 1295 #endif /* !TT_CONFIG_OPTION_COLOR_LAYERS */ 1296 1297 /* EOF */ 1298