AffineTransform SVGSVGElement::localCoordinateSpaceTransform(SVGLocatable::CTMScope mode) const { AffineTransform viewBoxTransform; if (attributes()->getAttributeItem(SVGNames::viewBoxAttr)) viewBoxTransform = viewBoxToViewTransform(width().value(this), height().value(this)); AffineTransform transform; if (!isOutermostSVG()) transform.translate(x().value(this), y().value(this)); else if (mode == SVGLocatable::ScreenScope) { if (RenderObject* renderer = this->renderer()) { // Translate in our CSS parent coordinate space // FIXME: This doesn't work correctly with CSS transforms. FloatPoint location = renderer->localToAbsolute(FloatPoint(), false, true); // Be careful here! localToAbsolute() includes the x/y offset coming from the viewBoxToViewTransform(), because // RenderSVGRoot::localToBorderBoxTransform() (called through mapLocalToContainer(), called from localToAbsolute()) // also takes the viewBoxToViewTransform() into account, so we have to subtract it here (original cause of bug #27183) transform.translate(location.x() - viewBoxTransform.e(), location.y() - viewBoxTransform.f()); // Respect scroll offset. if (FrameView* view = document()->view()) { IntSize scrollOffset = view->scrollOffset(); transform.translate(-scrollOffset.width(), -scrollOffset.height()); } } } return transform.multLeft(viewBoxTransform); }
static inline AffineTransform clipToTextMask(GraphicsContext* context, OwnPtr<ImageBuffer>& imageBuffer, FloatRect& targetRect, const RenderObject* object, GradientData* gradientData) { const RenderObject* textRootBlock = SVGRenderSupport::findTextRootObject(object); ASSERT(textRootBlock); targetRect = textRootBlock->repaintRectInLocalCoordinates(); AffineTransform absoluteTransform; SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(textRootBlock, absoluteTransform); FloatRect absoluteTargetRect = absoluteTransform.mapRect(targetRect); FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(textRootBlock, absoluteTargetRect); SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, clampedAbsoluteTargetRect, imageBuffer); AffineTransform matrix; if (gradientData->boundingBoxMode) { FloatRect maskBoundingBox = textRootBlock->objectBoundingBox(); matrix.translate(maskBoundingBox.x(), maskBoundingBox.y()); matrix.scaleNonUniform(maskBoundingBox.width(), maskBoundingBox.height()); } matrix.multLeft(gradientData->transform); return matrix; }
void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& dstRect) { if (m_data.m_tiledImage && context != m_context.get()) { FloatRect src = srcRect; if (src.width() == -1) src.setWidth(m_data.m_tiledImage->size().width()); if (src.height() == -1) src.setHeight(m_data.m_tiledImage->size().height()); ASSERT(context->platformContext()->activePainter()); AffineTransform phasedPatternTransform; phasedPatternTransform.translate(phase.x(), phase.y()); phasedPatternTransform.multLeft(patternTransform); PatternOpenVG pattern(m_data.m_tiledImage, src); pattern.setTransformation(phasedPatternTransform); PainterOpenVG* painter = context->platformContext()->activePainter(); PaintOpenVG currentPaint = painter->fillPaint(); CompositeOperator currentOp = painter->compositeOperation(); painter->setCompositeOperation(op); painter->setFillPattern(pattern); painter->drawRect(dstRect, VG_FILL_PATH); painter->setFillPaint(currentPaint); painter->setCompositeOperation(currentOp); return; } RefPtr<Image> imageCopy = copyImage(); imageCopy->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, op, dstRect); }