WTextItem WPdfImage::measureText(const WString& text, double maxWidth, bool wordWrap) { if (trueTypeFont_ && !trueTypeFonts_->busy()) return trueTypeFonts_->measureText(painter()->font(), text, maxWidth, wordWrap); else { HPDF_REAL width = 0; if (!wordWrap) maxWidth = 1E9; else maxWidth += EPSILON; if (trueTypeFonts_->busy()) setChanged(PainterChangeFlag::Font); std::string s = trueTypeFont_ ? text.toUTF8() : text.narrow(); int bytes = HPDF_Page_MeasureText(page_, s.c_str(), maxWidth, wordWrap, &width); if (trueTypeFont_) return WTextItem(WString::fromUTF8(s.substr(0, bytes)), width); else return WTextItem(text.value().substr(0, bytes), width); } }
WTextItem WRasterImage::measureText(const WString& text, double maxWidth, bool wordWrap) { SkScalar w = impl_->textPaint_.measureText(text.toUTF8().c_str(), text.toUTF8().size()); return WTextItem(text, SkScalarToFloat(w), -1); // TODO: what about wordwrap? }
WTextItem FontSupport::measureText(const WFont& font, const WString& text, double maxWidth, bool wordWrap) { PANGO_LOCK; enabledFontFormats = enabledFontFormats_; /* * Note: accurate measuring on a bitmap requires that the transformation * is applied, because hinting may push chars to boundaries e.g. when * rotated (or scaled too?) */ std::string utf8 = text.toUTF8(); const char *s = utf8.c_str(); if (wordWrap) { int utflen = g_utf8_strlen(s, -1); PangoLogAttr *attrs = new PangoLogAttr[utflen + 1]; PangoLanguage *language = pango_language_from_string("en-US"); pango_get_log_attrs(s, utf8.length(), -1, language, attrs, utflen + 1); double w = 0, nextW = -1; int current = 0; int measured = 0; int end = 0; bool maxWidthReached = false; for (int i = 0; i < utflen + 1; ++i) { if (i == utflen || attrs[i].is_line_break) { int cend = g_utf8_offset_to_pointer(s, end) - s; WTextItem ti = measureText(font, WString::fromUTF8(utf8.substr(measured, cend - measured)), -1, false); if (isEpsilonMore(w + ti.width(), maxWidth)) { nextW = ti.width(); maxWidthReached = true; break; } else { measured = cend; current = g_utf8_offset_to_pointer(s, i) - s; w += ti.width(); if (i == utflen) { w += measureText(font, WString::fromUTF8(utf8.substr(measured)), -1, false).width(); measured = utf8.length(); } } } if (!attrs[i].is_white) end = i + 1; } delete[] attrs; if (maxWidthReached) { return WTextItem(WString::fromUTF8(utf8.substr(0, current)), w, nextW); } else { /* * For some reason, the sum of the individual widths is a bit less * (for longer stretches of text), so we re-measure it ! */ w = measureText(font, WString::fromUTF8(utf8.substr(0, measured)), -1, false).width(); return WTextItem(text, w); } } else { std::vector<PangoGlyphString *> glyphs; int width; GList *items = layoutText(font, utf8, glyphs, width); double w = pangoUnitsToDouble(width); for (unsigned i = 0; i < glyphs.size(); ++i) pango_glyph_string_free(glyphs[i]); g_list_foreach(items, (GFunc) pango_item_free, nullptr); g_list_free(items); return WTextItem(text, w); } }