本文整理汇总了C++中SkRect::height方法的典型用法代码示例。如果您正苦于以下问题:C++ SkRect::height方法的具体用法?C++ SkRect::height怎么用?C++ SkRect::height使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SkRect
的用法示例。
在下文中一共展示了SkRect::height方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: 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;
}
}
}
示例2: IntersectLine
bool SkLineClipper::IntersectLine(const SkPoint src[2], const SkRect& clip,
SkPoint dst[2]) {
SkRect bounds;
bounds.set(src, 2);
if (containsNoEmptyCheck(clip, bounds)) {
if (src != dst) {
memcpy(dst, src, 2 * sizeof(SkPoint));
}
return true;
}
// check for no overlap, and only permit coincident edges if the line
// and the edge are colinear
if (nestedLT(bounds.fRight, clip.fLeft, bounds.width()) ||
nestedLT(clip.fRight, bounds.fLeft, bounds.width()) ||
nestedLT(bounds.fBottom, clip.fTop, bounds.height()) ||
nestedLT(clip.fBottom, bounds.fTop, bounds.height())) {
return false;
}
int index0, index1;
if (src[0].fY < src[1].fY) {
index0 = 0;
index1 = 1;
} else {
index0 = 1;
index1 = 0;
}
SkPoint tmp[2];
memcpy(tmp, src, sizeof(tmp));
// now compute Y intersections
if (tmp[index0].fY < clip.fTop) {
tmp[index0].set(sect_with_horizontal(src, clip.fTop), clip.fTop);
}
if (tmp[index1].fY > clip.fBottom) {
tmp[index1].set(sect_with_horizontal(src, clip.fBottom), clip.fBottom);
}
if (tmp[0].fX < tmp[1].fX) {
index0 = 0;
index1 = 1;
} else {
index0 = 1;
index1 = 0;
}
// check for quick-reject in X again, now that we may have been chopped
if ((tmp[index1].fX <= clip.fLeft || tmp[index0].fX >= clip.fRight) &&
tmp[index0].fX < tmp[index1].fX) {
// only reject if we have a non-zero width
return false;
}
if (tmp[index0].fX < clip.fLeft) {
tmp[index0].set(clip.fLeft, sect_with_vertical(src, clip.fLeft));
}
if (tmp[index1].fX > clip.fRight) {
tmp[index1].set(clip.fRight, sect_with_vertical(src, clip.fRight));
}
#ifdef SK_DEBUG
bounds.set(tmp, 2);
SkASSERT(containsNoEmptyCheck(clip, bounds));
#endif
memcpy(dst, tmp, sizeof(tmp));
return true;
}
示例3: inset
static SkRect inset(const SkRect& r) {
SkRect rect = r;
rect.inset(r.width() / 8, r.height() / 8);
return rect;
}
示例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, 10*SK_Scalar1);
path.fPath.cubicTo(40*SK_Scalar1, 20*SK_Scalar1,
60*SK_Scalar1, 20*SK_Scalar1,
75*SK_Scalar1, 10*SK_Scalar1);
path.fPath.close();
path.fName = "moveTo-cubic-close";
SkPaint titlePaint;
titlePaint.setColor(SK_ColorBLACK);
titlePaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&titlePaint);
titlePaint.setTextSize(15 * SK_Scalar1);
const char title[] = "Cubic Closed 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);
SkRandom 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);
sk_tool_utils::set_portable_typeface(&labelPaint);
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,
//.........这里部分代码省略.........
示例5: computeSize
static SkSize computeSize(const SkBitmap& bm, const SkMatrix& mat) {
SkRect bounds = SkRect::MakeWH(SkIntToScalar(bm.width()),
SkIntToScalar(bm.height()));
mat.mapRect(&bounds);
return SkSize::Make(bounds.width(), bounds.height());
}
示例6: NinePatch_Draw
void NinePatch_Draw(SkCanvas* canvas, const SkRect& bounds,
const SkBitmap& bitmap, const android::Res_png_9patch& chunk,
const SkPaint* paint, SkRegion** outRegion) {
if (canvas && canvas->quickReject(bounds, SkCanvas::kBW_EdgeType)) {
return;
}
// if our canvas is GL, draw this as a mesh, which will be faster than
// in parts (which is faster for raster)
if (canvas && canvas->getViewport(NULL)) {
SkNinePatch::DrawMesh(canvas, bounds, bitmap,
chunk.xDivs, chunk.numXDivs,
chunk.yDivs, chunk.numYDivs,
paint);
return;
}
#ifdef USE_TRACE
gTrace = true;
#endif
SkASSERT(canvas || outRegion);
#if 0
if (canvas) {
const SkMatrix& m = canvas->getTotalMatrix();
SkDebugf("ninepatch [%g %g %g] [%g %g %g]\n",
SkScalarToFloat(m[0]), SkScalarToFloat(m[1]), SkScalarToFloat(m[2]),
SkScalarToFloat(m[3]), SkScalarToFloat(m[4]), SkScalarToFloat(m[5]));
}
#endif
#ifdef USE_TRACE
if (gTrace) {
SkDEBUGF(("======== ninepatch bounds [%g %g]\n", SkScalarToFloat(bounds.width()), SkScalarToFloat(bounds.height())));
SkDEBUGF(("======== ninepatch paint bm [%d,%d]\n", bitmap.width(), bitmap.height()));
SkDEBUGF(("======== ninepatch xDivs [%d,%d]\n", chunk.xDivs[0], chunk.xDivs[1]));
SkDEBUGF(("======== ninepatch yDivs [%d,%d]\n", chunk.yDivs[0], chunk.yDivs[1]));
}
#endif
if (bounds.isEmpty() ||
bitmap.width() == 0 || bitmap.height() == 0 ||
(paint && paint->getXfermode() == NULL && paint->getAlpha() == 0))
{
#ifdef USE_TRACE
if (gTrace) SkDEBUGF(("======== abort ninepatch draw\n"));
#endif
return;
}
// should try a quick-reject test before calling lockPixels
SkAutoLockPixels alp(bitmap);
// after the lock, it is valid to check getPixels()
if (bitmap.getPixels() == NULL)
return;
SkPaint defaultPaint;
if (NULL == paint) {
paint = &defaultPaint;
}
const bool hasXfer = paint->getXfermode() != NULL;
SkRect dst;
SkIRect src;
const int32_t x0 = chunk.xDivs[0];
const int32_t y0 = chunk.yDivs[0];
const SkColor initColor = ((SkPaint*)paint)->getColor();
const uint8_t numXDivs = chunk.numXDivs;
const uint8_t numYDivs = chunk.numYDivs;
int i;
int j;
int colorIndex = 0;
uint32_t color;
bool xIsStretchable;
const bool initialXIsStretchable = (x0 == 0);
bool yIsStretchable = (y0 == 0);
const int bitmapWidth = bitmap.width();
const int bitmapHeight = bitmap.height();
SkScalar* dstRights = (SkScalar*) alloca((numXDivs + 1) * sizeof(SkScalar));
bool dstRightsHaveBeenCached = false;
int numStretchyXPixelsRemaining = 0;
for (i = 0; i < numXDivs; i += 2) {
numStretchyXPixelsRemaining += chunk.xDivs[i + 1] - chunk.xDivs[i];
}
int numFixedXPixelsRemaining = bitmapWidth - numStretchyXPixelsRemaining;
int numStretchyYPixelsRemaining = 0;
for (i = 0; i < numYDivs; i += 2) {
numStretchyYPixelsRemaining += chunk.yDivs[i + 1] - chunk.yDivs[i];
}
int numFixedYPixelsRemaining = bitmapHeight - numStretchyYPixelsRemaining;
#if 0
SkDebugf("NinePatch [%d %d] bounds [%g %g %g %g] divs [%d %d]\n",
bitmap.width(), bitmap.height(),
SkScalarToFloat(bounds.fLeft), SkScalarToFloat(bounds.fTop),
//.........这里部分代码省略.........
示例7: generateAAStrokeRectGeometry
void AAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices,
size_t offset,
size_t vertexStride,
int outerVertexNum,
int innerVertexNum,
GrColor color,
const SkRect& devOutside,
const SkRect& devOutsideAssist,
const SkRect& devInside,
bool miterStroke,
bool degenerate,
bool tweakAlphaForCoverage) const {
intptr_t verts = reinterpret_cast<intptr_t>(vertices) + offset;
// We create vertices for four nested rectangles. There are two ramps from 0 to full
// coverage, one on the exterior of the stroke and the other on the interior.
// The following pointers refer to the four rects, from outermost to innermost.
SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts);
SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + outerVertexNum * vertexStride);
SkPoint* fan2Pos = reinterpret_cast<SkPoint*>(verts + 2 * outerVertexNum * vertexStride);
SkPoint* fan3Pos = reinterpret_cast<SkPoint*>(verts +
(2 * outerVertexNum + innerVertexNum) *
vertexStride);
#ifndef SK_IGNORE_THIN_STROKED_RECT_FIX
// TODO: this only really works if the X & Y margins are the same all around
// the rect (or if they are all >= 1.0).
SkScalar inset;
if (!degenerate) {
inset = SkMinScalar(SK_Scalar1, devOutside.fRight - devInside.fRight);
inset = SkMinScalar(inset, devInside.fLeft - devOutside.fLeft);
inset = SkMinScalar(inset, devInside.fTop - devOutside.fTop);
if (miterStroke) {
inset = SK_ScalarHalf * SkMinScalar(inset, devOutside.fBottom - devInside.fBottom);
} else {
inset = SK_ScalarHalf * SkMinScalar(inset, devOutsideAssist.fBottom -
devInside.fBottom);
}
SkASSERT(inset >= 0);
} else {
// TODO use real devRect here
inset = SkMinScalar(devOutside.width(), SK_Scalar1);
inset = SK_ScalarHalf * SkMinScalar(inset, SkTMax(devOutside.height(),
devOutsideAssist.height()));
}
#else
SkScalar inset;
if (!degenerate) {
inset = SK_ScalarHalf;
} else {
// TODO use real devRect here
inset = SkMinScalar(devOutside.width(), SK_Scalar1);
inset = SK_ScalarHalf * SkMinScalar(inset, SkTMax(devOutside.height(),
devOutsideAssist.height()));
}
#endif
if (miterStroke) {
// outermost
set_inset_fan(fan0Pos, vertexStride, devOutside, -SK_ScalarHalf, -SK_ScalarHalf);
// inner two
set_inset_fan(fan1Pos, vertexStride, devOutside, inset, inset);
if (!degenerate) {
set_inset_fan(fan2Pos, vertexStride, devInside, -inset, -inset);
// innermost
set_inset_fan(fan3Pos, vertexStride, devInside, SK_ScalarHalf, SK_ScalarHalf);
} else {
// When the interior rect has become degenerate we smoosh to a single point
SkASSERT(devInside.fLeft == devInside.fRight &&
devInside.fTop == devInside.fBottom);
fan2Pos->setRectFan(devInside.fLeft, devInside.fTop,
devInside.fRight, devInside.fBottom, vertexStride);
fan3Pos->setRectFan(devInside.fLeft, devInside.fTop,
devInside.fRight, devInside.fBottom, vertexStride);
}
} else {
SkPoint* fan0AssistPos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride);
SkPoint* fan1AssistPos = reinterpret_cast<SkPoint*>(verts +
(outerVertexNum + 4) *
vertexStride);
// outermost
set_inset_fan(fan0Pos, vertexStride, devOutside, -SK_ScalarHalf, -SK_ScalarHalf);
set_inset_fan(fan0AssistPos, vertexStride, devOutsideAssist, -SK_ScalarHalf,
-SK_ScalarHalf);
// outer one of the inner two
set_inset_fan(fan1Pos, vertexStride, devOutside, inset, inset);
set_inset_fan(fan1AssistPos, vertexStride, devOutsideAssist, inset, inset);
if (!degenerate) {
// inner one of the inner two
set_inset_fan(fan2Pos, vertexStride, devInside, -inset, -inset);
// innermost
set_inset_fan(fan3Pos, vertexStride, devInside, SK_ScalarHalf, SK_ScalarHalf);
} else {
// When the interior rect has become degenerate we smoosh to a single point
SkASSERT(devInside.fLeft == devInside.fRight &&
devInside.fTop == devInside.fBottom);
fan2Pos->setRectFan(devInside.fLeft, devInside.fTop,
devInside.fRight, devInside.fBottom, vertexStride);
fan3Pos->setRectFan(devInside.fLeft, devInside.fTop,
devInside.fRight, devInside.fBottom, vertexStride);
//.........这里部分代码省略.........
示例8: drawPattern
void NativeImageSkia::drawPattern(
GraphicsContext* context,
const FloatRect& floatSrcRect,
const FloatSize& scale,
const FloatPoint& phase,
CompositeOperator compositeOp,
const FloatRect& destRect,
WebBlendMode blendMode,
const IntSize& repeatSpacing) const
{
FloatRect normSrcRect = floatSrcRect;
normSrcRect.intersect(FloatRect(0, 0, bitmap().width(), bitmap().height()));
if (destRect.isEmpty() || normSrcRect.isEmpty())
return; // nothing to draw
SkMatrix totalMatrix = context->getTotalMatrix();
AffineTransform ctm = context->getCTM();
SkScalar ctmScaleX = ctm.xScale();
SkScalar ctmScaleY = ctm.yScale();
totalMatrix.preScale(scale.width(), scale.height());
// Figure out what size the bitmap will be in the destination. The
// destination rect is the bounds of the pattern, we need to use the
// matrix to see how big it will be.
SkRect destRectTarget;
totalMatrix.mapRect(&destRectTarget, normSrcRect);
float destBitmapWidth = SkScalarToFloat(destRectTarget.width());
float destBitmapHeight = SkScalarToFloat(destRectTarget.height());
bool isLazyDecoded = DeferredImageDecoder::isLazyDecoded(bitmap());
// Compute the resampling mode.
InterpolationQuality resampling;
if (context->isAccelerated())
resampling = InterpolationLow;
else if (isLazyDecoded)
resampling = InterpolationHigh;
else
resampling = computeInterpolationQuality(totalMatrix, normSrcRect.width(), normSrcRect.height(), destBitmapWidth, destBitmapHeight, isDataComplete());
resampling = limitInterpolationQuality(context, resampling);
SkMatrix localMatrix;
// We also need to translate it such that the origin of the pattern is the
// origin of the destination rect, which is what WebKit expects. Skia uses
// the coordinate system origin as the base for the pattern. If WebKit wants
// a shifted image, it will shift it from there using the localMatrix.
const float adjustedX = phase.x() + normSrcRect.x() * scale.width();
const float adjustedY = phase.y() + normSrcRect.y() * scale.height();
localMatrix.setTranslate(SkFloatToScalar(adjustedX), SkFloatToScalar(adjustedY));
RefPtr<SkShader> shader;
SkFilterQuality filterLevel = static_cast<SkFilterQuality>(resampling);
// Bicubic filter is only applied to defer-decoded images, see
// NativeImageSkia::draw for details.
if (resampling == InterpolationHigh && !isLazyDecoded) {
// Do nice resampling.
filterLevel = kNone_SkFilterQuality;
float scaleX = destBitmapWidth / normSrcRect.width();
float scaleY = destBitmapHeight / normSrcRect.height();
SkRect scaledSrcRect;
// Since we are resizing the bitmap, we need to remove the scale
// applied to the pixels in the bitmap shader. This means we need
// CTM * localMatrix to have identity scale. Since we
// can't modify CTM (or the rectangle will be drawn in the wrong
// place), we must set localMatrix's scale to the inverse of
// CTM scale.
localMatrix.preScale(ctmScaleX ? 1 / ctmScaleX : 1, ctmScaleY ? 1 / ctmScaleY : 1);
// The image fragment generated here is not exactly what is
// requested. The scale factor used is approximated and image
// fragment is slightly larger to align to integer
// boundaries.
SkBitmap resampled = extractScaledImageFragment(normSrcRect, scaleX, scaleY, &scaledSrcRect);
if (repeatSpacing.isZero()) {
shader = adoptRef(SkShader::CreateBitmapShader(resampled, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &localMatrix));
} else {
shader = adoptRef(SkShader::CreateBitmapShader(
createBitmapWithSpace(resampled, repeatSpacing.width() * ctmScaleX, repeatSpacing.height() * ctmScaleY),
SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &localMatrix));
}
} else {
// Because no resizing occurred, the shader transform should be
// set to the pattern's transform, which just includes scale.
localMatrix.preScale(scale.width(), scale.height());
// No need to resample before drawing.
SkBitmap srcSubset;
bitmap().extractSubset(&srcSubset, enclosingIntRect(normSrcRect));
if (repeatSpacing.isZero()) {
shader = adoptRef(SkShader::CreateBitmapShader(srcSubset, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &localMatrix));
} else {
shader = adoptRef(SkShader::CreateBitmapShader(
createBitmapWithSpace(srcSubset, repeatSpacing.width() * ctmScaleX, repeatSpacing.height() * ctmScaleY),
SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &localMatrix));
}
}
//.........这里部分代码省略.........
示例9: BlurRect
bool SkBlurMask::BlurRect(SkScalar sigma, SkMask *dst,
const SkRect &src, SkBlurStyle style,
SkIPoint *margin, SkMask::CreateMode createMode) {
int profile_size = SkScalarCeilToInt(6*sigma);
int pad = profile_size/2;
if (margin) {
margin->set( pad, pad );
}
dst->fBounds.set(SkScalarRoundToInt(src.fLeft - pad),
SkScalarRoundToInt(src.fTop - pad),
SkScalarRoundToInt(src.fRight + pad),
SkScalarRoundToInt(src.fBottom + pad));
dst->fRowBytes = dst->fBounds.width();
dst->fFormat = SkMask::kA8_Format;
dst->fImage = NULL;
int sw = SkScalarFloorToInt(src.width());
int sh = SkScalarFloorToInt(src.height());
if (createMode == SkMask::kJustComputeBounds_CreateMode) {
if (style == kInner_SkBlurStyle) {
dst->fBounds.set(SkScalarRoundToInt(src.fLeft),
SkScalarRoundToInt(src.fTop),
SkScalarRoundToInt(src.fRight),
SkScalarRoundToInt(src.fBottom)); // restore trimmed bounds
dst->fRowBytes = sw;
}
return true;
}
uint8_t *profile = NULL;
ComputeBlurProfile(sigma, &profile);
SkAutoTDeleteArray<uint8_t> ada(profile);
size_t dstSize = dst->computeImageSize();
if (0 == dstSize) {
return false; // too big to allocate, abort
}
uint8_t* dp = SkMask::AllocImage(dstSize);
dst->fImage = dp;
int dstHeight = dst->fBounds.height();
int dstWidth = dst->fBounds.width();
uint8_t *outptr = dp;
SkAutoTMalloc<uint8_t> horizontalScanline(dstWidth);
SkAutoTMalloc<uint8_t> verticalScanline(dstHeight);
ComputeBlurredScanline(horizontalScanline, profile, dstWidth, sigma);
ComputeBlurredScanline(verticalScanline, profile, dstHeight, sigma);
for (int y = 0 ; y < dstHeight ; ++y) {
for (int x = 0 ; x < dstWidth ; x++) {
unsigned int maskval = SkMulDiv255Round(horizontalScanline[x], verticalScanline[y]);
*(outptr++) = maskval;
}
}
if (style == kInner_SkBlurStyle) {
// now we allocate the "real" dst, mirror the size of src
size_t srcSize = (size_t)(src.width() * src.height());
if (0 == srcSize) {
return false; // too big to allocate, abort
}
dst->fImage = SkMask::AllocImage(srcSize);
for (int y = 0 ; y < sh ; y++) {
uint8_t *blur_scanline = dp + (y+pad)*dstWidth + pad;
uint8_t *inner_scanline = dst->fImage + y*sw;
memcpy(inner_scanline, blur_scanline, sw);
}
SkMask::FreeImage(dp);
dst->fBounds.set(SkScalarRoundToInt(src.fLeft),
SkScalarRoundToInt(src.fTop),
SkScalarRoundToInt(src.fRight),
SkScalarRoundToInt(src.fBottom)); // restore trimmed bounds
dst->fRowBytes = sw;
} else if (style == kOuter_SkBlurStyle) {
for (int y = pad ; y < dstHeight-pad ; y++) {
uint8_t *dst_scanline = dp + y*dstWidth + pad;
memset(dst_scanline, 0, sw);
}
} else if (style == kSolid_SkBlurStyle) {
for (int y = pad ; y < dstHeight-pad ; y++) {
uint8_t *dst_scanline = dp + y*dstWidth + pad;
memset(dst_scanline, 0xff, sw);
}
}
// normal and solid styles are the same for analytic rect blurs, so don't
// need to handle solid specially.
return true;
}
示例10: canvas
SkPDFShader::State::State(const SkShader& shader, const SkMatrix& canvasTransform,
const SkIRect& bbox, SkScalar rasterScale)
: fCanvasTransform(canvasTransform),
fBBox(bbox),
fPixelGeneration(0) {
fInfo.fColorCount = 0;
fInfo.fColors = NULL;
fInfo.fColorOffsets = NULL;
fShaderTransform = shader.getLocalMatrix();
fImageTileModes[0] = fImageTileModes[1] = SkShader::kClamp_TileMode;
fType = shader.asAGradient(&fInfo);
if (fType == SkShader::kNone_GradientType) {
SkMatrix matrix;
if (shader.isABitmap(&fImage, &matrix, fImageTileModes)) {
SkASSERT(matrix.isIdentity());
} else {
// Generic fallback for unsupported shaders:
// * allocate a bbox-sized bitmap
// * shade the whole area
// * use the result as a bitmap shader
// bbox is in device space. While that's exactly what we want for sizing our bitmap,
// we need to map it into shader space for adjustments (to match
// SkPDFImageShader::Create's behavior).
SkRect shaderRect = SkRect::Make(bbox);
if (!inverse_transform_bbox(canvasTransform, &shaderRect)) {
fImage.reset();
return;
}
// Clamp the bitmap size to about 1M pixels
static const SkScalar kMaxBitmapArea = 1024 * 1024;
SkScalar bitmapArea = rasterScale * bbox.width() * rasterScale * bbox.height();
if (bitmapArea > kMaxBitmapArea) {
rasterScale *= SkScalarSqrt(kMaxBitmapArea / bitmapArea);
}
SkISize size = SkISize::Make(SkScalarRoundToInt(rasterScale * bbox.width()),
SkScalarRoundToInt(rasterScale * bbox.height()));
SkSize scale = SkSize::Make(SkIntToScalar(size.width()) / shaderRect.width(),
SkIntToScalar(size.height()) / shaderRect.height());
fImage.allocN32Pixels(size.width(), size.height());
fImage.eraseColor(SK_ColorTRANSPARENT);
SkPaint p;
p.setShader(const_cast<SkShader*>(&shader));
SkCanvas canvas(fImage);
canvas.scale(scale.width(), scale.height());
canvas.translate(-shaderRect.x(), -shaderRect.y());
canvas.drawPaint(p);
fShaderTransform.setTranslate(shaderRect.x(), shaderRect.y());
fShaderTransform.preScale(1 / scale.width(), 1 / scale.height());
}
fPixelGeneration = fImage.getGenerationID();
} else {
AllocateGradientInfoStorage();
shader.asAGradient(&fInfo);
}
}
示例11: pattern
SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state) : fState(state) {
fState.get()->fImage.lockPixels();
// The image shader pattern cell will be drawn into a separate device
// in pattern cell space (no scaling on the bitmap, though there may be
// translations so that all content is in the device, coordinates > 0).
// Map clip bounds to shader space to ensure the device is large enough
// to handle fake clamping.
SkMatrix finalMatrix = fState.get()->fCanvasTransform;
finalMatrix.preConcat(fState.get()->fShaderTransform);
SkRect deviceBounds;
deviceBounds.set(fState.get()->fBBox);
if (!inverseTransformBBox(finalMatrix, &deviceBounds)) {
return;
}
const SkBitmap* image = &fState.get()->fImage;
SkRect bitmapBounds;
image->getBounds(&bitmapBounds);
// For tiling modes, the bounds should be extended to include the bitmap,
// otherwise the bitmap gets clipped out and the shader is empty and awful.
// For clamp modes, we're only interested in the clip region, whether
// or not the main bitmap is in it.
SkShader::TileMode tileModes[2];
tileModes[0] = fState.get()->fImageTileModes[0];
tileModes[1] = fState.get()->fImageTileModes[1];
if (tileModes[0] != SkShader::kClamp_TileMode ||
tileModes[1] != SkShader::kClamp_TileMode) {
deviceBounds.join(bitmapBounds);
}
SkMatrix unflip;
unflip.setTranslate(0, SkScalarRoundToScalar(deviceBounds.height()));
unflip.preScale(SK_Scalar1, -SK_Scalar1);
SkISize size = SkISize::Make(SkScalarRound(deviceBounds.width()),
SkScalarRound(deviceBounds.height()));
SkPDFDevice pattern(size, size, unflip);
SkCanvas canvas(&pattern);
SkRect patternBBox;
image->getBounds(&patternBBox);
// Translate the canvas so that the bitmap origin is at (0, 0).
canvas.translate(-deviceBounds.left(), -deviceBounds.top());
patternBBox.offset(-deviceBounds.left(), -deviceBounds.top());
// Undo the translation in the final matrix
finalMatrix.preTranslate(deviceBounds.left(), deviceBounds.top());
// If the bitmap is out of bounds (i.e. clamp mode where we only see the
// stretched sides), canvas will clip this out and the extraneous data
// won't be saved to the PDF.
canvas.drawBitmap(*image, 0, 0);
SkScalar width = SkIntToScalar(image->width());
SkScalar height = SkIntToScalar(image->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(deviceBounds.left(), deviceBounds.top(), 0, 0);
if (!rect.isEmpty()) {
paint.setColor(image->getColor(0, 0));
canvas.drawRect(rect, paint);
}
rect = SkRect::MakeLTRB(width, deviceBounds.top(),
deviceBounds.right(), 0);
if (!rect.isEmpty()) {
paint.setColor(image->getColor(image->width() - 1, 0));
//.........这里部分代码省略.........
示例12: onDraw
void onDraw(SkCanvas* canvas) override {
int size = fPowerOfTwoSize ? kPOTSize : kNPOTSize;
SkRect r = { 0, 0, SkIntToScalar(size*2), SkIntToScalar(size*2) };
static const char* gConfigNames[] = { "8888", "565", "4444" };
static const bool gFilters[] = { false, true };
static const char* gFilterNames[] = { "point", "bilinear" };
static const SkShader::TileMode gModes[] = { SkShader::kClamp_TileMode, SkShader::kRepeat_TileMode, SkShader::kMirror_TileMode };
static const char* gModeNames[] = { "C", "R", "M" };
SkScalar y = SkIntToScalar(24);
SkScalar x = SkIntToScalar(10);
for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
SkPaint p;
SkString str;
p.setAntiAlias(true);
sk_tool_utils::set_portable_typeface_always(&p);
p.setDither(true);
str.printf("[%s,%s]", gModeNames[kx], gModeNames[ky]);
p.setTextAlign(SkPaint::kCenter_Align);
canvas->drawText(str.c_str(), str.size(), x + r.width()/2, y, p);
x += r.width() * 4 / 3;
}
}
y += SkIntToScalar(16);
for (size_t i = 0; i < SK_ARRAY_COUNT(gColorTypes); i++) {
for (size_t j = 0; j < SK_ARRAY_COUNT(gFilters); j++) {
x = SkIntToScalar(10);
for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
SkPaint paint;
#if 1 // Temporary change to regen bitmap before each draw. This may help tracking down an issue
// on SGX where resizing NPOT textures to POT textures exhibits a driver bug.
if (!fPowerOfTwoSize) {
makebm(&fTexture[i], gColorTypes[i], size, size);
}
#endif
setup(&paint, fTexture[i], gFilters[j], gModes[kx], gModes[ky]);
paint.setDither(true);
canvas->save();
canvas->translate(x, y);
canvas->drawRect(r, paint);
canvas->restore();
x += r.width() * 4 / 3;
}
}
{
SkPaint p;
SkString str;
p.setAntiAlias(true);
sk_tool_utils::set_portable_typeface_always(&p);
str.printf("%s, %s", gConfigNames[i], gFilterNames[j]);
canvas->drawText(str.c_str(), str.size(), x, y + r.height() * 2 / 3, p);
}
y += r.height() * 4 / 3;
}
}
}
示例13: paintSkBitmap
static void paintSkBitmap(PlatformContextSkia* platformContext, const NativeImageSkia& bitmap, const SkIRect& srcRect, const SkRect& destRect, const SkXfermode::Mode& compOp)
{
#if PLATFORM(CHROMIUM)
TRACE_EVENT("paintSkBitmap", platformContext, 0);
#endif
SkPaint paint;
paint.setXfermodeMode(compOp);
paint.setAlpha(platformContext->getNormalizedAlpha());
paint.setLooper(platformContext->getDrawLooper());
// only antialias if we're rotated or skewed
paint.setAntiAlias(hasNon90rotation(platformContext));
SkCanvas* canvas = platformContext->canvas();
ResamplingMode resampling;
if (platformContext->isAccelerated())
resampling = RESAMPLE_LINEAR;
else
resampling = platformContext->printing() ? RESAMPLE_NONE :
computeResamplingMode(platformContext, bitmap, srcRect.width(), srcRect.height(), SkScalarToFloat(destRect.width()), SkScalarToFloat(destRect.height()));
if (resampling == RESAMPLE_NONE) {
// FIXME: This is to not break tests (it results in the filter bitmap flag
// being set to true). We need to decide if we respect RESAMPLE_NONE
// being returned from computeResamplingMode.
resampling = RESAMPLE_LINEAR;
}
resampling = limitResamplingMode(platformContext, resampling);
paint.setFilterBitmap(resampling == RESAMPLE_LINEAR);
if (resampling == RESAMPLE_AWESOME)
drawResampledBitmap(*canvas, paint, bitmap, srcRect, destRect);
else {
// No resampling necessary, we can just draw the bitmap. We want to
// filter it if we decided to do linear interpolation above, or if there
// is something interesting going on with the matrix (like a rotation).
// Note: for serialization, we will want to subset the bitmap first so
// we don't send extra pixels.
canvas->drawBitmapRect(bitmap.bitmap(), &srcRect, destRect, &paint);
}
platformContext->didDrawRect(destRect, paint, &bitmap.bitmap());
}
示例14: StrokeAARect
void GrAARectRenderer::StrokeAARect(GrDrawTarget* target,
const 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);
}
示例15: geometryFillAARect
void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
const SkRect& rect,
const SkMatrix& combinedMatrix,
const SkRect& devRect) {
GrDrawState::AutoRestoreEffects are(drawState);
CoverageAttribType type;
SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color, &type));
size_t vertexStride = gp->getVertexStride();
GrDrawTarget::AutoReleaseGeometry geo(target, 8, vertexStride, 0);
if (!geo.succeeded()) {
SkDebugf("Failed to get space for vertices!\n");
return;
}
if (NULL == fAAFillRectIndexBuffer) {
fAAFillRectIndexBuffer = fGpu->createInstancedIndexBuffer(gFillAARectIdx,
kIndicesPerAAFillRect,
kNumAAFillRectsInIndexBuffer,
kVertsPerAAFillRect);
}
GrIndexBuffer* indexBuffer = fAAFillRectIndexBuffer;
if (NULL == indexBuffer) {
SkDebugf("Failed to create index buffer!\n");
return;
}
intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices());
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 (combinedMatrix.rectStaysRect()) {
// Temporarily #if'ed out. We don't want to pass in the devRect but
// right now it is computed in GrContext::apply_aa_to_rect and we don't
// want to throw away the work
#if 0
SkRect devRect;
combinedMatrix.mapRect(&devRect, rect);
#endif
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] = {
{ combinedMatrix[SkMatrix::kMScaleX], combinedMatrix[SkMatrix::kMSkewY] },
{ combinedMatrix[SkMatrix::kMSkewX], combinedMatrix[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);
combinedMatrix.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 (kUseCoverage_CoverageAttribType == type) {
*reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
*reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)) = 0;
} else {
*reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0;
}
}
int scale;
if (inset < SK_ScalarHalf) {
//.........这里部分代码省略.........