Add trivial implemenations of shaper run iterators.
Change-Id: I71f9cf2971cdb44ae2d189e29afc2ab330750dcb Reviewed-on: https://skia-review.googlesource.com/c/skia/+/216780 Reviewed-by: Herb Derby <herb@google.com> Commit-Queue: Ben Wagner <bungeman@google.com>
This commit is contained in:
parent
cf01a5ccd9
commit
e8db325168
@ -50,6 +50,21 @@ public:
|
||||
virtual bool atEnd() const = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
template <typename RunIteratorSubclass>
|
||||
class TrivialRunIterator : public RunIteratorSubclass {
|
||||
public:
|
||||
static_assert(std::is_base_of<RunIterator, RunIteratorSubclass>::value, "");
|
||||
TrivialRunIterator(size_t utf8Bytes) : fEnd(utf8Bytes), fAtEnd(false) {}
|
||||
void consume() override { fAtEnd = true; }
|
||||
size_t endOfCurrentRun() const override { return fAtEnd ? fEnd : 0; }
|
||||
bool atEnd() const override { return fAtEnd; }
|
||||
private:
|
||||
size_t fEnd;
|
||||
bool fAtEnd;
|
||||
};
|
||||
|
||||
public:
|
||||
class FontRunIterator : public RunIterator {
|
||||
public:
|
||||
virtual const SkFont& currentFont() const = 0;
|
||||
@ -57,6 +72,14 @@ public:
|
||||
static std::unique_ptr<FontRunIterator>
|
||||
MakeFontMgrRunIterator(const char* utf8, size_t utf8Bytes,
|
||||
const SkFont& font, sk_sp<SkFontMgr> fallback);
|
||||
class TrivialFontRunIterator : public TrivialRunIterator<FontRunIterator> {
|
||||
public:
|
||||
TrivialFontRunIterator(const SkFont& font, size_t utf8Bytes)
|
||||
: TrivialRunIterator(utf8Bytes), fFont(font) {}
|
||||
const SkFont& currentFont() const override { return fFont; }
|
||||
private:
|
||||
SkFont fFont;
|
||||
};
|
||||
|
||||
class BiDiRunIterator : public RunIterator {
|
||||
public:
|
||||
@ -64,9 +87,17 @@ public:
|
||||
virtual uint8_t currentLevel() const = 0;
|
||||
};
|
||||
#ifdef SK_SHAPER_HARFBUZZ_AVAILABLE
|
||||
static std::unique_ptr<SkShaper::BiDiRunIterator>
|
||||
static std::unique_ptr<BiDiRunIterator>
|
||||
MakeIcuBiDiRunIterator(const char* utf8, size_t utf8Bytes, uint8_t bidiLevel);
|
||||
#endif
|
||||
class TrivialBiDiRunIterator : public TrivialRunIterator<BiDiRunIterator> {
|
||||
public:
|
||||
TrivialBiDiRunIterator(uint8_t bidiLevel, size_t utf8Bytes)
|
||||
: TrivialRunIterator(utf8Bytes), fBidiLevel(bidiLevel) {}
|
||||
uint8_t currentLevel() const override { return fBidiLevel; }
|
||||
private:
|
||||
uint8_t fBidiLevel;
|
||||
};
|
||||
|
||||
class ScriptRunIterator : public RunIterator {
|
||||
public:
|
||||
@ -74,17 +105,33 @@ public:
|
||||
virtual SkFourByteTag currentScript() const = 0;
|
||||
};
|
||||
#ifdef SK_SHAPER_HARFBUZZ_AVAILABLE
|
||||
static std::unique_ptr<SkShaper::ScriptRunIterator>
|
||||
static std::unique_ptr<ScriptRunIterator>
|
||||
MakeHbIcuScriptRunIterator(const char* utf8, size_t utf8Bytes);
|
||||
#endif
|
||||
class TrivialScriptRunIterator : public TrivialRunIterator<ScriptRunIterator> {
|
||||
public:
|
||||
TrivialScriptRunIterator(SkFourByteTag script, size_t utf8Bytes)
|
||||
: TrivialRunIterator(utf8Bytes), fScript(script) {}
|
||||
SkFourByteTag currentScript() const override { return fScript; }
|
||||
private:
|
||||
SkFourByteTag fScript;
|
||||
};
|
||||
|
||||
class LanguageRunIterator : public RunIterator {
|
||||
public:
|
||||
/** Should be BCP-47, c locale names may also work. */
|
||||
virtual const char* currentLanguage() const = 0;
|
||||
};
|
||||
static std::unique_ptr<SkShaper::LanguageRunIterator>
|
||||
static std::unique_ptr<LanguageRunIterator>
|
||||
MakeStdLanguageRunIterator(const char* utf8, size_t utf8Bytes);
|
||||
class TrivialLanguageRunIterator : public TrivialRunIterator<LanguageRunIterator> {
|
||||
public:
|
||||
TrivialLanguageRunIterator(const char* language, size_t utf8Bytes)
|
||||
: TrivialRunIterator(utf8Bytes), fLanguage(language) {}
|
||||
const char* currentLanguage() const override { return fLanguage; }
|
||||
private:
|
||||
const char* fLanguage;
|
||||
};
|
||||
|
||||
class RunHandler {
|
||||
public:
|
||||
|
@ -272,6 +272,7 @@ hb_blob_t* skhb_get_table(hb_face_t* face, hb_tag_t tag, void* user_data) {
|
||||
}
|
||||
|
||||
HBFont create_hb_font(const SkFont& font) {
|
||||
SkASSERT(font.getTypeface());
|
||||
int index;
|
||||
std::unique_ptr<SkStreamAsset> typefaceAsset = font.getTypeface()->openStream(&index);
|
||||
HBFace face;
|
||||
|
@ -118,7 +118,7 @@ void SkShaperPrimitive::shape(const char* utf8, size_t utf8Bytes,
|
||||
FontRunIterator& font,
|
||||
BiDiRunIterator& bidi,
|
||||
ScriptRunIterator&,
|
||||
LanguageRunIterator& ,
|
||||
LanguageRunIterator&,
|
||||
SkScalar width,
|
||||
RunHandler* handler) const
|
||||
{
|
||||
@ -134,6 +134,7 @@ void SkShaperPrimitive::shape(const char* utf8, size_t utf8Bytes,
|
||||
SkScalar width,
|
||||
RunHandler* handler) const {
|
||||
sk_ignore_unused_variable(leftToRight);
|
||||
SkASSERT(font.getTypeface());
|
||||
|
||||
int glyphCount = font.countText(utf8, utf8Bytes, SkTextEncoding::kUTF8);
|
||||
if (glyphCount <= 0) {
|
||||
|
@ -5,9 +5,19 @@
|
||||
|
||||
#if !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) && !defined(SK_BUILD_FOR_GOOGLE3)
|
||||
|
||||
#include "include/core/SkData.h"
|
||||
#include "include/core/SkFont.h"
|
||||
#include "include/core/SkPoint.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkTypeface.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
#include "include/private/SkTo.h"
|
||||
#include "modules/skshaper/include/SkShaper.h"
|
||||
#include "tools/Resources.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
namespace {
|
||||
struct RunHandler final : public SkShaper::RunHandler {
|
||||
const char* fResource;
|
||||
@ -52,14 +62,30 @@ struct RunHandler final : public SkShaper::RunHandler {
|
||||
} // namespace
|
||||
|
||||
static void cluster_test(skiatest::Reporter* reporter, const char* resource) {
|
||||
constexpr float kWidth = 400;
|
||||
if (auto shaper = SkShaper::Make()) {
|
||||
if (auto data = GetResourceAsData(resource)) {
|
||||
SkFont font;
|
||||
RunHandler rh(resource, reporter);
|
||||
shaper->shape((const char*)data->data(), data->size(), font, true, kWidth, &rh);
|
||||
}
|
||||
auto shaper = SkShaper::Make();
|
||||
if (!shaper) {
|
||||
ERRORF(reporter, "Could not create shaper.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto data = GetResourceAsData(resource);
|
||||
if (!data) {
|
||||
ERRORF(reporter, "Could not get resource %s.", resource);
|
||||
return;
|
||||
}
|
||||
|
||||
constexpr float kWidth = 400;
|
||||
SkFont font(SkTypeface::MakeDefault());
|
||||
RunHandler rh(resource, reporter);
|
||||
shaper->shape((const char*)data->data(), data->size(), font, true, kWidth, &rh);
|
||||
|
||||
constexpr SkFourByteTag latn = SkSetFourByteTag('l','a','t','n');
|
||||
auto fontIterator = SkShaper::TrivialFontRunIterator(font, data->size());
|
||||
auto bidiIterator = SkShaper::TrivialBiDiRunIterator(0, data->size());
|
||||
auto scriptIterator = SkShaper::TrivialScriptRunIterator(latn, data->size());
|
||||
auto languageIterator = SkShaper::TrivialLanguageRunIterator("en-US", data->size());
|
||||
shaper->shape((const char*)data->data(), data->size(),
|
||||
fontIterator, bidiIterator, scriptIterator, languageIterator, kWidth, &rh);
|
||||
}
|
||||
|
||||
#define SHAPER_TEST(X) DEF_TEST(Shaper_cluster_ ## X, r) { cluster_test(r, "text/" #X ".txt"); }
|
||||
|
Loading…
Reference in New Issue
Block a user