Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
 public MoveToolContext(MoveToolContext cloneMe)
     : base(cloneMe)
 {
     this.poLiftedPixelsGuid = cloneMe.poLiftedPixelsGuid;
     this.poLiftedPixels     = cloneMe.poLiftedPixels; // do not clone
     this.liftedPixels       = cloneMe.liftedPixels;   // do not clone
 }
Example #4
0
 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;
 }
Example #6
0
        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));
        }
Example #7
0
        public bool PerformAction()
        {
            bool flag;

            try
            {
                flag = this.PerformActionImpl();
            }
            finally
            {
                this.clipData      = null;
                this.maskedSurface = null;
            }
            return(flag);
        }
Example #8
0
 public PasteAction(DocumentWorkspace documentWorkspace, IPdnDataObject clipData, MaskedSurface maskedSurface)
 {
     this.documentWorkspace = documentWorkspace;
     this.clipData          = clipData;
     this.maskedSurface     = maskedSurface;
 }
Example #9
0
        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;
        }
Example #11
0
        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();
        }
Example #12
0
        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);
        }
Example #13
0
        /// <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);
        }
Example #14
0
        /// <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);
        }
Example #15
0
 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 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);
        }
Example #17
0
        /// <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);
        }