本文整理匯總了C++中DrawTarget類的典型用法代碼示例。如果您正苦於以下問題:C++ DrawTarget類的具體用法?C++ DrawTarget怎麽用?C++ DrawTarget使用的例子?那麽, 這裏精選的類代碼示例或許可以為您提供幫助。
在下文中一共展示了DrawTarget類的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的C++代碼示例。
示例1: NS_ASSERTION
CGContextRef
gfxQuartzNativeDrawing::BeginNativeDrawing()
{
NS_ASSERTION(!mCGContext, "BeginNativeDrawing called when drawing already in progress");
if (mContext->IsCairo()) {
// We're past that now. Any callers that still supply a Cairo context
// don't deserve native theming.
NS_WARNING("gfxQuartzNativeDrawing being used with a gfxContext that is not backed by a DrawTarget");
return nullptr;
}
DrawTarget *dt = mContext->GetDrawTarget();
if (dt->GetBackendType() != BackendType::COREGRAPHICS || dt->IsDualDrawTarget()) {
IntSize backingSize(NSToIntFloor(mNativeRect.width * mBackingScale),
NSToIntFloor(mNativeRect.height * mBackingScale));
if (backingSize.IsEmpty()) {
return nullptr;
}
mDrawTarget = Factory::CreateDrawTarget(BackendType::COREGRAPHICS, backingSize, SurfaceFormat::B8G8R8A8);
Matrix transform;
transform.Scale(mBackingScale, mBackingScale);
transform.Translate(-mNativeRect.x, -mNativeRect.y);
mDrawTarget->SetTransform(transform);
dt = mDrawTarget;
}
mCGContext = mBorrowedContext.Init(dt);
MOZ_ASSERT(mCGContext);
return mCGContext;
}
示例2: GetSurfaceForDescriptor
void
ClientLayerManager::MakeSnapshotIfRequired()
{
if (!mShadowTarget) {
return;
}
if (mWidget) {
if (CompositorChild* remoteRenderer = GetRemoteRenderer()) {
nsIntRect bounds;
mWidget->GetBounds(bounds);
IntSize widgetSize = bounds.Size().ToIntSize();
SurfaceDescriptor inSnapshot, snapshot;
if (mForwarder->AllocSurfaceDescriptor(widgetSize,
gfxContentType::COLOR_ALPHA,
&inSnapshot) &&
// The compositor will usually reuse |snapshot| and return
// it through |outSnapshot|, but if it doesn't, it's
// responsible for freeing |snapshot|.
remoteRenderer->SendMakeSnapshot(inSnapshot, &snapshot)) {
RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(snapshot);
DrawTarget* dt = mShadowTarget->GetDrawTarget();
Rect widgetRect(Point(0, 0), Size(widgetSize.width, widgetSize.height));
dt->DrawSurface(surf, widgetRect, widgetRect,
DrawSurfaceOptions(),
DrawOptions(1.0f, CompositionOp::OP_OVER));
}
if (IsSurfaceDescriptorValid(snapshot)) {
mForwarder->DestroySharedSurface(&snapshot);
}
}
}
mShadowTarget = nullptr;
}
示例3: RepeatOrStretchSurface
static void
RepeatOrStretchSurface(DrawTarget& aDT, SourceSurface* aSurface,
const Rect& aDest, const Rect& aSrc, Rect& aSkipRect)
{
if (aSkipRect.Contains(aDest)) {
return;
}
if ((!aDT.GetTransform().IsRectilinear() &&
aDT.GetBackendType() != BackendType::CAIRO) ||
(aDT.GetBackendType() == BackendType::DIRECT2D)) {
// Use stretching if possible, since it leads to less seams when the
// destination is transformed. However, don't do this if we're using cairo,
// because if cairo is using pixman it won't render anything for large
// stretch factors because pixman's internal fixed point precision is not
// high enough to handle those scale factors.
// Calling FillRect on a D2D backend with a repeating pattern is much slower
// than DrawSurface, so special case the D2D backend here.
aDT.DrawSurface(aSurface, aDest, aSrc);
return;
}
SurfacePattern pattern(aSurface, ExtendMode::REPEAT,
Matrix::Translation(aDest.TopLeft() - aSrc.TopLeft()),
Filter::GOOD, RoundedToInt(aSrc));
aDT.FillRect(aDest, pattern);
}
示例4: ToOutsideIntRect
void
ClientLayerManager::MakeSnapshotIfRequired()
{
if (!mShadowTarget) {
return;
}
if (mWidget) {
if (CompositorChild* remoteRenderer = GetRemoteRenderer()) {
nsIntRect bounds = ToOutsideIntRect(mShadowTarget->GetClipExtents());
SurfaceDescriptor inSnapshot;
if (!bounds.IsEmpty() &&
mForwarder->AllocSurfaceDescriptor(bounds.Size().ToIntSize(),
gfxContentType::COLOR_ALPHA,
&inSnapshot) &&
remoteRenderer->SendMakeSnapshot(inSnapshot, bounds)) {
RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(inSnapshot);
DrawTarget* dt = mShadowTarget->GetDrawTarget();
Rect dstRect(bounds.x, bounds.y, bounds.width, bounds.height);
Rect srcRect(0, 0, bounds.width, bounds.height);
dt->DrawSurface(surf, dstRect, srcRect,
DrawSurfaceOptions(),
DrawOptions(1.0f, CompositionOp::OP_OVER));
}
mForwarder->DestroySharedSurface(&inSnapshot);
}
}
mShadowTarget = nullptr;
}
示例5: GetFrameAndOffset
void nsCaret::PaintCaret(DrawTarget& aDrawTarget,
nsIFrame* aForFrame,
const nsPoint &aOffset)
{
int32_t contentOffset;
nsIFrame* frame = GetFrameAndOffset(GetSelectionInternal(),
mOverrideContent, mOverrideOffset, &contentOffset);
if (!frame) {
return;
}
NS_ASSERTION(frame == aForFrame, "We're referring different frame");
int32_t appUnitsPerDevPixel = frame->PresContext()->AppUnitsPerDevPixel();
nsRect caretRect;
nsRect hookRect;
ComputeCaretRects(frame, contentOffset, &caretRect, &hookRect);
Rect devPxCaretRect =
NSRectToSnappedRect(caretRect + aOffset, appUnitsPerDevPixel, aDrawTarget);
Rect devPxHookRect =
NSRectToSnappedRect(hookRect + aOffset, appUnitsPerDevPixel, aDrawTarget);
ColorPattern color(ToDeviceColor(frame->GetCaretColorAt(contentOffset)));
aDrawTarget.FillRect(devPxCaretRect, color);
if (!hookRect.IsEmpty()) {
aDrawTarget.FillRect(devPxHookRect, color);
}
}
示例6: path
already_AddRefed<Path>
nsSVGPathGeometryElement::GetOrBuildPath(const DrawTarget& aDrawTarget,
FillRule aFillRule)
{
// We only cache the path if it matches the backend used for screen painting:
bool cacheable = aDrawTarget.GetBackendType() ==
gfxPlatform::GetPlatform()->GetDefaultContentBackend();
// Checking for and returning mCachedPath before checking the pref means
// that the pref is only live on page reload (or app restart for SVG in
// chrome). The benefit is that we avoid causing a CPU memory cache miss by
// looking at the global variable that the pref's stored in.
if (cacheable && mCachedPath) {
if (aDrawTarget.GetBackendType() == mCachedPath->GetBackendType()) {
RefPtr<Path> path(mCachedPath);
return path.forget();
}
}
RefPtr<PathBuilder> builder = aDrawTarget.CreatePathBuilder(aFillRule);
RefPtr<Path> path = BuildPath(builder);
if (cacheable && NS_SVGPathCachingEnabled()) {
mCachedPath = path;
}
return path.forget();
}
示例7: ProcessReadback
virtual void ProcessReadback(gfx::DataSourceSurface *aSourceSurface)
{
SourceRotatedBuffer rotBuffer(aSourceSurface, nullptr, mBufferRect, mBufferRotation);
for (uint32_t i = 0; i < mReadbackUpdates.Length(); ++i) {
ReadbackProcessor::Update& update = mReadbackUpdates[i];
nsIntPoint offset = update.mLayer->GetBackgroundLayerOffset();
ReadbackSink* sink = update.mLayer->GetSink();
if (!sink) {
continue;
}
if (!aSourceSurface) {
sink->SetUnknown(update.mSequenceCounter);
continue;
}
nsRefPtr<gfxContext> ctx =
sink->BeginUpdate(update.mUpdateRect + offset, update.mSequenceCounter);
if (!ctx) {
continue;
}
DrawTarget* dt = ctx->GetDrawTarget();
dt->SetTransform(Matrix::Translation(offset.x, offset.y));
rotBuffer.DrawBufferWithRotation(dt, RotatedBuffer::BUFFER_BLACK);
update.mLayer->GetSink()->EndUpdate(ctx, update.mUpdateRect + offset);
}
}
示例8: StrokeSnappedEdgesOfRect
void
StrokeSnappedEdgesOfRect(const Rect& aRect, DrawTarget& aDrawTarget,
const ColorPattern& aColor,
const StrokeOptions& aStrokeOptions)
{
if (aRect.IsEmpty()) {
return;
}
Point p1 = aRect.TopLeft();
Point p2 = aRect.BottomLeft();
SnapLineToDevicePixelsForStroking(p1, p2, aDrawTarget);
aDrawTarget.StrokeLine(p1, p2, aColor, aStrokeOptions);
p1 = aRect.BottomLeft();
p2 = aRect.BottomRight();
SnapLineToDevicePixelsForStroking(p1, p2, aDrawTarget);
aDrawTarget.StrokeLine(p1, p2, aColor, aStrokeOptions);
p1 = aRect.TopLeft();
p2 = aRect.TopRight();
SnapLineToDevicePixelsForStroking(p1, p2, aDrawTarget);
aDrawTarget.StrokeLine(p1, p2, aColor, aStrokeOptions);
p1 = aRect.TopRight();
p2 = aRect.BottomRight();
SnapLineToDevicePixelsForStroking(p1, p2, aDrawTarget);
aDrawTarget.StrokeLine(p1, p2, aColor, aStrokeOptions);
}
示例9: pathRect
/***
* Blur an inset box shadow by doing:
* 1) Create a minimal box shadow path that creates a frame.
* 2) Draw the box shadow portion over the destination surface.
* 3) The "inset" part is created by a clip rect that properly clips
* the alpha mask so that it has clean edges. We still create the full
* proper alpha mask, but let the clip deal with the clean edges.
*
* All parameters should already be in device pixels.
*/
void
gfxAlphaBoxBlur::BlurInsetBox(gfxContext* aDestinationCtx,
const Rect aDestinationRect,
const Rect aShadowClipRect,
const gfxIntSize aBlurRadius,
const gfxIntSize aSpreadRadius,
const Color& aShadowColor,
bool aHasBorderRadius,
const RectCornerRadii& aInnerClipRadii,
const Rect aSkipRect)
{
if ((aBlurRadius.width <= 0 && aBlurRadius.height <= 0)) {
// The outer path must be rounded out
// If not blurring, we're done now.
Rect pathRect(aDestinationRect);
pathRect.RoundOut();
FillDestinationPath(aDestinationCtx, pathRect, aShadowClipRect,
aShadowColor, aHasBorderRadius, aInnerClipRadii);
return;
}
DrawTarget* destDrawTarget = aDestinationCtx->GetDrawTarget();
Rect outerRect;
Rect innerRect;
Margin pathMargins;
ComputeRectsForInsetBoxShadow(aBlurRadius, aSpreadRadius,
aDestinationRect, aShadowClipRect,
outerRect, innerRect,
pathMargins);
IntPoint topLeft;
RefPtr<SourceSurface> minInsetBlur = GetInsetBlur(outerRect, innerRect,
aBlurRadius, aSpreadRadius,
aInnerClipRadii, aShadowColor,
aHasBorderRadius,
topLeft, aDestinationCtx);
if (!minInsetBlur) {
return;
}
Rect destRectOuter(aDestinationRect);
destRectOuter.RoundIn();
Rect destRectInner(destRectOuter);
destRectInner.Deflate(pathMargins);
Rect srcRectOuter(outerRect);
srcRectOuter.MoveBy(abs(topLeft.x), abs(topLeft.y));
Rect srcRectInner(srcRectOuter);
srcRectInner.Deflate(pathMargins);
if (srcRectOuter.IsEqualInterior(srcRectInner)) {
destDrawTarget->DrawSurface(minInsetBlur, destRectOuter, srcRectOuter);
} else {
DrawBoxShadows(*destDrawTarget, minInsetBlur,
destRectOuter, destRectInner,
srcRectOuter, srcRectInner,
aSkipRect);
}
}
示例10: GetRoundOutDeviceClipExtents
void
gfxContext::PushGroupAndCopyBackground(gfxContentType content)
{
IntRect clipExtents;
if (mDT->GetFormat() != SurfaceFormat::B8G8R8X8) {
gfxRect clipRect = GetRoundOutDeviceClipExtents(this);
clipExtents = IntRect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
}
if ((mDT->GetFormat() == SurfaceFormat::B8G8R8X8 ||
mDT->GetOpaqueRect().Contains(clipExtents)) &&
!mDT->GetUserData(&sDontUseAsSourceKey)) {
DrawTarget *oldDT = mDT;
RefPtr<SourceSurface> source = mDT->Snapshot();
Point oldDeviceOffset = CurrentState().deviceOffset;
PushNewDT(gfxContentType::COLOR);
if (oldDT == mDT) {
// Creating new DT failed.
return;
}
Point offset = CurrentState().deviceOffset - oldDeviceOffset;
Rect surfRect(0, 0, Float(mDT->GetSize().width), Float(mDT->GetSize().height));
Rect sourceRect = surfRect + offset;
mDT->SetTransform(Matrix());
// XXX: It's really sad that we have to do this (for performance).
// Once DrawTarget gets a PushLayer API we can implement this within
// DrawTargetTiled.
if (source->GetType() == SurfaceType::TILED) {
SnapshotTiled *sourceTiled = static_cast<SnapshotTiled*>(source.get());
for (uint32_t i = 0; i < sourceTiled->mSnapshots.size(); i++) {
Rect tileSourceRect = sourceRect.Intersect(Rect(sourceTiled->mOrigins[i].x,
sourceTiled->mOrigins[i].y,
sourceTiled->mSnapshots[i]->GetSize().width,
sourceTiled->mSnapshots[i]->GetSize().height));
if (tileSourceRect.IsEmpty()) {
continue;
}
Rect tileDestRect = tileSourceRect - offset;
tileSourceRect -= sourceTiled->mOrigins[i];
mDT->DrawSurface(sourceTiled->mSnapshots[i], tileDestRect, tileSourceRect);
}
} else {
mDT->DrawSurface(source, surfRect, sourceRect);
}
mDT->SetOpaqueRect(oldDT->GetOpaqueRect());
PushClipsToDT(mDT);
mDT->SetTransform(GetDTTransform());
return;
}
PushGroup(content);
}
示例11: MOZ_ASSERT
DrawTarget*
ContentClientIncremental::BorrowDrawTargetForPainting(const PaintState& aPaintState,
RotatedContentBuffer::DrawIterator* aIter)
{
if (aPaintState.mMode == SurfaceMode::SURFACE_NONE) {
return nullptr;
}
if (aIter) {
if (aIter->mCount++ > 0) {
return nullptr;
}
aIter->mDrawRegion = aPaintState.mRegionToDraw;
}
DrawTarget* result = nullptr;
nsIntRect drawBounds = aPaintState.mRegionToDraw.GetBounds();
MOZ_ASSERT(!mLoanedDrawTarget);
// BeginUpdate is allowed to modify the given region,
// if it wants more to be repainted than we request.
if (aPaintState.mMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
nsIntRegion drawRegionCopy = aPaintState.mRegionToDraw;
RefPtr<DrawTarget> onBlack = GetUpdateSurface(BUFFER_BLACK, drawRegionCopy);
RefPtr<DrawTarget> onWhite = GetUpdateSurface(BUFFER_WHITE, aPaintState.mRegionToDraw);
if (onBlack && onWhite) {
NS_ASSERTION(aPaintState.mRegionToDraw == drawRegionCopy,
"BeginUpdate should always modify the draw region in the same way!");
FillSurface(onBlack, aPaintState.mRegionToDraw, nsIntPoint(drawBounds.x, drawBounds.y), gfxRGBA(0.0, 0.0, 0.0, 1.0));
FillSurface(onWhite, aPaintState.mRegionToDraw, nsIntPoint(drawBounds.x, drawBounds.y), gfxRGBA(1.0, 1.0, 1.0, 1.0));
mLoanedDrawTarget = Factory::CreateDualDrawTarget(onBlack, onWhite);
} else {
mLoanedDrawTarget = nullptr;
}
} else {
mLoanedDrawTarget = GetUpdateSurface(BUFFER_BLACK, aPaintState.mRegionToDraw);
}
if (!mLoanedDrawTarget) {
NS_WARNING("unable to get context for update");
return nullptr;
}
result = mLoanedDrawTarget;
mLoanedTransform = mLoanedDrawTarget->GetTransform();
mLoanedTransform.Translate(-drawBounds.x, -drawBounds.y);
result->SetTransform(mLoanedTransform);
mLoanedTransform.Translate(drawBounds.x, drawBounds.y);
if (mContentType == gfxContentType::COLOR_ALPHA) {
gfxUtils::ClipToRegion(result, aPaintState.mRegionToDraw);
nsIntRect bounds = aPaintState.mRegionToDraw.GetBounds();
result->ClearRect(Rect(bounds.x, bounds.y, bounds.width, bounds.height));
}
return result;
}
示例12: GetBlur
static already_AddRefed<SourceSurface>
GetBlur(gfxContext* aDestinationCtx,
const IntSize& aRectSize,
const IntSize& aBlurRadius,
const RectCornerRadii* aCornerRadii,
const Color& aShadowColor,
bool aMirrorCorners,
IntMargin& aOutBlurMargin,
IntMargin& aOutSlice,
IntSize& aOutMinSize)
{
if (!gBlurCache) {
gBlurCache = new BlurCache();
}
IntSize minSize =
ComputeMinSizeForShadowShape(aCornerRadii, aBlurRadius, aOutSlice, aRectSize);
// We can get seams using the min size rect when drawing to the destination rect
// if we have a non-pixel aligned destination transformation. In those cases,
// fallback to just rendering the destination rect.
Matrix destMatrix = ToMatrix(aDestinationCtx->CurrentMatrix());
bool useDestRect = !destMatrix.IsRectilinear() || destMatrix.HasNonIntegerTranslation();
if (useDestRect) {
minSize = aRectSize;
}
aOutMinSize = minSize;
DrawTarget* destDT = aDestinationCtx->GetDrawTarget();
if (!useDestRect) {
BlurCacheData* cached = gBlurCache->Lookup(minSize, aBlurRadius,
aCornerRadii, aShadowColor,
destDT->GetBackendType());
if (cached) {
// See CreateBoxShadow() for these values
aOutBlurMargin = cached->mBlurMargin;
RefPtr<SourceSurface> blur = cached->mBlur;
return blur.forget();
}
}
RefPtr<SourceSurface> boxShadow =
CreateBoxShadow(destDT, minSize, aCornerRadii, aBlurRadius,
aShadowColor, aMirrorCorners, aOutBlurMargin);
if (!boxShadow) {
return nullptr;
}
if (!useDestRect) {
CacheBlur(destDT, minSize, aBlurRadius, aCornerRadii, aShadowColor,
aOutBlurMargin, boxShadow);
}
return boxShadow.forget();
}
示例13: FillDestinationPath
/***
* Blur an inset box shadow by doing:
* 1) Create a minimal box shadow path that creates a frame.
* 2) Draw the box shadow portion over the destination surface.
* 3) The "inset" part is created by a clip rect that properly clips
* the alpha mask so that it has clean edges. We still create the full
* proper alpha mask, but let the clip deal with the clean edges.
*
* All parameters should already be in device pixels.
*/
void
gfxAlphaBoxBlur::BlurInsetBox(gfxContext* aDestinationCtx,
const Rect aDestinationRect,
const Rect aShadowClipRect,
const IntSize aBlurRadius,
const IntSize aSpreadRadius,
const Color& aShadowColor,
bool aHasBorderRadius,
const RectCornerRadii& aInnerClipRadii,
const Rect aSkipRect,
const Point aShadowOffset)
{
DrawTarget* destDrawTarget = aDestinationCtx->GetDrawTarget();
// Blur inset shadows ALWAYS have a 0 spread radius.
if ((aBlurRadius.width <= 0 && aBlurRadius.height <= 0)) {
FillDestinationPath(aDestinationCtx, aDestinationRect, aShadowClipRect,
aShadowColor, aHasBorderRadius, aInnerClipRadii);
return;
}
IntMargin extendDest;
IntMargin slice;
bool didMoveOffset;
RefPtr<SourceSurface> minInsetBlur = GetInsetBlur(extendDest, slice,
aDestinationRect, aShadowClipRect,
aBlurRadius, aSpreadRadius,
aInnerClipRadii, aShadowColor,
aHasBorderRadius, aShadowOffset,
didMoveOffset, destDrawTarget);
if (!minInsetBlur) {
return;
}
Rect srcOuter(Point(), Size(minInsetBlur->GetSize()));
Rect srcInner = srcOuter;
srcInner.Deflate(Margin(slice));
Rect dstOuter(aDestinationRect);
if (!didMoveOffset) {
dstOuter.MoveBy(aShadowOffset);
}
dstOuter.Inflate(Margin(extendDest));
Rect dstInner = dstOuter;
dstInner.Deflate(Margin(slice));
if (dstOuter.Size() == srcOuter.Size()) {
destDrawTarget->DrawSurface(minInsetBlur, dstOuter, srcOuter);
} else {
DrawBoxShadows(*destDrawTarget, minInsetBlur,
dstOuter, dstInner,
srcOuter, srcInner,
aSkipRect);
}
}
示例14: ToOutsideIntRect
void
ClientLayerManager::MakeSnapshotIfRequired()
{
if (!mShadowTarget) {
return;
}
if (mWidget) {
if (CompositorBridgeChild* remoteRenderer = GetRemoteRenderer()) {
// The compositor doesn't draw to a different sized surface
// when there's a rotation. Instead we rotate the result
// when drawing into dt
LayoutDeviceIntRect outerBounds;
mWidget->GetBounds(outerBounds);
IntRect bounds = ToOutsideIntRect(mShadowTarget->GetClipExtents());
if (mTargetRotation) {
bounds =
RotateRect(bounds, outerBounds.ToUnknownRect(), mTargetRotation);
}
SurfaceDescriptor inSnapshot;
if (!bounds.IsEmpty() &&
mForwarder->AllocSurfaceDescriptor(bounds.Size(),
gfxContentType::COLOR_ALPHA,
&inSnapshot)) {
// Make a copy of |inSnapshot| because the call to send it over IPC
// will call forget() on the Shmem inside, and zero it out.
SurfaceDescriptor outSnapshot = inSnapshot;
if (remoteRenderer->SendMakeSnapshot(inSnapshot, bounds)) {
RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(outSnapshot);
DrawTarget* dt = mShadowTarget->GetDrawTarget();
Rect dstRect(bounds.x, bounds.y, bounds.width, bounds.height);
Rect srcRect(0, 0, bounds.width, bounds.height);
gfx::Matrix rotate =
ComputeTransformForUnRotation(outerBounds.ToUnknownRect(),
mTargetRotation);
gfx::Matrix oldMatrix = dt->GetTransform();
dt->SetTransform(rotate * oldMatrix);
dt->DrawSurface(surf, dstRect, srcRect,
DrawSurfaceOptions(),
DrawOptions(1.0f, CompositionOp::OP_OVER));
dt->SetTransform(oldMatrix);
}
mForwarder->DestroySurfaceDescriptor(&outSnapshot);
}
}
}
mShadowTarget = nullptr;
}
示例15: ColorPattern
void
GradientStopsView::UpdateView()
{
DrawTarget *dt = ui->dtWidget->GetDT();
dt->FillRect(Rect(0, 0, 100000, 100000), ColorPattern(Color(0.5f, 0.5f, 0.5f, 1.0f)));
RefPtr<GradientStops> stops = mTranslator->LookupGradientStops(mRefPtr);
ui->listWidget->clear();
if (!stops) {
dt->Flush();
ui->dtWidget->redraw();
ui->listWidget->addItem("Dead");
return;
}
IntSize dstSize = dt->GetSize();
RefPtr<DrawTarget> tmpdt = dt->CreateSimilarDrawTarget(IntSize(20, 20), SurfaceFormat::B8G8R8X8);
tmpdt->FillRect(Rect(0, 0, 10, 10), ColorPattern(Color(1.0f, 1.0f, 1.0f)));
tmpdt->FillRect(Rect(10, 10, 10, 10), ColorPattern(Color(1.0f, 1.0f, 1.0f)));
tmpdt->FillRect(Rect(10, 0, 10, 10), ColorPattern(Color(0.7f, 0.7f, 0.7f)));
tmpdt->FillRect(Rect(0, 10, 10, 10), ColorPattern(Color(0.7f, 0.7f, 0.7f)));
RefPtr<SourceSurface> src = tmpdt->Snapshot();
tmpdt = NULL;
Rect dstRect(0, 0, dstSize.width, dstSize.height);
dt->FillRect(dstRect, SurfacePattern(src, ExtendMode::REPEAT));
dt->FillRect(dstRect, LinearGradientPattern(Point(0, dstSize.height / 2), Point(dstSize.width, dstSize.height / 2), stops));
dt->Flush();
ui->dtWidget->redraw();
}