summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/rendering
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-05-24 11:24:40 +0100
committerBen Murdoch <benm@google.com>2011-06-02 09:53:15 +0100
commit81bc750723a18f21cd17d1b173cd2a4dda9cea6e (patch)
tree7a9e5ed86ff429fd347a25153107221543909b19 /Source/WebCore/rendering
parent94088a6d336c1dd80a1e734af51e96abcbb689a7 (diff)
downloadexternal_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.zip
external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.gz
external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.bz2
Merge WebKit at r80534: Intial merge by Git
Change-Id: Ia7a83357124c9e1cdb1debf55d9661ec0bd09a61
Diffstat (limited to 'Source/WebCore/rendering')
-rw-r--r--Source/WebCore/rendering/AutoTableLayout.cpp1
-rw-r--r--Source/WebCore/rendering/HitTestResult.cpp17
-rw-r--r--Source/WebCore/rendering/HitTestResult.h4
-rw-r--r--Source/WebCore/rendering/InlineBox.cpp32
-rw-r--r--Source/WebCore/rendering/InlineBox.h48
-rw-r--r--Source/WebCore/rendering/InlineFlowBox.cpp172
-rw-r--r--Source/WebCore/rendering/InlineFlowBox.h20
-rw-r--r--Source/WebCore/rendering/InlineTextBox.cpp97
-rw-r--r--Source/WebCore/rendering/InlineTextBox.h24
-rw-r--r--Source/WebCore/rendering/MediaControlElements.cpp33
-rw-r--r--Source/WebCore/rendering/MediaControlElements.h13
-rw-r--r--Source/WebCore/rendering/RenderBR.h4
-rw-r--r--Source/WebCore/rendering/RenderBlock.cpp444
-rw-r--r--Source/WebCore/rendering/RenderBlock.h65
-rw-r--r--Source/WebCore/rendering/RenderBlockLineLayout.cpp280
-rw-r--r--Source/WebCore/rendering/RenderBox.cpp852
-rw-r--r--Source/WebCore/rendering/RenderBox.h26
-rw-r--r--Source/WebCore/rendering/RenderBoxModelObject.cpp2
-rw-r--r--Source/WebCore/rendering/RenderBoxModelObject.h5
-rw-r--r--Source/WebCore/rendering/RenderCombineText.cpp8
-rw-r--r--Source/WebCore/rendering/RenderCombineText.h6
-rw-r--r--Source/WebCore/rendering/RenderCounter.cpp4
-rw-r--r--Source/WebCore/rendering/RenderCounter.h2
-rw-r--r--Source/WebCore/rendering/RenderEmbeddedObject.cpp3
-rw-r--r--Source/WebCore/rendering/RenderFileUploadControl.cpp2
-rw-r--r--Source/WebCore/rendering/RenderFlexibleBox.cpp31
-rw-r--r--Source/WebCore/rendering/RenderImage.cpp4
-rw-r--r--Source/WebCore/rendering/RenderInline.cpp82
-rw-r--r--Source/WebCore/rendering/RenderLayer.cpp63
-rw-r--r--Source/WebCore/rendering/RenderLayer.h13
-rw-r--r--Source/WebCore/rendering/RenderLayerBacking.cpp6
-rw-r--r--Source/WebCore/rendering/RenderLayerCompositor.cpp9
-rw-r--r--Source/WebCore/rendering/RenderLineBoxList.cpp8
-rw-r--r--Source/WebCore/rendering/RenderListBox.cpp55
-rw-r--r--Source/WebCore/rendering/RenderListBox.h3
-rw-r--r--Source/WebCore/rendering/RenderMedia.cpp26
-rw-r--r--Source/WebCore/rendering/RenderMediaControls.cpp28
-rw-r--r--Source/WebCore/rendering/RenderMediaControls.h6
-rw-r--r--Source/WebCore/rendering/RenderMenuList.cpp4
-rw-r--r--Source/WebCore/rendering/RenderObject.cpp13
-rw-r--r--Source/WebCore/rendering/RenderObject.h3
-rw-r--r--Source/WebCore/rendering/RenderObjectChildList.cpp17
-rw-r--r--Source/WebCore/rendering/RenderQuote.cpp331
-rw-r--r--Source/WebCore/rendering/RenderQuote.h61
-rw-r--r--Source/WebCore/rendering/RenderRubyBase.cpp30
-rw-r--r--Source/WebCore/rendering/RenderRubyBase.h9
-rw-r--r--Source/WebCore/rendering/RenderRubyRun.cpp19
-rw-r--r--Source/WebCore/rendering/RenderRubyText.cpp33
-rw-r--r--Source/WebCore/rendering/RenderRubyText.h4
-rw-r--r--Source/WebCore/rendering/RenderScrollbar.h2
-rw-r--r--Source/WebCore/rendering/RenderTable.cpp36
-rw-r--r--Source/WebCore/rendering/RenderTable.h1
-rw-r--r--Source/WebCore/rendering/RenderTableCell.cpp9
-rw-r--r--Source/WebCore/rendering/RenderTableCell.h2
-rw-r--r--Source/WebCore/rendering/RenderTableSection.cpp6
-rw-r--r--Source/WebCore/rendering/RenderText.cpp89
-rw-r--r--Source/WebCore/rendering/RenderText.h38
-rw-r--r--Source/WebCore/rendering/RenderTextControl.cpp16
-rw-r--r--Source/WebCore/rendering/RenderTextControl.h7
-rw-r--r--Source/WebCore/rendering/RenderTextControlMultiLine.cpp1
-rw-r--r--Source/WebCore/rendering/RenderTextControlSingleLine.cpp100
-rw-r--r--Source/WebCore/rendering/RenderTextControlSingleLine.h13
-rw-r--r--Source/WebCore/rendering/RenderTheme.cpp6
-rw-r--r--Source/WebCore/rendering/RenderTheme.h2
-rw-r--r--Source/WebCore/rendering/RenderThemeChromiumLinux.cpp8
-rw-r--r--Source/WebCore/rendering/RenderThemeChromiumMac.h2
-rw-r--r--Source/WebCore/rendering/RenderThemeChromiumMac.mm4
-rw-r--r--Source/WebCore/rendering/RenderThemeChromiumWin.cpp54
-rw-r--r--Source/WebCore/rendering/RenderThemeMac.h2
-rw-r--r--Source/WebCore/rendering/RenderThemeMac.mm13
-rw-r--r--Source/WebCore/rendering/RenderThemeWin.cpp4
-rw-r--r--Source/WebCore/rendering/RenderThemeWin.h2
-rw-r--r--Source/WebCore/rendering/RenderTreeAsText.cpp32
-rw-r--r--Source/WebCore/rendering/RenderingAllInOne.cpp2
-rw-r--r--Source/WebCore/rendering/RootInlineBox.cpp26
-rw-r--r--Source/WebCore/rendering/RootInlineBox.h8
-rw-r--r--Source/WebCore/rendering/TextControlInnerElements.cpp535
-rw-r--r--Source/WebCore/rendering/TextControlInnerElements.h158
-rw-r--r--Source/WebCore/rendering/VerticalPositionCache.h2
-rw-r--r--Source/WebCore/rendering/break_lines.cpp10
-rw-r--r--Source/WebCore/rendering/break_lines.h18
-rw-r--r--Source/WebCore/rendering/style/ContentData.cpp4
-rw-r--r--Source/WebCore/rendering/style/ContentData.h14
-rw-r--r--Source/WebCore/rendering/style/QuotesData.cpp60
-rw-r--r--Source/WebCore/rendering/style/QuotesData.h43
-rw-r--r--Source/WebCore/rendering/style/RenderStyle.cpp17
-rw-r--r--Source/WebCore/rendering/style/RenderStyle.h28
-rw-r--r--Source/WebCore/rendering/style/RenderStyleConstants.h6
-rw-r--r--Source/WebCore/rendering/style/SVGRenderStyle.cpp6
-rw-r--r--Source/WebCore/rendering/style/SVGRenderStyle.h50
-rw-r--r--Source/WebCore/rendering/style/SVGRenderStyleDefs.cpp44
-rw-r--r--Source/WebCore/rendering/style/SVGRenderStyleDefs.h14
-rw-r--r--Source/WebCore/rendering/style/StyleAllInOne.cpp1
-rw-r--r--Source/WebCore/rendering/style/StyleRareInheritedData.cpp14
-rw-r--r--Source/WebCore/rendering/style/StyleRareInheritedData.h7
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResource.cpp39
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp4
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp6
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.cpp4
-rw-r--r--Source/WebCore/rendering/svg/SVGInlineTextBox.cpp51
-rw-r--r--Source/WebCore/rendering/svg/SVGInlineTextBox.h4
-rw-r--r--Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp9
-rw-r--r--Source/WebCore/rendering/svg/SVGResources.cpp11
-rw-r--r--Source/WebCore/rendering/svg/SVGTextMetrics.cpp6
104 files changed, 2555 insertions, 2117 deletions
diff --git a/Source/WebCore/rendering/AutoTableLayout.cpp b/Source/WebCore/rendering/AutoTableLayout.cpp
index bb0df0b..9775ec5 100644
--- a/Source/WebCore/rendering/AutoTableLayout.cpp
+++ b/Source/WebCore/rendering/AutoTableLayout.cpp
@@ -519,7 +519,6 @@ void AutoTableLayout::layout()
// fall through
break;
case Auto:
- case Static:
if (m_layoutStruct[i].emptyCellsOnly)
numAutoEmptyCellsOnly++;
else {
diff --git a/Source/WebCore/rendering/HitTestResult.cpp b/Source/WebCore/rendering/HitTestResult.cpp
index 5d9b3df..ba98eff 100644
--- a/Source/WebCore/rendering/HitTestResult.cpp
+++ b/Source/WebCore/rendering/HitTestResult.cpp
@@ -545,6 +545,23 @@ bool HitTestResult::addNodeToRectBasedTestResult(Node* node, int x, int y, const
return !rect.contains(rectForPoint(x, y));
}
+bool HitTestResult::addNodeToRectBasedTestResult(Node* node, int x, int y, const FloatRect& rect)
+{
+ // If it is not a rect-based hit test, this method has to be no-op.
+ // Return false, so the hit test stops.
+ if (!isRectBasedTest())
+ return false;
+
+ // If node is null, return true so the hit test can continue.
+ if (!node)
+ return true;
+
+ node = node->shadowAncestorNode();
+ m_rectBasedTestResult.add(node);
+
+ return !rect.contains(rectForPoint(x, y));
+}
+
void HitTestResult::append(const HitTestResult& other)
{
ASSERT(isRectBasedTest() && other.isRectBasedTest());
diff --git a/Source/WebCore/rendering/HitTestResult.h b/Source/WebCore/rendering/HitTestResult.h
index 1545da9..3aa17e3 100644
--- a/Source/WebCore/rendering/HitTestResult.h
+++ b/Source/WebCore/rendering/HitTestResult.h
@@ -20,6 +20,7 @@
#ifndef HitTestResult_h
#define HitTestResult_h
+#include "FloatRect.h"
#include "IntPoint.h"
#include "IntRect.h"
#include "IntSize.h"
@@ -109,7 +110,8 @@ public:
// Returns true if it is rect-based hit test and needs to continue until the rect is fully
// enclosed by the boundaries of a node.
- bool addNodeToRectBasedTestResult(Node*, int x, int y, const IntRect& rect = IntRect());
+ bool addNodeToRectBasedTestResult(Node*, int x, int y, const IntRect& = IntRect());
+ bool addNodeToRectBasedTestResult(Node*, int x, int y, const FloatRect&);
const ListHashSet<RefPtr<Node> >& rectBasedTestResult() const { return m_rectBasedTestResult; }
void append(const HitTestResult&);
diff --git a/Source/WebCore/rendering/InlineBox.cpp b/Source/WebCore/rendering/InlineBox.cpp
index 4fcbe2d..1f4e244 100644
--- a/Source/WebCore/rendering/InlineBox.cpp
+++ b/Source/WebCore/rendering/InlineBox.cpp
@@ -150,14 +150,12 @@ void InlineBox::attachLine()
toRenderBox(m_renderer)->setInlineBoxWrapper(this);
}
-void InlineBox::adjustPosition(int dx, int dy)
+void InlineBox::adjustPosition(float dx, float dy)
{
m_x += dx;
m_y += dy;
- if (m_renderer->isReplaced()) {
- RenderBox* box = toRenderBox(m_renderer);
- box->move(dx, dy);
- }
+ if (m_renderer->isReplaced())
+ toRenderBox(m_renderer)->positionLineBox(this);
}
void InlineBox::paint(PaintInfo& paintInfo, int tx, int ty)
@@ -278,21 +276,35 @@ bool InlineBox::canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidt
return !(boxRect.intersects(ellipsisRect));
}
-int InlineBox::placeEllipsisBox(bool, int, int, int, bool&)
+float InlineBox::placeEllipsisBox(bool, float, float, float, bool&)
{
// Use -1 to mean "we didn't set the position."
return -1;
}
-IntPoint InlineBox::locationIncludingFlipping()
+FloatPoint InlineBox::locationIncludingFlipping()
{
if (!renderer()->style()->isFlippedBlocksWritingMode())
- return IntPoint(x(), y());
+ return FloatPoint(x(), y());
RenderBlock* block = root()->block();
if (block->style()->isHorizontalWritingMode())
- return IntPoint(x(), block->height() - height() - y());
+ return FloatPoint(x(), block->height() - height() - y());
else
- return IntPoint(block->width() - width() - x(), y());
+ return FloatPoint(block->width() - width() - x(), y());
+}
+
+void InlineBox::flipForWritingMode(FloatRect& rect)
+{
+ if (!renderer()->style()->isFlippedBlocksWritingMode())
+ return;
+ root()->block()->flipForWritingMode(rect);
+}
+
+FloatPoint InlineBox::flipForWritingMode(const FloatPoint& point)
+{
+ if (!renderer()->style()->isFlippedBlocksWritingMode())
+ return point;
+ return root()->block()->flipForWritingMode(point);
}
void InlineBox::flipForWritingMode(IntRect& rect)
diff --git a/Source/WebCore/rendering/InlineBox.h b/Source/WebCore/rendering/InlineBox.h
index d486ec0..de7b224 100644
--- a/Source/WebCore/rendering/InlineBox.h
+++ b/Source/WebCore/rendering/InlineBox.h
@@ -68,7 +68,7 @@ public:
{
}
- InlineBox(RenderObject* obj, int x, int y, int logicalWidth, bool firstLine, bool constructed,
+ InlineBox(RenderObject* obj, float x, float y, float logicalWidth, bool firstLine, bool constructed,
bool dirty, bool extracted, bool isHorizontal, InlineBox* next, InlineBox* prev, InlineFlowBox* parent)
: m_next(next)
, m_prev(prev)
@@ -112,15 +112,15 @@ public:
virtual bool isLineBreak() const { return false; }
- virtual void adjustPosition(int dx, int dy);
- void adjustLineDirectionPosition(int delta)
+ virtual void adjustPosition(float dx, float dy);
+ void adjustLineDirectionPosition(float delta)
{
if (isHorizontal())
adjustPosition(delta, 0);
else
adjustPosition(0, delta);
}
- void adjustBlockDirectionPosition(int delta)
+ void adjustBlockDirectionPosition(float delta)
{
if (isHorizontal())
adjustPosition(0, delta);
@@ -220,28 +220,28 @@ public:
RootInlineBox* root();
// x() is the left side of the box in the containing block's coordinate system.
- void setX(int x) { m_x = x; }
- int x() const { return m_x; }
+ void setX(float x) { m_x = x; }
+ float x() const { return m_x; }
// y() is the top side of the box in the containing block's coordinate system.
- void setY(int y) { m_y = y; }
- int y() const { return m_y; }
+ void setY(float y) { m_y = y; }
+ float y() const { return m_y; }
- int width() const { return isHorizontal() ? logicalWidth() : logicalHeight(); }
- int height() const { return isHorizontal() ? logicalHeight() : logicalWidth(); }
-
- IntRect frameRect() const { return IntRect(x(), y(), width(), height()); }
+ float width() const { return isHorizontal() ? logicalWidth() : logicalHeight(); }
+ float height() const { return isHorizontal() ? logicalHeight() : logicalWidth(); }
// The logicalLeft position is the left edge of the line box in a horizontal line and the top edge in a vertical line.
- int logicalLeft() const { return isHorizontal() ? m_x : m_y; }
- int logicalRight() const { return logicalLeft() + logicalWidth(); }
- void setLogicalLeft(int left)
+ float logicalLeft() const { return isHorizontal() ? m_x : m_y; }
+ float logicalRight() const { return logicalLeft() + logicalWidth(); }
+ void setLogicalLeft(float left)
{
if (isHorizontal())
m_x = left;
else
m_y = left;
}
+ int pixelSnappedLogicalLeft() const { return logicalLeft(); }
+ int pixelSnappedLogicalRight() const { return ceilf(logicalRight()); }
// The logicalTop[ position is the top edge of the line box in a horizontal line and the left edge in a vertical line.
int logicalTop() const { return isHorizontal() ? m_y : m_x; }
@@ -255,8 +255,8 @@ public:
}
// The logical width is our extent in the line's overall inline direction, i.e., width for horizontal text and height for vertical text.
- void setLogicalWidth(int w) { m_logicalWidth = w; }
- int logicalWidth() const { return m_logicalWidth; }
+ void setLogicalWidth(float w) { m_logicalWidth = w; }
+ float logicalWidth() const { return m_logicalWidth; }
// The logical height is our extent in the block flow direction, i.e., height for horizontal text and width for vertical text.
int logicalHeight() const;
@@ -286,7 +286,7 @@ public:
virtual bool canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth);
// visibleLeftEdge, visibleRightEdge are in the parent's coordinate system.
- virtual int placeEllipsisBox(bool ltr, int visibleLeftEdge, int visibleRightEdge, int ellipsisWidth, bool&);
+ virtual float placeEllipsisBox(bool ltr, float visibleLeftEdge, float visibleRightEdge, float ellipsisWidth, bool&);
void setHasBadParent();
@@ -294,6 +294,8 @@ public:
bool visibleToHitTesting() const { return renderer()->style()->visibility() == VISIBLE && renderer()->style()->pointerEvents() != PE_NONE; }
+ EVerticalAlign verticalAlign() const { return renderer()->style(m_firstLine)->verticalAlign(); }
+
// Use with caution! The type is not checked!
RenderBoxModelObject* boxModelObject() const
{
@@ -302,7 +304,9 @@ public:
return 0;
}
- IntPoint locationIncludingFlipping();
+ FloatPoint locationIncludingFlipping();
+ void flipForWritingMode(FloatRect&);
+ FloatPoint flipForWritingMode(const FloatPoint&);
void flipForWritingMode(IntRect&);
IntPoint flipForWritingMode(const IntPoint&);
@@ -315,9 +319,9 @@ private:
public:
RenderObject* m_renderer;
- int m_x;
- int m_y;
- int m_logicalWidth;
+ float m_x;
+ float m_y;
+ float m_logicalWidth;
// Some of these bits are actually for subclasses and moved here to compact the structures.
diff --git a/Source/WebCore/rendering/InlineFlowBox.cpp b/Source/WebCore/rendering/InlineFlowBox.cpp
index aa9fcb5..e146dd9 100644
--- a/Source/WebCore/rendering/InlineFlowBox.cpp
+++ b/Source/WebCore/rendering/InlineFlowBox.cpp
@@ -67,6 +67,18 @@ int InlineFlowBox::getFlowSpacingLogicalWidth()
return totWidth;
}
+IntRect InlineFlowBox::roundedFrameRect() const
+{
+ // Begin by snapping the x and y coordinates to the nearest pixel.
+ int snappedX = lroundf(x());
+ int snappedY = lroundf(y());
+
+ int snappedMaxX = lroundf(x() + width());
+ int snappedMaxY = lroundf(y() + height());
+
+ return IntRect(snappedX, snappedY, snappedMaxX - snappedX, snappedMaxY - snappedY);
+}
+
void InlineFlowBox::addToLine(InlineBox* child)
{
ASSERT(!child->parent());
@@ -167,13 +179,13 @@ void InlineFlowBox::attachLineBoxToRenderObject()
toRenderInline(renderer())->lineBoxes()->attachLineBox(this);
}
-void InlineFlowBox::adjustPosition(int dx, int dy)
+void InlineFlowBox::adjustPosition(float dx, float dy)
{
InlineBox::adjustPosition(dx, dy);
for (InlineBox* child = firstChild(); child; child = child->nextOnLine())
child->adjustPosition(dx, dy);
if (m_overflow)
- m_overflow->move(dx, dy);
+ m_overflow->move(dx, dy); // FIXME: Rounding error here since overflow was pixel snapped, but nobody other than list markers passes non-integral values here.
}
RenderLineBoxList* InlineFlowBox::rendererLineBoxes() const
@@ -255,12 +267,12 @@ void InlineFlowBox::determineSpacingForFlowBoxes(bool lastLine, RenderObject* en
}
}
-int InlineFlowBox::placeBoxesInInlineDirection(int logicalLeft, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap& textBoxDataMap)
+float InlineFlowBox::placeBoxesInInlineDirection(float logicalLeft, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap& textBoxDataMap)
{
// Set our x position.
setLogicalLeft(logicalLeft);
- int startLogicalLeft = logicalLeft;
+ float startLogicalLeft = logicalLeft;
logicalLeft += borderLogicalLeft() + paddingLogicalLeft();
for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
@@ -345,17 +357,16 @@ bool InlineFlowBox::requiresIdeographicBaseline(const GlyphOverflowAndFallbackFo
return false;
}
-void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
- int maxPositionTop, int maxPositionBottom)
+void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent, int maxPositionTop, int maxPositionBottom)
{
for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
// The computed lineheight needs to be extended for the
// positioned elements
if (curr->renderer()->isPositioned())
continue; // Positioned placeholders don't affect calculations.
- if (curr->logicalTop() == PositionTop || curr->logicalTop() == PositionBottom) {
+ if (curr->verticalAlign() == TOP || curr->verticalAlign() == BOTTOM) {
int lineHeight = curr->lineHeight();
- if (curr->logicalTop() == PositionTop) {
+ if (curr->verticalAlign() == TOP) {
if (maxAscent + maxDescent < lineHeight)
maxDescent = lineHeight - maxAscent;
}
@@ -397,40 +408,37 @@ static int verticalPositionForBox(InlineBox* box, FontBaseline baselineType, boo
int verticalPosition = 0;
EVerticalAlign verticalAlign = renderer->style()->verticalAlign();
- if (verticalAlign == TOP)
- verticalPosition = PositionTop;
- else if (verticalAlign == BOTTOM)
- verticalPosition = PositionBottom;
- else {
- RenderObject* parent = renderer->parent();
- if (parent->isRenderInline() && parent->style()->verticalAlign() != TOP && parent->style()->verticalAlign() != BOTTOM)
- verticalPosition = box->parent()->logicalTop();
-
- if (verticalAlign != BASELINE) {
- const Font& font = parent->style(firstLine)->font();
- const FontMetrics& fontMetrics = font.fontMetrics();
- int fontSize = font.pixelSize();
-
- LineDirectionMode lineDirection = parent->style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
-
- if (verticalAlign == SUB)
- verticalPosition += fontSize / 5 + 1;
- else if (verticalAlign == SUPER)
- verticalPosition -= fontSize / 3 + 1;
- else if (verticalAlign == TEXT_TOP)
- verticalPosition += renderer->baselinePosition(baselineType, firstLine, lineDirection) - fontMetrics.ascent(baselineType);
- else if (verticalAlign == MIDDLE)
- verticalPosition += -static_cast<int>(fontMetrics.xHeight() / 2) - renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType, firstLine, lineDirection);
- else if (verticalAlign == TEXT_BOTTOM) {
- verticalPosition += fontMetrics.descent(baselineType);
- // lineHeight - baselinePosition is always 0 for replaced elements (except inline blocks), so don't bother wasting time in that case.
- if (!renderer->isReplaced() || renderer->isInlineBlockOrInlineTable())
- verticalPosition -= (renderer->lineHeight(firstLine, lineDirection) - renderer->baselinePosition(baselineType, firstLine, lineDirection));
- } else if (verticalAlign == BASELINE_MIDDLE)
- verticalPosition += -renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType, firstLine, lineDirection);
- else if (verticalAlign == LENGTH)
- verticalPosition -= renderer->style()->verticalAlignLength().calcValue(renderer->lineHeight(firstLine, lineDirection));
- }
+ if (verticalAlign == TOP || verticalAlign == BOTTOM)
+ return 0;
+
+ RenderObject* parent = renderer->parent();
+ if (parent->isRenderInline() && parent->style()->verticalAlign() != TOP && parent->style()->verticalAlign() != BOTTOM)
+ verticalPosition = box->parent()->logicalTop();
+
+ if (verticalAlign != BASELINE) {
+ const Font& font = parent->style(firstLine)->font();
+ const FontMetrics& fontMetrics = font.fontMetrics();
+ int fontSize = font.pixelSize();
+
+ LineDirectionMode lineDirection = parent->style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
+
+ if (verticalAlign == SUB)
+ verticalPosition += fontSize / 5 + 1;
+ else if (verticalAlign == SUPER)
+ verticalPosition -= fontSize / 3 + 1;
+ else if (verticalAlign == TEXT_TOP)
+ verticalPosition += renderer->baselinePosition(baselineType, firstLine, lineDirection) - fontMetrics.ascent(baselineType);
+ else if (verticalAlign == MIDDLE)
+ verticalPosition += -static_cast<int>(fontMetrics.xHeight() / 2) - renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType, firstLine, lineDirection);
+ else if (verticalAlign == TEXT_BOTTOM) {
+ verticalPosition += fontMetrics.descent(baselineType);
+ // lineHeight - baselinePosition is always 0 for replaced elements (except inline blocks), so don't bother wasting time in that case.
+ if (!renderer->isReplaced() || renderer->isInlineBlockOrInlineTable())
+ verticalPosition -= (renderer->lineHeight(firstLine, lineDirection) - renderer->baselinePosition(baselineType, firstLine, lineDirection));
+ } else if (verticalAlign == BASELINE_MIDDLE)
+ verticalPosition += -renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType, firstLine, lineDirection);
+ else if (verticalAlign == LENGTH)
+ verticalPosition -= renderer->style()->verticalAlignLength().calcValue(renderer->lineHeight(firstLine, lineDirection));
}
// Store the cached value.
@@ -542,10 +550,10 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
}
}
- if (curr->logicalTop() == PositionTop) {
+ if (curr->verticalAlign() == TOP) {
if (maxPositionTop < lineHeight)
maxPositionTop = lineHeight;
- } else if (curr->logicalTop() == PositionBottom) {
+ } else if (curr->verticalAlign() == BOTTOM) {
if (maxPositionBottom < lineHeight)
maxPositionBottom = lineHeight;
} else if ((!isInlineFlow || static_cast<InlineFlowBox*>(curr)->hasTextChildren()) || curr->boxModelObject()->hasInlineDirectionBordersOrPadding() || strictMode) {
@@ -592,9 +600,9 @@ void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAs
lineTopIncludingMargins, lineBottomIncludingMargins, hasAnnotationsBefore, hasAnnotationsAfter, baselineType);
bool childAffectsTopBottomPos = true;
- if (curr->logicalTop() == PositionTop)
+ if (curr->verticalAlign() == TOP)
curr->setLogicalTop(top);
- else if (curr->logicalTop() == PositionBottom)
+ else if (curr->verticalAlign() == BOTTOM)
curr->setLogicalTop(top + maxHeight - curr->lineHeight());
else {
if ((isInlineFlow && !static_cast<InlineFlowBox*>(curr)->hasTextChildren()) && !curr->boxModelObject()->hasInlineDirectionBordersOrPadding() && !strictMode)
@@ -724,8 +732,8 @@ void InlineFlowBox::addBoxShadowVisualOverflow(IntRect& logicalVisualOverflow)
int boxShadowLogicalRight;
renderer()->style(m_firstLine)->getBoxShadowInlineDirectionExtent(boxShadowLogicalLeft, boxShadowLogicalRight);
- int logicalLeftVisualOverflow = min(logicalLeft() + boxShadowLogicalLeft, logicalVisualOverflow.x());
- int logicalRightVisualOverflow = max(logicalRight() + boxShadowLogicalRight, logicalVisualOverflow.maxX());
+ int logicalLeftVisualOverflow = min(pixelSnappedLogicalLeft() + boxShadowLogicalLeft, logicalVisualOverflow.x());
+ int logicalRightVisualOverflow = max(pixelSnappedLogicalRight() + boxShadowLogicalRight, logicalVisualOverflow.maxX());
logicalVisualOverflow = IntRect(logicalLeftVisualOverflow, logicalTopVisualOverflow,
logicalRightVisualOverflow - logicalLeftVisualOverflow, logicalBottomVisualOverflow - logicalTopVisualOverflow);
@@ -781,8 +789,8 @@ void InlineFlowBox::addTextBoxVisualOverflow(const InlineTextBox* textBox, Glyph
int logicalTopVisualOverflow = min(textBox->logicalTop() + childOverflowLogicalTop, logicalVisualOverflow.y());
int logicalBottomVisualOverflow = max(textBox->logicalBottom() + childOverflowLogicalBottom, logicalVisualOverflow.maxY());
- int logicalLeftVisualOverflow = min(textBox->logicalLeft() + childOverflowLogicalLeft, logicalVisualOverflow.x());
- int logicalRightVisualOverflow = max(textBox->logicalRight() + childOverflowLogicalRight, logicalVisualOverflow.maxX());
+ int logicalLeftVisualOverflow = min(textBox->pixelSnappedLogicalLeft() + childOverflowLogicalLeft, logicalVisualOverflow.x());
+ int logicalRightVisualOverflow = max(textBox->pixelSnappedLogicalRight() + childOverflowLogicalRight, logicalVisualOverflow.maxX());
logicalVisualOverflow = IntRect(logicalLeftVisualOverflow, logicalTopVisualOverflow,
logicalRightVisualOverflow - logicalLeftVisualOverflow, logicalBottomVisualOverflow - logicalTopVisualOverflow);
@@ -819,7 +827,7 @@ void InlineFlowBox::computeOverflow(int lineTop, int lineBottom, bool strictMode
// Visual overflow just includes overflow for stuff we need to repaint ourselves. Self-painting layers are ignored.
// Layout overflow is used to determine scrolling extent, so it still includes child layers and also factors in
// transforms, relative positioning, etc.
- IntRect logicalLayoutOverflow(logicalLeft(), topOverflow, logicalWidth(), bottomOverflow - topOverflow);
+ IntRect logicalLayoutOverflow(enclosingIntRect(FloatRect(logicalLeft(), topOverflow, logicalWidth(), bottomOverflow - topOverflow)));
IntRect logicalVisualOverflow(logicalLayoutOverflow);
// box-shadow on root line boxes is applying to the block and not to the lines.
@@ -864,7 +872,7 @@ void InlineFlowBox::computeOverflow(int lineTop, int lineBottom, bool strictMode
// all functions that query overflow.
void InlineFlowBox::setLayoutOverflow(const IntRect& rect)
{
- IntRect frameBox = frameRect();
+ IntRect frameBox = enclosingIntRect(FloatRect(x(), y(), width(), height()));
if (frameBox == rect || rect.isEmpty())
return;
@@ -876,7 +884,7 @@ void InlineFlowBox::setLayoutOverflow(const IntRect& rect)
void InlineFlowBox::setVisualOverflow(const IntRect& rect)
{
- IntRect frameBox = frameRect();
+ IntRect frameBox = enclosingIntRect(FloatRect(x(), y(), width(), height()));
if (frameBox == rect || rect.isEmpty())
return;
@@ -912,9 +920,9 @@ bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
}
// Now check ourselves.
- IntPoint boxOrigin = locationIncludingFlipping();
+ FloatPoint boxOrigin = locationIncludingFlipping();
boxOrigin.move(tx, ty);
- IntRect rect(boxOrigin, IntSize(width(), height()));
+ FloatRect rect(boxOrigin, IntSize(width(), height()));
if (visibleToHitTesting() && rect.intersects(result.rectForPoint(x, y))) {
renderer()->updateHitTestResult(result, flipForWritingMode(IntPoint(x - tx, y - ty))); // Don't add in m_x or m_y here, we want coords in the containing block's space.
if (!result.addNodeToRectBasedTestResult(renderer()->node(), x, y, rect))
@@ -943,13 +951,20 @@ void InlineFlowBox::paint(PaintInfo& paintInfo, int tx, int ty)
RenderBlock* cb = 0;
bool containingBlockPaintsContinuationOutline = inlineFlow->continuation() || inlineFlow->isInlineElementContinuation();
- if (containingBlockPaintsContinuationOutline) {
- cb = renderer()->containingBlock()->containingBlock();
-
- for (RenderBoxModelObject* box = boxModelObject(); box != cb; box = box->parent()->enclosingBoxModelObject()) {
- if (box->hasSelfPaintingLayer()) {
- containingBlockPaintsContinuationOutline = false;
- break;
+ if (containingBlockPaintsContinuationOutline) {
+ // FIXME: See https://bugs.webkit.org/show_bug.cgi?id=54690. We currently don't reconnect inline continuations
+ // after a child removal. As a result, those merged inlines do not get seperated and hence not get enclosed by
+ // anonymous blocks. In this case, it is better to bail out and paint it ourself.
+ RenderBlock* enclosingAnonymousBlock = renderer()->containingBlock();
+ if (!enclosingAnonymousBlock->isAnonymousBlock())
+ containingBlockPaintsContinuationOutline = false;
+ else {
+ cb = enclosingAnonymousBlock->containingBlock();
+ for (RenderBoxModelObject* box = boxModelObject(); box != cb; box = box->parent()->enclosingBoxModelObject()) {
+ if (box->hasSelfPaintingLayer()) {
+ containingBlockPaintsContinuationOutline = false;
+ break;
+ }
}
}
}
@@ -1050,10 +1065,12 @@ void InlineFlowBox::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
if (!paintInfo.shouldPaintWithinRoot(renderer()) || renderer()->style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseForeground)
return;
- int x = m_x;
- int y = m_y;
- int w = width();
- int h = height();
+ // Pixel snap background/border painting.
+ IntRect frameRect = roundedFrameRect();
+ int x = frameRect.x();
+ int y = frameRect.y();
+ int w = frameRect.width();
+ int h = frameRect.height();
// Constrain our background/border painting to the line top and bottom if necessary.
bool noQuirksMode = renderer()->document()->inNoQuirksMode();
@@ -1079,14 +1096,11 @@ void InlineFlowBox::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
RenderStyle* styleToUse = renderer()->style(m_firstLine);
if ((!parent() && m_firstLine && styleToUse != renderer()->style()) || (parent() && renderer()->hasBoxDecorations())) {
// Shadow comes first and is behind the background and border.
- if (styleToUse->boxShadow())
- paintBoxShadow(context, styleToUse, Normal, tx, ty, w, h);
+ paintBoxShadow(context, styleToUse, Normal, tx, ty, w, h);
Color c = styleToUse->visitedDependentColor(CSSPropertyBackgroundColor);
paintFillLayers(paintInfo, c, styleToUse->backgroundLayers(), tx, ty, w, h);
-
- if (styleToUse->boxShadow())
- paintBoxShadow(context, styleToUse, Inset, tx, ty, w, h);
+ paintBoxShadow(context, styleToUse, Inset, tx, ty, w, h);
// :first-line cannot be used to put borders on a line. Always paint borders with our
// non-first-line style.
@@ -1133,10 +1147,12 @@ void InlineFlowBox::paintMask(PaintInfo& paintInfo, int tx, int ty)
if (!paintInfo.shouldPaintWithinRoot(renderer()) || renderer()->style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseMask)
return;
- int x = m_x;
- int y = m_y;
- int w = width();
- int h = height();
+ // Pixel snap mask painting.
+ IntRect frameRect = roundedFrameRect();
+ int x = frameRect.x();
+ int y = frameRect.y();
+ int w = frameRect.width();
+ int h = frameRect.height();
// Constrain our background/border painting to the line top and bottom if necessary.
bool noQuirksMode = renderer()->document()->inNoQuirksMode();
@@ -1237,14 +1253,14 @@ bool InlineFlowBox::canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsis
return true;
}
-int InlineFlowBox::placeEllipsisBox(bool ltr, int blockLeftEdge, int blockRightEdge, int ellipsisWidth, bool& foundBox)
+float InlineFlowBox::placeEllipsisBox(bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, bool& foundBox)
{
- int result = -1;
+ float result = -1;
// We iterate over all children, the foundBox variable tells us when we've found the
// box containing the ellipsis. All boxes after that one in the flow are hidden.
// If our flow is ltr then iterate over the boxes from left to right, otherwise iterate
// from right to left. Varying the order allows us to correctly hide the boxes following the ellipsis.
- InlineBox *box = ltr ? firstChild() : lastChild();
+ InlineBox* box = ltr ? firstChild() : lastChild();
// NOTE: these will cross after foundBox = true.
int visibleLeftEdge = blockLeftEdge;
diff --git a/Source/WebCore/rendering/InlineFlowBox.h b/Source/WebCore/rendering/InlineFlowBox.h
index d47111f8..918cf5d 100644
--- a/Source/WebCore/rendering/InlineFlowBox.h
+++ b/Source/WebCore/rendering/InlineFlowBox.h
@@ -85,7 +85,7 @@ public:
virtual void deleteLine(RenderArena*);
virtual void extractLine();
virtual void attachLine();
- virtual void adjustPosition(int dx, int dy);
+ virtual void adjustPosition(float dx, float dy);
virtual void extractLineBoxFromRenderObject();
virtual void attachLineBoxToRenderObject();
@@ -93,6 +93,8 @@ public:
virtual void clearTruncation();
+ IntRect roundedFrameRect() const;
+
virtual void paintBoxDecorations(PaintInfo&, int tx, int ty);
virtual void paintMask(PaintInfo&, int tx, int ty);
void paintFillLayers(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int w, int h, CompositeOperator = CompositeSourceOver);
@@ -155,7 +157,7 @@ public:
void determineSpacingForFlowBoxes(bool lastLine, RenderObject* endObject);
int getFlowSpacingLogicalWidth();
bool onEndChain(RenderObject* endObject);
- int placeBoxesInInlineDirection(int logicalLeft, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap&);
+ float placeBoxesInInlineDirection(float logicalLeft, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap&);
void computeLogicalBoxHeights(int& maxPositionTop, int& maxPositionBottom,
int& maxAscent, int& maxDescent, bool& setMaxAscent, bool& setMaxDescent,
bool strictMode, GlyphOverflowAndFallbackFontsMap&, FontBaseline, VerticalPositionCache&);
@@ -176,7 +178,7 @@ public:
virtual RenderObject::SelectionState selectionState();
virtual bool canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth);
- virtual int placeEllipsisBox(bool ltr, int blockLeftEdge, int blockRightEdge, int ellipsisWidth, bool&);
+ virtual float placeEllipsisBox(bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, bool&);
bool hasTextChildren() const { return m_hasTextChildren; }
@@ -187,10 +189,10 @@ public:
// For horizontal-tb and vertical-lr they will match physical directions, but for horizontal-bt and vertical-rl, the top/bottom and left/right
// respectively are flipped when compared to their physical counterparts. For example minX is on the left in vertical-lr, but it is on the right in vertical-rl.
int minYLayoutOverflow() const { return m_overflow ? m_overflow->minYLayoutOverflow() : m_y; }
- int maxYLayoutOverflow() const { return m_overflow ? m_overflow->maxYLayoutOverflow() : m_y + height(); }
+ int maxYLayoutOverflow() const { return m_overflow ? m_overflow->maxYLayoutOverflow() : ceilf(m_y + height()); }
int minXLayoutOverflow() const { return m_overflow ? m_overflow->minXLayoutOverflow() : m_x; }
- int maxXLayoutOverflow() const { return m_overflow ? m_overflow->maxXLayoutOverflow() : m_x + width(); }
- IntRect layoutOverflowRect() const { return m_overflow ? m_overflow->layoutOverflowRect() : IntRect(m_x, m_y, width(), height()); }
+ int maxXLayoutOverflow() const { return m_overflow ? m_overflow->maxXLayoutOverflow() : ceilf(m_x + width()); }
+ IntRect layoutOverflowRect() const { return m_overflow ? m_overflow->layoutOverflowRect() : enclosingIntRect(FloatRect(m_x, m_y, width(), height())); }
int logicalLeftLayoutOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? minXLayoutOverflow() : minYLayoutOverflow(); }
int logicalRightLayoutOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? maxXLayoutOverflow() : maxYLayoutOverflow(); }
int logicalTopLayoutOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? minYVisualOverflow() : minXVisualOverflow(); }
@@ -204,10 +206,10 @@ public:
}
int minYVisualOverflow() const { return m_overflow ? m_overflow->minYVisualOverflow() : m_y; }
- int maxYVisualOverflow() const { return m_overflow ? m_overflow->maxYVisualOverflow() : m_y + height(); }
+ int maxYVisualOverflow() const { return m_overflow ? m_overflow->maxYVisualOverflow() : ceilf(m_y + height()); }
int minXVisualOverflow() const { return m_overflow ? m_overflow->minXVisualOverflow() : m_x; }
- int maxXVisualOverflow() const { return m_overflow ? m_overflow->maxXVisualOverflow() : m_x + width(); }
- IntRect visualOverflowRect() const { return m_overflow ? m_overflow->visualOverflowRect() : IntRect(m_x, m_y, width(), height()); }
+ int maxXVisualOverflow() const { return m_overflow ? m_overflow->maxXVisualOverflow() : ceilf(m_x + width()); }
+ IntRect visualOverflowRect() const { return m_overflow ? m_overflow->visualOverflowRect() : enclosingIntRect(FloatRect(m_x, m_y, width(), height())); }
int logicalLeftVisualOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? minXVisualOverflow() : minYVisualOverflow(); }
int logicalRightVisualOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? maxXVisualOverflow() : maxYVisualOverflow(); }
int logicalTopVisualOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? minYVisualOverflow() : minXVisualOverflow(); }
diff --git a/Source/WebCore/rendering/InlineTextBox.cpp b/Source/WebCore/rendering/InlineTextBox.cpp
index 4802f02..6d6ca4d 100644
--- a/Source/WebCore/rendering/InlineTextBox.cpp
+++ b/Source/WebCore/rendering/InlineTextBox.cpp
@@ -208,7 +208,7 @@ void InlineTextBox::attachLine()
toRenderText(renderer())->attachTextBox(this);
}
-int InlineTextBox::placeEllipsisBox(bool flowIsLTR, int visibleLeftEdge, int visibleRightEdge, int ellipsisWidth, bool& foundBox)
+float InlineTextBox::placeEllipsisBox(bool flowIsLTR, float visibleLeftEdge, float visibleRightEdge, float ellipsisWidth, bool& foundBox)
{
if (foundBox) {
m_truncation = cFullTruncation;
@@ -216,7 +216,7 @@ int InlineTextBox::placeEllipsisBox(bool flowIsLTR, int visibleLeftEdge, int vis
}
// For LTR this is the left edge of the box, for RTL, the right edge in parent coordinates.
- int ellipsisX = flowIsLTR ? visibleRightEdge - ellipsisWidth : visibleLeftEdge + ellipsisWidth;
+ float ellipsisX = flowIsLTR ? visibleRightEdge - ellipsisWidth : visibleLeftEdge + ellipsisWidth;
// Criteria for full truncation:
// LTR: the left edge of the ellipsis is to the left of our text run.
@@ -258,7 +258,7 @@ int InlineTextBox::placeEllipsisBox(bool flowIsLTR, int visibleLeftEdge, int vis
// If we got here that means that we were only partially truncated and we need to return the pixel offset at which
// to place the ellipsis.
- int widthOfVisibleText = toRenderText(renderer())->width(m_start, offset, textPos(), m_firstLine);
+ float widthOfVisibleText = toRenderText(renderer())->width(m_start, offset, textPos(), m_firstLine);
// The ellipsis needs to be placed just after the last visible character.
// Where "after" is defined by the flow directionality, not the inline
@@ -326,9 +326,9 @@ bool InlineTextBox::nodeAtPoint(const HitTestRequest&, HitTestResult& result, in
if (isLineBreak())
return false;
- IntPoint boxOrigin = locationIncludingFlipping();
+ FloatPoint boxOrigin = locationIncludingFlipping();
boxOrigin.move(tx, ty);
- IntRect rect(boxOrigin, IntSize(width(), height()));
+ FloatRect rect(boxOrigin, IntSize(width(), height()));
if (m_truncation != cFullTruncation && visibleToHitTesting() && rect.intersects(result.rectForPoint(x, y))) {
renderer()->updateHitTestResult(result, flipForWritingMode(IntPoint(x - tx, y - ty)));
if (!result.addNodeToRectBasedTestResult(renderer()->node(), x, y, rect))
@@ -364,8 +364,8 @@ FloatSize InlineTextBox::applyShadowToGraphicsContext(GraphicsContext* context,
return extraOffset;
}
-static void paintTextWithShadows(GraphicsContext* context, const Font& font, const TextRun& textRun, const AtomicString& emphasisMark, int emphasisMarkOffset, int startOffset, int endOffset, int truncationPoint, const IntPoint& textOrigin,
- const IntRect& boxRect, const ShadowData* shadow, bool stroked, bool horizontal)
+static void paintTextWithShadows(GraphicsContext* context, const Font& font, const TextRun& textRun, const AtomicString& emphasisMark, int emphasisMarkOffset, int startOffset, int endOffset, int truncationPoint, const FloatPoint& textOrigin,
+ const FloatRect& boxRect, const ShadowData* shadow, bool stroked, bool horizontal)
{
Color fillColor = context->fillColor();
ColorSpace fillColorSpace = context->fillColorSpace();
@@ -489,10 +489,10 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty)
ty -= styleToUse->isHorizontalWritingMode() ? 0 : logicalHeight();
- IntPoint boxOrigin = locationIncludingFlipping();
+ FloatPoint boxOrigin = locationIncludingFlipping();
boxOrigin.move(tx, ty);
- IntRect boxRect(boxOrigin, IntSize(logicalWidth(), logicalHeight()));
- IntPoint textOrigin = IntPoint(boxOrigin.x(), boxOrigin.y() + styleToUse->fontMetrics().ascent());
+ FloatRect boxRect(boxOrigin, IntSize(logicalWidth(), logicalHeight()));
+ FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + styleToUse->fontMetrics().ascent());
RenderCombineText* combinedText = styleToUse->hasTextCombine() ? toRenderCombineText(textRenderer()) : 0;
bool shouldRotate = !isHorizontal() && (!combinedText || !combinedText->isCombined());
@@ -747,7 +747,7 @@ void InlineTextBox::selectionStartEnd(int& sPos, int& ePos)
ePos = min(endPos - m_start, (int)m_len);
}
-void InlineTextBox::paintSelection(GraphicsContext* context, const IntPoint& boxOrigin, RenderStyle* style, const Font& font)
+void InlineTextBox::paintSelection(GraphicsContext* context, const FloatPoint& boxOrigin, RenderStyle* style, const Font& font)
{
// See if we have a selection to paint at all.
int sPos, ePos;
@@ -781,6 +781,7 @@ void InlineTextBox::paintSelection(GraphicsContext* context, const IntPoint& box
int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
int selHeight = selectionHeight();
+<<<<<<< HEAD
IntPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
context->clip(IntRect(localOrigin, IntSize(m_logicalWidth, selHeight)));
#ifdef ANDROID_DISABLE_ROUNDING_HACKS
@@ -790,6 +791,10 @@ void InlineTextBox::paintSelection(GraphicsContext* context, const IntPoint& box
textRun.disableRoundingHacks();
context->drawHighlightForText(font, textRun, localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
#else
+=======
+ FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
+ context->clip(FloatRect(localOrigin, FloatSize(m_logicalWidth, selHeight)));
+>>>>>>> WebKit at r80534
context->drawHighlightForText(font, TextRun(characters, length, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(),
!isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()),
localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
@@ -797,7 +802,7 @@ void InlineTextBox::paintSelection(GraphicsContext* context, const IntPoint& box
context->restore();
}
-void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const IntPoint& boxOrigin, RenderStyle* style, const Font& font, int startPos, int endPos)
+void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const FloatPoint& boxOrigin, RenderStyle* style, const Font& font, int startPos, int endPos)
{
int offset = m_start;
int sPos = max(startPos - offset, 0);
@@ -814,6 +819,7 @@ void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const I
int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
int selHeight = selectionHeight();
+<<<<<<< HEAD
IntPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
#ifdef ANDROID_DISABLE_ROUNDING_HACKS
TextRun textRun = TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(),
@@ -822,6 +828,9 @@ void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const I
textRun.disableRoundingHacks();
context->drawHighlightForText(font, textRun, localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
#else
+=======
+ FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
+>>>>>>> WebKit at r80534
context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(),
!isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()),
localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
@@ -849,14 +858,14 @@ void InlineTextBox::paintCustomHighlight(int tx, int ty, const AtomicString& typ
#endif
-void InlineTextBox::paintDecoration(GraphicsContext* context, const IntPoint& boxOrigin, int deco, const ShadowData* shadow)
+void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint& boxOrigin, int deco, const ShadowData* shadow)
{
if (m_truncation == cFullTruncation)
return;
- IntPoint localOrigin = boxOrigin;
+ FloatPoint localOrigin = boxOrigin;
- int width = m_logicalWidth;
+ float width = m_logicalWidth;
if (m_truncation != cNoTruncation) {
width = toRenderText(renderer())->width(m_start, m_truncation, textPos(), m_firstLine);
if (!isLeftToRightDirection())
@@ -880,9 +889,9 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const IntPoint& bo
int extraOffset = 0;
if (!linesAreOpaque && shadow && shadow->next()) {
context->save();
- IntRect clipRect(localOrigin, IntSize(width, baseline + 2));
+ FloatRect clipRect(localOrigin, FloatSize(width, baseline + 2));
for (const ShadowData* s = shadow; s; s = s->next()) {
- IntRect shadowRect(localOrigin, IntSize(width, baseline + 2));
+ FloatRect shadowRect(localOrigin, FloatSize(width, baseline + 2));
shadowRect.inflate(s->blur());
int shadowX = isHorizontal() ? s->x() : s->y();
int shadowY = isHorizontal() ? s->y() : -s->x();
@@ -909,7 +918,7 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const IntPoint& bo
}
int shadowX = isHorizontal() ? shadow->x() : shadow->y();
int shadowY = isHorizontal() ? shadow->y() : -shadow->x();
- context->setShadow(IntSize(shadowX, shadowY - extraOffset), shadow->blur(), shadow->color(), colorSpace);
+ context->setShadow(FloatSize(shadowX, shadowY - extraOffset), shadow->blur(), shadow->color(), colorSpace);
setShadow = true;
shadow = shadow->next();
}
@@ -918,7 +927,7 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const IntPoint& bo
context->setStrokeColor(underline, colorSpace);
context->setStrokeStyle(SolidStroke);
// Leave one pixel of white between the baseline and the underline.
- context->drawLineForText(IntPoint(localOrigin.x(), localOrigin.y() + baseline + 1), width, isPrinting);
+ context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + baseline + 1), width, isPrinting);
}
if (deco & OVERLINE) {
context->setStrokeColor(overline, colorSpace);
@@ -928,7 +937,7 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const IntPoint& bo
if (deco & LINE_THROUGH) {
context->setStrokeColor(linethrough, colorSpace);
context->setStrokeStyle(SolidStroke);
- context->drawLineForText(IntPoint(localOrigin.x(), localOrigin.y() + 2 * baseline / 3), width, isPrinting);
+ context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + 2 * baseline / 3), width, isPrinting);
}
} while (shadow);
@@ -953,7 +962,7 @@ static GraphicsContext::TextCheckingLineStyle textCheckingLineStyleForMarkerType
}
}
-void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, const IntPoint& boxOrigin, const DocumentMarker& marker, RenderStyle* style, const Font& font, bool grammar)
+void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, const FloatPoint& boxOrigin, const DocumentMarker& marker, RenderStyle* style, const Font& font, bool grammar)
{
// Never print spelling/grammar markers (5327887)
if (textRenderer()->document()->printing())
@@ -962,8 +971,8 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, const IntP
if (m_truncation == cFullTruncation)
return;
- int start = 0; // start of line to draw, relative to tx
- int width = m_logicalWidth; // how much line to draw
+ float start = 0; // start of line to draw, relative to tx
+ float width = m_logicalWidth; // how much line to draw
// Determine whether we need to measure text
bool markerSpansWholeBox = true;
@@ -984,13 +993,18 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, const IntP
// Calculate start & width
int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
int selHeight = selectionHeight();
- IntPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY);
+ FloatPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY);
TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
+<<<<<<< HEAD
#ifdef ANDROID_DISABLE_ROUNDING_HACKS
if (m_disableRoundingHacks)
run.disableRoundingHacks();
#endif
+=======
+
+ // FIXME: Convert the document markers to float rects.
+>>>>>>> WebKit at r80534
IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, selHeight, startPosition, endPosition));
start = markerRect.x() - startPoint.x();
width = markerRect.width();
@@ -1021,10 +1035,10 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, const IntP
// In larger fonts, though, place the underline up near the baseline to prevent a big gap.
underlineOffset = baseline + 2;
}
- pt->drawLineForTextChecking(IntPoint(boxOrigin.x() + start, boxOrigin.y() + underlineOffset), width, textCheckingLineStyleForMarkerType(marker.type));
+ pt->drawLineForTextChecking(FloatPoint(boxOrigin.x() + start, boxOrigin.y() + underlineOffset), width, textCheckingLineStyleForMarkerType(marker.type));
}
-void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const IntPoint& boxOrigin, const DocumentMarker& marker, RenderStyle* style, const Font& font)
+void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const FloatPoint& boxOrigin, const DocumentMarker& marker, RenderStyle* style, const Font& font)
{
// Use same y positioning and height as for selection, so that when the selection and this highlight are on
// the same word there are no pieces sticking out.
@@ -1051,8 +1065,8 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const IntPoint& bo
renderer()->theme()->platformInactiveTextSearchHighlightColor();
pt->save();
updateGraphicsContext(pt, color, color, 0, style->colorSpace()); // Don't draw text at all!
- pt->clip(IntRect(boxOrigin.x(), boxOrigin.y() - deltaY, m_logicalWidth, selHeight));
- pt->drawHighlightForText(font, run, IntPoint(boxOrigin.x(), boxOrigin.y() - deltaY), selHeight, color, style->colorSpace(), sPos, ePos);
+ pt->clip(FloatRect(boxOrigin.x(), boxOrigin.y() - deltaY, m_logicalWidth, selHeight));
+ pt->drawHighlightForText(font, run, FloatPoint(boxOrigin.x(), boxOrigin.y() - deltaY), selHeight, color, style->colorSpace(), sPos, ePos);
pt->restore();
}
}
@@ -1078,7 +1092,7 @@ void InlineTextBox::computeRectForReplacementMarker(const DocumentMarker& marker
renderer()->document()->markers()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
}
-void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, const IntPoint& boxOrigin, RenderStyle* style, const Font& font, bool background)
+void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, const FloatPoint& boxOrigin, RenderStyle* style, const Font& font, bool background)
{
if (!renderer()->node())
return;
@@ -1096,6 +1110,7 @@ void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, const IntPoint& bo
case DocumentMarker::Grammar:
case DocumentMarker::Spelling:
case DocumentMarker::CorrectionIndicator:
+ case DocumentMarker::Replacement:
if (background)
continue;
break;
@@ -1128,9 +1143,11 @@ void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, const IntPoint& bo
paintTextMatchMarker(pt, boxOrigin, marker, style, font);
break;
case DocumentMarker::CorrectionIndicator:
- computeRectForReplacementMarker(marker, style, font);
paintSpellingOrGrammarMarker(pt, boxOrigin, marker, style, font, false);
break;
+ case DocumentMarker::Replacement:
+ computeRectForReplacementMarker(marker, style, font);
+ break;
default:
ASSERT_NOT_REACHED();
}
@@ -1138,14 +1155,13 @@ void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, const IntPoint& bo
}
}
-
-void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, const IntPoint& boxOrigin, const CompositionUnderline& underline)
+void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, const FloatPoint& boxOrigin, const CompositionUnderline& underline)
{
if (m_truncation == cFullTruncation)
return;
- int start = 0; // start of line to draw, relative to tx
- int width = m_logicalWidth; // how much line to draw
+ float start = 0; // start of line to draw, relative to tx
+ float width = m_logicalWidth; // how much line to draw
bool useWholeWidth = true;
unsigned paintStart = m_start;
unsigned paintEnd = end() + 1; // end points at the last char, not past it
@@ -1181,7 +1197,7 @@ void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, const IntPoi
ctx->setStrokeColor(underline.color, renderer()->style()->colorSpace());
ctx->setStrokeThickness(lineThickness);
- ctx->drawLineForText(IntPoint(boxOrigin.x() + start, boxOrigin.y() + logicalHeight() - lineThickness), width, textRenderer()->document()->printing());
+ ctx->drawLineForText(FloatPoint(boxOrigin.x() + start, boxOrigin.y() + logicalHeight() - lineThickness), width, textRenderer()->document()->printing());
}
int InlineTextBox::caretMinOffset() const
@@ -1199,7 +1215,7 @@ unsigned InlineTextBox::caretMaxRenderedOffset() const
return m_start + m_len;
}
-int InlineTextBox::textPos() const
+float InlineTextBox::textPos() const
{
// When computing the width of a text run, RenderBlock::computeInlineDirectionPositionsForLine() doesn't include the actual offset
// from the containing block edge in its measurement. textPos() should be consistent so the text are rendered in the same width.
@@ -1208,7 +1224,7 @@ int InlineTextBox::textPos() const
return logicalLeft() - root()->logicalLeft();
}
-int InlineTextBox::offsetForPosition(int lineOffset, bool includePartialGlyphs) const
+int InlineTextBox::offsetForPosition(float lineOffset, bool includePartialGlyphs) const
{
if (isLineBreak())
return 0;
@@ -1242,7 +1258,7 @@ int InlineTextBox::offsetForPosition(int lineOffset, bool includePartialGlyphs)
return offset;
}
-int InlineTextBox::positionForOffset(int offset) const
+float InlineTextBox::positionForOffset(int offset) const
{
ASSERT(offset >= m_start);
ASSERT(offset <= m_start + m_len);
@@ -1255,6 +1271,7 @@ int InlineTextBox::positionForOffset(int offset) const
int from = !isLeftToRightDirection() ? offset - m_start : 0;
int to = !isLeftToRightDirection() ? m_len : offset - m_start;
// FIXME: Do we need to add rightBearing here?
+<<<<<<< HEAD
#ifdef ANDROID_DISABLE_ROUNDING_HACKS
TextRun textRun = TextRun(text->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride);
if (m_disableRoundingHacks)
@@ -1264,6 +1281,10 @@ int InlineTextBox::positionForOffset(int offset) const
return enclosingIntRect(f.selectionRectForText(TextRun(text->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride),
IntPoint(logicalLeft(), 0), 0, from, to)).maxX();
#endif
+=======
+ return f.selectionRectForText(TextRun(text->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride),
+ IntPoint(logicalLeft(), 0), 0, from, to).maxX();
+>>>>>>> WebKit at r80534
}
bool InlineTextBox::containsCaretOffset(int offset) const
diff --git a/Source/WebCore/rendering/InlineTextBox.h b/Source/WebCore/rendering/InlineTextBox.h
index 095fa16..a900a71 100644
--- a/Source/WebCore/rendering/InlineTextBox.h
+++ b/Source/WebCore/rendering/InlineTextBox.h
@@ -112,12 +112,12 @@ public:
private:
virtual void clearTruncation() { m_truncation = cNoTruncation; }
- virtual int placeEllipsisBox(bool flowIsLTR, int visibleLeftEdge, int visibleRightEdge, int ellipsisWidth, bool& foundBox);
+ virtual float placeEllipsisBox(bool flowIsLTR, float visibleLeftEdge, float visibleRightEdge, float ellipsisWidth, bool& foundBox);
public:
virtual bool isLineBreak() const;
- void setExpansion(int expansion) { m_logicalWidth -= m_expansion; m_expansion = expansion; m_logicalWidth += m_expansion; }
+ void setExpansion(float expansion) { m_logicalWidth -= m_expansion; m_expansion = expansion; m_logicalWidth += m_expansion; }
private:
virtual bool isInlineTextBox() const { return true; }
@@ -129,11 +129,11 @@ public:
private:
virtual unsigned caretMaxRenderedOffset() const;
- int textPos() const; // returns the x position relative to the left start of the text line.
+ float textPos() const; // returns the x position relative to the left start of the text line.
public:
- virtual int offsetForPosition(int x, bool includePartialGlyphs = true) const;
- virtual int positionForOffset(int offset) const;
+ virtual int offsetForPosition(float x, bool includePartialGlyphs = true) const;
+ virtual float positionForOffset(int offset) const;
bool containsCaretOffset(int offset) const; // false for offset after line break
@@ -154,18 +154,18 @@ private:
#endif
protected:
- void paintCompositionBackground(GraphicsContext*, const IntPoint& boxOrigin, RenderStyle*, const Font&, int startPos, int endPos);
- void paintDocumentMarkers(GraphicsContext*, const IntPoint& boxOrigin, RenderStyle*, const Font&, bool background);
- void paintCompositionUnderline(GraphicsContext*, const IntPoint& boxOrigin, const CompositionUnderline&);
+ void paintCompositionBackground(GraphicsContext*, const FloatPoint& boxOrigin, RenderStyle*, const Font&, int startPos, int endPos);
+ void paintDocumentMarkers(GraphicsContext*, const FloatPoint& boxOrigin, RenderStyle*, const Font&, bool background);
+ void paintCompositionUnderline(GraphicsContext*, const FloatPoint& boxOrigin, const CompositionUnderline&);
#if PLATFORM(MAC)
void paintCustomHighlight(int tx, int ty, const AtomicString& type);
#endif
private:
- void paintDecoration(GraphicsContext*, const IntPoint& boxOrigin, int decoration, const ShadowData*);
- void paintSelection(GraphicsContext*, const IntPoint& boxOrigin, RenderStyle*, const Font&);
- void paintSpellingOrGrammarMarker(GraphicsContext*, const IntPoint& boxOrigin, const DocumentMarker&, RenderStyle*, const Font&, bool grammar);
- void paintTextMatchMarker(GraphicsContext*, const IntPoint& boxOrigin, const DocumentMarker&, RenderStyle*, const Font&);
+ void paintDecoration(GraphicsContext*, const FloatPoint& boxOrigin, int decoration, const ShadowData*);
+ void paintSelection(GraphicsContext*, const FloatPoint& boxOrigin, RenderStyle*, const Font&);
+ void paintSpellingOrGrammarMarker(GraphicsContext*, const FloatPoint& boxOrigin, const DocumentMarker&, RenderStyle*, const Font&, bool grammar);
+ void paintTextMatchMarker(GraphicsContext*, const FloatPoint& boxOrigin, const DocumentMarker&, RenderStyle*, const Font&);
void computeRectForReplacementMarker(const DocumentMarker&, RenderStyle*, const Font&);
TextRun::TrailingExpansionBehavior trailingExpansionBehavior() const { return m_expansion && nextLeafChild() ? TextRun::AllowTrailingExpansion : TextRun::ForbidTrailingExpansion; }
diff --git a/Source/WebCore/rendering/MediaControlElements.cpp b/Source/WebCore/rendering/MediaControlElements.cpp
index 6defbb7..32aac90 100644
--- a/Source/WebCore/rendering/MediaControlElements.cpp
+++ b/Source/WebCore/rendering/MediaControlElements.cpp
@@ -487,13 +487,6 @@ inline MediaControlMuteButtonElement::MediaControlMuteButtonElement(HTMLMediaEle
{
}
-PassRefPtr<MediaControlMuteButtonElement> MediaControlMuteButtonElement::create(HTMLMediaElement* mediaElement)
-{
- RefPtr<MediaControlMuteButtonElement> button = adoptRef(new MediaControlMuteButtonElement(mediaElement, MediaMuteButton));
- button->setType("button");
- return button.release();
-}
-
void MediaControlMuteButtonElement::defaultEventHandler(Event* event)
{
if (event->type() == eventNames().clickEvent) {
@@ -503,17 +496,33 @@ void MediaControlMuteButtonElement::defaultEventHandler(Event* event)
HTMLInputElement::defaultEventHandler(event);
}
-const AtomicString& MediaControlMuteButtonElement::shadowPseudoId() const
+void MediaControlMuteButtonElement::updateDisplayType()
{
- DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-mute-button"));
- return id;
+ setDisplayType(mediaElement()->muted() ? MediaUnMuteButton : MediaMuteButton);
}
-void MediaControlMuteButtonElement::updateDisplayType()
+// ----------------------------
+
+inline MediaControlPanelMuteButtonElement::MediaControlPanelMuteButtonElement(HTMLMediaElement* mediaElement)
+ : MediaControlMuteButtonElement(mediaElement, MediaMuteButton)
{
- setDisplayType(mediaElement()->muted() ? MediaUnMuteButton : MediaMuteButton);
}
+PassRefPtr<MediaControlPanelMuteButtonElement> MediaControlPanelMuteButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlPanelMuteButtonElement> button = adoptRef(new MediaControlPanelMuteButtonElement(mediaElement));
+ button->setType("button");
+ return button.release();
+}
+
+const AtomicString& MediaControlPanelMuteButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-mute-button"));
+ return id;
+}
+
+// ----------------------------
+
inline MediaControlVolumeSliderMuteButtonElement::MediaControlVolumeSliderMuteButtonElement(HTMLMediaElement* mediaElement)
: MediaControlMuteButtonElement(mediaElement, MediaVolumeSliderMuteButton)
{
diff --git a/Source/WebCore/rendering/MediaControlElements.h b/Source/WebCore/rendering/MediaControlElements.h
index ff9541d..44e8811 100644
--- a/Source/WebCore/rendering/MediaControlElements.h
+++ b/Source/WebCore/rendering/MediaControlElements.h
@@ -210,8 +210,6 @@ private:
class MediaControlMuteButtonElement : public MediaControlInputElement {
public:
- static PassRefPtr<MediaControlMuteButtonElement> create(HTMLMediaElement*);
-
virtual void defaultEventHandler(Event*);
protected:
@@ -219,6 +217,17 @@ protected:
private:
virtual void updateDisplayType();
+};
+
+// ----------------------------
+
+class MediaControlPanelMuteButtonElement : public MediaControlMuteButtonElement {
+public:
+ static PassRefPtr<MediaControlPanelMuteButtonElement> create(HTMLMediaElement*);
+
+private:
+ MediaControlPanelMuteButtonElement(HTMLMediaElement*);
+
virtual const AtomicString& shadowPseudoId() const;
};
diff --git a/Source/WebCore/rendering/RenderBR.h b/Source/WebCore/rendering/RenderBR.h
index 72a4514..25717b1 100644
--- a/Source/WebCore/rendering/RenderBR.h
+++ b/Source/WebCore/rendering/RenderBR.h
@@ -40,8 +40,8 @@ public:
virtual IntRect selectionRectForRepaint(RenderBoxModelObject* /*repaintContainer*/, bool /*clipToVisibleContent*/) { return IntRect(); }
- virtual unsigned width(unsigned /*from*/, unsigned /*len*/, const Font&, int /*xPos*/, HashSet<const SimpleFontData*>* = 0 /*fallbackFonts*/ , GlyphOverflow* = 0) const { return 0; }
- virtual unsigned width(unsigned /*from*/, unsigned /*len*/, int /*xpos*/, bool = false /*firstLine*/, HashSet<const SimpleFontData*>* = 0 /*fallbackFonts*/, GlyphOverflow* = 0) const { return 0; }
+ virtual float width(unsigned /*from*/, unsigned /*len*/, const Font&, float /*xPos*/, HashSet<const SimpleFontData*>* = 0 /*fallbackFonts*/ , GlyphOverflow* = 0) const { return 0; }
+ virtual float width(unsigned /*from*/, unsigned /*len*/, float /*xpos*/, bool = false /*firstLine*/, HashSet<const SimpleFontData*>* = 0 /*fallbackFonts*/, GlyphOverflow* = 0) const { return 0; }
int lineHeight(bool firstLine) const;
diff --git a/Source/WebCore/rendering/RenderBlock.cpp b/Source/WebCore/rendering/RenderBlock.cpp
index 87aa630..7488ff5 100644
--- a/Source/WebCore/rendering/RenderBlock.cpp
+++ b/Source/WebCore/rendering/RenderBlock.cpp
@@ -126,8 +126,8 @@ RenderBlock::RenderBlock(Node* node)
RenderBlock::~RenderBlock()
{
- delete m_floatingObjects;
- delete m_positionedObjects;
+ if (m_floatingObjects)
+ deleteAllValues(m_floatingObjects->set());
if (hasColumns())
delete gColumnInfoMap->take(this);
@@ -1387,9 +1387,11 @@ void RenderBlock::addOverflowFromFloats()
{
if (!m_floatingObjects)
return;
- FloatingObject* r;
- DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
- for (; (r = it.current()); ++it) {
+
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ FloatingObjectSetIterator end = floatingObjectSet.end();
+ for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
+ FloatingObject* r = *it;
if (r->m_isDescendant)
addOverflowFromChild(r->m_renderer, IntSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r)));
}
@@ -1420,32 +1422,32 @@ bool RenderBlock::expandsToEncloseOverhangingFloats() const
void RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marginInfo)
{
- if (child->style()->hasStaticX()) {
- if (style()->isLeftToRightDirection())
- child->layer()->setStaticX(borderLeft() + paddingLeft());
- else
- child->layer()->setStaticX(borderRight() + paddingRight());
- }
+ bool isHorizontal = style()->isHorizontalWritingMode();
+ bool hasStaticInlinePosition = child->style()->hasStaticInlinePosition(isHorizontal);
+ bool hasStaticBlockPosition = child->style()->hasStaticBlockPosition(isHorizontal);
+ RenderLayer* childLayer = child->layer();
+
+ if (hasStaticInlinePosition)
+ childLayer->setStaticInlinePosition(borderAndPaddingStart());
- if (child->style()->hasStaticY()) {
- int y = height();
+ if (hasStaticBlockPosition) {
+ int logicalTop = logicalHeight();
if (!marginInfo.canCollapseWithMarginBefore()) {
child->computeBlockDirectionMargins(this);
- int marginTop = child->marginTop();
- int collapsedTopPos = marginInfo.positiveMargin();
- int collapsedTopNeg = marginInfo.negativeMargin();
- if (marginTop > 0) {
- if (marginTop > collapsedTopPos)
- collapsedTopPos = marginTop;
+ int marginBefore = marginBeforeForChild(child);
+ int collapsedBeforePos = marginInfo.positiveMargin();
+ int collapsedBeforeNeg = marginInfo.negativeMargin();
+ if (marginBefore > 0) {
+ if (marginBefore > collapsedBeforePos)
+ collapsedBeforePos = marginBefore;
} else {
- if (-marginTop > collapsedTopNeg)
- collapsedTopNeg = -marginTop;
+ if (-marginBefore > collapsedBeforeNeg)
+ collapsedBeforeNeg = -marginBefore;
}
- y += (collapsedTopPos - collapsedTopNeg) - marginTop;
+ logicalTop += (collapsedBeforePos - collapsedBeforeNeg) - marginBefore;
}
- RenderLayer* childLayer = child->layer();
- if (childLayer->staticY() != y) {
- child->layer()->setStaticY(y);
+ if (childLayer->staticBlockPosition() != logicalTop) {
+ childLayer->setStaticBlockPosition(logicalTop);
child->setChildNeedsLayout(true, false);
}
}
@@ -2135,7 +2137,7 @@ void RenderBlock::layoutPositionedObjects(bool relayoutChildren)
// non-positioned block. Rather than trying to detect all of these movement cases, we just always lay out positioned
// objects that are positioned implicitly like this. Such objects are rare, and so in typical DHTML menu usage (where everything is
// positioned explicitly) this should not incur a performance penalty.
- if (relayoutChildren || (r->style()->hasStaticY() && r->parent() != this && r->parent()->isBlockFlow()))
+ if (relayoutChildren || (r->style()->hasStaticBlockPosition(style()->isHorizontalWritingMode()) && r->parent() != this && r->parent()->isBlockFlow()))
r->setChildNeedsLayout(true, false);
// If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.
@@ -2187,14 +2189,14 @@ void RenderBlock::repaintOverhangingFloats(bool paintAllDescendants)
ASSERT(m_floatingObjects);
if (!m_floatingObjects)
return;
-
- FloatingObject* r;
- DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
// FIXME: Avoid disabling LayoutState. At the very least, don't disable it for floats originating
// in this block. Better yet would be to push extra state for the containers of other floats.
view()->disableLayoutState();
- for ( ; (r = it.current()); ++it) {
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ FloatingObjectSetIterator end = floatingObjectSet.end();
+ for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
+ FloatingObject* r = *it;
// Only repaint the object if it is overhanging, is not in its own layer, and
// is our responsibility to paint (m_shouldPaint is set). When paintAllDescendants is true, the latter
// condition is replaced with being a descendant of us.
@@ -2518,9 +2520,10 @@ void RenderBlock::paintFloats(PaintInfo& paintInfo, int tx, int ty, bool preserv
if (!m_floatingObjects)
return;
- FloatingObject* r;
- DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
- for (; (r = it.current()); ++it) {
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ FloatingObjectSetIterator end = floatingObjectSet.end();
+ for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
+ FloatingObject* r = *it;
// Only paint the object if our m_shouldPaint flag is set.
if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
PaintInfo currentPaintInfo(paintInfo);
@@ -2605,6 +2608,19 @@ void RenderBlock::addContinuationWithOutline(RenderInline* flow)
continuations->add(flow);
}
+bool RenderBlock::paintsContinuationOutline(RenderInline* flow)
+{
+ ContinuationOutlineTableMap* table = continuationOutlineTable();
+ if (table->isEmpty())
+ return false;
+
+ ListHashSet<RenderInline*>* continuations = table->get(this);
+ if (!continuations)
+ return false;
+
+ return continuations->contains(flow);
+}
+
void RenderBlock::paintContinuationOutlines(PaintInfo& info, int tx, int ty)
{
ContinuationOutlineTableMap* table = continuationOutlineTable();
@@ -2752,13 +2768,15 @@ GapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const IntPoint& root
IntRect flippedBlockRect = IntRect(offsetFromRootBlock.width(), offsetFromRootBlock.height(), width(), height());
rootBlock->flipForWritingMode(flippedBlockRect);
flippedBlockRect.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
- clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), m_positionedObjects);
+ clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), m_positionedObjects.get());
if (isBody() || isRoot()) // The <body> must make sure to examine its containingBlock's positioned objects.
for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock())
- clipOutPositionedObjects(paintInfo, IntPoint(cb->x(), cb->y()), cb->m_positionedObjects); // FIXME: Not right for flipped writing modes.
+ clipOutPositionedObjects(paintInfo, IntPoint(cb->x(), cb->y()), cb->m_positionedObjects.get()); // FIXME: Not right for flipped writing modes.
if (m_floatingObjects) {
- for (DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects); it.current(); ++it) {
- FloatingObject* r = it.current();
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ FloatingObjectSetIterator end = floatingObjectSet.end();
+ for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
+ FloatingObject* r = *it;
IntRect floatBox = IntRect(offsetFromRootBlock.width() + xPositionForFloatIncludingMargin(r),
offsetFromRootBlock.height() + yPositionForFloatIncludingMargin(r),
r->m_renderer->width(), r->m_renderer->height());
@@ -3016,7 +3034,7 @@ void RenderBlock::insertPositionedObject(RenderBox* o)
{
// Create the list of special objects if we don't aleady have one
if (!m_positionedObjects)
- m_positionedObjects = new PositionedObjectsListHashSet;
+ m_positionedObjects = adoptPtr(new PositionedObjectsListHashSet);
m_positionedObjects->add(o);
}
@@ -3065,18 +3083,14 @@ RenderBlock::FloatingObject* RenderBlock::insertFloatingObject(RenderBox* o)
ASSERT(o->isFloating());
// Create the list of special objects if we don't aleady have one
- if (!m_floatingObjects) {
- m_floatingObjects = new DeprecatedPtrList<FloatingObject>;
- m_floatingObjects->setAutoDelete(true);
- } else {
+ if (!m_floatingObjects)
+ m_floatingObjects = adoptPtr(new FloatingObjects);
+ else {
// Don't insert the object again if it's already in the list
- DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
- FloatingObject* f;
- while ( (f = it.current()) ) {
- if (f->m_renderer == o)
- return f;
- ++it;
- }
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ FloatingObjectSetIterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(o);
+ if (it != floatingObjectSet.end())
+ return *it;
}
// Create the special object entry & append it to the list
@@ -3102,7 +3116,8 @@ RenderBlock::FloatingObject* RenderBlock::insertFloatingObject(RenderBox* o)
newObj->m_isDescendant = true;
newObj->m_renderer = o;
- m_floatingObjects->append(newObj);
+ m_floatingObjects->increaseObjectsCount(newObj->type());
+ m_floatingObjects->set().add(newObj);
return newObj;
}
@@ -3110,22 +3125,28 @@ RenderBlock::FloatingObject* RenderBlock::insertFloatingObject(RenderBox* o)
void RenderBlock::removeFloatingObject(RenderBox* o)
{
if (m_floatingObjects) {
- DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
- while (it.current()) {
- if (it.current()->m_renderer == o) {
- if (childrenInline()) {
- int logicalTop = logicalTopForFloat(it.current());
- int logicalBottom = logicalBottomForFloat(it.current());
-
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ FloatingObjectSet::iterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(o);
+ if (it != floatingObjectSet.end()) {
+ FloatingObject* r = *it;
+ if (childrenInline()) {
+ int logicalTop = logicalTopForFloat(r);
+ int logicalBottom = logicalBottomForFloat(r);
+
+ // Fix for https://bugs.webkit.org/show_bug.cgi?id=54995.
+ if (logicalBottom < 0 || logicalBottom < logicalTop || logicalTop == numeric_limits<int>::max())
+ logicalBottom = numeric_limits<int>::max();
+ else {
// Special-case zero- and less-than-zero-height floats: those don't touch
// the line that they're on, but it still needs to be dirtied. This is
// accomplished by pretending they have a height of 1.
- logicalBottom = max(logicalBottom, logicalTop == numeric_limits<int>::max() ? logicalTop : logicalTop + 1);
- markLinesDirtyInBlockRange(0, logicalBottom);
+ logicalBottom = max(logicalBottom, logicalTop + 1);
}
- m_floatingObjects->removeRef(it.current());
+ markLinesDirtyInBlockRange(0, logicalBottom);
}
- ++it;
+ m_floatingObjects->decreaseObjectsCount(r->type());
+ floatingObjectSet.remove(it);
+ delete r;
}
}
}
@@ -3135,10 +3156,13 @@ void RenderBlock::removeFloatingObjectsBelow(FloatingObject* lastFloat, int logi
if (!m_floatingObjects)
return;
- FloatingObject* curr = m_floatingObjects->last();
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ FloatingObject* curr = floatingObjectSet.last();
while (curr != lastFloat && (!curr->isPlaced() || logicalTopForFloat(curr) >= logicalOffset)) {
- m_floatingObjects->removeLast();
- curr = m_floatingObjects->last();
+ m_floatingObjects->decreaseObjectsCount(curr->type());
+ floatingObjectSet.removeLast();
+ delete curr;
+ curr = floatingObjectSet.last();
}
}
@@ -3146,36 +3170,45 @@ bool RenderBlock::positionNewFloats()
{
if (!m_floatingObjects)
return false;
-
- FloatingObject* floatingObject = m_floatingObjects->last();
+
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ if (floatingObjectSet.isEmpty())
+ return false;
// If all floats have already been positioned, then we have no work to do.
- if (!floatingObject || floatingObject->isPlaced())
+ if (floatingObjectSet.last()->isPlaced())
return false;
// Move backwards through our floating object list until we find a float that has
// already been positioned. Then we'll be able to move forward, positioning all of
// the new floats that need it.
- FloatingObject* lastFloat = m_floatingObjects->getPrev();
- while (lastFloat && !lastFloat->isPlaced()) {
- floatingObject = m_floatingObjects->prev();
- lastFloat = m_floatingObjects->getPrev();
+ FloatingObjectSetIterator it = floatingObjectSet.end();
+ --it; // Go to last item.
+ FloatingObjectSetIterator begin = floatingObjectSet.begin();
+ FloatingObject* lastPlacedFloatingObject = 0;
+ while (it != begin) {
+ --it;
+ if ((*it)->isPlaced()) {
+ lastPlacedFloatingObject = *it;
+ ++it;
+ break;
+ }
}
int logicalTop = logicalHeight();
// The float cannot start above the top position of the last positioned float.
- if (lastFloat)
- logicalTop = max(logicalTopForFloat(lastFloat), logicalTop);
+ if (lastPlacedFloatingObject)
+ logicalTop = max(logicalTopForFloat(lastPlacedFloatingObject), logicalTop);
+ FloatingObjectSetIterator end = floatingObjectSet.end();
// Now walk through the set of unpositioned floats and place them.
- while (floatingObject) {
+ for (; it != end; ++it) {
+ FloatingObject* floatingObject = *it;
// The containing block is responsible for positioning floats, so if we have floats in our
// list that come from somewhere else, do not attempt to position them.
- if (floatingObject->renderer()->containingBlock() != this) {
- floatingObject = m_floatingObjects->next();
+ if (floatingObject->renderer()->containingBlock() != this)
continue;
- }
RenderBox* childBox = floatingObject->renderer();
int childLogicalLeftMargin = style()->isLeftToRightDirection() ? marginStartForChild(childBox) : marginEndForChild(childBox);
@@ -3257,8 +3290,6 @@ bool RenderBlock::positionNewFloats()
// If the child moved, we have to repaint it.
if (childBox->checkForRepaintDuringLayout())
childBox->repaintDuringLayoutIfMoved(oldRect);
-
- floatingObject = m_floatingObjects->next();
}
return true;
}
@@ -3269,16 +3300,23 @@ bool RenderBlock::positionNewFloatOnLine(FloatingObject* newFloat, FloatingObjec
if (!didPosition || !newFloat->m_paginationStrut)
return didPosition;
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ ASSERT(floatingObjectSet.last() == newFloat);
+
int floatLogicalTop = logicalTopForFloat(newFloat);
int paginationStrut = newFloat->m_paginationStrut;
- FloatingObject* f = m_floatingObjects->last();
- ASSERT(f == newFloat);
-
if (floatLogicalTop - paginationStrut != logicalHeight())
return didPosition;
- for (f = m_floatingObjects->prev(); f && f != lastFloatFromPreviousLine; f = m_floatingObjects->prev()) {
+ FloatingObjectSetIterator it = floatingObjectSet.end();
+ --it; // Last float is newFloat, skip that one.
+ FloatingObjectSetIterator begin = floatingObjectSet.begin();
+ while (it != begin) {
+ --it;
+ FloatingObject* f = *it;
+ if (f == lastFloatFromPreviousLine)
+ break;
if (logicalTopForFloat(f) == logicalHeight()) {
ASSERT(!f->m_paginationStrut);
f->m_paginationStrut = paginationStrut;
@@ -3381,12 +3419,14 @@ HashSet<RenderBox*>* RenderBlock::percentHeightDescendants() const
int RenderBlock::logicalLeftOffsetForLine(int logicalTop, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
{
int left = fixedOffset;
- if (m_floatingObjects) {
+ if (m_floatingObjects && m_floatingObjects->hasLeftObjects()) {
if (heightRemaining)
*heightRemaining = 1;
- FloatingObject* r;
- DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
- for ( ; (r = it.current()); ++it) {
+
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ FloatingObjectSetIterator end = floatingObjectSet.end();
+ for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
+ FloatingObject* r = *it;
if (r->isPlaced() && logicalTopForFloat(r) <= logicalTop && logicalBottomForFloat(r) > logicalTop
&& r->type() == FloatingObject::FloatLeft
&& logicalRightForFloat(r) > left) {
@@ -3411,12 +3451,13 @@ int RenderBlock::logicalRightOffsetForLine(int logicalTop, int fixedOffset, bool
{
int right = fixedOffset;
- if (m_floatingObjects) {
+ if (m_floatingObjects && m_floatingObjects->hasRightObjects()) {
if (heightRemaining)
*heightRemaining = 1;
- FloatingObject* r;
- DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
- for ( ; (r = it.current()); ++it) {
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ FloatingObjectSetIterator end = floatingObjectSet.end();
+ for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
+ FloatingObject* r = *it;
if (r->isPlaced() && logicalTopForFloat(r) <= logicalTop && logicalBottomForFloat(r) > logicalTop
&& r->type() == FloatingObject::FloatRight
&& logicalLeftForFloat(r) < right) {
@@ -3437,8 +3478,7 @@ int RenderBlock::logicalRightOffsetForLine(int logicalTop, int fixedOffset, bool
return right;
}
-int
-RenderBlock::availableLogicalWidthForLine(int position, bool firstLine) const
+int RenderBlock::availableLogicalWidthForLine(int position, bool firstLine) const
{
int result = logicalRightOffsetForLine(position, firstLine) - logicalLeftOffsetForLine(position, firstLine);
return (result < 0) ? 0 : result;
@@ -3450,9 +3490,10 @@ int RenderBlock::nextFloatLogicalBottomBelow(int logicalHeight) const
return 0;
int bottom = INT_MAX;
- FloatingObject* r;
- DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
- for ( ; (r = it.current()); ++it) {
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ FloatingObjectSetIterator end = floatingObjectSet.end();
+ for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
+ FloatingObject* r = *it;
int floatBottom = logicalBottomForFloat(r);
if (floatBottom > logicalHeight)
bottom = min(floatBottom, bottom);
@@ -3466,9 +3507,10 @@ int RenderBlock::lowestFloatLogicalBottom(FloatingObject::Type floatType) const
if (!m_floatingObjects)
return 0;
int lowestFloatBottom = 0;
- FloatingObject* r;
- DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
- for ( ; (r = it.current()); ++it) {
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ FloatingObjectSetIterator end = floatingObjectSet.end();
+ for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
+ FloatingObject* r = *it;
if (r->isPlaced() && r->type() & floatType)
lowestFloatBottom = max(lowestFloatBottom, logicalBottomForFloat(r));
}
@@ -3487,7 +3529,7 @@ void RenderBlock::markLinesDirtyInBlockRange(int logicalTop, int logicalBottom,
lowestDirtyLine = lowestDirtyLine->prevRootBox();
}
- while (afterLowest && afterLowest != highest && afterLowest->blockLogicalHeight() >= logicalTop) {
+ while (afterLowest && afterLowest != highest && (afterLowest->blockLogicalHeight() >= logicalTop || afterLowest->blockLogicalHeight() < 0)) {
afterLowest->markDirty();
afterLowest = afterLowest->prevRootBox();
}
@@ -3497,8 +3539,10 @@ void RenderBlock::clearFloats()
{
// Inline blocks are covered by the isReplaced() check in the avoidFloats method.
if (avoidsFloats() || isRoot() || isRenderView() || isFloatingOrPositioned() || isTableCell()) {
- if (m_floatingObjects)
+ if (m_floatingObjects) {
+ deleteAllValues(m_floatingObjects->set());
m_floatingObjects->clear();
+ }
return;
}
@@ -3506,12 +3550,16 @@ void RenderBlock::clearFloats()
RendererToFloatInfoMap floatMap;
if (m_floatingObjects) {
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
if (childrenInline()) {
- m_floatingObjects->first();
- while (FloatingObject* f = m_floatingObjects->take())
+ FloatingObjectSet::iterator end = floatingObjectSet.end();
+ for (FloatingObjectSet::iterator it = floatingObjectSet.begin(); it != end; ++it) {
+ FloatingObject* f = *it;
floatMap.add(f->m_renderer, f);
+ }
} else
- m_floatingObjects->clear();
+ deleteAllValues(floatingObjectSet);
+ m_floatingObjects->clear();
}
// We should not process floats if the parent node is not a RenderBlock. Otherwise, we will add
@@ -3557,7 +3605,10 @@ void RenderBlock::clearFloats()
int changeLogicalTop = numeric_limits<int>::max();
int changeLogicalBottom = numeric_limits<int>::min();
if (m_floatingObjects) {
- for (FloatingObject* f = m_floatingObjects->first(); f; f = m_floatingObjects->next()) {
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ FloatingObjectSetIterator end = floatingObjectSet.end();
+ for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
+ FloatingObject* f = *it;
FloatingObject* oldFloatingObject = floatMap.get(f->m_renderer);
int logicalBottom = logicalBottomForFloat(f);
if (oldFloatingObject) {
@@ -3603,8 +3654,9 @@ int RenderBlock::addOverhangingFloats(RenderBlock* child, int logicalLeftOffset,
// Floats that will remain the child's responsibility to paint should factor into its
// overflow.
- DeprecatedPtrListIterator<FloatingObject> it(*child->m_floatingObjects);
- for (FloatingObject* r; (r = it.current()); ++it) {
+ FloatingObjectSetIterator childEnd = child->m_floatingObjects->set().end();
+ for (FloatingObjectSetIterator childIt = child->m_floatingObjects->set().begin(); childIt != childEnd; ++childIt) {
+ FloatingObject* r = *childIt;
int logicalBottom = child->logicalTop() + logicalBottomForFloat(r);
lowestFloatLogicalBottom = max(lowestFloatLogicalBottom, logicalBottom);
@@ -3628,11 +3680,11 @@ int RenderBlock::addOverhangingFloats(RenderBlock* child, int logicalLeftOffset,
floatingObj->m_isDescendant = true;
// We create the floating object list lazily.
- if (!m_floatingObjects) {
- m_floatingObjects = new DeprecatedPtrList<FloatingObject>;
- m_floatingObjects->setAutoDelete(true);
- }
- m_floatingObjects->append(floatingObj);
+ if (!m_floatingObjects)
+ m_floatingObjects = adoptPtr(new FloatingObjects);
+
+ m_floatingObjects->increaseObjectsCount(floatingObj->type());
+ m_floatingObjects->set().add(floatingObj);
}
} else {
if (makeChildPaintOtherFloats && !r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer() &&
@@ -3661,22 +3713,13 @@ void RenderBlock::addIntrudingFloats(RenderBlock* prev, int logicalLeftOffset, i
return;
logicalLeftOffset += (style()->isHorizontalWritingMode() ? marginLeft() : marginTop());
-
- DeprecatedPtrListIterator<FloatingObject> it(*prev->m_floatingObjects);
- for (FloatingObject *r; (r = it.current()); ++it) {
+
+ FloatingObjectSet& prevSet = prev->m_floatingObjects->set();
+ FloatingObjectSetIterator prevEnd = prevSet.end();
+ for (FloatingObjectSetIterator prevIt = prevSet.begin(); prevIt != prevEnd; ++prevIt) {
+ FloatingObject* r = *prevIt;
if (logicalBottomForFloat(r) > logicalTopOffset) {
- // The object may already be in our list. Check for it up front to avoid
- // creating duplicate entries.
- FloatingObject* f = 0;
- if (m_floatingObjects) {
- DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
- while ((f = it.current())) {
- if (f->m_renderer == r->m_renderer)
- break;
- ++it;
- }
- }
- if (!f) {
+ if (!m_floatingObjects || !m_floatingObjects->set().contains(r)) {
int leftOffset = style()->isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset;
int topOffset = style()->isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset;
@@ -3698,11 +3741,10 @@ void RenderBlock::addIntrudingFloats(RenderBlock* prev, int logicalLeftOffset, i
floatingObj->m_renderer = r->m_renderer;
// We create the floating object list lazily.
- if (!m_floatingObjects) {
- m_floatingObjects = new DeprecatedPtrList<FloatingObject>;
- m_floatingObjects->setAutoDelete(true);
- }
- m_floatingObjects->append(floatingObj);
+ if (!m_floatingObjects)
+ m_floatingObjects = adoptPtr(new FloatingObjects);
+ m_floatingObjects->increaseObjectsCount(floatingObj->type());
+ m_floatingObjects->set().add(floatingObj);
}
}
}
@@ -3714,17 +3756,9 @@ bool RenderBlock::avoidsFloats() const
return RenderBox::avoidsFloats() || !style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth();
}
-bool RenderBlock::containsFloat(RenderObject* o)
+bool RenderBlock::containsFloat(RenderBox* renderer)
{
- if (m_floatingObjects) {
- DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
- while (it.current()) {
- if (it.current()->m_renderer == o)
- return true;
- ++it;
- }
- }
- return false;
+ return m_floatingObjects && m_floatingObjects->set().contains<RenderBox*, FloatingObjectHashTranslator>(renderer);
}
void RenderBlock::markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove, bool inLayout)
@@ -3882,9 +3916,11 @@ bool RenderBlock::hitTestFloats(const HitTestRequest& request, HitTestResult& re
ty += toRenderView(this)->frameView()->scrollY();
}
- FloatingObject* floatingObject;
- DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
- for (it.toLast(); (floatingObject = it.current()); --it) {
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ FloatingObjectSetIterator begin = floatingObjectSet.begin();
+ for (FloatingObjectSetIterator it = floatingObjectSet.end(); it != begin;) {
+ --it;
+ FloatingObject* floatingObject = *it;
if (floatingObject->m_shouldPaint && !floatingObject->m_renderer->hasSelfPaintingLayer()) {
int xOffset = xPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->x();
int yOffset = yPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->y();
@@ -4631,7 +4667,7 @@ static int getBorderPaddingMargin(const RenderBoxModelObject* child, bool endOfI
child->borderStart();
}
-static inline void stripTrailingSpace(int& inlineMax, int& inlineMin,
+static inline void stripTrailingSpace(float& inlineMax, float& inlineMin,
RenderObject* trailingSpaceChild)
{
if (trailingSpaceChild && trailingSpaceChild->isText()) {
@@ -4639,17 +4675,23 @@ static inline void stripTrailingSpace(int& inlineMax, int& inlineMin,
RenderText* t = toRenderText(trailingSpaceChild);
const UChar space = ' ';
const Font& font = t->style()->font(); // FIXME: This ignores first-line.
- int spaceWidth = font.width(TextRun(&space, 1));
+ float spaceWidth = font.width(TextRun(&space, 1));
inlineMax -= spaceWidth + font.wordSpacing();
if (inlineMin > inlineMax)
inlineMin = inlineMax;
}
}
+static inline void updatePreferredWidth(int& preferredWidth, float& result)
+{
+ int snappedResult = ceilf(result);
+ preferredWidth = max(snappedResult, preferredWidth);
+}
+
void RenderBlock::computeInlinePreferredLogicalWidths()
{
- int inlineMax = 0;
- int inlineMin = 0;
+ float inlineMax = 0;
+ float inlineMin = 0;
int cw = containingBlock()->contentLogicalWidth();
@@ -4710,15 +4752,15 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
// the width of the last non-breakable run and use that to start a new line
// (unless we end in whitespace).
RenderStyle* cstyle = child->style();
- int childMin = 0;
- int childMax = 0;
+ float childMin = 0;
+ float childMax = 0;
if (!child->isText()) {
// Case (1) and (2). Inline replaced and inline flow elements.
if (child->isRenderInline()) {
// Add in padding/border/margin from the appropriate side of
// the element.
- int bpm = getBorderPaddingMargin(toRenderInline(child), childIterator.endOfInline);
+ float bpm = getBorderPaddingMargin(toRenderInline(child), childIterator.endOfInline);
childMin += bpm;
childMax += bpm;
@@ -4728,7 +4770,7 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
child->setPreferredLogicalWidthsDirty(false);
} else {
// Inline replaced elts add in their margins to their min/max values.
- int margins = 0;
+ float margins = 0;
Length startMargin = cstyle->marginStart();
Length endMargin = cstyle->marginEnd();
if (startMargin.isFixed())
@@ -4758,13 +4800,13 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak;
if ((canBreakReplacedElement && (autoWrap || oldAutoWrap)) || clearPreviousFloat) {
- m_minPreferredLogicalWidth = max(inlineMin, m_minPreferredLogicalWidth);
+ updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
inlineMin = 0;
}
// If we're supposed to clear the previous float, then terminate maxwidth as well.
if (clearPreviousFloat) {
- m_maxPreferredLogicalWidth = max(inlineMax, m_maxPreferredLogicalWidth);
+ updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
inlineMax = 0;
}
@@ -4782,12 +4824,12 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
if (!autoWrap || !canBreakReplacedElement) {
if (child->isFloating())
- m_minPreferredLogicalWidth = max(childMin, m_minPreferredLogicalWidth);
+ updatePreferredWidth(m_minPreferredLogicalWidth, childMin);
else
inlineMin += childMin;
} else {
// Now check our line.
- m_minPreferredLogicalWidth = max(childMin, m_minPreferredLogicalWidth);
+ updatePreferredWidth(m_minPreferredLogicalWidth, childMin);
// Now start a new line.
inlineMin = 0;
@@ -4804,7 +4846,7 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
RenderText* t = toRenderText(child);
if (t->isWordBreak()) {
- m_minPreferredLogicalWidth = max(inlineMin, m_minPreferredLogicalWidth);
+ updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
inlineMin = 0;
continue;
}
@@ -4818,9 +4860,9 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
// then they shouldn't be considered in the breakable char
// check.
bool hasBreakableChar, hasBreak;
- int beginMin, endMin;
+ float beginMin, endMin;
bool beginWS, endWS;
- int beginMax, endMax;
+ float beginMax, endMax;
t->trimmedPrefWidths(inlineMax, beginMin, beginWS, endMin, endWS,
hasBreakableChar, hasBreak, beginMax, endMax,
childMin, childMax, stripFrontSpaces);
@@ -4828,7 +4870,7 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
// This text object will not be rendered, but it may still provide a breaking opportunity.
if (!hasBreak && childMax == 0) {
if (autoWrap && (beginWS || endWS)) {
- m_minPreferredLogicalWidth = max(inlineMin, m_minPreferredLogicalWidth);
+ updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
inlineMin = 0;
}
continue;
@@ -4858,10 +4900,10 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
// we start and end with whitespace.
if (beginWS)
// Go ahead and end the current line.
- m_minPreferredLogicalWidth = max(inlineMin, m_minPreferredLogicalWidth);
+ updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
else {
inlineMin += beginMin;
- m_minPreferredLogicalWidth = max(inlineMin, m_minPreferredLogicalWidth);
+ updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
childMin -= ti;
}
@@ -4870,18 +4912,18 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
if (endWS) {
// We end in whitespace, which means we can go ahead
// and end our current line.
- m_minPreferredLogicalWidth = max(inlineMin, m_minPreferredLogicalWidth);
+ updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
inlineMin = 0;
} else {
- m_minPreferredLogicalWidth = max(inlineMin, m_minPreferredLogicalWidth);
+ updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
inlineMin = endMin;
}
}
if (hasBreak) {
inlineMax += beginMax;
- m_maxPreferredLogicalWidth = max(inlineMax, m_maxPreferredLogicalWidth);
- m_maxPreferredLogicalWidth = max(childMax, m_maxPreferredLogicalWidth);
+ updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
+ updatePreferredWidth(m_maxPreferredLogicalWidth, childMax);
inlineMax = endMax;
} else
inlineMax += childMax;
@@ -4891,8 +4933,8 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
if (child->isListMarker())
stripFrontSpaces = true;
} else {
- m_minPreferredLogicalWidth = max(inlineMin, m_minPreferredLogicalWidth);
- m_maxPreferredLogicalWidth = max(inlineMax, m_maxPreferredLogicalWidth);
+ updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
+ updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
inlineMin = inlineMax = 0;
stripFrontSpaces = true;
trailingSpaceChild = 0;
@@ -4904,8 +4946,8 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
if (style()->collapseWhiteSpace())
stripTrailingSpace(inlineMax, inlineMin, trailingSpaceChild);
- m_minPreferredLogicalWidth = max(inlineMin, m_minPreferredLogicalWidth);
- m_maxPreferredLogicalWidth = max(inlineMax, m_maxPreferredLogicalWidth);
+ updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
+ updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
}
// Use a very large value (in effect infinite).
@@ -5284,13 +5326,25 @@ void RenderBlock::updateFirstLetter()
firstLetter->removeChild(child);
newFirstLetter->addChild(child, 0);
}
- RenderTextFragment* remainingText = toRenderTextFragment(firstLetter->nextSibling());
- ASSERT(remainingText->node()->renderer() == remainingText);
- // Replace the old renderer with the new one.
- remainingText->setFirstLetter(newFirstLetter);
+
+ RenderTextFragment* remainingText = 0;
+ RenderObject* nextSibling = firstLetter->nextSibling();
+ RenderObject* next = nextSibling;
+ while (next) {
+ if (next->isText() && toRenderText(next)->isTextFragment()) {
+ remainingText = toRenderTextFragment(next);
+ break;
+ }
+ next = next->nextSibling();
+ }
+ if (remainingText) {
+ ASSERT(remainingText->node()->renderer() == remainingText);
+ // Replace the old renderer with the new one.
+ remainingText->setFirstLetter(newFirstLetter);
+ }
firstLetter->destroy();
firstLetter = newFirstLetter;
- firstLetterContainer->addChild(firstLetter, remainingText);
+ firstLetterContainer->addChild(firstLetter, nextSibling);
view()->enableLayoutState();
} else
firstLetter->setStyle(pseudoStyle);
@@ -5471,9 +5525,9 @@ void RenderBlock::adjustForBorderFit(int x, int& left, int& right) const
if (childrenInline()) {
for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) {
if (box->firstChild())
- left = min(left, x + box->firstChild()->x());
+ left = min(left, x + static_cast<int>(box->firstChild()->x()));
if (box->lastChild())
- right = max(right, x + box->lastChild()->x() + box->lastChild()->logicalWidth());
+ right = max(right, x + static_cast<int>(ceilf(box->lastChild()->logicalRight())));
}
}
else {
@@ -5491,9 +5545,10 @@ void RenderBlock::adjustForBorderFit(int x, int& left, int& right) const
}
if (m_floatingObjects) {
- FloatingObject* r;
- DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
- for (; (r = it.current()); ++it) {
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ FloatingObjectSetIterator end = floatingObjectSet.end();
+ for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
+ FloatingObject* r = *it;
// Only examine the object if our m_shouldPaint flag is set.
if (r->m_shouldPaint) {
int floatLeft = xPositionForFloatIncludingMargin(r) - r->m_renderer->x();
@@ -5773,8 +5828,8 @@ void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
if (!hasOverflowClip() && !hasControlClip()) {
for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
- int top = max(curr->lineTop(), curr->y());
- int bottom = min(curr->lineBottom(), curr->y() + curr->logicalHeight());
+ int top = max(curr->lineTop(), curr->logicalTop());
+ int bottom = min(curr->lineBottom(), curr->logicalTop() + curr->logicalHeight());
IntRect rect(tx + curr->x(), ty + top, curr->logicalWidth(), bottom - top);
if (!rect.isEmpty())
rects.append(rect);
@@ -6200,4 +6255,27 @@ const char* RenderBlock::renderName() const
return "RenderBlock";
}
+inline void RenderBlock::FloatingObjects::clear()
+{
+ m_set.clear();
+ m_leftObjectsCount = 0;
+ m_rightObjectsCount = 0;
+}
+
+inline void RenderBlock::FloatingObjects::increaseObjectsCount(FloatingObject::Type type)
+{
+ if (type == FloatingObject::FloatLeft)
+ m_leftObjectsCount++;
+ else
+ m_rightObjectsCount++;
+}
+
+inline void RenderBlock::FloatingObjects::decreaseObjectsCount(FloatingObject::Type type)
+{
+ if (type == FloatingObject::FloatLeft)
+ m_leftObjectsCount--;
+ else
+ m_rightObjectsCount--;
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderBlock.h b/Source/WebCore/rendering/RenderBlock.h
index 2c61331..8d054a6 100644
--- a/Source/WebCore/rendering/RenderBlock.h
+++ b/Source/WebCore/rendering/RenderBlock.h
@@ -23,11 +23,11 @@
#ifndef RenderBlock_h
#define RenderBlock_h
-#include "DeprecatedPtrList.h"
#include "GapRects.h"
#include "RenderBox.h"
#include "RenderLineBoxList.h"
#include "RootInlineBox.h"
+#include <wtf/OwnPtr.h>
#include <wtf/ListHashSet.h>
namespace WebCore {
@@ -35,6 +35,7 @@ namespace WebCore {
class ColumnInfo;
class InlineIterator;
class LayoutStateMaintainer;
+class LazyLineBreakIterator;
class RenderInline;
struct BidiRun;
@@ -80,7 +81,7 @@ public:
void removePositionedObjects(RenderBlock*);
typedef ListHashSet<RenderBox*, 4> PositionedObjectsListHashSet;
- PositionedObjectsListHashSet* positionedObjects() const { return m_positionedObjects; }
+ PositionedObjectsListHashSet* positionedObjects() const { return m_positionedObjects.get(); }
void addPercentHeightDescendant(RenderBox*);
static void removePercentHeightDescendant(RenderBox*);
@@ -94,13 +95,14 @@ public:
void markPositionedObjectsForLayout();
virtual void markForPaginationRelayoutIfNeeded();
- bool containsFloats() { return m_floatingObjects && !m_floatingObjects->isEmpty(); }
- bool containsFloat(RenderObject*);
+ bool containsFloats() { return m_floatingObjects && !m_floatingObjects->set().isEmpty(); }
+ bool containsFloat(RenderBox*);
int availableLogicalWidthForLine(int position, bool firstLine) const;
int logicalRightOffsetForLine(int position, bool firstLine) const { return logicalRightOffsetForLine(position, logicalRightOffsetForContent(), firstLine); }
int logicalLeftOffsetForLine(int position, bool firstLine) const { return logicalLeftOffsetForLine(position, logicalLeftOffsetForContent(), firstLine); }
-
+ int startOffsetForLine(int position, bool firstLine) const { return style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, firstLine) : logicalRightOffsetForLine(position, firstLine); }
+
virtual VisiblePosition positionForPoint(const IntPoint&);
// Block flows subclass availableWidth to handle multi column layout (shrinking the width available to children when laying out.)
@@ -132,6 +134,7 @@ public:
virtual void adjustForColumns(IntSize&, const IntPoint&) const;
void addContinuationWithOutline(RenderInline*);
+ bool paintsContinuationOutline(RenderInline*);
virtual RenderBoxModelObject* virtualContinuation() const { return continuation(); }
bool isAnonymousBlockContinuation() const { return continuation() && isAnonymousBlock(); }
@@ -270,6 +273,9 @@ protected:
int logicalRightOffsetForLine(int position, int fixedOffset, bool applyTextIndent = true, int* logicalHeightRemaining = 0) const;
int logicalLeftOffsetForLine(int position, int fixedOffset, bool applyTextIndent = true, int* logicalHeightRemaining = 0) const;
+ virtual ETextAlign textAlignmentForLine(bool endsWithSoftBreak) const;
+ virtual void adjustInlineDirectionLineBounds(int /* expansionOpportunityCount */, float& /* logicalLeft */, float& /* logicalWidth */) const { }
+
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
virtual void computePreferredLogicalWidths();
@@ -300,9 +306,9 @@ protected:
void addOverflowFromBlockChildren();
void addOverflowFromInlineChildren();
-#if ENABLE(SVG)
-protected:
+ virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
+#if ENABLE(SVG)
// Only used by RenderSVGText, which explicitely overrides RenderBlock::layoutBlock(), do NOT use for anything else.
void forceLayoutInlineChildren()
{
@@ -485,10 +491,12 @@ private:
void skipTrailingWhitespace(InlineIterator&, bool isLineEmpty, bool previousLineBrokeCleanly);
int skipLeadingWhitespace(InlineBidiResolver&, bool firstLine, bool isLineEmpty, bool previousLineBrokeCleanly, FloatingObject* lastFloatFromPreviousLine);
- void fitBelowFloats(int widthToFit, bool firstLine, int& availableWidth);
- InlineIterator findNextLineBreak(InlineBidiResolver&, bool firstLine, bool& isLineEmpty, bool& previousLineBrokeCleanly, bool& hyphenated, EClear*, FloatingObject* lastFloatFromPreviousLine);
+ void fitBelowFloats(float widthToFit, bool firstLine, float& availableWidth);
+ typedef std::pair<RenderText*, LazyLineBreakIterator> LineBreakIteratorInfo;
+ InlineIterator findNextLineBreak(InlineBidiResolver&, bool firstLine, bool& isLineEmpty, LineBreakIteratorInfo&, bool& previousLineBrokeCleanly, bool& hyphenated, EClear*, FloatingObject* lastFloatFromPreviousLine);
RootInlineBox* constructLine(unsigned runCount, BidiRun* firstRun, BidiRun* lastRun, bool firstLine, bool lastLine, RenderObject* endObject);
InlineFlowBox* createLineBoxes(RenderObject*, bool firstLine);
+
void computeInlineDirectionPositionsForLine(RootInlineBox*, bool firstLine, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&);
void computeBlockDirectionPositionsForLine(RootInlineBox*, BidiRun*, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
void deleteEllipsisLineBoxes();
@@ -580,8 +588,6 @@ private:
virtual IntRect localCaretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0);
- virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
-
void adjustPointToColumnContents(IntPoint&) const;
void adjustForBorderFit(int x, int& left, int& right) const; // Helper function for borderFitAdjust
@@ -695,10 +701,41 @@ private:
int adjustForUnsplittableChild(RenderBox* child, int logicalOffset, bool includeMargins = false); // If the child is unsplittable and can't fit on the current page, return the top of the next page/column.
void adjustLinePositionForPagination(RootInlineBox*, int& deltaOffset); // Computes a deltaOffset value that put a line at the top of the next page if it doesn't fit on the current page.
- typedef PositionedObjectsListHashSet::const_iterator Iterator;
- DeprecatedPtrList<FloatingObject>* m_floatingObjects;
+ struct FloatingObjectHashFunctions {
+ static unsigned hash(FloatingObject* key) { return DefaultHash<RenderBox*>::Hash::hash(key->m_renderer); }
+ static bool equal(FloatingObject* a, FloatingObject* b) { return a->m_renderer == b->m_renderer; }
+ static const bool safeToCompareToEmptyOrDeleted = true;
+ };
+ struct FloatingObjectHashTranslator {
+ static unsigned hash(RenderBox* key) { return DefaultHash<RenderBox*>::Hash::hash(key); }
+ static bool equal(FloatingObject* a, RenderBox* b) { return a->m_renderer == b; }
+ };
+ typedef ListHashSet<FloatingObject*, 4, FloatingObjectHashFunctions> FloatingObjectSet;
+ typedef FloatingObjectSet::const_iterator FloatingObjectSetIterator;
+ class FloatingObjects {
+ public:
+ FloatingObjects()
+ : m_leftObjectsCount(0)
+ , m_rightObjectsCount(0)
+ {
+ }
+
+ void clear();
+ void increaseObjectsCount(FloatingObject::Type);
+ void decreaseObjectsCount(FloatingObject::Type);
+ bool hasLeftObjects() const { return m_leftObjectsCount > 0; }
+ bool hasRightObjects() const { return m_rightObjectsCount > 0; }
+ FloatingObjectSet& set() { return m_set; }
+
+ private:
+ FloatingObjectSet m_set;
+ unsigned m_leftObjectsCount;
+ unsigned m_rightObjectsCount;
+ };
+ OwnPtr<FloatingObjects> m_floatingObjects;
- PositionedObjectsListHashSet* m_positionedObjects;
+ typedef PositionedObjectsListHashSet::const_iterator Iterator;
+ OwnPtr<PositionedObjectsListHashSet> m_positionedObjects;
// Allocated only when some of these fields have non-default values
struct RenderBlockRareData {
diff --git a/Source/WebCore/rendering/RenderBlockLineLayout.cpp b/Source/WebCore/rendering/RenderBlockLineLayout.cpp
index 5e2b52d..d1fce88 100644
--- a/Source/WebCore/rendering/RenderBlockLineLayout.cpp
+++ b/Source/WebCore/rendering/RenderBlockLineLayout.cpp
@@ -34,6 +34,7 @@
#include "RenderListMarker.h"
#include "RenderView.h"
#include "Settings.h"
+#include "TextBreakIterator.h"
#include "TextRun.h"
#include "TrailingFloatsRootInlineBox.h"
#include "VerticalPositionCache.h"
@@ -122,7 +123,7 @@ static void addMidpoint(LineMidpointState& lineMidpointState, const InlineIterat
void RenderBlock::appendRunsForObject(int start, int end, RenderObject* obj, InlineBidiResolver& resolver)
{
if (start > end || obj->isFloating() ||
- (obj->isPositioned() && !obj->style()->hasStaticX() && !obj->style()->hasStaticY() && !obj->container()->isRenderInline()))
+ (obj->isPositioned() && !obj->style()->hasAutoLeftAndRight() && !obj->style()->hasAutoTopAndBottom() && !obj->container()->isRenderInline()))
return;
LineMidpointState& lineMidpointState = resolver.midpointState();
@@ -185,7 +186,7 @@ static inline InlineBox* createInlineBoxForRenderer(RenderObject* obj, bool isRo
static inline void dirtyLineBoxesForRenderer(RenderObject* o, bool fullLayout)
{
if (o->isText()) {
- if (o->preferredLogicalWidthsDirty() && o->isCounter())
+ if (o->preferredLogicalWidthsDirty() && (o->isCounter() || o->isQuote()))
toRenderText(o)->computePreferredLogicalWidths(0); // FIXME: Counters depend on this hack. No clue why. Should be investigated and removed.
toRenderText(o)->dirtyLineBoxes(fullLayout);
} else
@@ -289,7 +290,7 @@ RootInlineBox* RenderBlock::constructLine(unsigned runCount, BidiRun* firstRun,
parentBox->addToLine(box);
bool visuallyOrdered = r->m_object->style()->visuallyOrdered();
- box->setBidiLevel(visuallyOrdered ? 0 : r->level());
+ box->setBidiLevel(r->level());
if (box->isInlineTextBox()) {
InlineTextBox* text = static_cast<InlineTextBox*>(box);
@@ -323,16 +324,26 @@ RootInlineBox* RenderBlock::constructLine(unsigned runCount, BidiRun* firstRun,
return lastRootBox();
}
+ETextAlign RenderBlock::textAlignmentForLine(bool endsWithSoftBreak) const
+{
+ ETextAlign alignment = style()->textAlign();
+ if (!endsWithSoftBreak && alignment == JUSTIFY)
+ alignment = TAAUTO;
+
+ return alignment;
+}
+
void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox, bool firstLine, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap& textBoxDataMap)
{
- // First determine our total logical width.
- int availableLogicalWidth = availableLogicalWidthForLine(logicalHeight(), firstLine);
- int totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth();
+ ETextAlign textAlign = textAlignmentForLine(!reachedEnd && !lineBox->endsWithBreak());
+ float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), firstLine);
+ float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), firstLine) - logicalLeft;
+
bool needsWordSpacing = false;
+ float totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth();
unsigned expansionOpportunityCount = 0;
bool isAfterExpansion = true;
Vector<unsigned, 16> expansionOpportunities;
- ETextAlign textAlign = style()->textAlign();
for (BidiRun* r = firstRun; r; r = r->next()) {
if (!r->m_box || r->m_object->isPositioned() || r->m_box->isLineBreak())
@@ -394,7 +405,6 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
// we now examine our text-align property in order to determine where to position the
// objects horizontally. The total width of the line can be increased if we end up
// justifying text.
- int logicalLeft = logicalLeftOffsetForLine(logicalHeight(), firstLine);
switch (textAlign) {
case LEFT:
case WEBKIT_LEFT:
@@ -402,7 +412,7 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
// particular with RTL blocks, wide lines should still spill out to the left.
if (style()->isLeftToRightDirection()) {
if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun)
- trailingSpaceRun->m_box->setLogicalWidth(max(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
+ trailingSpaceRun->m_box->setLogicalWidth(max<float>(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
} else {
if (trailingSpaceRun)
trailingSpaceRun->m_box->setLogicalWidth(0);
@@ -411,7 +421,8 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
}
break;
case JUSTIFY:
- if (expansionOpportunityCount && !reachedEnd && !lineBox->endsWithBreak()) {
+ adjustInlineDirectionLineBounds(expansionOpportunityCount, logicalLeft, availableLogicalWidth);
+ if (expansionOpportunityCount) {
if (trailingSpaceRun) {
totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
trailingSpaceRun->m_box->setLogicalWidth(0);
@@ -420,11 +431,10 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
}
// fall through
case TAAUTO:
- expansionOpportunityCount = 0;
// for right to left fall through to right aligned
if (style()->isLeftToRightDirection()) {
if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun)
- trailingSpaceRun->m_box->setLogicalWidth(max(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
+ trailingSpaceRun->m_box->setLogicalWidth(max<float>(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
break;
}
case RIGHT:
@@ -441,7 +451,7 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
logicalLeft += availableLogicalWidth - totalLogicalWidth;
} else {
if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun) {
- trailingSpaceRun->m_box->setLogicalWidth(max(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
+ trailingSpaceRun->m_box->setLogicalWidth(max<float>(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
} else
logicalLeft += availableLogicalWidth - totalLogicalWidth;
@@ -449,14 +459,14 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
break;
case CENTER:
case WEBKIT_CENTER:
- int trailingSpaceWidth = 0;
+ float trailingSpaceWidth = 0;
if (trailingSpaceRun) {
totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
trailingSpaceWidth = min(trailingSpaceRun->m_box->logicalWidth(), (availableLogicalWidth - totalLogicalWidth + 1) / 2);
- trailingSpaceRun->m_box->setLogicalWidth(max(0, trailingSpaceWidth));
+ trailingSpaceRun->m_box->setLogicalWidth(max<float>(0, trailingSpaceWidth));
}
if (style()->isLeftToRightDirection())
- logicalLeft += max((availableLogicalWidth - totalLogicalWidth) / 2, 0);
+ logicalLeft += max<float>((availableLogicalWidth - totalLogicalWidth) / 2, 0);
else
logicalLeft += totalLogicalWidth > availableLogicalWidth ? (availableLogicalWidth - totalLogicalWidth) : (availableLogicalWidth - totalLogicalWidth) / 2 - trailingSpaceWidth;
break;
@@ -476,7 +486,7 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
// Only justify text if whitespace is collapsed.
if (r->m_object->style()->collapseWhiteSpace()) {
InlineTextBox* textBox = static_cast<InlineTextBox*>(r->m_box);
- int expansion = (availableLogicalWidth - totalLogicalWidth) * opportunitiesInRun / expansionOpportunityCount;
+ float expansion = (availableLogicalWidth - totalLogicalWidth) * opportunitiesInRun / expansionOpportunityCount;
textBox->setExpansion(expansion);
totalLogicalWidth += expansion;
}
@@ -728,7 +738,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
}
}
- FloatingObject* lastFloat = m_floatingObjects ? m_floatingObjects->last() : 0;
+ FloatingObject* lastFloat = (m_floatingObjects && !m_floatingObjects->set().isEmpty()) ? m_floatingObjects->set().last() : 0;
LineMidpointState& lineMidpointState = resolver.midpointState();
@@ -782,6 +792,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
bool isLineEmpty = true;
bool paginated = view()->layoutState() && view()->layoutState()->isPaginated();
+ LineBreakIteratorInfo lineBreakIteratorInfo;
VerticalPositionCache verticalPositionCache;
while (!end.atEnd()) {
@@ -797,8 +808,8 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
bool hyphenated;
InlineIterator oldEnd = end;
- FloatingObject* lastFloatFromPreviousLine = m_floatingObjects ? m_floatingObjects->last() : 0;
- end = findNextLineBreak(resolver, firstLine, isLineEmpty, previousLineBrokeCleanly, hyphenated, &clear, lastFloatFromPreviousLine);
+ FloatingObject* lastFloatFromPreviousLine = (m_floatingObjects && !m_floatingObjects->set().isEmpty()) ? m_floatingObjects->set().last() : 0;
+ end = findNextLineBreak(resolver, firstLine, isLineEmpty, lineBreakIteratorInfo, previousLineBrokeCleanly, hyphenated, &clear, lastFloatFromPreviousLine);
if (resolver.position().atEnd()) {
resolver.deleteRuns();
checkForFloatsFromLastLine = true;
@@ -807,7 +818,8 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
ASSERT(end != resolver.position());
if (!isLineEmpty) {
- resolver.createBidiRunsForLine(end, style()->visuallyOrdered(), previousLineBrokeCleanly);
+ VisualDirectionOverride override = (style()->visuallyOrdered() ? (style()->direction() == LTR ? VisualLeftToRightOverride : VisualRightToLeftOverride) : NoVisualOverride);
+ resolver.createBidiRunsForLine(end, override, previousLineBrokeCleanly);
ASSERT(resolver.position() == end);
BidiRun* trailingSpaceRun = 0;
@@ -947,13 +959,17 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
}
if (m_floatingObjects && lastRootBox()) {
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ FloatingObjectSetIterator it = floatingObjectSet.begin();
+ FloatingObjectSetIterator end = floatingObjectSet.end();
if (lastFloat) {
- for (FloatingObject* f = m_floatingObjects->last(); f != lastFloat; f = m_floatingObjects->prev()) {
- }
- m_floatingObjects->next();
- } else
- m_floatingObjects->first();
- for (FloatingObject* f = m_floatingObjects->current(); f; f = m_floatingObjects->next()) {
+ FloatingObjectSetIterator lastFloatIterator = floatingObjectSet.find(lastFloat);
+ ASSERT(lastFloatIterator != end);
+ ++lastFloatIterator;
+ it = lastFloatIterator;
+ }
+ for (; it != end; ++it) {
+ FloatingObject* f = *it;
lastRootBox()->floats().append(f->m_renderer);
ASSERT(f->m_renderer == floats[floatIndex].object);
// If a float's geometry has changed, give up on syncing with clean lines.
@@ -961,7 +977,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
checkForEndLineMatch = false;
floatIndex++;
}
- lastFloat = m_floatingObjects->last();
+ lastFloat = !floatingObjectSet.isEmpty() ? floatingObjectSet.last() : 0;
}
lineMidpointState.reset();
@@ -1024,15 +1040,19 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
trailingFloatsLineBox->setOverflowFromLogicalRects(logicalLayoutOverflow, logicalVisualOverflow);
trailingFloatsLineBox->setBlockLogicalHeight(logicalHeight());
}
+
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ FloatingObjectSetIterator it = floatingObjectSet.begin();
+ FloatingObjectSetIterator end = floatingObjectSet.end();
if (lastFloat) {
- for (FloatingObject* f = m_floatingObjects->last(); f != lastFloat; f = m_floatingObjects->prev()) {
- }
- m_floatingObjects->next();
- } else
- m_floatingObjects->first();
- for (FloatingObject* f = m_floatingObjects->current(); f; f = m_floatingObjects->next())
- lastRootBox()->floats().append(f->m_renderer);
- lastFloat = m_floatingObjects->last();
+ FloatingObjectSetIterator lastFloatIterator = floatingObjectSet.find(lastFloat);
+ ASSERT(lastFloatIterator != end);
+ ++lastFloatIterator;
+ it = lastFloatIterator;
+ }
+ for (; it != end; ++it)
+ lastRootBox()->floats().append((*it)->m_renderer);
+ lastFloat = !floatingObjectSet.isEmpty() ? floatingObjectSet.last() : 0;
}
size_t floatCount = floats.size();
// Floats that did not have layout did not repaint when we laid them out. They would have
@@ -1269,7 +1289,10 @@ bool RenderBlock::matchedEndLine(const InlineBidiResolver& resolver, const Inlin
int logicalBottom = lastLine->blockLogicalHeight() + abs(delta);
- for (FloatingObject* f = m_floatingObjects->first(); f; f = m_floatingObjects->next()) {
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ FloatingObjectSetIterator end = floatingObjectSet.end();
+ for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
+ FloatingObject* f = *it;
if (logicalBottomForFloat(f) >= logicalTop && logicalBottomForFloat(f) < logicalBottom)
return false;
}
@@ -1303,7 +1326,10 @@ bool RenderBlock::matchedEndLine(const InlineBidiResolver& resolver, const Inlin
int logicalBottom = lastLine->blockLogicalHeight() + abs(delta);
- for (FloatingObject* f = m_floatingObjects->first(); f; f = m_floatingObjects->next()) {
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ FloatingObjectSetIterator end = floatingObjectSet.end();
+ for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
+ FloatingObject* f = *it;
if (logicalBottomForFloat(f) >= logicalTop && logicalBottomForFloat(f) < logicalBottom)
return false;
}
@@ -1394,6 +1420,34 @@ bool RenderBlock::generatesLineBoxesForInlineChild(RenderObject* inlineObj, bool
return !it.atEnd();
}
+static void setStaticPositions(RenderBlock* block, RenderBox* child)
+{
+ // FIXME: The math here is actually not really right. It's a best-guess approximation that
+ // will work for the common cases
+ RenderObject* containerBlock = child->container();
+ if (containerBlock->isRenderInline()) {
+ // A relative positioned inline encloses us. In this case, we also have to determine our
+ // position as though we were an inline. Set |staticInlinePosition| and |staticBlockPosition| on the relative positioned
+ // inline so that we can obtain the value later.
+ toRenderInline(containerBlock)->layer()->setStaticInlinePosition(block->startOffsetForLine(block->logicalHeight(), false));
+ toRenderInline(containerBlock)->layer()->setStaticBlockPosition(block->logicalHeight());
+ }
+
+ bool isHorizontal = block->style()->isHorizontalWritingMode();
+ bool hasStaticInlinePosition = child->style()->hasStaticInlinePosition(isHorizontal);
+ bool hasStaticBlockPosition = child->style()->hasStaticBlockPosition(isHorizontal);
+
+ if (hasStaticInlinePosition) {
+ if (child->style()->isOriginalDisplayInlineType())
+ child->layer()->setStaticInlinePosition(block->startOffsetForLine(block->logicalHeight(), false));
+ else
+ child->layer()->setStaticInlinePosition(block->borderAndPaddingStart());
+ }
+
+ if (hasStaticBlockPosition)
+ child->layer()->setStaticBlockPosition(block->logicalHeight());
+}
+
// FIXME: The entire concept of the skipTrailingWhitespace function is flawed, since we really need to be building
// line boxes even for containers that may ultimately collapse away. Otherwise we'll never get positioned
// elements quite right. In other words, we need to build this function's work into the normal line
@@ -1406,29 +1460,8 @@ void RenderBlock::skipTrailingWhitespace(InlineIterator& iterator, bool isLineEm
RenderObject* object = iterator.obj;
if (object->isFloating()) {
insertFloatingObject(toRenderBox(object));
- } else if (object->isPositioned()) {
- // FIXME: The math here is actually not really right. It's a best-guess approximation that
- // will work for the common cases
- RenderObject* c = object->container();
- if (c->isRenderInline()) {
- // A relative positioned inline encloses us. In this case, we also have to determine our
- // position as though we were an inline. Set |staticX| and |staticY| on the relative positioned
- // inline so that we can obtain the value later.
- toRenderInline(c)->layer()->setStaticX(style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(height(), false) : logicalRightOffsetForLine(height(), false));
- toRenderInline(c)->layer()->setStaticY(height());
- }
-
- RenderBox* box = toRenderBox(object);
- if (box->style()->hasStaticX()) {
- if (box->style()->isOriginalDisplayInlineType())
- box->layer()->setStaticX(style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(height(), false) : width() - logicalRightOffsetForLine(height(), false));
- else
- box->layer()->setStaticX(style()->isLeftToRightDirection() ? borderLeft() + paddingLeft() : borderRight() + paddingRight());
- }
-
- if (box->style()->hasStaticY())
- box->layer()->setStaticY(height());
- }
+ } else if (object->isPositioned())
+ setStaticPositions(this, toRenderBox(object));
iterator.increment();
}
}
@@ -1442,29 +1475,8 @@ int RenderBlock::skipLeadingWhitespace(InlineBidiResolver& resolver, bool firstL
if (object->isFloating()) {
positionNewFloatOnLine(insertFloatingObject(toRenderBox(object)), lastFloatFromPreviousLine);
availableWidth = availableLogicalWidthForLine(logicalHeight(), firstLine);
- } else if (object->isPositioned()) {
- // FIXME: The math here is actually not really right. It's a best-guess approximation that
- // will work for the common cases
- RenderObject* c = object->container();
- if (c->isRenderInline()) {
- // A relative positioned inline encloses us. In this case, we also have to determine our
- // position as though we were an inline. Set |staticX| and |staticY| on the relative positioned
- // inline so that we can obtain the value later.
- toRenderInline(c)->layer()->setStaticX(style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(height(), firstLine) : logicalRightOffsetForLine(height(), firstLine));
- toRenderInline(c)->layer()->setStaticY(height());
- }
-
- RenderBox* box = toRenderBox(object);
- if (box->style()->hasStaticX()) {
- if (box->style()->isOriginalDisplayInlineType())
- box->layer()->setStaticX(style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(height(), firstLine) : width() - logicalRightOffsetForLine(height(), firstLine));
- else
- box->layer()->setStaticX(style()->isLeftToRightDirection() ? borderLeft() + paddingLeft() : borderRight() + paddingRight());
- }
-
- if (box->style()->hasStaticY())
- box->layer()->setStaticY(height());
- }
+ } else if (object->isPositioned())
+ setStaticPositions(this, toRenderBox(object));
resolver.increment();
}
resolver.commitExplicitEmbedding();
@@ -1488,13 +1500,13 @@ static bool shouldSkipWhitespaceAfterStartObject(RenderBlock* block, RenderObjec
return false;
}
-void RenderBlock::fitBelowFloats(int widthToFit, bool firstLine, int& availableWidth)
+void RenderBlock::fitBelowFloats(float widthToFit, bool firstLine, float& availableWidth)
{
ASSERT(widthToFit > availableWidth);
int floatLogicalBottom;
int lastFloatLogicalBottom = logicalHeight();
- int newLineWidth = availableWidth;
+ float newLineWidth = availableWidth;
while (true) {
floatLogicalBottom = nextFloatLogicalBottomBelow(lastFloatLogicalBottom);
if (!floatLogicalBottom)
@@ -1512,34 +1524,49 @@ void RenderBlock::fitBelowFloats(int widthToFit, bool firstLine, int& availableW
}
}
-static inline unsigned textWidth(RenderText* text, unsigned from, unsigned len, const Font& font, int xPos, bool isFixedPitch, bool collapseWhiteSpace)
+static inline float textWidth(RenderText* text, unsigned from, unsigned len, const Font& font, float xPos, bool isFixedPitch, bool collapseWhiteSpace)
{
if (isFixedPitch || (!from && len == text->textLength()) || text->style()->hasTextCombine())
return text->width(from, len, font, xPos);
return font.width(TextRun(text->characters() + from, len, !collapseWhiteSpace, xPos));
}
-static void tryHyphenating(RenderText* text, const Font& font, const AtomicString& localeIdentifier, int lastSpace, int pos, int xPos, int availableWidth, bool isFixedPitch, bool collapseWhiteSpace, int lastSpaceWordSpacing, InlineIterator& lineBreak, int nextBreakable, bool& hyphenated)
+static void tryHyphenating(RenderText* text, const Font& font, const AtomicString& localeIdentifier, int minimumPrefixLength, int minimumSuffixLength, int lastSpace, int pos, float xPos, int availableWidth, bool isFixedPitch, bool collapseWhiteSpace, int lastSpaceWordSpacing, InlineIterator& lineBreak, int nextBreakable, bool& hyphenated)
{
+ // Map 'hyphenate-limit-{before,after}: auto;' to 2.
+ if (minimumPrefixLength < 0)
+ minimumPrefixLength = 2;
+
+ if (minimumSuffixLength < 0)
+ minimumSuffixLength = 2;
+
+ if (pos - lastSpace <= minimumSuffixLength)
+ return;
+
const AtomicString& hyphenString = text->style()->hyphenString();
int hyphenWidth = font.width(TextRun(hyphenString.characters(), hyphenString.length()));
- int maxPrefixWidth = availableWidth - xPos - hyphenWidth - lastSpaceWordSpacing;
+ float maxPrefixWidth = availableWidth - xPos - hyphenWidth - lastSpaceWordSpacing;
// If the maximum width available for the prefix before the hyphen is small, then it is very unlikely
// that an hyphenation opportunity exists, so do not bother to look for it.
if (maxPrefixWidth <= font.pixelSize() * 5 / 4)
return;
unsigned prefixLength = font.offsetForPosition(TextRun(text->characters() + lastSpace, pos - lastSpace, !collapseWhiteSpace, xPos + lastSpaceWordSpacing), maxPrefixWidth, false);
- if (!prefixLength)
+ if (prefixLength < static_cast<unsigned>(minimumPrefixLength))
return;
- prefixLength = lastHyphenLocation(text->characters() + lastSpace, pos - lastSpace, prefixLength + 1, localeIdentifier);
- if (!prefixLength)
+ prefixLength = lastHyphenLocation(text->characters() + lastSpace, pos - lastSpace, min(prefixLength, static_cast<unsigned>(pos - lastSpace - minimumSuffixLength)) + 1, localeIdentifier);
+ // FIXME: The following assumes that the character at lastSpace is a space (and therefore should not factor
+ // into hyphenate-limit-before) unless lastSpace is 0. This is wrong in the rare case of hyphenating
+ // the first word in a text node which has leading whitespace.
+ if (prefixLength - (lastSpace ? 1 : 0) < static_cast<unsigned>(minimumPrefixLength))
return;
+ ASSERT(pos - lastSpace - prefixLength >= static_cast<unsigned>(minimumSuffixLength));
+
#if !ASSERT_DISABLED
- int prefixWidth = hyphenWidth + textWidth(text, lastSpace, prefixLength, font, xPos, isFixedPitch, collapseWhiteSpace) + lastSpaceWordSpacing;
+ float prefixWidth = hyphenWidth + textWidth(text, lastSpace, prefixLength, font, xPos, isFixedPitch, collapseWhiteSpace) + lastSpaceWordSpacing;
ASSERT(xPos + prefixWidth <= availableWidth);
#else
UNUSED_PARAM(isFixedPitch);
@@ -1551,7 +1578,7 @@ static void tryHyphenating(RenderText* text, const Font& font, const AtomicStrin
hyphenated = true;
}
-InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool firstLine, bool& isLineEmpty, bool& previousLineBrokeCleanly,
+InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool firstLine, bool& isLineEmpty, LineBreakIteratorInfo& lineBreakIteratorInfo, bool& previousLineBrokeCleanly,
bool& hyphenated, EClear* clear, FloatingObject* lastFloatFromPreviousLine)
{
ASSERT(resolver.position().block == this);
@@ -1559,10 +1586,10 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
bool appliedStartWidth = resolver.position().pos > 0;
LineMidpointState& lineMidpointState = resolver.midpointState();
- int width = skipLeadingWhitespace(resolver, firstLine, isLineEmpty, previousLineBrokeCleanly, lastFloatFromPreviousLine);
+ float width = skipLeadingWhitespace(resolver, firstLine, isLineEmpty, previousLineBrokeCleanly, lastFloatFromPreviousLine);
- int w = 0;
- int tmpW = 0;
+ float w = 0;
+ float tmpW = 0;
if (resolver.position().atEnd())
return resolver.position();
@@ -1581,8 +1608,8 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
InlineIterator lBreak = resolver.position();
- RenderObject *o = resolver.position().obj;
- RenderObject *last = o;
+ RenderObject* o = resolver.position().obj;
+ RenderObject* last = o;
unsigned pos = resolver.position().pos;
int nextBreakable = resolver.position().nextBreakablePosition;
bool atStart = true;
@@ -1655,28 +1682,26 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
floatsFitOnLine = false;
} else if (o->isPositioned()) {
// If our original display wasn't an inline type, then we can
- // go ahead and determine our static x position now.
+ // go ahead and determine our static inline position now.
RenderBox* box = toRenderBox(o);
bool isInlineType = box->style()->isOriginalDisplayInlineType();
- bool needToSetStaticX = box->style()->hasStaticX();
- if (box->style()->hasStaticX() && !isInlineType) {
- box->layer()->setStaticX(o->parent()->style()->isLeftToRightDirection() ?
- borderLeft() + paddingLeft() :
- borderRight() + paddingRight());
- needToSetStaticX = false;
+ bool needToSetStaticInlinePosition = box->style()->hasStaticInlinePosition(style()->isHorizontalWritingMode());
+ if (needToSetStaticInlinePosition && !isInlineType) {
+ box->layer()->setStaticInlinePosition(borderAndPaddingStart());
+ needToSetStaticInlinePosition = false;
}
// If our original display was an INLINE type, then we can go ahead
// and determine our static y position now.
- bool needToSetStaticY = box->style()->hasStaticY();
- if (box->style()->hasStaticY() && isInlineType) {
- box->layer()->setStaticY(height());
- needToSetStaticY = false;
+ bool needToSetStaticBlockPosition = box->style()->hasStaticBlockPosition(style()->isHorizontalWritingMode());
+ if (needToSetStaticBlockPosition && isInlineType) {
+ box->layer()->setStaticBlockPosition(logicalHeight());
+ needToSetStaticBlockPosition = false;
}
- bool needToCreateLineBox = needToSetStaticX || needToSetStaticY;
+ bool needToCreateLineBox = needToSetStaticInlinePosition || needToSetStaticBlockPosition;
RenderObject* c = o->container();
- if (c->isRenderInline() && (!needToSetStaticX || !needToSetStaticY))
+ if (c->isRenderInline() && (!needToSetStaticInlinePosition || !needToSetStaticBlockPosition))
needToCreateLineBox = true;
// If we're ignoring spaces, we have to stop and include this object and
@@ -1776,25 +1801,25 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
const Font& f = style->font();
bool isFixedPitch = f.isFixedPitch();
- bool canHyphenate = style->hyphens() == HyphensAuto && WebCore::canHyphenate(style->hyphenationLocale());
+ bool canHyphenate = style->hyphens() == HyphensAuto && WebCore::canHyphenate(style->locale());
int lastSpace = pos;
- int wordSpacing = o->style()->wordSpacing();
- int lastSpaceWordSpacing = 0;
+ float wordSpacing = o->style()->wordSpacing();
+ float lastSpaceWordSpacing = 0;
// Non-zero only when kerning is enabled, in which case we measure words with their trailing
// space, then subtract its width.
- int wordTrailingSpaceWidth = f.typesettingFeatures() & Kerning ? f.width(TextRun(&space, 1)) + wordSpacing : 0;
+ float wordTrailingSpaceWidth = f.typesettingFeatures() & Kerning ? f.width(TextRun(&space, 1)) + wordSpacing : 0;
- int wrapW = tmpW + inlineLogicalWidth(o, !appliedStartWidth, true);
- int charWidth = 0;
+ float wrapW = tmpW + inlineLogicalWidth(o, !appliedStartWidth, true);
+ float charWidth = 0;
bool breakNBSP = autoWrap && o->style()->nbspMode() == SPACE;
// Auto-wrapping text should wrap in the middle of a word only if it could not wrap before the word,
// which is only possible if the word is the first thing on the line, that is, if |w| is zero.
bool breakWords = o->style()->breakWords() && ((autoWrap && !w) || currWS == PRE);
bool midWordBreak = false;
bool breakAll = o->style()->wordBreak() == BreakAllWordBreak && autoWrap;
- int hyphenWidth = 0;
+ float hyphenWidth = 0;
if (t->isWordBreak()) {
w += tmpW;
@@ -1842,7 +1867,12 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
midWordBreak = w + wrapW + charWidth > width;
}
- bool betweenWords = c == '\n' || (currWS != PRE && !atStart && isBreakable(str, pos, strlen, nextBreakable, breakNBSP) && (style->hyphens() != HyphensNone || (pos && str[pos - 1] != softHyphen)));
+ if (lineBreakIteratorInfo.first != t) {
+ lineBreakIteratorInfo.first = t;
+ lineBreakIteratorInfo.second.reset(str, strlen);
+ }
+
+ bool betweenWords = c == '\n' || (currWS != PRE && !atStart && isBreakable(lineBreakIteratorInfo.second, pos, nextBreakable, breakNBSP) && (style->hyphens() != HyphensNone || (pos && str[pos - 1] != softHyphen)));
if (betweenWords || midWordBreak) {
bool stoppedIgnoringSpaces = false;
@@ -1863,7 +1893,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
}
}
- int additionalTmpW;
+ float additionalTmpW;
if (wordTrailingSpaceWidth && currentCharacterIsSpace)
additionalTmpW = textWidth(t, lastSpace, pos + 1 - lastSpace, f, w + tmpW, isFixedPitch, collapseWhiteSpace) - wordTrailingSpaceWidth + lastSpaceWordSpacing;
else
@@ -1900,7 +1930,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
}
if (lineWasTooWide || w + tmpW > width) {
if (canHyphenate && w + tmpW > width) {
- tryHyphenating(t, f, style->hyphenationLocale(), lastSpace, pos, w + tmpW - additionalTmpW, width, isFixedPitch, collapseWhiteSpace, lastSpaceWordSpacing, lBreak, nextBreakable, hyphenated);
+ tryHyphenating(t, f, style->locale(), style->hyphenationLimitBefore(), style->hyphenationLimitAfter(), lastSpace, pos, w + tmpW - additionalTmpW, width, isFixedPitch, collapseWhiteSpace, lastSpaceWordSpacing, lBreak, nextBreakable, hyphenated);
if (hyphenated)
goto end;
}
@@ -2013,12 +2043,12 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
}
// IMPORTANT: pos is > length here!
- int additionalTmpW = ignoringSpaces ? 0 : textWidth(t, lastSpace, pos - lastSpace, f, w + tmpW, isFixedPitch, collapseWhiteSpace) + lastSpaceWordSpacing;
+ float additionalTmpW = ignoringSpaces ? 0 : textWidth(t, lastSpace, pos - lastSpace, f, w + tmpW, isFixedPitch, collapseWhiteSpace) + lastSpaceWordSpacing;
tmpW += additionalTmpW;
tmpW += inlineLogicalWidth(o, !appliedStartWidth, true);
if (canHyphenate && w + tmpW > width) {
- tryHyphenating(t, f, style->hyphenationLocale(), lastSpace, pos, w + tmpW - additionalTmpW, width, isFixedPitch, collapseWhiteSpace, lastSpaceWordSpacing, lBreak, nextBreakable, hyphenated);
+ tryHyphenating(t, f, style->locale(), style->hyphenationLimitBefore(), style->hyphenationLimitAfter(), lastSpace, pos, w + tmpW - additionalTmpW, width, isFixedPitch, collapseWhiteSpace, lastSpaceWordSpacing, lBreak, nextBreakable, hyphenated);
if (hyphenated)
goto end;
}
@@ -2249,7 +2279,7 @@ void RenderBlock::checkLinesForTextOverflow()
// space.
int width = curr == firstRootBox() ? firstLineEllipsisWidth : ellipsisWidth;
int blockEdge = ltr ? blockRightEdge : blockLeftEdge;
- if (curr->canAccommodateEllipsis(ltr, blockEdge, lineBoxEdge, width))
+ if (curr->lineCanAccommodateEllipsis(ltr, blockEdge, lineBoxEdge, width))
curr->placeEllipsis(ellipsisStr, ltr, blockLeftEdge, blockRightEdge, width);
}
}
diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp
index 39c80d4..4d90284 100644
--- a/Source/WebCore/rendering/RenderBox.cpp
+++ b/Source/WebCore/rendering/RenderBox.cpp
@@ -236,8 +236,6 @@ void RenderBox::removeFloatingOrPositionedChildFromBlockLists()
RenderBlock* currBlock = toRenderBlock(curr);
if (currBlock->containsFloat(this))
parentBlock = currBlock;
- else
- break;
}
}
@@ -576,14 +574,14 @@ IntRect RenderBox::reflectedRect(const IntRect& r) const
bool RenderBox::includeVerticalScrollbarSize() const
{
- return !ScrollbarTheme::nativeTheme()->usesOverlayScrollbars()
- && hasOverflowClip() && (style()->overflowY() == OSCROLL || style()->overflowY() == OAUTO);
+ return hasOverflowClip() && !layer()->hasOverlayScrollbars()
+ && (style()->overflowY() == OSCROLL || style()->overflowY() == OAUTO);
}
bool RenderBox::includeHorizontalScrollbarSize() const
{
- return !ScrollbarTheme::nativeTheme()->usesOverlayScrollbars()
- && hasOverflowClip() && (style()->overflowX() == OSCROLL || style()->overflowX() == OAUTO);
+ return hasOverflowClip() && !layer()->hasOverlayScrollbars()
+ && (style()->overflowX() == OSCROLL || style()->overflowX() == OAUTO);
}
int RenderBox::verticalScrollbarWidth() const
@@ -1288,7 +1286,7 @@ IntSize RenderBox::offsetFromContainer(RenderObject* o, const IntPoint& point) c
} else
offset += locationOffsetIncludingFlipping();
} else
- offset += locationOffset();
+ offset += locationOffsetIncludingFlipping();
}
if (o->hasOverflowClip())
@@ -1321,18 +1319,18 @@ void RenderBox::positionLineBox(InlineBox* box)
if (isPositioned()) {
// Cache the x position only if we were an INLINE type originally.
bool wasInline = style()->isOriginalDisplayInlineType();
- if (wasInline && style()->hasStaticX()) {
+ if (wasInline && style()->hasStaticInlinePosition(box->isHorizontal())) {
// The value is cached in the xPos of the box. We only need this value if
// our object was inline originally, since otherwise it would have ended up underneath
// the inlines.
- layer()->setStaticX(box->x());
+ layer()->setStaticInlinePosition(lroundf(box->logicalLeft()));
setChildNeedsLayout(true, false); // Just go ahead and mark the positioned object as needing layout, so it will update its position properly.
- } else if (!wasInline && style()->hasStaticY()) {
+ } else if (!wasInline && style()->hasStaticBlockPosition(box->isHorizontal())) {
// Our object was a block originally, so we make our normal flow position be
// just below the line box (as though all the inlines that came before us got
// wrapped in an anonymous block, which is what would have happened had we been
// in flow). This value was cached in the y() of the box.
- layer()->setStaticY(box->y());
+ layer()->setStaticBlockPosition(box->logicalTop());
setChildNeedsLayout(true, false); // Just go ahead and mark the positioned object as needing layout, so it will update its position properly.
}
@@ -1340,7 +1338,7 @@ void RenderBox::positionLineBox(InlineBox* box)
box->remove();
box->destroy(renderArena());
} else if (isReplaced()) {
- setLocation(box->x(), box->y());
+ setLocation(lroundf(box->x()), lroundf(box->y()));
m_inlineBoxWrapper = box;
}
}
@@ -1994,7 +1992,7 @@ int RenderBox::computeReplacedLogicalWidthUsing(Length logicalWidth) const
// FIXME: containingBlockLogicalWidthForContent() is wrong if the replaced element's block-flow is perpendicular to the
// containing block's block-flow.
// https://bugs.webkit.org/show_bug.cgi?id=46496
- const int cw = isPositioned() ? containingBlockWidthForPositioned(toRenderBoxModelObject(container())) : containingBlockLogicalWidthForContent();
+ const int cw = isPositioned() ? containingBlockLogicalWidthForPositioned(toRenderBoxModelObject(container())) : containingBlockLogicalWidthForContent();
if (cw > 0)
return computeContentBoxLogicalWidth(logicalWidth.calcMinValue(cw));
}
@@ -2041,7 +2039,7 @@ int RenderBox::computeReplacedLogicalHeightUsing(Length logicalHeight) const
// FIXME: availableLogicalHeight() is wrong if the replaced element's block-flow is perpendicular to the
// containing block's block-flow.
// https://bugs.webkit.org/show_bug.cgi?id=46496
- int availableHeight = isPositioned() ? containingBlockHeightForPositioned(toRenderBoxModelObject(cb)) : toRenderBox(cb)->availableLogicalHeight();
+ int availableHeight = isPositioned() ? containingBlockLogicalHeightForPositioned(toRenderBoxModelObject(cb)) : toRenderBox(cb)->availableLogicalHeight();
// It is necessary to use the border-box to match WinIE's broken
// box model. This is essential for sizing inside
@@ -2117,8 +2115,9 @@ void RenderBox::computeBlockDirectionMargins(RenderBlock* containingBlock)
containingBlock->setMarginAfterForChild(this, style()->marginAfterUsing(containingBlockStyle).calcMinValue(cw));
}
-int RenderBox::containingBlockWidthForPositioned(const RenderBoxModelObject* containingBlock) const
+int RenderBox::containingBlockLogicalWidthForPositioned(const RenderBoxModelObject* containingBlock, bool checkForPerpendicularWritingMode) const
{
+<<<<<<< HEAD
#if PLATFORM(ANDROID)
// Fixed element's position should be decided by the visible screen size.
// That is in the doc coordindate.
@@ -2132,6 +2131,14 @@ int RenderBox::containingBlockWidthForPositioned(const RenderBoxModelObject* con
return containingBlockBox->width() - containingBlockBox->borderLeft() - containingBlockBox->borderRight() - containingBlockBox->verticalScrollbarWidth();
}
+=======
+ if (checkForPerpendicularWritingMode && containingBlock->style()->isHorizontalWritingMode() != style()->isHorizontalWritingMode())
+ return containingBlockLogicalHeightForPositioned(containingBlock, false);
+
+ if (containingBlock->isBox())
+ return toRenderBox(containingBlock)->clientLogicalWidth();
+
+>>>>>>> WebKit at r80534
ASSERT(containingBlock->isRenderInline() && containingBlock->isRelPositioned());
const RenderInline* flow = toRenderInline(containingBlock);
@@ -2155,6 +2162,7 @@ int RenderBox::containingBlockWidthForPositioned(const RenderBoxModelObject* con
return max(0, (fromRight - fromLeft));
}
+<<<<<<< HEAD
int RenderBox::containingBlockHeightForPositioned(const RenderBoxModelObject* containingBlock) const
{
#if PLATFORM(ANDROID)
@@ -2166,13 +2174,60 @@ int RenderBox::containingBlockHeightForPositioned(const RenderBoxModelObject* co
}
#endif
int heightResult = 0;
+=======
+int RenderBox::containingBlockLogicalHeightForPositioned(const RenderBoxModelObject* containingBlock, bool checkForPerpendicularWritingMode) const
+{
+ if (checkForPerpendicularWritingMode && containingBlock->style()->isHorizontalWritingMode() != style()->isHorizontalWritingMode())
+ return containingBlockLogicalWidthForPositioned(containingBlock, false);
+
+>>>>>>> WebKit at r80534
if (containingBlock->isBox())
- heightResult = toRenderBox(containingBlock)->height();
- else if (containingBlock->isRenderInline()) {
- ASSERT(containingBlock->isRelPositioned());
- heightResult = toRenderInline(containingBlock)->linesBoundingBox().height();
+ return toRenderBox(containingBlock)->clientLogicalHeight();
+
+ ASSERT(containingBlock->isRenderInline() && containingBlock->isRelPositioned());
+
+ const RenderInline* flow = toRenderInline(containingBlock);
+ InlineFlowBox* first = flow->firstLineBox();
+ InlineFlowBox* last = flow->lastLineBox();
+
+ // If the containing block is empty, return a height of 0.
+ if (!first || !last)
+ return 0;
+
+ int heightResult;
+ IntRect boundingBox = flow->linesBoundingBox();
+ if (containingBlock->style()->isHorizontalWritingMode())
+ heightResult = boundingBox.height();
+ else
+ heightResult = boundingBox.width();
+ heightResult -= (containingBlock->borderBefore() + containingBlock->borderAfter());
+ return heightResult;
+}
+
+static void computeInlineStaticDistance(Length& logicalLeft, Length& logicalRight, const RenderBox* child, const RenderBoxModelObject* containerBlock, int containerLogicalWidth,
+ TextDirection containerDirection)
+{
+ if (!logicalLeft.isAuto() || !logicalRight.isAuto())
+ return;
+
+ // FIXME: The static distance computation has not been patched for mixed writing modes yet.
+ if (containerDirection == LTR) {
+ int staticPosition = child->layer()->staticInlinePosition() - containerBlock->borderLogicalLeft();
+ for (RenderObject* curr = child->parent(); curr && curr != containerBlock; curr = curr->parent()) {
+ if (curr->isBox())
+ staticPosition += toRenderBox(curr)->logicalLeft();
+ }
+ logicalLeft.setValue(Fixed, staticPosition);
+ } else {
+ RenderBox* enclosingBox = child->parent()->enclosingBox();
+ int staticPosition = child->layer()->staticInlinePosition() + containerLogicalWidth + containerBlock->borderLogicalRight();
+ staticPosition -= enclosingBox->logicalWidth();
+ for (RenderObject* curr = enclosingBox; curr && curr != containerBlock; curr = curr->parent()) {
+ if (curr->isBox())
+ staticPosition -= toRenderBox(curr)->logicalLeft();
+ }
+ logicalRight.setValue(Fixed, staticPosition);
}
- return heightResult - containingBlock->borderTop() - containingBlock->borderBottom();
}
void RenderBox::computePositionedLogicalWidth()
@@ -2211,17 +2266,21 @@ void RenderBox::computePositionedLogicalWidth()
// relative positioned inline.
const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(container());
- const int containerWidth = containingBlockWidthForPositioned(containerBlock);
+ const int containerLogicalWidth = containingBlockLogicalWidthForPositioned(containerBlock);
// To match WinIE, in quirks mode use the parent's 'direction' property
// instead of the the container block's.
TextDirection containerDirection = (document()->inQuirksMode()) ? parent()->style()->direction() : containerBlock->style()->direction();
- const int bordersPlusPadding = borderAndPaddingWidth();
- const Length marginLeft = style()->marginLeft();
- const Length marginRight = style()->marginRight();
- Length left = style()->left();
- Length right = style()->right();
+ bool isHorizontal = style()->isHorizontalWritingMode();
+ const int bordersPlusPadding = borderAndPaddingLogicalWidth();
+ const Length marginLogicalLeft = isHorizontal ? style()->marginLeft() : style()->marginTop();
+ const Length marginLogicalRight = isHorizontal ? style()->marginRight() : style()->marginBottom();
+ int& marginLogicalLeftAlias = isHorizontal ? m_marginLeft : m_marginTop;
+ int& marginLogicalRightAlias = isHorizontal ? m_marginRight : m_marginBottom;
+
+ Length logicalLeft = style()->logicalLeft();
+ Length logicalRight = style()->logicalRight();
/*---------------------------------------------------------------------------*\
* For the purposes of this section and the next, the term "static position"
@@ -2249,107 +2308,98 @@ void RenderBox::computePositionedLogicalWidth()
// see FIXME 2
// Calculate the static distance if needed.
- if (left.isAuto() && right.isAuto()) {
- if (containerDirection == LTR) {
- // 'staticX' should already have been set through layout of the parent.
- int staticPosition = layer()->staticX() - containerBlock->borderLeft();
- for (RenderObject* curr = parent(); curr && curr != containerBlock; curr = curr->parent()) {
- if (curr->isBox())
- staticPosition += toRenderBox(curr)->x();
- }
- left.setValue(Fixed, staticPosition);
- } else {
- RenderBox* enclosingBox = parent()->enclosingBox();
- // 'staticX' should already have been set through layout of the parent.
- int staticPosition = layer()->staticX() + containerWidth + containerBlock->borderRight();
- staticPosition -= enclosingBox->width();
- for (RenderObject* curr = enclosingBox; curr && curr != containerBlock; curr = curr->parent()) {
- if (curr->isBox())
- staticPosition -= toRenderBox(curr)->x();
- }
- right.setValue(Fixed, staticPosition);
- }
- }
-
+ computeInlineStaticDistance(logicalLeft, logicalRight, this, containerBlock, containerLogicalWidth, containerDirection);
+
// Calculate constraint equation values for 'width' case.
- int widthResult;
- int xResult;
- computePositionedLogicalWidthUsing(style()->width(), containerBlock, containerDirection,
- containerWidth, bordersPlusPadding,
- left, right, marginLeft, marginRight,
- widthResult, m_marginLeft, m_marginRight, xResult);
- setWidth(widthResult);
- setX(xResult);
+ int logicalWidthResult;
+ int logicalLeftResult;
+ computePositionedLogicalWidthUsing(style()->logicalWidth(), containerBlock, containerDirection,
+ containerLogicalWidth, bordersPlusPadding,
+ logicalLeft, logicalRight, marginLogicalLeft, marginLogicalRight,
+ logicalWidthResult, marginLogicalLeftAlias, marginLogicalRightAlias, logicalLeftResult);
+ setLogicalWidth(logicalWidthResult);
+ setLogicalLeft(logicalLeftResult);
// Calculate constraint equation values for 'max-width' case.
- if (!style()->maxWidth().isUndefined()) {
- int maxWidth;
- int maxMarginLeft;
- int maxMarginRight;
- int maxXPos;
-
- computePositionedLogicalWidthUsing(style()->maxWidth(), containerBlock, containerDirection,
- containerWidth, bordersPlusPadding,
- left, right, marginLeft, marginRight,
- maxWidth, maxMarginLeft, maxMarginRight, maxXPos);
-
- if (width() > maxWidth) {
- setWidth(maxWidth);
- m_marginLeft = maxMarginLeft;
- m_marginRight = maxMarginRight;
- m_frameRect.setX(maxXPos);
+ if (!style()->logicalMaxWidth().isUndefined()) {
+ int maxLogicalWidth;
+ int maxMarginLogicalLeft;
+ int maxMarginLogicalRight;
+ int maxLogicalLeftPos;
+
+ computePositionedLogicalWidthUsing(style()->logicalMaxWidth(), containerBlock, containerDirection,
+ containerLogicalWidth, bordersPlusPadding,
+ logicalLeft, logicalRight, marginLogicalLeft, marginLogicalRight,
+ maxLogicalWidth, maxMarginLogicalLeft, maxMarginLogicalRight, maxLogicalLeftPos);
+
+ if (logicalWidth() > maxLogicalWidth) {
+ setLogicalWidth(maxLogicalWidth);
+ marginLogicalLeftAlias = maxMarginLogicalLeft;
+ marginLogicalRightAlias = maxMarginLogicalRight;
+ setLogicalLeft(maxLogicalLeftPos);
}
}
// Calculate constraint equation values for 'min-width' case.
- if (!style()->minWidth().isZero()) {
- int minWidth;
- int minMarginLeft;
- int minMarginRight;
- int minXPos;
-
- computePositionedLogicalWidthUsing(style()->minWidth(), containerBlock, containerDirection,
- containerWidth, bordersPlusPadding,
- left, right, marginLeft, marginRight,
- minWidth, minMarginLeft, minMarginRight, minXPos);
-
- if (width() < minWidth) {
- setWidth(minWidth);
- m_marginLeft = minMarginLeft;
- m_marginRight = minMarginRight;
- m_frameRect.setX(minXPos);
+ if (!style()->logicalMinWidth().isZero()) {
+ int minLogicalWidth;
+ int minMarginLogicalLeft;
+ int minMarginLogicalRight;
+ int minLogicalLeftPos;
+
+ computePositionedLogicalWidthUsing(style()->logicalMinWidth(), containerBlock, containerDirection,
+ containerLogicalWidth, bordersPlusPadding,
+ logicalLeft, logicalRight, marginLogicalLeft, marginLogicalRight,
+ minLogicalWidth, minMarginLogicalLeft, minMarginLogicalRight, minLogicalLeftPos);
+
+ if (logicalWidth() < minLogicalWidth) {
+ setLogicalWidth(minLogicalWidth);
+ marginLogicalLeftAlias = minMarginLogicalLeft;
+ marginLogicalRightAlias = minMarginLogicalRight;
+ setLogicalLeft(minLogicalLeftPos);
}
}
- if (stretchesToMinIntrinsicLogicalWidth() && width() < minPreferredLogicalWidth() - bordersPlusPadding) {
+ if (stretchesToMinIntrinsicLogicalWidth() && logicalWidth() < minPreferredLogicalWidth() - bordersPlusPadding) {
computePositionedLogicalWidthUsing(Length(minPreferredLogicalWidth() - bordersPlusPadding, Fixed), containerBlock, containerDirection,
- containerWidth, bordersPlusPadding,
- left, right, marginLeft, marginRight,
- widthResult, m_marginLeft, m_marginRight, xResult);
- setWidth(widthResult);
- setX(xResult);
+ containerLogicalWidth, bordersPlusPadding,
+ logicalLeft, logicalRight, marginLogicalLeft, marginLogicalRight,
+ logicalWidthResult, marginLogicalLeftAlias, marginLogicalRightAlias, logicalLeftResult);
+ setLogicalWidth(logicalWidthResult);
+ setLogicalLeft(logicalLeftResult);
}
- // Put width() into correct form.
- setWidth(width() + bordersPlusPadding);
+ // Put logicalWidth() into correct form.
+ setLogicalWidth(logicalWidth() + bordersPlusPadding);
}
-void RenderBox::computePositionedLogicalWidthUsing(Length width, const RenderBoxModelObject* containerBlock, TextDirection containerDirection,
- const int containerWidth, const int bordersPlusPadding,
- const Length left, const Length right, const Length marginLeft, const Length marginRight,
- int& widthValue, int& marginLeftValue, int& marginRightValue, int& xPos)
+static void computeLogicalLeftPositionedOffset(int& logicalLeftPos, const RenderBox* child, int logicalWidthValue, const RenderBoxModelObject* containerBlock, int containerLogicalWidth)
+{
+ // Deal with differing writing modes here. Our offset needs to be in the containing block's coordinate space. If the containing block is flipped
+ // along this axis, then we need to flip the coordinate. This can only happen if the containing block is both a flipped mode and perpendicular to us.
+ if (containerBlock->style()->isHorizontalWritingMode() != child->style()->isHorizontalWritingMode() && containerBlock->style()->isFlippedBlocksWritingMode()) {
+ logicalLeftPos = containerLogicalWidth - logicalWidthValue - logicalLeftPos;
+ logicalLeftPos += (child->style()->isHorizontalWritingMode() ? containerBlock->borderRight() : containerBlock->borderBottom());
+ } else
+ logicalLeftPos += (child->style()->isHorizontalWritingMode() ? containerBlock->borderLeft() : containerBlock->borderTop());
+}
+
+void RenderBox::computePositionedLogicalWidthUsing(Length logicalWidth, const RenderBoxModelObject* containerBlock, TextDirection containerDirection,
+ int containerLogicalWidth, int bordersPlusPadding,
+ Length logicalLeft, Length logicalRight, Length marginLogicalLeft, Length marginLogicalRight,
+ int& logicalWidthValue, int& marginLogicalLeftValue, int& marginLogicalRightValue, int& logicalLeftPos)
{
// 'left' and 'right' cannot both be 'auto' because one would of been
// converted to the static position already
- ASSERT(!(left.isAuto() && right.isAuto()));
+ ASSERT(!(logicalLeft.isAuto() && logicalRight.isAuto()));
- int leftValue = 0;
+ int logicalLeftValue = 0;
- bool widthIsAuto = width.isIntrinsicOrAuto();
- bool leftIsAuto = left.isAuto();
- bool rightIsAuto = right.isAuto();
+ bool logicalWidthIsAuto = logicalWidth.isIntrinsicOrAuto();
+ bool logicalLeftIsAuto = logicalLeft.isAuto();
+ bool logicalRightIsAuto = logicalRight.isAuto();
- if (!leftIsAuto && !widthIsAuto && !rightIsAuto) {
+ if (!logicalLeftIsAuto && !logicalWidthIsAuto && !logicalRightIsAuto) {
/*-----------------------------------------------------------------------*\
* If none of the three is 'auto': If both 'margin-left' and 'margin-
* right' are 'auto', solve the equation under the extra constraint that
@@ -2365,43 +2415,43 @@ void RenderBox::computePositionedLogicalWidthUsing(Length width, const RenderBox
// NOTE: It is not necessary to solve for 'right' in the over constrained
// case because the value is not used for any further calculations.
- leftValue = left.calcValue(containerWidth);
- widthValue = computeContentBoxLogicalWidth(width.calcValue(containerWidth));
+ logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
+ logicalWidthValue = computeContentBoxLogicalWidth(logicalWidth.calcValue(containerLogicalWidth));
- const int availableSpace = containerWidth - (leftValue + widthValue + right.calcValue(containerWidth) + bordersPlusPadding);
+ const int availableSpace = containerLogicalWidth - (logicalLeftValue + logicalWidthValue + logicalRight.calcValue(containerLogicalWidth) + bordersPlusPadding);
// Margins are now the only unknown
- if (marginLeft.isAuto() && marginRight.isAuto()) {
+ if (marginLogicalLeft.isAuto() && marginLogicalRight.isAuto()) {
// Both margins auto, solve for equality
if (availableSpace >= 0) {
- marginLeftValue = availableSpace / 2; // split the difference
- marginRightValue = availableSpace - marginLeftValue; // account for odd valued differences
+ marginLogicalLeftValue = availableSpace / 2; // split the difference
+ marginLogicalRightValue = availableSpace - marginLogicalLeftValue; // account for odd valued differences
} else {
// see FIXME 1
if (containerDirection == LTR) {
- marginLeftValue = 0;
- marginRightValue = availableSpace; // will be negative
+ marginLogicalLeftValue = 0;
+ marginLogicalRightValue = availableSpace; // will be negative
} else {
- marginLeftValue = availableSpace; // will be negative
- marginRightValue = 0;
+ marginLogicalLeftValue = availableSpace; // will be negative
+ marginLogicalRightValue = 0;
}
}
- } else if (marginLeft.isAuto()) {
+ } else if (marginLogicalLeft.isAuto()) {
// Solve for left margin
- marginRightValue = marginRight.calcValue(containerWidth);
- marginLeftValue = availableSpace - marginRightValue;
- } else if (marginRight.isAuto()) {
+ marginLogicalRightValue = marginLogicalRight.calcValue(containerLogicalWidth);
+ marginLogicalLeftValue = availableSpace - marginLogicalRightValue;
+ } else if (marginLogicalRight.isAuto()) {
// Solve for right margin
- marginLeftValue = marginLeft.calcValue(containerWidth);
- marginRightValue = availableSpace - marginLeftValue;
+ marginLogicalLeftValue = marginLogicalLeft.calcValue(containerLogicalWidth);
+ marginLogicalRightValue = availableSpace - marginLogicalLeftValue;
} else {
// Over-constrained, solve for left if direction is RTL
- marginLeftValue = marginLeft.calcValue(containerWidth);
- marginRightValue = marginRight.calcValue(containerWidth);
+ marginLogicalLeftValue = marginLogicalLeft.calcValue(containerLogicalWidth);
+ marginLogicalRightValue = marginLogicalRight.calcValue(containerLogicalWidth);
// see FIXME 1 -- used to be "this->style()->direction()"
if (containerDirection == RTL)
- leftValue = (availableSpace + leftValue) - marginLeftValue - marginRightValue;
+ logicalLeftValue = (availableSpace + logicalLeftValue) - marginLogicalLeftValue - marginLogicalRightValue;
}
} else {
/*--------------------------------------------------------------------*\
@@ -2446,51 +2496,51 @@ void RenderBox::computePositionedLogicalWidthUsing(Length width, const RenderBox
// because the value is not used for any further calculations.
// Calculate margins, 'auto' margins are ignored.
- marginLeftValue = marginLeft.calcMinValue(containerWidth);
- marginRightValue = marginRight.calcMinValue(containerWidth);
+ marginLogicalLeftValue = marginLogicalLeft.calcMinValue(containerLogicalWidth);
+ marginLogicalRightValue = marginLogicalRight.calcMinValue(containerLogicalWidth);
- const int availableSpace = containerWidth - (marginLeftValue + marginRightValue + bordersPlusPadding);
+ const int availableSpace = containerLogicalWidth - (marginLogicalLeftValue + marginLogicalRightValue + bordersPlusPadding);
// FIXME: Is there a faster way to find the correct case?
// Use rule/case that applies.
- if (leftIsAuto && widthIsAuto && !rightIsAuto) {
+ if (logicalLeftIsAuto && logicalWidthIsAuto && !logicalRightIsAuto) {
// RULE 1: (use shrink-to-fit for width, and solve of left)
- int rightValue = right.calcValue(containerWidth);
+ int logicalRightValue = logicalRight.calcValue(containerLogicalWidth);
// FIXME: would it be better to have shrink-to-fit in one step?
int preferredWidth = maxPreferredLogicalWidth() - bordersPlusPadding;
int preferredMinWidth = minPreferredLogicalWidth() - bordersPlusPadding;
- int availableWidth = availableSpace - rightValue;
- widthValue = min(max(preferredMinWidth, availableWidth), preferredWidth);
- leftValue = availableSpace - (widthValue + rightValue);
- } else if (!leftIsAuto && widthIsAuto && rightIsAuto) {
+ int availableWidth = availableSpace - logicalRightValue;
+ logicalWidthValue = min(max(preferredMinWidth, availableWidth), preferredWidth);
+ logicalLeftValue = availableSpace - (logicalWidthValue + logicalRightValue);
+ } else if (!logicalLeftIsAuto && logicalWidthIsAuto && logicalRightIsAuto) {
// RULE 3: (use shrink-to-fit for width, and no need solve of right)
- leftValue = left.calcValue(containerWidth);
+ logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
// FIXME: would it be better to have shrink-to-fit in one step?
int preferredWidth = maxPreferredLogicalWidth() - bordersPlusPadding;
int preferredMinWidth = minPreferredLogicalWidth() - bordersPlusPadding;
- int availableWidth = availableSpace - leftValue;
- widthValue = min(max(preferredMinWidth, availableWidth), preferredWidth);
- } else if (leftIsAuto && !width.isAuto() && !rightIsAuto) {
+ int availableWidth = availableSpace - logicalLeftValue;
+ logicalWidthValue = min(max(preferredMinWidth, availableWidth), preferredWidth);
+ } else if (logicalLeftIsAuto && !logicalWidthIsAuto && !logicalRightIsAuto) {
// RULE 4: (solve for left)
- widthValue = computeContentBoxLogicalWidth(width.calcValue(containerWidth));
- leftValue = availableSpace - (widthValue + right.calcValue(containerWidth));
- } else if (!leftIsAuto && widthIsAuto && !rightIsAuto) {
+ logicalWidthValue = computeContentBoxLogicalWidth(logicalWidth.calcValue(containerLogicalWidth));
+ logicalLeftValue = availableSpace - (logicalWidthValue + logicalRight.calcValue(containerLogicalWidth));
+ } else if (!logicalLeftIsAuto && logicalWidthIsAuto && !logicalRightIsAuto) {
// RULE 5: (solve for width)
- leftValue = left.calcValue(containerWidth);
- widthValue = availableSpace - (leftValue + right.calcValue(containerWidth));
- } else if (!leftIsAuto&& !widthIsAuto && rightIsAuto) {
+ logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
+ logicalWidthValue = availableSpace - (logicalLeftValue + logicalRight.calcValue(containerLogicalWidth));
+ } else if (!logicalLeftIsAuto && !logicalWidthIsAuto && logicalRightIsAuto) {
// RULE 6: (no need solve for right)
- leftValue = left.calcValue(containerWidth);
- widthValue = computeContentBoxLogicalWidth(width.calcValue(containerWidth));
+ logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
+ logicalWidthValue = computeContentBoxLogicalWidth(logicalWidth.calcValue(containerLogicalWidth));
}
}
// Use computed values to calculate the horizontal position.
- // FIXME: This hack is needed to calculate the xPos for a 'rtl' relatively
- // positioned, inline because right now, it is using the xPos
+ // FIXME: This hack is needed to calculate the logical left position for a 'rtl' relatively
+ // positioned, inline because right now, it is using the logical left position
// of the first line box when really it should use the last line box. When
// this is fixed elsewhere, this block should be removed.
if (containerBlock->isRenderInline() && !containerBlock->style()->isLeftToRightDirection()) {
@@ -2498,12 +2548,27 @@ void RenderBox::computePositionedLogicalWidthUsing(Length width, const RenderBox
InlineFlowBox* firstLine = flow->firstLineBox();
InlineFlowBox* lastLine = flow->lastLineBox();
if (firstLine && lastLine && firstLine != lastLine) {
- xPos = leftValue + marginLeftValue + lastLine->borderLogicalLeft() + (lastLine->x() - firstLine->x());
+ logicalLeftPos = logicalLeftValue + marginLogicalLeftValue + lastLine->borderLogicalLeft() + (lastLine->logicalLeft() - firstLine->logicalLeft());
return;
}
}
- xPos = leftValue + marginLeftValue + containerBlock->borderLeft();
+ logicalLeftPos = logicalLeftValue + marginLogicalLeftValue;
+ computeLogicalLeftPositionedOffset(logicalLeftPos, this, logicalWidthValue, containerBlock, containerLogicalWidth);
+}
+
+static void computeBlockStaticDistance(Length& logicalTop, Length& logicalBottom, const RenderBox* child, const RenderBoxModelObject* containerBlock)
+{
+ if (!logicalTop.isAuto() || !logicalBottom.isAuto())
+ return;
+
+ // FIXME: The static distance computation has not been patched for mixed writing modes.
+ int staticLogicalTop = child->layer()->staticBlockPosition() - containerBlock->borderBefore();
+ for (RenderObject* curr = child->parent(); curr && curr != containerBlock; curr = curr->parent()) {
+ if (curr->isBox() && !curr->isTableRow())
+ staticLogicalTop += toRenderBox(curr)->logicalTop();
+ }
+ logicalTop.setValue(Fixed, staticLogicalTop);
}
void RenderBox::computePositionedLogicalHeight()
@@ -2523,14 +2588,19 @@ void RenderBox::computePositionedLogicalHeight()
// We don't use containingBlock(), since we may be positioned by an enclosing relpositioned inline.
const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(container());
- const int containerHeight = containingBlockHeightForPositioned(containerBlock);
+ const int containerLogicalHeight = containingBlockLogicalHeightForPositioned(containerBlock);
- const int bordersPlusPadding = borderAndPaddingHeight();
- const Length marginTop = style()->marginTop();
- const Length marginBottom = style()->marginBottom();
- Length top = style()->top();
- Length bottom = style()->bottom();
+ bool isHorizontal = style()->isHorizontalWritingMode();
+ bool isFlipped = style()->isFlippedBlocksWritingMode();
+ const int bordersPlusPadding = borderAndPaddingLogicalHeight();
+ const Length marginBefore = style()->marginBefore();
+ const Length marginAfter = style()->marginAfter();
+ int& marginBeforeAlias = isHorizontal ? (isFlipped ? m_marginBottom : m_marginTop) : (isFlipped ? m_marginRight: m_marginLeft);
+ int& marginAfterAlias = isHorizontal ? (isFlipped ? m_marginTop : m_marginBottom) : (isFlipped ? m_marginLeft: m_marginRight);
+ Length logicalTop = style()->logicalTop();
+ Length logicalBottom = style()->logicalBottom();
+
/*---------------------------------------------------------------------------*\
* For the purposes of this section and the next, the term "static position"
* (of an element) refers, roughly, to the position an element would have had
@@ -2550,95 +2620,108 @@ void RenderBox::computePositionedLogicalHeight()
// see FIXME 2
// Calculate the static distance if needed.
- if (top.isAuto() && bottom.isAuto()) {
- // staticY should already have been set through layout of the parent()
- int staticTop = layer()->staticY() - containerBlock->borderTop();
- for (RenderObject* po = parent(); po && po != containerBlock; po = po->parent()) {
- if (po->isBox() && !po->isTableRow())
- staticTop += toRenderBox(po)->y();
- }
- top.setValue(Fixed, staticTop);
- }
-
+ computeBlockStaticDistance(logicalTop, logicalBottom, this, containerBlock);
- int h; // Needed to compute overflow.
- int y;
+ int logicalHeightResult; // Needed to compute overflow.
+ int logicalTopPos;
// Calculate constraint equation values for 'height' case.
- computePositionedLogicalHeightUsing(style()->height(), containerBlock, containerHeight, bordersPlusPadding,
- top, bottom, marginTop, marginBottom,
- h, m_marginTop, m_marginBottom, y);
- setY(y);
+ computePositionedLogicalHeightUsing(style()->logicalHeight(), containerBlock, containerLogicalHeight, bordersPlusPadding,
+ logicalTop, logicalBottom, marginBefore, marginAfter,
+ logicalHeightResult, marginBeforeAlias, marginAfterAlias, logicalTopPos);
+ setLogicalTop(logicalTopPos);
// Avoid doing any work in the common case (where the values of min-height and max-height are their defaults).
// see FIXME 3
// Calculate constraint equation values for 'max-height' case.
- if (!style()->maxHeight().isUndefined()) {
- int maxHeight;
- int maxMarginTop;
- int maxMarginBottom;
- int maxYPos;
-
- computePositionedLogicalHeightUsing(style()->maxHeight(), containerBlock, containerHeight, bordersPlusPadding,
- top, bottom, marginTop, marginBottom,
- maxHeight, maxMarginTop, maxMarginBottom, maxYPos);
-
- if (h > maxHeight) {
- h = maxHeight;
- m_marginTop = maxMarginTop;
- m_marginBottom = maxMarginBottom;
- m_frameRect.setY(maxYPos);
+ if (!style()->logicalMaxHeight().isUndefined()) {
+ int maxLogicalHeight;
+ int maxMarginBefore;
+ int maxMarginAfter;
+ int maxLogicalTopPos;
+
+ computePositionedLogicalHeightUsing(style()->logicalMaxHeight(), containerBlock, containerLogicalHeight, bordersPlusPadding,
+ logicalTop, logicalBottom, marginBefore, marginAfter,
+ maxLogicalHeight, maxMarginBefore, maxMarginAfter, maxLogicalTopPos);
+
+ if (logicalHeightResult > maxLogicalHeight) {
+ logicalHeightResult = maxLogicalHeight;
+ marginBeforeAlias = maxMarginBefore;
+ marginAfterAlias = maxMarginAfter;
+ setLogicalTop(maxLogicalTopPos);
}
}
// Calculate constraint equation values for 'min-height' case.
- if (!style()->minHeight().isZero()) {
- int minHeight;
- int minMarginTop;
- int minMarginBottom;
- int minYPos;
-
- computePositionedLogicalHeightUsing(style()->minHeight(), containerBlock, containerHeight, bordersPlusPadding,
- top, bottom, marginTop, marginBottom,
- minHeight, minMarginTop, minMarginBottom, minYPos);
-
- if (h < minHeight) {
- h = minHeight;
- m_marginTop = minMarginTop;
- m_marginBottom = minMarginBottom;
- m_frameRect.setY(minYPos);
+ if (!style()->logicalMinHeight().isZero()) {
+ int minLogicalHeight;
+ int minMarginBefore;
+ int minMarginAfter;
+ int minLogicalTopPos;
+
+ computePositionedLogicalHeightUsing(style()->logicalMinHeight(), containerBlock, containerLogicalHeight, bordersPlusPadding,
+ logicalTop, logicalBottom, marginBefore, marginAfter,
+ minLogicalHeight, minMarginBefore, minMarginAfter, minLogicalTopPos);
+
+ if (logicalHeightResult < minLogicalHeight) {
+ logicalHeightResult = minLogicalHeight;
+ marginBeforeAlias = minMarginBefore;
+ marginAfterAlias = minMarginAfter;
+ setLogicalTop(minLogicalTopPos);
}
}
// Set final height value.
- setHeight(h + bordersPlusPadding);
+ setLogicalHeight(logicalHeightResult + bordersPlusPadding);
}
-void RenderBox::computePositionedLogicalHeightUsing(Length h, const RenderBoxModelObject* containerBlock,
- const int containerHeight, const int bordersPlusPadding,
- const Length top, const Length bottom, const Length marginTop, const Length marginBottom,
- int& heightValue, int& marginTopValue, int& marginBottomValue, int& yPos)
+static void computeLogicalTopPositionedOffset(int& logicalTopPos, const RenderBox* child, int logicalHeightValue, const RenderBoxModelObject* containerBlock, int containerLogicalHeight)
+{
+ // Deal with differing writing modes here. Our offset needs to be in the containing block's coordinate space. If the containing block is flipped
+ // along this axis, then we need to flip the coordinate. This can only happen if the containing block is both a flipped mode and perpendicular to us.
+ if ((child->style()->isFlippedBlocksWritingMode() && child->style()->isHorizontalWritingMode() != containerBlock->style()->isHorizontalWritingMode())
+ || (child->style()->isFlippedBlocksWritingMode() != containerBlock->style()->isFlippedBlocksWritingMode() && child->style()->isHorizontalWritingMode() == containerBlock->style()->isHorizontalWritingMode()))
+ logicalTopPos = containerLogicalHeight - logicalHeightValue - logicalTopPos;
+
+ // Our offset is from the logical bottom edge in a flipped environment, e.g., right for vertical-rl and bottom for horizontal-bt.
+ if (containerBlock->style()->isFlippedBlocksWritingMode() && child->style()->isHorizontalWritingMode() == containerBlock->style()->isHorizontalWritingMode()) {
+ if (child->style()->isHorizontalWritingMode())
+ logicalTopPos += containerBlock->borderBottom();
+ else
+ logicalTopPos += containerBlock->borderRight();
+ } else {
+ if (child->style()->isHorizontalWritingMode())
+ logicalTopPos += containerBlock->borderTop();
+ else
+ logicalTopPos += containerBlock->borderLeft();
+ }
+}
+
+void RenderBox::computePositionedLogicalHeightUsing(Length logicalHeightLength, const RenderBoxModelObject* containerBlock,
+ int containerLogicalHeight, int bordersPlusPadding,
+ Length logicalTop, Length logicalBottom, Length marginBefore, Length marginAfter,
+ int& logicalHeightValue, int& marginBeforeValue, int& marginAfterValue, int& logicalTopPos)
{
// 'top' and 'bottom' cannot both be 'auto' because 'top would of been
// converted to the static position in computePositionedLogicalHeight()
- ASSERT(!(top.isAuto() && bottom.isAuto()));
+ ASSERT(!(logicalTop.isAuto() && logicalBottom.isAuto()));
- int contentHeight = height() - bordersPlusPadding;
+ int contentLogicalHeight = logicalHeight() - bordersPlusPadding;
- int topValue = 0;
+ int logicalTopValue = 0;
- bool heightIsAuto = h.isAuto();
- bool topIsAuto = top.isAuto();
- bool bottomIsAuto = bottom.isAuto();
+ bool logicalHeightIsAuto = logicalHeightLength.isAuto();
+ bool logicalTopIsAuto = logicalTop.isAuto();
+ bool logicalBottomIsAuto = logicalBottom.isAuto();
// Height is never unsolved for tables.
if (isTable()) {
- h.setValue(Fixed, contentHeight);
- heightIsAuto = false;
+ logicalHeightLength.setValue(Fixed, contentLogicalHeight);
+ logicalHeightIsAuto = false;
}
- if (!topIsAuto && !heightIsAuto && !bottomIsAuto) {
+ if (!logicalTopIsAuto && !logicalHeightIsAuto && !logicalBottomIsAuto) {
/*-----------------------------------------------------------------------*\
* If none of the three are 'auto': If both 'margin-top' and 'margin-
* bottom' are 'auto', solve the equation under the extra constraint that
@@ -2650,29 +2733,29 @@ void RenderBox::computePositionedLogicalHeightUsing(Length h, const RenderBoxMod
// NOTE: It is not necessary to solve for 'bottom' in the over constrained
// case because the value is not used for any further calculations.
- heightValue = computeContentBoxLogicalHeight(h.calcValue(containerHeight));
- topValue = top.calcValue(containerHeight);
+ logicalHeightValue = computeContentBoxLogicalHeight(logicalHeightLength.calcValue(containerLogicalHeight));
+ logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
- const int availableSpace = containerHeight - (topValue + heightValue + bottom.calcValue(containerHeight) + bordersPlusPadding);
+ const int availableSpace = containerLogicalHeight - (logicalTopValue + logicalHeightValue + logicalBottom.calcValue(containerLogicalHeight) + bordersPlusPadding);
// Margins are now the only unknown
- if (marginTop.isAuto() && marginBottom.isAuto()) {
+ if (marginBefore.isAuto() && marginAfter.isAuto()) {
// Both margins auto, solve for equality
// NOTE: This may result in negative values.
- marginTopValue = availableSpace / 2; // split the difference
- marginBottomValue = availableSpace - marginTopValue; // account for odd valued differences
- } else if (marginTop.isAuto()) {
+ marginBeforeValue = availableSpace / 2; // split the difference
+ marginAfterValue = availableSpace - marginBeforeValue; // account for odd valued differences
+ } else if (marginBefore.isAuto()) {
// Solve for top margin
- marginBottomValue = marginBottom.calcValue(containerHeight);
- marginTopValue = availableSpace - marginBottomValue;
- } else if (marginBottom.isAuto()) {
+ marginAfterValue = marginAfter.calcValue(containerLogicalHeight);
+ marginBeforeValue = availableSpace - marginAfterValue;
+ } else if (marginAfter.isAuto()) {
// Solve for bottom margin
- marginTopValue = marginTop.calcValue(containerHeight);
- marginBottomValue = availableSpace - marginTopValue;
+ marginBeforeValue = marginBefore.calcValue(containerLogicalHeight);
+ marginAfterValue = availableSpace - marginBeforeValue;
} else {
// Over-constrained, (no need solve for bottom)
- marginTopValue = marginTop.calcValue(containerHeight);
- marginBottomValue = marginBottom.calcValue(containerHeight);
+ marginBeforeValue = marginBefore.calcValue(containerLogicalHeight);
+ marginAfterValue = marginAfter.calcValue(containerLogicalHeight);
}
} else {
/*--------------------------------------------------------------------*\
@@ -2701,37 +2784,38 @@ void RenderBox::computePositionedLogicalHeightUsing(Length h, const RenderBoxMod
// because the value is not used for any further calculations.
// Calculate margins, 'auto' margins are ignored.
- marginTopValue = marginTop.calcMinValue(containerHeight);
- marginBottomValue = marginBottom.calcMinValue(containerHeight);
+ marginBeforeValue = marginBefore.calcMinValue(containerLogicalHeight);
+ marginAfterValue = marginAfter.calcMinValue(containerLogicalHeight);
- const int availableSpace = containerHeight - (marginTopValue + marginBottomValue + bordersPlusPadding);
+ const int availableSpace = containerLogicalHeight - (marginBeforeValue + marginAfterValue + bordersPlusPadding);
// Use rule/case that applies.
- if (topIsAuto && heightIsAuto && !bottomIsAuto) {
+ if (logicalTopIsAuto && logicalHeightIsAuto && !logicalBottomIsAuto) {
// RULE 1: (height is content based, solve of top)
- heightValue = contentHeight;
- topValue = availableSpace - (heightValue + bottom.calcValue(containerHeight));
- } else if (!topIsAuto && heightIsAuto && bottomIsAuto) {
+ logicalHeightValue = contentLogicalHeight;
+ logicalTopValue = availableSpace - (logicalHeightValue + logicalBottom.calcValue(containerLogicalHeight));
+ } else if (!logicalTopIsAuto && logicalHeightIsAuto && logicalBottomIsAuto) {
// RULE 3: (height is content based, no need solve of bottom)
- topValue = top.calcValue(containerHeight);
- heightValue = contentHeight;
- } else if (topIsAuto && !heightIsAuto && !bottomIsAuto) {
+ logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
+ logicalHeightValue = contentLogicalHeight;
+ } else if (logicalTopIsAuto && !logicalHeightIsAuto && !logicalBottomIsAuto) {
// RULE 4: (solve of top)
- heightValue = computeContentBoxLogicalHeight(h.calcValue(containerHeight));
- topValue = availableSpace - (heightValue + bottom.calcValue(containerHeight));
- } else if (!topIsAuto && heightIsAuto && !bottomIsAuto) {
+ logicalHeightValue = computeContentBoxLogicalHeight(logicalHeightLength.calcValue(containerLogicalHeight));
+ logicalTopValue = availableSpace - (logicalHeightValue + logicalBottom.calcValue(containerLogicalHeight));
+ } else if (!logicalTopIsAuto && logicalHeightIsAuto && !logicalBottomIsAuto) {
// RULE 5: (solve of height)
- topValue = top.calcValue(containerHeight);
- heightValue = max(0, availableSpace - (topValue + bottom.calcValue(containerHeight)));
- } else if (!topIsAuto && !heightIsAuto && bottomIsAuto) {
+ logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
+ logicalHeightValue = max(0, availableSpace - (logicalTopValue + logicalBottom.calcValue(containerLogicalHeight)));
+ } else if (!logicalTopIsAuto && !logicalHeightIsAuto && logicalBottomIsAuto) {
// RULE 6: (no need solve of bottom)
- heightValue = computeContentBoxLogicalHeight(h.calcValue(containerHeight));
- topValue = top.calcValue(containerHeight);
+ logicalHeightValue = computeContentBoxLogicalHeight(logicalHeightLength.calcValue(containerLogicalHeight));
+ logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
}
}
// Use computed values to calculate the vertical position.
- yPos = topValue + marginTopValue + containerBlock->borderTop();
+ logicalTopPos = logicalTopValue + marginBeforeValue;
+ computeLogicalTopPositionedOffset(logicalTopPos, this, logicalHeightValue, containerBlock, containerLogicalHeight);
}
void RenderBox::computePositionedLogicalWidthReplaced()
@@ -2746,18 +2830,20 @@ void RenderBox::computePositionedLogicalWidthReplaced()
// relative positioned inline.
const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(container());
- const int containerWidth = containingBlockWidthForPositioned(containerBlock);
+ const int containerLogicalWidth = containingBlockLogicalWidthForPositioned(containerBlock);
// To match WinIE, in quirks mode use the parent's 'direction' property
// instead of the the container block's.
TextDirection containerDirection = (document()->inQuirksMode()) ? parent()->style()->direction() : containerBlock->style()->direction();
// Variables to solve.
- Length left = style()->left();
- Length right = style()->right();
- Length marginLeft = style()->marginLeft();
- Length marginRight = style()->marginRight();
-
+ bool isHorizontal = style()->isHorizontalWritingMode();
+ Length logicalLeft = style()->logicalLeft();
+ Length logicalRight = style()->logicalRight();
+ Length marginLogicalLeft = isHorizontal ? style()->marginLeft() : style()->marginTop();
+ Length marginLogicalRight = isHorizontal ? style()->marginRight() : style()->marginBottom();
+ int& marginLogicalLeftAlias = isHorizontal ? m_marginLeft : m_marginTop;
+ int& marginLogicalRightAlias = isHorizontal ? m_marginRight : m_marginBottom;
/*-----------------------------------------------------------------------*\
* 1. The used value of 'width' is determined as for inline replaced
@@ -2766,8 +2852,8 @@ void RenderBox::computePositionedLogicalWidthReplaced()
// NOTE: This value of width is FINAL in that the min/max width calculations
// are dealt with in computeReplacedWidth(). This means that the steps to produce
// correct max/min in the non-replaced version, are not necessary.
- setWidth(computeReplacedLogicalWidth() + borderAndPaddingWidth());
- const int availableSpace = containerWidth - width();
+ setLogicalWidth(computeReplacedLogicalWidth() + borderAndPaddingLogicalWidth());
+ const int availableSpace = containerLogicalWidth - logicalWidth();
/*-----------------------------------------------------------------------*\
* 2. If both 'left' and 'right' have the value 'auto', then if 'direction'
@@ -2775,37 +2861,17 @@ void RenderBox::computePositionedLogicalWidthReplaced()
* else if 'direction' is 'rtl', set 'right' to the static position.
\*-----------------------------------------------------------------------*/
// see FIXME 2
- if (left.isAuto() && right.isAuto()) {
- // see FIXME 1
- if (containerDirection == LTR) {
- // 'staticX' should already have been set through layout of the parent.
- int staticPosition = layer()->staticX() - containerBlock->borderLeft();
- for (RenderObject* po = parent(); po && po != containerBlock; po = po->parent()) {
- if (po->isBox())
- staticPosition += toRenderBox(po)->x();
- }
- left.setValue(Fixed, staticPosition);
- } else {
- RenderObject* po = parent();
- // 'staticX' should already have been set through layout of the parent.
- int staticPosition = layer()->staticX() + containerWidth + containerBlock->borderRight();
- for ( ; po && po != containerBlock; po = po->parent()) {
- if (po->isBox())
- staticPosition += toRenderBox(po)->x();
- }
- right.setValue(Fixed, staticPosition);
- }
- }
+ computeInlineStaticDistance(logicalLeft, logicalRight, this, containerBlock, containerLogicalWidth, containerDirection);
/*-----------------------------------------------------------------------*\
* 3. If 'left' or 'right' are 'auto', replace any 'auto' on 'margin-left'
* or 'margin-right' with '0'.
\*-----------------------------------------------------------------------*/
- if (left.isAuto() || right.isAuto()) {
- if (marginLeft.isAuto())
- marginLeft.setValue(Fixed, 0);
- if (marginRight.isAuto())
- marginRight.setValue(Fixed, 0);
+ if (logicalLeft.isAuto() || logicalRight.isAuto()) {
+ if (marginLogicalLeft.isAuto())
+ marginLogicalLeft.setValue(Fixed, 0);
+ if (marginLogicalRight.isAuto())
+ marginLogicalRight.setValue(Fixed, 0);
}
/*-----------------------------------------------------------------------*\
@@ -2816,28 +2882,28 @@ void RenderBox::computePositionedLogicalWidthReplaced()
* ('rtl'), set 'margin-left' ('margin-right') to zero and solve for
* 'margin-right' ('margin-left').
\*-----------------------------------------------------------------------*/
- int leftValue = 0;
- int rightValue = 0;
+ int logicalLeftValue = 0;
+ int logicalRightValue = 0;
- if (marginLeft.isAuto() && marginRight.isAuto()) {
+ if (marginLogicalLeft.isAuto() && marginLogicalRight.isAuto()) {
// 'left' and 'right' cannot be 'auto' due to step 3
- ASSERT(!(left.isAuto() && right.isAuto()));
+ ASSERT(!(logicalLeft.isAuto() && logicalRight.isAuto()));
- leftValue = left.calcValue(containerWidth);
- rightValue = right.calcValue(containerWidth);
+ logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
+ logicalRightValue = logicalRight.calcValue(containerLogicalWidth);
- int difference = availableSpace - (leftValue + rightValue);
+ int difference = availableSpace - (logicalLeftValue + logicalRightValue);
if (difference > 0) {
- m_marginLeft = difference / 2; // split the difference
- m_marginRight = difference - m_marginLeft; // account for odd valued differences
+ marginLogicalLeftAlias = difference / 2; // split the difference
+ marginLogicalRightAlias = difference - marginLogicalLeftAlias; // account for odd valued differences
} else {
// see FIXME 1
if (containerDirection == LTR) {
- m_marginLeft = 0;
- m_marginRight = difference; // will be negative
+ marginLogicalLeftAlias = 0;
+ marginLogicalRightAlias = difference; // will be negative
} else {
- m_marginLeft = difference; // will be negative
- m_marginRight = 0;
+ marginLogicalLeftAlias = difference; // will be negative
+ marginLogicalRightAlias = 0;
}
}
@@ -2845,40 +2911,40 @@ void RenderBox::computePositionedLogicalWidthReplaced()
* 5. If at this point there is an 'auto' left, solve the equation for
* that value.
\*-----------------------------------------------------------------------*/
- } else if (left.isAuto()) {
- m_marginLeft = marginLeft.calcValue(containerWidth);
- m_marginRight = marginRight.calcValue(containerWidth);
- rightValue = right.calcValue(containerWidth);
+ } else if (logicalLeft.isAuto()) {
+ marginLogicalLeftAlias = marginLogicalLeft.calcValue(containerLogicalWidth);
+ marginLogicalRightAlias = marginLogicalRight.calcValue(containerLogicalWidth);
+ logicalRightValue = logicalRight.calcValue(containerLogicalWidth);
// Solve for 'left'
- leftValue = availableSpace - (rightValue + m_marginLeft + m_marginRight);
- } else if (right.isAuto()) {
- m_marginLeft = marginLeft.calcValue(containerWidth);
- m_marginRight = marginRight.calcValue(containerWidth);
- leftValue = left.calcValue(containerWidth);
+ logicalLeftValue = availableSpace - (logicalRightValue + marginLogicalLeftAlias + marginLogicalRightAlias);
+ } else if (logicalRight.isAuto()) {
+ marginLogicalLeftAlias = marginLogicalLeft.calcValue(containerLogicalWidth);
+ marginLogicalRightAlias = marginLogicalRight.calcValue(containerLogicalWidth);
+ logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
// Solve for 'right'
- rightValue = availableSpace - (leftValue + m_marginLeft + m_marginRight);
- } else if (marginLeft.isAuto()) {
- m_marginRight = marginRight.calcValue(containerWidth);
- leftValue = left.calcValue(containerWidth);
- rightValue = right.calcValue(containerWidth);
+ logicalRightValue = availableSpace - (logicalLeftValue + marginLogicalLeftAlias + marginLogicalRightAlias);
+ } else if (marginLogicalLeft.isAuto()) {
+ marginLogicalRightAlias = marginLogicalRight.calcValue(containerLogicalWidth);
+ logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
+ logicalRightValue = logicalRight.calcValue(containerLogicalWidth);
// Solve for 'margin-left'
- m_marginLeft = availableSpace - (leftValue + rightValue + m_marginRight);
- } else if (marginRight.isAuto()) {
- m_marginLeft = marginLeft.calcValue(containerWidth);
- leftValue = left.calcValue(containerWidth);
- rightValue = right.calcValue(containerWidth);
+ marginLogicalLeftAlias = availableSpace - (logicalLeftValue + logicalRightValue + marginLogicalRightAlias);
+ } else if (marginLogicalRight.isAuto()) {
+ marginLogicalLeftAlias = marginLogicalLeft.calcValue(containerLogicalWidth);
+ logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
+ logicalRightValue = logicalRight.calcValue(containerLogicalWidth);
// Solve for 'margin-right'
- m_marginRight = availableSpace - (leftValue + rightValue + m_marginLeft);
+ marginLogicalRightAlias = availableSpace - (logicalLeftValue + logicalRightValue + marginLogicalLeftAlias);
} else {
// Nothing is 'auto', just calculate the values.
- m_marginLeft = marginLeft.calcValue(containerWidth);
- m_marginRight = marginRight.calcValue(containerWidth);
- rightValue = right.calcValue(containerWidth);
- leftValue = left.calcValue(containerWidth);
+ marginLogicalLeftAlias = marginLogicalLeft.calcValue(containerLogicalWidth);
+ marginLogicalRightAlias = marginLogicalRight.calcValue(containerLogicalWidth);
+ logicalRightValue = logicalRight.calcValue(containerLogicalWidth);
+ logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
}
/*-----------------------------------------------------------------------*\
@@ -2889,14 +2955,17 @@ void RenderBox::computePositionedLogicalWidthReplaced()
\*-----------------------------------------------------------------------*/
// NOTE: It is not necessary to solve for 'right' when the direction is
// LTR because the value is not used.
- int totalWidth = width() + leftValue + rightValue + m_marginLeft + m_marginRight;
- if (totalWidth > containerWidth && (containerDirection == RTL))
- leftValue = containerWidth - (totalWidth - leftValue);
+ int totalLogicalWidth = logicalWidth() + logicalLeftValue + logicalRightValue + marginLogicalLeftAlias + marginLogicalRightAlias;
+ if (totalLogicalWidth > containerLogicalWidth && (containerDirection == RTL))
+ logicalLeftValue = containerLogicalWidth - (totalLogicalWidth - logicalLeftValue);
+ // FIXME: Deal with differing writing modes here. Our offset needs to be in the containing block's coordinate space, so that
+ // can make the result here rather complicated to compute.
+
// Use computed values to calculate the horizontal position.
- // FIXME: This hack is needed to calculate the xPos for a 'rtl' relatively
- // positioned, inline containing block because right now, it is using the xPos
+ // FIXME: This hack is needed to calculate the logical left position for a 'rtl' relatively
+ // positioned, inline containing block because right now, it is using the logical left position
// of the first line box when really it should use the last line box. When
// this is fixed elsewhere, this block should be removed.
if (containerBlock->isRenderInline() && !containerBlock->style()->isLeftToRightDirection()) {
@@ -2904,12 +2973,14 @@ void RenderBox::computePositionedLogicalWidthReplaced()
InlineFlowBox* firstLine = flow->firstLineBox();
InlineFlowBox* lastLine = flow->lastLineBox();
if (firstLine && lastLine && firstLine != lastLine) {
- m_frameRect.setX(leftValue + m_marginLeft + lastLine->borderLogicalLeft() + (lastLine->x() - firstLine->x()));
+ setLogicalLeft(logicalLeftValue + marginLogicalLeftAlias + lastLine->borderLogicalLeft() + (lastLine->logicalLeft() - firstLine->logicalLeft()));
return;
}
}
- m_frameRect.setX(leftValue + m_marginLeft + containerBlock->borderLeft());
+ int logicalLeftPos = logicalLeftValue + marginLogicalLeftAlias;
+ computeLogicalLeftPositionedOffset(logicalLeftPos, this, logicalWidth(), containerBlock, containerLogicalWidth);
+ setLogicalLeft(logicalLeftPos);
}
void RenderBox::computePositionedLogicalHeightReplaced()
@@ -2923,14 +2994,18 @@ void RenderBox::computePositionedLogicalHeightReplaced()
// We don't use containingBlock(), since we may be positioned by an enclosing relpositioned inline.
const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(container());
- const int containerHeight = containingBlockHeightForPositioned(containerBlock);
+ const int containerLogicalHeight = containingBlockLogicalHeightForPositioned(containerBlock);
// Variables to solve.
- Length top = style()->top();
- Length bottom = style()->bottom();
- Length marginTop = style()->marginTop();
- Length marginBottom = style()->marginBottom();
+ bool isHorizontal = style()->isHorizontalWritingMode();
+ bool isFlipped = style()->isFlippedBlocksWritingMode();
+ Length marginBefore = style()->marginBefore();
+ Length marginAfter = style()->marginAfter();
+ int& marginBeforeAlias = isHorizontal ? (isFlipped ? m_marginBottom : m_marginTop) : (isFlipped ? m_marginRight: m_marginLeft);
+ int& marginAfterAlias = isHorizontal ? (isFlipped ? m_marginTop : m_marginBottom) : (isFlipped ? m_marginLeft: m_marginRight);
+ Length logicalTop = style()->logicalTop();
+ Length logicalBottom = style()->logicalBottom();
/*-----------------------------------------------------------------------*\
* 1. The used value of 'height' is determined as for inline replaced
@@ -2939,23 +3014,15 @@ void RenderBox::computePositionedLogicalHeightReplaced()
// NOTE: This value of height is FINAL in that the min/max height calculations
// are dealt with in computeReplacedHeight(). This means that the steps to produce
// correct max/min in the non-replaced version, are not necessary.
- setHeight(computeReplacedLogicalHeight() + borderAndPaddingHeight());
- const int availableSpace = containerHeight - height();
+ setLogicalHeight(computeReplacedLogicalHeight() + borderAndPaddingLogicalHeight());
+ const int availableSpace = containerLogicalHeight - logicalHeight();
/*-----------------------------------------------------------------------*\
* 2. If both 'top' and 'bottom' have the value 'auto', replace 'top'
* with the element's static position.
\*-----------------------------------------------------------------------*/
// see FIXME 2
- if (top.isAuto() && bottom.isAuto()) {
- // staticY should already have been set through layout of the parent().
- int staticTop = layer()->staticY() - containerBlock->borderTop();
- for (RenderObject* po = parent(); po && po != containerBlock; po = po->parent()) {
- if (po->isBox() && !po->isTableRow())
- staticTop += toRenderBox(po)->y();
- }
- top.setValue(Fixed, staticTop);
- }
+ computeBlockStaticDistance(logicalTop, logicalBottom, this, containerBlock);
/*-----------------------------------------------------------------------*\
* 3. If 'bottom' is 'auto', replace any 'auto' on 'margin-top' or
@@ -2963,11 +3030,11 @@ void RenderBox::computePositionedLogicalHeightReplaced()
\*-----------------------------------------------------------------------*/
// FIXME: The spec. says that this step should only be taken when bottom is
// auto, but if only top is auto, this makes step 4 impossible.
- if (top.isAuto() || bottom.isAuto()) {
- if (marginTop.isAuto())
- marginTop.setValue(Fixed, 0);
- if (marginBottom.isAuto())
- marginBottom.setValue(Fixed, 0);
+ if (logicalTop.isAuto() || logicalBottom.isAuto()) {
+ if (marginBefore.isAuto())
+ marginBefore.setValue(Fixed, 0);
+ if (marginAfter.isAuto())
+ marginAfter.setValue(Fixed, 0);
}
/*-----------------------------------------------------------------------*\
@@ -2975,59 +3042,59 @@ void RenderBox::computePositionedLogicalHeightReplaced()
* 'auto', solve the equation under the extra constraint that the two
* margins must get equal values.
\*-----------------------------------------------------------------------*/
- int topValue = 0;
- int bottomValue = 0;
+ int logicalTopValue = 0;
+ int logicalBottomValue = 0;
- if (marginTop.isAuto() && marginBottom.isAuto()) {
+ if (marginBefore.isAuto() && marginAfter.isAuto()) {
// 'top' and 'bottom' cannot be 'auto' due to step 2 and 3 combined.
- ASSERT(!(top.isAuto() || bottom.isAuto()));
+ ASSERT(!(logicalTop.isAuto() || logicalBottom.isAuto()));
- topValue = top.calcValue(containerHeight);
- bottomValue = bottom.calcValue(containerHeight);
+ logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
+ logicalBottomValue = logicalBottom.calcValue(containerLogicalHeight);
- int difference = availableSpace - (topValue + bottomValue);
+ int difference = availableSpace - (logicalTopValue + logicalBottomValue);
// NOTE: This may result in negative values.
- m_marginTop = difference / 2; // split the difference
- m_marginBottom = difference - m_marginTop; // account for odd valued differences
+ marginBeforeAlias = difference / 2; // split the difference
+ marginAfterAlias = difference - marginBeforeAlias; // account for odd valued differences
/*-----------------------------------------------------------------------*\
* 5. If at this point there is only one 'auto' left, solve the equation
* for that value.
\*-----------------------------------------------------------------------*/
- } else if (top.isAuto()) {
- m_marginTop = marginTop.calcValue(containerHeight);
- m_marginBottom = marginBottom.calcValue(containerHeight);
- bottomValue = bottom.calcValue(containerHeight);
+ } else if (logicalTop.isAuto()) {
+ marginBeforeAlias = marginBefore.calcValue(containerLogicalHeight);
+ marginAfterAlias = marginAfter.calcValue(containerLogicalHeight);
+ logicalBottomValue = logicalBottom.calcValue(containerLogicalHeight);
// Solve for 'top'
- topValue = availableSpace - (bottomValue + m_marginTop + m_marginBottom);
- } else if (bottom.isAuto()) {
- m_marginTop = marginTop.calcValue(containerHeight);
- m_marginBottom = marginBottom.calcValue(containerHeight);
- topValue = top.calcValue(containerHeight);
+ logicalTopValue = availableSpace - (logicalBottomValue + marginBeforeAlias + marginAfterAlias);
+ } else if (logicalBottom.isAuto()) {
+ marginBeforeAlias = marginBefore.calcValue(containerLogicalHeight);
+ marginAfterAlias = marginAfter.calcValue(containerLogicalHeight);
+ logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
// Solve for 'bottom'
// NOTE: It is not necessary to solve for 'bottom' because we don't ever
// use the value.
- } else if (marginTop.isAuto()) {
- m_marginBottom = marginBottom.calcValue(containerHeight);
- topValue = top.calcValue(containerHeight);
- bottomValue = bottom.calcValue(containerHeight);
+ } else if (marginBefore.isAuto()) {
+ marginAfterAlias = marginAfter.calcValue(containerLogicalHeight);
+ logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
+ logicalBottomValue = logicalBottom.calcValue(containerLogicalHeight);
// Solve for 'margin-top'
- m_marginTop = availableSpace - (topValue + bottomValue + m_marginBottom);
- } else if (marginBottom.isAuto()) {
- m_marginTop = marginTop.calcValue(containerHeight);
- topValue = top.calcValue(containerHeight);
- bottomValue = bottom.calcValue(containerHeight);
+ marginBeforeAlias = availableSpace - (logicalTopValue + logicalBottomValue + marginAfterAlias);
+ } else if (marginAfter.isAuto()) {
+ marginBeforeAlias = marginBefore.calcValue(containerLogicalHeight);
+ logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
+ logicalBottomValue = logicalBottom.calcValue(containerLogicalHeight);
// Solve for 'margin-bottom'
- m_marginBottom = availableSpace - (topValue + bottomValue + m_marginTop);
+ marginAfterAlias = availableSpace - (logicalTopValue + logicalBottomValue + marginBeforeAlias);
} else {
// Nothing is 'auto', just calculate the values.
- m_marginTop = marginTop.calcValue(containerHeight);
- m_marginBottom = marginBottom.calcValue(containerHeight);
- topValue = top.calcValue(containerHeight);
+ marginBeforeAlias = marginBefore.calcValue(containerLogicalHeight);
+ marginAfterAlias = marginAfter.calcValue(containerLogicalHeight);
+ logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
// NOTE: It is not necessary to solve for 'bottom' because we don't ever
// use the value.
}
@@ -3041,7 +3108,9 @@ void RenderBox::computePositionedLogicalHeightReplaced()
// or not.
// Use computed values to calculate the vertical position.
- m_frameRect.setY(topValue + m_marginTop + containerBlock->borderTop());
+ int logicalTopPos = logicalTopValue + marginBeforeAlias;
+ computeLogicalTopPositionedOffset(logicalTopPos, this, logicalHeight(), containerBlock, containerLogicalHeight);
+ setLogicalTop(logicalTopPos);
}
IntRect RenderBox::localCaretRect(InlineBox* box, int caretOffset, int* extraWidthToEndOfLine)
@@ -3439,13 +3508,32 @@ IntSize RenderBox::flipForWritingMode(const IntSize& offset) const
return style()->isHorizontalWritingMode() ? IntSize(offset.width(), height() - offset.height()) : IntSize(width() - offset.width(), offset.height());
}
+FloatPoint RenderBox::flipForWritingMode(const FloatPoint& position) const
+{
+ if (!style()->isFlippedBlocksWritingMode())
+ return position;
+ return style()->isHorizontalWritingMode() ? FloatPoint(position.x(), height() - position.y()) : FloatPoint(width() - position.x(), position.y());
+}
+
+void RenderBox::flipForWritingMode(FloatRect& rect) const
+{
+ if (!style()->isFlippedBlocksWritingMode())
+ return;
+
+ if (style()->isHorizontalWritingMode())
+ rect.setY(height() - rect.maxY());
+ else
+ rect.setX(width() - rect.maxX());
+}
+
IntSize RenderBox::locationOffsetIncludingFlipping() const
{
- if (!parent() || !parent()->isBox())
+ RenderBlock* containerBlock = containingBlock();
+ if (!containerBlock || containerBlock == this)
return locationOffset();
IntRect rect(frameRect());
- parentBox()->flipForWritingMode(rect);
+ containerBlock->flipForWritingMode(rect); // FIXME: This is wrong if we are an absolutely positioned object enclosed by a relative-positioned inline.
return IntSize(rect.x(), rect.y());
}
diff --git a/Source/WebCore/rendering/RenderBox.h b/Source/WebCore/rendering/RenderBox.h
index 7241ed1..f0bd30d 100644
--- a/Source/WebCore/rendering/RenderBox.h
+++ b/Source/WebCore/rendering/RenderBox.h
@@ -176,7 +176,9 @@ public:
int clientTop() const { return borderTop(); }
int clientWidth() const;
int clientHeight() const;
- int clientLogicalBottom() const { return borderBefore() + (style()->isHorizontalWritingMode() ? clientHeight() : clientWidth()); }
+ int clientLogicalWidth() const { return style()->isHorizontalWritingMode() ? clientWidth() : clientHeight(); }
+ int clientLogicalHeight() const { return style()->isHorizontalWritingMode() ? clientHeight() : clientWidth(); }
+ int clientLogicalBottom() const { return borderBefore() + clientLogicalHeight(); }
IntRect clientBoxRect() const { return IntRect(clientLeft(), clientTop(), clientWidth(), clientHeight()); }
// scrollWidth/scrollHeight will be the same as clientWidth/clientHeight unless the
@@ -385,6 +387,8 @@ public:
IntPoint flipForWritingModeIncludingColumns(const IntPoint&) const;
IntSize flipForWritingMode(const IntSize&) const;
void flipForWritingMode(IntRect&) const;
+ FloatPoint flipForWritingMode(const FloatPoint&) const;
+ void flipForWritingMode(FloatRect&) const;
IntSize locationOffsetIncludingFlipping() const;
IntRect logicalVisualOverflowRectForPropagation(RenderStyle*) const;
@@ -426,18 +430,18 @@ private:
// Returns true if we did a full repaint
bool repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer* layers, bool drawingBackground);
- int containingBlockWidthForPositioned(const RenderBoxModelObject* containingBlock) const;
- int containingBlockHeightForPositioned(const RenderBoxModelObject* containingBlock) const;
+ int containingBlockLogicalWidthForPositioned(const RenderBoxModelObject* containingBlock, bool checkForPerpendicularWritingMode = true) const;
+ int containingBlockLogicalHeightForPositioned(const RenderBoxModelObject* containingBlock, bool checkForPerpendicularWritingMode = true) const;
void computePositionedLogicalHeight();
- void computePositionedLogicalWidthUsing(Length width, const RenderBoxModelObject* cb, TextDirection containerDirection,
- int containerWidth, int bordersPlusPadding,
- Length left, Length right, Length marginLeft, Length marginRight,
- int& widthValue, int& marginLeftValue, int& marginRightValue, int& xPos);
- void computePositionedLogicalHeightUsing(Length height, const RenderBoxModelObject* cb,
- int containerHeight, int bordersPlusPadding,
- Length top, Length bottom, Length marginTop, Length marginBottom,
- int& heightValue, int& marginTopValue, int& marginBottomValue, int& yPos);
+ void computePositionedLogicalWidthUsing(Length logicalWidth, const RenderBoxModelObject* containerBlock, TextDirection containerDirection,
+ int containerLogicalWidth, int bordersPlusPadding,
+ Length logicalLeft, Length logicalRight, Length marginLogicalLeft, Length marginLogicalRight,
+ int& logicalWidthValue, int& marginLogicalLeftValue, int& marginLogicalRightValue, int& logicalLeftPos);
+ void computePositionedLogicalHeightUsing(Length logicalHeight, const RenderBoxModelObject* containerBlock,
+ int containerLogicalHeight, int bordersPlusPadding,
+ Length logicalTop, Length logicalBottom, Length marginLogicalTop, Length marginLogicalBottom,
+ int& logicalHeightValue, int& marginLogicalTopValue, int& marginLogicalBottomValue, int& logicalTopPos);
void computePositionedLogicalHeightReplaced();
void computePositionedLogicalWidthReplaced();
diff --git a/Source/WebCore/rendering/RenderBoxModelObject.cpp b/Source/WebCore/rendering/RenderBoxModelObject.cpp
index ffbecce..eec048e 100644
--- a/Source/WebCore/rendering/RenderBoxModelObject.cpp
+++ b/Source/WebCore/rendering/RenderBoxModelObject.cpp
@@ -1593,7 +1593,7 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
{
// FIXME: Deal with border-image. Would be great to use border-image as a mask.
- if (context->paintingDisabled())
+ if (context->paintingDisabled() || !s->boxShadow())
return;
RoundedIntRect border(tx, ty, w, h);
diff --git a/Source/WebCore/rendering/RenderBoxModelObject.h b/Source/WebCore/rendering/RenderBoxModelObject.h
index f6bcb94..2e0bdda 100644
--- a/Source/WebCore/rendering/RenderBoxModelObject.h
+++ b/Source/WebCore/rendering/RenderBoxModelObject.h
@@ -89,6 +89,11 @@ public:
int borderAndPaddingWidth() const { return borderLeft() + borderRight() + paddingLeft() + paddingRight(); }
int borderAndPaddingLogicalHeight() const { return borderBefore() + borderAfter() + paddingBefore() + paddingAfter(); }
int borderAndPaddingLogicalWidth() const { return borderStart() + borderEnd() + paddingStart() + paddingEnd(); }
+ int borderAndPaddingLogicalLeft() const { return style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop(); }
+
+ int borderAndPaddingStart() const { return borderStart() + paddingStart(); }
+ int borderLogicalLeft() const { return style()->isHorizontalWritingMode() ? borderLeft() : borderTop(); }
+ int borderLogicalRight() const { return style()->isHorizontalWritingMode() ? borderRight() : borderBottom(); }
virtual int marginTop() const = 0;
virtual int marginBottom() const = 0;
diff --git a/Source/WebCore/rendering/RenderCombineText.cpp b/Source/WebCore/rendering/RenderCombineText.cpp
index 1b20bd8..250ec9b 100644
--- a/Source/WebCore/rendering/RenderCombineText.cpp
+++ b/Source/WebCore/rendering/RenderCombineText.cpp
@@ -52,7 +52,7 @@ void RenderCombineText::setTextInternal(PassRefPtr<StringImpl> text)
m_needsFontUpdate = true;
}
-unsigned RenderCombineText::width(unsigned from, unsigned length, const Font& font, int xPosition, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
+float RenderCombineText::width(unsigned from, unsigned length, const Font& font, float xPosition, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
{
if (!characters())
return 0;
@@ -63,7 +63,7 @@ unsigned RenderCombineText::width(unsigned from, unsigned length, const Font& fo
return RenderText::width(from, length, font, xPosition, fallbackFonts, glyphOverflow);
}
-void RenderCombineText::adjustTextOrigin(IntPoint& textOrigin, const IntRect& boxRect) const
+void RenderCombineText::adjustTextOrigin(FloatPoint& textOrigin, const FloatRect& boxRect) const
{
if (m_isCombined)
textOrigin.move(boxRect.height() / 2 - ceilf(m_combinedTextWidth) / 2, style()->font().pixelSize());
@@ -98,7 +98,7 @@ void RenderCombineText::combineText()
bool shouldUpdateFont = false;
description.setOrientation(Horizontal); // We are going to draw combined text horizontally.
- m_combinedTextWidth = style()->font().floatWidth(run);
+ m_combinedTextWidth = style()->font().width(run);
m_isCombined = m_combinedTextWidth <= emWidth;
if (m_isCombined)
@@ -110,7 +110,7 @@ void RenderCombineText::combineText()
description.setWidthVariant(widthVariants[i]);
Font compressedFont = Font(description, style()->font().letterSpacing(), style()->font().wordSpacing());
compressedFont.update(style()->font().fontSelector());
- float runWidth = compressedFont.floatWidth(run);
+ float runWidth = compressedFont.width(run);
if (runWidth <= emWidth) {
m_combinedTextWidth = runWidth;
m_isCombined = true;
diff --git a/Source/WebCore/rendering/RenderCombineText.h b/Source/WebCore/rendering/RenderCombineText.h
index 582cbd6..3484ab7 100644
--- a/Source/WebCore/rendering/RenderCombineText.h
+++ b/Source/WebCore/rendering/RenderCombineText.h
@@ -30,13 +30,13 @@ public:
RenderCombineText(Node*, PassRefPtr<StringImpl>);
void combineText();
- void adjustTextOrigin(IntPoint& textOrigin, const IntRect& boxRect) const;
+ void adjustTextOrigin(FloatPoint& textOrigin, const FloatRect& boxRect) const;
void charactersToRender(int start, const UChar*& characters, int& length) const;
bool isCombined() const { return m_isCombined; }
- int combinedTextWidth(const Font& font) const { return font.size(); }
+ float combinedTextWidth(const Font& font) const { return font.size(); }
private:
- virtual unsigned width(unsigned from, unsigned length, const Font&, int xPosition, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
+ virtual float width(unsigned from, unsigned length, const Font&, float xPosition, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
virtual const char* renderName() const { return "RenderCombineText"; }
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
virtual void setTextInternal(PassRefPtr<StringImpl>);
diff --git a/Source/WebCore/rendering/RenderCounter.cpp b/Source/WebCore/rendering/RenderCounter.cpp
index fbd5545..f4a8736 100644
--- a/Source/WebCore/rendering/RenderCounter.cpp
+++ b/Source/WebCore/rendering/RenderCounter.cpp
@@ -385,7 +385,7 @@ static bool findPlaceForCounter(RenderObject* counterOwner, const AtomicString&
if (previousSibling)
currentRenderer = previousSiblingOrParent(currentRenderer);
else
- currentRenderer = currentRenderer->previousInPreOrder();
+ currentRenderer = previousInPreOrder(currentRenderer);
}
return false;
}
@@ -493,7 +493,7 @@ PassRefPtr<StringImpl> RenderCounter::originalText() const
return text.impl();
}
-void RenderCounter::computePreferredLogicalWidths(int lead)
+void RenderCounter::computePreferredLogicalWidths(float lead)
{
setTextInternal(originalText());
RenderText::computePreferredLogicalWidths(lead);
diff --git a/Source/WebCore/rendering/RenderCounter.h b/Source/WebCore/rendering/RenderCounter.h
index de0ee1b..35ffc35 100644
--- a/Source/WebCore/rendering/RenderCounter.h
+++ b/Source/WebCore/rendering/RenderCounter.h
@@ -50,7 +50,7 @@ private:
virtual bool isCounter() const;
virtual PassRefPtr<StringImpl> originalText() const;
- virtual void computePreferredLogicalWidths(int leadWidth);
+ virtual void computePreferredLogicalWidths(float leadWidth);
CounterContent m_counter;
mutable CounterNode* m_counterNode;
diff --git a/Source/WebCore/rendering/RenderEmbeddedObject.cpp b/Source/WebCore/rendering/RenderEmbeddedObject.cpp
index cdd6c55..3561fe0 100644
--- a/Source/WebCore/rendering/RenderEmbeddedObject.cpp
+++ b/Source/WebCore/rendering/RenderEmbeddedObject.cpp
@@ -199,8 +199,7 @@ bool RenderEmbeddedObject::getReplacementTextGeometry(int tx, int ty, FloatRect&
font.update(0);
run = TextRun(m_replacementText.characters(), m_replacementText.length());
- run.disableRoundingHacks();
- textWidth = font.floatWidth(run);
+ textWidth = font.width(run);
replacementTextRect.setSize(FloatSize(textWidth + replacementTextRoundedRectLeftRightTextMargin * 2, replacementTextRoundedRectHeight));
float x = (contentRect.size().width() / 2 - replacementTextRect.size().width() / 2) + contentRect.location().x();
diff --git a/Source/WebCore/rendering/RenderFileUploadControl.cpp b/Source/WebCore/rendering/RenderFileUploadControl.cpp
index f72edad..b50b2ad 100644
--- a/Source/WebCore/rendering/RenderFileUploadControl.cpp
+++ b/Source/WebCore/rendering/RenderFileUploadControl.cpp
@@ -273,7 +273,7 @@ void RenderFileUploadControl::computePreferredLogicalWidths()
// Figure out how big the filename space needs to be for a given number of characters
// (using "0" as the nominal character).
const UChar ch = '0';
- float charWidth = style()->font().floatWidth(TextRun(&ch, 1, false, 0, 0, TextRun::AllowTrailingExpansion, false, false, false));
+ float charWidth = style()->font().width(TextRun(&ch, 1, false, 0, 0, TextRun::AllowTrailingExpansion, false));
m_maxPreferredLogicalWidth = (int)ceilf(charWidth * defaultWidthNumChars);
}
diff --git a/Source/WebCore/rendering/RenderFlexibleBox.cpp b/Source/WebCore/rendering/RenderFlexibleBox.cpp
index 9ab3c3f..8241dcd 100644
--- a/Source/WebCore/rendering/RenderFlexibleBox.cpp
+++ b/Source/WebCore/rendering/RenderFlexibleBox.cpp
@@ -420,15 +420,12 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
while (child) {
if (child->isPositioned()) {
child->containingBlock()->insertPositionedObject(child);
- if (child->style()->hasStaticX()) {
- if (style()->isLeftToRightDirection())
- child->layer()->setStaticX(xPos);
- else child->layer()->setStaticX(width() - xPos);
- }
- if (child->style()->hasStaticY()) {
- RenderLayer* childLayer = child->layer();
- if (childLayer->staticY() != yPos) {
- child->layer()->setStaticY(yPos);
+ RenderLayer* childLayer = child->layer();
+ if (child->style()->hasStaticInlinePosition(style()->isHorizontalWritingMode()))
+ childLayer->setStaticInlinePosition(xPos);
+ if (child->style()->hasStaticBlockPosition(style()->isHorizontalWritingMode())) {
+ if (childLayer->staticBlockPosition() != yPos) {
+ childLayer->setStaticBlockPosition(yPos);
child->setChildNeedsLayout(true, false);
}
}
@@ -686,16 +683,16 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
if (child->isPositioned()) {
child->containingBlock()->insertPositionedObject(child);
- if (child->style()->hasStaticX()) {
+ RenderLayer* childLayer = child->layer();
+ if (child->style()->hasStaticInlinePosition(style()->isHorizontalWritingMode())) {
if (style()->isLeftToRightDirection())
- child->layer()->setStaticX(borderLeft()+paddingLeft());
+ childLayer->setStaticInlinePosition(borderLeft() + paddingLeft());
else
- child->layer()->setStaticX(borderRight()+paddingRight());
+ childLayer->setStaticInlinePosition(borderRight() + paddingRight());
}
- if (child->style()->hasStaticY()) {
- RenderLayer* childLayer = child->layer();
- if (childLayer->staticY() != height()) {
- child->layer()->setStaticY(height());
+ if (child->style()->hasStaticBlockPosition(style()->isHorizontalWritingMode())) {
+ if (childLayer->staticBlockPosition() != height()) {
+ childLayer->setStaticBlockPosition(height());
child->setChildNeedsLayout(true, false);
}
}
@@ -1012,7 +1009,7 @@ void RenderFlexibleBox::applyLineClamp(FlexBoxIterator& iterator, bool relayoutC
int blockLeftEdge = destBlock->logicalLeftOffsetForLine(lastVisibleLine->y(), false);
int blockEdge = leftToRight ? blockRightEdge : blockLeftEdge;
- if (!lastVisibleLine->canAccommodateEllipsis(leftToRight, blockEdge, lastVisibleLine->x() + lastVisibleLine->logicalWidth(), totalWidth))
+ if (!lastVisibleLine->lineCanAccommodateEllipsis(leftToRight, blockEdge, lastVisibleLine->x() + lastVisibleLine->logicalWidth(), totalWidth))
continue;
// Let the truncation code kick in.
diff --git a/Source/WebCore/rendering/RenderImage.cpp b/Source/WebCore/rendering/RenderImage.cpp
index 7369f4e..9500aeb 100644
--- a/Source/WebCore/rendering/RenderImage.cpp
+++ b/Source/WebCore/rendering/RenderImage.cpp
@@ -85,7 +85,7 @@ static const unsigned short paddingHeight = 4;
// Alt text is restricted to this maximum size, in pixels. These are
// signed integers because they are compared with other signed values.
-static const int maxAltTextWidth = 1024;
+static const float maxAltTextWidth = 1024;
static const int maxAltTextHeight = 256;
IntSize RenderImage::imageSizeForError(CachedImage* newImage) const
@@ -449,7 +449,6 @@ bool RenderImage::isLogicalWidthSpecified() const
return true;
case Auto:
case Relative: // FIXME: Shouldn't this case return true?
- case Static:
case Intrinsic:
case MinIntrinsic:
return false;
@@ -466,7 +465,6 @@ bool RenderImage::isLogicalHeightSpecified() const
return true;
case Auto:
case Relative: // FIXME: Shouldn't this case return true?
- case Static:
case Intrinsic:
case MinIntrinsic:
return false;
diff --git a/Source/WebCore/rendering/RenderInline.cpp b/Source/WebCore/rendering/RenderInline.cpp
index 3768774..234d63c 100644
--- a/Source/WebCore/rendering/RenderInline.cpp
+++ b/Source/WebCore/rendering/RenderInline.cpp
@@ -53,6 +53,19 @@ RenderInline::RenderInline(Node* node)
void RenderInline::destroy()
{
+#ifndef NDEBUG
+ // Make sure we do not retain "this" in the continuation outline table map of our containing blocks.
+ if (parent() && style()->visibility() == VISIBLE && hasOutline()) {
+ bool containingBlockPaintsContinuationOutline = continuation() || isInlineElementContinuation();
+ if (containingBlockPaintsContinuationOutline) {
+ if (RenderBlock* cb = containingBlock()) {
+ if (RenderBlock* cbCb = cb->containingBlock())
+ ASSERT(!cbCb->paintsContinuationOutline(this));
+ }
+ }
+ }
+#endif
+
// Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
// properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
children()->destroyLeftoverChildren();
@@ -559,8 +572,8 @@ IntRect RenderInline::linesBoundingBox() const
ASSERT(!firstLineBox() == !lastLineBox()); // Either both are null or both exist.
if (firstLineBox() && lastLineBox()) {
// Return the width of the minimal left side and the maximal right side.
- int logicalLeftSide = 0;
- int logicalRightSide = 0;
+ float logicalLeftSide = 0;
+ float logicalRightSide = 0;
for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
if (curr == firstLineBox() || curr->logicalLeft() < logicalLeftSide)
logicalLeftSide = curr->logicalLeft();
@@ -570,11 +583,11 @@ IntRect RenderInline::linesBoundingBox() const
bool isHorizontal = style()->isHorizontalWritingMode();
- int x = isHorizontal ? logicalLeftSide : firstLineBox()->x();
- int y = isHorizontal ? firstLineBox()->y() : logicalLeftSide;
- int width = isHorizontal ? logicalRightSide - logicalLeftSide : lastLineBox()->logicalBottom() - x;
- int height = isHorizontal ? lastLineBox()->logicalBottom() - y : logicalRightSide - logicalLeftSide;
- result = IntRect(x, y, width, height);
+ float x = isHorizontal ? logicalLeftSide : firstLineBox()->x();
+ float y = isHorizontal ? firstLineBox()->y() : logicalLeftSide;
+ float width = isHorizontal ? logicalRightSide - logicalLeftSide : lastLineBox()->logicalBottom() - x;
+ float height = isHorizontal ? lastLineBox()->logicalBottom() - y : logicalRightSide - logicalLeftSide;
+ result = enclosingIntRect(FloatRect(x, y, width, height));
}
return result;
@@ -586,20 +599,20 @@ IntRect RenderInline::linesVisualOverflowBoundingBox() const
return IntRect();
// Return the width of the minimal left side and the maximal right side.
- int logicalLeftSide = numeric_limits<int>::max();
- int logicalRightSide = numeric_limits<int>::min();
+ float logicalLeftSide = numeric_limits<int>::max();
+ float logicalRightSide = numeric_limits<int>::min();
for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
- logicalLeftSide = min(logicalLeftSide, curr->logicalLeftVisualOverflow());
- logicalRightSide = max(logicalRightSide, curr->logicalRightVisualOverflow());
+ logicalLeftSide = min(logicalLeftSide, static_cast<float>(curr->logicalLeftVisualOverflow()));
+ logicalRightSide = max(logicalRightSide, static_cast<float>(curr->logicalRightVisualOverflow()));
}
bool isHorizontal = style()->isHorizontalWritingMode();
- int x = isHorizontal ? logicalLeftSide : firstLineBox()->minXVisualOverflow();
- int y = isHorizontal ? firstLineBox()->minYVisualOverflow() : logicalLeftSide;
- int width = isHorizontal ? logicalRightSide - logicalLeftSide : lastLineBox()->maxXVisualOverflow() - firstLineBox()->minXVisualOverflow();
- int height = isHorizontal ? lastLineBox()->maxYVisualOverflow() - firstLineBox()->minYVisualOverflow() : logicalRightSide - logicalLeftSide;
- return IntRect(x, y, width, height);
+ float x = isHorizontal ? logicalLeftSide : firstLineBox()->minXVisualOverflow();
+ float y = isHorizontal ? firstLineBox()->minYVisualOverflow() : logicalLeftSide;
+ float width = isHorizontal ? logicalRightSide - logicalLeftSide : lastLineBox()->maxXVisualOverflow() - firstLineBox()->minXVisualOverflow();
+ float height = isHorizontal ? lastLineBox()->maxYVisualOverflow() - firstLineBox()->minYVisualOverflow() : logicalRightSide - logicalLeftSide;
+ return enclosingIntRect(FloatRect(x, y, width, height));
}
IntRect RenderInline::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
@@ -915,6 +928,8 @@ int RenderInline::baselinePosition(FontBaseline baselineType, bool firstLine, Li
IntSize RenderInline::relativePositionedInlineOffset(const RenderBox* child) const
{
+ // FIXME: This function isn't right with mixed writing modes.
+
ASSERT(isRelPositioned());
if (!isRelPositioned())
return IntSize();
@@ -923,31 +938,32 @@ IntSize RenderInline::relativePositionedInlineOffset(const RenderBox* child) con
// box from the rest of the content, but only in the cases where we know we're positioned
// relative to the inline itself.
- IntSize offset;
- int sx;
- int sy;
+ IntSize logicalOffset;
+ int inlinePosition;
+ int blockPosition;
if (firstLineBox()) {
- sx = firstLineBox()->x();
- sy = firstLineBox()->y();
+ inlinePosition = lroundf(firstLineBox()->logicalLeft());
+ blockPosition = firstLineBox()->logicalTop();
} else {
- sx = layer()->staticX();
- sy = layer()->staticY();
+ inlinePosition = layer()->staticInlinePosition();
+ blockPosition = layer()->staticBlockPosition();
}
- if (!child->style()->hasStaticX())
- offset.setWidth(sx);
+ if (!child->style()->hasStaticInlinePosition(style()->isHorizontalWritingMode()))
+ logicalOffset.setWidth(inlinePosition);
+
// This is not terribly intuitive, but we have to match other browsers. Despite being a block display type inside
// an inline, we still keep our x locked to the left of the relative positioned inline. Arguably the correct
// behavior would be to go flush left to the block that contains the inline, but that isn't what other browsers
// do.
else if (!child->style()->isOriginalDisplayInlineType())
// Avoid adding in the left border/padding of the containing block twice. Subtract it out.
- offset.setWidth(sx - (child->containingBlock()->borderLeft() + child->containingBlock()->paddingLeft()));
+ logicalOffset.setWidth(inlinePosition - child->containingBlock()->borderAndPaddingLogicalLeft());
- if (!child->style()->hasStaticY())
- offset.setHeight(sy);
+ if (!child->style()->hasStaticBlockPosition(style()->isHorizontalWritingMode()))
+ logicalOffset.setHeight(blockPosition);
- return offset;
+ return style()->isHorizontalWritingMode() ? logicalOffset : logicalOffset.transposedSize();
}
void RenderInline::imageChanged(WrappedImagePtr, const IntRect*)
@@ -963,8 +979,8 @@ void RenderInline::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
{
for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
RootInlineBox* root = curr->root();
- int top = max(root->lineTop(), curr->y());
- int bottom = min(root->lineBottom(), curr->y() + curr->logicalHeight());
+ int top = max(root->lineTop(), curr->logicalTop());
+ int bottom = min(root->lineBottom(), curr->logicalBottom());
IntRect rect(tx + curr->x(), ty + top, curr->logicalWidth(), bottom - top);
if (!rect.isEmpty())
rects.append(rect);
@@ -1015,8 +1031,8 @@ void RenderInline::paintOutline(GraphicsContext* graphicsContext, int tx, int ty
rects.append(IntRect());
for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
RootInlineBox* root = curr->root();
- int top = max(root->lineTop(), curr->y());
- int bottom = min(root->lineBottom(), curr->y() + curr->logicalHeight());
+ int top = max(root->lineTop(), curr->logicalTop());
+ int bottom = min(root->lineBottom(), curr->logicalBottom());
rects.append(IntRect(curr->x(), top, curr->logicalWidth(), bottom - top));
}
rects.append(IntRect());
diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp
index e278c75..5f32933 100644
--- a/Source/WebCore/rendering/RenderLayer.cpp
+++ b/Source/WebCore/rendering/RenderLayer.cpp
@@ -182,8 +182,8 @@ RenderLayer::RenderLayer(RenderBoxModelObject* renderer)
, m_hasOverflowScroll(false)
#endif
, m_marquee(0)
- , m_staticX(0)
- , m_staticY(0)
+ , m_staticInlinePosition(0)
+ , m_staticBlockPosition(0)
, m_reflection(0)
, m_scrollCorner(0)
, m_resizer(0)
@@ -413,7 +413,7 @@ void RenderLayer::updateRepaintRectsAfterScroll(bool fixed)
if (fixed || renderer()->style()->position() == FixedPosition) {
computeRepaintRects();
fixed = true;
- } else if (renderer()->hasTransform()) {
+ } else if (renderer()->hasTransform() && !renderer()->isRenderView()) {
// Transforms act as fixed position containers, so nothing inside a
// transformed element can be fixed relative to the viewport if the
// transformed element is not fixed itself or child of a fixed element.
@@ -1839,8 +1839,13 @@ PassRefPtr<Scrollbar> RenderLayer::createScrollbar(ScrollbarOrientation orientat
bool hasCustomScrollbarStyle = actualRenderer->isBox() && actualRenderer->style()->hasPseudoStyle(SCROLLBAR);
if (hasCustomScrollbarStyle)
widget = RenderScrollbar::createCustomScrollbar(this, orientation, toRenderBox(actualRenderer));
- else
+ else {
widget = Scrollbar::createNativeScrollbar(this, orientation, RegularScrollbar);
+ if (orientation == HorizontalScrollbar)
+ didAddHorizontalScrollbar(widget.get());
+ else
+ didAddVerticalScrollbar(widget.get());
+ }
renderer()->document()->view()->addChild(widget.get());
return widget.release();
}
@@ -1851,6 +1856,12 @@ void RenderLayer::destroyScrollbar(ScrollbarOrientation orientation)
if (scrollbar) {
if (scrollbar->isCustomScrollbar())
static_cast<RenderScrollbar*>(scrollbar.get())->clearOwningRenderer();
+ else {
+ if (orientation == HorizontalScrollbar)
+ willRemoveHorizontalScrollbar(scrollbar.get());
+ else
+ willRemoveVerticalScrollbar(scrollbar.get());
+ }
scrollbar->removeFromParent();
scrollbar->disconnectFromScrollableArea();
@@ -1863,13 +1874,10 @@ void RenderLayer::setHasHorizontalScrollbar(bool hasScrollbar)
if (hasScrollbar == (m_hBar != 0))
return;
- if (hasScrollbar) {
+ if (hasScrollbar)
m_hBar = createScrollbar(HorizontalScrollbar);
- ScrollableArea::didAddHorizontalScrollbar(m_hBar.get());
- } else {
- ScrollableArea::willRemoveHorizontalScrollbar(m_hBar.get());
+ else
destroyScrollbar(HorizontalScrollbar);
- }
// Destroying or creating one bar can cause our scrollbar corner to come and go. We need to update the opposite scrollbar's style.
if (m_hBar)
@@ -1889,13 +1897,10 @@ void RenderLayer::setHasVerticalScrollbar(bool hasScrollbar)
if (hasScrollbar == (m_vBar != 0))
return;
- if (hasScrollbar) {
+ if (hasScrollbar)
m_vBar = createScrollbar(VerticalScrollbar);
- ScrollableArea::didAddVerticalScrollbar(m_vBar.get());
- } else {
- ScrollableArea::willRemoveVerticalScrollbar(m_vBar.get());
+ else
destroyScrollbar(VerticalScrollbar);
- }
// Destroying or creating one bar can cause our scrollbar corner to come and go. We need to update the opposite scrollbar's style.
if (m_hBar)
@@ -1912,14 +1917,14 @@ void RenderLayer::setHasVerticalScrollbar(bool hasScrollbar)
int RenderLayer::verticalScrollbarWidth() const
{
- if (!m_vBar || ScrollbarTheme::nativeTheme()->usesOverlayScrollbars())
+ if (!m_vBar || m_vBar->isOverlayScrollbar())
return 0;
return m_vBar->width();
}
int RenderLayer::horizontalScrollbarHeight() const
{
- if (!m_hBar || ScrollbarTheme::nativeTheme()->usesOverlayScrollbars())
+ if (!m_hBar || m_hBar->isOverlayScrollbar())
return 0;
return m_hBar->height();
}
@@ -3283,8 +3288,8 @@ void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, ClipRects& cl
RenderView* view = renderer()->view();
ASSERT(view);
if (view && clipRects.fixed() && rootLayer->renderer() == view) {
- x -= view->frameView()->scrollX();
- y -= view->frameView()->scrollY();
+ x -= view->frameView()->scrollXForFixedPosition();
+ y -= view->frameView()->scrollYForFixedPosition();
}
if (renderer()->hasOverflowClip()) {
@@ -3336,7 +3341,7 @@ IntRect RenderLayer::backgroundClipRect(const RenderLayer* rootLayer, bool tempo
RenderView* view = renderer()->view();
ASSERT(view);
if (view && parentRects.fixed() && rootLayer->renderer() == view)
- backgroundRect.move(view->frameView()->scrollX(), view->frameView()->scrollY());
+ backgroundRect.move(view->frameView()->scrollXForFixedPosition(), view->frameView()->scrollYForFixedPosition());
}
return backgroundRect;
}
@@ -3580,26 +3585,6 @@ bool RenderLayer::hasCompositedMask() const
}
#endif
-bool RenderLayer::scrollbarWillRenderIntoCompositingLayer() const
-{
-#if USE(ACCELERATED_COMPOSITING)
- if (enclosingCompositingLayer())
- return true;
-
- RenderView* view = renderer()->view();
- if (!view)
- return false;
-
- FrameView* frameView = view->frameView();
- if (!frameView)
- return false;
-
- return frameView->isEnclosedInCompositingLayer();
-#else
- return false;
-#endif
-}
-
bool RenderLayer::paintsWithTransform(PaintBehavior paintBehavior) const
{
#if USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/rendering/RenderLayer.h b/Source/WebCore/rendering/RenderLayer.h
index 66281ce..7dddbc8 100644
--- a/Source/WebCore/rendering/RenderLayer.h
+++ b/Source/WebCore/rendering/RenderLayer.h
@@ -444,10 +444,10 @@ public:
void updateRepaintRectsAfterScroll(bool fixed = false);
void setNeedsFullRepaint(bool f = true) { m_needsFullRepaint = f; }
- int staticX() const { return m_staticX; }
- int staticY() const { return m_staticY; }
- void setStaticX(int staticX) { m_staticX = staticX; }
- void setStaticY(int staticY) { m_staticY = staticY; }
+ int staticInlinePosition() const { return m_staticInlinePosition; }
+ int staticBlockPosition() const { return m_staticBlockPosition; }
+ void setStaticInlinePosition(int position) { m_staticInlinePosition = position; }
+ void setStaticBlockPosition(int position) { m_staticBlockPosition = position; }
bool hasTransform() const { return renderer()->hasTransform(); }
// Note that this transform has the transform-origin baked in.
@@ -483,7 +483,6 @@ public:
bool isComposited() const { return false; }
bool hasCompositedMask() const { return false; }
#endif
- virtual bool scrollbarWillRenderIntoCompositingLayer() const;
bool paintsWithTransparency(PaintBehavior paintBehavior) const
{
@@ -745,8 +744,8 @@ protected:
RenderMarquee* m_marquee; // Used by layers with overflow:marquee
// Cached normal flow values for absolute positioned elements with static left/top values.
- int m_staticX;
- int m_staticY;
+ int m_staticInlinePosition;
+ int m_staticBlockPosition;
OwnPtr<TransformationMatrix> m_transform;
diff --git a/Source/WebCore/rendering/RenderLayerBacking.cpp b/Source/WebCore/rendering/RenderLayerBacking.cpp
index d0a36c7..bda34ee 100644
--- a/Source/WebCore/rendering/RenderLayerBacking.cpp
+++ b/Source/WebCore/rendering/RenderLayerBacking.cpp
@@ -36,7 +36,6 @@
#include "CSSStyleSelector.h"
#include "FrameView.h"
#include "GraphicsContext.h"
-#include "GraphicsContext3D.h"
#include "GraphicsLayer.h"
#include "HTMLCanvasElement.h"
#include "HTMLElement.h"
@@ -55,7 +54,10 @@
#include "RenderVideo.h"
#include "RenderView.h"
#include "Settings.h"
-#include "WebGLRenderingContext.h"
+
+#if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
+#include "GraphicsContext3D.h"
+#endif
using namespace std;
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp
index f9c0f32..4ab274f 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp
@@ -344,7 +344,9 @@ bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeR
layer->ensureBacking();
#if PLATFORM(MAC) && PLATFORM(CA)
- if (layer->renderer()->isCanvas()) {
+ if (m_renderView->document()->settings()->acceleratedDrawingEnabled())
+ layer->backing()->graphicsLayer()->setAcceleratesDrawing(true);
+ else if (layer->renderer()->isCanvas()) {
HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(layer->renderer()->node());
if (canvas->renderingContext() && canvas->renderingContext()->isAccelerated())
layer->backing()->graphicsLayer()->setAcceleratesDrawing(true);
@@ -1159,6 +1161,10 @@ void RenderLayerCompositor::updateRootLayerPosition()
m_rootPlatformLayer->setSize(FloatSize(m_renderView->docWidth(), m_renderView->docHeight()));
m_rootPlatformLayer->setPosition(FloatPoint(m_renderView->docLeft(), m_renderView->docTop()));
}
+ if (m_clipLayer) {
+ FrameView* frameView = m_renderView->frameView();
+ m_clipLayer->setSize(FloatSize(frameView->layoutWidth(), frameView->layoutHeight()));
+ }
}
void RenderLayerCompositor::didStartAcceleratedAnimation(CSSPropertyID property)
@@ -1453,6 +1459,7 @@ bool RenderLayerCompositor::requiresCompositingForFullScreen(RenderObject* rende
#if ENABLE(FULLSCREEN_API)
return renderer->isRenderFullScreen() && toRenderFullScreen(renderer)->isAnimating();
#else
+ UNUSED_PARAM(renderer);
return false;
#endif
}
diff --git a/Source/WebCore/rendering/RenderLineBoxList.cpp b/Source/WebCore/rendering/RenderLineBoxList.cpp
index 274905e..9a40baf 100644
--- a/Source/WebCore/rendering/RenderLineBoxList.cpp
+++ b/Source/WebCore/rendering/RenderLineBoxList.cpp
@@ -363,11 +363,9 @@ void RenderLineBoxList::dirtyLinesFromChangedChild(RenderObject* container, Rend
adjacentBox = box->prevRootBox();
if (adjacentBox)
adjacentBox->markDirty();
- if (child->isBR() || (curr && curr->isBR())) {
- adjacentBox = box->nextRootBox();
- if (adjacentBox)
- adjacentBox->markDirty();
- }
+ adjacentBox = box->nextRootBox();
+ if (adjacentBox && (adjacentBox->lineBreakObj() == child || child->isBR() || (curr && curr->isBR())))
+ adjacentBox->markDirty();
}
}
diff --git a/Source/WebCore/rendering/RenderListBox.cpp b/Source/WebCore/rendering/RenderListBox.cpp
index 13e8e58..4457285 100644
--- a/Source/WebCore/rendering/RenderListBox.cpp
+++ b/Source/WebCore/rendering/RenderListBox.cpp
@@ -111,7 +111,7 @@ void RenderListBox::updateFromElement()
}
if (!text.isEmpty()) {
- float textWidth = itemFont.floatWidth(TextRun(text.impl(), false, 0, 0, TextRun::AllowTrailingExpansion, false, false, false, false));
+ float textWidth = itemFont.width(TextRun(text.impl(), false, 0, 0, TextRun::AllowTrailingExpansion, false, false));
width = max(width, textWidth);
}
}
@@ -278,6 +278,32 @@ void RenderListBox::paintObject(PaintInfo& paintInfo, int tx, int ty)
}
}
+void RenderListBox::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
+{
+ if (!isSpatialNavigationEnabled(frame()))
+ return RenderBlock::addFocusRingRects(rects, tx, ty);
+
+ SelectElement* select = toSelectElement(static_cast<Element*>(node()));
+
+ // Focus the last selected item.
+ int selectedItem = select->activeSelectionEndListIndex();
+ if (selectedItem >= 0) {
+ rects.append(itemBoundingBoxRect(tx, ty, selectedItem));
+ return;
+ }
+
+ // No selected items, find the first non-disabled item.
+ int size = numItems();
+ const Vector<Element*>& listItems = select->listItems();
+ for (int i = 0; i < size; ++i) {
+ OptionElement* optionElement = toOptionElement(listItems[i]);
+ if (optionElement && !optionElement->disabled()) {
+ rects.append(itemBoundingBoxRect(tx, ty, i));
+ return;
+ }
+ }
+}
+
void RenderListBox::paintScrollbar(PaintInfo& paintInfo, int tx, int ty)
{
if (m_vBar) {
@@ -333,7 +359,7 @@ void RenderListBox::paintItemForeground(PaintInfo& paintInfo, int tx, int ty, in
unsigned length = itemText.length();
const UChar* string = itemText.characters();
- TextRun textRun(string, length, false, 0, 0, TextRun::AllowTrailingExpansion, !itemStyle->isLeftToRightDirection(), itemStyle->unicodeBidi() == Override, false, false);
+ TextRun textRun(string, length, false, 0, 0, TextRun::AllowTrailingExpansion, !itemStyle->isLeftToRightDirection(), itemStyle->unicodeBidi() == Override);
// Draw the item text
if (itemStyle->visibility() != HIDDEN)
@@ -557,7 +583,7 @@ int RenderListBox::itemHeight() const
int RenderListBox::verticalScrollbarWidth() const
{
- return m_vBar && !ScrollbarTheme::nativeTheme()->usesOverlayScrollbars() ? m_vBar->width() : 0;
+ return m_vBar && !m_vBar->isOverlayScrollbar() ? m_vBar->width() : 0;
}
// FIXME: We ignore padding in the vertical direction as far as these values are concerned, since that's
@@ -721,22 +747,16 @@ IntPoint RenderListBox::currentMousePosition() const
return view->frameView()->currentMousePosition();
}
-bool RenderListBox::scrollbarWillRenderIntoCompositingLayer() const
-{
- RenderLayer* layer = this->enclosingLayer();
- if (!layer)
- return false;
- return layer->scrollbarWillRenderIntoCompositingLayer();
-}
-
PassRefPtr<Scrollbar> RenderListBox::createScrollbar()
{
RefPtr<Scrollbar> widget;
bool hasCustomScrollbarStyle = style()->hasPseudoStyle(SCROLLBAR);
if (hasCustomScrollbarStyle)
widget = RenderScrollbar::createCustomScrollbar(this, VerticalScrollbar, this);
- else
+ else {
widget = Scrollbar::createNativeScrollbar(this, VerticalScrollbar, theme()->scrollbarControlSizeForPart(ListboxPart));
+ didAddVerticalScrollbar(widget.get());
+ }
document()->view()->addChild(widget.get());
return widget.release();
}
@@ -745,7 +765,9 @@ void RenderListBox::destroyScrollbar()
{
if (!m_vBar)
return;
-
+
+ if (!m_vBar->isCustomScrollbar())
+ ScrollableArea::willRemoveVerticalScrollbar(m_vBar.get());
m_vBar->removeFromParent();
m_vBar->disconnectFromScrollableArea();
m_vBar = 0;
@@ -756,13 +778,10 @@ void RenderListBox::setHasVerticalScrollbar(bool hasScrollbar)
if (hasScrollbar == (m_vBar != 0))
return;
- if (hasScrollbar) {
+ if (hasScrollbar)
m_vBar = createScrollbar();
- ScrollableArea::didAddVerticalScrollbar(m_vBar.get());
- } else {
- ScrollableArea::willRemoveVerticalScrollbar(m_vBar.get());
+ else
destroyScrollbar();
- }
if (m_vBar)
m_vBar->styleChanged();
diff --git a/Source/WebCore/rendering/RenderListBox.h b/Source/WebCore/rendering/RenderListBox.h
index 1eb2036..faeede1 100644
--- a/Source/WebCore/rendering/RenderListBox.h
+++ b/Source/WebCore/rendering/RenderListBox.h
@@ -77,6 +77,8 @@ private:
virtual void layout();
+ virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
+
virtual bool canBeProgramaticallyScrolled(bool) const { return true; }
virtual void autoscroll();
virtual void stopAutoscroll();
@@ -110,7 +112,6 @@ private:
virtual int visibleHeight() const;
virtual int visibleWidth() const;
virtual IntPoint currentMousePosition() const;
- virtual bool scrollbarWillRenderIntoCompositingLayer() const;
// NOTE: This should only be called by the overriden setScrollOffset from ScrollableArea.
void scrollTo(int newOffset);
diff --git a/Source/WebCore/rendering/RenderMedia.cpp b/Source/WebCore/rendering/RenderMedia.cpp
index 16cd874..bbb5880 100644
--- a/Source/WebCore/rendering/RenderMedia.cpp
+++ b/Source/WebCore/rendering/RenderMedia.cpp
@@ -31,6 +31,7 @@
#include "HTMLMediaElement.h"
#include "MediaControlElements.h"
#include "MediaControls.h"
+#include "RenderView.h"
namespace WebCore {
@@ -80,17 +81,24 @@ void RenderMedia::layout()
if (!controlsRenderer)
return;
IntSize newSize = contentBoxRect().size();
- if (newSize != oldSize || controlsRenderer->needsLayout()) {
+ if (newSize == oldSize && !controlsRenderer->needsLayout())
+ return;
+
+ // When calling layout() on a child node, a parent must either push a LayoutStateMaintainter, or
+ // call view()->disableLayoutState(). Since using a LayoutStateMaintainer is slightly more efficient,
+ // and this method will be called many times per second during playback, use a LayoutStateMaintainer:
+ LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
+
+ m_controls->updateTimeDisplayVisibility();
- m_controls->updateTimeDisplayVisibility();
+ controlsRenderer->setLocation(borderLeft() + paddingLeft(), borderTop() + paddingTop());
+ controlsRenderer->style()->setHeight(Length(newSize.height(), Fixed));
+ controlsRenderer->style()->setWidth(Length(newSize.width(), Fixed));
+ controlsRenderer->setNeedsLayout(true, false);
+ controlsRenderer->layout();
+ setChildNeedsLayout(false);
- controlsRenderer->setLocation(borderLeft() + paddingLeft(), borderTop() + paddingTop());
- controlsRenderer->style()->setHeight(Length(newSize.height(), Fixed));
- controlsRenderer->style()->setWidth(Length(newSize.width(), Fixed));
- controlsRenderer->setNeedsLayout(true, false);
- controlsRenderer->layout();
- setChildNeedsLayout(false);
- }
+ statePusher.pop();
}
void RenderMedia::updateFromElement()
diff --git a/Source/WebCore/rendering/RenderMediaControls.cpp b/Source/WebCore/rendering/RenderMediaControls.cpp
index 9c4757c..dd58cd2 100644
--- a/Source/WebCore/rendering/RenderMediaControls.cpp
+++ b/Source/WebCore/rendering/RenderMediaControls.cpp
@@ -24,29 +24,37 @@
*/
#include "config.h"
+
+#if ENABLE(VIDEO)
+
#include "RenderMediaControls.h"
#include "GraphicsContext.h"
#include "HTMLMediaElement.h"
#include "HTMLNames.h"
#include "RenderTheme.h"
+
+// FIXME: Unify more of the code for Mac and Win.
+#if PLATFORM(WIN)
+
#include <CoreGraphics/CoreGraphics.h>
#include <WebKitSystemInterface/WebKitSystemInterface.h>
-#if PLATFORM(WIN)
// The Windows version of WKSI defines these functions as capitalized, while the Mac version defines them as lower case.
+// FIXME: Is this necessary anymore?
#define wkMediaControllerThemeAvailable(themeStyle) WKMediaControllerThemeAvailable(themeStyle)
#define wkHitTestMediaUIPart(part, themeStyle, bounds, point) WKHitTestMediaUIPart(part, themeStyle, bounds, point)
#define wkMeasureMediaUIPart(part, themeStyle, bounds, naturalSize) WKMeasureMediaUIPart(part, themeStyle, bounds, naturalSize)
#define wkDrawMediaUIPart(part, themeStyle, context, rect, state) WKDrawMediaUIPart(part, themeStyle, context, rect, state)
#define wkDrawMediaSliderTrack(themeStyle, context, rect, timeLoaded, currentTime, duration, state) WKDrawMediaSliderTrack(themeStyle, context, rect, timeLoaded, currentTime, duration, state)
+
#endif
using namespace std;
namespace WebCore {
-#if ENABLE(VIDEO)
+#if PLATFORM(WIN)
static WKMediaControllerThemeState determineState(RenderObject* o)
{
@@ -169,19 +177,21 @@ bool RenderMediaControls::paintMediaControlsPart(MediaControlElementType part, R
return false;
}
-IntPoint RenderMediaControls::volumeSliderOffsetFromMuteButton(Node* muteButton, const IntSize& size)
+#endif
+
+IntPoint RenderMediaControls::volumeSliderOffsetFromMuteButton(RenderBox* muteButtonBox, const IntSize& size)
{
static const int xOffset = -4;
static const int yOffset = 5;
- float zoomLevel = muteButton->renderer()->style()->effectiveZoom();
- int y = yOffset * zoomLevel + muteButton->renderBox()->offsetHeight() - size.height();
- FloatPoint absPoint = muteButton->renderer()->localToAbsolute(FloatPoint(muteButton->renderBox()->offsetLeft(), y), true, true);
+ float zoomLevel = muteButtonBox->style()->effectiveZoom();
+ int y = yOffset * zoomLevel + muteButtonBox->offsetHeight() - size.height();
+ FloatPoint absPoint = muteButtonBox->localToAbsolute(FloatPoint(muteButtonBox->offsetLeft(), y), true, true);
if (absPoint.y() < 0)
- y = muteButton->renderBox()->height();
+ y = muteButtonBox->height();
return IntPoint(xOffset * zoomLevel, y);
+}
}
-#endif // #if ENABLE(VIDEO)
-} // namespace WebCore
+#endif
diff --git a/Source/WebCore/rendering/RenderMediaControls.h b/Source/WebCore/rendering/RenderMediaControls.h
index 9edeef1..3d3b017 100644
--- a/Source/WebCore/rendering/RenderMediaControls.h
+++ b/Source/WebCore/rendering/RenderMediaControls.h
@@ -34,11 +34,15 @@
namespace WebCore {
class HTMLMediaElement;
+
class RenderMediaControls {
public:
+
+#if PLATFORM(WIN)
static bool paintMediaControlsPart(MediaControlElementType, RenderObject*, const PaintInfo&, const IntRect&);
static void adjustMediaSliderThumbSize(RenderObject*);
- static IntPoint volumeSliderOffsetFromMuteButton(Node*, const IntSize&);
+#endif
+ static IntPoint volumeSliderOffsetFromMuteButton(RenderBox*, const IntSize&);
};
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderMenuList.cpp b/Source/WebCore/rendering/RenderMenuList.cpp
index 3e9d198..8c11959 100644
--- a/Source/WebCore/rendering/RenderMenuList.cpp
+++ b/Source/WebCore/rendering/RenderMenuList.cpp
@@ -153,10 +153,10 @@ void RenderMenuList::updateOptionsWidth()
if (RenderStyle* optionStyle = element->renderStyle())
optionWidth += optionStyle->textIndent().calcMinValue(0);
if (!text.isEmpty())
- optionWidth += style()->font().floatWidth(text);
+ optionWidth += style()->font().width(text);
maxOptionWidth = max(maxOptionWidth, optionWidth);
} else if (!text.isEmpty())
- maxOptionWidth = max(maxOptionWidth, style()->font().floatWidth(text));
+ maxOptionWidth = max(maxOptionWidth, style()->font().width(text));
}
int width = static_cast<int>(ceilf(maxOptionWidth));
diff --git a/Source/WebCore/rendering/RenderObject.cpp b/Source/WebCore/rendering/RenderObject.cpp
index ebab355..d06db14 100644
--- a/Source/WebCore/rendering/RenderObject.cpp
+++ b/Source/WebCore/rendering/RenderObject.cpp
@@ -2651,13 +2651,14 @@ VisiblePosition RenderObject::createVisiblePosition(int offset, EAffinity affini
// If it can be found, we prefer a visually equivalent position that is editable.
Position position(node, offset);
Position candidate = position.downstream(CanCrossEditingBoundary);
- if (candidate.node()->isContentEditable())
+ if (candidate.deprecatedNode()->isContentEditable())
return VisiblePosition(candidate, affinity);
candidate = position.upstream(CanCrossEditingBoundary);
- if (candidate.node()->isContentEditable())
+ if (candidate.deprecatedNode()->isContentEditable())
return VisiblePosition(candidate, affinity);
}
- return VisiblePosition(node, offset, affinity);
+ // FIXME: Eliminate legacy editing positions
+ return VisiblePosition(Position(node, offset), affinity);
}
// We don't want to cross the boundary between editable and non-editable
@@ -2672,7 +2673,7 @@ VisiblePosition RenderObject::createVisiblePosition(int offset, EAffinity affini
RenderObject* renderer = child;
while ((renderer = renderer->nextInPreOrder(parent))) {
if (Node* node = renderer->node())
- return VisiblePosition(node, 0, DOWNSTREAM);
+ return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
}
// Find non-anonymous content before.
@@ -2681,12 +2682,12 @@ VisiblePosition RenderObject::createVisiblePosition(int offset, EAffinity affini
if (renderer == parent)
break;
if (Node* node = renderer->node())
- return VisiblePosition(lastDeepEditingPositionForNode(node), DOWNSTREAM);
+ return VisiblePosition(lastPositionInOrAfterNode(node), DOWNSTREAM);
}
// Use the parent itself unless it too is anonymous.
if (Node* node = parent->node())
- return VisiblePosition(node, 0, DOWNSTREAM);
+ return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
// Repeat at the next level up.
child = parent;
diff --git a/Source/WebCore/rendering/RenderObject.h b/Source/WebCore/rendering/RenderObject.h
index 43e6bea..8b9fa38 100644
--- a/Source/WebCore/rendering/RenderObject.h
+++ b/Source/WebCore/rendering/RenderObject.h
@@ -252,6 +252,7 @@ public:
virtual bool isBlockFlow() const { return false; }
virtual bool isBoxModelObject() const { return false; }
virtual bool isCounter() const { return false; }
+ virtual bool isQuote() const { return false; }
virtual bool isDetails() const { return false; }
virtual bool isDetailsMarker() const { return false; }
virtual bool isEmbeddedObject() const { return false; }
@@ -981,7 +982,7 @@ inline void RenderObject::markContainingBlocksForLayout(bool scheduleRelayout, R
if (!container && !o->isRenderView())
return;
if (!last->isText() && (last->style()->position() == FixedPosition || last->style()->position() == AbsolutePosition)) {
- if ((last->style()->top().isAuto() && last->style()->bottom().isAuto()) || last->style()->top().isStatic()) {
+ if (last->style()->top().isAuto() && last->style()->bottom().isAuto()) {
RenderObject* parent = last->parent();
if (!parent->normalChildNeedsLayout()) {
parent->setChildNeedsLayout(true, false);
diff --git a/Source/WebCore/rendering/RenderObjectChildList.cpp b/Source/WebCore/rendering/RenderObjectChildList.cpp
index 6a773dc..4df7180 100644
--- a/Source/WebCore/rendering/RenderObjectChildList.cpp
+++ b/Source/WebCore/rendering/RenderObjectChildList.cpp
@@ -36,6 +36,7 @@
#include "RenderInline.h"
#include "RenderLayer.h"
#include "RenderListItem.h"
+#include "RenderQuote.h"
#include "RenderStyle.h"
#include "RenderTextFragment.h"
#include "RenderView.h"
@@ -130,6 +131,7 @@ RenderObject* RenderObjectChildList::removeChildNode(RenderObject* owner, Render
if (oldChild->m_hasCounterNodeMap)
RenderCounter::destroyCounterNodes(oldChild);
+ RenderQuote::rendererRemovedFromTree(oldChild);
if (AXObjectCache::accessibilityEnabled())
owner->document()->axObjectCache()->childrenChanged(owner);
@@ -177,8 +179,8 @@ void RenderObjectChildList::appendChildNode(RenderObject* owner, RenderObject* n
if (!newChild->isFloatingOrPositioned() && owner->childrenInline())
owner->dirtyLinesFromChangedChild(newChild);
}
-
RenderCounter::rendererSubtreeAttached(newChild);
+ RenderQuote::rendererSubtreeAttached(newChild);
newChild->setNeedsLayoutAndPrefWidthsRecalc(); // Goes up the containing block hierarchy.
if (!owner->normalChildNeedsLayout())
owner->setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
@@ -239,6 +241,7 @@ void RenderObjectChildList::insertChildNode(RenderObject* owner, RenderObject* c
}
RenderCounter::rendererSubtreeAttached(child);
+ RenderQuote::rendererSubtreeAttached(child);
child->setNeedsLayoutAndPrefWidthsRecalc();
if (!owner->normalChildNeedsLayout())
owner->setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
@@ -460,10 +463,14 @@ void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, Pseudo
renderer = image;
break;
}
- case CONTENT_COUNTER:
- renderer = new (owner->renderArena()) RenderCounter(owner->document(), *content->counter());
- renderer->setStyle(pseudoElementStyle);
- break;
+ case CONTENT_COUNTER:
+ renderer = new (owner->renderArena()) RenderCounter(owner->document(), *content->counter());
+ renderer->setStyle(pseudoElementStyle);
+ break;
+ case CONTENT_QUOTE:
+ renderer = new (owner->renderArena()) RenderQuote(owner->document(), content->quote());
+ renderer->setStyle(pseudoElementStyle);
+ break;
}
if (renderer) {
diff --git a/Source/WebCore/rendering/RenderQuote.cpp b/Source/WebCore/rendering/RenderQuote.cpp
new file mode 100644
index 0000000..4523df8
--- /dev/null
+++ b/Source/WebCore/rendering/RenderQuote.cpp
@@ -0,0 +1,331 @@
+/**
+ * Copyright (C) 2011 Nokia Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "RenderQuote.h"
+
+#include "Document.h"
+#include "Element.h"
+#include "HTMLElement.h"
+#include "QuotesData.h"
+#include "RenderStyle.h"
+#include <algorithm>
+#include <wtf/text/AtomicString.h>
+#include <wtf/text/CString.h>
+
+#define UNKNOWN_DEPTH -1
+
+namespace WebCore {
+static inline void adjustDepth(int &depth, QuoteType type)
+{
+ switch (type) {
+ case OPEN_QUOTE:
+ case NO_OPEN_QUOTE:
+ ++depth;
+ break;
+ case CLOSE_QUOTE:
+ case NO_CLOSE_QUOTE:
+ if (depth)
+ --depth;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+}
+
+RenderQuote::RenderQuote(Document* node, QuoteType quote)
+ : RenderText(node, StringImpl::empty())
+ , m_type(quote)
+ , m_depth(UNKNOWN_DEPTH)
+ , m_next(0)
+ , m_previous(0)
+{
+}
+
+RenderQuote::~RenderQuote()
+{
+}
+
+const char* RenderQuote::renderName() const
+{
+ return "RenderQuote";
+}
+
+// This function places a list of quote renderers starting at "this" in the list of quote renderers already
+// in the document's renderer tree.
+// The assumptions are made (for performance):
+// 1. The list of quotes already in the renderers tree of the document is already in a consistent state
+// (All quote renderers are linked and have the correct depth set)
+// 2. The quote renderers of the inserted list are in a tree of renderers of their own which has been just
+// inserted in the main renderer tree with its root as child of some renderer.
+// 3. The quote renderers in the inserted list have depths consistent with their position in the list relative
+// to "this", thus if "this" does not need to change its depth upon insertion, the other renderers in the list don't
+// need to either.
+void RenderQuote::placeQuote()
+{
+ RenderQuote* head = this;
+ ASSERT(!head->m_previous);
+ RenderQuote* tail = 0;
+ for (RenderObject* predecessor = head->previousInPreOrder(); predecessor; predecessor = predecessor->previousInPreOrder()) {
+ if (!predecessor->isQuote())
+ continue;
+ head->m_previous = toRenderQuote(predecessor);
+ if (head->m_previous->m_next) {
+ // We need to splice the list of quotes headed by head into the document's list of quotes.
+ tail = head;
+ while (tail->m_next)
+ tail = tail->m_next;
+ tail->m_next = head->m_previous->m_next;
+ ASSERT(tail->m_next->m_previous == head->m_previous);
+ tail->m_next->m_previous = tail;
+ tail = tail->m_next; // This marks the splicing point here there may be a depth discontinuity
+ }
+ head->m_previous->m_next = head;
+ ASSERT(head->m_previous->m_depth != UNKNOWN_DEPTH);
+ break;
+ }
+ int newDepth;
+ if (!head->m_previous) {
+ newDepth = 0;
+ goto skipNewDepthCalc;
+ }
+ newDepth = head->m_previous->m_depth;
+ do {
+ adjustDepth(newDepth, head->m_previous->m_type);
+skipNewDepthCalc:
+ if (head->m_depth == newDepth) { // All remaining depth should be correct except if splicing was done.
+ if (!tail) // We've done the post splicing section already or there was no splicing.
+ break;
+ head = tail; // Continue after the splicing point
+ tail = 0; // Mark the possible splicing point discontinuity fixed.
+ newDepth = head->m_previous->m_depth;
+ continue;
+ }
+ head->m_depth = newDepth;
+ // FIXME: If the width and height of the quotation characters does not change we may only need to
+ // Invalidate the renderer's area not a relayout.
+ head->setNeedsLayoutAndPrefWidthsRecalc();
+ head = head->m_next;
+ if (head == tail) // We are at the splicing point
+ tail = 0; // Mark the possible depth discontinuity fixed.
+ } while (head);
+}
+
+#define ARRAY_SIZE(Carray) (sizeof(Carray) / sizeof(*Carray))
+#define LANGUAGE_DATA(name, languageSourceArray) { name, languageSourceArray, ARRAY_SIZE(languageSourceArray) }
+#define U(x) ((const UChar*)L##x)
+
+static const UChar* simpleQuotes[] = {U("\""), U("\""), U("'"), U("'")};
+
+static const UChar* englishQuotes[] = {U("\x201C"), U("\x201D"), U("\x2018"), U("\x2019")};
+static const UChar* norwegianQuotes[] = { U("\x00AB"), U("\x00BB"), U("\x2039"), U("\x203A") };
+static const UChar* romanianQuotes[] = { U("\x201E"), U("\x201D")};
+static const UChar* russianQuotes[] = { U("\x00AB"), U("\x00BB"), U("\x201E"), U("\x201C") };
+#undef U
+
+struct LanguageData {
+ const char *name;
+ const UChar* const* const array;
+ const int arraySize;
+ bool operator<(const LanguageData& compareTo) const
+ {
+ return strcmp(name, compareTo.name);
+ }
+};
+
+// Data mast be alphabetically sorted and in all lower case for fast comparison
+LanguageData languageData[] = {
+ LANGUAGE_DATA("en", englishQuotes),
+ LANGUAGE_DATA("no", norwegianQuotes),
+ LANGUAGE_DATA("ro", romanianQuotes),
+ LANGUAGE_DATA("ru", russianQuotes)
+};
+#undef LANGUAGE_DATA
+const LanguageData* const languageDataEnd = languageData + ARRAY_SIZE(languageData);
+
+#define defaultLanguageQuotesSource simpleQuotes
+#define defaultLanguageQuotesCount ARRAY_SIZE(defaultLanguageQuotesSource)
+
+static QuotesData* defaultLanguageQuotesValue = 0;
+static const QuotesData* defaultLanguageQuotes()
+{
+ if (!defaultLanguageQuotesValue) {
+ defaultLanguageQuotesValue = QuotesData::create(defaultLanguageQuotesCount);
+ if (!defaultLanguageQuotesValue)
+ return 0;
+ String* data = defaultLanguageQuotesValue->data();
+ for (size_t i = 0; i < defaultLanguageQuotesCount; ++i)
+ data[i] = defaultLanguageQuotesSource[i];
+ }
+ return defaultLanguageQuotesValue;
+}
+#undef defaultLanguageQuotesSource
+#undef defaultLanguageQuotesCount
+
+typedef HashMap<RefPtr<AtomicStringImpl>, QuotesData* > QuotesMap;
+
+static QuotesMap& quotesMap()
+{
+ DEFINE_STATIC_LOCAL(QuotesMap, staticQuotesMap, ());
+ return staticQuotesMap;
+}
+
+static const QuotesData* quotesForLanguage(AtomicStringImpl* language)
+{
+ QuotesData* returnValue;
+ AtomicString lower(language->lower());
+ returnValue = quotesMap().get(lower.impl());
+ if (returnValue)
+ return returnValue;
+ CString s(static_cast<const String&>(lower).ascii());
+ LanguageData request = { s.buffer()->data(), 0, 0 };
+ const LanguageData* lowerBound = std::lower_bound<const LanguageData*, const LanguageData>(languageData, languageDataEnd, request);
+ if (lowerBound == languageDataEnd)
+ return defaultLanguageQuotes();
+ if (strncmp(lowerBound->name, request.name, strlen(lowerBound->name)))
+ return defaultLanguageQuotes();
+ returnValue = QuotesData::create(lowerBound->arraySize);
+ if (!returnValue)
+ return defaultLanguageQuotes();
+ String* data = returnValue->data();
+ for (int i = 0; i < lowerBound->arraySize; ++i)
+ data[i] = lowerBound->array[i];
+ quotesMap().set(lower.impl(), returnValue);
+ return returnValue;
+}
+#undef ARRAY_SIZE
+
+static const QuotesData* defaultQuotes(const RenderObject* object)
+{
+ DEFINE_STATIC_LOCAL(String, langString, ("lang"));
+ Node* node = object->generatingNode();
+ Element* element;
+ if (!node) {
+ element = object->document()->body();
+ if (!element)
+ element = object->document()->documentElement();
+ } else if (!node->isElementNode()) {
+ element = node->parentElement();
+ if (!element)
+ return defaultLanguageQuotes();
+ } else
+ element = toElement(node);
+ const AtomicString* language;
+ while ((language = &element->getAttribute(langString)) && language->isNull()) {
+ element = element->parentElement();
+ if (!element)
+ return defaultLanguageQuotes();
+ }
+ return quotesForLanguage(language->impl());
+}
+
+PassRefPtr<StringImpl> RenderQuote::originalText() const
+{
+ if (!parent())
+ return 0;
+ ASSERT(m_depth != UNKNOWN_DEPTH);
+ const QuotesData* quotes = style()->quotes();
+ if (!quotes)
+ quotes = defaultQuotes(this);
+ if (!quotes->length)
+ return emptyAtom.impl();
+ int index = m_depth * 2;
+ switch (m_type) {
+ case NO_OPEN_QUOTE:
+ case NO_CLOSE_QUOTE:
+ return String("").impl();
+ case CLOSE_QUOTE:
+ if (index)
+ --index;
+ else
+ ++index;
+ break;
+ case OPEN_QUOTE:
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ return emptyAtom.impl();
+ }
+ if (index >= quotes->length)
+ index = (quotes->length-2) | (index & 1);
+ if (index < 0)
+ return emptyAtom.impl();
+ return quotes->data()[index].impl();
+}
+
+void RenderQuote::computePreferredLogicalWidths(float lead)
+{
+ setTextInternal(originalText());
+ RenderText::computePreferredLogicalWidths(lead);
+}
+
+void RenderQuote::rendererSubtreeAttached(RenderObject* renderer)
+{
+ if (renderer->documentBeingDestroyed())
+ return;
+ for (RenderObject* descendant = renderer; descendant; descendant = descendant->nextInPreOrder(renderer))
+ if (descendant->isQuote()) {
+ toRenderQuote(descendant)->placeQuote();
+ break;
+ }
+}
+
+void RenderQuote::rendererRemovedFromTree(RenderObject* subtreeRoot)
+{
+ if (subtreeRoot->documentBeingDestroyed())
+ return;
+ for (RenderObject* descendant = subtreeRoot; descendant; descendant = descendant->nextInPreOrder(subtreeRoot))
+ if (descendant->isQuote()) {
+ RenderQuote* removedQuote = toRenderQuote(descendant);
+ RenderQuote* lastQuoteBefore = removedQuote->m_previous;
+ removedQuote->m_previous = 0;
+ int depth = removedQuote->m_depth;
+ for (descendant = descendant->nextInPreOrder(subtreeRoot); descendant; descendant = descendant->nextInPreOrder(subtreeRoot))
+ if (descendant->isQuote())
+ removedQuote = toRenderQuote(descendant);
+ RenderQuote* quoteAfter = removedQuote->m_next;
+ removedQuote->m_next = 0;
+ if (lastQuoteBefore)
+ lastQuoteBefore->m_next = quoteAfter;
+ if (quoteAfter) {
+ quoteAfter->m_previous = lastQuoteBefore;
+ do {
+ if (depth == quoteAfter->m_depth)
+ break;
+ quoteAfter->m_depth = depth;
+ quoteAfter->setNeedsLayoutAndPrefWidthsRecalc();
+ adjustDepth(depth, quoteAfter->m_type);
+ quoteAfter = quoteAfter->m_next;
+ } while (quoteAfter);
+ }
+ break;
+ }
+}
+
+void RenderQuote::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+ const QuotesData* newQuotes = style()->quotes();
+ const QuotesData* oldQuotes = oldStyle ? oldStyle->quotes() : 0;
+ if (!((newQuotes && oldQuotes && (*newQuotes == *oldQuotes)) || (!newQuotes && !oldQuotes)))
+ setNeedsLayoutAndPrefWidthsRecalc();
+ RenderText::styleDidChange(diff, oldStyle);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderQuote.h b/Source/WebCore/rendering/RenderQuote.h
new file mode 100644
index 0000000..d9e5437
--- /dev/null
+++ b/Source/WebCore/rendering/RenderQuote.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2011 Nokia Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef RenderQuote_h
+#define RenderQuote_h
+
+#include "RenderStyleConstants.h"
+#include "RenderText.h"
+
+namespace WebCore {
+
+class RenderQuote : public RenderText {
+public:
+ RenderQuote(Document*, const QuoteType);
+ virtual ~RenderQuote();
+
+ static void rendererSubtreeAttached(RenderObject*);
+ static void rendererRemovedFromTree(RenderObject*);
+protected:
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+private:
+ virtual const char* renderName() const;
+ virtual bool isQuote() const { return true; };
+ virtual PassRefPtr<StringImpl> originalText() const;
+ virtual void computePreferredLogicalWidths(float leadWidth);
+ QuoteType m_type;
+ int m_depth;
+ RenderQuote* m_next;
+ RenderQuote* m_previous;
+ void placeQuote();
+};
+
+inline RenderQuote* toRenderQuote(RenderObject* object)
+{
+ ASSERT(!object || object->isQuote());
+ return static_cast<RenderQuote*>(object);
+}
+
+// This will catch anyone doing an unnecessary cast.
+void toRenderQuote(const RenderQuote*);
+
+} // namespace WebCore
+
+#endif // RenderQuote_h
diff --git a/Source/WebCore/rendering/RenderRubyBase.cpp b/Source/WebCore/rendering/RenderRubyBase.cpp
index 83399a1..d285157 100644
--- a/Source/WebCore/rendering/RenderRubyBase.cpp
+++ b/Source/WebCore/rendering/RenderRubyBase.cpp
@@ -31,6 +31,10 @@
#include "config.h"
#include "RenderRubyBase.h"
+#include "RenderRubyRun.h"
+#include "RenderRubyText.h"
+
+using namespace std;
namespace WebCore {
@@ -182,4 +186,30 @@ void RenderRubyBase::mergeBlockChildren(RenderRubyBase* toBase, RenderObject* fr
moveChildrenTo(toBase, firstChild(), fromBeforeChild);
}
+RenderRubyRun* RenderRubyBase::rubyRun() const
+{
+ ASSERT(parent());
+ ASSERT(parent()->isRubyRun());
+
+ return static_cast<RenderRubyRun*>(parent());
+}
+
+ETextAlign RenderRubyBase::textAlignmentForLine(bool /* endsWithSoftBreak */) const
+{
+ return JUSTIFY;
+}
+
+void RenderRubyBase::adjustInlineDirectionLineBounds(int expansionOpportunityCount, float& logicalLeft, float& logicalWidth) const
+{
+ int maxPreferredLogicalWidth = this->maxPreferredLogicalWidth();
+ if (maxPreferredLogicalWidth >= logicalWidth)
+ return;
+
+ // Inset the ruby base by half the inter-ideograph expansion amount.
+ float inset = (logicalWidth - maxPreferredLogicalWidth) / (expansionOpportunityCount + 1);
+
+ logicalLeft += inset / 2;
+ logicalWidth -= inset;
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderRubyBase.h b/Source/WebCore/rendering/RenderRubyBase.h
index c029bd5..850ab65 100644
--- a/Source/WebCore/rendering/RenderRubyBase.h
+++ b/Source/WebCore/rendering/RenderRubyBase.h
@@ -35,6 +35,8 @@
namespace WebCore {
+class RenderRubyRun;
+
class RenderRubyBase : public RenderBlock {
public:
RenderRubyBase(Node*);
@@ -47,13 +49,18 @@ public:
virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
private:
+ virtual ETextAlign textAlignmentForLine(bool endsWithSoftBreak) const;
+ virtual void adjustInlineDirectionLineBounds(int expansionOpportunityCount, float& logicalLeft, float& logicalWidth) const;
+
bool hasOnlyWrappedInlineChildren(RenderObject* beforeChild = 0) const;
void moveChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild = 0);
void moveInlineChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild = 0);
void moveBlockChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild = 0);
void mergeBlockChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild = 0);
-
+
+ RenderRubyRun* rubyRun() const;
+
// Allow RenderRubyRun to manipulate the children within ruby bases.
friend class RenderRubyRun;
};
diff --git a/Source/WebCore/rendering/RenderRubyRun.cpp b/Source/WebCore/rendering/RenderRubyRun.cpp
index f2e30eb..016c2a1 100644
--- a/Source/WebCore/rendering/RenderRubyRun.cpp
+++ b/Source/WebCore/rendering/RenderRubyRun.cpp
@@ -110,7 +110,6 @@ void RenderRubyRun::addChild(RenderObject* child, RenderObject* beforeChild)
{
ASSERT(child);
- // If child is a ruby text
if (child->isRubyText()) {
if (!beforeChild) {
// RenderRuby has already ascertained that we can add the child here.
@@ -133,16 +132,14 @@ void RenderRubyRun::addChild(RenderObject* child, RenderObject* beforeChild)
RenderBlock::addChild(child, beforeChild);
RenderBlock::removeChild(beforeChild);
newRun->addChild(beforeChild);
- } else {
- if (hasRubyBase()) {
- // Insertion before a ruby base object.
- // In this case we need insert a new run before the current one and split the base.
- RenderObject* ruby = parent();
- RenderRubyRun* newRun = staticCreateRubyRun(ruby);
- ruby->addChild(newRun, this);
- newRun->addChild(child);
- rubyBaseSafe()->moveChildren(newRun->rubyBaseSafe(), beforeChild);
- }
+ } else if (hasRubyBase()) {
+ // Insertion before a ruby base object.
+ // In this case we need insert a new run before the current one and split the base.
+ RenderObject* ruby = parent();
+ RenderRubyRun* newRun = staticCreateRubyRun(ruby);
+ ruby->addChild(newRun, this);
+ newRun->addChild(child);
+ rubyBaseSafe()->moveChildren(newRun->rubyBaseSafe(), beforeChild);
}
} else {
// child is not a text -> insert it into the base
diff --git a/Source/WebCore/rendering/RenderRubyText.cpp b/Source/WebCore/rendering/RenderRubyText.cpp
index 14cf7fc..2b0a360 100644
--- a/Source/WebCore/rendering/RenderRubyText.cpp
+++ b/Source/WebCore/rendering/RenderRubyText.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -32,6 +33,8 @@
#include "RenderRubyText.h"
+using namespace std;
+
namespace WebCore {
RenderRubyText::RenderRubyText(Node* node)
@@ -48,4 +51,34 @@ bool RenderRubyText::isChildAllowed(RenderObject* child, RenderStyle*) const
return child->isInline();
}
+ETextAlign RenderRubyText::textAlignmentForLine(bool endsWithSoftBreak) const
+{
+ ETextAlign textAlign = style()->textAlign();
+ if (textAlign != TAAUTO)
+ return RenderBlock::textAlignmentForLine(endsWithSoftBreak);
+
+ // The default behavior is to allow ruby text to expand if it is shorter than the ruby base.
+ return JUSTIFY;
+}
+
+void RenderRubyText::adjustInlineDirectionLineBounds(int expansionOpportunityCount, float& logicalLeft, float& logicalWidth) const
+{
+ ETextAlign textAlign = style()->textAlign();
+ if (textAlign != TAAUTO)
+ return RenderBlock::adjustInlineDirectionLineBounds(expansionOpportunityCount, logicalLeft, logicalWidth);
+
+ int maxPreferredLogicalWidth = this->maxPreferredLogicalWidth();
+ if (maxPreferredLogicalWidth >= logicalWidth)
+ return;
+
+ // Inset the ruby text by half the inter-ideograph expansion amount, but no more than a full-width
+ // ruby character on each side.
+ float inset = (logicalWidth - maxPreferredLogicalWidth) / (expansionOpportunityCount + 1);
+ if (expansionOpportunityCount)
+ inset = min<float>(2 * style()->fontSize(), inset);
+
+ logicalLeft += inset / 2;
+ logicalWidth -= inset;
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderRubyText.h b/Source/WebCore/rendering/RenderRubyText.h
index e475914..1c397ae 100644
--- a/Source/WebCore/rendering/RenderRubyText.h
+++ b/Source/WebCore/rendering/RenderRubyText.h
@@ -45,6 +45,10 @@ public:
virtual bool isRubyText() const { return true; }
virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
+
+private:
+ virtual ETextAlign textAlignmentForLine(bool endsWithSoftBreak) const;
+ virtual void adjustInlineDirectionLineBounds(int expansionOpportunityCount, float& logicalLeft, float& logicalWidth) const;
};
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderScrollbar.h b/Source/WebCore/rendering/RenderScrollbar.h
index 8f4de4f..810c98f 100644
--- a/Source/WebCore/rendering/RenderScrollbar.h
+++ b/Source/WebCore/rendering/RenderScrollbar.h
@@ -60,6 +60,8 @@ public:
int minimumThumbLength();
+ virtual bool isOverlayScrollbar() const { return false; }
+
private:
virtual void setParent(ScrollView*);
virtual void setEnabled(bool);
diff --git a/Source/WebCore/rendering/RenderTable.cpp b/Source/WebCore/rendering/RenderTable.cpp
index bb90e97..69c073c 100644
--- a/Source/WebCore/rendering/RenderTable.cpp
+++ b/Source/WebCore/rendering/RenderTable.cpp
@@ -261,6 +261,18 @@ void RenderTable::computeLogicalWidth()
}
}
+void RenderTable::adjustLogicalHeightForCaption()
+{
+ ASSERT(m_caption);
+ IntRect captionRect(m_caption->x(), m_caption->y(), m_caption->width(), m_caption->height());
+
+ m_caption->setLogicalLocation(m_caption->marginStart(), logicalHeight());
+ if (!selfNeedsLayout() && m_caption->checkForRepaintDuringLayout())
+ m_caption->repaintDuringLayoutIfMoved(captionRect);
+
+ setLogicalHeight(logicalHeight() + m_caption->logicalHeight() + m_caption->marginBefore() + m_caption->marginAfter());
+}
+
void RenderTable::layout()
{
ASSERT(needsLayout());
@@ -367,14 +379,7 @@ void RenderTable::layout()
// FIXME: Collapse caption margin.
if (m_caption && m_caption->style()->captionSide() != CAPBOTTOM) {
- IntRect captionRect(m_caption->x(), m_caption->y(), m_caption->width(), m_caption->height());
-
- m_caption->setLogicalLocation(m_caption->marginStart(), logicalHeight());
- if (!selfNeedsLayout() && m_caption->checkForRepaintDuringLayout())
- m_caption->repaintDuringLayoutIfMoved(captionRect);
-
- setLogicalHeight(logicalHeight() + m_caption->logicalHeight() + m_caption->marginBefore() + m_caption->marginAfter());
-
+ adjustLogicalHeightForCaption();
if (logicalHeight() != oldTableLogicalTop) {
sectionMoved = true;
movedSectionLogicalTop = min(logicalHeight(), oldTableLogicalTop);
@@ -429,15 +434,8 @@ void RenderTable::layout()
setLogicalHeight(logicalHeight() + borderAndPaddingAfter);
- if (m_caption && m_caption->style()->captionSide() == CAPBOTTOM) {
- IntRect captionRect(m_caption->x(), m_caption->y(), m_caption->width(), m_caption->height());
-
- m_caption->setLogicalLocation(m_caption->marginStart(), logicalHeight());
- if (!selfNeedsLayout() && m_caption->checkForRepaintDuringLayout())
- m_caption->repaintDuringLayoutIfMoved(captionRect);
-
- setLogicalHeight(logicalHeight() + m_caption->logicalHeight() + m_caption->marginBefore() + m_caption->marginAfter());
- }
+ if (m_caption && m_caption->style()->captionSide() == CAPBOTTOM)
+ adjustLogicalHeightForCaption();
if (isPositioned())
computeLogicalHeight();
@@ -577,6 +575,10 @@ void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty)
}
m_currentBorder = 0;
}
+
+ // Paint outline.
+ if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
+ paintOutline(paintInfo.context, tx, ty, width(), height());
}
void RenderTable::subtractCaptionRect(IntRect& rect) const
diff --git a/Source/WebCore/rendering/RenderTable.h b/Source/WebCore/rendering/RenderTable.h
index b9a7bad..67a311c 100644
--- a/Source/WebCore/rendering/RenderTable.h
+++ b/Source/WebCore/rendering/RenderTable.h
@@ -243,6 +243,7 @@ private:
void subtractCaptionRect(IntRect&) const;
void recalcSections() const;
+ void adjustLogicalHeightForCaption();
mutable Vector<int> m_columnPos;
mutable Vector<ColumnStruct> m_columns;
diff --git a/Source/WebCore/rendering/RenderTableCell.cpp b/Source/WebCore/rendering/RenderTableCell.cpp
index 1593a5c..2293bac 100644
--- a/Source/WebCore/rendering/RenderTableCell.cpp
+++ b/Source/WebCore/rendering/RenderTableCell.cpp
@@ -300,7 +300,7 @@ void RenderTableCell::computeRectForRepaint(RenderBoxModelObject* repaintContain
RenderBlock::computeRectForRepaint(repaintContainer, r, fixed);
}
-int RenderTableCell::baselinePosition() const
+int RenderTableCell::cellBaselinePosition() const
{
// <http://www.w3.org/TR/2007/CR-CSS21-20070719/tables.html#height-layout>: The baseline of a cell is the baseline of
// the first in-flow line box in the cell, or the first in-flow table-row in the cell, whichever comes first. If there
@@ -1014,13 +1014,12 @@ void RenderTableCell::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
int w = width();
int h = height();
- if (style()->boxShadow())
- paintBoxShadow(paintInfo.context, tx, ty, w, h, style(), Normal);
+ paintBoxShadow(paintInfo.context, tx, ty, w, h, style(), Normal);
// Paint our cell background.
paintBackgroundsBehindCell(paintInfo, tx, ty, this);
- if (style()->boxShadow())
- paintBoxShadow(paintInfo.context, tx, ty, w, h, style(), Inset);
+
+ paintBoxShadow(paintInfo.context, tx, ty, w, h, style(), Inset);
if (!style()->hasBorder() || tableElt->collapseBorders())
return;
diff --git a/Source/WebCore/rendering/RenderTableCell.h b/Source/WebCore/rendering/RenderTableCell.h
index 5b5992a..cfdb739 100644
--- a/Source/WebCore/rendering/RenderTableCell.h
+++ b/Source/WebCore/rendering/RenderTableCell.h
@@ -98,7 +98,7 @@ public:
void paintBackgroundsBehindCell(PaintInfo&, int tx, int ty, RenderObject* backgroundObject);
- int baselinePosition() const;
+ int cellBaselinePosition() const;
void setIntrinsicPaddingBefore(int p) { m_intrinsicPaddingBefore = p; }
void setIntrinsicPaddingAfter(int p) { m_intrinsicPaddingAfter = p; }
diff --git a/Source/WebCore/rendering/RenderTableSection.cpp b/Source/WebCore/rendering/RenderTableSection.cpp
index f20c236..3d46ece 100644
--- a/Source/WebCore/rendering/RenderTableSection.cpp
+++ b/Source/WebCore/rendering/RenderTableSection.cpp
@@ -400,7 +400,7 @@ int RenderTableSection::calcRowLogicalHeight()
// find out the baseline
EVerticalAlign va = cell->style()->verticalAlign();
if (va == BASELINE || va == TEXT_BOTTOM || va == TEXT_TOP || va == SUPER || va == SUB) {
- int b = cell->baselinePosition();
+ int b = cell->cellBaselinePosition();
if (b > cell->borderBefore() + cell->paddingBefore()) {
baseline = max(baseline, b - cell->intrinsicPaddingBefore());
bdesc = max(bdesc, m_rowPos[indx] + ch - (b - cell->intrinsicPaddingBefore()));
@@ -655,7 +655,7 @@ int RenderTableSection::layoutRows(int toAdd)
// If the baseline moved, we may have to update the data for our row. Find out the new baseline.
EVerticalAlign va = cell->style()->verticalAlign();
if (va == BASELINE || va == TEXT_BOTTOM || va == TEXT_TOP || va == SUPER || va == SUB) {
- int b = cell->baselinePosition();
+ int b = cell->cellBaselinePosition();
if (b > cell->borderBefore() + cell->paddingBefore())
m_grid[r].baseline = max(m_grid[r].baseline, b);
}
@@ -672,7 +672,7 @@ int RenderTableSection::layoutRows(int toAdd)
case TEXT_TOP:
case TEXT_BOTTOM:
case BASELINE: {
- int b = cell->baselinePosition();
+ int b = cell->cellBaselinePosition();
if (b > cell->borderBefore() + cell->paddingBefore())
intrinsicPaddingBefore = getBaseline(r) - (b - oldIntrinsicPaddingBefore);
break;
diff --git a/Source/WebCore/rendering/RenderText.cpp b/Source/WebCore/rendering/RenderText.cpp
index 1b05af2..d4f4166 100644
--- a/Source/WebCore/rendering/RenderText.cpp
+++ b/Source/WebCore/rendering/RenderText.cpp
@@ -506,15 +506,19 @@ IntRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, int* e
int height = box->root()->selectionHeight();
int top = box->root()->selectionTop();
- int left = box->positionForOffset(caretOffset);
+ // Go ahead and round left to snap it to the nearest pixel.
+ float left = box->positionForOffset(caretOffset);
// Distribute the caret's width to either side of the offset.
int caretWidthLeftOfOffset = caretWidth / 2;
left -= caretWidthLeftOfOffset;
int caretWidthRightOfOffset = caretWidth - caretWidthLeftOfOffset;
- int rootLeft = box->root()->logicalLeft();
- int rootRight = rootLeft + box->root()->logicalWidth();
+ left = roundf(left);
+
+ float rootLeft = box->root()->logicalLeft();
+ float rootRight = box->root()->logicalRight();
+
// FIXME: should we use the width of the root inline box or the
// width of the containing block for this?
if (extraWidthToEndOfLine)
@@ -522,14 +526,14 @@ IntRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, int* e
RenderBlock* cb = containingBlock();
RenderStyle* cbStyle = cb->style();
- int leftEdge;
- int rightEdge;
+ float leftEdge;
+ float rightEdge;
if (style()->autoWrap()) {
leftEdge = cb->logicalLeft();
rightEdge = cb->logicalRight();
} else {
- leftEdge = min(cb->logicalLeft(), rootLeft);
- rightEdge = max(cb->logicalRight(), rootRight);
+ leftEdge = min(static_cast<float>(cb->logicalLeft()), rootLeft);
+ rightEdge = max(static_cast<float>(cb->logicalRight()), rootRight);
}
bool rightAligned = false;
@@ -560,7 +564,7 @@ IntRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, int* e
return style()->isHorizontalWritingMode() ? IntRect(left, top, caretWidth, height) : IntRect(top, left, height, caretWidth);
}
-ALWAYS_INLINE int RenderText::widthFromCache(const Font& f, int start, int len, int xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
+ALWAYS_INLINE float RenderText::widthFromCache(const Font& f, int start, int len, float xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
{
if (style()->hasTextCombine()) {
const RenderCombineText* combineText = toRenderCombineText(this);
@@ -569,9 +573,9 @@ ALWAYS_INLINE int RenderText::widthFromCache(const Font& f, int start, int len,
}
if (f.isFixedPitch() && !f.isSmallCaps() && m_isAllASCII) {
- int monospaceCharacterWidth = f.spaceWidth();
- int tabWidth = allowTabs() ? monospaceCharacterWidth * 8 : 0;
- int w = 0;
+ float monospaceCharacterWidth = f.spaceWidth();
+ float tabWidth = allowTabs() ? monospaceCharacterWidth * 8 : 0;
+ float w = 0;
bool isSpace;
bool previousCharWasSpace = true; // FIXME: Preserves historical behavior, but seems wrong for start > 0.
ASSERT(m_text);
@@ -583,7 +587,7 @@ ALWAYS_INLINE int RenderText::widthFromCache(const Font& f, int start, int len,
w += monospaceCharacterWidth;
isSpace = true;
} else if (c == '\t') {
- w += tabWidth ? tabWidth - ((xPos + w) % tabWidth) : monospaceCharacterWidth;
+ w += tabWidth ? tabWidth - fmodf(xPos + w, tabWidth) : monospaceCharacterWidth;
isSpace = true;
} else
isSpace = false;
@@ -601,12 +605,12 @@ ALWAYS_INLINE int RenderText::widthFromCache(const Font& f, int start, int len,
return f.width(TextRun(text()->characters() + start, len, allowTabs(), xPos), fallbackFonts, glyphOverflow);
}
-void RenderText::trimmedPrefWidths(int leadWidth,
- int& beginMinW, bool& beginWS,
- int& endMinW, bool& endWS,
+void RenderText::trimmedPrefWidths(float leadWidth,
+ float& beginMinW, bool& beginWS,
+ float& endMinW, bool& endWS,
bool& hasBreakableChar, bool& hasBreak,
- int& beginMaxW, int& endMaxW,
- int& minW, int& maxW, bool& stripFrontSpaces)
+ float& beginMaxW, float& endMaxW,
+ float& minW, float& maxW, bool& stripFrontSpaces)
{
bool collapseWhiteSpace = style()->collapseWhiteSpace();
if (!collapseWhiteSpace)
@@ -646,7 +650,7 @@ void RenderText::trimmedPrefWidths(int leadWidth,
const Font& f = style()->font(); // FIXME: This ignores first-line.
if (stripFrontSpaces) {
const UChar space = ' ';
- int spaceWidth = f.width(TextRun(&space, 1));
+ float spaceWidth = f.width(TextRun(&space, 1));
maxW -= spaceWidth;
} else
maxW += f.wordSpacing();
@@ -695,7 +699,7 @@ static inline bool isSpaceAccordingToStyle(UChar c, RenderStyle* style)
return c == ' ' || (c == noBreakSpace && style->nbspMode() == SPACE);
}
-int RenderText::minPreferredLogicalWidth() const
+float RenderText::minLogicalWidth() const
{
if (preferredLogicalWidthsDirty())
const_cast<RenderText*>(this)->computePreferredLogicalWidths(0);
@@ -703,7 +707,7 @@ int RenderText::minPreferredLogicalWidth() const
return m_minWidth;
}
-int RenderText::maxPreferredLogicalWidth() const
+float RenderText::maxLogicalWidth() const
{
if (preferredLogicalWidthsDirty())
const_cast<RenderText*>(this)->computePreferredLogicalWidths(0);
@@ -711,7 +715,7 @@ int RenderText::maxPreferredLogicalWidth() const
return m_maxWidth;
}
-void RenderText::computePreferredLogicalWidths(int leadWidth)
+void RenderText::computePreferredLogicalWidths(float leadWidth)
{
HashSet<const SimpleFontData*> fallbackFonts;
GlyphOverflow glyphOverflow;
@@ -720,7 +724,7 @@ void RenderText::computePreferredLogicalWidths(int leadWidth)
m_knownToHaveNoOverflowAndNoFallbackFonts = true;
}
-void RenderText::computePreferredLogicalWidths(int leadWidth, HashSet<const SimpleFontData*>& fallbackFonts, GlyphOverflow& glyphOverflow)
+void RenderText::computePreferredLogicalWidths(float leadWidth, HashSet<const SimpleFontData*>& fallbackFonts, GlyphOverflow& glyphOverflow)
{
ASSERT(m_hasTab || preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflowAndNoFallbackFonts);
@@ -732,8 +736,8 @@ void RenderText::computePreferredLogicalWidths(int leadWidth, HashSet<const Simp
if (isBR())
return;
- int currMinWidth = 0;
- int currMaxWidth = 0;
+ float currMinWidth = 0;
+ float currMaxWidth = 0;
m_hasBreakableChar = false;
m_hasBreak = false;
m_hasTab = false;
@@ -741,9 +745,10 @@ void RenderText::computePreferredLogicalWidths(int leadWidth, HashSet<const Simp
m_hasEndWS = false;
const Font& f = style()->font(); // FIXME: This ignores first-line.
- int wordSpacing = style()->wordSpacing();
+ float wordSpacing = style()->wordSpacing();
int len = textLength();
const UChar* txt = characters();
+ LazyLineBreakIterator breakIterator(txt, len);
bool needsWordSpacing = false;
bool ignoringSpaces = false;
bool isSpace = false;
@@ -803,7 +808,7 @@ void RenderText::computePreferredLogicalWidths(int leadWidth, HashSet<const Simp
continue;
}
- bool hasBreak = breakAll || isBreakable(txt, i, len, nextBreakable, breakNBSP);
+ bool hasBreak = breakAll || isBreakable(breakIterator, i, nextBreakable, breakNBSP);
bool betweenWords = true;
int j = i;
while (c != '\n' && !isSpaceAccordingToStyle(c, style()) && c != '\t' && c != softHyphen) {
@@ -811,7 +816,7 @@ void RenderText::computePreferredLogicalWidths(int leadWidth, HashSet<const Simp
if (j == len)
break;
c = txt[j];
- if (isBreakable(txt, j, len, nextBreakable, breakNBSP))
+ if (isBreakable(breakIterator, j, nextBreakable, breakNBSP))
break;
if (breakAll) {
betweenWords = false;
@@ -821,7 +826,7 @@ void RenderText::computePreferredLogicalWidths(int leadWidth, HashSet<const Simp
int wordLen = j - i;
if (wordLen) {
- int w = widthFromCache(f, i, wordLen, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow);
+ float w = widthFromCache(f, i, wordLen, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow);
if (firstGlyphLeftOverflow < 0)
firstGlyphLeftOverflow = glyphOverflow.left;
currMinWidth += w;
@@ -933,17 +938,17 @@ bool RenderText::containsOnlyWhitespace(unsigned from, unsigned len) const
return currPos >= (from + len);
}
-IntPoint RenderText::firstRunOrigin() const
+FloatPoint RenderText::firstRunOrigin() const
{
return IntPoint(firstRunX(), firstRunY());
}
-int RenderText::firstRunX() const
+float RenderText::firstRunX() const
{
return m_firstTextBox ? m_firstTextBox->m_x : 0;
}
-int RenderText::firstRunY() const
+float RenderText::firstRunY() const
{
return m_firstTextBox ? m_firstTextBox->m_y : 0;
}
@@ -1240,7 +1245,7 @@ void RenderText::positionLineBox(InlineBox* box)
m_containsReversedText |= !s->isLeftToRightDirection();
}
-unsigned RenderText::width(unsigned from, unsigned len, int xPos, bool firstLine, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
+float RenderText::width(unsigned from, unsigned len, float xPos, bool firstLine, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
{
if (from >= textLength())
return 0;
@@ -1251,13 +1256,13 @@ unsigned RenderText::width(unsigned from, unsigned len, int xPos, bool firstLine
return width(from, len, style(firstLine)->font(), xPos, fallbackFonts, glyphOverflow);
}
-unsigned RenderText::width(unsigned from, unsigned len, const Font& f, int xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
+float RenderText::width(unsigned from, unsigned len, const Font& f, float xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
{
ASSERT(from + len <= textLength());
if (!characters())
return 0;
- int w;
+ float w;
if (&f == &style()->font()) {
if (!style()->preserveNewline() && !from && len == textLength()) {
if (fallbackFonts) {
@@ -1269,7 +1274,7 @@ unsigned RenderText::width(unsigned from, unsigned len, const Font& f, int xPos,
}
w = m_maxWidth;
} else
- w = maxPreferredLogicalWidth();
+ w = maxLogicalWidth();
} else
w = widthFromCache(f, from, len, xPos, fallbackFonts, glyphOverflow);
} else
@@ -1285,8 +1290,8 @@ IntRect RenderText::linesBoundingBox() const
ASSERT(!firstTextBox() == !lastTextBox()); // Either both are null or both exist.
if (firstTextBox() && lastTextBox()) {
// Return the width of the minimal left side and the maximal right side.
- int logicalLeftSide = 0;
- int logicalRightSide = 0;
+ float logicalLeftSide = 0;
+ float logicalRightSide = 0;
for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) {
if (curr == firstTextBox() || curr->logicalLeft() < logicalLeftSide)
logicalLeftSide = curr->logicalLeft();
@@ -1296,11 +1301,11 @@ IntRect RenderText::linesBoundingBox() const
bool isHorizontal = style()->isHorizontalWritingMode();
- int x = isHorizontal ? logicalLeftSide : firstTextBox()->x();
- int y = isHorizontal ? firstTextBox()->y() : logicalLeftSide;
- int width = isHorizontal ? logicalRightSide - logicalLeftSide : lastTextBox()->logicalBottom() - x;
- int height = isHorizontal ? lastTextBox()->logicalBottom() - y : logicalRightSide - logicalLeftSide;
- result = IntRect(x, y, width, height);
+ float x = isHorizontal ? logicalLeftSide : firstTextBox()->x();
+ float y = isHorizontal ? firstTextBox()->y() : logicalLeftSide;
+ float width = isHorizontal ? logicalRightSide - logicalLeftSide : lastTextBox()->logicalBottom() - x;
+ float height = isHorizontal ? lastTextBox()->logicalBottom() - y : logicalRightSide - logicalLeftSide;
+ result = enclosingIntRect(FloatRect(x, y, width, height));
}
return result;
diff --git a/Source/WebCore/rendering/RenderText.h b/Source/WebCore/rendering/RenderText.h
index 964a1d3..b88590c 100644
--- a/Source/WebCore/rendering/RenderText.h
+++ b/Source/WebCore/rendering/RenderText.h
@@ -71,24 +71,24 @@ public:
unsigned textLength() const { return m_text.length(); } // non virtual implementation of length()
void positionLineBox(InlineBox*);
- virtual unsigned width(unsigned from, unsigned len, const Font&, int xPos, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
- virtual unsigned width(unsigned from, unsigned len, int xPos, bool firstLine = false, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
+ virtual float width(unsigned from, unsigned len, const Font&, float xPos, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
+ virtual float width(unsigned from, unsigned len, float xPos, bool firstLine = false, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
- virtual int minPreferredLogicalWidth() const;
- virtual int maxPreferredLogicalWidth() const;
+ float minLogicalWidth() const;
+ float maxLogicalWidth() const;
- void trimmedPrefWidths(int leadWidth,
- int& beginMinW, bool& beginWS,
- int& endMinW, bool& endWS,
+ void trimmedPrefWidths(float leadWidth,
+ float& beginMinW, bool& beginWS,
+ float& endMinW, bool& endWS,
bool& hasBreakableChar, bool& hasBreak,
- int& beginMaxW, int& endMaxW,
- int& minW, int& maxW, bool& stripFrontSpaces);
+ float& beginMaxW, float& endMaxW,
+ float& minW, float& maxW, bool& stripFrontSpaces);
virtual IntRect linesBoundingBox() const;
- IntPoint firstRunOrigin() const;
- int firstRunX() const;
- int firstRunY() const;
+ FloatPoint firstRunOrigin() const;
+ float firstRunX() const;
+ float firstRunY() const;
void setText(PassRefPtr<StringImpl>, bool force = false);
void setTextWithOffset(PassRefPtr<StringImpl>, unsigned offset, unsigned len, bool force = false);
@@ -122,7 +122,7 @@ public:
void checkConsistency() const;
- virtual void computePreferredLogicalWidths(int leadWidth);
+ virtual void computePreferredLogicalWidths(float leadWidth);
bool isAllCollapsibleWhitespace();
protected:
@@ -135,7 +135,7 @@ protected:
virtual InlineTextBox* createTextBox(); // Subclassed by SVG.
private:
- void computePreferredLogicalWidths(int leadWidth, HashSet<const SimpleFontData*>& fallbackFonts, GlyphOverflow&);
+ void computePreferredLogicalWidths(float leadWidth, HashSet<const SimpleFontData*>& fallbackFonts, GlyphOverflow&);
// Make length() private so that callers that have a RenderText*
// will use the more efficient textLength() instead, while
@@ -148,22 +148,22 @@ private:
void deleteTextBoxes();
bool containsOnlyWhitespace(unsigned from, unsigned len) const;
- int widthFromCache(const Font&, int start, int len, int xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow*) const;
+ float widthFromCache(const Font&, int start, int len, float xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow*) const;
bool isAllASCII() const { return m_isAllASCII; }
void updateNeedsTranscoding();
inline void transformText(String&) const;
- int m_minWidth; // here to minimize padding in 64-bit.
+ float m_minWidth; // here to minimize padding in 64-bit.
String m_text;
InlineTextBox* m_firstTextBox;
InlineTextBox* m_lastTextBox;
- int m_maxWidth;
- int m_beginMinWidth;
- int m_endMinWidth;
+ float m_maxWidth;
+ float m_beginMinWidth;
+ float m_endMinWidth;
bool m_hasBreakableChar : 1; // Whether or not we can be broken into multiple lines.
bool m_hasBreak : 1; // Whether or not we have a hard break (e.g., <pre> with '\n').
diff --git a/Source/WebCore/rendering/RenderTextControl.cpp b/Source/WebCore/rendering/RenderTextControl.cpp
index 72b20ec..8149f6c 100644
--- a/Source/WebCore/rendering/RenderTextControl.cpp
+++ b/Source/WebCore/rendering/RenderTextControl.cpp
@@ -74,7 +74,6 @@ static Color disabledTextColor(const Color& textColor, const Color& backgroundCo
RenderTextControl::RenderTextControl(Node* node, bool placeholderVisible)
: RenderBlock(node)
, m_placeholderVisible(placeholderVisible)
- , m_wasChangedSinceLastChangeEvent(false)
, m_lastChangeWasUserEdit(false)
{
}
@@ -249,7 +248,7 @@ void setSelectionRange(Node* node, int start, int end)
// startPosition and endPosition can be null position for example when
// "-webkit-user-select: none" style attribute is specified.
if (startPosition.isNotNull() && endPosition.isNotNull()) {
- ASSERT(startPosition.deepEquivalent().node()->shadowAncestorNode() == node && endPosition.deepEquivalent().node()->shadowAncestorNode() == node);
+ ASSERT(startPosition.deepEquivalent().deprecatedNode()->shadowAncestorNode() == node && endPosition.deepEquivalent().deprecatedNode()->shadowAncestorNode() == node);
}
VisibleSelection newSelection = VisibleSelection(startPosition, endPosition);
@@ -321,7 +320,7 @@ PassRefPtr<Range> RenderTextControl::selection(int start, int end) const
VisiblePosition RenderTextControl::visiblePositionForIndex(int index) const
{
if (index <= 0)
- return VisiblePosition(m_innerText.get(), 0, DOWNSTREAM);
+ return VisiblePosition(Position(m_innerText.get(), 0, Position::PositionIsOffsetInAnchor), DOWNSTREAM);
ExceptionCode ec = 0;
RefPtr<Range> range = Range::create(document());
range->selectNodeContents(m_innerText.get(), ec);
@@ -332,26 +331,25 @@ VisiblePosition RenderTextControl::visiblePositionForIndex(int index) const
ASSERT(!ec);
int endOffset = it.range()->endOffset(ec);
ASSERT(!ec);
- return VisiblePosition(endContainer, endOffset, UPSTREAM);
+ return VisiblePosition(Position(endContainer, endOffset, Position::PositionIsOffsetInAnchor), UPSTREAM);
}
int RenderTextControl::indexForVisiblePosition(const VisiblePosition& pos) const
{
Position indexPosition = pos.deepEquivalent();
- if (!isSelectableElement(indexPosition.node()))
+ if (!isSelectableElement(indexPosition.deprecatedNode()))
return 0;
ExceptionCode ec = 0;
RefPtr<Range> range = Range::create(document());
range->setStart(m_innerText.get(), 0, ec);
ASSERT(!ec);
- range->setEnd(indexPosition.node(), indexPosition.deprecatedEditingOffset(), ec);
+ range->setEnd(indexPosition.deprecatedNode(), indexPosition.deprecatedEditingOffset(), ec);
ASSERT(!ec);
return TextIterator::rangeLength(range.get());
}
void RenderTextControl::subtreeHasChanged()
{
- m_wasChangedSinceLastChangeEvent = true;
m_lastChangeWasUserEdit = true;
}
@@ -544,7 +542,7 @@ float RenderTextControl::getAvgCharWidth(AtomicString family)
return roundf(style()->font().primaryFont()->avgCharWidth());
const UChar ch = '0';
- return style()->font().floatWidth(TextRun(&ch, 1, false, 0, 0, TextRun::AllowTrailingExpansion, false, false, false));
+ return style()->font().width(TextRun(&ch, 1, false, 0, 0, TextRun::AllowTrailingExpansion, false));
}
float RenderTextControl::scaleEmToUnits(int x) const
@@ -639,7 +637,7 @@ void RenderTextControl::paintPlaceholder(PaintInfo& paintInfo, int tx, int ty)
paintInfo.context->setFillColor(placeholderStyle->visitedDependentColor(CSSPropertyColor), placeholderStyle->colorSpace());
String placeholderText = static_cast<HTMLTextFormControlElement*>(node())->strippedPlaceholder();
- TextRun textRun(placeholderText.characters(), placeholderText.length(), false, 0, 0, TextRun::AllowTrailingExpansion, !placeholderStyle->isLeftToRightDirection(), placeholderStyle->unicodeBidi() == Override, false, false);
+ TextRun textRun(placeholderText.characters(), placeholderText.length(), false, 0, 0, TextRun::AllowTrailingExpansion, !placeholderStyle->isLeftToRightDirection(), placeholderStyle->unicodeBidi() == Override);
RenderBox* textRenderer = innerTextElement() ? innerTextElement()->renderBox() : 0;
if (textRenderer) {
diff --git a/Source/WebCore/rendering/RenderTextControl.h b/Source/WebCore/rendering/RenderTextControl.h
index fdb7fdc..0c30ed6 100644
--- a/Source/WebCore/rendering/RenderTextControl.h
+++ b/Source/WebCore/rendering/RenderTextControl.h
@@ -34,8 +34,7 @@ class RenderTextControl : public RenderBlock {
public:
virtual ~RenderTextControl();
- bool wasChangedSinceLastChangeEvent() const { return m_wasChangedSinceLastChangeEvent; }
- void setChangedSinceLastChangeEvent(bool wasChangedSinceLastChangeEvent) { m_wasChangedSinceLastChangeEvent = wasChangedSinceLastChangeEvent; }
+ HTMLElement* innerTextElement() const;
bool lastChangeWasUserEdit() const { return m_lastChangeWasUserEdit; }
void setLastChangeWasUserEdit(bool lastChangeWasUserEdit);
@@ -83,9 +82,6 @@ protected:
virtual void updateFromElement();
virtual void computeLogicalHeight();
- friend class TextIterator;
- HTMLElement* innerTextElement() const;
-
bool m_placeholderVisible;
private:
@@ -116,7 +112,6 @@ private:
void paintPlaceholder(PaintInfo&, int tx, int ty);
- bool m_wasChangedSinceLastChangeEvent;
bool m_lastChangeWasUserEdit;
RefPtr<TextControlInnerTextElement> m_innerText;
};
diff --git a/Source/WebCore/rendering/RenderTextControlMultiLine.cpp b/Source/WebCore/rendering/RenderTextControlMultiLine.cpp
index cf32f68..ea2be5b 100644
--- a/Source/WebCore/rendering/RenderTextControlMultiLine.cpp
+++ b/Source/WebCore/rendering/RenderTextControlMultiLine.cpp
@@ -49,6 +49,7 @@ void RenderTextControlMultiLine::subtreeHasChanged()
{
RenderTextControl::subtreeHasChanged();
HTMLTextAreaElement* textArea = static_cast<HTMLTextAreaElement*>(node());
+ textArea->setChangedSinceLastFormControlChangeEvent(true);
textArea->setFormControlValueMatchesRenderer(false);
textArea->setNeedsValidityCheck();
diff --git a/Source/WebCore/rendering/RenderTextControlSingleLine.cpp b/Source/WebCore/rendering/RenderTextControlSingleLine.cpp
index de8fb0d..8b98335 100644
--- a/Source/WebCore/rendering/RenderTextControlSingleLine.cpp
+++ b/Source/WebCore/rendering/RenderTextControlSingleLine.cpp
@@ -51,6 +51,23 @@ namespace WebCore {
using namespace HTMLNames;
+VisiblePosition RenderTextControlInnerBlock::positionForPoint(const IntPoint& point)
+{
+ IntPoint contentsPoint(point);
+
+ // Multiline text controls have the scroll on shadowAncestorNode, so we need to take that
+ // into account here.
+ if (m_multiLine) {
+ RenderTextControl* renderer = toRenderTextControl(node()->shadowAncestorNode()->renderer());
+ if (renderer->hasOverflowClip())
+ contentsPoint += renderer->layer()->scrolledContentOffset();
+ }
+
+ return RenderBlock::positionForPoint(contentsPoint);
+}
+
+// ----------------------------
+
RenderTextControlSingleLine::RenderTextControlSingleLine(Node* node, bool placeholderVisible)
: RenderTextControl(node, placeholderVisible)
, m_searchPopupIsVisible(false)
@@ -164,9 +181,13 @@ void RenderTextControlSingleLine::hidePopup()
void RenderTextControlSingleLine::subtreeHasChanged()
{
- bool wasChanged = wasChangedSinceLastChangeEvent();
RenderTextControl::subtreeHasChanged();
+ ASSERT(node()->isElementNode());
+ Element* element = static_cast<Element*>(node());
+ bool wasChanged = element->wasChangedSinceLastFormControlChangeEvent();
+ element->setChangedSinceLastFormControlChangeEvent(true);
+
InputElement* input = inputElement();
// We don't need to call sanitizeUserInputValue() function here because
// InputElement::handleBeforeTextInsertedEvent() has already called
@@ -174,7 +195,7 @@ void RenderTextControlSingleLine::subtreeHasChanged()
// sanitizeValue() is needed because IME input doesn't dispatch BeforeTextInsertedEvent.
String value = text();
if (input->isAcceptableValue(value))
- input->setValueFromRenderer(input->sanitizeValue(value));
+ input->setValueFromRenderer(input->sanitizeValue(input->convertFromVisibleValue(value)));
if (node()->isHTMLElement()) {
// Recalc for :invalid and hasUnacceptableValue() change.
static_cast<HTMLInputElement*>(input)->setNeedsStyleRecalc();
@@ -432,6 +453,9 @@ void RenderTextControlSingleLine::styleDidChange(StyleDifference diff, const Ren
if (RenderObject* spinRenderer = m_outerSpinButton ? m_outerSpinButton->renderer() : 0)
spinRenderer->setStyle(createOuterSpinButtonStyle());
+ if (RenderObject* spinRenderer = m_innerSpinButton ? m_innerSpinButton->renderer() : 0)
+ spinRenderer->setStyle(createInnerSpinButtonStyle());
+
#if ENABLE(INPUT_SPEECH)
if (RenderObject* speechRenderer = m_speechButton ? m_speechButton->renderer() : 0)
speechRenderer->setStyle(createSpeechButtonStyle());
@@ -609,9 +633,13 @@ void RenderTextControlSingleLine::adjustControlHeightBasedOnLineHeight(int lineH
void RenderTextControlSingleLine::createSubtreeIfNeeded()
{
- bool createSubtree = inputElement()->isSearchField();
- if (!createSubtree) {
- RenderTextControl::createSubtreeIfNeeded(m_innerBlock.get());
+ if (inputElement()->isSearchField()) {
+ if (!m_innerBlock) {
+ // Create the inner block element
+ m_innerBlock = TextControlInnerElement::create(toHTMLElement(node()));
+ m_innerBlock->attachInnerElement(node(), createInnerBlockStyle(style()), renderArena());
+ }
+
#if ENABLE(INPUT_SPEECH)
if (inputElement()->isSpeechEnabled() && !m_speechButton) {
// Create the speech button element.
@@ -619,52 +647,42 @@ void RenderTextControlSingleLine::createSubtreeIfNeeded()
m_speechButton->attachInnerElement(node(), createSpeechButtonStyle(), renderArena());
}
#endif
- bool hasSpinButton = inputElement()->hasSpinButton();
- if (hasSpinButton && !m_innerSpinButton) {
- m_innerSpinButton = SpinButtonElement::create(toHTMLElement(node()));
- m_innerSpinButton->attachInnerElement(node(), createInnerSpinButtonStyle(), renderArena());
- }
- if (hasSpinButton && !m_outerSpinButton) {
- m_outerSpinButton = SpinButtonElement::create(toHTMLElement(node()));
- m_outerSpinButton->attachInnerElement(node(), createOuterSpinButtonStyle(), renderArena());
- }
- return;
- }
-
- if (!m_innerBlock) {
- // Create the inner block element
- m_innerBlock = TextControlInnerElement::create(toHTMLElement(node()));
- m_innerBlock->attachInnerElement(node(), createInnerBlockStyle(style()), renderArena());
- }
-#if ENABLE(INPUT_SPEECH)
- if (inputElement()->isSpeechEnabled() && !m_speechButton) {
- // Create the speech button element.
- m_speechButton = InputFieldSpeechButtonElement::create(toHTMLElement(node()));
- m_speechButton->attachInnerElement(node(), createSpeechButtonStyle(), renderArena());
- }
-#endif
- if (inputElement()->hasSpinButton() && !m_outerSpinButton) {
- m_outerSpinButton = SpinButtonElement::create(toHTMLElement(node()));
- m_outerSpinButton->attachInnerElement(node(), createOuterSpinButtonStyle(), renderArena());
- }
- if (inputElement()->isSearchField()) {
if (!m_resultsButton) {
// Create the search results button element.
m_resultsButton = SearchFieldResultsButtonElement::create(document());
m_resultsButton->attachInnerElement(m_innerBlock.get(), createResultsButtonStyle(m_innerBlock->renderer()->style()), renderArena());
}
- }
- // Create innerText element before adding the other buttons.
- RenderTextControl::createSubtreeIfNeeded(m_innerBlock.get());
+ // Create innerText element before adding the other buttons.
+ RenderTextControl::createSubtreeIfNeeded(m_innerBlock.get());
- if (inputElement()->isSearchField()) {
if (!m_cancelButton) {
// Create the cancel button element.
m_cancelButton = SearchFieldCancelButtonElement::create(document());
m_cancelButton->attachInnerElement(m_innerBlock.get(), createCancelButtonStyle(m_innerBlock->renderer()->style()), renderArena());
}
+ } else {
+ RenderTextControl::createSubtreeIfNeeded(0);
+
+#if ENABLE(INPUT_SPEECH)
+ if (inputElement()->isSpeechEnabled() && !m_speechButton) {
+ // Create the speech button element.
+ m_speechButton = InputFieldSpeechButtonElement::create(toHTMLElement(node()));
+ m_speechButton->attachInnerElement(node(), createSpeechButtonStyle(), renderArena());
+ }
+#endif
+
+ bool hasSpinButton = inputElement()->hasSpinButton();
+
+ if (hasSpinButton && !m_innerSpinButton) {
+ m_innerSpinButton = SpinButtonElement::create(toHTMLElement(node()));
+ m_innerSpinButton->attachInnerElement(node(), createInnerSpinButtonStyle(), renderArena());
+ }
+ if (hasSpinButton && !m_outerSpinButton) {
+ m_outerSpinButton = SpinButtonElement::create(toHTMLElement(node()));
+ m_outerSpinButton->attachInnerElement(node(), createOuterSpinButtonStyle(), renderArena());
+ }
}
}
@@ -733,7 +751,7 @@ PassRefPtr<RenderStyle> RenderTextControlSingleLine::createInnerBlockStyle(const
RefPtr<RenderStyle> innerBlockStyle = RenderStyle::create();
innerBlockStyle->inheritFrom(startStyle);
- innerBlockStyle->setDisplay(inputElement()->hasSpinButton() ? INLINE_BLOCK : BLOCK);
+ innerBlockStyle->setDisplay(BLOCK);
innerBlockStyle->setDirection(LTR);
// We don't want the shadow dom to be editable, so we set this block to read-only in case the input itself is editable.
@@ -951,7 +969,7 @@ int RenderTextControlSingleLine::clientPaddingLeft() const
int padding = paddingLeft();
if (RenderBox* resultsRenderer = m_resultsButton ? m_resultsButton->renderBox() : 0)
- padding += resultsRenderer->width();
+ padding += resultsRenderer->width() + resultsRenderer->marginLeft() + resultsRenderer->paddingLeft() + resultsRenderer->marginRight() + resultsRenderer->paddingRight();
return padding;
}
@@ -961,7 +979,7 @@ int RenderTextControlSingleLine::clientPaddingRight() const
int padding = paddingRight();
if (RenderBox* cancelRenderer = m_cancelButton ? m_cancelButton->renderBox() : 0)
- padding += cancelRenderer->width();
+ padding += cancelRenderer->width() + cancelRenderer->marginLeft() + cancelRenderer->paddingLeft() + cancelRenderer->marginRight() + cancelRenderer->paddingRight();
return padding;
}
diff --git a/Source/WebCore/rendering/RenderTextControlSingleLine.h b/Source/WebCore/rendering/RenderTextControlSingleLine.h
index 6b99f59..18e5fc8 100644
--- a/Source/WebCore/rendering/RenderTextControlSingleLine.h
+++ b/Source/WebCore/rendering/RenderTextControlSingleLine.h
@@ -174,6 +174,19 @@ inline RenderTextControlSingleLine* toRenderTextControlSingleLine(RenderObject*
// This will catch anyone doing an unnecessary cast.
void toRenderTextControlSingleLine(const RenderTextControlSingleLine*);
+// ----------------------------
+
+class RenderTextControlInnerBlock : public RenderBlock {
+public:
+ RenderTextControlInnerBlock(Node* node, bool isMultiLine) : RenderBlock(node), m_multiLine(isMultiLine) { }
+
+private:
+ virtual bool hasLineIfEmpty() const { return true; }
+ virtual VisiblePosition positionForPoint(const IntPoint&);
+
+ bool m_multiLine;
+};
+
}
#endif
diff --git a/Source/WebCore/rendering/RenderTheme.cpp b/Source/WebCore/rendering/RenderTheme.cpp
index e67ecfc..b68429c 100644
--- a/Source/WebCore/rendering/RenderTheme.cpp
+++ b/Source/WebCore/rendering/RenderTheme.cpp
@@ -541,12 +541,12 @@ String RenderTheme::formatMediaControlsRemainingTime(float currentTime, float du
return formatMediaControlsTime(currentTime - duration);
}
-IntPoint RenderTheme::volumeSliderOffsetFromMuteButton(Node* muteButton, const IntSize& size) const
+IntPoint RenderTheme::volumeSliderOffsetFromMuteButton(RenderBox* muteButtonBox, const IntSize& size) const
{
int y = -size.height();
- FloatPoint absPoint = muteButton->renderer()->localToAbsolute(FloatPoint(muteButton->renderBox()->offsetLeft(), y), true, true);
+ FloatPoint absPoint = muteButtonBox->localToAbsolute(FloatPoint(muteButtonBox->offsetLeft(), y), true, true);
if (absPoint.y() < 0)
- y = muteButton->renderBox()->height();
+ y = muteButtonBox->height();
return IntPoint(0, y);
}
diff --git a/Source/WebCore/rendering/RenderTheme.h b/Source/WebCore/rendering/RenderTheme.h
index e2b9c78..5021712 100644
--- a/Source/WebCore/rendering/RenderTheme.h
+++ b/Source/WebCore/rendering/RenderTheme.h
@@ -188,7 +188,7 @@ public:
virtual String formatMediaControlsRemainingTime(float currentTime, float duration) const;
// Returns the media volume slider container's offset from the mute button.
- virtual IntPoint volumeSliderOffsetFromMuteButton(Node*, const IntSize&) const;
+ virtual IntPoint volumeSliderOffsetFromMuteButton(RenderBox*, const IntSize&) const;
#endif
#if ENABLE(METER_TAG)
diff --git a/Source/WebCore/rendering/RenderThemeChromiumLinux.cpp b/Source/WebCore/rendering/RenderThemeChromiumLinux.cpp
index 3a2874d..72ea7cb 100644
--- a/Source/WebCore/rendering/RenderThemeChromiumLinux.cpp
+++ b/Source/WebCore/rendering/RenderThemeChromiumLinux.cpp
@@ -227,6 +227,7 @@ bool RenderThemeChromiumLinux::paintButton(RenderObject* o, const PaintInfo& i,
{
PlatformBridge::ThemePaintExtraParams extraParams;
extraParams.button.isDefault = isDefault(o);
+ extraParams.button.hasBorder = true;
extraParams.button.backgroundColor = defaultButtonBackgroundColor;
if (o->hasBackground())
extraParams.button.backgroundColor = o->style()->visitedDependentColor(CSSPropertyBackgroundColor).rgb();
@@ -260,12 +261,19 @@ bool RenderThemeChromiumLinux::paintTextField(RenderObject* o, const PaintInfo&
bool RenderThemeChromiumLinux::paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& rect)
{
+ if (!o->isBox())
+ return false;
+
const int right = rect.x() + rect.width();
const int middle = rect.y() + rect.height() / 2;
PlatformBridge::ThemePaintExtraParams extraParams;
extraParams.menuList.arrowX = (o->style()->direction() == RTL) ? rect.x() + 7 : right - 13;
extraParams.menuList.arrowY = middle;
+ const RenderBox* box = toRenderBox(o);
+ // Match Chromium Win behaviour of showing all borders if any are shown.
+ extraParams.menuList.hasBorder = box->borderRight() || box->borderLeft() || box->borderTop() || box->borderBottom();
+ extraParams.menuList.hasBorderRadius = o->style()->hasBorderRadius();
extraParams.menuList.backgroundColor = SkColorSetRGB(0xdd, 0xdd, 0xdd);
if (o->hasBackground())
extraParams.menuList.backgroundColor = o->style()->visitedDependentColor(CSSPropertyBackgroundColor).rgb();
diff --git a/Source/WebCore/rendering/RenderThemeChromiumMac.h b/Source/WebCore/rendering/RenderThemeChromiumMac.h
index 80bbae4..4fd371f 100644
--- a/Source/WebCore/rendering/RenderThemeChromiumMac.h
+++ b/Source/WebCore/rendering/RenderThemeChromiumMac.h
@@ -45,7 +45,7 @@ protected:
virtual bool paintMediaVolumeSliderContainer(RenderObject*, const PaintInfo&, const IntRect&);
virtual bool paintMediaVolumeSliderTrack(RenderObject*, const PaintInfo&, const IntRect&);
virtual bool paintMediaVolumeSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
- virtual IntPoint volumeSliderOffsetFromMuteButton(Node*, const IntSize&) const;
+ virtual IntPoint volumeSliderOffsetFromMuteButton(RenderBox*, const IntSize&) const;
virtual bool usesMediaControlStatusDisplay() { return false; }
#endif
diff --git a/Source/WebCore/rendering/RenderThemeChromiumMac.mm b/Source/WebCore/rendering/RenderThemeChromiumMac.mm
index 10285ac..a7d59a9 100644
--- a/Source/WebCore/rendering/RenderThemeChromiumMac.mm
+++ b/Source/WebCore/rendering/RenderThemeChromiumMac.mm
@@ -155,9 +155,9 @@ bool RenderThemeChromiumMac::paintMediaSliderThumb(RenderObject* object, const P
return RenderMediaControlsChromium::paintMediaControlsPart(MediaSliderThumb, object, paintInfo, rect);
}
-IntPoint RenderThemeChromiumMac::volumeSliderOffsetFromMuteButton(Node* muteButton, const IntSize& size) const
+IntPoint RenderThemeChromiumMac::volumeSliderOffsetFromMuteButton(RenderBox* muteButtonBox, const IntSize& size) const
{
- return RenderTheme::volumeSliderOffsetFromMuteButton(muteButton, size);
+ return RenderTheme::volumeSliderOffsetFromMuteButton(muteButtonBox, size);
}
#endif
diff --git a/Source/WebCore/rendering/RenderThemeChromiumWin.cpp b/Source/WebCore/rendering/RenderThemeChromiumWin.cpp
index d538050..6f3be00 100644
--- a/Source/WebCore/rendering/RenderThemeChromiumWin.cpp
+++ b/Source/WebCore/rendering/RenderThemeChromiumWin.cpp
@@ -62,10 +62,15 @@ namespace WebCore {
static const int kStandardMenuListButtonWidth = 17;
namespace {
+// We must not create multiple ThemePainter instances.
class ThemePainter {
public:
ThemePainter(GraphicsContext* context, const IntRect& r)
{
+#ifndef NDEBUG
+ ASSERT(!s_hasInstance);
+ s_hasInstance = true;
+#endif
TransparencyWin::TransformMode transformMode = getTransformMode(context->getCTM());
m_helper.init(context, getLayerMode(context, transformMode), transformMode, r);
@@ -85,6 +90,9 @@ public:
~ThemePainter()
{
m_helper.composite();
+#ifndef NDEBUG
+ s_hasInstance = false;
+#endif
}
GraphicsContext* context() { return m_helper.context(); }
@@ -120,8 +128,15 @@ private:
}
TransparencyWin m_helper;
+#ifndef NDEBUG
+ static bool s_hasInstance;
+#endif
};
+#ifndef NDEBUG
+bool ThemePainter::s_hasInstance = false;
+#endif
+
} // namespace
static void getNonClientMetrics(NONCLIENTMETRICS* metrics)
@@ -707,23 +722,28 @@ bool RenderThemeChromiumWin::paintInnerSpinButton(RenderObject* object, const Pa
{
IntRect half = rect;
- half.setHeight(rect.height() / 2);
- const ThemeData& upThemeData = getThemeData(object, SpinButtonUp);
- ThemePainter upPainter(info.context, half);
- PlatformBridge::paintSpinButton(upPainter.context(),
- upThemeData.m_part,
- upThemeData.m_state,
- upThemeData.m_classicState,
- upPainter.drawRect());
-
- half.setY(rect.y() + rect.height() / 2);
- const ThemeData& downThemeData = getThemeData(object, SpinButtonDown);
- ThemePainter downPainter(info.context, half);
- PlatformBridge::paintSpinButton(downPainter.context(),
- downThemeData.m_part,
- downThemeData.m_state,
- downThemeData.m_classicState,
- downPainter.drawRect());
+ // Need explicit blocks to avoid to create multiple ThemePainter instances.
+ {
+ half.setHeight(rect.height() / 2);
+ const ThemeData& upThemeData = getThemeData(object, SpinButtonUp);
+ ThemePainter upPainter(info.context, half);
+ PlatformBridge::paintSpinButton(upPainter.context(),
+ upThemeData.m_part,
+ upThemeData.m_state,
+ upThemeData.m_classicState,
+ upPainter.drawRect());
+ }
+
+ {
+ half.setY(rect.y() + rect.height() / 2);
+ const ThemeData& downThemeData = getThemeData(object, SpinButtonDown);
+ ThemePainter downPainter(info.context, half);
+ PlatformBridge::paintSpinButton(downPainter.context(),
+ downThemeData.m_part,
+ downThemeData.m_state,
+ downThemeData.m_classicState,
+ downPainter.drawRect());
+ }
return false;
}
diff --git a/Source/WebCore/rendering/RenderThemeMac.h b/Source/WebCore/rendering/RenderThemeMac.h
index 9837c2a..d951ff6 100644
--- a/Source/WebCore/rendering/RenderThemeMac.h
+++ b/Source/WebCore/rendering/RenderThemeMac.h
@@ -166,7 +166,7 @@ protected:
virtual bool shouldRenderMediaControlPart(ControlPart, Element*);
virtual bool usesMediaControlStatusDisplay();
virtual void adjustMediaSliderThumbSize(RenderObject*) const;
- virtual IntPoint volumeSliderOffsetFromMuteButton(Node*, const IntSize&) const;
+ virtual IntPoint volumeSliderOffsetFromMuteButton(RenderBox*, const IntSize&) const;
#endif
virtual bool shouldShowPlaceholderWhenFocused() const;
diff --git a/Source/WebCore/rendering/RenderThemeMac.mm b/Source/WebCore/rendering/RenderThemeMac.mm
index e3c75c5..f5611dc 100644
--- a/Source/WebCore/rendering/RenderThemeMac.mm
+++ b/Source/WebCore/rendering/RenderThemeMac.mm
@@ -37,6 +37,7 @@
#import "MediaControlElements.h"
#import "PaintInfo.h"
#import "RenderMedia.h"
+#import "RenderMediaControls.h"
#import "RenderSlider.h"
#import "RenderView.h"
#import "SharedBuffer.h"
@@ -1986,17 +1987,9 @@ bool RenderThemeMac::usesMediaControlStatusDisplay()
return mediaControllerTheme() == MediaControllerThemeQuickTime;
}
-IntPoint RenderThemeMac::volumeSliderOffsetFromMuteButton(Node* muteButton, const IntSize& size) const
+IntPoint RenderThemeMac::volumeSliderOffsetFromMuteButton(RenderBox* muteButtonBox, const IntSize& size) const
{
- static const int xOffset = -4;
- static const int yOffset = 5;
-
- float zoomLevel = muteButton->renderer()->style()->effectiveZoom();
- int y = yOffset * zoomLevel + muteButton->renderBox()->offsetHeight() - size.height();
- FloatPoint absPoint = muteButton->renderer()->localToAbsolute(FloatPoint(muteButton->renderBox()->offsetLeft(), y), true, true);
- if (absPoint.y() < 0)
- y = muteButton->renderBox()->height();
- return IntPoint(xOffset * zoomLevel, y);
+ return RenderMediaControls::volumeSliderOffsetFromMuteButton(muteButtonBox, size);
}
bool RenderThemeMac::shouldShowPlaceholderWhenFocused() const
diff --git a/Source/WebCore/rendering/RenderThemeWin.cpp b/Source/WebCore/rendering/RenderThemeWin.cpp
index 5581db8..d5e4155 100644
--- a/Source/WebCore/rendering/RenderThemeWin.cpp
+++ b/Source/WebCore/rendering/RenderThemeWin.cpp
@@ -1108,9 +1108,9 @@ bool RenderThemeWin::paintMediaVolumeSliderThumb(RenderObject* o, const PaintInf
return RenderMediaControls::paintMediaControlsPart(MediaVolumeSliderThumb, o, paintInfo, r);
}
-IntPoint RenderThemeWin::volumeSliderOffsetFromMuteButton(Node* muteButton, const IntSize& size) const
+IntPoint RenderThemeWin::volumeSliderOffsetFromMuteButton(RenderBox* muteButtonBox, const IntSize& size) const
{
- return RenderMediaControls::volumeSliderOffsetFromMuteButton(muteButton, size);
+ return RenderMediaControls::volumeSliderOffsetFromMuteButton(muteButtonBox, size);
}
diff --git a/Source/WebCore/rendering/RenderThemeWin.h b/Source/WebCore/rendering/RenderThemeWin.h
index c05d2ee..7e0223a 100644
--- a/Source/WebCore/rendering/RenderThemeWin.h
+++ b/Source/WebCore/rendering/RenderThemeWin.h
@@ -138,7 +138,7 @@ public:
virtual bool paintMediaVolumeSliderContainer(RenderObject*, const PaintInfo&, const IntRect&);
virtual bool paintMediaVolumeSliderTrack(RenderObject*, const PaintInfo&, const IntRect&);
virtual bool paintMediaVolumeSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
- virtual IntPoint volumeSliderOffsetFromMuteButton(Node*, const IntSize&) const;
+ virtual IntPoint volumeSliderOffsetFromMuteButton(RenderBox*, const IntSize&) const;
#endif
private:
diff --git a/Source/WebCore/rendering/RenderTreeAsText.cpp b/Source/WebCore/rendering/RenderTreeAsText.cpp
index a81163b..cad5830 100644
--- a/Source/WebCore/rendering/RenderTreeAsText.cpp
+++ b/Source/WebCore/rendering/RenderTreeAsText.cpp
@@ -278,22 +278,22 @@ void RenderTreeAsText::writeRenderObject(TextStream& ts, const RenderObject& o,
ts << " " << quoteAndEscapeNonPrintables(toRenderFileUploadControl(&o)->fileTextValue());
if (o.parent() && (o.parent()->style()->color() != o.style()->color()))
- ts << " [color=" << o.style()->color().name() << "]";
+ ts << " [color=" << o.style()->color().nameForRenderTreeAsText() << "]";
if (o.parent() && (o.parent()->style()->backgroundColor() != o.style()->backgroundColor()) &&
o.style()->backgroundColor().isValid() && o.style()->backgroundColor().rgb())
// Do not dump invalid or transparent backgrounds, since that is the default.
- ts << " [bgcolor=" << o.style()->backgroundColor().name() << "]";
+ ts << " [bgcolor=" << o.style()->backgroundColor().nameForRenderTreeAsText() << "]";
if (o.parent() && (o.parent()->style()->textFillColor() != o.style()->textFillColor()) &&
o.style()->textFillColor().isValid() && o.style()->textFillColor() != o.style()->color() &&
o.style()->textFillColor().rgb())
- ts << " [textFillColor=" << o.style()->textFillColor().name() << "]";
+ ts << " [textFillColor=" << o.style()->textFillColor().nameForRenderTreeAsText() << "]";
if (o.parent() && (o.parent()->style()->textStrokeColor() != o.style()->textStrokeColor()) &&
o.style()->textStrokeColor().isValid() && o.style()->textStrokeColor() != o.style()->color() &&
o.style()->textStrokeColor().rgb())
- ts << " [textStrokeColor=" << o.style()->textStrokeColor().name() << "]";
+ ts << " [textStrokeColor=" << o.style()->textStrokeColor().nameForRenderTreeAsText() << "]";
if (o.parent() && (o.parent()->style()->textStrokeWidth() != o.style()->textStrokeWidth()) &&
o.style()->textStrokeWidth() > 0)
@@ -317,7 +317,7 @@ void RenderTreeAsText::writeRenderObject(TextStream& ts, const RenderObject& o,
Color col = o.style()->borderTopColor();
if (!col.isValid())
col = o.style()->color();
- ts << col.name() << ")";
+ ts << col.nameForRenderTreeAsText() << ")";
}
}
@@ -331,7 +331,7 @@ void RenderTreeAsText::writeRenderObject(TextStream& ts, const RenderObject& o,
Color col = o.style()->borderRightColor();
if (!col.isValid())
col = o.style()->color();
- ts << col.name() << ")";
+ ts << col.nameForRenderTreeAsText() << ")";
}
}
@@ -345,7 +345,7 @@ void RenderTreeAsText::writeRenderObject(TextStream& ts, const RenderObject& o,
Color col = o.style()->borderBottomColor();
if (!col.isValid())
col = o.style()->color();
- ts << col.name() << ")";
+ ts << col.nameForRenderTreeAsText() << ")";
}
}
@@ -359,7 +359,7 @@ void RenderTreeAsText::writeRenderObject(TextStream& ts, const RenderObject& o,
Color col = o.style()->borderLeftColor();
if (!col.isValid())
col = o.style()->color();
- ts << col.name() << ")";
+ ts << col.nameForRenderTreeAsText() << ")";
}
}
@@ -470,11 +470,17 @@ void RenderTreeAsText::writeRenderObject(TextStream& ts, const RenderObject& o,
static void writeTextRun(TextStream& ts, const RenderText& o, const InlineTextBox& run)
{
- // FIXME: Table cell adjustment is temporary until results can be updated.
+ // FIXME: For now use an "enclosingIntRect" model for x, y and logicalWidth, although this makes it harder
+ // to detect any changes caused by the conversion to floating point. :(
+ int x = run.m_x;
int y = run.m_y;
+ int logicalWidth = ceilf(run.m_x + run.m_logicalWidth) - x;
+
+ // FIXME: Table cell adjustment is temporary until results can be updated.
if (o.containingBlock()->isTableCell())
y -= toRenderTableCell(o.containingBlock())->intrinsicPaddingBefore();
- ts << "text run at (" << run.m_x << "," << y << ") width " << run.m_logicalWidth;
+
+ ts << "text run at (" << x << "," << y << ") width " << logicalWidth;
if (!run.isLeftToRightDirection() || run.m_dirOverride) {
ts << (!run.isLeftToRightDirection() ? " RTL" : " LTR");
if (run.m_dirOverride)
@@ -715,13 +721,13 @@ static void writeSelection(TextStream& ts, const RenderObject* o)
VisibleSelection selection = frame->selection()->selection();
if (selection.isCaret()) {
- ts << "caret: position " << selection.start().deprecatedEditingOffset() << " of " << nodePosition(selection.start().node());
+ ts << "caret: position " << selection.start().deprecatedEditingOffset() << " of " << nodePosition(selection.start().deprecatedNode());
if (selection.affinity() == UPSTREAM)
ts << " (upstream affinity)";
ts << "\n";
} else if (selection.isRange())
- ts << "selection start: position " << selection.start().deprecatedEditingOffset() << " of " << nodePosition(selection.start().node()) << "\n"
- << "selection end: position " << selection.end().deprecatedEditingOffset() << " of " << nodePosition(selection.end().node()) << "\n";
+ ts << "selection start: position " << selection.start().deprecatedEditingOffset() << " of " << nodePosition(selection.start().deprecatedNode()) << "\n"
+ << "selection end: position " << selection.end().deprecatedEditingOffset() << " of " << nodePosition(selection.end().deprecatedNode()) << "\n";
}
String externalRepresentation(Frame* frame, RenderAsTextBehavior behavior)
diff --git a/Source/WebCore/rendering/RenderingAllInOne.cpp b/Source/WebCore/rendering/RenderingAllInOne.cpp
index 760f02d..c9f6707 100644
--- a/Source/WebCore/rendering/RenderingAllInOne.cpp
+++ b/Source/WebCore/rendering/RenderingAllInOne.cpp
@@ -79,6 +79,7 @@
#include "RenderObjectChildList.cpp"
#include "RenderPart.cpp"
#include "RenderProgress.cpp"
+#include "RenderQuote.cpp"
#include "RenderReplaced.cpp"
#include "RenderReplica.cpp"
#include "RenderRuby.cpp"
@@ -110,6 +111,5 @@
#include "RootInlineBox.cpp"
#include "ScrollBehavior.cpp"
#include "ShadowElement.cpp"
-#include "TextControlInnerElements.cpp"
#include "TransformState.cpp"
#include "break_lines.cpp"
diff --git a/Source/WebCore/rendering/RootInlineBox.cpp b/Source/WebCore/rendering/RootInlineBox.cpp
index aa87683..8617252 100644
--- a/Source/WebCore/rendering/RootInlineBox.cpp
+++ b/Source/WebCore/rendering/RootInlineBox.cpp
@@ -85,7 +85,7 @@ void RootInlineBox::clearTruncation()
}
}
-bool RootInlineBox::canAccommodateEllipsis(bool ltr, int blockEdge, int lineBoxEdge, int ellipsisWidth)
+bool RootInlineBox::lineCanAccommodateEllipsis(bool ltr, int blockEdge, int lineBoxEdge, int ellipsisWidth)
{
// First sanity-check the unoverflowed width of the whole line to see if there is sufficient room.
int delta = ltr ? lineBoxEdge - blockEdge : blockEdge - lineBoxEdge;
@@ -97,7 +97,7 @@ bool RootInlineBox::canAccommodateEllipsis(bool ltr, int blockEdge, int lineBoxE
return InlineFlowBox::canAccommodateEllipsis(ltr, blockEdge, ellipsisWidth);
}
-void RootInlineBox::placeEllipsis(const AtomicString& ellipsisStr, bool ltr, int blockLeftEdge, int blockRightEdge, int ellipsisWidth,
+void RootInlineBox::placeEllipsis(const AtomicString& ellipsisStr, bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth,
InlineBox* markupBox)
{
// Create an ellipsis box.
@@ -123,9 +123,9 @@ void RootInlineBox::placeEllipsis(const AtomicString& ellipsisStr, bool ltr, in
ellipsisBox->m_x = placeEllipsisBox(ltr, blockLeftEdge, blockRightEdge, ellipsisWidth, foundBox);
}
-int RootInlineBox::placeEllipsisBox(bool ltr, int blockLeftEdge, int blockRightEdge, int ellipsisWidth, bool& foundBox)
+float RootInlineBox::placeEllipsisBox(bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, bool& foundBox)
{
- int result = InlineFlowBox::placeEllipsisBox(ltr, blockLeftEdge, blockRightEdge, ellipsisWidth, foundBox);
+ float result = InlineFlowBox::placeEllipsisBox(ltr, blockLeftEdge, blockRightEdge, ellipsisWidth, foundBox);
if (result == -1)
result = ltr ? blockRightEdge - ellipsisWidth : blockLeftEdge;
return result;
@@ -198,10 +198,10 @@ bool RootInlineBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
return InlineFlowBox::nodeAtPoint(request, result, x, y, tx, ty);
}
-void RootInlineBox::adjustPosition(int dx, int dy)
+void RootInlineBox::adjustPosition(float dx, float dy)
{
InlineFlowBox::adjustPosition(dx, dy);
- int blockDirectionDelta = isHorizontal() ? dy : dx;
+ int blockDirectionDelta = isHorizontal() ? dy : dx; // The block direction delta will always be integral.
m_lineTop += blockDirectionDelta;
m_lineBottom += blockDirectionDelta;
m_blockLogicalHeight += blockDirectionDelta;
@@ -268,10 +268,6 @@ int RootInlineBox::alignBoxesInBlockDirection(int heightOfBlock, GlyphOverflowAn
maxHeight = max(0, maxHeight);
- // Detect integer overflow.
- if (heightOfBlock > numeric_limits<int>::max() - maxHeight)
- return numeric_limits<int>::max();
-
return heightOfBlock + maxHeight;
}
@@ -289,7 +285,7 @@ int RootInlineBox::beforeAnnotationsAdjustment() const
// Annotations over this line may push us further down.
int highestAllowedPosition = prevRootBox() ? min(prevRootBox()->lineBottom(), lineTop()) + result : block()->borderBefore();
- result = computeOverAnnotationAdjustment(highestAllowedPosition);
+ result = computeOverAnnotationAdjustment(highestAllowedPosition);
} else {
// Annotations under this line may push us up.
if (hasAnnotationsBefore())
@@ -544,14 +540,14 @@ IntRect RootInlineBox::paddedLayoutOverflowRect(int endPadding) const
if (isHorizontal()) {
if (isLeftToRightDirection())
- lineLayoutOverflow.shiftMaxXEdgeTo(max(lineLayoutOverflow.maxX(), logicalRight() + endPadding));
+ lineLayoutOverflow.shiftMaxXEdgeTo(max(lineLayoutOverflow.maxX(), pixelSnappedLogicalRight() + endPadding));
else
- lineLayoutOverflow.shiftXEdgeTo(min(lineLayoutOverflow.x(), logicalLeft() - endPadding));
+ lineLayoutOverflow.shiftXEdgeTo(min(lineLayoutOverflow.x(), pixelSnappedLogicalLeft() - endPadding));
} else {
if (isLeftToRightDirection())
- lineLayoutOverflow.shiftMaxYEdgeTo(max(lineLayoutOverflow.maxY(), logicalRight() + endPadding));
+ lineLayoutOverflow.shiftMaxYEdgeTo(max(lineLayoutOverflow.maxY(), pixelSnappedLogicalRight() + endPadding));
else
- lineLayoutOverflow.shiftYEdgeTo(min(lineLayoutOverflow.y(), logicalRight() - endPadding));
+ lineLayoutOverflow.shiftYEdgeTo(min(lineLayoutOverflow.y(), pixelSnappedLogicalLeft() - endPadding));
}
return lineLayoutOverflow;
diff --git a/Source/WebCore/rendering/RootInlineBox.h b/Source/WebCore/rendering/RootInlineBox.h
index 7c4b15c..1a9f0a8 100644
--- a/Source/WebCore/rendering/RootInlineBox.h
+++ b/Source/WebCore/rendering/RootInlineBox.h
@@ -45,7 +45,7 @@ public:
RootInlineBox* nextRootBox() const { return static_cast<RootInlineBox*>(m_nextLineBox); }
RootInlineBox* prevRootBox() const { return static_cast<RootInlineBox*>(m_prevLineBox); }
- virtual void adjustPosition(int dx, int dy);
+ virtual void adjustPosition(float dx, float dy);
int lineTop() const { return m_lineTop; }
int lineBottom() const { return m_lineBottom; }
@@ -77,9 +77,9 @@ public:
void childRemoved(InlineBox* box);
- bool canAccommodateEllipsis(bool ltr, int blockEdge, int lineBoxEdge, int ellipsisWidth);
- void placeEllipsis(const AtomicString& ellipsisStr, bool ltr, int blockLeftEdge, int blockRightEdge, int ellipsisWidth, InlineBox* markupBox = 0);
- virtual int placeEllipsisBox(bool ltr, int blockLeftEdge, int blockRightEdge, int ellipsisWidth, bool& foundBox);
+ bool lineCanAccommodateEllipsis(bool ltr, int blockEdge, int lineBoxEdge, int ellipsisWidth);
+ void placeEllipsis(const AtomicString& ellipsisStr, bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, InlineBox* markupBox = 0);
+ virtual float placeEllipsisBox(bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, bool& foundBox);
EllipsisBox* ellipsisBox() const;
diff --git a/Source/WebCore/rendering/TextControlInnerElements.cpp b/Source/WebCore/rendering/TextControlInnerElements.cpp
deleted file mode 100644
index 1162999..0000000
--- a/Source/WebCore/rendering/TextControlInnerElements.cpp
+++ /dev/null
@@ -1,535 +0,0 @@
-/*
- * Copyright (C) 2006, 2008, 2010 Apple Inc. All rights reserved.
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "TextControlInnerElements.h"
-
-#include "BeforeTextInsertedEvent.h"
-#include "Document.h"
-#include "EventHandler.h"
-#include "EventNames.h"
-#include "Frame.h"
-#include "HTMLInputElement.h"
-#include "HTMLNames.h"
-#include "HTMLTextAreaElement.h"
-#include "MouseEvent.h"
-#include "Page.h"
-#include "RenderLayer.h"
-#include "RenderTextControlSingleLine.h"
-#include "ScrollbarTheme.h"
-#include "SpeechInput.h"
-#include "SpeechInputEvent.h"
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-class RenderTextControlInnerBlock : public RenderBlock {
-public:
- RenderTextControlInnerBlock(Node* node, bool isMultiLine) : RenderBlock(node), m_multiLine(isMultiLine) { }
-
-private:
- virtual bool hasLineIfEmpty() const { return true; }
- virtual VisiblePosition positionForPoint(const IntPoint&);
-
- bool m_multiLine;
-};
-
-VisiblePosition RenderTextControlInnerBlock::positionForPoint(const IntPoint& point)
-{
- IntPoint contentsPoint(point);
-
- // Multiline text controls have the scroll on shadowAncestorNode, so we need to take that
- // into account here.
- if (m_multiLine) {
- RenderTextControl* renderer = toRenderTextControl(node()->shadowAncestorNode()->renderer());
- if (renderer->hasOverflowClip())
- contentsPoint += renderer->layer()->scrolledContentOffset();
- }
-
- return RenderBlock::positionForPoint(contentsPoint);
-}
-
-// ----------------------------
-
-TextControlInnerElement::TextControlInnerElement(Document* document, HTMLElement* shadowParent)
- : HTMLDivElement(divTag, document)
-{
- setShadowHost(shadowParent);
-}
-
-PassRefPtr<TextControlInnerElement> TextControlInnerElement::create(HTMLElement* shadowParent)
-{
- return adoptRef(new TextControlInnerElement(shadowParent->document(), shadowParent));
-}
-
-void TextControlInnerElement::attachInnerElement(Node* parent, PassRefPtr<RenderStyle> style, RenderArena* arena)
-{
- // When adding these elements, create the renderer & style first before adding to the DOM.
- // Otherwise, the render tree will create some anonymous blocks that will mess up our layout.
-
- // Create the renderer with the specified style
- RenderObject* renderer = createRenderer(arena, style.get());
- if (renderer) {
- setRenderer(renderer);
- renderer->setStyle(style);
- }
-
- // Set these explicitly since this normally happens during an attach()
- setAttached();
- setInDocument();
-
- // For elements not yet in shadow DOM, add the node to the DOM normally.
- if (!isShadowRoot()) {
- // FIXME: This code seems very wrong. Why are we magically adding |this| to the DOM here?
- // We shouldn't be calling parser API methods outside of the parser!
- parent->deprecatedParserAddChild(this);
- }
-
- // Add the renderer to the render tree
- if (renderer)
- parent->renderer()->addChild(renderer);
-}
-
-void TextControlInnerElement::detach()
-{
- HTMLDivElement::detach();
- // FIXME: Remove once shadow DOM uses Element::setShadowRoot().
- if (shadowHost())
- setShadowHost(0);
-}
-
-// ----------------------------
-
-inline TextControlInnerTextElement::TextControlInnerTextElement(Document* document, HTMLElement* shadowParent)
- : TextControlInnerElement(document, shadowParent)
-{
-}
-
-PassRefPtr<TextControlInnerTextElement> TextControlInnerTextElement::create(Document* document, HTMLElement* shadowParent)
-{
- return adoptRef(new TextControlInnerTextElement(document, shadowParent));
-}
-
-void TextControlInnerTextElement::defaultEventHandler(Event* event)
-{
- // FIXME: In the future, we should add a way to have default event listeners.
- // Then we would add one to the text field's inner div, and we wouldn't need this subclass.
- // Or possibly we could just use a normal event listener.
- if (event->isBeforeTextInsertedEvent() || event->type() == eventNames().webkitEditableContentChangedEvent) {
- Node* shadowAncestor = shadowAncestorNode();
- // A TextControlInnerTextElement can be its own shadow ancestor if its been detached, but kept alive by an EditCommand.
- // In this case, an undo/redo can cause events to be sent to the TextControlInnerTextElement.
- // To prevent an infinite loop, we must check for this case before sending the event up the chain.
- if (shadowAncestor && shadowAncestor != this)
- shadowAncestor->defaultEventHandler(event);
- }
- if (!event->defaultHandled())
- HTMLDivElement::defaultEventHandler(event);
-}
-
-RenderObject* TextControlInnerTextElement::createRenderer(RenderArena* arena, RenderStyle*)
-{
- bool multiLine = false;
- Node* shadowAncestor = shadowAncestorNode();
- if (shadowAncestor && shadowAncestor->renderer()) {
- ASSERT(shadowAncestor->renderer()->isTextField() || shadowAncestor->renderer()->isTextArea());
- multiLine = shadowAncestor->renderer()->isTextArea();
- }
- return new (arena) RenderTextControlInnerBlock(this, multiLine);
-}
-
-// ----------------------------
-
-inline SearchFieldResultsButtonElement::SearchFieldResultsButtonElement(Document* document)
- : TextControlInnerElement(document)
-{
-}
-
-PassRefPtr<SearchFieldResultsButtonElement> SearchFieldResultsButtonElement::create(Document* document)
-{
- return adoptRef(new SearchFieldResultsButtonElement(document));
-}
-
-void SearchFieldResultsButtonElement::defaultEventHandler(Event* event)
-{
- // On mousedown, bring up a menu, if needed
- HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode());
- if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
- input->focus();
- input->select();
- RenderTextControlSingleLine* renderer = toRenderTextControlSingleLine(input->renderer());
- if (renderer->popupIsVisible())
- renderer->hidePopup();
- else if (input->maxResults() > 0)
- renderer->showPopup();
- event->setDefaultHandled();
- }
-
- if (!event->defaultHandled())
- HTMLDivElement::defaultEventHandler(event);
-}
-
-// ----------------------------
-
-inline SearchFieldCancelButtonElement::SearchFieldCancelButtonElement(Document* document)
- : TextControlInnerElement(document)
- , m_capturing(false)
-{
-}
-
-PassRefPtr<SearchFieldCancelButtonElement> SearchFieldCancelButtonElement::create(Document* document)
-{
- return adoptRef(new SearchFieldCancelButtonElement(document));
-}
-
-void SearchFieldCancelButtonElement::detach()
-{
- if (m_capturing) {
- if (Frame* frame = document()->frame())
- frame->eventHandler()->setCapturingMouseEventsNode(0);
- }
- TextControlInnerElement::detach();
-}
-
-
-void SearchFieldCancelButtonElement::defaultEventHandler(Event* event)
-{
- // If the element is visible, on mouseup, clear the value, and set selection
- RefPtr<HTMLInputElement> input(static_cast<HTMLInputElement*>(shadowAncestorNode()));
- if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
- if (renderer() && renderer()->visibleToHitTesting()) {
- if (Frame* frame = document()->frame()) {
- frame->eventHandler()->setCapturingMouseEventsNode(this);
- m_capturing = true;
- }
- }
- input->focus();
- input->select();
- event->setDefaultHandled();
- }
- if (event->type() == eventNames().mouseupEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
- if (m_capturing) {
- if (Frame* frame = document()->frame()) {
- frame->eventHandler()->setCapturingMouseEventsNode(0);
- m_capturing = false;
- }
- if (hovered()) {
- String oldValue = input->value();
- input->setValue("");
- if (!oldValue.isEmpty()) {
- toRenderTextControl(input->renderer())->setChangedSinceLastChangeEvent(true);
- input->dispatchFormControlInputEvent();
- }
- input->onSearch();
- event->setDefaultHandled();
- }
- }
- }
-
- if (!event->defaultHandled())
- HTMLDivElement::defaultEventHandler(event);
-}
-
-// ----------------------------
-
-inline SpinButtonElement::SpinButtonElement(HTMLElement* shadowParent)
- : TextControlInnerElement(shadowParent->document(), shadowParent)
- , m_capturing(false)
- , m_upDownState(Indeterminate)
- , m_pressStartingState(Indeterminate)
- , m_repeatingTimer(this, &SpinButtonElement::repeatingTimerFired)
-{
-}
-
-PassRefPtr<SpinButtonElement> SpinButtonElement::create(HTMLElement* shadowParent)
-{
- return adoptRef(new SpinButtonElement(shadowParent));
-}
-
-void SpinButtonElement::detach()
-{
- stopRepeatingTimer();
- if (m_capturing) {
- if (Frame* frame = document()->frame()) {
- frame->eventHandler()->setCapturingMouseEventsNode(0);
- m_capturing = false;
- }
- }
- TextControlInnerElement::detach();
-}
-
-void SpinButtonElement::defaultEventHandler(Event* event)
-{
- if (!event->isMouseEvent()) {
- if (!event->defaultHandled())
- HTMLDivElement::defaultEventHandler(event);
- return;
- }
-
- RenderBox* box = renderBox();
- if (!box) {
- if (!event->defaultHandled())
- HTMLDivElement::defaultEventHandler(event);
- return;
- }
-
- RefPtr<HTMLInputElement> input(static_cast<HTMLInputElement*>(shadowAncestorNode()));
- if (input->disabled() || input->isReadOnlyFormControl()) {
- if (!event->defaultHandled())
- HTMLDivElement::defaultEventHandler(event);
- return;
- }
-
- MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
- IntPoint local = roundedIntPoint(box->absoluteToLocal(mouseEvent->absoluteLocation(), false, true));
- if (mouseEvent->type() == eventNames().mousedownEvent && mouseEvent->button() == LeftButton) {
- if (box->borderBoxRect().contains(local)) {
- // The following functions of HTMLInputElement may run JavaScript
- // code which detaches this shadow node. We need to take a reference
- // and check renderer() after such function calls.
- RefPtr<Node> protector(this);
- input->focus();
- input->select();
- if (renderer()) {
- input->stepUpFromRenderer(m_upDownState == Up ? 1 : -1);
- if (renderer())
- startRepeatingTimer();
- }
- event->setDefaultHandled();
- }
- } else if (mouseEvent->type() == eventNames().mouseupEvent && mouseEvent->button() == LeftButton)
- stopRepeatingTimer();
- else if (event->type() == eventNames().mousemoveEvent) {
- if (box->borderBoxRect().contains(local)) {
- if (!m_capturing) {
- if (Frame* frame = document()->frame()) {
- frame->eventHandler()->setCapturingMouseEventsNode(this);
- m_capturing = true;
- }
- }
- UpDownState oldUpDownState = m_upDownState;
- m_upDownState = local.y() < box->height() / 2 ? Up : Down;
- if (m_upDownState != oldUpDownState)
- renderer()->repaint();
- } else {
- if (m_capturing) {
- stopRepeatingTimer();
- if (Frame* frame = document()->frame()) {
- frame->eventHandler()->setCapturingMouseEventsNode(0);
- m_capturing = false;
- }
- }
- }
- }
-
- if (!event->defaultHandled())
- HTMLDivElement::defaultEventHandler(event);
-}
-
-void SpinButtonElement::startRepeatingTimer()
-{
- m_pressStartingState = m_upDownState;
- ScrollbarTheme* theme = ScrollbarTheme::nativeTheme();
- m_repeatingTimer.start(theme->initialAutoscrollTimerDelay(), theme->autoscrollTimerDelay());
-}
-
-void SpinButtonElement::stopRepeatingTimer()
-{
- m_repeatingTimer.stop();
-}
-
-void SpinButtonElement::repeatingTimerFired(Timer<SpinButtonElement>*)
-{
- HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode());
- if (input->disabled() || input->isReadOnlyFormControl())
- return;
- // On Mac OS, NSStepper updates the value for the button under the mouse
- // cursor regardless of the button pressed at the beginning. So the
- // following check is not needed for Mac OS.
-#if !OS(MAC_OS_X)
- if (m_upDownState != m_pressStartingState)
- return;
-#endif
- input->stepUpFromRenderer(m_upDownState == Up ? 1 : -1);
-}
-
-void SpinButtonElement::setHovered(bool flag)
-{
- if (!hovered() && flag)
- m_upDownState = Indeterminate;
- TextControlInnerElement::setHovered(flag);
-}
-
-
-// ----------------------------
-
-#if ENABLE(INPUT_SPEECH)
-
-inline InputFieldSpeechButtonElement::InputFieldSpeechButtonElement(HTMLElement* shadowParent)
- : TextControlInnerElement(shadowParent->document(), shadowParent)
- , m_capturing(false)
- , m_state(Idle)
- , m_listenerId(document()->page()->speechInput()->registerListener(this))
-{
-}
-
-InputFieldSpeechButtonElement::~InputFieldSpeechButtonElement()
-{
- SpeechInput* speech = speechInput();
- if (speech && m_listenerId) { // Could be null when page is unloading.
- if (m_state != Idle)
- speech->cancelRecognition(m_listenerId);
- speech->unregisterListener(m_listenerId);
- }
-}
-
-PassRefPtr<InputFieldSpeechButtonElement> InputFieldSpeechButtonElement::create(HTMLElement* shadowParent)
-{
- return adoptRef(new InputFieldSpeechButtonElement(shadowParent));
-}
-
-void InputFieldSpeechButtonElement::defaultEventHandler(Event* event)
-{
- // For privacy reasons, only allow clicks directly coming from the user.
- if (!event->fromUserGesture()) {
- HTMLDivElement::defaultEventHandler(event);
- return;
- }
-
- // The call to focus() below dispatches a focus event, and an event handler in the page might
- // remove the input element from DOM. To make sure it remains valid until we finish our work
- // here, we take a temporary reference.
- RefPtr<HTMLInputElement> input(static_cast<HTMLInputElement*>(shadowAncestorNode()));
-
- // On mouse down, select the text and set focus.
- if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
- if (renderer() && renderer()->visibleToHitTesting()) {
- if (Frame* frame = document()->frame()) {
- frame->eventHandler()->setCapturingMouseEventsNode(this);
- m_capturing = true;
- }
- }
- RefPtr<InputFieldSpeechButtonElement> holdRefButton(this);
- input->focus();
- input->select();
- event->setDefaultHandled();
- }
- // On mouse up, release capture cleanly.
- if (event->type() == eventNames().mouseupEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
- if (m_capturing && renderer() && renderer()->visibleToHitTesting()) {
- if (Frame* frame = document()->frame()) {
- frame->eventHandler()->setCapturingMouseEventsNode(0);
- m_capturing = false;
- }
- }
- }
-
- if (event->type() == eventNames().clickEvent) {
- switch (m_state) {
- case Idle: {
- AtomicString language = input->computeInheritedLanguage();
- String grammar = input->getAttribute(webkitgrammarAttr);
- IntRect rect = input->renderer()->absoluteBoundingBoxRect();
- if (speechInput()->startRecognition(m_listenerId, rect, language, grammar, document()->securityOrigin()))
- setState(Recording);
- }
- break;
- case Recording:
- speechInput()->stopRecording(m_listenerId);
- break;
- case Recognizing:
- // Nothing to do here, we will continue to wait for results.
- break;
- }
- event->setDefaultHandled();
- }
-
- if (!event->defaultHandled())
- HTMLDivElement::defaultEventHandler(event);
-}
-
-void InputFieldSpeechButtonElement::setState(SpeechInputState state)
-{
- if (m_state != state) {
- m_state = state;
- shadowAncestorNode()->renderer()->repaint();
- }
-}
-
-SpeechInput* InputFieldSpeechButtonElement::speechInput()
-{
- return document()->page() ? document()->page()->speechInput() : 0;
-}
-
-void InputFieldSpeechButtonElement::didCompleteRecording(int)
-{
- setState(Recognizing);
-}
-
-void InputFieldSpeechButtonElement::didCompleteRecognition(int)
-{
- setState(Idle);
-}
-
-void InputFieldSpeechButtonElement::setRecognitionResult(int, const SpeechInputResultArray& results)
-{
- m_results = results;
-
- // The call to setValue() below dispatches an event, and an event handler in the page might
- // remove the input element from DOM. To make sure it remains valid until we finish our work
- // here, we take a temporary reference.
- RefPtr<HTMLInputElement> input(static_cast<HTMLInputElement*>(shadowAncestorNode()));
- RefPtr<InputFieldSpeechButtonElement> holdRefButton(this);
- input->setValue(results.isEmpty() ? "" : results[0]->utterance());
- input->dispatchEvent(SpeechInputEvent::create(eventNames().webkitspeechchangeEvent, results));
-
- // Check before accessing the renderer as the above event could have potentially turned off
- // speech in the input element, hence removing this button and renderer from the hierarchy.
- if (renderer())
- renderer()->repaint();
-}
-
-void InputFieldSpeechButtonElement::detach()
-{
- if (m_capturing) {
- if (Frame* frame = document()->frame())
- frame->eventHandler()->setCapturingMouseEventsNode(0);
- }
-
- if (m_listenerId) {
- if (m_state != Idle)
- speechInput()->cancelRecognition(m_listenerId);
- speechInput()->unregisterListener(m_listenerId);
- m_listenerId = 0;
- }
-
- TextControlInnerElement::detach();
-}
-
-#endif // ENABLE(INPUT_SPEECH)
-
-}
diff --git a/Source/WebCore/rendering/TextControlInnerElements.h b/Source/WebCore/rendering/TextControlInnerElements.h
deleted file mode 100644
index 4ba7857..0000000
--- a/Source/WebCore/rendering/TextControlInnerElements.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2006, 2008, 2010 Apple Inc. All rights reserved.
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TextControlInnerElements_h
-#define TextControlInnerElements_h
-
-#include "HTMLDivElement.h"
-#include "SpeechInputListener.h"
-#include "Timer.h"
-#include <wtf/Forward.h>
-
-namespace WebCore {
-
-class SpeechInput;
-
-class TextControlInnerElement : public HTMLDivElement {
-public:
- static PassRefPtr<TextControlInnerElement> create(HTMLElement* shadowParent);
- virtual void detach();
-
- void attachInnerElement(Node*, PassRefPtr<RenderStyle>, RenderArena*);
-
-protected:
- TextControlInnerElement(Document*, HTMLElement* shadowParent = 0);
-
-private:
- virtual bool isMouseFocusable() const { return false; }
-};
-
-class TextControlInnerTextElement : public TextControlInnerElement {
-public:
- static PassRefPtr<TextControlInnerTextElement> create(Document*, HTMLElement* shadowParent);
-
- virtual void defaultEventHandler(Event*);
-
-private:
- TextControlInnerTextElement(Document*, HTMLElement* shadowParent);
- virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
-};
-
-class SearchFieldResultsButtonElement : public TextControlInnerElement {
-public:
- static PassRefPtr<SearchFieldResultsButtonElement> create(Document*);
-
- virtual void defaultEventHandler(Event*);
-
-private:
- SearchFieldResultsButtonElement(Document*);
-};
-
-class SearchFieldCancelButtonElement : public TextControlInnerElement {
-public:
- static PassRefPtr<SearchFieldCancelButtonElement> create(Document*);
-
- virtual void defaultEventHandler(Event*);
-
-private:
- SearchFieldCancelButtonElement(Document*);
-
- virtual void detach();
-
- bool m_capturing;
-};
-
-class SpinButtonElement : public TextControlInnerElement {
-public:
- enum UpDownState {
- Indeterminate, // Hovered, but the event is not handled.
- Down,
- Up,
- };
-
- static PassRefPtr<SpinButtonElement> create(HTMLElement*);
- UpDownState upDownState() const { return m_upDownState; }
-
-private:
- SpinButtonElement(HTMLElement*);
-
- virtual void detach();
- virtual bool isSpinButtonElement() const { return true; }
- // FIXME: shadowAncestorNode() should be const.
- virtual bool isEnabledFormControl() const { return static_cast<Element*>(const_cast<SpinButtonElement*>(this)->shadowAncestorNode())->isEnabledFormControl(); }
- virtual bool isReadOnlyFormControl() const { return static_cast<Element*>(const_cast<SpinButtonElement*>(this)->shadowAncestorNode())->isReadOnlyFormControl(); }
- virtual void defaultEventHandler(Event*);
- void startRepeatingTimer();
- void stopRepeatingTimer();
- void repeatingTimerFired(Timer<SpinButtonElement>*);
- virtual void setHovered(bool = true);
-
- bool m_capturing;
- UpDownState m_upDownState;
- UpDownState m_pressStartingState;
- Timer<SpinButtonElement> m_repeatingTimer;
-};
-
-#if ENABLE(INPUT_SPEECH)
-
-class InputFieldSpeechButtonElement
- : public TextControlInnerElement,
- public SpeechInputListener {
-public:
- enum SpeechInputState {
- Idle,
- Recording,
- Recognizing,
- };
-
- static PassRefPtr<InputFieldSpeechButtonElement> create(HTMLElement*);
- virtual ~InputFieldSpeechButtonElement();
-
- virtual void detach();
- virtual void defaultEventHandler(Event*);
- SpeechInputState state() const { return m_state; }
-
- // SpeechInputListener methods.
- void didCompleteRecording(int);
- void didCompleteRecognition(int);
- void setRecognitionResult(int, const SpeechInputResultArray&);
-
-private:
- InputFieldSpeechButtonElement(HTMLElement*);
- SpeechInput* speechInput();
- void setState(SpeechInputState state);
-
- bool m_capturing;
- SpeechInputState m_state;
- int m_listenerId;
- SpeechInputResultArray m_results;
-};
-
-#endif // ENABLE(INPUT_SPEECH)
-
-} // namespace
-
-#endif
diff --git a/Source/WebCore/rendering/VerticalPositionCache.h b/Source/WebCore/rendering/VerticalPositionCache.h
index b25b2f6..bb39877 100644
--- a/Source/WebCore/rendering/VerticalPositionCache.h
+++ b/Source/WebCore/rendering/VerticalPositionCache.h
@@ -34,8 +34,6 @@ namespace WebCore {
class RenderObject;
// Values for vertical alignment.
-const int PositionTop = -0x7fffffff;
-const int PositionBottom = 0x7fffffff;
const int PositionUndefined = 0x80000000;
class VerticalPositionCache {
diff --git a/Source/WebCore/rendering/break_lines.cpp b/Source/WebCore/rendering/break_lines.cpp
index b888fb8..9ac3375 100644
--- a/Source/WebCore/rendering/break_lines.cpp
+++ b/Source/WebCore/rendering/break_lines.cpp
@@ -158,11 +158,10 @@ static inline TextBreakLocatorRef lineBreakLocator()
}
#endif
-int nextBreakablePosition(const UChar* str, int pos, int len, bool treatNoBreakSpaceAsBreak)
+int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, int pos, bool treatNoBreakSpaceAsBreak)
{
-#if !PLATFORM(MAC) || !defined(BUILDING_ON_TIGER)
- TextBreakIterator* breakIterator = 0;
-#endif
+ const UChar* str = lazyBreakIterator.string();
+ int len = lazyBreakIterator.length();
int nextBreak = -1;
UChar lastCh = pos > 0 ? str[pos - 1] : 0;
@@ -175,8 +174,7 @@ int nextBreakablePosition(const UChar* str, int pos, int len, bool treatNoBreakS
if (needsLineBreakIterator(ch) || needsLineBreakIterator(lastCh)) {
if (nextBreak < i && i) {
#if !PLATFORM(MAC) || !defined(BUILDING_ON_TIGER)
- if (!breakIterator)
- breakIterator = lineBreakIterator(str, len);
+ TextBreakIterator* breakIterator = lazyBreakIterator.get();
if (breakIterator)
nextBreak = textBreakFollowing(breakIterator, i - 1);
#else
diff --git a/Source/WebCore/rendering/break_lines.h b/Source/WebCore/rendering/break_lines.h
index 4d6b8dc..6600e52 100644
--- a/Source/WebCore/rendering/break_lines.h
+++ b/Source/WebCore/rendering/break_lines.h
@@ -25,14 +25,16 @@
namespace WebCore {
- int nextBreakablePosition(const UChar*, int pos, int len, bool breakNBSP = false);
-
- inline bool isBreakable(const UChar* str, int pos, int len, int& nextBreakable, bool breakNBSP = false)
- {
- if (pos > nextBreakable)
- nextBreakable = nextBreakablePosition(str, pos, len, breakNBSP);
- return pos == nextBreakable;
- }
+class LazyLineBreakIterator;
+
+int nextBreakablePosition(LazyLineBreakIterator&, int pos, bool breakNBSP = false);
+
+inline bool isBreakable(LazyLineBreakIterator& lazyBreakIterator, int pos, int& nextBreakable, bool breakNBSP = false)
+{
+ if (pos > nextBreakable)
+ nextBreakable = nextBreakablePosition(lazyBreakIterator, pos, breakNBSP);
+ return pos == nextBreakable;
+}
} // namespace WebCore
diff --git a/Source/WebCore/rendering/style/ContentData.cpp b/Source/WebCore/rendering/style/ContentData.cpp
index d150f77..ab504fd 100644
--- a/Source/WebCore/rendering/style/ContentData.cpp
+++ b/Source/WebCore/rendering/style/ContentData.cpp
@@ -51,6 +51,8 @@ bool ContentData::dataEquivalent(const ContentData& other) const
return StyleImage::imagesEquivalent(image(), other.image());
case CONTENT_COUNTER:
return *counter() == *other.counter();
+ case CONTENT_QUOTE:
+ return quote() == other.quote();
}
ASSERT_NOT_REACHED();
@@ -71,6 +73,8 @@ void ContentData::deleteContent()
case CONTENT_COUNTER:
delete m_content.m_counter;
break;
+ case CONTENT_QUOTE:
+ break;
}
m_type = CONTENT_NONE;
diff --git a/Source/WebCore/rendering/style/ContentData.h b/Source/WebCore/rendering/style/ContentData.h
index 15f6912..cce3754 100644
--- a/Source/WebCore/rendering/style/ContentData.h
+++ b/Source/WebCore/rendering/style/ContentData.h
@@ -51,6 +51,7 @@ public:
bool isCounter() const { return m_type == CONTENT_COUNTER; }
bool isImage() const { return m_type == CONTENT_OBJECT; }
bool isNone() const { return m_type == CONTENT_NONE; }
+ bool isQuote() const { return m_type == CONTENT_QUOTE; }
bool isText() const { return m_type == CONTENT_TEXT; }
StyleContentType type() const { return m_type; }
@@ -93,6 +94,18 @@ public:
m_content.m_counter = counter.leakPtr();
}
+ QuoteType quote() const
+ {
+ ASSERT(isQuote());
+ return m_content.m_quote;
+ }
+ void setQuote(QuoteType type)
+ {
+ deleteContent();
+ m_type = CONTENT_QUOTE;
+ m_content.m_quote = type;
+ }
+
ContentData* next() const { return m_next.get(); }
void setNext(PassOwnPtr<ContentData> next) { m_next = next; }
@@ -104,6 +117,7 @@ private:
StyleImage* m_image;
StringImpl* m_text;
CounterContent* m_counter;
+ QuoteType m_quote;
} m_content;
OwnPtr<ContentData> m_next;
};
diff --git a/Source/WebCore/rendering/style/QuotesData.cpp b/Source/WebCore/rendering/style/QuotesData.cpp
new file mode 100644
index 0000000..829fe3f
--- /dev/null
+++ b/Source/WebCore/rendering/style/QuotesData.cpp
@@ -0,0 +1,60 @@
+/**
+ * Copyright (C) 2011 Nokia Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "QuotesData.h"
+
+namespace WebCore {
+
+QuotesData* QuotesData::create(int stringCount)
+{
+ char* tmp = new char[sizeof(QuotesData)+sizeof(String)*stringCount];
+ if (!tmp)
+ return 0;
+ new (tmp) QuotesData(stringCount);
+ for (int i = 0; i < stringCount; ++i)
+ new (tmp +sizeof(QuotesData) + sizeof(String)*i) String();
+ return reinterpret_cast<QuotesData*>(tmp);
+}
+
+bool QuotesData::operator==(const QuotesData& other) const
+{
+ if (this == &other)
+ return true;
+ if (!&other || !this)
+ return false;
+ if (length != other.length)
+ return false;
+ const String* myData = data();
+ const String* otherData = other.data();
+ for (int i = length-1; i >= 0; --i)
+ if (myData[i] != otherData[i])
+ return false;
+ return true;
+}
+
+QuotesData::~QuotesData()
+{
+ String* p = data();
+ for (int i = 0; i < length; ++i)
+ p[i].~String();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/rendering/style/QuotesData.h b/Source/WebCore/rendering/style/QuotesData.h
new file mode 100644
index 0000000..df8a6dd
--- /dev/null
+++ b/Source/WebCore/rendering/style/QuotesData.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2011 Nokia Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef QuotesData_h
+#define QuotesData_h
+
+#include <wtf/RefPtr.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class QuotesData : public RefCounted<QuotesData> {
+public:
+ virtual ~QuotesData();
+ static QuotesData* create(int stringCount);
+ String* data() { return reinterpret_cast<String*>(this+1); }
+ const String* data() const { return reinterpret_cast<const String*>(this+1); }
+ int length;
+ bool operator==(const QuotesData&) const;
+ void operator delete(void* p) { delete[] static_cast<char*>(p); }
+private:
+ QuotesData(int stringCount) : length(stringCount) {}
+};
+
+}
+#endif // QuotesData_h
diff --git a/Source/WebCore/rendering/style/RenderStyle.cpp b/Source/WebCore/rendering/style/RenderStyle.cpp
index b76a350..122b762 100644
--- a/Source/WebCore/rendering/style/RenderStyle.cpp
+++ b/Source/WebCore/rendering/style/RenderStyle.cpp
@@ -27,6 +27,7 @@
#include "CSSPropertyNames.h"
#include "CSSStyleSelector.h"
#include "FontSelector.h"
+#include "QuotesData.h"
#include "RenderArena.h"
#include "RenderObject.h"
#include "ScaleTransformOperation.h"
@@ -404,8 +405,10 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon
rareInheritedData->khtmlLineBreak != other->rareInheritedData->khtmlLineBreak ||
rareInheritedData->textSecurity != other->rareInheritedData->textSecurity ||
rareInheritedData->hyphens != other->rareInheritedData->hyphens ||
+ rareInheritedData->hyphenationLimitBefore != other->rareInheritedData->hyphenationLimitBefore ||
+ rareInheritedData->hyphenationLimitAfter != other->rareInheritedData->hyphenationLimitAfter ||
rareInheritedData->hyphenationString != other->rareInheritedData->hyphenationString ||
- rareInheritedData->hyphenationLocale != other->rareInheritedData->hyphenationLocale ||
+ rareInheritedData->locale != other->rareInheritedData->locale ||
rareInheritedData->textEmphasisMark != other->rareInheritedData->textEmphasisMark ||
rareInheritedData->textEmphasisPosition != other->rareInheritedData->textEmphasisPosition ||
rareInheritedData->textEmphasisCustomMark != other->rareInheritedData->textEmphasisCustomMark)
@@ -605,6 +608,13 @@ void RenderStyle::setCursorList(PassRefPtr<CursorList> other)
rareInheritedData.access()->cursorData = other;
}
+void RenderStyle::setQuotes(PassRefPtr<QuotesData> q)
+{
+ if (*rareInheritedData->quotes.get() == *q.get())
+ return;
+ rareInheritedData.access()->quotes = q;
+}
+
void RenderStyle::clearCursorList()
{
if (rareInheritedData->cursorData)
@@ -672,6 +682,11 @@ void RenderStyle::setContent(PassOwnPtr<CounterContent> counter, bool add)
prepareToSetContent(0, add)->setCounter(counter);
}
+void RenderStyle::setContent(QuoteType quote, bool add)
+{
+ prepareToSetContent(0, add)->setQuote(quote);
+}
+
void RenderStyle::applyTransform(TransformationMatrix& transform, const IntSize& borderBoxSize, ApplyTransformOrigin applyOrigin) const
{
// transform-origin brackets the transform with translate operations.
diff --git a/Source/WebCore/rendering/style/RenderStyle.h b/Source/WebCore/rendering/style/RenderStyle.h
index 7b79db1..79ed6e4 100644
--- a/Source/WebCore/rendering/style/RenderStyle.h
+++ b/Source/WebCore/rendering/style/RenderStyle.h
@@ -372,10 +372,18 @@ public:
Length top() const { return surround->offset.top(); }
Length bottom() const { return surround->offset.bottom(); }
+ // Accessors for positioned object edges that take into account writing mode.
+ Length logicalLeft() const { return isHorizontalWritingMode() ? left() : top(); }
+ Length logicalRight() const { return isHorizontalWritingMode() ? right() : bottom(); }
+ Length logicalTop() const { return isHorizontalWritingMode() ? (isFlippedBlocksWritingMode() ? bottom() : top()) : (isFlippedBlocksWritingMode() ? right() : left()); }
+ Length logicalBottom() const { return isHorizontalWritingMode() ? (isFlippedBlocksWritingMode() ? top() : bottom()) : (isFlippedBlocksWritingMode() ? left() : right()); }
+
// Whether or not a positioned element requires normal flow x/y to be computed
// to determine its position.
- bool hasStaticX() const { return (left().isAuto() && right().isAuto()) || left().isStatic() || right().isStatic(); }
- bool hasStaticY() const { return (top().isAuto() && bottom().isAuto()) || top().isStatic(); }
+ bool hasAutoLeftAndRight() const { return left().isAuto() && right().isAuto(); }
+ bool hasAutoTopAndBottom() const { return top().isAuto() && bottom().isAuto(); }
+ bool hasStaticInlinePosition(bool horizontal) const { return horizontal ? hasAutoLeftAndRight() : hasAutoTopAndBottom(); }
+ bool hasStaticBlockPosition(bool horizontal) const { return horizontal ? hasAutoTopAndBottom() : hasAutoLeftAndRight(); }
EPosition position() const { return static_cast<EPosition>(noninherited_flags._position); }
EFloat floating() const { return static_cast<EFloat>(noninherited_flags._floating); }
@@ -686,8 +694,10 @@ public:
EMatchNearestMailBlockquoteColor matchNearestMailBlockquoteColor() const { return static_cast<EMatchNearestMailBlockquoteColor>(rareNonInheritedData->matchNearestMailBlockquoteColor); }
const AtomicString& highlight() const { return rareInheritedData->highlight; }
Hyphens hyphens() const { return static_cast<Hyphens>(rareInheritedData->hyphens); }
+ short hyphenationLimitBefore() const { return rareInheritedData->hyphenationLimitBefore; }
+ short hyphenationLimitAfter() const { return rareInheritedData->hyphenationLimitAfter; }
const AtomicString& hyphenationString() const { return rareInheritedData->hyphenationString; }
- const AtomicString& hyphenationLocale() const { return rareInheritedData->hyphenationLocale; }
+ const AtomicString& locale() const { return rareInheritedData->locale; }
EBorderFit borderFit() const { return static_cast<EBorderFit>(rareNonInheritedData->m_borderFit); }
EResize resize() const { return static_cast<EResize>(rareInheritedData->resize); }
float columnWidth() const { return rareNonInheritedData->m_multiCol->m_width; }
@@ -1055,8 +1065,10 @@ public:
void setMatchNearestMailBlockquoteColor(EMatchNearestMailBlockquoteColor c) { SET_VAR(rareNonInheritedData, matchNearestMailBlockquoteColor, c); }
void setHighlight(const AtomicString& h) { SET_VAR(rareInheritedData, highlight, h); }
void setHyphens(Hyphens h) { SET_VAR(rareInheritedData, hyphens, h); }
+ void setHyphenationLimitBefore(short limit) { SET_VAR(rareInheritedData, hyphenationLimitBefore, limit); }
+ void setHyphenationLimitAfter(short limit) { SET_VAR(rareInheritedData, hyphenationLimitAfter, limit); }
void setHyphenationString(const AtomicString& h) { SET_VAR(rareInheritedData, hyphenationString, h); }
- void setHyphenationLocale(const AtomicString& h) { SET_VAR(rareInheritedData, hyphenationLocale, h); }
+ void setLocale(const AtomicString& locale) { SET_VAR(rareInheritedData, locale, locale); }
void setBorderFit(EBorderFit b) { SET_VAR(rareNonInheritedData, m_borderFit, b); }
void setResize(EResize r) { SET_VAR(rareInheritedData, resize, r); }
void setColumnWidth(float f) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_autoWidth, false); SET_VAR(rareNonInheritedData.access()->m_multiCol, m_width, f); }
@@ -1161,10 +1173,14 @@ public:
void setContent(PassRefPtr<StringImpl>, bool add = false);
void setContent(PassRefPtr<StyleImage>, bool add = false);
void setContent(PassOwnPtr<CounterContent>, bool add = false);
+ void setContent(QuoteType, bool add = false);
const CounterDirectiveMap* counterDirectives() const;
CounterDirectiveMap& accessCounterDirectives();
+ QuotesData* quotes() const { return rareInheritedData->quotes.get(); }
+ void setQuotes(PassRefPtr<QuotesData>);
+
const AtomicString& hyphenString() const;
bool inheritedNotEqual(const RenderStyle*) const;
@@ -1296,8 +1312,10 @@ public:
static const AtomicString& initialHighlight() { return nullAtom; }
static ESpeak initialSpeak() { return SpeakNormal; }
static Hyphens initialHyphens() { return HyphensManual; }
+ static short initialHyphenationLimitBefore() { return -1; }
+ static short initialHyphenationLimitAfter() { return -1; }
static const AtomicString& initialHyphenationString() { return nullAtom; }
- static const AtomicString& initialHyphenationLocale() { return nullAtom; }
+ static const AtomicString& initialLocale() { return nullAtom; }
static EBorderFit initialBorderFit() { return BorderFitBorder; }
static EResize initialResize() { return RESIZE_NONE; }
static ControlPart initialAppearance() { return NoControlPart; }
diff --git a/Source/WebCore/rendering/style/RenderStyleConstants.h b/Source/WebCore/rendering/style/RenderStyleConstants.h
index 44cd3f5..3c62dbe 100644
--- a/Source/WebCore/rendering/style/RenderStyleConstants.h
+++ b/Source/WebCore/rendering/style/RenderStyleConstants.h
@@ -297,7 +297,11 @@ enum EListStyleType {
};
enum StyleContentType {
- CONTENT_NONE, CONTENT_OBJECT, CONTENT_TEXT, CONTENT_COUNTER
+ CONTENT_NONE, CONTENT_OBJECT, CONTENT_TEXT, CONTENT_COUNTER, CONTENT_QUOTE
+};
+
+enum QuoteType {
+ OPEN_QUOTE, CLOSE_QUOTE, NO_OPEN_QUOTE, NO_CLOSE_QUOTE
};
enum EBorderFit { BorderFitBorder, BorderFitLines };
diff --git a/Source/WebCore/rendering/style/SVGRenderStyle.cpp b/Source/WebCore/rendering/style/SVGRenderStyle.cpp
index 28f80f2..1ee1f36 100644
--- a/Source/WebCore/rendering/style/SVGRenderStyle.cpp
+++ b/Source/WebCore/rendering/style/SVGRenderStyle.cpp
@@ -169,7 +169,9 @@ StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const
// Some stroke properties, requires relayouts, as the cached stroke boundaries need to be recalculated.
if (stroke != other->stroke) {
if (stroke->width != other->stroke->width
- || stroke->paint != other->stroke->paint
+ || stroke->paintType != other->stroke->paintType
+ || stroke->paintColor != other->stroke->paintColor
+ || stroke->paintUri != other->stroke->paintUri
|| stroke->miterLimit != other->stroke->miterLimit
|| stroke->dashArray != other->stroke->dashArray
|| stroke->dashOffset != other->stroke->dashOffset)
@@ -191,7 +193,7 @@ StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const
}
// If fill changes, we just need to repaint. Fill boundaries are not influenced by this, only by the Path, that RenderSVGPath contains.
- if (fill != other->fill)
+ if (fill->paintType != other->fill->paintType || fill->paintColor != other->fill->paintColor || fill->paintUri != other->fill->paintUri)
return StyleDifferenceRepaint;
// If gradient stops change, we just need to repaint. Style updates are already handled through RenderSVGGradientSTop.
diff --git a/Source/WebCore/rendering/style/SVGRenderStyle.h b/Source/WebCore/rendering/style/SVGRenderStyle.h
index 7f032e7..88a48df 100644
--- a/Source/WebCore/rendering/style/SVGRenderStyle.h
+++ b/Source/WebCore/rendering/style/SVGRenderStyle.h
@@ -70,15 +70,19 @@ public:
static SVGWritingMode initialWritingMode() { return WM_LRTB; }
static EGlyphOrientation initialGlyphOrientationHorizontal() { return GO_0DEG; }
static EGlyphOrientation initialGlyphOrientationVertical() { return GO_AUTO; }
- static float initialFillOpacity() { return 1.0f; }
- static SVGPaint* initialFillPaint() { return SVGPaint::defaultFill(); }
- static float initialStrokeOpacity() { return 1.0f; }
- static SVGPaint* initialStrokePaint() { return SVGPaint::defaultStroke(); }
+ static float initialFillOpacity() { return 1; }
+ static SVGPaint::SVGPaintType initialFillPaintType() { return SVGPaint::SVG_PAINTTYPE_RGBCOLOR; }
+ static Color initialFillPaintColor() { return Color::black; }
+ static String initialFillPaintUri() { return String(); }
+ static float initialStrokeOpacity() { return 1; }
+ static SVGPaint::SVGPaintType initialStrokePaintType() { return SVGPaint::SVG_PAINTTYPE_NONE; }
+ static Color initialStrokePaintColor() { return Color(); }
+ static String initialStrokePaintUri() { return String(); }
static Vector<SVGLength> initialStrokeDashArray() { return Vector<SVGLength>(); }
- static float initialStrokeMiterLimit() { return 4.0f; }
- static float initialStopOpacity() { return 1.0f; }
+ static float initialStrokeMiterLimit() { return 4; }
+ static float initialStopOpacity() { return 1; }
static Color initialStopColor() { return Color(0, 0, 0); }
- static float initialFloodOpacity() { return 1.0f; }
+ static float initialFloodOpacity() { return 1; }
static Color initialFloodColor() { return Color(0, 0, 0); }
static Color initialLightingColor() { return Color(255, 255, 255); }
static ShadowData* initialShadow() { return 0; }
@@ -150,10 +154,14 @@ public:
fill.access()->opacity = obj;
}
- void setFillPaint(PassRefPtr<SVGPaint> obj)
+ void setFillPaint(SVGPaint::SVGPaintType type, const Color& color, const String& uri)
{
- if (!(fill->paint == obj))
- fill.access()->paint = obj;
+ if (!(fill->paintType == type))
+ fill.access()->paintType = type;
+ if (!(fill->paintColor == color))
+ fill.access()->paintColor = color;
+ if (!(fill->paintUri == uri))
+ fill.access()->paintUri = uri;
}
void setStrokeOpacity(float obj)
@@ -162,10 +170,14 @@ public:
stroke.access()->opacity = obj;
}
- void setStrokePaint(PassRefPtr<SVGPaint> obj)
+ void setStrokePaint(SVGPaint::SVGPaintType type, const Color& color, const String& uri)
{
- if (!(stroke->paint == obj))
- stroke.access()->paint = obj;
+ if (!(stroke->paintType == type))
+ stroke.access()->paintType = type;
+ if (!(stroke->paintColor == color))
+ stroke.access()->paintColor = color;
+ if (!(stroke->paintUri == uri))
+ stroke.access()->paintUri = uri;
}
void setStrokeDashArray(const Vector<SVGLength>& obj)
@@ -293,9 +305,13 @@ public:
EGlyphOrientation glyphOrientationHorizontal() const { return (EGlyphOrientation) svg_inherited_flags._glyphOrientationHorizontal; }
EGlyphOrientation glyphOrientationVertical() const { return (EGlyphOrientation) svg_inherited_flags._glyphOrientationVertical; }
float fillOpacity() const { return fill->opacity; }
- SVGPaint* fillPaint() const { return fill->paint.get(); }
+ const SVGPaint::SVGPaintType& fillPaintType() const { return fill->paintType; }
+ const Color& fillPaintColor() const { return fill->paintColor; }
+ const String& fillPaintUri() const { return fill->paintUri; }
float strokeOpacity() const { return stroke->opacity; }
- SVGPaint* strokePaint() const { return stroke->paint.get(); }
+ const SVGPaint::SVGPaintType& strokePaintType() const { return stroke->paintType; }
+ const Color& strokePaintColor() const { return stroke->paintColor; }
+ const String& strokePaintUri() const { return stroke->paintUri; }
Vector<SVGLength> strokeDashArray() const { return stroke->dashArray; }
float strokeMiterLimit() const { return stroke->miterLimit; }
SVGLength strokeWidth() const { return stroke->width; }
@@ -320,8 +336,8 @@ public:
bool hasMasker() const { return !maskerResource().isEmpty(); }
bool hasFilter() const { return !filterResource().isEmpty(); }
bool hasMarkers() const { return !markerStartResource().isEmpty() || !markerMidResource().isEmpty() || !markerEndResource().isEmpty(); }
- bool hasStroke() const { return strokePaint()->paintType() != SVGPaint::SVG_PAINTTYPE_NONE; }
- bool hasFill() const { return fillPaint()->paintType() != SVGPaint::SVG_PAINTTYPE_NONE; }
+ bool hasStroke() const { return strokePaintType() != SVGPaint::SVG_PAINTTYPE_NONE; }
+ bool hasFill() const { return fillPaintType() != SVGPaint::SVG_PAINTTYPE_NONE; }
bool isVerticalWritingMode() const { return writingMode() == WM_TBRL || writingMode() == WM_TB; }
protected:
diff --git a/Source/WebCore/rendering/style/SVGRenderStyleDefs.cpp b/Source/WebCore/rendering/style/SVGRenderStyleDefs.cpp
index c30ae6d..fb23e14 100644
--- a/Source/WebCore/rendering/style/SVGRenderStyleDefs.cpp
+++ b/Source/WebCore/rendering/style/SVGRenderStyleDefs.cpp
@@ -37,35 +37,27 @@ namespace WebCore {
StyleFillData::StyleFillData()
: opacity(SVGRenderStyle::initialFillOpacity())
- , paint(SVGRenderStyle::initialFillPaint())
+ , paintType(SVGRenderStyle::initialFillPaintType())
+ , paintColor(SVGRenderStyle::initialFillPaintColor())
+ , paintUri(SVGRenderStyle::initialFillPaintUri())
{
}
StyleFillData::StyleFillData(const StyleFillData& other)
: RefCounted<StyleFillData>()
, opacity(other.opacity)
- , paint(other.paint)
+ , paintType(other.paintType)
+ , paintColor(other.paintColor)
+ , paintUri(other.paintUri)
{
}
bool StyleFillData::operator==(const StyleFillData& other) const
{
- if (opacity != other.opacity)
- return false;
-
- if (!paint || !other.paint)
- return paint == other.paint;
-
- if (paint->paintType() != other.paint->paintType())
- return false;
-
- if (paint->paintType() == SVGPaint::SVG_PAINTTYPE_URI)
- return paint->uri() == other.paint->uri();
-
- if (paint->paintType() == SVGPaint::SVG_PAINTTYPE_RGBCOLOR)
- return paint->color() == other.paint->color();
-
- return paint == other.paint;
+ return opacity == other.opacity
+ && paintType == other.paintType
+ && paintColor == other.paintColor
+ && paintUri == other.paintUri;
}
StyleStrokeData::StyleStrokeData()
@@ -74,7 +66,9 @@ StyleStrokeData::StyleStrokeData()
, width(SVGRenderStyle::initialStrokeWidth())
, dashOffset(SVGRenderStyle::initialStrokeDashOffset())
, dashArray(SVGRenderStyle::initialStrokeDashArray())
- , paint(SVGRenderStyle::initialStrokePaint())
+ , paintType(SVGRenderStyle::initialStrokePaintType())
+ , paintColor(SVGRenderStyle::initialStrokePaintColor())
+ , paintUri(SVGRenderStyle::initialStrokePaintUri())
{
}
@@ -85,18 +79,22 @@ StyleStrokeData::StyleStrokeData(const StyleStrokeData& other)
, width(other.width)
, dashOffset(other.dashOffset)
, dashArray(other.dashArray)
- , paint(other.paint)
+ , paintType(other.paintType)
+ , paintColor(other.paintColor)
+ , paintUri(other.paintUri)
{
}
bool StyleStrokeData::operator==(const StyleStrokeData& other) const
{
- return paint == other.paint
- && width == other.width
+ return width == other.width
&& opacity == other.opacity
&& miterLimit == other.miterLimit
&& dashOffset == other.dashOffset
- && dashArray == other.dashArray;
+ && dashArray == other.dashArray
+ && paintType == other.paintType
+ && paintColor == other.paintColor
+ && paintUri == other.paintUri;
}
StyleStopData::StyleStopData()
diff --git a/Source/WebCore/rendering/style/SVGRenderStyleDefs.h b/Source/WebCore/rendering/style/SVGRenderStyleDefs.h
index de058a2..00358a0 100644
--- a/Source/WebCore/rendering/style/SVGRenderStyleDefs.h
+++ b/Source/WebCore/rendering/style/SVGRenderStyleDefs.h
@@ -29,9 +29,8 @@
#define SVGRenderStyleDefs_h
#if ENABLE(SVG)
-#include "Color.h"
-#include "PlatformString.h"
#include "SVGLength.h"
+#include "SVGPaint.h"
#include "ShadowData.h"
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
@@ -98,7 +97,7 @@ namespace WebCore {
public:
static PassRefPtr<StyleFillData> create() { return adoptRef(new StyleFillData); }
PassRefPtr<StyleFillData> copy() const { return adoptRef(new StyleFillData(*this)); }
-
+
bool operator==(const StyleFillData&) const;
bool operator!=(const StyleFillData& other) const
{
@@ -106,7 +105,9 @@ namespace WebCore {
}
float opacity;
- RefPtr<SVGPaint> paint;
+ SVGPaint::SVGPaintType paintType;
+ Color paintColor;
+ String paintUri;
private:
StyleFillData();
@@ -131,7 +132,9 @@ namespace WebCore {
SVGLength dashOffset;
Vector<SVGLength> dashArray;
- RefPtr<SVGPaint> paint;
+ SVGPaint::SVGPaintType paintType;
+ Color paintColor;
+ String paintUri;
private:
StyleStrokeData();
@@ -262,5 +265,4 @@ namespace WebCore {
} // namespace WebCore
#endif // ENABLE(SVG)
-
#endif // SVGRenderStyleDefs_h
diff --git a/Source/WebCore/rendering/style/StyleAllInOne.cpp b/Source/WebCore/rendering/style/StyleAllInOne.cpp
index 25b539f..967fa00 100644
--- a/Source/WebCore/rendering/style/StyleAllInOne.cpp
+++ b/Source/WebCore/rendering/style/StyleAllInOne.cpp
@@ -30,6 +30,7 @@
#include "FillLayer.cpp"
#include "KeyframeList.cpp"
#include "NinePieceImage.cpp"
+#include "QuotesData.cpp"
#include "RenderStyle.cpp"
#include "SVGRenderStyle.cpp"
#include "SVGRenderStyleDefs.cpp"
diff --git a/Source/WebCore/rendering/style/StyleRareInheritedData.cpp b/Source/WebCore/rendering/style/StyleRareInheritedData.cpp
index 0953dae..2798fd1 100644
--- a/Source/WebCore/rendering/style/StyleRareInheritedData.cpp
+++ b/Source/WebCore/rendering/style/StyleRareInheritedData.cpp
@@ -23,6 +23,7 @@
#include "StyleRareInheritedData.h"
#include "CursorList.h"
+#include "QuotesData.h"
#include "RenderStyle.h"
#include "RenderStyleConstants.h"
#include "ShadowData.h"
@@ -65,6 +66,8 @@ StyleRareInheritedData::StyleRareInheritedData()
, textEmphasisFill(TextEmphasisFillFilled)
, textEmphasisMark(TextEmphasisMarkNone)
, textEmphasisPosition(TextEmphasisPositionOver)
+ , hyphenationLimitBefore(-1)
+ , hyphenationLimitAfter(-1)
{
}
@@ -111,7 +114,9 @@ StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedData& o)
, textEmphasisMark(o.textEmphasisMark)
, textEmphasisPosition(o.textEmphasisPosition)
, hyphenationString(o.hyphenationString)
- , hyphenationLocale(o.hyphenationLocale)
+ , hyphenationLimitBefore(o.hyphenationLimitBefore)
+ , hyphenationLimitAfter(o.hyphenationLimitAfter)
+ , locale(o.locale)
, textEmphasisCustomMark(o.textEmphasisCustomMark)
{
}
@@ -169,12 +174,15 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const
&& colorSpace == o.colorSpace
&& speak == o.speak
&& hyphens == o.hyphens
+ && hyphenationLimitBefore == o.hyphenationLimitBefore
+ && hyphenationLimitAfter == o.hyphenationLimitAfter
&& textEmphasisFill == o.textEmphasisFill
&& textEmphasisMark == o.textEmphasisMark
&& textEmphasisPosition == o.textEmphasisPosition
&& hyphenationString == o.hyphenationString
- && hyphenationLocale == o.hyphenationLocale
- && textEmphasisCustomMark == o.textEmphasisCustomMark;
+ && locale == o.locale
+ && textEmphasisCustomMark == o.textEmphasisCustomMark
+ && *quotes == *o.quotes;
}
bool StyleRareInheritedData::shadowDataEquivalent(const StyleRareInheritedData& o) const
diff --git a/Source/WebCore/rendering/style/StyleRareInheritedData.h b/Source/WebCore/rendering/style/StyleRareInheritedData.h
index a370934..d4f233c 100644
--- a/Source/WebCore/rendering/style/StyleRareInheritedData.h
+++ b/Source/WebCore/rendering/style/StyleRareInheritedData.h
@@ -34,6 +34,7 @@
namespace WebCore {
class CursorList;
+class QuotesData;
class ShadowData;
// This struct is for rarely used inherited CSS3, CSS2, and WebKit-specific properties.
@@ -100,9 +101,13 @@ public:
unsigned textEmphasisPosition : 1; // TextEmphasisPosition
AtomicString hyphenationString;
- AtomicString hyphenationLocale;
+ short hyphenationLimitBefore;
+ short hyphenationLimitAfter;
+
+ AtomicString locale;
AtomicString textEmphasisCustomMark;
+ RefPtr<QuotesData> quotes;
private:
StyleRareInheritedData();
diff --git a/Source/WebCore/rendering/svg/RenderSVGResource.cpp b/Source/WebCore/rendering/svg/RenderSVGResource.cpp
index c0b16c5..12ed53a 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResource.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResource.cpp
@@ -51,33 +51,36 @@ static inline RenderSVGResource* requestPaintingResource(RenderSVGResourceMode m
return 0;
}
- SVGPaint* paint = mode == ApplyToFillMode ? svgStyle->fillPaint() : svgStyle->strokePaint();
- ASSERT(paint);
-
- SVGPaint::SVGPaintType paintType = paint->paintType();
+ bool applyToFill = mode == ApplyToFillMode;
+ SVGPaint::SVGPaintType paintType = applyToFill ? svgStyle->fillPaintType() : svgStyle->strokePaintType();
if (paintType == SVGPaint::SVG_PAINTTYPE_NONE)
return 0;
Color color;
- if (paintType == SVGPaint::SVG_PAINTTYPE_RGBCOLOR
- || paintType == SVGPaint::SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR
- || paintType == SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR
- || paintType == SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR)
- color = paint->color();
- else if (paintType == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR || paintType == SVGPaint::SVG_PAINTTYPE_URI_CURRENTCOLOR)
- color = style->visitedDependentColor(CSSPropertyColor);
+ switch (paintType) {
+ case SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR:
+ case SVGPaint::SVG_PAINTTYPE_RGBCOLOR:
+ case SVGPaint::SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR:
+ case SVGPaint::SVG_PAINTTYPE_URI_CURRENTCOLOR:
+ case SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR:
+ case SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR:
+ color = applyToFill ? svgStyle->fillPaintColor() : svgStyle->strokePaintColor();
+ default:
+ break;
+ }
if (style->insideLink() == InsideVisitedLink) {
RenderStyle* visitedStyle = style->getCachedPseudoStyle(VISITED_LINK);
ASSERT(visitedStyle);
- if (SVGPaint* visitedPaint = mode == ApplyToFillMode ? visitedStyle->svgStyle()->fillPaint() : visitedStyle->svgStyle()->strokePaint()) {
- // For SVG_PAINTTYPE_CURRENTCOLOR, 'color' already contains the 'visitedColor'.
- if (visitedPaint->paintType() < SVGPaint::SVG_PAINTTYPE_URI_NONE && visitedPaint->paintType() != SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR) {
- const Color& visitedColor = visitedPaint->color();
- if (visitedColor.isValid())
- color = Color(visitedColor.red(), visitedColor.green(), visitedColor.blue(), color.alpha());
- }
+ const SVGRenderStyle* svgVisitedStyle = visitedStyle->svgStyle();
+ SVGPaint::SVGPaintType visitedPaintType = applyToFill ? svgVisitedStyle->fillPaintType() : svgVisitedStyle->strokePaintType();
+
+ // For SVG_PAINTTYPE_CURRENTCOLOR, 'color' already contains the 'visitedColor'.
+ if (visitedPaintType < SVGPaint::SVG_PAINTTYPE_URI_NONE && visitedPaintType != SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR) {
+ const Color& visitedColor = applyToFill ? svgVisitedStyle->fillPaintColor() : svgVisitedStyle->strokePaintColor();
+ if (visitedColor.isValid())
+ color = Color(visitedColor.red(), visitedColor.green(), visitedColor.blue(), color.alpha());
}
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp
index c57f8b0..245a859 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp
@@ -254,8 +254,8 @@ bool RenderSVGResourceClipper::drawContentIntoMaskImage(ClipperData* clipperData
RefPtr<RenderStyle> oldRenderStyle = renderer->style();
RefPtr<RenderStyle> newRenderStyle = RenderStyle::clone(oldRenderStyle.get());
SVGRenderStyle* svgStyle = newRenderStyle.get()->accessSVGStyle();
- svgStyle->setFillPaint(SVGPaint::defaultFill());
- svgStyle->setStrokePaint(SVGPaint::defaultStroke());
+ svgStyle->setFillPaint(SVGRenderStyle::initialFillPaintType(), SVGRenderStyle::initialFillPaintColor(), SVGRenderStyle::initialFillPaintUri());
+ svgStyle->setStrokePaint(SVGRenderStyle::initialStrokePaintType(), SVGRenderStyle::initialStrokePaintColor(), SVGRenderStyle::initialStrokePaintUri());
svgStyle->setFillRule(newClipRule);
newRenderStyle.get()->setOpacity(1.0f);
svgStyle->setFillOpacity(1.0f);
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp b/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp
index 1b14ce4..b82be1b 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp
@@ -233,10 +233,8 @@ bool RenderSVGResourcePattern::buildTileImageTransform(RenderObject* renderer,
// Apply viewBox/objectBoundingBox transformations.
if (!viewBoxCTM.isIdentity())
tileImageTransform = viewBoxCTM;
- else if (attributes.boundingBoxModeContent()) {
- tileImageTransform.translate(objectBoundingBox.x(), objectBoundingBox.y());
+ else if (attributes.boundingBoxModeContent())
tileImageTransform.scale(objectBoundingBox.width(), objectBoundingBox.height());
- }
return true;
}
@@ -276,6 +274,8 @@ PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(RenderObject*
tileImageContext->concatCTM(tileImageTransform);
AffineTransform contentTransformation;
+ if (attributes.boundingBoxModeContent())
+ contentTransformation = tileImageTransform;
// Draw the content into the ImageBuffer.
for (Node* node = attributes.patternContentElement()->firstChild(); node; node = node->nextSibling()) {
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.cpp
index 99ea763..d429bdc 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.cpp
@@ -26,7 +26,11 @@
#include "RenderStyle.h"
#include "SVGRenderSupport.h"
+<<<<<<< HEAD
#if PLATFORM(SKIA) && !PLATFORM(ANDROID)
+=======
+#if USE(SKIA)
+>>>>>>> WebKit at r80534
#include "PlatformContextSkia.h"
#endif
diff --git a/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp b/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
index 52976f2..05e1357 100644
--- a/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
+++ b/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
@@ -47,7 +47,7 @@ SVGInlineTextBox::SVGInlineTextBox(RenderObject* object)
{
}
-int SVGInlineTextBox::offsetForPosition(int, bool) const
+int SVGInlineTextBox::offsetForPosition(float, bool) const
{
// SVG doesn't use the standard offset <-> position selection system, as it's not suitable for SVGs complex needs.
// vertical text selection, inline boxes spanning multiple lines (contrary to HTML, etc.)
@@ -76,7 +76,7 @@ int SVGInlineTextBox::offsetForPositionInFragment(const SVGTextFragment& fragmen
return fragment.positionListOffset - start() + textRenderer->scaledFont().offsetForPosition(textRun, position * scalingFactor, includePartialGlyphs);
}
-int SVGInlineTextBox::positionForOffset(int) const
+float SVGInlineTextBox::positionForOffset(int) const
{
// SVG doesn't use the offset <-> position selection system.
ASSERT_NOT_REACHED();
@@ -415,9 +415,6 @@ TextRun SVGInlineTextBox::constructTextRun(RenderStyle* style, const SVGTextFrag
run.setReferencingRenderObject(text);
#endif
- // Disable any word/character rounding.
- run.disableRoundingHacks();
-
// We handle letter & word spacing ourselves.
run.disableSpacing();
return run;
@@ -519,6 +516,29 @@ void SVGInlineTextBox::paintDecoration(GraphicsContext* context, ETextDecoration
}
}
+static inline void normalizeTransform(AffineTransform& transform)
+{
+ // Obtain consistent numerical results for the AffineTransform on both 32/64bit platforms.
+ // Tested with SnowLeopard on Core Duo vs. Core 2 Duo.
+ static const float s_floatEpsilon = std::numeric_limits<float>::epsilon();
+
+ if (fabs(transform.a() - 1) <= s_floatEpsilon)
+ transform.setA(1);
+ else if (fabs(transform.a() + 1) <= s_floatEpsilon)
+ transform.setA(-1);
+
+ if (fabs(transform.d() - 1) <= s_floatEpsilon)
+ transform.setD(1);
+ else if (fabs(transform.d() + 1) <= s_floatEpsilon)
+ transform.setD(-1);
+
+ if (fabs(transform.e()) <= s_floatEpsilon)
+ transform.setE(0);
+
+ if (fabs(transform.f()) <= s_floatEpsilon)
+ transform.setF(0);
+}
+
void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, ETextDecoration decoration, const SVGTextFragment& fragment, RenderObject* decorationRenderer)
{
ASSERT(!m_paintingResource);
@@ -546,7 +566,12 @@ void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, ETextD
if (scalingFactor != 1) {
width *= scalingFactor;
decorationOrigin.scale(scalingFactor, scalingFactor);
- context->scale(FloatSize(1 / scalingFactor, 1 / scalingFactor));
+
+ AffineTransform newTransform = context->getCTM();
+ newTransform.scale(1 / scalingFactor);
+ normalizeTransform(newTransform);
+
+ context->setCTM(newTransform);
}
decorationOrigin.move(0, -scaledFontMetrics.floatAscent() + positionOffsetForDecoration(decoration, scaledFontMetrics, thickness));
@@ -589,13 +614,21 @@ void SVGInlineTextBox::paintTextWithShadows(GraphicsContext* context, RenderStyl
if (shadow)
extraOffset = applyShadowToGraphicsContext(context, shadow, shadowRect, false /* stroked */, true /* opaque */, true /* horizontal */);
- if (scalingFactor != 1)
- context->scale(FloatSize(1 / scalingFactor, 1 / scalingFactor));
+ AffineTransform originalTransform;
+ if (scalingFactor != 1) {
+ originalTransform = context->getCTM();
+
+ AffineTransform newTransform = originalTransform;
+ newTransform.scale(1 / scalingFactor);
+ normalizeTransform(newTransform);
+
+ context->setCTM(newTransform);
+ }
scaledFont.drawText(context, textRun, textOrigin + extraOffset, startPosition, endPosition);
if (scalingFactor != 1)
- context->scale(FloatSize(scalingFactor, scalingFactor));
+ context->setCTM(originalTransform);
restoreGraphicsContextAfterTextPainting(context, textRun);
diff --git a/Source/WebCore/rendering/svg/SVGInlineTextBox.h b/Source/WebCore/rendering/svg/SVGInlineTextBox.h
index f2ca303..79c836f 100644
--- a/Source/WebCore/rendering/svg/SVGInlineTextBox.h
+++ b/Source/WebCore/rendering/svg/SVGInlineTextBox.h
@@ -42,8 +42,8 @@ public:
virtual int selectionTop() { return m_y; }
virtual int selectionHeight() { return m_logicalHeight; }
- virtual int offsetForPosition(int x, bool includePartialGlyphs = true) const;
- virtual int positionForOffset(int offset) const;
+ virtual int offsetForPosition(float x, bool includePartialGlyphs = true) const;
+ virtual float positionForOffset(int offset) const;
void paintSelectionBackground(PaintInfo&);
virtual void paint(PaintInfo&, int tx, int ty);
diff --git a/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp b/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp
index 97e15af..0f94fdd 100644
--- a/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp
+++ b/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp
@@ -222,7 +222,7 @@ static TextStream& operator<<(TextStream& ts, const SVGMarkerElement::SVGMarkerU
TextStream& operator<<(TextStream& ts, const Color& c)
{
- return ts << c.name();
+ return ts << c.nameForRenderTreeAsText();
}
// FIXME: Maybe this should be in KCanvasRenderingStyle.cpp
@@ -435,13 +435,16 @@ static void writeRenderSVGTextBox(TextStream& ts, const RenderBlock& text)
if (!box)
return;
- ts << " at (" << text.x() << "," << text.y() << ") size " << box->logicalWidth() << "x" << box->logicalHeight();
+ // FIXME: For now use an int for logicalWidth, although this makes it harder
+ // to detect any changes caused by the conversion to floating point. :(
+ int logicalWidth = ceilf(box->x() + box->logicalWidth()) - box->x();
+ ts << " at (" << text.x() << "," << text.y() << ") size " << logicalWidth << "x" << box->logicalHeight();
// FIXME: Remove this hack, once the new text layout engine is completly landed. We want to preserve the old layout test results for now.
ts << " contains 1 chunk(s)";
if (text.parent() && (text.parent()->style()->visitedDependentColor(CSSPropertyColor) != text.style()->visitedDependentColor(CSSPropertyColor)))
- writeNameValuePair(ts, "color", text.style()->visitedDependentColor(CSSPropertyColor).name());
+ writeNameValuePair(ts, "color", text.style()->visitedDependentColor(CSSPropertyColor).nameForRenderTreeAsText());
}
static inline void writeSVGInlineTextBox(TextStream& ts, SVGInlineTextBox* textBox, int indent)
diff --git a/Source/WebCore/rendering/svg/SVGResources.cpp b/Source/WebCore/rendering/svg/SVGResources.cpp
index 9a2c999..d3cd184 100644
--- a/Source/WebCore/rendering/svg/SVGResources.cpp
+++ b/Source/WebCore/rendering/svg/SVGResources.cpp
@@ -152,15 +152,12 @@ static inline String targetReferenceFromResource(SVGElement* element)
return SVGURIReference::getTarget(target);
}
-static inline RenderSVGResourceContainer* paintingResourceFromSVGPaint(Document* document, SVGPaint* paint, AtomicString& id, bool& hasPendingResource)
+static inline RenderSVGResourceContainer* paintingResourceFromSVGPaint(Document* document, const SVGPaint::SVGPaintType& paintType, const String& paintUri, AtomicString& id, bool& hasPendingResource)
{
- ASSERT(paint);
-
- SVGPaint::SVGPaintType paintType = paint->paintType();
if (paintType != SVGPaint::SVG_PAINTTYPE_URI && paintType != SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR)
return 0;
- id = SVGURIReference::getTarget(paint->uri());
+ id = SVGURIReference::getTarget(paintUri);
RenderSVGResourceContainer* container = getRenderSVGResourceContainerById(document, id);
if (!container) {
hasPendingResource = true;
@@ -259,7 +256,7 @@ bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRen
if (style->hasFill()) {
bool hasPendingResource = false;
AtomicString id;
- if (setFill(paintingResourceFromSVGPaint(document, style->fillPaint(), id, hasPendingResource)))
+ if (setFill(paintingResourceFromSVGPaint(document, style->fillPaintType(), style->fillPaintUri(), id, hasPendingResource)))
foundResources = true;
else if (hasPendingResource)
registerPendingResource(extensions, id, element);
@@ -268,7 +265,7 @@ bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRen
if (style->hasStroke()) {
bool hasPendingResource = false;
AtomicString id;
- if (setStroke(paintingResourceFromSVGPaint(document, style->strokePaint(), id, hasPendingResource)))
+ if (setStroke(paintingResourceFromSVGPaint(document, style->strokePaintType(), style->strokePaintUri(), id, hasPendingResource)))
foundResources = true;
else if (hasPendingResource)
registerPendingResource(extensions, id, element);
diff --git a/Source/WebCore/rendering/svg/SVGTextMetrics.cpp b/Source/WebCore/rendering/svg/SVGTextMetrics.cpp
index ca20d3d..d75bdb3 100644
--- a/Source/WebCore/rendering/svg/SVGTextMetrics.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextMetrics.cpp
@@ -47,8 +47,9 @@ SVGTextMetrics::SVGTextMetrics(RenderSVGInlineText* textRenderer, const TextRun&
int length = 0;
// Calculate width/height using the scaled font, divide this result by the scalingFactor afterwards.
- m_width = scaledFont.floatWidth(run, extraCharsAvailable, length, m_glyph.name) / scalingFactor;
+ m_width = scaledFont.width(run, extraCharsAvailable, length, m_glyph.name) / scalingFactor;
m_height = scaledFont.fontMetrics().floatHeight() / scalingFactor;
+
m_glyph.unicodeString = String(run.characters(), length);
m_glyph.isValid = true;
@@ -79,9 +80,6 @@ static TextRun constructTextRun(RenderSVGInlineText* text, const UChar* characte
run.setReferencingRenderObject(text);
#endif
- // Disable any word/character rounding.
- run.disableRoundingHacks();
-
// We handle letter & word spacing ourselves.
run.disableSpacing();
return run;