protected override HistoryMemento OnUndo(ProgressEventHandler progressCallback) { BitmapHistoryMementoData data = base.Data as BitmapHistoryMementoData; BitmapLayer layer = (BitmapLayer)this.historyWorkspace.Document.Layers[this.layerIndex]; RectInt32[] savedRegion = data.SavedRegion; MaskedSurface surface = null; BitmapHistoryMemento memento = new BitmapHistoryMemento(base.Name, base.Image, this.historyWorkspace, this.layerIndex, savedRegion); if (surface != null) { surface.Draw(layer.Surface); } else { using (FileStream stream = FileSystem.OpenStreamingFile(this.tempFileName, FileAccess.Read)) { LoadSurfaceRegion(stream, layer.Surface, data.SavedRegion); } this.tempFileHandle.Dispose(); this.tempFileHandle = null; } if (savedRegion.Length != 0) { RectInt32 roi = savedRegion.Bounds(); layer.Invalidate(roi); } return(memento); }
public bool PerformAction() { bool flag2; try { if (this.documentWorkspace.ApplyFunction(new AddNewBlankLayerFunction()) == HistoryFunctionResult.Success) { PasteAction action = new PasteAction(this.documentWorkspace, this.clipData, this.maskedSurface); if (!action.PerformAction()) { using (new WaitCursorChanger(this.documentWorkspace)) { this.documentWorkspace.History.StepBackward(this.documentWorkspace.AppWorkspace); goto Label_006E; } } return(true); } Label_006E: flag2 = false; } finally { this.clipData = null; this.maskedSurface = null; } return(flag2); }
public MoveToolContext(MoveToolContext cloneMe) : base(cloneMe) { this.poLiftedPixelsGuid = cloneMe.poLiftedPixelsGuid; this.poLiftedPixels = cloneMe.poLiftedPixels; // do not clone this.liftedPixels = cloneMe.liftedPixels; // do not clone }
public TransformBenchmark(string name, Surface dst, MaskedSurface src, Matrix transform, bool highQuality) : base(name) { Dest = dst; Source = src; Transform = transform.Clone(); HighQuality = highQuality; }
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; }
private static Surface CreateThumbnail(MaskedSurface maskedSurface) { int thumbSideLength = UIUtil.ScaleWidth(120); Surface surfaceReadOnly = maskedSurface.SurfaceReadOnly; GeometryList geometryMaskCopy = maskedSurface.GetGeometryMaskCopy(); RectInt32 maskBounds = maskedSurface.GeometryMaskBounds.Int32Bound; return(CreateThumbnail(surfaceReadOnly, geometryMaskCopy, maskBounds, thumbSideLength)); }
public bool PerformAction() { bool flag; try { flag = this.PerformActionImpl(); } finally { this.clipData = null; this.maskedSurface = null; } return(flag); }
public PasteAction(DocumentWorkspace documentWorkspace, IPdnDataObject clipData, MaskedSurface maskedSurface) { this.documentWorkspace = documentWorkspace; this.clipData = clipData; this.maskedSurface = maskedSurface; }
private bool PerformActionImpl() { PointInt32 num2; RectInt32 num3; if (this.clipData == null) { try { using (new WaitCursorChanger(this.documentWorkspace)) { CleanupManager.RequestCleanup(); this.clipData = PdnClipboard.GetDataObject(); } } catch (OutOfMemoryException exception) { ExceptionDialog.ShowErrorDialog(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.OutOfMemory"), exception); return(false); } catch (Exception exception2) { ExceptionDialog.ShowErrorDialog(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.TransferFromClipboard"), exception2); return(false); } } bool handled = false; if (this.documentWorkspace.Tool != null) { this.documentWorkspace.Tool.PerformPaste(this.clipData, out handled); } if (handled) { return(true); } if (this.maskedSurface == null) { try { using (new WaitCursorChanger(this.documentWorkspace)) { this.maskedSurface = ClipboardUtil.GetClipboardImage(this.documentWorkspace, this.clipData); } } catch (OutOfMemoryException exception3) { ExceptionDialog.ShowErrorDialog(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.OutOfMemory"), exception3); return(false); } catch (Exception exception4) { ExceptionDialog.ShowErrorDialog(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.TransferFromClipboard"), exception4); return(false); } } if (this.maskedSurface == null) { MessageBoxUtil.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.NoImage")); return(false); } RectInt32 cachedGeometryMaskScansBounds = this.maskedSurface.GetCachedGeometryMaskScansBounds(); if ((cachedGeometryMaskScansBounds.Width > this.documentWorkspace.Document.Width) || (cachedGeometryMaskScansBounds.Height > this.documentWorkspace.Document.Height)) { Surface surface; try { using (new WaitCursorChanger(this.documentWorkspace)) { surface = CreateThumbnail(this.maskedSurface); } } catch (OutOfMemoryException) { surface = null; } DialogResult result = ShowExpandCanvasTaskDialog(this.documentWorkspace, surface); int activeLayerIndex = this.documentWorkspace.ActiveLayerIndex; ColorBgra background = this.documentWorkspace.ToolSettings.SecondaryColor.Value; if (result != DialogResult.Cancel) { if (result != DialogResult.Yes) { if (result != DialogResult.No) { throw ExceptionUtil.InvalidEnumArgumentException <DialogResult>(result, "dr"); } goto Label_031D; } using (new PushNullToolMode(this.documentWorkspace)) { int width = Math.Max(cachedGeometryMaskScansBounds.Width, this.documentWorkspace.Document.Width); Size newSize = new Size(width, Math.Max(cachedGeometryMaskScansBounds.Height, this.documentWorkspace.Document.Height)); Document document = CanvasSizeAction.ResizeDocument(this.documentWorkspace.Document, newSize, AnchorEdge.TopLeft, background); if (document == null) { return(false); } SelectionHistoryMemento memento = new SelectionHistoryMemento(null, null, this.documentWorkspace); ReplaceDocumentHistoryMemento memento2 = new ReplaceDocumentHistoryMemento(CanvasSizeAction.StaticName, CanvasSizeAction.StaticImage, this.documentWorkspace); this.documentWorkspace.Document = document; HistoryMemento[] actions = new HistoryMemento[] { memento, memento2 }; CompoundHistoryMemento memento3 = new CompoundHistoryMemento(CanvasSizeAction.StaticName, CanvasSizeAction.StaticImage, actions); this.documentWorkspace.History.PushNewMemento(memento3); this.documentWorkspace.ActiveLayer = (Layer)this.documentWorkspace.Document.Layers[activeLayerIndex]; goto Label_031D; } } return(false); } Label_031D: num3 = this.documentWorkspace.Document.Bounds(); RectDouble visibleDocumentRect = this.documentWorkspace.VisibleDocumentRect; RectInt32? nullable = visibleDocumentRect.Int32Inset(); RectDouble num5 = nullable.HasValue ? ((RectDouble)nullable.Value) : visibleDocumentRect; RectInt32 num6 = num5.Int32Bound; if (num5.Contains(cachedGeometryMaskScansBounds)) { num2 = new PointInt32(0, 0); } else { int num12; int num13; int num16; int num17; if (cachedGeometryMaskScansBounds.X < num5.Left) { num12 = -cachedGeometryMaskScansBounds.X + num6.X; } else if (cachedGeometryMaskScansBounds.Right > num6.Right) { num12 = (-cachedGeometryMaskScansBounds.X + num6.Right) - cachedGeometryMaskScansBounds.Width; } else { num12 = 0; } if (cachedGeometryMaskScansBounds.Y < num5.Top) { num13 = -cachedGeometryMaskScansBounds.Y + num6.Y; } else if (cachedGeometryMaskScansBounds.Bottom > num6.Bottom) { num13 = (-cachedGeometryMaskScansBounds.Y + num6.Bottom) - cachedGeometryMaskScansBounds.Height; } else { num13 = 0; } PointInt32 num14 = new PointInt32(num12, num13); RectInt32 num15 = new RectInt32(cachedGeometryMaskScansBounds.X + num14.X, cachedGeometryMaskScansBounds.Y + num14.Y, cachedGeometryMaskScansBounds.Width, cachedGeometryMaskScansBounds.Height); if (num15.X < 0) { num16 = num12 - num15.X; } else { num16 = num12; } if (num15.Y < 0) { num17 = num13 - num15.Y; } else { num17 = num13; } PointInt32 num18 = new PointInt32(num16, num17); RectInt32 rect = new RectInt32(cachedGeometryMaskScansBounds.X + num18.X, cachedGeometryMaskScansBounds.Y + num18.Y, cachedGeometryMaskScansBounds.Width, cachedGeometryMaskScansBounds.Height); if (num3.Contains(rect)) { num2 = num18; } else { PointInt32 num20 = num18; if (rect.Right > num3.Right) { int num21 = rect.Right - num3.Right; int num22 = Math.Min(num21, rect.Left); num20.X -= num22; } if (rect.Bottom > num3.Bottom) { int num23 = rect.Bottom - num3.Bottom; int num24 = Math.Min(num23, rect.Top); num20.Y -= num24; } num2 = num20; } } RectInt32 b = this.documentWorkspace.VisibleDocumentRect.Int32Bound; RectInt32 a = new RectInt32(cachedGeometryMaskScansBounds.X + num2.X, cachedGeometryMaskScansBounds.Y + num2.Y, cachedGeometryMaskScansBounds.Width, cachedGeometryMaskScansBounds.Height); bool hasZeroArea = RectInt32.Intersect(a, b).HasZeroArea; MoveTool.BeginPaste(this.documentWorkspace, PdnResources.GetString("CommonAction.Paste"), PdnResources.GetImageResource("Icons.MenuEditPasteIcon.png"), this.maskedSurface.SurfaceReadOnly, this.maskedSurface.GeometryMask, num2); if (hasZeroArea) { PointInt32 num25 = new PointInt32(b.Left + (b.Width / 2), b.Top + (b.Height / 2)); PointInt32 num26 = new PointInt32(a.Left + (a.Width / 2), a.Top + (a.Height / 2)); SizeInt32 num27 = new SizeInt32(num26.X - num25.X, num26.Y - num25.Y); PointDouble documentScrollPosition = this.documentWorkspace.DocumentScrollPosition; PointDouble num29 = new PointDouble(documentScrollPosition.X + num27.Width, documentScrollPosition.Y + num27.Height); this.documentWorkspace.DocumentScrollPosition = num29; } return(true); }
public bool PerformAction() { bool success = true; if (this.documentWorkspace.Selection.IsEmpty || !(this.documentWorkspace.ActiveLayer is BitmapLayer)) { return false; } try { using (new WaitCursorChanger(this.documentWorkspace)) { Utility.GCFullCollect(); PdnRegion selectionRegion = this.documentWorkspace.Selection.CreateRegion(); PdnGraphicsPath selectionOutline = this.documentWorkspace.Selection.CreatePath(); BitmapLayer activeLayer = (BitmapLayer)this.documentWorkspace.ActiveLayer; RenderArgs renderArgs = new RenderArgs(activeLayer.Surface); MaskedSurface maskedSurface = new MaskedSurface(renderArgs.Surface, selectionOutline); SurfaceForClipboard surfaceForClipboard = new SurfaceForClipboard(maskedSurface); Rectangle selectionBounds = Utility.GetRegionBounds(selectionRegion); if (selectionBounds.Width > 0 && selectionBounds.Height > 0) { Surface copySurface = new Surface(selectionBounds.Width, selectionBounds.Height); Bitmap copyBitmap = copySurface.CreateAliasedBitmap(); Bitmap copyOpaqueBitmap = new Bitmap(copySurface.Width, copySurface.Height, PixelFormat.Format24bppRgb); using (Graphics copyBitmapGraphics = Graphics.FromImage(copyBitmap)) { copyBitmapGraphics.Clear(Color.White); } maskedSurface.Draw(copySurface, -selectionBounds.X, -selectionBounds.Y); using (Graphics copyOpaqueBitmapGraphics = Graphics.FromImage(copyOpaqueBitmap)) { copyOpaqueBitmapGraphics.Clear(Color.White); copyOpaqueBitmapGraphics.DrawImage(copyBitmap, 0, 0); } DataObject dataObject = new DataObject(); dataObject.SetData(DataFormats.Bitmap, copyOpaqueBitmap); dataObject.SetData(surfaceForClipboard); int retryCount = 2; while (retryCount >= 0) { try { using (new WaitCursorChanger(this.documentWorkspace)) { Clipboard.SetDataObject(dataObject, true); } break; } catch { if (retryCount == 0) { success = false; Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("CopyAction.Error.TransferToClipboard")); } else { Thread.Sleep(200); } } finally { --retryCount; } } copySurface.Dispose(); copyBitmap.Dispose(); copyOpaqueBitmap.Dispose(); } selectionRegion.Dispose(); selectionOutline.Dispose(); renderArgs.Dispose(); maskedSurface.Dispose(); } } catch (OutOfMemoryException) { success = false; Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("CopyAction.Error.OutOfMemory")); } catch (Exception) { success = false; Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("CopyAction.Error.Generic")); } Utility.GCFullCollect(); return success; }
static void Main(string[] args) { for (int i = 0; i < args.Length; i++) { switch (args[i]) { case "/proc": if (i + 1 == args.Length) { Console.WriteLine("Use /proc <N> to specify number of processors"); return; } int numProcs; if (Int32.TryParse(args[i + 1], out numProcs)) { // only increment i if successful b/c we're going to continue the run // with the default # of processors and don't want to automatically // eat the next parameter. ++i; Processor.LogicalCpuCount = numProcs; } else { Console.WriteLine("You must specify a integer for /proc <N>, continuing with default"); } break; case "/image": if (i + 1 == args.Length) { Console.WriteLine("Use /image <filename> to specify a file to perform benchmark with"); return; } ++i; benchmarkImageName = args[i]; if (!System.IO.File.Exists(benchmarkImageName)) { Console.WriteLine("Specified image doesn't exist"); return; } break; case "/tsv": useTsvOutput = true; break; case "/?": PrintHelp(); return; default: break; } } //Processor.LogicalCpuCount = 1; Console.WriteLine("PdnBench v" + PdnInfo.GetVersion()); Console.WriteLine("Running in " + (8 * Marshal.SizeOf(typeof(IntPtr))) + "-bit mode on " + Processor.NativeArchitecture.ToString().ToLower() + " OS"); Console.WriteLine("Processor: " + Processor.LogicalCpuCount + "x " + Processor.CpuName); Console.WriteLine("Memory: " + ((Memory.TotalPhysicalBytes / 1024) / 1024) + " MB"); Console.WriteLine(); Console.WriteLine("Using " + Processor.LogicalCpuCount + " threads."); ArrayList benchmarks = new ArrayList(); Document document; Console.Write("Loading image ... "); Stream imageStream = null; try { imageStream = (defaultImageName == benchmarkImageName) ? Assembly.GetExecutingAssembly().GetManifestResourceStream(benchmarkImageName) : new FileStream(benchmarkImageName, FileMode.Open); JpegFileType jft = new JpegFileType(); document = jft.Load(imageStream); } finally { if (imageStream != null) { imageStream.Dispose(); } } Console.WriteLine("(" + document.Width + " x " + document.Height + ") done"); Surface surface = ((BitmapLayer)document.Layers[0]).Surface; #if EFFECTS for (double i = 0; i < (2 * Math.PI); i += 70.0 * ((2 * Math.PI) / 360.0)) { benchmarks.Add( new EffectBenchmark("Rotate/Zoom at " + ((i * 180.0) / Math.PI).ToString("F2") + " degrees", 3, new PaintDotNet.Effects.RotateZoomEffect(), new PaintDotNet.Effects.RotateZoomEffectConfigToken( true, (float)(Math.PI * 0.3f), (float)((Math.PI * -0.4) + i), 50, 0.5f, new PointF(-0.2f, 0.3f), false, true), surface)); } for (int i = 1; i <= 4; i += 3) { for (int j = 10; j < 100; j += 75) { benchmarks.Add( new EffectBenchmark( "Oil Painting, brush size = " + i + ", coarseness = " + j, 1, new OilPaintingEffect(), new TwoAmountsConfigToken(i, j), surface)); } } for (int i = 2; i <= 50; i += i) { benchmarks.Add( new EffectBenchmark( "Blur with radius of " + i, 1, new BlurEffect(), new AmountEffectConfigToken(i), surface)); } for (int i = 1; i <= 4; i += 3) { benchmarks.Add( new EffectBenchmark( "Sharpen with value of " + i, 1, new SharpenEffect(), new AmountEffectConfigToken(i), surface)); } benchmarks.Add( new EffectBenchmark( "Auto-Levels", 50, new AutoLevelEffect(), null, surface)); for (int i = 81; i >= 5; i /= 3) { benchmarks.Add( new EffectBenchmark( "Clouds, roughness = " + i, 2, new CloudsEffect(), new CloudsEffectConfigToken(50, i, 12345, new UserBlendOps.NormalBlendOp()), surface)); } for (int i = 4; i <= 64; i *= 4) { benchmarks.Add( new EffectBenchmark( "Median, radius " + i, 1, new MedianEffect(), new TwoAmountsConfigToken(/*radius*/ i, /*roughness*/ 50), surface)); } for (int i = 4; i <= 64; i *= 4) { benchmarks.Add( new EffectBenchmark( "Unfocus, radius " + i, 1, new UnfocusEffect(), new AmountEffectConfigToken(i), surface)); } benchmarks.Add( new EffectBenchmark( "Motion Blur, Horizontal", 1, new MotionBlurEffect(), new MotionBlurEffectConfigToken(0, 100, true), surface)); benchmarks.Add( new EffectBenchmark( "Motion Blur, Vertical", 1, new MotionBlurEffect(), new MotionBlurEffectConfigToken(90, 100, true), surface)); #endif Surface dst = new Surface(surface.Width * 4, surface.Height * 4); #if RESIZE // Resize benchmarks for (int i = 1; i < 8; i += 2) { int newWidth = i * (dst.Width / 8); int newHeight = i * (dst.Height / 8); Surface dstWindow = dst.CreateWindow(new Rectangle(0, 0, newWidth, newHeight)); benchmarks.Add(new ResizeBenchmark("Resize from " + surface.Width + "x" + surface.Height + " to " + newWidth + "x" + newHeight, surface, dstWindow)); benchmarks.Add(new ResizeBenchmark("Resize from " + newWidth + "x" + newHeight + " to " + surface.Width + "x" + surface.Height, dstWindow, surface)); } #endif #if GRADIENT // Gradient benchmarks benchmarks.Add(new GradientBenchmark( "Linear reflected gradient @ " + dst.Width + "x" + dst.Height + " (5x)", dst, new GradientRenderers.LinearReflected(false, new UserBlendOps.NormalBlendOp()), 2)); benchmarks.Add(new GradientBenchmark( "Conical gradient @ " + dst.Width + "x" + dst.Height + " (5x)", dst, new GradientRenderers.Conical(false, new UserBlendOps.NormalBlendOp()), 2)); benchmarks.Add(new GradientBenchmark( "Radial gradient @ " + dst.Width + "x" + dst.Height + " (5x)", dst, new GradientRenderers.Radial(false, new UserBlendOps.NormalBlendOp()), 2)); #endif #if COMPOSITION // Composition benchmarks Document doc1 = new Document(surface.Size); BitmapLayer layer1 = Layer.CreateBackgroundLayer(doc1.Width, doc1.Height); layer1.Surface.CopySurface(surface); doc1.Layers.Add(layer1); doc1.Layers.Add(layer1.Clone()); doc1.Layers.Add(layer1.Clone()); doc1.Layers.Add(layer1.Clone()); benchmarks.Add(new CompositionBenchmark("Compositing one layer, Normal blend mode, 255 opacity (" + CompositionBenchmark.Iterations + "x)", doc1, surface, delegate(int layerIndex, Layer layer) { if (layerIndex == 0) { layer.Visible = true; layer.Opacity = 255; ((BitmapLayer)layer).SetBlendOp(new UserBlendOps.NormalBlendOp()); } else { layer.Visible = false; } })); benchmarks.Add(new CompositionBenchmark("Compositing one layer, Normal blend mode, 128 opacity (" + CompositionBenchmark.Iterations + "x)", doc1, surface, delegate(int layerIndex, Layer layer) { if (layerIndex == 0) { layer.Visible = true; layer.Opacity = 128; ((BitmapLayer)layer).SetBlendOp(new UserBlendOps.NormalBlendOp()); } else { layer.Visible = false; } })); benchmarks.Add(new CompositionBenchmark("Compositing four layers, Normal blend mode, 255 opacity (" + CompositionBenchmark.Iterations + "x)", doc1, surface, delegate(int layerIndex, Layer layer) { layer.Visible = true; layer.Opacity = 255; ((BitmapLayer)layer).SetBlendOp(new UserBlendOps.NormalBlendOp()); })); benchmarks.Add(new CompositionBenchmark("Compositing four layers, Normal blend mode, 255 (layer 0) and 128 (layer 1-3) opacity (" + CompositionBenchmark.Iterations + "x)", doc1, surface, delegate(int layerIndex, Layer layer) { layer.Visible = true; layer.Opacity = 128; ((BitmapLayer)layer).SetBlendOp(new UserBlendOps.NormalBlendOp()); })); benchmarks.Add(new CompositionBenchmark("Compositing four layers, Normal blend mode, 128 opacity (" + CompositionBenchmark.Iterations + "x)", doc1, surface, delegate(int layerIndex, Layer layer) { layer.Visible = true; layer.Opacity = 128; ((BitmapLayer)layer).SetBlendOp(new UserBlendOps.NormalBlendOp()); })); benchmarks.Add(new CompositionBenchmark("Compositing three layers, Normal+Multiply+Overlay blending, 150+255+170 opacity (" + CompositionBenchmark.Iterations + "x)", doc1, surface, delegate(int layerIndex, Layer layer) { if (layerIndex == 0) { layer.Visible = true; layer.Opacity = 150; ((BitmapLayer)layer).SetBlendOp(new UserBlendOps.NormalBlendOp()); } else if (layerIndex == 1) { layer.Visible = true; layer.Opacity = 255; ((BitmapLayer)layer).SetBlendOp(new UserBlendOps.MultiplyBlendOp()); } else if (layerIndex == 2) { layer.Visible = true; layer.Opacity = 170; ((BitmapLayer)layer).SetBlendOp(new UserBlendOps.OverlayBlendOp()); } else { layer.Visible = false; } })); #endif #if TRANSFORM // Transform benchmarks Matrix m = new Matrix(); m.Reset(); MaskedSurface msSimple = new MaskedSurface(surface, new PdnRegion(surface.Bounds)); // simple masked surface PdnRegion complexRegion = new PdnRegion(surface.Bounds); // cut 4 holes in region 1 to form a complex clipping surface for (int x = -1; x < 3; ++x) { for (int y = -1; y < 3; ++y) { int left = (1 + (x * 3)) * (surface.Width / 6); int top = (1 + (x * 3)) * (surface.Height / 6); int right = (2 + (x * 3)) * (surface.Width / 6); int bottom = (2 + (x * 3)) * (surface.Height / 6); Rectangle rect = Rectangle.FromLTRB(left, top, right, bottom); PdnGraphicsPath path = new PdnGraphicsPath(); path.AddEllipse(rect); complexRegion.Exclude(path); } } MaskedSurface msComplex = new MaskedSurface(surface, complexRegion); benchmarks.Add(new TransformBenchmark("Transform simple surface, no transform, nearest neighbor resampling (" + TransformBenchmark.Iterations + "x)", surface, msSimple, m, false)); benchmarks.Add(new TransformBenchmark("Transform complex surface, no transform, nearest neighbor resampling (" + TransformBenchmark.Iterations + "x)", surface, msSimple, m, false)); benchmarks.Add(new TransformBenchmark("Transform simple surface, no transform, bilinear resampling (" + TransformBenchmark.Iterations + "x)", surface, msSimple, m, true)); benchmarks.Add(new TransformBenchmark("Transform complex surface, no transform, bilinear resampling (" + TransformBenchmark.Iterations + "x)", surface, msSimple, m, true)); Matrix m2 = m.Clone(); m2.RotateAt(45.0f, new PointF(surface.Width / 2, surface.Height / 2)); benchmarks.Add(new TransformBenchmark("Transform simple surface, 45 deg. rotation about center, bilinear resampling (" + TransformBenchmark.Iterations + "x)", surface, msSimple, m2, true)); benchmarks.Add(new TransformBenchmark("Transform complex surface, 45 deg. rotation about center, bilinear resampling (" + TransformBenchmark.Iterations + "x)", surface, msSimple, m2, true)); Matrix m3 = m.Clone(); m3.Scale(0.5f, 0.75f); benchmarks.Add(new TransformBenchmark("Transform simple surface, 50% x-scaling 75% y-scaling, bilinear resampling (" + TransformBenchmark.Iterations + "x)", surface, msSimple, m3, true)); benchmarks.Add(new TransformBenchmark("Transform complex surface, 50% x-scaling 75% y-scaling, bilinear resampling (" + TransformBenchmark.Iterations + "x)", surface, msSimple, m3, true)); #endif #if BLIT // Blit benchmarks benchmarks.Add(new ZoomOutBlitBenchmark("Zoom out, rotated grid multisampling, 66% (" + ZoomOutBlitBenchmark.IterationCount + "x)", surface, dst, new Size((surface.Width * 2) / 3, (surface.Height * 2) / 3))); benchmarks.Add(new ZoomOutBlitBenchmark("Zoom out, rotated grid multisampling, 28% (" + ZoomOutBlitBenchmark.IterationCount + "x)", surface, dst, new Size((surface.Width * 28) / 100, (surface.Height * 28) / 100))); benchmarks.Add(new ZoomOneToOneBlitBenchmark("Zoom 1:1, straight blit (" + ZoomOneToOneBlitBenchmark.IterationCount + "x)", surface, dst.CreateWindow(new Rectangle(0, 0, surface.Width, surface.Height)))); #endif // Run benchmarks! Timing timing = new Timing(); ulong start = timing.GetTickCount(); foreach (Benchmark benchmark in benchmarks) { Console.Write(benchmark.Name + (useTsvOutput ? "\t" : " ... ")); TimeSpan timeSpan = benchmark.Execute(); Console.WriteLine(" " + timeSpan.TotalMilliseconds.ToString() + (useTsvOutput ? "\t" : "") + " milliseconds"); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); GC.WaitForPendingFinalizers(); } ulong end = timing.GetTickCount(); Console.WriteLine(); Console.WriteLine("Total time: " + (useTsvOutput ? "\t" : "") + (end - start).ToString() + (useTsvOutput ? "\t" : "") + " milliseconds"); Console.WriteLine(); }
protected override HistoryMemento OnUndo() { BitmapHistoryMementoData data = this.Data as BitmapHistoryMementoData; BitmapLayer layer = (BitmapLayer)this.historyWorkspace.Document.Layers[this.layerIndex]; PdnRegion region; MaskedSurface maskedSurface = null; if (this.poMaskedSurfaceRef != Guid.Empty) { PersistedObject <MaskedSurface> poMS = PersistedObjectLocker.Get <MaskedSurface>(this.poMaskedSurfaceRef); maskedSurface = poMS.Object; region = maskedSurface.CreateRegion(); } else if (data.UndoImage == null) { region = data.SavedRegion; } else { region = data.UndoImage.Region; } BitmapHistoryMemento redo; if (this.poUndoMaskedSurfaceRef == Guid.Empty) { redo = new BitmapHistoryMemento(Name, Image, this.historyWorkspace, this.layerIndex, region); redo.poUndoMaskedSurfaceRef = this.poMaskedSurfaceRef; } else { redo = new BitmapHistoryMemento(Name, Image, this.historyWorkspace, this.layerIndex, this.poUndoMaskedSurfaceRef); } PdnRegion simplified = Utility.SimplifyAndInflateRegion(region); if (maskedSurface != null) { maskedSurface.Draw(layer.Surface); } else if (data.UndoImage == null) { using (FileStream input = FileSystem.OpenStreamingFile(this.tempFileName, FileAccess.Read)) { LoadSurfaceRegion(input, layer.Surface, data.SavedRegion); } data.SavedRegion.Dispose(); this.tempFileHandle.Dispose(); this.tempFileHandle = null; } else { data.UndoImage.Draw(layer.Surface); data.UndoImage.Dispose(); } layer.Invalidate(simplified); simplified.Dispose(); return(redo); }
/// <summary> /// Provided as a special entry point so that Paste can work well. /// </summary> /// <param name="surface">What you want to paste.</param> /// <param name="offset">Where you want to paste it.</param> public void PasteMouseDown(SurfaceForClipboard sfc, Point offset) { if (this.context.lifted) { Drop(); } MaskedSurface pixels = sfc.MaskedSurface; PdnGraphicsPath pastePath = pixels.CreatePath(); PdnRegion pasteRegion = new PdnRegion(pastePath); PdnRegion simplifiedPasteRegion = Utility.SimplifyAndInflateRegion(pasteRegion); HistoryMemento bitmapAction = new BitmapHistoryMemento(Name, Image, DocumentWorkspace, ActiveLayerIndex, simplifiedPasteRegion); // SLOW (110ms) this.currentHistoryMementos.Add(bitmapAction); PushContextHistoryMemento(); this.context.seriesGuid = Guid.NewGuid(); this.context.currentMode = Mode.Translate; this.context.startEdge = Edge.None; this.context.startAngle = 0.0f; this.ourContext.LiftedPixels = pixels; this.context.lifted = true; this.context.liftTransform = new Matrix(); this.context.liftTransform.Reset(); this.context.deltaTransform = new Matrix(); this.context.deltaTransform.Reset(); this.context.offset = new Point(0, 0); bool oldDD = this.dontDrop; this.dontDrop = true; SelectionHistoryMemento sha = new SelectionHistoryMemento(null, null, DocumentWorkspace); this.currentHistoryMementos.Add(sha); Selection.PerformChanging(); Selection.Reset(); Selection.SetContinuation(pastePath, CombineMode.Replace, true); pastePath = null; Selection.CommitContinuation(); Selection.PerformChanged(); PushContextHistoryMemento(); this.context.liftedBounds = Selection.GetBoundsF(false); this.context.startBounds = this.context.liftedBounds; this.context.baseTransform = new Matrix(); this.context.baseTransform.Reset(); this.tracking = true; this.dontDrop = oldDD; this.didPaste = true; this.tracking = true; DestroyNubs(); PositionNubs(this.context.currentMode); // we use the value 70,000 to simulate mouse input because that's guaranteed to be out of bounds of where // the mouse can actually be -- PDN is limited to 65536 x 65536 images by design MouseEventArgs mea1 = new MouseEventArgs(MouseButtons.Left, 0, 70000, 70000, 0); MouseEventArgs mea2 = new MouseEventArgs(MouseButtons.Left, 0, 70000 + offset.X, 70000 + offset.Y, 0); this.context.startMouseXY = new Point(70000, 70000); OnMouseDown(mea1); OnMouseMove(mea2); // SLOW (200ms) OnMouseUp(mea2); }
/// <summary> /// Pastes from the clipboard into the document. /// </summary> /// <returns>true if the paste operation completed, false if there was an error or if it was cancelled for some reason</returns> public bool PerformAction() { SurfaceForClipboard surfaceForClipboard = null; IDataObject clipData = null; try { Utility.GCFullCollect(); clipData = Clipboard.GetDataObject(); } catch (ExternalException) { Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.TransferFromClipboard")); return(false); } catch (OutOfMemoryException) { Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.OutOfMemory")); return(false); } // First "ask" the current tool if it wants to handle it bool handledByTool = false; if (this.documentWorkspace.Tool != null) { this.documentWorkspace.Tool.PerformPaste(clipData, out handledByTool); } if (handledByTool) { return(true); } if (clipData.GetDataPresent(typeof(SurfaceForClipboard))) { try { Utility.GCFullCollect(); surfaceForClipboard = clipData.GetData(typeof(SurfaceForClipboard)) as SurfaceForClipboard; } catch (OutOfMemoryException) { Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.OutOfMemory")); return(false); } } if (surfaceForClipboard != null && surfaceForClipboard.MaskedSurface.IsDisposed) { // Have been getting crash reports where sfc contains a disposed MaskedSurface ... surfaceForClipboard = null; } if (surfaceForClipboard == null && (clipData.GetDataPresent(DataFormats.Bitmap, true) || clipData.GetDataPresent(DataFormats.EnhancedMetafile, true))) { Image image; try { Utility.GCFullCollect(); image = clipData.GetData(DataFormats.Bitmap, true) as Image; if (image == null) { image = SystemLayer.Clipboard.GetEmfFromClipboard(this.documentWorkspace); } } catch (OutOfMemoryException) { Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.OutOfMemory")); return(false); } // Sometimes we get weird errors if we're in, say, 16-bit mode but the image was copied // to the clipboard in 32-bit mode if (image == null) { Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.NotRecognized")); return(false); } MaskedSurface maskedSurface = null; try { Utility.GCFullCollect(); Bitmap bitmap; Surface surface = null; if (image is Bitmap) { bitmap = (Bitmap)image; image = null; } else { bitmap = new Bitmap(image); image.Dispose(); image = null; } surface = Surface.CopyFromBitmap(bitmap); bitmap.Dispose(); bitmap = null; maskedSurface = new MaskedSurface(surface, new PdnRegion(surface.Bounds)); surface.Dispose(); surface = null; } catch (Exception) { Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.OutOfMemory")); return(false); } surfaceForClipboard = new SurfaceForClipboard(maskedSurface); } if (surfaceForClipboard == null || surfaceForClipboard.MaskedSurface == null) { // silently fail: like what if a program overwrote the clipboard in between the time // we enabled the "Paste" menu item and the user actually clicked paste? // it could happen! Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.NoImage")); return(false); } // If the image is larger than the document, ask them if they'd like to make the image larger first Rectangle bounds = surfaceForClipboard.Bounds; if (bounds.Width > this.documentWorkspace.Document.Width || bounds.Height > this.documentWorkspace.Document.Height) { Surface thumb; try { using (new WaitCursorChanger(this.documentWorkspace)) { thumb = CreateThumbnail(surfaceForClipboard); } } catch (OutOfMemoryException) { thumb = null; } DialogResult dr = ShowExpandCanvasTaskDialog(this.documentWorkspace, thumb); int layerIndex = this.documentWorkspace.ActiveLayerIndex; switch (dr) { case DialogResult.Yes: Size newSize = new Size(Math.Max(bounds.Width, this.documentWorkspace.Document.Width), Math.Max(bounds.Height, this.documentWorkspace.Document.Height)); Document newDoc = CanvasSizeAction.ResizeDocument( this.documentWorkspace.Document, newSize, AnchorEdge.TopLeft, this.documentWorkspace.AppWorkspace.AppEnvironment.SecondaryColor); if (newDoc == null) { return(false); // user clicked cancel! } else { HistoryMemento rdha = new ReplaceDocumentHistoryMemento( CanvasSizeAction.StaticName, CanvasSizeAction.StaticImage, this.documentWorkspace); this.documentWorkspace.Document = newDoc; this.documentWorkspace.History.PushNewMemento(rdha); this.documentWorkspace.ActiveLayer = (Layer)this.documentWorkspace.Document.Layers[layerIndex]; } break; case DialogResult.No: break; case DialogResult.Cancel: return(false); default: throw new InvalidEnumArgumentException("Internal error: DialogResult was neither Yes, No, nor Cancel"); } } // Decide where to paste to: If the paste is within bounds of the document, do as normal // Otherwise, center it. Rectangle docBounds = this.documentWorkspace.Document.Bounds; Rectangle intersect1 = Rectangle.Intersect(docBounds, bounds); bool doMove = intersect1 != bounds; //intersect1.IsEmpty; Point pasteOffset; if (doMove) { pasteOffset = new Point(-bounds.X + (docBounds.Width / 2) - (bounds.Width / 2), -bounds.Y + (docBounds.Height / 2) - (bounds.Height / 2)); } else { pasteOffset = new Point(0, 0); } // Paste to the place it was originally copied from (for PDN-to-PDN transfers) // and then if its not pasted within the viewable rectangle we pan to that location RectangleF visibleDocRectF = this.documentWorkspace.VisibleDocumentRectangleF; Rectangle visibleDocRect = Utility.RoundRectangle(visibleDocRectF); Rectangle bounds2 = new Rectangle(new Point(bounds.X + pasteOffset.X, bounds.Y + pasteOffset.Y), bounds.Size); Rectangle intersect2 = Rectangle.Intersect(bounds2, visibleDocRect); bool doPan = intersect2.IsEmpty; this.documentWorkspace.SetTool(null); this.documentWorkspace.SetToolFromType(typeof(MoveTool)); ((MoveTool)this.documentWorkspace.Tool).PasteMouseDown(surfaceForClipboard, pasteOffset); if (doPan) { Point centerPtView = new Point(visibleDocRect.Left + (visibleDocRect.Width / 2), visibleDocRect.Top + (visibleDocRect.Height / 2)); Point centerPtPasted = new Point(bounds2.Left + (bounds2.Width / 2), bounds2.Top + (bounds2.Height / 2)); Size delta = new Size(centerPtPasted.X - centerPtView.X, centerPtPasted.Y - centerPtView.Y); PointF docScrollPos = this.documentWorkspace.DocumentScrollPositionF; PointF newDocScrollPos = new PointF(docScrollPos.X + delta.Width, docScrollPos.Y + delta.Height); this.documentWorkspace.DocumentScrollPositionF = newDocScrollPos; } return(true); }
public bool PerformAction() { bool success = true; if (this.documentWorkspace.Selection.IsEmpty || !(this.documentWorkspace.ActiveLayer is BitmapLayer)) { return(false); } try { using (new WaitCursorChanger(this.documentWorkspace)) { Utility.GCFullCollect(); PdnRegion selectionRegion = this.documentWorkspace.Selection.CreateRegion(); PdnGraphicsPath selectionOutline = this.documentWorkspace.Selection.CreatePath(); BitmapLayer activeLayer = (BitmapLayer)this.documentWorkspace.ActiveLayer; RenderArgs renderArgs = new RenderArgs(activeLayer.Surface); MaskedSurface maskedSurface = new MaskedSurface(renderArgs.Surface, selectionOutline); SurfaceForClipboard surfaceForClipboard = new SurfaceForClipboard(maskedSurface); Rectangle selectionBounds = Utility.GetRegionBounds(selectionRegion); if (selectionBounds.Width > 0 && selectionBounds.Height > 0) { Surface copySurface = new Surface(selectionBounds.Width, selectionBounds.Height); Bitmap copyBitmap = copySurface.CreateAliasedBitmap(); Bitmap copyOpaqueBitmap = new Bitmap(copySurface.Width, copySurface.Height, PixelFormat.Format24bppRgb); using (Graphics copyBitmapGraphics = Graphics.FromImage(copyBitmap)) { copyBitmapGraphics.Clear(Color.White); } maskedSurface.Draw(copySurface, -selectionBounds.X, -selectionBounds.Y); using (Graphics copyOpaqueBitmapGraphics = Graphics.FromImage(copyOpaqueBitmap)) { copyOpaqueBitmapGraphics.Clear(Color.White); copyOpaqueBitmapGraphics.DrawImage(copyBitmap, 0, 0); } DataObject dataObject = new DataObject(); dataObject.SetData(DataFormats.Bitmap, copyOpaqueBitmap); dataObject.SetData(surfaceForClipboard); int retryCount = 2; while (retryCount >= 0) { try { using (new WaitCursorChanger(this.documentWorkspace)) { Clipboard.SetDataObject(dataObject, true); } break; } catch { if (retryCount == 0) { success = false; Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("CopyAction.Error.TransferToClipboard")); } else { Thread.Sleep(200); } } finally { --retryCount; } } copySurface.Dispose(); copyBitmap.Dispose(); copyOpaqueBitmap.Dispose(); } selectionRegion.Dispose(); selectionOutline.Dispose(); renderArgs.Dispose(); maskedSurface.Dispose(); } } catch (OutOfMemoryException) { success = false; Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("CopyAction.Error.OutOfMemory")); } catch (Exception) { success = false; Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("CopyAction.Error.Generic")); } Utility.GCFullCollect(); return(success); }
/// <summary> /// Pastes from the clipboard into the document. /// </summary> /// <returns>true if the paste operation completed, false if there was an error or if it was cancelled for some reason</returns> public bool PerformAction() { SurfaceForClipboard surfaceForClipboard = null; IDataObject clipData = null; try { Utility.GCFullCollect(); clipData = Clipboard.GetDataObject(); } catch (ExternalException) { Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.TransferFromClipboard")); return false; } catch (OutOfMemoryException) { Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.OutOfMemory")); return false; } // First "ask" the current tool if it wants to handle it bool handledByTool = false; if (this.documentWorkspace.Tool != null) { this.documentWorkspace.Tool.PerformPaste(clipData, out handledByTool); } if (handledByTool) { return true; } if (clipData.GetDataPresent(typeof(SurfaceForClipboard))) { try { Utility.GCFullCollect(); surfaceForClipboard = clipData.GetData(typeof(SurfaceForClipboard)) as SurfaceForClipboard; } catch (OutOfMemoryException) { Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.OutOfMemory")); return false; } } if (surfaceForClipboard != null && surfaceForClipboard.MaskedSurface.IsDisposed) { // Have been getting crash reports where sfc contains a disposed MaskedSurface ... surfaceForClipboard = null; } if (surfaceForClipboard == null && clipData.GetDataPresent(DataFormats.Bitmap)) { Image image; try { Utility.GCFullCollect(); image = (Image)clipData.GetData(DataFormats.Bitmap); } catch (OutOfMemoryException) { Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.OutOfMemory")); return false; } // Sometimes we get weird errors if we're in, say, 16-bit mode but the image was copied // to the clipboard in 32-bit mode if (image == null) { Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.NotRecognized")); return false; } MaskedSurface maskedSurface = null; try { Utility.GCFullCollect(); Bitmap bitmap; Surface surface = null; if (image is Bitmap) { bitmap = (Bitmap)image; image = null; } else { bitmap = new Bitmap(image); image.Dispose(); } surface = Surface.CopyFromBitmap(bitmap); bitmap.Dispose(); bitmap = null; maskedSurface = new MaskedSurface(surface, new PdnRegion(surface.Bounds)); surface.Dispose(); surface = null; } catch (Exception) { Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.OutOfMemory")); return false; } surfaceForClipboard = new SurfaceForClipboard(maskedSurface); } if (surfaceForClipboard == null || surfaceForClipboard.MaskedSurface == null) { // silently fail: like what if a program overwrote the clipboard in between the time // we enabled the "Paste" menu item and the user actually clicked paste? // it could happen! Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.NoImage")); return false; } // If the image is larger than the document, ask them if they'd like to make the image larger first Rectangle bounds = surfaceForClipboard.Bounds; if (bounds.Width > this.documentWorkspace.Document.Width || bounds.Height > this.documentWorkspace.Document.Height) { DialogResult dr = MessageBox.Show( this.documentWorkspace, PdnResources.GetString("PasteAction.Question.ExpandCanvas"), PdnInfo.GetAppName(), MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); int layerIndex = this.documentWorkspace.ActiveLayerIndex; switch (dr) { case DialogResult.Yes: Size newSize = new Size(Math.Max(bounds.Width, this.documentWorkspace.Document.Width), Math.Max(bounds.Height, this.documentWorkspace.Document.Height)); Document newDoc = CanvasSizeAction.ResizeDocument( this.documentWorkspace.Document, newSize, AnchorEdge.TopLeft, this.documentWorkspace.AppWorkspace.AppEnvironment.SecondaryColor); if (newDoc == null) { return false; // user clicked cancel! } else { HistoryMemento rdha = new ReplaceDocumentHistoryMemento( CanvasSizeAction.StaticName, CanvasSizeAction.StaticImage, this.documentWorkspace); this.documentWorkspace.Document = newDoc; this.documentWorkspace.History.PushNewMemento(rdha); this.documentWorkspace.ActiveLayer = (Layer)this.documentWorkspace.Document.Layers[layerIndex]; } break; case DialogResult.No: break; case DialogResult.Cancel: return false; default: throw new InvalidEnumArgumentException("Internal error: DialogResult was neither Yes, No, nor Cancel"); } } // Decide where to paste to: If the paste is within bounds of the document, do as normal // Otherwise, center it. Rectangle docBounds = this.documentWorkspace.Document.Bounds; Rectangle intersect1 = Rectangle.Intersect(docBounds, bounds); bool doMove = intersect1 != bounds; //intersect1.IsEmpty; Point pasteOffset; if (doMove) { pasteOffset = new Point(-bounds.X + (docBounds.Width / 2) - (bounds.Width / 2), -bounds.Y + (docBounds.Height / 2) - (bounds.Height / 2)); } else { pasteOffset = new Point(0, 0); } // Paste to the place it was originally copied from (for PDN-to-PDN transfers) // and then if its not pasted within the viewable rectangle we pan to that location RectangleF visibleDocRectF = this.documentWorkspace.VisibleDocumentRectangleF; Rectangle visibleDocRect = Utility.RoundRectangle(visibleDocRectF); Rectangle bounds2 = new Rectangle(new Point(bounds.X + pasteOffset.X, bounds.Y + pasteOffset.Y), bounds.Size); Rectangle intersect2 = Rectangle.Intersect(bounds2, visibleDocRect); bool doPan = intersect2.IsEmpty; this.documentWorkspace.SetTool(null); this.documentWorkspace.SetToolFromType(typeof(MoveTool)); ((MoveTool)this.documentWorkspace.Tool).PasteMouseDown(surfaceForClipboard, pasteOffset); if (doPan) { Point centerPtView = new Point(visibleDocRect.Left + (visibleDocRect.Width / 2), visibleDocRect.Top + (visibleDocRect.Height / 2)); Point centerPtPasted = new Point(bounds2.Left + (bounds2.Width / 2), bounds2.Top + (bounds2.Height / 2)); Size delta = new Size(centerPtPasted.X - centerPtView.X, centerPtPasted.Y - centerPtView.Y); PointF docScrollPos = this.documentWorkspace.DocumentScrollPositionF; PointF newDocScrollPos = new PointF(docScrollPos.X + delta.Width, docScrollPos.Y + delta.Height); this.documentWorkspace.DocumentScrollPositionF = newDocScrollPos; } return true; }
public bool PerformAction() { bool flag = true; if (!this.QueryCanPerformAction()) { return(false); } try { using (new WaitCursorChanger(this.documentWorkspace)) { IRenderer <ColorBgra> source = this.GetSource(); RectInt32 num = source.Bounds <ColorBgra>(); GeometryList cachedClippingMask = this.documentWorkspace.Selection.GetCachedClippingMask(); RectInt32 a = cachedClippingMask.Bounds.Int32Bound; IRenderer <ColorAlpha8> cachedClippingMaskRenderer = this.documentWorkspace.Selection.GetCachedClippingMaskRenderer(this.documentWorkspace.ToolSettings.Selection.RenderingQuality.Value); RectInt32 sourceRect = RectInt32.Intersect(a, source.Bounds <ColorBgra>()); IRenderer <ColorBgra> renderer3 = new ClippedRenderer <ColorBgra>(source, sourceRect); IRenderer <ColorAlpha8> alpha = new ClippedRenderer <ColorAlpha8>(cachedClippingMaskRenderer, sourceRect); IRenderer <ColorBgra> sourceRHS = new MultiplyAlphaChannelRendererBgra32(renderer3, alpha); IRenderer <ColorBgra> sourceLHS = new SolidColorRendererBgra(sourceRHS.Width, sourceRHS.Height, ColorBgra.White); IRenderer <ColorBgra> renderer = new BlendRendererBgra(sourceLHS, CompositionOps.Normal.Static, sourceRHS); if ((a.Width > 0) && (a.Height > 0)) { int num5 = 10; while (num5 >= 0) { try { try { using (Clipboard.Transaction transaction = Clipboard.Open(this.documentWorkspace)) { transaction.Empty(); using (MaskedSurface surface = MaskedSurface.CopyFrom(source, cachedClippingMask)) { transaction.AddManagedData(surface); using (Surface surface2 = surface.Surface.CreateWindow(new Rectangle(0, 0, a.Width, a.Height))) { sourceRHS.Parallelize <ColorBgra>(TilingStrategy.Tiles, 7, WorkItemQueuePriority.Normal).Render <ColorBgra>(surface2); using (Bitmap copyBitmap = surface2.CreateAliasedBitmap(true)) { transaction.AddRawNativeData("PNG", delegate(Stream dstStream) { copyBitmap.Save(dstStream, ImageFormat.Png); }); } renderer.Parallelize <ColorBgra>(TilingStrategy.Tiles, 7, WorkItemQueuePriority.Normal).Render <ColorBgra>(surface2); using (Bitmap bitmap = surface2.CreateAliasedBitmap(false)) { transaction.AddDibV5(bitmap); } } goto Label_0292; } } } catch (Exception exception) { if (num5 == 0) { flag = false; ExceptionDialog.ShowErrorDialog(this.documentWorkspace, PdnResources.GetString("CopyAction.Error.TransferToClipboard"), exception.ToString()); } else { CleanupManager.RequestCleanup(); CleanupManager.WaitForPendingCleanup(50); Thread.Sleep(50); } } continue; } finally { num5--; } } } } } catch (OutOfMemoryException exception2) { flag = false; ExceptionDialog.ShowErrorDialog(this.documentWorkspace, PdnResources.GetString("CopyAction.Error.OutOfMemory"), exception2.ToString()); } catch (Exception exception3) { flag = false; ExceptionDialog.ShowErrorDialog(this.documentWorkspace, PdnResources.GetString("CopyAction.Error.Generic"), exception3.ToString()); } Label_0292: CleanupManager.RequestCleanup(); return(flag); }