1 /* 2 PPDocument.h 3 4 Copyright 2013-2018 Josh Freeman 5 http://www.twilightedge.com 6 7 This file is part of PikoPixel for Mac OS X and GNUstep. 8 PikoPixel is a graphical application for drawing & editing pixel-art images. 9 10 PikoPixel is free software: you can redistribute it and/or modify it under 11 the terms of the GNU Affero General Public License as published by the 12 Free Software Foundation, either version 3 of the License, or (at your 13 option) any later version approved for PikoPixel by its copyright holder (or 14 an authorized proxy). 15 16 PikoPixel is distributed in the hope that it will be useful, but WITHOUT ANY 17 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 18 FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more 19 details. 20 21 You should have received a copy of the GNU Affero General Public License 22 along with this program. If not, see <http://www.gnu.org/licenses/>. 23 */ 24 25 #import <Cocoa/Cocoa.h> 26 #import "PPDocumentTypes.h" 27 #import "PPDefines.h" 28 #import "PPToolType.h" 29 #import "PPGridType.h" 30 #import "PPDirectionType.h" 31 #import "PPLayerDisplayMode.h" 32 #import "PPSamplerImagePanelType.h" 33 #import "NSDocument_PPUtilities.h" 34 #import "PPBitmapPixelTypes.h" 35 36 37 @class PPDocumentLayer, PPTool, PPBackgroundPattern, PPGridPattern, PPDocumentSamplerImage, 38 PPExportPanelAccessoryViewController, PPDocumentWindowController; 39 40 @interface PPDocument : NSDocument <NSCoding> 41 { 42 NSRect _canvasFrame; 43 44 NSMutableArray *_layers; 45 int _numLayers; 46 47 PPDocumentLayer *_drawingLayer; 48 NSBitmapImageRep *_drawingLayerBitmap; 49 NSImage *_drawingLayerImage; 50 int _indexOfDrawingLayer; 51 52 NSBitmapImageRep *_dissolvedDrawingLayerBitmap; 53 NSImage *_dissolvedDrawingLayerThumbnailImage; 54 55 NSBitmapImageRep *_mergedVisibleLayersBitmap; 56 NSImage *_mergedVisibleLayersThumbnailImage; 57 58 NSBitmapImageRep *_mergedVisibleLayersLinearBitmap; 59 60 NSObject *_cachedOverlayersImageObjects[kMaxLayersPerDocument]; 61 NSObject *_cachedUnderlayersImageObjects[kMaxLayersPerDocument]; 62 63 NSBitmapImageRep *_drawingMask; 64 65 NSBitmapImageRep *_drawingUndoBitmap; 66 NSRect _drawingUndoBounds; 67 68 NSBitmapImageRep *_selectionMask; 69 NSRect _selectionBounds; 70 71 NSBitmapImageRep *_interactiveEraseMask; 72 NSRect _interactiveEraseBounds; 73 74 PPToolType _selectedToolType; 75 PPToolType _lastSelectedToolType; 76 PPToolType _activeToolType; 77 PPTool *_activeTool; 78 79 PPPenMode _penMode; 80 81 NSColor *_fillColor; // original colorspace preserved, returned by -fillColor method 82 NSColor *_fillColor_sRGB; // _fillColor in sRGB colorspace, used when drawing & saving 83 84 PPImageBitmapPixel _fillColorPixelValue_sRGB; // _fillColor_sRGB as bitmapData pixel-value 85 86 PPLayerOperationTarget _layerOperationTarget; 87 int _targetLayerIndexes[kMaxLayersPerDocument]; 88 int _numTargetLayerIndexes; 89 90 PPLayerBlendingMode _layerBlendingMode; 91 92 PPBackgroundPattern *_backgroundPattern; 93 NSImage *_backgroundImage; 94 NSData *_compressedBackgroundImageData; 95 96 PPGridPattern *_gridPattern; 97 98 NSMutableArray *_samplerImages; 99 int _numSamplerImages; 100 int _activeSamplerImageIndexes[kNumPPSamplerImagePanelTypes]; 101 int _samplerImageMinIndexValues[kNumPPSamplerImagePanelTypes]; 102 103 PPLayerOperationTarget _interactiveMoveOperationTarget; 104 PPLayerDisplayMode _interactiveMoveDisplayMode; 105 NSBitmapImageRep *_interactiveMoveTargetBitmap; 106 NSBitmapImageRep *_interactiveMoveFloatingBitmap; 107 NSBitmapImageRep *_interactiveMoveFloatingMask; 108 NSBitmapImageRep *_interactiveMoveUnderlyingBitmap; 109 NSBitmapImageRep *_interactiveMoveInitialSelectionMask; 110 NSRect _interactiveMoveInitialSelectionBounds; 111 PPMoveOperationType _lastInteractiveMoveType; 112 NSPoint _lastInteractiveMoveOffset; 113 NSRect _lastInteractiveMoveBounds; 114 115 PPExportPanelAccessoryViewController *_exportPanelViewController; 116 117 PPDocumentSaveFormat _saveFormat; 118 119 bool _hasSelection; 120 bool _isDrawing; 121 bool _shouldUndoCurrentDrawing; 122 bool _isPerformingInteractiveMove; 123 bool _shouldDisplayBackgroundImage; 124 bool _shouldSmoothenBackgroundImage; 125 bool _shouldDisplayGrid; 126 bool _shouldEnableSamplerImagePanel; 127 bool _mergedVisibleBitmapHasEnabledLayer; 128 bool _disallowUpdatesToMergedBitmap; 129 bool _disallowThumbnailImageUpdateNotifications; 130 bool _disallowAutosaving; 131 bool _shouldAutosaveWhenAllowed; 132 bool _savePanelShouldAttachExportAccessoryView; 133 bool _saveToOperationShouldUseExportSettings; 134 bool _sourceBitmapHasAnimationFrames; 135 } 136 137 - (bool) setupNewPPDocumentWithCanvasSize: (NSSize) canvasSize; 138 139 - (bool) loadFromPPDocument: (PPDocument *) ppDocument; 140 141 - (bool) loadFromImageBitmap: (NSBitmapImageRep *) bitmap 142 withFileType: (NSString *) fileType; 143 144 - (bool) needToSetCanvasSize; 145 - (NSSize) canvasSize; 146 147 - (bool) resizeCanvasForCurrentLayers; 148 149 - (NSBitmapImageRep *) mergedVisibleLayersBitmap; 150 - (NSImage *) mergedVisibleLayersThumbnailImage; 151 152 - (NSBitmapImageRep *) drawingLayerBitmap; 153 - (NSImage *) drawingLayerThumbnailImage; 154 155 - (NSBitmapImageRep *) dissolvedDrawingLayerBitmap; 156 - (NSImage *) dissolvedDrawingLayerThumbnailImage; 157 158 - (NSBitmapImageRep *) mergedVisibleLayersBitmapUsingExportPanelSettings; 159 160 - (PPDocumentWindowController *) ppDocumentWindowController; 161 162 - (void) setupCompressedBackgroundImageData; 163 - (void) destroyCompressedBackgroundImageData; 164 165 - (bool) sourceBitmapHasAnimationFrames; 166 167 @end 168 169 @interface PPDocument (Saving) 170 171 - (void) disableAutosaving: (bool) disallowAutosaving; 172 173 - (void) exportImage; 174 175 @end 176 177 @interface PPDocument (LayerOperationTarget) 178 179 - (void) setLayerOperationTarget: (PPLayerOperationTarget) operationTarget; 180 - (PPLayerOperationTarget) layerOperationTarget; 181 182 - (bool) layerOperationTargetHasEnabledLayer; 183 184 - (NSBitmapImageRep *) sourceBitmapForLayerOperationTarget: 185 (PPLayerOperationTarget) operationTarget; 186 187 - (void) setupTargetLayerIndexesForOperationTarget: (PPLayerOperationTarget) operationTarget; 188 189 - (NSString *) nameOfLayerOperationTarget: (PPLayerOperationTarget) operationTarget; 190 - (NSString *) nameWithSelectionStateForLayerOperationTarget: 191 (PPLayerOperationTarget) operationTarget; 192 193 @end 194 195 @interface PPDocument (Layers) 196 197 - (int) numLayers; 198 - (PPDocumentLayer *) layerAtIndex: (int) index; 199 200 - (void) createNewLayer; 201 - (void) insertLayer: (PPDocumentLayer *) layer 202 atIndex: (int) index 203 andSetAsDrawingLayer: (bool) shouldSetAsDrawingLayer; 204 - (void) removeLayerAtIndex: (int) index; 205 - (void) moveLayerAtIndex: (int) oldIndex 206 toIndex: (int) newIndex; 207 - (void) duplicateLayerAtIndex: (int) index; 208 209 - (void) removeAllLayers; 210 - (void) removeNontargetLayers; 211 212 - (bool) setLayers: (NSArray *) newLayers; 213 214 - (void) selectDrawingLayerAtIndex: (int) newDrawingLayerIndex; 215 - (int) indexOfDrawingLayer; 216 - (PPDocumentLayer *) drawingLayer; 217 218 - (void) beginMultilayerOperation; 219 - (void) finishMultilayerOperation; 220 221 - (void) moveDrawingLayerUp; 222 - (void) moveDrawingLayerDown; 223 224 - (void) mergeDrawingLayerUp; 225 - (void) mergeDrawingLayerDown; 226 227 - (void) mergeAllLayers; 228 229 - (void) setEnabledFlagForAllLayers: (bool) isEnabled; 230 231 - (PPLayerBlendingMode) layerBlendingMode; 232 - (void) setLayerBlendingMode: (PPLayerBlendingMode) layerBlendingMode; 233 - (void) toggleLayerBlendingMode; 234 235 - (bool) setupLayerBlendingBitmapOfSize: (NSSize) bitmapSize; 236 237 - (void) copyImageBitmap: (NSBitmapImageRep *) bitmap 238 toLayerAtIndex: (int) index 239 atPoint: (NSPoint) origin; 240 241 - (void) handleUpdateToLayerAtIndex: (int) index 242 inRect: (NSRect) updateRect; 243 244 @end 245 246 @interface PPDocument (ActiveTool) 247 248 // The Selected tool is the tool selected by the user in the tool palette; The Active tool is 249 // the tool used on the canvas - it can be different from the Selected tool if a modifier key's 250 // pressed. 251 252 - (void) setSelectedToolType: (PPToolType) toolType; 253 - (void) setSelectedToolTypeToLastSelectedType; 254 - (PPToolType) selectedToolType; 255 256 - (void) setActiveToolType: (PPToolType) toolType; 257 - (PPToolType) activeToolType; 258 - (PPTool *) activeTool; 259 260 @end 261 262 @interface PPDocument (Drawing) 263 264 - (NSColor *) fillColor; 265 - (void) setFillColor: (NSColor *) fillColor; 266 - (void) setFillColorWithoutUndoRegistration: (NSColor *) fillColor; 267 268 - (void) beginDrawingWithPenMode: (PPPenMode) penMode; 269 - (void) finishDrawing; 270 271 - (void) undoCurrentDrawingAtNextDraw; 272 273 - (void) drawPixelAtPoint: (NSPoint) point; 274 - (void) drawLineFromPoint: (NSPoint) startPoint toPoint: (NSPoint) endPoint; 275 - (void) drawRect: (NSRect) rect andFill: (bool) shouldFill; 276 - (void) drawOvalInRect: (NSRect) rect andFill: (bool) shouldFill; 277 - (void) drawBezierPath: (NSBezierPath *) path andFill: (bool) shouldFill; 278 279 - (void) drawColorRampWithStartingColor: (NSColor *) startColor 280 fromPoint: (NSPoint) startPoint 281 toPoint: (NSPoint) endPoint 282 returnedRampBounds: (NSRect *) returnedRampBounds 283 returnedDrawMask: (NSBitmapImageRep **) returnedDrawMask; 284 285 - (NSColor *) colorAtPoint: (NSPoint) point 286 inTarget: (PPLayerOperationTarget) target; 287 288 - (void) fillPixelsMatchingColorAtPoint: (NSPoint) point 289 colorMatchTolerance: (unsigned) colorMatchTolerance 290 pixelMatchingMode: (PPPixelMatchingMode) pixelMatchingMode 291 returnedMatchMask: (NSBitmapImageRep **) returnedMatchMask 292 returnedMatchMaskBounds: (NSRect *) returnedMatchMaskBounds; 293 294 - (void) noninteractiveFillSelectedDrawingArea; 295 296 - (void) noninteractiveEraseSelectedAreaInTarget: (PPLayerOperationTarget) operationTarget 297 andClearSelectionMask: (bool) shouldClearSelectionMask; 298 299 - (bool) getInteractiveEraseMask: (NSBitmapImageRep **) returnedEraseMask 300 andBounds: (NSRect *) returnedEraseBounds; 301 302 - (void) copyImageBitmapToDrawingLayer: (NSBitmapImageRep *) bitmap atPoint: (NSPoint) origin; 303 304 @end 305 306 @interface PPDocument (Selection) 307 308 - (bool) setupSelectionMaskBitmapOfSize: (NSSize) maskSize; 309 310 - (bool) hasSelection; 311 - (NSRect) selectionBounds; 312 313 - (NSBitmapImageRep *) selectionMask; 314 - (void) setSelectionMask: (NSBitmapImageRep *) selectionMask; 315 316 - (void) setSelectionMaskAreaWithBitmap: (NSBitmapImageRep *) selectionMask 317 atPoint: (NSPoint) origin; 318 319 - (void) selectRect: (NSRect) rect 320 selectionMode: (PPSelectionMode) selectionMode; 321 322 - (void) selectPath: (NSBezierPath *) path 323 selectionMode: (PPSelectionMode) selectionMode; 324 325 - (void) selectPixelsMatchingColorAtPoint: (NSPoint) point 326 colorMatchTolerance: (unsigned) colorMatchTolerance 327 pixelMatchingMode: (PPPixelMatchingMode) pixelMatchingMode 328 selectionMode: (PPSelectionMode) selectionMode; 329 330 - (void) selectAll; 331 - (void) selectVisibleTargetPixels; 332 - (void) deselectAll; 333 - (void) deselectInvisibleTargetPixels; 334 335 - (void) invertSelection; 336 - (void) closeHolesInSelection; 337 338 - (PPDocument *) ppDocumentFromSelection; 339 340 @end 341 342 @interface PPDocument (PixelMatching) 343 344 // maskForPixelsMatchingColorAtPoint::: can be called repeatedly (when dragging the fill or 345 // wand tools), so rather than construct a new bitmap each time, it just returns a pointer to 346 // the _drawingMask member (the returned bitmap should only be used temporarily) 347 348 - (NSBitmapImageRep *) maskForPixelsMatchingColorAtPoint: (NSPoint) point 349 colorMatchTolerance: (unsigned) colorMatchTolerance 350 pixelMatchingMode: (PPPixelMatchingMode) pixelMatchingMode 351 shouldIntersectSelectionMask: (bool) shouldIntersectSelectionMask; 352 353 @end 354 355 @interface PPDocument (Moving) 356 357 - (void) nudgeInDirection: (PPDirectionType) directionType 358 moveType: (PPMoveOperationType) moveType 359 target: (PPLayerOperationTarget) operationTarget; 360 361 - (void) beginInteractiveMoveWithTarget: (PPLayerOperationTarget) operationTarget 362 canvasDisplayMode: (PPLayerDisplayMode) canvasDisplayMode 363 moveType: (PPMoveOperationType) moveType; 364 365 - (void) setInteractiveMoveOffset: (NSPoint) offset 366 andMoveType: (PPMoveOperationType) moveType; 367 368 - (void) finishInteractiveMove; 369 370 @end 371 372 @interface PPDocument (MirroringRotating) 373 374 - (void) mirrorHorizontallyWithTarget: (PPLayerOperationTarget) operationTarget; 375 - (void) mirrorVerticallyWithTarget: (PPLayerOperationTarget) operationTarget; 376 377 - (void) rotate180WithTarget: (PPLayerOperationTarget) operationTarget; 378 - (void) rotate90ClockwiseWithTarget: (PPLayerOperationTarget) operationTarget; 379 - (void) rotate90CounterclockwiseWithTarget: (PPLayerOperationTarget) operationTarget; 380 381 @end 382 383 @interface PPDocument (Pasteboard) 384 385 - (bool) canReadFromPasteboard; 386 - (bool) canWriteToPasteboard; 387 388 - (void) copySelectionToPasteboardFromTarget: (PPLayerOperationTarget) operationTarget; 389 390 - (void) cutSelectionToPasteboardFromTarget: (PPLayerOperationTarget) operationTarget; 391 392 - (void) pasteNewLayerFromPasteboard; 393 - (void) pasteIntoDrawingLayerFromPasteboard; 394 395 + (PPDocument *) ppDocumentFromPasteboard; 396 397 @end 398 399 @interface PPDocument (CanvasSettings) 400 401 - (void) setBackgroundPattern: (PPBackgroundPattern *) backgroundPattern 402 backgroundImage: (NSImage *) backgroundImage 403 shouldDisplayBackgroundImage: (bool) shouldDisplayBackgroundImage 404 shouldSmoothenBackgroundImage: (bool) shouldSmoothenBackgroundImage; 405 406 - (PPBackgroundPattern *) backgroundPattern; 407 - (NSColor *) backgroundPatternAsColor; 408 - (NSImage *) backgroundImage; 409 - (bool) shouldDisplayBackgroundImage; 410 - (bool) shouldSmoothenBackgroundImage; 411 412 - (void) toggleBackgroundImageVisibility; 413 - (void) toggleBackgroundImageSmoothing; 414 415 - (void) setGridPattern: (PPGridPattern *) gridPattern 416 shouldDisplayGrid: (bool) shouldDisplayGrid; 417 418 - (PPGridPattern *) gridPattern; 419 420 - (bool) shouldDisplayGrid; 421 - (void) toggleGridVisibility; 422 423 - (PPGridType) pixelGridPatternType; 424 - (void) togglePixelGridPatternType; 425 426 - (bool) gridPatternShouldDisplayGuidelines; 427 - (void) toggleGridGuidelinesVisibility; 428 429 - (bool) shouldDisplayGridAndGridGuidelines; 430 431 - (NSRect) gridGuidelineBoundsCoveredByRect: (NSRect) rect; 432 433 - (bool) hasCustomCanvasSettings; 434 435 @end 436 437 @interface PPDocument (Resizing) 438 439 - (void) resizeToSize: (NSSize) newSize shouldScale: (bool) shouldScale; 440 441 - (void) cropToSelectionBounds; 442 443 @end 444 445 @interface PPDocument (Tiling) 446 447 - (void) tileSelection; 448 449 - (void) tileSelectionAsNewLayer; 450 451 @end 452 453 @interface PPDocument (SamplerImages) 454 455 - (void) setupSamplerImageIndexes; 456 457 - (int) numSamplerImages; 458 459 - (NSArray *) samplerImages; 460 - (void) setSamplerImages: (NSArray *) newSamplerImages; 461 462 - (PPDocumentSamplerImage *) activeSamplerImageForPanelType: 463 (PPSamplerImagePanelType) samplerPanelType; 464 465 - (void) activateNextSamplerImageForPanelType: (PPSamplerImagePanelType) samplerPanelType; 466 - (void) activatePreviousSamplerImageForPanelType: (PPSamplerImagePanelType) samplerPanelType; 467 468 - (bool) hasActiveSamplerImageForPanelType: (PPSamplerImagePanelType) samplerPanelType; 469 470 - (bool) shouldEnableSamplerImagePanel; 471 - (void) setShouldEnableSamplerImagePanel: (bool) shouldEnableSamplerImagePanel; 472 473 @end 474 475 @interface PPDocument (NotificationOverrides) 476 477 // for better performance, operations that perform multiple quick updates to the document 478 // bitmaps (interactive drawing, interactive moving, opacity sliders) should disable thumbnail 479 // image update notifications to prevent the various thumbnail views from redrawing (each 480 // different size forces a resample of the entire image: SLOW) until the end of the operation 481 - (void) disableThumbnailImageUpdateNotifications: 482 (bool) shouldDisableThumbnailImageUpdateNotifications; 483 484 - (void) sendThumbnailImageUpdateNotifications; 485 486 @end 487 488 extern NSString *PPDocumentNotification_UpdatedMergedVisibleArea; 489 extern NSString *PPDocumentNotification_UpdatedDrawingLayerArea; 490 extern NSString *PPDocumentNotification_UpdatedMergedVisibleThumbnailImage; 491 extern NSString *PPDocumentNotification_UpdatedDrawingLayerThumbnailImage; 492 extern NSString *PPDocumentNotification_UpdatedSelection; 493 extern NSString *PPDocumentNotification_SwitchedDrawingLayer; 494 extern NSString *PPDocumentNotification_ReorderedLayers; 495 extern NSString *PPDocumentNotification_PerformedMultilayerOperation; 496 extern NSString *PPDocumentNotification_ChangedLayerAttribute; 497 extern NSString *PPDocumentNotification_SwitchedLayerOperationTarget; 498 extern NSString *PPDocumentNotification_SwitchedLayerBlendingMode; 499 extern NSString *PPDocumentNotification_SwitchedSelectedTool; 500 extern NSString *PPDocumentNotification_SwitchedActiveTool; 501 extern NSString *PPDocumentNotification_ChangedFillColor; 502 extern NSString *PPDocumentNotification_UpdatedBackgroundSettings; 503 extern NSString *PPDocumentNotification_UpdatedGridSettings; 504 extern NSString *PPDocumentNotification_ReloadedDocument; 505 extern NSString *PPDocumentNotification_UpdatedSamplerImages; 506 extern NSString *PPDocumentNotification_SwitchedActiveSamplerImage; 507 508 extern NSString *PPDocumentNotification_UserInfoKey_UpdateAreaRect; 509 extern NSString *PPDocumentNotification_UserInfoKey_IndexOfChangedLayer; 510 extern NSString *PPDocumentNotification_UserInfoKey_SamplerImagePanelType; 511