Home | History | Annotate | Download | only in core
      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