• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
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 "SkLayerDrawLooper.h"
11 #include "SkPaint.h"
12 #include "SkUnPreMultiply.h"
13 
LayerInfo()14 SkLayerDrawLooper::LayerInfo::LayerInfo() {
15     fFlagsMask = 0;                     // ignore our paint flags
16     fPaintBits = 0;                     // ignore our paint fields
17     fColorMode = SkXfermode::kDst_Mode; // ignore our color
18     fOffset.set(0, 0);
19     fPostTranslate = false;
20 }
21 
SkLayerDrawLooper()22 SkLayerDrawLooper::SkLayerDrawLooper()
23         : fRecs(NULL),
24           fCount(0),
25           fCurrRec(NULL) {
26 }
27 
~SkLayerDrawLooper()28 SkLayerDrawLooper::~SkLayerDrawLooper() {
29     Rec* rec = fRecs;
30     while (rec) {
31         Rec* next = rec->fNext;
32         SkDELETE(rec);
33         rec = next;
34     }
35 }
36 
addLayer(const LayerInfo & info)37 SkPaint* SkLayerDrawLooper::addLayer(const LayerInfo& info) {
38     fCount += 1;
39 
40     Rec* rec = SkNEW(Rec);
41     rec->fNext = fRecs;
42     rec->fInfo = info;
43     fRecs = rec;
44 
45     return &rec->fPaint;
46 }
47 
addLayer(SkScalar dx,SkScalar dy)48 void SkLayerDrawLooper::addLayer(SkScalar dx, SkScalar dy) {
49     LayerInfo info;
50 
51     info.fOffset.set(dx, dy);
52     (void)this->addLayer(info);
53 }
54 
init(SkCanvas * canvas)55 void SkLayerDrawLooper::init(SkCanvas* canvas) {
56     fCurrRec = fRecs;
57     canvas->save(SkCanvas::kMatrix_SaveFlag);
58 }
59 
xferColor(SkColor src,SkColor dst,SkXfermode::Mode mode)60 static SkColor xferColor(SkColor src, SkColor dst, SkXfermode::Mode mode) {
61     switch (mode) {
62         case SkXfermode::kSrc_Mode:
63             return src;
64         case SkXfermode::kDst_Mode:
65             return dst;
66         default: {
67             SkPMColor pmS = SkPreMultiplyColor(src);
68             SkPMColor pmD = SkPreMultiplyColor(dst);
69             SkPMColor result = SkXfermode::GetProc(mode)(pmS, pmD);
70             return SkUnPreMultiply::PMColorToColor(result);
71         }
72     }
73 }
74 
75 // Even with kEntirePaint_Bits, we always ensure that the master paint's
76 // text-encoding is respected, since that controls how we interpret the
77 // text/length parameters of a draw[Pos]Text call.
ApplyInfo(SkPaint * dst,const SkPaint & src,const LayerInfo & info)78 void SkLayerDrawLooper::ApplyInfo(SkPaint* dst, const SkPaint& src,
79                                   const LayerInfo& info) {
80 
81     uint32_t mask = info.fFlagsMask;
82     dst->setFlags((dst->getFlags() & ~mask) | (src.getFlags() & mask));
83     dst->setColor(xferColor(src.getColor(), dst->getColor(), info.fColorMode));
84 
85     BitFlags bits = info.fPaintBits;
86     SkPaint::TextEncoding encoding = dst->getTextEncoding();
87 
88     if (0 == bits) {
89         return;
90     }
91     if (kEntirePaint_Bits == bits) {
92         // we've already computed these, so save it from the assignment
93         uint32_t f = dst->getFlags();
94         SkColor c = dst->getColor();
95         *dst = src;
96         dst->setFlags(f);
97         dst->setColor(c);
98         dst->setTextEncoding(encoding);
99         return;
100     }
101 
102     if (bits & kStyle_Bit) {
103         dst->setStyle(src.getStyle());
104         dst->setStrokeWidth(src.getStrokeWidth());
105         dst->setStrokeMiter(src.getStrokeMiter());
106         dst->setStrokeCap(src.getStrokeCap());
107         dst->setStrokeJoin(src.getStrokeJoin());
108     }
109 
110     if (bits & kTextSkewX_Bit) {
111         dst->setTextSkewX(src.getTextSkewX());
112     }
113 
114     if (bits & kPathEffect_Bit) {
115         dst->setPathEffect(src.getPathEffect());
116     }
117     if (bits & kMaskFilter_Bit) {
118         dst->setMaskFilter(src.getMaskFilter());
119     }
120     if (bits & kShader_Bit) {
121         dst->setShader(src.getShader());
122     }
123     if (bits & kColorFilter_Bit) {
124         dst->setColorFilter(src.getColorFilter());
125     }
126     if (bits & kXfermode_Bit) {
127         dst->setXfermode(src.getXfermode());
128     }
129 
130     // we don't override these
131 #if 0
132     dst->setTypeface(src.getTypeface());
133     dst->setTextSize(src.getTextSize());
134     dst->setTextScaleX(src.getTextScaleX());
135     dst->setRasterizer(src.getRasterizer());
136     dst->setLooper(src.getLooper());
137     dst->setTextEncoding(src.getTextEncoding());
138     dst->setHinting(src.getHinting());
139 #endif
140 }
141 
142 // Should we add this to canvas?
postTranslate(SkCanvas * canvas,SkScalar dx,SkScalar dy)143 static void postTranslate(SkCanvas* canvas, SkScalar dx, SkScalar dy) {
144     SkMatrix m = canvas->getTotalMatrix();
145     m.postTranslate(dx, dy);
146     canvas->setMatrix(m);
147 }
148 
next(SkCanvas * canvas,SkPaint * paint)149 bool SkLayerDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
150     canvas->restore();
151     if (NULL == fCurrRec) {
152         return false;
153     }
154 
155     ApplyInfo(paint, fCurrRec->fPaint, fCurrRec->fInfo);
156 
157     canvas->save(SkCanvas::kMatrix_SaveFlag);
158     if (fCurrRec->fInfo.fPostTranslate) {
159         postTranslate(canvas, fCurrRec->fInfo.fOffset.fX,
160                       fCurrRec->fInfo.fOffset.fY);
161     } else {
162         canvas->translate(fCurrRec->fInfo.fOffset.fX, fCurrRec->fInfo.fOffset.fY);
163     }
164     fCurrRec = fCurrRec->fNext;
165 
166     return true;
167 }
168 
Reverse(Rec * head)169 SkLayerDrawLooper::Rec* SkLayerDrawLooper::Rec::Reverse(Rec* head) {
170     Rec* rec = head;
171     Rec* prev = NULL;
172     while (rec) {
173         Rec* next = rec->fNext;
174         rec->fNext = prev;
175         prev = rec;
176         rec = next;
177     }
178     return prev;
179 }
180 
181 ///////////////////////////////////////////////////////////////////////////////
182 
flatten(SkFlattenableWriteBuffer & buffer)183 void SkLayerDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) {
184     this->INHERITED::flatten(buffer);
185 
186 #ifdef SK_DEBUG
187     {
188         Rec* rec = fRecs;
189         int count = 0;
190         while (rec) {
191             rec = rec->fNext;
192             count += 1;
193         }
194         SkASSERT(count == fCount);
195     }
196 #endif
197 
198     buffer.writeInt(fCount);
199 
200     Rec* rec = fRecs;
201     for (int i = 0; i < fCount; i++) {
202         buffer.writeInt(rec->fInfo.fPaintBits);
203         buffer.writeInt(rec->fInfo.fColorMode);
204         buffer.writeScalar(rec->fInfo.fOffset.fX);
205         buffer.writeScalar(rec->fInfo.fOffset.fY);
206         buffer.writeBool(rec->fInfo.fPostTranslate);
207         rec->fPaint.flatten(buffer);
208         rec = rec->fNext;
209     }
210 }
211 
SkLayerDrawLooper(SkFlattenableReadBuffer & buffer)212 SkLayerDrawLooper::SkLayerDrawLooper(SkFlattenableReadBuffer& buffer)
213         : INHERITED(buffer),
214           fRecs(NULL),
215           fCount(0),
216           fCurrRec(NULL) {
217     int count = buffer.readInt();
218 
219     for (int i = 0; i < count; i++) {
220         LayerInfo info;
221         if (buffer.getPictureVersion() == PICTURE_VERSION_ICS)
222             info.fFlagsMask = buffer.readInt();
223         info.fPaintBits = buffer.readInt();
224         info.fColorMode = (SkXfermode::Mode)buffer.readInt();
225         info.fOffset.fX = buffer.readScalar();
226         info.fOffset.fY = buffer.readScalar();
227         info.fPostTranslate = buffer.readBool();
228         this->addLayer(info)->unflatten(buffer);
229     }
230     SkASSERT(count == fCount);
231 
232     // we're in reverse order, so fix it now
233     fRecs = Rec::Reverse(fRecs);
234 
235 #ifdef SK_DEBUG
236     {
237         Rec* rec = fRecs;
238         int n = 0;
239         while (rec) {
240             rec = rec->fNext;
241             n += 1;
242         }
243         SkASSERT(count == n);
244     }
245 #endif
246 }
247 
248 ///////////////////////////////////////////////////////////////////////////////
249 
250 SK_DEFINE_FLATTENABLE_REGISTRAR(SkLayerDrawLooper)
251