void makeMatrices() { { SkMatrix m; m.setScale(SkIntToScalar(2), SkIntToScalar(3)); fMatrices.push_back(m); } { SkMatrix m; m.setScale(SkIntToScalar(2), SkIntToScalar(2)); fMatrices.push_back(m); } { SkMatrix m; m.setSkew(SkIntToScalar(2), SkIntToScalar(3)); fMatrices.push_back(m); } { SkMatrix m; m.setSkew(SkIntToScalar(2), SkIntToScalar(2)); fMatrices.push_back(m); } { SkMatrix m; m.setRotate(SkIntToScalar(30)); fMatrices.push_back(m); } }
static void test_treatAsSprite(skiatest::Reporter* reporter) { const unsigned bilerBits = kSkSubPixelBitsForBilerp; SkMatrix mat; SkISize size; SkRandom rand; // assert: translate-only no-filter can always be treated as sprite for (int i = 0; i < 1000; ++i) { rand_matrix(&mat, rand, SkMatrix::kTranslate_Mask); for (int j = 0; j < 1000; ++j) { rand_size(&size, rand); REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, 0)); } } // assert: rotate/perspect is never treated as sprite for (int i = 0; i < 1000; ++i) { rand_matrix(&mat, rand, SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask); for (int j = 0; j < 1000; ++j) { rand_size(&size, rand); REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, 0)); REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits)); } } size.set(500, 600); const SkScalar tooMuchSubpixel = 100.1f; mat.setTranslate(tooMuchSubpixel, 0); REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits)); mat.setTranslate(0, tooMuchSubpixel); REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits)); const SkScalar tinySubPixel = 100.02f; mat.setTranslate(tinySubPixel, 0); REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, bilerBits)); mat.setTranslate(0, tinySubPixel); REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, bilerBits)); const SkScalar twoThirds = SK_Scalar1 * 2 / 3; const SkScalar bigScale = (size.width() + twoThirds) / size.width(); mat.setScale(bigScale, bigScale); REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, false)); REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits)); const SkScalar oneThird = SK_Scalar1 / 3; const SkScalar smallScale = (size.width() + oneThird) / size.width(); mat.setScale(smallScale, smallScale); REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, false)); REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits)); const SkScalar oneFortyth = SK_Scalar1 / 40; const SkScalar tinyScale = (size.width() + oneFortyth) / size.width(); mat.setScale(tinyScale, tinyScale); REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, false)); REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, bilerBits)); }
static void textonpath_slide(SkCanvas* canvas) { const char* text = "Displacement"; size_t len =strlen(text); SkPath path; path.moveTo(100, 300); path.quadTo(300, 100, 500, 300); path.offset(0, -100); SkPaint paint; paint.setAntiAlias(true); paint.setTextSize(40); paint.setStyle(SkPaint::kStroke_Style); canvas->drawPath(path, paint); paint.setStyle(SkPaint::kFill_Style); SkScalar x = 50; paint.setColor(0xFF008800); canvas->drawTextOnPathHV(text, len, path, x, paint.getTextSize()*2/3, paint); paint.setColor(SK_ColorRED); canvas->drawTextOnPathHV(text, len, path, x + 60, 0, paint); paint.setColor(SK_ColorBLUE); canvas->drawTextOnPathHV(text, len, path, x + 120, -paint.getTextSize()*2/3, paint); path.offset(0, 200); paint.setTextAlign(SkPaint::kRight_Align); text = "Matrices"; len = strlen(text); SkScalar pathLen = getpathlen(path); SkMatrix matrix; paint.setColor(SK_ColorBLACK); paint.setStyle(SkPaint::kStroke_Style); canvas->drawPath(path, paint); paint.setStyle(SkPaint::kFill_Style); paint.setTextSize(50); canvas->drawTextOnPath(text, len, path, NULL, paint); paint.setColor(SK_ColorRED); matrix.setScale(-SK_Scalar1, SK_Scalar1); matrix.postTranslate(pathLen, 0); canvas->drawTextOnPath(text, len, path, &matrix, paint); paint.setColor(SK_ColorBLUE); matrix.setScale(SK_Scalar1, -SK_Scalar1); canvas->drawTextOnPath(text, len, path, &matrix, paint); paint.setColor(0xFF008800); matrix.setScale(-SK_Scalar1, -SK_Scalar1); matrix.postTranslate(pathLen, 0); canvas->drawTextOnPath(text, len, path, &matrix, paint); }
void setWHZ(int width, int height, int zoom) { fZoom = zoom; fBounds.set(0, 0, SkIntToScalar(width * zoom), SkIntToScalar(height * zoom)); fMatrix.setScale(SkIntToScalar(zoom), SkIntToScalar(zoom)); fInverse.setScale(SK_Scalar1 / zoom, SK_Scalar1 / zoom); fShader.reset(sk_tool_utils::create_checkerboard_shader( 0xFFCCCCCC, 0xFFFFFFFF, zoom)); SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); fMinSurface.reset(SkSurface::NewRaster(info)); info = info.makeWH(width * zoom, height * zoom); fMaxSurface.reset(SkSurface::NewRaster(info)); }
static void test_decompScale(skiatest::Reporter* reporter) { SkMatrix m; m.reset(); REPORTER_ASSERT(reporter, check_decompScale(m)); m.setScale(2, 3); REPORTER_ASSERT(reporter, check_decompScale(m)); m.setRotate(35, 0, 0); REPORTER_ASSERT(reporter, check_decompScale(m)); m.setScale(1, 0); REPORTER_ASSERT(reporter, !check_decompScale(m)); }
void makeMatrices() { { SkMatrix m; m.setIdentity(); fMatrices.push_back(m); } { SkMatrix m; m.setScale(SkIntToScalar(3), SkIntToScalar(2)); fMatrices.push_back(m); } { SkMatrix m; m.setScale(SkIntToScalar(2), SkIntToScalar(2)); fMatrices.push_back(m); } { SkMatrix m; m.setScale(SkIntToScalar(1), SkIntToScalar(2)); fMatrices.push_back(m); } { SkMatrix m; m.setScale(SkIntToScalar(4), SkIntToScalar(1)); fMatrices.push_back(m); } { SkMatrix m; m.setRotate(SkIntToScalar(90)); fMatrices.push_back(m); } { SkMatrix m; m.setSkew(SkIntToScalar(2), SkIntToScalar(3)); fMatrices.push_back(m); } { SkMatrix m; m.setRotate(SkIntToScalar(60)); fMatrices.push_back(m); } }
void SkPDFDevice::internalDrawBitmap(const SkMatrix& matrix, const SkBitmap& bitmap, const SkIRect* srcRect, const SkPaint& paint) { SkIRect subset = SkIRect::MakeWH(bitmap.width(), bitmap.height()); if (srcRect && !subset.intersect(*srcRect)) return; SkPDFImage* image = SkPDFImage::CreateImage(bitmap, subset, paint); if (!image) return; SkMatrix scaled; // Adjust for origin flip. scaled.setScale(1, -1); scaled.postTranslate(0, 1); // Scale the image up from 1x1 to WxH. scaled.postScale(SkIntToScalar(subset.width()), SkIntToScalar(subset.height())); scaled.postConcat(matrix); SkMatrix curTransform = setTransform(scaled); updateGSFromPaint(paint, false); fXObjectResources.push(image); // Transfer reference. fContent.writeText("/X"); fContent.writeDecAsText(fXObjectResources.count() - 1); fContent.writeText(" Do\n"); setTransform(curTransform); }
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); }
virtual void onDraw(SkCanvas* canvas) { this->drawBG(canvas); SkMatrix matrix; SkGroupShape* gs = new SkGroupShape; SkAutoUnref aur(gs); gs->appendShape(&fGroup); matrix.setScale(-SK_Scalar1, SK_Scalar1); matrix.postTranslate(SkIntToScalar(220), SkIntToScalar(240)); gs->appendShape(&fGroup, matrix); matrix.setTranslate(SkIntToScalar(240), 0); matrix.preScale(SK_Scalar1*2, SK_Scalar1*2); gs->appendShape(&fGroup, matrix); #if 1 SkPicture* pict = new SkPicture; SkCanvas* cv = pict->beginRecording(1000, 1000); cv->scale(SK_ScalarHalf, SK_ScalarHalf); gs->draw(cv); cv->translate(SkIntToScalar(680), SkIntToScalar(480)); cv->scale(-SK_Scalar1, SK_Scalar1); gs->draw(cv); pict->endRecording(); canvas->drawPicture(*pict); pict->unref(); #endif }
static void r7(SkLayerRasterizer* rast, SkPaint& p) { SkMatrix lattice; lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0); lattice.postSkew(SK_Scalar1/3, 0, 0, 0); p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*4, lattice))->unref(); rast->addLayer(p); }
static SkPathEffect* makepe(float interp, SkTDArray<SkPoint>* pts) { SkMatrix lattice; SkScalar rad = 3 + SkIntToScalar(4) * (1 - interp); lattice.setScale(rad*2, rad*2, 0, 0); lattice.postSkew(SK_Scalar1/3, 0, 0, 0); return new Dot2DPathEffect(rad, lattice, pts); }
virtual void onDraw(SkCanvas* canvas) { this->drawBG(canvas); SkMatrix saveM = *fMatrixRefs[3]; SkScalar c = SkIntToScalar(50); fMatrixRefs[3]->preRotate(SkIntToScalar(30), c, c); SkMatrix matrix; SkGroupShape* gs = new SkGroupShape; SkAutoUnref aur(gs); gs->appendShape(&fGroup); matrix.setScale(-SK_Scalar1, SK_Scalar1); matrix.postTranslate(SkIntToScalar(220), SkIntToScalar(240)); gs->appendShape(&fGroup, matrix); matrix.setTranslate(SkIntToScalar(240), 0); matrix.preScale(SK_Scalar1*2, SK_Scalar1*2); gs->appendShape(&fGroup, matrix); #if 0 canvas->drawShape(gs); #else SkPicture pict; SkCanvas* cv = pict.beginRecording(1000, 1000); cv->scale(SK_ScalarHalf, SK_ScalarHalf); cv->drawShape(gs); cv->translate(SkIntToScalar(680), SkIntToScalar(480)); cv->scale(-SK_Scalar1, SK_Scalar1); cv->drawShape(gs); pict.endRecording(); canvas->drawPicture(pict); #endif *fMatrixRefs[3] = saveM; }
static void make_strip(Rec* rec, int texWidth, int texHeight) { const SkScalar tx = SkIntToScalar(texWidth); const SkScalar ty = SkIntToScalar(texHeight); const int n = 24; rec->fMode = SkCanvas::kTriangleStrip_VertexMode; rec->fCount = 2 * (n + 1); rec->fVerts = new SkPoint[rec->fCount]; rec->fTexs = new SkPoint[rec->fCount]; SkPoint* v = rec->fVerts; SkPoint* t = rec->fTexs; for (int i = 0; i < n; i++) { SkScalar cos; SkScalar sin = SkScalarSinCos(SK_ScalarPI * 2 * i / n, &cos); v[i*2 + 0].set(cos/2, sin/2); v[i*2 + 1].set(cos, sin); t[i*2 + 0].set(tx * i / n, ty); t[i*2 + 1].set(tx * i / n, 0); } v[2*n + 0] = v[0]; v[2*n + 1] = v[1]; t[2*n + 0].set(tx, ty); t[2*n + 1].set(tx, 0); SkMatrix m; m.setScale(SkIntToScalar(100), SkIntToScalar(100)); m.postTranslate(SkIntToScalar(110), SkIntToScalar(110)); m.mapPoints(v, rec->fCount); }
// Set a bitmap shader that mimics dashing by width-on, width-off. // Returns false if it could not succeed (e.g. there was an existing shader) static bool setBitmapDash(SkPaint* paint, int width) { if (width <= 0 || paint->getShader()) return false; SkColor c = paint->getColor(); SkBitmap bm; bm.setConfig(SkBitmap::kARGB_8888_Config, 2, 1); bm.allocPixels(); bm.lockPixels(); // set the ON pixel *bm.getAddr32(0, 0) = SkPreMultiplyARGB(0xFF, SkColorGetR(c), SkColorGetG(c), SkColorGetB(c)); // set the OFF pixel *bm.getAddr32(1, 0) = 0; bm.unlockPixels(); SkMatrix matrix; matrix.setScale(SkIntToScalar(width), SK_Scalar1); SkShader* s = SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode, SkShader::kClamp_TileMode); s->setLocalMatrix(matrix); paint->setShader(s)->unref(); return true; }
void draw(SkCanvas* canvas, const SkRect& rect, const SkSize& deviceSize, SkPaint::FilterLevel filterLevel, SkImageFilter* input = NULL) { SkRect dstRect; canvas->getTotalMatrix().mapRect(&dstRect, rect); canvas->save(); SkScalar deviceScaleX = SkScalarDiv(deviceSize.width(), dstRect.width()); SkScalar deviceScaleY = SkScalarDiv(deviceSize.height(), dstRect.height()); canvas->translate(rect.x(), rect.y()); canvas->scale(deviceScaleX, deviceScaleY); canvas->translate(-rect.x(), -rect.y()); SkMatrix matrix; matrix.setScale(SkScalarInvert(deviceScaleX), SkScalarInvert(deviceScaleY)); SkAutoTUnref<SkImageFilter> imageFilter( SkMatrixImageFilter::Create(matrix, filterLevel, input)); SkPaint filteredPaint; filteredPaint.setImageFilter(imageFilter.get()); canvas->saveLayer(&rect, &filteredPaint); SkPaint paint; paint.setColor(0xFF00FF00); SkRect ovalRect = rect; ovalRect.inset(SkIntToScalar(4), SkIntToScalar(4)); canvas->drawOval(ovalRect, paint); canvas->restore(); // for saveLayer canvas->restore(); }
void make_fan(Rec* rec, int texWidth, int texHeight) { const SkScalar tx = SkIntToScalar(texWidth); const SkScalar ty = SkIntToScalar(texHeight); const int n = 24; rec->fMode = SkCanvas::kTriangleFan_VertexMode; rec->fCount = n + 2; rec->fVerts = new SkPoint[rec->fCount]; rec->fTexs = new SkPoint[rec->fCount]; SkPoint* v = rec->fVerts; SkPoint* t = rec->fTexs; v[0].set(0, 0); t[0].set(0, 0); for (int i = 0; i < n; i++) { SkScalar cos; SkScalar sin = SkScalarSinCos(SK_ScalarPI * 2 * i / n, &cos); v[i+1].set(cos, sin); t[i+1].set(i*tx/n, ty); } v[n+1] = v[1]; t[n+1].set(tx, ty); SkMatrix m; m.setScale(SkIntToScalar(100), SkIntToScalar(100)); m.postTranslate(SkIntToScalar(110), SkIntToScalar(110)); m.mapPoints(v, rec->fCount); }
static SkMatrix TestMatrix() { SkMatrix matrix; matrix.reset(); matrix.setScale(SkIntToScalar(2), SkIntToScalar(3)); return matrix; }
SkMatrix onGetInitialTransform() const override { SkMatrix result; SkScalar scale = 0.8f; result.setScale(scale, scale); result.postTranslate(SkIntToScalar(7), SkIntToScalar(23)); return result; }
void onDraw(SkCanvas* canvas) override { // The PDF device has already clipped to the content area, but we // do it again here so that the raster and pdf results are consistent. canvas->clipRect(SkRect::MakeWH(SkIntToScalar(320), SkIntToScalar(240))); SkMatrix canvasScale; SkScalar scale = 0.7f; canvasScale.setScale(scale, scale); canvas->concat(canvasScale); // Background shader. SkPaint paint; paint.setShader(MakeShader(559, 387, false))->unref(); SkRect r = SkRect::MakeXYWH(SkIntToScalar(-12), SkIntToScalar(-41), SkIntToScalar(571), SkIntToScalar(428)); canvas->drawRect(r, paint); // Constrained shader. paint.setShader(MakeShader(101, 151, true))->unref(); r = SkRect::MakeXYWH(SkIntToScalar(43), SkIntToScalar(71), SkIntToScalar(101), SkIntToScalar(151)); canvas->clipRect(r); canvas->drawRect(r, paint); }
static void r7(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) { SkMatrix lattice; lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0); lattice.postSkew(SK_Scalar1/3, 0, 0, 0); p.setPathEffect(MakeDotEffect(SK_Scalar1*4, lattice)); rastBuilder->addLayer(p); }
static void draw_gradients(SkCanvas* canvas, sk_sp<SkShader> (*makeShader)(const SkPoint[2], const SkMatrix&), const SkPoint ptsArray[][2], int numImages) { // Use some nice prime numbers for the rectangle and matrix with // different scaling along the x and y axes (which is the bug this // test addresses, where incorrect order of operations mixed up the axes) SkRect rectGrad = { SkIntToScalar(43), SkIntToScalar(61), SkIntToScalar(181), SkIntToScalar(167) }; SkMatrix shaderMat; shaderMat.setScale(rectGrad.width(), rectGrad.height()); shaderMat.postTranslate(rectGrad.left(), rectGrad.top()); canvas->save(); for (int i = 0; i < numImages; i++) { // Advance line downwards if necessary. if (i % IMAGES_X == 0 && i != 0) { canvas->restore(); canvas->translate(0, TESTGRID_Y); canvas->save(); } SkPaint paint; paint.setShader(makeShader(*ptsArray, shaderMat)); canvas->drawRect(rectGrad, paint); // Advance to next position. canvas->translate(TESTGRID_X, 0); ptsArray++; } canvas->restore(); }
static void test_transform(skiatest::Reporter* reporter) { SkPath p, p1; static const SkPoint pts[] = { { 0, 0 }, { SkIntToScalar(10), SkIntToScalar(10) }, { SkIntToScalar(20), SkIntToScalar(10) }, { SkIntToScalar(20), 0 }, { 0, 0 }, { 0, SkIntToScalar(10) }, { SkIntToScalar(1), SkIntToScalar(10) } }; p.moveTo(pts[0]); p.lineTo(pts[1]); p.quadTo(pts[2], pts[3]); p.cubicTo(pts[4], pts[5], pts[6]); SkMatrix matrix; matrix.reset(); p.transform(matrix, &p1); REPORTER_ASSERT(reporter, p == p1); matrix.setScale(SK_Scalar1 * 2, SK_Scalar1 * 3); p.transform(matrix, &p1); SkPoint pts1[7]; int count = p1.getPoints(pts1, 7); REPORTER_ASSERT(reporter, 7 == count); for (int i = 0; i < count; ++i) { SkPoint newPt = SkPoint::Make(pts[i].fX * 2, pts[i].fY * 3); REPORTER_ASSERT(reporter, newPt == pts1[i]); } }
virtual void onDraw(SkCanvas* canvas) { SkPoint pts[2] = { { 0, 0 }, { SkIntToScalar(100), SkIntToScalar(100) } }; SkShader::TileMode tm = SkShader::kClamp_TileMode; SkRect r = { 0, 0, SkIntToScalar(100), SkIntToScalar(100) }; SkPaint paint; paint.setAntiAlias(true); paint.setDither(fDither); canvas->translate(SkIntToScalar(20), SkIntToScalar(20)); for (size_t i = 0; i < SK_ARRAY_COUNT(gGradData); i++) { canvas->save(); for (size_t j = 0; j < SK_ARRAY_COUNT(gGradMakers); j++) { SkMatrix scale = SkMatrix::I(); if (i == 5) { // if the clamp case scale.setScale(0.5f, 0.5f); scale.postTranslate(25.f, 25.f); } paint.setShader(gGradMakers[j](pts, gGradData[i], tm, scale)); canvas->drawRect(r, paint); canvas->translate(0, SkIntToScalar(120)); } canvas->restore(); canvas->translate(SkIntToScalar(120), 0); } }
static void scale_to_width(SkPath* path, SkScalar dstWidth) { const SkRect& bounds = path->getBounds(); SkScalar scale = dstWidth / bounds.width(); SkMatrix matrix; matrix.setScale(scale, scale); path->transform(matrix); }
static void setup_matrices(int numQuads, Func f) { // We draw a really small triangle so we are not fill rate limited for (int i = 0 ; i < numQuads; i++) { SkMatrix m = SkMatrix::I(); m.setScale(0.0001f, 0.0001f); f(m); } }
void Matrix::NativeSetScale( /* [in] */ Int64 nObj, /* [in] */ Float sx, /* [in] */ Float sy) { SkMatrix* obj = reinterpret_cast<SkMatrix*>(nObj); obj->setScale(sx, sy); }
void GrDrawPathRangeBatch::onDraw(GrBatchFlushState* state, const SkRect& bounds) { const Draw& head = *fDraws.head(); SkMatrix drawMatrix(this->viewMatrix()); drawMatrix.preScale(fScale, fScale); drawMatrix.preTranslate(head.fX, head.fY); SkMatrix localMatrix; localMatrix.setScale(fScale, fScale); localMatrix.preTranslate(head.fX, head.fY); SkAutoTUnref<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color(), this->overrides(), drawMatrix, localMatrix)); if (fDraws.count() == 1) { const InstanceData& instances = *head.fInstanceData; state->gpu()->pathRendering()->drawPaths(*this->pipeline(), *pathProc, this->stencilPassSettings(), fPathRange.get(), instances.indices(), GrPathRange::kU16_PathIndexType, instances.transformValues(), instances.transformType(), instances.count()); } else { int floatsPerTransform = GrPathRendering::PathTransformSize(this->transformType()); SkAutoSTMalloc<4096, float> transformStorage(floatsPerTransform * fTotalPathCount); SkAutoSTMalloc<2048, uint16_t> indexStorage(fTotalPathCount); int idx = 0; for (DrawList::Iter iter(fDraws); iter.get(); iter.next()) { const Draw& draw = *iter.get(); const InstanceData& instances = *draw.fInstanceData; memcpy(&indexStorage[idx], instances.indices(), instances.count() * sizeof(uint16_t)); pre_translate_transform_values(instances.transformValues(), this->transformType(), instances.count(), draw.fX - head.fX, draw.fY - head.fY, &transformStorage[floatsPerTransform * idx]); idx += instances.count(); // TODO: Support mismatched transform types if we start using more types other than 2D. SkASSERT(instances.transformType() == this->transformType()); } SkASSERT(idx == fTotalPathCount); state->gpu()->pathRendering()->drawPaths(*this->pipeline(), *pathProc, this->stencilPassSettings(), fPathRange.get(), indexStorage, GrPathRange::kU16_PathIndexType, transformStorage, this->transformType(), fTotalPathCount); } }
virtual void onDraw(SkCanvas* canvas) { SkMatrix m; m.reset(); m.setRotate(33 * SK_Scalar1); m.postScale(3000 * SK_Scalar1, 3000 * SK_Scalar1); m.postTranslate(6000 * SK_Scalar1, -5000 * SK_Scalar1); canvas->concat(m); SkPaint paint; paint.setColor(SK_ColorRED); paint.setAntiAlias(true); bool success = m.invert(&m); SkASSERT(success); (void) success; // silence compiler :( SkPath path; SkPoint pt = {10 * SK_Scalar1, 10 * SK_Scalar1}; SkScalar small = 1 / (500 * SK_Scalar1); m.mapPoints(&pt, 1); path.addCircle(pt.fX, pt.fY, small); canvas->drawPath(path, paint); pt.set(30 * SK_Scalar1, 10 * SK_Scalar1); m.mapPoints(&pt, 1); SkRect rect = {pt.fX - small, pt.fY - small, pt.fX + small, pt.fY + small}; canvas->drawRect(rect, paint); SkBitmap bmp; bmp.setConfig(SkBitmap::kARGB_8888_Config, 2, 2); bmp.allocPixels(); bmp.lockPixels(); uint32_t* pixels = reinterpret_cast<uint32_t*>(bmp.getPixels()); pixels[0] = SkPackARGB32(0xFF, 0xFF, 0x00, 0x00); pixels[1] = SkPackARGB32(0xFF, 0x00, 0xFF, 0x00); pixels[2] = SkPackARGB32(0x80, 0x00, 0x00, 0x00); pixels[3] = SkPackARGB32(0xFF, 0x00, 0x00, 0xFF); bmp.unlockPixels(); pt.set(30 * SK_Scalar1, 30 * SK_Scalar1); m.mapPoints(&pt, 1); SkShader* shader = SkShader::CreateBitmapShader( bmp, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); SkMatrix s; s.reset(); s.setScale(SK_Scalar1 / 1000, SK_Scalar1 / 1000); shader->setLocalMatrix(s); paint.setShader(shader)->unref(); paint.setAntiAlias(false); paint.setFilterLevel(SkPaint::kLow_FilterLevel); rect.setLTRB(pt.fX - small, pt.fY - small, pt.fX + small, pt.fY + small); canvas->drawRect(rect, paint); }
// Create a selection of imagefilter-based paints to test static void create_paints(SkImageFilter* source, SkTArray<SkPaint>* paints) { { SkMatrix scale; scale.setScale(2.0f, 2.0f); SkAutoTUnref<SkImageFilter> scaleMIF( SkImageFilter::CreateMatrixFilter(scale, kLow_SkFilterQuality, source)); add_paint(scaleMIF, paints); } { SkMatrix rot; rot.setRotate(-33.3f); SkAutoTUnref<SkImageFilter> rotMIF( SkImageFilter::CreateMatrixFilter(rot, kLow_SkFilterQuality, source)); add_paint(rotMIF, paints); } { static const SkDropShadowImageFilter::ShadowMode kBoth = SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode; SkAutoTUnref<SkDropShadowImageFilter> dsif( SkDropShadowImageFilter::Create(10.0f, 10.0f, 3.0f, 3.0f, SK_ColorRED, kBoth, source, nullptr)); add_paint(dsif, paints); } { SkAutoTUnref<SkDropShadowImageFilter> dsif( SkDropShadowImageFilter::Create(27.0f, 27.0f, 3.0f, 3.0f, SK_ColorRED, SkDropShadowImageFilter::kDrawShadowOnly_ShadowMode, source, nullptr)); add_paint(dsif, paints); } { SkAutoTUnref<SkBlurImageFilter> bif(SkBlurImageFilter::Create(3, 3, source)); add_paint(bif, paints); } { SkAutoTUnref<SkOffsetImageFilter> oif(SkOffsetImageFilter::Create(15, 15, source)); add_paint(oif, paints); } }
static SkPathEffect* MakeTileEffect() { SkMatrix m; m.setScale(SkIntToScalar(12), SkIntToScalar(12)); SkPath path; path.addCircle(0, 0, SkIntToScalar(5)); return SkPath2DPathEffect::Create(m, path); }