Commit 0d41895c authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

Fix DCHECK failure in ShapeResult::StartIndexForResult

When no glyphs are found in the source text to shape, and if
HarfBuzzShaper decided not to create a run instead of creating
an empty run, ShapeIndexForResult does not work.

This patch fixes the situation by creating an empty run.

Note, in order to avoid the risk of the synthesized run affects
existing layout, it creates only when the start is not zero.
Only LayoutNG uses this case.

Bug: 794149
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_layout_tests_layout_ng
Change-Id: Id3980fc4bb0f76cf86d08be138ca2876618f7423
Reviewed-on: https://chromium-review.googlesource.com/842603Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Commit-Queue: Emil A Eklund <eae@chromium.org>
Cr-Commit-Position: refs/heads/master@{#526081}
parent e21ba6f3
...@@ -885,6 +885,10 @@ scoped_refptr<ShapeResult> HarfBuzzShaper::Shape(const Font* font, ...@@ -885,6 +885,10 @@ scoped_refptr<ShapeResult> HarfBuzzShaper::Shape(const Font* font,
ShapeSegment(&range_data, segment_range, result.get()); ShapeSegment(&range_data, segment_range, result.get());
} }
// Ensure we have at least one run for StartIndexForResult().
if (UNLIKELY(result->runs_.IsEmpty() && start))
result->InsertRunForIndex(start);
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
if (result) if (result)
CheckShapeResultRange(result.get(), start, end, text_, font); CheckShapeResultRange(result.get(), start, end, text_, font);
......
...@@ -227,6 +227,8 @@ size_t ShapeResult::ByteSize() const { ...@@ -227,6 +227,8 @@ size_t ShapeResult::ByteSize() const {
} }
unsigned ShapeResult::StartIndexForResult() const { unsigned ShapeResult::StartIndexForResult() const {
if (UNLIKELY(runs_.IsEmpty()))
return 0;
const RunInfo& first_run = *runs_.front(); const RunInfo& first_run = *runs_.front();
if (!Rtl()) if (!Rtl())
return first_run.start_index_; return first_run.start_index_;
...@@ -236,6 +238,8 @@ unsigned ShapeResult::StartIndexForResult() const { ...@@ -236,6 +238,8 @@ unsigned ShapeResult::StartIndexForResult() const {
} }
unsigned ShapeResult::EndIndexForResult() const { unsigned ShapeResult::EndIndexForResult() const {
if (UNLIKELY(runs_.IsEmpty()))
return NumCharacters();
const RunInfo& first_run = *runs_.front(); const RunInfo& first_run = *runs_.front();
if (!Rtl()) if (!Rtl())
return first_run.start_index_ + NumCharacters(); return first_run.start_index_ + NumCharacters();
...@@ -674,6 +678,17 @@ void ShapeResult::InsertRun(std::unique_ptr<ShapeResult::RunInfo> run) { ...@@ -674,6 +678,17 @@ void ShapeResult::InsertRun(std::unique_ptr<ShapeResult::RunInfo> run) {
runs_.push_back(std::move(run)); runs_.push_back(std::move(run));
} }
// Insert a |RunInfo| without glyphs. |StartIndexForResult()| needs a run to
// compute the start character index. When all glyphs are missing, this function
// synthesize a run without glyphs.
void ShapeResult::InsertRunForIndex(unsigned start_character_index) {
DCHECK(runs_.IsEmpty());
runs_.push_back(base::MakeUnique<RunInfo>(
primary_font_.get(), !Rtl() ? HB_DIRECTION_LTR : HB_DIRECTION_RTL,
CanvasRotationInVertical::kRegular, HB_SCRIPT_UNKNOWN,
start_character_index, 0, num_characters_));
}
ShapeResult::RunInfo* ShapeResult::InsertRunForTesting( ShapeResult::RunInfo* ShapeResult::InsertRunForTesting(
unsigned start_index, unsigned start_index,
unsigned num_characters, unsigned num_characters,
......
...@@ -158,6 +158,7 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> { ...@@ -158,6 +158,7 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
unsigned num_glyphs, unsigned num_glyphs,
hb_buffer_t*); hb_buffer_t*);
void InsertRun(std::unique_ptr<ShapeResult::RunInfo>); void InsertRun(std::unique_ptr<ShapeResult::RunInfo>);
void InsertRunForIndex(unsigned start_character_index);
void ReorderRtlRuns(unsigned run_size_before); void ReorderRtlRuns(unsigned run_size_before);
float width_; float width_;
......
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