本文整理汇总了C++中SkMatrix::preTranslate方法的典型用法代码示例。如果您正苦于以下问题:C++ SkMatrix::preTranslate方法的具体用法?C++ SkMatrix::preTranslate怎么用?C++ SkMatrix::preTranslate使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SkMatrix
的用法示例。
在下文中一共展示了SkMatrix::preTranslate方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: drawSprite
void SkSVGDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
int x, int y, const SkPaint& paint) {
SkMatrix adjustedMatrix = *draw.fMatrix;
adjustedMatrix.preTranslate(SkIntToScalar(x), SkIntToScalar(y));
SkDraw adjustedDraw(draw);
adjustedDraw.fMatrix = &adjustedMatrix;
drawBitmapCommon(adjustedDraw, bitmap, paint);
}
示例2: onRasterize
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;
}
示例3: onRasterize
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;
}
示例4: make_bmp
static SkBitmap make_bmp(int w, int h) {
SkBitmap bmp;
bmp.allocN32Pixels(w, h, true);
SkCanvas canvas(bmp);
SkScalar wScalar = SkIntToScalar(w);
SkScalar hScalar = SkIntToScalar(h);
SkPoint pt = { wScalar / 2, hScalar / 2 };
SkScalar radius = 3 * SkMaxScalar(wScalar, hScalar);
SkColor colors[] = { SK_ColorDKGRAY, 0xFF222255,
0xFF331133, 0xFF884422,
0xFF000022, SK_ColorWHITE,
0xFFAABBCC};
SkScalar pos[] = {0,
SK_Scalar1 / 6,
2 * SK_Scalar1 / 6,
3 * SK_Scalar1 / 6,
4 * SK_Scalar1 / 6,
5 * SK_Scalar1 / 6,
SK_Scalar1};
SkPaint paint;
SkRect rect = SkRect::MakeWH(wScalar, hScalar);
SkMatrix mat = SkMatrix::I();
for (int i = 0; i < 4; ++i) {
paint.setShader(SkGradientShader::CreateRadial(
pt, radius,
colors, pos,
SK_ARRAY_COUNT(colors),
SkShader::kRepeat_TileMode,
0, &mat))->unref();
canvas.drawRect(rect, paint);
rect.inset(wScalar / 8, hScalar / 8);
mat.preTranslate(6 * wScalar, 6 * hScalar);
mat.postScale(SK_Scalar1 / 3, SK_Scalar1 / 3);
}
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
paint.setTextSize(wScalar / 2.2f);
paint.setShader(0);
paint.setColor(SK_ColorLTGRAY);
static const char kTxt[] = "Skia";
SkPoint texPos = { wScalar / 17, hScalar / 2 + paint.getTextSize() / 2.5f };
canvas.drawText(kTxt, SK_ARRAY_COUNT(kTxt)-1, texPos.fX, texPos.fY, paint);
paint.setColor(SK_ColorBLACK);
paint.setStyle(SkPaint::kStroke_Style);
paint.setStrokeWidth(SK_Scalar1);
canvas.drawText(kTxt, SK_ARRAY_COUNT(kTxt)-1, texPos.fX, texPos.fY, paint);
return bmp;
}
示例5: DrawLayersToAtlas
void GrLayerHoister::DrawLayersToAtlas(GrContext* context,
const SkTDArray<GrHoistedLayer>& atlased) {
if (atlased.count() > 0) {
// All the atlased layers are rendered into the same GrTexture
SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
atlased[0].fLayer->texture()->asRenderTarget(), NULL));
SkCanvas* atlasCanvas = surface->getCanvas();
SkPaint clearPaint;
clearPaint.setColor(SK_ColorTRANSPARENT);
clearPaint.setXfermode(SkXfermode::Create(SkXfermode::kSrc_Mode))->unref();
for (int i = 0; i < atlased.count(); ++i) {
const GrCachedLayer* layer = atlased[i].fLayer;
const SkPicture* pict = atlased[i].fPicture;
const SkIPoint offset = atlased[i].fOffset;
SkDEBUGCODE(const SkPaint* layerPaint = layer->paint();)
SkASSERT(!layerPaint || !layerPaint->getImageFilter());
atlasCanvas->save();
// Add a rect clip to make sure the rendering doesn't
// extend beyond the boundaries of the atlased sub-rect
SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft),
SkIntToScalar(layer->rect().fTop),
SkIntToScalar(layer->rect().width()),
SkIntToScalar(layer->rect().height()));
atlasCanvas->clipRect(bound);
// Since 'clear' doesn't respect the clip we need to draw a rect
atlasCanvas->drawRect(bound, clearPaint);
// '-offset' maps the layer's top/left to the origin.
// Since this layer is atlased, the top/left corner needs
// to be offset to the correct location in the backing texture.
SkMatrix initialCTM;
initialCTM.setTranslate(SkIntToScalar(-offset.fX), SkIntToScalar(-offset.fY));
initialCTM.preTranslate(bound.fLeft, bound.fTop);
initialCTM.preConcat(atlased[i].fPreMat);
atlasCanvas->setMatrix(initialCTM);
atlasCanvas->concat(atlased[i].fLocalMat);
SkRecordPartialDraw(*pict->fRecord.get(), atlasCanvas, bound,
layer->start() + 1, layer->stop(), initialCTM);
atlasCanvas->restore();
}
atlasCanvas->flush();
}
示例6: DrawLayersToAtlas
void GrLayerHoister::DrawLayersToAtlas(GrContext* context,
const SkTDArray<GrHoistedLayer>& atlased) {
if (atlased.count() > 0) {
// All the atlased layers are rendered into the same GrTexture
SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
atlased[0].fLayer->texture()->asRenderTarget(), &props));
SkCanvas* atlasCanvas = surface->getCanvas();
for (int i = 0; i < atlased.count(); ++i) {
const GrCachedLayer* layer = atlased[i].fLayer;
const SkBigPicture* pict = atlased[i].fPicture->asSkBigPicture();
if (!pict) {
// TODO: can we assume / assert this?
continue;
}
const SkIPoint offset = SkIPoint::Make(layer->srcIR().fLeft, layer->srcIR().fTop);
SkDEBUGCODE(const SkPaint* layerPaint = layer->paint();)
SkASSERT(!layerPaint || !layerPaint->getImageFilter());
SkASSERT(!layer->filter());
atlasCanvas->save();
// Add a rect clip to make sure the rendering doesn't
// extend beyond the boundaries of the atlased sub-rect
const SkRect bound = SkRect::Make(layer->rect());
atlasCanvas->clipRect(bound);
atlasCanvas->clear(0);
// '-offset' maps the layer's top/left to the origin.
// Since this layer is atlased, the top/left corner needs
// to be offset to the correct location in the backing texture.
SkMatrix initialCTM;
initialCTM.setTranslate(SkIntToScalar(-offset.fX), SkIntToScalar(-offset.fY));
initialCTM.preTranslate(bound.fLeft, bound.fTop);
initialCTM.preConcat(atlased[i].fPreMat);
atlasCanvas->setMatrix(initialCTM);
atlasCanvas->concat(atlased[i].fLocalMat);
pict->partialPlayback(atlasCanvas, layer->start() + 1, layer->stop(), initialCTM);
atlasCanvas->restore();
}
atlasCanvas->flush();
}
示例7: Create
////////////////////////////////////////////////////////////////////////////////
// set up the draw state to enable the aa clipping mask. Besides setting up the
// stage matrix this also alters the vertex layout
static const GrFragmentProcessor* create_fp_for_mask(GrTexture* result, const SkIRect &devBound) {
SkMatrix mat;
// We use device coords to compute the texture coordinates. We set our matrix to be a
// translation to the devBound, and then a scaling matrix to normalized coords.
mat.setIDiv(result->width(), result->height());
mat.preTranslate(SkIntToScalar(-devBound.fLeft),
SkIntToScalar(-devBound.fTop));
SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height());
return GrTextureDomainEffect::Create(result,
mat,
GrTextureDomain::MakeTexelDomain(result, domainTexels),
GrTextureDomain::kDecal_Mode,
GrTextureParams::kNone_FilterMode,
kDevice_GrCoordSet);
}
示例8: draw
void draw(SkCanvas* canvas) {
SkPaint paint;
SkPictureRecorder recorder;
SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
paint.setColor(color);
recordingCanvas->drawRect({10, 10, 30, 40}, paint);
recordingCanvas->translate(10, 10);
recordingCanvas->scale(1.2f, 1.4f);
}
sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
const SkPicture* playbackPtr = playback.get();
SkMatrix matrix;
matrix.reset();
for (auto alpha : { 70, 140, 210 } ) {
paint.setAlpha(alpha);
canvas->drawPicture(playbackPtr, &matrix, &paint);
matrix.preTranslate(70, 70);
}
}
示例9: morphpoints
static void morphpoints(SkPoint dst[], const SkPoint src[], int count,
SkPathMeasure& meas, SkScalar dist) {
for (int i = 0; i < count; i++) {
SkPoint pos;
SkVector tangent;
SkScalar sx = src[i].fX;
SkScalar sy = src[i].fY;
meas.getPosTan(dist + sx, &pos, &tangent);
SkMatrix matrix;
SkPoint pt;
pt.set(sx, sy);
matrix.setSinCos(tangent.fY, tangent.fX, 0, 0);
matrix.preTranslate(-sx, 0);
matrix.postTranslate(pos.fX, pos.fY);
matrix.mapPoints(&dst[i], &pt, 1);
}
}
示例10: compute_bounds
static bool compute_bounds(const SkDeque& layers, const SkPath& path,
const SkMatrix& matrix,
const SkIRect* clipBounds, SkIRect* bounds) {
SkDeque::F2BIter iter(layers);
SkLayerRasterizer_Rec* rec;
bounds->set(SK_MaxS32, SK_MaxS32, SK_MinS32, SK_MinS32);
while ((rec = (SkLayerRasterizer_Rec*)iter.next()) != NULL) {
const SkPaint& paint = rec->fPaint;
SkPath fillPath, devPath;
const SkPath* p = &path;
if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) {
paint.getFillPath(path, &fillPath);
p = &fillPath;
}
if (p->isEmpty()) {
continue;
}
// apply the matrix and offset
{
SkMatrix m = matrix;
m.preTranslate(rec->fOffset.fX, rec->fOffset.fY);
p->transform(m, &devPath);
}
SkMask mask;
if (!SkDraw::DrawToMask(devPath, clipBounds, paint.getMaskFilter(),
&matrix, &mask,
SkMask::kJustComputeBounds_CreateMode,
SkPaint::kFill_Style)) {
return false;
}
bounds->join(mask.fBounds);
}
return true;
}
示例11: DrawToTargetWithPathMask
void GrSWMaskHelper::DrawToTargetWithPathMask(GrTexture* texture,
GrDrawContext* drawContext,
const GrPaint* paint,
const GrUserStencilSettings* userStencilSettings,
const GrClip& clip,
GrColor color,
const SkMatrix& viewMatrix,
const SkIRect& rect) {
SkMatrix invert;
if (!viewMatrix.invert(&invert)) {
return;
}
SkRect dstRect = SkRect::MakeLTRB(SK_Scalar1 * rect.fLeft,
SK_Scalar1 * rect.fTop,
SK_Scalar1 * rect.fRight,
SK_Scalar1 * rect.fBottom);
// We use device coords to compute the texture coordinates. We take the device coords and apply
// a translation so that the top-left of the device bounds maps to 0,0, and then a scaling
// matrix to normalized coords.
SkMatrix maskMatrix;
maskMatrix.setIDiv(texture->width(), texture->height());
maskMatrix.preTranslate(SkIntToScalar(-rect.fLeft), SkIntToScalar(-rect.fTop));
GrPipelineBuilder pipelineBuilder(*paint, drawContext->isUnifiedMultisampled());
pipelineBuilder.setRenderTarget(drawContext->accessRenderTarget());
pipelineBuilder.setUserStencil(userStencilSettings);
pipelineBuilder.addCoverageFragmentProcessor(
GrSimpleTextureEffect::Create(texture,
maskMatrix,
GrTextureParams::kNone_FilterMode,
kDevice_GrCoordSet))->unref();
SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, SkMatrix::I(),
dstRect, nullptr, &invert));
drawContext->drawBatch(pipelineBuilder, clip, batch);
}
示例12: drawTextBlob
void SkBaseDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkScalar x, SkScalar y,
const SkPaint &paint) {
SkMatrix localMatrix;
SkDraw localDraw(draw);
if (x || y) {
localMatrix = *draw.fMatrix;
localMatrix.preTranslate(x, y);
localDraw.fMatrix = &localMatrix;
}
SkPaint runPaint = paint;
SkTextBlob::RunIterator it(blob);
while (!it.done()) {
size_t textLen = it.glyphCount() * sizeof(uint16_t);
const SkPoint& offset = it.offset();
// applyFontToPaint() always overwrites the exact same attributes,
// so it is safe to not re-seed the paint.
it.applyFontToPaint(&runPaint);
switch (it.positioning()) {
case SkTextBlob::kDefault_Positioning:
this->drawText(localDraw, it.glyphs(), textLen, offset.x(), offset.y(), runPaint);
break;
case SkTextBlob::kHorizontal_Positioning:
case SkTextBlob::kFull_Positioning:
this->drawPosText(localDraw, it.glyphs(), textLen, it.pos(), offset.y(),
SkTextBlob::ScalarsPerGlyph(it.positioning()), runPaint);
break;
default:
SkFAIL("unhandled positioning mode");
}
it.next();
}
}
示例13: pattern
SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state) : fState(state) {
fState.get()->fImage.lockPixels();
SkMatrix finalMatrix = fState.get()->fCanvasTransform;
finalMatrix.preConcat(fState.get()->fShaderTransform);
SkRect surfaceBBox;
surfaceBBox.set(fState.get()->fBBox);
transformBBox(finalMatrix, &surfaceBBox);
SkMatrix unflip;
unflip.setTranslate(0, SkScalarRound(surfaceBBox.height()));
unflip.preScale(SK_Scalar1, -SK_Scalar1);
SkISize size = SkISize::Make(SkScalarRound(surfaceBBox.width()),
SkScalarRound(surfaceBBox.height()));
SkPDFDevice pattern(size, size, unflip);
SkCanvas canvas(&pattern);
canvas.translate(-surfaceBBox.fLeft, -surfaceBBox.fTop);
finalMatrix.preTranslate(surfaceBBox.fLeft, surfaceBBox.fTop);
const SkBitmap* image = &fState.get()->fImage;
int width = image->width();
int height = image->height();
SkShader::TileMode tileModes[2];
tileModes[0] = fState.get()->fImageTileModes[0];
tileModes[1] = fState.get()->fImageTileModes[1];
canvas.drawBitmap(*image, 0, 0);
SkRect patternBBox = SkRect::MakeXYWH(-surfaceBBox.fLeft, -surfaceBBox.fTop,
width, height);
// Tiling is implied. First we handle mirroring.
if (tileModes[0] == SkShader::kMirror_TileMode) {
SkMatrix xMirror;
xMirror.setScale(-1, 1);
xMirror.postTranslate(2 * width, 0);
canvas.drawBitmapMatrix(*image, xMirror);
patternBBox.fRight += width;
}
if (tileModes[1] == SkShader::kMirror_TileMode) {
SkMatrix yMirror;
yMirror.setScale(SK_Scalar1, -SK_Scalar1);
yMirror.postTranslate(0, 2 * height);
canvas.drawBitmapMatrix(*image, yMirror);
patternBBox.fBottom += height;
}
if (tileModes[0] == SkShader::kMirror_TileMode &&
tileModes[1] == SkShader::kMirror_TileMode) {
SkMatrix mirror;
mirror.setScale(-1, -1);
mirror.postTranslate(2 * width, 2 * height);
canvas.drawBitmapMatrix(*image, mirror);
}
// Then handle Clamping, which requires expanding the pattern canvas to
// cover the entire surfaceBBox.
// If both x and y are in clamp mode, we start by filling in the corners.
// (Which are just a rectangles of the corner colors.)
if (tileModes[0] == SkShader::kClamp_TileMode &&
tileModes[1] == SkShader::kClamp_TileMode) {
SkPaint paint;
SkRect rect;
rect = SkRect::MakeLTRB(surfaceBBox.fLeft, surfaceBBox.fTop, 0, 0);
if (!rect.isEmpty()) {
paint.setColor(image->getColor(0, 0));
canvas.drawRect(rect, paint);
}
rect = SkRect::MakeLTRB(width, surfaceBBox.fTop, surfaceBBox.fRight, 0);
if (!rect.isEmpty()) {
paint.setColor(image->getColor(width - 1, 0));
canvas.drawRect(rect, paint);
}
rect = SkRect::MakeLTRB(width, height, surfaceBBox.fRight,
surfaceBBox.fBottom);
if (!rect.isEmpty()) {
paint.setColor(image->getColor(width - 1, height - 1));
canvas.drawRect(rect, paint);
}
rect = SkRect::MakeLTRB(surfaceBBox.fLeft, height, 0,
surfaceBBox.fBottom);
if (!rect.isEmpty()) {
paint.setColor(image->getColor(0, height - 1));
canvas.drawRect(rect, paint);
}
}
// Then expand the left, right, top, then bottom.
if (tileModes[0] == SkShader::kClamp_TileMode) {
SkIRect subset = SkIRect::MakeXYWH(0, 0, 1, height);
if (surfaceBBox.fLeft < 0) {
SkBitmap left;
SkAssertResult(image->extractSubset(&left, subset));
SkMatrix leftMatrix;
leftMatrix.setScale(-surfaceBBox.fLeft, 1);
leftMatrix.postTranslate(surfaceBBox.fLeft, 0);
canvas.drawBitmapMatrix(left, leftMatrix);
//.........这里部分代码省略.........
示例14: MakeFromGpu
sk_sp<SkSpecialImage> SkDisplacementMapEffect::onFilterImage(SkSpecialImage* source,
const Context& ctx,
SkIPoint* offset) const {
SkIPoint colorOffset = SkIPoint::Make(0, 0);
sk_sp<SkSpecialImage> color(this->filterInput(1, source, ctx, &colorOffset));
if (!color) {
return nullptr;
}
SkIPoint displOffset = SkIPoint::Make(0, 0);
sk_sp<SkSpecialImage> displ(this->filterInput(0, source, ctx, &displOffset));
if (!displ) {
return nullptr;
}
const SkIRect srcBounds = SkIRect::MakeXYWH(colorOffset.x(), colorOffset.y(),
color->width(), color->height());
// Both paths do bounds checking on color pixel access, we don't need to
// pad the color bitmap to bounds here.
SkIRect bounds;
if (!this->applyCropRect(ctx, srcBounds, &bounds)) {
return nullptr;
}
SkIRect displBounds;
displ = this->applyCropRect(ctx, displ.get(), &displOffset, &displBounds);
if (!displ) {
return nullptr;
}
if (!bounds.intersect(displBounds)) {
return nullptr;
}
const SkIRect colorBounds = bounds.makeOffset(-colorOffset.x(), -colorOffset.y());
SkVector scale = SkVector::Make(fScale, fScale);
ctx.ctm().mapVectors(&scale, 1);
#if SK_SUPPORT_GPU
if (source->isTextureBacked()) {
GrContext* context = source->getContext();
sk_sp<GrTexture> colorTexture(color->asTextureRef(context));
sk_sp<GrTexture> displTexture(displ->asTextureRef(context));
if (!colorTexture || !displTexture) {
return nullptr;
}
GrSurfaceDesc desc;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fWidth = bounds.width();
desc.fHeight = bounds.height();
desc.fConfig = kSkia8888_GrPixelConfig;
SkAutoTUnref<GrTexture> dst(context->textureProvider()->createApproxTexture(desc));
if (!dst) {
return nullptr;
}
GrPaint paint;
SkMatrix offsetMatrix = GrCoordTransform::MakeDivByTextureWHMatrix(displTexture.get());
offsetMatrix.preTranslate(SkIntToScalar(colorOffset.fX - displOffset.fX),
SkIntToScalar(colorOffset.fY - displOffset.fY));
paint.addColorFragmentProcessor(
GrDisplacementMapEffect::Create(fXChannelSelector,
fYChannelSelector,
scale,
displTexture.get(),
offsetMatrix,
colorTexture.get(),
SkISize::Make(color->width(),
color->height())))->unref();
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
SkMatrix matrix;
matrix.setTranslate(-SkIntToScalar(colorBounds.x()), -SkIntToScalar(colorBounds.y()));
SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(dst->asRenderTarget()));
if (!drawContext) {
return nullptr;
}
drawContext->drawRect(GrClip::WideOpen(), paint, matrix, SkRect::Make(colorBounds));
offset->fX = bounds.left();
offset->fY = bounds.top();
return SkSpecialImage::MakeFromGpu(SkIRect::MakeWH(bounds.width(), bounds.height()),
kNeedNewImageUniqueID_SpecialImage,
dst);
}
#endif
SkBitmap colorBM, displBM;
if (!color->getROPixels(&colorBM) || !displ->getROPixels(&displBM)) {
return nullptr;
}
//.........这里部分代码省略.........
示例15: filterImageGPU
bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy,
const SkBitmap& src,
const Context& ctx,
SkBitmap* result,
SkIPoint* offset) const {
SkBitmap background = src;
SkIPoint backgroundOffset = SkIPoint::Make(0, 0);
if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &background,
&backgroundOffset)) {
return onFilterImage(proxy, src, ctx, result, offset);
}
GrTexture* backgroundTex = background.getTexture();
SkBitmap foreground = src;
SkIPoint foregroundOffset = SkIPoint::Make(0, 0);
if (getInput(1) && !getInput(1)->getInputResultGPU(proxy, src, ctx, &foreground,
&foregroundOffset)) {
return onFilterImage(proxy, src, ctx, result, offset);
}
GrTexture* foregroundTex = foreground.getTexture();
GrContext* context = foregroundTex->getContext();
GrEffect* xferEffect = NULL;
GrTextureDesc desc;
desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
desc.fWidth = src.width();
desc.fHeight = src.height();
desc.fConfig = kSkia8888_GrPixelConfig;
GrAutoScratchTexture ast(context, desc);
if (NULL == ast.texture()) {
return false;
}
SkAutoTUnref<GrTexture> dst(ast.detach());
GrContext::AutoRenderTarget art(context, dst->asRenderTarget());
if (!fMode || !fMode->asNewEffect(&xferEffect, backgroundTex)) {
// canFilterImageGPU() should've taken care of this
SkASSERT(false);
return false;
}
SkMatrix foregroundMatrix = GrCoordTransform::MakeDivByTextureWHMatrix(foregroundTex);
foregroundMatrix.preTranslate(SkIntToScalar(backgroundOffset.fX-foregroundOffset.fX),
SkIntToScalar(backgroundOffset.fY-foregroundOffset.fY));
SkRect srcRect;
src.getBounds(&srcRect);
GrPaint paint;
paint.addColorTextureEffect(foregroundTex, foregroundMatrix);
paint.addColorEffect(xferEffect)->unref();
context->drawRect(paint, srcRect);
offset->fX = backgroundOffset.fX;
offset->fY = backgroundOffset.fY;
WrapTexture(dst, src.width(), src.height(), result);
return true;
}