1 /* 2 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer. 11 * 2. Redistributions in binary form must reproduce the above 12 * copyright notice, this list of conditions and the following 13 * disclaimer in the documentation and/or other materials 14 * provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 21 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 26 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #ifndef ShapeInfo_h 31 #define ShapeInfo_h 32 33 #include "core/rendering/shapes/Shape.h" 34 #include "core/rendering/style/RenderStyle.h" 35 #include "core/rendering/style/ShapeValue.h" 36 #include "platform/LayoutUnit.h" 37 #include "platform/geometry/FloatRect.h" 38 #include "wtf/OwnPtr.h" 39 #include "wtf/Vector.h" 40 41 namespace WebCore { 42 43 template<class KeyType, class InfoType> 44 class MappedInfo { 45 public: 46 static InfoType* ensureInfo(const KeyType* key) 47 { 48 InfoMap& infoMap = MappedInfo<KeyType, InfoType>::infoMap(); 49 if (InfoType* info = infoMap.get(key)) 50 return info; 51 typename InfoMap::AddResult result = infoMap.add(key, InfoType::createInfo(key)); 52 return result.iterator->value.get(); 53 } 54 static void removeInfo(const KeyType* key) { infoMap().remove(key); } 55 static InfoType* info(const KeyType* key) { return infoMap().get(key); } 56 private: 57 typedef HashMap<const KeyType*, OwnPtr<InfoType> > InfoMap; 58 static InfoMap& infoMap() 59 { 60 DEFINE_STATIC_LOCAL(InfoMap, staticInfoMap, ()); 61 return staticInfoMap; 62 } 63 }; 64 65 template<class RenderType> 66 class ShapeInfo { 67 WTF_MAKE_FAST_ALLOCATED; 68 public: 69 virtual ~ShapeInfo() { } 70 71 void setShapeSize(LayoutUnit logicalWidth, LayoutUnit logicalHeight) 72 { 73 if (shapeValue()->type() == ShapeValue::Box) { 74 switch (shapeValue()->layoutBox()) { 75 case MarginBox: 76 logicalHeight += m_renderer->marginLogicalHeight(); 77 logicalWidth += m_renderer->marginLogicalWidth(); 78 break; 79 case BorderBox: 80 break; 81 case PaddingBox: 82 logicalHeight -= m_renderer->borderLogicalHeight(); 83 logicalWidth -= m_renderer->borderLogicalWidth(); 84 break; 85 case ContentBox: 86 logicalHeight -= m_renderer->borderAndPaddingLogicalHeight(); 87 logicalWidth -= m_renderer->borderAndPaddingLogicalWidth(); 88 break; 89 } 90 } else if (m_renderer->style()->boxSizing() == CONTENT_BOX) { 91 logicalHeight -= m_renderer->borderAndPaddingLogicalHeight(); 92 logicalWidth -= m_renderer->borderAndPaddingLogicalWidth(); 93 } 94 95 LayoutSize newLogicalSize(logicalWidth, logicalHeight); 96 if (m_shapeLogicalSize == newLogicalSize) 97 return; 98 dirtyShapeSize(); 99 m_shapeLogicalSize = newLogicalSize; 100 } 101 102 SegmentList computeSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineHeight) const; 103 104 LayoutUnit shapeLogicalTop() const { return computedShapeLogicalBoundingBox().y() + logicalTopOffset(); } 105 LayoutUnit shapeLogicalBottom() const { return computedShapeLogicalBoundingBox().maxY() + logicalTopOffset(); } 106 LayoutUnit shapeLogicalLeft() const { return computedShapeLogicalBoundingBox().x() + logicalLeftOffset(); } 107 LayoutUnit shapeLogicalRight() const { return computedShapeLogicalBoundingBox().maxX() + logicalLeftOffset(); } 108 LayoutUnit shapeLogicalWidth() const { return computedShapeLogicalBoundingBox().width(); } 109 LayoutUnit shapeLogicalHeight() const { return computedShapeLogicalBoundingBox().height(); } 110 111 LayoutUnit logicalLineTop() const { return m_shapeLineTop + logicalTopOffset(); } 112 LayoutUnit logicalLineBottom() const { return m_shapeLineTop + m_lineHeight + logicalTopOffset(); } 113 114 LayoutUnit shapeContainingBlockHeight() const { return (m_renderer->style()->boxSizing() == CONTENT_BOX) ? (m_shapeLogicalSize.height() + m_renderer->borderAndPaddingLogicalHeight()) : m_shapeLogicalSize.height(); } 115 116 virtual bool lineOverlapsShapeBounds() const = 0; 117 118 void dirtyShapeSize() { m_shape.clear(); } 119 bool shapeSizeDirty() { return !m_shape.get(); } 120 const RenderType* owner() const { return m_renderer; } 121 LayoutSize shapeSize() const { return m_shapeLogicalSize; } 122 123 protected: 124 ShapeInfo(const RenderType* renderer): m_renderer(renderer) { } 125 126 const Shape* computedShape() const; 127 128 virtual LayoutRect computedShapeLogicalBoundingBox() const = 0; 129 virtual ShapeValue* shapeValue() const = 0; 130 virtual void getIntervals(LayoutUnit, LayoutUnit, SegmentList&) const = 0; 131 132 LayoutUnit logicalTopOffset() const 133 { 134 if (shapeValue()->type() == ShapeValue::Box) { 135 switch (shapeValue()->layoutBox()) { 136 case MarginBox: 137 return -m_renderer->marginBefore(); 138 case BorderBox: 139 return LayoutUnit(); 140 case PaddingBox: 141 return m_renderer->borderBefore(); 142 case ContentBox: 143 return m_renderer->borderAndPaddingBefore(); 144 } 145 } 146 return m_renderer->style()->boxSizing() == CONTENT_BOX ? m_renderer->borderAndPaddingBefore() : LayoutUnit(); 147 } 148 149 LayoutUnit logicalLeftOffset() const 150 { 151 if (shapeValue()->type() == ShapeValue::Box) { 152 switch (shapeValue()->layoutBox()) { 153 case MarginBox: 154 return -m_renderer->marginStart(); 155 case BorderBox: 156 return LayoutUnit(); 157 case PaddingBox: 158 return m_renderer->borderStart(); 159 case ContentBox: 160 return m_renderer->borderAndPaddingStart(); 161 } 162 } 163 return (m_renderer->style()->boxSizing() == CONTENT_BOX && !m_renderer->isRenderRegion()) ? m_renderer->borderAndPaddingStart() : LayoutUnit(); 164 } 165 166 LayoutUnit m_shapeLineTop; 167 LayoutUnit m_lineHeight; 168 169 const RenderType* m_renderer; 170 171 private: 172 mutable OwnPtr<Shape> m_shape; 173 LayoutSize m_shapeLogicalSize; 174 }; 175 176 bool checkShapeImageOrigin(Document&, ImageResource&); 177 178 } 179 #endif 180