本文整理汇总了C++中SkVector::x方法的典型用法代码示例。如果您正苦于以下问题:C++ SkVector::x方法的具体用法?C++ SkVector::x怎么用?C++ SkVector::x使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SkVector
的用法示例。
在下文中一共展示了SkVector::x方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: onFilterBounds
bool SkBlurImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
SkIRect* dst) const {
SkIRect bounds = src;
if (getInput(0) && !getInput(0)->filterBounds(src, ctm, &bounds)) {
return false;
}
SkVector sigma = SkVector::Make(fSigma.width(), fSigma.height());
ctm.mapVectors(&sigma, 1);
bounds.outset(SkScalarCeilToInt(SkScalarMul(sigma.x(), SkIntToScalar(3))),
SkScalarCeilToInt(SkScalarMul(sigma.y(), SkIntToScalar(3))));
*dst = bounds;
return true;
}
示例2: MakeImage
static sk_sp<SkImage> MakeImage(const SkVector& vec, SkColor color) {
const SkPoint start = SkPoint::Make(vec.y() * kSegLen / 2, vec.x() * kSegLen / 2);
const SkPoint end = SkPoint::Make(start.x() + vec.x() * (kSegLen - 1),
start.y() + vec.y() * (kSegLen - 1));
SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterN32Premul(kSegLen, kSegLen));
surface->getCanvas()->clear(SK_ColorTRANSPARENT);
SkPaint paint;
paint.setAntiAlias(true);
const SkRect border = SkRect::MakeIWH(kSegLen, kSegLen).makeInset(.5f, .5f);
paint.setColor(SK_ColorBLUE);
paint.setStyle(SkPaint::kStroke_Style);
surface->getCanvas()->drawRect(border, paint);
paint.setColor(SK_ColorBLACK);
surface->getCanvas()->drawLine(start.x(), start.y(), end.x(), end.y(), paint);
surface->getCanvas()->drawPoint(start.x(), start.y(), color);
surface->getCanvas()->drawPoint(end.x(), end.y(), color);
return surface->makeImageSnapshot();
}
示例3: onFilterBounds
bool SkMorphologyImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
SkIRect* dst) const {
SkIRect bounds = src;
SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()),
SkIntToScalar(this->radius().height()));
ctm.mapVectors(&radius, 1);
bounds.outset(SkScalarCeilToInt(radius.x()), SkScalarCeilToInt(radius.y()));
if (getInput(0) && !getInput(0)->filterBounds(bounds, ctm, &bounds)) {
return false;
}
*dst = bounds;
return true;
}
示例4: onFilterImage
SkSpecialImage* SkOffsetImageFilter::onFilterImage(SkSpecialImage* source,
const Context& ctx,
SkIPoint* offset) const {
SkIPoint srcOffset = SkIPoint::Make(0, 0);
SkAutoTUnref<SkSpecialImage> input(this->filterInput(0, source, ctx, &srcOffset));
if (!input) {
return nullptr;
}
SkVector vec;
ctx.ctm().mapVectors(&vec, &fOffset, 1);
if (!this->cropRectIsSet()) {
offset->fX = srcOffset.fX + SkScalarRoundToInt(vec.fX);
offset->fY = srcOffset.fY + SkScalarRoundToInt(vec.fY);
return input.release();
} else {
SkIRect bounds;
SkIRect srcBounds = SkIRect::MakeWH(input->width(), input->height());
srcBounds.offset(srcOffset);
if (!this->applyCropRect(ctx, srcBounds, &bounds)) {
return nullptr;
}
SkImageInfo info = SkImageInfo::MakeN32(bounds.width(), bounds.height(),
kPremul_SkAlphaType);
sk_sp<SkSpecialSurface> surf(source->makeSurface(info));
if (!surf) {
return nullptr;
}
SkCanvas* canvas = surf->getCanvas();
SkASSERT(canvas);
// TODO: it seems like this clear shouldn't be necessary (see skbug.com/5075)
canvas->clear(0x0);
SkPaint paint;
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
canvas->translate(SkIntToScalar(srcOffset.fX - bounds.fLeft),
SkIntToScalar(srcOffset.fY - bounds.fTop));
input->draw(canvas, vec.x(), vec.y(), &paint);
offset->fX = bounds.fLeft;
offset->fY = bounds.fTop;
return surf->makeImageSnapshot().release();
}
}
示例5: onFilterImage
bool SkOffsetImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source,
const Context& ctx,
SkBitmap* result,
SkIPoint* offset) const {
SkBitmap src = source;
SkIPoint srcOffset = SkIPoint::Make(0, 0);
if (!cropRectIsSet()) {
if (!this->filterInput(0, proxy, source, ctx, &src, &srcOffset)) {
return false;
}
SkVector vec;
ctx.ctm().mapVectors(&vec, &fOffset, 1);
offset->fX = srcOffset.fX + SkScalarRoundToInt(vec.fX);
offset->fY = srcOffset.fY + SkScalarRoundToInt(vec.fY);
*result = src;
} else {
if (!this->filterInput(0, proxy, source, ctx, &src, &srcOffset)) {
return false;
}
SkIRect bounds;
if (!this->applyCropRect(ctx, src, srcOffset, &bounds)) {
return false;
}
SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
if (nullptr == device.get()) {
return false;
}
SkCanvas canvas(device);
SkPaint paint;
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
canvas.translate(SkIntToScalar(srcOffset.fX - bounds.fLeft),
SkIntToScalar(srcOffset.fY - bounds.fTop));
SkVector vec;
ctx.ctm().mapVectors(&vec, &fOffset, 1);
canvas.drawBitmap(src, vec.x(), vec.y(), &paint);
*result = device->accessBitmap(false);
offset->fX = bounds.fLeft;
offset->fY = bounds.fTop;
}
return true;
}
示例6: filterImageGPU
bool SkBlurImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx,
SkBitmap* result, SkIPoint* offset) const {
#if SK_SUPPORT_GPU
SkBitmap input = src;
SkIPoint srcOffset = SkIPoint::Make(0, 0);
if (!this->filterInputGPU(0, proxy, src, ctx, &input, &srcOffset)) {
return false;
}
SkIRect srcBounds, dstBounds;
if (!this->applyCropRect(this->mapContext(ctx), input, srcOffset, &dstBounds, &srcBounds)) {
return false;
}
if (!srcBounds.intersect(dstBounds)) {
return false;
}
GrTexture* source = input.getTexture();
SkVector sigma = mapSigma(fSigma, ctx.ctm());
offset->fX = dstBounds.fLeft;
offset->fY = dstBounds.fTop;
srcBounds.offset(-srcOffset);
dstBounds.offset(-srcOffset);
SkRect srcBoundsF(SkRect::Make(srcBounds));
auto constraint = GrTextureProvider::FromImageFilter(ctx.sizeConstraint());
SkAutoTUnref<GrTexture> tex(SkGpuBlurUtils::GaussianBlur(source->getContext(),
source,
false,
SkRect::Make(dstBounds),
&srcBoundsF,
sigma.x(),
sigma.y(),
constraint));
if (!tex) {
return false;
}
WrapTexture(tex, dstBounds.width(), dstBounds.height(), result);
return true;
#else
SkDEBUGFAIL("Should not call in GPU-less build");
return false;
#endif
}
示例7: onFilterImage
bool SkOffsetImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source,
const Context& ctx,
SkBitmap* result,
SkIPoint* offset) const {
SkImageFilter* input = getInput(0);
SkBitmap src = source;
SkIPoint srcOffset = SkIPoint::Make(0, 0);
#ifdef SK_DISABLE_OFFSETIMAGEFILTER_OPTIMIZATION
if (false) {
#else
if (!cropRectIsSet()) {
#endif
if (input && !input->filterImage(proxy, source, ctx, &src, &srcOffset)) {
return false;
}
SkVector vec;
ctx.ctm().mapVectors(&vec, &fOffset, 1);
offset->fX = srcOffset.fX + SkScalarRoundToInt(vec.fX);
offset->fY = srcOffset.fY + SkScalarRoundToInt(vec.fY);
*result = src;
} else {
if (input && !input->filterImage(proxy, source, ctx, &src, &srcOffset)) {
return false;
}
SkIRect bounds;
if (!this->applyCropRect(ctx, src, srcOffset, &bounds)) {
return false;
}
SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
if (NULL == device.get()) {
return false;
}
SkCanvas canvas(device);
SkPaint paint;
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
canvas.translate(SkIntToScalar(srcOffset.fX - bounds.fLeft),
SkIntToScalar(srcOffset.fY - bounds.fTop));
SkVector vec;
ctx.ctm().mapVectors(&vec, &fOffset, 1);
canvas.drawBitmap(src, vec.x(), vec.y(), &paint);
*result = device->accessBitmap(false);
offset->fX = bounds.fLeft;
offset->fY = bounds.fTop;
}
return true;
}
void SkOffsetImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const {
if (getInput(0)) {
getInput(0)->computeFastBounds(src, dst);
} else {
*dst = src;
}
SkRect copy = *dst;
dst->offset(fOffset.fX, fOffset.fY);
dst->join(copy);
}
bool SkOffsetImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
SkIRect* dst) const {
SkVector vec;
ctm.mapVectors(&vec, &fOffset, 1);
SkIRect bounds = src;
bounds.offset(-SkScalarCeilToInt(vec.fX), -SkScalarCeilToInt(vec.fY));
bounds.join(src);
if (getInput(0)) {
return getInput(0)->filterBounds(bounds, ctm, dst);
}
*dst = bounds;
return true;
}
示例8: onFilterImage
bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
const SkBitmap& source, const Context& ctx,
SkBitmap* dst, SkIPoint* offset) const {
SkBitmap src = source;
SkIPoint srcOffset = SkIPoint::Make(0, 0);
if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcOffset)) {
return false;
}
if (src.colorType() != kN32_SkColorType) {
return false;
}
SkIRect srcBounds, dstBounds;
if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &srcBounds, &src)) {
return false;
}
SkAutoLockPixels alp(src);
if (!src.getPixels()) {
return false;
}
if (!dst->allocPixels(src.info().makeWH(srcBounds.width(), srcBounds.height()))) {
return false;
}
dst->getBounds(&dstBounds);
SkVector sigma = SkVector::Make(fSigma.width(), fSigma.height());
ctx.ctm().mapVectors(&sigma, 1);
sigma.fX = SkMinScalar(sigma.fX, MAX_SIGMA);
sigma.fY = SkMinScalar(sigma.fY, MAX_SIGMA);
int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX;
int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY;
getBox3Params(sigma.x(), &kernelSizeX, &kernelSizeX3, &lowOffsetX, &highOffsetX);
getBox3Params(sigma.y(), &kernelSizeY, &kernelSizeY3, &lowOffsetY, &highOffsetY);
if (kernelSizeX < 0 || kernelSizeY < 0) {
return false;
}
if (kernelSizeX == 0 && kernelSizeY == 0) {
src.copyTo(dst, dst->colorType());
offset->fX = srcBounds.fLeft;
offset->fY = srcBounds.fTop;
return true;
}
SkBitmap temp;
if (!temp.allocPixels(dst->info())) {
return false;
}
offset->fX = srcBounds.fLeft;
offset->fY = srcBounds.fTop;
srcBounds.offset(-srcOffset);
const SkPMColor* s = src.getAddr32(srcBounds.left(), srcBounds.top());
SkPMColor* t = temp.getAddr32(0, 0);
SkPMColor* d = dst->getAddr32(0, 0);
int w = dstBounds.width(), h = dstBounds.height();
int sw = src.rowBytesAsPixels();
SkBoxBlurProc boxBlurX, boxBlurY, boxBlurXY, boxBlurYX;
if (!SkBoxBlurGetPlatformProcs(&boxBlurX, &boxBlurY, &boxBlurXY, &boxBlurYX)) {
boxBlurX = boxBlur<kX, kX>;
boxBlurY = boxBlur<kY, kY>;
boxBlurXY = boxBlur<kX, kY>;
boxBlurYX = boxBlur<kY, kX>;
}
if (kernelSizeX > 0 && kernelSizeY > 0) {
boxBlurX(s, sw, t, kernelSizeX, lowOffsetX, highOffsetX, w, h);
boxBlurX(t, w, d, kernelSizeX, highOffsetX, lowOffsetX, w, h);
boxBlurXY(d, w, t, kernelSizeX3, highOffsetX, highOffsetX, w, h);
boxBlurX(t, h, d, kernelSizeY, lowOffsetY, highOffsetY, h, w);
boxBlurX(d, h, t, kernelSizeY, highOffsetY, lowOffsetY, h, w);
boxBlurXY(t, h, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
} else if (kernelSizeX > 0) {
boxBlurX(s, sw, d, kernelSizeX, lowOffsetX, highOffsetX, w, h);
boxBlurX(d, w, t, kernelSizeX, highOffsetX, lowOffsetX, w, h);
boxBlurX(t, w, d, kernelSizeX3, highOffsetX, highOffsetX, w, h);
} else if (kernelSizeY > 0) {
boxBlurYX(s, sw, d, kernelSizeY, lowOffsetY, highOffsetY, h, w);
boxBlurX(d, h, t, kernelSizeY, highOffsetY, lowOffsetY, h, w);
boxBlurXY(t, h, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
}
return true;
}
示例9: inputBoundsF
sk_sp<SkSpecialImage> SkBlurImageFilter::onFilterImage(SkSpecialImage* source,
const Context& ctx,
SkIPoint* offset) const {
SkIPoint inputOffset = SkIPoint::Make(0, 0);
sk_sp<SkSpecialImage> input(this->filterInput(0, source, ctx, &inputOffset));
if (!input) {
return nullptr;
}
SkIRect inputBounds = SkIRect::MakeXYWH(inputOffset.fX, inputOffset.fY,
input->width(), input->height());
SkIRect dstBounds;
if (!this->applyCropRect(this->mapContext(ctx), inputBounds, &dstBounds)) {
return nullptr;
}
if (!inputBounds.intersect(dstBounds)) {
return nullptr;
}
const SkVector sigma = map_sigma(fSigma, ctx.ctm());
#if SK_SUPPORT_GPU
if (input->peekTexture() && input->peekTexture()->getContext()) {
if (0 == sigma.x() && 0 == sigma.y()) {
offset->fX = inputBounds.x();
offset->fY = inputBounds.y();
return input->makeSubset(inputBounds.makeOffset(-inputOffset.x(),
-inputOffset.y()));
}
GrTexture* inputTexture = input->peekTexture();
offset->fX = dstBounds.fLeft;
offset->fY = dstBounds.fTop;
inputBounds.offset(-inputOffset);
dstBounds.offset(-inputOffset);
SkRect inputBoundsF(SkRect::Make(inputBounds));
SkAutoTUnref<GrTexture> tex(SkGpuBlurUtils::GaussianBlur(inputTexture->getContext(),
inputTexture,
false,
source->props().allowSRGBInputs(),
SkRect::Make(dstBounds),
&inputBoundsF,
sigma.x(),
sigma.y()));
if (!tex) {
return nullptr;
}
return SkSpecialImage::MakeFromGpu(source->internal_getProxy(),
SkIRect::MakeWH(dstBounds.width(), dstBounds.height()),
kNeedNewImageUniqueID_SpecialImage,
tex, &source->props());
}
#endif
int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX;
int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY;
get_box3_params(sigma.x(), &kernelSizeX, &kernelSizeX3, &lowOffsetX, &highOffsetX);
get_box3_params(sigma.y(), &kernelSizeY, &kernelSizeY3, &lowOffsetY, &highOffsetY);
if (kernelSizeX < 0 || kernelSizeY < 0) {
return nullptr;
}
if (kernelSizeX == 0 && kernelSizeY == 0) {
offset->fX = inputBounds.x();
offset->fY = inputBounds.y();
return input->makeSubset(inputBounds.makeOffset(-inputOffset.x(),
-inputOffset.y()));
}
SkPixmap inputPixmap;
if (!input->peekPixels(&inputPixmap)) {
return nullptr;
}
if (inputPixmap.colorType() != kN32_SkColorType) {
return nullptr;
}
SkImageInfo info = SkImageInfo::Make(dstBounds.width(), dstBounds.height(),
inputPixmap.colorType(), inputPixmap.alphaType());
SkBitmap tmp, dst;
if (!tmp.tryAllocPixels(info) || !dst.tryAllocPixels(info)) {
return nullptr;
}
SkAutoLockPixels tmpLock(tmp), dstLock(dst);
offset->fX = dstBounds.fLeft;
offset->fY = dstBounds.fTop;
SkPMColor* t = tmp.getAddr32(0, 0);
SkPMColor* d = dst.getAddr32(0, 0);
int w = dstBounds.width(), h = dstBounds.height();
const SkPMColor* s = inputPixmap.addr32(inputBounds.x() - inputOffset.x(),
//.........这里部分代码省略.........
示例10: onFilterNodeBounds
SkIRect SkBlurImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
MapDirection) const {
SkVector sigma = map_sigma(fSigma, ctm);
return src.makeOutset(SkScalarCeilToInt(SkScalarMul(sigma.x(), SkIntToScalar(3))),
SkScalarCeilToInt(SkScalarMul(sigma.y(), SkIntToScalar(3))));
}
示例11: onFilterImage
bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
const SkBitmap& source, const Context& ctx,
SkBitmap* dst, SkIPoint* offset) const {
SkBitmap src = source;
SkIPoint srcOffset = SkIPoint::Make(0, 0);
if (!this->filterInput(0, proxy, source, ctx, &src, &srcOffset)) {
return false;
}
if (src.colorType() != kN32_SkColorType) {
return false;
}
SkIRect srcBounds, dstBounds;
if (!this->applyCropRect(this->mapContext(ctx), src, srcOffset, &dstBounds, &srcBounds)) {
return false;
}
if (!srcBounds.intersect(dstBounds)) {
return false;
}
SkAutoLockPixels alp(src);
if (!src.getPixels()) {
return false;
}
SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(dstBounds.width(), dstBounds.height()));
if (!device) {
return false;
}
*dst = device->accessBitmap(false);
SkAutoLockPixels alp_dst(*dst);
SkVector sigma = mapSigma(fSigma, ctx.ctm());
int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX;
int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY;
getBox3Params(sigma.x(), &kernelSizeX, &kernelSizeX3, &lowOffsetX, &highOffsetX);
getBox3Params(sigma.y(), &kernelSizeY, &kernelSizeY3, &lowOffsetY, &highOffsetY);
if (kernelSizeX < 0 || kernelSizeY < 0) {
return false;
}
if (kernelSizeX == 0 && kernelSizeY == 0) {
src.copyTo(dst, dst->colorType());
offset->fX = dstBounds.x() + srcOffset.x();
offset->fY = dstBounds.y() + srcOffset.y();
return true;
}
SkAutoTUnref<SkBaseDevice> tempDevice(proxy->createDevice(dst->width(), dst->height()));
if (!tempDevice) {
return false;
}
SkBitmap temp = tempDevice->accessBitmap(false);
SkAutoLockPixels alpTemp(temp);
offset->fX = dstBounds.fLeft;
offset->fY = dstBounds.fTop;
SkPMColor* t = temp.getAddr32(0, 0);
SkPMColor* d = dst->getAddr32(0, 0);
int w = dstBounds.width(), h = dstBounds.height();
const SkPMColor* s = src.getAddr32(srcBounds.x() - srcOffset.x(), srcBounds.y() - srcOffset.y());
srcBounds.offset(-dstBounds.x(), -dstBounds.y());
dstBounds.offset(-dstBounds.x(), -dstBounds.y());
SkIRect srcBoundsT = SkIRect::MakeLTRB(srcBounds.top(), srcBounds.left(), srcBounds.bottom(), srcBounds.right());
SkIRect dstBoundsT = SkIRect::MakeWH(dstBounds.height(), dstBounds.width());
int sw = src.rowBytesAsPixels();
/**
*
* In order to make memory accesses cache-friendly, we reorder the passes to
* use contiguous memory reads wherever possible.
*
* For example, the 6 passes of the X-and-Y blur case are rewritten as
* follows. Instead of 3 passes in X and 3 passes in Y, we perform
* 2 passes in X, 1 pass in X transposed to Y on write, 2 passes in X,
* then 1 pass in X transposed to Y on write.
*
* +----+ +----+ +----+ +---+ +---+ +---+ +----+
* + AB + ----> | AB | ----> | AB | -----> | A | ----> | A | ----> | A | -----> | AB |
* +----+ blurX +----+ blurX +----+ blurXY | B | blurX | B | blurX | B | blurXY +----+
* +---+ +---+ +---+
*
* In this way, two of the y-blurs become x-blurs applied to transposed
* images, and all memory reads are contiguous.
*/
if (kernelSizeX > 0 && kernelSizeY > 0) {
SkOpts::box_blur_xx(s, sw, srcBounds, t, kernelSizeX, lowOffsetX, highOffsetX, w, h);
SkOpts::box_blur_xx(t, w, dstBounds, d, kernelSizeX, highOffsetX, lowOffsetX, w, h);
SkOpts::box_blur_xy(d, w, dstBounds, t, kernelSizeX3, highOffsetX, highOffsetX, w, h);
SkOpts::box_blur_xx(t, h, dstBoundsT, d, kernelSizeY, lowOffsetY, highOffsetY, h, w);
SkOpts::box_blur_xx(d, h, dstBoundsT, t, kernelSizeY, highOffsetY, lowOffsetY, h, w);
SkOpts::box_blur_xy(t, h, dstBoundsT, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
} else if (kernelSizeX > 0) {
SkOpts::box_blur_xx(s, sw, srcBounds, d, kernelSizeX, lowOffsetX, highOffsetX, w, h);
SkOpts::box_blur_xx(d, w, dstBounds, t, kernelSizeX, highOffsetX, lowOffsetX, w, h);
SkOpts::box_blur_xx(t, w, dstBounds, d, kernelSizeX3, highOffsetX, highOffsetX, w, h);
} else if (kernelSizeY > 0) {
//.........这里部分代码省略.........
示例12: flush
void GrTextBlob::flush(GrTextTarget* target, const SkSurfaceProps& props,
const GrDistanceFieldAdjustTable* distanceAdjustTable,
const SkPaint& paint, GrColor filteredColor, const GrClip& clip,
const SkMatrix& viewMatrix, SkScalar x, SkScalar y) {
// GrTextBlob::makeOp only takes uint16_t values for run and subRun indices.
// Encountering something larger than this is highly unlikely, so we'll just not draw it.
int lastRun = SkTMin(fRunCount, (1 << 16)) - 1;
// For each run in the GrTextBlob we're going to churn through all the glyphs.
// Each run is broken into a path part and a Mask / DFT / ARGB part.
for (int runIndex = 0; runIndex <= lastRun; runIndex++) {
Run& run = fRuns[runIndex];
// first flush any path glyphs
if (run.fPathGlyphs.count()) {
SkPaint runPaint{paint};
runPaint.setFlags((runPaint.getFlags() & ~Run::kPaintFlagsMask) | run.fPaintFlags);
for (int i = 0; i < run.fPathGlyphs.count(); i++) {
GrTextBlob::Run::PathGlyph& pathGlyph = run.fPathGlyphs[i];
SkMatrix ctm;
const SkPath* path = &pathGlyph.fPath;
// TmpPath must be in the same scope as GrShape shape below.
SkTLazy<SkPath> tmpPath;
// The glyph positions and glyph outlines are either in device space or in source
// space based on fPreTransformed.
if (!pathGlyph.fPreTransformed) {
// Positions and outlines are in source space.
ctm = viewMatrix;
SkMatrix pathMatrix = SkMatrix::MakeScale(pathGlyph.fScale, pathGlyph.fScale);
// The origin for the blob may have changed, so figure out the delta.
SkVector originShift = SkPoint{x, y} - SkPoint{fInitialX, fInitialY};
// Shift the original glyph location in source space to the position of the new
// blob.
pathMatrix.postTranslate(originShift.x() + pathGlyph.fX,
originShift.y() + pathGlyph.fY);
// If there are shaders, blurs or styles, the path must be scaled into source
// space independently of the CTM. This allows the CTM to be correct for the
// different effects.
GrStyle style(runPaint);
bool scalePath = runPaint.getShader()
|| style.applies()
|| runPaint.getMaskFilter();
if (!scalePath) {
// Scale can be applied to CTM -- no effects.
ctm.preConcat(pathMatrix);
} else {
// Scale the outline into source space.
// Transform the path form the normalized outline to source space. This
// way the CTM will remain the same so it can be used by the effects.
SkPath* sourceOutline = tmpPath.init();
path->transform(pathMatrix, sourceOutline);
sourceOutline->setIsVolatile(true);
path = sourceOutline;
}
} else {
// Positions and outlines are in device space.
SkPoint originalOrigin = {fInitialX, fInitialY};
fInitialViewMatrix.mapPoints(&originalOrigin, 1);
SkPoint newOrigin = {x, y};
viewMatrix.mapPoints(&newOrigin, 1);
// The origin shift in device space.
SkPoint originShift = newOrigin - originalOrigin;
// Shift the original glyph location in device space to the position of the
// new blob.
ctm = SkMatrix::MakeTrans(originShift.x() + pathGlyph.fX,
originShift.y() + pathGlyph.fY);
}
// TODO: we are losing the mutability of the path here
GrShape shape(*path, paint);
target->drawShape(clip, runPaint, ctm, shape);
}
}
// then flush each subrun, if any
if (!run.fInitialized) {
continue;
}
int lastSubRun = SkTMin(run.fSubRunInfo.count(), 1 << 16) - 1;
for (int subRun = 0; subRun <= lastSubRun; subRun++) {
//.........这里部分代码省略.........