TEST_F(DisplayItemPropertyTreeBuilderTest, TransformDisplayItemCreatesTransformNode) { // 2D transform display items should create a transform node as well, // unless the transform is a 2D translation only. AffineTransform rotation; rotation.rotate(45); processDummyDisplayItem(); auto transformClient = processBeginTransform(rotation); processDummyDisplayItem(); processEndTransform(transformClient); processDummyDisplayItem(); finishPropertyTrees(); // There should be two transform nodes. ASSERT_EQ(2u, transformTree().nodeCount()); EXPECT_TRUE(transformTree().nodeAt(0).isRoot()); EXPECT_EQ(0u, transformTree().nodeAt(1).parentNodeIndex); EXPECT_TRANSFORMS_ALMOST_EQ(TransformationMatrix(rotation), transformTree().nodeAt(1).matrix); // There should be three range records, the middle one affected by the // rotation. EXPECT_THAT(rangeRecordsAsStdVector(), ElementsAre( AllOf(hasRange(0, 1), hasTransformNode(0)), AllOf(hasRange(2, 3), hasTransformNode(1)), AllOf(hasRange(4, 5), hasTransformNode(0)))); }
void PaintPropertyTreeBuilder::updatePaintOffsetTranslation(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) { if (object.isBoxModelObject()) { // TODO(trchen): Eliminate PaintLayer dependency. PaintLayer* layer = toLayoutBoxModelObject(object).layer(); if (!layer || !layer->paintsWithTransform(GlobalPaintNormalPhase)) return; } if (context.paintOffset == LayoutPoint()) return; // We should use the same subpixel paint offset values for snapping regardless of whether a // transform is present. If there is a transform we round the paint offset but keep around // the residual fractional component for the transformed content to paint with. // In spv1 this was called "subpixel accumulation". For more information, see // PaintLayer::subpixelAccumulation() and PaintLayerPainter::paintFragmentByApplyingTransform. IntPoint roundedPaintOffset = roundedIntPoint(context.paintOffset); LayoutPoint fractionalPaintOffset = LayoutPoint(context.paintOffset - roundedPaintOffset); RefPtr<TransformPaintPropertyNode> paintOffsetTranslation = TransformPaintPropertyNode::create( TransformationMatrix().translate(roundedPaintOffset.x(), roundedPaintOffset.y()), FloatPoint3D(), context.currentTransform); context.currentTransform = paintOffsetTranslation.get(); context.paintOffset = fractionalPaintOffset; object.getMutableForPainting().ensureObjectPaintProperties().setPaintOffsetTranslation(paintOffsetTranslation.release()); }
TEST_F(DisplayItemPropertyTreeBuilderTest, RootTransformNodeHasIdentityTransform) { finishPropertyTrees(); ASSERT_EQ(1u, transformTree().nodeCount()); EXPECT_TRUE(transformTree().nodeAt(0).matrix.isIdentity()); EXPECT_TRANSFORMS_ALMOST_EQ(TransformationMatrix(), transformTree().nodeAt(0).matrix); }
IntRect TextureMapperLayer::intermediateSurfaceRect(const TransformationMatrix& matrix) { IntRect rect; TransformationMatrix localTransform = TransformationMatrix(matrix).multiply(m_transform.combined()); rect = enclosingIntRect(localTransform.mapRect(layerRect())); if (!m_state.masksToBounds && !m_state.maskLayer) { for (size_t i = 0; i < m_children.size(); ++i) rect.unite(m_children[i]->intermediateSurfaceRect(matrix)); } #if ENABLE(CSS_FILTERS) if (m_filters.hasOutsets()) { int leftOutset; int topOutset; int bottomOutset; int rightOutset; m_filters.getOutsets(topOutset, rightOutset, bottomOutset, leftOutset); IntRect unfilteredTargetRect(rect); rect.move(std::max(0, -leftOutset), std::max(0, -topOutset)); rect.expand(leftOutset + rightOutset, topOutset + bottomOutset); rect.unite(unfilteredTargetRect); } #endif if (m_state.replicaLayer) rect.unite(m_state.replicaLayer->intermediateSurfaceRect(matrix)); return rect; }
void RenderForeignObject::paint(PaintInfo& paintInfo, int parentX, int parentY) { if (paintInfo.context->paintingDisabled()) return; paintInfo.context->save(); paintInfo.context->concatCTM(TransformationMatrix().translate(parentX, parentY)); paintInfo.context->concatCTM(localTransform()); paintInfo.context->concatCTM(translationForAttributes()); paintInfo.context->clip(getClipRect(parentX, parentY)); float opacity = style()->opacity(); if (opacity < 1.0f) // FIXME: Possible optimization by clipping to bbox here, once relativeBBox is implemented & clip, mask and filter support added. paintInfo.context->beginTransparencyLayer(opacity); PaintInfo pi(paintInfo); pi.rect = absoluteTransform().inverse().mapRect(paintInfo.rect); RenderBlock::paint(pi, 0, 0); if (opacity < 1.0f) paintInfo.context->endTransparencyLayer(); paintInfo.context->restore(); }
// Perform a concatenation of the matrices (this * secondMatrix) PassRefPtrWillBeRawPtr<CSSMatrix> CSSMatrix::multiply(CSSMatrix* secondMatrix) const { if (!secondMatrix) return nullptr; return CSSMatrix::create(TransformationMatrix(m_matrix).multiply(secondMatrix->m_matrix)); }
// Perform a concatenation of the matrices (this * secondMatrix) PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::multiply(WebKitCSSMatrix* secondMatrix) const { if (!secondMatrix) return 0; return WebKitCSSMatrix::create(TransformationMatrix(m_matrix).multiply(secondMatrix->m_matrix)); }
void TextureMapperLayer::paintUsingOverlapRegions(const TextureMapperPaintOptions& options) { Region overlapRegion; Region nonOverlapRegion; computeOverlapRegions(overlapRegion, nonOverlapRegion, ResolveSelfOverlapAlways); if (overlapRegion.isEmpty()) { paintSelfAndChildrenWithReplica(options); return; } Vector<IntRect> rects; nonOverlapRegion.translate(options.offset); rects = nonOverlapRegion.rects(); for (size_t i = 0; i < rects.size(); ++i) { options.textureMapper->beginClip(TransformationMatrix(), rects[i]); paintSelfAndChildrenWithReplica(options); options.textureMapper->endClip(); } rects = overlapRegion.rects(); IntSize maxTextureSize = options.textureMapper->maxTextureSize(); IntRect rect; for (size_t i = 0; i < rects.size(); ++i) { rect = rects[i]; for (int x = rect.x(); x < rect.maxX(); x += maxTextureSize.width()) { for (int y = rect.y(); y < rect.maxY(); y += maxTextureSize.height()) { IntRect tileRect(IntPoint(x, y), maxTextureSize); tileRect.intersect(rect); paintWithIntermediateSurface(options, tileRect); } } } }
TEST_F(PaintPropertyTreeBuilderTest, TransformNodeDoesNotAffectEffectNodes) { setBodyInnerHTML( "<div id='nodeWithOpacity' style='opacity: 0.6'>" " <div id='childWithTransform' style='transform: translate3d(10px, 10px, 0px);'>" " <div id='grandChildWithOpacity' style='opacity: 0.4'/>" " </div>" "</div>"); LayoutObject& nodeWithOpacity = *document().getElementById("nodeWithOpacity")->layoutObject(); ObjectPaintProperties* nodeWithOpacityProperties = nodeWithOpacity.objectPaintProperties(); EXPECT_EQ(0.6f, nodeWithOpacityProperties->effect()->opacity()); EXPECT_EQ(nullptr, nodeWithOpacityProperties->effect()->parent()); EXPECT_EQ(nullptr, nodeWithOpacityProperties->transform()); LayoutObject& childWithTransform = *document().getElementById("childWithTransform")->layoutObject(); ObjectPaintProperties* childWithTransformProperties = childWithTransform.objectPaintProperties(); EXPECT_EQ(nullptr, childWithTransformProperties->effect()); EXPECT_EQ(TransformationMatrix().translate(10, 10), childWithTransformProperties->transform()->matrix()); LayoutObject& grandChildWithOpacity = *document().getElementById("grandChildWithOpacity")->layoutObject(); ObjectPaintProperties* grandChildWithOpacityProperties = grandChildWithOpacity.objectPaintProperties(); EXPECT_EQ(0.4f, grandChildWithOpacityProperties->effect()->opacity()); EXPECT_EQ(nodeWithOpacityProperties->effect(), grandChildWithOpacityProperties->effect()->parent()); EXPECT_EQ(nullptr, grandChildWithOpacityProperties->transform()); }
void TextureMapperNode::paintSurface(const TexmapPaintOptions& options) { if (m_layerType == RootLayer || m_layerType == DefaultLayer || m_layerType == ScissorLayer) return; RefPtr<BitmapTexture> maskTexture; if (TextureMapperNode* mask = m_state.maskLayer) maskTexture = mask->m_texture; ASSERT(m_surface); BitmapTexture& texture = *m_surface.get(); if (maskTexture) maskTexture->unpack(); texture.unpack(); if (paintReplica(options)) return; options.textureMapper->bindSurface(options.surface); options.textureMapper->drawTexture(texture, m_layerType == TransparencyLayer ? IntRect(IntPoint(0, 0), options.surface->size()) : targetRect(), m_layerType == TransparencyLayer ? TransformationMatrix() : m_transforms.target, options.opacity, maskTexture.get()); options.cache->mark(&texture); }
void TextureMapperNode::paintSelf(const TexmapPaintOptions& options) { if (m_size.isEmpty() || (!m_state.drawsContent && m_currentContent.contentType == HTMLContentType)) return; RefPtr<BitmapTexture> replicaMaskTexture; m_texture->unpack(); RefPtr<BitmapTexture> maskTexture = m_state.maskLayer ? m_state.maskLayer->m_texture : 0; if (m_state.replicaLayer && m_state.replicaLayer->m_state.maskLayer) replicaMaskTexture = m_state.replicaLayer->m_state.maskLayer->m_texture; if (maskTexture) maskTexture->unpack(); if (replicaMaskTexture) replicaMaskTexture->unpack(); const float opacity = options.isSurface ? 1 : options.opacity; if (m_state.replicaLayer && !options.isSurface) options.textureMapper->drawTexture(*m_texture.get(), replicaRect(), m_transforms.replica, opacity * m_state.replicaLayer->m_state.opacity, replicaMaskTexture ? replicaMaskTexture.get() : maskTexture.get()); const IntRect rect = m_layerType == ClipLayer ? entireRect() : targetRect(); const TransformationMatrix transform = m_layerType == ClipLayer ? TransformationMatrix() : m_transforms.target; options.textureMapper->drawTexture(*m_texture.get(), rect, transform, opacity, options.isSurface ? 0 : maskTexture.get()); options.cache->mark(m_texture.get()); }
// SVG does not use the general transform update of |updateTransform|, instead // creating a transform node for SVG-specific transforms without 3D. void PaintPropertyTreeBuilder::updateTransformForNonRootSVG( const LayoutObject& object, PaintPropertyTreeBuilderContext& context) { DCHECK(object.isSVG() && !object.isSVGRoot()); // SVG (other than SVGForeignObject) does not use paint offset internally. DCHECK(object.isSVGForeignObject() || context.current.paintOffset == LayoutPoint()); // TODO(pdr): Refactor this so all non-root SVG objects use the same // transform function. const AffineTransform& transform = object.isSVGForeignObject() ? object.localSVGTransform() : object.localToSVGParentTransform(); // TODO(pdr): Check for the presence of a transform instead of the value. // Checking for an identity matrix will cause the property tree structure // to change during animations if the animation passes through the // identity matrix. if (!transform.isIdentity()) { // The origin is included in the local transform, so leave origin empty. object.getMutableForPainting().ensurePaintProperties().updateTransform( context.current.transform, TransformationMatrix(transform), FloatPoint3D()); } else { if (auto* properties = object.getMutableForPainting().paintProperties()) properties->clearTransform(); } if (object.paintProperties() && object.paintProperties()->transform()) { context.current.transform = object.paintProperties()->transform(); context.current.shouldFlattenInheritedTransform = false; context.current.renderingContextID = 0; } }
FloatSize TextureMapperLayer::mapScrollOffset(const FloatSize& offset) { double zeroX, zeroY, offsetX, offsetY; TransformationMatrix transform = m_currentTransform.combined().inverse().valueOr(TransformationMatrix()); transform.map(0, 0, zeroX, zeroY); transform.map(offset.width(), offset.height(), offsetX, offsetY); return FloatSize(offsetX - zeroX, offsetY - zeroY); }
TransformationMatrix CCRenderSurface::computeDeviceTransform(LayerRendererChromium* layerRenderer, const TransformationMatrix& drawTransform) const { TransformationMatrix renderTransform = drawTransform; // Apply a scaling factor to size the quad from 1x1 to its intended size. renderTransform.scale3d(m_contentRect.width(), m_contentRect.height(), 1); TransformationMatrix deviceTransform = TransformationMatrix(layerRenderer->windowMatrix() * layerRenderer->projectionMatrix() * renderTransform).to2dTransform(); return deviceTransform; }
void GraphicsContextPlatformPrivate::scale(const FloatSize& size) { if (!m_hdc) return; XFORM xform = TransformationMatrix().scaleNonUniform(size.width(), size.height()); ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY); }
void GraphicsContextPlatformPrivate::translate(float x , float y) { if (!m_hdc) return; XFORM xform = TransformationMatrix().translate(x, y); ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY); }
TEST_F(PaintPropertyTreeBuilderTest, FrameScrollingTraditional) { setBodyInnerHTML("<style> body { height: 10000px; } </style>"); document().domWindow()->scrollTo(0, 100); FrameView* frameView = document().view(); frameView->updateAllLifecyclePhases(); EXPECT_EQ(TransformationMatrix(), frameView->preTranslation()->matrix()); EXPECT_EQ(nullptr, frameView->preTranslation()->parent()); EXPECT_EQ(TransformationMatrix().translate(0, -100), frameView->scrollTranslation()->matrix()); EXPECT_EQ(frameView->preTranslation(), frameView->scrollTranslation()->parent()); LayoutView* layoutView = document().layoutView(); ObjectPaintProperties* layoutViewProperties = layoutView->objectPaintProperties(); EXPECT_EQ(nullptr, layoutViewProperties); }
TEST_F(PaintPropertyTreeBuilderTest, Perspective) { loadTestData("perspective.html"); Element* perspective = document().getElementById("perspective"); ObjectPaintProperties* perspectiveProperties = perspective->layoutObject()->objectPaintProperties(); EXPECT_EQ(TransformationMatrix().applyPerspective(100), perspectiveProperties->perspective()->matrix()); // The perspective origin is the center of the border box plus accumulated paint offset. EXPECT_EQ(FloatPoint3D(250, 250, 0), perspectiveProperties->perspective()->origin()); EXPECT_EQ(document().view()->scrollTranslation(), perspectiveProperties->perspective()->parent()); // Adding perspective doesn't clear paint offset. The paint offset will be passed down to children. Element* inner = document().getElementById("inner"); ObjectPaintProperties* innerProperties = inner->layoutObject()->objectPaintProperties(); EXPECT_EQ(TransformationMatrix().translate(50, 100), innerProperties->paintOffsetTranslation()->matrix()); EXPECT_EQ(perspectiveProperties->perspective(), innerProperties->paintOffsetTranslation()->parent()); }
const bool Test_Matrix_TransformationMatrix() { const TVector3d kTranslate_d{1.0, 2.0, 3.0}; const TVector3d kAxis_d = Normalize(TVector3d(), TVector3d{1.0, 1.0, 1.0}); const double kdAngle = s_kdTau / 8.0; const TVector4d kQuatOrient_d = AxisAngleQuaternion(TVector4d(), kAxis_d, kdAngle); const double kdScale = 2.0; const TMatrix4d kTranslation_d = TranslationMatrix(TMatrix4d(), kTranslate_d); const TMatrix4d kOrientation_d = RotationMatrix(TMatrix4d(), kQuatOrient_d); const TMatrix4d kScaling_d = ScalingMatrix(TMatrix4d(), kdScale, kdScale, kdScale); const TMatrix4d kTransformA_d = Multiply(TMatrix4d(), kScaling_d, kOrientation_d); const TMatrix4d kTransformB_d = Multiply(TMatrix4d(), kTranslation_d, kTransformA_d); const TVector3d kBasisX_d = QuaternionRotate(TVector3d(), TVector3d{kdScale, 0.0, 0.0}, kQuatOrient_d); const TVector3d kBasisY_d = QuaternionRotate(TVector3d(), TVector3d{0.0, kdScale, 0.0}, kQuatOrient_d); const TVector3d kBasisZ_d = QuaternionRotate(TVector3d(), TVector3d{0.0, 0.0, kdScale}, kQuatOrient_d); const TMatrix4d kTransformC_d = TransformationMatrix(TMatrix4d(), kBasisX_d, kBasisY_d, kBasisZ_d, kTranslate_d); const bool kbPass_d = Equal(kTransformC_d, kTransformB_d, s_kdEpsilon); // const TVector3f kTranslate_f{1.0f, 2.0f, 3.0f}; const TVector3f kAxis_f = Normalize(TVector3f(), TVector3f{1.0f, 1.0f, 1.0f}); const float kfAngle = s_kfTau / 8.0f; const TVector4f kQuatOrient_f = AxisAngleQuaternion(TVector4f(), kAxis_f, kfAngle); const float kfScale = 2.0f; const TMatrix4f kTranslation_f = TranslationMatrix(TMatrix4f(), kTranslate_f); const TMatrix4f kOrientation_f = RotationMatrix(TMatrix4f(), kQuatOrient_f); const TMatrix4f kScaling_f = ScalingMatrix(TMatrix4f(), kfScale, kfScale, kfScale); const TMatrix4f kTransformA_f = Multiply(TMatrix4f(), kScaling_f, kOrientation_f); const TMatrix4f kTransformB_f = Multiply(TMatrix4f(), kTranslation_f, kTransformA_f); const TVector3f kBasisX_f = QuaternionRotate(TVector3f(), TVector3f{kfScale, 0.0f, 0.0f}, kQuatOrient_f); const TVector3f kBasisY_f = QuaternionRotate(TVector3f(), TVector3f{0.0f, kfScale, 0.0f}, kQuatOrient_f); const TVector3f kBasisZ_f = QuaternionRotate(TVector3f(), TVector3f{0.0f, 0.0f, kfScale}, kQuatOrient_f); const TMatrix4f kTransformC_f = TransformationMatrix(TMatrix4f(), kBasisX_f, kBasisY_f, kBasisZ_f, kTranslate_f); const bool kbPass_f = Equal(kTransformC_f, kTransformB_f, s_kfEpsilon); return(kbPass_d && kbPass_f); }
void CoordinatedGraphicsScene::paintToCurrentGLContext(const TransformationMatrix& matrix, float opacity, const FloatRect& clipRect, TextureMapper::PaintFlags PaintFlags) { if (!m_textureMapper) { m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode); static_cast<TextureMapperGL*>(m_textureMapper.get())->setEnableEdgeDistanceAntialiasing(true); } ASSERT(m_textureMapper->accelerationMode() == TextureMapper::OpenGLMode); syncRemoteContent(); adjustPositionForFixedLayers(); TextureMapperLayer* currentRootLayer = rootLayer(); if (!currentRootLayer) return; TextureMapperLayer* layer = currentRootLayer; if (!layer) return; layer->setTextureMapper(m_textureMapper.get()); layer->applyAnimationsRecursively(); m_textureMapper->beginPainting(PaintFlags); m_textureMapper->beginClip(TransformationMatrix(), clipRect); if (m_setDrawsBackground) { RGBA32 rgba = makeRGBA32FromFloats(m_backgroundColor.red(), m_backgroundColor.green(), m_backgroundColor.blue(), m_backgroundColor.alpha() * opacity); m_textureMapper->drawSolidColor(clipRect, TransformationMatrix(), Color(rgba)); } if (currentRootLayer->opacity() != opacity || currentRootLayer->transform() != matrix) { currentRootLayer->setOpacity(opacity); currentRootLayer->setTransform(matrix); } layer->paint(); m_fpsCounter.updateFPSAndDisplay(m_textureMapper.get(), clipRect.location(), matrix); m_textureMapper->endClip(); m_textureMapper->endPainting(); if (layer->descendantsOrSelfHaveRunningAnimations()) dispatchOnMainThread(bind(&CoordinatedGraphicsScene::updateViewport, this)); }
WebBitmap* Frame::imageFromRect(const FloatRect& rect) const { // We should not try to create a bitmap of zero height or width as it is not supported. IntRect irect(rect); if(irect.size().width() == 0 || irect.size().height() == 0) return NULL; FrameLoaderClientApollo* const clientApollo = FrameLoaderClientApollo::clientApollo(this); WebHost* webHost = clientApollo->webHost(); ASSERT(webHost); WebBitmap* resultBitmap = webHost->m_pVTable->createBitmap(webHost, irect.size().width(), irect.size().height()); // clear pixels with transparent black (0) void *pixelData = resultBitmap->m_pVTable->getPixelData(resultBitmap); unsigned long stride = resultBitmap->m_pVTable->getStride(resultBitmap); memset( pixelData, 0, stride * irect.height() ); // now, paint the selection in a graphics context WebIntRect sourceRect; sourceRect.m_left = 0; sourceRect.m_top = 0; sourceRect.m_right = irect.width(); sourceRect.m_bottom = irect.height(); GraphicsContext gc (resultBitmap,&sourceRect); IntSize offset = view()->scrollOffset(); irect.move(-offset.width(), -offset.height()); irect = view()->convertToContainingWindow(irect); #if OS(WINDOWS) || OS(DARWIN) // changing origin from top-left to bottom-left gc.concatCTM(TransformationMatrix(1, 0, 0, -1, 0, irect.height()).toAffineTransform()); #endif // this transformation moves the clip into the origin of the user space gc.concatCTM(TransformationMatrix().translate(-irect.x(), -irect.y()).toAffineTransform()); view()->paint(&gc,irect); return resultBitmap; }
TransformationMatrix TransformationMatrix::rectToRect(const FloatRect& from, const FloatRect& to) { ASSERT(!from.isEmpty()); return TransformationMatrix(to.width() / from.width(), 0, 0, to.height() / from.height(), to.x() - from.x(), to.y() - from.y()); }
TEST_F(PaintPropertyTreeBuilderTest, RelativePositionInline) { loadTestData("relative-position-inline.html"); Element* inlineBlock = document().getElementById("inline-block"); ObjectPaintProperties* inlineBlockProperties = inlineBlock->layoutObject()->objectPaintProperties(); EXPECT_EQ(TransformationMatrix().translate(135, 490), inlineBlockProperties->paintOffsetTranslation()->matrix()); EXPECT_EQ(document().view()->scrollTranslation(), inlineBlockProperties->paintOffsetTranslation()->parent()); }
CSSMatrix* CSSMatrix::translate(double x, double y, double z) const { if (std::isnan(x)) x = 0; if (std::isnan(y)) y = 0; if (std::isnan(z)) z = 0; return CSSMatrix::create( TransformationMatrix(*m_matrix).translate3d(x, y, z)); }
TransformationMatrix GraphicsContext::getCTM() const { const SkMatrix& m = platformContext()->canvas()->getTotalMatrix(); return TransformationMatrix(SkScalarToDouble(m.getScaleX()), // a SkScalarToDouble(m.getSkewY()), // b SkScalarToDouble(m.getSkewX()), // c SkScalarToDouble(m.getScaleY()), // d SkScalarToDouble(m.getTranslateX()), // e SkScalarToDouble(m.getTranslateY())); // f }
CSSMatrix* CSSMatrix::scale(double scaleX, double scaleY, double scaleZ) const { if (std::isnan(scaleX)) scaleX = 1; if (std::isnan(scaleY)) scaleY = scaleX; if (std::isnan(scaleZ)) scaleZ = 1; return CSSMatrix::create( TransformationMatrix(*m_matrix).scale3d(scaleX, scaleY, scaleZ)); }
TransformationMatrix SVGFitToViewBox::viewBoxToViewTransform(float viewWidth, float viewHeight) const { FloatRect viewBoxRect = viewBox(); if (!viewBoxRect.width() || !viewBoxRect.height()) return TransformationMatrix(); return preserveAspectRatio()->getCTM(viewBoxRect.x(), viewBoxRect.y(), viewBoxRect.width(), viewBoxRect.height(), 0, 0, viewWidth, viewHeight); }
void TextureMapperLayer::computePatternTransformIfNeeded() { if (!m_patternTransformDirty) return; m_patternTransformDirty = false; m_patternTransform = TransformationMatrix::rectToRect(FloatRect(FloatPoint::zero(), m_state.contentsTileSize), FloatRect(FloatPoint::zero(), m_state.contentsRect.size())) .multiply(TransformationMatrix().translate(m_state.contentsTilePhase.width() / m_state.contentsRect.width(), m_state.contentsTilePhase.height() / m_state.contentsRect.height())); }
PassRefPtrWillBeRawPtr<CSSMatrix> CSSMatrix::translate(double x, double y, double z) const { if (std::isnan(x)) x = 0; if (std::isnan(y)) y = 0; if (std::isnan(z)) z = 0; return CSSMatrix::create(TransformationMatrix(m_matrix).translate3d(x, y, z)); }
PassRefPtrWillBeRawPtr<CSSMatrix> CSSMatrix::scale(double scaleX, double scaleY, double scaleZ) const { if (std::isnan(scaleX)) scaleX = 1; if (std::isnan(scaleY)) scaleY = scaleX; if (std::isnan(scaleZ)) scaleZ = 1; return CSSMatrix::create(TransformationMatrix(m_matrix).scale3d(scaleX, scaleY, scaleZ)); }