blob: a931ccd96c1a98c27af09f363ed4d1ad35b025e6 [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
reed@google.com9d07fec2011-03-16 20:02:59 +000092 void setHinting(Hinting hintingLevel) {
agl@chromium.org309485b2009-07-21 17:41:32 +000093 fHinting = hintingLevel;
94 }
95
reed@android.com8a1c16f2008-12-17 15:59:43 +000096 /** Specifies the bit values that are stored in the paint's flags.
97 */
98 enum Flags {
99 kAntiAlias_Flag = 0x01, //!< mask to enable antialiasing
100 kFilterBitmap_Flag = 0x02, //!< mask to enable bitmap filtering
101 kDither_Flag = 0x04, //!< mask to enable dithering
102 kUnderlineText_Flag = 0x08, //!< mask to enable underline text
103 kStrikeThruText_Flag = 0x10, //!< mask to enable strike-thru text
104 kFakeBoldText_Flag = 0x20, //!< mask to enable fake-bold text
105 kLinearText_Flag = 0x40, //!< mask to enable linear-text
agl@chromium.org309485b2009-07-21 17:41:32 +0000106 kSubpixelText_Flag = 0x80, //!< mask to enable subpixel text positioning
reed@android.com8a1c16f2008-12-17 15:59:43 +0000107 kDevKernText_Flag = 0x100, //!< mask to enable device kerning text
agl@chromium.org309485b2009-07-21 17:41:32 +0000108 kLCDRenderText_Flag = 0x200, //!< mask to enable subpixel glyph renderering
agl@chromium.orge95c91e2010-01-04 18:27:55 +0000109 kEmbeddedBitmapText_Flag = 0x400, //!< mask to enable embedded bitmap strikes
agl@chromium.orga2c71cb2010-06-17 20:49:17 +0000110 kAutoHinting_Flag = 0x800, //!< mask to force Freetype's autohinter
agl@chromium.org309485b2009-07-21 17:41:32 +0000111 // when adding extra flags, note that the fFlags member is specified
112 // with a bit-width and you'll have to expand it.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000113
agl@chromium.orga2c71cb2010-06-17 20:49:17 +0000114 kAllFlags = 0xFFF
reed@android.com8a1c16f2008-12-17 15:59:43 +0000115 };
116
117 /** Return the paint's flags. Use the Flag enum to test flag values.
118 @return the paint's flags (see enums ending in _Flag for bit masks)
119 */
120 uint32_t getFlags() const { return fFlags; }
121
122 /** Set the paint's flags. Use the Flag enum to specific flag values.
123 @param flags The new flag bits for the paint (see Flags enum)
124 */
125 void setFlags(uint32_t flags);
126
127 /** Helper for getFlags(), returning true if kAntiAlias_Flag bit is set
128 @return true if the antialias bit is set in the paint's flags.
129 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000130 bool isAntiAlias() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000131 return SkToBool(this->getFlags() & kAntiAlias_Flag);
132 }
reed@google.com9d07fec2011-03-16 20:02:59 +0000133
reed@android.com8a1c16f2008-12-17 15:59:43 +0000134 /** Helper for setFlags(), setting or clearing the kAntiAlias_Flag bit
135 @param aa true to enable antialiasing, false to disable it
136 */
137 void setAntiAlias(bool aa);
reed@google.com9d07fec2011-03-16 20:02:59 +0000138
reed@android.com8a1c16f2008-12-17 15:59:43 +0000139 /** Helper for getFlags(), returning true if kDither_Flag bit is set
140 @return true if the dithering bit is set in the paint's flags.
141 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000142 bool isDither() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000143 return SkToBool(this->getFlags() & kDither_Flag);
144 }
reed@google.com9d07fec2011-03-16 20:02:59 +0000145
reed@android.com8a1c16f2008-12-17 15:59:43 +0000146 /** Helper for setFlags(), setting or clearing the kDither_Flag bit
147 @param dither true to enable dithering, false to disable it
148 */
149 void setDither(bool dither);
reed@google.com9d07fec2011-03-16 20:02:59 +0000150
reed@android.com8a1c16f2008-12-17 15:59:43 +0000151 /** Helper for getFlags(), returning true if kLinearText_Flag bit is set
152 @return true if the lineartext bit is set in the paint's flags
153 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000154 bool isLinearText() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000155 return SkToBool(this->getFlags() & kLinearText_Flag);
156 }
157
158 /** Helper for setFlags(), setting or clearing the kLinearText_Flag bit
159 @param linearText true to set the linearText bit in the paint's flags,
160 false to clear it.
161 */
162 void setLinearText(bool linearText);
163
164 /** Helper for getFlags(), returning true if kSubpixelText_Flag bit is set
165 @return true if the lineartext bit is set in the paint's flags
166 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000167 bool isSubpixelText() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000168 return SkToBool(this->getFlags() & kSubpixelText_Flag);
169 }
reed@google.com9d07fec2011-03-16 20:02:59 +0000170
agl@chromium.org309485b2009-07-21 17:41:32 +0000171 /** Helper for setFlags(), setting or clearing the kSubpixelText_Flag
172 bit @param subpixelText true to set the subpixelText bit in the paint's flags,
173 false to clear it.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000174 */
175 void setSubpixelText(bool subpixelText);
agl@chromium.org309485b2009-07-21 17:41:32 +0000176
reed@google.com9d07fec2011-03-16 20:02:59 +0000177 bool isLCDRenderText() const {
agl@chromium.org309485b2009-07-21 17:41:32 +0000178 return SkToBool(this->getFlags() & kLCDRenderText_Flag);
179 }
180
181 /** Helper for setFlags(), setting or clearing the kLCDRenderText_Flag bit
182 @param subpixelRender true to set the subpixelRenderText bit in the paint's flags,
183 false to clear it.
184 */
185 void setLCDRenderText(bool subpixelRender);
186
reed@google.com9d07fec2011-03-16 20:02:59 +0000187 bool isEmbeddedBitmapText() const {
agl@chromium.orge95c91e2010-01-04 18:27:55 +0000188 return SkToBool(this->getFlags() & kEmbeddedBitmapText_Flag);
189 }
190
191 /** Helper for setFlags(), setting or clearing the kEmbeddedBitmapText_Flag bit
192 @param useEmbeddedBitmapText true to set the kEmbeddedBitmapText bit in the paint's flags,
193 false to clear it.
194 */
195 void setEmbeddedBitmapText(bool useEmbeddedBitmapText);
196
reed@google.com9d07fec2011-03-16 20:02:59 +0000197 bool isAutohinted() const {
agl@chromium.orga2c71cb2010-06-17 20:49:17 +0000198 return SkToBool(this->getFlags() & kAutoHinting_Flag);
199 }
200
201 /** Helper for setFlags(), setting or clearing the kAutoHinting_Flag bit
202 @param useAutohinter true to set the kEmbeddedBitmapText bit in the
203 paint's flags,
204 false to clear it.
205 */
206 void setAutohinted(bool useAutohinter);
207
reed@android.com8a1c16f2008-12-17 15:59:43 +0000208 /** Helper for getFlags(), returning true if kUnderlineText_Flag bit is set
209 @return true if the underlineText bit is set in the paint's flags.
210 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000211 bool isUnderlineText() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000212 return SkToBool(this->getFlags() & kUnderlineText_Flag);
213 }
214
215 /** Helper for setFlags(), setting or clearing the kUnderlineText_Flag bit
216 @param underlineText true to set the underlineText bit in the paint's
217 flags, false to clear it.
218 */
219 void setUnderlineText(bool underlineText);
220
221 /** Helper for getFlags(), returns true if kStrikeThruText_Flag bit is set
222 @return true if the strikeThruText bit is set in the paint's flags.
223 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000224 bool isStrikeThruText() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000225 return SkToBool(this->getFlags() & kStrikeThruText_Flag);
226 }
227
228 /** Helper for setFlags(), setting or clearing the kStrikeThruText_Flag bit
229 @param strikeThruText true to set the strikeThruText bit in the
230 paint's flags, false to clear it.
231 */
232 void setStrikeThruText(bool strikeThruText);
233
234 /** Helper for getFlags(), returns true if kFakeBoldText_Flag bit is set
235 @return true if the kFakeBoldText_Flag bit is set in the paint's flags.
236 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000237 bool isFakeBoldText() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000238 return SkToBool(this->getFlags() & kFakeBoldText_Flag);
239 }
240
241 /** Helper for setFlags(), setting or clearing the kFakeBoldText_Flag bit
242 @param fakeBoldText true to set the kFakeBoldText_Flag bit in the paint's
243 flags, false to clear it.
244 */
245 void setFakeBoldText(bool fakeBoldText);
246
247 /** Helper for getFlags(), returns true if kDevKernText_Flag bit is set
248 @return true if the kernText bit is set in the paint's flags.
249 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000250 bool isDevKernText() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000251 return SkToBool(this->getFlags() & kDevKernText_Flag);
252 }
253
254 /** Helper for setFlags(), setting or clearing the kKernText_Flag bit
255 @param kernText true to set the kKernText_Flag bit in the paint's
256 flags, false to clear it.
257 */
258 void setDevKernText(bool devKernText);
259
reed@google.com9d07fec2011-03-16 20:02:59 +0000260 bool isFilterBitmap() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000261 return SkToBool(this->getFlags() & kFilterBitmap_Flag);
262 }
reed@google.com9d07fec2011-03-16 20:02:59 +0000263
reed@android.com8a1c16f2008-12-17 15:59:43 +0000264 void setFilterBitmap(bool filterBitmap);
265
266 /** Styles apply to rect, oval, path, and text.
267 Bitmaps are always drawn in "fill", and lines are always drawn in
268 "stroke".
reed@google.com9d07fec2011-03-16 20:02:59 +0000269
reed@android.comed881c22009-09-15 14:10:42 +0000270 Note: strokeandfill implicitly draws the result with
271 SkPath::kWinding_FillType, so if the original path is even-odd, the
272 results may not appear the same as if it was drawn twice, filled and
273 then stroked.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000274 */
275 enum Style {
reed@android.comed881c22009-09-15 14:10:42 +0000276 kFill_Style, //!< fill the geometry
277 kStroke_Style, //!< stroke the geometry
278 kStrokeAndFill_Style, //!< fill and stroke the geometry
reed@android.com8a1c16f2008-12-17 15:59:43 +0000279
280 kStyleCount,
281 };
282
283 /** Return the paint's style, used for controlling how primitives'
284 geometries are interpreted (except for drawBitmap, which always assumes
285 kFill_Style).
286 @return the paint's Style
287 */
288 Style getStyle() const { return (Style)fStyle; }
289
290 /** Set the paint's style, used for controlling how primitives'
291 geometries are interpreted (except for drawBitmap, which always assumes
292 Fill).
293 @param style The new style to set in the paint
294 */
295 void setStyle(Style style);
296
297 /** Return the paint's color. Note that the color is a 32bit value
298 containing alpha as well as r,g,b. This 32bit value is not
299 premultiplied, meaning that its alpha can be any value, regardless of
300 the values of r,g,b.
301 @return the paint's color (and alpha).
302 */
303 SkColor getColor() const { return fColor; }
304
305 /** Set the paint's color. Note that the color is a 32bit value containing
306 alpha as well as r,g,b. This 32bit value is not premultiplied, meaning
307 that its alpha can be any value, regardless of the values of r,g,b.
308 @param color The new color (including alpha) to set in the paint.
309 */
310 void setColor(SkColor color);
311
312 /** Helper to getColor() that just returns the color's alpha value.
313 @return the alpha component of the paint's color.
314 */
315 uint8_t getAlpha() const { return SkToU8(SkColorGetA(fColor)); }
reed@google.com9d07fec2011-03-16 20:02:59 +0000316
reed@android.com8a1c16f2008-12-17 15:59:43 +0000317 /** Helper to setColor(), that only assigns the color's alpha value,
318 leaving its r,g,b values unchanged.
319 @param a set the alpha component (0..255) of the paint's color.
320 */
321 void setAlpha(U8CPU a);
322
323 /** Helper to setColor(), that takes a,r,g,b and constructs the color value
324 using SkColorSetARGB()
325 @param a The new alpha component (0..255) of the paint's color.
326 @param r The new red component (0..255) of the paint's color.
327 @param g The new green component (0..255) of the paint's color.
328 @param b The new blue component (0..255) of the paint's color.
329 */
330 void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
331
reed@google.com9d07fec2011-03-16 20:02:59 +0000332 /** Return the width for stroking.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000333 <p />
334 A value of 0 strokes in hairline mode.
335 Hairlines always draw 1-pixel wide, regardless of the matrix.
336 @return the paint's stroke width, used whenever the paint's style is
337 Stroke or StrokeAndFill.
338 */
339 SkScalar getStrokeWidth() const { return fWidth; }
340
reed@google.com9d07fec2011-03-16 20:02:59 +0000341 /** Set the width for stroking.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000342 Pass 0 to stroke in hairline mode.
343 Hairlines always draw 1-pixel wide, regardless of the matrix.
344 @param width set the paint's stroke width, used whenever the paint's
345 style is Stroke or StrokeAndFill.
346 */
347 void setStrokeWidth(SkScalar width);
348
349 /** Return the paint's stroke miter value. This is used to control the
350 behavior of miter joins when the joins angle is sharp.
351 @return the paint's miter limit, used whenever the paint's style is
352 Stroke or StrokeAndFill.
353 */
354 SkScalar getStrokeMiter() const { return fMiterLimit; }
355
356 /** Set the paint's stroke miter value. This is used to control the
357 behavior of miter joins when the joins angle is sharp. This value must
358 be >= 0.
359 @param miter set the miter limit on the paint, used whenever the
360 paint's style is Stroke or StrokeAndFill.
361 */
362 void setStrokeMiter(SkScalar miter);
363
364 /** Cap enum specifies the settings for the paint's strokecap. This is the
365 treatment that is applied to the beginning and end of each non-closed
366 contour (e.g. lines).
367 */
368 enum Cap {
369 kButt_Cap, //!< begin/end contours with no extension
370 kRound_Cap, //!< begin/end contours with a semi-circle extension
371 kSquare_Cap, //!< begin/end contours with a half square extension
372
373 kCapCount,
374 kDefault_Cap = kButt_Cap
375 };
376
377 /** Join enum specifies the settings for the paint's strokejoin. This is
378 the treatment that is applied to corners in paths and rectangles.
379 */
380 enum Join {
381 kMiter_Join, //!< connect path segments with a sharp join
382 kRound_Join, //!< connect path segments with a round join
383 kBevel_Join, //!< connect path segments with a flat bevel join
384
385 kJoinCount,
386 kDefault_Join = kMiter_Join
387 };
388
389 /** Return the paint's stroke cap type, controlling how the start and end
390 of stroked lines and paths are treated.
391 @return the line cap style for the paint, used whenever the paint's
392 style is Stroke or StrokeAndFill.
393 */
394 Cap getStrokeCap() const { return (Cap)fCapType; }
395
396 /** Set the paint's stroke cap type.
397 @param cap set the paint's line cap style, used whenever the paint's
398 style is Stroke or StrokeAndFill.
399 */
400 void setStrokeCap(Cap cap);
401
402 /** Return the paint's stroke join type.
403 @return the paint's line join style, used whenever the paint's style is
404 Stroke or StrokeAndFill.
405 */
406 Join getStrokeJoin() const { return (Join)fJoinType; }
407
408 /** Set the paint's stroke join type.
409 @param join set the paint's line join style, used whenever the paint's
410 style is Stroke or StrokeAndFill.
411 */
412 void setStrokeJoin(Join join);
413
414 /** Applies any/all effects (patheffect, stroking) to src, returning the
415 result in dst. The result is that drawing src with this paint will be
416 the same as drawing dst with a default paint (at least from the
417 geometric perspective).
418 @param src input path
419 @param dst output path (may be the same as src)
420 @return true if the path should be filled, or false if it should be
421 drawn with a hairline (width == 0)
422 */
423 bool getFillPath(const SkPath& src, SkPath* dst) const;
424
425 /** Returns true if the current paint settings allow for fast computation of
426 bounds (i.e. there is nothing complex like a patheffect that would make
427 the bounds computation expensive.
428 */
reed@android.comd252db02009-04-01 18:31:44 +0000429 bool canComputeFastBounds() const {
430 // use bit-or since no need for early exit
431 return (reinterpret_cast<uintptr_t>(this->getMaskFilter()) |
432 reinterpret_cast<uintptr_t>(this->getLooper()) |
433 reinterpret_cast<uintptr_t>(this->getRasterizer()) |
434 reinterpret_cast<uintptr_t>(this->getPathEffect())) == 0;
435 }
436
reed@android.com8a1c16f2008-12-17 15:59:43 +0000437 /** Only call this if canComputeFastBounds() returned true. This takes a
438 raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
439 effects in the paint (e.g. stroking). If needed, it uses the storage
440 rect parameter. It returns the adjusted bounds that can then be used
441 for quickReject tests.
reed@google.com9d07fec2011-03-16 20:02:59 +0000442
reed@android.com8a1c16f2008-12-17 15:59:43 +0000443 The returned rect will either be orig or storage, thus the caller
444 should not rely on storage being set to the result, but should always
445 use the retured value. It is legal for orig and storage to be the same
446 rect.
reed@google.com9d07fec2011-03-16 20:02:59 +0000447
reed@android.com8a1c16f2008-12-17 15:59:43 +0000448 e.g.
449 if (paint.canComputeFastBounds()) {
450 SkRect r, storage;
451 path.computeBounds(&r, SkPath::kFast_BoundsType);
452 const SkRect& fastR = paint.computeFastBounds(r, &storage);
453 if (canvas->quickReject(fastR, ...)) {
454 // don't draw the path
455 }
456 }
457 */
reed@android.comd252db02009-04-01 18:31:44 +0000458 const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const {
459 return this->getStyle() == kFill_Style ? orig :
460 this->computeStrokeFastBounds(orig, storage);
461 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000462
463 /** Get the paint's shader object.
464 <p />
465 The shader's reference count is not affected.
466 @return the paint's shader (or NULL)
467 */
468 SkShader* getShader() const { return fShader; }
469
470 /** Set or clear the shader object.
471 <p />
472 Pass NULL to clear any previous shader.
473 As a convenience, the parameter passed is also returned.
474 If a previous shader exists, its reference count is decremented.
475 If shader is not NULL, its reference count is incremented.
476 @param shader May be NULL. The shader to be installed in the paint
477 @return shader
478 */
479 SkShader* setShader(SkShader* shader);
reed@google.com9d07fec2011-03-16 20:02:59 +0000480
reed@android.com8a1c16f2008-12-17 15:59:43 +0000481 /** Get the paint's colorfilter. If there is a colorfilter, its reference
482 count is not changed.
483 @return the paint's colorfilter (or NULL)
484 */
485 SkColorFilter* getColorFilter() const { return fColorFilter; }
486
487 /** Set or clear the paint's colorfilter, returning the parameter.
488 <p />
489 If the paint already has a filter, its reference count is decremented.
490 If filter is not NULL, its reference count is incremented.
491 @param filter May be NULL. The filter to be installed in the paint
492 @return filter
493 */
494 SkColorFilter* setColorFilter(SkColorFilter* filter);
495
496 /** Get the paint's xfermode object.
497 <p />
498 The xfermode's reference count is not affected.
499 @return the paint's xfermode (or NULL)
500 */
501 SkXfermode* getXfermode() const { return fXfermode; }
502
503 /** Set or clear the xfermode object.
504 <p />
505 Pass NULL to clear any previous xfermode.
506 As a convenience, the parameter passed is also returned.
507 If a previous xfermode exists, its reference count is decremented.
508 If xfermode is not NULL, its reference count is incremented.
509 @param xfermode May be NULL. The new xfermode to be installed in the
510 paint
511 @return xfermode
512 */
513 SkXfermode* setXfermode(SkXfermode* xfermode);
reed@android.coma0f5d152009-06-22 17:38:10 +0000514
515 /** Create an xfermode based on the specified Mode, and assign it into the
516 paint, returning the mode that was set. If the Mode is SrcOver, then
517 the paint's xfermode is set to null.
518 */
reed@android.com0baf1932009-06-24 12:41:42 +0000519 SkXfermode* setXfermodeMode(SkXfermode::Mode);
reed@android.coma0f5d152009-06-22 17:38:10 +0000520
reed@android.com8a1c16f2008-12-17 15:59:43 +0000521 /** Get the paint's patheffect object.
522 <p />
523 The patheffect reference count is not affected.
524 @return the paint's patheffect (or NULL)
525 */
526 SkPathEffect* getPathEffect() const { return fPathEffect; }
527
528 /** Set or clear the patheffect object.
529 <p />
530 Pass NULL to clear any previous patheffect.
531 As a convenience, the parameter passed is also returned.
532 If a previous patheffect exists, its reference count is decremented.
533 If patheffect is not NULL, its reference count is incremented.
534 @param effect May be NULL. The new patheffect to be installed in the
535 paint
536 @return effect
537 */
538 SkPathEffect* setPathEffect(SkPathEffect* effect);
539
540 /** Get the paint's maskfilter object.
541 <p />
542 The maskfilter reference count is not affected.
543 @return the paint's maskfilter (or NULL)
544 */
545 SkMaskFilter* getMaskFilter() const { return fMaskFilter; }
546
547 /** Set or clear the maskfilter object.
548 <p />
549 Pass NULL to clear any previous maskfilter.
550 As a convenience, the parameter passed is also returned.
551 If a previous maskfilter exists, its reference count is decremented.
552 If maskfilter is not NULL, its reference count is incremented.
553 @param maskfilter May be NULL. The new maskfilter to be installed in
554 the paint
555 @return maskfilter
556 */
557 SkMaskFilter* setMaskFilter(SkMaskFilter* maskfilter);
558
559 // These attributes are for text/fonts
560
561 /** Get the paint's typeface object.
562 <p />
563 The typeface object identifies which font to use when drawing or
564 measuring text. The typeface reference count is not affected.
565 @return the paint's typeface (or NULL)
566 */
567 SkTypeface* getTypeface() const { return fTypeface; }
568
569 /** Set or clear the typeface object.
570 <p />
571 Pass NULL to clear any previous typeface.
572 As a convenience, the parameter passed is also returned.
573 If a previous typeface exists, its reference count is decremented.
574 If typeface is not NULL, its reference count is incremented.
575 @param typeface May be NULL. The new typeface to be installed in the
576 paint
577 @return typeface
578 */
579 SkTypeface* setTypeface(SkTypeface* typeface);
580
581 /** Get the paint's rasterizer (or NULL).
582 <p />
583 The raster controls how paths/text are turned into alpha masks.
584 @return the paint's rasterizer (or NULL)
585 */
586 SkRasterizer* getRasterizer() const { return fRasterizer; }
587
588 /** Set or clear the rasterizer object.
589 <p />
590 Pass NULL to clear any previous rasterizer.
591 As a convenience, the parameter passed is also returned.
592 If a previous rasterizer exists in the paint, its reference count is
593 decremented. If rasterizer is not NULL, its reference count is
594 incremented.
595 @param rasterizer May be NULL. The new rasterizer to be installed in
596 the paint.
597 @return rasterizer
598 */
599 SkRasterizer* setRasterizer(SkRasterizer* rasterizer);
600
reed@google.com9d07fec2011-03-16 20:02:59 +0000601 /**
602 * Return the paint's SkDrawLooper (if any). Does not affect the looper's
603 * reference count.
604 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000605 SkDrawLooper* getLooper() const { return fLooper; }
reed@google.com9d07fec2011-03-16 20:02:59 +0000606
607 /**
608 * Set or clear the looper object.
609 * <p />
610 * Pass NULL to clear any previous looper.
611 * As a convenience, the parameter passed is also returned.
612 * If a previous looper exists in the paint, its reference count is
613 * decremented. If looper is not NULL, its reference count is
614 * incremented.
615 * @param looper May be NULL. The new looper to be installed in the paint.
616 * @return looper
617 */
618 SkDrawLooper* setLooper(SkDrawLooper* looper);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000619
620 enum Align {
621 kLeft_Align,
622 kCenter_Align,
623 kRight_Align,
624
625 kAlignCount
626 };
reed@google.com9d07fec2011-03-16 20:02:59 +0000627
reed@android.com8a1c16f2008-12-17 15:59:43 +0000628 /** Return the paint's Align value for drawing text.
629 @return the paint's Align value for drawing text.
630 */
631 Align getTextAlign() const { return (Align)fTextAlign; }
reed@google.com9d07fec2011-03-16 20:02:59 +0000632
reed@android.com8a1c16f2008-12-17 15:59:43 +0000633 /** Set the paint's text alignment.
634 @param align set the paint's Align value for drawing text.
635 */
636 void setTextAlign(Align align);
637
638 /** Return the paint's text size.
639 @return the paint's text size.
640 */
641 SkScalar getTextSize() const { return fTextSize; }
642
643 /** Set the paint's text size. This value must be > 0
644 @param textSize set the paint's text size.
645 */
646 void setTextSize(SkScalar textSize);
647
648 /** Return the paint's horizontal scale factor for text. The default value
649 is 1.0.
650 @return the paint's scale factor in X for drawing/measuring text
651 */
652 SkScalar getTextScaleX() const { return fTextScaleX; }
653
654 /** Set the paint's horizontal scale factor for text. The default value
655 is 1.0. Values > 1.0 will stretch the text wider. Values < 1.0 will
656 stretch the text narrower.
657 @param scaleX set the paint's scale factor in X for drawing/measuring
658 text.
659 */
660 void setTextScaleX(SkScalar scaleX);
661
662 /** Return the paint's horizontal skew factor for text. The default value
663 is 0.
664 @return the paint's skew factor in X for drawing text.
665 */
666 SkScalar getTextSkewX() const { return fTextSkewX; }
667
668 /** Set the paint's horizontal skew factor for text. The default value
669 is 0. For approximating oblique text, use values around -0.25.
670 @param skewX set the paint's skew factor in X for drawing text.
671 */
672 void setTextSkewX(SkScalar skewX);
673
674 /** Describes how to interpret the text parameters that are passed to paint
675 methods like measureText() and getTextWidths().
676 */
677 enum TextEncoding {
678 kUTF8_TextEncoding, //!< the text parameters are UTF8
679 kUTF16_TextEncoding, //!< the text parameters are UTF16
680 kGlyphID_TextEncoding //!< the text parameters are glyph indices
681 };
reed@google.com9d07fec2011-03-16 20:02:59 +0000682
683 TextEncoding getTextEncoding() const { return (TextEncoding)fTextEncoding; }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000684
685 void setTextEncoding(TextEncoding encoding);
686
687 struct FontMetrics {
688 SkScalar fTop; //!< The greatest distance above the baseline for any glyph (will be <= 0)
689 SkScalar fAscent; //!< The recommended distance above the baseline (will be <= 0)
690 SkScalar fDescent; //!< The recommended distance below the baseline (will be >= 0)
691 SkScalar fBottom; //!< The greatest distance below the baseline for any glyph (will be >= 0)
692 SkScalar fLeading; //!< The recommended distance to add between lines of text (will be >= 0)
agl@chromium.orgcc3096b2009-04-22 22:09:04 +0000693 SkScalar fAvgCharWidth; //!< the average charactor width (>= 0)
694 SkScalar fXMin; //!< The minimum bounding box x value for all glyphs
695 SkScalar fXMax; //!< The maximum bounding box x value for all glyphs
696 SkScalar fXHeight; //!< the height of an 'x' in px, or 0 if no 'x' in face
reed@android.com8a1c16f2008-12-17 15:59:43 +0000697 };
reed@google.com9d07fec2011-03-16 20:02:59 +0000698
reed@android.com8a1c16f2008-12-17 15:59:43 +0000699 /** Return the recommend spacing between lines (which will be
700 fDescent - fAscent + fLeading).
701 If metrics is not null, return in it the font metrics for the
reed@google.com9d07fec2011-03-16 20:02:59 +0000702 typeface/pointsize/etc. currently set in the paint.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000703 @param metrics If not null, returns the font metrics for the
704 current typeface/pointsize/etc setting in this
705 paint.
706 @param scale If not 0, return width as if the canvas were scaled
707 by this value
708 @param return the recommended spacing between lines
709 */
710 SkScalar getFontMetrics(FontMetrics* metrics, SkScalar scale = 0) const;
reed@google.com9d07fec2011-03-16 20:02:59 +0000711
reed@android.com8a1c16f2008-12-17 15:59:43 +0000712 /** Return the recommend line spacing. This will be
713 fDescent - fAscent + fLeading
714 */
715 SkScalar getFontSpacing() const { return this->getFontMetrics(NULL, 0); }
716
717 /** Convert the specified text into glyph IDs, returning the number of
718 glyphs ID written. If glyphs is NULL, it is ignore and only the count
719 is returned.
720 */
721 int textToGlyphs(const void* text, size_t byteLength,
722 uint16_t glyphs[]) const;
723
reed@android.coma5dcaf62010-02-05 17:12:32 +0000724 /** Return true if all of the specified text has a corresponding non-zero
725 glyph ID. If any of the code-points in the text are not supported in
726 the typeface (i.e. the glyph ID would be zero), then return false.
727
728 If the text encoding for the paint is kGlyph_TextEncoding, then this
729 returns true if all of the specified glyph IDs are non-zero.
730 */
731 bool containsText(const void* text, size_t byteLength) const;
732
reed@android.com9d3a9852010-01-08 14:07:42 +0000733 /** Convert the glyph array into Unichars. Unconvertable glyphs are mapped
734 to zero. Note: this does not look at the text-encoding setting in the
735 paint, only at the typeface.
736 */
737 void glyphsToUnichars(const uint16_t glyphs[], int count,
738 SkUnichar text[]) const;
739
reed@android.com8a1c16f2008-12-17 15:59:43 +0000740 /** Return the number of drawable units in the specified text buffer.
741 This looks at the current TextEncoding field of the paint. If you also
742 want to have the text converted into glyph IDs, call textToGlyphs
743 instead.
744 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000745 int countText(const void* text, size_t byteLength) const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000746 return this->textToGlyphs(text, byteLength, NULL);
747 }
748
749 /** Return the width of the text.
750 @param text The text to be measured
751 @param length Number of bytes of text to measure
752 @param bounds If not NULL, returns the bounds of the text,
753 relative to (0, 0).
754 @param scale If not 0, return width as if the canvas were scaled
755 by this value
756 @return The advance width of the text
757 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000758 SkScalar measureText(const void* text, size_t length,
759 SkRect* bounds, SkScalar scale = 0) const;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000760
761 /** Return the width of the text.
762 @param text Address of the text
763 @param length Number of bytes of text to measure
764 @return The width of the text
765 */
reed@google.com9d07fec2011-03-16 20:02:59 +0000766 SkScalar measureText(const void* text, size_t length) const {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000767 return this->measureText(text, length, NULL, 0);
768 }
reed@google.com9d07fec2011-03-16 20:02:59 +0000769
reed@android.com8a1c16f2008-12-17 15:59:43 +0000770 /** Specify the direction the text buffer should be processed in breakText()
771 */
772 enum TextBufferDirection {
773 /** When measuring text for breakText(), begin at the start of the text
774 buffer and proceed forward through the data. This is the default.
775 */
776 kForward_TextBufferDirection,
777 /** When measuring text for breakText(), begin at the end of the text
778 buffer and proceed backwards through the data.
779 */
780 kBackward_TextBufferDirection
781 };
782
783 /** Return the width of the text.
784 @param text The text to be measured
785 @param length Number of bytes of text to measure
786 @param maxWidth Maximum width. Only the subset of text whose accumulated
787 widths are <= maxWidth are measured.
788 @param measuredWidth Optional. If non-null, this returns the actual
789 width of the measured text.
790 @param tbd Optional. The direction the text buffer should be
791 traversed during measuring.
792 @return The number of bytes of text that were measured. Will be
793 <= length.
794 */
795 size_t breakText(const void* text, size_t length, SkScalar maxWidth,
796 SkScalar* measuredWidth = NULL,
797 TextBufferDirection tbd = kForward_TextBufferDirection)
798 const;
799
800 /** Return the advance widths for the characters in the string.
801 @param text the text
802 @param byteLength number of bytes to of text
803 @param widths If not null, returns the array of advance widths of
804 the glyphs. If not NULL, must be at least a large
805 as the number of unichars in the specified text.
806 @param bounds If not null, returns the bounds for each of
807 character, relative to (0, 0)
808 @return the number of unichars in the specified text.
809 */
810 int getTextWidths(const void* text, size_t byteLength, SkScalar widths[],
811 SkRect bounds[] = NULL) const;
812
813 /** Return the path (outline) for the specified text.
814 Note: just like SkCanvas::drawText, this will respect the Align setting
815 in the paint.
816 */
817 void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y,
818 SkPath* path) const;
819
820private:
821 SkTypeface* fTypeface;
822 SkScalar fTextSize;
823 SkScalar fTextScaleX;
824 SkScalar fTextSkewX;
825
826 SkPathEffect* fPathEffect;
827 SkShader* fShader;
828 SkXfermode* fXfermode;
829 SkMaskFilter* fMaskFilter;
830 SkColorFilter* fColorFilter;
831 SkRasterizer* fRasterizer;
832 SkDrawLooper* fLooper;
833
834 SkColor fColor;
835 SkScalar fWidth;
836 SkScalar fMiterLimit;
agl@chromium.orga2c71cb2010-06-17 20:49:17 +0000837 unsigned fFlags : 12;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000838 unsigned fTextAlign : 2;
839 unsigned fCapType : 2;
840 unsigned fJoinType : 2;
841 unsigned fStyle : 2;
842 unsigned fTextEncoding : 2; // 3 values
agl@chromium.org309485b2009-07-21 17:41:32 +0000843 unsigned fHinting : 2;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000844
845 SkDrawCacheProc getDrawCacheProc() const;
846 SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir,
847 bool needFullMetrics) const;
848
849 SkScalar measure_text(SkGlyphCache*, const char* text, size_t length,
850 int* count, SkRect* bounds) const;
851
852 SkGlyphCache* detachCache(const SkMatrix*) const;
853
854 void descriptorProc(const SkMatrix* deviceMatrix,
855 void (*proc)(const SkDescriptor*, void*),
djsollen@google.com57f49692011-02-23 20:46:31 +0000856 void* context, bool ignoreGamma = false) const;
reed@android.comd252db02009-04-01 18:31:44 +0000857
858 const SkRect& computeStrokeFastBounds(const SkRect& orig,
859 SkRect* storage) const;
860
reed@android.com8a1c16f2008-12-17 15:59:43 +0000861 enum {
862 kCanonicalTextSizeForPaths = 64
863 };
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000864 friend class SkAutoGlyphCache;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000865 friend class SkCanvas;
866 friend class SkDraw;
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000867 friend class SkPDFDevice;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000868 friend class SkTextToPathIter;
869};
870
871//////////////////////////////////////////////////////////////////////////
872
873#include "SkPathEffect.h"
874
875/** \class SkStrokePathEffect
876
877 SkStrokePathEffect simulates stroking inside a patheffect, allowing the
878 caller to have explicit control of when to stroke a path. Typically this is
879 used if the caller wants to stroke before another patheffect is applied
880 (using SkComposePathEffect or SkSumPathEffect).
881*/
882class SkStrokePathEffect : public SkPathEffect {
883public:
884 SkStrokePathEffect(const SkPaint&);
885 SkStrokePathEffect(SkScalar width, SkPaint::Style, SkPaint::Join,
886 SkPaint::Cap, SkScalar miterLimit = -1);
887
888 // overrides
889 // This method is not exported to java.
890 virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
891
892 // overrides for SkFlattenable
893 // This method is not exported to java.
894 virtual void flatten(SkFlattenableWriteBuffer&);
895 // This method is not exported to java.
896 virtual Factory getFactory();
897
898private:
899 SkScalar fWidth, fMiter;
900 uint8_t fStyle, fJoin, fCap;
901
902 static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
903 SkStrokePathEffect(SkFlattenableReadBuffer&);
904
905 typedef SkPathEffect INHERITED;
906
907 // illegal
908 SkStrokePathEffect(const SkStrokePathEffect&);
909 SkStrokePathEffect& operator=(const SkStrokePathEffect&);
910};
911
912#endif
913