home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / sun / volume1 / palette / part02 / canvas.c next >
Encoding:
C/C++ Source or Header  |  1989-05-18  |  6.4 KB  |  243 lines

  1. /* 
  2.  * canvas.c - This module implements all the I/O to the palette canvas.  
  3.  *            This includes the color swatches, highlighting the current 
  4.  *            color(s), and determining the location of a mouse click.
  5.  *            
  6.  *            Exported routines:
  7.  *              MakePalette
  8.  *              SetPaletteSize
  9.  *              SavePalette
  10.  *              DrawPalette
  11.  *              WhichSwatch
  12.  *              HighlightSwatch
  13.  *              BoxSwatches
  14.  */
  15.  
  16. /**************************************************************************
  17.  *      palette - a colormap editor
  18.  *      Copyright (c) 1988 Wayne Mesard                                   *
  19.  *                                                                        *
  20.  *      This is free software.  It may be reproduced, retransmitted,      *
  21.  *      redistributed and otherwise propogated at will, provided that     *
  22.  *      no monetary profit is realized and that this notice remains       *
  23.  *      intact and in place.                                              *
  24.  *                                                                        *
  25.  *      Please direct bug reports, code enhancements and comments         *
  26.  *      to mesard@BBN.COM.                                                *
  27.  *                                                                        *
  28.  **************************************************************************/
  29.  
  30. #include <suntool/sunview.h>
  31. #include <suntool/canvas.h>
  32. #include <stdio.h>
  33.  
  34. #define Y_LOC(ENTRY) (y_edge + ((ENTRY)/powx)*edge)
  35. #define X_LOC(ENTRY) (x_edge + ((ENTRY)%powx)*edge)
  36.  
  37. static Canvas palette_canvas;
  38. static Pixwin *palette_pw;
  39.  
  40. static int palette_width, palette_height, x_edge, y_edge, edge;
  41. static unsigned int powx, powy;
  42.  
  43.  
  44. /* MakePalette - Sets module variables and returns the pixwin of the
  45.  *               canvas.  Must be called once before any other routines
  46.  *               in this module.  
  47.  */
  48.  
  49. Pixwin *MakePalette(canvas)
  50. Canvas canvas;
  51. {
  52.     return(palette_pw = canvas_pixwin(palette_canvas=canvas));
  53. }
  54.  
  55.  
  56.  
  57. /* 
  58.  * SetPaletteSize - Updates module variables.  Must be called when 
  59.  *                  canvas is resized.
  60.  */
  61.  
  62. void SetPaletteSize()
  63. {
  64.     palette_width = (int) window_get(palette_canvas, CANVAS_WIDTH);
  65.     palette_height = (int) window_get(palette_canvas, CANVAS_HEIGHT);
  66. }
  67.  
  68.  
  69.  
  70. /* 
  71.  * SavePalette - Given an open file pointer, creates a rasterfile image 
  72.  *               of the palette.
  73.  */
  74.  
  75. int SavePalette(fp, colormap)
  76. FILE *fp;
  77. colormap_t *colormap;
  78. {
  79.     return(pr_dump(palette_pw->pw_prretained, fp, colormap, RT_STANDARD, 0));
  80. }
  81.  
  82.  
  83. /* 
  84.  * DrawPalette - Given a number of colors, draw a recangle containing a 
  85.  *               square for each color.  The size of the rectangle 
  86.  *               should be maximal w.r.t. the size of the palette.  
  87.  *               (This procedure is greatly simplified by the fact that 
  88.  *               the width:height ratio is always a power of 2 (since 
  89.  *               the number of colors is always a power of 2.
  90.  */
  91.  
  92. void DrawPalette(n_colors)
  93. int n_colors;
  94. {
  95.     void DrawRect();
  96.     register int x, y;
  97.     int temp;
  98.     int x_max = palette_width;
  99.     int y_max = palette_height;
  100.  
  101.     edge = 0;
  102.     for (x = n_colors, y = 1; x; x >>= 1, y <<= 1) {
  103.     temp = ((x_max-8)/x < (y_max-8)/y ?
  104.          (x_max-8)/x : (y_max-8)/y);
  105.     if (temp > edge) {
  106.         powx = x;
  107.         powy = y;
  108.         edge = temp;
  109.     }
  110.     }
  111.     /* Note: a non-iterative algorithm for the above procedure exists,
  112.      * but it requires floating point arithmetic and mathlib routines.
  113.      * This is computationally more efficient, although less elegant.
  114.      */
  115.  
  116.     x_edge = (x_max - (powx*edge))/2;
  117.     y_edge = (y_max - (powy*edge))/2;
  118.  
  119.     pw_batch_on(palette_pw);
  120.     pw_writebackground(palette_pw, 0, 0, x_max, y_max, PIX_SRC | PIX_COLOR(0));
  121.  
  122.     x_max = x_edge + powx*edge;
  123.     y_max = y_edge + powy*edge;
  124.  
  125.     n_colors--;            /* So we don't have to compare n-1 */
  126.  
  127.     DrawRect(x_edge-2, y_edge-2, x_max, y_max, PIX_SRC, n_colors);
  128.  
  129.     for (temp = -1, y=y_edge; y < y_max; y += edge)
  130.     for (x=x_edge; x < x_max; x += edge) {
  131.         pw_writebackground(palette_pw, x, y, edge-1, edge-1,
  132.                    PIX_SRC | PIX_COLOR(++temp));
  133.     }
  134.     pw_batch_off(palette_pw);
  135. }
  136.  
  137.  
  138.  
  139. /*
  140.  * WhichSwatch - Find out which color is at specified position.  Return 
  141.  *               -1 if it's outside the rectangle.
  142.  *               
  143.  *               Can't simply look at the pixel value, since it might be
  144.  *               on the border, or adjacent to the currently selected
  145.  *               square (and therefore with that color's enlarge square
  146.  */
  147.  
  148. int WhichSwatch(x, y)
  149. int x, y;
  150. {
  151.     x = x-x_edge;
  152.     y = y-y_edge;
  153.     if (x < 0 || y < 0 || (x=x/edge) >= powx || (y=y/edge) >= powy)
  154.     return (-1);
  155.     else
  156.     return((y*powx)+x);
  157. }        
  158.  
  159.  
  160.  
  161. /*
  162.  * HighlightSwatch - Draw a big old square for the specified color. 
  163.  */
  164.  
  165. void HighlightSwatch(num, border_color)
  166. int num, border_color;
  167. {
  168.     void DrawRect();
  169.     int x, y;
  170.  
  171.     if (border_color > 2) {
  172.     y = Y_LOC(num);
  173.     x = X_LOC(num);
  174.  
  175.     pw_batch_on(palette_pw);
  176.     pw_writebackground(palette_pw, x-edge/2, y-edge/2, 2*edge, 2*edge,
  177.                PIX_SRC | PIX_COLOR(num));
  178.     DrawRect(x, y, x+edge, y+edge, PIX_SRC,
  179.          (num == border_color ? 0 : border_color));
  180.     pw_batch_off(palette_pw);
  181.  
  182.     }
  183. }
  184.  
  185.  
  186.  
  187. /* 
  188.  * BoxSwatches - Draw a border around the specified range of color squares.
  189.  */
  190.  
  191. void BoxSwatches(e1, e2)
  192. int e1, e2;
  193. {
  194.     void BoxRegion();
  195.     int temp;
  196.  
  197.     pw_batch_on(palette_pw);
  198.     /* Box the first row iff region doesn't start at col 0. */
  199.     if (e1 % powx && ((e2-e1 > powx) || (e2%powx < e1%powx))) {
  200.     temp = e1-(e1%powx)+powx-1;
  201.     BoxRegion(e1, temp);
  202.     e1 = temp+1;
  203.     }
  204.     /* Box the rows between the first and the last, if there are any. */
  205.     if (e2-e1 >= powx) {
  206.     temp = e2-(e2%powx)-1;
  207.     BoxRegion(e1, temp);
  208.     e1 = temp+1;
  209.     }
  210.     /* Box the partial row at the end, if there is one. */
  211.     if (e1 <= e2)
  212.     BoxRegion(e1, e2);
  213.     
  214.     pw_batch_off(palette_pw);
  215. }
  216.  
  217.  
  218.  
  219. /* 
  220.  * BoxRegion - Draw a rectangle whose upper left corner is at square e1 
  221.  *             and whose lower right is at e2.
  222.  */
  223.  
  224. static void BoxRegion(e1, e2)
  225. int e1, e2;
  226. {
  227.     void DrawRect();
  228.  
  229.     DrawRect(X_LOC(e1)-1, Y_LOC(e1)-1, X_LOC(e2)+edge-1, Y_LOC(e2)+edge-1, 
  230.          PIX_NOT(PIX_DST), 0);
  231. }
  232.  
  233.  
  234. static void DrawRect(x1, y1, x2, y2, op, color)
  235. int x1, y1, x2, y2, color;
  236. {
  237.     pw_vector(palette_pw, x1, y1, x2, y1, op, color);
  238.     pw_vector(palette_pw, x2,  y1, x2, y2,  op, color);
  239.     pw_vector(palette_pw, x2,  y2,  x1, y2, op, color);
  240.     pw_vector(palette_pw, x1, y2,  x1, y1, op, color);
  241. }
  242.  
  243.