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