gfx/skia/trunk/include/core/SkPaint.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

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

mercurial