public void Apply(Surface dst, Surface src, Rectangle[] rois, int startIndex, int length) { for (int i = startIndex; i < startIndex + length; ++i) { ApplyBase(dst, rois[i].Location, src, rois[i].Location, rois[i].Size); } }
public GradientBenchmark(string name, Surface surface, GradientRenderer renderer, int iterations) : base(name) { this.surface = surface; this.renderer = renderer; this.iterations = iterations; }
public FitSurfaceContext(Surface dstSurface, Surface srcSurface, Rectangle[] dstRois, ResamplingAlgorithm algorithm) { this.dstSurface = dstSurface; this.srcSurface = srcSurface; this.dstRois = dstRois; this.algorithm = algorithm; }
private void MyRender(Surface dst, Surface src) { PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds); ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor; ColorBgra SecondaryColor = (ColorBgra)EnvironmentParameters.SecondaryColor; int BrushWidth = (int)EnvironmentParameters.BrushWidth; if (PGP.Length > 0 && Draw ) { using (Graphics g = new RenderArgs(dst).Graphics) { using (Region reg = new Region(selectionRegion.GetRegionData())) { g.SetClip(reg, CombineMode.Replace); } g.SmoothingMode = SmoothingMode.AntiAlias; Pen p = new Pen(PrimaryColor); p.Width = BrushWidth; for (int i = 0; i < PGP.Length; i++) { if (PGP[i].PointCount > 0) { g.DrawPath(p, PGP[i]); } } } } }
public ZoomOutBlitBenchmark(string name, Surface source, Surface dst, Size blitSize) : base(name) { this.source = source; this.dst = dst; this.blitSize = blitSize; }
protected void RenderCompositionTo(Surface dst, bool highQuality, bool forceUpToDate) { if (forceUpToDate) { UpdateComposition(false); } if (dst.Width == this.compositionSurface.Width && dst.Height == this.compositionSurface.Height) { dst.ClearWithCheckboardPattern(); new UserBlendOps.NormalBlendOp().Apply(dst, this.compositionSurface); } else if (highQuality) { Surface thumb = new Surface(dst.Size); thumb.SuperSamplingFitSurface(this.compositionSurface); dst.ClearWithCheckboardPattern(); new UserBlendOps.NormalBlendOp().Apply(dst, thumb); thumb.Dispose(); } else { this.surfaceBox.RenderTo(dst); } }
public CompositionBenchmark(string name, Document composeMe, Surface dstSurface, SetLayerInfoDelegate sliDelegate) : base(name) { this.composeMe = composeMe; this.dstSurface = dstSurface; this.sliDelegate = sliDelegate; }
public TransformBenchmark(string name, Surface dst, MaskedSurface src, Matrix transform, bool highQuality) : base(name) { this.dst = dst; this.src = src; this.transform = transform.Clone(); this.highQuality = highQuality; }
protected override void OnSave(Document input, Stream output, SaveConfigToken token, Surface scratchSurface, ProgressEventHandler callback) { RenderArgs ra = new RenderArgs(new Surface(input.Size)); input.Render(ra); ra.Bitmap.Save(output, ImageFormat.Bmp); }
public BitmapLayer(int width, int height, ColorBgra fillColor) : base(width, height) { this.surface = new Surface(width, height); // clear to see-through white, 0x00ffffff this.Surface.Clear(fillColor); this.properties = new BitmapLayerProperties(UserBlendOps.CreateDefaultBlendOp()); }
private unsafe void ApplyRectangle(Surface surface, Rectangle rect) { for (int y = rect.Top; y < rect.Bottom; ++y) { ColorBgra *ptr = surface.GetPointAddress(rect.Left, y); Apply(ptr, rect.Width); } }
public EffectBenchmark(string name, int iterations, Effect effect, EffectConfigToken token, Surface image) : base(name + " (" + iterations + "x)") { this.effect = effect; this.token = token; this.image = image; this.iterations = iterations; }
public void Save(Stream dstStream, Document srcDocument, FileType dstFileType, SaveConfigToken parameters, Surface saveScratchSurface) { this.document = srcDocument; this.fileType = dstFileType; this.stream = dstStream; this.saveConfigToken = parameters; this.scratchSurface = saveScratchSurface; DialogResult dr = this.ShowDialog(false, !dstFileType.SavesWithProgress , new ThreadStart(SaveCallback)); }
public PlacedSurface(Surface source, Rectangle roi) { where = roi.Location; Surface window = source.CreateWindow(roi); what = new Surface(window.Size); what.CopySurface(window); window.Dispose(); }
public BitVector2DSurfaceAdapter(Surface surface) { if (surface == null) { throw new ArgumentNullException("surface"); } this.surface = surface; }
public void Draw(Surface dst) { if (disposed) { throw new ObjectDisposedException("PlacedSurface"); } dst.CopySurface(what, where); }
public override sealed void Render(Surface dst, Point offset) { if (ShouldRender()) { using (RenderArgs ra = new RenderArgs(dst)) { RenderToGraphics(ra.Graphics, offset); } } }
protected override void OnSave(Document input, Stream output, SaveConfigToken token, Surface scratchSurface, ProgressEventHandler callback) { if (callback == null) { input.SaveToStream(output); } else { UpdateProgressTranslator upt = new UpdateProgressTranslator(ApproximateMaxOutputOffset(input), callback); input.SaveToStream(output, new IOEventHandler(upt.IOEventHandler)); } }
protected override ColorBgra Render(int x, int y, ColorBgra initial, Surface source) { var targetA = source[Offset(Bounds.Left, x, Bounds.Right), y]; initial = initial.Blend(targetA, GetBorderBlendValue(Bounds.Left, x, Bounds.Right)); var targetC = source[Offset(Bounds.Left, x, Bounds.Right), Offset(Bounds.Top, y, Bounds.Bottom)]; var targetB = source[x, Offset(Bounds.Top, y, Bounds.Bottom)]; targetB = targetB.Blend(targetC, GetBorderBlendValue(Bounds.Left, x, Bounds.Right)); initial = initial.Blend(targetB, GetBorderBlendValue(Bounds.Top, y, Bounds.Bottom)); return initial; }
/// <summary> /// Provides a default implementation for performing dst = F(lhs, rhs) over some rectangle of interest. /// </summary> /// <param name="dst">The Surface to write pixels to.</param> /// <param name="dstOffset">The pixel offset that defines the upper-left of the rectangle-of-interest for the dst Surface.</param> /// <param name="lhs">The Surface to read pixels from for the lhs parameter given to the method <b>ColorBgra Apply(ColorBgra, ColorBgra)</b>b>.</param></param> /// <param name="lhsOffset">The pixel offset that defines the upper-left of the rectangle-of-interest for the lhs Surface.</param> /// <param name="rhs">The Surface to read pixels from for the rhs parameter given to the method <b>ColorBgra Apply(ColorBgra, ColorBgra)</b></param> /// <param name="rhsOffset">The pixel offset that defines the upper-left of the rectangle-of-interest for the rhs Surface.</param> /// <param name="roiSize">The size of the rectangles-of-interest for all Surfaces.</param> public void Apply(Surface dst, Point dstOffset, Surface lhs, Point lhsOffset, Surface rhs, Point rhsOffset, Size roiSize) { // Bounds checking only enabled in Debug builds. #if DEBUG // Create bounding rectangles for each Surface Rectangle dstRect = new Rectangle(dstOffset, roiSize); Rectangle lhsRect = new Rectangle(lhsOffset, roiSize); Rectangle rhsRect = new Rectangle(rhsOffset, roiSize); // Clip those rectangles to those Surface's bounding rectangles Rectangle dstClip = Rectangle.Intersect(dstRect, dst.Bounds); Rectangle lhsClip = Rectangle.Intersect(lhsRect, lhs.Bounds); Rectangle rhsClip = Rectangle.Intersect(rhsRect, rhs.Bounds); // If any of those Rectangles actually got clipped, then throw an exception if (dstRect != dstClip) { throw new ArgumentOutOfRangeException("roiSize", "Destination roi out of bounds"); } if (lhsRect != lhsClip) { throw new ArgumentOutOfRangeException("roiSize", "lhs roi out of bounds"); } if (rhsRect != rhsClip) { throw new ArgumentOutOfRangeException("roiSize", "rhs roi out of bounds"); } #endif // Cache the width and height properties int width = roiSize.Width; int height = roiSize.Height; // Do the work. unsafe { for (int row = 0; row < height; ++row) { ColorBgra *dstPtr = dst.GetPointAddress(dstOffset.X, dstOffset.Y + row); ColorBgra *lhsPtr = lhs.GetPointAddress(lhsOffset.X, lhsOffset.Y + row); ColorBgra *rhsPtr = rhs.GetPointAddress(rhsOffset.X, rhsOffset.Y + row); Apply(dstPtr, lhsPtr, rhsPtr, width); } } }
protected override void OnSave(Document input, Stream output, SaveConfigToken token, Surface scratchSurface, ProgressEventHandler progressCallback) { GifSaveConfigToken gsct = (GifSaveConfigToken)token; // Flatten and pre-process the image scratchSurface.Clear(ColorBgra.FromBgra(255, 255, 255, 0)); using (RenderArgs ra = new RenderArgs(scratchSurface)) { input.Render(ra, true); } for (int y = 0; y < scratchSurface.Height; ++y) { unsafe { ColorBgra* ptr = scratchSurface.GetRowAddressUnchecked(y); for (int x = 0; x < scratchSurface.Width; ++x) { if (ptr->A < gsct.Threshold) { ptr->Bgra = 0; } else { if (gsct.PreMultiplyAlpha) { int r = ((ptr->R * ptr->A) + (255 * (255 - ptr->A))) / 255; int g = ((ptr->G * ptr->A) + (255 * (255 - ptr->A))) / 255; int b = ((ptr->B * ptr->A) + (255 * (255 - ptr->A))) / 255; int a = 255; *ptr = ColorBgra.FromBgra((byte)b, (byte)g, (byte)r, (byte)a); } else { ptr->Bgra |= 0xff000000; } } ++ptr; } } } using (Bitmap quantized = Quantize(scratchSurface, gsct.DitherLevel, 255, progressCallback)) { quantized.Save(output, ImageFormat.Gif); } }
/// <summary> /// Creates a new BitmapLayer of the same size as the given Surface, and either /// copies the pixels of the given Surface or takes ownership of it. /// </summary> /// <param name="surface">The Surface.</param> /// <param name="takeOwnership"> /// true to take ownership of the surface (make sure to Dispose() it yourself), or /// false to copy its pixels /// </param> public BitmapLayer(Surface surface, bool takeOwnership) : base(surface.Width, surface.Height) { if (takeOwnership) { this.surface = surface; } else { this.surface = surface.Clone(); } this.properties = new BitmapLayerProperties(UserBlendOps.CreateDefaultBlendOp()); }
/// <summary> /// Constructs an IrregularSurface by copying the given region-of-interest from an Image. /// </summary> /// <param name="source">The Surface to copy pixels from.</param> /// <param name="roi">Defines the Region from which to copy pixels from the Image.</param> public IrregularSurface(Surface source, PdnRegion roi) { PdnRegion roiClipped = (PdnRegion)roi.Clone(); roiClipped.Intersect(source.Bounds); Rectangle[] rects = roiClipped.GetRegionScansReadOnlyInt(); this.placedSurfaces = new ArrayList(rects.Length); foreach (Rectangle rect in rects) { this.placedSurfaces.Add(new PlacedSurface(source, rect)); } this.region = roiClipped; }
protected override unsafe void AddSurfaceRectangleToHistogram(Surface surface, Rectangle rect) { long[] histogramLuminosity = histogram[0]; for (int y = rect.Top; y < rect.Bottom; ++y) { ColorBgra* ptr = surface.GetPointAddressUnchecked(rect.Left, y); for (int x = rect.Left; x < rect.Right; ++x) { ++histogramLuminosity[ptr->GetIntensityByte()]; ++ptr; } } }
protected override unsafe void OnSave( Document input, Stream output, SaveConfigToken token, Surface scratchSurface, ProgressEventHandler callback ) { DdsSaveConfigToken ddsToken = ( DdsSaveConfigToken )token; // We need to be able to feast on the goo inside.. scratchSurface.Clear( ColorBgra.Transparent ); using ( RenderArgs ra = new RenderArgs( scratchSurface ) ) { input.Render( ra, true ); } // Create the DDS file, and save it.. DdsFile ddsFile = new DdsFile(); ddsFile.Save( output, scratchSurface, ddsToken, callback ); }
public static void Save(Document input, Stream output, Surface scratchSurface, ImageFormat format, ProgressEventHandler callback) { // flatten the document scratchSurface.Clear(ColorBgra.FromBgra(0, 0, 0, 0)); using (RenderArgs ra = new RenderArgs(scratchSurface)) { input.Render(ra, true); } using (Bitmap bitmap = scratchSurface.CreateAliasedBitmap()) { LoadProperties(bitmap, input); bitmap.Save(output, format); } }
public IrregularSurface(Surface source, Rectangle[] roi) { this.placedSurfaces = new ArrayList(roi.Length); foreach (Rectangle rect in roi) { Rectangle ri = Rectangle.Intersect(source.Bounds, rect); if (!ri.IsEmpty) { this.placedSurfaces.Add(new PlacedSurface(source, ri)); } } this.region = Utility.RectanglesToRegion(roi); this.region.Intersect(source.Bounds); }
public override Surface RenderThumbnail(int maxEdgeLength) { Size thumbSize = Utility.ComputeThumbnailSize(this.Size, maxEdgeLength); Surface thumb = new Surface(thumbSize); thumb.SuperSamplingFitSurface(this.surface); Surface thumb2 = new Surface(thumbSize); thumb2.ClearWithCheckboardPattern(); UserBlendOps.NormalBlendOp nbop = new UserBlendOps.NormalBlendOp(); nbop.Apply(thumb2, thumb); thumb.Dispose(); thumb = null; return thumb2; }
public void Apply(Surface surface, RectangleF[] roiF, int startIndex, int length) { Rectangle regionBounds = Rectangle.Truncate(Utility.GetRegionBounds(roiF, startIndex, length)); if (regionBounds != Rectangle.Intersect(surface.Bounds, regionBounds)) { throw new ArgumentOutOfRangeException("roiF", "Region is out of bounds"); } unsafe { for (int x = startIndex; x < startIndex + length; ++x) { ApplyRectangle(surface, Rectangle.Truncate(roiF[x])); } } }
protected override unsafe void AddSurfaceRectangleToHistogram(Surface surface, Rectangle rect) { long[] histogramB = histogram[0]; long[] histogramG = histogram[1]; long[] histogramR = histogram[2]; for (int y = rect.Top; y < rect.Bottom; ++y) { ColorBgra* ptr = surface.GetPointAddressUnchecked(rect.Left, y); for (int x = rect.Left; x < rect.Right; ++x) { ++histogramB[ptr->B]; ++histogramG[ptr->G]; ++histogramR[ptr->R]; ++ptr; } } }
private void DrawGradient(Graphics g) { g.PixelOffsetMode = PixelOffsetMode.Half; Rectangle gradientRect; float gradientAngle; switch (this.orientation) { case Orientation.Horizontal: gradientAngle = 180.0f; break; case Orientation.Vertical: gradientAngle = 90.0f; break; default: throw new InvalidEnumArgumentException(); } // draw gradient gradientRect = ClientRectangle; switch (this.orientation) { case Orientation.Horizontal: gradientRect.Inflate(-triangleHalfLength, -triangleSize + 3); break; case Orientation.Vertical: gradientRect.Inflate(-triangleSize + 3, -triangleHalfLength); break; default: throw new InvalidEnumArgumentException(); } if (this.customGradient != null && gradientRect.Width > 1 && gradientRect.Height > 1) { Surface gradientSurface = new Surface(gradientRect.Width, gradientRect.Height); using (RenderArgs ra = new RenderArgs(gradientSurface)) { Utility.DrawColorRectangle(ra.Graphics, ra.Bounds, Color.Transparent, false); if (Orientation == Orientation.Horizontal) { for (int x = 0; x < gradientSurface.Width; ++x) { // TODO: refactor, double buffer, save this computation in a bitmap somewhere double index = (double)(x * (this.customGradient.Length - 1)) / (double)(gradientSurface.Width - 1); int indexL = (int)Math.Floor(index); double t = 1.0 - (index - indexL); int indexR = (int)Math.Min(this.customGradient.Length - 1, Math.Ceiling(index)); Color colorL = this.customGradient[indexL]; Color colorR = this.customGradient[indexR]; double a1 = colorL.A / 255.0; double r1 = colorL.R / 255.0; double g1 = colorL.G / 255.0; double b1 = colorL.B / 255.0; double a2 = colorR.A / 255.0; double r2 = colorR.R / 255.0; double g2 = colorR.G / 255.0; double b2 = colorR.B / 255.0; double at = (t * a1) + ((1.0 - t) * a2); double rt; double gt; double bt; if (at == 0) { rt = 0; gt = 0; bt = 0; } else { rt = ((t * a1 * r1) + ((1.0 - t) * a2 * r2)) / at; gt = ((t * a1 * g1) + ((1.0 - t) * a2 * g2)) / at; bt = ((t * a1 * b1) + ((1.0 - t) * a2 * b2)) / at; } int ap = Utility.Clamp((int)Math.Round(at * 255.0), 0, 255); int rp = Utility.Clamp((int)Math.Round(rt * 255.0), 0, 255); int gp = Utility.Clamp((int)Math.Round(gt * 255.0), 0, 255); int bp = Utility.Clamp((int)Math.Round(bt * 255.0), 0, 255); for (int y = 0; y < gradientSurface.Height; ++y) { ColorBgra src = gradientSurface[x, y]; // we are assuming that src.A = 255 int rd = ((rp * ap) + (src.R * (255 - ap))) / 255; int gd = ((gp * ap) + (src.G * (255 - ap))) / 255; int bd = ((bp * ap) + (src.B * (255 - ap))) / 255; // TODO: proper alpha blending! gradientSurface[x, y] = ColorBgra.FromBgra((byte)bd, (byte)gd, (byte)rd, 255); } } g.DrawImage(ra.Bitmap, gradientRect, ra.Bounds, GraphicsUnit.Pixel); } else if (Orientation == Orientation.Vertical) { // TODO } else { throw new InvalidEnumArgumentException(); } } gradientSurface.Dispose(); } else { using (LinearGradientBrush lgb = new LinearGradientBrush(this.ClientRectangle, maxColor, minColor, gradientAngle, false)) { g.FillRectangle(lgb, gradientRect); } } // fill background using (Region nonGradientRegion = new Region()) { nonGradientRegion.MakeInfinite(); nonGradientRegion.Exclude(gradientRect); using (SolidBrush sb = new SolidBrush(this.BackColor)) { g.FillRegion(sb, nonGradientRegion); } } // draw value triangles for (int i = 0; i < this.vals.Length; i++) { int pos = ValueToPosition(vals[i]); Brush brush; Pen pen; if (i == highlight) { brush = Brushes.Blue; pen = (Pen)Pens.White.Clone(); } else { brush = Brushes.Black; pen = (Pen)Pens.Gray.Clone(); } g.SmoothingMode = SmoothingMode.AntiAlias; Point a1; Point b1; Point c1; Point a2; Point b2; Point c2; switch (this.orientation) { case Orientation.Horizontal: a1 = new Point(pos - triangleHalfLength, 0); b1 = new Point(pos, triangleSize - 1); c1 = new Point(pos + triangleHalfLength, 0); a2 = new Point(a1.X, Height - 1 - a1.Y); b2 = new Point(b1.X, Height - 1 - b1.Y); c2 = new Point(c1.X, Height - 1 - c1.Y); break; case Orientation.Vertical: a1 = new Point(0, pos - triangleHalfLength); b1 = new Point(triangleSize - 1, pos); c1 = new Point(0, pos + triangleHalfLength); a2 = new Point(Width - 1 - a1.X, a1.Y); b2 = new Point(Width - 1 - b1.X, b1.Y); c2 = new Point(Width - 1 - c1.X, c1.Y); break; default: throw new InvalidEnumArgumentException(); } if (this.drawNearNub) { g.FillPolygon(brush, new Point[] { a1, b1, c1, a1 }); } if (this.drawFarNub) { g.FillPolygon(brush, new Point[] { a2, b2, c2, a2 }); } if (pen != null) { if (this.drawNearNub) { g.DrawPolygon(pen, new Point[] { a1, b1, c1, a1 }); } if (this.drawFarNub) { g.DrawPolygon(pen, new Point[] { a2, b2, c2, a2 }); } pen.Dispose(); } } }
/// <summary> /// Creates an instance of the RenderArgs class. /// </summary> /// <param name="surface"> /// The Surface to associate with this instance. This instance of RenderArgs does not /// take ownership of this Surface. /// </param> public RenderArgs(Surface surface) { this.surface = surface; this.bitmap = null; this.graphics = null; }
/// <summary> /// Renders, at the appropriate scale, the layer's imagery. /// </summary> /// <param name="dst">The Surface to render to.</param> /// <param name="dstTranslation">The (x,y) location of the upper-left corner of dst within DestinationSize.</param> public abstract void Render(Surface dst, Point offset);
public unsafe void Render(Surface surface, Rectangle[] rois, int startIndex, int length) { byte startAlpha; byte endAlpha; if (this.alphaOnly) { ComputeAlphaOnlyValuesFromColors(this.startColor, this.endColor, out startAlpha, out endAlpha); } else { startAlpha = this.startColor.A; endAlpha = this.endColor.A; } for (int ri = startIndex; ri < startIndex + length; ++ri) { Rectangle rect = rois[ri]; if (this.startPoint.Equals(this.endPoint)) { // Start and End point are the same ... fill with solid color. for (int y = rect.Top; y < rect.Bottom; ++y) { ColorBgra *pixelPtr = surface.GetPointAddress(rect.Left, y); for (int x = rect.Left; x < rect.Right; ++x) { ColorBgra result; if (this.alphaOnly && this.alphaBlending) { byte resultAlpha = (byte)PixelUtils.FastDivideShortByByte((ushort)(pixelPtr->A * endAlpha), 255); result = *pixelPtr; result.A = resultAlpha; } else if (this.alphaOnly && !this.alphaBlending) { result = *pixelPtr; result.A = endAlpha; } else if (!this.alphaOnly && this.alphaBlending) { result = this.normalBlendOp.Apply(*pixelPtr, this.endColor); } else //if (!this.alphaOnly && !this.alphaBlending) { result = this.endColor; } *pixelPtr = result; ++pixelPtr; } } } else { for (int y = rect.Top; y < rect.Bottom; ++y) { ColorBgra *pixelPtr = surface.GetPointAddress(rect.Left, y); if (this.alphaOnly && this.alphaBlending) { for (int x = rect.Left; x < rect.Right; ++x) { float lerpUnbounded = ComputeUnboundedLerp(x, y); float lerpBounded = BoundLerp(lerpUnbounded); byte lerpByte = (byte)(lerpBounded * 255.0f); byte lerpAlpha = this.lerpAlphas[lerpByte]; byte resultAlpha = PixelUtils.FastScaleByteByByte(pixelPtr->A, lerpAlpha); pixelPtr->A = resultAlpha; ++pixelPtr; } } else if (this.alphaOnly && !this.alphaBlending) { for (int x = rect.Left; x < rect.Right; ++x) { float lerpUnbounded = ComputeUnboundedLerp(x, y); float lerpBounded = BoundLerp(lerpUnbounded); byte lerpByte = (byte)(lerpBounded * 255.0f); byte lerpAlpha = this.lerpAlphas[lerpByte]; pixelPtr->A = lerpAlpha; ++pixelPtr; } } else if (!this.alphaOnly && (this.alphaBlending && (startAlpha != 255 || endAlpha != 255))) { // If we're doing all color channels, and we're doing alpha blending, and if alpha blending is necessary for (int x = rect.Left; x < rect.Right; ++x) { float lerpUnbounded = ComputeUnboundedLerp(x, y); float lerpBounded = BoundLerp(lerpUnbounded); byte lerpByte = (byte)(lerpBounded * 255.0f); ColorBgra lerpColor = this.lerpColors[lerpByte]; ColorBgra result = this.normalBlendOp.Apply(*pixelPtr, lerpColor); * pixelPtr = result; ++pixelPtr; } } else //if (!this.alphaOnly && !this.alphaBlending) // or sC.A == 255 && eC.A == 255 { for (int x = rect.Left; x < rect.Right; ++x) { float lerpUnbounded = ComputeUnboundedLerp(x, y); float lerpBounded = BoundLerp(lerpUnbounded); byte lerpByte = (byte)(lerpBounded * 255.0f); ColorBgra lerpColor = this.lerpColors[lerpByte]; * pixelPtr = lerpColor; ++pixelPtr; } } } } } AfterRender(); }
public void Save(Stream dstStream, Document srcDocument, FileType dstFileType, SaveConfigToken parameters, Surface saveScratchSurface) { this.document = srcDocument; this.fileType = dstFileType; this.stream = dstStream; this.saveConfigToken = parameters; this.scratchSurface = saveScratchSurface; DialogResult dr = this.ShowDialog(false, !dstFileType.SavesWithProgress, new ThreadStart(SaveCallback)); }