Commit 5cdaf457 authored by Yoshifumi Inoue's avatar Yoshifumi Inoue Committed by Commit Bot

Make NGInlineNode::ShapeText() not to reuse ShapeResult for letter-spacing

This patch changes |NGInlineNode::ShapeText()| not to reuse
|ShapeResult| for text with CSS property "letter-spacing" because we
modify |ShapeResult| directly to apply letter spacing. Thus, letter-
spacing is applied more than once on reused portion of |ShapeResult|.

Note: This patch also changes number of bits of
|SharepResult::num_glyphs_| from 30 to 29 to hold bit flags in
|unsigned| (32-bit) for re-landing[1].

[1] http://crrev.com/c/2390615 Revert "Make NGInlineNode::ShapeText()
not to reuse ShapeResult for letter-spacing"

Bug: 1124446
Change-Id: I120cc379a191e1499ac1548a569474ed03d0f6a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2391890
Commit-Queue: Yoshifumi Inoue <yosin@chromium.org>
Commit-Queue: Koji Ishii <kojii@chromium.org>
Auto-Submit: Yoshifumi Inoue <yosin@chromium.org>
Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#804185}
parent 08bea025
......@@ -231,6 +231,8 @@ class ReusingTextShaper final {
continue;
if (!item->TextShapeResult() || item->Direction() != direction)
continue;
if (item->TextShapeResult()->IsAppliedSpacing())
continue;
shape_results.push_back(item->TextShapeResult());
}
return shape_results;
......
......@@ -63,6 +63,20 @@ struct SameSizeAsHarfBuzzRunGlyphData {
ASSERT_SIZE(HarfBuzzRunGlyphData, SameSizeAsHarfBuzzRunGlyphData);
struct SameSizeAsShapeResult : RefCounted<SameSizeAsShapeResult> {
float width_;
FloatRect deprecated_ink_bounds_;
Vector<scoped_refptr<ShapeResult::RunInfo>> runs_;
scoped_refptr<const SimpleFontData> primary_font_;
std::unique_ptr<int> character_position_;
unsigned start_index_;
unsigned num_characters_;
unsigned flags;
};
ASSERT_SIZE(ShapeResult, SameSizeAsShapeResult);
unsigned ShapeResult::RunInfo::NextSafeToBreakOffset(unsigned offset) const {
DCHECK_LE(offset, num_characters_);
if (!Rtl()) {
......@@ -370,7 +384,8 @@ ShapeResult::ShapeResult(scoped_refptr<const SimpleFontData> font_data,
num_characters_(num_characters),
num_glyphs_(0),
direction_(static_cast<unsigned>(direction)),
has_vertical_offsets_(0) {}
has_vertical_offsets_(false),
is_applied_spacing_(false) {}
ShapeResult::ShapeResult(const Font* font,
unsigned start_index,
......@@ -892,6 +907,7 @@ void ShapeResult::ApplySpacingImpl(
void ShapeResult::ApplySpacing(ShapeResultSpacing<String>& spacing,
int text_start_offset) {
is_applied_spacing_ = true;
ApplySpacingImpl(spacing, text_start_offset);
}
......
......@@ -185,6 +185,9 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
// have vertical offsets.
bool HasVerticalOffsets() const { return has_vertical_offsets_; }
// Note: We should not reuse |ShapeResult| if we call |ApplySpacing()|.
bool IsAppliedSpacing() const { return is_applied_spacing_; }
// For memory reporting.
size_t ByteSize() const;
......@@ -490,7 +493,7 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
unsigned start_index_;
unsigned num_characters_;
unsigned num_glyphs_ : 30;
unsigned num_glyphs_ : 29;
// Overall direction for the TextRun, dictates which order each individual
// sub run (represented by RunInfo structs in the m_runs vector) can have a
......@@ -500,6 +503,12 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
// Tracks whether any runs contain glyphs with a y-offset != 0.
unsigned has_vertical_offsets_ : 1;
// True once called |ApplySpacing()|.
unsigned is_applied_spacing_ : 1;
// Note: When you add more bit flags, please consider to reduce size of
// |num_glyphs_| or |num_characters_|.
private:
friend class HarfBuzzShaper;
friend class ShapeResultBuffer;
......
<!doctype html>
<script src="../../resources/ahem.js"></script>
<style>
#target {
font: 10px/15px Ahem;
letter-spacing: 20px;
}
</style>
<div id="target">abcx</div>
<!doctype html>
<script src="../../resources/ahem.js"></script>
<style>
#target {
font: 10px/15px Ahem;
letter-spacing: 20px;
}
</style>
<div id="target">x</div>
<script>
const text = target.firstChild;
function typing(character) {
text.replaceData(0, 0, character);
document.body.offsetHeight;
}
typing('a');
typing('b');
typing('c');
</script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment