blob: 05d795778d4d976127142887a066ba66b865b6d7 [file] [log] [blame]
/*
* 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);
}
SkStrikeSpecStorage SkStrikeSpecStorage::MakePDFVector(const SkTypeface& typeface, int* size) {
SkFont font;
font.setHinting(SkFontHinting::kNone);
font.setEdging(SkFont::Edging::kAlias);
font.setTypeface(sk_ref_sp(&typeface));
int unitsPerEm = typeface.getUnitsPerEm();
if (unitsPerEm <= 0) {
unitsPerEm = 1024;
}
if (size) {
*size = unitsPerEm;
}
font.setSize((SkScalar)unitsPerEm);
SkStrikeSpecStorage storage;
storage.commonSetup(font,
SkPaint(),
SkSurfaceProps(0, kUnknown_SkPixelGeometry),
kFakeGammaAndBoostContrast,
SkMatrix::I());
return storage;
}
#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);
}