diff --git a/src/app/util/render_text.cpp b/src/app/util/render_text.cpp index e0a27fd8c..bee1d6760 100644 --- a/src/app/util/render_text.cpp +++ b/src/app/util/render_text.cpp @@ -21,17 +21,50 @@ #include "doc/primitives.h" #include "text/draw_text.h" #include "text/font_metrics.h" +#include "text/text_blob.h" #ifdef LAF_SKIA #include "app/util/shader_helpers.h" #include "os/skia/skia_surface.h" #endif +#include #include #include namespace app { +namespace { + +class MeasureHandler : public text::TextBlob::RunHandler { +public: + MeasureHandler() : m_bounds(0, 0, 1, 1) { + } + + const gfx::RectF& bounds() const { + return m_bounds; + } + + // text::TextBlob::RunHandler impl + void commitRunBuffer(text::TextBlob::RunInfo& info) override { + ASSERT(info.font); + if (info.clusters && + info.glyphCount > 0) { + const float height = info.font->metrics(nullptr); + + for (int i=0; imeasureText(text, &bounds, &paint); - text::FontMetrics metrics; - bounds.w += 1; - bounds.h = font->metrics(&metrics); + if (fontInfo.type() == FontInfo::Type::System) { + // For native fonts we have to measure all text runs which might + // use different fonts (e.g. if the given font is not enough to + // shape other code points/languages). + MeasureHandler handler; + blob = text::TextBlob::MakeWithShaper(fontMgr, font, text, &handler); + bounds = handler.bounds(); + } + else { + font->measureText(text, &bounds, &paint); + bounds.w += 1 + std::abs(bounds.x); + + text::FontMetrics metrics; + bounds.h = font->metrics(&metrics); + } if (bounds.w < 1) bounds.w = 1; if (bounds.h < 1) bounds.h = 1; @@ -89,8 +134,8 @@ doc::ImageRef render_text( sk_sp skSurface = wrap_docimage_in_sksurface(image.get()); os::SurfaceRef surface = base::make_ref(skSurface); if (fontInfo.type() == FontInfo::Type::System) { - text::draw_text_with_shaper( - surface.get(), fontMgr, font, text, gfx::PointF(0, 0), &paint); + text::draw_text(surface.get(), blob, + gfx::PointF(0, 0), &paint); } else { text::draw_text(