| #include "SkCanvas.h" |
| #include "SkLayerDrawLooper.h" |
| #include "SkPaint.h" |
| |
| SkLayerDrawLooper::SkLayerDrawLooper() { |
| fRecs = NULL; |
| fCount = 0; |
| } |
| |
| SkLayerDrawLooper::~SkLayerDrawLooper() { |
| Rec* rec = fRecs; |
| while (rec) { |
| Rec* next = rec->fNext; |
| SkDELETE(rec); |
| rec = next; |
| } |
| } |
| |
| SkPaint* SkLayerDrawLooper::addLayer(SkScalar dx, SkScalar dy) { |
| fCount += 1; |
| |
| Rec* rec = SkNEW(Rec); |
| rec->fNext = fRecs; |
| rec->fOffset.set(dx, dy); |
| fRecs = rec; |
| |
| return &rec->fPaint; |
| } |
| |
| void SkLayerDrawLooper::init(SkCanvas* canvas, SkPaint* paint) { |
| fIter.fSavedPaint = *paint; |
| fIter.fPaint = paint; |
| fIter.fCanvas = canvas; |
| fIter.fRec = fRecs; |
| canvas->save(SkCanvas::kMatrix_SaveFlag); |
| } |
| |
| bool SkLayerDrawLooper::next() { |
| Rec* rec = fIter.fRec; |
| if (rec) { |
| *fIter.fPaint = rec->fPaint; |
| fIter.fCanvas->restore(); |
| fIter.fCanvas->save(SkCanvas::kMatrix_SaveFlag); |
| fIter.fCanvas->translate(rec->fOffset.fX, rec->fOffset.fY); |
| |
| fIter.fRec = rec->fNext; |
| return true; |
| } |
| return false; |
| } |
| |
| void SkLayerDrawLooper::restore() { |
| fIter.fCanvas->restore(); |
| *fIter.fPaint = fIter.fSavedPaint; |
| } |
| |
| SkLayerDrawLooper::Rec* SkLayerDrawLooper::Rec::Reverse(Rec* head) { |
| Rec* rec = head; |
| Rec* prev = NULL; |
| while (rec) { |
| Rec* next = rec->fNext; |
| rec->fNext = prev; |
| prev = rec; |
| rec = next; |
| } |
| return prev; |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| void SkLayerDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) { |
| this->INHERITED::flatten(buffer); |
| |
| #ifdef SK_DEBUG |
| { |
| Rec* rec = fRecs; |
| int count = 0; |
| while (rec) { |
| rec = rec->fNext; |
| count += 1; |
| } |
| SkASSERT(count == fCount); |
| } |
| #endif |
| |
| buffer.writeInt(fCount); |
| |
| Rec* rec = fRecs; |
| for (int i = 0; i < fCount; i++) { |
| buffer.writeScalar(rec->fOffset.fX); |
| buffer.writeScalar(rec->fOffset.fY); |
| rec->fPaint.flatten(buffer); |
| rec = rec->fNext; |
| } |
| } |
| |
| SkLayerDrawLooper::SkLayerDrawLooper(SkFlattenableReadBuffer& buffer) |
| : INHERITED(buffer) { |
| fRecs = NULL; |
| fCount = 0; |
| |
| int count = buffer.readInt(); |
| |
| for (int i = 0; i < count; i++) { |
| SkScalar dx = buffer.readScalar(); |
| SkScalar dy = buffer.readScalar(); |
| this->addLayer(dx, dy)->unflatten(buffer); |
| } |
| SkASSERT(count == fCount); |
| |
| // we're in reverse order, so fix it now |
| fRecs = Rec::Reverse(fRecs); |
| |
| #ifdef SK_DEBUG |
| { |
| Rec* rec = fRecs; |
| int n = 0; |
| while (rec) { |
| rec = rec->fNext; |
| n += 1; |
| } |
| SkASSERT(count == n); |
| } |
| #endif |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| static SkFlattenable::Registrar gReg("SkLayerDrawLooper", |
| SkLayerDrawLooper::CreateProc); |