Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(814)

Side by Side Diff: src/core/SkPaint.cpp

Issue 158913005: Merge tomhudson and mtklein SkPaint shrinking approaches. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Don't unref typeface. Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « include/core/SkPaint.h ('k') | src/core/SkPictureFlat.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "SkPaint.h" 9 #include "SkPaint.h"
10 #include "SkAnnotation.h" 10 #include "SkAnnotation.h"
(...skipping 17 matching lines...) Expand all
28 #include "SkScalerContext.h" 28 #include "SkScalerContext.h"
29 #include "SkShader.h" 29 #include "SkShader.h"
30 #include "SkStringUtils.h" 30 #include "SkStringUtils.h"
31 #include "SkStroke.h" 31 #include "SkStroke.h"
32 #include "SkTextFormatParams.h" 32 #include "SkTextFormatParams.h"
33 #include "SkTextToPathIter.h" 33 #include "SkTextToPathIter.h"
34 #include "SkTLazy.h" 34 #include "SkTLazy.h"
35 #include "SkTypeface.h" 35 #include "SkTypeface.h"
36 #include "SkXfermode.h" 36 #include "SkXfermode.h"
37 37
38 enum {
39 kColor_DirtyBit = 1 << 0,
40 kBitfields_DirtyBit = 1 << 1,
41 kTextSize_DirtyBit = 1 << 2,
42 kTextScaleX_DirtyBit = 1 << 3,
43 kTextSkewX_DirtyBit = 1 << 4,
44 kStrokeWidth_DirtyBit = 1 << 5,
45 kStrokeMiter_DirtyBit = 1 << 6,
46 kPathEffect_DirtyBit = 1 << 7,
47 kShader_DirtyBit = 1 << 8,
48 kXfermode_DirtyBit = 1 << 9,
49 kMaskFilter_DirtyBit = 1 << 10,
50 kColorFilter_DirtyBit = 1 << 11,
51 kRasterizer_DirtyBit = 1 << 12,
52 kLooper_DirtyBit = 1 << 13,
53 kImageFilter_DirtyBit = 1 << 14,
54 kTypeface_DirtyBit = 1 << 15,
55 kAnnotation_DirtyBit = 1 << 16,
56 kPaintOptionsAndroid_DirtyBit = 1 << 17,
57 };
38 58
39 // define this to get a printf for out-of-range parameter in setters 59 // define this to get a printf for out-of-range parameter in setters
40 // e.g. setTextSize(-1) 60 // e.g. setTextSize(-1)
41 //#define SK_REPORT_API_RANGE_CHECK 61 //#define SK_REPORT_API_RANGE_CHECK
42 62
43 #ifdef SK_BUILD_FOR_ANDROID 63 #ifdef SK_BUILD_FOR_ANDROID
44 #define GEN_ID_INC fGenerationID++ 64 #define GEN_ID_INC fGenerationID++
45 #define GEN_ID_INC_EVAL(expression) if (expression) { fGenerationID++; } 65 #define GEN_ID_INC_EVAL(expression) if (expression) { fGenerationID++; }
46 #else 66 #else
47 #define GEN_ID_INC 67 #define GEN_ID_INC
48 #define GEN_ID_INC_EVAL(expression) 68 #define GEN_ID_INC_EVAL(expression)
49 #endif 69 #endif
50 70
51 SkPaint::SkPaint() { 71 SkPaint::SkPaint() {
52 // since we may have padding, we zero everything so that our memcmp() call 72 // since we may have padding, we zero everything so that our memcmp() call
53 // in operator== will work correctly. 73 // in operator== will work correctly.
54 // with this, we can skip 0 and null individual initializations 74 // with this, we can skip 0 and null individual initializations
55 sk_bzero(this, sizeof(*this)); 75 sk_bzero(this, sizeof(*this));
56 76
57 #if 0 // not needed with the bzero call above 77 #if 0 // not needed with the bzero call above
58 fTypeface = NULL; 78 fTypeface = NULL;
59 fTextSkewX = 0; 79 fTextSkewX = 0;
60 fPathEffect = NULL; 80 fPathEffect = NULL;
61 fShader = NULL; 81 fShader = NULL;
62 fXfermode = NULL; 82 fXfermode = NULL;
63 fMaskFilter = NULL; 83 fMaskFilter = NULL;
64 fColorFilter = NULL; 84 fColorFilter = NULL;
65 fRasterizer = NULL; 85 fRasterizer = NULL;
66 fLooper = NULL; 86 fLooper = NULL;
67 fImageFilter = NULL; 87 fImageFilter = NULL;
68 fAnnotation = NULL; 88 fAnnotation = NULL;
69 fWidth = 0; 89 fWidth = 0;
90 fDirtyBits = 0;
70 #endif 91 #endif
71 92
72 fTextSize = SkPaintDefaults_TextSize; 93 fTextSize = SkPaintDefaults_TextSize;
73 fTextScaleX = SK_Scalar1; 94 fTextScaleX = SK_Scalar1;
74 fColor = SK_ColorBLACK; 95 fColor = SK_ColorBLACK;
75 fMiterLimit = SkPaintDefaults_MiterLimit; 96 fMiterLimit = SkPaintDefaults_MiterLimit;
76 fFlags = SkPaintDefaults_Flags; 97 fFlags = SkPaintDefaults_Flags;
77 fCapType = kDefault_Cap; 98 fCapType = kDefault_Cap;
78 fJoinType = kDefault_Join; 99 fJoinType = kDefault_Join;
79 fTextAlign = kLeft_Align; 100 fTextAlign = kLeft_Align;
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 unsigned SkPaint::getBaseGlyphCount(SkUnichar text) const { 212 unsigned SkPaint::getBaseGlyphCount(SkUnichar text) const {
192 SkAutoGlyphCache autoCache(*this, NULL, NULL); 213 SkAutoGlyphCache autoCache(*this, NULL, NULL);
193 SkGlyphCache* cache = autoCache.getCache(); 214 SkGlyphCache* cache = autoCache.getCache();
194 return cache->getBaseGlyphCount(text); 215 return cache->getBaseGlyphCount(text);
195 } 216 }
196 217
197 void SkPaint::setPaintOptionsAndroid(const SkPaintOptionsAndroid& options) { 218 void SkPaint::setPaintOptionsAndroid(const SkPaintOptionsAndroid& options) {
198 if (options != fPaintOptionsAndroid) { 219 if (options != fPaintOptionsAndroid) {
199 fPaintOptionsAndroid = options; 220 fPaintOptionsAndroid = options;
200 GEN_ID_INC; 221 GEN_ID_INC;
222 fDirtyBits |= kPaintOptionsAndroid_DirtyBit;
201 } 223 }
202 } 224 }
203 #endif 225 #endif
204 226
205 SkPaint::FilterLevel SkPaint::getFilterLevel() const { 227 SkPaint::FilterLevel SkPaint::getFilterLevel() const {
206 int level = 0; 228 int level = 0;
207 if (fFlags & kFilterBitmap_Flag) { 229 if (fFlags & kFilterBitmap_Flag) {
208 level |= 1; 230 level |= 1;
209 } 231 }
210 if (fFlags & kHighQualityFilterBitmap_Flag) { 232 if (fFlags & kHighQualityFilterBitmap_Flag) {
(...skipping 10 matching lines...) Expand all
221 } 243 }
222 if (level & 2) { 244 if (level & 2) {
223 flags |= kHighQualityFilterBitmap_Flag; 245 flags |= kHighQualityFilterBitmap_Flag;
224 } 246 }
225 this->setFlags((fFlags & ~mask) | flags); 247 this->setFlags((fFlags & ~mask) | flags);
226 } 248 }
227 249
228 void SkPaint::setHinting(Hinting hintingLevel) { 250 void SkPaint::setHinting(Hinting hintingLevel) {
229 GEN_ID_INC_EVAL((unsigned) hintingLevel != fHinting); 251 GEN_ID_INC_EVAL((unsigned) hintingLevel != fHinting);
230 fHinting = hintingLevel; 252 fHinting = hintingLevel;
253 fDirtyBits |= kBitfields_DirtyBit;
231 } 254 }
232 255
233 void SkPaint::setFlags(uint32_t flags) { 256 void SkPaint::setFlags(uint32_t flags) {
234 GEN_ID_INC_EVAL(fFlags != flags); 257 GEN_ID_INC_EVAL(fFlags != flags);
235 fFlags = flags; 258 fFlags = flags;
259 fDirtyBits |= kBitfields_DirtyBit;
236 } 260 }
237 261
238 void SkPaint::setAntiAlias(bool doAA) { 262 void SkPaint::setAntiAlias(bool doAA) {
239 this->setFlags(SkSetClearMask(fFlags, doAA, kAntiAlias_Flag)); 263 this->setFlags(SkSetClearMask(fFlags, doAA, kAntiAlias_Flag));
240 } 264 }
241 265
242 void SkPaint::setDither(bool doDither) { 266 void SkPaint::setDither(bool doDither) {
243 this->setFlags(SkSetClearMask(fFlags, doDither, kDither_Flag)); 267 this->setFlags(SkSetClearMask(fFlags, doDither, kDither_Flag));
244 } 268 }
245 269
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 } 304 }
281 305
282 void SkPaint::setDevKernText(bool doDevKern) { 306 void SkPaint::setDevKernText(bool doDevKern) {
283 this->setFlags(SkSetClearMask(fFlags, doDevKern, kDevKernText_Flag)); 307 this->setFlags(SkSetClearMask(fFlags, doDevKern, kDevKernText_Flag));
284 } 308 }
285 309
286 void SkPaint::setStyle(Style style) { 310 void SkPaint::setStyle(Style style) {
287 if ((unsigned)style < kStyleCount) { 311 if ((unsigned)style < kStyleCount) {
288 GEN_ID_INC_EVAL((unsigned)style != fStyle); 312 GEN_ID_INC_EVAL((unsigned)style != fStyle);
289 fStyle = style; 313 fStyle = style;
314 fDirtyBits |= kBitfields_DirtyBit;
290 } else { 315 } else {
291 #ifdef SK_REPORT_API_RANGE_CHECK 316 #ifdef SK_REPORT_API_RANGE_CHECK
292 SkDebugf("SkPaint::setStyle(%d) out of range\n", style); 317 SkDebugf("SkPaint::setStyle(%d) out of range\n", style);
293 #endif 318 #endif
294 } 319 }
295 } 320 }
296 321
297 void SkPaint::setColor(SkColor color) { 322 void SkPaint::setColor(SkColor color) {
298 GEN_ID_INC_EVAL(color != fColor); 323 GEN_ID_INC_EVAL(color != fColor);
299 fColor = color; 324 fColor = color;
325 fDirtyBits |= kColor_DirtyBit;
300 } 326 }
301 327
302 void SkPaint::setAlpha(U8CPU a) { 328 void SkPaint::setAlpha(U8CPU a) {
303 this->setColor(SkColorSetARGB(a, SkColorGetR(fColor), 329 this->setColor(SkColorSetARGB(a, SkColorGetR(fColor),
304 SkColorGetG(fColor), SkColorGetB(fColor))); 330 SkColorGetG(fColor), SkColorGetB(fColor)));
305 } 331 }
306 332
307 void SkPaint::setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { 333 void SkPaint::setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
308 this->setColor(SkColorSetARGB(a, r, g, b)); 334 this->setColor(SkColorSetARGB(a, r, g, b));
309 } 335 }
310 336
311 void SkPaint::setStrokeWidth(SkScalar width) { 337 void SkPaint::setStrokeWidth(SkScalar width) {
312 if (width >= 0) { 338 if (width >= 0) {
313 GEN_ID_INC_EVAL(width != fWidth); 339 GEN_ID_INC_EVAL(width != fWidth);
314 fWidth = width; 340 fWidth = width;
341 fDirtyBits |= kStrokeWidth_DirtyBit;
315 } else { 342 } else {
316 #ifdef SK_REPORT_API_RANGE_CHECK 343 #ifdef SK_REPORT_API_RANGE_CHECK
317 SkDebugf("SkPaint::setStrokeWidth() called with negative value\n"); 344 SkDebugf("SkPaint::setStrokeWidth() called with negative value\n");
318 #endif 345 #endif
319 } 346 }
320 } 347 }
321 348
322 void SkPaint::setStrokeMiter(SkScalar limit) { 349 void SkPaint::setStrokeMiter(SkScalar limit) {
323 if (limit >= 0) { 350 if (limit >= 0) {
324 GEN_ID_INC_EVAL(limit != fMiterLimit); 351 GEN_ID_INC_EVAL(limit != fMiterLimit);
325 fMiterLimit = limit; 352 fMiterLimit = limit;
353 fDirtyBits |= kStrokeMiter_DirtyBit;
326 } else { 354 } else {
327 #ifdef SK_REPORT_API_RANGE_CHECK 355 #ifdef SK_REPORT_API_RANGE_CHECK
328 SkDebugf("SkPaint::setStrokeMiter() called with negative value\n"); 356 SkDebugf("SkPaint::setStrokeMiter() called with negative value\n");
329 #endif 357 #endif
330 } 358 }
331 } 359 }
332 360
333 void SkPaint::setStrokeCap(Cap ct) { 361 void SkPaint::setStrokeCap(Cap ct) {
334 if ((unsigned)ct < kCapCount) { 362 if ((unsigned)ct < kCapCount) {
335 GEN_ID_INC_EVAL((unsigned)ct != fCapType); 363 GEN_ID_INC_EVAL((unsigned)ct != fCapType);
336 fCapType = SkToU8(ct); 364 fCapType = SkToU8(ct);
365 fDirtyBits |= kBitfields_DirtyBit;
337 } else { 366 } else {
338 #ifdef SK_REPORT_API_RANGE_CHECK 367 #ifdef SK_REPORT_API_RANGE_CHECK
339 SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct); 368 SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct);
340 #endif 369 #endif
341 } 370 }
342 } 371 }
343 372
344 void SkPaint::setStrokeJoin(Join jt) { 373 void SkPaint::setStrokeJoin(Join jt) {
345 if ((unsigned)jt < kJoinCount) { 374 if ((unsigned)jt < kJoinCount) {
346 GEN_ID_INC_EVAL((unsigned)jt != fJoinType); 375 GEN_ID_INC_EVAL((unsigned)jt != fJoinType);
347 fJoinType = SkToU8(jt); 376 fJoinType = SkToU8(jt);
377 fDirtyBits |= kBitfields_DirtyBit;
348 } else { 378 } else {
349 #ifdef SK_REPORT_API_RANGE_CHECK 379 #ifdef SK_REPORT_API_RANGE_CHECK
350 SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt); 380 SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt);
351 #endif 381 #endif
352 } 382 }
353 } 383 }
354 384
355 /////////////////////////////////////////////////////////////////////////////// 385 ///////////////////////////////////////////////////////////////////////////////
356 386
357 void SkPaint::setTextAlign(Align align) { 387 void SkPaint::setTextAlign(Align align) {
358 if ((unsigned)align < kAlignCount) { 388 if ((unsigned)align < kAlignCount) {
359 GEN_ID_INC_EVAL((unsigned)align != fTextAlign); 389 GEN_ID_INC_EVAL((unsigned)align != fTextAlign);
360 fTextAlign = SkToU8(align); 390 fTextAlign = SkToU8(align);
391 fDirtyBits |= kBitfields_DirtyBit;
361 } else { 392 } else {
362 #ifdef SK_REPORT_API_RANGE_CHECK 393 #ifdef SK_REPORT_API_RANGE_CHECK
363 SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align); 394 SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align);
364 #endif 395 #endif
365 } 396 }
366 } 397 }
367 398
368 void SkPaint::setTextSize(SkScalar ts) { 399 void SkPaint::setTextSize(SkScalar ts) {
369 if (ts >= 0) { 400 if (ts >= 0) {
370 GEN_ID_INC_EVAL(ts != fTextSize); 401 GEN_ID_INC_EVAL(ts != fTextSize);
371 fTextSize = ts; 402 fTextSize = ts;
403 fDirtyBits |= kTextSize_DirtyBit;
372 } else { 404 } else {
373 #ifdef SK_REPORT_API_RANGE_CHECK 405 #ifdef SK_REPORT_API_RANGE_CHECK
374 SkDebugf("SkPaint::setTextSize() called with negative value\n"); 406 SkDebugf("SkPaint::setTextSize() called with negative value\n");
375 #endif 407 #endif
376 } 408 }
377 } 409 }
378 410
379 void SkPaint::setTextScaleX(SkScalar scaleX) { 411 void SkPaint::setTextScaleX(SkScalar scaleX) {
380 GEN_ID_INC_EVAL(scaleX != fTextScaleX); 412 GEN_ID_INC_EVAL(scaleX != fTextScaleX);
381 fTextScaleX = scaleX; 413 fTextScaleX = scaleX;
414 fDirtyBits |= kTextScaleX_DirtyBit;
382 } 415 }
383 416
384 void SkPaint::setTextSkewX(SkScalar skewX) { 417 void SkPaint::setTextSkewX(SkScalar skewX) {
385 GEN_ID_INC_EVAL(skewX != fTextSkewX); 418 GEN_ID_INC_EVAL(skewX != fTextSkewX);
386 fTextSkewX = skewX; 419 fTextSkewX = skewX;
420 fDirtyBits |= kTextSkewX_DirtyBit;
387 } 421 }
388 422
389 void SkPaint::setTextEncoding(TextEncoding encoding) { 423 void SkPaint::setTextEncoding(TextEncoding encoding) {
390 if ((unsigned)encoding <= kGlyphID_TextEncoding) { 424 if ((unsigned)encoding <= kGlyphID_TextEncoding) {
391 GEN_ID_INC_EVAL((unsigned)encoding != fTextEncoding); 425 GEN_ID_INC_EVAL((unsigned)encoding != fTextEncoding);
392 fTextEncoding = encoding; 426 fTextEncoding = encoding;
427 fDirtyBits |= kBitfields_DirtyBit;
393 } else { 428 } else {
394 #ifdef SK_REPORT_API_RANGE_CHECK 429 #ifdef SK_REPORT_API_RANGE_CHECK
395 SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding); 430 SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding);
396 #endif 431 #endif
397 } 432 }
398 } 433 }
399 434
400 /////////////////////////////////////////////////////////////////////////////// 435 ///////////////////////////////////////////////////////////////////////////////
401 436
437 // Returns dst with the given bitmask enabled or disabled, depending on value.
438 inline static uint32_t set_mask(uint32_t dst, uint32_t bitmask, bool value) {
439 return value ? (dst | bitmask) : (dst & ~bitmask);
440 }
441
402 SkTypeface* SkPaint::setTypeface(SkTypeface* font) { 442 SkTypeface* SkPaint::setTypeface(SkTypeface* font) {
403 SkRefCnt_SafeAssign(fTypeface, font); 443 SkRefCnt_SafeAssign(fTypeface, font);
404 GEN_ID_INC; 444 GEN_ID_INC;
445 fDirtyBits = set_mask(fDirtyBits, kTypeface_DirtyBit, font != NULL);
405 return font; 446 return font;
406 } 447 }
407 448
408 SkRasterizer* SkPaint::setRasterizer(SkRasterizer* r) { 449 SkRasterizer* SkPaint::setRasterizer(SkRasterizer* r) {
409 SkRefCnt_SafeAssign(fRasterizer, r); 450 SkRefCnt_SafeAssign(fRasterizer, r);
410 GEN_ID_INC; 451 GEN_ID_INC;
452 fDirtyBits = set_mask(fDirtyBits, kRasterizer_DirtyBit, r != NULL);
411 return r; 453 return r;
412 } 454 }
413 455
414 SkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper) { 456 SkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper) {
415 SkRefCnt_SafeAssign(fLooper, looper); 457 SkRefCnt_SafeAssign(fLooper, looper);
416 GEN_ID_INC; 458 GEN_ID_INC;
459 fDirtyBits = set_mask(fDirtyBits, kLooper_DirtyBit, looper != NULL);
417 return looper; 460 return looper;
418 } 461 }
419 462
420 SkImageFilter* SkPaint::setImageFilter(SkImageFilter* imageFilter) { 463 SkImageFilter* SkPaint::setImageFilter(SkImageFilter* imageFilter) {
421 SkRefCnt_SafeAssign(fImageFilter, imageFilter); 464 SkRefCnt_SafeAssign(fImageFilter, imageFilter);
422 GEN_ID_INC; 465 GEN_ID_INC;
466 fDirtyBits = set_mask(fDirtyBits, kImageFilter_DirtyBit, imageFilter != NULL );
423 return imageFilter; 467 return imageFilter;
424 } 468 }
425 469
426 SkAnnotation* SkPaint::setAnnotation(SkAnnotation* annotation) { 470 SkAnnotation* SkPaint::setAnnotation(SkAnnotation* annotation) {
427 SkRefCnt_SafeAssign(fAnnotation, annotation); 471 SkRefCnt_SafeAssign(fAnnotation, annotation);
428 GEN_ID_INC; 472 GEN_ID_INC;
473 fDirtyBits = set_mask(fDirtyBits, kAnnotation_DirtyBit, annotation != NULL);
429 return annotation; 474 return annotation;
430 } 475 }
431 476
432 /////////////////////////////////////////////////////////////////////////////// 477 ///////////////////////////////////////////////////////////////////////////////
433 478
434 static SkScalar mag2(SkScalar x, SkScalar y) { 479 static SkScalar mag2(SkScalar x, SkScalar y) {
435 return x * x + y * y; 480 return x * x + y * y;
436 } 481 }
437 482
438 static bool tooBig(const SkMatrix& m, SkScalar ma2max) { 483 static bool tooBig(const SkMatrix& m, SkScalar ma2max) {
(...skipping 1703 matching lines...) Expand 10 before | Expand all | Expand 10 after
2142 this->setPaintOptionsAndroid(options); 2187 this->setPaintOptionsAndroid(options);
2143 #endif 2188 #endif
2144 } 2189 }
2145 } 2190 }
2146 2191
2147 /////////////////////////////////////////////////////////////////////////////// 2192 ///////////////////////////////////////////////////////////////////////////////
2148 2193
2149 SkShader* SkPaint::setShader(SkShader* shader) { 2194 SkShader* SkPaint::setShader(SkShader* shader) {
2150 GEN_ID_INC_EVAL(shader != fShader); 2195 GEN_ID_INC_EVAL(shader != fShader);
2151 SkRefCnt_SafeAssign(fShader, shader); 2196 SkRefCnt_SafeAssign(fShader, shader);
2197 fDirtyBits = set_mask(fDirtyBits, kShader_DirtyBit, shader != NULL);
2152 return shader; 2198 return shader;
2153 } 2199 }
2154 2200
2155 SkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter) { 2201 SkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter) {
2156 GEN_ID_INC_EVAL(filter != fColorFilter); 2202 GEN_ID_INC_EVAL(filter != fColorFilter);
2157 SkRefCnt_SafeAssign(fColorFilter, filter); 2203 SkRefCnt_SafeAssign(fColorFilter, filter);
2204 fDirtyBits = set_mask(fDirtyBits, kColorFilter_DirtyBit, filter != NULL);
2158 return filter; 2205 return filter;
2159 } 2206 }
2160 2207
2161 SkXfermode* SkPaint::setXfermode(SkXfermode* mode) { 2208 SkXfermode* SkPaint::setXfermode(SkXfermode* mode) {
2162 GEN_ID_INC_EVAL(mode != fXfermode); 2209 GEN_ID_INC_EVAL(mode != fXfermode);
2163 SkRefCnt_SafeAssign(fXfermode, mode); 2210 SkRefCnt_SafeAssign(fXfermode, mode);
2211 fDirtyBits = set_mask(fDirtyBits, kXfermode_DirtyBit, mode != NULL);
2164 return mode; 2212 return mode;
2165 } 2213 }
2166 2214
2167 SkXfermode* SkPaint::setXfermodeMode(SkXfermode::Mode mode) { 2215 SkXfermode* SkPaint::setXfermodeMode(SkXfermode::Mode mode) {
2168 SkSafeUnref(fXfermode); 2216 SkSafeUnref(fXfermode);
2169 fXfermode = SkXfermode::Create(mode); 2217 fXfermode = SkXfermode::Create(mode);
2170 GEN_ID_INC; 2218 GEN_ID_INC;
2219 fDirtyBits = set_mask(fDirtyBits, kXfermode_DirtyBit, fXfermode != NULL);
2171 return fXfermode; 2220 return fXfermode;
2172 } 2221 }
2173 2222
2174 SkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect) { 2223 SkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect) {
2175 GEN_ID_INC_EVAL(effect != fPathEffect); 2224 GEN_ID_INC_EVAL(effect != fPathEffect);
2176 SkRefCnt_SafeAssign(fPathEffect, effect); 2225 SkRefCnt_SafeAssign(fPathEffect, effect);
2226 fDirtyBits = set_mask(fDirtyBits, kPathEffect_DirtyBit, effect != NULL);
2177 return effect; 2227 return effect;
2178 } 2228 }
2179 2229
2180 SkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter) { 2230 SkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter) {
2181 GEN_ID_INC_EVAL(filter != fMaskFilter); 2231 GEN_ID_INC_EVAL(filter != fMaskFilter);
2182 SkRefCnt_SafeAssign(fMaskFilter, filter); 2232 SkRefCnt_SafeAssign(fMaskFilter, filter);
2233 fDirtyBits = set_mask(fDirtyBits, kMaskFilter_DirtyBit, filter != NULL);
2183 return filter; 2234 return filter;
2184 } 2235 }
2185 2236
2186 /////////////////////////////////////////////////////////////////////////////// 2237 ///////////////////////////////////////////////////////////////////////////////
2187 2238
2188 bool SkPaint::getFillPath(const SkPath& src, SkPath* dst, 2239 bool SkPaint::getFillPath(const SkPath& src, SkPath* dst,
2189 const SkRect* cullRect) const { 2240 const SkRect* cullRect) const {
2190 SkStrokeRec rec(*this); 2241 SkStrokeRec rec(*this);
2191 2242
2192 const SkPath* srcPtr = &src; 2243 const SkPath* srcPtr = &src;
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
2543 case SkXfermode::kPlus_Mode: 2594 case SkXfermode::kPlus_Mode:
2544 return 0 == this->getAlpha(); 2595 return 0 == this->getAlpha();
2545 case SkXfermode::kDst_Mode: 2596 case SkXfermode::kDst_Mode:
2546 return true; 2597 return true;
2547 default: 2598 default:
2548 break; 2599 break;
2549 } 2600 }
2550 } 2601 }
2551 return false; 2602 return false;
2552 } 2603 }
2604
2605 void SkPaint::setBitfields(uint32_t bitfields) {
2606 fBitfields = bitfields;
2607 fDirtyBits |= kBitfields_DirtyBit;
2608 }
2609
2610 inline static unsigned popcount(uint8_t x) {
2611 // As in Hacker's delight, adapted for just 8 bits.
2612 x = (x & 0x55) + ((x >> 1) & 0x55); // a b c d w x y z -> a+b c+d w+x y+z
2613 x = (x & 0x33) + ((x >> 2) & 0x33); // a+b c+d w+x y+z -> a+b+c+d w+x+y+z
2614 x = (x & 0x0F) + ((x >> 4) & 0x0F); // a+b+c+d w+x+y+z -> a+b+c+d+w+x+y+z
2615 return x;
2616 }
2617
2618 void SkPaint::FlatteningTraits::Flatten(SkWriteBuffer& buffer, const SkPaint& pa int) {
2619 const uint32_t dirty = paint.fDirtyBits;
2620
2621 // Each of the low 7 dirty bits corresponds to a 4-byte flat value, plus one for the dirty bits.
2622 const size_t flatBytes = 4 * (popcount(dirty & 127) + 1);
2623 SkASSERT(flatBytes <= 32);
2624 uint32_t* u32 = buffer.reserve(flatBytes);
2625 *u32++ = dirty;
2626 if (dirty == 0) {
2627 return;
2628 }
2629
2630 #define F(dst, field) if (dirty & k##field##_DirtyBit) *dst++ = paint.get##field ()
2631 F(u32, Color);
2632 F(u32, Bitfields);
2633 SkScalar* f32 = reinterpret_cast<SkScalar*>(u32);
2634 F(f32, TextSize);
2635 F(f32, TextScaleX);
2636 F(f32, TextSkewX);
2637 F(f32, StrokeWidth);
2638 F(f32, StrokeMiter);
2639 #undef F
2640 #define F(field) if (dirty & k##field##_DirtyBit) buffer.writeFlattenable(paint. get##field())
2641 F(PathEffect);
2642 F(Shader);
2643 F(Xfermode);
2644 F(MaskFilter);
2645 F(ColorFilter);
2646 F(Rasterizer);
2647 F(Looper);
2648 F(ImageFilter);
2649 #undef F
2650 if (dirty & kTypeface_DirtyBit) buffer.writeTypeface(paint.getTypeface());
2651 if (dirty & kAnnotation_DirtyBit) paint.getAnnotation()->writeToBuffer(buffe r);
2652 #ifdef SK_BUILD_FOR_ANDROID
2653 if (dirty & kPaintOptionsAndroid_DirtyBit) paint.getPaintOptionsAndroid().fl atten(buffer);
2654 #endif
2655 }
2656
2657 void SkPaint::FlatteningTraits::Unflatten(SkReadBuffer& buffer, SkPaint* paint) {
2658 const uint32_t dirty = buffer.readUInt();
2659 if (dirty == 0) {
2660 return;
2661 }
2662 #define F(field, reader) if (dirty & k##field##_DirtyBit) paint->set##field(buff er.reader())
2663 // Same function, except it unrefs the object newly set on the paint:
2664 #define F_UNREF(field, reader) \
2665 if (dirty & k##field##_DirtyBit) \
2666 paint->set##field(buffer.reader())->unref()
2667
2668 F(Color, readUInt);
2669 F(Bitfields, readUInt);
2670 F(TextSize, readScalar);
2671 F(TextScaleX, readScalar);
2672 F(TextSkewX, readScalar);
2673 F(StrokeWidth, readScalar);
2674 F(StrokeMiter, readScalar);
2675 F_UNREF(PathEffect, readPathEffect);
2676 F_UNREF(Shader, readShader);
2677 F_UNREF(Xfermode, readXfermode);
2678 F_UNREF(MaskFilter, readMaskFilter);
2679 F_UNREF(ColorFilter, readColorFilter);
2680 F_UNREF(Rasterizer, readRasterizer);
2681 F_UNREF(Looper, readDrawLooper);
2682 F_UNREF(ImageFilter, readImageFilter);
2683 F(Typeface, readTypeface);
2684 #undef F
2685 #undef F_UNREF
2686 if (dirty & kAnnotation_DirtyBit) {
2687 paint->setAnnotation(SkNEW_ARGS(SkAnnotation, (buffer)))->unref();
2688 }
2689 #ifdef SK_BUILD_FOR_ANDROID
2690 if (dirty & kPaintOptionsAndroid_DirtyBit) {
2691 SkPaintOptionsAndroid options;
2692 options.unflatten(buffer);
2693 paint->setPaintOptionsAndroid(options);
2694 }
2695 #endif
2696 SkASSERT(dirty == paint->fDirtyBits);
2697 }
OLDNEW
« no previous file with comments | « include/core/SkPaint.h ('k') | src/core/SkPictureFlat.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698