Home | History | Annotate | Download | only in shapes
      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 #include "config.h"
     31 #include "core/rendering/shapes/ShapeInsideInfo.h"
     32 
     33 #include "core/rendering/InlineIterator.h"
     34 #include "core/rendering/RenderBlock.h"
     35 
     36 namespace WebCore {
     37 
     38 LineSegmentRange::LineSegmentRange(const InlineIterator& start, const InlineIterator& end)
     39     : start(start.root(), start.object(), start.offset())
     40     , end(end.root(), end.object(), end.offset())
     41     {
     42     }
     43 
     44 bool ShapeInsideInfo::isEnabledFor(const RenderBlock* renderer)
     45 {
     46     ShapeValue* shapeValue = renderer->style()->resolvedShapeInside();
     47     if (!shapeValue)
     48         return false;
     49 
     50     switch (shapeValue->type()) {
     51     case ShapeValue::Shape:
     52         return shapeValue->shape() && shapeValue->shape()->type() != BasicShape::BasicShapeInsetRectangleType;
     53     case ShapeValue::Image:
     54         return shapeValue->isImageValid() && checkShapeImageOrigin(renderer->document(), *(shapeValue->image()->cachedImage()));
     55     case ShapeValue::Box:
     56     case ShapeValue::Outside:
     57         return false;
     58     }
     59 
     60     return false;
     61 }
     62 
     63 bool ShapeInsideInfo::updateSegmentsForLine(LayoutSize lineOffset, LayoutUnit lineHeight)
     64 {
     65     bool result = updateSegmentsForLine(lineOffset.height(), lineHeight);
     66     for (size_t i = 0; i < m_segments.size(); i++) {
     67         m_segments[i].logicalLeft -= lineOffset.width();
     68         m_segments[i].logicalRight -= lineOffset.width();
     69     }
     70     return result;
     71 }
     72 
     73 bool ShapeInsideInfo::updateSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineHeight)
     74 {
     75     ASSERT(lineHeight >= 0);
     76     m_shapeLineTop = lineTop - logicalTopOffset();
     77     m_lineHeight = lineHeight;
     78     m_segments.clear();
     79     m_segmentRanges.clear();
     80 
     81     if (lineOverlapsShapeBounds())
     82         m_segments = computeSegmentsForLine(lineTop, lineHeight);
     83 
     84     return m_segments.size();
     85 }
     86 
     87 bool ShapeInsideInfo::adjustLogicalLineTop(float minSegmentWidth)
     88 {
     89     const Shape* shape = computedShape();
     90     if (!shape || m_lineHeight <= 0 || logicalLineTop() > shapeLogicalBottom())
     91         return false;
     92 
     93     LayoutUnit newLineTop;
     94     if (shape->firstIncludedIntervalLogicalTop(m_shapeLineTop, LayoutSize(minSegmentWidth, m_lineHeight), newLineTop)) {
     95         if (newLineTop > m_shapeLineTop) {
     96             m_shapeLineTop = newLineTop;
     97             return true;
     98         }
     99     }
    100 
    101     return false;
    102 }
    103 
    104 ShapeValue* ShapeInsideInfo::shapeValue() const
    105 {
    106     return m_renderer->style()->resolvedShapeInside();
    107 }
    108 
    109 LayoutUnit ShapeInsideInfo::computeFirstFitPositionForFloat(const LayoutSize floatSize) const
    110 {
    111     if (!computedShape() || !floatSize.width() || shapeLogicalBottom() < logicalLineTop())
    112         return 0;
    113 
    114     LayoutUnit firstFitPosition = 0;
    115     if (computedShape()->firstIncludedIntervalLogicalTop(m_shapeLineTop, floatSize, firstFitPosition) && (m_shapeLineTop <= firstFitPosition))
    116         return firstFitPosition;
    117 
    118     return 0;
    119 }
    120 
    121 }
    122