home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Pascal / Applications / NIH Image 1.59 / 1.59 Source / Image.p < prev    next >
Encoding:
Text File  |  1995-10-26  |  72.2 KB  |  2,542 lines  |  [TEXT/PJMM]

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