bool sk_path_get_bounds(const sk_path_t* cpath, sk_rect_t* crect) { const SkPath& path = AsPath(*cpath); if (path.isEmpty()) { if (crect) { *crect = ToRect(SkRect::MakeEmpty()); } return false; } if (crect) { *crect = ToRect(path.getBounds()); } return true; }
NS_IMETHODIMP ImageBitmapRenderingContext::Redraw(const gfxRect& aDirty) { if (!mCanvasElement) { return NS_OK; } mozilla::gfx::Rect rect = ToRect(aDirty); mCanvasElement->InvalidateCanvasContent(&rect); return NS_OK; }
void Compositor::DrawDiagnostics(DiagnosticFlags aFlags, const nsIntRegion& aVisibleRegion, const gfx::Rect& aClipRect, const gfx::Matrix4x4& aTransform) { if (!ShouldDrawDiagnostics(aFlags)) { return; } if (aVisibleRegion.GetNumRects() > 1) { nsIntRegionRectIterator screenIter(aVisibleRegion); while (const nsIntRect* rect = screenIter.Next()) { DrawDiagnostics(aFlags | DIAGNOSTIC_REGION_RECT, ToRect(*rect), aClipRect, aTransform); } } DrawDiagnostics(aFlags, ToRect(aVisibleRegion.GetBounds()), aClipRect, aTransform); }
Rect PathD2D::GetBounds(const Matrix &aTransform) const { D2D1_RECT_F d2dBounds; HRESULT hr = mGeometry->GetBounds(D2DMatrix(aTransform), &d2dBounds); Rect bounds = ToRect(d2dBounds); if (FAILED(hr) || !bounds.IsFinite()) { gfxWarning() << "Failed to get stroked bounds for path. Code: " << hexa(hr); return Rect(); } return bounds; }
Rect PathD2D::GetStrokedBounds(const StrokeOptions &aStrokeOptions, const Matrix &aTransform) const { D2D1_RECT_F d2dBounds; RefPtr<ID2D1StrokeStyle> strokeStyle = CreateStrokeStyleForOptions(aStrokeOptions); HRESULT hr = mGeometry->GetWidenedBounds(aStrokeOptions.mLineWidth, strokeStyle, D2DMatrix(aTransform), &d2dBounds); Rect bounds = ToRect(d2dBounds); if (FAILED(hr) || !bounds.IsFinite()) { gfxWarning() << "Failed to get stroked bounds for path. Code: " << hexa(hr); return Rect(); } return bounds; }
static void SubtractTransformedRegion(nsIntRegion& aRegion, const nsIntRegion& aRegionToSubtract, const Matrix4x4& aTransform) { if (aRegionToSubtract.IsEmpty()) { return; } // For each rect in the region, find out its bounds in screen space and // subtract it from the screen region. nsIntRegionRectIterator it(aRegionToSubtract); while (const IntRect* rect = it.Next()) { Rect incompleteRect = aTransform.TransformBounds(ToRect(*rect)); aRegion.Sub(aRegion, IntRect(incompleteRect.x, incompleteRect.y, incompleteRect.width, incompleteRect.height)); } }
void BasicCompositor::EndFrame() { // Pop aClipRectIn/bounds rect mRenderTarget->mDrawTarget->PopClip(); if (gfxPrefs::WidgetUpdateFlashing()) { float r = float(rand()) / RAND_MAX; float g = float(rand()) / RAND_MAX; float b = float(rand()) / RAND_MAX; // We're still clipped to mInvalidRegion, so just fill the bounds. mRenderTarget->mDrawTarget->FillRect(ToRect(mInvalidRegion.GetBounds()), ColorPattern(Color(r, g, b, 0.2f))); } // Pop aInvalidregion mRenderTarget->mDrawTarget->PopClip(); // Note: Most platforms require us to buffer drawing to the widget surface. // That's why we don't draw to mDrawTarget directly. RefPtr<SourceSurface> source = mRenderTarget->mDrawTarget->Snapshot(); RefPtr<DrawTarget> dest(mTarget ? mTarget : mDrawTarget); nsIntPoint offset = mTarget ? mTargetBounds.TopLeft() : nsIntPoint(); // The source DrawTarget is clipped to the invalidation region, so we have // to copy the individual rectangles in the region or else we'll draw blank // pixels. nsIntRegionRectIterator iter(mInvalidRegion); for (const IntRect *r = iter.Next(); r; r = iter.Next()) { dest->CopySurface(source, IntRect(r->x - mInvalidRect.x, r->y - mInvalidRect.y, r->width, r->height), IntPoint(r->x - offset.x, r->y - offset.y)); } if (!mTarget) { mWidget->EndRemoteDrawingInRegion(mDrawTarget, mInvalidRegion); } mDrawTarget = nullptr; mRenderTarget = nullptr; }
Rect XMLElement::GetRect(const ea::string& name) const { return ToRect(GetAttribute(name)); }
sk_rect_t sk_picture_get_bounds(sk_picture_t* cpic) { return ToRect(AsPicture(cpic)->cullRect()); }
Rect ToRect(const String& source) { return ToRect(source.CString()); }
void Variant::FromString(VariantType type, const char* value) { switch (type) { case VAR_INT: *this = ToInt(value); break; case VAR_INT64: *this = ToInt64(value); break; case VAR_BOOL: *this = ToBool(value); break; case VAR_FLOAT: *this = ToFloat(value); break; case VAR_VECTOR2: *this = ToVector2(value); break; case VAR_VECTOR3: *this = ToVector3(value); break; case VAR_VECTOR4: *this = ToVector4(value); break; case VAR_QUATERNION: *this = ToQuaternion(value); break; case VAR_COLOR: *this = ToColor(value); break; case VAR_STRING: *this = value; break; case VAR_BUFFER: { SetType(VAR_BUFFER); PODVector<unsigned char>& buffer = *(reinterpret_cast<PODVector<unsigned char>*>(&value_)); StringToBuffer(buffer, value); } break; case VAR_VOIDPTR: // From string to void pointer not supported, set to null *this = (void*)0; break; case VAR_RESOURCEREF: { StringVector values = String::Split(value, ';'); if (values.Size() == 2) { SetType(VAR_RESOURCEREF); ResourceRef& ref = *(reinterpret_cast<ResourceRef*>(&value_)); ref.type_ = values[0]; ref.name_ = values[1]; } } break; case VAR_RESOURCEREFLIST: { StringVector values = String::Split(value, ';', true); if (values.Size() >= 1) { SetType(VAR_RESOURCEREFLIST); ResourceRefList& refList = *(reinterpret_cast<ResourceRefList*>(&value_)); refList.type_ = values[0]; refList.names_.Resize(values.Size() - 1); for (unsigned i = 1; i < values.Size(); ++i) refList.names_[i - 1] = values[i]; } } break; case VAR_INTRECT: *this = ToIntRect(value); break; case VAR_INTVECTOR2: *this = ToIntVector2(value); break; case VAR_INTVECTOR3: *this = ToIntVector3(value); break; case VAR_PTR: // From string to RefCounted pointer not supported, set to null *this = (RefCounted*)0; break; case VAR_MATRIX3: *this = ToMatrix3(value); break; case VAR_MATRIX3X4: *this = ToMatrix3x4(value); break; case VAR_MATRIX4: *this = ToMatrix4(value); break; case VAR_DOUBLE: *this = ToDouble(value); break; case VAR_RECT: *this = ToRect(value); break; default: SetType(VAR_NONE); } }
void BasicCompositor::DrawQuad(const gfx::Rect& aRect, const gfx::Rect& aClipRect, const EffectChain &aEffectChain, gfx::Float aOpacity, const gfx::Matrix4x4& aTransform, const gfx::Rect& aVisibleRect) { RefPtr<DrawTarget> buffer = mRenderTarget->mDrawTarget; // For 2D drawing, |dest| and |buffer| are the same surface. For 3D drawing, // |dest| is a temporary surface. RefPtr<DrawTarget> dest = buffer; buffer->PushClipRect(aClipRect); AutoRestoreTransform autoRestoreTransform(dest); Matrix newTransform; Rect transformBounds; gfx3DMatrix new3DTransform; IntPoint offset = mRenderTarget->GetOrigin(); if (aTransform.Is2D()) { newTransform = aTransform.As2D(); } else { // Create a temporary surface for the transform. dest = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(RoundOut(aRect).Size(), SurfaceFormat::B8G8R8A8); if (!dest) { return; } dest->SetTransform(Matrix::Translation(-aRect.x, -aRect.y)); // Get the bounds post-transform. new3DTransform = To3DMatrix(aTransform); gfxRect bounds = new3DTransform.TransformBounds(ThebesRect(aRect)); bounds.IntersectRect(bounds, gfxRect(offset.x, offset.y, buffer->GetSize().width, buffer->GetSize().height)); transformBounds = ToRect(bounds); transformBounds.RoundOut(); // Propagate the coordinate offset to our 2D draw target. newTransform = Matrix::Translation(transformBounds.x, transformBounds.y); // When we apply the 3D transformation, we do it against a temporary // surface, so undo the coordinate offset. new3DTransform = gfx3DMatrix::Translation(aRect.x, aRect.y, 0) * new3DTransform; } newTransform.PostTranslate(-offset.x, -offset.y); buffer->SetTransform(newTransform); RefPtr<SourceSurface> sourceMask; Matrix maskTransform; if (aEffectChain.mSecondaryEffects[EffectTypes::MASK]) { EffectMask *effectMask = static_cast<EffectMask*>(aEffectChain.mSecondaryEffects[EffectTypes::MASK].get()); sourceMask = effectMask->mMaskTexture->AsSourceBasic()->GetSurface(dest); MOZ_ASSERT(effectMask->mMaskTransform.Is2D(), "How did we end up with a 3D transform here?!"); MOZ_ASSERT(!effectMask->mIs3D); maskTransform = effectMask->mMaskTransform.As2D(); maskTransform.PreTranslate(-offset.x, -offset.y); } switch (aEffectChain.mPrimaryEffect->mType) { case EffectTypes::SOLID_COLOR: { EffectSolidColor* effectSolidColor = static_cast<EffectSolidColor*>(aEffectChain.mPrimaryEffect.get()); FillRectWithMask(dest, aRect, effectSolidColor->mColor, DrawOptions(aOpacity), sourceMask, &maskTransform); break; } case EffectTypes::RGB: { TexturedEffect* texturedEffect = static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get()); TextureSourceBasic* source = texturedEffect->mTexture->AsSourceBasic(); if (texturedEffect->mPremultiplied) { DrawSurfaceWithTextureCoords(dest, aRect, source->GetSurface(dest), texturedEffect->mTextureCoords, texturedEffect->mFilter, aOpacity, sourceMask, &maskTransform); } else { RefPtr<DataSourceSurface> srcData = source->GetSurface(dest)->GetDataSurface(); // Yes, we re-create the premultiplied data every time. // This might be better with a cache, eventually. RefPtr<DataSourceSurface> premultData = gfxUtils::CreatePremultipliedDataSurface(srcData); DrawSurfaceWithTextureCoords(dest, aRect, premultData, texturedEffect->mTextureCoords, texturedEffect->mFilter, aOpacity, sourceMask, &maskTransform); } break; } case EffectTypes::YCBCR: { NS_RUNTIMEABORT("Can't (easily) support component alpha with BasicCompositor!"); break; } case EffectTypes::RENDER_TARGET: { EffectRenderTarget* effectRenderTarget = static_cast<EffectRenderTarget*>(aEffectChain.mPrimaryEffect.get()); RefPtr<BasicCompositingRenderTarget> surface = static_cast<BasicCompositingRenderTarget*>(effectRenderTarget->mRenderTarget.get()); RefPtr<SourceSurface> sourceSurf = surface->mDrawTarget->Snapshot(); DrawSurfaceWithTextureCoords(dest, aRect, sourceSurf, effectRenderTarget->mTextureCoords, effectRenderTarget->mFilter, aOpacity, sourceMask, &maskTransform); break; } case EffectTypes::COMPONENT_ALPHA: { NS_RUNTIMEABORT("Can't (easily) support component alpha with BasicCompositor!"); break; } default: { NS_RUNTIMEABORT("Invalid effect type!"); break; } } if (!aTransform.Is2D()) { dest->Flush(); RefPtr<SourceSurface> snapshot = dest->Snapshot(); RefPtr<DataSourceSurface> source = snapshot->GetDataSurface(); RefPtr<DataSourceSurface> temp = Factory::CreateDataSourceSurface(RoundOut(transformBounds).Size(), SurfaceFormat::B8G8R8A8 #ifdef MOZ_ENABLE_SKIA , true #endif ); if (NS_WARN_IF(!temp)) { buffer->PopClip(); return; } Transform(temp, source, new3DTransform, transformBounds.TopLeft()); transformBounds.MoveTo(0, 0); buffer->DrawSurface(temp, transformBounds, transformBounds); } buffer->PopClip(); }
/** * @param aXSide LEFT means we draw from the left side of the buffer (which * is drawn on the right side of mBufferRect). RIGHT means we draw from * the right side of the buffer (which is drawn on the left side of * mBufferRect). * @param aYSide TOP means we draw from the top side of the buffer (which * is drawn on the bottom side of mBufferRect). BOTTOM means we draw from * the bottom side of the buffer (which is drawn on the top side of * mBufferRect). */ void RotatedBuffer::DrawBufferQuadrant(gfx::DrawTarget* aTarget, XSide aXSide, YSide aYSide, ContextSource aSource, float aOpacity, gfx::CompositionOp aOperator, gfx::SourceSurface* aMask, const gfx::Matrix* aMaskTransform) const { // The rectangle that we're going to fill. Basically we're going to // render the buffer at mBufferRect + quadrantTranslation to get the // pixels in the right place, but we're only going to paint within // mBufferRect nsIntRect quadrantRect = GetQuadrantRectangle(aXSide, aYSide); nsIntRect fillRect; if (!fillRect.IntersectRect(mBufferRect, quadrantRect)) return; gfx::Point quadrantTranslation(quadrantRect.x, quadrantRect.y); MOZ_ASSERT(aOperator == OP_OVER || aOperator == OP_SOURCE); // direct2d is much slower when using OP_SOURCE so use OP_OVER and // (maybe) a clear instead. Normally we need to draw in a single operation // (to avoid flickering) but direct2d is ok since it defers rendering. // We should try abstract this logic in a helper when we have other use // cases. if (aTarget->GetType() == BACKEND_DIRECT2D && aOperator == OP_SOURCE) { aOperator = OP_OVER; if (mDTBuffer->GetFormat() == FORMAT_B8G8R8A8) { aTarget->ClearRect(ToRect(fillRect)); } } RefPtr<gfx::SourceSurface> snapshot; if (aSource == BUFFER_BLACK) { snapshot = mDTBuffer->Snapshot(); } else { MOZ_ASSERT(aSource == BUFFER_WHITE); snapshot = mDTBufferOnWhite->Snapshot(); } if (aOperator == OP_SOURCE) { // OP_SOURCE is unbounded in Azure, and we really don't want that behaviour here. // We also can't do a ClearRect+FillRect since we need the drawing to happen // as an atomic operation (to prevent flickering). aTarget->PushClipRect(gfx::Rect(fillRect.x, fillRect.y, fillRect.width, fillRect.height)); } if (aMask) { // Transform from user -> buffer space. Matrix transform; transform.Translate(quadrantTranslation.x, quadrantTranslation.y); #ifdef MOZ_GFX_OPTIMIZE_MOBILE SurfacePattern source(snapshot, EXTEND_CLAMP, transform, FILTER_POINT); #else SurfacePattern source(snapshot, EXTEND_CLAMP, transform); #endif Matrix oldTransform = aTarget->GetTransform(); aTarget->SetTransform(*aMaskTransform); aTarget->MaskSurface(source, aMask, Point(0, 0), DrawOptions(aOpacity, aOperator)); aTarget->SetTransform(oldTransform); } else { #ifdef MOZ_GFX_OPTIMIZE_MOBILE DrawSurfaceOptions options(FILTER_POINT); #else DrawSurfaceOptions options; #endif aTarget->DrawSurface(snapshot, ToRect(fillRect), GetSourceRectangle(aXSide, aYSide), options, DrawOptions(aOpacity, aOperator)); } if (aOperator == OP_SOURCE) { aTarget->PopClip(); } aTarget->Flush(); }
void CanvasLayerD3D10::UpdateSurface() { if (!IsDirty()) return; Painted(); if (mDrawTarget) { mDrawTarget->Flush(); } else if (mIsD2DTexture) { return; } if (!mTexture) { return; } if (mGLContext) { SharedSurface_GL* surf = mGLContext->RequestFrame(); if (!surf) { return; } switch (surf->Type()) { case SharedSurfaceType::EGLSurfaceANGLE: { SharedSurface_ANGLEShareHandle* shareSurf = SharedSurface_ANGLEShareHandle::Cast(surf); mSRView = shareSurf->GetSRV(); return; } case SharedSurfaceType::Basic: { SharedSurface_Basic* shareSurf = SharedSurface_Basic::Cast(surf); // WebGL reads entire surface. D3D10_MAPPED_TEXTURE2D map; HRESULT hr = mTexture->Map(0, D3D10_MAP_WRITE_DISCARD, 0, &map); if (FAILED(hr)) { NS_WARNING("Failed to map CanvasLayer texture."); return; } DataSourceSurface* frameData = shareSurf->GetData(); // Scope for DrawTarget, so it's destroyed before Unmap. { IntSize boundsSize(mBounds.width, mBounds.height); RefPtr<DrawTarget> mapDt = Factory::CreateDrawTargetForData(BackendType::CAIRO, (uint8_t*)map.pData, boundsSize, map.RowPitch, SurfaceFormat::B8G8R8A8); Rect drawRect(0, 0, frameData->GetSize().width, frameData->GetSize().height); mapDt->DrawSurface(frameData, drawRect, drawRect, DrawSurfaceOptions(), DrawOptions(1.0F, CompositionOp::OP_SOURCE)); mapDt->Flush(); } mTexture->Unmap(0); mSRView = mUploadSRView; break; } default: MOZ_CRASH("Unhandled SharedSurfaceType."); } } else if (mSurface) { D3D10_MAPPED_TEXTURE2D map; HRESULT hr = mTexture->Map(0, D3D10_MAP_WRITE_DISCARD, 0, &map); if (FAILED(hr)) { NS_WARNING("Failed to lock CanvasLayer texture."); return; } RefPtr<DrawTarget> destTarget = Factory::CreateDrawTargetForD3D10Texture(mTexture, SurfaceFormat::R8G8B8A8); Rect r(Point(0, 0), ToRect(mBounds).Size()); destTarget->DrawSurface(mSurface, r, r, DrawSurfaceOptions(), DrawOptions(1.0F, CompositionOp::OP_SOURCE)); mTexture->Unmap(0); mSRView = mUploadSRView; } }