本文整理汇总了C++中SkRect类的典型用法代码示例。如果您正苦于以下问题:C++ SkRect类的具体用法?C++ SkRect怎么用?C++ SkRect使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了SkRect类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: intersects
bool intersects(SkRect tRect, float tRot, TextDrawInfo* s)
{
float sRot = s->pathRotate;
if (abs(tRot) < M_PI / 15 && abs(sRot) < M_PI / 15) {
return SkRect::Intersects(tRect, s->bounds);
}
float dist = sqrt(sqr(tRect.centerX() - s->bounds.centerX()) + sqr(tRect.centerY() - s->bounds.centerY()));
if(dist < 3) {
return true;
}
SkRect sRect = s->bounds;
// difference close to 90/270 degrees
if(abs(cos(tRot-sRot)) < 0.3 ){
// rotate one rectangle to 90 degrees
tRot += M_PI_2;
tRect = SkRect::MakeXYWH(tRect.centerX() - tRect.height() / 2, tRect.centerY() - tRect.width() / 2,
tRect.height(), tRect.width());
}
// determine difference close to 180/0 degrees
if(abs(sin(tRot-sRot)) < 0.3){
// rotate t box
// (calculate offset for t center suppose we rotate around s center)
float diff = atan2(tRect.centerY() - sRect.centerY(), tRect.centerX() - sRect.centerX());
diff -= sRot;
float left = sRect.centerX() + dist* cos(diff) - tRect.width()/2;
float top = sRect.centerY() - dist* sin(diff) - tRect.height()/2;
SkRect nRect = SkRect::MakeXYWH(left, top, tRect.width(), tRect.height());
return SkRect::Intersects(nRect, sRect);
}
// TODO other cases not covered
return SkRect::Intersects(tRect, sRect);
}
示例2: GaussianBlur
GrTexture* GaussianBlur(GrContext* context,
GrTexture* srcTexture,
bool canClobberSrc,
const SkRect& rect,
bool cropToRect,
float sigmaX,
float sigmaY) {
SkASSERT(context);
SkIRect clearRect;
int scaleFactorX, radiusX;
int scaleFactorY, radiusY;
int maxTextureSize = context->getMaxTextureSize();
sigmaX = adjust_sigma(sigmaX, maxTextureSize, &scaleFactorX, &radiusX);
sigmaY = adjust_sigma(sigmaY, maxTextureSize, &scaleFactorY, &radiusY);
SkRect srcRect(rect);
scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY);
srcRect.roundOut(&srcRect);
scale_rect(&srcRect, static_cast<float>(scaleFactorX),
static_cast<float>(scaleFactorY));
// setup new clip
GrClip clip(SkRect::MakeWH(srcRect.width(), srcRect.height()));
SkASSERT(kBGRA_8888_GrPixelConfig == srcTexture->config() ||
kRGBA_8888_GrPixelConfig == srcTexture->config() ||
kAlpha_8_GrPixelConfig == srcTexture->config());
GrSurfaceDesc desc;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fWidth = SkScalarFloorToInt(srcRect.width());
desc.fHeight = SkScalarFloorToInt(srcRect.height());
desc.fConfig = srcTexture->config();
GrTexture* dstTexture;
GrTexture* tempTexture;
SkAutoTUnref<GrTexture> temp1, temp2;
temp1.reset(context->textureProvider()->refScratchTexture(
desc, GrTextureProvider::kApprox_ScratchTexMatch));
dstTexture = temp1.get();
if (canClobberSrc) {
tempTexture = srcTexture;
} else {
temp2.reset(context->textureProvider()->refScratchTexture(
desc, GrTextureProvider::kApprox_ScratchTexMatch));
tempTexture = temp2.get();
}
if (NULL == dstTexture || NULL == tempTexture) {
return NULL;
}
GrDrawContext* drawContext = context->drawContext();
if (!drawContext) {
return NULL;
}
for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) {
GrPaint paint;
SkMatrix matrix;
matrix.setIDiv(srcTexture->width(), srcTexture->height());
SkRect dstRect(srcRect);
if (cropToRect && i == 1) {
dstRect.offset(-dstRect.fLeft, -dstRect.fTop);
SkRect domain;
matrix.mapRect(&domain, rect);
domain.inset(i < scaleFactorX ? SK_ScalarHalf / srcTexture->width() : 0.0f,
i < scaleFactorY ? SK_ScalarHalf / srcTexture->height() : 0.0f);
SkAutoTUnref<GrFragmentProcessor> fp( GrTextureDomainEffect::Create(
srcTexture,
matrix,
domain,
GrTextureDomain::kDecal_Mode,
GrTextureParams::kBilerp_FilterMode));
paint.addColorProcessor(fp);
} else {
GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode);
paint.addColorTextureProcessor(srcTexture, matrix, params);
}
scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f,
i < scaleFactorY ? 0.5f : 1.0f);
drawContext->drawNonAARectToRect(dstTexture->asRenderTarget(), clip, paint, SkMatrix::I(),
dstRect, srcRect);
srcRect = dstRect;
srcTexture = dstTexture;
SkTSwap(dstTexture, tempTexture);
}
const SkIRect srcIRect = srcRect.roundOut();
// For really small blurs(Certainly no wider than 5x5 on desktop gpus) it is faster to just
// launch a single non separable kernel vs two launches
if (sigmaX > 0.0f && sigmaY > 0 &&
(2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) {
// We shouldn't be scaling because this is a small size blur
SkASSERT((scaleFactorX == scaleFactorY) == 1);
SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
convolve_gaussian_2d(drawContext, dstTexture->asRenderTarget(), clip, srcRect, dstRect,
//.........这里部分代码省略.........
示例3: onOnceBeforeDraw
void onOnceBeforeDraw() override {
fPaint.setAntiAlias(true);
fPaint.setLCDRenderText(fLCD);
SkISize size = this->getISize();
SkScalar w = SkIntToScalar(size.fWidth);
SkScalar h = SkIntToScalar(size.fHeight);
SK_COMPILE_ASSERT(4 == SK_ARRAY_COUNT(fTypefacesToUnref), typeface_cnt);
fTypefacesToUnref[0] = sk_tool_utils::create_portable_typeface("sans-serif", SkTypeface::kNormal);
fTypefacesToUnref[1] = sk_tool_utils::create_portable_typeface("sans-serif", SkTypeface::kBold);
fTypefacesToUnref[2] = sk_tool_utils::create_portable_typeface("serif", SkTypeface::kNormal);
fTypefacesToUnref[3] = sk_tool_utils::create_portable_typeface("serif", SkTypeface::kBold);
SkRandom random;
for (int i = 0; i < kCnt; ++i) {
int length = random.nextRangeU(kMinLength, kMaxLength);
char text[kMaxLength];
for (int j = 0; j < length; ++j) {
text[j] = (char)random.nextRangeU('!', 'z');
}
fStrings[i].set(text, length);
fColors[i] = random.nextU();
fColors[i] |= 0xFF000000;
fColors[i] = sk_tool_utils::color_to_565(fColors[i]);
static const SkScalar kMinPtSize = 8.f;
static const SkScalar kMaxPtSize = 32.f;
fPtSizes[i] = random.nextRangeScalar(kMinPtSize, kMaxPtSize);
fTypefaces[i] = fTypefacesToUnref[
random.nextULessThan(SK_ARRAY_COUNT(fTypefacesToUnref))];
SkRect r;
fPaint.setColor(fColors[i]);
fPaint.setTypeface(fTypefaces[i]);
fPaint.setTextSize(fPtSizes[i]);
fPaint.measureText(fStrings[i].c_str(), fStrings[i].size(), &r);
// safeRect is set of x,y positions where we can draw the string without hitting
// the GM's border.
SkRect safeRect = SkRect::MakeLTRB(-r.fLeft, -r.fTop, w - r.fRight, h - r.fBottom);
if (safeRect.isEmpty()) {
// If we don't fit then just don't worry about how we get cliped to the device
// border.
safeRect = SkRect::MakeWH(w, h);
}
fPositions[i].fX = random.nextRangeScalar(safeRect.fLeft, safeRect.fRight);
fPositions[i].fY = random.nextRangeScalar(safeRect.fTop, safeRect.fBottom);
fClipRects[i] = r;
fClipRects[i].offset(fPositions[i].fX, fPositions[i].fY);
fClipRects[i].outset(2.f, 2.f);
if (fEffectiveClip) {
fClipRects[i].fRight -= 0.25f * fClipRects[i].width();
}
}
}
示例4: onDraw
virtual void onDraw(SkCanvas* canvas) {
struct FillAndName {
SkPath::FillType fFill;
const char* fName;
};
static const FillAndName gFills[] = {
{SkPath::kWinding_FillType, "Winding"},
{SkPath::kEvenOdd_FillType, "Even / Odd"},
{SkPath::kInverseWinding_FillType, "Inverse Winding"},
{SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
};
struct StyleAndName {
SkPaint::Style fStyle;
const char* fName;
};
static const StyleAndName gStyles[] = {
{SkPaint::kFill_Style, "Fill"},
{SkPaint::kStroke_Style, "Stroke"},
{SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
};
struct CapAndName {
SkPaint::Cap fCap;
SkPaint::Join fJoin;
const char* fName;
};
static const CapAndName gCaps[] = {
{SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"},
{SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"},
{SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"}
};
struct PathAndName {
SkPath fPath;
const char* fName;
};
PathAndName path;
path.fPath.moveTo(25*SK_Scalar1, 15*SK_Scalar1);
path.fPath.lineTo(75*SK_Scalar1, 15*SK_Scalar1);
path.fName = "moveTo-line";
SkPaint titlePaint;
titlePaint.setColor(SK_ColorBLACK);
titlePaint.setAntiAlias(true);
titlePaint.setLCDRenderText(true);
titlePaint.setTextSize(15 * SK_Scalar1);
const char title[] = "Line Drawn Into Rectangle Clips With "
"Indicated Style, Fill and Linecaps, with stroke width 10";
canvas->drawText(title, strlen(title),
20 * SK_Scalar1,
20 * SK_Scalar1,
titlePaint);
SkLCGRandom rand;
SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
canvas->save();
canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
canvas->save();
for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
if (0 < cap) {
canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0);
}
canvas->save();
for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
if (0 < fill) {
canvas->translate(0, rect.height() + 40 * SK_Scalar1);
}
canvas->save();
for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
if (0 < style) {
canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
}
SkColor color = 0xff007000;
this->drawPath(path.fPath, canvas, color, rect,
gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle,
gFills[fill].fFill, SK_Scalar1*10);
SkPaint rectPaint;
rectPaint.setColor(SK_ColorBLACK);
rectPaint.setStyle(SkPaint::kStroke_Style);
rectPaint.setStrokeWidth(-1);
rectPaint.setAntiAlias(true);
canvas->drawRect(rect, rectPaint);
SkPaint labelPaint;
labelPaint.setColor(color);
labelPaint.setAntiAlias(true);
labelPaint.setLCDRenderText(true);
labelPaint.setTextSize(10 * SK_Scalar1);
canvas->drawText(gStyles[style].fName,
strlen(gStyles[style].fName),
0, rect.height() + 12 * SK_Scalar1,
labelPaint);
canvas->drawText(gFills[fill].fName,
strlen(gFills[fill].fName),
0, rect.height() + 24 * SK_Scalar1,
labelPaint);
canvas->drawText(gCaps[cap].fName,
strlen(gCaps[cap].fName),
0, rect.height() + 36 * SK_Scalar1,
labelPaint);
//.........这里部分代码省略.........
示例5: onSetData
void GLCircularRRectEffect::onSetData(const GrGLProgramDataManager& pdman,
const GrProcessor& processor) {
const CircularRRectEffect& crre = processor.cast<CircularRRectEffect>();
const SkRRect& rrect = crre.getRRect();
if (rrect != fPrevRRect) {
SkRect rect = rrect.getBounds();
SkScalar radius = 0;
switch (crre.getCircularCornerFlags()) {
case CircularRRectEffect::kAll_CornerFlags:
SkASSERT(rrect.isSimpleCircular());
radius = rrect.getSimpleRadii().fX;
SkASSERT(radius >= kRadiusMin);
rect.inset(radius, radius);
break;
case CircularRRectEffect::kTopLeft_CornerFlag:
radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX;
rect.fLeft += radius;
rect.fTop += radius;
rect.fRight += 0.5f;
rect.fBottom += 0.5f;
break;
case CircularRRectEffect::kTopRight_CornerFlag:
radius = rrect.radii(SkRRect::kUpperRight_Corner).fX;
rect.fLeft -= 0.5f;
rect.fTop += radius;
rect.fRight -= radius;
rect.fBottom += 0.5f;
break;
case CircularRRectEffect::kBottomRight_CornerFlag:
radius = rrect.radii(SkRRect::kLowerRight_Corner).fX;
rect.fLeft -= 0.5f;
rect.fTop -= 0.5f;
rect.fRight -= radius;
rect.fBottom -= radius;
break;
case CircularRRectEffect::kBottomLeft_CornerFlag:
radius = rrect.radii(SkRRect::kLowerLeft_Corner).fX;
rect.fLeft += radius;
rect.fTop -= 0.5f;
rect.fRight += 0.5f;
rect.fBottom -= radius;
break;
case CircularRRectEffect::kLeft_CornerFlags:
radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX;
rect.fLeft += radius;
rect.fTop += radius;
rect.fRight += 0.5f;
rect.fBottom -= radius;
break;
case CircularRRectEffect::kTop_CornerFlags:
radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX;
rect.fLeft += radius;
rect.fTop += radius;
rect.fRight -= radius;
rect.fBottom += 0.5f;
break;
case CircularRRectEffect::kRight_CornerFlags:
radius = rrect.radii(SkRRect::kUpperRight_Corner).fX;
rect.fLeft -= 0.5f;
rect.fTop += radius;
rect.fRight -= radius;
rect.fBottom -= radius;
break;
case CircularRRectEffect::kBottom_CornerFlags:
radius = rrect.radii(SkRRect::kLowerLeft_Corner).fX;
rect.fLeft += radius;
rect.fTop -= 0.5f;
rect.fRight -= radius;
rect.fBottom -= radius;
break;
default:
SkFAIL("Should have been one of the above cases.");
}
pdman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
pdman.set1f(fRadiusPlusHalfUniform, radius + 0.5f);
fPrevRRect = rrect;
}
}
示例6: onDrawContent
virtual void onDrawContent(SkCanvas* canvas) {
struct FillAndName {
SkPath::FillType fFill;
const char* fName;
};
static const FillAndName gFills[] = {
{SkPath::kWinding_FillType, "Winding"},
{SkPath::kEvenOdd_FillType, "Even / Odd"},
{SkPath::kInverseWinding_FillType, "Inverse Winding"},
{SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
};
struct StyleAndName {
SkPaint::Style fStyle;
const char* fName;
};
static const StyleAndName gStyles[] = {
{SkPaint::kFill_Style, "Fill"},
{SkPaint::kStroke_Style, "Stroke"},
{SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
};
SkPaint titlePaint;
titlePaint.setColor(SK_ColorBLACK);
titlePaint.setAntiAlias(true);
titlePaint.setLCDRenderText(true);
titlePaint.setTextSize(24 * SK_Scalar1);
const char title[] = "Empty Paths Drawn Into Rectangle Clips With Indicated Style and Fill";
canvas->drawText(title, strlen(title),
40 * SK_Scalar1,
100*SK_Scalar1,
titlePaint);
SkRandom rand;
SkRect rect = SkRect::MakeWH(125*SK_Scalar1, 100*SK_Scalar1);
int i = 0;
canvas->save();
canvas->translate(80 * SK_Scalar1, 0);
canvas->save();
for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
if (0 == i % 4) {
canvas->restore();
canvas->translate(0, rect.height() + 50 * SK_Scalar1);
canvas->save();
} else {
canvas->translate(rect.width() + 100 * SK_Scalar1, 0);
}
++i;
SkColor color = rand.nextU();
color = 0xff000000| color; // force solid
this->drawEmpty(canvas, color, rect,
gStyles[style].fStyle, gFills[fill].fFill);
SkPaint rectPaint;
rectPaint.setColor(SK_ColorBLACK);
rectPaint.setStyle(SkPaint::kStroke_Style);
rectPaint.setStrokeWidth(-1);
rectPaint.setAntiAlias(true);
canvas->drawRect(rect, rectPaint);
char label[1024];
sprintf(label, "%s, %s", gStyles[style].fName,
gFills[fill].fName);
SkPaint labelPaint;
labelPaint.setColor(color);
labelPaint.setAntiAlias(true);
labelPaint.setLCDRenderText(true);
canvas->drawText(label, strlen(label),
0, rect.height() + 15 * SK_Scalar1,
labelPaint);
}
}
canvas->restore();
canvas->restore();
}
示例7: SkASSERT
bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) {
SkASSERT(!args.fStroke->isHairlineStyle());
const SkPath& path = *args.fPath;
GrPipelineBuilder* pipelineBuilder = args.fPipelineBuilder;
const SkMatrix& viewMatrix = *args.fViewMatrix;
SkASSERT(pipelineBuilder->getStencil().isDisabled());
if (args.fAntiAlias) {
SkASSERT(pipelineBuilder->getRenderTarget()->isStencilBufferMultisampled());
pipelineBuilder->enableState(GrPipelineBuilder::kHWAntialias_Flag);
}
SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, *args.fStroke));
if (path.isInverseFillType()) {
GR_STATIC_CONST_SAME_STENCIL(kInvertedStencilPass,
kKeep_StencilOp,
kZero_StencilOp,
// We know our rect will hit pixels outside the clip and the user bits will be 0
// outside the clip. So we can't just fill where the user bits are 0. We also need to
// check that the clip bit is set.
kEqualIfInClip_StencilFunc,
0xffff,
0x0000,
0xffff);
pipelineBuilder->setStencil(kInvertedStencilPass);
// fake inverse with a stencil and cover
args.fTarget->stencilPath(*pipelineBuilder, viewMatrix, p, p->getFillType());
SkMatrix invert = SkMatrix::I();
SkRect bounds =
SkRect::MakeLTRB(0, 0, SkIntToScalar(pipelineBuilder->getRenderTarget()->width()),
SkIntToScalar(pipelineBuilder->getRenderTarget()->height()));
SkMatrix vmi;
// mapRect through persp matrix may not be correct
if (!viewMatrix.hasPerspective() && viewMatrix.invert(&vmi)) {
vmi.mapRect(&bounds);
// theoretically could set bloat = 0, instead leave it because of matrix inversion
// precision.
SkScalar bloat = viewMatrix.getMaxScale() * SK_ScalarHalf;
bounds.outset(bloat, bloat);
} else {
if (!viewMatrix.invert(&invert)) {
return false;
}
}
const SkMatrix& viewM = viewMatrix.hasPerspective() ? SkMatrix::I() : viewMatrix;
if (pipelineBuilder->getRenderTarget()->hasMixedSamples()) {
pipelineBuilder->disableState(GrPipelineBuilder::kHWAntialias_Flag);
}
args.fTarget->drawNonAARect(*pipelineBuilder, args.fColor, viewM, bounds, invert);
} else {
GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
kZero_StencilOp,
kKeep_StencilOp,
kNotEqual_StencilFunc,
0xffff,
0x0000,
0xffff);
pipelineBuilder->setStencil(kStencilPass);
SkAutoTUnref<GrDrawPathBatchBase> batch(
GrDrawPathBatch::Create(viewMatrix, args.fColor, p->getFillType(), p));
args.fTarget->drawPathBatch(*pipelineBuilder, batch);
}
pipelineBuilder->stencil()->setDisabled();
return true;
}
示例8: SkScalarMul
void GrAARectRenderer::StrokeAARect(GrDrawTarget* target,
GrPipelineBuilder* pipelineBuilder,
GrColor color,
const SkMatrix& viewMatrix,
const SkRect& rect,
const SkRect& devRect,
const SkStrokeRec& stroke) {
SkVector devStrokeSize;
SkScalar width = stroke.getWidth();
if (width > 0) {
devStrokeSize.set(width, width);
viewMatrix.mapVectors(&devStrokeSize, 1);
devStrokeSize.setAbs(devStrokeSize);
} else {
devStrokeSize.set(SK_Scalar1, SK_Scalar1);
}
const SkScalar dx = devStrokeSize.fX;
const SkScalar dy = devStrokeSize.fY;
const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf);
const SkScalar ry = SkScalarMul(dy, SK_ScalarHalf);
SkScalar spare;
{
SkScalar w = devRect.width() - dx;
SkScalar h = devRect.height() - dy;
spare = SkTMin(w, h);
}
SkRect devOutside(devRect);
devOutside.outset(rx, ry);
bool miterStroke = true;
// For hairlines, make bevel and round joins appear the same as mitered ones.
// small miter limit means right angles show bevel...
if ((width > 0) && (stroke.getJoin() != SkPaint::kMiter_Join ||
stroke.getMiter() < SK_ScalarSqrt2)) {
miterStroke = false;
}
if (spare <= 0 && miterStroke) {
FillAARect(target, pipelineBuilder, color, viewMatrix, devOutside, devOutside);
return;
}
SkRect devInside(devRect);
devInside.inset(rx, ry);
SkRect devOutsideAssist(devRect);
// For bevel-stroke, use 2 SkRect instances(devOutside and devOutsideAssist)
// to draw the outer of the rect. Because there are 8 vertices on the outer
// edge, while vertex number of inner edge is 4, the same as miter-stroke.
if (!miterStroke) {
devOutside.inset(0, ry);
devOutsideAssist.outset(0, ry);
}
GeometryStrokeAARect(target, pipelineBuilder, color, viewMatrix, devOutside,
devOutsideAssist, devInside, miterStroke);
}
示例9: handleBBox
void SkBBoxHierarchyRecord::handleBBox(const SkRect& bounds) {
SkIRect r;
bounds.roundOut(&r);
SkPictureStateTree::Draw* draw = fStateTree->appendDraw(this->writeStream().bytesWritten());
fBoundingHierarchy->insert(draw, r, true);
}
示例10: SkIntToScalar
void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
const SkRect* src, const SkRect& dst,
const SkPaint& paint,
SkCanvas::DrawBitmapRectFlags flags) {
SkMatrix matrix;
SkRect bitmapBounds, tmpSrc, tmpDst;
SkBitmap tmpBitmap;
bitmapBounds.isetWH(bitmap.width(), bitmap.height());
// Compute matrix from the two rectangles
if (src) {
tmpSrc = *src;
} else {
tmpSrc = bitmapBounds;
}
matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
const SkRect* dstPtr = &dst;
const SkBitmap* bitmapPtr = &bitmap;
// clip the tmpSrc to the bounds of the bitmap, and recompute dstRect if
// needed (if the src was clipped). No check needed if src==null.
if (src) {
if (!bitmapBounds.contains(*src)) {
if (!tmpSrc.intersect(bitmapBounds)) {
return; // nothing to draw
}
// recompute dst, based on the smaller tmpSrc
matrix.mapRect(&tmpDst, tmpSrc);
dstPtr = &tmpDst;
}
// since we may need to clamp to the borders of the src rect within
// the bitmap, we extract a subset.
SkIRect srcIR;
tmpSrc.roundOut(&srcIR);
if(bitmap.pixelRef()->getTexture()) {
// Accelerated source canvas, don't use extractSubset but readPixels to get the subset.
// This way, the pixels are copied in CPU memory instead of GPU memory.
bitmap.pixelRef()->readPixels(&tmpBitmap, &srcIR);
} else {
if (!bitmap.extractSubset(&tmpBitmap, srcIR)) {
return;
}
}
bitmapPtr = &tmpBitmap;
// Since we did an extract, we need to adjust the matrix accordingly
SkScalar dx = 0, dy = 0;
if (srcIR.fLeft > 0) {
dx = SkIntToScalar(srcIR.fLeft);
}
if (srcIR.fTop > 0) {
dy = SkIntToScalar(srcIR.fTop);
}
if (dx || dy) {
matrix.preTranslate(dx, dy);
}
SkRect extractedBitmapBounds;
extractedBitmapBounds.isetWH(bitmapPtr->width(), bitmapPtr->height());
if (extractedBitmapBounds == tmpSrc) {
// no fractional part in src, we can just call drawBitmap
goto USE_DRAWBITMAP;
}
} else {
USE_DRAWBITMAP:
// We can go faster by just calling drawBitmap, which will concat the
// matrix with the CTM, and try to call drawSprite if it can. If not,
// it will make a shader and call drawRect, as we do below.
this->drawBitmap(draw, *bitmapPtr, matrix, paint);
return;
}
// construct a shader, so we can call drawRect with the dst
SkShader* s = SkShader::CreateBitmapShader(*bitmapPtr,
SkShader::kClamp_TileMode,
SkShader::kClamp_TileMode,
&matrix);
if (NULL == s) {
return;
}
SkPaint paintWithShader(paint);
paintWithShader.setStyle(SkPaint::kFill_Style);
paintWithShader.setShader(s)->unref();
// Call ourself, in case the subclass wanted to share this setup code
// but handle the drawRect code themselves.
this->drawRect(draw, *dstPtr, paintWithShader);
}
示例11: generateAAFillRectGeometry
void generateAAFillRectGeometry(void* vertices,
size_t offset,
size_t vertexStride,
GrColor color,
const SkMatrix& viewMatrix,
const SkRect& rect,
const SkRect& devRect,
bool tweakAlphaForCoverage) const {
intptr_t verts = reinterpret_cast<intptr_t>(vertices) + offset;
SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts);
SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride);
SkScalar inset = SkMinScalar(devRect.width(), SK_Scalar1);
inset = SK_ScalarHalf * SkMinScalar(inset, devRect.height());
if (viewMatrix.rectStaysRect()) {
set_inset_fan(fan0Pos, vertexStride, devRect, -SK_ScalarHalf, -SK_ScalarHalf);
set_inset_fan(fan1Pos, vertexStride, devRect, inset, inset);
} else {
// compute transformed (1, 0) and (0, 1) vectors
SkVector vec[2] = {
{ viewMatrix[SkMatrix::kMScaleX], viewMatrix[SkMatrix::kMSkewY] },
{ viewMatrix[SkMatrix::kMSkewX], viewMatrix[SkMatrix::kMScaleY] }
};
vec[0].normalize();
vec[0].scale(SK_ScalarHalf);
vec[1].normalize();
vec[1].scale(SK_ScalarHalf);
// create the rotated rect
fan0Pos->setRectFan(rect.fLeft, rect.fTop,
rect.fRight, rect.fBottom, vertexStride);
viewMatrix.mapPointsWithStride(fan0Pos, vertexStride, 4);
// Now create the inset points and then outset the original
// rotated points
// TL
*((SkPoint*)((intptr_t)fan1Pos + 0 * vertexStride)) =
*((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) + vec[0] + vec[1];
*((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) -= vec[0] + vec[1];
// BL
*((SkPoint*)((intptr_t)fan1Pos + 1 * vertexStride)) =
*((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) + vec[0] - vec[1];
*((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) -= vec[0] - vec[1];
// BR
*((SkPoint*)((intptr_t)fan1Pos + 2 * vertexStride)) =
*((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) - vec[0] - vec[1];
*((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) += vec[0] + vec[1];
// TR
*((SkPoint*)((intptr_t)fan1Pos + 3 * vertexStride)) =
*((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) - vec[0] + vec[1];
*((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[1];
}
// Make verts point to vertex color and then set all the color and coverage vertex attrs
// values.
verts += sizeof(SkPoint);
for (int i = 0; i < 4; ++i) {
if (tweakAlphaForCoverage) {
*reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0;
} else {
*reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
*reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)) = 0;
}
}
int scale;
if (inset < SK_ScalarHalf) {
scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf));
SkASSERT(scale >= 0 && scale <= 255);
} else {
scale = 0xff;
}
verts += 4 * vertexStride;
float innerCoverage = GrNormalizeByteToFloat(scale);
GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale);
for (int i = 0; i < 4; ++i) {
if (tweakAlphaForCoverage) {
*reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor;
} else {
*reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
*reinterpret_cast<float*>(verts + i * vertexStride +
sizeof(GrColor)) = innerCoverage;
}
}
}
示例12: flush_translate
void SkDeferredCanvas::flush_translate(SkScalar* x, SkScalar* y, const SkPaint& paint) {
SkRect tmp = SkRect::MakeXYWH(*x, *y, 1, 1);
this->flush_check(&tmp, &paint, kNoClip_Flag | kNoCull_Flag | kNoScale_Flag);
*x = tmp.x();
*y = tmp.y();
}
示例13: GaussianBlur
GrTexture* GaussianBlur(GrContext* context,
GrTexture* srcTexture,
bool canClobberSrc,
const SkRect& rect,
bool cropToRect,
float sigmaX,
float sigmaY) {
SkASSERT(NULL != context);
GrContext::AutoRenderTarget art(context);
GrContext::AutoMatrix am;
am.setIdentity(context);
SkIRect clearRect;
int scaleFactorX, radiusX;
int scaleFactorY, radiusY;
sigmaX = adjust_sigma(sigmaX, &scaleFactorX, &radiusX);
sigmaY = adjust_sigma(sigmaY, &scaleFactorY, &radiusY);
SkRect srcRect(rect);
scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY);
srcRect.roundOut();
scale_rect(&srcRect, static_cast<float>(scaleFactorX),
static_cast<float>(scaleFactorY));
GrContext::AutoClip acs(context, SkRect::MakeWH(srcRect.width(), srcRect.height()));
SkASSERT(kBGRA_8888_GrPixelConfig == srcTexture->config() ||
kRGBA_8888_GrPixelConfig == srcTexture->config() ||
kAlpha_8_GrPixelConfig == srcTexture->config());
GrTextureDesc desc;
desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
desc.fWidth = SkScalarFloorToInt(srcRect.width());
desc.fHeight = SkScalarFloorToInt(srcRect.height());
desc.fConfig = srcTexture->config();
GrAutoScratchTexture temp1, temp2;
GrTexture* dstTexture = temp1.set(context, desc);
GrTexture* tempTexture = canClobberSrc ? srcTexture : temp2.set(context, desc);
if (NULL == dstTexture || NULL == tempTexture) {
return NULL;
}
for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) {
GrPaint paint;
SkMatrix matrix;
matrix.setIDiv(srcTexture->width(), srcTexture->height());
context->setRenderTarget(dstTexture->asRenderTarget());
SkRect dstRect(srcRect);
if (cropToRect && i == 1) {
dstRect.offset(-dstRect.fLeft, -dstRect.fTop);
SkRect domain;
matrix.mapRect(&domain, rect);
domain.inset(i < scaleFactorX ? SK_ScalarHalf / srcTexture->width() : 0.0f,
i < scaleFactorY ? SK_ScalarHalf / srcTexture->height() : 0.0f);
SkAutoTUnref<GrEffectRef> effect(GrTextureDomainEffect::Create(
srcTexture,
matrix,
domain,
GrTextureDomain::kDecal_Mode,
GrTextureParams::kBilerp_FilterMode));
paint.addColorEffect(effect);
} else {
GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode);
paint.addColorTextureEffect(srcTexture, matrix, params);
}
scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f,
i < scaleFactorY ? 0.5f : 1.0f);
context->drawRectToRect(paint, dstRect, srcRect);
srcRect = dstRect;
srcTexture = dstTexture;
SkTSwap(dstTexture, tempTexture);
}
SkIRect srcIRect;
srcRect.roundOut(&srcIRect);
if (sigmaX > 0.0f) {
if (scaleFactorX > 1) {
// Clear out a radius to the right of the srcRect to prevent the
// X convolution from reading garbage.
clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
radiusX, srcIRect.height());
context->clear(&clearRect, 0x0, false);
}
context->setRenderTarget(dstTexture->asRenderTarget());
SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
convolve_gaussian(context, srcRect, dstRect, srcTexture,
Gr1DKernelEffect::kX_Direction, radiusX, sigmaX, cropToRect);
srcTexture = dstTexture;
srcRect = dstRect;
SkTSwap(dstTexture, tempTexture);
}
if (sigmaY > 0.0f) {
if (scaleFactorY > 1 || sigmaX > 0.0f) {
// Clear out a radius below the srcRect to prevent the Y
// convolution from reading garbage.
//.........这里部分代码省略.........
示例14: drawTextOverCanvas
void drawTextOverCanvas(RenderingContext* rc, SkCanvas* cv) {
SkRect r = SkRect::MakeLTRB(0, 0, rc->width, rc->height);
r.inset(-100, -100);
quad_tree<TextDrawInfo*> boundsIntersect(r, 4, 0.6);
SkPaint paintIcon;
paintIcon.setStyle(SkPaint::kStroke_Style);
paintIcon.setStrokeWidth(1);
paintIcon.setColor(0xff000000);
SkPaint paintText;
paintText.setStyle(SkPaint::kFill_Style);
paintText.setStrokeWidth(1);
paintText.setColor(0xff000000);
paintText.setTextAlign(SkPaint::kCenter_Align);
paintText.setTypeface(serif);
paintText.setAntiAlias(true);
SkPaint::FontMetrics fm;
// 1. Sort text using text order
std::sort(rc->textToDraw.begin(), rc->textToDraw.end(), textOrder);
uint size = rc->textToDraw.size();
for (uint i = 0; i < size; i++) {
TextDrawInfo* text = rc->textToDraw.at(i);
if (text->text.length() > 0) {
size_t d = text->text.find(DELIM_CHAR);
// not used now functionality
// possibly it will be used specifying english names after that character
if (d > 0) {
text->text = text->text.substr(0, d);
}
// sest text size before finding intersection (it is used there)
float textSize = getDensityValue(rc, text->textSize);
paintText.setTextSize(textSize);
paintText.setFakeBoldText(text->bold);
paintText.setColor(text->textColor);
// align center y
paintText.getFontMetrics(&fm);
text->centerY += (-fm.fAscent);
// calculate if there is intersection
bool intersects = findTextIntersection(cv, rc, boundsIntersect, text, &paintText, &paintIcon);
if (!intersects) {
if(rc->interrupted()){
return;
}
if (text->drawOnPath && text->path != NULL) {
if (text->textShadow > 0) {
paintText.setColor(0xFFFFFFFF);
paintText.setStyle(SkPaint::kStroke_Style);
paintText.setStrokeWidth(2 + text->textShadow);
rc->nativeOperations.pause();
cv->drawTextOnPathHV(text->text.c_str(), text->text.length(), *text->path, text->hOffset,
text->vOffset, paintText);
rc->nativeOperations.start();
// reset
paintText.setStyle(SkPaint::kFill_Style);
paintText.setStrokeWidth(2);
paintText.setColor(text->textColor);
}
rc->nativeOperations.pause();
cv->drawTextOnPathHV(text->text.c_str(), text->text.length(), *text->path, text->hOffset,
text->vOffset, paintText);
rc->nativeOperations.start();
} else {
if (text->shieldRes.length() > 0) {
SkBitmap* ico = getCachedBitmap(rc, text->shieldRes);
if (ico != NULL) {
rc->nativeOperations.pause();
cv->drawBitmap(*ico, text->centerX - ico->width() / 2 - 0.5f,
text->centerY - ico->height() / 2 - getDensityValue(rc, 4.5f), &paintIcon);
rc->nativeOperations.start();
}
}
drawWrappedText(rc, cv, text, textSize, paintText);
}
}
}
}
}
示例15: inset
static SkRect inset(const SkRect& r) {
SkRect rect = r;
rect.inset(r.width() / 8, r.height() / 8);
return rect;
}