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