CropToSelectionFunction.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. using PaintDotNet.Measurement.HistoryMementos;
  2. using System;
  3. using System.Drawing;
  4. namespace PaintDotNet.Measurement.HistoryFunctions
  5. {
  6. /// <summary>
  7. /// Crops the image to the currently selected region.
  8. /// </summary>
  9. public sealed class CropToSelectionFunction : HistoryFunction
  10. {
  11. public static string StaticName
  12. {
  13. get
  14. {
  15. return PdnResources.GetString("CropAction.Name");
  16. }
  17. }
  18. public override HistoryMemento OnExecute(IDocumentWorkspace historyWorkspace)
  19. {
  20. if (historyWorkspace.GetSelection().IsEmpty)
  21. {
  22. return null;
  23. }
  24. else
  25. {
  26. PdnRegion selectionRegion = historyWorkspace.GetSelection().CreateRegion();
  27. if (selectionRegion.GetArea() == 0)
  28. {
  29. selectionRegion.Dispose();
  30. return null;
  31. }
  32. SelectionHistoryMemento sha = new SelectionHistoryMemento(StaticName, null, historyWorkspace);
  33. ReplaceDocumentHistoryMemento rdha = new ReplaceDocumentHistoryMemento(StaticName, null, historyWorkspace);
  34. Rectangle boundingBox;
  35. Rectangle[] inverseRegionRects = null;
  36. boundingBox = Utility.GetRegionBounds(selectionRegion);
  37. using (PdnRegion inverseRegion = new PdnRegion(boundingBox))
  38. {
  39. inverseRegion.Exclude(selectionRegion);
  40. inverseRegionRects = Utility.TranslateRectangles(
  41. inverseRegion.GetRegionScansReadOnlyInt(),
  42. -boundingBox.X,
  43. -boundingBox.Y);
  44. }
  45. selectionRegion.Dispose();
  46. selectionRegion = null;
  47. Document oldDocument = historyWorkspace.GetDocument(); // TODO: serialize this to disk so we don't *have* to store the full thing
  48. Document newDocument = new Document(boundingBox.Width, boundingBox.Height);
  49. // copy the document's meta data over
  50. newDocument.ReplaceMetaDataFrom(oldDocument);
  51. foreach (Layer layer in oldDocument.Layers)
  52. {
  53. if (layer is BitmapLayer)
  54. {
  55. BitmapLayer oldLayer = (BitmapLayer)layer;
  56. Surface croppedSurface = oldLayer.Surface.CreateWindow(boundingBox);
  57. BitmapLayer newLayer = new BitmapLayer(croppedSurface);
  58. ColorBgra clearWhite = ColorBgra.White.NewAlpha(0);
  59. foreach (Rectangle rect in inverseRegionRects)
  60. {
  61. newLayer.Surface.Clear(rect, clearWhite);
  62. }
  63. newLayer.LoadProperties(oldLayer.SaveProperties());
  64. newDocument.Layers.Add(newLayer);
  65. }
  66. else
  67. {
  68. throw new InvalidOperationException("Crop does not support Layers that are not BitmapLayers");
  69. }
  70. }
  71. CompoundHistoryMemento cha = new CompoundHistoryMemento(
  72. StaticName,
  73. PdnResources.GetImageResource("Icons.MenuImageCropIcon.png"),
  74. new HistoryMemento[] { sha, rdha });
  75. EnterCriticalRegion();
  76. historyWorkspace.SetDocument(newDocument);
  77. return cha;
  78. }
  79. }
  80. public CropToSelectionFunction()
  81. : base(PaintDotNet.Measurement.Enum.ActionFlags.None)
  82. {
  83. }
  84. }
  85. }