Beispiel #1
0
    FillBounds(const SkRecord& record, SkBBoxHierarchy* bbh) : fBounds(record.count()) {
        // Calculate bounds for all ops.  This won't go quite in order, so we'll need
        // to store the bounds separately then feed them in to the BBH later in order.
        fCTM.setIdentity();
        for (fCurrentOp = 0; fCurrentOp < record.count(); fCurrentOp++) {
            record.visit<void>(fCurrentOp, *this);
        }

        // If we have any lingering unpaired Saves, simulate restores to make
        // sure all ops in those Save blocks have their bounds calculated.
        while (!fSaveStack.isEmpty()) {
            this->popSaveBlock();
        }

        // Any control ops not part of any Save/Restore block draw everywhere.
        while (!fControlIndices.isEmpty()) {
            this->popControl(SkIRect::MakeLargest());
        }

        // Finally feed all stored bounds into the BBH.  They'll be returned in this order.
        SkASSERT(NULL != bbh);
        for (uintptr_t i = 0; i < record.count(); i++) {
            if (!fBounds[i].isEmpty()) {
                bbh->insert((void*)i, fBounds[i], true/*ok to defer*/);
            }
        }
        bbh->flushDeferredInserts();
    }
Beispiel #2
0
// A regression test for crbug.com/415468 and https://bug.skia.org/2957 .
//
// This also now serves as a regression test for crbug.com/418417.  We used to adjust the
// bounds for the saveLayer, clip, and restore to be greater than the bounds of the picture.
// (We were applying the saveLayer paint to the bounds after restore, which makes no sense.)
DEF_TEST(RecordDraw_SaveLayerAffectsClipBounds, r) {
    SkRecord record;
    SkRecorder recorder(&record, 50, 50);

    // We draw a rectangle with a long drop shadow.  We used to not update the clip
    // bounds based on SaveLayer paints, so the drop shadow could be cut off.
    SkPaint paint;
    paint.setImageFilter(SkDropShadowImageFilter::Make(
                                 20, 0, 0, 0, SK_ColorBLACK,
                                 SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
                                 nullptr));

    recorder.saveLayer(nullptr, &paint);
        recorder.clipRect(SkRect::MakeWH(20, 40));
        recorder.drawRect(SkRect::MakeWH(20, 40), SkPaint());
    recorder.restore();

    // Under the original bug, the right edge value of the drawRect would be 20 less than asserted
    // here because we intersected it with a clip that had not been adjusted for the drop shadow.
    //
    // The second bug showed up as adjusting the picture bounds (0,0,50,50) by the drop shadow too.
    // The saveLayer, clipRect, and restore bounds were incorrectly (0,0,70,50).
    SkAutoTMalloc<SkRect> bounds(record.count());
    SkRecordFillBounds(SkRect::MakeWH(50, 50), record, bounds);
    REPORTER_ASSERT(r, sloppy_rect_eq(bounds[0], SkRect::MakeLTRB(0, 0, 50, 50)));
    REPORTER_ASSERT(r, sloppy_rect_eq(bounds[1], SkRect::MakeLTRB(0, 0, 50, 50)));
    REPORTER_ASSERT(r, sloppy_rect_eq(bounds[2], SkRect::MakeLTRB(0, 0, 40, 40)));
    REPORTER_ASSERT(r, sloppy_rect_eq(bounds[3], SkRect::MakeLTRB(0, 0, 50, 50)));
}
Beispiel #3
0
// Make sure the abort callback works
DEF_TEST(RecordReplaceDraw_Abort, r) {
    sk_sp<SkPicture> pic;

    {
        // Record two commands.
        SkPictureRecorder recorder;
        SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight));

        canvas->drawRect(SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight)), SkPaint());
        canvas->clipRect(SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight)));

        pic = recorder.finishRecordingAsPicture();
    }

    SkRecord rerecord;
    SkRecorder canvas(&rerecord, kWidth, kHeight);

    JustOneDraw callback;
    GrRecordReplaceDraw(pic.get(), &canvas, nullptr, SkMatrix::I(), &callback);

    switch (rerecord.count()) {
        case 3:
            assert_type<SkRecords::Save>(r, rerecord, 0);
            assert_type<SkRecords::DrawRect>(r, rerecord, 1);
            assert_type<SkRecords::Restore>(r, rerecord, 2);
            break;
        case 1:
            assert_type<SkRecords::DrawRect>(r, rerecord, 0);
            break;
        default:
            REPORTER_ASSERT(r, false);
    }
}
Beispiel #4
0
    FillBounds(const SkRect& cullRect, const SkRecord& record, SkBBoxHierarchy* bbh) 
        : fCullRect(cullRect)
        , fBounds(record.count()) {
        // Calculate bounds for all ops.  This won't go quite in order, so we'll need
        // to store the bounds separately then feed them in to the BBH later in order.
        fCTM = &SkMatrix::I();
        fCurrentClipBounds = fCullRect;
        for (fCurrentOp = 0; fCurrentOp < record.count(); fCurrentOp++) {
            record.visit<void>(fCurrentOp, *this);
        }

        // If we have any lingering unpaired Saves, simulate restores to make
        // sure all ops in those Save blocks have their bounds calculated.
        while (!fSaveStack.isEmpty()) {
            this->popSaveBlock();
        }

        // Any control ops not part of any Save/Restore block draw everywhere.
        while (!fControlIndices.isEmpty()) {
            this->popControl(fCullRect);
        }

        // Finally feed all stored bounds into the BBH.  They'll be returned in this order.
        SkASSERT(bbh);
        bbh->insert(&fBounds, record.count());
    }
Beispiel #5
0
// Make sure GrRecordReplaceDraw balances unbalanced saves
DEF_TEST(RecordReplaceDraw_Unbalanced, r) {
    sk_sp<SkPicture> pic;

    {
        SkPictureRecorder recorder;
        SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight));

        // We won't balance this, but GrRecordReplaceDraw will for us.
        canvas->save();
        canvas->scale(2, 2);
        pic = recorder.finishRecordingAsPicture();

        // we may have optimized everything away. If so, just return
        if (pic->approximateOpCount() == 0) {
            return;
        }
    }

    SkRecord rerecord;
    SkRecorder canvas(&rerecord, kWidth, kHeight);

    GrRecordReplaceDraw(pic.get(), &canvas, nullptr, SkMatrix::I(), nullptr/*callback*/);

    // ensure rerecord is balanced (in this case by checking that the count is odd)
    REPORTER_ASSERT(r, (rerecord.count() & 1) == 1);
}
Beispiel #6
0
DEF_TEST(RecordOpts_SaveSaveLayerRestoreRestore, r) {
    SkRecord record;
    SkRecorder recorder(&record, W, H);

    // A previous bug NoOp'd away the first 3 commands.
    recorder.save();
    recorder.saveLayer(NULL, NULL);
    recorder.restore();
    recorder.restore();

    SkRecordNoopSaveRestores(&record);
    switch (record.count()) {
    case 4:
        assert_type<SkRecords::Save>     (r, record, 0);
        assert_type<SkRecords::SaveLayer>(r, record, 1);
        assert_type<SkRecords::Restore>  (r, record, 2);
        assert_type<SkRecords::Restore>  (r, record, 3);
        break;
    case 2:
        assert_type<SkRecords::SaveLayer>(r, record, 0);
        assert_type<SkRecords::Restore>  (r, record, 1);
        break;
    case 0:
        break;
    default:
        REPORTER_ASSERT(r, false);
    }
}
Beispiel #7
0
DEF_TEST(RecordDraw_SetMatrixClobber, r) {
    // Set up an SkRecord that just scales by 2x,3x.
    SkRecord scaleRecord;
    SkRecorder scaleCanvas(&scaleRecord, W, H);
    SkMatrix scale;
    scale.setScale(2, 3);
    scaleCanvas.setMatrix(scale);

    // Set up an SkRecord with an initial +20, +20 translate.
    SkRecord translateRecord;
    SkRecorder translateCanvas(&translateRecord, W, H);
    SkMatrix translate;
    translate.setTranslate(20, 20);
    translateCanvas.setMatrix(translate);

    SkRecordDraw(scaleRecord, &translateCanvas, nullptr, nullptr, 0, nullptr/*bbh*/, nullptr/*callback*/);
    REPORTER_ASSERT(r, 4 == translateRecord.count());
    assert_type<SkRecords::SetMatrix>(r, translateRecord, 0);
    assert_type<SkRecords::Save>     (r, translateRecord, 1);
    assert_type<SkRecords::SetMatrix>(r, translateRecord, 2);
    assert_type<SkRecords::Restore>  (r, translateRecord, 3);

    // When we look at translateRecord now, it should have its first +20,+20 translate,
    // then a 2x,3x scale that's been concatted with that +20,+20 translate.
    const SkRecords::SetMatrix* setMatrix;
    setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 0);
    REPORTER_ASSERT(r, setMatrix->matrix == translate);

    setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 2);
    SkMatrix expected = scale;
    expected.postConcat(translate);
    REPORTER_ASSERT(r, setMatrix->matrix == expected);
}
Beispiel #8
0
void SkRecordFillBounds(const SkRect& cullRect, const SkRecord& record, SkRect bounds[]) {
    SkRecords::FillBounds visitor(cullRect, record, bounds);
    for (int curOp = 0; curOp < record.count(); curOp++) {
        visitor.setCurrentOp(curOp);
        record.visit(curOp, visitor);
    }
    visitor.cleanUp();
}
void DumpRecord(const SkRecord& record,
                  SkCanvas* canvas,
                  bool timeWithCommand) {
    Dumper dumper(canvas, record.count(), timeWithCommand);
    for (int i = 0; i < record.count(); i++) {
        record.visit<void>(i, dumper);
    }
}
Beispiel #10
0
void SkRecordPartialDraw(const SkRecord& record, SkCanvas* canvas,
                         SkPicture const* const drawablePicts[], int drawableCount,
                         int start, int stop,
                         const SkMatrix& initialCTM) {
    SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/);

    stop = SkTMin(stop, record.count());
    SkRecords::Draw draw(canvas, drawablePicts, nullptr, drawableCount, &initialCTM);
    for (int i = start; i < stop; i++) {
        record.visit(i, draw);
    }
}
Beispiel #11
0
void SkBigPicture::Analysis::init(const SkRecord& record) {
    TRACE_EVENT0("disabled-by-default-skia", "SkBigPicture::Analysis::init()");
    SkBitmapHunter bitmap;
    SkPathCounter  path;

    bool hasBitmap = false;
    for (int i = 0; i < record.count(); i++) {
        hasBitmap = hasBitmap || record.visit(i, bitmap);
        record.visit(i, path);
    }

    fWillPlaybackBitmaps        = hasBitmap;
    fNumSlowPathsAndDashEffects = SkTMin<int>(path.fNumSlowPathsAndDashEffects, 255);
}
Beispiel #12
0
DEF_TEST(RecordDraw_PosTextHQuickReject, r) {
    SkRecord record;
    SkRecorder recorder(&record, W, H);

    draw_pos_text_h(&recorder, "This will draw.", 20);
    draw_pos_text_h(&recorder, "This won't.", 5000);

    SkRecordBoundDrawPosTextH(&record);

    SkRecord clipped;
    record_clipped(record, SkRect::MakeLTRB(20, 20, 200, 200), &clipped);

    // clipRect and the first drawPosTextH.
    REPORTER_ASSERT(r, 2 == clipped.count());
}
Beispiel #13
0
DEF_TEST(RecordDraw_BasicBounds, r) {
    SkRecord record;
    SkRecorder recorder(&record, W, H);
    recorder.save();
        recorder.clipRect(SkRect::MakeWH(400, 500));
        recorder.scale(2, 2);
        recorder.drawRect(SkRect::MakeWH(320, 240), SkPaint());
    recorder.restore();

    SkAutoTMalloc<SkRect> bounds(record.count());
    SkRecordFillBounds(SkRect::MakeWH(SkIntToScalar(W), SkIntToScalar(H)), record, bounds);

    for (int i = 0; i < record.count(); i++) {
        REPORTER_ASSERT(r, sloppy_rect_eq(SkRect::MakeWH(400, 480), bounds[i]));
    }
}
Beispiel #14
0
 FillBounds(const SkRect& cullRect, const SkRecord& record, SkRect bounds[])
     : fNumRecords(record.count())
     , fCullRect(cullRect)
     , fBounds(bounds) {
     fCTM = SkMatrix::I();
     fCurrentClipBounds = fCullRect;
 }
Beispiel #15
0
void SkRecordDraw(const SkRecord& record,
                  SkCanvas* canvas,
                  SkPicture const* const drawablePicts[],
                  SkDrawable* const drawables[],
                  int drawableCount,
                  const SkBBoxHierarchy* bbh,
                  SkPicture::AbortCallback* callback) {
    SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/);

    if (bbh) {
        // Draw only ops that affect pixels in the canvas's current clip.
        // The SkRecord and BBH were recorded in identity space.  This canvas
        // is not necessarily in that same space.  getClipBounds() returns us
        // this canvas' clip bounds transformed back into identity space, which
        // lets us query the BBH.
        SkRect query;
        if (!canvas->getClipBounds(&query)) {
            query.setEmpty();
        }

        SkTDArray<int> ops;
        bbh->search(query, &ops);

        SkRecords::Draw draw(canvas, drawablePicts, drawables, drawableCount);
        for (int i = 0; i < ops.count(); i++) {
            if (callback && callback->abort()) {
                return;
            }
            // This visit call uses the SkRecords::Draw::operator() to call
            // methods on the |canvas|, wrapped by methods defined with the
            // DRAW() macro.
            record.visit(ops[i], draw);
        }
    } else {
        // Draw all ops.
        SkRecords::Draw draw(canvas, drawablePicts, drawables, drawableCount);
        for (int i = 0; i < record.count(); i++) {
            if (callback && callback->abort()) {
                return;
            }
            // This visit call uses the SkRecords::Draw::operator() to call
            // methods on the |canvas|, wrapped by methods defined with the
            // DRAW() macro.
            record.visit(i, draw);
        }
    }
}
Beispiel #16
0
DEF_TEST(RecordDraw_LazySaves, r) {
    // Record two commands.
    SkRecord record;
    SkRecorder recorder(&record, W, H);

    REPORTER_ASSERT(r, 0 == record.count());
    recorder.save();
    REPORTER_ASSERT(r, 0 == record.count());    // the save was not recorded (yet)
    recorder.drawColor(SK_ColorRED);
    REPORTER_ASSERT(r, 1 == record.count());
    recorder.scale(2, 2);
    REPORTER_ASSERT(r, 3 == record.count());    // now we see the save
    recorder.restore();
    REPORTER_ASSERT(r, 4 == record.count());

    assert_type<SkRecords::DrawPaint>(r, record, 0);
    assert_type<SkRecords::Save>     (r, record, 1);
    assert_type<SkRecords::Concat>   (r, record, 2);
    assert_type<SkRecords::Restore>  (r, record, 3);

    recorder.save();
    recorder.save();
    recorder.restore();
    recorder.restore();
    REPORTER_ASSERT(r, 4 == record.count());
}
Beispiel #17
0
bool WillPlaybackBitmaps(const SkRecord& record) {
    BitmapTester tester;
    for (unsigned i = 0; i < record.count(); i++) {
        if (record.visit<bool>(i, tester)) {
            return true;
        }
    }
    return false;
}
Beispiel #18
0
// When a saveLayer provides an explicit bound and has a complex paint (e.g., one that
// affects transparent black), that bound should serve to shrink the area of the required
// backing store.
DEF_TEST(RecordDraw_SaveLayerBoundsAffectsClipBounds, r) {
    SkRecord record;
    SkRecorder recorder(&record, 50, 50);

    SkPaint p;
    p.setBlendMode(SkBlendMode::kSrc);

    SkRect layerBounds = SkRect::MakeLTRB(10, 10, 40, 40);
    recorder.saveLayer(&layerBounds, &p);
    recorder.drawRect(SkRect::MakeLTRB(20, 20, 30, 30), SkPaint());
    recorder.restore();

    SkAutoTMalloc<SkRect> bounds(record.count());
    SkRecordFillBounds(SkRect::MakeWH(50, 50), record, bounds);
    if (!SkCanvas::Internal_Private_GetIgnoreSaveLayerBounds()) {
        REPORTER_ASSERT(r, sloppy_rect_eq(bounds[0], SkRect::MakeLTRB(10, 10, 40, 40)));
        REPORTER_ASSERT(r, sloppy_rect_eq(bounds[1], SkRect::MakeLTRB(20, 20, 30, 30)));
        REPORTER_ASSERT(r, sloppy_rect_eq(bounds[2], SkRect::MakeLTRB(10, 10, 40, 40)));
    }
}
// Make sure GrRecordReplaceDraw balances unbalanced saves
DEF_TEST(RecordReplaceDraw_Unbalanced, r) {
    SkAutoTUnref<const SkPicture> pic;

    {
        SkPictureRecorder recorder;
        SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight));

        // We won't balance this, but GrRecordReplaceDraw will for us.
        canvas->save();
        canvas->scale(2, 2);
        pic.reset(recorder.endRecording());
    }

    SkRecord rerecord;
    SkRecorder canvas(&rerecord, kWidth, kHeight);

    GrRecordReplaceDraw(pic, &canvas, nullptr, SkMatrix::I(), nullptr/*callback*/);

    // ensure rerecord is balanced (in this case by checking that the count is odd)
    REPORTER_ASSERT(r, (rerecord.count() & 1) == 1);
}
Beispiel #20
0
DEF_TEST(RecordOpts_NoopSaveRestores, r) {
    SkRecord record;
    SkRecorder recorder(&record, W, H);

    // The second pass will clean up this pair after the first pass noops all the innards.
    recorder.save();
    // A simple pointless pair of save/restore.
    recorder.save();
    recorder.restore();

    // As long as we don't draw in there, everything is a noop.
    recorder.save();
    recorder.clipRect(SkRect::MakeWH(200, 200));
    recorder.clipRect(SkRect::MakeWH(100, 100));
    recorder.restore();
    recorder.restore();

    SkRecordNoopSaveRestores(&record);
    for (int index = 0; index < record.count(); index++) {
        assert_type<SkRecords::NoOp>(r, record, index);
    }
}
Beispiel #21
0
void SkRecordPartialDraw(const SkRecord& record,
                         SkCanvas* canvas,
                         const SkRect& clearRect,
                         unsigned start, unsigned stop,
                         const SkMatrix& initialCTM) {
    SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/);

    stop = SkTMin(stop, record.count());
    SkRecords::PartialDraw draw(canvas, clearRect, initialCTM);
    for (unsigned i = start; i < stop; i++) {
        record.visit<void>(i, draw);
    }
}
Beispiel #22
0
// A regression test for crbug.com/409110.
DEF_TEST(RecordDraw_TextBounds, r) {
    SkRecord record;
    SkRecorder recorder(&record, W, H);

    // Two Chinese characters in UTF-8.
    const char text[] = { '\xe6', '\xbc', '\xa2', '\xe5', '\xad', '\x97' };
    const size_t bytes = SK_ARRAY_COUNT(text);

    const SkScalar xpos[] = { 10, 20 };
    recorder.drawPosTextH(text, bytes, xpos, 30, SkPaint());

    const SkPoint pos[] = { {40, 50}, {60, 70} };
    recorder.drawPosText(text, bytes, pos, SkPaint());

    SkAutoTMalloc<SkRect> bounds(record.count());
    SkRecordFillBounds(SkRect::MakeWH(SkIntToScalar(W), SkIntToScalar(H)), record, bounds);

    // We can make these next assertions confidently because SkRecordFillBounds
    // builds its bounds by overestimating font metrics in a platform-independent way.
    // If that changes, these tests will need to be more flexible.
    REPORTER_ASSERT(r, sloppy_rect_eq(bounds[0], SkRect::MakeLTRB(0,  0, 140, 60)));
    REPORTER_ASSERT(r, sloppy_rect_eq(bounds[1], SkRect::MakeLTRB(0, 20, 180, 100)));
}
Beispiel #23
0
DEF_TEST(RecordDraw_Culling, r) {
    // Record these 7 drawing commands verbatim.
    SkRecord record;
    SkRecorder recorder(&record, W, H);

    recorder.pushCull(SkRect::MakeWH(100, 100));
        recorder.drawRect(SkRect::MakeWH(10, 10), SkPaint());
        recorder.drawRect(SkRect::MakeWH(30, 30), SkPaint());
        recorder.pushCull(SkRect::MakeWH(5, 5));
            recorder.drawRect(SkRect::MakeWH(1, 1), SkPaint());
        recorder.popCull();
    recorder.popCull();

    // Take a pass over to match up pushCulls and popCulls.
    SkRecordAnnotateCullingPairs(&record);

    // This clip intersects the outer cull, but allows us to quick reject the inner one.
    SkRecord clipped;
    record_clipped(record, SkRect::MakeLTRB(20, 20, 200, 200), &clipped);

    // We'll keep the clipRect call from above, and the outer two drawRects, and the push/pop pair.
    // If culling weren't working, we'd see 8 commands recorded here.
    REPORTER_ASSERT(r, 5 == clipped.count());
}
Beispiel #24
0
DEF_TEST(RecordPattern_Complex, r) {
    Pattern3<Is<Save>,
             Star<Not<Or3<Is<Save>,
             Is<Restore>,
             IsDraw> > >,
             Is<Restore> > pattern;

    SkRecord record;
    SkRecorder recorder(&record, 1920, 1200);
    int start, begin, end;

    start = record.count();
    recorder.save();
    recorder.clipRect(SkRect::MakeWH(300, 200));
    recorder.restore();
    REPORTER_ASSERT(r, pattern.match(&record, 0) == record.count());
    end = start;
    REPORTER_ASSERT(r, pattern.search(&record, &begin, &end));
    REPORTER_ASSERT(r, begin == start);
    REPORTER_ASSERT(r, end == record.count());

    start = record.count();
    recorder.save();
    recorder.clipRect(SkRect::MakeWH(300, 200));
    recorder.drawRect(SkRect::MakeWH(100, 3000), SkPaint());
    recorder.restore();
    REPORTER_ASSERT(r, !pattern.match(&record, start));
    end = start;
    REPORTER_ASSERT(r, !pattern.search(&record, &begin, &end));

    start = record.count();
    recorder.save();
    recorder.clipRect(SkRect::MakeWH(300, 200));
    recorder.clipRect(SkRect::MakeWH(100, 400));
    recorder.restore();
    REPORTER_ASSERT(r, pattern.match(&record, start) == record.count());
    end = start;
    REPORTER_ASSERT(r, pattern.search(&record, &begin, &end));
    REPORTER_ASSERT(r, begin == start);
    REPORTER_ASSERT(r, end == record.count());

    REPORTER_ASSERT(r, !pattern.search(&record, &begin, &end));
}
Beispiel #25
0
void SkRecordDraw(const SkRecord& record,
                  SkCanvas* canvas,
                  const SkBBoxHierarchy* bbh,
                  SkDrawPictureCallback* callback) {
    SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/);

    if (NULL != bbh) {
        // Draw only ops that affect pixels in the canvas's current clip.
        SkIRect devBounds;
        canvas->getClipDeviceBounds(&devBounds);
        SkTDArray<void*> ops;
        bbh->search(devBounds, &ops);

        // FIXME: QuadTree doesn't send these back in the order we inserted them.  :(
        // Also remove the sort in SkPictureData::getActiveOps()?
        if (ops.count() > 0) {
            SkTQSort(ops.begin(), ops.end() - 1, SkTCompareLT<void*>());
        }

        SkRecords::Draw draw(canvas);
        for (int i = 0; i < ops.count(); i++) {
            if (NULL != callback && callback->abortDrawing()) {
                return;
            }
            record.visit<void>((uintptr_t)ops[i], draw);  // See FillBounds below.
        }
    } else {
        // Draw all ops.
        for (SkRecords::Draw draw(canvas); draw.index() < record.count(); draw.next()) {
            if (NULL != callback && callback->abortDrawing()) {
                return;
            }
            record.visit<void>(draw.index(), draw);
        }
    }
}
Beispiel #26
0
void SkRecordDraw(const SkRecord& record, SkCanvas* canvas) {
    for (Draw draw(canvas); draw.index() < record.count(); draw.next()) {
        record.visit(draw.index(), draw);
    }
}
Beispiel #27
0
 void apply(const SkRecord& record) {
     for (unsigned i = 0; i < record.count(); i++) {
         record.visit<void>(i, *this);
     }
 }
Beispiel #28
0
 void apply(const SkRecord& record) {
     for (int i = 0; i < record.count(); i++) {
         record.visit(i, *this);
     }
 }