本文整理汇总了C++中SkStrokeRec::getWidth方法的典型用法代码示例。如果您正苦于以下问题:C++ SkStrokeRec::getWidth方法的具体用法?C++ SkStrokeRec::getWidth怎么用?C++ SkStrokeRec::getWidth使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SkStrokeRec
的用法示例。
在下文中一共展示了SkStrokeRec::getWidth方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: draw
/**
* Draw a single path element of the clip stack into the accumulation bitmap
*/
void GrSWMaskHelper::draw(const SkPath& path, const SkStrokeRec& stroke, SkRegion::Op op,
bool antiAlias, uint8_t alpha) {
SkPaint paint;
if (stroke.isHairlineStyle()) {
paint.setStyle(SkPaint::kStroke_Style);
paint.setStrokeWidth(SK_Scalar1);
} else {
if (stroke.isFillStyle()) {
paint.setStyle(SkPaint::kFill_Style);
} else {
paint.setStyle(SkPaint::kStroke_Style);
paint.setStrokeJoin(stroke.getJoin());
paint.setStrokeCap(stroke.getCap());
paint.setStrokeWidth(stroke.getWidth());
}
}
paint.setAntiAlias(antiAlias);
if (SkRegion::kReplace_Op == op && 0xFF == alpha) {
SkASSERT(0xFF == paint.getAlpha());
fDraw.drawPathCoverage(path, paint);
} else {
paint.setXfermodeMode(op_to_mode(op));
paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha));
fDraw.drawPath(path, paint);
}
}
示例2: ComputeStrokeKey
uint64_t GrPath::ComputeStrokeKey(const SkStrokeRec& stroke) {
enum {
kStyleBits = 2,
kJoinBits = 2,
kCapBits = 2,
kWidthBits = 29,
kMiterBits = 29,
kJoinShift = kStyleBits,
kCapShift = kJoinShift + kJoinBits,
kWidthShift = kCapShift + kCapBits,
kMiterShift = kWidthShift + kWidthBits,
kBitCount = kMiterShift + kMiterBits
};
SK_COMPILE_ASSERT(SkStrokeRec::kStyleCount <= (1 << kStyleBits), style_shift_will_be_wrong);
SK_COMPILE_ASSERT(SkPaint::kJoinCount <= (1 << kJoinBits), cap_shift_will_be_wrong);
SK_COMPILE_ASSERT(SkPaint::kCapCount <= (1 << kCapBits), miter_shift_will_be_wrong);
SK_COMPILE_ASSERT(kBitCount == 64, wrong_stroke_key_size);
if (!stroke.needToApply()) {
return SkStrokeRec::kFill_Style;
}
uint64_t key = stroke.getStyle();
key |= stroke.getJoin() << kJoinShift;
key |= stroke.getCap() << kCapShift;
key |= get_top_n_float_bits<kWidthBits>(stroke.getWidth()) << kWidthShift;
key |= get_top_n_float_bits<kMiterBits>(stroke.getMiter()) << kMiterShift;
return key;
}
示例3: Make
static std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, const SkMatrix& viewMatrix,
const SkRect& rect, const SkStrokeRec& stroke,
bool snapToPixelCenters) {
if (!allowed_stroke(stroke)) {
return nullptr;
}
NonAAStrokeRectOp* op = new NonAAStrokeRectOp();
op->fColor = color;
op->fViewMatrix = viewMatrix;
op->fRect = rect;
// Sort the rect for hairlines
op->fRect.sort();
op->fStrokeWidth = stroke.getWidth();
SkScalar rad = SkScalarHalf(op->fStrokeWidth);
SkRect bounds = rect;
bounds.outset(rad, rad);
// If our caller snaps to pixel centers then we have to round out the bounds
if (snapToPixelCenters) {
viewMatrix.mapRect(&bounds);
// We want to be consistent with how we snap non-aa lines. To match what we do in
// GrGLSLVertexShaderBuilder, we first floor all the vertex values and then add half a
// pixel to force us to pixel centers.
bounds.set(SkScalarFloorToScalar(bounds.fLeft),
SkScalarFloorToScalar(bounds.fTop),
SkScalarFloorToScalar(bounds.fRight),
SkScalarFloorToScalar(bounds.fBottom));
bounds.offset(0.5f, 0.5f);
op->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo);
} else {
op->setTransformedBounds(bounds, op->fViewMatrix, HasAABloat::kNo, IsZeroArea::kNo);
}
return std::unique_ptr<GrLegacyMeshDrawOp>(op);
}
示例4:
inline static bool is_miter(const SkStrokeRec& stroke) {
// For hairlines, make bevel and round joins appear the same as mitered ones.
// small miter limit means right angles show bevel...
if ((stroke.getWidth() > 0) && (stroke.getJoin() != SkPaint::kMiter_Join ||
stroke.getMiter() < SK_ScalarSqrt2)) {
return false;
}
return true;
}
示例5: outset_for_stroke
static void outset_for_stroke(SkRect* rect, const SkStrokeRec& rec) {
SkScalar radius = SkScalarHalf(rec.getWidth());
if (0 == radius) {
radius = SK_Scalar1; // hairlines
}
if (SkPaint::kMiter_Join == rec.getJoin()) {
radius = SkScalarMul(radius, rec.getMiter());
}
rect->outset(radius, radius);
}
示例6: Append
bool Append(GrBatch* origBatch,
GrColor color,
const SkMatrix& viewMatrix,
const SkRect& rect,
const SkStrokeRec& stroke) {
AAStrokeRectBatch* batch = origBatch->cast<AAStrokeRectBatch>();
// we can't batch across vm changes
bool isMiterStroke = is_miter(stroke);
if (!batch->canAppend(viewMatrix, isMiterStroke)) {
return false;
}
SkRect devOutside, devOutsideAssist, devInside;
bool isDegenerate;
compute_rects(&devOutside, &devOutsideAssist, &devInside, &isDegenerate, viewMatrix,
rect, stroke.getWidth(), isMiterStroke);
batch->appendAndUpdateBounds(color, devOutside, devOutsideAssist, devInside, isDegenerate);
return true;
}
示例7: draw
/**
* Draw a single path element of the clip stack into the accumulation bitmap
*/
void GrSWMaskHelper::draw(const SkPath& path, const SkStrokeRec& stroke, SkRegion::Op op,
bool antiAlias, uint8_t alpha) {
SkPaint paint;
if (stroke.isHairlineStyle()) {
paint.setStyle(SkPaint::kStroke_Style);
paint.setStrokeWidth(SK_Scalar1);
} else {
if (stroke.isFillStyle()) {
paint.setStyle(SkPaint::kFill_Style);
} else {
paint.setStyle(SkPaint::kStroke_Style);
paint.setStrokeJoin(stroke.getJoin());
paint.setStrokeCap(stroke.getCap());
paint.setStrokeWidth(stroke.getWidth());
}
}
paint.setAntiAlias(antiAlias);
SkTBlitterAllocator allocator;
SkBlitter* blitter = nullptr;
if (kBlitter_CompressionMode == fCompressionMode) {
SkASSERT(fCompressedBuffer.get());
blitter = SkTextureCompressor::CreateBlitterForFormat(
fPixels.width(), fPixels.height(), fCompressedBuffer.get(), &allocator,
fCompressedFormat);
}
if (SkRegion::kReplace_Op == op && 0xFF == alpha) {
SkASSERT(0xFF == paint.getAlpha());
fDraw.drawPathCoverage(path, paint, blitter);
} else {
paint.setXfermodeMode(op_to_mode(op));
paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha));
fDraw.drawPath(path, paint, blitter);
}
}
示例8: asPoints
// Currently asPoints is more restrictive then it needs to be. In the future
// we need to:
// allow kRound_Cap capping (could allow rotations in the matrix with this)
// allow paths to be returned
bool SkDashPathEffect::asPoints(PointData* results,
const SkPath& src,
const SkStrokeRec& rec,
const SkMatrix& matrix,
const SkRect* cullRect) const {
// width < 0 -> fill && width == 0 -> hairline so requiring width > 0 rules both out
if (fInitialDashLength < 0 || 0 >= rec.getWidth()) {
return false;
}
// TODO: this next test could be eased up. We could allow any number of
// intervals as long as all the ons match and all the offs match.
// Additionally, they do not necessarily need to be integers.
// We cannot allow arbitrary intervals since we want the returned points
// to be uniformly sized.
if (fCount != 2 ||
!SkScalarNearlyEqual(fIntervals[0], fIntervals[1]) ||
!SkScalarIsInt(fIntervals[0]) ||
!SkScalarIsInt(fIntervals[1])) {
return false;
}
SkPoint pts[2];
if (!src.isLine(pts)) {
return false;
}
// TODO: this test could be eased up to allow circles
if (SkPaint::kButt_Cap != rec.getCap()) {
return false;
}
// TODO: this test could be eased up for circles. Rotations could be allowed.
if (!matrix.rectStaysRect()) {
return false;
}
// See if the line can be limited to something plausible.
if (!cull_line(pts, rec, matrix, cullRect, fIntervalLength)) {
return false;
}
SkScalar length = SkPoint::Distance(pts[1], pts[0]);
SkVector tangent = pts[1] - pts[0];
if (tangent.isZero()) {
return false;
}
tangent.scale(SkScalarInvert(length));
// TODO: make this test for horizontal & vertical lines more robust
bool isXAxis = true;
if (SkScalarNearlyEqual(SK_Scalar1, tangent.fX) ||
SkScalarNearlyEqual(-SK_Scalar1, tangent.fX)) {
results->fSize.set(SkScalarHalf(fIntervals[0]), SkScalarHalf(rec.getWidth()));
} else if (SkScalarNearlyEqual(SK_Scalar1, tangent.fY) ||
SkScalarNearlyEqual(-SK_Scalar1, tangent.fY)) {
results->fSize.set(SkScalarHalf(rec.getWidth()), SkScalarHalf(fIntervals[0]));
isXAxis = false;
} else if (SkPaint::kRound_Cap != rec.getCap()) {
// Angled lines don't have axis-aligned boxes.
return false;
}
if (results) {
results->fFlags = 0;
SkScalar clampedInitialDashLength = SkMinScalar(length, fInitialDashLength);
if (SkPaint::kRound_Cap == rec.getCap()) {
results->fFlags |= PointData::kCircles_PointFlag;
}
results->fNumPoints = 0;
SkScalar len2 = length;
if (clampedInitialDashLength > 0 || 0 == fInitialDashIndex) {
SkASSERT(len2 >= clampedInitialDashLength);
if (0 == fInitialDashIndex) {
if (clampedInitialDashLength > 0) {
if (clampedInitialDashLength >= fIntervals[0]) {
++results->fNumPoints; // partial first dash
}
len2 -= clampedInitialDashLength;
}
len2 -= fIntervals[1]; // also skip first space
if (len2 < 0) {
len2 = 0;
}
} else {
len2 -= clampedInitialDashLength; // skip initial partial empty
}
}
int numMidPoints = SkScalarFloorToInt(len2 / fIntervalLength);
results->fNumPoints += numMidPoints;
len2 -= numMidPoints * fIntervalLength;
//.........这里部分代码省略.........
示例9: SkASSERT
// Allow all hairlines and all miters, so long as the miter limit doesn't produce beveled corners.
inline static bool allowed_stroke(const SkStrokeRec& stroke) {
SkASSERT(stroke.getStyle() == SkStrokeRec::kStroke_Style ||
stroke.getStyle() == SkStrokeRec::kHairline_Style);
return !stroke.getWidth() ||
(stroke.getJoin() == SkPaint::kMiter_Join && stroke.getMiter() > SK_ScalarSqrt2);
}
示例10: strokeAARect
void GrAARectRenderer::strokeAARect(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
const SkRect& rect,
const SkMatrix& combinedMatrix,
const SkRect& devRect,
const SkStrokeRec& stroke) {
SkVector devStrokeSize;
SkScalar width = stroke.getWidth();
if (width > 0) {
devStrokeSize.set(width, width);
combinedMatrix.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);
// 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
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) {
this->fillAARect(target, drawState, color, devOutside, SkMatrix::I(), 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);
}
this->geometryStrokeAARect(target, drawState, color, devOutside, devOutsideAssist, devInside,
miterStroke);
}
示例11: onDrawPath
bool GrStrokePathRenderer::onDrawPath(const SkPath& origPath,
const SkStrokeRec& stroke,
GrDrawTarget* target,
bool antiAlias) {
if (origPath.isEmpty()) {
return true;
}
SkScalar width = stroke.getWidth();
if (width <= 0) {
return false;
}
// Get the join type
SkPaint::Join join = stroke.getJoin();
SkScalar miterLimit = stroke.getMiter();
SkScalar sqMiterLimit = SkScalarMul(miterLimit, miterLimit);
if ((join == SkPaint::kMiter_Join) && (miterLimit <= SK_Scalar1)) {
// If the miter limit is small, treat it as a bevel join
join = SkPaint::kBevel_Join;
}
const bool isMiter = (join == SkPaint::kMiter_Join);
const bool isBevel = (join == SkPaint::kBevel_Join);
SkScalar invMiterLimit = isMiter ? SK_Scalar1 / miterLimit : 0;
SkScalar invMiterLimitSq = SkScalarMul(invMiterLimit, invMiterLimit);
// Allocate vertices
const int nbQuads = origPath.countPoints() + 1; // Could be "-1" if path is not closed
const int extraVerts = isMiter || isBevel ? 1 : 0;
const int maxVertexCount = nbQuads * (4 + extraVerts);
const int maxIndexCount = nbQuads * (6 + extraVerts * 3); // Each extra vert adds a triangle
target->drawState()->setDefaultVertexAttribs();
GrDrawTarget::AutoReleaseGeometry arg(target, maxVertexCount, maxIndexCount);
if (!arg.succeeded()) {
return false;
}
SkPoint* verts = reinterpret_cast<SkPoint*>(arg.vertices());
uint16_t* idxs = reinterpret_cast<uint16_t*>(arg.indices());
int vCount = 0, iCount = 0;
// Transform the path into a list of triangles
SkPath::Iter iter(origPath, false);
SkPoint pts[4];
const SkScalar radius = SkScalarMul(width, 0.5f);
SkPoint *firstPt = verts, *lastPt = NULL;
SkVector firstDir, dir;
firstDir.set(0, 0);
dir.set(0, 0);
bool isOpen = true;
for(SkPath::Verb v = iter.next(pts); v != SkPath::kDone_Verb; v = iter.next(pts)) {
switch(v) {
case SkPath::kMove_Verb:
// This will already be handled as pts[0] of the 1st line
break;
case SkPath::kClose_Verb:
isOpen = (lastPt == NULL);
break;
case SkPath::kLine_Verb:
{
SkVector v0 = dir;
dir = pts[1] - pts[0];
if (dir.setLength(radius)) {
SkVector dirT;
dirT.set(dir.fY, -dir.fX); // Get perpendicular direction
SkPoint l1a = pts[0]+dirT, l1b = pts[1]+dirT,
l2a = pts[0]-dirT, l2b = pts[1]-dirT;
SkPoint miterPt[2];
bool useMiterPoint = false;
int idx0(-1), idx1(-1);
if (NULL == lastPt) {
firstDir = dir;
} else {
SkVector v1 = dir;
if (v0.normalize() && v1.normalize()) {
SkScalar dotProd = v0.dot(v1);
// No need for bevel or miter join if the angle
// is either 0 or 180 degrees
if (!SkScalarNearlyZero(dotProd + SK_Scalar1) &&
!SkScalarNearlyZero(dotProd - SK_Scalar1)) {
bool ccw = !is_clockwise(v0, v1);
int offset = ccw ? 1 : 0;
idx0 = vCount-2+offset;
idx1 = vCount+offset;
const SkPoint* pt0 = &(lastPt[offset]);
const SkPoint* pt1 = ccw ? &l2a : &l1a;
switch(join) {
case SkPaint::kMiter_Join:
{
// *Note : Logic is from MiterJoiner
// FIXME : Special case if we have a right angle ?
// if (SkScalarNearlyZero(dotProd)) {...}
SkScalar sinHalfAngleSq =
SkScalarHalf(SK_Scalar1 + dotProd);
if (sinHalfAngleSq >= invMiterLimitSq) {
// Find the miter point (or points if it is further
// than the miter limit)
const SkPoint pt2 = *pt0+v0, pt3 = *pt1+v1;
if (intersection(*pt0, pt2, *pt1, pt3, miterPt[0]) !=
//.........这里部分代码省略.........
示例12: 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);
}
示例13: init
void GrStencilAndCoverTextContext::init(const GrPaint& paint,
const SkPaint& skPaint,
size_t textByteLength,
RenderMode renderMode,
SkScalar textTranslateY) {
GrTextContext::init(paint, skPaint);
fContextInitialMatrix = fContext->getMatrix();
const bool otherBackendsWillDrawAsPaths =
SkDraw::ShouldDrawTextAsPaths(skPaint, fContextInitialMatrix);
fNeedsDeviceSpaceGlyphs = !otherBackendsWillDrawAsPaths &&
kMaxAccuracy_RenderMode == renderMode &&
SkToBool(fContextInitialMatrix.getType() &
(SkMatrix::kScale_Mask | SkMatrix::kAffine_Mask));
if (fNeedsDeviceSpaceGlyphs) {
// SkDraw::ShouldDrawTextAsPaths takes care of perspective transforms.
SkASSERT(!fContextInitialMatrix.hasPerspective());
SkASSERT(0 == textTranslateY); // TODO: Handle textTranslateY in device-space usecase.
fTextRatio = fTextInverseRatio = 1.0f;
// Glyphs loaded by GPU path rendering have an inverted y-direction.
SkMatrix m;
m.setScale(1, -1);
fContext->setMatrix(m);
// Post-flip the initial matrix so we're left with just the flip after
// the paint preConcats the inverse.
m = fContextInitialMatrix;
m.postScale(1, -1);
fPaint.localCoordChangeInverse(m);
// The whole shape (including stroke) will be baked into the glyph outlines. Make
// NVPR just fill the baked shapes.
fGlyphCache = fSkPaint.detachCache(&fDeviceProperties, &fContextInitialMatrix, false);
fGlyphs = get_gr_glyphs(fContext, fGlyphCache->getScalerContext()->getTypeface(),
&fGlyphCache->getDescriptor(),
SkStrokeRec(SkStrokeRec::kFill_InitStyle));
} else {
// Don't bake strokes into the glyph outlines. We will stroke the glyphs
// using the GPU instead. This is the fast path.
SkStrokeRec gpuStroke = SkStrokeRec(fSkPaint);
fSkPaint.setStyle(SkPaint::kFill_Style);
if (gpuStroke.isHairlineStyle()) {
// Approximate hairline stroke.
SkScalar strokeWidth = SK_Scalar1 /
(SkVector::Make(fContextInitialMatrix.getScaleX(),
fContextInitialMatrix.getSkewY()).length());
gpuStroke.setStrokeStyle(strokeWidth, false /*strokeAndFill*/);
} else if (fSkPaint.isFakeBoldText() &&
#ifdef SK_USE_FREETYPE_EMBOLDEN
kMaxPerformance_RenderMode == renderMode &&
#endif
SkStrokeRec::kStroke_Style != gpuStroke.getStyle()) {
// Instead of baking fake bold into the glyph outlines, do it with the GPU stroke.
SkScalar fakeBoldScale = SkScalarInterpFunc(fSkPaint.getTextSize(),
kStdFakeBoldInterpKeys,
kStdFakeBoldInterpValues,
kStdFakeBoldInterpLength);
SkScalar extra = SkScalarMul(fSkPaint.getTextSize(), fakeBoldScale);
gpuStroke.setStrokeStyle(gpuStroke.needToApply() ? gpuStroke.getWidth() + extra : extra,
true /*strokeAndFill*/);
fSkPaint.setFakeBoldText(false);
}
bool canUseRawPaths;
if (otherBackendsWillDrawAsPaths || kMaxPerformance_RenderMode == renderMode) {
// We can draw the glyphs from canonically sized paths.
fTextRatio = fSkPaint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths;
fTextInverseRatio = SkPaint::kCanonicalTextSizeForPaths / fSkPaint.getTextSize();
// Compensate for the glyphs being scaled by fTextRatio.
if (!gpuStroke.isFillStyle()) {
gpuStroke.setStrokeStyle(gpuStroke.getWidth() / fTextRatio,
SkStrokeRec::kStrokeAndFill_Style == gpuStroke.getStyle());
}
fSkPaint.setLinearText(true);
fSkPaint.setLCDRenderText(false);
fSkPaint.setAutohinted(false);
fSkPaint.setHinting(SkPaint::kNo_Hinting);
fSkPaint.setSubpixelText(true);
fSkPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths));
canUseRawPaths = SK_Scalar1 == fSkPaint.getTextScaleX() &&
0 == fSkPaint.getTextSkewX() &&
!fSkPaint.isFakeBoldText() &&
!fSkPaint.isVerticalText();
} else {
fTextRatio = fTextInverseRatio = 1.0f;
canUseRawPaths = false;
}
//.........这里部分代码省略.........