FloatRect FEDisplacementMap::mapPaintRect(const FloatRect& rect, bool) { FloatRect result = rect; result.inflateX(filter()->applyHorizontalScale(m_scale / 2)); result.inflateY(filter()->applyVerticalScale(m_scale / 2)); return result; }
FloatRect FEMorphology::mapRect(const FloatRect& rect, bool) { FloatRect result = rect; result.inflateX(filter()->applyHorizontalScale(m_radiusX)); result.inflateY(filter()->applyVerticalScale(m_radiusY)); return result; }
void FEDropShadow::determineAbsolutePaintRect() { Filter* filter = this->filter(); ASSERT(filter); FloatRect absolutePaintRect = inputEffect(0)->absolutePaintRect(); FloatRect absoluteOffsetPaintRect(absolutePaintRect); absoluteOffsetPaintRect.move(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy)); absolutePaintRect.unite(absoluteOffsetPaintRect); unsigned kernelSizeX = 0; unsigned kernelSizeY = 0; FEGaussianBlur::calculateKernelSize(filter, kernelSizeX, kernelSizeY, m_stdX, m_stdY); // We take the half kernel size and multiply it with three, because we run box blur three times. absolutePaintRect.inflateX(3 * kernelSizeX * 0.5f); absolutePaintRect.inflateY(3 * kernelSizeY * 0.5f); if (clipsToBounds()) absolutePaintRect.intersect(maxEffectRect()); else absolutePaintRect.unite(maxEffectRect()); setAbsolutePaintRect(enclosingIntRect(absolutePaintRect)); }
static FloatRect inflateRect(const FloatRect& rect, float inflateX, float inflateY) { FloatRect inflatedRect = rect; inflatedRect.inflateX(inflateX); inflatedRect.inflateY(inflateY); return inflatedRect; }
void FEMorphology::determineAbsolutePaintRect() { FloatRect paintRect = inputEffect(0)->absolutePaintRect(); Filter* filter = this->filter(); paintRect.inflateX(filter->applyHorizontalScale(m_radiusX)); paintRect.inflateY(filter->applyVerticalScale(m_radiusY)); paintRect.intersect(maxEffectRect()); setAbsolutePaintRect(enclosingIntRect(paintRect)); }
FloatRect FEGaussianBlur::mapRect(const FloatRect& rect, bool) { FloatRect result = rect; IntSize kernelSize = calculateKernelSize(filter(), FloatPoint(m_stdX, m_stdY)); // We take the half kernel size and multiply it with three, because we run box blur three times. result.inflateX(3 * kernelSize.width() * 0.5f); result.inflateY(3 * kernelSize.height() * 0.5f); return result; }
void FEGaussianBlur::determineAbsolutePaintRect() { FloatRect absolutePaintRect = inputEffect(0)->absolutePaintRect(); absolutePaintRect.intersect(maxEffectRect()); unsigned kernelSizeX = 0; unsigned kernelSizeY = 0; calculateKernelSize(filter(), kernelSizeX, kernelSizeY, m_stdX, m_stdY); // We take the half kernel size and multiply it with three, because we run box blur three times. absolutePaintRect.inflateX(3 * kernelSizeX * 0.5f); absolutePaintRect.inflateY(3 * kernelSizeY * 0.5f); setAbsolutePaintRect(enclosingIntRect(absolutePaintRect)); }
FloatRect FEDropShadow::mapRect(const FloatRect& rect, bool forward) { FloatRect result = rect; Filter* filter = this->filter(); ASSERT(filter); FloatRect offsetRect = rect; if (forward) offsetRect.move(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy)); else offsetRect.move(-filter->applyHorizontalScale(m_dx), -filter->applyVerticalScale(m_dy)); result.unite(offsetRect); IntSize kernelSize = FEGaussianBlur::calculateKernelSize(filter, FloatPoint(m_stdX, m_stdY)); // We take the half kernel size and multiply it with three, because we run box blur three times. result.inflateX(3 * kernelSize.width() * 0.5f); result.inflateY(3 * kernelSize.height() * 0.5f); return result; }
void FEGaussianBlur::determineAbsolutePaintRect() { IntSize kernelSize = calculateKernelSize(filter(), FloatPoint(m_stdX, m_stdY)); FloatRect absolutePaintRect = inputEffect(0)->absolutePaintRect(); // Edge modes other than 'none' do not inflate the affected paint rect. if (m_edgeMode != EDGEMODE_NONE) { setAbsolutePaintRect(enclosingIntRect(absolutePaintRect)); return; } // We take the half kernel size and multiply it with three, because we run box blur three times. absolutePaintRect.inflateX(3 * kernelSize.width() * 0.5f); absolutePaintRect.inflateY(3 * kernelSize.height() * 0.5f); if (clipsToBounds()) absolutePaintRect.intersect(maxEffectRect()); else absolutePaintRect.unite(maxEffectRect()); setAbsolutePaintRect(enclosingIntRect(absolutePaintRect)); }
// Return 'rect' padded evenly on all sides to achieve 'newSize', but make the padding uneven to contain within constrainingRect. static FloatRect expandRectWithinRect(const FloatRect& rect, const FloatSize& newSize, const FloatRect& constrainingRect) { ASSERT(newSize.width() >= rect.width() && newSize.height() >= rect.height()); FloatSize extraSize = newSize - rect.size(); FloatRect expandedRect = rect; expandedRect.inflateX(extraSize.width() / 2); expandedRect.inflateY(extraSize.height() / 2); if (expandedRect.x() < constrainingRect.x()) expandedRect.setX(constrainingRect.x()); else if (expandedRect.maxX() > constrainingRect.maxX()) expandedRect.setX(constrainingRect.maxX() - expandedRect.width()); if (expandedRect.y() < constrainingRect.y()) expandedRect.setY(constrainingRect.y()); else if (expandedRect.maxY() > constrainingRect.maxY()) expandedRect.setY(constrainingRect.maxY() - expandedRect.height()); return intersection(expandedRect, constrainingRect); }
void FEDropShadow::determineAbsolutePaintRect() { Filter& filter = this->filter(); FloatRect absolutePaintRect = inputEffect(0)->absolutePaintRect(); FloatRect absoluteOffsetPaintRect(absolutePaintRect); absoluteOffsetPaintRect.move(filter.applyHorizontalScale(m_dx), filter.applyVerticalScale(m_dy)); absolutePaintRect.unite(absoluteOffsetPaintRect); IntSize kernelSize = FEGaussianBlur::calculateKernelSize(filter, FloatPoint(m_stdX, m_stdY)); // We take the half kernel size and multiply it with three, because we run box blur three times. absolutePaintRect.inflateX(3 * kernelSize.width() * 0.5f); absolutePaintRect.inflateY(3 * kernelSize.height() * 0.5f); if (clipsToBounds()) absolutePaintRect.intersect(maxEffectRect()); else absolutePaintRect.unite(maxEffectRect()); setAbsolutePaintRect(enclosingIntRect(absolutePaintRect)); }
static bool initializeIndicator(TextIndicatorData& data, Frame& frame, const Range& range, FloatSize margin, bool indicatesCurrentSelection) { Vector<FloatRect> textRects; // FIXME (138888): Ideally we wouldn't remove the margin in this case, but we need to // ensure that the indicator and indicator-with-highlight overlap precisely, and // we can't add a margin to the indicator-with-highlight. if (indicatesCurrentSelection && !(data.options & TextIndicatorOptionIncludeMarginIfRangeMatchesSelection)) margin = FloatSize(); FrameSelection::TextRectangleHeight textRectHeight = (data.options & TextIndicatorOptionTightlyFitContent) ? FrameSelection::TextRectangleHeight::TextHeight : FrameSelection::TextRectangleHeight::SelectionHeight; if ((data.options & TextIndicatorOptionUseBoundingRectAndPaintAllContentForComplexRanges) && hasNonInlineOrReplacedElements(range)) data.options |= TextIndicatorOptionPaintAllContent; else { if (data.options & TextIndicatorOptionDoNotClipToVisibleRect) frame.selection().getTextRectangles(textRects, textRectHeight); else frame.selection().getClippedVisibleTextRectangles(textRects, textRectHeight); } if (textRects.isEmpty()) { RenderView* renderView = frame.contentRenderer(); if (!renderView) return false; FloatRect boundingRect = range.absoluteBoundingRect(); if (data.options & TextIndicatorOptionDoNotClipToVisibleRect) textRects.append(boundingRect); else { // Clip to the visible rect, just like getClippedVisibleTextRectangles does. // FIXME: We really want to clip to the unobscured rect in both cases, I think. // (this seems to work on Mac, but maybe not iOS?) FloatRect visibleContentRect = frame.view()->visibleContentRect(ScrollableArea::LegacyIOSDocumentVisibleRect); textRects.append(intersection(visibleContentRect, boundingRect)); } } FloatRect textBoundingRectInRootViewCoordinates; FloatRect textBoundingRectInDocumentCoordinates; Vector<FloatRect> textRectsInRootViewCoordinates; for (const FloatRect& textRect : textRects) { FloatRect textRectInDocumentCoordinatesIncludingMargin = textRect; textRectInDocumentCoordinatesIncludingMargin.inflateX(margin.width()); textRectInDocumentCoordinatesIncludingMargin.inflateY(margin.height()); textBoundingRectInDocumentCoordinates.unite(textRectInDocumentCoordinatesIncludingMargin); FloatRect textRectInRootViewCoordinates = frame.view()->contentsToRootView(enclosingIntRect(textRectInDocumentCoordinatesIncludingMargin)); textRectsInRootViewCoordinates.append(textRectInRootViewCoordinates); textBoundingRectInRootViewCoordinates.unite(textRectInRootViewCoordinates); } Vector<FloatRect> textRectsInBoundingRectCoordinates; for (auto rect : textRectsInRootViewCoordinates) { rect.moveBy(-textBoundingRectInRootViewCoordinates.location()); textRectsInBoundingRectCoordinates.append(rect); } // Store the selection rect in window coordinates, to be used subsequently // to determine if the indicator and selection still precisely overlap. data.selectionRectInRootViewCoordinates = frame.view()->contentsToRootView(enclosingIntRect(frame.selection().selectionBounds())); data.textBoundingRectInRootViewCoordinates = textBoundingRectInRootViewCoordinates; data.textRectsInBoundingRectCoordinates = textRectsInBoundingRectCoordinates; return takeSnapshots(data, frame, enclosingIntRect(textBoundingRectInDocumentCoordinates)); }
void BackingStoreScrollbar::repaint(const WebCore::IntRect& hotRect, bool vertical) { SurfaceOpenVG* surface = SurfacePool::globalSurfacePool()->tileRenderingSurface(); const IntSize surfaceSize(surface->width(), surface->height()); PainterOpenVG painter(surface); // If the rendering surface is smaller than the scrollbar // (e.g. when the screen is rotated), paint it multiple times. int lastXTile = (m_size.width() - 1) / surfaceSize.width(); int lastYTile = (m_size.height() - 1) / surfaceSize.height(); FloatRect innerRect = hotRect; innerRect.move(0.5, 0.5); // draw it pixel-perfect with a 1.0 wide stroke int radius = vertical ? hotRect.width() / 2 : hotRect.height() / 2; if (vertical) innerRect.inflateY(-radius); else innerRect.inflateX(-radius); Path path; if (vertical) { path.moveTo(FloatPoint(innerRect.x(), innerRect.y())); path.addArc(FloatPoint(innerRect.x() + radius, innerRect.y()), radius, piFloat, 0, false); path.addLineTo(FloatPoint(innerRect.right(), innerRect.bottom())); path.addArc(FloatPoint(innerRect.x() + radius, innerRect.bottom()), radius, 0, piFloat, false); path.closeSubpath(); } else { path.moveTo(FloatPoint(innerRect.right(), innerRect.y())); path.addArc(FloatPoint(innerRect.right(), innerRect.y() + radius), radius, piFloat + piFloat / 2, piFloat / 2, false); path.addLineTo(FloatPoint(innerRect.x(), innerRect.bottom())); path.addArc(FloatPoint(innerRect.x(), innerRect.y() + radius), radius, piFloat / 2, piFloat + piFloat / 2, false); path.closeSubpath(); } for (int i = 0; i <= lastXTile; ++i) { for (int j = 0; j <= lastYTile; ++j) { const int dstX = i * surfaceSize.width(); const int dstY = j * surfaceSize.height(); const int dstRight = (i == lastXTile) ? m_size.width() : (i + 1) * surfaceSize.width(); const int dstBottom = (j == lastYTile) ? m_size.height() : (j + 1) * surfaceSize.height(); painter.translate(rect().x(), rect().y()); if (dstX || dstY) painter.translate(-dstX, -dstY); // Paint the actual scrollbar. painter.setFillColor(Color(255, 255, 255)); painter.drawRect(IntRect(IntPoint(0, 0), rect().size()), VG_FILL_PATH); painter.setFillColor(Color(173, 176, 178)); painter.drawPath(path, VG_FILL_PATH, WebCore::RULE_NONZERO); surface->makeCurrent(); unsigned char* dstBufferStart = m_image + (dstY * imageStride()) + (dstX * imageBytesPerPixel()); vgReadPixels(dstBufferStart, imageStride(), VG_sRGB_565, 0, 0, dstRight - dstX, dstBottom - dstY); ASSERT_VG_NO_ERROR(); // Paint the alpha channel for the actual scrollbar. painter.setCompositeOperation(CompositeClear); painter.setFillColor(Color(0, 0, 0)); painter.drawRect(IntRect(IntPoint(0, 0), rect().size()), VG_FILL_PATH); painter.setCompositeOperation(CompositeSourceOver); painter.setFillColor(Color(255, 255, 255)); painter.drawPath(path, VG_FILL_PATH, WebCore::RULE_NONZERO); surface->makeCurrent(); // FIXME: We need VG_A_4 until proper alpha blending is available. // When we get 8-bit formats, make sure to adapt both the format // and remove the division by two when determining the dstAlphaBufferStart. unsigned char* dstAlphaBufferStart = m_alphaImage + (dstY * alphaImageStride()) + dstX / 2; vgReadPixels(dstAlphaBufferStart, alphaImageStride(), VG_A_4, 0, 0, dstRight - dstX, dstBottom - dstY); ASSERT_VG_NO_ERROR(); if (dstX || dstY) painter.translate(dstX, dstY); } } }
FloatRect FEDisplacementMap::mapEffect(const FloatRect& rect) const { FloatRect result = rect; result.inflateX(getFilter()->applyHorizontalScale(std::abs(m_scale) / 2)); result.inflateY(getFilter()->applyVerticalScale(std::abs(m_scale) / 2)); return result; }