summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering')
-rw-r--r--WebCore/rendering/InlineBox.cpp14
-rw-r--r--WebCore/rendering/InlineBox.h9
-rw-r--r--WebCore/rendering/InlineFlowBox.cpp230
-rw-r--r--WebCore/rendering/InlineFlowBox.h9
-rw-r--r--WebCore/rendering/InlineTextBox.cpp8
-rw-r--r--WebCore/rendering/InlineTextBox.h2
-rw-r--r--WebCore/rendering/MediaControlElements.cpp16
-rw-r--r--WebCore/rendering/RenderBlock.cpp88
-rw-r--r--WebCore/rendering/RenderBlock.h4
-rw-r--r--WebCore/rendering/RenderBlockLineLayout.cpp76
-rw-r--r--WebCore/rendering/RenderBox.cpp71
-rw-r--r--WebCore/rendering/RenderBox.h14
-rw-r--r--WebCore/rendering/RenderBoxModelObject.cpp47
-rw-r--r--WebCore/rendering/RenderBoxModelObject.h10
-rw-r--r--WebCore/rendering/RenderFileUploadControl.cpp2
-rw-r--r--WebCore/rendering/RenderFlexibleBox.cpp2
-rw-r--r--WebCore/rendering/RenderImage.cpp67
-rw-r--r--WebCore/rendering/RenderImage.h7
-rw-r--r--WebCore/rendering/RenderInline.cpp19
-rw-r--r--WebCore/rendering/RenderInline.h6
-rw-r--r--WebCore/rendering/RenderLayer.cpp9
-rw-r--r--WebCore/rendering/RenderLayer.h3
-rw-r--r--WebCore/rendering/RenderLayerBacking.cpp2
-rw-r--r--WebCore/rendering/RenderListBox.cpp4
-rw-r--r--WebCore/rendering/RenderListBox.h2
-rw-r--r--WebCore/rendering/RenderListItem.cpp40
-rw-r--r--WebCore/rendering/RenderListMarker.cpp206
-rw-r--r--WebCore/rendering/RenderListMarker.h2
-rw-r--r--WebCore/rendering/RenderMenuList.cpp4
-rw-r--r--WebCore/rendering/RenderMenuList.h2
-rw-r--r--WebCore/rendering/RenderObject.cpp11
-rw-r--r--WebCore/rendering/RenderObject.h6
-rw-r--r--WebCore/rendering/RenderReplaced.cpp26
-rw-r--r--WebCore/rendering/RenderReplaced.h2
-rw-r--r--WebCore/rendering/RenderRuby.cpp3
-rw-r--r--WebCore/rendering/RenderRuby.h4
-rw-r--r--WebCore/rendering/RenderRubyBase.cpp3
-rw-r--r--WebCore/rendering/RenderRubyBase.h4
-rw-r--r--WebCore/rendering/RenderRubyRun.cpp12
-rw-r--r--WebCore/rendering/RenderRubyRun.h4
-rw-r--r--WebCore/rendering/RenderRubyText.cpp3
-rw-r--r--WebCore/rendering/RenderRubyText.h4
-rw-r--r--WebCore/rendering/RenderSVGGradientStop.cpp2
-rw-r--r--WebCore/rendering/RenderSVGViewportContainer.h1
-rw-r--r--WebCore/rendering/RenderSlider.cpp5
-rw-r--r--WebCore/rendering/RenderSlider.h2
-rw-r--r--WebCore/rendering/RenderTable.cpp14
-rw-r--r--WebCore/rendering/RenderTableCell.cpp8
-rw-r--r--WebCore/rendering/RenderTableCell.h2
-rw-r--r--WebCore/rendering/RenderTableRow.cpp11
-rw-r--r--WebCore/rendering/RenderTableSection.cpp55
-rw-r--r--WebCore/rendering/RenderText.cpp18
-rw-r--r--WebCore/rendering/RenderTextControl.cpp69
-rw-r--r--WebCore/rendering/RenderTextControl.h7
-rw-r--r--WebCore/rendering/RenderTextControlMultiLine.cpp49
-rw-r--r--WebCore/rendering/RenderTextControlMultiLine.h4
-rw-r--r--WebCore/rendering/RenderTextControlSingleLine.cpp70
-rw-r--r--WebCore/rendering/RenderTextControlSingleLine.h5
-rw-r--r--WebCore/rendering/RenderTreeAsText.cpp38
-rw-r--r--WebCore/rendering/RenderTreeAsText.h4
-rw-r--r--WebCore/rendering/RenderView.cpp17
-rw-r--r--WebCore/rendering/RootInlineBox.cpp24
-rw-r--r--WebCore/rendering/RootInlineBox.h11
-rw-r--r--WebCore/rendering/SVGImageBufferTools.cpp4
-rw-r--r--WebCore/rendering/ShadowElement.cpp2
-rw-r--r--WebCore/rendering/ShadowElement.h6
-rw-r--r--WebCore/rendering/TextControlInnerElements.cpp14
-rw-r--r--WebCore/rendering/TextControlInnerElements.h6
-rw-r--r--WebCore/rendering/VerticalPositionCache.h70
-rw-r--r--WebCore/rendering/style/RenderStyle.cpp30
-rw-r--r--WebCore/rendering/style/RenderStyle.h2
-rw-r--r--WebCore/rendering/svg/SVGInlineTextBox.cpp2
72 files changed, 991 insertions, 618 deletions
diff --git a/WebCore/rendering/InlineBox.cpp b/WebCore/rendering/InlineBox.cpp
index b8f0ce1..145096b 100644
--- a/WebCore/rendering/InlineBox.cpp
+++ b/WebCore/rendering/InlineBox.cpp
@@ -164,22 +164,26 @@ void InlineBox::paint(PaintInfo& paintInfo, int tx, int ty)
if (!paintInfo.shouldPaintWithinRoot(renderer()) || (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection))
return;
+ IntPoint childPoint = IntPoint(tx, ty);
+ if (parent()->renderer()->style()->isFlippedBlocksWritingMode()) // Faster than calling containingBlock().
+ childPoint = renderer()->containingBlock()->flipForWritingMode(toRenderBox(renderer()), childPoint, RenderBox::ParentToChildFlippingAdjustment);
+
// Paint all phases of replaced elements atomically, as though the replaced element established its
// own stacking context. (See Appendix E.2, section 6.4 on inline block/table elements in the CSS2.1
// specification.)
bool preservePhase = paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip;
PaintInfo info(paintInfo);
info.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
- renderer()->paint(info, tx, ty);
+ renderer()->paint(info, childPoint.x(), childPoint.y());
if (!preservePhase) {
info.phase = PaintPhaseChildBlockBackgrounds;
- renderer()->paint(info, tx, ty);
+ renderer()->paint(info, childPoint.x(), childPoint.y());
info.phase = PaintPhaseFloat;
- renderer()->paint(info, tx, ty);
+ renderer()->paint(info, childPoint.x(), childPoint.y());
info.phase = PaintPhaseForeground;
- renderer()->paint(info, tx, ty);
+ renderer()->paint(info, childPoint.x(), childPoint.y());
info.phase = PaintPhaseOutline;
- renderer()->paint(info, tx, ty);
+ renderer()->paint(info, childPoint.x(), childPoint.y());
}
}
diff --git a/WebCore/rendering/InlineBox.h b/WebCore/rendering/InlineBox.h
index 72e5534..c5f1997 100644
--- a/WebCore/rendering/InlineBox.h
+++ b/WebCore/rendering/InlineBox.h
@@ -113,6 +113,13 @@ public:
virtual bool isLineBreak() const { return false; }
virtual void adjustPosition(int dx, int dy);
+ void adjustLineDirectionPosition(int delta)
+ {
+ if (isHorizontal())
+ adjustPosition(delta, 0);
+ else
+ adjustPosition(0, delta);
+ }
virtual void paint(PaintInfo&, int tx, int ty);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty);
@@ -248,7 +255,7 @@ public:
// The logical height is our extent in the block flow direction, i.e., height for horizontal text and width for vertical text.
int logicalHeight() const;
- virtual int baselinePosition() const { return boxModelObject()->baselinePosition(m_firstLine, isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine); }
+ virtual int baselinePosition(FontBaseline baselineType) const { return boxModelObject()->baselinePosition(baselineType, m_firstLine, isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine); }
virtual int lineHeight() const { return boxModelObject()->lineHeight(m_firstLine, isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine); }
diff --git a/WebCore/rendering/InlineFlowBox.cpp b/WebCore/rendering/InlineFlowBox.cpp
index 8525673..e67c751 100644
--- a/WebCore/rendering/InlineFlowBox.cpp
+++ b/WebCore/rendering/InlineFlowBox.cpp
@@ -35,6 +35,7 @@
#include "RenderTableCell.h"
#include "RootInlineBox.h"
#include "Text.h"
+#include "VerticalPositionCache.h"
#include <math.h>
@@ -359,6 +360,43 @@ int InlineFlowBox::placeBoxesInInlineDirection(int logicalLeft, bool& needsWordS
return logicalLeft;
}
+bool InlineFlowBox::requiresIdeographicBaseline(const GlyphOverflowAndFallbackFontsMap& textBoxDataMap) const
+{
+ if (isHorizontal())
+ return false;
+
+ if (renderer()->style(m_firstLine)->font().primaryFont()->orientation() == Vertical)
+ return true;
+
+ for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
+ if (curr->renderer()->isPositioned())
+ continue; // Positioned placeholders don't affect calculations.
+
+ if (curr->isInlineFlowBox()) {
+ if (static_cast<InlineFlowBox*>(curr)->requiresIdeographicBaseline(textBoxDataMap))
+ return true;
+ } else {
+ if (curr->renderer()->style(m_firstLine)->font().primaryFont()->orientation() == Vertical)
+ return true;
+
+ const Vector<const SimpleFontData*>* usedFonts = 0;
+ if (curr->isInlineTextBox()) {
+ GlyphOverflowAndFallbackFontsMap::const_iterator it = textBoxDataMap.find(static_cast<InlineTextBox*>(curr));
+ usedFonts = it == textBoxDataMap.end() ? 0 : &it->second.first;
+ }
+
+ if (usedFonts) {
+ for (size_t i = 0; i < usedFonts->size(); ++i) {
+ if (usedFonts->at(i)->orientation() == Vertical)
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
int maxPositionTop, int maxPositionBottom)
{
@@ -387,29 +425,102 @@ void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
}
}
-static int verticalPositionForBox(InlineBox* curr, bool firstLine)
+static int verticalPositionForBox(InlineBox* box, FontBaseline baselineType, bool firstLine, VerticalPositionCache& verticalPositionCache)
{
- if (curr->renderer()->isText())
- return curr->parent()->logicalTop();
- if (curr->renderer()->isBox())
- return toRenderBox(curr->renderer())->verticalPosition(firstLine);
- return toRenderInline(curr->renderer())->verticalPositionFromCache(firstLine);
+ if (box->renderer()->isText())
+ return box->parent()->logicalTop();
+
+ RenderBoxModelObject* renderer = box->boxModelObject();
+ ASSERT(renderer->isInline());
+ if (!renderer->isInline())
+ return 0;
+
+ // This method determines the vertical position for inline elements.
+ if (firstLine && !renderer->document()->usesFirstLineRules())
+ firstLine = false;
+
+ // Check the cache.
+ bool isRenderInline = renderer->isRenderInline();
+ if (isRenderInline && !firstLine) {
+ int verticalPosition = verticalPositionCache.get(renderer, baselineType);
+ if (verticalPosition != PositionUndefined)
+ return verticalPosition;
+ }
+
+ int verticalPosition = 0;
+ EVerticalAlign verticalAlign = renderer->style()->verticalAlign();
+ if (verticalAlign == TOP)
+ verticalPosition = PositionTop;
+ else if (verticalAlign == BOTTOM)
+ verticalPosition = PositionBottom;
+ else {
+ RenderObject* parent = renderer->parent();
+ if (parent->isRenderInline() && parent->style()->verticalAlign() != TOP && parent->style()->verticalAlign() != BOTTOM)
+ verticalPosition = box->parent()->logicalTop();
+
+ if (verticalAlign != BASELINE) {
+ const Font& font = parent->style(firstLine)->font();
+ int fontSize = font.pixelSize();
+
+ LineDirectionMode lineDirection = parent->style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
+
+ if (verticalAlign == SUB)
+ verticalPosition += fontSize / 5 + 1;
+ else if (verticalAlign == SUPER)
+ verticalPosition -= fontSize / 3 + 1;
+ else if (verticalAlign == TEXT_TOP)
+ verticalPosition += renderer->baselinePosition(baselineType, firstLine, lineDirection) - font.ascent(baselineType);
+ else if (verticalAlign == MIDDLE)
+ verticalPosition += -static_cast<int>(font.xHeight() / 2) - renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType, firstLine, lineDirection);
+ else if (verticalAlign == TEXT_BOTTOM) {
+ verticalPosition += font.descent(baselineType);
+ // lineHeight - baselinePosition is always 0 for replaced elements (except inline blocks), so don't bother wasting time in that case.
+ if (!renderer->isReplaced() || renderer->isInlineBlockOrInlineTable())
+ verticalPosition -= (renderer->lineHeight(firstLine, lineDirection) - renderer->baselinePosition(baselineType, firstLine, lineDirection));
+ } else if (verticalAlign == BASELINE_MIDDLE)
+ verticalPosition += -renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType, firstLine, lineDirection);
+ else if (verticalAlign == LENGTH)
+ verticalPosition -= renderer->style()->verticalAlignLength().calcValue(renderer->lineHeight(firstLine, lineDirection));
+ }
+ }
+
+ // Store the cached value.
+ if (isRenderInline && !firstLine)
+ verticalPositionCache.set(renderer, baselineType, verticalPosition);
+
+ return verticalPosition;
}
void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositionBottom,
- int& maxAscent, int& maxDescent, bool strictMode, GlyphOverflowAndFallbackFontsMap& textBoxDataMap)
+ int& maxAscent, int& maxDescent, bool& setMaxAscent, bool& setMaxDescent,
+ bool strictMode, GlyphOverflowAndFallbackFontsMap& textBoxDataMap,
+ FontBaseline baselineType, VerticalPositionCache& verticalPositionCache)
{
+ // The primary purpose of this function is to compute the maximal ascent and descent values for
+ // a line.
+ //
+ // The maxAscent value represents the distance of the highest point of any box (including line-height) from
+ // the root box's baseline. The maxDescent value represents the distance of the lowest point of any box
+ // (also including line-height) from the root box baseline. These values can be negative.
+ //
+ // A secondary purpose of this function is to store the offset of very box's baseline from the root box's
+ // baseline. This information is cached in the logicalTop() of every box. We're effectively just using
+ // the logicalTop() as scratch space.
if (isRootInlineBox()) {
// Examine our root box.
int height = lineHeight();
- int baseline = baselinePosition();
+ int baseline = baselinePosition(baselineType);
if (hasTextChildren() || strictMode) {
int ascent = baseline;
int descent = height - ascent;
- if (maxAscent < ascent)
+ if (maxAscent < ascent || !setMaxAscent) {
maxAscent = ascent;
- if (maxDescent < descent)
+ setMaxAscent = true;
+ }
+ if (maxDescent < descent || !setMaxDescent) {
maxDescent = descent;
+ setMaxDescent = true;
+ }
}
}
@@ -418,7 +529,18 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
continue; // Positioned placeholders don't affect calculations.
bool isInlineFlow = curr->isInlineFlowBox();
-
+
+ // Because a box can be positioned such that it ends up fully above or fully below the
+ // root line box, we only consider it to affect the maxAscent and maxDescent values if some
+ // part of the box (EXCLUDING line-height) is above (for ascent) or below (for descent) the root box's baseline.
+ bool affectsAscent = false;
+ bool affectsDescent = false;
+
+ // The verticalPositionForBox function returns the distance between the child box's baseline
+ // and the root box's baseline. The value is negative if the child box's baseline is above the
+ // root box's baseline, and it is positive if the child box's baseline is below the root box's baseline.
+ curr->setLogicalTop(verticalPositionForBox(curr, baselineType, m_firstLine, verticalPositionCache));
+
int lineHeight;
int baseline;
Vector<const SimpleFontData*>* usedFonts = 0;
@@ -427,39 +549,45 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
usedFonts = it == textBoxDataMap.end() ? 0 : &it->second.first;
}
- if (usedFonts) {
+ if (usedFonts && curr->renderer()->style(m_firstLine)->lineHeight().isNegative()) {
usedFonts->append(curr->renderer()->style(m_firstLine)->font().primaryFont());
Length parentLineHeight = curr->renderer()->parent()->style()->lineHeight();
- if (parentLineHeight.isNegative()) {
- int baselineToBottom = 0;
- baseline = 0;
- for (size_t i = 0; i < usedFonts->size(); ++i) {
- int halfLeading = (usedFonts->at(i)->lineSpacing() - usedFonts->at(i)->ascent() - usedFonts->at(i)->descent()) / 2;
- baseline = max(baseline, halfLeading + usedFonts->at(i)->ascent());
- baselineToBottom = max(baselineToBottom, usedFonts->at(i)->lineSpacing() - usedFonts->at(i)->ascent() - usedFonts->at(i)->descent() - halfLeading);
- }
- lineHeight = baseline + baselineToBottom;
- } else if (parentLineHeight.isPercent()) {
- lineHeight = parentLineHeight.calcMinValue(curr->renderer()->style()->fontSize());
- baseline = 0;
- for (size_t i = 0; i < usedFonts->size(); ++i) {
- int halfLeading = (lineHeight - usedFonts->at(i)->ascent() - usedFonts->at(i)->descent()) / 2;
- baseline = max(baseline, halfLeading + usedFonts->at(i)->ascent());
- }
- } else {
- lineHeight = parentLineHeight.value();
- baseline = 0;
- for (size_t i = 0; i < usedFonts->size(); ++i) {
- int halfLeading = (lineHeight - usedFonts->at(i)->ascent() - usedFonts->at(i)->descent()) / 2;
- baseline = max(baseline, halfLeading + usedFonts->at(i)->ascent());
+ bool baselineSet = false;
+ 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 usedFontAscent = halfLeading + usedFonts->at(i)->ascent(baselineType);
+ int usedFontDescent = usedFonts->at(i)->lineSpacing() - usedFontAscent;
+ if (!baselineSet) {
+ baselineSet = true;
+ baseline = usedFontAscent;
+ baselineToBottom = usedFontDescent;
+ } else {
+ baseline = max(baseline, usedFontAscent);
+ baselineToBottom = max(baselineToBottom, usedFontDescent);
}
}
+ lineHeight = baseline + baselineToBottom;
} else {
lineHeight = curr->lineHeight();
- baseline = curr->baselinePosition();
+ baseline = curr->baselinePosition(baselineType);
+ if (curr->isText() || isInlineFlow) {
+ // 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;
+
+ // 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;
+ } else {
+ // Replaced elements always affect both the ascent and descent.
+ affectsAscent = true;
+ affectsDescent = true;
+ }
}
- curr->setLogicalTop(verticalPositionForBox(curr, m_firstLine));
if (curr->logicalTop() == PositionTop) {
if (maxPositionTop < lineHeight)
maxPositionTop = lineHeight;
@@ -467,23 +595,35 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
if (maxPositionBottom < lineHeight)
maxPositionBottom = lineHeight;
} else if ((!isInlineFlow || static_cast<InlineFlowBox*>(curr)->hasTextChildren()) || curr->boxModelObject()->hasInlineDirectionBordersOrPadding() || strictMode) {
+ // Note that these values can be negative. Even though we only affect the maxAscent and maxDescent values
+ // if our box (excluding line-height) was above (for ascent) or below (for descent) the root baseline, once you factor in line-height
+ // the final box can end up being fully above or fully below the root box's baseline! This is ok, but what it
+ // means is that ascent and descent (including leading), can end up being negative. The setMaxAscent and
+ // setMaxDescent booleans are used to ensure that we're willing to initially set maxAscent/Descent to negative
+ // values.
int ascent = baseline - curr->logicalTop();
int descent = lineHeight - ascent;
- if (maxAscent < ascent)
+ if (affectsAscent && (maxAscent < ascent || !setMaxAscent)) {
maxAscent = ascent;
- if (maxDescent < descent)
+ setMaxAscent = true;
+ }
+ if (affectsDescent && (maxDescent < descent || !setMaxDescent)) {
maxDescent = descent;
+ setMaxDescent = true;
+ }
}
if (curr->isInlineFlowBox())
- static_cast<InlineFlowBox*>(curr)->computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent, strictMode, textBoxDataMap);
+ static_cast<InlineFlowBox*>(curr)->computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent,
+ setMaxAscent, setMaxDescent, strictMode, textBoxDataMap,
+ baselineType, verticalPositionCache);
}
}
-void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom, bool& setLineTop)
+void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom, bool& setLineTop, FontBaseline baselineType)
{
if (isRootInlineBox())
- setLogicalTop(top + maxAscent - baselinePosition()); // Place our root box.
+ setLogicalTop(top + maxAscent - baselinePosition(baselineType)); // Place our root box.
for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
if (curr->renderer()->isPositioned())
@@ -493,7 +633,7 @@ void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAs
// line-height).
bool isInlineFlow = curr->isInlineFlowBox();
if (isInlineFlow)
- static_cast<InlineFlowBox*>(curr)->placeBoxesInBlockDirection(top, maxHeight, maxAscent, strictMode, lineTop, lineBottom, setLineTop);
+ static_cast<InlineFlowBox*>(curr)->placeBoxesInBlockDirection(top, maxHeight, maxAscent, strictMode, lineTop, lineBottom, setLineTop, baselineType);
bool childAffectsTopBottomPos = true;
if (curr->logicalTop() == PositionTop)
@@ -503,14 +643,14 @@ void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAs
else {
if ((isInlineFlow && !static_cast<InlineFlowBox*>(curr)->hasTextChildren()) && !curr->boxModelObject()->hasInlineDirectionBordersOrPadding() && !strictMode)
childAffectsTopBottomPos = false;
- int posAdjust = maxAscent - curr->baselinePosition();
+ int posAdjust = maxAscent - curr->baselinePosition(baselineType);
curr->setLogicalTop(curr->logicalTop() + top + posAdjust);
}
int newLogicalTop = curr->logicalTop();
if (curr->isText() || curr->isInlineFlowBox()) {
const Font& font = curr->renderer()->style(m_firstLine)->font();
- newLogicalTop += curr->baselinePosition() - font.ascent();
+ newLogicalTop += curr->baselinePosition(baselineType) - font.ascent(baselineType);
if (curr->isInlineFlowBox()) {
RenderBoxModelObject* boxObject = toRenderBoxModelObject(curr->renderer());
newLogicalTop -= boxObject->style(m_firstLine)->isHorizontalWritingMode() ? boxObject->borderTop() + boxObject->paddingTop() :
@@ -536,7 +676,7 @@ void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAs
if (isRootInlineBox()) {
const Font& font = renderer()->style(m_firstLine)->font();
- setLogicalTop(logicalTop() + baselinePosition() - font.ascent());
+ setLogicalTop(logicalTop() + baselinePosition(baselineType) - font.ascent(baselineType));
if (hasTextChildren() || strictMode) {
if (!setLineTop) {
diff --git a/WebCore/rendering/InlineFlowBox.h b/WebCore/rendering/InlineFlowBox.h
index be6dfd2..e3127af 100644
--- a/WebCore/rendering/InlineFlowBox.h
+++ b/WebCore/rendering/InlineFlowBox.h
@@ -30,6 +30,7 @@ class HitTestRequest;
class HitTestResult;
class InlineTextBox;
class RenderLineBoxList;
+class VerticalPositionCache;
typedef HashMap<const InlineTextBox*, pair<Vector<const SimpleFontData*>, GlyphOverflow> > GlyphOverflowAndFallbackFontsMap;
@@ -155,13 +156,15 @@ public:
bool onEndChain(RenderObject* endObject);
int placeBoxesInInlineDirection(int logicalLeft, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap&);
void computeLogicalBoxHeights(int& maxPositionTop, int& maxPositionBottom,
- int& maxAscent, int& maxDescent, bool strictMode, GlyphOverflowAndFallbackFontsMap&);
+ int& maxAscent, int& maxDescent, bool& setMaxAscent, bool& setMaxDescent,
+ bool strictMode, GlyphOverflowAndFallbackFontsMap&, FontBaseline, VerticalPositionCache&);
void adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
int maxPositionTop, int maxPositionBottom);
- void placeBoxesInBlockDirection(int logicalTop, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom, bool& setLineTop);
+ void placeBoxesInBlockDirection(int logicalTop, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom, bool& setLineTop, FontBaseline);
void flipLinesInBlockDirection(int lineTop, int lineBottom);
void computeBlockDirectionOverflow(int lineTop, int lineBottom, bool strictMode, GlyphOverflowAndFallbackFontsMap&);
-
+ bool requiresIdeographicBaseline(const GlyphOverflowAndFallbackFontsMap&) const;
+
void removeChild(InlineBox* child);
virtual RenderObject::SelectionState selectionState();
diff --git a/WebCore/rendering/InlineTextBox.cpp b/WebCore/rendering/InlineTextBox.cpp
index 9c96cc6..575bdf2 100644
--- a/WebCore/rendering/InlineTextBox.cpp
+++ b/WebCore/rendering/InlineTextBox.cpp
@@ -43,11 +43,11 @@ using namespace std;
namespace WebCore {
-int InlineTextBox::baselinePosition() const
+int InlineTextBox::baselinePosition(FontBaseline baselineType) const
{
if (!isText() || !parent())
return 0;
- return parent()->baselinePosition();
+ return parent()->baselinePosition(baselineType);
}
int InlineTextBox::lineHeight() const
@@ -171,9 +171,7 @@ IntRect InlineTextBox::selectionRect(int tx, int ty, int startPos, int endPos)
int width = isHorizontal() ? logicalWidth : selHeight;
int height = isHorizontal() ? selHeight : logicalWidth;
- IntRect result = IntRect(topPoint, IntSize(width, height));
- flipForWritingMode(result);
- return result;
+ return IntRect(topPoint, IntSize(width, height));
}
void InlineTextBox::deleteLine(RenderArena* arena)
diff --git a/WebCore/rendering/InlineTextBox.h b/WebCore/rendering/InlineTextBox.h
index e72d625..bc2219b 100644
--- a/WebCore/rendering/InlineTextBox.h
+++ b/WebCore/rendering/InlineTextBox.h
@@ -70,7 +70,7 @@ public:
static inline bool compareByStart(const InlineTextBox* first, const InlineTextBox* second) { return first->start() < second->start(); }
- virtual int baselinePosition() const;
+ virtual int baselinePosition(FontBaseline) const;
virtual int lineHeight() const;
private:
diff --git a/WebCore/rendering/MediaControlElements.cpp b/WebCore/rendering/MediaControlElements.cpp
index adaac03..1af1b80 100644
--- a/WebCore/rendering/MediaControlElements.cpp
+++ b/WebCore/rendering/MediaControlElements.cpp
@@ -166,7 +166,7 @@ bool MediaControlElement::rendererIsNeeded(RenderStyle* style)
{
ASSERT(document()->page());
- return HTMLDivElement::rendererIsNeeded(style) && parent() && parent()->renderer()
+ return HTMLDivElement::rendererIsNeeded(style) && parentNode() && parentNode()->renderer()
&& (!style->hasAppearance() || document()->page()->theme()->shouldRenderMediaControlPart(style->appearance(), m_mediaElement));
}
@@ -183,12 +183,12 @@ void MediaControlElement::attach()
return;
renderer->setStyle(style.get());
setRenderer(renderer);
- if (parent() && parent()->renderer()) {
+ if (parentNode() && parentNode()->renderer()) {
// Find next sibling with a renderer to determine where to insert.
Node* sibling = nextSibling();
while (sibling && !sibling->renderer())
sibling = sibling->nextSibling();
- parent()->renderer()->addChild(renderer, sibling ? sibling->renderer() : 0);
+ parentNode()->renderer()->addChild(renderer, sibling ? sibling->renderer() : 0);
}
ContainerNode::attach();
}
@@ -202,7 +202,7 @@ void MediaControlElement::updateStyle()
if (!style)
return;
- bool needsRenderer = rendererIsNeeded(style.get()) && parent() && parent()->renderer();
+ bool needsRenderer = rendererIsNeeded(style.get()) && parentNode() && parentNode()->renderer();
if (renderer() && !needsRenderer)
detach();
else if (!renderer() && needsRenderer)
@@ -416,7 +416,7 @@ bool MediaControlInputElement::rendererIsNeeded(RenderStyle* style)
{
ASSERT(document()->page());
- return HTMLInputElement::rendererIsNeeded(style) && parent() && parent()->renderer()
+ return HTMLInputElement::rendererIsNeeded(style) && parentNode() && parentNode()->renderer()
&& (!style->hasAppearance() || document()->page()->theme()->shouldRenderMediaControlPart(style->appearance(), mediaElement()));
}
@@ -434,12 +434,12 @@ void MediaControlInputElement::attach()
return;
renderer->setStyle(style.get());
setRenderer(renderer);
- if (parent() && parent()->renderer()) {
+ if (parentNode() && parentNode()->renderer()) {
// Find next sibling with a renderer to determine where to insert.
Node* sibling = nextSibling();
while (sibling && !sibling->renderer())
sibling = sibling->nextSibling();
- parent()->renderer()->addChild(renderer, sibling ? sibling->renderer() : 0);
+ parentNode()->renderer()->addChild(renderer, sibling ? sibling->renderer() : 0);
}
ContainerNode::attach();
}
@@ -453,7 +453,7 @@ void MediaControlInputElement::updateStyle()
if (!style)
return;
- bool needsRenderer = rendererIsNeeded(style.get()) && parent() && parent()->renderer();
+ bool needsRenderer = rendererIsNeeded(style.get()) && parentNode() && parentNode()->renderer();
if (renderer() && !needsRenderer)
detach();
else if (!renderer() && needsRenderer)
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index a43fea9..aadc1d4 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -931,11 +931,9 @@ static bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObje
if (prev && prev->firstChild() && prev->firstChild()->isInline() && prev->firstChild()->isRunIn())
return false;
-#if ENABLE(RUBY)
if ((prev && (prev->isRubyRun() || prev->isRubyBase()))
|| (next && (next->isRubyRun() || next->isRubyBase())))
return false;
-#endif
if (!prev || !next)
return true;
@@ -1164,7 +1162,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren, int pageHeight)
colInfo->clearForcedBreaks();
}
- LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection(), pageHeight, pageHeightChanged, colInfo);
+ LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode(), pageHeight, pageHeightChanged, colInfo);
// We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track
// our current maximal positive and negative margins. These values are used when we
@@ -1997,7 +1995,7 @@ bool RenderBlock::layoutOnlyPositionedObjects()
if (!posChildNeedsLayout() || normalChildNeedsLayout() || selfNeedsLayout())
return false;
- LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection());
+ LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
if (needsPositionedMovementLayout()) {
tryLayoutDoingPositionedMovementOnly();
@@ -2583,8 +2581,9 @@ void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
if (RenderLayer* layer = enclosingLayer()) {
gapRectsBounds.move(IntSize(-tx, -ty));
if (!hasLayer()) {
- FloatRect localBounds(gapRectsBounds);
- gapRectsBounds = localToContainerQuad(localBounds, layer->renderer()).enclosingBoundingBox();
+ IntRect localBounds(gapRectsBounds);
+ flipForWritingMode(localBounds);
+ gapRectsBounds = localToContainerQuad(FloatRect(localBounds), layer->renderer()).enclosingBoundingBox();
gapRectsBounds.move(layer->scrolledContentOffset());
}
layer->addBlockSelectionGapsBounds(gapRectsBounds);
@@ -3978,8 +3977,12 @@ void RenderBlock::addIntrudingFloats(RenderBlock* prev, int logicalLeftOffset, i
// above. |logicalLeftOffset| will equal the margin in this case, so it's already been taken
// into account. Only apply this code if prev is the parent, since otherwise the left margin
// will get applied twice.
- if (prev != parent())
- floatingObj->setLeft(floatingObj->left() + (style()->isHorizontalWritingMode() ? prev->marginLeft() : prev->marginTop()));
+ if (prev != parent()) {
+ if (style()->isHorizontalWritingMode())
+ floatingObj->setLeft(floatingObj->left() + prev->marginLeft());
+ else
+ floatingObj->setTop(floatingObj->top() + prev->marginTop());
+ }
floatingObj->m_shouldPaint = false; // We are not in the direct inheritance chain for this float. We will never paint it.
floatingObj->m_renderer = r->m_renderer;
@@ -4150,7 +4153,7 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) {
IntRect boundsRect(tx, ty, width(), height());
if (visibleToHitTesting() && boundsRect.intersects(result.rectForPoint(_x, _y))) {
- updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
+ updateHitTestResult(result, flipForWritingMode(IntPoint(_x - tx, _y - ty)));
if (!result.addNodeToRectBasedTestResult(node(), _x, _y, boundsRect))
return true;
}
@@ -4174,8 +4177,8 @@ bool RenderBlock::hitTestFloats(const HitTestRequest& request, HitTestResult& re
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 yOffset = floatingObject->top() + floatingObject->m_renderer->marginTop() - floatingObject->m_renderer->y();
+ IntPoint childPoint = flipForWritingMode(floatingObject->m_renderer, IntPoint(tx + xOffset, ty + yOffset), ParentToChildFlippingAdjustment);
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;
@@ -4278,8 +4281,9 @@ Position RenderBlock::positionForRenderer(RenderObject* renderer, bool start) co
// 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.
-static VisiblePosition positionForPointRespectingEditingBoundaries(RenderBox* parent, RenderBox* child, const IntPoint& pointInParentCoordinates)
+static VisiblePosition positionForPointRespectingEditingBoundaries(RenderBlock* parent, RenderBox* child, const IntPoint& pointInParentCoordinates)
{
+ // FIXME: This is wrong if the child's writing-mode is different from the parent's.
IntPoint pointInChildCoordinates(pointInParentCoordinates - child->location());
// If this is an anonymous renderer, we just recur normally
@@ -4297,14 +4301,15 @@ static VisiblePosition positionForPointRespectingEditingBoundaries(RenderBox* pa
if (!ancestor || ancestor->node()->isContentEditable() == childNode->isContentEditable())
return child->positionForPoint(pointInChildCoordinates);
- // Otherwise return before or after the child, depending on if the click was left or right of the child
- int childMidX = child->width() / 2;
- if (pointInChildCoordinates.x() < childMidX)
+ // Otherwise return before or after the child, depending on if the click was to the logical left or logical right of the child
+ int childMiddle = parent->logicalWidthForChild(child) / 2;
+ int logicalLeft = parent->style()->isHorizontalWritingMode() ? pointInChildCoordinates.x() : pointInChildCoordinates.y();
+ if (logicalLeft < childMiddle)
return ancestor->createVisiblePosition(childNode->nodeIndex(), DOWNSTREAM);
return ancestor->createVisiblePosition(childNode->nodeIndex() + 1, UPSTREAM);
}
-VisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint& pointInContents)
+VisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint& pointInLogicalContents)
{
ASSERT(childrenInline());
@@ -4323,8 +4328,8 @@ VisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint&
lastRootBoxWithChildren = root;
// check if this root line box is located at this y coordinate
- if (pointInContents.y() < root->selectionBottom()) {
- closestBox = root->closestLeafChildForXPos(pointInContents.x());
+ if (pointInLogicalContents.y() < root->selectionBottom()) {
+ closestBox = root->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
if (closestBox)
break;
}
@@ -4334,17 +4339,22 @@ VisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint&
if (!moveCaretToBoundary && !closestBox && lastRootBoxWithChildren) {
// y coordinate is below last root line box, pretend we hit it
- closestBox = lastRootBoxWithChildren->closestLeafChildForXPos(pointInContents.x());
+ closestBox = lastRootBoxWithChildren->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
}
if (closestBox) {
- if (moveCaretToBoundary && pointInContents.y() < firstRootBoxWithChildren->selectionTop()) {
+ if (moveCaretToBoundary && pointInLogicalContents.y() < firstRootBoxWithChildren->selectionTop()) {
// y coordinate is above first root line box, so return the start of the first
return VisiblePosition(positionForBox(firstRootBoxWithChildren->firstLeafChild(), true), DOWNSTREAM);
}
- // pass the box a y position that is inside it
- return closestBox->renderer()->positionForPoint(IntPoint(pointInContents.x(), closestBox->m_y));
+ // pass the box a top position that is inside it
+ IntPoint point(pointInLogicalContents.x(), closestBox->logicalTop());
+ if (!style()->isHorizontalWritingMode())
+ point = point.transposedPoint();
+ if (closestBox->renderer()->isReplaced())
+ return positionForPointRespectingEditingBoundaries(this, toRenderBox(closestBox->renderer()), point);
+ return closestBox->renderer()->positionForPoint(point);
}
if (lastRootBoxWithChildren) {
@@ -4370,9 +4380,13 @@ VisiblePosition RenderBlock::positionForPoint(const IntPoint& point)
return RenderBox::positionForPoint(point);
if (isReplaced()) {
- if (point.y() < 0 || (point.y() < height() && point.x() < 0))
+ // FIXME: This seems wrong when the object's writing-mode doesn't match the line's writing-mode.
+ int pointLogicalLeft = style()->isHorizontalWritingMode() ? point.x() : point.y();
+ int pointLogicalTop = style()->isHorizontalWritingMode() ? point.y() : point.x();
+
+ if (pointLogicalTop < 0 || (pointLogicalTop < logicalHeight() && pointLogicalLeft < 0))
return createVisiblePosition(caretMinOffset(), DOWNSTREAM);
- if (point.y() >= height() || (point.y() >= 0 && point.x() >= width()))
+ if (pointLogicalTop >= logicalHeight() || (pointLogicalTop >= 0 && pointLogicalLeft >= logicalWidth()))
return createVisiblePosition(caretMaxOffset(), DOWNSTREAM);
}
@@ -4380,11 +4394,14 @@ VisiblePosition RenderBlock::positionForPoint(const IntPoint& point)
int contentsY = point.y();
offsetForContents(contentsX, contentsY);
IntPoint pointInContents(contentsX, contentsY);
+ IntPoint pointInLogicalContents(pointInContents);
+ if (!style()->isHorizontalWritingMode())
+ pointInLogicalContents = pointInLogicalContents.transposedPoint();
if (childrenInline())
- return positionForPointWithInlineChildren(pointInContents);
+ return positionForPointWithInlineChildren(pointInLogicalContents);
- if (lastChildBox() && contentsY > lastChildBox()->y()) {
+ if (lastChildBox() && pointInContents.y() > lastChildBox()->logicalTop()) {
for (RenderBox* childBox = lastChildBox(); childBox; childBox = childBox->previousSiblingBox()) {
if (isChildHitTestCandidate(childBox))
return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents);
@@ -4392,7 +4409,7 @@ VisiblePosition RenderBlock::positionForPoint(const IntPoint& point)
} else {
for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
// We hit child if our click is above the bottom of its padding box (like IE6/7 and FF3).
- if (isChildHitTestCandidate(childBox) && contentsY < childBox->frameRect().bottom())
+ if (isChildHitTestCandidate(childBox) && pointInContents.y() < childBox->logicalBottom())
return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents);
}
}
@@ -5255,7 +5272,7 @@ int RenderBlock::lineHeight(bool firstLine, LineDirectionMode direction, LinePos
return m_lineHeight;
}
-int RenderBlock::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
+int RenderBlock::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
{
// Inline blocks are replaced elements. Otherwise, just pass off to
// the base class. If we're being queried as though we're the root line
@@ -5276,28 +5293,29 @@ int RenderBlock::baselinePosition(bool firstLine, LineDirectionMode direction, L
// vertically (e.g., an overflow:hidden block that has had scrollTop moved) or if the baseline is outside
// of our content box.
bool ignoreBaseline = (layer() && (layer()->marquee() || (direction == HorizontalLine ? (layer()->verticalScrollbar() || layer()->scrollYOffset() != 0)
- : (layer()->horizontalScrollbar() || layer()->scrollXOffset() != 0)))) || isWritingModeRoot();
+ : (layer()->horizontalScrollbar() || layer()->scrollXOffset() != 0)))) || (isWritingModeRoot() && !isRubyRun());
+
int baselinePos = ignoreBaseline ? -1 : lastLineBoxBaseline();
int bottomOfContent = direction == HorizontalLine ? borderTop() + paddingTop() + contentHeight() : borderRight() + paddingRight() + contentWidth();
if (baselinePos != -1 && baselinePos <= bottomOfContent)
return direction == HorizontalLine ? marginTop() + baselinePos : marginRight() + baselinePos;
- return RenderBox::baselinePosition(firstLine, direction, linePositionMode);
+ return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
}
const Font& f = style(firstLine)->font();
- return f.ascent() + (lineHeight(firstLine, direction, linePositionMode) - f.height()) / 2;
+ return f.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - f.height()) / 2;
}
int RenderBlock::firstLineBoxBaseline() const
{
- if (!isBlockFlow() || isWritingModeRoot())
+ if (!isBlockFlow() || (isWritingModeRoot() && !isRubyRun()))
return -1;
if (childrenInline()) {
if (firstLineBox())
- return firstLineBox()->logicalTop() + style(true)->font().ascent();
+ return firstLineBox()->logicalTop() + style(true)->font().ascent(firstRootBox()->baselineType());
else
return -1;
}
@@ -5316,7 +5334,7 @@ int RenderBlock::firstLineBoxBaseline() const
int RenderBlock::lastLineBoxBaseline() const
{
- if (!isBlockFlow() || isWritingModeRoot())
+ if (!isBlockFlow() || (isWritingModeRoot() && !isRubyRun()))
return -1;
LineDirectionMode lineDirection = style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
@@ -5327,7 +5345,7 @@ int RenderBlock::lastLineBoxBaseline() const
return f.ascent() + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - f.height()) / 2 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
}
if (lastLineBox())
- return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->font().ascent();
+ return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->font().ascent(lastRootBox()->baselineType());
return -1;
} else {
bool haveNormalFlowChild = false;
diff --git a/WebCore/rendering/RenderBlock.h b/WebCore/rendering/RenderBlock.h
index 1cc89c0..645c0ec 100644
--- a/WebCore/rendering/RenderBlock.h
+++ b/WebCore/rendering/RenderBlock.h
@@ -58,7 +58,7 @@ public:
// These two functions are overridden for inline-block.
virtual int lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
- virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+ virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
RenderLineBoxList* lineBoxes() { return &m_lineBoxes; }
const RenderLineBoxList* lineBoxes() const { return &m_lineBoxes; }
@@ -458,7 +458,7 @@ private:
RootInlineBox* constructLine(unsigned runCount, BidiRun* firstRun, BidiRun* lastRun, bool firstLine, bool lastLine, RenderObject* endObject);
InlineFlowBox* createLineBoxes(RenderObject*, bool firstLine);
void computeInlineDirectionPositionsForLine(RootInlineBox*, bool firstLine, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&);
- void computeBlockDirectionPositionsForLine(RootInlineBox*, BidiRun*, GlyphOverflowAndFallbackFontsMap&);
+ void computeBlockDirectionPositionsForLine(RootInlineBox*, BidiRun*, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
void deleteEllipsisLineBoxes();
void checkLinesForTextOverflow();
void addOverflowFromInlineChildren();
diff --git a/WebCore/rendering/RenderBlockLineLayout.cpp b/WebCore/rendering/RenderBlockLineLayout.cpp
index e843110..b6dc39f 100644
--- a/WebCore/rendering/RenderBlockLineLayout.cpp
+++ b/WebCore/rendering/RenderBlockLineLayout.cpp
@@ -35,6 +35,7 @@
#include "RenderView.h"
#include "Settings.h"
#include "TrailingFloatsRootInlineBox.h"
+#include "VerticalPositionCache.h"
#include "break_lines.h"
#include <wtf/AlwaysInline.h>
#include <wtf/RefCountedLeakCounter.h>
@@ -477,9 +478,10 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
lineBox->placeBoxesInInlineDirection(logicalLeft, needsWordSpacing, textBoxDataMap);
}
-void RenderBlock::computeBlockDirectionPositionsForLine(RootInlineBox* lineBox, BidiRun* firstRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap)
+void RenderBlock::computeBlockDirectionPositionsForLine(RootInlineBox* lineBox, BidiRun* firstRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap,
+ VerticalPositionCache& verticalPositionCache)
{
- setLogicalHeight(lineBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap));
+ setLogicalHeight(lineBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, verticalPositionCache));
lineBox->setBlockLogicalHeight(logicalHeight());
// Now make sure we place replaced render objects correctly.
@@ -639,6 +641,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
if (fullLayout || o->selfNeedsLayout())
dirtyLineBoxesForRenderer(o, fullLayout);
o->setNeedsLayout(false);
+<<<<<<< HEAD
#ifdef ANDROID_LAYOUT
if (doTextWrap && !hasTextToWrap && o->isText()) {
Node* node = o->node();
@@ -661,6 +664,8 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
#endif
if (!o->isText())
toRenderInline(o)->invalidateVerticalPosition(); // FIXME: Should do better here and not always invalidate everything.
+=======
+>>>>>>> webkit.org at r72274
}
o = bidiNext(this, o, 0, false, &endOfInline);
}
@@ -783,6 +788,8 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
bool isLineEmpty = true;
bool paginated = view()->layoutState() && view()->layoutState()->isPaginated();
+ VerticalPositionCache verticalPositionCache;
+
while (!end.atEnd()) {
// FIXME: Is this check necessary before the first iteration or can it be moved to the end?
if (checkForEndLineMatch && (endLineMatched = matchedEndLine(resolver, cleanLineStart, cleanLineBidiStatus, endLine, endLineLogicalTop, repaintLogicalBottom, repaintLogicalTop)))
@@ -883,7 +890,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
computeInlineDirectionPositionsForLine(lineBox, firstLine, resolver.firstRun(), trailingSpaceRun, end.atEnd(), textBoxDataMap);
// Now position our text runs vertically.
- computeBlockDirectionPositionsForLine(lineBox, resolver.firstRun(), textBoxDataMap);
+ computeBlockDirectionPositionsForLine(lineBox, resolver.firstRun(), textBoxDataMap, verticalPositionCache);
#if ENABLE(SVG)
// SVG text layout code computes vertical & horizontal positions on its own.
@@ -1013,7 +1020,8 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
m_lineBoxes.appendLineBox(trailingFloatsLineBox);
trailingFloatsLineBox->setConstructed();
GlyphOverflowAndFallbackFontsMap textBoxDataMap;
- trailingFloatsLineBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap);
+ VerticalPositionCache verticalPositionCache;
+ trailingFloatsLineBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, verticalPositionCache);
trailingFloatsLineBox->setBlockDirectionOverflowPositions(logicalHeight(), bottomLayoutOverflow, logicalHeight(), bottomVisualOverflow);
trailingFloatsLineBox->setBlockLogicalHeight(logicalHeight());
}
@@ -2162,66 +2170,38 @@ void RenderBlock::addOverflowFromInlineChildren()
int RenderBlock::beforeSideVisibleOverflowForLine(RootInlineBox* line) const
{
- switch (style()->writingMode()) {
- case TopToBottomWritingMode:
+ // 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.
+ if (style()->isHorizontalWritingMode())
return line->topVisibleOverflow();
- case LeftToRightWritingMode:
- return line->leftVisibleOverflow();
- case RightToLeftWritingMode:
- return line->rightVisibleOverflow();
- case BottomToTopWritingMode:
- return line->bottomVisibleOverflow();
- }
- ASSERT_NOT_REACHED();
- return line->topVisibleOverflow();
+ return line->leftVisibleOverflow();
}
int RenderBlock::afterSideVisibleOverflowForLine(RootInlineBox* line) const
{
- switch (style()->writingMode()) {
- case TopToBottomWritingMode:
+ // 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.
+ if (style()->isHorizontalWritingMode())
return line->bottomVisibleOverflow();
- case LeftToRightWritingMode:
- return line->rightVisibleOverflow();
- case RightToLeftWritingMode:
- return line->leftVisibleOverflow();
- case BottomToTopWritingMode:
- return line->topVisibleOverflow();
- }
- ASSERT_NOT_REACHED();
- return line->bottomVisibleOverflow();
+ return line->rightVisibleOverflow();
}
int RenderBlock::beforeSideLayoutOverflowForLine(RootInlineBox* line) const
{
- switch (style()->writingMode()) {
- case TopToBottomWritingMode:
+ // 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.
+ if (style()->isHorizontalWritingMode())
return line->topLayoutOverflow();
- case LeftToRightWritingMode:
- return line->leftLayoutOverflow();
- case RightToLeftWritingMode:
- return line->rightLayoutOverflow();
- case BottomToTopWritingMode:
- return line->bottomLayoutOverflow();
- }
- ASSERT_NOT_REACHED();
- return line->topLayoutOverflow();
+ return line->leftLayoutOverflow();
}
int RenderBlock::afterSideLayoutOverflowForLine(RootInlineBox* line) const
{
- switch (style()->writingMode()) {
- case TopToBottomWritingMode:
+ // 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.
+ if (style()->isHorizontalWritingMode())
return line->bottomLayoutOverflow();
- case LeftToRightWritingMode:
- return line->rightLayoutOverflow();
- case RightToLeftWritingMode:
- return line->leftLayoutOverflow();
- case BottomToTopWritingMode:
- return line->topLayoutOverflow();
- }
- ASSERT_NOT_REACHED();
- return line->bottomLayoutOverflow();
+ return line->rightLayoutOverflow();
}
void RenderBlock::deleteEllipsisLineBoxes()
diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp
index fc617c4..41e2cd5 100644
--- a/WebCore/rendering/RenderBox.cpp
+++ b/WebCore/rendering/RenderBox.cpp
@@ -297,15 +297,13 @@ void RenderBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle
// If our zoom factor changes and we have a defined scrollLeft/Top, we need to adjust that value into the
// new zoomed coordinate space.
if (hasOverflowClip() && oldStyle && style() && oldStyle->effectiveZoom() != style()->effectiveZoom()) {
- int left = scrollLeft();
- if (left) {
+ if (int left = layer()->scrollXOffset()) {
left = (left / oldStyle->effectiveZoom()) * style()->effectiveZoom();
- setScrollLeft(left);
+ layer()->scrollToXOffset(left);
}
- int top = scrollTop();
- if (top) {
+ if (int top = layer()->scrollYOffset()) {
top = (top / oldStyle->effectiveZoom()) * style()->effectiveZoom();
- setScrollTop(top);
+ layer()->scrollToYOffset(top);
}
}
@@ -387,7 +385,7 @@ void RenderBox::layout()
return;
}
- LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()));
+ LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), style()->isFlippedBlocksWritingMode());
while (child) {
child->layoutIfNeeded();
ASSERT(!child->needsLayout());
@@ -1183,7 +1181,7 @@ void RenderBox::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool
fixed |= isFixedPos;
IntSize containerOffset = offsetFromContainer(o, roundedIntPoint(transformState.mappedPoint()));
-
+
bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
if (useTransforms && shouldUseTransformFromContainer(o)) {
TransformationMatrix t;
@@ -1243,9 +1241,11 @@ IntSize RenderBox::offsetFromContainer(RenderObject* o, const IntPoint& point) c
offset += relativePositionOffset();
if (!isInline() || isReplaced()) {
- if (style()->position() != AbsolutePosition && style()->position() != FixedPosition)
+ if (style()->position() != AbsolutePosition && style()->position() != FixedPosition) {
o->adjustForColumns(offset, IntPoint(point.x() + x(), point.y() + y()));
- offset.expand(x(), y());
+ offset += locationOffsetIncludingFlipping();
+ } else
+ offset += locationOffset();
}
if (o->hasOverflowClip())
@@ -1338,12 +1338,21 @@ IntRect RenderBox::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintCo
r.inflate(v->maximalOutlineSize());
}
}
+
computeRectForRepaint(repaintContainer, r);
return r;
}
void RenderBox::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed)
{
+ // The rect we compute at each step is shifted by our x/y offset in the parent container's coordinate space.
+ // Only when we cross a writing mode boundary will we have to possibly flipForWritingMode (to convert into a more appropriate
+ // offset corner for the enclosing container). This allows for a fully RL or BT document to repaint
+ // properly even during layout, since the rect remains flipped all the way until the end.
+ //
+ // RenderView::computeRectForRepaint then converts the rect to physical coordinates. We also convert to
+ // physical when we hit a repaintContainer boundary. Therefore the final rect returned is always in the
+ // physical coordinate space of the repaintContainer.
if (RenderView* v = view()) {
// LayoutState is only valid for root-relative repainting
if (v->layoutStateEnabled() && !repaintContainer) {
@@ -1366,14 +1375,19 @@ void RenderBox::computeRectForRepaint(RenderBoxModelObject* repaintContainer, In
if (hasReflection())
rect.unite(reflectedRect(rect));
- if (repaintContainer == this)
+ if (repaintContainer == this) {
+ if (repaintContainer->style()->isFlippedBlocksWritingMode())
+ flipForWritingMode(rect);
return;
+ }
bool containerSkipped;
RenderObject* o = container(repaintContainer, &containerSkipped);
if (!o)
return;
+ if (isWritingModeRoot() && !isPositioned())
+ flipForWritingMode(rect);
IntPoint topLeft = rect.location();
topLeft.move(x(), y());
@@ -1433,10 +1447,7 @@ void RenderBox::computeRectForRepaint(RenderBoxModelObject* repaintContainer, In
rect.move(-containerOffset);
return;
}
-
- if (o->isBox())
- toRenderBox(o)->flipForWritingMode(rect);
-
+
o->computeRectForRepaint(repaintContainer, rect, fixed);
}
@@ -3164,7 +3175,7 @@ bool RenderBox::shrinkToAvoidFloats() const
bool RenderBox::avoidsFloats() const
{
- return isReplaced() || hasOverflowClip() || isHR() || isWritingModeRoot();
+ return isReplaced() || hasOverflowClip() || isHR() || isLegend() || isWritingModeRoot();
}
void RenderBox::addShadowOverflow()
@@ -3249,10 +3260,14 @@ int RenderBox::lineHeight(bool /*firstLine*/, LineDirectionMode direction, LineP
return 0;
}
-int RenderBox::baselinePosition(bool /*firstLine*/, LineDirectionMode direction, LinePositionMode /*linePositionMode*/) const
+int RenderBox::baselinePosition(FontBaseline baselineType, bool /*firstLine*/, LineDirectionMode direction, LinePositionMode /*linePositionMode*/) const
{
- if (isReplaced())
- return direction == HorizontalLine ? m_marginTop + height() + m_marginBottom : m_marginRight + width() + m_marginLeft;
+ if (isReplaced()) {
+ int result = direction == HorizontalLine ? m_marginTop + height() + m_marginBottom : m_marginRight + width() + m_marginLeft;
+ if (baselineType == AlphabeticBaseline)
+ return result;
+ return result - result / 2;
+ }
return 0;
}
@@ -3272,7 +3287,7 @@ void RenderBox::blockDirectionOverflow(bool isLineHorizontal, int& logicalTopLay
}
}
-IntPoint RenderBox::flipForWritingMode(RenderBox* child, const IntPoint& point, FlippingAdjustment adjustment)
+IntPoint RenderBox::flipForWritingMode(const RenderBox* child, const IntPoint& point, FlippingAdjustment adjustment) const
{
if (!style()->isFlippedBlocksWritingMode())
return point;
@@ -3284,7 +3299,7 @@ IntPoint RenderBox::flipForWritingMode(RenderBox* child, const IntPoint& point,
return IntPoint(point.x() + width() - child->width() - child->x() - (adjustment == ParentToChildFlippingAdjustment ? child->x() : 0), point.y());
}
-void RenderBox::flipForWritingMode(IntRect& rect)
+void RenderBox::flipForWritingMode(IntRect& rect) const
{
if (!style()->isFlippedBlocksWritingMode())
return;
@@ -3295,35 +3310,35 @@ void RenderBox::flipForWritingMode(IntRect& rect)
rect.setX(width() - rect.right());
}
-int RenderBox::flipForWritingMode(int position)
+int RenderBox::flipForWritingMode(int position) const
{
if (!style()->isFlippedBlocksWritingMode())
return position;
return logicalHeight() - position;
}
-IntPoint RenderBox::flipForWritingMode(const IntPoint& position)
+IntPoint RenderBox::flipForWritingMode(const IntPoint& position) const
{
if (!style()->isFlippedBlocksWritingMode())
return position;
return style()->isHorizontalWritingMode() ? IntPoint(position.x(), height() - position.y()) : IntPoint(width() - position.x(), position.y());
}
-IntSize RenderBox::flipForWritingMode(const IntSize& offset)
+IntSize RenderBox::flipForWritingMode(const IntSize& offset) const
{
if (!style()->isFlippedBlocksWritingMode())
return offset;
return style()->isHorizontalWritingMode() ? IntSize(offset.width(), height() - offset.height()) : IntSize(width() - offset.width(), offset.height());
}
-IntSize RenderBox::locationOffsetIncludingFlipping()
+IntSize RenderBox::locationOffsetIncludingFlipping() const
{
if (!parent() || !parent()->isBox())
return locationOffset();
- RenderBox* parent = parentBox();
- IntPoint localPoint = parent->flipForWritingMode(this, location(), ChildToParentFlippingAdjustment);
- return IntSize(localPoint.x(), localPoint.y());
+ IntRect rect(frameRect());
+ parentBox()->flipForWritingMode(rect);
+ return IntSize(rect.x(), rect.y());
}
} // namespace WebCore
diff --git a/WebCore/rendering/RenderBox.h b/WebCore/rendering/RenderBox.h
index ac96bb7..091796b 100644
--- a/WebCore/rendering/RenderBox.h
+++ b/WebCore/rendering/RenderBox.h
@@ -378,15 +378,15 @@ public:
bool isWritingModeRoot() const { return !parent() || parent()->style()->writingMode() != style()->writingMode(); }
virtual int lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
- virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+ virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
enum FlippingAdjustment { ChildToParentFlippingAdjustment, ParentToChildFlippingAdjustment };
- IntPoint flipForWritingMode(RenderBox* child, const IntPoint&, FlippingAdjustment);
- int flipForWritingMode(int position);
- IntPoint flipForWritingMode(const IntPoint&);
- IntSize flipForWritingMode(const IntSize&);
- void flipForWritingMode(IntRect&);
- IntSize locationOffsetIncludingFlipping();
+ 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;
+ IntSize flipForWritingMode(const IntSize&) const;
+ void flipForWritingMode(IntRect&) const;
+ IntSize locationOffsetIncludingFlipping() const;
#ifdef ANDROID_LAYOUT
int getVisibleWidth() const { return m_visibleWidth; }
diff --git a/WebCore/rendering/RenderBoxModelObject.cpp b/WebCore/rendering/RenderBoxModelObject.cpp
index ae89e0a..1580b49 100644
--- a/WebCore/rendering/RenderBoxModelObject.cpp
+++ b/WebCore/rendering/RenderBoxModelObject.cpp
@@ -845,53 +845,6 @@ void RenderBoxModelObject::calculateBackgroundImageGeometry(const FillLayer* fil
destRect.intersect(IntRect(tx, ty, w, h));
}
-int RenderBoxModelObject::verticalPosition(bool firstLine) const
-{
- // This method determines the vertical position for inline elements.
- ASSERT(isInline());
- if (!isInline())
- return 0;
-
- int vpos = 0;
- EVerticalAlign va = style()->verticalAlign();
- if (va == TOP)
- vpos = PositionTop;
- else if (va == BOTTOM)
- vpos = PositionBottom;
- else {
- bool checkParent = parent()->isRenderInline() && parent()->style()->verticalAlign() != TOP && parent()->style()->verticalAlign() != BOTTOM;
- vpos = checkParent ? toRenderInline(parent())->verticalPositionFromCache(firstLine) : 0;
- // don't allow elements nested inside text-top to have a different valignment.
- if (va == BASELINE)
- return vpos;
-
- const Font& f = parent()->style(firstLine)->font();
- int fontsize = f.pixelSize();
-
- LineDirectionMode lineDirection = parent()->style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
-
- if (va == SUB)
- vpos += fontsize / 5 + 1;
- else if (va == SUPER)
- vpos -= fontsize / 3 + 1;
- else if (va == TEXT_TOP)
- vpos += baselinePosition(firstLine, lineDirection) - f.ascent();
- else if (va == MIDDLE)
- vpos += -static_cast<int>(f.xHeight() / 2) - lineHeight(firstLine, lineDirection) / 2 + baselinePosition(firstLine, lineDirection);
- else if (va == TEXT_BOTTOM) {
- vpos += f.descent();
- // lineHeight - baselinePosition is always 0 for replaced elements (except inline blocks), so don't bother wasting time in that case.
- if (!isReplaced() || style()->display() == INLINE_BLOCK)
- vpos -= (lineHeight(firstLine, lineDirection) - baselinePosition(firstLine, lineDirection));
- } else if (va == BASELINE_MIDDLE)
- vpos += -lineHeight(firstLine, lineDirection) / 2 + baselinePosition(firstLine, lineDirection);
- else if (va == LENGTH)
- vpos -= style()->verticalAlignLength().calcValue(lineHeight(firstLine, lineDirection));
- }
-
- return vpos;
-}
-
bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext, int tx, int ty, int w, int h, const RenderStyle* style,
const NinePieceImage& ninePieceImage, CompositeOperator op)
{
diff --git a/WebCore/rendering/RenderBoxModelObject.h b/WebCore/rendering/RenderBoxModelObject.h
index 121601f..f502424 100644
--- a/WebCore/rendering/RenderBoxModelObject.h
+++ b/WebCore/rendering/RenderBoxModelObject.h
@@ -28,11 +28,6 @@
namespace WebCore {
-// Values for vertical alignment.
-const int PositionTop = -0x7fffffff;
-const int PositionBottom = 0x7fffffff;
-const int PositionUndefined = 0x80000000;
-
// Modes for some of the line-related functions.
enum LinePositionMode { PositionOnContainingLine, PositionOfInteriorLineBoxes };
enum LineDirectionMode { HorizontalLine, VerticalLine };
@@ -113,13 +108,10 @@ public:
bool paintNinePieceImage(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, const NinePieceImage&, CompositeOperator = CompositeSourceOver);
void paintBoxShadow(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, ShadowStyle, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true);
void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int width, int height, InlineFlowBox* = 0, CompositeOperator = CompositeSourceOver, RenderObject* backgroundObject = 0);
-
- // The difference between this inline's baseline position and the line's baseline position.
- int verticalPosition(bool firstLine) const;
// Overridden by subclasses to determine line height and baseline position.
virtual int lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const = 0;
- virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const = 0;
+ virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const = 0;
// Called by RenderObject::destroy() (and RenderWidget::destroy()) and is the only way layers should ever be destroyed
void destroyLayer();
diff --git a/WebCore/rendering/RenderFileUploadControl.cpp b/WebCore/rendering/RenderFileUploadControl.cpp
index 3da8530..82bd1fa 100644
--- a/WebCore/rendering/RenderFileUploadControl.cpp
+++ b/WebCore/rendering/RenderFileUploadControl.cpp
@@ -231,7 +231,7 @@ void RenderFileUploadControl::paintObject(PaintInfo& paintInfo, int tx, int ty)
RenderButton* buttonRenderer = toRenderButton(m_button->renderer());
int textY = buttonRenderer->absoluteBoundingBoxRect().y()
+ buttonRenderer->marginTop() + buttonRenderer->borderTop() + buttonRenderer->paddingTop()
- + buttonRenderer->baselinePosition(true, HorizontalLine, PositionOnContainingLine);
+ + buttonRenderer->baselinePosition(AlphabeticBaseline, true, HorizontalLine, PositionOnContainingLine);
paintInfo.context->setFillColor(style()->visitedDependentColor(CSSPropertyColor), style()->colorSpace());
diff --git a/WebCore/rendering/RenderFlexibleBox.cpp b/WebCore/rendering/RenderFlexibleBox.cpp
index d4dc75a..841442b 100644
--- a/WebCore/rendering/RenderFlexibleBox.cpp
+++ b/WebCore/rendering/RenderFlexibleBox.cpp
@@ -214,7 +214,7 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren, int /*pageHeight FIXM
return;
LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
- LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasTransform() || hasReflection());
+ LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
int previousWidth = width();
int previousHeight = height();
diff --git a/WebCore/rendering/RenderImage.cpp b/WebCore/rendering/RenderImage.cpp
index d21c1ea..48f21f1 100644
--- a/WebCore/rendering/RenderImage.cpp
+++ b/WebCore/rendering/RenderImage.cpp
@@ -61,6 +61,7 @@ using namespace HTMLNames;
RenderImage::RenderImage(Node* node)
: RenderReplaced(node, IntSize(0, 0))
+ , m_needsToSetSizeForAltText(false)
{
updateAltText();
@@ -89,34 +90,35 @@ static const unsigned short paddingHeight = 4;
static const int maxAltTextWidth = 1024;
static const int maxAltTextHeight = 256;
+IntSize RenderImage::imageSizeForError(CachedImage* newImage) const
+{
+ ASSERT_ARG(newImage, newImage);
+ ASSERT_ARG(newImage, newImage->image());
+
+ // imageSize() returns 0 for the error image. We need the true size of the
+ // error image, so we have to get it by grabbing image() directly.
+ return IntSize(paddingWidth + newImage->image()->width() * style()->effectiveZoom(), paddingHeight + newImage->image()->height() * style()->effectiveZoom());
+}
+
// Sets the image height and width to fit the alt text. Returns true if the
// image size changed.
bool RenderImage::setImageSizeForAltText(CachedImage* newImage /* = 0 */)
{
- int imageWidth = 0;
- int imageHeight = 0;
-
- // If we'll be displaying either text or an image, add a little padding.
- if (!m_altText.isEmpty() || newImage) {
- imageWidth = paddingWidth;
- imageHeight = paddingHeight;
- }
-
- if (newImage && newImage->image()) {
- // imageSize() returns 0 for the error image. We need the true size of the
- // error image, so we have to get it by grabbing image() directly.
- imageWidth += newImage->image()->width() * style()->effectiveZoom();
- imageHeight += newImage->image()->height() * style()->effectiveZoom();
+ IntSize imageSize;
+ if (newImage && newImage->image())
+ imageSize = imageSizeForError(newImage);
+ else if (!m_altText.isEmpty() || newImage) {
+ // If we'll be displaying either text or an image, add a little padding.
+ imageSize = IntSize(paddingWidth, paddingHeight);
}
-
+
// we have an alt and the user meant it (its not a text we invented)
if (!m_altText.isEmpty()) {
const Font& font = style()->font();
- imageWidth = max(imageWidth, min(font.width(TextRun(m_altText.characters(), m_altText.length())), maxAltTextWidth));
- imageHeight = max(imageHeight, min(font.height(), maxAltTextHeight));
+ IntSize textSize(min(font.width(TextRun(m_altText.characters(), m_altText.length())), maxAltTextWidth), min(font.height(), maxAltTextHeight));
+ imageSize = imageSize.expandedTo(textSize);
}
-
- IntSize imageSize = IntSize(imageWidth, imageHeight);
+
if (imageSize == intrinsicSize())
return false;
@@ -124,6 +126,16 @@ bool RenderImage::setImageSizeForAltText(CachedImage* newImage /* = 0 */)
return true;
}
+void RenderImage::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+ RenderReplaced::styleDidChange(diff, oldStyle);
+ if (m_needsToSetSizeForAltText) {
+ if (!m_altText.isEmpty() && setImageSizeForAltText(m_imageResource->cachedImage()))
+ imageDimensionsChanged(true /* imageSizeChanged */);
+ m_needsToSetSizeForAltText = false;
+ }
+}
+
void RenderImage::imageChanged(WrappedImagePtr newImage, const IntRect* rect)
{
if (documentBeingDestroyed())
@@ -141,12 +153,25 @@ void RenderImage::imageChanged(WrappedImagePtr newImage, const IntRect* rect)
bool imageSizeChanged = false;
// Set image dimensions, taking into account the size of the alt text.
- if (m_imageResource->errorOccurred())
+ if (m_imageResource->errorOccurred()) {
+ if (!m_altText.isEmpty() && document()->isPendingStyleRecalc()) {
+ ASSERT(node());
+ if (node()) {
+ m_needsToSetSizeForAltText = true;
+ node()->setNeedsStyleRecalc(SyntheticStyleChange);
+ }
+ return;
+ }
imageSizeChanged = setImageSizeForAltText(m_imageResource->cachedImage());
+ }
+
+ imageDimensionsChanged(imageSizeChanged, rect);
+}
+void RenderImage::imageDimensionsChanged(bool imageSizeChanged, const IntRect* rect)
+{
bool shouldRepaint = true;
- // Image dimensions have been changed, see what needs to be done
if (m_imageResource->imageSize(style()->effectiveZoom()) != intrinsicSize() || imageSizeChanged) {
if (!m_imageResource->errorOccurred())
setIntrinsicSize(m_imageResource->imageSize(style()->effectiveZoom()));
diff --git a/WebCore/rendering/RenderImage.h b/WebCore/rendering/RenderImage.h
index 308c863..86f5621 100644
--- a/WebCore/rendering/RenderImage.h
+++ b/WebCore/rendering/RenderImage.h
@@ -52,6 +52,8 @@ public:
void highQualityRepaintTimerFired(Timer<RenderImage>*);
protected:
+ virtual void styleDidChange(StyleDifference, const RenderStyle*);
+
virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
virtual void paintIntoRect(GraphicsContext*, const IntRect&);
@@ -83,13 +85,16 @@ private:
virtual int computeReplacedLogicalWidth(bool includeMaxWidth = true) const;
virtual int computeReplacedLogicalHeight() const;
+ IntSize imageSizeForError(CachedImage*) const;
+ void imageDimensionsChanged(bool imageSizeChanged, const IntRect* = 0);
+
int calcAspectRatioLogicalWidth() const;
int calcAspectRatioLogicalHeight() const;
-private:
// Text to display as long as the image isn't available.
String m_altText;
OwnPtr<RenderImageResource> m_imageResource;
+ bool m_needsToSetSizeForAltText;
friend class RenderImageScaleObserver;
};
diff --git a/WebCore/rendering/RenderInline.cpp b/WebCore/rendering/RenderInline.cpp
index 1a792e7..8f828f9 100644
--- a/WebCore/rendering/RenderInline.cpp
+++ b/WebCore/rendering/RenderInline.cpp
@@ -48,7 +48,6 @@ RenderInline::RenderInline(Node* node)
: RenderBoxModelObject(node)
, m_continuation(0)
, m_lineHeight(-1)
- , m_verticalPosition(PositionUndefined)
{
setChildrenInline(true);
}
@@ -628,7 +627,6 @@ IntRect RenderInline::clippedOverflowRectForRepaint(RenderBoxModelObject* repain
}
IntRect r(-ow + left, -ow + top, boundingBox.width() + ow * 2, boundingBox.height() + ow * 2);
- cb->flipForWritingMode(r);
if (cb->hasColumns())
cb->adjustRectForColumns(r);
@@ -904,23 +902,10 @@ int RenderInline::lineHeight(bool firstLine, LineDirectionMode /*direction*/, Li
return m_lineHeight;
}
-int RenderInline::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
+int RenderInline::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
{
const Font& f = style(firstLine)->font();
- return f.ascent() + (lineHeight(firstLine, direction, linePositionMode) - f.height()) / 2;
-}
-
-int RenderInline::verticalPositionFromCache(bool firstLine) const
-{
- if (firstLine) // We're only really a first-line style if the document actually uses first-line rules.
- firstLine = document()->usesFirstLineRules();
- int vpos = m_verticalPosition;
- if (m_verticalPosition == PositionUndefined || firstLine) {
- vpos = verticalPosition(firstLine);
- if (!firstLine)
- m_verticalPosition = vpos;
- }
- return vpos;
+ return f.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - f.height()) / 2;
}
IntSize RenderInline::relativePositionedInlineOffset(const RenderBox* child) const
diff --git a/WebCore/rendering/RenderInline.h b/WebCore/rendering/RenderInline.h
index 1eb32ff..399a167 100644
--- a/WebCore/rendering/RenderInline.h
+++ b/WebCore/rendering/RenderInline.h
@@ -77,9 +77,6 @@ public:
virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
void paintOutline(GraphicsContext*, int tx, int ty);
- int verticalPositionFromCache(bool firstLine) const;
- void invalidateVerticalPosition() { m_verticalPosition = PositionUndefined; }
-
protected:
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
@@ -134,7 +131,7 @@ private:
virtual void dirtyLinesFromChangedChild(RenderObject* child) { m_lineBoxes.dirtyLinesFromChangedChild(this, child); }
virtual int lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
- virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+ virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
virtual void childBecameNonInline(RenderObject* child);
@@ -159,7 +156,6 @@ private:
RenderBoxModelObject* m_continuation; // Can be either a block or an inline. <b><i><p>Hello</p></i></b>. In this example the <i> will have a block as its continuation but the
// <b> will just have an inline as its continuation.
mutable int m_lineHeight;
- mutable int m_verticalPosition;
};
inline RenderInline* toRenderInline(RenderObject* object)
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp
index 2f1032f..12360c8 100644
--- a/WebCore/rendering/RenderLayer.cpp
+++ b/WebCore/rendering/RenderLayer.cpp
@@ -3970,8 +3970,15 @@ void showLayerTree(const WebCore::RenderLayer* layer)
return;
if (WebCore::Frame* frame = layer->renderer()->frame()) {
- WTF::String output = externalRepresentation(frame, WebCore::RenderAsTextShowAllLayers | WebCore::RenderAsTextShowLayerNesting | WebCore::RenderAsTextShowCompositedLayers | WebCore::RenderAsTextShowAddresses | WebCore::RenderAsTextShowIDAndClass);
+ WTF::String output = externalRepresentation(frame, WebCore::RenderAsTextShowAllLayers | WebCore::RenderAsTextShowLayerNesting | WebCore::RenderAsTextShowCompositedLayers | WebCore::RenderAsTextShowAddresses | WebCore::RenderAsTextShowIDAndClass | WebCore::RenderAsTextDontUpdateLayout | WebCore::RenderAsTextShowLayoutState);
fprintf(stderr, "%s\n", output.utf8().data());
}
}
+
+void showLayerTree(const WebCore::RenderObject* renderer)
+{
+ if (!renderer)
+ return;
+ showLayerTree(renderer->enclosingLayer());
+}
#endif
diff --git a/WebCore/rendering/RenderLayer.h b/WebCore/rendering/RenderLayer.h
index 060c7c6..27d2b31 100644
--- a/WebCore/rendering/RenderLayer.h
+++ b/WebCore/rendering/RenderLayer.h
@@ -704,7 +704,8 @@ private:
#ifndef NDEBUG
// Outside the WebCore namespace for ease of invocation from gdb.
-void showLayerTree(const WebCore::RenderLayer* layer);
+void showLayerTree(const WebCore::RenderLayer*);
+void showLayerTree(const WebCore::RenderObject*);
#endif
#endif // RenderLayer_h
diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp
index 6f8dbc8..517a6d2 100644
--- a/WebCore/rendering/RenderLayerBacking.cpp
+++ b/WebCore/rendering/RenderLayerBacking.cpp
@@ -1152,7 +1152,7 @@ bool RenderLayerBacking::showRepaintCounter() const
bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim, const KeyframeList& keyframes)
{
bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity);
- bool hasTransform = keyframes.containsProperty(CSSPropertyWebkitTransform);
+ bool hasTransform = renderer()->isBox() && keyframes.containsProperty(CSSPropertyWebkitTransform);
if (!hasOpacity && !hasTransform)
return false;
diff --git a/WebCore/rendering/RenderListBox.cpp b/WebCore/rendering/RenderListBox.cpp
index 532c551..5717871 100644
--- a/WebCore/rendering/RenderListBox.cpp
+++ b/WebCore/rendering/RenderListBox.cpp
@@ -238,9 +238,9 @@ void RenderListBox::computeLogicalHeight()
}
}
-int RenderListBox::baselinePosition(bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
+int RenderListBox::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
{
- return RenderBox::baselinePosition(firstLine, lineDirection, linePositionMode) - baselineAdjustment;
+ return RenderBox::baselinePosition(baselineType, firstLine, lineDirection, linePositionMode) - baselineAdjustment;
}
IntRect RenderListBox::itemBoundingBoxRect(int tx, int ty, int index)
diff --git a/WebCore/rendering/RenderListBox.h b/WebCore/rendering/RenderListBox.h
index 072fc91..69acb57 100644
--- a/WebCore/rendering/RenderListBox.h
+++ b/WebCore/rendering/RenderListBox.h
@@ -71,7 +71,7 @@ private:
virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1, Node** stopNode = 0);
virtual void computePreferredLogicalWidths();
- virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+ virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
virtual void computeLogicalHeight();
virtual void layout();
diff --git a/WebCore/rendering/RenderListItem.cpp b/WebCore/rendering/RenderListItem.cpp
index 1f600fe..2b64f04 100644
--- a/WebCore/rendering/RenderListItem.cpp
+++ b/WebCore/rendering/RenderListItem.cpp
@@ -161,7 +161,7 @@ static RenderObject* getParentOfFirstLineBox(RenderBlock* curr, RenderObject* ma
if (currChild->isFloating() || currChild->isPositioned())
continue;
- if (currChild->isTable() || !currChild->isRenderBlock())
+ if (currChild->isTable() || !currChild->isRenderBlock() || (currChild->isBox() && toRenderBox(currChild)->isWritingModeRoot()))
break;
if (curr->isListItem() && inQuirksMode && currChild->node() &&
@@ -246,39 +246,39 @@ void RenderListItem::layout()
void RenderListItem::positionListMarker()
{
if (m_marker && m_marker->parent()->isBox() && !m_marker->isInside() && m_marker->inlineBoxWrapper()) {
- int markerOldX = m_marker->x();
- int yOffset = 0;
- int xOffset = 0;
+ int markerOldLogicalLeft = m_marker->logicalLeft();
+ int blockOffset = 0;
+ int lineOffset = 0;
for (RenderBox* o = m_marker->parentBox(); o != this; o = o->parentBox()) {
- yOffset += o->y();
- xOffset += o->x();
+ blockOffset += o->logicalTop();
+ lineOffset += o->logicalLeft();
}
bool adjustOverflow = false;
- int markerXPos;
+ int markerLogicalLeft;
RootInlineBox* root = m_marker->inlineBoxWrapper()->root();
// FIXME: Inline flows in the line box hierarchy that have self-painting layers should act as cutoff points
// and really shouldn't keep propagating overflow up. This won't really break anything other than repainting
// not being as tight as it could be though.
if (style()->isLeftToRightDirection()) {
- int leftLineOffset = logicalLeftOffsetForLine(yOffset, logicalLeftOffsetForLine(yOffset, false), false);
- markerXPos = leftLineOffset - xOffset - paddingLeft() - borderLeft() + m_marker->marginLeft();
- m_marker->inlineBoxWrapper()->adjustPosition(markerXPos - markerOldX, 0);
+ int leftLineOffset = logicalLeftOffsetForLine(blockOffset, logicalLeftOffsetForLine(blockOffset, false), false);
+ markerLogicalLeft = leftLineOffset - lineOffset - paddingStart() - borderStart() + m_marker->marginStart();
+ m_marker->inlineBoxWrapper()->adjustLineDirectionPosition(markerLogicalLeft - markerOldLogicalLeft);
for (InlineFlowBox* box = m_marker->inlineBoxWrapper()->parent(); box; box = box->parent()) {
- if (markerXPos < box->leftLayoutOverflow()) {
- box->setInlineDirectionOverflowPositions(markerXPos, box->rightLayoutOverflow(), box->leftVisualOverflow(), box->rightVisualOverflow());
+ if (markerLogicalLeft < box->logicalLeftLayoutOverflow()) {
+ box->setInlineDirectionOverflowPositions(markerLogicalLeft, box->logicalRightLayoutOverflow(), box->logicalLeftVisualOverflow(), box->logicalRightVisualOverflow());
if (box == root)
adjustOverflow = true;
}
}
} else {
- int rightLineOffset = logicalRightOffsetForLine(yOffset, logicalRightOffsetForLine(yOffset, false), false);
- markerXPos = rightLineOffset - xOffset + paddingRight() + borderRight() + m_marker->marginLeft();
- m_marker->inlineBoxWrapper()->adjustPosition(markerXPos - markerOldX, 0);
+ int rightLineOffset = logicalRightOffsetForLine(blockOffset, logicalRightOffsetForLine(blockOffset, false), false);
+ markerLogicalLeft = rightLineOffset - lineOffset + paddingStart() + borderStart() + m_marker->marginEnd();
+ m_marker->inlineBoxWrapper()->adjustLineDirectionPosition(markerLogicalLeft - markerOldLogicalLeft);
for (InlineFlowBox* box = m_marker->inlineBoxWrapper()->parent(); box; box = box->parent()) {
- if (markerXPos + m_marker->width() > box->rightLayoutOverflow()) {
- box->setInlineDirectionOverflowPositions(box->leftLayoutOverflow(), markerXPos + m_marker->width(), box->leftVisualOverflow(), box->rightVisualOverflow());
+ if (markerLogicalLeft + m_marker->logicalWidth() > box->logicalRightLayoutOverflow()) {
+ box->setInlineDirectionOverflowPositions(box->logicalLeftLayoutOverflow(), markerLogicalLeft + m_marker->logicalWidth(), box->logicalLeftVisualOverflow(), box->logicalRightVisualOverflow());
if (box == root)
adjustOverflow = true;
}
@@ -286,7 +286,9 @@ void RenderListItem::positionListMarker()
}
if (adjustOverflow) {
- IntRect markerRect(markerXPos + xOffset, yOffset, m_marker->width(), m_marker->height());
+ IntRect markerRect(markerLogicalLeft + lineOffset, blockOffset, m_marker->width(), m_marker->height());
+ if (!style()->isHorizontalWritingMode())
+ markerRect = markerRect.transposedRect();
RenderBox* o = m_marker;
do {
o = o->parentBox();
@@ -300,7 +302,7 @@ void RenderListItem::positionListMarker()
void RenderListItem::paint(PaintInfo& paintInfo, int tx, int ty)
{
- if (!height())
+ if (!logicalHeight())
return;
RenderBlock::paint(paintInfo, tx, ty);
diff --git a/WebCore/rendering/RenderListMarker.cpp b/WebCore/rendering/RenderListMarker.cpp
index ab5da61..2f33afb 100644
--- a/WebCore/rendering/RenderListMarker.cpp
+++ b/WebCore/rendering/RenderListMarker.cpp
@@ -1086,9 +1086,12 @@ IntRect RenderListMarker::localSelectionRect()
{
InlineBox* box = inlineBoxWrapper();
if (!box)
- return IntRect();
- RootInlineBox* root = box->root();
- return IntRect(x(), root->selectionTop() - y(), width(), root->selectionHeight());
+ return IntRect(0, 0, width(), height());
+ RootInlineBox* root = m_inlineBoxWrapper->root();
+ int newLogicalTop = root->block()->style()->isFlippedBlocksWritingMode() ? m_inlineBoxWrapper->logicalBottom() - root->selectionBottom() : root->selectionTop() - m_inlineBoxWrapper->logicalTop();
+ if (root->block()->style()->isHorizontalWritingMode())
+ return IntRect(0, newLogicalTop, width(), root->selectionHeight());
+ return IntRect(newLogicalTop, 0, root->selectionHeight(), height());
}
void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
@@ -1099,16 +1102,18 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
if (style()->visibility() != VISIBLE)
return;
- IntRect marker = getRelativeMarkerRect();
- marker.move(tx, ty);
-
- IntRect box(tx + x(), ty + y(), width(), height());
+ IntPoint boxOrigin(tx + x(), ty + y());
+ IntRect overflowRect(visibleOverflowRect());
+ overflowRect.move(boxOrigin.x(), boxOrigin.y());
+ overflowRect.inflate(maximalOutlineSize(paintInfo.phase));
- if (box.y() > paintInfo.rect.bottom() || box.y() + box.height() < paintInfo.rect.y())
+ if (!paintInfo.rect.intersects(overflowRect))
return;
- if (hasBoxDecorations())
- paintBoxDecorations(paintInfo, box.x(), box.y());
+ IntRect box(boxOrigin, IntSize(width(), height()));
+
+ IntRect marker = getRelativeMarkerRect();
+ marker.move(boxOrigin.x(), boxOrigin.y());
GraphicsContext* context = paintInfo.context;
@@ -1117,10 +1122,10 @@ 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.location());
+ context->drawImage(m_image->image(this, marker.size()), style()->colorSpace(), marker);
if (selectionState() != SelectionNone) {
IntRect selRect = localSelectionRect();
- selRect.move(tx, ty);
+ selRect.move(boxOrigin.x(), boxOrigin.y());
context->fillRect(selRect, selectionBackgroundColor(), style()->colorSpace());
}
return;
@@ -1134,7 +1139,7 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
if (selectionState() != SelectionNone) {
IntRect selRect = localSelectionRect();
- selRect.move(tx, ty);
+ selRect.move(boxOrigin.x(), boxOrigin.y());
context->fillRect(selRect, selectionBackgroundColor(), style()->colorSpace());
}
@@ -1146,10 +1151,6 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
EListStyleType type = style()->listStyleType();
switch (type) {
- case Asterisks:
- case Footnotes:
- context->drawText(style()->font(), TextRun(m_text), marker.location());
- return;
case Disc:
context->drawEllipse(marker);
return;
@@ -1235,6 +1236,8 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
case UpperNorwegian:
case UpperRoman:
case Urdu:
+ case Asterisks:
+ case Footnotes:
break;
}
if (m_text.isEmpty())
@@ -1242,32 +1245,51 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
TextRun textRun(m_text);
- // Text is not arbitrary. We can judge whether it's RTL from the first character,
- // and we only need to handle the direction RightToLeft for now.
- bool textNeedsReversing = direction(m_text[0]) == RightToLeft;
- Vector<UChar> reversedText;
- if (textNeedsReversing) {
- int length = m_text.length();
- reversedText.grow(length);
- for (int i = 0; i < length; ++i)
- reversedText[length - i - 1] = m_text[i];
- textRun = TextRun(reversedText.data(), length);
+ if (!style()->isHorizontalWritingMode()) {
+ marker.move(-boxOrigin.x(), -boxOrigin.y());
+ marker = marker.transposedRect();
+ marker.move(box.x(), box.y() - logicalHeight());
+ context->save();
+ context->translate(marker.x(), marker.bottom());
+ context->rotate(static_cast<float>(deg2rad(90.)));
+ context->translate(-marker.x(), -marker.bottom());
}
- const Font& font = style()->font();
- const UChar suffix = listMarkerSuffix(type, m_listItem->value());
- if (style()->isLeftToRightDirection()) {
- int width = font.width(textRun);
- context->drawText(style()->font(), textRun, marker.location());
- UChar suffixSpace[2] = { suffix, ' ' };
- context->drawText(style()->font(), TextRun(suffixSpace, 2), marker.location() + IntSize(width, 0));
- } else {
- UChar spaceSuffix[2] = { ' ', suffix };
- TextRun spaceSuffixRun(spaceSuffix, 2);
- int width = font.width(spaceSuffixRun);
- context->drawText(style()->font(), spaceSuffixRun, marker.location());
- context->drawText(style()->font(), textRun, marker.location() + IntSize(width, 0));
+ IntPoint textOrigin = IntPoint(marker.x(), marker.y() + style()->font().ascent());
+
+ if (type == Asterisks || type == Footnotes)
+ context->drawText(style()->font(), textRun, textOrigin);
+ else {
+ // Text is not arbitrary. We can judge whether it's RTL from the first character,
+ // and we only need to handle the direction RightToLeft for now.
+ bool textNeedsReversing = direction(m_text[0]) == RightToLeft;
+ Vector<UChar> reversedText;
+ if (textNeedsReversing) {
+ int length = m_text.length();
+ reversedText.grow(length);
+ for (int i = 0; i < length; ++i)
+ reversedText[length - i - 1] = m_text[i];
+ textRun = TextRun(reversedText.data(), length);
+ }
+
+ const Font& font = style()->font();
+ const UChar suffix = listMarkerSuffix(type, m_listItem->value());
+ if (style()->isLeftToRightDirection()) {
+ int width = font.width(textRun);
+ context->drawText(style()->font(), textRun, textOrigin);
+ UChar suffixSpace[2] = { suffix, ' ' };
+ context->drawText(style()->font(), TextRun(suffixSpace, 2), textOrigin + IntSize(width, 0));
+ } else {
+ UChar spaceSuffix[2] = { ' ', suffix };
+ TextRun spaceSuffixRun(spaceSuffix, 2);
+ int width = font.width(spaceSuffixRun);
+ context->drawText(style()->font(), spaceSuffixRun, textOrigin);
+ context->drawText(style()->font(), textRun, textOrigin + IntSize(width, 0));
+ }
}
+
+ if (!style()->isHorizontalWritingMode())
+ context->restore();
}
void RenderListMarker::layout()
@@ -1278,18 +1300,19 @@ void RenderListMarker::layout()
setWidth(m_image->imageSize(this, style()->effectiveZoom()).width());
setHeight(m_image->imageSize(this, style()->effectiveZoom()).height());
} else {
- setWidth(minPreferredLogicalWidth());
- setHeight(style()->font().height());
+ setLogicalWidth(minPreferredLogicalWidth());
+ setLogicalHeight(style()->font().height());
}
- m_marginLeft = m_marginRight = 0;
+ setMarginStart(0);
+ setMarginEnd(0);
- Length leftMargin = style()->marginLeft();
- Length rightMargin = style()->marginRight();
- if (leftMargin.isFixed())
- m_marginLeft = leftMargin.value();
- if (rightMargin.isFixed())
- m_marginRight = rightMargin.value();
+ Length startMargin = style()->marginStart();
+ Length endMargin = style()->marginEnd();
+ if (startMargin.isFixed())
+ setMarginStart(startMargin.value());
+ if (endMargin.isFixed())
+ setMarginEnd(endMargin.value());
setNeedsLayout(false);
}
@@ -1319,13 +1342,14 @@ void RenderListMarker::computePreferredLogicalWidths()
// until we support the CSS3 marker pseudoclass to allow control over the width and height of the marker box.
int bulletWidth = font.ascent() / 2;
m_image->setImageContainerSize(IntSize(bulletWidth, bulletWidth));
- m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = m_image->imageSize(this, style()->effectiveZoom()).width();
+ IntSize imageSize = m_image->imageSize(this, style()->effectiveZoom());
+ m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = style()->isHorizontalWritingMode() ? imageSize.width() : imageSize.height();
setPreferredLogicalWidthsDirty(false);
updateMargins();
return;
}
- int width = 0;
+ int logicalWidth = 0;
EListStyleType type = style()->listStyleType();
switch (type) {
case NoneListStyle:
@@ -1333,13 +1357,13 @@ void RenderListMarker::computePreferredLogicalWidths()
case Asterisks:
case Footnotes:
m_text = listMarkerText(type, m_listItem->value());
- width = font.width(m_text); // no suffix for these types
+ logicalWidth = font.width(m_text); // no suffix for these types
break;
case Circle:
case Disc:
case Square:
m_text = listMarkerText(type, 0); // value is ignored for these types
- width = (font.ascent() * 2 / 3 + 1) / 2 + 2;
+ logicalWidth = (font.ascent() * 2 / 3 + 1) / 2 + 2;
break;
case Afar:
case Amharic:
@@ -1416,18 +1440,18 @@ void RenderListMarker::computePreferredLogicalWidths()
case Urdu:
m_text = listMarkerText(type, m_listItem->value());
if (m_text.isEmpty())
- width = 0;
+ logicalWidth = 0;
else {
int itemWidth = font.width(m_text);
UChar suffixSpace[2] = { listMarkerSuffix(type, m_listItem->value()), ' ' };
int suffixSpaceWidth = font.width(TextRun(suffixSpace, 2));
- width = itemWidth + suffixSpaceWidth;
+ logicalWidth = itemWidth + suffixSpaceWidth;
}
break;
}
- m_minPreferredLogicalWidth = width;
- m_maxPreferredLogicalWidth = width;
+ m_minPreferredLogicalWidth = logicalWidth;
+ m_maxPreferredLogicalWidth = logicalWidth;
setPreferredLogicalWidthsDirty(false);
@@ -1438,26 +1462,18 @@ void RenderListMarker::updateMargins()
{
const Font& font = style()->font();
- int marginLeft = 0;
- int marginRight = 0;
+ int marginStart = 0;
+ int marginEnd = 0;
if (isInside()) {
- if (isImage()) {
- if (style()->isLeftToRightDirection())
- marginRight = cMarkerPadding;
- else
- marginLeft = cMarkerPadding;
- } else switch (style()->listStyleType()) {
+ if (isImage())
+ marginEnd = cMarkerPadding;
+ else switch (style()->listStyleType()) {
case Disc:
case Circle:
case Square:
- if (style()->isLeftToRightDirection()) {
- marginLeft = -1;
- marginRight = font.ascent() - minPreferredLogicalWidth() + 1;
- } else {
- marginLeft = font.ascent() - minPreferredLogicalWidth() + 1;
- marginRight = -1;
- }
+ marginStart = -1;
+ marginEnd = font.ascent() - minPreferredLogicalWidth() + 1;
break;
default:
break;
@@ -1465,44 +1481,46 @@ void RenderListMarker::updateMargins()
} else {
if (style()->isLeftToRightDirection()) {
if (isImage())
- marginLeft = -minPreferredLogicalWidth() - cMarkerPadding;
+ marginStart = -minPreferredLogicalWidth() - cMarkerPadding;
else {
int offset = font.ascent() * 2 / 3;
switch (style()->listStyleType()) {
case Disc:
case Circle:
case Square:
- marginLeft = -offset - cMarkerPadding - 1;
+ marginStart = -offset - cMarkerPadding - 1;
break;
case NoneListStyle:
break;
default:
- marginLeft = m_text.isEmpty() ? 0 : -minPreferredLogicalWidth() - offset / 2;
+ marginStart = m_text.isEmpty() ? 0 : -minPreferredLogicalWidth() - offset / 2;
}
}
+ marginEnd = -marginStart - minPreferredLogicalWidth();
} else {
if (isImage())
- marginLeft = cMarkerPadding;
+ marginEnd = cMarkerPadding;
else {
int offset = font.ascent() * 2 / 3;
switch (style()->listStyleType()) {
case Disc:
case Circle:
case Square:
- marginLeft = offset + cMarkerPadding + 1 - minPreferredLogicalWidth();
+ marginEnd = offset + cMarkerPadding + 1 - minPreferredLogicalWidth();
break;
case NoneListStyle:
break;
default:
- marginLeft = m_text.isEmpty() ? 0 : offset / 2;
+ marginEnd = m_text.isEmpty() ? 0 : offset / 2;
}
}
+ marginStart = -marginEnd - minPreferredLogicalWidth();
}
- marginRight = -marginLeft - minPreferredLogicalWidth();
+
}
- style()->setMarginLeft(Length(marginLeft, Fixed));
- style()->setMarginRight(Length(marginRight, Fixed));
+ style()->setMarginStart(Length(marginStart, Fixed));
+ style()->setMarginEnd(Length(marginEnd, Fixed));
}
int RenderListMarker::lineHeight(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
@@ -1512,11 +1530,11 @@ int RenderListMarker::lineHeight(bool firstLine, LineDirectionMode direction, Li
return RenderBox::lineHeight(firstLine, direction, linePositionMode);
}
-int RenderListMarker::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
+int RenderListMarker::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
{
if (!isImage())
- return m_listItem->baselinePosition(firstLine, direction, PositionOfInteriorLineBoxes);
- return RenderBox::baselinePosition(firstLine, direction, linePositionMode);
+ return m_listItem->baselinePosition(baselineType, firstLine, direction, PositionOfInteriorLineBoxes);
+ return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
}
String RenderListMarker::suffix() const
@@ -1546,14 +1564,16 @@ bool RenderListMarker::isInside() const
IntRect RenderListMarker::getRelativeMarkerRect()
{
if (isImage())
- return IntRect(x(), y(), m_image->imageSize(this, style()->effectiveZoom()).width(), m_image->imageSize(this, style()->effectiveZoom()).height());
-
+ return IntRect(0, 0, m_image->imageSize(this, style()->effectiveZoom()).width(), m_image->imageSize(this, style()->effectiveZoom()).height());
+
+ IntRect relativeRect;
EListStyleType type = style()->listStyleType();
switch (type) {
case Asterisks:
case Footnotes: {
const Font& font = style()->font();
- return IntRect(x(), y() + font.ascent(), font.width(m_text), font.height());
+ relativeRect = IntRect(0, 0, font.width(m_text), font.height());
+ break;
}
case Disc:
case Circle:
@@ -1562,7 +1582,8 @@ IntRect RenderListMarker::getRelativeMarkerRect()
const Font& font = style()->font();
int ascent = font.ascent();
int bulletWidth = (ascent * 2 / 3 + 1) / 2;
- return IntRect(x() + 1, y() + 3 * (ascent - ascent * 2 / 3) / 2, bulletWidth, bulletWidth);
+ relativeRect = IntRect(1, 3 * (ascent - ascent * 2 / 3) / 2, bulletWidth, bulletWidth);
+ break;
}
case NoneListStyle:
return IntRect();
@@ -1645,10 +1666,15 @@ IntRect RenderListMarker::getRelativeMarkerRect()
int itemWidth = font.width(m_text);
UChar suffixSpace[2] = { listMarkerSuffix(type, m_listItem->value()), ' ' };
int suffixSpaceWidth = font.width(TextRun(suffixSpace, 2));
- return IntRect(x(), y() + font.ascent(), itemWidth + suffixSpaceWidth, font.height());
+ relativeRect = IntRect(0, 0, itemWidth + suffixSpaceWidth, font.height());
+ }
+
+ if (!style()->isHorizontalWritingMode()) {
+ relativeRect = relativeRect.transposedRect();
+ relativeRect.setX(width() - relativeRect.x() - relativeRect.width());
}
- return IntRect();
+ return relativeRect;
}
void RenderListMarker::setSelectionState(SelectionState state)
diff --git a/WebCore/rendering/RenderListMarker.h b/WebCore/rendering/RenderListMarker.h
index fe025c3..d23e674 100644
--- a/WebCore/rendering/RenderListMarker.h
+++ b/WebCore/rendering/RenderListMarker.h
@@ -59,7 +59,7 @@ private:
virtual InlineBox* createInlineBox();
virtual int lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
- virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+ virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
bool isImage() const;
bool isText() const { return !isImage(); }
diff --git a/WebCore/rendering/RenderMenuList.cpp b/WebCore/rendering/RenderMenuList.cpp
index a88903f..5ad661f 100644
--- a/WebCore/rendering/RenderMenuList.cpp
+++ b/WebCore/rendering/RenderMenuList.cpp
@@ -419,7 +419,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->textIndent(), style->direction()) : menuStyle();
+ return style ? PopupMenuStyle(style->visitedDependentColor(CSSPropertyColor), itemBackgroundColor(listIndex), style->font(), style->visibility() == VISIBLE, style->display() == NONE, style->textIndent(), style->direction()) : menuStyle();
}
Color RenderMenuList::itemBackgroundColor(unsigned listIndex) const
@@ -449,7 +449,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->textIndent(), s->direction());
+ return PopupMenuStyle(s->visitedDependentColor(CSSPropertyColor), s->visitedDependentColor(CSSPropertyBackgroundColor), s->font(), s->visibility() == VISIBLE, s->display() == NONE, s->textIndent(), s->direction());
}
HostWindow* RenderMenuList::hostWindow() const
diff --git a/WebCore/rendering/RenderMenuList.h b/WebCore/rendering/RenderMenuList.h
index 7faa372..2c99b1e 100644
--- a/WebCore/rendering/RenderMenuList.h
+++ b/WebCore/rendering/RenderMenuList.h
@@ -137,7 +137,7 @@ private:
};
inline RenderMenuList* toRenderMenuList(RenderObject* object)
-{
+{
ASSERT(!object || object->isMenuList());
return static_cast<RenderMenuList*>(object);
}
diff --git a/WebCore/rendering/RenderObject.cpp b/WebCore/rendering/RenderObject.cpp
index b04d455..503b0a3 100644
--- a/WebCore/rendering/RenderObject.cpp
+++ b/WebCore/rendering/RenderObject.cpp
@@ -120,7 +120,6 @@ RenderObject* RenderObject::createObject(Node* node, RenderStyle* style)
return image;
}
-#if ENABLE(RUBY)
if (node->hasTagName(rubyTag)) {
if (style->display() == INLINE)
return new (arena) RenderRubyAsInline(node);
@@ -130,7 +129,6 @@ RenderObject* RenderObject::createObject(Node* node, RenderStyle* style)
// treat <rt> as ruby text ONLY if it still has its default treatment of block
if (node->hasTagName(rtTag) && style->display() == BLOCK)
return new (arena) RenderRubyText(node);
-#endif
switch (style->display()) {
case NONE:
@@ -260,6 +258,15 @@ bool RenderObject::isHR() const
return node() && node()->hasTagName(hrTag);
}
+bool RenderObject::isLegend() const
+{
+ return node() && (node()->hasTagName(legendTag)
+#if ENABLE(WML)
+ || node()->hasTagName(WMLNames::insertedLegendTag)
+#endif
+ );
+}
+
bool RenderObject::isHTMLMarquee() const
{
return node() && node()->renderer() == this && node()->hasTagName(marqueeTag);
diff --git a/WebCore/rendering/RenderObject.h b/WebCore/rendering/RenderObject.h
index 9c29ce1..bfc62fe 100644
--- a/WebCore/rendering/RenderObject.h
+++ b/WebCore/rendering/RenderObject.h
@@ -266,12 +266,12 @@ public:
virtual bool isRenderPart() const { return false; }
virtual bool isRenderView() const { return false; }
virtual bool isReplica() const { return false; }
-#if ENABLE(RUBY)
+
virtual bool isRuby() const { return false; }
virtual bool isRubyBase() const { return false; }
virtual bool isRubyRun() const { return false; }
virtual bool isRubyText() const { return false; }
-#endif
+
virtual bool isSlider() const { return false; }
virtual bool isTable() const { return false; }
virtual bool isTableCell() const { return false; }
@@ -288,6 +288,7 @@ public:
bool isRoot() const { return document()->documentElement() == m_node; }
bool isBody() const;
bool isHR() const;
+ bool isLegend() const;
bool isHTMLMarquee() const;
@@ -314,6 +315,7 @@ public:
// to add SVG renderer methods to RenderObject with an ASSERT_NOT_REACHED() default implementation.
virtual bool isSVGRoot() const { return false; }
virtual bool isSVGContainer() const { return false; }
+ virtual bool isSVGViewportContainer() const { return false; }
virtual bool isSVGGradientStop() const { return false; }
virtual bool isSVGHiddenContainer() const { return false; }
virtual bool isSVGPath() const { return false; }
diff --git a/WebCore/rendering/RenderReplaced.cpp b/WebCore/rendering/RenderReplaced.cpp
index a087038..b1a7711 100644
--- a/WebCore/rendering/RenderReplaced.cpp
+++ b/WebCore/rendering/RenderReplaced.cpp
@@ -284,17 +284,20 @@ VisiblePosition RenderReplaced::positionForPoint(const IntPoint& point)
RootInlineBox* root = box->root();
- int top = root->lineTop();
- int bottom = root->nextRootBox() ? root->nextRootBox()->lineTop() : root->lineBottom();
+ int top = root->selectionTop();
+ int bottom = root->selectionBottom();
- if (point.y() + y() < top)
+ int blockDirectionPosition = box->isHorizontal() ? point.y() + y() : point.x() + x();
+ int lineDirectionPosition = box->isHorizontal() ? point.x() + x() : point.y() + y();
+
+ if (blockDirectionPosition < top)
return createVisiblePosition(caretMinOffset(), DOWNSTREAM); // coordinates are above
- if (point.y() + y() >= bottom)
+ if (blockDirectionPosition >= bottom)
return createVisiblePosition(caretMaxOffset(), DOWNSTREAM); // coordinates are below
if (node()) {
- if (point.x() <= width() / 2)
+ if (lineDirectionPosition <= box->logicalLeft() + (box->logicalWidth() / 2))
return createVisiblePosition(0, DOWNSTREAM);
return createVisiblePosition(1, DOWNSTREAM);
}
@@ -326,25 +329,22 @@ IntRect RenderReplaced::localSelectionRect(bool checkWhetherSelected) const
if (!m_inlineBoxWrapper)
// We're a block-level replaced element. Just return our own dimensions.
return IntRect(0, 0, width(), height());
-
- RenderBlock* cb = containingBlock();
- if (!cb)
- return IntRect();
RootInlineBox* root = m_inlineBoxWrapper->root();
- return IntRect(0, root->selectionTop() - y(), width(), root->selectionHeight());
+ int newLogicalTop = root->block()->style()->isFlippedBlocksWritingMode() ? m_inlineBoxWrapper->logicalBottom() - root->selectionBottom() : root->selectionTop() - m_inlineBoxWrapper->logicalTop();
+ if (root->block()->style()->isHorizontalWritingMode())
+ return IntRect(0, newLogicalTop, width(), root->selectionHeight());
+ return IntRect(newLogicalTop, 0, root->selectionHeight(), height());
}
void RenderReplaced::setSelectionState(SelectionState s)
{
- RenderBox::setSelectionState(s);
+ RenderBox::setSelectionState(s); // The selection state for our containing block hierarchy is updated by the base class call.
if (m_inlineBoxWrapper) {
RootInlineBox* line = m_inlineBoxWrapper->root();
if (line)
line->setHasSelectedChildren(isSelected());
}
-
- containingBlock()->setSelectionState(s);
}
bool RenderReplaced::isSelected() const
diff --git a/WebCore/rendering/RenderReplaced.h b/WebCore/rendering/RenderReplaced.h
index fbc5151..d6ebba6 100644
--- a/WebCore/rendering/RenderReplaced.h
+++ b/WebCore/rendering/RenderReplaced.h
@@ -53,7 +53,7 @@ protected:
virtual void paint(PaintInfo&, int tx, int ty);
bool shouldPaint(PaintInfo&, int& tx, int& ty);
- IntRect localSelectionRect(bool checkWhetherSelected = true) const;
+ IntRect localSelectionRect(bool checkWhetherSelected = true) const; // This is in local coordinates, but it's a physical rect (so the top left corner is physical top left).
private:
virtual const char* renderName() const { return "RenderReplaced"; }
diff --git a/WebCore/rendering/RenderRuby.cpp b/WebCore/rendering/RenderRuby.cpp
index 7e19a79..1c5cfaf 100644
--- a/WebCore/rendering/RenderRuby.cpp
+++ b/WebCore/rendering/RenderRuby.cpp
@@ -30,7 +30,6 @@
#include "config.h"
-#if ENABLE(RUBY)
#include "RenderRuby.h"
#include "RenderRubyRun.h"
@@ -203,5 +202,3 @@ void RenderRubyAsBlock::removeChild(RenderObject* child)
}
} // namespace WebCore
-
-#endif // ENABLE(RUBY)
diff --git a/WebCore/rendering/RenderRuby.h b/WebCore/rendering/RenderRuby.h
index a5dafe9..49a84d8 100644
--- a/WebCore/rendering/RenderRuby.h
+++ b/WebCore/rendering/RenderRuby.h
@@ -31,8 +31,6 @@
#ifndef RenderRuby_h
#define RenderRuby_h
-#if ENABLE(RUBY)
-
#include "RenderBlock.h"
#include "RenderInline.h"
@@ -86,6 +84,4 @@ private:
} // namespace WebCore
-#endif
-
#endif // RenderRuby_h
diff --git a/WebCore/rendering/RenderRubyBase.cpp b/WebCore/rendering/RenderRubyBase.cpp
index 967a054..83399a1 100644
--- a/WebCore/rendering/RenderRubyBase.cpp
+++ b/WebCore/rendering/RenderRubyBase.cpp
@@ -30,7 +30,6 @@
#include "config.h"
-#if ENABLE(RUBY)
#include "RenderRubyBase.h"
namespace WebCore {
@@ -184,5 +183,3 @@ void RenderRubyBase::mergeBlockChildren(RenderRubyBase* toBase, RenderObject* fr
}
} // namespace WebCore
-
-#endif // ENABLE(RUBY)
diff --git a/WebCore/rendering/RenderRubyBase.h b/WebCore/rendering/RenderRubyBase.h
index 29c4858..c029bd5 100644
--- a/WebCore/rendering/RenderRubyBase.h
+++ b/WebCore/rendering/RenderRubyBase.h
@@ -31,8 +31,6 @@
#ifndef RenderRubyBase_h
#define RenderRubyBase_h
-#if ENABLE(RUBY)
-
#include "RenderBlock.h"
namespace WebCore {
@@ -62,6 +60,4 @@ private:
} // namespace WebCore
-#endif
-
#endif // RenderRubyBase_h
diff --git a/WebCore/rendering/RenderRubyRun.cpp b/WebCore/rendering/RenderRubyRun.cpp
index d48646b..a83a3e2 100644
--- a/WebCore/rendering/RenderRubyRun.cpp
+++ b/WebCore/rendering/RenderRubyRun.cpp
@@ -30,7 +30,6 @@
#include "config.h"
-#if ENABLE(RUBY)
#include "RenderRubyRun.h"
#include "RenderRubyBase.h"
@@ -221,10 +220,17 @@ RenderRubyRun* RenderRubyRun::staticCreateRubyRun(const RenderObject* parentRuby
RefPtr<RenderStyle> newStyle = RenderStyle::create();
newStyle->inheritFrom(parentRuby->style());
newStyle->setDisplay(INLINE_BLOCK);
+ if (parentRuby->style()->isFlippedLinesWritingMode()) {
+ // Ruby text is always in the line direction, so invert our block flow relative to the parent to
+ // ensure that the Ruby ends up on the correct side.
+ if (parentRuby->style()->isHorizontalWritingMode())
+ newStyle->setWritingMode(TopToBottomWritingMode);
+ else
+ newStyle->setWritingMode(RightToLeftWritingMode);
+ }
+
rr->setStyle(newStyle.release());
return rr;
}
} // namespace WebCore
-
-#endif // ENABLE(RUBY)
diff --git a/WebCore/rendering/RenderRubyRun.h b/WebCore/rendering/RenderRubyRun.h
index acf359b..222ddb6 100644
--- a/WebCore/rendering/RenderRubyRun.h
+++ b/WebCore/rendering/RenderRubyRun.h
@@ -31,8 +31,6 @@
#ifndef RenderRubyRun_h
#define RenderRubyRun_h
-#if ENABLE(RUBY)
-
#include "RenderBlock.h"
namespace WebCore {
@@ -80,6 +78,4 @@ private:
} // namespace WebCore
-#endif
-
#endif // RenderRubyRun_h
diff --git a/WebCore/rendering/RenderRubyText.cpp b/WebCore/rendering/RenderRubyText.cpp
index 12e8fea..14cf7fc 100644
--- a/WebCore/rendering/RenderRubyText.cpp
+++ b/WebCore/rendering/RenderRubyText.cpp
@@ -30,7 +30,6 @@
#include "config.h"
-#if ENABLE(RUBY)
#include "RenderRubyText.h"
namespace WebCore {
@@ -50,5 +49,3 @@ bool RenderRubyText::isChildAllowed(RenderObject* child, RenderStyle*) const
}
} // namespace WebCore
-
-#endif // ENABLE(RUBY)
diff --git a/WebCore/rendering/RenderRubyText.h b/WebCore/rendering/RenderRubyText.h
index 865d179..e475914 100644
--- a/WebCore/rendering/RenderRubyText.h
+++ b/WebCore/rendering/RenderRubyText.h
@@ -31,8 +31,6 @@
#ifndef RenderRubyText_h
#define RenderRubyText_h
-#if ENABLE(RUBY)
-
#include "RenderBlock.h"
namespace WebCore {
@@ -51,6 +49,4 @@ public:
} // namespace WebCore
-#endif
-
#endif // RenderRubyText_h
diff --git a/WebCore/rendering/RenderSVGGradientStop.cpp b/WebCore/rendering/RenderSVGGradientStop.cpp
index a5e5808..094fc7f 100644
--- a/WebCore/rendering/RenderSVGGradientStop.cpp
+++ b/WebCore/rendering/RenderSVGGradientStop.cpp
@@ -72,7 +72,7 @@ void RenderSVGGradientStop::layout()
SVGGradientElement* RenderSVGGradientStop::gradientElement() const
{
- ContainerNode* parentNode = node()->parent();
+ ContainerNode* parentNode = node()->parentNode();
if (parentNode->hasTagName(linearGradientTag) || parentNode->hasTagName(radialGradientTag))
return static_cast<SVGGradientElement*>(parentNode);
return 0;
diff --git a/WebCore/rendering/RenderSVGViewportContainer.h b/WebCore/rendering/RenderSVGViewportContainer.h
index 63c336c..5373ca8 100644
--- a/WebCore/rendering/RenderSVGViewportContainer.h
+++ b/WebCore/rendering/RenderSVGViewportContainer.h
@@ -36,6 +36,7 @@ public:
private:
virtual bool isSVGContainer() const { return true; }
+ virtual bool isSVGViewportContainer() const { return true; }
virtual const char* renderName() const { return "RenderSVGViewportContainer"; }
AffineTransform viewportTransform() const;
diff --git a/WebCore/rendering/RenderSlider.cpp b/WebCore/rendering/RenderSlider.cpp
index 35d72f4..d680bc7 100644
--- a/WebCore/rendering/RenderSlider.cpp
+++ b/WebCore/rendering/RenderSlider.cpp
@@ -159,8 +159,9 @@ RenderSlider::~RenderSlider()
m_thumb->detach();
}
-int RenderSlider::baselinePosition(bool /*firstLine*/, LineDirectionMode, LinePositionMode) const
+int RenderSlider::baselinePosition(FontBaseline, bool /*firstLine*/, LineDirectionMode, LinePositionMode) const
{
+ // FIXME: Patch this function for writing-mode.
return height() + marginTop();
}
@@ -285,7 +286,7 @@ void RenderSlider::layout()
if (oldSize != size())
thumb->setChildNeedsLayout(true, false);
- LayoutStateMaintainer statePusher(view(), this, size());
+ LayoutStateMaintainer statePusher(view(), this, size(), style()->isFlippedBlocksWritingMode());
IntRect oldThumbRect = thumb->frameRect();
diff --git a/WebCore/rendering/RenderSlider.h b/WebCore/rendering/RenderSlider.h
index fa743de..03779a3 100644
--- a/WebCore/rendering/RenderSlider.h
+++ b/WebCore/rendering/RenderSlider.h
@@ -42,7 +42,7 @@ namespace WebCore {
virtual const char* renderName() const { return "RenderSlider"; }
virtual bool isSlider() const { return true; }
- virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+ virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
virtual void computePreferredLogicalWidths();
virtual void layout();
virtual void updateFromElement();
diff --git a/WebCore/rendering/RenderTable.cpp b/WebCore/rendering/RenderTable.cpp
index d158284..de10680 100644
--- a/WebCore/rendering/RenderTable.cpp
+++ b/WebCore/rendering/RenderTable.cpp
@@ -268,7 +268,7 @@ void RenderTable::layout()
recalcSectionsIfNeeded();
LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
- LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()));
+ LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), style()->isFlippedBlocksWritingMode());
setLogicalHeight(0);
m_overflow.clear();
@@ -1211,10 +1211,12 @@ bool RenderTable::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
// Check kids first.
if (!hasOverflowClip() || overflowClipRect(tx, ty).intersects(result.rectForPoint(xPos, yPos))) {
for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
- if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && (child->isTableSection() || child == m_caption) &&
- child->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) {
- updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
- return true;
+ if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && (child->isTableSection() || child == m_caption)) {
+ IntPoint childPoint = flipForWritingMode(toRenderBox(child), IntPoint(tx, ty), ParentToChildFlippingAdjustment);
+ if (child->nodeAtPoint(request, result, xPos, yPos, childPoint.x(), childPoint.y(), action)) {
+ updateHitTestResult(result, IntPoint(xPos - childPoint.x(), yPos - childPoint.y()));
+ return true;
+ }
}
}
}
@@ -1222,7 +1224,7 @@ bool RenderTable::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
// Check our bounds next.
IntRect boundsRect = IntRect(tx, ty, width(), height());
if (visibleToHitTesting() && (action == HitTestBlockBackground || action == HitTestChildBlockBackground) && boundsRect.intersects(result.rectForPoint(xPos, yPos))) {
- updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
+ updateHitTestResult(result, flipForWritingMode(IntPoint(xPos - tx, yPos - ty)));
if (!result.addNodeToRectBasedTestResult(node(), xPos, yPos, boundsRect))
return true;
}
diff --git a/WebCore/rendering/RenderTableCell.cpp b/WebCore/rendering/RenderTableCell.cpp
index 3ba185a..801a362 100644
--- a/WebCore/rendering/RenderTableCell.cpp
+++ b/WebCore/rendering/RenderTableCell.cpp
@@ -299,19 +299,15 @@ void RenderTableCell::computeRectForRepaint(RenderBoxModelObject* repaintContain
RenderBlock::computeRectForRepaint(repaintContainer, r, fixed);
}
-int RenderTableCell::baselinePosition(bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
+int RenderTableCell::baselinePosition() const
{
- // FIXME: This function still needs to be patched for writing-mode.
- if (linePositionMode == PositionOfInteriorLineBoxes)
- return RenderBlock::baselinePosition(firstLine, lineDirection, linePositionMode);
-
// <http://www.w3.org/TR/2007/CR-CSS21-20070719/tables.html#height-layout>: The baseline of a cell is the baseline of
// the first in-flow line box in the cell, or the first in-flow table-row in the cell, whichever comes first. If there
// is no such line box or table-row, the baseline is the bottom of content edge of the cell box.
int firstLineBaseline = firstLineBoxBaseline();
if (firstLineBaseline != -1)
return firstLineBaseline;
- return paddingTop() + borderTop() + contentHeight();
+ return paddingBefore() + borderBefore() + contentLogicalHeight();
}
void RenderTableCell::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
diff --git a/WebCore/rendering/RenderTableCell.h b/WebCore/rendering/RenderTableCell.h
index 15e6bab..281c226 100644
--- a/WebCore/rendering/RenderTableCell.h
+++ b/WebCore/rendering/RenderTableCell.h
@@ -98,7 +98,7 @@ public:
void paintBackgroundsBehindCell(PaintInfo&, int tx, int ty, RenderObject* backgroundObject);
- virtual int baselinePosition(bool firstLine = false, LineDirectionMode = HorizontalLine, LinePositionMode = PositionOnContainingLine) const;
+ int baselinePosition() const;
void setIntrinsicPaddingBefore(int p) { m_intrinsicPaddingBefore = p; }
void setIntrinsicPaddingAfter(int p) { m_intrinsicPaddingAfter = p; }
diff --git a/WebCore/rendering/RenderTableRow.cpp b/WebCore/rendering/RenderTableRow.cpp
index 2166ef2..98544a6 100644
--- a/WebCore/rendering/RenderTableRow.cpp
+++ b/WebCore/rendering/RenderTableRow.cpp
@@ -115,7 +115,7 @@ void RenderTableRow::layout()
ASSERT(needsLayout());
// Table rows do not add translation.
- LayoutStateMaintainer statePusher(view(), this, IntSize());
+ LayoutStateMaintainer statePusher(view(), this, IntSize(), style()->isFlippedBlocksWritingMode());
bool paginated = view()->layoutState()->isPaginated();
@@ -175,9 +175,12 @@ bool RenderTableRow::nodeAtPoint(const HitTestRequest& request, HitTestResult& r
// at the moment (a demoted inline <form> for example). If we ever implement a
// table-specific hit-test method (which we should do for performance reasons anyway),
// then we can remove this check.
- if (child->isTableCell() && !toRenderBox(child)->hasSelfPaintingLayer() && child->nodeAtPoint(request, result, x, y, tx, ty, action)) {
- updateHitTestResult(result, IntPoint(x - tx, y - ty));
- return true;
+ if (child->isTableCell() && !toRenderBox(child)->hasSelfPaintingLayer()) {
+ IntPoint cellPoint = flipForWritingMode(toRenderTableCell(child), IntPoint(tx, ty), ParentToChildFlippingAdjustment);
+ if (child->nodeAtPoint(request, result, x, y, cellPoint.x(), cellPoint.y(), action)) {
+ updateHitTestResult(result, IntPoint(x - cellPoint.x(), y - cellPoint.y()));
+ return true;
+ }
}
}
diff --git a/WebCore/rendering/RenderTableSection.cpp b/WebCore/rendering/RenderTableSection.cpp
index e07461f..30620d2 100644
--- a/WebCore/rendering/RenderTableSection.cpp
+++ b/WebCore/rendering/RenderTableSection.cpp
@@ -430,7 +430,7 @@ void RenderTableSection::layout()
{
ASSERT(needsLayout());
- LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()));
+ LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), style()->isFlippedBlocksWritingMode());
for (RenderObject* child = children()->firstChild(); child; child = child->nextSibling()) {
if (child->isTableRow()) {
child->layoutIfNeeded();
@@ -571,7 +571,7 @@ int RenderTableSection::layoutRows(int toAdd)
int vspacing = table()->vBorderSpacing();
int nEffCols = table()->numEffCols();
- LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()));
+ LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), style()->isFlippedBlocksWritingMode());
for (int r = 0; r < totalRows; r++) {
// Set the row's x/y position and width/height.
@@ -1327,36 +1327,44 @@ bool RenderTableSection::nodeAtPoint(const HitTestRequest& request, HitTestResul
// at the moment (a demoted inline <form> for example). If we ever implement a
// table-specific hit-test method (which we should do for performance reasons anyway),
// then we can remove this check.
- if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && child->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) {
- updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
- return true;
+ if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer()) {
+ IntPoint childPoint = flipForWritingMode(toRenderBox(child), IntPoint(tx, ty), ParentToChildFlippingAdjustment);
+ if (child->nodeAtPoint(request, result, xPos, yPos, childPoint.x(), childPoint.y(), action)) {
+ updateHitTestResult(result, IntPoint(xPos - childPoint.x(), yPos - childPoint.y()));
+ return true;
+ }
}
}
return false;
}
- int relativeY = yPos - ty;
- // leftrow corresponds to the first row that starts after the y mouse position
- unsigned leftrow = std::upper_bound(m_rowPos.begin(), m_rowPos.end(), relativeY) - m_rowPos.begin();
- if (leftrow == m_rowPos.size())
+ IntPoint location = IntPoint(xPos - tx, yPos - ty);
+ if (style()->isFlippedBlocksWritingMode()) {
+ if (style()->isHorizontalWritingMode())
+ location.setY(height() - location.y());
+ else
+ location.setX(width() - location.x());
+ }
+
+ int offsetInColumnDirection = style()->isHorizontalWritingMode() ? location.y() : location.x();
+ // Find the first row that starts after offsetInColumnDirection.
+ unsigned nextRow = std::upper_bound(m_rowPos.begin(), m_rowPos.end(), offsetInColumnDirection) - m_rowPos.begin();
+ if (nextRow == m_rowPos.size())
return false;
- // Grab the last row that starts before the y mouse position.
- if (leftrow > 0)
- --leftrow;
+ // Now set hitRow to the index of the hit row, or 0.
+ unsigned hitRow = nextRow > 0 ? nextRow - 1 : 0;
Vector<int>& columnPos = table()->columnPositions();
- bool rtl = !style()->isLeftToRightDirection();
- int relativeX = xPos - tx;
- if (rtl)
- relativeX = columnPos[columnPos.size() - 1] - relativeX;
+ int offsetInRowDirection = style()->isHorizontalWritingMode() ? location.x() : location.y();
+ if (!style()->isLeftToRightDirection())
+ offsetInRowDirection = columnPos[columnPos.size() - 1] - offsetInRowDirection;
- unsigned leftcol = std::lower_bound(columnPos.begin(), columnPos.end(), relativeX) - columnPos.begin();
- if (leftcol == columnPos.size())
+ unsigned nextColumn = std::lower_bound(columnPos.begin(), columnPos.end(), offsetInRowDirection) - columnPos.begin();
+ if (nextColumn == columnPos.size())
return false;
- if (leftcol > 0)
- --leftcol;
+ unsigned hitColumn = nextColumn > 0 ? nextColumn - 1 : 0;
- CellStruct& current = cellAt(leftrow, leftcol);
+ CellStruct& current = cellAt(hitRow, hitColumn);
// If the cell is empty, there's nothing to do
if (!current.hasCells())
@@ -1364,8 +1372,9 @@ bool RenderTableSection::nodeAtPoint(const HitTestRequest& request, HitTestResul
for (int i = current.cells.size() - 1; i >= 0; --i) {
RenderTableCell* cell = current.cells[i];
- if (static_cast<RenderObject*>(cell)->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) {
- updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
+ IntPoint cellPoint = flipForWritingMode(cell, IntPoint(tx, ty), ParentToChildFlippingAdjustment);
+ if (static_cast<RenderObject*>(cell)->nodeAtPoint(request, result, xPos, yPos, cellPoint.x(), cellPoint.y(), action)) {
+ updateHitTestResult(result, IntPoint(xPos - cellPoint.x(), yPos - cellPoint.y()));
return true;
}
}
diff --git a/WebCore/rendering/RenderText.cpp b/WebCore/rendering/RenderText.cpp
index aa362b3..7635d07 100644
--- a/WebCore/rendering/RenderText.cpp
+++ b/WebCore/rendering/RenderText.cpp
@@ -59,6 +59,9 @@ static void makeCapitalized(String* string, UChar previous)
unsigned length = string->length();
const UChar* characters = string->characters();
+ if (length >= numeric_limits<unsigned>::max())
+ CRASH();
+
StringBuffer stringWithPrevious(length + 1);
stringWithPrevious[0] = previous == noBreakSpace ? ' ' : previous;
for (unsigned i = 1; i < length + 1; i++) {
@@ -422,13 +425,13 @@ VisiblePosition RenderText::positionForPoint(const IntPoint& point)
int pointBlockDirection = firstTextBox()->isHorizontal() ? point.y() : point.x();
// FIXME: We should be able to roll these special cases into the general cases in the loop below.
- if (firstTextBox() && pointBlockDirection < firstTextBox()->root()->lineBottom() && pointLineDirection < firstTextBox()->logicalLeft()) {
+ if (firstTextBox() && pointBlockDirection < firstTextBox()->root()->selectionBottom() && pointLineDirection < firstTextBox()->logicalLeft()) {
// at the y coordinate of the first line or above
// and the x coordinate is to the left of the first text box left edge
offset = firstTextBox()->offsetForPosition(pointLineDirection);
return createVisiblePosition(offset + firstTextBox()->start(), DOWNSTREAM);
}
- if (lastTextBox() && pointBlockDirection >= lastTextBox()->root()->lineTop() && pointLineDirection >= lastTextBox()->logicalRight()) {
+ if (lastTextBox() && pointBlockDirection >= lastTextBox()->root()->selectionTop() && pointLineDirection >= lastTextBox()->logicalRight()) {
// at the y coordinate of the last line or below
// and the x coordinate is to the right of the last text box right edge
offset = lastTextBox()->offsetForPosition(pointLineDirection);
@@ -437,8 +440,11 @@ VisiblePosition RenderText::positionForPoint(const IntPoint& point)
InlineTextBox* lastBoxAbove = 0;
for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
- if (pointBlockDirection >= box->root()->lineTop()) {
- int bottom = box->root()->nextRootBox() ? box->root()->nextRootBox()->lineTop() : box->root()->lineBottom();
+ RootInlineBox* rootBox = box->root();
+ if (pointBlockDirection >= rootBox->selectionTop()) {
+ int bottom = rootBox->selectionBottom();
+ if (rootBox->nextRootBox())
+ bottom = min(bottom, rootBox->nextRootBox()->lineTop());
if (pointBlockDirection < bottom) {
offset = box->offsetForPosition(pointLineDirection);
@@ -481,8 +487,8 @@ IntRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, int* e
InlineTextBox* box = static_cast<InlineTextBox*>(inlineBox);
- int height = box->root()->lineBottom() - box->root()->lineTop();
- int top = box->root()->lineTop();
+ int height = box->root()->selectionHeight();
+ int top = box->root()->selectionTop();
int left = box->positionForOffset(caretOffset);
diff --git a/WebCore/rendering/RenderTextControl.cpp b/WebCore/rendering/RenderTextControl.cpp
index e81dfb9..9b9e51a 100644
--- a/WebCore/rendering/RenderTextControl.cpp
+++ b/WebCore/rendering/RenderTextControl.cpp
@@ -30,6 +30,7 @@
#include "Frame.h"
#include "HTMLBRElement.h"
#include "HTMLFormControlElement.h"
+#include "HTMLInputElement.h"
#include "HTMLNames.h"
#include "HitTestResult.h"
#include "RenderLayer.h"
@@ -256,6 +257,22 @@ void setSelectionRange(Node* node, int start, int end)
frame->selection()->setSelection(newSelection);
}
+bool RenderTextControl::isSelectableElement(Node* node) const
+{
+ if (!node || !m_innerText)
+ return false;
+
+ if (node->rootEditableElement() == m_innerText)
+ return true;
+
+ if (!m_innerText->contains(node))
+ return false;
+
+ Node* shadowAncestor = node->shadowAncestorNode();
+ return shadowAncestor && (shadowAncestor->hasTagName(textareaTag)
+ || (shadowAncestor->hasTagName(inputTag) && static_cast<HTMLInputElement*>(shadowAncestor)->isTextField()));
+}
+
PassRefPtr<Range> RenderTextControl::selection(int start, int end) const
{
if (!m_innerText)
@@ -284,7 +301,7 @@ VisiblePosition RenderTextControl::visiblePositionForIndex(int index) const
int RenderTextControl::indexForVisiblePosition(const VisiblePosition& pos) const
{
Position indexPosition = pos.deepEquivalent();
- if (!indexPosition.node() || indexPosition.node()->rootEditableElement() != m_innerText)
+ if (!isSelectableElement(indexPosition.node()))
return 0;
ExceptionCode ec = 0;
RefPtr<Range> range = Range::create(document());
@@ -561,14 +578,52 @@ void RenderTextControl::updatePlaceholderVisibility(bool placeholderShouldBeVisi
{
bool oldPlaceholderVisible = m_placeholderVisible;
m_placeholderVisible = placeholderShouldBeVisible;
- if (oldPlaceholderVisible != m_placeholderVisible || placeholderValueChanged) {
- // Sets the inner text style to the normal style or :placeholder style.
- setInnerTextStyle(createInnerTextStyle(textBaseStyle()));
+ if (oldPlaceholderVisible != m_placeholderVisible || placeholderValueChanged)
+ repaint();
+}
- // updateFromElement() of the subclasses updates the text content
- // to the element's value(), placeholder(), or the empty string.
- updateFromElement();
+void RenderTextControl::paintPlaceholder(PaintInfo& paintInfo, int tx, int ty)
+{
+ if (style()->visibility() != VISIBLE)
+ return;
+
+ IntRect clipRect(tx + borderLeft(), ty + borderTop(), width() - borderLeft() - borderRight(), height() - borderBottom() - borderTop());
+ if (clipRect.isEmpty())
+ return;
+
+ paintInfo.context->save();
+
+ paintInfo.context->clip(clipRect);
+
+ RefPtr<RenderStyle> placeholderStyle = getCachedPseudoStyle(INPUT_PLACEHOLDER);
+ if (!placeholderStyle)
+ placeholderStyle = style();
+
+ 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);
+
+ RenderBox* textRenderer = innerTextElement() ? innerTextElement()->renderBox() : 0;
+ if (textRenderer) {
+ IntPoint textPoint;
+ textPoint.setY(ty + borderTop() + paddingTop() + textRenderer->paddingTop() + placeholderStyle->font().ascent());
+ if (placeholderStyle->isLeftToRightDirection())
+ textPoint.setX(tx + textBlockInsetLeft());
+ else
+ textPoint.setX(tx + width() - textBlockInsetRight() - style()->font().width(textRun));
+
+ paintInfo.context->drawBidiText(placeholderStyle->font(), textRun, textPoint);
}
+ paintInfo.context->restore();
+}
+
+void RenderTextControl::paintObject(PaintInfo& paintInfo, int tx, int ty)
+{
+ if (m_placeholderVisible && paintInfo.phase == PaintPhaseForeground)
+ paintPlaceholder(paintInfo, tx, ty);
+
+ RenderBlock::paintObject(paintInfo, tx, ty);
}
} // namespace WebCore
diff --git a/WebCore/rendering/RenderTextControl.h b/WebCore/rendering/RenderTextControl.h
index 0060973..4b1d6e3 100644
--- a/WebCore/rendering/RenderTextControl.h
+++ b/WebCore/rendering/RenderTextControl.h
@@ -96,6 +96,7 @@ private:
virtual bool canHaveChildren() const { return false; }
virtual bool avoidsFloats() const { return true; }
void setInnerTextStyle(PassRefPtr<RenderStyle>);
+ virtual void paintObject(PaintInfo&, int tx, int ty);
virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
@@ -107,6 +108,12 @@ private:
bool hasVisibleTextArea() const;
friend void setSelectionRange(Node*, int start, int end);
+ bool isSelectableElement(Node*) const;
+
+ virtual int textBlockInsetLeft() const = 0;
+ virtual int textBlockInsetRight() const = 0;
+
+ void paintPlaceholder(PaintInfo&, int tx, int ty);
bool m_wasChangedSinceLastChangeEvent;
bool m_lastChangeWasUserEdit;
diff --git a/WebCore/rendering/RenderTextControlMultiLine.cpp b/WebCore/rendering/RenderTextControlMultiLine.cpp
index 2c93164..eaa7eca 100644
--- a/WebCore/rendering/RenderTextControlMultiLine.cpp
+++ b/WebCore/rendering/RenderTextControlMultiLine.cpp
@@ -55,8 +55,6 @@ void RenderTextControlMultiLine::subtreeHasChanged()
if (!node()->focused())
return;
- node()->dispatchEvent(Event::create(eventNames().inputEvent, true, false));
-
if (Frame* frame = this->frame())
frame->editor()->textDidChangeInTextArea(textArea);
}
@@ -66,10 +64,7 @@ bool RenderTextControlMultiLine::nodeAtPoint(const HitTestRequest& request, HitT
if (!RenderTextControl::nodeAtPoint(request, result, x, y, tx, ty, hitTestAction))
return false;
- bool resultIsTextValueOrPlaceholder
- = (!m_placeholderVisible && result.innerNode() == innerTextElement())
- || (m_placeholderVisible && result.innerNode()->isDescendantOf(innerTextElement()));
- if (result.innerNode() == node() || resultIsTextValueOrPlaceholder)
+ if (result.innerNode() == node() || result.innerNode() == innerTextElement())
hitInnerTextElement(result, x, y, tx, ty);
return true;
@@ -102,9 +97,9 @@ void RenderTextControlMultiLine::adjustControlHeightBasedOnLineHeight(int lineHe
setHeight(height() + lineHeight * static_cast<HTMLTextAreaElement*>(node())->rows());
}
-int RenderTextControlMultiLine::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
+int RenderTextControlMultiLine::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
{
- return RenderBox::baselinePosition(firstLine, direction, linePositionMode);
+ return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
}
void RenderTextControlMultiLine::updateFromElement()
@@ -112,11 +107,7 @@ void RenderTextControlMultiLine::updateFromElement()
createSubtreeIfNeeded(0);
RenderTextControl::updateFromElement();
- HTMLTextAreaElement* textArea = static_cast<HTMLTextAreaElement*>(node());
- if (m_placeholderVisible)
- setInnerTextValue(textArea->strippedPlaceholder());
- else
- setInnerTextValue(textArea->value());
+ setInnerTextValue(static_cast<HTMLTextAreaElement*>(node())->value());
}
void RenderTextControlMultiLine::cacheSelection(int start, int end)
@@ -126,16 +117,8 @@ void RenderTextControlMultiLine::cacheSelection(int start, int end)
PassRefPtr<RenderStyle> RenderTextControlMultiLine::createInnerTextStyle(const RenderStyle* startStyle) const
{
- RefPtr<RenderStyle> textBlockStyle;
- if (m_placeholderVisible) {
- if (RenderStyle* pseudoStyle = getCachedPseudoStyle(INPUT_PLACEHOLDER))
- textBlockStyle = RenderStyle::clone(pseudoStyle);
- }
- if (!textBlockStyle) {
- textBlockStyle = RenderStyle::create();
- textBlockStyle->inheritFrom(startStyle);
- }
-
+ RefPtr<RenderStyle> textBlockStyle = RenderStyle::create();
+ textBlockStyle->inheritFrom(startStyle);
adjustInnerTextStyle(startStyle, textBlockStyle.get());
textBlockStyle->setDisplay(BLOCK);
@@ -146,5 +129,25 @@ RenderStyle* RenderTextControlMultiLine::textBaseStyle() const
{
return style();
}
+
+int RenderTextControlMultiLine::textBlockInsetLeft() const
+{
+ int inset = borderLeft() + paddingLeft();
+ if (HTMLElement* innerText = innerTextElement()) {
+ if (RenderBox* innerTextRenderer = innerText->renderBox())
+ inset += innerTextRenderer->paddingLeft();
+ }
+ return inset;
+}
+
+int RenderTextControlMultiLine::textBlockInsetRight() const
+{
+ int inset = borderRight() + paddingRight();
+ if (HTMLElement* innerText = innerTextElement()) {
+ if (RenderBox* innerTextRenderer = innerText->renderBox())
+ inset += innerTextRenderer->paddingRight();
+ }
+ return inset;
+}
}
diff --git a/WebCore/rendering/RenderTextControlMultiLine.h b/WebCore/rendering/RenderTextControlMultiLine.h
index e061e89..6dc2032 100644
--- a/WebCore/rendering/RenderTextControlMultiLine.h
+++ b/WebCore/rendering/RenderTextControlMultiLine.h
@@ -43,13 +43,15 @@ private:
virtual float getAvgCharWidth(AtomicString family);
virtual int preferredContentWidth(float charWidth) const;
virtual void adjustControlHeightBasedOnLineHeight(int lineHeight);
- virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+ virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
virtual void updateFromElement();
virtual void cacheSelection(int start, int end);
virtual RenderStyle* textBaseStyle() const;
virtual PassRefPtr<RenderStyle> createInnerTextStyle(const RenderStyle* startStyle) const;
+ virtual int textBlockInsetLeft() const;
+ virtual int textBlockInsetRight() const;
};
inline RenderTextControlMultiLine* toRenderTextControlMultiLine(RenderObject* object)
diff --git a/WebCore/rendering/RenderTextControlSingleLine.cpp b/WebCore/rendering/RenderTextControlSingleLine.cpp
index ea03c61..da85863 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.cpp
+++ b/WebCore/rendering/RenderTextControlSingleLine.cpp
@@ -401,7 +401,7 @@ void RenderTextControlSingleLine::forwardEvent(Event* event)
m_resultsButton->defaultEventHandler(event);
else if (m_cancelButton && localPoint.x() > textRight)
m_cancelButton->defaultEventHandler(event);
- else if (m_innerSpinButton && localPoint.x() > textRight && localPoint.x() < textRight + m_innerSpinButton->renderBox()->width())
+ else if (m_innerSpinButton && localPoint.x() > textRight && m_innerSpinButton->renderBox() && localPoint.x() < textRight + m_innerSpinButton->renderBox()->width())
m_innerSpinButton->defaultEventHandler(event);
else if (m_outerSpinButton && localPoint.x() > textRight)
m_outerSpinButton->defaultEventHandler(event);
@@ -678,25 +678,14 @@ void RenderTextControlSingleLine::updateFromElement()
if (m_cancelButton)
updateCancelButtonVisibility();
- if (m_placeholderVisible) {
- // node() must be an HTMLInputElement. WMLInputElement doesn't support placeholder.
- ASSERT(node()->isHTMLElement());
- ExceptionCode ec = 0;
- innerTextElement()->setInnerText(static_cast<HTMLInputElement*>(node())->strippedPlaceholder(), ec);
- ASSERT(!ec);
- } else {
- if (!inputElement()->suggestedValue().isNull())
- setInnerTextValue(inputElement()->suggestedValue());
- else {
- bool shouldUpdateValue = true;
- if (node()->isHTMLElement()) {
- // For HTMLInputElement, update the renderer value if the element
- // supports placeholder or the formControlValueMatchesRenderer()
- // flag is false. It protects an unacceptable renderer value from
- // being overwritten with the DOM value.
- shouldUpdateValue = static_cast<HTMLTextFormControlElement*>(node())->supportsPlaceholder() || !static_cast<HTMLInputElement*>(node())->formControlValueMatchesRenderer();
- }
- if (shouldUpdateValue)
+ if (!inputElement()->suggestedValue().isNull())
+ setInnerTextValue(inputElement()->suggestedValue());
+ else {
+ if (node()->hasTagName(inputTag)) {
+ // For HTMLInputElement, update the renderer value if the formControlValueMatchesRenderer()
+ // 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());
}
}
@@ -712,16 +701,8 @@ void RenderTextControlSingleLine::cacheSelection(int start, int end)
PassRefPtr<RenderStyle> RenderTextControlSingleLine::createInnerTextStyle(const RenderStyle* startStyle) const
{
- RefPtr<RenderStyle> textBlockStyle;
- if (m_placeholderVisible) {
- if (RenderStyle* pseudoStyle = getCachedPseudoStyle(INPUT_PLACEHOLDER))
- textBlockStyle = RenderStyle::clone(pseudoStyle);
- }
- if (!textBlockStyle) {
- textBlockStyle = RenderStyle::create();
- textBlockStyle->inheritFrom(startStyle);
- }
-
+ RefPtr<RenderStyle> textBlockStyle = RenderStyle::create();
+ textBlockStyle->inheritFrom(startStyle);
adjustInnerTextStyle(startStyle, textBlockStyle.get());
textBlockStyle->setWhiteSpace(PRE);
@@ -744,13 +725,6 @@ PassRefPtr<RenderStyle> RenderTextControlSingleLine::createInnerTextStyle(const
textBlockStyle->setPaddingLeft(Length(1, Fixed));
textBlockStyle->setPaddingRight(Length(1, Fixed));
- // When the placeholder is going to be displayed, temporarily override the text security to be "none".
- // After this, updateFromElement will immediately update the text displayed.
- // When the placeholder is no longer visible, updatePlaceholderVisiblity will reset the style,
- // and the text security mode will be set back to the computed value correctly.
- if (m_placeholderVisible)
- textBlockStyle->setTextSecurity(TSNONE);
-
return textBlockStyle.release();
}
@@ -956,7 +930,7 @@ PopupMenuStyle RenderTextControlSingleLine::itemStyle(unsigned) const
PopupMenuStyle RenderTextControlSingleLine::menuStyle() const
{
- return PopupMenuStyle(style()->visitedDependentColor(CSSPropertyColor), style()->visitedDependentColor(CSSPropertyBackgroundColor), style()->font(), style()->visibility() == VISIBLE, style()->textIndent(), style()->direction());
+ return PopupMenuStyle(style()->visitedDependentColor(CSSPropertyColor), style()->visitedDependentColor(CSSPropertyBackgroundColor), style()->font(), style()->visibility() == VISIBLE, style()->display() == NONE, style()->textIndent(), style()->direction());
}
int RenderTextControlSingleLine::clientInsetLeft() const
@@ -1116,4 +1090,24 @@ InputElement* RenderTextControlSingleLine::inputElement() const
return toInputElement(static_cast<Element*>(node()));
}
+int RenderTextControlSingleLine::textBlockInsetLeft() const
+{
+ int inset = borderLeft() + clientPaddingLeft();
+ if (HTMLElement* innerText = innerTextElement()) {
+ if (RenderBox* innerTextRenderer = innerText->renderBox())
+ inset += innerTextRenderer->paddingLeft();
+ }
+ return inset;
+}
+
+int RenderTextControlSingleLine::textBlockInsetRight() const
+{
+ int inset = borderRight() + clientPaddingRight();
+ if (HTMLElement* innerText = innerTextElement()) {
+ if (RenderBox* innerTextRenderer = innerText->renderBox())
+ inset += innerTextRenderer->paddingRight();
+ }
+ return inset;
+}
+
}
diff --git a/WebCore/rendering/RenderTextControlSingleLine.h b/WebCore/rendering/RenderTextControlSingleLine.h
index 0deb063..26987fd 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.h
+++ b/WebCore/rendering/RenderTextControlSingleLine.h
@@ -143,6 +143,9 @@ private:
InputElement* inputElement() const;
+ virtual int textBlockInsetLeft() const;
+ virtual int textBlockInsetRight() const;
+
bool m_searchPopupIsVisible;
bool m_shouldDrawCapsLockIndicator;
@@ -161,7 +164,7 @@ private:
};
inline RenderTextControlSingleLine* toRenderTextControlSingleLine(RenderObject* object)
-{
+{
ASSERT(!object || object->isTextField());
return static_cast<RenderTextControlSingleLine*>(object);
}
diff --git a/WebCore/rendering/RenderTreeAsText.cpp b/WebCore/rendering/RenderTreeAsText.cpp
index ec36b7e..f93cd55 100644
--- a/WebCore/rendering/RenderTreeAsText.cpp
+++ b/WebCore/rendering/RenderTreeAsText.cpp
@@ -413,6 +413,41 @@ void RenderTreeAsText::writeRenderObject(TextStream& ts, const RenderObject& o,
}
}
}
+
+ if (behavior & RenderAsTextShowLayoutState) {
+ bool needsLayout = o.selfNeedsLayout() || o.needsPositionedMovementLayout() || o.posChildNeedsLayout() || o.normalChildNeedsLayout();
+ if (needsLayout)
+ ts << " (needs layout:";
+
+ bool havePrevious = false;
+ if (o.selfNeedsLayout()) {
+ ts << " self";
+ havePrevious = true;
+ }
+
+ if (o.needsPositionedMovementLayout()) {
+ if (havePrevious)
+ ts << ",";
+ havePrevious = true;
+ ts << " positioned movement";
+ }
+
+ if (o.normalChildNeedsLayout()) {
+ if (havePrevious)
+ ts << ",";
+ havePrevious = true;
+ ts << " child";
+ }
+
+ if (o.posChildNeedsLayout()) {
+ if (havePrevious)
+ ts << ",";
+ ts << " positioned child";
+ }
+
+ if (needsLayout)
+ ts << ")";
+ }
#if PLATFORM(QT)
// Print attributes of embedded QWidgets. E.g. when the WebCore::Widget
@@ -691,7 +726,8 @@ String externalRepresentation(Frame* frame, RenderAsTextBehavior behavior)
printContext.begin(frame->contentRenderer()->width());
}
- frame->document()->updateLayout();
+ if (!(behavior & RenderAsTextDontUpdateLayout))
+ frame->document()->updateLayout();
RenderObject* o = frame->contentRenderer();
if (!o)
diff --git a/WebCore/rendering/RenderTreeAsText.h b/WebCore/rendering/RenderTreeAsText.h
index 59a0abb..4c8b145 100644
--- a/WebCore/rendering/RenderTreeAsText.h
+++ b/WebCore/rendering/RenderTreeAsText.h
@@ -48,7 +48,9 @@ enum RenderAsTextBehaviorFlags {
RenderAsTextShowCompositedLayers = 1 << 2, // Show which layers are composited.
RenderAsTextShowAddresses = 1 << 3, // Show layer and renderer addresses.
RenderAsTextShowIDAndClass = 1 << 4, // Show id and class attributes
- RenderAsTextPrintingMode = 1 << 5 // Dump the tree in printing mode.
+ RenderAsTextPrintingMode = 1 << 5, // Dump the tree in printing mode.
+ RenderAsTextDontUpdateLayout = 1 << 6, // Don't update layout, to make it safe to call showLayerTree() from the debugger inside layout or painting code.
+ RenderAsTextShowLayoutState = 1 << 7 // Print the various 'needs layout' bits on renderers.
};
typedef unsigned RenderAsTextBehavior;
diff --git a/WebCore/rendering/RenderView.cpp b/WebCore/rendering/RenderView.cpp
index 3349403..2885f15 100644
--- a/WebCore/rendering/RenderView.cpp
+++ b/WebCore/rendering/RenderView.cpp
@@ -307,11 +307,6 @@ void RenderView::repaintRectangleInViewAndCompositedLayers(const IntRect& ur, bo
repaintViewRectangle(ur, immediate);
#if USE(ACCELERATED_COMPOSITING)
- // If we're a frame, repaintViewRectangle will have repainted via a RenderObject in the
- // parent document.
- if (document()->ownerElement())
- return;
-
if (compositor()->inCompositingMode())
compositor()->repaintCompositedLayersAbsoluteRect(ur);
#endif
@@ -326,6 +321,7 @@ void RenderView::computeRectForRepaint(RenderBoxModelObject* repaintContainer, I
if (printing())
return;
+<<<<<<< HEAD
#ifdef ANDROID_FIXED_ELEMENTS
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
const Settings * settings = document()->settings();
@@ -335,6 +331,17 @@ void RenderView::computeRectForRepaint(RenderBoxModelObject* repaintContainer, I
if (false)
#endif
#endif
+=======
+ if (style()->isFlippedBlocksWritingMode()) {
+ // 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());
+ else
+ rect.setX(viewWidth() - rect.right());
+ }
+
+>>>>>>> webkit.org at r72274
if (fixed && m_frameView)
rect.move(m_frameView->scrollX(), m_frameView->scrollY());
diff --git a/WebCore/rendering/RootInlineBox.cpp b/WebCore/rendering/RootInlineBox.cpp
index 3e5b6c7..cdc6525 100644
--- a/WebCore/rendering/RootInlineBox.cpp
+++ b/WebCore/rendering/RootInlineBox.cpp
@@ -47,6 +47,7 @@ RootInlineBox::RootInlineBox(RenderBlock* block)
, m_lineBottom(0)
, m_paginationStrut(0)
, m_blockLogicalHeight(0)
+ , m_baselineType(AlphabeticBaseline)
{
setIsHorizontal(block->style()->isHorizontalWritingMode());
}
@@ -214,7 +215,7 @@ void RootInlineBox::childRemoved(InlineBox* box)
}
}
-int RootInlineBox::alignBoxesInBlockDirection(int heightOfBlock, GlyphOverflowAndFallbackFontsMap& textBoxDataMap)
+int RootInlineBox::alignBoxesInBlockDirection(int heightOfBlock, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache)
{
#if ENABLE(SVG)
// SVG will handle vertical alignment on its own.
@@ -226,11 +227,16 @@ int RootInlineBox::alignBoxesInBlockDirection(int heightOfBlock, GlyphOverflowAn
int maxPositionBottom = 0;
int maxAscent = 0;
int maxDescent = 0;
+ bool setMaxAscent = false;
+ bool setMaxDescent = false;
// Figure out if we're in no-quirks mode.
bool noQuirksMode = renderer()->document()->inNoQuirksMode();
- computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent, noQuirksMode, textBoxDataMap);
+ m_baselineType = requiresIdeographicBaseline(textBoxDataMap) ? IdeographicBaseline : AlphabeticBaseline;
+
+ computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent, setMaxAscent, setMaxDescent, noQuirksMode,
+ textBoxDataMap, m_baselineType, verticalPositionCache);
if (maxAscent + maxDescent < max(maxPositionTop, maxPositionBottom))
adjustMaxAscentAndDescent(maxAscent, maxDescent, maxPositionTop, maxPositionBottom);
@@ -239,7 +245,7 @@ int RootInlineBox::alignBoxesInBlockDirection(int heightOfBlock, GlyphOverflowAn
int lineTop = heightOfBlock;
int lineBottom = heightOfBlock;
bool setLineTop = false;
- placeBoxesInBlockDirection(heightOfBlock, maxHeight, maxAscent, noQuirksMode, lineTop, lineBottom, setLineTop);
+ placeBoxesInBlockDirection(heightOfBlock, maxHeight, maxAscent, noQuirksMode, lineTop, lineBottom, setLineTop, m_baselineType);
computeBlockDirectionOverflow(lineTop, lineBottom, noQuirksMode, textBoxDataMap);
setLineTopBottomPositions(lineTop, lineBottom);
@@ -403,7 +409,7 @@ static bool isEditableLeaf(InlineBox* leaf)
return leaf && leaf->renderer() && leaf->renderer()->node() && leaf->renderer()->node()->isContentEditable();
}
-InlineBox* RootInlineBox::closestLeafChildForXPos(int x, bool onlyEditableLeaves)
+InlineBox* RootInlineBox::closestLeafChildForLogicalLeftPosition(int leftPosition, bool onlyEditableLeaves)
{
InlineBox* firstLeaf = firstLeafChild();
InlineBox* lastLeaf = lastLeafChild();
@@ -411,13 +417,13 @@ InlineBox* RootInlineBox::closestLeafChildForXPos(int x, bool onlyEditableLeaves
return firstLeaf;
// Avoid returning a list marker when possible.
- if (x <= firstLeaf->m_x && !firstLeaf->renderer()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(firstLeaf)))
- // The x coordinate is less or equal to left edge of the firstLeaf.
+ if (leftPosition <= firstLeaf->logicalLeft() && !firstLeaf->renderer()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(firstLeaf)))
+ // The leftPosition coordinate is less or equal to left edge of the firstLeaf.
// Return it.
return firstLeaf;
- if (x >= lastLeaf->m_x + lastLeaf->m_logicalWidth && !lastLeaf->renderer()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(lastLeaf)))
- // The x coordinate is greater or equal to right edge of the lastLeaf.
+ if (leftPosition >= lastLeaf->logicalRight() && !lastLeaf->renderer()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(lastLeaf)))
+ // The leftPosition coordinate is greater or equal to right edge of the lastLeaf.
// Return it.
return lastLeaf;
@@ -425,7 +431,7 @@ InlineBox* RootInlineBox::closestLeafChildForXPos(int x, bool onlyEditableLeaves
for (InlineBox* leaf = firstLeaf; leaf; leaf = leaf->nextLeafChild()) {
if (!leaf->renderer()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(leaf))) {
closestLeaf = leaf;
- if (x < leaf->m_x + leaf->m_logicalWidth)
+ if (leftPosition < leaf->logicalRight())
// The x coordinate is less than the right edge of the box.
// Return it.
return leaf;
diff --git a/WebCore/rendering/RootInlineBox.h b/WebCore/rendering/RootInlineBox.h
index f13d00f..851b4b1 100644
--- a/WebCore/rendering/RootInlineBox.h
+++ b/WebCore/rendering/RootInlineBox.h
@@ -57,7 +57,7 @@ public:
int selectionBottom() const;
int selectionHeight() const { return max(0, selectionBottom() - selectionTop()); }
- int alignBoxesInBlockDirection(int heightOfBlock, GlyphOverflowAndFallbackFontsMap&);
+ int alignBoxesInBlockDirection(int heightOfBlock, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
void setLineTopBottomPositions(int top, int bottom);
virtual RenderLineBoxList* rendererLineBoxes() const;
@@ -88,7 +88,7 @@ public:
virtual void clearTruncation();
- virtual int baselinePosition() const { return boxModelObject()->baselinePosition(m_firstLine, isHorizontal() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes); }
+ virtual int baselinePosition(FontBaseline baselineType) const { return boxModelObject()->baselinePosition(baselineType, m_firstLine, isHorizontal() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes); }
virtual int lineHeight() const { return boxModelObject()->lineHeight(m_firstLine, isHorizontal() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes); }
#if PLATFORM(MAC)
@@ -110,7 +110,7 @@ public:
RenderBlock* block() const;
- InlineBox* closestLeafChildForXPos(int x, bool onlyEditableLeaves = false);
+ InlineBox* closestLeafChildForLogicalLeftPosition(int, bool onlyEditableLeaves = false);
Vector<RenderBox*>& floats()
{
@@ -125,6 +125,8 @@ public:
virtual void extractLineBoxFromRenderObject();
virtual void attachLineBoxToRenderObject();
virtual void removeLineBoxFromRenderObject();
+
+ FontBaseline baselineType() const { return m_baselineType; }
private:
bool hasEllipsisBox() const { return m_hasEllipsisBoxOrHyphen; }
@@ -148,6 +150,9 @@ private:
// The logical height of the block at the end of this line. This is where the next line starts.
int m_blockLogicalHeight;
+ // Whether or not this line uses alphabetic or ideographic baselines by default.
+ FontBaseline m_baselineType;
+
WTF::Unicode::Direction m_lineBreakBidiStatusEor : 5;
WTF::Unicode::Direction m_lineBreakBidiStatusLastStrong : 5;
WTF::Unicode::Direction m_lineBreakBidiStatusLast : 5;
diff --git a/WebCore/rendering/SVGImageBufferTools.cpp b/WebCore/rendering/SVGImageBufferTools.cpp
index 903aa21..20f45b1 100644
--- a/WebCore/rendering/SVGImageBufferTools.cpp
+++ b/WebCore/rendering/SVGImageBufferTools.cpp
@@ -81,10 +81,8 @@ void SVGImageBufferTools::renderSubtreeToImageBuffer(ImageBuffer* image, RenderO
PaintInfo info(image->context(), PaintInfo::infiniteRect(), PaintPhaseForeground, 0, 0, 0);
- // FIXME: isSVGContainer returns true for RenderSVGViewportContainer, so if this is ever
- // called with one of those, we will read from the wrong offset in an object due to a bad cast.
RenderSVGContainer* svgContainer = 0;
- if (item && item->isSVGContainer())
+ if (item && item->isSVGContainer() && !item->isSVGViewportContainer())
svgContainer = toRenderSVGContainer(item);
bool drawsContents = svgContainer ? svgContainer->drawsContents() : false;
diff --git a/WebCore/rendering/ShadowElement.cpp b/WebCore/rendering/ShadowElement.cpp
index c52ce17..cea3164 100644
--- a/WebCore/rendering/ShadowElement.cpp
+++ b/WebCore/rendering/ShadowElement.cpp
@@ -45,7 +45,7 @@ void ShadowBlockElement::layoutAsPart(const IntRect& partRect)
RenderBox* selfRenderer = toRenderBox(renderer());
IntRect oldRect = selfRenderer->frameRect();
- LayoutStateMaintainer statePusher(parentRenderer->view(), parentRenderer, parentRenderer->size());
+ LayoutStateMaintainer statePusher(parentRenderer->view(), parentRenderer, parentRenderer->size(), parentRenderer->style()->isFlippedBlocksWritingMode());
if (oldRect.size() != partRect.size())
selfRenderer->setChildNeedsLayout(true, false);
diff --git a/WebCore/rendering/ShadowElement.h b/WebCore/rendering/ShadowElement.h
index 04db62b..f5668ef 100644
--- a/WebCore/rendering/ShadowElement.h
+++ b/WebCore/rendering/ShadowElement.h
@@ -43,13 +43,13 @@ protected:
{
}
- HTMLElement* shadowParent() const { return m_shadowParent; }
+ HTMLElement* shadowParent() const { return m_shadowParent.get(); }
private:
virtual bool isShadowNode() const { return true; }
- virtual ContainerNode* shadowParentNode() { return m_shadowParent; }
+ virtual ContainerNode* shadowParentNode() { return m_shadowParent.get(); }
- HTMLElement* m_shadowParent;
+ RefPtr<HTMLElement> m_shadowParent;
};
class ShadowBlockElement : public ShadowElement<HTMLDivElement> {
diff --git a/WebCore/rendering/TextControlInnerElements.cpp b/WebCore/rendering/TextControlInnerElements.cpp
index 6495d04..fba523e 100644
--- a/WebCore/rendering/TextControlInnerElements.cpp
+++ b/WebCore/rendering/TextControlInnerElements.cpp
@@ -51,23 +51,11 @@ public:
RenderTextControlInnerBlock(Node* node, bool isMultiLine) : RenderBlock(node), m_multiLine(isMultiLine) { }
private:
- virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
virtual VisiblePosition positionForPoint(const IntPoint&);
bool m_multiLine;
};
-bool RenderTextControlInnerBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
-{
- RenderObject* renderer = node()->shadowAncestorNode()->renderer();
-
- bool placeholderIsVisible = false;
- if (renderer->isTextField())
- placeholderIsVisible = toRenderTextControlSingleLine(renderer)->placeholderIsVisible();
-
- return RenderBlock::nodeAtPoint(request, result, x, y, tx, ty, placeholderIsVisible ? HitTestBlockBackground : hitTestAction);
-}
-
VisiblePosition RenderTextControlInnerBlock::positionForPoint(const IntPoint& point)
{
IntPoint contentsPoint(point);
@@ -154,7 +142,7 @@ void TextControlInnerTextElement::defaultEventHandler(Event* event)
if (shadowAncestor && shadowAncestor != this)
shadowAncestor->defaultEventHandler(event);
}
- if (event->defaultHandled())
+ if (!event->defaultHandled())
HTMLDivElement::defaultEventHandler(event);
}
diff --git a/WebCore/rendering/TextControlInnerElements.h b/WebCore/rendering/TextControlInnerElements.h
index 61c9dba..51c9aff 100644
--- a/WebCore/rendering/TextControlInnerElements.h
+++ b/WebCore/rendering/TextControlInnerElements.h
@@ -47,12 +47,12 @@ protected:
private:
virtual bool isMouseFocusable() const { return false; }
- virtual bool isShadowNode() const { return m_shadowParent; }
- virtual ContainerNode* shadowParentNode() { return m_shadowParent; }
+ virtual bool isShadowNode() const { return m_shadowParent.get(); }
+ virtual ContainerNode* shadowParentNode() { return m_shadowParent.get(); }
virtual bool isSpellCheckingEnabled() const;
void setShadowParentNode(HTMLElement* shadowParent) { m_shadowParent = shadowParent; }
- HTMLElement* m_shadowParent;
+ RefPtr<HTMLElement> m_shadowParent;
};
class TextControlInnerTextElement : public TextControlInnerElement {
diff --git a/WebCore/rendering/VerticalPositionCache.h b/WebCore/rendering/VerticalPositionCache.h
new file mode 100644
index 0000000..4deaef5
--- /dev/null
+++ b/WebCore/rendering/VerticalPositionCache.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VerticalPositionCache_h
+#define VerticalPositionCache_h
+
+#include "FontBaseline.h"
+#include <wtf/HashMap.h>
+
+namespace WebCore {
+
+class RenderObject;
+
+// Values for vertical alignment.
+const int PositionTop = -0x7fffffff;
+const int PositionBottom = 0x7fffffff;
+const int PositionUndefined = 0x80000000;
+
+class VerticalPositionCache : public Noncopyable {
+public:
+ VerticalPositionCache()
+ { }
+
+ int get(RenderObject* renderer, FontBaseline baselineType) const
+ {
+ const HashMap<RenderObject*, int>& mapToCheck = baselineType == AlphabeticBaseline ? m_alphabeticPositions : m_ideographicPositions;
+ const HashMap<RenderObject*, int>::const_iterator it = mapToCheck.find(renderer);
+ if (it == mapToCheck.end())
+ return PositionUndefined;
+ return it->second;
+ }
+
+ void set(RenderObject* renderer, FontBaseline baselineType, int position)
+ {
+ if (baselineType == AlphabeticBaseline)
+ m_alphabeticPositions.set(renderer, position);
+ else
+ m_ideographicPositions.set(renderer, position);
+ }
+
+private:
+ HashMap<RenderObject*, int> m_alphabeticPositions;
+ HashMap<RenderObject*, int> m_ideographicPositions;
+};
+
+} // namespace WebCore
+
+#endif // VerticalPositionCache_h
diff --git a/WebCore/rendering/style/RenderStyle.cpp b/WebCore/rendering/style/RenderStyle.cpp
index a6e7d59..0ea3673 100644
--- a/WebCore/rendering/style/RenderStyle.cpp
+++ b/WebCore/rendering/style/RenderStyle.cpp
@@ -1332,6 +1332,36 @@ Length RenderStyle::marginEndUsing(const RenderStyle* otherStyle) const
return otherStyle->isLeftToRightDirection() ? marginBottom() : marginTop();
}
+void RenderStyle::setMarginStart(Length margin)
+{
+ if (isHorizontalWritingMode()) {
+ if (isLeftToRightDirection())
+ setMarginLeft(margin);
+ else
+ setMarginRight(margin);
+ } else {
+ if (isLeftToRightDirection())
+ setMarginTop(margin);
+ else
+ setMarginBottom(margin);
+ }
+}
+
+void RenderStyle::setMarginEnd(Length margin)
+{
+ if (isHorizontalWritingMode()) {
+ if (isLeftToRightDirection())
+ setMarginRight(margin);
+ else
+ setMarginLeft(margin);
+ } else {
+ if (isLeftToRightDirection())
+ setMarginBottom(margin);
+ else
+ setMarginTop(margin);
+ }
+}
+
Length RenderStyle::paddingBefore() const
{
switch (writingMode()) {
diff --git a/WebCore/rendering/style/RenderStyle.h b/WebCore/rendering/style/RenderStyle.h
index 75dc58f..c206acd 100644
--- a/WebCore/rendering/style/RenderStyle.h
+++ b/WebCore/rendering/style/RenderStyle.h
@@ -985,6 +985,8 @@ public:
void setMarginBottom(Length v) { SET_VAR(surround, margin.m_bottom, v) }
void setMarginLeft(Length v) { SET_VAR(surround, margin.m_left, v) }
void setMarginRight(Length v) { SET_VAR(surround, margin.m_right, v) }
+ void setMarginStart(Length);
+ void setMarginEnd(Length);
void resetPadding() { SET_VAR(surround, padding, LengthBox(Auto)) }
void setPaddingBox(const LengthBox& b) { SET_VAR(surround, padding, b) }
diff --git a/WebCore/rendering/svg/SVGInlineTextBox.cpp b/WebCore/rendering/svg/SVGInlineTextBox.cpp
index 699d788..d1f660a 100644
--- a/WebCore/rendering/svg/SVGInlineTextBox.cpp
+++ b/WebCore/rendering/svg/SVGInlineTextBox.cpp
@@ -588,7 +588,7 @@ IntRect SVGInlineTextBox::calculateBoundaries() const
RenderStyle* style = textRenderer->style();
ASSERT(style);
- int baseline = baselinePosition();
+ int baseline = baselinePosition(AlphabeticBaseline);
int heightDifference = baseline - style->font().ascent();
unsigned textFragmentsSize = m_textFragments.size();