blob: a1dc59c17955d93d070f52af8d4c4921b75db09a [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"
14#include "SkMath.h"
reed@android.coma0f5d152009-06-22 17:38:10 +000015#include "SkXfermode.h"
16
reed@android.com8a1c16f2008-12-17 15:59:43 +000017class SkAutoGlyphCache;
18class SkColorFilter;
19class SkDescriptor;
20class SkFlattenableReadBuffer;
21class SkFlattenableWriteBuffer;
22struct SkGlyph;
23struct SkRect;
24class SkGlyphCache;
25class 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
agl@chromium.org309485b2009-07-21 17:41:32 +0000102 // when adding extra flags, note that the fFlags member is specified
103 // with a bit-width and you'll have to expand it.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000104
agl@chromium.orga2c71cb2010-06-17 20:49:17 +0000105 kAllFlags = 0xFFF
reed@android.com8a1c16f2008-12-17 15:59:43 +0000106 };
107
108 /** Return the paint's flags. Use the Flag enum to test flag values.
109 @return the paint's flags (see enums ending in _Flag for bit masks)
110 */
111 uint32_t getFlags() const { return fFlags; }
112
113 /** Set the paint's flags. Use the Flag enum to specific flag values.
114 @param flags The new flag bits for the paint (see Flags enum)
115 */
116 void setFlags(uint32_t flags);
117
118 /** Helper for getFlags(), returning true if kAntiAlias_Flag bit is set
119 @return true if the antialias bit is set in the paint's flags.
120 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000121 bool isAntiAlias() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000122 return SkToBool(this->getFlags() & kAntiAlias_Flag);
123 }
reed@google.com9d07fec2011-03-16 20:02:59 +0000124
reed@android.com8a1c16f2008-12-17 15:59:43 +0000125 /** Helper for setFlags(), setting or clearing the kAntiAlias_Flag bit
126 @param aa true to enable antialiasing, false to disable it
127 */
128 void setAntiAlias(bool aa);
reed@google.com9d07fec2011-03-16 20:02:59 +0000129
reed@android.com8a1c16f2008-12-17 15:59:43 +0000130 /** Helper for getFlags(), returning true if kDither_Flag bit is set
131 @return true if the dithering bit is set in the paint's flags.
132 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000133 bool isDither() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000134 return SkToBool(this->getFlags() & kDither_Flag);
135 }
reed@google.com9d07fec2011-03-16 20:02:59 +0000136
reed@android.com8a1c16f2008-12-17 15:59:43 +0000137 /** Helper for setFlags(), setting or clearing the kDither_Flag bit
138 @param dither true to enable dithering, false to disable it
139 */
140 void setDither(bool dither);
reed@google.com9d07fec2011-03-16 20:02:59 +0000141
reed@android.com8a1c16f2008-12-17 15:59:43 +0000142 /** Helper for getFlags(), returning true if kLinearText_Flag bit is set
143 @return true if the lineartext bit is set in the paint's flags
144 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000145 bool isLinearText() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000146 return SkToBool(this->getFlags() & kLinearText_Flag);
147 }
148
149 /** Helper for setFlags(), setting or clearing the kLinearText_Flag bit
150 @param linearText true to set the linearText bit in the paint's flags,
151 false to clear it.
152 */
153 void setLinearText(bool linearText);
154
155 /** Helper for getFlags(), returning true if kSubpixelText_Flag bit is set
156 @return true if the lineartext bit is set in the paint's flags
157 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000158 bool isSubpixelText() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000159 return SkToBool(this->getFlags() & kSubpixelText_Flag);
160 }
reed@google.com9d07fec2011-03-16 20:02:59 +0000161
reed@google.com84b437e2011-08-01 12:45:35 +0000162 /**
163 * Helper for setFlags(), setting or clearing the kSubpixelText_Flag.
164 * @param subpixelText true to set the subpixelText bit in the paint's
165 * flags, false to clear it.
166 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000167 void setSubpixelText(bool subpixelText);
agl@chromium.org309485b2009-07-21 17:41:32 +0000168
reed@google.com9d07fec2011-03-16 20:02:59 +0000169 bool isLCDRenderText() const {
agl@chromium.org309485b2009-07-21 17:41:32 +0000170 return SkToBool(this->getFlags() & kLCDRenderText_Flag);
171 }
172
reed@google.com84b437e2011-08-01 12:45:35 +0000173 /**
174 * Helper for setFlags(), setting or clearing the kLCDRenderText_Flag.
175 * Note: antialiasing must also be on for lcd rendering
176 * @param lcdText true to set the LCDRenderText bit in the paint's flags,
177 * false to clear it.
178 */
179 void setLCDRenderText(bool lcdText);
agl@chromium.org309485b2009-07-21 17:41:32 +0000180
reed@google.com9d07fec2011-03-16 20:02:59 +0000181 bool isEmbeddedBitmapText() const {
agl@chromium.orge95c91e2010-01-04 18:27:55 +0000182 return SkToBool(this->getFlags() & kEmbeddedBitmapText_Flag);
183 }
184
185 /** Helper for setFlags(), setting or clearing the kEmbeddedBitmapText_Flag bit
186 @param useEmbeddedBitmapText true to set the kEmbeddedBitmapText bit in the paint's flags,
187 false to clear it.
188 */
189 void setEmbeddedBitmapText(bool useEmbeddedBitmapText);
190
reed@google.com9d07fec2011-03-16 20:02:59 +0000191 bool isAutohinted() const {
agl@chromium.orga2c71cb2010-06-17 20:49:17 +0000192 return SkToBool(this->getFlags() & kAutoHinting_Flag);
193 }
194
195 /** Helper for setFlags(), setting or clearing the kAutoHinting_Flag bit
196 @param useAutohinter true to set the kEmbeddedBitmapText bit in the
197 paint's flags,
198 false to clear it.
199 */
200 void setAutohinted(bool useAutohinter);
201
reed@android.com8a1c16f2008-12-17 15:59:43 +0000202 /** Helper for getFlags(), returning true if kUnderlineText_Flag bit is set
203 @return true if the underlineText bit is set in the paint's flags.
204 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000205 bool isUnderlineText() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000206 return SkToBool(this->getFlags() & kUnderlineText_Flag);
207 }
208
209 /** Helper for setFlags(), setting or clearing the kUnderlineText_Flag bit
210 @param underlineText true to set the underlineText bit in the paint's
211 flags, false to clear it.
212 */
213 void setUnderlineText(bool underlineText);
214
215 /** Helper for getFlags(), returns true if kStrikeThruText_Flag bit is set
216 @return true if the strikeThruText bit is set in the paint's flags.
217 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000218 bool isStrikeThruText() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000219 return SkToBool(this->getFlags() & kStrikeThruText_Flag);
220 }
221
222 /** Helper for setFlags(), setting or clearing the kStrikeThruText_Flag bit
223 @param strikeThruText true to set the strikeThruText bit in the
224 paint's flags, false to clear it.
225 */
226 void setStrikeThruText(bool strikeThruText);
227
228 /** Helper for getFlags(), returns true if kFakeBoldText_Flag bit is set
229 @return true if the kFakeBoldText_Flag bit is set in the paint's flags.
230 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000231 bool isFakeBoldText() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000232 return SkToBool(this->getFlags() & kFakeBoldText_Flag);
233 }
234
235 /** Helper for setFlags(), setting or clearing the kFakeBoldText_Flag bit
236 @param fakeBoldText true to set the kFakeBoldText_Flag bit in the paint's
237 flags, false to clear it.
238 */
239 void setFakeBoldText(bool fakeBoldText);
240
241 /** Helper for getFlags(), returns true if kDevKernText_Flag bit is set
242 @return true if the kernText bit is set in the paint's flags.
243 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000244 bool isDevKernText() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000245 return SkToBool(this->getFlags() & kDevKernText_Flag);
246 }
247
248 /** Helper for setFlags(), setting or clearing the kKernText_Flag bit
249 @param kernText true to set the kKernText_Flag bit in the paint's
250 flags, false to clear it.
251 */
252 void setDevKernText(bool devKernText);
253
reed@google.com9d07fec2011-03-16 20:02:59 +0000254 bool isFilterBitmap() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000255 return SkToBool(this->getFlags() & kFilterBitmap_Flag);
256 }
reed@google.com9d07fec2011-03-16 20:02:59 +0000257
reed@android.com8a1c16f2008-12-17 15:59:43 +0000258 void setFilterBitmap(bool filterBitmap);
259
260 /** Styles apply to rect, oval, path, and text.
261 Bitmaps are always drawn in "fill", and lines are always drawn in
262 "stroke".
reed@google.com9d07fec2011-03-16 20:02:59 +0000263
reed@android.comed881c22009-09-15 14:10:42 +0000264 Note: strokeandfill implicitly draws the result with
265 SkPath::kWinding_FillType, so if the original path is even-odd, the
266 results may not appear the same as if it was drawn twice, filled and
267 then stroked.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000268 */
269 enum Style {
reed@android.comed881c22009-09-15 14:10:42 +0000270 kFill_Style, //!< fill the geometry
271 kStroke_Style, //!< stroke the geometry
272 kStrokeAndFill_Style, //!< fill and stroke the geometry
reed@android.com8a1c16f2008-12-17 15:59:43 +0000273
274 kStyleCount,
275 };
276
277 /** Return the paint's style, used for controlling how primitives'
278 geometries are interpreted (except for drawBitmap, which always assumes
279 kFill_Style).
280 @return the paint's Style
281 */
282 Style getStyle() const { return (Style)fStyle; }
283
284 /** Set the paint's style, used for controlling how primitives'
285 geometries are interpreted (except for drawBitmap, which always assumes
286 Fill).
287 @param style The new style to set in the paint
288 */
289 void setStyle(Style style);
290
291 /** Return the paint's color. Note that the color is a 32bit value
292 containing alpha as well as r,g,b. This 32bit value is not
293 premultiplied, meaning that its alpha can be any value, regardless of
294 the values of r,g,b.
295 @return the paint's color (and alpha).
296 */
297 SkColor getColor() const { return fColor; }
298
299 /** Set the paint's color. Note that the color is a 32bit value containing
300 alpha as well as r,g,b. This 32bit value is not premultiplied, meaning
301 that its alpha can be any value, regardless of the values of r,g,b.
302 @param color The new color (including alpha) to set in the paint.
303 */
304 void setColor(SkColor color);
305
306 /** Helper to getColor() that just returns the color's alpha value.
307 @return the alpha component of the paint's color.
308 */
309 uint8_t getAlpha() const { return SkToU8(SkColorGetA(fColor)); }
reed@google.com9d07fec2011-03-16 20:02:59 +0000310
reed@android.com8a1c16f2008-12-17 15:59:43 +0000311 /** Helper to setColor(), that only assigns the color's alpha value,
312 leaving its r,g,b values unchanged.
313 @param a set the alpha component (0..255) of the paint's color.
314 */
315 void setAlpha(U8CPU a);
316
317 /** Helper to setColor(), that takes a,r,g,b and constructs the color value
318 using SkColorSetARGB()
319 @param a The new alpha component (0..255) of the paint's color.
320 @param r The new red component (0..255) of the paint's color.
321 @param g The new green component (0..255) of the paint's color.
322 @param b The new blue component (0..255) of the paint's color.
323 */
324 void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
325
reed@google.com9d07fec2011-03-16 20:02:59 +0000326 /** Return the width for stroking.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000327 <p />
328 A value of 0 strokes in hairline mode.
329 Hairlines always draw 1-pixel wide, regardless of the matrix.
330 @return the paint's stroke width, used whenever the paint's style is
331 Stroke or StrokeAndFill.
332 */
333 SkScalar getStrokeWidth() const { return fWidth; }
334
reed@google.com9d07fec2011-03-16 20:02:59 +0000335 /** Set the width for stroking.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000336 Pass 0 to stroke in hairline mode.
337 Hairlines always draw 1-pixel wide, regardless of the matrix.
338 @param width set the paint's stroke width, used whenever the paint's
339 style is Stroke or StrokeAndFill.
340 */
341 void setStrokeWidth(SkScalar width);
342
343 /** Return the paint's stroke miter value. This is used to control the
344 behavior of miter joins when the joins angle is sharp.
345 @return the paint's miter limit, used whenever the paint's style is
346 Stroke or StrokeAndFill.
347 */
348 SkScalar getStrokeMiter() const { return fMiterLimit; }
349
350 /** Set the paint's stroke miter value. This is used to control the
351 behavior of miter joins when the joins angle is sharp. This value must
352 be >= 0.
353 @param miter set the miter limit on the paint, used whenever the
354 paint's style is Stroke or StrokeAndFill.
355 */
356 void setStrokeMiter(SkScalar miter);
357
358 /** Cap enum specifies the settings for the paint's strokecap. This is the
359 treatment that is applied to the beginning and end of each non-closed
360 contour (e.g. lines).
361 */
362 enum Cap {
363 kButt_Cap, //!< begin/end contours with no extension
364 kRound_Cap, //!< begin/end contours with a semi-circle extension
365 kSquare_Cap, //!< begin/end contours with a half square extension
366
367 kCapCount,
368 kDefault_Cap = kButt_Cap
369 };
370
371 /** Join enum specifies the settings for the paint's strokejoin. This is
372 the treatment that is applied to corners in paths and rectangles.
373 */
374 enum Join {
375 kMiter_Join, //!< connect path segments with a sharp join
376 kRound_Join, //!< connect path segments with a round join
377 kBevel_Join, //!< connect path segments with a flat bevel join
378
379 kJoinCount,
380 kDefault_Join = kMiter_Join
381 };
382
383 /** Return the paint's stroke cap type, controlling how the start and end
384 of stroked lines and paths are treated.
385 @return the line cap style for the paint, used whenever the paint's
386 style is Stroke or StrokeAndFill.
387 */
388 Cap getStrokeCap() const { return (Cap)fCapType; }
389
390 /** Set the paint's stroke cap type.
391 @param cap set the paint's line cap style, used whenever the paint's
392 style is Stroke or StrokeAndFill.
393 */
394 void setStrokeCap(Cap cap);
395
396 /** Return the paint's stroke join type.
397 @return the paint's line join style, used whenever the paint's style is
398 Stroke or StrokeAndFill.
399 */
400 Join getStrokeJoin() const { return (Join)fJoinType; }
401
402 /** Set the paint's stroke join type.
403 @param join set the paint's line join style, used whenever the paint's
404 style is Stroke or StrokeAndFill.
405 */
406 void setStrokeJoin(Join join);
407
408 /** Applies any/all effects (patheffect, stroking) to src, returning the
409 result in dst. The result is that drawing src with this paint will be
410 the same as drawing dst with a default paint (at least from the
411 geometric perspective).
412 @param src input path
413 @param dst output path (may be the same as src)
414 @return true if the path should be filled, or false if it should be
415 drawn with a hairline (width == 0)
416 */
417 bool getFillPath(const SkPath& src, SkPath* dst) const;
418
419 /** Returns true if the current paint settings allow for fast computation of
420 bounds (i.e. there is nothing complex like a patheffect that would make
421 the bounds computation expensive.
422 */
reed@android.comd252db02009-04-01 18:31:44 +0000423 bool canComputeFastBounds() const {
424 // use bit-or since no need for early exit
425 return (reinterpret_cast<uintptr_t>(this->getMaskFilter()) |
426 reinterpret_cast<uintptr_t>(this->getLooper()) |
427 reinterpret_cast<uintptr_t>(this->getRasterizer()) |
428 reinterpret_cast<uintptr_t>(this->getPathEffect())) == 0;
429 }
430
reed@android.com8a1c16f2008-12-17 15:59:43 +0000431 /** Only call this if canComputeFastBounds() returned true. This takes a
432 raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
433 effects in the paint (e.g. stroking). If needed, it uses the storage
434 rect parameter. It returns the adjusted bounds that can then be used
435 for quickReject tests.
reed@google.com9d07fec2011-03-16 20:02:59 +0000436
reed@android.com8a1c16f2008-12-17 15:59:43 +0000437 The returned rect will either be orig or storage, thus the caller
438 should not rely on storage being set to the result, but should always
439 use the retured value. It is legal for orig and storage to be the same
440 rect.
reed@google.com9d07fec2011-03-16 20:02:59 +0000441
reed@android.com8a1c16f2008-12-17 15:59:43 +0000442 e.g.
443 if (paint.canComputeFastBounds()) {
444 SkRect r, storage;
445 path.computeBounds(&r, SkPath::kFast_BoundsType);
446 const SkRect& fastR = paint.computeFastBounds(r, &storage);
447 if (canvas->quickReject(fastR, ...)) {
448 // don't draw the path
449 }
450 }
451 */
reed@android.comd252db02009-04-01 18:31:44 +0000452 const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const {
453 return this->getStyle() == kFill_Style ? orig :
454 this->computeStrokeFastBounds(orig, storage);
455 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000456
457 /** Get the paint's shader object.
458 <p />
459 The shader's reference count is not affected.
460 @return the paint's shader (or NULL)
461 */
462 SkShader* getShader() const { return fShader; }
463
464 /** Set or clear the shader object.
465 <p />
466 Pass NULL to clear any previous shader.
467 As a convenience, the parameter passed is also returned.
468 If a previous shader exists, its reference count is decremented.
469 If shader is not NULL, its reference count is incremented.
470 @param shader May be NULL. The shader to be installed in the paint
471 @return shader
472 */
473 SkShader* setShader(SkShader* shader);
reed@google.com9d07fec2011-03-16 20:02:59 +0000474
reed@android.com8a1c16f2008-12-17 15:59:43 +0000475 /** Get the paint's colorfilter. If there is a colorfilter, its reference
476 count is not changed.
477 @return the paint's colorfilter (or NULL)
478 */
479 SkColorFilter* getColorFilter() const { return fColorFilter; }
480
481 /** Set or clear the paint's colorfilter, returning the parameter.
482 <p />
483 If the paint already has a filter, its reference count is decremented.
484 If filter is not NULL, its reference count is incremented.
485 @param filter May be NULL. The filter to be installed in the paint
486 @return filter
487 */
488 SkColorFilter* setColorFilter(SkColorFilter* filter);
489
490 /** Get the paint's xfermode object.
491 <p />
492 The xfermode's reference count is not affected.
493 @return the paint's xfermode (or NULL)
494 */
495 SkXfermode* getXfermode() const { return fXfermode; }
496
497 /** Set or clear the xfermode object.
498 <p />
499 Pass NULL to clear any previous xfermode.
500 As a convenience, the parameter passed is also returned.
501 If a previous xfermode exists, its reference count is decremented.
502 If xfermode is not NULL, its reference count is incremented.
503 @param xfermode May be NULL. The new xfermode to be installed in the
504 paint
505 @return xfermode
506 */
507 SkXfermode* setXfermode(SkXfermode* xfermode);
reed@android.coma0f5d152009-06-22 17:38:10 +0000508
509 /** Create an xfermode based on the specified Mode, and assign it into the
510 paint, returning the mode that was set. If the Mode is SrcOver, then
511 the paint's xfermode is set to null.
512 */
reed@android.com0baf1932009-06-24 12:41:42 +0000513 SkXfermode* setXfermodeMode(SkXfermode::Mode);
reed@android.coma0f5d152009-06-22 17:38:10 +0000514
reed@android.com8a1c16f2008-12-17 15:59:43 +0000515 /** Get the paint's patheffect object.
516 <p />
517 The patheffect reference count is not affected.
518 @return the paint's patheffect (or NULL)
519 */
520 SkPathEffect* getPathEffect() const { return fPathEffect; }
521
522 /** Set or clear the patheffect object.
523 <p />
524 Pass NULL to clear any previous patheffect.
525 As a convenience, the parameter passed is also returned.
526 If a previous patheffect exists, its reference count is decremented.
527 If patheffect is not NULL, its reference count is incremented.
528 @param effect May be NULL. The new patheffect to be installed in the
529 paint
530 @return effect
531 */
532 SkPathEffect* setPathEffect(SkPathEffect* effect);
533
534 /** Get the paint's maskfilter object.
535 <p />
536 The maskfilter reference count is not affected.
537 @return the paint's maskfilter (or NULL)
538 */
539 SkMaskFilter* getMaskFilter() const { return fMaskFilter; }
540
541 /** Set or clear the maskfilter object.
542 <p />
543 Pass NULL to clear any previous maskfilter.
544 As a convenience, the parameter passed is also returned.
545 If a previous maskfilter exists, its reference count is decremented.
546 If maskfilter is not NULL, its reference count is incremented.
547 @param maskfilter May be NULL. The new maskfilter to be installed in
548 the paint
549 @return maskfilter
550 */
551 SkMaskFilter* setMaskFilter(SkMaskFilter* maskfilter);
552
553 // These attributes are for text/fonts
554
555 /** Get the paint's typeface object.
556 <p />
557 The typeface object identifies which font to use when drawing or
558 measuring text. The typeface reference count is not affected.
559 @return the paint's typeface (or NULL)
560 */
561 SkTypeface* getTypeface() const { return fTypeface; }
562
563 /** Set or clear the typeface object.
564 <p />
565 Pass NULL to clear any previous typeface.
566 As a convenience, the parameter passed is also returned.
567 If a previous typeface exists, its reference count is decremented.
568 If typeface is not NULL, its reference count is incremented.
569 @param typeface May be NULL. The new typeface to be installed in the
570 paint
571 @return typeface
572 */
573 SkTypeface* setTypeface(SkTypeface* typeface);
574
575 /** Get the paint's rasterizer (or NULL).
576 <p />
577 The raster controls how paths/text are turned into alpha masks.
578 @return the paint's rasterizer (or NULL)
579 */
580 SkRasterizer* getRasterizer() const { return fRasterizer; }
581
582 /** Set or clear the rasterizer object.
583 <p />
584 Pass NULL to clear any previous rasterizer.
585 As a convenience, the parameter passed is also returned.
586 If a previous rasterizer exists in the paint, its reference count is
587 decremented. If rasterizer is not NULL, its reference count is
588 incremented.
589 @param rasterizer May be NULL. The new rasterizer to be installed in
590 the paint.
591 @return rasterizer
592 */
593 SkRasterizer* setRasterizer(SkRasterizer* rasterizer);
594
reed@google.com9d07fec2011-03-16 20:02:59 +0000595 /**
596 * Return the paint's SkDrawLooper (if any). Does not affect the looper's
597 * reference count.
598 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000599 SkDrawLooper* getLooper() const { return fLooper; }
reed@google.com9d07fec2011-03-16 20:02:59 +0000600
601 /**
602 * Set or clear the looper object.
603 * <p />
604 * Pass NULL to clear any previous looper.
605 * As a convenience, the parameter passed is also returned.
606 * If a previous looper exists in the paint, its reference count is
607 * decremented. If looper is not NULL, its reference count is
608 * incremented.
609 * @param looper May be NULL. The new looper to be installed in the paint.
610 * @return looper
611 */
612 SkDrawLooper* setLooper(SkDrawLooper* looper);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000613
614 enum Align {
615 kLeft_Align,
616 kCenter_Align,
617 kRight_Align,
618
619 kAlignCount
620 };
reed@google.com9d07fec2011-03-16 20:02:59 +0000621
reed@android.com8a1c16f2008-12-17 15:59:43 +0000622 /** Return the paint's Align value for drawing text.
623 @return the paint's Align value for drawing text.
624 */
625 Align getTextAlign() const { return (Align)fTextAlign; }
reed@google.com9d07fec2011-03-16 20:02:59 +0000626
reed@android.com8a1c16f2008-12-17 15:59:43 +0000627 /** Set the paint's text alignment.
628 @param align set the paint's Align value for drawing text.
629 */
630 void setTextAlign(Align align);
631
632 /** Return the paint's text size.
633 @return the paint's text size.
634 */
635 SkScalar getTextSize() const { return fTextSize; }
636
637 /** Set the paint's text size. This value must be > 0
638 @param textSize set the paint's text size.
639 */
640 void setTextSize(SkScalar textSize);
641
642 /** Return the paint's horizontal scale factor for text. The default value
643 is 1.0.
644 @return the paint's scale factor in X for drawing/measuring text
645 */
646 SkScalar getTextScaleX() const { return fTextScaleX; }
647
648 /** Set the paint's horizontal scale factor for text. The default value
649 is 1.0. Values > 1.0 will stretch the text wider. Values < 1.0 will
650 stretch the text narrower.
651 @param scaleX set the paint's scale factor in X for drawing/measuring
652 text.
653 */
654 void setTextScaleX(SkScalar scaleX);
655
656 /** Return the paint's horizontal skew factor for text. The default value
657 is 0.
658 @return the paint's skew factor in X for drawing text.
659 */
660 SkScalar getTextSkewX() const { return fTextSkewX; }
661
662 /** Set the paint's horizontal skew factor for text. The default value
663 is 0. For approximating oblique text, use values around -0.25.
664 @param skewX set the paint's skew factor in X for drawing text.
665 */
666 void setTextSkewX(SkScalar skewX);
667
668 /** Describes how to interpret the text parameters that are passed to paint
669 methods like measureText() and getTextWidths().
670 */
671 enum TextEncoding {
672 kUTF8_TextEncoding, //!< the text parameters are UTF8
673 kUTF16_TextEncoding, //!< the text parameters are UTF16
674 kGlyphID_TextEncoding //!< the text parameters are glyph indices
675 };
reed@google.com9d07fec2011-03-16 20:02:59 +0000676
677 TextEncoding getTextEncoding() const { return (TextEncoding)fTextEncoding; }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000678
679 void setTextEncoding(TextEncoding encoding);
680
681 struct FontMetrics {
682 SkScalar fTop; //!< The greatest distance above the baseline for any glyph (will be <= 0)
683 SkScalar fAscent; //!< The recommended distance above the baseline (will be <= 0)
684 SkScalar fDescent; //!< The recommended distance below the baseline (will be >= 0)
685 SkScalar fBottom; //!< The greatest distance below the baseline for any glyph (will be >= 0)
686 SkScalar fLeading; //!< The recommended distance to add between lines of text (will be >= 0)
agl@chromium.orgcc3096b2009-04-22 22:09:04 +0000687 SkScalar fAvgCharWidth; //!< the average charactor width (>= 0)
688 SkScalar fXMin; //!< The minimum bounding box x value for all glyphs
689 SkScalar fXMax; //!< The maximum bounding box x value for all glyphs
690 SkScalar fXHeight; //!< the height of an 'x' in px, or 0 if no 'x' in face
reed@android.com8a1c16f2008-12-17 15:59:43 +0000691 };
reed@google.com9d07fec2011-03-16 20:02:59 +0000692
reed@android.com8a1c16f2008-12-17 15:59:43 +0000693 /** Return the recommend spacing between lines (which will be
694 fDescent - fAscent + fLeading).
695 If metrics is not null, return in it the font metrics for the
reed@google.com9d07fec2011-03-16 20:02:59 +0000696 typeface/pointsize/etc. currently set in the paint.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000697 @param metrics If not null, returns the font metrics for the
698 current typeface/pointsize/etc setting in this
699 paint.
700 @param scale If not 0, return width as if the canvas were scaled
701 by this value
702 @param return the recommended spacing between lines
703 */
704 SkScalar getFontMetrics(FontMetrics* metrics, SkScalar scale = 0) const;
reed@google.com9d07fec2011-03-16 20:02:59 +0000705
reed@android.com8a1c16f2008-12-17 15:59:43 +0000706 /** Return the recommend line spacing. This will be
707 fDescent - fAscent + fLeading
708 */
709 SkScalar getFontSpacing() const { return this->getFontMetrics(NULL, 0); }
710
711 /** Convert the specified text into glyph IDs, returning the number of
712 glyphs ID written. If glyphs is NULL, it is ignore and only the count
713 is returned.
714 */
715 int textToGlyphs(const void* text, size_t byteLength,
716 uint16_t glyphs[]) const;
717
reed@android.coma5dcaf62010-02-05 17:12:32 +0000718 /** Return true if all of the specified text has a corresponding non-zero
719 glyph ID. If any of the code-points in the text are not supported in
720 the typeface (i.e. the glyph ID would be zero), then return false.
721
722 If the text encoding for the paint is kGlyph_TextEncoding, then this
723 returns true if all of the specified glyph IDs are non-zero.
724 */
725 bool containsText(const void* text, size_t byteLength) const;
726
reed@android.com9d3a9852010-01-08 14:07:42 +0000727 /** Convert the glyph array into Unichars. Unconvertable glyphs are mapped
728 to zero. Note: this does not look at the text-encoding setting in the
729 paint, only at the typeface.
730 */
731 void glyphsToUnichars(const uint16_t glyphs[], int count,
732 SkUnichar text[]) const;
733
reed@android.com8a1c16f2008-12-17 15:59:43 +0000734 /** Return the number of drawable units in the specified text buffer.
735 This looks at the current TextEncoding field of the paint. If you also
736 want to have the text converted into glyph IDs, call textToGlyphs
737 instead.
738 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000739 int countText(const void* text, size_t byteLength) const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000740 return this->textToGlyphs(text, byteLength, NULL);
741 }
742
743 /** Return the width of the text.
744 @param text The text to be measured
745 @param length Number of bytes of text to measure
746 @param bounds If not NULL, returns the bounds of the text,
747 relative to (0, 0).
748 @param scale If not 0, return width as if the canvas were scaled
749 by this value
750 @return The advance width of the text
751 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000752 SkScalar measureText(const void* text, size_t length,
753 SkRect* bounds, SkScalar scale = 0) const;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000754
755 /** Return the width of the text.
756 @param text Address of the text
757 @param length Number of bytes of text to measure
758 @return The width of the text
759 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000760 SkScalar measureText(const void* text, size_t length) const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000761 return this->measureText(text, length, NULL, 0);
762 }
reed@google.com9d07fec2011-03-16 20:02:59 +0000763
reed@android.com8a1c16f2008-12-17 15:59:43 +0000764 /** Specify the direction the text buffer should be processed in breakText()
765 */
766 enum TextBufferDirection {
767 /** When measuring text for breakText(), begin at the start of the text
768 buffer and proceed forward through the data. This is the default.
769 */
770 kForward_TextBufferDirection,
771 /** When measuring text for breakText(), begin at the end of the text
772 buffer and proceed backwards through the data.
773 */
774 kBackward_TextBufferDirection
775 };
776
777 /** Return the width of the text.
778 @param text The text to be measured
779 @param length Number of bytes of text to measure
780 @param maxWidth Maximum width. Only the subset of text whose accumulated
781 widths are <= maxWidth are measured.
782 @param measuredWidth Optional. If non-null, this returns the actual
783 width of the measured text.
784 @param tbd Optional. The direction the text buffer should be
785 traversed during measuring.
786 @return The number of bytes of text that were measured. Will be
787 <= length.
788 */
789 size_t breakText(const void* text, size_t length, SkScalar maxWidth,
790 SkScalar* measuredWidth = NULL,
791 TextBufferDirection tbd = kForward_TextBufferDirection)
792 const;
793
794 /** Return the advance widths for the characters in the string.
795 @param text the text
796 @param byteLength number of bytes to of text
797 @param widths If not null, returns the array of advance widths of
798 the glyphs. If not NULL, must be at least a large
799 as the number of unichars in the specified text.
800 @param bounds If not null, returns the bounds for each of
801 character, relative to (0, 0)
802 @return the number of unichars in the specified text.
803 */
804 int getTextWidths(const void* text, size_t byteLength, SkScalar widths[],
805 SkRect bounds[] = NULL) const;
806
807 /** Return the path (outline) for the specified text.
808 Note: just like SkCanvas::drawText, this will respect the Align setting
809 in the paint.
810 */
811 void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y,
812 SkPath* path) const;
813
djsollen@google.comf5dbe2f2011-04-15 13:41:26 +0000814#ifdef ANDROID
815 const SkGlyph& getUnicharMetrics(SkUnichar);
816 const void* findImage(const SkGlyph&);
817
818 uint32_t getGenerationID() const;
819#endif
820
reed@android.com8a1c16f2008-12-17 15:59:43 +0000821private:
822 SkTypeface* fTypeface;
823 SkScalar fTextSize;
824 SkScalar fTextScaleX;
825 SkScalar fTextSkewX;
826
827 SkPathEffect* fPathEffect;
828 SkShader* fShader;
829 SkXfermode* fXfermode;
830 SkMaskFilter* fMaskFilter;
831 SkColorFilter* fColorFilter;
832 SkRasterizer* fRasterizer;
833 SkDrawLooper* fLooper;
834
835 SkColor fColor;
836 SkScalar fWidth;
837 SkScalar fMiterLimit;
agl@chromium.orga2c71cb2010-06-17 20:49:17 +0000838 unsigned fFlags : 12;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000839 unsigned fTextAlign : 2;
840 unsigned fCapType : 2;
841 unsigned fJoinType : 2;
842 unsigned fStyle : 2;
843 unsigned fTextEncoding : 2; // 3 values
agl@chromium.org309485b2009-07-21 17:41:32 +0000844 unsigned fHinting : 2;
djsollen@google.comf5dbe2f2011-04-15 13:41:26 +0000845#ifdef ANDROID
846 uint32_t fGenerationID;
847#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000848
849 SkDrawCacheProc getDrawCacheProc() const;
850 SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir,
851 bool needFullMetrics) const;
852
853 SkScalar measure_text(SkGlyphCache*, const char* text, size_t length,
854 int* count, SkRect* bounds) const;
855
856 SkGlyphCache* detachCache(const SkMatrix*) const;
857
858 void descriptorProc(const SkMatrix* deviceMatrix,
859 void (*proc)(const SkDescriptor*, void*),
djsollen@google.com57f49692011-02-23 20:46:31 +0000860 void* context, bool ignoreGamma = false) const;
reed@android.comd252db02009-04-01 18:31:44 +0000861
862 const SkRect& computeStrokeFastBounds(const SkRect& orig,
863 SkRect* storage) const;
864
reed@android.com8a1c16f2008-12-17 15:59:43 +0000865 enum {
866 kCanonicalTextSizeForPaths = 64
867 };
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000868 friend class SkAutoGlyphCache;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000869 friend class SkCanvas;
870 friend class SkDraw;
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000871 friend class SkPDFDevice;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000872 friend class SkTextToPathIter;
873};
874
reed@google.com6bac9472011-06-21 19:24:00 +0000875///////////////////////////////////////////////////////////////////////////////
reed@android.com8a1c16f2008-12-17 15:59:43 +0000876
877#include "SkPathEffect.h"
878
879/** \class SkStrokePathEffect
880
881 SkStrokePathEffect simulates stroking inside a patheffect, allowing the
882 caller to have explicit control of when to stroke a path. Typically this is
883 used if the caller wants to stroke before another patheffect is applied
884 (using SkComposePathEffect or SkSumPathEffect).
885*/
886class SkStrokePathEffect : public SkPathEffect {
887public:
888 SkStrokePathEffect(const SkPaint&);
889 SkStrokePathEffect(SkScalar width, SkPaint::Style, SkPaint::Join,
890 SkPaint::Cap, SkScalar miterLimit = -1);
891
892 // overrides
reed@android.com8a1c16f2008-12-17 15:59:43 +0000893 virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
894
895 // overrides for SkFlattenable
reed@android.com8a1c16f2008-12-17 15:59:43 +0000896 virtual void flatten(SkFlattenableWriteBuffer&);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000897 virtual Factory getFactory();
898
reed@google.com6bac9472011-06-21 19:24:00 +0000899 static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
900
reed@android.com8a1c16f2008-12-17 15:59:43 +0000901private:
902 SkScalar fWidth, fMiter;
903 uint8_t fStyle, fJoin, fCap;
904
reed@android.com8a1c16f2008-12-17 15:59:43 +0000905 SkStrokePathEffect(SkFlattenableReadBuffer&);
906
907 typedef SkPathEffect INHERITED;
908
909 // illegal
910 SkStrokePathEffect(const SkStrokePathEffect&);
911 SkStrokePathEffect& operator=(const SkStrokePathEffect&);
912};
913
914#endif
915