| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 | using PaintDotNet.Measurement.HistoryMementos;using System;using System.Collections.Generic;using System.Drawing;using System.Drawing.Drawing2D;using System.Windows.Forms;namespace PaintDotNet.Measurement.Tools{    public class EraserTool : Tool    {        private bool mouseDown;        private MouseButtons mouseButton;        private List<Rectangle> savedRects;        private Point lastMouseXY;        private RenderArgs renderArgs;        private BitmapLayer bitmapLayer;        private Cursor cursorMouseDown;        private Cursor cursorMouseUp;        private BrushPreviewRenderer previewRenderer;        protected override void OnMouseEnter()        {            this.previewRenderer.Visible = true;            base.OnMouseEnter();        }        protected override void OnMouseLeave()        {            this.previewRenderer.Visible = false;            base.OnMouseLeave();        }        protected override void OnActivate()        {            base.OnActivate();            // cursor-transitions            this.cursorMouseUp = new Cursor(PdnResources.GetResourceStream("Cursors.EraserToolCursor.cur"));            this.cursorMouseDown = new Cursor(PdnResources.GetResourceStream("Cursors.EraserToolCursorMouseDown.cur"));            this.Cursor = cursorMouseUp;            this.savedRects = new List<Rectangle>();            if (ActiveLayer != null)            {                bitmapLayer = (BitmapLayer)ActiveLayer;                renderArgs = new RenderArgs(bitmapLayer.Surface);            }            else            {                bitmapLayer = null;                renderArgs = null;            }            this.previewRenderer = new BrushPreviewRenderer(this.RendererList);            this.RendererList.Add(this.previewRenderer, false);        }        protected override void OnDeactivate()        {            base.OnDeactivate();            if (cursorMouseUp != null)            {                cursorMouseUp.Dispose();                cursorMouseUp = null;            }            if (cursorMouseDown != null)            {                cursorMouseDown.Dispose();                cursorMouseDown = null;            }            if (mouseDown)            {                OnMouseUp(new MouseEventArgs(mouseButton, 0, lastMouseXY.X, lastMouseXY.Y, 0));            }            this.RendererList.Remove(this.previewRenderer);            this.previewRenderer.Dispose();            this.previewRenderer = null;            this.savedRects.Clear();            if (renderArgs != null)            {                renderArgs.Dispose();                renderArgs = null;            }            bitmapLayer = null;        }        protected override void OnMouseDown(MouseEventArgs e)        {            base.OnMouseDown(e);            this.Cursor = this.cursorMouseDown;            if (((e.Button & MouseButtons.Left) == MouseButtons.Left) ||                ((e.Button & MouseButtons.Right) == MouseButtons.Right))            {                this.previewRenderer.Visible = false;                mouseDown = true;                mouseButton = e.Button;                lastMouseXY.X = e.X;                lastMouseXY.Y = e.Y;                PdnRegion clipRegion = Selection.CreateRegion();                renderArgs.Graphics.SetClip(clipRegion.GetRegionReadOnly(), CombineMode.Replace);                clipRegion.Dispose();                OnMouseMove(e);            }        }        protected override void OnMouseUp(MouseEventArgs e)        {            base.OnMouseUp(e);            Cursor = cursorMouseUp;            if (mouseDown)            {                OnMouseMove(e);                this.previewRenderer.Visible = true;                mouseDown = false;                if (this.savedRects.Count > 0)                {                    Rectangle[] savedScans = this.savedRects.ToArray();                    PdnRegion saveMeRegion = Utility.RectanglesToRegion(savedScans);                    HistoryMemento ha = new BitmapHistoryMemento(Name, Image, DocumentWorkspace,                        ActiveLayerIndex, saveMeRegion, this.ScratchSurface);                    //HistoryStack.PushNewMemento(ha);                    saveMeRegion.Dispose();                    this.savedRects.Clear();                    ClearSavedMemory();                }            }        }        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.GetPrimaryColorA();//.A;                }                else                {                    alpha = AppEnvironment.GetSecondaryColorA();//.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;            }        }        public EraserTool(IDocumentWorkspace documentWorkspace)            : base(documentWorkspace,                   PdnResources.GetImageResource("Icons.EraserToolIcon.png"),                   PdnResources.GetString("EraserTool.Name"),                   PdnResources.GetString("EraserTool.HelpText"), //"Click and drag to erase a portion of the image",                   'e',                   false,                   ToolBarConfigItems.Pen | ToolBarConfigItems.Antialiasing)        {        }    }}
 |