1 /**************************************************************************** 2 * 3 * ftstroke.h 4 * 5 * FreeType path stroker (specification). 6 * 7 * Copyright (C) 2002-2020 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 #ifndef FTSTROKE_H_ 20 #define FTSTROKE_H_ 21 22 #include <ft2build.h> 23 #include FT_OUTLINE_H 24 #include FT_GLYPH_H 25 26 27 FT_BEGIN_HEADER 28 29 30 /************************************************************************** 31 * 32 * @section: 33 * glyph_stroker 34 * 35 * @title: 36 * Glyph Stroker 37 * 38 * @abstract: 39 * Generating bordered and stroked glyphs. 40 * 41 * @description: 42 * This component generates stroked outlines of a given vectorial glyph. 43 * It also allows you to retrieve the 'outside' and/or the 'inside' 44 * borders of the stroke. 45 * 46 * This can be useful to generate 'bordered' glyph, i.e., glyphs 47 * displayed with a coloured (and anti-aliased) border around their 48 * shape. 49 * 50 * @order: 51 * FT_Stroker 52 * 53 * FT_Stroker_LineJoin 54 * FT_Stroker_LineCap 55 * FT_StrokerBorder 56 * 57 * FT_Outline_GetInsideBorder 58 * FT_Outline_GetOutsideBorder 59 * 60 * FT_Glyph_Stroke 61 * FT_Glyph_StrokeBorder 62 * 63 * FT_Stroker_New 64 * FT_Stroker_Set 65 * FT_Stroker_Rewind 66 * FT_Stroker_ParseOutline 67 * FT_Stroker_Done 68 * 69 * FT_Stroker_BeginSubPath 70 * FT_Stroker_EndSubPath 71 * 72 * FT_Stroker_LineTo 73 * FT_Stroker_ConicTo 74 * FT_Stroker_CubicTo 75 * 76 * FT_Stroker_GetBorderCounts 77 * FT_Stroker_ExportBorder 78 * FT_Stroker_GetCounts 79 * FT_Stroker_Export 80 * 81 */ 82 83 84 /************************************************************************** 85 * 86 * @type: 87 * FT_Stroker 88 * 89 * @description: 90 * Opaque handle to a path stroker object. 91 */ 92 typedef struct FT_StrokerRec_* FT_Stroker; 93 94 95 /************************************************************************** 96 * 97 * @enum: 98 * FT_Stroker_LineJoin 99 * 100 * @description: 101 * These values determine how two joining lines are rendered in a 102 * stroker. 103 * 104 * @values: 105 * FT_STROKER_LINEJOIN_ROUND :: 106 * Used to render rounded line joins. Circular arcs are used to join 107 * two lines smoothly. 108 * 109 * FT_STROKER_LINEJOIN_BEVEL :: 110 * Used to render beveled line joins. The outer corner of the joined 111 * lines is filled by enclosing the triangular region of the corner 112 * with a straight line between the outer corners of each stroke. 113 * 114 * FT_STROKER_LINEJOIN_MITER_FIXED :: 115 * Used to render mitered line joins, with fixed bevels if the miter 116 * limit is exceeded. The outer edges of the strokes for the two 117 * segments are extended until they meet at an angle. A bevel join 118 * (see above) is used if the segments meet at too sharp an angle and 119 * the outer edges meet beyond a distance corresponding to the meter 120 * limit. This prevents long spikes being created. 121 * `FT_STROKER_LINEJOIN_MITER_FIXED` generates a miter line join as 122 * used in PostScript and PDF. 123 * 124 * FT_STROKER_LINEJOIN_MITER_VARIABLE :: 125 * FT_STROKER_LINEJOIN_MITER :: 126 * Used to render mitered line joins, with variable bevels if the miter 127 * limit is exceeded. The intersection of the strokes is clipped 128 * perpendicularly to the bisector, at a distance corresponding to 129 * the miter limit. This prevents long spikes being created. 130 * `FT_STROKER_LINEJOIN_MITER_VARIABLE` generates a mitered line join 131 * as used in XPS. `FT_STROKER_LINEJOIN_MITER` is an alias for 132 * `FT_STROKER_LINEJOIN_MITER_VARIABLE`, retained for backward 133 * compatibility. 134 */ 135 typedef enum FT_Stroker_LineJoin_ 136 { 137 FT_STROKER_LINEJOIN_ROUND = 0, 138 FT_STROKER_LINEJOIN_BEVEL = 1, 139 FT_STROKER_LINEJOIN_MITER_VARIABLE = 2, 140 FT_STROKER_LINEJOIN_MITER = FT_STROKER_LINEJOIN_MITER_VARIABLE, 141 FT_STROKER_LINEJOIN_MITER_FIXED = 3 142 143 } FT_Stroker_LineJoin; 144 145 146 /************************************************************************** 147 * 148 * @enum: 149 * FT_Stroker_LineCap 150 * 151 * @description: 152 * These values determine how the end of opened sub-paths are rendered in 153 * a stroke. 154 * 155 * @values: 156 * FT_STROKER_LINECAP_BUTT :: 157 * The end of lines is rendered as a full stop on the last point 158 * itself. 159 * 160 * FT_STROKER_LINECAP_ROUND :: 161 * The end of lines is rendered as a half-circle around the last point. 162 * 163 * FT_STROKER_LINECAP_SQUARE :: 164 * The end of lines is rendered as a square around the last point. 165 */ 166 typedef enum FT_Stroker_LineCap_ 167 { 168 FT_STROKER_LINECAP_BUTT = 0, 169 FT_STROKER_LINECAP_ROUND, 170 FT_STROKER_LINECAP_SQUARE 171 172 } FT_Stroker_LineCap; 173 174 175 /************************************************************************** 176 * 177 * @enum: 178 * FT_StrokerBorder 179 * 180 * @description: 181 * These values are used to select a given stroke border in 182 * @FT_Stroker_GetBorderCounts and @FT_Stroker_ExportBorder. 183 * 184 * @values: 185 * FT_STROKER_BORDER_LEFT :: 186 * Select the left border, relative to the drawing direction. 187 * 188 * FT_STROKER_BORDER_RIGHT :: 189 * Select the right border, relative to the drawing direction. 190 * 191 * @note: 192 * Applications are generally interested in the 'inside' and 'outside' 193 * borders. However, there is no direct mapping between these and the 194 * 'left' and 'right' ones, since this really depends on the glyph's 195 * drawing orientation, which varies between font formats. 196 * 197 * You can however use @FT_Outline_GetInsideBorder and 198 * @FT_Outline_GetOutsideBorder to get these. 199 */ 200 typedef enum FT_StrokerBorder_ 201 { 202 FT_STROKER_BORDER_LEFT = 0, 203 FT_STROKER_BORDER_RIGHT 204 205 } FT_StrokerBorder; 206 207 208 /************************************************************************** 209 * 210 * @function: 211 * FT_Outline_GetInsideBorder 212 * 213 * @description: 214 * Retrieve the @FT_StrokerBorder value corresponding to the 'inside' 215 * borders of a given outline. 216 * 217 * @input: 218 * outline :: 219 * The source outline handle. 220 * 221 * @return: 222 * The border index. @FT_STROKER_BORDER_RIGHT for empty or invalid 223 * outlines. 224 */ 225 FT_EXPORT( FT_StrokerBorder ) 226 FT_Outline_GetInsideBorder( FT_Outline* outline ); 227 228 229 /************************************************************************** 230 * 231 * @function: 232 * FT_Outline_GetOutsideBorder 233 * 234 * @description: 235 * Retrieve the @FT_StrokerBorder value corresponding to the 'outside' 236 * borders of a given outline. 237 * 238 * @input: 239 * outline :: 240 * The source outline handle. 241 * 242 * @return: 243 * The border index. @FT_STROKER_BORDER_LEFT for empty or invalid 244 * outlines. 245 */ 246 FT_EXPORT( FT_StrokerBorder ) 247 FT_Outline_GetOutsideBorder( FT_Outline* outline ); 248 249 250 /************************************************************************** 251 * 252 * @function: 253 * FT_Stroker_New 254 * 255 * @description: 256 * Create a new stroker object. 257 * 258 * @input: 259 * library :: 260 * FreeType library handle. 261 * 262 * @output: 263 * astroker :: 264 * A new stroker object handle. `NULL` in case of error. 265 * 266 * @return: 267 * FreeType error code. 0~means success. 268 */ 269 FT_EXPORT( FT_Error ) 270 FT_Stroker_New( FT_Library library, 271 FT_Stroker *astroker ); 272 273 274 /************************************************************************** 275 * 276 * @function: 277 * FT_Stroker_Set 278 * 279 * @description: 280 * Reset a stroker object's attributes. 281 * 282 * @input: 283 * stroker :: 284 * The target stroker handle. 285 * 286 * radius :: 287 * The border radius. 288 * 289 * line_cap :: 290 * The line cap style. 291 * 292 * line_join :: 293 * The line join style. 294 * 295 * miter_limit :: 296 * The maximum reciprocal sine of half-angle at the miter join, 297 * expressed as 16.16 fixed point value. 298 * 299 * @note: 300 * The `radius` is expressed in the same units as the outline 301 * coordinates. 302 * 303 * The `miter_limit` multiplied by the `radius` gives the maximum size 304 * of a miter spike, at which it is clipped for 305 * @FT_STROKER_LINEJOIN_MITER_VARIABLE or replaced with a bevel join for 306 * @FT_STROKER_LINEJOIN_MITER_FIXED. 307 * 308 * This function calls @FT_Stroker_Rewind automatically. 309 */ 310 FT_EXPORT( void ) 311 FT_Stroker_Set( FT_Stroker stroker, 312 FT_Fixed radius, 313 FT_Stroker_LineCap line_cap, 314 FT_Stroker_LineJoin line_join, 315 FT_Fixed miter_limit ); 316 317 318 /************************************************************************** 319 * 320 * @function: 321 * FT_Stroker_Rewind 322 * 323 * @description: 324 * Reset a stroker object without changing its attributes. You should 325 * call this function before beginning a new series of calls to 326 * @FT_Stroker_BeginSubPath or @FT_Stroker_EndSubPath. 327 * 328 * @input: 329 * stroker :: 330 * The target stroker handle. 331 */ 332 FT_EXPORT( void ) 333 FT_Stroker_Rewind( FT_Stroker stroker ); 334 335 336 /************************************************************************** 337 * 338 * @function: 339 * FT_Stroker_ParseOutline 340 * 341 * @description: 342 * A convenience function used to parse a whole outline with the stroker. 343 * The resulting outline(s) can be retrieved later by functions like 344 * @FT_Stroker_GetCounts and @FT_Stroker_Export. 345 * 346 * @input: 347 * stroker :: 348 * The target stroker handle. 349 * 350 * outline :: 351 * The source outline. 352 * 353 * opened :: 354 * A boolean. If~1, the outline is treated as an open path instead of 355 * a closed one. 356 * 357 * @return: 358 * FreeType error code. 0~means success. 359 * 360 * @note: 361 * If `opened` is~0 (the default), the outline is treated as a closed 362 * path, and the stroker generates two distinct 'border' outlines. 363 * 364 * If `opened` is~1, the outline is processed as an open path, and the 365 * stroker generates a single 'stroke' outline. 366 * 367 * This function calls @FT_Stroker_Rewind automatically. 368 */ 369 FT_EXPORT( FT_Error ) 370 FT_Stroker_ParseOutline( FT_Stroker stroker, 371 FT_Outline* outline, 372 FT_Bool opened ); 373 374 375 /************************************************************************** 376 * 377 * @function: 378 * FT_Stroker_BeginSubPath 379 * 380 * @description: 381 * Start a new sub-path in the stroker. 382 * 383 * @input: 384 * stroker :: 385 * The target stroker handle. 386 * 387 * to :: 388 * A pointer to the start vector. 389 * 390 * open :: 391 * A boolean. If~1, the sub-path is treated as an open one. 392 * 393 * @return: 394 * FreeType error code. 0~means success. 395 * 396 * @note: 397 * This function is useful when you need to stroke a path that is not 398 * stored as an @FT_Outline object. 399 */ 400 FT_EXPORT( FT_Error ) 401 FT_Stroker_BeginSubPath( FT_Stroker stroker, 402 FT_Vector* to, 403 FT_Bool open ); 404 405 406 /************************************************************************** 407 * 408 * @function: 409 * FT_Stroker_EndSubPath 410 * 411 * @description: 412 * Close the current sub-path in the stroker. 413 * 414 * @input: 415 * stroker :: 416 * The target stroker handle. 417 * 418 * @return: 419 * FreeType error code. 0~means success. 420 * 421 * @note: 422 * You should call this function after @FT_Stroker_BeginSubPath. If the 423 * subpath was not 'opened', this function 'draws' a single line segment 424 * to the start position when needed. 425 */ 426 FT_EXPORT( FT_Error ) 427 FT_Stroker_EndSubPath( FT_Stroker stroker ); 428 429 430 /************************************************************************** 431 * 432 * @function: 433 * FT_Stroker_LineTo 434 * 435 * @description: 436 * 'Draw' a single line segment in the stroker's current sub-path, from 437 * the last position. 438 * 439 * @input: 440 * stroker :: 441 * The target stroker handle. 442 * 443 * to :: 444 * A pointer to the destination point. 445 * 446 * @return: 447 * FreeType error code. 0~means success. 448 * 449 * @note: 450 * You should call this function between @FT_Stroker_BeginSubPath and 451 * @FT_Stroker_EndSubPath. 452 */ 453 FT_EXPORT( FT_Error ) 454 FT_Stroker_LineTo( FT_Stroker stroker, 455 FT_Vector* to ); 456 457 458 /************************************************************************** 459 * 460 * @function: 461 * FT_Stroker_ConicTo 462 * 463 * @description: 464 * 'Draw' a single quadratic Bezier in the stroker's current sub-path, 465 * from the last position. 466 * 467 * @input: 468 * stroker :: 469 * The target stroker handle. 470 * 471 * control :: 472 * A pointer to a Bezier control point. 473 * 474 * to :: 475 * A pointer to the destination point. 476 * 477 * @return: 478 * FreeType error code. 0~means success. 479 * 480 * @note: 481 * You should call this function between @FT_Stroker_BeginSubPath and 482 * @FT_Stroker_EndSubPath. 483 */ 484 FT_EXPORT( FT_Error ) 485 FT_Stroker_ConicTo( FT_Stroker stroker, 486 FT_Vector* control, 487 FT_Vector* to ); 488 489 490 /************************************************************************** 491 * 492 * @function: 493 * FT_Stroker_CubicTo 494 * 495 * @description: 496 * 'Draw' a single cubic Bezier in the stroker's current sub-path, from 497 * the last position. 498 * 499 * @input: 500 * stroker :: 501 * The target stroker handle. 502 * 503 * control1 :: 504 * A pointer to the first Bezier control point. 505 * 506 * control2 :: 507 * A pointer to second Bezier control point. 508 * 509 * to :: 510 * A pointer to the destination point. 511 * 512 * @return: 513 * FreeType error code. 0~means success. 514 * 515 * @note: 516 * You should call this function between @FT_Stroker_BeginSubPath and 517 * @FT_Stroker_EndSubPath. 518 */ 519 FT_EXPORT( FT_Error ) 520 FT_Stroker_CubicTo( FT_Stroker stroker, 521 FT_Vector* control1, 522 FT_Vector* control2, 523 FT_Vector* to ); 524 525 526 /************************************************************************** 527 * 528 * @function: 529 * FT_Stroker_GetBorderCounts 530 * 531 * @description: 532 * Call this function once you have finished parsing your paths with the 533 * stroker. It returns the number of points and contours necessary to 534 * export one of the 'border' or 'stroke' outlines generated by the 535 * stroker. 536 * 537 * @input: 538 * stroker :: 539 * The target stroker handle. 540 * 541 * border :: 542 * The border index. 543 * 544 * @output: 545 * anum_points :: 546 * The number of points. 547 * 548 * anum_contours :: 549 * The number of contours. 550 * 551 * @return: 552 * FreeType error code. 0~means success. 553 * 554 * @note: 555 * When an outline, or a sub-path, is 'closed', the stroker generates two 556 * independent 'border' outlines, named 'left' and 'right'. 557 * 558 * When the outline, or a sub-path, is 'opened', the stroker merges the 559 * 'border' outlines with caps. The 'left' border receives all points, 560 * while the 'right' border becomes empty. 561 * 562 * Use the function @FT_Stroker_GetCounts instead if you want to retrieve 563 * the counts associated to both borders. 564 */ 565 FT_EXPORT( FT_Error ) 566 FT_Stroker_GetBorderCounts( FT_Stroker stroker, 567 FT_StrokerBorder border, 568 FT_UInt *anum_points, 569 FT_UInt *anum_contours ); 570 571 572 /************************************************************************** 573 * 574 * @function: 575 * FT_Stroker_ExportBorder 576 * 577 * @description: 578 * Call this function after @FT_Stroker_GetBorderCounts to export the 579 * corresponding border to your own @FT_Outline structure. 580 * 581 * Note that this function appends the border points and contours to your 582 * outline, but does not try to resize its arrays. 583 * 584 * @input: 585 * stroker :: 586 * The target stroker handle. 587 * 588 * border :: 589 * The border index. 590 * 591 * outline :: 592 * The target outline handle. 593 * 594 * @note: 595 * Always call this function after @FT_Stroker_GetBorderCounts to get 596 * sure that there is enough room in your @FT_Outline object to receive 597 * all new data. 598 * 599 * When an outline, or a sub-path, is 'closed', the stroker generates two 600 * independent 'border' outlines, named 'left' and 'right'. 601 * 602 * When the outline, or a sub-path, is 'opened', the stroker merges the 603 * 'border' outlines with caps. The 'left' border receives all points, 604 * while the 'right' border becomes empty. 605 * 606 * Use the function @FT_Stroker_Export instead if you want to retrieve 607 * all borders at once. 608 */ 609 FT_EXPORT( void ) 610 FT_Stroker_ExportBorder( FT_Stroker stroker, 611 FT_StrokerBorder border, 612 FT_Outline* outline ); 613 614 615 /************************************************************************** 616 * 617 * @function: 618 * FT_Stroker_GetCounts 619 * 620 * @description: 621 * Call this function once you have finished parsing your paths with the 622 * stroker. It returns the number of points and contours necessary to 623 * export all points/borders from the stroked outline/path. 624 * 625 * @input: 626 * stroker :: 627 * The target stroker handle. 628 * 629 * @output: 630 * anum_points :: 631 * The number of points. 632 * 633 * anum_contours :: 634 * The number of contours. 635 * 636 * @return: 637 * FreeType error code. 0~means success. 638 */ 639 FT_EXPORT( FT_Error ) 640 FT_Stroker_GetCounts( FT_Stroker stroker, 641 FT_UInt *anum_points, 642 FT_UInt *anum_contours ); 643 644 645 /************************************************************************** 646 * 647 * @function: 648 * FT_Stroker_Export 649 * 650 * @description: 651 * Call this function after @FT_Stroker_GetBorderCounts to export all 652 * borders to your own @FT_Outline structure. 653 * 654 * Note that this function appends the border points and contours to your 655 * outline, but does not try to resize its arrays. 656 * 657 * @input: 658 * stroker :: 659 * The target stroker handle. 660 * 661 * outline :: 662 * The target outline handle. 663 */ 664 FT_EXPORT( void ) 665 FT_Stroker_Export( FT_Stroker stroker, 666 FT_Outline* outline ); 667 668 669 /************************************************************************** 670 * 671 * @function: 672 * FT_Stroker_Done 673 * 674 * @description: 675 * Destroy a stroker object. 676 * 677 * @input: 678 * stroker :: 679 * A stroker handle. Can be `NULL`. 680 */ 681 FT_EXPORT( void ) 682 FT_Stroker_Done( FT_Stroker stroker ); 683 684 685 /************************************************************************** 686 * 687 * @function: 688 * FT_Glyph_Stroke 689 * 690 * @description: 691 * Stroke a given outline glyph object with a given stroker. 692 * 693 * @inout: 694 * pglyph :: 695 * Source glyph handle on input, new glyph handle on output. 696 * 697 * @input: 698 * stroker :: 699 * A stroker handle. 700 * 701 * destroy :: 702 * A Boolean. If~1, the source glyph object is destroyed on success. 703 * 704 * @return: 705 * FreeType error code. 0~means success. 706 * 707 * @note: 708 * The source glyph is untouched in case of error. 709 * 710 * Adding stroke may yield a significantly wider and taller glyph 711 * depending on how large of a radius was used to stroke the glyph. You 712 * may need to manually adjust horizontal and vertical advance amounts to 713 * account for this added size. 714 */ 715 FT_EXPORT( FT_Error ) 716 FT_Glyph_Stroke( FT_Glyph *pglyph, 717 FT_Stroker stroker, 718 FT_Bool destroy ); 719 720 721 /************************************************************************** 722 * 723 * @function: 724 * FT_Glyph_StrokeBorder 725 * 726 * @description: 727 * Stroke a given outline glyph object with a given stroker, but only 728 * return either its inside or outside border. 729 * 730 * @inout: 731 * pglyph :: 732 * Source glyph handle on input, new glyph handle on output. 733 * 734 * @input: 735 * stroker :: 736 * A stroker handle. 737 * 738 * inside :: 739 * A Boolean. If~1, return the inside border, otherwise the outside 740 * border. 741 * 742 * destroy :: 743 * A Boolean. If~1, the source glyph object is destroyed on success. 744 * 745 * @return: 746 * FreeType error code. 0~means success. 747 * 748 * @note: 749 * The source glyph is untouched in case of error. 750 * 751 * Adding stroke may yield a significantly wider and taller glyph 752 * depending on how large of a radius was used to stroke the glyph. You 753 * may need to manually adjust horizontal and vertical advance amounts to 754 * account for this added size. 755 */ 756 FT_EXPORT( FT_Error ) 757 FT_Glyph_StrokeBorder( FT_Glyph *pglyph, 758 FT_Stroker stroker, 759 FT_Bool inside, 760 FT_Bool destroy ); 761 762 /* */ 763 764 FT_END_HEADER 765 766 #endif /* FTSTROKE_H_ */ 767 768 769 /* END */ 770 771 772 /* Local Variables: */ 773 /* coding: utf-8 */ 774 /* End: */