1 /*
2  * Copyright 2013 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "SkBitmap.h"
9 #include "SkColorFilter.h"
10 #include "SkPaintPriv.h"
11 #include "SkImage.h"
12 #include "SkPaint.h"
13 #include "SkShaderBase.h"
14 #include "SkUtils.h"
15 #include "SkXfermodePriv.h"
16 
changes_alpha(const SkPaint & paint)17 static bool changes_alpha(const SkPaint& paint) {
18     SkColorFilter* cf = paint.getColorFilter();
19     return cf && !(cf->getFlags() & SkColorFilter::kAlphaUnchanged_Flag);
20 }
21 
Overwrites(const SkPaint * paint,ShaderOverrideOpacity overrideOpacity)22 bool SkPaintPriv::Overwrites(const SkPaint* paint, ShaderOverrideOpacity overrideOpacity) {
23     if (!paint) {
24         // No paint means we default to SRC_OVER, so we overwrite iff our shader-override
25         // is opaque, or we don't have one.
26         return overrideOpacity != kNotOpaque_ShaderOverrideOpacity;
27     }
28 
29     SkXfermode::SrcColorOpacity opacityType = SkXfermode::kUnknown_SrcColorOpacity;
30 
31     if (!changes_alpha(*paint)) {
32         const unsigned paintAlpha = paint->getAlpha();
33         if (0xff == paintAlpha && overrideOpacity != kNotOpaque_ShaderOverrideOpacity &&
34             (!paint->getShader() || paint->getShader()->isOpaque()))
35         {
36             opacityType = SkXfermode::kOpaque_SrcColorOpacity;
37         } else if (0 == paintAlpha) {
38             if (overrideOpacity == kNone_ShaderOverrideOpacity && !paint->getShader()) {
39                 opacityType = SkXfermode::kTransparentBlack_SrcColorOpacity;
40             } else {
41                 opacityType = SkXfermode::kTransparentAlpha_SrcColorOpacity;
42             }
43         }
44     }
45 
46     return SkXfermode::IsOpaque(paint->getBlendMode(), opacityType);
47 }
48 
Overwrites(const SkBitmap & bitmap,const SkPaint * paint)49 bool SkPaintPriv::Overwrites(const SkBitmap& bitmap, const SkPaint* paint) {
50     return Overwrites(paint, bitmap.isOpaque() ? kOpaque_ShaderOverrideOpacity
51                                                : kNotOpaque_ShaderOverrideOpacity);
52 }
53 
Overwrites(const SkImage * image,const SkPaint * paint)54 bool SkPaintPriv::Overwrites(const SkImage* image, const SkPaint* paint) {
55     return Overwrites(paint, image->isOpaque() ? kOpaque_ShaderOverrideOpacity
56                                                : kNotOpaque_ShaderOverrideOpacity);
57 }
58 
ScaleFontMetrics(SkPaint::FontMetrics * metrics,SkScalar scale)59 void SkPaintPriv::ScaleFontMetrics(SkPaint::FontMetrics* metrics, SkScalar scale) {
60     metrics->fTop *= scale;
61     metrics->fAscent *= scale;
62     metrics->fDescent *= scale;
63     metrics->fBottom *= scale;
64     metrics->fLeading *= scale;
65     metrics->fAvgCharWidth *= scale;
66     metrics->fMaxCharWidth *= scale;
67     metrics->fXMin *= scale;
68     metrics->fXMax *= scale;
69     metrics->fXHeight *= scale;
70     metrics->fCapHeight *= scale;
71     metrics->fUnderlineThickness *= scale;
72     metrics->fUnderlinePosition *= scale;
73     metrics->fStrikeoutThickness *= scale;
74     metrics->fStrikeoutPosition *= scale;
75 }
76 
ShouldDither(const SkPaint & p,SkColorType dstCT)77 bool SkPaintPriv::ShouldDither(const SkPaint& p, SkColorType dstCT) {
78     // The paint dither flag can veto.
79     if (!p.isDither()) {
80         return false;
81     }
82 
83     // We always dither 565 or 4444 when requested.
84     if (dstCT == kRGB_565_SkColorType || dstCT == kARGB_4444_SkColorType) {
85         return true;
86     }
87 
88     // Otherwise, dither is only needed for non-const paints.
89     return p.getImageFilter() || p.getMaskFilter()
90         || !p.getShader() || !as_SB(p.getShader())->isConstant();
91 }
92 
ValidCountText(const void * text,size_t length,SkPaint::TextEncoding encoding)93 int SkPaintPriv::ValidCountText(const void* text, size_t length, SkPaint::TextEncoding encoding) {
94     if (length == 0) {
95         return 0;
96     }
97     switch (encoding) {
98         case SkPaint::kUTF8_TextEncoding: return SkUTF8_CountUnichars(text, length);
99         case SkPaint::kUTF16_TextEncoding: return SkUTF16_CountUnichars(text, length);
100         case SkPaint::kUTF32_TextEncoding: return SkUTF32_CountUnichars(text, length);
101         case SkPaint::kGlyphID_TextEncoding:
102             if (SkIsAlign2(intptr_t(text)) && SkIsAlign2(length)) {
103                 return length >> 1;
104             }
105             break;
106     }
107     return 0;
108 }
109 
110