diff options
author | Hal Canary <halcanary@google.com> | 2018-06-06 13:29:51 +0000 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-06-06 13:29:57 +0000 |
commit | 74b390d6b136a60f1df15ac5ecd19bd8ad5a394b (patch) | |
tree | afba5f9d8d8d802e9b6873c5f4c7948a94f76762 /src/core | |
parent | 102c8cf26e2886ba783a2b54827e1f5d1cf0a774 (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.cpp | 6 | ||||
-rw-r--r-- | src/core/SkBitmapDevice.h | 2 | ||||
-rw-r--r-- | src/core/SkCanvas.cpp | 21 | ||||
-rw-r--r-- | src/core/SkDevice.cpp | 30 | ||||
-rw-r--r-- | src/core/SkDevice.h | 12 | ||||
-rw-r--r-- | src/core/SkDraw.cpp | 31 | ||||
-rw-r--r-- | src/core/SkDraw.h | 2 | ||||
-rw-r--r-- | src/core/SkGlyphCache.cpp | 7 | ||||
-rw-r--r-- | src/core/SkGlyphCache.h | 3 | ||||
-rw-r--r-- | src/core/SkGlyphRun.cpp | 236 | ||||
-rw-r--r-- | src/core/SkGlyphRun.h | 72 | ||||
-rw-r--r-- | src/core/SkThreadedBMPDevice.cpp | 10 | ||||
-rw-r--r-- | src/core/SkThreadedBMPDevice.h | 3 |
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; |