1 /***************************************************************************/ 2 /* */ 3 /* ftglyph.c */ 4 /* */ 5 /* FreeType convenience functions to handle glyphs (body). */ 6 /* */ 7 /* Copyright 1996-2018 by */ 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9 /* */ 10 /* This file is part of the FreeType project, and may only be used, */ 11 /* modified, and distributed under the terms of the FreeType project */ 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13 /* this file you indicate that you have read the license and */ 14 /* understand and accept it fully. */ 15 /* */ 16 /***************************************************************************/ 17 18 /*************************************************************************/ 19 /* */ 20 /* This file contains the definition of several convenience functions */ 21 /* that can be used by client applications to easily retrieve glyph */ 22 /* bitmaps and outlines from a given face. */ 23 /* */ 24 /* These functions should be optional if you are writing a font server */ 25 /* or text layout engine on top of FreeType. However, they are pretty */ 26 /* handy for many other simple uses of the library. */ 27 /* */ 28 /*************************************************************************/ 29 30 31 #include <ft2build.h> 32 #include FT_INTERNAL_DEBUG_H 33 34 #include FT_GLYPH_H 35 #include FT_OUTLINE_H 36 #include FT_BITMAP_H 37 #include FT_INTERNAL_OBJECTS_H 38 39 #include "basepic.h" 40 41 /*************************************************************************/ 42 /* */ 43 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 44 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 45 /* messages during execution. */ 46 /* */ 47 #undef FT_COMPONENT 48 #define FT_COMPONENT trace_glyph 49 50 51 /*************************************************************************/ 52 /*************************************************************************/ 53 /**** ****/ 54 /**** FT_BitmapGlyph support ****/ 55 /**** ****/ 56 /*************************************************************************/ 57 /*************************************************************************/ 58 59 FT_CALLBACK_DEF( FT_Error ) 60 ft_bitmap_glyph_init( FT_Glyph bitmap_glyph, 61 FT_GlyphSlot slot ) 62 { 63 FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph; 64 FT_Error error = FT_Err_Ok; 65 FT_Library library = FT_GLYPH( glyph )->library; 66 67 68 if ( slot->format != FT_GLYPH_FORMAT_BITMAP ) 342 goto Exit; 343 344 copy->advance = source->advance; 345 copy->format = source->format; 346 347 if ( clazz->glyph_copy ) 348 error = clazz->glyph_copy( source, copy ); 349 350 if ( error ) 351 FT_Done_Glyph( copy ); 352 else 353 *target = copy; 354 355 Exit: 356 return error; 357 } 358 359 360 /* documentation is in ftglyph.h */ 361 362 FT_EXPORT_DEF( FT_Error ) 363 FT_Get_Glyph( FT_GlyphSlot slot, 364 FT_Glyph *aglyph ) 365 { 366 FT_Library library; 367 FT_Error error; 368 FT_Glyph glyph; 369 370 const FT_Glyph_Class* clazz = NULL; 371 372 373 if ( !slot ) 374 return FT_THROW( Invalid_Slot_Handle ); 375 376 library = slot->library; 377 378 if ( !aglyph ) 379 return FT_THROW( Invalid_Argument ); 380 381 /* if it is a bitmap, that's easy :-) */ 382 if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) 383 clazz = FT_BITMAP_GLYPH_CLASS_GET; 384 385 /* if it is an outline */ 386 else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) 387 clazz = FT_OUTLINE_GLYPH_CLASS_GET; 388 389 else 390 { 391 /* try to find a renderer that supports the glyph image format */ 392 FT_Renderer render = FT_Lookup_Renderer( library, slot->format, 0 ); 393 394 395 if ( render ) 396 clazz = &render->glyph_class; 397 } 398 399 if ( !clazz ) 400 { 401 error = FT_THROW( Invalid_Glyph_Format ); 402 goto Exit; 403 } 404 405 /* create FT_Glyph object */ 406 error = ft_new_glyph( library, clazz, &glyph ); 407 if ( error ) 408 goto Exit; 409 410 /* copy advance while converting 26.6 to 16.16 format */ 411 if ( slot->advance.x >= 0x8000L * 64 || 412 slot->advance.x <= -0x8000L * 64 ) 413 { 414 FT_ERROR(( "FT_Get_Glyph: advance width too large\n" )); 415 error = FT_THROW( Invalid_Argument ); 416 goto Exit2; 417 } 418 if ( slot->advance.y >= 0x8000L * 64 || 419 slot->advance.y <= -0x8000L * 64 ) 420 { 421 FT_ERROR(( "FT_Get_Glyph: advance height too large\n" )); 422 error = FT_THROW( Invalid_Argument ); 423 goto Exit2; 424 } 425 426 glyph->advance.x = slot->advance.x * 1024; 427 glyph->advance.y = slot->advance.y * 1024; 428 429 /* now import the image from the glyph slot */ 430 error = clazz->glyph_init( glyph, slot ); 431 432 Exit2: 433 /* if an error occurred, destroy the glyph */ 434 if ( error ) 435 FT_Done_Glyph( glyph ); 436 else 437 *aglyph = glyph; 438 439 Exit: 440 return error; 441 } 442 443 444 /* documentation is in ftglyph.h */ 445 446 FT_EXPORT_DEF( FT_Error ) 447 FT_Glyph_Transform( FT_Glyph glyph, 448 FT_Matrix* matrix, 449 FT_Vector* delta ) 450 { 488 return; 489 490 acbox->xMin = acbox->yMin = acbox->xMax = acbox->yMax = 0; 491 492 if ( !glyph || !glyph->clazz ) 493 return; 494 495 clazz = glyph->clazz; 496 if ( !clazz->glyph_bbox ) 497 return; 498 499 /* retrieve bbox in 26.6 coordinates */ 500 clazz->glyph_bbox( glyph, acbox ); 501 502 /* perform grid fitting if needed */ 503 if ( bbox_mode == FT_GLYPH_BBOX_GRIDFIT || 504 bbox_mode == FT_GLYPH_BBOX_PIXELS ) 505 { 506 acbox->xMin = FT_PIX_FLOOR( acbox->xMin ); 507 acbox->yMin = FT_PIX_FLOOR( acbox->yMin ); 508 acbox->xMax = FT_PIX_CEIL( acbox->xMax ); 509 acbox->yMax = FT_PIX_CEIL( acbox->yMax ); 510 } 511 512 /* convert to integer pixels if needed */ 513 if ( bbox_mode == FT_GLYPH_BBOX_TRUNCATE || 514 bbox_mode == FT_GLYPH_BBOX_PIXELS ) 515 { 516 acbox->xMin >>= 6; 517 acbox->yMin >>= 6; 518 acbox->xMax >>= 6; 519 acbox->yMax >>= 6; 520 } 521 } 522 523 524 /* documentation is in ftglyph.h */ 525 526 FT_EXPORT_DEF( FT_Error ) 527 FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, 528 FT_Render_Mode render_mode, 529 FT_Vector* origin, 530 FT_Bool destroy ) 531 { 532 FT_GlyphSlotRec dummy; 533 FT_GlyphSlot_InternalRec dummy_internal; 534 FT_Error error = FT_Err_Ok; 535 FT_Glyph b, glyph; 536 FT_BitmapGlyph bitmap = NULL; 537 const FT_Glyph_Class* clazz; 538 539 /* FT_BITMAP_GLYPH_CLASS_GET dereferences `library' in PIC mode */ 540 FT_Library library; 541 542 543 /* check argument */ 544 if ( !the_glyph ) 545 goto Bad; 546 glyph = *the_glyph; 547 if ( !glyph ) 548 goto Bad; 549 550 clazz = glyph->clazz; 551 library = glyph->library; 552 if ( !library || !clazz ) 553 goto Bad; 554 555 /* when called with a bitmap glyph, do nothing and return successfully */ 556 if ( clazz == FT_BITMAP_GLYPH_CLASS_GET ) 557 goto Exit; 558 559 if ( !clazz->glyph_prepare ) 560 goto Bad; 561 562 /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */ 563 /* then calling FT_Render_Glyph_Internal() */ 564 565 FT_ZERO( &dummy ); 566 FT_ZERO( &dummy_internal ); 567 dummy.internal = &dummy_internal; 568 dummy.library = library; 569 dummy.format = clazz->glyph_format; 570 571 /* create result bitmap glyph */ 572 error = ft_new_glyph( library, FT_BITMAP_GLYPH_CLASS_GET, &b ); 573 if ( error ) 574 goto Exit; 575 bitmap = (FT_BitmapGlyph)b; 576 577 #if 1 578 /* if `origin' is set, translate the glyph image */ 579 if ( origin ) 580 FT_Glyph_Transform( glyph, 0, origin ); 581 #else 582 FT_UNUSED( origin ); 583 #endif 584 585 /* prepare dummy slot for rendering */ 586 error = clazz->glyph_prepare( glyph, &dummy ); 587 if ( !error ) 588 error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode ); 589 590 #if 1 591 if ( !destroy && origin ) 592 { | 1 /**************************************************************************** 2 * 3 * ftglyph.c 4 * 5 * FreeType convenience functions to handle glyphs (body). 6 * 7 * Copyright (C) 1996-2019 by 8 * David Turner, Robert Wilhelm, and Werner Lemberg. 9 * 10 * This file is part of the FreeType project, and may only be used, 11 * modified, and distributed under the terms of the FreeType project 12 * license, LICENSE.TXT. By continuing to use, modify, or distribute 13 * this file you indicate that you have read the license and 14 * understand and accept it fully. 15 * 16 */ 17 18 /************************************************************************** 19 * 20 * This file contains the definition of several convenience functions 21 * that can be used by client applications to easily retrieve glyph 22 * bitmaps and outlines from a given face. 23 * 24 * These functions should be optional if you are writing a font server 25 * or text layout engine on top of FreeType. However, they are pretty 26 * handy for many other simple uses of the library. 27 * 28 */ 29 30 31 #include <ft2build.h> 32 #include FT_INTERNAL_DEBUG_H 33 34 #include FT_GLYPH_H 35 #include FT_OUTLINE_H 36 #include FT_BITMAP_H 37 #include FT_INTERNAL_OBJECTS_H 38 39 40 /************************************************************************** 41 * 42 * The macro FT_COMPONENT is used in trace mode. It is an implicit 43 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log 44 * messages during execution. 45 */ 46 #undef FT_COMPONENT 47 #define FT_COMPONENT glyph 48 49 50 /*************************************************************************/ 51 /*************************************************************************/ 52 /**** ****/ 53 /**** FT_BitmapGlyph support ****/ 54 /**** ****/ 55 /*************************************************************************/ 56 /*************************************************************************/ 57 58 FT_CALLBACK_DEF( FT_Error ) 59 ft_bitmap_glyph_init( FT_Glyph bitmap_glyph, 60 FT_GlyphSlot slot ) 61 { 62 FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph; 63 FT_Error error = FT_Err_Ok; 64 FT_Library library = FT_GLYPH( glyph )->library; 65 66 67 if ( slot->format != FT_GLYPH_FORMAT_BITMAP ) 341 goto Exit; 342 343 copy->advance = source->advance; 344 copy->format = source->format; 345 346 if ( clazz->glyph_copy ) 347 error = clazz->glyph_copy( source, copy ); 348 349 if ( error ) 350 FT_Done_Glyph( copy ); 351 else 352 *target = copy; 353 354 Exit: 355 return error; 356 } 357 358 359 /* documentation is in ftglyph.h */ 360 361 FT_EXPORT( FT_Error ) 362 FT_New_Glyph( FT_Library library, 363 FT_Glyph_Format format, 364 FT_Glyph *aglyph ) 365 { 366 const FT_Glyph_Class* clazz = NULL; 367 368 if ( !library || !aglyph ) 369 return FT_THROW( Invalid_Argument ); 370 371 /* if it is a bitmap, that's easy :-) */ 372 if ( format == FT_GLYPH_FORMAT_BITMAP ) 373 clazz = &ft_bitmap_glyph_class; 374 375 /* if it is an outline */ 376 else if ( format == FT_GLYPH_FORMAT_OUTLINE ) 377 clazz = &ft_outline_glyph_class; 378 379 else 380 { 381 /* try to find a renderer that supports the glyph image format */ 382 FT_Renderer render = FT_Lookup_Renderer( library, format, 0 ); 383 384 385 if ( render ) 386 clazz = &render->glyph_class; 387 } 388 389 if ( !clazz ) 390 return FT_THROW( Invalid_Glyph_Format ); 391 392 /* create FT_Glyph object */ 393 return ft_new_glyph( library, clazz, aglyph ); 394 } 395 396 397 /* documentation is in ftglyph.h */ 398 399 FT_EXPORT_DEF( FT_Error ) 400 FT_Get_Glyph( FT_GlyphSlot slot, 401 FT_Glyph *aglyph ) 402 { 403 FT_Error error; 404 FT_Glyph glyph; 405 406 407 if ( !slot ) 408 return FT_THROW( Invalid_Slot_Handle ); 409 410 if ( !aglyph ) 411 return FT_THROW( Invalid_Argument ); 412 413 /* create FT_Glyph object */ 414 error = FT_New_Glyph( slot->library, slot->format, &glyph ); 415 if ( error ) 416 goto Exit; 417 418 /* copy advance while converting 26.6 to 16.16 format */ 419 if ( slot->advance.x >= 0x8000L * 64 || 420 slot->advance.x <= -0x8000L * 64 ) 421 { 422 FT_ERROR(( "FT_Get_Glyph: advance width too large\n" )); 423 error = FT_THROW( Invalid_Argument ); 424 goto Exit2; 425 } 426 if ( slot->advance.y >= 0x8000L * 64 || 427 slot->advance.y <= -0x8000L * 64 ) 428 { 429 FT_ERROR(( "FT_Get_Glyph: advance height too large\n" )); 430 error = FT_THROW( Invalid_Argument ); 431 goto Exit2; 432 } 433 434 glyph->advance.x = slot->advance.x * 1024; 435 glyph->advance.y = slot->advance.y * 1024; 436 437 /* now import the image from the glyph slot */ 438 error = glyph->clazz->glyph_init( glyph, slot ); 439 440 Exit2: 441 /* if an error occurred, destroy the glyph */ 442 if ( error ) 443 FT_Done_Glyph( glyph ); 444 else 445 *aglyph = glyph; 446 447 Exit: 448 return error; 449 } 450 451 452 /* documentation is in ftglyph.h */ 453 454 FT_EXPORT_DEF( FT_Error ) 455 FT_Glyph_Transform( FT_Glyph glyph, 456 FT_Matrix* matrix, 457 FT_Vector* delta ) 458 { 496 return; 497 498 acbox->xMin = acbox->yMin = acbox->xMax = acbox->yMax = 0; 499 500 if ( !glyph || !glyph->clazz ) 501 return; 502 503 clazz = glyph->clazz; 504 if ( !clazz->glyph_bbox ) 505 return; 506 507 /* retrieve bbox in 26.6 coordinates */ 508 clazz->glyph_bbox( glyph, acbox ); 509 510 /* perform grid fitting if needed */ 511 if ( bbox_mode == FT_GLYPH_BBOX_GRIDFIT || 512 bbox_mode == FT_GLYPH_BBOX_PIXELS ) 513 { 514 acbox->xMin = FT_PIX_FLOOR( acbox->xMin ); 515 acbox->yMin = FT_PIX_FLOOR( acbox->yMin ); 516 acbox->xMax = FT_PIX_CEIL_LONG( acbox->xMax ); 517 acbox->yMax = FT_PIX_CEIL_LONG( acbox->yMax ); 518 } 519 520 /* convert to integer pixels if needed */ 521 if ( bbox_mode == FT_GLYPH_BBOX_TRUNCATE || 522 bbox_mode == FT_GLYPH_BBOX_PIXELS ) 523 { 524 acbox->xMin >>= 6; 525 acbox->yMin >>= 6; 526 acbox->xMax >>= 6; 527 acbox->yMax >>= 6; 528 } 529 } 530 531 532 /* documentation is in ftglyph.h */ 533 534 FT_EXPORT_DEF( FT_Error ) 535 FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, 536 FT_Render_Mode render_mode, 537 FT_Vector* origin, 538 FT_Bool destroy ) 539 { 540 FT_GlyphSlotRec dummy; 541 FT_GlyphSlot_InternalRec dummy_internal; 542 FT_Error error = FT_Err_Ok; 543 FT_Glyph b, glyph; 544 FT_BitmapGlyph bitmap = NULL; 545 const FT_Glyph_Class* clazz; 546 547 FT_Library library; 548 549 550 /* check argument */ 551 if ( !the_glyph ) 552 goto Bad; 553 glyph = *the_glyph; 554 if ( !glyph ) 555 goto Bad; 556 557 clazz = glyph->clazz; 558 library = glyph->library; 559 if ( !library || !clazz ) 560 goto Bad; 561 562 /* when called with a bitmap glyph, do nothing and return successfully */ 563 if ( clazz == &ft_bitmap_glyph_class ) 564 goto Exit; 565 566 if ( !clazz->glyph_prepare ) 567 goto Bad; 568 569 /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */ 570 /* then calling FT_Render_Glyph_Internal() */ 571 572 FT_ZERO( &dummy ); 573 FT_ZERO( &dummy_internal ); 574 dummy.internal = &dummy_internal; 575 dummy.library = library; 576 dummy.format = clazz->glyph_format; 577 578 /* create result bitmap glyph */ 579 error = ft_new_glyph( library, &ft_bitmap_glyph_class, &b ); 580 if ( error ) 581 goto Exit; 582 bitmap = (FT_BitmapGlyph)b; 583 584 #if 1 585 /* if `origin' is set, translate the glyph image */ 586 if ( origin ) 587 FT_Glyph_Transform( glyph, 0, origin ); 588 #else 589 FT_UNUSED( origin ); 590 #endif 591 592 /* prepare dummy slot for rendering */ 593 error = clazz->glyph_prepare( glyph, &dummy ); 594 if ( !error ) 595 error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode ); 596 597 #if 1 598 if ( !destroy && origin ) 599 { |