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