Commit cd00ae88 authored by eae@chromium.org's avatar eae@chromium.org

Invalidation not taking glyph bounds into account on HarfBuzz path

Implement support for computing and populating the GlyphOverflow
structure for the harfbuzz code path. The current implementation is a
straight copy of the current Mac implementation with minor
modifications to use the corresponding harfbuzz APIs.

R=dglazkov@chromium.org,behdad@chromium.org
BUG=354165
TEST=fast/text/international/repaint-glyph-bounds.html

Review URL: https://codereview.chromium.org/205553003

git-svn-id: svn://svn.chromium.org/blink/trunk@169605 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent abb96c39
......@@ -594,6 +594,7 @@ crbug.com/327698 [ Win ] virtual/gpu/fast/canvas/canvas-lost-gpu-context.html [
crbug.com/298039 [ Mac ] compositing/overflow/clear-scroll-parent.html [ Failure ]
crbug.com/298039 [ Mac ] virtual/gpu/compositedscrolling/overflow/clear-scroll-parent.html [ Failure ]
crbug.com/334269 [ Mac ] fast/text/international/bdo-bidi-width.html [ ImageOnlyFailure ]
crbug.com/354165 fast/text/complex-text-opacity.html [ NeedsRebaseline ]
crbug.com/298188 [ Win ] virtual/implsidepainting/inspector/timeline [ Skip ]
crbug.com/298188 virtual/implsidepainting/inspector/timeline/timeline-paint.html [ Failure Pass Slow ]
......
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
#test {
font-family: arial;
font-size: 300%;
}
</style>
</head>
<body>
<section id="test">
بِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِا<br><span>test 1</span><br><span>test 2</span>
</section>
<section>
<p>
Tests that the glyph overflow rect, used for repaint, is
correctly computed. After selecting and unselecting either
<code>test</code> line above the harakat from the first line are
correctly repainted.
</p>
</section>
<script>
var testElements = document.getElementById('test').
getElementsByTagName('span');
var text = testElements[1].firstChild;
window.getSelection().setBaseAndExtent(text, 3, text, text.length);
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
#test {
font-family: arial;
font-size: 300%;
}
</style>
</head>
<body>
<section id="test">
بِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِا<br><span>test 1</span><br><span>test 2</span>
</section>
<section>
<p>
Tests that the glyph overflow rect, used for repaint, is
correctly computed. After selecting and unselecting either
<code>test</code> line above the harakat from the first line are
correctly repainted.
</p>
</section>
<script>
if (window.testRunner)
testRunner.waitUntilDone();
var testElements = document.getElementById('test').
getElementsByTagName('span');
window.setTimeout(function() {
var text = testElements[0].firstChild;
window.getSelection().setBaseAndExtent(text, 0, text, text.length);
window.setTimeout(function() {
var text = testElements[1].firstChild;
window.getSelection().setBaseAndExtent(text, 0, text, text.length);
window.setTimeout(function() {
var text = testElements[1].firstChild;
window.getSelection().setBaseAndExtent(text, 3, text, text.length);
if (window.testRunner)
testRunner.notifyDone();
}, 0);
}, 0);
}, 0);
</script>
</body>
</html>
......@@ -206,11 +206,18 @@ float Font::getGlyphsAndAdvancesForComplexText(const TextRun& run, int from, int
return 0;
}
float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* /* fallbackFonts */, GlyphOverflow* /* glyphOverflow */) const
float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* /* fallbackFonts */, GlyphOverflow* glyphOverflow) const
{
HarfBuzzShaper shaper(this, run);
if (!shaper.shape())
return 0;
if (glyphOverflow) {
glyphOverflow->top = std::max<int>(glyphOverflow->top, ceilf(-shaper.minGlyphBoundingBoxY()) - (glyphOverflow->computeBounds ? 0 : fontMetrics().ascent()));
glyphOverflow->bottom = std::max<int>(glyphOverflow->bottom, ceilf(shaper.maxGlyphBoundingBoxY()) - (glyphOverflow->computeBounds ? 0 : fontMetrics().descent()));
glyphOverflow->left = std::max<int>(0, ceilf(-shaper.minGlyphBoundingBoxX()));
glyphOverflow->right = std::max<int>(0, ceilf(shaper.maxGlyphBoundingBoxX() - shaper.totalWidth()));
}
return shaper.totalWidth();
}
......
......@@ -382,6 +382,10 @@ HarfBuzzShaper::HarfBuzzShaper(const Font* font, const TextRun& run, ForTextEmph
, m_fromIndex(0)
, m_toIndex(m_run.length())
, m_forTextEmphasis(forTextEmphasis)
, m_minGlyphBoundingBoxX(std::numeric_limits<float>::max())
, m_maxGlyphBoundingBoxX(std::numeric_limits<float>::min())
, m_minGlyphBoundingBoxY(std::numeric_limits<float>::max())
, m_maxGlyphBoundingBoxY(std::numeric_limits<float>::min())
{
m_normalizedBuffer = adoptArrayPtr(new UChar[m_run.length() + 1]);
normalizeCharacters(m_run, m_run.length(), m_normalizedBuffer.get(), &m_normalizedBufferLength);
......@@ -863,6 +867,7 @@ void HarfBuzzShaper::setGlyphPositionsForHarfBuzzRun(HarfBuzzRun* currentRun, hb
unsigned numGlyphs = currentRun->numGlyphs();
uint16_t* glyphToCharacterIndexes = currentRun->glyphToCharacterIndexes();
float totalAdvance = 0;
FloatPoint glyphOrigin;
// HarfBuzz returns the shaping result in visual order. We need not to flip for RTL.
for (size_t i = 0; i < numGlyphs; ++i) {
......@@ -899,6 +904,14 @@ void HarfBuzzShaper::setGlyphPositionsForHarfBuzzRun(HarfBuzzRun* currentRun, hb
currentRun->setGlyphAndPositions(i, glyph, advance, offsetX, offsetY);
FloatRect glyphBounds = currentFontData->boundsForGlyph(glyph);
glyphBounds.move(glyphOrigin.x(), glyphOrigin.y());
m_minGlyphBoundingBoxX = std::min(m_minGlyphBoundingBoxX, glyphBounds.x());
m_maxGlyphBoundingBoxX = std::max(m_maxGlyphBoundingBoxX, glyphBounds.maxX());
m_minGlyphBoundingBoxY = std::min(m_minGlyphBoundingBoxY, glyphBounds.y());
m_maxGlyphBoundingBoxY = std::max(m_maxGlyphBoundingBoxY, glyphBounds.maxY());
glyphOrigin += FloatSize(advance + offsetX, offsetY);
totalAdvance += advance;
}
currentRun->setWidth(totalAdvance > 0.0 ? totalAdvance : 0.0);
......
......@@ -61,6 +61,11 @@ public:
int offsetForPosition(float targetX);
FloatRect selectionRect(const FloatPoint&, int height, int from, int to);
float minGlyphBoundingBoxX() const { return m_minGlyphBoundingBoxX; }
float maxGlyphBoundingBoxX() const { return m_maxGlyphBoundingBoxX; }
float minGlyphBoundingBoxY() const { return m_minGlyphBoundingBoxY; }
float maxGlyphBoundingBoxY() const { return m_maxGlyphBoundingBoxY; }
private:
class HarfBuzzRun {
public:
......@@ -158,6 +163,10 @@ private:
ForTextEmphasisOrNot m_forTextEmphasis;
float m_totalWidth;
float m_minGlyphBoundingBoxX;
float m_maxGlyphBoundingBoxX;
float m_minGlyphBoundingBoxY;
float m_maxGlyphBoundingBoxY;
friend struct CachedShapingResults;
};
......
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