mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
LibWeb: Make canvas text preparation handle multi-code point glyphs
This commit is contained in:
parent
cb04e4e9da
commit
3d7b13ac03
Notes:
sideshowbarker
2024-07-17 03:03:37 +09:00
Author: https://github.com/trflynn89 Commit: https://github.com/SerenityOS/serenity/commit/3d7b13ac03 Pull-request: https://github.com/SerenityOS/serenity/pull/17568
2 changed files with 18 additions and 9 deletions
|
@ -10,6 +10,7 @@
|
|||
#include <LibGfx/Painter.h>
|
||||
#include <LibGfx/Quad.h>
|
||||
#include <LibGfx/Rect.h>
|
||||
#include <LibUnicode/Segmentation.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/HTML/CanvasRenderingContext2D.h>
|
||||
#include <LibWeb/HTML/HTMLCanvasElement.h>
|
||||
|
@ -451,9 +452,10 @@ CanvasRenderingContext2D::PreparedText CanvasRenderingContext2D::prepare_text(De
|
|||
auto& font = Platform::FontPlugin::the().default_font();
|
||||
size_t width = 0;
|
||||
size_t height = font.pixel_size();
|
||||
for (auto c : Utf8View { replaced_text }) {
|
||||
width += font.glyph_or_emoji_width(c);
|
||||
}
|
||||
|
||||
Utf8View replaced_text_view { replaced_text };
|
||||
for (auto it = replaced_text_view.begin(); it != replaced_text_view.end(); ++it)
|
||||
width += font.glyph_or_emoji_width(it);
|
||||
|
||||
// 6. If maxWidth was provided and the hypothetical width of the inline box in the hypothetical line box is greater than maxWidth CSS pixels, then change font to have a more condensed font (if one is available or if a reasonably readable one can be synthesized by applying a horizontal scale factor to the font) or a smaller font, and return to the previous step.
|
||||
// FIXME: Record the font size used for this piece of text, and actually retry with a smaller size if needed.
|
||||
|
@ -478,11 +480,17 @@ CanvasRenderingContext2D::PreparedText CanvasRenderingContext2D::prepare_text(De
|
|||
PreparedText prepared_text { {}, physical_alignment, { 0, 0, static_cast<int>(width), static_cast<int>(height) } };
|
||||
prepared_text.glyphs.ensure_capacity(replaced_text.length());
|
||||
|
||||
size_t offset = 0;
|
||||
for (auto c : Utf8View { replaced_text }) {
|
||||
prepared_text.glyphs.append({ c, { static_cast<int>(offset), 0 } });
|
||||
offset += font.glyph_or_emoji_width(c);
|
||||
}
|
||||
size_t previous_grapheme_boundary = 0;
|
||||
Unicode::for_each_grapheme_segmentation_boundary(replaced_text_view, [&](auto boundary) {
|
||||
if (boundary == 0)
|
||||
return IterationDecision::Continue;
|
||||
|
||||
auto glyph_view = replaced_text_view.substring_view(previous_grapheme_boundary, boundary - previous_grapheme_boundary);
|
||||
auto glyph = String::from_utf8(glyph_view.as_string()).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
prepared_text.glyphs.append({ move(glyph), { static_cast<int>(boundary), 0 } });
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
|
||||
// 9. Return result, physical alignment, and the inline box.
|
||||
return prepared_text;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <AK/Variant.h>
|
||||
#include <LibGfx/AffineTransform.h>
|
||||
#include <LibGfx/AntiAliasingPainter.h>
|
||||
|
@ -90,7 +91,7 @@ private:
|
|||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
struct PreparedTextGlyph {
|
||||
unsigned int c;
|
||||
String glyph;
|
||||
Gfx::IntPoint position;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue