void GraphicsContext::fillRectWithRoundedHole(const IntRect& rect, const FloatRoundedRect& roundedHoleRect, const Color& color, ColorSpace colorSpace) { if (paintingDisabled()) return; Path path; path.addRect(rect); if (!roundedHoleRect.radii().isZero()) path.addRoundedRect(roundedHoleRect); else path.addRect(roundedHoleRect.rect()); WindRule oldFillRule = fillRule(); Color oldFillColor = fillColor(); ColorSpace oldFillColorSpace = fillColorSpace(); setFillRule(RULE_EVENODD); setFillColor(color, colorSpace); fillPath(path); setFillRule(oldFillRule); setFillColor(oldFillColor, oldFillColorSpace); }
void RenderThemeSafari::paintMenuListButtonGradients(const RenderObject& o, const PaintInfo& paintInfo, const IntRect& r) { if (r.isEmpty()) return; CGContextRef context = paintInfo.context->platformContext(); paintInfo.context->save(); FloatRoundedRect bound = FloatRoundedRect(o.style().getRoundedBorderFor(r)); int radius = bound.radii().topLeft().width(); CGColorSpaceRef cspace = deviceRGBColorSpaceRef(); FloatRect topGradient(r.x(), r.y(), r.width(), r.height() / 2.0f); struct CGFunctionCallbacks topCallbacks = { 0, TopGradientInterpolate, NULL }; RetainPtr<CGFunctionRef> topFunction = adoptCF(CGFunctionCreate(NULL, 1, NULL, 4, NULL, &topCallbacks)); RetainPtr<CGShadingRef> topShading = adoptCF(CGShadingCreateAxial(cspace, CGPointMake(topGradient.x(), topGradient.y()), CGPointMake(topGradient.x(), topGradient.maxY()), topFunction.get(), false, false)); FloatRect bottomGradient(r.x() + radius, r.y() + r.height() / 2.0f, r.width() - 2.0f * radius, r.height() / 2.0f); struct CGFunctionCallbacks bottomCallbacks = { 0, BottomGradientInterpolate, NULL }; RetainPtr<CGFunctionRef> bottomFunction = adoptCF(CGFunctionCreate(NULL, 1, NULL, 4, NULL, &bottomCallbacks)); RetainPtr<CGShadingRef> bottomShading = adoptCF(CGShadingCreateAxial(cspace, CGPointMake(bottomGradient.x(), bottomGradient.y()), CGPointMake(bottomGradient.x(), bottomGradient.maxY()), bottomFunction.get(), false, false)); struct CGFunctionCallbacks mainCallbacks = { 0, MainGradientInterpolate, NULL }; RetainPtr<CGFunctionRef> mainFunction = adoptCF(CGFunctionCreate(NULL, 1, NULL, 4, NULL, &mainCallbacks)); RetainPtr<CGShadingRef> mainShading = adoptCF(CGShadingCreateAxial(cspace, CGPointMake(r.x(), r.y()), CGPointMake(r.x(), r.maxY()), mainFunction.get(), false, false)); RetainPtr<CGShadingRef> leftShading = adoptCF(CGShadingCreateAxial(cspace, CGPointMake(r.x(), r.y()), CGPointMake(r.x() + radius, r.y()), mainFunction.get(), false, false)); RetainPtr<CGShadingRef> rightShading = adoptCF(CGShadingCreateAxial(cspace, CGPointMake(r.maxX(), r.y()), CGPointMake(r.maxX() - radius, r.y()), mainFunction.get(), false, false)); paintInfo.context->save(); CGContextClipToRect(context, r); paintInfo.context->clipRoundedRect(bound); CGContextDrawShading(context, mainShading.get()); paintInfo.context->restore(); paintInfo.context->save(); CGContextClipToRect(context, topGradient); paintInfo.context->clipRoundedRect(FloatRoundedRect(enclosingIntRect(topGradient), bound.radii().topLeft(), bound.radii().topRight(), IntSize(), IntSize())); CGContextDrawShading(context, topShading.get()); paintInfo.context->restore(); if (!bottomGradient.isEmpty()) { paintInfo.context->save(); CGContextClipToRect(context, bottomGradient); paintInfo.context->clipRoundedRect(FloatRoundedRect(enclosingIntRect(bottomGradient), IntSize(), IntSize(), bound.radii().bottomLeft(), bound.radii().bottomRight())); CGContextDrawShading(context, bottomShading.get()); paintInfo.context->restore(); } paintInfo.context->save(); CGContextClipToRect(context, r); paintInfo.context->clipRoundedRect(bound); CGContextDrawShading(context, leftShading.get()); CGContextDrawShading(context, rightShading.get()); paintInfo.context->restore(); paintInfo.context->restore(); }
void PrintTo(const FloatRoundedRect& roundedRect, std::ostream* os) { *os << "FloatRoundedRect("; PrintTo(roundedRect.rect(), os); *os << ", "; PrintTo(roundedRect.getRadii(), os); *os << ")"; }
void GraphicsContext::fillRoundedRect(const FloatRoundedRect& rect, const Color& color, BlendMode blendMode) { if (rect.isRounded()) { setCompositeOperation(compositeOperation(), blendMode); platformFillRoundedRect(rect, color); setCompositeOperation(compositeOperation()); } else fillRect(rect.rect(), color, compositeOperation(), blendMode); }
PassOwnPtr<Shape> Shape::createLayoutBoxShape(const FloatRoundedRect& roundedRect, WritingMode writingMode, float margin) { FloatRect rect(0, 0, roundedRect.rect().width(), roundedRect.rect().height()); FloatRoundedRect bounds(rect, roundedRect.radii()); OwnPtr<Shape> shape = createInsetShape(bounds); shape->m_writingMode = writingMode; shape->m_margin = margin; return shape.release(); }
std::unique_ptr<Shape> Shape::createLayoutBoxShape( const FloatRoundedRect& roundedRect, WritingMode writingMode, float margin) { FloatRect rect(0, 0, roundedRect.rect().width(), roundedRect.rect().height()); FloatRoundedRect bounds(rect, roundedRect.getRadii()); std::unique_ptr<Shape> shape = createInsetShape(bounds); shape->m_writingMode = writingMode; shape->m_margin = margin; return shape; }
void GraphicsContext::clipOutRoundedRect(const FloatRoundedRect& rect) { if (paintingDisabled()) return; if (!rect.isRounded()) { clipOut(rect.rect()); return; } Path path; path.addRoundedRect(rect); clipOut(path); }
void GraphicsContext::fillRoundedRect(const FloatRoundedRect& rect, const Color& color, BlendMode blendMode) { if (paintingDisabled()) return; if (isRecording()) { m_displayListRecorder->fillRoundedRect(rect, color, blendMode); return; } if (rect.isRounded()) { setCompositeOperation(compositeOperation(), blendMode); platformFillRoundedRect(rect, color); setCompositeOperation(compositeOperation()); } else fillRect(rect.rect(), color, compositeOperation(), blendMode); }
void GraphicsContext::fillRectWithRoundedHole(const FloatRect& rect, const FloatRoundedRect& roundedHoleRect, const Color& color, ColorSpace) { if (paintingDisabled() || !color.isValid()) return; if (this->mustUseShadowBlur()) platformContext()->shadowBlur().drawInsetShadow(this, rect, roundedHoleRect); Path path; path.addRect(rect); if (!roundedHoleRect.radii().isZero()) path.addRoundedRect(roundedHoleRect); else path.addRect(roundedHoleRect.rect()); cairo_t* cr = platformContext()->cr(); cairo_save(cr); setPathOnCairoContext(platformContext()->cr(), path.platformPath()->context()); fillCurrentCairoPath(this); cairo_restore(cr); }
void Path::addRoundedRect(const FloatRoundedRect& r, RoundedRectStrategy strategy) { if (r.isEmpty()) return; const FloatRoundedRect::Radii& radii = r.radii(); const FloatRect& rect = r.rect(); if (!r.isRenderable()) { // If all the radii cannot be accommodated, return a rect. addRect(rect); return; } if (strategy == PreferNativeRoundedRect) { #if USE(CG) platformAddPathForRoundedRect(rect, radii.topLeft(), radii.topRight(), radii.bottomLeft(), radii.bottomRight()); return; #endif } addBeziersForRoundedRect(rect, radii.topLeft(), radii.topRight(), radii.bottomLeft(), radii.bottomRight()); }
void Path::addRoundedRect(const FloatRoundedRect& r) { addRoundedRect(r.rect(), r.getRadii().topLeft(), r.getRadii().topRight(), r.getRadii().bottomLeft(), r.getRadii().bottomRight()); }
static PassOwnPtr<Shape> createInsetShape(const FloatRoundedRect& bounds) { ASSERT(bounds.rect().width() >= 0 && bounds.rect().height() >= 0); return adoptPtr(new BoxShape(bounds)); }
TEST(FloatRoundedRectTest, zeroRadii) { FloatRoundedRect r = FloatRoundedRect(1, 2, 3, 4); EXPECT_EQ(FloatRect(1, 2, 3, 4), r.rect()); EXPECT_EQ(FloatSize(), r.radii().topLeft()); EXPECT_EQ(FloatSize(), r.radii().topRight()); EXPECT_EQ(FloatSize(), r.radii().bottomLeft()); EXPECT_EQ(FloatSize(), r.radii().bottomRight()); EXPECT_TRUE(r.radii().isZero()); EXPECT_FALSE(r.isRounded()); EXPECT_FALSE(r.isEmpty()); EXPECT_EQ(FloatRect(1, 2, 0, 0), r.topLeftCorner()); EXPECT_EQ(FloatRect(4, 2, 0, 0), r.topRightCorner()); EXPECT_EQ(FloatRect(4, 6, 0, 0), r.bottomRightCorner()); EXPECT_EQ(FloatRect(1, 6, 0, 0), r.bottomLeftCorner()); TEST_INTERCEPTS(r, 2, r.rect().x(), r.rect().maxX()); TEST_INTERCEPTS(r, 4, r.rect().x(), r.rect().maxX()); TEST_INTERCEPTS(r, 6, r.rect().x(), r.rect().maxX()); float minXIntercept; float maxXIntercept; EXPECT_FALSE(r.xInterceptsAtY(1, minXIntercept, maxXIntercept)); EXPECT_FALSE(r.xInterceptsAtY(7, minXIntercept, maxXIntercept)); // The FloatRoundedRect::expandRadii() function doesn't change radii FloatSizes that // are <= zero. Same as RoundedRect::expandRadii(). r.expandRadii(20); r.shrinkRadii(10); EXPECT_TRUE(r.radii().isZero()); }
static PassOwnPtr<Shape> createBoxShape(const FloatRoundedRect& bounds, float shapeMargin, float shapePadding) { ASSERT(bounds.rect().width() >= 0 && bounds.rect().height() >= 0); return adoptPtr(new BoxShape(bounds, shapeMargin, shapePadding)); }
static std::unique_ptr<Shape> createInsetShape(const FloatRoundedRect& bounds) { ASSERT(bounds.rect().width() >= 0 && bounds.rect().height() >= 0); return wrapUnique(new BoxShape(bounds)); }
static bool isKeyNull(const FloatRoundedRect& rect) { return rect.isEmpty(); }
static std::unique_ptr<Shape> createInsetShape(const FloatRoundedRect& bounds) { ASSERT(bounds.rect().width() >= 0 && bounds.rect().height() >= 0); return std::make_unique<BoxShape>(bounds); }
void PrintTo(const FloatRoundedRect& roundedRect, std::ostream* os) { *os << "FloatRoundedRect(" << ::testing::PrintToString(roundedRect.rect()) << ", " << ::testing::PrintToString(roundedRect.radii()) << ")"; }
void PrintTo(const FloatRoundedRect& roundedRect, std::ostream* os) { *os << roundedRect.toString(); }
RoundedInnerRectClipper::RoundedInnerRectClipper(LayoutObject& layoutObject, const PaintInfo& paintInfo, const LayoutRect& rect, const FloatRoundedRect& clipRect, RoundedInnerRectClipperBehavior behavior) : m_layoutObject(layoutObject) , m_paintInfo(paintInfo) , m_useDisplayItemList(RuntimeEnabledFeatures::slimmingPaintEnabled() && behavior == ApplyToDisplayListIfEnabled) , m_clipType(m_useDisplayItemList ? m_paintInfo.displayItemTypeForClipping() : DisplayItem::ClipBoxPaintPhaseFirst) { Vector<FloatRoundedRect> roundedRectClips; if (clipRect.isRenderable()) { roundedRectClips.append(clipRect); } else { // We create a rounded rect for each of the corners and clip it, while making sure we clip opposing corners together. if (!clipRect.radii().topLeft().isEmpty() || !clipRect.radii().bottomRight().isEmpty()) { FloatRect topCorner(clipRect.rect().x(), clipRect.rect().y(), rect.maxX() - clipRect.rect().x(), rect.maxY() - clipRect.rect().y()); FloatRoundedRect::Radii topCornerRadii; topCornerRadii.setTopLeft(clipRect.radii().topLeft()); roundedRectClips.append(FloatRoundedRect(topCorner, topCornerRadii)); FloatRect bottomCorner(rect.x().toFloat(), rect.y().toFloat(), clipRect.rect().maxX() - rect.x().toFloat(), clipRect.rect().maxY() - rect.y().toFloat()); FloatRoundedRect::Radii bottomCornerRadii; bottomCornerRadii.setBottomRight(clipRect.radii().bottomRight()); roundedRectClips.append(FloatRoundedRect(bottomCorner, bottomCornerRadii)); } if (!clipRect.radii().topRight().isEmpty() || !clipRect.radii().bottomLeft().isEmpty()) { FloatRect topCorner(rect.x().toFloat(), clipRect.rect().y(), clipRect.rect().maxX() - rect.x().toFloat(), rect.maxY() - clipRect.rect().y()); FloatRoundedRect::Radii topCornerRadii; topCornerRadii.setTopRight(clipRect.radii().topRight()); roundedRectClips.append(FloatRoundedRect(topCorner, topCornerRadii)); FloatRect bottomCorner(clipRect.rect().x(), rect.y().toFloat(), rect.maxX() - clipRect.rect().x(), clipRect.rect().maxY() - rect.y().toFloat()); FloatRoundedRect::Radii bottomCornerRadii; bottomCornerRadii.setBottomLeft(clipRect.radii().bottomLeft()); roundedRectClips.append(FloatRoundedRect(bottomCorner, bottomCornerRadii)); } } if (m_useDisplayItemList) { ASSERT(m_paintInfo.context->displayItemList()); if (m_paintInfo.context->displayItemList()->displayItemConstructionIsDisabled()) return; m_paintInfo.context->displayItemList()->createAndAppend<ClipDisplayItem>(layoutObject, m_clipType, LayoutRect::infiniteIntRect(), roundedRectClips); } else { ClipDisplayItem clipDisplayItem(layoutObject, m_clipType, LayoutRect::infiniteIntRect(), roundedRectClips); clipDisplayItem.replay(*paintInfo.context); } }