Reviewed by Dan Bernstein.
Rework baselinePosition and lineHeight to be writing-mode-aware. There's a lot of refactoring here to clean up
the method parameters to be more readable and to simplify the subclassing of the various methods in order to
keep the horizontal/vertical querying to a minimum.
* WebCore.xcodeproj/project.pbxproj:
* mathml/RenderMathMLFraction.cpp:
(WebCore::RenderMathMLFraction::baselinePosition):
* mathml/RenderMathMLFraction.h:
* mathml/RenderMathMLOperator.cpp:
(WebCore::RenderMathMLOperator::baselinePosition):
* mathml/RenderMathMLOperator.h:
* mathml/RenderMathMLRow.cpp:
(WebCore::RenderMathMLRow::baselinePosition):
* mathml/RenderMathMLRow.h:
* mathml/RenderMathMLSubSup.cpp:
(WebCore::RenderMathMLSubSup::baselinePosition):
* mathml/RenderMathMLSubSup.h:
* mathml/RenderMathMLUnderOver.cpp:
(WebCore::RenderMathMLUnderOver::layout):
(WebCore::RenderMathMLUnderOver::baselinePosition):
* mathml/RenderMathMLUnderOver.h:
* rendering/InlineBox.h:
(WebCore::InlineBox::baselinePosition):
(WebCore::InlineBox::lineHeight):
* rendering/InlineFlowBox.cpp:
(WebCore::InlineFlowBox::adjustMaxAscentAndDescent):
(WebCore::InlineFlowBox::computeLogicalBoxHeights):
(WebCore::InlineFlowBox::placeBoxesInBlockDirection):
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::baselinePosition):
(WebCore::InlineTextBox::lineHeight):
* rendering/InlineTextBox.h:
* rendering/RenderBR.cpp:
(WebCore::RenderBR::lineHeight):
* rendering/RenderBR.h:
(WebCore::toRenderBR):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::lineHeight):
(WebCore::RenderBlock::baselinePosition):
(WebCore::RenderBlock::firstLineBoxBaseline):
(WebCore::RenderBlock::lastLineBoxBaseline):
(WebCore::RenderBlock::localCaretRect):
* rendering/RenderBlock.h:
* rendering/RenderBlockLineLayout.cpp:
(WebCore::RenderBlock::layoutInlineChildren):
* rendering/RenderBox.cpp:
(WebCore::RenderBox::lineHeight):
(WebCore::RenderBox::baselinePosition):
* rendering/RenderBox.h:
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::verticalPosition):
* rendering/RenderBoxModelObject.h:
* rendering/RenderFileUploadControl.cpp:
(WebCore::RenderFileUploadControl::paintObject):
* rendering/RenderFlexibleBox.cpp:
(WebCore::RenderFlexibleBox::layoutHorizontalBox):
(WebCore::RenderFlexibleBox::layoutVerticalBox):
* rendering/RenderInline.cpp:
(WebCore::RenderInline::lineHeight):
(WebCore::RenderInline::baselinePosition):
* rendering/RenderInline.h:
* rendering/RenderListBox.cpp:
(WebCore::RenderListBox::baselinePosition):
* rendering/RenderListBox.h:
* rendering/RenderListMarker.cpp:
(WebCore::RenderListMarker::lineHeight):
(WebCore::RenderListMarker::baselinePosition):
* rendering/RenderListMarker.h:
* rendering/RenderObject.cpp:
* rendering/RenderObject.h:
* rendering/RenderReplaced.cpp:
* rendering/RenderReplaced.h:
* rendering/RenderSVGRoot.cpp:
* rendering/RenderSVGRoot.h:
* rendering/RenderSlider.cpp:
(WebCore::RenderSlider::baselinePosition):
* rendering/RenderSlider.h:
* rendering/RenderTableCell.cpp:
(WebCore::RenderTableCell::baselinePosition):
* rendering/RenderTableCell.h:
* rendering/RenderTableCol.h:
(WebCore::RenderTableCol::isTableCol):
* rendering/RenderTableRow.h:
* rendering/RenderTableSection.h:
* rendering/RenderText.cpp:
* rendering/RenderText.h:
* rendering/RenderTextControl.cpp:
(WebCore::RenderTextControl::computeLogicalHeight):
* rendering/RenderTextControlMultiLine.cpp:
(WebCore::RenderTextControlMultiLine::baselinePosition):
* rendering/RenderTextControlMultiLine.h:
* rendering/RenderTextControlSingleLine.cpp:
(WebCore::RenderTextControlSingleLine::createInnerTextStyle):
* rendering/RootInlineBox.h:
(WebCore::RootInlineBox::baselinePosition):
(WebCore::RootInlineBox::lineHeight):
* rendering/svg/SVGInlineTextBox.cpp:
(WebCore::SVGInlineTextBox::calculateBoundaries):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@70072
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2010-10-19 David Hyatt <hyatt@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ https://bugs.webkit.org/show_bug.cgi?id=47841
+
+ Rework baselinePosition and lineHeight to be writing-mode-aware. There's a lot of refactoring here to clean up
+ the method parameters to be more readable and to simplify the subclassing of the various methods in order to
+ keep the horizontal/vertical querying to a minimum.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * mathml/RenderMathMLFraction.cpp:
+ (WebCore::RenderMathMLFraction::baselinePosition):
+ * mathml/RenderMathMLFraction.h:
+ * mathml/RenderMathMLOperator.cpp:
+ (WebCore::RenderMathMLOperator::baselinePosition):
+ * mathml/RenderMathMLOperator.h:
+ * mathml/RenderMathMLRow.cpp:
+ (WebCore::RenderMathMLRow::baselinePosition):
+ * mathml/RenderMathMLRow.h:
+ * mathml/RenderMathMLSubSup.cpp:
+ (WebCore::RenderMathMLSubSup::baselinePosition):
+ * mathml/RenderMathMLSubSup.h:
+ * mathml/RenderMathMLUnderOver.cpp:
+ (WebCore::RenderMathMLUnderOver::layout):
+ (WebCore::RenderMathMLUnderOver::baselinePosition):
+ * mathml/RenderMathMLUnderOver.h:
+ * rendering/InlineBox.h:
+ (WebCore::InlineBox::baselinePosition):
+ (WebCore::InlineBox::lineHeight):
+ * rendering/InlineFlowBox.cpp:
+ (WebCore::InlineFlowBox::adjustMaxAscentAndDescent):
+ (WebCore::InlineFlowBox::computeLogicalBoxHeights):
+ (WebCore::InlineFlowBox::placeBoxesInBlockDirection):
+ * rendering/InlineTextBox.cpp:
+ (WebCore::InlineTextBox::baselinePosition):
+ (WebCore::InlineTextBox::lineHeight):
+ * rendering/InlineTextBox.h:
+ * rendering/RenderBR.cpp:
+ (WebCore::RenderBR::lineHeight):
+ * rendering/RenderBR.h:
+ (WebCore::toRenderBR):
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::lineHeight):
+ (WebCore::RenderBlock::baselinePosition):
+ (WebCore::RenderBlock::firstLineBoxBaseline):
+ (WebCore::RenderBlock::lastLineBoxBaseline):
+ (WebCore::RenderBlock::localCaretRect):
+ * rendering/RenderBlock.h:
+ * rendering/RenderBlockLineLayout.cpp:
+ (WebCore::RenderBlock::layoutInlineChildren):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::lineHeight):
+ (WebCore::RenderBox::baselinePosition):
+ * rendering/RenderBox.h:
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::verticalPosition):
+ * rendering/RenderBoxModelObject.h:
+ * rendering/RenderFileUploadControl.cpp:
+ (WebCore::RenderFileUploadControl::paintObject):
+ * rendering/RenderFlexibleBox.cpp:
+ (WebCore::RenderFlexibleBox::layoutHorizontalBox):
+ (WebCore::RenderFlexibleBox::layoutVerticalBox):
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::lineHeight):
+ (WebCore::RenderInline::baselinePosition):
+ * rendering/RenderInline.h:
+ * rendering/RenderListBox.cpp:
+ (WebCore::RenderListBox::baselinePosition):
+ * rendering/RenderListBox.h:
+ * rendering/RenderListMarker.cpp:
+ (WebCore::RenderListMarker::lineHeight):
+ (WebCore::RenderListMarker::baselinePosition):
+ * rendering/RenderListMarker.h:
+ * rendering/RenderObject.cpp:
+ * rendering/RenderObject.h:
+ * rendering/RenderReplaced.cpp:
+ * rendering/RenderReplaced.h:
+ * rendering/RenderSVGRoot.cpp:
+ * rendering/RenderSVGRoot.h:
+ * rendering/RenderSlider.cpp:
+ (WebCore::RenderSlider::baselinePosition):
+ * rendering/RenderSlider.h:
+ * rendering/RenderTableCell.cpp:
+ (WebCore::RenderTableCell::baselinePosition):
+ * rendering/RenderTableCell.h:
+ * rendering/RenderTableCol.h:
+ (WebCore::RenderTableCol::isTableCol):
+ * rendering/RenderTableRow.h:
+ * rendering/RenderTableSection.h:
+ * rendering/RenderText.cpp:
+ * rendering/RenderText.h:
+ * rendering/RenderTextControl.cpp:
+ (WebCore::RenderTextControl::computeLogicalHeight):
+ * rendering/RenderTextControlMultiLine.cpp:
+ (WebCore::RenderTextControlMultiLine::baselinePosition):
+ * rendering/RenderTextControlMultiLine.h:
+ * rendering/RenderTextControlSingleLine.cpp:
+ (WebCore::RenderTextControlSingleLine::createInnerTextStyle):
+ * rendering/RootInlineBox.h:
+ (WebCore::RootInlineBox::baselinePosition):
+ (WebCore::RootInlineBox::lineHeight):
+ * rendering/svg/SVGInlineTextBox.cpp:
+ (WebCore::SVGInlineTextBox::calculateBoundaries):
+
2010-10-19 Jia Pu <jpu@apple.com>
Reviewed by Adele Peterson.
BCEA4861097D93020094C9E4 /* RenderBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA4822097D93020094C9E4 /* RenderBox.cpp */; };
BCEA4862097D93020094C9E4 /* RenderBox.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEA4823097D93020094C9E4 /* RenderBox.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCEA4863097D93020094C9E4 /* RenderBR.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA4824097D93020094C9E4 /* RenderBR.cpp */; };
- BCEA4864097D93020094C9E4 /* RenderBR.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEA4825097D93020094C9E4 /* RenderBR.h */; };
+ BCEA4864097D93020094C9E4 /* RenderBR.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEA4825097D93020094C9E4 /* RenderBR.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCEA4865097D93020094C9E4 /* RenderButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA4826097D93020094C9E4 /* RenderButton.cpp */; };
BCEA4866097D93020094C9E4 /* RenderButton.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEA4827097D93020094C9E4 /* RenderButton.h */; };
BCEA4867097D93020094C9E4 /* RenderView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA4828097D93020094C9E4 /* RenderView.cpp */; };
info.context->restore();
}
-int RenderMathMLFraction::baselinePosition(bool firstLine, bool isRootLineBox) const
+int RenderMathMLFraction::baselinePosition(bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
{
if (firstChild() && firstChild()->isRenderMathMLBlock()) {
RenderMathMLBlock* numerator = toRenderMathMLBlock(firstChild());
// a good guess.
return numerator->offsetHeight() + style()->fontSize() / 3;
}
- return RenderBlock::baselinePosition(firstLine, isRootLineBox);
+ return RenderBlock::baselinePosition(firstLine, lineDirection, linePositionMode);
}
}
RenderMathMLFraction(Element* fraction);
virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
virtual void updateFromElement();
- virtual int baselinePosition(bool , bool) const;
+ virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
virtual void paint(PaintInfo&, int tx, int ty);
protected:
virtual void layout();
return container;
}
-int RenderMathMLOperator::baselinePosition(bool firstLine, bool isRootLineBox) const
+int RenderMathMLOperator::baselinePosition(bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
{
if (m_isStacked)
- return m_stretchHeight * 2 / 3 - (m_stretchHeight - static_cast<int>(m_stretchHeight / gOperatorExpansion)) / 2;
-
- return RenderBlock::baselinePosition(firstLine, isRootLineBox);
+ return m_stretchHeight * 2 / 3 - (m_stretchHeight - static_cast<int>(m_stretchHeight / gOperatorExpansion)) / 2;
+ return RenderBlock::baselinePosition(firstLine, lineDirection, linePositionMode);
}
}
virtual void stretchToHeight(int pixelHeight);
virtual void updateFromElement();
virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
- virtual int baselinePosition(bool , bool) const;
-
+ virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+
protected:
virtual void layout();
virtual RefPtr<RenderStyle> createStackableStyle(int size, int topRelative);
RenderBlock::layout();
}
-int RenderMathMLRow::baselinePosition(bool firstLine, bool isRootLineBox) const
+int RenderMathMLRow::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
{
if (firstChild() && firstChild()->isRenderMathMLBlock()) {
RenderMathMLBlock* block = toRenderMathMLBlock(firstChild());
if (block->isRenderMathMLOperator())
- return block->y() + block->baselinePosition(firstLine, isRootLineBox);
+ return block->y() + block->baselinePosition(firstLine, direction, linePositionMode);
}
- return RenderBlock::baselinePosition(firstLine, isRootLineBox);
+ return RenderBlock::baselinePosition(firstLine, direction, linePositionMode);
}
}
RenderMathMLRow(Node* container);
virtual bool isRenderMathMLRow() const { return true; }
virtual int nonOperatorHeight() const;
- virtual int baselinePosition(bool , bool) const;
+ virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
protected:
virtual void layout();
};
}
}
-int RenderMathMLSubSup::baselinePosition(bool firstLine, bool isRootLineBox) const
+int RenderMathMLSubSup::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
{
RenderObject* base = firstChild();
if (!base)
return offsetHeight();
base = base->firstChild();
- if (!base)
- return offsetHeight();
int baseline = offsetHeight();
-
+ if (!base || !base->isBoxModelObject())
+ return baseline;
+
+ RenderBoxModelObject* box = toRenderBoxModelObject(base);
+
switch (m_kind) {
case SubSup:
if (m_scripts) {
- int topAdjust = 0;
- if (base->isBoxModelObject()) {
- RenderBoxModelObject* box = toRenderBoxModelObject(base);
- topAdjust = (m_scripts->offsetHeight() - box->offsetHeight()) / 2;
- }
+ int topAdjust = (m_scripts->offsetHeight() - box->offsetHeight()) / 2;
+
// FIXME: The last bit of this calculation should be more exact. Why is the 2-3px scaled for zoom necessary?
// The baseline is top spacing of the base + the baseline of the base + adjusted space for zoom
float zoomFactor = style()->effectiveZoom();
- return topAdjust + base->baselinePosition(firstLine, isRootLineBox) + static_cast<int>((zoomFactor > 1.25 ? 2 : 3) * zoomFactor);
+ return topAdjust + box->baselinePosition(firstLine, direction, linePositionMode) + static_cast<int>((zoomFactor > 1.25 ? 2 : 3) * zoomFactor);
}
break;
- case Sup:
- if (base) {
- baseline = base->baselinePosition(firstLine, isRootLineBox) + 4;
- // FIXME: The extra amount of the superscript ascending above the base's box
- // isn't taken into account. This should be calculated in a more reliable
- // way.
- RenderObject* sup = base->nextSibling();
- if (sup && sup->isBoxModelObject()) {
- RenderBoxModelObject* box = toRenderBoxModelObject(sup);
- // we'll take half of the sup's box height into account in the baseline
- baseline += static_cast<int>(box->offsetHeight() * 0.5);
- }
- baseline++;
+ case Sup: {
+ baseline = box->baselinePosition(firstLine, direction, linePositionMode) + 4;
+ // FIXME: The extra amount of the superscript ascending above the base's box
+ // isn't taken into account. This should be calculated in a more reliable
+ // way.
+ RenderObject* sup = base->nextSibling();
+ if (sup && sup->isBoxModelObject()) {
+ RenderBoxModelObject* box = toRenderBoxModelObject(sup);
+ // we'll take half of the sup's box height into account in the baseline
+ baseline += static_cast<int>(box->offsetHeight() * 0.5);
}
+ baseline++;
break;
+ }
case Sub:
- if (base)
- baseline = base->baselinePosition(true) + 4;
+ baseline = box->baselinePosition(true, direction) + 4;
+ break;
}
return baseline;
virtual bool hasBase() const { return true; }
virtual int nonOperatorHeight() const;
virtual void stretchToHeight(int pixelHeight);
- virtual int baselinePosition(bool, bool) const;
+ virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
protected:
virtual void layout();
if (over) {
// FIXME: descending glyphs intrude into base (e.g. lowercase y over base)
// FIXME: bases that ascend higher than the line box intrude into the over
- int overSpacing = static_cast<int>(gOverSpacingAdjustment * (getOffsetHeight(over) - over->firstChild()->baselinePosition(true)));
+ if (!over->firstChild()->isBoxModelObject())
+ break;
+
+ int overSpacing = static_cast<int>(gOverSpacingAdjustment * (getOffsetHeight(over) - toRenderBoxModelObject(over->firstChild())->baselinePosition(true, HorizontalLine)));
// base row wrapper
base = over->nextSibling();
int baseHeight = getOffsetHeight(base);
// actual base
base = base->firstChild();
+ if (!base->isBoxModelObject())
+ break;
+
// FIXME: We need to look at the space between a single maximum height of
// the line boxes and the baseline and squeeze them together
- int underSpacing = baseHeight - base->baselinePosition(true);
+ int underSpacing = baseHeight - toRenderBoxModelObject(base)->baselinePosition(true, HorizontalLine);
// adjust the base's intrusion into the under
RenderObject* under = lastChild();
if (over) {
// FIXME: descending glyphs intrude into base (e.g. lowercase y over base)
// FIXME: bases that ascend higher than the line box intrude into the over
- int overSpacing = static_cast<int>(gOverSpacingAdjustment * (getOffsetHeight(over) - over->firstChild()->baselinePosition(true)));
+ if (!over->firstChild()->isBoxModelObject())
+ break;
+ int overSpacing = static_cast<int>(gOverSpacingAdjustment * (getOffsetHeight(over) - toRenderBoxModelObject(over->firstChild())->baselinePosition(true, HorizontalLine)));
// base row wrapper
base = over->nextSibling();
int baseHeight = getOffsetHeight(base);
// actual base
base = base->firstChild();
+ if (!base->isBoxModelObject())
+ break;
+
// FIXME: We need to look at the space between a single maximum height of
// the line boxes and the baseline and squeeze them together
- int underSpacing = baseHeight - base->baselinePosition(true);
+ int underSpacing = baseHeight - toRenderBoxModelObject(base)->baselinePosition(true, HorizontalLine);
RenderObject* under = lastChild();
if (under && under->firstChild()->isRenderInline() && underSpacing > 0)
RenderBlock::layout();
}
-int RenderMathMLUnderOver::baselinePosition(bool firstLine, bool isRootLineBox) const
+int RenderMathMLUnderOver::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
{
RenderObject* current = firstChild();
if (!current)
- return RenderBlock::baselinePosition(firstLine, isRootLineBox);
+ return RenderBlock::baselinePosition(firstLine, direction, linePositionMode);
int baseline = 0;
switch (m_kind) {
if (current) {
// actual base
RenderObject* base = current->firstChild();
- if (!base)
+ if (!base || !base->isBoxModelObject())
break;
- baseline += base->baselinePosition(firstLine, isRootLineBox);
+ baseline += toRenderBoxModelObject(base)->baselinePosition(firstLine, HorizontalLine, linePositionMode);
// added the negative top margin
baseline += current->style()->marginTop().value();
}
break;
case Under:
RenderObject* base = current->firstChild();
- if (base)
- baseline += base->baselinePosition(true);
+ if (base && base->isBoxModelObject())
+ baseline += toRenderBoxModelObject(base)->baselinePosition(true, HorizontalLine);
}
// FIXME: Where is the extra 2-3px adjusted for zoom coming from?
virtual void layout();
virtual bool hasBase() const { return true; }
virtual int nonOperatorHeight() const;
- virtual int baselinePosition(bool , bool) const;
+ virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
virtual void stretchToHeight(int pixelHeight);
private:
enum UnderOverType { Under, Over, UnderOver };
#ifndef InlineBox_h
#define InlineBox_h
+#include "RenderBR.h"
#include "RenderBoxModelObject.h"
#include "TextDirection.h"
// 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;
- inline int baselinePosition(bool isRootLineBox) const { return renderer()->baselinePosition(m_firstLine, isRootLineBox); }
- inline int lineHeight(bool isRootLineBox) const { return renderer()->lineHeight(m_firstLine, isRootLineBox); }
+ virtual int baselinePosition() const { return boxModelObject()->baselinePosition(m_firstLine, m_isVertical ? VerticalLine : HorizontalLine, PositionOnContainingLine); }
+ virtual int lineHeight() const { return boxModelObject()->lineHeight(m_firstLine, m_isVertical ? VerticalLine : HorizontalLine, PositionOnContainingLine); }
+
virtual int caretMinOffset() const;
virtual int caretMaxOffset() const;
if (curr->renderer()->isPositioned())
continue; // Positioned placeholders don't affect calculations.
if (curr->y() == PositionTop || curr->y() == PositionBottom) {
- int lineHeight = curr->lineHeight(false);
+ int lineHeight = curr->lineHeight();
if (curr->y() == PositionTop) {
if (maxAscent + maxDescent < lineHeight)
maxDescent = lineHeight - maxAscent;
{
if (isRootInlineBox()) {
// Examine our root box.
- int height = lineHeight(true);
- int baseline = baselinePosition(true);
+ int height = lineHeight();
+ int baseline = baselinePosition();
if (hasTextChildren() || strictMode) {
int ascent = baseline;
int descent = height - ascent;
}
}
} else {
- lineHeight = curr->lineHeight(false);
- baseline = curr->baselinePosition(false);
+ lineHeight = curr->lineHeight();
+ baseline = curr->baselinePosition();
}
curr->setY(verticalPositionForBox(curr, m_firstLine));
void InlineFlowBox::placeBoxesInBlockDirection(int yPos, int maxHeight, int maxAscent, bool strictMode, int& selectionTop, int& selectionBottom)
{
if (isRootInlineBox())
- setY(yPos + maxAscent - baselinePosition(true)); // Place our root box.
+ setY(yPos + maxAscent - baselinePosition()); // Place our root box.
for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
if (curr->renderer()->isPositioned())
if (curr->y() == PositionTop)
curr->setY(yPos);
else if (curr->y() == PositionBottom)
- curr->setY(yPos + maxHeight - curr->lineHeight(false));
+ curr->setY(yPos + maxHeight - curr->lineHeight());
else {
if ((isInlineFlow && !static_cast<InlineFlowBox*>(curr)->hasTextChildren()) && !curr->boxModelObject()->hasInlineDirectionBordersOrPadding() && !strictMode)
childAffectsTopBottomPos = false;
- int posAdjust = maxAscent - curr->baselinePosition(false);
+ int posAdjust = maxAscent - curr->baselinePosition();
curr->setY(curr->y() + yPos + posAdjust);
}
int newY = curr->y();
if (curr->isText() || curr->isInlineFlowBox()) {
const Font& font = curr->renderer()->style(m_firstLine)->font();
- newY += curr->baselinePosition(false) - font.ascent();
+ newY += curr->baselinePosition() - font.ascent();
if (curr->isInlineFlowBox())
newY -= curr->boxModelObject()->borderTop() + curr->boxModelObject()->paddingTop();
} else if (!curr->renderer()->isBR()) {
if (isRootInlineBox()) {
const Font& font = renderer()->style(m_firstLine)->font();
- setY(y() + baselinePosition(true) - font.ascent());
+ setY(y() + baselinePosition() - font.ascent());
if (hasTextChildren() || strictMode) {
selectionTop = min(selectionTop, y());
selectionBottom = max(selectionBottom, y() + logicalHeight());
namespace WebCore {
+int InlineTextBox::baselinePosition() const
+{
+ if (!isText() || !parent())
+ return 0;
+ return parent()->baselinePosition();
+}
+
+int InlineTextBox::lineHeight() const
+{
+ if (!isText() || !parent())
+ return 0;
+ if (m_renderer->isBR())
+ return toRenderBR(m_renderer)->lineHeight(m_firstLine);
+ return parent()->lineHeight();
+}
+
int InlineTextBox::selectionTop()
{
return root()->selectionTop();
void setHasHyphen(bool hasHyphen) { m_hasEllipsisBoxOrHyphen = hasHyphen; }
static inline bool compareByStart(const InlineTextBox* first, const InlineTextBox* second) { return first->start() < second->start(); }
+
+ virtual int baselinePosition() const;
+ virtual int lineHeight() const;
+
private:
virtual int selectionTop();
virtual int selectionHeight();
{
}
-int RenderBR::baselinePosition(bool firstLine, bool isRootLineBox) const
+int RenderBR::lineHeight(bool firstLine) const
{
- if (firstTextBox() && !firstTextBox()->isText())
- return 0;
- return RenderText::baselinePosition(firstLine, isRootLineBox);
-}
-
-int RenderBR::lineHeight(bool firstLine, bool /*isRootLineBox*/) const
-{
- if (firstTextBox() && !firstTextBox()->isText())
- return 0;
-
- if (firstLine) {
+ if (firstLine && document()->usesFirstLineRules()) {
RenderStyle* s = style(firstLine);
- Length lh = s->lineHeight();
- if (lh.isNegative()) {
- if (s == style()) {
- if (m_lineHeight == -1)
- m_lineHeight = RenderObject::lineHeight(false);
- return m_lineHeight;
- }
- return s->font().lineSpacing();
- }
- if (lh.isPercent())
- return lh.calcMinValue(s->fontSize());
- return lh.value();
+ if (s != style())
+ return s->computedLineHeight();
}
-
+
if (m_lineHeight == -1)
- m_lineHeight = RenderObject::lineHeight(false);
+ m_lineHeight = style()->computedLineHeight();
+
return m_lineHeight;
}
virtual unsigned width(unsigned /*from*/, unsigned /*len*/, const Font&, int /*xpos*/) const { return 0; }
virtual unsigned width(unsigned /*from*/, unsigned /*len*/, int /*xpos*/, bool /*firstLine = false*/) const { return 0; }
- virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
- virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const;
+ int lineHeight(bool firstLine) const;
// overrides
virtual bool isBR() const { return true; }
mutable int m_lineHeight;
};
+
+inline RenderBR* toRenderBR(RenderObject* object)
+{
+ ASSERT(!object || object->isBR());
+ return static_cast<RenderBR*>(object);
+}
+
+inline const RenderBR* toRenderBR(const RenderObject* object)
+{
+ ASSERT(!object || object->isBR());
+ return static_cast<const RenderBR*>(object);
+}
+
+// This will catch anyone doing an unnecessary cast.
+void toRenderBR(const RenderBR*);
+
} // namespace WebCore
#endif // RenderBR_h
return false;
}
-int RenderBlock::lineHeight(bool firstLine, bool isRootLineBox) const
+int RenderBlock::lineHeight(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
// box, then the fact that we're an inline-block is irrelevant, and we behave
// just like a block.
- if (isReplaced() && !isRootLineBox)
- return height() + marginTop() + marginBottom();
-
+ if (isReplaced() && linePositionMode == PositionOnContainingLine)
+ return RenderBox::lineHeight(firstLine, direction, linePositionMode);
+
if (firstLine && document()->usesFirstLineRules()) {
RenderStyle* s = style(firstLine);
if (s != style())
return m_lineHeight;
}
-int RenderBlock::baselinePosition(bool b, bool isRootLineBox) const
+int RenderBlock::baselinePosition(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
// box, then the fact that we're an inline-block is irrelevant, and we behave
// just like a block.
- if (isReplaced() && !isRootLineBox) {
+ if (isReplaced() && linePositionMode == PositionOnContainingLine) {
// For "leaf" theme objects, let the theme decide what the baseline position is.
// FIXME: Might be better to have a custom CSS property instead, so that if the theme
// is turned off, checkboxes/radios will still have decent baselines.
+ // FIXME: Need to patch form controls to deal with vertical lines.
if (style()->hasAppearance() && !theme()->isControlContainer(style()->appearance()))
return theme()->baselinePosition(this);
// We also give up on finding a baseline if we have a vertical scrollbar, or if we are scrolled
// vertically (e.g., an overflow:hidden block that has had scrollTop moved) or if the baseline is outside
// of our content box.
- int baselinePos = (layer() && (layer()->marquee() || layer()->verticalScrollbar() || layer()->scrollYOffset() != 0)) ? -1 : lastLineBoxBaseline();
- if (baselinePos != -1 && baselinePos <= borderTop() + paddingTop() + contentHeight())
- return marginTop() + baselinePos;
- return height() + marginTop() + marginBottom();
+ bool ignoreBaseline = (layer() && (layer()->marquee() || (direction == HorizontalLine ? (layer()->verticalScrollbar() || layer()->scrollYOffset() != 0)
+ : (layer()->horizontalScrollbar() || layer()->scrollXOffset() != 0)))) || isWritingModeRoot();
+ 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(b, isRootLineBox);
+
+ const Font& f = style(firstLine)->font();
+ return f.ascent() + (lineHeight(firstLine, direction, linePositionMode) - f.height()) / 2;
}
int RenderBlock::firstLineBoxBaseline() const
{
- if (!isBlockFlow())
+ if (!isBlockFlow() || isWritingModeRoot())
return -1;
if (childrenInline()) {
if (firstLineBox())
- return firstLineBox()->y() + style(true)->font().ascent();
+ return firstLineBox()->logicalTop() + style(true)->font().ascent();
else
return -1;
}
if (!curr->isFloatingOrPositioned()) {
int result = curr->firstLineBoxBaseline();
if (result != -1)
- return curr->y() + result; // Translate to our coordinate space.
+ return curr->logicalTop() + result; // Translate to our coordinate space.
}
}
}
int RenderBlock::lastLineBoxBaseline() const
{
- if (!isBlockFlow())
+ if (!isBlockFlow() || isWritingModeRoot())
return -1;
+ LineDirectionMode lineDirection = style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
+
if (childrenInline()) {
- if (!firstLineBox() && hasLineIfEmpty())
- return RenderBox::baselinePosition(true, true) + borderTop() + paddingTop();
+ if (!firstLineBox() && hasLineIfEmpty()) {
+ const Font& f = firstLineStyle()->font();
+ return f.ascent() + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - f.height()) / 2 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
+ }
if (lastLineBox())
- return lastLineBox()->y() + style(lastLineBox() == firstLineBox())->font().ascent();
+ return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->font().ascent();
return -1;
- }
- else {
+ } else {
bool haveNormalFlowChild = false;
for (RenderBox* curr = lastChildBox(); curr; curr = curr->previousSiblingBox()) {
if (!curr->isFloatingOrPositioned()) {
haveNormalFlowChild = true;
int result = curr->lastLineBoxBaseline();
if (result != -1)
- return curr->y() + result; // Translate to our coordinate space.
+ return curr->logicalTop() + result; // Translate to our coordinate space.
}
}
- if (!haveNormalFlowChild && hasLineIfEmpty())
- return RenderBox::baselinePosition(true, true) + borderTop() + paddingTop();
+ if (!haveNormalFlowChild && hasLineIfEmpty()) {
+ const Font& f = firstLineStyle()->font();
+ return f.ascent() + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - f.height()) / 2 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
+ }
}
return -1;
// constructed and this kludge is not called any more. So only the caret size
// of an empty :first-line'd block is wrong. I think we can live with that.
RenderStyle* currentStyle = firstLineStyle();
- int height = lineHeight(true);
+ int height = lineHeight(true, currentStyle->isHorizontalWritingMode() ? HorizontalLine : VerticalLine);
enum CaretAlignment { alignLeft, alignRight, alignCenter };
virtual void destroy();
// These two functions are overridden for inline-block.
- virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
- virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const;
+ virtual int lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+ virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
RenderLineBoxList* lineBoxes() { return &m_lineBoxes; }
const RenderLineBoxList* lineBoxes() const { return &m_lineBoxes; }
setLogicalHeight(logicalHeight() + borderAfter() + paddingAfter() + scrollbarLogicalHeight());
if (!firstLineBox() && hasLineIfEmpty())
- setLogicalHeight(logicalHeight() + lineHeight(true, true));
+ setLogicalHeight(logicalHeight() + lineHeight(true, style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
// See if we have any lines that spill out of our block. If we do, then we will possibly need to
// truncate text.
m_overflow->resetLayoutOverflow(borderBoxRect());
}
+int RenderBox::lineHeight(bool /*firstLine*/, LineDirectionMode direction, LinePositionMode /*linePositionMode*/) const
+{
+ if (isReplaced())
+ return direction == HorizontalLine ? m_marginTop + height() + m_marginBottom : m_marginRight + width() + m_marginLeft;
+ return 0;
+}
+
+int RenderBox::baselinePosition(bool /*firstLine*/, LineDirectionMode direction, LinePositionMode /*linePositionMode*/) const
+{
+ if (isReplaced())
+ return direction == HorizontalLine ? m_marginTop + height() + m_marginBottom : m_marginRight + width() + m_marginLeft;
+ return 0;
+}
+
} // namespace WebCore
virtual void markForPaginationRelayoutIfNeeded() { }
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;
protected:
virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
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) - f.ascent();
+ vpos += baselinePosition(firstLine, lineDirection) - f.ascent();
else if (va == MIDDLE)
- vpos += -static_cast<int>(f.xHeight() / 2) - lineHeight(firstLine) / 2 + baselinePosition(firstLine);
+ 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) - baselinePosition(firstLine));
+ vpos -= (lineHeight(firstLine, lineDirection) - baselinePosition(firstLine, lineDirection));
} else if (va == BASELINE_MIDDLE)
- vpos += -lineHeight(firstLine) / 2 + baselinePosition(firstLine);
+ vpos += -lineHeight(firstLine, lineDirection) / 2 + baselinePosition(firstLine, lineDirection);
else if (va == LENGTH)
- vpos -= style()->verticalAlignLength().calcValue(lineHeight(firstLine));
+ vpos -= style()->verticalAlignLength().calcValue(lineHeight(firstLine, lineDirection));
}
return vpos;
const int PositionBottom = 0x7fffffff;
const int PositionUndefined = 0x80000000;
+// Modes for some of the line-related functions.
+enum LinePositionMode { PositionOnContainingLine, PositionOfInteriorLineBoxes };
+enum LineDirectionMode { HorizontalLine, VerticalLine };
+
// This class is the base for all objects that adhere to the CSS box model as described
// at http://www.w3.org/TR/CSS21/box.html
// 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;
// Called by RenderObject::destroy() (and RenderWidget::destroy()) and is the only way layers should ever be destroyed
void destroyLayer();
RenderButton* buttonRenderer = toRenderButton(m_button->renderer());
int textY = buttonRenderer->absoluteBoundingBoxRect().y()
+ buttonRenderer->marginTop() + buttonRenderer->borderTop() + buttonRenderer->paddingTop()
- + buttonRenderer->baselinePosition(true, false);
+ + buttonRenderer->baselinePosition(true, HorizontalLine, PositionOnContainingLine);
paintInfo.context->setFillColor(style()->visitedDependentColor(CSSPropertyColor), style()->colorSpace());
}
if (!iterator.first() && hasLineIfEmpty())
- setHeight(height() + lineHeight(true, true));
+ setHeight(height() + lineHeight(true, style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
setHeight(height() + toAdd);
yPos = height();
if (!iterator.first() && hasLineIfEmpty())
- setHeight(height() + lineHeight(true, true));
+ setHeight(height() + lineHeight(true, style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
setHeight(height() + toAdd);
return flowBox;
}
-int RenderInline::lineHeight(bool firstLine, bool /*isRootLineBox*/) const
+int RenderInline::lineHeight(bool firstLine, LineDirectionMode /*direction*/, LinePositionMode /*linePositionMode*/) const
{
if (firstLine && document()->usesFirstLineRules()) {
RenderStyle* s = style(firstLine);
return m_lineHeight;
}
+int RenderInline::baselinePosition(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.
virtual void dirtyLinesFromChangedChild(RenderObject* child) { m_lineBoxes.dirtyLinesFromChangedChild(this, child); }
- virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
+ virtual int lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+ virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
virtual void childBecameNonInline(RenderObject* child);
}
}
-int RenderListBox::baselinePosition(bool, bool) const
+int RenderListBox::baselinePosition(bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
{
- return height() + marginTop() + marginBottom() - baselineAdjustment;
+ return RenderBox::baselinePosition(firstLine, lineDirection, linePositionMode) - baselineAdjustment;
}
IntRect RenderListBox::itemBoundingBoxRect(int tx, int ty, int index)
virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1, Node** stopNode = 0);
virtual void computePreferredLogicalWidths();
- virtual int baselinePosition(bool firstLine, bool isRootLineBox) const;
+ virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
virtual void computeLogicalHeight();
virtual void layout();
style()->setMarginRight(Length(marginRight, Fixed));
}
-int RenderListMarker::lineHeight(bool, bool) const
+int RenderListMarker::lineHeight(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
{
if (!isImage())
- return m_listItem->lineHeight(false, true);
- return height();
+ return m_listItem->lineHeight(firstLine, direction, PositionOfInteriorLineBoxes);
+ return RenderBox::lineHeight(firstLine, direction, linePositionMode);
}
-int RenderListMarker::baselinePosition(bool, bool) const
+int RenderListMarker::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
{
- if (!isImage()) {
- const Font& font = style()->font();
- return font.ascent() + (lineHeight(false) - font.height())/2;
- }
- return height();
+ if (!isImage())
+ return m_listItem->baselinePosition(firstLine, direction, PositionOfInteriorLineBoxes);
+ return RenderBox::baselinePosition(firstLine, direction, linePositionMode);
}
String RenderListMarker::suffix() const
virtual InlineBox* createInlineBox();
- virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
- virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const;
+ virtual int lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+ virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
bool isImage() const;
bool isText() const { return !isImage(); }
return false;
}
-int RenderObject::lineHeight(bool firstLine, bool /*isRootLineBox*/) const
-{
- return style(firstLine)->computedLineHeight();
-}
-
-int RenderObject::baselinePosition(bool firstLine, bool isRootLineBox) const
-{
- const Font& f = style(firstLine)->font();
- return f.ascent() + (lineHeight(firstLine, isRootLineBox) - f.height()) / 2;
-}
-
void RenderObject::scheduleRelayout()
{
if (isRenderView()) {
void updateFillImages(const FillLayer*, const FillLayer*);
void updateImage(StyleImage*, StyleImage*);
- // for discussion of lineHeight see CSS2 spec
- virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
- // for the vertical-align property of inline elements
- // the offset of baseline from the top of the object.
- virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const;
virtual void paint(PaintInfo&, int tx, int ty);
// Recursive function that computes the size and position of this object and all its descendants.
setPreferredLogicalWidthsDirty(false);
}
-int RenderReplaced::lineHeight(bool, bool) const
-{
- return height() + marginTop() + marginBottom();
-}
-
-int RenderReplaced::baselinePosition(bool, bool) const
-{
- return height() + marginTop() + marginBottom();
-}
-
unsigned RenderReplaced::caretMaxRenderedOffset() const
{
return 1;
virtual bool canHaveChildren() const { return false; }
- virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
- virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const;
-
virtual void computePreferredLogicalWidths();
int calcAspectRatioLogicalWidth() const;
{
}
-int RenderSVGRoot::lineHeight(bool, bool) const
-{
- return height() + marginTop() + marginBottom();
-}
-
-int RenderSVGRoot::baselinePosition(bool, bool) const
-{
- return height() + marginTop() + marginBottom();
-}
-
void RenderSVGRoot::computePreferredLogicalWidths()
{
ASSERT(preferredLogicalWidthsDirty());
virtual bool isSVGRoot() const { return true; }
virtual const char* renderName() const { return "RenderSVGRoot"; }
- virtual int lineHeight(bool b, bool isRootLineBox = false) const;
- virtual int baselinePosition(bool b, bool isRootLineBox = false) const;
virtual void computePreferredLogicalWidths();
virtual int computeReplacedLogicalWidth(bool includeMaxWidth = true) const;
virtual int computeReplacedLogicalHeight() const;
m_thumb->detach();
}
-int RenderSlider::baselinePosition(bool, bool) const
+int RenderSlider::baselinePosition(bool /*firstLine*/, LineDirectionMode, LinePositionMode) const
{
return height() + marginTop();
}
virtual const char* renderName() const { return "RenderSlider"; }
virtual bool isSlider() const { return true; }
- virtual int baselinePosition(bool, bool) const;
+ virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
virtual void computePreferredLogicalWidths();
virtual void layout();
virtual void updateFromElement();
RenderBlock::computeRectForRepaint(repaintContainer, r, fixed);
}
-int RenderTableCell::baselinePosition(bool firstLine, bool isRootLineBox) const
+int RenderTableCell::baselinePosition(bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
{
- if (isRootLineBox)
- return RenderBox::baselinePosition(firstLine, isRootLineBox);
+ // 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
void paintBackgroundsBehindCell(PaintInfo&, int tx, int ty, RenderObject* backgroundObject);
- virtual int baselinePosition(bool firstLine = false, bool isRootLineBox = false) const;
+ virtual int baselinePosition(bool firstLine = false, LineDirectionMode = HorizontalLine, LinePositionMode = PositionOnContainingLine) const;
void setIntrinsicPaddingBefore(int p) { m_intrinsicPaddingBefore = p; }
void setIntrinsicPaddingAfter(int p) { m_intrinsicPaddingAfter = p; }
virtual const char* renderName() const { return "RenderTableCol"; }
virtual bool isTableCol() const { return true; }
- virtual int lineHeight(bool) const { return 0; }
virtual void updateFromElement();
virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
virtual void destroy();
virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
- virtual int lineHeight(bool, bool) const { return 0; }
virtual void layout();
virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
- virtual int lineHeight(bool, bool) const { return 0; }
-
bool ensureRows(int);
void clearGrid();
return text;
}
-int RenderText::lineHeight(bool firstLine, bool) const
-{
- // Always use the interior line height of the parent (e.g., if our parent is an inline block).
- return parent()->lineHeight(firstLine, true);
-}
-
void RenderText::dirtyLineBoxes(bool fullLayout)
{
if (fullLayout)
virtual unsigned width(unsigned from, unsigned len, const Font&, int xPos, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
virtual unsigned width(unsigned from, unsigned len, int xPos, bool firstLine = false, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
- virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
-
virtual int minPreferredLogicalWidth() const;
virtual int maxPreferredLogicalWidth() const;
m_innerText->renderBox()->paddingTop() + m_innerText->renderBox()->paddingBottom() +
m_innerText->renderBox()->marginTop() + m_innerText->renderBox()->marginBottom());
- adjustControlHeightBasedOnLineHeight(m_innerText->renderer()->lineHeight(true, true));
+ adjustControlHeightBasedOnLineHeight(m_innerText->renderBox()->lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes));
setHeight(height() + borderAndPaddingHeight());
// We are able to have a horizontal scrollbar if the overflow style is scroll, or if its auto and there's no word wrap.
setHeight(height() + lineHeight * static_cast<HTMLTextAreaElement*>(node())->rows());
}
-int RenderTextControlMultiLine::baselinePosition(bool, bool) const
+int RenderTextControlMultiLine::baselinePosition(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
{
- return height() + marginTop() + marginBottom();
+ return RenderBox::baselinePosition(firstLine, direction, linePositionMode);
}
void RenderTextControlMultiLine::updateFromElement()
virtual float getAvgCharWidth(AtomicString family);
virtual int preferredContentWidth(float charWidth) const;
virtual void adjustControlHeightBasedOnLineHeight(int lineHeight);
- virtual int baselinePosition(bool firstLine, bool isRootLineBox) const;
+ virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
virtual void updateFromElement();
virtual void cacheSelection(int start, int end);
textBlockStyle->setOverflowY(OHIDDEN);
// Do not allow line-height to be smaller than our default.
- if (textBlockStyle->font().lineSpacing() > lineHeight(true, true))
+ if (textBlockStyle->font().lineSpacing() > lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes))
textBlockStyle->setLineHeight(Length(-100.0f, Percent));
WebCore::EDisplay display = (m_innerBlock || inputElement()->hasSpinButton() ? INLINE_BLOCK : BLOCK);
virtual void clearTruncation();
+ virtual int baselinePosition() const { return boxModelObject()->baselinePosition(m_firstLine, m_isVertical ? VerticalLine : HorizontalLine, PositionOfInteriorLineBoxes); }
+ virtual int lineHeight() const { return boxModelObject()->lineHeight(m_firstLine, m_isVertical ? VerticalLine : HorizontalLine, PositionOfInteriorLineBoxes); }
+
#if PLATFORM(MAC)
void addHighlightOverflow();
void paintCustomHighlight(PaintInfo&, int tx, int ty, const AtomicString& highlightType);
RenderStyle* style = textRenderer->style();
ASSERT(style);
- int baseline = baselinePosition(true);
+ int baseline = baselinePosition();
int heightDifference = baseline - style->font().ascent();
unsigned textFragmentsSize = m_textFragments.size();