mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-29 12:32:52 +00:00
Fix text bounds using shaped text w/the font of each text run
This fixes the required output image size to render text in different languages when the text doesn't support the full range of the specified chars/code points, and multiple fonts/text runs are used.
This commit is contained in:
parent
bc63d2f660
commit
cf67842760
@ -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 <cmath>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
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; i<info.glyphCount; ++i) {
|
||||
auto rc = info.getGlyphBounds(i);
|
||||
m_bounds |= gfx::RectF(rc.x, 0, rc.w, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
gfx::RectF m_bounds;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
doc::ImageRef render_text(
|
||||
const text::FontMgrRef& fontMgr,
|
||||
const FontInfo& fontInfo,
|
||||
@ -74,12 +107,24 @@ doc::ImageRef render_text(
|
||||
paint.style(os::Paint::StrokeAndFill);
|
||||
paint.color(color);
|
||||
|
||||
text::TextBlobRef blob;
|
||||
gfx::RectF bounds;
|
||||
bounds.w = font->measureText(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> skSurface = wrap_docimage_in_sksurface(image.get());
|
||||
os::SurfaceRef surface = base::make_ref<os::SkiaSurface>(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(
|
||||
|
Loading…
x
Reference in New Issue
Block a user