]> www.wagner.pp.ru Git - oss/fgis.git/blob - dll/fgisEppDraw.c
7cd90174fe0fe18ecdff6092a011e161d02aad0e
[oss/fgis.git] / dll / fgisEppDraw.c
1 #include <tk.h>
2 #include <tcl.h>
3 #include <stdlib.h>
4 #include <reclass.h>
5 #include <epp.h>
6 #include "fgis.h"
7 #include "fgisInt.h"
8 unsigned short int *border_buffer1, *border_buffer2, *bbuf_ptr1, *bbuf_ptr2;
9
10 void init_border (int width, int offsite)
11 {
12     int i;
13     border_buffer1 = (unsigned short int *)Tcl_Alloc (
14                 (width + 1) * sizeof (unsigned short int));
15     border_buffer2 = (unsigned short int *)Tcl_Alloc (
16         (width + 1) * sizeof (unsigned  short int));
17     *border_buffer2 = offsite;
18     for (i = 0, bbuf_ptr1 = border_buffer1; i <= width; i++, bbuf_ptr1++)
19         *bbuf_ptr1 = offsite;
20 }
21 void new_border_row ()
22 {
23     unsigned short int *tmp;
24     tmp = border_buffer1;
25     border_buffer1 = border_buffer2;
26     border_buffer2 = tmp;
27     bbuf_ptr1 = border_buffer1;
28     bbuf_ptr2 = border_buffer2;
29
30 } int check_border (int class)
31 {
32     *(++bbuf_ptr1) = class;
33     bbuf_ptr2++;
34     return *bbuf_ptr2 != class || *(bbuf_ptr1 - 1) !=
35       class || *(bbuf_ptr2 - 1) != class;
36 }
37 void done_border ()
38 {
39     Tcl_Free ((char*)border_buffer1);
40     Tcl_Free ((char*)border_buffer2);
41 }
42 /*
43
44 òÉÓÕÅÔ ÕËÁÚÁÎÎÙÊ ËÕÓÏË ÒÁÓÔÒÁ (× ÁÌØÔÅÒÎÁÔÉ×ÎÙÈ ËÏÏÒÄÉÎÁÔÁÈ)
45 */ 
46
47 int Fgis_MakePhotoImage (Tk_PhotoHandle imghandle,
48                        int xl, int yb, int xr, int yt,
49                        double XL, double XR, double YT, double YB,
50                        RASTER_OBJECT handle,
51                        int border,/* 0 - ÎÉÞÅÇÏ, 1, ÐÒÉ ÎÅÓÏ×ÐÁÄÅÎÉÉ
52                                      Ã×ÅÔÏ× ÐÏÓÌÅ ÒÅËÌÁÓÓÁ,
53                                      2 - ÐÒÉ ÎÅÓÏ×ÐÁÄÅÎÉÉ Ã×ÅÔÏ× 
54                                            ÂÁÚÏ×ÏÇÏ ÒÁÓÔÒÁ
55                                  */
56                       PALETTE palette,
57                       int bordercolor,
58                       int mapmode       /* 0 - wrap (x&0xFF), -1 x>255?255:x,
59                                            >0 map
60                                          */
61                     )
62 {
63     Tk_PhotoImageBlock block =
64     {NULL, 0, 1, 1000, 4,
65 #ifdef LSB_FIRST
66      {2, 1, 0}
67 #else
68      {1, 2, 3}
69 #endif
70     };
71
72     EPP *e = epp (handle);
73     RECLASS r = handle->reclass;
74     int width = xr - xl, height = yb - yt;
75     int *irow, *rp;
76     int *pal;
77     int *coltab, *col;
78     double W_Alt = XR - XL, H_Alt = YB - YT;
79     int x, y, row, i, j, maxclass=0;
80     int max_base_class;
81     int base  ;
82 /*
83    ÜÔÏ ÂÕÆÅÒ ÄÌÑ ÈÒÁÎÅÎÉÑ ÐÒÏÒÉÓÏ×ÁÎÎÏÊ ÓÔÒÏËÉ 
84  */
85     irow =(int *) Tcl_Alloc (width * sizeof (int));
86     max_base_class = epp_table_size (e) + 1;
87 /*
88    íÁÓÓÉ× ×ÈÏÄÏ× × ÐÁÌÉÔÒÕ ÄÌÑ ËÌÁÓÓÏ× ÂÁÚÏ×ÏÇÏ ÒÁÓÔÒÁ 
89  */
90     pal = (int *)Tcl_Alloc(max_base_class * sizeof (int));
91     if (mapmode > 0)
92         maxclass = Fgis_RasterMax (handle);
93     for (i = 0; i < max_base_class; i++) {
94         int index;
95         index = r[i];
96         if (index > 255)
97             switch (mapmode) {
98             case 0:
99                 index &= 0xFF;
100                 break;          /*
101                                    wrap 
102                                  */
103             case -1:
104                 index = 255;
105                 break;          /*
106                                    no wrap
107                                  */
108             default:
109                 index = index * mapmode / maxclass;
110                 if (i == e->offsite)
111                     index = 255;
112               
113             }
114         pal[i] = palette[index];
115       if (i!= e->offsite) 
116        pal[i]|=0xff000000;
117     }   
118  /*
119    ÜÔÏ ÔÁÂÌÉÃÁ ÐÏÒÑÄËÏ×ÙÈ ÎÏÍÅÒÏ× ËÏÌÏÎÏË × epp-ÆÁÊÌÅ, ÓÏÏÔ×ÅÔÓÔ×ÕÀÝÉÈ
120    ÐÉËÓÅÌÁÍ ÒÁÓÔÒÁ 
121  */
122     coltab =(int *) Tcl_Alloc (width * sizeof (int));
123     for (i = xl, col = coltab, j = 0; i < xr; i++, j++, col++) {
124         *col = epp_col (e, W_Alt * (j + 0.5) / width + XL);
125     }
126 /*
127    úÁÐÏÌÎÉÍ ÔÅ ÐÏÌÑ ÓÔÒÕËÔÕÒÙ block, ËÏÔÏÒÙÅ ÍÙ ÎÅ ÍÏÇÌÉ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ 
128  */
129     block.pixelPtr = (unsigned char *) irow;
130     block.width = width;
131     block.pitch = width * sizeof (int);
132     if (border) {
133         if (border == 1)
134             init_border (width, r[e->offsite]);
135         else
136             init_border (width, e->offsite);
137     }
138     /* ðÏÞÉÓÔÉÍ image */
139     Tk_PhotoBlank(imghandle);
140     for (y = yt, i = 0; y < yb; y++, i++) {
141         row = epp_row (e, H_Alt * (i + 0.5) / height + YT);
142         if (border)
143             new_border_row ();
144         for (x = xl, j = 0, col = coltab, rp = irow; x < xr;
145                 j++, col++, rp++, x++) {
146             base = epp_get (e, *col, row);
147             if (border) {
148                 if (border == 1 ? check_border (r[base]) :
149                         check_border (base)) {
150                     *rp = bordercolor;
151                     continue;
152                 }
153             }
154             *rp = pal[base];
155         }
156         Tk_PhotoPutBlock (imghandle, &block, xl, y, width, 1);
157     }
158     done_border ();
159     Tcl_Free ((char *)pal);
160     Tcl_Free ((char *)irow);
161     Tcl_Free ((char *)coltab);
162     return TCL_OK;
163
164 }
165
166 void Fgis_PlotPatterns(Tcl_Interp *interp,
167          char *bitmap_image,
168          int xl,int yb,int xr,int yt,
169          double XL, double XR,double YT,double YB,
170          RASTER_OBJECT handle,
171          int bordermode, PATTERNS patterns,XColor* color,int mapmode)
172 { /* NOT IMPLEMENTED YET */      
173
174 void  Fgis_PlotSymbols(Tcl_Interp *interp,
175                 char *bitmap_image,
176                 int xl,int yb,int xr,int yt,
177                 double XL,double XR,double  YT,double  YB,
178                 RASTER_OBJECT handle,
179                 PATTERNS patterns, XColor* color,
180                 int mapmode)
181 { /*NOT IMPLEMENTED YET*/
182
183 }
184 /*
185  * Fgis_RasterImage
186  * - implementation of command fgisRasterColorImage and
187  * fgisRasterBWImage
188  */
189 EXPORT(int, Fgis_RasterImage) (ClientData data, Tcl_Interp *interp, 
190       int argc, char **argv)
191 {
192   int listc; char **listv; /* for parsing result of $planchet bbox $item */
193   Tk_PhotoHandle imghandle=NULL;
194   int colorplot=(int)data; /* how to distinguish between color and bw */
195   char *bitmap_image=NULL;
196   enum {PATTERNS_MODE,SYMBOLS_MODE} symbolmode=PATTERNS_MODE;
197   int mapmode=0;
198   int bordercolor=0;
199   int bordermode=((int)data)?0:1;
200   PATTERNS patterns=NULL;
201   PALETTE palette=default_palette;
202   RASTER_OBJECT raster;
203   int i;
204   int xl=0,yt=0,xr,yb,imgstartx,imgstarty;
205   double XL,YT,XR,YB; 
206   XColor *clr;
207   Tk_Window canvas=Tk_NameToWindow(interp,argv[2],Tk_MainWindow(interp));
208   
209   clr=Tk_GetColor(interp,canvas,"black");
210     if (Fgis_CkArgs(interp,argc<5,
211             argv[0],"raster planchet item ?options?"))
212      return TCL_ERROR;
213     if (!Fgis_ValidPlanchet(interp,argv[2]))     
214          return TCL_ERROR;
215     if (Tcl_VarEval(interp,argv[2]," bbox ",argv[3],NULL)!=TCL_OK) 
216          return TCL_ERROR;
217     if (Tcl_SplitList(interp,interp->result,&listc,&listv)!=TCL_OK) 
218          return TCL_ERROR;
219     imgstartx=atol(listv[0]);
220     imgstarty=atol(listv[1]);
221     xr=atol(listv[2]);
222     yb=atol(listv[3]);
223     XL=Fgis_AltX(interp,argv[2],imgstartx);
224     XR=Fgis_AltX(interp,argv[2],xr+1);
225     YT=Fgis_AltY(interp,argv[2],imgstarty);
226     YB=Fgis_AltY(interp,argv[2],yb+1);
227     xr-=imgstartx;
228     yb-=imgstarty;
229     Tcl_Free((char *)listv);
230     if (Tcl_VarEval(interp,argv[2]," itemcget ",argv[3]," -image",NULL)!=TCL_OK)
231          return TCL_ERROR;
232     if (colorplot) {     
233         imghandle=Tk_FindPhoto(interp,interp->result);
234         if (!imghandle) {
235            Tcl_AppendResult(interp,"No valid image for item ",argv[3],
236                        " in planchet ", argv[2],NULL);
237            return TCL_ERROR;
238         }   
239     } else {
240         if (interp->result)
241            bitmap_image=stralloc(interp->result);
242         else {   
243            Tcl_AppendResult(interp,"No valid image for item ",argv[3],
244                        " in planchet ", argv[2],NULL);
245            return TCL_ERROR;
246         }   
247     }   
248     raster=Fgis_GetRaster(interp,argv[1]);
249     if (!raster) {
250        Tcl_AppendResult(interp,argv[1]," is not valid raster",NULL);
251        return TCL_ERROR;
252     }   
253
254 for(i=4;i<argc;i++) { 
255     if (!strcmp(argv[i],"-palette")&&colorplot) {
256         if(!(palette=Fgis_GetPalette(interp,argv[++i])))
257             return TCL_ERROR;
258     } else if (!strcmp(argv[i],"-patterns")&&!colorplot) {
259         if(!(patterns=Fgis_GetPatterns(interp,argv[++i])))
260            return TCL_ERROR;
261         symbolmode=PATTERNS_MODE;
262     } else if (!strcmp(argv[i],"-symbols")&&!colorplot) {
263        if (!(patterns=Fgis_GetPatterns(interp,argv[++i])))
264            return TCL_ERROR;
265        symbolmode=SYMBOLS_MODE;
266        bordermode=0;
267     } else if (!strcmp(argv[i],"-border")) { 
268         if (i<argc-1) {
269           i++;
270           if (!strcmp(argv[i],"base")) {
271               bordermode=2;
272           } else if (!strcmp(argv[i],"yes")) {
273               bordermode=1;
274           } else if (!strcmp(argv[i],"none")) {
275               bordermode=0;
276           } else if (argv[i][0]=='-') {
277           /* -border without parameter decrease i */
278               bordermode=1;
279               i--;
280          } else { 
281            Tcl_SetResult(interp,"Invalid border option. Should be one "
282                   "of none, yes, base",TCL_STATIC);
283            return TCL_ERROR;
284         }
285       } else {
286           bordermode=1;
287       }   
288    } else
289    if (!strcmp(argv[i],"-color")) { 
290         clr=Tk_GetColor(interp,canvas,argv[++i]);
291         if (!clr) return TCL_ERROR;
292         /* What range have XColor fields? */
293         if (colorplot) {
294            bordercolor=((clr->red&0xff)<<16)|((clr->green&0xff)<<8)|
295                    (clr->blue&0xff);
296         }
297     } else
298     if (!strcmp(argv[i],"-map")) { 
299         if (mapmode) 
300             ERROR_MESSAGE("Duplicate color remapping specification",TCL_STATIC);
301         i++;
302         if (!strcmp(argv[i],"wrap")) {
303            mapmode=0;
304         } else 
305        if (!strcmp(argv[i],"none")) {
306            mapmode=-1;
307        } else 
308        if (Fgis_GetInt(interp, argc, argv, ++i, 0, 256, &mapmode,
309             "color index") !=TCL_OK) {
310           return TCL_ERROR;
311        }   
312     } else
313     if (!strcmp(argv[i],"-update")) {
314         double X1,Y1,X2,Y2;
315         int x1,y1,x2,y2;
316         if (++i==argc)
317            ERROR_MESSAGE("List of four doubles expected",TCL_STATIC);
318         if (Fgis_GetLimits(interp,argv[i],&X1,&Y1,&X2,&Y2)!=TCL_OK)
319            return TCL_ERROR;
320         x1=Fgis_PlanchetX(interp,argv[2],X1)-imgstartx;
321         x2=Fgis_PlanchetX(interp,argv[2],X2)-imgstartx;
322         if (x2<x1) {
323             int t;
324             t=x1;x1=x2;x2=t;
325         }
326         if (x1>0) {xl=x1;XL=Fgis_AltX(interp,argv[2],x1+imgstartx);}
327         if (x2<xr) {xr=x2;XR=Fgis_AltX(interp,argv[2],x2+1+imgstartx);}
328         y1=Fgis_PlanchetY(interp,argv[2],Y1)-imgstarty;
329         y2=Fgis_PlanchetY(interp,argv[2],Y2)-imgstarty;
330         if (y2<y1) {
331             int t;
332             t=y1;y1=y2;y2=t;
333         }
334         if (y1>0) {yt=y1;YT=Fgis_AltY(interp,argv[2],y1+imgstarty);}
335         if (y2<yb) {yb=y2;YB=Y2;Fgis_AltY(interp,argv[2],y2+1+imgstarty);}
336  
337     } else {
338        Tcl_ResetResult(interp);
339        Tcl_AppendResult(interp,"Invalid option.\"",argv[i],
340         "\" Should be one of -border, -bordercolor, -map, ",
341           NULL);
342        if (colorplot) 
343           Tcl_AppendResult(interp,"-palette",NULL);
344        else
345           Tcl_AppendResult(interp,"-patterns, -symbols",NULL);
346        Tcl_AppendResult(interp,", -update",NULL);
347        return TCL_ERROR;
348     }    
349           
350 }
351
352 if (colorplot) {
353   Fgis_MakePhotoImage(imghandle,xl,yb,xr,yt,XL,XR,YT,YB,raster,bordermode,
354                  palette,bordercolor,mapmode);
355 } else 
356 if (symbolmode==PATTERNS_MODE) {
357   Fgis_PlotPatterns(interp,bitmap_image,xl,yb,xr,yt,XL,XR,YT,YB,raster,
358    bordermode, patterns,clr,mapmode);
359 } else {
360   Fgis_PlotSymbols(interp,bitmap_image,xl,yb,xr,yt,XL,XR,YT,YB,raster,
361     patterns, clr, mapmode);
362 }    
363 return TCL_OK;
364 }