aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkFindAndPlaceGlyph.h
diff options
context:
space:
mode:
authorGravatar Herb Derby <herb@google.com>2017-06-22 10:58:16 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-06-22 15:27:10 +0000
commiteb64b9b201d04f9f72b37a05e86d459e6a91d974 (patch)
tree67adcfac4ce6526d1209f27c413957d513d5a378 /src/core/SkFindAndPlaceGlyph.h
parent2e5eaf022e9389b1382cc856fcd7a8e90a078e13 (diff)
Replace variant system with arena
Bug: skia:6764 Change-Id: I9327b953efeedd73e7985904d17b971939468e40 Reviewed-on: https://skia-review.googlesource.com/20500 Commit-Queue: Herb Derby <herb@google.com> Reviewed-by: Mike Klein <mtklein@google.com>
Diffstat (limited to 'src/core/SkFindAndPlaceGlyph.h')
-rw-r--r--src/core/SkFindAndPlaceGlyph.h379
1 files changed, 126 insertions, 253 deletions
diff --git a/src/core/SkFindAndPlaceGlyph.h b/src/core/SkFindAndPlaceGlyph.h
index c17dccbe3e..5d7c46bf27 100644
--- a/src/core/SkFindAndPlaceGlyph.h
+++ b/src/core/SkFindAndPlaceGlyph.h
@@ -8,6 +8,7 @@
#ifndef SkFindAndPositionGlyph_DEFINED
#define SkFindAndPositionGlyph_DEFINED
+#include "SkArenaAlloc.h"
#include "SkAutoKern.h"
#include "SkGlyph.h"
#include "SkGlyphCache.h"
@@ -16,31 +17,6 @@
#include "SkUtils.h"
#include <utility>
-// Calculate a type with the same size as the max of all the Ts.
-// This must be top level because the is no specialization of inner classes.
-template<typename... Ts> struct SkMaxSizeOf;
-
-template<>
-struct SkMaxSizeOf<> {
- static const size_t value = 0;
-};
-
-template<typename H, typename... Ts>
-struct SkMaxSizeOf<H, Ts...> {
- static const size_t value =
- sizeof(H) >= SkMaxSizeOf<Ts...>::value ? sizeof(H) : SkMaxSizeOf<Ts...>::value;
-};
-
-
-// This is a temporary helper function to work around a bug in the code generation
-// for aarch64 (arm) on GCC 4.9. This bug does not show up on other platforms, so it
-// seems to be an aarch64 backend problem.
-//
-// GCC 4.9 on ARM64 does not generate the proper constructor code for PositionReader or
-// GlyphFindAndPlace. The vtable is not set properly without adding the fixme code.
-// The implementation is in SkDraw.cpp.
-extern void FixGCC49Arm64Bug(int v);
-
class SkFindAndPlaceGlyph {
public:
template<typename ProcessOneGlyph>
@@ -72,53 +48,6 @@ public:
SkGlyphCache* cache, ProcessOneGlyph&& processOneGlyph);
private:
- // UntaggedVariant is a pile of memory that can hold one of the Ts. It provides a way
- // to initialize that memory in a typesafe way.
- template<typename... Ts>
- class UntaggedVariant {
- public:
- UntaggedVariant() { }
-
- ~UntaggedVariant() { }
- UntaggedVariant(const UntaggedVariant&) = delete;
- UntaggedVariant& operator=(const UntaggedVariant&) = delete;
- UntaggedVariant(UntaggedVariant&&) = delete;
- UntaggedVariant& operator=(UntaggedVariant&&) = delete;
-
- template<typename Variant, typename... Args>
- void initialize(Args&&... args) {
- SkASSERT(sizeof(Variant) <= sizeof(fSpace));
- #if defined(_MSC_VER) && _MSC_VER < 1900
- #define alignof __alignof
- #endif
- SkASSERT(alignof(Variant) <= alignof(Space));
- new(&fSpace) Variant(std::forward<Args>(args)...);
- }
-
- private:
- typedef SkAlignedSStorage<SkMaxSizeOf<Ts...>::value> Space;
- Space fSpace;
- };
-
- // PolymorphicVariant holds subclasses of Base without slicing. Ts must be subclasses of Base.
- template<typename Base, typename... Ts>
- class PolymorphicVariant {
- public:
- typedef UntaggedVariant<Ts...> Variants;
-
- template<typename Initializer>
- PolymorphicVariant(Initializer&& initializer) {
- initializer(&fVariants);
- }
- ~PolymorphicVariant() { get()->~Base(); }
- Base* get() const { return reinterpret_cast<Base*>(&fVariants); }
- Base* operator->() const { return get(); }
- Base& operator*() const { return *get(); }
-
- private:
- mutable Variants fVariants;
- };
-
// GlyphFinderInterface is the polymorphic base for classes that parse a stream of chars into
// the right UniChar (or GlyphID) and lookup up the glyph on the cache. The concrete
// implementations are: Utf8GlyphFinder, Utf16GlyphFinder, Utf32GlyphFinder,
@@ -132,7 +61,10 @@ private:
class UtfNGlyphFinder : public GlyphFinderInterface {
public:
- UtfNGlyphFinder(SkGlyphCache* cache) : fCache(cache) { SkASSERT(cache != nullptr); }
+ explicit UtfNGlyphFinder(SkGlyphCache* cache)
+ : fCache(cache) {
+ SkASSERT(cache != nullptr);
+ }
const SkGlyph& lookupGlyph(const char** text) override {
SkASSERT(text != nullptr);
@@ -150,7 +82,7 @@ private:
class Utf8GlyphFinder final : public UtfNGlyphFinder {
public:
- Utf8GlyphFinder(SkGlyphCache* cache) : UtfNGlyphFinder(cache) { }
+ explicit Utf8GlyphFinder(SkGlyphCache* cache) : UtfNGlyphFinder(cache) { }
private:
SkUnichar nextUnichar(const char** text) override { return SkUTF8_NextUnichar(text); }
@@ -158,7 +90,7 @@ private:
class Utf16GlyphFinder final : public UtfNGlyphFinder {
public:
- Utf16GlyphFinder(SkGlyphCache* cache) : UtfNGlyphFinder(cache) { }
+ explicit Utf16GlyphFinder(SkGlyphCache* cache) : UtfNGlyphFinder(cache) { }
private:
SkUnichar nextUnichar(const char** text) override {
@@ -168,7 +100,7 @@ private:
class Utf32GlyphFinder final : public UtfNGlyphFinder {
public:
- Utf32GlyphFinder(SkGlyphCache* cache) : UtfNGlyphFinder(cache) { }
+ explicit Utf32GlyphFinder(SkGlyphCache* cache) : UtfNGlyphFinder(cache) { }
private:
SkUnichar nextUnichar(const char** text) override {
@@ -181,7 +113,10 @@ private:
class GlyphIdGlyphFinder final : public GlyphFinderInterface {
public:
- GlyphIdGlyphFinder(SkGlyphCache* cache) : fCache(cache) { SkASSERT(cache != nullptr); }
+ explicit GlyphIdGlyphFinder(SkGlyphCache* cache)
+ : fCache(cache) {
+ SkASSERT(cache != nullptr);
+ }
const SkGlyph& lookupGlyph(const char** text) override {
return fCache->getGlyphIDMetrics(nextGlyphId(text));
@@ -203,35 +138,21 @@ private:
SkGlyphCache* fCache;
};
- typedef PolymorphicVariant<
- GlyphFinderInterface,
- Utf8GlyphFinder,
- Utf16GlyphFinder,
- Utf32GlyphFinder,
- GlyphIdGlyphFinder> LookupGlyphVariant;
-
- class LookupGlyph : public LookupGlyphVariant {
- public:
- LookupGlyph(SkPaint::TextEncoding encoding, SkGlyphCache* cache)
- : LookupGlyphVariant(
- [&](LookupGlyphVariant::Variants* to_init) {
- switch(encoding) {
- case SkPaint::kUTF8_TextEncoding:
- to_init->initialize<Utf8GlyphFinder>(cache);
- break;
- case SkPaint::kUTF16_TextEncoding:
- to_init->initialize<Utf16GlyphFinder>(cache);
- break;
- case SkPaint::kUTF32_TextEncoding:
- to_init->initialize<Utf32GlyphFinder>(cache);
- break;
- case SkPaint::kGlyphID_TextEncoding:
- to_init->initialize<GlyphIdGlyphFinder>(cache);
- break;
- }
- }
- ) { }
- };
+ static GlyphFinderInterface* getGlyphFinder(
+ SkArenaAlloc* arena, SkPaint::TextEncoding encoding, SkGlyphCache* cache) {
+ switch(encoding) {
+ case SkPaint::kUTF8_TextEncoding:
+ return arena->make<Utf8GlyphFinder>(cache);
+ case SkPaint::kUTF16_TextEncoding:
+ return arena->make<Utf16GlyphFinder>(cache);
+ case SkPaint::kUTF32_TextEncoding:
+ return arena->make<Utf32GlyphFinder>(cache);
+ case SkPaint::kGlyphID_TextEncoding:
+ return arena->make<GlyphIdGlyphFinder>(cache);
+ }
+ SkFAIL("Should not get here.");
+ return nullptr;
+ }
// PositionReaderInterface reads a point from the pos vector.
// * HorizontalPositions - assumes a common Y for many X values.
@@ -240,9 +161,6 @@ private:
public:
virtual ~PositionReaderInterface() { }
virtual SkPoint nextPoint() = 0;
- // This is only here to fix a GCC 4.9 aarch64 code gen bug.
- // See comment at the top of the file.
- virtual int forceUseForBug() = 0;
};
class HorizontalPositions final : public PositionReaderInterface {
@@ -255,8 +173,6 @@ private:
return {x, 0};
}
- int forceUseForBug() override { return 1; }
-
private:
const SkScalar* fPositions;
};
@@ -272,15 +188,10 @@ private:
return to_return;
}
- int forceUseForBug() override { return 2; }
-
private:
const SkScalar* fPositions;
};
- typedef PolymorphicVariant<PositionReaderInterface, HorizontalPositions, ArbitraryPositions>
- PositionReader;
-
// MapperInterface given a point map it through the matrix. There are several shortcut
// variants.
// * TranslationMapper - assumes a translation only matrix.
@@ -338,9 +249,6 @@ private:
const SkMatrix::MapXYProc fMapProc;
};
- typedef PolymorphicVariant<
- MapperInterface, TranslationMapper, XScaleMapper, GeneralMapper> Mapper;
-
// TextAlignmentAdjustment handles shifting the glyph based on its width.
static SkPoint TextAlignmentAdjustment(SkPaint::Align textAlignment, const SkGlyph& glyph) {
switch (textAlignment) {
@@ -429,10 +337,8 @@ private:
SkAxisAlignment kAxisAlignment>
class GlyphFindAndPlaceSubpixel final : public GlyphFindAndPlaceInterface<ProcessOneGlyph> {
public:
- GlyphFindAndPlaceSubpixel(LookupGlyph& glyphFinder)
- : fGlyphFinder(glyphFinder) {
- FixGCC49Arm64Bug(1);
- }
+ explicit GlyphFindAndPlaceSubpixel(GlyphFinderInterface* glyphFinder)
+ : fGlyphFinder(glyphFinder) { }
SkPoint findAndPositionGlyph(
const char** text, SkPoint position, ProcessOneGlyph&& processOneGlyph) override {
@@ -472,7 +378,7 @@ private:
}
private:
- LookupGlyph& fGlyphFinder;
+ GlyphFinderInterface* fGlyphFinder;
};
enum SelectKerning {
@@ -486,9 +392,8 @@ private:
template<typename ProcessOneGlyph, SkPaint::Align kTextAlignment, SelectKerning kUseKerning>
class GlyphFindAndPlaceFullPixel final : public GlyphFindAndPlaceInterface<ProcessOneGlyph> {
public:
- GlyphFindAndPlaceFullPixel(LookupGlyph& glyphFinder)
+ explicit GlyphFindAndPlaceFullPixel(GlyphFinderInterface* glyphFinder)
: fGlyphFinder(glyphFinder) {
- FixGCC49Arm64Bug(2);
// Kerning can only be used with SkPaint::kLeft_Align
static_assert(!kUseKerning || SkPaint::kLeft_Align == kTextAlignment,
"Kerning can only be used with left aligned text.");
@@ -510,62 +415,32 @@ private:
}
private:
- LookupGlyph& fGlyphFinder;
+ GlyphFinderInterface* fGlyphFinder;
SkAutoKern fAutoKern;
};
- // GlyphFindAndPlace is a large variant that encapsulates the multiple types of finding and
- // placing a glyph. There are three factors that go into the different factors.
- // * Is sub-pixel positioned - a boolean that says whether to use sub-pixel positioning.
- // * Text alignment - indicates if the glyph should be placed to the right, centered or left
- // of a given position.
- // * Axis alignment - indicates if the glyphs final sub-pixel position should be rounded to a
- // whole pixel if the glyph is aligned with an axis. This is only used for sub-pixel
- // positioning and allows the baseline to look crisp.
- template<typename ProcessOneGlyph>
- using GlyphFindAndPlace = PolymorphicVariant<
- GlyphFindAndPlaceInterface<ProcessOneGlyph>,
- // Subpixel
- GlyphFindAndPlaceSubpixel<ProcessOneGlyph, SkPaint::kLeft_Align, kNone_SkAxisAlignment>,
- GlyphFindAndPlaceSubpixel<ProcessOneGlyph, SkPaint::kLeft_Align, kX_SkAxisAlignment >,
- GlyphFindAndPlaceSubpixel<ProcessOneGlyph, SkPaint::kLeft_Align, kY_SkAxisAlignment >,
- GlyphFindAndPlaceSubpixel<ProcessOneGlyph, SkPaint::kCenter_Align, kNone_SkAxisAlignment>,
- GlyphFindAndPlaceSubpixel<ProcessOneGlyph, SkPaint::kCenter_Align, kX_SkAxisAlignment >,
- GlyphFindAndPlaceSubpixel<ProcessOneGlyph, SkPaint::kCenter_Align, kY_SkAxisAlignment >,
- GlyphFindAndPlaceSubpixel<ProcessOneGlyph, SkPaint::kRight_Align, kNone_SkAxisAlignment>,
- GlyphFindAndPlaceSubpixel<ProcessOneGlyph, SkPaint::kRight_Align, kX_SkAxisAlignment >,
- GlyphFindAndPlaceSubpixel<ProcessOneGlyph, SkPaint::kRight_Align, kY_SkAxisAlignment >,
- // Full pixel
- GlyphFindAndPlaceFullPixel<ProcessOneGlyph, SkPaint::kLeft_Align, kNoKerning>,
- GlyphFindAndPlaceFullPixel<ProcessOneGlyph, SkPaint::kCenter_Align, kNoKerning>,
- GlyphFindAndPlaceFullPixel<ProcessOneGlyph, SkPaint::kRight_Align, kNoKerning>
- >;
-
- // InitSubpixel is a helper function for initializing all the variants of
- // GlyphFindAndPlaceSubpixel.
- template<typename ProcessOneGlyph, SkPaint::Align kTextAlignment>
- static void InitSubpixel(
- typename GlyphFindAndPlace<ProcessOneGlyph>::Variants* to_init,
- SkAxisAlignment axisAlignment,
- LookupGlyph& glyphFinder) {
+ template <typename ProcessOneGlyph, SkPaint::Align kTextAlignment>
+ static GlyphFindAndPlaceInterface<ProcessOneGlyph>* getSubpixel(
+ SkArenaAlloc* arena, SkAxisAlignment axisAlignment, GlyphFinderInterface* glyphFinder)
+ {
switch (axisAlignment) {
case kX_SkAxisAlignment:
- to_init->template initialize<GlyphFindAndPlaceSubpixel<
+ return arena->make<GlyphFindAndPlaceSubpixel<
ProcessOneGlyph, kTextAlignment, kX_SkAxisAlignment>>(glyphFinder);
- break;
case kNone_SkAxisAlignment:
- to_init->template initialize<GlyphFindAndPlaceSubpixel<
+ return arena->make<GlyphFindAndPlaceSubpixel<
ProcessOneGlyph, kTextAlignment, kNone_SkAxisAlignment>>(glyphFinder);
- break;
case kY_SkAxisAlignment:
- to_init->template initialize<GlyphFindAndPlaceSubpixel<
+ return arena->make<GlyphFindAndPlaceSubpixel<
ProcessOneGlyph, kTextAlignment, kY_SkAxisAlignment>>(glyphFinder);
- break;
}
+ SkFAIL("Should never get here.");
+ return nullptr;
}
- static SkPoint MeasureText(LookupGlyph& glyphFinder, const char text[], size_t byteLength) {
+ static SkPoint MeasureText(
+ GlyphFinderInterface* glyphFinder, const char text[], size_t byteLength) {
SkScalar x = 0, y = 0;
const char* stop = text + byteLength;
@@ -593,93 +468,94 @@ inline void SkFindAndPlaceGlyph::ProcessPosText(
SkAxisAlignment axisAlignment = cache->getScalerContext()->computeAxisAlignmentForHText();
uint32_t mtype = matrix.getType();
- LookupGlyph glyphFinder(textEncoding, cache);
- // Specialized code for handling the most common case for blink. The while loop is totally
- // de-virtualized.
- if (scalarsPerPosition == 1
+ // Specialized code for handling the most common case for blink.
+ if (textEncoding == SkPaint::kGlyphID_TextEncoding
&& textAlignment == SkPaint::kLeft_Align
&& axisAlignment == kX_SkAxisAlignment
&& cache->isSubpixel()
- && mtype <= SkMatrix::kTranslate_Mask) {
- typedef GlyphFindAndPlaceSubpixel<
- ProcessOneGlyph, SkPaint::kLeft_Align, kX_SkAxisAlignment> Positioner;
- HorizontalPositions positions{pos};
+ && mtype <= SkMatrix::kTranslate_Mask)
+ {
+ GlyphIdGlyphFinder glyphFinder(cache);
+ using Positioner =
+ GlyphFindAndPlaceSubpixel <
+ ProcessOneGlyph, SkPaint::kLeft_Align, kX_SkAxisAlignment>;
+ HorizontalPositions hPositions{pos};
+ ArbitraryPositions aPositions{pos};
+ PositionReaderInterface* positions = nullptr;
+ if (scalarsPerPosition == 2) {
+ positions = &aPositions;
+ } else {
+ positions = &hPositions;
+ }
TranslationMapper mapper{matrix, offset};
- Positioner positioner(glyphFinder);
+ Positioner positioner(&glyphFinder);
const char* cursor = text;
const char* stop = text + byteLength;
while (cursor < stop) {
- SkPoint mappedPoint = mapper.TranslationMapper::map(
- positions.HorizontalPositions::nextPoint());
+ SkPoint mappedPoint = mapper.TranslationMapper::map(positions->nextPoint());
positioner.Positioner::findAndPositionGlyph(
&cursor, mappedPoint, std::forward<ProcessOneGlyph>(processOneGlyph));
}
return;
}
- PositionReader positionReader{
- [&](PositionReader::Variants* to_init) {
- if (2 == scalarsPerPosition) {
- to_init->initialize<ArbitraryPositions>(pos);
- } else {
- to_init->initialize<HorizontalPositions>(pos);
- }
- positionReader->forceUseForBug();
- }
- };
+ SkSTArenaAlloc<120> arena;
- Mapper mapper{
- [&](Mapper::Variants* to_init) {
- if (mtype & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)
- || scalarsPerPosition == 2) {
- to_init->initialize<GeneralMapper>(matrix, offset);
- } else if (mtype & SkMatrix::kScale_Mask) {
- to_init->initialize<XScaleMapper>(matrix, offset);
- } else {
- to_init->initialize<TranslationMapper>(matrix, offset);
- }
- }
- };
+ GlyphFinderInterface* glyphFinder = getGlyphFinder(&arena, textEncoding, cache);
- GlyphFindAndPlace<ProcessOneGlyph> findAndPosition {
- [&](typename GlyphFindAndPlace<ProcessOneGlyph>::Variants* to_init) {
- if (cache->isSubpixel()) {
- switch (textAlignment) {
- case SkPaint::kLeft_Align:
- InitSubpixel<ProcessOneGlyph, SkPaint::kLeft_Align>(
- to_init, axisAlignment, glyphFinder);
- break;
- case SkPaint::kCenter_Align:
- InitSubpixel<ProcessOneGlyph, SkPaint::kCenter_Align>(
- to_init, axisAlignment, glyphFinder);
- break;
- case SkPaint::kRight_Align:
- InitSubpixel<ProcessOneGlyph, SkPaint::kRight_Align>(
- to_init, axisAlignment, glyphFinder);
- break;
- }
- } else {
- switch (textAlignment) {
- case SkPaint::kLeft_Align:
- to_init->template initialize<
- GlyphFindAndPlaceFullPixel<ProcessOneGlyph,
- SkPaint::kLeft_Align, kNoKerning>>(glyphFinder);
- break;
- case SkPaint::kCenter_Align:
- to_init->template initialize<
- GlyphFindAndPlaceFullPixel<ProcessOneGlyph,
- SkPaint::kCenter_Align, kNoKerning>>(glyphFinder);
- break;
- case SkPaint::kRight_Align:
- to_init->template initialize<
- GlyphFindAndPlaceFullPixel<ProcessOneGlyph,
- SkPaint::kRight_Align, kNoKerning>>(glyphFinder);
- break;
- }
- }
+ PositionReaderInterface* positionReader = nullptr;
+ if (2 == scalarsPerPosition) {
+ positionReader = arena.make<ArbitraryPositions>(pos);
+ } else {
+ positionReader = arena.make<HorizontalPositions>(pos);
+ }
+
+ MapperInterface* mapper = nullptr;
+ if (mtype & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)
+ || scalarsPerPosition == 2) {
+ mapper = arena.make<GeneralMapper>(matrix, offset);
+ } else if (mtype & SkMatrix::kScale_Mask) {
+ mapper = arena.make<XScaleMapper>(matrix, offset);
+ } else {
+ mapper = arena.make<TranslationMapper>(matrix, offset);
+ }
+
+ GlyphFindAndPlaceInterface<ProcessOneGlyph>* findAndPosition = nullptr;
+ if (cache->isSubpixel()) {
+ switch (textAlignment) {
+ case SkPaint::kLeft_Align:
+ findAndPosition = getSubpixel<ProcessOneGlyph, SkPaint::kLeft_Align>(
+ &arena, axisAlignment, glyphFinder);
+ break;
+ case SkPaint::kCenter_Align:
+ findAndPosition = getSubpixel<ProcessOneGlyph, SkPaint::kCenter_Align>(
+ &arena, axisAlignment, glyphFinder);
+ break;
+ case SkPaint::kRight_Align:
+ findAndPosition = getSubpixel<ProcessOneGlyph, SkPaint::kRight_Align>(
+ &arena, axisAlignment, glyphFinder);
+ break;
}
- };
+ } else {
+ switch (textAlignment) {
+ case SkPaint::kLeft_Align:
+ findAndPosition = arena.make<
+ GlyphFindAndPlaceFullPixel<ProcessOneGlyph,
+ SkPaint::kLeft_Align, kNoKerning>>(glyphFinder);
+ break;
+ case SkPaint::kCenter_Align:
+ findAndPosition = arena.make<
+ GlyphFindAndPlaceFullPixel<ProcessOneGlyph,
+ SkPaint::kCenter_Align, kNoKerning>>(glyphFinder);
+ break;
+ case SkPaint::kRight_Align:
+ findAndPosition = arena.make<
+ GlyphFindAndPlaceFullPixel<ProcessOneGlyph,
+ SkPaint::kRight_Align, kNoKerning>>(glyphFinder);
+ break;
+ }
+ }
const char* stop = text + byteLength;
while (text < stop) {
@@ -694,11 +570,12 @@ inline void SkFindAndPlaceGlyph::ProcessText(
SkPaint::TextEncoding textEncoding, const char text[], size_t byteLength,
SkPoint offset, const SkMatrix& matrix, SkPaint::Align textAlignment,
SkGlyphCache* cache, ProcessOneGlyph&& processOneGlyph) {
+ SkSTArenaAlloc<64> arena;
// transform the starting point
matrix.mapPoints(&offset, 1);
- LookupGlyph glyphFinder(textEncoding, cache);
+ GlyphFinderInterface* glyphFinder = getGlyphFinder(&arena, textEncoding, cache);
// need to measure first
if (textAlignment != SkPaint::kLeft_Align) {
@@ -710,20 +587,16 @@ inline void SkFindAndPlaceGlyph::ProcessText(
offset -= stop;
}
- GlyphFindAndPlace<ProcessOneGlyph> findAndPosition{
- [&](typename GlyphFindAndPlace<ProcessOneGlyph>::Variants* to_init) {
- if (cache->isSubpixel()) {
- SkAxisAlignment axisAlignment =
- cache->getScalerContext()->computeAxisAlignmentForHText();
- InitSubpixel<ProcessOneGlyph, SkPaint::kLeft_Align>(
- to_init, axisAlignment, glyphFinder);
- } else {
- to_init->template initialize<
- GlyphFindAndPlaceFullPixel<
- ProcessOneGlyph, SkPaint::kLeft_Align, kUseKerning>>(glyphFinder);
- }
- }
- };
+ GlyphFindAndPlaceInterface<ProcessOneGlyph>* findAndPosition = nullptr;
+ if (cache->isSubpixel()) {
+ SkAxisAlignment axisAlignment = cache->getScalerContext()->computeAxisAlignmentForHText();
+ findAndPosition = getSubpixel<ProcessOneGlyph, SkPaint::kLeft_Align>(
+ &arena, axisAlignment, glyphFinder);
+ } else {
+ using FullPixel =
+ GlyphFindAndPlaceFullPixel<ProcessOneGlyph, SkPaint::kLeft_Align, kUseKerning>;
+ findAndPosition = arena.make<FullPixel>(glyphFinder);
+ }
const char* stop = text + byteLength;
SkPoint current = offset;