protected override void Drop() { RestoreSavedRegion(); PdnRegion regionCopy = Selection.CreateRegion(); using (PdnRegion simplifiedRegion = Utility.SimplifyAndInflateRegion(regionCopy, Utility.DefaultSimplificationFactor, 2)) { HistoryMemento bitmapAction2 = new BitmapHistoryMemento(Name, Image, DocumentWorkspace, ActiveLayerIndex, simplifiedRegion); bool oldHQ = this.fullQuality; this.fullQuality = true; Render(this.context.offset, true); this.fullQuality = oldHQ; this.currentHistoryMementos.Add(bitmapAction2); activeLayer.Invalidate(simplifiedRegion); Update(); } regionCopy.Dispose(); regionCopy = null; ContextHistoryMemento cha = new ContextHistoryMemento(this.DocumentWorkspace, this.ourContext, this.Name, this.Image); this.currentHistoryMementos.Add(cha); string name; ImageResource image; if (didPaste) { name = EnumLocalizer.EnumValueToLocalizedName(typeof(CommonAction), CommonAction.Paste); image = PdnResources.GetImageResource("Icons.MenuEditPasteIcon.png"); } else { name = this.Name; image = this.Image; } didPaste = false; SelectionHistoryMemento sha = new SelectionHistoryMemento(this.Name, this.Image, this.DocumentWorkspace); this.currentHistoryMementos.Add(sha); this.context.Dispose(); this.context = new MoveToolContext(); this.FlushHistoryMementos(PdnResources.GetString("MoveTool.HistoryMemento.DropPixels")); }
protected override HistoryMemento OnUndo(ProgressEventHandler progressCallback) { BitmapHistoryMementoData data = base.Data as BitmapHistoryMementoData; BitmapLayer layer = (BitmapLayer)this.historyWorkspace.Document.Layers[this.layerIndex]; RectInt32[] savedRegion = data.SavedRegion; MaskedSurface surface = null; BitmapHistoryMemento memento = new BitmapHistoryMemento(base.Name, base.Image, this.historyWorkspace, this.layerIndex, savedRegion); if (surface != null) { surface.Draw(layer.Surface); } else { using (FileStream stream = FileSystem.OpenStreamingFile(this.tempFileName, FileAccess.Read)) { LoadSurfaceRegion(stream, layer.Surface, data.SavedRegion); } this.tempFileHandle.Dispose(); this.tempFileHandle = null; } if (savedRegion.Length != 0) { RectInt32 roi = savedRegion.Bounds(); layer.Invalidate(roi); } return(memento); }
public override HistoryMemento OnExecute(IHistoryWorkspace historyWorkspace) { if (historyWorkspace.Selection.IsEmpty) { return(null); } PdnRegion region = historyWorkspace.Selection.CreateRegion(); BitmapLayer layer = ((BitmapLayer)historyWorkspace.ActiveLayer); PdnRegion simplifiedRegion = Utility.SimplifyAndInflateRegion(region); HistoryMemento hm = new BitmapHistoryMemento( StaticName, StaticImage, historyWorkspace, historyWorkspace.ActiveLayerIndex, simplifiedRegion); EnterCriticalRegion(); layer.Surface.Clear(region, this.fillColor); layer.Invalidate(simplifiedRegion); simplifiedRegion.Dispose(); region.Dispose(); return(hm); }
public override HistoryMemento OnExecute(IHistoryWorkspace historyWorkspace) { if ((this.layerIndex < 1) || (this.layerIndex >= historyWorkspace.Document.Layers.Count)) { object[] objArray1 = new object[] { "layerIndex must be greater than or equal to 1, and a valid layer index. layerIndex=", this.layerIndex, ", allowableRange=[0,", historyWorkspace.Document.Layers.Count, ")" }; throw new ArgumentException(string.Concat(objArray1)); } int layerIndex = this.layerIndex - 1; RectInt32 rect = historyWorkspace.Document.Bounds(); GeometryList list = new GeometryList(); list.AddRect(rect); RectInt32[] changedRegion = list.EnumerateInteriorScans().ToArrayEx <RectInt32>(); BitmapHistoryMemento memento = new BitmapHistoryMemento(null, null, historyWorkspace, layerIndex, changedRegion); BitmapLayer layer = (BitmapLayer)historyWorkspace.Document.Layers[this.layerIndex]; BitmapLayer layer2 = (BitmapLayer)historyWorkspace.Document.Layers[layerIndex]; RenderArgs args = new RenderArgs(layer2.Surface); base.EnterCriticalRegion(); foreach (RectInt32 num4 in changedRegion) { layer.Render(args, num4.ToGdipRectangle()); } layer2.Invalidate(); args.Dispose(); args = null; list = null; HistoryMemento memento2 = new DeleteLayerFunction(this.layerIndex).Execute(historyWorkspace); return(new CompoundHistoryMemento(StaticName, StaticImage, new HistoryMemento[] { memento, memento2 })); }
protected override HistoryMemento OnUndo(ProgressEventHandler progressCallback) { FlipLayerHistoryMemento memento = new FlipLayerHistoryMemento(base.Name, base.Image, this.historyWorkspace, this.layerIndex, this.flipType); BitmapLayer layer = (BitmapLayer)this.historyWorkspace.Document.Layers[this.layerIndex]; FlipInPlace(layer.Surface, this.flipType); layer.Invalidate(); return(memento); }
protected override HistoryMemento OnUndo() { FlipLayerHistoryMemento fha = new FlipLayerHistoryMemento(this.Name, this.Image, this.historyWorkspace, layerIndex, flipType); BitmapLayer layer = (BitmapLayer)this.historyWorkspace.Document.Layers[layerIndex]; Flip(layer.Surface); layer.Invalidate(); return(fha); }
public override HistoryMemento OnExecute(IHistoryWorkspace historyWorkspace) { if (this.layerIndex < 1 || this.layerIndex >= historyWorkspace.Document.Layers.Count) { throw new ArgumentException("layerIndex must be greater than or equal to 1, and a valid layer index. layerIndex=" + layerIndex + ", allowableRange=[0," + historyWorkspace.Document.Layers.Count + ")"); } int bottomLayerIndex = this.layerIndex - 1; Rectangle bounds = historyWorkspace.Document.Bounds; PdnRegion region = new PdnRegion(bounds); BitmapHistoryMemento bhm = new BitmapHistoryMemento( null, null, historyWorkspace, bottomLayerIndex, region); BitmapLayer topLayer = (BitmapLayer)historyWorkspace.Document.Layers[this.layerIndex]; BitmapLayer bottomLayer = (BitmapLayer)historyWorkspace.Document.Layers[bottomLayerIndex]; RenderArgs bottomRA = new RenderArgs(bottomLayer.Surface); EnterCriticalRegion(); topLayer.Render(bottomRA, region); bottomLayer.Invalidate(); bottomRA.Dispose(); bottomRA = null; region.Dispose(); region = null; DeleteLayerFunction dlf = new DeleteLayerFunction(this.layerIndex); HistoryMemento dlhm = dlf.Execute(historyWorkspace); CompoundHistoryMemento chm = new CompoundHistoryMemento(StaticName, StaticImage, new HistoryMemento[] { bhm, dlhm }); return(chm); }
public override HistoryMemento OnExecute(IHistoryWorkspace historyWorkspace) { if (historyWorkspace.Selection.IsEmpty) { return(null); } SelectionHistoryMemento shm = new SelectionHistoryMemento(string.Empty, null, historyWorkspace); PdnRegion region = historyWorkspace.Selection.CreateRegion(); BitmapLayer layer = ((BitmapLayer)historyWorkspace.ActiveLayer); PdnRegion simplifiedRegion = Utility.SimplifyAndInflateRegion(region); HistoryMemento hm = new BitmapHistoryMemento( null, null, historyWorkspace, historyWorkspace.ActiveLayerIndex, simplifiedRegion); HistoryMemento chm = new CompoundHistoryMemento( StaticName, StaticImage, new HistoryMemento[] { shm, hm }); EnterCriticalRegion(); layer.Surface.Clear(region, ColorBgra.FromBgra(255, 255, 255, 0)); layer.Invalidate(simplifiedRegion); historyWorkspace.Document.Invalidate(simplifiedRegion); simplifiedRegion.Dispose(); region.Dispose(); historyWorkspace.Selection.Reset(); return(chm); }
protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if (mouseDown && ((e.Button & mouseButton) != MouseButtons.None)) { Point mouseXY = new Point(e.X, e.Y); if (lastPoint == Point.Empty) { lastPoint = mouseXY; } difference = new Point(mouseXY.X - lastPoint.X, mouseXY.Y - lastPoint.Y); if (tracePoints.Count > 0) { Point lastMouseXY = (Point)tracePoints[tracePoints.Count - 1]; if (lastMouseXY == mouseXY) { return; } } if ((mouseButton & MouseButtons.Left) == MouseButtons.Left) { this.pencilColor = AppEnvironment.PrimaryColor; } else // if ((mouseButton & MouseButtons.Right) == MouseButtons.Right) { // right mouse button = swap primary/secondary this.pencilColor = AppEnvironment.SecondaryColor; } if (!(tracePoints.Count > 0 && mouseXY == (Point)tracePoints[tracePoints.Count - 1])) { tracePoints.Add(mouseXY); } if (ActiveLayer is BitmapLayer) { Rectangle saveRect; if (tracePoints.Count == 1) { saveRect = Utility.PointsToRectangle(mouseXY, mouseXY); } else { // >1 points saveRect = Utility.PointsToRectangle((Point)tracePoints[tracePoints.Count - 1], (Point)tracePoints[tracePoints.Count - 2]); } saveRect.Inflate(2, 2); saveRect.Intersect(ActiveLayer.Bounds); // drawing outside of the canvas is a no-op, so don't do anything in that case! // also make sure it's within the clipping bounds if (saveRect.Width > 0 && saveRect.Height > 0 && renderArgs.Graphics.IsVisible(saveRect)) { SaveRegion(null, saveRect); this.savedRects.Add(saveRect); int startIndex; int length; if (tracePoints.Count == 1) { startIndex = 0; length = 1; } else { startIndex = tracePoints.Count - 2; length = 2; } DrawLines(this.renderArgs, tracePoints, startIndex, length, pencilColor); bitmapLayer.Invalidate(saveRect); Update(); } } else { // will have to do something here if we add other layer types besides BitmapLayer } lastPoint = mouseXY; } }
protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if (mouseDown && ((e.Button & mouseButton) != MouseButtons.None)) { int alpha; if (e.Button == MouseButtons.Left) { alpha = AppEnvironment.PrimaryColor.A; } else { alpha = AppEnvironment.SecondaryColor.A; } Pen pen = AppEnvironment.PenInfo.CreatePen(AppEnvironment.BrushInfo, Color.FromArgb(alpha, 0, 0, 0), Color.FromArgb(alpha, 0, 0, 0)); Point a = lastMouseXY; Point b = new Point(e.X, e.Y); Rectangle saveRect = Utility.PointsToRectangle(a, b); saveRect.Inflate((int)Math.Ceiling(pen.Width), (int)Math.Ceiling(pen.Width)); if (renderArgs.Graphics.SmoothingMode == SmoothingMode.AntiAlias) { saveRect.Inflate(1, 1); } saveRect.Intersect(ActiveLayer.Bounds); // drawing outside of the canvas is a no-op, so don't do anything in that case! // also make sure we're within the clip region if (saveRect.Width > 0 && saveRect.Height > 0 && renderArgs.Graphics.IsVisible(saveRect)) { SaveRegion(null, saveRect); this.savedRects.Add(saveRect); if (AppEnvironment.AntiAliasing) { renderArgs.Graphics.SmoothingMode = SmoothingMode.AntiAlias; } else { renderArgs.Graphics.SmoothingMode = SmoothingMode.None; } new UnaryPixelOps.InvertWithAlpha().Apply(renderArgs.Surface, saveRect); renderArgs.Graphics.CompositingMode = CompositingMode.SourceOver; if (pen.Width > 1) { renderArgs.Graphics.PixelOffsetMode = PixelOffsetMode.Half; } else { renderArgs.Graphics.PixelOffsetMode = PixelOffsetMode.None; } pen.EndCap = LineCap.Round; pen.StartCap = LineCap.Round; renderArgs.Graphics.DrawLine(pen, a, b); renderArgs.Graphics.FillEllipse(pen.Brush, a.X - pen.Width / 2.0f, a.Y - pen.Width / 2.0f, pen.Width, pen.Width); new UnaryPixelOps.InvertWithAlpha().Apply(renderArgs.Surface, saveRect); new BinaryPixelOps.SetColorChannels().Apply(renderArgs.Surface, saveRect.Location, ScratchSurface, saveRect.Location, saveRect.Size); bitmapLayer.Invalidate(saveRect); Update(); } lastMouseXY = b; pen.Dispose(); } else { this.previewRenderer.BrushLocation = new Point(e.X, e.Y); this.previewRenderer.BrushSize = AppEnvironment.PenInfo.Width / 2.0f; } }
protected override void OnStylusMove(StylusEventArgs e) { base.OnStylusMove(e); PointF currMouseXY = new PointF(e.Fx, e.Fy); if (mouseDown && ((e.Button & mouseButton) != MouseButtons.None)) { float pressure = GetWidth(e.Pressure); float length; PointF a = lastMouseXY; PointF b = currMouseXY; PointF dir = new PointF(b.X - a.X, b.Y - a.Y); PointF norm; PointF[] poly; RectangleF dotRect = Utility.RectangleFromCenter(currMouseXY, pressure); if (pressure > 0.5f) { renderArgs.Graphics.PixelOffsetMode = PixelOffsetMode.Half; } else { renderArgs.Graphics.PixelOffsetMode = PixelOffsetMode.None; } // save direction before normalizing lastDir = dir; // normalize length = Utility.Magnitude(dir); dir.X /= length; dir.Y /= length; // compute normal vector, calculate perpendicular offest from stroke for width norm = new PointF(dir.Y, -dir.X); norm.X *= pressure; norm.Y *= pressure; a.X -= dir.X * 0.1666f; a.Y -= dir.Y * 0.1666f; lastNorm = norm; poly = MakePolygon( new PointF(a.X - lastNorm.X, a.Y - lastNorm.Y), new PointF(a.X + lastNorm.X, a.Y + lastNorm.Y), new PointF(b.X + norm.X, b.Y + norm.Y), new PointF(b.X - norm.X, b.Y - norm.Y)); RectangleF saveRect = RectangleF.Union( dotRect, RectangleF.Union( Utility.PointsToRectangle(poly[0], poly[1]), Utility.PointsToRectangle(poly[2], poly[3]))); saveRect.Inflate(2.0f, 2.0f); // account for anti-aliasing saveRect.Intersect(ActiveLayer.Bounds); // drawing outside of the canvas is a no-op, so don't do anything in that case! // also make sure we're within the clip region if (saveRect.Width > 0 && saveRect.Height > 0 && renderArgs.Graphics.IsVisible(saveRect)) { Rectangle saveRectRounded = Utility.RoundRectangle(saveRect); saveRectRounded.Intersect(ActiveLayer.Bounds); if (saveRectRounded.Width > 0 && saveRectRounded.Height > 0) { SaveRegion(null, saveRectRounded); this.savedRects.Add(saveRectRounded); if (AppEnvironment.AntiAliasing) { renderArgs.Graphics.SmoothingMode = SmoothingMode.AntiAlias; } else { renderArgs.Graphics.SmoothingMode = SmoothingMode.None; } renderArgs.Graphics.CompositingMode = AppEnvironment.GetCompositingMode(); renderArgs.Graphics.FillEllipse(brush, dotRect); // bail out early if the mouse hasn't even moved. If we don't bail out, we'll get a 0-distance move, which will result in a div-by-0 if (lastMouseXY != currMouseXY) { renderArgs.Graphics.FillPolygon(brush, poly, FillMode.Winding); } } bitmapLayer.Invalidate(saveRectRounded); } lastNorm = norm; lastMouseXY = currMouseXY; } else { lastMouseXY = currMouseXY; lastNorm = PointF.Empty; lastDir = PointF.Empty; this.previewRenderer.BrushSize = AppEnvironment.PenInfo.Width / 2.0f; } this.previewRenderer.BrushLocation = currMouseXY; }
protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); this.previewRenderer.BrushLocation = new Point(e.X, e.Y); this.previewRenderer.BrushSize = AppEnvironment.PenInfo.Width / 2.0f; if (mouseDown) { if (BtnDownMouseLeft(e) || BtnDownMouseRight(e)) { if (modifierDown == 0) { // if the primary and secondary colors are identical, // return...there's no point in committing any action if (colorReplacing == colorToReplace) { return; } // get our start and end coordinates, since we need // to trace along an action line -- the user will expect this behavior // if we don't, it'll look like a tin can riddled with bullet holes Point pointStartCorner = lastMouseXY; // start point Point pointEndCorner = new Point(e.X, e.Y); // end point // create the rectangle with the 'a' and 'b' points above Rectangle inspectionRect = Utility.PointsToRectangle(pointStartCorner, pointEndCorner); // inflate the region to address account for the pen width // then intersect with the Workspace to "clip" the boundary // the total area of the clipped rectangle includes the // width of the pen surrounding the points limited by either // the canvas perimeter or the selection outline inspectionRect.Inflate(1 + ceilingPenWidth / 2, 1 + ceilingPenWidth / 2); inspectionRect.Intersect(ActiveLayer.Bounds); // Enforce the selection area restrictions. // If within the selection area restrictions, build an image history bool gotWidth = inspectionRect.Width > 0; bool gotHeight = inspectionRect.Height > 0; bool isInClip = renderArgs.Graphics.IsVisible(inspectionRect); if ((gotWidth) && (gotHeight) && (isInClip)) { PlacedSurface savedPS = new PlacedSurface(renderArgs.Surface, inspectionRect); savedSurfaces.Add(savedPS); renderArgs.Graphics.CompositingMode = CompositingMode.SourceOver; // check the mouse buttons and if we've made it this far, at least // one of the mouse buttons (left|right) was depressed if (BtnDownMouseLeft(e)) { this.DrawOverPoints(pointStartCorner, pointEndCorner, colorReplacing, colorToReplace); } else { this.DrawOverPoints(pointStartCorner, pointEndCorner, colorToReplace, colorReplacing); } bitmapLayer.Invalidate(inspectionRect); Update(); } // update the lastMouseXY so we know how to "connect the dots" lastMouseXY = pointEndCorner; } else { switch (modifierDown & (Keys.Control | Keys.Shift)) { case Keys.Control: PickColor(e); break; case Keys.Shift: AdjustDrawingColor(e); break; default: break; } } } } }
protected void RenderShape() { // create the Pen we will use to draw with Pen outlinePen = null; Brush interiorBrush = null; PenInfo pi = AppEnvironment.PenInfo; BrushInfo bi = AppEnvironment.BrushInfo; ColorBgra primary = AppEnvironment.PrimaryColor; ColorBgra secondary = AppEnvironment.SecondaryColor; if (!ForceShapeDrawType && AppEnvironment.ShapeDrawType == ShapeDrawType.Interior) { Utility.Swap(ref primary, ref secondary); } // Initialize pens and brushes to the correct colors if ((mouseButton & MouseButtons.Left) == MouseButtons.Left) { outlinePen = pi.CreatePen(AppEnvironment.BrushInfo, primary.ToColor(), secondary.ToColor()); interiorBrush = bi.CreateBrush(secondary.ToColor(), primary.ToColor()); } else if ((mouseButton & MouseButtons.Right) == MouseButtons.Right) { outlinePen = pi.CreatePen(AppEnvironment.BrushInfo, secondary.ToColor(), primary.ToColor()); interiorBrush = bi.CreateBrush(primary.ToColor(), secondary.ToColor()); } if (!this.UseDashStyle) { outlinePen.DashStyle = DashStyle.Solid; } outlinePen.LineJoin = LineJoin.MiterClipped; outlinePen.MiterLimit = 2; // redraw the old saveSurface if (interiorSaveRegion != null) { RestoreRegion(interiorSaveRegion); interiorSaveRegion.Dispose(); interiorSaveRegion = null; } if (outlineSaveRegion != null) { RestoreRegion(outlineSaveRegion); outlineSaveRegion.Dispose(); outlineSaveRegion = null; } // anti-aliasing? Don't mind if I do if (AppEnvironment.AntiAliasing) { renderArgs.Graphics.SmoothingMode = SmoothingMode.AntiAlias; } else { renderArgs.Graphics.SmoothingMode = SmoothingMode.None; } // also set the pixel offset mode renderArgs.Graphics.PixelOffsetMode = GetPixelOffsetMode(); // figure out how we're going to draw ShapeDrawType drawType; if (ForceShapeDrawType) { drawType = ForcedShapeDrawType; } else { drawType = AppEnvironment.ShapeDrawType; } // get the region we want to save points = this.TrimShapePath(points); PointF[] pointsArray = points.ToArray(); PdnGraphicsPath shapePath = CreateShapePath(pointsArray); if (shapePath != null) { // create non-optimized interior region PdnRegion interiorRegion = new PdnRegion(shapePath); // create non-optimized outline region PdnRegion outlineRegion; using (PdnGraphicsPath outlinePath = (PdnGraphicsPath)shapePath.Clone()) { try { outlinePath.Widen(outlinePen); outlineRegion = new PdnRegion(outlinePath); } // Sometimes GDI+ gets cranky if we have a very small shape (e.g. all points // are coincident). catch (OutOfMemoryException) { outlineRegion = new PdnRegion(shapePath); } } // create optimized outlineRegion for purposes of rendering, if it is possible to do so // shapes will often provide an "optimized" region that circumvents the fact that // we'd otherwise get a region that encompasses the outline *and* the interior, thus // slowing rendering significantly in many cases. RectangleF[] optimizedOutlineRegion = GetOptimizedShapeOutlineRegion(pointsArray, shapePath); PdnRegion invalidOutlineRegion; if (optimizedOutlineRegion != null) { Utility.InflateRectanglesInPlace(optimizedOutlineRegion, (int)(outlinePen.Width + 2)); invalidOutlineRegion = Utility.RectanglesToRegion(optimizedOutlineRegion); } else { invalidOutlineRegion = Utility.SimplifyAndInflateRegion(outlineRegion, Utility.DefaultSimplificationFactor, (int)(outlinePen.Width + 2)); } // create optimized interior region PdnRegion invalidInteriorRegion = Utility.SimplifyAndInflateRegion(interiorRegion, Utility.DefaultSimplificationFactor, 3); PdnRegion invalidRegion = new PdnRegion(); invalidRegion.MakeEmpty(); // set up alpha blending renderArgs.Graphics.CompositingMode = AppEnvironment.GetCompositingMode(); SaveRegion(invalidOutlineRegion, invalidOutlineRegion.GetBoundsInt()); this.outlineSaveRegion = invalidOutlineRegion; if ((drawType & ShapeDrawType.Outline) != 0) { shapePath.Draw(renderArgs.Graphics, outlinePen); } invalidRegion.Union(invalidOutlineRegion); // draw shape if ((drawType & ShapeDrawType.Interior) != 0) { SaveRegion(invalidInteriorRegion, invalidInteriorRegion.GetBoundsInt()); this.interiorSaveRegion = invalidInteriorRegion; renderArgs.Graphics.FillPath(interiorBrush, shapePath); invalidRegion.Union(invalidInteriorRegion); } else { invalidInteriorRegion.Dispose(); invalidInteriorRegion = null; } bitmapLayer.Invalidate(invalidRegion); invalidRegion.Dispose(); invalidRegion = null; outlineRegion.Dispose(); outlineRegion = null; interiorRegion.Dispose(); interiorRegion = null; } Update(); if (shapePath != null) { shapePath.Dispose(); shapePath = null; } outlinePen.Dispose(); interiorBrush.Dispose(); }
protected override HistoryMemento OnUndo() { BitmapHistoryMementoData data = this.Data as BitmapHistoryMementoData; BitmapLayer layer = (BitmapLayer)this.historyWorkspace.Document.Layers[this.layerIndex]; PdnRegion region; MaskedSurface maskedSurface = null; if (this.poMaskedSurfaceRef != Guid.Empty) { PersistedObject <MaskedSurface> poMS = PersistedObjectLocker.Get <MaskedSurface>(this.poMaskedSurfaceRef); maskedSurface = poMS.Object; region = maskedSurface.CreateRegion(); } else if (data.UndoImage == null) { region = data.SavedRegion; } else { region = data.UndoImage.Region; } BitmapHistoryMemento redo; if (this.poUndoMaskedSurfaceRef == Guid.Empty) { redo = new BitmapHistoryMemento(Name, Image, this.historyWorkspace, this.layerIndex, region); redo.poUndoMaskedSurfaceRef = this.poMaskedSurfaceRef; } else { redo = new BitmapHistoryMemento(Name, Image, this.historyWorkspace, this.layerIndex, this.poUndoMaskedSurfaceRef); } PdnRegion simplified = Utility.SimplifyAndInflateRegion(region); if (maskedSurface != null) { maskedSurface.Draw(layer.Surface); } else if (data.UndoImage == null) { using (FileStream input = FileSystem.OpenStreamingFile(this.tempFileName, FileAccess.Read)) { LoadSurfaceRegion(input, layer.Surface, data.SavedRegion); } data.SavedRegion.Dispose(); this.tempFileHandle.Dispose(); this.tempFileHandle = null; } else { data.UndoImage.Draw(layer.Surface); data.UndoImage.Dispose(); } layer.Invalidate(simplified); simplified.Dispose(); return(redo); }
public override HistoryMemento OnExecute(IHistoryWorkspace historyWorkspace) { historyWorkspace.VerifyAccess(); BitmapLayer layer = (BitmapLayer)historyWorkspace.Document.Layers[this.layerIndex]; Surface layerSurface = layer.Surface; TileMathHelper tileMathHelper = new TileMathHelper(layerSurface.Width, layerSurface.Height, this.rendererTileEdgeLog2); TileMathHelper tileGroupMathHelper = new TileMathHelper(layerSurface.Width, layerSurface.Height, this.rendererTileEdgeLog2 + 3); HistoryMemento actionHM = null; ManualResetEvent taskFinishedEvent = new ManualResetEvent(false); ThreadTask <Unit> commitTask = historyWorkspace.TaskManager.StartNewThreadTask(delegate(Task task) { SegmentedList <RectInt32> list = tileGroupMathHelper.EnumerateTilesClippedToSourceRect(this.rendererClipRect).ToSegmentedList <RectInt32>(); ListUtil.FisherYatesShuffle <RectInt32>(list); ConcurrentQueue <ISurface <ColorBgra> > queue = new ConcurrentQueue <ISurface <ColorBgra> >(); ConcurrentQueue <RectInt32> changedTiles = new ConcurrentQueue <RectInt32>(); ConcurrentQueue <TupleStruct <RectInt32, ISurface <ColorBgra> > > changedTileGroups = new ConcurrentQueue <TupleStruct <RectInt32, ISurface <ColorBgra> > >(); double progressIncrement = 1.0 / ((double)Math.Max(1, list.Count)); task.Progress = 0.0; Work.ParallelForEach <RectInt32>(WaitType.Blocking, list, delegate(RectInt32 tileGroupRect) { ISurface <ColorBgra> dst = RetryManager.RunMemorySensitiveOperation <ISurfaceRef <ColorBgra> >(() => SurfaceAllocator.Bgra.Allocate <ColorBgra>(tileGroupRect.Size, AllocationOptions.ZeroFillNotRequired)); this.renderer.Render(dst, tileGroupRect.Location); bool flag = false; foreach (RectInt32 num in tileMathHelper.EnumerateTilesClippedToSourceRect(tileGroupRect)) { RectInt32 bounds = RectInt32.Offset(num, -tileGroupRect.Location); using (ISurface <ColorBgra> surface2 = layerSurface.CreateWindow(num)) { using (ISurface <ColorBgra> surface3 = dst.CreateWindow <ColorBgra>(bounds)) { if (!SurfaceBgraUtil.ArePixelsEqual(surface2, surface3)) { flag = true; changedTiles.Enqueue(num); } } } } if (flag) { changedTileGroups.Enqueue(TupleStruct.Create <RectInt32, ISurface <ColorBgra> >(tileGroupRect, dst)); } else { DisposableUtil.Free <ISurface <ColorBgra> >(ref dst); } task.IncrementProgressBy(progressIncrement); }, WorkItemQueuePriority.Normal, null); task.Progress = null; if (changedTiles.Count == 0) { actionHM = null; } else { SegmentedList <RectInt32> scans = new SegmentedList <RectInt32>(changedTiles.Count, 7); scans.AddRange(changedTiles); ScansHelpers.SortScansByTopLeft(scans); ScansHelpers.ConsolidateSortedScansInPlace(scans); actionHM = new BitmapHistoryMemento(this.historyMementoName, this.historyMementoImage, historyWorkspace, this.layerIndex, scans); this.EnterCriticalRegion(); Work.ParallelForEach <TupleStruct <RectInt32, ISurface <ColorBgra> > >(WaitType.Blocking, changedTileGroups, delegate(TupleStruct <RectInt32, ISurface <ColorBgra> > tileInfo) { using (ISurface <ColorBgra> surface = layerSurface.CreateWindow(tileInfo.Item1)) { tileInfo.Item2.Render(surface, PointInt32.Zero); } tileInfo.Item2.Dispose(); }, WorkItemQueuePriority.Normal, null); foreach (RectInt32 num in scans) { layer.Invalidate(num); } } }, ApartmentState.MTA); commitTask.ResultAsync <Unit>().Receive(delegate(Result <Unit> r) { taskFinishedEvent.Set(); }).Observe(); if (!taskFinishedEvent.WaitOne(this.delayUntilProgressDialogMs)) { string headerText = PdnResources.GetString("ApplyRendererToBitmapLayerHistoryFunction.ProgressDialog.HeaderText"); string headerTextFormat = PdnResources.GetString("ApplyRendererToBitmapLayerHistoryFunction.ProgressDialog.HeaderText.Format"); using (TaskProgressDialog progressDialog = new TaskProgressDialog()) { Action updateHeaderText = delegate { progressDialog.VerifyAccess(); if (!progressDialog.IsDisposed) { string text1; double?progress = commitTask.Progress; if (!progress.HasValue) { text1 = headerText; } else { text1 = string.Format(headerTextFormat, (progress.Value * 100.0).ToString("N0")); } progressDialog.HeaderText = text1; } }; progressDialog.Text = this.historyMementoName; progressDialog.Icon = this.historyMementoImage.Reference.ToIcon(); progressDialog.CloseOnFinished = true; progressDialog.ShowCancelButton = false; progressDialog.Task = commitTask; updateHeaderText(); commitTask.ProgressChanged += delegate(object s, ValueEventArgs <double?> e) { PdnSynchronizationContext.Instance.EnsurePosted(updateHeaderText); }; progressDialog.ShowDialog(historyWorkspace.Window); } } if (!commitTask.TaskResult.IsError) { return(actionHM); } if (commitTask.TaskResult.Error is OutOfMemoryException) { throw new OutOfMemoryException(null, commitTask.TaskResult.Error); } throw new AggregateException(null, commitTask.TaskResult.Error); }