summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/rendering
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2011-05-18 13:36:51 +0100
committerSteve Block <steveblock@google.com>2011-05-24 15:38:28 +0100
commit2fc2651226baac27029e38c9d6ef883fa32084db (patch)
treee396d4bf89dcce6ed02071be66212495b1df1dec /Source/WebCore/rendering
parentb3725cedeb43722b3b175aaeff70552e562d2c94 (diff)
downloadexternal_webkit-2fc2651226baac27029e38c9d6ef883fa32084db.zip
external_webkit-2fc2651226baac27029e38c9d6ef883fa32084db.tar.gz
external_webkit-2fc2651226baac27029e38c9d6ef883fa32084db.tar.bz2
Merge WebKit at r78450: Initial merge by git.
Change-Id: I6d3e5f1f868ec266a0aafdef66182ddc3f265dc1
Diffstat (limited to 'Source/WebCore/rendering')
-rw-r--r--Source/WebCore/rendering/CounterNode.cpp2
-rw-r--r--Source/WebCore/rendering/CounterNode.h2
-rw-r--r--Source/WebCore/rendering/EllipsisBox.cpp10
-rw-r--r--Source/WebCore/rendering/InlineBox.cpp6
-rw-r--r--Source/WebCore/rendering/InlineBox.h10
-rw-r--r--Source/WebCore/rendering/InlineFlowBox.cpp62
-rw-r--r--Source/WebCore/rendering/InlineFlowBox.h39
-rw-r--r--Source/WebCore/rendering/InlineTextBox.cpp81
-rw-r--r--Source/WebCore/rendering/InlineTextBox.h9
-rw-r--r--Source/WebCore/rendering/LayoutState.cpp4
-rw-r--r--Source/WebCore/rendering/LayoutState.h2
-rw-r--r--Source/WebCore/rendering/MediaControlElements.cpp367
-rw-r--r--Source/WebCore/rendering/MediaControlElements.h139
-rw-r--r--Source/WebCore/rendering/RenderBR.h4
-rw-r--r--Source/WebCore/rendering/RenderBlock.cpp530
-rw-r--r--Source/WebCore/rendering/RenderBlock.h71
-rw-r--r--Source/WebCore/rendering/RenderBlockLineLayout.cpp125
-rw-r--r--Source/WebCore/rendering/RenderBox.cpp59
-rw-r--r--Source/WebCore/rendering/RenderBox.h31
-rw-r--r--Source/WebCore/rendering/RenderBoxModelObject.cpp182
-rw-r--r--Source/WebCore/rendering/RenderCombineText.cpp135
-rw-r--r--Source/WebCore/rendering/RenderCombineText.h66
-rw-r--r--Source/WebCore/rendering/RenderCounter.cpp243
-rw-r--r--Source/WebCore/rendering/RenderCounter.h5
-rw-r--r--Source/WebCore/rendering/RenderEmbeddedObject.cpp3
-rw-r--r--Source/WebCore/rendering/RenderFileUploadControl.cpp9
-rw-r--r--Source/WebCore/rendering/RenderFileUploadControl.h4
-rw-r--r--Source/WebCore/rendering/RenderFlexibleBox.cpp4
-rw-r--r--Source/WebCore/rendering/RenderFrameSet.cpp8
-rw-r--r--Source/WebCore/rendering/RenderImage.cpp93
-rw-r--r--Source/WebCore/rendering/RenderImage.h7
-rw-r--r--Source/WebCore/rendering/RenderImageResource.h3
-rw-r--r--Source/WebCore/rendering/RenderImageResourceStyleImage.h2
-rw-r--r--Source/WebCore/rendering/RenderIndicator.cpp41
-rw-r--r--Source/WebCore/rendering/RenderIndicator.h18
-rw-r--r--Source/WebCore/rendering/RenderInline.cpp50
-rw-r--r--Source/WebCore/rendering/RenderLayer.cpp154
-rw-r--r--Source/WebCore/rendering/RenderLayer.h6
-rw-r--r--Source/WebCore/rendering/RenderLayerBacking.cpp8
-rw-r--r--Source/WebCore/rendering/RenderLayerCompositor.cpp2
-rw-r--r--Source/WebCore/rendering/RenderLineBoxList.cpp14
-rw-r--r--Source/WebCore/rendering/RenderListBox.cpp56
-rw-r--r--Source/WebCore/rendering/RenderListBox.h5
-rw-r--r--Source/WebCore/rendering/RenderListItem.cpp4
-rw-r--r--Source/WebCore/rendering/RenderListMarker.cpp33
-rw-r--r--Source/WebCore/rendering/RenderMarquee.cpp4
-rw-r--r--Source/WebCore/rendering/RenderMedia.cpp218
-rw-r--r--Source/WebCore/rendering/RenderMedia.h82
-rw-r--r--Source/WebCore/rendering/RenderMenuList.cpp37
-rw-r--r--Source/WebCore/rendering/RenderMenuList.h4
-rw-r--r--Source/WebCore/rendering/RenderMeter.cpp2
-rw-r--r--Source/WebCore/rendering/RenderObject.cpp57
-rw-r--r--Source/WebCore/rendering/RenderObject.h18
-rw-r--r--Source/WebCore/rendering/RenderObjectChildList.cpp130
-rw-r--r--Source/WebCore/rendering/RenderObjectChildList.h6
-rw-r--r--Source/WebCore/rendering/RenderOverflow.h126
-rw-r--r--Source/WebCore/rendering/RenderProgress.cpp28
-rw-r--r--Source/WebCore/rendering/RenderProgress.h16
-rw-r--r--Source/WebCore/rendering/RenderReplaced.cpp8
-rw-r--r--Source/WebCore/rendering/RenderRubyRun.cpp12
-rw-r--r--Source/WebCore/rendering/RenderRubyRun.h4
-rw-r--r--Source/WebCore/rendering/RenderScrollbarTheme.cpp4
-rw-r--r--Source/WebCore/rendering/RenderTable.cpp16
-rw-r--r--Source/WebCore/rendering/RenderTableCell.cpp10
-rw-r--r--Source/WebCore/rendering/RenderTableRow.cpp2
-rw-r--r--Source/WebCore/rendering/RenderTableSection.cpp10
-rw-r--r--Source/WebCore/rendering/RenderText.cpp35
-rw-r--r--Source/WebCore/rendering/RenderTextControl.cpp10
-rw-r--r--Source/WebCore/rendering/RenderTextControlMultiLine.cpp2
-rw-r--r--Source/WebCore/rendering/RenderTextControlSingleLine.cpp23
-rw-r--r--Source/WebCore/rendering/RenderTheme.h3
-rw-r--r--Source/WebCore/rendering/RenderThemeChromiumMac.h1
-rw-r--r--Source/WebCore/rendering/RenderThemeChromiumWin.cpp6
-rw-r--r--Source/WebCore/rendering/RenderThemeMac.h3
-rw-r--r--Source/WebCore/rendering/RenderThemeMac.mm32
-rw-r--r--Source/WebCore/rendering/RenderThemeSafari.cpp18
-rw-r--r--Source/WebCore/rendering/RenderThemeWin.cpp7
-rw-r--r--Source/WebCore/rendering/RenderThemeWinCE.cpp28
-rw-r--r--Source/WebCore/rendering/RenderTreeAsText.cpp21
-rw-r--r--Source/WebCore/rendering/RenderVideo.cpp16
-rw-r--r--Source/WebCore/rendering/RenderView.cpp18
-rw-r--r--Source/WebCore/rendering/RenderWidget.cpp5
-rw-r--r--Source/WebCore/rendering/RenderingAllInOne.cpp1
-rw-r--r--Source/WebCore/rendering/RootInlineBox.cpp8
-rw-r--r--Source/WebCore/rendering/ShadowElement.cpp2
-rw-r--r--Source/WebCore/rendering/ShadowElement.h6
-rw-r--r--Source/WebCore/rendering/TextControlInnerElements.cpp45
-rw-r--r--Source/WebCore/rendering/TextControlInnerElements.h3
-rw-r--r--Source/WebCore/rendering/TransformState.cpp6
-rw-r--r--Source/WebCore/rendering/break_lines.cpp2
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp2
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLOperator.h2
-rw-r--r--Source/WebCore/rendering/style/RenderStyle.cpp3
-rw-r--r--Source/WebCore/rendering/style/RenderStyle.h5
-rw-r--r--Source/WebCore/rendering/style/RenderStyleConstants.h11
-rw-r--r--Source/WebCore/rendering/style/StyleCachedImage.cpp2
-rw-r--r--Source/WebCore/rendering/style/StyleCachedImage.h2
-rw-r--r--Source/WebCore/rendering/style/StyleGeneratedImage.cpp2
-rw-r--r--Source/WebCore/rendering/style/StyleGeneratedImage.h2
-rw-r--r--Source/WebCore/rendering/style/StyleImage.h4
-rw-r--r--Source/WebCore/rendering/style/StylePendingImage.h3
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGImage.cpp4
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGInlineText.cpp47
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGInlineText.h7
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp39
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceFilter.h3
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp12
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h23
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceMarker.cpp5
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGRoot.cpp7
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGText.cpp21
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp5
-rw-r--r--Source/WebCore/rendering/svg/SVGInlineTextBox.cpp136
-rw-r--r--Source/WebCore/rendering/svg/SVGInlineTextBox.h4
-rw-r--r--Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp2
-rw-r--r--Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.cpp26
-rw-r--r--Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp2
-rw-r--r--Source/WebCore/rendering/svg/SVGTextMetrics.cpp29
-rw-r--r--Source/WebCore/rendering/svg/SVGTextMetrics.h3
-rw-r--r--Source/WebCore/rendering/svg/SVGTextQuery.cpp5
120 files changed, 2664 insertions, 1557 deletions
diff --git a/Source/WebCore/rendering/CounterNode.cpp b/Source/WebCore/rendering/CounterNode.cpp
index fe2148a..eadd386 100644
--- a/Source/WebCore/rendering/CounterNode.cpp
+++ b/Source/WebCore/rendering/CounterNode.cpp
@@ -263,7 +263,7 @@ static void showTreeAndMark(const CounterNode* node)
#ifndef NDEBUG
-void showTree(const WebCore::CounterNode* counter)
+void showCounterTree(const WebCore::CounterNode* counter)
{
if (counter)
showTreeAndMark(counter);
diff --git a/Source/WebCore/rendering/CounterNode.h b/Source/WebCore/rendering/CounterNode.h
index 529d409..639946c 100644
--- a/Source/WebCore/rendering/CounterNode.h
+++ b/Source/WebCore/rendering/CounterNode.h
@@ -94,7 +94,7 @@ private:
#ifndef NDEBUG
// Outside the WebCore namespace for ease of invocation from gdb.
-void showTree(const WebCore::CounterNode*);
+void showCounterTree(const WebCore::CounterNode*);
#endif
#endif // CounterNode_h
diff --git a/Source/WebCore/rendering/EllipsisBox.cpp b/Source/WebCore/rendering/EllipsisBox.cpp
index d367c07..db66b43 100644
--- a/Source/WebCore/rendering/EllipsisBox.cpp
+++ b/Source/WebCore/rendering/EllipsisBox.cpp
@@ -53,7 +53,7 @@ void EllipsisBox::paint(PaintInfo& paintInfo, int tx, int ty)
}
const String& str = m_str;
- context->drawText(style->font(), TextRun(str.characters(), str.length(), false, 0, 0, false, style->visuallyOrdered()), IntPoint(m_x + tx, m_y + ty + style->font().ascent()));
+ context->drawText(style->font(), TextRun(str.characters(), str.length(), false, 0, 0, TextRun::AllowTrailingExpansion, false, style->visuallyOrdered()), IntPoint(m_x + tx, m_y + ty + style->fontMetrics().ascent()));
// Restore the regular fill color.
if (textColor != context->fillColor())
@@ -65,7 +65,7 @@ void EllipsisBox::paint(PaintInfo& paintInfo, int tx, int ty)
if (m_markupBox) {
// Paint the markup box
tx += m_x + m_logicalWidth - m_markupBox->x();
- ty += m_y + style->font().ascent() - (m_markupBox->y() + m_markupBox->renderer()->style(m_firstLine)->font().ascent());
+ ty += m_y + style->fontMetrics().ascent() - (m_markupBox->y() + m_markupBox->renderer()->style(m_firstLine)->fontMetrics().ascent());
m_markupBox->paint(paintInfo, tx, ty);
}
}
@@ -74,7 +74,7 @@ IntRect EllipsisBox::selectionRect(int tx, int ty)
{
RenderStyle* style = m_renderer->style(m_firstLine);
const Font& f = style->font();
- return enclosingIntRect(f.selectionRectForText(TextRun(m_str.characters(), m_str.length(), false, 0, 0, false, style->visuallyOrdered()),
+ return enclosingIntRect(f.selectionRectForText(TextRun(m_str.characters(), m_str.length(), false, 0, 0, TextRun::AllowTrailingExpansion, false, style->visuallyOrdered()),
IntPoint(m_x + tx, m_y + ty + root()->selectionTop()), root()->selectionHeight()));
}
@@ -94,7 +94,7 @@ void EllipsisBox::paintSelection(GraphicsContext* context, int tx, int ty, Rende
int y = root()->selectionTop();
int h = root()->selectionHeight();
context->clip(IntRect(m_x + tx, y + ty, m_logicalWidth, h));
- context->drawHighlightForText(font, TextRun(m_str.characters(), m_str.length(), false, 0, 0, false, style->visuallyOrdered()),
+ context->drawHighlightForText(font, TextRun(m_str.characters(), m_str.length(), false, 0, 0, TextRun::AllowTrailingExpansion, false, style->visuallyOrdered()),
IntPoint(m_x + tx, m_y + ty + y), h, c, style->colorSpace());
context->restore();
}
@@ -108,7 +108,7 @@ bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
if (m_markupBox) {
RenderStyle* style = m_renderer->style(m_firstLine);
int mtx = tx + m_logicalWidth - m_markupBox->x();
- int mty = ty + style->font().ascent() - (m_markupBox->y() + m_markupBox->renderer()->style(m_firstLine)->font().ascent());
+ int mty = ty + style->fontMetrics().ascent() - (m_markupBox->y() + m_markupBox->renderer()->style(m_firstLine)->fontMetrics().ascent());
if (m_markupBox->nodeAtPoint(request, result, x, y, mtx, mty)) {
renderer()->updateHitTestResult(result, IntPoint(x - mtx, y - mty));
return true;
diff --git a/Source/WebCore/rendering/InlineBox.cpp b/Source/WebCore/rendering/InlineBox.cpp
index bbf5a748..4fcbe2d 100644
--- a/Source/WebCore/rendering/InlineBox.cpp
+++ b/Source/WebCore/rendering/InlineBox.cpp
@@ -94,14 +94,14 @@ int InlineBox::logicalHeight() const
#endif
if (renderer()->isText())
- return m_isText ? renderer()->style(m_firstLine)->font().height() : 0;
+ return m_isText ? renderer()->style(m_firstLine)->fontMetrics().height() : 0;
if (renderer()->isBox() && parent())
return isHorizontal() ? toRenderBox(m_renderer)->height() : toRenderBox(m_renderer)->width();
ASSERT(isInlineFlowBox());
RenderBoxModelObject* flowObject = boxModelObject();
- const Font& font = renderer()->style(m_firstLine)->font();
- int result = font.height();
+ const FontMetrics& fontMetrics = renderer()->style(m_firstLine)->fontMetrics();
+ int result = fontMetrics.height();
if (parent())
result += flowObject->borderAndPaddingLogicalHeight();
return result;
diff --git a/Source/WebCore/rendering/InlineBox.h b/Source/WebCore/rendering/InlineBox.h
index 5b3f682..d486ec0 100644
--- a/Source/WebCore/rendering/InlineBox.h
+++ b/Source/WebCore/rendering/InlineBox.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011 Apple 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
@@ -61,7 +61,7 @@ public:
, m_determinedIfPrevOnLineExists(false)
, m_nextOnLineExists(false)
, m_prevOnLineExists(false)
- , m_toAdd(0)
+ , m_expansion(0)
#ifndef NDEBUG
, m_hasBadParent(false)
#endif
@@ -95,7 +95,7 @@ public:
, m_determinedIfPrevOnLineExists(false)
, m_nextOnLineExists(false)
, m_prevOnLineExists(false)
- , m_toAdd(0)
+ , m_expansion(0)
#ifndef NDEBUG
, m_hasBadParent(false)
#endif
@@ -290,7 +290,7 @@ public:
void setHasBadParent();
- int toAdd() const { return m_toAdd; }
+ int expansion() const { return m_expansion; }
bool visibleToHitTesting() const { return renderer()->style()->visibility() == VISIBLE && renderer()->style()->pointerEvents() != PE_NONE; }
@@ -348,7 +348,7 @@ protected:
mutable bool m_determinedIfPrevOnLineExists : 1;
mutable bool m_nextOnLineExists : 1;
mutable bool m_prevOnLineExists : 1;
- int m_toAdd : 11; // for justified text
+ int m_expansion : 11; // for justified text
#ifndef NDEBUG
private:
diff --git a/Source/WebCore/rendering/InlineFlowBox.cpp b/Source/WebCore/rendering/InlineFlowBox.cpp
index 75b23c5..aa9fcb5 100644
--- a/Source/WebCore/rendering/InlineFlowBox.cpp
+++ b/Source/WebCore/rendering/InlineFlowBox.cpp
@@ -408,6 +408,7 @@ static int verticalPositionForBox(InlineBox* box, FontBaseline baselineType, boo
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;
@@ -417,11 +418,11 @@ static int verticalPositionForBox(InlineBox* box, FontBaseline baselineType, boo
else if (verticalAlign == SUPER)
verticalPosition -= fontSize / 3 + 1;
else if (verticalAlign == TEXT_TOP)
- verticalPosition += renderer->baselinePosition(baselineType, firstLine, lineDirection) - font.ascent(baselineType);
+ verticalPosition += renderer->baselinePosition(baselineType, firstLine, lineDirection) - fontMetrics.ascent(baselineType);
else if (verticalAlign == MIDDLE)
- verticalPosition += -static_cast<int>(font.xHeight() / 2) - renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType, firstLine, lineDirection);
+ verticalPosition += -static_cast<int>(fontMetrics.xHeight() / 2) - renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType, firstLine, lineDirection);
else if (verticalAlign == TEXT_BOTTOM) {
- verticalPosition += font.descent(baselineType);
+ 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));
@@ -503,9 +504,10 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
baseline = 0;
int baselineToBottom = 0;
for (size_t i = 0; i < usedFonts->size(); ++i) {
- int halfLeading = (usedFonts->at(i)->lineSpacing() - usedFonts->at(i)->height()) / 2;
- int usedFontBaseline = halfLeading + usedFonts->at(i)->ascent(baselineType);
- int usedFontBaselineToBottom = usedFonts->at(i)->lineSpacing() - usedFontBaseline;
+ const FontMetrics& fontMetrics = usedFonts->at(i)->fontMetrics();
+ int halfLeading = (fontMetrics.lineSpacing() - fontMetrics.height()) / 2;
+ int usedFontBaseline = halfLeading + fontMetrics.ascent(baselineType);
+ int usedFontBaselineToBottom = fontMetrics.lineSpacing() - usedFontBaseline;
if (!baselineSet) {
baselineSet = true;
baseline = usedFontBaseline;
@@ -515,9 +517,9 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
baselineToBottom = max(baselineToBottom, usedFontBaselineToBottom);
}
if (!affectsAscent)
- affectsAscent = usedFonts->at(i)->ascent() - curr->logicalTop() > 0;
+ affectsAscent = fontMetrics.ascent() - curr->logicalTop() > 0;
if (!affectsDescent)
- affectsDescent = usedFonts->at(i)->descent() + curr->logicalTop() > 0;
+ affectsDescent = fontMetrics.descent() + curr->logicalTop() > 0;
}
lineHeight = baseline + baselineToBottom;
} else {
@@ -527,11 +529,12 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
// Examine the font box for inline flows and text boxes to see if any part of it is above the baseline.
// If the top of our font box relative to the root box baseline is above the root box baseline, then
// we are contributing to the maxAscent value.
- affectsAscent = curr->renderer()->style(m_firstLine)->font().ascent(baselineType) - curr->logicalTop() > 0;
+ const FontMetrics& fontMetrics = curr->renderer()->style(m_firstLine)->fontMetrics();
+ affectsAscent = fontMetrics.ascent(baselineType) - curr->logicalTop() > 0;
// Descent is similar. If any part of our font box is below the root box's baseline, then
// we contribute to the maxDescent value.
- affectsDescent = curr->renderer()->style(m_firstLine)->font().descent(baselineType) + curr->logicalTop() > 0;
+ affectsDescent = fontMetrics.descent(baselineType) + curr->logicalTop() > 0;
} else {
// Replaced elements always affect both the ascent and descent.
affectsAscent = true;
@@ -601,13 +604,13 @@ void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAs
}
int newLogicalTop = curr->logicalTop();
- int newLogicalTopIncludingMargins;
+ int newLogicalTopIncludingMargins = newLogicalTop;
int boxHeight = curr->logicalHeight();
int boxHeightIncludingMargins = boxHeight;
if (curr->isText() || curr->isInlineFlowBox()) {
- const Font& font = curr->renderer()->style(m_firstLine)->font();
- newLogicalTop += curr->baselinePosition(baselineType) - font.ascent(baselineType);
+ const FontMetrics& fontMetrics = curr->renderer()->style(m_firstLine)->fontMetrics();
+ newLogicalTop += curr->baselinePosition(baselineType) - fontMetrics.ascent(baselineType);
if (curr->isInlineFlowBox()) {
RenderBoxModelObject* boxObject = toRenderBoxModelObject(curr->renderer());
newLogicalTop -= boxObject->style(m_firstLine)->isHorizontalWritingMode() ? boxObject->borderTop() + boxObject->paddingTop() :
@@ -668,8 +671,8 @@ void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAs
}
if (isRootInlineBox()) {
- const Font& font = renderer()->style(m_firstLine)->font();
- setLogicalTop(logicalTop() + baselinePosition(baselineType) - font.ascent(baselineType));
+ const FontMetrics& fontMetrics = renderer()->style(m_firstLine)->fontMetrics();
+ setLogicalTop(logicalTop() + baselinePosition(baselineType) - fontMetrics.ascent(baselineType));
if (hasTextChildren() || strictMode) {
if (!setLineTop) {
@@ -715,14 +718,14 @@ void InlineFlowBox::addBoxShadowVisualOverflow(IntRect& logicalVisualOverflow)
renderer()->style(m_firstLine)->getBoxShadowBlockDirectionExtent(boxShadowLogicalTop, boxShadowLogicalBottom);
int logicalTopVisualOverflow = min(logicalTop() + boxShadowLogicalTop, logicalVisualOverflow.y());
- int logicalBottomVisualOverflow = max(logicalBottom() + boxShadowLogicalBottom, logicalVisualOverflow.bottom());
+ int logicalBottomVisualOverflow = max(logicalBottom() + boxShadowLogicalBottom, logicalVisualOverflow.maxY());
int boxShadowLogicalLeft;
int boxShadowLogicalRight;
renderer()->style(m_firstLine)->getBoxShadowInlineDirectionExtent(boxShadowLogicalLeft, boxShadowLogicalRight);
int logicalLeftVisualOverflow = min(logicalLeft() + boxShadowLogicalLeft, logicalVisualOverflow.x());
- int logicalRightVisualOverflow = max(logicalRight() + boxShadowLogicalRight, logicalVisualOverflow.right());
+ int logicalRightVisualOverflow = max(logicalRight() + boxShadowLogicalRight, logicalVisualOverflow.maxX());
logicalVisualOverflow = IntRect(logicalLeftVisualOverflow, logicalTopVisualOverflow,
logicalRightVisualOverflow - logicalLeftVisualOverflow, logicalBottomVisualOverflow - logicalTopVisualOverflow);
@@ -777,9 +780,9 @@ void InlineFlowBox::addTextBoxVisualOverflow(const InlineTextBox* textBox, Glyph
int childOverflowLogicalRight = max(textShadowLogicalRight + rightGlyphOverflow, rightGlyphOverflow);
int logicalTopVisualOverflow = min(textBox->logicalTop() + childOverflowLogicalTop, logicalVisualOverflow.y());
- int logicalBottomVisualOverflow = max(textBox->logicalBottom() + childOverflowLogicalBottom, logicalVisualOverflow.bottom());
+ int logicalBottomVisualOverflow = max(textBox->logicalBottom() + childOverflowLogicalBottom, logicalVisualOverflow.maxY());
int logicalLeftVisualOverflow = min(textBox->logicalLeft() + childOverflowLogicalLeft, logicalVisualOverflow.x());
- int logicalRightVisualOverflow = max(textBox->logicalRight() + childOverflowLogicalRight, logicalVisualOverflow.right());
+ int logicalRightVisualOverflow = max(textBox->logicalRight() + childOverflowLogicalRight, logicalVisualOverflow.maxX());
logicalVisualOverflow = IntRect(logicalLeftVisualOverflow, logicalTopVisualOverflow,
logicalRightVisualOverflow - logicalLeftVisualOverflow, logicalBottomVisualOverflow - logicalTopVisualOverflow);
@@ -1005,14 +1008,21 @@ void InlineFlowBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, c
// strip. Even though that strip has been broken up across multiple lines, you still paint it
// as though you had one single line. This means each line has to pick up the background where
// the previous line left off.
- // FIXME: What the heck do we do with RTL here? The math we're using is obviously not right,
- // but it isn't even clear how this should work at all.
int logicalOffsetOnLine = 0;
- for (InlineFlowBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
- logicalOffsetOnLine += curr->logicalWidth();
- int totalLogicalWidth = logicalOffsetOnLine;
- for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox())
- totalLogicalWidth += curr->logicalWidth();
+ int totalLogicalWidth;
+ if (renderer()->style()->direction() == LTR) {
+ for (InlineFlowBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
+ logicalOffsetOnLine += curr->logicalWidth();
+ totalLogicalWidth = logicalOffsetOnLine;
+ for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox())
+ totalLogicalWidth += curr->logicalWidth();
+ } else {
+ for (InlineFlowBox* curr = nextLineBox(); curr; curr = curr->nextLineBox())
+ logicalOffsetOnLine += curr->logicalWidth();
+ totalLogicalWidth = logicalOffsetOnLine;
+ for (InlineFlowBox* curr = this; curr; curr = curr->prevLineBox())
+ totalLogicalWidth += curr->logicalWidth();
+ }
int stripX = tx - (isHorizontal() ? logicalOffsetOnLine : 0);
int stripY = ty - (isHorizontal() ? 0 : logicalOffsetOnLine);
int stripWidth = isHorizontal() ? totalLogicalWidth : width();
diff --git a/Source/WebCore/rendering/InlineFlowBox.h b/Source/WebCore/rendering/InlineFlowBox.h
index 232c3b7..d47111f8 100644
--- a/Source/WebCore/rendering/InlineFlowBox.h
+++ b/Source/WebCore/rendering/InlineFlowBox.h
@@ -183,19 +183,18 @@ public:
void checkConsistency() const;
void setHasBadChildList();
- // Line visual and layout overflow are in the coordinate space of the block. This means that - unlike other unprefixed uses of the words
- // top/right/bottom/left in the code - these aren't purely physical directions. 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 inverted when compared to
- // their physical counterparts.
- int topLayoutOverflow() const { return m_overflow ? m_overflow->topLayoutOverflow() : m_y; }
- int bottomLayoutOverflow() const { return m_overflow ? m_overflow->bottomLayoutOverflow() : m_y + height(); }
- int leftLayoutOverflow() const { return m_overflow ? m_overflow->leftLayoutOverflow() : m_x; }
- int rightLayoutOverflow() const { return m_overflow ? m_overflow->rightLayoutOverflow() : m_x + width(); }
+ // Line visual and layout overflow are in the coordinate space of the block. This means that they aren't purely physical directions.
+ // 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 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 logicalLeftLayoutOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? leftLayoutOverflow() : topLayoutOverflow(); }
- int logicalRightLayoutOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? rightLayoutOverflow() : bottomLayoutOverflow(); }
- int logicalTopLayoutOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? topVisualOverflow() : leftVisualOverflow(); }
- int logicalBottomLayoutOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? bottomLayoutOverflow() : rightLayoutOverflow(); }
+ 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(); }
+ int logicalBottomLayoutOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? maxYLayoutOverflow() : maxXLayoutOverflow(); }
IntRect logicalLayoutOverflowRect() const
{
IntRect result = layoutOverflowRect();
@@ -204,15 +203,15 @@ public:
return result;
}
- int topVisualOverflow() const { return m_overflow ? m_overflow->topVisualOverflow() : m_y; }
- int bottomVisualOverflow() const { return m_overflow ? m_overflow->bottomVisualOverflow() : m_y + height(); }
- int leftVisualOverflow() const { return m_overflow ? m_overflow->leftVisualOverflow() : m_x; }
- int rightVisualOverflow() const { return m_overflow ? m_overflow->rightVisualOverflow() : m_x + width(); }
+ int minYVisualOverflow() const { return m_overflow ? m_overflow->minYVisualOverflow() : m_y; }
+ int maxYVisualOverflow() const { return m_overflow ? m_overflow->maxYVisualOverflow() : 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 logicalLeftVisualOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? leftVisualOverflow() : topVisualOverflow(); }
- int logicalRightVisualOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? rightVisualOverflow() : bottomVisualOverflow(); }
- int logicalTopVisualOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? topVisualOverflow() : leftVisualOverflow(); }
- int logicalBottomVisualOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? bottomVisualOverflow() : rightVisualOverflow(); }
+ 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(); }
+ int logicalBottomVisualOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? maxYVisualOverflow() : maxXVisualOverflow(); }
IntRect logicalVisualOverflowRect() const
{
IntRect result = visualOverflowRect();
diff --git a/Source/WebCore/rendering/InlineTextBox.cpp b/Source/WebCore/rendering/InlineTextBox.cpp
index 8992964..9f7e024 100644
--- a/Source/WebCore/rendering/InlineTextBox.cpp
+++ b/Source/WebCore/rendering/InlineTextBox.cpp
@@ -1,7 +1,7 @@
/*
* (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple 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
@@ -36,11 +36,11 @@
#include "PaintInfo.h"
#include "RenderArena.h"
#include "RenderBlock.h"
+#include "RenderCombineText.h"
#include "RenderRubyRun.h"
#include "RenderRubyText.h"
#include "RenderTheme.h"
#include "Text.h"
-#include "TextRun.h"
#include "break_lines.h"
#include <wtf/AlwaysInline.h>
@@ -163,6 +163,7 @@ IntRect InlineTextBox::selectionRect(int tx, int ty, int startPos, int endPos)
ePos = len;
}
+<<<<<<< HEAD
#ifdef ANDROID_DISABLE_ROUNDING_HACKS
TextRun textRun = TextRun(characters, len, textObj->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride);
if (m_disableRoundingHacks)
@@ -170,13 +171,16 @@ IntRect InlineTextBox::selectionRect(int tx, int ty, int startPos, int endPos)
IntRect r = enclosingIntRect(f.selectionRectForText(textRun, IntPoint(), selHeight, sPos, ePos));
#else
IntRect r = enclosingIntRect(f.selectionRectForText(TextRun(characters, len, textObj->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride),
+=======
+ IntRect r = enclosingIntRect(f.selectionRectForText(TextRun(characters, len, textObj->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride),
+>>>>>>> webkit.org at r78450
IntPoint(), selHeight, sPos, ePos));
#endif
int logicalWidth = r.width();
if (r.x() > m_logicalWidth)
logicalWidth = 0;
- else if (r.right() > m_logicalWidth)
+ else if (r.maxX() > m_logicalWidth)
logicalWidth = m_logicalWidth - r.x();
IntPoint topPoint = isHorizontal() ? IntPoint(tx + m_x + r.x(), ty + selTop) : IntPoint(tx + selTop, ty + m_y + r.x());
@@ -449,7 +453,7 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty)
int logicalStart = logicalLeft() - logicalLeftOverflow + (isHorizontal() ? tx : ty);
int logicalExtent = logicalWidth() + logicalLeftOverflow + logicalRightOverflow;
- int paintEnd = isHorizontal() ? paintInfo.rect.right() : paintInfo.rect.bottom();
+ int paintEnd = isHorizontal() ? paintInfo.rect.maxX() : paintInfo.rect.maxY();
int paintStart = isHorizontal() ? paintInfo.rect.x() : paintInfo.rect.y();
if (logicalStart >= paintEnd || logicalStart + logicalExtent <= paintStart)
@@ -492,13 +496,15 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty)
IntPoint boxOrigin = locationIncludingFlipping();
boxOrigin.move(tx, ty);
IntRect boxRect(boxOrigin, IntSize(logicalWidth(), logicalHeight()));
- IntPoint textOrigin = IntPoint(boxOrigin.x(), boxOrigin.y() + styleToUse->font().ascent());
+ IntPoint textOrigin = IntPoint(boxOrigin.x(), boxOrigin.y() + styleToUse->fontMetrics().ascent());
- if (!isHorizontal()) {
+ RenderCombineText* combinedText = styleToUse->hasTextCombine() ? toRenderCombineText(textRenderer()) : 0;
+ bool shouldRotate = !isHorizontal() && (!combinedText || !combinedText->isCombined());
+ if (shouldRotate) {
context->save();
- context->translate(boxRect.x(), boxRect.bottom());
+ context->translate(boxRect.x(), boxRect.maxY());
context->rotate(static_cast<float>(deg2rad(90.)));
- context->translate(-boxRect.x(), -boxRect.bottom());
+ context->translate(-boxRect.x(), -boxRect.maxY());
}
@@ -510,6 +516,9 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty)
int d = styleToUse->textDecorationsInEffect();
const Font& font = styleToUse->font();
+ if (combinedText)
+ combinedText->adjustTextOrigin(textOrigin, boxRect);
+
// 1. Paint backgrounds behind text if needed. Examples of such backgrounds include selection
// and composition underlines.
if (paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseTextClip && !isPrinting) {
@@ -609,17 +618,26 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty)
}
}
- const UChar* characters = textRenderer()->text()->characters() + m_start;
int length = m_len;
+ const UChar* characters;
+ if (!combinedText)
+ characters = textRenderer()->text()->characters() + m_start;
+ else
+ combinedText->charactersToRender(m_start, characters, length);
+
BufferForAppendingHyphen charactersWithHyphen;
if (hasHyphen())
adjustCharactersAndLengthForHyphen(charactersWithHyphen, styleToUse, characters, length);
+<<<<<<< HEAD
TextRun textRun(characters, length, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride || styleToUse->visuallyOrdered());
#ifdef ANDROID_DISABLE_ROUNDING_HACKS
if (m_disableRoundingHacks)
textRun.disableRoundingHacks();
#endif
+=======
+ TextRun textRun(characters, length, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || styleToUse->visuallyOrdered());
+>>>>>>> webkit.org at r78450
int sPos = 0;
int ePos = 0;
@@ -637,7 +655,7 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty)
bool hasTextEmphasis = getEmphasisMarkPosition(styleToUse, emphasisMarkPosition);
const AtomicString& emphasisMark = hasTextEmphasis ? styleToUse->textEmphasisMarkString() : nullAtom;
if (!emphasisMark.isEmpty())
- emphasisMarkOffset = emphasisMarkPosition == TextEmphasisPositionOver ? -font.ascent() - font.emphasisMarkDescent(emphasisMark) : font.descent() + font.emphasisMarkAscent(emphasisMark);
+ emphasisMarkOffset = emphasisMarkPosition == TextEmphasisPositionOver ? -font.fontMetrics().ascent() - font.emphasisMarkDescent(emphasisMark) : font.fontMetrics().descent() + font.emphasisMarkAscent(emphasisMark);
if (!paintSelectedTextOnly) {
// For stroked painting, we have to change the text drawing mode. It's probably dangerous to leave that mutated as a side
@@ -715,7 +733,7 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty)
}
}
- if (!isHorizontal())
+ if (shouldRotate)
context->restore();
}
@@ -773,6 +791,7 @@ void InlineTextBox::paintSelection(GraphicsContext* context, const IntPoint& box
int selHeight = selectionHeight();
IntPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
context->clip(IntRect(localOrigin, IntSize(m_logicalWidth, selHeight)));
+<<<<<<< HEAD
#ifdef ANDROID_DISABLE_ROUNDING_HACKS
TextRun textRun = TextRun(characters, length, textRenderer()->allowTabs(), textPos(), m_toAdd,
!isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
@@ -781,6 +800,9 @@ void InlineTextBox::paintSelection(GraphicsContext* context, const IntPoint& box
context->drawHighlightForText(font, textRun, localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
#else
context->drawHighlightForText(font, TextRun(characters, length, textRenderer()->allowTabs(), textPos(), m_toAdd,
+=======
+ context->drawHighlightForText(font, TextRun(characters, length, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(),
+>>>>>>> webkit.org at r78450
!isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()),
localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
#endif
@@ -805,6 +827,7 @@ void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const I
int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
int selHeight = selectionHeight();
IntPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
+<<<<<<< HEAD
#ifdef ANDROID_DISABLE_ROUNDING_HACKS
TextRun textRun = TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd,
!isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
@@ -813,6 +836,9 @@ void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const I
context->drawHighlightForText(font, textRun, localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
#else
context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd,
+=======
+ context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(),
+>>>>>>> webkit.org at r78450
!isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()),
localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
#endif
@@ -864,7 +890,7 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const IntPoint& bo
bool linesAreOpaque = !isPrinting && (!(deco & UNDERLINE) || underline.alpha() == 255) && (!(deco & OVERLINE) || overline.alpha() == 255) && (!(deco & LINE_THROUGH) || linethrough.alpha() == 255);
RenderStyle* styleToUse = renderer()->style(m_firstLine);
- int baseline = styleToUse->font().ascent();
+ int baseline = styleToUse->fontMetrics().ascent();
bool setClip = false;
int extraOffset = 0;
@@ -975,11 +1001,15 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, const IntP
int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
int selHeight = selectionHeight();
IntPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY);
+<<<<<<< HEAD
TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
#ifdef ANDROID_DISABLE_ROUNDING_HACKS
if (m_disableRoundingHacks)
run.disableRoundingHacks();
#endif
+=======
+ TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
+>>>>>>> webkit.org at r78450
IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, selHeight, startPosition, endPosition));
start = markerRect.x() - startPoint.x();
@@ -1001,7 +1031,7 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, const IntP
// So, we generally place the underline at the bottom of the text, but in larger fonts that's not so good so
// we pin to two pixels under the baseline.
int lineThickness = cMisspellingLineThickness;
- int baseline = renderer()->style(m_firstLine)->font().ascent();
+ int baseline = renderer()->style(m_firstLine)->fontMetrics().ascent();
int descent = logicalHeight() - baseline;
int underlineOffset;
if (descent <= (2 + lineThickness)) {
@@ -1023,11 +1053,15 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const IntPoint& bo
int sPos = max(marker.startOffset - m_start, (unsigned)0);
int ePos = min(marker.endOffset - m_start, (unsigned)m_len);
+<<<<<<< HEAD
TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
#ifdef ANDROID_DISABLE_ROUNDING_HACKS
if (m_disableRoundingHacks)
run.disableRoundingHacks();
#endif
+=======
+ TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
+>>>>>>> webkit.org at r78450
// Always compute and store the rect associated with this marker. The computed rect is in absolute coordinates.
IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoint(m_x, selectionTop()), selHeight, sPos, ePos));
@@ -1055,11 +1089,15 @@ void InlineTextBox::computeRectForReplacementMarker(const DocumentMarker& marker
int sPos = max(marker.startOffset - m_start, (unsigned)0);
int ePos = min(marker.endOffset - m_start, (unsigned)m_len);
+<<<<<<< HEAD
TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
#ifdef ANDROID_DISABLE_ROUNDING_HACKS
if (m_disableRoundingHacks)
run.disableRoundingHacks();
#endif
+=======
+ TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
+>>>>>>> webkit.org at r78450
IntPoint startPoint = IntPoint(m_x, y);
// Compute and store the rect associated with this marker.
@@ -1085,9 +1123,7 @@ void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, const IntPoint& bo
switch (marker.type) {
case DocumentMarker::Grammar:
case DocumentMarker::Spelling:
- case DocumentMarker::Replacement:
case DocumentMarker::CorrectionIndicator:
- case DocumentMarker::RejectedCorrection:
if (background)
continue;
break;
@@ -1095,9 +1131,8 @@ void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, const IntPoint& bo
if (!background)
continue;
break;
-
default:
- ASSERT_NOT_REACHED();
+ continue;
}
if (marker.endOffset <= start())
@@ -1124,9 +1159,6 @@ void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, const IntPoint& bo
computeRectForReplacementMarker(marker, style, font);
paintSpellingOrGrammarMarker(pt, boxOrigin, marker, style, font, false);
break;
- case DocumentMarker::Replacement:
- case DocumentMarker::RejectedCorrection:
- break;
default:
ASSERT_NOT_REACHED();
}
@@ -1166,7 +1198,7 @@ void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, const IntPoi
// All other marked text underlines are 1px thick.
// If there's not enough space the underline will touch or overlap characters.
int lineThickness = 1;
- int baseline = renderer()->style(m_firstLine)->font().ascent();
+ int baseline = renderer()->style(m_firstLine)->fontMetrics().ascent();
if (underline.thick && logicalHeight() - baseline >= 2)
lineThickness = 2;
@@ -1230,7 +1262,7 @@ int InlineTextBox::offsetForPosition(int lineOffset, bool includePartialGlyphs)
int offset = f->offsetForPosition(textRun, lineOffset - logicalLeft(), includePartialGlyphs);
#else
int offset = f->offsetForPosition(TextRun(textRenderer()->text()->characters() + m_start, m_len,
- textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()),
+ textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()),
lineOffset - logicalLeft(), includePartialGlyphs);
#endif
if (blockIsInOppositeDirection && (!offset || offset == m_len))
@@ -1251,6 +1283,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_toAdd, !isLeftToRightDirection(), m_dirOverride);
if (m_disableRoundingHacks)
@@ -1260,6 +1293,10 @@ int InlineTextBox::positionForOffset(int offset) const
return enclosingIntRect(f.selectionRectForText(TextRun(text->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride),
IntPoint(logicalLeft(), 0), 0, from, to)).right();
#endif
+=======
+ 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();
+>>>>>>> webkit.org at r78450
}
bool InlineTextBox::containsCaretOffset(int offset) const
diff --git a/Source/WebCore/rendering/InlineTextBox.h b/Source/WebCore/rendering/InlineTextBox.h
index ee75f06..095fa16 100644
--- a/Source/WebCore/rendering/InlineTextBox.h
+++ b/Source/WebCore/rendering/InlineTextBox.h
@@ -1,7 +1,7 @@
/*
* (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2009, 2010, 2011 Apple 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
@@ -25,6 +25,7 @@
#include "InlineBox.h"
#include "RenderText.h" // so textRenderer() can be inline
+#include "TextRun.h"
namespace WebCore {
@@ -88,7 +89,7 @@ private:
int selectionHeight();
public:
- virtual IntRect calculateBoundaries() const { return IntRect(x(), y(), logicalWidth(), logicalHeight()); }
+ virtual IntRect calculateBoundaries() const { return IntRect(x(), y(), width(), height()); }
virtual IntRect selectionRect(int absx, int absy, int startPos, int endPos);
bool isSelected(int startPos, int endPos) const;
@@ -116,7 +117,7 @@ private:
public:
virtual bool isLineBreak() const;
- void setSpaceAdd(int add) { m_logicalWidth -= m_toAdd; m_toAdd = add; m_logicalWidth += m_toAdd; }
+ void setExpansion(int expansion) { m_logicalWidth -= m_expansion; m_expansion = expansion; m_logicalWidth += m_expansion; }
private:
virtual bool isInlineTextBox() const { return true; }
@@ -166,6 +167,8 @@ private:
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 computeRectForReplacementMarker(const DocumentMarker&, RenderStyle*, const Font&);
+
+ TextRun::TrailingExpansionBehavior trailingExpansionBehavior() const { return m_expansion && nextLeafChild() ? TextRun::AllowTrailingExpansion : TextRun::ForbidTrailingExpansion; }
};
inline RenderText* InlineTextBox::textRenderer() const
diff --git a/Source/WebCore/rendering/LayoutState.cpp b/Source/WebCore/rendering/LayoutState.cpp
index aeba416..8e4201e 100644
--- a/Source/WebCore/rendering/LayoutState.cpp
+++ b/Source/WebCore/rendering/LayoutState.cpp
@@ -167,11 +167,11 @@ int LayoutState::pageLogicalOffset(int childLogicalOffset) const
return m_layoutOffset.height() + childLogicalOffset - m_pageOffset.height();
}
-void LayoutState::addForcedColumnBreak(int childY)
+void LayoutState::addForcedColumnBreak(int childLogicalOffset)
{
if (!m_columnInfo || m_columnInfo->columnHeight())
return;
- m_columnInfo->addForcedBreak(pageLogicalOffset(childY));
+ m_columnInfo->addForcedBreak(pageLogicalOffset(childLogicalOffset));
}
} // namespace WebCore
diff --git a/Source/WebCore/rendering/LayoutState.h b/Source/WebCore/rendering/LayoutState.h
index c499435..f14c9ff 100644
--- a/Source/WebCore/rendering/LayoutState.h
+++ b/Source/WebCore/rendering/LayoutState.h
@@ -71,7 +71,7 @@ public:
// direction (so an x-offset in vertical text and a y-offset for horizontal text).
int pageLogicalOffset(int childLogicalOffset) const;
- void addForcedColumnBreak(int childY);
+ void addForcedColumnBreak(int childLogicalOffset);
bool pageLogicalHeight() const { return m_pageLogicalHeight; }
bool pageLogicalHeightChanged() const { return m_pageLogicalHeightChanged; }
diff --git a/Source/WebCore/rendering/MediaControlElements.cpp b/Source/WebCore/rendering/MediaControlElements.cpp
index 1f66719..3acce61 100644
--- a/Source/WebCore/rendering/MediaControlElements.cpp
+++ b/Source/WebCore/rendering/MediaControlElements.cpp
@@ -32,11 +32,13 @@
#include "MediaControlElements.h"
+#include "CSSStyleSelector.h"
#include "EventNames.h"
#include "FloatConversion.h"
#include "Frame.h"
#include "HTMLNames.h"
#include "LocalizedStrings.h"
+#include "MediaControls.h"
#include "MouseEvent.h"
#include "Page.h"
#include "RenderMedia.h"
@@ -88,14 +90,6 @@ PassRefPtr<MediaControlShadowRootElement> MediaControlShadowRootElement::create(
return element.release();
}
-void MediaControlShadowRootElement::updateStyle()
-{
- if (renderer()) {
- RenderStyle* timelineContainerStyle = shadowHost()->renderer()->getCachedPseudoStyle(MEDIA_CONTROLS_TIMELINE_CONTAINER);
- renderer()->setStyle(timelineContainerStyle);
- }
-}
-
void MediaControlShadowRootElement::detach()
{
HTMLDivElement::detach();
@@ -105,40 +99,11 @@ void MediaControlShadowRootElement::detach()
// ----------------------------
-MediaControlElement::MediaControlElement(HTMLMediaElement* mediaElement, PseudoId pseudo)
+MediaControlElement::MediaControlElement(HTMLMediaElement* mediaElement)
: HTMLDivElement(divTag, mediaElement->document())
, m_mediaElement(mediaElement)
- , m_pseudoStyleId(pseudo)
{
setInDocument();
- switch (pseudo) {
- case MEDIA_CONTROLS_CURRENT_TIME_DISPLAY:
- m_displayType = MediaCurrentTimeDisplay;
- break;
- case MEDIA_CONTROLS_TIME_REMAINING_DISPLAY:
- m_displayType = MediaTimeRemainingDisplay;
- break;
- case MEDIA_CONTROLS_TIMELINE_CONTAINER:
- m_displayType = MediaTimelineContainer;
- break;
- case MEDIA_CONTROLS_STATUS_DISPLAY:
- m_displayType = MediaStatusDisplay;
- break;
- case MEDIA_CONTROLS_PANEL:
- m_displayType = MediaControlsPanel;
- break;
- case MEDIA_CONTROLS_VOLUME_SLIDER_CONTAINER:
- m_displayType = MediaVolumeSliderContainer;
- break;
- default:
- ASSERT_NOT_REACHED();
- break;
- }
-}
-
-PassRefPtr<MediaControlElement> MediaControlElement::create(HTMLMediaElement* mediaElement, PseudoId pseudoStyleId)
-{
- return adoptRef(new MediaControlElement(mediaElement, pseudoStyleId));
}
void MediaControlElement::attachToParent(Element* parent)
@@ -157,7 +122,8 @@ void MediaControlElement::update()
PassRefPtr<RenderStyle> MediaControlElement::styleForElement()
{
- RenderStyle* style = m_mediaElement->renderer()->getCachedPseudoStyle(m_pseudoStyleId);
+ ASSERT(m_mediaElement->renderer());
+ RefPtr<RenderStyle> style = document()->styleSelector()->styleForElement(this, m_mediaElement->renderer()->style(), true);
if (!style)
return 0;
@@ -225,8 +191,31 @@ void MediaControlElement::updateStyle()
// ----------------------------
+inline MediaControlPanelElement::MediaControlPanelElement(HTMLMediaElement* mediaElement)
+ : MediaControlElement(mediaElement)
+{
+}
+
+PassRefPtr<MediaControlPanelElement> MediaControlPanelElement::create(HTMLMediaElement* mediaElement)
+{
+ return adoptRef(new MediaControlPanelElement(mediaElement));
+}
+
+MediaControlElementType MediaControlPanelElement::displayType() const
+{
+ return MediaControlsPanel;
+}
+
+const AtomicString& MediaControlPanelElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-panel"));
+ return id;
+}
+
+// ----------------------------
+
inline MediaControlTimelineContainerElement::MediaControlTimelineContainerElement(HTMLMediaElement* mediaElement)
- : MediaControlElement(mediaElement, MEDIA_CONTROLS_TIMELINE_CONTAINER)
+ : MediaControlElement(mediaElement)
{
}
@@ -240,20 +229,29 @@ bool MediaControlTimelineContainerElement::rendererIsNeeded(RenderStyle* style)
if (!MediaControlElement::rendererIsNeeded(style))
return false;
- // This is for MediaControllerThemeClassic:
- // If there is no style for MediaControlStatusDisplayElement style, don't hide
- // the timeline.
- if (!mediaElement()->renderer()->getCachedPseudoStyle(MEDIA_CONTROLS_STATUS_DISPLAY))
+ // Always show the timeline if the theme doesn't use status display (MediaControllerThemeClassic, for instance).
+ if (!document()->page()->theme()->usesMediaControlStatusDisplay())
return true;
float duration = mediaElement()->duration();
return !isnan(duration) && !isinf(duration);
}
+MediaControlElementType MediaControlTimelineContainerElement::displayType() const
+{
+ return MediaTimelineContainer;
+}
+
+const AtomicString& MediaControlTimelineContainerElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-timeline-container"));
+ return id;
+}
+
// ----------------------------
inline MediaControlVolumeSliderContainerElement::MediaControlVolumeSliderContainerElement(HTMLMediaElement* mediaElement)
- : MediaControlElement(mediaElement, MEDIA_CONTROLS_VOLUME_SLIDER_CONTAINER)
+ : MediaControlElement(mediaElement)
, m_isVisible(false)
, m_x(0)
, m_y(0)
@@ -298,10 +296,21 @@ bool MediaControlVolumeSliderContainerElement::hitTest(const IntPoint& absPoint)
return false;
}
+MediaControlElementType MediaControlVolumeSliderContainerElement::displayType() const
+{
+ return MediaVolumeSliderContainer;
+}
+
+const AtomicString& MediaControlVolumeSliderContainerElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-volume-slider-container"));
+ return id;
+}
+
// ----------------------------
inline MediaControlStatusDisplayElement::MediaControlStatusDisplayElement(HTMLMediaElement* mediaElement)
- : MediaControlElement(mediaElement, MEDIA_CONTROLS_STATUS_DISPLAY)
+ : MediaControlElement(mediaElement)
, m_stateBeingDisplayed(Nothing)
{
}
@@ -344,59 +353,30 @@ void MediaControlStatusDisplayElement::update()
bool MediaControlStatusDisplayElement::rendererIsNeeded(RenderStyle* style)
{
- if (!MediaControlElement::rendererIsNeeded(style))
+ if (!MediaControlElement::rendererIsNeeded(style) || !document()->page()->theme()->usesMediaControlStatusDisplay())
return false;
float duration = mediaElement()->duration();
return (isnan(duration) || isinf(duration));
}
+MediaControlElementType MediaControlStatusDisplayElement::displayType() const
+{
+ return MediaStatusDisplay;
+}
+
+const AtomicString& MediaControlStatusDisplayElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-status-display"));
+ return id;
+}
+
// ----------------------------
-MediaControlInputElement::MediaControlInputElement(HTMLMediaElement* mediaElement, PseudoId pseudo)
- : HTMLInputElement(inputTag, mediaElement->document())
+MediaControlInputElement::MediaControlInputElement(HTMLMediaElement* mediaElement, MediaControlElementType displayType)
+ : HTMLInputElement(inputTag, mediaElement->document(), 0, false)
, m_mediaElement(mediaElement)
- , m_pseudoStyleId(pseudo)
+ , m_displayType(displayType)
{
- setInDocument();
-
- switch (pseudo) {
- case MEDIA_CONTROLS_MUTE_BUTTON:
- m_displayType = MediaMuteButton;
- break;
- case MEDIA_CONTROLS_PLAY_BUTTON:
- m_displayType = MediaPlayButton;
- break;
- case MEDIA_CONTROLS_SEEK_FORWARD_BUTTON:
- m_displayType = MediaSeekForwardButton;
- break;
- case MEDIA_CONTROLS_SEEK_BACK_BUTTON:
- m_displayType = MediaSeekBackButton;
- break;
- case MEDIA_CONTROLS_FULLSCREEN_BUTTON:
- m_displayType = MediaFullscreenButton;
- break;
- case MEDIA_CONTROLS_TIMELINE:
- m_displayType = MediaSlider;
- break;
- case MEDIA_CONTROLS_RETURN_TO_REALTIME_BUTTON:
- m_displayType = MediaReturnToRealtimeButton;
- break;
- case MEDIA_CONTROLS_REWIND_BUTTON:
- m_displayType = MediaRewindButton;
- break;
- case MEDIA_CONTROLS_VOLUME_SLIDER:
- m_displayType = MediaVolumeSlider;
- break;
- case MEDIA_CONTROLS_VOLUME_SLIDER_MUTE_BUTTON:
- m_displayType = MediaVolumeSliderMuteButton;
- break;
- case MEDIA_CONTROLS_TOGGLE_CLOSED_CAPTIONS_BUTTON:
- m_displayType = MediaShowClosedCaptionsButton;
- break;
- default:
- ASSERT_NOT_REACHED();
- break;
- }
}
void MediaControlInputElement::attachToParent(Element* parent)
@@ -416,7 +396,7 @@ void MediaControlInputElement::update()
PassRefPtr<RenderStyle> MediaControlInputElement::styleForElement()
{
- return mediaElement()->renderer()->getCachedPseudoStyle(m_pseudoStyleId);
+ return document()->styleSelector()->styleForElement(this, 0, true);
}
bool MediaControlInputElement::rendererIsNeeded(RenderStyle* style)
@@ -481,7 +461,7 @@ void MediaControlInputElement::updateStyle()
if (Node* shadowNode = shadowRoot())
shadowNode->recalcStyle(Node::Force);
}
-
+
bool MediaControlInputElement::hitTest(const IntPoint& absPoint)
{
if (renderer() && renderer()->style()->hasAppearance())
@@ -502,14 +482,14 @@ void MediaControlInputElement::setDisplayType(MediaControlElementType displayTyp
// ----------------------------
-inline MediaControlMuteButtonElement::MediaControlMuteButtonElement(HTMLMediaElement* mediaElement, ButtonLocation location)
- : MediaControlInputElement(mediaElement, location == Controller ? MEDIA_CONTROLS_MUTE_BUTTON : MEDIA_CONTROLS_VOLUME_SLIDER_MUTE_BUTTON)
+inline MediaControlMuteButtonElement::MediaControlMuteButtonElement(HTMLMediaElement* mediaElement, MediaControlElementType displayType)
+ : MediaControlInputElement(mediaElement, displayType)
{
}
-PassRefPtr<MediaControlMuteButtonElement> MediaControlMuteButtonElement::create(HTMLMediaElement* mediaElement, ButtonLocation location)
+PassRefPtr<MediaControlMuteButtonElement> MediaControlMuteButtonElement::create(HTMLMediaElement* mediaElement)
{
- RefPtr<MediaControlMuteButtonElement> button = adoptRef(new MediaControlMuteButtonElement(mediaElement, location));
+ RefPtr<MediaControlMuteButtonElement> button = adoptRef(new MediaControlMuteButtonElement(mediaElement, MediaMuteButton));
button->setType("button");
return button.release();
}
@@ -523,15 +503,39 @@ void MediaControlMuteButtonElement::defaultEventHandler(Event* event)
HTMLInputElement::defaultEventHandler(event);
}
+const AtomicString& MediaControlMuteButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-mute-button"));
+ return id;
+}
+
void MediaControlMuteButtonElement::updateDisplayType()
{
setDisplayType(mediaElement()->muted() ? MediaUnMuteButton : MediaMuteButton);
}
+inline MediaControlVolumeSliderMuteButtonElement::MediaControlVolumeSliderMuteButtonElement(HTMLMediaElement* mediaElement)
+ : MediaControlMuteButtonElement(mediaElement, MediaVolumeSliderMuteButton)
+{
+}
+
+PassRefPtr<MediaControlVolumeSliderMuteButtonElement> MediaControlVolumeSliderMuteButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlVolumeSliderMuteButtonElement> button = adoptRef(new MediaControlVolumeSliderMuteButtonElement(mediaElement));
+ button->setType("button");
+ return button.release();
+}
+
+const AtomicString& MediaControlVolumeSliderMuteButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-volume-slider-mute-button"));
+ return id;
+}
+
// ----------------------------
inline MediaControlPlayButtonElement::MediaControlPlayButtonElement(HTMLMediaElement* mediaElement)
- : MediaControlInputElement(mediaElement, MEDIA_CONTROLS_PLAY_BUTTON)
+ : MediaControlInputElement(mediaElement, MediaPlayButton)
{
}
@@ -556,28 +560,22 @@ void MediaControlPlayButtonElement::updateDisplayType()
setDisplayType(mediaElement()->canPlay() ? MediaPlayButton : MediaPauseButton);
}
+const AtomicString& MediaControlPlayButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-play-button"));
+ return id;
+}
+
// ----------------------------
-inline MediaControlSeekButtonElement::MediaControlSeekButtonElement(HTMLMediaElement* mediaElement, PseudoId pseudoId)
- : MediaControlInputElement(mediaElement, pseudoId)
+inline MediaControlSeekButtonElement::MediaControlSeekButtonElement(HTMLMediaElement* mediaElement, MediaControlElementType displayType)
+ : MediaControlInputElement(mediaElement, displayType)
, m_seeking(false)
, m_capturing(false)
, m_seekTimer(this, &MediaControlSeekButtonElement::seekTimerFired)
{
}
-PassRefPtr<MediaControlSeekButtonElement> MediaControlSeekButtonElement::create(HTMLMediaElement* mediaElement, PseudoId pseudoStyleId)
-{
- RefPtr<MediaControlSeekButtonElement> button = adoptRef(new MediaControlSeekButtonElement(mediaElement, pseudoStyleId));
- button->setType("button");
- return button.release();
-}
-
-inline bool MediaControlSeekButtonElement::isForwardButton() const
-{
- return pseudoStyleId() == MEDIA_CONTROLS_SEEK_FORWARD_BUTTON;
-}
-
void MediaControlSeekButtonElement::defaultEventHandler(Event* event)
{
if (event->type() == eventNames().mousedownEvent) {
@@ -627,8 +625,48 @@ void MediaControlSeekButtonElement::detach()
// ----------------------------
+inline MediaControlSeekForwardButtonElement::MediaControlSeekForwardButtonElement(HTMLMediaElement* mediaElement)
+ : MediaControlSeekButtonElement(mediaElement, MediaSeekForwardButton)
+{
+}
+
+PassRefPtr<MediaControlSeekForwardButtonElement> MediaControlSeekForwardButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlSeekForwardButtonElement> button = adoptRef(new MediaControlSeekForwardButtonElement(mediaElement));
+ button->setType("button");
+ return button.release();
+}
+
+const AtomicString& MediaControlSeekForwardButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-seek-forward-button"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlSeekBackButtonElement::MediaControlSeekBackButtonElement(HTMLMediaElement* mediaElement)
+ : MediaControlSeekButtonElement(mediaElement, MediaSeekBackButton)
+{
+}
+
+PassRefPtr<MediaControlSeekBackButtonElement> MediaControlSeekBackButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlSeekBackButtonElement> button = adoptRef(new MediaControlSeekBackButtonElement(mediaElement));
+ button->setType("button");
+ return button.release();
+}
+
+const AtomicString& MediaControlSeekBackButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-seek-back-button"));
+ return id;
+}
+
+// ----------------------------
+
inline MediaControlRewindButtonElement::MediaControlRewindButtonElement(HTMLMediaElement* element)
- : MediaControlInputElement(element, MEDIA_CONTROLS_REWIND_BUTTON)
+ : MediaControlInputElement(element, MediaRewindButton)
{
}
@@ -648,10 +686,16 @@ void MediaControlRewindButtonElement::defaultEventHandler(Event* event)
HTMLInputElement::defaultEventHandler(event);
}
+const AtomicString& MediaControlRewindButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-rewind-button"));
+ return id;
+}
+
// ----------------------------
inline MediaControlReturnToRealtimeButtonElement::MediaControlReturnToRealtimeButtonElement(HTMLMediaElement* mediaElement)
- : MediaControlInputElement(mediaElement, MEDIA_CONTROLS_RETURN_TO_REALTIME_BUTTON)
+ : MediaControlInputElement(mediaElement, MediaReturnToRealtimeButton)
{
}
@@ -671,11 +715,16 @@ void MediaControlReturnToRealtimeButtonElement::defaultEventHandler(Event* event
HTMLInputElement::defaultEventHandler(event);
}
+const AtomicString& MediaControlReturnToRealtimeButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-return-to-realtime-button"));
+ return id;
+}
// ----------------------------
inline MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement(HTMLMediaElement* mediaElement)
- : MediaControlInputElement(mediaElement, MEDIA_CONTROLS_TOGGLE_CLOSED_CAPTIONS_BUTTON)
+ : MediaControlInputElement(mediaElement, MediaShowClosedCaptionsButton)
{
}
@@ -701,10 +750,16 @@ void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType()
setDisplayType(mediaElement()->closedCaptionsVisible() ? MediaHideClosedCaptionsButton : MediaShowClosedCaptionsButton);
}
+const AtomicString& MediaControlToggleClosedCaptionsButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-toggle-closed-captions-button"));
+ return id;
+}
+
// ----------------------------
MediaControlTimelineElement::MediaControlTimelineElement(HTMLMediaElement* mediaElement)
- : MediaControlInputElement(mediaElement, MEDIA_CONTROLS_TIMELINE)
+ : MediaControlInputElement(mediaElement, MediaSlider)
{
}
@@ -739,12 +794,17 @@ void MediaControlTimelineElement::defaultEventHandler(Event* event)
}
RenderSlider* slider = toRenderSlider(renderer());
+<<<<<<< HEAD
if (slider && slider->inDragMode()) {
toRenderMedia(mediaElement()->renderer())->updateTimeDisplay();
#if PLATFORM(ANDROID)
toRenderMedia(mediaElement()->renderer())->updateLastTouch();
#endif
}
+=======
+ if (slider && slider->inDragMode())
+ toRenderMedia(mediaElement()->renderer())->controls()->updateTimeDisplay();
+>>>>>>> webkit.org at r78450
if (event->type() == eventNames().mouseupEvent)
mediaElement()->endScrubbing();
@@ -760,10 +820,16 @@ void MediaControlTimelineElement::update(bool updateDuration)
MediaControlInputElement::update();
}
+const AtomicString& MediaControlTimelineElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-timeline"));
+ return id;
+}
+
// ----------------------------
inline MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(HTMLMediaElement* mediaElement)
- : MediaControlInputElement(mediaElement, MEDIA_CONTROLS_VOLUME_SLIDER)
+ : MediaControlInputElement(mediaElement, MediaVolumeSlider)
{
}
@@ -804,10 +870,16 @@ void MediaControlVolumeSliderElement::update()
MediaControlInputElement::update();
}
+const AtomicString& MediaControlVolumeSliderElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-volume-slider"));
+ return id;
+}
+
// ----------------------------
inline MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement(HTMLMediaElement* mediaElement)
- : MediaControlInputElement(mediaElement, MEDIA_CONTROLS_FULLSCREEN_BUTTON)
+ : MediaControlInputElement(mediaElement, MediaFullscreenButton)
{
}
@@ -840,20 +912,21 @@ void MediaControlFullscreenButtonElement::defaultEventHandler(Event* event)
HTMLInputElement::defaultEventHandler(event);
}
+const AtomicString& MediaControlFullscreenButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-fullscreen-button"));
+ return id;
+}
+
// ----------------------------
-inline MediaControlTimeDisplayElement::MediaControlTimeDisplayElement(HTMLMediaElement* mediaElement, PseudoId pseudo)
- : MediaControlElement(mediaElement, pseudo)
+inline MediaControlTimeDisplayElement::MediaControlTimeDisplayElement(HTMLMediaElement* mediaElement)
+ : MediaControlElement(mediaElement)
, m_currentValue(0)
, m_isVisible(true)
{
}
-PassRefPtr<MediaControlTimeDisplayElement> MediaControlTimeDisplayElement::create(HTMLMediaElement* mediaElement, PseudoId pseudoStyleId)
-{
- return adoptRef(new MediaControlTimeDisplayElement(mediaElement, pseudoStyleId));
-}
-
PassRefPtr<RenderStyle> MediaControlTimeDisplayElement::styleForElement()
{
RefPtr<RenderStyle> style = MediaControlElement::styleForElement();
@@ -884,6 +957,52 @@ void MediaControlTimeDisplayElement::setCurrentValue(float time)
m_currentValue = time;
}
+// ----------------------------
+
+PassRefPtr<MediaControlTimeRemainingDisplayElement> MediaControlTimeRemainingDisplayElement::create(HTMLMediaElement* mediaElement)
+{
+ return adoptRef(new MediaControlTimeRemainingDisplayElement(mediaElement));
+}
+
+MediaControlTimeRemainingDisplayElement::MediaControlTimeRemainingDisplayElement(HTMLMediaElement* mediaElement)
+ : MediaControlTimeDisplayElement(mediaElement)
+{
+}
+
+MediaControlElementType MediaControlTimeRemainingDisplayElement::displayType() const
+{
+ return MediaTimeRemainingDisplay;
+}
+
+const AtomicString& MediaControlTimeRemainingDisplayElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-time-remaining-display"));
+ return id;
+}
+
+// ----------------------------
+
+PassRefPtr<MediaControlCurrentTimeDisplayElement> MediaControlCurrentTimeDisplayElement::create(HTMLMediaElement* mediaElement)
+{
+ return adoptRef(new MediaControlCurrentTimeDisplayElement(mediaElement));
+}
+
+MediaControlCurrentTimeDisplayElement::MediaControlCurrentTimeDisplayElement(HTMLMediaElement* mediaElement)
+ : MediaControlTimeDisplayElement(mediaElement)
+{
+}
+
+MediaControlElementType MediaControlCurrentTimeDisplayElement::displayType() const
+{
+ return MediaCurrentTimeDisplay;
+}
+
+const AtomicString& MediaControlCurrentTimeDisplayElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-current-time-display"));
+ return id;
+}
+
} // namespace WebCore
#endif // ENABLE(VIDEO)
diff --git a/Source/WebCore/rendering/MediaControlElements.h b/Source/WebCore/rendering/MediaControlElements.h
index b2d063d..ff9541d 100644
--- a/Source/WebCore/rendering/MediaControlElements.h
+++ b/Source/WebCore/rendering/MediaControlElements.h
@@ -75,7 +75,6 @@ class MediaControlShadowRootElement : public HTMLDivElement {
public:
static PassRefPtr<MediaControlShadowRootElement> create(HTMLMediaElement*);
- void updateStyle();
virtual void detach();
private:
@@ -86,19 +85,17 @@ private:
class MediaControlElement : public HTMLDivElement {
public:
- static PassRefPtr<MediaControlElement> create(HTMLMediaElement*, PseudoId);
-
virtual void attach();
void attachToParent(Element*);
void update();
void updateStyle();
- MediaControlElementType displayType() const { return m_displayType; }
+ virtual MediaControlElementType displayType() const = 0;
HTMLMediaElement* mediaElement() const { return m_mediaElement; }
protected:
- MediaControlElement(HTMLMediaElement*, PseudoId);
+ MediaControlElement(HTMLMediaElement*);
virtual bool rendererIsNeeded(RenderStyle*);
@@ -108,19 +105,32 @@ private:
virtual bool isMediaControlElement() const { return true; }
HTMLMediaElement* m_mediaElement;
- PseudoId m_pseudoStyleId;
- MediaControlElementType m_displayType; // some elements can show multiple types (e.g. play/pause)
};
// ----------------------------
+class MediaControlPanelElement : public MediaControlElement {
+public:
+ static PassRefPtr<MediaControlPanelElement> create(HTMLMediaElement*);
+
+private:
+ MediaControlPanelElement(HTMLMediaElement*);
+ virtual MediaControlElementType displayType() const;
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+
+// ----------------------------
+
class MediaControlTimelineContainerElement : public MediaControlElement {
public:
static PassRefPtr<MediaControlTimelineContainerElement> create(HTMLMediaElement*);
private:
MediaControlTimelineContainerElement(HTMLMediaElement*);
+ virtual MediaControlElementType displayType() const;
virtual bool rendererIsNeeded(RenderStyle*);
+ virtual const AtomicString& shadowPseudoId() const;
};
// ----------------------------
@@ -137,6 +147,8 @@ public:
private:
MediaControlVolumeSliderContainerElement(HTMLMediaElement*);
+ virtual MediaControlElementType displayType() const;
+ virtual const AtomicString& shadowPseudoId() const;
bool m_isVisible;
int m_x, m_y;
@@ -153,7 +165,9 @@ public:
private:
MediaControlStatusDisplayElement(HTMLMediaElement*);
+ virtual MediaControlElementType displayType() const;
virtual bool rendererIsNeeded(RenderStyle*);
+ virtual const AtomicString& shadowPseudoId() const;
enum StateBeingDisplayed { Nothing, Loading, LiveBroadcast };
StateBeingDisplayed m_stateBeingDisplayed;
@@ -174,12 +188,10 @@ public:
HTMLMediaElement* mediaElement() const { return m_mediaElement; }
protected:
- MediaControlInputElement(HTMLMediaElement*, PseudoId);
+ MediaControlInputElement(HTMLMediaElement*, MediaControlElementType);
void setDisplayType(MediaControlElementType);
- PseudoId pseudoStyleId() const { return m_pseudoStyleId; }
-
private:
virtual void attach();
virtual bool rendererIsNeeded(RenderStyle*);
@@ -190,8 +202,7 @@ private:
virtual void updateDisplayType() { }
- HTMLMediaElement* m_mediaElement;
- PseudoId m_pseudoStyleId;
+ HTMLMediaElement* m_mediaElement;
MediaControlElementType m_displayType;
};
@@ -199,17 +210,31 @@ private:
class MediaControlMuteButtonElement : public MediaControlInputElement {
public:
- enum ButtonLocation { Controller, VolumeSlider };
- static PassRefPtr<MediaControlMuteButtonElement> create(HTMLMediaElement*, ButtonLocation);
+ static PassRefPtr<MediaControlMuteButtonElement> create(HTMLMediaElement*);
virtual void defaultEventHandler(Event*);
-private:
- MediaControlMuteButtonElement(HTMLMediaElement*, ButtonLocation);
+protected:
+ MediaControlMuteButtonElement(HTMLMediaElement*, MediaControlElementType);
+private:
virtual void updateDisplayType();
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+// ----------------------------
+
+class MediaControlVolumeSliderMuteButtonElement : public MediaControlMuteButtonElement {
+public:
+ static PassRefPtr<MediaControlVolumeSliderMuteButtonElement> create(HTMLMediaElement*);
+
+private:
+ MediaControlVolumeSliderMuteButtonElement(HTMLMediaElement*);
+
+ virtual const AtomicString& shadowPseudoId() const;
};
+
// ----------------------------
class MediaControlPlayButtonElement : public MediaControlInputElement {
@@ -222,20 +247,20 @@ private:
MediaControlPlayButtonElement(HTMLMediaElement*);
virtual void updateDisplayType();
+ virtual const AtomicString& shadowPseudoId() const;
};
// ----------------------------
class MediaControlSeekButtonElement : public MediaControlInputElement {
public:
- static PassRefPtr<MediaControlSeekButtonElement> create(HTMLMediaElement*, PseudoId);
-
virtual void defaultEventHandler(Event*);
-private:
- MediaControlSeekButtonElement(HTMLMediaElement*, PseudoId);
+protected:
+ MediaControlSeekButtonElement(HTMLMediaElement*, MediaControlElementType);
- bool isForwardButton() const;
+private:
+ virtual bool isForwardButton() const = 0;
virtual void detach();
void seekTimerFired(Timer<MediaControlSeekButtonElement>*);
@@ -244,7 +269,33 @@ private:
bool m_capturing;
Timer<MediaControlSeekButtonElement> m_seekTimer;
};
-
+
+// ----------------------------
+
+class MediaControlSeekForwardButtonElement : public MediaControlSeekButtonElement {
+public:
+ static PassRefPtr<MediaControlSeekForwardButtonElement> create(HTMLMediaElement*);
+
+private:
+ MediaControlSeekForwardButtonElement(HTMLMediaElement*);
+
+ virtual bool isForwardButton() const { return true; }
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+// ----------------------------
+
+class MediaControlSeekBackButtonElement : public MediaControlSeekButtonElement {
+public:
+ static PassRefPtr<MediaControlSeekBackButtonElement> create(HTMLMediaElement*);
+
+private:
+ MediaControlSeekBackButtonElement(HTMLMediaElement*);
+
+ virtual bool isForwardButton() const { return false; }
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
// ----------------------------
class MediaControlRewindButtonElement : public MediaControlInputElement {
@@ -255,6 +306,8 @@ public:
private:
MediaControlRewindButtonElement(HTMLMediaElement*);
+
+ virtual const AtomicString& shadowPseudoId() const;
};
// ----------------------------
@@ -267,6 +320,8 @@ public:
private:
MediaControlReturnToRealtimeButtonElement(HTMLMediaElement*);
+
+ virtual const AtomicString& shadowPseudoId() const;
};
// ----------------------------
@@ -281,6 +336,7 @@ private:
MediaControlToggleClosedCaptionsButtonElement(HTMLMediaElement*);
virtual void updateDisplayType();
+ virtual const AtomicString& shadowPseudoId() const;
};
// ----------------------------
@@ -294,6 +350,8 @@ public:
private:
MediaControlTimelineElement(HTMLMediaElement*);
+
+ virtual const AtomicString& shadowPseudoId() const;
};
// ----------------------------
@@ -307,6 +365,8 @@ public:
private:
MediaControlVolumeSliderElement(HTMLMediaElement*);
+
+ virtual const AtomicString& shadowPseudoId() const;
};
// ----------------------------
@@ -319,22 +379,23 @@ public:
private:
MediaControlFullscreenButtonElement(HTMLMediaElement*);
+
+ virtual const AtomicString& shadowPseudoId() const;
};
// ----------------------------
class MediaControlTimeDisplayElement : public MediaControlElement {
public:
- static PassRefPtr<MediaControlTimeDisplayElement> create(HTMLMediaElement*, PseudoId);
-
void setVisible(bool);
void setCurrentValue(float);
float currentValue() const { return m_currentValue; }
-private:
- MediaControlTimeDisplayElement(HTMLMediaElement*, PseudoId);
+protected:
+ MediaControlTimeDisplayElement(HTMLMediaElement*);
+private:
virtual PassRefPtr<RenderStyle> styleForElement();
float m_currentValue;
bool m_isVisible;
@@ -342,6 +403,32 @@ private:
// ----------------------------
+class MediaControlTimeRemainingDisplayElement : public MediaControlTimeDisplayElement {
+public:
+ static PassRefPtr<MediaControlTimeRemainingDisplayElement> create(HTMLMediaElement*);
+
+private:
+ MediaControlTimeRemainingDisplayElement(HTMLMediaElement*);
+
+ virtual MediaControlElementType displayType() const;
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+// ----------------------------
+
+class MediaControlCurrentTimeDisplayElement : public MediaControlTimeDisplayElement {
+public:
+ static PassRefPtr<MediaControlCurrentTimeDisplayElement> create(HTMLMediaElement*);
+
+private:
+ MediaControlCurrentTimeDisplayElement(HTMLMediaElement*);
+
+ virtual MediaControlElementType displayType() const;
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+// ----------------------------
+
class RenderMediaControlShadowRoot : public RenderBlock {
public:
RenderMediaControlShadowRoot(Element* e) : RenderBlock(e) { }
diff --git a/Source/WebCore/rendering/RenderBR.h b/Source/WebCore/rendering/RenderBR.h
index 7216b5a..72a4514 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*/) const { return 0; }
- virtual unsigned width(unsigned /*from*/, unsigned /*len*/, int /*xpos*/, bool /*firstLine = false*/) const { return 0; }
+ 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; }
int lineHeight(bool firstLine) const;
diff --git a/Source/WebCore/rendering/RenderBlock.cpp b/Source/WebCore/rendering/RenderBlock.cpp
index 7275461..87aa630 100644
--- a/Source/WebCore/rendering/RenderBlock.cpp
+++ b/Source/WebCore/rendering/RenderBlock.cpp
@@ -36,6 +36,7 @@
#include "HitTestResult.h"
#include "InlineTextBox.h"
#include "PaintInfo.h"
+#include "RenderCombineText.h"
#include "RenderFlexibleBox.h"
#include "RenderImage.h"
#include "RenderInline.h"
@@ -1267,7 +1268,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren, int pageLogicalHeight)
statePusher.pop();
if (view()->layoutState()->m_pageLogicalHeight)
- setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(y()));
+ setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(logicalTop()));
updateLayerTransform();
@@ -1330,10 +1331,18 @@ void RenderBlock::addOverflowFromChildren()
ColumnInfo* colInfo = columnInfo();
if (columnCount(colInfo)) {
IntRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
- int overflowLeft = !style()->isLeftToRightDirection() ? min(0, lastRect.x()) : 0;
- int overflowRight = style()->isLeftToRightDirection() ? max(width(), lastRect.x() + lastRect.width()) : 0;
- int overflowHeight = borderTop() + paddingTop() + colInfo->columnHeight();
- addLayoutOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight));
+ if (style()->isHorizontalWritingMode()) {
+ int overflowLeft = !style()->isLeftToRightDirection() ? min(0, lastRect.x()) : 0;
+ int overflowRight = style()->isLeftToRightDirection() ? max(width(), lastRect.maxX()) : 0;
+ int overflowHeight = borderBefore() + paddingBefore() + colInfo->columnHeight();
+ addLayoutOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight));
+ } else {
+ IntRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
+ int overflowTop = !style()->isLeftToRightDirection() ? min(0, lastRect.y()) : 0;
+ int overflowBottom = style()->isLeftToRightDirection() ? max(height(), lastRect.maxY()) : 0;
+ int overflowWidth = borderBefore() + paddingBefore() + colInfo->columnHeight();
+ addLayoutOverflow(IntRect(0, overflowTop, overflowWidth, overflowBottom - overflowTop));
+ }
}
}
}
@@ -1376,14 +1385,13 @@ void RenderBlock::addOverflowFromBlockChildren()
void RenderBlock::addOverflowFromFloats()
{
- IntRect result;
if (!m_floatingObjects)
return;
FloatingObject* r;
DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
for (; (r = it.current()); ++it) {
if (r->m_isDescendant)
- addOverflowFromChild(r->m_renderer, IntSize(r->left() + r->m_renderer->marginLeft(), r->top() + r->m_renderer->marginTop()));
+ addOverflowFromChild(r->m_renderer, IntSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r)));
}
return;
}
@@ -1649,7 +1657,7 @@ int RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo)
bool paginated = view()->layoutState()->isPaginated();
if (paginated && logicalTop > beforeCollapseLogicalTop) {
int oldLogicalTop = logicalTop;
- logicalTop = min(logicalTop, nextPageTop(beforeCollapseLogicalTop));
+ logicalTop = min(logicalTop, nextPageLogicalTop(beforeCollapseLogicalTop));
setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop));
}
return logicalTop;
@@ -1719,7 +1727,7 @@ int RenderBlock::estimateLogicalTopPosition(RenderBox* child, const MarginInfo&
// Adjust logicalTopEstimate down to the next page if the margins are so large that we don't fit on the current
// page.
if (paginated && logicalTopEstimate > logicalHeight())
- logicalTopEstimate = min(logicalTopEstimate, nextPageTop(logicalHeight()));
+ logicalTopEstimate = min(logicalTopEstimate, nextPageLogicalTop(logicalHeight()));
logicalTopEstimate += getClearDelta(child, logicalTopEstimate);
@@ -2062,7 +2070,7 @@ void RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, int
if (paginated) {
// Check for an after page/column break.
- int newHeight = applyAfterBreak(child, height(), marginInfo);
+ int newHeight = applyAfterBreak(child, logicalHeight(), marginInfo);
if (newHeight != height())
setLogicalHeight(newHeight);
}
@@ -2166,7 +2174,7 @@ void RenderBlock::markForPaginationRelayoutIfNeeded()
if (needsLayout())
return;
- if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(y()) != pageLogicalOffset()))
+ if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(logicalTop()) != pageLogicalOffset()))
setChildNeedsLayout(true, false);
}
@@ -2243,32 +2251,34 @@ void RenderBlock::paintColumnRules(PaintInfo& paintInfo, int tx, int ty)
// We need to do multiple passes, breaking up our child painting into strips.
ColumnInfo* colInfo = columnInfo();
unsigned colCount = columnCount(colInfo);
- int currXOffset = style()->isLeftToRightDirection() ? 0 : contentWidth();
- int ruleAdd = borderLeft() + paddingLeft();
- int ruleX = style()->isLeftToRightDirection() ? 0 : contentWidth();
+ int currLogicalLeftOffset = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth();
+ int ruleAdd = logicalLeftOffsetForContent();
+ int ruleLogicalLeft = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth();
for (unsigned i = 0; i < colCount; i++) {
IntRect colRect = columnRectAt(colInfo, i);
+ int inlineDirectionSize = style()->isHorizontalWritingMode() ? colRect.width() : colRect.height();
+
// Move to the next position.
if (style()->isLeftToRightDirection()) {
- ruleX += colRect.width() + colGap / 2;
- currXOffset += colRect.width() + colGap;
+ ruleLogicalLeft += inlineDirectionSize + colGap / 2;
+ currLogicalLeftOffset += inlineDirectionSize + colGap;
} else {
- ruleX -= (colRect.width() + colGap / 2);
- currXOffset -= (colRect.width() + colGap);
+ ruleLogicalLeft -= (inlineDirectionSize + colGap / 2);
+ currLogicalLeftOffset -= (inlineDirectionSize + colGap);
}
// Now paint the column rule.
if (i < colCount - 1) {
- int ruleStart = tx + ruleX - ruleWidth / 2 + ruleAdd;
- int ruleEnd = ruleStart + ruleWidth;
- int ruleTop = ty + borderTop() + paddingTop();
- int ruleBottom = ruleTop + contentHeight();
- drawLineForBoxSide(paintInfo.context, ruleStart, ruleTop, ruleEnd, ruleBottom,
+ int ruleLeft = style()->isHorizontalWritingMode() ? tx + ruleLogicalLeft - ruleWidth / 2 + ruleAdd : tx + borderBefore() + paddingBefore();
+ int ruleRight = style()->isHorizontalWritingMode() ? ruleLeft + ruleWidth : ruleLeft + contentWidth();
+ int ruleTop = style()->isHorizontalWritingMode() ? ty + borderTop() + paddingTop() : ty + ruleLogicalLeft - ruleWidth / 2 + ruleAdd;
+ int ruleBottom = style()->isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleWidth;
+ drawLineForBoxSide(paintInfo.context, ruleLeft, ruleTop, ruleRight, ruleBottom,
style()->isLeftToRightDirection() ? BSLeft : BSRight, ruleColor, ruleStyle, 0, 0);
}
- ruleX = currXOffset;
+ ruleLogicalLeft = currLogicalLeftOffset;
}
}
@@ -2276,16 +2286,17 @@ void RenderBlock::paintColumnContents(PaintInfo& paintInfo, int tx, int ty, bool
{
// We need to do multiple passes, breaking up our child painting into strips.
GraphicsContext* context = paintInfo.context;
- int colGap = columnGap();
ColumnInfo* colInfo = columnInfo();
unsigned colCount = columnCount(colInfo);
if (!colCount)
return;
- int currXOffset = style()->isLeftToRightDirection() ? 0 : contentWidth() - columnRectAt(colInfo, 0).width();
- int currYOffset = 0;
+ int currLogicalTopOffset = 0;
for (unsigned i = 0; i < colCount; i++) {
// For each rect, we clip to the rect, and then we adjust our coords.
IntRect colRect = columnRectAt(colInfo, i);
+ flipForWritingMode(colRect);
+ int logicalLeftOffset = (style()->isHorizontalWritingMode() ? colRect.x() : colRect.y()) - logicalLeftOffsetForContent();
+ IntSize offset = style()->isHorizontalWritingMode() ? IntSize(logicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, logicalLeftOffset);
colRect.move(tx, ty);
PaintInfo info(paintInfo);
info.rect.intersect(colRect);
@@ -2296,10 +2307,10 @@ void RenderBlock::paintColumnContents(PaintInfo& paintInfo, int tx, int ty, bool
// Each strip pushes a clip, since column boxes are specified as being
// like overflow:hidden.
context->clip(colRect);
-
+
// Adjust our x and y when painting.
- int finalX = tx + currXOffset;
- int finalY = ty + currYOffset;
+ int finalX = tx + offset.width();
+ int finalY = ty + offset.height();
if (paintingFloats)
paintFloats(info, finalX, finalY, paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip);
else
@@ -2307,14 +2318,12 @@ void RenderBlock::paintColumnContents(PaintInfo& paintInfo, int tx, int ty, bool
context->restore();
}
-
- // Move to the next position.
- if (style()->isLeftToRightDirection())
- currXOffset += colRect.width() + colGap;
+
+ int blockDelta = (style()->isHorizontalWritingMode() ? colRect.height() : colRect.width());
+ if (style()->isFlippedBlocksWritingMode())
+ currLogicalTopOffset += blockDelta;
else
- currXOffset -= (colRect.width() + colGap);
-
- currYOffset -= colRect.height();
+ currLogicalTopOffset -= blockDelta;
}
}
@@ -2352,14 +2361,14 @@ void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
bool checkBeforeAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakBefore() == PBALWAYS);
if (checkBeforeAlways
&& (ty + child->y()) > paintInfo.rect.y()
- && (ty + child->y()) < paintInfo.rect.bottom()) {
+ && (ty + child->y()) < paintInfo.rect.maxY()) {
view()->setBestTruncatedAt(ty + child->y(), this, true);
return;
}
if (!child->isFloating() && child->isReplaced() && usePrintRect && child->height() <= renderView->printRect().height()) {
// Paginate block-level replaced elements.
- if (ty + child->y() + child->height() > renderView->printRect().bottom()) {
+ if (ty + child->y() + child->height() > renderView->printRect().maxY()) {
if (ty + child->y() < renderView->truncatedAt())
renderView->setBestTruncatedAt(ty + child->y(), child);
// If we were able to truncate, don't paint.
@@ -2376,7 +2385,7 @@ void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
bool checkAfterAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakAfter() == PBALWAYS);
if (checkAfterAlways
&& (ty + child->y() + child->height()) > paintInfo.rect.y()
- && (ty + child->y() + child->height()) < paintInfo.rect.bottom()) {
+ && (ty + child->y() + child->height()) < paintInfo.rect.maxY()) {
view()->setBestTruncatedAt(ty + child->y() + child->height() + max(0, child->collapsedMarginAfter()), this, true);
return;
}
@@ -2491,6 +2500,19 @@ void RenderBlock::paintObject(PaintInfo& paintInfo, int tx, int ty)
}
}
+IntPoint RenderBlock::flipFloatForWritingMode(const FloatingObject* child, const IntPoint& point) const
+{
+ if (!style()->isFlippedBlocksWritingMode())
+ return point;
+
+ // This is similar to the ParentToChildFlippingAdjustment in RenderBox::flipForWritingMode. We have to subtract out our left/top offsets twice, since
+ // it's going to get added back in. We hide this complication here so that the calling code looks normal for the unflipped
+ // case.
+ if (style()->isHorizontalWritingMode())
+ return IntPoint(point.x(), point.y() + height() - child->renderer()->height() - 2 * yPositionForFloatIncludingMargin(child));
+ return IntPoint(point.x() + width() - child->width() - 2 * xPositionForFloatIncludingMargin(child), point.y());
+}
+
void RenderBlock::paintFloats(PaintInfo& paintInfo, int tx, int ty, bool preservePhase)
{
if (!m_floatingObjects)
@@ -2503,7 +2525,7 @@ void RenderBlock::paintFloats(PaintInfo& paintInfo, int tx, int ty, bool preserv
if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
PaintInfo currentPaintInfo(paintInfo);
currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
- IntPoint childPoint = flipForWritingMode(r->m_renderer, IntPoint(tx + r->left() + r->m_renderer->marginLeft() - r->m_renderer->x(), ty + r->top() + r->m_renderer->marginTop() - r->m_renderer->y()), ParentToChildFlippingAdjustment);
+ IntPoint childPoint = flipFloatForWritingMode(r, IntPoint(tx + xPositionForFloatIncludingMargin(r) - r->m_renderer->x(), ty + yPositionForFloatIncludingMargin(r) - r->m_renderer->y()));
r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
if (!preservePhase) {
currentPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
@@ -2529,7 +2551,7 @@ void RenderBlock::paintEllipsisBoxes(PaintInfo& paintInfo, int tx, int ty)
// intersect.
int yPos = ty + firstLineBox()->y();
int h = lastLineBox()->y() + lastLineBox()->logicalHeight() - firstLineBox()->y();
- if (yPos >= paintInfo.rect.bottom() || yPos + h <= paintInfo.rect.y())
+ if (yPos >= paintInfo.rect.maxY() || yPos + h <= paintInfo.rect.y())
return;
// See if our boxes intersect with the dirty rect. If so, then we paint
@@ -2538,7 +2560,7 @@ void RenderBlock::paintEllipsisBoxes(PaintInfo& paintInfo, int tx, int ty)
for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
yPos = ty + curr->y();
h = curr->logicalHeight();
- if (curr->ellipsisBox() && yPos < paintInfo.rect.bottom() && yPos + h > paintInfo.rect.y())
+ if (curr->ellipsisBox() && yPos < paintInfo.rect.maxY() && yPos + h > paintInfo.rect.y())
curr->paintEllipsisBox(paintInfo, tx, ty);
}
}
@@ -2737,8 +2759,8 @@ GapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const IntPoint& root
if (m_floatingObjects) {
for (DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects); it.current(); ++it) {
FloatingObject* r = it.current();
- IntRect floatBox = IntRect(offsetFromRootBlock.width() + r->left() + r->m_renderer->marginLeft(),
- offsetFromRootBlock.height() + r->top() + r->m_renderer->marginTop(),
+ IntRect floatBox = IntRect(offsetFromRootBlock.width() + xPositionForFloatIncludingMargin(r),
+ offsetFromRootBlock.height() + yPositionForFloatIncludingMargin(r),
r->m_renderer->width(), r->m_renderer->height());
rootBlock->flipForWritingMode(floatBox);
floatBox.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
@@ -2808,8 +2830,8 @@ GapRects RenderBlock::inlineSelectionGaps(RenderBlock* rootBlock, const IntPoint
IntRect logicalRect(curr->logicalLeft(), selTop, curr->logicalWidth(), selTop + selHeight);
logicalRect.move(style()->isHorizontalWritingMode() ? offsetFromRootBlock : IntSize(offsetFromRootBlock.height(), offsetFromRootBlock.width()));
IntRect physicalRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect);
- if (!paintInfo || (style()->isHorizontalWritingMode() && physicalRect.y() < paintInfo->rect.bottom() && physicalRect.bottom() > paintInfo->rect.y())
- || (!style()->isHorizontalWritingMode() && physicalRect.x() < paintInfo->rect.right() && physicalRect.right() > paintInfo->rect.x()))
+ if (!paintInfo || (style()->isHorizontalWritingMode() && physicalRect.y() < paintInfo->rect.maxY() && physicalRect.maxY() > paintInfo->rect.y())
+ || (!style()->isHorizontalWritingMode() && physicalRect.x() < paintInfo->rect.maxX() && physicalRect.maxX() > paintInfo->rect.x()))
result.unite(curr->lineSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, selTop, selHeight, paintInfo));
lastSelectedLine = curr;
@@ -3098,7 +3120,7 @@ void RenderBlock::removeFloatingObject(RenderBox* o)
// 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 + 1);
+ logicalBottom = max(logicalBottom, logicalTop == numeric_limits<int>::max() ? logicalTop : logicalTop + 1);
markLinesDirtyInBlockRange(0, logicalBottom);
}
m_floatingObjects->removeRef(it.current());
@@ -3108,13 +3130,13 @@ void RenderBlock::removeFloatingObject(RenderBox* o)
}
}
-void RenderBlock::removeFloatingObjectsBelow(FloatingObject* lastFloat, int y)
+void RenderBlock::removeFloatingObjectsBelow(FloatingObject* lastFloat, int logicalOffset)
{
if (!m_floatingObjects)
return;
FloatingObject* curr = m_floatingObjects->last();
- while (curr != lastFloat && (!curr->isPlaced() || curr->top() >= y)) {
+ while (curr != lastFloat && (!curr->isPlaced() || logicalTopForFloat(curr) >= logicalOffset)) {
m_floatingObjects->removeLast();
curr = m_floatingObjects->last();
}
@@ -3460,7 +3482,7 @@ void RenderBlock::markLinesDirtyInBlockRange(int logicalTop, int logicalBottom,
RootInlineBox* lowestDirtyLine = lastRootBox();
RootInlineBox* afterLowest = lowestDirtyLine;
- while (lowestDirtyLine && lowestDirtyLine->blockLogicalHeight() >= logicalBottom) {
+ while (lowestDirtyLine && lowestDirtyLine->blockLogicalHeight() >= logicalBottom && logicalBottom < numeric_limits<int>::max()) {
afterLowest = lowestDirtyLine;
lowestDirtyLine = lowestDirtyLine->prevRootBox();
}
@@ -3591,7 +3613,7 @@ int RenderBlock::addOverhangingFloats(RenderBlock* child, int logicalLeftOffset,
if (!containsFloat(r->m_renderer)) {
int leftOffset = style()->isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset;
int topOffset = style()->isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset;
- FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->left() - leftOffset, r->top() - topOffset, r->width(), r->height()));
+ FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->x() - leftOffset, r->y() - topOffset, r->width(), r->height()));
floatingObj->m_renderer = r->m_renderer;
// The nearest enclosing layer always paints the float (so that zindex and stacking
@@ -3626,7 +3648,7 @@ int RenderBlock::addOverhangingFloats(RenderBlock* child, int logicalLeftOffset,
// Since the float doesn't overhang, it didn't get put into our list. We need to go ahead and add its overflow in to the
// child now.
if (r->m_isDescendant)
- child->addOverflowFromChild(r->m_renderer, IntSize(r->left() + r->m_renderer->marginLeft(), r->top() + r->m_renderer->marginTop()));
+ child->addOverflowFromChild(r->m_renderer, IntSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r)));
}
}
return lowestFloatLogicalBottom;
@@ -3658,7 +3680,7 @@ void RenderBlock::addIntrudingFloats(RenderBlock* prev, int logicalLeftOffset, i
int leftOffset = style()->isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset;
int topOffset = style()->isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset;
- FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->left() - leftOffset, r->top() - topOffset, r->width(), r->height()));
+ FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->x() - leftOffset, r->y() - topOffset, r->width(), r->height()));
// Applying the child's margin makes no sense in the case where the child was passed in.
// since this margin was added already through the modification of the |logicalLeftOffset| variable
@@ -3667,9 +3689,9 @@ void RenderBlock::addIntrudingFloats(RenderBlock* prev, int logicalLeftOffset, i
// will get applied twice.
if (prev != parent()) {
if (style()->isHorizontalWritingMode())
- floatingObj->setLeft(floatingObj->left() + prev->marginLeft());
+ floatingObj->setX(floatingObj->x() + prev->marginLeft());
else
- floatingObj->setTop(floatingObj->top() + prev->marginTop());
+ floatingObj->setY(floatingObj->y() + prev->marginTop());
}
floatingObj->m_shouldPaint = false; // We are not in the direct inheritance chain for this float. We will never paint it.
@@ -3864,9 +3886,9 @@ bool RenderBlock::hitTestFloats(const HitTestRequest& request, HitTestResult& re
DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
for (it.toLast(); (floatingObject = it.current()); --it) {
if (floatingObject->m_shouldPaint && !floatingObject->m_renderer->hasSelfPaintingLayer()) {
- int xOffset = floatingObject->left() + floatingObject->m_renderer->marginLeft() - floatingObject->m_renderer->x();
- int yOffset = floatingObject->top() + floatingObject->m_renderer->marginTop() - floatingObject->m_renderer->y();
- IntPoint childPoint = flipForWritingMode(floatingObject->m_renderer, IntPoint(tx + xOffset, ty + yOffset), ParentToChildFlippingAdjustment);
+ int xOffset = xPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->x();
+ int yOffset = yPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->y();
+ IntPoint childPoint = flipFloatForWritingMode(floatingObject, IntPoint(tx + xOffset, ty + yOffset));
if (floatingObject->m_renderer->hitTest(request, result, IntPoint(x, y), childPoint.x(), childPoint.y())) {
updateHitTestResult(result, IntPoint(x - childPoint.x(), y - childPoint.y()));
return true;
@@ -3884,23 +3906,36 @@ bool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& r
int colCount = columnCount(colInfo);
if (!colCount)
return false;
- int left = borderLeft() + paddingLeft();
- int currYOffset = 0;
+ int logicalLeft = logicalLeftOffsetForContent();
+ int currLogicalTopOffset = 0;
int i;
- for (i = 0; i < colCount; i++)
- currYOffset -= columnRectAt(colInfo, i).height();
+ bool isHorizontal = style()->isHorizontalWritingMode();
+ for (i = 0; i < colCount; i++) {
+ IntRect colRect = columnRectAt(colInfo, i);
+ int blockDelta = (isHorizontal ? colRect.height() : colRect.width());
+ if (style()->isFlippedBlocksWritingMode())
+ currLogicalTopOffset += blockDelta;
+ else
+ currLogicalTopOffset -= blockDelta;
+ }
for (i = colCount - 1; i >= 0; i--) {
IntRect colRect = columnRectAt(colInfo, i);
- int currXOffset = colRect.x() - left;
- currYOffset += colRect.height();
+ flipForWritingMode(colRect);
+ int currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft;
+ int blockDelta = (isHorizontal ? colRect.height() : colRect.width());
+ if (style()->isFlippedBlocksWritingMode())
+ currLogicalTopOffset -= blockDelta;
+ else
+ currLogicalTopOffset += blockDelta;
colRect.move(tx, ty);
if (colRect.intersects(result.rectForPoint(x, y))) {
// The point is inside this column.
// Adjust tx and ty to change where we hit test.
- int finalX = tx + currXOffset;
- int finalY = ty + currYOffset;
+ IntSize offset = isHorizontal ? IntSize(currLogicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, currLogicalLeftOffset);
+ int finalX = tx + offset.width();
+ int finalY = ty + offset.height();
if (result.isRectBasedTest() && !colRect.contains(result.rectForPoint(x, y)))
hitTestContents(request, result, x, y, finalX, finalY, hitTestAction);
else
@@ -3947,25 +3982,6 @@ Position RenderBlock::positionForBox(InlineBox *box, bool start) const
return Position(box->renderer()->node(), start ? textBox->start() : textBox->start() + textBox->len());
}
-Position RenderBlock::positionForRenderer(RenderObject* renderer, bool start) const
-{
- if (!renderer)
- return Position(node(), 0);
-
- Node* n = renderer->node() ? renderer->node() : node();
- if (!n)
- return Position();
-
- ASSERT(renderer == n->renderer());
-
- int offset = start ? renderer->caretMinOffset() : renderer->caretMaxOffset();
-
- // FIXME: This was a runtime check that seemingly couldn't fail; changed it to an assertion for now.
- ASSERT(!n->isCharacterDataNode() || renderer->isText());
-
- return Position(n, offset);
-}
-
// FIXME: This function should go on RenderObject as an instance method. Then
// all cases in which positionForPoint recurs could call this instead to
// prevent crossing editable boundaries. This would require many tests.
@@ -4139,7 +4155,7 @@ void RenderBlock::calcColumnWidth()
{
// Calculate our column width and column count.
unsigned desiredColumnCount = 1;
- int desiredColumnWidth = contentWidth();
+ int desiredColumnWidth = contentLogicalWidth();
// For now, we don't support multi-column layouts when printing, since we have to do a lot of work for proper pagination.
if (document()->paginated() || (style()->hasAutoColumnCount() && style()->hasAutoColumnWidth())) {
@@ -4214,7 +4230,7 @@ void RenderBlock::setDesiredColumnCountAndWidth(int count, int width)
int RenderBlock::desiredColumnWidth() const
{
if (!hasColumns())
- return contentWidth();
+ return contentLogicalWidth();
return gColumnInfoMap->get(this)->desiredColumnWidth();
}
@@ -4243,14 +4259,17 @@ IntRect RenderBlock::columnRectAt(ColumnInfo* colInfo, unsigned index) const
ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo);
// Compute the appropriate rect based off our information.
- int colWidth = colInfo->desiredColumnWidth();
- int colHeight = colInfo->columnHeight();
- int colTop = borderTop() + paddingTop();
+ int colLogicalWidth = colInfo->desiredColumnWidth();
+ int colLogicalHeight = colInfo->columnHeight();
+ int colLogicalTop = borderBefore() + paddingBefore();
int colGap = columnGap();
- int colLeft = style()->isLeftToRightDirection() ?
- borderLeft() + paddingLeft() + (index * (colWidth + colGap))
- : borderLeft() + paddingLeft() + contentWidth() - colWidth - (index * (colWidth + colGap));
- return IntRect(colLeft, colTop, colWidth, colHeight);
+ int colLogicalLeft = style()->isLeftToRightDirection() ?
+ logicalLeftOffsetForContent() + (index * (colLogicalWidth + colGap))
+ : logicalLeftOffsetForContent() + contentLogicalWidth() - colLogicalWidth - (index * (colLogicalWidth + colGap));
+ IntRect rect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
+ if (style()->isHorizontalWritingMode())
+ return IntRect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
+ return IntRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogicalWidth);
}
bool RenderBlock::layoutColumns(bool hasSpecifiedPageLogicalHeight, int pageLogicalHeight, LayoutStateMaintainer& statePusher)
@@ -4270,12 +4289,12 @@ bool RenderBlock::layoutColumns(bool hasSpecifiedPageLogicalHeight, int pageLogi
// maximum page break distance.
if (!pageLogicalHeight) {
int distanceBetweenBreaks = max(colInfo->maximumDistanceBetweenForcedBreaks(),
- view()->layoutState()->pageLogicalOffset(borderTop() + paddingTop() + contentHeight()) - colInfo->forcedBreakOffset());
+ view()->layoutState()->pageLogicalOffset(borderBefore() + paddingBefore() + contentLogicalHeight()) - colInfo->forcedBreakOffset());
columnHeight = max(colInfo->minimumColumnHeight(), distanceBetweenBreaks);
}
- } else if (contentHeight() > pageLogicalHeight * desiredColumnCount) {
+ } else if (contentLogicalHeight() > pageLogicalHeight * desiredColumnCount) {
// Now that we know the intrinsic height of the columns, we have to rebalance them.
- columnHeight = max(colInfo->minimumColumnHeight(), (int)ceilf((float)contentHeight() / desiredColumnCount));
+ columnHeight = max(colInfo->minimumColumnHeight(), (int)ceilf((float)contentLogicalHeight() / desiredColumnCount));
}
if (columnHeight && columnHeight != pageLogicalHeight) {
@@ -4287,10 +4306,10 @@ bool RenderBlock::layoutColumns(bool hasSpecifiedPageLogicalHeight, int pageLogi
}
if (pageLogicalHeight)
- colInfo->setColumnCountAndHeight(ceilf((float)contentHeight() / pageLogicalHeight), pageLogicalHeight);
+ colInfo->setColumnCountAndHeight(ceilf((float)contentLogicalHeight() / pageLogicalHeight), pageLogicalHeight);
if (columnCount(colInfo)) {
- setLogicalHeight(borderTop() + paddingTop() + colInfo->columnHeight() + borderBottom() + paddingBottom() + horizontalScrollbarHeight());
+ setLogicalHeight(borderBefore() + paddingBefore() + colInfo->columnHeight() + borderAfter() + paddingAfter() + scrollbarLogicalHeight());
m_overflow.clear();
}
@@ -4309,34 +4328,57 @@ void RenderBlock::adjustPointToColumnContents(IntPoint& point) const
// Determine which columns we intersect.
int colGap = columnGap();
- int leftGap = colGap / 2;
+ int halfColGap = colGap / 2;
IntPoint columnPoint(columnRectAt(colInfo, 0).location());
- int yOffset = 0;
+ int logicalOffset = 0;
for (unsigned i = 0; i < colInfo->columnCount(); i++) {
// Add in half the column gap to the left and right of the rect.
IntRect colRect = columnRectAt(colInfo, i);
- IntRect gapAndColumnRect(colRect.x() - leftGap, colRect.y(), colRect.width() + colGap, colRect.height());
-
- if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRect.right()) {
- // FIXME: The clamping that follows is not completely right for right-to-left
- // content.
- // Clamp everything above the column to its top left.
- if (point.y() < gapAndColumnRect.y())
- point = gapAndColumnRect.location();
- // Clamp everything below the column to the next column's top left. If there is
- // no next column, this still maps to just after this column.
- else if (point.y() >= gapAndColumnRect.bottom()) {
- point = gapAndColumnRect.location();
- point.move(0, gapAndColumnRect.height());
+ if (style()->isHorizontalWritingMode()) {
+ IntRect gapAndColumnRect(colRect.x() - halfColGap, colRect.y(), colRect.width() + colGap, colRect.height());
+ if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRect.maxX()) {
+ // FIXME: The clamping that follows is not completely right for right-to-left
+ // content.
+ // Clamp everything above the column to its top left.
+ if (point.y() < gapAndColumnRect.y())
+ point = gapAndColumnRect.location();
+ // Clamp everything below the column to the next column's top left. If there is
+ // no next column, this still maps to just after this column.
+ else if (point.y() >= gapAndColumnRect.maxY()) {
+ point = gapAndColumnRect.location();
+ point.move(0, gapAndColumnRect.height());
+ }
+
+ // We're inside the column. Translate the x and y into our column coordinate space.
+ point.move(columnPoint.x() - colRect.x(), logicalOffset);
+ return;
}
+
+ // Move to the next position.
+ logicalOffset += colRect.height();
+ } else {
+ IntRect gapAndColumnRect(colRect.x(), colRect.y() - halfColGap, colRect.width(), colRect.height() + colGap);
+ if (point.y() >= gapAndColumnRect.y() && point.y() < gapAndColumnRect.maxY()) {
+ // FIXME: The clamping that follows is not completely right for right-to-left
+ // content.
+ // Clamp everything above the column to its top left.
+ if (point.x() < gapAndColumnRect.x())
+ point = gapAndColumnRect.location();
+ // Clamp everything below the column to the next column's top left. If there is
+ // no next column, this still maps to just after this column.
+ else if (point.x() >= gapAndColumnRect.maxX()) {
+ point = gapAndColumnRect.location();
+ point.move(gapAndColumnRect.width(), 0);
+ }
- // We're inside the column. Translate the x and y into our column coordinate space.
- point.move(columnPoint.x() - colRect.x(), yOffset);
- return;
+ // We're inside the column. Translate the x and y into our column coordinate space.
+ point.move(logicalOffset, columnPoint.y() - colRect.y());
+ return;
+ }
+
+ // Move to the next position.
+ logicalOffset += colRect.width();
}
-
- // Move to the next position.
- yOffset += colRect.height();
}
}
@@ -4356,27 +4398,56 @@ void RenderBlock::adjustRectForColumns(IntRect& r) const
if (!colCount)
return;
- int left = borderLeft() + paddingLeft();
-
- int currYOffset = 0;
+ int logicalLeft = logicalLeftOffsetForContent();
+ int currLogicalOffset = 0;
+
for (unsigned i = 0; i < colCount; i++) {
IntRect colRect = columnRectAt(colInfo, i);
- int currXOffset = colRect.x() - left;
-
IntRect repaintRect = r;
- repaintRect.move(currXOffset, currYOffset);
-
+ if (style()->isHorizontalWritingMode()) {
+ int currXOffset = colRect.x() - logicalLeft;
+ repaintRect.move(currXOffset, currLogicalOffset);
+ currLogicalOffset -= colRect.height();
+ } else {
+ int currYOffset = colRect.y() - logicalLeft;
+ repaintRect.move(currLogicalOffset, currYOffset);
+ currLogicalOffset -= colRect.width();
+ }
repaintRect.intersect(colRect);
-
result.unite(repaintRect);
-
- // Move to the next position.
- currYOffset -= colRect.height();
}
r = result;
}
+IntPoint RenderBlock::flipForWritingModeIncludingColumns(const IntPoint& point) const
+{
+ ASSERT(hasColumns());
+ if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
+ return point;
+ ColumnInfo* colInfo = columnInfo();
+ int columnLogicalHeight = colInfo->columnHeight();
+ int expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
+ if (style()->isHorizontalWritingMode())
+ return IntPoint(point.x(), expandedLogicalHeight - point.y());
+ return IntPoint(expandedLogicalHeight - point.x(), point.y());
+}
+
+void RenderBlock::flipForWritingModeIncludingColumns(IntRect& rect) const
+{
+ ASSERT(hasColumns());
+ if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
+ return;
+
+ ColumnInfo* colInfo = columnInfo();
+ int columnLogicalHeight = colInfo->columnHeight();
+ int expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
+ if (style()->isHorizontalWritingMode())
+ rect.setY(expandedLogicalHeight - rect.maxY());
+ else
+ rect.setX(expandedLogicalHeight - rect.maxX());
+}
+
void RenderBlock::adjustForColumns(IntSize& offset, const IntPoint& point) const
{
if (!hasColumns())
@@ -4384,18 +4455,34 @@ void RenderBlock::adjustForColumns(IntSize& offset, const IntPoint& point) const
ColumnInfo* colInfo = columnInfo();
- int left = borderLeft() + paddingLeft();
- int yOffset = 0;
+ int logicalLeft = logicalLeftOffsetForContent();
size_t colCount = columnCount(colInfo);
+ int colLogicalWidth = colInfo->desiredColumnWidth();
+ int colLogicalHeight = colInfo->columnHeight();
+
for (size_t i = 0; i < colCount; ++i) {
- IntRect columnRect = columnRectAt(colInfo, i);
- int xOffset = columnRect.x() - left;
- if (point.y() < columnRect.bottom() + yOffset) {
- offset.expand(xOffset, -yOffset);
- return;
- }
+ // Compute the edges for a given column in the block progression direction.
+ IntRect sliceRect = IntRect(logicalLeft, borderBefore() + paddingBefore() + i * colLogicalHeight, colLogicalWidth, colLogicalHeight);
+ if (!style()->isHorizontalWritingMode())
+ sliceRect = sliceRect.transposedRect();
+
+ // If we have a flipped blocks writing mode, then convert the column so that it's coming from the after edge (either top or left edge).
+ flipForWritingModeIncludingColumns(sliceRect);
+
+ int logicalOffset = style()->isFlippedBlocksWritingMode() ? (colCount - 1 - i) * colLogicalHeight : i * colLogicalHeight;
- yOffset += columnRect.height();
+ // Now we're in the same coordinate space as the point. See if it is inside the rectangle.
+ if (style()->isHorizontalWritingMode()) {
+ if (point.y() >= sliceRect.y() && point.y() < sliceRect.maxY()) {
+ offset.expand(columnRectAt(colInfo, i).x() - logicalLeft, -logicalOffset);
+ return;
+ }
+ } else {
+ if (point.x() >= sliceRect.x() && point.x() < sliceRect.maxX()) {
+ offset.expand(-logicalOffset, columnRectAt(colInfo, i).y() - logicalLeft);
+ return;
+ }
+ }
}
}
@@ -4535,16 +4622,13 @@ static int getBPMWidth(int childValue, Length cssUnit)
static int getBorderPaddingMargin(const RenderBoxModelObject* child, bool endOfInline)
{
RenderStyle* cstyle = child->style();
- int result = 0;
- bool leftSide = (cstyle->isLeftToRightDirection()) ? !endOfInline : endOfInline;
- result += getBPMWidth((leftSide ? child->marginLeft() : child->marginRight()),
- (leftSide ? cstyle->marginLeft() :
- cstyle->marginRight()));
- result += getBPMWidth((leftSide ? child->paddingLeft() : child->paddingRight()),
- (leftSide ? cstyle->paddingLeft() :
- cstyle->paddingRight()));
- result += leftSide ? child->borderLeft() : child->borderRight();
- return result;
+ if (endOfInline)
+ return getBPMWidth(child->marginEnd(), cstyle->marginEnd()) +
+ getBPMWidth(child->paddingEnd(), cstyle->paddingEnd()) +
+ child->borderEnd();
+ return getBPMWidth(child->marginStart(), cstyle->marginStart()) +
+ getBPMWidth(child->paddingStart(), cstyle->paddingStart()) +
+ child->borderStart();
}
static inline void stripTrailingSpace(int& inlineMax, int& inlineMin,
@@ -4567,7 +4651,7 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
int inlineMax = 0;
int inlineMin = 0;
- int cw = containingBlock()->contentWidth();
+ int cw = containingBlock()->contentLogicalWidth();
// If we are at the start of a line, we want to ignore all white-space.
// Also strip spaces if we previously had text that ended in a trailing space.
@@ -4577,7 +4661,7 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
// Firefox and Opera will allow a table cell to grow to fit an image inside it under
// very specific cirucumstances (in order to match common WinIE renderings).
// Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
- bool allowImagesToBreak = !document()->inQuirksMode() || !isTableCell() || !style()->width().isIntrinsicOrAuto();
+ bool allowImagesToBreak = !document()->inQuirksMode() || !isTableCell() || !style()->logicalWidth().isIntrinsicOrAuto();
bool autoWrap, oldAutoWrap;
autoWrap = oldAutoWrap = style()->autoWrap();
@@ -4645,12 +4729,12 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
} else {
// Inline replaced elts add in their margins to their min/max values.
int margins = 0;
- Length leftMargin = cstyle->marginLeft();
- Length rightMargin = cstyle->marginRight();
- if (leftMargin.isFixed())
- margins += leftMargin.value();
- if (rightMargin.isFixed())
- margins += rightMargin.value();
+ Length startMargin = cstyle->marginStart();
+ Length endMargin = cstyle->marginEnd();
+ if (startMargin.isFixed())
+ margins += startMargin.value();
+ if (endMargin.isFixed())
+ margins += endMargin.value();
childMin += margins;
childMax += margins;
}
@@ -4689,8 +4773,8 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
if (!addedTextIndent) {
addedTextIndent = true;
ti = style()->textIndent().calcMinValue(cw);
- childMin+=ti;
- childMax+=ti;
+ childMin += ti;
+ childMax += ti;
}
// Add our width to the max.
@@ -4725,6 +4809,9 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
continue;
}
+ if (t->style()->hasTextCombine())
+ toRenderCombineText(t)->combineText();
+
// Determine if we have a breakable character. Pass in
// whether or not we should ignore any spaces at the front
// of the string. If those are going to be stripped out,
@@ -4852,14 +4939,16 @@ void RenderBlock::computeBlockPreferredLogicalWidths()
// A margin basically has three types: fixed, percentage, and auto (variable).
// Auto and percentage margins simply become 0 when computing min/max width.
// Fixed margins can be added in as is.
- Length ml = child->style()->marginLeft();
- Length mr = child->style()->marginRight();
- int margin = 0, marginLeft = 0, marginRight = 0;
- if (ml.isFixed())
- marginLeft += ml.value();
- if (mr.isFixed())
- marginRight += mr.value();
- margin = marginLeft + marginRight;
+ Length startMarginLength = child->style()->marginStart();
+ Length endMarginLength = child->style()->marginEnd();
+ int margin = 0;
+ int marginStart = 0;
+ int marginEnd = 0;
+ if (startMarginLength.isFixed())
+ marginStart += startMarginLength.value();
+ if (endMarginLength.isFixed())
+ marginEnd += endMarginLength.value();
+ margin = marginStart + marginEnd;
int w = child->minPreferredLogicalWidth() + margin;
m_minPreferredLogicalWidth = max(w, m_minPreferredLogicalWidth);
@@ -4875,8 +4964,11 @@ void RenderBlock::computeBlockPreferredLogicalWidths()
// Determine a left and right max value based off whether or not the floats can fit in the
// margins of the object. For negative margins, we will attempt to overlap the float if the negative margin
// is smaller than the float width.
- int maxLeft = marginLeft > 0 ? max(floatLeftWidth, marginLeft) : floatLeftWidth + marginLeft;
- int maxRight = marginRight > 0 ? max(floatRightWidth, marginRight) : floatRightWidth + marginRight;
+ bool ltr = containingBlock()->style()->isLeftToRightDirection();
+ int marginLogicalLeft = ltr ? marginStart : marginEnd;
+ int marginLogicalRight = ltr ? marginEnd : marginStart;
+ int maxLeft = marginLogicalLeft > 0 ? max(floatLeftWidth, marginLogicalLeft) : floatLeftWidth + marginLogicalLeft;
+ int maxRight = marginLogicalRight > 0 ? max(floatRightWidth, marginLogicalRight) : floatRightWidth + marginLogicalRight;
w = child->maxPreferredLogicalWidth() + maxLeft + maxRight;
w = max(w, floatLeftWidth + floatRightWidth);
}
@@ -4906,7 +4998,7 @@ void RenderBlock::computeBlockPreferredLogicalWidths()
// of 100px because of the table.
// We can achieve this effect by making the maxwidth of blocks that contain tables
// with percentage widths be infinite (as long as they are not inside a table cell).
- if (document()->inQuirksMode() && child->style()->width().isPercent() &&
+ if (document()->inQuirksMode() && child->style()->logicalWidth().isPercent() &&
!isTableCell() && child->isTable() && m_maxPreferredLogicalWidth < BLOCK_MAX_WIDTH) {
RenderBlock* cb = containingBlock();
while (!cb->isRenderView() && !cb->isTableCell())
@@ -4992,8 +5084,8 @@ int RenderBlock::baselinePosition(FontBaseline baselineType, bool firstLine, Lin
return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
}
- const Font& f = style(firstLine)->font();
- return f.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - f.height()) / 2;
+ const FontMetrics& fontMetrics = style(firstLine)->fontMetrics();
+ return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2;
}
int RenderBlock::firstLineBoxBaseline() const
@@ -5003,7 +5095,7 @@ int RenderBlock::firstLineBoxBaseline() const
if (childrenInline()) {
if (firstLineBox())
- return firstLineBox()->logicalTop() + style(true)->font().ascent(firstRootBox()->baselineType());
+ return firstLineBox()->logicalTop() + style(true)->fontMetrics().ascent(firstRootBox()->baselineType());
else
return -1;
}
@@ -5029,11 +5121,13 @@ int RenderBlock::lastLineBoxBaseline() const
if (childrenInline()) {
if (!firstLineBox() && hasLineIfEmpty()) {
- const Font& f = firstLineStyle()->font();
- return f.ascent() + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - f.height()) / 2 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
+ const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
+ return fontMetrics.ascent()
+ + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
+ + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
}
if (lastLineBox())
- return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->font().ascent(lastRootBox()->baselineType());
+ return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->fontMetrics().ascent(lastRootBox()->baselineType());
return -1;
} else {
bool haveNormalFlowChild = false;
@@ -5046,8 +5140,10 @@ int RenderBlock::lastLineBoxBaseline() const
}
}
if (!haveNormalFlowChild && hasLineIfEmpty()) {
- const Font& f = firstLineStyle()->font();
- return f.ascent() + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - f.height()) / 2 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
+ const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
+ return fontMetrics.ascent()
+ + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
+ + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
}
}
@@ -5400,7 +5496,7 @@ void RenderBlock::adjustForBorderFit(int x, int& left, int& right) const
for (; (r = it.current()); ++it) {
// Only examine the object if our m_shouldPaint flag is set.
if (r->m_shouldPaint) {
- int floatLeft = r->left() - r->m_renderer->x() + r->m_renderer->marginLeft();
+ int floatLeft = xPositionForFloatIncludingMargin(r) - r->m_renderer->x();
int floatRight = floatLeft + r->m_renderer->width();
left = min(left, floatLeft);
right = max(right, floatRight);
@@ -5755,16 +5851,18 @@ RenderBlock* RenderBlock::createAnonymousColumnSpanBlock() const
return newBox;
}
-int RenderBlock::nextPageTop(int yPos) const
+int RenderBlock::nextPageLogicalTop(int logicalOffset) const
{
LayoutState* layoutState = view()->layoutState();
if (!layoutState->m_pageLogicalHeight)
- return yPos;
+ return logicalOffset;
- // The yPos is in our coordinate space. We can add in our pushed offset.
+ // The logicalOffset is in our coordinate space. We can add in our pushed offset.
int pageLogicalHeight = layoutState->m_pageLogicalHeight;
- int remainingHeight = (pageLogicalHeight - ((layoutState->m_layoutOffset - layoutState->m_pageOffset).height() + yPos) % pageLogicalHeight) % pageLogicalHeight;
- return yPos + remainingHeight;
+ IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
+ int offset = style()->isHorizontalWritingMode() ? delta.height() : delta.width();
+ int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight;
+ return logicalOffset + remainingLogicalHeight;
}
static bool inNormalFlow(RenderBox* child)
@@ -5781,7 +5879,7 @@ static bool inNormalFlow(RenderBox* child)
return true;
}
-int RenderBlock::applyBeforeBreak(RenderBox* child, int yPos)
+int RenderBlock::applyBeforeBreak(RenderBox* child, int logicalOffset)
{
// FIXME: Add page break checking here when we support printing.
bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
@@ -5789,13 +5887,13 @@ int RenderBlock::applyBeforeBreak(RenderBox* child, int yPos)
bool checkBeforeAlways = (checkColumnBreaks && child->style()->columnBreakBefore() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakBefore() == PBALWAYS);
if (checkBeforeAlways && inNormalFlow(child)) {
if (checkColumnBreaks)
- view()->layoutState()->addForcedColumnBreak(yPos);
- return nextPageTop(yPos);
+ view()->layoutState()->addForcedColumnBreak(logicalOffset);
+ return nextPageLogicalTop(logicalOffset);
}
- return yPos;
+ return logicalOffset;
}
-int RenderBlock::applyAfterBreak(RenderBox* child, int yPos, MarginInfo& marginInfo)
+int RenderBlock::applyAfterBreak(RenderBox* child, int logicalOffset, MarginInfo& marginInfo)
{
// FIXME: Add page break checking here when we support printing.
bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
@@ -5804,28 +5902,30 @@ int RenderBlock::applyAfterBreak(RenderBox* child, int yPos, MarginInfo& marginI
if (checkAfterAlways && inNormalFlow(child)) {
marginInfo.setMarginAfterQuirk(true); // Cause margins to be discarded for any following content.
if (checkColumnBreaks)
- view()->layoutState()->addForcedColumnBreak(yPos);
- return nextPageTop(yPos);
+ view()->layoutState()->addForcedColumnBreak(logicalOffset);
+ return nextPageLogicalTop(logicalOffset);
}
- return yPos;
+ return logicalOffset;
}
-int RenderBlock::adjustForUnsplittableChild(RenderBox* child, int yPos, bool includeMargins)
+int RenderBlock::adjustForUnsplittableChild(RenderBox* child, int logicalOffset, bool includeMargins)
{
bool isUnsplittable = child->isReplaced() || child->scrollsOverflow();
if (!isUnsplittable)
- return yPos;
- int childHeight = child->height() + (includeMargins ? child->marginTop() + child->marginBottom() : 0);
+ return logicalOffset;
+ int childLogicalHeight = logicalHeightForChild(child) + (includeMargins ? marginBeforeForChild(child) + marginAfterForChild(child) : 0);
LayoutState* layoutState = view()->layoutState();
if (layoutState->m_columnInfo)
- layoutState->m_columnInfo->updateMinimumColumnHeight(childHeight);
+ layoutState->m_columnInfo->updateMinimumColumnHeight(childLogicalHeight);
int pageLogicalHeight = layoutState->m_pageLogicalHeight;
- if (!pageLogicalHeight || childHeight > pageLogicalHeight)
- return yPos;
- int remainingHeight = (pageLogicalHeight - ((layoutState->m_layoutOffset - layoutState->m_pageOffset).height() + yPos) % pageLogicalHeight) % pageLogicalHeight;
- if (remainingHeight < childHeight)
- return yPos + remainingHeight;
- return yPos;
+ if (!pageLogicalHeight || childLogicalHeight > pageLogicalHeight)
+ return logicalOffset;
+ IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
+ int offset = style()->isHorizontalWritingMode() ? delta.height() : delta.width();
+ int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight;
+ if (remainingLogicalHeight < childLogicalHeight)
+ return logicalOffset + remainingLogicalHeight;
+ return logicalOffset;
}
void RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, int& delta)
@@ -5848,22 +5948,24 @@ void RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, int& d
// line and all following lines.
LayoutState* layoutState = view()->layoutState();
int pageLogicalHeight = layoutState->m_pageLogicalHeight;
- int yPos = lineBox->topVisualOverflow();
- int lineHeight = lineBox->bottomVisualOverflow() - yPos;
+ int logicalOffset = lineBox->logicalTopVisualOverflow();
+ int lineHeight = lineBox->logicalBottomVisualOverflow() - logicalOffset;
if (layoutState->m_columnInfo)
layoutState->m_columnInfo->updateMinimumColumnHeight(lineHeight);
- yPos += delta;
+ logicalOffset += delta;
lineBox->setPaginationStrut(0);
if (!pageLogicalHeight || lineHeight > pageLogicalHeight)
return;
- int remainingHeight = pageLogicalHeight - ((layoutState->m_layoutOffset - layoutState->m_pageOffset).height() + yPos) % pageLogicalHeight;
- if (remainingHeight < lineHeight) {
- int totalHeight = lineHeight + max(0, yPos);
- if (lineBox == firstRootBox() && totalHeight < pageLogicalHeight && !isPositioned() && !isTableCell())
- setPaginationStrut(remainingHeight + max(0, yPos));
+ IntSize offsetDelta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
+ int offset = style()->isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width();
+ int remainingLogicalHeight = pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight;
+ if (remainingLogicalHeight < lineHeight) {
+ int totalLogicalHeight = lineHeight + max(0, logicalOffset);
+ if (lineBox == firstRootBox() && totalLogicalHeight < pageLogicalHeight && !isPositioned() && !isTableCell())
+ setPaginationStrut(remainingLogicalHeight + max(0, logicalOffset));
else {
- delta += remainingHeight;
- lineBox->setPaginationStrut(remainingHeight);
+ delta += remainingLogicalHeight;
+ lineBox->setPaginationStrut(remainingLogicalHeight);
}
}
}
diff --git a/Source/WebCore/rendering/RenderBlock.h b/Source/WebCore/rendering/RenderBlock.h
index f8829ee..2c61331 100644
--- a/Source/WebCore/rendering/RenderBlock.h
+++ b/Source/WebCore/rendering/RenderBlock.h
@@ -106,6 +106,9 @@ public:
// Block flows subclass availableWidth to handle multi column layout (shrinking the width available to children when laying out.)
virtual int availableLogicalWidth() const;
+ IntPoint flipForWritingModeIncludingColumns(const IntPoint&) const;
+ void flipForWritingModeIncludingColumns(IntRect&) const;
+
RootInlineBox* firstRootBox() const { return static_cast<RootInlineBox*>(firstLineBox()); }
RootInlineBox* lastRootBox() const { return static_cast<RootInlineBox*>(lastLineBox()); }
@@ -212,6 +215,9 @@ public:
virtual void scrollbarsChanged(bool /*horizontalScrollbarChanged*/, bool /*verticalScrollbarChanged*/) { };
+ int logicalRightOffsetForContent() const { return style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() + availableLogicalWidth() : borderTop() + paddingTop() + availableLogicalWidth(); }
+ int logicalLeftOffsetForContent() const { return style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop(); }
+
protected:
// These functions are only used internally to manipulate the render tree structure via remove/insert/appendChildNode.
// Since they are typically called only to move objects around within anonymous blocks (which only have layers in
@@ -261,8 +267,6 @@ protected:
virtual void paint(PaintInfo&, int tx, int ty);
virtual void paintObject(PaintInfo&, int tx, int ty);
- int logicalRightOffsetForContent() const { return style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() + availableLogicalWidth() : borderTop() + paddingTop() + availableLogicalWidth(); }
- int logicalLeftOffsetForContent() const { return style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop(); }
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;
@@ -393,15 +397,15 @@ private:
bool isPlaced() const { return m_isPlaced; }
void setIsPlaced(bool placed = true) { m_isPlaced = placed; }
- int left() const { ASSERT(isPlaced()); return m_frameRect.x(); }
- int right() const { ASSERT(isPlaced()); return m_frameRect.right(); }
- int top() const { ASSERT(isPlaced()); return m_frameRect.y(); }
- int bottom() const { ASSERT(isPlaced()); return m_frameRect.bottom(); }
+ int x() const { ASSERT(isPlaced()); return m_frameRect.x(); }
+ int maxX() const { ASSERT(isPlaced()); return m_frameRect.maxX(); }
+ int y() const { ASSERT(isPlaced()); return m_frameRect.y(); }
+ int maxY() const { ASSERT(isPlaced()); return m_frameRect.maxY(); }
int width() const { return m_frameRect.width(); }
int height() const { return m_frameRect.height(); }
-
- void setLeft(int left) { m_frameRect.setX(left); }
- void setTop(int top) { m_frameRect.setY(top); }
+
+ void setX(int x) { m_frameRect.setX(x); }
+ void setY(int y) { m_frameRect.setY(y); }
void setWidth(int width) { m_frameRect.setWidth(width); }
void setHeight(int height) { m_frameRect.setHeight(height); }
@@ -417,24 +421,26 @@ private:
bool m_isPlaced : 1;
};
- int logicalTopForFloat(FloatingObject* child) const { return style()->isHorizontalWritingMode() ? child->top() : child->left(); }
- int logicalBottomForFloat(FloatingObject* child) const { return style()->isHorizontalWritingMode() ? child->bottom() : child->right(); }
- int logicalLeftForFloat(FloatingObject* child) const { return style()->isHorizontalWritingMode() ? child->left() : child->top(); }
- int logicalRightForFloat(FloatingObject* child) const { return style()->isHorizontalWritingMode() ? child->right() : child->bottom(); }
- int logicalWidthForFloat(FloatingObject* child) const { return style()->isHorizontalWritingMode() ? child->width() : child->height(); }
+ IntPoint flipFloatForWritingMode(const FloatingObject*, const IntPoint&) const;
+
+ int logicalTopForFloat(const FloatingObject* child) const { return style()->isHorizontalWritingMode() ? child->y() : child->x(); }
+ int logicalBottomForFloat(const FloatingObject* child) const { return style()->isHorizontalWritingMode() ? child->maxY() : child->maxX(); }
+ int logicalLeftForFloat(const FloatingObject* child) const { return style()->isHorizontalWritingMode() ? child->x() : child->y(); }
+ int logicalRightForFloat(const FloatingObject* child) const { return style()->isHorizontalWritingMode() ? child->maxX() : child->maxY(); }
+ int logicalWidthForFloat(const FloatingObject* child) const { return style()->isHorizontalWritingMode() ? child->width() : child->height(); }
void setLogicalTopForFloat(FloatingObject* child, int logicalTop)
{
if (style()->isHorizontalWritingMode())
- child->setTop(logicalTop);
+ child->setY(logicalTop);
else
- child->setLeft(logicalTop);
+ child->setX(logicalTop);
}
void setLogicalLeftForFloat(FloatingObject* child, int logicalLeft)
{
if (style()->isHorizontalWritingMode())
- child->setLeft(logicalLeft);
+ child->setX(logicalLeft);
else
- child->setTop(logicalLeft);
+ child->setY(logicalLeft);
}
void setLogicalHeightForFloat(FloatingObject* child, int logicalHeight)
{
@@ -451,6 +457,22 @@ private:
child->setHeight(logicalWidth);
}
+ int xPositionForFloatIncludingMargin(const FloatingObject* child) const
+ {
+ if (style()->isHorizontalWritingMode())
+ return child->x() + child->renderer()->marginLeft();
+ else
+ return child->x() + marginBeforeForChild(child->renderer());
+ }
+
+ int yPositionForFloatIncludingMargin(const FloatingObject* child) const
+ {
+ if (style()->isHorizontalWritingMode())
+ return child->y() + marginBeforeForChild(child->renderer());
+ else
+ return child->y() + child->renderer()->marginTop();
+ }
+
// The following functions' implementations are in RenderBlockLineLayout.cpp.
RootInlineBox* determineStartPosition(bool& firstLine, bool& fullLayout, bool& previousLineBrokeCleanly,
InlineBidiResolver&, Vector<FloatWithRect>& floats, unsigned& numCleanFloats,
@@ -488,7 +510,7 @@ private:
FloatingObject* insertFloatingObject(RenderBox*);
void removeFloatingObject(RenderBox*);
- void removeFloatingObjectsBelow(FloatingObject*, int y);
+ void removeFloatingObjectsBelow(FloatingObject*, int logicalOffset);
// Called from lineWidth, to position the floats added in the last line.
// Returns true if and only if it has positioned any floats.
@@ -568,7 +590,6 @@ private:
void newLine(EClear);
Position positionForBox(InlineBox*, bool start = true) const;
- Position positionForRenderer(RenderObject*, bool start = true) const;
VisiblePosition positionForPointWithInlineChildren(const IntPoint&);
// Adjust tx and ty from painting offsets to the local coords of this renderer
@@ -668,11 +689,11 @@ private:
// End helper functions and structs used by layoutBlockChildren.
// Pagination routines.
- int nextPageTop(int yPos) const; // Returns the top of the next page following yPos.
- int applyBeforeBreak(RenderBox* child, int yPos); // If the child has a before break, then return a new yPos that shifts to the top of the next page/column.
- int applyAfterBreak(RenderBox* child, int yPos, MarginInfo& marginInfo); // If the child has an after break, then return a new yPos that shifts to the top of the next page/column.
- int adjustForUnsplittableChild(RenderBox* child, int yPos, 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& deltaY); // Computes a deltaY value that put a line at the top of the next page if it doesn't fit on the current page.
+ int nextPageLogicalTop(int logicalOffset) const; // Returns the top of the next page following logicalOffset.
+ int applyBeforeBreak(RenderBox* child, int logicalOffset); // If the child has a before break, then return a new yPos that shifts to the top of the next page/column.
+ int applyAfterBreak(RenderBox* child, int logicalOffset, MarginInfo& marginInfo); // If the child has an after break, then return a new offset that shifts to the top of the next page/column.
+ 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;
diff --git a/Source/WebCore/rendering/RenderBlockLineLayout.cpp b/Source/WebCore/rendering/RenderBlockLineLayout.cpp
index 5e16931..00c2d86 100644
--- a/Source/WebCore/rendering/RenderBlockLineLayout.cpp
+++ b/Source/WebCore/rendering/RenderBlockLineLayout.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2000 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010 Apple Inc. All right reserved.
+ * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All right reserved.
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -23,12 +23,12 @@
#include "config.h"
#include "BidiResolver.h"
-#include "CharacterNames.h"
#include "Hyphenation.h"
#include "InlineIterator.h"
#include "InlineTextBox.h"
#include "Logging.h"
#include "RenderArena.h"
+#include "RenderCombineText.h"
#include "RenderInline.h"
#include "RenderLayer.h"
#include "RenderListMarker.h"
@@ -42,6 +42,7 @@
#include <wtf/RefCountedLeakCounter.h>
#include <wtf/StdLibExtras.h>
#include <wtf/Vector.h>
+<<<<<<< HEAD
#ifdef ANDROID_LAYOUT
#include "Frame.h"
#include "FrameTree.h"
@@ -49,6 +50,9 @@
#include "Text.h"
#include "HTMLNames.h"
#endif // ANDROID_LAYOUT
+=======
+#include <wtf/unicode/CharacterNames.h>
+>>>>>>> webkit.org at r78450
#if ENABLE(SVG)
#include "RenderSVGInlineText.h"
@@ -190,6 +194,16 @@ static inline void dirtyLineBoxesForRenderer(RenderObject* o, bool fullLayout)
toRenderInline(o)->dirtyLineBoxes(fullLayout);
}
+static bool parentIsConstructedOrHaveNext(InlineFlowBox* parentBox)
+{
+ do {
+ if (parentBox->isConstructed() || parentBox->nextOnLine())
+ return true;
+ parentBox = parentBox->parent();
+ } while (parentBox);
+ return false;
+}
+
InlineFlowBox* RenderBlock::createLineBoxes(RenderObject* obj, bool firstLine)
{
// See if we have an unconstructed line box for this object that is also
@@ -204,13 +218,13 @@ InlineFlowBox* RenderBlock::createLineBoxes(RenderObject* obj, bool firstLine)
// Get the last box we made for this render object.
parentBox = obj->isRenderInline() ? toRenderInline(obj)->lastLineBox() : toRenderBlock(obj)->lastLineBox();
- // If this box is constructed then it is from a previous line, and we need
- // to make a new box for our line. If this box is unconstructed but it has
+ // If this box or its ancestor is constructed then it is from a previous line, and we need
+ // to make a new box for our line. If this box or its ancestor is unconstructed but it has
// something following it on the line, then we know we have to make a new box
// as well. In this situation our inline has actually been split in two on
// the same line (this can happen with very fancy language mixtures).
bool constructedNewBox = false;
- if (!parentBox || parentBox->isConstructed() || parentBox->nextOnLine()) {
+ if (!parentBox || parentIsConstructedOrHaveNext(parentBox)) {
// We need to make a new box for this render object. Once
// made, we need to place it at the end of the current line.
InlineBox* newBox = createInlineBoxForRenderer(obj, obj == this);
@@ -317,7 +331,9 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
int availableLogicalWidth = availableLogicalWidthForLine(logicalHeight(), firstLine);
int totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth();
bool needsWordSpacing = false;
- unsigned numSpaces = 0;
+ unsigned expansionOpportunityCount = 0;
+ bool isAfterExpansion = true;
+ Vector<unsigned, 16> expansionOpportunities;
ETextAlign textAlign = style()->textAlign();
for (BidiRun* r = firstRun; r; r = r->next()) {
@@ -329,12 +345,9 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
RenderText* rt = toRenderText(r->m_object);
if (textAlign == JUSTIFY && r != trailingSpaceRun) {
- const UChar* characters = rt->characters();
- for (int i = r->m_start; i < r->m_stop; i++) {
- UChar c = characters[i];
- if (c == ' ' || c == '\n' || c == '\t')
- numSpaces++;
- }
+ unsigned opportunitiesInRun = Font::expansionOpportunityCount(rt->characters() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), isAfterExpansion);
+ expansionOpportunities.append(opportunitiesInRun);
+ expansionOpportunityCount += opportunitiesInRun;
}
if (int length = rt->textLength()) {
@@ -361,16 +374,24 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(static_cast<InlineTextBox*>(r->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).first;
it->second.second = glyphOverflow;
}
- } else if (!r->m_object->isRenderInline()) {
- RenderBox* renderBox = toRenderBox(r->m_object);
- renderBox->computeLogicalWidth();
- r->m_box->setLogicalWidth(logicalWidthForChild(renderBox));
- totalLogicalWidth += marginStartForChild(renderBox) + marginEndForChild(renderBox);
+ } else {
+ isAfterExpansion = false;
+ if (!r->m_object->isRenderInline()) {
+ RenderBox* renderBox = toRenderBox(r->m_object);
+ renderBox->computeLogicalWidth();
+ r->m_box->setLogicalWidth(logicalWidthForChild(renderBox));
+ totalLogicalWidth += marginStartForChild(renderBox) + marginEndForChild(renderBox);
+ }
}
totalLogicalWidth += r->m_box->logicalWidth();
}
+ if (isAfterExpansion && !expansionOpportunities.isEmpty()) {
+ expansionOpportunities.last()--;
+ expansionOpportunityCount--;
+ }
+
// Armed with the total width of the line (without justification),
// 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
@@ -392,7 +413,7 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
}
break;
case JUSTIFY:
- if (numSpaces && !reachedEnd && !lineBox->endsWithBreak()) {
+ if (expansionOpportunityCount && !reachedEnd && !lineBox->endsWithBreak()) {
if (trailingSpaceRun) {
totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
trailingSpaceRun->m_box->setLogicalWidth(0);
@@ -401,7 +422,7 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
}
// fall through
case TAAUTO:
- numSpaces = 0;
+ expansionOpportunityCount = 0;
// for right to left fall through to right aligned
if (style()->isLeftToRightDirection()) {
if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun)
@@ -443,31 +464,26 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
break;
}
- if (numSpaces) {
+ if (expansionOpportunityCount) {
+ size_t i = 0;
for (BidiRun* r = firstRun; r; r = r->next()) {
if (!r->m_box || r == trailingSpaceRun)
continue;
- int spaceAdd = 0;
if (r->m_object->isText()) {
- unsigned spaces = 0;
- const UChar* characters = toRenderText(r->m_object)->characters();
- for (int i = r->m_start; i < r->m_stop; i++) {
- UChar c = characters[i];
- if (c == ' ' || c == '\n' || c == '\t')
- spaces++;
- }
+ unsigned opportunitiesInRun = expansionOpportunities[i++];
- ASSERT(spaces <= numSpaces);
+ ASSERT(opportunitiesInRun <= expansionOpportunityCount);
// Only justify text if whitespace is collapsed.
if (r->m_object->style()->collapseWhiteSpace()) {
- spaceAdd = (availableLogicalWidth - totalLogicalWidth) * spaces / numSpaces;
- static_cast<InlineTextBox*>(r->m_box)->setSpaceAdd(spaceAdd);
- totalLogicalWidth += spaceAdd;
+ InlineTextBox* textBox = static_cast<InlineTextBox*>(r->m_box);
+ int expansion = (availableLogicalWidth - totalLogicalWidth) * opportunitiesInRun / expansionOpportunityCount;
+ textBox->setExpansion(expansion);
+ totalLogicalWidth += expansion;
}
- numSpaces -= spaces;
- if (!numSpaces)
+ expansionOpportunityCount -= opportunitiesInRun;
+ if (!expansionOpportunityCount)
break;
}
}
@@ -909,7 +925,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
adjustLinePositionForPagination(lineBox, adjustment);
if (adjustment) {
int oldLineWidth = availableLogicalWidthForLine(oldLogicalHeight, firstLine);
- lineBox->adjustPosition(0, adjustment);
+ lineBox->adjustBlockDirectionPosition(adjustment);
if (useRepaintBounds) // This can only be a positive adjustment, so no need to update repaintTop.
repaintLogicalBottom = max(repaintLogicalBottom, afterSideVisualOverflowForLine(lineBox));
@@ -967,7 +983,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
if (delta) {
repaintLogicalTop = min(repaintLogicalTop, beforeSideVisualOverflowForLine(line) + min(delta, 0));
repaintLogicalBottom = max(repaintLogicalBottom, afterSideVisualOverflowForLine(line) + max(delta, 0));
- line->adjustPosition(0, delta);
+ line->adjustBlockDirectionPosition(delta);
}
if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) {
Vector<RenderBox*>::iterator end = cleanLineFloats->end();
@@ -1084,7 +1100,7 @@ RootInlineBox* RenderBlock::determineStartPosition(bool& firstLine, bool& fullLa
repaintLogicalTop = min(repaintLogicalTop, beforeSideVisualOverflowForLine(curr) + min(paginationDelta, 0));
repaintLogicalBottom = max(repaintLogicalBottom, afterSideVisualOverflowForLine(curr) + max(paginationDelta, 0));
- curr->adjustPosition(0, paginationDelta);
+ curr->adjustBlockDirectionPosition(paginationDelta);
}
}
@@ -1500,7 +1516,7 @@ 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)
{
- if (isFixedPitch || (!from && len == text->textLength()))
+ 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));
}
@@ -1752,11 +1768,14 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
bool isSVGText = t->isSVGInlineText();
#endif
+ RenderStyle* style = t->style(firstLine);
+ if (style->hasTextCombine())
+ toRenderCombineText(o)->combineText();
+
int strlen = t->textLength();
int len = strlen - pos;
const UChar* str = t->characters();
- RenderStyle* style = t->style(firstLine);
const Font& f = style->font();
bool isFixedPitch = f.isFixedPitch();
bool canHyphenate = style->hyphens() == HyphensAuto && WebCore::canHyphenate(style->hyphenationLocale());
@@ -2169,38 +2188,34 @@ void RenderBlock::addOverflowFromInlineChildren()
int RenderBlock::beforeSideVisualOverflowForLine(RootInlineBox* line) const
{
- // Overflow is in the block's coordinate space, which means it isn't purely physical. For flipped blocks (rl and bt),
- // we continue to use top and left overflow even though physically it's bottom and right.
+ // Overflow is in the block's coordinate space, which means it isn't purely physical.
if (style()->isHorizontalWritingMode())
- return line->topVisualOverflow();
- return line->leftVisualOverflow();
+ return line->minYVisualOverflow();
+ return line->minXVisualOverflow();
}
int RenderBlock::afterSideVisualOverflowForLine(RootInlineBox* line) const
{
- // Overflow is in the block's coordinate space, which means it isn't purely physical. For flipped blocks (rl and bt),
- // we continue to use bottom and right overflow even though physically it's top and left.
+ // Overflow is in the block's coordinate space, which means it isn't purely physical.
if (style()->isHorizontalWritingMode())
- return line->bottomVisualOverflow();
- return line->rightVisualOverflow();
+ return line->maxYVisualOverflow();
+ return line->maxXVisualOverflow();
}
int RenderBlock::beforeSideLayoutOverflowForLine(RootInlineBox* line) const
{
- // Overflow is in the block's coordinate space, which means it isn't purely physical. For flipped blocks (rl and bt),
- // we continue to use top and left overflow even though physically it's bottom and right.
+ // Overflow is in the block's coordinate space, which means it isn't purely physical.
if (style()->isHorizontalWritingMode())
- return line->topLayoutOverflow();
- return line->leftLayoutOverflow();
+ return line->minYLayoutOverflow();
+ return line->minXLayoutOverflow();
}
int RenderBlock::afterSideLayoutOverflowForLine(RootInlineBox* line) const
{
- // Overflow is in the block's coordinate space, which means it isn't purely physical. For flipped blocks (rl and bt),
- // we continue to use bottom and right overflow even though physically it's top and left.
+ // Overflow is in the block's coordinate space, which means it isn't purely physical.
if (style()->isHorizontalWritingMode())
- return line->bottomLayoutOverflow();
- return line->rightLayoutOverflow();
+ return line->maxYLayoutOverflow();
+ return line->maxXLayoutOverflow();
}
void RenderBlock::deleteEllipsisLineBoxes()
diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp
index 265c46a..39c80d4 100644
--- a/Source/WebCore/rendering/RenderBox.cpp
+++ b/Source/WebCore/rendering/RenderBox.cpp
@@ -425,8 +425,8 @@ int RenderBox::scrollWidth() const
// For objects with visible overflow, this matches IE.
// FIXME: Need to work right with writing modes.
if (style()->isLeftToRightDirection())
- return max(clientWidth(), rightLayoutOverflow() - borderLeft());
- return clientWidth() - min(0, leftLayoutOverflow() - borderLeft());
+ return max(clientWidth(), maxXLayoutOverflow() - borderLeft());
+ return clientWidth() - min(0, minXLayoutOverflow() - borderLeft());
}
int RenderBox::scrollHeight() const
@@ -435,7 +435,7 @@ int RenderBox::scrollHeight() const
return layer()->scrollHeight();
// For objects with visible overflow, this matches IE.
// FIXME: Need to work right with writing modes.
- return max(clientHeight(), bottomLayoutOverflow() - borderTop());
+ return max(clientHeight(), maxYLayoutOverflow() - borderTop());
}
int RenderBox::scrollLeft() const
@@ -559,16 +559,16 @@ IntRect RenderBox::reflectedRect(const IntRect& r) const
IntRect result = r;
switch (style()->boxReflect()->direction()) {
case ReflectionBelow:
- result.setY(box.bottom() + reflectionOffset() + (box.bottom() - r.bottom()));
+ result.setY(box.maxY() + reflectionOffset() + (box.maxY() - r.maxY()));
break;
case ReflectionAbove:
- result.setY(box.y() - reflectionOffset() - box.height() + (box.bottom() - r.bottom()));
+ result.setY(box.y() - reflectionOffset() - box.height() + (box.maxY() - r.maxY()));
break;
case ReflectionLeft:
- result.setX(box.x() - reflectionOffset() - box.width() + (box.right() - r.right()));
+ result.setX(box.x() - reflectionOffset() - box.width() + (box.maxX() - r.maxX()));
break;
case ReflectionRight:
- result.setX(box.right() + reflectionOffset() + (box.right() - r.right()));
+ result.setX(box.maxX() + reflectionOffset() + (box.maxX() - r.maxX()));
break;
}
return result;
@@ -1279,8 +1279,14 @@ IntSize RenderBox::offsetFromContainer(RenderObject* o, const IntPoint& point) c
if (!isInline() || isReplaced()) {
if (style()->position() != AbsolutePosition && style()->position() != FixedPosition) {
- o->adjustForColumns(offset, IntPoint(point.x() + x(), point.y() + y()));
- offset += locationOffsetIncludingFlipping();
+ if (o->hasColumns()) {
+ IntRect columnRect(frameRect());
+ toRenderBlock(o)->flipForWritingModeIncludingColumns(columnRect);
+ offset += IntSize(columnRect.location().x(), columnRect.location().y());
+ columnRect.move(point.x(), point.y());
+ o->adjustForColumns(offset, columnRect.location());
+ } else
+ offset += locationOffsetIncludingFlipping();
} else
offset += locationOffset();
}
@@ -3067,12 +3073,12 @@ IntRect RenderBox::localCaretRect(InlineBox* box, int caretOffset, int* extraWid
// <rdar://problem/3777804> Deleting all content in a document can result in giant tall-as-window insertion point
//
// FIXME: ignoring :first-line, missing good reason to take care of
- int fontHeight = style()->font().height();
+ int fontHeight = style()->fontMetrics().height();
if (fontHeight > rect.height() || (!isReplaced() && !isTable()))
rect.setHeight(fontHeight);
if (extraWidthToEndOfLine)
- *extraWidthToEndOfLine = x() + width() - rect.right();
+ *extraWidthToEndOfLine = x() + width() - rect.maxX();
// Move to local coords
rect.move(-x(), -y());
@@ -3193,9 +3199,9 @@ void RenderBox::addShadowOverflow()
style()->getBoxShadowExtent(shadowTop, shadowRight, shadowBottom, shadowLeft);
IntRect borderBox = borderBoxRect();
int overflowLeft = borderBox.x() + shadowLeft;
- int overflowRight = borderBox.right() + shadowRight;
+ int overflowRight = borderBox.maxX() + shadowRight;
int overflowTop = borderBox.y() + shadowTop;
- int overflowBottom = borderBox.bottom() + shadowBottom;
+ int overflowBottom = borderBox.maxY() + shadowBottom;
addVisualOverflow(IntRect(overflowLeft, overflowTop, overflowRight - overflowLeft, overflowBottom - overflowTop));
}
@@ -3234,13 +3240,13 @@ void RenderBox::addLayoutOverflow(const IntRect& rect)
bool hasLeftOverflow = !style()->isLeftToRightDirection() && style()->isHorizontalWritingMode();
if (!hasTopOverflow)
- overflowRect.shiftTopEdgeTo(max(overflowRect.y(), clientBox.y()));
+ overflowRect.shiftYEdgeTo(max(overflowRect.y(), clientBox.y()));
else
- overflowRect.shiftBottomEdgeTo(min(overflowRect.bottom(), clientBox.bottom()));
+ overflowRect.shiftMaxYEdgeTo(min(overflowRect.maxY(), clientBox.maxY()));
if (!hasLeftOverflow)
- overflowRect.shiftLeftEdgeTo(max(overflowRect.x(), clientBox.x()));
+ overflowRect.shiftXEdgeTo(max(overflowRect.x(), clientBox.x()));
else
- overflowRect.shiftRightEdgeTo(min(overflowRect.right(), clientBox.right()));
+ overflowRect.shiftMaxXEdgeTo(min(overflowRect.maxX(), clientBox.maxX()));
// Now re-test with the adjusted rectangle and see if it has become unreachable or fully
// contained.
@@ -3329,9 +3335,9 @@ IntRect RenderBox::visualOverflowRectForPropagation(RenderStyle* parentStyle) co
// We are putting ourselves into our parent's coordinate space. If there is a flipped block mismatch
// in a particular axis, then we have to flip the rect along that axis.
if (style()->writingMode() == RightToLeftWritingMode || parentStyle->writingMode() == RightToLeftWritingMode)
- rect.setX(width() - rect.right());
+ rect.setX(width() - rect.maxX());
else if (style()->writingMode() == BottomToTopWritingMode || parentStyle->writingMode() == BottomToTopWritingMode)
- rect.setY(height() - rect.bottom());
+ rect.setY(height() - rect.maxY());
return rect;
}
@@ -3375,9 +3381,9 @@ IntRect RenderBox::layoutOverflowRectForPropagation(RenderStyle* parentStyle) co
// We are putting ourselves into our parent's coordinate space. If there is a flipped block mismatch
// in a particular axis, then we have to flip the rect along that axis.
if (style()->writingMode() == RightToLeftWritingMode || parentStyle->writingMode() == RightToLeftWritingMode)
- rect.setX(width() - rect.right());
+ rect.setX(width() - rect.maxX());
else if (style()->writingMode() == BottomToTopWritingMode || parentStyle->writingMode() == BottomToTopWritingMode)
- rect.setY(height() - rect.bottom());
+ rect.setY(height() - rect.maxY());
return rect;
}
@@ -3400,9 +3406,9 @@ void RenderBox::flipForWritingMode(IntRect& rect) const
return;
if (style()->isHorizontalWritingMode())
- rect.setY(height() - rect.bottom());
+ rect.setY(height() - rect.maxY());
else
- rect.setX(width() - rect.right());
+ rect.setX(width() - rect.maxX());
}
int RenderBox::flipForWritingMode(int position) const
@@ -3419,6 +3425,13 @@ IntPoint RenderBox::flipForWritingMode(const IntPoint& position) const
return style()->isHorizontalWritingMode() ? IntPoint(position.x(), height() - position.y()) : IntPoint(width() - position.x(), position.y());
}
+IntPoint RenderBox::flipForWritingModeIncludingColumns(const IntPoint& point) const
+{
+ if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
+ return flipForWritingMode(point);
+ return toRenderBlock(this)->flipForWritingModeIncludingColumns(point);
+}
+
IntSize RenderBox::flipForWritingMode(const IntSize& offset) const
{
if (!style()->isFlippedBlocksWritingMode())
diff --git a/Source/WebCore/rendering/RenderBox.h b/Source/WebCore/rendering/RenderBox.h
index acbcc29..7241ed1 100644
--- a/Source/WebCore/rendering/RenderBox.h
+++ b/Source/WebCore/rendering/RenderBox.h
@@ -127,21 +127,25 @@ public:
RenderBox* nextSiblingBox() const;
RenderBox* parentBox() const;
+ // Visual and layout overflow are in the coordinate space of the box. This means that they aren't purely physical directions.
+ // 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.
IntRect layoutOverflowRect() const { return m_overflow ? m_overflow->layoutOverflowRect() : clientBoxRect(); }
- int topLayoutOverflow() const { return m_overflow? m_overflow->topLayoutOverflow() : borderTop(); }
- int bottomLayoutOverflow() const { return m_overflow ? m_overflow->bottomLayoutOverflow() : borderTop() + clientHeight(); }
- int leftLayoutOverflow() const { return m_overflow ? m_overflow->leftLayoutOverflow() : borderLeft(); }
- int rightLayoutOverflow() const { return m_overflow ? m_overflow->rightLayoutOverflow() : borderLeft() + clientWidth(); }
- int logicalLeftLayoutOverflow() const { return style()->isHorizontalWritingMode() ? leftLayoutOverflow() : topLayoutOverflow(); }
- int logicalRightLayoutOverflow() const { return style()->isHorizontalWritingMode() ? rightLayoutOverflow() : bottomLayoutOverflow(); }
+ int minYLayoutOverflow() const { return m_overflow? m_overflow->minYLayoutOverflow() : borderTop(); }
+ int maxYLayoutOverflow() const { return m_overflow ? m_overflow->maxYLayoutOverflow() : borderTop() + clientHeight(); }
+ int minXLayoutOverflow() const { return m_overflow ? m_overflow->minXLayoutOverflow() : borderLeft(); }
+ int maxXLayoutOverflow() const { return m_overflow ? m_overflow->maxXLayoutOverflow() : borderLeft() + clientWidth(); }
+ int logicalLeftLayoutOverflow() const { return style()->isHorizontalWritingMode() ? minXLayoutOverflow() : minYLayoutOverflow(); }
+ int logicalRightLayoutOverflow() const { return style()->isHorizontalWritingMode() ? maxXLayoutOverflow() : maxYLayoutOverflow(); }
IntRect visualOverflowRect() const { return m_overflow ? m_overflow->visualOverflowRect() : borderBoxRect(); }
- int topVisualOverflow() const { return m_overflow? m_overflow->topVisualOverflow() : 0; }
- int bottomVisualOverflow() const { return m_overflow ? m_overflow->bottomVisualOverflow() : height(); }
- int leftVisualOverflow() const { return m_overflow ? m_overflow->leftVisualOverflow() : 0; }
- int rightVisualOverflow() const { return m_overflow ? m_overflow->rightVisualOverflow() : width(); }
- int logicalLeftVisualOverflow() const { return style()->isHorizontalWritingMode() ? leftVisualOverflow() : topVisualOverflow(); }
- int logicalRightVisualOverflow() const { return style()->isHorizontalWritingMode() ? rightVisualOverflow() : bottomVisualOverflow(); }
+ int minYVisualOverflow() const { return m_overflow? m_overflow->minYVisualOverflow() : 0; }
+ int maxYVisualOverflow() const { return m_overflow ? m_overflow->maxYVisualOverflow() : height(); }
+ int minXVisualOverflow() const { return m_overflow ? m_overflow->minXVisualOverflow() : 0; }
+ int maxXVisualOverflow() const { return m_overflow ? m_overflow->maxXVisualOverflow() : width(); }
+ int logicalLeftVisualOverflow() const { return style()->isHorizontalWritingMode() ? minXVisualOverflow() : minYVisualOverflow(); }
+ int logicalRightVisualOverflow() const { return style()->isHorizontalWritingMode() ? maxXVisualOverflow() : maxYVisualOverflow(); }
void addLayoutOverflow(const IntRect&);
void addVisualOverflow(const IntRect&);
@@ -172,7 +176,7 @@ public:
int clientTop() const { return borderTop(); }
int clientWidth() const;
int clientHeight() const;
- int clientLogicalBottom() const { return style()->isHorizontalWritingMode() ? clientTop() + clientHeight() : clientLeft() + clientWidth(); }
+ int clientLogicalBottom() const { return borderBefore() + (style()->isHorizontalWritingMode() ? clientHeight() : clientWidth()); }
IntRect clientBoxRect() const { return IntRect(clientLeft(), clientTop(), clientWidth(), clientHeight()); }
// scrollWidth/scrollHeight will be the same as clientWidth/clientHeight unless the
@@ -378,6 +382,7 @@ public:
IntPoint flipForWritingMode(const RenderBox* child, const IntPoint&, FlippingAdjustment) const;
int flipForWritingMode(int position) const; // The offset is in the block direction (y for horizontal writing modes, x for vertical writing modes).
IntPoint flipForWritingMode(const IntPoint&) const;
+ IntPoint flipForWritingModeIncludingColumns(const IntPoint&) const;
IntSize flipForWritingMode(const IntSize&) const;
void flipForWritingMode(IntRect&) const;
IntSize locationOffsetIncludingFlipping() const;
diff --git a/Source/WebCore/rendering/RenderBoxModelObject.cpp b/Source/WebCore/rendering/RenderBoxModelObject.cpp
index f2412a1..ffbecce 100644
--- a/Source/WebCore/rendering/RenderBoxModelObject.cpp
+++ b/Source/WebCore/rendering/RenderBoxModelObject.cpp
@@ -50,8 +50,8 @@ bool RenderBoxModelObject::s_layerWasSelfPainting = false;
static const double cInterpolationCutoff = 800. * 800.;
static const double cLowQualityTimeThreshold = 0.500; // 500 ms
-typedef pair<RenderBoxModelObject*, const void*> LastPaintSizeMapKey;
-typedef HashMap<LastPaintSizeMapKey, IntSize> LastPaintSizeMap;
+typedef HashMap<const void*, IntSize> LayerSizeMap;
+typedef HashMap<RenderBoxModelObject*, LayerSizeMap> ObjectLayerSizeMap;
// The HashMap for storing continuation pointers.
// An inline can be split with blocks occuring in between the inline content.
@@ -68,14 +68,16 @@ class ImageQualityController {
public:
ImageQualityController();
bool shouldPaintAtLowQuality(GraphicsContext*, RenderBoxModelObject*, Image*, const void* layer, const IntSize&);
- void keyDestroyed(LastPaintSizeMapKey key);
+ void removeLayer(RenderBoxModelObject*, LayerSizeMap* innerMap, const void* layer);
+ void set(RenderBoxModelObject*, LayerSizeMap* innerMap, const void* layer, const IntSize&);
void objectDestroyed(RenderBoxModelObject*);
+ bool isEmpty() { return m_objectLayerSizeMap.isEmpty(); }
private:
void highQualityRepaintTimerFired(Timer<ImageQualityController>*);
void restartTimer();
- LastPaintSizeMap m_lastPaintSizeMap;
+ ObjectLayerSizeMap m_objectLayerSizeMap;
Timer<ImageQualityController> m_timer;
bool m_animatedResizeIsActive;
};
@@ -86,31 +88,41 @@ ImageQualityController::ImageQualityController()
{
}
-void ImageQualityController::keyDestroyed(LastPaintSizeMapKey key)
+void ImageQualityController::removeLayer(RenderBoxModelObject* object, LayerSizeMap* innerMap, const void* layer)
{
- m_lastPaintSizeMap.remove(key);
- if (m_lastPaintSizeMap.isEmpty()) {
- m_animatedResizeIsActive = false;
- m_timer.stop();
+ if (innerMap) {
+ innerMap->remove(layer);
+ if (innerMap->isEmpty())
+ objectDestroyed(object);
}
}
-void ImageQualityController::objectDestroyed(RenderBoxModelObject* object)
+void ImageQualityController::set(RenderBoxModelObject* object, LayerSizeMap* innerMap, const void* layer, const IntSize& size)
{
- Vector<LastPaintSizeMapKey> keysToDie;
- for (LastPaintSizeMap::iterator it = m_lastPaintSizeMap.begin(); it != m_lastPaintSizeMap.end(); ++it)
- if (it->first.first == object)
- keysToDie.append(it->first);
- for (Vector<LastPaintSizeMapKey>::iterator it = keysToDie.begin(); it != keysToDie.end(); ++it)
- keyDestroyed(*it);
+ if (innerMap)
+ innerMap->set(layer, size);
+ else {
+ LayerSizeMap newInnerMap;
+ newInnerMap.set(layer, size);
+ m_objectLayerSizeMap.set(object, newInnerMap);
+ }
}
+void ImageQualityController::objectDestroyed(RenderBoxModelObject* object)
+{
+ m_objectLayerSizeMap.remove(object);
+ if (m_objectLayerSizeMap.isEmpty()) {
+ m_animatedResizeIsActive = false;
+ m_timer.stop();
+ }
+}
+
void ImageQualityController::highQualityRepaintTimerFired(Timer<ImageQualityController>*)
{
if (m_animatedResizeIsActive) {
m_animatedResizeIsActive = false;
- for (LastPaintSizeMap::iterator it = m_lastPaintSizeMap.begin(); it != m_lastPaintSizeMap.end(); ++it)
- it->first.first->repaint();
+ for (ObjectLayerSizeMap::iterator it = m_objectLayerSizeMap.begin(); it != m_objectLayerSizeMap.end(); ++it)
+ it->first->repaint();
}
}
@@ -130,17 +142,24 @@ bool ImageQualityController::shouldPaintAtLowQuality(GraphicsContext* context, R
// is actually being scaled.
IntSize imageSize(image->width(), image->height());
- // Look ourselves up in the hashtable.
- LastPaintSizeMapKey key(object, layer);
- LastPaintSizeMap::iterator i = m_lastPaintSizeMap.find(key);
+ // Look ourselves up in the hashtables.
+ ObjectLayerSizeMap::iterator i = m_objectLayerSizeMap.find(object);
+ LayerSizeMap* innerMap = i != m_objectLayerSizeMap.end() ? &i->second : 0;
+ IntSize oldSize;
+ bool isFirstResize = true;
+ if (innerMap) {
+ LayerSizeMap::iterator j = innerMap->find(layer);
+ if (j != innerMap->end()) {
+ isFirstResize = false;
+ oldSize = j->second;
+ }
+ }
const AffineTransform& currentTransform = context->getCTM();
bool contextIsScaled = !currentTransform.isIdentityOrTranslationOrFlipped();
if (!contextIsScaled && imageSize == size) {
// There is no scale in effect. If we had a scale in effect before, we can just remove this object from the list.
- if (i != m_lastPaintSizeMap.end())
- m_lastPaintSizeMap.remove(key);
-
+ removeLayer(object, innerMap, layer);
return false;
}
@@ -150,39 +169,44 @@ bool ImageQualityController::shouldPaintAtLowQuality(GraphicsContext* context, R
if (totalPixels > cInterpolationCutoff)
return true;
}
+
// If an animated resize is active, paint in low quality and kick the timer ahead.
if (m_animatedResizeIsActive) {
- m_lastPaintSizeMap.set(key, size);
+ set(object, innerMap, layer, size);
restartTimer();
return true;
}
// If this is the first time resizing this image, or its size is the
// same as the last resize, draw at high res, but record the paint
// size and set the timer.
- if (i == m_lastPaintSizeMap.end() || size == i->second) {
+ if (isFirstResize || oldSize == size) {
restartTimer();
- m_lastPaintSizeMap.set(key, size);
+ set(object, innerMap, layer, size);
return false;
}
// If the timer is no longer active, draw at high quality and don't
// set the timer.
if (!m_timer.isActive()) {
- keyDestroyed(key);
+ removeLayer(object, innerMap, layer);
return false;
}
// This object has been resized to two different sizes while the timer
// is active, so draw at low quality, set the flag for animated resizes and
// the object to the list for high quality redraw.
- m_lastPaintSizeMap.set(key, size);
+ set(object, innerMap, layer, size);
m_animatedResizeIsActive = true;
restartTimer();
return true;
}
+static ImageQualityController* gImageQualityController = 0;
+
static ImageQualityController* imageQualityController()
{
- static ImageQualityController* controller = new ImageQualityController;
- return controller;
+ if (!gImageQualityController)
+ gImageQualityController = new ImageQualityController;
+
+ return gImageQualityController;
}
void RenderBoxModelObject::setSelectionState(SelectionState s)
@@ -223,7 +247,13 @@ RenderBoxModelObject::~RenderBoxModelObject()
// Our layer should have been destroyed and cleared by now
ASSERT(!hasLayer());
ASSERT(!m_layer);
- imageQualityController()->objectDestroyed(this);
+ if (gImageQualityController) {
+ gImageQualityController->objectDestroyed(this);
+ if (gImageQualityController->isEmpty()) {
+ delete gImageQualityController;
+ gImageQualityController = 0;
+ }
+ }
}
void RenderBoxModelObject::destroyLayer()
@@ -351,7 +381,7 @@ int RenderBoxModelObject::relativePositionOffsetX() const
// call availableWidth on our containing block.
if (!style()->left().isAuto()) {
RenderBlock* cb = containingBlock();
- if (!style()->right().isAuto() && !containingBlock()->style()->isLeftToRightDirection())
+ if (!style()->right().isAuto() && !cb->style()->isLeftToRightDirection())
return -style()->right().calcValue(cb->availableWidth());
return style()->left().calcValue(cb->availableWidth());
}
@@ -693,9 +723,9 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
phase += destRect.location() - destOrigin;
CompositeOperator compositeOp = op == CompositeSourceOver ? bgLayer->composite() : op;
RenderObject* clientForBackgroundImage = backgroundObject ? backgroundObject : this;
- Image* image = bg->image(clientForBackgroundImage, tileSize);
- bool useLowQualityScaling = shouldPaintAtLowQuality(context, image, bgLayer, tileSize);
- context->drawTiledImage(image, style()->colorSpace(), destRect, phase, tileSize, compositeOp, useLowQualityScaling);
+ RefPtr<Image> image = bg->image(clientForBackgroundImage, tileSize);
+ bool useLowQualityScaling = shouldPaintAtLowQuality(context, image.get(), bgLayer, tileSize);
+ context->drawTiledImage(image.get(), style()->colorSpace(), destRect, phase, tileSize, compositeOp, useLowQualityScaling);
}
}
@@ -897,7 +927,7 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
bool drawMiddle = (imageWidth - leftSlice - rightSlice) > 0 && (w - leftWidth - rightWidth) > 0 &&
(imageHeight - topSlice - bottomSlice) > 0 && (h - topWidth - bottomWidth) > 0;
- Image* image = styleImage->image(this, imageSize);
+ RefPtr<Image> image = styleImage->image(this, imageSize);
ColorSpace colorSpace = style->colorSpace();
if (drawLeft) {
@@ -906,18 +936,18 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
// The top left corner rect is (tx, ty, leftWidth, topWidth)
// The rect to use from within the image is obtained from our slice, and is (0, 0, leftSlice, topSlice)
if (drawTop)
- graphicsContext->drawImage(image, colorSpace, IntRect(tx, ty, leftWidth, topWidth),
+ graphicsContext->drawImage(image.get(), colorSpace, IntRect(tx, ty, leftWidth, topWidth),
IntRect(0, 0, leftSlice, topSlice), op);
// The bottom left corner rect is (tx, ty + h - bottomWidth, leftWidth, bottomWidth)
// The rect to use from within the image is (0, imageHeight - bottomSlice, leftSlice, botomSlice)
if (drawBottom)
- graphicsContext->drawImage(image, colorSpace, IntRect(tx, ty + h - bottomWidth, leftWidth, bottomWidth),
+ graphicsContext->drawImage(image.get(), colorSpace, IntRect(tx, ty + h - bottomWidth, leftWidth, bottomWidth),
IntRect(0, imageHeight - bottomSlice, leftSlice, bottomSlice), op);
// Paint the left edge.
// Have to scale and tile into the border rect.
- graphicsContext->drawTiledImage(image, colorSpace, IntRect(tx, ty + topWidth, leftWidth,
+ graphicsContext->drawTiledImage(image.get(), colorSpace, IntRect(tx, ty + topWidth, leftWidth,
h - topWidth - bottomWidth),
IntRect(0, topSlice, leftSlice, imageHeight - topSlice - bottomSlice),
Image::StretchTile, (Image::TileRule)vRule, op);
@@ -928,17 +958,17 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
// The top right corner rect is (tx + w - rightWidth, ty, rightWidth, topWidth)
// The rect to use from within the image is obtained from our slice, and is (imageWidth - rightSlice, 0, rightSlice, topSlice)
if (drawTop)
- graphicsContext->drawImage(image, colorSpace, IntRect(tx + w - rightWidth, ty, rightWidth, topWidth),
+ graphicsContext->drawImage(image.get(), colorSpace, IntRect(tx + w - rightWidth, ty, rightWidth, topWidth),
IntRect(imageWidth - rightSlice, 0, rightSlice, topSlice), op);
// The bottom right corner rect is (tx + w - rightWidth, ty + h - bottomWidth, rightWidth, bottomWidth)
// The rect to use from within the image is (imageWidth - rightSlice, imageHeight - bottomSlice, rightSlice, bottomSlice)
if (drawBottom)
- graphicsContext->drawImage(image, colorSpace, IntRect(tx + w - rightWidth, ty + h - bottomWidth, rightWidth, bottomWidth),
+ graphicsContext->drawImage(image.get(), colorSpace, IntRect(tx + w - rightWidth, ty + h - bottomWidth, rightWidth, bottomWidth),
IntRect(imageWidth - rightSlice, imageHeight - bottomSlice, rightSlice, bottomSlice), op);
// Paint the right edge.
- graphicsContext->drawTiledImage(image, colorSpace, IntRect(tx + w - rightWidth, ty + topWidth, rightWidth,
+ graphicsContext->drawTiledImage(image.get(), colorSpace, IntRect(tx + w - rightWidth, ty + topWidth, rightWidth,
h - topWidth - bottomWidth),
IntRect(imageWidth - rightSlice, topSlice, rightSlice, imageHeight - topSlice - bottomSlice),
Image::StretchTile, (Image::TileRule)vRule, op);
@@ -946,20 +976,20 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
// Paint the top edge.
if (drawTop)
- graphicsContext->drawTiledImage(image, colorSpace, IntRect(tx + leftWidth, ty, w - leftWidth - rightWidth, topWidth),
+ graphicsContext->drawTiledImage(image.get(), colorSpace, IntRect(tx + leftWidth, ty, w - leftWidth - rightWidth, topWidth),
IntRect(leftSlice, 0, imageWidth - rightSlice - leftSlice, topSlice),
(Image::TileRule)hRule, Image::StretchTile, op);
// Paint the bottom edge.
if (drawBottom)
- graphicsContext->drawTiledImage(image, colorSpace, IntRect(tx + leftWidth, ty + h - bottomWidth,
+ graphicsContext->drawTiledImage(image.get(), colorSpace, IntRect(tx + leftWidth, ty + h - bottomWidth,
w - leftWidth - rightWidth, bottomWidth),
IntRect(leftSlice, imageHeight - bottomSlice, imageWidth - rightSlice - leftSlice, bottomSlice),
(Image::TileRule)hRule, Image::StretchTile, op);
// Paint the middle.
if (drawMiddle)
- graphicsContext->drawTiledImage(image, colorSpace, IntRect(tx + leftWidth, ty + topWidth, w - leftWidth - rightWidth,
+ graphicsContext->drawTiledImage(image.get(), colorSpace, IntRect(tx + leftWidth, ty + topWidth, w - leftWidth - rightWidth,
h - topWidth - bottomWidth),
IntRect(leftSlice, topSlice, imageWidth - rightSlice - leftSlice, imageHeight - topSlice - bottomSlice),
(Image::TileRule)hRule, (Image::TileRule)vRule, op);
@@ -1545,6 +1575,20 @@ void RenderBoxModelObject::clipBorderSidePolygon(GraphicsContext* graphicsContex
graphicsContext->clipConvexPolygon(4, secondQuad, !secondEdgeMatches);
}
+static inline IntRect areaCastingShadowInHole(const IntRect& holeRect, int shadowBlur, int shadowSpread, const IntSize& shadowOffset)
+{
+ IntRect bounds(holeRect);
+
+ bounds.inflate(shadowBlur);
+
+ if (shadowSpread < 0)
+ bounds.inflate(-shadowSpread);
+
+ IntRect offsetBounds = bounds;
+ offsetBounds.move(-shadowOffset);
+ return unionRect(bounds, offsetBounds);
+}
+
void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int ty, int w, int h, const RenderStyle* s, ShadowStyle shadowStyle, bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
{
// FIXME: Deal with border-image. Would be great to use border-image as a mask.
@@ -1555,17 +1599,18 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
RoundedIntRect border(tx, ty, w, h);
bool hasBorderRadius = s->hasBorderRadius();
bool isHorizontal = s->isHorizontalWritingMode();
- if (hasBorderRadius && (includeLogicalLeftEdge || includeLogicalRightEdge)) {
- RoundedIntRect::Radii radii = ((shadowStyle == Inset) ? s->getRoundedInnerBorderWithBorderWidths(border.rect(), borderTop(), borderBottom(), borderLeft(), borderRight()) : s->getRoundedBorderFor(border.rect())).radii();
- border.includeLogicalEdges(radii, isHorizontal, includeLogicalLeftEdge, includeLogicalRightEdge);
- }
-
+
if (shadowStyle == Inset)
border.setRect(IntRect(border.rect().x() + (includeLogicalLeftEdge || !isHorizontal ? borderLeft() : 0),
border.rect().y() + (includeLogicalLeftEdge || isHorizontal ? borderTop() : 0),
border.rect().width() - ((includeLogicalLeftEdge || !isHorizontal) ? borderLeft() : 0) - ((includeLogicalRightEdge || !isHorizontal) ? borderRight() : 0),
border.rect().height() - ((includeLogicalLeftEdge || isHorizontal) ? borderTop() : 0) - ((includeLogicalRightEdge || isHorizontal) ? borderBottom() : 0)));
+ if (hasBorderRadius && (includeLogicalLeftEdge || includeLogicalRightEdge)) {
+ RoundedIntRect::Radii radii = ((shadowStyle == Inset) ? s->getRoundedInnerBorderWithBorderWidths(border.rect(), borderTop(), borderBottom(), borderLeft(), borderRight()) : s->getRoundedBorderFor(border.rect())).radii();
+ border.includeLogicalEdges(radii, isHorizontal, includeLogicalLeftEdge, includeLogicalRightEdge);
+ }
+
bool hasOpaqueBackground = s->visitedDependentColor(CSSPropertyBackgroundColor).isValid() && s->visitedDependentColor(CSSPropertyBackgroundColor).alpha() == 255;
for (const ShadowData* shadow = s->boxShadow(); shadow; shadow = shadow->next()) {
if (shadow->style() != shadowStyle)
@@ -1595,7 +1640,11 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
shadowOffset -= extraOffset;
fillRect.move(extraOffset);
- context->setShadow(shadowOffset, shadowBlur, shadowColor, s->colorSpace());
+ if (shadow->isWebkitBoxShadow())
+ context->setLegacyShadow(shadowOffset, shadowBlur, shadowColor, s->colorSpace());
+ else
+ context->setShadow(shadowOffset, shadowBlur, shadowColor, s->colorSpace());
+
if (hasBorderRadius) {
RoundedIntRect rectToClipOut = border;
@@ -1611,6 +1660,7 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
if (shadowSpread < 0)
fillRect.expandRadii(shadowSpread);
+
context->fillRoundedRect(fillRect, Color::black, s->colorSpace());
} else {
IntRect rectToClipOut = border.rect();
@@ -1663,17 +1713,14 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
Color fillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), 255);
- IntRect outerRect(border.rect());
- outerRect.inflateX(w - 2 * shadowSpread);
- outerRect.inflateY(h - 2 * shadowSpread);
-
+ IntRect outerRect = areaCastingShadowInHole(border.rect(), shadowBlur, shadowSpread, shadowOffset);
context->save();
Path path;
if (hasBorderRadius) {
+ Path path;
path.addRoundedRect(border.rect(), border.radii().topLeft(), border.radii().topRight(), border.radii().bottomLeft(), border.radii().bottomRight());
context->clip(path);
- path.clear();
} else
context->clip(border.rect());
@@ -1681,19 +1728,16 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
context->translate(extraOffset.width(), extraOffset.height());
shadowOffset -= extraOffset;
- path.addRect(outerRect);
-
- if (hasBorderRadius) {
- if (shadowSpread > 0)
- border.shrinkRadii(shadowSpread);
- path.addRoundedRect(holeRect, border.radii().topLeft(), border.radii().topRight(), border.radii().bottomLeft(), border.radii().bottomRight());
- } else
- path.addRect(holeRect);
+ if (hasBorderRadius && shadowSpread > 0)
+ border.shrinkRadii(shadowSpread);
+
+ if (shadow->isWebkitBoxShadow())
+ context->setLegacyShadow(shadowOffset, shadowBlur, shadowColor, s->colorSpace());
+ else
+ context->setShadow(shadowOffset, shadowBlur, shadowColor, s->colorSpace());
- context->setFillRule(RULE_EVENODD);
- context->setFillColor(fillColor, s->colorSpace());
- context->setShadow(shadowOffset, shadowBlur, shadowColor, s->colorSpace());
- context->fillPath(path);
+ RoundedIntRect roundedHole(holeRect, border.radii());
+ context->fillRectWithRoundedHole(outerRect, roundedHole, fillColor, s->colorSpace());
context->restore();
}
diff --git a/Source/WebCore/rendering/RenderCombineText.cpp b/Source/WebCore/rendering/RenderCombineText.cpp
new file mode 100644
index 0000000..1b20bd8
--- /dev/null
+++ b/Source/WebCore/rendering/RenderCombineText.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2011 Apple 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 "RenderCombineText.h"
+
+#include "TextRun.h"
+
+namespace WebCore {
+
+const float textCombineMargin = 1.1f; // Allow em + 10% margin
+
+RenderCombineText::RenderCombineText(Node* node, PassRefPtr<StringImpl> string)
+ : RenderText(node, string)
+ , m_combinedTextWidth(0)
+ , m_isCombined(false)
+ , m_needsFontUpdate(false)
+{
+}
+
+void RenderCombineText::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+ RenderText::styleDidChange(diff, oldStyle);
+
+ if (m_isCombined)
+ RenderText::setTextInternal(originalText()); // This RenderCombineText has been combined once. Restore the original text for the next combineText().
+
+ m_needsFontUpdate = true;
+}
+
+void RenderCombineText::setTextInternal(PassRefPtr<StringImpl> text)
+{
+ RenderText::setTextInternal(text);
+
+ m_needsFontUpdate = true;
+}
+
+unsigned RenderCombineText::width(unsigned from, unsigned length, const Font& font, int xPosition, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
+{
+ if (!characters())
+ return 0;
+
+ if (m_isCombined)
+ return font.size();
+
+ return RenderText::width(from, length, font, xPosition, fallbackFonts, glyphOverflow);
+}
+
+void RenderCombineText::adjustTextOrigin(IntPoint& textOrigin, const IntRect& boxRect) const
+{
+ if (m_isCombined)
+ textOrigin.move(boxRect.height() / 2 - ceilf(m_combinedTextWidth) / 2, style()->font().pixelSize());
+}
+
+void RenderCombineText::charactersToRender(int start, const UChar*& characters, int& length) const
+{
+ if (m_isCombined) {
+ length = originalText()->length();
+ characters = originalText()->characters();
+ return;
+ }
+
+ characters = text()->characters() + start;
+}
+
+void RenderCombineText::combineText()
+{
+ if (!m_needsFontUpdate)
+ return;
+
+ m_isCombined = false;
+ m_needsFontUpdate = false;
+
+ // CSS3 spec says text-combine works only in vertical writing mode.
+ if (style()->isHorizontalWritingMode())
+ return;
+
+ TextRun run = TextRun(String(text()));
+ FontDescription description = style()->font().fontDescription();
+ float emWidth = description.computedSize() * textCombineMargin;
+ bool shouldUpdateFont = false;
+
+ description.setOrientation(Horizontal); // We are going to draw combined text horizontally.
+ m_combinedTextWidth = style()->font().floatWidth(run);
+ m_isCombined = m_combinedTextWidth <= emWidth;
+
+ if (m_isCombined)
+ shouldUpdateFont = style()->setFontDescription(description); // Need to change font orientation to horizontal.
+ else {
+ // Need to try compressed glyphs.
+ static const FontWidthVariant widthVariants[] = { HalfWidth, ThirdWidth, QuarterWidth };
+ for (size_t i = 0 ; i < WTF_ARRAY_LENGTH(widthVariants) ; ++i) {
+ description.setWidthVariant(widthVariants[i]);
+ Font compressedFont = Font(description, style()->font().letterSpacing(), style()->font().wordSpacing());
+ compressedFont.update(style()->font().fontSelector());
+ float runWidth = compressedFont.floatWidth(run);
+ if (runWidth <= emWidth) {
+ m_combinedTextWidth = runWidth;
+ m_isCombined = true;
+
+ // Replace my font with the new one.
+ shouldUpdateFont = style()->setFontDescription(description);
+ break;
+ }
+ }
+ }
+
+ if (shouldUpdateFont)
+ style()->font().update(style()->font().fontSelector());
+
+ if (m_isCombined) {
+ static const UChar newCharacter = objectReplacementCharacter;
+ DEFINE_STATIC_LOCAL(String, objectReplacementCharacterString, (&newCharacter, 1));
+ RenderText::setTextInternal(objectReplacementCharacterString.impl());
+ }
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderCombineText.h b/Source/WebCore/rendering/RenderCombineText.h
new file mode 100644
index 0000000..582cbd6
--- /dev/null
+++ b/Source/WebCore/rendering/RenderCombineText.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2011 Apple 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 RenderCombineText_h
+#define RenderCombineText_h
+
+#include "RenderText.h"
+
+namespace WebCore {
+
+class RenderCombineText : public RenderText {
+public:
+ RenderCombineText(Node*, PassRefPtr<StringImpl>);
+
+ void combineText();
+ void adjustTextOrigin(IntPoint& textOrigin, const IntRect& 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(); }
+
+private:
+ virtual unsigned width(unsigned from, unsigned length, const Font&, int 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>);
+
+ float m_combinedTextWidth;
+ bool m_isCombined : 1;
+ bool m_needsFontUpdate : 1;
+};
+
+inline RenderCombineText* toRenderCombineText(RenderObject* object)
+{
+ ASSERT(!object || object->isText());
+ return static_cast<RenderCombineText*>(object);
+}
+
+inline const RenderCombineText* toRenderCombineText(const RenderObject* object)
+{
+ ASSERT(!object || object->isText());
+ return static_cast<const RenderCombineText*>(object);
+}
+
+// This will catch anyone doing an unnecessary cast.
+void toRenderCombineText(const RenderCombineText*);
+
+} // namespace WebCore
+
+#endif // RenderCombineText_h
diff --git a/Source/WebCore/rendering/RenderCounter.cpp b/Source/WebCore/rendering/RenderCounter.cpp
index 57c54f8..fbd5545 100644
--- a/Source/WebCore/rendering/RenderCounter.cpp
+++ b/Source/WebCore/rendering/RenderCounter.cpp
@@ -24,6 +24,7 @@
#include "CounterNode.h"
#include "Document.h"
+#include "Element.h"
#include "HTMLNames.h"
#include "HTMLOListElement.h"
#include "RenderListItem.h"
@@ -46,11 +47,157 @@ static CounterMaps& counterMaps()
return staticCounterMaps;
}
-static inline RenderObject* previousSiblingOrParent(RenderObject* object)
+// This function processes the renderer tree in the order of the DOM tree
+// including pseudo elements as defined in CSS 2.1.
+// Anonymous renderers are skipped except for those representing pseudo elements.
+static RenderObject* previousInPreOrder(const RenderObject* object)
{
- if (RenderObject* sibling = object->previousSibling())
- return sibling;
- return object->parent();
+ Element* parent;
+ Element* sibling;
+ switch (object->style()->styleType()) {
+ case NOPSEUDO:
+ ASSERT(!object->isAnonymous());
+ parent = toElement(object->node());
+ sibling = parent->previousElementSibling();
+ parent = parent->parentElement();
+ break;
+ case BEFORE:
+ return object->generatingNode()->renderer(); // It is always the generating node's renderer
+ case AFTER:
+ parent = toElement(object->generatingNode());
+ sibling = parent->lastElementChild();
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+ while (sibling) {
+ if (RenderObject* renderer = sibling->renderer()) {
+ if (RenderObject* after = renderer->afterPseudoElementRenderer())
+ return after;
+ parent = sibling;
+ sibling = sibling->lastElementChild();
+ if (!sibling) {
+ if (RenderObject* before = renderer->beforePseudoElementRenderer())
+ return before;
+ return renderer;
+ }
+ } else
+ sibling = sibling->previousElementSibling();
+ }
+ if (!parent)
+ return 0;
+ RenderObject* renderer = parent->renderer(); // Should never be null
+ if (RenderObject* before = renderer->beforePseudoElementRenderer())
+ return before;
+ return renderer;
+}
+
+// This function processes the renderer tree in the order of the DOM tree
+// including pseudo elements as defined in CSS 2.1.
+// Anonymous renderers are skipped except for those representing pseudo elements.
+static RenderObject* previousSiblingOrParent(const RenderObject* object)
+{
+ Element* parent;
+ Element* sibling;
+ switch (object->style()->styleType()) {
+ case NOPSEUDO:
+ ASSERT(!object->isAnonymous());
+ parent = toElement(object->node());
+ sibling = parent->previousElementSibling();
+ parent = parent->parentElement();
+ break;
+ case BEFORE:
+ return object->generatingNode()->renderer(); // It is always the generating node's renderer
+ case AFTER:
+ parent = toElement(object->generatingNode());
+ sibling = parent->lastElementChild();
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+ while (sibling) {
+ if (RenderObject* renderer = sibling->renderer()) // This skips invisible nodes
+ return renderer;
+ sibling = sibling->previousElementSibling();
+ }
+ if (parent) {
+ RenderObject* renderer = parent->renderer();
+ if (RenderObject* before = renderer->virtualChildren()->beforePseudoElementRenderer(renderer))
+ return before;
+ return renderer;
+ }
+ return 0;
+}
+
+static Element* parentElement(RenderObject* object)
+{
+ switch (object->style()->styleType()) {
+ case NOPSEUDO:
+ ASSERT(!object->isAnonymous());
+ return toElement(object->node())->parentElement();
+ case BEFORE:
+ case AFTER:
+ return toElement(object->generatingNode());
+ default:
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+}
+
+static inline bool areRenderersElementsSiblings(RenderObject* first, RenderObject* second)
+{
+ return parentElement(first) == parentElement(second);
+}
+
+// This function processes the renderer tree in the order of the DOM tree
+// including pseudo elements as defined in CSS 2.1.
+// Anonymous renderers are skipped except for those representing pseudo elements.
+static RenderObject* nextInPreOrder(const RenderObject* object, const Element* stayWithin, bool skipDescendants = false)
+{
+ Element* self;
+ Element* child;
+ RenderObject* result;
+ self = toElement(object->generatingNode());
+ if (skipDescendants)
+ goto nextsibling;
+ switch (object->style()->styleType()) {
+ case NOPSEUDO:
+ ASSERT(!object->isAnonymous());
+ result = object->beforePseudoElementRenderer();
+ if (result)
+ return result;
+ break;
+ case BEFORE:
+ break;
+ case AFTER:
+ goto nextsibling;
+ default:
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+ child = self->firstElementChild();
+ while (true) {
+ while (child) {
+ result = child->renderer();
+ if (result)
+ return result;
+ child = child->nextElementSibling();
+ }
+ result = self->renderer()->afterPseudoElementRenderer();
+ if (result)
+ return result;
+nextsibling:
+ if (self == stayWithin)
+ return 0;
+ child = self->nextElementSibling();
+ self = self->parentElement();
+ if (!self) {
+ ASSERT(!child); // We can only reach this if we are searching beyond the root element
+ return 0; // which cannot have siblings
+ }
+ }
}
static bool planCounter(RenderObject* object, const AtomicString& identifier, bool& isReset, int& value)
@@ -61,10 +208,27 @@ static bool planCounter(RenderObject* object, const AtomicString& identifier, bo
// We can't even look at their styles or we'll see extra resets and increments!
if (object->isText() && !object->isBR())
return false;
-
+ Node* generatingNode = object->generatingNode();
+ // We must have a generating node or else we cannot have a counter.
+ if (!generatingNode)
+ return false;
RenderStyle* style = object->style();
ASSERT(style);
+ switch (style->styleType()) {
+ case NOPSEUDO:
+ // Sometimes nodes have more then one renderer. Only the first one gets the counter
+ // LayoutTests/http/tests/css/counter-crash.html
+ if (generatingNode->renderer() != object)
+ return false;
+ break;
+ case BEFORE:
+ case AFTER:
+ break;
+ default:
+ return false; // Counters are forbidden from all other pseudo elements.
+ }
+
if (const CounterDirectiveMap* directivesMap = style->counterDirectives()) {
CounterDirectives directives = directivesMap->get(identifier.impl());
if (directives.m_reset) {
@@ -133,14 +297,9 @@ static bool findPlaceForCounter(RenderObject* counterOwner, const AtomicString&
// We check renderers in preOrder from the renderer that our counter is attached to
// towards the begining of the document for counters with the same identifier as the one
// we are trying to find a place for. This is the next renderer to be checked.
- RenderObject* currentRenderer = counterOwner->previousInPreOrder();
+ RenderObject* currentRenderer = previousInPreOrder(counterOwner);
previousSibling = 0;
while (currentRenderer) {
- // A sibling without a parent means that the counter node tree was not constructed correctly so we stop
- // traversing. In the future RenderCounter should handle RenderObjects that are not connected to the
- // render tree at counter node creation. See bug 43812.
- if (previousSibling && !previousSibling->parent())
- return false;
CounterNode* currentCounter = makeCounterNode(currentRenderer, identifier, false);
if (searchEndRenderer == currentRenderer) {
// We may be at the end of our search.
@@ -149,7 +308,7 @@ static bool findPlaceForCounter(RenderObject* counterOwner, const AtomicString&
if (previousSibling) { // But we already found another counter that we come after.
if (currentCounter->actsAsReset()) {
// We found a reset counter that is on a renderer that is a sibling of ours or a parent.
- if (isReset && currentRenderer->parent() == counterOwner->parent()) {
+ if (isReset && areRenderersElementsSiblings(currentRenderer, counterOwner)) {
// We are also a reset counter and the previous reset was on a sibling renderer
// hence we are the next sibling of that counter if that reset is not a root or
// we are a root node if that reset is a root.
@@ -164,7 +323,7 @@ static bool findPlaceForCounter(RenderObject* counterOwner, const AtomicString&
return true;
}
// CurrentCounter, the counter at the EndSearchRenderer, is not reset.
- if (!isReset || currentRenderer->parent() != counterOwner->parent()) {
+ if (!isReset || !areRenderersElementsSiblings(currentRenderer, counterOwner)) {
// If the node we are placing is not reset or we have found a counter that is attached
// to an ancestor of the placed counter's renderer we know we are a sibling of that node.
ASSERT(currentCounter->parent() == previousSibling->parent());
@@ -177,7 +336,7 @@ static bool findPlaceForCounter(RenderObject* counterOwner, const AtomicString&
// previousSibling, and when we are a sibling of the end counter we must set previousSibling
// to currentCounter.
if (currentCounter->actsAsReset()) {
- if (isReset && currentRenderer->parent() == counterOwner->parent()) {
+ if (isReset && areRenderersElementsSiblings(currentRenderer, counterOwner)) {
parent = currentCounter->parent();
previousSibling = currentCounter;
return parent;
@@ -185,7 +344,7 @@ static bool findPlaceForCounter(RenderObject* counterOwner, const AtomicString&
parent = currentCounter;
return true;
}
- if (!isReset || currentRenderer->parent() != counterOwner->parent()) {
+ if (!isReset || !areRenderersElementsSiblings(currentRenderer, counterOwner)) {
parent = currentCounter->parent();
previousSibling = currentCounter;
return true;
@@ -210,7 +369,7 @@ static bool findPlaceForCounter(RenderObject* counterOwner, const AtomicString&
previousSibling = currentCounter;
// We are no longer interested in previous siblings of the currentRenderer or their children
// as counters they may have attached cannot be the previous sibling of the counter we are placing.
- currentRenderer = currentRenderer->parent();
+ currentRenderer = parentElement(currentRenderer)->renderer();
continue;
}
} else
@@ -261,28 +420,28 @@ static CounterNode* makeCounterNode(RenderObject* object, const AtomicString& id
object->m_hasCounterNodeMap = true;
}
nodeMap->set(identifier.impl(), newNode);
- if (newNode->parent() || !object->nextInPreOrder(object->parent()))
+ if (newNode->parent())
return newNode.get();
// Checking if some nodes that were previously counter tree root nodes
// should become children of this node now.
CounterMaps& maps = counterMaps();
- RenderObject* stayWithin = object->parent();
- for (RenderObject* currentRenderer = object->nextInPreOrder(stayWithin); currentRenderer; currentRenderer = currentRenderer->nextInPreOrder(stayWithin)) {
+ Element* stayWithin = parentElement(object);
+ bool skipDescendants;
+ for (RenderObject* currentRenderer = nextInPreOrder(object, stayWithin); currentRenderer; currentRenderer = nextInPreOrder(currentRenderer, stayWithin, skipDescendants)) {
+ skipDescendants = false;
if (!currentRenderer->m_hasCounterNodeMap)
continue;
CounterNode* currentCounter = maps.get(currentRenderer)->get(identifier.impl()).get();
if (!currentCounter)
continue;
+ skipDescendants = true;
if (currentCounter->parent()) {
ASSERT(newNode->firstChild());
- if (currentRenderer->lastChild())
- currentRenderer = currentRenderer->lastChild();
continue;
}
- if (stayWithin != currentRenderer->parent() || !currentCounter->hasResetType())
- newNode->insertAfter(currentCounter, newNode->lastChild(), identifier);
- if (currentRenderer->lastChild())
- currentRenderer = currentRenderer->lastChild();
+ if (stayWithin == parentElement(currentRenderer) && currentCounter->hasResetType())
+ break;
+ newNode->insertAfter(currentCounter, newNode->lastChild(), identifier);
}
return newNode.get();
}
@@ -449,12 +608,22 @@ static void updateCounters(RenderObject* renderer)
void RenderCounter::rendererSubtreeAttached(RenderObject* renderer)
{
+ Node* node = renderer->node();
+ if (node)
+ node = node->parentNode();
+ else
+ node = renderer->generatingNode();
+ if (node && !node->attached())
+ return; // No need to update if the parent is not attached yet
for (RenderObject* descendant = renderer; descendant; descendant = descendant->nextInPreOrder(renderer))
updateCounters(descendant);
}
void RenderCounter::rendererStyleChanged(RenderObject* renderer, const RenderStyle* oldStyle, const RenderStyle* newStyle)
{
+ Node* node = renderer->generatingNode();
+ if (!node || !node->attached())
+ return; // cannot have generated content or if it can have, it will be handled during attaching
const CounterDirectiveMap* newCounterDirectives;
const CounterDirectiveMap* oldCounterDirectives;
if (oldStyle && (oldCounterDirectives = oldStyle->counterDirectives())) {
@@ -494,3 +663,27 @@ void RenderCounter::rendererStyleChanged(RenderObject* renderer, const RenderSty
}
} // namespace WebCore
+
+#ifndef NDEBUG
+
+void showCounterRendererTree(const WebCore::RenderObject* renderer, const char* counterName)
+{
+ if (!renderer)
+ return;
+ const WebCore::RenderObject* root = renderer;
+ while (root->parent())
+ root = root->parent();
+
+ AtomicString identifier(counterName);
+ for (const WebCore::RenderObject* current = root; current; current = current->nextInPreOrder()) {
+ fprintf(stderr, "%c", (current == renderer) ? '*' : ' ');
+ for (const WebCore::RenderObject* parent = current; parent && parent != root; parent = parent->parent())
+ fprintf(stderr, " ");
+ fprintf(stderr, "%p N:%p P:%p PS:%p NS:%p C:%p\n",
+ current, current->node(), current->parent(), current->previousSibling(),
+ current->nextSibling(), current->m_hasCounterNodeMap?
+ counterName ? WebCore::counterMaps().get(current)->get(identifier.impl()).get() : (WebCore::CounterNode*)1 : (WebCore::CounterNode*)0);
+ }
+}
+
+#endif // NDEBUG
diff --git a/Source/WebCore/rendering/RenderCounter.h b/Source/WebCore/rendering/RenderCounter.h
index 9373193..de0ee1b 100644
--- a/Source/WebCore/rendering/RenderCounter.h
+++ b/Source/WebCore/rendering/RenderCounter.h
@@ -67,4 +67,9 @@ void toRenderCounter(const RenderCounter*);
} // namespace WebCore
+#ifndef NDEBUG
+// Outside the WebCore namespace for ease of invocation from gdb.
+void showCounterRendererTree(const WebCore::RenderObject*, const char* counterName = 0);
+#endif
+
#endif // RenderCounter_h
diff --git a/Source/WebCore/rendering/RenderEmbeddedObject.cpp b/Source/WebCore/rendering/RenderEmbeddedObject.cpp
index 5486d51..cdd6c55 100644
--- a/Source/WebCore/rendering/RenderEmbeddedObject.cpp
+++ b/Source/WebCore/rendering/RenderEmbeddedObject.cpp
@@ -172,8 +172,9 @@ void RenderEmbeddedObject::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
context->setFillColor(m_missingPluginIndicatorIsPressed ? replacementTextRoundedRectPressedColor() : Color::white, style()->colorSpace());
context->fillPath(path);
+ const FontMetrics& fontMetrics = font.fontMetrics();
float labelX = roundf(replacementTextRect.location().x() + (replacementTextRect.size().width() - textWidth) / 2);
- float labelY = roundf(replacementTextRect.location().y() + (replacementTextRect.size().height() - font.height()) / 2 + font.ascent());
+ float labelY = roundf(replacementTextRect.location().y() + (replacementTextRect.size().height() - fontMetrics.height()) / 2 + fontMetrics.ascent());
context->setAlpha(m_missingPluginIndicatorIsPressed ? replacementTextPressedTextOpacity : replacementTextTextOpacity);
context->setFillColor(Color::black, style()->colorSpace());
context->drawBidiText(font, run, FloatPoint(labelX, labelY));
diff --git a/Source/WebCore/rendering/RenderFileUploadControl.cpp b/Source/WebCore/rendering/RenderFileUploadControl.cpp
index aec55a8..f72edad 100644
--- a/Source/WebCore/rendering/RenderFileUploadControl.cpp
+++ b/Source/WebCore/rendering/RenderFileUploadControl.cpp
@@ -216,7 +216,7 @@ void RenderFileUploadControl::paintObject(PaintInfo& paintInfo, int tx, int ty)
const String& displayedFilename = fileTextValue();
unsigned length = displayedFilename.length();
const UChar* string = displayedFilename.characters();
- TextRun textRun(string, length, false, 0, 0, !style()->isLeftToRightDirection(), style()->unicodeBidi() == Override);
+ TextRun textRun(string, length, false, 0, 0, TextRun::AllowTrailingExpansion, !style()->isLeftToRightDirection(), style()->unicodeBidi() == Override);
// Determine where the filename should be placed
int contentLeft = tx + borderLeft() + paddingLeft();
@@ -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, false, false, false));
+ float charWidth = style()->font().floatWidth(TextRun(&ch, 1, false, 0, 0, TextRun::AllowTrailingExpansion, false, false, false));
m_maxPreferredLogicalWidth = (int)ceilf(charWidth * defaultWidthNumChars);
}
@@ -297,6 +297,11 @@ void RenderFileUploadControl::computePreferredLogicalWidths()
setPreferredLogicalWidthsDirty(false);
}
+VisiblePosition RenderFileUploadControl::positionForPoint(const IntPoint&)
+{
+ return VisiblePosition();
+}
+
void RenderFileUploadControl::receiveDroppedFiles(const Vector<String>& paths)
{
if (allowsMultipleFiles())
diff --git a/Source/WebCore/rendering/RenderFileUploadControl.h b/Source/WebCore/rendering/RenderFileUploadControl.h
index c96800c..22974fe 100644
--- a/Source/WebCore/rendering/RenderFileUploadControl.h
+++ b/Source/WebCore/rendering/RenderFileUploadControl.h
@@ -28,7 +28,7 @@ namespace WebCore {
class Chrome;
class HTMLInputElement;
-
+
// Each RenderFileUploadControl contains a RenderButton (for opening the file chooser), and
// sufficient space to draw a file icon and filename. The RenderButton has a shadow node
// associated with it to receive click/hover events.
@@ -71,6 +71,8 @@ private:
Chrome* chrome() const;
int maxFilenameWidth() const;
PassRefPtr<RenderStyle> createButtonStyle(const RenderStyle* parentStyle) const;
+
+ virtual VisiblePosition positionForPoint(const IntPoint&);
RefPtr<HTMLInputElement> m_button;
RefPtr<FileChooser> m_fileChooser;
diff --git a/Source/WebCore/rendering/RenderFlexibleBox.cpp b/Source/WebCore/rendering/RenderFlexibleBox.cpp
index 5af5733..9ab3c3f 100644
--- a/Source/WebCore/rendering/RenderFlexibleBox.cpp
+++ b/Source/WebCore/rendering/RenderFlexibleBox.cpp
@@ -25,11 +25,11 @@
#include "config.h"
#include "RenderFlexibleBox.h"
-#include "CharacterNames.h"
#include "RenderLayer.h"
#include "RenderView.h"
#include "TextRun.h"
#include <wtf/StdLibExtras.h>
+#include <wtf/unicode/CharacterNames.h>
#ifdef ANDROID_LAYOUT
#include "Document.h"
@@ -288,7 +288,7 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren, int /*pageHeight FIXM
updateLayerTransform();
if (view()->layoutState()->pageLogicalHeight())
- setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(y()));
+ setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(logicalTop()));
// Update our scrollbars if we're overflow:auto/scroll/hidden now that we know if
// we overflow or not.
diff --git a/Source/WebCore/rendering/RenderFrameSet.cpp b/Source/WebCore/rendering/RenderFrameSet.cpp
index 06b2a7a..e4eee6e 100644
--- a/Source/WebCore/rendering/RenderFrameSet.cpp
+++ b/Source/WebCore/rendering/RenderFrameSet.cpp
@@ -96,8 +96,8 @@ void RenderFrameSet::paintColumnBorder(const PaintInfo& paintInfo, const IntRect
// Now stroke the edges but only if we have enough room to paint both edges with a little
// bit of the fill color showing through.
if (borderRect.width() >= 3) {
- context->fillRect(IntRect(borderRect.topLeft(), IntSize(1, height())), borderStartEdgeColor(), colorSpace);
- context->fillRect(IntRect(borderRect.topRight(), IntSize(1, height())), borderEndEdgeColor(), colorSpace);
+ context->fillRect(IntRect(borderRect.location(), IntSize(1, height())), borderStartEdgeColor(), colorSpace);
+ context->fillRect(IntRect(IntPoint(borderRect.maxX() - 1, borderRect.y()), IntSize(1, height())), borderEndEdgeColor(), colorSpace);
}
}
@@ -116,8 +116,8 @@ void RenderFrameSet::paintRowBorder(const PaintInfo& paintInfo, const IntRect& b
// Now stroke the edges but only if we have enough room to paint both edges with a little
// bit of the fill color showing through.
if (borderRect.height() >= 3) {
- context->fillRect(IntRect(borderRect.topLeft(), IntSize(width(), 1)), borderStartEdgeColor(), colorSpace);
- context->fillRect(IntRect(borderRect.bottomLeft(), IntSize(width(), 1)), borderEndEdgeColor(), colorSpace);
+ context->fillRect(IntRect(borderRect.location(), IntSize(width(), 1)), borderStartEdgeColor(), colorSpace);
+ context->fillRect(IntRect(IntPoint(borderRect.x(), borderRect.maxY() - 1), IntSize(width(), 1)), borderEndEdgeColor(), colorSpace);
}
}
diff --git a/Source/WebCore/rendering/RenderImage.cpp b/Source/WebCore/rendering/RenderImage.cpp
index 839328e..7369f4e 100644
--- a/Source/WebCore/rendering/RenderImage.cpp
+++ b/Source/WebCore/rendering/RenderImage.cpp
@@ -4,7 +4,7 @@
* (C) 2000 Dirk Mueller (mueller@kde.org)
* (C) 2006 Allan Sandfeld Jensen (kde@carewolf.com)
* (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -30,7 +30,6 @@
#include "Frame.h"
#include "GraphicsContext.h"
#include "HTMLAreaElement.h"
-#include "HTMLCollection.h"
#include "HTMLImageElement.h"
#include "HTMLInputElement.h"
#include "HTMLMapElement.h"
@@ -38,11 +37,9 @@
#include "HitTestResult.h"
#include "Page.h"
#include "RenderLayer.h"
-#include "RenderTheme.h"
#include "RenderView.h"
#include "SelectionController.h"
#include "TextRun.h"
-#include <wtf/CurrentTime.h>
#include <wtf/UnusedParam.h>
#ifdef ANDROID_LAYOUT
@@ -116,7 +113,7 @@ bool RenderImage::setImageSizeForAltText(CachedImage* newImage /* = 0 */)
// we have an alt and the user meant it (its not a text we invented)
if (!m_altText.isEmpty()) {
const Font& font = style()->font();
- IntSize textSize(min(font.width(TextRun(m_altText.characters(), m_altText.length())), maxAltTextWidth), min(font.height(), maxAltTextHeight));
+ IntSize textSize(min(font.width(TextRun(m_altText.characters(), m_altText.length())), maxAltTextWidth), min(font.fontMetrics().height(), maxAltTextHeight));
imageSize = imageSize.expandedTo(textSize);
}
@@ -277,7 +274,7 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
int usableWidth = cWidth - 2;
int usableHeight = cHeight - 2;
- Image* image = m_imageResource->image();
+ RefPtr<Image> image = m_imageResource->image();
if (m_imageResource->errorOccurred() && !image->isNull() && usableWidth >= image->width() && usableHeight >= image->height()) {
// Center the error image, accounting for border and padding.
@@ -289,7 +286,7 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
centerY = 0;
imageX = leftBorder + leftPad + centerX + 1;
imageY = topBorder + topPad + centerY + 1;
- context->drawImage(image, style()->colorSpace(), IntPoint(tx + imageX, ty + imageY));
+ context->drawImage(image.get(), style()->colorSpace(), IntPoint(tx + imageX, ty + imageY));
errorPictureDrawn = true;
}
@@ -299,21 +296,22 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
int ax = tx + leftBorder + leftPad;
int ay = ty + topBorder + topPad;
const Font& font = style()->font();
- int ascent = font.ascent();
+ const FontMetrics& fontMetrics = font.fontMetrics();
+ int ascent = fontMetrics.ascent();
// Only draw the alt text if it'll fit within the content box,
// and only if it fits above the error image.
TextRun textRun(text.characters(), text.length());
int textWidth = font.width(textRun);
if (errorPictureDrawn) {
- if (usableWidth >= textWidth && font.height() <= imageY)
- context->drawText(style()->font(), textRun, IntPoint(ax, ay + ascent));
- } else if (usableWidth >= textWidth && cHeight >= font.height())
- context->drawText(style()->font(), textRun, IntPoint(ax, ay + ascent));
+ if (usableWidth >= textWidth && fontMetrics.height() <= imageY)
+ context->drawText(font, textRun, IntPoint(ax, ay + ascent));
+ } else if (usableWidth >= textWidth && cHeight >= fontMetrics.height())
+ context->drawText(font, textRun, IntPoint(ax, ay + ascent));
}
}
} else if (m_imageResource->hasImage() && cWidth > 0 && cHeight > 0) {
- Image* img = m_imageResource->image(cWidth, cHeight);
+ RefPtr<Image> img = m_imageResource->image(cWidth, cHeight);
if (!img || img->isNull())
return;
@@ -333,60 +331,65 @@ void RenderImage::paint(PaintInfo& paintInfo, int tx, int ty)
RenderReplaced::paint(paintInfo, tx, ty);
if (paintInfo.phase == PaintPhaseOutline)
- paintFocusRing(paintInfo, style());
+ paintAreaElementFocusRing(paintInfo);
}
-void RenderImage::paintFocusRing(PaintInfo& paintInfo, const RenderStyle*)
+void RenderImage::paintAreaElementFocusRing(PaintInfo& paintInfo)
{
- // Don't draw focus rings if printing.
- if (document()->printing() || !frame()->selection()->isFocusedAndActive())
+ Document* document = this->document();
+
+ if (document->printing() || !document->frame()->selection()->isFocusedAndActive())
return;
if (paintInfo.context->paintingDisabled() && !paintInfo.context->updatingControlTints())
return;
- HTMLMapElement* mapElement = imageMap();
- if (!mapElement)
+ Node* focusedNode = document->focusedNode();
+ if (!focusedNode || !focusedNode->hasTagName(areaTag))
return;
-
- Document* document = mapElement->document();
- if (!document)
+
+ HTMLAreaElement* areaElement = static_cast<HTMLAreaElement*>(focusedNode);
+ if (areaElement->imageElement() != node())
return;
-
- Node* focusedNode = document->focusedNode();
- if (!focusedNode)
+
+ // Even if the theme handles focus ring drawing for entire elements, it won't do it for
+ // an area within an image, so we don't call RenderTheme::supportsFocusRing here.
+
+ Path path = areaElement->computePath(this);
+ if (path.isEmpty())
return;
-
- RefPtr<HTMLCollection> areas = mapElement->areas();
- unsigned numAreas = areas->length();
-
- // FIXME: Clip the paths to the image bounding box.
- for (unsigned k = 0; k < numAreas; ++k) {
- HTMLAreaElement* areaElement = static_cast<HTMLAreaElement*>(areas->item(k));
- if (focusedNode != areaElement)
- continue;
-
- RenderStyle* styleToUse = areaElement->computedStyle();
- if (theme()->supportsFocusRing(styleToUse))
- return; // The theme draws the focus ring.
- paintInfo.context->drawFocusRing(areaElement->getPath(this), styleToUse->outlineWidth(), styleToUse->outlineOffset(), styleToUse->visitedDependentColor(CSSPropertyOutlineColor));
- break;
- }
+
+ // FIXME: Do we need additional code to clip the path to the image's bounding box?
+
+ RenderStyle* areaElementStyle = areaElement->computedStyle();
+ paintInfo.context->drawFocusRing(path, areaElementStyle->outlineWidth(), areaElementStyle->outlineOffset(),
+ areaElementStyle->visitedDependentColor(CSSPropertyOutlineColor));
}
-
+
+void RenderImage::areaElementFocusChanged(HTMLAreaElement* element)
+{
+ ASSERT_UNUSED(element, element->imageElement() == node());
+
+ // It would be more efficient to only repaint the focus ring rectangle
+ // for the passed-in area element. That would require adding functions
+ // to the area element class.
+ repaint();
+}
+
void RenderImage::paintIntoRect(GraphicsContext* context, const IntRect& rect)
{
if (!m_imageResource->hasImage() || m_imageResource->errorOccurred() || rect.width() <= 0 || rect.height() <= 0)
return;
- Image* img = m_imageResource->image(rect.width(), rect.height());
+ RefPtr<Image> img = m_imageResource->image(rect.width(), rect.height());
if (!img || img->isNull())
return;
HTMLImageElement* imageElt = (node() && node()->hasTagName(imgTag)) ? static_cast<HTMLImageElement*>(node()) : 0;
CompositeOperator compositeOperator = imageElt ? imageElt->compositeOperator() : CompositeSourceOver;
- bool useLowQualityScaling = shouldPaintAtLowQuality(context, m_imageResource->image(), 0, rect.size());
- context->drawImage(m_imageResource->image(rect.width(), rect.height()), style()->colorSpace(), rect, compositeOperator, useLowQualityScaling);
+ Image* image = m_imageResource->image().get();
+ bool useLowQualityScaling = shouldPaintAtLowQuality(context, image, image, rect.size());
+ context->drawImage(m_imageResource->image(rect.width(), rect.height()).get(), style()->colorSpace(), rect, compositeOperator, useLowQualityScaling);
}
int RenderImage::minimumReplacedHeight() const
diff --git a/Source/WebCore/rendering/RenderImage.h b/Source/WebCore/rendering/RenderImage.h
index 16ae7ec..e3f743c 100644
--- a/Source/WebCore/rendering/RenderImage.h
+++ b/Source/WebCore/rendering/RenderImage.h
@@ -3,7 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2006 Allan Sandfeld Jensen (kde@carewolf.com)
* (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2011 Apple 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
@@ -30,6 +30,7 @@
namespace WebCore {
+class HTMLAreaElement;
class HTMLMapElement;
class RenderImage : public RenderReplaced {
@@ -48,6 +49,7 @@ public:
void updateAltText();
HTMLMapElement* imageMap() const;
+ void areaElementFocusChanged(HTMLAreaElement*);
void highQualityRepaintTimerFired(Timer<RenderImage>*);
@@ -57,7 +59,6 @@ protected:
virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
virtual void paintIntoRect(GraphicsContext*, const IntRect&);
- void paintFocusRing(PaintInfo&, const RenderStyle*);
virtual void paint(PaintInfo&, int tx, int ty);
bool isLogicalWidthSpecified() const;
@@ -91,6 +92,8 @@ private:
int calcAspectRatioLogicalWidth() const;
int calcAspectRatioLogicalHeight() const;
+ void paintAreaElementFocusRing(PaintInfo&);
+
// Text to display as long as the image isn't available.
String m_altText;
OwnPtr<RenderImageResource> m_imageResource;
diff --git a/Source/WebCore/rendering/RenderImageResource.h b/Source/WebCore/rendering/RenderImageResource.h
index a20c55a..f1ec75b 100644
--- a/Source/WebCore/rendering/RenderImageResource.h
+++ b/Source/WebCore/rendering/RenderImageResource.h
@@ -28,6 +28,7 @@
#include "CachedImage.h"
#include "CachedResourceHandle.h"
+#include "Image.h"
#include "StyleImage.h"
namespace WebCore {
@@ -53,7 +54,7 @@ public:
void resetAnimation();
- virtual Image* image(int /* width */ = 0, int /* height */ = 0) { return m_cachedImage ? m_cachedImage->image() : nullImage(); }
+ virtual PassRefPtr<Image> image(int /* width */ = 0, int /* height */ = 0) const { return m_cachedImage ? m_cachedImage->image() : nullImage(); }
virtual bool errorOccurred() const { return m_cachedImage && m_cachedImage->errorOccurred(); }
virtual void setImageContainerSize(const IntSize& size) const;
diff --git a/Source/WebCore/rendering/RenderImageResourceStyleImage.h b/Source/WebCore/rendering/RenderImageResourceStyleImage.h
index d91aaa8..278a82c 100644
--- a/Source/WebCore/rendering/RenderImageResourceStyleImage.h
+++ b/Source/WebCore/rendering/RenderImageResourceStyleImage.h
@@ -46,7 +46,7 @@ public:
virtual void shutdown();
virtual bool hasImage() const { return true; }
- virtual Image* image(int width = 0, int height = 0) { return m_styleImage->image(m_renderer, IntSize(width, height)); }
+ virtual PassRefPtr<Image> image(int width = 0, int height = 0) const { return m_styleImage->image(m_renderer, IntSize(width, height)); }
virtual bool errorOccurred() const { return m_styleImage->errorOccurred(); }
virtual void setImageContainerSize(const IntSize& size) const { m_styleImage->setImageContainerSize(size); }
diff --git a/Source/WebCore/rendering/RenderIndicator.cpp b/Source/WebCore/rendering/RenderIndicator.cpp
index b03dfba..8f34a40 100644
--- a/Source/WebCore/rendering/RenderIndicator.cpp
+++ b/Source/WebCore/rendering/RenderIndicator.cpp
@@ -25,12 +25,51 @@
#include "RenderIndicator.h"
#include "RenderTheme.h"
-#include "ShadowElement.h"
+#include "RenderView.h"
using namespace std;
namespace WebCore {
+RenderIndicatorPart::RenderIndicatorPart(Node* node)
+ : RenderBlock(node)
+ , m_originalVisibility(HIDDEN)
+{
+}
+
+RenderIndicatorPart::~RenderIndicatorPart()
+{
+}
+
+void RenderIndicatorPart::layout()
+{
+ RenderBox* parentRenderer = toRenderBox(parent());
+ IntRect oldRect = frameRect();
+ IntRect newRect = preferredFrameRect();
+
+ LayoutStateMaintainer statePusher(parentRenderer->view(), parentRenderer, parentRenderer->size(), parentRenderer->style()->isFlippedBlocksWritingMode());
+
+ if (oldRect.size() != newRect.size())
+ setChildNeedsLayout(true, false);
+ if (needsLayout())
+ RenderBlock::layout();
+ setFrameRect(newRect);
+
+ if (checkForRepaintDuringLayout())
+ repaintDuringLayoutIfMoved(oldRect);
+
+ statePusher.pop();
+ parentRenderer->addOverflowFromChild(this);
+ style()->setVisibility(shouldBeHidden() ? HIDDEN : originalVisibility());
+}
+
+void RenderIndicatorPart::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+ m_originalVisibility = style()->visibility();
+ RenderBlock::styleDidChange(diff, oldStyle);
+}
+
+
RenderIndicator::RenderIndicator(Node* node)
: RenderBlock(node)
{
diff --git a/Source/WebCore/rendering/RenderIndicator.h b/Source/WebCore/rendering/RenderIndicator.h
index 50d819d..7c2a346 100644
--- a/Source/WebCore/rendering/RenderIndicator.h
+++ b/Source/WebCore/rendering/RenderIndicator.h
@@ -26,6 +26,24 @@
namespace WebCore {
+class RenderIndicatorPart : public RenderBlock {
+public:
+ RenderIndicatorPart(Node*);
+ virtual ~RenderIndicatorPart();
+
+protected:
+ EVisibility originalVisibility() const { return m_originalVisibility; }
+ virtual IntRect preferredFrameRect() = 0;
+ virtual bool shouldBeHidden() = 0;
+private:
+ virtual void layout();
+ virtual bool requiresForcedStyleRecalcPropagation() const { return true; }
+ virtual bool canHaveChildren() const { return false; }
+ virtual void styleDidChange(StyleDifference, const RenderStyle*);
+
+ EVisibility m_originalVisibility;
+};
+
class RenderIndicator : public RenderBlock {
public:
RenderIndicator(Node*);
diff --git a/Source/WebCore/rendering/RenderInline.cpp b/Source/WebCore/rendering/RenderInline.cpp
index 7466ace..3768774 100644
--- a/Source/WebCore/rendering/RenderInline.cpp
+++ b/Source/WebCore/rendering/RenderInline.cpp
@@ -595,10 +595,10 @@ IntRect RenderInline::linesVisualOverflowBoundingBox() const
bool isHorizontal = style()->isHorizontalWritingMode();
- int x = isHorizontal ? logicalLeftSide : firstLineBox()->leftVisualOverflow();
- int y = isHorizontal ? firstLineBox()->topVisualOverflow() : logicalLeftSide;
- int width = isHorizontal ? logicalRightSide - logicalLeftSide : lastLineBox()->rightVisualOverflow() - firstLineBox()->leftVisualOverflow();
- int height = isHorizontal ? lastLineBox()->bottomVisualOverflow() - firstLineBox()->topVisualOverflow() : logicalRightSide - logicalLeftSide;
+ 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);
}
@@ -749,7 +749,7 @@ void RenderInline::computeRectForRepaint(RenderBoxModelObject* repaintContainer,
IntSize RenderInline::offsetFromContainer(RenderObject* container, const IntPoint& point) const
{
ASSERT(container == this->container());
-
+
IntSize offset;
if (isRelPositioned())
offset += relativePositionOffset();
@@ -783,6 +783,10 @@ void RenderInline::mapLocalToContainer(RenderBoxModelObject* repaintContainer, b
if (!o)
return;
+ IntPoint centerPoint = roundedIntPoint(transformState.mappedPoint());
+ if (o->isBox() && o->style()->isFlippedBlocksWritingMode())
+ transformState.move(toRenderBox(o)->flipForWritingModeIncludingColumns(roundedIntPoint(transformState.mappedPoint())) - centerPoint);
+
IntSize containerOffset = offsetFromContainer(o, roundedIntPoint(transformState.mappedPoint()));
bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
@@ -905,8 +909,8 @@ int RenderInline::lineHeight(bool firstLine, LineDirectionMode /*direction*/, Li
int RenderInline::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
{
- const Font& f = style(firstLine)->font();
- return f.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - f.height()) / 2;
+ const FontMetrics& fontMetrics = style(firstLine)->fontMetrics();
+ return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2;
}
IntSize RenderInline::relativePositionedInlineOffset(const RenderBox* child) const
@@ -1033,30 +1037,30 @@ void RenderInline::paintOutlineForLine(GraphicsContext* graphicsContext, int tx,
int t = ty + thisline.y() - offset;
int l = tx + thisline.x() - offset;
- int b = ty + thisline.bottom() + offset;
- int r = tx + thisline.right() + offset;
+ int b = ty + thisline.maxY() + offset;
+ int r = tx + thisline.maxX() + offset;
// left edge
drawLineForBoxSide(graphicsContext,
l - ow,
- t - (lastline.isEmpty() || thisline.x() < lastline.x() || (lastline.right() - 1) <= thisline.x() ? ow : 0),
+ t - (lastline.isEmpty() || thisline.x() < lastline.x() || (lastline.maxX() - 1) <= thisline.x() ? ow : 0),
l,
- b + (nextline.isEmpty() || thisline.x() <= nextline.x() || (nextline.right() - 1) <= thisline.x() ? ow : 0),
+ b + (nextline.isEmpty() || thisline.x() <= nextline.x() || (nextline.maxX() - 1) <= thisline.x() ? ow : 0),
BSLeft,
oc, os,
- (lastline.isEmpty() || thisline.x() < lastline.x() || (lastline.right() - 1) <= thisline.x() ? ow : -ow),
- (nextline.isEmpty() || thisline.x() <= nextline.x() || (nextline.right() - 1) <= thisline.x() ? ow : -ow));
+ (lastline.isEmpty() || thisline.x() < lastline.x() || (lastline.maxX() - 1) <= thisline.x() ? ow : -ow),
+ (nextline.isEmpty() || thisline.x() <= nextline.x() || (nextline.maxX() - 1) <= thisline.x() ? ow : -ow));
// right edge
drawLineForBoxSide(graphicsContext,
r,
- t - (lastline.isEmpty() || lastline.right() < thisline.right() || (thisline.right() - 1) <= lastline.x() ? ow : 0),
+ t - (lastline.isEmpty() || lastline.maxX() < thisline.maxX() || (thisline.maxX() - 1) <= lastline.x() ? ow : 0),
r + ow,
- b + (nextline.isEmpty() || nextline.right() <= thisline.right() || (thisline.right() - 1) <= nextline.x() ? ow : 0),
+ b + (nextline.isEmpty() || nextline.maxX() <= thisline.maxX() || (thisline.maxX() - 1) <= nextline.x() ? ow : 0),
BSRight,
oc, os,
- (lastline.isEmpty() || lastline.right() < thisline.right() || (thisline.right() - 1) <= lastline.x() ? ow : -ow),
- (nextline.isEmpty() || nextline.right() <= thisline.right() || (thisline.right() - 1) <= nextline.x() ? ow : -ow));
+ (lastline.isEmpty() || lastline.maxX() < thisline.maxX() || (thisline.maxX() - 1) <= lastline.x() ? ow : -ow),
+ (nextline.isEmpty() || nextline.maxX() <= thisline.maxX() || (thisline.maxX() - 1) <= nextline.x() ? ow : -ow));
// upper edge
if (thisline.x() < lastline.x())
drawLineForBoxSide(graphicsContext,
@@ -1068,14 +1072,14 @@ void RenderInline::paintOutlineForLine(GraphicsContext* graphicsContext, int tx,
ow,
(!lastline.isEmpty() && tx + lastline.x() + 1 < r + ow) ? -ow : ow);
- if (lastline.right() < thisline.right())
+ if (lastline.maxX() < thisline.maxX())
drawLineForBoxSide(graphicsContext,
- max(lastline.isEmpty() ? -1000000 : tx + lastline.right(), l - ow),
+ max(lastline.isEmpty() ? -1000000 : tx + lastline.maxX(), l - ow),
t - ow,
r + ow,
t ,
BSTop, oc, os,
- (!lastline.isEmpty() && l - ow < tx + lastline.right()) ? -ow : ow,
+ (!lastline.isEmpty() && l - ow < tx + lastline.maxX()) ? -ow : ow,
ow);
// lower edge
@@ -1089,14 +1093,14 @@ void RenderInline::paintOutlineForLine(GraphicsContext* graphicsContext, int tx,
ow,
(!nextline.isEmpty() && tx + nextline.x() + 1 < r + ow) ? -ow : ow);
- if (nextline.right() < thisline.right())
+ if (nextline.maxX() < thisline.maxX())
drawLineForBoxSide(graphicsContext,
- max(!nextline.isEmpty() ? tx + nextline.right() : -1000000, l - ow),
+ max(!nextline.isEmpty() ? tx + nextline.maxX() : -1000000, l - ow),
b,
r + ow,
b + ow,
BSBottom, oc, os,
- (!nextline.isEmpty() && l - ow < tx + nextline.right()) ? -ow : ow,
+ (!nextline.isEmpty() && l - ow < tx + nextline.maxX()) ? -ow : ow,
ow);
}
diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp
index 29a6fc9..e278c75 100644
--- a/Source/WebCore/rendering/RenderLayer.cpp
+++ b/Source/WebCore/rendering/RenderLayer.cpp
@@ -188,6 +188,8 @@ RenderLayer::RenderLayer(RenderBoxModelObject* renderer)
, m_scrollCorner(0)
, m_resizer(0)
{
+ ScrollableArea::setConstrainsScrollingToContentEdge(false);
+
if (!renderer->firstChild() && renderer->style()) {
m_visibleContentStatusDirty = false;
m_hasVisibleContent = renderer->style()->visibility() == VISIBLE;
@@ -960,7 +962,7 @@ static IntRect transparencyClipBox(const RenderLayer* l, const RenderLayer* root
TransformationMatrix transform;
transform.translate(x, y);
- transform = *l->transform() * transform;
+ transform = transform * *l->transform();
IntRect clipRect = l->boundingBox(l);
expandClipRectForDescendantsAndReflection(clipRect, l, l, paintBehavior);
@@ -1532,7 +1534,7 @@ IntRect RenderLayer::getRectToExpose(const IntRect &visibleRect, const IntRect &
scrollX = ScrollAlignment::getHiddenBehavior(alignX);
// If we're trying to align to the closest edge, and the exposeRect is further right
// than the visibleRect, and not bigger than the visible area, then align with the right.
- if (scrollX == alignToClosestEdge && exposeRect.right() > visibleRect.right() && exposeRect.width() < visibleRect.width())
+ if (scrollX == alignToClosestEdge && exposeRect.maxX() > visibleRect.maxX() && exposeRect.width() < visibleRect.width())
scrollX = alignRight;
// Given the X behavior, compute the X coordinate.
@@ -1540,7 +1542,7 @@ IntRect RenderLayer::getRectToExpose(const IntRect &visibleRect, const IntRect &
if (scrollX == noScroll)
x = visibleRect.x();
else if (scrollX == alignRight)
- x = exposeRect.right() - visibleRect.width();
+ x = exposeRect.maxX() - visibleRect.width();
else if (scrollX == alignCenter)
x = exposeRect.x() + (exposeRect.width() - visibleRect.width()) / 2;
else
@@ -1565,7 +1567,7 @@ IntRect RenderLayer::getRectToExpose(const IntRect &visibleRect, const IntRect &
scrollY = ScrollAlignment::getHiddenBehavior(alignY);
// If we're trying to align to the closest edge, and the exposeRect is further down
// than the visibleRect, and not bigger than the visible area, then align with the bottom.
- if (scrollY == alignToClosestEdge && exposeRect.bottom() > visibleRect.bottom() && exposeRect.height() < visibleRect.height())
+ if (scrollY == alignToClosestEdge && exposeRect.maxY() > visibleRect.maxY() && exposeRect.height() < visibleRect.height())
scrollY = alignBottom;
// Given the Y behavior, compute the Y coordinate.
@@ -1573,7 +1575,7 @@ IntRect RenderLayer::getRectToExpose(const IntRect &visibleRect, const IntRect &
if (scrollY == noScroll)
y = visibleRect.y();
else if (scrollY == alignBottom)
- y = exposeRect.bottom() - visibleRect.height();
+ y = exposeRect.maxY() - visibleRect.height();
else if (scrollY == alignCenter)
y = exposeRect.y() + (exposeRect.height() - visibleRect.height()) / 2;
else
@@ -1681,7 +1683,7 @@ int RenderLayer::scrollPosition(Scrollbar* scrollbar) const
if (scrollbar->orientation() == HorizontalScrollbar)
return scrollXOffset();
if (scrollbar->orientation() == VerticalScrollbar)
- return m_scrollY;
+ return scrollYOffset();
return 0;
}
@@ -1710,8 +1712,8 @@ static IntRect cornerRect(const RenderLayer* layer, const IntRect& bounds)
horizontalThickness = layer->verticalScrollbar()->width();
verticalThickness = layer->horizontalScrollbar()->height();
}
- return IntRect(bounds.right() - horizontalThickness - layer->renderer()->style()->borderRightWidth(),
- bounds.bottom() - verticalThickness - layer->renderer()->style()->borderBottomWidth(),
+ return IntRect(bounds.maxX() - horizontalThickness - layer->renderer()->style()->borderRightWidth(),
+ bounds.maxY() - verticalThickness - layer->renderer()->style()->borderBottomWidth(),
horizontalThickness, verticalThickness);
}
@@ -1789,6 +1791,21 @@ IntPoint RenderLayer::convertFromContainingViewToScrollbar(const Scrollbar* scro
return point;
}
+IntSize RenderLayer::contentsSize() const
+{
+ return IntSize(const_cast<RenderLayer*>(this)->scrollWidth(), const_cast<RenderLayer*>(this)->scrollHeight());
+}
+
+int RenderLayer::visibleHeight() const
+{
+ return m_height;
+}
+
+int RenderLayer::visibleWidth() const
+{
+ return m_width;
+}
+
IntSize RenderLayer::scrollbarOffset(const Scrollbar* scrollbar) const
{
RenderBox* box = renderBox();
@@ -1846,10 +1863,13 @@ void RenderLayer::setHasHorizontalScrollbar(bool hasScrollbar)
if (hasScrollbar == (m_hBar != 0))
return;
- if (hasScrollbar)
+ if (hasScrollbar) {
m_hBar = createScrollbar(HorizontalScrollbar);
- else
+ ScrollableArea::didAddHorizontalScrollbar(m_hBar.get());
+ } else {
+ ScrollableArea::willRemoveHorizontalScrollbar(m_hBar.get());
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)
@@ -1869,10 +1889,13 @@ void RenderLayer::setHasVerticalScrollbar(bool hasScrollbar)
if (hasScrollbar == (m_vBar != 0))
return;
- if (hasScrollbar)
+ if (hasScrollbar) {
m_vBar = createScrollbar(VerticalScrollbar);
- else
+ ScrollableArea::didAddVerticalScrollbar(m_vBar.get());
+ } else {
+ ScrollableArea::willRemoveVerticalScrollbar(m_vBar.get());
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)
@@ -1936,14 +1959,14 @@ void RenderLayer::positionOverflowControls(int tx, int ty)
IntRect scrollCorner(scrollCornerRect(this, borderBox));
IntRect absBounds(borderBox.x() + tx, borderBox.y() + ty, borderBox.width(), borderBox.height());
if (m_vBar)
- m_vBar->setFrameRect(IntRect(absBounds.right() - box->borderRight() - m_vBar->width(),
+ m_vBar->setFrameRect(IntRect(absBounds.maxX() - box->borderRight() - m_vBar->width(),
absBounds.y() + box->borderTop(),
m_vBar->width(),
absBounds.height() - (box->borderTop() + box->borderBottom()) - scrollCorner.height()));
if (m_hBar)
m_hBar->setFrameRect(IntRect(absBounds.x() + box->borderLeft(),
- absBounds.bottom() - box->borderBottom() - m_hBar->height(),
+ absBounds.maxY() - box->borderBottom() - m_hBar->height(),
absBounds.width() - (box->borderLeft() + box->borderRight()) - scrollCorner.width(),
m_hBar->height()));
@@ -2000,7 +2023,7 @@ int RenderLayer::overflowBottom() const
RenderBox* box = renderBox();
IntRect overflowRect(box->layoutOverflowRect());
box->flipForWritingMode(overflowRect);
- return overflowRect.bottom();
+ return overflowRect.maxY();
}
int RenderLayer::overflowLeft() const
@@ -2016,7 +2039,7 @@ int RenderLayer::overflowRight() const
RenderBox* box = renderBox();
IntRect overflowRect(box->layoutOverflowRect());
box->flipForWritingMode(overflowRect);
- return overflowRect.right();
+ return overflowRect.maxX();
}
void RenderLayer::computeScrollDimensions(bool* needHBar, bool* needVBar)
@@ -2078,8 +2101,8 @@ void RenderLayer::updateScrollInfoAfterLayout()
// Layout may cause us to be in an invalid scroll position. In this case we need
// to pull our scroll offsets back to the max (or push them up to the min).
int newX = max(0, min(scrollXOffset(), scrollWidth() - box->clientWidth()));
- int newY = max(0, min(m_scrollY, scrollHeight() - box->clientHeight()));
- if (newX != scrollXOffset() || newY != m_scrollY) {
+ int newY = max(0, min(scrollYOffset(), scrollHeight() - box->clientHeight()));
+ if (newX != scrollXOffset() || newY != scrollYOffset()) {
RenderView* view = renderer()->view();
ASSERT(view);
// scrollToOffset() may call updateLayerPositions(), which doesn't work
@@ -2163,7 +2186,10 @@ void RenderLayer::updateScrollInfoAfterLayout()
m_vBar->setProportion(clientHeight, m_scrollHeight);
}
+ RenderView* view = renderer()->view();
+ view->disableLayoutState();
scrollToOffset(scrollXOffset(), scrollYOffset());
+ view->enableLayoutState();
if (renderer()->node() && renderer()->document()->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
updateOverflowStatus(horizontalOverflow, verticalOverflow);
@@ -2256,7 +2282,7 @@ void RenderLayer::paintResizer(GraphicsContext* context, int tx, int ty, const I
// Paint the resizer control.
DEFINE_STATIC_LOCAL(RefPtr<Image>, resizeCornerImage, (Image::loadPlatformResource("textAreaResizeCorner")));
- IntPoint imagePoint(absRect.right() - resizeCornerImage->width(), absRect.bottom() - resizeCornerImage->height());
+ IntPoint imagePoint(absRect.maxX() - resizeCornerImage->width(), absRect.maxY() - resizeCornerImage->height());
context->drawImage(resizeCornerImage.get(), box->style()->colorSpace(), imagePoint);
// Draw a frame around the resizer (1px grey line) if there are any scrollbars present.
@@ -2634,13 +2660,18 @@ void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, RenderLaye
int layerY = 0;
columnBlock->layer()->convertToLayerCoords(rootLayer, layerX, layerY);
+ bool isHorizontal = columnBlock->style()->isHorizontalWritingMode();
+
ColumnInfo* colInfo = columnBlock->columnInfo();
unsigned colCount = columnBlock->columnCount(colInfo);
- int currYOffset = 0;
+ int currLogicalTopOffset = 0;
for (unsigned i = 0; i < colCount; i++) {
// For each rect, we clip to the rect, and then we adjust our coords.
IntRect colRect = columnBlock->columnRectAt(colInfo, i);
- int currXOffset = colRect.x() - (columnBlock->borderLeft() + columnBlock->paddingLeft());
+ columnBlock->flipForWritingMode(colRect);
+ int logicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - columnBlock->logicalLeftOffsetForContent();
+ IntSize offset = isHorizontal ? IntSize(logicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, logicalLeftOffset);
+
colRect.move(layerX, layerY);
IntRect localDirtyRect(paintDirtyRect);
@@ -2660,7 +2691,7 @@ void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, RenderLaye
if (oldHasTransform)
oldTransform = *childLayer->transform();
TransformationMatrix newTransform(oldTransform);
- newTransform.translateRight(currXOffset, currYOffset);
+ newTransform.translateRight(offset.width(), offset.height());
childLayer->m_transform.set(new TransformationMatrix(newTransform));
childLayer->paintLayer(rootLayer, context, localDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, paintFlags);
@@ -2675,7 +2706,7 @@ void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, RenderLaye
int childY = 0;
columnLayers[colIndex - 1]->convertToLayerCoords(rootLayer, childX, childY);
TransformationMatrix transform;
- transform.translateRight(childX + currXOffset, childY + currYOffset);
+ transform.translateRight(childX + offset.width(), childY + offset.height());
// Apply the transform.
context->concatCTM(transform.toAffineTransform());
@@ -2690,7 +2721,11 @@ void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, RenderLaye
}
// Move to the next position.
- currYOffset -= colRect.height();
+ int blockDelta = isHorizontal ? colRect.height() : colRect.width();
+ if (columnBlock->style()->isFlippedBlocksWritingMode())
+ currLogicalTopOffset += blockDelta;
+ else
+ currLogicalTopOffset -= blockDelta;
}
}
@@ -3111,21 +3146,35 @@ RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, Rend
int colCount = columnBlock->columnCount(colInfo);
// We have to go backwards from the last column to the first.
- int left = columnBlock->borderLeft() + columnBlock->paddingLeft();
- int currYOffset = 0;
+ bool isHorizontal = columnBlock->style()->isHorizontalWritingMode();
+ int logicalLeft = columnBlock->logicalLeftOffsetForContent();
+ int currLogicalTopOffset = 0;
int i;
- for (i = 0; i < colCount; i++)
- currYOffset -= columnBlock->columnRectAt(colInfo, i).height();
+ for (i = 0; i < colCount; i++) {
+ IntRect colRect = columnBlock->columnRectAt(colInfo, i);
+ int blockDelta = (isHorizontal ? colRect.height() : colRect.width());
+ if (columnBlock->style()->isFlippedBlocksWritingMode())
+ currLogicalTopOffset += blockDelta;
+ else
+ currLogicalTopOffset -= blockDelta;
+ }
for (i = colCount - 1; i >= 0; i--) {
// For each rect, we clip to the rect, and then we adjust our coords.
IntRect colRect = columnBlock->columnRectAt(colInfo, i);
- int currXOffset = colRect.x() - left;
- currYOffset += colRect.height();
+ columnBlock->flipForWritingMode(colRect);
+ int currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft;
+ int blockDelta = (isHorizontal ? colRect.height() : colRect.width());
+ if (columnBlock->style()->isFlippedBlocksWritingMode())
+ currLogicalTopOffset -= blockDelta;
+ else
+ currLogicalTopOffset += blockDelta;
colRect.move(layerX, layerY);
IntRect localClipRect(hitTestRect);
localClipRect.intersect(colRect);
+ IntSize offset = isHorizontal ? IntSize(currLogicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, currLogicalLeftOffset);
+
if (!localClipRect.isEmpty() && localClipRect.intersects(result.rectForPoint(hitTestPoint))) {
RenderLayer* hitLayer = 0;
if (!columnIndex) {
@@ -3135,7 +3184,7 @@ RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, Rend
if (oldHasTransform)
oldTransform = *childLayer->transform();
TransformationMatrix newTransform(oldTransform);
- newTransform.translateRight(currXOffset, currYOffset);
+ newTransform.translateRight(offset.width(), offset.height());
childLayer->m_transform.set(new TransformationMatrix(newTransform));
hitLayer = childLayer->hitTestLayer(rootLayer, columnLayers[0], request, result, localClipRect, hitTestPoint, false, transformState, zOffset);
@@ -3148,7 +3197,7 @@ RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, Rend
// This involves subtracting out the position of the layer in our current coordinate space.
RenderLayer* nextLayer = columnLayers[columnIndex - 1];
RefPtr<HitTestingTransformState> newTransformState = nextLayer->createLocalTransformState(rootLayer, nextLayer, localClipRect, hitTestPoint, transformState);
- newTransformState->translate(currXOffset, currYOffset, HitTestingTransformState::AccumulateTransform);
+ newTransformState->translate(offset.width(), offset.height(), HitTestingTransformState::AccumulateTransform);
IntPoint localPoint = roundedIntPoint(newTransformState->mappedPoint());
IntRect localHitTestRect = newTransformState->mappedQuad().enclosingBoundingBox();
newTransformState->flatten();
@@ -3437,19 +3486,9 @@ IntRect RenderLayer::localBoundingBox() const
// as part of our bounding box. We do this because we are the responsible layer for both hit testing and painting those
// floats.
IntRect result;
- if (renderer()->isRenderInline()) {
- // Go from our first line box to our last line box.
- RenderInline* inlineFlow = toRenderInline(renderer());
- InlineFlowBox* firstBox = inlineFlow->firstLineBox();
- if (!firstBox)
- return result;
- int top = firstBox->topVisualOverflow();
- int bottom = inlineFlow->lastLineBox()->bottomVisualOverflow();
- int left = firstBox->x();
- for (InlineFlowBox* curr = firstBox->nextLineBox(); curr; curr = curr->nextLineBox())
- left = min(left, curr->x());
- result = IntRect(left, top, width(), bottom - top);
- } else if (renderer()->isTableRow()) {
+ if (renderer()->isRenderInline())
+ result = toRenderInline(renderer())->linesVisualOverflowBoundingBox();
+ else if (renderer()->isTableRow()) {
// Our bounding box is just the union of all of our cells' border/overflow rects.
for (RenderObject* child = renderer()->firstChild(); child; child = child->nextSibling()) {
if (child->isTableCell()) {
@@ -3485,7 +3524,10 @@ IntRect RenderLayer::localBoundingBox() const
IntRect RenderLayer::boundingBox(const RenderLayer* ancestorLayer) const
{
IntRect result = localBoundingBox();
-
+ if (renderer()->isBox())
+ renderBox()->flipForWritingMode(result);
+ else
+ renderer()->containingBlock()->flipForWritingMode(result);
int deltaX = 0, deltaY = 0;
convertToLayerCoords(ancestorLayer, deltaX, deltaY);
result.move(deltaX, deltaY);
@@ -3538,6 +3580,26 @@ 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 57cb4de..66281ce 100644
--- a/Source/WebCore/rendering/RenderLayer.h
+++ b/Source/WebCore/rendering/RenderLayer.h
@@ -483,6 +483,7 @@ public:
bool isComposited() const { return false; }
bool hasCompositedMask() const { return false; }
#endif
+ virtual bool scrollbarWillRenderIntoCompositingLayer() const;
bool paintsWithTransparency(PaintBehavior paintBehavior) const
{
@@ -495,7 +496,6 @@ private:
// The normal operator new is disallowed on all render objects.
void* operator new(size_t) throw();
-private:
void setNextSibling(RenderLayer* next) { m_next = next; }
void setPreviousSibling(RenderLayer* prev) { m_previous = prev; }
void setParent(RenderLayer* parent);
@@ -571,6 +571,9 @@ private:
virtual IntRect convertFromContainingViewToScrollbar(const Scrollbar*, const IntRect&) const;
virtual IntPoint convertFromScrollbarToContainingView(const Scrollbar*, const IntPoint&) const;
virtual IntPoint convertFromContainingViewToScrollbar(const Scrollbar*, const IntPoint&) const;
+ virtual IntSize contentsSize() const;
+ virtual int visibleHeight() const;
+ virtual int visibleWidth() const;
// NOTE: This should only be called by the overriden setScrollOffset from ScrollableArea.
void scrollTo(int x, int y);
@@ -624,7 +627,6 @@ private:
void updateContentsScale(float);
-private:
friend class RenderLayerBacking;
friend class RenderLayerCompositor;
friend class RenderBoxModelObject;
diff --git a/Source/WebCore/rendering/RenderLayerBacking.cpp b/Source/WebCore/rendering/RenderLayerBacking.cpp
index 8001c42..d0a36c7 100644
--- a/Source/WebCore/rendering/RenderLayerBacking.cpp
+++ b/Source/WebCore/rendering/RenderLayerBacking.cpp
@@ -70,7 +70,7 @@ static IntRect clipBox(RenderBox* renderer);
static inline bool isAcceleratedCanvas(RenderObject* renderer)
{
-#if ENABLE(3D_CANVAS) || ENABLE(ACCELERATED_2D_CANVAS)
+#if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
if (renderer->isCanvas()) {
HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
if (CanvasRenderingContext* context = canvas->renderingContext())
@@ -287,7 +287,7 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration()
m_graphicsLayer->setContentsToMedia(mediaElement->platformLayer());
}
#endif
-#if ENABLE(3D_CANVAS) || ENABLE(ACCELERATED_2D_CANVAS)
+#if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
else if (isAcceleratedCanvas(renderer)) {
HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
if (CanvasRenderingContext* context = canvas->renderingContext())
@@ -803,7 +803,7 @@ bool RenderLayerBacking::containsPaintedContent() const
return hasBoxDecorationsOrBackground(renderer());
#endif
#if PLATFORM(MAC) && PLATFORM(CA) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
-#elif ENABLE(3D_CANVAS) || ENABLE(ACCELERATED_2D_CANVAS)
+#elif ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
if (isAcceleratedCanvas(renderer()))
return hasBoxDecorationsOrBackground(renderer());
#endif
@@ -843,7 +843,7 @@ void RenderLayerBacking::contentChanged(RenderLayer::ContentChangeType changeTyp
updateAfterLayout(CompositingChildren, isUpdateRoot);
}
-#if ENABLE(3D_CANVAS) || ENABLE(ACCELERATED_2D_CANVAS)
+#if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
if ((changeType == RenderLayer::CanvasChanged) && isAcceleratedCanvas(renderer())) {
m_graphicsLayer->setContentsNeedsDisplay();
return;
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp
index 9a5dda7..f9c0f32 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp
@@ -1483,7 +1483,7 @@ void RenderLayerCompositor::ensureRootPlatformLayer()
#ifndef NDEBUG
m_rootPlatformLayer->setName("Root platform");
#endif
- m_rootPlatformLayer->setSize(FloatSize(m_renderView->rightLayoutOverflow(), m_renderView->bottomLayoutOverflow()));
+ m_rootPlatformLayer->setSize(FloatSize(m_renderView->maxXLayoutOverflow(), m_renderView->maxYLayoutOverflow()));
m_rootPlatformLayer->setPosition(FloatPoint());
// Need to clip to prevent transformed content showing outside this frame
diff --git a/Source/WebCore/rendering/RenderLineBoxList.cpp b/Source/WebCore/rendering/RenderLineBoxList.cpp
index 1488ecc..274905e 100644
--- a/Source/WebCore/rendering/RenderLineBoxList.cpp
+++ b/Source/WebCore/rendering/RenderLineBoxList.cpp
@@ -160,11 +160,11 @@ bool RenderLineBoxList::rangeIntersectsRect(RenderBoxModelObject* renderer, int
if (renderer->style()->isHorizontalWritingMode()) {
physicalStart += ty;
- if (physicalStart >= rect.bottom() || physicalStart + physicalExtent <= rect.y())
+ if (physicalStart >= rect.maxY() || physicalStart + physicalExtent <= rect.y())
return false;
} else {
physicalStart += tx;
- if (physicalStart >= rect.right() || physicalStart + physicalExtent <= rect.x())
+ if (physicalStart >= rect.maxX() || physicalStart + physicalExtent <= rect.x())
return false;
}
@@ -231,19 +231,19 @@ void RenderLineBoxList::paint(RenderBoxModelObject* renderer, PaintInfo& paintIn
// FIXME: This is the deprecated pagination model that is still needed
// for embedded views inside AppKit. AppKit is incapable of paginating vertical
// text pages, so we don't have to deal with vertical lines at all here.
- int topForPaginationCheck = curr->topVisualOverflow();
- int bottomForPaginationCheck = curr->bottomVisualOverflow();
+ int topForPaginationCheck = curr->minYVisualOverflow();
+ int bottomForPaginationCheck = curr->maxYVisualOverflow();
if (!curr->parent()) {
// We're a root box. Use lineTop and lineBottom as well here.
topForPaginationCheck = min(topForPaginationCheck, curr->root()->lineTop());
bottomForPaginationCheck = max(bottomForPaginationCheck, curr->root()->lineBottom());
}
if (bottomForPaginationCheck - topForPaginationCheck <= v->printRect().height()) {
- if (ty + bottomForPaginationCheck > v->printRect().bottom()) {
+ if (ty + bottomForPaginationCheck > v->printRect().maxY()) {
if (RootInlineBox* nextRootBox = curr->root()->nextRootBox())
- bottomForPaginationCheck = min(bottomForPaginationCheck, min(nextRootBox->topVisualOverflow(), nextRootBox->lineTop()));
+ bottomForPaginationCheck = min(bottomForPaginationCheck, min(nextRootBox->minYVisualOverflow(), nextRootBox->lineTop()));
}
- if (ty + bottomForPaginationCheck > v->printRect().bottom()) {
+ if (ty + bottomForPaginationCheck > v->printRect().maxY()) {
if (ty + topForPaginationCheck < v->truncatedAt())
v->setBestTruncatedAt(ty + topForPaginationCheck, renderer);
// If we were able to truncate, don't paint.
diff --git a/Source/WebCore/rendering/RenderListBox.cpp b/Source/WebCore/rendering/RenderListBox.cpp
index 90f13da..13e8e58 100644
--- a/Source/WebCore/rendering/RenderListBox.cpp
+++ b/Source/WebCore/rendering/RenderListBox.cpp
@@ -1,7 +1,5 @@
/*
- * This file is part of the select element renderer in WebCore.
- *
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
* 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* Redistribution and use in source and binary forms, with or without
@@ -48,6 +46,7 @@
#include "OptionElement.h"
#include "Page.h"
#include "PaintInfo.h"
+#include "RenderLayer.h"
#include "RenderScrollbar.h"
#include "RenderTheme.h"
#include "RenderView.h"
@@ -112,7 +111,7 @@ void RenderListBox::updateFromElement()
}
if (!text.isEmpty()) {
- float textWidth = itemFont.floatWidth(TextRun(text.impl(), 0, 0, 0, false, false, false, false));
+ float textWidth = itemFont.floatWidth(TextRun(text.impl(), false, 0, 0, TextRun::AllowTrailingExpansion, false, false, false, false));
width = max(width, textWidth);
}
}
@@ -142,8 +141,11 @@ void RenderListBox::selectionChanged()
void RenderListBox::layout()
{
RenderBlock::layout();
- if (m_scrollToRevealSelectionAfterLayout)
+ if (m_scrollToRevealSelectionAfterLayout) {
+ view()->disableLayoutState();
scrollToRevealSelection();
+ view()->enableLayoutState();
+ }
}
void RenderListBox::scrollToRevealSelection()
@@ -303,7 +305,7 @@ void RenderListBox::paintItemForeground(PaintInfo& paintInfo, int tx, int ty, in
// Determine where the item text should be placed
IntRect r = itemBoundingBoxRect(tx, ty, listIndex);
- r.move(optionsSpacingHorizontal, style()->font().ascent());
+ r.move(optionsSpacingHorizontal, style()->fontMetrics().ascent());
RenderStyle* itemStyle = element->renderStyle();
if (!itemStyle)
@@ -331,7 +333,7 @@ void RenderListBox::paintItemForeground(PaintInfo& paintInfo, int tx, int ty, in
unsigned length = itemText.length();
const UChar* string = itemText.characters();
- TextRun textRun(string, length, 0, 0, 0, !itemStyle->isLeftToRightDirection(), itemStyle->unicodeBidi() == Override, false, false);
+ TextRun textRun(string, length, false, 0, 0, TextRun::AllowTrailingExpansion, !itemStyle->isLeftToRightDirection(), itemStyle->unicodeBidi() == Override, false, false);
// Draw the item text
if (itemStyle->visibility() != HIDDEN)
@@ -550,7 +552,7 @@ void RenderListBox::scrollTo(int newOffset)
int RenderListBox::itemHeight() const
{
- return style()->font().height() + rowSpacing;
+ return style()->fontMetrics().height() + rowSpacing;
}
int RenderListBox::verticalScrollbarWidth() const
@@ -696,6 +698,37 @@ IntPoint RenderListBox::convertFromContainingViewToScrollbar(const Scrollbar* sc
return point;
}
+IntSize RenderListBox::contentsSize() const
+{
+ return IntSize(scrollWidth(), scrollHeight());
+}
+
+int RenderListBox::visibleHeight() const
+{
+ return height();
+}
+
+int RenderListBox::visibleWidth() const
+{
+ return width();
+}
+
+IntPoint RenderListBox::currentMousePosition() const
+{
+ RenderView* view = this->view();
+ if (!view)
+ return IntPoint();
+ 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;
@@ -723,10 +756,13 @@ void RenderListBox::setHasVerticalScrollbar(bool hasScrollbar)
if (hasScrollbar == (m_vBar != 0))
return;
- if (hasScrollbar)
+ if (hasScrollbar) {
m_vBar = createScrollbar();
- else
+ ScrollableArea::didAddVerticalScrollbar(m_vBar.get());
+ } else {
+ ScrollableArea::willRemoveVerticalScrollbar(m_vBar.get());
destroyScrollbar();
+ }
if (m_vBar)
m_vBar->styleChanged();
diff --git a/Source/WebCore/rendering/RenderListBox.h b/Source/WebCore/rendering/RenderListBox.h
index 1ba2b94..1eb2036 100644
--- a/Source/WebCore/rendering/RenderListBox.h
+++ b/Source/WebCore/rendering/RenderListBox.h
@@ -106,6 +106,11 @@ private:
virtual IntPoint convertFromScrollbarToContainingView(const Scrollbar*, const IntPoint&) const;
virtual IntPoint convertFromContainingViewToScrollbar(const Scrollbar*, const IntPoint&) const;
virtual Scrollbar* verticalScrollbar() const { return m_vBar.get(); }
+ virtual IntSize contentsSize() const;
+ 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/RenderListItem.cpp b/Source/WebCore/rendering/RenderListItem.cpp
index 65606f3..5cfb522 100644
--- a/Source/WebCore/rendering/RenderListItem.cpp
+++ b/Source/WebCore/rendering/RenderListItem.cpp
@@ -297,12 +297,12 @@ void RenderListItem::positionListMarker()
for (InlineFlowBox* box = m_marker->inlineBoxWrapper()->parent(); box; box = box->parent()) {
IntRect newLogicalVisualOverflowRect = box->logicalVisualOverflowRect();
IntRect newLogicalLayoutOverflowRect = box->logicalLayoutOverflowRect();
- if (markerLogicalLeft + m_marker->logicalWidth() > newLogicalVisualOverflowRect.right() && !hitSelfPaintingLayer) {
+ if (markerLogicalLeft + m_marker->logicalWidth() > newLogicalVisualOverflowRect.maxX() && !hitSelfPaintingLayer) {
newLogicalVisualOverflowRect.setWidth(markerLogicalLeft + m_marker->logicalWidth() - box->logicalLeftVisualOverflow());
if (box == root)
adjustOverflow = true;
}
- if (markerLogicalLeft + m_marker->logicalWidth() > newLogicalLayoutOverflowRect.right()) {
+ if (markerLogicalLeft + m_marker->logicalWidth() > newLogicalLayoutOverflowRect.maxX()) {
newLogicalLayoutOverflowRect.setWidth(markerLogicalLeft + m_marker->logicalWidth() - box->logicalLeftLayoutOverflow());
if (box == root)
adjustOverflow = true;
diff --git a/Source/WebCore/rendering/RenderListMarker.cpp b/Source/WebCore/rendering/RenderListMarker.cpp
index cd41c75..c1c7245 100644
--- a/Source/WebCore/rendering/RenderListMarker.cpp
+++ b/Source/WebCore/rendering/RenderListMarker.cpp
@@ -26,13 +26,13 @@
#include "RenderListMarker.h"
#include "CachedImage.h"
-#include "CharacterNames.h"
#include "Document.h"
#include "GraphicsContext.h"
#include "RenderLayer.h"
#include "RenderListItem.h"
#include "RenderView.h"
#include "TextRun.h"
+#include <wtf/unicode/CharacterNames.h>
using namespace std;
using namespace WTF;
@@ -1130,7 +1130,7 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
if (style()->highlight() != nullAtom && !paintInfo.context->paintingDisabled())
paintCustomHighlight(tx, ty, style()->highlight(), true);
#endif
- context->drawImage(m_image->image(this, marker.size()), style()->colorSpace(), marker);
+ context->drawImage(m_image->image(this, marker.size()).get(), style()->colorSpace(), marker);
if (selectionState() != SelectionNone) {
IntRect selRect = localSelectionRect();
selRect.move(boxOrigin.x(), boxOrigin.y());
@@ -1260,12 +1260,12 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
marker = marker.transposedRect();
marker.move(box.x(), box.y() - logicalHeight());
context->save();
- context->translate(marker.x(), marker.bottom());
+ context->translate(marker.x(), marker.maxY());
context->rotate(static_cast<float>(deg2rad(90.)));
- context->translate(-marker.x(), -marker.bottom());
+ context->translate(-marker.x(), -marker.maxY());
}
- IntPoint textOrigin = IntPoint(marker.x(), marker.y() + style()->font().ascent());
+ IntPoint textOrigin = IntPoint(marker.x(), marker.y() + style()->fontMetrics().ascent());
if (type == Asterisks || type == Footnotes)
context->drawText(style()->font(), textRun, textOrigin);
@@ -1311,7 +1311,7 @@ void RenderListMarker::layout()
setHeight(m_image->imageSize(this, style()->effectiveZoom()).height());
} else {
setLogicalWidth(minPreferredLogicalWidth());
- setLogicalHeight(style()->font().height());
+ setLogicalHeight(style()->fontMetrics().height());
}
setMarginStart(0);
@@ -1346,11 +1346,12 @@ void RenderListMarker::computePreferredLogicalWidths()
m_text = "";
const Font& font = style()->font();
+ const FontMetrics& fontMetrics = font.fontMetrics();
if (isImage()) {
// FIXME: This is a somewhat arbitrary width. Generated images for markers really won't become particularly useful
// until we support the CSS3 marker pseudoclass to allow control over the width and height of the marker box.
- int bulletWidth = font.ascent() / 2;
+ int bulletWidth = fontMetrics.ascent() / 2;
m_image->setImageContainerSize(IntSize(bulletWidth, bulletWidth));
IntSize imageSize = m_image->imageSize(this, style()->effectiveZoom());
m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = style()->isHorizontalWritingMode() ? imageSize.width() : imageSize.height();
@@ -1373,7 +1374,7 @@ void RenderListMarker::computePreferredLogicalWidths()
case Disc:
case Square:
m_text = listMarkerText(type, 0); // value is ignored for these types
- logicalWidth = (font.ascent() * 2 / 3 + 1) / 2 + 2;
+ logicalWidth = (fontMetrics.ascent() * 2 / 3 + 1) / 2 + 2;
break;
case Afar:
case Amharic:
@@ -1472,7 +1473,7 @@ void RenderListMarker::computePreferredLogicalWidths()
void RenderListMarker::updateMargins()
{
- const Font& font = style()->font();
+ const FontMetrics& fontMetrics = style()->fontMetrics();
int marginStart = 0;
int marginEnd = 0;
@@ -1485,7 +1486,7 @@ void RenderListMarker::updateMargins()
case Circle:
case Square:
marginStart = -1;
- marginEnd = font.ascent() - minPreferredLogicalWidth() + 1;
+ marginEnd = fontMetrics.ascent() - minPreferredLogicalWidth() + 1;
break;
default:
break;
@@ -1495,7 +1496,7 @@ void RenderListMarker::updateMargins()
if (isImage())
marginStart = -minPreferredLogicalWidth() - cMarkerPadding;
else {
- int offset = font.ascent() * 2 / 3;
+ int offset = fontMetrics.ascent() * 2 / 3;
switch (style()->listStyleType()) {
case Disc:
case Circle:
@@ -1513,7 +1514,7 @@ void RenderListMarker::updateMargins()
if (isImage())
marginEnd = cMarkerPadding;
else {
- int offset = font.ascent() * 2 / 3;
+ int offset = fontMetrics.ascent() * 2 / 3;
switch (style()->listStyleType()) {
case Disc:
case Circle:
@@ -1584,15 +1585,15 @@ IntRect RenderListMarker::getRelativeMarkerRect()
case Asterisks:
case Footnotes: {
const Font& font = style()->font();
- relativeRect = IntRect(0, 0, font.width(m_text), font.height());
+ relativeRect = IntRect(0, 0, font.width(m_text), font.fontMetrics().height());
break;
}
case Disc:
case Circle:
case Square: {
// FIXME: Are these particular rounding rules necessary?
- const Font& font = style()->font();
- int ascent = font.ascent();
+ const FontMetrics& fontMetrics = style()->fontMetrics();
+ int ascent = fontMetrics.ascent();
int bulletWidth = (ascent * 2 / 3 + 1) / 2;
relativeRect = IntRect(1, 3 * (ascent - ascent * 2 / 3) / 2, bulletWidth, bulletWidth);
break;
@@ -1680,7 +1681,7 @@ IntRect RenderListMarker::getRelativeMarkerRect()
int itemWidth = font.width(m_text);
UChar suffixSpace[2] = { listMarkerSuffix(type, m_listItem->value()), ' ' };
int suffixSpaceWidth = font.width(TextRun(suffixSpace, 2));
- relativeRect = IntRect(0, 0, itemWidth + suffixSpaceWidth, font.height());
+ relativeRect = IntRect(0, 0, itemWidth + suffixSpaceWidth, font.fontMetrics().height());
}
if (!style()->isHorizontalWritingMode()) {
diff --git a/Source/WebCore/rendering/RenderMarquee.cpp b/Source/WebCore/rendering/RenderMarquee.cpp
index 9b58118..6f59340 100644
--- a/Source/WebCore/rendering/RenderMarquee.cpp
+++ b/Source/WebCore/rendering/RenderMarquee.cpp
@@ -116,7 +116,7 @@ int RenderMarquee::computePosition(EMarqueeDirection dir, bool stopAtContentEdge
if (isHorizontal()) {
bool ltr = s->isLeftToRightDirection();
int clientWidth = box->clientWidth();
- int contentWidth = ltr ? box->rightLayoutOverflow() : box->leftLayoutOverflow();
+ int contentWidth = ltr ? box->maxXLayoutOverflow() : box->minXLayoutOverflow();
if (ltr)
contentWidth += (box->paddingRight() - box->borderLeft());
else {
@@ -137,7 +137,7 @@ int RenderMarquee::computePosition(EMarqueeDirection dir, bool stopAtContentEdge
}
}
else {
- int contentHeight = box->bottomLayoutOverflow() - box->borderTop() + box->paddingBottom();
+ int contentHeight = box->maxYLayoutOverflow() - box->borderTop() + box->paddingBottom();
int clientHeight = box->clientHeight();
if (dir == MUP) {
if (stopAtContentEdge)
diff --git a/Source/WebCore/rendering/RenderMedia.cpp b/Source/WebCore/rendering/RenderMedia.cpp
index 0b913ee..d10c593 100644
--- a/Source/WebCore/rendering/RenderMedia.cpp
+++ b/Source/WebCore/rendering/RenderMedia.cpp
@@ -28,10 +28,9 @@
#if ENABLE(VIDEO)
#include "RenderMedia.h"
-#include "EventNames.h"
-#include "FloatConversion.h"
-#include "HTMLNames.h"
+#include "HTMLMediaElement.h"
#include "MediaControlElements.h"
+<<<<<<< HEAD
#include "MouseEvent.h"
#include "Page.h"
#include "RenderLayer.h"
@@ -45,16 +44,15 @@
#endif
using namespace std;
+=======
+#include "MediaControls.h"
+>>>>>>> webkit.org at r78450
namespace WebCore {
-using namespace HTMLNames;
-
-static const double cTimeUpdateRepeatDelay = 0.2;
-static const double cOpacityAnimationRepeatDelay = 0.05;
-
RenderMedia::RenderMedia(HTMLMediaElement* video)
: RenderImage(video)
+<<<<<<< HEAD
, m_timeUpdateTimer(this, &RenderMedia::timeUpdateTimerFired)
, m_opacityAnimationTimer(this, &RenderMedia::opacityAnimationTimerFired)
, m_mouseOver(false)
@@ -65,12 +63,16 @@ RenderMedia::RenderMedia(HTMLMediaElement* video)
#if PLATFORM(ANDROID)
, m_lastTouch(0)
#endif
+=======
+ , m_controls(new MediaControls(video))
+>>>>>>> webkit.org at r78450
{
setImageResource(RenderImageResource::create());
}
RenderMedia::RenderMedia(HTMLMediaElement* video, const IntSize& intrinsicSize)
: RenderImage(video)
+<<<<<<< HEAD
, m_timeUpdateTimer(this, &RenderMedia::timeUpdateTimerFired)
, m_opacityAnimationTimer(this, &RenderMedia::opacityAnimationTimerFired)
, m_mouseOver(false)
@@ -81,6 +83,9 @@ RenderMedia::RenderMedia(HTMLMediaElement* video, const IntSize& intrinsicSize)
#if PLATFORM(ANDROID)
, m_lastTouch(0)
#endif
+=======
+ , m_controls(new MediaControls(video))
+>>>>>>> webkit.org at r78450
{
setImageResource(RenderImageResource::create());
setIntrinsicSize(intrinsicSize);
@@ -92,16 +97,7 @@ RenderMedia::~RenderMedia()
void RenderMedia::destroy()
{
- if (m_controlsShadowRoot && m_controlsShadowRoot->renderer()) {
-
- // detach the panel before removing the shadow renderer to prevent a crash in m_controlsShadowRoot->detach()
- // when display: style changes
- m_panel->detach();
-
- removeChild(m_controlsShadowRoot->renderer());
- m_controlsShadowRoot->detach();
- m_controlsShadowRoot = 0;
- }
+ m_controls->destroy();
RenderImage::destroy();
}
@@ -110,51 +106,10 @@ HTMLMediaElement* RenderMedia::mediaElement() const
return static_cast<HTMLMediaElement*>(node());
}
-MediaPlayer* RenderMedia::player() const
-{
- return mediaElement()->player();
-}
-
void RenderMedia::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderImage::styleDidChange(diff, oldStyle);
-
- if (m_controlsShadowRoot) {
- if (m_panel)
- m_panel->updateStyle();
- if (m_muteButton)
- m_muteButton->updateStyle();
- if (m_playButton)
- m_playButton->updateStyle();
- if (m_seekBackButton)
- m_seekBackButton->updateStyle();
- if (m_seekForwardButton)
- m_seekForwardButton->updateStyle();
- if (m_rewindButton)
- m_rewindButton->updateStyle();
- if (m_returnToRealtimeButton)
- m_returnToRealtimeButton->updateStyle();
- if (m_toggleClosedCaptionsButton)
- m_toggleClosedCaptionsButton->updateStyle();
- if (m_statusDisplay)
- m_statusDisplay->updateStyle();
- if (m_timelineContainer)
- m_timelineContainer->updateStyle();
- if (m_timeline)
- m_timeline->updateStyle();
- if (m_fullscreenButton)
- m_fullscreenButton->updateStyle();
- if (m_currentTimeDisplay)
- m_currentTimeDisplay->updateStyle();
- if (m_timeRemainingDisplay)
- m_timeRemainingDisplay->updateStyle();
- if (m_volumeSliderContainer)
- m_volumeSliderContainer->updateStyle();
- if (m_volumeSliderMuteButton)
- m_volumeSliderMuteButton->updateStyle();
- if (m_volumeSlider)
- m_volumeSlider->updateStyle();
- }
+ m_controls->updateStyle();
}
void RenderMedia::layout()
@@ -163,17 +118,13 @@ void RenderMedia::layout()
RenderImage::layout();
- RenderBox* controlsRenderer = m_controlsShadowRoot ? m_controlsShadowRoot->renderBox() : 0;
+ RenderBox* controlsRenderer = m_controls->renderBox();
if (!controlsRenderer)
return;
IntSize newSize = contentBoxRect().size();
if (newSize != oldSize || controlsRenderer->needsLayout()) {
- if (m_currentTimeDisplay && m_timeRemainingDisplay) {
- bool shouldShowTimeDisplays = shouldShowTimeDisplayControls();
- m_currentTimeDisplay->setVisible(shouldShowTimeDisplays);
- m_timeRemainingDisplay->setVisible(shouldShowTimeDisplays);
- }
+ m_controls->updateTimeDisplayVisibility();
controlsRenderer->setLocation(borderLeft() + paddingLeft(), borderTop() + paddingTop());
controlsRenderer->style()->setHeight(Length(newSize.height(), Fixed));
@@ -184,139 +135,9 @@ void RenderMedia::layout()
}
}
-void RenderMedia::createControlsShadowRoot()
-{
- ASSERT(!m_controlsShadowRoot);
- m_controlsShadowRoot = MediaControlShadowRootElement::create(mediaElement());
- addChild(m_controlsShadowRoot->renderer());
-}
-
-void RenderMedia::createPanel()
-{
- ASSERT(!m_panel);
- m_panel = MediaControlElement::create(mediaElement(), MEDIA_CONTROLS_PANEL);
- m_panel->attachToParent(m_controlsShadowRoot.get());
-}
-
-void RenderMedia::createMuteButton()
-{
- ASSERT(!m_muteButton);
- m_muteButton = MediaControlMuteButtonElement::create(mediaElement(), MediaControlMuteButtonElement::Controller);
- m_muteButton->attachToParent(m_panel.get());
-}
-
-void RenderMedia::createPlayButton()
-{
- ASSERT(!m_playButton);
- m_playButton = MediaControlPlayButtonElement::create(mediaElement());
- m_playButton->attachToParent(m_panel.get());
-}
-
-void RenderMedia::createSeekBackButton()
-{
- ASSERT(!m_seekBackButton);
- m_seekBackButton = MediaControlSeekButtonElement::create(mediaElement(), MEDIA_CONTROLS_SEEK_BACK_BUTTON);
- m_seekBackButton->attachToParent(m_panel.get());
-}
-
-void RenderMedia::createSeekForwardButton()
-{
- ASSERT(!m_seekForwardButton);
- m_seekForwardButton = MediaControlSeekButtonElement::create(mediaElement(), MEDIA_CONTROLS_SEEK_FORWARD_BUTTON);
- m_seekForwardButton->attachToParent(m_panel.get());
-}
-
-void RenderMedia::createRewindButton()
-{
- ASSERT(!m_rewindButton);
- m_rewindButton = MediaControlRewindButtonElement::create(mediaElement());
- m_rewindButton->attachToParent(m_panel.get());
-}
-
-void RenderMedia::createReturnToRealtimeButton()
-{
- ASSERT(!m_returnToRealtimeButton);
- m_returnToRealtimeButton = MediaControlReturnToRealtimeButtonElement::create(mediaElement());
- m_returnToRealtimeButton->attachToParent(m_panel.get());
-}
-
-void RenderMedia::createToggleClosedCaptionsButton()
-{
- ASSERT(!m_toggleClosedCaptionsButton);
- m_toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(mediaElement());
- m_toggleClosedCaptionsButton->attachToParent(m_panel.get());
-}
-
-void RenderMedia::createStatusDisplay()
-{
- ASSERT(!m_statusDisplay);
- m_statusDisplay = MediaControlStatusDisplayElement::create(mediaElement());
- m_statusDisplay->attachToParent(m_panel.get());
-}
-
-void RenderMedia::createTimelineContainer()
-{
- ASSERT(!m_timelineContainer);
- m_timelineContainer = MediaControlTimelineContainerElement::create(mediaElement());
- m_timelineContainer->attachToParent(m_panel.get());
-}
-
-void RenderMedia::createTimeline()
-{
- ASSERT(!m_timeline);
- m_timeline = MediaControlTimelineElement::create(mediaElement());
- m_timeline->setAttribute(precisionAttr, "float");
- m_timeline->attachToParent(m_timelineContainer.get());
-}
-
-void RenderMedia::createVolumeSliderContainer()
-{
- ASSERT(!m_volumeSliderContainer);
- m_volumeSliderContainer = MediaControlVolumeSliderContainerElement::create(mediaElement());
- m_volumeSliderContainer->attachToParent(m_panel.get());
-}
-
-void RenderMedia::createVolumeSlider()
-{
- ASSERT(!m_volumeSlider);
- m_volumeSlider = MediaControlVolumeSliderElement::create(mediaElement());
- m_volumeSlider->setAttribute(precisionAttr, "float");
- m_volumeSlider->setAttribute(maxAttr, "1");
- m_volumeSlider->setAttribute(valueAttr, String::number(mediaElement()->volume()));
- m_volumeSlider->attachToParent(m_volumeSliderContainer.get());
-}
-
-void RenderMedia::createVolumeSliderMuteButton()
-{
- ASSERT(!m_volumeSliderMuteButton);
- m_volumeSliderMuteButton = MediaControlMuteButtonElement::create(mediaElement(), MediaControlMuteButtonElement::VolumeSlider);
- m_volumeSliderMuteButton->attachToParent(m_volumeSliderContainer.get());
-
-}
-
-void RenderMedia::createCurrentTimeDisplay()
-{
- ASSERT(!m_currentTimeDisplay);
- m_currentTimeDisplay = MediaControlTimeDisplayElement::create(mediaElement(), MEDIA_CONTROLS_CURRENT_TIME_DISPLAY);
- m_currentTimeDisplay->attachToParent(m_timelineContainer.get());
-}
-
-void RenderMedia::createTimeRemainingDisplay()
-{
- ASSERT(!m_timeRemainingDisplay);
- m_timeRemainingDisplay = MediaControlTimeDisplayElement::create(mediaElement(), MEDIA_CONTROLS_TIME_REMAINING_DISPLAY);
- m_timeRemainingDisplay->attachToParent(m_timelineContainer.get());
-}
-
-void RenderMedia::createFullscreenButton()
-{
- ASSERT(!m_fullscreenButton);
- m_fullscreenButton = MediaControlFullscreenButtonElement::create(mediaElement());
- m_fullscreenButton->attachToParent(m_panel.get());
-}
-
void RenderMedia::updateFromElement()
{
+<<<<<<< HEAD
updateControls();
}
@@ -658,6 +479,9 @@ bool RenderMedia::shouldShowTimeDisplayControls() const
int width = mediaElement()->renderBox()->width();
return width >= minWidthToDisplayTimeDisplays * style()->effectiveZoom();
+=======
+ m_controls->update();
+>>>>>>> webkit.org at r78450
}
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderMedia.h b/Source/WebCore/rendering/RenderMedia.h
index 817252d..1772766 100644
--- a/Source/WebCore/rendering/RenderMedia.h
+++ b/Source/WebCore/rendering/RenderMedia.h
@@ -29,27 +29,11 @@
#if ENABLE(VIDEO)
#include "RenderImage.h"
-#include "Timer.h"
namespace WebCore {
-
-class HTMLInputElement;
+
class HTMLMediaElement;
-class MediaControlMuteButtonElement;
-class MediaControlPlayButtonElement;
-class MediaControlSeekButtonElement;
-class MediaControlRewindButtonElement;
-class MediaControlReturnToRealtimeButtonElement;
-class MediaControlToggleClosedCaptionsButtonElement;
-class MediaControlTimelineElement;
-class MediaControlVolumeSliderElement;
-class MediaControlFullscreenButtonElement;
-class MediaControlTimeDisplayElement;
-class MediaControlStatusDisplayElement;
-class MediaControlTimelineContainerElement;
-class MediaControlVolumeSliderContainerElement;
-class MediaControlElement;
-class MediaPlayer;
+class MediaControls;
class RenderMedia : public RenderImage {
public:
@@ -61,10 +45,9 @@ public:
RenderObjectChildList* children() { return &m_children; }
HTMLMediaElement* mediaElement() const;
- MediaPlayer* player() const;
-
- bool shouldShowTimeDisplayControls() const;
+ MediaControls* controls() const;
+<<<<<<< HEAD
void updateFromElement();
void updatePlayer();
void updateControls();
@@ -74,6 +57,9 @@ public:
#if PLATFORM(ANDROID)
void updateLastTouch();
#endif
+=======
+ virtual void updateFromElement();
+>>>>>>> webkit.org at r78450
protected:
virtual void layout();
@@ -88,57 +74,14 @@ private:
virtual bool isMedia() const { return true; }
virtual bool isImage() const { return false; }
- void createControlsShadowRoot();
- void destroyControlsShadowRoot();
- void createPanel();
- void createMuteButton();
- void createPlayButton();
- void createSeekBackButton();
- void createSeekForwardButton();
- void createRewindButton();
- void createReturnToRealtimeButton();
- void createToggleClosedCaptionsButton();
- void createStatusDisplay();
- void createTimelineContainer();
- void createTimeline();
- void createVolumeSliderContainer();
- void createVolumeSlider();
- void createVolumeSliderMuteButton();
- void createCurrentTimeDisplay();
- void createTimeRemainingDisplay();
- void createFullscreenButton();
-
- void timeUpdateTimerFired(Timer<RenderMedia>*);
-
- void updateControlVisibility();
- void changeOpacity(HTMLElement*, float opacity);
- void opacityAnimationTimerFired(Timer<RenderMedia>*);
-
- void updateVolumeSliderContainer(bool visible);
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
virtual bool requiresForcedStyleRecalcPropagation() const { return true; }
- RefPtr<HTMLElement> m_controlsShadowRoot;
- RefPtr<MediaControlElement> m_panel;
- RefPtr<MediaControlMuteButtonElement> m_muteButton;
- RefPtr<MediaControlPlayButtonElement> m_playButton;
- RefPtr<MediaControlSeekButtonElement> m_seekBackButton;
- RefPtr<MediaControlSeekButtonElement> m_seekForwardButton;
- RefPtr<MediaControlRewindButtonElement> m_rewindButton;
- RefPtr<MediaControlReturnToRealtimeButtonElement> m_returnToRealtimeButton;
- RefPtr<MediaControlToggleClosedCaptionsButtonElement> m_toggleClosedCaptionsButton;
- RefPtr<MediaControlTimelineElement> m_timeline;
- RefPtr<MediaControlVolumeSliderElement> m_volumeSlider;
- RefPtr<MediaControlMuteButtonElement> m_volumeSliderMuteButton;
- RefPtr<MediaControlFullscreenButtonElement> m_fullscreenButton;
- RefPtr<MediaControlTimelineContainerElement> m_timelineContainer;
- RefPtr<MediaControlVolumeSliderContainerElement> m_volumeSliderContainer;
- RefPtr<MediaControlTimeDisplayElement> m_currentTimeDisplay;
- RefPtr<MediaControlTimeDisplayElement> m_timeRemainingDisplay;
- RefPtr<MediaControlStatusDisplayElement> m_statusDisplay;
+ OwnPtr<MediaControls> m_controls;
RenderObjectChildList m_children;
+<<<<<<< HEAD
Node* m_lastUnderNode;
Node* m_nodeUnderMouse;
@@ -152,6 +95,8 @@ private:
#if PLATFORM(ANDROID)
double m_lastTouch;
#endif
+=======
+>>>>>>> webkit.org at r78450
};
inline RenderMedia* toRenderMedia(RenderObject* object)
@@ -160,6 +105,11 @@ inline RenderMedia* toRenderMedia(RenderObject* object)
return static_cast<RenderMedia*>(object);
}
+inline MediaControls* RenderMedia::controls() const
+{
+ return m_controls.get();
+}
+
// This will catch anyone doing an unnecessary cast.
void toRenderMedia(const RenderMedia*);
diff --git a/Source/WebCore/rendering/RenderMenuList.cpp b/Source/WebCore/rendering/RenderMenuList.cpp
index e55b5ca..3e9d198 100644
--- a/Source/WebCore/rendering/RenderMenuList.cpp
+++ b/Source/WebCore/rendering/RenderMenuList.cpp
@@ -2,7 +2,7 @@
* This file is part of the select element renderer in WebCore.
*
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
- * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
* 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
@@ -55,7 +55,6 @@ RenderMenuList::RenderMenuList(Element* element)
, m_optionsChanged(true)
, m_optionsWidth(0)
, m_lastSelectedIndex(-1)
- , m_popup(0)
, m_popupIsVisible(false)
{
}
@@ -84,19 +83,26 @@ void RenderMenuList::createInnerBlock()
void RenderMenuList::adjustInnerStyle()
{
- m_innerBlock->style()->setBoxFlex(1.0f);
+ RenderStyle* innerStyle = m_innerBlock->style();
+ innerStyle->setBoxFlex(1);
- m_innerBlock->style()->setPaddingLeft(Length(theme()->popupInternalPaddingLeft(style()), Fixed));
- m_innerBlock->style()->setPaddingRight(Length(theme()->popupInternalPaddingRight(style()), Fixed));
- m_innerBlock->style()->setPaddingTop(Length(theme()->popupInternalPaddingTop(style()), Fixed));
- m_innerBlock->style()->setPaddingBottom(Length(theme()->popupInternalPaddingBottom(style()), Fixed));
+ innerStyle->setPaddingLeft(Length(theme()->popupInternalPaddingLeft(style()), Fixed));
+ innerStyle->setPaddingRight(Length(theme()->popupInternalPaddingRight(style()), Fixed));
+ innerStyle->setPaddingTop(Length(theme()->popupInternalPaddingTop(style()), Fixed));
+ innerStyle->setPaddingBottom(Length(theme()->popupInternalPaddingBottom(style()), Fixed));
if (document()->page()->chrome()->selectItemWritingDirectionIsNatural()) {
// Items in the popup will not respect the CSS text-align and direction properties,
// so we must adjust our own style to match.
- m_innerBlock->style()->setTextAlign(LEFT);
+ innerStyle->setTextAlign(LEFT);
TextDirection direction = (m_buttonText && m_buttonText->text()->defaultWritingDirection() == WTF::Unicode::RightToLeft) ? RTL : LTR;
- m_innerBlock->style()->setDirection(direction);
+ innerStyle->setDirection(direction);
+ } else if (m_optionStyle && document()->page()->chrome()->selectItemAlignmentFollowsMenuWritingDirection()) {
+ if ((m_optionStyle->direction() != innerStyle->direction() || m_optionStyle->unicodeBidi() != innerStyle->unicodeBidi()))
+ m_innerBlock->setNeedsLayoutAndPrefWidthsRecalc();
+ innerStyle->setTextAlign(style()->isLeftToRightDirection() ? LEFT : RIGHT);
+ innerStyle->setDirection(m_optionStyle->direction());
+ innerStyle->setUnicodeBidi(m_optionStyle->unicodeBidi());
}
}
@@ -184,8 +190,11 @@ void RenderMenuList::setTextFromOption(int optionIndex)
int i = select->optionToListIndex(optionIndex);
String text = "";
if (i >= 0 && i < size) {
- if (OptionElement* optionElement = toOptionElement(listItems[i]))
+ Element* element = listItems[i];
+ if (OptionElement* optionElement = toOptionElement(element)) {
text = optionElement->textIndentedToRespectGroupLabel();
+ m_optionStyle = element->renderStyle();
+ }
}
setText(text.stripWhiteSpace());
@@ -418,7 +427,7 @@ PopupMenuStyle RenderMenuList::itemStyle(unsigned listIndex) const
Element* element = listItems[listIndex];
RenderStyle* style = element->renderStyle() ? element->renderStyle() : element->computedStyle();
- return style ? PopupMenuStyle(style->visitedDependentColor(CSSPropertyColor), itemBackgroundColor(listIndex), style->font(), style->visibility() == VISIBLE, style->display() == NONE, style->textIndent(), style->direction()) : menuStyle();
+ return style ? PopupMenuStyle(style->visitedDependentColor(CSSPropertyColor), itemBackgroundColor(listIndex), style->font(), style->visibility() == VISIBLE, style->display() == NONE, style->textIndent(), style->direction(), style->unicodeBidi() == Override) : menuStyle();
}
Color RenderMenuList::itemBackgroundColor(unsigned listIndex) const
@@ -448,7 +457,7 @@ Color RenderMenuList::itemBackgroundColor(unsigned listIndex) const
PopupMenuStyle RenderMenuList::menuStyle() const
{
RenderStyle* s = m_innerBlock ? m_innerBlock->style() : style();
- return PopupMenuStyle(s->visitedDependentColor(CSSPropertyColor), s->visitedDependentColor(CSSPropertyBackgroundColor), s->font(), s->visibility() == VISIBLE, s->display() == NONE, s->textIndent(), s->direction());
+ return PopupMenuStyle(s->visitedDependentColor(CSSPropertyColor), s->visitedDependentColor(CSSPropertyBackgroundColor), s->font(), s->visibility() == VISIBLE, s->display() == NONE, s->textIndent(), style()->direction(), style()->unicodeBidi() == Override);
}
HostWindow* RenderMenuList::hostWindow() const
@@ -479,7 +488,7 @@ int RenderMenuList::clientInsetRight() const
int RenderMenuList::clientPaddingLeft() const
{
- return paddingLeft();
+ return paddingLeft() + m_innerBlock->paddingLeft();
}
const int endOfLinePadding = 2;
@@ -495,7 +504,7 @@ int RenderMenuList::clientPaddingRight() const
// If the appearance isn't MenulistPart, then the select is styled (non-native), so
// we want to return the user specified padding.
- return paddingRight();
+ return paddingRight() + m_innerBlock->paddingRight();
}
int RenderMenuList::listSize() const
diff --git a/Source/WebCore/rendering/RenderMenuList.h b/Source/WebCore/rendering/RenderMenuList.h
index b84b799..cd6e561 100644
--- a/Source/WebCore/rendering/RenderMenuList.h
+++ b/Source/WebCore/rendering/RenderMenuList.h
@@ -2,7 +2,7 @@
* This file is part of the select element renderer in WebCore.
*
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
- * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple 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
@@ -132,6 +132,8 @@ private:
int m_lastSelectedIndex;
+ RefPtr<RenderStyle> m_optionStyle;
+
RefPtr<PopupMenu> m_popup;
bool m_popupIsVisible;
};
diff --git a/Source/WebCore/rendering/RenderMeter.cpp b/Source/WebCore/rendering/RenderMeter.cpp
index 6439651..f3ada0b 100644
--- a/Source/WebCore/rendering/RenderMeter.cpp
+++ b/Source/WebCore/rendering/RenderMeter.cpp
@@ -107,7 +107,7 @@ RenderMeter::~RenderMeter()
PassRefPtr<MeterPartElement> RenderMeter::createPart(PseudoId pseudoId)
{
- RefPtr<MeterPartElement> element = MeterPartElement::createForPart(static_cast<HTMLElement*>(node()), pseudoId);
+ RefPtr<MeterPartElement> element = MeterPartElement::createForPart(toHTMLElement(node()), pseudoId);
if (element->renderer())
addChild(element->renderer());
return element;
diff --git a/Source/WebCore/rendering/RenderObject.cpp b/Source/WebCore/rendering/RenderObject.cpp
index 9a1233e..ebab355 100644
--- a/Source/WebCore/rendering/RenderObject.cpp
+++ b/Source/WebCore/rendering/RenderObject.cpp
@@ -3,7 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Dirk Mueller (mueller@kde.org)
* (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2009 Google Inc. All rights reserved.
* Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
@@ -31,6 +31,7 @@
#include "CSSStyleSelector.h"
#include "Chrome.h"
#include "ContentData.h"
+#include "CursorList.h"
#include "DashArray.h"
#include "EditingBoundary.h"
#include "FloatQuad.h"
@@ -319,7 +320,6 @@ void RenderObject::addChild(RenderObject* newChild, RenderObject* beforeChild)
// Just add it...
children->insertChildNode(this, newChild, beforeChild);
}
- RenderCounter::rendererSubtreeAttached(newChild);
if (newChild->isText() && newChild->style()->textTransform() == CAPITALIZE) {
RefPtr<StringImpl> textToTransform = toRenderText(newChild)->originalText();
if (textToTransform)
@@ -1381,11 +1381,11 @@ bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintConta
else if (deltaLeft < 0)
repaintUsingContainer(repaintContainer, IntRect(newBounds.x(), newBounds.y(), -deltaLeft, newBounds.height()));
- int deltaRight = newBounds.right() - oldBounds.right();
+ int deltaRight = newBounds.maxX() - oldBounds.maxX();
if (deltaRight > 0)
- repaintUsingContainer(repaintContainer, IntRect(oldBounds.right(), newBounds.y(), deltaRight, newBounds.height()));
+ repaintUsingContainer(repaintContainer, IntRect(oldBounds.maxX(), newBounds.y(), deltaRight, newBounds.height()));
else if (deltaRight < 0)
- repaintUsingContainer(repaintContainer, IntRect(newBounds.right(), oldBounds.y(), -deltaRight, oldBounds.height()));
+ repaintUsingContainer(repaintContainer, IntRect(newBounds.maxX(), oldBounds.y(), -deltaRight, oldBounds.height()));
int deltaTop = newBounds.y() - oldBounds.y();
if (deltaTop > 0)
@@ -1393,11 +1393,11 @@ bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintConta
else if (deltaTop < 0)
repaintUsingContainer(repaintContainer, IntRect(newBounds.x(), newBounds.y(), newBounds.width(), -deltaTop));
- int deltaBottom = newBounds.bottom() - oldBounds.bottom();
+ int deltaBottom = newBounds.maxY() - oldBounds.maxY();
if (deltaBottom > 0)
- repaintUsingContainer(repaintContainer, IntRect(newBounds.x(), oldBounds.bottom(), newBounds.width(), deltaBottom));
+ repaintUsingContainer(repaintContainer, IntRect(newBounds.x(), oldBounds.maxY(), newBounds.width(), deltaBottom));
else if (deltaBottom < 0)
- repaintUsingContainer(repaintContainer, IntRect(oldBounds.x(), newBounds.bottom(), oldBounds.width(), -deltaBottom));
+ repaintUsingContainer(repaintContainer, IntRect(oldBounds.x(), newBounds.maxY(), oldBounds.width(), -deltaBottom));
if (newOutlineBox == oldOutlineBox)
return false;
@@ -1419,7 +1419,7 @@ bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintConta
newOutlineBox.y(),
width + borderWidth,
max(newOutlineBox.height(), oldOutlineBox.height()));
- int right = min(newBounds.right(), oldBounds.right());
+ int right = min(newBounds.maxX(), oldBounds.maxX());
if (rightRect.x() < right) {
rightRect.setWidth(min(rightRect.width(), right - rightRect.x()));
repaintUsingContainer(repaintContainer, rightRect);
@@ -1435,10 +1435,10 @@ bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintConta
int boxHeight = isBox() ? toRenderBox(this)->height() : 0;
int borderHeight = max(-outlineStyle->outlineOffset(), max(borderBottom, max(style()->borderBottomLeftRadius().height().calcValue(boxHeight), style()->borderBottomRightRadius().height().calcValue(boxHeight)))) + max(ow, shadowBottom);
IntRect bottomRect(newOutlineBox.x(),
- min(newOutlineBox.bottom(), oldOutlineBox.bottom()) - borderHeight,
+ min(newOutlineBox.maxY(), oldOutlineBox.maxY()) - borderHeight,
max(newOutlineBox.width(), oldOutlineBox.width()),
height + borderHeight);
- int bottom = min(newBounds.bottom(), oldBounds.bottom());
+ int bottom = min(newBounds.maxY(), oldBounds.maxY());
if (bottomRect.y() < bottom) {
bottomRect.setHeight(min(bottomRect.height(), bottom - bottomRect.y()));
repaintUsingContainer(repaintContainer, bottomRect);
@@ -1863,6 +1863,17 @@ void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle* newS
}
}
+static bool areNonIdenticalCursorListsEqual(const RenderStyle* a, const RenderStyle* b)
+{
+ ASSERT(a->cursors() != b->cursors());
+ return a->cursors() && b->cursors() && *a->cursors() == *b->cursors();
+}
+
+static inline bool areCursorsEqual(const RenderStyle* a, const RenderStyle* b)
+{
+ return a->cursor() == b->cursor() && (a->cursors() == b->cursors() || areNonIdenticalCursorListsEqual(a, b));
+}
+
void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
if (s_affectsParentBlock)
@@ -1888,6 +1899,11 @@ void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle* oldSt
// Don't check for repaint here; we need to wait until the layer has been
// updated by subclasses before we know if we have to repaint (in setStyle()).
+
+ if (oldStyle && !areCursorsEqual(oldStyle, style())) {
+ if (Frame* frame = this->frame())
+ frame->eventHandler()->dispatchFakeMouseMoveEventSoon();
+ }
}
void RenderObject::updateFillImages(const FillLayer* oldLayers, const FillLayer* newLayers)
@@ -1950,6 +1966,10 @@ void RenderObject::mapLocalToContainer(RenderBoxModelObject* repaintContainer, b
if (!o)
return;
+ IntPoint centerPoint = roundedIntPoint(transformState.mappedPoint());
+ if (o->isBox() && o->style()->isFlippedBlocksWritingMode())
+ transformState.move(toRenderBox(o)->flipForWritingModeIncludingColumns(roundedIntPoint(transformState.mappedPoint())) - centerPoint);
+
IntSize columnOffset;
o->adjustForColumns(columnOffset, roundedIntPoint(transformState.mappedPoint()));
if (!columnOffset.isZero())
@@ -1989,7 +2009,7 @@ void RenderObject::getTransformFromContainer(const RenderObject* containerObject
transform.translate(offsetInContainer.width(), offsetInContainer.height());
RenderLayer* layer;
if (hasLayer() && (layer = toRenderBoxModelObject(this)->layer()) && layer->transform())
- transform.multLeft(layer->currentTransform());
+ transform.multiply(layer->currentTransform());
#if ENABLE(3D_RENDERING)
if (containerObject && containerObject->hasLayer() && containerObject->style()->hasPerspective()) {
@@ -2001,7 +2021,7 @@ void RenderObject::getTransformFromContainer(const RenderObject* containerObject
perspectiveMatrix.applyPerspective(containerObject->style()->perspective());
transform.translateRight3d(-perspectiveOrigin.x(), -perspectiveOrigin.y(), 0);
- transform.multiply(perspectiveMatrix);
+ transform = perspectiveMatrix * transform;
transform.translateRight3d(perspectiveOrigin.x(), perspectiveOrigin.y(), 0);
}
#else
@@ -2157,9 +2177,6 @@ void RenderObject::destroy()
if (frame() && frame()->eventHandler()->autoscrollRenderer() == this)
frame()->eventHandler()->stopAutoscrollTimer(true);
- if (m_hasCounterNodeMap)
- RenderCounter::destroyCounterNodes(this);
-
if (AXObjectCache::accessibilityEnabled()) {
document()->axObjectCache()->childrenChanged(this->parent());
document()->axObjectCache()->remove(this);
@@ -2172,6 +2189,14 @@ void RenderObject::destroy()
remove();
+ // If this renderer had a parent, remove should have destroyed any counters
+ // attached to this renderer and marked the affected other counters for
+ // reevaluation. This apparently redundant check is here for the case when
+ // this renderer had no parent at the time remove() was called.
+
+ if (m_hasCounterNodeMap)
+ RenderCounter::destroyCounterNodes(this);
+
// FIXME: Would like to do this in RenderBoxModelObject, but the timing is so complicated that this can't easily
// be moved into RenderBoxModelObject::destroy.
if (hasLayer()) {
diff --git a/Source/WebCore/rendering/RenderObject.h b/Source/WebCore/rendering/RenderObject.h
index f2e7f13..43e6bea 100644
--- a/Source/WebCore/rendering/RenderObject.h
+++ b/Source/WebCore/rendering/RenderObject.h
@@ -143,6 +143,18 @@ public:
return children->lastChild();
return 0;
}
+ RenderObject* beforePseudoElementRenderer() const
+ {
+ if (const RenderObjectChildList* children = virtualChildren())
+ return children->beforePseudoElementRenderer(this);
+ return 0;
+ }
+ RenderObject* afterPseudoElementRenderer() const
+ {
+ if (const RenderObjectChildList* children = virtualChildren())
+ return children->afterPseudoElementRenderer(this);
+ return 0;
+ }
virtual RenderObjectChildList* virtualChildren() { return 0; }
virtual const RenderObjectChildList* virtualChildren() const { return 0; }
@@ -332,6 +344,7 @@ public:
virtual bool isSVGImage() const { return false; }
virtual bool isSVGForeignObject() const { return false; }
virtual bool isSVGResourceContainer() const { return false; }
+ virtual bool isSVGResourceFilter() const { return false; }
virtual bool isSVGResourceFilterPrimitive() const { return false; }
virtual bool isSVGShadowTreeRootContainer() const { return false; }
@@ -444,6 +457,11 @@ public:
bool isRooted(RenderView** = 0);
Node* node() const { return m_isAnonymous ? 0 : m_node; }
+
+ // Returns the styled node that caused the generation of this renderer.
+ // This is the same as node() except for renderers of :before and :after
+ // pseudo elements for which their parent node is returned.
+ Node* generatingNode() const { return m_node == document() ? 0 : m_node; }
void setNode(Node* node) { m_node = node; }
Document* document() const { return m_node->document(); }
diff --git a/Source/WebCore/rendering/RenderObjectChildList.cpp b/Source/WebCore/rendering/RenderObjectChildList.cpp
index fa4f902..6a773dc 100644
--- a/Source/WebCore/rendering/RenderObjectChildList.cpp
+++ b/Source/WebCore/rendering/RenderObjectChildList.cpp
@@ -128,6 +128,9 @@ RenderObject* RenderObjectChildList::removeChildNode(RenderObject* owner, Render
oldChild->setNextSibling(0);
oldChild->setParent(0);
+ if (oldChild->m_hasCounterNodeMap)
+ RenderCounter::destroyCounterNodes(oldChild);
+
if (AXObjectCache::accessibilityEnabled())
owner->document()->axObjectCache()->childrenChanged(owner);
@@ -175,6 +178,7 @@ void RenderObjectChildList::appendChildNode(RenderObject* owner, RenderObject* n
owner->dirtyLinesFromChangedChild(newChild);
}
+ RenderCounter::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.
@@ -234,6 +238,7 @@ void RenderObjectChildList::insertChildNode(RenderObject* owner, RenderObject* c
owner->dirtyLinesFromChangedChild(child);
}
+ RenderCounter::rendererSubtreeAttached(child);
child->setNeedsLayoutAndPrefWidthsRecalc();
if (!owner->normalChildNeedsLayout())
owner->setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
@@ -242,59 +247,6 @@ void RenderObjectChildList::insertChildNode(RenderObject* owner, RenderObject* c
owner->document()->axObjectCache()->childrenChanged(owner);
}
-static RenderObject* beforeAfterContainer(RenderObject* container, PseudoId type)
-{
- if (type == BEFORE) {
- // An anonymous (generated) inline run-in that has PseudoId BEFORE must come from a grandparent.
- // Therefore we should skip these generated run-ins when checking our immediate children.
- // If we don't find our :before child immediately, then we should check if we own a
- // generated inline run-in in the next level of children.
- RenderObject* first = container;
- do {
- // Skip list markers and generated run-ins
- first = first->firstChild();
- while (first && (first->isListMarker() || (first->isRenderInline() && first->isRunIn() && first->isAnonymous())))
- first = first->nextSibling();
- } while (first && first->isAnonymous() && first->style()->styleType() == NOPSEUDO);
-
- if (!first)
- return 0;
-
- if (first->style()->styleType() == type)
- return first;
-
- // Check for a possible generated run-in, using run-in positioning rules.
- // Skip inlines and floating / positioned blocks, and place as the first child.
- first = container->firstChild();
- if (!first->isRenderBlock())
- return 0;
- while (first && first->isFloatingOrPositioned())
- first = first->nextSibling();
- if (first) {
- first = first->firstChild();
- // We still need to skip any list markers that could exist before the run-in.
- while (first && first->isListMarker())
- first = first->nextSibling();
- if (first && first->style()->styleType() == type && first->isRenderInline() && first->isRunIn() && first->isAnonymous())
- return first;
- }
- return 0;
- }
-
- if (type == AFTER) {
- RenderObject* last = container;
- do {
- last = last->lastChild();
- } while (last && last->isAnonymous() && last->style()->styleType() == NOPSEUDO && !last->isListMarker());
- if (last && last->style()->styleType() != type)
- return 0;
- return last;
- }
-
- ASSERT_NOT_REACHED();
- return 0;
-}
-
static RenderObject* findBeforeAfterParent(RenderObject* object)
{
// Only table parts need to search for the :before or :after parent
@@ -325,14 +277,63 @@ static void invalidateCountersInContainer(RenderObject* container, const AtomicS
}
}
-void RenderObjectChildList::invalidateCounters(RenderObject* owner, const AtomicString& identifier)
+void RenderObjectChildList::invalidateCounters(const RenderObject* owner, const AtomicString& identifier)
{
ASSERT(!owner->documentBeingDestroyed());
- invalidateCountersInContainer(beforeAfterContainer(owner, BEFORE), identifier);
- invalidateCountersInContainer(beforeAfterContainer(owner, AFTER), identifier);
+ invalidateCountersInContainer(beforePseudoElementRenderer(owner), identifier);
+ invalidateCountersInContainer(afterPseudoElementRenderer(owner), identifier);
}
-void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, PseudoId type, RenderObject* styledObject)
+RenderObject* RenderObjectChildList::beforePseudoElementRenderer(const RenderObject* owner) const
+{
+ // An anonymous (generated) inline run-in that has PseudoId BEFORE must come from a grandparent.
+ // Therefore we should skip these generated run-ins when checking our immediate children.
+ // If we don't find our :before child immediately, then we should check if we own a
+ // generated inline run-in in the next level of children.
+ RenderObject* first = const_cast<RenderObject*>(owner);
+ do {
+ // Skip list markers and generated run-ins
+ first = first->firstChild();
+ while (first && (first->isListMarker() || (first->isRenderInline() && first->isRunIn() && first->isAnonymous())))
+ first = first->nextSibling();
+ } while (first && first->isAnonymous() && first->style()->styleType() == NOPSEUDO);
+
+ if (!first)
+ return 0;
+
+ if (first->style()->styleType() == BEFORE)
+ return first;
+
+ // Check for a possible generated run-in, using run-in positioning rules.
+ // Skip inlines and floating / positioned blocks, and place as the first child.
+ first = owner->firstChild();
+ if (!first->isRenderBlock())
+ return 0;
+ while (first && first->isFloatingOrPositioned())
+ first = first->nextSibling();
+ if (first) {
+ first = first->firstChild();
+ // We still need to skip any list markers that could exist before the run-in.
+ while (first && first->isListMarker())
+ first = first->nextSibling();
+ if (first && first->style()->styleType() == BEFORE && first->isRenderInline() && first->isRunIn() && first->isAnonymous())
+ return first;
+ }
+ return 0;
+}
+
+RenderObject* RenderObjectChildList::afterPseudoElementRenderer(const RenderObject* owner) const
+{
+ RenderObject* last = const_cast<RenderObject*>(owner);
+ do {
+ last = last->lastChild();
+ } while (last && last->isAnonymous() && last->style()->styleType() == NOPSEUDO && !last->isListMarker());
+ if (last && last->style()->styleType() != AFTER)
+ return 0;
+ return last;
+}
+
+void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, PseudoId type, const RenderObject* styledObject)
{
// Double check that the document did in fact use generated content rules. Otherwise we should not have been called.
ASSERT(owner->document()->usesBeforeAfterRules());
@@ -345,7 +346,18 @@ void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, Pseudo
styledObject = owner;
RenderStyle* pseudoElementStyle = styledObject->getCachedPseudoStyle(type);
- RenderObject* child = beforeAfterContainer(owner, type);
+ RenderObject* child;
+ switch (type) {
+ case BEFORE:
+ child = beforePseudoElementRenderer(owner);
+ break;
+ case AFTER:
+ child = afterPseudoElementRenderer(owner);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ return;
+ }
// Whether or not we currently have generated content attached.
bool oldContentPresent = child;
@@ -459,6 +471,8 @@ void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, Pseudo
// Make a generated box that might be any display type now that we are able to drill down into children
// to find the original content properly.
generatedContentContainer = RenderObject::createObject(owner->document(), pseudoElementStyle);
+ ASSERT(styledObject->node()); // The styled object cannot be anonymous or else it could not have ':before' or ':after' pseudo elements.
+ generatedContentContainer->setNode(styledObject->node()); // This allows access to the generatingNode.
generatedContentContainer->setStyle(pseudoElementStyle);
owner->addChild(generatedContentContainer, insertBefore);
}
diff --git a/Source/WebCore/rendering/RenderObjectChildList.h b/Source/WebCore/rendering/RenderObjectChildList.h
index 8b80f37..087adfb 100644
--- a/Source/WebCore/rendering/RenderObjectChildList.h
+++ b/Source/WebCore/rendering/RenderObjectChildList.h
@@ -55,8 +55,10 @@ public:
void appendChildNode(RenderObject* owner, RenderObject*, bool fullAppend = true);
void insertChildNode(RenderObject* owner, RenderObject* child, RenderObject* before, bool fullInsert = true);
- void updateBeforeAfterContent(RenderObject* owner, PseudoId type, RenderObject* styledObject = 0);
- void invalidateCounters(RenderObject* owner, const AtomicString& identifier);
+ void updateBeforeAfterContent(RenderObject* owner, PseudoId type, const RenderObject* styledObject = 0);
+ RenderObject* beforePseudoElementRenderer(const RenderObject* owner) const;
+ RenderObject* afterPseudoElementRenderer(const RenderObject* owner) const;
+ void invalidateCounters(const RenderObject* owner, const AtomicString& identifier);
private:
RenderObject* m_firstChild;
diff --git a/Source/WebCore/rendering/RenderOverflow.h b/Source/WebCore/rendering/RenderOverflow.h
index 33e8cff..48fe2bb 100644
--- a/Source/WebCore/rendering/RenderOverflow.h
+++ b/Source/WebCore/rendering/RenderOverflow.h
@@ -41,38 +41,38 @@ class RenderOverflow {
WTF_MAKE_NONCOPYABLE(RenderOverflow); WTF_MAKE_FAST_ALLOCATED;
public:
RenderOverflow(const IntRect& layoutRect, const IntRect& visualRect)
- : m_topLayoutOverflow(layoutRect.y())
- , m_bottomLayoutOverflow(layoutRect.bottom())
- , m_leftLayoutOverflow(layoutRect.x())
- , m_rightLayoutOverflow(layoutRect.right())
- , m_topVisualOverflow(visualRect.y())
- , m_bottomVisualOverflow(visualRect.bottom())
- , m_leftVisualOverflow(visualRect.x())
- , m_rightVisualOverflow(visualRect.right())
+ : m_minYLayoutOverflow(layoutRect.y())
+ , m_maxYLayoutOverflow(layoutRect.maxY())
+ , m_minXLayoutOverflow(layoutRect.x())
+ , m_maxXLayoutOverflow(layoutRect.maxX())
+ , m_minYVisualOverflow(visualRect.y())
+ , m_maxYVisualOverflow(visualRect.maxY())
+ , m_minXVisualOverflow(visualRect.x())
+ , m_maxXVisualOverflow(visualRect.maxX())
{
}
- int topLayoutOverflow() const { return m_topLayoutOverflow; }
- int bottomLayoutOverflow() const { return m_bottomLayoutOverflow; }
- int leftLayoutOverflow() const { return m_leftLayoutOverflow; }
- int rightLayoutOverflow() const { return m_rightLayoutOverflow; }
+ int minYLayoutOverflow() const { return m_minYLayoutOverflow; }
+ int maxYLayoutOverflow() const { return m_maxYLayoutOverflow; }
+ int minXLayoutOverflow() const { return m_minXLayoutOverflow; }
+ int maxXLayoutOverflow() const { return m_maxXLayoutOverflow; }
IntRect layoutOverflowRect() const;
- int topVisualOverflow() const { return m_topVisualOverflow; }
- int bottomVisualOverflow() const { return m_bottomVisualOverflow; }
- int leftVisualOverflow() const { return m_leftVisualOverflow; }
- int rightVisualOverflow() const { return m_rightVisualOverflow; }
+ int minYVisualOverflow() const { return m_minYVisualOverflow; }
+ int maxYVisualOverflow() const { return m_maxYVisualOverflow; }
+ int minXVisualOverflow() const { return m_minXVisualOverflow; }
+ int maxXVisualOverflow() const { return m_maxXVisualOverflow; }
IntRect visualOverflowRect() const;
- void setTopLayoutOverflow(int overflow) { m_topLayoutOverflow = overflow; }
- void setBottomLayoutOverflow(int overflow) { m_bottomLayoutOverflow = overflow; }
- void setLeftLayoutOverflow(int overflow) { m_leftLayoutOverflow = overflow; }
- void setRightLayoutOverflow(int overflow) { m_rightLayoutOverflow = overflow; }
+ void setMinYLayoutOverflow(int overflow) { m_minYLayoutOverflow = overflow; }
+ void setMaxYLayoutOverflow(int overflow) { m_maxYLayoutOverflow = overflow; }
+ void setMinXLayoutOverflow(int overflow) { m_minXLayoutOverflow = overflow; }
+ void setMaxXLayoutOverflow(int overflow) { m_maxXLayoutOverflow = overflow; }
- void setTopVisualOverflow(int overflow) { m_topVisualOverflow = overflow; }
- void setBottomVisualOverflow(int overflow) { m_bottomVisualOverflow = overflow; }
- void setLeftVisualOverflow(int overflow) { m_leftVisualOverflow = overflow; }
- void setRightVisualOverflow(int overflow) { m_rightVisualOverflow = overflow; }
+ void setMinYVisualOverflow(int overflow) { m_minYVisualOverflow = overflow; }
+ void setMaxYVisualOverflow(int overflow) { m_maxYVisualOverflow = overflow; }
+ void setMinXVisualOverflow(int overflow) { m_minXVisualOverflow = overflow; }
+ void setMaxXVisualOverflow(int overflow) { m_maxXVisualOverflow = overflow; }
void move(int dx, int dy);
@@ -85,78 +85,78 @@ public:
void resetLayoutOverflow(const IntRect& defaultRect);
private:
- int m_topLayoutOverflow;
- int m_bottomLayoutOverflow;
- int m_leftLayoutOverflow;
- int m_rightLayoutOverflow;
-
- int m_topVisualOverflow;
- int m_bottomVisualOverflow;
- int m_leftVisualOverflow;
- int m_rightVisualOverflow;
+ int m_minYLayoutOverflow;
+ int m_maxYLayoutOverflow;
+ int m_minXLayoutOverflow;
+ int m_maxXLayoutOverflow;
+
+ int m_minYVisualOverflow;
+ int m_maxYVisualOverflow;
+ int m_minXVisualOverflow;
+ int m_maxXVisualOverflow;
};
inline IntRect RenderOverflow::layoutOverflowRect() const
{
- return IntRect(m_leftLayoutOverflow, m_topLayoutOverflow, m_rightLayoutOverflow - m_leftLayoutOverflow, m_bottomLayoutOverflow - m_topLayoutOverflow);
+ return IntRect(m_minXLayoutOverflow, m_minYLayoutOverflow, m_maxXLayoutOverflow - m_minXLayoutOverflow, m_maxYLayoutOverflow - m_minYLayoutOverflow);
}
inline IntRect RenderOverflow::visualOverflowRect() const
{
- return IntRect(m_leftVisualOverflow, m_topVisualOverflow, m_rightVisualOverflow - m_leftVisualOverflow, m_bottomVisualOverflow - m_topVisualOverflow);
+ return IntRect(m_minXVisualOverflow, m_minYVisualOverflow, m_maxXVisualOverflow - m_minXVisualOverflow, m_maxYVisualOverflow - m_minYVisualOverflow);
}
inline void RenderOverflow::move(int dx, int dy)
{
- m_topLayoutOverflow += dy;
- m_bottomLayoutOverflow += dy;
- m_leftLayoutOverflow += dx;
- m_rightLayoutOverflow += dx;
+ m_minYLayoutOverflow += dy;
+ m_maxYLayoutOverflow += dy;
+ m_minXLayoutOverflow += dx;
+ m_maxXLayoutOverflow += dx;
- m_topVisualOverflow += dy;
- m_bottomVisualOverflow += dy;
- m_leftVisualOverflow += dx;
- m_rightVisualOverflow += dx;
+ m_minYVisualOverflow += dy;
+ m_maxYVisualOverflow += dy;
+ m_minXVisualOverflow += dx;
+ m_maxXVisualOverflow += dx;
}
inline void RenderOverflow::addLayoutOverflow(const IntRect& rect)
{
- m_topLayoutOverflow = std::min(rect.y(), m_topLayoutOverflow);
- m_bottomLayoutOverflow = std::max(rect.bottom(), m_bottomLayoutOverflow);
- m_leftLayoutOverflow = std::min(rect.x(), m_leftLayoutOverflow);
- m_rightLayoutOverflow = std::max(rect.right(), m_rightLayoutOverflow);
+ m_minYLayoutOverflow = std::min(rect.y(), m_minYLayoutOverflow);
+ m_maxYLayoutOverflow = std::max(rect.maxY(), m_maxYLayoutOverflow);
+ m_minXLayoutOverflow = std::min(rect.x(), m_minXLayoutOverflow);
+ m_maxXLayoutOverflow = std::max(rect.maxX(), m_maxXLayoutOverflow);
}
inline void RenderOverflow::addVisualOverflow(const IntRect& rect)
{
- m_topVisualOverflow = std::min(rect.y(), m_topVisualOverflow);
- m_bottomVisualOverflow = std::max(rect.bottom(), m_bottomVisualOverflow);
- m_leftVisualOverflow = std::min(rect.x(), m_leftVisualOverflow);
- m_rightVisualOverflow = std::max(rect.right(), m_rightVisualOverflow);
+ m_minYVisualOverflow = std::min(rect.y(), m_minYVisualOverflow);
+ m_maxYVisualOverflow = std::max(rect.maxY(), m_maxYVisualOverflow);
+ m_minXVisualOverflow = std::min(rect.x(), m_minXVisualOverflow);
+ m_maxXVisualOverflow = std::max(rect.maxX(), m_maxXVisualOverflow);
}
inline void RenderOverflow::setLayoutOverflow(const IntRect& rect)
{
- m_topLayoutOverflow = rect.y();
- m_bottomLayoutOverflow = rect.bottom();
- m_leftLayoutOverflow = rect.x();
- m_rightLayoutOverflow = rect.right();
+ m_minYLayoutOverflow = rect.y();
+ m_maxYLayoutOverflow = rect.maxY();
+ m_minXLayoutOverflow = rect.x();
+ m_maxXLayoutOverflow = rect.maxX();
}
inline void RenderOverflow::setVisualOverflow(const IntRect& rect)
{
- m_topVisualOverflow = rect.y();
- m_bottomVisualOverflow = rect.bottom();
- m_leftVisualOverflow = rect.x();
- m_rightVisualOverflow = rect.right();
+ m_minYVisualOverflow = rect.y();
+ m_maxYVisualOverflow = rect.maxY();
+ m_minXVisualOverflow = rect.x();
+ m_maxXVisualOverflow = rect.maxX();
}
inline void RenderOverflow::resetLayoutOverflow(const IntRect& rect)
{
- m_topLayoutOverflow = rect.y();
- m_bottomLayoutOverflow = rect.bottom();
- m_leftLayoutOverflow = rect.x();
- m_rightLayoutOverflow = rect.right();
+ m_minYLayoutOverflow = rect.y();
+ m_maxYLayoutOverflow = rect.maxY();
+ m_minXLayoutOverflow = rect.x();
+ m_maxXLayoutOverflow = rect.maxX();
}
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderProgress.cpp b/Source/WebCore/rendering/RenderProgress.cpp
index 4194e2b..2a8e6f3 100644
--- a/Source/WebCore/rendering/RenderProgress.cpp
+++ b/Source/WebCore/rendering/RenderProgress.cpp
@@ -36,6 +36,16 @@ using namespace std;
namespace WebCore {
+IntRect RenderProgressBarValuePart::preferredFrameRect()
+{
+ return toRenderProgress(parent())->valuePartRect();
+}
+
+bool RenderProgressBarValuePart::shouldBeHidden()
+{
+ return !toRenderProgress(parent())->shouldHaveParts();
+}
+
RenderProgress::RenderProgress(HTMLProgressElement* element)
: RenderIndicator(element)
, m_position(-1)
@@ -49,23 +59,10 @@ RenderProgress::RenderProgress(HTMLProgressElement* element)
RenderProgress::~RenderProgress()
{
- if (m_valuePart)
- m_valuePart->detach();
}
void RenderProgress::updateFromElement()
{
- if (!m_valuePart) {
- m_valuePart = ShadowBlockElement::createForPart(static_cast<HTMLElement*>(node()), PROGRESS_BAR_VALUE);
- if (m_valuePart->renderer())
- addChild(m_valuePart->renderer());
- }
-
- if (shouldHaveParts())
- style()->setAppearance(NoControlPart);
- else if (m_valuePart->renderer())
- m_valuePart->renderer()->style()->setVisibility(HIDDEN);
-
HTMLProgressElement* element = progressElement();
if (m_position == element->position())
return;
@@ -102,7 +99,8 @@ void RenderProgress::paint(PaintInfo& paintInfo, int tx, int ty)
void RenderProgress::layoutParts()
{
- m_valuePart->layoutAsPart(valuePartRect());
+ for (RenderObject* child = firstChild(); child; child = child->nextSibling())
+ child->layout();
updateAnimationState();
}
@@ -110,8 +108,6 @@ bool RenderProgress::shouldHaveParts() const
{
if (!style()->hasAppearance())
return true;
- if (ShadowBlockElement::partShouldHaveStyle(this, PROGRESS_BAR_VALUE))
- return true;
return false;
}
diff --git a/Source/WebCore/rendering/RenderProgress.h b/Source/WebCore/rendering/RenderProgress.h
index 9ed5741..78cf359 100644
--- a/Source/WebCore/rendering/RenderProgress.h
+++ b/Source/WebCore/rendering/RenderProgress.h
@@ -28,7 +28,14 @@
namespace WebCore {
class HTMLProgressElement;
-class ShadowBlockElement;
+
+class RenderProgressBarValuePart : public RenderIndicatorPart {
+public:
+ RenderProgressBarValuePart(Node* node) : RenderIndicatorPart(node) {}
+private:
+ virtual IntRect preferredFrameRect();
+ virtual bool shouldBeHidden();
+};
class RenderProgress : public RenderIndicator {
public:
@@ -40,6 +47,8 @@ public:
double animationStartTime() const { return m_animationStartTime; }
bool isDeterminate() const;
+ IntRect valuePartRect() const;
+ bool shouldHaveParts() const;
HTMLProgressElement* progressElement() const;
@@ -48,12 +57,8 @@ private:
virtual bool isProgress() const { return true; }
virtual void updateFromElement();
virtual void paint(PaintInfo&, int tx, int ty);
-
virtual void layoutParts();
- IntRect valuePartRect() const;
- bool shouldHaveParts() const;
-
void animationTimerFired(Timer<RenderProgress>*);
void updateAnimationState();
@@ -63,7 +68,6 @@ private:
double m_animationDuration;
bool m_animating;
Timer<RenderProgress> m_animationTimer;
- RefPtr<ShadowBlockElement> m_valuePart;
};
inline RenderProgress* toRenderProgress(RenderObject* object)
diff --git a/Source/WebCore/rendering/RenderReplaced.cpp b/Source/WebCore/rendering/RenderReplaced.cpp
index 0d72f95..c27d336 100644
--- a/Source/WebCore/rendering/RenderReplaced.cpp
+++ b/Source/WebCore/rendering/RenderReplaced.cpp
@@ -172,8 +172,8 @@ bool RenderReplaced::shouldPaint(PaintInfo& paintInfo, int& tx, int& ty)
int currentTY = ty + y();
// Early exit if the element touches the edges.
- int top = currentTY + topVisualOverflow();
- int bottom = currentTY + bottomVisualOverflow();
+ int top = currentTY + minYVisualOverflow();
+ int bottom = currentTY + maxYVisualOverflow();
if (isSelected() && m_inlineBoxWrapper) {
int selTop = ty + m_inlineBoxWrapper->root()->selectionTop();
int selBottom = ty + selTop + m_inlineBoxWrapper->root()->selectionHeight();
@@ -182,9 +182,9 @@ bool RenderReplaced::shouldPaint(PaintInfo& paintInfo, int& tx, int& ty)
}
int os = 2 * maximalOutlineSize(paintInfo.phase);
- if (currentTX + leftVisualOverflow() >= paintInfo.rect.right() + os || currentTX + rightVisualOverflow() <= paintInfo.rect.x() - os)
+ if (currentTX + minXVisualOverflow() >= paintInfo.rect.maxX() + os || currentTX + maxXVisualOverflow() <= paintInfo.rect.x() - os)
return false;
- if (top >= paintInfo.rect.bottom() + os || bottom <= paintInfo.rect.y() - os)
+ if (top >= paintInfo.rect.maxY() + os || bottom <= paintInfo.rect.y() - os)
return false;
return true;
diff --git a/Source/WebCore/rendering/RenderRubyRun.cpp b/Source/WebCore/rendering/RenderRubyRun.cpp
index c12e543..f2e30eb 100644
--- a/Source/WebCore/rendering/RenderRubyRun.cpp
+++ b/Source/WebCore/rendering/RenderRubyRun.cpp
@@ -42,7 +42,6 @@ namespace WebCore {
RenderRubyRun::RenderRubyRun(Node* node)
: RenderBlock(node)
- , m_beingDestroyed(false)
{
setReplaced(true);
setInline(true);
@@ -52,13 +51,6 @@ RenderRubyRun::~RenderRubyRun()
{
}
-void RenderRubyRun::destroy()
-{
- // Mark if the run is being destroyed to avoid trouble in removeChild().
- m_beingDestroyed = true;
- RenderBlock::destroy();
-}
-
bool RenderRubyRun::hasRubyText() const
{
// The only place where a ruby text can be is in the first position
@@ -165,7 +157,7 @@ void RenderRubyRun::removeChild(RenderObject* child)
{
// If the child is a ruby text, then merge the ruby base with the base of
// the right sibling run, if possible.
- if (!m_beingDestroyed && !documentBeingDestroyed() && child->isRubyText()) {
+ if (!beingDestroyed() && !documentBeingDestroyed() && child->isRubyText()) {
RenderRubyBase* base = rubyBase();
RenderObject* rightNeighbour = nextSibling();
if (base && rightNeighbour && rightNeighbour->isRubyRun()) {
@@ -184,7 +176,7 @@ void RenderRubyRun::removeChild(RenderObject* child)
RenderBlock::removeChild(child);
- if (!m_beingDestroyed && !documentBeingDestroyed()) {
+ if (!beingDestroyed() && !documentBeingDestroyed()) {
// Check if our base (if any) is now empty. If so, destroy it.
RenderBlock* base = rubyBase();
if (base && !base->firstChild()) {
diff --git a/Source/WebCore/rendering/RenderRubyRun.h b/Source/WebCore/rendering/RenderRubyRun.h
index d844bff..53209bc 100644
--- a/Source/WebCore/rendering/RenderRubyRun.h
+++ b/Source/WebCore/rendering/RenderRubyRun.h
@@ -46,8 +46,6 @@ public:
RenderRubyRun(Node*);
virtual ~RenderRubyRun();
- virtual void destroy();
-
bool hasRubyText() const;
bool hasRubyBase() const;
bool isEmpty() const;
@@ -75,8 +73,6 @@ private:
virtual const char* renderName() const { return "RenderRubyRun (anonymous)"; }
virtual bool createsAnonymousWrapper() const { return true; }
virtual void removeLeftoverAnonymousBlock(RenderBlock*) { }
-
- bool m_beingDestroyed;
};
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderScrollbarTheme.cpp b/Source/WebCore/rendering/RenderScrollbarTheme.cpp
index e32d87a..87309d4 100644
--- a/Source/WebCore/rendering/RenderScrollbarTheme.cpp
+++ b/Source/WebCore/rendering/RenderScrollbarTheme.cpp
@@ -98,10 +98,10 @@ IntRect RenderScrollbarTheme::constrainTrackRectToTrackPieces(Scrollbar* scrollb
IntRect result = rect;
if (scrollbar->orientation() == HorizontalScrollbar) {
result.setX(backRect.x());
- result.setWidth(forwardRect.right() - backRect.x());
+ result.setWidth(forwardRect.maxX() - backRect.x());
} else {
result.setY(backRect.y());
- result.setHeight(forwardRect.bottom() - backRect.y());
+ result.setHeight(forwardRect.maxY() - backRect.y());
}
return result;
}
diff --git a/Source/WebCore/rendering/RenderTable.cpp b/Source/WebCore/rendering/RenderTable.cpp
index 3fc1c72..bb90e97 100644
--- a/Source/WebCore/rendering/RenderTable.cpp
+++ b/Source/WebCore/rendering/RenderTable.cpp
@@ -168,7 +168,7 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
if (!wrapInAnonymousSection) {
// If the next renderer is actually wrapped in an anonymous table section, we need to go up and find that.
- while (beforeChild && !beforeChild->isTableSection() && !beforeChild->isTableCol() && beforeChild->style()->display() != TABLE_CAPTION)
+ while (beforeChild && beforeChild->parent() != this)
beforeChild = beforeChild->parent();
RenderBox::addChild(child, beforeChild);
@@ -419,7 +419,7 @@ void RenderTable::layout()
while (section) {
if (!sectionMoved && section->logicalTop() != logicalHeight()) {
sectionMoved = true;
- movedSectionLogicalTop = min(logicalHeight(), section->logicalTop()) + (style()->isHorizontalWritingMode() ? section->topVisualOverflow() : section->leftVisualOverflow());
+ movedSectionLogicalTop = min(logicalHeight(), section->logicalTop()) + (style()->isHorizontalWritingMode() ? section->minYVisualOverflow() : section->minXVisualOverflow());
}
section->setLogicalLocation(sectionLogicalLeft, logicalHeight());
@@ -453,15 +453,15 @@ void RenderTable::layout()
statePusher.pop();
if (view()->layoutState()->pageLogicalHeight())
- setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(y()));
+ setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(logicalTop()));
bool didFullRepaint = repainter.repaintAfterLayout();
// Repaint with our new bounds if they are different from our old bounds.
if (!didFullRepaint && sectionMoved) {
if (style()->isHorizontalWritingMode())
- repaintRectangle(IntRect(leftVisualOverflow(), movedSectionLogicalTop, rightVisualOverflow() - leftVisualOverflow(), bottomVisualOverflow() - movedSectionLogicalTop));
+ repaintRectangle(IntRect(minXVisualOverflow(), movedSectionLogicalTop, maxXVisualOverflow() - minXVisualOverflow(), maxYVisualOverflow() - movedSectionLogicalTop));
else
- repaintRectangle(IntRect(movedSectionLogicalTop, topVisualOverflow(), rightVisualOverflow() - movedSectionLogicalTop, bottomVisualOverflow() - topVisualOverflow()));
+ repaintRectangle(IntRect(movedSectionLogicalTop, minYVisualOverflow(), maxXVisualOverflow() - movedSectionLogicalTop, maxYVisualOverflow() - minYVisualOverflow()));
}
setNeedsLayout(false);
@@ -513,9 +513,9 @@ void RenderTable::paint(PaintInfo& paintInfo, int tx, int ty)
PaintPhase paintPhase = paintInfo.phase;
int os = 2 * maximalOutlineSize(paintPhase);
- if (ty + topVisualOverflow() >= paintInfo.rect.bottom() + os || ty + bottomVisualOverflow() <= paintInfo.rect.y() - os)
+ if (ty + minYVisualOverflow() >= paintInfo.rect.maxY() + os || ty + maxYVisualOverflow() <= paintInfo.rect.y() - os)
return;
- if (tx + leftVisualOverflow() >= paintInfo.rect.right() + os || tx + rightVisualOverflow() <= paintInfo.rect.x() - os)
+ if (tx + minXVisualOverflow() >= paintInfo.rect.maxX() + os || tx + maxXVisualOverflow() <= paintInfo.rect.x() - os)
return;
bool pushedClip = pushContentsClip(paintInfo, tx, ty);
@@ -1185,6 +1185,8 @@ int RenderTable::firstLineBoxBaseline() const
if (isWritingModeRoot())
return -1;
+ recalcSectionsIfNeeded();
+
RenderTableSection* firstNonEmptySection = m_head ? m_head : (m_firstBody ? m_firstBody : m_foot);
if (firstNonEmptySection && !firstNonEmptySection->numRows())
firstNonEmptySection = sectionBelow(firstNonEmptySection, true);
diff --git a/Source/WebCore/rendering/RenderTableCell.cpp b/Source/WebCore/rendering/RenderTableCell.cpp
index 8549f49..1593a5c 100644
--- a/Source/WebCore/rendering/RenderTableCell.cpp
+++ b/Source/WebCore/rendering/RenderTableCell.cpp
@@ -276,9 +276,9 @@ IntRect RenderTableCell::clippedOverflowRectForRepaint(RenderBoxModelObject* rep
right = max(right, below->borderHalfRight(true));
}
}
- left = max(left, -leftVisualOverflow());
- top = max(top, -topVisualOverflow());
- IntRect r(-left, - top, left + max(width() + right, rightVisualOverflow()), top + max(height() + bottom, bottomVisualOverflow()));
+ left = max(left, -minXVisualOverflow());
+ top = max(top, -minYVisualOverflow());
+ IntRect r(-left, - top, left + max(width() + right, maxXVisualOverflow()), top + max(height() + bottom, maxYVisualOverflow()));
if (RenderView* v = view()) {
// FIXME: layoutDelta needs to be applied in parts before/after transforms and
@@ -812,8 +812,8 @@ void RenderTableCell::paint(PaintInfo& paintInfo, int tx, int ty)
tx += x();
ty += y();
int os = 2 * maximalOutlineSize(paintInfo.phase);
- if (ty - table()->outerBorderTop() < paintInfo.rect.bottom() + os &&
- ty + height() + table()->outerBorderBottom() > paintInfo.rect.y() - os)
+ if (ty - table()->outerBorderTop() < paintInfo.rect.maxY() + os
+ && ty + height() + table()->outerBorderBottom() > paintInfo.rect.y() - os)
paintCollapsedBorder(paintInfo.context, tx, ty, width(), height());
return;
}
diff --git a/Source/WebCore/rendering/RenderTableRow.cpp b/Source/WebCore/rendering/RenderTableRow.cpp
index 595e156..7300c19 100644
--- a/Source/WebCore/rendering/RenderTableRow.cpp
+++ b/Source/WebCore/rendering/RenderTableRow.cpp
@@ -125,7 +125,7 @@ void RenderTableRow::layout()
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
if (child->isTableCell()) {
RenderTableCell* cell = toRenderTableCell(child);
- if (!cell->needsLayout() && paginated && view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(cell->y()) != cell->pageLogicalOffset())
+ if (!cell->needsLayout() && paginated && view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(cell->logicalTop()) != cell->pageLogicalOffset())
cell->setChildNeedsLayout(true, false);
if (child->needsLayout()) {
diff --git a/Source/WebCore/rendering/RenderTableSection.cpp b/Source/WebCore/rendering/RenderTableSection.cpp
index 265d2ef..f20c236 100644
--- a/Source/WebCore/rendering/RenderTableSection.cpp
+++ b/Source/WebCore/rendering/RenderTableSection.cpp
@@ -704,7 +704,7 @@ int RenderTableSection::layoutRows(int toAdd)
if (intrinsicPaddingBefore != oldIntrinsicPaddingBefore || intrinsicPaddingAfter != oldIntrinsicPaddingAfter)
cell->setNeedsLayout(true, false);
- if (!cell->needsLayout() && view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(cell->y()) != cell->pageLogicalOffset())
+ if (!cell->needsLayout() && view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(cell->logicalTop()) != cell->pageLogicalOffset())
cell->setChildNeedsLayout(true, false);
cell->layoutIfNeeded();
@@ -1068,9 +1068,9 @@ void RenderTableSection::paintObject(PaintInfo& paintInfo, int tx, int ty)
localRepaintRect.move(-tx, -ty);
if (style()->isFlippedBlocksWritingMode()) {
if (style()->isHorizontalWritingMode())
- localRepaintRect.setY(height() - localRepaintRect.bottom());
+ localRepaintRect.setY(height() - localRepaintRect.maxY());
else
- localRepaintRect.setX(width() - localRepaintRect.right());
+ localRepaintRect.setX(width() - localRepaintRect.maxX());
}
// If some cell overflows, just paint all of them.
@@ -1085,7 +1085,7 @@ void RenderTableSection::paintObject(PaintInfo& paintInfo, int tx, int ty)
if (startrow == m_rowPos.size() || (startrow > 0 && (m_rowPos[startrow] > before)))
--startrow;
- int after = (style()->isHorizontalWritingMode() ? localRepaintRect.bottom() : localRepaintRect.right()) + os;
+ int after = (style()->isHorizontalWritingMode() ? localRepaintRect.maxY() : localRepaintRect.maxX()) + os;
endrow = std::lower_bound(m_rowPos.begin(), m_rowPos.end(), after) - m_rowPos.begin();
if (endrow == m_rowPos.size())
--endrow;
@@ -1104,7 +1104,7 @@ void RenderTableSection::paintObject(PaintInfo& paintInfo, int tx, int ty)
if ((startcol == columnPos.size()) || (startcol > 0 && (columnPos[startcol] > start)))
--startcol;
- int end = (style()->isHorizontalWritingMode() ? localRepaintRect.right() : localRepaintRect.bottom()) + os;
+ int end = (style()->isHorizontalWritingMode() ? localRepaintRect.maxX() : localRepaintRect.maxY()) + os;
endcol = std::lower_bound(columnPos.begin(), columnPos.end(), end) - columnPos.begin();
if (endcol == columnPos.size())
--endcol;
diff --git a/Source/WebCore/rendering/RenderText.cpp b/Source/WebCore/rendering/RenderText.cpp
index 86b32d5..1b05af2 100644
--- a/Source/WebCore/rendering/RenderText.cpp
+++ b/Source/WebCore/rendering/RenderText.cpp
@@ -26,7 +26,6 @@
#include "RenderText.h"
#include "AXObjectCache.h"
-#include "CharacterNames.h"
#include "EllipsisBox.h"
#include "FloatQuad.h"
#include "FontTranscoder.h"
@@ -35,6 +34,7 @@
#include "Range.h"
#include "RenderArena.h"
#include "RenderBlock.h"
+#include "RenderCombineText.h"
#include "RenderLayer.h"
#include "RenderView.h"
#include "Text.h"
@@ -45,6 +45,7 @@
#include "break_lines.h"
#include <wtf/AlwaysInline.h>
#include <wtf/text/StringBuffer.h>
+#include <wtf/unicode/CharacterNames.h>
using namespace std;
using namespace WTF;
@@ -345,8 +346,12 @@ void RenderText::absoluteQuads(Vector<FloatQuad>& quads, ClippingOption option)
// Shorten the width of this text box if it ends in an ellipsis.
IntRect ellipsisRect = (option == ClipToEllipsis) ? ellipsisRectForBox(box, 0, textLength()) : IntRect();
- if (!ellipsisRect.isEmpty())
- boundaries.setWidth(ellipsisRect.right() - boundaries.x());
+ if (!ellipsisRect.isEmpty()) {
+ if (style()->isHorizontalWritingMode())
+ boundaries.setWidth(ellipsisRect.maxX() - boundaries.x());
+ else
+ boundaries.setHeight(ellipsisRect.maxY() - boundaries.y());
+ }
quads.append(localToAbsoluteQuad(FloatRect(boundaries)));
}
}
@@ -374,8 +379,13 @@ void RenderText::absoluteQuadsForRange(Vector<FloatQuad>& quads, unsigned start,
IntRect r(box->calculateBoundaries());
if (useSelectionHeight) {
IntRect selectionRect = box->selectionRect(0, 0, start, end);
- r.setHeight(selectionRect.height());
- r.setY(selectionRect.y());
+ if (box->isHorizontal()) {
+ r.setHeight(selectionRect.height());
+ r.setY(selectionRect.y());
+ } else {
+ r.setWidth(selectionRect.width());
+ r.setX(selectionRect.x());
+ }
}
quads.append(localToAbsoluteQuad(FloatRect(r)));
} else {
@@ -384,8 +394,13 @@ void RenderText::absoluteQuadsForRange(Vector<FloatQuad>& quads, unsigned start,
if (r.height()) {
if (!useSelectionHeight) {
// change the height and y position because selectionRect uses selection-specific values
- r.setHeight(box->logicalHeight());
- r.setY(box->y());
+ if (box->isHorizontal()) {
+ r.setHeight(box->logicalHeight());
+ r.setY(box->y());
+ } else {
+ r.setWidth(box->logicalHeight());
+ r.setX(box->x());
+ }
}
quads.append(localToAbsoluteQuad(FloatRect(r)));
}
@@ -547,6 +562,12 @@ IntRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, int* e
ALWAYS_INLINE int RenderText::widthFromCache(const Font& f, int start, int len, int xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
{
+ if (style()->hasTextCombine()) {
+ const RenderCombineText* combineText = toRenderCombineText(this);
+ if (combineText->isCombined())
+ return combineText->combinedTextWidth(f);
+ }
+
if (f.isFixedPitch() && !f.isSmallCaps() && m_isAllASCII) {
int monospaceCharacterWidth = f.spaceWidth();
int tabWidth = allowTabs() ? monospaceCharacterWidth * 8 : 0;
diff --git a/Source/WebCore/rendering/RenderTextControl.cpp b/Source/WebCore/rendering/RenderTextControl.cpp
index cac8113..72b20ec 100644
--- a/Source/WebCore/rendering/RenderTextControl.cpp
+++ b/Source/WebCore/rendering/RenderTextControl.cpp
@@ -23,7 +23,6 @@
#include "RenderTextControl.h"
#include "AXObjectCache.h"
-#include "CharacterNames.h"
#include "Editor.h"
#include "Event.h"
#include "EventNames.h"
@@ -42,6 +41,7 @@
#include "TextControlInnerElements.h"
#include "TextIterator.h"
#include "TextRun.h"
+#include <wtf/unicode/CharacterNames.h>
using namespace std;
@@ -146,7 +146,7 @@ void RenderTextControl::createSubtreeIfNeeded(TextControlInnerElement* innerBloc
// For non-search fields, there is no intermediate innerBlock as the shadow node.
// m_innerText will be the shadow node in that case.
RenderStyle* parentStyle = innerBlock ? innerBlock->renderer()->style() : style();
- m_innerText = TextControlInnerTextElement::create(document(), innerBlock ? 0 : static_cast<HTMLElement*>(node()));
+ m_innerText = TextControlInnerTextElement::create(document(), innerBlock ? 0 : toHTMLElement(node()));
m_innerText->attachInnerElement(innerBlock ? innerBlock : node(), createInnerTextStyle(parentStyle), renderArena());
}
}
@@ -544,7 +544,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, false, false, false));
+ return style()->font().floatWidth(TextRun(&ch, 1, false, 0, 0, TextRun::AllowTrailingExpansion, false, false, false));
}
float RenderTextControl::scaleEmToUnits(int x) const
@@ -639,12 +639,12 @@ 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(), 0, 0, 0, !placeholderStyle->isLeftToRightDirection(), placeholderStyle->unicodeBidi() == Override, false, false);
+ TextRun textRun(placeholderText.characters(), placeholderText.length(), false, 0, 0, TextRun::AllowTrailingExpansion, !placeholderStyle->isLeftToRightDirection(), placeholderStyle->unicodeBidi() == Override, false, false);
RenderBox* textRenderer = innerTextElement() ? innerTextElement()->renderBox() : 0;
if (textRenderer) {
IntPoint textPoint;
- textPoint.setY(ty + textBlockInsetTop() + placeholderStyle->font().ascent());
+ textPoint.setY(ty + textBlockInsetTop() + placeholderStyle->fontMetrics().ascent());
if (placeholderStyle->isLeftToRightDirection())
textPoint.setX(tx + textBlockInsetLeft());
else
diff --git a/Source/WebCore/rendering/RenderTextControlMultiLine.cpp b/Source/WebCore/rendering/RenderTextControlMultiLine.cpp
index d0b0cbc..cf32f68 100644
--- a/Source/WebCore/rendering/RenderTextControlMultiLine.cpp
+++ b/Source/WebCore/rendering/RenderTextControlMultiLine.cpp
@@ -41,7 +41,7 @@ RenderTextControlMultiLine::RenderTextControlMultiLine(Node* node, bool placehol
RenderTextControlMultiLine::~RenderTextControlMultiLine()
{
- if (node())
+ if (node() && node()->inDocument())
static_cast<HTMLTextAreaElement*>(node())->rendererWillBeDestroyed();
}
diff --git a/Source/WebCore/rendering/RenderTextControlSingleLine.cpp b/Source/WebCore/rendering/RenderTextControlSingleLine.cpp
index 95f209a..de8fb0d 100644
--- a/Source/WebCore/rendering/RenderTextControlSingleLine.cpp
+++ b/Source/WebCore/rendering/RenderTextControlSingleLine.cpp
@@ -397,7 +397,7 @@ void RenderTextControlSingleLine::forwardEvent(Event* event)
#endif
FloatPoint localPoint = innerTextRenderer->absoluteToLocal(static_cast<MouseEvent*>(event)->absoluteLocation(), false, true);
- int textRight = innerTextRenderer->borderBoxRect().right();
+ int textRight = innerTextRenderer->borderBoxRect().maxX();
if (m_resultsButton && localPoint.x() < innerTextRenderer->borderBoxRect().x())
m_resultsButton->defaultEventHandler(event);
@@ -564,9 +564,6 @@ int RenderTextControlSingleLine::preferredContentWidth(float charWidth) const
result += cancelRenderer->borderLeft() + cancelRenderer->borderRight() +
cancelRenderer->paddingLeft() + cancelRenderer->paddingRight();
- if (RenderBox* spinRenderer = m_innerSpinButton ? m_innerSpinButton->renderBox() : 0)
- result += spinRenderer->minPreferredLogicalWidth();
-
#if ENABLE(INPUT_SPEECH)
if (RenderBox* speechRenderer = m_speechButton ? m_speechButton->renderBox() : 0) {
result += speechRenderer->borderLeft() + speechRenderer->borderRight() +
@@ -618,17 +615,17 @@ void RenderTextControlSingleLine::createSubtreeIfNeeded()
#if ENABLE(INPUT_SPEECH)
if (inputElement()->isSpeechEnabled() && !m_speechButton) {
// Create the speech button element.
- m_speechButton = InputFieldSpeechButtonElement::create(static_cast<HTMLElement*>(node()));
+ 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(static_cast<HTMLElement*>(node()));
+ m_innerSpinButton = SpinButtonElement::create(toHTMLElement(node()));
m_innerSpinButton->attachInnerElement(node(), createInnerSpinButtonStyle(), renderArena());
}
if (hasSpinButton && !m_outerSpinButton) {
- m_outerSpinButton = SpinButtonElement::create(static_cast<HTMLElement*>(node()));
+ m_outerSpinButton = SpinButtonElement::create(toHTMLElement(node()));
m_outerSpinButton->attachInnerElement(node(), createOuterSpinButtonStyle(), renderArena());
}
return;
@@ -636,18 +633,18 @@ void RenderTextControlSingleLine::createSubtreeIfNeeded()
if (!m_innerBlock) {
// Create the inner block element
- m_innerBlock = TextControlInnerElement::create(static_cast<HTMLElement*>(node()));
+ 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(static_cast<HTMLElement*>(node()));
+ m_speechButton = InputFieldSpeechButtonElement::create(toHTMLElement(node()));
m_speechButton->attachInnerElement(node(), createSpeechButtonStyle(), renderArena());
}
#endif
if (inputElement()->hasSpinButton() && !m_outerSpinButton) {
- m_outerSpinButton = SpinButtonElement::create(static_cast<HTMLElement*>(node()));
+ m_outerSpinButton = SpinButtonElement::create(toHTMLElement(node()));
m_outerSpinButton->attachInnerElement(node(), createOuterSpinButtonStyle(), renderArena());
}
@@ -687,7 +684,7 @@ void RenderTextControlSingleLine::updateFromElement()
// flag is false. It protects an unacceptable renderer value from
// being overwritten with the DOM value.
if (!static_cast<HTMLInputElement*>(node())->formControlValueMatchesRenderer())
- setInnerTextValue(inputElement()->value());
+ setInnerTextValue(inputElement()->visibleValue());
}
}
@@ -712,7 +709,7 @@ PassRefPtr<RenderStyle> RenderTextControlSingleLine::createInnerTextStyle(const
textBlockStyle->setOverflowY(OHIDDEN);
// Do not allow line-height to be smaller than our default.
- if (textBlockStyle->font().lineSpacing() > lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes))
+ if (textBlockStyle->fontMetrics().lineSpacing() > lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes))
textBlockStyle->setLineHeight(Length(-100.0f, Percent));
WebCore::EDisplay display = (m_innerBlock || inputElement()->hasSpinButton() ? INLINE_BLOCK : BLOCK);
@@ -931,7 +928,7 @@ PopupMenuStyle RenderTextControlSingleLine::itemStyle(unsigned) const
PopupMenuStyle RenderTextControlSingleLine::menuStyle() const
{
- return PopupMenuStyle(style()->visitedDependentColor(CSSPropertyColor), style()->visitedDependentColor(CSSPropertyBackgroundColor), style()->font(), style()->visibility() == VISIBLE, style()->display() == NONE, style()->textIndent(), style()->direction());
+ return PopupMenuStyle(style()->visitedDependentColor(CSSPropertyColor), style()->visitedDependentColor(CSSPropertyBackgroundColor), style()->font(), style()->visibility() == VISIBLE, style()->display() == NONE, style()->textIndent(), style()->direction(), style()->unicodeBidi() == Override);
}
int RenderTextControlSingleLine::clientInsetLeft() const
diff --git a/Source/WebCore/rendering/RenderTheme.h b/Source/WebCore/rendering/RenderTheme.h
index 13c69e6..e2b9c78 100644
--- a/Source/WebCore/rendering/RenderTheme.h
+++ b/Source/WebCore/rendering/RenderTheme.h
@@ -180,6 +180,7 @@ public:
// Media controls
virtual bool hitTestMediaControlPart(RenderObject*, const IntPoint& absPoint);
virtual bool shouldRenderMediaControlPart(ControlPart, Element*);
+ virtual bool usesMediaControlStatusDisplay() { return false; }
virtual double mediaControlsFadeInDuration() { return 0.1; }
virtual double mediaControlsFadeOutDuration() { return 0.3; }
virtual String formatMediaControlsTime(float time) const;
@@ -194,6 +195,8 @@ public:
virtual IntSize meterSizeForBounds(const RenderMeter*, const IntRect&) const;
virtual bool supportsMeter(ControlPart, bool isHorizontal) const;
#endif
+
+ virtual bool shouldShowPlaceholderWhenFocused() const { return false; }
protected:
// The platform selection color.
diff --git a/Source/WebCore/rendering/RenderThemeChromiumMac.h b/Source/WebCore/rendering/RenderThemeChromiumMac.h
index d1875fc..80bbae4 100644
--- a/Source/WebCore/rendering/RenderThemeChromiumMac.h
+++ b/Source/WebCore/rendering/RenderThemeChromiumMac.h
@@ -46,6 +46,7 @@ protected:
virtual bool paintMediaVolumeSliderTrack(RenderObject*, const PaintInfo&, const IntRect&);
virtual bool paintMediaVolumeSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
virtual IntPoint volumeSliderOffsetFromMuteButton(Node*, const IntSize&) const;
+ virtual bool usesMediaControlStatusDisplay() { return false; }
#endif
diff --git a/Source/WebCore/rendering/RenderThemeChromiumWin.cpp b/Source/WebCore/rendering/RenderThemeChromiumWin.cpp
index bba0520..d538050 100644
--- a/Source/WebCore/rendering/RenderThemeChromiumWin.cpp
+++ b/Source/WebCore/rendering/RenderThemeChromiumWin.cpp
@@ -479,15 +479,15 @@ bool RenderThemeChromiumWin::paintMenuList(RenderObject* o, const PaintInfo& i,
int spacingBottom = borderBottom + box->paddingBottom();
int buttonX;
- if (r.right() - r.x() < buttonWidth)
+ if (r.maxX() - r.x() < buttonWidth)
buttonX = r.x();
else
- buttonX = o->style()->direction() == LTR ? r.right() - spacingRight - buttonWidth : r.x() + spacingLeft;
+ buttonX = o->style()->direction() == LTR ? r.maxX() - spacingRight - buttonWidth : r.x() + spacingLeft;
// Compute the rectangle of the button in the destination image.
IntRect rect(buttonX,
r.y() + spacingTop,
- std::min(buttonWidth, r.right() - r.x()),
+ std::min(buttonWidth, r.maxX() - r.x()),
r.height() - (spacingTop + spacingBottom));
// Get the correct theme data for a textfield and paint the menu.
diff --git a/Source/WebCore/rendering/RenderThemeMac.h b/Source/WebCore/rendering/RenderThemeMac.h
index 95661b8..9837c2a 100644
--- a/Source/WebCore/rendering/RenderThemeMac.h
+++ b/Source/WebCore/rendering/RenderThemeMac.h
@@ -164,9 +164,12 @@ protected:
virtual String extraMediaControlsStyleSheet();
virtual bool shouldRenderMediaControlPart(ControlPart, Element*);
+ virtual bool usesMediaControlStatusDisplay();
virtual void adjustMediaSliderThumbSize(RenderObject*) const;
virtual IntPoint volumeSliderOffsetFromMuteButton(Node*, const IntSize&) const;
#endif
+
+ virtual bool shouldShowPlaceholderWhenFocused() const;
private:
diff --git a/Source/WebCore/rendering/RenderThemeMac.mm b/Source/WebCore/rendering/RenderThemeMac.mm
index 605e958..e3c75c5 100644
--- a/Source/WebCore/rendering/RenderThemeMac.mm
+++ b/Source/WebCore/rendering/RenderThemeMac.mm
@@ -1041,20 +1041,20 @@ void RenderThemeMac::paintMenuListButtonGradients(RenderObject* o, const PaintIn
FloatRect topGradient(r.x(), r.y(), r.width(), r.height() / 2.0f);
struct CGFunctionCallbacks topCallbacks = { 0, TopGradientInterpolate, NULL };
RetainPtr<CGFunctionRef> topFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &topCallbacks));
- RetainPtr<CGShadingRef> topShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(topGradient.x(), topGradient.y()), CGPointMake(topGradient.x(), topGradient.bottom()), topFunction.get(), false, false));
+ RetainPtr<CGShadingRef> topShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(topGradient.x(), topGradient.y()), CGPointMake(topGradient.x(), topGradient.maxY()), topFunction.get(), false, false));
FloatRect bottomGradient(r.x() + radius, r.y() + r.height() / 2.0f, r.width() - 2.0f * radius, r.height() / 2.0f);
struct CGFunctionCallbacks bottomCallbacks = { 0, BottomGradientInterpolate, NULL };
RetainPtr<CGFunctionRef> bottomFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &bottomCallbacks));
- RetainPtr<CGShadingRef> bottomShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(bottomGradient.x(), bottomGradient.y()), CGPointMake(bottomGradient.x(), bottomGradient.bottom()), bottomFunction.get(), false, false));
+ RetainPtr<CGShadingRef> bottomShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(bottomGradient.x(), bottomGradient.y()), CGPointMake(bottomGradient.x(), bottomGradient.maxY()), bottomFunction.get(), false, false));
struct CGFunctionCallbacks mainCallbacks = { 0, MainGradientInterpolate, NULL };
RetainPtr<CGFunctionRef> mainFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &mainCallbacks));
- RetainPtr<CGShadingRef> mainShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.x(), r.y()), CGPointMake(r.x(), r.bottom()), mainFunction.get(), false, false));
+ RetainPtr<CGShadingRef> mainShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.x(), r.y()), CGPointMake(r.x(), r.maxY()), mainFunction.get(), false, false));
RetainPtr<CGShadingRef> leftShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.x(), r.y()), CGPointMake(r.x() + radius, r.y()), mainFunction.get(), false, false));
- RetainPtr<CGShadingRef> rightShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.right(), r.y()), CGPointMake(r.right() - radius, r.y()), mainFunction.get(), false, false));
+ RetainPtr<CGShadingRef> rightShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.maxX(), r.y()), CGPointMake(r.maxX() - radius, r.y()), mainFunction.get(), false, false));
paintInfo.context->save();
CGContextClipToRect(context, r);
paintInfo.context->addRoundedRectClip(border);
@@ -1099,7 +1099,7 @@ bool RenderThemeMac::paintMenuListButton(RenderObject* o, const PaintInfo& paint
float centerY = bounds.y() + bounds.height() / 2.0f;
float arrowHeight = baseArrowHeight * fontScale;
float arrowWidth = baseArrowWidth * fontScale;
- float leftEdge = bounds.right() - arrowPaddingRight * o->style()->effectiveZoom() - arrowWidth;
+ float leftEdge = bounds.maxX() - arrowPaddingRight * o->style()->effectiveZoom() - arrowWidth;
float spaceBetweenArrows = baseSpaceBetweenArrows * fontScale;
if (bounds.width() < arrowWidth + arrowPaddingLeft * o->style()->effectiveZoom())
@@ -1138,11 +1138,11 @@ bool RenderThemeMac::paintMenuListButton(RenderObject* o, const PaintInfo& paint
paintInfo.context->setStrokeStyle(SolidStroke);
paintInfo.context->setStrokeColor(leftSeparatorColor, ColorSpaceDeviceRGB);
paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator, bounds.y()),
- IntPoint(leftEdgeOfSeparator, bounds.bottom()));
+ IntPoint(leftEdgeOfSeparator, bounds.maxY()));
paintInfo.context->setStrokeColor(rightSeparatorColor, ColorSpaceDeviceRGB);
paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.y()),
- IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.bottom()));
+ IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.maxY()));
paintInfo.context->restore();
return false;
@@ -1293,9 +1293,9 @@ bool RenderThemeMac::paintSliderTrack(RenderObject* o, const PaintInfo& paintInf
RetainPtr<CGFunctionRef> mainFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &mainCallbacks));
RetainPtr<CGShadingRef> mainShading;
if (o->style()->appearance() == SliderVerticalPart)
- mainShading.adoptCF(CGShadingCreateAxial(cspace, CGPointMake(bounds.x(), bounds.bottom()), CGPointMake(bounds.right(), bounds.bottom()), mainFunction.get(), false, false));
+ mainShading.adoptCF(CGShadingCreateAxial(cspace, CGPointMake(bounds.x(), bounds.maxY()), CGPointMake(bounds.maxX(), bounds.maxY()), mainFunction.get(), false, false));
else
- mainShading.adoptCF(CGShadingCreateAxial(cspace, CGPointMake(bounds.x(), bounds.y()), CGPointMake(bounds.x(), bounds.bottom()), mainFunction.get(), false, false));
+ mainShading.adoptCF(CGShadingCreateAxial(cspace, CGPointMake(bounds.x(), bounds.y()), CGPointMake(bounds.x(), bounds.maxY()), mainFunction.get(), false, false));
IntSize radius(trackRadius, trackRadius);
paintInfo.context->addRoundedRectClip(RoundedIntRect(bounds, radius, radius, radius, radius));
@@ -1981,6 +1981,11 @@ bool RenderThemeMac::shouldRenderMediaControlPart(ControlPart part, Element* ele
return RenderTheme::shouldRenderMediaControlPart(part, element);
}
+bool RenderThemeMac::usesMediaControlStatusDisplay()
+{
+ return mediaControllerTheme() == MediaControllerThemeQuickTime;
+}
+
IntPoint RenderThemeMac::volumeSliderOffsetFromMuteButton(Node* muteButton, const IntSize& size) const
{
static const int xOffset = -4;
@@ -1994,6 +1999,15 @@ IntPoint RenderThemeMac::volumeSliderOffsetFromMuteButton(Node* muteButton, cons
return IntPoint(xOffset * zoomLevel, y);
}
+bool RenderThemeMac::shouldShowPlaceholderWhenFocused() const
+{
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
+ return true;
+#else
+ return false;
+#endif
+}
+
#endif // ENABLE(VIDEO)
NSPopUpButtonCell* RenderThemeMac::popupButton() const
diff --git a/Source/WebCore/rendering/RenderThemeSafari.cpp b/Source/WebCore/rendering/RenderThemeSafari.cpp
index 47f627e..a2f9ed1 100644
--- a/Source/WebCore/rendering/RenderThemeSafari.cpp
+++ b/Source/WebCore/rendering/RenderThemeSafari.cpp
@@ -760,20 +760,20 @@ void RenderThemeSafari::paintMenuListButtonGradients(RenderObject* o, const Pain
FloatRect topGradient(r.x(), r.y(), r.width(), r.height() / 2.0f);
struct CGFunctionCallbacks topCallbacks = { 0, TopGradientInterpolate, NULL };
RetainPtr<CGFunctionRef> topFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &topCallbacks));
- RetainPtr<CGShadingRef> topShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(topGradient.x(), topGradient.y()), CGPointMake(topGradient.x(), topGradient.bottom()), topFunction.get(), false, false));
+ RetainPtr<CGShadingRef> topShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(topGradient.x(), topGradient.y()), CGPointMake(topGradient.x(), topGradient.maxY()), topFunction.get(), false, false));
FloatRect bottomGradient(r.x() + radius, r.y() + r.height() / 2.0f, r.width() - 2.0f * radius, r.height() / 2.0f);
struct CGFunctionCallbacks bottomCallbacks = { 0, BottomGradientInterpolate, NULL };
RetainPtr<CGFunctionRef> bottomFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &bottomCallbacks));
- RetainPtr<CGShadingRef> bottomShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(bottomGradient.x(), bottomGradient.y()), CGPointMake(bottomGradient.x(), bottomGradient.bottom()), bottomFunction.get(), false, false));
+ RetainPtr<CGShadingRef> bottomShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(bottomGradient.x(), bottomGradient.y()), CGPointMake(bottomGradient.x(), bottomGradient.maxY()), bottomFunction.get(), false, false));
struct CGFunctionCallbacks mainCallbacks = { 0, MainGradientInterpolate, NULL };
RetainPtr<CGFunctionRef> mainFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &mainCallbacks));
- RetainPtr<CGShadingRef> mainShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.x(), r.y()), CGPointMake(r.x(), r.bottom()), mainFunction.get(), false, false));
+ RetainPtr<CGShadingRef> mainShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.x(), r.y()), CGPointMake(r.x(), r.maxY()), mainFunction.get(), false, false));
RetainPtr<CGShadingRef> leftShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.x(), r.y()), CGPointMake(r.x() + radius, r.y()), mainFunction.get(), false, false));
- RetainPtr<CGShadingRef> rightShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.right(), r.y()), CGPointMake(r.right() - radius, r.y()), mainFunction.get(), false, false));
+ RetainPtr<CGShadingRef> rightShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.maxX(), r.y()), CGPointMake(r.maxX() - radius, r.y()), mainFunction.get(), false, false));
paintInfo.context->save();
CGContextClipToRect(context, bound.rect());
paintInfo.context->addRoundedRectClip(bound);
@@ -818,7 +818,7 @@ bool RenderThemeSafari::paintMenuListButton(RenderObject* o, const PaintInfo& pa
float centerY = bounds.y() + bounds.height() / 2.0f;
float arrowHeight = baseArrowHeight * fontScale;
float arrowWidth = baseArrowWidth * fontScale;
- float leftEdge = bounds.right() - arrowPaddingRight - arrowWidth;
+ float leftEdge = bounds.maxX() - arrowPaddingRight - arrowWidth;
if (bounds.width() < arrowWidth + arrowPaddingLeft)
return false;
@@ -848,11 +848,11 @@ bool RenderThemeSafari::paintMenuListButton(RenderObject* o, const PaintInfo& pa
paintInfo.context->setStrokeStyle(SolidStroke);
paintInfo.context->setStrokeColor(leftSeparatorColor, ColorSpaceDeviceRGB);
paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator, bounds.y()),
- IntPoint(leftEdgeOfSeparator, bounds.bottom()));
+ IntPoint(leftEdgeOfSeparator, bounds.maxY()));
paintInfo.context->setStrokeColor(rightSeparatorColor, ColorSpaceDeviceRGB);
paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.y()),
- IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.bottom()));
+ IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.maxY()));
paintInfo.context->restore();
return false;
@@ -976,9 +976,9 @@ bool RenderThemeSafari::paintSliderTrack(RenderObject* o, const PaintInfo& paint
RetainPtr<CGFunctionRef> mainFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &mainCallbacks));
RetainPtr<CGShadingRef> mainShading;
if (o->style()->appearance() == SliderVerticalPart)
- mainShading.adoptCF(CGShadingCreateAxial(cspace, CGPointMake(bounds.rect().x(), bounds.rect().bottom()), CGPointMake(bounds.rect().right(), bounds.rect().bottom()), mainFunction.get(), false, false));
+ mainShading.adoptCF(CGShadingCreateAxial(cspace, CGPointMake(bounds.rect().x(), bounds.rect().maxY()), CGPointMake(bounds.rect().maxX(), bounds.rect().maxY()), mainFunction.get(), false, false));
else
- mainShading.adoptCF(CGShadingCreateAxial(cspace, CGPointMake(bounds.rect().x(), bounds.rect().y()), CGPointMake(bounds.rect().x(), bounds.rect().bottom()), mainFunction.get(), false, false));
+ mainShading.adoptCF(CGShadingCreateAxial(cspace, CGPointMake(bounds.rect().x(), bounds.rect().y()), CGPointMake(bounds.rect().x(), bounds.rect().maxY()), mainFunction.get(), false, false));
paintInfo.context->addRoundedRectClip(bounds);
CGContextDrawShading(context, mainShading.get());
diff --git a/Source/WebCore/rendering/RenderThemeWin.cpp b/Source/WebCore/rendering/RenderThemeWin.cpp
index f0f8268..5581db8 100644
--- a/Source/WebCore/rendering/RenderThemeWin.cpp
+++ b/Source/WebCore/rendering/RenderThemeWin.cpp
@@ -27,6 +27,7 @@
#include "Frame.h"
#include "GraphicsContext.h"
#include "LocalWindowsContext.h"
+#include "PaintInfo.h"
#include "RenderSlider.h"
#include "Settings.h"
#include "SoftLinking.h"
@@ -694,7 +695,7 @@ bool RenderThemeWin::paintInnerSpinButton(RenderObject* o, const PaintInfo& i, c
IntRect upRect(r);
upRect.setHeight(r.height() / 2);
IntRect downRect(r);
- downRect.setY(upRect.bottom());
+ downRect.setY(upRect.maxY());
downRect.setHeight(r.height() - upRect.height());
drawControl(i.context, o, spinButtonTheme(), getThemeData(o, SpinButtonUp), upRect);
drawControl(i.context, o, spinButtonTheme(), getThemeData(o, SpinButtonDown), downRect);
@@ -769,7 +770,7 @@ void RenderThemeWin::adjustMenuListButtonStyle(CSSStyleSelector* selector, Rende
style->setHeight(Length(Auto));
// Calculate our min-height
- int minHeight = style->font().height();
+ int minHeight = style->fontMetrics().height();
minHeight = max(minHeight, dropDownBoxMinHeight);
style->setMinHeight(Length(minHeight, Fixed));
@@ -788,7 +789,7 @@ bool RenderThemeWin::paintMenuListButton(RenderObject* o, const PaintInfo& i, co
IntRect buttonRect(r);
buttonRect.inflate(-borderThickness);
if (o->style()->direction() == LTR)
- buttonRect.setX(buttonRect.right() - dropDownButtonWidth);
+ buttonRect.setX(buttonRect.maxX() - dropDownButtonWidth);
buttonRect.setWidth(dropDownButtonWidth);
if (isRunningOnVistaOrLater()) {
diff --git a/Source/WebCore/rendering/RenderThemeWinCE.cpp b/Source/WebCore/rendering/RenderThemeWinCE.cpp
index d4bff96..a56ab3e 100644
--- a/Source/WebCore/rendering/RenderThemeWinCE.cpp
+++ b/Source/WebCore/rendering/RenderThemeWinCE.cpp
@@ -250,7 +250,7 @@ bool RenderThemeWinCE::paintMenuList(RenderObject* o, const PaintInfo& i, const
bool RenderThemeWinCE::paintMenuListButton(RenderObject* o, const PaintInfo& i, const IntRect& r)
{
- IntRect buttonRect(r.right() - dropDownButtonWidth - 1, r.y(), dropDownButtonWidth, r.height());
+ IntRect buttonRect(r.maxX() - dropDownButtonWidth - 1, r.y(), dropDownButtonWidth, r.height());
buttonRect.inflateY(-1);
i.context->drawFrameControl(buttonRect, DFC_SCROLL, DFCS_SCROLLCOMBOBOX | determineClassicState(o));
return true;
@@ -386,7 +386,7 @@ bool RenderThemeWinCE::paintSearchFieldCancelButton(RenderObject* o, const Paint
IntRect xBounds(cancelBounds.location() + IntSize(3, 3), xSize);
paintInfo.context->setStrokeColor(Color::white, ColorSpaceDeviceRGB);
paintInfo.context->drawLine(xBounds.location(), xBounds.location() + xBounds.size());
- paintInfo.context->drawLine(IntPoint(xBounds.right(), xBounds.y()), IntPoint(xBounds.x(), xBounds.bottom()));
+ paintInfo.context->drawLine(IntPoint(xBounds.maxX(), xBounds.y()), IntPoint(xBounds.x(), xBounds.maxY()));
paintInfo.context->restore();
return false;
@@ -452,7 +452,7 @@ void RenderThemeWinCE::adjustMenuListButtonStyle(CSSStyleSelector* selector, Ren
style->setHeight(Length(Auto));
// Calculate our min-height
- int minHeight = style->font().height();
+ int minHeight = style->fontMetrics().height();
minHeight = max(minHeight, dropDownBoxMinHeight);
style->setMinHeight(Length(minHeight, Fixed));
@@ -489,7 +489,7 @@ static HTMLMediaElement* mediaElementParent(Node* node)
bool RenderThemeWinCE::paintSliderTrack(RenderObject* o, const PaintInfo& i, const IntRect& r)
{
bool rc = RenderTheme::paintSliderTrack(o, i, r);
- IntPoint left = IntPoint(r.x() + 2, (r.y() + r.bottom()) / 2);
+ IntPoint left = IntPoint(r.x() + 2, (r.y() + r.maxY()) / 2);
i.context->save();
i.context->setStrokeColor(Color::gray, ColorSpaceDeviceRGB);
i.context->setFillColor(Color::gray, ColorSpaceDeviceRGB);
@@ -498,13 +498,13 @@ bool RenderThemeWinCE::paintSliderTrack(RenderObject* o, const PaintInfo& i, con
HTMLMediaElement* mediaElement = mediaElementParent(o->node());
if (mediaElement) {
i.context->setStrokeColor(Color(0, 0xff, 0));
- IntPoint right = IntPoint(left.x() + mediaElement->percentLoaded() * (r.right() - r.x() - 4), (r.y() + r.bottom()) / 2);
+ IntPoint right = IntPoint(left.x() + mediaElement->percentLoaded() * (r.maxX() - r.x() - 4), (r.y() + r.maxY()) / 2);
i.context->drawLine(left, right);
left = right;
}
#endif
i.context->setStrokeColor(Color::black, ColorSpaceDeviceRGB);
- i.context->drawLine(left, IntPoint(r.right() - 2, left.y()));
+ i.context->drawLine(left, IntPoint(r.maxX() - 2, left.y()));
i.context->restore();
return rc;
}
@@ -566,14 +566,14 @@ bool RenderThemeWinCE::paintMediaMuteButton(RenderObject* o, const PaintInfo& pa
FloatPoint pts[6] = {
FloatPoint(imRect.x() + 1, imRect.y() + imRect.height() / 3.0),
FloatPoint(imRect.x() + 1 + imRect.width() / 2.0, imRect.y() + imRect.height() / 3.0),
- FloatPoint(imRect.right() - 1, imRect.y()),
- FloatPoint(imRect.right() - 1, imRect.bottom()),
+ FloatPoint(imRect.maxX() - 1, imRect.y()),
+ FloatPoint(imRect.maxX() - 1, imRect.maxY()),
FloatPoint(imRect.x() + 1 + imRect.width() / 2.0, imRect.y() + 2.0 * imRect.height() / 3.0),
FloatPoint(imRect.x() + 1, imRect.y() + 2.0 * imRect.height() / 3.0)
};
paintInfo.context->drawConvexPolygon(6, pts);
if (muted)
- paintInfo.context->drawLine(IntPoint(imRect.right(), imRect.y()), IntPoint(imRect.x(), imRect.bottom()));
+ paintInfo.context->drawLine(IntPoint(imRect.maxX(), imRect.y()), IntPoint(imRect.x(), imRect.maxY()));
paintInfo.context->restore();
return rc;
}
@@ -595,7 +595,7 @@ bool RenderThemeWinCE::paintMediaPlayButton(RenderObject* o, const PaintInfo& pa
imRect.move(2.0 * width / 3.0, 0);
paintInfo.context->fillRect(imRect);
} else {
- FloatPoint pts[3] = { FloatPoint(imRect.x(), imRect.y()), FloatPoint(imRect.right(), (imRect.y() + imRect.bottom()) / 2.0), FloatPoint(imRect.x(), imRect.bottom()) };
+ FloatPoint pts[3] = { FloatPoint(imRect.x(), imRect.y()), FloatPoint(imRect.maxX(), (imRect.y() + imRect.maxY()) / 2.0), FloatPoint(imRect.x(), imRect.maxY()) };
paintInfo.context->drawConvexPolygon(3, pts);
}
paintInfo.context->restore();
@@ -607,8 +607,8 @@ bool RenderThemeWinCE::paintMediaSeekBackButton(RenderObject* o, const PaintInfo
bool rc = paintButton(o, paintInfo, r);
FloatRect imRect = r;
imRect.inflate(-3);
- FloatPoint pts[3] = { FloatPoint((imRect.x() + imRect.right()) / 2.0, imRect.y()), FloatPoint(imRect.x(), (imRect.y() + imRect.bottom()) / 2.0), FloatPoint((imRect.x() + imRect.right()) / 2.0, imRect.bottom()) };
- FloatPoint pts2[3] = { FloatPoint(imRect.right(), imRect.y()), FloatPoint((imRect.x() + imRect.right()) / 2.0, (imRect.y() + imRect.bottom()) / 2.0), FloatPoint(imRect.right(), imRect.bottom()) };
+ FloatPoint pts[3] = { FloatPoint((imRect.x() + imRect.maxX()) / 2.0, imRect.y()), FloatPoint(imRect.x(), (imRect.y() + imRect.maxY()) / 2.0), FloatPoint((imRect.x() + imRect.maxX()) / 2.0, imRect.maxY()) };
+ FloatPoint pts2[3] = { FloatPoint(imRect.maxX(), imRect.y()), FloatPoint((imRect.x() + imRect.maxX()) / 2.0, (imRect.y() + imRect.maxY()) / 2.0), FloatPoint(imRect.maxX(), imRect.maxY()) };
paintInfo.context->save();
paintInfo.context->setStrokeColor(Color::black);
paintInfo.context->setFillColor(Color::black);
@@ -623,8 +623,8 @@ bool RenderThemeWinCE::paintMediaSeekForwardButton(RenderObject* o, const PaintI
bool rc = paintButton(o, paintInfo, r);
FloatRect imRect = r;
imRect.inflate(-3);
- FloatPoint pts[3] = { FloatPoint(imRect.x(), imRect.y()), FloatPoint((imRect.x() + imRect.right()) / 2.0, (imRect.y() + imRect.bottom()) / 2.0), FloatPoint(imRect.x(), imRect.bottom()) };
- FloatPoint pts2[3] = { FloatPoint((imRect.x() + imRect.right()) / 2.0, imRect.y()), FloatPoint(imRect.right(), (imRect.y() + imRect.bottom()) / 2.0), FloatPoint((imRect.x() + imRect.right()) / 2.0, imRect.bottom()) };
+ FloatPoint pts[3] = { FloatPoint(imRect.x(), imRect.y()), FloatPoint((imRect.x() + imRect.maxX()) / 2.0, (imRect.y() + imRect.maxY()) / 2.0), FloatPoint(imRect.x(), imRect.maxY()) };
+ FloatPoint pts2[3] = { FloatPoint((imRect.x() + imRect.maxX()) / 2.0, imRect.y()), FloatPoint(imRect.maxX(), (imRect.y() + imRect.maxY()) / 2.0), FloatPoint((imRect.x() + imRect.maxX()) / 2.0, imRect.maxY()) };
paintInfo.context->save();
paintInfo.context->setStrokeColor(Color::black);
paintInfo.context->setFillColor(Color::black);
diff --git a/Source/WebCore/rendering/RenderTreeAsText.cpp b/Source/WebCore/rendering/RenderTreeAsText.cpp
index 2e64999..a81163b 100644
--- a/Source/WebCore/rendering/RenderTreeAsText.cpp
+++ b/Source/WebCore/rendering/RenderTreeAsText.cpp
@@ -27,7 +27,6 @@
#include "RenderTreeAsText.h"
#include "CSSMutableStyleDeclaration.h"
-#include "CharacterNames.h"
#include "Document.h"
#include "Frame.h"
#include "FrameView.h"
@@ -48,6 +47,7 @@
#include "SelectionController.h"
#include <wtf/UnusedParam.h>
#include <wtf/Vector.h>
+#include <wtf/unicode/CharacterNames.h>
#if ENABLE(SVG)
#include "RenderSVGContainer.h"
@@ -621,10 +621,10 @@ static void writeLayers(TextStream& ts, const RenderLayer* rootLayer, RenderLaye
// FIXME: Apply overflow to the root layer to not break every test. Complete hack. Sigh.
IntRect paintDirtyRect(paintRect);
if (rootLayer == l) {
- paintDirtyRect.setWidth(max(paintDirtyRect.width(), rootLayer->renderBox()->rightLayoutOverflow()));
- paintDirtyRect.setHeight(max(paintDirtyRect.height(), rootLayer->renderBox()->bottomLayoutOverflow()));
- l->setWidth(max(l->width(), l->renderBox()->rightLayoutOverflow()));
- l->setHeight(max(l->height(), l->renderBox()->bottomLayoutOverflow()));
+ paintDirtyRect.setWidth(max(paintDirtyRect.width(), rootLayer->renderBox()->maxXLayoutOverflow()));
+ paintDirtyRect.setHeight(max(paintDirtyRect.height(), rootLayer->renderBox()->maxYLayoutOverflow()));
+ l->setWidth(max(l->width(), l->renderBox()->maxXLayoutOverflow()));
+ l->setHeight(max(l->height(), l->renderBox()->maxYLayoutOverflow()));
}
// Calculate the clip rects we should use.
@@ -769,13 +769,12 @@ String counterValueForElement(Element* element)
element->document()->updateLayout();
TextStream stream;
bool isFirstCounter = true;
- // The counter renderers should be children of anonymous children
- // (i.e., :before or :after pseudo-elements).
+ // The counter renderers should be children of :before or :after pseudo-elements.
if (RenderObject* renderer = element->renderer()) {
- for (RenderObject* child = renderer->firstChild(); child; child = child->nextSibling()) {
- if (child->isAnonymous())
- writeCounterValuesFromChildren(stream, child, isFirstCounter);
- }
+ if (RenderObject* pseudoElement = renderer->beforePseudoElementRenderer())
+ writeCounterValuesFromChildren(stream, pseudoElement, isFirstCounter);
+ if (RenderObject* pseudoElement = renderer->afterPseudoElementRenderer())
+ writeCounterValuesFromChildren(stream, pseudoElement, isFirstCounter);
}
return stream.release();
}
diff --git a/Source/WebCore/rendering/RenderVideo.cpp b/Source/WebCore/rendering/RenderVideo.cpp
index 0f3b551..1ae736b 100644
--- a/Source/WebCore/rendering/RenderVideo.cpp
+++ b/Source/WebCore/rendering/RenderVideo.cpp
@@ -56,7 +56,7 @@ RenderVideo::RenderVideo(HTMLVideoElement* video)
RenderVideo::~RenderVideo()
{
- if (MediaPlayer* p = player()) {
+ if (MediaPlayer* p = mediaElement()->player()) {
p->setVisible(false);
p->setFrameView(0);
}
@@ -108,9 +108,9 @@ IntSize RenderVideo::calculateIntrinsicSize()
// The intrinsic height of a video element's playback area is the intrinsic height
// of the video resource, if that is available; otherwise it is the intrinsic
// height of the poster frame, if that is available; otherwise it is 150 CSS pixels.
-
- if (player() && video->readyState() >= HTMLVideoElement::HAVE_METADATA)
- return player()->naturalSize();
+ MediaPlayer* player = mediaElement()->player();
+ if (player && video->readyState() >= HTMLVideoElement::HAVE_METADATA)
+ return player->naturalSize();
if (video->shouldDisplayPosterImage() && !m_cachedImageSize.isEmpty() && !imageResource()->errorOccurred())
return m_cachedImageSize;
@@ -186,7 +186,7 @@ bool RenderVideo::shouldDisplayVideo() const
void RenderVideo::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
{
- MediaPlayer* mediaPlayer = player();
+ MediaPlayer* mediaPlayer = mediaElement()->player();
bool displayingPoster = videoElement()->shouldDisplayPosterImage();
if (!displayingPoster) {
@@ -228,7 +228,7 @@ void RenderVideo::updatePlayer()
{
updateIntrinsicSize();
- MediaPlayer* mediaPlayer = player();
+ MediaPlayer* mediaPlayer = mediaElement()->player();
if (!mediaPlayer)
return;
@@ -265,7 +265,7 @@ int RenderVideo::minimumReplacedHeight() const
#if USE(ACCELERATED_COMPOSITING)
bool RenderVideo::supportsAcceleratedRendering() const
{
- MediaPlayer* p = player();
+ MediaPlayer* p = mediaElement()->player();
if (p)
return p->supportsAcceleratedRendering();
@@ -274,7 +274,7 @@ bool RenderVideo::supportsAcceleratedRendering() const
void RenderVideo::acceleratedRenderingStateChanged()
{
- MediaPlayer* p = player();
+ MediaPlayer* p = mediaElement()->player();
if (p)
p->acceleratedRenderingStateChanged();
}
diff --git a/Source/WebCore/rendering/RenderView.cpp b/Source/WebCore/rendering/RenderView.cpp
index 687ba85..2fd441d 100644
--- a/Source/WebCore/rendering/RenderView.cpp
+++ b/Source/WebCore/rendering/RenderView.cpp
@@ -116,7 +116,7 @@ void RenderView::layout()
setPageLogicalHeight(0);
if (printing())
- m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = width();
+ m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = logicalWidth();
// Use calcWidth/Height to get the new width/height, since this will take the full page zoom factor into account.
bool relayoutChildren = !printing() && (!m_frameView || width() != viewWidth() || height() != viewHeight());
@@ -160,13 +160,13 @@ void RenderView::mapLocalToContainer(RenderBoxModelObject* repaintContainer, boo
}
if (fixed && m_frameView)
- transformState.move(m_frameView->scrollOffset());
+ transformState.move(m_frameView->scrollOffsetForFixedPosition());
}
void RenderView::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const
{
if (fixed && m_frameView)
- transformState.move(-m_frameView->scrollOffset());
+ transformState.move(-m_frameView->scrollOffsetForFixedPosition());
if (useTransforms && shouldUseTransformFromContainer(0)) {
TransformationMatrix t;
@@ -315,13 +315,13 @@ void RenderView::computeRectForRepaint(RenderBoxModelObject* repaintContainer, I
// We have to flip by hand since the view's logical height has not been determined. We
// can use the viewport width and height.
if (style()->isHorizontalWritingMode())
- rect.setY(viewHeight() - rect.bottom());
+ rect.setY(viewHeight() - rect.maxY());
else
- rect.setX(viewWidth() - rect.right());
+ rect.setX(viewWidth() - rect.maxX());
}
if (fixed && m_frameView)
- rect.move(m_frameView->scrollX(), m_frameView->scrollY());
+ rect.move(m_frameView->scrollXForFixedPosition(), m_frameView->scrollYForFixedPosition());
// Apply our transform if we have one (because of full page zooming).
if (m_layer && m_layer->transform())
@@ -662,7 +662,7 @@ IntRect RenderView::viewRect() const
int RenderView::docTop() const
{
- IntRect overflowRect(0, topLayoutOverflow(), 0, bottomLayoutOverflow() - topLayoutOverflow());
+ IntRect overflowRect(0, minYLayoutOverflow(), 0, maxYLayoutOverflow() - minYLayoutOverflow());
flipForWritingMode(overflowRect);
if (hasTransform())
overflowRect = layer()->currentTransform().mapRect(overflowRect);
@@ -675,7 +675,7 @@ int RenderView::docBottom() const
flipForWritingMode(overflowRect);
if (hasTransform())
overflowRect = layer()->currentTransform().mapRect(overflowRect);
- return overflowRect.bottom();
+ return overflowRect.maxY();
}
int RenderView::docLeft() const
@@ -693,7 +693,7 @@ int RenderView::docRight() const
flipForWritingMode(overflowRect);
if (hasTransform())
overflowRect = layer()->currentTransform().mapRect(overflowRect);
- return overflowRect.right();
+ return overflowRect.maxX();
}
int RenderView::viewHeight() const
diff --git a/Source/WebCore/rendering/RenderWidget.cpp b/Source/WebCore/rendering/RenderWidget.cpp
index d4b8ba6..13b572d 100644
--- a/Source/WebCore/rendering/RenderWidget.cpp
+++ b/Source/WebCore/rendering/RenderWidget.cpp
@@ -120,8 +120,6 @@ void RenderWidget::destroy()
if (RenderView* v = view())
v->removeWidget(this);
- if (m_hasCounterNodeMap)
- RenderCounter::destroyCounterNodes(this);
if (AXObjectCache::accessibilityEnabled()) {
document()->axObjectCache()->childrenChanged(this->parent());
@@ -129,6 +127,9 @@ void RenderWidget::destroy()
}
remove();
+ if (m_hasCounterNodeMap)
+ RenderCounter::destroyCounterNodes(this);
+
setWidget(0);
// removes from override size map
diff --git a/Source/WebCore/rendering/RenderingAllInOne.cpp b/Source/WebCore/rendering/RenderingAllInOne.cpp
index faa3566..760f02d 100644
--- a/Source/WebCore/rendering/RenderingAllInOne.cpp
+++ b/Source/WebCore/rendering/RenderingAllInOne.cpp
@@ -45,6 +45,7 @@
#include "RenderBox.cpp"
#include "RenderBoxModelObject.cpp"
#include "RenderButton.cpp"
+#include "RenderCombineText.cpp"
#include "RenderCounter.cpp"
#include "RenderDataGrid.cpp"
#include "RenderDetails.cpp"
diff --git a/Source/WebCore/rendering/RootInlineBox.cpp b/Source/WebCore/rendering/RootInlineBox.cpp
index e9e2029..aa87683 100644
--- a/Source/WebCore/rendering/RootInlineBox.cpp
+++ b/Source/WebCore/rendering/RootInlineBox.cpp
@@ -544,14 +544,14 @@ IntRect RootInlineBox::paddedLayoutOverflowRect(int endPadding) const
if (isHorizontal()) {
if (isLeftToRightDirection())
- lineLayoutOverflow.shiftRightEdgeTo(max(lineLayoutOverflow.right(), logicalRight() + endPadding));
+ lineLayoutOverflow.shiftMaxXEdgeTo(max(lineLayoutOverflow.maxX(), logicalRight() + endPadding));
else
- lineLayoutOverflow.shiftLeftEdgeTo(min(lineLayoutOverflow.x(), logicalLeft() - endPadding));
+ lineLayoutOverflow.shiftXEdgeTo(min(lineLayoutOverflow.x(), logicalLeft() - endPadding));
} else {
if (isLeftToRightDirection())
- lineLayoutOverflow.shiftBottomEdgeTo(max(lineLayoutOverflow.bottom(), logicalRight() + endPadding));
+ lineLayoutOverflow.shiftMaxYEdgeTo(max(lineLayoutOverflow.maxY(), logicalRight() + endPadding));
else
- lineLayoutOverflow.shiftTopEdgeTo(min(lineLayoutOverflow.y(), logicalRight() - endPadding));
+ lineLayoutOverflow.shiftYEdgeTo(min(lineLayoutOverflow.y(), logicalRight() - endPadding));
}
return lineLayoutOverflow;
diff --git a/Source/WebCore/rendering/ShadowElement.cpp b/Source/WebCore/rendering/ShadowElement.cpp
index e1b247c..5b1a962 100644
--- a/Source/WebCore/rendering/ShadowElement.cpp
+++ b/Source/WebCore/rendering/ShadowElement.cpp
@@ -114,7 +114,7 @@ PassRefPtr<ShadowInputElement> ShadowInputElement::create(HTMLElement* shadowPar
}
ShadowInputElement::ShadowInputElement(HTMLElement* shadowParent)
- : ShadowElement<HTMLInputElement>(inputTag, shadowParent)
+ : ShadowElement<HTMLInputElement>(inputTag, shadowParent, 0, false)
{
}
diff --git a/Source/WebCore/rendering/ShadowElement.h b/Source/WebCore/rendering/ShadowElement.h
index 8bcb34e..9a5d118 100644
--- a/Source/WebCore/rendering/ShadowElement.h
+++ b/Source/WebCore/rendering/ShadowElement.h
@@ -43,6 +43,12 @@ protected:
BaseElement::setShadowHost(shadowParent);
}
+ ShadowElement(const QualifiedName& name, HTMLElement* shadowParent, HTMLFormElement* form, bool createdByParser)
+ : BaseElement(name, shadowParent->document(), form, createdByParser)
+ {
+ BaseElement::setShadowHost(shadowParent);
+ }
+
public:
virtual void detach();
};
diff --git a/Source/WebCore/rendering/TextControlInnerElements.cpp b/Source/WebCore/rendering/TextControlInnerElements.cpp
index 7b1b36f..1162999 100644
--- a/Source/WebCore/rendering/TextControlInnerElements.cpp
+++ b/Source/WebCore/rendering/TextControlInnerElements.cpp
@@ -77,7 +77,6 @@ VisiblePosition RenderTextControlInnerBlock::positionForPoint(const IntPoint& po
TextControlInnerElement::TextControlInnerElement(Document* document, HTMLElement* shadowParent)
: HTMLDivElement(divTag, document)
- , m_shadowParent(shadowParent)
{
setShadowHost(shadowParent);
}
@@ -220,7 +219,7 @@ void SearchFieldCancelButtonElement::detach()
void SearchFieldCancelButtonElement::defaultEventHandler(Event* event)
{
// If the element is visible, on mouseup, clear the value, and set selection
- HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode());
+ 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()) {
@@ -233,13 +232,12 @@ void SearchFieldCancelButtonElement::defaultEventHandler(Event* event)
event->setDefaultHandled();
}
if (event->type() == eventNames().mouseupEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
- if (m_capturing && renderer() && renderer()->visibleToHitTesting()) {
+ if (m_capturing) {
if (Frame* frame = document()->frame()) {
frame->eventHandler()->setCapturingMouseEventsNode(0);
m_capturing = false;
}
if (hovered()) {
- RefPtr<HTMLInputElement> protector(input);
String oldValue = input->value();
input->setValue("");
if (!oldValue.isEmpty()) {
@@ -272,6 +270,18 @@ PassRefPtr<SpinButtonElement> SpinButtonElement::create(HTMLElement* shadowParen
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()) {
@@ -287,7 +297,7 @@ void SpinButtonElement::defaultEventHandler(Event* event)
return;
}
- HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode());
+ RefPtr<HTMLInputElement> input(static_cast<HTMLInputElement*>(shadowAncestorNode()));
if (input->disabled() || input->isReadOnlyFormControl()) {
if (!event->defaultHandled())
HTMLDivElement::defaultEventHandler(event);
@@ -298,12 +308,18 @@ void SpinButtonElement::defaultEventHandler(Event* event)
IntPoint local = roundedIntPoint(box->absoluteToLocal(mouseEvent->absoluteLocation(), false, true));
if (mouseEvent->type() == eventNames().mousedownEvent && mouseEvent->button() == LeftButton) {
if (box->borderBoxRect().contains(local)) {
- RefPtr<Node> protector(input);
+ // 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();
- input->stepUpFromRenderer(m_upDownState == Up ? 1 : -1);
+ if (renderer()) {
+ input->stepUpFromRenderer(m_upDownState == Up ? 1 : -1);
+ if (renderer())
+ startRepeatingTimer();
+ }
event->setDefaultHandled();
- startRepeatingTimer();
}
} else if (mouseEvent->type() == eventNames().mouseupEvent && mouseEvent->button() == LeftButton)
stopRepeatingTimer();
@@ -404,8 +420,12 @@ void InputFieldSpeechButtonElement::defaultEventHandler(Event* 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.
- 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()) {
@@ -413,10 +433,6 @@ void InputFieldSpeechButtonElement::defaultEventHandler(Event* event)
m_capturing = true;
}
}
- // 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> holdRef(input);
RefPtr<InputFieldSpeechButtonElement> holdRefButton(this);
input->focus();
input->select();
@@ -483,11 +499,10 @@ void InputFieldSpeechButtonElement::setRecognitionResult(int, const SpeechInputR
{
m_results = results;
- HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode());
// 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> holdRef(input);
+ 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));
diff --git a/Source/WebCore/rendering/TextControlInnerElements.h b/Source/WebCore/rendering/TextControlInnerElements.h
index bb77dcd..4ba7857 100644
--- a/Source/WebCore/rendering/TextControlInnerElements.h
+++ b/Source/WebCore/rendering/TextControlInnerElements.h
@@ -48,8 +48,6 @@ protected:
private:
virtual bool isMouseFocusable() const { return false; }
-
- RefPtr<HTMLElement> m_shadowParent;
};
class TextControlInnerTextElement : public TextControlInnerElement {
@@ -101,6 +99,7 @@ public:
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(); }
diff --git a/Source/WebCore/rendering/TransformState.cpp b/Source/WebCore/rendering/TransformState.cpp
index ecc614e..9f177ea 100644
--- a/Source/WebCore/rendering/TransformState.cpp
+++ b/Source/WebCore/rendering/TransformState.cpp
@@ -60,9 +60,9 @@ void TransformState::applyTransform(const TransformationMatrix& transformFromCon
// If we have an accumulated transform from last time, multiply in this transform
if (m_accumulatedTransform) {
if (m_direction == ApplyTransformDirection)
- m_accumulatedTransform->multiply(transformFromContainer);
+ m_accumulatedTransform.set(new TransformationMatrix(transformFromContainer * *m_accumulatedTransform));
else
- m_accumulatedTransform->multLeft(transformFromContainer);
+ m_accumulatedTransform->multiply(transformFromContainer);
} else if (accumulate == AccumulateTransform) {
// Make one if we started to accumulate
m_accumulatedTransform.set(new TransformationMatrix(transformFromContainer));
@@ -140,7 +140,7 @@ void HitTestingTransformState::translate(int x, int y, TransformAccumulation acc
void HitTestingTransformState::applyTransform(const TransformationMatrix& transformFromContainer, TransformAccumulation accumulate)
{
- m_accumulatedTransform.multLeft(transformFromContainer);
+ m_accumulatedTransform.multiply(transformFromContainer);
if (accumulate == FlattenTransform)
flattenWithTransform(m_accumulatedTransform);
diff --git a/Source/WebCore/rendering/break_lines.cpp b/Source/WebCore/rendering/break_lines.cpp
index 16bfcc2..b888fb8 100644
--- a/Source/WebCore/rendering/break_lines.cpp
+++ b/Source/WebCore/rendering/break_lines.cpp
@@ -26,9 +26,9 @@
#include "config.h"
#include "break_lines.h"
-#include "CharacterNames.h"
#include "TextBreakIterator.h"
#include <wtf/StdLibExtras.h>
+#include <wtf/unicode/CharacterNames.h>
#if PLATFORM(MAC)
#include <CoreServices/CoreServices.h>
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp b/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp
index 9d80fbe..48d3f39 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp
@@ -176,7 +176,7 @@ int RenderMathMLFraction::baselinePosition(FontBaseline, bool firstLine, LineDir
refStyle = previousSibling()->style();
else if (nextSibling())
refStyle = nextSibling()->style();
- int shift = int(ceil((refStyle->font().xHeight() + 1) / 2));
+ int shift = int(ceil((refStyle->fontMetrics().xHeight() + 1) / 2));
return numerator->offsetHeight() + shift;
}
return RenderBlock::baselinePosition(AlphabeticBaseline, firstLine, lineDirection, linePositionMode);
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLOperator.h b/Source/WebCore/rendering/mathml/RenderMathMLOperator.h
index 6501494..3ef15c5 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLOperator.h
+++ b/Source/WebCore/rendering/mathml/RenderMathMLOperator.h
@@ -28,8 +28,8 @@
#if ENABLE(MATHML)
-#include "CharacterNames.h"
#include "RenderMathMLBlock.h"
+#include <wtf/unicode/CharacterNames.h>
namespace WebCore {
diff --git a/Source/WebCore/rendering/style/RenderStyle.cpp b/Source/WebCore/rendering/style/RenderStyle.cpp
index 2836fb9..b76a350 100644
--- a/Source/WebCore/rendering/style/RenderStyle.cpp
+++ b/Source/WebCore/rendering/style/RenderStyle.cpp
@@ -462,7 +462,8 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon
inherited_flags._text_transform != other->inherited_flags._text_transform ||
inherited_flags._direction != other->inherited_flags._direction ||
inherited_flags._white_space != other->inherited_flags._white_space ||
- noninherited_flags._clear != other->noninherited_flags._clear)
+ noninherited_flags._clear != other->noninherited_flags._clear ||
+ noninherited_flags._unicodeBidi != other->noninherited_flags._unicodeBidi)
return StyleDifferenceLayout;
// Check block flow direction.
diff --git a/Source/WebCore/rendering/style/RenderStyle.h b/Source/WebCore/rendering/style/RenderStyle.h
index 9d5239b..7b79db1 100644
--- a/Source/WebCore/rendering/style/RenderStyle.h
+++ b/Source/WebCore/rendering/style/RenderStyle.h
@@ -165,7 +165,6 @@ protected:
(_text_align == other._text_align) &&
(_text_transform == other._text_transform) &&
(_text_decorations == other._text_decorations) &&
- (_text_transform == other._text_transform) &&
(_cursor_style == other._cursor_style) &&
(_direction == other._direction) &&
(_border_collapse == other._border_collapse) &&
@@ -463,6 +462,7 @@ public:
ETableLayout tableLayout() const { return static_cast<ETableLayout>(noninherited_flags._table_layout); }
const Font& font() const { return inherited->font; }
+ const FontMetrics& fontMetrics() const { return inherited->font.fontMetrics(); }
const FontDescription& fontDescription() const { return inherited->font.fontDescription(); }
int fontSize() const { return inherited->font.pixelSize(); }
@@ -487,7 +487,7 @@ public:
// Negative value means the line height is not set. Use the font's built-in spacing.
if (lh.isNegative())
- return font().lineSpacing();
+ return fontMetrics().lineSpacing();
if (lh.isPercent())
return lh.calcMinValue(fontSize());
@@ -727,6 +727,7 @@ public:
bool hasMask() const { return rareNonInheritedData->m_mask.hasImage() || rareNonInheritedData->m_maskBoxImage.hasImage(); }
TextCombine textCombine() const { return static_cast<TextCombine>(rareNonInheritedData->m_textCombine); }
+ bool hasTextCombine() const { return textCombine() != TextCombineNone; }
// End CSS3 Getters
// Apple-specific property getter methods
diff --git a/Source/WebCore/rendering/style/RenderStyleConstants.h b/Source/WebCore/rendering/style/RenderStyleConstants.h
index 7cd4903..44cd3f5 100644
--- a/Source/WebCore/rendering/style/RenderStyleConstants.h
+++ b/Source/WebCore/rendering/style/RenderStyleConstants.h
@@ -68,14 +68,9 @@ enum StyleDifferenceContextSensitiveProperty {
enum PseudoId {
// The order must be NOP ID, public IDs, and then internal IDs.
NOPSEUDO, FIRST_LINE, FIRST_LETTER, BEFORE, AFTER, SELECTION, FIRST_LINE_INHERITED, SCROLLBAR, FILE_UPLOAD_BUTTON, INPUT_PLACEHOLDER,
- SEARCH_CANCEL_BUTTON, SEARCH_DECORATION, SEARCH_RESULTS_DECORATION, SEARCH_RESULTS_BUTTON, MEDIA_CONTROLS_PANEL,
- MEDIA_CONTROLS_PLAY_BUTTON, MEDIA_CONTROLS_MUTE_BUTTON, MEDIA_CONTROLS_TIMELINE, MEDIA_CONTROLS_TIMELINE_CONTAINER,
- MEDIA_CONTROLS_VOLUME_SLIDER, MEDIA_CONTROLS_VOLUME_SLIDER_CONTAINER, MEDIA_CONTROLS_VOLUME_SLIDER_MUTE_BUTTON,
- MEDIA_CONTROLS_CURRENT_TIME_DISPLAY, MEDIA_CONTROLS_TIME_REMAINING_DISPLAY,
- MEDIA_CONTROLS_SEEK_BACK_BUTTON, MEDIA_CONTROLS_SEEK_FORWARD_BUTTON, MEDIA_CONTROLS_FULLSCREEN_BUTTON, MEDIA_CONTROLS_REWIND_BUTTON,
- MEDIA_CONTROLS_RETURN_TO_REALTIME_BUTTON, MEDIA_CONTROLS_TOGGLE_CLOSED_CAPTIONS_BUTTON,
- MEDIA_CONTROLS_STATUS_DISPLAY, SCROLLBAR_THUMB, SCROLLBAR_BUTTON, SCROLLBAR_TRACK, SCROLLBAR_TRACK_PIECE, SCROLLBAR_CORNER, RESIZER,
- INPUT_LIST_BUTTON, INPUT_SPEECH_BUTTON, INNER_SPIN_BUTTON, OUTER_SPIN_BUTTON, VISITED_LINK, PROGRESS_BAR_VALUE,
+ SEARCH_CANCEL_BUTTON, SEARCH_DECORATION, SEARCH_RESULTS_DECORATION, SEARCH_RESULTS_BUTTON,
+ SCROLLBAR_THUMB, SCROLLBAR_BUTTON, SCROLLBAR_TRACK, SCROLLBAR_TRACK_PIECE, SCROLLBAR_CORNER, RESIZER,
+ INPUT_LIST_BUTTON, INPUT_SPEECH_BUTTON, INNER_SPIN_BUTTON, OUTER_SPIN_BUTTON, VISITED_LINK,
METER_HORIZONTAL_BAR, METER_HORIZONTAL_OPTIMUM, METER_HORIZONTAL_SUBOPTIMAL, METER_HORIZONTAL_EVEN_LESS_GOOD,
METER_VERTICAL_BAR, METER_VERTICAL_OPTIMUM, METER_VERTICAL_SUBOPTIMAL, METER_VERTICAL_EVEN_LESS_GOOD,
AFTER_LAST_INTERNAL_PSEUDOID,
diff --git a/Source/WebCore/rendering/style/StyleCachedImage.cpp b/Source/WebCore/rendering/style/StyleCachedImage.cpp
index 1d7aba8..05cb0ea 100644
--- a/Source/WebCore/rendering/style/StyleCachedImage.cpp
+++ b/Source/WebCore/rendering/style/StyleCachedImage.cpp
@@ -84,7 +84,7 @@ void StyleCachedImage::removeClient(RenderObject* renderer)
return m_image->removeClient(renderer);
}
-Image* StyleCachedImage::image(RenderObject*, const IntSize&) const
+PassRefPtr<Image> StyleCachedImage::image(RenderObject*, const IntSize&) const
{
return m_image->image();
}
diff --git a/Source/WebCore/rendering/style/StyleCachedImage.h b/Source/WebCore/rendering/style/StyleCachedImage.h
index 3d6e1a2..2be6f4c 100644
--- a/Source/WebCore/rendering/style/StyleCachedImage.h
+++ b/Source/WebCore/rendering/style/StyleCachedImage.h
@@ -52,7 +52,7 @@ public:
virtual void setImageContainerSize(const IntSize&);
virtual void addClient(RenderObject*);
virtual void removeClient(RenderObject*);
- virtual Image* image(RenderObject*, const IntSize&) const;
+ virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const;
private:
StyleCachedImage(CachedImage* image)
diff --git a/Source/WebCore/rendering/style/StyleGeneratedImage.cpp b/Source/WebCore/rendering/style/StyleGeneratedImage.cpp
index 2322f5f..fa0aad7 100644
--- a/Source/WebCore/rendering/style/StyleGeneratedImage.cpp
+++ b/Source/WebCore/rendering/style/StyleGeneratedImage.cpp
@@ -72,7 +72,7 @@ void StyleGeneratedImage::removeClient(RenderObject* renderer)
m_generator->removeClient(renderer);
}
-Image* StyleGeneratedImage::image(RenderObject* renderer, const IntSize& size) const
+PassRefPtr<Image> StyleGeneratedImage::image(RenderObject* renderer, const IntSize& size) const
{
return m_generator->image(renderer, size);
}
diff --git a/Source/WebCore/rendering/style/StyleGeneratedImage.h b/Source/WebCore/rendering/style/StyleGeneratedImage.h
index 7be1f6a..8e6076a 100644
--- a/Source/WebCore/rendering/style/StyleGeneratedImage.h
+++ b/Source/WebCore/rendering/style/StyleGeneratedImage.h
@@ -51,7 +51,7 @@ public:
virtual void setImageContainerSize(const IntSize&);
virtual void addClient(RenderObject*);
virtual void removeClient(RenderObject*);
- virtual Image* image(RenderObject*, const IntSize&) const;
+ virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const;
private:
StyleGeneratedImage(CSSImageGeneratorValue* val, bool fixedSize)
diff --git a/Source/WebCore/rendering/style/StyleImage.h b/Source/WebCore/rendering/style/StyleImage.h
index ead8d4a..2c844f6 100644
--- a/Source/WebCore/rendering/style/StyleImage.h
+++ b/Source/WebCore/rendering/style/StyleImage.h
@@ -25,6 +25,7 @@
#define StyleImage_h
#include "CSSValue.h"
+#include "Image.h"
#include "IntSize.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -33,7 +34,6 @@
namespace WebCore {
class CSSValue;
-class Image;
class RenderObject;
typedef void* WrappedImagePtr;
@@ -59,7 +59,7 @@ public:
virtual void setImageContainerSize(const IntSize&) = 0;
virtual void addClient(RenderObject*) = 0;
virtual void removeClient(RenderObject*) = 0;
- virtual Image* image(RenderObject*, const IntSize&) const = 0;
+ virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const = 0;
virtual WrappedImagePtr data() const = 0;
virtual bool isCachedImage() const { return false; }
diff --git a/Source/WebCore/rendering/style/StylePendingImage.h b/Source/WebCore/rendering/style/StylePendingImage.h
index b0c9b01..60c993c 100644
--- a/Source/WebCore/rendering/style/StylePendingImage.h
+++ b/Source/WebCore/rendering/style/StylePendingImage.h
@@ -26,6 +26,7 @@
#ifndef StylePendingImage_h
#define StylePendingImage_h
+#include "Image.h"
#include "StyleImage.h"
namespace WebCore {
@@ -52,7 +53,7 @@ public:
virtual void setImageContainerSize(const IntSize&) { }
virtual void addClient(RenderObject*) { }
virtual void removeClient(RenderObject*) { }
- virtual Image* image(RenderObject*, const IntSize&) const
+ virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const
{
ASSERT_NOT_REACHED();
return 0;
diff --git a/Source/WebCore/rendering/svg/RenderSVGImage.cpp b/Source/WebCore/rendering/svg/RenderSVGImage.cpp
index 0f5a55e..81a5cea 100644
--- a/Source/WebCore/rendering/svg/RenderSVGImage.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGImage.cpp
@@ -122,7 +122,7 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, int, int)
PaintInfo savedInfo(childPaintInfo);
if (SVGRenderSupport::prepareToRenderSVGContent(this, childPaintInfo)) {
- Image* image = m_imageResource->image();
+ RefPtr<Image> image = m_imageResource->image();
FloatRect destRect = m_objectBoundingBox;
FloatRect srcRect(0, 0, image->width(), image->height());
@@ -130,7 +130,7 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, int, int)
if (imageElement->preserveAspectRatio().align() != SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE)
imageElement->preserveAspectRatio().transformRect(destRect, srcRect);
- childPaintInfo.context->drawImage(image, ColorSpaceDeviceRGB, destRect, srcRect);
+ childPaintInfo.context->drawImage(image.get(), ColorSpaceDeviceRGB, destRect, srcRect);
}
SVGRenderSupport::finishRenderSVGContent(this, childPaintInfo, savedInfo.context);
diff --git a/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp b/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
index 91ffb5c..a8aa0c8 100644
--- a/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
@@ -26,11 +26,14 @@
#if ENABLE(SVG)
#include "RenderSVGInlineText.h"
+#include "CSSStyleSelector.h"
#include "FloatConversion.h"
#include "FloatQuad.h"
#include "RenderBlock.h"
#include "RenderSVGRoot.h"
#include "RenderSVGText.h"
+#include "Settings.h"
+#include "SVGImageBufferTools.h"
#include "SVGInlineTextBox.h"
#include "SVGRootInlineBox.h"
#include "VisiblePosition.h"
@@ -63,6 +66,7 @@ static PassRefPtr<StringImpl> applySVGWhitespaceRules(PassRefPtr<StringImpl> str
RenderSVGInlineText::RenderSVGInlineText(Node* n, PassRefPtr<StringImpl> string)
: RenderText(n, applySVGWhitespaceRules(string, false))
+ , m_scalingFactor(1)
{
}
@@ -74,6 +78,8 @@ void RenderSVGInlineText::styleDidChange(StyleDifference diff, const RenderStyle
// The text metrics may be influenced by style changes.
if (RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(this))
textRenderer->setNeedsPositioningValuesUpdate();
+
+ updateScaledFont();
}
const RenderStyle* newStyle = style();
@@ -103,12 +109,12 @@ IntRect RenderSVGInlineText::localCaretRect(InlineBox* box, int caretOffset, int
// Use the edge of the selection rect to determine the caret rect.
if (static_cast<unsigned>(caretOffset) < textBox->start() + textBox->len()) {
IntRect rect = textBox->selectionRect(0, 0, caretOffset, caretOffset + 1);
- int x = box->isLeftToRightDirection() ? rect.x() : rect.right();
+ int x = box->isLeftToRightDirection() ? rect.x() : rect.maxX();
return IntRect(x, rect.y(), caretWidth, rect.height());
}
IntRect rect = textBox->selectionRect(0, 0, caretOffset - 1, caretOffset);
- int x = box->isLeftToRightDirection() ? rect.right() : rect.x();
+ int x = box->isLeftToRightDirection() ? rect.maxX() : rect.x();
return IntRect(x, rect.y(), caretWidth, rect.height());
}
@@ -159,9 +165,7 @@ VisiblePosition RenderSVGInlineText::positionForPoint(const IntPoint& point)
if (!firstTextBox() || !textLength())
return createVisiblePosition(0, DOWNSTREAM);
- RenderStyle* style = this->style();
- ASSERT(style);
- int baseline = style->font().ascent();
+ float baseline = m_scaledFont.fontMetrics().floatAscent();
RenderBlock* containingBlock = this->containingBlock();
ASSERT(containingBlock);
@@ -206,6 +210,39 @@ VisiblePosition RenderSVGInlineText::positionForPoint(const IntPoint& point)
return createVisiblePosition(offset + closestDistanceBox->start(), offset > 0 ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM);
}
+void RenderSVGInlineText::updateScaledFont()
+{
+ computeNewScaledFontForStyle(this, style(), m_scalingFactor, m_scaledFont);
+}
+
+void RenderSVGInlineText::computeNewScaledFontForStyle(RenderObject* renderer, const RenderStyle* style, float& scalingFactor, Font& scaledFont)
+{
+ ASSERT(style);
+ ASSERT(renderer);
+
+ Document* document = renderer->document();
+ ASSERT(document);
+
+ CSSStyleSelector* styleSelector = document->styleSelector();
+ ASSERT(styleSelector);
+
+ // Alter font-size to the right on-screen value, to avoid scaling the glyphs themselves.
+ AffineTransform ctm;
+ SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(renderer, ctm);
+ scalingFactor = narrowPrecisionToFloat(sqrt((pow(ctm.xScale(), 2) + pow(ctm.yScale(), 2)) / 2));
+ if (scalingFactor == 1 || !scalingFactor) {
+ scalingFactor = 1;
+ scaledFont = style->font();
+ return;
+ }
+
+ FontDescription fontDescription(style->fontDescription());
+ fontDescription.setComputedSize(fontDescription.computedSize() * scalingFactor);
+
+ scaledFont = Font(fontDescription, 0, 0);
+ scaledFont.update(styleSelector->fontSelector());
+}
+
}
#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGInlineText.h b/Source/WebCore/rendering/svg/RenderSVGInlineText.h
index f5247f6..9eed8cd 100644
--- a/Source/WebCore/rendering/svg/RenderSVGInlineText.h
+++ b/Source/WebCore/rendering/svg/RenderSVGInlineText.h
@@ -40,6 +40,11 @@ public:
const SVGTextLayoutAttributes& layoutAttributes() const { return m_attributes; }
void storeLayoutAttributes(const SVGTextLayoutAttributes& attributes) { m_attributes = attributes; }
+ float scalingFactor() const { return m_scalingFactor; }
+ const Font& scaledFont() const { return m_scaledFont; }
+ void updateScaledFont();
+ static void computeNewScaledFontForStyle(RenderObject*, const RenderStyle*, float& scalingFactor, Font& scaledFont);
+
private:
virtual const char* renderName() const { return "RenderSVGInlineText"; }
@@ -57,6 +62,8 @@ private:
virtual IntRect linesBoundingBox() const;
virtual InlineTextBox* createTextBox();
+ float m_scalingFactor;
+ Font m_scaledFont;
SVGTextLayoutAttributes m_attributes;
};
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
index 4ba4e0a..96514af 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
@@ -111,7 +111,7 @@ PassRefPtr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives(Filter* fi
builder->clearEffects();
return 0;
}
- builder->appendEffectToEffectReferences(effect);
+ builder->appendEffectToEffectReferences(effect, effectElement->renderer());
effectElement->setStandardAttributes(primitiveBoundingBoxMode, effect.get());
builder->add(effectElement->result(), effect);
}
@@ -208,13 +208,13 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,
if (!lastEffect)
return false;
- RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(lastEffect, filterData->filter.get());
+ RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(lastEffect);
FloatRect subRegion = lastEffect->maxEffectRect();
// At least one FilterEffect has a too big image size,
// recalculate the effect sizes with new scale factors.
if (!fitsInMaximumImageSize(subRegion.size(), scale)) {
filterData->filter->setFilterResolution(scale);
- RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(lastEffect, filterData->filter.get());
+ RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(lastEffect);
}
// If the drawingRegion is empty, we have something like <g filter=".."/>.
@@ -290,16 +290,19 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo
// This is the real filtering of the object. It just needs to be called on the
// initial filtering process. We just take the stored filter result on a
// second drawing.
- if (!filterData->builded) {
+ if (!filterData->builded)
filterData->filter->setSourceImage(filterData->sourceGraphicBuffer.release());
+
+ // Always true if filterData is just built (filterData->builded is false).
+ if (!lastEffect->hasResult()) {
lastEffect->apply();
#if !PLATFORM(CG)
ImageBuffer* resultImage = lastEffect->asImageBuffer();
if (resultImage)
resultImage->transformColorSpace(ColorSpaceLinearRGB, ColorSpaceDeviceRGB);
#endif
- filterData->builded = true;
}
+ filterData->builded = true;
ImageBuffer* resultImage = lastEffect->asImageBuffer();
if (resultImage) {
@@ -324,5 +327,31 @@ FloatRect RenderSVGResourceFilter::resourceBoundingBox(RenderObject* object)
return FloatRect();
}
+void RenderSVGResourceFilter::primitiveAttributeChanged(RenderObject* object, const QualifiedName& attribute)
+{
+ HashMap<RenderObject*, FilterData*>::iterator it = m_filter.begin();
+ HashMap<RenderObject*, FilterData*>::iterator end = m_filter.end();
+ SVGFilterPrimitiveStandardAttributes* primitve = static_cast<SVGFilterPrimitiveStandardAttributes*>(object->node());
+
+ for (; it != end; ++it) {
+ FilterData* filterData = it->second;
+ if (!filterData->builded)
+ continue;
+
+ SVGFilterBuilder* builder = filterData->builder.get();
+ FilterEffect* effect = builder->effectByRenderer(object);
+ if (!effect)
+ continue;
+ // Since all effects shares the same attribute value, all
+ // or none of them will be changed.
+ if (!primitve->setFilterEffectAttribute(effect, attribute))
+ return;
+ builder->clearResultsRecursive(effect);
+
+ // Repaint the image on the screen.
+ markClientForInvalidation(it->first, RepaintInvalidation);
+ }
+}
+
}
#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h
index f9a15ce..c809f23 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h
@@ -64,6 +64,7 @@ public:
virtual ~RenderSVGResourceFilter();
virtual const char* renderName() const { return "RenderSVGResourceFilter"; }
+ virtual bool isSVGResourceFilter() const { return true; }
virtual void removeAllClientsFromCache(bool markForInvalidation = true);
virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
@@ -78,6 +79,8 @@ public:
SVGUnitTypes::SVGUnitType filterUnits() const { return toUnitType(static_cast<SVGFilterElement*>(node())->filterUnits()); }
SVGUnitTypes::SVGUnitType primitiveUnits() const { return toUnitType(static_cast<SVGFilterElement*>(node())->primitiveUnits()); }
+ void primitiveAttributeChanged(RenderObject*, const QualifiedName&);
+
virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
static RenderSVGResourceType s_resourceType;
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
index fc7362e..64df700 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
@@ -29,25 +29,29 @@
#if ENABLE(SVG) && ENABLE(FILTERS)
#include "RenderSVGResourceFilterPrimitive.h"
+#include "RenderSVGResource.h"
#include "SVGFEImage.h"
+#include "SVGFilter.h"
namespace WebCore {
-FloatRect RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(FilterEffect* effect, SVGFilter* filter)
+FloatRect RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(FilterEffect* effect)
{
FloatRect uniteRect;
FloatRect subregionBoundingBox = effect->effectBoundaries();
FloatRect subregion = subregionBoundingBox;
+ SVGFilter* filter = static_cast<SVGFilter*>(effect->filter());
+ ASSERT(filter);
if (effect->filterEffectType() != FilterEffectTypeTile) {
// FETurbulence, FEImage and FEFlood don't have input effects, take the filter region as unite rect.
if (unsigned numberOfInputEffects = effect->inputEffects().size()) {
for (unsigned i = 0; i < numberOfInputEffects; ++i)
- uniteRect.unite(determineFilterPrimitiveSubregion(effect->inputEffect(i), filter));
+ uniteRect.unite(determineFilterPrimitiveSubregion(effect->inputEffect(i)));
} else
uniteRect = filter->filterRegionInUserSpace();
} else {
- determineFilterPrimitiveSubregion(effect->inputEffect(0), filter);
+ determineFilterPrimitiveSubregion(effect->inputEffect(0));
uniteRect = filter->filterRegionInUserSpace();
}
@@ -90,7 +94,7 @@ FloatRect RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(Fi
// FEImage needs the unclipped subregion in absolute coordinates to determine the correct
// destination rect in combination with preserveAspectRatio.
if (effect->filterEffectType() == FilterEffectTypeImage)
- reinterpret_cast<FEImage*>(effect)->setAbsoluteSubregion(absoluteSubregion);
+ static_cast<FEImage*>(effect)->setAbsoluteSubregion(absoluteSubregion);
// Clip every filter effect to the filter region.
FloatRect absoluteScaledFilterRegion = filter->filterRegion();
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h
index f25f62e..8176d29 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h
@@ -30,25 +30,32 @@
#if ENABLE(SVG) && ENABLE(FILTERS)
#include "RenderSVGHiddenContainer.h"
-#include "SVGFilter.h"
-#include "SVGFilterPrimitiveStandardAttributes.h"
+#include "RenderSVGResourceFilter.h"
namespace WebCore {
+class FilterEffect;
+
class RenderSVGResourceFilterPrimitive : public RenderSVGHiddenContainer {
public:
-
- explicit RenderSVGResourceFilterPrimitive(SVGFilterPrimitiveStandardAttributes* filterPrimitiveElement)
+ explicit RenderSVGResourceFilterPrimitive(SVGStyledElement* filterPrimitiveElement)
: RenderSVGHiddenContainer(filterPrimitiveElement)
{
}
- // They depend on the RenderObject argument of RenderSVGResourceFilter::applyResource.
- static FloatRect determineFilterPrimitiveSubregion(FilterEffect*, SVGFilter*);
-
-private:
virtual const char* renderName() const { return "RenderSVGResourceFilterPrimitive"; }
virtual bool isSVGResourceFilterPrimitive() const { return true; }
+
+ // They depend on the RenderObject argument of RenderSVGResourceFilter::applyResource.
+ static FloatRect determineFilterPrimitiveSubregion(FilterEffect*);
+
+ inline void primitiveAttributeChanged(const QualifiedName& attribute)
+ {
+ RenderObject* filter = parent();
+ if (!filter || !filter->isSVGResourceFilter())
+ return;
+ static_cast<RenderSVGResourceFilter*>(filter)->primitiveAttributeChanged(this, attribute);
+ }
};
} // namespace WebCore
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceMarker.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceMarker.cpp
index 2a68d92..fcad27f 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceMarker.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceMarker.cpp
@@ -86,11 +86,10 @@ FloatRect RenderSVGResourceMarker::markerBoundaries(const AffineTransform& marke
const AffineTransform& RenderSVGResourceMarker::localToParentTransform() const
{
- AffineTransform viewportTranslation(viewportTransform());
- m_localToParentTransform = viewportTranslation.translateRight(m_viewport.x(), m_viewport.y());
+ m_localToParentTransform = AffineTransform::translation(m_viewport.x(), m_viewport.y()) * viewportTransform();
return m_localToParentTransform;
// If this class were ever given a localTransform(), then the above would read:
- // return viewportTransform() * localTransform() * viewportTranslation;
+ // return viewportTranslation * localTransform() * viewportTransform();
}
FloatPoint RenderSVGResourceMarker::referencePoint() const
diff --git a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
index 3a8dce9..30f72b9 100644
--- a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
@@ -261,18 +261,15 @@ IntSize RenderSVGRoot::borderOriginToContentBox() const
AffineTransform RenderSVGRoot::localToRepaintContainerTransform(const IntPoint& parentOriginInContainer) const
{
- AffineTransform parentToContainer(localToParentTransform());
- return parentToContainer.translateRight(parentOriginInContainer.x(), parentOriginInContainer.y());
+ return AffineTransform::translation(parentOriginInContainer.x(), parentOriginInContainer.y()) * localToParentTransform();
}
const AffineTransform& RenderSVGRoot::localToParentTransform() const
{
IntSize parentToBorderBoxOffset = parentOriginToBorderBox();
- AffineTransform borderBoxOriginToParentOrigin(localToBorderBoxTransform());
- borderBoxOriginToParentOrigin.translateRight(parentToBorderBoxOffset.width(), parentToBorderBoxOffset.height());
+ m_localToParentTransform = AffineTransform::translation(parentToBorderBoxOffset.width(), parentToBorderBoxOffset.height()) * localToBorderBoxTransform();
- m_localToParentTransform = borderBoxOriginToParentOrigin;
return m_localToParentTransform;
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGText.cpp b/Source/WebCore/rendering/svg/RenderSVGText.cpp
index dad0b70..56d9306 100644
--- a/Source/WebCore/rendering/svg/RenderSVGText.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGText.cpp
@@ -33,7 +33,7 @@
#include "GraphicsContext.h"
#include "HitTestRequest.h"
#include "PointerEventsHitRules.h"
-#include "RenderLayer.h"
+#include "RenderSVGInlineText.h"
#include "RenderSVGResource.h"
#include "RenderSVGRoot.h"
#include "SVGLengthList.h"
@@ -91,6 +91,18 @@ void RenderSVGText::mapLocalToContainer(RenderBoxModelObject* repaintContainer,
SVGRenderSupport::mapLocalToContainer(this, repaintContainer, fixed, useTransforms, transformState);
}
+static inline void recursiveUpdateScaledFont(RenderObject* start)
+{
+ for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) {
+ if (child->isSVGInlineText()) {
+ toRenderSVGInlineText(child)->updateScaledFont();
+ continue;
+ }
+
+ recursiveUpdateScaledFont(child);
+ }
+}
+
void RenderSVGText::layout()
{
ASSERT(needsLayout());
@@ -104,6 +116,13 @@ void RenderSVGText::layout()
updateCachedBoundariesInParents = true;
}
+ // If the root layout size changed (eg. window size changes) or the positioning values change, recompute the on-screen font size.
+ if (m_needsPositioningValuesUpdate || SVGRenderSupport::findTreeRootObject(this)->isLayoutSizeChanged()) {
+ recursiveUpdateScaledFont(this);
+ m_needsPositioningValuesUpdate = true;
+ updateCachedBoundariesInParents = true;
+ }
+
if (m_needsPositioningValuesUpdate) {
// Perform SVG text layout phase one (see SVGTextLayoutAttributesBuilder for details).
SVGTextLayoutAttributesBuilder layoutAttributesBuilder;
diff --git a/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp
index 7f4b6f7..0f2f273 100644
--- a/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp
@@ -72,11 +72,10 @@ AffineTransform RenderSVGViewportContainer::viewportTransform() const
const AffineTransform& RenderSVGViewportContainer::localToParentTransform() const
{
- AffineTransform viewportTranslation(viewportTransform());
- m_localToParentTransform = viewportTranslation.translateRight(m_viewport.x(), m_viewport.y());
+ m_localToParentTransform = AffineTransform::translation(m_viewport.x(), m_viewport.y()) * viewportTransform();
return m_localToParentTransform;
// If this class were ever given a localTransform(), then the above would read:
- // return viewportTransform() * localTransform() * viewportTranslation;
+ // return viewportTranslation * localTransform() * viewportTransform()
}
bool RenderSVGViewportContainer::pointIsInsideViewportClip(const FloatPoint& pointInParent)
diff --git a/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp b/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
index 2879f20..52976f2 100644
--- a/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
+++ b/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
@@ -30,6 +30,7 @@
#include "RenderSVGInlineText.h"
#include "RenderSVGResource.h"
#include "RenderSVGResourceSolidColor.h"
+#include "SVGImageBufferTools.h"
#include "SVGRootInlineBox.h"
#include "TextRun.h"
@@ -56,9 +57,12 @@ int SVGInlineTextBox::offsetForPosition(int, bool) const
int SVGInlineTextBox::offsetForPositionInFragment(const SVGTextFragment& fragment, float position, bool includePartialGlyphs) const
{
- RenderText* textRenderer = this->textRenderer();
+ RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
ASSERT(textRenderer);
+ float scalingFactor = textRenderer->scalingFactor();
+ ASSERT(scalingFactor);
+
RenderStyle* style = textRenderer->style();
ASSERT(style);
@@ -69,7 +73,7 @@ int SVGInlineTextBox::offsetForPositionInFragment(const SVGTextFragment& fragmen
if (!fragment.transform.isIdentity())
textRun.setHorizontalGlyphStretch(narrowPrecisionToFloat(fragment.transform.xScale()));
- return fragment.positionListOffset - start() + style->font().offsetForPosition(textRun, position, includePartialGlyphs);
+ return fragment.positionListOffset - start() + textRenderer->scaledFont().offsetForPosition(textRun, position * scalingFactor, includePartialGlyphs);
}
int SVGInlineTextBox::positionForOffset(int) const
@@ -82,10 +86,28 @@ int SVGInlineTextBox::positionForOffset(int) const
FloatRect SVGInlineTextBox::selectionRectForTextFragment(const SVGTextFragment& fragment, int startPosition, int endPosition, RenderStyle* style)
{
ASSERT(startPosition < endPosition);
+ ASSERT(style);
+
+ RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
+ ASSERT(textRenderer);
+
+ float scalingFactor = textRenderer->scalingFactor();
+ ASSERT(scalingFactor);
- const Font& font = style->font();
- FloatPoint textOrigin(fragment.x, fragment.y - font.ascent());
- return font.selectionRectForText(constructTextRun(style, fragment), textOrigin, fragment.height, startPosition, endPosition);
+ const Font& scaledFont = textRenderer->scaledFont();
+ const FontMetrics& scaledFontMetrics = scaledFont.fontMetrics();
+ FloatPoint textOrigin(fragment.x, fragment.y);
+ if (scalingFactor != 1)
+ textOrigin.scale(scalingFactor, scalingFactor);
+
+ textOrigin.move(0, -scaledFontMetrics.floatAscent());
+
+ FloatRect selectionRect = scaledFont.selectionRectForText(constructTextRun(style, fragment), textOrigin, fragment.height * scalingFactor, startPosition, endPosition);
+ if (scalingFactor == 1)
+ return selectionRect;
+
+ selectionRect.scale(1 / scalingFactor);
+ return selectionRect;
}
IntRect SVGInlineTextBox::selectionRect(int, int, int startPosition, int endPosition)
@@ -125,6 +147,13 @@ IntRect SVGInlineTextBox::selectionRect(int, int, int startPosition, int endPosi
return enclosingIntRect(selectionRect);
}
+static inline bool textShouldBePainted(RenderSVGInlineText* textRenderer)
+{
+ // Font::pixelSize(), returns FontDescription::computedPixelSize(), which returns "int(x + 0.5)".
+ // If the absolute font size on screen is below x=0.5, don't render anything.
+ return textRenderer->scaledFont().pixelSize();
+}
+
void SVGInlineTextBox::paintSelectionBackground(PaintInfo& paintInfo)
{
ASSERT(paintInfo.shouldPaintWithinRoot(renderer()));
@@ -148,6 +177,11 @@ void SVGInlineTextBox::paintSelectionBackground(PaintInfo& paintInfo)
if (!backgroundColor.isValid() || !backgroundColor.alpha())
return;
+ RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
+ ASSERT(textRenderer);
+ if (!textShouldBePainted(textRenderer))
+ return;
+
RenderStyle* style = parentRenderer->style();
ASSERT(style);
@@ -222,6 +256,11 @@ void SVGInlineTextBox::paint(PaintInfo& paintInfo, int, int)
if (!hasSelection && paintSelectedTextOnly)
return;
+ RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
+ ASSERT(textRenderer);
+ if (!textShouldBePainted(textRenderer))
+ return;
+
RenderStyle* style = parentRenderer->style();
ASSERT(style);
@@ -286,8 +325,9 @@ void SVGInlineTextBox::paint(PaintInfo& paintInfo, int, int)
ASSERT(!m_paintingResource);
}
-bool SVGInlineTextBox::acquirePaintingResource(GraphicsContext*& context, RenderObject* renderer, RenderStyle* style)
+bool SVGInlineTextBox::acquirePaintingResource(GraphicsContext*& context, float scalingFactor, RenderObject* renderer, RenderStyle* style)
{
+ ASSERT(scalingFactor);
ASSERT(renderer);
ASSERT(style);
ASSERT(m_paintingResourceMode != ApplyToDefaultMode);
@@ -315,6 +355,9 @@ bool SVGInlineTextBox::acquirePaintingResource(GraphicsContext*& context, Render
}
}
+ if (scalingFactor != 1 && m_paintingResourceMode & ApplyToStrokeMode)
+ context->setStrokeThickness(context->strokeThickness() * scalingFactor);
+
return true;
}
@@ -329,9 +372,9 @@ void SVGInlineTextBox::releasePaintingResource(GraphicsContext*& context, const
m_paintingResource = 0;
}
-bool SVGInlineTextBox::prepareGraphicsContextForTextPainting(GraphicsContext*& context, TextRun& textRun, RenderStyle* style)
+bool SVGInlineTextBox::prepareGraphicsContextForTextPainting(GraphicsContext*& context, float scalingFactor, TextRun& textRun, RenderStyle* style)
{
- bool acquiredResource = acquirePaintingResource(context, parent()->renderer(), style);
+ bool acquiredResource = acquirePaintingResource(context, scalingFactor, parent()->renderer(), style);
#if ENABLE(SVG_FONTS)
// SVG Fonts need access to the painting resource used to draw the current text chunk.
@@ -364,14 +407,12 @@ TextRun SVGInlineTextBox::constructTextRun(RenderStyle* style, const SVGTextFrag
, false /* allowTabs */
, 0 /* xPos, only relevant with allowTabs=true */
, 0 /* padding, only relevant for justified text, not relevant for SVG */
+ , TextRun::AllowTrailingExpansion
, direction() == RTL
, m_dirOverride || style->visuallyOrdered() /* directionalOverride */);
#if ENABLE(SVG_FONTS)
- RenderObject* parentRenderer = parent()->renderer();
- ASSERT(parentRenderer);
-
- run.setReferencingRenderObject(parentRenderer);
+ run.setReferencingRenderObject(text);
#endif
// Disable any word/character rounding.
@@ -409,16 +450,16 @@ bool SVGInlineTextBox::mapStartEndPositionsIntoFragmentCoordinates(const SVGText
return true;
}
-static inline float positionOffsetForDecoration(ETextDecoration decoration, const Font& font, float thickness)
+static inline float positionOffsetForDecoration(ETextDecoration decoration, const FontMetrics& fontMetrics, float thickness)
{
// FIXME: For SVG Fonts we need to use the attributes defined in the <font-face> if specified.
// Compatible with Batik/Opera.
if (decoration == UNDERLINE)
- return font.ascent() + thickness * 1.5f;
+ return fontMetrics.floatAscent() + thickness * 1.5f;
if (decoration == OVERLINE)
return thickness;
if (decoration == LINE_THROUGH)
- return font.ascent() * 5.0f / 8.0f;
+ return fontMetrics.floatAscent() * 5 / 8.0f;
ASSERT_NOT_REACHED();
return 0.0f;
@@ -486,22 +527,34 @@ void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, ETextD
RenderStyle* decorationStyle = decorationRenderer->style();
ASSERT(decorationStyle);
- const Font& font = decorationStyle->font();
+ float scalingFactor = 1;
+ Font scaledFont;
+ RenderSVGInlineText::computeNewScaledFontForStyle(decorationRenderer, decorationStyle, scalingFactor, scaledFont);
+ ASSERT(scalingFactor);
// The initial y value refers to overline position.
- float thickness = thicknessForDecoration(decoration, font);
+ float thickness = thicknessForDecoration(decoration, scaledFont);
if (fragment.width <= 0 && thickness <= 0)
return;
- float y = fragment.y - font.ascent() + positionOffsetForDecoration(decoration, font, thickness);
-
- Path path;
- path.addRect(FloatRect(fragment.x, y, fragment.width, thickness));
+ FloatPoint decorationOrigin(fragment.x, fragment.y);
+ float width = fragment.width;
+ const FontMetrics& scaledFontMetrics = scaledFont.fontMetrics();
context->save();
+ if (scalingFactor != 1) {
+ width *= scalingFactor;
+ decorationOrigin.scale(scalingFactor, scalingFactor);
+ context->scale(FloatSize(1 / scalingFactor, 1 / scalingFactor));
+ }
- if (acquirePaintingResource(context, decorationRenderer, decorationStyle))
+ decorationOrigin.move(0, -scaledFontMetrics.floatAscent() + positionOffsetForDecoration(decoration, scaledFontMetrics, thickness));
+
+ Path path;
+ path.addRect(FloatRect(decorationOrigin, FloatSize(width, thickness)));
+
+ if (acquirePaintingResource(context, scalingFactor, decorationRenderer, decorationStyle))
releasePaintingResource(context, &path);
context->restore();
@@ -509,21 +562,41 @@ void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, ETextD
void SVGInlineTextBox::paintTextWithShadows(GraphicsContext* context, RenderStyle* style, TextRun& textRun, const SVGTextFragment& fragment, int startPosition, int endPosition)
{
- const Font& font = style->font();
+ RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
+ ASSERT(textRenderer);
+
+ float scalingFactor = textRenderer->scalingFactor();
+ ASSERT(scalingFactor);
+
+ const Font& scaledFont = textRenderer->scaledFont();
const ShadowData* shadow = style->textShadow();
FloatPoint textOrigin(fragment.x, fragment.y);
- FloatRect shadowRect(FloatPoint(textOrigin.x(), textOrigin.y() - font.ascent()), FloatSize(fragment.width, fragment.height));
+ FloatSize textSize(fragment.width, fragment.height);
+
+ if (scalingFactor != 1) {
+ textOrigin.scale(scalingFactor, scalingFactor);
+ textSize.scale(scalingFactor);
+ }
+
+ FloatRect shadowRect(FloatPoint(textOrigin.x(), textOrigin.y() - scaledFont.fontMetrics().floatAscent()), textSize);
do {
- if (!prepareGraphicsContextForTextPainting(context, textRun, style))
+ if (!prepareGraphicsContextForTextPainting(context, scalingFactor, textRun, style))
break;
FloatSize extraOffset;
if (shadow)
extraOffset = applyShadowToGraphicsContext(context, shadow, shadowRect, false /* stroked */, true /* opaque */, true /* horizontal */);
- font.drawText(context, textRun, textOrigin + extraOffset, startPosition, endPosition);
+ if (scalingFactor != 1)
+ context->scale(FloatSize(1 / scalingFactor, 1 / scalingFactor));
+
+ scaledFont.drawText(context, textRun, textOrigin + extraOffset, startPosition, endPosition);
+
+ if (scalingFactor != 1)
+ context->scale(FloatSize(scalingFactor, scalingFactor));
+
restoreGraphicsContextAfterTextPainting(context, textRun);
if (!shadow)
@@ -580,19 +653,18 @@ IntRect SVGInlineTextBox::calculateBoundaries() const
{
FloatRect textRect;
- RenderText* textRenderer = this->textRenderer();
+ RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
ASSERT(textRenderer);
- RenderStyle* style = textRenderer->style();
- ASSERT(style);
+ float scalingFactor = textRenderer->scalingFactor();
+ ASSERT(scalingFactor);
- int baseline = baselinePosition(AlphabeticBaseline);
- int heightDifference = baseline - style->font().ascent();
+ float baseline = textRenderer->scaledFont().fontMetrics().floatAscent() / scalingFactor;
unsigned textFragmentsSize = m_textFragments.size();
for (unsigned i = 0; i < textFragmentsSize; ++i) {
const SVGTextFragment& fragment = m_textFragments.at(i);
- FloatRect fragmentRect(fragment.x, fragment.y - baseline, fragment.width, fragment.height + heightDifference);
+ FloatRect fragmentRect(fragment.x, fragment.y - baseline, fragment.width, fragment.height);
if (!fragment.transform.isIdentity())
fragmentRect = fragment.transform.mapRect(fragmentRect);
diff --git a/Source/WebCore/rendering/svg/SVGInlineTextBox.h b/Source/WebCore/rendering/svg/SVGInlineTextBox.h
index 0458de0..f2ca303 100644
--- a/Source/WebCore/rendering/svg/SVGInlineTextBox.h
+++ b/Source/WebCore/rendering/svg/SVGInlineTextBox.h
@@ -66,10 +66,10 @@ public:
private:
TextRun constructTextRun(RenderStyle*, const SVGTextFragment&) const;
- bool acquirePaintingResource(GraphicsContext*&, RenderObject*, RenderStyle*);
+ bool acquirePaintingResource(GraphicsContext*&, float scalingFactor, RenderObject*, RenderStyle*);
void releasePaintingResource(GraphicsContext*&, const Path*);
- bool prepareGraphicsContextForTextPainting(GraphicsContext*&, TextRun&, RenderStyle*);
+ bool prepareGraphicsContextForTextPainting(GraphicsContext*&, float scalingFactor, TextRun&, RenderStyle*);
void restoreGraphicsContextAfterTextPainting(GraphicsContext*&, TextRun&);
void paintDecoration(GraphicsContext*, ETextDecoration, const SVGTextFragment&);
diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp b/Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp
index 3b28d2b..c25ed79 100644
--- a/Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp
@@ -310,7 +310,7 @@ void SVGTextLayoutEngine::finalizeTransformMatrices(Vector<SVGInlineTextBox*>& b
SVGTextFragment& fragment = fragments.at(i);
AffineTransform& transform = fragment.transform;
if (!transform.isIdentity()) {
- transform.translateRight(fragment.x, fragment.y);
+ transform = AffineTransform::translation(fragment.x, fragment.y) * transform;
transform.translate(-fragment.x, -fragment.y);
}
diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.cpp b/Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.cpp
index 3863322..4221f26 100644
--- a/Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.cpp
@@ -49,9 +49,9 @@ float SVGTextLayoutEngineBaseline::calculateBaselineShift(const SVGRenderStyle*
case BS_BASELINE:
return 0;
case BS_SUB:
- return -m_font.height() / 2;
+ return -m_font.fontMetrics().floatHeight() / 2;
case BS_SUPER:
- return m_font.height() / 2;
+ return m_font.fontMetrics().floatHeight() / 2;
default:
ASSERT_NOT_REACHED();
return 0;
@@ -122,27 +122,29 @@ float SVGTextLayoutEngineBaseline::calculateAlignmentBaselineShift(bool isVertic
ASSERT(baseline != AB_AUTO);
}
+ const FontMetrics& fontMetrics = m_font.fontMetrics();
+
// Note: http://wiki.apache.org/xmlgraphics-fop/LineLayout/AlignmentHandling
switch (baseline) {
case AB_BASELINE:
return dominantBaselineToAlignmentBaseline(isVerticalText, textRendererParent);
case AB_BEFORE_EDGE:
case AB_TEXT_BEFORE_EDGE:
- return m_font.ascent();
+ return fontMetrics.floatAscent();
case AB_MIDDLE:
- return m_font.xHeight() / 2;
+ return fontMetrics.xHeight() / 2;
case AB_CENTRAL:
- return (m_font.ascent() - m_font.descent()) / 2;
+ return (fontMetrics.floatAscent() - fontMetrics.floatDescent()) / 2;
case AB_AFTER_EDGE:
case AB_TEXT_AFTER_EDGE:
case AB_IDEOGRAPHIC:
- return m_font.descent();
+ return fontMetrics.floatDescent();
case AB_ALPHABETIC:
return 0;
case AB_HANGING:
- return m_font.ascent() * 8 / 10.f;
+ return fontMetrics.floatAscent() * 8 / 10.f;
case AB_MATHEMATICAL:
- return m_font.ascent() / 2;
+ return fontMetrics.floatAscent() / 2;
default:
ASSERT_NOT_REACHED();
return 0;
@@ -192,12 +194,14 @@ float SVGTextLayoutEngineBaseline::calculateGlyphAdvanceAndOrientation(bool isVe
// Spec: If if the 'glyph-orientation-vertical' results in an orientation angle that is not a multiple of
// 180 degrees, then the current text position is incremented according to the horizontal metrics of the glyph.
+ const FontMetrics& fontMetrics = m_font.fontMetrics();
+
// Vertical orientation handling.
if (isVerticalText) {
- float ascentMinusDescent = m_font.ascent() - m_font.descent();
+ float ascentMinusDescent = fontMetrics.floatAscent() - fontMetrics.floatDescent();
if (!angle) {
xOrientationShift = (ascentMinusDescent - metrics.width()) / 2;
- yOrientationShift = m_font.ascent();
+ yOrientationShift = fontMetrics.floatAscent();
} else if (angle == 180)
xOrientationShift = (ascentMinusDescent + metrics.width()) / 2;
else if (angle == 270) {
@@ -217,7 +221,7 @@ float SVGTextLayoutEngineBaseline::calculateGlyphAdvanceAndOrientation(bool isVe
yOrientationShift = -metrics.width();
else if (angle == 180) {
xOrientationShift = metrics.width();
- yOrientationShift = -m_font.ascent();
+ yOrientationShift = -fontMetrics.floatAscent();
} else if (angle == 270)
xOrientationShift = metrics.width();
diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp b/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp
index 6c54b67..e9aa127 100644
--- a/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp
@@ -58,7 +58,7 @@ float SVGTextLayoutEngineSpacing::calculateSVGKerning(bool isVerticalText, const
m_lastGlyph = currentGlyph;
m_lastGlyph.isValid = true;
- kerning *= m_font.size() / m_font.primaryFont()->unitsPerEm();
+ kerning *= m_font.size() / m_font.fontMetrics().unitsPerEm();
return kerning;
#else
UNUSED_PARAM(isVerticalText);
diff --git a/Source/WebCore/rendering/svg/SVGTextMetrics.cpp b/Source/WebCore/rendering/svg/SVGTextMetrics.cpp
index ec8c2c6..ca20d3d 100644
--- a/Source/WebCore/rendering/svg/SVGTextMetrics.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextMetrics.cpp
@@ -34,16 +34,21 @@ SVGTextMetrics::SVGTextMetrics()
{
}
-SVGTextMetrics::SVGTextMetrics(const Font& font, const TextRun& run, unsigned position, unsigned textLength)
- : m_width(0)
- , m_height(0)
- , m_length(0)
+SVGTextMetrics::SVGTextMetrics(RenderSVGInlineText* textRenderer, const TextRun& run, unsigned position, unsigned textLength)
{
+ ASSERT(textRenderer);
+
+ float scalingFactor = textRenderer->scalingFactor();
+ ASSERT(scalingFactor);
+
+ const Font& scaledFont = textRenderer->scaledFont();
+
int extraCharsAvailable = textLength - (position + run.length());
int length = 0;
- m_width = font.floatWidth(run, extraCharsAvailable, length, m_glyph.name);
- m_height = font.height();
+ // 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_height = scaledFont.fontMetrics().floatHeight() / scalingFactor;
m_glyph.unicodeString = String(run.characters(), length);
m_glyph.isValid = true;
@@ -71,8 +76,7 @@ static TextRun constructTextRun(RenderSVGInlineText* text, const UChar* characte
TextRun run(characters + position, length);
#if ENABLE(SVG_FONTS)
- ASSERT(text->parent());
- run.setReferencingRenderObject(text->parent());
+ run.setReferencingRenderObject(text);
#endif
// Disable any word/character rounding.
@@ -86,18 +90,13 @@ static TextRun constructTextRun(RenderSVGInlineText* text, const UChar* characte
SVGTextMetrics SVGTextMetrics::measureCharacterRange(RenderSVGInlineText* text, unsigned position, unsigned length)
{
ASSERT(text);
- ASSERT(text->style());
-
TextRun run(constructTextRun(text, text->characters(), position, length));
- return SVGTextMetrics(text->style()->font(), run, position, text->textLength());
+ return SVGTextMetrics(text, run, position, text->textLength());
}
void SVGTextMetrics::measureAllCharactersIndividually(RenderSVGInlineText* text, Vector<SVGTextMetrics>& allMetrics)
{
ASSERT(text);
- ASSERT(text->style());
-
- const Font& font = text->style()->font();
const UChar* characters = text->characters();
unsigned length = text->textLength();
@@ -105,7 +104,7 @@ void SVGTextMetrics::measureAllCharactersIndividually(RenderSVGInlineText* text,
for (unsigned position = 0; position < length; ) {
run.setText(characters + position, 1);
- SVGTextMetrics metrics(font, run, position, text->textLength());
+ SVGTextMetrics metrics(text, run, position, text->textLength());
allMetrics.append(metrics);
position += metrics.length();
}
diff --git a/Source/WebCore/rendering/svg/SVGTextMetrics.h b/Source/WebCore/rendering/svg/SVGTextMetrics.h
index ba18589..7ef0f7d 100644
--- a/Source/WebCore/rendering/svg/SVGTextMetrics.h
+++ b/Source/WebCore/rendering/svg/SVGTextMetrics.h
@@ -25,7 +25,6 @@
namespace WebCore {
-class Font;
class RenderSVGInlineText;
class TextRun;
@@ -64,7 +63,7 @@ public:
private:
SVGTextMetrics();
- SVGTextMetrics(const Font&, const TextRun&, unsigned position, unsigned textLength);
+ SVGTextMetrics(RenderSVGInlineText*, const TextRun&, unsigned position, unsigned textLength);
float m_width;
float m_height;
diff --git a/Source/WebCore/rendering/svg/SVGTextQuery.cpp b/Source/WebCore/rendering/svg/SVGTextQuery.cpp
index 42d511b..1a4cdab 100644
--- a/Source/WebCore/rendering/svg/SVGTextQuery.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextQuery.cpp
@@ -472,7 +472,10 @@ struct ExtentOfCharacterData : SVGTextQuery::Data {
static inline void calculateGlyphBoundaries(SVGTextQuery::Data* queryData, const SVGTextFragment& fragment, int startPosition, FloatRect& extent)
{
- extent.setLocation(FloatPoint(fragment.x, fragment.y - queryData->textRenderer->style()->font().ascent()));
+ float scalingFactor = queryData->textRenderer->scalingFactor();
+ ASSERT(scalingFactor);
+
+ extent.setLocation(FloatPoint(fragment.x, fragment.y - queryData->textRenderer->scaledFont().fontMetrics().floatAscent() / scalingFactor));
if (startPosition) {
SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textRenderer, fragment.positionListOffset, startPosition);