home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / vos2-121.zip / v / iconed / viedcnv.cpp < prev    next >
C/C++ Source or Header  |  1998-07-03  |  59KB  |  2,168 lines

  1. //========================= viedcnv.cxx =================================
  2. // This is the source file for the icon editor picture class, the color
  3. // palette class, and the canvas pane class.   -
  4. //
  5. // Copyright (C) 1996 Philip Eckenroth, Mike Tipping, Marilee Padilla,
  6. //                    John Fredric Jr. Masciantoni, and Bruce E. Wampler.
  7. //
  8. // This file is part of the V Icon Editor, and is covered
  9. // under the terms of the GNU General Public License,
  10. // Version 2. This program has NO WARRANTY. See the source file
  11. // viedapp.cpp for more complete information about license terms.
  12. //=======================================================================
  13.  
  14. #include <fstream.h>
  15. #include <ctype.h>
  16. #include <v/vapp.h>
  17. #include <v/vnotice.h>
  18.  
  19. #include "viedcmdw.h"
  20. #include "viedcnv.h"
  21. #include "coldlg.h"
  22. #include "imageio.h"
  23.  
  24. //================>>> myCanvasPane::myCanvasPane <<<==============
  25.   myCanvasPane::myCanvasPane(myCmdWindow* cw)
  26.   {
  27.     // Initialize items in the canvas pane to default values
  28.  
  29.     _DrawShape = m_DrawPoint;    // set draw tool to line
  30.     _begx = -100;  _begy = -100;
  31.     _curx = -100;  _cury = -100;
  32.     _changed = 0;           // not changed
  33.     _dx = _dy = 0;          // no shift yet
  34.     _cwin = cw;
  35.     _drawGrid = 1;
  36.     _drawmode = DRAW;
  37.     _rdh =  _rdw = 0;    // for smarter redraws
  38.  
  39.  
  40.     // define an instance of the Picture class
  41.     _myPicture = new Picture();    
  42.  
  43.     // define an instance of the Color Palette class
  44.     _myColorPal = new Color_Pal();
  45.  
  46.     _PixSize = 8;
  47.  
  48.     _SelectbegX = -1;  _SelectbegY = -1;
  49.     _SelectendX = -1;  _SelectendY = -1;
  50.     _BrushOffX = 0;  _BrushOffY = 0;
  51.     _BrushWidth = 1; _BrushHeight = 1;
  52.     _BrushX = 0;     _BrushY = 0;
  53.     _BrushPrevX = -1;  _BrushPrevY = -1;
  54.  
  55.     _myPicture->SetIndex(0,0,BrushLayer,-99);    // reset picture index table
  56.     _prevind = -1;            // reset previous index
  57.     _snap = 0;                // turn snap utility off
  58.     _maxx = _PixSize * _myPicture->GetPicWidth();
  59.     _maxy = _PixSize * _myPicture->GetPicHeight();
  60.   }
  61.  
  62. //==============>>> myCanvasPane::~myCanvasPane <<<================
  63.   myCanvasPane::~myCanvasPane()
  64.   {
  65.     // Destroys the myCanvasPane class instance
  66.     if (_myPicture != 0)
  67.     delete _myPicture;
  68.     if (_myColorPal != 0)
  69.     delete _myColorPal;
  70.   }
  71.  
  72. //=================>>> myCanvasPane::ResizeCanvas <<<=====================
  73.   void myCanvasPane::ResizeCanvas( int width, int height)
  74.   {
  75.     // Resizes canvas to given width and height
  76.  
  77.     int* oldPic;
  78.     int oldH, oldW, x, y;
  79.     long oldLim;
  80.  
  81.     if (width < 2 || height < 2)
  82.     return; 
  83.  
  84.     oldH = _myPicture->_height;
  85.     oldW = _myPicture->_width;
  86.     if (oldH == height && oldW == width)    // no op
  87.     return;
  88.     
  89.     _myPicture->Flatten();  // do flatten in case trans layer still holds op
  90.  
  91.     oldLim = (long)oldW * (long)oldH;
  92.     oldPic = new int[oldLim];        // space for temp copy
  93.     // Copy current pic
  94.     for (x = 0 ; x < oldW ; ++x)
  95.       {
  96.     for (y = 0 ; y < oldH ; ++y)
  97.       {
  98.         oldPic[(x*oldH)+y] = 
  99.         _myPicture->GetIndex(x,y,ImageLayer);
  100.       }
  101.       }
  102.  
  103.     if (_myPicture != 0)
  104.     delete _myPicture;
  105.     _myPicture = new Picture(width, height);
  106.  
  107.     _myPicture->Clear(BrushLayer);
  108.     _myPicture->Clear(TransLayer);
  109.  
  110.     // Now, copy upper left corner of old image into new one
  111.     for (x = 0 ; x < oldW && x < width; ++x)
  112.       {
  113.     for (y = 0 ; y < oldH && y < height; ++y)
  114.       {
  115.         _myPicture->SetIndex(x, y, ImageLayer, 
  116.         oldPic[(x*oldH)+y]);
  117.       }
  118.       }
  119.  
  120.     delete [] oldPic;        // Free the storage
  121.     setfg(0); setbg(1);
  122.     _changed = 1;   // has changed now
  123.  
  124.     Clear();
  125.     Redraw(0,0,0,0);
  126.   }
  127.  
  128. //=================>>> myCanvasPane::NewCanvas <<<=====================
  129.   void myCanvasPane::NewCanvas( int width, int height)
  130.   {
  131.     // Creates a new canvas with given width and height
  132.  
  133.     if (_myPicture != 0)
  134.     delete _myPicture;
  135.     _myPicture = new Picture(width, height);
  136.     if (_myColorPal)
  137.     _myColorPal->init_Palette();
  138. //    Redraw(0,0,0,0);
  139.   }
  140.  
  141. //=================>>> myCanvasPane::SetDrawShape <<<=====================
  142.   void myCanvasPane::SetDrawShape(int dm)
  143.   { 
  144.     // Check if setting a brush
  145.     if (dm == m_DrawSelect)
  146.       {
  147.     _myPicture->Clear(BrushLayer, _myColorPal->getbg());
  148.     _myPicture->SetIndex(0,0,BrushLayer,-99);
  149.     _BrushWidth = 1;
  150.     _BrushHeight = 1;
  151.     _BrushOffX = 0;
  152.     _BrushOffY = 0;
  153.       }
  154.     else if (dm == m_DrawText)
  155.       {
  156.       }
  157.     else if (dm == m_DrawPixel)
  158.       {
  159.     _myPicture->Clear(BrushLayer, _myColorPal->getbg());
  160.     _myPicture->SetIndex(0,0,BrushLayer,-99);
  161.     _BrushWidth = 1;
  162.     _BrushHeight = 1;
  163.     _BrushOffX = 0;
  164.     _BrushOffY = 0;
  165.       }
  166.     // else a just shape
  167.     
  168.     _DrawShape = dm;
  169.   }
  170.  
  171. //=================>>> myCanvasPane::SetFGColor <<<=====================
  172.   void myCanvasPane::SetFGColor(vColor& color)
  173.   {
  174.     // Search current palette and set to BG color to that color.
  175.     // If we don't have a match, then we will allocate a new color
  176.     // at the end of the palette until we run out of colors
  177.  
  178.     int colorsUsed = _myColorPal->ColorsUsed();
  179.  
  180.     for (int ix = 0 ; ix < colorsUsed ; ++ix)
  181.       {
  182.     if (_myColorPal->_Palette[ix] == color)
  183.       {
  184.         setfg(ix);
  185.         return;
  186.       }
  187.       }
  188.  
  189.     // Fall through means no match, so have to do more
  190.     if (colorsUsed < 256)    // can add
  191.       {
  192.     // change next free color palette entry
  193.     _myColorPal->_Palette[colorsUsed].ResetColor(color);
  194.     _myColorPal->SetColorsUsed(colorsUsed+1);
  195.     setfg(colorsUsed);
  196.       }
  197.     else
  198.     setfg(0);    // @@ for now, just use 0 (need message)
  199.   }
  200.  
  201. //=================>>> myCanvasPane::SetBGColor <<<=====================
  202.   void myCanvasPane::SetBGColor(vColor& color)
  203.   {
  204.     // Search current palette and set to BG color to that color.
  205.     // If we don't have a match, then we will allocate a new color
  206.     // at the end of the palette until we run out of colors
  207.  
  208.     int colorsUsed = _myColorPal->ColorsUsed();
  209.  
  210.     for (int ix = 0 ; ix < colorsUsed ; ++ix)
  211.       {
  212.     if (_myColorPal->_Palette[ix] == color)
  213.       {
  214.         setbg(ix);
  215.         return;
  216.       }
  217.       }
  218.     // Fall through means no match, so have to do more
  219.     if (colorsUsed < 256)    // can add
  220.       {
  221.     // change next free color palette entry
  222.     _myColorPal->_Palette[colorsUsed].ResetColor(color);
  223.     _myColorPal->SetColorsUsed(colorsUsed+1);
  224.     setbg(colorsUsed);
  225.       }
  226.     else
  227.     setbg(1);
  228.   }
  229.  
  230. //=================>>> myCanvasPane::DrawGrid <<<=====================
  231.   void myCanvasPane::DrawGrid()
  232.   {
  233.     //  This will draw the black grid and set scroll bars if needed
  234.  
  235.     int x, width, height;
  236.     vPen gridPen;
  237.     vBrush gridBrush;
  238.  
  239.  
  240.     // set the pen and brush settings to draw the grid
  241.     gridPen.SetColor(0,0,0);
  242.     SetPen(gridPen);
  243.     gridBrush.SetColor(255,255,255);
  244.     gridBrush.SetStyle(vTransparent);
  245.     SetBrush(gridBrush);
  246.  
  247.     // find width and height of icon in order to scale the grid
  248.     width = _myPicture->GetPicWidth();
  249.     height = _myPicture->GetPicHeight();
  250.  
  251.     if (_drawGrid)
  252.       {
  253.     // draw the grids vertical lines
  254.     for (x = 0 ; x <= width ; x++)
  255.       {
  256.         DrawLine(x*_PixSize, 0, x*_PixSize, height*_PixSize);
  257.       }
  258.  
  259.     // draw the grids horizontal lines
  260.     for (x=0; x<=height; x++)
  261.       {
  262.         DrawLine(0, x*_PixSize, width*_PixSize, x*_PixSize);
  263.       }
  264.       }
  265.     else        // Just a box
  266.       {
  267.     DrawLine(0, 0, 0, height*_PixSize+1);
  268.     DrawLine(width*_PixSize+1, 0, width*_PixSize+1, height*_PixSize+1);
  269.     DrawLine(0, 0, width*_PixSize+1, 0);
  270.     DrawLine(0, height*_PixSize+1, width*_PixSize+1, height*_PixSize+1);
  271.       }
  272.  
  273.  
  274.     // Draw Border around small Icon (actual size icon)
  275.     DrawLine(_myPicture->_width * _PixSize + 10 - 1, 10 - 1,
  276.         (_myPicture->_width * _PixSize + 10 + 1) + _myPicture->_width, 10 - 1);
  277.     DrawLine(_myPicture->_width * _PixSize + 10 - 1, 10 + _myPicture->_height,
  278.         (_myPicture->_width * _PixSize + 10 + 1) + _myPicture->_width,
  279.         10 + _myPicture->_height);
  280.  
  281.     DrawLine(_myPicture->_width * _PixSize + 10 - 1, 10,
  282.         _myPicture->_width * _PixSize + 10 - 1, 10 + _myPicture->_height);
  283.  
  284.     DrawLine((_myPicture->_width * _PixSize + 10) + _myPicture->_width, 10,
  285.         (_myPicture->_width * _PixSize + 10) + _myPicture->_width,
  286.         10 + _myPicture->_height);
  287.  
  288.     // reset pen and brush to default settings
  289.     _PixelPen.SetColor(0,0,0);
  290.     _PixelPen.SetStyle(vTransparent);
  291.     SetPen(_PixelPen);
  292.     _PixelBrush.SetColor(255,255,255);
  293.     _PixelBrush.SetStyle(vSolid);
  294.     SetBrush(_PixelBrush);
  295.  
  296.     // set max values used by scroll bars
  297.     _maxx = _PixSize * _myPicture->GetPicWidth();
  298.     _maxy = _PixSize * _myPicture->GetPicHeight();;
  299.  
  300.     // set scroll bars
  301.     SetScrollBarPositions();
  302.   }
  303.  
  304. //=================>>> myCanvasPane::DrawPixel <<<====================
  305.   void myCanvasPane::DrawDot(int x, int y)
  306.   {
  307.     // draw zoomed pixel
  308.     if (_drawGrid)
  309.     DrawRectangle(_PixSize*x+1, _PixSize*y+1, _PixSize-1, _PixSize-1);
  310.     else
  311.     DrawRectangle(_PixSize*x+1, _PixSize*y+1, _PixSize, _PixSize);
  312.  
  313.     // draw actual pixel
  314.     DrawRectangle(x + (_myPicture->_width * _PixSize) + 10, y + 10, 1,1);
  315.   }
  316.  
  317. //=================>>> myCanvasPane::DrawPixel <<<====================
  318.   void myCanvasPane::DrawPixel(int x, int y, int layer)
  319.   {
  320.     //  This will draw a zoomed pixel (scaled for the zoomed icon)
  321.     //  and an actual pixel (icon on the side that is the actual sized icon)
  322.     //  It draws the pixel from layer 'layer' at x,y
  323.  
  324.     int tempind;    // temporary index
  325.  
  326.     // set temp index to the index from x,y in the layer 'layer'
  327.     tempind = _myPicture->GetIndex(x,y,layer);
  328.  
  329.     // check to see if it is an alpha (transparent)
  330.     if( tempind != -1 )
  331.       {  // not transparent
  332.  
  333.     // We found that V is slowing down the redraw so we try to
  334.     // improve the speed by only changing the pen/brush color when
  335.     // we had to.
  336.  
  337.     if ( tempind != _prevind )
  338.       {  // current color differs from needed
  339.         _PixelBrush.SetColor(_myColorPal->getColor(tempind));
  340.         SetBrush(_PixelBrush);
  341.         _prevind = tempind;      // set this color as current color
  342.       }
  343.  
  344.     // draw zoomed pixel
  345.     if (_drawGrid)
  346.         DrawRectangle(_PixSize*x+1, _PixSize*y+1, _PixSize-1, _PixSize-1);
  347.     else
  348.         DrawRectangle(_PixSize*x+1, _PixSize*y+1, _PixSize, _PixSize);
  349.  
  350.     // draw actual pixel
  351.     DrawRectangle(x + (_myPicture->_width * _PixSize) + 10, y + 10, 1,1);
  352.       }
  353.   }
  354.  
  355. //=================>>> myCanvasPane::DrawImage <<<====================
  356.   void myCanvasPane::DrawImage()
  357.   {
  358.     //  Draw entire image - used on a redraw command.  It walks through the
  359.     //  the entire array and draws the image and transparent layer only.
  360.  
  361.     int x, y, width, height, ind;
  362.  
  363.     // get icon height and width
  364.     width = _myPicture->GetPicWidth();
  365.     height = _myPicture->GetPicHeight();
  366.  
  367.     int colorsUsed = _myColorPal->ColorsUsed();
  368.     int colorSet;
  369.  
  370.     // walk through array by color to optimize resetting of colors
  371.     for (int c = 0 ; c < colorsUsed ; ++c)
  372.       {
  373.     colorSet = 0;
  374.     for (x = 0 ; x < width ; x++)
  375.       {
  376.         for (y = 0 ; y < height ; y++)
  377.           {
  378.         // set index to the x,y cord on transparent layer
  379.         ind = _myPicture->GetIndex(x, y, TransLayer);
  380.         if (ind == -1)
  381.             ind = _myPicture->GetIndex(x, y, ImageLayer);
  382.         if (ind == c)    // found an instance of this color
  383.           {
  384.             // This is the major optimization - we will set
  385.             // the color only once per color
  386.             if (!colorSet)
  387.               {
  388.             colorSet = 1;
  389.             _PixelBrush.SetColor(_myColorPal->getColor(ind));
  390.             SetBrush(_PixelBrush);
  391.               }
  392.             DrawDot(x,y);        // And draw the dot
  393.           }
  394.           }
  395.       }
  396.       }
  397.   }
  398.  
  399. //=================>>> myCanvasPane::ClearShapes <<<====================
  400.   void myCanvasPane::ClearShapes()
  401.   {
  402.     //  This will clear all shapes and pixels on the canvas screen
  403.  
  404.     Clear();       // clear the canvas
  405.     _prevind = -1; // force the pen to be updated next time DrawPixel is called
  406.     DrawGrid();    // Draw the grid and set scroll bars
  407.  
  408.     // clear the image and transparent layers
  409.     _myPicture->Clear(ImageLayer, _myColorPal->getbg());
  410.     _myPicture->Clear(TransLayer);
  411.  
  412.     // set top and left start point to 0
  413.     _dx = _dy = 0;
  414.     SetTranslate(_dx,_dy);
  415.   }
  416.  
  417. //================>>> myCanvasPane::MouseDown <<<=================
  418.   void myCanvasPane::MouseDown(int x, int y, int button)
  419.   {
  420.     //  Everytime a mouse button is depressed run this command
  421.  
  422.     int ind;
  423.     vColor clrPen;
  424.  
  425.     // Mouse down means beginning to draw a shape
  426.  
  427.     // first we flatten the transparent layer and redraw
  428.     _myPicture->Flatten();
  429. //    Redraw(0,0,0,0);
  430.  
  431.     // set foreground or background color as active
  432.     if (button == 1)
  433.       {
  434.     _curPen = _myColorPal->getfg();
  435.       }
  436.     else if (button == 3)
  437.       {
  438.     _curPen = _myColorPal->getbg();
  439.       }
  440.  
  441.     // set mouse cordinates
  442.     _begx = _curx = x - _dx;
  443.     _begy = _cury = y - _dy;
  444.     _prex = _curx;
  445.     _prey = _cury;
  446.  
  447.     _cwin->MouseXYStatus(_curx/_PixSize, _cury/_PixSize);
  448.  
  449.     // if text was selected set mode to point
  450.     if (_DrawShape == m_DrawText)
  451.     _DrawShape = m_DrawPoint;
  452.  
  453.     // if pixel was selected set mode to point
  454.     if (_DrawShape == m_DrawPixel)
  455.     _DrawShape = _PrevDrawShape;
  456.  
  457.     switch (_DrawShape)
  458.       {
  459.     case m_DrawPoint:        // Draw tool point is selected
  460.       {
  461.         // drawing a point is drawing a line at start and end
  462.         // values are the same
  463.         IconLine(_begx/_PixSize,_begy/_PixSize,_begx/_PixSize,_begy/_PixSize);
  464.         _changed = 1;   // has changed now
  465.         break;
  466.       }
  467.  
  468.     case m_DrawFill:         // mode tool fill is selected
  469.       {
  470.         _myPicture->Flatten();    // Flatten before we fill
  471.  
  472.         // get index from image layer as test pixel
  473.         ind = _myPicture->GetIndex(_begx/_PixSize,_begy/_PixSize,ImageLayer);
  474.  
  475.         FillTool(_begx/_PixSize,_begy/_PixSize,ind,button);  // Fill it
  476.         _changed = 1;   // has changed now
  477.         break;
  478.       }
  479.  
  480.     case m_DrawDropper:    // mode tool eye dropper is selected
  481.       {
  482.         if (button == 1)  // left button - set fg color
  483.           {
  484.         setfg(_myPicture->GetIndex(_begx/_PixSize,_begy/_PixSize,ImageLayer));
  485.           }
  486.         else if (button == 3)   // right button - set bg color
  487.           {
  488.         setbg(_myPicture->GetIndex(_begx/_PixSize,_begy/_PixSize,ImageLayer));
  489.           }
  490.         break;
  491.       }
  492.  
  493.     case m_DrawSelect:  // cut - copy - paste tool is selected
  494.       {
  495.         _SelectbegX = _begx/_PixSize;  // set start x position
  496.         _SelectbegY = _begy/_PixSize;  // set start y position
  497.         _changed = 1;   // has changed now
  498.         break;
  499.       }
  500.       }
  501.   }
  502.  
  503. //==================>>> myCanvasPane::MouseMotion <<<===============
  504.   void myCanvasPane::MouseMotion(int mx, int my)
  505.   {
  506.     // everytime the mouse is in motion run this command
  507.  
  508.     // update brush cordinates
  509.     _BrushPrevX = _BrushX;
  510.     _BrushPrevY = _BrushY;
  511.     _BrushX = (mx - _dx)/_PixSize;
  512.     _BrushY = (my - _dy)/_PixSize;
  513.  
  514.     // if brush has left the prev pixel erase old brush
  515.     if ( !( (_BrushPrevX == _BrushX ) && (_BrushPrevY == _BrushY ) ) )
  516.       DrawBrush(_BrushPrevX, _BrushPrevY, 0);
  517.  
  518.     // update to current brush values
  519.     _cwin->MouseXYStatus(_BrushX,_BrushY);
  520.  
  521.     // if brush has left prev pixel draw new brush
  522.     if ( !( (_BrushPrevX == _BrushX ) && (_BrushPrevY == _BrushY ) ) )
  523.     DrawBrush(_BrushX, _BrushY, 1);
  524.   }
  525.  
  526. //==================>>> myCanvasPane::MouseMove <<<===============
  527.   void myCanvasPane::MouseMove(int mx, int my, int button)
  528.   {
  529.     // everytime the mouse moves run this command
  530.  
  531.     int h, w;
  532.     int x = mx - _dx;           // shift to drawing space
  533.     int y = my - _dy;
  534.  
  535.     if (_DrawShape == m_DrawFill)
  536.     return; 
  537.  
  538.     // Draw rubber band shape on mouse move
  539.     if( !( (_prex == _curx) && (_prey == _cury) ) )
  540.       {
  541.     // do only if pointer leaves the pixel space
  542.     if ( !( ( _prex/_PixSize == _curx/_PixSize ) &&
  543.               ( _prey/_PixSize == _cury/_PixSize ) ) )
  544.       {
  545.         switch (_DrawShape)        // determine which draw tool we are using
  546.           {
  547.         case m_DrawLine:        // using line draw tool
  548.           {
  549.             _drawmode = ERASE;  // tell to erase previous line
  550.             IconLine(_begx/_PixSize, _begy/_PixSize,
  551.             _prex/_PixSize, _prey/_PixSize);
  552.             // update previous x and y values
  553.             _prex = _curx;
  554.             _prey = _cury;
  555.             break;
  556.           }
  557.  
  558.         case m_DrawSelect:      // using the select tool, select will mock the rectangle
  559.           {
  560.           }
  561.  
  562.         case m_DrawRect:        // using the rectangle draw tool
  563.           {
  564.             _drawmode = ERASE;  // tell to erase previous line
  565.             IconRect(_begx/_PixSize, _begy/_PixSize,
  566.             _prex/_PixSize, _prey/_PixSize, _snap);
  567.             // update previous x and y values
  568.             _prex = _curx;
  569.             _prey = _cury;
  570.             break;
  571.           }
  572.  
  573.         case m_DrawRdRect:        // using the rounded rectangle draw tool
  574.           {
  575.             _drawmode = ERASE;  // tell to erase previous line
  576.             IconRdRect(_begx/_PixSize, _begy/_PixSize,
  577.             _prex/_PixSize, _prey/_PixSize, _snap);
  578.             // update previous x and y values
  579.             _prex = _curx;
  580.             _prey = _cury;
  581.             break;
  582.           }
  583.  
  584.  
  585.         case m_DrawEllipse:        // using the ellipse draw tool
  586.           {
  587.             _drawmode = ERASE;  // tell to erase previous line
  588.             IconEllipse(_begx/_PixSize, _begy/_PixSize,
  589.             _prex/_PixSize, _prey/_PixSize, _snap);
  590.             // update previous x and y values
  591.             _prex = _curx;
  592.             _prey = _cury;
  593.             break;
  594.           }
  595.  
  596.           }
  597.       }
  598.       }
  599.  
  600.     if (_begx != x || _begy != y)       // draw new line
  601.       {
  602.         _cwin->MouseXYStatus(x/_PixSize, y/_PixSize);
  603.         h = y - _begy;
  604.         w = x - _begx;
  605.         if (h == 0) h = 1;
  606.         if (w == 0) w = 1;
  607.  
  608.     switch (_DrawShape)            // makes call to draw with the tool selected
  609.       {
  610.         case m_DrawLine:            // line draw tool selected
  611.           {
  612.         _drawmode = DRAW;  // tell to draw previous line
  613.         IconLine(_begx/_PixSize, _begy/_PixSize,
  614.         _curx/_PixSize, _cury/_PixSize);
  615.         break;
  616.           }
  617.  
  618.         case m_DrawSelect:          // select tool selected, select mocks rectangle
  619.           {
  620.           }
  621.  
  622.         case m_DrawRect:            // rectangle draw tool selected
  623.           {
  624.         _drawmode = DRAW;  // tell to draw previous line
  625.         IconRect(_begx/_PixSize, _begy/_PixSize,
  626.             _curx/_PixSize, _cury/_PixSize, _snap);
  627.         break;
  628.           }
  629.  
  630.         case m_DrawRdRect:        // rounded rectangle draw tool selected
  631.           {
  632.         _drawmode = DRAW;  // tell to draw previous line
  633.         IconRdRect(_begx/_PixSize, _begy/_PixSize,
  634.             _curx/_PixSize, _cury/_PixSize, _snap);
  635.         break;
  636.           }
  637.  
  638.         case m_DrawEllipse:        // ellipse draw tool selected
  639.           {
  640.         _drawmode = DRAW;  // tell to draw previous line
  641.         IconEllipse(_begx/_PixSize, _begy/_PixSize,
  642.             _curx/_PixSize, _cury/_PixSize, _snap);
  643.         break;
  644.           }
  645.  
  646.         case m_DrawPoint:            // point draw tool selected
  647.           {
  648.         _begx = x;    _begy = y;
  649.         IconLine(x/_PixSize, y/_PixSize, x/_PixSize, y/_PixSize);
  650.         break;
  651.           }
  652.       }
  653.       }
  654.     _curx = x;    _cury = y;            // update position
  655.   }
  656.  
  657. //==================>>> myCanvasPane::MouseUp <<<=================
  658.   void myCanvasPane::MouseUp(int mx, int my, int button)
  659.   {
  660.     // Finish drawing shape on mouse up
  661.  
  662.     int h, w;
  663.     int x = mx - _dx;           // shift to drawing space
  664.     int y = my - _dy;
  665.     int width, height;
  666.     int selectx, selecty, newind;
  667.  
  668.     // get icon width and height
  669.     width = _myPicture->GetPicWidth();
  670.     height = _myPicture->GetPicHeight();
  671.  
  672.     // draw point
  673.     if (_DrawShape == m_DrawPoint)
  674.       {
  675.     if ( (_prex == _curx) && (_prey == _cury) )
  676.         IconLine(_prex/_PixSize, _prey/_PixSize,
  677.                    _prex/_PixSize, _prey/_PixSize);
  678. //    Redraw(0,0,0,0);
  679.     return;
  680.       }
  681.  
  682.     if (_DrawShape == m_DrawFill)
  683.       {
  684.     Redraw(0,0,0,0);
  685.     return;
  686.       }
  687.  
  688.     // if select tool must copy selected area to the brush layer
  689.     if (_DrawShape == m_DrawSelect)
  690.       {
  691.     // clear previous brush layer
  692.     _myPicture->Clear(BrushLayer);
  693.  
  694.     // set selection end point
  695.     _SelectendX = _curx/_PixSize + 1;
  696.     _SelectendY = _cury/_PixSize + 1;
  697.  
  698.     // set custom brush width and height
  699.     _BrushWidth  = MyAbs(_SelectendX - _SelectbegX);
  700.     _BrushHeight = MyAbs(_SelectendY - _SelectbegY);
  701.  
  702.     // alway need a brush width/height
  703.     if (_BrushWidth  == 0)
  704.         _BrushWidth  = 1;
  705.     if (_BrushHeight == 0)
  706.         _BrushHeight = 1;
  707.  
  708.     // force mouse pointer to upper left corner of brush
  709.     _BrushOffX = 0;
  710.     _BrushOffY = 0;
  711.  
  712.     // check to see which way the area was selected (left to right or
  713.        // right to left  etc...) and reajust accordingly
  714.        if ( _SelectbegX < _SelectendX )
  715.        selectx = _SelectbegX;
  716.        else
  717.        selectx = _SelectendX;
  718.  
  719.        if ( _SelectbegY < _SelectendY )
  720.        selecty = _SelectbegY;
  721.        else
  722.        selecty = _SelectendY;
  723.  
  724.        // start storing brush into brush layer
  725.        // NOTE: we will not pick up the background color
  726.        for( int i=0; i<_BrushWidth; i++ )
  727.      {
  728.        for( int j=0; j<_BrushHeight; j++ )
  729.          {
  730.            // get pixel from image layer
  731.            newind = _myPicture->GetIndex(selectx+i, selecty+j, ImageLayer);
  732.  
  733.            // erase mode so set to background color
  734.            if (button == 3)
  735.            _myPicture->SetIndex(selectx+i, selecty+j, ImageLayer,
  736.              _myColorPal->getbg());
  737.  
  738.            // store into brush layer if not background color
  739.            if (newind != _myColorPal->_bg)
  740.            _myPicture->SetIndex(i, j, BrushLayer, newind);
  741.          }
  742.      }
  743.      }
  744.  
  745.     // if mouse pointer has entered a new pixel
  746.     if ( !( ( _prex/_PixSize == _curx/_PixSize ) &&
  747.             ( _prey/_PixSize == _cury/_PixSize ) ) )
  748.       {
  749.     switch (_DrawShape)        // finish drawing shape selected
  750.       {
  751.         case m_DrawLine:        // line draw tool selected
  752.           {
  753.         _drawmode = ERASE;  // tell to erase previous line
  754.         IconLine(_begx/_PixSize, _begy/_PixSize,
  755.         _prex/_PixSize, _prey/_PixSize);
  756.         _prex = _curx;
  757.         _prey = _cury;
  758.         break;
  759.           }
  760.  
  761.         case m_DrawRect:        // rectangle draw tool selected
  762.           {
  763.         _drawmode = ERASE;  // tell to erase previous line
  764.         IconRect(_begx/_PixSize, _begy/_PixSize,
  765.         _prex/_PixSize, _prey/_PixSize, _snap);
  766.         _prex = _curx;
  767.         _prey = _cury;
  768.         break;
  769.           }
  770.  
  771.         case m_DrawRdRect:        // rounded rectangle draw tool selected
  772.           {
  773.         _drawmode = ERASE;  // tell to erase previous line
  774.         IconRdRect(_begx/_PixSize, _begy/_PixSize,
  775.         _prex/_PixSize, _prey/_PixSize, _snap);
  776.         _prex = _curx;
  777.         _prey = _cury;
  778.         break;
  779.           }
  780.  
  781.         case m_DrawEllipse:        // ellipse draw tool selected
  782.           {
  783.         _drawmode = ERASE;  // tell to erase previous line
  784.         IconEllipse(_begx/_PixSize, _begy/_PixSize,
  785.         _prex/_PixSize, _prey/_PixSize, _snap);
  786.         _prex = _curx;
  787.         _prey = _cury;
  788.         break;
  789.           }
  790.       }
  791.       }
  792.  
  793.  
  794.     if (_begx != x || _begy != y)       // First time?
  795.       {
  796.     _cwin->MouseXYStatus(x/_PixSize, y/_PixSize);
  797.     h = y - _begy;
  798.     w = x - _begx;
  799.  
  800.     if (h == 0)
  801.         h = 1;
  802.     if (w == 0)
  803.         w = 1;
  804.  
  805.     // clear transparent layer
  806.     _myPicture->Clear(TransLayer);
  807.  
  808.     switch (_DrawShape)
  809.           {
  810.             case m_DrawLine:        // line draw tool selected
  811.           {
  812.                 _drawmode = DRAW;  // tell to draw previous line
  813.                 IconLine(_begx/_PixSize, _begy/_PixSize,
  814.                          x/_PixSize, y/_PixSize);
  815.                 _PrevDrawShape = _DrawShape;
  816.                 break;
  817.           }
  818.  
  819.             case m_DrawRect:        // rectangle draw tool selected
  820.           {
  821.                 _drawmode = DRAW;  // tell to draw previous line
  822.                 IconRect(_begx/_PixSize, _begy/_PixSize,
  823.                          x/_PixSize, y/_PixSize, _snap);
  824.                 _PrevDrawShape = _DrawShape;
  825.                 break;
  826.           }
  827.  
  828.             case m_DrawRdRect:        // rounded rectangle draw tool selected
  829.           {
  830.                 _drawmode = DRAW;  // tell to draw previous line
  831.                 IconRdRect(_begx/_PixSize, _begy/_PixSize,
  832.                            x/_PixSize, y/_PixSize, _snap);
  833.                 _PrevDrawShape = _DrawShape;
  834.                 break;
  835.           }
  836.  
  837.             case m_DrawEllipse:        // ellipse draw tool selected
  838.           {
  839.                 _drawmode = DRAW;  // tell to draw previous line
  840.                 IconEllipse(_begx/_PixSize, _begy/_PixSize,
  841.                             x/_PixSize, y/_PixSize, _snap);
  842.                 _PrevDrawShape = _DrawShape;
  843.                 break;
  844.           }
  845.  
  846.           }
  847.       }
  848.  
  849.     _changed = 1;       // changed now
  850.     _begx = -100;  _begy = -100;  _curx = -100;  _cury = -100;
  851.  
  852.     // force a redraw
  853.     Redraw(0,0,0,0);
  854.  
  855.     if (_DrawShape == m_DrawSelect)
  856.       {
  857.     _DrawShape = m_DrawPoint;
  858.     _cwin->WindowCommand(m_DrawPoint,1,C_Button);
  859.       }
  860.   }
  861.  
  862. //===================>>> myCanvasPane::Redraw <<<=================
  863.   void myCanvasPane::Redraw(int x, int y, int w, int h)
  864.   {
  865.     // This is a redraw that draws everything on the canvas
  866.  
  867.     // force a pen update
  868.  
  869. //    if ( w != 0 || h != 0)    // caused by expose, etc.
  870. //      {
  871.     // We can handle the case of x,y == 0 and new h and w
  872.     // less than last h and w (which seems to get generated
  873.     // by X all the time, but maybe not Windows...
  874. //    if (x == 0 && y == 0 && w <= _rdw && h <= _rdh)
  875. //        return;
  876. //      }
  877.  
  878.     _rdh = h; _rdw = w;
  879.  
  880.     _prevind = -1;
  881.  
  882.     DrawGrid();   // draw grid
  883.     DrawImage();  // draw image
  884.   }
  885.  
  886. //===================>>> myCanvasPane::ResetScroll <<<=================
  887.   void myCanvasPane::ResetScroll()
  888.   {
  889.     // reset to no scrolling
  890.     _dx = _dy = 0;
  891.     SetTransX(0);             // simple translation
  892.     SetTransY(0);             // simple translation
  893.     SetScrollBarPositions();
  894.   }
  895.  
  896. //===================>>> myCanvasPane::HPage <<<=================
  897.   void myCanvasPane::HPage(int shown, int top)
  898.   {
  899.     int dX;
  900.  
  901.     if (GetWidth() > 0 && shown != 100)
  902.       {
  903.         dX = (int)(((long)top*(long)(_maxx-GetWidth())) / (long)(100 - shown));
  904.       }
  905.     else
  906.         dX = 0;
  907.  
  908.     _dx = -dX;
  909.     SetTransX(_dx);             // simple translation
  910.     Clear();            // clear the canvas
  911.     Redraw(0,0,0,0);
  912.     SetScrollBarPositions();
  913.   }
  914.  
  915. //===================>>> myCanvasPane::HScroll <<<=================
  916.   void myCanvasPane::HScroll(int step)
  917.   {
  918.     if (step > 0 && (GetWidth() - _dx) <= _maxx)        // scroll right
  919.       {
  920.         _dx -= 10;              // bump up by 10
  921.         SetTransX(_dx);
  922.         Clear();                // clear the canvas
  923.         Redraw(0,0,0,0);
  924.       }
  925.     else if (step < 0 && _dx < 0)               // scroll left
  926.       {
  927.         _dx += 10;              // shift by 10
  928.         if (_dx > 0)
  929.             _dx = 0;
  930.         SetTransX(_dx);         // simple translation
  931.         Clear();                // clear the canvas
  932.         Redraw(0,0,0,0);
  933.       }
  934.     SetScrollBarPositions();
  935.   }
  936.  
  937. //===================>>> myCanvasPane::VPage <<<=================
  938.   void myCanvasPane::VPage(int shown, int top)
  939.   {
  940.  
  941.     int dY;
  942.  
  943.     if (GetHeight() > 0 && shown != 100)
  944.         dY = (int)(((long)top*(long)(_maxy-GetHeight())) / (long)(100 - shown));
  945.     else
  946.         dY = 0;
  947.  
  948.     _dy = -dY;
  949.     SetTransY(_dy);             // simple translation
  950.     Clear();            // clear the canvas
  951.     Redraw(0,0,0,0);
  952.     SetScrollBarPositions();
  953.   }
  954.  
  955. //===================>>> myCanvasPane::VScroll <<<=================
  956.   void myCanvasPane::VScroll(int step)
  957.   {
  958.     if (step > 0 && (GetHeight() - _dy) <= _maxy )      // scroll up
  959.       {
  960.         _dy -= 10;              // bump up by 10
  961.         SetTransY(_dy);
  962.         Clear();                // clear the canvas
  963.         Redraw(0,0,0,0);
  964.       }
  965.     else if (step < 0 && _dy < 0) // scroll down
  966.       {
  967.         _dy += 10;              // shift by 10
  968.         if (_dy > 0)
  969.             _dy = 0;
  970.         SetTransY(_dy);         // simple translation
  971.         Clear();                // clear the canvas
  972.         Redraw(0,0,0,0);
  973.       }
  974.     SetScrollBarPositions();
  975.   }
  976.  
  977. //=================>>> myCanvasPane::SetScrollBarPositions <<<=================
  978.   void myCanvasPane::SetScrollBarPositions()
  979.   {
  980.     // Calculate the percentage shown, and how far down scrolls should go
  981.  
  982.     int vShown, hShown, vTop, hTop;
  983.  
  984. // LEAVE IN FOR NOW - FIRST ATTEMPT TO CORRECT SCROLL POSITION
  985. /*
  986.     if ((_myPicture->_height * _PixSize) > GetHeight())
  987.       {
  988.         vShown = (int)((long)100L *(long)GetHeight() /(long)(_myPicture->_height * _PixSize));
  989.         if (((_myPicture->_height * _PixSize) - GetHeight()) != 0)
  990.             vTop = 1;
  991.         else
  992.             vTop = 0;
  993. */
  994.     int Iwidth = _PixSize * _myPicture->GetPicWidth();
  995.     int Iheight = _PixSize * _myPicture->GetPicHeight();
  996.  
  997.     if (Iheight > 0 && Iheight > GetHeight())       // not 100% shown
  998.       {
  999.         vShown = (int)((long)(100L*(long)GetHeight())/(long)Iheight);
  1000.         if ((Iheight - GetHeight()) != 0)
  1001.             vTop = (int)((long)((long)(-_dy*100) / (long)Iheight));
  1002.         else
  1003.             vTop = 0;
  1004.       }
  1005.     else                                // 100% shown
  1006.       {
  1007.         vShown = 100; vTop = 0;
  1008.       }
  1009.  
  1010.     if (Iwidth > 0 && Iwidth > GetWidth())        // not 100%
  1011.       {
  1012.         hShown = (int)((long)(100L*(long)GetWidth())/(long)Iwidth);
  1013.         if ((Iwidth - GetWidth()) != 0)
  1014.             hTop = (int)((long) ((long)(-_dx*100) / (long)Iwidth));
  1015.         else
  1016.             hTop = 0;
  1017.       }
  1018.     else
  1019.       {
  1020.         hShown = 100; hTop = 0;
  1021.       }
  1022.  
  1023.     if (vShown > 100) vShown = 100;     // normalize to 100
  1024.     if (hShown > 100) hShown = 100;     // normalize to 100
  1025.  
  1026.     SetVScroll(vShown,vTop);
  1027.     SetHScroll(hShown,hTop);
  1028.   }
  1029.  
  1030. //==================>>> myCanvasPane::Undo <<<==================
  1031.   void myCanvasPane::Undo()
  1032.   {
  1033.     //  Undo last command by clearing the transparent
  1034.     //  layer and redrawing
  1035.  
  1036.     // clear transparent layer
  1037.     _myPicture->Clear(TransLayer);
  1038.  
  1039.     // force redraw
  1040.     Redraw(0,0,0,0);
  1041.   }
  1042.  
  1043. //==================>>> myCanvasPane::Resize <<<==================
  1044.   void myCanvasPane::Resize(int w, int h)
  1045.   {
  1046.     int needClear = 0;
  1047.  
  1048.     if (w > _maxx && _dx != 0)          // see if now big enough for
  1049.       {                                 // entire drawing
  1050.         needClear = 1; _dx = 0;
  1051.       }
  1052.  
  1053.     if (h > _maxy && _dy != 0)
  1054.       {
  1055.         needClear = 1; _dy = 0;
  1056.       }
  1057.  
  1058.     if (needClear)
  1059.       {
  1060.         SetTranslate(_dx,_dy);
  1061.         Clear();
  1062.       }
  1063.  
  1064.     SetScrollBarPositions();
  1065.     vCanvasPane::Resize(w,h);           // call default resize
  1066.   }
  1067.  
  1068. //==================>>> myCanvasPane::ReadIcon <<<====================
  1069.   int myCanvasPane::ReadIcon(char* name)
  1070.   {
  1071.     // reads in a VBM file and parses
  1072.  
  1073.     int x, y, ix;
  1074.     int height, width;
  1075.  
  1076.     int colors;
  1077.     unsigned char *r, *g, *b;
  1078.     unsigned char* pix;        // for pixels
  1079.  
  1080.     char strip_name[256], ext[256];
  1081.  
  1082.     if (!name || !*name)
  1083.     return 0;
  1084.  
  1085.     getBaseAndExt(name, strip_name, ext);
  1086.  
  1087.     imageIO vbmIO;
  1088.  
  1089.     if (strcmp(ext,"vbm") == 0 || strcmp(ext,"VBM") == 0)
  1090.       {
  1091.     if (!vbmIO.ReadVBM(name))        // Read a VBM image
  1092.         return 0;
  1093.       }
  1094.     else if (strcmp(ext,"xpm") == 0 || strcmp(ext,"XPM") == 0)
  1095.       {
  1096.     if (!vbmIO.ReadXPM(name))        // Read a VBM image
  1097.         return 0;
  1098.       }
  1099.     else if (strcmp(ext,"xbm") == 0 || strcmp(ext,"XBM") == 0)
  1100.       {
  1101.     if (!vbmIO.ReadXBM(name))        // Read a XBM image
  1102.         return 0;
  1103.       }
  1104.     else if (strcmp(ext,"bmp") == 0 || strcmp(ext,"BMP") == 0)
  1105.       {
  1106.     if (!vbmIO.ReadBMP(name))        // Read a VBM image
  1107.         return 0;
  1108.       }
  1109.     else
  1110.     return 0;
  1111.  
  1112.     if (vbmIO.Depth() > 8)
  1113.       {
  1114.     vNoticeDialog note(theApp);
  1115.     note.Notice("Can't handle 24-bit Files.");
  1116.     return 0;
  1117.       }
  1118.  
  1119.     r = vbmIO.RedMap(); g = vbmIO.GreenMap(); b = vbmIO.BlueMap();
  1120.  
  1121.     colors = vbmIO.Colors();
  1122.     width = vbmIO.Width();
  1123.     height = vbmIO.Height();
  1124.  
  1125.     for (ix = 0; ix < colors; ix++)    // fetch the color list
  1126.       {
  1127.     _myColorPal->_Palette[ix].Set(r[ix],g[ix],b[ix]);
  1128.       }
  1129.  
  1130.     _myColorPal->SetColorsUsed(colors);
  1131.  
  1132.     // Put color pallet clear and fill here
  1133.     if (_myPicture != 0)
  1134.     delete _myPicture;
  1135.     _myPicture = new Picture(width, height);
  1136.  
  1137.     _myPicture->Clear(ImageLayer, _myColorPal->getbg());
  1138.     _myPicture->Clear(TransLayer);
  1139.     _myPicture->Clear(BrushLayer);
  1140.     Clear();
  1141.  
  1142.  
  1143.     pix = vbmIO.Pixels();
  1144.     ix = 0;            // start reading pixels at 0
  1145.     for (y = 0; y < height; y++)
  1146.       {
  1147.     for (x = 0; x < width; x++)
  1148.       {
  1149.         _myPicture->SetIndex(x, y, ImageLayer, pix[ix++]);
  1150.       }
  1151.       }
  1152.  
  1153. //    Redraw(0,0,0,0);
  1154.     return 1;
  1155.   }
  1156.  
  1157. //==================>>> myCanvasPane::Read <<<====================
  1158.   int myCanvasPane::Read(char* name)
  1159.   {
  1160.     // load in a file
  1161.  
  1162.  
  1163.     if (!name || !*name)
  1164.         return 0;       // sanity check
  1165.  
  1166.     return ReadIcon(name);
  1167.   }
  1168.  
  1169. //==================>>> myCanvasPane::SaveIcon <<<====================
  1170.   int myCanvasPane::SaveIcon(char* filename, char* iconname, char* ext)
  1171.   {
  1172.     // Save an image. The process is relatively simple by using
  1173.     // the imageIO package. We Flatten the image to make sure it
  1174.     // is up to date. Then we create an imageIO color map, copy
  1175.     // our color map to it. Then we set depth, height, width, and
  1176.     // number of colors used. Then, we copy our pixel array
  1177.     // to the imageIO pixel array. Finally, we call the imageIO
  1178.     // routine to optimize the color map. Then we call the appropriate
  1179.     // output converter based on the extension.
  1180.  
  1181.     unsigned char *r, *g, *b, *pix;
  1182.     long px;
  1183.  
  1184.     _myPicture->Flatten();  // do flatten in case trans layer still holds op
  1185. //    Redraw(0,0,0,0);
  1186.  
  1187.     imageIO vbmIO;
  1188.  
  1189.     // 1. Set up color map
  1190.  
  1191.     vbmIO.CreateColorMap(256);    // Create an empty color map
  1192.     r = vbmIO.RedMap();
  1193.     g = vbmIO.GreenMap();
  1194.     b = vbmIO.BlueMap();
  1195.  
  1196.     for (int ix = 0 ; ix < _myColorPal->ColorsUsed() ; ++ix)
  1197.       {
  1198.     r[ix] = (unsigned char) _myColorPal->getColor(ix).r();
  1199.     g[ix] = (unsigned char) _myColorPal->getColor(ix).g();
  1200.     b[ix] = (unsigned char) _myColorPal->getColor(ix).b();
  1201.       }
  1202.  
  1203.     // 2. set various attributes
  1204.  
  1205.     vbmIO.SetDepth(8);
  1206.     vbmIO.SetColors(_myColorPal->ColorsUsed());
  1207.     vbmIO.SetWidth(_myPicture->_width);
  1208.     vbmIO.SetHeight(_myPicture->_height);
  1209.  
  1210.    // 3. Copy the image array
  1211.  
  1212.     pix = vbmIO.CreatePixels((long)(_myPicture->_height * _myPicture->_width));
  1213.  
  1214.     px = 0;
  1215.     for (int ir = 0 ; ir < _myPicture->_height ; ++ir)
  1216.       {
  1217.     for (int ic = 0 ; ic < _myPicture->_width ; ++ic)
  1218.       {
  1219.         pix[px++] = (unsigned char)_myPicture->GetIndex(ic,ir,ImageLayer);
  1220.       }
  1221.       }
  1222.  
  1223.     // 4. Optimize color map
  1224.  
  1225.     vbmIO.OptimizeColorMap();        // squish color map
  1226.  
  1227.     // 5. Write out in appropriate format
  1228.  
  1229.  
  1230.     if (strcmp(ext,"vbm") == 0 || strcmp(ext,"VBM") == 0)
  1231.     return vbmIO.WriteVBM(filename,iconname);
  1232.     else if (strcmp(ext,"xpm") == 0 || strcmp(ext,"XPM") == 0)
  1233.     return vbmIO.WriteXPM(filename,iconname);
  1234.     else if (strcmp(ext,"bmp") == 0 || strcmp(ext,"BMP") == 0)
  1235.     return vbmIO.WriteBMP(filename,iconname);
  1236.     else if (strcmp(ext,"xbm") == 0 || strcmp(ext,"XBM") == 0)
  1237.       {
  1238.         if (vbmIO.Colors() > 2)
  1239.       {
  1240.         vNoticeDialog note(theApp);
  1241.         note.Notice("Too many colors for .XBM.");
  1242.       }
  1243.     else 
  1244.         return vbmIO.WriteXBM(filename, iconname);
  1245.       }
  1246.  
  1247.     return 0;
  1248.   }
  1249.  
  1250. //==================>>> myCanvasPane::getBaseAndExt <<<====================
  1251.   int myCanvasPane::getBaseAndExt(char* name, char* base, char* ext)
  1252.   {
  1253.     char temp_str[256];
  1254.  
  1255.     strcpy(temp_str,name);
  1256.  
  1257.     int ix;
  1258.     for (ix = strlen(temp_str) - 1 ; ix >= 0 ; --ix)
  1259.       {
  1260.     if (temp_str[ix] == '.')    // found break
  1261.       {
  1262.         strcpy(ext,&temp_str[ix+1]);
  1263.         temp_str[ix] = 0;
  1264.         break;
  1265.       }
  1266.     if (temp_str[ix] == '/' || temp_str[ix] == '\\')
  1267.         break;
  1268.       }
  1269.  
  1270.     for ( ; ix >= 0 ; --ix)
  1271.       {
  1272.     if (temp_str[ix] == '/' || temp_str[ix] == '\\')
  1273.       {
  1274.         strcpy(base,&temp_str[ix+1]);
  1275.         break;
  1276.       }
  1277.       }
  1278.  
  1279.     if (ix <= 0 &&
  1280.     temp_str[0] != '/' && temp_str[0] != '\\')
  1281.       {
  1282.     strcpy(base,&temp_str[0]);
  1283.       }
  1284.  
  1285.     for (char *cp = base ; *cp ; ++cp)
  1286.     *cp = tolower(*cp);
  1287.     return 1;
  1288.   }
  1289.  
  1290. //==================>>> myCanvasPane::Save <<<====================
  1291.   int myCanvasPane::Save(char* name)
  1292.   {
  1293.     char strip_name[256];
  1294.     char extension[32];
  1295.  
  1296.     if (!name || !*name)
  1297.     return 0;      // sanity check
  1298.  
  1299.     // crop the full path name to extract filename - extension
  1300.  
  1301.     strcpy(extension,"vbm");        // vbm by default
  1302.  
  1303.     getBaseAndExt(name, strip_name, extension);
  1304.  
  1305.     int retv = SaveIcon(name, strip_name, extension);
  1306.     if (retv)
  1307.     _changed = 0;        // not changed anymore
  1308.     return retv;
  1309.   }
  1310.  
  1311. //==================>>> myCanvasPane::FillGrid <<<=====================
  1312.   void myCanvasPane::FillGrid(int x, int y)
  1313.   {
  1314.     //  fill the pixel into the grid(array) called from drawline, etc
  1315.  
  1316.     int tempind;
  1317.     int newx, newy;
  1318.     int layer;
  1319.  
  1320.     // draw the brush so walk through brush layer
  1321.     for (int i = 0; i < _BrushWidth; i++)
  1322.       {
  1323.     for (int j = 0; j < _BrushHeight; j++)
  1324.       {
  1325.         // set new x and y cord
  1326.         newx = x-_BrushOffX+i;
  1327.         newy = y-_BrushOffY+j;
  1328.  
  1329.         // make sure we are in bounds of icon
  1330.         if ( (newx>=0) && (newx<_myPicture->_width)
  1331.         && (newy>=0) && (newy<_myPicture->_height) )
  1332.           {
  1333.         // set temp index to brush layer at x,y
  1334.         tempind = _myPicture->GetIndex(i, j, BrushLayer);
  1335.         // set to transparent layer
  1336.         layer = TransLayer;
  1337.  
  1338.         // transparent don't draw
  1339.         if (tempind != -1)
  1340.           {
  1341.             // if we are in draw mode . . . draw
  1342.             if (_drawmode == DRAW)
  1343.               {
  1344.             // if -99 then the brush is default
  1345.             // so use fg/bg colors
  1346.             if (tempind == -99)
  1347.               {
  1348.                 tempind = getCurPenInd();
  1349.               }
  1350.             else
  1351.               { // custom vrush - read brush's colors
  1352.                 // set alyer to brush
  1353.                 layer = BrushLayer;
  1354.  
  1355.                 // if right button pressed - erase
  1356.                 if (_myColorPal->getbg() == _curPen)
  1357.                 tempind = _myColorPal->getbg();
  1358.               }
  1359.               }
  1360.             else
  1361.               {  // ERASE
  1362.             // set temp index to image x,y
  1363.             tempind = _myPicture->GetIndex(newx,newy,ImageLayer);
  1364.  
  1365.             // make sure layer is set to transparent
  1366.             layer = TransLayer;
  1367.               }
  1368.  
  1369.             // set pixel into array
  1370.             _myPicture->SetIndex(newx, newy, TransLayer, tempind);
  1371.             // draw pixel to screen
  1372.             DrawPixel(newx, newy, layer);
  1373.           }
  1374.           }
  1375.       }
  1376.       }
  1377.   }
  1378.  
  1379. //==================>>> myCanvasPane::DrawBrush <<<=====================
  1380.   void myCanvasPane::DrawBrush(int x, int y, int mode)
  1381.   {  //  draw the brush selected (default or custom)
  1382.  
  1383.     int tempind;
  1384.     int newx, newy;
  1385.     int layer;
  1386.  
  1387.     if ( (x <0 ) || (y < 0) ) 
  1388.     return;
  1389.  
  1390.     // walk through brush layer
  1391.     for (int i = 0; i < _BrushWidth; i++)
  1392.       {
  1393.     for (int j = 0; j < _BrushHeight; j++)
  1394.       {
  1395.         // set new x and y
  1396.         newx = x-_BrushOffX+i;
  1397.         newy = y-_BrushOffY+j;
  1398.  
  1399.         // if in bounds of icon
  1400.         if( (newx>=0) && (newx<_myPicture->_width)
  1401.         && (newy>=0) && (newy<_myPicture->_height) )
  1402.           {
  1403.  
  1404.         // set temp index to brush layer
  1405.         tempind = _myPicture->GetIndex(i, j, BrushLayer);
  1406.         layer = TransLayer;
  1407.  
  1408.         // transparent??? do nothing
  1409.         if (tempind != -1 && (tempind < 256 && tempind > 0))
  1410.           {
  1411.             if (mode)  // draw
  1412.               {
  1413.             // -99 is a default brush so use bg/fg color
  1414.             if (tempind == -99)
  1415.               {
  1416.                 tempind = getCurPenInd();
  1417.               } 
  1418.             else
  1419.               {  // custom brush better read color
  1420.                 layer = BrushLayer;
  1421.               }
  1422.               }
  1423.             else
  1424.               {  // erase
  1425.             // read from transparent layer
  1426.             tempind = _myPicture->GetIndex(newx,newy,TransLayer);
  1427.  
  1428.             // if transparent read from image layer
  1429.             if (tempind == -1  && (tempind < 256 && tempind > 0))
  1430.                 tempind = _myPicture->GetIndex(newx,newy,ImageLayer);
  1431.  
  1432.             // layer = transparent
  1433.             layer = TransLayer;
  1434.               }
  1435.  
  1436.             // draw if it not transparent
  1437.             if ( tempind != -1 && (tempind < 256 && tempind > 0))
  1438.               {
  1439.             // update pen only if needed
  1440.             if ( tempind != _prevind && (tempind < 256 && tempind > 0))
  1441.               {
  1442.                 _PixelBrush.SetColor(_myColorPal->getColor(tempind));
  1443.                 SetBrush(_PixelBrush);
  1444.                 _prevind = tempind;
  1445.               }
  1446.  
  1447.             // draw pixel - no sotarge into array needed
  1448.             DrawRectangle(_PixSize*newx+1, _PixSize*newy+1,
  1449.             _PixSize-1, _PixSize-1);
  1450.               }
  1451.           }
  1452.           }
  1453.       }
  1454.       }
  1455.   }
  1456.  
  1457. //==================>>> myCanvasPane::FillTool <<<======================
  1458.   void myCanvasPane::FillTool(int x, int y, int the_index, int button)
  1459.   {  
  1460. //#define RECURSIVE_FILL
  1461.  
  1462. #ifdef RECURSIVE_FILL
  1463.     //  recursive fill tool 
  1464.  
  1465.     // Make sure we are not out of our image
  1466.     if ( (x >=0) && (x < _myPicture->_width) &&
  1467.        (y >=0) && (y < _myPicture->_height) )
  1468.       {
  1469.     // get pixels index on transparent layer
  1470.     int tempind = _myPicture->GetIndex(x,y,TransLayer);
  1471.  
  1472.     if (tempind == -1)          // transparent -> look at image layer
  1473.         tempind = _myPicture->GetIndex(x,y,ImageLayer);
  1474.  
  1475.     if ( tempind == the_index)  // is original color, so fill
  1476.       {
  1477.         if (button == 1)
  1478.         _myPicture->SetIndex(x, y, TransLayer, _myColorPal->getfg());  // set pixel index
  1479.         else
  1480.         _myPicture->SetIndex(x, y, TransLayer, _myColorPal->getbg());  // set pixel index
  1481.  
  1482.         // start recursive calls
  1483.         if (y > 0)
  1484.         FillTool(x, y-1, the_index,button);  // fill up
  1485.         if (x+1 < _myPicture->_width)
  1486.         FillTool(x+1, y, the_index,button);  // fill right
  1487.         if (y + 1 < _myPicture->_height)
  1488.         FillTool(x, y+1, the_index,button);  // fill down
  1489.         if (x > 0)
  1490.         FillTool(x-1, y, the_index,button);  // fill left
  1491.       }
  1492.       }
  1493. #else
  1494.     // stack based fill
  1495.     int fillcolor;
  1496.     if (button == 1)
  1497.     fillcolor = _myColorPal->getfg();    // fill with fg
  1498.     else
  1499.     fillcolor = _myColorPal->getbg();    // fill with bg
  1500.     fill(x, y, _myPicture->_width, _myPicture->_height, the_index, fillcolor);
  1501.  
  1502. #endif
  1503.   }
  1504.  
  1505. #ifndef RECURSIVE_FILL
  1506. //
  1507. // A Seed Fill Algorithm
  1508. // by Paul Heckbert
  1509. // from "Graphics Gems", Academic Press, 1990
  1510. //
  1511.  
  1512. typedef struct {short y, xl, xr, dy;} Segment;
  1513. //
  1514. // Filled horizontal segment of scanline y for xl<=x<=xr.
  1515. // Parent segment was on line y-dy.  dy=1 or -1
  1516. //
  1517.  
  1518. #define STACKSIZE 8000    // max depth of stack (< 64K DOS SEGMENT)
  1519.  
  1520. // push new segment on stack
  1521. #define PUSH(Y, XL, XR, DY) \
  1522.     if (sp<stack+STACKSIZE && Y+(DY)>=0 && Y+(DY)<height) \
  1523.     {sp->y = Y; sp->xl = XL; sp->xr = XR; sp->dy = DY; sp++;}
  1524.  
  1525. // pop segment off stack
  1526. #define POP(Y, XL, XR, DY) \
  1527.     {sp--; Y = sp->y+(DY = sp->dy); XL = sp->xl; XR = sp->xr;}
  1528.  
  1529. //
  1530. // fill: set the pixel at (x,y) and all of its 4-connected neighbors
  1531. // with the same pixel value to the new pixel value nv.
  1532. // A 4-connected neighbor is a pixel above, below, left, or right of a pixel.
  1533. //
  1534.  
  1535. //======================>>> myCanvasPane::pixelwrite <<<===========================
  1536.   void myCanvasPane::pixelwrite(int x, int y, int val)
  1537.   {
  1538.     _myPicture->SetIndex(x,y,TransLayer,val);
  1539.   }
  1540.  
  1541. //======================>>> myCanvasPane::pixelread <<<===========================
  1542.   int myCanvasPane::pixelread(int x, int y)
  1543.   {
  1544.     int tmp = _myPicture->GetIndex(x,y,TransLayer);
  1545.     if (tmp == -1)
  1546.     tmp = _myPicture->GetIndex(x,y,ImageLayer);
  1547.     return tmp;
  1548.   }
  1549.  
  1550. //======================>>> myCanvasPane::fill <<<===========================
  1551.   void myCanvasPane::fill(int x, int y, int width, int height, 
  1552.     int ov, int fillcolor)
  1553.   {
  1554.     int start, x1, x2, dy = 0;
  1555.  
  1556.     if (fillcolor == ov)        // nothing to do
  1557.     return;
  1558.  
  1559.     Segment* stack = new Segment[STACKSIZE]; // allocate the stack
  1560.     Segment* sp = stack;
  1561.  
  1562.     PUSH(y, x, x, 1);            // needed in some cases
  1563.     PUSH(y+1, x, x, -1);        // seed segment (popped 1st)
  1564.  
  1565.     while (sp > stack)
  1566.       {
  1567.     // pop segment off stack and fill a neighboring scan line
  1568.     POP(y, x1, x2, dy);
  1569.  
  1570.     // segment of scan line y-dy for x1<=x<=x2 was previously filled,
  1571.  
  1572.     for (x = x1; x >= 0 && pixelread(x, y) == ov; x--)
  1573.         pixelwrite(x, y,fillcolor);
  1574.     if (x >= x1) 
  1575.       {
  1576.         for (x++; x<=x2 && pixelread(x, y)!=ov; x++)
  1577.         ;
  1578.         start = x;
  1579.         if (x > x2)
  1580.         continue;
  1581.       } 
  1582.     else
  1583.       {
  1584.         start = x+1;
  1585.         if (start<x1)
  1586.         PUSH(y, start, x1-1, -dy);       // leak on left?
  1587.         x = x1+1;
  1588.       }
  1589.     do 
  1590.       {
  1591.      //   for (; x<width && pixelread(x, y)==ov; x++)
  1592.         for (; x < width && pixelread(x, y)==ov; x++)
  1593.         pixelwrite(x, y, fillcolor);
  1594.         PUSH(y, start, x-1, dy);
  1595.         if (x>x2+1) 
  1596.         PUSH(y, x2+1, x-1, -dy);       // leak on right?
  1597.         for (x++; x<=x2 && pixelread(x, y)!=ov; x++)
  1598.         ;
  1599.         start = x;
  1600.       } 
  1601.     while (x<=x2)
  1602.         ;
  1603.       }
  1604.     delete [] stack;
  1605.   }
  1606. #endif
  1607. //==================>>> myCanvasPane::MyAbs <<<==========================
  1608.   int myCanvasPane::MyAbs(int value)
  1609.   {  // This function mimics the absolute math funtion
  1610.  
  1611.     if (value < 0) 
  1612.     return -value;
  1613.     else 
  1614.     return value;
  1615.   }
  1616.  
  1617. //==================>>> myCanvasPane::Round <<<==========================
  1618.   int myCanvasPane::Round(float num)
  1619.   {  // This function will round the float and return an integer
  1620.  
  1621.     int sign;                     // sign for positive or negative num
  1622.     float temp;                   // temp val
  1623.  
  1624.     if (num < 0)
  1625.     sign = -1;    // compute sign
  1626.     else 
  1627.     sign = 1;
  1628.  
  1629.     temp = sign * (num - (int)num);       // set temp to remainer
  1630.  
  1631.     return (int)(num + (sign * temp));    // return rounded value
  1632.   }
  1633.  
  1634. //==================>>> myCanvasPane::IconLine <<<======================
  1635.   void myCanvasPane::IconLine(int begx, int begy, int curx, int cury)
  1636.   {  // This function will draw a line from begx,begy to curx,cury
  1637.  
  1638.     if ( (curx == begx) && (cury == begy) )       // draw point
  1639.       {
  1640.     _x = curx;
  1641.     _y = cury;
  1642.     FillGrid(_x, _y);
  1643.       }
  1644.  
  1645.     if (curx != begx)           // not a vertical line
  1646.       {
  1647.     _m = ((float)(cury - begy) / (float)(curx - begx)); // set slope
  1648.     _b = (float)(cury - (_m * curx));                   // set y intercept
  1649.  
  1650.     if (curx >= begx) // set begin and end for for loop, this depends
  1651.       {                 // on which way to walk through the for loop
  1652.         _endval = curx;
  1653.         _startval = begx;
  1654.       }
  1655.     else 
  1656.       {
  1657.         _endval = begx;
  1658.         _startval = curx;
  1659.       }
  1660.  
  1661.     for (_x = _startval; _x <= _endval; _x++) // walk along x axis
  1662.       {
  1663.         _y = Round( ((_m * _x) + _b) );         // equation for a line;
  1664.         FillGrid(_x, _y);                       // make call to fill the grid
  1665.       }
  1666.       }
  1667.  
  1668.     if (cury != begy)                   // not a horizontal line
  1669.       {
  1670.     if (begx != curx)                 // set slope
  1671.         _m = ((float)(cury - begy) / (float)(curx - begx));
  1672.  
  1673.     _b = (float)(cury - (_m * curx));         // set y intercept
  1674.     if (cury >= begy)                 // find which way the line runs
  1675.       {
  1676.         _endval = cury;
  1677.         _startval = begy;
  1678.       } 
  1679.     else 
  1680.       {
  1681.         _endval = begy;
  1682.         _startval = cury;
  1683.       }
  1684.  
  1685.     for (_y=_startval; _y <= _endval; _y++)   // walk down y axis
  1686.       {
  1687.         if (begx != curx)
  1688.         _x = Round( ((_y - _b) / _m) );
  1689.         else
  1690.         _x = curx;
  1691.         FillGrid(_x, _y);                   // make call to grid
  1692.       }
  1693.       }
  1694.   }
  1695.  
  1696. //==================>>> myCanvasPane::IconRect <<<======================
  1697.   void myCanvasPane::IconRect(int begx, int begy, int curx, int cury, int mode)
  1698.   {  // This function will draw a rectangle with opposite corners at begx,begy
  1699.   // to curx,cury
  1700.  
  1701.     if (mode == 1)                            // draw square for snap mode
  1702.       {
  1703.  
  1704.     // check to see how drawn - (left to right vs right to left,
  1705.     //                           up to down vd down to up)
  1706.     if (MyAbs(curx-begx) > MyAbs(cury-begy) )
  1707.       {
  1708.         if ((cury-begy) < 0)
  1709.         cury = begy - MyAbs(curx-begx);
  1710.         else
  1711.         cury = begy + MyAbs(curx-begx);
  1712.       }
  1713.     else if (MyAbs(cury-begy) > MyAbs(curx-begx) )
  1714.       {
  1715.         if ((curx-begx) < 0)
  1716.         curx = begx - MyAbs(cury-begy);
  1717.         else
  1718.         curx = begx + MyAbs(cury-begy);
  1719.       }
  1720.       }
  1721.  
  1722.     if ( (curx == begx) && (cury == begy) )       // draw point
  1723.     FillGrid(curx, cury);
  1724.  
  1725.     // Draw the rectangle according to begx, begy, curx, cury
  1726.  
  1727.     IconLine(begx, begy, begx+(curx-begx), begy);
  1728.     IconLine(begx, begy, begx, begy+(cury-begy));
  1729.     IconLine(begx+(curx-begx), begy, begx+(curx-begx), begy+(cury-begy));
  1730.     IconLine(begx, begy+(cury-begy), begx+(curx-begx), begy+(cury-begy));
  1731.   }
  1732.  
  1733. //==================>>> myCanvasPane::IconRdRect <<<====================
  1734.   void myCanvasPane::IconRdRect(int begx, int begy, int curx, int cury, int mode)
  1735.   {  // This function will draw a rectangle like above but with rounded corners
  1736.  
  1737.     int smallest;                 // smallest side of rectangle
  1738.  
  1739.     if (mode == 1)                            // draw square for snap mode
  1740.       {
  1741.     // check to see how drawn - (left to right vs right to left,
  1742.     //                           up to down vd down to up)
  1743.     if (MyAbs(curx-begx) > MyAbs(cury-begy) )
  1744.       {
  1745.         if ((cury-begy) < 0)
  1746.         cury = begy - MyAbs(curx-begx);
  1747.         else
  1748.         cury = begy + MyAbs(curx-begx);
  1749.       }
  1750.     else if (MyAbs(cury-begy) > MyAbs(curx-begx) )
  1751.       {
  1752.         if ((curx-begx) < 0)
  1753.         curx = begx - MyAbs(cury-begy);
  1754.         else
  1755.         curx = begx + MyAbs(cury-begy);
  1756.       }
  1757.       }
  1758.  
  1759.     if ( (curx == begx) && (cury == begy) )       // draw point
  1760.     FillGrid(curx, cury);
  1761.  
  1762.     // find smallest side
  1763.     if (MyAbs(begy-cury) > MyAbs(begx-curx) )
  1764.     smallest = MyAbs(curx-begx);
  1765.     else
  1766.     smallest = MyAbs(cury-begy);
  1767.  
  1768.     // no need to draw rounded corners
  1769.     if (smallest <= 1)
  1770.       {
  1771.     IconLine(begx, begy, curx, begy);
  1772.     IconLine(begx, cury, curx, cury);
  1773.     IconLine(begx, begy, begx, cury);
  1774.     IconLine(curx, begy, curx, cury);
  1775.       }
  1776.     else if (smallest <= 5)    // draw rounded corners
  1777.       {
  1778.     // right to left
  1779.     if (begx > curx)
  1780.       {
  1781.         //  top to bottom
  1782.         if (begy > cury)
  1783.           {
  1784.         IconLine(begx-1, begy, curx+1, begy);
  1785.         IconLine(begx-1, cury, curx+1, cury);
  1786.         IconLine(begx, begy-1, begx, cury+1);
  1787.         IconLine(curx, begy-1, curx, cury+1);
  1788.           }
  1789.         else        // bottom to top
  1790.           {
  1791.         IconLine(begx-1, begy, curx+1, begy);
  1792.         IconLine(begx-1, cury, curx+1, cury);
  1793.         IconLine(begx, begy+1, begx, cury-1);
  1794.         IconLine(curx, begy+1, curx, cury-1);
  1795.           }
  1796.       }
  1797.     else    // left to right
  1798.       {
  1799.         // top to bottom
  1800.         if (begy > cury)
  1801.           {
  1802.         IconLine(begx+1, begy, curx-1, begy);
  1803.         IconLine(begx+1, cury, curx-1, cury);
  1804.         IconLine(begx, begy-1, begx, cury+1);
  1805.         IconLine(curx, begy-1, curx, cury+1);
  1806.           }
  1807.         else      // bottom to top
  1808.           {
  1809.         IconLine(begx+1, begy, curx-1, begy);
  1810.         IconLine(begx+1, cury, curx-1, cury);
  1811.         IconLine(begx, begy+1, begx, cury-1);
  1812.         IconLine(curx, begy+1, curx, cury-1);
  1813.           }
  1814.       }
  1815.       }
  1816.     else //Bigger then 5 in smallest (smallest <= 5)
  1817.       {
  1818.     // same checking of drawing orientation
  1819.     if (begx > curx)
  1820.       {
  1821.         if (begy > cury)
  1822.           {
  1823.         IconLine(begx-2, begy, curx+2, begy);
  1824.         IconLine(begx-2, cury, curx+2, cury);
  1825.         IconLine(begx, begy-2, begx, cury+2);
  1826.         IconLine(curx, begy-2, curx, cury+2);
  1827.         FillGrid(begx-1, begy-1);  FillGrid(curx+1, cury+1);
  1828.         FillGrid(begx-1, cury+1);  FillGrid(curx+1, begy-1);
  1829.           }
  1830.         else // if (begy < cury)
  1831.           {
  1832.         IconLine(begx-2, begy, curx+2, begy);
  1833.         IconLine(begx-2, cury, curx+2, cury);
  1834.         IconLine(begx, begy+2, begx, cury-2);
  1835.         IconLine(curx, begy+2, curx, cury-2);
  1836.         FillGrid(begx-1, begy+1);  FillGrid(curx+1, cury-1);
  1837.         FillGrid(begx-1, cury-1);  FillGrid(curx+1, begy+1);
  1838.           }
  1839.       }
  1840.     else
  1841.       {
  1842.         if (begy > cury)
  1843.           {
  1844.         IconLine(begx+2, begy, curx-2, begy);
  1845.         IconLine(begx+2, cury, curx-2, cury);
  1846.         IconLine(begx, begy-2, begx, cury+2);
  1847.         IconLine(curx, begy-2, curx, cury+2);
  1848.         FillGrid(begx+1, begy-1);  FillGrid(curx-1, cury+1);
  1849.         FillGrid(begx+1, cury+1);  FillGrid(curx-1, begy-1);
  1850.           }
  1851.         else // if (begy < cury)
  1852.           {
  1853.         IconLine(begx+2, begy, curx-2, begy);
  1854.         IconLine(begx+2, cury, curx-2, cury);
  1855.         IconLine(begx, begy+2, begx, cury-2);
  1856.         IconLine(curx, begy+2, curx, cury-2);
  1857.         FillGrid(begx+1, begy+1);  FillGrid(curx-1, cury-1);
  1858.         FillGrid(begx+1, cury-1);  FillGrid(curx-1, begy+1);
  1859.           }
  1860.       }
  1861.       }
  1862.   }
  1863.  
  1864. //==================>>> myCanvasPane::IconEllipse <<<====================
  1865.   void myCanvasPane::IconEllipse(int begx, int begy, int curx, int cury, int mode)
  1866.   {  // This function will draw an elipse with center at begx,begy
  1867.     //  The x axis radius = |curx-begx|
  1868.     //  The y axis radius = |cury-begy|
  1869.  
  1870.     if (mode == 1)           // draw circle
  1871.       {
  1872.     // check to see how drawn - (left to right vs right to left,
  1873.     //                           up to down vd down to up)
  1874.     if (MyAbs(curx-begx) > MyAbs(cury-begy) )
  1875.       {
  1876.         cury = curx;
  1877.         _a = MyAbs(curx - begx);      // find a ->x axis radius
  1878.         _b = _a;                      // find b ->y axis radius
  1879.       }
  1880.     else if ( (curx == begx) && (cury == begy) )
  1881.       {
  1882.         _x = curx;
  1883.         _y = cury;
  1884.         FillGrid(_x, _y);
  1885.       }
  1886.     else
  1887.       {
  1888.         curx = cury;
  1889.         _b = MyAbs(cury - begy);      // find b ->y axis radius
  1890.         _a = _b;
  1891.       }
  1892.       }
  1893.     else
  1894.       {
  1895.     _a = MyAbs(curx - begx);        // find a ->x axis radius
  1896.     _b = MyAbs(cury - begy);        // find b ->y axis radius
  1897.       }
  1898.  
  1899.     if ( (curx == begx) && (cury == begy) )       // draw point
  1900.       {
  1901.     _x = curx;
  1902.     _y = cury;
  1903.     FillGrid(_x, _y);
  1904.  
  1905.       }
  1906.     else if (_a == 0)
  1907.       {             // vertical line
  1908.     IconLine(begx, begy + (begy-cury), curx, cury);
  1909.       }
  1910.     else if (_b == 0)
  1911.       {             // horizonta line
  1912.     IconLine(begx + (begx-curx), begy, curx, cury);
  1913.       }
  1914.     else
  1915.       {
  1916.  
  1917.     _startval = -(int)_a;            // set start val for loop
  1918.     _endval = (int)_a;               // set end val for loop
  1919.  
  1920.     for (_x = _startval; _x <= _endval; _x++)   // walk down x axis
  1921.       {
  1922.         _y = Round( (float)sqrt( (float)(_b*_b) * // equation for elipse
  1923.         ( 1.0 - ((float)(_x*_x)/(float)(_a*_a)) ) ) );
  1924.         FillGrid(_x + begx, _y + begy);
  1925.         FillGrid(_x + begx, -_y + begy);
  1926.       }
  1927.  
  1928.     _startval = -(int)_b;               // set start val for loop
  1929.     _endval = (int)_b;                  // set end val for loop
  1930.  
  1931.     for (_y = _startval; _y <= _endval; _y++)   // walk down x axis
  1932.       {
  1933.         _x = Round( (float)sqrt( (float)(_a*_a) * // equation for elipse
  1934.         ( 1.0 - ((float)(_y*_y)/(float)(_b*_b)) ) ) );
  1935.         FillGrid(_x + begx, _y + begy);
  1936.         FillGrid(-_x + begx, _y + begy);
  1937.       }
  1938.       }
  1939.   }
  1940.  
  1941. //================>>> Picture::Picture <<<==============
  1942.   Picture::Picture(int width, int height)
  1943.   {
  1944.     // Allocate and Initialize the reset picture array with preset width and
  1945.     // height
  1946.  
  1947.     int i, j, k;
  1948.  
  1949.     for (i = 0 ; i < deflayers ; ++i)
  1950.     pixels[i] = new int[width*height];
  1951.  
  1952.     _width = width;
  1953.     _height = height;
  1954.     for (i = 0 ; i < deflayers ; i++)
  1955.       {
  1956.     for (j=0; j < _height; j++)
  1957.       {
  1958.         for (k=0; k < _width; k++)
  1959.           {
  1960.         seti(k, j, i, 1);       // initialize pixels to white
  1961.           }
  1962.       }
  1963.       }
  1964.   }
  1965.  
  1966. //==============>>> Picture::~Picture <<<================
  1967.   Picture::~Picture()
  1968.   {
  1969.      // Deallocate the picture array
  1970.      for (int i = 0 ; i < deflayers ; ++i)
  1971.     delete [] pixels[i];
  1972.   }
  1973.  
  1974. //=================>>> Picture::GetIndex <<<====================
  1975.   int Picture::GetIndex(int x, int y, int layer)
  1976.   {
  1977.      // Get the index to the color table of the specified pixel
  1978.  
  1979.      return (int) geti(x, y, layer);
  1980.   }
  1981.  
  1982. //================>>> Picture::SetIndex <<<=================
  1983.   void Picture::SetIndex(int x, int y, int layer, int index)
  1984.   {
  1985.      // Set the specified pixel with an index value from the color table
  1986.  
  1987.      seti(x, y, layer, index);
  1988.   }
  1989.  
  1990. //==================>>> Picture::GetPicWidth <<<===============
  1991.   int Picture::GetPicWidth()
  1992.   {
  1993.      // return the current width of the picture
  1994.  
  1995.     return _width;
  1996.   }
  1997.  
  1998. //==================>>> Picture::GetPicHeight <<<===============
  1999.   int Picture::GetPicHeight()
  2000.   {
  2001.      // return the current height of the picture
  2002.  
  2003.      return _height;
  2004.   }
  2005.  
  2006. //==================>>> Picture::Flatten <<<===============
  2007.   void Picture::Flatten()
  2008.   {
  2009.     // Copy the transparent layer (1) to the base layer (0) if a change has been made in
  2010.     // the top layer, -1 indicates no new changes have been made
  2011.  
  2012.     int i, j, value;
  2013.  
  2014.     for (i=0; i < _height; i++)
  2015.       {
  2016.     for (j=0; j < _width; j++)
  2017.       {
  2018.         value = geti(j, i, TransLayer);
  2019.         if (value != -1)
  2020.         seti(j, i, ImageLayer, value);
  2021.       }
  2022.       }
  2023.   }
  2024.  
  2025. //==================>>> Picture::Clear <<<===============
  2026.   void Picture::Clear(int layer, int thecolor)
  2027.   {
  2028.     // Reset given layer to new value in order to clear it. If top layer,
  2029.     // clear to null values to indicate no change.
  2030.     // If base layer, clear to white.
  2031.  
  2032.      int i, j, value;
  2033.  
  2034.      if (layer == ImageLayer)
  2035.         value = thecolor;    // if base layer then set to background
  2036.      else
  2037.         value = -1;             // if other layer then set to null
  2038.  
  2039.     for (i=0; i < _height; i++)
  2040.       {
  2041.     for (j=0; j < _width; j++)
  2042.       {
  2043.         seti(j, i, layer, value);       // reset pixels to value
  2044.       }
  2045.       }
  2046.   }
  2047.  
  2048. //==================>>> Color_Pal::Color_Pal <<<=======================
  2049.   Color_Pal::Color_Pal()
  2050.   {
  2051.     // setup the color palette
  2052.  
  2053.     init_Palette();
  2054.   }
  2055.  
  2056. //==================>>> Color_Pal::~Color_Pal <<<======================
  2057.   Color_Pal::~Color_Pal()
  2058.   {
  2059.     // destroy color palette instances
  2060.   }
  2061.  
  2062. //==================>>> Color_Pal::init_Palette <<<=======================
  2063.   void Color_Pal::init_Palette()
  2064.   {
  2065.     // setup the color palette
  2066.  
  2067. #include "paldecla.h"
  2068.     _colorsUsed = 64;
  2069.     _fg = 0;
  2070.     _bg = 1;
  2071.   }
  2072.  
  2073. //==================>>> Color_Pal::makefg <<<==========================
  2074.   void Color_Pal::makefg(int index)
  2075.   {
  2076.     //  make index as the foreground color
  2077.  
  2078.     _fg = index;
  2079.   }
  2080.  
  2081. //==================>>> Color_Pal::makebg <<<==========================
  2082.   void Color_Pal::makebg(int index)
  2083.   {
  2084.     //  make index as the background color
  2085.  
  2086.     _bg = index;
  2087.   }
  2088.  
  2089. //==================>>> Color_Pal::getfg <<<===========================
  2090.   int  Color_Pal::getfg()
  2091.   {  // get the current foreground color
  2092.  
  2093.   return _fg;
  2094.   }
  2095.  
  2096. //==================>>> Color_Pal::getbg <<<===========================
  2097.   int  Color_Pal::getbg()
  2098.   {  //  get current background color
  2099.  
  2100.   return _bg;
  2101.   }
  2102.  
  2103. //==================>>> myCanvasPane::setfg <<<========================
  2104.   void myCanvasPane::setfg(int index)
  2105.   {  //  set foreground color on the color palette
  2106.  
  2107.     _myColorPal->_fg = index;
  2108.     _cwin->SetFGBtn(_myColorPal->_Palette[index]);
  2109.  
  2110.   }
  2111.  
  2112. //==================>>> myCanvasPane::setbg <<<========================
  2113.   void myCanvasPane::setbg(int index)
  2114.   {  //  set background color on the color palette
  2115.  
  2116.     _myColorPal->_bg = index;
  2117.     _cwin->SetBGBtn(_myColorPal->_Palette[index]);
  2118.   }
  2119.  
  2120. //==================>>> myCanvasPane::getCurPenInd <<<================
  2121.   int myCanvasPane::getCurPenInd()
  2122.   {  //  get index of the curent foreground pen settings
  2123.  
  2124.     return _curPen;
  2125.   }
  2126.  
  2127. //==================>>> Color_Pal::getColor <<<=======================
  2128.   vColor  Color_Pal::getColor(int index)
  2129.   {  //  get color by given index number from the color palette
  2130.  
  2131.     return _Palette[index];
  2132.   }
  2133.  
  2134. //==================>>> myCanvasPane::setCurPenCol <<<================
  2135.   void  myCanvasPane::setCurPenCol(int index)
  2136.   {  //  set foreground to index number (current foreground color)
  2137.  
  2138.     _curPen = index;
  2139.   }
  2140.  
  2141. //==================>>> Color_Pal::setColor <<<=======================
  2142.   void Color_Pal::setColor(int index, vColor value)
  2143.   {  //  set color to index array location
  2144.  
  2145.     _Palette[index] = value;
  2146.   }
  2147.  
  2148. //==================>>> Color_Pal::setRed <<<=========================
  2149.   void Color_Pal::setRed(int index, int value)
  2150.   {  //  set red color value
  2151.  
  2152.     _Palette[index].SetR(value);
  2153.   }
  2154.  
  2155. //==================>>> Color_Pal::setGreen <<<=======================
  2156.   void Color_Pal::setGreen(int index, int value)
  2157.   {  //  set green color value
  2158.  
  2159.     _Palette[index].SetG(value);
  2160.   }
  2161.  
  2162. //==================>>> Color_Pal::setBlue <<<========================
  2163.   void Color_Pal::setBlue(int index, int value)
  2164.   {  //  set blue color value
  2165.  
  2166.     _Palette[index].SetB(value);
  2167.   }
  2168.