1 :
2 : /*
3 : * Copyright 2006 The Android Open Source Project
4 : *
5 : * Use of this source code is governed by a BSD-style license that can be
6 : * found in the LICENSE file.
7 : */
8 :
9 :
10 : #ifndef SkPaint_DEFINED
11 : #define SkPaint_DEFINED
12 :
13 : #include "SkColor.h"
14 : #include "SkXfermode.h"
15 :
16 : class SkAutoGlyphCache;
17 : class SkColorFilter;
18 : class SkDescriptor;
19 : class SkFlattenableReadBuffer;
20 : class SkFlattenableWriteBuffer;
21 : struct SkGlyph;
22 : struct SkRect;
23 : class SkGlyphCache;
24 : class SkImageFilter;
25 : class SkMaskFilter;
26 : class SkMatrix;
27 : class SkPath;
28 : class SkPathEffect;
29 : class SkRasterizer;
30 : class SkShader;
31 : class SkDrawLooper;
32 : class SkTypeface;
33 :
34 : typedef const SkGlyph& (*SkDrawCacheProc)(SkGlyphCache*, const char**,
35 : SkFixed x, SkFixed y);
36 :
37 : typedef 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 : */
44 : class SK_API SkPaint {
45 : public:
46 : SkPaint();
47 : SkPaint(const SkPaint& paint);
48 : ~SkPaint();
49 :
50 : SkPaint& operator=(const SkPaint&);
51 :
52 : SK_API friend bool operator==(const SkPaint& a, const SkPaint& b);
53 : friend bool operator!=(const SkPaint& a, const SkPaint& b) {
54 : return !(a == b);
55 : }
56 :
57 : void flatten(SkFlattenableWriteBuffer&) const;
58 : void unflatten(SkFlattenableReadBuffer&);
59 :
60 : /** Restores the paint to its initial settings.
61 : */
62 : void reset();
63 :
64 : /** 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 :
81 0 : Hinting getHinting() const {
82 0 : return static_cast<Hinting>(fHinting);
83 : }
84 :
85 : void setHinting(Hinting hintingLevel);
86 :
87 : /** 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
97 : kSubpixelText_Flag = 0x80, //!< mask to enable subpixel text positioning
98 : kDevKernText_Flag = 0x100, //!< mask to enable device kerning text
99 : kLCDRenderText_Flag = 0x200, //!< mask to enable subpixel glyph renderering
100 : kEmbeddedBitmapText_Flag = 0x400, //!< mask to enable embedded bitmap strikes
101 : kAutoHinting_Flag = 0x800, //!< mask to force Freetype's autohinter
102 : kVerticalText_Flag = 0x1000,
103 :
104 : // when adding extra flags, note that the fFlags member is specified
105 : // with a bit-width and you'll have to expand it.
106 :
107 : kAllFlags = 0x1FFF
108 : };
109 :
110 : /** Return the paint's flags. Use the Flag enum to test flag values.
111 : @return the paint's flags (see enums ending in _Flag for bit masks)
112 : */
113 0 : uint32_t getFlags() const { return fFlags; }
114 :
115 : /** Set the paint's flags. Use the Flag enum to specific flag values.
116 : @param flags The new flag bits for the paint (see Flags enum)
117 : */
118 : void setFlags(uint32_t flags);
119 :
120 : /** Helper for getFlags(), returning true if kAntiAlias_Flag bit is set
121 : @return true if the antialias bit is set in the paint's flags.
122 : */
123 0 : bool isAntiAlias() const {
124 0 : return SkToBool(this->getFlags() & kAntiAlias_Flag);
125 : }
126 :
127 : /** Helper for setFlags(), setting or clearing the kAntiAlias_Flag bit
128 : @param aa true to enable antialiasing, false to disable it
129 : */
130 : void setAntiAlias(bool aa);
131 :
132 : /** Helper for getFlags(), returning true if kDither_Flag bit is set
133 : @return true if the dithering bit is set in the paint's flags.
134 : */
135 0 : bool isDither() const {
136 0 : return SkToBool(this->getFlags() & kDither_Flag);
137 : }
138 :
139 : /** Helper for setFlags(), setting or clearing the kDither_Flag bit
140 : @param dither true to enable dithering, false to disable it
141 : */
142 : void setDither(bool dither);
143 :
144 : /** Helper for getFlags(), returning true if kLinearText_Flag bit is set
145 : @return true if the lineartext bit is set in the paint's flags
146 : */
147 0 : bool isLinearText() const {
148 0 : return SkToBool(this->getFlags() & kLinearText_Flag);
149 : }
150 :
151 : /** Helper for setFlags(), setting or clearing the kLinearText_Flag bit
152 : @param linearText true to set the linearText bit in the paint's flags,
153 : false to clear it.
154 : */
155 : void setLinearText(bool linearText);
156 :
157 : /** Helper for getFlags(), returning true if kSubpixelText_Flag bit is set
158 : @return true if the lineartext bit is set in the paint's flags
159 : */
160 0 : bool isSubpixelText() const {
161 0 : return SkToBool(this->getFlags() & kSubpixelText_Flag);
162 : }
163 :
164 : /**
165 : * Helper for setFlags(), setting or clearing the kSubpixelText_Flag.
166 : * @param subpixelText true to set the subpixelText bit in the paint's
167 : * flags, false to clear it.
168 : */
169 : void setSubpixelText(bool subpixelText);
170 :
171 0 : bool isLCDRenderText() const {
172 0 : return SkToBool(this->getFlags() & kLCDRenderText_Flag);
173 : }
174 :
175 : /**
176 : * Helper for setFlags(), setting or clearing the kLCDRenderText_Flag.
177 : * Note: antialiasing must also be on for lcd rendering
178 : * @param lcdText true to set the LCDRenderText bit in the paint's flags,
179 : * false to clear it.
180 : */
181 : void setLCDRenderText(bool lcdText);
182 :
183 0 : bool isEmbeddedBitmapText() const {
184 0 : return SkToBool(this->getFlags() & kEmbeddedBitmapText_Flag);
185 : }
186 :
187 : /** Helper for setFlags(), setting or clearing the kEmbeddedBitmapText_Flag bit
188 : @param useEmbeddedBitmapText true to set the kEmbeddedBitmapText bit in the paint's flags,
189 : false to clear it.
190 : */
191 : void setEmbeddedBitmapText(bool useEmbeddedBitmapText);
192 :
193 0 : bool isAutohinted() const {
194 0 : return SkToBool(this->getFlags() & kAutoHinting_Flag);
195 : }
196 :
197 : /** Helper for setFlags(), setting or clearing the kAutoHinting_Flag bit
198 : @param useAutohinter true to set the kEmbeddedBitmapText bit in the
199 : paint's flags,
200 : false to clear it.
201 : */
202 : void setAutohinted(bool useAutohinter);
203 :
204 0 : bool isVerticalText() const {
205 0 : return SkToBool(this->getFlags() & kVerticalText_Flag);
206 : }
207 :
208 : /**
209 : * Helper for setting or clearing the kVerticalText_Flag bit in
210 : * setFlags(...).
211 : *
212 : * If this bit is set, then advances are treated as Y values rather than
213 : * X values, and drawText will places its glyphs vertically rather than
214 : * horizontally.
215 : */
216 : void setVerticalText(bool);
217 :
218 : /** Helper for getFlags(), returning true if kUnderlineText_Flag bit is set
219 : @return true if the underlineText bit is set in the paint's flags.
220 : */
221 : bool isUnderlineText() const {
222 : return SkToBool(this->getFlags() & kUnderlineText_Flag);
223 : }
224 :
225 : /** Helper for setFlags(), setting or clearing the kUnderlineText_Flag bit
226 : @param underlineText true to set the underlineText bit in the paint's
227 : flags, false to clear it.
228 : */
229 : void setUnderlineText(bool underlineText);
230 :
231 : /** Helper for getFlags(), returns true if kStrikeThruText_Flag bit is set
232 : @return true if the strikeThruText bit is set in the paint's flags.
233 : */
234 : bool isStrikeThruText() const {
235 : return SkToBool(this->getFlags() & kStrikeThruText_Flag);
236 : }
237 :
238 : /** Helper for setFlags(), setting or clearing the kStrikeThruText_Flag bit
239 : @param strikeThruText true to set the strikeThruText bit in the
240 : paint's flags, false to clear it.
241 : */
242 : void setStrikeThruText(bool strikeThruText);
243 :
244 : /** Helper for getFlags(), returns true if kFakeBoldText_Flag bit is set
245 : @return true if the kFakeBoldText_Flag bit is set in the paint's flags.
246 : */
247 0 : bool isFakeBoldText() const {
248 0 : return SkToBool(this->getFlags() & kFakeBoldText_Flag);
249 : }
250 :
251 : /** Helper for setFlags(), setting or clearing the kFakeBoldText_Flag bit
252 : @param fakeBoldText true to set the kFakeBoldText_Flag bit in the paint's
253 : flags, false to clear it.
254 : */
255 : void setFakeBoldText(bool fakeBoldText);
256 :
257 : /** Helper for getFlags(), returns true if kDevKernText_Flag bit is set
258 : @return true if the kernText bit is set in the paint's flags.
259 : */
260 0 : bool isDevKernText() const {
261 0 : return SkToBool(this->getFlags() & kDevKernText_Flag);
262 : }
263 :
264 : /** Helper for setFlags(), setting or clearing the kKernText_Flag bit
265 : @param kernText true to set the kKernText_Flag bit in the paint's
266 : flags, false to clear it.
267 : */
268 : void setDevKernText(bool devKernText);
269 :
270 0 : bool isFilterBitmap() const {
271 0 : return SkToBool(this->getFlags() & kFilterBitmap_Flag);
272 : }
273 :
274 : void setFilterBitmap(bool filterBitmap);
275 :
276 : /** Styles apply to rect, oval, path, and text.
277 : Bitmaps are always drawn in "fill", and lines are always drawn in
278 : "stroke".
279 :
280 : Note: strokeandfill implicitly draws the result with
281 : SkPath::kWinding_FillType, so if the original path is even-odd, the
282 : results may not appear the same as if it was drawn twice, filled and
283 : then stroked.
284 : */
285 : enum Style {
286 : kFill_Style, //!< fill the geometry
287 : kStroke_Style, //!< stroke the geometry
288 : kStrokeAndFill_Style, //!< fill and stroke the geometry
289 :
290 : kStyleCount
291 : };
292 :
293 : /** Return the paint's style, used for controlling how primitives'
294 : geometries are interpreted (except for drawBitmap, which always assumes
295 : kFill_Style).
296 : @return the paint's Style
297 : */
298 0 : Style getStyle() const { return (Style)fStyle; }
299 :
300 : /** Set the paint's style, used for controlling how primitives'
301 : geometries are interpreted (except for drawBitmap, which always assumes
302 : Fill).
303 : @param style The new style to set in the paint
304 : */
305 : void setStyle(Style style);
306 :
307 : /** Return the paint's color. Note that the color is a 32bit value
308 : containing alpha as well as r,g,b. This 32bit value is not
309 : premultiplied, meaning that its alpha can be any value, regardless of
310 : the values of r,g,b.
311 : @return the paint's color (and alpha).
312 : */
313 0 : SkColor getColor() const { return fColor; }
314 :
315 : /** Set the paint's color. Note that the color is a 32bit value containing
316 : alpha as well as r,g,b. This 32bit value is not premultiplied, meaning
317 : that its alpha can be any value, regardless of the values of r,g,b.
318 : @param color The new color (including alpha) to set in the paint.
319 : */
320 : void setColor(SkColor color);
321 :
322 : /** Helper to getColor() that just returns the color's alpha value.
323 : @return the alpha component of the paint's color.
324 : */
325 0 : uint8_t getAlpha() const { return SkToU8(SkColorGetA(fColor)); }
326 :
327 : /** Helper to setColor(), that only assigns the color's alpha value,
328 : leaving its r,g,b values unchanged.
329 : @param a set the alpha component (0..255) of the paint's color.
330 : */
331 : void setAlpha(U8CPU a);
332 :
333 : /** Helper to setColor(), that takes a,r,g,b and constructs the color value
334 : using SkColorSetARGB()
335 : @param a The new alpha component (0..255) of the paint's color.
336 : @param r The new red component (0..255) of the paint's color.
337 : @param g The new green component (0..255) of the paint's color.
338 : @param b The new blue component (0..255) of the paint's color.
339 : */
340 : void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
341 :
342 : /** Return the width for stroking.
343 : <p />
344 : A value of 0 strokes in hairline mode.
345 : Hairlines always draw 1-pixel wide, regardless of the matrix.
346 : @return the paint's stroke width, used whenever the paint's style is
347 : Stroke or StrokeAndFill.
348 : */
349 0 : SkScalar getStrokeWidth() const { return fWidth; }
350 :
351 : /** Set the width for stroking.
352 : Pass 0 to stroke in hairline mode.
353 : Hairlines always draw 1-pixel wide, regardless of the matrix.
354 : @param width set the paint's stroke width, used whenever the paint's
355 : style is Stroke or StrokeAndFill.
356 : */
357 : void setStrokeWidth(SkScalar width);
358 :
359 : /** Return the paint's stroke miter value. This is used to control the
360 : behavior of miter joins when the joins angle is sharp.
361 : @return the paint's miter limit, used whenever the paint's style is
362 : Stroke or StrokeAndFill.
363 : */
364 0 : SkScalar getStrokeMiter() const { return fMiterLimit; }
365 :
366 : /** Set the paint's stroke miter value. This is used to control the
367 : behavior of miter joins when the joins angle is sharp. This value must
368 : be >= 0.
369 : @param miter set the miter limit on the paint, used whenever the
370 : paint's style is Stroke or StrokeAndFill.
371 : */
372 : void setStrokeMiter(SkScalar miter);
373 :
374 : /** Cap enum specifies the settings for the paint's strokecap. This is the
375 : treatment that is applied to the beginning and end of each non-closed
376 : contour (e.g. lines).
377 : */
378 : enum Cap {
379 : kButt_Cap, //!< begin/end contours with no extension
380 : kRound_Cap, //!< begin/end contours with a semi-circle extension
381 : kSquare_Cap, //!< begin/end contours with a half square extension
382 :
383 : kCapCount,
384 : kDefault_Cap = kButt_Cap
385 : };
386 :
387 : /** Join enum specifies the settings for the paint's strokejoin. This is
388 : the treatment that is applied to corners in paths and rectangles.
389 : */
390 : enum Join {
391 : kMiter_Join, //!< connect path segments with a sharp join
392 : kRound_Join, //!< connect path segments with a round join
393 : kBevel_Join, //!< connect path segments with a flat bevel join
394 :
395 : kJoinCount,
396 : kDefault_Join = kMiter_Join
397 : };
398 :
399 : /** Return the paint's stroke cap type, controlling how the start and end
400 : of stroked lines and paths are treated.
401 : @return the line cap style for the paint, used whenever the paint's
402 : style is Stroke or StrokeAndFill.
403 : */
404 0 : Cap getStrokeCap() const { return (Cap)fCapType; }
405 :
406 : /** Set the paint's stroke cap type.
407 : @param cap set the paint's line cap style, used whenever the paint's
408 : style is Stroke or StrokeAndFill.
409 : */
410 : void setStrokeCap(Cap cap);
411 :
412 : /** Return the paint's stroke join type.
413 : @return the paint's line join style, used whenever the paint's style is
414 : Stroke or StrokeAndFill.
415 : */
416 0 : Join getStrokeJoin() const { return (Join)fJoinType; }
417 :
418 : /** Set the paint's stroke join type.
419 : @param join set the paint's line join style, used whenever the paint's
420 : style is Stroke or StrokeAndFill.
421 : */
422 : void setStrokeJoin(Join join);
423 :
424 : /** Applies any/all effects (patheffect, stroking) to src, returning the
425 : result in dst. The result is that drawing src with this paint will be
426 : the same as drawing dst with a default paint (at least from the
427 : geometric perspective).
428 : @param src input path
429 : @param dst output path (may be the same as src)
430 : @return true if the path should be filled, or false if it should be
431 : drawn with a hairline (width == 0)
432 : */
433 : bool getFillPath(const SkPath& src, SkPath* dst) const;
434 :
435 : /** Returns true if the current paint settings allow for fast computation of
436 : bounds (i.e. there is nothing complex like a patheffect that would make
437 : the bounds computation expensive.
438 : */
439 0 : bool canComputeFastBounds() const {
440 : // use bit-or since no need for early exit
441 0 : return (reinterpret_cast<uintptr_t>(this->getMaskFilter()) |
442 0 : reinterpret_cast<uintptr_t>(this->getLooper()) |
443 0 : reinterpret_cast<uintptr_t>(this->getRasterizer()) |
444 0 : reinterpret_cast<uintptr_t>(this->getPathEffect())) == 0;
445 : }
446 :
447 : /** Only call this if canComputeFastBounds() returned true. This takes a
448 : raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
449 : effects in the paint (e.g. stroking). If needed, it uses the storage
450 : rect parameter. It returns the adjusted bounds that can then be used
451 : for quickReject tests.
452 :
453 : The returned rect will either be orig or storage, thus the caller
454 : should not rely on storage being set to the result, but should always
455 : use the retured value. It is legal for orig and storage to be the same
456 : rect.
457 :
458 : e.g.
459 : if (paint.canComputeFastBounds()) {
460 : SkRect r, storage;
461 : path.computeBounds(&r, SkPath::kFast_BoundsType);
462 : const SkRect& fastR = paint.computeFastBounds(r, &storage);
463 : if (canvas->quickReject(fastR, ...)) {
464 : // don't draw the path
465 : }
466 : }
467 : */
468 0 : const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const {
469 0 : return this->getStyle() == kFill_Style ? orig :
470 0 : this->computeStrokeFastBounds(orig, storage);
471 : }
472 :
473 : /** Get the paint's shader object.
474 : <p />
475 : The shader's reference count is not affected.
476 : @return the paint's shader (or NULL)
477 : */
478 0 : SkShader* getShader() const { return fShader; }
479 :
480 : /** Set or clear the shader object.
481 : <p />
482 : Pass NULL to clear any previous shader.
483 : As a convenience, the parameter passed is also returned.
484 : If a previous shader exists, its reference count is decremented.
485 : If shader is not NULL, its reference count is incremented.
486 : @param shader May be NULL. The shader to be installed in the paint
487 : @return shader
488 : */
489 : SkShader* setShader(SkShader* shader);
490 :
491 : /** Get the paint's colorfilter. If there is a colorfilter, its reference
492 : count is not changed.
493 : @return the paint's colorfilter (or NULL)
494 : */
495 0 : SkColorFilter* getColorFilter() const { return fColorFilter; }
496 :
497 : /** Set or clear the paint's colorfilter, returning the parameter.
498 : <p />
499 : If the paint already has a filter, its reference count is decremented.
500 : If filter is not NULL, its reference count is incremented.
501 : @param filter May be NULL. The filter to be installed in the paint
502 : @return filter
503 : */
504 : SkColorFilter* setColorFilter(SkColorFilter* filter);
505 :
506 : /** Get the paint's xfermode object.
507 : <p />
508 : The xfermode's reference count is not affected.
509 : @return the paint's xfermode (or NULL)
510 : */
511 0 : SkXfermode* getXfermode() const { return fXfermode; }
512 :
513 : /** Set or clear the xfermode object.
514 : <p />
515 : Pass NULL to clear any previous xfermode.
516 : As a convenience, the parameter passed is also returned.
517 : If a previous xfermode exists, its reference count is decremented.
518 : If xfermode is not NULL, its reference count is incremented.
519 : @param xfermode May be NULL. The new xfermode to be installed in the
520 : paint
521 : @return xfermode
522 : */
523 : SkXfermode* setXfermode(SkXfermode* xfermode);
524 :
525 : /** Create an xfermode based on the specified Mode, and assign it into the
526 : paint, returning the mode that was set. If the Mode is SrcOver, then
527 : the paint's xfermode is set to null.
528 : */
529 : SkXfermode* setXfermodeMode(SkXfermode::Mode);
530 :
531 : /** Get the paint's patheffect object.
532 : <p />
533 : The patheffect reference count is not affected.
534 : @return the paint's patheffect (or NULL)
535 : */
536 0 : SkPathEffect* getPathEffect() const { return fPathEffect; }
537 :
538 : /** Set or clear the patheffect object.
539 : <p />
540 : Pass NULL to clear any previous patheffect.
541 : As a convenience, the parameter passed is also returned.
542 : If a previous patheffect exists, its reference count is decremented.
543 : If patheffect is not NULL, its reference count is incremented.
544 : @param effect May be NULL. The new patheffect to be installed in the
545 : paint
546 : @return effect
547 : */
548 : SkPathEffect* setPathEffect(SkPathEffect* effect);
549 :
550 : /** Get the paint's maskfilter object.
551 : <p />
552 : The maskfilter reference count is not affected.
553 : @return the paint's maskfilter (or NULL)
554 : */
555 0 : SkMaskFilter* getMaskFilter() const { return fMaskFilter; }
556 :
557 : /** Set or clear the maskfilter object.
558 : <p />
559 : Pass NULL to clear any previous maskfilter.
560 : As a convenience, the parameter passed is also returned.
561 : If a previous maskfilter exists, its reference count is decremented.
562 : If maskfilter is not NULL, its reference count is incremented.
563 : @param maskfilter May be NULL. The new maskfilter to be installed in
564 : the paint
565 : @return maskfilter
566 : */
567 : SkMaskFilter* setMaskFilter(SkMaskFilter* maskfilter);
568 :
569 : // These attributes are for text/fonts
570 :
571 : /** Get the paint's typeface object.
572 : <p />
573 : The typeface object identifies which font to use when drawing or
574 : measuring text. The typeface reference count is not affected.
575 : @return the paint's typeface (or NULL)
576 : */
577 0 : SkTypeface* getTypeface() const { return fTypeface; }
578 :
579 : /** Set or clear the typeface object.
580 : <p />
581 : Pass NULL to clear any previous typeface.
582 : As a convenience, the parameter passed is also returned.
583 : If a previous typeface exists, its reference count is decremented.
584 : If typeface is not NULL, its reference count is incremented.
585 : @param typeface May be NULL. The new typeface to be installed in the
586 : paint
587 : @return typeface
588 : */
589 : SkTypeface* setTypeface(SkTypeface* typeface);
590 :
591 : /** Get the paint's rasterizer (or NULL).
592 : <p />
593 : The raster controls how paths/text are turned into alpha masks.
594 : @return the paint's rasterizer (or NULL)
595 : */
596 0 : SkRasterizer* getRasterizer() const { return fRasterizer; }
597 :
598 : /** Set or clear the rasterizer object.
599 : <p />
600 : Pass NULL to clear any previous rasterizer.
601 : As a convenience, the parameter passed is also returned.
602 : If a previous rasterizer exists in the paint, its reference count is
603 : decremented. If rasterizer is not NULL, its reference count is
604 : incremented.
605 : @param rasterizer May be NULL. The new rasterizer to be installed in
606 : the paint.
607 : @return rasterizer
608 : */
609 : SkRasterizer* setRasterizer(SkRasterizer* rasterizer);
610 :
611 0 : SkImageFilter* getImageFilter() const { return fImageFilter; }
612 : SkImageFilter* setImageFilter(SkImageFilter*);
613 :
614 : /**
615 : * Return the paint's SkDrawLooper (if any). Does not affect the looper's
616 : * reference count.
617 : */
618 0 : SkDrawLooper* getLooper() const { return fLooper; }
619 :
620 : /**
621 : * Set or clear the looper object.
622 : * <p />
623 : * Pass NULL to clear any previous looper.
624 : * As a convenience, the parameter passed is also returned.
625 : * If a previous looper exists in the paint, its reference count is
626 : * decremented. If looper is not NULL, its reference count is
627 : * incremented.
628 : * @param looper May be NULL. The new looper to be installed in the paint.
629 : * @return looper
630 : */
631 : SkDrawLooper* setLooper(SkDrawLooper* looper);
632 :
633 : enum Align {
634 : kLeft_Align,
635 : kCenter_Align,
636 : kRight_Align,
637 :
638 : kAlignCount
639 : };
640 :
641 : /** Return the paint's Align value for drawing text.
642 : @return the paint's Align value for drawing text.
643 : */
644 0 : Align getTextAlign() const { return (Align)fTextAlign; }
645 :
646 : /** Set the paint's text alignment.
647 : @param align set the paint's Align value for drawing text.
648 : */
649 : void setTextAlign(Align align);
650 :
651 : /** Return the paint's text size.
652 : @return the paint's text size.
653 : */
654 0 : SkScalar getTextSize() const { return fTextSize; }
655 :
656 : /** Set the paint's text size. This value must be > 0
657 : @param textSize set the paint's text size.
658 : */
659 : void setTextSize(SkScalar textSize);
660 :
661 : /** Return the paint's horizontal scale factor for text. The default value
662 : is 1.0.
663 : @return the paint's scale factor in X for drawing/measuring text
664 : */
665 0 : SkScalar getTextScaleX() const { return fTextScaleX; }
666 :
667 : /** Set the paint's horizontal scale factor for text. The default value
668 : is 1.0. Values > 1.0 will stretch the text wider. Values < 1.0 will
669 : stretch the text narrower.
670 : @param scaleX set the paint's scale factor in X for drawing/measuring
671 : text.
672 : */
673 : void setTextScaleX(SkScalar scaleX);
674 :
675 : /** Return the paint's horizontal skew factor for text. The default value
676 : is 0.
677 : @return the paint's skew factor in X for drawing text.
678 : */
679 0 : SkScalar getTextSkewX() const { return fTextSkewX; }
680 :
681 : /** Set the paint's horizontal skew factor for text. The default value
682 : is 0. For approximating oblique text, use values around -0.25.
683 : @param skewX set the paint's skew factor in X for drawing text.
684 : */
685 : void setTextSkewX(SkScalar skewX);
686 :
687 : /** Describes how to interpret the text parameters that are passed to paint
688 : methods like measureText() and getTextWidths().
689 : */
690 : enum TextEncoding {
691 : kUTF8_TextEncoding, //!< the text parameters are UTF8
692 : kUTF16_TextEncoding, //!< the text parameters are UTF16
693 : kGlyphID_TextEncoding //!< the text parameters are glyph indices
694 : };
695 :
696 0 : TextEncoding getTextEncoding() const { return (TextEncoding)fTextEncoding; }
697 :
698 : void setTextEncoding(TextEncoding encoding);
699 :
700 : struct FontMetrics {
701 : SkScalar fTop; //!< The greatest distance above the baseline for any glyph (will be <= 0)
702 : SkScalar fAscent; //!< The recommended distance above the baseline (will be <= 0)
703 : SkScalar fDescent; //!< The recommended distance below the baseline (will be >= 0)
704 : SkScalar fBottom; //!< The greatest distance below the baseline for any glyph (will be >= 0)
705 : SkScalar fLeading; //!< The recommended distance to add between lines of text (will be >= 0)
706 : SkScalar fAvgCharWidth; //!< the average charactor width (>= 0)
707 : SkScalar fXMin; //!< The minimum bounding box x value for all glyphs
708 : SkScalar fXMax; //!< The maximum bounding box x value for all glyphs
709 : SkScalar fXHeight; //!< the height of an 'x' in px, or 0 if no 'x' in face
710 : };
711 :
712 : /** Return the recommend spacing between lines (which will be
713 : fDescent - fAscent + fLeading).
714 : If metrics is not null, return in it the font metrics for the
715 : typeface/pointsize/etc. currently set in the paint.
716 : @param metrics If not null, returns the font metrics for the
717 : current typeface/pointsize/etc setting in this
718 : paint.
719 : @param scale If not 0, return width as if the canvas were scaled
720 : by this value
721 : @param return the recommended spacing between lines
722 : */
723 : SkScalar getFontMetrics(FontMetrics* metrics, SkScalar scale = 0) const;
724 :
725 : /** Return the recommend line spacing. This will be
726 : fDescent - fAscent + fLeading
727 : */
728 : SkScalar getFontSpacing() const { return this->getFontMetrics(NULL, 0); }
729 :
730 : /** Convert the specified text into glyph IDs, returning the number of
731 : glyphs ID written. If glyphs is NULL, it is ignore and only the count
732 : is returned.
733 : */
734 : int textToGlyphs(const void* text, size_t byteLength,
735 : uint16_t glyphs[]) const;
736 :
737 : /** Return true if all of the specified text has a corresponding non-zero
738 : glyph ID. If any of the code-points in the text are not supported in
739 : the typeface (i.e. the glyph ID would be zero), then return false.
740 :
741 : If the text encoding for the paint is kGlyph_TextEncoding, then this
742 : returns true if all of the specified glyph IDs are non-zero.
743 : */
744 : bool containsText(const void* text, size_t byteLength) const;
745 :
746 : /** Convert the glyph array into Unichars. Unconvertable glyphs are mapped
747 : to zero. Note: this does not look at the text-encoding setting in the
748 : paint, only at the typeface.
749 : */
750 : void glyphsToUnichars(const uint16_t glyphs[], int count,
751 : SkUnichar text[]) const;
752 :
753 : /** Return the number of drawable units in the specified text buffer.
754 : This looks at the current TextEncoding field of the paint. If you also
755 : want to have the text converted into glyph IDs, call textToGlyphs
756 : instead.
757 : */
758 0 : int countText(const void* text, size_t byteLength) const {
759 0 : return this->textToGlyphs(text, byteLength, NULL);
760 : }
761 :
762 : /** Return the width of the text. This will return the vertical measure
763 : * if isVerticalText() is true, in which case the returned value should
764 : * be treated has a height instead of a width.
765 : *
766 : * @param text The text to be measured
767 : * @param length Number of bytes of text to measure
768 : * @param bounds If not NULL, returns the bounds of the text,
769 : * relative to (0, 0).
770 : * @param scale If not 0, return width as if the canvas were scaled
771 : * by this value
772 : * @return The advance width of the text
773 : */
774 : SkScalar measureText(const void* text, size_t length,
775 : SkRect* bounds, SkScalar scale = 0) const;
776 :
777 : /** Return the width of the text. This will return the vertical measure
778 : * if isVerticalText() is true, in which case the returned value should
779 : * be treated has a height instead of a width.
780 : *
781 : * @param text Address of the text
782 : * @param length Number of bytes of text to measure
783 : * @return The width of the text
784 : */
785 0 : SkScalar measureText(const void* text, size_t length) const {
786 0 : return this->measureText(text, length, NULL, 0);
787 : }
788 :
789 : /** Specify the direction the text buffer should be processed in breakText()
790 : */
791 : enum TextBufferDirection {
792 : /** When measuring text for breakText(), begin at the start of the text
793 : buffer and proceed forward through the data. This is the default.
794 : */
795 : kForward_TextBufferDirection,
796 : /** When measuring text for breakText(), begin at the end of the text
797 : buffer and proceed backwards through the data.
798 : */
799 : kBackward_TextBufferDirection
800 : };
801 :
802 : /** Return the number of bytes of text that were measured. If
803 : * isVerticalText() is true, then the vertical advances are used for
804 : * the measurement.
805 : *
806 : * @param text The text to be measured
807 : * @param length Number of bytes of text to measure
808 : * @param maxWidth Maximum width. Only the subset of text whose accumulated
809 : * widths are <= maxWidth are measured.
810 : * @param measuredWidth Optional. If non-null, this returns the actual
811 : * width of the measured text.
812 : * @param tbd Optional. The direction the text buffer should be
813 : * traversed during measuring.
814 : * @return The number of bytes of text that were measured. Will be
815 : * <= length.
816 : */
817 : size_t breakText(const void* text, size_t length, SkScalar maxWidth,
818 : SkScalar* measuredWidth = NULL,
819 : TextBufferDirection tbd = kForward_TextBufferDirection)
820 : const;
821 :
822 : /** Return the advances for the text. These will be vertical advances if
823 : * isVerticalText() returns true.
824 : *
825 : * @param text the text
826 : * @param byteLength number of bytes to of text
827 : * @param widths If not null, returns the array of advances for
828 : * the glyphs. If not NULL, must be at least a large
829 : * as the number of unichars in the specified text.
830 : * @param bounds If not null, returns the bounds for each of
831 : * character, relative to (0, 0)
832 : * @return the number of unichars in the specified text.
833 : */
834 : int getTextWidths(const void* text, size_t byteLength, SkScalar widths[],
835 : SkRect bounds[] = NULL) const;
836 :
837 : /** Return the path (outline) for the specified text.
838 : Note: just like SkCanvas::drawText, this will respect the Align setting
839 : in the paint.
840 : */
841 : void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y,
842 : SkPath* path) const;
843 :
844 : void getPosTextPath(const void* text, size_t length,
845 : const SkPoint pos[], SkPath* path) const;
846 :
847 : #ifdef SK_BUILD_FOR_ANDROID
848 : const SkGlyph& getUnicharMetrics(SkUnichar);
849 : const void* findImage(const SkGlyph&);
850 :
851 : uint32_t getGenerationID() const;
852 : #endif
853 :
854 : // returns true if the paint's settings (e.g. xfermode + alpha) resolve to
855 : // mean that we need not draw at all (e.g. SrcOver + 0-alpha)
856 : bool nothingToDraw() const;
857 :
858 : private:
859 : SkTypeface* fTypeface;
860 : SkScalar fTextSize;
861 : SkScalar fTextScaleX;
862 : SkScalar fTextSkewX;
863 :
864 : SkPathEffect* fPathEffect;
865 : SkShader* fShader;
866 : SkXfermode* fXfermode;
867 : SkMaskFilter* fMaskFilter;
868 : SkColorFilter* fColorFilter;
869 : SkRasterizer* fRasterizer;
870 : SkDrawLooper* fLooper;
871 : SkImageFilter* fImageFilter;
872 :
873 : SkColor fColor;
874 : SkScalar fWidth;
875 : SkScalar fMiterLimit;
876 : unsigned fFlags : 14;
877 : unsigned fTextAlign : 2;
878 : unsigned fCapType : 2;
879 : unsigned fJoinType : 2;
880 : unsigned fStyle : 2;
881 : unsigned fTextEncoding : 2; // 3 values
882 : unsigned fHinting : 2;
883 :
884 : SkDrawCacheProc getDrawCacheProc() const;
885 : SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir,
886 : bool needFullMetrics) const;
887 :
888 : SkScalar measure_text(SkGlyphCache*, const char* text, size_t length,
889 : int* count, SkRect* bounds) const;
890 :
891 : SkGlyphCache* detachCache(const SkMatrix*) const;
892 :
893 : void descriptorProc(const SkMatrix* deviceMatrix,
894 : void (*proc)(const SkDescriptor*, void*),
895 : void* context, bool ignoreGamma = false) const;
896 :
897 : const SkRect& computeStrokeFastBounds(const SkRect& orig,
898 : SkRect* storage) const;
899 :
900 : enum {
901 : kCanonicalTextSizeForPaths = 64
902 : };
903 : friend class SkAutoGlyphCache;
904 : friend class SkCanvas;
905 : friend class SkDraw;
906 : friend class SkPDFDevice;
907 : friend class SkTextToPathIter;
908 :
909 : #ifdef SK_BUILD_FOR_ANDROID
910 : // In order for the == operator to work properly this must be the last field
911 : // in the struct so that we can do a memcmp to this field's offset.
912 : uint32_t fGenerationID;
913 : #endif
914 : };
915 :
916 : ///////////////////////////////////////////////////////////////////////////////
917 :
918 : #include "SkPathEffect.h"
919 :
920 : /** \class SkStrokePathEffect
921 :
922 : SkStrokePathEffect simulates stroking inside a patheffect, allowing the
923 : caller to have explicit control of when to stroke a path. Typically this is
924 : used if the caller wants to stroke before another patheffect is applied
925 : (using SkComposePathEffect or SkSumPathEffect).
926 : */
927 0 : class SkStrokePathEffect : public SkPathEffect {
928 : public:
929 : SkStrokePathEffect(const SkPaint&);
930 : SkStrokePathEffect(SkScalar width, SkPaint::Style, SkPaint::Join,
931 : SkPaint::Cap, SkScalar miterLimit = -1);
932 :
933 : // overrides
934 : virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
935 :
936 : // overrides for SkFlattenable
937 : virtual void flatten(SkFlattenableWriteBuffer&);
938 : virtual Factory getFactory();
939 :
940 : static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
941 :
942 : private:
943 : SkScalar fWidth, fMiter;
944 : uint8_t fStyle, fJoin, fCap;
945 :
946 : SkStrokePathEffect(SkFlattenableReadBuffer&);
947 :
948 : typedef SkPathEffect INHERITED;
949 :
950 : // illegal
951 : SkStrokePathEffect(const SkStrokePathEffect&);
952 : SkStrokePathEffect& operator=(const SkStrokePathEffect&);
953 : };
954 :
955 : #endif
956 :
|