blob: 592418a82d18ce73c0055e9fbc3557694a964a48 [file] [log] [blame]
* Copyright 2014 Google Inc.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
#ifndef TestSVGTypeface_DEFINED
#define TestSVGTypeface_DEFINED
#include "SkFontArguments.h"
#include "SkFontMetrics.h"
#include "SkMutex.h"
#include "SkPaint.h"
#include "SkPathOps.h"
#include "SkPoint.h"
#include "SkRect.h"
#include "SkRefCnt.h"
#include "SkScalar.h"
#include "SkSpan.h"
#include "SkStream.h"
#include "SkString.h"
#include "SkTArray.h"
#include "SkTHash.h"
#include "SkTypeface.h"
#include "SkTypes.h"
#include <memory>
class SkCanvas;
class SkDescriptor;
class SkFontDescriptor;
class SkFontStyle;
class SkGlyph;
class SkPath;
class SkScalerContext;
class SkSVGDOM;
class SkWStream;
struct SkAdvancedTypefaceMetrics;
struct SkScalerContextEffects;
struct SkScalerContextRec;
struct SkSVGTestTypefaceGlyphData {
const char* fSvgResourcePath;
SkPoint fOrigin; // y-down
SkScalar fAdvance;
SkUnichar fUnicode; // TODO: this limits to 1:1
class TestSVGTypeface : public SkTypeface {
TestSVGTypeface(const char* name,
int upem,
const SkFontMetrics& metrics,
SkSpan<const SkSVGTestTypefaceGlyphData> data,
const SkFontStyle& style);
~TestSVGTypeface() override;
void getAdvance(SkGlyph* glyph) const;
void getFontMetrics(SkFontMetrics* metrics) const;
static sk_sp<TestSVGTypeface> Default();
static sk_sp<TestSVGTypeface> Planets();
void exportTtxCbdt(SkWStream*, SkSpan<unsigned> strikeSizes) const;
void exportTtxSbix(SkWStream*, SkSpan<unsigned> strikeSizes) const;
void exportTtxColr(SkWStream*) const;
virtual bool getPathOp(SkColor, SkPathOp*) const = 0;
struct GlyfLayerInfo {
GlyfLayerInfo(int layerColorIndex, SkIRect bounds)
: fLayerColorIndex(layerColorIndex), fBounds(bounds) {}
int fLayerColorIndex;
SkIRect fBounds;
struct GlyfInfo {
GlyfInfo() : fBounds(SkIRect::MakeEmpty()) {}
SkIRect fBounds;
SkTArray<GlyfLayerInfo> fLayers;
void exportTtxCommon(SkWStream*, const char* type, const SkTArray<GlyfInfo>* = nullptr) const;
SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
const SkDescriptor* desc) const override;
void onFilterRec(SkScalerContextRec* rec) const override;
void getGlyphToUnicodeMap(SkUnichar*) const override;
std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override;
std::unique_ptr<SkStreamAsset> onOpenStream(int* ttcIndex) const override { return nullptr; }
sk_sp<SkTypeface> onMakeClone(const SkFontArguments& args) const override {
return sk_ref_sp(this);
void onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const override;
void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override;
int onCountGlyphs() const override { return fGlyphCount; }
int onGetUPEM() const override { return fUpem; }
void onGetFamilyName(SkString* familyName) const override;
SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override;
int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],
int coordinateCount) const override {
return 0;
int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],
int parameterCount) const override {
return 0;
int onGetTableTags(SkFontTableTag tags[]) const override { return 0; }
size_t onGetTableData(SkFontTableTag tag,
size_t offset,
size_t length,
void* data) const override {
return 0;
struct Glyph {
SkPoint fOrigin;
SkScalar fAdvance;
const char* fResourcePath;
SkSize size() const;
void render(SkCanvas*) const;
// Lazily parses the SVG from fResourcePath, and manages mutex locking.
template <typename Fn> void withSVG(Fn&&) const;
// The mutex guards lazy parsing of the SVG, but also predates that.
// Must be SkSVGDOM::render() is not thread safe?
// If not, an SkOnce is enough here.
mutable SkMutex fSvgMutex;
mutable bool fParsedSvg = false;
mutable sk_sp<SkSVGDOM> fSvg;
SkString fName;
int fUpem;
const SkFontMetrics fFontMetrics;
std::unique_ptr<Glyph[]> fGlyphs;
int fGlyphCount;
SkTHashMap<SkUnichar, SkGlyphID> fCMap;
friend class SkTestSVGScalerContext;