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 "LayoutRect.h" 28#include "RenderLayerModelObject.h" 29 30namespace WebCore { 31 32// Modes for some of the line-related functions. 33enum LinePositionMode { PositionOnContainingLine, PositionOfInteriorLineBoxes }; 34enum LineDirectionMode { HorizontalLine, VerticalLine }; 35typedef unsigned BorderEdgeFlags; 36 37enum BackgroundBleedAvoidance { 38 BackgroundBleedNone, 39 BackgroundBleedShrinkBackground, 40 BackgroundBleedUseTransparencyLayer, 41 BackgroundBleedBackgroundOverBorder 42}; 43 44enum ContentChangeType { 45 ImageChanged, 46 MaskImageChanged, 47 BackgroundImageChanged, 48 CanvasChanged, 49 CanvasPixelsChanged, 50 VideoChanged, 51 FullScreenChanged 52}; 53 54class KeyframeList; 55class InlineFlowBox; 56class 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 61class RenderBoxModelObject : public RenderLayerModelObject { 62public: 63 RenderBoxModelObject(ContainerNode*); 64 virtual ~RenderBoxModelObject(); 65 66 LayoutSize relativePositionOffset() const; 67 LayoutSize relativePositionLogicalOffset() const { return style()->isHorizontalWritingMode() ? relativePositionOffset() : relativePositionOffset().transposedSize(); } 68 69 void computeStickyPositionConstraints(StickyPositionViewportConstraints&, const FloatRect& viewportRect) const; 70 LayoutSize stickyPositionOffset() const; 71 LayoutSize stickyPositionLogicalOffset() const { return style()->isHorizontalWritingMode() ? stickyPositionOffset() : stickyPositionOffset().transposedSize(); } 72 73 LayoutSize offsetForInFlowPosition() const; 74 LayoutSize paintOffset() const; 75 76 // IE extensions. Used to calculate offsetWidth/Height. Overridden by inlines (RenderFlow) 77 // to return the remaining width on a given line (and the height of a single line). 78 virtual LayoutUnit offsetLeft() const; 79 virtual LayoutUnit offsetTop() const; 80 virtual LayoutUnit offsetWidth() const = 0; 81 virtual LayoutUnit offsetHeight() const = 0; 82 83 int pixelSnappedOffsetLeft() const { return roundToInt(offsetLeft()); } 84 int pixelSnappedOffsetTop() const { return roundToInt(offsetTop()); } 85 virtual int pixelSnappedOffsetWidth() const; 86 virtual int pixelSnappedOffsetHeight() const; 87 88 virtual void updateFromStyle() OVERRIDE; 89 90 virtual bool requiresLayer() const OVERRIDE { return isRoot() || isPositioned() || createsGroup() || hasClipPath() || hasTransform() || hasHiddenBackface() || hasReflection() || style()->specifiesColumns(); } 91 92 // This will work on inlines to return the bounding box of all of the lines' border boxes. 93 virtual IntRect borderBoundingBox() const = 0; 94 95 // These return the CSS computed padding values. 96 LayoutUnit computedCSSPaddingTop() const { return computedCSSPadding(style()->paddingTop()); } 97 LayoutUnit computedCSSPaddingBottom() const { return computedCSSPadding(style()->paddingBottom()); } 98 LayoutUnit computedCSSPaddingLeft() const { return computedCSSPadding(style()->paddingLeft()); } 99 LayoutUnit computedCSSPaddingRight() const { return computedCSSPadding(style()->paddingRight()); } 100 LayoutUnit computedCSSPaddingBefore() const { return computedCSSPadding(style()->paddingBefore()); } 101 LayoutUnit computedCSSPaddingAfter() const { return computedCSSPadding(style()->paddingAfter()); } 102 LayoutUnit computedCSSPaddingStart() const { return computedCSSPadding(style()->paddingStart()); } 103 LayoutUnit computedCSSPaddingEnd() const { return computedCSSPadding(style()->paddingEnd()); } 104 105 // These functions are used during layout. Table cells and the MathML 106 // code override them to include some extra intrinsic padding. 107 virtual LayoutUnit paddingTop() const { return computedCSSPaddingTop(); } 108 virtual LayoutUnit paddingBottom() const { return computedCSSPaddingBottom(); } 109 virtual LayoutUnit paddingLeft() const { return computedCSSPaddingLeft(); } 110 virtual LayoutUnit paddingRight() const { return computedCSSPaddingRight(); } 111 virtual LayoutUnit paddingBefore() const { return computedCSSPaddingBefore(); } 112 virtual LayoutUnit paddingAfter() const { return computedCSSPaddingAfter(); } 113 virtual LayoutUnit paddingStart() const { return computedCSSPaddingStart(); } 114 virtual LayoutUnit paddingEnd() const { return computedCSSPaddingEnd(); } 115 116 virtual int borderTop() const { return style()->borderTopWidth(); } 117 virtual int borderBottom() const { return style()->borderBottomWidth(); } 118 virtual int borderLeft() const { return style()->borderLeftWidth(); } 119 virtual int borderRight() const { return style()->borderRightWidth(); } 120 virtual int borderBefore() const { return style()->borderBeforeWidth(); } 121 virtual int borderAfter() const { return style()->borderAfterWidth(); } 122 virtual int borderStart() const { return style()->borderStartWidth(); } 123 virtual int borderEnd() const { return style()->borderEndWidth(); } 124 125 LayoutUnit borderAndPaddingStart() const { return borderStart() + paddingStart(); } 126 LayoutUnit borderAndPaddingBefore() const { return borderBefore() + paddingBefore(); } 127 LayoutUnit borderAndPaddingAfter() const { return borderAfter() + paddingAfter(); } 128 129 LayoutUnit borderAndPaddingHeight() const { return borderTop() + borderBottom() + paddingTop() + paddingBottom(); } 130 LayoutUnit borderAndPaddingWidth() const { return borderLeft() + borderRight() + paddingLeft() + paddingRight(); } 131 LayoutUnit borderAndPaddingLogicalHeight() const { return borderAndPaddingBefore() + borderAndPaddingAfter(); } 132 LayoutUnit borderAndPaddingLogicalWidth() const { return borderStart() + borderEnd() + paddingStart() + paddingEnd(); } 133 LayoutUnit borderAndPaddingLogicalLeft() const { return style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop(); } 134 135 LayoutUnit borderLogicalLeft() const { return style()->isHorizontalWritingMode() ? borderLeft() : borderTop(); } 136 LayoutUnit borderLogicalRight() const { return style()->isHorizontalWritingMode() ? borderRight() : borderBottom(); } 137 138 LayoutUnit paddingLogicalLeft() const { return style()->isHorizontalWritingMode() ? paddingLeft() : paddingTop(); } 139 LayoutUnit paddingLogicalRight() const { return style()->isHorizontalWritingMode() ? paddingRight() : paddingBottom(); } 140 141 virtual LayoutUnit marginTop() const = 0; 142 virtual LayoutUnit marginBottom() const = 0; 143 virtual LayoutUnit marginLeft() const = 0; 144 virtual LayoutUnit marginRight() const = 0; 145 virtual LayoutUnit marginBefore(const RenderStyle* otherStyle = 0) const = 0; 146 virtual LayoutUnit marginAfter(const RenderStyle* otherStyle = 0) const = 0; 147 virtual LayoutUnit marginStart(const RenderStyle* otherStyle = 0) const = 0; 148 virtual LayoutUnit marginEnd(const RenderStyle* otherStyle = 0) const = 0; 149 LayoutUnit marginHeight() const { return marginTop() + marginBottom(); } 150 LayoutUnit marginWidth() const { return marginLeft() + marginRight(); } 151 LayoutUnit marginLogicalHeight() const { return marginBefore() + marginAfter(); } 152 LayoutUnit marginLogicalWidth() const { return marginStart() + marginEnd(); } 153 154 bool hasInlineDirectionBordersPaddingOrMargin() const { return hasInlineDirectionBordersOrPadding() || marginStart()|| marginEnd(); } 155 bool hasInlineDirectionBordersOrPadding() const { return borderStart() || borderEnd() || paddingStart()|| paddingEnd(); } 156 157 virtual LayoutUnit containingBlockLogicalWidthForContent() const; 158 159 virtual void childBecameNonInline(RenderObject* /*child*/) { } 160 161 void paintBorder(const PaintInfo&, const LayoutRect&, const RenderStyle*, BackgroundBleedAvoidance = BackgroundBleedNone, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true); 162 bool paintNinePieceImage(GraphicsContext*, const LayoutRect&, const RenderStyle*, const NinePieceImage&, CompositeOperator = CompositeSourceOver); 163 void paintBoxShadow(const PaintInfo&, const LayoutRect&, const RenderStyle*, ShadowStyle, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true); 164 void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, const LayoutRect&, BackgroundBleedAvoidance, InlineFlowBox* = 0, const LayoutSize& = LayoutSize(), CompositeOperator = CompositeSourceOver, RenderObject* backgroundObject = 0); 165 166 virtual bool boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance, InlineFlowBox* = 0) const; 167 168 // Overridden by subclasses to determine line height and baseline position. 169 virtual LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const = 0; 170 virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const = 0; 171 172 virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) 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(); } 179 180 void getGeometryForBackgroundImage(const RenderLayerModelObject* paintContainer, IntRect& destRect, IntPoint& phase, IntSize& tileSize) const; 181#if USE(ACCELERATED_COMPOSITING) 182 void contentChanged(ContentChangeType); 183 bool hasAcceleratedCompositing() const; 184 185 bool startTransition(double, CSSPropertyID, const RenderStyle* fromStyle, const RenderStyle* toStyle); 186 void transitionPaused(double timeOffset, CSSPropertyID); 187 void transitionFinished(CSSPropertyID); 188 189 bool startAnimation(double timeOffset, const Animation*, const KeyframeList& keyframes); 190 void animationPaused(double timeOffset, const String& name); 191 void animationFinished(const String& name); 192 193 void suspendAnimations(double time = 0); 194#endif 195 196protected: 197 virtual void willBeDestroyed(); 198 199 class BackgroundImageGeometry { 200 public: 201 BackgroundImageGeometry() 202 : m_hasNonLocalGeometry(false) 203 { } 204 IntPoint destOrigin() const { return m_destOrigin; } 205 void setDestOrigin(const IntPoint& destOrigin) 206 { 207 m_destOrigin = destOrigin; 208 } 209 210 IntRect destRect() const { return m_destRect; } 211 void setDestRect(const IntRect& destRect) 212 { 213 m_destRect = destRect; 214 } 215 216 // Returns the phase relative to the destination rectangle. 217 IntPoint relativePhase() const; 218 219 IntPoint phase() const { return m_phase; } 220 void setPhase(const IntPoint& phase) 221 { 222 m_phase = phase; 223 } 224 225 IntSize tileSize() const { return m_tileSize; } 226 void setTileSize(const IntSize& tileSize) 227 { 228 m_tileSize = tileSize; 229 } 230 231 void setPhaseX(int x) { m_phase.setX(x); } 232 void setPhaseY(int y) { m_phase.setY(y); } 233 234 void setNoRepeatX(int xOffset); 235 void setNoRepeatY(int yOffset); 236 237 void useFixedAttachment(const IntPoint& attachmentPoint); 238 239 void clip(const IntRect&); 240 241 void setHasNonLocalGeometry(bool hasNonLocalGeometry = true) { m_hasNonLocalGeometry = hasNonLocalGeometry; } 242 bool hasNonLocalGeometry() const { return m_hasNonLocalGeometry; } 243 244 private: 245 IntRect m_destRect; 246 IntPoint m_destOrigin; 247 IntPoint m_phase; 248 IntSize m_tileSize; 249 bool m_hasNonLocalGeometry; // Has background-attachment: fixed. Implies that we can't always cheaply compute destRect. 250 }; 251 252 LayoutPoint adjustedPositionRelativeToOffsetParent(const LayoutPoint&) const; 253 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 bool shouldPaintAtLowQuality(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 bool shouldAntialiasLines(GraphicsContext*); 269 270 static void clipRoundedInnerRect(GraphicsContext*, const LayoutRect&, const RoundedRect& clipRect); 271 272 bool hasAutoHeightOrContainingBlockWithAutoHeight() const; 273 274public: 275 // For RenderBlocks and RenderInlines with m_style->styleType() == FIRST_LETTER, this tracks their remaining text fragments 276 RenderObject* firstLetterRemainingText() const; 277 void setFirstLetterRemainingText(RenderObject*); 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, firstChild(), 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 303private: 304 LayoutUnit computedCSSPadding(Length) const; 305 virtual bool isBoxModelObject() const { return true; } 306 307 virtual LayoutRect frameRectForStickyPositioning() const = 0; 308 309 IntSize calculateFillTileSize(const FillLayer*, const IntSize& scaledPositioningAreaSize) const; 310 311 enum ScaleByEffectiveZoomOrNot { ScaleByEffectiveZoom, DoNotScaleByEffectiveZoom }; 312 IntSize calculateImageIntrinsicDimensions(StyleImage*, const IntSize& scaledPositioningAreaSize, ScaleByEffectiveZoomOrNot) 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 335inline RenderBoxModelObject* toRenderBoxModelObject(RenderObject* object) 336{ 337 ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isBoxModelObject()); 338 return static_cast<RenderBoxModelObject*>(object); 339} 340 341inline const RenderBoxModelObject* toRenderBoxModelObject(const RenderObject* object) 342{ 343 ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isBoxModelObject()); 344 return static_cast<const RenderBoxModelObject*>(object); 345} 346 347// This will catch anyone doing an unnecessary cast. 348void toRenderBoxModelObject(const RenderBoxModelObject*); 349 350} // namespace WebCore 351 352#endif // RenderBoxModelObject_h 353