Backed out changeset 1e6d52401dd2

This commit is contained in:
Dão Gottwald 2009-09-04 15:32:17 +02:00
Родитель 8a5befd049
Коммит 5b3009c210
9 изменённых файлов: 74 добавлений и 55 удалений

Просмотреть файл

@ -1162,30 +1162,35 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext,
gfxRect frameGfxRect = RectToGfxRect(aFrameArea, twipsPerPixel); gfxRect frameGfxRect = RectToGfxRect(aFrameArea, twipsPerPixel);
frameGfxRect.Round(); frameGfxRect.Round();
gfxRect dirtyGfxRect = RectToGfxRect(aDirtyRect, twipsPerPixel);
for (PRUint32 i = shadows->Length(); i > 0; --i) { for (PRUint32 i = shadows->Length(); i > 0; --i) {
nsCSSShadowItem* shadowItem = shadows->ShadowAt(i - 1); nsCSSShadowItem* shadowItem = shadows->ShadowAt(i - 1);
if (shadowItem->mInset) if (shadowItem->mInset)
continue; continue;
nsRect shadowRect = aFrameArea; gfxRect shadowRect(aFrameArea.x, aFrameArea.y, aFrameArea.width, aFrameArea.height);
shadowRect.MoveBy(shadowItem->mXOffset, shadowItem->mYOffset); shadowRect.MoveBy(gfxPoint(shadowItem->mXOffset, shadowItem->mYOffset));
shadowRect.Inflate(shadowItem->mSpread, shadowItem->mSpread); shadowRect.Outset(shadowItem->mSpread);
gfxRect shadowRectPlusBlur = shadowRect;
shadowRect.ScaleInverse(twipsPerPixel);
shadowRect.Round();
// shadowRect won't include the blur, so make an extra rect here that includes the blur // shadowRect won't include the blur, so make an extra rect here that includes the blur
// for use in the even-odd rule below. // for use in the even-odd rule below.
nsRect shadowRectPlusBlur = shadowRect;
nscoord blurRadius = shadowItem->mRadius; nscoord blurRadius = shadowItem->mRadius;
shadowRectPlusBlur.Inflate(blurRadius, blurRadius); shadowRectPlusBlur.Outset(blurRadius);
shadowRectPlusBlur.ScaleInverse(twipsPerPixel);
gfxRect shadowGfxRect = RectToGfxRect(shadowRect, twipsPerPixel); shadowRectPlusBlur.RoundOut();
gfxRect shadowGfxRectPlusBlur = RectToGfxRect(shadowRectPlusBlur, twipsPerPixel);
gfxContext* renderContext = aRenderingContext.ThebesContext(); gfxContext* renderContext = aRenderingContext.ThebesContext();
nsRefPtr<gfxContext> shadowContext; nsRefPtr<gfxContext> shadowContext;
nsContextBoxBlur blurringArea; nsContextBoxBlur blurringArea;
shadowContext = blurringArea.Init(shadowRect, blurRadius, twipsPerPixel, renderContext, aDirtyRect); // shadowRect is already in device pixels, pass 1 as the appunits/pixel value
blurRadius /= twipsPerPixel;
shadowContext = blurringArea.Init(shadowRect, blurRadius, 1, renderContext, dirtyGfxRect);
if (!shadowContext) if (!shadowContext)
continue; continue;
@ -1202,7 +1207,7 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext,
// Clip out the area of the actual frame so the shadow is not shown within // Clip out the area of the actual frame so the shadow is not shown within
// the frame // the frame
renderContext->NewPath(); renderContext->NewPath();
renderContext->Rectangle(shadowGfxRectPlusBlur); renderContext->Rectangle(shadowRectPlusBlur);
if (hasBorderRadius) if (hasBorderRadius)
renderContext->RoundedRectangle(frameGfxRect, borderRadii); renderContext->RoundedRectangle(frameGfxRect, borderRadii);
else else
@ -1225,9 +1230,9 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext,
}; };
nsCSSBorderRenderer::ComputeInnerRadii(borderRadii, borderSizes, nsCSSBorderRenderer::ComputeInnerRadii(borderRadii, borderSizes,
&clipRectRadii); &clipRectRadii);
shadowContext->RoundedRectangle(shadowGfxRect, clipRectRadii); shadowContext->RoundedRectangle(shadowRect, clipRectRadii);
} else { } else {
shadowContext->Rectangle(shadowGfxRect); shadowContext->Rectangle(shadowRect);
} }
shadowContext->Fill(); shadowContext->Fill();
@ -1274,6 +1279,7 @@ nsCSSRendering::PaintBoxShadowInner(nsPresContext* aPresContext,
&innerRadii); &innerRadii);
} }
gfxRect dirtyGfxRect = RectToGfxRect(aDirtyRect, twipsPerPixel);
for (PRUint32 i = shadows->Length(); i > 0; --i) { for (PRUint32 i = shadows->Length(); i > 0; --i) {
nsCSSShadowItem* shadowItem = shadows->ShadowAt(i - 1); nsCSSShadowItem* shadowItem = shadows->ShadowAt(i - 1);
if (!shadowItem->mInset) if (!shadowItem->mInset)
@ -1287,18 +1293,28 @@ nsCSSRendering::PaintBoxShadowInner(nsPresContext* aPresContext,
* that we will NOT paint in * that we will NOT paint in
*/ */
nscoord blurRadius = shadowItem->mRadius; nscoord blurRadius = shadowItem->mRadius;
nsRect shadowPaintRect = paddingRect; gfxRect shadowRect(paddingRect.x, paddingRect.y, paddingRect.width, paddingRect.height);
shadowPaintRect.Inflate(blurRadius, blurRadius); gfxRect shadowPaintRect = shadowRect;
shadowPaintRect.Outset(blurRadius);
nsRect shadowClipRect = paddingRect; gfxRect shadowClipRect = shadowRect;
shadowClipRect.MoveBy(shadowItem->mXOffset, shadowItem->mYOffset); shadowClipRect.MoveBy(gfxPoint(shadowItem->mXOffset, shadowItem->mYOffset));
shadowClipRect.Deflate(shadowItem->mSpread, shadowItem->mSpread); shadowClipRect.Inset(shadowItem->mSpread);
shadowRect.ScaleInverse(twipsPerPixel);
shadowRect.Round();
shadowPaintRect.ScaleInverse(twipsPerPixel);
shadowPaintRect.RoundOut();
shadowClipRect.ScaleInverse(twipsPerPixel);
shadowClipRect.Round();
gfxContext* renderContext = aRenderingContext.ThebesContext(); gfxContext* renderContext = aRenderingContext.ThebesContext();
nsRefPtr<gfxContext> shadowContext; nsRefPtr<gfxContext> shadowContext;
nsContextBoxBlur blurringArea; nsContextBoxBlur blurringArea;
shadowContext = blurringArea.Init(shadowPaintRect, blurRadius, twipsPerPixel, renderContext, aDirtyRect); // shadowPaintRect is already in device pixels, pass 1 as the appunits/pixel value
blurRadius /= twipsPerPixel;
shadowContext = blurringArea.Init(shadowPaintRect, blurRadius, 1, renderContext, dirtyGfxRect);
if (!shadowContext) if (!shadowContext)
continue; continue;
@ -1314,20 +1330,17 @@ nsCSSRendering::PaintBoxShadowInner(nsPresContext* aPresContext,
// Clip the context to the area of the frame's padding rect, so no part of the // Clip the context to the area of the frame's padding rect, so no part of the
// shadow is painted outside // shadow is painted outside
gfxRect shadowGfxRect = RectToGfxRect(paddingRect, twipsPerPixel);
renderContext->NewPath(); renderContext->NewPath();
if (hasBorderRadius) if (hasBorderRadius)
renderContext->RoundedRectangle(shadowGfxRect, innerRadii, PR_FALSE); renderContext->RoundedRectangle(shadowRect, innerRadii, PR_FALSE);
else else
renderContext->Rectangle(shadowGfxRect); renderContext->Rectangle(shadowRect);
renderContext->Clip(); renderContext->Clip();
// Fill the temporary surface minus the area within the frame that we should // Fill the temporary surface minus the area within the frame that we should
// not paint in, and blur and apply it // not paint in, and blur and apply it
gfxRect shadowPaintGfxRect = RectToGfxRect(shadowPaintRect, twipsPerPixel);
gfxRect shadowClipGfxRect = RectToGfxRect(shadowClipRect, twipsPerPixel);
shadowContext->NewPath(); shadowContext->NewPath();
shadowContext->Rectangle(shadowPaintGfxRect); shadowContext->Rectangle(shadowPaintRect);
if (hasBorderRadius) { if (hasBorderRadius) {
// Calculate the radii the inner clipping rect will have // Calculate the radii the inner clipping rect will have
gfxCornerSizes clipRectRadii; gfxCornerSizes clipRectRadii;
@ -1338,9 +1351,9 @@ nsCSSRendering::PaintBoxShadowInner(nsPresContext* aPresContext,
}; };
nsCSSBorderRenderer::ComputeInnerRadii(innerRadii, borderSizes, nsCSSBorderRenderer::ComputeInnerRadii(innerRadii, borderSizes,
&clipRectRadii); &clipRectRadii);
shadowContext->RoundedRectangle(shadowClipGfxRect, clipRectRadii, PR_FALSE); shadowContext->RoundedRectangle(shadowClipRect, clipRectRadii, PR_FALSE);
} else { } else {
shadowContext->Rectangle(shadowClipGfxRect); shadowContext->Rectangle(shadowClipRect);
} }
shadowContext->SetFillRule(gfxContext::FILL_RULE_EVEN_ODD); shadowContext->SetFillRule(gfxContext::FILL_RULE_EVEN_ODD);
shadowContext->Fill(); shadowContext->Fill();
@ -3193,14 +3206,15 @@ ImageRenderer::Draw(nsPresContext* aPresContext,
// nsContextBoxBlur // nsContextBoxBlur
// ----- // -----
gfxContext* gfxContext*
nsContextBoxBlur::Init(const nsRect& aRect, nscoord aBlurRadius, nsContextBoxBlur::Init(const gfxRect& aRect, nscoord aBlurRadius,
PRInt32 aAppUnitsPerDevPixel, PRInt32 aAppUnitsPerDevPixel,
gfxContext* aDestinationCtx, gfxContext* aDestinationCtx,
const nsRect& aDirtyRect) const gfxRect& aDirtyRect)
{ {
PRInt32 blurRadius = static_cast<PRInt32>(aBlurRadius / aAppUnitsPerDevPixel);
mDestinationCtx = aDestinationCtx; mDestinationCtx = aDestinationCtx;
PRInt32 blurRadius = static_cast<PRInt32>(aBlurRadius / aAppUnitsPerDevPixel);
// if not blurring, draw directly onto the destination device // if not blurring, draw directly onto the destination device
if (blurRadius <= 0) { if (blurRadius <= 0) {
mContext = aDestinationCtx; mContext = aDestinationCtx;
@ -3208,14 +3222,18 @@ nsContextBoxBlur::Init(const nsRect& aRect, nscoord aBlurRadius,
} }
// Convert from app units to device pixels // Convert from app units to device pixels
gfxRect rect = RectToGfxRect(aRect, aAppUnitsPerDevPixel); gfxRect rect = aRect;
rect.ScaleInverse(aAppUnitsPerDevPixel);
if (rect.IsEmpty()) { if (rect.IsEmpty()) {
mContext = aDestinationCtx; mContext = aDestinationCtx;
return mContext; return mContext;
} }
gfxRect dirtyRect = RectToGfxRect(aDirtyRect, aAppUnitsPerDevPixel); gfxRect dirtyRect = aDirtyRect;
dirtyRect.ScaleInverse(aAppUnitsPerDevPixel);
mDestinationCtx = aDestinationCtx;
// Create the temporary surface for blurring // Create the temporary surface for blurring
mContext = blur.Init(rect, gfxIntSize(blurRadius, blurRadius), &dirtyRect); mContext = blur.Init(rect, gfxIntSize(blurRadius, blurRadius), &dirtyRect);

Просмотреть файл

@ -400,9 +400,9 @@ public:
* should prepare the destination context as if you were going to draw * should prepare the destination context as if you were going to draw
* directly on it instead of any temporary surface created in this class. * directly on it instead of any temporary surface created in this class.
*/ */
gfxContext* Init(const nsRect& aRect, nscoord aBlurRadius, gfxContext* Init(const gfxRect& aRect, nscoord aBlurRadius,
PRInt32 aAppUnitsPerDevPixel, gfxContext* aDestinationCtx, PRInt32 aAppUnitsPerDevPixel, gfxContext* aDestinationCtx,
const nsRect& aDirtyRect); const gfxRect& aDirtyRect);
/** /**
* Does the actual blurring and mask applying. Users of this object *must* * Does the actual blurring and mask applying. Users of this object *must*

Просмотреть файл

@ -155,7 +155,7 @@ class nsDisplayTextShadow : public nsDisplayItem {
public: public:
nsDisplayTextShadow(nsHTMLContainerFrame* aFrame, const PRUint8 aDecoration, nsDisplayTextShadow(nsHTMLContainerFrame* aFrame, const PRUint8 aDecoration,
const nscolor& aColor, nsLineBox* aLine, const nscolor& aColor, nsLineBox* aLine,
const nscoord& aBlurRadius, const nsPoint& aOffset) const nscoord& aBlurRadius, const gfxPoint& aOffset)
: nsDisplayItem(aFrame), mLine(aLine), mColor(aColor), : nsDisplayItem(aFrame), mLine(aLine), mColor(aColor),
mDecorationFlags(aDecoration), mDecorationFlags(aDecoration),
mBlurRadius(aBlurRadius), mOffset(aOffset) { mBlurRadius(aBlurRadius), mOffset(aOffset) {
@ -174,7 +174,7 @@ private:
nscolor mColor; nscolor mColor;
PRUint8 mDecorationFlags; PRUint8 mDecorationFlags;
nscoord mBlurRadius; // App units nscoord mBlurRadius; // App units
nsPoint mOffset; // App units gfxPoint mOffset; // App units
}; };
void void
@ -192,17 +192,21 @@ nsDisplayTextShadow::Paint(nsDisplayListBuilder* aBuilder,
if (!firstFont) if (!firstFont)
return; // OOM return; // OOM
const gfxFont::Metrics& metrics = firstFont->GetMetrics(); const gfxFont::Metrics& metrics = firstFont->GetMetrics();
nsPoint pt = aBuilder->ToReferenceFrame(mFrame) + nsPoint(mOffset.x, mOffset.y);
nsHTMLContainerFrame* f = static_cast<nsHTMLContainerFrame*>(mFrame); nsHTMLContainerFrame* f = static_cast<nsHTMLContainerFrame*>(mFrame);
nsPoint pt = aBuilder->ToReferenceFrame(mFrame) + mOffset; nsMargin bp = f->GetUsedBorderAndPadding();
nscoord innerWidthInAppUnits = (mFrame->GetSize().width - bp.LeftRight());
nsRect shadowRect = mFrame->GetContentRect() - mFrame->GetPosition() + pt; gfxRect shadowRect = gfxRect(pt.x, pt.y, innerWidthInAppUnits, mFrame->GetSize().height);
gfxContext* thebesCtx = aCtx->ThebesContext(); gfxContext* thebesCtx = aCtx->ThebesContext();
gfxRect dirtyRect(aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height);
nsContextBoxBlur contextBoxBlur; nsContextBoxBlur contextBoxBlur;
gfxContext* shadowCtx = contextBoxBlur.Init(shadowRect, mBlurRadius, gfxContext* shadowCtx = contextBoxBlur.Init(shadowRect, mBlurRadius,
mFrame->PresContext()->AppUnitsPerDevPixel(), mFrame->PresContext()->AppUnitsPerDevPixel(),
thebesCtx, aDirtyRect); thebesCtx, dirtyRect);
if (!shadowCtx) if (!shadowCtx)
return; return;
@ -275,7 +279,7 @@ nsHTMLContainerFrame::DisplayTextDecorations(nsDisplayListBuilder* aBuilder,
else else
shadowColor = GetStyleColor()->mColor; shadowColor = GetStyleColor()->mColor;
nsPoint offset(shadow->mXOffset, shadow->mYOffset); gfxPoint offset = gfxPoint(shadow->mXOffset, shadow->mYOffset);
// Add it to the display list so it is painted underneath the text and all decorations // Add it to the display list so it is painted underneath the text and all decorations
nsresult rv = aBelowTextDecorations->AppendNewToTop(new (aBuilder) nsresult rv = aBelowTextDecorations->AppendNewToTop(new (aBuilder)

Просмотреть файл

@ -418,7 +418,7 @@ protected:
PRUint32 aLength, PRUint32 aLength,
nsCSSShadowItem* aShadowDetails, nsCSSShadowItem* aShadowDetails,
PropertyProvider* aProvider, PropertyProvider* aProvider,
const nsRect& aDirtyRect, const gfxRect& aDirtyRect,
const gfxPoint& aFramePt, const gfxPoint& aFramePt,
const gfxPoint& aTextBaselinePt, const gfxPoint& aTextBaselinePt,
gfxContext* aCtx, gfxContext* aCtx,

Просмотреть файл

@ -4422,7 +4422,7 @@ AddHyphenToMetrics(nsTextFrame* aTextFrame, gfxTextRun* aBaseTextRun,
void void
nsTextFrame::PaintOneShadow(PRUint32 aOffset, PRUint32 aLength, nsTextFrame::PaintOneShadow(PRUint32 aOffset, PRUint32 aLength,
nsCSSShadowItem* aShadowDetails, nsCSSShadowItem* aShadowDetails,
PropertyProvider* aProvider, const nsRect& aDirtyRect, PropertyProvider* aProvider, const gfxRect& aDirtyRect,
const gfxPoint& aFramePt, const gfxPoint& aTextBaselinePt, const gfxPoint& aFramePt, const gfxPoint& aTextBaselinePt,
gfxContext* aCtx, const nscolor& aForegroundColor) gfxContext* aCtx, const nscolor& aForegroundColor)
{ {
@ -4439,10 +4439,8 @@ nsTextFrame::PaintOneShadow(PRUint32 aOffset, PRUint32 aLength,
// This rect is the box which is equivalent to where the shadow will be painted. // This rect is the box which is equivalent to where the shadow will be painted.
// The origin of mBoundingBox is the text baseline left, so we must translate it by // The origin of mBoundingBox is the text baseline left, so we must translate it by
// that much in order to make the origin the top-left corner of the text bounding box. // that much in order to make the origin the top-left corner of the text bounding box.
gfxRect shadowGfxRect = shadowMetrics.mBoundingBox + gfxRect shadowRect = shadowMetrics.mBoundingBox +
gfxPoint(aFramePt.x, aTextBaselinePt.y) + shadowOffset; gfxPoint(aFramePt.x, aTextBaselinePt.y) + shadowOffset;
nsRect shadowRect(shadowGfxRect.X(), shadowGfxRect.Y(),
shadowGfxRect.Width(), shadowGfxRect.Height());
nsContextBoxBlur contextBoxBlur; nsContextBoxBlur contextBoxBlur;
gfxContext* shadowContext = contextBoxBlur.Init(shadowRect, blurRadius, gfxContext* shadowContext = contextBoxBlur.Init(shadowRect, blurRadius,
@ -4464,18 +4462,17 @@ nsTextFrame::PaintOneShadow(PRUint32 aOffset, PRUint32 aLength,
// Draw the text onto our alpha-only surface to capture the alpha values. // Draw the text onto our alpha-only surface to capture the alpha values.
// Remember that the box blur context has a device offset on it, so we don't need to // Remember that the box blur context has a device offset on it, so we don't need to
// translate any coordinates to fit on the surface. // translate any coordinates to fit on the surface.
gfxRect dirtyGfxRect(aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height);
gfxFloat advanceWidth; gfxFloat advanceWidth;
DrawText(shadowContext, DrawText(shadowContext,
aTextBaselinePt + shadowOffset, aTextBaselinePt + shadowOffset,
aOffset, aLength, &dirtyGfxRect, aProvider, advanceWidth, aOffset, aLength, &aDirtyRect, aProvider, advanceWidth,
(GetStateBits() & TEXT_HYPHEN_BREAK) != 0); (GetStateBits() & TEXT_HYPHEN_BREAK) != 0);
// This will only have an effect in quirks mode. Standards mode text-decoration shadow painting // This will only have an effect in quirks mode. Standards mode text-decoration shadow painting
// is handled in nsHTMLContainerFrame.cpp, so you must remember to consider that if you change // is handled in nsHTMLContainerFrame.cpp, so you must remember to consider that if you change
// any code behaviour here. // any code behaviour here.
nsTextPaintStyle textPaintStyle(this); nsTextPaintStyle textPaintStyle(this);
PaintTextDecorations(shadowContext, dirtyGfxRect, aFramePt + shadowOffset, PaintTextDecorations(shadowContext, aDirtyRect, aFramePt + shadowOffset,
aTextBaselinePt + shadowOffset, aTextBaselinePt + shadowOffset,
textPaintStyle, *aProvider, &shadowColor); textPaintStyle, *aProvider, &shadowColor);
@ -4741,7 +4738,7 @@ nsTextFrame::PaintText(nsIRenderingContext* aRenderingContext, nsPoint aPt,
PaintOneShadow(provider.GetStart().GetSkippedOffset(), PaintOneShadow(provider.GetStart().GetSkippedOffset(),
ComputeTransformedLength(provider), ComputeTransformedLength(provider),
textStyle->mTextShadow->ShadowAt(i - 1), &provider, textStyle->mTextShadow->ShadowAt(i - 1), &provider,
aDirtyRect, framePt, textBaselinePt, ctx, dirtyRect, framePt, textBaselinePt, ctx,
textPaintStyle.GetTextColor()); textPaintStyle.GetTextColor());
} }
} }

Просмотреть файл

@ -1 +0,0 @@
<!DOCTYPE HTML><div><a href="http://test" style="margin-left: 20px; text-shadow: 2px 2px 3px blue;">Hello world hello world</a></div>

Просмотреть файл

@ -1 +0,0 @@
<!DOCTYPE HTML><div><a href="http://test" style="padding-left: 20px; text-shadow: 2px 2px 3px blue;">Hello world hello world</a></div>

Просмотреть файл

@ -13,5 +13,4 @@
== multiple-noblur.html multiple-noblur-ref.html == multiple-noblur.html multiple-noblur-ref.html
== quirks-decor-noblur.html quirks-decor-noblur-ref.html == quirks-decor-noblur.html quirks-decor-noblur-ref.html
== standards-decor-noblur.html standards-decor-noblur-ref.html == standards-decor-noblur.html standards-decor-noblur-ref.html
== padding-decoration.html padding-decoration-ref.html

Просмотреть файл

@ -574,10 +574,14 @@ void nsTextBoxFrame::PaintOneShadow(gfxContext* aCtx,
nsRect shadowRect(aTextRect); nsRect shadowRect(aTextRect);
shadowRect.MoveBy(shadowOffset); shadowRect.MoveBy(shadowOffset);
gfxRect shadowRectGFX(shadowRect.x, shadowRect.y, shadowRect.width, shadowRect.height);
gfxRect dirtyRectGFX(aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height);
nsContextBoxBlur contextBoxBlur; nsContextBoxBlur contextBoxBlur;
gfxContext* shadowContext = contextBoxBlur.Init(shadowRect, blurRadius, gfxContext* shadowContext = contextBoxBlur.Init(shadowRectGFX, blurRadius,
PresContext()->AppUnitsPerDevPixel(), PresContext()->AppUnitsPerDevPixel(),
aCtx, aDirtyRect); aCtx, dirtyRectGFX);
if (!shadowContext) if (!shadowContext)
return; return;
@ -591,8 +595,7 @@ void nsTextBoxFrame::PaintOneShadow(gfxContext* aCtx,
nsCOMPtr<nsIRenderingContext> renderingContext = nsnull; nsCOMPtr<nsIRenderingContext> renderingContext = nsnull;
nsIDeviceContext* devCtx = PresContext()->DeviceContext(); nsIDeviceContext* devCtx = PresContext()->DeviceContext();
devCtx->CreateRenderingContextInstance(*getter_AddRefs(renderingContext)); devCtx->CreateRenderingContextInstance(*getter_AddRefs(renderingContext));
if (!renderingContext) if (!renderingContext) return;
return;
renderingContext->Init(devCtx, shadowContext); renderingContext->Init(devCtx, shadowContext);
aCtx->Save(); aCtx->Save();