Introduce SkStrikeSpecStorage.

SkStrikeSpecStorage is the centralized class for creating different sets of
SkScalerContextRecs/Effects for different text rendering methods.

It is initailly called SkStrikeSpecStorage, but as a last stage will be
renamed to SkStrikeSpec as it encompasses the current functionality of
the existing SkStrikeSpec.

I'm breaking up a much larger prototype for this CL and several
following CLs. The prototype is at:

https://skia-review.googlesource.com/c/skia/+/209109

Change-Id: I617eaae6fcb4b0b29914c3f1a82c52c81d81aabe
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/212733
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
This commit is contained in:
Herb Derby 2019-05-08 14:38:51 -04:00 committed by Skia Commit-Bot
parent 13371a10b0
commit 8fae51b699
6 changed files with 230 additions and 4 deletions

View File

@ -349,6 +349,8 @@ skia_core_sources = [
"$_src/core/SkStrikeCache.cpp",
"$_src/core/SkStrikeCache.h",
"$_src/core/SkStrikeInterface.h",
"$_src/core/SkStrikeSpec.cpp",
"$_src/core/SkStrikeSpec.h",
"$_src/core/SkString.cpp",
"$_src/core/SkStringUtils.cpp",
"$_src/core/SkStroke.h",

View File

@ -516,6 +516,7 @@ private:
friend class SkGlyphRunListPainter;
friend class SkTextBlobCacheDiffCanvas;
friend class SVGTextBuilder;
friend class SkStrikeSpecStorage;
};
#endif

View File

@ -104,6 +104,14 @@ bool SkDescriptor::isValid() const {
SkAutoDescriptor::SkAutoDescriptor() = default;
SkAutoDescriptor::SkAutoDescriptor(size_t size) { this->reset(size); }
SkAutoDescriptor::SkAutoDescriptor(const SkDescriptor& desc) { this->reset(desc); }
SkAutoDescriptor::SkAutoDescriptor(const SkAutoDescriptor& ad) {
this->reset(*ad.getDesc());
}
SkAutoDescriptor& SkAutoDescriptor::operator=(const SkAutoDescriptor& ad) {
this->reset(*ad.getDesc());
return *this;
}
SkAutoDescriptor::~SkAutoDescriptor() { this->free(); }
void SkAutoDescriptor::reset(size_t size) {

View File

@ -74,13 +74,15 @@ private:
uint32_t fCount;
};
class SkAutoDescriptor : SkNoncopyable {
class SkAutoDescriptor {
public:
SkAutoDescriptor();
SkAutoDescriptor(size_t size);
SkAutoDescriptor(const SkDescriptor& desc);
explicit SkAutoDescriptor(size_t size);
explicit SkAutoDescriptor(const SkDescriptor& desc);
SkAutoDescriptor(const SkAutoDescriptor& ad);
SkAutoDescriptor& operator= (const SkAutoDescriptor& ad);
SkAutoDescriptor(SkAutoDescriptor&&) = delete;
SkAutoDescriptor& operator =(SkAutoDescriptor&&) = delete;
SkAutoDescriptor& operator= (SkAutoDescriptor&&) = delete;
~SkAutoDescriptor();

128
src/core/SkStrikeSpec.cpp Normal file
View File

@ -0,0 +1,128 @@
/*
* Copyright 2019 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 "src/core/SkStrikeSpec.h"
#include "src/core/SkDraw.h"
#include "src/core/SkStrikeCache.h"
#include "src/core/SkTLazy.h"
SkStrikeSpecStorage SkStrikeSpecStorage::MakeMask(const SkFont& font, const SkPaint& paint,
const SkSurfaceProps& surfaceProps,
SkScalerContextFlags scalerContextFlags,
const SkMatrix& deviceMatrix) {
SkStrikeSpecStorage storage;
storage.commonSetup(font, paint, surfaceProps, scalerContextFlags, deviceMatrix);
return storage;
}
SkStrikeSpecStorage SkStrikeSpecStorage::MakePath(const SkFont& font, const SkPaint& paint,
const SkSurfaceProps& surfaceProps,
SkScalerContextFlags scalerContextFlags) {
SkStrikeSpecStorage storage;
// setup our std runPaint, in hopes of getting hits in the cache
SkPaint pathPaint{paint};
SkFont pathFont{font};
// The factor to get from the size stored in the strike to the size needed for
// the source.
storage.fStrikeToSourceRatio = pathFont.setupForAsPaths(&pathPaint);
// The sub-pixel position will always happen when transforming to the screen.
pathFont.setSubpixel(false);
storage.commonSetup(pathFont, pathPaint, surfaceProps, scalerContextFlags, SkMatrix::I());
return storage;
}
SkStrikeSpecStorage SkStrikeSpecStorage::MakeCanonicalized(
const SkFont& font, const SkPaint* paint) {
SkStrikeSpecStorage storage;
SkPaint canonicalizedPaint;
if (paint != nullptr) {
canonicalizedPaint = *paint;
}
const SkFont* canonicalizedFont = &font;
SkTLazy<SkFont> pathFont;
if (SkDraw::ShouldDrawTextAsPaths(font, canonicalizedPaint, SkMatrix::I())) {
canonicalizedFont = pathFont.set(font);
storage.fStrikeToSourceRatio = pathFont->setupForAsPaths(nullptr);
canonicalizedPaint.reset();
}
storage.commonSetup(*canonicalizedFont,
canonicalizedPaint,
SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType),
kFakeGammaAndBoostContrast,
SkMatrix::I());
return storage;
}
SkStrikeSpecStorage SkStrikeSpecStorage::MakeDefault() {
SkFont defaultFont;
return MakeCanonicalized(defaultFont);
}
#if SK_SUPPORT_GPU
std::tuple<SkStrikeSpecStorage, SkScalar, SkScalar>
SkStrikeSpecStorage::MakeSDFT(const SkFont& font, const SkPaint& paint,
const SkSurfaceProps& surfaceProps, const SkMatrix& deviceMatrix,
const GrTextContext::Options& options) {
SkStrikeSpecStorage storage;
SkPaint dfPaint = GrTextContext::InitDistanceFieldPaint(paint);
SkFont dfFont = GrTextContext::InitDistanceFieldFont(
font, deviceMatrix, options, &storage.fStrikeToSourceRatio);
// Fake-gamma and subpixel antialiasing are applied in the shader, so we ignore the
// passed-in scaler context flags. (It's only used when we fall-back to bitmap text).
SkScalerContextFlags flags = SkScalerContextFlags::kNone;
SkScalar minScale, maxScale;
std::tie(minScale, maxScale) = GrTextContext::InitDistanceFieldMinMaxScale(
font.getSize(), deviceMatrix, options);
storage.commonSetup(dfFont, dfPaint, surfaceProps, flags, SkMatrix::I());
return std::tie(storage, minScale, maxScale);
}
sk_sp<GrTextStrike> SkStrikeSpecStorage::findOrCreateGrStrike(GrStrikeCache* cache) const {
return cache->getStrike(*fAutoDescriptor.getDesc());
}
#endif
void SkStrikeSpecStorage::commonSetup(const SkFont& font, const SkPaint& paint,
const SkSurfaceProps& surfaceProps,
SkScalerContextFlags scalerContextFlags,
const SkMatrix& deviceMatrix) {
SkScalerContextEffects effects;
SkScalerContext::CreateDescriptorAndEffectsUsingPaint(
font, paint, surfaceProps, scalerContextFlags, deviceMatrix,
&fAutoDescriptor, &effects);
fMaskFilter = sk_ref_sp(effects.fMaskFilter);
fPathEffect = sk_ref_sp(effects.fPathEffect);
fTypeface = font.refTypefaceOrDefault();
}
SkScopedStrike SkStrikeSpecStorage::findOrCreateScopedStrike(SkStrikeCacheInterface* cache) const {
SkScalerContextEffects effects{fPathEffect.get(), fMaskFilter.get()};
return cache->findOrCreateScopedStrike(*fAutoDescriptor.getDesc(), effects, *fTypeface);
}
SkExclusiveStrikePtr SkStrikeSpecStorage::findOrCreateExclusiveStrike(SkStrikeCache* cache) const {
SkScalerContextEffects effects{fPathEffect.get(), fMaskFilter.get()};
return cache->findOrCreateStrikeExclusive(*fAutoDescriptor.getDesc(), effects, *fTypeface);
}

85
src/core/SkStrikeSpec.h Normal file
View File

@ -0,0 +1,85 @@
/*
* Copyright 2019 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkStrikeSpec_DEFINED
#define SkStrikeSpec_DEFINED
#include "src/core/SkDescriptor.h"
#include "src/core/SkStrikeCache.h"
#include "src/core/SkStrikeInterface.h"
#if SK_SUPPORT_GPU
#include "src/gpu/text/GrStrikeCache.h"
#include "src/gpu/text/GrTextContext.h"
#endif
class SkFont;
class SkPaint;
class SkStrikeCache;
class SkSurfaceProps;
// TODO: rename to SkStrikeSpec when the current SkStrikeSpec is remove from the code.
class SkStrikeSpecStorage {
public:
// Create a strike spec for mask style cache entries.
static SkStrikeSpecStorage MakeMask(
const SkFont& font,
const SkPaint& paint,
const SkSurfaceProps& surfaceProps,
SkScalerContextFlags scalerContextFlags,
const SkMatrix& deviceMatrix);
// Create a strike spec for path style cache entries.
static SkStrikeSpecStorage MakePath(
const SkFont& font,
const SkPaint& paint,
const SkSurfaceProps& surfaceProps,
SkScalerContextFlags scalerContextFlags);
// Create a canonical strike spec for device-less measurements.
static SkStrikeSpecStorage MakeCanonicalized(
const SkFont& font, const SkPaint* paint = nullptr);
// Make a canonical strike spec for device-less measurements using default typeface and size.
static SkStrikeSpecStorage MakeDefault();
#if SK_SUPPORT_GPU
// Create a strike spec for scaled distance field text.
static std::tuple<SkStrikeSpecStorage, SkScalar, SkScalar> MakeSDFT(
const SkFont& font,
const SkPaint& paint,
const SkSurfaceProps& surfaceProps,
const SkMatrix& deviceMatrix,
const GrTextContext::Options& options);
sk_sp<GrTextStrike> findOrCreateGrStrike(GrStrikeCache* cache) const;
#endif
SkScopedStrike findOrCreateScopedStrike(SkStrikeCacheInterface* cache) const;
SkExclusiveStrikePtr findOrCreateExclusiveStrike(
SkStrikeCache* cache = SkStrikeCache::GlobalStrikeCache()) const;
SkScalar strikeToSourceRatio() const { return fStrikeToSourceRatio; }
const SkDescriptor& descriptor() const { return *fAutoDescriptor.getDesc(); }
private:
void commonSetup(
const SkFont& font,
const SkPaint& paint,
const SkSurfaceProps& surfaceProps,
SkScalerContextFlags scalerContextFlags,
const SkMatrix& deviceMatrix);
SkAutoDescriptor fAutoDescriptor;
sk_sp<SkMaskFilter> fMaskFilter;
sk_sp<SkPathEffect> fPathEffect;
sk_sp<SkTypeface> fTypeface;
SkScalar fStrikeToSourceRatio{1.0f};
};
#endif // SkStrikeSpec_DEFINED