/[zanavi_public1]/navit/navit/graphics.c
ZANavi

Contents of /navit/navit/graphics.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 27 - (hide annotations) (download)
Mon Apr 9 21:27:36 2012 UTC (12 years ago) by zoff99
File MIME type: text/plain
File size: 86746 byte(s)
lots of new stuff, tranlsations, bug fixes ...
1 zoff99 2 /**
2 zoff99 27 * ZANavi, Zoff Android Navigation system.
3     * Copyright (C) 2011-2012 Zoff <zoff@zoff.cc>
4     *
5     * This program is free software; you can redistribute it and/or
6     * modify it under the terms of the GNU General Public License
7     * version 2 as published by the Free Software Foundation.
8     *
9     * This program is distributed in the hope that it will be useful,
10     * but WITHOUT ANY WARRANTY; without even the implied warranty of
11     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12     * GNU General Public License for more details.
13     *
14     * You should have received a copy of the GNU General Public License
15     * along with this program; if not, write to the
16     * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17     * Boston, MA 02110-1301, USA.
18     */
19    
20     /**
21 zoff99 2 * Navit, a modular navigation system.
22     * Copyright (C) 2005-2008 Navit Team
23     *
24     * This program is free software; you can redistribute it and/or
25     * modify it under the terms of the GNU General Public License
26     * version 2 as published by the Free Software Foundation.
27     *
28     * This program is distributed in the hope that it will be useful,
29     * but WITHOUT ANY WARRANTY; without even the implied warranty of
30     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31     * GNU General Public License for more details.
32     *
33     * You should have received a copy of the GNU General Public License
34     * along with this program; if not, write to the
35     * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
36     * Boston, MA 02110-1301, USA.
37     */
38    
39     //##############################################################################################################
40     //#
41     //# File: graphics.c
42     //# Description:
43     //# Comment:
44     //# Authors: Martin Schaller (04/2008)
45     //#
46     //##############################################################################################################
47    
48     #include <stdlib.h>
49     #include <glib.h>
50     #include <stdio.h>
51     #include <math.h>
52     #include "config.h"
53     #include "debug.h"
54     #include "string.h"
55     #include "draw_info.h"
56     #include "point.h"
57     #include "graphics.h"
58     #include "projection.h"
59     #include "item.h"
60     #include "map.h"
61     #include "coord.h"
62     #include "transform.h"
63     #include "plugin.h"
64     #include "profile.h"
65     #include "mapset.h"
66     #include "layout.h"
67     #include "route.h"
68     #include "util.h"
69     #include "callback.h"
70     #include "file.h"
71     #include "event.h"
72     //
73     #include "attr.h"
74     #include "navit.h"
75 zoff99 27 #include "route.h"
76 zoff99 2
77     //##############################################################################################################
78     //# Description:
79     //# Comment:
80     //# Authors: Martin Schaller (04/2008)
81     //##############################################################################################################
82    
83     // above what "order" level to show only prerendered map
84     #define ORDER_USE_PRERENDERED_MAP 0
85    
86     struct graphics
87     {
88     struct graphics_priv *priv;
89     struct graphics_methods meth;
90     char *default_font;
91     int font_len;
92     struct graphics_font **font;
93     struct graphics_gc *gc[3];
94     struct attr **attrs;
95     struct callback_list *cbl;
96     struct point_rect r;
97 zoff99 27 int gamma, brightness, contrast;
98 zoff99 2 int colormgmt;
99     int font_size;
100     GList *selection;
101     };
102    
103    
104 zoff99 27 /*
105     struct display_context
106     {
107     struct graphics *gra;
108     struct element *e;
109     struct graphics_gc *gc;
110     struct graphics_gc *gc_background;
111     struct graphics_image *img;
112     enum projection pro;
113     int mindist;
114     struct transformation *trans;
115     enum item_type type;
116     int maxlen;
117     };
118 zoff99 2
119 zoff99 27 #define HASH_SIZE 1024
120     */
121 zoff99 2
122 zoff99 27 /*
123     struct hash_entry
124     {
125     enum item_type type;
126     struct displayitem *di;
127     };
128     */
129 zoff99 2
130 zoff99 27 /*
131     struct displaylist {
132     int busy;
133     int workload;
134     struct callback *cb;
135     struct layout *layout, *layout_hashed;
136     struct display_context dc;
137     int order, order_hashed, max_offset;
138     struct mapset *ms;
139     struct mapset_handle *msh;
140     struct map *m;
141     int conv;
142     struct map_selection *sel;
143     struct map_rect *mr;
144     struct callback *idle_cb;
145     struct event_idle *idle_ev;
146     unsigned int seq;
147     struct hash_entry hash_entries[HASH_SIZE];
148     };
149     */
150 zoff99 2
151 zoff99 27 struct displaylist_icon_cache
152     {
153 zoff99 2 unsigned int seq;
154    
155     };
156    
157     /**
158     * FIXME
159     * @param <>
160     * @returns <>
161     * @author Martin Schaller (04/2008)
162 zoff99 27 */
163     struct displayitem
164     {
165 zoff99 2 struct displayitem *next;
166     struct item item;
167     char *label;
168     int count;
169     struct coord c[0];
170     };
171    
172     static void draw_circle(struct point *pnt, int diameter, int scale, int start, int len, struct point *res, int *pos, int dir);
173     static void graphics_process_selection(struct graphics *gra, struct displaylist *dl);
174     static void graphics_gc_init(struct graphics *this_);
175    
176 zoff99 27 static void clear_hash(struct displaylist *dl)
177 zoff99 2 {
178     int i;
179 zoff99 27 for (i = 0; i < HASH_SIZE_GRAPHICS_; i++)
180     dl->hash_entries[i].type = type_none;
181 zoff99 2 }
182    
183     static struct hash_entry *
184     get_hash_entry(struct displaylist *dl, enum item_type type)
185     {
186 zoff99 27 int hashidx = (type * 2654435761UL) & (HASH_SIZE_GRAPHICS_ - 1);
187     int offset = dl->max_offset;
188     do
189     {
190 zoff99 2 if (!dl->hash_entries[hashidx].type)
191 zoff99 27 {
192 zoff99 2 return NULL;
193 zoff99 27 }
194 zoff99 2 if (dl->hash_entries[hashidx].type == type)
195 zoff99 27 {
196 zoff99 2 return &dl->hash_entries[hashidx];
197 zoff99 27 }
198     hashidx = (hashidx + 1) & (HASH_SIZE_GRAPHICS_ - 1);
199     }
200    
201     while (offset-- > 0);
202    
203 zoff99 2 return NULL;
204     }
205    
206     static struct hash_entry *
207     set_hash_entry(struct displaylist *dl, enum item_type type)
208     {
209 zoff99 27 int hashidx = (type * 2654435761UL) & (HASH_SIZE_GRAPHICS_ - 1);
210     int offset = 0;
211     for (;;)
212     {
213     if (!dl->hash_entries[hashidx].type)
214     {
215     dl->hash_entries[hashidx].type = type;
216 zoff99 2 if (dl->max_offset < offset)
217 zoff99 27 dl->max_offset = offset;
218 zoff99 2 return &dl->hash_entries[hashidx];
219     }
220     if (dl->hash_entries[hashidx].type == type)
221     return &dl->hash_entries[hashidx];
222 zoff99 27 hashidx = (hashidx + 1) & (HASH_SIZE_GRAPHICS_ - 1);
223 zoff99 2 offset++;
224     }
225     return NULL;
226     }
227    
228 zoff99 27 static int graphics_set_attr_do(struct graphics *gra, struct attr *attr)
229 zoff99 2 {
230 zoff99 27 switch (attr->type)
231     {
232     case attr_gamma:
233     gra->gamma = attr->u.num;
234     break;
235     case attr_brightness:
236     gra->brightness = attr->u.num;
237     break;
238     case attr_contrast:
239     gra->contrast = attr->u.num;
240     break;
241     case attr_font_size:
242     gra->font_size = attr->u.num;
243     return 1;
244     default:
245     return 0;
246 zoff99 2 }
247 zoff99 27 gra->colormgmt = (gra->gamma != 65536 || gra->brightness != 0 || gra->contrast != 65536);
248 zoff99 2 graphics_gc_init(gra);
249     return 1;
250     }
251    
252 zoff99 27 int graphics_set_attr(struct graphics *gra, struct attr *attr)
253 zoff99 2 {
254 zoff99 27 int ret = 1;
255     // //DBG dbg(0,"enter\n");
256 zoff99 2 if (gra->meth.set_attr)
257 zoff99 27 ret = gra->meth.set_attr(gra->priv, attr);
258 zoff99 2 if (!ret)
259 zoff99 27 ret = graphics_set_attr_do(gra, attr);
260     return ret != 0;
261 zoff99 2 }
262    
263 zoff99 27 void graphics_set_rect(struct graphics *gra, struct point_rect *pr)
264 zoff99 2 {
265 zoff99 27 gra->r = *pr;
266 zoff99 2 }
267    
268     /**
269     * Creates a new graphics object
270     * attr type required
271     * @param <>
272     * @returns <>
273     * @author Martin Schaller (04/2008)
274 zoff99 27 */
275 zoff99 2 struct graphics * graphics_new(struct attr *parent, struct attr **attrs)
276     {
277     struct graphics *this_;
278 zoff99 27 struct attr *type_attr;
279 zoff99 2 struct graphics_priv * (*graphicstype_new)(struct navit *nav, struct graphics_methods *meth, struct attr **attrs, struct callback_list *cbl);
280    
281 zoff99 27 if (!(type_attr = attr_search(attrs, NULL, attr_type)))
282     {
283     return NULL;
284     }
285 zoff99 2
286 zoff99 27 graphicstype_new = plugin_get_graphics_type(type_attr->u.str);
287     if (!graphicstype_new)
288     {
289 zoff99 2 return NULL;
290 zoff99 27 }
291    
292 zoff99 2 this_=g_new0(struct graphics, 1);
293 zoff99 27 this_->cbl = callback_list_new();
294     this_->priv = (*graphicstype_new)(parent->u.navit, &this_->meth, attrs, this_->cbl);
295     this_->attrs = attr_list_dup(attrs);
296     this_->brightness = 0;
297     this_->contrast = 65536;
298     this_->gamma = 65536;
299     this_->font_size = 20;
300    
301     while (*attrs)
302     {
303     graphics_set_attr_do(this_, *attrs);
304 zoff99 2 attrs++;
305     }
306 zoff99 27
307 zoff99 2 return this_;
308     }
309    
310     /**
311     * FIXME
312     * @param <>
313     * @returns <>
314     * @author Martin Schaller (04/2008)
315 zoff99 27 */
316 zoff99 2 int graphics_get_attr(struct graphics *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter)
317     {
318     return attr_generic_get_attr(this_->attrs, NULL, type, attr, iter);
319     }
320    
321     /**
322     * FIXME
323     * @param <>
324     * @returns <>
325     * @author Martin Schaller (04/2008)
326 zoff99 27 */
327 zoff99 2 struct graphics * graphics_overlay_new(struct graphics *parent, struct point *p, int w, int h, int alpha, int wraparound)
328     {
329     struct graphics *this_;
330     struct point_rect pr;
331     if (!parent->meth.overlay_new)
332 zoff99 27 return NULL;this_=g_new0(struct graphics, 1);
333     this_->priv = parent->meth.overlay_new(parent->priv, &this_->meth, p, w, h, alpha, wraparound);
334     pr.lu.x = 0;
335     pr.lu.y = 0;
336     pr.rl.x = w;
337     pr.rl.y = h;
338     this_->font_size = 20;
339 zoff99 2 graphics_set_rect(this_, &pr);
340 zoff99 27 if (!this_->priv)
341     {
342 zoff99 2 g_free(this_);
343 zoff99 27 this_ = NULL;
344 zoff99 2 }
345     return this_;
346     }
347    
348     /**
349     * @brief Alters the size, position, alpha and wraparound for an overlay
350     *
351     * @param this_ The overlay's graphics struct
352     * @param p The new position of the overlay
353     * @param w The new width of the overlay
354     * @param h The new height of the overlay
355     * @param alpha The new alpha of the overlay
356     * @param wraparound The new wraparound of the overlay
357     */
358 zoff99 27 void graphics_overlay_resize(struct graphics *this_, struct point *p, int w, int h, int alpha, int wraparound)
359 zoff99 2 {
360 zoff99 27 if (!this_->meth.overlay_resize)
361     {
362 zoff99 2 return;
363     }
364    
365     this_->meth.overlay_resize(this_->priv, p, w, h, alpha, wraparound);
366     }
367    
368 zoff99 27 static void graphics_gc_init(struct graphics *this_)
369 zoff99 2 {
370 zoff99 27 struct color background =
371     { COLOR_BACKGROUND_ };
372     struct color black =
373     { COLOR_BLACK_ };
374     struct color white =
375     { COLOR_WHITE_ };
376 zoff99 2 if (!this_->gc[0] || !this_->gc[1] || !this_->gc[2])
377     return;
378 zoff99 27 graphics_gc_set_background(this_->gc[0], &background);
379     graphics_gc_set_foreground(this_->gc[0], &background);
380     graphics_gc_set_background(this_->gc[1], &black);
381     graphics_gc_set_foreground(this_->gc[1], &white);
382     graphics_gc_set_background(this_->gc[2], &white);
383     graphics_gc_set_foreground(this_->gc[2], &black);
384 zoff99 2 }
385    
386     /**
387     * FIXME
388     * @param <>
389     * @returns <>
390     * @author Martin Schaller (04/2008)
391 zoff99 27 */
392 zoff99 2 void graphics_init(struct graphics *this_)
393     {
394     if (this_->gc[0])
395     return;
396 zoff99 27 this_->gc[0] = graphics_gc_new(this_);
397     this_->gc[1] = graphics_gc_new(this_);
398     this_->gc[2] = graphics_gc_new(this_);
399 zoff99 2 graphics_gc_init(this_);
400     graphics_background_gc(this_, this_->gc[0]);
401     }
402    
403     /**
404     * FIXME
405     * @param <>
406     * @returns <>
407     * @author Martin Schaller (04/2008)
408 zoff99 27 */
409 zoff99 2 void * graphics_get_data(struct graphics *this_, const char *type)
410     {
411     return (this_->meth.get_data(this_->priv, type));
412     }
413    
414     void graphics_add_callback(struct graphics *this_, struct callback *cb)
415     {
416     callback_list_add(this_->cbl, cb);
417     }
418    
419     void graphics_remove_callback(struct graphics *this_, struct callback *cb)
420     {
421     callback_list_remove(this_->cbl, cb);
422     }
423    
424     /**
425     * FIXME
426     * @param <>
427     * @returns <>
428     * @author Martin Schaller (04/2008)
429 zoff99 27 */
430 zoff99 2 struct graphics_font * graphics_font_new(struct graphics *gra, int size, int flags)
431     {
432     struct graphics_font *this_;
433    
434     this_=g_new0(struct graphics_font,1);
435 zoff99 27 this_->priv = gra->meth.font_new(gra->priv, &this_->meth, gra->default_font, size, flags);
436 zoff99 2 return this_;
437     }
438    
439     struct graphics_font * graphics_named_font_new(struct graphics *gra, char *font, int size, int flags)
440     {
441     struct graphics_font *this_;
442    
443     this_=g_new0(struct graphics_font,1);
444 zoff99 27 this_->priv = gra->meth.font_new(gra->priv, &this_->meth, font, size, flags);
445 zoff99 2 return this_;
446     }
447    
448     /**
449     * Destroy graphics
450     * Called when navit exits
451     * @param gra The graphics instance
452     * @returns nothing
453     * @author David Tegze (02/2011)
454     */
455     void graphics_free(struct graphics *gra)
456     {
457     if (!gra)
458     return;
459     gra->meth.graphics_destroy(gra->priv);
460     g_free(gra->default_font);
461     graphics_font_destroy_all(gra);
462     g_free(gra);
463     }
464    
465     /**
466     * Free all loaded fonts.
467     * Used when switching layouts.
468     * @param gra The graphics instance
469     * @returns nothing
470     * @author Sarah Nordstrom (05/2008)
471     */
472     void graphics_font_destroy_all(struct graphics *gra)
473     {
474     int i;
475 zoff99 27 for (i = 0; i < gra->font_len; i++)
476     {
477     if (!gra->font[i])
478     continue;
479     gra->font[i]->meth.font_destroy(gra->font[i]->priv);
480     gra->font[i] = NULL;
481 zoff99 2 }
482     }
483    
484     /**
485     * FIXME
486     * @param <>
487     * @returns <>
488     * @author Martin Schaller (04/2008)
489 zoff99 27 */
490 zoff99 2 struct graphics_gc * graphics_gc_new(struct graphics *gra)
491     {
492     struct graphics_gc *this_;
493    
494     this_=g_new0(struct graphics_gc,1);
495 zoff99 27 this_->priv = gra->meth.gc_new(gra->priv, &this_->meth);
496     this_->gra = gra;
497 zoff99 2 return this_;
498     }
499    
500     /**
501     * FIXME
502     * @param <>
503     * @returns <>
504     * @author Martin Schaller (04/2008)
505 zoff99 27 */
506 zoff99 2 void graphics_gc_destroy(struct graphics_gc *gc)
507     {
508     gc->meth.gc_destroy(gc->priv);
509     g_free(gc);
510     }
511    
512 zoff99 27 static void graphics_convert_color(struct graphics *gra, struct color *in, struct color *out)
513 zoff99 2 {
514 zoff99 27 *out = *in;
515     if (gra->brightness)
516     {
517     out->r += gra->brightness;
518     out->g += gra->brightness;
519     out->b += gra->brightness;
520 zoff99 2 }
521 zoff99 27 if (gra->contrast != 65536)
522     {
523     out->r = out->r * gra->contrast / 65536;
524     out->g = out->g * gra->contrast / 65536;
525     out->b = out->b * gra->contrast / 65536;
526 zoff99 2 }
527     if (out->r < 0)
528 zoff99 27 out->r = 0;
529 zoff99 2 if (out->r > 65535)
530 zoff99 27 out->r = 65535;
531 zoff99 2 if (out->g < 0)
532 zoff99 27 out->g = 0;
533 zoff99 2 if (out->g > 65535)
534 zoff99 27 out->g = 65535;
535 zoff99 2 if (out->b < 0)
536 zoff99 27 out->b = 0;
537 zoff99 2 if (out->b > 65535)
538 zoff99 27 out->b = 65535;
539     if (gra->gamma != 65536)
540     {
541     out->r = pow(out->r / 65535.0, gra->gamma / 65536.0) * 65535.0;
542     out->g = pow(out->g / 65535.0, gra->gamma / 65536.0) * 65535.0;
543     out->b = pow(out->b / 65535.0, gra->gamma / 65536.0) * 65535.0;
544 zoff99 2 }
545     }
546    
547     /**
548     * FIXME
549     * @param <>
550     * @returns <>
551     * @author Martin Schaller (04/2008)
552 zoff99 27 */
553 zoff99 2 void graphics_gc_set_foreground(struct graphics_gc *gc, struct color *c)
554     {
555     struct color cn;
556 zoff99 27 if (gc->gra->colormgmt)
557     {
558 zoff99 2 graphics_convert_color(gc->gra, c, &cn);
559 zoff99 27 c = &cn;
560 zoff99 2 }
561     gc->meth.gc_set_foreground(gc->priv, c);
562     }
563    
564     /**
565     * FIXME
566     * @param <>
567     * @returns <>
568     * @author Martin Schaller (04/2008)
569 zoff99 27 */
570 zoff99 2 void graphics_gc_set_background(struct graphics_gc *gc, struct color *c)
571     {
572     struct color cn;
573 zoff99 27 if (gc->gra->colormgmt)
574     {
575 zoff99 2 graphics_convert_color(gc->gra, c, &cn);
576 zoff99 27 c = &cn;
577 zoff99 2 }
578     gc->meth.gc_set_background(gc->priv, c);
579     }
580    
581     /**
582     * FIXME
583     * @param <>
584     * @returns <>
585     * @author Martin Schaller (04/2008)
586 zoff99 27 */
587 zoff99 2 void graphics_gc_set_stipple(struct graphics_gc *gc, struct graphics_image *img)
588     {
589     gc->meth.gc_set_stipple(gc->priv, img ? img->priv : NULL);
590     }
591    
592     /**
593     * FIXME
594     * @param <>
595     * @returns <>
596     * @author Martin Schaller (04/2008)
597 zoff99 27 */
598 zoff99 2 void graphics_gc_set_linewidth(struct graphics_gc *gc, int width)
599     {
600     gc->meth.gc_set_linewidth(gc->priv, width);
601     }
602    
603     /**
604     * FIXME
605     * @param <>
606     * @returns <>
607     * @author Martin Schaller (04/2008)
608 zoff99 27 */
609     void graphics_gc_set_dashes(struct graphics *gra, struct graphics_gc *gc, int width, int offset, int dash_list[], int n, int order)
610 zoff99 2 {
611     if (gc->meth.gc_set_dashes)
612 zoff99 27 {
613     gc->meth.gc_set_dashes(gra->priv, gc->priv, width, offset, dash_list, order);
614     }
615 zoff99 2 }
616    
617     /**
618     * Create a new image from file path scaled to w and h pixels
619     * @param gra the graphics instance
620     * @param path path of the image to load
621     * @param w width to rescale to
622     * @param h height to rescale to
623     * @returns <>
624     * @author Martin Schaller (04/2008)
625 zoff99 27 */
626 zoff99 2 struct graphics_image * graphics_image_new_scaled(struct graphics *gra, char *path, int w, int h)
627     {
628     struct graphics_image *this_;
629    
630     this_=g_new0(struct graphics_image,1);
631 zoff99 27 this_->height = h;
632     this_->width = w;
633     this_->priv = gra->meth.image_new(gra->priv, &this_->meth, path, &this_->width, &this_->height, &this_->hot, 0);
634     if (!this_->priv)
635     {
636 zoff99 2 g_free(this_);
637 zoff99 27 this_ = NULL;
638 zoff99 2 }
639     return this_;
640     }
641    
642     /**
643     * Create a new image from file path scaled to w and h pixels and possibly rotated
644     * @param gra the graphics instance
645     * @param path path of the image to load
646     * @param w width to rescale to
647     * @param h height to rescale to
648     * @param rotate angle to rotate the image. Warning, graphics might only support 90 degree steps here
649     * @returns <>
650     * @author Martin Schaller (04/2008)
651 zoff99 27 */
652 zoff99 2 struct graphics_image * graphics_image_new_scaled_rotated(struct graphics *gra, char *path, int w, int h, int rotate)
653     {
654     struct graphics_image *this_;
655    
656     this_=g_new0(struct graphics_image,1);
657 zoff99 27 this_->height = h;
658     this_->width = w;
659     this_->priv = gra->meth.image_new(gra->priv, &this_->meth, path, &this_->width, &this_->height, &this_->hot, rotate);
660     if (!this_->priv)
661     {
662 zoff99 2 g_free(this_);
663 zoff99 27 this_ = NULL;
664 zoff99 2 }
665     return this_;
666     }
667    
668     /**
669     * Create a new image from file path
670     * @param gra the graphics instance
671     * @param path path of the image to load
672     * @returns <>
673     * @author Martin Schaller (04/2008)
674 zoff99 27 */
675 zoff99 2 struct graphics_image * graphics_image_new(struct graphics *gra, char *path)
676     {
677     return graphics_image_new_scaled(gra, path, -1, -1);
678     }
679    
680     /**
681     * FIXME
682     * @param <>
683     * @returns <>
684     * @author Martin Schaller (04/2008)
685 zoff99 27 */
686 zoff99 2 void graphics_image_free(struct graphics *gra, struct graphics_image *img)
687     {
688     if (gra->meth.image_free)
689     gra->meth.image_free(gra->priv, img->priv);
690     g_free(img);
691     }
692    
693     /**
694     * FIXME
695     * @param <>
696     * @returns <>
697     * @author Martin Schaller (04/2008)
698 zoff99 27 */
699 zoff99 2 void graphics_draw_restore(struct graphics *this_, struct point *p, int w, int h)
700     {
701 zoff99 27 ////DBG dbg(0,"ooo enter ooo\n");
702 zoff99 2
703     this_->meth.draw_restore(this_->priv, p, w, h);
704     }
705    
706     /**
707     * FIXME
708     * @param <>
709     * @returns <>
710     * @author Martin Schaller (04/2008)
711 zoff99 27 */
712 zoff99 2 void graphics_draw_mode(struct graphics *this_, enum draw_mode_num mode)
713     {
714 zoff99 27 ////DBG dbg(0,"ooo enter ooo\n");
715 zoff99 2
716     this_->meth.draw_mode(this_->priv, mode);
717     }
718    
719     /**
720     * FIXME
721     * @param <>
722     * @returns <>
723     * @author Martin Schaller (04/2008)
724 zoff99 27 */
725 zoff99 2 void graphics_draw_lines(struct graphics *this_, struct graphics_gc *gc, struct point *p, int count)
726     {
727     this_->meth.draw_lines(this_->priv, gc->priv, p, count);
728     }
729    
730     void graphics_draw_lines_dashed(struct graphics *this_, struct graphics_gc *gc, struct point *p, int count, int order, int oneway)
731     {
732     this_->meth.draw_lines_dashed(this_->priv, gc->priv, p, count, order, oneway);
733     }
734    
735     /**
736     * FIXME
737     * @param <>
738     * @returns <>
739     * @author Martin Schaller (04/2008)
740 zoff99 27 */
741 zoff99 2 void graphics_draw_circle(struct graphics *this_, struct graphics_gc *gc, struct point *p, int r)
742     {
743 zoff99 27 struct point *pnt = g_alloca(sizeof(struct point) * (r * 4 + 64));
744     int i = 0;
745 zoff99 2
746 zoff99 27 if (this_->meth.draw_circle)
747 zoff99 2 this_->meth.draw_circle(this_->priv, gc->priv, p, r);
748     else
749     {
750     draw_circle(p, r, 0, -1, 1026, pnt, &i, 1);
751     pnt[i] = pnt[0];
752     i++;
753     this_->meth.draw_lines(this_->priv, gc->priv, pnt, i);
754     }
755     }
756    
757     /**
758     * FIXME
759     * @param <>
760     * @returns <>
761     * @author Martin Schaller (04/2008)
762 zoff99 27 */
763 zoff99 2 void graphics_draw_rectangle(struct graphics *this_, struct graphics_gc *gc, struct point *p, int w, int h)
764     {
765     this_->meth.draw_rectangle(this_->priv, gc->priv, p, w, h);
766     }
767    
768     void graphics_draw_rectangle_rounded(struct graphics *this_, struct graphics_gc *gc, struct point *plu, int w, int h, int r, int fill)
769     {
770 zoff99 27 struct point *p = g_alloca(sizeof(struct point) * (r * 4 + 32));
771     struct point pi0 =
772     { plu->x + r, plu->y + r };
773     struct point pi1 =
774     { plu->x + w - r, plu->y + r };
775     struct point pi2 =
776     { plu->x + w - r, plu->y + h - r };
777     struct point pi3 =
778     { plu->x + r, plu->y + h - r };
779     int i = 0;
780 zoff99 2
781 zoff99 27 draw_circle(&pi2, r * 2, 0, -1, 258, p, &i, 1);
782     draw_circle(&pi1, r * 2, 0, 255, 258, p, &i, 1);
783     draw_circle(&pi0, r * 2, 0, 511, 258, p, &i, 1);
784     draw_circle(&pi3, r * 2, 0, 767, 258, p, &i, 1);
785     p[i] = p[0];
786 zoff99 2 i++;
787     if (fill)
788     this_->meth.draw_polygon(this_->priv, gc->priv, p, i);
789     else
790     this_->meth.draw_lines(this_->priv, gc->priv, p, i);
791     }
792    
793     /**
794     * FIXME
795     * @param <>
796     * @returns <>
797     * @author Martin Schaller (04/2008)
798 zoff99 27 */
799 zoff99 2 void graphics_draw_text(struct graphics *this_, struct graphics_gc *gc1, struct graphics_gc *gc2, struct graphics_font *font, char *text, struct point *p, int dx, int dy)
800     {
801     this_->meth.draw_text(this_->priv, gc1->priv, gc2 ? gc2->priv : NULL, font->priv, text, p, dx, dy);
802     }
803    
804     /**
805     * FIXME
806     * @param <>
807     * @returns <>
808     * @author Martin Schaller (04/2008)
809 zoff99 27 */
810 zoff99 2 void graphics_get_text_bbox(struct graphics *this_, struct graphics_font *font, char *text, int dx, int dy, struct point *ret, int estimate)
811     {
812     this_->meth.get_text_bbox(this_->priv, font->priv, text, dx, dy, ret, estimate);
813     }
814    
815     /**
816     * FIXME
817     * @param <>
818     * @returns <>
819     * @author Martin Schaller (04/2008)
820 zoff99 27 */
821 zoff99 2 void graphics_overlay_disable(struct graphics *this_, int disable)
822     {
823     if (this_->meth.overlay_disable)
824     this_->meth.overlay_disable(this_->priv, disable);
825     }
826    
827     /**
828     * FIXME
829     * @param <>
830     * @returns <>
831     * @author Martin Schaller (04/2008)
832 zoff99 27 */
833 zoff99 2 void graphics_draw_image(struct graphics *this_, struct graphics_gc *gc, struct point *p, struct graphics_image *img)
834     {
835     this_->meth.draw_image(this_->priv, gc->priv, p, img->priv);
836     }
837    
838     /**
839     *
840     *
841     * @author Zoff (2011)
842 zoff99 27 */
843 zoff99 2 void graphics_draw_bigmap(struct graphics *this_, struct graphics_gc *gc, int yaw, int order, float clat, float clng, int x, int y, int scx, int scy, int px, int py, int valid)
844     {
845     this_->meth.draw_bigmap(this_->priv, gc->priv, yaw, order, clat, clng, x, y, scx, scy, px, py, valid);
846     }
847    
848     void graphics_send_osd_values(struct graphics *this_, struct graphics_gc *gc, char *id, char *text1, char *text2, char *text3, int i1, int i2, int i3, int i4, float f1, float f2, float f3)
849     {
850     this_->meth.send_osd_values(this_->priv, gc->priv, id, text1, text2, text3, i1, i2, i3, i4, f1, f2, f3);
851     }
852    
853     //##############################################################################################################
854     //# Description:
855     //# Comment:
856     //# Authors: Martin Schaller (04/2008)
857     //##############################################################################################################
858 zoff99 27 int graphics_draw_drag(struct graphics *this_, struct point *p)
859 zoff99 2 {
860 zoff99 27 ////DBG dbg(0,"ooo enter ooo\n");
861 zoff99 2
862     if (!this_->meth.draw_drag)
863     {
864     return 0;
865     }
866 zoff99 27 ////DBG dbg(0,"draw DRAG start ...\n");
867 zoff99 2 this_->meth.draw_drag(this_->priv, p);
868 zoff99 27 ////DBG dbg(0,"draw DRAG end ...\n");
869 zoff99 2 return 1;
870     }
871    
872 zoff99 27 void graphics_background_gc(struct graphics *this_, struct graphics_gc *gc)
873 zoff99 2 {
874 zoff99 27 ////DBG dbg(0,"ooo enter ooo\n");
875 zoff99 2
876     this_->meth.background_gc(this_->priv, gc ? gc->priv : NULL);
877     }
878    
879     #include "attr.h"
880     #include "popup.h"
881     #include <stdio.h>
882    
883     #if 0
884     //##############################################################################################################
885     //# Description:
886     //# Comment:
887     //# Authors: Martin Schaller (04/2008)
888     //##############################################################################################################
889     static void popup_view_html(struct popup_item *item, char *file)
890     {
891     char command[1024];
892     sprintf(command,"firefox %s", file);
893     system(command);
894     }
895    
896     struct transformatin *tg;
897     enum projection pg;
898    
899     //##############################################################################################################
900     //# Description:
901     //# Comment:
902     //# Authors: Martin Schaller (04/2008)
903     //##############################################################################################################
904     static void graphics_popup(struct display_list *list, struct popup_item **popup)
905     {
906     struct item *item;
907     struct attr attr;
908     struct map_rect *mr;
909     struct coord c;
910     struct popup_item *curr_item,*last=NULL;
911     item=list->data;
912     mr=map_rect_new(item->map, NULL, NULL, 0);
913     printf("id hi=0x%x lo=0x%x\n", item->id_hi, item->id_lo);
914     item=map_rect_get_item_byid(mr, item->id_hi, item->id_lo);
915 zoff99 27 if (item)
916     {
917     if (item_attr_get(item, attr_name, &attr))
918     {
919 zoff99 2 curr_item=popup_item_new_text(popup,attr.u.str,1);
920 zoff99 27 if (item_attr_get(item, attr_info_html, &attr))
921     {
922 zoff99 2 popup_item_new_func(&last,"HTML Info",1, popup_view_html, g_strdup(attr.u.str));
923     }
924 zoff99 27 if (item_attr_get(item, attr_price_html, &attr))
925     {
926 zoff99 2 popup_item_new_func(&last,"HTML Preis",2, popup_view_html, g_strdup(attr.u.str));
927     }
928     curr_item->submenu=last;
929     }
930     }
931     map_rect_destroy(mr);
932     }
933     #endif
934    
935     /**
936     * FIXME
937     * @param <>
938     * @returns <>
939     * @author Martin Schaller (04/2008)
940 zoff99 27 */
941 zoff99 2 static void xdisplay_free(struct displaylist *dl)
942     {
943     int i;
944 zoff99 27 for (i = 0; i < HASH_SIZE_GRAPHICS_; i++)
945     {
946     struct displayitem *di = dl->hash_entries[i].di;
947     while (di)
948     {
949     struct displayitem *next = di->next;
950 zoff99 2 g_free(di);
951 zoff99 27 di = next;
952 zoff99 2 }
953 zoff99 27 dl->hash_entries[i].di = NULL;
954 zoff99 2 }
955     }
956    
957     /**
958     * FIXME
959     * @param <>
960     * @returns <>
961     * @author Martin Schaller (04/2008)
962 zoff99 27 */
963 zoff99 2 static void display_add(struct hash_entry *entry, struct item *item, int count, struct coord *c, char **label, int label_count)
964     {
965     struct displayitem *di;
966 zoff99 27 int len, i;
967 zoff99 2 char *p;
968    
969 zoff99 27 len = sizeof(*di) + count * sizeof(*c);
970     if (label && label_count)
971     {
972     for (i = 0; i < label_count; i++)
973     {
974 zoff99 2 if (label[i])
975 zoff99 27 len += strlen(label[i]) + 1;
976 zoff99 2 else
977     len++;
978     }
979     }
980 zoff99 27 p = g_malloc(len);
981 zoff99 2
982 zoff99 27 di = (struct displayitem *) p;
983     p += sizeof(*di) + count * sizeof(*c);
984     di->item = *item;
985     if (label && label_count)
986     {
987     di->label = p;
988     for (i = 0; i < label_count; i++)
989     {
990     if (label[i])
991     {
992 zoff99 2 strcpy(p, label[i]);
993 zoff99 27 p += strlen(label[i]) + 1;
994     }
995     else
996     *p++ = '\0';
997 zoff99 2 }
998 zoff99 27 }
999     else
1000     {
1001     di->label = NULL;
1002     }
1003     di->count = count;
1004     memcpy(di->c, c, count * sizeof(*c));
1005     di->next = entry->di;
1006     entry->di = di;
1007 zoff99 2 }
1008    
1009     /**
1010     * FIXME
1011     * @param <>
1012     * @returns <>
1013     * @author Martin Schaller (04/2008)
1014 zoff99 27 */
1015 zoff99 2 static void label_line(struct graphics *gra, struct graphics_gc *fg, struct graphics_gc *bg, struct graphics_font *font, struct point *p, int count, char *label)
1016     {
1017 zoff99 27 int i, x, y, tl, tlm, th, thm, tlsq, l;
1018 zoff99 2 float lsq;
1019 zoff99 27 double dx, dy;
1020 zoff99 2 struct point p_t;
1021     struct point pb[5];
1022    
1023 zoff99 27 if (gra->meth.get_text_bbox)
1024     {
1025 zoff99 2 gra->meth.get_text_bbox(gra->priv, font->priv, label, 0x10000, 0x0, pb, 1);
1026 zoff99 27 tl = (pb[2].x - pb[0].x);
1027     th = (pb[0].y - pb[1].y);
1028 zoff99 2 }
1029 zoff99 27 else
1030     {
1031     tl = strlen(label) * 4;
1032     th = 8;
1033     }
1034     tlm = tl * 32;
1035     thm = th * 36;
1036     tlsq = tlm * tlm;
1037     for (i = 0; i < count - 1; i++)
1038     {
1039     dx = p[i + 1].x - p[i].x;
1040     dx *= 32;
1041     dy = p[i + 1].y - p[i].y;
1042     dy *= 32;
1043     lsq = dx * dx + dy * dy;
1044     if (lsq > tlsq)
1045     {
1046     l = (int) sqrtf(lsq);
1047     x = p[i].x;
1048     y = p[i].y;
1049     if (dx < 0)
1050     {
1051     dx = -dx;
1052     dy = -dy;
1053     x = p[i + 1].x;
1054     y = p[i + 1].y;
1055 zoff99 2 }
1056 zoff99 27 x += (l - tlm) * dx / l / 64;
1057     y += (l - tlm) * dy / l / 64;
1058     x -= dy * thm / l / 64;
1059     y += dx * thm / l / 64;
1060     p_t.x = x;
1061     p_t.y = y;
1062 zoff99 2 #if 0
1063 zoff99 27 //DBG dbg(0,"display_text: '%s', %d, %d, %d, %d %d\n", label, x, y, dx*0x10000/l, dy*0x10000/l, l);
1064 zoff99 2 #endif
1065     if (x < gra->r.rl.x && x + tl > gra->r.lu.x && y + tl > gra->r.lu.y && y - tl < gra->r.rl.y)
1066 zoff99 27 gra->meth.draw_text(gra->priv, fg->priv, bg ? bg->priv : NULL, font->priv, label, &p_t, dx * 0x10000 / l, dy * 0x10000 / l);
1067 zoff99 2 }
1068     }
1069     }
1070    
1071     static void display_draw_arrow(struct point *p, int dx, int dy, int l, struct graphics_gc *gc, struct graphics *gra)
1072     {
1073     struct point pnt[3];
1074 zoff99 27 pnt[0] = pnt[1] = pnt[2] = *p;
1075     pnt[0].x += -dx * l / 65536 + dy * l / 65536;
1076     pnt[0].y += -dy * l / 65536 - dx * l / 65536;
1077     pnt[2].x += -dx * l / 65536 - dy * l / 65536;
1078     pnt[2].y += -dy * l / 65536 + dx * l / 65536;
1079 zoff99 2 gra->meth.draw_lines(gra->priv, gc->priv, pnt, 3);
1080     }
1081    
1082     static void display_draw_arrows(struct graphics *gra, struct graphics_gc *gc, struct point *pnt, int count)
1083     {
1084 zoff99 27 int i, dx, dy, l;
1085 zoff99 2 struct point p;
1086 zoff99 27 for (i = 0; i < count - 1; i++)
1087     {
1088     dx = pnt[i + 1].x - pnt[i].x;
1089     dy = pnt[i + 1].y - pnt[i].y;
1090     l = sqrt(dx * dx + dy * dy);
1091     if (l)
1092     {
1093     dx = dx * 65536 / l;
1094     dy = dy * 65536 / l;
1095     p = pnt[i];
1096     p.x += dx * 15 / 65536;
1097     p.y += dy * 15 / 65536;
1098 zoff99 2 display_draw_arrow(&p, dx, dy, 10, gc, gra);
1099 zoff99 27 p = pnt[i + 1];
1100     p.x -= dx * 15 / 65536;
1101     p.y -= dy * 15 / 65536;
1102 zoff99 2 display_draw_arrow(&p, dx, dy, 10, gc, gra);
1103     }
1104     }
1105     }
1106    
1107 zoff99 27 static int intersection(struct point * a1, int adx, int ady, struct point * b1, int bdx, int bdy, struct point * res)
1108 zoff99 2 {
1109     int n, a, b;
1110     n = bdy * adx - bdx * ady;
1111     a = bdx * (a1->y - b1->y) - bdy * (a1->x - b1->x);
1112     b = adx * (a1->y - b1->y) - ady * (a1->x - b1->x);
1113 zoff99 27 if (n < 0)
1114     {
1115 zoff99 2 n = -n;
1116     a = -a;
1117     b = -b;
1118     }
1119     #if 0
1120     if (a < 0 || b < 0)
1121 zoff99 27 return 0;
1122 zoff99 2 if (a > n || b > n)
1123 zoff99 27 return 0;
1124 zoff99 2 #endif
1125     if (n == 0)
1126     return 0;
1127     res->x = a1->x + a * adx / n;
1128     res->y = a1->y + a * ady / n;
1129     return 1;
1130     }
1131    
1132 zoff99 27 struct circle
1133     {
1134     short x, y, fowler;
1135     } circle64[] =
1136     {
1137     { 0, 128, 0 },
1138     { 13, 127, 13 },
1139     { 25, 126, 25 },
1140     { 37, 122, 38 },
1141     { 49, 118, 53 },
1142     { 60, 113, 67 },
1143     { 71, 106, 85 },
1144     { 81, 99, 104 },
1145     { 91, 91, 128 },
1146     { 99, 81, 152 },
1147     { 106, 71, 171 },
1148     { 113, 60, 189 },
1149     { 118, 49, 203 },
1150     { 122, 37, 218 },
1151     { 126, 25, 231 },
1152     { 127, 13, 243 },
1153     { 128, 0, 256 },
1154     { 127, -13, 269 },
1155     { 126, -25, 281 },
1156     { 122, -37, 294 },
1157     { 118, -49, 309 },
1158     { 113, -60, 323 },
1159     { 106, -71, 341 },
1160     { 99, -81, 360 },
1161     { 91, -91, 384 },
1162     { 81, -99, 408 },
1163     { 71, -106, 427 },
1164     { 60, -113, 445 },
1165     { 49, -118, 459 },
1166     { 37, -122, 474 },
1167     { 25, -126, 487 },
1168     { 13, -127, 499 },
1169     { 0, -128, 512 },
1170     { -13, -127, 525 },
1171     { -25, -126, 537 },
1172     { -37, -122, 550 },
1173     { -49, -118, 565 },
1174     { -60, -113, 579 },
1175     { -71, -106, 597 },
1176     { -81, -99, 616 },
1177     { -91, -91, 640 },
1178     { -99, -81, 664 },
1179     { -106, -71, 683 },
1180     { -113, -60, 701 },
1181     { -118, -49, 715 },
1182     { -122, -37, 730 },
1183     { -126, -25, 743 },
1184     { -127, -13, 755 },
1185     { -128, 0, 768 },
1186     { -127, 13, 781 },
1187     { -126, 25, 793 },
1188     { -122, 37, 806 },
1189     { -118, 49, 821 },
1190     { -113, 60, 835 },
1191     { -106, 71, 853 },
1192     { -99, 81, 872 },
1193     { -91, 91, 896 },
1194     { -81, 99, 920 },
1195     { -71, 106, 939 },
1196     { -60, 113, 957 },
1197     { -49, 118, 971 },
1198     { -37, 122, 986 },
1199     { -25, 126, 999 },
1200     { -13, 127, 1011 }, };
1201 zoff99 2
1202 zoff99 27 static void draw_circle(struct point *pnt, int diameter, int scale, int start, int len, struct point *res, int *pos, int dir)
1203 zoff99 2 {
1204     struct circle *c;
1205    
1206     #if 0
1207 zoff99 27 //DBG dbg(0,"diameter=%d start=%d len=%d pos=%d dir=%d\n", diameter, start, len, *pos, dir);
1208 zoff99 2 #endif
1209 zoff99 27 int count = 64;
1210     int end = start + len;
1211     int i, step;
1212     c = circle64;
1213 zoff99 2 if (diameter > 128)
1214 zoff99 27 step = 1;
1215 zoff99 2 else if (diameter > 64)
1216 zoff99 27 step = 2;
1217 zoff99 2 else if (diameter > 24)
1218 zoff99 27 step = 4;
1219 zoff99 2 else if (diameter > 8)
1220 zoff99 27 step = 8;
1221 zoff99 2 else
1222 zoff99 27 step = 16;
1223     if (len > 0)
1224     {
1225     while (start < 0)
1226     {
1227     start += 1024;
1228     end += 1024;
1229 zoff99 2 }
1230 zoff99 27 while (end > 0)
1231     {
1232     i = 0;
1233 zoff99 2 while (i < count && c[i].fowler <= start)
1234 zoff99 27 {
1235     i += step;
1236     }
1237     while (i < count && c[i].fowler < end)
1238     {
1239     if (1 < *pos || 0 < dir)
1240     {
1241     res[*pos].x = pnt->x + ((c[i].x * diameter + 128) >> 8);
1242     res[*pos].y = pnt->y + ((c[i].y * diameter + 128) >> 8);
1243     (*pos) += dir;
1244 zoff99 2 }
1245 zoff99 27 i += step;
1246 zoff99 2 }
1247 zoff99 27 end -= 1024;
1248     start -= 1024;
1249 zoff99 2 }
1250 zoff99 27 }
1251     else
1252     {
1253     while (start > 1024)
1254     {
1255     start -= 1024;
1256     end -= 1024;
1257 zoff99 2 }
1258 zoff99 27 while (end < 1024)
1259     {
1260     i = count - 1;
1261 zoff99 2 while (i >= 0 && c[i].fowler >= start)
1262 zoff99 27 i -= step;
1263     while (i >= 0 && c[i].fowler > end)
1264     {
1265     if (1 < *pos || 0 < dir)
1266     {
1267     res[*pos].x = pnt->x + ((c[i].x * diameter + 128) >> 8);
1268     res[*pos].y = pnt->y + ((c[i].y * diameter + 128) >> 8);
1269     (*pos) += dir;
1270 zoff99 2 }
1271 zoff99 27 i -= step;
1272 zoff99 2 }
1273 zoff99 27 start += 1024;
1274     end += 1024;
1275 zoff99 2 }
1276     }
1277     }
1278    
1279 zoff99 27 static int fowler(int dy, int dx)
1280 zoff99 2 {
1281 zoff99 27 int adx, ady; /* Absolute Values of Dx and Dy */
1282     int code; /* Angular Region Classification Code */
1283 zoff99 2
1284 zoff99 27 adx = (dx < 0) ? -dx : dx; /* Compute the absolute values. */
1285 zoff99 2 ady = (dy < 0) ? -dy : dy;
1286    
1287     code = (adx < ady) ? 1 : 0;
1288     if (dx < 0)
1289     code += 2;
1290     if (dy < 0)
1291     code += 4;
1292    
1293 zoff99 27 switch (code)
1294     {
1295     case 0:
1296     return (dx == 0) ? 0 : 128 * ady / adx; /* [ 0, 45] */
1297     case 1:
1298     return (256 - (128 * adx / ady)); /* ( 45, 90] */
1299     case 3:
1300     return (256 + (128 * adx / ady)); /* ( 90,135) */
1301     case 2:
1302     return (512 - (128 * ady / adx)); /* [135,180] */
1303     case 6:
1304     return (512 + (128 * ady / adx)); /* (180,225] */
1305     case 7:
1306     return (768 - (128 * adx / ady)); /* (225,270) */
1307     case 5:
1308     return (768 + (128 * adx / ady)); /* [270,315) */
1309     case 4:
1310     return (1024 - (128 * ady / adx));/* [315,360) */
1311 zoff99 2 }
1312     return 0;
1313     }
1314 zoff99 27
1315     static int int_sqrt(unsigned int n)
1316 zoff99 2 {
1317 zoff99 27 unsigned int h, p = 0, q = 1, r = n;
1318 zoff99 2
1319     /* avoid q rollover */
1320 zoff99 27 if (n >= (1 << (sizeof(n) * 8 - 2)))
1321     {
1322     q = 1 << (sizeof(n) * 8 - 2);
1323     }
1324     else
1325     {
1326     while (q <= n)
1327     {
1328 zoff99 2 q <<= 2;
1329     }
1330     q >>= 2;
1331     }
1332    
1333 zoff99 27 while (q != 0)
1334     {
1335 zoff99 2 h = p + q;
1336     p >>= 1;
1337 zoff99 27 if (r >= h)
1338     {
1339 zoff99 2 p += q;
1340     r -= h;
1341     }
1342     q >>= 2;
1343     }
1344     return p;
1345     }
1346    
1347 zoff99 27 struct offset
1348     {
1349     int px, py, nx, ny;
1350 zoff99 2 };
1351    
1352 zoff99 27 static void calc_offsets(int wi, int l, int dx, int dy, struct offset *res)
1353 zoff99 2 {
1354 zoff99 27 int x, y;
1355 zoff99 2
1356     x = (dx * wi) / l;
1357     y = (dy * wi) / l;
1358 zoff99 27 if (x < 0)
1359     {
1360     res->nx = -x / 2;
1361     res->px = (x - 1) / 2;
1362 zoff99 2 }
1363 zoff99 27 else
1364     {
1365     res->nx = -(x + 1) / 2;
1366     res->px = x / 2;
1367 zoff99 2 }
1368 zoff99 27 if (y < 0)
1369     {
1370     res->ny = -y / 2;
1371     res->py = (y - 1) / 2;
1372     }
1373     else
1374     {
1375     res->ny = -(y + 1) / 2;
1376     res->py = y / 2;
1377     }
1378 zoff99 2 }
1379    
1380 zoff99 27 static void graphics_draw_polyline_as_polygon(struct graphics *gra, struct graphics_gc *gc, struct point *pnt, int count, int *width, int step, int fill, int order, int oneway)
1381 zoff99 2 {
1382 zoff99 27 int maxpoints = 200;
1383     struct point *res = g_alloca(sizeof(struct point) * maxpoints);
1384 zoff99 2 struct point pos, poso, neg, nego;
1385 zoff99 27 int i, dx = 0, dy = 0, l = 0, dxo = 0, dyo = 0;
1386     struct offset o, oo =
1387     { 0, 0, 0, 0 };
1388     int fow = 0, fowo = 0, delta;
1389     int wi, ppos = maxpoints / 2, npos = maxpoints / 2;
1390     int state, prec = 5;
1391     int max_circle_points = 20;
1392     int lscale = 16;
1393     i = 0;
1394     for (;;)
1395     {
1396     wi = *width;
1397     width += step;
1398     if (i < count - 1)
1399     {
1400     int dxs, dys, lscales;
1401 zoff99 2
1402     dx = (pnt[i + 1].x - pnt[i].x);
1403     dy = (pnt[i + 1].y - pnt[i].y);
1404     #if 0
1405     l = int_sqrt(dx * dx * lscale * lscale + dy * dy * lscale * lscale);
1406     #else
1407 zoff99 27 dxs = dx * dx;
1408     dys = dy * dy;
1409     lscales = lscale * lscale;
1410     if (dxs + dys > lscales)
1411     l = int_sqrt(dxs + dys) * lscale;
1412     else
1413     l = int_sqrt((dxs + dys) * lscales);
1414 zoff99 2 #endif
1415 zoff99 27 fow = fowler(-dy, dx);
1416 zoff99 2 }
1417 zoff99 27 if (!l)
1418     l = 1;
1419     if (wi * lscale > 10000)
1420     lscale = 10000 / wi;
1421     dbg_assert(wi * lscale <= 10000);
1422     calc_offsets(wi * lscale, l, dx, dy, &o);
1423 zoff99 2 pos.x = pnt[i].x + o.ny;
1424     pos.y = pnt[i].y + o.px;
1425     neg.x = pnt[i].x + o.py;
1426     neg.y = pnt[i].y + o.nx;
1427 zoff99 27 if (!i)
1428     state = 0;
1429     else if (i == count - 1)
1430     state = 2;
1431     else if (npos < max_circle_points || ppos >= maxpoints - max_circle_points)
1432     state = 3;
1433 zoff99 2 else
1434 zoff99 27 state = 1;
1435     switch (state)
1436     {
1437     case 1:
1438     if (fowo != fow)
1439     {
1440     poso.x = pnt[i].x + oo.ny;
1441     poso.y = pnt[i].y + oo.px;
1442     nego.x = pnt[i].x + oo.py;
1443     nego.y = pnt[i].y + oo.nx;
1444     delta = fowo - fow;
1445     if (delta < 0)
1446     delta += 1024;
1447     if (delta < 512)
1448     {
1449     if (intersection(&pos, dx, dy, &poso, dxo, dyo, &res[ppos]))
1450     {
1451     ppos++;
1452     }
1453     res[--npos] = nego;
1454     --npos;
1455     if (fill == 1)
1456     {
1457     if (draw_polylines_fast == 0)
1458     {
1459     draw_circle(&pnt[i], wi, prec, fowo - 512, -delta, res, &npos, -1);
1460     }
1461     }
1462     res[npos] = neg;
1463     }
1464     else
1465     {
1466     res[ppos++] = poso;
1467     if (fill == 1)
1468     {
1469     if (draw_polylines_fast == 0)
1470     {
1471     draw_circle(&pnt[i], wi, prec, fowo, 1024 - delta, res, &ppos, 1);
1472     }
1473     }
1474     res[ppos++] = pos;
1475     if (intersection(&neg, dx, dy, &nego, dxo, dyo, &res[npos - 1]))
1476     {
1477     npos--;
1478     }
1479     }
1480 zoff99 2 }
1481     break;
1482 zoff99 27 case 2:
1483     case 3:
1484     res[--npos] = neg;
1485     --npos;
1486     if (fill == 1)
1487     {
1488     if (draw_polylines_fast == 0)
1489     {
1490     draw_circle(&pnt[i], wi, prec, fow - 512, -512, res, &npos, -1);
1491     }
1492     }
1493     res[npos] = pos;
1494     res[ppos++] = pos;
1495     dbg_assert(npos > 0);
1496     dbg_assert(ppos < maxpoints);
1497     if (fill == 1)
1498     {
1499     gra->meth.draw_polygon2(gra->priv, gc->priv, res + npos, ppos - npos, order, oneway);
1500     }
1501     else
1502     {
1503     gra->meth.draw_lines_dashed(gra->priv, gc->priv, res + npos, ppos - npos, order, oneway);
1504     }
1505     if (state == 2)
1506     break;
1507     npos = maxpoints / 2;
1508     ppos = maxpoints / 2;
1509     case 0:
1510     res[ppos++] = neg;
1511     if (fill == 1)
1512     {
1513     if (draw_polylines_fast == 0)
1514     {
1515     draw_circle(&pnt[i], wi, prec, fow + 512, 512, res, &ppos, 1);
1516     }
1517     }
1518     res[ppos++] = pos;
1519     break;
1520 zoff99 2 }
1521 zoff99 27
1522 zoff99 2 i++;
1523 zoff99 27
1524 zoff99 2 if (i >= count)
1525 zoff99 27 {
1526 zoff99 2 break;
1527 zoff99 27 }
1528    
1529     if (step)
1530     {
1531     wi = *width;
1532     calc_offsets(wi * lscale, l, dx, dy, &oo);
1533     }
1534     else
1535     {
1536     oo = o;
1537     }
1538    
1539 zoff99 2 dxo = -dx;
1540     dyo = -dy;
1541 zoff99 27 fowo = fow;
1542 zoff99 2 }
1543     }
1544    
1545 zoff99 27 struct wpoint
1546     {
1547     int x, y, w;
1548 zoff99 2 };
1549    
1550 zoff99 27 static int clipcode(struct wpoint *p, struct point_rect *r)
1551 zoff99 2 {
1552 zoff99 27 int code = 0;
1553 zoff99 2 if (p->x < r->lu.x)
1554 zoff99 27 code = 1;
1555 zoff99 2 if (p->x > r->rl.x)
1556 zoff99 27 code = 2;
1557 zoff99 2 if (p->y < r->lu.y)
1558 zoff99 27 code |= 4;
1559 zoff99 2 if (p->y > r->rl.y)
1560 zoff99 27 code |= 8;
1561 zoff99 2 return code;
1562     }
1563    
1564 zoff99 27 static int clip_line(struct wpoint *p1, struct wpoint *p2, struct point_rect *r)
1565 zoff99 2 {
1566 zoff99 27 int code1, code2, ret = 1;
1567     int dx, dy, dw;
1568     code1 = clipcode(p1, r);
1569 zoff99 2 if (code1)
1570     ret |= 2;
1571 zoff99 27 code2 = clipcode(p2, r);
1572 zoff99 2 if (code2)
1573     ret |= 4;
1574 zoff99 27 dx = p2->x - p1->x;
1575     dy = p2->y - p1->y;
1576     dw = p2->w - p1->w;
1577     while (code1 || code2)
1578     {
1579 zoff99 2 if (code1 & code2)
1580     return 0;
1581 zoff99 27 if (code1 & 1)
1582     {
1583     p1->y += (r->lu.x - p1->x) * dy / dx;
1584     p1->w += (r->lu.x - p1->x) * dw / dx;
1585     p1->x = r->lu.x;
1586 zoff99 2 }
1587 zoff99 27 else if (code1 & 2)
1588     {
1589     p1->y += (r->rl.x - p1->x) * dy / dx;
1590     p1->w += (r->rl.x - p1->x) * dw / dx;
1591     p1->x = r->rl.x;
1592     }
1593     else if (code1 & 4)
1594     {
1595     p1->x += (r->lu.y - p1->y) * dx / dy;
1596     p1->w += (r->lu.y - p1->y) * dw / dy;
1597     p1->y = r->lu.y;
1598     }
1599     else if (code1 & 8)
1600     {
1601     p1->x += (r->rl.y - p1->y) * dx / dy;
1602     p1->w += (r->rl.y - p1->y) * dw / dy;
1603     p1->y = r->rl.y;
1604     }
1605     code1 = clipcode(p1, r);
1606 zoff99 2 if (code1 & code2)
1607     return 0;
1608 zoff99 27 if (code2 & 1)
1609     {
1610     p2->y += (r->lu.x - p2->x) * dy / dx;
1611     p2->w += (r->lu.x - p2->x) * dw / dx;
1612     p2->x = r->lu.x;
1613 zoff99 2 }
1614 zoff99 27 else if (code2 & 2)
1615     {
1616     p2->y += (r->rl.x - p2->x) * dy / dx;
1617     p2->w += (r->rl.x - p2->x) * dw / dx;
1618     p2->x = r->rl.x;
1619     }
1620     else if (code2 & 4)
1621     {
1622     p2->x += (r->lu.y - p2->y) * dx / dy;
1623     p2->w += (r->lu.y - p2->y) * dw / dy;
1624     p2->y = r->lu.y;
1625     }
1626     else if (code2 & 8)
1627     {
1628     p2->x += (r->rl.y - p2->y) * dx / dy;
1629     p2->w += (r->rl.y - p2->y) * dw / dy;
1630     p2->y = r->rl.y;
1631     }
1632     code2 = clipcode(p2, r);
1633 zoff99 2 }
1634     return ret;
1635     }
1636    
1637 zoff99 27 static void graphics_draw_polyline_clipped(struct graphics *gra, struct graphics_gc *gc, struct point *pa, int count, int *width, int step, int poly, int order, int oneway)
1638 zoff99 2 {
1639 zoff99 27 struct point *p = g_alloca(sizeof(struct point) * (count + 1));
1640     int *w = g_alloca(sizeof(int) * (count * step + 1));
1641     struct wpoint p1, p2;
1642     int i, code, out = 0;
1643 zoff99 2 int wmax;
1644 zoff99 27 struct point_rect r = gra->r;
1645 zoff99 2
1646 zoff99 27 wmax = width[0];
1647     if (step)
1648     {
1649     for (i = 1; i < count; i++)
1650     {
1651     if (width[i * step] > wmax)
1652     wmax = width[i * step];
1653 zoff99 2 }
1654     }
1655     if (wmax <= 0)
1656 zoff99 27 {
1657 zoff99 2 return;
1658 zoff99 27 }
1659     r.lu.x -= wmax;
1660     r.lu.y -= wmax;
1661     r.rl.x += wmax;
1662     r.rl.y += wmax;
1663    
1664     for (i = 0; i < count; i++)
1665     {
1666     if (i)
1667     {
1668     p1.x = pa[i - 1].x;
1669     p1.y = pa[i - 1].y;
1670     p1.w = width[(i - 1) * step];
1671     p2.x = pa[i].x;
1672     p2.y = pa[i].y;
1673     p2.w = width[i * step];
1674 zoff99 2 /* 0 = invisible, 1 = completely visible, 3 = start point clipped, 5 = end point clipped, 7 both points clipped */
1675 zoff99 27 code = clip_line(&p1, &p2, &r);
1676    
1677     if (((code == 1 || code == 5) && i == 1) || (code & 2))
1678     {
1679     p[out].x = p1.x;
1680     p[out].y = p1.y;
1681     w[out * step] = p1.w;
1682 zoff99 2 out++;
1683     }
1684 zoff99 27
1685     if (code)
1686     {
1687     p[out].x = p2.x;
1688     p[out].y = p2.y;
1689     w[out * step] = p2.w;
1690 zoff99 2 out++;
1691     }
1692 zoff99 27
1693     if (i == count - 1 || (code & 4))
1694     {
1695     if (out > 1)
1696     {
1697     if ((poly == 1) || (poly == 0))
1698 zoff99 2 {
1699     // normal street
1700 zoff99 27 //if (1 == 0)
1701     //{
1702     // // draw as polygon --> OLD method
1703     // graphics_draw_polyline_as_polygon(gra, gc, p, out, w, step, 1, order, 0);
1704     //}
1705     //else
1706     //{
1707     // draw as line
1708     // dbg(0,"w=%d", width[i]);
1709     gra->meth.draw_lines3(gra->priv, gc->priv, p, out, order, width[i]);
1710     //}
1711    
1712 zoff99 2 // one way arrow
1713     if (oneway > 0)
1714     {
1715     gra->meth.draw_lines2(gra->priv, gc->priv, p, out, order, oneway);
1716     }
1717     }
1718 zoff99 27 else if (poly == 2)
1719 zoff99 2 {
1720 zoff99 27 // ******* street is underground ********
1721     // ******* street is underground ********
1722     // ******* street is underground ********
1723    
1724     //if (1 == 0)
1725     //{
1726     // // draw as polygon --> OLD method
1727     // graphics_draw_polyline_as_polygon(gra, gc, p, out, w, step, 0, order, 0);
1728     //}
1729     //else
1730     //{
1731     // draw as line
1732     gra->meth.draw_lines4(gra->priv, gc->priv, p, out, order, width[i], 1);
1733     //}
1734    
1735 zoff99 2 // one way arrow
1736     if (oneway > 0)
1737     {
1738     gra->meth.draw_lines2(gra->priv, gc->priv, p, out, order, oneway);
1739     }
1740     }
1741 zoff99 27 else if (poly == 3)
1742     {
1743     // ******* street has bridge ********
1744     // ******* street has bridge ********
1745     // ******* street has bridge ********
1746     gra->meth.draw_lines4(gra->priv, gc->priv, p, out, order, width[i], 2);
1747    
1748     // one way arrow
1749     if (oneway > 0)
1750     {
1751     gra->meth.draw_lines2(gra->priv, gc->priv, p, out, order, oneway);
1752     }
1753     }
1754     // --> now NOT used anymore!!
1755 zoff99 2 else // poly==0 -> street that is only a line (width=1)
1756     {
1757 zoff99 27 // OLD // gra->meth.draw_lines2(gra->priv, gc->priv, p, out, order, 0);
1758    
1759     gra->meth.draw_lines3(gra->priv, gc->priv, p, out, order, width[i]);
1760    
1761     // one way arrow
1762     if (oneway > 0)
1763     {
1764     gra->meth.draw_lines2(gra->priv, gc->priv, p, out, order, oneway);
1765     }
1766 zoff99 2 }
1767 zoff99 27 out = 0;
1768 zoff99 2 }
1769     }
1770     }
1771     }
1772     }
1773    
1774 zoff99 27 static int is_inside(struct point *p, struct point_rect *r, int edge)
1775 zoff99 2 {
1776 zoff99 27 switch (edge)
1777     {
1778     case 0:
1779     return p->x >= r->lu.x;
1780     case 1:
1781     return p->x <= r->rl.x;
1782     case 2:
1783     return p->y >= r->lu.y;
1784     case 3:
1785     return p->y <= r->rl.y;
1786     default:
1787     return 0;
1788 zoff99 2 }
1789     }
1790    
1791 zoff99 27 static void poly_intersection(struct point *p1, struct point *p2, struct point_rect *r, int edge, struct point *ret)
1792 zoff99 2 {
1793 zoff99 27 int dx = p2->x - p1->x;
1794     int dy = p2->y - p1->y;
1795     switch (edge)
1796     {
1797     case 0:
1798     ret->y = p1->y + (r->lu.x - p1->x) * dy / dx;
1799     ret->x = r->lu.x;
1800     break;
1801     case 1:
1802     ret->y = p1->y + (r->rl.x - p1->x) * dy / dx;
1803     ret->x = r->rl.x;
1804     break;
1805     case 2:
1806     ret->x = p1->x + (r->lu.y - p1->y) * dx / dy;
1807     ret->y = r->lu.y;
1808     break;
1809     case 3:
1810     ret->x = p1->x + (r->rl.y - p1->y) * dx / dy;
1811     ret->y = r->rl.y;
1812     break;
1813 zoff99 2 }
1814     }
1815    
1816 zoff99 27 static void graphics_draw_polygon_clipped(struct graphics *gra, struct graphics_gc *gc, struct point *pin, int count_in)
1817 zoff99 2 {
1818 zoff99 27 struct point_rect r = gra->r;
1819     struct point *pout, *p, *s, pi, *p1, *p2;
1820     int limit = 10000;
1821     struct point *pa1 = g_alloca(sizeof(struct point) * (count_in < limit ? count_in * 8 + 1 : 0));
1822     struct point *pa2 = g_alloca(sizeof(struct point) * (count_in < limit ? count_in * 8 + 1 : 0));
1823     int count_out, edge = 3;
1824 zoff99 2 int i;
1825     #if 0
1826     r.lu.x+=20;
1827     r.lu.y+=20;
1828     r.rl.x-=20;
1829     r.rl.y-=20;
1830     #endif
1831 zoff99 27 if (count_in < limit)
1832     {
1833     p1 = pa1;
1834     p2 = pa2;
1835     }
1836     else
1837     {
1838 zoff99 2 p1=g_new(struct point, count_in*8+1);
1839     p2=g_new(struct point, count_in*8+1);
1840     }
1841    
1842     pout=p1;
1843 zoff99 27 for (edge = 0; edge < 4; edge++)
1844     {
1845 zoff99 2 p=pin;
1846     s=pin+count_in-1;
1847     count_out=0;
1848 zoff99 27 for (i = 0; i < count_in; i++)
1849     {
1850     if (is_inside(p, &r, edge))
1851     {
1852     if (! is_inside(s, &r, edge))
1853     {
1854 zoff99 2 poly_intersection(s,p,&r,edge,&pi);
1855     pout[count_out++]=pi;
1856     }
1857     pout[count_out++]=*p;
1858 zoff99 27 }
1859     else
1860     {
1861     if (is_inside(s, &r, edge))
1862     {
1863 zoff99 2 poly_intersection(p,s,&r,edge,&pi);
1864     pout[count_out++]=pi;
1865     }
1866     }
1867     s=p;
1868     p++;
1869     }
1870     count_in=count_out;
1871 zoff99 27 if (pin == p1)
1872     {
1873 zoff99 2 pin=p2;
1874     pout=p1;
1875 zoff99 27 }
1876     else
1877     {
1878 zoff99 2 pin=p1;
1879     pout=p2;
1880     }
1881     }
1882 zoff99 27
1883 zoff99 2 gra->meth.draw_polygon(gra->priv, gc->priv, pin, count_in);
1884 zoff99 27 if (count_in >= limit)
1885     {
1886 zoff99 2 g_free(p1);
1887     g_free(p2);
1888     }
1889     }
1890    
1891 zoff99 27 static void display_context_free(struct display_context *dc)
1892 zoff99 2 {
1893     if (dc->gc)
1894     graphics_gc_destroy(dc->gc);
1895     if (dc->gc_background)
1896     graphics_gc_destroy(dc->gc_background);
1897     if (dc->img)
1898     graphics_image_free(dc->gra, dc->img);
1899 zoff99 27 dc->gc = NULL;
1900     dc->gc_background = NULL;
1901     dc->img = NULL;
1902 zoff99 2 }
1903    
1904     static struct graphics_font *
1905     get_font(struct graphics *gra, int size)
1906     {
1907     if (size > 64)
1908 zoff99 27 {
1909     size = 64;
1910     }
1911     if (size >= gra->font_len)
1912     {
1913 zoff99 2 gra->font=g_renew(struct graphics_font *, gra->font, size+1);
1914     while (gra->font_len <= size)
1915 zoff99 27 {
1916     gra->font[gra->font_len++] = NULL;
1917     }
1918 zoff99 2 }
1919 zoff99 27 if (!gra->font[size])
1920     {
1921     gra->font[size] = graphics_font_new(gra, size * gra->font_size, 0);
1922     }
1923 zoff99 2 return gra->font[size];
1924     }
1925    
1926     void graphics_draw_text_std(struct graphics *this_, int text_size, char *text, struct point *p)
1927     {
1928 zoff99 27 struct graphics_font *font = get_font(this_, text_size);
1929 zoff99 2 struct point bbox[4];
1930     int i;
1931    
1932     graphics_get_text_bbox(this_, font, text, 0x10000, 0, bbox, 0);
1933 zoff99 27 for (i = 0; i < 4; i++)
1934     {
1935     bbox[i].x += p->x;
1936     bbox[i].y += p->y;
1937 zoff99 2 }
1938 zoff99 27 graphics_draw_rectangle(this_, this_->gc[2], &bbox[1], bbox[2].x - bbox[0].x, bbox[0].y - bbox[1].y + 5);
1939 zoff99 2 graphics_draw_text(this_, this_->gc[1], this_->gc[2], font, text, p, 0x10000, 0);
1940     }
1941    
1942     char *
1943     graphics_icon_path(char *icon)
1944     {
1945     static char *navit_sharedir;
1946 zoff99 27 char *ret = NULL;
1947     struct file_wordexp *wordexp = NULL;
1948     // dbg(1, "enter %s\n", icon);
1949     if (strchr(icon, '$'))
1950     {
1951     wordexp = file_wordexp_new(icon);
1952 zoff99 2 if (file_wordexp_get_count(wordexp))
1953 zoff99 27 {
1954     icon = file_wordexp_get_array(wordexp)[0];
1955     }
1956 zoff99 2 }
1957 zoff99 27
1958     if (strchr(icon, '/'))
1959     {
1960     ret = g_strdup(icon);
1961     }
1962     else
1963     {
1964 zoff99 2 #ifdef HAVE_API_ANDROID
1965     // get resources for the correct screen density
1966     //
1967     // this part not needed, android unpacks only the correct version into res/drawable dir!
1968 zoff99 27 // // dbg(1,"android icon_path %s\n",icon);
1969 zoff99 2 // static char *android_density;
1970     // android_density = getenv("ANDROID_DENSITY");
1971     // ret=g_strdup_printf("res/drawable-%s/%s",android_density ,icon);
1972     ret=g_strdup_printf("res/drawable/%s" ,icon);
1973     #else
1974 zoff99 27 if (!navit_sharedir)
1975     {
1976 zoff99 2 navit_sharedir = getenv("NAVIT_SHAREDIR");
1977 zoff99 27 }
1978     ret = g_strdup_printf("%s/xpm/%s", navit_sharedir, icon);
1979 zoff99 2 #endif
1980     }
1981 zoff99 27
1982 zoff99 2 if (wordexp)
1983 zoff99 27 {
1984 zoff99 2 file_wordexp_destroy(wordexp);
1985 zoff99 27 }
1986    
1987 zoff99 2 return ret;
1988     }
1989    
1990 zoff99 27 static int limit_count(struct coord *c, int count)
1991 zoff99 2 {
1992     int i;
1993 zoff99 27 for (i = 1; i < count; i++)
1994     {
1995 zoff99 2 if (c[i].x == c[0].x && c[i].y == c[0].y)
1996 zoff99 27 return i + 1;
1997 zoff99 2 }
1998     return count;
1999     }
2000    
2001 zoff99 27 static void displayitem_draw(struct displayitem *di, void *dummy, struct display_context *dc, int order, int allow_dashed)
2002 zoff99 2 {
2003 zoff99 27 ////DBG dbg(0,"ooo enter ooo\n");
2004 zoff99 2
2005 zoff99 27 int *width = g_alloca(sizeof(int) * dc->maxlen);
2006     struct point *pa = g_alloca(sizeof(struct point) * dc->maxlen);
2007     struct graphics *gra = dc->gra;
2008     struct graphics_gc *gc = dc->gc;
2009     struct element *e = dc->e;
2010     struct graphics_image *img = dc->img;
2011 zoff99 2 struct point p;
2012     char *path;
2013    
2014 zoff99 27 // //DBG dbg(0,"enter\n");
2015 zoff99 2
2016     while (di)
2017     {
2018 zoff99 27 int i, count = di->count, mindist = dc->mindist;
2019 zoff99 2
2020 zoff99 27 if (!gc)
2021 zoff99 2 {
2022 zoff99 27 gc = graphics_gc_new(gra);
2023 zoff99 2 graphics_gc_set_foreground(gc, &e->color);
2024 zoff99 27 dc->gc = gc;
2025 zoff99 2 }
2026    
2027     if (item_type_is_area(dc->type) && (dc->e->type == element_polyline || dc->e->type == element_text))
2028 zoff99 27 {
2029     count = limit_count(di->c, count);
2030     }
2031 zoff99 2 if (dc->type == type_poly_water_tiled)
2032 zoff99 27 {
2033     mindist = 0;
2034     }
2035 zoff99 2 if (dc->e->type == element_polyline)
2036 zoff99 27 {
2037     count = transform(dc->trans, dc->pro, di->c, pa, count, mindist, e->u.polyline.width, width);
2038     }
2039 zoff99 2 else
2040 zoff99 27 {
2041     count = transform(dc->trans, dc->pro, di->c, pa, count, mindist, 0, NULL);
2042     //struct coord *c9191;
2043     //c9191 = di->c;
2044     //dbg(0,"di->c %i %i pa %d %d \n",c9191->x, c9191->y, pa->x, pa->y);
2045     }
2046 zoff99 2
2047     switch (e->type)
2048     {
2049 zoff99 27 case element_polygon:
2050     graphics_draw_polygon_clipped(gra, gc, pa, count);
2051     break;
2052     case element_polyline:
2053 zoff99 2 {
2054     gc->meth.gc_set_linewidth(gc->priv, 1);
2055    
2056 zoff99 27 int poly = e->u.polyline.width > 1;
2057 zoff99 2
2058     // detect underground streets/lines/etc ...
2059 zoff99 27 //if ((allow_dashed) && (di->item.flags & AF_UNDERGROUND))
2060     if (di->item.flags & AF_UNDERGROUND)
2061 zoff99 2 {
2062 zoff99 27 poly = 2;
2063 zoff99 2 }
2064 zoff99 27 else if (di->item.flags & AF_BRIDGE)
2065     {
2066     poly = 3;
2067     }
2068 zoff99 2
2069 zoff99 27 int oneway = 0;
2070 zoff99 2
2071     if (di->item.flags & AF_ONEWAYREV)
2072     {
2073 zoff99 27 oneway = 2;
2074 zoff99 2 }
2075     else if (di->item.flags & AF_ONEWAY)
2076     {
2077 zoff99 27 oneway = 1;
2078 zoff99 2 }
2079    
2080 zoff99 27 // -------- apply dashes -------
2081     //if (e->u.polyline.width > 0 && e->u.polyline.dash_num > 0)
2082     if (e->u.polyline.dash_num > 0)
2083 zoff99 2 {
2084 zoff99 27 graphics_gc_set_dashes(gra, gc, e->u.polyline.width, e->u.polyline.offset, e->u.polyline.dash_table, e->u.polyline.dash_num, order);
2085 zoff99 2 }
2086 zoff99 27 // -------- apply dashes -------
2087    
2088     for (i = 0; i < count; i++)
2089 zoff99 2 {
2090     if (width[i] < 2)
2091 zoff99 27 {
2092     width[i] = 2;
2093     }
2094 zoff99 2 }
2095     graphics_draw_polyline_clipped(gra, gc, pa, count, width, 1, poly, order, oneway);
2096 zoff99 27
2097     // -------- cancel dashes -------
2098     if (e->u.polyline.dash_num > 0)
2099     {
2100     int dummy_1[1];
2101     dummy_1[0]=0;
2102     graphics_gc_set_dashes(gra, gc, e->u.polyline.width, e->u.polyline.offset, dummy_1, e->u.polyline.dash_num, order);
2103     }
2104     // -------- cancel dashes -------
2105 zoff99 2 }
2106 zoff99 27 break;
2107     case element_circle:
2108     if (count)
2109     {
2110     if (e->u.circle.width > 1)
2111     {
2112     gc->meth.gc_set_linewidth(gc->priv, e->u.polyline.width);
2113     }
2114 zoff99 2
2115 zoff99 27 graphics_draw_circle(gra, gc, pa, e->u.circle.radius);
2116 zoff99 2
2117 zoff99 27 if (di->label && e->text_size)
2118     {
2119     struct graphics_font *font = get_font(gra, e->text_size);
2120     struct graphics_gc *gc_background = dc->gc_background;
2121     if (!gc_background && e->u.circle.background_color.a)
2122     {
2123     gc_background = graphics_gc_new(gra);
2124     graphics_gc_set_foreground(gc_background, &e->u.circle.background_color);
2125     dc->gc_background = gc_background;
2126     }
2127     p.x = pa[0].x + 3;
2128     p.y = pa[0].y + 10;
2129    
2130     if (font)
2131     {
2132     gra->meth.draw_text(gra->priv, gc->priv, gc_background ? gc_background->priv : NULL, font->priv, di->label, &p, 0x10000, 0);
2133     }
2134     else
2135     {
2136     //DBG dbg(0, "Failed to get font with size %d\n", e->text_size);
2137     }
2138     }
2139     }
2140     break;
2141     case element_text:
2142     if (count && di->label)
2143 zoff99 2 {
2144 zoff99 27 struct graphics_font *font = get_font(gra, e->text_size);
2145     struct graphics_gc *gc_background = dc->gc_background;
2146    
2147     if (!gc_background && e->u.text.background_color.a)
2148     {
2149     gc_background = graphics_gc_new(gra);
2150     graphics_gc_set_foreground(gc_background, &e->u.text.background_color);
2151     dc->gc_background = gc_background;
2152 zoff99 2 }
2153    
2154     if (font)
2155 zoff99 27 {
2156     label_line(gra, gc, gc_background, font, pa, count, di->label);
2157     }
2158 zoff99 2 else
2159 zoff99 27 {
2160     //DBG dbg(0, "Failed to get font with size %d\n", e->text_size);
2161     }
2162 zoff99 2 }
2163 zoff99 27 break;
2164     case element_icon:
2165     if (count)
2166 zoff99 2 {
2167 zoff99 27 if (!img || item_is_custom_poi(di->item))
2168 zoff99 2 {
2169 zoff99 27 if (item_is_custom_poi(di->item))
2170     {
2171     char *icon;
2172     char *src;
2173     if (img)
2174     {
2175     graphics_image_free(dc->gra, img);
2176     }
2177     src = e->u.icon.src;
2178     if (!src || !src[0])
2179     {
2180     src = "%s";
2181     }
2182     icon = g_strdup_printf(src, di->label + strlen(di->label) + 1);
2183     path = graphics_icon_path(icon);
2184     g_free(icon);
2185     }
2186     else
2187     {
2188     path = graphics_icon_path(e->u.icon.src);
2189     }
2190     img = graphics_image_new_scaled_rotated(gra, path, e->u.icon.width, e->u.icon.height, e->u.icon.rotation);
2191 zoff99 2 if (img)
2192 zoff99 27 {
2193     dc->img = img;
2194     }
2195     else
2196     {
2197     dbg(0, "-- ICON MISSING -- failed to load icon '%s'\n", path);
2198     }
2199     g_free(path);
2200 zoff99 2 }
2201 zoff99 27
2202     if (img)
2203 zoff99 2 {
2204 zoff99 27 p.x = pa[0].x - img->hot.x;
2205     p.y = pa[0].y - img->hot.y;
2206     //dbg(0, "icon: '%s'\n", path);
2207     //dbg(0,"hot: %d %d\n", img->hot.x, img->hot.y);
2208     gra->meth.draw_image(gra->priv, gra->gc[0]->priv, &p, img->priv);
2209 zoff99 2 }
2210     }
2211 zoff99 27 break;
2212     case element_image:
2213     //dbg(0, "image: '%s'\n", di->label);
2214     if (gra->meth.draw_image_warp)
2215     gra->meth.draw_image_warp(gra->priv, gra->gc[0]->priv, pa, count, di->label);
2216     else
2217 zoff99 2 {
2218 zoff99 27 // dbg(0,"draw_image_warp not supported by graphics driver drawing '%s'\n",di->label);
2219 zoff99 2 }
2220 zoff99 27 break;
2221     case element_arrows:
2222     display_draw_arrows(gra, gc, pa, count);
2223     break;
2224     default:
2225     printf("Unhandled element type %d\n", e->type);
2226 zoff99 2
2227     }
2228 zoff99 27 di = di->next;
2229 zoff99 2 }
2230     }
2231     /**
2232     * FIXME
2233     * @param <>
2234     * @returns <>
2235     * @author Martin Schaller (04/2008)
2236 zoff99 27 */
2237 zoff99 2 static void xdisplay_draw_elements(struct graphics *gra, struct displaylist *display_list, struct itemgra *itm)
2238     {
2239 zoff99 27 //dbg(0,"Enter\n");
2240 zoff99 2
2241     struct element *e;
2242 zoff99 27 GList *es, *types;
2243     struct display_context *dc = &display_list->dc;
2244 zoff99 2 struct hash_entry *entry;
2245    
2246 zoff99 27 es = itm->elements;
2247 zoff99 2 while (es)
2248     {
2249 zoff99 27 //dbg(0,"*es\n");
2250     e = es->data;
2251     dc->e = e;
2252     types = itm->type;
2253 zoff99 2 while (types)
2254     {
2255 zoff99 27 dc->type = GPOINTER_TO_INT(types->data);
2256     // dbg(0,"**type=%d\n", dc->type);
2257     entry = get_hash_entry(display_list, dc->type);
2258 zoff99 2 if (entry && entry->di)
2259     {
2260 zoff99 27 //dbg(0,"++type=%s\n", item_to_name(dc->type));
2261 zoff99 2 displayitem_draw(entry->di, NULL, dc, display_list->order, 1);
2262 zoff99 27 //dbg(0,"**+gc free\n");
2263 zoff99 2 display_context_free(dc);
2264     }
2265 zoff99 27 types = g_list_next(types);
2266 zoff99 2 }
2267 zoff99 27 es = g_list_next(es);
2268 zoff99 2 }
2269     }
2270    
2271 zoff99 27 void graphics_draw_itemgra(struct graphics *gra, struct itemgra *itm, struct transformation *t, char *label)
2272 zoff99 2 {
2273 zoff99 27 ////DBG dbg(0,"ooo enter ooo\n");
2274 zoff99 2
2275     // HINT: seems to only be called from vehicle.c (draw the vehicle on screen)
2276    
2277     GList *es;
2278     struct display_context dc;
2279 zoff99 27 int max_coord = 32;
2280     char *buffer = g_alloca(sizeof(struct displayitem) + max_coord * sizeof(struct coord));
2281     struct displayitem *di = (struct displayitem *) buffer;
2282     es = itm->elements;
2283     di->item.type = type_none;
2284     di->item.id_hi = 0;
2285     di->item.id_lo = 0;
2286     di->item.map = NULL;
2287     di->label = label;
2288     dc.gra = gra;
2289     dc.gc = NULL;
2290     dc.gc_background = NULL;
2291     dc.img = NULL;
2292     dc.pro = projection_screen;
2293     dc.mindist = 0;
2294     dc.trans = t;
2295     dc.type = type_none;
2296     dc.maxlen = max_coord;
2297     while (es)
2298     {
2299     struct element *e = es->data;
2300     if (e->coord_count)
2301     {
2302     if (e->coord_count > max_coord)
2303     {
2304     //DBG dbg(0, "maximum number of coords reached: %d > %d\n", e->coord_count, max_coord);
2305     di->count = max_coord;
2306     }
2307     else
2308     di->count = e->coord_count;
2309     memcpy(di->c, e->coord, di->count * sizeof(struct coord));
2310 zoff99 2 }
2311 zoff99 27 else
2312     {
2313     di->c[0].x = 0;
2314     di->c[0].y = 0;
2315     di->count = 1;
2316     }
2317     dc.e = e;
2318     di->next = NULL;
2319     displayitem_draw(di, NULL, &dc, transform_get_scale(t), 0);
2320 zoff99 2 display_context_free(&dc);
2321 zoff99 27 es = g_list_next(es);
2322 zoff99 2 }
2323     }
2324    
2325     /**
2326     * FIXME
2327     * @param <>
2328     * @returns <>
2329     * @author Martin Schaller (04/2008)
2330 zoff99 27 */
2331 zoff99 2 static void xdisplay_draw_layer(struct displaylist *display_list, struct graphics *gra, struct layer *lay, int order)
2332     {
2333 zoff99 27 //DBG dbg(0,"ooo enter ooo\n");
2334 zoff99 2
2335     GList *itms;
2336     struct itemgra *itm;
2337 zoff99 27 int order_corrected = order;
2338     if (order_corrected < limit_order_corrected)
2339 zoff99 2 {
2340 zoff99 27 order_corrected = limit_order_corrected;
2341 zoff99 2 }
2342 zoff99 27 int order_corrected_2 = order;
2343     if (order < 0)
2344     {
2345     order_corrected_2 = 0;
2346     }
2347 zoff99 2
2348 zoff99 27 //dbg(0,"layer name=%s\n", lay->name);
2349    
2350     itms = lay->itemgras;
2351 zoff99 2 while (itms)
2352     {
2353 zoff99 27 // stop drawing is requested
2354     if (cancel_drawing_global == 1)
2355     {
2356     //DBG dbg(0, "** STOP MD 002 **\n");
2357     break;
2358     }
2359    
2360     itm = itms->data;
2361     //if (order_corrected >= itm->order.min && order_corrected <= itm->order.max)
2362     if (order_corrected_2 >= itm->order.min && order_corrected_2 <= itm->order.max)
2363     {
2364     xdisplay_draw_elements(gra, display_list, itm);
2365     }
2366     itms = g_list_next(itms);
2367     }
2368    
2369     if (strncmp("streets__tunnel", lay->name, 15) == 0)
2370     {
2371     }
2372     else if (strncmp("streets__bridge", lay->name, 15) == 0)
2373     {
2374     }
2375     // dirty hack to draw "waypoint(s)" ---------------------------
2376     else if (strncmp("Internal", lay->name, 8) == 0)
2377     {
2378     if (global_navit->route)
2379     {
2380     if (global_navit->destination_valid == 1)
2381 zoff99 2 {
2382 zoff99 27 int count_ = 0;
2383     int curr_ = 0;
2384     count_ = g_list_length(global_navit->route->destinations);
2385     if (count_ > 1)
2386     {
2387     if (!global_img_waypoint)
2388     {
2389     char *path2;
2390     path2 = graphics_icon_path("nav_waypoint_bk_center.png");
2391     global_img_waypoint = graphics_image_new_scaled_rotated(gra, path2, 59, 59, 0);
2392     g_free(path2);
2393     }
2394    
2395     struct point p2;
2396     struct coord pc77;
2397     GList *ldest = global_navit->route->destinations;
2398     while (ldest)
2399     {
2400     curr_++;
2401     if (curr_ < count_)
2402     {
2403     struct route_info *dst = ldest->data;
2404     pc77.x = dst->c.x;
2405     pc77.y = dst->c.y;
2406     //dbg(0, "draw1 curr=%d x y: %d %d\n", curr_, dst->c.x, dst->c.y);
2407     enum projection pro = transform_get_projection(global_navit->trans_cursor);
2408     transform(global_navit->trans, pro, &pc77, &p2, 1, 0, 0, NULL);
2409     // transform(global_navit->trans, projection_mg, &pc77, &p2, 1, 0, 0, NULL);
2410     p2.x = p2.x - global_img_waypoint->hot.x; // hot = 29
2411     p2.y = p2.y - global_img_waypoint->hot.y; // hot = 29
2412     gra->meth.draw_image(gra->priv, gra->gc[0]->priv, &p2, global_img_waypoint->priv);
2413     }
2414     // next dest. / waypoint
2415     ldest=g_list_next(ldest);
2416     }
2417     }
2418 zoff99 2 }
2419 zoff99 27 }
2420 zoff99 2 }
2421 zoff99 27 // dirty hack to draw "waypoint(s)" ---------------------------
2422 zoff99 2 }
2423    
2424     /**
2425     * FIXME
2426     * @param <>
2427     * @returns <>
2428     * @author Martin Schaller (04/2008)
2429 zoff99 27 */
2430 zoff99 2 static void xdisplay_draw(struct displaylist *display_list, struct graphics *gra, struct layout *l, int order)
2431     {
2432 zoff99 27 ////DBG dbg(0,"ooo enter ooo\n");
2433 zoff99 2
2434     GList *lays;
2435     struct layer *lay;
2436    
2437 zoff99 27 ////DBG dbg(0,"draw prerender map for drag!!\n");
2438 zoff99 2
2439    
2440 zoff99 27 int draw_vector_map = 1;
2441    
2442 zoff99 2 // if zoomed out too much then use prerendered map tiles
2443 zoff99 27 if (display_list->order < ORDER_USE_PRERENDERED_MAP)
2444 zoff99 2 {
2445 zoff99 27 draw_vector_map = 0;
2446 zoff99 2 }
2447    
2448 zoff99 27 ////DBG dbg(0,"ooo %d %d %d\n",display_list->order_hashed,ORDER_USE_PRERENDERED_MAP,draw_vector_map);
2449     ////DBG dbg(0,"ooo xxx ooo2\n");
2450 zoff99 2
2451     if (!draw_vector_map)
2452     {
2453     // draw prerendered big mapimage --- HERE ---
2454    
2455 zoff99 27 ////DBG dbg(0,"###### order=%d\n",display_list->order);
2456 zoff99 2 struct transformation *t;
2457 zoff99 27 t = display_list->dc.trans;
2458     ////DBG dbg(0,"###### screen center x=%d\n",t->screen_center.x);
2459     ////DBG dbg(0,"###### screen center y=%d\n",t->screen_center.y);
2460 zoff99 2
2461     struct coord *cp;
2462 zoff99 27 cp = transform_get_center(t);
2463     ////DBG dbg(0,"###### t center x=%d\n",cp->x);
2464     ////DBG dbg(0,"###### t center y=%d\n",cp->y);
2465 zoff99 2
2466     struct attr attr;
2467 zoff99 27 struct config
2468     {
2469     struct attr **attrs;
2470     struct callback_list *cbl;
2471     }*config;
2472 zoff99 2 struct point p;
2473 zoff99 27 int valid = 0;
2474 zoff99 2 // config_get_attr(config, attr_navit, &attr, NULL);
2475     if (global_navit)
2476     {
2477 zoff99 27 if ((global_navit->vehicle) && (global_navit->vehicle->vehicle))
2478 zoff99 2 {
2479 zoff99 27 ////DBG dbg(0,"###### v x=%d\n",p.x);
2480     ////DBG dbg(0,"###### v y=%d\n",p.y);
2481 zoff99 2
2482 zoff99 27 ////DBG dbg(0,"###### v2 x=%d\n",global_vehicle_pos_onscreen.x);
2483     ////DBG dbg(0,"###### v2 y=%d\n",global_vehicle_pos_onscreen.y);
2484 zoff99 2
2485 zoff99 27 ////DBG dbg(0,"### vf x=%d\n",global_navit->vehicle->last.x);
2486     ////DBG dbg(0,"### vf y=%d\n",global_navit->vehicle->last.y);
2487 zoff99 2
2488 zoff99 27 ////DBG dbg(0,"### vff x=%d\n",global_navit->vehicle->coord.x);
2489     ////DBG dbg(0,"### vff y=%d\n",global_navit->vehicle->coord.y);
2490 zoff99 2
2491 zoff99 27 int a, s;
2492 zoff99 2 struct point pnt2;
2493     vehicle_get_cursor_data(global_navit->vehicle->vehicle, &pnt2, &a, &s);
2494 zoff99 27 ////DBG dbg(0,"### vf 2 x=%d\n",pnt2.x);
2495     ////DBG dbg(0,"### vf 2 y=%d\n",pnt2.y);
2496 zoff99 2 //global_vehicle_pos_onscreen.x=pnt2.x;
2497     //global_vehicle_pos_onscreen.y=pnt2.y;
2498    
2499    
2500     struct attr pos_attr;
2501 zoff99 27 if (vehicle_get_attr(global_navit->vehicle->vehicle, attr_position_coord_geo, &pos_attr, NULL))
2502 zoff99 2 {
2503 zoff99 27 ////DBG dbg(0,"1 lat=%f, lng=%f\n",pos_attr.u.coord_geo->lat,pos_attr.u.coord_geo->lng);
2504 zoff99 2 }
2505    
2506 zoff99 27 valid = 1;
2507 zoff99 2 }
2508     }
2509    
2510 zoff99 27 ////DBG dbg(0,"###### yaw=%d\n",-t->yaw);
2511 zoff99 2 struct coord *c;
2512 zoff99 27 c = &(t->map_center);
2513     ////DBG dbg(0,"###### map center x=%d\n",c->x);
2514     ////DBG dbg(0,"###### map center y=%d\n",c->y);
2515 zoff99 2
2516 zoff99 27 enum projection pro = transform_get_projection(global_navit->trans_cursor);
2517 zoff99 2 struct coord_geo g22;
2518     struct coord *c22;
2519     struct point mcenter_pnt;
2520 zoff99 27 c22 = &(t->map_center);
2521 zoff99 2 transform_to_geo(projection_mg, c22, &g22);
2522 zoff99 27 ////DBG dbg(0,"2 lat=%f, lng=%f\n",g22.lat,g22.lng);
2523 zoff99 2 transform(global_navit->trans, pro, c22, &mcenter_pnt, 1, 0, 0, NULL);
2524 zoff99 27 ////DBG dbg(0,"xxx 5 44444xxxx=%d\n",mcenter_pnt.x);
2525     ////DBG dbg(0,"yyy 5 44444yyyy=%d\n",mcenter_pnt.y);
2526 zoff99 2
2527    
2528     struct coord c99;
2529     struct coord_geo g99;
2530     struct point cursor_pnt;
2531     struct point p99;
2532    
2533     /*
2534 zoff99 27 g99.lat=79.0;
2535     g99.lng=-170.0;
2536     transform_from_geo(pro, &g99, &c99);
2537     //DBG dbg(0,"left top lat=%f, lng=%f, x=%d y=%d\n",g99.lat,g99.lng,c99.x,c99.y);
2538     ////DBG dbg(0,"left top lat=%f, lng=%f, x=%f y=%f\n",g99.lat,g99.lng,c99.x,c99.y);
2539     ////DBG dbg(0,"0x%x,0x%x\n",c99.x,c99.y);
2540     transform(global_navit->trans, pro, &c99, &cursor_pnt, 1, 0, 0, NULL);
2541     //DBG dbg(0,"xxxxxxx=%d\n",cursor_pnt.x);
2542     //DBG dbg(0,"yyyyyyy=%d\n",cursor_pnt.y);
2543 zoff99 2
2544 zoff99 27 g99.lat=-79.0;
2545     g99.lng=170.0;
2546     transform_from_geo(pro, &g99, &c99);
2547     //DBG dbg(0,"right bottom lat=%f, lng=%f, x=%d y=%d\n",g99.lat,g99.lng,c99.x,c99.y);
2548     ////DBG dbg(0,"right bottom lat=%f, lng=%f, x=%f y=%f\n",g99.lat,g99.lng,c99.x,c99.y);
2549     transform(global_navit->trans, pro, &c99, &cursor_pnt, 1, 0, 0, NULL);
2550     //DBG dbg(0,"xxxxxxx=%d\n",cursor_pnt.x);
2551     //DBG dbg(0,"yyyyyyy=%d\n",cursor_pnt.y);
2552     */
2553 zoff99 2
2554 zoff99 27 g99.lat = 0.0;
2555     g99.lng = 0.0;
2556 zoff99 2 transform_from_geo(pro, &g99, &c99);
2557 zoff99 27 ////DBG dbg(0,"center center lat=%f, lng=%f, x=%d y=%d\n",g99.lat,g99.lng,c99.x,c99.y);
2558     ////DBG dbg(0,"center center lat=%f, lng=%f, x=%f y=%f\n",g99.lat,g99.lng,c99.x,c99.y);
2559 zoff99 2 transform(global_navit->trans, pro, &c99, &cursor_pnt, 1, 0, 0, NULL);
2560 zoff99 27 ////DBG dbg(0,"xxx44444xxxx=%d\n",cursor_pnt.x);
2561     ////DBG dbg(0,"yyy44444yyyy=%d\n",cursor_pnt.y);
2562 zoff99 2
2563     //struct coord *c77;
2564     //c77=&(t->map_center);
2565     //transform(global_navit->trans, pro, &c77, &cursor_pnt, 1, 0, 0, NULL);
2566 zoff99 27 ////DBG dbg(0,"---> cx=%d\n",cursor_pnt.x);
2567     ////DBG dbg(0,"---> cy=%d\n",cursor_pnt.y);
2568 zoff99 2
2569    
2570     // now really draw it
2571 zoff99 27 struct graphics *gra22 = display_list->dc.gra;
2572     struct graphics_gc *gc22 = display_list->dc.gc;
2573     if (!gc22)
2574 zoff99 2 {
2575 zoff99 27 gc22 = graphics_gc_new(gra22);
2576 zoff99 2 }
2577     // graphics_draw_bigmap(gra22, gc22, -t->yaw, display_list->order, g22.lat, g22.lng, c->x, c->y, t->screen_center.x, t->screen_center.y, global_vehicle_pos_onscreen.x, global_vehicle_pos_onscreen.y, valid);
2578     graphics_draw_bigmap(gra22, gc22, -t->yaw, display_list->order, g22.lat, g22.lng, cursor_pnt.x, cursor_pnt.y, mcenter_pnt.x, mcenter_pnt.y, global_vehicle_pos_onscreen.x, global_vehicle_pos_onscreen.y, valid);
2579     }
2580    
2581 zoff99 27 ////DBG dbg(0, "XXXXXYYYYYYY Draw: 001\n");
2582 zoff99 2
2583 zoff99 27 // reset value;
2584     cancel_drawing_global = 0;
2585 zoff99 2
2586 zoff99 27 lays = l->layers;
2587     while (lays)
2588     {
2589     lay = lays->data;
2590 zoff99 2 if (lay->active)
2591 zoff99 27 {
2592 zoff99 2 xdisplay_draw_layer(display_list, gra, lay, order);
2593 zoff99 27 }
2594     lays = g_list_next(lays);
2595    
2596     // stop drawing is requested
2597     if (cancel_drawing_global == 1)
2598     {
2599     //DBG dbg(0, "** STOP MD 003 **\n");
2600     break;
2601     }
2602 zoff99 2 }
2603    
2604 zoff99 27 // reset value;
2605     cancel_drawing_global = 0;
2606    
2607     ////DBG dbg(0, "XXXXXYYYYYYY Draw: 002\n");
2608    
2609 zoff99 2 #ifdef HAVE_API_ANDROID
2610     android_return_generic_int(2, 1);
2611     #endif
2612    
2613     }
2614    
2615     /**
2616     * FIXME
2617     * @param <>
2618     * @returns <>
2619     * @author Martin Schaller (04/2008)
2620 zoff99 27 */
2621 zoff99 2 extern void *route_selection;
2622    
2623 zoff99 27 static void displaylist_update_layers(struct displaylist *displaylist, GList *layers, int order)
2624 zoff99 2 {
2625 zoff99 27 ////DBG dbg(0,"ooo enter ooo\n");
2626 zoff99 2
2627 zoff99 27 int order_corrected = order;
2628 zoff99 2 //int saved=displaylist->order;
2629 zoff99 27 if (order < limit_order_corrected)
2630 zoff99 2 {
2631 zoff99 27 order_corrected = limit_order_corrected;
2632 zoff99 2 // displaylist->order=0;
2633     }
2634 zoff99 27
2635     while (layers)
2636     {
2637     struct layer *layer = layers->data;
2638     GList *itemgras = layer->itemgras;
2639     while (itemgras)
2640     {
2641     struct itemgra *itemgra = itemgras->data;
2642     GList *types = itemgra->type;
2643 zoff99 2 if (itemgra->order.min <= order_corrected && itemgra->order.max >= order_corrected)
2644     {
2645 zoff99 27 while (types)
2646     {
2647     enum item_type type = (enum item_type) types->data;
2648 zoff99 2 set_hash_entry(displaylist, type);
2649 zoff99 27 types = g_list_next(types);
2650 zoff99 2 }
2651     }
2652 zoff99 27 itemgras = g_list_next(itemgras);
2653 zoff99 2 }
2654 zoff99 27 layers = g_list_next(layers);
2655 zoff99 2 }
2656     // displaylist->order=saved;
2657     }
2658    
2659 zoff99 27 static void displaylist_update_hash(struct displaylist *displaylist)
2660 zoff99 2 {
2661 zoff99 27 ////DBG dbg(0,"ooo enter ooo\n");
2662 zoff99 2
2663 zoff99 27 displaylist->max_offset = 0;
2664 zoff99 2 clear_hash(displaylist);
2665     displaylist_update_layers(displaylist, displaylist->layout->layers, displaylist->order);
2666 zoff99 27 // dbg(1, "max offset %d\n", displaylist->max_offset);
2667 zoff99 2 }
2668    
2669 zoff99 27 static void do_draw(struct displaylist *displaylist, int cancel, int flags)
2670 zoff99 2 {
2671     struct item *item;
2672 zoff99 27 int count, max = displaylist->dc.maxlen, workload = 0;
2673     struct coord *ca = g_alloca(sizeof(struct coord) * max);
2674     struct attr attr, attr2;
2675 zoff99 2 enum projection pro;
2676 zoff99 27 int draw_vector_map = 1; // do we draw the vecotor map, or not? 0=false, 1=true
2677     int mapset_counter = 0;
2678     int mapset_need_draw = 0;
2679 zoff99 2
2680 zoff99 27 //DBG dbg(0,"ooo enter ooo %d\n",displaylist->order);
2681 zoff99 2
2682 zoff99 27 int order_corrected = displaylist->order;
2683     int saved = displaylist->order;
2684     if (order_corrected < limit_order_corrected)
2685 zoff99 2 {
2686 zoff99 27 order_corrected = limit_order_corrected;
2687 zoff99 2 }
2688    
2689     if (displaylist->order != displaylist->order_hashed || displaylist->layout != displaylist->layout_hashed)
2690     {
2691     displaylist_update_hash(displaylist);
2692 zoff99 27 displaylist->order_hashed = displaylist->order;
2693     displaylist->layout_hashed = displaylist->layout;
2694 zoff99 2
2695 zoff99 27 // //DBG dbg(0,"-----====> order (zoom) = %d",displaylist->order);
2696     // //DBG dbg(0,"-----====> order (zoom) = %d",displaylist->order_hashed);
2697 zoff99 2 // TODO // give new order (zoom) back to Java // TODO
2698     }
2699    
2700 zoff99 27 //profile(0, NULL);
2701     pro = transform_get_projection(displaylist->dc.trans);
2702 zoff99 2
2703 zoff99 27 // //DBG dbg(0,"ooo xxx ooo1\n");
2704     // //DBG dbg(0,"ooo %d %d %d\n",displaylist->order_hashed,ORDER_USE_PRERENDERED_MAP,draw_vector_map);
2705 zoff99 2
2706     // if zoomed out too much then use prerendered map tiles
2707 zoff99 27 if (displaylist->order_hashed < ORDER_USE_PRERENDERED_MAP)
2708 zoff99 2 {
2709 zoff99 27 draw_vector_map = 0;
2710 zoff99 2 }
2711    
2712 zoff99 27 // //DBG dbg(0,"ooo %d %d %d\n",displaylist->order_hashed,ORDER_USE_PRERENDERED_MAP,draw_vector_map);
2713     // //DBG dbg(0,"ooo xxx ooo2\n");
2714 zoff99 2
2715     if (!draw_vector_map)
2716     {
2717     // draw prerendered big mapimage --- HERE ---
2718    
2719 zoff99 27 ////DBG dbg(0,"###### order=%d\n",displaylist->order_hashed);
2720 zoff99 2 struct transformation *t;
2721 zoff99 27 t = displaylist->dc.trans;
2722     ////DBG dbg(0,"###### screen center x=%d\n",t->screen_center.x);
2723     ////DBG dbg(0,"###### screen center y=%d\n",t->screen_center.y);
2724 zoff99 2
2725     struct coord *cp;
2726 zoff99 27 cp = transform_get_center(t);
2727     ////DBG dbg(0,"###### t center x=%d\n",cp->x);
2728     ////DBG dbg(0,"###### t center y=%d\n",cp->y);
2729 zoff99 2
2730     struct attr attr;
2731 zoff99 27 struct config
2732     {
2733     struct attr **attrs;
2734     struct callback_list *cbl;
2735     }*config;
2736 zoff99 2 struct point p;
2737 zoff99 27 int valid = 0;
2738 zoff99 2 // config_get_attr(config, attr_navit, &attr, NULL);
2739     if (global_navit)
2740     {
2741 zoff99 27 if ((global_navit->vehicle) && (global_navit->vehicle->vehicle))
2742 zoff99 2 {
2743 zoff99 27 ////DBG dbg(0,"###### v x=%d\n",p.x);
2744     ////DBG dbg(0,"###### v y=%d\n",p.y);
2745 zoff99 2
2746 zoff99 27 ////DBG dbg(0,"###### v2 x=%d\n",global_vehicle_pos_onscreen.x);
2747     ////DBG dbg(0,"###### v2 y=%d\n",global_vehicle_pos_onscreen.y);
2748 zoff99 2
2749 zoff99 27 ////DBG dbg(0,"### vf x=%d\n",global_navit->vehicle->last.x);
2750     ////DBG dbg(0,"### vf y=%d\n",global_navit->vehicle->last.y);
2751 zoff99 2
2752 zoff99 27 ////DBG dbg(0,"### vff x=%d\n",global_navit->vehicle->coord.x);
2753     ////DBG dbg(0,"### vff y=%d\n",global_navit->vehicle->coord.y);
2754 zoff99 2
2755 zoff99 27 int a, s;
2756 zoff99 2 struct point pnt2;
2757     vehicle_get_cursor_data(global_navit->vehicle->vehicle, &pnt2, &a, &s);
2758 zoff99 27 ////DBG dbg(0,"### vf 2 x=%d\n",pnt2.x);
2759     ////DBG dbg(0,"### vf 2 y=%d\n",pnt2.y);
2760 zoff99 2 //global_vehicle_pos_onscreen.x=pnt2.x;
2761     //global_vehicle_pos_onscreen.y=pnt2.y;
2762    
2763     struct attr pos_attr;
2764 zoff99 27 if (vehicle_get_attr(global_navit->vehicle->vehicle, attr_position_coord_geo, &pos_attr, NULL))
2765 zoff99 2 {
2766 zoff99 27 ////DBG dbg(0,"1 lat=%f, lng=%f\n",pos_attr.u.coord_geo->lat,pos_attr.u.coord_geo->lng);
2767 zoff99 2 }
2768    
2769 zoff99 27 valid = 1;
2770 zoff99 2 }
2771     }
2772    
2773 zoff99 27 //DBG dbg(0,"###### yaw=%d\n",-t->yaw);
2774 zoff99 2 struct coord *c;
2775 zoff99 27 c = &(t->map_center);
2776     //DBG dbg(0,"###### map center x=%d\n",c->x);
2777     //DBG dbg(0,"###### map center y=%d\n",c->y);
2778 zoff99 2
2779 zoff99 27 enum projection pro = transform_get_projection(global_navit->trans_cursor);
2780 zoff99 2 struct coord_geo g22;
2781     struct coord *c22;
2782     struct point mcenter_pnt;
2783 zoff99 27 c22 = &(t->map_center);
2784 zoff99 2 transform_to_geo(projection_mg, c22, &g22);
2785 zoff99 27 ////DBG dbg(0,"2 lat=%f, lng=%f\n",g22.lat,g22.lng);
2786 zoff99 2 transform(global_navit->trans, pro, c22, &mcenter_pnt, 1, 0, 0, NULL);
2787 zoff99 27 ////DBG dbg(0,"xxx 5 33333xxxx=%d\n",mcenter_pnt.x);
2788     ////DBG dbg(0,"yyy 5 33333yyyy=%d\n",mcenter_pnt.y);
2789 zoff99 2
2790    
2791     struct coord c99;
2792     struct coord_geo g99;
2793     struct point cursor_pnt;
2794     struct point p99;
2795    
2796     /*
2797 zoff99 27 g99.lat=79.0;
2798     g99.lng=-170.0;
2799     transform_from_geo(pro, &g99, &c99);
2800     //DBG dbg(0,"left top lat=%f, lng=%f, x=%d y=%d\n",g99.lat,g99.lng,c99.x,c99.y);
2801     ////DBG dbg(0,"left top lat=%f, lng=%f, x=%f y=%f\n",g99.lat,g99.lng,c99.x,c99.y);
2802     ////DBG dbg(0,"0x%x,0x%x\n",c99.x,c99.y);
2803     transform(global_navit->trans, pro, &c99, &cursor_pnt, 1, 0, 0, NULL);
2804     //DBG dbg(0,"xxxxxxx=%d\n",cursor_pnt.x);
2805     //DBG dbg(0,"yyyyyyy=%d\n",cursor_pnt.y);
2806 zoff99 2
2807 zoff99 27 g99.lat=-79.0;
2808     g99.lng=170.0;
2809     transform_from_geo(pro, &g99, &c99);
2810     //DBG dbg(0,"right bottom lat=%f, lng=%f, x=%d y=%d\n",g99.lat,g99.lng,c99.x,c99.y);
2811     ////DBG dbg(0,"right bottom lat=%f, lng=%f, x=%f y=%f\n",g99.lat,g99.lng,c99.x,c99.y);
2812     transform(global_navit->trans, pro, &c99, &cursor_pnt, 1, 0, 0, NULL);
2813     //DBG dbg(0,"xxxxxxx=%d\n",cursor_pnt.x);
2814     //DBG dbg(0,"yyyyyyy=%d\n",cursor_pnt.y);
2815     */
2816 zoff99 2
2817 zoff99 27 g99.lat = 0.0;
2818     g99.lng = 0.0;
2819 zoff99 2 transform_from_geo(pro, &g99, &c99);
2820 zoff99 27 ////DBG dbg(0,"center center lat=%f, lng=%f, x=%d y=%d\n",g99.lat,g99.lng,c99.x,c99.y);
2821     ////DBG dbg(0,"center center lat=%f, lng=%f, x=%f y=%f\n",g99.lat,g99.lng,c99.x,c99.y);
2822 zoff99 2 transform(global_navit->trans, pro, &c99, &cursor_pnt, 1, 0, 0, NULL);
2823 zoff99 27 ////DBG dbg(0,"xxxx333xxx=%d\n",cursor_pnt.x);
2824     ////DBG dbg(0,"yyyy333yyy=%d\n",cursor_pnt.y);
2825 zoff99 2
2826     //struct coord *c77;
2827     //c77=&(t->map_center);
2828     //transform(global_navit->trans, pro, &c77, &cursor_pnt, 1, 0, 0, NULL);
2829 zoff99 27 ////DBG dbg(0,"---> cx=%d\n",cursor_pnt.x);
2830     ////DBG dbg(0,"---> cy=%d\n",cursor_pnt.y);
2831 zoff99 2
2832    
2833     // now really draw it
2834 zoff99 27 struct graphics *gra22 = displaylist->dc.gra;
2835     struct graphics_gc *gc22 = displaylist->dc.gc;
2836     if (!gc22)
2837 zoff99 2 {
2838 zoff99 27 gc22 = graphics_gc_new(gra22);
2839 zoff99 2 }
2840 zoff99 27 //DBG dbg(0,"graphics_draw_bigmap s\n");
2841 zoff99 2 graphics_draw_bigmap(gra22, gc22, -t->yaw, displaylist->order, g22.lat, g22.lng, cursor_pnt.x, cursor_pnt.y, mcenter_pnt.x, mcenter_pnt.y, global_vehicle_pos_onscreen.x, global_vehicle_pos_onscreen.y, valid);
2842 zoff99 27 //DBG dbg(0,"graphics_draw_bigmap e\n");
2843 zoff99 2 }
2844    
2845 zoff99 27 //DBG dbg(0,"xxx uuu xxx\n");
2846 zoff99 2
2847 zoff99 27 displaylist->order = order_corrected;
2848 zoff99 2
2849 zoff99 27 //DBG dbg(0, "XXXXXYYYYYYY Draw: 003\n");
2850    
2851     // reset value;
2852     cancel_drawing_global = 0;
2853    
2854 zoff99 2 while (!cancel)
2855     {
2856     if (!displaylist->msh)
2857 zoff99 27 {
2858     displaylist->msh = mapset_open(displaylist->ms);
2859     }
2860    
2861     if (!displaylist->m)
2862     {
2863     displaylist->m = mapset_next(displaylist->msh, 1);
2864     if (!displaylist->m)
2865     {
2866 zoff99 2 mapset_close(displaylist->msh);
2867 zoff99 27 displaylist->msh = NULL;
2868 zoff99 2 break;
2869     }
2870    
2871     mapset_counter++;
2872 zoff99 27 mapset_need_draw = 1;
2873 zoff99 2 struct attr map_name_attr;
2874 zoff99 27
2875     if (map_get_attr(displaylist->m, attr_name, &map_name_attr, NULL))
2876 zoff99 2 {
2877 zoff99 27 // //DBG dbg(0,"map name=%s",map_name_attr.u.str);
2878 zoff99 2 if (strncmp("_ms_sdcard_map:", map_name_attr.u.str, 15) == 0)
2879     {
2880     if (strncmp("_ms_sdcard_map:/sdcard/zanavi/maps/borders.bin", map_name_attr.u.str, 41) == 0)
2881     {
2882     // if its the countryborder map, always draw it
2883 zoff99 27 mapset_need_draw = 0; // --> now dont even draw borders on low zoom level, we have prerendered image
2884 zoff99 2 }
2885     else
2886     {
2887     // if its an sdcard street map, don't draw it
2888 zoff99 27 mapset_need_draw = 0;
2889 zoff99 2 }
2890     }
2891     }
2892    
2893 zoff99 27 ////DBG dbg(0,"---------==============>>>>>>>>>> ***** %d ****",mapset_counter);
2894 zoff99 2
2895 zoff99 27 displaylist->dc.pro = map_projection(displaylist->m);
2896     displaylist->conv = map_requires_conversion(displaylist->m);
2897 zoff99 2 if (route_selection)
2898     {
2899 zoff99 27 displaylist->sel = route_selection;
2900 zoff99 2 }
2901     else
2902     {
2903 zoff99 27 displaylist->sel = transform_get_selection(displaylist->dc.trans, displaylist->dc.pro, displaylist->order);
2904 zoff99 2 }
2905 zoff99 27 displaylist->mr = map_rect_new(displaylist->m, displaylist->sel);
2906 zoff99 2 }
2907 zoff99 27
2908 zoff99 2 if (displaylist->mr)
2909     {
2910     // draw vector map, or not?
2911 zoff99 27 //dbg(0,"draw_vector_map=%d mapset_need_draw=%d\n", draw_vector_map, mapset_need_draw);
2912 zoff99 2 if ((draw_vector_map) || (mapset_need_draw == 1))
2913     {
2914 zoff99 27
2915     //dbg(0, "XXXXXYYYYYYY Draw: A.01\n");
2916    
2917     while ((item = map_rect_get_item(displaylist->mr)))
2918 zoff99 2 {
2919 zoff99 27 int label_count = 0;
2920 zoff99 2 char *labels[2];
2921     struct hash_entry *entry;
2922    
2923 zoff99 27 if (cancel_drawing_global == 1)
2924     {
2925     // stop drawing map is requested
2926     //DBG dbg(0, "** STOP MD 001 **\n");
2927     break;
2928     }
2929    
2930 zoff99 2 if (item == &busy_item)
2931     {
2932     if (displaylist->workload)
2933     {
2934     // restore order :-)
2935 zoff99 27 displaylist->order = saved;
2936 zoff99 2 return;
2937     }
2938     else
2939 zoff99 27 {
2940 zoff99 2 continue;
2941 zoff99 27 }
2942 zoff99 2 }
2943    
2944 zoff99 27 entry = get_hash_entry(displaylist, item->type);
2945 zoff99 2
2946 zoff99 27 //dbg(0, "XXXXXYYYYYYY Draw: A.item1 %p %i\n", entry, item->type);
2947    
2948     // DEBUG -------- zoffzoff
2949     // DEBUG -------- zoffzoff
2950     // DEBUG -------- zoffzoff
2951     //item_dump_attr_stdout(item, displaylist->m);
2952     // DEBUG -------- zoffzoff
2953     // DEBUG -------- zoffzoff
2954     // DEBUG -------- zoffzoff
2955    
2956 zoff99 2 if (!entry)
2957 zoff99 27 {
2958 zoff99 2 continue;
2959 zoff99 27 }
2960 zoff99 2
2961 zoff99 27 count = item_coord_get_within_selection(item, ca, item->type < type_line ? 1 : max, displaylist->sel);
2962 zoff99 2
2963 zoff99 27 if (!count)
2964     {
2965 zoff99 2 continue;
2966 zoff99 27 }
2967 zoff99 2
2968 zoff99 27 //dbg(0, "XXXXXYYYYYYY Draw: A.item2\n");
2969    
2970 zoff99 2 if (displaylist->dc.pro != pro)
2971     transform_from_to_count(ca, displaylist->dc.pro, ca, pro, count);
2972    
2973     if (count == max)
2974     {
2975 zoff99 27 //DBG dbg(0,"point count overflow %d for %s "ITEM_ID_FMT"\n", count,item_to_name(item->type),ITEM_ID_ARGS(*item));
2976     displaylist->dc.maxlen = max * 2;
2977 zoff99 2 }
2978    
2979     if (item_is_custom_poi(*item))
2980     {
2981     if (item_attr_get(item, attr_icon_src, &attr2))
2982 zoff99 27 labels[1] = map_convert_string(displaylist->m, attr2.u.str);
2983 zoff99 2 else
2984 zoff99 27 labels[1] = NULL;
2985     label_count = 2;
2986 zoff99 2 }
2987     else
2988     {
2989 zoff99 27 labels[1] = NULL;
2990     label_count = 0;
2991 zoff99 2 }
2992    
2993     if (item_attr_get(item, attr_label, &attr))
2994     {
2995 zoff99 27 labels[0] = attr.u.str;
2996 zoff99 2 if (!label_count)
2997 zoff99 27 {
2998     label_count = 2;
2999     }
3000 zoff99 2 }
3001     else
3002     {
3003 zoff99 27 labels[0] = NULL;
3004 zoff99 2 }
3005    
3006 zoff99 27 // DEBUG -------- zoffzoff
3007     // DEBUG -------- zoffzoff
3008     // DEBUG -------- zoffzoff
3009     // item_dump_attr_stdout(item, displaylist->m);
3010     // DEBUG -------- zoffzoff
3011     // DEBUG -------- zoffzoff
3012     // DEBUG -------- zoffzoff
3013 zoff99 2
3014     struct attr attr_77;
3015     if (item_attr_get(item, attr_flags, &attr_77))
3016     {
3017     // dbg(0,"uuuuuuuuuuuuu %s uuuuu %d\n",item_to_name(item->type), attr_77.u.num);
3018 zoff99 27 item->flags = attr_77.u.num;
3019 zoff99 2 }
3020     else
3021     {
3022 zoff99 27 item->flags = 0;
3023 zoff99 2 }
3024    
3025     //struct attr *attr88;
3026     //if (item_attr_get(item, attr_flags, &attr88))
3027     //{
3028 zoff99 27 ////DBG dbg(0,"item flags=%d\n",attr88->u.num);
3029 zoff99 2 //}
3030     //attr88=NULL;
3031    
3032 zoff99 27
3033     /*
3034     if (item->flags & AF_UNDERGROUND)
3035     {
3036     dbg(0,"is UNDERGROUND\n");
3037     }
3038     else if (item->flags & AF_BRIDGE)
3039     {
3040     dbg(0,"is BRIDGE\n");
3041     }
3042     */
3043    
3044 zoff99 2 if (displaylist->conv && label_count)
3045     {
3046 zoff99 27 labels[0] = map_convert_string(displaylist->m, labels[0]);
3047 zoff99 2 display_add(entry, item, count, ca, labels, label_count);
3048     map_convert_free(labels[0]);
3049     }
3050     else
3051     {
3052     display_add(entry, item, count, ca, labels, label_count);
3053     }
3054    
3055     if (labels[1])
3056     {
3057     map_convert_free(labels[1]);
3058     }
3059    
3060     workload++;
3061    
3062     if (workload == displaylist->workload)
3063     {
3064     // restore order :-)
3065 zoff99 27 displaylist->order = saved;
3066     // reset value;
3067     cancel_drawing_global = 0;
3068 zoff99 2 return;
3069     }
3070 zoff99 27 } // while item=map_rect_get_item
3071    
3072     ////DBG dbg(0, "XXXXXYYYYYYY Draw: A.02\n");
3073    
3074 zoff99 2 map_rect_destroy(displaylist->mr);
3075     }
3076     }
3077    
3078     if (!route_selection)
3079     {
3080     map_selection_destroy(displaylist->sel);
3081     }
3082    
3083 zoff99 27 displaylist->mr = NULL;
3084     displaylist->sel = NULL;
3085     displaylist->m = NULL;
3086 zoff99 2 } // while ----
3087    
3088 zoff99 27 //DBG dbg(0, "XXXXXYYYYYYY Draw: 004\n");
3089    
3090     // reset value;
3091     cancel_drawing_global = 0;
3092    
3093 zoff99 2 // restore order :-)
3094 zoff99 27 displaylist->order = saved;
3095 zoff99 2
3096 zoff99 27 // profile(1,"process_selection\n");
3097    
3098     //DBG dbg(0,"ee s\n");
3099 zoff99 2 if (displaylist->idle_ev)
3100 zoff99 27 {
3101 zoff99 2 event_remove_idle(displaylist->idle_ev);
3102 zoff99 27 }
3103     //DBG dbg(0,"ee e\n");
3104     displaylist->idle_ev = NULL;
3105 zoff99 2 callback_destroy(displaylist->idle_cb);
3106 zoff99 27 displaylist->idle_cb = NULL;
3107     displaylist->busy = 0;
3108 zoff99 2
3109     // graphics_process_selection(displaylist->dc.gra, displaylist);
3110    
3111 zoff99 27 //profile(1, "draw\n");
3112    
3113     //DBG dbg(0, "XXXXXYYYYYYY Draw: 005\n");
3114    
3115     if (!cancel)
3116 zoff99 2 {
3117     int flags2 = flags;
3118     if (!(flags2 & 2))
3119     {
3120     if (!draw_vector_map)
3121     {
3122     // dont clean bg of screen when drawing prerendered tiles
3123     flags2 = flags2 + 2;
3124     }
3125     }
3126 zoff99 27 //DBG dbg(0,"call graphics_displaylist_draw 3")
3127 zoff99 2 graphics_displaylist_draw(displaylist->dc.gra, displaylist, displaylist->dc.trans, displaylist->layout, flags2);
3128     }
3129    
3130 zoff99 27 //DBG dbg(0, "XXXXXYYYYYYY Draw: 006\n");
3131    
3132 zoff99 2 #ifdef HAVE_API_ANDROID
3133     android_return_generic_int(2, 0);
3134     #endif
3135    
3136     map_rect_destroy(displaylist->mr);
3137     if (!route_selection)
3138     map_selection_destroy(displaylist->sel);
3139     mapset_close(displaylist->msh);
3140 zoff99 27 displaylist->mr = NULL;
3141     displaylist->sel = NULL;
3142     displaylist->m = NULL;
3143     displaylist->msh = NULL;
3144     //profile(1, "callback\n");
3145 zoff99 2 callback_call_1(displaylist->cb, cancel);
3146 zoff99 27 //profile(0, "end\n");
3147     //DBG dbg(0,"leave\n");
3148 zoff99 2 }
3149    
3150     /**
3151     * FIXME
3152     * @param <>
3153     * @returns <>
3154     * @author Martin Schaller (04/2008)
3155 zoff99 27 */
3156 zoff99 2 void graphics_displaylist_draw(struct graphics *gra, struct displaylist *displaylist, struct transformation *trans, struct layout *l, int flags)
3157     {
3158 zoff99 27 //DBG dbg(0,"ooo enter ooo\n");
3159 zoff99 2
3160 zoff99 27 int order = transform_get_order(trans);
3161     displaylist->dc.trans = trans;
3162     displaylist->dc.gra = gra;
3163     displaylist->dc.mindist = transform_get_scale(trans) / 2;
3164     //DBG dbg(0,"1\n");
3165 zoff99 2 // FIXME find a better place to set the background color
3166     if (l)
3167     {
3168     graphics_gc_set_background(gra->gc[0], &l->color);
3169     graphics_gc_set_foreground(gra->gc[0], &l->color);
3170     gra->default_font = g_strdup(l->font);
3171     }
3172 zoff99 27 //DBG dbg(0,"2\n");
3173 zoff99 2 graphics_background_gc(gra, gra->gc[0]);
3174     if (flags & 1)
3175     {
3176 zoff99 27 //DBG dbg(0,"3\n");
3177 zoff99 2 callback_list_call_attr_0(gra->cbl, attr_predraw);
3178 zoff99 27 //DBG dbg(0,"4\n");
3179 zoff99 2 }
3180 zoff99 27 gra->meth.draw_mode(gra->priv, (flags & 8) ? draw_mode_begin_clear : draw_mode_begin);
3181     //DBG dbg(0,"5\n");
3182 zoff99 2 if (!(flags & 2))
3183 zoff99 27 {
3184     //DBG dbg(0,"6\n");
3185 zoff99 2 // clear the display/screen/whatever here
3186 zoff99 27 gra->meth.draw_rectangle(gra->priv, gra->gc[0]->priv, &gra->r.lu, gra->r.rl.x - gra->r.lu.x, gra->r.rl.y - gra->r.lu.y);
3187     //DBG dbg(0,"7\n");
3188     }
3189 zoff99 2 if (l)
3190     {
3191 zoff99 27 //DBG dbg(0,"8\n");
3192     // //DBG dbg(0,"o , l->d = %d , %d\n",order,l->order_delta);
3193     xdisplay_draw(displaylist, gra, l, order + l->order_delta);
3194     //DBG dbg(0,"9\n");
3195 zoff99 2 }
3196     if (flags & 1)
3197     {
3198 zoff99 27 //DBG dbg(0,"10\n");
3199 zoff99 2 callback_list_call_attr_0(gra->cbl, attr_postdraw);
3200 zoff99 27 //DBG dbg(0,"11\n");
3201 zoff99 2 }
3202     if (!(flags & 4))
3203 zoff99 27 {
3204     //DBG dbg(0,"12\n");
3205 zoff99 2 gra->meth.draw_mode(gra->priv, draw_mode_end);
3206 zoff99 27 //DBG dbg(0,"13\n");
3207     }
3208    
3209     //DBG dbg(0,"leave\n");
3210 zoff99 2 }
3211    
3212     static void graphics_load_mapset(struct graphics *gra, struct displaylist *displaylist, struct mapset *mapset, struct transformation *trans, struct layout *l, int async, struct callback *cb, int flags)
3213     {
3214 zoff99 27 int order = transform_get_order(trans);
3215 zoff99 2
3216 zoff99 27 //DBG dbg(0,"enter displaylist->busy=%d\n",displaylist->busy);
3217     ////DBG dbg(0,"async=%d\n",async);
3218 zoff99 2 if (displaylist->busy)
3219     {
3220     if (async == 1)
3221     {
3222     return;
3223     }
3224 zoff99 27 //DBG dbg(0,"**draw 1");
3225 zoff99 2 do_draw(displaylist, 1, flags);
3226     }
3227     xdisplay_free(displaylist);
3228    
3229 zoff99 27 displaylist->dc.gra = gra;
3230     displaylist->ms = mapset;
3231     displaylist->dc.trans = trans;
3232     displaylist->workload = async ? 100 : 0;
3233     displaylist->cb = cb;
3234 zoff99 2 displaylist->seq++;
3235    
3236     if (l)
3237     {
3238 zoff99 27 order += l->order_delta;
3239 zoff99 2 }
3240 zoff99 27 displaylist->order = order;
3241     displaylist->busy = 1;
3242     displaylist->layout = l;
3243 zoff99 2
3244     if (async)
3245     {
3246 zoff99 27 //DBG dbg(0,"§§async");
3247     if (!displaylist->idle_cb)
3248 zoff99 2 {
3249 zoff99 27 //DBG dbg(0,"§§async --> callback");
3250     displaylist->idle_cb = callback_new_3(callback_cast(do_draw), displaylist, 0, flags);
3251 zoff99 2 }
3252 zoff99 27 //DBG dbg(0,"§§async --> add idle");
3253     displaylist->idle_ev = event_add_idle(50, displaylist->idle_cb);
3254 zoff99 2 }
3255     else
3256     {
3257 zoff99 27 //DBG dbg(0,"@@sync");
3258 zoff99 2 do_draw(displaylist, 0, flags);
3259     }
3260     }
3261    
3262     /**
3263     * FIXME
3264     * @param <>
3265     * @returns <>
3266     * @author Martin Schaller (04/2008)
3267 zoff99 27 */
3268 zoff99 2 void graphics_draw(struct graphics *gra, struct displaylist *displaylist, struct mapset *mapset, struct transformation *trans, struct layout *l, int async, struct callback *cb, int flags)
3269     {
3270 zoff99 27 //DBG dbg(0,"ooo enter ooo\n");
3271 zoff99 2
3272     graphics_load_mapset(gra, displaylist, mapset, trans, l, async, cb, flags);
3273     }
3274    
3275 zoff99 27 int graphics_draw_cancel(struct graphics *gra, struct displaylist *displaylist)
3276 zoff99 2 {
3277 zoff99 27 //DBG dbg(0,"ooo enter ooo\n");
3278 zoff99 2
3279     if (!displaylist->busy)
3280     return 0;
3281     do_draw(displaylist, 1, 0);
3282     return 1;
3283     }
3284    
3285     /**
3286     * FIXME
3287     * @param <>
3288     * @returns <>
3289     * @author Martin Schaller (04/2008)
3290 zoff99 27 */
3291     struct displaylist_handle
3292     {
3293 zoff99 2 struct displaylist *dl;
3294     struct displayitem *di;
3295     int hashidx;
3296     };
3297    
3298     /**
3299     * FIXME
3300     * @param <>
3301     * @returns <>
3302     * @author Martin Schaller (04/2008)
3303 zoff99 27 */
3304 zoff99 2 struct displaylist_handle * graphics_displaylist_open(struct displaylist *displaylist)
3305     {
3306     struct displaylist_handle *ret;
3307    
3308     ret=g_new0(struct displaylist_handle, 1);
3309 zoff99 27 ret->dl = displaylist;
3310 zoff99 2
3311     return ret;
3312     }
3313    
3314     /**
3315     * FIXME
3316     * @param <>
3317     * @returns <>
3318     * @author Martin Schaller (04/2008)
3319 zoff99 27 */
3320 zoff99 2 struct displayitem * graphics_displaylist_next(struct displaylist_handle *dlh)
3321     {
3322     struct displayitem *ret;
3323     if (!dlh)
3324     return NULL;
3325 zoff99 27 for (;;)
3326     {
3327     if (dlh->di)
3328     {
3329     ret = dlh->di;
3330     dlh->di = ret->next;
3331 zoff99 2 break;
3332     }
3333 zoff99 27 if (dlh->hashidx == HASH_SIZE_GRAPHICS_)
3334     {
3335     ret = NULL;
3336 zoff99 2 break;
3337     }
3338     if (dlh->dl->hash_entries[dlh->hashidx].type)
3339 zoff99 27 dlh->di = dlh->dl->hash_entries[dlh->hashidx].di;
3340 zoff99 2 dlh->hashidx++;
3341     }
3342     return ret;
3343     }
3344    
3345     /**
3346     * FIXME
3347     * @param <>
3348     * @returns <>
3349     * @author Martin Schaller (04/2008)
3350 zoff99 27 */
3351 zoff99 2 void graphics_displaylist_close(struct displaylist_handle *dlh)
3352     {
3353     g_free(dlh);
3354     }
3355    
3356     /**
3357     * FIXME
3358     * @param <>
3359     * @returns <>
3360     * @author Martin Schaller (04/2008)
3361 zoff99 27 */
3362 zoff99 2 struct displaylist * graphics_displaylist_new(void)
3363     {
3364     struct displaylist *ret=g_new0(struct displaylist, 1);
3365    
3366 zoff99 27 ret->dc.maxlen = 16384;
3367 zoff99 2
3368     return ret;
3369     }
3370    
3371     /**
3372     * FIXME
3373     * @param <>
3374     * @returns <>
3375     * @author Martin Schaller (04/2008)
3376 zoff99 27 */
3377 zoff99 2 struct item * graphics_displayitem_get_item(struct displayitem *di)
3378     {
3379     return &di->item;
3380     }
3381    
3382 zoff99 27 int graphics_displayitem_get_coord_count(struct displayitem *di)
3383 zoff99 2 {
3384     return di->count;
3385     }
3386    
3387     /**
3388     * FIXME
3389     * @param <>
3390     * @returns <>
3391     * @author Martin Schaller (04/2008)
3392 zoff99 27 */
3393 zoff99 2 char * graphics_displayitem_get_label(struct displayitem *di)
3394     {
3395     return di->label;
3396     }
3397    
3398 zoff99 27 int graphics_displayitem_get_displayed(struct displayitem *di)
3399 zoff99 2 {
3400     return 1;
3401     }
3402    
3403     /**
3404     * FIXME
3405     * @param <>
3406     * @returns <>
3407     * @author Martin Schaller (04/2008)
3408 zoff99 27 */
3409 zoff99 2 static int within_dist_point(struct point *p0, struct point *p1, int dist)
3410     {
3411     if (p0->x == 32767 || p0->y == 32767 || p1->x == 32767 || p1->y == 32767)
3412     return 0;
3413     if (p0->x == -32768 || p0->y == -32768 || p1->x == -32768 || p1->y == -32768)
3414     return 0;
3415 zoff99 27 if ((p0->x - p1->x) * (p0->x - p1->x) + (p0->y - p1->y) * (p0->y - p1->y) <= dist * dist)
3416     {
3417     return 1;
3418     }
3419     return 0;
3420 zoff99 2 }
3421    
3422     /**
3423     * FIXME
3424     * @param <>
3425     * @returns <>
3426     * @author Martin Schaller (04/2008)
3427 zoff99 27 */
3428 zoff99 2 static int within_dist_line(struct point *p, struct point *line_p0, struct point *line_p1, int dist)
3429     {
3430 zoff99 27 int vx, vy, wx, wy;
3431     int c1, c2;
3432 zoff99 2 struct point line_p;
3433    
3434 zoff99 27 if (line_p0->x < line_p1->x)
3435     {
3436 zoff99 2 if (p->x < line_p0->x - dist)
3437     return 0;
3438     if (p->x > line_p1->x + dist)
3439     return 0;
3440 zoff99 27 }
3441     else
3442     {
3443 zoff99 2 if (p->x < line_p1->x - dist)
3444     return 0;
3445     if (p->x > line_p0->x + dist)
3446     return 0;
3447     }
3448 zoff99 27 if (line_p0->y < line_p1->y)
3449     {
3450 zoff99 2 if (p->y < line_p0->y - dist)
3451     return 0;
3452     if (p->y > line_p1->y + dist)
3453     return 0;
3454 zoff99 27 }
3455     else
3456     {
3457 zoff99 2 if (p->y < line_p1->y - dist)
3458     return 0;
3459     if (p->y > line_p0->y + dist)
3460     return 0;
3461     }
3462    
3463 zoff99 27 vx = line_p1->x - line_p0->x;
3464     vy = line_p1->y - line_p0->y;
3465     wx = p->x - line_p0->x;
3466     wy = p->y - line_p0->y;
3467 zoff99 2
3468 zoff99 27 c1 = vx * wx + vy * wy;
3469     if (c1 <= 0)
3470 zoff99 2 return within_dist_point(p, line_p0, dist);
3471 zoff99 27 c2 = vx * vx + vy * vy;
3472     if (c2 <= c1)
3473 zoff99 2 return within_dist_point(p, line_p1, dist);
3474    
3475 zoff99 27 line_p.x = line_p0->x + vx * c1 / c2;
3476     line_p.y = line_p0->y + vy * c1 / c2;
3477 zoff99 2 return within_dist_point(p, &line_p, dist);
3478     }
3479    
3480     /**
3481     * FIXME
3482     * @param <>
3483     * @returns <>
3484     * @author Martin Schaller (04/2008)
3485 zoff99 27 */
3486 zoff99 2 static int within_dist_polyline(struct point *p, struct point *line_pnt, int count, int dist, int close)
3487     {
3488     int i;
3489 zoff99 27 for (i = 0; i < count - 1; i++)
3490     {
3491     if (within_dist_line(p, line_pnt + i, line_pnt + i + 1, dist))
3492     {
3493 zoff99 2 return 1;
3494     }
3495     }
3496     if (close)
3497 zoff99 27 return (within_dist_line(p, line_pnt, line_pnt + count - 1, dist));
3498 zoff99 2 return 0;
3499     }
3500    
3501     /**
3502     * FIXME
3503     * @param <>
3504     * @returns <>
3505     * @author Martin Schaller (04/2008)
3506 zoff99 27 */
3507 zoff99 2 static int within_dist_polygon(struct point *p, struct point *poly_pnt, int count, int dist)
3508     {
3509     int i, j, c = 0;
3510 zoff99 27 for (i = 0, j = count - 1; i < count; j = i++)
3511     {
3512     if ((((poly_pnt[i].y <= p->y) && (p->y < poly_pnt[j].y)) || ((poly_pnt[j].y <= p->y) && (p->y < poly_pnt[i].y))) && (p->x < (poly_pnt[j].x - poly_pnt[i].x) * (p->y - poly_pnt[i].y) / (poly_pnt[j].y - poly_pnt[i].y) + poly_pnt[i].x))
3513     c = !c;
3514     }
3515     if (!c)
3516 zoff99 2 return within_dist_polyline(p, poly_pnt, count, dist, 1);
3517 zoff99 27 return c;
3518 zoff99 2 }
3519    
3520     /**
3521     * FIXME
3522     * @param <>
3523     * @returns <>
3524     * @author Martin Schaller (04/2008)
3525 zoff99 27 */
3526 zoff99 2 int graphics_displayitem_within_dist(struct displaylist *displaylist, struct displayitem *di, struct point *p, int dist)
3527     {
3528 zoff99 27 struct point *pa = g_alloca(sizeof(struct point) * displaylist->dc.maxlen);
3529 zoff99 2 int count;
3530    
3531 zoff99 27 count = transform(displaylist->dc.trans, displaylist->dc.pro, di->c, pa, di->count, 1, 0, NULL);
3532 zoff99 2
3533 zoff99 27 if (di->item.type < type_line)
3534     {
3535 zoff99 2 return within_dist_point(p, &pa[0], dist);
3536     }
3537 zoff99 27 if (di->item.type < type_area)
3538     {
3539 zoff99 2 return within_dist_polyline(p, pa, count, dist, 0);
3540     }
3541     return within_dist_polygon(p, pa, count, dist);
3542     }
3543    
3544 zoff99 27 static void graphics_process_selection_item(struct displaylist *dl, struct item *item)
3545 zoff99 2 {
3546     #if 0 /* FIXME */
3547     struct displayitem di,*di_res;
3548     GHashTable *h;
3549     int count,max=dl->dc.maxlen;
3550     struct coord ca[max];
3551     struct attr attr;
3552     struct map_rect *mr;
3553    
3554     di.item=*item;
3555     di.label=NULL;
3556     di.count=0;
3557     h=g_hash_table_lookup(dl->dl, GINT_TO_POINTER(di.item.type));
3558 zoff99 27 if (h)
3559     {
3560 zoff99 2 di_res=g_hash_table_lookup(h, &di);
3561 zoff99 27 if (di_res)
3562     {
3563 zoff99 2 di.item.type=(enum item_type)item->priv_data;
3564     display_add(dl, &di.item, di_res->count, di_res->c, NULL, 0);
3565     return;
3566     }
3567     }
3568     mr=map_rect_new(item->map, NULL);
3569     item=map_rect_get_item_byid(mr, item->id_hi, item->id_lo);
3570     count=item_coord_get(item, ca, item->type < type_line ? 1: max);
3571     if (!item_attr_get(item, attr_label, &attr))
3572 zoff99 27 attr.u.str=NULL;
3573     if (dl->conv && attr.u.str && attr.u.str[0])
3574     {
3575 zoff99 2 char *str=map_convert_string(item->map, attr.u.str);
3576     display_add(dl, item, count, ca, &str, 1);
3577     map_convert_free(str);
3578 zoff99 27 }
3579     else
3580     display_add(dl, item, count, ca, &attr.u.str, 1);
3581 zoff99 2 map_rect_destroy(mr);
3582     #endif
3583     }
3584    
3585 zoff99 27 void graphics_add_selection(struct graphics *gra, struct item *item, enum item_type type, struct displaylist *dl)
3586 zoff99 2 {
3587     struct item *item_dup=g_new(struct item, 1);
3588 zoff99 27 *item_dup = *item;
3589     item_dup->priv_data = (void *) type;
3590     gra->selection = g_list_append(gra->selection, item_dup);
3591 zoff99 2 if (dl)
3592     graphics_process_selection_item(dl, item_dup);
3593     }
3594    
3595 zoff99 27 void graphics_remove_selection(struct graphics *gra, struct item *item, enum item_type type, struct displaylist *dl)
3596 zoff99 2 {
3597     GList *curr;
3598     int found;
3599    
3600 zoff99 27 for (;;)
3601     {
3602     curr = gra->selection;
3603     found = 0;
3604     while (curr)
3605     {
3606     struct item *sitem = curr->data;
3607     if (item_is_equal(*item, *sitem))
3608     {
3609     if (dl)
3610     {
3611 zoff99 2 struct displayitem di;
3612     /* Unused Variable
3613 zoff99 27 GHashTable *h; */
3614     di.item = *sitem;
3615     di.label = NULL;
3616     di.count = 0;
3617     di.item.type = type;
3618 zoff99 2 #if 0 /* FIXME */
3619     h=g_hash_table_lookup(dl->dl, GINT_TO_POINTER(di.item.type));
3620     if (h)
3621 zoff99 27 g_hash_table_remove(h, &di);
3622 zoff99 2 #endif
3623     }
3624     g_free(sitem);
3625 zoff99 27 gra->selection = g_list_remove(gra->selection, curr->data);
3626     found = 1;
3627 zoff99 2 break;
3628     }
3629     }
3630     if (!found)
3631     return;
3632     }
3633     }
3634    
3635 zoff99 27 void graphics_clear_selection(struct graphics *gra, struct displaylist *dl)
3636 zoff99 2 {
3637 zoff99 27 while (gra->selection)
3638     {
3639     struct item *item = (struct item *) gra->selection->data;
3640     graphics_remove_selection(gra, item, (enum item_type) item->priv_data, dl);
3641 zoff99 2 }
3642     }
3643    
3644 zoff99 27 static void graphics_process_selection(struct graphics *gra, struct displaylist *dl)
3645 zoff99 2 {
3646     GList *curr;
3647    
3648 zoff99 27 curr = gra->selection;
3649     while (curr)
3650     {
3651     struct item *item = curr->data;
3652 zoff99 2 graphics_process_selection_item(dl, item);
3653 zoff99 27 curr = g_list_next(curr);
3654 zoff99 2 }
3655     }

   
Visit the ZANavi Wiki