示例#1
0
void RenderSVGRoot::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const
{
    // Spec: http://www.w3.org/TR/SVG/coords.html#IntrinsicSizing
    // SVG needs to specify how to calculate some intrinsic sizing properties to enable inclusion within other languages.
    // The intrinsic width and height of the viewport of SVG content must be determined from the ‘width’ and ‘height’ attributes.
    // If either of these are not specified, a value of '100%' must be assumed. Note: the ‘width’ and ‘height’ attributes are not
    // the same as the CSS width and height properties. Specifically, percentage values do not provide an intrinsic width or height,
    // and do not indicate a percentage of the containing block. Rather, once the viewport is established, they indicate the portion
    // of the viewport that is actually covered by image data.
    SVGSVGElement* svg = toSVGSVGElement(node());
    ASSERT(svg);
    Length intrinsicWidthAttribute = svg->intrinsicWidth(SVGSVGElement::IgnoreCSSProperties);
    Length intrinsicHeightAttribute = svg->intrinsicHeight(SVGSVGElement::IgnoreCSSProperties);

    // The intrinsic aspect ratio of the viewport of SVG content is necessary for example, when including SVG from an ‘object’
    // element in HTML styled with CSS. It is possible (indeed, common) for an SVG graphic to have an intrinsic aspect ratio but
    // not to have an intrinsic width or height. The intrinsic aspect ratio must be calculated based upon the following rules:
    // - The aspect ratio is calculated by dividing a width by a height.
    // - If the ‘width’ and ‘height’ of the rootmost ‘svg’ element are both specified with unit identifiers (in, mm, cm, pt, pc,
    //   px, em, ex) or in user units, then the aspect ratio is calculated from the ‘width’ and ‘height’ attributes after
    //   resolving both values to user units.
    if (intrinsicWidthAttribute.isFixed() || intrinsicHeightAttribute.isFixed()) {
        if (intrinsicWidthAttribute.isFixed())
            intrinsicSize.setWidth(floatValueForLength(intrinsicWidthAttribute, 0));
        if (intrinsicHeightAttribute.isFixed())
            intrinsicSize.setHeight(floatValueForLength(intrinsicHeightAttribute, 0));
        if (!intrinsicSize.isEmpty())
            intrinsicRatio = intrinsicSize.width() / static_cast<double>(intrinsicSize.height());
        return;
    }

    // - If either/both of the ‘width’ and ‘height’ of the rootmost ‘svg’ element are in percentage units (or omitted), the
    //   aspect ratio is calculated from the width and height values of the ‘viewBox’ specified for the current SVG document
    //   fragment. If the ‘viewBox’ is not correctly specified, or set to 'none', the intrinsic aspect ratio cannot be
    //   calculated and is considered unspecified.
    intrinsicSize = svg->viewBox().size();
    if (!intrinsicSize.isEmpty()) {
        // The viewBox can only yield an intrinsic ratio, not an intrinsic size.
        intrinsicRatio = intrinsicSize.width() / static_cast<double>(intrinsicSize.height());
        intrinsicSize = FloatSize();
        return;
    }

    // If our intrinsic size is in percentage units, return those to the caller through the intrinsicSize. Notify the caller
    // about the special situation, by setting isPercentageIntrinsicSize=true, so it knows how to interpret the return values.
    if (intrinsicWidthAttribute.isPercent() && intrinsicHeightAttribute.isPercent()) {
        isPercentageIntrinsicSize = true;
        intrinsicSize = FloatSize(intrinsicWidthAttribute.percent(), intrinsicHeightAttribute.percent());
    }
}
示例#2
0
void BasicShapeCircle::path(Path& path, const FloatRect& boundingBox)
{
    ASSERT(path.isEmpty());
    float diagonal = sqrtf((boundingBox.width() * boundingBox.width() + boundingBox.height() * boundingBox.height()) / 2);
    float centerX = floatValueForLength(m_centerX, boundingBox.width());
    float centerY = floatValueForLength(m_centerY, boundingBox.height());
    float radius = floatValueForLength(m_radius, diagonal);
    path.addEllipse(FloatRect(
        centerX - radius + boundingBox.x(),
        centerY - radius + boundingBox.y(),
        radius * 2,
        radius * 2
    ));
}
示例#3
0
void BasicShapeEllipse::path(Path& path, const FloatRect& boundingBox)
{
    ASSERT(path.isEmpty());
    float centerX = floatValueForLength(m_centerX, boundingBox.width());
    float centerY = floatValueForLength(m_centerY, boundingBox.height());
    float radiusX = floatValueForLength(m_radiusX, boundingBox.width());
    float radiusY = floatValueForLength(m_radiusY, boundingBox.height());
    path.addEllipse(FloatRect(
        centerX - radiusX + boundingBox.x(),
        centerY - radiusY + boundingBox.y(),
        radiusX * 2,
        radiusY * 2
    ));
}
示例#4
0
文件: Shape.cpp 项目: Igalia/blink
PassOwnPtr<Shape> Shape::createLayoutBoxShape(const LayoutSize& logicalSize, WritingMode writingMode, const Length& margin, const Length& padding)
{
    FloatRect rect(0, 0, logicalSize.width(), logicalSize.height());
    FloatSize radii(0, 0);
    FloatRoundedRect bounds(rect, radii, radii, radii, radii);
    float shapeMargin = floatValueForLength(margin, 0);
    float shapePadding = floatValueForLength(padding, 0);

    OwnPtr<Shape> shape = createBoxShape(bounds, shapeMargin, shapePadding);
    shape->m_writingMode = writingMode;
    shape->m_margin = shapeMargin;
    shape->m_padding = shapePadding;

    return shape.release();
}
示例#5
0
FloatSize SVGSVGElement::currentViewportSize() const
{
    if (hasIntrinsicWidth() && hasIntrinsicHeight())
        return FloatSize(floatValueForLength(intrinsicWidth(), 0), floatValueForLength(intrinsicHeight(), 0));

    if (!renderer())
        return { };

    if (is<RenderSVGRoot>(*renderer())) {
        auto& root = downcast<RenderSVGRoot>(*renderer());
        return root.contentBoxRect().size() / root.style().effectiveZoom();
    }

    return downcast<RenderSVGViewportContainer>(*renderer()).viewport().size();
}
示例#6
0
const Path& BasicShapeInset::path(const FloatRect& boundingBox)
{
    float left = floatValueForLength(m_left, boundingBox.width());
    float top = floatValueForLength(m_top, boundingBox.height());
    auto rect = FloatRect(left + boundingBox.x(), top + boundingBox.y(),
        std::max<float>(boundingBox.width() - left - floatValueForLength(m_right, boundingBox.width()), 0),
        std::max<float>(boundingBox.height() - top - floatValueForLength(m_bottom, boundingBox.height()), 0));
    auto radii = FloatRoundedRect::Radii(floatSizeForLengthSize(m_topLeftRadius, boundingBox),
        floatSizeForLengthSize(m_topRightRadius, boundingBox),
        floatSizeForLengthSize(m_bottomLeftRadius, boundingBox),
        floatSizeForLengthSize(m_bottomRightRadius, boundingBox));
    radii.scale(calcBorderRadiiConstraintScaleFor(rect, radii));

    return cachedRoundedRectPath(FloatRoundedRect(rect, radii));
}
示例#7
0
void SVGImage::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio)
{
    SVGSVGElement* rootElement = this->rootElement();
    if (!rootElement)
        return;

    intrinsicWidth = rootElement->intrinsicWidth();
    intrinsicHeight = rootElement->intrinsicHeight();
    if (rootElement->preserveAspectRatio().align() == SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE)
        return;

    intrinsicRatio = rootElement->viewBox().size();
    if (intrinsicRatio.isEmpty() && intrinsicWidth.isFixed() && intrinsicHeight.isFixed())
        intrinsicRatio = FloatSize(floatValueForLength(intrinsicWidth, 0), floatValueForLength(intrinsicHeight, 0));
}
float TextAutosizer::widthFromBlock(const LayoutBlock* block) const
{
    RELEASE_ASSERT(block);
    RELEASE_ASSERT(block->style());

    if (!(block->isTable() || block->isTableCell() || block->isListItem()))
        return block->contentLogicalWidth().toFloat();

    if (!block->containingBlock())
        return 0;

    // Tables may be inflated before computing their preferred widths. Try several methods to
    // obtain a width, and fall back on a containing block's width.
    for (; block; block = block->containingBlock()) {
        float width;
        Length specifiedWidth = block->isTableCell()
            ? toLayoutTableCell(block)->styleOrColLogicalWidth() : block->style()->logicalWidth();
        if (specifiedWidth.isFixed()) {
            if ((width = specifiedWidth.value()) > 0)
                return width;
        }
        if (specifiedWidth.hasPercent()) {
            if (float containerWidth = block->containingBlock()->contentLogicalWidth().toFloat()) {
                if ((width = floatValueForLength(specifiedWidth, containerWidth)) > 0)
                    return width;
            }
        }
        if ((width = block->contentLogicalWidth().toFloat()) > 0)
            return width;
    }
    return 0;
}
示例#9
0
const Shape& ShapeOutsideInfo::computedShape() const
{
    if (Shape* shape = m_shape.get())
        return *shape;

    const RenderStyle& style = m_renderer.style();
    ASSERT(m_renderer.containingBlock());
    const RenderStyle& containingBlockStyle = m_renderer.containingBlock()->style();

    WritingMode writingMode = containingBlockStyle.writingMode();
    float margin = floatValueForLength(m_renderer.style().shapeMargin(), m_renderer.containingBlock() ? m_renderer.containingBlock()->contentWidth() : LayoutUnit());
    float shapeImageThreshold = style.shapeImageThreshold();
    const ShapeValue& shapeValue = *style.shapeOutside();

    switch (shapeValue.type()) {
    case ShapeValue::Type::Shape:
        ASSERT(shapeValue.shape());
        m_shape = Shape::createShape(shapeValue.shape(), m_referenceBoxLogicalSize, writingMode, margin);
        break;
    case ShapeValue::Type::Image:
        ASSERT(shapeValue.isImageValid());
        m_shape = createShapeForImage(shapeValue.image(), shapeImageThreshold, writingMode, margin);
        break;
    case ShapeValue::Type::Box: {
        RoundedRect shapeRect = computeRoundedRectForBoxShape(referenceBox(shapeValue), m_renderer);
        if (!containingBlockStyle.isHorizontalWritingMode())
            shapeRect = shapeRect.transposedRect();
        m_shape = Shape::createBoxShape(shapeRect, writingMode, margin);
        break;
    }
    }

    ASSERT(m_shape);
    return *m_shape;
}
示例#10
0
FilterOutsets FilterOperations::outsets() const
{
    FilterOutsets totalOutsets;
    for (size_t i = 0; i < m_operations.size(); ++i) {
        FilterOperation* filterOperation = m_operations.at(i).get();
        switch (filterOperation->type()) {
        case FilterOperation::BLUR: {
            BlurFilterOperation* blurOperation = toBlurFilterOperation(filterOperation);
            float stdDeviation = floatValueForLength(blurOperation->stdDeviation(), 0);
            IntSize outsetSize = outsetSizeForBlur(stdDeviation);
            FilterOutsets outsets(outsetSize.height(), outsetSize.width(), outsetSize.height(), outsetSize.width());
            totalOutsets += outsets;
            break;
        }
        case FilterOperation::DROP_SHADOW: {
            DropShadowFilterOperation* dropShadowOperation = toDropShadowFilterOperation(filterOperation);
            IntSize outsetSize = outsetSizeForBlur(dropShadowOperation->stdDeviation());
            FilterOutsets outsets(
                std::max(0, outsetSize.height() - dropShadowOperation->y()),
                std::max(0, outsetSize.width() + dropShadowOperation->x()),
                std::max(0, outsetSize.height() + dropShadowOperation->y()),
                std::max(0, outsetSize.width() - dropShadowOperation->x())
            );
            totalOutsets += outsets;
            break;
        }
        default:
            break;
        }
    }
    return totalOutsets;
}
示例#11
0
float floatValueForCenterCoordinate(const BasicShapeCenterCoordinate& center, float boxDimension)
{
    float offset = floatValueForLength(center.length(), boxDimension);
    if (center.direction() == BasicShapeCenterCoordinate::TopLeft)
        return offset;
    return boxDimension - offset;
}
示例#12
0
void BasicShapeInset::path(Path& path, const FloatRect& boundingBox)
{
    ASSERT(path.isEmpty());
    float left = floatValueForLength(m_left, boundingBox.width());
    float top = floatValueForLength(m_top, boundingBox.height());
    FloatRect rect(left + boundingBox.x(), top + boundingBox.y(),
        std::max<float>(boundingBox.width() - left - floatValueForLength(m_right, boundingBox.width()), 0),
        std::max<float>(boundingBox.height() - top - floatValueForLength(m_bottom, boundingBox.height()), 0));
    auto radii = FloatRoundedRect::Radii(floatSizeForLengthSize(m_topLeftRadius, boundingBox),
        floatSizeForLengthSize(m_topRightRadius, boundingBox),
        floatSizeForLengthSize(m_bottomLeftRadius, boundingBox),
        floatSizeForLengthSize(m_bottomRightRadius, boundingBox));

    FloatRoundedRect finalRect(rect, radii);
    finalRect.constrainRadii();
    path.addRoundedRect(finalRect);
}
示例#13
0
void BasicShapePolygon::path(Path& path, const FloatRect& boundingBox)
{
    ASSERT(path.isEmpty());
    ASSERT(!(m_values.size() % 2));
    size_t length = m_values.size();
    
    if (!length)
        return;

    path.moveTo(FloatPoint(floatValueForLength(m_values.at(0), boundingBox.width()) + boundingBox.x(),
        floatValueForLength(m_values.at(1), boundingBox.height()) + boundingBox.y()));
    for (size_t i = 2; i < length; i = i + 2) {
        path.addLineTo(FloatPoint(floatValueForLength(m_values.at(i), boundingBox.width()) + boundingBox.x(),
            floatValueForLength(m_values.at(i + 1), boundingBox.height()) + boundingBox.y()));
    }
    path.closeSubpath();
}
bool AnimationBase::computeTransformedExtentViaTransformList(const FloatRect& rendererBox, const RenderStyle& style, LayoutRect& bounds) const
{
    FloatRect floatBounds = bounds;
    FloatPoint transformOrigin;
    
    bool applyTransformOrigin = containsRotation(style.transform().operations()) || style.transform().affectedByTransformOrigin();
    if (applyTransformOrigin) {
        float offsetX = style.transformOriginX().isPercent() ? rendererBox.x() : 0;
        float offsetY = style.transformOriginY().isPercent() ? rendererBox.y() : 0;

        transformOrigin.setX(floatValueForLength(style.transformOriginX(), rendererBox.width()) + offsetX);
        transformOrigin.setY(floatValueForLength(style.transformOriginY(), rendererBox.height()) + offsetY);
        // Ignore transformOriginZ because we'll bail if we encounter any 3D transforms.
        
        floatBounds.moveBy(-transformOrigin);
    }

    for (const auto& operation : style.transform().operations()) {
        if (operation->type() == TransformOperation::ROTATE) {
            // For now, just treat this as a full rotation. This could take angle into account to reduce inflation.
            floatBounds = boundsOfRotatingRect(floatBounds);
        } else {
            TransformationMatrix transform;
            operation->apply(transform, rendererBox.size());
            if (!transform.isAffine())
                return false;

            if (operation->type() == TransformOperation::MATRIX || operation->type() == TransformOperation::MATRIX_3D) {
                TransformationMatrix::Decomposed2Type toDecomp;
                transform.decompose2(toDecomp);
                // Any rotation prevents us from using a simple start/end rect union.
                if (toDecomp.angle)
                    return false;
            }

            floatBounds = transform.mapRect(floatBounds);
        }
    }

    if (applyTransformOrigin)
        floatBounds.moveBy(transformOrigin);

    bounds = LayoutRect(floatBounds);
    return true;
}
示例#15
0
FloatSize SVGSVGElement::currentViewportSize() const
{
    Length intrinsicWidth = this->intrinsicWidth();
    Length intrinsicHeight = this->intrinsicHeight();
    if (intrinsicWidth.isFixed() && intrinsicHeight.isFixed())
        return FloatSize(floatValueForLength(intrinsicWidth, 0), floatValueForLength(intrinsicHeight, 0));

    if (!renderer())
        return FloatSize();

    if (renderer()->isSVGRoot()) {
        LayoutRect contentBoxRect = toRenderSVGRoot(renderer())->contentBoxRect();
        return FloatSize(contentBoxRect.width() / renderer()->style()->effectiveZoom(), contentBoxRect.height() / renderer()->style()->effectiveZoom());
    }

    FloatRect viewportRect = toRenderSVGViewportContainer(renderer())->viewport();
    return FloatSize(viewportRect.width() / renderer()->style()->effectiveZoom(), viewportRect.height() / renderer()->style()->effectiveZoom());
}
float SVGLengthContext::valueForLength(const Length& length, float zoom, float dimension)
{
    ASSERT(zoom != 0);
    // isIntrinsic can occur for 'width' and 'height', but has no
    // real meaning for svg.
    if (length.isIntrinsic())
        return 0;
    return floatValueForLength(length, dimension * zoom) / zoom;
}
示例#17
0
void SVGImage::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio)
{
    if (!m_page)
        return;
    Frame* frame = m_page->mainFrame();
    SVGSVGElement* rootElement = static_cast<SVGDocument*>(frame->document())->rootElement();
    if (!rootElement)
        return;

    intrinsicWidth = rootElement->intrinsicWidth();
    intrinsicHeight = rootElement->intrinsicHeight();
    if (rootElement->preserveAspectRatio().align() == SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE)
        return;

    intrinsicRatio = rootElement->viewBox().size();
    if (intrinsicRatio.isEmpty() && intrinsicWidth.isFixed() && intrinsicHeight.isFixed())
        intrinsicRatio = FloatSize(floatValueForLength(intrinsicWidth, 0), floatValueForLength(intrinsicHeight, 0));
}
示例#18
0
FloatSize SVGSVGElement::currentViewportSize() const
{
    if (hasIntrinsicWidth() && hasIntrinsicHeight()) {
        Length intrinsicWidth = this->intrinsicWidth();
        Length intrinsicHeight = this->intrinsicHeight();
        return FloatSize(floatValueForLength(intrinsicWidth, 0), floatValueForLength(intrinsicHeight, 0));
    }

    if (!renderer())
        return FloatSize();

    if (is<RenderSVGRoot>(*renderer())) {
        LayoutRect contentBoxRect = downcast<RenderSVGRoot>(*renderer()).contentBoxRect();
        return FloatSize(contentBoxRect.width() / renderer()->style().effectiveZoom(), contentBoxRect.height() / renderer()->style().effectiveZoom());
    }

    FloatRect viewportRect = downcast<RenderSVGViewportContainer>(*renderer()).viewport();
    return FloatSize(viewportRect.width(), viewportRect.height());
}
示例#19
0
文件: Shape.cpp 项目: MYSHLIFE/webkit
PassOwnPtr<Shape> Shape::createRasterShape(Image* image, float threshold, const LayoutRect& imageR, const LayoutRect& marginR, WritingMode writingMode, Length margin, Length padding)
{
    IntRect imageRect = pixelSnappedIntRect(imageR);
    IntRect marginRect = pixelSnappedIntRect(marginR);
    OwnPtr<RasterShapeIntervals> intervals = adoptPtr(new RasterShapeIntervals(marginRect.height(), -marginRect.y()));
    std::unique_ptr<ImageBuffer> imageBuffer = ImageBuffer::create(imageRect.size());

    if (imageBuffer) {
        GraphicsContext* graphicsContext = imageBuffer->context();
        graphicsContext->drawImage(image, ColorSpaceDeviceRGB, IntRect(IntPoint(), imageRect.size()));

        RefPtr<Uint8ClampedArray> pixelArray = imageBuffer->getUnmultipliedImageData(IntRect(IntPoint(), imageRect.size()));
        unsigned pixelArrayLength = pixelArray->length();
        unsigned pixelArrayOffset = 3; // Each pixel is four bytes: RGBA.
        uint8_t alphaPixelThreshold = threshold * 255;

        int minBufferY = std::max(0, marginRect.y() - imageRect.y());
        int maxBufferY = std::min(imageRect.height(), marginRect.maxY() - imageRect.y());

        if (static_cast<unsigned>(imageRect.width() * imageRect.height() * 4) == pixelArrayLength) { // sanity check
            for (int y = minBufferY; y < maxBufferY; ++y) {
                int startX = -1;
                for (int x = 0; x < imageRect.width(); ++x, pixelArrayOffset += 4) {
                    uint8_t alpha = pixelArray->item(pixelArrayOffset);
                    bool alphaAboveThreshold = alpha > alphaPixelThreshold;
                    if (startX == -1 && alphaAboveThreshold) {
                        startX = x;
                    } else if (startX != -1 && (!alphaAboveThreshold || x == imageRect.width() - 1)) {
                        intervals->appendInterval(y + imageRect.y(), startX + imageRect.x(), x + imageRect.x());
                        startX = -1;
                    }
                }
            }
        }
    }

    OwnPtr<RasterShape> rasterShape = adoptPtr(new RasterShape(intervals.release(), marginRect.size()));
    rasterShape->m_writingMode = writingMode;
    rasterShape->m_margin = floatValueForLength(margin, 0);
    rasterShape->m_padding = floatValueForLength(padding, 0);
    return rasterShape.release();
}
示例#20
0
PassOwnPtr<Shape> Shape::createShape(const StyleImage* styleImage, float threshold, const LayoutSize&, WritingMode writingMode, Length margin, Length padding)
{
    ASSERT(styleImage && styleImage->isCachedImage() && styleImage->cachedImage() && styleImage->cachedImage()->image());

    Image* image = styleImage->cachedImage()->image();
    const IntSize& imageSize = image->size();

    OwnPtr<RasterShapeIntervals> intervals = adoptPtr(new RasterShapeIntervals(imageSize.height()));

    OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(imageSize);
    if (imageBuffer) {
        GraphicsContext* graphicsContext = imageBuffer->context();
        graphicsContext->drawImage(image, ColorSpaceDeviceRGB, IntPoint());

        RefPtr<Uint8ClampedArray> pixelArray = imageBuffer->getUnmultipliedImageData(IntRect(IntPoint(), imageSize));
        unsigned pixelArrayLength = pixelArray->length();
        unsigned pixelArrayOffset = 3; // Each pixel is four bytes: RGBA.
        uint8_t alphaPixelThreshold = threshold * 255;

        if (static_cast<unsigned>(imageSize.width() * imageSize.height() * 4) == pixelArrayLength) { // sanity check
            for (int y = 0; y < imageSize.height(); ++y) {
                int startX = -1;
                for (int x = 0; x < imageSize.width(); ++x, pixelArrayOffset += 4) {
                    uint8_t alpha = pixelArray->item(pixelArrayOffset);
                    bool alphaAboveThreshold = alpha > alphaPixelThreshold;
                    if (startX == -1 && alphaAboveThreshold) {
                        startX = x;
                    } else if (startX != -1 && (!alphaAboveThreshold || x == imageSize.width() - 1)) {
                        intervals->appendInterval(y, startX, x);
                        startX = -1;
                    }
                }
            }
        }
    }

    OwnPtr<RasterShape> rasterShape = adoptPtr(new RasterShape(intervals.release()));
    rasterShape->m_writingMode = writingMode;
    rasterShape->m_margin = floatValueForLength(margin, 0);
    rasterShape->m_padding = floatValueForLength(padding, 0);
    return rasterShape.release();
}
示例#21
0
float SVGLengthContext::valueForLength(const Length& length, SVGLengthMode mode)
{
    if (length.isPercent())
        return convertValueFromPercentageToUserUnits(length.value() / 100, mode, IGNORE_EXCEPTION);
    if (length.isAuto() || !length.isSpecified())
        return 0;

    FloatSize viewportSize;
    determineViewport(viewportSize);

    switch (mode) {
    case LengthModeWidth:
        return floatValueForLength(length, viewportSize.width());
    case LengthModeHeight:
        return floatValueForLength(length, viewportSize.height());
    case LengthModeOther:
        return floatValueForLength(length, sqrtf(viewportSize.diagonalLengthSquared() / 2));
    };
    return 0;
}
示例#22
0
float BasicShapeEllipse::floatValueForRadiusInBox(const BasicShapeRadius& radius, float center, float boxWidthOrHeight) const
{
    if (radius.type() == BasicShapeRadius::Value)
        return floatValueForLength(radius.value(), boxWidthOrHeight);

    if (radius.type() == BasicShapeRadius::ClosestSide)
        return std::min(center, boxWidthOrHeight - center);

    ASSERT(radius.type() == BasicShapeRadius::FarthestSide);
    return std::max(center, boxWidthOrHeight - center);
}
示例#23
0
FloatRect SVGSVGElement::currentViewBoxRect() const
{
    if (m_useCurrentView)
        return m_viewSpec ? m_viewSpec->viewBox() : FloatRect();

    FloatRect useViewBox = viewBox();
    if (!useViewBox.isEmpty())
        return useViewBox;
    if (!renderer() || !renderer()->isSVGRoot())
        return FloatRect();
    if (!toRenderSVGRoot(renderer())->isEmbeddedThroughSVGImage())
        return FloatRect();

    Length intrinsicWidth = this->intrinsicWidth();
    Length intrinsicHeight = this->intrinsicHeight();
    if (!intrinsicWidth.isFixed() || !intrinsicHeight.isFixed())
        return FloatRect();

    // If no viewBox is specified but non-relative width/height values, then we
    // should always synthesize a viewBox if we're embedded through a SVGImage.    
    return FloatRect(FloatPoint(), FloatSize(floatValueForLength(intrinsicWidth, 0), floatValueForLength(intrinsicHeight, 0)));
}
示例#24
0
const Shape& ShapeOutsideInfo::computedShape() const {
  if (Shape* shape = m_shape.get())
    return *shape;

  AutoReset<bool> isInComputingShape(&m_isComputingShape, true);

  const ComputedStyle& style = *m_layoutBox.style();
  ASSERT(m_layoutBox.containingBlock());
  const ComputedStyle& containingBlockStyle =
      *m_layoutBox.containingBlock()->style();

  WritingMode writingMode = containingBlockStyle.getWritingMode();
  // Make sure contentWidth is not negative. This can happen when containing
  // block has a vertical scrollbar and its content is smaller than the
  // scrollbar width.
  LayoutUnit maximumValue =
      m_layoutBox.containingBlock()
          ? std::max(LayoutUnit(),
                     m_layoutBox.containingBlock()->contentWidth())
          : LayoutUnit();
  float margin = floatValueForLength(m_layoutBox.style()->shapeMargin(),
                                     maximumValue.toFloat());

  float shapeImageThreshold = style.shapeImageThreshold();
  ASSERT(style.shapeOutside());
  const ShapeValue& shapeValue = *style.shapeOutside();

  switch (shapeValue.type()) {
    case ShapeValue::Shape:
      ASSERT(shapeValue.shape());
      m_shape = Shape::createShape(
          shapeValue.shape(), m_referenceBoxLogicalSize, writingMode, margin);
      break;
    case ShapeValue::Image:
      ASSERT(shapeValue.isImageValid());
      m_shape = createShapeForImage(shapeValue.image(), shapeImageThreshold,
                                    writingMode, margin);
      break;
    case ShapeValue::Box: {
      const FloatRoundedRect& shapeRect = style.getRoundedBorderFor(
          LayoutRect(LayoutPoint(), m_referenceBoxLogicalSize),
          m_layoutBox.view());
      m_shape = Shape::createLayoutBoxShape(shapeRect, writingMode, margin);
      break;
    }
  }

  ASSERT(m_shape);
  return *m_shape;
}
示例#25
0
float BasicShapeCircle::floatValueForRadiusInBox(float boxWidth, float boxHeight) const
{
    if (m_radius.type() == BasicShapeRadius::Value)
        return floatValueForLength(m_radius.value(), sqrtf((boxWidth * boxWidth + boxHeight * boxHeight) / 2));

    float centerX = floatValueForCenterCoordinate(m_centerX, boxWidth);
    float centerY = floatValueForCenterCoordinate(m_centerY, boxHeight);

    if (m_radius.type() == BasicShapeRadius::ClosestSide)
        return std::min(std::min(centerX, boxWidth - centerX), std::min(centerY, boxHeight - centerY));

    // If radius.type() == BasicShapeRadius::FarthestSide.
    return std::max(std::max(centerX, boxWidth - centerX), std::max(centerY, boxHeight - centerY));
}
示例#26
0
FloatRect SVGSVGElement::currentViewBoxRect() const
{
    if (m_useCurrentView)
        return m_viewSpec ? m_viewSpec->viewBox() : FloatRect();

    FloatRect viewBox = this->viewBox();
    if (!viewBox.isEmpty())
        return viewBox;

    if (!is<RenderSVGRoot>(renderer()))
        return { };
    if (!downcast<RenderSVGRoot>(*renderer()).isEmbeddedThroughSVGImage())
        return { };

    Length intrinsicWidth = this->intrinsicWidth();
    Length intrinsicHeight = this->intrinsicHeight();
    if (!intrinsicWidth.isFixed() || !intrinsicHeight.isFixed())
        return { };

    // If no viewBox is specified but non-relative width/height values, then we
    // should always synthesize a viewBox if we're embedded through a SVGImage.    
    return { 0, 0, floatValueForLength(intrinsicWidth, 0), floatValueForLength(intrinsicHeight, 0) };
}
示例#27
0
void RenderStyle::applyTransform(TransformationMatrix& transform, const FloatRect& boundingBox, ApplyTransformOrigin applyOrigin) const
{
    const Vector<RefPtr<TransformOperation> >& transformOperations = rareNonInheritedData->m_transform->m_operations.operations();
    bool applyTransformOrigin = requireTransformOrigin(transformOperations, applyOrigin);

    float offsetX = transformOriginX().type() == Percent ? boundingBox.x() : 0;
    float offsetY = transformOriginY().type() == Percent ? boundingBox.y() : 0;

    if (applyTransformOrigin) {
        transform.translate3d(floatValueForLength(transformOriginX(), boundingBox.width()) + offsetX,
            floatValueForLength(transformOriginY(), boundingBox.height()) + offsetY,
            transformOriginZ());
    }

    unsigned size = transformOperations.size();
    for (unsigned i = 0; i < size; ++i)
        transformOperations[i]->apply(transform, boundingBox.size());

    if (applyTransformOrigin) {
        transform.translate3d(-floatValueForLength(transformOriginX(), boundingBox.width()) - offsetX,
            -floatValueForLength(transformOriginY(), boundingBox.height()) - offsetY,
            -transformOriginZ());
    }
}
示例#28
0
float BasicShapeCircle::floatValueForRadiusInBox(FloatSize boxSize) const
{
    if (m_radius.type() == BasicShapeRadius::Value)
        return floatValueForLength(m_radius.value(), hypotf(boxSize.width(), boxSize.height()) / sqrtf(2));

    FloatPoint center = floatPointForCenterCoordinate(m_centerX, m_centerY, boxSize);

    float widthDelta = std::abs(boxSize.width() - center.x());
    float heightDelta = std::abs(boxSize.height() - center.y());
    if (m_radius.type() == BasicShapeRadius::ClosestSide)
        return std::min(std::min(std::abs(center.x()), widthDelta), std::min(std::abs(center.y()), heightDelta));

    // If radius.type() == BasicShapeRadius::FarthestSide.
    return std::max(std::max(center.x(), widthDelta), std::max(center.y(), heightDelta));
}
示例#29
0
float SVGLengthContext::valueForLength(const Length& length, SVGLengthMode mode)
{
    if (length.isPercent()) {
        auto result = convertValueFromPercentageToUserUnits(length.value() / 100, mode);
        if (result.hasException())
            return 0;
        return result.releaseReturnValue();
    }
    if (length.isAuto() || !length.isSpecified())
        return 0;

    FloatSize viewportSize;
    determineViewport(viewportSize);

    switch (mode) {
    case LengthModeWidth:
        return floatValueForLength(length, viewportSize.width());
    case LengthModeHeight:
        return floatValueForLength(length, viewportSize.height());
    case LengthModeOther:
        return floatValueForLength(length, std::sqrt(viewportSize.diagonalLengthSquared() / 2));
    };
    return 0;
}
示例#30
0
FilterOutsets FilterOperations::outsets() const
{
    FilterOutsets totalOutsets;
    for (size_t i = 0; i < m_operations.size(); ++i) {
        FilterOperation* filterOperation = m_operations.at(i).get();
        switch (filterOperation->type()) {
        case FilterOperation::BLUR: {
            BlurFilterOperation* blurOperation = toBlurFilterOperation(filterOperation);
            float stdDeviation = floatValueForLength(blurOperation->stdDeviation(), 0);
            IntSize outsetSize = outsetSizeForBlur(stdDeviation);
            FilterOutsets outsets(outsetSize.height(), outsetSize.width(), outsetSize.height(), outsetSize.width());
            totalOutsets += outsets;
            break;
        }
        case FilterOperation::DROP_SHADOW: {
            DropShadowFilterOperation* dropShadowOperation = toDropShadowFilterOperation(filterOperation);
            IntSize outsetSize = outsetSizeForBlur(dropShadowOperation->stdDeviation());
            FilterOutsets outsets(
                std::max(0, outsetSize.height() - dropShadowOperation->y()),
                std::max(0, outsetSize.width() + dropShadowOperation->x()),
                std::max(0, outsetSize.height() + dropShadowOperation->y()),
                std::max(0, outsetSize.width() - dropShadowOperation->x())
            );
            totalOutsets += outsets;
            break;
        }
        case FilterOperation::REFERENCE: {
            ReferenceFilterOperation* referenceOperation = toReferenceFilterOperation(filterOperation);
            if (referenceOperation->filter() && referenceOperation->filter()->lastEffect()) {
                FloatRect outsetRect(0, 0, 1, 1);
                outsetRect = referenceOperation->filter()->lastEffect()->mapRectRecursive(outsetRect);
                FilterOutsets outsets(
                    std::max(0.0f, -outsetRect.y()),
                    std::max(0.0f, outsetRect.x() + outsetRect.width() - 1),
                    std::max(0.0f, outsetRect.y() + outsetRect.height() - 1),
                    std::max(0.0f, -outsetRect.x())
                );
                totalOutsets += outsets;
            }
            break;
        }
        default:
            break;
        }
    }
    return totalOutsets;
}