gfx/skia/trunk/src/effects/SkLayerDrawLooper.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     2 /*
     3  * Copyright 2011 Google Inc.
     4  *
     5  * Use of this source code is governed by a BSD-style license that can be
     6  * found in the LICENSE file.
     7  */
     8 #include "SkCanvas.h"
     9 #include "SkColor.h"
    10 #include "SkReadBuffer.h"
    11 #include "SkWriteBuffer.h"
    12 #include "SkLayerDrawLooper.h"
    13 #include "SkString.h"
    14 #include "SkStringUtils.h"
    15 #include "SkUnPreMultiply.h"
    17 SkLayerDrawLooper::LayerInfo::LayerInfo() {
    18     fPaintBits = 0;                     // ignore our paint fields
    19     fColorMode = SkXfermode::kDst_Mode; // ignore our color
    20     fOffset.set(0, 0);
    21     fPostTranslate = false;
    22 }
    24 SkLayerDrawLooper::SkLayerDrawLooper()
    25         : fRecs(NULL),
    26           fTopRec(NULL),
    27           fCount(0) {
    28 }
    30 SkLayerDrawLooper::~SkLayerDrawLooper() {
    31     Rec* rec = fRecs;
    32     while (rec) {
    33         Rec* next = rec->fNext;
    34         SkDELETE(rec);
    35         rec = next;
    36     }
    37 }
    39 SkPaint* SkLayerDrawLooper::addLayer(const LayerInfo& info) {
    40     fCount += 1;
    42     Rec* rec = SkNEW(Rec);
    43     rec->fNext = fRecs;
    44     rec->fInfo = info;
    45     fRecs = rec;
    46     if (NULL == fTopRec) {
    47         fTopRec = rec;
    48     }
    50     return &rec->fPaint;
    51 }
    53 void SkLayerDrawLooper::addLayer(SkScalar dx, SkScalar dy) {
    54     LayerInfo info;
    56     info.fOffset.set(dx, dy);
    57     (void)this->addLayer(info);
    58 }
    60 SkPaint* SkLayerDrawLooper::addLayerOnTop(const LayerInfo& info) {
    61     fCount += 1;
    63     Rec* rec = SkNEW(Rec);
    64     rec->fNext = NULL;
    65     rec->fInfo = info;
    66     if (NULL == fRecs) {
    67         fRecs = rec;
    68     } else {
    69         SkASSERT(NULL != fTopRec);
    70         fTopRec->fNext = rec;
    71     }
    72     fTopRec = rec;
    74     return &rec->fPaint;
    75 }
    77 SkLayerDrawLooper::Context* SkLayerDrawLooper::createContext(SkCanvas* canvas, void* storage) const {
    78     canvas->save(SkCanvas::kMatrix_SaveFlag);
    79     return SkNEW_PLACEMENT_ARGS(storage, LayerDrawLooperContext, (this));
    80 }
    82 static SkColor xferColor(SkColor src, SkColor dst, SkXfermode::Mode mode) {
    83     switch (mode) {
    84         case SkXfermode::kSrc_Mode:
    85             return src;
    86         case SkXfermode::kDst_Mode:
    87             return dst;
    88         default: {
    89             SkPMColor pmS = SkPreMultiplyColor(src);
    90             SkPMColor pmD = SkPreMultiplyColor(dst);
    91             SkPMColor result = SkXfermode::GetProc(mode)(pmS, pmD);
    92             return SkUnPreMultiply::PMColorToColor(result);
    93         }
    94     }
    95 }
    97 // Even with kEntirePaint_Bits, we always ensure that the master paint's
    98 // text-encoding is respected, since that controls how we interpret the
    99 // text/length parameters of a draw[Pos]Text call.
   100 void SkLayerDrawLooper::LayerDrawLooperContext::ApplyInfo(
   101         SkPaint* dst, const SkPaint& src, const LayerInfo& info) {
   103     dst->setColor(xferColor(src.getColor(), dst->getColor(), info.fColorMode));
   105     BitFlags bits = info.fPaintBits;
   106     SkPaint::TextEncoding encoding = dst->getTextEncoding();
   108     if (0 == bits) {
   109         return;
   110     }
   111     if (kEntirePaint_Bits == bits) {
   112         // we've already computed these, so save it from the assignment
   113         uint32_t f = dst->getFlags();
   114         SkColor c = dst->getColor();
   115         *dst = src;
   116         dst->setFlags(f);
   117         dst->setColor(c);
   118         dst->setTextEncoding(encoding);
   119         return;
   120     }
   122     if (bits & kStyle_Bit) {
   123         dst->setStyle(src.getStyle());
   124         dst->setStrokeWidth(src.getStrokeWidth());
   125         dst->setStrokeMiter(src.getStrokeMiter());
   126         dst->setStrokeCap(src.getStrokeCap());
   127         dst->setStrokeJoin(src.getStrokeJoin());
   128     }
   130     if (bits & kTextSkewX_Bit) {
   131         dst->setTextSkewX(src.getTextSkewX());
   132     }
   134     if (bits & kPathEffect_Bit) {
   135         dst->setPathEffect(src.getPathEffect());
   136     }
   137     if (bits & kMaskFilter_Bit) {
   138         dst->setMaskFilter(src.getMaskFilter());
   139     }
   140     if (bits & kShader_Bit) {
   141         dst->setShader(src.getShader());
   142     }
   143     if (bits & kColorFilter_Bit) {
   144         dst->setColorFilter(src.getColorFilter());
   145     }
   146     if (bits & kXfermode_Bit) {
   147         dst->setXfermode(src.getXfermode());
   148     }
   150     // we don't override these
   151 #if 0
   152     dst->setTypeface(src.getTypeface());
   153     dst->setTextSize(src.getTextSize());
   154     dst->setTextScaleX(src.getTextScaleX());
   155     dst->setRasterizer(src.getRasterizer());
   156     dst->setLooper(src.getLooper());
   157     dst->setTextEncoding(src.getTextEncoding());
   158     dst->setHinting(src.getHinting());
   159 #endif
   160 }
   162 // Should we add this to canvas?
   163 static void postTranslate(SkCanvas* canvas, SkScalar dx, SkScalar dy) {
   164     SkMatrix m = canvas->getTotalMatrix();
   165     m.postTranslate(dx, dy);
   166     canvas->setMatrix(m);
   167 }
   169 SkLayerDrawLooper::LayerDrawLooperContext::LayerDrawLooperContext(
   170         const SkLayerDrawLooper* looper) : fCurrRec(looper->fRecs) {}
   172 bool SkLayerDrawLooper::LayerDrawLooperContext::next(SkCanvas* canvas,
   173                                                      SkPaint* paint) {
   174     canvas->restore();
   175     if (NULL == fCurrRec) {
   176         return false;
   177     }
   179     ApplyInfo(paint, fCurrRec->fPaint, fCurrRec->fInfo);
   181     canvas->save(SkCanvas::kMatrix_SaveFlag);
   182     if (fCurrRec->fInfo.fPostTranslate) {
   183         postTranslate(canvas, fCurrRec->fInfo.fOffset.fX,
   184                       fCurrRec->fInfo.fOffset.fY);
   185     } else {
   186         canvas->translate(fCurrRec->fInfo.fOffset.fX,
   187                           fCurrRec->fInfo.fOffset.fY);
   188     }
   189     fCurrRec = fCurrRec->fNext;
   191     return true;
   192 }
   194 ///////////////////////////////////////////////////////////////////////////////
   196 void SkLayerDrawLooper::flatten(SkWriteBuffer& buffer) const {
   197     this->INHERITED::flatten(buffer);
   199 #ifdef SK_DEBUG
   200     {
   201         Rec* rec = fRecs;
   202         int count = 0;
   203         while (rec) {
   204             rec = rec->fNext;
   205             count += 1;
   206         }
   207         SkASSERT(count == fCount);
   208     }
   209 #endif
   211     buffer.writeInt(fCount);
   213     Rec* rec = fRecs;
   214     for (int i = 0; i < fCount; i++) {
   215         // Legacy "flagsmask" field -- now ignored, remove when we bump version
   216         buffer.writeInt(0);
   218         buffer.writeInt(rec->fInfo.fPaintBits);
   219         buffer.writeInt(rec->fInfo.fColorMode);
   220         buffer.writePoint(rec->fInfo.fOffset);
   221         buffer.writeBool(rec->fInfo.fPostTranslate);
   222         buffer.writePaint(rec->fPaint);
   223         rec = rec->fNext;
   224     }
   225 }
   227 SkFlattenable* SkLayerDrawLooper::CreateProc(SkReadBuffer& buffer) {
   228     int count = buffer.readInt();
   230     Builder builder;
   231     for (int i = 0; i < count; i++) {
   232         LayerInfo info;
   233         // Legacy "flagsmask" field -- now ignored, remove when we bump version
   234         (void)buffer.readInt();
   236         info.fPaintBits = buffer.readInt();
   237         info.fColorMode = (SkXfermode::Mode)buffer.readInt();
   238         buffer.readPoint(&info.fOffset);
   239         info.fPostTranslate = buffer.readBool();
   240         buffer.readPaint(builder.addLayerOnTop(info));
   241     }
   242     SkLayerDrawLooper* looper = builder.detachLooper();
   243     SkASSERT(count == looper->fCount);
   245 #ifdef SK_DEBUG
   246     {
   247         Rec* rec = looper->fRecs;
   248         int n = 0;
   249         while (rec) {
   250             rec = rec->fNext;
   251             n += 1;
   252         }
   253         SkASSERT(count == n);
   254     }
   255 #endif
   257     return looper;
   258 }
   260 #ifndef SK_IGNORE_TO_STRING
   261 void SkLayerDrawLooper::toString(SkString* str) const {
   262     str->appendf("SkLayerDrawLooper (%d): ", fCount);
   264     Rec* rec = fRecs;
   265     for (int i = 0; i < fCount; i++) {
   266         str->appendf("%d: paintBits: (", i);
   267         if (0 == rec->fInfo.fPaintBits) {
   268             str->append("None");
   269         } else if (kEntirePaint_Bits == rec->fInfo.fPaintBits) {
   270             str->append("EntirePaint");
   271         } else {
   272             bool needSeparator = false;
   273             SkAddFlagToString(str, SkToBool(kStyle_Bit & rec->fInfo.fPaintBits), "Style",
   274                               &needSeparator);
   275             SkAddFlagToString(str, SkToBool(kTextSkewX_Bit & rec->fInfo.fPaintBits), "TextSkewX",
   276                               &needSeparator);
   277             SkAddFlagToString(str, SkToBool(kPathEffect_Bit & rec->fInfo.fPaintBits), "PathEffect",
   278                               &needSeparator);
   279             SkAddFlagToString(str, SkToBool(kMaskFilter_Bit & rec->fInfo.fPaintBits), "MaskFilter",
   280                               &needSeparator);
   281             SkAddFlagToString(str, SkToBool(kShader_Bit & rec->fInfo.fPaintBits), "Shader",
   282                               &needSeparator);
   283             SkAddFlagToString(str, SkToBool(kColorFilter_Bit & rec->fInfo.fPaintBits), "ColorFilter",
   284                               &needSeparator);
   285             SkAddFlagToString(str, SkToBool(kXfermode_Bit & rec->fInfo.fPaintBits), "Xfermode",
   286                               &needSeparator);
   287         }
   288         str->append(") ");
   290         static const char* gModeStrings[SkXfermode::kLastMode+1] = {
   291             "kClear", "kSrc", "kDst", "kSrcOver", "kDstOver", "kSrcIn", "kDstIn",
   292             "kSrcOut", "kDstOut", "kSrcATop", "kDstATop", "kXor", "kPlus",
   293             "kMultiply", "kScreen", "kOverlay", "kDarken", "kLighten", "kColorDodge",
   294             "kColorBurn", "kHardLight", "kSoftLight", "kDifference", "kExclusion"
   295         };
   297         str->appendf("mode: %s ", gModeStrings[rec->fInfo.fColorMode]);
   299         str->append("offset: (");
   300         str->appendScalar(rec->fInfo.fOffset.fX);
   301         str->append(", ");
   302         str->appendScalar(rec->fInfo.fOffset.fY);
   303         str->append(") ");
   305         str->append("postTranslate: ");
   306         if (rec->fInfo.fPostTranslate) {
   307             str->append("true ");
   308         } else {
   309             str->append("false ");
   310         }
   312         rec->fPaint.toString(str);
   313         rec = rec->fNext;
   314     }
   315 }
   316 #endif
   318 SkLayerDrawLooper::Builder::Builder()
   319         : fRecs(NULL),
   320           fTopRec(NULL),
   321           fCount(0) {
   322 }
   324 SkLayerDrawLooper::Builder::~Builder() {
   325     Rec* rec = fRecs;
   326     while (rec) {
   327         Rec* next = rec->fNext;
   328         SkDELETE(rec);
   329         rec = next;
   330     }
   331 }
   333 SkPaint* SkLayerDrawLooper::Builder::addLayer(const LayerInfo& info) {
   334     fCount += 1;
   336     Rec* rec = SkNEW(Rec);
   337     rec->fNext = fRecs;
   338     rec->fInfo = info;
   339     fRecs = rec;
   340     if (NULL == fTopRec) {
   341         fTopRec = rec;
   342     }
   344     return &rec->fPaint;
   345 }
   347 void SkLayerDrawLooper::Builder::addLayer(SkScalar dx, SkScalar dy) {
   348     LayerInfo info;
   350     info.fOffset.set(dx, dy);
   351     (void)this->addLayer(info);
   352 }
   354 SkPaint* SkLayerDrawLooper::Builder::addLayerOnTop(const LayerInfo& info) {
   355     fCount += 1;
   357     Rec* rec = SkNEW(Rec);
   358     rec->fNext = NULL;
   359     rec->fInfo = info;
   360     if (NULL == fRecs) {
   361         fRecs = rec;
   362     } else {
   363         SkASSERT(NULL != fTopRec);
   364         fTopRec->fNext = rec;
   365     }
   366     fTopRec = rec;
   368     return &rec->fPaint;
   369 }
   371 SkLayerDrawLooper* SkLayerDrawLooper::Builder::detachLooper() {
   372     SkLayerDrawLooper* looper = SkNEW(SkLayerDrawLooper);
   373     looper->fCount = fCount;
   374     looper->fRecs = fRecs;
   376     fCount = 0;
   377     fRecs = NULL;
   378     fTopRec = NULL;
   380     return looper;
   381 }

mercurial