blob: f4b325fea58d930e872b45ce11c71190a66ff8cc [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SkPaint_DEFINED
18#define SkPaint_DEFINED
19
20#include "SkColor.h"
21#include "SkMath.h"
reed@android.coma0f5d152009-06-22 17:38:10 +000022#include "SkXfermode.h"
23
reed@android.com8a1c16f2008-12-17 15:59:43 +000024class SkAutoGlyphCache;
25class SkColorFilter;
26class SkDescriptor;
27class SkFlattenableReadBuffer;
28class SkFlattenableWriteBuffer;
29struct SkGlyph;
30struct SkRect;
31class SkGlyphCache;
32class SkMaskFilter;
33class SkMatrix;
34class SkPath;
35class SkPathEffect;
36class SkRasterizer;
37class SkShader;
38class SkDrawLooper;
39class SkTypeface;
reed@android.com8a1c16f2008-12-17 15:59:43 +000040
41typedef const SkGlyph& (*SkDrawCacheProc)(SkGlyphCache*, const char**,
42 SkFixed x, SkFixed y);
43
44typedef const SkGlyph& (*SkMeasureCacheProc)(SkGlyphCache*, const char**);
45
46/** \class SkPaint
47
48 The SkPaint class holds the style and color information about how to draw
49 geometries, text and bitmaps.
50*/
ctguil@chromium.org7ffb1b22011-03-15 21:27:08 +000051class SK_API SkPaint {
reed@android.com8a1c16f2008-12-17 15:59:43 +000052public:
53 SkPaint();
54 SkPaint(const SkPaint& paint);
55 ~SkPaint();
56
57 SkPaint& operator=(const SkPaint&);
58
ctguil@chromium.org7ffb1b22011-03-15 21:27:08 +000059 SK_API friend int operator==(const SkPaint& a, const SkPaint& b);
reed@google.com9d07fec2011-03-16 20:02:59 +000060 friend int operator!=(const SkPaint& a, const SkPaint& b) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000061 return !(a == b);
62 }
reed@google.com9d07fec2011-03-16 20:02:59 +000063
reed@android.com8a1c16f2008-12-17 15:59:43 +000064 void flatten(SkFlattenableWriteBuffer&) const;
65 void unflatten(SkFlattenableReadBuffer&);
66
67 /** Restores the paint to its initial settings.
68 */
69 void reset();
70
agl@chromium.org309485b2009-07-21 17:41:32 +000071 /** Specifies the level of hinting to be performed. These names are taken
72 from the Gnome/Cairo names for the same. They are translated into
73 Freetype concepts the same as in cairo-ft-font.c:
74 kNo_Hinting -> FT_LOAD_NO_HINTING
75 kSlight_Hinting -> FT_LOAD_TARGET_LIGHT
76 kNormal_Hinting -> <default, no option>
77 kFull_Hinting -> <same as kNormalHinting, unless we are rendering
78 subpixel glyphs, in which case TARGET_LCD or
79 TARGET_LCD_V is used>
80 */
81 enum Hinting {
82 kNo_Hinting = 0,
83 kSlight_Hinting = 1,
84 kNormal_Hinting = 2, //!< this is the default
85 kFull_Hinting = 3,
86 };
87
reed@google.com9d07fec2011-03-16 20:02:59 +000088 Hinting getHinting() const {
agl@chromium.org309485b2009-07-21 17:41:32 +000089 return static_cast<Hinting>(fHinting);
90 }
91
djsollen@google.comf5dbe2f2011-04-15 13:41:26 +000092 void setHinting(Hinting hintingLevel);
agl@chromium.org309485b2009-07-21 17:41:32 +000093
reed@android.com8a1c16f2008-12-17 15:59:43 +000094 /** Specifies the bit values that are stored in the paint's flags.
95 */
96 enum Flags {
97 kAntiAlias_Flag = 0x01, //!< mask to enable antialiasing
98 kFilterBitmap_Flag = 0x02, //!< mask to enable bitmap filtering
99 kDither_Flag = 0x04, //!< mask to enable dithering
100 kUnderlineText_Flag = 0x08, //!< mask to enable underline text
101 kStrikeThruText_Flag = 0x10, //!< mask to enable strike-thru text
102 kFakeBoldText_Flag = 0x20, //!< mask to enable fake-bold text
103 kLinearText_Flag = 0x40, //!< mask to enable linear-text
agl@chromium.org309485b2009-07-21 17:41:32 +0000104 kSubpixelText_Flag = 0x80, //!< mask to enable subpixel text positioning
reed@android.com8a1c16f2008-12-17 15:59:43 +0000105 kDevKernText_Flag = 0x100, //!< mask to enable device kerning text
agl@chromium.org309485b2009-07-21 17:41:32 +0000106 kLCDRenderText_Flag = 0x200, //!< mask to enable subpixel glyph renderering
agl@chromium.orge95c91e2010-01-04 18:27:55 +0000107 kEmbeddedBitmapText_Flag = 0x400, //!< mask to enable embedded bitmap strikes
agl@chromium.orga2c71cb2010-06-17 20:49:17 +0000108 kAutoHinting_Flag = 0x800, //!< mask to force Freetype's autohinter
agl@chromium.org309485b2009-07-21 17:41:32 +0000109 // when adding extra flags, note that the fFlags member is specified
110 // with a bit-width and you'll have to expand it.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000111
agl@chromium.orga2c71cb2010-06-17 20:49:17 +0000112 kAllFlags = 0xFFF
reed@android.com8a1c16f2008-12-17 15:59:43 +0000113 };
114
115 /** Return the paint's flags. Use the Flag enum to test flag values.
116 @return the paint's flags (see enums ending in _Flag for bit masks)
117 */
118 uint32_t getFlags() const { return fFlags; }
119
120 /** Set the paint's flags. Use the Flag enum to specific flag values.
121 @param flags The new flag bits for the paint (see Flags enum)
122 */
123 void setFlags(uint32_t flags);
124
125 /** Helper for getFlags(), returning true if kAntiAlias_Flag bit is set
126 @return true if the antialias bit is set in the paint's flags.
127 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000128 bool isAntiAlias() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000129 return SkToBool(this->getFlags() & kAntiAlias_Flag);
130 }
reed@google.com9d07fec2011-03-16 20:02:59 +0000131
reed@android.com8a1c16f2008-12-17 15:59:43 +0000132 /** Helper for setFlags(), setting or clearing the kAntiAlias_Flag bit
133 @param aa true to enable antialiasing, false to disable it
134 */
135 void setAntiAlias(bool aa);
reed@google.com9d07fec2011-03-16 20:02:59 +0000136
reed@android.com8a1c16f2008-12-17 15:59:43 +0000137 /** Helper for getFlags(), returning true if kDither_Flag bit is set
138 @return true if the dithering bit is set in the paint's flags.
139 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000140 bool isDither() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000141 return SkToBool(this->getFlags() & kDither_Flag);
142 }
reed@google.com9d07fec2011-03-16 20:02:59 +0000143
reed@android.com8a1c16f2008-12-17 15:59:43 +0000144 /** Helper for setFlags(), setting or clearing the kDither_Flag bit
145 @param dither true to enable dithering, false to disable it
146 */
147 void setDither(bool dither);
reed@google.com9d07fec2011-03-16 20:02:59 +0000148
reed@android.com8a1c16f2008-12-17 15:59:43 +0000149 /** Helper for getFlags(), returning true if kLinearText_Flag bit is set
150 @return true if the lineartext bit is set in the paint's flags
151 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000152 bool isLinearText() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000153 return SkToBool(this->getFlags() & kLinearText_Flag);
154 }
155
156 /** Helper for setFlags(), setting or clearing the kLinearText_Flag bit
157 @param linearText true to set the linearText bit in the paint's flags,
158 false to clear it.
159 */
160 void setLinearText(bool linearText);
161
162 /** Helper for getFlags(), returning true if kSubpixelText_Flag bit is set
163 @return true if the lineartext bit is set in the paint's flags
164 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000165 bool isSubpixelText() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000166 return SkToBool(this->getFlags() & kSubpixelText_Flag);
167 }
reed@google.com9d07fec2011-03-16 20:02:59 +0000168
agl@chromium.org309485b2009-07-21 17:41:32 +0000169 /** Helper for setFlags(), setting or clearing the kSubpixelText_Flag
170 bit @param subpixelText true to set the subpixelText bit in the paint's flags,
171 false to clear it.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000172 */
173 void setSubpixelText(bool subpixelText);
agl@chromium.org309485b2009-07-21 17:41:32 +0000174
reed@google.com9d07fec2011-03-16 20:02:59 +0000175 bool isLCDRenderText() const {
agl@chromium.org309485b2009-07-21 17:41:32 +0000176 return SkToBool(this->getFlags() & kLCDRenderText_Flag);
177 }
178
179 /** Helper for setFlags(), setting or clearing the kLCDRenderText_Flag bit
180 @param subpixelRender true to set the subpixelRenderText bit in the paint's flags,
181 false to clear it.
182 */
183 void setLCDRenderText(bool subpixelRender);
184
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.com9d07fec2011-03-16 20:02:59 +0000599 /**
600 * Return the paint's SkDrawLooper (if any). Does not affect the looper's
601 * reference count.
602 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000603 SkDrawLooper* getLooper() const { return fLooper; }
reed@google.com9d07fec2011-03-16 20:02:59 +0000604
605 /**
606 * Set or clear the looper object.
607 * <p />
608 * Pass NULL to clear any previous looper.
609 * As a convenience, the parameter passed is also returned.
610 * If a previous looper exists in the paint, its reference count is
611 * decremented. If looper is not NULL, its reference count is
612 * incremented.
613 * @param looper May be NULL. The new looper to be installed in the paint.
614 * @return looper
615 */
616 SkDrawLooper* setLooper(SkDrawLooper* looper);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000617
618 enum Align {
619 kLeft_Align,
620 kCenter_Align,
621 kRight_Align,
622
623 kAlignCount
624 };
reed@google.com9d07fec2011-03-16 20:02:59 +0000625
reed@android.com8a1c16f2008-12-17 15:59:43 +0000626 /** Return the paint's Align value for drawing text.
627 @return the paint's Align value for drawing text.
628 */
629 Align getTextAlign() const { return (Align)fTextAlign; }
reed@google.com9d07fec2011-03-16 20:02:59 +0000630
reed@android.com8a1c16f2008-12-17 15:59:43 +0000631 /** Set the paint's text alignment.
632 @param align set the paint's Align value for drawing text.
633 */
634 void setTextAlign(Align align);
635
636 /** Return the paint's text size.
637 @return the paint's text size.
638 */
639 SkScalar getTextSize() const { return fTextSize; }
640
641 /** Set the paint's text size. This value must be > 0
642 @param textSize set the paint's text size.
643 */
644 void setTextSize(SkScalar textSize);
645
646 /** Return the paint's horizontal scale factor for text. The default value
647 is 1.0.
648 @return the paint's scale factor in X for drawing/measuring text
649 */
650 SkScalar getTextScaleX() const { return fTextScaleX; }
651
652 /** Set the paint's horizontal scale factor for text. The default value
653 is 1.0. Values > 1.0 will stretch the text wider. Values < 1.0 will
654 stretch the text narrower.
655 @param scaleX set the paint's scale factor in X for drawing/measuring
656 text.
657 */
658 void setTextScaleX(SkScalar scaleX);
659
660 /** Return the paint's horizontal skew factor for text. The default value
661 is 0.
662 @return the paint's skew factor in X for drawing text.
663 */
664 SkScalar getTextSkewX() const { return fTextSkewX; }
665
666 /** Set the paint's horizontal skew factor for text. The default value
667 is 0. For approximating oblique text, use values around -0.25.
668 @param skewX set the paint's skew factor in X for drawing text.
669 */
670 void setTextSkewX(SkScalar skewX);
671
672 /** Describes how to interpret the text parameters that are passed to paint
673 methods like measureText() and getTextWidths().
674 */
675 enum TextEncoding {
676 kUTF8_TextEncoding, //!< the text parameters are UTF8
677 kUTF16_TextEncoding, //!< the text parameters are UTF16
678 kGlyphID_TextEncoding //!< the text parameters are glyph indices
679 };
reed@google.com9d07fec2011-03-16 20:02:59 +0000680
681 TextEncoding getTextEncoding() const { return (TextEncoding)fTextEncoding; }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000682
683 void setTextEncoding(TextEncoding encoding);
684
685 struct FontMetrics {
686 SkScalar fTop; //!< The greatest distance above the baseline for any glyph (will be <= 0)
687 SkScalar fAscent; //!< The recommended distance above the baseline (will be <= 0)
688 SkScalar fDescent; //!< The recommended distance below the baseline (will be >= 0)
689 SkScalar fBottom; //!< The greatest distance below the baseline for any glyph (will be >= 0)
690 SkScalar fLeading; //!< The recommended distance to add between lines of text (will be >= 0)
agl@chromium.orgcc3096b2009-04-22 22:09:04 +0000691 SkScalar fAvgCharWidth; //!< the average charactor width (>= 0)
692 SkScalar fXMin; //!< The minimum bounding box x value for all glyphs
693 SkScalar fXMax; //!< The maximum bounding box x value for all glyphs
694 SkScalar fXHeight; //!< the height of an 'x' in px, or 0 if no 'x' in face
reed@android.com8a1c16f2008-12-17 15:59:43 +0000695 };
reed@google.com9d07fec2011-03-16 20:02:59 +0000696
reed@android.com8a1c16f2008-12-17 15:59:43 +0000697 /** Return the recommend spacing between lines (which will be
698 fDescent - fAscent + fLeading).
699 If metrics is not null, return in it the font metrics for the
reed@google.com9d07fec2011-03-16 20:02:59 +0000700 typeface/pointsize/etc. currently set in the paint.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000701 @param metrics If not null, returns the font metrics for the
702 current typeface/pointsize/etc setting in this
703 paint.
704 @param scale If not 0, return width as if the canvas were scaled
705 by this value
706 @param return the recommended spacing between lines
707 */
708 SkScalar getFontMetrics(FontMetrics* metrics, SkScalar scale = 0) const;
reed@google.com9d07fec2011-03-16 20:02:59 +0000709
reed@android.com8a1c16f2008-12-17 15:59:43 +0000710 /** Return the recommend line spacing. This will be
711 fDescent - fAscent + fLeading
712 */
713 SkScalar getFontSpacing() const { return this->getFontMetrics(NULL, 0); }
714
715 /** Convert the specified text into glyph IDs, returning the number of
716 glyphs ID written. If glyphs is NULL, it is ignore and only the count
717 is returned.
718 */
719 int textToGlyphs(const void* text, size_t byteLength,
720 uint16_t glyphs[]) const;
721
reed@android.coma5dcaf62010-02-05 17:12:32 +0000722 /** Return true if all of the specified text has a corresponding non-zero
723 glyph ID. If any of the code-points in the text are not supported in
724 the typeface (i.e. the glyph ID would be zero), then return false.
725
726 If the text encoding for the paint is kGlyph_TextEncoding, then this
727 returns true if all of the specified glyph IDs are non-zero.
728 */
729 bool containsText(const void* text, size_t byteLength) const;
730
reed@android.com9d3a9852010-01-08 14:07:42 +0000731 /** Convert the glyph array into Unichars. Unconvertable glyphs are mapped
732 to zero. Note: this does not look at the text-encoding setting in the
733 paint, only at the typeface.
734 */
735 void glyphsToUnichars(const uint16_t glyphs[], int count,
736 SkUnichar text[]) const;
737
reed@android.com8a1c16f2008-12-17 15:59:43 +0000738 /** Return the number of drawable units in the specified text buffer.
739 This looks at the current TextEncoding field of the paint. If you also
740 want to have the text converted into glyph IDs, call textToGlyphs
741 instead.
742 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000743 int countText(const void* text, size_t byteLength) const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000744 return this->textToGlyphs(text, byteLength, NULL);
745 }
746
747 /** Return the width of the text.
748 @param text The text to be measured
749 @param length Number of bytes of text to measure
750 @param bounds If not NULL, returns the bounds of the text,
751 relative to (0, 0).
752 @param scale If not 0, return width as if the canvas were scaled
753 by this value
754 @return The advance width of the text
755 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000756 SkScalar measureText(const void* text, size_t length,
757 SkRect* bounds, SkScalar scale = 0) const;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000758
759 /** Return the width of the text.
760 @param text Address of the text
761 @param length Number of bytes of text to measure
762 @return The width of the text
763 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000764 SkScalar measureText(const void* text, size_t length) const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000765 return this->measureText(text, length, NULL, 0);
766 }
reed@google.com9d07fec2011-03-16 20:02:59 +0000767
reed@android.com8a1c16f2008-12-17 15:59:43 +0000768 /** Specify the direction the text buffer should be processed in breakText()
769 */
770 enum TextBufferDirection {
771 /** When measuring text for breakText(), begin at the start of the text
772 buffer and proceed forward through the data. This is the default.
773 */
774 kForward_TextBufferDirection,
775 /** When measuring text for breakText(), begin at the end of the text
776 buffer and proceed backwards through the data.
777 */
778 kBackward_TextBufferDirection
779 };
780
781 /** Return the width of the text.
782 @param text The text to be measured
783 @param length Number of bytes of text to measure
784 @param maxWidth Maximum width. Only the subset of text whose accumulated
785 widths are <= maxWidth are measured.
786 @param measuredWidth Optional. If non-null, this returns the actual
787 width of the measured text.
788 @param tbd Optional. The direction the text buffer should be
789 traversed during measuring.
790 @return The number of bytes of text that were measured. Will be
791 <= length.
792 */
793 size_t breakText(const void* text, size_t length, SkScalar maxWidth,
794 SkScalar* measuredWidth = NULL,
795 TextBufferDirection tbd = kForward_TextBufferDirection)
796 const;
797
798 /** Return the advance widths for the characters in the string.
799 @param text the text
800 @param byteLength number of bytes to of text
801 @param widths If not null, returns the array of advance widths of
802 the glyphs. If not NULL, must be at least a large
803 as the number of unichars in the specified text.
804 @param bounds If not null, returns the bounds for each of
805 character, relative to (0, 0)
806 @return the number of unichars in the specified text.
807 */
808 int getTextWidths(const void* text, size_t byteLength, SkScalar widths[],
809 SkRect bounds[] = NULL) const;
810
811 /** Return the path (outline) for the specified text.
812 Note: just like SkCanvas::drawText, this will respect the Align setting
813 in the paint.
814 */
815 void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y,
816 SkPath* path) const;
817
djsollen@google.comf5dbe2f2011-04-15 13:41:26 +0000818#ifdef ANDROID
819 const SkGlyph& getUnicharMetrics(SkUnichar);
820 const void* findImage(const SkGlyph&);
821
822 uint32_t getGenerationID() const;
823#endif
824
reed@android.com8a1c16f2008-12-17 15:59:43 +0000825private:
826 SkTypeface* fTypeface;
827 SkScalar fTextSize;
828 SkScalar fTextScaleX;
829 SkScalar fTextSkewX;
830
831 SkPathEffect* fPathEffect;
832 SkShader* fShader;
833 SkXfermode* fXfermode;
834 SkMaskFilter* fMaskFilter;
835 SkColorFilter* fColorFilter;
836 SkRasterizer* fRasterizer;
837 SkDrawLooper* fLooper;
838
839 SkColor fColor;
840 SkScalar fWidth;
841 SkScalar fMiterLimit;
agl@chromium.orga2c71cb2010-06-17 20:49:17 +0000842 unsigned fFlags : 12;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000843 unsigned fTextAlign : 2;
844 unsigned fCapType : 2;
845 unsigned fJoinType : 2;
846 unsigned fStyle : 2;
847 unsigned fTextEncoding : 2; // 3 values
agl@chromium.org309485b2009-07-21 17:41:32 +0000848 unsigned fHinting : 2;
djsollen@google.comf5dbe2f2011-04-15 13:41:26 +0000849#ifdef ANDROID
850 uint32_t fGenerationID;
851#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000852
853 SkDrawCacheProc getDrawCacheProc() const;
854 SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir,
855 bool needFullMetrics) const;
856
857 SkScalar measure_text(SkGlyphCache*, const char* text, size_t length,
858 int* count, SkRect* bounds) const;
859
860 SkGlyphCache* detachCache(const SkMatrix*) const;
861
862 void descriptorProc(const SkMatrix* deviceMatrix,
863 void (*proc)(const SkDescriptor*, void*),
djsollen@google.com57f49692011-02-23 20:46:31 +0000864 void* context, bool ignoreGamma = false) const;
reed@android.comd252db02009-04-01 18:31:44 +0000865
866 const SkRect& computeStrokeFastBounds(const SkRect& orig,
867 SkRect* storage) const;
868
reed@android.com8a1c16f2008-12-17 15:59:43 +0000869 enum {
870 kCanonicalTextSizeForPaths = 64
871 };
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000872 friend class SkAutoGlyphCache;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000873 friend class SkCanvas;
874 friend class SkDraw;
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000875 friend class SkPDFDevice;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000876 friend class SkTextToPathIter;
877};
878
879//////////////////////////////////////////////////////////////////////////
880
881#include "SkPathEffect.h"
882
883/** \class SkStrokePathEffect
884
885 SkStrokePathEffect simulates stroking inside a patheffect, allowing the
886 caller to have explicit control of when to stroke a path. Typically this is
887 used if the caller wants to stroke before another patheffect is applied
888 (using SkComposePathEffect or SkSumPathEffect).
889*/
890class SkStrokePathEffect : public SkPathEffect {
891public:
892 SkStrokePathEffect(const SkPaint&);
893 SkStrokePathEffect(SkScalar width, SkPaint::Style, SkPaint::Join,
894 SkPaint::Cap, SkScalar miterLimit = -1);
895
896 // overrides
897 // This method is not exported to java.
898 virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
899
900 // overrides for SkFlattenable
901 // This method is not exported to java.
902 virtual void flatten(SkFlattenableWriteBuffer&);
903 // This method is not exported to java.
904 virtual Factory getFactory();
905
906private:
907 SkScalar fWidth, fMiter;
908 uint8_t fStyle, fJoin, fCap;
909
910 static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
911 SkStrokePathEffect(SkFlattenableReadBuffer&);
912
913 typedef SkPathEffect INHERITED;
914
915 // illegal
916 SkStrokePathEffect(const SkStrokePathEffect&);
917 SkStrokePathEffect& operator=(const SkStrokePathEffect&);
918};
919
920#endif
921