Example #1
0
        /// <summary>
        /// Constructs an outline of the given region with the given bounds
        /// and scaling factor.
        /// </summary>
        /// <param name="region">
        /// The selection to approximate.
        /// </param>
        /// <param name="bounds">
        /// The boundaries of the image.
        /// </param>
        /// <param name="scalingMultiplier">
        /// The amount to scale the size of the outline by.
        /// </param>
        public static PdnRegion ConstructOutline(
            this PdnRegion region,
            RectangleF bounds,
            float scalingMultiplier)
        {
            GraphicsPath path      = new GraphicsPath();
            PdnRegion    newRegion = region.Clone();

            //The size to scale the region by.
            Matrix scalematrix = new Matrix(
                bounds,
                new PointF[] {
                new PointF(bounds.Left, bounds.Top),
                new PointF(bounds.Right * scalingMultiplier, bounds.Top),
                new PointF(bounds.Left, bounds.Bottom * scalingMultiplier)
            });

            newRegion.Transform(scalematrix);

            //Makes the new region slightly larger by inflating rectangles.
            foreach (RectangleF rect in newRegion.GetRegionScans())
            {
                path.AddRectangle(RectangleF.Inflate(rect, 1, 1));
            }

            //Subtracts the old region, leaving an outline from the expansion.
            PdnRegion result = new PdnRegion(path);

            result.Exclude(newRegion);

            return(result);
        }
Example #2
0
        public static PdnRegion GetOutline(this PdnRegion region, RectangleF bounds, float scalefactor)
        {
            GraphicsPath path = new GraphicsPath();

            PdnRegion region2 = region.Clone();

            Matrix scalematrix = new Matrix(
                bounds,
                new PointF[] {
                new PointF(bounds.Left, bounds.Top),
                new PointF(bounds.Right * scalefactor, bounds.Top),
                new PointF(bounds.Left, bounds.Bottom * scalefactor)
            });

            region2.Transform(scalematrix);

            foreach (RectangleF rect in region2.GetRegionScans())
            {
                path.AddRectangle(RectangleF.Inflate(rect, 1, 1));
            }

            PdnRegion retval = new PdnRegion(path);

            retval.Exclude(region2);

            return(retval);
        }
Example #3
0
 private void InvalidateSelection()
 {
     if (selection != null)
     {
         unSelection = new PdnRegion(new Rectangle(0, 0, surface.Width, surface.Height));
         unSelection.Exclude(selection);
         selectionOutline = selection.GetOutline(surface.Bounds, scale);
     }
     canvas.Invalidate();
 }
Example #4
0
        public override HistoryMemento OnExecute(IHistoryWorkspace historyWorkspace)
        {
            if (historyWorkspace.Selection.IsEmpty)
            {
                return(null);
            }
            else
            {
                PdnRegion selectionRegion = historyWorkspace.Selection.CreateRegion();

                if (selectionRegion.GetArea() == 0)
                {
                    selectionRegion.Dispose();
                    return(null);
                }

                SelectionHistoryMemento       sha  = new SelectionHistoryMemento(StaticName, null, historyWorkspace);
                ReplaceDocumentHistoryMemento rdha = new ReplaceDocumentHistoryMemento(StaticName, null, historyWorkspace);
                Rectangle   boundingBox;
                Rectangle[] inverseRegionRects = null;

                boundingBox = Utility.GetRegionBounds(selectionRegion);

                using (PdnRegion inverseRegion = new PdnRegion(boundingBox))
                {
                    inverseRegion.Exclude(selectionRegion);

                    inverseRegionRects = Utility.TranslateRectangles(
                        inverseRegion.GetRegionScansReadOnlyInt(),
                        -boundingBox.X,
                        -boundingBox.Y);
                }

                selectionRegion.Dispose();
                selectionRegion = null;

                Document oldDocument = historyWorkspace.Document; // TODO: serialize this to disk so we don't *have* to store the full thing
                Document newDocument = new Document(boundingBox.Width, boundingBox.Height);

                // copy the document's meta data over
                newDocument.ReplaceMetaDataFrom(oldDocument);

                foreach (Layer layer in oldDocument.Layers)
                {
                    if (layer is BitmapLayer)
                    {
                        BitmapLayer oldLayer       = (BitmapLayer)layer;
                        Surface     croppedSurface = oldLayer.Surface.CreateWindow(boundingBox);
                        BitmapLayer newLayer       = new BitmapLayer(croppedSurface);

                        ColorBgra clearWhite = ColorBgra.White.NewAlpha(0);

                        foreach (Rectangle rect in inverseRegionRects)
                        {
                            newLayer.Surface.Clear(rect, clearWhite);
                        }

                        newLayer.LoadProperties(oldLayer.SaveProperties());
                        newDocument.Layers.Add(newLayer);
                    }
                    else
                    {
                        throw new InvalidOperationException("Crop does not support Layers that are not BitmapLayers");
                    }
                }

                CompoundHistoryMemento cha = new CompoundHistoryMemento(
                    StaticName,
                    PdnResources.GetImageResource("Icons.MenuImageCropIcon.png"),
                    new HistoryMemento[] { sha, rdha });

                EnterCriticalRegion();
                historyWorkspace.Document = newDocument;

                return(cha);
            }
        }
Example #5
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 #6
0
        public void RunEffect(Type effectType)
        {
            bool oldDirtyValue   = AppWorkspace.ActiveDocumentWorkspace.Document.Dirty;
            bool resetDirtyValue = false;

            AppWorkspace.Update(); // make sure the window is done 'closing'
            AppWorkspace.Widgets.StatusBarProgress.ResetProgressStatusBar();
            DocumentWorkspace activeDW = AppWorkspace.ActiveDocumentWorkspace;

            PdnRegion selectedRegion;

            if (activeDW.Selection.IsEmpty)
            {
                selectedRegion = new PdnRegion(activeDW.Document.Bounds);
            }
            else
            {
                selectedRegion = activeDW.Selection.CreateRegion();
            }

            BitmapLayer layer = (BitmapLayer)activeDW.ActiveLayer;

            using (new PushNullToolMode(activeDW))
            {
                try
                {
                    Effect effect = (Effect)Activator.CreateInstance(effectType);

                    EffectEnvironmentParameters eep = new EffectEnvironmentParameters(
                        AppWorkspace.AppEnvironment.PrimaryColor,
                        AppWorkspace.AppEnvironment.SecondaryColor,
                        AppWorkspace.AppEnvironment.PenInfo.Width,
                        selectedRegion);

                    string            name         = effect.Name;
                    EffectConfigToken newLastToken = null;
                    effect.EnvironmentParameters = eep;

                    if (!(effect.IsConfigurable))
                    {
                        Surface copy = activeDW.BorrowScratchSurface(this.GetType() + ".RunEffect() using scratch surface for non-configurable rendering");

                        try
                        {
                            using (new WaitCursorChanger(AppWorkspace))
                            {
                                copy.CopySurface(layer.Surface);
                            }

                            DoEffect(effect, null, selectedRegion, selectedRegion, copy);
                        }

                        finally
                        {
                            activeDW.ReturnScratchSurface(copy);
                        }
                    }
                    else
                    {
                        PdnRegion previewRegion = (PdnRegion)selectedRegion.Clone();
                        previewRegion.Intersect(RectangleF.Inflate(activeDW.VisibleDocumentRectangleF, 1, 1));

                        Surface originalSurface = activeDW.BorrowScratchSurface(this.GetType() + ".RunEffect() using scratch surface for rendering during configuration");

                        try
                        {
                            using (new WaitCursorChanger(AppWorkspace))
                            {
                                originalSurface.CopySurface(layer.Surface);
                            }

                            //
                            AppWorkspace.SuspendThumbnailUpdates();
                            //

                            using (EffectConfigDialog configDialog = effect.CreateConfigDialog())
                            {
                                configDialog.Opacity             = 0.9;
                                configDialog.Effect              = effect;
                                configDialog.EffectSourceSurface = originalSurface;
                                configDialog.Selection           = selectedRegion;

                                EventHandler eh = new EventHandler(EffectConfigTokenChangedHandler);
                                configDialog.EffectTokenChanged += eh;

                                if (this.effectTokens.ContainsKey(effectType))
                                {
                                    EffectConfigToken oldToken = (EffectConfigToken)effectTokens[effectType].Clone();
                                    configDialog.EffectToken = oldToken;
                                }

                                BackgroundEffectRenderer ber = new BackgroundEffectRenderer(
                                    effect,
                                    configDialog.EffectToken,
                                    new RenderArgs(layer.Surface),
                                    new RenderArgs(originalSurface),
                                    previewRegion,
                                    tilesPerCpu * renderingThreadCount,
                                    renderingThreadCount);

                                ber.RenderedTile      += new RenderedTileEventHandler(RenderedTileHandler);
                                ber.StartingRendering += new EventHandler(StartingRenderingHandler);
                                ber.FinishedRendering += new EventHandler(FinishedRenderingHandler);
                                configDialog.Tag       = ber;

                                invalidateTimer.Enabled = true;
                                DialogResult dr = Utility.ShowDialog(configDialog, AppWorkspace);
                                invalidateTimer.Enabled = false;

                                this.InvalidateTimer_Tick(invalidateTimer, EventArgs.Empty);

                                if (dr == DialogResult.OK)
                                {
                                    this.effectTokens[effectType] = (EffectConfigToken)configDialog.EffectToken.Clone();
                                }

                                using (new WaitCursorChanger(AppWorkspace))
                                {
                                    ber.Abort();
                                    ber.Join();
                                    ber.Dispose();
                                    ber = null;

                                    if (dr != DialogResult.OK)
                                    {
                                        ((BitmapLayer)activeDW.ActiveLayer).Surface.CopySurface(originalSurface);
                                        activeDW.ActiveLayer.Invalidate();
                                    }

                                    configDialog.EffectTokenChanged -= eh;
                                    configDialog.Hide();
                                    AppWorkspace.Update();
                                    previewRegion.Dispose();
                                }

                                //
                                AppWorkspace.ResumeThumbnailUpdates();
                                //

                                if (dr == DialogResult.OK)
                                {
                                    PdnRegion remainingToRender = selectedRegion.Clone();
                                    PdnRegion alreadyRendered   = PdnRegion.CreateEmpty();

                                    for (int i = 0; i < this.progressRegions.Length; ++i)
                                    {
                                        if (this.progressRegions[i] == null)
                                        {
                                            break;
                                        }
                                        else
                                        {
                                            remainingToRender.Exclude(this.progressRegions[i]);
                                            alreadyRendered.Union(this.progressRegions[i]);
                                        }
                                    }

                                    activeDW.ActiveLayer.Invalidate(alreadyRendered);
                                    newLastToken = (EffectConfigToken)configDialog.EffectToken.Clone();
                                    AppWorkspace.Widgets.StatusBarProgress.ResetProgressStatusBar();
                                    DoEffect(effect, newLastToken, selectedRegion, remainingToRender, originalSurface);
                                }
                                else // if (dr == DialogResult.Cancel)
                                {
                                    using (new WaitCursorChanger(AppWorkspace))
                                    {
                                        activeDW.ActiveLayer.Invalidate();
                                        Utility.GCFullCollect();
                                    }

                                    resetDirtyValue = true;
                                    return;
                                }
                            }
                        }

                        finally
                        {
                            activeDW.ReturnScratchSurface(originalSurface);
                        }
                    }

                    // if it was from the Effects menu, save it as the "Repeat ...." item
                    if (effect.Category == EffectCategory.Effect)
                    {
                        this.lastEffect = effect;

                        if (newLastToken == null)
                        {
                            this.lastEffectToken = null;
                        }
                        else
                        {
                            this.lastEffectToken = (EffectConfigToken)newLastToken.Clone();
                        }

                        PopulateMenu(true);
                    }
                }

                finally
                {
                    selectedRegion.Dispose();
                    AppWorkspace.Widgets.StatusBarProgress.ResetProgressStatusBar();
                    AppWorkspace.Widgets.StatusBarProgress.EraseProgressStatusBar();
                    AppWorkspace.ActiveDocumentWorkspace.EnableOutlineAnimation = true;

                    for (int i = 0; i < this.progressRegions.Length; ++i)
                    {
                        if (this.progressRegions[i] != null)
                        {
                            this.progressRegions[i].Dispose();
                            this.progressRegions[i] = null;
                        }
                    }

                    if (resetDirtyValue)
                    {
                        AppWorkspace.ActiveDocumentWorkspace.Document.Dirty = oldDirtyValue;
                    }
                }
            }
        }
        public override HistoryMemento OnExecute(IHistoryWorkspace historyWorkspace)
        {
            if (historyWorkspace.Selection.IsEmpty)
            {
                return null;
            }
            else
            {
                PdnRegion selectionRegion = historyWorkspace.Selection.CreateRegion();

                if (selectionRegion.GetArea() == 0)
                {
                    selectionRegion.Dispose();
                    return null;
                }

                SelectionHistoryMemento sha = new SelectionHistoryMemento(StaticName, null, historyWorkspace);
                ReplaceDocumentHistoryMemento rdha = new ReplaceDocumentHistoryMemento(StaticName, null, historyWorkspace);
                Rectangle boundingBox;
                Rectangle[] inverseRegionRects = null;

                boundingBox = Utility.GetRegionBounds(selectionRegion);

                using (PdnRegion inverseRegion = new PdnRegion(boundingBox))
                {
                    inverseRegion.Exclude(selectionRegion);

                    inverseRegionRects = Utility.TranslateRectangles(
                        inverseRegion.GetRegionScansReadOnlyInt(),
                        -boundingBox.X,
                        -boundingBox.Y);
                }

                selectionRegion.Dispose();
                selectionRegion = null;

                Document oldDocument = historyWorkspace.Document; // TODO: serialize this to disk so we don't *have* to store the full thing
                Document newDocument = new Document(boundingBox.Width, boundingBox.Height);

                // copy the document's meta data over
                newDocument.ReplaceMetaDataFrom(oldDocument);

                foreach (Layer layer in oldDocument.Layers)
                {
                    if (layer is BitmapLayer)
                    {
                        BitmapLayer oldLayer = (BitmapLayer)layer;
                        Surface croppedSurface = oldLayer.Surface.CreateWindow(boundingBox);
                        BitmapLayer newLayer = new BitmapLayer(croppedSurface);

                        ColorBgra clearWhite = ColorBgra.White.NewAlpha(0);

                        foreach (Rectangle rect in inverseRegionRects)
                        {
                            newLayer.Surface.Clear(rect, clearWhite);
                        }

                        newLayer.LoadProperties(oldLayer.SaveProperties());
                        newDocument.Layers.Add(newLayer);
                    }
                    else
                    {
                        throw new InvalidOperationException("Crop does not support Layers that are not BitmapLayers");
                    }
                }

                CompoundHistoryMemento cha = new CompoundHistoryMemento(
                    StaticName,
                    PdnResources.GetImageResource("Icons.MenuImageCropIcon.png"),
                    new HistoryMemento[] { sha, rdha });

                EnterCriticalRegion();
                historyWorkspace.Document = newDocument;

                return cha;
            }
        }
        private void DrawGradient(Graphics g)
        {
            Rectangle rectangle;
            double    num;

            g.PixelOffsetMode = PixelOffsetMode.Half;
            System.Windows.Forms.Orientation orientation = this.orientation;
            if (orientation != System.Windows.Forms.Orientation.Horizontal)
            {
                if (orientation != System.Windows.Forms.Orientation.Vertical)
                {
                    throw ExceptionUtil.InvalidEnumArgumentException <System.Windows.Forms.Orientation>(this.orientation, "this.Orientation");
                }
            }
            else
            {
                num = 180.0;
                goto Label_0040;
            }
            num = 90.0;
Label_0040:
            rectangle   = base.ClientRectangle;
            orientation = this.orientation;
            if (orientation != System.Windows.Forms.Orientation.Horizontal)
            {
                if (orientation != System.Windows.Forms.Orientation.Vertical)
                {
                    throw ExceptionUtil.InvalidEnumArgumentException <System.Windows.Forms.Orientation>(this.orientation, "this.Orientation");
                }
            }
            else
            {
                rectangle.Inflate(-3, -4);
                goto Label_0082;
            }
            rectangle.Inflate(-4, -3);
Label_0082:
            if (((this.customGradient != null) && (rectangle.Width > 1)) && (rectangle.Height > 1))
            {
                Surface surface = new Surface(rectangle.Size.ToSizeInt32());
                using (RenderArgs args = new RenderArgs(surface))
                {
                    ColorRectangle.Draw(args.Graphics, args.Bounds, Color.Transparent, true, false);
                    if (this.Orientation == System.Windows.Forms.Orientation.Horizontal)
                    {
                        for (int j = 0; j < surface.Width; j++)
                        {
                            double num16;
                            double num17;
                            double num18;
                            double d             = ((double)(j * (this.customGradient.Length - 1))) / ((double)(surface.Width - 1));
                            int    index         = (int)Math.Floor(d);
                            double num5          = 1.0 - (d - index);
                            int    num6          = (int)Math.Min((double)(this.customGradient.Length - 1), Math.Ceiling(d));
                            Color  c             = this.customGradient[index];
                            Color  disabledColor = this.customGradient[num6];
                            if (!base.Enabled)
                            {
                                c             = DisabledRendering.GetDisabledColor(c);
                                disabledColor = DisabledRendering.GetDisabledColor(disabledColor);
                            }
                            double num7  = ((double)c.A) / 255.0;
                            double num8  = ((double)c.R) / 255.0;
                            double num9  = ((double)c.G) / 255.0;
                            double num10 = ((double)c.B) / 255.0;
                            double num11 = ((double)disabledColor.A) / 255.0;
                            double num12 = ((double)disabledColor.R) / 255.0;
                            double num13 = ((double)disabledColor.G) / 255.0;
                            double num14 = ((double)disabledColor.B) / 255.0;
                            double num15 = (num5 * num7) + ((1.0 - num5) * num11);
                            if (num15 == 0.0)
                            {
                                num16 = 0.0;
                                num17 = 0.0;
                                num18 = 0.0;
                            }
                            else
                            {
                                num16 = (((num5 * num7) * num8) + (((1.0 - num5) * num11) * num12)) / num15;
                                num17 = (((num5 * num7) * num9) + (((1.0 - num5) * num11) * num13)) / num15;
                                num18 = (((num5 * num7) * num10) + (((1.0 - num5) * num11) * num14)) / num15;
                            }
                            int num19 = ((int)Math.Round((double)(num15 * 255.0), MidpointRounding.AwayFromZero)).Clamp(0, 0xff);
                            int num20 = ((int)Math.Round((double)(num16 * 255.0), MidpointRounding.AwayFromZero)).Clamp(0, 0xff);
                            int num21 = ((int)Math.Round((double)(num17 * 255.0), MidpointRounding.AwayFromZero)).Clamp(0, 0xff);
                            int num22 = ((int)Math.Round((double)(num18 * 255.0), MidpointRounding.AwayFromZero)).Clamp(0, 0xff);
                            for (int k = 0; k < surface.Height; k++)
                            {
                                ColorBgra bgra  = surface[j, k];
                                int       num24 = ((num20 * num19) + (bgra.R * (0xff - num19))) / 0xff;
                                int       num25 = ((num21 * num19) + (bgra.G * (0xff - num19))) / 0xff;
                                int       num26 = ((num22 * num19) + (bgra.B * (0xff - num19))) / 0xff;
                                surface[j, k] = ColorBgra.FromBgra((byte)num26, (byte)num25, (byte)num24, 0xff);
                            }
                        }
                        g.DrawImage(args.Bitmap, rectangle, args.Bounds, GraphicsUnit.Pixel);
                    }
                    else if (this.Orientation != System.Windows.Forms.Orientation.Vertical)
                    {
                        throw ExceptionUtil.InvalidEnumArgumentException <System.Windows.Forms.Orientation>(this.orientation, "this.Orientation");
                    }
                }
                surface.Dispose();
            }
            else
            {
                Color color3 = base.Enabled ? this.maxColor : DisabledRendering.GetDisabledColor(this.maxColor);
                Color color4 = base.Enabled ? this.minColor : DisabledRendering.GetDisabledColor(this.minColor);
                using (LinearGradientBrush brush = new LinearGradientBrush(base.ClientRectangle, color3, color4, (float)num, false))
                {
                    g.FillRectangle(brush, rectangle);
                }
            }
            using (PdnRegion region = new PdnRegion())
            {
                region.MakeInfinite();
                region.Exclude(rectangle);
                using (SolidBrush brush2 = new SolidBrush(this.BackColor))
                {
                    g.FillRegion(brush2, region.GetRegionReadOnly());
                }
            }
            for (int i = 0; i < this.vals.Length; i++)
            {
                Brush blue;
                Pen   pen;
                Point point;
                Point point2;
                Point point3;
                Point point4;
                Point point5;
                Point point6;
                int   x = this.ValueToPosition(this.vals[i]);
                if (i == this.highlight)
                {
                    blue = Brushes.Blue;
                    pen  = (Pen)Pens.White.Clone();
                }
                else
                {
                    blue = base.Enabled ? Brushes.Black : Brushes.Gray;
                    pen  = (Pen)Pens.Gray.Clone();
                }
                g.SmoothingMode = SmoothingMode.AntiAlias;
                orientation     = this.orientation;
                if (orientation != System.Windows.Forms.Orientation.Horizontal)
                {
                    if (orientation != System.Windows.Forms.Orientation.Vertical)
                    {
                        throw ExceptionUtil.InvalidEnumArgumentException <System.Windows.Forms.Orientation>(this.orientation, "this.Orientation");
                    }
                }
                else
                {
                    point  = new Point(x - 3, 0);
                    point2 = new Point(x, 6);
                    point3 = new Point(x + 3, 0);
                    point4 = new Point(point.X, (base.Height - 1) - point.Y);
                    point5 = new Point(point2.X, (base.Height - 1) - point2.Y);
                    point6 = new Point(point3.X, (base.Height - 1) - point3.Y);
                    goto Label_0678;
                }
                point  = new Point(0, x - 3);
                point2 = new Point(6, x);
                point3 = new Point(0, x + 3);
                point4 = new Point((base.Width - 1) - point.X, point.Y);
                point5 = new Point((base.Width - 1) - point2.X, point2.Y);
                point6 = new Point((base.Width - 1) - point3.X, point3.Y);
Label_0678:
                if (this.drawNearNub)
                {
                    Point[] points = new Point[] { point, point2, point3, point };
                    g.FillPolygon(blue, points);
                }
                if (this.drawFarNub)
                {
                    Point[] pointArray2 = new Point[] { point4, point5, point6, point4 };
                    g.FillPolygon(blue, pointArray2);
                }
                if (pen != null)
                {
                    if (this.drawNearNub)
                    {
                        Point[] pointArray3 = new Point[] { point, point2, point3, point };
                        g.DrawPolygon(pen, pointArray3);
                    }
                    if (this.drawFarNub)
                    {
                        Point[] pointArray4 = new Point[] { point4, point5, point6, point4 };
                        g.DrawPolygon(pen, pointArray4);
                    }
                    pen.Dispose();
                }
            }
        }
Example #9
0
        public void RunEffect(Type effectType)
        {
            bool oldDirtyValue   = AppWorkspace.ActiveDocumentWorkspace.Document.Dirty;
            bool resetDirtyValue = false;

            AppWorkspace.Update(); // make sure the window is done 'closing'
            AppWorkspace.Widgets.StatusBarProgress.ResetProgressStatusBar();
            DocumentWorkspace activeDW = AppWorkspace.ActiveDocumentWorkspace;

            PdnRegion selectedRegion;

            if (activeDW.Selection.IsEmpty)
            {
                selectedRegion = new PdnRegion(activeDW.Document.Bounds);
            }
            else
            {
                selectedRegion = activeDW.Selection.CreateRegion();
            }

            Exception   exception = null;
            Effect      effect    = null;
            BitmapLayer layer     = (BitmapLayer)activeDW.ActiveLayer;

            using (new PushNullToolMode(activeDW))
            {
                try
                {
                    effect = (Effect)Activator.CreateInstance(effectType);

                    string            name         = effect.Name;
                    EffectConfigToken newLastToken = null;

                    if (!(effect.CheckForEffectFlags(EffectFlags.Configurable)))
                    {
                        Surface copy = activeDW.BorrowScratchSurface(GetType() +
                                                                     ".RunEffect() using scratch surface for non-configurable rendering");

                        try
                        {
                            using (new WaitCursorChanger(AppWorkspace))
                            {
                                copy.CopySurface(layer.Surface);
                            }

                            EffectEnvironmentParameters eep = new EffectEnvironmentParameters(
                                AppWorkspace.AppEnvironment.PrimaryColor,
                                AppWorkspace.AppEnvironment.SecondaryColor,
                                AppWorkspace.AppEnvironment.PenInfo.Width,
                                selectedRegion,
                                copy);

                            effect.EnvironmentParameters = eep;

                            DoEffect(effect, null, selectedRegion, selectedRegion, copy, out exception);
                        }

                        finally
                        {
                            activeDW.ReturnScratchSurface(copy);
                        }
                    }
                    else
                    {
                        PdnRegion previewRegion = (PdnRegion)selectedRegion.Clone();
                        previewRegion.Intersect(RectangleF.Inflate(activeDW.VisibleDocumentRectangleF, 1, 1));

                        Surface originalSurface = activeDW.BorrowScratchSurface(GetType() +
                                                                                ".RunEffect() using scratch surface for rendering during configuration");

                        try
                        {
                            using (new WaitCursorChanger(AppWorkspace))
                            {
                                originalSurface.CopySurface(layer.Surface);
                            }

                            EffectEnvironmentParameters eep = new EffectEnvironmentParameters(
                                AppWorkspace.AppEnvironment.PrimaryColor,
                                AppWorkspace.AppEnvironment.SecondaryColor,
                                AppWorkspace.AppEnvironment.PenInfo.Width,
                                selectedRegion,
                                originalSurface);

                            effect.EnvironmentParameters = eep;

                            //
                            IDisposable resumeTUFn = AppWorkspace.SuspendThumbnailUpdates();
                            //

                            using (EffectConfigDialog configDialog = effect.CreateConfigDialog())
                            {
                                configDialog.Opacity             = 0.9;
                                configDialog.Effect              = effect;
                                configDialog.EffectSourceSurface = originalSurface;
                                configDialog.Selection           = selectedRegion;

                                BackgroundEffectRenderer ber = null;

                                void OnEffectTokenChanged(object sender, EventArgs e)
                                {
                                    EffectConfigDialog ecf = (EffectConfigDialog)sender;

                                    if (ber != null)
                                    {
                                        AppWorkspace.Widgets.StatusBarProgress.ResetProgressStatusBarAsync();

                                        try
                                        {
                                            ber.Start();
                                        }

                                        catch (Exception ex)
                                        {
                                            exception = ex;
                                            ecf.Close();
                                        }
                                    }
                                }

                                configDialog.EffectTokenChanged += OnEffectTokenChanged;

                                if (EffectTokens.ContainsKey(effectType))
                                {
                                    EffectConfigToken oldToken = (EffectConfigToken)EffectTokens[effectType].Clone();
                                    configDialog.EffectToken = oldToken;
                                }

                                int pixelCount  = layer.Surface.Height;
                                int threadCount = effect.CheckForEffectFlags(EffectFlags.SingleThreaded) ? 1 : RenderingThreadCount;
                                int maxTiles    = TilesPerCpu * threadCount;
                                int tileCount   = Math.Min(maxTiles, pixelCount);
                                ber = new BackgroundEffectRenderer(
                                    effect,
                                    configDialog.EffectToken,
                                    new RenderArgs(layer.Surface),
                                    new RenderArgs(originalSurface),
                                    previewRegion,
                                    tileCount,
                                    threadCount);

                                ber.RenderedTile      += new RenderedTileEventHandler(RenderedTileHandler);
                                ber.StartingRendering += new EventHandler(StartingRenderingHandler);
                                ber.FinishedRendering += new EventHandler(FinishedRenderingHandler);

                                InvalidateTimer.Enabled = true;

                                DialogResult dr;

                                try
                                {
                                    dr = Utility.ShowDialog(configDialog, AppWorkspace);
                                }

                                catch (Exception ex)
                                {
                                    dr        = DialogResult.None;
                                    exception = ex;
                                }

                                InvalidateTimer.Enabled = false;

                                InvalidateTimer_Tick(InvalidateTimer, EventArgs.Empty);

                                if (dr == DialogResult.OK)
                                {
                                    EffectTokens[effectType] = (EffectConfigToken)configDialog.EffectToken.Clone();
                                }

                                using (new WaitCursorChanger(AppWorkspace))
                                {
                                    try
                                    {
                                        ber.Abort();
                                        ber.Join();
                                    }

                                    catch (Exception ex)
                                    {
                                        exception = ex;
                                    }

                                    ber.Dispose();
                                    ber = null;

                                    if (dr != DialogResult.OK)
                                    {
                                        ((BitmapLayer)activeDW.ActiveLayer).Surface.CopySurface(originalSurface);
                                        activeDW.ActiveLayer.Invalidate();
                                    }

                                    configDialog.EffectTokenChanged -= OnEffectTokenChanged;
                                    configDialog.Hide();
                                    AppWorkspace.Update();
                                    previewRegion.Dispose();
                                }

                                //
                                resumeTUFn.Dispose();
                                resumeTUFn = null;
                                //

                                if (dr == DialogResult.OK)
                                {
                                    PdnRegion remainingToRender = selectedRegion.Clone();
                                    PdnRegion alreadyRendered   = PdnRegion.CreateEmpty();

                                    for (int i = 0; i < ProgressRegions.Length; ++i)
                                    {
                                        if (ProgressRegions[i] == null)
                                        {
                                            break;
                                        }
                                        else
                                        {
                                            remainingToRender.Exclude(ProgressRegions[i]);
                                            alreadyRendered.Union(ProgressRegions[i]);
                                        }
                                    }

                                    activeDW.ActiveLayer.Invalidate(alreadyRendered);
                                    newLastToken = (EffectConfigToken)configDialog.EffectToken.Clone();
                                    AppWorkspace.Widgets.StatusBarProgress.ResetProgressStatusBar();
                                    DoEffect(effect, newLastToken, selectedRegion, remainingToRender, originalSurface, out exception);
                                }
                                else // if (dr == DialogResult.Cancel)
                                {
                                    using (new WaitCursorChanger(AppWorkspace))
                                    {
                                        activeDW.ActiveLayer.Invalidate();
                                        Utility.GCFullCollect();
                                    }

                                    resetDirtyValue = true;
                                    return;
                                }
                            }
                        }

                        catch (Exception ex)
                        {
                            exception = ex;
                        }

                        finally
                        {
                            activeDW.ReturnScratchSurface(originalSurface);
                        }
                    }

                    // if it was from the Effects menu, save it as the "Repeat ...." item
                    if (effect.Category == EffectCategory.Effect)
                    {
                        LastEffect = effect;

                        LastEffectToken = newLastToken == null ? null :
                                          (EffectConfigToken)newLastToken.Clone();

                        PopulateMenu(true);
                    }
                }

                catch (Exception ex)
                {
                    exception = ex;
                }

                finally
                {
                    selectedRegion.Dispose();
                    AppWorkspace.Widgets.StatusBarProgress.ResetProgressStatusBar();
                    AppWorkspace.Widgets.StatusBarProgress.EraseProgressStatusBar();
                    AppWorkspace.ActiveDocumentWorkspace.EnableOutlineAnimation = true;

                    if (ProgressRegions != null)
                    {
                        for (int i = 0; i < ProgressRegions.Length; ++i)
                        {
                            ProgressRegions[i]?.Dispose();
                            ProgressRegions[i] = null;
                        }
                    }

                    if (resetDirtyValue)
                    {
                        AppWorkspace.ActiveDocumentWorkspace.Document.Dirty = oldDirtyValue;
                    }

                    if (exception != null)
                    {
                        HandleEffectException(AppWorkspace, effect, exception);
                    }
                }
            }
        }