public MaskedSurface(Surface source, PdnGraphicsPath path) { RectangleF boundsF = path.GetBounds(); Rectangle bounds = Utility.RoundRectangle(boundsF); Rectangle boundsClipped = Rectangle.Intersect(bounds, source.Bounds); Rectangle boundsRead; if (bounds != boundsClipped) { PdnRegion region = new PdnRegion(path); region.Intersect(source.Bounds); SetPathField(PdnGraphicsPath.FromRegion(region)); this.region = region; boundsRead = region.GetBoundsInt(); } else { SetPathField(path.Clone()); this.region = new PdnRegion(this.path); boundsRead = boundsClipped; } if (boundsRead.Width > 0 && boundsRead.Height > 0) { this.surface = new Surface(boundsRead.Size); this.surface.CopySurface(source, boundsRead); } else { this.surface = null; } }
public void Set(PdnRegion region, bool newValue) { foreach (Rectangle rect in region.GetRegionScansReadOnlyInt()) { Set(rect, newValue); } }
public PdnGraphicsPath(SerializationInfo info, StreamingContext context) { int ptCount = info.GetInt32("ptCount"); PointF[] pts; byte[] types; if (ptCount == 0) { pts = new PointF[0]; types = new byte[0]; } else { pts = (PointF[])info.GetValue("pts", typeof(PointF[])); types = (byte[])info.GetValue("types", typeof(byte[])); } FillMode fillMode = (FillMode)info.GetValue("fillMode", typeof(FillMode)); Changed(); if (ptCount == 0) { gdiPath = new GraphicsPath(); } else { gdiPath = new GraphicsPath(pts, types, fillMode); } this.tooComplex = false; this.regionCache = null; }
public void Invert(PdnRegion region) { foreach (Rectangle rect in region.GetRegionScansReadOnlyInt()) { Invert(rect); } }
private void Dispose(bool disposing) { if (disposing) { if (this.surface != null) { this.surface.Dispose(); this.surface = null; } if (this.region != null) { this.region.Dispose(); this.region = null; } if (this.path != null) { this.path.Dispose(); this.path = null; } if (this.shadowPath != null) { this.shadowPath.Dispose(); this.shadowPath = null; } } this.disposed = true; }
public void Union(PdnRegion region2) { lock (SyncRoot) { Changed(); gdiRegion.Union(region2.gdiRegion); } }
private void Dispose(bool disposing) { if (disposing) { if (this.SurfaceReadOnly != null) { this.SurfaceReadOnly.Dispose(); this.SurfaceReadOnly = null; } if (this.region != null) { this.region.Dispose(); this.region = null; } if (this.path != null) { this.path.Dispose(); this.path = null; } if (this.shadowPath != null) { this.shadowPath.Dispose(); this.shadowPath = null; } } this.IsDisposed = true; }
public void Intersect(PdnRegion region2) { lock (SyncRoot) { Changed(); gdiRegion.Intersect(region2.gdiRegion); } }
public void Exclude(PdnRegion region2) { lock (SyncRoot) { gdiRegion.Exclude(region2.gdiRegion); } }
public EffectConfigDialog() { InitializeComponent(); InitialInitToken(); effectSelection = new PdnRegion(); effectSelection.MakeInfinite(); }
public static PdnGraphicsPath FromRegion(PdnRegion region) { Rectangle bounds = region.GetBoundsInt(); Rectangle[] scans = region.GetRegionScansReadOnlyInt(); BitVector2D stencil = new BitVector2D(bounds.Width, bounds.Height); for (int i = 0; i < scans.Length; ++i) { Rectangle rect = scans[i]; rect.X -= bounds.X; rect.Y -= bounds.Y; stencil.SetUnchecked(rect, true); } PdnGraphicsPath path = PathFromStencil(stencil, new Rectangle(0, 0, stencil.Width, stencil.Height)); using (Matrix matrix = new Matrix()) { matrix.Reset(); matrix.Translate(bounds.X, bounds.Y); path.Transform(matrix); } return(path); }
public static PdnRegion WrapRegion(Region region) { PdnRegion pdnRegion = new PdnRegion(false); pdnRegion.gdiRegion = region; return(pdnRegion); }
/// <summary> /// Causes a portion of the layer surface to be invalidated. /// </summary> /// <param name="roi">The region of interest to be invalidated.</param> public void Invalidate(PdnRegion roi) { foreach (Rectangle rect in roi.GetRegionScansReadOnlyInt()) { Invalidate(rect); } }
private void Activate() { Debug.Assert(this.active != true, "already active!"); this.active = true; this.handCursor = new Cursor(PdnResources.GetResourceStream("Cursors.PanToolCursor.cur")); this.handCursorMouseDown = new Cursor(PdnResources.GetResourceStream("Cursors.PanToolCursorMouseDown.cur")); this.handCursorInvalid = new Cursor(PdnResources.GetResourceStream("Cursors.PanToolCursorInvalid.cur")); this.panTracking = false; this.panMode = false; this.mouseDown = 0; this.savedTiles = null; this.saveRegion = null; this.scratchSurface = DocumentWorkspace.BorrowScratchSurface(this.GetType().Name + ": Tool.Activate()"); #if DEBUG this.haveClearedScratch = false; #endif Selection.Changing += new EventHandler(SelectionChangingHandler); Selection.Changed += new EventHandler(SelectionChangedHandler); HistoryStack.ExecutingHistoryMemento += new ExecutingHistoryMementoEventHandler(ExecutingHistoryMemento); HistoryStack.ExecutedHistoryMemento += new ExecutedHistoryMementoEventHandler(ExecutedHistoryMemento); HistoryStack.FinishedStepGroup += new EventHandler(FinishedHistoryStepGroup); this.trackingNub = new MoveNubRenderer(this.RendererList); this.trackingNub.Visible = false; this.trackingNub.Size = new SizeF(10, 10); this.trackingNub.Shape = MoveNubShape.Compass; this.RendererList.Add(this.trackingNub, false); OnActivate(); }
public static PdnRegion CreateEmpty() { PdnRegion region = new PdnRegion(); region.MakeEmpty(); return(region); }
public void Xor(PdnRegion region2) { lock (SyncRoot) { Changed(); gdiRegion.Xor(region2.gdiRegion); } }
public void Complement(PdnRegion region2) { lock (SyncRoot) { Changed(); gdiRegion.Complement(region2.gdiRegion); } }
/// <summary> /// Constructs an IrregularSurface by copying the given rectangle-of-interest from an Image. /// </summary> /// <param name="source">The Surface to copy pixels from.</param> /// <param name="roi">Defines the Rectangle from which to copy pixels from the Image.</param> public IrregularSurface(Surface source, Rectangle roi) { this.placedSurfaces = new ArrayList { new PlacedSurface(source, roi) }; this.region = new PdnRegion(roi); }
public void ClearSavedRegion() { if (this.saveRegion != null) { this.saveRegion.Dispose(); this.saveRegion = null; } }
public void Exclude(PdnRegion region2) { throw new StillNotPortedException(); //lock (SyncRoot) //{ // gdiRegion.Exclude(region2.gdiRegion); //} }
public SurfaceForClipboard(MaskedSurface maskedSurface) { using (PdnRegion region = maskedSurface.CreateRegion()) { this.Bounds = region.GetBoundsInt(); } this.MaskedSurface = maskedSurface; }
public void RestoreRegion(PdnRegion region) { if (region != null) { BitmapLayer activeLayer = (BitmapLayer)ActiveLayer; activeLayer.Surface.CopySurface(this.ScratchSurface, region); activeLayer.Invalidate(region); } }
internal PdnRegion GetRegionCache() { if (regionCache == null) { regionCache = new PdnRegion(this.gdiPath); } return(regionCache); }
internal PdnRegion GetRegionCache() { if (regionCache == null) { regionCache = new PdnRegion(this.gdiPath); } return regionCache; }
private PdnRegion GetRegion() { if (this.region == null) { this.region = new PdnRegion(this.shadowPath); } return(this.region); }
public void Xor(PdnRegion region2) { throw new StillNotPortedException(); // lock (SyncRoot) // { // Changed(); // gdiRegion.Xor(region2.gdiRegion); // } }
private PdnRegion(PdnRegion pdnRegion) { lock (pdnRegion.SyncRoot) { this.gdiRegion = pdnRegion.gdiRegion.Clone(); this.changed = pdnRegion.changed; this.cachedArea = pdnRegion.cachedArea; this.cachedRectsF = pdnRegion.cachedRectsF; this.cachedRects = pdnRegion.cachedRects; } }
public void Union(RectangleF[] rectsF) { lock (SyncRoot) { Changed(); using (PdnRegion tempRegion = Utility.RectanglesToRegion(rectsF)) { this.Union(tempRegion); } } }
private void Changed() { if (regionCache != null) { lock (regionCache.SyncRoot) { regionCache.Dispose(); regionCache = null; } } }
private IrregularSurface(IrregularSurface cloneMe) { this.placedSurfaces = new ArrayList(cloneMe.placedSurfaces.Count); foreach (PlacedSurface ps in cloneMe.placedSurfaces) { this.placedSurfaces.Add(ps.Clone()); } this.region = (PdnRegion)cloneMe.Region.Clone(); }
public void UpdateHistogram(Surface surface, PdnRegion roi) { Clear(); foreach (Rectangle rect in roi.GetRegionScansReadOnlyInt()) { AddSurfaceRectangleToHistogram(surface, rect); } OnHistogramUpdated(); }
public PdnGraphicsPath CreatePixelatedPath() { using (PdnGraphicsPath path = CreatePath()) { using (PdnRegion region = new PdnRegion(path)) { PdnGraphicsPath pixellatedPath = PdnGraphicsPath.FromRegion(region); return(pixellatedPath); } } }
/// <summary> /// Constructs an IrregularSurface by copying the given region-of-interest from an Image. /// </summary> /// <param name="source">The Surface to copy pixels from.</param> /// <param name="roi">Defines the Region from which to copy pixels from the Image.</param> public IrregularSurface(Surface source, PdnRegion roi) { PdnRegion roiClipped = (PdnRegion)roi.Clone(); roiClipped.Intersect(source.Bounds); Rectangle[] rects = roiClipped.GetRegionScansReadOnlyInt(); this.placedSurfaces = new ArrayList(rects.Length); foreach (Rectangle rect in rects) { this.placedSurfaces.Add(new PlacedSurface(source, rect)); } this.region = roiClipped; }
public IrregularSurface(Surface source, RectangleF[] roi) { this.placedSurfaces = new ArrayList(roi.Length); foreach (RectangleF rectF in roi) { RectangleF ri = RectangleF.Intersect(source.Bounds, rectF); if (!ri.IsEmpty) { this.placedSurfaces.Add(new PlacedSurface(source, Rectangle.Truncate(ri))); } } this.region = Utility.RectanglesToRegion(roi); this.region.Intersect(source.Bounds); }
public void OnDeserialization(object sender) { region = PdnRegion.CreateEmpty(); Rectangle[] rects = new Rectangle[placedSurfaces.Count]; for (int i = 0; i < placedSurfaces.Count; ++i) { rects[i] = ((PlacedSurface)placedSurfaces[i]).Bounds; } region = Utility.RectanglesToRegion(rects); }
/// <summary> /// Constructs an IrregularSurface by copying the given rectangle-of-interest from an Image. /// </summary> /// <param name="source">The Surface to copy pixels from.</param> /// <param name="roi">Defines the Rectangle from which to copy pixels from the Image.</param> public IrregularSurface(Surface source, Rectangle roi) { this.placedSurfaces = new ArrayList(); this.placedSurfaces.Add(new PlacedSurface(source, roi)); this.region = new PdnRegion(roi); }
/// <summary> /// Invalidates a portion of the document. The given region is then tagged /// for rerendering during the next call to Update. /// </summary> /// <param name="roi">The region of interest to be invalidated.</param> public void Invalidate(PdnRegion roi) { Dirty = true; foreach (Rectangle rect in roi.GetRegionScansReadOnlyInt()) { rect.Intersect(this.Bounds); updateRegion.Add(rect); if (!rect.IsEmpty) { InvalidateEventArgs iea = new InvalidateEventArgs(rect); OnInvalidated(iea); } } }
public void RestoreSavedRegion() { if (this.saveRegion != null) { BitmapLayer activeLayer = (BitmapLayer)ActiveLayer; activeLayer.Surface.CopySurface(this.ScratchSurface, this.saveRegion); activeLayer.Invalidate(this.saveRegion); this.saveRegion.Dispose(); this.saveRegion = null; } }
public void Apply(Surface surface, PdnRegion roi) { Apply(surface, roi.GetRegionScansReadOnlyInt()); }
public unsafe void Draw(Surface dst, Matrix transform, ResamplingAlgorithm sampling) { if (this.disposed) { throw new ObjectDisposedException("MaskedSurface"); } if (this.surface == null || !transform.IsInvertible) { return; } PdnRegion theRegion; Rectangle regionBounds; if (this.path == null) { theRegion = this.region.Clone(); regionBounds = this.region.GetBoundsInt(); theRegion.Transform(transform); } else { using (PdnGraphicsPath mPath = this.shadowPath.Clone()) { regionBounds = Rectangle.Truncate(mPath.GetBounds()); mPath.Transform(transform); theRegion = new PdnRegion(mPath); } } DrawContext dc = new DrawContext(); dc.boundsX = regionBounds.X; dc.boundsY = regionBounds.Y; Matrix inverse = transform.Clone(); inverse.Invert(); dc.inverses = new Matrix[Processor.LogicalCpuCount]; for (int i = 0; i < dc.inverses.Length; ++i) { dc.inverses[i] = inverse.Clone(); } // change in source-[X|Y] w.r.t. destination-[X|Y] PointF[] pts = new PointF[] { new PointF(1, 0), new PointF(0, 1) }; inverse.TransformVectors(pts); inverse.Dispose(); inverse = null; dc.dsxddx = pts[0].X; if (Math.Abs(dc.dsxddx) > fp_MaxValue) { dc.dsxddx = 0.0f; } dc.dsyddx = pts[0].Y; if (Math.Abs(dc.dsyddx) > fp_MaxValue) { dc.dsyddx = 0.0f; } dc.dsxddy = pts[1].X; if (Math.Abs(dc.dsxddy) > fp_MaxValue) { dc.dsxddy = 0.0f; } dc.dsyddy = pts[1].Y; if (Math.Abs(dc.dsyddy) > fp_MaxValue) { dc.dsyddy = 0.0f; } dc.fp_dsxddx = (int)(dc.dsxddx * fp_MultFactor); dc.fp_dsyddx = (int)(dc.dsyddx * fp_MultFactor); dc.fp_dsxddy = (int)(dc.dsxddy * fp_MultFactor); dc.fp_dsyddy = (int)(dc.dsyddy * fp_MultFactor); dc.dst = dst; dc.src = this.surface; Rectangle[] scans = theRegion.GetRegionScansReadOnlyInt(); if (scans.Length == 1) { dc.dstScans = new Rectangle[Processor.LogicalCpuCount]; Utility.SplitRectangle(scans[0], dc.dstScans); } else { dc.dstScans = scans; } WaitCallback wc; switch (sampling) { case ResamplingAlgorithm.NearestNeighbor: wc = new WaitCallback(dc.DrawScansNearestNeighbor); break; case ResamplingAlgorithm.Bilinear: wc = new WaitCallback(dc.DrawScansBilinear); break; default: throw new System.ComponentModel.InvalidEnumArgumentException(); } for (int i = 0; i < Processor.LogicalCpuCount; ++i) { if (i == Processor.LogicalCpuCount - 1) { // Don't queue the last work item into a separate thread wc(BoxedConstants.GetInt32(i)); } else { threadPool.QueueUserWorkItem(wc, BoxedConstants.GetInt32(i)); } } threadPool.Drain(); for (int i = 0; i < Processor.LogicalCpuCount; ++i) { dc.inverses[i].Dispose(); dc.inverses[i] = null; } dc.src = null; theRegion.Dispose(); theRegion = null; }
protected virtual void Dispose(bool disposing) { Debug.Assert(!this.active, "Tool is still active!"); if (disposing) { if (this.saveRegion != null) { this.saveRegion.Dispose(); this.saveRegion = null; } OnDisposed(); } }
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 Windows " + Environment.OSVersion.Version.ToString() + " " + OS.Revision + (OS.Revision.Length > 0 ? " " : string.Empty) + OS.Type + " " + Processor.NativeArchitecture.ToString().ToLower()); Console.WriteLine("Processor: " + Processor.LogicalCpuCount + "x \"" + Processor.CpuName + "\" @ ~" + GetCpuSpeed() + " MHz"); 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(); }
private PdnRegion GetRegion() { if (this.region == null) { this.region = new PdnRegion(this.shadowPath); } return this.region; }
private void Deactivate() { Debug.Assert(this.active != false, "not active!"); this.active = false; Selection.Changing -= new EventHandler(SelectionChangingHandler); Selection.Changed -= new EventHandler(SelectionChangedHandler); HistoryStack.ExecutingHistoryMemento -= new ExecutingHistoryMementoEventHandler(ExecutingHistoryMemento); HistoryStack.ExecutedHistoryMemento -= new ExecutedHistoryMementoEventHandler(ExecutedHistoryMemento); HistoryStack.FinishedStepGroup -= new EventHandler(FinishedHistoryStepGroup); OnDeactivate(); this.RendererList.Remove(this.trackingNub); this.trackingNub.Dispose(); this.trackingNub = null; DocumentWorkspace.ReturnScratchSurface(this.scratchSurface); this.scratchSurface = null; if (this.saveRegion != null) { this.saveRegion.Dispose(); this.saveRegion = null; } this.savedTiles = null; if (this.handCursor != null) { this.handCursor.Dispose(); this.handCursor = null; } if (this.handCursorMouseDown != null) { this.handCursorMouseDown.Dispose(); this.handCursorMouseDown = null; } if (this.handCursorInvalid != null) { this.handCursorInvalid.Dispose(); this.handCursorInvalid = null; } }
/// <summary> /// Constructs a MaskSurface by copying the given region-of-interest from an Image. /// </summary> /// <param name="source">The Surface to copy pixels from.</param> /// <param name="roi">Defines the Region from which to copy pixels from the Image.</param> public MaskedSurface(Surface source, PdnRegion roi) { PdnRegion roiClipped = (PdnRegion)roi.Clone(); roiClipped.Intersect(source.Bounds); Rectangle boundsClipped = roiClipped.GetBoundsInt(); this.surface = new Surface(boundsClipped.Size); this.surface.Clear(ColorBgra.FromUInt32(0x00ffffff)); Rectangle rect = boundsClipped; Point dstOffset = new Point(rect.X - boundsClipped.X, rect.Y - boundsClipped.Y); this.surface.CopySurface(source, dstOffset, rect); this.region = roiClipped; SetPathField(PdnGraphicsPath.FromRegion(this.region)); }
private void DrawGradient(Graphics g) { g.PixelOffsetMode = PixelOffsetMode.Half; Rectangle gradientRect; float gradientAngle; switch (this.orientation) { case Orientation.Horizontal: gradientAngle = 180.0f; break; case Orientation.Vertical: gradientAngle = 90.0f; break; default: throw new InvalidEnumArgumentException(); } // draw gradient gradientRect = ClientRectangle; switch (this.orientation) { case Orientation.Horizontal: gradientRect.Inflate(-triangleHalfLength, -triangleSize + 3); break; case Orientation.Vertical: gradientRect.Inflate(-triangleSize + 3, -triangleHalfLength); break; default: throw new InvalidEnumArgumentException(); } if (this.customGradient != null && gradientRect.Width > 1 && gradientRect.Height > 1) { Surface gradientSurface = new Surface(gradientRect.Size); using (RenderArgs ra = new RenderArgs(gradientSurface)) { Utility.DrawColorRectangle(ra.Graphics, ra.Bounds, Color.Transparent, false); if (Orientation == Orientation.Horizontal) { for (int x = 0; x < gradientSurface.Width; ++x) { // TODO: refactor, double buffer, save this computation in a bitmap somewhere double index = (double)(x * (this.customGradient.Length - 1)) / (double)(gradientSurface.Width - 1); int indexL = (int)Math.Floor(index); double t = 1.0 - (index - indexL); int indexR = (int)Math.Min(this.customGradient.Length - 1, Math.Ceiling(index)); Color colorL = this.customGradient[indexL]; Color colorR = this.customGradient[indexR]; double a1 = colorL.A / 255.0; double r1 = colorL.R / 255.0; double g1 = colorL.G / 255.0; double b1 = colorL.B / 255.0; double a2 = colorR.A / 255.0; double r2 = colorR.R / 255.0; double g2 = colorR.G / 255.0; double b2 = colorR.B / 255.0; double at = (t * a1) + ((1.0 - t) * a2); double rt; double gt; double bt; if (at == 0) { rt = 0; gt = 0; bt = 0; } else { rt = ((t * a1 * r1) + ((1.0 - t) * a2 * r2)) / at; gt = ((t * a1 * g1) + ((1.0 - t) * a2 * g2)) / at; bt = ((t * a1 * b1) + ((1.0 - t) * a2 * b2)) / at; } int ap = Utility.Clamp((int)Math.Round(at * 255.0), 0, 255); int rp = Utility.Clamp((int)Math.Round(rt * 255.0), 0, 255); int gp = Utility.Clamp((int)Math.Round(gt * 255.0), 0, 255); int bp = Utility.Clamp((int)Math.Round(bt * 255.0), 0, 255); for (int y = 0; y < gradientSurface.Height; ++y) { ColorBgra src = gradientSurface[x, y]; // we are assuming that src.A = 255 int rd = ((rp * ap) + (src.R * (255 - ap))) / 255; int gd = ((gp * ap) + (src.G * (255 - ap))) / 255; int bd = ((bp * ap) + (src.B * (255 - ap))) / 255; // TODO: proper alpha blending! gradientSurface[x, y] = ColorBgra.FromBgra((byte)bd, (byte)gd, (byte)rd, 255); } } g.DrawImage(ra.Bitmap, gradientRect, ra.Bounds, GraphicsUnit.Pixel); } else if (Orientation == Orientation.Vertical) { // TODO } else { throw new InvalidEnumArgumentException(); } } gradientSurface.Dispose(); } else { using (LinearGradientBrush lgb = new LinearGradientBrush(this.ClientRectangle, maxColor, minColor, gradientAngle, false)) { g.FillRectangle(lgb, gradientRect); } } // fill background using (PdnRegion nonGradientRegion = new PdnRegion()) { nonGradientRegion.MakeInfinite(); nonGradientRegion.Exclude(gradientRect); using (SolidBrush sb = new SolidBrush(this.BackColor)) { g.FillRegion(sb, nonGradientRegion.GetRegionReadOnly()); } } // draw value triangles for (int i = 0; i < this.vals.Length; i++) { int pos = ValueToPosition(vals[i]); Brush brush; Pen pen; if (i == highlight) { brush = Brushes.Blue; pen = (Pen)Pens.White.Clone(); } else { brush = Brushes.Black; pen = (Pen)Pens.Gray.Clone(); } g.SmoothingMode = SmoothingMode.AntiAlias; Point a1; Point b1; Point c1; Point a2; Point b2; Point c2; switch (this.orientation) { case Orientation.Horizontal: a1 = new Point(pos - triangleHalfLength, 0); b1 = new Point(pos, triangleSize - 1); c1 = new Point(pos + triangleHalfLength, 0); a2 = new Point(a1.X, Height - 1 - a1.Y); b2 = new Point(b1.X, Height - 1 - b1.Y); c2 = new Point(c1.X, Height - 1 - c1.Y); break; case Orientation.Vertical: a1 = new Point(0, pos - triangleHalfLength); b1 = new Point(triangleSize - 1, pos); c1 = new Point(0, pos + triangleHalfLength); a2 = new Point(Width - 1 - a1.X, a1.Y); b2 = new Point(Width - 1 - b1.X, b1.Y); c2 = new Point(Width - 1 - c1.X, c1.Y); break; default: throw new InvalidEnumArgumentException(); } if (this.drawNearNub) { g.FillPolygon(brush, new Point[] { a1, b1, c1, a1 }); } if (this.drawFarNub) { g.FillPolygon(brush, new Point[] { a2, b2, c2, a2 }); } if (pen != null) { if (this.drawNearNub) { g.DrawPolygon(pen, new Point[] { a1, b1, c1, a1 }); } if (this.drawFarNub) { g.DrawPolygon(pen, new Point[] { a2, b2, c2, a2 }); } pen.Dispose(); } } }
public void SaveRegion(PdnRegion saveMeRegion, Rectangle saveMeBounds) { BitmapLayer activeLayer = (BitmapLayer)ActiveLayer; if (savedTiles == null) { savedTiles = new BitVector2D( (activeLayer.Width + saveTileGranularity - 1) / saveTileGranularity, (activeLayer.Height + saveTileGranularity - 1) / saveTileGranularity); savedTiles.Clear(false); } Rectangle regionBounds; if (saveMeRegion == null) { regionBounds = saveMeBounds; } else { regionBounds = saveMeRegion.GetBoundsInt(); } Rectangle bounds = Rectangle.Union(regionBounds, saveMeBounds); bounds.Intersect(activeLayer.Bounds); int leftTile = bounds.Left / saveTileGranularity; int topTile = bounds.Top / saveTileGranularity; int rightTile = (bounds.Right - 1) / saveTileGranularity; int bottomTile = (bounds.Bottom - 1) / saveTileGranularity; for (int tileY = topTile; tileY <= bottomTile; ++tileY) { Rectangle rowAccumBounds = Rectangle.Empty; for (int tileX = leftTile; tileX <= rightTile; ++tileX) { if (!savedTiles.Get(tileX, tileY)) { Rectangle tileBounds = new Rectangle(tileX * saveTileGranularity, tileY * saveTileGranularity, saveTileGranularity, saveTileGranularity); tileBounds.Intersect(activeLayer.Bounds); if (rowAccumBounds == Rectangle.Empty) { rowAccumBounds = tileBounds; } else { rowAccumBounds = Rectangle.Union(rowAccumBounds, tileBounds); } savedTiles.Set(tileX, tileY, true); } else { if (rowAccumBounds != Rectangle.Empty) { using (Surface dst = ScratchSurface.CreateWindow(rowAccumBounds), src = activeLayer.Surface.CreateWindow(rowAccumBounds)) { dst.CopySurface(src); } rowAccumBounds = Rectangle.Empty; } } } if (rowAccumBounds != Rectangle.Empty) { using (Surface dst = ScratchSurface.CreateWindow(rowAccumBounds), src = activeLayer.Surface.CreateWindow(rowAccumBounds)) { dst.CopySurface(src); } rowAccumBounds = Rectangle.Empty; } } if (this.saveRegion != null) { this.saveRegion.Dispose(); this.saveRegion = null; } if (saveMeRegion != null) { this.saveRegion = saveMeRegion.Clone(); } }
public PdnGraphicsPath CreatePixelatedPath() { using (PdnGraphicsPath path = CreatePath()) //PdnGraphicsPath path = GetPathReadOnly(); { using (PdnRegion region = new PdnRegion(path)) { PdnGraphicsPath pixellatedPath = PdnGraphicsPath.FromRegion(region); return pixellatedPath; } } }
private void OnSelectionChanged(object sender, EventArgs e) { this.render = true; PdnGraphicsPath path = this.selection.CreatePath(); //this.selection.GetPathReadOnly(); if (this.selectedPath == null) { Invalidate(); } else { this.selectedPath.Dispose(); // this.selectedPath = null; } bool fullInvalidate = false; this.selectedPath = path; // HACK: Sometimes the selection leaves behind artifacts. So do a full invalidate // every 1 second. if (this.selectedPath.PointCount > 10 && (DateTime.Now - lastFullInvalidate > new TimeSpan(0, 0, 0, 1, 0))) { fullInvalidate = true; } // if we're moving to a simpler selection region ... if (this.selectedPath == null)// || this.selectedPath.PointCount == 0) { // then invalidate everything fullInvalidate = true; } else { // otherwise, be intelligent about it and only redraw the 'new' area PdnRegion xorMe = new PdnRegion(this.selectedPath); selectionRedrawInterior.Xor(xorMe); xorMe.Dispose(); } float ratio = 1.0f / (float)OwnerList.ScaleFactor.Ratio; int ratioInt = (int)Math.Ceiling(ratio); if (this.Visible && (this.EnableSelectionOutline || this.EnableSelectionTinting)) { using (PdnRegion simplified = Utility.SimplifyAndInflateRegion(selectionRedrawInterior, Utility.DefaultSimplificationFactor, 2 * ratioInt)) { Invalidate(simplified); } } if (fullInvalidate) { Rectangle rect = Rectangle.Inflate(Rectangle.Truncate(selectionRedrawOutline.GetBounds2()), 1, 1); Invalidate(rect); lastFullInvalidate = DateTime.Now; } this.selectionRedrawInterior.Dispose(); this.selectionRedrawInterior = null; if (this.zoomInSelectedPath != null) { this.zoomInSelectedPath.Dispose(); this.zoomInSelectedPath = null; } this.simplifiedRegionForTimer = null; // prepare for next call if (this.selectedPath != null && !this.selectedPath.IsEmpty) { this.selectionRedrawOutline = (PdnGraphicsPath)this.selectedPath.Clone(); this.selectionRedrawInterior = new PdnRegion(this.selectedPath); } else { if (invertedTinting) { this.selectionRedrawInterior = new PdnRegion(new Rectangle(0, 0, this.SourceSize.Width, this.SourceSize.Height)); } else { this.selectionRedrawInterior = new PdnRegion(); this.selectionRedrawInterior.MakeEmpty(); } Invalidate(); this.selectionRedrawOutline = new PdnGraphicsPath(); } }
public RenderedTileEventArgs(PdnRegion renderedRegion, int tileCount, int tileNumber) { this.renderedRegion = renderedRegion; this.tileCount = tileCount; this.tileNumber = tileNumber; }