Skip to content

Commit

Permalink
Improve skia text shaping/bounds calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
ckaiser authored and dacap committed Aug 26, 2024
1 parent 5057368 commit a63e1fb
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 11 deletions.
35 changes: 26 additions & 9 deletions text/skia_text_blob_shaper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<SkTextBlob> makeBlob() {
return m_builder.makeBlob();
Expand Down Expand Up @@ -131,17 +132,33 @@ TextBlobRef SkiaTextBlob::MakeWithShaper(
ASSERT(dynamic_cast<SkiaFont*>(font.get()));

SkFont skFont = static_cast<SkiaFont*>(font.get())->skFont();
auto skFontMgr = static_cast<SkiaFontMgr*>(fontMgr.get())->skFontMgr();
sk_sp<SkTextBlob> textBlob;
gfx::RectF bounds;
if (auto shaper = SkShaper::Make(
static_cast<SkiaFontMgr*>(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<float>::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<float>::max(),
&shaperHandler);

textBlob = shaperHandler.makeBlob();
bounds = shaperHandler.bounds();
}
Expand Down
6 changes: 4 additions & 2 deletions text/text_blob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit a63e1fb

Please sign in to comment.