aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkDraw.cpp
diff options
context:
space:
mode:
authorGravatar Herb Derby <herb@google.com>2018-07-20 11:48:38 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-07-24 14:53:25 +0000
commit81ecdbb7ff36afef9091c1b524baafe67381e70d (patch)
treec9d2a2ace6fecc88bf85e1377c2eeb8d8d007a5a /src/core/SkDraw.cpp
parentab98509717e1d20b8171a631d2923f47ce26fc0e (diff)
Clean up bitmap path
Change-Id: If149194fd86f14bea289ad68262ea99cbbc398b6 Reviewed-on: https://skia-review.googlesource.com/142817 Reviewed-by: Ben Wagner <bungeman@google.com> Commit-Queue: Herb Derby <herb@google.com>
Diffstat (limited to 'src/core/SkDraw.cpp')
-rw-r--r--src/core/SkDraw.cpp134
1 files changed, 134 insertions, 0 deletions
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index ae1a873f2b..4c9dddf1f5 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -1598,6 +1598,140 @@ void SkDraw::drawPosText(const char text[], size_t byteLength, const SkScalar po
offset, *fMatrix, pos, scalarsPerPosition, cache.get(), drawOneGlyph);
}
+void SkDraw::drawGlyphRunAsPaths(
+ SkGlyphRun* glyphRun, SkPoint origin, const SkSurfaceProps* props) const {
+ // setup our std paint, in hopes of getting hits in the cache
+ const SkPaint& origPaint = glyphRun->paint();
+ SkPaint paint(glyphRun->paint());
+ SkScalar matrixScale = paint.setupForAsPaths();
+
+ SkMatrix matrix;
+ matrix.setScale(matrixScale, matrixScale);
+
+ // Temporarily jam in kFill, so we only ever ask for the raw outline from the cache.
+ paint.setStyle(SkPaint::kFill_Style);
+ paint.setPathEffect(nullptr);
+
+ auto cache = SkStrikeCache::FindOrCreateStrikeExclusive(
+ paint, props, this->scalerContextFlags(), nullptr);
+
+ // Now restore the original settings, so we "draw" with whatever style/stroking.
+ paint.setStyle(origPaint.getStyle());
+ paint.setPathEffect(origPaint.refPathEffect());
+
+ auto eachGlyph = [this, origin, &cache, &matrix, &paint](SkGlyphID glyphID, SkPoint position) {
+ const SkGlyph& glyph = cache->getGlyphIDMetrics(glyphID);
+ if (glyph.fWidth > 0) {
+ const SkPath* path = cache->findPath(glyph);
+ if (path != nullptr) {
+ SkPoint loc = position + origin;
+ matrix[SkMatrix::kMTransX] = loc.fX;
+ matrix[SkMatrix::kMTransY] = loc.fY;
+ this->drawPath(*path, paint, &matrix, false);
+ }
+ }
+ };
+ glyphRun->forEachGlyphAndPosition(eachGlyph);
+}
+
+void SkDraw::drawGlyphRunAsSubpixelMask(
+ SkGlyphCache* cache, SkGlyphRun* glyphRun, SkPoint origin) const {
+
+ SkMatrix matrix = *fMatrix;
+ // Add rounding and origin.
+ SkAxisAlignment axisAlignment = cache->getScalerContext()->computeAxisAlignmentForHText();
+ SkPoint rounding = SkFindAndPlaceGlyph::SubpixelPositionRounding(axisAlignment);
+ matrix.preTranslate(origin.x(), origin.y());
+ matrix.postTranslate(rounding.x(), rounding.y());
+
+ glyphRun->mapPositions(matrix);
+
+ auto paint = glyphRun->paint();
+ // The Blitter Choose needs to be live while using the blitter below.
+ SkAutoBlitterChoose blitterChooser(*this, nullptr, paint);
+ SkAAClipBlitterWrapper wrapper(*fRC, blitterChooser.get());
+ DrawOneGlyph drawOneGlyph(*this, paint, cache, wrapper.getBlitter());
+
+ auto eachGlyph = [cache, &drawOneGlyph, axisAlignment](SkGlyphID glyphID, SkPoint position) {
+ auto subpixelAlignment = [](SkAxisAlignment axisAlignment, SkPoint position) -> SkIPoint {
+
+ if (!SkScalarsAreFinite(position.fX, position.fY)) {
+ return {0, 0};
+ }
+
+ // Only the fractional part of position.fX and position.fY matter, because the result of
+ // this function will just be passed to FixedToSub.
+ switch (axisAlignment) {
+ case kX_SkAxisAlignment:
+ return {SkScalarToFixed(SkScalarFraction(position.fX)), 0};
+ case kY_SkAxisAlignment:
+ return {0, SkScalarToFixed(SkScalarFraction(position.fY))};
+ case kNone_SkAxisAlignment:
+ return {SkScalarToFixed(SkScalarFraction(position.fX)),
+ SkScalarToFixed(SkScalarFraction(position.fY))};
+ }
+ SK_ABORT("Should not get here.");
+ return {0, 0};
+ };
+
+ SkIPoint lookupPosition = subpixelAlignment(axisAlignment, position);
+ const SkGlyph& glyph = cache->getGlyphIDMetrics(
+ glyphID, lookupPosition.x(), lookupPosition.y());
+ if (glyph.fWidth > 0) {
+ drawOneGlyph(glyph, position, SkPoint::Make(0, 0));
+ }
+ };
+ glyphRun->forEachGlyphAndPosition(eachGlyph);
+}
+
+void SkDraw::drawGlyphRunAsFullpixelMask(
+ SkGlyphCache* cache, SkGlyphRun* glyphRun, SkPoint origin) const {
+ SkMatrix matrix = *fMatrix;
+ // Add rounding and origin.
+ matrix.preTranslate(origin.x(), origin.y());
+ matrix.postTranslate(SK_ScalarHalf, SK_ScalarHalf);
+ glyphRun->mapPositions(matrix);
+
+ auto paint = glyphRun->paint();
+ // The Blitter Choose needs to be live while using the blitter below.
+ SkAutoBlitterChoose blitterChooser(*this, nullptr, paint);
+ SkAAClipBlitterWrapper wrapper(*fRC, blitterChooser.get());
+ DrawOneGlyph drawOneGlyph(*this, paint, cache, wrapper.getBlitter());
+
+ auto eachGlyph = [cache, &drawOneGlyph](SkGlyphID glyphID, SkPoint position) {
+ const SkGlyph& glyph = cache->getGlyphIDMetrics(glyphID);
+ if (glyph.fWidth > 0) {
+ drawOneGlyph(glyph, position, SkPoint::Make(0, 0));
+ }
+ };
+ glyphRun->forEachGlyphAndPosition(eachGlyph);
+}
+
+void SkDraw::drawGlyphRunList(SkGlyphRunList* glyphRunList, const SkSurfaceProps* props) const {
+
+ SkDEBUGCODE(this->validate();)
+
+ if (fRC->isEmpty()) {
+ return;
+ }
+
+ SkPoint origin = glyphRunList->origin();
+ for (auto& glyphRun : *glyphRunList) {
+ if (ShouldDrawTextAsPaths(glyphRun.paint(), *fMatrix)) {
+ this->drawGlyphRunAsPaths(&glyphRun, origin, props);
+ } else {
+ auto cache = SkStrikeCache::FindOrCreateStrikeExclusive(
+ glyphRun.paint(), props, this->scalerContextFlags(), fMatrix);
+ if (cache->isSubpixel()) {
+ this->drawGlyphRunAsSubpixelMask(cache.get(), &glyphRun, origin);
+ } else {
+ this->drawGlyphRunAsFullpixelMask(cache.get(), &glyphRun, origin);
+ }
+ }
+ }
+
+}
+
#if defined _WIN32
#pragma warning ( pop )
#endif