Commit 83821ae6 authored by Dominik Röttsches's avatar Dominik Röttsches Committed by Commit Bot

Fix incorrect font used in prefix of run ending in fallback grapheme

When a run ended in a grapheme cluster consisting of a least two
characters, and this grapheme resulted in not being shaped with the
current font and needed fallback, then the full run from the beginning
was incorrectly rendered in the fallback font. This is because one state
transition between shaped and not shaped was not recognized, as the
last_change_position had been advanced too far.

To fix this, I clarified the shaping loop and moved the logic for
commiting glyphs and queueing characters for reshaping into separate
functions. When reaching the end of the glyph run, transitions between
shaped or unshaped are detected for the last grapheme cluster and added
to the ShapeResult or the reshaping queue accordingly.

       inspector-protocol/layout-fonts/prefix-fallback-multi-character-grapheme.js
       svg/text/combining-character-queries-expected.svg

Bug: 758380
Tests: EmojiZWJSequence in HarfBuzzShaperTest.cpp,
Change-Id: I95d536c488ac602cb4bdfd4e1ac4a729f92b1462
Reviewed-on: https://chromium-review.googlesource.com/657977
Commit-Queue: Dominik Röttsches <drott@chromium.org>
Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Cr-Commit-Position: refs/heads/master@{#504327}
parent 1b947d37
(async function(testRunner) {
var page = await testRunner.createPage();
await page.loadHTML(`
<html>
<meta charset="UTF-8">
<style type="text/css">
@font-face {
font-family: 'Tinos';
src: url("../../third_party/Tinos/tinos-subset.woff2");
}
body {
font-family: "Tinos", Times, serif;
font-size: 40px;
}
</style>
<body>
<div class="test">
<div id="should_be_half_tinos_half_serif">bẩbẩbẩbẩbẩbẩbẩ</div>
</div>
</body>
</html>
`);
var session = await page.createSession();
var helper = await testRunner.loadScript('./resources/layout-font-test.js');
await helper(testRunner, session);
testRunner.completeTest();
})
bẩbẩbẩbẩbẩbẩbẩ
#should_be_half_tinos_half_serif:
"Times" : 7,
"Tinos" : 7
bẩbẩbẩbẩbẩbẩbẩ
#should_be_half_tinos_half_serif:
"Tinos" : 7,
"Times New Roman" : 7
......@@ -34,7 +34,6 @@
#include "platform/fonts/shaping/RunSegmenter.h"
#include "platform/fonts/shaping/ShapeResult.h"
#include "platform/wtf/Allocator.h"
#include "platform/wtf/Deque.h"
#include "platform/wtf/Vector.h"
namespace blink {
......@@ -42,7 +41,9 @@ namespace blink {
class Font;
class SimpleFontData;
class HarfBuzzShaper;
struct HolesQueueItem;
struct ReshapeQueueItem;
struct RangeData;
struct BufferSlice;
class PLATFORM_EXPORT HarfBuzzShaper final {
public:
......@@ -70,7 +71,6 @@ class PLATFORM_EXPORT HarfBuzzShaper final {
~HarfBuzzShaper() {}
private:
struct RangeData;
// Shapes a single seqment, as identified by the RunSegmenterRange parameter,
// one or more times taking font fallback into account. The start and end
......@@ -82,15 +82,22 @@ class PLATFORM_EXPORT HarfBuzzShaper final {
void ExtractShapeResults(RangeData*,
bool& font_cycle_queued,
const HolesQueueItem&,
const ReshapeQueueItem&,
const SimpleFontData*,
UScriptCode,
bool is_last_resort,
ShapeResult*) const;
bool CollectFallbackHintChars(const Deque<HolesQueueItem>&,
bool CollectFallbackHintChars(const Deque<ReshapeQueueItem>&,
Vector<UChar32>& hint) const;
void CommitGlyphs(RangeData*,
const SimpleFontData* current_font,
UScriptCode current_run_script,
bool is_last_resort,
const BufferSlice&,
ShapeResult*) const;
const UChar* text_;
unsigned text_length_;
};
......
......@@ -407,6 +407,15 @@ TEST_F(HarfBuzzShaperTest, PositionForOffsetArabic) {
ASSERT_NEAR(result->Width(), result->PositionForOffset(0), 0.1);
}
TEST_F(HarfBuzzShaperTest, EmojiZWJSequence) {
UChar emoji_zwj_sequence[] = {0x270C, 0x200D, 0xD83C, 0xDFFF,
0x270C, 0x200D, 0xD83C, 0xDFFC};
TextDirection direction = TextDirection::kLtr;
HarfBuzzShaper shaper(emoji_zwj_sequence, arraysize(emoji_zwj_sequence));
RefPtr<ShapeResult> result = shaper.Shape(&font, direction);
}
// A Value-Parameterized Test class to test OffsetForPosition() with
// |include_partial_glyphs| parameter.
class IncludePartialGlyphs : public HarfBuzzShaperTest,
......
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