blob: ee9b65ca7d20607bc0021f6e3ad33285ba2710be [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@android.com8a1c16f2008-12-17 15:59:43 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2006 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00004 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00005 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
reed@android.com8a1c16f2008-12-17 15:59:43 +000010#ifndef SkPaint_DEFINED
11#define SkPaint_DEFINED
12
13#include "SkColor.h"
reed@android.coma0f5d152009-06-22 17:38:10 +000014#include "SkXfermode.h"
15
reed@android.com8a1c16f2008-12-17 15:59:43 +000016class SkAutoGlyphCache;
17class SkColorFilter;
18class SkDescriptor;
19class SkFlattenableReadBuffer;
20class SkFlattenableWriteBuffer;
21struct SkGlyph;
22struct SkRect;
23class SkGlyphCache;
reed@google.com15356a62011-11-03 19:29:08 +000024class SkImageFilter;
reed@android.com8a1c16f2008-12-17 15:59:43 +000025class SkMaskFilter;
26class SkMatrix;
27class SkPath;
28class SkPathEffect;
29class SkRasterizer;
30class SkShader;
31class SkDrawLooper;
32class SkTypeface;
reed@android.com8a1c16f2008-12-17 15:59:43 +000033
34typedef const SkGlyph& (*SkDrawCacheProc)(SkGlyphCache*, const char**,
35 SkFixed x, SkFixed y);
36
37typedef const SkGlyph& (*SkMeasureCacheProc)(SkGlyphCache*, const char**);
38
39/** \class SkPaint
40
41 The SkPaint class holds the style and color information about how to draw
42 geometries, text and bitmaps.
43*/
ctguil@chromium.org7ffb1b22011-03-15 21:27:08 +000044class SK_API SkPaint {
reed@android.com8a1c16f2008-12-17 15:59:43 +000045public:
46 SkPaint();
47 SkPaint(const SkPaint& paint);
48 ~SkPaint();
49
50 SkPaint& operator=(const SkPaint&);
51
reed@google.comb530ef52011-07-20 19:55:42 +000052 SK_API friend bool operator==(const SkPaint& a, const SkPaint& b);
53 friend bool operator!=(const SkPaint& a, const SkPaint& b) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000054 return !(a == b);
55 }
reed@google.com9d07fec2011-03-16 20:02:59 +000056
reed@android.com8a1c16f2008-12-17 15:59:43 +000057 void flatten(SkFlattenableWriteBuffer&) const;
58 void unflatten(SkFlattenableReadBuffer&);
59
60 /** Restores the paint to its initial settings.
61 */
62 void reset();
63
agl@chromium.org309485b2009-07-21 17:41:32 +000064 /** Specifies the level of hinting to be performed. These names are taken
65 from the Gnome/Cairo names for the same. They are translated into
66 Freetype concepts the same as in cairo-ft-font.c:
67 kNo_Hinting -> FT_LOAD_NO_HINTING
68 kSlight_Hinting -> FT_LOAD_TARGET_LIGHT
69 kNormal_Hinting -> <default, no option>
70 kFull_Hinting -> <same as kNormalHinting, unless we are rendering
71 subpixel glyphs, in which case TARGET_LCD or
72 TARGET_LCD_V is used>
73 */
74 enum Hinting {
75 kNo_Hinting = 0,
76 kSlight_Hinting = 1,
77 kNormal_Hinting = 2, //!< this is the default
78 kFull_Hinting = 3,
79 };
80
reed@google.com9d07fec2011-03-16 20:02:59 +000081 Hinting getHinting() const {
agl@chromium.org309485b2009-07-21 17:41:32 +000082 return static_cast<Hinting>(fHinting);
83 }
84
djsollen@google.comf5dbe2f2011-04-15 13:41:26 +000085 void setHinting(Hinting hintingLevel);
agl@chromium.org309485b2009-07-21 17:41:32 +000086
reed@android.com8a1c16f2008-12-17 15:59:43 +000087 /** Specifies the bit values that are stored in the paint's flags.
88 */
89 enum Flags {
90 kAntiAlias_Flag = 0x01, //!< mask to enable antialiasing
91 kFilterBitmap_Flag = 0x02, //!< mask to enable bitmap filtering
92 kDither_Flag = 0x04, //!< mask to enable dithering
93 kUnderlineText_Flag = 0x08, //!< mask to enable underline text
94 kStrikeThruText_Flag = 0x10, //!< mask to enable strike-thru text
95 kFakeBoldText_Flag = 0x20, //!< mask to enable fake-bold text
96 kLinearText_Flag = 0x40, //!< mask to enable linear-text
agl@chromium.org309485b2009-07-21 17:41:32 +000097 kSubpixelText_Flag = 0x80, //!< mask to enable subpixel text positioning
reed@android.com8a1c16f2008-12-17 15:59:43 +000098 kDevKernText_Flag = 0x100, //!< mask to enable device kerning text
agl@chromium.org309485b2009-07-21 17:41:32 +000099 kLCDRenderText_Flag = 0x200, //!< mask to enable subpixel glyph renderering
agl@chromium.orge95c91e2010-01-04 18:27:55 +0000100 kEmbeddedBitmapText_Flag = 0x400, //!< mask to enable embedded bitmap strikes
agl@chromium.orga2c71cb2010-06-17 20:49:17 +0000101 kAutoHinting_Flag = 0x800, //!< mask to force Freetype's autohinter
reed@google.com32538982011-09-30 20:57:05 +0000102
103 // experimental/private
104 kForceAAText_Flag = 0x1000,
105
agl@chromium.org309485b2009-07-21 17:41:32 +0000106 // when adding extra flags, note that the fFlags member is specified
107 // with a bit-width and you'll have to expand it.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000108
reed@google.com32538982011-09-30 20:57:05 +0000109 kAllFlags = 0x1FFF
reed@android.com8a1c16f2008-12-17 15:59:43 +0000110 };
111
112 /** Return the paint's flags. Use the Flag enum to test flag values.
113 @return the paint's flags (see enums ending in _Flag for bit masks)
114 */
115 uint32_t getFlags() const { return fFlags; }
116
117 /** Set the paint's flags. Use the Flag enum to specific flag values.
118 @param flags The new flag bits for the paint (see Flags enum)
119 */
120 void setFlags(uint32_t flags);
121
122 /** Helper for getFlags(), returning true if kAntiAlias_Flag bit is set
123 @return true if the antialias bit is set in the paint's flags.
124 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000125 bool isAntiAlias() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000126 return SkToBool(this->getFlags() & kAntiAlias_Flag);
127 }
reed@google.com9d07fec2011-03-16 20:02:59 +0000128
reed@android.com8a1c16f2008-12-17 15:59:43 +0000129 /** Helper for setFlags(), setting or clearing the kAntiAlias_Flag bit
130 @param aa true to enable antialiasing, false to disable it
131 */
132 void setAntiAlias(bool aa);
reed@google.com9d07fec2011-03-16 20:02:59 +0000133
reed@android.com8a1c16f2008-12-17 15:59:43 +0000134 /** Helper for getFlags(), returning true if kDither_Flag bit is set
135 @return true if the dithering bit is set in the paint's flags.
136 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000137 bool isDither() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000138 return SkToBool(this->getFlags() & kDither_Flag);
139 }
reed@google.com9d07fec2011-03-16 20:02:59 +0000140
reed@android.com8a1c16f2008-12-17 15:59:43 +0000141 /** Helper for setFlags(), setting or clearing the kDither_Flag bit
142 @param dither true to enable dithering, false to disable it
143 */
144 void setDither(bool dither);
reed@google.com9d07fec2011-03-16 20:02:59 +0000145
reed@android.com8a1c16f2008-12-17 15:59:43 +0000146 /** Helper for getFlags(), returning true if kLinearText_Flag bit is set
147 @return true if the lineartext bit is set in the paint's flags
148 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000149 bool isLinearText() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000150 return SkToBool(this->getFlags() & kLinearText_Flag);
151 }
152
153 /** Helper for setFlags(), setting or clearing the kLinearText_Flag bit
154 @param linearText true to set the linearText bit in the paint's flags,
155 false to clear it.
156 */
157 void setLinearText(bool linearText);
158
159 /** Helper for getFlags(), returning true if kSubpixelText_Flag bit is set
160 @return true if the lineartext bit is set in the paint's flags
161 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000162 bool isSubpixelText() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000163 return SkToBool(this->getFlags() & kSubpixelText_Flag);
164 }
reed@google.com9d07fec2011-03-16 20:02:59 +0000165
reed@google.com84b437e2011-08-01 12:45:35 +0000166 /**
167 * Helper for setFlags(), setting or clearing the kSubpixelText_Flag.
168 * @param subpixelText true to set the subpixelText bit in the paint's
169 * flags, false to clear it.
170 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000171 void setSubpixelText(bool subpixelText);
agl@chromium.org309485b2009-07-21 17:41:32 +0000172
reed@google.com9d07fec2011-03-16 20:02:59 +0000173 bool isLCDRenderText() const {
agl@chromium.org309485b2009-07-21 17:41:32 +0000174 return SkToBool(this->getFlags() & kLCDRenderText_Flag);
175 }
176
reed@google.com84b437e2011-08-01 12:45:35 +0000177 /**
178 * Helper for setFlags(), setting or clearing the kLCDRenderText_Flag.
179 * Note: antialiasing must also be on for lcd rendering
180 * @param lcdText true to set the LCDRenderText bit in the paint's flags,
181 * false to clear it.
182 */
183 void setLCDRenderText(bool lcdText);
agl@chromium.org309485b2009-07-21 17:41:32 +0000184
reed@google.com9d07fec2011-03-16 20:02:59 +0000185 bool isEmbeddedBitmapText() const {
agl@chromium.orge95c91e2010-01-04 18:27:55 +0000186 return SkToBool(this->getFlags() & kEmbeddedBitmapText_Flag);
187 }
188
189 /** Helper for setFlags(), setting or clearing the kEmbeddedBitmapText_Flag bit
190 @param useEmbeddedBitmapText true to set the kEmbeddedBitmapText bit in the paint's flags,
191 false to clear it.
192 */
193 void setEmbeddedBitmapText(bool useEmbeddedBitmapText);
194
reed@google.com9d07fec2011-03-16 20:02:59 +0000195 bool isAutohinted() const {
agl@chromium.orga2c71cb2010-06-17 20:49:17 +0000196 return SkToBool(this->getFlags() & kAutoHinting_Flag);
197 }
198
199 /** Helper for setFlags(), setting or clearing the kAutoHinting_Flag bit
200 @param useAutohinter true to set the kEmbeddedBitmapText bit in the
201 paint's flags,
202 false to clear it.
203 */
204 void setAutohinted(bool useAutohinter);
205
reed@android.com8a1c16f2008-12-17 15:59:43 +0000206 /** Helper for getFlags(), returning true if kUnderlineText_Flag bit is set
207 @return true if the underlineText bit is set in the paint's flags.
208 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000209 bool isUnderlineText() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000210 return SkToBool(this->getFlags() & kUnderlineText_Flag);
211 }
212
213 /** Helper for setFlags(), setting or clearing the kUnderlineText_Flag bit
214 @param underlineText true to set the underlineText bit in the paint's
215 flags, false to clear it.
216 */
217 void setUnderlineText(bool underlineText);
218
219 /** Helper for getFlags(), returns true if kStrikeThruText_Flag bit is set
220 @return true if the strikeThruText bit is set in the paint's flags.
221 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000222 bool isStrikeThruText() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000223 return SkToBool(this->getFlags() & kStrikeThruText_Flag);
224 }
225
226 /** Helper for setFlags(), setting or clearing the kStrikeThruText_Flag bit
227 @param strikeThruText true to set the strikeThruText bit in the
228 paint's flags, false to clear it.
229 */
230 void setStrikeThruText(bool strikeThruText);
231
232 /** Helper for getFlags(), returns true if kFakeBoldText_Flag bit is set
233 @return true if the kFakeBoldText_Flag bit is set in the paint's flags.
234 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000235 bool isFakeBoldText() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000236 return SkToBool(this->getFlags() & kFakeBoldText_Flag);
237 }
238
239 /** Helper for setFlags(), setting or clearing the kFakeBoldText_Flag bit
240 @param fakeBoldText true to set the kFakeBoldText_Flag bit in the paint's
241 flags, false to clear it.
242 */
243 void setFakeBoldText(bool fakeBoldText);
244
245 /** Helper for getFlags(), returns true if kDevKernText_Flag bit is set
246 @return true if the kernText bit is set in the paint's flags.
247 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000248 bool isDevKernText() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000249 return SkToBool(this->getFlags() & kDevKernText_Flag);
250 }
251
252 /** Helper for setFlags(), setting or clearing the kKernText_Flag bit
253 @param kernText true to set the kKernText_Flag bit in the paint's
254 flags, false to clear it.
255 */
256 void setDevKernText(bool devKernText);
257
reed@google.com9d07fec2011-03-16 20:02:59 +0000258 bool isFilterBitmap() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000259 return SkToBool(this->getFlags() & kFilterBitmap_Flag);
260 }
reed@google.com9d07fec2011-03-16 20:02:59 +0000261
reed@android.com8a1c16f2008-12-17 15:59:43 +0000262 void setFilterBitmap(bool filterBitmap);
263
264 /** Styles apply to rect, oval, path, and text.
265 Bitmaps are always drawn in "fill", and lines are always drawn in
266 "stroke".
reed@google.com9d07fec2011-03-16 20:02:59 +0000267
reed@android.comed881c22009-09-15 14:10:42 +0000268 Note: strokeandfill implicitly draws the result with
269 SkPath::kWinding_FillType, so if the original path is even-odd, the
270 results may not appear the same as if it was drawn twice, filled and
271 then stroked.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000272 */
273 enum Style {
reed@android.comed881c22009-09-15 14:10:42 +0000274 kFill_Style, //!< fill the geometry
275 kStroke_Style, //!< stroke the geometry
276 kStrokeAndFill_Style, //!< fill and stroke the geometry
reed@android.com8a1c16f2008-12-17 15:59:43 +0000277
278 kStyleCount,
279 };
280
281 /** Return the paint's style, used for controlling how primitives'
282 geometries are interpreted (except for drawBitmap, which always assumes
283 kFill_Style).
284 @return the paint's Style
285 */
286 Style getStyle() const { return (Style)fStyle; }
287
288 /** Set the paint's style, used for controlling how primitives'
289 geometries are interpreted (except for drawBitmap, which always assumes
290 Fill).
291 @param style The new style to set in the paint
292 */
293 void setStyle(Style style);
294
295 /** Return the paint's color. Note that the color is a 32bit value
296 containing alpha as well as r,g,b. This 32bit value is not
297 premultiplied, meaning that its alpha can be any value, regardless of
298 the values of r,g,b.
299 @return the paint's color (and alpha).
300 */
301 SkColor getColor() const { return fColor; }
302
303 /** Set the paint's color. Note that the color is a 32bit value containing
304 alpha as well as r,g,b. This 32bit value is not premultiplied, meaning
305 that its alpha can be any value, regardless of the values of r,g,b.
306 @param color The new color (including alpha) to set in the paint.
307 */
308 void setColor(SkColor color);
309
310 /** Helper to getColor() that just returns the color's alpha value.
311 @return the alpha component of the paint's color.
312 */
313 uint8_t getAlpha() const { return SkToU8(SkColorGetA(fColor)); }
reed@google.com9d07fec2011-03-16 20:02:59 +0000314
reed@android.com8a1c16f2008-12-17 15:59:43 +0000315 /** Helper to setColor(), that only assigns the color's alpha value,
316 leaving its r,g,b values unchanged.
317 @param a set the alpha component (0..255) of the paint's color.
318 */
319 void setAlpha(U8CPU a);
320
321 /** Helper to setColor(), that takes a,r,g,b and constructs the color value
322 using SkColorSetARGB()
323 @param a The new alpha component (0..255) of the paint's color.
324 @param r The new red component (0..255) of the paint's color.
325 @param g The new green component (0..255) of the paint's color.
326 @param b The new blue component (0..255) of the paint's color.
327 */
328 void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
329
reed@google.com9d07fec2011-03-16 20:02:59 +0000330 /** Return the width for stroking.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000331 <p />
332 A value of 0 strokes in hairline mode.
333 Hairlines always draw 1-pixel wide, regardless of the matrix.
334 @return the paint's stroke width, used whenever the paint's style is
335 Stroke or StrokeAndFill.
336 */
337 SkScalar getStrokeWidth() const { return fWidth; }
338
reed@google.com9d07fec2011-03-16 20:02:59 +0000339 /** Set the width for stroking.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000340 Pass 0 to stroke in hairline mode.
341 Hairlines always draw 1-pixel wide, regardless of the matrix.
342 @param width set the paint's stroke width, used whenever the paint's
343 style is Stroke or StrokeAndFill.
344 */
345 void setStrokeWidth(SkScalar width);
346
347 /** Return the paint's stroke miter value. This is used to control the
348 behavior of miter joins when the joins angle is sharp.
349 @return the paint's miter limit, used whenever the paint's style is
350 Stroke or StrokeAndFill.
351 */
352 SkScalar getStrokeMiter() const { return fMiterLimit; }
353
354 /** Set the paint's stroke miter value. This is used to control the
355 behavior of miter joins when the joins angle is sharp. This value must
356 be >= 0.
357 @param miter set the miter limit on the paint, used whenever the
358 paint's style is Stroke or StrokeAndFill.
359 */
360 void setStrokeMiter(SkScalar miter);
361
362 /** Cap enum specifies the settings for the paint's strokecap. This is the
363 treatment that is applied to the beginning and end of each non-closed
364 contour (e.g. lines).
365 */
366 enum Cap {
367 kButt_Cap, //!< begin/end contours with no extension
368 kRound_Cap, //!< begin/end contours with a semi-circle extension
369 kSquare_Cap, //!< begin/end contours with a half square extension
370
371 kCapCount,
372 kDefault_Cap = kButt_Cap
373 };
374
375 /** Join enum specifies the settings for the paint's strokejoin. This is
376 the treatment that is applied to corners in paths and rectangles.
377 */
378 enum Join {
379 kMiter_Join, //!< connect path segments with a sharp join
380 kRound_Join, //!< connect path segments with a round join
381 kBevel_Join, //!< connect path segments with a flat bevel join
382
383 kJoinCount,
384 kDefault_Join = kMiter_Join
385 };
386
387 /** Return the paint's stroke cap type, controlling how the start and end
388 of stroked lines and paths are treated.
389 @return the line cap style for the paint, used whenever the paint's
390 style is Stroke or StrokeAndFill.
391 */
392 Cap getStrokeCap() const { return (Cap)fCapType; }
393
394 /** Set the paint's stroke cap type.
395 @param cap set the paint's line cap style, used whenever the paint's
396 style is Stroke or StrokeAndFill.
397 */
398 void setStrokeCap(Cap cap);
399
400 /** Return the paint's stroke join type.
401 @return the paint's line join style, used whenever the paint's style is
402 Stroke or StrokeAndFill.
403 */
404 Join getStrokeJoin() const { return (Join)fJoinType; }
405
406 /** Set the paint's stroke join type.
407 @param join set the paint's line join style, used whenever the paint's
408 style is Stroke or StrokeAndFill.
409 */
410 void setStrokeJoin(Join join);
411
412 /** Applies any/all effects (patheffect, stroking) to src, returning the
413 result in dst. The result is that drawing src with this paint will be
414 the same as drawing dst with a default paint (at least from the
415 geometric perspective).
416 @param src input path
417 @param dst output path (may be the same as src)
418 @return true if the path should be filled, or false if it should be
419 drawn with a hairline (width == 0)
420 */
421 bool getFillPath(const SkPath& src, SkPath* dst) const;
422
423 /** Returns true if the current paint settings allow for fast computation of
424 bounds (i.e. there is nothing complex like a patheffect that would make
425 the bounds computation expensive.
426 */
reed@android.comd252db02009-04-01 18:31:44 +0000427 bool canComputeFastBounds() const {
428 // use bit-or since no need for early exit
429 return (reinterpret_cast<uintptr_t>(this->getMaskFilter()) |
430 reinterpret_cast<uintptr_t>(this->getLooper()) |
431 reinterpret_cast<uintptr_t>(this->getRasterizer()) |
432 reinterpret_cast<uintptr_t>(this->getPathEffect())) == 0;
433 }
434
reed@android.com8a1c16f2008-12-17 15:59:43 +0000435 /** Only call this if canComputeFastBounds() returned true. This takes a
436 raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
437 effects in the paint (e.g. stroking). If needed, it uses the storage
438 rect parameter. It returns the adjusted bounds that can then be used
439 for quickReject tests.
reed@google.com9d07fec2011-03-16 20:02:59 +0000440
reed@android.com8a1c16f2008-12-17 15:59:43 +0000441 The returned rect will either be orig or storage, thus the caller
442 should not rely on storage being set to the result, but should always
443 use the retured value. It is legal for orig and storage to be the same
444 rect.
reed@google.com9d07fec2011-03-16 20:02:59 +0000445
reed@android.com8a1c16f2008-12-17 15:59:43 +0000446 e.g.
447 if (paint.canComputeFastBounds()) {
448 SkRect r, storage;
449 path.computeBounds(&r, SkPath::kFast_BoundsType);
450 const SkRect& fastR = paint.computeFastBounds(r, &storage);
451 if (canvas->quickReject(fastR, ...)) {
452 // don't draw the path
453 }
454 }
455 */
reed@android.comd252db02009-04-01 18:31:44 +0000456 const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const {
457 return this->getStyle() == kFill_Style ? orig :
458 this->computeStrokeFastBounds(orig, storage);
459 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000460
461 /** Get the paint's shader object.
462 <p />
463 The shader's reference count is not affected.
464 @return the paint's shader (or NULL)
465 */
466 SkShader* getShader() const { return fShader; }
467
468 /** Set or clear the shader object.
469 <p />
470 Pass NULL to clear any previous shader.
471 As a convenience, the parameter passed is also returned.
472 If a previous shader exists, its reference count is decremented.
473 If shader is not NULL, its reference count is incremented.
474 @param shader May be NULL. The shader to be installed in the paint
475 @return shader
476 */
477 SkShader* setShader(SkShader* shader);
reed@google.com9d07fec2011-03-16 20:02:59 +0000478
reed@android.com8a1c16f2008-12-17 15:59:43 +0000479 /** Get the paint's colorfilter. If there is a colorfilter, its reference
480 count is not changed.
481 @return the paint's colorfilter (or NULL)
482 */
483 SkColorFilter* getColorFilter() const { return fColorFilter; }
484
485 /** Set or clear the paint's colorfilter, returning the parameter.
486 <p />
487 If the paint already has a filter, its reference count is decremented.
488 If filter is not NULL, its reference count is incremented.
489 @param filter May be NULL. The filter to be installed in the paint
490 @return filter
491 */
492 SkColorFilter* setColorFilter(SkColorFilter* filter);
493
494 /** Get the paint's xfermode object.
495 <p />
496 The xfermode's reference count is not affected.
497 @return the paint's xfermode (or NULL)
498 */
499 SkXfermode* getXfermode() const { return fXfermode; }
500
501 /** Set or clear the xfermode object.
502 <p />
503 Pass NULL to clear any previous xfermode.
504 As a convenience, the parameter passed is also returned.
505 If a previous xfermode exists, its reference count is decremented.
506 If xfermode is not NULL, its reference count is incremented.
507 @param xfermode May be NULL. The new xfermode to be installed in the
508 paint
509 @return xfermode
510 */
511 SkXfermode* setXfermode(SkXfermode* xfermode);
reed@android.coma0f5d152009-06-22 17:38:10 +0000512
513 /** Create an xfermode based on the specified Mode, and assign it into the
514 paint, returning the mode that was set. If the Mode is SrcOver, then
515 the paint's xfermode is set to null.
516 */
reed@android.com0baf1932009-06-24 12:41:42 +0000517 SkXfermode* setXfermodeMode(SkXfermode::Mode);
reed@android.coma0f5d152009-06-22 17:38:10 +0000518
reed@android.com8a1c16f2008-12-17 15:59:43 +0000519 /** Get the paint's patheffect object.
520 <p />
521 The patheffect reference count is not affected.
522 @return the paint's patheffect (or NULL)
523 */
524 SkPathEffect* getPathEffect() const { return fPathEffect; }
525
526 /** Set or clear the patheffect object.
527 <p />
528 Pass NULL to clear any previous patheffect.
529 As a convenience, the parameter passed is also returned.
530 If a previous patheffect exists, its reference count is decremented.
531 If patheffect is not NULL, its reference count is incremented.
532 @param effect May be NULL. The new patheffect to be installed in the
533 paint
534 @return effect
535 */
536 SkPathEffect* setPathEffect(SkPathEffect* effect);
537
538 /** Get the paint's maskfilter object.
539 <p />
540 The maskfilter reference count is not affected.
541 @return the paint's maskfilter (or NULL)
542 */
543 SkMaskFilter* getMaskFilter() const { return fMaskFilter; }
544
545 /** Set or clear the maskfilter object.
546 <p />
547 Pass NULL to clear any previous maskfilter.
548 As a convenience, the parameter passed is also returned.
549 If a previous maskfilter exists, its reference count is decremented.
550 If maskfilter is not NULL, its reference count is incremented.
551 @param maskfilter May be NULL. The new maskfilter to be installed in
552 the paint
553 @return maskfilter
554 */
555 SkMaskFilter* setMaskFilter(SkMaskFilter* maskfilter);
556
557 // These attributes are for text/fonts
558
559 /** Get the paint's typeface object.
560 <p />
561 The typeface object identifies which font to use when drawing or
562 measuring text. The typeface reference count is not affected.
563 @return the paint's typeface (or NULL)
564 */
565 SkTypeface* getTypeface() const { return fTypeface; }
566
567 /** Set or clear the typeface object.
568 <p />
569 Pass NULL to clear any previous typeface.
570 As a convenience, the parameter passed is also returned.
571 If a previous typeface exists, its reference count is decremented.
572 If typeface is not NULL, its reference count is incremented.
573 @param typeface May be NULL. The new typeface to be installed in the
574 paint
575 @return typeface
576 */
577 SkTypeface* setTypeface(SkTypeface* typeface);
578
579 /** Get the paint's rasterizer (or NULL).
580 <p />
581 The raster controls how paths/text are turned into alpha masks.
582 @return the paint's rasterizer (or NULL)
583 */
584 SkRasterizer* getRasterizer() const { return fRasterizer; }
585
586 /** Set or clear the rasterizer object.
587 <p />
588 Pass NULL to clear any previous rasterizer.
589 As a convenience, the parameter passed is also returned.
590 If a previous rasterizer exists in the paint, its reference count is
591 decremented. If rasterizer is not NULL, its reference count is
592 incremented.
593 @param rasterizer May be NULL. The new rasterizer to be installed in
594 the paint.
595 @return rasterizer
596 */
597 SkRasterizer* setRasterizer(SkRasterizer* rasterizer);
598
reed@google.com15356a62011-11-03 19:29:08 +0000599 SkImageFilter* getImageFilter() const { return fImageFilter; }
600 SkImageFilter* setImageFilter(SkImageFilter*);
601
reed@google.com9d07fec2011-03-16 20:02:59 +0000602 /**
603 * Return the paint's SkDrawLooper (if any). Does not affect the looper's
604 * reference count.
605 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000606 SkDrawLooper* getLooper() const { return fLooper; }
reed@google.com9d07fec2011-03-16 20:02:59 +0000607
608 /**
609 * Set or clear the looper object.
610 * <p />
611 * Pass NULL to clear any previous looper.
612 * As a convenience, the parameter passed is also returned.
613 * If a previous looper exists in the paint, its reference count is
614 * decremented. If looper is not NULL, its reference count is
615 * incremented.
616 * @param looper May be NULL. The new looper to be installed in the paint.
617 * @return looper
618 */
619 SkDrawLooper* setLooper(SkDrawLooper* looper);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000620
621 enum Align {
622 kLeft_Align,
623 kCenter_Align,
624 kRight_Align,
625
626 kAlignCount
627 };
reed@google.com9d07fec2011-03-16 20:02:59 +0000628
reed@android.com8a1c16f2008-12-17 15:59:43 +0000629 /** Return the paint's Align value for drawing text.
630 @return the paint's Align value for drawing text.
631 */
632 Align getTextAlign() const { return (Align)fTextAlign; }
reed@google.com9d07fec2011-03-16 20:02:59 +0000633
reed@android.com8a1c16f2008-12-17 15:59:43 +0000634 /** Set the paint's text alignment.
635 @param align set the paint's Align value for drawing text.
636 */
637 void setTextAlign(Align align);
638
639 /** Return the paint's text size.
640 @return the paint's text size.
641 */
642 SkScalar getTextSize() const { return fTextSize; }
643
644 /** Set the paint's text size. This value must be > 0
645 @param textSize set the paint's text size.
646 */
647 void setTextSize(SkScalar textSize);
648
649 /** Return the paint's horizontal scale factor for text. The default value
650 is 1.0.
651 @return the paint's scale factor in X for drawing/measuring text
652 */
653 SkScalar getTextScaleX() const { return fTextScaleX; }
654
655 /** Set the paint's horizontal scale factor for text. The default value
656 is 1.0. Values > 1.0 will stretch the text wider. Values < 1.0 will
657 stretch the text narrower.
658 @param scaleX set the paint's scale factor in X for drawing/measuring
659 text.
660 */
661 void setTextScaleX(SkScalar scaleX);
662
663 /** Return the paint's horizontal skew factor for text. The default value
664 is 0.
665 @return the paint's skew factor in X for drawing text.
666 */
667 SkScalar getTextSkewX() const { return fTextSkewX; }
668
669 /** Set the paint's horizontal skew factor for text. The default value
670 is 0. For approximating oblique text, use values around -0.25.
671 @param skewX set the paint's skew factor in X for drawing text.
672 */
673 void setTextSkewX(SkScalar skewX);
674
675 /** Describes how to interpret the text parameters that are passed to paint
676 methods like measureText() and getTextWidths().
677 */
678 enum TextEncoding {
679 kUTF8_TextEncoding, //!< the text parameters are UTF8
680 kUTF16_TextEncoding, //!< the text parameters are UTF16
681 kGlyphID_TextEncoding //!< the text parameters are glyph indices
682 };
reed@google.com9d07fec2011-03-16 20:02:59 +0000683
684 TextEncoding getTextEncoding() const { return (TextEncoding)fTextEncoding; }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000685
686 void setTextEncoding(TextEncoding encoding);
687
688 struct FontMetrics {
689 SkScalar fTop; //!< The greatest distance above the baseline for any glyph (will be <= 0)
690 SkScalar fAscent; //!< The recommended distance above the baseline (will be <= 0)
691 SkScalar fDescent; //!< The recommended distance below the baseline (will be >= 0)
692 SkScalar fBottom; //!< The greatest distance below the baseline for any glyph (will be >= 0)
693 SkScalar fLeading; //!< The recommended distance to add between lines of text (will be >= 0)
agl@chromium.orgcc3096b2009-04-22 22:09:04 +0000694 SkScalar fAvgCharWidth; //!< the average charactor width (>= 0)
695 SkScalar fXMin; //!< The minimum bounding box x value for all glyphs
696 SkScalar fXMax; //!< The maximum bounding box x value for all glyphs
697 SkScalar fXHeight; //!< the height of an 'x' in px, or 0 if no 'x' in face
reed@android.com8a1c16f2008-12-17 15:59:43 +0000698 };
reed@google.com9d07fec2011-03-16 20:02:59 +0000699
reed@android.com8a1c16f2008-12-17 15:59:43 +0000700 /** Return the recommend spacing between lines (which will be
701 fDescent - fAscent + fLeading).
702 If metrics is not null, return in it the font metrics for the
reed@google.com9d07fec2011-03-16 20:02:59 +0000703 typeface/pointsize/etc. currently set in the paint.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000704 @param metrics If not null, returns the font metrics for the
705 current typeface/pointsize/etc setting in this
706 paint.
707 @param scale If not 0, return width as if the canvas were scaled
708 by this value
709 @param return the recommended spacing between lines
710 */
711 SkScalar getFontMetrics(FontMetrics* metrics, SkScalar scale = 0) const;
reed@google.com9d07fec2011-03-16 20:02:59 +0000712
reed@android.com8a1c16f2008-12-17 15:59:43 +0000713 /** Return the recommend line spacing. This will be
714 fDescent - fAscent + fLeading
715 */
716 SkScalar getFontSpacing() const { return this->getFontMetrics(NULL, 0); }
717
718 /** Convert the specified text into glyph IDs, returning the number of
719 glyphs ID written. If glyphs is NULL, it is ignore and only the count
720 is returned.
721 */
722 int textToGlyphs(const void* text, size_t byteLength,
723 uint16_t glyphs[]) const;
724
reed@android.coma5dcaf62010-02-05 17:12:32 +0000725 /** Return true if all of the specified text has a corresponding non-zero
726 glyph ID. If any of the code-points in the text are not supported in
727 the typeface (i.e. the glyph ID would be zero), then return false.
728
729 If the text encoding for the paint is kGlyph_TextEncoding, then this
730 returns true if all of the specified glyph IDs are non-zero.
731 */
732 bool containsText(const void* text, size_t byteLength) const;
733
reed@android.com9d3a9852010-01-08 14:07:42 +0000734 /** Convert the glyph array into Unichars. Unconvertable glyphs are mapped
735 to zero. Note: this does not look at the text-encoding setting in the
736 paint, only at the typeface.
737 */
738 void glyphsToUnichars(const uint16_t glyphs[], int count,
739 SkUnichar text[]) const;
740
reed@android.com8a1c16f2008-12-17 15:59:43 +0000741 /** Return the number of drawable units in the specified text buffer.
742 This looks at the current TextEncoding field of the paint. If you also
743 want to have the text converted into glyph IDs, call textToGlyphs
744 instead.
745 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000746 int countText(const void* text, size_t byteLength) const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000747 return this->textToGlyphs(text, byteLength, NULL);
748 }
749
750 /** Return the width of the text.
751 @param text The text to be measured
752 @param length Number of bytes of text to measure
753 @param bounds If not NULL, returns the bounds of the text,
754 relative to (0, 0).
755 @param scale If not 0, return width as if the canvas were scaled
756 by this value
757 @return The advance width of the text
758 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000759 SkScalar measureText(const void* text, size_t length,
760 SkRect* bounds, SkScalar scale = 0) const;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000761
762 /** Return the width of the text.
763 @param text Address of the text
764 @param length Number of bytes of text to measure
765 @return The width of the text
766 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000767 SkScalar measureText(const void* text, size_t length) const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000768 return this->measureText(text, length, NULL, 0);
769 }
reed@google.com9d07fec2011-03-16 20:02:59 +0000770
reed@android.com8a1c16f2008-12-17 15:59:43 +0000771 /** Specify the direction the text buffer should be processed in breakText()
772 */
773 enum TextBufferDirection {
774 /** When measuring text for breakText(), begin at the start of the text
775 buffer and proceed forward through the data. This is the default.
776 */
777 kForward_TextBufferDirection,
778 /** When measuring text for breakText(), begin at the end of the text
779 buffer and proceed backwards through the data.
780 */
781 kBackward_TextBufferDirection
782 };
783
784 /** Return the width of the text.
785 @param text The text to be measured
786 @param length Number of bytes of text to measure
787 @param maxWidth Maximum width. Only the subset of text whose accumulated
788 widths are <= maxWidth are measured.
789 @param measuredWidth Optional. If non-null, this returns the actual
790 width of the measured text.
791 @param tbd Optional. The direction the text buffer should be
792 traversed during measuring.
793 @return The number of bytes of text that were measured. Will be
794 <= length.
795 */
796 size_t breakText(const void* text, size_t length, SkScalar maxWidth,
797 SkScalar* measuredWidth = NULL,
798 TextBufferDirection tbd = kForward_TextBufferDirection)
799 const;
800
801 /** Return the advance widths for the characters in the string.
802 @param text the text
803 @param byteLength number of bytes to of text
804 @param widths If not null, returns the array of advance widths of
805 the glyphs. If not NULL, must be at least a large
806 as the number of unichars in the specified text.
807 @param bounds If not null, returns the bounds for each of
808 character, relative to (0, 0)
809 @return the number of unichars in the specified text.
810 */
811 int getTextWidths(const void* text, size_t byteLength, SkScalar widths[],
812 SkRect bounds[] = NULL) const;
813
814 /** Return the path (outline) for the specified text.
815 Note: just like SkCanvas::drawText, this will respect the Align setting
816 in the paint.
817 */
818 void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y,
819 SkPath* path) const;
820
djsollen@google.comf5dbe2f2011-04-15 13:41:26 +0000821#ifdef ANDROID
822 const SkGlyph& getUnicharMetrics(SkUnichar);
823 const void* findImage(const SkGlyph&);
824
825 uint32_t getGenerationID() const;
826#endif
827
reed@google.com632e1a22011-10-06 12:37:00 +0000828 // returns true if the paint's settings (e.g. xfermode + alpha) resolve to
829 // mean that we need not draw at all (e.g. SrcOver + 0-alpha)
830 bool nothingToDraw() const;
831
reed@android.com8a1c16f2008-12-17 15:59:43 +0000832private:
833 SkTypeface* fTypeface;
834 SkScalar fTextSize;
835 SkScalar fTextScaleX;
836 SkScalar fTextSkewX;
837
838 SkPathEffect* fPathEffect;
839 SkShader* fShader;
840 SkXfermode* fXfermode;
841 SkMaskFilter* fMaskFilter;
842 SkColorFilter* fColorFilter;
843 SkRasterizer* fRasterizer;
844 SkDrawLooper* fLooper;
reed@google.com15356a62011-11-03 19:29:08 +0000845 SkImageFilter* fImageFilter;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000846
847 SkColor fColor;
848 SkScalar fWidth;
849 SkScalar fMiterLimit;
reed@google.com32538982011-09-30 20:57:05 +0000850 unsigned fFlags : 13;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000851 unsigned fTextAlign : 2;
852 unsigned fCapType : 2;
853 unsigned fJoinType : 2;
854 unsigned fStyle : 2;
855 unsigned fTextEncoding : 2; // 3 values
agl@chromium.org309485b2009-07-21 17:41:32 +0000856 unsigned fHinting : 2;
djsollen@google.comf5dbe2f2011-04-15 13:41:26 +0000857#ifdef ANDROID
858 uint32_t fGenerationID;
859#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000860
861 SkDrawCacheProc getDrawCacheProc() const;
862 SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir,
863 bool needFullMetrics) const;
864
865 SkScalar measure_text(SkGlyphCache*, const char* text, size_t length,
866 int* count, SkRect* bounds) const;
867
868 SkGlyphCache* detachCache(const SkMatrix*) const;
869
870 void descriptorProc(const SkMatrix* deviceMatrix,
871 void (*proc)(const SkDescriptor*, void*),
djsollen@google.com57f49692011-02-23 20:46:31 +0000872 void* context, bool ignoreGamma = false) const;
reed@android.comd252db02009-04-01 18:31:44 +0000873
874 const SkRect& computeStrokeFastBounds(const SkRect& orig,
875 SkRect* storage) const;
876
reed@android.com8a1c16f2008-12-17 15:59:43 +0000877 enum {
878 kCanonicalTextSizeForPaths = 64
879 };
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000880 friend class SkAutoGlyphCache;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000881 friend class SkCanvas;
882 friend class SkDraw;
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000883 friend class SkPDFDevice;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000884 friend class SkTextToPathIter;
885};
886
reed@google.com6bac9472011-06-21 19:24:00 +0000887///////////////////////////////////////////////////////////////////////////////
reed@android.com8a1c16f2008-12-17 15:59:43 +0000888
889#include "SkPathEffect.h"
890
891/** \class SkStrokePathEffect
892
893 SkStrokePathEffect simulates stroking inside a patheffect, allowing the
894 caller to have explicit control of when to stroke a path. Typically this is
895 used if the caller wants to stroke before another patheffect is applied
896 (using SkComposePathEffect or SkSumPathEffect).
897*/
898class SkStrokePathEffect : public SkPathEffect {
899public:
900 SkStrokePathEffect(const SkPaint&);
901 SkStrokePathEffect(SkScalar width, SkPaint::Style, SkPaint::Join,
902 SkPaint::Cap, SkScalar miterLimit = -1);
903
904 // overrides
reed@android.com8a1c16f2008-12-17 15:59:43 +0000905 virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
906
907 // overrides for SkFlattenable
reed@android.com8a1c16f2008-12-17 15:59:43 +0000908 virtual void flatten(SkFlattenableWriteBuffer&);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000909 virtual Factory getFactory();
910
reed@google.com6bac9472011-06-21 19:24:00 +0000911 static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
912
reed@android.com8a1c16f2008-12-17 15:59:43 +0000913private:
914 SkScalar fWidth, fMiter;
915 uint8_t fStyle, fJoin, fCap;
916
reed@android.com8a1c16f2008-12-17 15:59:43 +0000917 SkStrokePathEffect(SkFlattenableReadBuffer&);
918
919 typedef SkPathEffect INHERITED;
920
921 // illegal
922 SkStrokePathEffect(const SkStrokePathEffect&);
923 SkStrokePathEffect& operator=(const SkStrokePathEffect&);
924};
925
926#endif
927