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#if ENABLE(CSS_SHAPES) 34 35#include "FloatRect.h" 36#include "LayoutUnit.h" 37#include "RenderStyle.h" 38#include "Shape.h" 39#include "ShapeValue.h" 40#include <wtf/OwnPtr.h> 41#include <wtf/Vector.h> 42 43namespace WebCore { 44 45template<class KeyType, class InfoType> 46class MappedInfo { 47public: 48 static InfoType* ensureInfo(const KeyType* key) 49 { 50 InfoMap& infoMap = MappedInfo<KeyType, InfoType>::infoMap(); 51 if (InfoType* info = infoMap.get(key)) 52 return info; 53 typename InfoMap::AddResult result = infoMap.add(key, InfoType::createInfo(key)); 54 return result.iterator->value.get(); 55 } 56 static void removeInfo(const KeyType* key) { infoMap().remove(key); } 57 static InfoType* info(const KeyType* key) { return infoMap().get(key); } 58private: 59 typedef HashMap<const KeyType*, OwnPtr<InfoType> > InfoMap; 60 static InfoMap& infoMap() 61 { 62 DEFINE_STATIC_LOCAL(InfoMap, staticInfoMap, ()); 63 return staticInfoMap; 64 } 65}; 66 67template<class RenderType, ShapeValue* (RenderStyle::*shapeGetter)() const, void (Shape::*intervalGetter)(LayoutUnit, LayoutUnit, SegmentList&) const> 68class ShapeInfo { 69 WTF_MAKE_FAST_ALLOCATED; 70public: 71 virtual ~ShapeInfo() { } 72 73 void setShapeSize(LayoutUnit logicalWidth, LayoutUnit logicalHeight) 74 { 75 if (m_renderer->style()->boxSizing() == CONTENT_BOX) { 76 logicalWidth -= m_renderer->borderAndPaddingLogicalWidth(); 77 logicalHeight -= m_renderer->borderAndPaddingLogicalHeight(); 78 } 79 80 if (m_shapeLogicalWidth == logicalWidth && m_shapeLogicalHeight == logicalHeight) 81 return; 82 dirtyShapeSize(); 83 m_shapeLogicalWidth = logicalWidth; 84 m_shapeLogicalHeight = logicalHeight; 85 } 86 87 virtual bool computeSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineHeight); 88 void clearSegments() { m_segments.clear(); } 89 90 LayoutUnit shapeLogicalTop() const { return computedShapeLogicalBoundingBox().y() + logicalTopOffset(); } 91 LayoutUnit shapeLogicalBottom() const { return computedShapeLogicalBoundingBox().maxY() + logicalTopOffset(); } 92 LayoutUnit shapeLogicalLeft() const { return computedShapeLogicalBoundingBox().x() + logicalLeftOffset(); } 93 LayoutUnit shapeLogicalRight() const { return computedShapeLogicalBoundingBox().maxX() + logicalLeftOffset(); } 94 LayoutUnit shapeLogicalWidth() const { return computedShapeLogicalBoundingBox().width(); } 95 LayoutUnit shapeLogicalHeight() const { return computedShapeLogicalBoundingBox().height(); } 96 97 LayoutUnit logicalLineTop() const { return m_shapeLineTop + logicalTopOffset(); } 98 LayoutUnit logicalLineBottom() const { return m_shapeLineTop + m_lineHeight + logicalTopOffset(); } 99 100 LayoutUnit shapeContainingBlockHeight() const { return (m_renderer->style()->boxSizing() == CONTENT_BOX) ? (m_shapeLogicalHeight + m_renderer->borderAndPaddingLogicalHeight()) : m_shapeLogicalHeight; } 101 102 bool lineOverlapsShapeBounds() const { return logicalLineTop() < shapeLogicalBottom() && shapeLogicalTop() <= logicalLineBottom(); } 103 bool lineWithinShapeBounds() const { return lineOverlapsShapeBounds() && (logicalLineBottom() <= shapeLogicalBottom()); } 104 105 void dirtyShapeSize() { m_shape.clear(); } 106 bool shapeSizeDirty() { return !m_shape.get(); } 107 const RenderType* owner() const { return m_renderer; } 108 109protected: 110 ShapeInfo(const RenderType* renderer): m_renderer(renderer) { } 111 112 const Shape* computedShape() const; 113 virtual LayoutRect computedShapeLogicalBoundingBox() const = 0; 114 115 LayoutUnit logicalTopOffset() const { return m_renderer->style()->boxSizing() == CONTENT_BOX ? m_renderer->borderAndPaddingBefore() : LayoutUnit(); }; 116 LayoutUnit logicalLeftOffset() const { return (m_renderer->style()->boxSizing() == CONTENT_BOX && !m_renderer->isRenderRegion()) ? m_renderer->borderAndPaddingStart() : LayoutUnit(); } 117 118 LayoutUnit m_shapeLineTop; 119 LayoutUnit m_lineHeight; 120 SegmentList m_segments; 121 122private: 123 mutable OwnPtr<Shape> m_shape; 124 125 LayoutUnit m_shapeLogicalWidth; 126 LayoutUnit m_shapeLogicalHeight; 127 const RenderType* m_renderer; 128}; 129} 130#endif 131#endif 132