SkLayerDrawLooper.cpp revision 0e2810be95d3f1aa95c341521d3f514eb9e9ebde
1#include "SkCanvas.h" 2#include "SkLayerDrawLooper.h" 3#include "SkPaint.h" 4 5SkLayerDrawLooper::SkLayerDrawLooper() { 6 fRecs = NULL; 7 fCount = 0; 8} 9 10SkLayerDrawLooper::~SkLayerDrawLooper() { 11 Rec* rec = fRecs; 12 while (rec) { 13 Rec* next = rec->fNext; 14 SkDELETE(rec); 15 rec = next; 16 } 17} 18 19SkPaint* SkLayerDrawLooper::addLayer(SkScalar dx, SkScalar dy, BitFlags bits) { 20 fCount += 1; 21 22 Rec* rec = SkNEW(Rec); 23 rec->fNext = fRecs; 24 rec->fOffset.set(dx, dy); 25 rec->fBits = bits; 26 fRecs = rec; 27 28 return &rec->fPaint; 29} 30 31void SkLayerDrawLooper::init(SkCanvas* canvas) { 32 fCurrRec = fRecs; 33 canvas->save(SkCanvas::kMatrix_SaveFlag); 34} 35 36void SkLayerDrawLooper::ApplyBits(SkPaint* dst, const SkPaint& src, 37 BitFlags bits) { 38 if (kEntirePaint_Bits == bits) { 39 *dst = src; 40 return; 41 } 42 43 SkColor c = dst->getColor(); 44 if (bits & kAlpha_Bit) { 45 c &= 0x00FFFFFF; 46 c |= src.getColor() & 0xFF000000; 47 } 48 if (bits & kColor_Bit) { 49 c &= 0xFF000000; 50 c |= src.getColor() & 0x00FFFFFF; 51 } 52 dst->setColor(c); 53 54 if (bits & kStyle_Bit) { 55 dst->setStyle(src.getStyle()); 56 dst->setStrokeWidth(src.getStrokeWidth()); 57 dst->setStrokeMiter(src.getStrokeMiter()); 58 dst->setStrokeCap(src.getStrokeCap()); 59 dst->setStrokeJoin(src.getStrokeJoin()); 60 } 61 62 if (bits & kTextSkewX_Bit) { 63 dst->setTextSkewX(src.getTextSkewX()); 64 } 65 66 if (bits & kPathEffect_Bit) { 67 dst->setPathEffect(src.getPathEffect()); 68 } 69 if (bits & kMaskFilter_Bit) { 70 dst->setMaskFilter(src.getMaskFilter()); 71 } 72 if (bits & kShader_Bit) { 73 dst->setShader(src.getShader()); 74 } 75 if (bits & kColorFilter_Bit) { 76 dst->setColorFilter(src.getColorFilter()); 77 } 78 if (bits & kXfermode_Bit) { 79 dst->setXfermode(src.getXfermode()); 80 } 81 82 // we never copy these 83#if 0 84 dst->setFlags(src.getFlags()); 85 dst->setTypeface(src.getTypeface()); 86 dst->setTextSize(src.getTextSize()); 87 dst->setTextScaleX(src.getTextScaleX()); 88 dst->setTextSkewX(src.getTextSkewX()); 89 dst->setRasterizer(src.getRasterizer()); 90 dst->setLooper(src.getLooper()); 91 dst->setTextEncoding(src.getTextEncoding()); 92 dst->setHinting(src.getHinting()); 93#endif 94} 95 96bool SkLayerDrawLooper::next(SkCanvas* canvas, SkPaint* paint) { 97 canvas->restore(); 98 if (NULL == fCurrRec) { 99 return false; 100 } 101 102 ApplyBits(paint, fCurrRec->fPaint, fCurrRec->fBits); 103 canvas->save(SkCanvas::kMatrix_SaveFlag); 104 canvas->translate(fCurrRec->fOffset.fX, fCurrRec->fOffset.fY); 105 fCurrRec = fCurrRec->fNext; 106 107 return true; 108} 109 110SkLayerDrawLooper::Rec* SkLayerDrawLooper::Rec::Reverse(Rec* head) { 111 Rec* rec = head; 112 Rec* prev = NULL; 113 while (rec) { 114 Rec* next = rec->fNext; 115 rec->fNext = prev; 116 prev = rec; 117 rec = next; 118 } 119 return prev; 120} 121 122/////////////////////////////////////////////////////////////////////////////// 123 124void SkLayerDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) { 125 this->INHERITED::flatten(buffer); 126 127#ifdef SK_DEBUG 128 { 129 Rec* rec = fRecs; 130 int count = 0; 131 while (rec) { 132 rec = rec->fNext; 133 count += 1; 134 } 135 SkASSERT(count == fCount); 136 } 137#endif 138 139 buffer.writeInt(fCount); 140 141 Rec* rec = fRecs; 142 for (int i = 0; i < fCount; i++) { 143 buffer.writeScalar(rec->fOffset.fX); 144 buffer.writeScalar(rec->fOffset.fY); 145 rec->fPaint.flatten(buffer); 146 rec = rec->fNext; 147 } 148} 149 150SkLayerDrawLooper::SkLayerDrawLooper(SkFlattenableReadBuffer& buffer) 151 : INHERITED(buffer) { 152 fRecs = NULL; 153 fCount = 0; 154 155 int count = buffer.readInt(); 156 157 for (int i = 0; i < count; i++) { 158 SkScalar dx = buffer.readScalar(); 159 SkScalar dy = buffer.readScalar(); 160 this->addLayer(dx, dy)->unflatten(buffer); 161 } 162 SkASSERT(count == fCount); 163 164 // we're in reverse order, so fix it now 165 fRecs = Rec::Reverse(fRecs); 166 167#ifdef SK_DEBUG 168 { 169 Rec* rec = fRecs; 170 int n = 0; 171 while (rec) { 172 rec = rec->fNext; 173 n += 1; 174 } 175 SkASSERT(count == n); 176 } 177#endif 178} 179 180/////////////////////////////////////////////////////////////////////////////// 181 182static SkFlattenable::Registrar gReg("SkLayerDrawLooper", 183 SkLayerDrawLooper::CreateProc); 184