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