diff --git a/text/skia_text_blob_shaper.cpp b/text/skia_text_blob_shaper.cpp index d2b3ff5c2..19bb56404 100644 --- a/text/skia_text_blob_shaper.cpp +++ b/text/skia_text_blob_shaper.cpp @@ -34,7 +34,8 @@ class ShaperRunHandler final : public SkShaper::RunHandler { const gfx::PointF& offset, TextBlob::RunHandler* subHandler) : m_builder(utf8Text, os::to_skia(offset)) - , m_subHandler(subHandler) { } + , m_subHandler(subHandler) + , m_buffer() { } sk_sp makeBlob() { return m_builder.makeBlob(); @@ -131,17 +132,33 @@ TextBlobRef SkiaTextBlob::MakeWithShaper( ASSERT(dynamic_cast(font.get())); SkFont skFont = static_cast(font.get())->skFont(); + auto skFontMgr = static_cast(fontMgr.get())->skFontMgr(); sk_sp textBlob; gfx::RectF bounds; - if (auto shaper = SkShaper::Make( - static_cast(fontMgr.get())->skFontMgr())) { + if (auto shaper = SkShaper::Make(skFontMgr)) { ShaperRunHandler shaperHandler(text.c_str(), { 0, 0 }, handler); - shaper->shape( - text.c_str(), text.size(), - skFont, - true, - std::numeric_limits::max(), - &shaperHandler); + + auto bidiRun = SkShaper::MakeBiDiRunIterator(text.c_str(), text.size(), 0xfe); + constexpr SkFourByteTag tag = SkSetFourByteTag('Z', 'y', 'y', 'y'); + auto scriptRun = SkShaper::MakeScriptRunIterator(text.c_str(), text.size(), tag); + auto languageRun = SkShaper::MakeStdLanguageRunIterator(text.c_str(), text.size()); + auto fontRun = SkShaper::MakeFontMgrRunIterator(text.c_str(), + text.size(), + skFont, + skFontMgr, + "Arial", // Fallback + SkFontStyle::Normal(), + &*languageRun); + + shaper->shape(text.c_str(), + text.size(), + *fontRun, + *bidiRun, + *scriptRun, + *languageRun, + std::numeric_limits::max(), + &shaperHandler); + textBlob = shaperHandler.makeBlob(); bounds = shaperHandler.bounds(); } diff --git a/text/text_blob.cpp b/text/text_blob.cpp index c106e5a87..2f3c43e17 100644 --- a/text/text_blob.cpp +++ b/text/text_blob.cpp @@ -69,10 +69,12 @@ gfx::RectF TextBlob::RunInfo::getGlyphBounds(const size_t i) const if (bounds.isEmpty()) { FontMetrics metrics; font->metrics(&metrics); - bounds.w = metrics.avgCharWidth; - bounds.h = -metrics.capHeight; + // avgCharWidth can be 0, so we grab the next most useful thing, the height + bounds.w = metrics.avgCharWidth > 0 ? metrics.avgCharWidth : metrics.xHeight; + bounds.h = 1.0; } + ASSERT(!bounds.isEmpty()); bounds.offset(positions[i].x, positions[i].y); if (offsets) {