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 "SkXfermodePriv.h"
15
changes_alpha(const SkPaint & paint)16 static bool changes_alpha(const SkPaint& paint) {
17 SkColorFilter* cf = paint.getColorFilter();
18 return cf && !(cf->getFlags() & SkColorFilter::kAlphaUnchanged_Flag);
19 }
20
Overwrites(const SkPaint * paint,ShaderOverrideOpacity overrideOpacity)21 bool SkPaintPriv::Overwrites(const SkPaint* paint, ShaderOverrideOpacity overrideOpacity) {
22 if (!paint) {
23 // No paint means we default to SRC_OVER, so we overwrite iff our shader-override
24 // is opaque, or we don't have one.
25 return overrideOpacity != kNotOpaque_ShaderOverrideOpacity;
26 }
27
28 SkXfermode::SrcColorOpacity opacityType = SkXfermode::kUnknown_SrcColorOpacity;
29
30 if (!changes_alpha(*paint)) {
31 const unsigned paintAlpha = paint->getAlpha();
32 if (0xff == paintAlpha && overrideOpacity != kNotOpaque_ShaderOverrideOpacity &&
33 (!paint->getShader() || paint->getShader()->isOpaque()))
34 {
35 opacityType = SkXfermode::kOpaque_SrcColorOpacity;
36 } else if (0 == paintAlpha) {
37 if (overrideOpacity == kNone_ShaderOverrideOpacity && !paint->getShader()) {
38 opacityType = SkXfermode::kTransparentBlack_SrcColorOpacity;
39 } else {
40 opacityType = SkXfermode::kTransparentAlpha_SrcColorOpacity;
41 }
42 }
43 }
44
45 return SkXfermode::IsOpaque(paint->getBlendMode(), opacityType);
46 }
47
Overwrites(const SkBitmap & bitmap,const SkPaint * paint)48 bool SkPaintPriv::Overwrites(const SkBitmap& bitmap, const SkPaint* paint) {
49 return Overwrites(paint, bitmap.isOpaque() ? kOpaque_ShaderOverrideOpacity
50 : kNotOpaque_ShaderOverrideOpacity);
51 }
52
Overwrites(const SkImage * image,const SkPaint * paint)53 bool SkPaintPriv::Overwrites(const SkImage* image, const SkPaint* paint) {
54 return Overwrites(paint, image->isOpaque() ? kOpaque_ShaderOverrideOpacity
55 : kNotOpaque_ShaderOverrideOpacity);
56 }
57
ScaleFontMetrics(SkPaint::FontMetrics * metrics,SkScalar scale)58 void SkPaintPriv::ScaleFontMetrics(SkPaint::FontMetrics* metrics, SkScalar scale) {
59 metrics->fTop *= scale;
60 metrics->fAscent *= scale;
61 metrics->fDescent *= scale;
62 metrics->fBottom *= scale;
63 metrics->fLeading *= scale;
64 metrics->fAvgCharWidth *= scale;
65 metrics->fXMin *= scale;
66 metrics->fXMax *= scale;
67 metrics->fXHeight *= scale;
68 metrics->fUnderlineThickness *= scale;
69 metrics->fUnderlinePosition *= scale;
70 }
71
ShouldDither(const SkPaint & p,SkColorType dstCT)72 bool SkPaintPriv::ShouldDither(const SkPaint& p, SkColorType dstCT) {
73 // The paint dither flag can veto.
74 if (!p.isDither()) {
75 return false;
76 }
77
78 // We always dither 565 or 4444 when requested.
79 if (dstCT == kRGB_565_SkColorType || dstCT == kARGB_4444_SkColorType) {
80 return true;
81 }
82
83 // Otherwise, dither is only needed for non-const paints.
84 return p.getImageFilter() || p.getMaskFilter()
85 || !p.getShader() || !as_SB(p.getShader())->isConstant();
86 }
87