extern "C" bool complex_layers_draw_from_canvas_state(SkCanvasState* state, float left, float top, float right, float bottom, int32_t spacer) { std::unique_ptr<SkCanvas> canvas = SkCanvasStateUtils::MakeFromCanvasState(state); if (!canvas) { return false; } complex_layers_draw(canvas.get(), left, top, right, bottom, spacer); return true; }
DEF_TEST(CanvasState_test_complex_layers, reporter) { const int WIDTH = 400; const int HEIGHT = 400; const int SPACER = 10; SkRect rect = SkRect::MakeXYWH(SkIntToScalar(SPACER), SkIntToScalar(SPACER), SkIntToScalar(WIDTH-(2*SPACER)), SkIntToScalar((HEIGHT-(2*SPACER)) / 7)); const SkColorType colorTypes[] = { kRGB_565_SkColorType, kN32_SkColorType }; const int layerAlpha[] = { 255, 255, 0 }; const SkCanvas::SaveLayerFlags flags[] = { static_cast<SkCanvas::SaveLayerFlags>(SkCanvas::kDontClipToLayer_Legacy_SaveLayerFlag), 0, static_cast<SkCanvas::SaveLayerFlags>(SkCanvas::kDontClipToLayer_Legacy_SaveLayerFlag), }; REPORTER_ASSERT(reporter, sizeof(layerAlpha) == sizeof(flags)); bool (*drawFn)(SkCanvasState* state, float l, float t, float r, float b, int32_t s); OpenLibResult openLibResult(reporter); if (openLibResult.handle() != nullptr) { *(void**) (&drawFn) = dlsym(openLibResult.handle(), "complex_layers_draw_from_canvas_state"); } else { drawFn = complex_layers_draw_from_canvas_state; } REPORTER_ASSERT(reporter, drawFn); if (!drawFn) { return; } for (size_t i = 0; i < SK_ARRAY_COUNT(colorTypes); ++i) { SkBitmap bitmaps[2]; for (int j = 0; j < 2; ++j) { bitmaps[j].allocPixels(SkImageInfo::Make(WIDTH, HEIGHT, colorTypes[i], kPremul_SkAlphaType)); SkCanvas canvas(bitmaps[j]); canvas.drawColor(SK_ColorRED); for (size_t k = 0; k < SK_ARRAY_COUNT(layerAlpha); ++k) { SkTLazy<SkPaint> paint; if (layerAlpha[k] != 0xFF) { paint.init()->setAlpha(layerAlpha[k]); } // draw a rect within the layer's bounds and again outside the layer's bounds canvas.saveLayer(SkCanvas::SaveLayerRec(&rect, paint.getMaybeNull(), flags[k])); if (j) { // Capture from the first Skia. SkCanvasState* state = SkCanvasStateUtils::CaptureCanvasState(&canvas); REPORTER_ASSERT(reporter, state); // And draw to it in the second Skia. bool success = complex_layers_draw_from_canvas_state(state, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, SPACER); REPORTER_ASSERT(reporter, success); // And release it in the *first* Skia. SkCanvasStateUtils::ReleaseCanvasState(state); } else { // Draw in the first Skia. complex_layers_draw(&canvas, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, SPACER); } canvas.restore(); // translate the canvas for the next iteration canvas.translate(0, 2*(rect.height() + SPACER)); } } // now we memcmp the two bitmaps REPORTER_ASSERT(reporter, bitmaps[0].getSize() == bitmaps[1].getSize()); REPORTER_ASSERT(reporter, !memcmp(bitmaps[0].getPixels(), bitmaps[1].getPixels(), bitmaps[0].getSize())); } }