void onDraw(SkCanvas* canvas) override { const struct { SkISize size; SkScalar scaleX, scaleY; SkScalar opacity; } configs[] = { { SkISize::Make(200, 100), 1, 1, 1 }, { SkISize::Make(200, 200), 1, 1, 1 }, { SkISize::Make(200, 200), 1, 2, 1 }, { SkISize::Make(400, 200), 2, 2, 1 }, { SkISize::Make(200, 100), 1, 1, 0.9f }, { SkISize::Make(200, 200), 1, 1, 0.75f }, { SkISize::Make(200, 200), 1, 2, 0.5f }, { SkISize::Make(400, 200), 2, 2, 0.25f }, { SkISize::Make(200, 200), 0.5f, 1, 1 }, { SkISize::Make(200, 200), 1, 0.5f, 1 }, { SkISize::Make(200, 200), 0.5f, 0.5f, 1 }, { SkISize::Make(200, 200), 2, 2, 1 }, { SkISize::Make(200, 100), -1, 1, 1 }, { SkISize::Make(200, 100), 1, -1, 1 }, { SkISize::Make(200, 100), -1, -1, 1 }, { SkISize::Make(200, 100), -1, -1, 0.5f }, }; const unsigned kDrawsPerRow = 4; const SkScalar kDrawSize = 250; for (size_t i = 0; i < SK_ARRAY_COUNT(configs); ++i) { SkPaint p; p.setAlpha(SkScalarRoundToInt(255 * configs[i].opacity)); SkMatrix m = SkMatrix::MakeScale(configs[i].scaleX, configs[i].scaleY); if (configs[i].scaleX < 0) { m.postTranslate(SkIntToScalar(configs[i].size.width()), 0); } if (configs[i].scaleY < 0) { m.postTranslate(0, SkIntToScalar(configs[i].size.height())); } SkAutoTDelete<SkImageGenerator> gen( SkImageGenerator::NewFromPicture(configs[i].size, fPicture.get(), &m, p.getAlpha() != 255 ? &p : nullptr)); SkBitmap bm; gen->generateBitmap(&bm); const SkScalar x = kDrawSize * (i % kDrawsPerRow); const SkScalar y = kDrawSize * (i / kDrawsPerRow); p.setColor(0xfff0f0f0); p.setAlpha(255); canvas->drawRect(SkRect::MakeXYWH(x, y, SkIntToScalar(bm.width()), SkIntToScalar(bm.height())), p); canvas->drawBitmap(bm, x, y); } }
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 SkBitmapDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int x, int y, const SkPaint& paint) { SkASSERT(!srcImg->isTextureBacked()); SkBitmap resultBM; SkImageFilter* filter = paint.getImageFilter(); if (filter) { SkIPoint offset = SkIPoint::Make(0, 0); SkMatrix matrix = *draw.fMatrix; matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y)); const SkIRect clipBounds = draw.fRC->getBounds().makeOffset(-x, -y); SkAutoTUnref<SkImageFilterCache> cache(this->getImageFilterCache()); SkImageFilter::OutputProperties outputProperties(fBitmap.colorSpace()); SkImageFilter::Context ctx(matrix, clipBounds, cache.get(), outputProperties); sk_sp<SkSpecialImage> resultImg(filter->filterImage(srcImg, ctx, &offset)); if (resultImg) { SkPaint tmpUnfiltered(paint); tmpUnfiltered.setImageFilter(nullptr); if (resultImg->getROPixels(&resultBM)) { this->drawSprite(draw, resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered); } } } else { if (srcImg->getROPixels(&resultBM)) { this->drawSprite(draw, resultBM, x, y, paint); } } }
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 }
const GrFragmentProcessor* GrTextureAdjuster::createFragmentProcessor( const SkMatrix& origTextureMatrix, const SkRect& origConstraintRect, FilterConstraint filterConstraint, bool coordsLimitedToConstraintRect, const GrTextureParams::FilterMode* filterOrNullForBicubic) { SkMatrix textureMatrix = origTextureMatrix; const SkIRect* contentArea = this->contentAreaOrNull(); // Convert the constraintRect to be relative to the texture rather than the content area so // that both rects are in the same coordinate system. SkTCopyOnFirstWrite<SkRect> constraintRect(origConstraintRect); if (contentArea) { SkScalar l = SkIntToScalar(contentArea->fLeft); SkScalar t = SkIntToScalar(contentArea->fTop); constraintRect.writable()->offset(l, t); textureMatrix.postTranslate(l, t); } SkRect domain; GrTextureParams params; if (filterOrNullForBicubic) { params.setFilterMode(*filterOrNullForBicubic); } SkAutoTUnref<GrTexture> texture(this->refTextureSafeForParams(params, nullptr)); if (!texture) { return nullptr; } // If we made a copy then we only copied the contentArea, in which case the new texture is all // content. if (texture != this->originalTexture()) { contentArea = nullptr; } DomainMode domainMode = determine_domain_mode(*constraintRect, filterConstraint, coordsLimitedToConstraintRect, texture->width(), texture->height(), contentArea, filterOrNullForBicubic, &domain); if (kTightCopy_DomainMode == domainMode) { // TODO: Copy the texture and adjust the texture matrix (both parts need to consider // non-int constraint rect) // For now: treat as bilerp and ignore what goes on above level 0. // We only expect MIP maps to require a tight copy. SkASSERT(filterOrNullForBicubic && GrTextureParams::kMipMap_FilterMode == *filterOrNullForBicubic); static const GrTextureParams::FilterMode kBilerp = GrTextureParams::kBilerp_FilterMode; domainMode = determine_domain_mode(*constraintRect, filterConstraint, coordsLimitedToConstraintRect, texture->width(), texture->height(), contentArea, &kBilerp, &domain); SkASSERT(kTightCopy_DomainMode != domainMode); } SkASSERT(kNoDomain_DomainMode == domainMode || (domain.fLeft <= domain.fRight && domain.fTop <= domain.fBottom)); textureMatrix.postIDiv(texture->width(), texture->height()); return create_fp_for_domain_and_filter(texture, textureMatrix, domainMode, domain, filterOrNullForBicubic); }
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); }
ShapesGM() { SkMatrix m; fGroup.appendShape(make_shape0(false))->unref(); m.setRotate(SkIntToScalar(30), SkIntToScalar(50), SkIntToScalar(50)); m.postTranslate(0, SkIntToScalar(120)); fGroup.appendShape(make_shape0(true), m)->unref(); m.setTranslate(SkIntToScalar(120), 0); fGroup.appendShape(make_shape1(), m)->unref(); m.postTranslate(0, SkIntToScalar(120)); fGroup.appendShape(make_shape2(), m)->unref(); for (size_t i = 0; i < SK_ARRAY_COUNT(fMatrixRefs); i++) { SkSafeRef(fMatrixRefs[i] = fGroup.getShapeMatrixRef(i)); } }
SkMatrix onGetInitialTransform() const override { SkMatrix result; SkScalar scale = 0.8f; result.setScale(scale, scale); result.postTranslate(SkIntToScalar(7), SkIntToScalar(23)); return result; }
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); }
static void scaleMatrix(const SkPath& one, const SkPath& two, SkMatrix& scale) { SkRect larger = one.getBounds(); larger.join(two.getBounds()); SkScalar largerWidth = larger.width(); if (largerWidth < 4) { largerWidth = 4; } SkScalar largerHeight = larger.height(); if (largerHeight < 4) { largerHeight = 4; } SkScalar hScale = (bitWidth - 2) / largerWidth; SkScalar vScale = (bitHeight - 2) / largerHeight; scale.reset(); scale.preScale(hScale, vScale); larger.fLeft *= hScale; larger.fRight *= hScale; larger.fTop *= vScale; larger.fBottom *= vScale; SkScalar dx = -16000 > larger.fLeft ? -16000 - larger.fLeft : 16000 < larger.fRight ? 16000 - larger.fRight : 0; SkScalar dy = -16000 > larger.fTop ? -16000 - larger.fTop : 16000 < larger.fBottom ? 16000 - larger.fBottom : 0; scale.postTranslate(dx, dy); }
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); } }
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); }
void SkBaseDevice::drawSpriteWithFilter(const SkDraw& draw, const SkBitmap& bitmap, int x, int y, const SkPaint& paint) { SkImageFilter* filter = paint.getImageFilter(); SkASSERT(filter); SkIPoint offset = SkIPoint::Make(0, 0); SkMatrix matrix = *draw.fMatrix; matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y)); const SkIRect clipBounds = draw.fRC->getBounds().makeOffset(-x, -y); SkAutoTUnref<SkImageFilterCache> cache(this->getImageFilterCache()); SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); sk_sp<SkSpecialImage> srcImg(SkSpecialImage::internal_fromBM(bitmap, &this->surfaceProps())); if (!srcImg) { return; // something disastrous happened } sk_sp<SkSpecialImage> resultImg(filter->filterImage(srcImg.get(), ctx, &offset)); if (resultImg) { SkPaint tmpUnfiltered(paint); tmpUnfiltered.setImageFilter(nullptr); SkBitmap resultBM; if (resultImg->internal_getBM(&resultBM)) { // TODO: add drawSprite(SkSpecialImage) to SkDevice? (see skbug.com/5073) this->drawSprite(draw, resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered); } } }
void DrawTargetSkia::MaskSurface(const Pattern &aSource, SourceSurface *aMask, Point aOffset, const DrawOptions &aOptions) { MarkChanged(); AutoPaintSetup paint(mCanvas.get(), aOptions, aSource); TempBitmap bitmap = GetBitmapForSurface(aMask); if (bitmap.mBitmap.colorType() == kAlpha_8_SkColorType) { mCanvas->drawBitmap(bitmap.mBitmap, aOffset.x, aOffset.y, &paint.mPaint); } else { SkPaint maskPaint; TempBitmap tmpBitmap; SetPaintPattern(maskPaint, SurfacePattern(aMask, ExtendMode::CLAMP), tmpBitmap); SkMatrix transform = maskPaint.getShader()->getLocalMatrix(); transform.postTranslate(SkFloatToScalar(aOffset.x), SkFloatToScalar(aOffset.y)); maskPaint.getShader()->setLocalMatrix(transform); SkLayerRasterizer::Builder builder; builder.addLayer(maskPaint); SkAutoTUnref<SkRasterizer> raster(builder.detachRasterizer()); paint.mPaint.setRasterizer(raster.get()); IntSize size = aMask->GetSize(); Rect rect = Rect(aOffset.x, aOffset.y, size.width, size.height); mCanvas->drawRect(RectToSkRect(rect), paint.mPaint); } }
GrTexture* SkPictureImageGenerator::onGenerateTexture(GrContext* ctx, SkImageUsageType usage, const SkIRect* subset) { const SkImageInfo& info = this->getInfo(); SkImageInfo surfaceInfo = subset ? info.makeWH(subset->width(), subset->height()) : info; // // TODO: respect the usage, by possibly creating a different (pow2) surface // SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(ctx, SkSurface::kYes_Budgeted, surfaceInfo)); if (!surface.get()) { return nullptr; } SkMatrix matrix = fMatrix; if (subset) { matrix.postTranslate(-subset->x(), -subset->y()); } surface->getCanvas()->clear(0); // does NewRenderTarget promise to do this for us? surface->getCanvas()->drawPicture(fPicture, &matrix, fPaint.getMaybeNull()); SkAutoTUnref<SkImage> image(surface->newImageSnapshot()); if (!image.get()) { return nullptr; } return SkSafeRef(image->getTexture()); }
void DrawTargetSkia::MaskSurface(const Pattern &aSource, SourceSurface *aMask, Point aOffset, const DrawOptions &aOptions) { MarkChanged(); AutoPaintSetup paint(mCanvas.get(), aOptions, aSource); SkPaint maskPaint; TempBitmap tmpBitmap; SetPaintPattern(maskPaint, SurfacePattern(aMask, ExtendMode::CLAMP), tmpBitmap); SkMatrix transform = maskPaint.getShader()->getLocalMatrix(); transform.postTranslate(SkFloatToScalar(aOffset.x), SkFloatToScalar(aOffset.y)); maskPaint.getShader()->setLocalMatrix(transform); SkLayerRasterizer *raster = new SkLayerRasterizer(); raster->addLayer(maskPaint); SkSafeUnref(paint.mPaint.setRasterizer(raster)); IntSize size = aMask->GetSize(); Rect rect = Rect(aOffset.x, aOffset.y, size.width, size.height); mCanvas->drawRect(RectToSkRect(rect), paint.mPaint); }
void QuiltTask::draw() { SkAutoTUnref<SkPicture> recorded(RecordPicture(fGM.get())); SkBitmap full; SetupBitmap(fReference.colorType(), fGM.get(), &full); SkCanvas fullCanvas(full); SkBitmap tile; tile.allocPixels(SkImageInfo::Make(FLAGS_quiltTile, FLAGS_quiltTile, fReference.colorType(), kPremul_SkAlphaType)); SkCanvas tileCanvas(tile); for (int y = 0; y < tiles_needed(full.height(), tile.height()); y++) { for (int x = 0; x < tiles_needed(full.width(), tile.width()); x++) { SkAutoCanvasRestore ar(&tileCanvas, true/*also save now*/); const SkScalar xOffset = SkIntToScalar(x * tile.width()), yOffset = SkIntToScalar(y * tile.height()); SkMatrix matrix = tileCanvas.getTotalMatrix(); matrix.postTranslate(-xOffset, -yOffset); tileCanvas.setMatrix(matrix); recorded->draw(&tileCanvas); tileCanvas.flush(); fullCanvas.drawBitmap(tile, xOffset, yOffset, NULL); } } if (!BitmapsEqual(full, fReference)) { this->fail(); this->spawnChild(SkNEW_ARGS(WriteTask, (*this, full))); } }
static void __createRotationMatrix(int rotation, int width, int height, SkMatrix &outMatrix) { // set the position of the image to the middle of the screen outMatrix.setRotate(rotation, width / 2, height / 2); outMatrix.postTranslate((DISPLAY_WIDTH - width) / 2, (DISPLAY_HEIGHT - height) / 2); }
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(); }
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; }
void Matrix::NativePostTranslate( /* [in] */ Int64 nObj, /* [in] */ Float dx, /* [in] */ Float dy) { SkMatrix* obj = reinterpret_cast<SkMatrix*>(nObj); obj->postTranslate(dx, dy); }
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); }
bool SkLayerRasterizer::onRasterize(const SkPath& path, const SkMatrix& matrix, const SkIRect* clipBounds, SkMask* mask, SkMask::CreateMode mode) const { SkASSERT(fLayers); if (fLayers->empty()) { return false; } if (SkMask::kJustRenderImage_CreateMode != mode) { if (!compute_bounds(*fLayers, path, matrix, clipBounds, &mask->fBounds)) return false; } if (SkMask::kComputeBoundsAndRenderImage_CreateMode == mode) { mask->fFormat = SkMask::kA8_Format; mask->fRowBytes = mask->fBounds.width(); size_t size = mask->computeImageSize(); if (0 == size) { return false; // too big to allocate, abort } mask->fImage = SkMask::AllocImage(size); memset(mask->fImage, 0, size); } if (SkMask::kJustComputeBounds_CreateMode != mode) { SkBitmap device; SkRasterClip rectClip; SkDraw draw; SkMatrix translatedMatrix; // this translates us to our local pixels SkMatrix drawMatrix; // this translates the path by each layer's offset rectClip.setRect(SkIRect::MakeWH(mask->fBounds.width(), mask->fBounds.height())); translatedMatrix = matrix; translatedMatrix.postTranslate(-SkIntToScalar(mask->fBounds.fLeft), -SkIntToScalar(mask->fBounds.fTop)); device.installMaskPixels(*mask); draw.fBitmap = &device; draw.fMatrix = &drawMatrix; draw.fRC = &rectClip; draw.fClip = &rectClip.bwRgn(); // we set the matrixproc in the loop, as the matrix changes each time (potentially) SkDeque::F2BIter iter(*fLayers); SkLayerRasterizer_Rec* rec; while ((rec = (SkLayerRasterizer_Rec*)iter.next()) != NULL) { drawMatrix = translatedMatrix; drawMatrix.preTranslate(rec->fOffset.fX, rec->fOffset.fY); draw.drawPath(path, rec->fPaint); } } return true; }
bool SkLayerRasterizer::onRasterize(const SkPath& path, const SkMatrix& matrix, const SkIRect* clipBounds, SkMask* mask, SkMask::CreateMode mode) { if (fLayers.empty()) return false; if (SkMask::kJustRenderImage_CreateMode != mode) { if (!compute_bounds(fLayers, path, matrix, clipBounds, &mask->fBounds)) return false; } if (SkMask::kComputeBoundsAndRenderImage_CreateMode == mode) { mask->fFormat = SkMask::kA8_Format; mask->fRowBytes = SkToU16(mask->fBounds.width()); mask->fImage = SkMask::AllocImage(mask->computeImageSize()); memset(mask->fImage, 0, mask->computeImageSize()); } if (SkMask::kJustComputeBounds_CreateMode != mode) { SkBitmap device; SkDraw draw; SkMatrix translatedMatrix; // this translates us to our local pixels SkMatrix drawMatrix; // this translates the path by each layer's offset SkRegion rectClip; rectClip.setRect(0, 0, mask->fBounds.width(), mask->fBounds.height()); translatedMatrix = matrix; translatedMatrix.postTranslate(-SkIntToScalar(mask->fBounds.fLeft), -SkIntToScalar(mask->fBounds.fTop)); device.setConfig(SkBitmap::kA8_Config, mask->fBounds.width(), mask->fBounds.height(), mask->fRowBytes); device.setPixels(mask->fImage); draw.fBitmap = &device; draw.fMatrix = &drawMatrix; draw.fClip = &rectClip; // we set the matrixproc in the loop, as the matrix changes each time (potentially) draw.fBounder = NULL; SkDeque::Iter iter(fLayers); SkLayerRasterizer_Rec* rec; while ((rec = (SkLayerRasterizer_Rec*)iter.next()) != NULL) { drawMatrix = translatedMatrix; drawMatrix.preTranslate(rec->fOffset.fX, rec->fOffset.fY); draw.drawPath(path, rec->fPaint); } } return true; }
void SkMatrixImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const { SkRect bounds = src; if (getInput(0)) { getInput(0)->computeFastBounds(src, &bounds); } SkMatrix matrix; matrix.setTranslate(-bounds.x(), -bounds.y()); matrix.postConcat(fTransform); matrix.postTranslate(bounds.x(), bounds.y()); matrix.mapRect(dst, bounds); }
/** * We need to handle setMatrix specially as it overwrites the matrix in each * canvas unlike all other matrix operations (i.e. translate, scale, etc) which * just pre-concatenate with the existing matrix. */ void SkCanvasStack::didSetMatrix(const SkMatrix& matrix) { SkASSERT(fList.count() == fCanvasData.count()); for (int i = 0; i < fList.count(); ++i) { SkMatrix tempMatrix = matrix; tempMatrix.postTranslate(SkIntToScalar(-fCanvasData[i].origin.x()), SkIntToScalar(-fCanvasData[i].origin.y())); fList[i]->setMatrix(tempMatrix); } this->SkCanvas::didSetMatrix(matrix); }
void onOnceBeforeDraw() override { const SkRect bounds = SkRect::MakeXYWH(100, 100, 100, 100); SkPictureRecorder recorder; draw_something(recorder.beginRecording(bounds), bounds); fPicture = recorder.finishRecordingAsPicture(); // extract enough just for the oval. const SkISize size = SkISize::Make(100, 100); auto srgbColorSpace = SkColorSpace::MakeSRGB(); SkMatrix matrix; matrix.setTranslate(-100, -100); fImage0 = SkImage::MakeFromPicture(fPicture, size, &matrix, nullptr, SkImage::BitDepth::kU8, srgbColorSpace); matrix.postTranslate(-50, -50); matrix.postRotate(45); matrix.postTranslate(50, 50); fImage1 = SkImage::MakeFromPicture(fPicture, size, &matrix, nullptr, SkImage::BitDepth::kU8, srgbColorSpace); }
static SkMatrix pts_to_unit_matrix(const SkPoint pts[2]) { SkVector vec = pts[1] - pts[0]; SkScalar mag = vec.length(); SkScalar inv = mag ? SkScalarInvert(mag) : 0; vec.scale(inv); SkMatrix matrix; matrix.setSinCos(-vec.fY, vec.fX, pts[0].fX, pts[0].fY); matrix.postTranslate(-pts[0].fX, -pts[0].fY); matrix.postScale(inv, inv); return matrix; }
/** * Draw a single rect element of the clip stack into the accumulation bitmap */ void GrSWMaskHelper::drawRect(const SkRect& rect, const SkMatrix& matrix, SkRegion::Op op, GrAA aa, uint8_t alpha) { SkPaint paint; paint.setBlendMode(op_to_mode(op)); paint.setAntiAlias(GrAA::kYes == aa); paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha)); SkMatrix translatedMatrix = matrix; translatedMatrix.postTranslate(fTranslate.fX, fTranslate.fY); fDraw.fMatrix = &translatedMatrix; fDraw.drawRect(rect, paint); }
static CGAffineTransform matrix_to_transform(CGContextRef cg, const SkMatrix& ctm) { SkMatrix matrix; matrix.setScale(1, -1); matrix.postTranslate(0, SkIntToScalar(CGBitmapContextGetHeight(cg))); matrix.preConcat(ctm); return CGAffineTransformMake(matrix[SkMatrix::kMScaleX], matrix[SkMatrix::kMSkewY], matrix[SkMatrix::kMSkewX], matrix[SkMatrix::kMScaleY], matrix[SkMatrix::kMTransX], matrix[SkMatrix::kMTransY]); }