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 17 static bool changes_alpha(const SkPaint& paint) { 18 SkColorFilter* cf = paint.getColorFilter(); 19 return cf && !(cf->getFlags() & SkColorFilter::kAlphaUnchanged_Flag); 20 } 21 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 49 bool SkPaintPriv::Overwrites(const SkBitmap& bitmap, const SkPaint* paint) { 50 return Overwrites(paint, bitmap.isOpaque() ? kOpaque_ShaderOverrideOpacity 51 : kNotOpaque_ShaderOverrideOpacity); 52 } 53 54 bool SkPaintPriv::Overwrites(const SkImage* image, const SkPaint* paint) { 55 return Overwrites(paint, image->isOpaque() ? kOpaque_ShaderOverrideOpacity 56 : kNotOpaque_ShaderOverrideOpacity); 57 } 58 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 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 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