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/rendering/RenderLayerModelObject.h" 28 #include "core/rendering/style/ShadowData.h" 29 #include "platform/geometry/LayoutRect.h" 30 31 namespace WebCore { 32 33 // Modes for some of the line-related functions. 34 enum LinePositionMode { PositionOnContainingLine, PositionOfInteriorLineBoxes }; 35 enum LineDirectionMode { HorizontalLine, VerticalLine }; 36 typedef unsigned BorderEdgeFlags; 37 38 enum BackgroundBleedAvoidance { 39 BackgroundBleedNone, 40 BackgroundBleedShrinkBackground, 41 BackgroundBleedUseTransparencyLayer, 42 BackgroundBleedBackgroundOverBorder 43 }; 44 45 enum ContentChangeType { 46 ImageChanged, 47 MaskImageChanged, 48 CanvasChanged, 49 CanvasPixelsChanged, 50 VideoChanged, 51 FullScreenChanged 52 }; 53 54 class KeyframeList; 55 class RenderTextFragment; 56 class StickyPositionViewportConstraints; 57 58 // This class is the base for all objects that adhere to the CSS box model as described 59 // at http://www.w3.org/TR/CSS21/box.html 60 61 class RenderBoxModelObject : public RenderLayerModelObject { 62 public: 63 RenderBoxModelObject(ContainerNode*); 64 virtual ~RenderBoxModelObject(); 65 66 LayoutSize relativePositionOffset() const; relativePositionLogicalOffset()67 LayoutSize relativePositionLogicalOffset() const { return style()->isHorizontalWritingMode() ? relativePositionOffset() : relativePositionOffset().transposedSize(); } 68 69 void computeStickyPositionConstraints(StickyPositionViewportConstraints&, const FloatRect& viewportRect) const; 70 LayoutSize stickyPositionOffset() const; stickyPositionLogicalOffset()71 LayoutSize stickyPositionLogicalOffset() const { return style()->isHorizontalWritingMode() ? stickyPositionOffset() : stickyPositionOffset().transposedSize(); } 72 73 LayoutSize offsetForInFlowPosition() const; 74 75 // IE extensions. Used to calculate offsetWidth/Height. Overridden by inlines (RenderFlow) 76 // to return the remaining width on a given line (and the height of a single line). 77 virtual LayoutUnit offsetLeft() const; 78 virtual LayoutUnit offsetTop() const; 79 virtual LayoutUnit offsetWidth() const = 0; 80 virtual LayoutUnit offsetHeight() const = 0; 81 pixelSnappedOffsetLeft()82 int pixelSnappedOffsetLeft() const { return roundToInt(offsetLeft()); } pixelSnappedOffsetTop()83 int pixelSnappedOffsetTop() const { return roundToInt(offsetTop()); } 84 virtual int pixelSnappedOffsetWidth() const; 85 virtual int pixelSnappedOffsetHeight() const; 86 87 virtual void updateFromStyle() OVERRIDE; 88 requiresLayer()89 virtual bool requiresLayer() const OVERRIDE { return isRoot() || isPositioned() || createsGroup() || hasClipPath() || hasTransform() || hasHiddenBackface() || hasReflection() || style()->specifiesColumns(); } 90 91 // This will work on inlines to return the bounding box of all of the lines' border boxes. 92 virtual IntRect borderBoundingBox() const = 0; 93 94 // These return the CSS computed padding values. computedCSSPaddingTop()95 LayoutUnit computedCSSPaddingTop() const { return computedCSSPadding(style()->paddingTop()); } computedCSSPaddingBottom()96 LayoutUnit computedCSSPaddingBottom() const { return computedCSSPadding(style()->paddingBottom()); } computedCSSPaddingLeft()97 LayoutUnit computedCSSPaddingLeft() const { return computedCSSPadding(style()->paddingLeft()); } computedCSSPaddingRight()98 LayoutUnit computedCSSPaddingRight() const { return computedCSSPadding(style()->paddingRight()); } computedCSSPaddingBefore()99 LayoutUnit computedCSSPaddingBefore() const { return computedCSSPadding(style()->paddingBefore()); } computedCSSPaddingAfter()100 LayoutUnit computedCSSPaddingAfter() const { return computedCSSPadding(style()->paddingAfter()); } computedCSSPaddingStart()101 LayoutUnit computedCSSPaddingStart() const { return computedCSSPadding(style()->paddingStart()); } computedCSSPaddingEnd()102 LayoutUnit computedCSSPaddingEnd() const { return computedCSSPadding(style()->paddingEnd()); } 103 104 // These functions are used during layout. Table cells 105 // override them to include some extra intrinsic padding. paddingTop()106 virtual LayoutUnit paddingTop() const { return computedCSSPaddingTop(); } paddingBottom()107 virtual LayoutUnit paddingBottom() const { return computedCSSPaddingBottom(); } paddingLeft()108 virtual LayoutUnit paddingLeft() const { return computedCSSPaddingLeft(); } paddingRight()109 virtual LayoutUnit paddingRight() const { return computedCSSPaddingRight(); } paddingBefore()110 virtual LayoutUnit paddingBefore() const { return computedCSSPaddingBefore(); } paddingAfter()111 virtual LayoutUnit paddingAfter() const { return computedCSSPaddingAfter(); } paddingStart()112 virtual LayoutUnit paddingStart() const { return computedCSSPaddingStart(); } paddingEnd()113 virtual LayoutUnit paddingEnd() const { return computedCSSPaddingEnd(); } 114 borderTop()115 virtual int borderTop() const { return style()->borderTopWidth(); } borderBottom()116 virtual int borderBottom() const { return style()->borderBottomWidth(); } borderLeft()117 virtual int borderLeft() const { return style()->borderLeftWidth(); } borderRight()118 virtual int borderRight() const { return style()->borderRightWidth(); } borderBefore()119 virtual int borderBefore() const { return style()->borderBeforeWidth(); } borderAfter()120 virtual int borderAfter() const { return style()->borderAfterWidth(); } borderStart()121 virtual int borderStart() const { return style()->borderStartWidth(); } borderEnd()122 virtual int borderEnd() const { return style()->borderEndWidth(); } 123 borderAndPaddingStart()124 LayoutUnit borderAndPaddingStart() const { return borderStart() + paddingStart(); } borderAndPaddingBefore()125 LayoutUnit borderAndPaddingBefore() const { return borderBefore() + paddingBefore(); } borderAndPaddingAfter()126 LayoutUnit borderAndPaddingAfter() const { return borderAfter() + paddingAfter(); } 127 borderAndPaddingHeight()128 LayoutUnit borderAndPaddingHeight() const { return borderTop() + borderBottom() + paddingTop() + paddingBottom(); } borderAndPaddingWidth()129 LayoutUnit borderAndPaddingWidth() const { return borderLeft() + borderRight() + paddingLeft() + paddingRight(); } borderAndPaddingLogicalHeight()130 LayoutUnit borderAndPaddingLogicalHeight() const { return borderAndPaddingBefore() + borderAndPaddingAfter(); } borderAndPaddingLogicalWidth()131 LayoutUnit borderAndPaddingLogicalWidth() const { return borderStart() + borderEnd() + paddingStart() + paddingEnd(); } borderAndPaddingLogicalLeft()132 LayoutUnit borderAndPaddingLogicalLeft() const { return style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop(); } 133 134 borderLogicalLeft()135 LayoutUnit borderLogicalLeft() const { return style()->isHorizontalWritingMode() ? borderLeft() : borderTop(); } borderLogicalRight()136 LayoutUnit borderLogicalRight() const { return style()->isHorizontalWritingMode() ? borderRight() : borderBottom(); } borderLogicalWidth()137 LayoutUnit borderLogicalWidth() const { return borderStart() + borderEnd(); } borderLogicalHeight()138 LayoutUnit borderLogicalHeight() const { return borderBefore() + borderAfter(); } 139 paddingLogicalLeft()140 LayoutUnit paddingLogicalLeft() const { return style()->isHorizontalWritingMode() ? paddingLeft() : paddingTop(); } paddingLogicalRight()141 LayoutUnit paddingLogicalRight() const { return style()->isHorizontalWritingMode() ? paddingRight() : paddingBottom(); } paddingLogicalWidth()142 LayoutUnit paddingLogicalWidth() const { return paddingStart() + paddingEnd(); } paddingLogicalHeight()143 LayoutUnit paddingLogicalHeight() const { return paddingBefore() + paddingAfter(); } 144 145 virtual LayoutUnit marginTop() const = 0; 146 virtual LayoutUnit marginBottom() const = 0; 147 virtual LayoutUnit marginLeft() const = 0; 148 virtual LayoutUnit marginRight() const = 0; 149 virtual LayoutUnit marginBefore(const RenderStyle* otherStyle = 0) const = 0; 150 virtual LayoutUnit marginAfter(const RenderStyle* otherStyle = 0) const = 0; 151 virtual LayoutUnit marginStart(const RenderStyle* otherStyle = 0) const = 0; 152 virtual LayoutUnit marginEnd(const RenderStyle* otherStyle = 0) const = 0; marginHeight()153 LayoutUnit marginHeight() const { return marginTop() + marginBottom(); } marginWidth()154 LayoutUnit marginWidth() const { return marginLeft() + marginRight(); } marginLogicalHeight()155 LayoutUnit marginLogicalHeight() const { return marginBefore() + marginAfter(); } marginLogicalWidth()156 LayoutUnit marginLogicalWidth() const { return marginStart() + marginEnd(); } 157 hasInlineDirectionBordersPaddingOrMargin()158 bool hasInlineDirectionBordersPaddingOrMargin() const { return hasInlineDirectionBordersOrPadding() || marginStart()|| marginEnd(); } hasInlineDirectionBordersOrPadding()159 bool hasInlineDirectionBordersOrPadding() const { return borderStart() || borderEnd() || paddingStart()|| paddingEnd(); } 160 161 virtual LayoutUnit containingBlockLogicalWidthForContent() const; 162 childBecameNonInline(RenderObject *)163 virtual void childBecameNonInline(RenderObject* /*child*/) { } 164 165 void paintBorder(const PaintInfo&, const LayoutRect&, const RenderStyle*, BackgroundBleedAvoidance = BackgroundBleedNone, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true); 166 bool paintNinePieceImage(GraphicsContext*, const LayoutRect&, const RenderStyle*, const NinePieceImage&, CompositeOperator = CompositeSourceOver); 167 void paintBoxShadow(const PaintInfo&, const LayoutRect&, const RenderStyle*, ShadowStyle, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true); 168 void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, const LayoutRect&, BackgroundBleedAvoidance, InlineFlowBox* = 0, const LayoutSize& = LayoutSize(), CompositeOperator = CompositeSourceOver, RenderObject* backgroundObject = 0); 169 170 virtual bool boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance, InlineFlowBox* = 0) const; 171 172 // Overridden by subclasses to determine line height and baseline position. 173 virtual LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const = 0; 174 virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const = 0; 175 176 virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) const OVERRIDE; 177 virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE; 178 179 void highQualityRepaintTimerFired(Timer<RenderBoxModelObject>*); 180 181 virtual void setSelectionState(SelectionState s); 182 canHaveBoxInfoInRegion()183 bool canHaveBoxInfoInRegion() const { return !isFloating() && !isReplaced() && !isInline() && !hasColumns() && !isTableCell() && isRenderBlock() && !isRenderSVGBlock(); } 184 185 void contentChanged(ContentChangeType); 186 bool hasAcceleratedCompositing() const; 187 188 bool startTransition(double, CSSPropertyID, const RenderStyle* fromStyle, const RenderStyle* toStyle); 189 void transitionPaused(double timeOffset, CSSPropertyID); 190 void transitionFinished(CSSPropertyID); 191 192 bool startAnimation(double timeOffset, const CSSAnimationData*, const KeyframeList& keyframes); 193 void animationPaused(double timeOffset, const String& name); 194 void animationFinished(const String& name); 195 196 virtual void computeLayerHitTestRects(LayerHitTestRects&) const OVERRIDE; 197 198 protected: 199 virtual void willBeDestroyed(); 200 201 class BackgroundImageGeometry { 202 public: destOrigin()203 IntPoint destOrigin() const { return m_destOrigin; } setDestOrigin(const IntPoint & destOrigin)204 void setDestOrigin(const IntPoint& destOrigin) 205 { 206 m_destOrigin = destOrigin; 207 } 208 destRect()209 IntRect destRect() const { return m_destRect; } setDestRect(const IntRect & destRect)210 void setDestRect(const IntRect& destRect) 211 { 212 m_destRect = destRect; 213 } 214 215 // Returns the phase relative to the destination rectangle. 216 IntPoint relativePhase() const; 217 phase()218 IntPoint phase() const { return m_phase; } setPhase(const IntPoint & phase)219 void setPhase(const IntPoint& phase) 220 { 221 m_phase = phase; 222 } 223 tileSize()224 IntSize tileSize() const { return m_tileSize; } setTileSize(const IntSize & tileSize)225 void setTileSize(const IntSize& tileSize) 226 { 227 m_tileSize = tileSize; 228 } 229 230 // Space-size represents extra width and height that may be added to 231 // the image if used as a pattern with repeat: space spaceSize()232 IntSize spaceSize() const { return m_repeatSpacing; } setSpaceSize(const IntSize & repeatSpacing)233 void setSpaceSize(const IntSize& repeatSpacing) 234 { 235 m_repeatSpacing = repeatSpacing; 236 } 237 setPhaseX(int x)238 void setPhaseX(int x) { m_phase.setX(x); } setPhaseY(int y)239 void setPhaseY(int y) { m_phase.setY(y); } 240 241 void setNoRepeatX(int xOffset); 242 void setNoRepeatY(int yOffset); 243 244 void useFixedAttachment(const IntPoint& attachmentPoint); 245 246 void clip(const IntRect&); 247 private: 248 IntRect m_destRect; 249 IntPoint m_destOrigin; 250 IntPoint m_phase; 251 IntSize m_tileSize; 252 IntSize m_repeatSpacing; 253 }; 254 255 LayoutPoint adjustedPositionRelativeToOffsetParent(const LayoutPoint&) const; 256 257 void calculateBackgroundImageGeometry(const FillLayer*, const LayoutRect& paintRect, BackgroundImageGeometry&, RenderObject* = 0); 258 void getBorderEdgeInfo(class BorderEdge[], const RenderStyle*, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true) const; 259 bool borderObscuresBackgroundEdge(const FloatSize& contextScale) const; 260 bool borderObscuresBackground() const; 261 RoundedRect backgroundRoundedRectAdjustedForBleedAvoidance(GraphicsContext*, const LayoutRect&, BackgroundBleedAvoidance, InlineFlowBox*, const LayoutSize&, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const; 262 LayoutRect borderInnerRectAdjustedForBleedAvoidance(GraphicsContext*, const LayoutRect&, BackgroundBleedAvoidance) const; 263 264 bool shouldPaintAtLowQuality(GraphicsContext*, Image*, const void*, const LayoutSize&); 265 266 RenderBoxModelObject* continuation() const; 267 void setContinuation(RenderBoxModelObject*); 268 269 LayoutRect localCaretRectForEmptyElement(LayoutUnit width, LayoutUnit textIndentOffset); 270 271 static bool shouldAntialiasLines(GraphicsContext*); 272 273 static void clipRoundedInnerRect(GraphicsContext*, const LayoutRect&, const RoundedRect& clipRect); 274 275 bool hasAutoHeightOrContainingBlockWithAutoHeight() const; 276 277 public: 278 // For RenderBlocks and RenderInlines with m_style->styleType() == FIRST_LETTER, this tracks their remaining text fragments 279 RenderTextFragment* firstLetterRemainingText() const; 280 void setFirstLetterRemainingText(RenderTextFragment*); 281 282 // These functions are only used internally to manipulate the render tree structure via remove/insert/appendChildNode. 283 // Since they are typically called only to move objects around within anonymous blocks (which only have layers in 284 // the case of column spans), the default for fullRemoveInsert is false rather than true. 285 void moveChildTo(RenderBoxModelObject* toBoxModelObject, RenderObject* child, RenderObject* beforeChild, bool fullRemoveInsert = false); 286 void moveChildTo(RenderBoxModelObject* toBoxModelObject, RenderObject* child, bool fullRemoveInsert = false) 287 { 288 moveChildTo(toBoxModelObject, child, 0, fullRemoveInsert); 289 } 290 void moveAllChildrenTo(RenderBoxModelObject* toBoxModelObject, bool fullRemoveInsert = false) 291 { 292 moveAllChildrenTo(toBoxModelObject, 0, fullRemoveInsert); 293 } 294 void moveAllChildrenTo(RenderBoxModelObject* toBoxModelObject, RenderObject* beforeChild, bool fullRemoveInsert = false) 295 { 296 moveChildrenTo(toBoxModelObject, firstChild(), 0, beforeChild, fullRemoveInsert); 297 } 298 // Move all of the kids from |startChild| up to but excluding |endChild|. 0 can be passed as the |endChild| to denote 299 // that all the kids from |startChild| onwards should be moved. 300 void moveChildrenTo(RenderBoxModelObject* toBoxModelObject, RenderObject* startChild, RenderObject* endChild, bool fullRemoveInsert = false) 301 { 302 moveChildrenTo(toBoxModelObject, startChild, endChild, 0, fullRemoveInsert); 303 } 304 void moveChildrenTo(RenderBoxModelObject* toBoxModelObject, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert = false); 305 306 private: 307 LayoutUnit computedCSSPadding(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 enum ScaleByEffectiveZoomOrNot { ScaleByEffectiveZoom, DoNotScaleByEffectiveZoom }; 315 IntSize calculateImageIntrinsicDimensions(StyleImage*, const IntSize& scaledPositioningAreaSize, ScaleByEffectiveZoomOrNot) const; 316 317 RoundedRect getBackgroundRoundedRect(const LayoutRect&, InlineFlowBox*, LayoutUnit inlineBoxWidth, LayoutUnit inlineBoxHeight, 318 bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const; 319 320 bool fixedBackgroundPaintsInLocalCoordinates() const; 321 322 void clipBorderSidePolygon(GraphicsContext*, const RoundedRect& outerBorder, const RoundedRect& innerBorder, 323 BoxSide, bool firstEdgeMatches, bool secondEdgeMatches); 324 void clipBorderSideForComplexInnerPath(GraphicsContext*, const RoundedRect&, const RoundedRect&, BoxSide, const class BorderEdge[]); 325 void paintOneBorderSide(GraphicsContext*, const RenderStyle*, const RoundedRect& outerBorder, const RoundedRect& innerBorder, 326 const IntRect& sideRect, BoxSide, BoxSide adjacentSide1, BoxSide adjacentSide2, const class BorderEdge[], 327 const Path*, BackgroundBleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias, const Color* overrideColor = 0); 328 void paintTranslucentBorderSides(GraphicsContext*, const RenderStyle*, const RoundedRect& outerBorder, const RoundedRect& innerBorder, const IntPoint& innerBorderAdjustment, 329 const class BorderEdge[], BorderEdgeFlags, BackgroundBleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias = false); 330 void paintBorderSides(GraphicsContext*, const RenderStyle*, const RoundedRect& outerBorder, const RoundedRect& innerBorder, 331 const IntPoint& innerBorderAdjustment, const class BorderEdge[], BorderEdgeFlags, BackgroundBleedAvoidance, 332 bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias = false, const Color* overrideColor = 0); 333 void drawBoxSideFromPath(GraphicsContext*, const LayoutRect&, const Path&, const class BorderEdge[], 334 float thickness, float drawThickness, BoxSide, const RenderStyle*, 335 Color, EBorderStyle, BackgroundBleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge); 336 }; 337 338 DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderBoxModelObject, isBoxModelObject()); 339 340 } // namespace WebCore 341 342 #endif // RenderBoxModelObject_h 343