[skottie,skshaper] Plumb an optional SkFontMgr in SkShaper/SkottieShaper
Skottie already takes an optional client fontmgr at load time, but SkShaper(HB) currently uses the default fontmgr for fallback. Plumb the Skottie font manager all the way to SkShaper. This should give clients more control over font fallback, instead of relying on the default SkFontMgr. Change-Id: I3df16b3924a68d232573e25f9e526f523fc1dc08 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/230122 Commit-Queue: Florin Malita <fmalita@chromium.org> Reviewed-by: Ben Wagner aka dogben <benjaminwagner@google.com>
This commit is contained in:
parent
c561189af9
commit
426843323f
@ -65,6 +65,7 @@ if (skia_enable_skottie) {
|
||||
":skottie",
|
||||
"../..:gpu_tool_utils",
|
||||
"../..:skia",
|
||||
"../skshaper",
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "include/core/SkFontMgr.h"
|
||||
#include "include/core/SkMatrix.h"
|
||||
#include "include/core/SkStream.h"
|
||||
#include "include/core/SkTextBlob.h"
|
||||
@ -12,9 +13,10 @@
|
||||
#include "modules/skottie/include/Skottie.h"
|
||||
#include "modules/skottie/include/SkottieProperty.h"
|
||||
#include "modules/skottie/src/text/SkottieShaper.h"
|
||||
#include "src/core/SkFontDescriptor.h"
|
||||
#include "src/core/SkTextBlobPriv.h"
|
||||
|
||||
#include "tests/Test.h"
|
||||
#include "tools/ToolUtils.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <tuple>
|
||||
@ -300,7 +302,8 @@ DEF_TEST(Skottie_Shaper_HAlign, reporter) {
|
||||
Shaper::Flags::kNone
|
||||
};
|
||||
|
||||
const auto shape_result = skottie::Shaper::Shape(text, desc, text_point);
|
||||
const auto shape_result = skottie::Shaper::Shape(text, desc, text_point,
|
||||
SkFontMgr::RefDefault());
|
||||
REPORTER_ASSERT(reporter, shape_result.fFragments.size() == 1ul);
|
||||
REPORTER_ASSERT(reporter, shape_result.fFragments[0].fBlob);
|
||||
|
||||
@ -364,7 +367,8 @@ DEF_TEST(Skottie_Shaper_VAlign, reporter) {
|
||||
Shaper::Flags::kNone
|
||||
};
|
||||
|
||||
const auto shape_result = skottie::Shaper::Shape(text, desc, text_box);
|
||||
const auto shape_result = skottie::Shaper::Shape(text, desc, text_box,
|
||||
SkFontMgr::RefDefault());
|
||||
REPORTER_ASSERT(reporter, shape_result.fFragments.size() == 1ul);
|
||||
REPORTER_ASSERT(reporter, shape_result.fFragments[0].fBlob);
|
||||
|
||||
@ -403,7 +407,8 @@ DEF_TEST(Skottie_Shaper_FragmentGlyphs, reporter) {
|
||||
const auto text_box = SkRect::MakeWH(100, 100);
|
||||
|
||||
{
|
||||
const auto shape_result = skottie::Shaper::Shape(text, desc, text_box);
|
||||
const auto shape_result = skottie::Shaper::Shape(text, desc, text_box,
|
||||
SkFontMgr::RefDefault());
|
||||
// Default/consolidated mode => single blob result.
|
||||
REPORTER_ASSERT(reporter, shape_result.fFragments.size() == 1ul);
|
||||
REPORTER_ASSERT(reporter, shape_result.fFragments[0].fBlob);
|
||||
@ -411,7 +416,8 @@ DEF_TEST(Skottie_Shaper_FragmentGlyphs, reporter) {
|
||||
|
||||
{
|
||||
desc.fFlags = Shaper::Flags::kFragmentGlyphs;
|
||||
const auto shape_result = skottie::Shaper::Shape(text, desc, text_box);
|
||||
const auto shape_result = skottie::Shaper::Shape(text, desc, text_box,
|
||||
SkFontMgr::RefDefault());
|
||||
// Fragmented mode => one blob per glyph.
|
||||
const size_t expectedSize = text.size();
|
||||
REPORTER_ASSERT(reporter, shape_result.fFragments.size() == expectedSize);
|
||||
@ -420,3 +426,97 @@ DEF_TEST(Skottie_Shaper_FragmentGlyphs, reporter) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(SK_SHAPER_HARFBUZZ_AVAILABLE) && !defined(SK_BUILD_FOR_WIN)
|
||||
|
||||
DEF_TEST(Skottie_Shaper_ExplicitFontMgr, reporter) {
|
||||
class CountingFontMgr : public SkFontMgr {
|
||||
public:
|
||||
size_t fallbackCount() const { return fFallbackCount; }
|
||||
|
||||
protected:
|
||||
int onCountFamilies() const override { return 0; }
|
||||
void onGetFamilyName(int index, SkString* familyName) const override {
|
||||
SkDEBUGFAIL("onGetFamilyName called with bad index");
|
||||
}
|
||||
SkFontStyleSet* onCreateStyleSet(int index) const override {
|
||||
SkDEBUGFAIL("onCreateStyleSet called with bad index");
|
||||
return nullptr;
|
||||
}
|
||||
SkFontStyleSet* onMatchFamily(const char[]) const override {
|
||||
return SkFontStyleSet::CreateEmpty();
|
||||
}
|
||||
|
||||
SkTypeface* onMatchFamilyStyle(const char[], const SkFontStyle&) const override {
|
||||
return nullptr;
|
||||
}
|
||||
SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
|
||||
const SkFontStyle& style,
|
||||
const char* bcp47[],
|
||||
int bcp47Count,
|
||||
SkUnichar character) const override {
|
||||
fFallbackCount++;
|
||||
return nullptr;
|
||||
}
|
||||
SkTypeface* onMatchFaceStyle(const SkTypeface*, const SkFontStyle&) const override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sk_sp<SkTypeface> onMakeFromData(sk_sp<SkData>, int) const override {
|
||||
return nullptr;
|
||||
}
|
||||
sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset>, int) const override {
|
||||
return nullptr;
|
||||
}
|
||||
sk_sp<SkTypeface> onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset>,
|
||||
const SkFontArguments&) const override {
|
||||
return nullptr;
|
||||
}
|
||||
sk_sp<SkTypeface> onMakeFromFontData(std::unique_ptr<SkFontData>) const override {
|
||||
return nullptr;
|
||||
}
|
||||
sk_sp<SkTypeface> onMakeFromFile(const char[], int) const override {
|
||||
return nullptr;
|
||||
}
|
||||
sk_sp<SkTypeface> onLegacyMakeTypeface(const char [], SkFontStyle) const override {
|
||||
return nullptr;
|
||||
}
|
||||
private:
|
||||
mutable size_t fFallbackCount = 0;
|
||||
};
|
||||
|
||||
auto fontmgr = sk_make_sp<CountingFontMgr>();
|
||||
|
||||
skottie::Shaper::TextDesc desc = {
|
||||
ToolUtils::create_portable_typeface(),
|
||||
18,
|
||||
18,
|
||||
0,
|
||||
SkTextUtils::Align::kCenter_Align,
|
||||
Shaper::VAlign::kTop,
|
||||
Shaper::Flags::kNone
|
||||
};
|
||||
|
||||
const auto text_box = SkRect::MakeWH(100, 100);
|
||||
|
||||
{
|
||||
const auto shape_result = skottie::Shaper::Shape(SkString("foo bar"),
|
||||
desc, text_box, fontmgr);
|
||||
|
||||
REPORTER_ASSERT(reporter, shape_result.fFragments.size() == 1ul);
|
||||
REPORTER_ASSERT(reporter, shape_result.fFragments[0].fBlob);
|
||||
REPORTER_ASSERT(reporter, fontmgr->fallbackCount() == 0ul);
|
||||
}
|
||||
|
||||
{
|
||||
// An unassigned codepoint should trigger fallback.
|
||||
const auto shape_result = skottie::Shaper::Shape(SkString("foo\U000DFFFFbar"),
|
||||
desc, text_box, fontmgr);
|
||||
|
||||
REPORTER_ASSERT(reporter, shape_result.fFragments.size() == 1ul);
|
||||
REPORTER_ASSERT(reporter, shape_result.fFragments[0].fBlob);
|
||||
REPORTER_ASSERT(reporter, fontmgr->fallbackCount() == 1ul);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -291,7 +291,7 @@ sk_sp<sksg::RenderNode> AnimationBuilder::attachTextLayer(const skjson::ObjectVa
|
||||
}
|
||||
|
||||
auto text_root = sksg::Group::Make();
|
||||
auto adapter = sk_make_sp<TextAdapter>(text_root, has_animators);
|
||||
auto adapter = sk_make_sp<TextAdapter>(text_root, fLazyFontMgr.getMaybeNull(), has_animators);
|
||||
|
||||
this->bindProperty<TextValue>(*jd,
|
||||
[adapter] (const TextValue& txt) {
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "modules/skottie/src/text/SkottieShaper.h"
|
||||
|
||||
#include "include/core/SkFontMetrics.h"
|
||||
#include "include/core/SkFontMgr.h"
|
||||
#include "include/core/SkTextBlob.h"
|
||||
#include "include/private/SkTemplates.h"
|
||||
#include "modules/skshaper/include/SkShaper.h"
|
||||
@ -48,12 +49,12 @@ SkRect ComputeBlobBounds(const sk_sp<SkTextBlob>& blob) {
|
||||
// per-line position adjustments (for external line breaking, horizontal alignment, etc).
|
||||
class BlobMaker final : public SkShaper::RunHandler {
|
||||
public:
|
||||
BlobMaker(const Shaper::TextDesc& desc, const SkRect& box)
|
||||
BlobMaker(const Shaper::TextDesc& desc, const SkRect& box, const sk_sp<SkFontMgr>& fontmgr)
|
||||
: fDesc(desc)
|
||||
, fBox(box)
|
||||
, fHAlignFactor(HAlignFactor(fDesc.fHAlign))
|
||||
, fFont(fDesc.fTypeface, fDesc.fTextSize)
|
||||
, fShaper(SkShaper::Make()) {
|
||||
, fShaper(SkShaper::Make(fontmgr)) {
|
||||
fFont.setHinting(SkFontHinting::kNone);
|
||||
fFont.setSubpixel(true);
|
||||
fFont.setLinearMetrics(true);
|
||||
@ -314,7 +315,8 @@ private:
|
||||
};
|
||||
|
||||
Shaper::Result ShapeImpl(const SkString& txt, const Shaper::TextDesc& desc,
|
||||
const SkRect& box, float* shaped_height = nullptr) {
|
||||
const SkRect& box, const sk_sp<SkFontMgr>& fontmgr,
|
||||
float* shaped_height = nullptr) {
|
||||
SkASSERT(desc.fVAlign != Shaper::VAlign::kVisualResizeToFit);
|
||||
|
||||
const auto& is_line_break = [](SkUnichar uch) {
|
||||
@ -326,7 +328,7 @@ Shaper::Result ShapeImpl(const SkString& txt, const Shaper::TextDesc& desc,
|
||||
const char* line_start = ptr;
|
||||
const char* end = ptr + txt.size();
|
||||
|
||||
BlobMaker blobMaker(desc, box);
|
||||
BlobMaker blobMaker(desc, box, fontmgr);
|
||||
while (ptr < end) {
|
||||
if (is_line_break(SkUTF::NextUTF8(&ptr, end))) {
|
||||
blobMaker.shapeLine(line_start, ptr - 1);
|
||||
@ -339,7 +341,7 @@ Shaper::Result ShapeImpl(const SkString& txt, const Shaper::TextDesc& desc,
|
||||
}
|
||||
|
||||
Shaper::Result ShapeToFit(const SkString& txt, const Shaper::TextDesc& orig_desc,
|
||||
const SkRect& box) {
|
||||
const SkRect& box, const sk_sp<SkFontMgr>& fontmgr) {
|
||||
SkASSERT(orig_desc.fVAlign == Shaper::VAlign::kVisualResizeToFit);
|
||||
|
||||
Shaper::Result best_result;
|
||||
@ -368,7 +370,7 @@ Shaper::Result ShapeToFit(const SkString& txt, const Shaper::TextDesc& orig_desc
|
||||
desc.fAscent = try_scale * orig_desc.fAscent;
|
||||
|
||||
float res_height = 0;
|
||||
auto res = ShapeImpl(txt, desc, box, &res_height);
|
||||
auto res = ShapeImpl(txt, desc, box, fontmgr, &res_height);
|
||||
|
||||
if (res_height > box.height()) {
|
||||
out_scale = try_scale;
|
||||
@ -396,16 +398,18 @@ Shaper::Result ShapeToFit(const SkString& txt, const Shaper::TextDesc& orig_desc
|
||||
|
||||
} // namespace
|
||||
|
||||
Shaper::Result Shaper::Shape(const SkString& txt, const TextDesc& desc, const SkPoint& point) {
|
||||
Shaper::Result Shaper::Shape(const SkString& txt, const TextDesc& desc, const SkPoint& point,
|
||||
const sk_sp<SkFontMgr>& fontmgr) {
|
||||
return (desc.fVAlign == VAlign::kVisualResizeToFit) // makes no sense in point mode
|
||||
? Result()
|
||||
: ShapeImpl(txt, desc, SkRect::MakeEmpty().makeOffset(point.x(), point.y()));
|
||||
: ShapeImpl(txt, desc, SkRect::MakeEmpty().makeOffset(point.x(), point.y()), fontmgr);
|
||||
}
|
||||
|
||||
Shaper::Result Shaper::Shape(const SkString& txt, const TextDesc& desc, const SkRect& box) {
|
||||
Shaper::Result Shaper::Shape(const SkString& txt, const TextDesc& desc, const SkRect& box,
|
||||
const sk_sp<SkFontMgr>& fontmgr) {
|
||||
return (desc.fVAlign == VAlign::kVisualResizeToFit)
|
||||
? ShapeToFit(txt, desc, box)
|
||||
: ShapeImpl(txt, desc, box);
|
||||
? ShapeToFit(txt, desc, box, fontmgr)
|
||||
: ShapeImpl(txt, desc, box, fontmgr);
|
||||
}
|
||||
|
||||
SkRect Shaper::Result::computeVisualBounds() const {
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
class SkFontMgr;
|
||||
class SkTextBlob;
|
||||
|
||||
namespace skottie {
|
||||
@ -83,12 +84,14 @@ public:
|
||||
|
||||
// Performs text layout along an infinite horizontal line, starting at |textPoint|.
|
||||
// Only explicit line breaks (\r) are observed.
|
||||
static Result Shape(const SkString& text, const TextDesc& desc, const SkPoint& textPoint);
|
||||
static Result Shape(const SkString& text, const TextDesc& desc, const SkPoint& textPoint,
|
||||
const sk_sp<SkFontMgr>&);
|
||||
|
||||
// Performs text layout within |textBox|, injecting line breaks as needed to ensure
|
||||
// horizontal fitting. The result is *not* guaranteed to fit vertically (it may extend
|
||||
// below the box bottom).
|
||||
static Result Shape(const SkString& text, const TextDesc& desc, const SkRect& textBox);
|
||||
static Result Shape(const SkString& text, const TextDesc& desc, const SkRect& textBox,
|
||||
const sk_sp<SkFontMgr>&);
|
||||
|
||||
private:
|
||||
Shaper() = delete;
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "modules/skottie/src/text/TextAdapter.h"
|
||||
|
||||
#include "include/core/SkFontMgr.h"
|
||||
#include "modules/skottie/src/text/TextAnimator.h"
|
||||
#include "modules/sksg/include/SkSGDraw.h"
|
||||
#include "modules/sksg/include/SkSGGroup.h"
|
||||
@ -18,8 +19,9 @@
|
||||
namespace skottie {
|
||||
namespace internal {
|
||||
|
||||
TextAdapter::TextAdapter(sk_sp<sksg::Group> root, bool hasAnimators)
|
||||
TextAdapter::TextAdapter(sk_sp<sksg::Group> root, sk_sp<SkFontMgr> fontmgr, bool hasAnimators)
|
||||
: fRoot(std::move(root))
|
||||
, fFontMgr(std::move(fontmgr))
|
||||
, fHasAnimators(hasAnimators) {}
|
||||
|
||||
TextAdapter::~TextAdapter() = default;
|
||||
@ -128,7 +130,7 @@ void TextAdapter::apply() {
|
||||
fText.fVAlign,
|
||||
fHasAnimators ? Shaper::Flags::kFragmentGlyphs : Shaper::Flags::kNone,
|
||||
};
|
||||
const auto shape_result = Shaper::Shape(fText.fText, text_desc, fText.fBox);
|
||||
const auto shape_result = Shaper::Shape(fText.fText, text_desc, fText.fBox, fFontMgr);
|
||||
|
||||
// Rebuild all fragments.
|
||||
// TODO: we can be smarter here and try to reuse the existing SG structure if needed.
|
||||
|
@ -15,12 +15,14 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
class SkFontMgr;
|
||||
|
||||
namespace skottie {
|
||||
namespace internal {
|
||||
|
||||
class TextAdapter final : public SkNVRefCnt<TextAdapter> {
|
||||
public:
|
||||
TextAdapter(sk_sp<sksg::Group> root, bool hasAnimators);
|
||||
TextAdapter(sk_sp<sksg::Group> root, sk_sp<SkFontMgr>, bool hasAnimators);
|
||||
~TextAdapter();
|
||||
|
||||
ADAPTER_PROPERTY(Text, TextValue, TextValue())
|
||||
@ -49,11 +51,12 @@ private:
|
||||
const TextAnimator::DomainSpan&,
|
||||
float line_tracking) const;
|
||||
|
||||
sk_sp<sksg::Group> fRoot;
|
||||
const sk_sp<sksg::Group> fRoot;
|
||||
const sk_sp<SkFontMgr> fFontMgr;
|
||||
const bool fHasAnimators;
|
||||
|
||||
std::vector<FragmentRec> fFragments;
|
||||
TextAnimator::DomainMaps fMaps;
|
||||
|
||||
const bool fHasAnimators;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
@ -8,6 +8,7 @@
|
||||
#ifndef SkShaper_DEFINED
|
||||
#define SkShaper_DEFINED
|
||||
|
||||
#include "include/core/SkFontMgr.h"
|
||||
#include "include/core/SkPoint.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkScalar.h"
|
||||
@ -29,12 +30,12 @@ class SkShaper {
|
||||
public:
|
||||
static std::unique_ptr<SkShaper> MakePrimitive();
|
||||
#ifdef SK_SHAPER_HARFBUZZ_AVAILABLE
|
||||
static std::unique_ptr<SkShaper> MakeShaperDrivenWrapper();
|
||||
static std::unique_ptr<SkShaper> MakeShapeThenWrap();
|
||||
static std::unique_ptr<SkShaper> MakeShapeDontWrapOrReorder();
|
||||
static std::unique_ptr<SkShaper> MakeShaperDrivenWrapper(sk_sp<SkFontMgr> = nullptr);
|
||||
static std::unique_ptr<SkShaper> MakeShapeThenWrap(sk_sp<SkFontMgr> = nullptr);
|
||||
static std::unique_ptr<SkShaper> MakeShapeDontWrapOrReorder(sk_sp<SkFontMgr> = nullptr);
|
||||
#endif
|
||||
|
||||
static std::unique_ptr<SkShaper> Make();
|
||||
static std::unique_ptr<SkShaper> Make(sk_sp<SkFontMgr> = nullptr);
|
||||
|
||||
SkShaper();
|
||||
virtual ~SkShaper();
|
||||
|
@ -22,9 +22,9 @@
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
std::unique_ptr<SkShaper> SkShaper::Make() {
|
||||
std::unique_ptr<SkShaper> SkShaper::Make(sk_sp<SkFontMgr> fontmgr) {
|
||||
#ifdef SK_SHAPER_HARFBUZZ_AVAILABLE
|
||||
std::unique_ptr<SkShaper> shaper = SkShaper::MakeShaperDrivenWrapper();
|
||||
std::unique_ptr<SkShaper> shaper = SkShaper::MakeShaperDrivenWrapper(std::move(fontmgr));
|
||||
if (shaper) {
|
||||
return shaper;
|
||||
}
|
||||
|
@ -618,7 +618,8 @@ struct ShapedRunGlyphIterator {
|
||||
|
||||
class ShaperHarfBuzz : public SkShaper {
|
||||
public:
|
||||
ShaperHarfBuzz(HBBuffer, ICUBrk line, ICUBrk grapheme);
|
||||
ShaperHarfBuzz(HBBuffer, ICUBrk line, ICUBrk grapheme, sk_sp<SkFontMgr>);
|
||||
|
||||
protected:
|
||||
ICUBrk fLineBreakIterator;
|
||||
ICUBrk fGraphemeBreakIterator;
|
||||
@ -631,7 +632,8 @@ protected:
|
||||
const ScriptRunIterator&,
|
||||
const FontRunIterator&) const;
|
||||
private:
|
||||
HBBuffer fBuffer;
|
||||
const sk_sp<SkFontMgr> fFontMgr;
|
||||
HBBuffer fBuffer;
|
||||
|
||||
void shape(const char* utf8, size_t utf8Bytes,
|
||||
const SkFont&,
|
||||
@ -699,7 +701,7 @@ private:
|
||||
RunHandler*) const override;
|
||||
};
|
||||
|
||||
static std::unique_ptr<SkShaper> MakeHarfBuzz(bool correct) {
|
||||
static std::unique_ptr<SkShaper> MakeHarfBuzz(sk_sp<SkFontMgr> fontmgr, bool correct) {
|
||||
#if defined(SK_USING_THIRD_PARTY_ICU)
|
||||
if (!SkLoadICU()) {
|
||||
SkDEBUGF("SkLoadICU() failed!\n");
|
||||
@ -726,17 +728,23 @@ static std::unique_ptr<SkShaper> MakeHarfBuzz(bool correct) {
|
||||
}
|
||||
|
||||
if (correct) {
|
||||
return skstd::make_unique<ShaperDrivenWrapper>(
|
||||
std::move(buffer), std::move(lineBreakIterator), std::move(graphemeBreakIterator));
|
||||
return skstd::make_unique<ShaperDrivenWrapper>(std::move(buffer),
|
||||
std::move(lineBreakIterator),
|
||||
std::move(graphemeBreakIterator),
|
||||
std::move(fontmgr));
|
||||
} else {
|
||||
return skstd::make_unique<ShapeThenWrap>(
|
||||
std::move(buffer), std::move(lineBreakIterator), std::move(graphemeBreakIterator));
|
||||
return skstd::make_unique<ShapeThenWrap>(std::move(buffer),
|
||||
std::move(lineBreakIterator),
|
||||
std::move(graphemeBreakIterator),
|
||||
std::move(fontmgr));
|
||||
}
|
||||
}
|
||||
|
||||
ShaperHarfBuzz::ShaperHarfBuzz(HBBuffer buffer, ICUBrk line, ICUBrk grapheme)
|
||||
ShaperHarfBuzz::ShaperHarfBuzz(HBBuffer buffer, ICUBrk line, ICUBrk grapheme,
|
||||
sk_sp<SkFontMgr> fontmgr)
|
||||
: fLineBreakIterator(std::move(line))
|
||||
, fGraphemeBreakIterator(std::move(grapheme))
|
||||
, fFontMgr(std::move(fontmgr))
|
||||
, fBuffer(std::move(buffer))
|
||||
{}
|
||||
|
||||
@ -747,7 +755,6 @@ void ShaperHarfBuzz::shape(const char* utf8, size_t utf8Bytes,
|
||||
RunHandler* handler) const
|
||||
{
|
||||
SkASSERT(handler);
|
||||
sk_sp<SkFontMgr> fontMgr = SkFontMgr::RefDefault();
|
||||
UBiDiLevel defaultLevel = leftToRight ? UBIDI_DEFAULT_LTR : UBIDI_DEFAULT_RTL;
|
||||
|
||||
std::unique_ptr<BiDiRunIterator> bidi(MakeIcuBiDiRunIterator(utf8, utf8Bytes, defaultLevel));
|
||||
@ -765,8 +772,9 @@ void ShaperHarfBuzz::shape(const char* utf8, size_t utf8Bytes,
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<FontRunIterator> font(MakeFontMgrRunIterator(utf8, utf8Bytes,
|
||||
srcFont, std::move(fontMgr)));
|
||||
std::unique_ptr<FontRunIterator> font(
|
||||
MakeFontMgrRunIterator(utf8, utf8Bytes, srcFont,
|
||||
fFontMgr ? fFontMgr : SkFontMgr::RefDefault()));
|
||||
if (!font) {
|
||||
return;
|
||||
}
|
||||
@ -1354,13 +1362,13 @@ SkShaper::MakeHbIcuScriptRunIterator(const char* utf8, size_t utf8Bytes) {
|
||||
return skstd::make_unique<HbIcuScriptRunIterator>(utf8, utf8Bytes);
|
||||
}
|
||||
|
||||
std::unique_ptr<SkShaper> SkShaper::MakeShaperDrivenWrapper() {
|
||||
return MakeHarfBuzz(true);
|
||||
std::unique_ptr<SkShaper> SkShaper::MakeShaperDrivenWrapper(sk_sp<SkFontMgr> fontmgr) {
|
||||
return MakeHarfBuzz(std::move(fontmgr), true);
|
||||
}
|
||||
std::unique_ptr<SkShaper> SkShaper::MakeShapeThenWrap() {
|
||||
return MakeHarfBuzz(false);
|
||||
std::unique_ptr<SkShaper> SkShaper::MakeShapeThenWrap(sk_sp<SkFontMgr> fontmgr) {
|
||||
return MakeHarfBuzz(std::move(fontmgr), false);
|
||||
}
|
||||
std::unique_ptr<SkShaper> SkShaper::MakeShapeDontWrapOrReorder() {
|
||||
std::unique_ptr<SkShaper> SkShaper::MakeShapeDontWrapOrReorder(sk_sp<SkFontMgr> fontmgr) {
|
||||
#if defined(SK_USING_THIRD_PARTY_ICU)
|
||||
if (!SkLoadICU()) {
|
||||
SkDEBUGF("SkLoadICU() failed!\n");
|
||||
@ -1373,5 +1381,6 @@ std::unique_ptr<SkShaper> SkShaper::MakeShapeDontWrapOrReorder() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return skstd::make_unique<ShapeDontWrapOrReorder>(std::move(buffer), nullptr, nullptr);
|
||||
return skstd::make_unique<ShapeDontWrapOrReorder>(std::move(buffer), nullptr, nullptr,
|
||||
std::move(fontmgr));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user