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