home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / image144.sit / Image.p < prev    next >
Encoding:
Text File  |  1992-04-02  |  63.4 KB  |  2,464 lines

  1. program Image;
  2.  
  3. {NIH Image is a public domain program for the Macintosh for acquiring, enhancing, }
  4. {analyzing, editing, printing, and animating grayscale and color images.}
  5.  
  6.  
  7. {Version 1.44, 31 March 1992}
  8.  
  9.  
  10. {Developed using Think Pascal 4.0.1}
  11. {Note: provide at least a 4MB partition for Think Pascal when using MultiFinder.}
  12.  
  13. {Author :}
  14.  
  15. {Wayne Rasband}
  16. {National Institutes of Health}
  17.  
  18. {Internet: wayne@helix.nih.gov}
  19. {Phone: 301-496-4957}
  20.  
  21.  
  22.     uses
  23.         QuickDraw, Palettes, PrintTraps, globals, Utilities, Initialization, File1, File2, Analysis, Graphics, edit, Functions, Camera, User, Macros1, stacks, Background, Lut, Projection;
  24.  
  25. {$I-}
  26.  
  27.  
  28. {PROCEDURE MacsBug; inline $a9ff;}
  29.  
  30.  
  31.     procedure UpdateOptionsMenu;
  32.         var
  33.             CheckIt: boolean;
  34.             i: integer;
  35.     begin
  36.         with info^ do begin
  37.                 CheckItem(OptionsMenuH, GrayscaleItem, (LutMode = Grayscale) or (LutMode = CustomGrayscale));
  38.                 if LutMode <> PseudoColor then
  39.                     ColorTable := CustomTable;
  40.                 CheckItem(ColorTablesMenuH, SystemPaletteItem, ColorTable = AppleDefault);
  41.                 CheckItem(ColorTablesMenuH, Pseudo20Item, ColorTable = Pseudo20);
  42.                 CheckItem(ColorTablesMenuH, Pseudo32Item, ColorTable = Pseudo32);
  43.                 CheckItem(ColorTablesMenuH, RainbowItem, ColorTable = Rainbow);
  44.                 CheckItem(ColorTablesMenuH, Fire1Item, ColorTable = Fire1);
  45.                 CheckItem(ColorTablesMenuH, Fire2Item, ColorTable = Fire2);
  46.                 CheckItem(ColorTablesMenuH, IceItem, ColorTable = Ice);
  47.                 CheckItem(ColorTablesMenuH, GraysItem, ColorTable = Grays);
  48.                 CheckItem(ColorTablesMenuH, SpectrumItem, ColorTable = Spectrum);
  49.                 SetMenuItem(OptionsMenuH, ScaleToFitItem, info <> NoInfo);
  50.                 CheckIt := ScaleToFitWindow;
  51.                 CheckItem(OptionsMenuH, ScaleToFitItem, CheckIt);
  52.                 CheckItem(OptionsMenuH, ThresholdItem, Thresholding);
  53.                 CheckItem(OptionsMenuH, SliceItem, DensitySlicing);
  54.                 SetMenuItem(OptionsMenuH, PropagateItem, nPics > 1);
  55.             end;
  56.     end;
  57.  
  58.  
  59.     procedure UpdateEnhanceMenu;
  60.         var
  61.             ShowItems: boolean;
  62.             i: integer;
  63.             str: str255;
  64.     begin
  65.         ShowItems := Info <> NoInfo;
  66.         for i := SmoothItem to ConvolveItem do
  67.             SetMenuItem(EnhanceMenuH, i, ShowItems);
  68.         with info^ do
  69.             if (LutMode = GrayScale) or (LutMode = CustomGrayscale) or DensitySlicing then
  70.                 SetItem(EnhanceMenuH, ApplyItem, 'Apply LUT')
  71.             else
  72.                 SetItem(EnhanceMenuH, ApplyItem, 'Convert to Grayscale');
  73.         for i := BinaryItem to ChangeItem do
  74.             SetMenuItem(EnhanceMenuH, i, ShowItems);
  75.         NumToString(BinaryCount, str);
  76.         str := concat('Set Count[', str, ']╔');
  77.         SetItem(BinaryMenuH, SetCountItem, str);
  78.         NumToString(BinaryIterations, str);
  79.         str := concat('Set Iterations[', str, ']╔');
  80.         SetItem(BinaryMenuH, IterationsItem, str);
  81.         CheckItem(BackgroundMenuH, FasterItem, FasterBackgroundSubtraction);
  82.         NumToString(BallRadius, str);
  83.         str := concat('Set Radius[', str, ']╔');
  84.         SetItem(BackgroundMenuH, RadiusItem, str);
  85.     end;
  86.  
  87.  
  88.     procedure UpdateSpecialMenu;
  89.         var
  90.             ShowItems: boolean;
  91.     begin
  92.         ShowItems := Info <> NoInfo;
  93.         SetMenuItem(SpecialMenuH, SaveBlankFieldItem, ShowItems);
  94.         SetMenuItem(SpecialMenuH, PhotoModeItem, ShowItems);
  95.         with info^ do
  96.             SetMenuItem(SpecialMenuH, SortItem, not ((LutMode = grayscale) or (LutMode = CustomGrayscale)));
  97.     end;
  98.  
  99.  
  100.     procedure UpdateStacksMenu;
  101.         var
  102.             ShowItems: boolean;
  103.             isStack: boolean;
  104.     begin
  105.         ShowItems := Info <> NoInfo;
  106.         SetMenuItem(StacksMenuH, StackFromWindowsItem, nPics > 0);
  107.         isStack := info^.StackInfo <> nil;
  108.         SetMenuItem(StacksMenuH, WindowsFromStackItem, isStack);
  109.         SetMenuItem(StacksMenuH, AddSliceItem, isStack);
  110.         SetMenuItem(StacksMenuH, DeleteSliceItem, isStack);
  111.         SetMenuItem(StacksMenuH, NextSliceItem, isStack);
  112.         SetMenuItem(StacksMenuH, PreviousSliceItem, isStack);
  113.         SetMenuItem(StacksMenuH, MakeMovieItem, ShowItems);
  114.         SetMenuItem(StacksMenuH, CaptureFramesItem, ShowItems);
  115.         SetMenuItem(StacksMenuH, AnimateItem, isStack);
  116.         SetMenuItem(StacksMenuH, ProjectItem, isStack);
  117.         SetMenuItem(StacksMenuH, ResliceItem, isStack);
  118.         SetMenuItem(StacksMenuH, ResliceOptionsItem, isStack);
  119.     end;
  120.  
  121.  
  122.     function AboutFilter (d: DialogPtr; var event: EventRecord; var ItemHit: integer): boolean;
  123. { simple filter proc for about box -- must be at top level! % }
  124.     begin
  125.         if (event.what in [MouseDown, KeyDown, AutoKey]) then begin
  126.                 AboutFilter := true;
  127.                 ItemHit := OK;
  128.             end
  129.         else begin
  130.                 AboutFilter := false;
  131.                 ItemHit := 0;
  132.             end;
  133.     end;
  134.  
  135.  
  136.     procedure AboutUProc (d: DialogPtr; item: integer);
  137. { About box user proc -- must be at top level!}
  138.         var
  139.             s: str255;
  140.             saveport: grafptr;
  141.             VersInfo: str255;
  142.     begin
  143.         getport(saveport);
  144.         setport(d);
  145.         if (item = MemItem) then begin
  146.                 NumToString(FreeMem div 1024, s);
  147.                 s := concat(s, 'K free');
  148.                 DrawSItem(MemItem, Geneva, 9, d, s);
  149.             end
  150.         else if (item = VersItem) then begin
  151.                 RealToString(version / 100.0, 4, 2, VersInfo);
  152.                 VersInfo := concat('Version ', VersInfo);
  153.                 DrawSItem(VersItem, Geneva, 9, d, VersInfo);
  154.             end;
  155.         setport(saveport);
  156.     end;
  157.  
  158.  
  159.     procedure DoAbout;
  160.   {About Box by David Powell}
  161.         var
  162.             i: integer;
  163.             d: dialogptr;
  164.             midscreen: point;
  165.             r: rect;
  166.             h: handle;
  167.             itype: integer;
  168.     begin
  169.         d := getnewdialog(AboutID, nil, pointer(-1));
  170.         if (d <> nil) then begin
  171.                 SetPort(d);
  172.                 GetDItem(d, VersItem, itype, h, r);
  173.                 SetDItem(d, VersItem, itype, @AboutUProc, r);
  174.                 GetDItem(d, MemItem, itype, h, r);
  175.                 SetDItem(d, MemItem, itype, @AboutUProc, r);
  176.                 ShowWindow(d);
  177.                 repeat
  178.                     ModalDialog(@aboutfilter, i);
  179.                 until (i = OK);
  180.                 DisposDialog(d);
  181.                 FlushEvents(EveryEvent, 0);
  182.             end;
  183.     end;
  184.  
  185.  
  186.     procedure DoPreferences;
  187.         const
  188.             WidthID = 4;
  189.             HeightID = 6;
  190.             BufferSizeID = 7;
  191.             ScaleArithmeticID = 10;
  192.             InvertValuesID = 11;
  193.             InvertYID = 12;
  194.             LW6ID = 13;
  195.             ScaleConvolutionsID = 14;
  196.             SwitchingID = 15;
  197.         var
  198.             mylog: DialogPtr;
  199.             item, i: integer;
  200.             SaveScale, SaveLW6, SaveScaleC: boolean;
  201.             SaveInvertValues, SaveInvertY: boolean;
  202.             SaveWidth, SaveHeight: integer;
  203.             SaveBufferSize: LongInt;
  204.     begin
  205.         InitCursor;
  206.         SaveWidth := NewPicWidth;
  207.         SaveHeight := NewPicHeight;
  208.         SaveBufferSize := BufferSize;
  209.         SaveScale := ScaleArithmetic;
  210.         SaveInvertY := InvertYCoordinates;
  211.         SaveLW6 := DriverHalftoning;
  212.         SaveScaleC := ScaleConvolutions;
  213.         mylog := GetNewDialog(6000, nil, pointer(-1));
  214.         SetDNum(MyLog, WidthID, NewPicWidth);
  215.         SetDNum(MyLog, HeightID, NewPicHeight);
  216.         SetDNum(MyLog, BufferSizeID, BufferSize div 1024);
  217.         SetDialogItem(mylog, ScaleArithmeticID, ord(ScaleArithmetic));
  218.         SetDialogItem(mylog, ScaleConvolutionsID, ord(ScaleConvolutions));
  219.         SetDialogItem(mylog, InvertYID, ord(InvertYCoordinates));
  220.         SetDialogItem(mylog, LW6ID, ord(not DriverHalftoning));
  221.         SetDialogItem(mylog, SwitchingID, ord(SwitchLUTOnSuspend));
  222.         SaveInvertValues := InvertPixelValues;
  223.         if InvertPixelValues then
  224.             SetDialogItem(mylog, InvertValuesID, 1);
  225.         OutlineButton(MyLog, ok, 16);
  226.         repeat
  227.             ModalDialog(nil, item);
  228.             if item = WidthID then begin
  229.                     NewPicWidth := GetDNum(MyLog, WidthID);
  230.                     if (NewPicWidth < 0) or (NewPicWidth > MaxPicSize) then begin
  231.                             NewPicWidth := SaveWidth;
  232.                             SetDNum(MyLog, WidthID, NewPicWidth);
  233.                         end;
  234.                 end;
  235.             if item = HeightID then begin
  236.                     NewPicHeight := GetDNum(MyLog, HeightID);
  237.                     if (NewPicHeight < 0) or (NewPicHeight > MaxPicSize) then begin
  238.                             NewPicHeight := SaveHeight;
  239.                             SetDNum(MyLog, HeightID, NewPicHeight);
  240.                         end;
  241.                 end;
  242.             if item = BufferSizeID then begin
  243.                     BufferSize := GetDNum(MyLog, BufferSizeID) * 1024;
  244.                     if BufferSize < 1 then begin
  245.                             beep;
  246.                             BufferSize := 1;
  247.                             SetDNum(MyLog, BufferSizeID, BufferSize);
  248.                         end;
  249.                 end;
  250.             if item = ScaleArithmeticID then begin
  251.                     ScaleArithmetic := not ScaleArithmetic;
  252.                     SetDialogItem(mylog, ScaleArithmeticID, ord(ScaleArithmetic));
  253.                     if PasteControl <> nil then
  254.                         DrawPasteControl
  255.                 end;
  256.             if item = ScaleConvolutionsID then begin
  257.                     ScaleConvolutions := not ScaleConvolutions;
  258.                     SetDialogItem(mylog, ScaleConvolutionsID, ord(ScaleConvolutions));
  259.                 end;
  260.             if item = InvertValuesID then begin
  261.                     InvertPixelValues := not InvertPixelValues;
  262.                     SetDialogItem(mylog, InvertValuesID, ord(InvertPixelValues));
  263.                 end;
  264.             if item = InvertYID then begin
  265.                     InvertYCoordinates := not InvertYCoordinates;
  266.                     SetDialogItem(mylog, InvertYID, ord(InvertYCoordinates));
  267.                 end;
  268.             if item = LW6ID then begin
  269.                     DriverHalftoning := not DriverHalftoning;
  270.                     SetDialogItem(mylog, LW6ID, ord(not DriverHalftoning));
  271.                 end;
  272.             if item = SwitchingID then begin
  273.                     SwitchLUTOnSuspend := not SwitchLUTOnSuspend;
  274.                     SetDialogItem(mylog, SwitchingID, ord(SwitchLUTOnSuspend));
  275.                 end;
  276.         until (item = ok) or (item = cancel);
  277.         DisposDialog(mylog);
  278.         if NewPicWidth < 32 then
  279.             NewPicWidth := 32;
  280.         if odd(NewPicWidth) then
  281.             NewPicWidth := NewPicWidth + 1;
  282.         if NewPicHeight < 16 then
  283.             NewPicHeight := 16;
  284.         if item = cancel then begin
  285.                 NewPicWidth := SaveWidth;
  286.                 NewPicHeight := SaveHeight;
  287.                 BufferSize := SaveBufferSize;
  288.                 ScaleArithmetic := SaveScale;
  289.                 ScaleConvolutions := SaveScaleC;
  290.                 InvertYCoordinates := SaveInvertY;
  291.                 DriverHalftoning := SaveLW6;
  292.                 if PasteControl <> nil then
  293.                     DrawPasteControl
  294.             end
  295.         else
  296.             with info^ do begin
  297.                     if InvertPixelValues and (SaveInvertValues = false) then
  298.                         InvertgrayLevels
  299.                     else if (InvertPixelValues = false) and SaveInvertValues then begin
  300.                             DensityCalibrated := false;
  301.                             DrawLabels('', '', '');
  302.                         end;
  303.                     UpdateTitleBar;
  304.                 end;
  305.         if BufferSize <> SaveBufferSIze then
  306.             PutMessage('You must "Record Preferences" and restart before the Undo and Clipboard buffer size change will take effect.');
  307.     end;
  308.  
  309.  
  310.     procedure UpdateWindowsMenu;
  311.         var
  312.             i, kind: integer;
  313.             fwptr: WindowPtr;
  314.     begin
  315.         for i := NextWindowItem to TileWindowsItem do
  316.             SetMenuItem(WindowsMenuH, i, nPics > 1);
  317.         for i := SelectToolsItem to SelectResultsItem do
  318.             CheckItem(WindowsMenuH, i, false);
  319.         SetMenuItem(WindowsMenuH, SelectHistogramItem, HistoWindow <> nil);
  320.         SetMenuItem(WindowsMenuH, SelectPlotItem, PlotWindow <> nil);
  321.         SetMenuItem(WindowsMenuH, SelectResultsItem, ResultsWindow <> nil);
  322.         for i := 1 to nPics do
  323.             CheckItem(WindowsMenuH, WindowsMenuItems + i, false);
  324.         fwptr := FrontWindow;
  325.         kind := WindowPeek(fwptr)^.WindowKind;
  326.         if PasteControl = nil then
  327.             SetItem(WindowsMenuH, PasteControlItem, 'Show Paste Control')
  328.         else
  329.             SetItem(WindowsMenuH, PasteControlItem, 'Hide Paste Control');
  330.         if kind < 0 then
  331.             exit(UpdateWindowsMenu); {System Window}
  332.         case kind of
  333.             ToolKind: 
  334.                 CheckItem(WindowsMenuH, SelectToolsItem, true);
  335.             MapKind: 
  336.                 CheckItem(WindowsMenuH, SelectGrayMapItem, true);
  337.             LUTKind: 
  338.                 CheckItem(WindowsMenuH, SelectLutItem, true);
  339.             ValuesKind: 
  340.                 CheckItem(WindowsMenuH, SelectValuesItem, true);
  341.             HistoKind: 
  342.                 CheckItem(WindowsMenuH, SelectHistogramItem, true);
  343.             ProfilePlotKind, CalibrationPLotKind: 
  344.                 CheckItem(WindowsMenuH, SelectPlotItem, true);
  345.             ResultsKind: 
  346.                 CheckItem(WindowsMenuH, SelectResultsItem, true);
  347.             PicKind: 
  348.                 CheckItem(WindowsMenuH, WindowsMenuItems + info^.PicNum, true);
  349.             otherwise
  350.         end;
  351.     end;
  352.  
  353.  
  354.  
  355.  
  356.     procedure CloseAll;
  357.     FORWARD;
  358.  
  359.  
  360.     procedure DoMenuEvent (MenuChoice: LongInt);
  361.         var
  362.             MenuID, MenuItem, i, ignore: integer;
  363.             name, str: str255;
  364.             dna, RefNum: integer;
  365.             ItemName: str255;
  366.             FontName: str255;
  367.             ok, isSelection: boolean;
  368.             NewStyle: StyleItem;
  369.             t: FateTable;  {Only needed for MakeSkeleton}
  370.     begin
  371.         MenuID := HiWord(MenuChoice);
  372.         MenuItem := LoWord(MenuChoice);
  373.         case MenuID of
  374.  
  375.             AppleMenu:  begin
  376.                     if MenuItem = 1 then
  377.                         DoAbout
  378.                     else begin
  379.                             GetItem(GetMHandle(AppleMenu), MenuItem, name);
  380.                             ignore := OpenDeskAcc(name)
  381.                         end;
  382.                 end;
  383.  
  384.             FileMenu:  begin
  385.                     StopDigitizing;
  386.                     isInsertionPoint := false;
  387.                     case MenuItem of
  388.                         NewItem: 
  389.                             if (LongInt(NewPicWidth) * NewPicHeight) <= UndoBufSize then
  390.                                 ok := NewPicWindow('Untitled', NewPicWidth, NewPicHeight)
  391.                             else
  392.                                 PutMessage('Sorry, but new windows can''t be larger than the Undo buffer.');
  393.                         OpenItem: 
  394.                             ok := DoOpen('', 0);
  395.                         ImportItem: 
  396.                             ok := ImportFile('', 0);
  397.                         CloseItem: 
  398.                             if OptionKeyWasDown then
  399.                                 CloseAll
  400.                             else
  401.                                 DoClose;
  402.      {-}
  403.                         SaveItem: 
  404.                             if OptionKeyWasDown and (info^.StackInfo = nil) then
  405.                                 SaveAll
  406.                             else
  407.                                 SaveFile;
  408.                         SaveAsItem: 
  409.                             if FrontWindow = ResultsWindow then
  410.                                 Export('', 0)
  411.                             else
  412.                                 SaveAs('', 0);
  413.                         ExportItem: 
  414.                             Export('', 0);
  415.                         SaveScreenItem: 
  416.                             SaveScreen;
  417.                         RecordPreferencesItem: 
  418.                             SaveSettings;
  419.        {-}
  420.                         RevertItem: 
  421.                             RevertToSaved;
  422.                         DuplicateItem: 
  423.                             ok := Duplicate('', false);
  424.                         GetInfoItem: 
  425.                             GetInfo;
  426.        {-}
  427.                         SetHalftoneItem: 
  428.                             SetHalftone;
  429.                         PageSetupItem: 
  430.                             DoPageSetup;
  431.                         PrintItem: 
  432.                             Print(true);
  433.        {-}
  434.                         QuitItem: 
  435.                             finished := true;
  436.                     end;
  437.                 end;
  438.  
  439.             EditMenu:  begin
  440.                     StopDigitizing;
  441.                     GetItem(GetMHandle(EditMenu), MenuItem, ItemName);
  442.                     if not SystemEdit(MenuItem - 1) then
  443.                         case MenuItem of
  444.                             UndoItem: 
  445.                                 DoUndo;
  446.              {-}
  447.                             CutItem: 
  448.                                 DoCut;
  449.                             CopyItem: 
  450.                                 DoCopy;
  451.                             PasteItem: 
  452.                                 DoPaste;
  453.                             ClearItem: 
  454.                                 DoClear;
  455.             {-}
  456.                             FillItem, InvertItem, DrawBoundaryItem: 
  457.                                 SetupOperation(MenuItem);
  458.                             DrawScaleItem: 
  459.                                 DrawScale;
  460.              {-}
  461.                             SelectAllItem: 
  462.                                 with info^ do
  463.                                     if RoiShowing and EqualRect(RoiRect, PicRect) then
  464.                                         KillRoi
  465.                                     else
  466.                                         SelectAll(true);
  467.                             ScaleAndRotateItem: 
  468.                                 ScaleAndRotate;
  469.               {-}
  470.                             RotateLeftItem: 
  471.                                 Rotate(RotateLeft);
  472.                             RotateRightItem: 
  473.                                 Rotate(RotateRight);
  474.                             FlipVerticalItem: 
  475.                                 FlipOrRotate(FlipVertical);
  476.                             FlipHorizontalItem: 
  477.                                 FlipOrRotate(FlipHorizontal);
  478.               {-}
  479.                             UnzoomItem: 
  480.                                 Unzoom;
  481.                             ShowClipboardItem: 
  482.                                 ShowClipboard;
  483.                         end;
  484.                 end;
  485.  
  486.             OptionsMenu:  begin
  487.                     case MenuItem of
  488.                         InvertPaletteItem:  begin
  489.                                 SetupLutUndo;
  490.                                 InvertPalette;
  491.                                 UpdateLUT;
  492.                             end;
  493.                         SetNumberItem: 
  494.                             SetNumberOfColors;
  495.                         SetExtraColorsItem: 
  496.                             SetNumberOfExtraColors;
  497.                         GrayscaleItem: 
  498.                             ResetGrayMap;
  499.            {-}
  500.                         PreferencesItem: 
  501.                             DoPreferences;
  502.                         PlotOptionsItem: 
  503.                             DoProfilePlotOptions;
  504.                         ScaleToFitItem: 
  505.                             ScaleToFit;
  506.                         ThresholdItem:  begin
  507.                                 if DensitySlicing then
  508.                                     DisableDensitySlice;
  509.                                 if Thresholding then begin
  510.                                         if WhatToUndo = UndoLut then begin
  511.                                                 UndoLutChange;
  512.                                                 DrawMap
  513.                                             end
  514.                                         else
  515.                                             ResetGrayMap
  516.                                     end
  517.                                 else begin
  518.                                         SetupLutUndo;
  519.                                         EnableThresholding(128);
  520.                                     end;
  521.                             end;
  522.                         SliceItem: 
  523.                             if DensitySlicing then
  524.                                 DisableDensitySlice
  525.                             else begin
  526.                                     if thresholding then
  527.                                         ResetGrayMap;
  528.                                     EnableDensitySlice;
  529.                                 end;
  530.                     end;
  531.                 end;
  532.  
  533.             ColorTablesMenu: 
  534.                 SwitchColorTables(MenuItem, true);
  535.  
  536.             FontMenu:  begin
  537.                     GetItem(FontMenuH, MenuItem, FontName);
  538.                     GetFNum(FontName, CurrentFontID);
  539.                     DisplayText(true);
  540.                 end;
  541.  
  542.             SizeMenu:  begin
  543.                     case MenuItem of
  544.                         1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12: 
  545.                             CurrentSize := GetFontSize(MenuItem);
  546.                     end;
  547.                     DisplayText(true);
  548.                     if IsInsertionPoint then
  549.                         UpdatePicWindow;
  550.                 end;
  551.  
  552.             StyleMenu:  begin
  553.                     case MenuItem of
  554.                         1: 
  555.                             CurrentStyle := [];
  556.                         2, 3, 4, 5, 6:  begin
  557.                                 case MenuItem of
  558.                                     TxBold: 
  559.                                         NewStyle := Bold;
  560.                                     TxItalic: 
  561.                                         NewStyle := Italic;
  562.                                     TxUnderLine: 
  563.                                         NewStyle := Underline;
  564.                                     TxOutLine: 
  565.                                         NewStyle := Outline;
  566.                                     TxShadow: 
  567.                                         NewStyle := Shadow;
  568.                                 end;
  569.                                 if NewStyle in CurrentStyle then
  570.                                     CurrentStyle := CurrentStyle - [NewStyle]
  571.                                 else
  572.                                     CurrentStyle := CurrentStyle + [NewStyle];
  573.                             end;
  574.                         LeftItem: 
  575.                             TextJust := teJustLeft;
  576.                         CenterItem: 
  577.                             TextJust := teJustCenter;
  578.                         RightItem: 
  579.                             TextJust := teJustRight;
  580.                         NoBackgroundItem: 
  581.                             TextBack := NoBack;
  582.                         WithBackgroundItem: 
  583.                             TextBack := WithBack;
  584.                     end; {case}
  585.                     DisplayText(true);
  586.                 end;
  587.  
  588.             PropagateMenu: 
  589.                 DoPropagate(MenuItem);
  590.  
  591.             EnhanceMenu:  begin
  592.                     StopDigitizing;
  593.                     SetupUndo;
  594.                     case MenuItem of
  595.                         SmoothItem: 
  596.                             if OptionKeyDown then
  597.                                 Filter(UnweightedAvg, 0, t)
  598.                             else
  599.                                 Filter(WeightedAvg, 0, t);
  600.                         SharpenItem: 
  601.                             Filter(fsharpen, 0, t);
  602.                         ShadowItem: 
  603.                             Filter(fshadow, 0, t);
  604.                         EdgeDetectItem: 
  605.                             Filter(EdgeDetect, 0, t);
  606.                         ReduceNoiseItem: 
  607.                             Filter(ReduceNoise, 0, t);
  608.                         DitherItem: 
  609.                             Filter(Dither, 0, t);
  610.                         ConvolveItem: 
  611.                             Convolve('', 0);
  612.            {-}
  613.                         ApplyItem: 
  614.                             ApplyLookupTable;
  615.                         EnhanceItem: 
  616.                             EnhanceContrast;
  617.                         EqualizeItem: 
  618.                             EqualizeHistogram;
  619.                         ChangeItem: 
  620.                             ChangeValues(ForegroundIndex, ForegroundIndex, BackgroundIndex);
  621.                     end;
  622.                 end;
  623.  
  624.             BinaryMenu: 
  625.                 case MenuItem of
  626.                     MakeBinaryItem: 
  627.                         MakeBinary;
  628.                     ErosionItem: 
  629.                         DoErosion;
  630.                     DilationItem: 
  631.                         DoDilation;
  632.                     OpeningItem: 
  633.                         DoOpening;
  634.                     ClosingItem: 
  635.                         DoClosing;
  636.                     SetCountItem: 
  637.                         SetBinaryCount;
  638.                     IterationsItem: 
  639.                         SetIterations;
  640.                     OutlineItem: 
  641.                         filter(OutlineFilter, 0, t);
  642.                     SkeletonizeItem: 
  643.                         MakeSkeleton;
  644.                 end;
  645.  
  646.             ArithmeticMenu: 
  647.                 DoArithmetic(MenuItem, 0);
  648.  
  649.             BackgroundMenu: 
  650.                 DoBackgroundMenuEvent(MenuItem);
  651.  
  652.             AnalyzeMenu:  begin
  653.                     SetupUndo;
  654.                     case MenuItem of
  655.                         MeasureItem: 
  656.                             Measure;
  657.                         AnalyzeItem: 
  658.                             AnalyzeParticles;
  659.                         ShowItem: 
  660.                             ShowResults;
  661.                         OptionsItem: 
  662.                             DoMeasurementOptions;
  663.                         HistogramItem: 
  664.                             DoHistogram;
  665.                         PlotItem: 
  666.                             PlotDensityProfile;
  667.                         PlotSurfaceItem: 
  668.                             PlotSurface;
  669.            {-}
  670.                         SetScaleItem: 
  671.                             SetScale;
  672.                         CalibrateItem: 
  673.                             Calibrate;
  674.                         RedoItem: 
  675.                             RedoMeasurement;
  676.                         DeleteItem: 
  677.                             DeleteMeasurement;
  678.                         ResetItem: 
  679.                             ResetCounter;
  680.                         RestoreItem:  begin
  681.                                 StopDigitizing;
  682.                                 RestoreRoi;
  683.                             end;
  684.                         MarkItem: 
  685.                             MarkSelection(mCount);
  686.                     end;
  687.                 end;
  688.  
  689.             SpecialMenu:  begin
  690.                     case MenuItem of
  691.                         StartItem: 
  692.                             StartDigitizing;
  693.                         AverageItem: 
  694.                             AverageFrames;
  695.                         SaveBlankFieldItem: 
  696.                             SaveBlankField;
  697.                         VideoOptionsItem: 
  698.                             DoVideoOptions;
  699.                         PhotoModeItem: 
  700.                             PhotoMode;
  701.                         LoadMacrosItem: 
  702.                             if OpenTextFile(name, RefNum) then
  703.                                 LoadMacros(name, RefNum);
  704.                         otherwise
  705.                             if MenuItem >= FirstMacroItem then
  706.                                 RunMacro(MenuItem - FirstMacroItem + 1);
  707.                     end;
  708.                 end;
  709.  
  710.             StacksMenu:  begin
  711.                     StopDigitizing;
  712.                     case MenuItem of
  713.                         StackFromWindowsItem: 
  714.                             MakeStack;
  715.                         WindowsFromStackItem: 
  716.                             MakeWindowsFromStack;
  717.                         AddSliceItem: 
  718.                             ok := AddSlice(true);
  719.                         DeleteSliceItem: 
  720.                             DeleteSlice;
  721.                         NextSliceItem, PreviousSliceItem: 
  722.                             ShowNextSlice(MenuItem);
  723.                         MakeMovieItem: 
  724.                             MakeMovie;
  725.                         CaptureFramesItem: 
  726.                             CaptureFrames;
  727.                         AnimateItem: 
  728.                             Animate;
  729.                         ProjectItem: 
  730.                             Project;
  731.                         ResliceItem: 
  732.                             Reslice;
  733.                         ResliceOptionsItem: 
  734.                             DoResliceOptions;
  735.                         otherwise
  736.                             beep
  737.                     end;
  738.                 end;
  739.  
  740.             SortPaletteMenu: 
  741.                 SortPalette(MenuItem);
  742.  
  743.             WindowsMenu:  begin
  744.                     if MenuItem <> PasteControlItem then
  745.                         StopDigitizing;
  746.                     case MenuItem of
  747.                         NextWindowItem: 
  748.                             ShowNextWindow;
  749.                         StackWindowsItem: 
  750.                             StackWindows;
  751.                         TileWindowsItem: 
  752.                             TileWindows;
  753.                         PasteControlItem: 
  754.                             if PasteControl = nil then
  755.                                 ShowPasteControl
  756.                             else
  757.                                 ignore := CloseAWindow(PasteControl);
  758.             {-}
  759.                         SelectToolsItem: 
  760.                             SelectWindow(ToolWindow);
  761.                         SelectGrayMapItem: 
  762.                             SelectWindow(MapWindow);
  763.                         SelectLutItem: 
  764.                             SelectWindow(LUTWindow);
  765.                         SelectValuesItem: 
  766.                             SelectWindow(ValuesWindow);
  767.                         SelectHistogramItem: 
  768.                             if HistoWindow <> nil then
  769.                                 SelectWindow(HistoWindow);
  770.                         SelectPlotItem: 
  771.                             if PlotWindow <> nil then
  772.                                 SelectWindow(PlotWindow);
  773.                         SelectResultsItem: 
  774.                             if ResultsWindow <> nil then
  775.                                 SelectWindow(ResultsWindow);
  776.           {-}
  777.                         otherwise
  778.                             SelectWindow(PicWindow[MenuItem - WindowsMenuItems]);
  779.                     end;
  780.                 end;
  781.  
  782.             UserMenu: 
  783.                 DoUserMenuEvent(MenuItem);
  784.             otherwise
  785.         end;
  786.         HiliteMenu(0);
  787.         RoiUpdateTime := 0;
  788.     end;
  789.  
  790.  
  791.     procedure DoFreehand (imag: integer);
  792.         var
  793.             finish: point;
  794.             event: EventRecord;
  795.             wright, wbottom, ff: integer;
  796.             b: boolean;
  797.     begin
  798.         SetPort(info^.wptr);
  799.         ff := imag div 2;
  800.         if ff < 0 then
  801.             ff := 0;
  802.         PenPat(pat[PatIndex]);
  803.         with info^.wptr^.PortRect do begin
  804.                 wright := right;
  805.                 wbottom := bottom;
  806.             end;
  807.         while Button do begin
  808.                 GetMouse(finish);
  809.                 with finish do begin
  810.                         if h < 0 then
  811.                             h := 0;
  812.                         if v < 0 then
  813.                             v := 0;
  814.                         if h > wright then
  815.                             h := wright;
  816.                         if v > wbottom then
  817.                             v := wbottom;
  818.                         if (xCoordinates^[nCoordinates] <> h) or (yCoordinates^[nCoordinates] <> v) then begin
  819.                                 if nCoordinates < MaxCoordinates then
  820.                                     nCoordinates := nCoordinates + 1
  821.                                 else
  822.                                     beep;
  823.                                 LineTo(h - ff, v - ff);
  824.                                 xCoordinates^[nCoordinates] := h;
  825.                                 yCoordinates^[nCoordinates] := v;
  826.                                 wait(1);
  827.                             end; {if mouse has moved}
  828.                     end; {with}
  829.             end; {while Button}
  830.     end;
  831.  
  832.  
  833.     procedure DoPolygon (imag: integer; start: point);
  834.         var
  835.             Finish, OldFinish: point;
  836.             finished, DoubleClick, done: boolean;
  837.             ticks, MouseUpTime, LastMouseUpTime: LongInt;
  838.             wright, wbottom, ff: integer;
  839.             StartRect: rect;
  840.             MouseDown, MouseUpEvent: boolean;
  841.     begin
  842.         ff := imag div 2;
  843.         DrawLabels('DX:', 'DY:', 'Length:');
  844.         SetPort(info^.wptr);
  845.         PenMode(PatXor);
  846.         if CurrentTool = PolygonTool then begin
  847.                 PenSize(1, 1);
  848.                 Pt2Rect(Start, Start, StartRect);
  849.                 InsetRect(StartRect, -4 * (ff + 1), -4 * (ff + 1));
  850.                 FrameRect(StartRect);
  851.                 PenSize(imag, imag);
  852.             end
  853.         else
  854.             SetRect(StartRect, 0, 0, 0, 0);
  855.         finish := start;
  856.         finished := false;
  857.         with info^.wptr^.PortRect do begin
  858.                 wright := right;
  859.                 wbottom := bottom;
  860.             end;
  861.         MouseUpTime := 0;
  862.         done := false;
  863.         MouseUpEvent := false;
  864.         MouseDown := button;
  865.         repeat
  866.             ShowDxDy(0, 0);
  867.             repeat
  868.                 OldFinish := finish;
  869.                 GetMouse(finish);
  870.                 with finish do begin
  871.                         if h < 0 then begin
  872.                                 h := 0;
  873.                                 done := CurrentTool = LineTool;
  874.                             end;
  875.                         if v < 0 then begin
  876.                                 v := 0;
  877.                                 done := CurrentTool = LineTool;
  878.                             end;
  879.                         if h > wright then begin
  880.                                 h := wright;
  881.                                 done := CurrentTool = LineTool;
  882.                             end;
  883.                         if v > wbottom then begin
  884.                                 v := wbottom;
  885.                                 done := CurrentTool = LineTool;
  886.                             end;
  887.                     end;
  888.                 if not EqualPt(finish, OldFinish) then begin
  889.                         ticks := TickCount;
  890.                         repeat
  891.                         until TickCount <> ticks;
  892.                         MoveTo(start.h - ff, start.v - ff);
  893.                         LineTo(OldFinish.h - ff, OldFinish.v - ff);
  894.                         MoveTo(start.h - ff, start.v - ff);
  895.                         LineTo(finish.h - ff, finish.v - ff);
  896.                         ShowDxDy(abs(finish.h - start.h), abs(finish.v - start.v));
  897.                     end;
  898.                 if button <> MouseDown then begin
  899.                         MouseUpEvent := not button;
  900.                         MouseDown := button;
  901.                     end;
  902.             until MouseUpEvent;
  903.             MouseUpEvent := false;
  904.             LastMouseUpTime := MouseUpTime;
  905.             MouseUpTime := TickCount;
  906.             DoubleClick := ((MouseUpTime - LastMouseUpTime) < GetDblTime) and EqualPt(start, finish);
  907.             if nCoordinates < MaxCoordinates then
  908.                 nCoordinates := nCoordinates + 1
  909.             else
  910.                 beep;
  911.             xCoordinates^[nCoordinates] := finish.h;
  912.             yCoordinates^[nCoordinates] := finish.v;
  913.             start := finish;
  914.             Finished := (PtInRect(finish, StartRect) or DoubleClick or done) and (nCoordinates > 2);
  915.         until finished;
  916.         FlushEvents(EveryEvent, 0);
  917.     end;
  918.  
  919.  
  920.     procedure MakePolygon (event: EventRecord);
  921.         var
  922.             Start: point;
  923.             i, ff, imag: integer;
  924.     begin
  925.         with info^ do begin
  926.                 start := event.where;
  927.                 SetPort(wptr);
  928.                 imag := round(0.75 * magnification);
  929.                 if imag < 1 then
  930.                     imag := 1;
  931.                 ff := imag div 2;
  932.                 PenNormal;
  933.                 PenSize(imag, imag);
  934.                 xCoordinates^[1] := Start.h;
  935.                 yCoordinates^[1] := Start.v;
  936.                 nCoordinates := 1;
  937.                 MoveTo(start.h, start.v);
  938.                 case CurrentTool of
  939.                     FreehandTool:  begin
  940.                             DoFreehand(imag);
  941.                             with Start do
  942.                                 LineTo(h - ff, v - ff);
  943.                         end;
  944.                     PolygonTool: 
  945.                         DoPolygon(imag, start);
  946.                 end;
  947.                 if nCoordinates > 2 then
  948.                     with SrcRect do begin
  949.                             if (magnification <> 1.0) or (left <> 0) or (top <> 0) then
  950.                                 for i := 1 to nCoordinates do {Convert from screen to offscreen corridinates}
  951.                                     begin
  952.                                         xCoordinates^[i] := left + trunc(xCoordinates^[i] / magnification);
  953.                                         yCoordinates^[i] := top + trunc(yCoordinates^[i] / magnification);
  954.                                     end;
  955.                             MakeOutline
  956.                         end
  957.                 else begin
  958.                         KillRoi;
  959.                         UpdatePicWindow;
  960.                     end;
  961.             end; {with}
  962.     end;
  963.  
  964.  
  965.     procedure MakeLineRoi (event: EventRecord);
  966.         var
  967.             Start, pt, spt: point;
  968.             i, ff, imag: integer;
  969.             SaveInfo: InfoPtr;
  970.     begin
  971.         start := event.where;
  972.         with Info^ do begin
  973.                 if PixMapSize > UndoBufSize then begin
  974.                         beep;
  975.                         exit(MakeLineRoi);
  976.                     end;
  977.                 WhatToUndo := NothingToUndo;
  978.                 measuring := false;
  979.                 if LOIType = Straight then begin
  980.                         DoObject(LineObj, event);
  981.                         RoiType := LineRoi;
  982.                         MakeRegion;
  983.                         RoiShowing := true;
  984.                         SetupUndo;
  985.                         exit(MakeLineRoi);
  986.                     end;
  987.                 SetPort(wptr);
  988.                 imag := trunc(magnification + 0.5) * LineWidth;
  989.                 PenNormal;
  990.                 PenSize(imag, imag);
  991.                 MoveTo(start.h, start.v);
  992.                 xCoordinates^[1] := Start.h;
  993.                 yCoordinates^[1] := Start.v;
  994.                 nCoordinates := 1;
  995.             end; {with info}
  996.         if LOIType = Freehand then
  997.             DoFreehand(imag)
  998.         else
  999.             DoPolygon(imag, start);
  1000.         if nCoordinates > 1 then begin
  1001.                 SetupUndoInfoRec;
  1002.                 SaveInfo := Info;
  1003.                 Info := UndoInfo;
  1004.                 with info^ do begin
  1005.                         magnification := SaveInfo^.magnification;
  1006.                         SrcRect := SaveInfo^.SrcRect;
  1007.                         BinaryPic := true;
  1008.                         SetPort(GrafPtr(osPort));
  1009.                     end;
  1010.                 pmForeColor(BlackIndex);
  1011.                 pmBackColor(WhiteIndex);
  1012.                 PenNormal;
  1013.                 PenSize(LineWidth, LineWidth);
  1014.                 EraseRect(info^.PicRect);
  1015.                 ff := LineWidth div 2;
  1016.                 if ff < 0 then
  1017.                     ff := 0;
  1018.                 spt.h := xCoordinates^[1];
  1019.                 spt.v := yCoordinates^[1];
  1020.                 ScreenToOffscreen(spt);
  1021.                 MoveTo(spt.h - ff, spt.v - ff);
  1022.                 for i := 2 to nCoordinates do begin
  1023.                         pt.h := xCoordinates^[i];
  1024.                         pt.v := yCoordinates^[i];
  1025.                         ScreenToOffscreen(pt);
  1026.                         LineTo(pt.h - ff, pt.v - ff);
  1027.                     end;
  1028.                 start.h := start.h - 1;
  1029.                 MakingLOI := true;
  1030.                 AutoOutline(start);
  1031.                 MakingLOI := false;
  1032.                 info^.RoiShowing := false;
  1033.                 Info := SaveInfo;
  1034.                 with info^ do begin
  1035.                         CopyRgn(UndoInfo^.roiRgn, roiRgn);
  1036.                         RoiRect := UndoInfo^.RoiRect;
  1037.                         SetEmptyRgn(UndoInfo^.roiRgn);
  1038.                         RoiShowing := true;
  1039.                         SetupUndo;
  1040.                         case LOIType of
  1041.                             Freehand: 
  1042.                                 roiType := FreeLineRoi;
  1043.                             Segmented: 
  1044.                                 roiType := SegLineRoi;
  1045.                         end;
  1046.                         ComputeLength(false);
  1047.                         with RoiRect do begin
  1048.                                 LX1 := spt.h - left;
  1049.                                 LY1 := spt.v - top;
  1050.                                 LX2 := pt.h - left;
  1051.                                 LY2 := pt.v - top;
  1052.                             end;
  1053.                     end;
  1054.             end
  1055.         else
  1056.             with info^ do begin
  1057.                     RoiShowing := false;
  1058.                     RoiType := NoRoi;
  1059.                     UpdatePicWindow;
  1060.                 end;
  1061.     end;
  1062.  
  1063.  
  1064.     procedure DoMouseDownInWindow (event: EventRecord; WhichWindow: WindowPtr);
  1065.   {Handles mouse down events in the content region of image windows.}
  1066.         var
  1067.             r: rect;
  1068.             str: str255;
  1069.             hloc, vloc: integer;
  1070.             tool: ToolType;
  1071.     begin
  1072.         if (WindowPeek(WhichWindow)^.WindowKind <> PicKind) then
  1073.             exit(DoMouseDownInWindow);
  1074.         SetPort(info^.wptr);
  1075.         if Digitizing then
  1076.             if (CurrentTool <> MagnifyingGlass) and (CurrentTool <> Grabber) then
  1077.                 StopDigitizing;
  1078.         GlobalToLocal(event.where);
  1079.         IsInsertionPoint := false;
  1080.         with info^ do
  1081.             if RoiShowing then
  1082.                 if EqualRect(RoiRect, PicRect) and (SelectionMode = NewSelection) then {if Select All}
  1083.                     if not (OpPending and (CurrentOp = PasteOp)) then begin
  1084.                             KillRoi;
  1085.                             MouseState := NotInRoi;
  1086.                             exit(DoMouseDownInWindow);
  1087.                         end;
  1088.         if MouseState <> NotInRoi then
  1089.             exit(DoMouseDownInWindow);
  1090.         if (SelectionMode = NewSelection) and not ((CurrentTool = MagnifyingGlass) or (CurrentTool = Grabber)) then
  1091.             KillRoi;
  1092.         SetupUndo;
  1093.         if SpaceBarDown and (CurrentTool <> TextTool) then
  1094.             tool := grabber
  1095.         else
  1096.             tool := CurrentTool;
  1097.         case tool of
  1098.             SelectionTool: 
  1099.                 DoObject(SelectionRect, event);
  1100.             PolygonTool, FreehandTool: 
  1101.                 MakePolygon(event);
  1102.             OvalSelectionTool: 
  1103.                 DoObject(SelectionOval, event);
  1104.             LineTool: 
  1105.                 MakeLineRoi(event);
  1106.             MagnifyingGlass: 
  1107.                 ZoomIn(event);
  1108.             Grabber: 
  1109.                 Scroll(event);
  1110.             Pencil, Brush, Eraser: 
  1111.                 DoBrush(event);
  1112.             AirBrushTool: 
  1113.                 DoAirBrush;
  1114.             ruler: 
  1115.                 if OptionKeyDown or ControlKeyDown then
  1116.                     PutMessage('Use the line selection tool and Measure to measure path lengths.')
  1117.                 else begin
  1118.                         DoObject(LineObj, event);
  1119.                         WhatToUndo := UndoEdit;
  1120.                     end;
  1121.             PaintBucket: 
  1122.                 DoFill(event);
  1123.             TextTool: 
  1124.                 DoText(event.where);
  1125.             PlotTool: 
  1126.                 DoObject(PlotLine, event);
  1127.             PickerTool: 
  1128.                 if BitAnd(Event.modifiers, OptionKey) = OptionKey then
  1129.                     GetBackgroundColor(event)
  1130.                 else
  1131.                     GetForegroundColor(event);
  1132.             CrossHairTool: 
  1133.                 DoPoints(event);
  1134.             AngleTool: 
  1135.                 FindAngle(event);
  1136.             Wand:  begin
  1137.                     if Digitizing then
  1138.                         StopDigitizing;
  1139.                     AutoOutline(event.where);
  1140.                 end;
  1141.             otherwise
  1142.                 beep;
  1143.         end;
  1144.     end;
  1145.  
  1146.  
  1147.     procedure DoPopupMenusInTools;
  1148.         var
  1149.             MenuItem: integer;
  1150.             ticks, PopUpResult: LongInt;
  1151.             MenuLoc: point;
  1152.  
  1153.         procedure DrawCurrentTool;
  1154.         begin
  1155.             InvalRect(ToolRect[CurrentTool]);
  1156.             BeginUpdate(ToolWindow);
  1157.             DrawTools;
  1158.             EndUpdate(ToolWindow);
  1159.         end;
  1160.  
  1161.     begin
  1162.         DrawCurrentTool;
  1163.         ticks := TickCount;
  1164.         repeat
  1165.         until (not button) or (TickCount > ticks + 20);
  1166.         if button and (TickCount > (ticks + 20)) then
  1167.             with ToolRect[CurrentTool], MenuLoc do begin
  1168.                     MenuLoc.h := left;
  1169.                     MenuLoc.v := top;
  1170.                     LocalToGlobal(MenuLoc);
  1171.                     PopUpResult := PopupMenuSelect(LineToolMenuH, v, h, ord(LOIType) + 1);
  1172.                     MenuItem := LoWord(PopUpResult);
  1173.                     case MenuItem of
  1174.                         1:  begin
  1175.                                 LOIType := Straight;
  1176.                                 ToolChar[LineTool] := chr(StraightChar);
  1177.                             end;
  1178.                         2:  begin
  1179.                                 LOIType := Freehand;
  1180.                                 ToolChar[LineTool] := chr(FreehandChar);
  1181.                             end;
  1182.                         3:  begin
  1183.                                 LOIType := Segmented;
  1184.                                 ToolChar[LineTool] := chr(SegmentedChar);
  1185.                             end;
  1186.                     end; {case}
  1187.                     DrawCurrentTool;
  1188.                 end;
  1189.     end;
  1190.  
  1191.  
  1192.     procedure DoMouseDownInTools (loc: point);
  1193.  {Handles mouse down events in the tool palette.}
  1194.         var
  1195.             r: rect;
  1196.             OddTool, DoubleClick: boolean;
  1197.             ToolNum, i: integer;
  1198.     begin
  1199.         SetPort(ToolWindow);
  1200.         GlobalToLocal(loc);
  1201.         if loc.v <= StartOfLines then begin
  1202.                 PreviousTool := CurrentTool;
  1203.                 OddTool := loc.h < tmiddle;
  1204.                 ToolNum := (loc.v div tmiddle) * 2;
  1205.                 if not OddTool then
  1206.                     ToolNum := ToolNum + 1;
  1207.                 CurrentTool := ToolType(ToolNum);
  1208.                 isSelectionTool := (CurrentTool = SelectionTool) or (CurrentTool = OvalSelectionTool) or (CurrentTool = PolygonTool) or (CurrentTool = FreehandTool) or (CurrentTool = LineTool);
  1209.                 DoubleClick := (TickCount - ToolTime) < GetDblTime;
  1210.                 ToolTime := TickCount;
  1211.                 InvalRect(ToolRect[CurrentTool]);
  1212.                 InvalRect(ToolRect[PreviousTool]);
  1213.                 IsInsertionPoint := false;
  1214.                 if DoubleClick and (CurrentTool = PreviousTool) then
  1215.                     case CurrentTool of
  1216.                         MagnifyingGlass: 
  1217.                             Unzoom;
  1218.                         SelectionTool:  begin
  1219.                                 StopDigitizing;
  1220.                                 SelectAll(true);
  1221.                             end;
  1222.                         AirbrushTool: 
  1223.                             SetAirbrushSize;
  1224.                         Brush: 
  1225.                             SetBrushSize;
  1226.                         LineTool: 
  1227.                             SetScale;
  1228.                         PolygonTool: 
  1229.                             DoMeasurementOptions;
  1230.                         FreehandTool: 
  1231.                             Calibrate;
  1232.                         PlotTool: 
  1233.                             DoProfilePlotOptions;
  1234.                         Eraser: 
  1235.                             if info <> NoInfo then begin
  1236.                                     KillRoi;
  1237.                                     SetupUndo;
  1238.                                     WhatToUndo := UndoClear;
  1239.                                     StopDigitizing;
  1240.                                     SelectAll(false);
  1241.                                     DoOperation(eraseOp);
  1242.                                 end;
  1243.                         LutTool, Wand: 
  1244.                             if DensitySlicing then
  1245.                                 DisableDensitySlice
  1246.                             else begin
  1247.                                     if Thresholding then {Turn of Gray Map thresholding}
  1248.                                         ResetGrayMap;
  1249.                                     EnableDensitySlice;
  1250.                                 end;
  1251.                         PickerTool: 
  1252.                             if info^.LutMode <> PseudoColor then begin  {Switch to pseudocolor mode}
  1253.                                     DisableDensitySlice;
  1254.                                     UpdateLUT;
  1255.                                     CurrentTool := LutTool;
  1256.                                     isSelectionTool := false;
  1257.                                     InvalRect(ToolRect[CurrentTool]);
  1258.                                 end
  1259.                             else
  1260.                                 ResetGrayMap;
  1261.                         otherwise
  1262.                     end; {case}
  1263.                 if (not isSelectionTool) and (CurrentTool <> MagnifyingGlass) and (CurrentTool <> Grabber) and (CurrentTool <> Wand) then
  1264.                     KillRoi;
  1265.                 if not DoubleClick and (CurrentTool = LineTool) then
  1266.                     KillRoi;
  1267.                 with info^ do
  1268.                     if RoiShowing then
  1269.                         if EqualRect(RoiRect, PicRect) and not isSelectionTool then {if Select All}
  1270.                             KillRoi;
  1271.                 if (CurrentTool = SelectionTool) or (CurrentTool = CrossHairTool) then begin
  1272.                         ValuesMessage := '';
  1273.                         if mCount > 0 then
  1274.                             ShowValues;
  1275.                     end;
  1276.                 RoiMode := MoveMode;
  1277.                 if CurrentTool = LineTool then begin
  1278.                         if Button then
  1279.                             DoPopUpMenusInTools;
  1280.                         if (LoiType = Straight) and (LineWidth <> 1) then begin
  1281.                                 LineWidth := 1;
  1282.                                 UpdateRoiLineWidth;
  1283.                                 ShowLineWidth;
  1284.                             end;
  1285.                     end;
  1286.             end
  1287.         else begin
  1288.                 for i := 1 to nLineTypes do begin
  1289.                         r := lines[i];
  1290.                         with r do begin
  1291.                                 left := left - 13;
  1292.                                 top := top - 2;
  1293.                                 right := right + 2;
  1294.                                 bottom := bottom + 2;
  1295.                             end;
  1296.                         if i = 1 then
  1297.                             with r do
  1298.                                 top := top - 7;
  1299.                         if PtInRect(loc, r) then begin
  1300.                                 with lines[i] do
  1301.                                     LineWidth := bottom - top;
  1302.                                 LineIndex := i;
  1303.                             end;
  1304.                     end;
  1305.                 EraseRect(CheckRect);
  1306.                 InvalRect(CheckRect);
  1307.                 UpdateRoiLineWidth;
  1308.             end;
  1309.     end;
  1310.  
  1311.  
  1312.     procedure ScaleToFitScreen;
  1313.         var
  1314.             trect: rect;
  1315.             ignore: boolean;
  1316.     begin
  1317.         with info^ do begin
  1318.                 MoveWindow(wptr, PicLeftBase, PicTopBase, true);
  1319.                 SetRect(trect, 0, 0, ScreenWidth, ScreenHeight);
  1320.                 ScaleImageWindow(trect);
  1321.                 wrect := trect;
  1322.                 SizeWindow(wptr, trect.right, trect.bottom, true);
  1323.             end;
  1324.     end;
  1325.  
  1326.  
  1327.     procedure DoDrag (WhichWindow: WindowPtr; loc: point);
  1328.         var
  1329.             WinRect, DragBounds, trect: rect;
  1330.             kind: integer;
  1331.     begin
  1332.         kind := WindowPeek(WhichWindow)^.WindowKind;
  1333.         if kind = PicKind then begin
  1334.                 if info^.PictureType = ScionType then
  1335.                     exit(DoDrag);
  1336.                 with info^ do begin  {Save window location}
  1337.                         GetWindowRect(wptr, trect);
  1338.                         savehloc := trect.left;
  1339.                         savevloc := trect.top;
  1340.                     end;
  1341.                 PicLeft := PicLeftBase;
  1342.                 PicTop := PicTopBase;
  1343.             end;
  1344.         DragBounds := ScreenBits.bounds;
  1345.         DragWindow(WhichWindow, loc, DragBounds);
  1346.         if (info^.PictureType = QuickCaptureType) or OptionKeyDown then begin
  1347.                 GetWindowRect(WhichWindow, trect);
  1348.                 MoveWindow(WhichWindow, band(trect.left, $fffc), trect.top, true);
  1349.             end;
  1350.         if WhichWindow = ValuesWindow then
  1351.             ShowValues;
  1352.     end;
  1353.  
  1354.  
  1355.     procedure UpdateMenus;
  1356.     begin
  1357.         OptionKeyWasDown := OptionKeyDown;
  1358.         UpdateFileMenu;
  1359.         UpdateEditMenu;
  1360.         UpdateOptionsMenu;
  1361.         UpdateTextItems;
  1362.         UpdateEnhanceMenu;
  1363.         UpdateAnalysisMenu;
  1364.         UpdateSpecialMenu;
  1365.         UpdateStacksMenu;
  1366.         UpdateWindowsMenu;
  1367.     end;
  1368.  
  1369.  
  1370.     procedure DoMouseDown (event: EventRecord);
  1371.         var
  1372.             WhichWindow: WindowPtr;
  1373.             ThePart, ignore: integer;
  1374.             trect: rect;
  1375.     begin
  1376.         ThePart := FindWindow(event.where, WhichWindow);
  1377.         case ThePart of
  1378.             InDesk: 
  1379.                 ;
  1380.             InMenuBar:  begin
  1381.                     UpdateMenus;
  1382.                     DoMenuEvent(MenuSelect(event.where));
  1383.                 end;
  1384.             InSysWindow: 
  1385.                 SystemClick(Event, WhichWindow);
  1386.             InContent:  begin
  1387.                     RoiUpdateTime := 0;
  1388.                     if WhichWindow = ToolWindow then begin
  1389.                             DoMouseDownInTools(event.where);
  1390.                             exit(DoMouseDown);
  1391.                         end;
  1392.                     if WhichWindow = MapWindow then begin
  1393.                             DoMouseDownInMap;
  1394.                             exit(DoMouseDown)
  1395.                         end;
  1396.                     if WhichWindow = LUTWindow then begin
  1397.                             DoMouseDownInLUT(event);
  1398.                             exit(DoMouseDown)
  1399.                         end;
  1400.                     if WhichWindow = PasteControl then begin
  1401.                             DoMouseDownInPasteControl(event.where);
  1402.                             exit(DoMouseDown)
  1403.                         end;
  1404.                     if WhichWindow = ResultsWindow then begin
  1405.                             DoMouseDownInResults(event.where);
  1406.                             exit(DoMouseDown)
  1407.                         end;
  1408.                     if WhichWindow <> FrontWindow then
  1409.                         SelectWindow(WhichWindow)
  1410.                     else
  1411.                         DoMouseDownInWindow(Event, WhichWindow);
  1412.                 end;
  1413.             InDrag: 
  1414.                 DoDrag(WhichWindow, event.where);
  1415.             InGrow: 
  1416.                 DoGrow(WhichWindow, event);
  1417.             InGoAway: 
  1418.                 if TrackGoAway(WhichWindow, event.where) then
  1419.                     if OptionKeyDown and (WindowPeek(WhichWindow)^.WindowKind = PicKind) then
  1420.                         CloseAll
  1421.                     else begin
  1422.                             StopDigitizing;
  1423.                             ignore := CloseAWindow(WhichWindow);
  1424.                         end;
  1425.             InZoomIn, InZoomOut: 
  1426.                 with info^ do
  1427.                     case WindowState of
  1428.                         NormalWindow:  begin
  1429.                                 if digitizing then
  1430.                                     exit(DoMouseDown);
  1431.                                 ScaleToFit;
  1432.                                 if ScaleToFitWindow then
  1433.                                     ScaleToFitScreen;
  1434.                             end;
  1435.                         TiledSmall, TiledSmallScaled:  begin
  1436.                                 if WindowState = TiledSmall then begin
  1437.                                         ScaleToFitWindow := true;
  1438.                                         WindowState := TiledBig;
  1439.                                     end
  1440.                                 else
  1441.                                     WindowState := TiledBigScaled;
  1442.                                 savewrect := wrect;
  1443.                                 SaveSrcRect := SrcRect;
  1444.                                 SaveMagnification := magnification;
  1445.                                 GetWindowRect(wptr, trect);
  1446.                                 savehloc := trect.left;
  1447.                                 savevloc := trect.top;
  1448.                                 ScaleToFitScreen;
  1449.                                 UpdatePicWindow;
  1450.                             end;
  1451.                         TiledBig:  begin
  1452.                                 ScaleToFitWindow := false;
  1453.                                 WindowState := TiledSmall;
  1454.                                 wrect := savewrect;
  1455.                                 SrcRect := SaveSrcRect;
  1456.                                 magnification := SaveMagnification;
  1457.                                 HideWindow(wptr);
  1458.                                 SizeWindow(wptr, wrect.right, wrect.bottom, true);
  1459.                                 MoveWindow(wptr, savehloc, savevloc, true);
  1460.                                 ShowWindow(wptr);
  1461.                                 UpdatePicWindow;
  1462.                                 magnification := 1.0;
  1463.                                 UpdateTitleBar;
  1464.                             end;
  1465.                         TiledBigScaled:  begin
  1466.                                 WindowState := TiledSmallScaled;
  1467.                                 wrect := savewrect;
  1468.                                 SrcRect := PicRect;
  1469.                                 HideWindow(wptr);
  1470.                                 SizeWindow(wptr, wrect.right, wrect.bottom, true);
  1471.                                 MoveWindow(wptr, savehloc, savevloc, true);
  1472.                                 ShowWindow(wptr);
  1473.                                 UpdatePicWindow;
  1474.                                 if PicRect.right <> 0 then
  1475.                                     magnification := wrect.right / PicRect.right;
  1476.                                 UpdateTitleBar;
  1477.                             end;
  1478.                     end; {case WindowState}
  1479.         end; {case thePart}
  1480.     end;
  1481.  
  1482.  
  1483.     procedure NudgeRoi (key: integer);
  1484.         var
  1485.             dh, dv: integer;
  1486.     begin
  1487.         with info^ do begin
  1488.                 if not RoiShowing then
  1489.                     exit(NudgeRoi);
  1490.                 case key of
  1491.                     LeftArrow:  begin
  1492.                             dh := -1;
  1493.                             dv := 0
  1494.                         end;
  1495.                     RightArrow:  begin
  1496.                             dh := 1;
  1497.                             dv := 0
  1498.                         end;
  1499.                     UpArrow:  begin
  1500.                             dh := 0;
  1501.                             dv := -1
  1502.                         end;
  1503.                     DownArrow:  begin
  1504.                             dh := 0;
  1505.                             dv := 1
  1506.                         end;
  1507.                 end;
  1508.                 if OptionKeyDown then begin
  1509.                         if RoiType = RectRoi then
  1510.                             with RoiRect do begin
  1511.                                     right := right + dh;
  1512.                                     if right < left + 2 then
  1513.                                         right := left + 2;
  1514.                                     bottom := bottom + dv;
  1515.                                     if bottom < top + 2 then
  1516.                                         bottom := top + 2;
  1517.                                     MakeRegion;
  1518.                                 end
  1519.                         else
  1520.                             beep;
  1521.                     end
  1522.                 else begin
  1523.                         OffsetRgn(roiRgn, dh, dv);
  1524.                         RoiRect := roiRgn^^.rgnBBox;
  1525.                     end;
  1526.                 RoiNudged := true;
  1527.                 RoiUpdateTime := 0;
  1528.             end;
  1529.     end;
  1530.  
  1531.  
  1532.     procedure DoKeyDown (event: EventRecord);
  1533.         var
  1534.             Ch: char;
  1535.             ich, KeyCode: integer;
  1536.     begin
  1537.         Ch := chr(band(Event.message, CharCodeMask));
  1538.         ich := ord(ch);
  1539. {ShowMessage(long2str(ich));}
  1540.         KeyCode := bsr(band(Event.message, KeyCodeMask), 8);
  1541.         if BitAnd(Event.modifiers, CmdKey) = CmdKey then begin
  1542.                 UpdateMenus;
  1543.                 if OptionKeyWasDown then begin
  1544.                         case KeyCode of
  1545.                             1: 
  1546.                                 ch := 'S';
  1547.                             5: 
  1548.                                 ch := 'G';
  1549.                             8: 
  1550.                                 ch := 'C';
  1551.                             13: 
  1552.                                 ch := 'W';
  1553.                             17: 
  1554.                                 ch := 'T';
  1555.                             24: 
  1556.                                 ch := '=';
  1557.                             35: 
  1558.                                 ch := 'P';
  1559.                         end;
  1560.                     end;
  1561.                 DoMenuEvent(MenuKey(Ch));
  1562.                 exit(DoKeyDown)
  1563.             end;
  1564.         with info^ do
  1565.             if (CurrentTool = TextTool) and IsInsertionPoint and (ord(ch) <> FunctionKey) then
  1566.                 DrawCharacter(ch)
  1567.             else if ch = BackSpace then
  1568.                 DoClear
  1569.             else if RoiShowing and (ich >= LeftArrow) and (ich <= DownArrow) then
  1570.                 NudgeRoi(ich)
  1571.             else if (StackInfo <> nil) and (ch in ['<', ',', chr(PageUp), '>', '.', chr(PageDown), chr(HomeKey), chr(EndKey)]) then begin
  1572.                     if ch in ['<', ',', chr(PageUp)] then
  1573.                         ShowNextSlice(PreviousSliceItem)
  1574.                     else if ch in ['>', '.', chr(PageDown)] then
  1575.                         ShowNextSlice(NextSliceItem)
  1576.                     else if (ich = HomeKey) or (ich = EndKey) then
  1577.                         ShowFirstOrLastSlice(ich);
  1578.                 end
  1579.             else if nMacros > 0 then
  1580.                 RunKeyMacro(ch, KeyCode);
  1581.     end;
  1582.  
  1583.  
  1584.     procedure DoActivate (event: EventRecord);
  1585.         var
  1586.             WhichWindow: WindowPtr;
  1587.             Activating, SwitchingWindows, isOK: boolean;
  1588.             I, kind: integer;
  1589.             NewInfo: InfoPtr;
  1590.     begin
  1591.         WhichWindow := WindowPtr(event.message);
  1592.         kind := WindowPeek(WhichWindow)^.WindowKind;
  1593.         Activating := odd(event.modifiers);
  1594.         case kind of
  1595.             PicKind:  begin
  1596.                     if Activating then begin
  1597.                             NewInfo := pointer(WindowPeek(WhichWindow)^.RefCon);
  1598.                             SwitchingWindows := NewInfo <> Info;
  1599.                             if SwitchingWindows then begin
  1600.                                     StopDigitizing;
  1601.                                     SaveRoi;
  1602.                                     DisableDensitySlice;
  1603.                                 end;
  1604.                             Info := NewInfo;
  1605.                             if SwitchingWindows then
  1606.                                 ActivateWindow;
  1607.                             Measuring := false;
  1608.                             with info^ do begin
  1609.                                     if (LutMode = GrayScale) or (LutMode = CustomGrayscale) then
  1610.                                         DrawMap;
  1611.                                     LoadLUT(cTable);
  1612.                                     if digitizing and HighlightSaturatedPixels then
  1613.                                         HighlightPixels;
  1614.                                     GenerateValues;
  1615.                                     if not DensityCalibrated then
  1616.                                         DrawLabels('', '', '');
  1617.                                 end; {with}
  1618.                         end
  1619.                     else
  1620.                         KillOperation; {Deactivate}
  1621.                 end;
  1622.             ResultsKind: 
  1623.                 UpdateResultsWindow;
  1624.             otherwise
  1625.         end; {case}
  1626.         if not activating then begin
  1627.                 WhichWindow := FrontWindow;
  1628.                 kind := WindowPeek(WhichWindow)^.WindowKind;
  1629.                 if kind < 0 then
  1630.                     ConvertClipboard; {DA has become active}
  1631.             end;
  1632.     end;
  1633.  
  1634.  
  1635.     procedure DoUpdate (event: EventRecord);
  1636.         var
  1637.             WhichWindow: WindowPtr;
  1638.             SaveInfo: InfoPtr;
  1639.             kind: integer;
  1640.     begin
  1641.         WhichWindow := WindowPtr(event.message);
  1642.         kind := WindowPeek(WhichWindow)^.WindowKind;
  1643.         BeginUpdate(WhichWindow);
  1644.         case kind of
  1645.             Pickind:  begin
  1646.                     SaveInfo := info;
  1647.                     Info := pointer(WindowPeek(WhichWindow)^.RefCon);
  1648.                     if not digitizing then begin
  1649.                             UpdatePicWindow;
  1650.                             DrawMyGrowIcon(info^.wptr);
  1651.                         end;
  1652.                     info := SaveInfo;
  1653.                 end;
  1654.             ToolKind: 
  1655.                 DrawTools;
  1656.             MapKind: 
  1657.                 DrawMap;
  1658.             LUTKind: 
  1659.                 DrawLUT;
  1660.             ValuesKind:  begin
  1661.                     DrawLabels('', '', '');
  1662.                     if (mCount > 0) or (ValuesMessage <> '') then
  1663.                         ShowValues;
  1664.                 end;
  1665.             HistoKind: 
  1666.                 DrawHistogram;
  1667.             ProfilePlotKind, CalibrationPlotKind: 
  1668.                 UpdatePlotWindow;
  1669.             ResultsKind: 
  1670.                 UpdateResultsWindow;
  1671.             PasteControlKind: 
  1672.                 DrawPasteControl;
  1673.         end;
  1674.         EndUpdate(WhichWindow);
  1675.     end;
  1676.  
  1677.  
  1678.     procedure DoDiskInsert (event: EventRecord);
  1679. { Process disk insertion event, check for damaged or uninitialized disks. }
  1680.         var
  1681.             p: point;
  1682.             intjunk: integer;
  1683.     begin
  1684.         if (HiWord(event.message) <> NoErr) then begin
  1685.                 DiLoad;
  1686.                 SetPt(p, 100, 80);
  1687.                 intjunk := DiBadMount(p, event.message);
  1688.                 DiUnload;
  1689.             end;
  1690.     end;
  1691.  
  1692.  
  1693.     function HandleEvents: boolean;
  1694.         const
  1695.             mousemovedmessage = $FA;
  1696.             SuspendResumeMessage = 1;
  1697.             ResumeMask = 1;
  1698.         var
  1699.             Event: EventRecord;
  1700.             result: boolean;
  1701.             theDialog: DialogPtr;
  1702.             ItemHit: integer;
  1703.             SleepTicks: LongInt;
  1704.             okay: boolean;
  1705.     begin
  1706.         if Digitizing then
  1707.             SleepTicks := 0
  1708.         else
  1709.             SleepTicks := 2;
  1710.         if WaitNextEvent(EveryEvent, Event, SleepTicks, nil) then begin
  1711.                 case Event.what of
  1712.                     KeyDown, AutoKey: 
  1713.                         DoKeyDown(Event);
  1714.                     MouseDown: 
  1715.                         DoMouseDown(Event);
  1716.                     ActivateEvt: 
  1717.                         DoActivate(Event);
  1718.                     DiskEvt: 
  1719.                         DoDiskInsert(Event);
  1720.                     UpdateEvt: 
  1721.                         DoUpdate(Event);
  1722.                     app4Evt: 
  1723.                         case BSR(event.message, 24) of
  1724.                             MouseMovedMessage: 
  1725.                                 ;
  1726.                             SuspendResumeMessage: 
  1727.                                 if BAND(event.message, ResumeMask) <> 0 then begin{Resume event}
  1728.                                         if SwitchLUTOnSuspend and (WhatToUndo = UndoLUT) then begin
  1729.                                                 UndoLUTChange;
  1730.                                                 WhatToUndo := NothingToUndo;
  1731.                                             end
  1732.                                         else
  1733.                                             LoadLUT(info^.ctable);
  1734.                                     end
  1735.                                 else begin {Suspend event}
  1736.                                         KillOperation;
  1737.                                         ConvertClipboard;
  1738.                                         if SwitchLUTOnSuspend then begin
  1739.                                                 SetupLUTUndo;
  1740.                                                 okay := LoadCLUTResource(AppleDefaultCLUT);
  1741.                                             end;
  1742.                                     end;
  1743.                         end;
  1744.                     otherwise {Do nothing}
  1745.                 end; {case}
  1746.                 HandleEvents := true
  1747.             end
  1748.         else
  1749.             HandleEvents := false;
  1750.     end;
  1751.  
  1752.  
  1753.     procedure ShowInsertionPoint;
  1754.         var
  1755.             tRect: rect;
  1756.             Loc: point;
  1757.             height, imag: integer;
  1758.     begin
  1759.         if (not isInsertionPoint) or (info = NoInfo) then
  1760.             exit(ShowInsertionPoint);
  1761.         if (TickCount mod (BlinkTime * 2)) < BlinkTime then
  1762.             exit(ShowInsertionPoint);
  1763.         if info = NoInfo then
  1764.             exit(ShowInsertionPoint);
  1765.         Loc := InsertionPoint;
  1766.         OffscreenToScreen(loc);
  1767.         with info^, tRect do begin
  1768.                 SetPort(wptr);
  1769.                 imag := trunc(magnification + 0.5);
  1770.                 height := CurrentSize * imag;
  1771.                 height := height - height div 4;
  1772.                 left := loc.h;
  1773.                 bottom := loc.v - imag + 1;
  1774.                 top := bottom - height;
  1775.                 right := left + 1;
  1776.                 PenNormal;
  1777.                 PenSize(imag, imag);
  1778.                 PenMode(PatXor);
  1779.                 FrameRect(tRect);
  1780.                 ticks := TickCount + 3;
  1781.                 repeat
  1782.                 until TickCount > ticks;
  1783.                 FrameRect(tRect);
  1784.             end;
  1785.     end;
  1786.  
  1787.  
  1788.     procedure UndoRoi;
  1789.         var
  1790.             SrcPtr, DstPtr: ptr;
  1791.             offset, ByteCount, tTop, tBottom: LongInt;
  1792.             tRect: rect;
  1793.     begin
  1794.         with info^ do begin
  1795.                 if PixMapSize <> CurrentUndoSize then
  1796.                     exit(UndoRoi);
  1797.                 tRect := RoiRect;
  1798.                 if RoiType = LineRoi then
  1799.                     InsetRect(tRect, -RoiHandleSize, -RoiHandleSize);
  1800.                 with tRect do begin
  1801.                         tTop := top;
  1802.                         tBottom := bottom;
  1803.                         if tTop < 0 then
  1804.                             tTop := 0;
  1805.                         if tTop > PicRect.bottom then
  1806.                             tTop := PicRect.bottom;
  1807.                         if tBottom < 0 then
  1808.                             tBottom := 0;
  1809.                         if tBottom > PicRect.bottom then
  1810.                             tBottom := PicRect.bottom;
  1811.                     end;
  1812.                 offset := tTop * BytesPerRow;
  1813.                 if offset < 0 then
  1814.                     offset := 0;
  1815.                 SrcPtr := ptr(ord4(UndoBuf) + offset);
  1816.                 DstPtr := ptr(ord4(PicBaseAddr) + offset);
  1817.                 ByteCount := (tBottom - tTop) * BytesPerRow;
  1818.                 BlockMove(SrcPtr, DstPtr, ByteCount);
  1819.             end;
  1820.     end;
  1821.  
  1822.  
  1823.     procedure GetLineHandles (var LeftHandle, MiddleHandle, RightHandle: rect);
  1824.         var
  1825.             offset1, offset2, xcenter, ycenter, x1, y1, x2, y2: integer;
  1826.             rx1, ry1, rx2, ry2: real;
  1827.     begin
  1828.         offset1 := RoiHandleSize div 2;
  1829.         offset2 := offset1 + 1;
  1830.         GetLoi(rx1, ry1, rx2, ry2);
  1831.         x1 := trunc(rx1);
  1832.         y1 := trunc(ry1);
  1833.         x2 := trunc(rx2);
  1834.         y2 := trunc(ry2);
  1835.         SetRect(LeftHandle, x1 - offset1, y1 - offset1, x1 + offset2, y1 + offset2);
  1836.         with info^.RoiRect do begin
  1837.                 xcenter := left + (right - left) div 2;
  1838.                 ycenter := top + (bottom - top) div 2;
  1839.             end;
  1840.         SetRect(MiddleHandle, xcenter - offset1, ycenter - offset1, xcenter + offset2, ycenter + offset2);
  1841.         SetRect(RightHandle, x2 - offset1, y2 - offset1, x2 + offset2, y2 + offset2);
  1842.     end;
  1843.  
  1844.  
  1845.     procedure DrawROI;
  1846.         var
  1847.             tRect: rect;
  1848.             RoiHandle, LeftHandle, MiddleHandle, RightHandle: rect;
  1849.             psize: integer;
  1850.             StartTicks: LongInt;
  1851.     begin
  1852.         with Info^ do begin
  1853.                 StartTicks := TickCount;
  1854.                 if OpPending then
  1855.                     DoOperation(CurrentOp);
  1856.                 SetPort(GrafPtr(Info^.osPort));
  1857.                 PenNormal;
  1858.                 if ScaleToFitWindow then
  1859.                     if (magnification < 1.0) and (magnification <> 0.0) then begin
  1860.                             psize := round(1.0 / magnification + 1.5);
  1861.                             PenSize(psize, psize);
  1862.                         end;
  1863.                 if not ((MouseState = DownInRoi) and OpPending) then
  1864.                     if PixMapSize <= UndoBufSize then begin
  1865.                             pmForeColor(BlackIndex);
  1866.                             pmBackColor(WhiteIndex);
  1867.                             case RoiType of
  1868.                                 RectRoi: 
  1869.                                     with RoiRect do begin
  1870.                                             SetRect(RoiHandle, right - RoiHandleSize, bottom - RoiHandleSize, right, bottom);
  1871.                                             if ((right - left) > RoiHandleSize) and ((bottom - top) > RoiHandleSize) then
  1872.                                                 PaintRect(RoiHandle);
  1873.                                         end;
  1874.                                 LineRoi: 
  1875.                                     if Magnification <= 2.0 then begin
  1876.                                             GetLineHandles(LeftHandle, MiddleHandle, RightHandle);
  1877.                                             PaintRect(LeftHandle);
  1878.                                             if LineWidth < 4 then
  1879.                                                 PaintRect(MiddleHandle);
  1880.                                             PaintRect(RightHandle);
  1881.                                             pmForeColor(WhiteIndex);
  1882.                                             FrameRect(LeftHandle);
  1883.                                             if LineWidth < 4 then
  1884.                                                 FrameRect(MiddleHandle);
  1885.                                             FrameRect(RightHandle);
  1886.                                             pmForeColor(BlackIndex);
  1887.                                         end;
  1888.                                 otherwise
  1889.                             end;
  1890.                             PatIndex := (PatIndex + 1) mod 8;
  1891.                             PenPat(pat[PatIndex]);
  1892.                             FrameRgn(roiRgn);
  1893.                             pmForeColor(ForegroundIndex);
  1894.                             pmBackColor(BackgroundIndex);
  1895.                         end;
  1896.                 if PixMapSize > UndoBufSize then begin
  1897.                         if magnification < 1.0 then
  1898.                             PenSize(2, 2);
  1899.                         PatIndex := (PatIndex + 1) mod 8;
  1900.                         PenPat(pat[PatIndex]);
  1901.                         PenMode(PatXor);
  1902.                         FrameRgn(roiRgn);
  1903.                         if MouseState = DownInRoi then begin
  1904.                                 UnionRect(RoiRect, OldRoiRect, tRect);
  1905.                                 UpdateScreen(tRect);
  1906.                             end
  1907.                         else
  1908.                             UpdateScreen(RoiRect);
  1909.                         FrameRgn(roiRgn);
  1910.                     end
  1911.                 else begin
  1912.                         tRect := RoiRect;
  1913.                         if MouseState = DownInRoi then
  1914.                             UnionRect(RoiRect, OldRoiRect, tRect)
  1915.                         else if RoiNudged then begin
  1916.                                 tRect := RoiRect;
  1917.                                 RoiNudged := false;
  1918.                             end;
  1919.                         if RoiType = LineRoi then
  1920.                             InsetRect(tRect, -RoiHandleSize * 2, -RoiHandleSize * 2)
  1921.                         else
  1922.                             InsetRect(tRect, -2, -2);
  1923.                         UpdateScreen(tRect);
  1924.                         UndoRoi;  {Erase offscreen ROI}
  1925.                     end;
  1926.                 RoiUpdateTime := TickCount - StartTicks;
  1927.             end; {with}
  1928.     end;
  1929.  
  1930.  
  1931.     procedure MoveLineEndPoint (osloc: point);
  1932.         var
  1933.             deltax, deltay: real;
  1934.     begin
  1935.         with info^, osloc, info^.RoiRect do begin
  1936.                 if h < 0 then
  1937.                     h := 0;
  1938.                 if h > PicRect.right then
  1939.                     h := PicRect.right;
  1940.                 if v < 0 then
  1941.                     v := 0;
  1942.                 if v > PicRect.bottom then
  1943.                     v := PicRect.bottom;
  1944.                 if RoiMode = LeftEndMode then begin
  1945.                         LX1 := h;
  1946.                         LY1 := v;
  1947.                         LX2 := left + LX2;
  1948.                         LY2 := top + LY2;
  1949.                     end
  1950.                 else begin
  1951.                         LX2 := h;
  1952.                         LY2 := v;
  1953.                         LX1 := left + LX1;
  1954.                         LY1 := top + LY1;
  1955.                     end;
  1956.                 if ShiftKeyDown then begin
  1957.                         deltax := LX2 - LX1;
  1958.                         deltay := LY2 - LY1;
  1959.                         if abs(deltax) > abs(deltay) then begin
  1960.                                 if RoiMode = LeftEndMode then
  1961.                                     LY2 := LY1
  1962.                                 else
  1963.                                     LY1 := LY2
  1964.                             end
  1965.                         else begin
  1966.                                 if RoiMode = LeftEndMode then
  1967.                                     LX2 := LX1
  1968.                                 else
  1969.                                     LX1 := LX2
  1970.                             end;
  1971.                     end; {if ShiftKeyDown}
  1972.                 MakeRegion;
  1973.                 osMouseDownLoc := osloc;
  1974.                 RoiUpdateTime := 0;
  1975.                 Show3Values(h, v, MyGetPixel(h, v));
  1976.             end;
  1977.     end;
  1978.  
  1979.  
  1980.     procedure MoveRoi (osloc: point);
  1981.         var
  1982.             dh, dv: integer;
  1983.     begin
  1984.         with info^, info^.RoiRect, osloc do begin
  1985.                 dh := h - osMouseDownLoc.h;
  1986.                 dv := v - osMouseDownLoc.v;
  1987.                 OldRoiRect := RoiRect;
  1988.                 if RoiType = LineRoi then
  1989.                     if (RoiMode = LeftEndMode) or (RoiMode = RightEndMode) then begin
  1990.                             MoveLineEndPoint(osloc);
  1991.                             exit(MoveRoi);
  1992.                         end;
  1993.                 if RoiMode = MoveMode then begin
  1994.                         if RoiMovementState = Constrained then begin
  1995.                                 if dv <> 0 then
  1996.                                     RoiMovementState := ConstrainedV
  1997.                                 else if dh <> 0 then
  1998.                                     RoiMovementState := ConstrainedH
  1999.                             end;
  2000.                         if RoiMovementState = ConstrainedH then
  2001.                             dv := 0
  2002.                         else if RoiMovementState = ConstrainedV then
  2003.                             dh := 0;
  2004.                         if not OpPending then begin
  2005.                                 if left + dh < 0 then
  2006.                                     dh := -left;
  2007.                                 if top + dv < 0 then
  2008.                                     dv := -top;
  2009.                             end;
  2010.                     end;
  2011.                 if not OpPending then begin
  2012.                         if right + dh > PicRect.right then
  2013.                             dh := PicRect.right - right;
  2014.                         if bottom + dv > PicRect.bottom then
  2015.                             dv := PicRect.bottom - bottom;
  2016.                     end;
  2017.                 if RoiMode = StretchMode then begin
  2018.                         measuring := false;
  2019.                         DrawLabels('Width:', 'Height:', '');
  2020.                         if h > left then begin
  2021.                                 right := right + dh;
  2022.                                 if right < (left + 1) then
  2023.                                     right := left + 1;
  2024.                                 if (right - h) > 5 then
  2025.                                     right := h + 2;
  2026.                             end
  2027.                         else
  2028.                             right := left + 1;
  2029.                         if v > top then begin
  2030.                                 bottom := bottom + dv;
  2031.                                 if bottom < (top + 1) then
  2032.                                     bottom := top + 1;
  2033.                                 if (bottom - v) > 5 then
  2034.                                     bottom := v + 2;
  2035.                             end
  2036.                         else
  2037.                             bottom := top + 1;
  2038.                         Show3Values(right - left, bottom - top, -1);
  2039.                         MakeRegion;
  2040.                     end
  2041.                 else begin
  2042.                         OffsetRgn(roiRgn, dh, dv);
  2043.                         Show3Values(left, top, MyGetPixel(left, top));
  2044.                     end;
  2045.                 RoiRect := roiRgn^^.rgnBBox;
  2046.                 osMouseDownLoc := osloc;
  2047.                 RoiUpdateTime := 0; {Forces ROI outline to be redrawn}
  2048.             end; {with Info}
  2049.     end;
  2050.  
  2051.  
  2052.     procedure ShowHistogramValues (GrayLevel: LongInt);
  2053.         var
  2054.             hstart, vstart, ivalue: integer;
  2055.     begin
  2056.         hstart := ValuesHStart;
  2057.         vstart := ValuesVStart;
  2058.         SetPort(ValuesWindow);
  2059.         TextSize(9);
  2060.         TextFont(Monaco);
  2061.         TextMode(SrcCopy);
  2062.         MoveTo(xValueLoc, vstart);
  2063.         with info^ do
  2064.             if DensityCalibrated then begin
  2065.                     if InvertingCalibrationFunction then
  2066.                         DrawReal(cvalue[255 - GrayLevel], 8, 2)
  2067.                     else
  2068.                         DrawReal(cvalue[GrayLevel], 8, 2);
  2069.                     DrawString(' (');
  2070.                     DrawLong(GrayLevel);
  2071.                     DrawString(' )');
  2072.                 end
  2073.             else
  2074.                 DrawLong(GrayLevel);
  2075.         DrawString('          ');
  2076.         MoveTo(yValueLoc, vstart + 10);
  2077.         if InvertingCalibrationFunction then
  2078.             DrawLong(histogram[255 - GrayLevel])
  2079.         else
  2080.             DrawLong(histogram[GrayLevel]);
  2081.         DrawString('          ');
  2082.     end;
  2083.  
  2084.  
  2085.     procedure SelectCursor;
  2086.         var
  2087.             loc, osloc, gloc: point;
  2088.             where, kind, i, color, x, y, margin: integer;
  2089.             WhichWindow: WindowPtr;
  2090.             MouseInRoi: boolean;
  2091.             fwptr: WindowPtr;
  2092.             CalValue, xscale: extended;
  2093.             RoiStretchHandle, LeftHandle, MiddleHandle, RightHandle: rect;
  2094.             MovingRoi: boolean;
  2095.             xvalue, pvalue: integer;
  2096.     begin
  2097.         if PasteControl <> nil then begin
  2098.                 fwptr := FrontWindow;
  2099.                 if WindowPeek(fwptr)^.WindowKind <> PasteControlKind then
  2100.                     BringToFront(PasteControl);
  2101.             end;
  2102.         SetPort(ScreenPort);
  2103.         GetMouse(gloc);
  2104.         loc := gloc;
  2105.         where := FindWindow(gloc, WhichWindow);
  2106.         if WhichWindow = nil then begin
  2107.                 InitCursor;
  2108.                 exit(SelectCursor)
  2109.             end;
  2110.         kind := WindowPeek(WhichWindow)^.WindowKind;
  2111.         if kind < 0 then
  2112.             exit(SelectCursor); {System Window}
  2113.         if where <> InContent then begin
  2114.                 InitCursor;
  2115.                 exit(SelectCursor)
  2116.             end;
  2117.         case kind of
  2118.             PicKind:  begin
  2119.                     if Info = NoInfo then begin
  2120.                             InitCursor;
  2121.                             exit(SelectCursor)
  2122.                         end;
  2123.                     SetPort(info^.wptr);
  2124.                     GlobalToLocal(loc);
  2125.                     osloc := loc;
  2126.                     ScreenToOffscreen(osloc);
  2127.                     MovingRoi := false;
  2128.                     with info^ do begin
  2129.                             SelectionMode := NewSelection;
  2130.                             if RoiShowing and ((isSelectionTool) or (CurrentTool = Wand)) and (currentTool <> LineTool) then begin
  2131.                                     if OptionKeyDown then
  2132.                                         SelectionMode := SubSelection
  2133.                                     else if ControlKeyDown or (ShiftKeyDown and (CurrentTool <> OvalSelectionTool) and (CurrentTool <> SelectionTool)) then
  2134.                                         SelectionMode := AddSelection;
  2135.                                 end;
  2136.                             if RoiShowing and (SelectionMode = NewSelection) then begin
  2137.                                     MouseInRoi := PtInRgn(osloc, roiRgn);
  2138.                                     if RoiType = LineRoi then begin
  2139.                                             GetLineHandles(LeftHandle, MiddleHandle, RightHandle);
  2140.                                             if magnification <= 2.0 then begin
  2141.                                                     InsetRect(LeftHandle, -2, -2);
  2142.                                                     InsetRect(MiddleHandle, -2, -2);
  2143.                                                     InsetRect(RightHandle, -2, -2);
  2144.                                                 end;
  2145.                                             MouseInRoi := MouseInRoi or PtInRect(osloc, LeftHandle) or MouseInRoi or PtInRect(osloc, MiddleHandle) or MouseInRoi or PtInRect(osloc, RightHandle);
  2146.                                         end;
  2147.                                 end
  2148.                             else
  2149.                                 MouseInRoi := false
  2150.                         end; {with}
  2151.                     if MouseInRoi or (MouseState = DownInRoi) then begin
  2152.                             if MouseState = NotInRoi then
  2153.                                 MouseState := InRoi;
  2154.                             InitCursor;
  2155.                             if button then begin
  2156.                                     if MouseState = InRoi then begin
  2157.                                             if OpPending and (CurrentOp <> PasteOp) then
  2158.                                                 SetupUndo;
  2159.                                             MouseState := DownInRoi;
  2160.                                             osMouseDownLoc := osloc;
  2161.                                             with info^ do
  2162.                                                 case RoiType of
  2163.                                                     RectRoi:  begin
  2164.                                                             if magnification > 1.0 then
  2165.                                                                 margin := 0
  2166.                                                             else
  2167.                                                                 margin := 2;
  2168.                                                             with RoiRect do
  2169.                                                                 SetRect(RoiStretchHandle, right - RoiHandleSize - margin, bottom - RoiHandleSize - margin, right, bottom);
  2170.                                                             if PtInRect(osloc, RoiStretchHandle) then
  2171.                                                                 RoiMode := StretchMode
  2172.                                                             else
  2173.                                                                 RoiMode := MoveMode;
  2174.                                                         end;
  2175.                                                     LineRoi: 
  2176.                                                         if PtInRect(osloc, LeftHandle) then
  2177.                                                             RoiMode := LeftEndMode
  2178.                                                         else if PtInRect(osloc, RightHandle) then
  2179.                                                             RoiMode := RightEndMode
  2180.                                                         else
  2181.                                                             RoiMode := MoveMode;
  2182.                                                     otherwise
  2183.                                                 end; {case}
  2184.                                             if ShiftKeyDown then
  2185.                                                 RoiMovementState := Constrained
  2186.                                             else
  2187.                                                 RoiMovementState := Unconstrained;
  2188.                                         end;
  2189.                                     MoveRoi(osloc);
  2190.                                     MovingRoi := true;
  2191.                                 end
  2192.                             else
  2193.                                 MouseState := InRoi
  2194.                         end
  2195.                     else begin
  2196.                             MouseState := NotInRoi;
  2197.                             if SpaceBarDown and (CurrentTool <> TextTool) then
  2198.                                 SetCursor(ToolCursor[Grabber])
  2199.                             else if (SelectionMode = AddSelection) and (CurrentTool = Wand) then
  2200.                                 SetCursor(WandPlusCursor)
  2201.                             else if (SelectionMode = SubSelection) and (CurrentTool = Wand) then
  2202.                                 SetCursor(WandMinusCursor)
  2203.                             else if SelectionMode = AddSelection then
  2204.                                 SetCursor(CrossPlusCursor)
  2205.                             else if SelectionMode = SubSelection then
  2206.                                 SetCursor(CrossMinusCursor)
  2207.                             else if (CurrentTool = MagnifyingGlass) and OptionKeyDown then
  2208.                                 SetCursor(GlassMinusCursor)
  2209.                             else
  2210.                                 SetCursor(ToolCursor[CurrentTool]);
  2211.                         end;
  2212.                     if not MovingRoi then begin
  2213.                             if CurrentTool = PickerTool then
  2214.                                 DrawLabels('X:', 'Y:', 'RGB:')
  2215.                             else
  2216.                                 DrawLabels('X:', 'Y:', 'Value:');
  2217.                             with osloc do begin
  2218.                                     if Digitizing then
  2219.                                         pvalue := GetQCPixel(h, v)
  2220.                                     else
  2221.                                         pvalue := MyGetPixel(h, v);
  2222.                                     Show3Values(h, v, pvalue);
  2223.                                 end;
  2224.                         end;
  2225.                 end;
  2226.             HistoKind:  begin
  2227.                     DrawLabels('Level:', 'Count:', '');
  2228.                     SetCursor(ToolCursor[SelectionTool]);
  2229.                     SetPort(HistoWindow);
  2230.                     GlobalToLocal(loc);
  2231.                     ShowHistogramValues(loc.h);
  2232.                 end;
  2233.             ProfilePlotKind, CalibrationPlotKind:  begin
  2234.                     DrawLabels('X:', 'Y:', '');
  2235.                     SetCursor(ToolCursor[SelectionTool]);
  2236.                     SetPort(PlotWindow);
  2237.                     GlobalToLocal(loc);
  2238.                     xscale := PlotCount / (PlotWidth - PlotRightMargin - PlotLeftMargin);
  2239.                     xvalue := trunc((loc.h - PlotLeftMargin) * xscale);
  2240.                     if (xvalue >= 0) and (xvalue < PlotWidth) then
  2241.                         if kind = CalibrationPlotKind then
  2242.                             Show2CalibratedValues(xvalue, xvalue, false)
  2243.                         else
  2244.                             Show2CalibratedValues(xvalue, PlotData^[xvalue], true);
  2245.                 end;
  2246.             LUTKind:  begin
  2247.                     if info^.DensityCalibrated then
  2248.                         DrawLabels('Index:', 'Value:', '  RGB:')
  2249.                     else
  2250.                         DrawLabels('Index:', '  RGB:', '');
  2251.                     SetPort(LUTWindow);
  2252.                     GlobalToLocal(loc);
  2253.                     if (CurrentTool = LutTool) or (CurrentTool = Wand) then begin
  2254.                             if loc.v < 256 then
  2255.                                 SetCursor(LUTCursor)
  2256.                             else
  2257.                                 InitCursor
  2258.                         end
  2259.                     else
  2260.                         SetCursor(PickerCursor);
  2261.                     if loc.v < 256 then begin
  2262.                             ShowRGBValues(loc.v);
  2263.                         end
  2264.                     else begin
  2265.                             color := 0;
  2266.                             for i := 1 to nExtraColors + 2 do
  2267.                                 if PtInRect(loc, ExtraColorsRect[i]) then
  2268.                                     Color := ExtraColorsEntry[i];
  2269.                             ShowRGBValues(color);
  2270.                         end;
  2271.                 end;
  2272.             MapKind: 
  2273.                 if OptionKeyDown then
  2274.                     SetCursor(ToolCursor[SelectionTool])
  2275.                 else
  2276.                     SetCursor(gmCursor);
  2277.             otherwise
  2278.                 InitCursor;
  2279.         end; {case}
  2280.     end;
  2281.  
  2282.  
  2283.     procedure CloseAll;
  2284.         var
  2285.             i, j, result: integer;
  2286.             WPeek, NextWPeek: WindowPeek;
  2287.             ignore: boolean;
  2288.     begin
  2289.         InitCursor;
  2290.         WPeek := WindowPeek(FrontWindow);
  2291.         StopDigitizing;
  2292.         while wpeek <> nil do begin
  2293.                 NextWPeek := WPeek^.NextWindow;
  2294.                 if WPeek^.WindowKind = PicKind then begin
  2295.                         Info := pointer(WPeek^.RefCon);
  2296.                         result := CloseAWindow(info^.wptr);
  2297.                         if not CommandPeriod then
  2298.                             for j := 1 to 2 do
  2299.                                 ignore := HandleEvents;
  2300.                         if result = cancel then begin
  2301.                                 ActivateWindow;
  2302.                                 finished := false;
  2303.                                 exit(CloseAll)
  2304.                             end;
  2305.                     end;
  2306.                 wpeek := NextWPeek;
  2307.             end;
  2308.     end;
  2309.  
  2310.  
  2311.     procedure DoStartup;
  2312.   {Process Finder startup information}
  2313.         var
  2314.             message, ndocs, err, i, j: integer;
  2315.             DocInfo: AppFile;
  2316.             DefaultPalette, OpenedOK: boolean;
  2317.             PaletteName, OutlineName: str255;
  2318.             PaletteFile, OutlineFile: boolean;
  2319.             ignore, PrintDocs: boolean;
  2320.  
  2321.         procedure PrintDocument;
  2322.             var
  2323.                 i: integer;
  2324.         begin
  2325.             WhatToPrint := PrintImage;
  2326.             Print(false);
  2327.             DoClose;
  2328.             for i := 1 to 10 do
  2329.                 ignore := HandleEvents;
  2330.         end;
  2331.  
  2332.     begin
  2333.         for j := 1 to 10 do
  2334.             ignore := HandleEvents;
  2335.         PaletteFile := false;
  2336.         OutlineFile := false;
  2337.         CountAppFiles(message, ndocs);
  2338.         PrintDocs := message = appPrint;
  2339.         if ndocs >= 1 then
  2340.             for i := 1 to ndocs do begin
  2341.                     GetAppFiles(i, DocInfo);
  2342.                     with DocInfo do begin
  2343.                             if ftype = 'ICOL' then begin
  2344.                                     PaletteFile := true;
  2345.                                     PaletteName := docinfo.fname;
  2346.                                     ClrAppFiles(i)
  2347.                                 end;
  2348.                             if fType = 'IPIC' then begin
  2349.                                     WhatToOpen := OpenImage;
  2350.                                     OpenedOK := OpenFile(fName, vRefNum);
  2351.                                     for j := 1 to 10 do
  2352.                                         ignore := HandleEvents;
  2353.                                     ClrAppFiles(i);
  2354.                                     if not OpenedOK then
  2355.                                         exit(DoStartup);
  2356.                                     if PrintDocs then
  2357.                                         PrintDocument;
  2358.                                 end;
  2359.                             if fType = 'TIFF' then begin
  2360.                                     WhatToOpen := OpenTIFF;
  2361.                                     OpenedOK := OpenFile(fName, vRefNum);
  2362.                                     for j := 1 to 10 do
  2363.                                         ignore := HandleEvents;
  2364.                                     ClrAppFiles(i);
  2365.                                     if not OpenedOK then
  2366.                                         exit(DoStartup);
  2367.                                     if PrintDocs then
  2368.                                         PrintDocument;
  2369.                                 end;
  2370.                             if fType = 'PICT' then begin
  2371.                                     OpenedOK := OpenPICT(fName, vRefNum, false);
  2372.                                     for j := 1 to 10 do
  2373.                                         ignore := HandleEvents;
  2374.                                     ClrAppFiles(i);
  2375.                                     if not OpenedOK then
  2376.                                         exit(DoStartup);
  2377.                                     if PrintDocs then
  2378.                                         PrintDocument;
  2379.                                 end;
  2380.                             if fType = 'PICS' then begin
  2381.                                     OpenedOK := OpenPICS(fName, vRefNum);
  2382.                                     for j := 1 to 10 do
  2383.                                         ignore := HandleEvents;
  2384.                                     ClrAppFiles(i);
  2385.                                     if not OpenedOK then
  2386.                                         exit(DoStartup);
  2387.                                 end;
  2388.                             if ftype = 'Iout' then begin
  2389.                                     OutlineFile := true;
  2390.                                     OutlineName := docinfo.fname;
  2391.                                     ClrAppFiles(i)
  2392.                                 end;
  2393.                         end; {with}
  2394.                 end;
  2395.         if PaletteFile then
  2396.             OpenColorTable(PaletteName, DocInfo.vRefNum);
  2397.         if OutlineFile then
  2398.             OpenOutline(OutlineName, DocInfo.vRefNum);
  2399.     end;
  2400.  
  2401.  
  2402.     procedure LoadDefaultMacros;
  2403.   {Looks for a text file named "Image Macros" in the same folder as}
  2404.   {Image, and, if found,  loads the macros contained in it.}
  2405.         var
  2406.             err: OSErr;
  2407.             LaunchRefNum: integer;
  2408.             FinderInfo: FInfo;
  2409.     begin
  2410.         err := GetVol(nil, LaunchRefNum);
  2411.         err := GetFInfo('Image Macros', LaunchRefNum, FinderInfo);
  2412.         if err = NoErr then begin
  2413.                 LoadMacros('Image Macros', LaunchRefNum);
  2414.                 UnloadSeg(@LoadMacros);
  2415.             end;
  2416.     end;
  2417.  
  2418.  
  2419.     procedure Shutdown;
  2420.         var
  2421.             AlertID: integer;
  2422.     begin
  2423.         if (UnsavedResults and (mCount > 10)) or (UnsavedResults and (ResultsWindow <> nil)) then begin
  2424.                 InitCursor;
  2425.                 AlertID := alert(500, nil);
  2426.                 if AlertID = CancelResetID then begin
  2427.                         finished := false;
  2428.                         exit(Shutdown)
  2429.                     end;
  2430.             end;
  2431.         CloseAll;
  2432.         if finished then
  2433.             ConvertClipboard;
  2434.     end;
  2435.  
  2436.  
  2437. begin
  2438.     Init;
  2439.     SetupMenus;
  2440.     GetSettings;
  2441.     AllocateBuffers;
  2442.     AllocateArrays;
  2443.     ConvertSystemClipboard;
  2444.     DoStartup;
  2445.     LoadDefaultMacros;
  2446.     UnloadSeg(@Init);
  2447. {InitUser;}
  2448.     repeat
  2449.         if not HandleEvents then
  2450.             if info^.RoiShowing and (RoiUpdateTime < 30) then
  2451.                 DrawRoi;
  2452.         ShowInsertionPoint;
  2453.         SelectCursor;
  2454.         if Digitizing then begin
  2455.                 CaptureAndDisplayQCFrame;
  2456.                 if ContinuousHistogram then
  2457.                     ShowContinuousHistogram;
  2458.             end;
  2459.         if Finished then
  2460.             Shutdown;
  2461.     until finished;
  2462.     isOK := LoadCLUTResource(AppleDefaultCLUT);
  2463.     RestoreScreen; {Force Finder to redraw color icons}
  2464. end.