Support font palette overrides through SkFontArguments

Co-authored with Ben Wagner, bungeman@google.com.

Similar to how we allow configuration of variable font configurations,
provide additional SkFontArguments to select a base palette and a set
of potentially sparse color overrides.

This is required for implementing CSS font-palette.

Modify the more_samples-glyf_colr_1.ttf to have two additional palettes,
and two additional test glyphs, one that draws with COLRv0 logic, one
that draws with COLRv1 logic and has a foreground palette index dot
in the middle. See [1] & [2] for the additions to the test font.

Add a GM which tests this on the SkFontMgr_custom using makeClone() and
makeFromStreamArgs(). The test displays the two glyphs in default
palette on the left, then with palette overrides (as in the title of the
test) on the right. The first row uses a typeface created with
makeFromStreamArgs(), the second uses one created with makeClone().

[1] https://github.com/googlefonts/color-fonts/pull/91
[2] https://github.com/googlefonts/color-fonts/pull/92

Bug: skia:12730, chromium:1170794
Cq-Include-Trybots: luci.skia.skia.primary:Test-Android-Clang-GalaxyS20-GPU-MaliG77-arm64-Release-All-Android_NativeFonts,Test-Debian10-Clang-GCE-CPU-AVX2-x86_64-Debug-All-NativeFonts
Change-Id: Ia1334f069240edc78fd4791969914e8a6f4fbaf9
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/479616
Reviewed-by: Ben Wagner <bungeman@google.com>
Reviewed-by: Derek Sollenberger <djsollen@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
This commit is contained in:
Dominik Röttsches 2022-02-17 12:37:49 +02:00 committed by SkCQ
parent 76699a4495
commit 01be94d7f1
18 changed files with 404 additions and 80 deletions

View File

@ -34,6 +34,8 @@ Milestone 99
https://review.skia.org/481416 https://review.skia.org/481416
* Added a new variant of SkImageFilters::RuntimeShader that supports multiple child nodes. * Added a new variant of SkImageFilters::RuntimeShader that supports multiple child nodes.
https://review.skia.org/489536 https://review.skia.org/489536
* Add the ability to specifiy palette overrides in SkFontArguments. Implemented
for the FreeType-backed SkFontMgrs.
* * * * * *

148
gm/palette.cpp Normal file
View File

@ -0,0 +1,148 @@
/*
* Copyright 2022 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontMetrics.h"
#include "include/core/SkFontMgr.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"
#include <string.h>
namespace skiagm {
namespace {
const char kColrCpalTestFontPath[] = "fonts/more_samples-glyf_colr_1.ttf";
constexpr SkFontArguments::Palette::Override kColorOverridesAll[] = {
// A gradient of dark to light purple for the circle palette test glyph.
{0, 0xff310b55},
{1, 0xff510970},
{2, 0xff76078f},
{3, 0xff9606aa},
{4, 0xffb404c4},
{5, 0xffd802e2},
{6, 0xfffa00ff},
{7, 0xff888888},
{8, 0xff888888},
{9, 0xff888888},
{10, 0xff888888},
{11, 0xff888888}};
constexpr SkFontArguments::Palette::Override kColorOverridesOne[] = {
{2, 0xff02dfe2},
};
constexpr SkFontArguments::Palette kLightPaletteOverride{2, nullptr, 0};
constexpr SkFontArguments::Palette kDarkPaletteOverride{1, nullptr, 0};
constexpr SkFontArguments::Palette kOnePaletteOverride{
0, kColorOverridesOne, SK_ARRAY_COUNT(kColorOverridesOne)};
constexpr SkFontArguments::Palette kAllPaletteOverride{
0, kColorOverridesAll, SK_ARRAY_COUNT(kColorOverridesAll)};
constexpr uint16_t kTestGlyphs[] = {56, 57};
} // namespace
class FontPaletteGM : public GM {
public:
FontPaletteGM(const char* test_name,
const SkFontArguments::Palette& paletteOverride)
: fName(test_name), fPalette(paletteOverride) {}
protected:
sk_sp<SkTypeface> fTypefaceDefault;
sk_sp<SkTypeface> fTypefaceFromStream;
sk_sp<SkTypeface> fTypefaceCloned;
void onOnceBeforeDraw() override {
SkFontArguments paletteArguments;
paletteArguments.setPalette(fPalette);
fTypefaceDefault = MakeResourceAsTypeface(kColrCpalTestFontPath);
fTypefaceCloned =
fTypefaceDefault ? fTypefaceDefault->makeClone(paletteArguments) : nullptr;
fTypefaceFromStream = SkFontMgr::RefDefault()->makeFromStream(
GetResourceAsStream(kColrCpalTestFontPath), paletteArguments);
}
SkString onShortName() override {
SkString gm_name = SkStringPrintf("font_palette_%s", fName.c_str());
return gm_name;
}
SkISize onISize() override { return SkISize::Make(1000, 400); }
DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
canvas->drawColor(SK_ColorWHITE);
SkPaint paint;
canvas->translate(10, 20);
if (!fTypefaceCloned || !fTypefaceFromStream) {
*errorMsg = "Did not recognize COLR v1 test font format.";
return DrawResult::kSkip;
}
SkFontMetrics metrics;
SkScalar y = 0;
SkScalar textSize = 200;
for (auto& typeface : { fTypefaceFromStream, fTypefaceCloned} ) {
SkFont defaultFont(fTypefaceDefault);
SkFont paletteFont(typeface);
defaultFont.setSize(textSize);
paletteFont.setSize(textSize);
defaultFont.getMetrics(&metrics);
y += -metrics.fAscent;
// Set a recognizable foreground color which is not to be overriden.
paint.setColor(SK_ColorGRAY);
// Draw the default palette on the left, for COLRv0 and COLRv1.
canvas->drawSimpleText(kTestGlyphs,
SK_ARRAY_COUNT(kTestGlyphs) * sizeof(uint16_t),
SkTextEncoding::kGlyphID,
0,
y,
defaultFont,
paint);
// Draw the overriden palette on the right.
canvas->drawSimpleText(kTestGlyphs,
SK_ARRAY_COUNT(kTestGlyphs) * sizeof(uint16_t),
SkTextEncoding::kGlyphID,
440,
y,
paletteFont,
paint);
y += metrics.fDescent + metrics.fLeading;
}
return DrawResult::kOk;
}
private:
using INHERITED = GM;
SkString fName;
SkFontArguments::Palette fPalette;
};
DEF_GM(return new FontPaletteGM("default", SkFontArguments::Palette()));
DEF_GM(return new FontPaletteGM("light", kLightPaletteOverride));
DEF_GM(return new FontPaletteGM("dark", kDarkPaletteOverride));
DEF_GM(return new FontPaletteGM("one", kOnePaletteOverride));
DEF_GM(return new FontPaletteGM("all", kAllPaletteOverride));
} // namespace skiagm

View File

@ -279,6 +279,7 @@ gm_sources = [
"$_gm/overdrawcolorfilter.cpp", "$_gm/overdrawcolorfilter.cpp",
"$_gm/overstroke.cpp", "$_gm/overstroke.cpp",
"$_gm/p3.cpp", "$_gm/p3.cpp",
"$_gm/palette.cpp",
"$_gm/particles.cpp", "$_gm/particles.cpp",
"$_gm/patch.cpp", "$_gm/patch.cpp",
"$_gm/path_stroke_with_zero_length.cpp", "$_gm/path_stroke_with_zero_length.cpp",

View File

@ -8,6 +8,7 @@
#ifndef SkFontArguments_DEFINED #ifndef SkFontArguments_DEFINED
#define SkFontArguments_DEFINED #define SkFontArguments_DEFINED
#include "include/core/SkColor.h"
#include "include/core/SkScalar.h" #include "include/core/SkScalar.h"
#include "include/core/SkTypes.h" #include "include/core/SkTypes.h"
@ -22,7 +23,27 @@ struct SkFontArguments {
int coordinateCount; int coordinateCount;
}; };
SkFontArguments() : fCollectionIndex(0), fVariationDesignPosition{nullptr, 0} {} /** Specify a palette to use and overrides for palette entries.
*
* `overrides` is a list of pairs of palette entry index and color.
* The overriden palette entries will use the associated color.
* Override pairs with palette entry indices out of range will not be applied.
* Later override entries override earlier ones.
*/
struct Palette {
struct Override {
int index;
SkColor color;
};
int index;
const Override* overrides;
int overrideCount;
};
SkFontArguments()
: fCollectionIndex(0)
, fVariationDesignPosition{nullptr, 0}
, fPalette{0, nullptr, 0} {}
/** Specify the index of the desired font. /** Specify the index of the desired font.
* *
@ -54,9 +75,20 @@ struct SkFontArguments {
VariationPosition getVariationDesignPosition() const { VariationPosition getVariationDesignPosition() const {
return fVariationDesignPosition; return fVariationDesignPosition;
} }
SkFontArguments& setPalette(Palette palette) {
fPalette.index = palette.index;
fPalette.overrides = palette.overrides;
fPalette.overrideCount = palette.overrideCount;
return *this;
}
Palette getPalette() const { return fPalette; }
private: private:
int fCollectionIndex; int fCollectionIndex;
VariationPosition fVariationDesignPosition; VariationPosition fVariationDesignPosition;
Palette fPalette;
}; };
#endif #endif

View File

@ -22,6 +22,8 @@ enum {
kItalic = 0x13, // scalar (0 is Roman, 1 is fully Italic) kItalic = 0x13, // scalar (0 is Roman, 1 is fully Italic)
// Related to font data. Can also be used with a requested font. // Related to font data. Can also be used with a requested font.
kPaletteIndex = 0xF8, // int
kPaletteEntryOverrides = 0xF9, // int count, (int, u32)[count]
kFontVariation = 0xFA, // int count, (u32, scalar)[count] kFontVariation = 0xFA, // int count, (u32, scalar)[count]
// Related to font data. // Related to font data.
@ -80,6 +82,15 @@ bool SkFontDescriptor::Deserialize(SkStream* stream, SkFontDescriptor* result) {
size_t index; size_t index;
using CollectionIndexType = decltype(result->fCollectionIndex); using CollectionIndexType = decltype(result->fCollectionIndex);
size_t paletteIndex;
using PaletteIndexType = decltype(result->fPaletteIndex);
size_t paletteEntryOverrideCount;
using PaletteEntryOverrideCountType = decltype(result->fPaletteEntryOverrideCount);
size_t paletteEntryOverrideIndex;
using PaletteEntryOverrideIndexType = decltype(result->fPaletteEntryOverrides[0].index);
SkScalar weight = SkFontStyle::kNormal_Weight; SkScalar weight = SkFontStyle::kNormal_Weight;
SkScalar width = SkFontStyle::kNormal_Width; SkScalar width = SkFontStyle::kNormal_Width;
SkScalar slant = 0; SkScalar slant = 0;
@ -131,6 +142,32 @@ bool SkFontDescriptor::Deserialize(SkStream* stream, SkFontDescriptor* result) {
if (!SkTFitsIn<CollectionIndexType>(index)) { return false; } if (!SkTFitsIn<CollectionIndexType>(index)) { return false; }
result->fCollectionIndex = SkTo<CollectionIndexType>(index); result->fCollectionIndex = SkTo<CollectionIndexType>(index);
break; break;
case kPaletteIndex:
if (!stream->readPackedUInt(&paletteIndex)) { return false; }
if (!SkTFitsIn<PaletteIndexType>(paletteIndex)) { return false; }
result->fPaletteIndex = SkTo<PaletteIndexType>(paletteIndex);
break;
case kPaletteEntryOverrides:
if (!stream->readPackedUInt(&paletteEntryOverrideCount)) { return false; }
if (!SkTFitsIn<PaletteEntryOverrideCountType>(paletteEntryOverrideCount)) {
return false;
}
result->fPaletteEntryOverrideCount =
SkTo<PaletteEntryOverrideCountType>(paletteEntryOverrideCount);
result->fPaletteEntryOverrides.reset(paletteEntryOverrideCount);
for (size_t i = 0; i < paletteEntryOverrideCount; ++i) {
if (!stream->readPackedUInt(&paletteEntryOverrideIndex)) { return false; }
if (!SkTFitsIn<PaletteEntryOverrideIndexType>(paletteEntryOverrideIndex)) {
return false;
}
result->fPaletteEntryOverrides[i].index =
SkTo<PaletteEntryOverrideIndexType>(paletteEntryOverrideIndex);
if (!stream->readU32(&result->fPaletteEntryOverrides[i].color)) {
return false;
}
}
break;
default: default:
SkDEBUGFAIL("Unknown id used by a font descriptor"); SkDEBUGFAIL("Unknown id used by a font descriptor");
return false; return false;
@ -172,6 +209,9 @@ void SkFontDescriptor::serialize(SkWStream* stream) const {
if (fCollectionIndex) { if (fCollectionIndex) {
write_uint(stream, fCollectionIndex, kFontIndex); write_uint(stream, fCollectionIndex, kFontIndex);
} }
if (fPaletteIndex) {
write_uint(stream, fPaletteIndex, kPaletteIndex);
}
if (fCoordinateCount) { if (fCoordinateCount) {
write_uint(stream, fCoordinateCount, kFontVariation); write_uint(stream, fCoordinateCount, kFontVariation);
for (int i = 0; i < fCoordinateCount; ++i) { for (int i = 0; i < fCoordinateCount; ++i) {
@ -179,6 +219,13 @@ void SkFontDescriptor::serialize(SkWStream* stream) const {
stream->writeScalar(fVariation[i].value); stream->writeScalar(fVariation[i].value);
} }
} }
if (fPaletteEntryOverrideCount) {
write_uint(stream, fPaletteEntryOverrideCount, kPaletteEntryOverrides);
for (int i = 0; i < fPaletteEntryOverrideCount; ++i) {
stream->writePackedUInt(fPaletteEntryOverrides[i].index);
stream->write32(fPaletteEntryOverrides[i].color);
}
}
stream->writePackedUInt(kSentinel); stream->writePackedUInt(kSentinel);

View File

@ -18,31 +18,40 @@
class SkFontData { class SkFontData {
public: public:
/** Makes a copy of the data in 'axis'. */ /** Makes a copy of the data in 'axis'. */
SkFontData(std::unique_ptr<SkStreamAsset> stream, int index, const SkFixed* axis, int axisCount) SkFontData(std::unique_ptr<SkStreamAsset> stream, int index, int paletteIndex,
: fStream(std::move(stream)), fIndex(index), fAxisCount(axisCount), fAxis(axisCount) const SkFixed* axis, int axisCount,
{ const SkFontArguments::Palette::Override* paletteOverrides, int paletteOverrideCount)
for (int i = 0; i < axisCount; ++i) { : fStream(std::move(stream))
fAxis[i] = axis[i]; , fIndex(index)
} , fPaletteIndex(paletteIndex)
} , fAxisCount(axisCount)
SkFontData(std::unique_ptr<SkStreamAsset> stream, SkFontArguments args) , fPaletteOverrideCount(paletteOverrideCount)
: fStream(std::move(stream)), fIndex(args.getCollectionIndex()) , fAxis(fAxisCount)
, fAxisCount(args.getVariationDesignPosition().coordinateCount) , fPaletteOverrides(fPaletteOverrideCount)
, fAxis(args.getVariationDesignPosition().coordinateCount)
{ {
for (int i = 0; i < fAxisCount; ++i) { for (int i = 0; i < fAxisCount; ++i) {
fAxis[i] = SkFloatToFixed(args.getVariationDesignPosition().coordinates[i].value); fAxis[i] = axis[i];
}
for (int i = 0; i < fPaletteOverrideCount; ++i) {
fPaletteOverrides[i] = paletteOverrides[i];
} }
} }
SkFontData(const SkFontData& that) SkFontData(const SkFontData& that)
: fStream(that.fStream->duplicate()) : fStream(that.fStream->duplicate())
, fIndex(that.fIndex) , fIndex(that.fIndex)
, fPaletteIndex(that.fPaletteIndex)
, fAxisCount(that.fAxisCount) , fAxisCount(that.fAxisCount)
, fPaletteOverrideCount(that.fPaletteOverrideCount)
, fAxis(fAxisCount) , fAxis(fAxisCount)
, fPaletteOverrides(fPaletteOverrideCount)
{ {
for (int i = 0; i < fAxisCount; ++i) { for (int i = 0; i < fAxisCount; ++i) {
fAxis[i] = that.fAxis[i]; fAxis[i] = that.fAxis[i];
} }
for (int i = 0; i < fPaletteOverrideCount; ++i) {
fPaletteOverrides[i] = that.fPaletteOverrides[i];
}
} }
bool hasStream() const { return fStream != nullptr; } bool hasStream() const { return fStream != nullptr; }
std::unique_ptr<SkStreamAsset> detachStream() { return std::move(fStream); } std::unique_ptr<SkStreamAsset> detachStream() { return std::move(fStream); }
@ -51,12 +60,20 @@ public:
int getIndex() const { return fIndex; } int getIndex() const { return fIndex; }
int getAxisCount() const { return fAxisCount; } int getAxisCount() const { return fAxisCount; }
const SkFixed* getAxis() const { return fAxis.get(); } const SkFixed* getAxis() const { return fAxis.get(); }
int getPaletteIndex() const { return fPaletteIndex; }
int getPaletteOverrideCount() const { return fPaletteOverrideCount; }
const SkFontArguments::Palette::Override* getPaletteOverrides() const {
return fPaletteOverrides.get();
}
private: private:
std::unique_ptr<SkStreamAsset> fStream; std::unique_ptr<SkStreamAsset> fStream;
int fIndex; int fIndex;
int fPaletteIndex;
int fAxisCount; int fAxisCount;
int fPaletteOverrideCount;
SkAutoSTMalloc<4, SkFixed> fAxis; SkAutoSTMalloc<4, SkFixed> fAxis;
SkAutoSTMalloc<4, SkFontArguments::Palette::Override> fPaletteOverrides;
}; };
class SkFontDescriptor : SkNoncopyable { class SkFontDescriptor : SkNoncopyable {
@ -81,18 +98,28 @@ public:
bool hasStream() const { return bool(fStream); } bool hasStream() const { return bool(fStream); }
std::unique_ptr<SkStreamAsset> dupStream() const { return fStream->duplicate(); } std::unique_ptr<SkStreamAsset> dupStream() const { return fStream->duplicate(); }
int getCollectionIndex() const { return fCollectionIndex; } int getCollectionIndex() const { return fCollectionIndex; }
int getPaletteIndex() const { return fPaletteIndex; }
int getVariationCoordinateCount() const { return fCoordinateCount; } int getVariationCoordinateCount() const { return fCoordinateCount; }
const SkFontArguments::VariationPosition::Coordinate* getVariation() const { const SkFontArguments::VariationPosition::Coordinate* getVariation() const {
return fVariation.get(); return fVariation.get();
} }
int getPaletteEntryOverrideCount() const { return fPaletteEntryOverrideCount; }
const SkFontArguments::Palette::Override* getPaletteEntryOverrides() {
return fPaletteEntryOverrides.get();
}
std::unique_ptr<SkStreamAsset> detachStream() { return std::move(fStream); } std::unique_ptr<SkStreamAsset> detachStream() { return std::move(fStream); }
void setStream(std::unique_ptr<SkStreamAsset> stream) { fStream = std::move(stream); } void setStream(std::unique_ptr<SkStreamAsset> stream) { fStream = std::move(stream); }
void setCollectionIndex(int collectionIndex) { fCollectionIndex = collectionIndex; } void setCollectionIndex(int collectionIndex) { fCollectionIndex = collectionIndex; }
void setPaleteIndex(int paletteIndex) { fPaletteIndex = paletteIndex; }
SkFontArguments::VariationPosition::Coordinate* setVariationCoordinates(int coordinateCount) { SkFontArguments::VariationPosition::Coordinate* setVariationCoordinates(int coordinateCount) {
fCoordinateCount = coordinateCount; fCoordinateCount = coordinateCount;
return fVariation.reset(coordinateCount); return fVariation.reset(coordinateCount);
} }
SkFontArguments::Palette::Override* setPaletteEntryOverrides(int paletteEntryOverrideCount) {
fPaletteEntryOverrideCount = paletteEntryOverrideCount;
return fPaletteEntryOverrides.reset(paletteEntryOverrideCount);
}
static SkFontStyle::Width SkFontStyleWidthForWidthAxisValue(SkScalar width); static SkFontStyle::Width SkFontStyleWidthForWidthAxisValue(SkScalar width);
@ -107,6 +134,9 @@ private:
using Coordinates = SkAutoSTMalloc<4, SkFontArguments::VariationPosition::Coordinate>; using Coordinates = SkAutoSTMalloc<4, SkFontArguments::VariationPosition::Coordinate>;
int fCoordinateCount = 0; int fCoordinateCount = 0;
Coordinates fVariation; Coordinates fVariation;
int fPaletteIndex = 0;
int fPaletteEntryOverrideCount = 0;
SkAutoTMalloc<SkFontArguments::Palette::Override> fPaletteEntryOverrides;
}; };
#endif // SkFontDescriptor_DEFINED #endif // SkFontDescriptor_DEFINED

View File

@ -222,6 +222,9 @@ sk_sp<SkTypeface> SkTypeface::MakeDeserialize(SkStream* stream) {
SkFontArguments args; SkFontArguments args;
args.setCollectionIndex(desc.getCollectionIndex()); args.setCollectionIndex(desc.getCollectionIndex());
args.setVariationDesignPosition({desc.getVariation(), desc.getVariationCoordinateCount()}); args.setVariationDesignPosition({desc.getVariation(), desc.getVariationCoordinateCount()});
args.setPalette({desc.getPaletteIndex(),
desc.getPaletteEntryOverrides(),
desc.getPaletteEntryOverrideCount()});
sk_sp<SkFontMgr> defaultFm = SkFontMgr::RefDefault(); sk_sp<SkFontMgr> defaultFm = SkFontMgr::RefDefault();
sk_sp<SkTypeface> typeface = defaultFm->makeFromStream(desc.detachStream(), args); sk_sp<SkTypeface> typeface = defaultFm->makeFromStream(desc.detachStream(), args);
if (typeface) { if (typeface) {

View File

@ -188,6 +188,8 @@ public:
SkUniqueFTFace fFace; SkUniqueFTFace fFace;
FT_StreamRec fFTStream; FT_StreamRec fFTStream;
std::unique_ptr<SkStreamAsset> fSkStream; std::unique_ptr<SkStreamAsset> fSkStream;
FT_UShort fFTPaletteEntryCount = 0;
std::unique_ptr<SkColor[]> fSkPalette;
static std::unique_ptr<FaceRec> Make(const SkTypeface_FreeType* typeface); static std::unique_ptr<FaceRec> Make(const SkTypeface_FreeType* typeface);
~FaceRec(); ~FaceRec();
@ -195,6 +197,7 @@ public:
private: private:
FaceRec(std::unique_ptr<SkStreamAsset> stream); FaceRec(std::unique_ptr<SkStreamAsset> stream);
void setupAxes(const SkFontData& data); void setupAxes(const SkFontData& data);
void setupPalette(const SkFontData& data);
// Private to ref_ft_library and unref_ft_library // Private to ref_ft_library and unref_ft_library
static int gFTCount; static int gFTCount;
@ -303,6 +306,44 @@ void SkTypeface_FreeType::FaceRec::setupAxes(const SkFontData& data) {
} }
} }
void SkTypeface_FreeType::FaceRec::setupPalette(const SkFontData& data) {
#ifdef FT_COLOR_H
FT_Palette_Data paletteData;
if (FT_Palette_Data_Get(fFace.get(), &paletteData)) {
return;
}
if (paletteData.num_palettes < data.getPaletteIndex() ) {
return;
}
FT_Color* ftPalette = nullptr;
if (FT_Palette_Select(fFace.get(), data.getPaletteIndex(), &ftPalette)) {
return;
}
fFTPaletteEntryCount = paletteData.num_palette_entries;
for (int i = 0; i < data.getPaletteOverrideCount(); ++i) {
const SkFontArguments::Palette::Override& paletteOverride = data.getPaletteOverrides()[i];
if (paletteOverride.index > fFTPaletteEntryCount) {
continue;
}
const SkColor& skColor = paletteOverride.color;
FT_Color& ftColor = ftPalette[i];
ftColor.blue = SkColorGetB(skColor);
ftColor.green = SkColorGetG(skColor);
ftColor.red = SkColorGetR(skColor);
ftColor.alpha = SkColorGetA(skColor);
}
fSkPalette.reset(new SkColor[fFTPaletteEntryCount]);
for (int i = 0; i < fFTPaletteEntryCount; ++i) {
fSkPalette[i] = SkColorSetARGB(ftPalette[i].alpha,
ftPalette[i].red,
ftPalette[i].green,
ftPalette[i].blue);
}
#endif
}
// Will return nullptr on failure // Will return nullptr on failure
// Caller must lock f_t_mutex() before calling this function. // Caller must lock f_t_mutex() before calling this function.
std::unique_ptr<SkTypeface_FreeType::FaceRec> std::unique_ptr<SkTypeface_FreeType::FaceRec>
@ -340,6 +381,7 @@ SkTypeface_FreeType::FaceRec::Make(const SkTypeface_FreeType* typeface) {
SkASSERT(rec->fFace); SkASSERT(rec->fFace);
rec->setupAxes(*data); rec->setupAxes(*data);
rec->setupPalette(*data);
// FreeType will set the charmap to the "most unicode" cmap if it exists. // FreeType will set the charmap to the "most unicode" cmap if it exists.
// If there are no unicode cmaps, the charmap is set to nullptr. // If there are no unicode cmaps, the charmap is set to nullptr.
@ -663,9 +705,17 @@ std::unique_ptr<SkFontData> SkTypeface_FreeType::cloneFontData(const SkFontArgum
SkAutoSTMalloc<4, SkFixed> axisValues(axisCount); SkAutoSTMalloc<4, SkFixed> axisValues(axisCount);
Scanner::computeAxisValues(axisDefinitions, args.getVariationDesignPosition(), axisValues, name, Scanner::computeAxisValues(axisDefinitions, args.getVariationDesignPosition(), axisValues, name,
currentAxisCount == axisCount ? currentPosition.get() : nullptr); currentAxisCount == axisCount ? currentPosition.get() : nullptr);
int ttcIndex; int ttcIndex;
std::unique_ptr<SkStreamAsset> stream = this->openStream(&ttcIndex); std::unique_ptr<SkStreamAsset> stream = this->openStream(&ttcIndex);
return std::make_unique<SkFontData>(std::move(stream), ttcIndex, axisValues.get(), axisCount);
return std::make_unique<SkFontData>(std::move(stream),
ttcIndex,
args.getPalette().index,
axisValues.get(),
axisCount,
args.getPalette().overrides,
args.getPalette().overrideCount);
} }
void SkTypeface_FreeType::onFilterRec(SkScalerContextRec* rec) const { void SkTypeface_FreeType::onFilterRec(SkScalerContextRec* rec) const {
@ -945,10 +995,6 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(sk_sp<SkTypeface_FreeType> ty
fMatrix22.yx = SkScalarToFixed(-fMatrix22Scalar.getSkewY()); fMatrix22.yx = SkScalarToFixed(-fMatrix22Scalar.getSkewY());
fMatrix22.yy = SkScalarToFixed(fMatrix22Scalar.getScaleY()); fMatrix22.yy = SkScalarToFixed(fMatrix22Scalar.getScaleY());
#ifdef FT_COLOR_H
FT_Palette_Select(fFaceRec->fFace.get(), 0, nullptr);
#endif
fFTSize = ftSize.release(); fFTSize = ftSize.release();
fFace = fFaceRec->fFace.get(); fFace = fFaceRec->fFace.get();
fDoLinearMetrics = linearMetrics; fDoLinearMetrics = linearMetrics;
@ -1333,7 +1379,9 @@ void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) {
SkFixedToScalar(glyph.getSubYFixed())); SkFixedToScalar(glyph.getSubYFixed()));
bitmapMatrix = &subpixelBitmapMatrix; bitmapMatrix = &subpixelBitmapMatrix;
} }
generateGlyphImage(fFace, glyph, *bitmapMatrix);
SkSpan<SkColor> palette(fFaceRec->fSkPalette.get(), fFaceRec->fFTPaletteEntryCount);
generateGlyphImage(fFace, palette, glyph, *bitmapMatrix);
} }
sk_sp<SkDrawable> SkScalerContext_FreeType::generateDrawable(const SkGlyph& glyph) { sk_sp<SkDrawable> SkScalerContext_FreeType::generateDrawable(const SkGlyph& glyph) {
@ -1360,7 +1408,8 @@ sk_sp<SkDrawable> SkScalerContext_FreeType::generateDrawable(const SkGlyph& glyp
} }
emboldenIfNeeded(fFace, fFace->glyph, glyph.getGlyphID()); emboldenIfNeeded(fFace, fFace->glyph, glyph.getGlyphID());
return generateGlyphDrawable(fFace, glyph); SkSpan<SkColor> palette(fFaceRec->fSkPalette.get(), fFaceRec->fFTPaletteEntryCount);
return generateGlyphDrawable(fFace, palette, glyph);
} }
bool SkScalerContext_FreeType::generatePath(const SkGlyph& glyph, SkPath* path) { bool SkScalerContext_FreeType::generatePath(const SkGlyph& glyph, SkPath* path) {
@ -1822,6 +1871,16 @@ std::unique_ptr<SkFontData> SkTypeface_FreeType::makeFontData() const {
return this->onMakeFontData(); return this->onMakeFontData();
} }
void SkTypeface_FreeType::FontDataPaletteToDescriptorPalette(const SkFontData& fontData,
SkFontDescriptor* desc) {
desc->setPaleteIndex(fontData.getPaletteIndex());
int paletteOverrideCount = fontData.getPaletteOverrideCount();
auto overrides = desc->setPaletteEntryOverrides(paletteOverrideCount);
for (int i = 0; i < paletteOverrideCount; ++i) {
overrides[i] = fontData.getPaletteOverrides()[i];
}
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -1239,41 +1239,15 @@ bool colrv1_start_glyph_bounds(SkMatrix *ctm,
#ifdef FT_COLOR_H #ifdef FT_COLOR_H
bool SkScalerContext_FreeType_Base::drawColorGlyph(SkCanvas* canvas, bool SkScalerContext_FreeType_Base::drawColorGlyph(SkCanvas* canvas,
FT_Face face, FT_Face face,
SkSpan<SkColor> palette,
const SkGlyph& glyph) { const SkGlyph& glyph) {
SkPaint paint; SkPaint paint;
paint.setAntiAlias(true); paint.setAntiAlias(true);
FT_Palette_Data palette_data;
FT_Error err = FT_Palette_Data_Get(face, &palette_data);
if (err) {
SK_TRACEFTR(err, "Could not get palette data from %s fontFace.",
face->family_name);
return false;
}
SkAutoTArray<SkColor> originalPalette;
FT_Color* ftPalette;
err = FT_Palette_Select(face, 0, &ftPalette);
if (err) {
SK_TRACEFTR(err, "Could not get palette colors from %s fontFace.",
face->family_name);
return false;
}
originalPalette.reset(palette_data.num_palette_entries);
for (int i = 0; i < palette_data.num_palette_entries; ++i) {
originalPalette[i] = SkColorSetARGB(ftPalette[i].alpha,
ftPalette[i].red,
ftPalette[i].green,
ftPalette[i].blue);
}
SkSpan<SkColor> paletteSpan(originalPalette.data(),
palette_data.num_palette_entries);
// Only attempt to draw a COLRv1 glyph if FreeType is new enough to have the COLRv1 support. // Only attempt to draw a COLRv1 glyph if FreeType is new enough to have the COLRv1 support.
#ifdef TT_SUPPORT_COLRV1 #ifdef TT_SUPPORT_COLRV1
VisitedSet visited_set; VisitedSet visited_set;
if (colrv1_start_glyph(canvas, paletteSpan, if (colrv1_start_glyph(canvas, palette,
fRec.fForegroundColor, fRec.fForegroundColor,
face, glyph.getGlyphID(), face, glyph.getGlyphID(),
FT_COLOR_INCLUDE_ROOT_TRANSFORM, FT_COLOR_INCLUDE_ROOT_TRANSFORM,
@ -1295,7 +1269,7 @@ bool SkScalerContext_FreeType_Base::drawColorGlyph(SkCanvas* canvas,
if (layerColorIndex == 0xFFFF) { if (layerColorIndex == 0xFFFF) {
paint.setColor(fRec.fForegroundColor); paint.setColor(fRec.fForegroundColor);
} else { } else {
paint.setColor(paletteSpan[layerColorIndex]); paint.setColor(palette[layerColorIndex]);
} }
SkPath path; SkPath path;
if (this->generateFacePath(face, layerGlyphIndex, &path)) { if (this->generateFacePath(face, layerGlyphIndex, &path)) {
@ -1308,6 +1282,7 @@ bool SkScalerContext_FreeType_Base::drawColorGlyph(SkCanvas* canvas,
void SkScalerContext_FreeType_Base::generateGlyphImage( void SkScalerContext_FreeType_Base::generateGlyphImage(
FT_Face face, FT_Face face,
SkSpan<SkColor> customPalette,
const SkGlyph& glyph, const SkGlyph& glyph,
const SkMatrix& bitmapTransform) const SkMatrix& bitmapTransform)
{ {
@ -1352,7 +1327,7 @@ void SkScalerContext_FreeType_Base::generateGlyphImage(
SkFixedToScalar(glyph.getSubYFixed())); SkFixedToScalar(glyph.getSubYFixed()));
} }
bool haveLayers = this->drawColorGlyph(&canvas, face, glyph); bool haveLayers = this->drawColorGlyph(&canvas, face, customPalette, glyph);
if (!haveLayers) { if (!haveLayers) {
SkDebugf("Could not get layers (neither v0, nor v1) from %s fontFace.", SkDebugf("Could not get layers (neither v0, nor v1) from %s fontFace.",
@ -1788,13 +1763,13 @@ bool SkScalerContext_FreeType_Base::computeColrV1GlyphBoundingBox(FT_Face face,
#endif #endif
} }
sk_sp<SkDrawable> SkScalerContext_FreeType_Base::generateGlyphDrawable(FT_Face face, sk_sp<SkDrawable> SkScalerContext_FreeType_Base::generateGlyphDrawable(
const SkGlyph& glyph) { FT_Face face, SkSpan<SkColor> palette, const SkGlyph& glyph) {
#ifdef FT_COLOR_H #ifdef FT_COLOR_H
if (face->glyph->format == FT_GLYPH_FORMAT_OUTLINE && glyph.isColor()) { if (face->glyph->format == FT_GLYPH_FORMAT_OUTLINE && glyph.isColor()) {
SkPictureRecorder recorder; SkPictureRecorder recorder;
SkCanvas* recordingCanvas = recorder.beginRecording(SkRect::Make(glyph.mask().fBounds)); SkCanvas* recordingCanvas = recorder.beginRecording(SkRect::Make(glyph.mask().fBounds));
if (!this->drawColorGlyph(recordingCanvas, face, glyph)) { if (!this->drawColorGlyph(recordingCanvas, face, palette, glyph)) {
return nullptr; return nullptr;
} }
return recorder.finishRecordingAsDrawable(); return recorder.finishRecordingAsDrawable();

View File

@ -47,11 +47,14 @@ protected:
: INHERITED(std::move(typeface), effects, desc) : INHERITED(std::move(typeface), effects, desc)
{} {}
bool drawColorGlyph(SkCanvas*, FT_Face, const SkGlyph&); bool drawColorGlyph(SkCanvas*, FT_Face, SkSpan<SkColor> palette, const SkGlyph&);
void generateGlyphImage(FT_Face face, const SkGlyph& glyph, const SkMatrix& bitmapTransform); void generateGlyphImage(FT_Face face,
SkSpan<SkColor> palette,
const SkGlyph& glyph,
const SkMatrix& bitmapTransform);
bool generateGlyphPath(FT_Face face, SkPath* path); bool generateGlyphPath(FT_Face face, SkPath* path);
bool generateFacePath(FT_Face face, SkGlyphID glyphID, SkPath* path); bool generateFacePath(FT_Face face, SkGlyphID glyphID, SkPath* path);
sk_sp<SkDrawable> generateGlyphDrawable(FT_Face face, const SkGlyph&); sk_sp<SkDrawable> generateGlyphDrawable(FT_Face face, SkSpan<SkColor> palette, const SkGlyph&);
// Computes a bounding box for a COLRv1 glyph id in FT_BBox 26.6 format and FreeType's y-up // Computes a bounding box for a COLRv1 glyph id in FT_BBox 26.6 format and FreeType's y-up
// coordinate space. // coordinate space.
@ -93,7 +96,6 @@ public:
const SkString& name, const SkString& name,
const SkFontArguments::VariationPosition::Coordinate* currentPosition = nullptr); const SkFontArguments::VariationPosition::Coordinate* currentPosition = nullptr);
static bool GetAxes(FT_Face face, AxisDefinitions* axes); static bool GetAxes(FT_Face face, AxisDefinitions* axes);
private: private:
FT_Face openFace(SkStreamAsset* stream, int ttcIndex, FT_Stream ftStream) const; FT_Face openFace(SkStreamAsset* stream, int ttcIndex, FT_Stream ftStream) const;
FT_Library fLibrary; FT_Library fLibrary;
@ -103,9 +105,7 @@ public:
/** Fetch units/EM from "head" table if needed (ie for bitmap fonts) */ /** Fetch units/EM from "head" table if needed (ie for bitmap fonts) */
static int GetUnitsPerEm(FT_Face face); static int GetUnitsPerEm(FT_Face face);
/** /** Return the font data, or nullptr on failure. */
* Return the font data, or nullptr on failure.
*/
std::unique_ptr<SkFontData> makeFontData() const; std::unique_ptr<SkFontData> makeFontData() const;
class FaceRec; class FaceRec;
FaceRec* getFaceRec() const; FaceRec* getFaceRec() const;
@ -141,6 +141,8 @@ protected:
sk_sp<SkData> onCopyTableData(SkFontTableTag) const override; sk_sp<SkData> onCopyTableData(SkFontTableTag) const override;
virtual std::unique_ptr<SkFontData> onMakeFontData() const = 0; virtual std::unique_ptr<SkFontData> onMakeFontData() const = 0;
/** Utility to fill out the SkFontDescriptor palette information from the SkFontData. */
static void FontDataPaletteToDescriptorPalette(const SkFontData&, SkFontDescriptor*);
private: private:
mutable SkOnce fFTFaceOnce; mutable SkOnce fFTFaceOnce;

View File

@ -39,7 +39,7 @@ std::unique_ptr<SkFontData> SkTypeface_FCI::onMakeFontData() const {
const SkFontConfigInterface::FontIdentity& id = this->getIdentity(); const SkFontConfigInterface::FontIdentity& id = this->getIdentity();
return std::make_unique<SkFontData>(std::unique_ptr<SkStreamAsset>(fFCI->openStream(id)), return std::make_unique<SkFontData>(std::unique_ptr<SkStreamAsset>(fFCI->openStream(id)),
id.fTTCIndex, nullptr, 0); id.fTTCIndex, 0, nullptr, 0, nullptr, 0);
} }
void SkTypeface_FCI::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocalStream) const { void SkTypeface_FCI::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocalStream) const {
@ -47,6 +47,9 @@ void SkTypeface_FCI::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocalSt
this->getFamilyName(&name); this->getFamilyName(&name);
desc->setFamilyName(name.c_str()); desc->setFamilyName(name.c_str());
desc->setStyle(this->fontStyle()); desc->setStyle(this->fontStyle());
if (fFontData) {
SkTypeface_FreeType::FontDataPaletteToDescriptorPalette(*fFontData, desc);
}
*isLocalStream = SkToBool(fFontData); *isLocalStream = SkToBool(fFontData);
} }
@ -239,7 +242,8 @@ protected:
return nullptr; return nullptr;
} }
auto fontData = std::make_unique<SkFontData>(std::move(stream), ttcIndex, nullptr, 0); auto fontData = std::make_unique<SkFontData>(std::move(stream), ttcIndex, 0,
nullptr, 0, nullptr, 0);
return sk_sp<SkTypeface>(SkTypeface_FCI::Create(std::move(fontData), std::move(name), return sk_sp<SkTypeface>(SkTypeface_FCI::Create(std::move(fontData), std::move(name),
style, isFixedPitch)); style, isFixedPitch));
} }
@ -271,8 +275,11 @@ protected:
auto fontData = std::make_unique<SkFontData>(std::move(stream), auto fontData = std::make_unique<SkFontData>(std::move(stream),
args.getCollectionIndex(), args.getCollectionIndex(),
args.getPalette().index,
axisValues.get(), axisValues.get(),
axisDefinitions.count()); axisDefinitions.count(),
args.getPalette().overrides,
args.getPalette().overrideCount);
return sk_sp<SkTypeface>(SkTypeface_FCI::Create(std::move(fontData), std::move(name), return sk_sp<SkTypeface>(SkTypeface_FCI::Create(std::move(fontData), std::move(name),
style, isFixedPitch)); style, isFixedPitch));
} }

View File

@ -94,8 +94,8 @@ public:
return this->makeStream(); return this->makeStream();
} }
std::unique_ptr<SkFontData> onMakeFontData() const override { std::unique_ptr<SkFontData> onMakeFontData() const override {
return std::make_unique<SkFontData>(this->makeStream(), fIndex, return std::make_unique<SkFontData>(
fAxes.begin(), fAxes.count()); this->makeStream(), fIndex, 0, fAxes.begin(), fAxes.count(), nullptr, 0);
} }
sk_sp<SkTypeface> onMakeClone(const SkFontArguments& args) const override { sk_sp<SkTypeface> onMakeClone(const SkFontArguments& args) const override {
std::unique_ptr<SkFontData> data = this->cloneFontData(args); std::unique_ptr<SkFontData> data = this->cloneFontData(args);
@ -138,6 +138,7 @@ public:
SkASSERT(desc); SkASSERT(desc);
SkASSERT(serialize); SkASSERT(serialize);
desc->setFamilyName(fFamilyName.c_str()); desc->setFamilyName(fFamilyName.c_str());
SkTypeface_FreeType::FontDataPaletteToDescriptorPalette(*fData, desc);
*serialize = true; *serialize = true;
} }
@ -448,7 +449,8 @@ protected:
if (!fScanner.scanFont(stream.get(), ttcIndex, &name, &style, &isFixedPitch, nullptr)) { if (!fScanner.scanFont(stream.get(), ttcIndex, &name, &style, &isFixedPitch, nullptr)) {
return nullptr; return nullptr;
} }
auto data = std::make_unique<SkFontData>(std::move(stream), ttcIndex, nullptr, 0); auto data = std::make_unique<SkFontData>(std::move(stream), ttcIndex, 0,
nullptr, 0, nullptr, 0);
return sk_sp<SkTypeface>(new SkTypeface_AndroidStream(std::move(data), return sk_sp<SkTypeface>(new SkTypeface_AndroidStream(std::move(data),
style, isFixedPitch, name)); style, isFixedPitch, name));
} }
@ -470,8 +472,10 @@ protected:
Scanner::computeAxisValues(axisDefinitions, args.getVariationDesignPosition(), Scanner::computeAxisValues(axisDefinitions, args.getVariationDesignPosition(),
axisValues, name); axisValues, name);
auto data = std::make_unique<SkFontData>(std::move(stream), args.getCollectionIndex(), auto data = std::make_unique<SkFontData>(
axisValues.get(), axisDefinitions.count()); std::move(stream), args.getCollectionIndex(), args.getPalette().index,
axisValues.get(), axisDefinitions.count(),
args.getPalette().overrides, args.getPalette().overrideCount);
return sk_sp<SkTypeface>(new SkTypeface_AndroidStream(std::move(data), return sk_sp<SkTypeface>(new SkTypeface_AndroidStream(std::move(data),
style, isFixedPitch, name)); style, isFixedPitch, name));
} }

View File

@ -87,6 +87,11 @@ sk_sp<SkTypeface> SkTypeface_Stream::onMakeClone(const SkFontArguments& args) co
familyName); familyName);
} }
void SkTypeface_Stream::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
this->SkTypeface_Custom::onGetFontDescriptor(desc, isLocal);
SkTypeface_FreeType::FontDataPaletteToDescriptorPalette(*fData, desc);
}
SkTypeface_File::SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont, SkTypeface_File::SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
const SkString familyName, const char path[], int index) const SkString familyName, const char path[], int index)
: INHERITED(style, isFixedPitch, sysFont, familyName, index) : INHERITED(style, isFixedPitch, sysFont, familyName, index)
@ -120,7 +125,7 @@ std::unique_ptr<SkFontData> SkTypeface_File::onMakeFontData() const {
if (!stream) { if (!stream) {
return nullptr; return nullptr;
} }
return std::make_unique<SkFontData>(std::move(stream), index, nullptr, 0); return std::make_unique<SkFontData>(std::move(stream), index, 0, nullptr, 0, nullptr, 0);
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -240,8 +245,7 @@ sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamArgs(std::unique_ptr<SkStrea
SkString name; SkString name;
Scanner::AxisDefinitions axisDefinitions; Scanner::AxisDefinitions axisDefinitions;
if (!fScanner.scanFont(stream.get(), args.getCollectionIndex(), if (!fScanner.scanFont(stream.get(), args.getCollectionIndex(),
&name, &style, &isFixedPitch, &axisDefinitions)) &name, &style, &isFixedPitch, &axisDefinitions)) {
{
return nullptr; return nullptr;
} }
@ -249,8 +253,10 @@ sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamArgs(std::unique_ptr<SkStrea
SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count()); SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
Scanner::computeAxisValues(axisDefinitions, position, axisValues, name); Scanner::computeAxisValues(axisDefinitions, position, axisValues, name);
auto data = std::make_unique<SkFontData>(std::move(stream), args.getCollectionIndex(), auto data = std::make_unique<SkFontData>(
axisValues.get(), axisDefinitions.count()); std::move(stream), args.getCollectionIndex(), args.getPalette().index,
axisValues.get(), axisDefinitions.count(),
args.getPalette().overrides, args.getPalette().overrideCount);
return sk_sp<SkTypeface>(new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name)); return sk_sp<SkTypeface>(new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name));
} }

View File

@ -68,6 +68,7 @@ protected:
std::unique_ptr<SkStreamAsset> onOpenStream(int* ttcIndex) const override; std::unique_ptr<SkStreamAsset> onOpenStream(int* ttcIndex) const override;
std::unique_ptr<SkFontData> onMakeFontData() const override; std::unique_ptr<SkFontData> onMakeFontData() const override;
sk_sp<SkTypeface> onMakeClone(const SkFontArguments& args) const override; sk_sp<SkTypeface> onMakeClone(const SkFontArguments& args) const override;
void onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const override;
private: private:
const std::unique_ptr<const SkFontData> fData; const std::unique_ptr<const SkFontData> fData;

View File

@ -99,7 +99,8 @@ static void load_font_from_data(const SkTypeface_FreeType::Scanner& scanner,
addTo = new SkFontStyleSet_Custom(realname); addTo = new SkFontStyleSet_Custom(realname);
families->push_back().reset(addTo); families->push_back().reset(addTo);
} }
auto data = std::make_unique<SkFontData>(stream->duplicate(), faceIndex, nullptr, 0); auto data = std::make_unique<SkFontData>(stream->duplicate(), faceIndex, 0,
nullptr, 0, nullptr, 0);
addTo->appendTypeface(sk_make_sp<SkTypeface_Stream>(std::move(data), addTo->appendTypeface(sk_make_sp<SkTypeface_Stream>(std::move(data),
style, isFixedPitch, style, isFixedPitch,
true, realname)); true, realname));

View File

@ -410,6 +410,7 @@ public:
} }
void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const override { void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const override {
SkTypeface_FreeType::FontDataPaletteToDescriptorPalette(*fData, desc);
*serialize = true; *serialize = true;
} }
@ -541,7 +542,7 @@ public:
return nullptr; return nullptr;
} }
// TODO: FC_VARIABLE and FC_FONT_VARIATIONS // TODO: FC_VARIABLE and FC_FONT_VARIATIONS
return std::make_unique<SkFontData>(std::move(stream), index, nullptr, 0); return std::make_unique<SkFontData>(std::move(stream), index, 0, nullptr, 0, nullptr, 0);
} }
~SkTypeface_fontconfig() override { ~SkTypeface_fontconfig() override {
@ -966,7 +967,8 @@ protected:
return nullptr; return nullptr;
} }
auto data = std::make_unique<SkFontData>(std::move(stream), ttcIndex, nullptr, 0); auto data = std::make_unique<SkFontData>(std::move(stream), ttcIndex, 0,
nullptr, 0, nullptr, 0);
return sk_sp<SkTypeface>(new SkTypeface_stream(std::move(data), std::move(name), return sk_sp<SkTypeface>(new SkTypeface_stream(std::move(data), std::move(name),
style, isFixedWidth)); style, isFixedWidth));
} }
@ -988,8 +990,10 @@ protected:
Scanner::computeAxisValues(axisDefinitions, args.getVariationDesignPosition(), Scanner::computeAxisValues(axisDefinitions, args.getVariationDesignPosition(),
axisValues, name); axisValues, name);
auto data = std::make_unique<SkFontData>(std::move(stream), args.getCollectionIndex(), auto data = std::make_unique<SkFontData>(
axisValues.get(), axisDefinitions.count()); std::move(stream), args.getCollectionIndex(), args.getPalette().index,
axisValues.get(), axisDefinitions.count(),
args.getPalette().overrides, args.getPalette().overrideCount);
return sk_sp<SkTypeface>(new SkTypeface_stream(std::move(data), std::move(name), return sk_sp<SkTypeface>(new SkTypeface_stream(std::move(data), std::move(name),
style, isFixedPitch)); style, isFixedPitch));
} }

View File

@ -217,8 +217,10 @@ sk_sp<SkTypeface> CreateTypefaceFromSkStream(std::unique_ptr<SkStreamAsset> stre
SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count()); SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
Scanner::computeAxisValues(axisDefinitions, position, axisValues, name); Scanner::computeAxisValues(axisDefinitions, position, axisValues, name);
auto fontData = std::make_unique<SkFontData>(std::move(stream), args.getCollectionIndex(), auto fontData = std::make_unique<SkFontData>(
axisValues.get(), axisDefinitions.count()); std::move(stream), args.getCollectionIndex(), args.getPalette().index,
axisValues.get(), axisDefinitions.count(),
args.getPalette().overrides, args.getPalette().overrideCount);
return sk_make_sp<SkTypeface_Fuchsia>(std::move(fontData), style, isFixedPitch, name, id); return sk_make_sp<SkTypeface_Fuchsia>(std::move(fontData), style, isFixedPitch, name, id);
} }