Introduce SkGlyphCacheInterface
Change-Id: I54ee9f5a5a13eff0b7f9a07bb22314d8ea2350a4 Reviewed-on: https://skia-review.googlesource.com/148813 Commit-Queue: Herb Derby <herb@google.com> Reviewed-by: Mike Klein <mtklein@google.com>
This commit is contained in:
parent
7989dad6c3
commit
4f169ec737
@ -27,7 +27,9 @@ SkGlyphCache::SkGlyphCache(
|
||||
const SkPaint::FontMetrics& fontMetrics)
|
||||
: fDesc{desc}
|
||||
, fScalerContext{std::move(scaler)}
|
||||
, fFontMetrics(fontMetrics)
|
||||
, fFontMetrics{fontMetrics}
|
||||
, fIsSubpixel{fScalerContext->isSubpixel()}
|
||||
, fAxisAlignment{fScalerContext->computeAxisAlignmentForHText()}
|
||||
{
|
||||
SkASSERT(fScalerContext != nullptr);
|
||||
fMemoryUsed = sizeof(*this);
|
||||
@ -282,6 +284,20 @@ void SkGlyphCache::initializeGlyphFromFallback(SkGlyph* glyph, const SkGlyph& fa
|
||||
fMemoryUsed += glyph->copyImageData(fallback, &fAlloc);
|
||||
}
|
||||
|
||||
SkVector SkGlyphCache::rounding() const {
|
||||
return SkGlyphCacheCommon::PixelRounding(fIsSubpixel, fAxisAlignment);
|
||||
}
|
||||
|
||||
const SkGlyph& SkGlyphCache::getGlyphMetrics(SkGlyphID glyphID, SkPoint position) {
|
||||
if (!fIsSubpixel) {
|
||||
return this->getGlyphIDMetrics(glyphID);
|
||||
} else {
|
||||
SkIPoint lookupPosition = SkGlyphCacheCommon::SubpixelLookup(fAxisAlignment, position);
|
||||
|
||||
return this->getGlyphIDMetrics(glyphID, lookupPosition.x(), lookupPosition.y());
|
||||
}
|
||||
}
|
||||
|
||||
#include "../pathops/SkPathOpsCubic.h"
|
||||
#include "../pathops/SkPathOpsQuad.h"
|
||||
|
||||
|
@ -30,12 +30,12 @@
|
||||
The Find*Exclusive() method returns SkExclusiveStrikePtr, which releases exclusive ownership
|
||||
when they go out of scope.
|
||||
*/
|
||||
class SkGlyphCache {
|
||||
class SkGlyphCache : public SkGlyphCacheInterface {
|
||||
public:
|
||||
SkGlyphCache(const SkDescriptor& desc,
|
||||
std::unique_ptr<SkScalerContext> scaler,
|
||||
const SkPaint::FontMetrics&);
|
||||
~SkGlyphCache();
|
||||
~SkGlyphCache() override;
|
||||
|
||||
const SkDescriptor& getDescriptor() const;
|
||||
|
||||
@ -132,9 +132,13 @@ public:
|
||||
}
|
||||
|
||||
bool isSubpixel() const {
|
||||
return fScalerContext->isSubpixel();
|
||||
return fIsSubpixel;
|
||||
}
|
||||
|
||||
SkVector rounding() const override;
|
||||
|
||||
const SkGlyph& getGlyphMetrics(SkGlyphID glyphID, SkPoint position) override;
|
||||
|
||||
/** Return the approx RAM usage for this cache. */
|
||||
size_t getMemoryUsed() const { return fMemoryUsed; }
|
||||
|
||||
@ -233,6 +237,9 @@ private:
|
||||
|
||||
// used to track (approx) how much ram is tied-up in this cache
|
||||
size_t fMemoryUsed;
|
||||
|
||||
const bool fIsSubpixel;
|
||||
const SkAxisAlignment fAxisAlignment;
|
||||
};
|
||||
|
||||
#endif // SkGlyphCache_DEFINED
|
||||
|
@ -140,42 +140,16 @@ SkGlyphRunListPainter::SkGlyphRunListPainter(
|
||||
SkGlyphRunListPainter::SkGlyphRunListPainter(const GrRenderTargetContext& rtc)
|
||||
: SkGlyphRunListPainter{rtc.surfaceProps(), rtc.colorSpaceInfo()} {}
|
||||
|
||||
// TODO: all this logic should move to the glyph cache.
|
||||
static const SkGlyph& lookup_glyph_by_subpixel(
|
||||
SkAxisAlignment axisAlignment, SkPoint position, SkGlyphID glyphID, SkGlyphCache* cache) {
|
||||
SkFixed lookupX = SkScalarToFixed(SkScalarFraction(position.x())),
|
||||
lookupY = SkScalarToFixed(SkScalarFraction(position.y()));
|
||||
|
||||
// Snap to a given axis if alignment is requested.
|
||||
if (axisAlignment == kX_SkAxisAlignment) {
|
||||
lookupY = 0;
|
||||
} else if (axisAlignment == kY_SkAxisAlignment) {
|
||||
lookupX = 0;
|
||||
}
|
||||
|
||||
return cache->getGlyphIDMetrics(glyphID, lookupX, lookupY);
|
||||
}
|
||||
|
||||
|
||||
// forEachMappedDrawableGlyph handles positioning for mask type glyph handling for both sub-pixel
|
||||
// and full pixel positioning.
|
||||
template <typename EachGlyph>
|
||||
void SkGlyphRunListPainter::forEachMappedDrawableGlyph(
|
||||
const SkGlyphRun& glyphRun, SkPoint origin, const SkMatrix& deviceMatrix,
|
||||
SkGlyphCache* cache, EachGlyph eachGlyph) {
|
||||
bool isSubpixel = cache->isSubpixel();
|
||||
|
||||
SkAxisAlignment axisAlignment = kNone_SkAxisAlignment;
|
||||
SkGlyphCacheInterface* cache, EachGlyph eachGlyph) {
|
||||
SkMatrix mapping = deviceMatrix;
|
||||
mapping.preTranslate(origin.x(), origin.y());
|
||||
// TODO: all this logic should move to the glyph cache.
|
||||
if (isSubpixel) {
|
||||
axisAlignment = cache->getScalerContext()->computeAxisAlignmentForHText();
|
||||
SkPoint rounding = SkFindAndPlaceGlyph::SubpixelPositionRounding(axisAlignment);
|
||||
mapping.postTranslate(rounding.x(), rounding.y());
|
||||
} else {
|
||||
mapping.postTranslate(SK_ScalarHalf, SK_ScalarHalf);
|
||||
}
|
||||
SkVector rounding = cache->rounding();
|
||||
mapping.postTranslate(rounding.x(), rounding.y());
|
||||
|
||||
auto runSize = glyphRun.runSize();
|
||||
if (this->ensureBitmapBuffers(runSize)) {
|
||||
@ -186,10 +160,7 @@ void SkGlyphRunListPainter::forEachMappedDrawableGlyph(
|
||||
auto mappedPt = *mappedPtCursor++;
|
||||
auto pt = origin + *ptCursor++;
|
||||
if (SkScalarsAreFinite(mappedPt.x(), mappedPt.y())) {
|
||||
// TODO: all this logic should move to the glyph cache.
|
||||
const SkGlyph& glyph =
|
||||
isSubpixel ? lookup_glyph_by_subpixel(axisAlignment, mappedPt, glyphID, cache)
|
||||
: cache->getGlyphIDMetrics(glyphID);
|
||||
const SkGlyph& glyph = cache->getGlyphMetrics(glyphID, mappedPt);
|
||||
if (!glyph.isEmpty()) {
|
||||
// Prevent glyphs from being drawn outside of or straddling the edge
|
||||
// of device space. Comparisons written a little weirdly so that NaN
|
||||
@ -357,7 +328,6 @@ void SkGlyphRunListPainter::drawGlyphRunAsFullpixelMask(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SkGlyphRunListPainter::drawForBitmapDevice(
|
||||
const SkGlyphRunList& glyphRunList, const SkMatrix& deviceMatrix,
|
||||
PerMaskCreator perMaskCreator, PerPathCreator perPathCreator) {
|
||||
|
@ -30,6 +30,51 @@ class SkBaseDevice;
|
||||
class SkGlyphRunList;
|
||||
class SkRasterClip;
|
||||
|
||||
class SkGlyphCacheInterface {
|
||||
public:
|
||||
virtual ~SkGlyphCacheInterface() = default;
|
||||
virtual SkVector rounding() const = 0;
|
||||
virtual const SkGlyph& getGlyphMetrics(SkGlyphID glyphID, SkPoint position) = 0;
|
||||
};
|
||||
|
||||
class SkGlyphCacheCommon {
|
||||
public:
|
||||
static SkVector PixelRounding(bool isSubpixel, SkAxisAlignment axisAlignment) {
|
||||
if (!isSubpixel) {
|
||||
return {SK_ScalarHalf, SK_ScalarHalf};
|
||||
} else {
|
||||
static constexpr SkScalar kSubpixelRounding = SkFixedToScalar(SkGlyph::kSubpixelRound);
|
||||
switch (axisAlignment) {
|
||||
case kX_SkAxisAlignment:
|
||||
return {kSubpixelRounding, SK_ScalarHalf};
|
||||
case kY_SkAxisAlignment:
|
||||
return {SK_ScalarHalf, kSubpixelRounding};
|
||||
case kNone_SkAxisAlignment:
|
||||
return {kSubpixelRounding, kSubpixelRounding};
|
||||
}
|
||||
}
|
||||
|
||||
// Some compilers need this.
|
||||
return {0, 0};
|
||||
}
|
||||
|
||||
// This assumes that position has the appropriate rounding term applied.
|
||||
static SkIPoint SubpixelLookup(SkAxisAlignment axisAlignment, SkPoint position) {
|
||||
// TODO: SkScalarFraction uses truncf to calculate the fraction. This should be floorf.
|
||||
SkFixed lookupX = SkScalarToFixed(SkScalarFraction(position.x())),
|
||||
lookupY = SkScalarToFixed(SkScalarFraction(position.y()));
|
||||
|
||||
// Snap to a given axis if alignment is requested.
|
||||
if (axisAlignment == kX_SkAxisAlignment) {
|
||||
lookupY = 0;
|
||||
} else if (axisAlignment == kY_SkAxisAlignment) {
|
||||
lookupX = 0;
|
||||
}
|
||||
|
||||
return {lookupX, lookupY};
|
||||
}
|
||||
};
|
||||
|
||||
class SkGlyphRun {
|
||||
public:
|
||||
SkGlyphRun() = default;
|
||||
@ -128,7 +173,7 @@ private:
|
||||
template <typename EachGlyph>
|
||||
void forEachMappedDrawableGlyph(
|
||||
const SkGlyphRun& glyphRun, SkPoint origin, const SkMatrix& deviceMatrix,
|
||||
SkGlyphCache* cache, EachGlyph eachGlyph);
|
||||
SkGlyphCacheInterface* cache, EachGlyph eachGlyph);
|
||||
|
||||
void drawGlyphRunAsSubpixelMask(
|
||||
SkGlyphCache* cache, const SkGlyphRun& glyphRun,
|
||||
|
Loading…
Reference in New Issue
Block a user