1 /* 2 * Copyright 2006 The Android Open Source Project 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkPaint_DEFINED 9 #define SkPaint_DEFINED 10 11 #include "SkBlendMode.h" 12 #include "SkColor.h" 13 #include "SkFilterQuality.h" 14 #include "SkMatrix.h" 15 #include "SkRefCnt.h" 16 17 class SkAutoDescriptor; 18 class SkAutoGlyphCache; 19 class SkColorFilter; 20 class SkData; 21 class SkDescriptor; 22 class SkDrawLooper; 23 class SkReadBuffer; 24 class SkWriteBuffer; 25 class SkGlyph; 26 struct SkRect; 27 class SkGlyphCache; 28 class SkImageFilter; 29 class SkMaskFilter; 30 class SkPath; 31 class SkPathEffect; 32 struct SkPoint; 33 class SkRasterizer; 34 struct SkScalerContextEffects; 35 class SkShader; 36 class SkSurfaceProps; 37 class SkTextBlob; 38 class SkTypeface; 39 40 /** \class SkPaint 41 42 The SkPaint class holds the style and color information about how to draw 43 geometries, text and bitmaps. 44 */ 45 class SK_API SkPaint { 46 public: 47 SkPaint(); 48 SkPaint(const SkPaint& paint); 49 SkPaint(SkPaint&& paint); 50 ~SkPaint(); 51 52 SkPaint& operator=(const SkPaint&); 53 SkPaint& operator=(SkPaint&&); 54 55 /** operator== may give false negatives: two paints that draw equivalently 56 may return false. It will never give false positives: two paints that 57 are not equivalent always return false. 58 */ 59 SK_API friend bool operator==(const SkPaint& a, const SkPaint& b); 60 friend bool operator!=(const SkPaint& a, const SkPaint& b) { 61 return !(a == b); 62 } 63 64 /** getHash() is a shallow hash, with the same limitations as operator==. 65 * If operator== returns true for two paints, getHash() returns the same value for each. 66 */ 67 uint32_t getHash() const; 68 69 void flatten(SkWriteBuffer&) const; 70 void unflatten(SkReadBuffer&); 71 72 /** Restores the paint to its initial settings. 73 */ 74 void reset(); 75 76 /** Specifies the level of hinting to be performed. These names are taken 77 from the Gnome/Cairo names for the same. They are translated into 78 Freetype concepts the same as in cairo-ft-font.c: 79 kNo_Hinting -> FT_LOAD_NO_HINTING 80 kSlight_Hinting -> FT_LOAD_TARGET_LIGHT 81 kNormal_Hinting -> <default, no option> 82 kFull_Hinting -> <same as kNormalHinting, unless we are rendering 83 subpixel glyphs, in which case TARGET_LCD or 84 TARGET_LCD_V is used> 85 */ 86 enum Hinting { 87 kNo_Hinting = 0, 88 kSlight_Hinting = 1, 89 kNormal_Hinting = 2, //!< this is the default 90 kFull_Hinting = 3 91 }; 92 93 Hinting getHinting() const { 94 return static_cast<Hinting>(fBitfields.fHinting); 95 } 96 97 void setHinting(Hinting hintingLevel); 98 99 /** Specifies the bit values that are stored in the paint's flags. 100 */ 101 enum Flags { 102 kAntiAlias_Flag = 0x01, //!< mask to enable antialiasing 103 kDither_Flag = 0x04, //!< mask to enable dithering 104 kFakeBoldText_Flag = 0x20, //!< mask to enable fake-bold text 105 kLinearText_Flag = 0x40, //!< mask to enable linear-text 106 kSubpixelText_Flag = 0x80, //!< mask to enable subpixel text positioning 107 kDevKernText_Flag = 0x100, //!< mask to enable device kerning text 108 kLCDRenderText_Flag = 0x200, //!< mask to enable subpixel glyph renderering 109 kEmbeddedBitmapText_Flag = 0x400, //!< mask to enable embedded bitmap strikes 110 kAutoHinting_Flag = 0x800, //!< mask to force Freetype's autohinter 111 kVerticalText_Flag = 0x1000, 112 kGenA8FromLCD_Flag = 0x2000, // hack for GDI -- do not use if you can help it 113 // when adding extra flags, note that the fFlags member is specified 114 // with a bit-width and you'll have to expand it. 115 116 kAllFlags = 0xFFFF, 117 118 #ifdef SK_SUPPORT_LEGACY_PAINT_TEXTDECORATION 119 kUnderlineText_Flag = 0x08, 120 kStrikeThruText_Flag = 0x10, 121 #endif 122 }; 123 124 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 125 enum ReserveFlags { 126 // These are not used by paint, but the bits are reserved for private use by the 127 // android framework. 128 kUnderlineText_ReserveFlag = 0x08, //!< mask to enable underline text 129 kStrikeThruText_ReserveFlag = 0x10, //!< mask to enable strike-thru text 130 }; 131 #endif 132 133 /** Return the paint's flags. Use the Flag enum to test flag values. 134 @return the paint's flags (see enums ending in _Flag for bit masks) 135 */ 136 uint32_t getFlags() const { return fBitfields.fFlags; } 137 138 /** Set the paint's flags. Use the Flag enum to specific flag values. 139 @param flags The new flag bits for the paint (see Flags enum) 140 */ 141 void setFlags(uint32_t flags); 142 143 /** Helper for getFlags(), returning true if kAntiAlias_Flag bit is set 144 @return true if the antialias bit is set in the paint's flags. 145 */ 146 bool isAntiAlias() const { 147 return SkToBool(this->getFlags() & kAntiAlias_Flag); 148 } 149 150 /** Helper for setFlags(), setting or clearing the kAntiAlias_Flag bit 151 @param aa true to enable antialiasing, false to disable it 152 */ 153 void setAntiAlias(bool aa); 154 155 /** Helper for getFlags(), returning true if kDither_Flag bit is set 156 @return true if the dithering bit is set in the paint's flags. 157 */ 158 bool isDither() const { 159 return SkToBool(this->getFlags() & kDither_Flag); 160 } 161 162 /** Helper for setFlags(), setting or clearing the kDither_Flag bit 163 @param dither true to enable dithering, false to disable it 164 */ 165 void setDither(bool dither); 166 167 /** Helper for getFlags(), returning true if kLinearText_Flag bit is set 168 @return true if the lineartext bit is set in the paint's flags 169 */ 170 bool isLinearText() const { 171 return SkToBool(this->getFlags() & kLinearText_Flag); 172 } 173 174 /** Helper for setFlags(), setting or clearing the kLinearText_Flag bit 175 @param linearText true to set the linearText bit in the paint's flags, 176 false to clear it. 177 */ 178 void setLinearText(bool linearText); 179 180 /** Helper for getFlags(), returning true if kSubpixelText_Flag bit is set 181 @return true if the lineartext bit is set in the paint's flags 182 */ 183 bool isSubpixelText() const { 184 return SkToBool(this->getFlags() & kSubpixelText_Flag); 185 } 186 187 /** 188 * Helper for setFlags(), setting or clearing the kSubpixelText_Flag. 189 * @param subpixelText true to set the subpixelText bit in the paint's 190 * flags, false to clear it. 191 */ 192 void setSubpixelText(bool subpixelText); 193 194 bool isLCDRenderText() const { 195 return SkToBool(this->getFlags() & kLCDRenderText_Flag); 196 } 197 198 /** 199 * Helper for setFlags(), setting or clearing the kLCDRenderText_Flag. 200 * Note: antialiasing must also be on for lcd rendering 201 * @param lcdText true to set the LCDRenderText bit in the paint's flags, 202 * false to clear it. 203 */ 204 void setLCDRenderText(bool lcdText); 205 206 bool isEmbeddedBitmapText() const { 207 return SkToBool(this->getFlags() & kEmbeddedBitmapText_Flag); 208 } 209 210 /** Helper for setFlags(), setting or clearing the kEmbeddedBitmapText_Flag bit 211 @param useEmbeddedBitmapText true to set the kEmbeddedBitmapText bit in the paint's flags, 212 false to clear it. 213 */ 214 void setEmbeddedBitmapText(bool useEmbeddedBitmapText); 215 216 bool isAutohinted() const { 217 return SkToBool(this->getFlags() & kAutoHinting_Flag); 218 } 219 220 /** Helper for setFlags(), setting or clearing the kAutoHinting_Flag bit 221 @param useAutohinter true to set the kEmbeddedBitmapText bit in the 222 paint's flags, 223 false to clear it. 224 */ 225 void setAutohinted(bool useAutohinter); 226 227 bool isVerticalText() const { 228 return SkToBool(this->getFlags() & kVerticalText_Flag); 229 } 230 231 /** 232 * Helper for setting or clearing the kVerticalText_Flag bit in 233 * setFlags(...). 234 * 235 * If this bit is set, then advances are treated as Y values rather than 236 * X values, and drawText will places its glyphs vertically rather than 237 * horizontally. 238 */ 239 void setVerticalText(bool); 240 241 /** Helper for getFlags(), returning true if kUnderlineText_Flag bit is set 242 @return true if the underlineText bit is set in the paint's flags. 243 */ 244 #ifdef SK_SUPPORT_LEGACY_PAINT_TEXTDECORATION 245 bool isUnderlineText() const { return false; } 246 #endif 247 248 /** Helper for getFlags(), returns true if kStrikeThruText_Flag bit is set 249 @return true if the strikeThruText bit is set in the paint's flags. 250 */ 251 #ifdef SK_SUPPORT_LEGACY_PAINT_TEXTDECORATION 252 bool isStrikeThruText() const { return false; } 253 #endif 254 255 /** Helper for getFlags(), returns true if kFakeBoldText_Flag bit is set 256 @return true if the kFakeBoldText_Flag bit is set in the paint's flags. 257 */ 258 bool isFakeBoldText() const { 259 return SkToBool(this->getFlags() & kFakeBoldText_Flag); 260 } 261 262 /** Helper for setFlags(), setting or clearing the kFakeBoldText_Flag bit 263 @param fakeBoldText true to set the kFakeBoldText_Flag bit in the paint's 264 flags, false to clear it. 265 */ 266 void setFakeBoldText(bool fakeBoldText); 267 268 /** Helper for getFlags(), returns true if kDevKernText_Flag bit is set 269 @return true if the kernText bit is set in the paint's flags. 270 */ 271 bool isDevKernText() const { 272 return SkToBool(this->getFlags() & kDevKernText_Flag); 273 } 274 275 /** Helper for setFlags(), setting or clearing the kKernText_Flag bit 276 @param kernText true to set the kKernText_Flag bit in the paint's 277 flags, false to clear it. 278 */ 279 void setDevKernText(bool devKernText); 280 281 /** 282 * Return the filter level. This affects the quality (and performance) of 283 * drawing scaled images. 284 */ 285 SkFilterQuality getFilterQuality() const { 286 return (SkFilterQuality)fBitfields.fFilterQuality; 287 } 288 289 /** 290 * Set the filter quality. This affects the quality (and performance) of 291 * drawing scaled images. 292 */ 293 void setFilterQuality(SkFilterQuality quality); 294 295 /** Styles apply to rect, oval, path, and text. 296 Bitmaps are always drawn in "fill", and lines are always drawn in 297 "stroke". 298 299 Note: strokeandfill implicitly draws the result with 300 SkPath::kWinding_FillType, so if the original path is even-odd, the 301 results may not appear the same as if it was drawn twice, filled and 302 then stroked. 303 */ 304 enum Style { 305 kFill_Style, //!< fill the geometry 306 kStroke_Style, //!< stroke the geometry 307 kStrokeAndFill_Style, //!< fill and stroke the geometry 308 }; 309 enum { 310 kStyleCount = kStrokeAndFill_Style + 1 311 }; 312 313 /** Return the paint's style, used for controlling how primitives' 314 geometries are interpreted (except for drawBitmap, which always assumes 315 kFill_Style). 316 @return the paint's Style 317 */ 318 Style getStyle() const { return (Style)fBitfields.fStyle; } 319 320 /** Set the paint's style, used for controlling how primitives' 321 geometries are interpreted (except for drawBitmap, which always assumes 322 Fill). 323 @param style The new style to set in the paint 324 */ 325 void setStyle(Style style); 326 327 /** Return the paint's color. Note that the color is a 32bit value 328 containing alpha as well as r,g,b. This 32bit value is not 329 premultiplied, meaning that its alpha can be any value, regardless of 330 the values of r,g,b. 331 @return the paint's color (and alpha). 332 */ 333 SkColor getColor() const { return fColor; } 334 335 /** Set the paint's color. Note that the color is a 32bit value containing 336 alpha as well as r,g,b. This 32bit value is not premultiplied, meaning 337 that its alpha can be any value, regardless of the values of r,g,b. 338 @param color The new color (including alpha) to set in the paint. 339 */ 340 void setColor(SkColor color); 341 342 /** Helper to getColor() that just returns the color's alpha value. 343 @return the alpha component of the paint's color. 344 */ 345 uint8_t getAlpha() const { return SkToU8(SkColorGetA(fColor)); } 346 347 /** Helper to setColor(), that only assigns the color's alpha value, 348 leaving its r,g,b values unchanged. 349 @param a set the alpha component (0..255) of the paint's color. 350 */ 351 void setAlpha(U8CPU a); 352 353 /** Helper to setColor(), that takes a,r,g,b and constructs the color value 354 using SkColorSetARGB() 355 @param a The new alpha component (0..255) of the paint's color. 356 @param r The new red component (0..255) of the paint's color. 357 @param g The new green component (0..255) of the paint's color. 358 @param b The new blue component (0..255) of the paint's color. 359 */ 360 void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b); 361 362 /** Return the width for stroking. 363 <p /> 364 A value of 0 strokes in hairline mode. 365 Hairlines always draw 1-pixel wide, regardless of the matrix. 366 @return the paint's stroke width, used whenever the paint's style is 367 Stroke or StrokeAndFill. 368 */ 369 SkScalar getStrokeWidth() const { return fWidth; } 370 371 /** Set the width for stroking. 372 Pass 0 to stroke in hairline mode. 373 Hairlines always draw 1-pixel wide, regardless of the matrix. 374 @param width set the paint's stroke width, used whenever the paint's 375 style is Stroke or StrokeAndFill. 376 */ 377 void setStrokeWidth(SkScalar width); 378 379 /** Return the paint's stroke miter value. This is used to control the 380 behavior of miter joins when the joins angle is sharp. 381 @return the paint's miter limit, used whenever the paint's style is 382 Stroke or StrokeAndFill. 383 */ 384 SkScalar getStrokeMiter() const { return fMiterLimit; } 385 386 /** Set the paint's stroke miter value. This is used to control the 387 behavior of miter joins when the joins angle is sharp. This value must 388 be >= 0. 389 @param miter set the miter limit on the paint, used whenever the 390 paint's style is Stroke or StrokeAndFill. 391 */ 392 void setStrokeMiter(SkScalar miter); 393 394 /** Cap enum specifies the settings for the paint's strokecap. This is the 395 treatment that is applied to the beginning and end of each non-closed 396 contour (e.g. lines). 397 398 If the cap is round or square, the caps are drawn when the contour has 399 a zero length. Zero length contours can be created by following moveTo 400 with a lineTo at the same point, or a moveTo followed by a close. 401 402 A dash with an on interval of zero also creates a zero length contour. 403 404 The zero length contour draws the square cap without rotation, since 405 the no direction can be inferred. 406 */ 407 enum Cap { 408 kButt_Cap, //!< begin/end contours with no extension 409 kRound_Cap, //!< begin/end contours with a semi-circle extension 410 kSquare_Cap, //!< begin/end contours with a half square extension 411 412 kLast_Cap = kSquare_Cap, 413 kDefault_Cap = kButt_Cap 414 }; 415 static constexpr int kCapCount = kLast_Cap + 1; 416 417 /** Join enum specifies the settings for the paint's strokejoin. This is 418 the treatment that is applied to corners in paths and rectangles. 419 */ 420 enum Join { 421 kMiter_Join, //!< connect path segments with a sharp join 422 kRound_Join, //!< connect path segments with a round join 423 kBevel_Join, //!< connect path segments with a flat bevel join 424 425 kLast_Join = kBevel_Join, 426 kDefault_Join = kMiter_Join 427 }; 428 static constexpr int kJoinCount = kLast_Join + 1; 429 430 /** Return the paint's stroke cap type, controlling how the start and end 431 of stroked lines and paths are treated. 432 @return the line cap style for the paint, used whenever the paint's 433 style is Stroke or StrokeAndFill. 434 */ 435 Cap getStrokeCap() const { return (Cap)fBitfields.fCapType; } 436 437 /** Set the paint's stroke cap type. 438 @param cap set the paint's line cap style, used whenever the paint's 439 style is Stroke or StrokeAndFill. 440 */ 441 void setStrokeCap(Cap cap); 442 443 /** Return the paint's stroke join type. 444 @return the paint's line join style, used whenever the paint's style is 445 Stroke or StrokeAndFill. 446 */ 447 Join getStrokeJoin() const { return (Join)fBitfields.fJoinType; } 448 449 /** Set the paint's stroke join type. 450 @param join set the paint's line join style, used whenever the paint's 451 style is Stroke or StrokeAndFill. 452 */ 453 void setStrokeJoin(Join join); 454 455 /** 456 * Applies any/all effects (patheffect, stroking) to src, returning the 457 * result in dst. The result is that drawing src with this paint will be 458 * the same as drawing dst with a default paint (at least from the 459 * geometric perspective). 460 * 461 * @param src input path 462 * @param dst output path (may be the same as src) 463 * @param cullRect If not null, the dst path may be culled to this rect. 464 * @param resScale If > 1, increase precision, else if (0 < res < 1) reduce precision 465 * in favor of speed/size. 466 * @return true if the path should be filled, or false if it should be 467 * drawn with a hairline (width == 0) 468 */ 469 bool getFillPath(const SkPath& src, SkPath* dst, const SkRect* cullRect, 470 SkScalar resScale = 1) const; 471 472 bool getFillPath(const SkPath& src, SkPath* dst) const { 473 return this->getFillPath(src, dst, NULL, 1); 474 } 475 476 /** Get the paint's shader object. 477 <p /> 478 The shader's reference count is not affected. 479 @return the paint's shader (or NULL) 480 */ 481 SkShader* getShader() const { return fShader.get(); } 482 sk_sp<SkShader> refShader() const; 483 484 /** Set or clear the shader object. 485 * Shaders specify the source color(s) for what is being drawn. If a paint 486 * has no shader, then the paint's color is used. If the paint has a 487 * shader, then the shader's color(s) are use instead, but they are 488 * modulated by the paint's alpha. This makes it easy to create a shader 489 * once (e.g. bitmap tiling or gradient) and then change its transparency 490 * w/o having to modify the original shader... only the paint's alpha needs 491 * to be modified. 492 * 493 * There is an exception to this only-respect-paint's-alpha rule: If the shader only generates 494 * alpha (e.g. SkShader::CreateBitmapShader(bitmap, ...) where bitmap's colortype is kAlpha_8) 495 * then the shader will use the paint's entire color to "colorize" its output (modulating the 496 * bitmap's alpha with the paint's color+alpha). 497 * 498 * Pass NULL to clear any previous shader. 499 * As a convenience, the parameter passed is also returned. 500 * If a previous shader exists, its reference count is decremented. 501 * If shader is not NULL, its reference count is incremented. 502 * @param shader May be NULL. The shader to be installed in the paint 503 */ 504 void setShader(sk_sp<SkShader>); 505 506 /** Get the paint's colorfilter. If there is a colorfilter, its reference 507 count is not changed. 508 @return the paint's colorfilter (or NULL) 509 */ 510 SkColorFilter* getColorFilter() const { return fColorFilter.get(); } 511 sk_sp<SkColorFilter> refColorFilter() const; 512 513 /** Set or clear the paint's colorfilter. 514 <p /> 515 If the paint already has a filter, its reference count is decremented. 516 If filter is not NULL, its reference count is incremented. 517 @param filter May be NULL. The filter to be installed in the paint 518 */ 519 void setColorFilter(sk_sp<SkColorFilter>); 520 521 SkBlendMode getBlendMode() const { return (SkBlendMode)fBlendMode; } 522 bool isSrcOver() const { return (SkBlendMode)fBlendMode == SkBlendMode::kSrcOver; } 523 void setBlendMode(SkBlendMode mode) { fBlendMode = (unsigned)mode; } 524 525 /** Get the paint's patheffect object. 526 <p /> 527 The patheffect reference count is not affected. 528 @return the paint's patheffect (or NULL) 529 */ 530 SkPathEffect* getPathEffect() const { return fPathEffect.get(); } 531 sk_sp<SkPathEffect> refPathEffect() const; 532 533 /** Set or clear the patheffect object. 534 <p /> 535 Pass NULL to clear any previous patheffect. 536 As a convenience, the parameter passed is also returned. 537 If a previous patheffect exists, its reference count is decremented. 538 If patheffect is not NULL, its reference count is incremented. 539 @param effect May be NULL. The new patheffect to be installed in the 540 paint 541 @return effect 542 */ 543 void setPathEffect(sk_sp<SkPathEffect>); 544 545 /** Get the paint's maskfilter object. 546 <p /> 547 The maskfilter reference count is not affected. 548 @return the paint's maskfilter (or NULL) 549 */ 550 SkMaskFilter* getMaskFilter() const { return fMaskFilter.get(); } 551 sk_sp<SkMaskFilter> refMaskFilter() const; 552 553 /** Set or clear the maskfilter object. 554 <p /> 555 Pass NULL to clear any previous maskfilter. 556 As a convenience, the parameter passed is also returned. 557 If a previous maskfilter exists, its reference count is decremented. 558 If maskfilter is not NULL, its reference count is incremented. 559 @param maskfilter May be NULL. The new maskfilter to be installed in 560 the paint 561 @return maskfilter 562 */ 563 void setMaskFilter(sk_sp<SkMaskFilter>); 564 565 // These attributes are for text/fonts 566 567 /** Get the paint's typeface object. 568 <p /> 569 The typeface object identifies which font to use when drawing or 570 measuring text. The typeface reference count is not affected. 571 @return the paint's typeface (or NULL) 572 */ 573 SkTypeface* getTypeface() const { return fTypeface.get(); } 574 sk_sp<SkTypeface> refTypeface() const; 575 576 /** Set or clear the typeface object. 577 <p /> 578 Pass NULL to clear any previous typeface. 579 As a convenience, the parameter passed is also returned. 580 If a previous typeface exists, its reference count is decremented. 581 If typeface is not NULL, its reference count is incremented. 582 @param typeface May be NULL. The new typeface to be installed in the 583 paint 584 @return typeface 585 */ 586 void setTypeface(sk_sp<SkTypeface>); 587 588 /** Get the paint's rasterizer (or NULL). 589 <p /> 590 The raster controls how paths/text are turned into alpha masks. 591 @return the paint's rasterizer (or NULL) 592 */ 593 SkRasterizer* getRasterizer() const { return fRasterizer.get(); } 594 sk_sp<SkRasterizer> refRasterizer() const; 595 596 /** Set or clear the rasterizer object. 597 <p /> 598 Pass NULL to clear any previous rasterizer. 599 As a convenience, the parameter passed is also returned. 600 If a previous rasterizer exists in the paint, its reference count is 601 decremented. If rasterizer is not NULL, its reference count is 602 incremented. 603 @param rasterizer May be NULL. The new rasterizer to be installed in 604 the paint. 605 @return rasterizer 606 */ 607 void setRasterizer(sk_sp<SkRasterizer>); 608 609 SkImageFilter* getImageFilter() const { return fImageFilter.get(); } 610 sk_sp<SkImageFilter> refImageFilter() const; 611 void setImageFilter(sk_sp<SkImageFilter>); 612 613 /** 614 * Return the paint's SkDrawLooper (if any). Does not affect the looper's 615 * reference count. 616 */ 617 SkDrawLooper* getDrawLooper() const { return fDrawLooper.get(); } 618 sk_sp<SkDrawLooper> refDrawLooper() const; 619 620 SkDrawLooper* getLooper() const { return fDrawLooper.get(); } 621 /** 622 * Set or clear the looper object. 623 * <p /> 624 * Pass NULL to clear any previous looper. 625 * If a previous looper exists in the paint, its reference count is 626 * decremented. If looper is not NULL, its reference count is 627 * incremented. 628 * @param looper May be NULL. The new looper to be installed in the paint. 629 */ 630 void setDrawLooper(sk_sp<SkDrawLooper>); 631 632 void setLooper(sk_sp<SkDrawLooper>); 633 634 enum Align { 635 kLeft_Align, 636 kCenter_Align, 637 kRight_Align, 638 }; 639 enum { 640 kAlignCount = 3 641 }; 642 643 /** Return the paint's Align value for drawing text. 644 @return the paint's Align value for drawing text. 645 */ 646 Align getTextAlign() const { return (Align)fBitfields.fTextAlign; } 647 648 /** Set the paint's text alignment. 649 @param align set the paint's Align value for drawing text. 650 */ 651 void setTextAlign(Align align); 652 653 /** Return the paint's text size. 654 @return the paint's text size. 655 */ 656 SkScalar getTextSize() const { return fTextSize; } 657 658 /** Set the paint's text size. This value must be > 0 659 @param textSize set the paint's text size. 660 */ 661 void setTextSize(SkScalar textSize); 662 663 /** Return the paint's horizontal scale factor for text. The default value 664 is 1.0. 665 @return the paint's scale factor in X for drawing/measuring text 666 */ 667 SkScalar getTextScaleX() const { return fTextScaleX; } 668 669 /** Set the paint's horizontal scale factor for text. The default value 670 is 1.0. Values > 1.0 will stretch the text wider. Values < 1.0 will 671 stretch the text narrower. 672 @param scaleX set the paint's scale factor in X for drawing/measuring 673 text. 674 */ 675 void setTextScaleX(SkScalar scaleX); 676 677 /** Return the paint's horizontal skew factor for text. The default value 678 is 0. 679 @return the paint's skew factor in X for drawing text. 680 */ 681 SkScalar getTextSkewX() const { return fTextSkewX; } 682 683 /** Set the paint's horizontal skew factor for text. The default value 684 is 0. For approximating oblique text, use values around -0.25. 685 @param skewX set the paint's skew factor in X for drawing text. 686 */ 687 void setTextSkewX(SkScalar skewX); 688 689 /** Describes how to interpret the text parameters that are passed to paint 690 methods like measureText() and getTextWidths(). 691 */ 692 enum TextEncoding { 693 kUTF8_TextEncoding, //!< the text parameters are UTF8 694 kUTF16_TextEncoding, //!< the text parameters are UTF16 695 kUTF32_TextEncoding, //!< the text parameters are UTF32 696 kGlyphID_TextEncoding //!< the text parameters are glyph indices 697 }; 698 699 TextEncoding getTextEncoding() const { 700 return (TextEncoding)fBitfields.fTextEncoding; 701 } 702 703 void setTextEncoding(TextEncoding encoding); 704 705 struct FontMetrics { 706 /** Flags which indicate the confidence level of various metrics. 707 A set flag indicates that the metric may be trusted. 708 */ 709 enum FontMetricsFlags { 710 kUnderlineThicknessIsValid_Flag = 1 << 0, 711 kUnderlinePositionIsValid_Flag = 1 << 1, 712 }; 713 714 uint32_t fFlags; //!< Bit field to identify which values are unknown 715 SkScalar fTop; //!< The greatest distance above the baseline for any glyph (will be <= 0) 716 SkScalar fAscent; //!< The recommended distance above the baseline (will be <= 0) 717 SkScalar fDescent; //!< The recommended distance below the baseline (will be >= 0) 718 SkScalar fBottom; //!< The greatest distance below the baseline for any glyph (will be >= 0) 719 SkScalar fLeading; //!< The recommended distance to add between lines of text (will be >= 0) 720 SkScalar fAvgCharWidth; //!< the average character width (>= 0) 721 SkScalar fMaxCharWidth; //!< the max character width (>= 0) 722 SkScalar fXMin; //!< The minimum bounding box x value for all glyphs 723 SkScalar fXMax; //!< The maximum bounding box x value for all glyphs 724 SkScalar fXHeight; //!< The height of an 'x' in px, or 0 if no 'x' in face 725 SkScalar fCapHeight; //!< The cap height (> 0), or 0 if cannot be determined. 726 SkScalar fUnderlineThickness; //!< underline thickness, or 0 if cannot be determined 727 728 /** Underline Position - position of the top of the Underline stroke 729 relative to the baseline, this can have following values 730 - Negative - means underline should be drawn above baseline. 731 - Positive - means below baseline. 732 - Zero - mean underline should be drawn on baseline. 733 */ 734 SkScalar fUnderlinePosition; //!< underline position, or 0 if cannot be determined 735 736 /** If the fontmetrics has a valid underline thickness, return true, and set the 737 thickness param to that value. If it doesn't return false and ignore the 738 thickness param. 739 */ 740 bool hasUnderlineThickness(SkScalar* thickness) const { 741 if (SkToBool(fFlags & kUnderlineThicknessIsValid_Flag)) { 742 *thickness = fUnderlineThickness; 743 return true; 744 } 745 return false; 746 } 747 748 /** If the fontmetrics has a valid underline position, return true, and set the 749 position param to that value. If it doesn't return false and ignore the 750 position param. 751 */ 752 bool hasUnderlinePosition(SkScalar* position) const { 753 if (SkToBool(fFlags & kUnderlinePositionIsValid_Flag)) { 754 *position = fUnderlinePosition; 755 return true; 756 } 757 return false; 758 } 759 760 }; 761 762 /** Return the recommend spacing between lines (which will be 763 fDescent - fAscent + fLeading). 764 If metrics is not null, return in it the font metrics for the 765 typeface/pointsize/etc. currently set in the paint. 766 @param metrics If not null, returns the font metrics for the 767 current typeface/pointsize/etc setting in this 768 paint. 769 @param scale If not 0, return width as if the canvas were scaled 770 by this value 771 @param return the recommended spacing between lines 772 */ 773 SkScalar getFontMetrics(FontMetrics* metrics, SkScalar scale = 0) const; 774 775 /** Return the recommend line spacing. This will be 776 fDescent - fAscent + fLeading 777 */ 778 SkScalar getFontSpacing() const { return this->getFontMetrics(NULL, 0); } 779 780 /** Convert the specified text into glyph IDs, returning the number of 781 glyphs ID written. If glyphs is NULL, it is ignore and only the count 782 is returned. 783 */ 784 int textToGlyphs(const void* text, size_t byteLength, 785 SkGlyphID glyphs[]) const; 786 787 /** Return true if all of the specified text has a corresponding non-zero 788 glyph ID. If any of the code-points in the text are not supported in 789 the typeface (i.e. the glyph ID would be zero), then return false. 790 791 If the text encoding for the paint is kGlyph_TextEncoding, then this 792 returns true if all of the specified glyph IDs are non-zero. 793 */ 794 bool containsText(const void* text, size_t byteLength) const; 795 796 /** Convert the glyph array into Unichars. Unconvertable glyphs are mapped 797 to zero. Note: this does not look at the text-encoding setting in the 798 paint, only at the typeface. 799 */ 800 void glyphsToUnichars(const SkGlyphID glyphs[], int count, SkUnichar text[]) const; 801 802 /** Return the number of drawable units in the specified text buffer. 803 This looks at the current TextEncoding field of the paint. If you also 804 want to have the text converted into glyph IDs, call textToGlyphs 805 instead. 806 */ 807 int countText(const void* text, size_t byteLength) const { 808 return this->textToGlyphs(text, byteLength, NULL); 809 } 810 811 /** Return the width of the text. This will return the vertical measure 812 * if isVerticalText() is true, in which case the returned value should 813 * be treated has a height instead of a width. 814 * 815 * @param text The text to be measured 816 * @param length Number of bytes of text to measure 817 * @param bounds If not NULL, returns the bounds of the text, 818 * relative to (0, 0). 819 * @return The advance width of the text 820 */ 821 SkScalar measureText(const void* text, size_t length, SkRect* bounds) const; 822 823 /** Return the width of the text. This will return the vertical measure 824 * if isVerticalText() is true, in which case the returned value should 825 * be treated has a height instead of a width. 826 * 827 * @param text Address of the text 828 * @param length Number of bytes of text to measure 829 * @return The advance width of the text 830 */ 831 SkScalar measureText(const void* text, size_t length) const { 832 return this->measureText(text, length, NULL); 833 } 834 835 /** Return the number of bytes of text that were measured. If 836 * isVerticalText() is true, then the vertical advances are used for 837 * the measurement. 838 * 839 * @param text The text to be measured 840 * @param length Number of bytes of text to measure 841 * @param maxWidth Maximum width. Only the subset of text whose accumulated 842 * widths are <= maxWidth are measured. 843 * @param measuredWidth Optional. If non-null, this returns the actual 844 * width of the measured text. 845 * @return The number of bytes of text that were measured. Will be 846 * <= length. 847 */ 848 size_t breakText(const void* text, size_t length, SkScalar maxWidth, 849 SkScalar* measuredWidth = NULL) const; 850 851 /** Return the advances for the text. These will be vertical advances if 852 * isVerticalText() returns true. 853 * 854 * @param text the text 855 * @param byteLength number of bytes to of text 856 * @param widths If not null, returns the array of advances for 857 * the glyphs. If not NULL, must be at least a large 858 * as the number of unichars in the specified text. 859 * @param bounds If not null, returns the bounds for each of 860 * character, relative to (0, 0) 861 * @return the number of unichars in the specified text. 862 */ 863 int getTextWidths(const void* text, size_t byteLength, SkScalar widths[], 864 SkRect bounds[] = NULL) const; 865 866 /** Return the path (outline) for the specified text. 867 * Note: just like SkCanvas::drawText, this will respect the Align setting 868 * in the paint. 869 * 870 * @param text the text 871 * @param length number of bytes of text 872 * @param x The x-coordinate of the origin of the text. 873 * @param y The y-coordinate of the origin of the text. 874 * @param path The outline of the text. 875 */ 876 void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y, 877 SkPath* path) const; 878 879 /** Return the path (outline) for the specified text. 880 * Note: just like SkCanvas::drawText, this will respect the Align setting 881 * in the paint. 882 * 883 * @param text the text 884 * @param length number of bytes of text 885 * @param pos array of positions, used to position each character 886 * @param path The outline of the text. 887 */ 888 void getPosTextPath(const void* text, size_t length, 889 const SkPoint pos[], SkPath* path) const; 890 891 /** Return the number of intervals that intersect the intercept along the axis of the advance. 892 * The return count is zero or a multiple of two, and is at most the number of glyphs * 2 in 893 * the string. The caller may pass nullptr for intervals to determine the size of the interval 894 * array, or may conservatively pre-allocate an array with length * 2 entries. The computed 895 * intervals are cached by glyph to improve performance for multiple calls. 896 * This permits constructing an underline that skips the descenders. 897 * 898 * @param text the text 899 * @param length number of bytes of text 900 * @param x The x-coordinate of the origin of the text. 901 * @param y The y-coordinate of the origin of the text. 902 * @param bounds The lower and upper line parallel to the advance. 903 * @param array If not null, the found intersections. 904 * 905 * @return The number of intersections, which may be zero. 906 */ 907 int getTextIntercepts(const void* text, size_t length, SkScalar x, SkScalar y, 908 const SkScalar bounds[2], SkScalar* intervals) const; 909 910 /** Return the number of intervals that intersect the intercept along the axis of the advance. 911 * The return count is zero or a multiple of two, and is at most the number of glyphs * 2 in 912 * string. The caller may pass nullptr for intervals to determine the size of the interval 913 * array, or may conservatively pre-allocate an array with length * 2 entries. The computed 914 * intervals are cached by glyph to improve performance for multiple calls. 915 * This permits constructing an underline that skips the descenders. 916 * 917 * @param text the text 918 * @param length number of bytes of text 919 * @param pos array of positions, used to position each character 920 * @param bounds The lower and upper line parallel to the advance. 921 * @param array If not null, the glyph bounds contained by the advance parallel lines. 922 * 923 * @return The number of intersections, which may be zero. 924 */ 925 int getPosTextIntercepts(const void* text, size_t length, const SkPoint pos[], 926 const SkScalar bounds[2], SkScalar* intervals) const; 927 928 /** Return the number of intervals that intersect the intercept along the axis of the advance. 929 * The return count is zero or a multiple of two, and is at most the number of glyphs * 2 in 930 * string. The caller may pass nullptr for intervals to determine the size of the interval 931 * array, or may conservatively pre-allocate an array with length * 2 entries. The computed 932 * intervals are cached by glyph to improve performance for multiple calls. 933 * This permits constructing an underline that skips the descenders. 934 * 935 * @param text The text. 936 * @param length Number of bytes of text. 937 * @param xpos Array of x-positions, used to position each character. 938 * @param constY The shared Y coordinate for all of the positions. 939 * @param bounds The lower and upper line parallel to the advance. 940 * @param array If not null, the glyph bounds contained by the advance parallel lines. 941 * 942 * @return The number of intersections, which may be zero. 943 */ 944 int getPosTextHIntercepts(const void* text, size_t length, const SkScalar xpos[], 945 SkScalar constY, const SkScalar bounds[2], SkScalar* intervals) const; 946 947 /** Return the number of intervals that intersect the intercept along the axis of the advance. 948 * The return count is zero or a multiple of two, and is at most the number of glyphs * 2 in 949 * text blob. The caller may pass nullptr for intervals to determine the size of the interval 950 * array. The computed intervals are cached by glyph to improve performance for multiple calls. 951 * This permits constructing an underline that skips the descenders. 952 * 953 * @param blob The text blob. 954 * @param bounds The lower and upper line parallel to the advance. 955 * @param array If not null, the glyph bounds contained by the advance parallel lines. 956 * 957 * @return The number of intersections, which may be zero. 958 */ 959 int getTextBlobIntercepts(const SkTextBlob* blob, const SkScalar bounds[2], 960 SkScalar* intervals) const; 961 962 /** 963 * Return a rectangle that represents the union of the bounds of all 964 * of the glyphs, but each one positioned at (0,0). This may be conservatively large, and 965 * will not take into account any hinting, but will respect any text-scale-x or text-skew-x 966 * on this paint. 967 */ 968 SkRect getFontBounds() const; 969 970 // returns true if the paint's settings (e.g. xfermode + alpha) resolve to 971 // mean that we need not draw at all (e.g. SrcOver + 0-alpha) 972 bool nothingToDraw() const; 973 974 /////////////////////////////////////////////////////////////////////////// 975 // would prefer to make these private... 976 977 /** Returns true if the current paint settings allow for fast computation of 978 bounds (i.e. there is nothing complex like a patheffect that would make 979 the bounds computation expensive. 980 */ 981 bool canComputeFastBounds() const; 982 983 /** Only call this if canComputeFastBounds() returned true. This takes a 984 raw rectangle (the raw bounds of a shape), and adjusts it for stylistic 985 effects in the paint (e.g. stroking). If needed, it uses the storage 986 rect parameter. It returns the adjusted bounds that can then be used 987 for quickReject tests. 988 989 The returned rect will either be orig or storage, thus the caller 990 should not rely on storage being set to the result, but should always 991 use the retured value. It is legal for orig and storage to be the same 992 rect. 993 994 e.g. 995 if (paint.canComputeFastBounds()) { 996 SkRect r, storage; 997 path.computeBounds(&r, SkPath::kFast_BoundsType); 998 const SkRect& fastR = paint.computeFastBounds(r, &storage); 999 if (canvas->quickReject(fastR, ...)) { 1000 // don't draw the path 1001 } 1002 } 1003 */ 1004 const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const { 1005 SkPaint::Style style = this->getStyle(); 1006 // ultra fast-case: filling with no effects that affect geometry 1007 if (kFill_Style == style) { 1008 uintptr_t effects = reinterpret_cast<uintptr_t>(this->getLooper()); 1009 effects |= reinterpret_cast<uintptr_t>(this->getMaskFilter()); 1010 effects |= reinterpret_cast<uintptr_t>(this->getPathEffect()); 1011 effects |= reinterpret_cast<uintptr_t>(this->getImageFilter()); 1012 if (!effects) { 1013 return orig; 1014 } 1015 } 1016 1017 return this->doComputeFastBounds(orig, storage, style); 1018 } 1019 1020 const SkRect& computeFastStrokeBounds(const SkRect& orig, 1021 SkRect* storage) const { 1022 return this->doComputeFastBounds(orig, storage, kStroke_Style); 1023 } 1024 1025 // Take the style explicitly, so the caller can force us to be stroked 1026 // without having to make a copy of the paint just to change that field. 1027 const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage, 1028 Style) const; 1029 1030 /** 1031 * Return a matrix that applies the paint's text values: size, scale, skew 1032 */ 1033 static SkMatrix* SetTextMatrix(SkMatrix* matrix, SkScalar size, 1034 SkScalar scaleX, SkScalar skewX) { 1035 matrix->setScale(size * scaleX, size); 1036 if (skewX) { 1037 matrix->postSkew(skewX, 0); 1038 } 1039 return matrix; 1040 } 1041 1042 SkMatrix* setTextMatrix(SkMatrix* matrix) const { 1043 return SetTextMatrix(matrix, fTextSize, fTextScaleX, fTextSkewX); 1044 } 1045 1046 typedef const SkGlyph& (*GlyphCacheProc)(SkGlyphCache*, const char**); 1047 1048 SK_TO_STRING_NONVIRT() 1049 1050 private: 1051 sk_sp<SkTypeface> fTypeface; 1052 sk_sp<SkPathEffect> fPathEffect; 1053 sk_sp<SkShader> fShader; 1054 sk_sp<SkMaskFilter> fMaskFilter; 1055 sk_sp<SkColorFilter> fColorFilter; 1056 sk_sp<SkRasterizer> fRasterizer; 1057 sk_sp<SkDrawLooper> fDrawLooper; 1058 sk_sp<SkImageFilter> fImageFilter; 1059 1060 SkScalar fTextSize; 1061 SkScalar fTextScaleX; 1062 SkScalar fTextSkewX; 1063 SkColor fColor; 1064 SkScalar fWidth; 1065 SkScalar fMiterLimit; 1066 uint32_t fBlendMode; // just need 5-6 bits 1067 union { 1068 struct { 1069 // all of these bitfields should add up to 32 1070 unsigned fFlags : 16; 1071 unsigned fTextAlign : 2; 1072 unsigned fCapType : 2; 1073 unsigned fJoinType : 2; 1074 unsigned fStyle : 2; 1075 unsigned fTextEncoding : 2; // 3 values 1076 unsigned fHinting : 2; 1077 unsigned fFilterQuality : 2; 1078 //unsigned fFreeBits : 2; 1079 } fBitfields; 1080 uint32_t fBitfieldsUInt; 1081 }; 1082 1083 static GlyphCacheProc GetGlyphCacheProc(TextEncoding encoding, 1084 bool isDevKern, 1085 bool needFullMetrics); 1086 1087 SkScalar measure_text(SkGlyphCache*, const char* text, size_t length, 1088 int* count, SkRect* bounds) const; 1089 1090 enum ScalerContextFlags : uint32_t { 1091 kNone_ScalerContextFlags = 0, 1092 1093 kFakeGamma_ScalerContextFlag = 1 << 0, 1094 kBoostContrast_ScalerContextFlag = 1 << 1, 1095 1096 kFakeGammaAndBoostContrast_ScalerContextFlags = 1097 kFakeGamma_ScalerContextFlag | kBoostContrast_ScalerContextFlag, 1098 }; 1099 1100 /* 1101 * Allocs an SkDescriptor on the heap and return it to the caller as a refcnted 1102 * SkData. Caller is responsible for managing the lifetime of this object. 1103 */ 1104 void getScalerContextDescriptor(SkScalerContextEffects*, SkAutoDescriptor*, 1105 const SkSurfaceProps& surfaceProps, 1106 uint32_t scalerContextFlags, const SkMatrix*) const; 1107 1108 SkGlyphCache* detachCache(const SkSurfaceProps* surfaceProps, uint32_t scalerContextFlags, 1109 const SkMatrix*) const; 1110 1111 void descriptorProc(const SkSurfaceProps* surfaceProps, uint32_t scalerContextFlags, 1112 const SkMatrix* deviceMatrix, 1113 void (*proc)(SkTypeface*, const SkScalerContextEffects&, 1114 const SkDescriptor*, void*), 1115 void* context) const; 1116 1117 /* 1118 * The luminance color is used to determine which Gamma Canonical color to map to. This is 1119 * really only used by backends which want to cache glyph masks, and need some way to know if 1120 * they need to generate new masks based off a given color. 1121 */ 1122 SkColor computeLuminanceColor() const; 1123 1124 enum { 1125 /* This is the size we use when we ask for a glyph's path. We then 1126 * post-transform it as we draw to match the request. 1127 * This is done to try to re-use cache entries for the path. 1128 * 1129 * This value is somewhat arbitrary. In theory, it could be 1, since 1130 * we store paths as floats. However, we get the path from the font 1131 * scaler, and it may represent its paths as fixed-point (or 26.6), 1132 * so we shouldn't ask for something too big (might overflow 16.16) 1133 * or too small (underflow 26.6). 1134 * 1135 * This value could track kMaxSizeForGlyphCache, assuming the above 1136 * constraints, but since we ask for unhinted paths, the two values 1137 * need not match per-se. 1138 */ 1139 kCanonicalTextSizeForPaths = 64, 1140 1141 /* 1142 * Above this size (taking into account CTM and textSize), we never use 1143 * the cache for bits or metrics (we might overflow), so we just ask 1144 * for a caononical size and post-transform that. 1145 */ 1146 kMaxSizeForGlyphCache = 256, 1147 }; 1148 1149 static bool TooBigToUseCache(const SkMatrix& ctm, const SkMatrix& textM); 1150 1151 // Set flags/hinting/textSize up to use for drawing text as paths. 1152 // Returns scale factor to restore the original textSize, since will will 1153 // have change it to kCanonicalTextSizeForPaths. 1154 SkScalar setupForAsPaths(); 1155 1156 static SkScalar MaxCacheSize2() { 1157 static const SkScalar kMaxSize = SkIntToScalar(kMaxSizeForGlyphCache); 1158 static const SkScalar kMag2Max = kMaxSize * kMaxSize; 1159 return kMag2Max; 1160 } 1161 1162 friend class SkAutoGlyphCache; 1163 friend class SkAutoGlyphCacheNoGamma; 1164 friend class SkCanvas; 1165 friend class SkDraw; 1166 friend class SkPDFDevice; 1167 friend class GrAtlasTextBlob; 1168 friend class GrAtlasTextContext; 1169 friend class GrStencilAndCoverTextContext; 1170 friend class GrPathRendering; 1171 friend class GrTextUtils; 1172 friend class GrGLPathRendering; 1173 friend class SkScalerContext; 1174 friend class SkTextBaseIter; 1175 friend class SkCanonicalizePaint; 1176 }; 1177 1178 #endif 1179