mirror of
https://github.com/zebrajr/ladybird.git
synced 2025-12-06 00:19:53 +01:00
LibGfx+LibWeb: Implement GlyphRun::bounding_rect()
Allows us to skip painting of glyph runs lying outside of viewport.
This commit is contained in:
parent
9c204f36ec
commit
2cf10981af
|
|
@ -15,6 +15,19 @@
|
|||
|
||||
namespace Gfx {
|
||||
|
||||
FloatRect GlyphRun::bounding_rect() const
|
||||
{
|
||||
if (glyphs().is_empty())
|
||||
return {};
|
||||
auto const& first = glyphs().first();
|
||||
FloatRect result { first.position, { first.glyph_width, m_line_height } };
|
||||
for (auto const& glyph : glyphs()) {
|
||||
FloatRect glyph_rect { glyph.position, { glyph.glyph_width, m_line_height } };
|
||||
result.unite(glyph_rect);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Vector<NonnullRefPtr<GlyphRun>> shape_text(FloatPoint baseline_start, Utf16View const& string, FontCascadeList const& font_cascade_list)
|
||||
{
|
||||
if (string.is_empty())
|
||||
|
|
@ -88,6 +101,7 @@ static hb_buffer_t* setup_text_shaping(Utf16View const& string, Font const& font
|
|||
|
||||
NonnullRefPtr<GlyphRun> shape_text(FloatPoint baseline_start, float letter_spacing, Utf16View const& string, Font const& font, GlyphRun::TextType text_type, ShapeFeatures const& features)
|
||||
{
|
||||
auto const& metrics = font.pixel_metrics();
|
||||
auto& shaping_cache = font.shaping_cache();
|
||||
|
||||
// NOTE: We only cache shaping results for a specific set of features. If the features change, we clear the cache.
|
||||
|
|
@ -146,7 +160,7 @@ NonnullRefPtr<GlyphRun> shape_text(FloatPoint baseline_start, float letter_spaci
|
|||
|
||||
for (size_t i = 0; i < glyph_count; ++i) {
|
||||
auto position = point
|
||||
- FloatPoint { 0, font.pixel_metrics().ascent }
|
||||
- FloatPoint { 0, metrics.ascent }
|
||||
+ FloatPoint { positions[i].x_offset, positions[i].y_offset } / text_shaping_resolution;
|
||||
|
||||
glyph_run.unchecked_append({
|
||||
|
|
@ -163,7 +177,7 @@ NonnullRefPtr<GlyphRun> shape_text(FloatPoint baseline_start, float letter_spaci
|
|||
point.translate_by(letter_spacing, 0);
|
||||
}
|
||||
|
||||
return adopt_ref(*new GlyphRun(move(glyph_run), font, text_type, point.x() - baseline_start.x()));
|
||||
return adopt_ref(*new GlyphRun(move(glyph_run), font, text_type, point.x() - baseline_start.x(), metrics.ascent + metrics.descent));
|
||||
}
|
||||
|
||||
float measure_text_width(Utf16View const& string, Font const& font, ShapeFeatures const& features)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include <LibGfx/FontCascadeList.h>
|
||||
#include <LibGfx/Forward.h>
|
||||
#include <LibGfx/Point.h>
|
||||
#include <LibGfx/Rect.h>
|
||||
#include <LibGfx/ShapeFeature.h>
|
||||
|
||||
namespace Gfx {
|
||||
|
|
@ -36,11 +37,12 @@ public:
|
|||
Rtl,
|
||||
};
|
||||
|
||||
GlyphRun(Vector<DrawGlyph>&& glyphs, NonnullRefPtr<Font const> font, TextType text_type, float width)
|
||||
GlyphRun(Vector<DrawGlyph>&& glyphs, NonnullRefPtr<Font const> font, TextType text_type, float width, float line_height)
|
||||
: m_glyphs(move(glyphs))
|
||||
, m_font(move(font))
|
||||
, m_text_type(text_type)
|
||||
, m_width(width)
|
||||
, m_line_height(line_height)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -50,12 +52,14 @@ public:
|
|||
[[nodiscard]] Vector<DrawGlyph>& glyphs() { return m_glyphs; }
|
||||
[[nodiscard]] bool is_empty() const { return m_glyphs.is_empty(); }
|
||||
[[nodiscard]] float width() const { return m_width; }
|
||||
[[nodiscard]] FloatRect bounding_rect() const;
|
||||
|
||||
private:
|
||||
Vector<DrawGlyph> m_glyphs;
|
||||
NonnullRefPtr<Font const> m_font;
|
||||
TextType m_text_type;
|
||||
float m_width { 0 };
|
||||
float m_line_height { 0 };
|
||||
};
|
||||
|
||||
NonnullRefPtr<GlyphRun> shape_text(FloatPoint baseline_start, float letter_spacing, Utf16View const&, Gfx::Font const& font, GlyphRun::TextType, ShapeFeatures const& features);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ void DrawGlyphRun::translate_by(Gfx::IntPoint const& offset)
|
|||
{
|
||||
rect.translate_by(offset);
|
||||
translation.translate_by(offset.to_type<float>());
|
||||
bounding_rectangle.translate_by(offset);
|
||||
}
|
||||
|
||||
Gfx::IntRect PaintOuterBoxShadow::bounding_rect() const
|
||||
|
|
|
|||
|
|
@ -43,7 +43,9 @@ struct DrawGlyphRun {
|
|||
Gfx::FloatPoint translation;
|
||||
Color color;
|
||||
Gfx::Orientation orientation { Gfx::Orientation::Horizontal };
|
||||
Gfx::IntRect bounding_rectangle;
|
||||
|
||||
[[nodiscard]] Gfx::IntRect bounding_rect() const { return bounding_rectangle; }
|
||||
void translate_by(Gfx::IntPoint const& offset);
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -553,13 +553,12 @@ void DisplayListPlayerSkia::paint_text_shadow(PaintTextShadow const& command)
|
|||
SkPaint blur_paint;
|
||||
blur_paint.setImageFilter(blur_image_filter);
|
||||
canvas.saveLayer(SkCanvas::SaveLayerRec(nullptr, &blur_paint, nullptr, 0));
|
||||
draw_glyph_run({
|
||||
.glyph_run = command.glyph_run,
|
||||
draw_glyph_run({ .glyph_run = command.glyph_run,
|
||||
.scale = command.glyph_run_scale,
|
||||
.rect = command.text_rect,
|
||||
.translation = command.draw_location + command.text_rect.location().to_type<float>(),
|
||||
.color = command.color,
|
||||
});
|
||||
.bounding_rectangle = command.bounding_rect() });
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -255,6 +255,7 @@ void DisplayListRecorder::draw_glyph_run(Gfx::FloatPoint baseline_start, Gfx::Gl
|
|||
.translation = baseline_start,
|
||||
.color = color,
|
||||
.orientation = orientation,
|
||||
.bounding_rectangle = glyph_run.bounding_rect().scaled(scale).translated(baseline_start).to_type<int>(),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user