bool RenderFlowThread::hitTestFlowThreadPortionInRegion(RenderRegion* region, LayoutRect flowThreadPortionRect, LayoutRect flowThreadPortionOverflowRect, const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const { LayoutRect regionClippingRect = computeRegionClippingRect(accumulatedOffset, flowThreadPortionRect, flowThreadPortionOverflowRect); if (!regionClippingRect.contains(locationInContainer.point())) return false; LayoutSize renderFlowThreadOffset; if (style()->isFlippedBlocksWritingMode()) { LayoutRect flippedFlowThreadPortionRect(flowThreadPortionRect); flipForWritingMode(flippedFlowThreadPortionRect); renderFlowThreadOffset = accumulatedOffset - flippedFlowThreadPortionRect.location(); } else renderFlowThreadOffset = accumulatedOffset - flowThreadPortionRect.location(); // Always ignore clipping, since the RenderFlowThread has nothing to do with the bounds of the FrameView. HitTestRequest newRequest(request.type() | HitTestRequest::IgnoreClipping); // Make a new temporary HitTestLocation in the new region. HitTestLocation newHitTestLocation(locationInContainer, -renderFlowThreadOffset, region); bool isPointInsideFlowThread = layer()->hitTest(newRequest, newHitTestLocation, result); // FIXME: Should we set result.m_localPoint back to the RenderRegion's coordinate space or leave it in the RenderFlowThread's coordinate // space? Right now it's staying in the RenderFlowThread's coordinate space, which may end up being ok. We will know more when we get around to // patching positionForPoint. return isPointInsideFlowThread; }
void RenderRegion::repaintFlowThreadContentRectangle(const LayoutRect& repaintRect, const LayoutRect& flowThreadPortionRect, const LayoutPoint& regionLocation, const LayoutRect* flowThreadPortionClipRect) { ASSERT(isValid()); // We only have to issue a repaint in this region if the region rect intersects the repaint rect. LayoutRect clippedRect(repaintRect); if (flowThreadPortionClipRect) { LayoutRect flippedFlowThreadPortionClipRect(*flowThreadPortionClipRect); flowThread()->flipForWritingMode(flippedFlowThreadPortionClipRect); clippedRect.intersect(flippedFlowThreadPortionClipRect); } if (clippedRect.isEmpty()) return; LayoutRect flippedFlowThreadPortionRect(flowThreadPortionRect); flowThread()->flipForWritingMode(flippedFlowThreadPortionRect); // Put the region rects into physical coordinates. // Put the region rect into the region's physical coordinate space. clippedRect.setLocation(regionLocation + (clippedRect.location() - flippedFlowThreadPortionRect.location())); // Now switch to the region's writing mode coordinate space and let it repaint itself. flipForWritingMode(clippedRect); // Issue the repaint. repaintRectangle(clippedRect); }
LayoutPoint RenderRegion::flowThreadPortionLocation() const { LayoutPoint portionLocation; LayoutRect portionRect = flowThreadPortionRect(); if (flowThread()->style().isFlippedBlocksWritingMode()) { LayoutRect flippedFlowThreadPortionRect(portionRect); flowThread()->flipForWritingMode(flippedFlowThreadPortionRect); portionLocation = flippedFlowThreadPortionRect.location(); } else portionLocation = portionRect.location(); return portionLocation; }
void RenderFlowThread::paintFlowThreadPortionInRegion(PaintInfo& paintInfo, RenderRegion* region, LayoutRect flowThreadPortionRect, LayoutRect flowThreadPortionOverflowRect, const LayoutPoint& paintOffset) const { GraphicsContext* context = paintInfo.context; if (!context) return; // RenderFlowThread should start painting its content in a position that is offset // from the region rect's current position. The amount of offset is equal to the location of // the flow thread portion in the flow thread's local coordinates. // Note that we have to pixel snap the location at which we're going to paint, since this is necessary // to minimize the amount of incorrect snapping that would otherwise occur. // If we tried to paint by applying a non-integral translation, then all the // layout code that attempted to pixel snap would be incorrect. IntPoint adjustedPaintOffset; LayoutPoint portionLocation; if (style()->isFlippedBlocksWritingMode()) { LayoutRect flippedFlowThreadPortionRect(flowThreadPortionRect); flipForWritingMode(flippedFlowThreadPortionRect); portionLocation = flippedFlowThreadPortionRect.location(); } else portionLocation = flowThreadPortionRect.location(); adjustedPaintOffset = roundedIntPoint(paintOffset - portionLocation); // The clipping rect for the region is set up by assuming the flowThreadPortionRect is going to paint offset from adjustedPaintOffset. // Remember that we pixel snapped and moved the paintOffset and stored the snapped result in adjustedPaintOffset. Now we add back in // the flowThreadPortionRect's location to get the spot where we expect the portion to actually paint. This can be non-integral and // that's ok. We then pixel snap the resulting clipping rect to account for snapping that will occur when the flow thread paints. IntRect regionClippingRect = pixelSnappedIntRect(computeRegionClippingRect(adjustedPaintOffset + portionLocation, flowThreadPortionRect, flowThreadPortionOverflowRect)); PaintInfo info(paintInfo); info.rect.intersect(regionClippingRect); if (!info.rect.isEmpty()) { context->save(); context->clip(regionClippingRect); context->translate(adjustedPaintOffset.x(), adjustedPaintOffset.y()); info.rect.moveBy(-adjustedPaintOffset); layer()->paint(context, info.rect, 0, 0, region, RenderLayer::PaintLayerTemporaryClipRects); context->restore(); } }
void RenderFlowThread::paintFlowThreadPortionInRegion(PaintInfo& paintInfo, RenderRegion* region, LayoutRect flowThreadPortionRect, LayoutRect flowThreadPortionOverflowRect, const LayoutPoint& paintOffset) const { GraphicsContext* context = paintInfo.context; if (!context) return; // Adjust the clipping rect for the region. // paintOffset contains the offset where the painting should occur // adjusted with the region padding and border. LayoutRect regionClippingRect = computeRegionClippingRect(paintOffset, flowThreadPortionRect, flowThreadPortionOverflowRect); PaintInfo info(paintInfo); info.rect.intersect(pixelSnappedIntRect(regionClippingRect)); if (!info.rect.isEmpty()) { context->save(); context->clip(regionClippingRect); // RenderFlowThread should start painting its content in a position that is offset // from the region rect's current position. The amount of offset is equal to the location of // the flow thread portion in the flow thread's local coordinates. IntPoint renderFlowThreadOffset; if (style()->isFlippedBlocksWritingMode()) { LayoutRect flippedFlowThreadPortionRect(flowThreadPortionRect); flipForWritingMode(flippedFlowThreadPortionRect); renderFlowThreadOffset = roundedIntPoint(paintOffset - flippedFlowThreadPortionRect.location()); } else renderFlowThreadOffset = roundedIntPoint(paintOffset - flowThreadPortionRect.location()); context->translate(renderFlowThreadOffset.x(), renderFlowThreadOffset.y()); info.rect.moveBy(-renderFlowThreadOffset); layer()->paint(context, info.rect, 0, 0, region, RenderLayer::PaintLayerTemporaryClipRects); context->restore(); } }