aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Hal Canary <halcanary@google.com>2018-06-06 13:29:51 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-06 13:29:57 +0000
commit74b390d6b136a60f1df15ac5ecd19bd8ad5a394b (patch)
treeafba5f9d8d8d802e9b6873c5f4c7948a94f76762 /src/core
parent102c8cf26e2886ba783a2b54827e1f5d1cf0a774 (diff)
Revert "Have draw(Text|PosText|PosTextH) use a single entry on the device"
This reverts commit 4225b3220ef4bf50f0d9403f812ea94d50c4ee59. Reason for revert: made valgrind unhappy. Original change's description: > Have draw(Text|PosText|PosTextH) use a single entry on the device > > Handle the positioning of drawText at the canvas layer. Simplify > the code by removing similar implementations. > > Change-Id: I8b711783435072f560e29fca1dd934fa2e345ed2 > Reviewed-on: https://skia-review.googlesource.com/127131 > Reviewed-by: Ben Wagner <bungeman@google.com> > Commit-Queue: Herb Derby <herb@google.com> TBR=jvanverth@google.com,bungeman@google.com,herb@google.com Change-Id: I65c9d30ae6ecb1f87e8660e56d8f8ce5daab7551 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://skia-review.googlesource.com/132403 Reviewed-by: Hal Canary <halcanary@google.com> Commit-Queue: Hal Canary <halcanary@google.com>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkBitmapDevice.cpp6
-rw-r--r--src/core/SkBitmapDevice.h2
-rw-r--r--src/core/SkCanvas.cpp21
-rw-r--r--src/core/SkDevice.cpp30
-rw-r--r--src/core/SkDevice.h12
-rw-r--r--src/core/SkDraw.cpp31
-rw-r--r--src/core/SkDraw.h2
-rw-r--r--src/core/SkGlyphCache.cpp7
-rw-r--r--src/core/SkGlyphCache.h3
-rw-r--r--src/core/SkGlyphRun.cpp236
-rw-r--r--src/core/SkGlyphRun.h72
-rw-r--r--src/core/SkThreadedBMPDevice.cpp10
-rw-r--r--src/core/SkThreadedBMPDevice.h3
13 files changed, 71 insertions, 364 deletions
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp
index cbd9a7cc40..71b85af268 100644
--- a/src/core/SkBitmapDevice.cpp
+++ b/src/core/SkBitmapDevice.cpp
@@ -565,6 +565,12 @@ void SkBitmapDevice::drawSprite(const SkBitmap& bitmap, int x, int y, const SkPa
BDDraw(this).drawSprite(bitmap, x, y, paint);
}
+void SkBitmapDevice::drawText(const void* text, size_t len,
+ SkScalar x, SkScalar y, const SkPaint& paint) {
+ SkBitmapDeviceFilteredSurfaceProps props(fBitmap, paint, fSurfaceProps);
+ LOOP_TILER( drawText((const char*)text, len, x, y, paint, &props()), nullptr)
+}
+
void SkBitmapDevice::drawPosText(const void* text, size_t len, const SkScalar xpos[],
int scalarsPerPos, const SkPoint& offset, const SkPaint& paint) {
SkBitmapDeviceFilteredSurfaceProps props(fBitmap, paint, fSurfaceProps);
diff --git a/src/core/SkBitmapDevice.h b/src/core/SkBitmapDevice.h
index ba7846ca43..c36bc28713 100644
--- a/src/core/SkBitmapDevice.h
+++ b/src/core/SkBitmapDevice.h
@@ -111,6 +111,8 @@ protected:
* Does not handle text decoration.
* Decorations (underline and stike-thru) will be handled by SkCanvas.
*/
+ void drawText(const void* text, size_t len, SkScalar x, SkScalar y,
+ const SkPaint&) override;
void drawPosText(const void* text, size_t len, const SkScalar pos[],
int scalarsPerPos, const SkPoint& offset, const SkPaint& paint) override;
void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) override;
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index dcff1b0cc3..8230fb3928 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -15,8 +15,6 @@
#include "SkDrawable.h"
#include "SkDrawFilter.h"
#include "SkDrawLooper.h"
-#include "SkGlyphCache.h"
-#include "SkGlyphRun.h"
#include "SkImage.h"
#include "SkImage_Base.h"
#include "SkImageFilter.h"
@@ -36,7 +34,6 @@
#include "SkRasterHandleAllocator.h"
#include "SkRRect.h"
#include "SkSpecialImage.h"
-#include "SkStrikeCache.h"
#include "SkString.h"
#include "SkSurface_Base.h"
#include "SkTextBlob.h"
@@ -1078,8 +1075,7 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra
const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() ||
(saveLayerFlags & kPreserveLCDText_SaveLayerFlag);
const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage;
- const bool trackCoverage =
- SkToBool(saveLayerFlags & kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag);
+ const bool trackCoverage = SkToBool(saveLayerFlags & kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag);
const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(info, usage, geo,
preserveLCDText,
trackCoverage,
@@ -2443,13 +2439,10 @@ void SkCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattic
void SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
const SkPaint& paint) {
-
LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr)
while (iter.next()) {
- auto glyphRun = SkGlyphRun::MakeFromDrawText(
- looper.paint(), text, byteLength, SkPoint::Make(x, y));
- iter.fDevice->drawGlyphRun(looper.paint(), &glyphRun);
+ iter.fDevice->drawText(text, byteLength, x, y, looper.paint());
}
LOOPER_END
@@ -2457,12 +2450,12 @@ void SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkSca
void SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
const SkPaint& paint) {
+ SkPoint textOffset = SkPoint::Make(0, 0);
LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr)
while (iter.next()) {
- auto glyphRun = SkGlyphRun::MakeFromDrawPosText(looper.paint(), text, byteLength, pos);
- iter.fDevice->drawGlyphRun(looper.paint(), &glyphRun);
+ iter.fDevice->drawPosText(text, byteLength, &pos->fX, 2, textOffset, looper.paint());
}
LOOPER_END
@@ -2471,12 +2464,12 @@ void SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint
void SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
SkScalar constY, const SkPaint& paint) {
+ SkPoint textOffset = SkPoint::Make(0, constY);
+
LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr)
while (iter.next()) {
- auto glyphRun =
- SkGlyphRun::MakeFromDrawPosTextH(looper.paint(), text, byteLength, xpos, constY);
- iter.fDevice->drawGlyphRun(looper.paint(), &glyphRun);
+ iter.fDevice->drawPosText(text, byteLength, xpos, 1, textOffset, looper.paint());
}
LOOPER_END
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 1bad6dba6e..35cfc9ab71 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -9,14 +9,12 @@
#include "SkColorFilter.h"
#include "SkDraw.h"
#include "SkDrawFilter.h"
-#include "SkGlyphRun.h"
#include "SkImageFilter.h"
#include "SkImageFilterCache.h"
#include "SkImagePriv.h"
#include "SkImage_Base.h"
#include "SkLatticeIter.h"
#include "SkLocalMatrixShader.h"
-#include "SkMakeUnique.h"
#include "SkMatrixPriv.h"
#include "SkPatchUtils.h"
#include "SkPathMeasure.h"
@@ -159,16 +157,9 @@ void SkBaseDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
}
switch (it.positioning()) {
- case SkTextBlob::kDefault_Positioning: {
- auto origin = SkPoint::Make(x + offset.x(), y + offset.y());
- auto glyphRun =
- SkGlyphRun::MakeFromDrawText(runPaint,
- (const char*) it.glyphs(), textLen, origin);
- this->drawPosText(
- it.glyphs(), textLen, glyphRun.getPositions(), 2,
- SkPoint::Make(0, 0), runPaint);
- }
- break;
+ case SkTextBlob::kDefault_Positioning:
+ this->drawText(it.glyphs(), textLen, x + offset.x(), y + offset.y(), runPaint);
+ break;
case SkTextBlob::kHorizontal_Positioning:
this->drawPosText(it.glyphs(), textLen, it.pos(), 1,
SkPoint::Make(x, y + offset.y()), runPaint);
@@ -252,17 +243,6 @@ void SkBaseDevice::drawImageLattice(const SkImage* image,
}
}
-void SkBaseDevice::drawGlyphRun(const SkPaint& paint, SkGlyphRun* info) {
- SkPaint glyphPaint(paint);
- glyphPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
-
- auto glyphs = info->copyGlyphIDs();
-
- this->drawPosText(
- glyphs.get(), info->runSize() * 2,
- info->getPositions(), 2, SkPoint::Make(0, 0), glyphPaint);
-}
-
void SkBaseDevice::drawBitmapLattice(const SkBitmap& bitmap,
const SkCanvas::Lattice& lattice, const SkRect& dst,
const SkPaint& paint) {
@@ -516,8 +496,6 @@ void SkBaseDevice::drawTextRSXform(const void* text, size_t len,
SkPaint localPaint(paint);
SkShader* shader = paint.getShader();
- SkScalar pos[2] = {0.0f, 0.0f};
- SkPoint origin = SkPoint::Make(0, 0);
SkMatrix localM, currM;
const void* stopText = (const char*)text + len;
@@ -539,7 +517,7 @@ void SkBaseDevice::drawTextRSXform(const void* text, size_t len,
}
int subLen = proc((const char*)text);
- this->drawPosText(text, subLen, pos, 2, origin, localPaint);
+ this->drawText(text, subLen, 0, 0, localPaint);
text = (const char*)text + subLen;
}
}
diff --git a/src/core/SkDevice.h b/src/core/SkDevice.h
index d36dc4d6ab..40b9589ce5 100644
--- a/src/core/SkDevice.h
+++ b/src/core/SkDevice.h
@@ -17,7 +17,6 @@
class SkBitmap;
class SkDrawFilter;
struct SkDrawShadowRec;
-class SkGlyphRun;
class SkImageFilterCache;
struct SkIRect;
class SkMatrix;
@@ -223,7 +222,11 @@ protected:
* Does not handle text decoration.
* Decorations (underline and stike-thru) will be handled by SkCanvas.
*/
- virtual void drawGlyphRun(const SkPaint& paint, SkGlyphRun* info);
+ virtual void drawText(const void* text, size_t len,
+ SkScalar x, SkScalar y, const SkPaint& paint) = 0;
+ virtual void drawPosText(const void* text, size_t len,
+ const SkScalar pos[], int scalarsPerPos,
+ const SkPoint& offset, const SkPaint& paint) = 0;
virtual void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) = 0;
virtual void drawShadow(const SkPath&, const SkDrawShadowRec&);
@@ -346,10 +349,6 @@ private:
friend class SkSurface_Raster;
friend class DeviceTestingAccess;
- virtual void drawPosText(const void* text, size_t len,
- const SkScalar pos[], int scalarsPerPos,
- const SkPoint& offset, const SkPaint& paint) = 0;
-
// used to change the backend's pixels (and possibly config/rowbytes)
// but cannot change the width/height, so there should be no change to
// any clip information.
@@ -428,6 +427,7 @@ protected:
void drawSprite(const SkBitmap&, int, int, const SkPaint&) override {}
void drawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint&,
SkCanvas::SrcRectConstraint) override {}
+ void drawText(const void*, size_t, SkScalar, SkScalar, const SkPaint&) override {}
void drawPosText(const void*, size_t, const SkScalar[], int, const SkPoint&,
const SkPaint&) override {}
void drawDevice(SkBaseDevice*, int, int, const SkPaint&) override {}
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index e975ea2a4b..b7150f85f8 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -1537,6 +1537,37 @@ SkScalerContextFlags SkDraw::scalerContextFlags() const {
return flags;
}
+void SkDraw::drawText(const char text[], size_t byteLength, SkScalar x, SkScalar y,
+ const SkPaint& paint, const SkSurfaceProps* props) const {
+ SkASSERT(byteLength == 0 || text != nullptr);
+
+ SkDEBUGCODE(this->validate();)
+
+ // nothing to draw
+ if (text == nullptr || byteLength == 0 || fRC->isEmpty()) {
+ return;
+ }
+
+ // SkScalarRec doesn't currently have a way of representing hairline stroke and
+ // will fill if its frame-width is 0.
+ if (ShouldDrawTextAsPaths(paint, *fMatrix)) {
+ this->drawText_asPaths(text, byteLength, x, y, paint);
+ return;
+ }
+
+ auto cache = SkStrikeCache::FindOrCreateStrikeExclusive(
+ paint, props, this->scalerContextFlags(), fMatrix);
+
+ // 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.get(), wrapper.getBlitter());
+
+ SkFindAndPlaceGlyph::ProcessText(
+ paint.getTextEncoding(), text, byteLength,
+ {x, y}, *fMatrix, paint.getTextAlign(), cache.get(), drawOneGlyph);
+}
+
//////////////////////////////////////////////////////////////////////////////
void SkDraw::drawPosText_asPaths(const char text[], size_t byteLength, const SkScalar pos[],
diff --git a/src/core/SkDraw.h b/src/core/SkDraw.h
index 266960eedd..eabccf0d8d 100644
--- a/src/core/SkDraw.h
+++ b/src/core/SkDraw.h
@@ -62,6 +62,8 @@ public:
void drawBitmap(const SkBitmap&, const SkMatrix&, const SkRect* dstOrNull,
const SkPaint&) const;
void drawSprite(const SkBitmap&, int x, int y, const SkPaint&) const;
+ void drawText(const char text[], size_t byteLength, SkScalar x,
+ SkScalar y, const SkPaint& paint, const SkSurfaceProps*) const;
void drawPosText(const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition,
const SkPoint& offset, const SkPaint&, const SkSurfaceProps*) const;
diff --git a/src/core/SkGlyphCache.cpp b/src/core/SkGlyphCache.cpp
index 3734b96ee2..bf5f77c817 100644
--- a/src/core/SkGlyphCache.cpp
+++ b/src/core/SkGlyphCache.cpp
@@ -130,13 +130,6 @@ const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID, SkFixed x, SkFi
return *this->lookupByPackedGlyphID(packedGlyphID, kFull_MetricsType);
}
-void SkGlyphCache::getAdvances(SkSpan<SkGlyphID> glyphIDs, SkPoint advances[]) {
- for (ptrdiff_t i = 0; i < glyphIDs.size(); i++) {
- auto glyph = this->getGlyphIDAdvance(glyphIDs[i]);
- advances[i] = SkPoint::Make(glyph.fAdvanceX, glyph.fAdvanceY);
- }
-}
-
SkGlyph* SkGlyphCache::lookupByChar(SkUnichar charCode, MetricsType type, SkFixed x, SkFixed y) {
SkPackedUnicharID id(charCode, x, y);
CharGlyphRec* rec = this->getCharGlyphRec(id);
diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h
index e904c6e5c7..2e7355779a 100644
--- a/src/core/SkGlyphCache.h
+++ b/src/core/SkGlyphCache.h
@@ -10,7 +10,6 @@
#include "SkArenaAlloc.h"
#include "SkDescriptor.h"
#include "SkGlyph.h"
-#include "SkGlyphRun.h"
#include "SkPaint.h"
#include "SkTHash.h"
#include "SkScalerContext.h"
@@ -68,8 +67,6 @@ public:
const SkGlyph& getUnicharMetrics(SkUnichar, SkFixed x, SkFixed y);
const SkGlyph& getGlyphIDMetrics(uint16_t, SkFixed x, SkFixed y);
- void getAdvances(SkSpan<SkGlyphID>, SkPoint[]);
-
/** Return the glyphID for the specified Unichar. If the char has already been seen, use the
existing cache entry. If not, ask the scalercontext to compute it for us.
*/
diff --git a/src/core/SkGlyphRun.cpp b/src/core/SkGlyphRun.cpp
deleted file mode 100644
index a25b9afa8e..0000000000
--- a/src/core/SkGlyphRun.cpp
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkGlyphRun.h"
-
-#include <algorithm>
-#include <tuple>
-
-#include "SkDraw.h"
-#include "SkGlyphCache.h"
-#include "SkMakeUnique.h"
-#include "SkMSAN.h"
-#include "SkPaint.h"
-#include "SkPaintPriv.h"
-#include "SkStrikeCache.h"
-#include "SkUtils.h"
-
-namespace {
-
-// A faster set implementation that does not need any initialization, and reading the set items
-// is order the number of items, and not the size of the universe.
-// This implementation is based on the paper by Briggs and Torczon, "An Efficient Representation
-// for Sparse Sets"
-class GlyphSet {
-public:
- GlyphSet(uint32_t glyphUniverseSize)
- : fUniverseSize{glyphUniverseSize}
- , fIndexes{skstd::make_unique_default<uint16_t[]>(2 * glyphUniverseSize)}
- , fUniqueGlyphIDs{&fIndexes[glyphUniverseSize]} {
- SkASSERT(glyphUniverseSize <= (1 << 16));
- sk_msan_mark_initialized(fIndexes.get(), &fIndexes[glyphUniverseSize], "works with uninited");
- }
-
- uint16_t add(SkGlyphID glyphID) {
- if (glyphID >= fUniverseSize) {
- glyphID = kUndefGlyph;
- }
- auto index = fIndexes[glyphID];
- if (index < fUniqueCount && fUniqueGlyphIDs[index] == glyphID) {
- return index;
- }
-
- fUniqueGlyphIDs[fUniqueCount] = glyphID;
- fIndexes[glyphID] = fUniqueCount;
- fUniqueCount += 1;
- return fUniqueCount - 1;
- }
-
- std::tuple<uint16_t, std::unique_ptr<SkGlyphID[]>> uniqueGlyphIDs() const {
- auto uniqueGlyphs = skstd::make_unique_default<SkGlyphID[]>(fUniqueCount);
- memcpy(uniqueGlyphs.get(), fUniqueGlyphIDs, fUniqueCount * sizeof(SkGlyphID));
- return std::make_tuple(fUniqueCount, std::move(uniqueGlyphs));
- }
-
-private:
- static constexpr SkGlyphID kUndefGlyph{0};
- const uint32_t fUniverseSize;
- uint16_t fUniqueCount{0};
- std::unique_ptr<uint16_t[]> fIndexes;
- SkGlyphID* fUniqueGlyphIDs;
- };
-
-template<typename T>
-bool is_aligned(const void* ptr) {
- uintptr_t bits = reinterpret_cast<uintptr_t>(ptr);
- return (bits & (alignof(T) - 1)) == 0;
-}
-
-template<typename T>
-bool is_aligned_size(size_t size) {
- return size % sizeof(T) == 0;
-}
-
-SkTypeface::Encoding convert_encoding(SkPaint::TextEncoding encoding) {
- switch (encoding) {
- case SkPaint::kUTF8_TextEncoding: return SkTypeface::kUTF8_Encoding;
- case SkPaint::kUTF16_TextEncoding: return SkTypeface::kUTF16_Encoding;
- case SkPaint::kUTF32_TextEncoding: return SkTypeface::kUTF32_Encoding;
- default: return SkTypeface::kUTF32_Encoding;
- }
-}
-
-using Core = std::tuple<size_t, std::unique_ptr<uint16_t[]>,
- uint16_t, std::unique_ptr<SkGlyphID[]>>;
-
-Core make_from_glyphids(size_t glyphCount, const SkGlyphID* glyphs, SkGlyphID maxGlyphID) {
- if (glyphCount == 0) { return Core(0, nullptr, 0, nullptr); }
-
- GlyphSet glyphSet{maxGlyphID};
-
- auto denseIndex = skstd::make_unique_default<uint16_t[]>(glyphCount);
- for (size_t i = 0; i < glyphCount; i++) {
- denseIndex[i] = glyphSet.add(glyphs[i]);
- }
-
- std::unique_ptr<SkGlyphID[]> uniqueGlyphIDs;
- uint16_t uniqueCount;
- std::tie(uniqueCount, uniqueGlyphIDs) = glyphSet.uniqueGlyphIDs();
-
- return Core(glyphCount, std::move(denseIndex), uniqueCount, std::move(uniqueGlyphIDs));
-}
-
-Core make_from_utfn(size_t byteLength, const void* utfN, const SkTypeface& typeface,
- SkTypeface::Encoding encoding) {
- auto count = SkUTFN_CountUnichars(encoding, utfN, byteLength);
-
- if (count <= 0) {
- return Core(0, nullptr, 0, nullptr);
- }
-
- auto glyphs = skstd::make_unique_default<SkGlyphID[]>(count);
-
- // TODO: move to using cached version.
- typeface.charsToGlyphs(utfN, encoding, glyphs.get(), count);
-
- return make_from_glyphids(count, glyphs.get(), typeface.countGlyphs());
-}
-
-Core make_core(const SkPaint& paint, const void* bytes, size_t byteLength) {
- auto encoding = paint.getTextEncoding();
- auto typeface = SkPaintPriv::GetTypefaceOrDefault(paint);
- if (encoding == SkPaint::kGlyphID_TextEncoding) {
- return make_from_glyphids(
- byteLength / 2, reinterpret_cast<const SkGlyphID*>(bytes), typeface->countGlyphs());
- } else {
- return make_from_utfn(byteLength, bytes, *typeface, convert_encoding(encoding));
- }
-}
-
-} // namespace
-
-SkGlyphRun SkGlyphRun::MakeFromDrawText(
- const SkPaint& paint, const void* bytes, size_t byteLength,
- const SkPoint origin) {
- size_t runSize;
- std::unique_ptr<uint16_t[]> denseIndex;
- uint16_t uniqueSize;
- std::unique_ptr<SkGlyphID[]> uniqueGlyphIDs;
- std::tie(runSize, denseIndex, uniqueSize, uniqueGlyphIDs) = make_core(paint, bytes, byteLength);
-
- if (runSize == 0) { return SkGlyphRun{}; }
-
- auto advances = skstd::make_unique_default<SkPoint[]>(uniqueSize);
-
- {
- auto cache = SkStrikeCache::FindOrCreateStrikeExclusive(paint);
- cache->getAdvances(SkSpan<SkGlyphID>{uniqueGlyphIDs.get(), uniqueSize}, advances.get());
- }
-
- auto positions = skstd::make_unique_default<SkPoint[]>(runSize);
-
- SkPoint endOfLastGlyph = origin;
-
- for (size_t i = 0; i < runSize; i++) {
- positions[i] = endOfLastGlyph;
- endOfLastGlyph += advances[denseIndex[i]];
- }
-
- if (paint.getTextAlign() != SkPaint::kLeft_Align) {
- SkVector len = endOfLastGlyph - origin;
- if (paint.getTextAlign() == SkPaint::kCenter_Align) {
- len.scale(SK_ScalarHalf);
- }
- for (size_t i = 0; i < runSize; i++) {
- positions[i] -= len;
- }
- }
-
- return SkGlyphRun{
- runSize, std::move(denseIndex), std::move(positions), uniqueSize, std::move(uniqueGlyphIDs)};
-}
-
-SkGlyphRun SkGlyphRun::MakeFromDrawPosTextH(
- const SkPaint& paint, const void* bytes, size_t byteLength,
- const SkScalar xpos[], SkScalar constY) {
- size_t runSize;
- std::unique_ptr<uint16_t[]> denseIndex;
- uint16_t uniqueSize;
- std::unique_ptr<SkGlyphID[]> uniqueGlyphIDs;
- std::tie(runSize, denseIndex, uniqueSize, uniqueGlyphIDs) = make_core(paint, bytes, byteLength);
-
- if (runSize == 0) { return SkGlyphRun{}; }
-
- auto positions = skstd::make_unique_default<SkPoint[]>(runSize);
-
- for (size_t i = 0; i < runSize; i++) {
- positions[i] = SkPoint::Make(xpos[i], constY);
- }
-
- return SkGlyphRun{
- runSize, std::move(denseIndex), std::move(positions), uniqueSize, std::move(uniqueGlyphIDs)};
-}
-
-SkGlyphRun SkGlyphRun::MakeFromDrawPosText(
- const SkPaint& paint, const void* bytes, size_t byteLength,
- const SkPoint pos[]) {
- size_t runSize;
- std::unique_ptr<uint16_t[]> denseIndex;
- uint16_t uniqueSize;
- std::unique_ptr<SkGlyphID[]> uniqueGlyphIDs;
- std::tie(runSize, denseIndex, uniqueSize, uniqueGlyphIDs) = make_core(paint, bytes, byteLength);
-
- if (runSize == 0) { return SkGlyphRun{}; }
-
- auto positions = skstd::make_unique_default<SkPoint[]>(runSize);
-
- memcpy(positions.get(), pos, sizeof(SkPoint) * runSize);
-
- return SkGlyphRun{
- runSize, std::move(denseIndex), std::move(positions), uniqueSize, std::move(uniqueGlyphIDs)};
-}
-
-std::unique_ptr<SkGlyphID[]> SkGlyphRun::copyGlyphIDs() const {
- auto glyphs = skstd::make_unique_default<SkGlyphID[]>(fRunSize);
-
- for (size_t i = 0; i < fRunSize; i++) {
- glyphs[i] = fUniqueGlyphs[fDenseIndex[i]];
- }
-
- return glyphs;
-}
-
-SkGlyphRun::SkGlyphRun(size_t runSize,
- std::unique_ptr<uint16_t[]>&& denseIndex,
- std::unique_ptr<SkPoint[]>&& positions,
- uint16_t uniqueSize,
- std::unique_ptr<SkGlyphID[]>&& uniqueGlyphIDs)
- : fDenseIndex{std::move(denseIndex)}
- , fPositions{std::move(positions)}
- , fUniqueGlyphs{std::move(uniqueGlyphIDs)}
- , fRunSize{runSize}
- , fUniqueSize{uniqueSize} { }
diff --git a/src/core/SkGlyphRun.h b/src/core/SkGlyphRun.h
deleted file mode 100644
index 17b4297208..0000000000
--- a/src/core/SkGlyphRun.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkGlyphRunInfo_DEFINED
-#define SkGlyphRunInfo_DEFINED
-
-#include <memory>
-#include <vector>
-
-#include "SkDescriptor.h"
-#include "SkMask.h"
-#include "SkPath.h"
-#include "SkPoint.h"
-#include "SkTypes.h"
-
-class SkGlyphRun {
-public:
- SkGlyphRun() = default;
- SkGlyphRun(SkGlyphRun&&) = default;
- static SkGlyphRun MakeFromDrawText(
- const SkPaint& paint, const void* bytes, size_t byteLength,
- SkPoint origin);
- static SkGlyphRun MakeFromDrawPosTextH(
- const SkPaint& paint, const void* bytes, size_t byteLength,
- const SkScalar xpos[], SkScalar constY);
- static SkGlyphRun MakeFromDrawPosText(
- const SkPaint& paint, const void* bytes, size_t byteLength,
- const SkPoint pos[]);
-
- size_t runSize() const { return fRunSize; }
- uint16_t uniqueSize() const { return fUniqueSize; }
-
- // copyGlyphIDs is temporary glue to work with the existing system. Don't use with new code.
- std::unique_ptr<SkGlyphID[]> copyGlyphIDs() const;
- const SkScalar* getPositions() const {
- return reinterpret_cast<const SkScalar*>(fPositions.get());
- }
-
-private:
- SkGlyphRun(size_t runSize,
- std::unique_ptr<uint16_t[]>&& denseIndex,
- std::unique_ptr<SkPoint[]>&& positions,
- uint16_t uniqueSize,
- std::unique_ptr<SkGlyphID[]>&& uniqueGlyphIDs);
-
- std::unique_ptr<uint16_t[]> fDenseIndex;
- std::unique_ptr<SkPoint[]> fPositions;
- std::unique_ptr<SkGlyphID[]> fUniqueGlyphs;
- const size_t fRunSize{0};
- const uint16_t fUniqueSize{0};
-};
-
-template <typename T>
-class SkSpan {
-public:
- SkSpan(const T* ptr, size_t size) : fPtr{ptr}, fSize{size} {}
- SkSpan(const std::vector<T>& v) : fPtr{v.data()}, fSize{v.size()} {}
- const T& operator [] (ptrdiff_t i) const { return fPtr[i]; }
- const T* begin() const { return fPtr; }
- const T* end() const { return fPtr + fSize; }
- ptrdiff_t size() const { return fSize; }
-
-private:
- const T* fPtr;
- size_t fSize;
-};
-
-#endif // SkGlyphRunInfo_DEFINED
diff --git a/src/core/SkThreadedBMPDevice.cpp b/src/core/SkThreadedBMPDevice.cpp
index 10cd824205..b75e90d5e4 100644
--- a/src/core/SkThreadedBMPDevice.cpp
+++ b/src/core/SkThreadedBMPDevice.cpp
@@ -210,6 +210,16 @@ void SkThreadedBMPDevice::drawSprite(const SkBitmap& bitmap, int x, int y, const
});
}
+void SkThreadedBMPDevice::drawText(const void* text, size_t len, SkScalar x, SkScalar y,
+ const SkPaint& paint) {
+ char* clonedText = this->cloneArray((const char*)text, len);
+ SkRect drawBounds = SkRectPriv::MakeLargest(); // TODO tighter drawBounds
+ SkSurfaceProps prop(SkBitmapDeviceFilteredSurfaceProps(fBitmap, paint, this->surfaceProps())());
+ fQueue.push(drawBounds, [=](SkArenaAlloc*, const DrawState& ds, const SkIRect& tileBounds){
+ TileDraw(ds, tileBounds).drawText(clonedText, len, x, y, paint, &prop);
+ });
+}
+
void SkThreadedBMPDevice::drawPosText(const void* text, size_t len, const SkScalar xpos[],
int scalarsPerPos, const SkPoint& offset, const SkPaint& paint) {
char* clonedText = this->cloneArray((const char*)text, len);
diff --git a/src/core/SkThreadedBMPDevice.h b/src/core/SkThreadedBMPDevice.h
index 6defce5d8c..d9e27b449c 100644
--- a/src/core/SkThreadedBMPDevice.h
+++ b/src/core/SkThreadedBMPDevice.h
@@ -32,6 +32,9 @@ protected:
void drawPath(const SkPath&, const SkPaint&, const SkMatrix* prePathMatrix,
bool pathIsMutable) override;
void drawSprite(const SkBitmap&, int x, int y, const SkPaint&) override;
+
+ void drawText(const void* text, size_t len, SkScalar x, SkScalar y,
+ const SkPaint&) override;
void drawPosText(const void* text, size_t len, const SkScalar pos[],
int scalarsPerPos, const SkPoint& offset, const SkPaint& paint) override;
void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) override;