1 /* 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 4 * Copyright (C) 2003, 2006, 2007, 2009 Apple Inc. All rights reserved. 5 * Copyright (C) 2010 Google Inc. All rights reserved. 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Library General Public 9 * License as published by the Free Software Foundation; either 10 * version 2 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Library General Public License for more details. 16 * 17 * You should have received a copy of the GNU Library General Public License 18 * along with this library; see the file COPYING.LIB. If not, write to 19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 * Boston, MA 02110-1301, USA. 21 * 22 */ 23 24 #ifndef RenderBoxModelObject_h 25 #define RenderBoxModelObject_h 26 27 #include "core/animation/ActiveAnimations.h" 28 #include "core/rendering/RenderLayerModelObject.h" 29 #include "core/rendering/style/ShadowData.h" 30 #include "platform/geometry/LayoutRect.h" 31 32 namespace WebCore { 33 34 // Modes for some of the line-related functions. 35 enum LinePositionMode { PositionOnContainingLine, PositionOfInteriorLineBoxes }; 36 enum LineDirectionMode { HorizontalLine, VerticalLine }; 37 typedef unsigned BorderEdgeFlags; 38 39 enum BackgroundBleedAvoidance { 40 BackgroundBleedNone, 41 BackgroundBleedShrinkBackground, 42 BackgroundBleedClipBackground, 43 BackgroundBleedBackgroundOverBorder 44 }; 45 46 enum ContentChangeType { 47 ImageChanged, 48 CanvasChanged, 49 CanvasPixelsChanged, 50 CanvasContextChanged 51 }; 52 53 class RenderTextFragment; 54 class StickyPositionViewportConstraints; 55 56 // This class is the base for all objects that adhere to the CSS box model as described 57 // at http://www.w3.org/TR/CSS21/box.html 58 59 class RenderBoxModelObject : public RenderLayerModelObject { 60 public: 61 RenderBoxModelObject(ContainerNode*); 62 virtual ~RenderBoxModelObject(); 63 64 LayoutSize relativePositionOffset() const; relativePositionLogicalOffset()65 LayoutSize relativePositionLogicalOffset() const { return style()->isHorizontalWritingMode() ? relativePositionOffset() : relativePositionOffset().transposedSize(); } 66 67 void computeStickyPositionConstraints(StickyPositionViewportConstraints&, const FloatRect& constrainingRect) const; 68 LayoutSize stickyPositionOffset() const; stickyPositionLogicalOffset()69 LayoutSize stickyPositionLogicalOffset() const { return style()->isHorizontalWritingMode() ? stickyPositionOffset() : stickyPositionOffset().transposedSize(); } 70 71 LayoutSize offsetForInFlowPosition() const; 72 73 // IE extensions. Used to calculate offsetWidth/Height. Overridden by inlines (RenderFlow) 74 // to return the remaining width on a given line (and the height of a single line). 75 virtual LayoutUnit offsetLeft() const; 76 virtual LayoutUnit offsetTop() const; 77 virtual LayoutUnit offsetWidth() const = 0; 78 virtual LayoutUnit offsetHeight() const = 0; 79 pixelSnappedOffsetLeft()80 int pixelSnappedOffsetLeft() const { return roundToInt(offsetLeft()); } pixelSnappedOffsetTop()81 int pixelSnappedOffsetTop() const { return roundToInt(offsetTop()); } 82 virtual int pixelSnappedOffsetWidth() const; 83 virtual int pixelSnappedOffsetHeight() const; 84 85 virtual void updateFromStyle() OVERRIDE; 86 87 // This will work on inlines to return the bounding box of all of the lines' border boxes. 88 virtual IntRect borderBoundingBox() const = 0; 89 90 // These return the CSS computed padding values. computedCSSPaddingTop()91 LayoutUnit computedCSSPaddingTop() const { return computedCSSPadding(style()->paddingTop()); } computedCSSPaddingBottom()92 LayoutUnit computedCSSPaddingBottom() const { return computedCSSPadding(style()->paddingBottom()); } computedCSSPaddingLeft()93 LayoutUnit computedCSSPaddingLeft() const { return computedCSSPadding(style()->paddingLeft()); } computedCSSPaddingRight()94 LayoutUnit computedCSSPaddingRight() const { return computedCSSPadding(style()->paddingRight()); } computedCSSPaddingBefore()95 LayoutUnit computedCSSPaddingBefore() const { return computedCSSPadding(style()->paddingBefore()); } computedCSSPaddingAfter()96 LayoutUnit computedCSSPaddingAfter() const { return computedCSSPadding(style()->paddingAfter()); } computedCSSPaddingStart()97 LayoutUnit computedCSSPaddingStart() const { return computedCSSPadding(style()->paddingStart()); } computedCSSPaddingEnd()98 LayoutUnit computedCSSPaddingEnd() const { return computedCSSPadding(style()->paddingEnd()); } 99 100 // These functions are used during layout. Table cells 101 // override them to include some extra intrinsic padding. paddingTop()102 virtual LayoutUnit paddingTop() const { return computedCSSPaddingTop(); } paddingBottom()103 virtual LayoutUnit paddingBottom() const { return computedCSSPaddingBottom(); } paddingLeft()104 virtual LayoutUnit paddingLeft() const { return computedCSSPaddingLeft(); } paddingRight()105 virtual LayoutUnit paddingRight() const { return computedCSSPaddingRight(); } paddingBefore()106 virtual LayoutUnit paddingBefore() const { return computedCSSPaddingBefore(); } paddingAfter()107 virtual LayoutUnit paddingAfter() const { return computedCSSPaddingAfter(); } paddingStart()108 virtual LayoutUnit paddingStart() const { return computedCSSPaddingStart(); } paddingEnd()109 virtual LayoutUnit paddingEnd() const { return computedCSSPaddingEnd(); } 110 borderTop()111 virtual int borderTop() const { return style()->borderTopWidth(); } borderBottom()112 virtual int borderBottom() const { return style()->borderBottomWidth(); } borderLeft()113 virtual int borderLeft() const { return style()->borderLeftWidth(); } borderRight()114 virtual int borderRight() const { return style()->borderRightWidth(); } borderBefore()115 virtual int borderBefore() const { return style()->borderBeforeWidth(); } borderAfter()116 virtual int borderAfter() const { return style()->borderAfterWidth(); } borderStart()117 virtual int borderStart() const { return style()->borderStartWidth(); } borderEnd()118 virtual int borderEnd() const { return style()->borderEndWidth(); } 119 borderWidth()120 int borderWidth() const { return borderLeft() + borderRight(); } borderHeight()121 int borderHeight() const { return borderTop() + borderBottom(); } 122 borderAndPaddingStart()123 LayoutUnit borderAndPaddingStart() const { return borderStart() + paddingStart(); } borderAndPaddingBefore()124 LayoutUnit borderAndPaddingBefore() const { return borderBefore() + paddingBefore(); } borderAndPaddingAfter()125 LayoutUnit borderAndPaddingAfter() const { return borderAfter() + paddingAfter(); } 126 borderAndPaddingHeight()127 LayoutUnit borderAndPaddingHeight() const { return borderTop() + borderBottom() + paddingTop() + paddingBottom(); } borderAndPaddingWidth()128 LayoutUnit borderAndPaddingWidth() const { return borderLeft() + borderRight() + paddingLeft() + paddingRight(); } borderAndPaddingLogicalHeight()129 LayoutUnit borderAndPaddingLogicalHeight() const { return borderAndPaddingBefore() + borderAndPaddingAfter(); } borderAndPaddingLogicalWidth()130 LayoutUnit borderAndPaddingLogicalWidth() const { return borderStart() + borderEnd() + paddingStart() + paddingEnd(); } borderAndPaddingLogicalLeft()131 LayoutUnit borderAndPaddingLogicalLeft() const { return style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop(); } 132 133 borderLogicalLeft()134 LayoutUnit borderLogicalLeft() const { return style()->isHorizontalWritingMode() ? borderLeft() : borderTop(); } borderLogicalRight()135 LayoutUnit borderLogicalRight() const { return style()->isHorizontalWritingMode() ? borderRight() : borderBottom(); } borderLogicalWidth()136 LayoutUnit borderLogicalWidth() const { return borderStart() + borderEnd(); } borderLogicalHeight()137 LayoutUnit borderLogicalHeight() const { return borderBefore() + borderAfter(); } 138 paddingLogicalLeft()139 LayoutUnit paddingLogicalLeft() const { return style()->isHorizontalWritingMode() ? paddingLeft() : paddingTop(); } paddingLogicalRight()140 LayoutUnit paddingLogicalRight() const { return style()->isHorizontalWritingMode() ? paddingRight() : paddingBottom(); } paddingLogicalWidth()141 LayoutUnit paddingLogicalWidth() const { return paddingStart() + paddingEnd(); } paddingLogicalHeight()142 LayoutUnit paddingLogicalHeight() const { return paddingBefore() + paddingAfter(); } 143 144 virtual LayoutUnit marginTop() const = 0; 145 virtual LayoutUnit marginBottom() const = 0; 146 virtual LayoutUnit marginLeft() const = 0; 147 virtual LayoutUnit marginRight() const = 0; 148 virtual LayoutUnit marginBefore(const RenderStyle* otherStyle = 0) const = 0; 149 virtual LayoutUnit marginAfter(const RenderStyle* otherStyle = 0) const = 0; 150 virtual LayoutUnit marginStart(const RenderStyle* otherStyle = 0) const = 0; 151 virtual LayoutUnit marginEnd(const RenderStyle* otherStyle = 0) const = 0; marginHeight()152 LayoutUnit marginHeight() const { return marginTop() + marginBottom(); } marginWidth()153 LayoutUnit marginWidth() const { return marginLeft() + marginRight(); } marginLogicalHeight()154 LayoutUnit marginLogicalHeight() const { return marginBefore() + marginAfter(); } marginLogicalWidth()155 LayoutUnit marginLogicalWidth() const { return marginStart() + marginEnd(); } 156 hasInlineDirectionBordersPaddingOrMargin()157 bool hasInlineDirectionBordersPaddingOrMargin() const { return hasInlineDirectionBordersOrPadding() || marginStart()|| marginEnd(); } hasInlineDirectionBordersOrPadding()158 bool hasInlineDirectionBordersOrPadding() const { return borderStart() || borderEnd() || paddingStart()|| paddingEnd(); } 159 160 virtual LayoutUnit containingBlockLogicalWidthForContent() const; 161 childBecameNonInline(RenderObject *)162 virtual void childBecameNonInline(RenderObject* /*child*/) { } 163 164 void paintBorder(const PaintInfo&, const LayoutRect&, const RenderStyle*, BackgroundBleedAvoidance = BackgroundBleedNone, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true); 165 bool paintNinePieceImage(GraphicsContext*, const LayoutRect&, const RenderStyle*, const NinePieceImage&, CompositeOperator = CompositeSourceOver); 166 void paintBoxShadow(const PaintInfo&, const LayoutRect&, const RenderStyle*, ShadowStyle, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true); 167 void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, const LayoutRect&, BackgroundBleedAvoidance, InlineFlowBox* = 0, const LayoutSize& = LayoutSize(), CompositeOperator = CompositeSourceOver, RenderObject* backgroundObject = 0); 168 169 virtual bool boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance, InlineFlowBox* = 0) const; 170 171 // Overridden by subclasses to determine line height and baseline position. 172 virtual LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const = 0; 173 virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const = 0; 174 175 virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) const OVERRIDE; 176 virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE; 177 178 virtual void setSelectionState(SelectionState) OVERRIDE; 179 180 void contentChanged(ContentChangeType); 181 bool hasAcceleratedCompositing() const; 182 183 virtual void computeLayerHitTestRects(LayerHitTestRects&) const OVERRIDE; 184 185 protected: 186 virtual void willBeDestroyed() OVERRIDE; 187 188 class BackgroundImageGeometry { 189 public: BackgroundImageGeometry()190 BackgroundImageGeometry() 191 : m_hasNonLocalGeometry(false) 192 { } 193 destOrigin()194 IntPoint destOrigin() const { return m_destOrigin; } setDestOrigin(const IntPoint & destOrigin)195 void setDestOrigin(const IntPoint& destOrigin) 196 { 197 m_destOrigin = destOrigin; 198 } 199 destRect()200 IntRect destRect() const { return m_destRect; } setDestRect(const IntRect & destRect)201 void setDestRect(const IntRect& destRect) 202 { 203 m_destRect = destRect; 204 } 205 206 // Returns the phase relative to the destination rectangle. 207 IntPoint relativePhase() const; 208 phase()209 IntPoint phase() const { return m_phase; } setPhase(const IntPoint & phase)210 void setPhase(const IntPoint& phase) 211 { 212 m_phase = phase; 213 } 214 tileSize()215 IntSize tileSize() const { return m_tileSize; } setTileSize(const IntSize & tileSize)216 void setTileSize(const IntSize& tileSize) 217 { 218 m_tileSize = tileSize; 219 } 220 221 // Space-size represents extra width and height that may be added to 222 // the image if used as a pattern with repeat: space spaceSize()223 IntSize spaceSize() const { return m_repeatSpacing; } setSpaceSize(const IntSize & repeatSpacing)224 void setSpaceSize(const IntSize& repeatSpacing) 225 { 226 m_repeatSpacing = repeatSpacing; 227 } 228 setPhaseX(int x)229 void setPhaseX(int x) { m_phase.setX(x); } setPhaseY(int y)230 void setPhaseY(int y) { m_phase.setY(y); } 231 232 void setNoRepeatX(int xOffset); 233 void setNoRepeatY(int yOffset); 234 235 void useFixedAttachment(const IntPoint& attachmentPoint); 236 237 void clip(const IntRect&); 238 239 void setHasNonLocalGeometry(bool hasNonLocalGeometry = true) { m_hasNonLocalGeometry = hasNonLocalGeometry; } hasNonLocalGeometry()240 bool hasNonLocalGeometry() const { return m_hasNonLocalGeometry; } 241 242 private: 243 IntRect m_destRect; 244 IntPoint m_destOrigin; 245 IntPoint m_phase; 246 IntSize m_tileSize; 247 IntSize m_repeatSpacing; 248 bool m_hasNonLocalGeometry; // Has background-attachment: fixed. Implies that we can't always cheaply compute destRect. 249 }; 250 251 LayoutPoint adjustedPositionRelativeToOffsetParent(const LayoutPoint&) const; 252 253 bool calculateHasBoxDecorations() const; 254 void calculateBackgroundImageGeometry(const RenderLayerModelObject* paintContainer, const FillLayer*, const LayoutRect& paintRect, BackgroundImageGeometry&, RenderObject* = 0) const; 255 void getBorderEdgeInfo(class BorderEdge[], const RenderStyle*, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true) const; 256 bool borderObscuresBackgroundEdge(const FloatSize& contextScale) const; 257 bool borderObscuresBackground() const; 258 RoundedRect backgroundRoundedRectAdjustedForBleedAvoidance(GraphicsContext*, const LayoutRect&, BackgroundBleedAvoidance, InlineFlowBox*, const LayoutSize&, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const; 259 LayoutRect borderInnerRectAdjustedForBleedAvoidance(GraphicsContext*, const LayoutRect&, BackgroundBleedAvoidance) const; 260 261 InterpolationQuality chooseInterpolationQuality(GraphicsContext*, Image*, const void*, const LayoutSize&); 262 263 RenderBoxModelObject* continuation() const; 264 void setContinuation(RenderBoxModelObject*); 265 266 LayoutRect localCaretRectForEmptyElement(LayoutUnit width, LayoutUnit textIndentOffset); 267 268 static void clipRoundedInnerRect(GraphicsContext*, const LayoutRect&, const RoundedRect& clipRect); 269 270 bool hasAutoHeightOrContainingBlockWithAutoHeight() const; 271 272 public: 273 static bool shouldAntialiasLines(GraphicsContext*); 274 275 // For RenderBlocks and RenderInlines with m_style->styleType() == FIRST_LETTER, this tracks their remaining text fragments 276 RenderTextFragment* firstLetterRemainingText() const; 277 void setFirstLetterRemainingText(RenderTextFragment*); 278 279 // These functions are only used internally to manipulate the render tree structure via remove/insert/appendChildNode. 280 // Since they are typically called only to move objects around within anonymous blocks (which only have layers in 281 // the case of column spans), the default for fullRemoveInsert is false rather than true. 282 void moveChildTo(RenderBoxModelObject* toBoxModelObject, RenderObject* child, RenderObject* beforeChild, bool fullRemoveInsert = false); 283 void moveChildTo(RenderBoxModelObject* toBoxModelObject, RenderObject* child, bool fullRemoveInsert = false) 284 { 285 moveChildTo(toBoxModelObject, child, 0, fullRemoveInsert); 286 } 287 void moveAllChildrenTo(RenderBoxModelObject* toBoxModelObject, bool fullRemoveInsert = false) 288 { 289 moveAllChildrenTo(toBoxModelObject, 0, fullRemoveInsert); 290 } 291 void moveAllChildrenTo(RenderBoxModelObject* toBoxModelObject, RenderObject* beforeChild, bool fullRemoveInsert = false) 292 { 293 moveChildrenTo(toBoxModelObject, slowFirstChild(), 0, beforeChild, fullRemoveInsert); 294 } 295 // Move all of the kids from |startChild| up to but excluding |endChild|. 0 can be passed as the |endChild| to denote 296 // that all the kids from |startChild| onwards should be moved. 297 void moveChildrenTo(RenderBoxModelObject* toBoxModelObject, RenderObject* startChild, RenderObject* endChild, bool fullRemoveInsert = false) 298 { 299 moveChildrenTo(toBoxModelObject, startChild, endChild, 0, fullRemoveInsert); 300 } 301 void moveChildrenTo(RenderBoxModelObject* toBoxModelObject, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert = false); 302 303 enum ScaleByEffectiveZoomOrNot { ScaleByEffectiveZoom, DoNotScaleByEffectiveZoom }; 304 IntSize calculateImageIntrinsicDimensions(StyleImage*, const IntSize& scaledPositioningAreaSize, ScaleByEffectiveZoomOrNot) const; 305 306 private: 307 LayoutUnit computedCSSPadding(const Length&) const; isBoxModelObject()308 virtual bool isBoxModelObject() const OVERRIDE FINAL { return true; } 309 310 virtual LayoutRect frameRectForStickyPositioning() const = 0; 311 312 IntSize calculateFillTileSize(const FillLayer*, const IntSize& scaledPositioningAreaSize) const; 313 314 RoundedRect getBackgroundRoundedRect(const LayoutRect&, InlineFlowBox*, LayoutUnit inlineBoxWidth, LayoutUnit inlineBoxHeight, 315 bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const; 316 317 bool fixedBackgroundPaintsInLocalCoordinates() const; 318 319 void clipBorderSidePolygon(GraphicsContext*, const RoundedRect& outerBorder, const RoundedRect& innerBorder, 320 BoxSide, bool firstEdgeMatches, bool secondEdgeMatches); 321 void clipBorderSideForComplexInnerPath(GraphicsContext*, const RoundedRect&, const RoundedRect&, BoxSide, const class BorderEdge[]); 322 void paintOneBorderSide(GraphicsContext*, const RenderStyle*, const RoundedRect& outerBorder, const RoundedRect& innerBorder, 323 const IntRect& sideRect, BoxSide, BoxSide adjacentSide1, BoxSide adjacentSide2, const class BorderEdge[], 324 const Path*, BackgroundBleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias, const Color* overrideColor = 0); 325 void paintTranslucentBorderSides(GraphicsContext*, const RenderStyle*, const RoundedRect& outerBorder, const RoundedRect& innerBorder, const IntPoint& innerBorderAdjustment, 326 const class BorderEdge[], BorderEdgeFlags, BackgroundBleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias = false); 327 void paintBorderSides(GraphicsContext*, const RenderStyle*, const RoundedRect& outerBorder, const RoundedRect& innerBorder, 328 const IntPoint& innerBorderAdjustment, const class BorderEdge[], BorderEdgeFlags, BackgroundBleedAvoidance, 329 bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias = false, const Color* overrideColor = 0); 330 void drawBoxSideFromPath(GraphicsContext*, const LayoutRect&, const Path&, const class BorderEdge[], 331 float thickness, float drawThickness, BoxSide, const RenderStyle*, 332 Color, EBorderStyle, BackgroundBleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge); 333 }; 334 335 DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderBoxModelObject, isBoxModelObject()); 336 337 } // namespace WebCore 338 339 #endif // RenderBoxModelObject_h 340