Commit 01a04124 authored by antti@apple.com's avatar antti@apple.com
Browse files

Simple line layout should support floats

https://bugs.webkit.org/show_bug.cgi?id=124666

Reviewed by Dave Hyatt.

Source/WebCore: 

Tests: fast/text/simple-lines-float-compare.html
       fast/text/simple-lines-float.html

* rendering/line/LineWidth.h:
(WebCore::LineWidth::logicalLeftOffset):
        
    Expose the left offset so we don't need to recompute it.

* rendering/SimpleLineLayout.cpp:
(WebCore::SimpleLineLayout::canUseFor):
(WebCore::SimpleLineLayout::computeLineLeft):
        
    Include the left offset from floats.

(WebCore::SimpleLineLayout::createTextRuns):
        
    Keep the flow height updated during the loop as LineWidth reads the current position from there.

* rendering/SimpleLineLayoutResolver.h:
(WebCore::SimpleLineLayout::RunResolver::Run::rect):
(WebCore::SimpleLineLayout::RunResolver::Run::baseline):
(WebCore::SimpleLineLayout::RunResolver::RunResolver):
(WebCore::SimpleLineLayout::RunResolver::lineIndexForHeight):
        
    We now bake the border and the padding to the line left offset. No need to add it during resolve.

LayoutTests: 

* fast/text/simple-lines-float-compare-expected.html: Added.
* fast/text/simple-lines-float-compare.html: Added.
* fast/text/simple-lines-float-expected.html: Added.
* fast/text/simple-lines-float.html: Added.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@159579 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent c1767f0a
2013-11-20 Antti Koivisto <antti@apple.com>
Simple line layout should support floats
https://bugs.webkit.org/show_bug.cgi?id=124666
Reviewed by Dave Hyatt.
* fast/text/simple-lines-float-compare-expected.html: Added.
* fast/text/simple-lines-float-compare.html: Added.
* fast/text/simple-lines-float-expected.html: Added.
* fast/text/simple-lines-float.html: Added.
2013-11-20 Robert Hogan <robert@webkit.org>
 
REGRESSION(r127163): Respect clearance set on ancestors when placing floats
......
<script>
if (window.internals)
internals.settings.setSimpleLineLayoutEnabled(false);
</script>
<div style="float:left; border:1px solid blue; width:50px; height:50px"></div>
<p style="border:1px solid red; width:55px">O tempora</p>
<div style="float:left; border:1px solid blue; width:50px; height:50px"></div>
<p style="border:1px solid red; width:80px">O tempora</p>
<div style="float:left; border:1px solid blue; width:50px; height:200px"></div>
<p>Quo usque tandem abutere, Catilina, patientia nostra? quam diu etiam
furor iste tuus nos eludet? quem ad finem sese effrenata iactabit
audacia? Nihilne te nocturnum praesidium Palati, nihil urbis vigiliae,
nihil timor populi, nihil concursus bonorum omnium, nihil hic munitissimus
habendi senatus locus, nihil horum ora voltusque moverunt? Patere tua
consilia non sentis, constrictam iam horum omnium scientia teneri
coniurationem tuam non vides? Quid proxima, quid superiore nocte egeris,
ubi fueris, quos convocaveris, quid consilii ceperis, quem nostrum
ignorare arbitraris? O tempora, o mores!
</p>
<div style="float:right; border:1px solid blue; width:50px; height:200px"></div>
<p>Quo usque tandem abutere, Catilina, patientia nostra? quam diu etiam
furor iste tuus nos eludet? quem ad finem sese effrenata iactabit
audacia? Nihilne te nocturnum praesidium Palati, nihil urbis vigiliae,
nihil timor populi, nihil concursus bonorum omnium, nihil hic munitissimus
habendi senatus locus, nihil horum ora voltusque moverunt? Patere tua
consilia non sentis, constrictam iam horum omnium scientia teneri
coniurationem tuam non vides? Quid proxima, quid superiore nocte egeris,
ubi fueris, quos convocaveris, quid consilii ceperis, quem nostrum
ignorare arbitraris? O tempora, o mores!
</div>
<div style="float:left; border:1px solid blue; width:50px; height:200px"></div>
<div style="float:right; border:1px solid blue; width:50px; height:200px"></div>
<p>Quo usque tandem abutere, Catilina, patientia nostra? quam diu etiam
furor iste tuus nos eludet? quem ad finem sese effrenata iactabit
audacia? Nihilne te nocturnum praesidium Palati, nihil urbis vigiliae,
nihil timor populi, nihil concursus bonorum omnium, nihil hic munitissimus
habendi senatus locus, nihil horum ora voltusque moverunt? Patere tua
consilia non sentis, constrictam iam horum omnium scientia teneri
coniurationem tuam non vides? Quid proxima, quid superiore nocte egeris,
ubi fueris, quos convocaveris, quid consilii ceperis, quem nostrum
ignorare arbitraris? O tempora, o mores!
</p>
<div style="float:left; border:1px solid blue; width:50px; height:50px"></div>
<p style="border:1px solid red; width:55px">O tempora</p>
<div style="float:left; border:1px solid blue; width:50px; height:50px"></div>
<p style="border:1px solid red; width:80px">O tempora</p>
<div style="float:left; border:1px solid blue; width:50px; height:200px"></div>
<p>Quo usque tandem abutere, Catilina, patientia nostra? quam diu etiam
furor iste tuus nos eludet? quem ad finem sese effrenata iactabit
audacia? Nihilne te nocturnum praesidium Palati, nihil urbis vigiliae,
nihil timor populi, nihil concursus bonorum omnium, nihil hic munitissimus
habendi senatus locus, nihil horum ora voltusque moverunt? Patere tua
consilia non sentis, constrictam iam horum omnium scientia teneri
coniurationem tuam non vides? Quid proxima, quid superiore nocte egeris,
ubi fueris, quos convocaveris, quid consilii ceperis, quem nostrum
ignorare arbitraris? O tempora, o mores!
</p>
<div style="float:right; border:1px solid blue; width:50px; height:200px"></div>
<p>Quo usque tandem abutere, Catilina, patientia nostra? quam diu etiam
furor iste tuus nos eludet? quem ad finem sese effrenata iactabit
audacia? Nihilne te nocturnum praesidium Palati, nihil urbis vigiliae,
nihil timor populi, nihil concursus bonorum omnium, nihil hic munitissimus
habendi senatus locus, nihil horum ora voltusque moverunt? Patere tua
consilia non sentis, constrictam iam horum omnium scientia teneri
coniurationem tuam non vides? Quid proxima, quid superiore nocte egeris,
ubi fueris, quos convocaveris, quid consilii ceperis, quem nostrum
ignorare arbitraris? O tempora, o mores!
</div>
<div style="float:left; border:1px solid blue; width:50px; height:200px"></div>
<div style="float:right; border:1px solid blue; width:50px; height:200px"></div>
<p>Quo usque tandem abutere, Catilina, patientia nostra? quam diu etiam
furor iste tuus nos eludet? quem ad finem sese effrenata iactabit
audacia? Nihilne te nocturnum praesidium Palati, nihil urbis vigiliae,
nihil timor populi, nihil concursus bonorum omnium, nihil hic munitissimus
habendi senatus locus, nihil horum ora voltusque moverunt? Patere tua
consilia non sentis, constrictam iam horum omnium scientia teneri
coniurationem tuam non vides? Quid proxima, quid superiore nocte egeris,
ubi fueris, quos convocaveris, quid consilii ceperis, quem nostrum
ignorare arbitraris? O tempora, o mores!
</p>
<script>
if (window.internals)
internals.settings.setSimpleLineLayoutDebugBordersEnabled(true);
</script>
<div style="position:relative">
<div style="position:absolute; border:1px solid blue; width:50px; height:200px"></div>
<div style="position:absolute; left:52px">
Quo usque tandem abutere, Catilina, patientia nostra? quam diu etiam
furor iste tuus nos eludet? quem ad finem sese effrenata iactabit
audacia? Nihilne te nocturnum praesidium Palati, nihil urbis vigiliae,
nihil timor populi, nihil concursus bonorum omnium, nihil hic munitissimus
habendi senatus locus, nihil horum ora voltusque moverunt? Patere tua
consilia non sentis, constrictam iam horum omnium scientia teneri
coniurationem tuam non vides? Quid proxima, quid superiore nocte egeris,
ubi fueris, quos convocaveris, quid consilii ceperis, quem nostrum
ignorare arbitraris? O tempora, o mores!
</div>
</div>
<div style="position:relative; top:202px">
<div style="position:absolute; border:1px solid blue; right:0px; width:50px; height:200px"></div>
<div style="position:absolute; right:52px">
Quo usque tandem abutere, Catilina, patientia nostra? quam diu etiam
furor iste tuus nos eludet? quem ad finem sese effrenata iactabit
audacia? Nihilne te nocturnum praesidium Palati, nihil urbis vigiliae,
nihil timor populi, nihil concursus bonorum omnium, nihil hic munitissimus
habendi senatus locus, nihil horum ora voltusque moverunt? Patere tua
consilia non sentis, constrictam iam horum omnium scientia teneri
coniurationem tuam non vides? Quid proxima, quid superiore nocte egeris,
ubi fueris, quos convocaveris, quid consilii ceperis, quem nostrum
ignorare arbitraris? O tempora, o mores!
</div>
</div>
<div style="position:relative; top:404px">
<div style="position:absolute; border:1px solid blue; width:50px; height:200px"></div>
<div style="position:absolute; border:1px solid blue; right:0px; width:50px; height:200px"></div>
<div style="position:absolute; left:52px; right:52px">
Quo usque tandem abutere, Catilina, patientia nostra? quam diu etiam
furor iste tuus nos eludet? quem ad finem sese effrenata iactabit
audacia? Nihilne te nocturnum praesidium Palati, nihil urbis vigiliae,
nihil timor populi, nihil concursus bonorum omnium, nihil hic munitissimus
habendi senatus locus, nihil horum ora voltusque moverunt? Patere tua
consilia non sentis, constrictam iam horum omnium scientia teneri
coniurationem tuam non vides? Quid proxima, quid superiore nocte egeris,
ubi fueris, quos convocaveris, quid consilii ceperis, quem nostrum
ignorare arbitraris? O tempora, o mores!
</div>
</div>
<script>
if (window.internals)
internals.settings.setSimpleLineLayoutDebugBordersEnabled(true);
</script>
<div style="float:left; border:1px solid blue; width:50px; height:200px"></div>
<div>Quo usque tandem abutere, Catilina, patientia nostra? quam diu etiam
furor iste tuus nos eludet? quem ad finem sese effrenata iactabit
audacia? Nihilne te nocturnum praesidium Palati, nihil urbis vigiliae,
nihil timor populi, nihil concursus bonorum omnium, nihil hic munitissimus
habendi senatus locus, nihil horum ora voltusque moverunt? Patere tua
consilia non sentis, constrictam iam horum omnium scientia teneri
coniurationem tuam non vides? Quid proxima, quid superiore nocte egeris,
ubi fueris, quos convocaveris, quid consilii ceperis, quem nostrum
ignorare arbitraris? O tempora, o mores!
</div>
<br clear=both>
<div style="float:right; border:1px solid blue; width:50px; height:200px"></div>
<div>Quo usque tandem abutere, Catilina, patientia nostra? quam diu etiam
furor iste tuus nos eludet? quem ad finem sese effrenata iactabit
audacia? Nihilne te nocturnum praesidium Palati, nihil urbis vigiliae,
nihil timor populi, nihil concursus bonorum omnium, nihil hic munitissimus
habendi senatus locus, nihil horum ora voltusque moverunt? Patere tua
consilia non sentis, constrictam iam horum omnium scientia teneri
coniurationem tuam non vides? Quid proxima, quid superiore nocte egeris,
ubi fueris, quos convocaveris, quid consilii ceperis, quem nostrum
ignorare arbitraris? O tempora, o mores!
</div>
<br clear=both>
<div style="float:left; border:1px solid blue; width:50px; height:200px"></div>
<div style="float:right; border:1px solid blue; width:50px; height:200px"></div>
<div>Quo usque tandem abutere, Catilina, patientia nostra? quam diu etiam
furor iste tuus nos eludet? quem ad finem sese effrenata iactabit
audacia? Nihilne te nocturnum praesidium Palati, nihil urbis vigiliae,
nihil timor populi, nihil concursus bonorum omnium, nihil hic munitissimus
habendi senatus locus, nihil horum ora voltusque moverunt? Patere tua
consilia non sentis, constrictam iam horum omnium scientia teneri
coniurationem tuam non vides? Quid proxima, quid superiore nocte egeris,
ubi fueris, quos convocaveris, quid consilii ceperis, quem nostrum
ignorare arbitraris? O tempora, o mores!
</div>
2013-11-20 Antti Koivisto <antti@apple.com>
Simple line layout should support floats
https://bugs.webkit.org/show_bug.cgi?id=124666
Reviewed by Dave Hyatt.
Tests: fast/text/simple-lines-float-compare.html
fast/text/simple-lines-float.html
* rendering/line/LineWidth.h:
(WebCore::LineWidth::logicalLeftOffset):
Expose the left offset so we don't need to recompute it.
* rendering/SimpleLineLayout.cpp:
(WebCore::SimpleLineLayout::canUseFor):
(WebCore::SimpleLineLayout::computeLineLeft):
Include the left offset from floats.
(WebCore::SimpleLineLayout::createTextRuns):
Keep the flow height updated during the loop as LineWidth reads the current position from there.
* rendering/SimpleLineLayoutResolver.h:
(WebCore::SimpleLineLayout::RunResolver::Run::rect):
(WebCore::SimpleLineLayout::RunResolver::Run::baseline):
(WebCore::SimpleLineLayout::RunResolver::RunResolver):
(WebCore::SimpleLineLayout::RunResolver::lineIndexForHeight):
We now bake the border and the padding to the line left offset. No need to add it during resolve.
2013-11-20 Alexey Proskuryakov <ap@apple.com>
 
Use std::function callbacks in CryptoAlgorithm instead of JS promises
......
......@@ -42,7 +42,7 @@
#include "RenderTextControl.h"
#include "RenderView.h"
#include "Settings.h"
#include "SimpleLineLayoutResolver.h"
#include "SimpleLineLayoutFunctions.h"
#include "Text.h"
#include "TextPaintStyle.h"
#include "break_lines.h"
......@@ -105,9 +105,6 @@ bool canUseFor(const RenderBlockFlow& flow)
return false;
if (!flow.firstChild()->isText())
return false;
// Supporting floats would be very beneficial.
if (flow.containsFloats())
return false;
if (!flow.isHorizontalWritingMode())
return false;
if (flow.flowThreadState() != RenderObject::NotInsideFlowThread)
......@@ -182,6 +179,12 @@ bool canUseFor(const RenderBlockFlow& flow)
if (style.borderFit() == BorderFitLines)
return false;
const RenderText& textRenderer = toRenderText(*flow.firstChild());
if (flow.containsFloats()) {
// We can't use the code path if any lines would need to be shifted below floats. This is because we don't keep per-line y coordinates.
// It is enough to test the first line width only as currently all floats must be overhanging.
if (textRenderer.minLogicalWidth() > LineWidth(const_cast<RenderBlockFlow&>(flow), false, DoNotIndentText).availableWidth())
return false;
}
if (textRenderer.isCombineText() || textRenderer.isCounter() || textRenderer.isQuote() || textRenderer.isTextFragment()
#if ENABLE(SVG)
|| textRenderer.isSVGInlineText()
......@@ -373,20 +376,22 @@ Vector<Run, 4> createLineRuns(unsigned lineStart, LineWidth& lineWidth, LazyLine
return lineRuns;
}
static float computeLineLeft(ETextAlign textAlign, float remainingWidth)
static float computeLineLeft(ETextAlign textAlign, const LineWidth& lineWidth)
{
float remainingWidth = lineWidth.availableWidth() - lineWidth.committedWidth();
float left = lineWidth.logicalLeftOffset();
switch (textAlign) {
case LEFT:
case WEBKIT_LEFT:
case TASTART:
return 0;
return left;
case RIGHT:
case WEBKIT_RIGHT:
case TAEND:
return std::max<float>(remainingWidth, 0);
return left + std::max<float>(remainingWidth, 0);
case CENTER:
case WEBKIT_CENTER:
return std::max<float>(remainingWidth / 2, 0);
return left + std::max<float>(remainingWidth / 2, 0);
case JUSTIFY:
break;
}
......@@ -412,6 +417,9 @@ void createTextRuns(Layout::RunVector& runs, unsigned& lineCount, RenderBlockFlo
const CharacterType* text = textRenderer.text()->getCharacters<CharacterType>();
const unsigned textLength = textRenderer.textLength();
LayoutUnit borderAndPaddingBefore = flow.borderAndPaddingBefore();
LayoutUnit lineHeight = lineHeightFromFlow(flow);
LazyLineBreakIterator lineBreakIterator(textRenderer.text(), flow.style().locale());
unsigned lineEnd = 0;
......@@ -421,7 +429,10 @@ void createTextRuns(Layout::RunVector& runs, unsigned& lineCount, RenderBlockFlo
unsigned lineStart = lineEnd;
// LineWidth reads the current y position from the flow so keep it updated.
flow.setLogicalHeight(lineHeight * lineCount + borderAndPaddingBefore);
LineWidth lineWidth(flow, false, DoNotIndentText);
auto lineRuns = createLineRuns(lineStart, lineWidth, lineBreakIterator, style, text, textLength, textRenderer);
lineEnd = lineRuns.last().end;
......@@ -430,7 +441,7 @@ void createTextRuns(Layout::RunVector& runs, unsigned& lineCount, RenderBlockFlo
lineRuns.last().isEndOfLine = true;
float lineLeft = computeLineLeft(style.textAlign, lineWidth.availableWidth() - lineWidth.committedWidth());
float lineLeft = computeLineLeft(style.textAlign, lineWidth);
adjustRunOffsets(lineRuns, lineLeft);
for (unsigned i = 0; i < lineRuns.size(); ++i)
......
......@@ -108,9 +108,9 @@ private:
const String m_string;
const LayoutUnit m_lineHeight;
const LayoutUnit m_baseline;
const LayoutUnit m_borderAndPaddingBefore;
const float m_ascent;
const float m_descent;
const LayoutPoint m_contentOffset;
};
class LineResolver {
......@@ -166,9 +166,10 @@ inline LayoutRect RunResolver::Run::rect() const
auto& resolver = m_iterator.resolver();
auto& run = m_iterator.simpleRun();
LayoutPoint linePosition(floor(run.left), resolver.m_lineHeight * m_iterator.lineIndex() + resolver.m_baseline - resolver.m_ascent);
float baselinePosition = resolver.m_lineHeight * m_iterator.lineIndex() + resolver.m_baseline;
LayoutPoint linePosition(floor(run.left), baselinePosition - resolver.m_ascent + resolver.m_borderAndPaddingBefore);
LayoutSize lineSize(ceil(run.right) - floor(run.left), resolver.m_ascent + resolver.m_descent);
return LayoutRect(linePosition + resolver.m_contentOffset, lineSize);
return LayoutRect(linePosition, lineSize);
}
inline FloatPoint RunResolver::Run::baseline() const
......@@ -176,8 +177,8 @@ inline FloatPoint RunResolver::Run::baseline() const
auto& resolver = m_iterator.resolver();
auto& run = m_iterator.simpleRun();
float baselineY = resolver.m_lineHeight * m_iterator.lineIndex() + resolver.m_baseline;
return FloatPoint(run.left, baselineY) + resolver.m_contentOffset;
float baselinePosition = resolver.m_lineHeight * m_iterator.lineIndex() + resolver.m_baseline;
return FloatPoint(run.left, baselinePosition + resolver.m_borderAndPaddingBefore);
}
inline String RunResolver::Run::text() const
......@@ -253,9 +254,9 @@ inline RunResolver::RunResolver(const RenderBlockFlow& flow, const Layout& layou
, m_string(toRenderText(*flow.firstChild()).text())
, m_lineHeight(lineHeightFromFlow(flow))
, m_baseline(baselineFromFlow(flow))
, m_borderAndPaddingBefore(flow.borderAndPaddingBefore())
, m_ascent(flow.style().font().fontMetrics().ascent())
, m_descent(flow.style().font().fontMetrics().descent())
, m_contentOffset(flow.borderLeft() + flow.paddingLeft(), flow.borderTop() + flow.paddingTop())
{
}
......@@ -272,7 +273,7 @@ inline RunResolver::Iterator RunResolver::end() const
inline unsigned RunResolver::lineIndexForHeight(LayoutUnit height) const
{
ASSERT(m_lineHeight);
float y = std::max<float>(height - m_contentOffset.y() - m_baseline + m_ascent, 0);
float y = std::max<float>(height - m_borderAndPaddingBefore - m_baseline + m_ascent, 0);
return std::min<unsigned>(y / m_lineHeight, m_layout.lineCount() - 1);
}
......
......@@ -56,6 +56,7 @@ public:
float uncommittedWidth() const { return m_uncommittedWidth; }
float committedWidth() const { return m_committedWidth; }
float availableWidth() const { return m_availableWidth; }
float logicalLeftOffset() const { return m_left; }
void updateAvailableWidth(LayoutUnit minimumHeight = 0);
void shrinkAvailableWidthForNewFloatIfNeeded(FloatingObject*);
......
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