void DrawTargetD2D1::PushClipRect(const Rect &aRect) { if (!mTransform.IsRectilinear()) { // Whoops, this isn't a rectangle in device space, Direct2D will not deal // with this transform the way we want it to. // See remarks: http://msdn.microsoft.com/en-us/library/dd316860%28VS.85%29.aspx RefPtr<PathBuilder> pathBuilder = CreatePathBuilder(); pathBuilder->MoveTo(aRect.TopLeft()); pathBuilder->LineTo(aRect.TopRight()); pathBuilder->LineTo(aRect.BottomRight()); pathBuilder->LineTo(aRect.BottomLeft()); pathBuilder->Close(); RefPtr<Path> path = pathBuilder->Finish(); return PushClip(path); } PushedClip clip; Rect rect = mTransform.TransformBounds(aRect); IntRect intRect; clip.mIsPixelAligned = rect.ToIntRect(&intRect); // Do not store the transform, just store the device space rectangle directly. clip.mBounds = D2DRect(rect); mPushedClips.push_back(clip); mDC->SetTransform(D2D1::IdentityMatrix()); mTransformDirty = true; if (mClipsArePushed) { mDC->PushAxisAlignedClip(clip.mBounds, clip.mIsPixelAligned ? D2D1_ANTIALIAS_MODE_ALIASED : D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); } }
void DrawTargetD2D1::MaskSurface(const Pattern &aSource, SourceSurface *aMask, Point aOffset, const DrawOptions &aOptions) { RefPtr<ID2D1Bitmap> bitmap; RefPtr<ID2D1Image> image = GetImageForSurface(aMask, ExtendMode::CLAMP); PrepareForDrawing(aOptions.mCompositionOp, aSource); // FillOpacityMask only works if the antialias mode is MODE_ALIASED mDC->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED); IntSize size = aMask->GetSize(); Rect maskRect = Rect(0.f, 0.f, Float(size.width), Float(size.height)); image->QueryInterface((ID2D1Bitmap**)&bitmap); if (!bitmap) { gfxWarning() << "FillOpacityMask only works with Bitmap source surfaces."; return; } Rect dest = Rect(aOffset.x, aOffset.y, Float(size.width), Float(size.height)); RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aSource, aOptions.mAlpha); mDC->FillOpacityMask(bitmap, brush, D2D1_OPACITY_MASK_CONTENT_GRAPHICS, D2DRect(dest), D2DRect(maskRect)); mDC->SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); FinalizeDrawing(aOptions.mCompositionOp, aSource); }
void DrawTargetD2D1::Mask(const Pattern &aSource, const Pattern &aMask, const DrawOptions &aOptions) { PrepareForDrawing(aOptions.mCompositionOp, aSource); RefPtr<ID2D1Brush> source = CreateBrushForPattern(aSource, aOptions.mAlpha); RefPtr<ID2D1Brush> mask = CreateBrushForPattern(aMask, 1.0f); mDC->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), nullptr, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, D2D1::IdentityMatrix(), 1.0f, mask), nullptr); Rect rect(0, 0, (Float)mSize.width, (Float)mSize.height); Matrix mat = mTransform; mat.Invert(); mDC->FillRectangle(D2DRect(mat.TransformBounds(rect)), source); mDC->PopLayer(); FinalizeDrawing(aOptions.mCompositionOp, aSource); }
void FilterNodeD2D1::SetAttribute(uint32_t aIndex, const Rect &aValue) { UINT32 input = GetD2D1PropForAttribute(mType, aIndex); MOZ_ASSERT(input < mEffect->GetPropertyCount()); mEffect->SetValue(input, D2DRect(aValue)); }
void DrawTargetD2D1::ClearRect(const Rect &aRect) { MarkChanged(); mDC->PushAxisAlignedClip(D2DRect(aRect), D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); mDC->Clear(); mDC->PopAxisAlignedClip(); }
void DrawTargetD2D1::DrawSurface(SourceSurface *aSurface, const Rect &aDest, const Rect &aSource, const DrawSurfaceOptions &aSurfOptions, const DrawOptions &aOptions) { RefPtr<ID2D1Image> image = GetImageForSurface(aSurface, ExtendMode::CLAMP); if (!image) { gfxWarning() << *this << ": Unable to get D2D image for surface."; return; } PrepareForDrawing(aOptions.mCompositionOp, ColorPattern(Color())); D2D1_RECT_F samplingBounds; if (aSurfOptions.mSamplingBounds == SamplingBounds::BOUNDED) { samplingBounds = D2DRect(aSource); } else { samplingBounds = D2D1::RectF(0, 0, Float(aSurface->GetSize().width), Float(aSurface->GetSize().height)); } Float xScale = aDest.width / aSource.width; Float yScale = aDest.height / aSource.height; RefPtr<ID2D1ImageBrush> brush; // Here we scale the source pattern up to the size and position where we want // it to be. Matrix transform; transform.Translate(aDest.x, aDest.y); transform.Scale(xScale, yScale); mDC->CreateImageBrush(image, D2D1::ImageBrushProperties(samplingBounds), D2D1::BrushProperties(aOptions.mAlpha, D2DMatrix(transform)), byRef(brush)); mDC->FillRectangle(D2DRect(aDest), brush); FinalizeDrawing(aOptions.mCompositionOp, ColorPattern(Color())); }
void DrawTargetD2D1::FillRect(const Rect &aRect, const Pattern &aPattern, const DrawOptions &aOptions) { PrepareForDrawing(aOptions.mCompositionOp, aPattern); RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha); mDC->FillRectangle(D2DRect(aRect), brush); FinalizeDrawing(aOptions.mCompositionOp, aPattern); }
void DrawTargetD2D1::StrokeRect(const Rect &aRect, const Pattern &aPattern, const StrokeOptions &aStrokeOptions, const DrawOptions &aOptions) { PrepareForDrawing(aOptions.mCompositionOp, aPattern); RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha); RefPtr<ID2D1StrokeStyle> strokeStyle = CreateStrokeStyleForOptions(aStrokeOptions); mDC->DrawRectangle(D2DRect(aRect), brush, aStrokeOptions.mLineWidth, strokeStyle); FinalizeDrawing(aOptions.mCompositionOp, aPattern); }
void DrawTargetD2D1::DrawFilter(FilterNode *aNode, const Rect &aSourceRect, const Point &aDestPoint, const DrawOptions &aOptions) { if (aNode->GetBackendType() != FILTER_BACKEND_DIRECT2D1_1) { gfxWarning() << *this << ": Incompatible filter passed to DrawFilter."; return; } PrepareForDrawing(aOptions.mCompositionOp, ColorPattern(Color())); mDC->DrawImage(static_cast<FilterNodeD2D1*>(aNode)->OutputEffect(), D2DPoint(aDestPoint), D2DRect(aSourceRect)); }