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

Contents of /navit/navit/graphics.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 46 - (hide annotations) (download)
Mon Aug 24 18:55:43 2015 UTC (8 years, 7 months ago) by zoff99
File MIME type: text/plain
File size: 143012 byte(s)
v2.0.47
1 zoff99 2 /**
2 zoff99 27 * ZANavi, Zoff Android Navigation system.
3 zoff99 40 * Copyright (C) 2011-2014 Zoff <zoff@zoff.cc>
4 zoff99 27 *
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 zoff99 40 #include "track.h"
75 zoff99 2 #include "navit.h"
76 zoff99 27 #include "route.h"
77 zoff99 2
78 zoff99 30 #ifdef HAVE_API_ANDROID
79     // nothing todo for android
80     #else
81     // linux seems to need this explicitly
82     #include "pthread.h"
83     #endif
84    
85     static pthread_cond_t uiConditionVariable = PTHREAD_COND_INITIALIZER;
86     static pthread_mutex_t uiConditionMutex = PTHREAD_MUTEX_INITIALIZER;
87    
88 zoff99 40
89    
90    
91    
92     // #define NAVIT_FUNC_CALLS_DEBUG_PRINT 1
93    
94    
95     // --------------- debug function calls ------------------
96     // --------------- debug function calls ------------------
97     #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
98     #undef return2
99     #define return2 dbg_func(0, global_func_indent_counter, "return(%d)\n", __LINE__);global_func_indent_counter--;return
100    
101     #define __F_START__ global_func_indent_counter++;dbg_func(0, global_func_indent_counter, "enter\n");
102     #define __F_END__ dbg_func(0, global_func_indent_counter, "leave\n");global_func_indent_counter--;
103     #else
104     #undef return2
105     #define return2 return
106    
107     #define __F_START__
108     #define __F_END__
109     #endif
110     // --------------- debug function calls ------------------
111     // --------------- debug function calls ------------------
112    
113    
114    
115    
116    
117    
118 zoff99 2 //##############################################################################################################
119     //# Description:
120     //# Comment:
121     //# Authors: Martin Schaller (04/2008)
122     //##############################################################################################################
123    
124 zoff99 34 // above what "order" level to show only prerendered-map or vector-map
125     #define ORDER_USE_PRERENDERED_MAP 5
126     #define ORDER_USE_NORMAL_MAP 6
127 zoff99 40 #define ORDER_USE_PRERENDERED_MAP__C 4
128     #define ORDER_USE_NORMAL_MAP__C 3
129 zoff99 34 #define ORDER_USE_BORDERS_MAP 14
130    
131 zoff99 29 // minimum (line legth * 32) squared (in pixel) to show text label
132 zoff99 28 #define MIN_LINE_LENGTH_FOR_TEXT_2 409600
133 zoff99 29 // minimum (line legth * 32) squared (in pixel) to show text label -> for middle segments of streets
134 zoff99 28 #define MIN_LINE_LENGTH_FOR_TEXT_MIDDLE_2 1638400
135 zoff99 2
136 zoff99 34 #define MAX_POI_ICONS_ON_MAP 30
137     #define MAX_POI_ICON_TEXTS_ON_MAP 12
138    
139     #define MAX_PLACE_LABELS_ON_MAP 13
140     #define MAX_DISTRICT_LABELS_ON_MAP 13
141     #define MAX_MAJOR_PLACE_LABELS_ON_MAP 9
142    
143 zoff99 28 #define ORDER_LEVEL_FOR_STREET_SIMPLIFY 9
144     #define STREET_SIMPLIFY 24
145    
146 zoff99 2 struct graphics
147     {
148     struct graphics_priv *priv;
149     struct graphics_methods meth;
150     char *default_font;
151     int font_len;
152     struct graphics_font **font;
153     struct graphics_gc *gc[3];
154     struct attr **attrs;
155     struct callback_list *cbl;
156     struct point_rect r;
157 zoff99 27 int gamma, brightness, contrast;
158 zoff99 2 int colormgmt;
159     int font_size;
160     GList *selection;
161     };
162    
163 zoff99 27 /*
164     struct display_context
165     {
166     struct graphics *gra;
167     struct element *e;
168     struct graphics_gc *gc;
169     struct graphics_gc *gc_background;
170     struct graphics_image *img;
171     enum projection pro;
172     int mindist;
173     struct transformation *trans;
174     enum item_type type;
175     int maxlen;
176     };
177 zoff99 2
178 zoff99 27 #define HASH_SIZE 1024
179     */
180 zoff99 2
181 zoff99 27 /*
182     struct hash_entry
183     {
184     enum item_type type;
185     struct displayitem *di;
186     };
187     */
188 zoff99 2
189 zoff99 27 /*
190     struct displaylist {
191     int busy;
192     int workload;
193     struct callback *cb;
194     struct layout *layout, *layout_hashed;
195     struct display_context dc;
196     int order, order_hashed, max_offset;
197     struct mapset *ms;
198     struct mapset_handle *msh;
199     struct map *m;
200     int conv;
201     struct map_selection *sel;
202     struct map_rect *mr;
203     struct callback *idle_cb;
204     struct event_idle *idle_ev;
205     unsigned int seq;
206     struct hash_entry hash_entries[HASH_SIZE];
207     };
208     */
209 zoff99 2
210 zoff99 27 struct displaylist_icon_cache
211     {
212 zoff99 2 unsigned int seq;
213    
214     };
215    
216     /**
217     * FIXME
218     * @param <>
219     * @returns <>
220     * @author Martin Schaller (04/2008)
221 zoff99 27 */
222     struct displayitem
223     {
224 zoff99 2 struct displayitem *next;
225     struct item item;
226     char *label;
227 zoff99 34 // struct color color;
228     unsigned int col_int_value;
229 zoff99 2 int count;
230     struct coord c[0];
231     };
232    
233     static void draw_circle(struct point *pnt, int diameter, int scale, int start, int len, struct point *res, int *pos, int dir);
234     static void graphics_process_selection(struct graphics *gra, struct displaylist *dl);
235     static void graphics_gc_init(struct graphics *this_);
236    
237 zoff99 27 static void clear_hash(struct displaylist *dl)
238 zoff99 2 {
239     int i;
240 zoff99 27 for (i = 0; i < HASH_SIZE_GRAPHICS_; i++)
241 zoff99 28 {
242 zoff99 27 dl->hash_entries[i].type = type_none;
243 zoff99 28 }
244 zoff99 2 }
245    
246     static struct hash_entry *
247     get_hash_entry(struct displaylist *dl, enum item_type type)
248     {
249 zoff99 27 int hashidx = (type * 2654435761UL) & (HASH_SIZE_GRAPHICS_ - 1);
250     int offset = dl->max_offset;
251     do
252     {
253 zoff99 2 if (!dl->hash_entries[hashidx].type)
254 zoff99 27 {
255 zoff99 2 return NULL;
256 zoff99 27 }
257 zoff99 2 if (dl->hash_entries[hashidx].type == type)
258 zoff99 27 {
259 zoff99 2 return &dl->hash_entries[hashidx];
260 zoff99 27 }
261     hashidx = (hashidx + 1) & (HASH_SIZE_GRAPHICS_ - 1);
262     }
263     while (offset-- > 0);
264    
265 zoff99 2 return NULL;
266     }
267    
268     static struct hash_entry *
269     set_hash_entry(struct displaylist *dl, enum item_type type)
270     {
271 zoff99 27 int hashidx = (type * 2654435761UL) & (HASH_SIZE_GRAPHICS_ - 1);
272     int offset = 0;
273     for (;;)
274     {
275     if (!dl->hash_entries[hashidx].type)
276     {
277     dl->hash_entries[hashidx].type = type;
278 zoff99 2 if (dl->max_offset < offset)
279 zoff99 27 dl->max_offset = offset;
280 zoff99 2 return &dl->hash_entries[hashidx];
281     }
282     if (dl->hash_entries[hashidx].type == type)
283     return &dl->hash_entries[hashidx];
284 zoff99 27 hashidx = (hashidx + 1) & (HASH_SIZE_GRAPHICS_ - 1);
285 zoff99 2 offset++;
286     }
287     return NULL;
288     }
289    
290 zoff99 27 static int graphics_set_attr_do(struct graphics *gra, struct attr *attr)
291 zoff99 2 {
292 zoff99 27 switch (attr->type)
293     {
294     case attr_gamma:
295     gra->gamma = attr->u.num;
296     break;
297     case attr_brightness:
298     gra->brightness = attr->u.num;
299     break;
300     case attr_contrast:
301     gra->contrast = attr->u.num;
302     break;
303     case attr_font_size:
304     gra->font_size = attr->u.num;
305     return 1;
306     default:
307     return 0;
308 zoff99 2 }
309 zoff99 27 gra->colormgmt = (gra->gamma != 65536 || gra->brightness != 0 || gra->contrast != 65536);
310 zoff99 2 graphics_gc_init(gra);
311     return 1;
312     }
313    
314 zoff99 27 int graphics_set_attr(struct graphics *gra, struct attr *attr)
315 zoff99 2 {
316 zoff99 27 int ret = 1;
317 zoff99 30 // //DBG // dbg(0,"enter\n");
318 zoff99 2 if (gra->meth.set_attr)
319 zoff99 27 ret = gra->meth.set_attr(gra->priv, attr);
320 zoff99 2 if (!ret)
321 zoff99 27 ret = graphics_set_attr_do(gra, attr);
322     return ret != 0;
323 zoff99 2 }
324    
325 zoff99 27 void graphics_set_rect(struct graphics *gra, struct point_rect *pr)
326 zoff99 2 {
327 zoff99 27 gra->r = *pr;
328 zoff99 2 }
329    
330     /**
331     * Creates a new graphics object
332     * attr type required
333     * @param <>
334     * @returns <>
335     * @author Martin Schaller (04/2008)
336 zoff99 27 */
337 zoff99 2 struct graphics * graphics_new(struct attr *parent, struct attr **attrs)
338     {
339 zoff99 30 // dbg(0, "EEnter\n");
340    
341     int count = 0;
342 zoff99 2 struct graphics *this_;
343 zoff99 27 struct attr *type_attr;
344 zoff99 2 struct graphics_priv * (*graphicstype_new)(struct navit *nav, struct graphics_methods *meth, struct attr **attrs, struct callback_list *cbl);
345    
346 zoff99 27 if (!(type_attr = attr_search(attrs, NULL, attr_type)))
347     {
348     return NULL;
349     }
350 zoff99 2
351 zoff99 30 // dbg(0, "plugins\n");
352    
353 zoff99 40 #ifdef PLUGSSS
354 zoff99 27 graphicstype_new = plugin_get_graphics_type(type_attr->u.str);
355     if (!graphicstype_new)
356     {
357 zoff99 2 return NULL;
358 zoff99 27 }
359 zoff99 40 #endif
360 zoff99 27
361 zoff99 30 // dbg(0, "g 003\n");
362    
363 zoff99 2 this_=g_new0(struct graphics, 1);
364 zoff99 40 this_->cbl = callback_list_new("graphics_new:this_->cbl");
365    
366     #ifdef PLUGSSS
367 zoff99 27 this_->priv = (*graphicstype_new)(parent->u.navit, &this_->meth, attrs, this_->cbl);
368 zoff99 40 #else
369     this_->priv = graphics_android_new(parent->u.navit, &this_->meth, attrs, this_->cbl);
370     #endif
371    
372 zoff99 27 this_->attrs = attr_list_dup(attrs);
373     this_->brightness = 0;
374     this_->contrast = 65536;
375     this_->gamma = 65536;
376     this_->font_size = 20;
377    
378 zoff99 30 // dbg(0, "g 004\n");
379    
380 zoff99 27 while (*attrs)
381     {
382 zoff99 30 count++;
383     // dbg(0, "g 005 attr %d\n", count);
384 zoff99 27 graphics_set_attr_do(this_, *attrs);
385 zoff99 2 attrs++;
386 zoff99 30 // dbg(0, "g 006 attr\n");
387 zoff99 2 }
388 zoff99 27
389 zoff99 30 // dbg(0, "return\n");
390 zoff99 2 return this_;
391     }
392    
393     /**
394     * FIXME
395     * @param <>
396     * @returns <>
397     * @author Martin Schaller (04/2008)
398 zoff99 27 */
399 zoff99 2 int graphics_get_attr(struct graphics *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter)
400     {
401     return attr_generic_get_attr(this_->attrs, NULL, type, attr, iter);
402     }
403    
404     /**
405     * FIXME
406     * @param <>
407     * @returns <>
408     * @author Martin Schaller (04/2008)
409 zoff99 27 */
410 zoff99 30 struct graphics * graphics_overlay_new(const char* name, struct graphics *parent, struct point *p, int w, int h, int alpha, int wraparound)
411 zoff99 2 {
412     struct graphics *this_;
413     struct point_rect pr;
414     if (!parent->meth.overlay_new)
415 zoff99 27 return NULL;this_=g_new0(struct graphics, 1);
416 zoff99 30 this_->priv = parent->meth.overlay_new(name, parent->priv, &this_->meth, p, w, h, alpha, wraparound);
417 zoff99 27 pr.lu.x = 0;
418     pr.lu.y = 0;
419     pr.rl.x = w;
420     pr.rl.y = h;
421     this_->font_size = 20;
422 zoff99 2 graphics_set_rect(this_, &pr);
423 zoff99 27 if (!this_->priv)
424     {
425 zoff99 2 g_free(this_);
426 zoff99 27 this_ = NULL;
427 zoff99 2 }
428     return this_;
429     }
430    
431     /**
432     * @brief Alters the size, position, alpha and wraparound for an overlay
433     *
434     * @param this_ The overlay's graphics struct
435     * @param p The new position of the overlay
436     * @param w The new width of the overlay
437     * @param h The new height of the overlay
438     * @param alpha The new alpha of the overlay
439     * @param wraparound The new wraparound of the overlay
440     */
441 zoff99 27 void graphics_overlay_resize(struct graphics *this_, struct point *p, int w, int h, int alpha, int wraparound)
442 zoff99 2 {
443 zoff99 27 if (!this_->meth.overlay_resize)
444     {
445 zoff99 2 return;
446     }
447    
448     this_->meth.overlay_resize(this_->priv, p, w, h, alpha, wraparound);
449     }
450    
451 zoff99 27 static void graphics_gc_init(struct graphics *this_)
452 zoff99 2 {
453 zoff99 30 // dbg(0, "EEnter\n");
454    
455     struct color background = { COLOR_BACKGROUND_ };
456     struct color black = { COLOR_BLACK_ };
457     struct color white = { COLOR_WHITE_ };
458 zoff99 2 if (!this_->gc[0] || !this_->gc[1] || !this_->gc[2])
459     return;
460 zoff99 27 graphics_gc_set_background(this_->gc[0], &background);
461     graphics_gc_set_foreground(this_->gc[0], &background);
462     graphics_gc_set_background(this_->gc[1], &black);
463     graphics_gc_set_foreground(this_->gc[1], &white);
464     graphics_gc_set_background(this_->gc[2], &white);
465     graphics_gc_set_foreground(this_->gc[2], &black);
466 zoff99 30
467     // dbg(0, "return\n");
468 zoff99 2 }
469    
470     /**
471     * FIXME
472     * @param <>
473     * @returns <>
474     * @author Martin Schaller (04/2008)
475 zoff99 27 */
476 zoff99 2 void graphics_init(struct graphics *this_)
477     {
478     if (this_->gc[0])
479     return;
480 zoff99 27 this_->gc[0] = graphics_gc_new(this_);
481     this_->gc[1] = graphics_gc_new(this_);
482     this_->gc[2] = graphics_gc_new(this_);
483 zoff99 2 graphics_gc_init(this_);
484     graphics_background_gc(this_, this_->gc[0]);
485     }
486    
487     /**
488     * FIXME
489     * @param <>
490     * @returns <>
491     * @author Martin Schaller (04/2008)
492 zoff99 27 */
493 zoff99 2 void * graphics_get_data(struct graphics *this_, const char *type)
494     {
495     return (this_->meth.get_data(this_->priv, type));
496     }
497    
498     void graphics_add_callback(struct graphics *this_, struct callback *cb)
499     {
500     callback_list_add(this_->cbl, cb);
501     }
502    
503     void graphics_remove_callback(struct graphics *this_, struct callback *cb)
504     {
505     callback_list_remove(this_->cbl, cb);
506     }
507    
508     /**
509     * FIXME
510     * @param <>
511     * @returns <>
512     * @author Martin Schaller (04/2008)
513 zoff99 27 */
514 zoff99 2 struct graphics_font * graphics_font_new(struct graphics *gra, int size, int flags)
515     {
516     struct graphics_font *this_;
517    
518     this_=g_new0(struct graphics_font,1);
519 zoff99 27 this_->priv = gra->meth.font_new(gra->priv, &this_->meth, gra->default_font, size, flags);
520 zoff99 2 return this_;
521     }
522    
523     struct graphics_font * graphics_named_font_new(struct graphics *gra, char *font, int size, int flags)
524     {
525     struct graphics_font *this_;
526    
527     this_=g_new0(struct graphics_font,1);
528 zoff99 27 this_->priv = gra->meth.font_new(gra->priv, &this_->meth, font, size, flags);
529 zoff99 2 return this_;
530     }
531    
532     /**
533     * Destroy graphics
534     * Called when navit exits
535     * @param gra The graphics instance
536     * @returns nothing
537     * @author David Tegze (02/2011)
538     */
539     void graphics_free(struct graphics *gra)
540     {
541     if (!gra)
542     return;
543     gra->meth.graphics_destroy(gra->priv);
544     g_free(gra->default_font);
545     graphics_font_destroy_all(gra);
546     g_free(gra);
547     }
548    
549     /**
550     * Free all loaded fonts.
551     * Used when switching layouts.
552     * @param gra The graphics instance
553     * @returns nothing
554     * @author Sarah Nordstrom (05/2008)
555     */
556     void graphics_font_destroy_all(struct graphics *gra)
557     {
558     int i;
559 zoff99 27 for (i = 0; i < gra->font_len; i++)
560     {
561     if (!gra->font[i])
562     continue;
563     gra->font[i]->meth.font_destroy(gra->font[i]->priv);
564     gra->font[i] = NULL;
565 zoff99 2 }
566     }
567    
568     /**
569     * FIXME
570     * @param <>
571     * @returns <>
572     * @author Martin Schaller (04/2008)
573 zoff99 27 */
574 zoff99 2 struct graphics_gc * graphics_gc_new(struct graphics *gra)
575     {
576     struct graphics_gc *this_;
577    
578     this_=g_new0(struct graphics_gc,1);
579 zoff99 27 this_->priv = gra->meth.gc_new(gra->priv, &this_->meth);
580     this_->gra = gra;
581 zoff99 2 return this_;
582     }
583    
584     /**
585     * FIXME
586     * @param <>
587     * @returns <>
588     * @author Martin Schaller (04/2008)
589 zoff99 27 */
590 zoff99 2 void graphics_gc_destroy(struct graphics_gc *gc)
591     {
592     gc->meth.gc_destroy(gc->priv);
593     g_free(gc);
594     }
595    
596 zoff99 27 static void graphics_convert_color(struct graphics *gra, struct color *in, struct color *out)
597 zoff99 2 {
598 zoff99 27 *out = *in;
599     if (gra->brightness)
600     {
601     out->r += gra->brightness;
602     out->g += gra->brightness;
603     out->b += gra->brightness;
604 zoff99 2 }
605 zoff99 27 if (gra->contrast != 65536)
606     {
607     out->r = out->r * gra->contrast / 65536;
608     out->g = out->g * gra->contrast / 65536;
609     out->b = out->b * gra->contrast / 65536;
610 zoff99 2 }
611     if (out->r < 0)
612 zoff99 27 out->r = 0;
613 zoff99 2 if (out->r > 65535)
614 zoff99 27 out->r = 65535;
615 zoff99 2 if (out->g < 0)
616 zoff99 27 out->g = 0;
617 zoff99 2 if (out->g > 65535)
618 zoff99 27 out->g = 65535;
619 zoff99 2 if (out->b < 0)
620 zoff99 27 out->b = 0;
621 zoff99 2 if (out->b > 65535)
622 zoff99 27 out->b = 65535;
623     if (gra->gamma != 65536)
624     {
625     out->r = pow(out->r / 65535.0, gra->gamma / 65536.0) * 65535.0;
626     out->g = pow(out->g / 65535.0, gra->gamma / 65536.0) * 65535.0;
627     out->b = pow(out->b / 65535.0, gra->gamma / 65536.0) * 65535.0;
628 zoff99 2 }
629     }
630    
631     /**
632     * FIXME
633     * @param <>
634     * @returns <>
635     * @author Martin Schaller (04/2008)
636 zoff99 27 */
637 zoff99 2 void graphics_gc_set_foreground(struct graphics_gc *gc, struct color *c)
638     {
639     struct color cn;
640 zoff99 27 if (gc->gra->colormgmt)
641     {
642 zoff99 2 graphics_convert_color(gc->gra, c, &cn);
643 zoff99 27 c = &cn;
644 zoff99 2 }
645     gc->meth.gc_set_foreground(gc->priv, c);
646     }
647    
648     /**
649     * FIXME
650     * @param <>
651     * @returns <>
652     * @author Martin Schaller (04/2008)
653 zoff99 27 */
654 zoff99 2 void graphics_gc_set_background(struct graphics_gc *gc, struct color *c)
655     {
656     struct color cn;
657 zoff99 27 if (gc->gra->colormgmt)
658     {
659 zoff99 2 graphics_convert_color(gc->gra, c, &cn);
660 zoff99 27 c = &cn;
661 zoff99 2 }
662     gc->meth.gc_set_background(gc->priv, c);
663     }
664    
665     /**
666     * FIXME
667     * @param <>
668     * @returns <>
669     * @author Martin Schaller (04/2008)
670 zoff99 27 */
671 zoff99 2 void graphics_gc_set_stipple(struct graphics_gc *gc, struct graphics_image *img)
672     {
673     gc->meth.gc_set_stipple(gc->priv, img ? img->priv : NULL);
674     }
675    
676     /**
677     * FIXME
678     * @param <>
679     * @returns <>
680     * @author Martin Schaller (04/2008)
681 zoff99 27 */
682 zoff99 2 void graphics_gc_set_linewidth(struct graphics_gc *gc, int width)
683     {
684     gc->meth.gc_set_linewidth(gc->priv, width);
685     }
686    
687     /**
688     * FIXME
689     * @param <>
690     * @returns <>
691     * @author Martin Schaller (04/2008)
692 zoff99 27 */
693     void graphics_gc_set_dashes(struct graphics *gra, struct graphics_gc *gc, int width, int offset, int dash_list[], int n, int order)
694 zoff99 2 {
695     if (gc->meth.gc_set_dashes)
696 zoff99 27 {
697     gc->meth.gc_set_dashes(gra->priv, gc->priv, width, offset, dash_list, order);
698     }
699 zoff99 2 }
700    
701     /**
702     * Create a new image from file path scaled to w and h pixels
703     * @param gra the graphics instance
704     * @param path path of the image to load
705     * @param w width to rescale to
706     * @param h height to rescale to
707     * @returns <>
708     * @author Martin Schaller (04/2008)
709 zoff99 27 */
710 zoff99 2 struct graphics_image * graphics_image_new_scaled(struct graphics *gra, char *path, int w, int h)
711     {
712     struct graphics_image *this_;
713    
714     this_=g_new0(struct graphics_image,1);
715 zoff99 27 this_->height = h;
716     this_->width = w;
717     this_->priv = gra->meth.image_new(gra->priv, &this_->meth, path, &this_->width, &this_->height, &this_->hot, 0);
718     if (!this_->priv)
719     {
720 zoff99 2 g_free(this_);
721 zoff99 27 this_ = NULL;
722 zoff99 2 }
723     return this_;
724     }
725    
726     /**
727     * Create a new image from file path scaled to w and h pixels and possibly rotated
728     * @param gra the graphics instance
729     * @param path path of the image to load
730     * @param w width to rescale to
731     * @param h height to rescale to
732     * @param rotate angle to rotate the image. Warning, graphics might only support 90 degree steps here
733     * @returns <>
734     * @author Martin Schaller (04/2008)
735 zoff99 27 */
736 zoff99 2 struct graphics_image * graphics_image_new_scaled_rotated(struct graphics *gra, char *path, int w, int h, int rotate)
737     {
738     struct graphics_image *this_;
739    
740     this_=g_new0(struct graphics_image,1);
741 zoff99 27 this_->height = h;
742     this_->width = w;
743     this_->priv = gra->meth.image_new(gra->priv, &this_->meth, path, &this_->width, &this_->height, &this_->hot, rotate);
744     if (!this_->priv)
745     {
746 zoff99 2 g_free(this_);
747 zoff99 27 this_ = NULL;
748 zoff99 2 }
749     return this_;
750     }
751    
752     /**
753     * Create a new image from file path
754     * @param gra the graphics instance
755     * @param path path of the image to load
756     * @returns <>
757     * @author Martin Schaller (04/2008)
758 zoff99 27 */
759 zoff99 2 struct graphics_image * graphics_image_new(struct graphics *gra, char *path)
760     {
761     return graphics_image_new_scaled(gra, path, -1, -1);
762     }
763    
764     /**
765     * FIXME
766     * @param <>
767     * @returns <>
768     * @author Martin Schaller (04/2008)
769 zoff99 27 */
770 zoff99 2 void graphics_image_free(struct graphics *gra, struct graphics_image *img)
771     {
772     if (gra->meth.image_free)
773     gra->meth.image_free(gra->priv, img->priv);
774     g_free(img);
775     }
776    
777     /**
778     * FIXME
779     * @param <>
780     * @returns <>
781     * @author Martin Schaller (04/2008)
782 zoff99 27 */
783 zoff99 2 void graphics_draw_restore(struct graphics *this_, struct point *p, int w, int h)
784     {
785 zoff99 30 ////DBG // dbg(0,"ooo enter ooo\n");
786 zoff99 2
787     this_->meth.draw_restore(this_->priv, p, w, h);
788     }
789    
790     /**
791     * FIXME
792     * @param <>
793     * @returns <>
794     * @author Martin Schaller (04/2008)
795 zoff99 27 */
796 zoff99 2 void graphics_draw_mode(struct graphics *this_, enum draw_mode_num mode)
797     {
798 zoff99 30 ////DBG // dbg(0,"ooo enter ooo\n");
799 zoff99 2
800     this_->meth.draw_mode(this_->priv, mode);
801     }
802    
803     /**
804     * FIXME
805     * @param <>
806     * @returns <>
807     * @author Martin Schaller (04/2008)
808 zoff99 27 */
809 zoff99 2 void graphics_draw_lines(struct graphics *this_, struct graphics_gc *gc, struct point *p, int count)
810     {
811     this_->meth.draw_lines(this_->priv, gc->priv, p, count);
812     }
813    
814     void graphics_draw_lines_dashed(struct graphics *this_, struct graphics_gc *gc, struct point *p, int count, int order, int oneway)
815     {
816     this_->meth.draw_lines_dashed(this_->priv, gc->priv, p, count, order, oneway);
817     }
818    
819     /**
820     * FIXME
821     * @param <>
822     * @returns <>
823     * @author Martin Schaller (04/2008)
824 zoff99 27 */
825 zoff99 2 void graphics_draw_circle(struct graphics *this_, struct graphics_gc *gc, struct point *p, int r)
826     {
827 zoff99 27 int i = 0;
828 zoff99 2
829 zoff99 27 if (this_->meth.draw_circle)
830 zoff99 30 {
831 zoff99 2 this_->meth.draw_circle(this_->priv, gc->priv, p, r);
832 zoff99 30 }
833 zoff99 2 else
834     {
835 zoff99 30 struct point *pnt = g_alloca(sizeof(struct point) * (r * 4 + 64));
836 zoff99 2 draw_circle(p, r, 0, -1, 1026, pnt, &i, 1);
837     pnt[i] = pnt[0];
838     i++;
839     this_->meth.draw_lines(this_->priv, gc->priv, pnt, i);
840     }
841     }
842    
843     /**
844     * FIXME
845     * @param <>
846     * @returns <>
847     * @author Martin Schaller (04/2008)
848 zoff99 27 */
849 zoff99 2 void graphics_draw_rectangle(struct graphics *this_, struct graphics_gc *gc, struct point *p, int w, int h)
850     {
851     this_->meth.draw_rectangle(this_->priv, gc->priv, p, w, h);
852     }
853    
854     void graphics_draw_rectangle_rounded(struct graphics *this_, struct graphics_gc *gc, struct point *plu, int w, int h, int r, int fill)
855     {
856 zoff99 27 struct point *p = g_alloca(sizeof(struct point) * (r * 4 + 32));
857 zoff99 30 struct point pi0 = { plu->x + r, plu->y + r };
858     struct point pi1 = { plu->x + w - r, plu->y + r };
859     struct point pi2 = { plu->x + w - r, plu->y + h - r };
860     struct point pi3 = { plu->x + r, plu->y + h - r };
861 zoff99 27 int i = 0;
862 zoff99 2
863 zoff99 27 draw_circle(&pi2, r * 2, 0, -1, 258, p, &i, 1);
864     draw_circle(&pi1, r * 2, 0, 255, 258, p, &i, 1);
865     draw_circle(&pi0, r * 2, 0, 511, 258, p, &i, 1);
866     draw_circle(&pi3, r * 2, 0, 767, 258, p, &i, 1);
867     p[i] = p[0];
868 zoff99 2 i++;
869     if (fill)
870     this_->meth.draw_polygon(this_->priv, gc->priv, p, i);
871     else
872     this_->meth.draw_lines(this_->priv, gc->priv, p, i);
873     }
874    
875     /**
876     * FIXME
877     * @param <>
878     * @returns <>
879     * @author Martin Schaller (04/2008)
880 zoff99 27 */
881 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)
882     {
883     this_->meth.draw_text(this_->priv, gc1->priv, gc2 ? gc2->priv : NULL, font->priv, text, p, dx, dy);
884     }
885    
886     /**
887     * FIXME
888     * @param <>
889     * @returns <>
890     * @author Martin Schaller (04/2008)
891 zoff99 27 */
892 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)
893     {
894     this_->meth.get_text_bbox(this_->priv, font->priv, text, dx, dy, ret, estimate);
895     }
896    
897     /**
898     * FIXME
899     * @param <>
900     * @returns <>
901     * @author Martin Schaller (04/2008)
902 zoff99 27 */
903 zoff99 2 void graphics_overlay_disable(struct graphics *this_, int disable)
904     {
905     if (this_->meth.overlay_disable)
906     this_->meth.overlay_disable(this_->priv, disable);
907     }
908    
909     /**
910     * FIXME
911     * @param <>
912     * @returns <>
913     * @author Martin Schaller (04/2008)
914 zoff99 27 */
915 zoff99 2 void graphics_draw_image(struct graphics *this_, struct graphics_gc *gc, struct point *p, struct graphics_image *img)
916     {
917     this_->meth.draw_image(this_->priv, gc->priv, p, img->priv);
918     }
919    
920     /**
921     *
922     *
923     * @author Zoff (2011)
924 zoff99 27 */
925 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)
926     {
927     this_->meth.draw_bigmap(this_->priv, gc->priv, yaw, order, clat, clng, x, y, scx, scy, px, py, valid);
928     }
929    
930     //##############################################################################################################
931     //# Description:
932     //# Comment:
933     //# Authors: Martin Schaller (04/2008)
934     //##############################################################################################################
935 zoff99 27 int graphics_draw_drag(struct graphics *this_, struct point *p)
936 zoff99 2 {
937 zoff99 40 __F_START__
938 zoff99 2
939     if (!this_->meth.draw_drag)
940     {
941 zoff99 40 return2 0;
942 zoff99 2 }
943 zoff99 30 ////DBG // dbg(0,"draw DRAG start ...\n");
944 zoff99 2 this_->meth.draw_drag(this_->priv, p);
945 zoff99 30 ////DBG // dbg(0,"draw DRAG end ...\n");
946 zoff99 40 return2 1;
947    
948     __F_END__
949    
950 zoff99 2 }
951    
952 zoff99 27 void graphics_background_gc(struct graphics *this_, struct graphics_gc *gc)
953 zoff99 2 {
954 zoff99 30 ////DBG // dbg(0,"ooo enter ooo\n");
955 zoff99 2
956     this_->meth.background_gc(this_->priv, gc ? gc->priv : NULL);
957     }
958    
959     #include "attr.h"
960     #include "popup.h"
961     #include <stdio.h>
962    
963     #if 0
964     //##############################################################################################################
965     //# Description:
966     //# Comment:
967     //# Authors: Martin Schaller (04/2008)
968     //##############################################################################################################
969     static void popup_view_html(struct popup_item *item, char *file)
970     {
971     char command[1024];
972     sprintf(command,"firefox %s", file);
973     system(command);
974     }
975    
976     struct transformatin *tg;
977     enum projection pg;
978    
979     //##############################################################################################################
980     //# Description:
981     //# Comment:
982     //# Authors: Martin Schaller (04/2008)
983     //##############################################################################################################
984     static void graphics_popup(struct display_list *list, struct popup_item **popup)
985     {
986     struct item *item;
987     struct attr attr;
988     struct map_rect *mr;
989     struct coord c;
990     struct popup_item *curr_item,*last=NULL;
991     item=list->data;
992     mr=map_rect_new(item->map, NULL, NULL, 0);
993     printf("id hi=0x%x lo=0x%x\n", item->id_hi, item->id_lo);
994     item=map_rect_get_item_byid(mr, item->id_hi, item->id_lo);
995 zoff99 27 if (item)
996     {
997     if (item_attr_get(item, attr_name, &attr))
998     {
999 zoff99 2 curr_item=popup_item_new_text(popup,attr.u.str,1);
1000 zoff99 27 if (item_attr_get(item, attr_info_html, &attr))
1001     {
1002 zoff99 2 popup_item_new_func(&last,"HTML Info",1, popup_view_html, g_strdup(attr.u.str));
1003     }
1004 zoff99 27 if (item_attr_get(item, attr_price_html, &attr))
1005     {
1006 zoff99 2 popup_item_new_func(&last,"HTML Preis",2, popup_view_html, g_strdup(attr.u.str));
1007     }
1008     curr_item->submenu=last;
1009     }
1010     }
1011     map_rect_destroy(mr);
1012     }
1013     #endif
1014    
1015     /**
1016     * FIXME
1017     * @param <>
1018     * @returns <>
1019     * @author Martin Schaller (04/2008)
1020 zoff99 27 */
1021 zoff99 2 static void xdisplay_free(struct displaylist *dl)
1022     {
1023     int i;
1024 zoff99 27 for (i = 0; i < HASH_SIZE_GRAPHICS_; i++)
1025     {
1026     struct displayitem *di = dl->hash_entries[i].di;
1027     while (di)
1028     {
1029     struct displayitem *next = di->next;
1030 zoff99 2 g_free(di);
1031 zoff99 27 di = next;
1032 zoff99 2 }
1033 zoff99 27 dl->hash_entries[i].di = NULL;
1034 zoff99 2 }
1035     }
1036    
1037     /**
1038     * FIXME
1039     * @param <>
1040     * @returns <>
1041     * @author Martin Schaller (04/2008)
1042 zoff99 27 */
1043 zoff99 34 static void display_add(struct hash_entry *entry, struct item *item, int count, struct coord *c, char **label, int label_count, int color_yes_no, unsigned int color_int)
1044 zoff99 2 {
1045     struct displayitem *di;
1046 zoff99 27 int len, i;
1047 zoff99 34 // int len2;
1048 zoff99 2 char *p;
1049    
1050 zoff99 27 len = sizeof(*di) + count * sizeof(*c);
1051 zoff99 34 if (label && label_count > 0)
1052 zoff99 27 {
1053     for (i = 0; i < label_count; i++)
1054     {
1055 zoff99 2 if (label[i])
1056 zoff99 28 {
1057 zoff99 34 //dbg(0, "label=X%sX\n", label[i]);
1058     len += strlen(label[i]);
1059     if (i < (label_count - 1))
1060     {
1061     len = len + 2; // put ', '(==2 chars) between labels!
1062     }
1063 zoff99 28 }
1064 zoff99 2 }
1065 zoff99 34 len++; // NULL at the end
1066 zoff99 2 }
1067 zoff99 34
1068 zoff99 27 p = g_malloc(len);
1069 zoff99 34 //len2 = len - (sizeof(*di) + count * sizeof(*c));
1070     //dbg(0,"malloc len:%d len2:%d\n", len, len2);
1071 zoff99 2
1072 zoff99 27 di = (struct displayitem *) p;
1073     p += sizeof(*di) + count * sizeof(*c);
1074     di->item = *item;
1075 zoff99 34
1076     if (color_yes_no)
1077 zoff99 27 {
1078 zoff99 34 //di->color.r = r;
1079     //di->color.g = g;
1080     //di->color.b = b;
1081     //di->color.a = a;
1082     di->col_int_value = color_int;
1083     }
1084     else
1085     {
1086     // 0 --> no custom color is set
1087     //di->color.a = 0;
1088     di->col_int_value = (unsigned int)0;
1089     }
1090    
1091     if (label && label_count > 0)
1092     {
1093 zoff99 27 di->label = p;
1094     for (i = 0; i < label_count; i++)
1095     {
1096     if (label[i])
1097     {
1098 zoff99 34 strncpy(p, label[i], strlen(label[i])); // copy string without!! NULL byte at the end
1099     p += strlen(label[i]);
1100     if (i < (label_count - 1))
1101     {
1102     // put ', ' between labels!
1103     *p++ = ',';
1104     *p++ = ' ';
1105     }
1106 zoff99 27 }
1107 zoff99 2 }
1108 zoff99 34 *p++ = '\0'; // add NULL at the end
1109     //p = di->label;
1110     //p = p + len2;
1111     //*p = '\0'; // for safety NULL at the real end!
1112     //dbg(0, "add:strlen=%d p=%s\n", strlen(di->label), di->label);
1113 zoff99 27 }
1114     else
1115     {
1116     di->label = NULL;
1117     }
1118 zoff99 34
1119 zoff99 27 di->count = count;
1120     memcpy(di->c, c, count * sizeof(*c));
1121     di->next = entry->di;
1122     entry->di = di;
1123 zoff99 2 }
1124    
1125     /**
1126     * FIXME
1127     * @param <>
1128     * @returns <>
1129     * @author Martin Schaller (04/2008)
1130 zoff99 27 */
1131 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)
1132     {
1133 zoff99 27 int i, x, y, tl, tlm, th, thm, tlsq, l;
1134 zoff99 2 float lsq;
1135 zoff99 28 // double dx, dy;
1136     float dx, dy;
1137 zoff99 2 struct point p_t;
1138     struct point pb[5];
1139    
1140 zoff99 27 if (gra->meth.get_text_bbox)
1141     {
1142 zoff99 2 gra->meth.get_text_bbox(gra->priv, font->priv, label, 0x10000, 0x0, pb, 1);
1143 zoff99 28 // tl -> text length
1144 zoff99 27 tl = (pb[2].x - pb[0].x);
1145 zoff99 28 // th -> text height
1146 zoff99 27 th = (pb[0].y - pb[1].y);
1147 zoff99 2 }
1148 zoff99 27 else
1149     {
1150 zoff99 28 // tl -> text length
1151 zoff99 27 tl = strlen(label) * 4;
1152 zoff99 28 // th -> text height
1153 zoff99 27 th = 8;
1154     }
1155     tlm = tl * 32;
1156     thm = th * 36;
1157 zoff99 28 // tlsq -> (text length * 32) squared
1158 zoff99 27 tlsq = tlm * tlm;
1159     for (i = 0; i < count - 1; i++)
1160     {
1161     dx = p[i + 1].x - p[i].x;
1162     dx *= 32;
1163     dy = p[i + 1].y - p[i].y;
1164     dy *= 32;
1165 zoff99 28 // lsq -> (line length * 32) squared
1166 zoff99 27 lsq = dx * dx + dy * dy;
1167     if (lsq > tlsq)
1168     {
1169 zoff99 30 if (((int) lsq > MIN_LINE_LENGTH_FOR_TEXT_MIDDLE_2) || (((i == 0) || (i == (count - 2)) && ((int) lsq > (int) MIN_LINE_LENGTH_FOR_TEXT_2))))
1170 zoff99 27 {
1171 zoff99 28 // segments in the middle of the "way" need to be longer for streetname to be drawn
1172     // l -> line length
1173     l = (int) sqrtf_fast2(lsq);
1174     x = p[i].x;
1175     y = p[i].y;
1176     if (dx < 0)
1177     {
1178     dx = -dx;
1179     dy = -dy;
1180     x = p[i + 1].x;
1181     y = p[i + 1].y;
1182     }
1183     x += (l - tlm) * dx / l / 64;
1184     y += (l - tlm) * dy / l / 64;
1185     x -= dy * thm / l / 64;
1186     y += dx * thm / l / 64;
1187     p_t.x = x;
1188     p_t.y = y;
1189 zoff99 30 #if 0
1190     //DBG // dbg(0,"display_text: '%s', %d, %d, %d, %d %d\n", label, x, y, dx*0x10000/l, dy*0x10000/l, l);
1191     #endif
1192 zoff99 28 if (x < gra->r.rl.x && x + tl > gra->r.lu.x && y + tl > gra->r.lu.y && y - tl < gra->r.rl.y)
1193     {
1194     gra->meth.draw_text(gra->priv, fg->priv, bg ? bg->priv : NULL, font->priv, label, &p_t, dx * 0x10000 / l, dy * 0x10000 / l);
1195     }
1196 zoff99 2 }
1197     }
1198     }
1199     }
1200    
1201     static void display_draw_arrow(struct point *p, int dx, int dy, int l, struct graphics_gc *gc, struct graphics *gra)
1202     {
1203     struct point pnt[3];
1204 zoff99 27 pnt[0] = pnt[1] = pnt[2] = *p;
1205     pnt[0].x += -dx * l / 65536 + dy * l / 65536;
1206     pnt[0].y += -dy * l / 65536 - dx * l / 65536;
1207     pnt[2].x += -dx * l / 65536 - dy * l / 65536;
1208     pnt[2].y += -dy * l / 65536 + dx * l / 65536;
1209 zoff99 2 gra->meth.draw_lines(gra->priv, gc->priv, pnt, 3);
1210     }
1211    
1212     static void display_draw_arrows(struct graphics *gra, struct graphics_gc *gc, struct point *pnt, int count)
1213     {
1214 zoff99 27 int i, dx, dy, l;
1215 zoff99 2 struct point p;
1216 zoff99 27 for (i = 0; i < count - 1; i++)
1217     {
1218     dx = pnt[i + 1].x - pnt[i].x;
1219     dy = pnt[i + 1].y - pnt[i].y;
1220     l = sqrt(dx * dx + dy * dy);
1221     if (l)
1222     {
1223     dx = dx * 65536 / l;
1224     dy = dy * 65536 / l;
1225     p = pnt[i];
1226     p.x += dx * 15 / 65536;
1227     p.y += dy * 15 / 65536;
1228 zoff99 2 display_draw_arrow(&p, dx, dy, 10, gc, gra);
1229 zoff99 27 p = pnt[i + 1];
1230     p.x -= dx * 15 / 65536;
1231     p.y -= dy * 15 / 65536;
1232 zoff99 2 display_draw_arrow(&p, dx, dy, 10, gc, gra);
1233     }
1234     }
1235     }
1236    
1237 zoff99 27 static int intersection(struct point * a1, int adx, int ady, struct point * b1, int bdx, int bdy, struct point * res)
1238 zoff99 2 {
1239     int n, a, b;
1240     n = bdy * adx - bdx * ady;
1241     a = bdx * (a1->y - b1->y) - bdy * (a1->x - b1->x);
1242     b = adx * (a1->y - b1->y) - ady * (a1->x - b1->x);
1243 zoff99 27 if (n < 0)
1244     {
1245 zoff99 2 n = -n;
1246     a = -a;
1247     b = -b;
1248     }
1249     #if 0
1250     if (a < 0 || b < 0)
1251 zoff99 27 return 0;
1252 zoff99 2 if (a > n || b > n)
1253 zoff99 27 return 0;
1254 zoff99 2 #endif
1255     if (n == 0)
1256     return 0;
1257     res->x = a1->x + a * adx / n;
1258     res->y = a1->y + a * ady / n;
1259     return 1;
1260     }
1261    
1262 zoff99 27 struct circle
1263     {
1264     short x, y, fowler;
1265 zoff99 30 }
1266     circle64[] =
1267     { { 0, 128, 0 }, { 13, 127, 13 }, { 25, 126, 25 }, { 37, 122, 38 }, { 49, 118, 53 }, { 60, 113, 67 }, { 71, 106, 85 }, { 81, 99, 104 }, { 91, 91, 128 }, { 99, 81, 152 }, { 106, 71, 171 }, { 113, 60, 189 }, { 118, 49, 203 }, { 122, 37, 218 }, { 126, 25, 231 }, { 127, 13, 243 }, { 128, 0, 256 }, { 127, -13, 269 }, { 126, -25, 281 }, { 122, -37, 294 }, { 118, -49, 309 }, { 113, -60, 323 }, { 106, -71, 341 }, { 99, -81, 360 }, { 91, -91, 384 }, { 81, -99, 408 }, { 71, -106, 427 }, { 60, -113, 445 }, { 49, -118, 459 }, { 37, -122, 474 }, { 25, -126, 487 }, { 13, -127, 499 }, { 0, -128, 512 }, { -13, -127, 525 }, { -25, -126, 537 }, { -37, -122, 550 }, { -49, -118, 565 }, { -60, -113, 579 }, { -71, -106, 597 }, { -81, -99, 616 }, { -91, -91, 640 }, { -99, -81, 664 }, { -106, -71, 683 }, { -113, -60, 701 }, { -118, -49, 715 }, { -122, -37, 730 }, { -126, -25, 743 }, { -127, -13, 755 }, { -128, 0, 768 }, { -127, 13, 781 }, { -126, 25, 793 }, { -122, 37, 806 }, { -118, 49, 821 }, { -113, 60, 835 }, { -106, 71, 853 }, { -99, 81, 872 }, { -91, 91, 896 }, { -81, 99, 920 }, { -71, 106, 939 }, { -60, 113, 957 }, { -49, 118, 971 }, { -37, 122, 986 }, { -25, 126, 999 }, { -13, 127, 1011 }, };
1268 zoff99 2
1269 zoff99 27 static void draw_circle(struct point *pnt, int diameter, int scale, int start, int len, struct point *res, int *pos, int dir)
1270 zoff99 2 {
1271     struct circle *c;
1272    
1273     #if 0
1274 zoff99 30 //DBG // dbg(0,"diameter=%d start=%d len=%d pos=%d dir=%d\n", diameter, start, len, *pos, dir);
1275 zoff99 2 #endif
1276 zoff99 27 int count = 64;
1277     int end = start + len;
1278     int i, step;
1279     c = circle64;
1280 zoff99 2 if (diameter > 128)
1281 zoff99 27 step = 1;
1282 zoff99 2 else if (diameter > 64)
1283 zoff99 27 step = 2;
1284 zoff99 2 else if (diameter > 24)
1285 zoff99 27 step = 4;
1286 zoff99 2 else if (diameter > 8)
1287 zoff99 27 step = 8;
1288 zoff99 2 else
1289 zoff99 27 step = 16;
1290     if (len > 0)
1291     {
1292     while (start < 0)
1293     {
1294     start += 1024;
1295     end += 1024;
1296 zoff99 2 }
1297 zoff99 27 while (end > 0)
1298     {
1299     i = 0;
1300 zoff99 2 while (i < count && c[i].fowler <= start)
1301 zoff99 27 {
1302     i += step;
1303     }
1304     while (i < count && c[i].fowler < end)
1305     {
1306     if (1 < *pos || 0 < dir)
1307     {
1308     res[*pos].x = pnt->x + ((c[i].x * diameter + 128) >> 8);
1309     res[*pos].y = pnt->y + ((c[i].y * diameter + 128) >> 8);
1310     (*pos) += dir;
1311 zoff99 2 }
1312 zoff99 27 i += step;
1313 zoff99 2 }
1314 zoff99 27 end -= 1024;
1315     start -= 1024;
1316 zoff99 2 }
1317 zoff99 27 }
1318     else
1319     {
1320     while (start > 1024)
1321     {
1322     start -= 1024;
1323     end -= 1024;
1324 zoff99 2 }
1325 zoff99 27 while (end < 1024)
1326     {
1327     i = count - 1;
1328 zoff99 2 while (i >= 0 && c[i].fowler >= start)
1329 zoff99 27 i -= step;
1330     while (i >= 0 && c[i].fowler > end)
1331     {
1332     if (1 < *pos || 0 < dir)
1333     {
1334     res[*pos].x = pnt->x + ((c[i].x * diameter + 128) >> 8);
1335     res[*pos].y = pnt->y + ((c[i].y * diameter + 128) >> 8);
1336     (*pos) += dir;
1337 zoff99 2 }
1338 zoff99 27 i -= step;
1339 zoff99 2 }
1340 zoff99 27 start += 1024;
1341     end += 1024;
1342 zoff99 2 }
1343     }
1344     }
1345    
1346 zoff99 27 static int fowler(int dy, int dx)
1347 zoff99 2 {
1348 zoff99 27 int adx, ady; /* Absolute Values of Dx and Dy */
1349     int code; /* Angular Region Classification Code */
1350 zoff99 2
1351 zoff99 27 adx = (dx < 0) ? -dx : dx; /* Compute the absolute values. */
1352 zoff99 2 ady = (dy < 0) ? -dy : dy;
1353    
1354     code = (adx < ady) ? 1 : 0;
1355     if (dx < 0)
1356     code += 2;
1357     if (dy < 0)
1358     code += 4;
1359    
1360 zoff99 27 switch (code)
1361     {
1362     case 0:
1363     return (dx == 0) ? 0 : 128 * ady / adx; /* [ 0, 45] */
1364     case 1:
1365     return (256 - (128 * adx / ady)); /* ( 45, 90] */
1366     case 3:
1367     return (256 + (128 * adx / ady)); /* ( 90,135) */
1368     case 2:
1369     return (512 - (128 * ady / adx)); /* [135,180] */
1370     case 6:
1371     return (512 + (128 * ady / adx)); /* (180,225] */
1372     case 7:
1373     return (768 - (128 * adx / ady)); /* (225,270) */
1374     case 5:
1375     return (768 + (128 * adx / ady)); /* [270,315) */
1376     case 4:
1377     return (1024 - (128 * ady / adx));/* [315,360) */
1378 zoff99 2 }
1379     return 0;
1380     }
1381 zoff99 27
1382     static int int_sqrt(unsigned int n)
1383 zoff99 2 {
1384 zoff99 27 unsigned int h, p = 0, q = 1, r = n;
1385 zoff99 2
1386     /* avoid q rollover */
1387 zoff99 27 if (n >= (1 << (sizeof(n) * 8 - 2)))
1388     {
1389     q = 1 << (sizeof(n) * 8 - 2);
1390     }
1391     else
1392     {
1393     while (q <= n)
1394     {
1395 zoff99 2 q <<= 2;
1396     }
1397     q >>= 2;
1398     }
1399    
1400 zoff99 27 while (q != 0)
1401     {
1402 zoff99 2 h = p + q;
1403     p >>= 1;
1404 zoff99 27 if (r >= h)
1405     {
1406 zoff99 2 p += q;
1407     r -= h;
1408     }
1409     q >>= 2;
1410     }
1411     return p;
1412     }
1413    
1414 zoff99 27 struct offset
1415     {
1416     int px, py, nx, ny;
1417 zoff99 2 };
1418    
1419 zoff99 27 static void calc_offsets(int wi, int l, int dx, int dy, struct offset *res)
1420 zoff99 2 {
1421 zoff99 27 int x, y;
1422 zoff99 2
1423     x = (dx * wi) / l;
1424     y = (dy * wi) / l;
1425 zoff99 27 if (x < 0)
1426     {
1427     res->nx = -x / 2;
1428     res->px = (x - 1) / 2;
1429 zoff99 2 }
1430 zoff99 27 else
1431     {
1432     res->nx = -(x + 1) / 2;
1433     res->px = x / 2;
1434 zoff99 2 }
1435 zoff99 27 if (y < 0)
1436     {
1437     res->ny = -y / 2;
1438     res->py = (y - 1) / 2;
1439     }
1440     else
1441     {
1442     res->ny = -(y + 1) / 2;
1443     res->py = y / 2;
1444     }
1445 zoff99 2 }
1446    
1447 zoff99 29 // this func. is now obsolete!! and unused!!!!
1448     // this func. is now obsolete!! and unused!!!!
1449     // this func. is now obsolete!! and unused!!!!
1450 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)
1451 zoff99 2 {
1452 zoff99 27 int maxpoints = 200;
1453     struct point *res = g_alloca(sizeof(struct point) * maxpoints);
1454 zoff99 2 struct point pos, poso, neg, nego;
1455 zoff99 27 int i, dx = 0, dy = 0, l = 0, dxo = 0, dyo = 0;
1456 zoff99 30 struct offset o, oo = { 0, 0, 0, 0 };
1457 zoff99 27 int fow = 0, fowo = 0, delta;
1458     int wi, ppos = maxpoints / 2, npos = maxpoints / 2;
1459     int state, prec = 5;
1460     int max_circle_points = 20;
1461     int lscale = 16;
1462     i = 0;
1463     for (;;)
1464     {
1465     wi = *width;
1466     width += step;
1467     if (i < count - 1)
1468     {
1469     int dxs, dys, lscales;
1470 zoff99 2
1471     dx = (pnt[i + 1].x - pnt[i].x);
1472     dy = (pnt[i + 1].y - pnt[i].y);
1473     #if 0
1474     l = int_sqrt(dx * dx * lscale * lscale + dy * dy * lscale * lscale);
1475     #else
1476 zoff99 27 dxs = dx * dx;
1477     dys = dy * dy;
1478     lscales = lscale * lscale;
1479     if (dxs + dys > lscales)
1480     l = int_sqrt(dxs + dys) * lscale;
1481     else
1482     l = int_sqrt((dxs + dys) * lscales);
1483 zoff99 2 #endif
1484 zoff99 27 fow = fowler(-dy, dx);
1485 zoff99 2 }
1486 zoff99 27 if (!l)
1487     l = 1;
1488     if (wi * lscale > 10000)
1489     lscale = 10000 / wi;
1490     dbg_assert(wi * lscale <= 10000);
1491     calc_offsets(wi * lscale, l, dx, dy, &o);
1492 zoff99 2 pos.x = pnt[i].x + o.ny;
1493     pos.y = pnt[i].y + o.px;
1494     neg.x = pnt[i].x + o.py;
1495     neg.y = pnt[i].y + o.nx;
1496 zoff99 27 if (!i)
1497     state = 0;
1498     else if (i == count - 1)
1499     state = 2;
1500     else if (npos < max_circle_points || ppos >= maxpoints - max_circle_points)
1501     state = 3;
1502 zoff99 2 else
1503 zoff99 27 state = 1;
1504     switch (state)
1505     {
1506     case 1:
1507     if (fowo != fow)
1508     {
1509     poso.x = pnt[i].x + oo.ny;
1510     poso.y = pnt[i].y + oo.px;
1511     nego.x = pnt[i].x + oo.py;
1512     nego.y = pnt[i].y + oo.nx;
1513     delta = fowo - fow;
1514     if (delta < 0)
1515     delta += 1024;
1516     if (delta < 512)
1517     {
1518     if (intersection(&pos, dx, dy, &poso, dxo, dyo, &res[ppos]))
1519     {
1520     ppos++;
1521     }
1522     res[--npos] = nego;
1523     --npos;
1524     if (fill == 1)
1525     {
1526     if (draw_polylines_fast == 0)
1527     {
1528     draw_circle(&pnt[i], wi, prec, fowo - 512, -delta, res, &npos, -1);
1529     }
1530     }
1531     res[npos] = neg;
1532     }
1533     else
1534     {
1535     res[ppos++] = poso;
1536     if (fill == 1)
1537     {
1538     if (draw_polylines_fast == 0)
1539     {
1540     draw_circle(&pnt[i], wi, prec, fowo, 1024 - delta, res, &ppos, 1);
1541     }
1542     }
1543     res[ppos++] = pos;
1544     if (intersection(&neg, dx, dy, &nego, dxo, dyo, &res[npos - 1]))
1545     {
1546     npos--;
1547     }
1548     }
1549 zoff99 2 }
1550     break;
1551 zoff99 27 case 2:
1552     case 3:
1553     res[--npos] = neg;
1554     --npos;
1555     if (fill == 1)
1556     {
1557     if (draw_polylines_fast == 0)
1558     {
1559     draw_circle(&pnt[i], wi, prec, fow - 512, -512, res, &npos, -1);
1560     }
1561     }
1562     res[npos] = pos;
1563     res[ppos++] = pos;
1564     dbg_assert(npos > 0);
1565     dbg_assert(ppos < maxpoints);
1566     if (fill == 1)
1567     {
1568     gra->meth.draw_polygon2(gra->priv, gc->priv, res + npos, ppos - npos, order, oneway);
1569     }
1570     else
1571     {
1572     gra->meth.draw_lines_dashed(gra->priv, gc->priv, res + npos, ppos - npos, order, oneway);
1573     }
1574     if (state == 2)
1575     break;
1576     npos = maxpoints / 2;
1577     ppos = maxpoints / 2;
1578     case 0:
1579     res[ppos++] = neg;
1580     if (fill == 1)
1581     {
1582     if (draw_polylines_fast == 0)
1583     {
1584     draw_circle(&pnt[i], wi, prec, fow + 512, 512, res, &ppos, 1);
1585     }
1586     }
1587     res[ppos++] = pos;
1588     break;
1589 zoff99 2 }
1590 zoff99 27
1591 zoff99 2 i++;
1592 zoff99 27
1593 zoff99 2 if (i >= count)
1594 zoff99 27 {
1595 zoff99 2 break;
1596 zoff99 27 }
1597    
1598     if (step)
1599     {
1600     wi = *width;
1601     calc_offsets(wi * lscale, l, dx, dy, &oo);
1602     }
1603     else
1604     {
1605     oo = o;
1606     }
1607    
1608 zoff99 2 dxo = -dx;
1609     dyo = -dy;
1610 zoff99 27 fowo = fow;
1611 zoff99 2 }
1612     }
1613 zoff99 29 // this func. is now obsolete!! and unused!!!!
1614     // this func. is now obsolete!! and unused!!!!
1615     // this func. is now obsolete!! and unused!!!!
1616 zoff99 2
1617 zoff99 28
1618 zoff99 27 struct wpoint
1619     {
1620     int x, y, w;
1621 zoff99 2 };
1622    
1623 zoff99 27 static int clipcode(struct wpoint *p, struct point_rect *r)
1624 zoff99 2 {
1625 zoff99 27 int code = 0;
1626 zoff99 2 if (p->x < r->lu.x)
1627 zoff99 27 code = 1;
1628 zoff99 2 if (p->x > r->rl.x)
1629 zoff99 27 code = 2;
1630 zoff99 2 if (p->y < r->lu.y)
1631 zoff99 27 code |= 4;
1632 zoff99 2 if (p->y > r->rl.y)
1633 zoff99 27 code |= 8;
1634 zoff99 2 return code;
1635     }
1636    
1637 zoff99 28 #define DONT_INTERSECT 0
1638     #define DO_INTERSECT 1
1639     #define COLLINEAR 2
1640     #define SAME_SIGNS( a, b ) \
1641     (((long) ((unsigned long) a ^ (unsigned long) b)) >= 0 )
1642    
1643 zoff99 30 static int lines_intersect(int x1, int y1, /* First line segment */
1644     int x2, int y2,
1645 zoff99 28
1646 zoff99 30 int x3, int y3, /* Second line segment */
1647     int x4, int y4,
1648 zoff99 28
1649 zoff99 30 int *x, int *y /* Output value:
1650     * point of intersection */
1651     )
1652 zoff99 28 {
1653 zoff99 30 int a1, a2, b1, b2, c1, c2; /* Coefficients of line eqns. */
1654     int r1, r2, r3, r4; /* 'Sign' values */
1655     int denom, offset, num; /* Intermediate values */
1656 zoff99 28
1657 zoff99 30 /* Compute a1, b1, c1, where line joining points 1 and 2
1658     * is "a1 x + b1 y + c1 = 0".
1659     */
1660 zoff99 28
1661 zoff99 30 a1 = y2 - y1;
1662     b1 = x1 - x2;
1663     c1 = x2 * y1 - x1 * y2;
1664 zoff99 28
1665 zoff99 30 /* Compute r3 and r4.
1666     */
1667     r3 = a1 * x3 + b1 * y3 + c1;
1668     r4 = a1 * x4 + b1 * y4 + c1;
1669 zoff99 28
1670 zoff99 30 /* Check signs of r3 and r4. If both point 3 and point 4 lie on
1671     * same side of line 1, the line segments do not intersect.
1672     */
1673     if (r3 != 0 && r4 != 0 && SAME_SIGNS( r3, r4 ))
1674 zoff99 28 {
1675 zoff99 30 return (DONT_INTERSECT);
1676 zoff99 28 }
1677    
1678 zoff99 30 /* Compute a2, b2, c2 */
1679     a2 = y4 - y3;
1680     b2 = x3 - x4;
1681     c2 = x4 * y3 - x3 * y4;
1682 zoff99 28
1683 zoff99 30 /* Compute r1 and r2 */
1684     r1 = a2 * x1 + b2 * y1 + c2;
1685     r2 = a2 * x2 + b2 * y2 + c2;
1686 zoff99 28
1687 zoff99 30 /* Check signs of r1 and r2. If both point 1 and point 2 lie
1688     * on same side of second line segment, the line segments do
1689     * not intersect.
1690     */
1691     if (r1 != 0 && r2 != 0 && SAME_SIGNS( r1, r2 ))
1692 zoff99 28 {
1693 zoff99 30 return (DONT_INTERSECT);
1694 zoff99 28 }
1695    
1696 zoff99 30 /* Line segments intersect: compute intersection point.
1697     */
1698 zoff99 28
1699 zoff99 30 denom = a1 * b2 - a2 * b1;
1700     if (denom == 0)
1701 zoff99 28 {
1702 zoff99 30 return (COLLINEAR);
1703 zoff99 28 }
1704 zoff99 30 offset = denom < 0 ? -denom / 2 : denom / 2;
1705 zoff99 28
1706 zoff99 30 /* The denom/2 is to get rounding instead of truncating. It
1707     * is added or subtracted to the numerator, depending upon the
1708     * sign of the numerator.
1709     */
1710 zoff99 28 /*
1711 zoff99 30 num = b1 * c2 - b2 * c1;
1712     *x = ( num < 0 ? num - offset : num + offset ) / denom;
1713     num = a2 * c1 - a1 * c2;
1714     *y = ( num < 0 ? num - offset : num + offset ) / denom;
1715     */
1716 zoff99 28
1717 zoff99 30 return (DO_INTERSECT);
1718 zoff99 28 } /* lines_intersect */
1719    
1720     static int clip_line_aprox(struct wpoint *p1, struct wpoint *p2, struct point_rect *r)
1721     {
1722     int code1, code2;
1723     code1 = clipcode(p1, r);
1724     code2 = clipcode(p2, r);
1725     if (code1 & code2)
1726     {
1727     // line completely invisible!
1728     return 0;
1729     }
1730 zoff99 30 else if ((code1 == 0) && (code2 == 0))
1731 zoff99 28 {
1732     // line completely visible!
1733     return 1;
1734     }
1735 zoff99 30 else if ((code1 == 0) || (code2 == 0))
1736 zoff99 28 {
1737     // at least 1 point of line is visible
1738     return 2;
1739     }
1740     else
1741     {
1742     int xx;
1743     int yy;
1744     // top
1745 zoff99 30 int ret_ = lines_intersect(p1->x, p1->y, p2->x, p2->y, r->lu.x, r->lu.y, r->rl.x, r->lu.y, &xx, &yy);
1746 zoff99 28 if (ret_ == DO_INTERSECT)
1747     {
1748     return 3;
1749     }
1750     // bottom
1751 zoff99 30 ret_ = lines_intersect(p1->x, p1->y, p2->x, p2->y, r->lu.x, r->rl.y, r->rl.x, r->rl.y, &xx, &yy);
1752 zoff99 28 if (ret_ == DO_INTERSECT)
1753     {
1754     return 3;
1755     }
1756     // left
1757 zoff99 30 ret_ = lines_intersect(p1->x, p1->y, p2->x, p2->y, r->lu.x, r->lu.y, r->lu.x, r->rl.y, &xx, &yy);
1758 zoff99 28 if (ret_ == DO_INTERSECT)
1759     {
1760     return 3;
1761     }
1762     // right
1763 zoff99 30 ret_ = lines_intersect(p1->x, p1->y, p2->x, p2->y, r->rl.x, r->lu.y, r->rl.x, r->rl.y, &xx, &yy);
1764 zoff99 28 if (ret_ == DO_INTERSECT)
1765     {
1766     return 3;
1767     }
1768     }
1769     // not visible
1770     return 0;
1771     }
1772    
1773 zoff99 27 static int clip_line(struct wpoint *p1, struct wpoint *p2, struct point_rect *r)
1774 zoff99 2 {
1775 zoff99 27 int code1, code2, ret = 1;
1776     int dx, dy, dw;
1777     code1 = clipcode(p1, r);
1778 zoff99 2 if (code1)
1779     ret |= 2;
1780 zoff99 27 code2 = clipcode(p2, r);
1781 zoff99 2 if (code2)
1782     ret |= 4;
1783 zoff99 27 dx = p2->x - p1->x;
1784     dy = p2->y - p1->y;
1785     dw = p2->w - p1->w;
1786     while (code1 || code2)
1787     {
1788 zoff99 2 if (code1 & code2)
1789 zoff99 28 {
1790 zoff99 2 return 0;
1791 zoff99 28 }
1792 zoff99 27 if (code1 & 1)
1793     {
1794     p1->y += (r->lu.x - p1->x) * dy / dx;
1795     p1->w += (r->lu.x - p1->x) * dw / dx;
1796     p1->x = r->lu.x;
1797 zoff99 2 }
1798 zoff99 27 else if (code1 & 2)
1799     {
1800     p1->y += (r->rl.x - p1->x) * dy / dx;
1801     p1->w += (r->rl.x - p1->x) * dw / dx;
1802     p1->x = r->rl.x;
1803     }
1804     else if (code1 & 4)
1805     {
1806     p1->x += (r->lu.y - p1->y) * dx / dy;
1807     p1->w += (r->lu.y - p1->y) * dw / dy;
1808     p1->y = r->lu.y;
1809     }
1810     else if (code1 & 8)
1811     {
1812     p1->x += (r->rl.y - p1->y) * dx / dy;
1813     p1->w += (r->rl.y - p1->y) * dw / dy;
1814     p1->y = r->rl.y;
1815     }
1816     code1 = clipcode(p1, r);
1817 zoff99 2 if (code1 & code2)
1818     return 0;
1819 zoff99 27 if (code2 & 1)
1820     {
1821     p2->y += (r->lu.x - p2->x) * dy / dx;
1822     p2->w += (r->lu.x - p2->x) * dw / dx;
1823     p2->x = r->lu.x;
1824 zoff99 2 }
1825 zoff99 27 else if (code2 & 2)
1826     {
1827     p2->y += (r->rl.x - p2->x) * dy / dx;
1828     p2->w += (r->rl.x - p2->x) * dw / dx;
1829     p2->x = r->rl.x;
1830     }
1831     else if (code2 & 4)
1832     {
1833     p2->x += (r->lu.y - p2->y) * dx / dy;
1834     p2->w += (r->lu.y - p2->y) * dw / dy;
1835     p2->y = r->lu.y;
1836     }
1837     else if (code2 & 8)
1838     {
1839     p2->x += (r->rl.y - p2->y) * dx / dy;
1840     p2->w += (r->rl.y - p2->y) * dw / dy;
1841     p2->y = r->rl.y;
1842     }
1843     code2 = clipcode(p2, r);
1844 zoff99 2 }
1845     return ret;
1846     }
1847    
1848 zoff99 40
1849    
1850     // --------------- COLORs ---------------
1851     static struct color bicycle_blue = { 0x0000,0x0000,0xf9f9,0xffff }; // RR GG BB AA
1852     static struct color bicycle_green = { 0x0808,0x8a8a,0x0808,0xffff }; // RR GG BB AA
1853     // --------------- COLORs ---------------
1854    
1855    
1856     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, int dashes, struct color *c, int mark_way)
1857 zoff99 2 {
1858 zoff99 31
1859 zoff99 27 struct point *p = g_alloca(sizeof(struct point) * (count + 1));
1860     struct wpoint p1, p2;
1861 zoff99 28 int i;
1862     int code;
1863 zoff99 2 int wmax;
1864 zoff99 28 int out = 0;
1865 zoff99 30 // const int max_segs = 2000;
1866 zoff99 34 int max_segs = 20; // send max this many segments to java with one single call
1867 zoff99 27 struct point_rect r = gra->r;
1868 zoff99 2
1869 zoff99 40
1870 zoff99 34 if (order < global_order_level_for_fast_draw)
1871     {
1872     max_segs = 100;
1873     }
1874    
1875 zoff99 30 //if (count > 30)
1876     //{
1877     // dbg(0,"segment count=%d\n", count);
1878     //}
1879 zoff99 29
1880     #if 0
1881 zoff99 28 // check if whole line is within a 2x2 pixel square
1882     if (order < 11)
1883 zoff99 27 {
1884 zoff99 28 const int max_dist = 2*2;
1885     int need_draw = 0;
1886     int diff;
1887     for (i = 0; i < count; i++)
1888 zoff99 27 {
1889 zoff99 28 if (i > 0)
1890     {
1891     p2.x = pa[i].x;
1892     p2.y = pa[i].y;
1893     diff = (p2.x - p1.x) * (p2.y - p1.y);
1894     if (diff < 0)
1895     {
1896     diff = -diff;
1897     }
1898    
1899     if (diff > max_dist)
1900     {
1901     // line is bigger, so we need to draw it
1902     need_draw = 1;
1903     break;
1904     }
1905     }
1906     else
1907     {
1908     p1.x = pa[i - 1].x;
1909     p1.y = pa[i - 1].y;
1910     }
1911 zoff99 2 }
1912 zoff99 28
1913     if (need_draw == 0)
1914     {
1915     // dont draw this line
1916     return;
1917     }
1918 zoff99 2 }
1919 zoff99 29 #endif
1920 zoff99 27
1921 zoff99 28 // calc visible area on screen
1922 zoff99 30 wmax = width[0];
1923     r.lu.x -= wmax;
1924     r.lu.y -= wmax;
1925     r.rl.x += wmax;
1926     r.rl.y += wmax;
1927 zoff99 28
1928 zoff99 27 for (i = 0; i < count; i++)
1929     {
1930 zoff99 28 if (i > 0)
1931 zoff99 27 {
1932     p1.x = pa[i - 1].x;
1933     p1.y = pa[i - 1].y;
1934     p2.x = pa[i].x;
1935     p2.y = pa[i].y;
1936 zoff99 28 /* 0 = invisible, 1 = completely visible, 2,3 = at least part of line visible */
1937 zoff99 30 code = clip_line_aprox(&p1, &p2, &r);
1938 zoff99 29 // code = 1;
1939 zoff99 27
1940 zoff99 28 if (code > 0)
1941 zoff99 27 {
1942 zoff99 28 if (out == 0)
1943     {
1944 zoff99 30 p[out].x = p1.x;
1945     p[out].y = p1.y;
1946 zoff99 28 out++;
1947     }
1948 zoff99 30 p[out].x = p2.x;
1949     p[out].y = p2.y;
1950 zoff99 2 out++;
1951 zoff99 28
1952     if ((out <= max_segs) && (i < (count - 1)))
1953     {
1954     // ok gather more line segs
1955     continue;
1956     }
1957 zoff99 2 }
1958 zoff99 28 else // (code == 0)
1959 zoff99 27 {
1960 zoff99 28 if (out == 0)
1961     {
1962     // first visible line seg not yet found, search on ...
1963     continue;
1964     }
1965 zoff99 2 }
1966 zoff99 27
1967 zoff99 28 // PAINT --- LINE SEGMENTS ------------
1968     // PAINT --- LINE SEGMENTS ------------
1969    
1970 zoff99 30 if ((poly == 1) || (poly == 0))
1971     {
1972     // normal street
1973     //if (1 == 0)
1974     //{
1975     // // draw as polygon --> OLD method
1976     // graphics_draw_polyline_as_polygon(gra, gc, p, out, w, step, 1, order, 0);
1977     //}
1978     //else
1979     //{
1980     // draw as line
1981 zoff99 40 if (mark_way == 1)
1982     {
1983     // dbg(0, "CYCLE LANE:001\n");
1984     // mark way with bicycle lanes
1985     gra->meth.draw_lines3(gra->priv, gc->priv, p, out, order, width[i] + 4, dashes, &bicycle_green, global_clinedrawing_active, 0);
1986     }
1987     else if (mark_way == 2)
1988     {
1989     // dbg(0, "CYCLE LANE:001\n");
1990     // mark way with bicycle tracks
1991     gra->meth.draw_lines3(gra->priv, gc->priv, p, out, order, width[i] + 4, dashes, &bicycle_blue, global_clinedrawing_active, 0);
1992     }
1993     gra->meth.draw_lines3(gra->priv, gc->priv, p, out, order, width[i], dashes, c, global_clinedrawing_active, 1);
1994 zoff99 30 //draw_lines_count_3++;
1995     //}
1996 zoff99 27
1997 zoff99 30 // one way arrow
1998     if ((oneway > 0) && (order > 13))
1999     {
2000     gra->meth.draw_lines2(gra->priv, gc->priv, p, out, order, oneway);
2001     //draw_lines_count_2++;
2002     }
2003     }
2004     else if (poly == 2)
2005     {
2006     // ******* street is underground ********
2007     // ******* street is underground ********
2008     // ******* street is underground ********
2009 zoff99 27
2010 zoff99 30 //if (1 == 0)
2011     //{
2012     // // draw as polygon --> OLD method
2013     // graphics_draw_polyline_as_polygon(gra, gc, p, out, w, step, 0, order, 0);
2014     //}
2015     //else
2016     //{
2017 zoff99 28
2018 zoff99 40 if (mark_way == 1)
2019     {
2020     // mark way with bicycle lanes
2021     gra->meth.draw_lines4(gra->priv, gc->priv, p, out, order, width[i] + 4, 1, dashes, &bicycle_green, 0);
2022     }
2023     else if (mark_way == 2)
2024     {
2025     // mark way with bicycle track
2026     gra->meth.draw_lines4(gra->priv, gc->priv, p, out, order, width[i] + 4, 1, dashes, &bicycle_blue, 0);
2027     }
2028    
2029 zoff99 30 // draw as line
2030 zoff99 40 gra->meth.draw_lines4(gra->priv, gc->priv, p, out, order, width[i], 1, dashes, c, 1);
2031 zoff99 30 //draw_lines_count_4++;
2032     //}
2033 zoff99 27
2034 zoff99 30 // one way arrow
2035     if ((oneway > 0) && (order > 13))
2036     {
2037     gra->meth.draw_lines2(gra->priv, gc->priv, p, out, order, oneway);
2038     //draw_lines_count_2++;
2039     }
2040     }
2041     else if (poly == 3)
2042     {
2043     // ******* street has bridge ********
2044     // ******* street has bridge ********
2045     // ******* street has bridge ********
2046 zoff99 40
2047     if (mark_way == 1)
2048     {
2049     // mark way with bicycle lanes
2050     gra->meth.draw_lines4(gra->priv, gc->priv, p, out, order, width[i] + 4, 2, dashes, &bicycle_green, 0);
2051     }
2052     else if (mark_way == 2)
2053     {
2054     // mark way with bicycle track
2055     gra->meth.draw_lines4(gra->priv, gc->priv, p, out, order, width[i] + 4, 2, dashes, &bicycle_blue, 0);
2056     }
2057    
2058     gra->meth.draw_lines4(gra->priv, gc->priv, p, out, order, width[i], 2, dashes, c, 1);
2059 zoff99 30 //draw_lines_count_4++;
2060 zoff99 27
2061 zoff99 30 // one way arrow
2062     if ((oneway > 0) && (order > 13))
2063     {
2064     gra->meth.draw_lines2(gra->priv, gc->priv, p, out, order, oneway);
2065     //draw_lines_count_2++;
2066     }
2067     }
2068     // --> now NOT used anymore!!
2069     else // poly==0 -> street that is only a line (width=1)
2070     {
2071     // OLD // gra->meth.draw_lines2(gra->priv, gc->priv, p, out, order, 0);
2072 zoff99 27
2073 zoff99 40 gra->meth.draw_lines3(gra->priv, gc->priv, p, out, order, width[i], dashes, c, global_clinedrawing_active, 1);
2074 zoff99 30 //draw_lines_count_3++;
2075 zoff99 27
2076 zoff99 30 // one way arrow
2077     if ((oneway > 0) && (order > 13))
2078     {
2079     gra->meth.draw_lines2(gra->priv, gc->priv, p, out, order, oneway);
2080     //draw_lines_count_2++;
2081     }
2082     }
2083 zoff99 28
2084     out = 0; // reset point counter after painting
2085     // PAINT --- LINE SEGMENTS ------------
2086     // PAINT --- LINE SEGMENTS ------------
2087     // PAINT --- LINE SEGMENTS ------------
2088 zoff99 2 }
2089     }
2090     }
2091    
2092 zoff99 27 static int is_inside(struct point *p, struct point_rect *r, int edge)
2093 zoff99 2 {
2094 zoff99 27 switch (edge)
2095     {
2096     case 0:
2097     return p->x >= r->lu.x;
2098     case 1:
2099     return p->x <= r->rl.x;
2100     case 2:
2101     return p->y >= r->lu.y;
2102     case 3:
2103     return p->y <= r->rl.y;
2104     default:
2105     return 0;
2106 zoff99 2 }
2107     }
2108    
2109 zoff99 27 static void poly_intersection(struct point *p1, struct point *p2, struct point_rect *r, int edge, struct point *ret)
2110 zoff99 2 {
2111 zoff99 27 int dx = p2->x - p1->x;
2112     int dy = p2->y - p1->y;
2113     switch (edge)
2114     {
2115     case 0:
2116     ret->y = p1->y + (r->lu.x - p1->x) * dy / dx;
2117     ret->x = r->lu.x;
2118     break;
2119     case 1:
2120     ret->y = p1->y + (r->rl.x - p1->x) * dy / dx;
2121     ret->x = r->rl.x;
2122     break;
2123     case 2:
2124     ret->x = p1->x + (r->lu.y - p1->y) * dx / dy;
2125     ret->y = r->lu.y;
2126     break;
2127     case 3:
2128     ret->x = p1->x + (r->rl.y - p1->y) * dx / dy;
2129     ret->y = r->rl.y;
2130     break;
2131 zoff99 2 }
2132     }
2133    
2134 zoff99 27 static void graphics_draw_polygon_clipped(struct graphics *gra, struct graphics_gc *gc, struct point *pin, int count_in)
2135 zoff99 2 {
2136 zoff99 27 struct point_rect r = gra->r;
2137     struct point *pout, *p, *s, pi, *p1, *p2;
2138     int limit = 10000;
2139     struct point *pa1 = g_alloca(sizeof(struct point) * (count_in < limit ? count_in * 8 + 1 : 0));
2140     struct point *pa2 = g_alloca(sizeof(struct point) * (count_in < limit ? count_in * 8 + 1 : 0));
2141     int count_out, edge = 3;
2142 zoff99 2 int i;
2143     #if 0
2144     r.lu.x+=20;
2145     r.lu.y+=20;
2146     r.rl.x-=20;
2147     r.rl.y-=20;
2148     #endif
2149 zoff99 27 if (count_in < limit)
2150     {
2151     p1 = pa1;
2152     p2 = pa2;
2153     }
2154     else
2155     {
2156 zoff99 40 p1 = g_new0(struct point, count_in*8+1);
2157     p2 = g_new0(struct point, count_in*8+1);
2158     }
2159 zoff99 2
2160 zoff99 40 pout=p1;
2161     for (edge = 0; edge < 4; edge++)
2162 zoff99 27 {
2163 zoff99 40 p=pin;
2164     s=pin+count_in-1;
2165     count_out=0;
2166     for (i = 0; i < count_in; i++)
2167 zoff99 27 {
2168 zoff99 40 if (is_inside(p, &r, edge))
2169 zoff99 27 {
2170 zoff99 40 if (! is_inside(s, &r, edge))
2171     {
2172     poly_intersection(s,p,&r,edge,&pi);
2173     pout[count_out++]=pi;
2174     }
2175     pout[count_out++]=*p;
2176 zoff99 27 }
2177 zoff99 40 else
2178     {
2179     if (is_inside(s, &r, edge))
2180     {
2181     poly_intersection(p,s,&r,edge,&pi);
2182     pout[count_out++]=pi;
2183     }
2184     }
2185     s=p;
2186     p++;
2187 zoff99 2 }
2188 zoff99 40 count_in=count_out;
2189     if (pin == p1)
2190     {
2191     pin=p2;
2192     pout=p1;
2193     }
2194 zoff99 27 else
2195     {
2196 zoff99 40 pin=p1;
2197     pout=p2;
2198 zoff99 2 }
2199     }
2200 zoff99 40
2201    
2202    
2203     gra->meth.draw_polygon(gra->priv, gc->priv, pin, count_in);
2204     if (count_in >= limit)
2205 zoff99 27 {
2206 zoff99 40 g_free(p1);
2207     g_free(p2);
2208 zoff99 2 }
2209     }
2210    
2211 zoff99 27 static void display_context_free(struct display_context *dc)
2212 zoff99 2 {
2213     if (dc->gc)
2214     graphics_gc_destroy(dc->gc);
2215     if (dc->gc_background)
2216     graphics_gc_destroy(dc->gc_background);
2217     if (dc->img)
2218     graphics_image_free(dc->gra, dc->img);
2219 zoff99 27 dc->gc = NULL;
2220     dc->gc_background = NULL;
2221     dc->img = NULL;
2222 zoff99 2 }
2223    
2224     static struct graphics_font *
2225     get_font(struct graphics *gra, int size)
2226     {
2227     if (size > 64)
2228 zoff99 27 {
2229     size = 64;
2230     }
2231 zoff99 40
2232 zoff99 27 if (size >= gra->font_len)
2233     {
2234 zoff99 2 gra->font=g_renew(struct graphics_font *, gra->font, size+1);
2235     while (gra->font_len <= size)
2236 zoff99 27 {
2237     gra->font[gra->font_len++] = NULL;
2238     }
2239 zoff99 2 }
2240 zoff99 40
2241 zoff99 27 if (!gra->font[size])
2242     {
2243     gra->font[size] = graphics_font_new(gra, size * gra->font_size, 0);
2244     }
2245 zoff99 40
2246 zoff99 2 return gra->font[size];
2247     }
2248    
2249     void graphics_draw_text_std(struct graphics *this_, int text_size, char *text, struct point *p)
2250     {
2251 zoff99 27 struct graphics_font *font = get_font(this_, text_size);
2252 zoff99 2 struct point bbox[4];
2253     int i;
2254    
2255     graphics_get_text_bbox(this_, font, text, 0x10000, 0, bbox, 0);
2256 zoff99 27 for (i = 0; i < 4; i++)
2257     {
2258     bbox[i].x += p->x;
2259     bbox[i].y += p->y;
2260 zoff99 2 }
2261 zoff99 27 graphics_draw_rectangle(this_, this_->gc[2], &bbox[1], bbox[2].x - bbox[0].x, bbox[0].y - bbox[1].y + 5);
2262 zoff99 2 graphics_draw_text(this_, this_->gc[1], this_->gc[2], font, text, p, 0x10000, 0);
2263     }
2264    
2265     char *
2266     graphics_icon_path(char *icon)
2267     {
2268     static char *navit_sharedir;
2269 zoff99 27 char *ret = NULL;
2270     struct file_wordexp *wordexp = NULL;
2271     // dbg(1, "enter %s\n", icon);
2272     if (strchr(icon, '$'))
2273     {
2274     wordexp = file_wordexp_new(icon);
2275 zoff99 2 if (file_wordexp_get_count(wordexp))
2276 zoff99 27 {
2277     icon = file_wordexp_get_array(wordexp)[0];
2278     }
2279 zoff99 2 }
2280 zoff99 27
2281     if (strchr(icon, '/'))
2282     {
2283     ret = g_strdup(icon);
2284     }
2285     else
2286     {
2287 zoff99 2 #ifdef HAVE_API_ANDROID
2288     // get resources for the correct screen density
2289     //
2290     // this part not needed, android unpacks only the correct version into res/drawable dir!
2291 zoff99 27 // // dbg(1,"android icon_path %s\n",icon);
2292 zoff99 2 // static char *android_density;
2293     // android_density = getenv("ANDROID_DENSITY");
2294     // ret=g_strdup_printf("res/drawable-%s/%s",android_density ,icon);
2295     ret=g_strdup_printf("res/drawable/%s" ,icon);
2296     #else
2297 zoff99 27 if (!navit_sharedir)
2298     {
2299 zoff99 2 navit_sharedir = getenv("NAVIT_SHAREDIR");
2300 zoff99 27 }
2301     ret = g_strdup_printf("%s/xpm/%s", navit_sharedir, icon);
2302 zoff99 2 #endif
2303     }
2304 zoff99 27
2305 zoff99 2 if (wordexp)
2306 zoff99 27 {
2307 zoff99 2 file_wordexp_destroy(wordexp);
2308 zoff99 27 }
2309    
2310 zoff99 2 return ret;
2311     }
2312    
2313 zoff99 27 static int limit_count(struct coord *c, int count)
2314 zoff99 2 {
2315     int i;
2316 zoff99 27 for (i = 1; i < count; i++)
2317     {
2318 zoff99 2 if (c[i].x == c[0].x && c[i].y == c[0].y)
2319 zoff99 27 return i + 1;
2320 zoff99 2 }
2321     return count;
2322     }
2323    
2324 zoff99 40 static void displayitem_draw(struct displayitem *di, void *dummy, struct display_context *dc, int order, int allow_dashed, int run_type, int is_first)
2325 zoff99 2 {
2326 zoff99 31
2327 zoff99 27 int *width = g_alloca(sizeof(int) * dc->maxlen);
2328     struct point *pa = g_alloca(sizeof(struct point) * dc->maxlen);
2329     struct graphics *gra = dc->gra;
2330     struct graphics_gc *gc = dc->gc;
2331     struct element *e = dc->e;
2332     struct graphics_image *img = dc->img;
2333 zoff99 2 struct point p;
2334     char *path;
2335 zoff99 34 struct color custom_color;
2336     int dont_draw = 0;
2337 zoff99 2
2338 zoff99 40 int oneway;
2339     int mark_way;
2340    
2341 zoff99 30 //if (run_type > 100) // dbg(0,"enter\n");
2342 zoff99 2
2343     while (di)
2344     {
2345 zoff99 30
2346     // stop drawing is requested
2347     if (cancel_drawing_global == 1)
2348     {
2349     break;
2350     }
2351    
2352 zoff99 28 if (run_type != 99)
2353     {
2354     if (run_type == 1)
2355     {
2356 zoff99 34 if (di->item.flags & NAVIT_AF_UNDERGROUND)
2357 zoff99 28 {
2358     // next item
2359     di = di->next;
2360     continue;
2361     }
2362 zoff99 34 else if (di->item.flags & NAVIT_AF_BRIDGE)
2363 zoff99 28 {
2364     // next item
2365     di = di->next;
2366     continue;
2367     }
2368     }
2369     else if (run_type == 2)
2370     {
2371     // tunnel
2372 zoff99 34 if (di->item.flags & NAVIT_AF_UNDERGROUND)
2373 zoff99 28 {
2374     }
2375     else
2376     {
2377     // next item
2378     di = di->next;
2379     continue;
2380     }
2381     }
2382     else if (run_type == 3)
2383     {
2384     // bridge
2385 zoff99 34 if (di->item.flags & NAVIT_AF_BRIDGE)
2386 zoff99 28 {
2387     }
2388     else
2389     {
2390     // next item
2391     di = di->next;
2392     continue;
2393     }
2394     }
2395     }
2396    
2397 zoff99 27 int i, count = di->count, mindist = dc->mindist;
2398 zoff99 2
2399 zoff99 27 if (!gc)
2400 zoff99 2 {
2401 zoff99 27 gc = graphics_gc_new(gra);
2402 zoff99 2 graphics_gc_set_foreground(gc, &e->color);
2403 zoff99 27 dc->gc = gc;
2404 zoff99 2 }
2405    
2406     if (item_type_is_area(dc->type) && (dc->e->type == element_polyline || dc->e->type == element_text))
2407 zoff99 27 {
2408     count = limit_count(di->c, count);
2409     }
2410 zoff99 31
2411 zoff99 2 if (dc->type == type_poly_water_tiled)
2412 zoff99 27 {
2413     mindist = 0;
2414 zoff99 34 if (order < 12)
2415 zoff99 31 {
2416 zoff99 34 mindist = 4;
2417 zoff99 31 }
2418 zoff99 27 }
2419 zoff99 31 else if (dc->type == type_border_country)
2420 zoff99 28 {
2421     if (order < 10)
2422     {
2423 zoff99 34 mindist = 4;
2424 zoff99 28 }
2425     }
2426 zoff99 31 else if (dc->type == type_poly_wood_from_triang)
2427     {
2428 zoff99 34 if (order > 11)
2429 zoff99 31 {
2430     mindist = 0;
2431     }
2432     }
2433     else if (dc->type == type_poly_water_from_triang)
2434     {
2435 zoff99 34 if (order > 10)
2436 zoff99 31 {
2437     mindist = 0;
2438     }
2439     }
2440 zoff99 34 #if 0
2441     else
2442     {
2443     if (order < global_order_level_for_fast_draw)
2444     {
2445     dbg(0, "else: mindist_old=%d\n", mindist);
2446     mindist = 5;
2447     dbg(0, "else: mindist_new=%d\n", mindist);
2448     }
2449     }
2450     #endif
2451     //dbg(0, "mindist now=%d\n", mindist);
2452 zoff99 31
2453 zoff99 34
2454 zoff99 2 if (dc->e->type == element_polyline)
2455 zoff99 27 {
2456     count = transform(dc->trans, dc->pro, di->c, pa, count, mindist, e->u.polyline.width, width);
2457     }
2458 zoff99 2 else
2459 zoff99 27 {
2460     count = transform(dc->trans, dc->pro, di->c, pa, count, mindist, 0, NULL);
2461     }
2462 zoff99 2
2463 zoff99 40 //dbg(0,"**dc->type=%s count=%d\n", item_to_name(dc->type), count);
2464     //dbg(0,"** e->type=%s\n", item_to_name(e->type));
2465    
2466 zoff99 2 switch (e->type)
2467     {
2468 zoff99 27 case element_polygon:
2469     graphics_draw_polygon_clipped(gra, gc, pa, count);
2470     break;
2471     case element_polyline:
2472 zoff99 2 {
2473     gc->meth.gc_set_linewidth(gc->priv, 1);
2474    
2475 zoff99 27 int poly = e->u.polyline.width > 1;
2476 zoff99 2
2477     // detect underground streets/lines/etc ...
2478 zoff99 34 //if ((allow_dashed) && (di->item.flags & NAVIT_AF_UNDERGROUND))
2479     if (di->item.flags & NAVIT_AF_UNDERGROUND)
2480 zoff99 2 {
2481 zoff99 27 poly = 2;
2482 zoff99 2 }
2483 zoff99 34 else if (di->item.flags & NAVIT_AF_BRIDGE)
2484 zoff99 27 {
2485     poly = 3;
2486     }
2487 zoff99 2
2488 zoff99 40 oneway = 0;
2489 zoff99 34 if (di->item.flags & NAVIT_AF_ONEWAYREV)
2490 zoff99 2 {
2491 zoff99 27 oneway = 2;
2492 zoff99 40 if (di->item.flags & NAVIT_AF_ONEWAY_BICYCLE_NO)
2493     {
2494     oneway = oneway + 4; // oneway does not apply to bicycles here
2495     }
2496 zoff99 2 }
2497 zoff99 34 else if (di->item.flags & NAVIT_AF_ONEWAY)
2498 zoff99 2 {
2499 zoff99 27 oneway = 1;
2500 zoff99 40 if (di->item.flags & NAVIT_AF_ONEWAY_BICYCLE_NO)
2501     {
2502     oneway = oneway + 4; // oneway does not apply to bicycles here
2503     }
2504 zoff99 2 }
2505    
2506 zoff99 40 mark_way = 0;
2507     // dbg(0, "CYCLE LANE:002 is_first=%d\n", is_first);
2508     if ((dc->type != type_cycleway) && (is_first == 1) && ((global_vehicle_profile == 1) || (global_vehicle_profile == 2)))
2509     {
2510     if (di->item.flags & NAVIT_AF_BICYCLE_LANE)
2511     {
2512     mark_way = 1; // way with cycle lane
2513     }
2514     else if (di->item.flags & NAVIT_AF_BICYCLE_TRACK)
2515     {
2516     mark_way = 2; // way with cycle track (sperate bicycle lane)
2517     }
2518     }
2519    
2520 zoff99 27 // -------- apply dashes -------
2521 zoff99 30 //if (e->u.polyline.dash_num > 0)
2522     //{
2523     // 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);
2524     //}
2525 zoff99 27 // -------- apply dashes -------
2526    
2527 zoff99 30 //for (i = 0; i < count; i++)
2528     //{
2529     // if (width[i] < 1)
2530     // {
2531     // width[i] = 1;
2532     // }
2533     //}
2534 zoff99 27
2535 zoff99 28 if (dc->type == type_border_country)
2536     {
2537 zoff99 40 graphics_draw_polyline_clipped(gra, gc, pa, count, width, 99, poly, order, oneway, e->u.polyline.dash_num, &e->color, 0);
2538 zoff99 28 }
2539     else
2540     {
2541 zoff99 34 // use custom color for underground trains
2542     if (dc->type == type_rail_subway)
2543     {
2544     //dbg(0, "colour1=r:%d g:%d b:%d a:%d\n", e->color.r, e->color.g, e->color.b, e->color.a);
2545     if (di->col_int_value != 0)
2546     {
2547     //dbg(0, "colour2=r:%d g:%d b:%d a:%d\n", di->color.r, di->color.g, di->color.b, di->color.a);
2548     //e->color.r = di->color.r;
2549     //e->color.g = di->color.g;
2550     //e->color.b = di->color.b;
2551     //e->color.a = di->color.a;
2552     custom_color.r = (di->col_int_value >> 16) & 0xff;
2553     custom_color.g = (di->col_int_value >> 8) & 0xff;
2554     custom_color.b = di->col_int_value & 0xff;
2555    
2556     custom_color.r = custom_color.r << 8;
2557     custom_color.g = custom_color.g << 8;
2558     custom_color.b = custom_color.b << 8;
2559    
2560     custom_color.a = 0xffff;
2561    
2562 zoff99 40 graphics_draw_polyline_clipped(gra, gc, pa, count, width, 1, poly, order, oneway, e->u.polyline.dash_num, &custom_color, 0);
2563 zoff99 34 }
2564     else
2565     {
2566 zoff99 40 graphics_draw_polyline_clipped(gra, gc, pa, count, width, 1, poly, order, oneway, e->u.polyline.dash_num, &e->color, 0);
2567 zoff99 34 }
2568     }
2569 zoff99 40 // change color of route if in bicycle-route-mode and we want to drive against the oneway street
2570 zoff99 41 else if ((dc->type == type_street_route || dc->type == type_street_route_waypoint) && (global_vehicle_profile == 1) && ((di->col_int_value >> 26) & 3))
2571 zoff99 34 {
2572 zoff99 40 // if oneway and route goes against it
2573     if ( ((di->col_int_value >> 24) & 2) && ((di->col_int_value >> 26) & 1) )
2574     {
2575     //struct attr attr_98;
2576     //if (item_attr_get(&(di->item), attr_direction, &attr_98))
2577     //{
2578    
2579     // custom_color.a = ((di->col_int_value >> 24) & 3); // "1" == 1 , "-1" == 3 , "0" == 0 direction of route on street
2580     // ((di->col_int_value >> 26) & 3) // 1 == NAVIT_AF_ONEWAY, 2 == NAVIT_AF_ONEWAYREV
2581    
2582     // dbg(0, "direction(2).0=%x\n", di->col_int_value);
2583     // dbg(0, "direction(2)=%x oneway bicycle=%d\n", custom_color.a, ((di->col_int_value >> 26) & 3));
2584     //}
2585    
2586     // mark route in ORANGE here
2587     custom_color.r = 0xff << 8;
2588     custom_color.g = 0x80 << 8;
2589     custom_color.b = 0x00 << 8;
2590    
2591     custom_color.a = 0xffff;
2592    
2593     graphics_draw_polyline_clipped(gra, gc, pa, count, width, 1, poly, order, oneway, e->u.polyline.dash_num, &custom_color, 0);
2594     }
2595     else
2596     {
2597     graphics_draw_polyline_clipped(gra, gc, pa, count, width, 1, poly, order, oneway, e->u.polyline.dash_num, &e->color, 0);
2598     }
2599 zoff99 34 }
2600 zoff99 40 else // all other ways
2601     {
2602     graphics_draw_polyline_clipped(gra, gc, pa, count, width, 1, poly, order, oneway, e->u.polyline.dash_num, &e->color, mark_way);
2603     }
2604 zoff99 28 }
2605    
2606 zoff99 27 // -------- cancel dashes -------
2607 zoff99 30 //if (e->u.polyline.dash_num > 0)
2608     //{
2609     // int dummy_1[1];
2610     // dummy_1[0] = 0;
2611     // graphics_gc_set_dashes(gra, gc, e->u.polyline.width, e->u.polyline.offset, dummy_1, e->u.polyline.dash_num, order);
2612     //}
2613     //if (run_type > 100) // dbg(0,"gg005\n");
2614 zoff99 27 // -------- cancel dashes -------
2615 zoff99 2 }
2616 zoff99 27 break;
2617     case element_circle:
2618     if (count)
2619     {
2620 zoff99 30 //// dbg(0, "graphics_draw_circle\n");
2621 zoff99 2
2622 zoff99 34 if (di->label)
2623 zoff99 27 {
2624 zoff99 34 dont_draw = 0;
2625     // dbg(0,"poi-texton_map:m#%d:t#%d:p#%d:%s\n", label_major_on_map_count, label_on_map_count, poi_on_map_count, item_to_name(dc->type));
2626     // count labels and poi-texts and stop after drawing more than n of those
2627     if (item_is_poi(dc->type))
2628 zoff99 27 {
2629 zoff99 34 if (poi_on_map_count > MAX_POI_ICON_TEXTS_ON_MAP)
2630     {
2631     dont_draw = 1;
2632     }
2633     else
2634     {
2635     poi_on_map_count++;
2636     }
2637 zoff99 27 }
2638 zoff99 34 else if (item_is_town_label_no_major(dc->type))
2639 zoff99 27 {
2640 zoff99 34 if (label_on_map_count > MAX_PLACE_LABELS_ON_MAP)
2641     {
2642     dont_draw = 1;
2643     }
2644     else
2645     {
2646     label_on_map_count++;
2647     }
2648 zoff99 27 }
2649 zoff99 34 else if (item_is_town_label_major(dc->type))
2650 zoff99 27 {
2651 zoff99 34 if (label_major_on_map_count > MAX_MAJOR_PLACE_LABELS_ON_MAP)
2652     {
2653     dont_draw = 1;
2654     }
2655     else
2656     {
2657     label_major_on_map_count++;
2658     }
2659 zoff99 27 }
2660 zoff99 34 else if (item_is_district_label(dc->type))
2661     {
2662     // dbg(0, "district:%s\n", di->label);
2663    
2664     if (label_district_on_map_count > MAX_DISTRICT_LABELS_ON_MAP)
2665     {
2666     dont_draw = 1;
2667     }
2668     else
2669     {
2670     //dbg(0, "district *DRAW*\n");
2671     label_district_on_map_count++;
2672     }
2673     }
2674    
2675    
2676     if (dont_draw == 0)
2677     {
2678     if (e->u.circle.width > 1)
2679     {
2680     gc->meth.gc_set_linewidth(gc->priv, e->u.polyline.width);
2681     }
2682     graphics_draw_circle(gra, gc, pa, e->u.circle.radius);
2683    
2684     // -----------------------------
2685    
2686     if (e->text_size)
2687     {
2688     struct graphics_font *font = get_font(gra, e->text_size);
2689     struct graphics_gc *gc_background = dc->gc_background;
2690     if (!gc_background && e->u.circle.background_color.a)
2691     {
2692     gc_background = graphics_gc_new(gra);
2693     graphics_gc_set_foreground(gc_background, &e->u.circle.background_color);
2694     dc->gc_background = gc_background;
2695     }
2696     p.x = pa[0].x + 4 + e->u.circle.radius; // move text label a bit to the right, so it does not overlap the circle
2697     p.y = pa[0].y + (int)(e->text_size / 2); // move label a bit down, so that it is in the middle of the circle (on y-axis)
2698    
2699     if (font)
2700     {
2701     gra->meth.draw_text(gra->priv, gc->priv, gc_background ? gc_background->priv : NULL, font->priv, di->label, &p, 0x10000, 0);
2702     }
2703     else
2704     {
2705     //DBG // dbg(0, "Failed to get font with size %d\n", e->text_size);
2706     }
2707    
2708     }
2709     }
2710 zoff99 27 }
2711 zoff99 40 else // circle without label
2712     {
2713     if (dont_draw == 0)
2714     {
2715     if (e->u.circle.width > 1)
2716     {
2717     gc->meth.gc_set_linewidth(gc->priv, e->u.polyline.width);
2718     }
2719     graphics_draw_circle(gra, gc, pa, e->u.circle.radius);
2720     }
2721     }
2722 zoff99 27 }
2723     break;
2724     case element_text:
2725     if (count && di->label)
2726 zoff99 2 {
2727 zoff99 30 //if (run_type > 100) // dbg(0,"gg006\n");
2728 zoff99 28
2729 zoff99 27 struct graphics_font *font = get_font(gra, e->text_size);
2730     struct graphics_gc *gc_background = dc->gc_background;
2731    
2732     if (!gc_background && e->u.text.background_color.a)
2733     {
2734     gc_background = graphics_gc_new(gra);
2735     graphics_gc_set_foreground(gc_background, &e->u.text.background_color);
2736     dc->gc_background = gc_background;
2737 zoff99 2 }
2738    
2739     if (font)
2740 zoff99 27 {
2741 zoff99 34 if (order > 8)
2742     {
2743     label_line(gra, gc, gc_background, font, pa, count, di->label);
2744     }
2745 zoff99 27 }
2746 zoff99 2 else
2747 zoff99 27 {
2748 zoff99 30 //DBG // dbg(0, "Failed to get font with size %d\n", e->text_size);
2749 zoff99 27 }
2750 zoff99 2 }
2751 zoff99 27 break;
2752     case element_icon:
2753     if (count)
2754 zoff99 2 {
2755 zoff99 34 dont_draw = 0;
2756 zoff99 40
2757     // dbg(0,"MAP:poi-on_map:#%d:%s\n", poi_icon_on_map_count, item_to_name(dc->type));
2758    
2759 zoff99 34 if (item_is_poi(dc->type))
2760 zoff99 2 {
2761 zoff99 34 if (poi_icon_on_map_count > MAX_POI_ICONS_ON_MAP)
2762 zoff99 27 {
2763 zoff99 34 dont_draw = 1;
2764     }
2765     else
2766     {
2767     poi_icon_on_map_count++;
2768     }
2769     }
2770    
2771     if (dont_draw == 0)
2772     {
2773     if (!img || item_is_custom_poi(di->item))
2774     {
2775     if (item_is_custom_poi(di->item))
2776     {
2777     char *icon;
2778     char *src;
2779     if (img)
2780     {
2781     graphics_image_free(dc->gra, img);
2782     }
2783     src = e->u.icon.src;
2784     if (!src || !src[0])
2785     {
2786     src = "%s";
2787     }
2788     icon = g_strdup_printf(src, di->label + strlen(di->label) + 1);
2789 zoff99 40
2790 zoff99 34 path = graphics_icon_path(icon);
2791     g_free(icon);
2792     }
2793     else
2794     {
2795     path = graphics_icon_path(e->u.icon.src);
2796 zoff99 40
2797     // dbg(0,"MAP:icon=%s\n", path);
2798 zoff99 34 }
2799    
2800     img = graphics_image_new_scaled_rotated(gra, path, e->u.icon.width, e->u.icon.height, e->u.icon.rotation);
2801 zoff99 27 if (img)
2802     {
2803 zoff99 34 dc->img = img;
2804    
2805     // compensate for streched images on high dpi devices
2806     img->hot.x = (int)((float)img->width / 2.0f / (float)global_dpi_factor);
2807     img->hot.y = (int)((float)img->height / 2.0f / (float)global_dpi_factor);
2808    
2809     //dbg(0, "img2_factor=%f\n", (float)global_dpi_factor);
2810     //dbg(0, "img2_h=%d\n", img->height);
2811     //dbg(0, "img2_w=%d\n", img->width);
2812     //dbg(0, "img2_hotx=%d\n", img->hot.x);
2813     //dbg(0, "img2_hoty=%d\n", img->hot.y);
2814     //dbg(0, "img2_icon: '%s'\n", path);
2815    
2816 zoff99 27 }
2817 zoff99 34 else
2818 zoff99 27 {
2819 zoff99 40 // missing icon //
2820     dbg(0, "-- ICON MISSING -- failed to load icon '%s'\n", path);
2821 zoff99 27 }
2822 zoff99 34
2823     g_free(path);
2824 zoff99 27 }
2825 zoff99 34
2826 zoff99 2 if (img)
2827 zoff99 27 {
2828 zoff99 34 p.x = pa[0].x - img->hot.x;
2829     p.y = pa[0].y - img->hot.y;
2830    
2831     //// dbg(0,"hot: %d %d\n", img->hot.x, img->hot.y);
2832     gra->meth.draw_image(gra->priv, gra->gc[0]->priv, &p, img->priv);
2833 zoff99 27 }
2834 zoff99 2 }
2835     }
2836 zoff99 27 break;
2837     case element_image:
2838 zoff99 34 //dbg(0, "***image***: '%s'\n", di->label);
2839 zoff99 27 if (gra->meth.draw_image_warp)
2840 zoff99 34 {
2841 zoff99 27 gra->meth.draw_image_warp(gra->priv, gra->gc[0]->priv, pa, count, di->label);
2842 zoff99 34 }
2843     //else
2844     //{
2845     // dbg(0,"draw_image_warp not supported by graphics driver drawing: image='%s' count=%d\n",di->label, count);
2846     //}
2847     break;
2848     case element_maptile: // same as image, just has a diferent name in the mapfile, so we can do cool things with it!
2849     //dbg(0, "***maptile***: '%s'\n", di->label);
2850     if (gra->meth.draw_image_warp)
2851 zoff99 2 {
2852 zoff99 34 gra->meth.draw_image_warp(gra->priv, gra->gc[0]->priv, pa, count, di->label);
2853 zoff99 2 }
2854 zoff99 34 //else
2855     //{
2856     // dbg(0,"draw_image_warp not supported by graphics driver drawing: image='%s' count=%d\n",di->label, count);
2857     //}
2858 zoff99 27 break;
2859     case element_arrows:
2860     display_draw_arrows(gra, gc, pa, count);
2861     break;
2862 zoff99 30 //default:
2863     // printf("Unhandled element type %d\n", e->type);
2864 zoff99 2 }
2865 zoff99 27 di = di->next;
2866 zoff99 2 }
2867 zoff99 28
2868 zoff99 30 //if (run_type > 100) // dbg(0,"gg099\n");
2869 zoff99 40 }
2870 zoff99 28
2871 zoff99 40
2872    
2873    
2874    
2875 zoff99 2 /**
2876     * FIXME
2877     * @param <>
2878     * @returns <>
2879     * @author Martin Schaller (04/2008)
2880 zoff99 27 */
2881 zoff99 28 static void xdisplay_draw_elements(struct graphics *gra, struct displaylist *display_list, struct itemgra *itm, int run_type)
2882 zoff99 2 {
2883    
2884     struct element *e;
2885 zoff99 27 GList *es, *types;
2886     struct display_context *dc = &display_list->dc;
2887 zoff99 2 struct hash_entry *entry;
2888 zoff99 28 int draw_it = 1;
2889 zoff99 40 int is_first_item = 1;
2890 zoff99 2
2891 zoff99 28 #ifdef NAVIT_MEASURE_TIME_DEBUG
2892     clock_t s_ = debug_measure_start();
2893     #endif
2894    
2895 zoff99 40 is_first_item = 1;
2896    
2897 zoff99 27 es = itm->elements;
2898 zoff99 2 while (es)
2899     {
2900 zoff99 30 //// dbg(0,"*es\n");
2901 zoff99 27 e = es->data;
2902     dc->e = e;
2903     types = itm->type;
2904 zoff99 2 while (types)
2905     {
2906 zoff99 28 draw_it = 1;
2907    
2908 zoff99 30 // stop drawing is requested
2909     if (cancel_drawing_global == 1)
2910     {
2911     break;
2912     }
2913    
2914 zoff99 27 dc->type = GPOINTER_TO_INT(types->data);
2915 zoff99 40 // dbg(0,"**type=%s\n", item_to_name(dc->type));
2916 zoff99 28
2917 zoff99 31 if (global_draw_multipolygons == 0)
2918 zoff99 2 {
2919 zoff99 31 if (dc->type == type_poly_water_from_relations)
2920 zoff99 28 {
2921 zoff99 31 // ok "poly_water_from_relations" is found, now what?
2922 zoff99 28 draw_it = 0;
2923     }
2924 zoff99 31 else if (dc->type == type_poly_water_from_triang)
2925     {
2926     draw_it = 0;
2927     }
2928     else if (dc->type == type_wood_from_relations)
2929     {
2930     draw_it = 0;
2931     }
2932     else if (dc->type == type_poly_wood_from_triang)
2933     {
2934     draw_it = 0;
2935     }
2936     else if (dc->type == type_poly_building_from_triang)
2937     {
2938     draw_it = 0;
2939     }
2940 zoff99 2 }
2941 zoff99 28
2942     if (draw_it == 1)
2943     {
2944     entry = get_hash_entry(display_list, dc->type);
2945     if (entry && entry->di)
2946     {
2947 zoff99 40 //dbg(0,"++type=%s\n", item_to_name(dc->type));
2948     //dbg(0, "is_first_item=%d run_type=%d\n", is_first_item, run_type);
2949 zoff99 28 //if (!strcmp(item_to_name(dc->type), "border_country"))
2950     //{
2951     // displayitem_draw(entry->di, NULL, dc, display_list->order, 1, 101);
2952     //}
2953     //else
2954     //{
2955 zoff99 40 displayitem_draw(entry->di, NULL, dc, display_list->order, 1, run_type, is_first_item);
2956     is_first_item = 0;
2957 zoff99 28 //}
2958 zoff99 30 // // dbg(0,"**+gc free\n");
2959 zoff99 28 display_context_free(dc);
2960     }
2961     }
2962 zoff99 27 types = g_list_next(types);
2963 zoff99 28 draw_it = 1;
2964 zoff99 2 }
2965 zoff99 27 es = g_list_next(es);
2966 zoff99 2 }
2967 zoff99 28
2968     #ifdef NAVIT_MEASURE_TIME_DEBUG
2969     debug_mrp("xdisplay_draw_elements:", debug_measure_end(s_));
2970     #endif
2971 zoff99 40
2972    
2973 zoff99 2 }
2974    
2975 zoff99 27 void graphics_draw_itemgra(struct graphics *gra, struct itemgra *itm, struct transformation *t, char *label)
2976 zoff99 2 {
2977 zoff99 30 // dbg(0, "EEnter\n");
2978 zoff99 2
2979     // HINT: seems to only be called from vehicle.c (draw the vehicle on screen)
2980    
2981     GList *es;
2982     struct display_context dc;
2983 zoff99 27 int max_coord = 32;
2984     char *buffer = g_alloca(sizeof(struct displayitem) + max_coord * sizeof(struct coord));
2985     struct displayitem *di = (struct displayitem *) buffer;
2986     es = itm->elements;
2987     di->item.type = type_none;
2988     di->item.id_hi = 0;
2989     di->item.id_lo = 0;
2990     di->item.map = NULL;
2991     di->label = label;
2992     dc.gra = gra;
2993     dc.gc = NULL;
2994     dc.gc_background = NULL;
2995     dc.img = NULL;
2996     dc.pro = projection_screen;
2997     dc.mindist = 0;
2998     dc.trans = t;
2999     dc.type = type_none;
3000     dc.maxlen = max_coord;
3001     while (es)
3002     {
3003 zoff99 30 // dbg(0, "while loop\n");
3004 zoff99 27 struct element *e = es->data;
3005     if (e->coord_count)
3006     {
3007     if (e->coord_count > max_coord)
3008     {
3009 zoff99 30 //DBG // dbg(0, "maximum number of coords reached: %d > %d\n", e->coord_count, max_coord);
3010 zoff99 27 di->count = max_coord;
3011     }
3012     else
3013 zoff99 28 {
3014 zoff99 27 di->count = e->coord_count;
3015 zoff99 28 }
3016 zoff99 27 memcpy(di->c, e->coord, di->count * sizeof(struct coord));
3017 zoff99 2 }
3018 zoff99 27 else
3019     {
3020     di->c[0].x = 0;
3021     di->c[0].y = 0;
3022     di->count = 1;
3023     }
3024     dc.e = e;
3025     di->next = NULL;
3026 zoff99 40 displayitem_draw(di, NULL, &dc, transform_get_scale(t), 0, 99, 0);
3027 zoff99 2 display_context_free(&dc);
3028 zoff99 27 es = g_list_next(es);
3029 zoff99 2 }
3030     }
3031    
3032     /**
3033     * FIXME
3034     * @param <>
3035     * @returns <>
3036     * @author Martin Schaller (04/2008)
3037 zoff99 27 */
3038 zoff99 2 static void xdisplay_draw_layer(struct displaylist *display_list, struct graphics *gra, struct layer *lay, int order)
3039     {
3040    
3041     GList *itms;
3042     struct itemgra *itm;
3043 zoff99 28
3044 zoff99 30 int run_type = 0; // 99 -> normal
3045     // 1 -> normal streets (except tunnels and bridges)
3046     // 2 -> tunnel
3047     // 3 -> bridge
3048 zoff99 28
3049 zoff99 29 int send_refresh = 0;
3050    
3051 zoff99 28 int order_corrected = order + shift_order;
3052 zoff99 27 if (order_corrected < limit_order_corrected)
3053 zoff99 2 {
3054 zoff99 27 order_corrected = limit_order_corrected;
3055 zoff99 2 }
3056 zoff99 28
3057     int order_corrected_2 = order + shift_order;
3058 zoff99 27 if (order < 0)
3059     {
3060     order_corrected_2 = 0;
3061     }
3062 zoff99 2
3063 zoff99 34 int fast_draw_mode = 0;
3064     //dbg(0,"orderlevel=%d\n", order);
3065     if (order < global_order_level_for_fast_draw)
3066     {
3067     //dbg(0,"fast_draw_mode=1\n");
3068     fast_draw_mode = 1;
3069     run_type = 99; // draw only 1 pass, bridges and tunnels will be drawn in any order
3070     }
3071    
3072 zoff99 40 // dbg(0,"layer name=%s\n", lay->name);
3073 zoff99 27
3074 zoff99 34 // reset max drawing counters ----------------------
3075     poi_on_map_count = 0;
3076     label_on_map_count = 0;
3077     label_district_on_map_count = 0;
3078     label_major_on_map_count = 0;
3079     poi_icon_on_map_count = 0;
3080     // reset max drawing counters ----------------------
3081    
3082    
3083 zoff99 28 if ((strncmp("streets_1", lay->name, 9) == 0))
3084 zoff99 2 {
3085 zoff99 30 //// dbg(0,"MT:7.3.1 - tunnel start\n");
3086 zoff99 28 //draw_lines_count_2 = 0;
3087     //draw_lines_count_3 = 0;
3088     //draw_lines_count_4 = 0;
3089    
3090 zoff99 29 send_refresh = 1;
3091    
3092 zoff99 34 //dbg(0,"a1 fast_draw_mode=%d run_type=%d\n", fast_draw_mode, run_type);
3093    
3094    
3095     if (fast_draw_mode == 0)
3096     {
3097    
3098     //dbg(0,"fast_draw_mode===0 ?\n");
3099    
3100    
3101 zoff99 28 run_type = 2;
3102     itms = lay->itemgras;
3103     while (itms)
3104 zoff99 27 {
3105 zoff99 28 // stop drawing is requested
3106     if (cancel_drawing_global == 1)
3107     {
3108 zoff99 30 //DBG // dbg(0, "** STOP MD 002 **\n");
3109 zoff99 28 break;
3110     }
3111    
3112     itm = itms->data;
3113     //if (order_corrected >= itm->order.min && order_corrected <= itm->order.max)
3114     if (order_corrected_2 >= itm->order.min && order_corrected_2 <= itm->order.max)
3115     {
3116     xdisplay_draw_elements(gra, display_list, itm, run_type);
3117     }
3118     itms = g_list_next(itms);
3119 zoff99 27 }
3120    
3121 zoff99 30 //// dbg(0,"lines count2=%lld\n", draw_lines_count_2);
3122     //// dbg(0,"lines count3=%lld\n", draw_lines_count_3);
3123     //// dbg(0,"lines count4=%lld\n", draw_lines_count_4);
3124 zoff99 28 //draw_lines_count_2 = 0;
3125     //draw_lines_count_3 = 0;
3126     //draw_lines_count_4 = 0;
3127 zoff99 30 //// dbg(0,"MT:7.3.2 - streets start\n");
3128 zoff99 28
3129     run_type = 1;
3130     itms = lay->itemgras;
3131     while (itms)
3132 zoff99 27 {
3133 zoff99 28 // stop drawing is requested
3134     if (cancel_drawing_global == 1)
3135     {
3136 zoff99 30 //DBG // dbg(0, "** STOP MD 002 **\n");
3137 zoff99 28 break;
3138     }
3139    
3140     itm = itms->data;
3141     //if (order_corrected >= itm->order.min && order_corrected <= itm->order.max)
3142     if (order_corrected_2 >= itm->order.min && order_corrected_2 <= itm->order.max)
3143     {
3144     xdisplay_draw_elements(gra, display_list, itm, run_type);
3145     }
3146     itms = g_list_next(itms);
3147 zoff99 27 }
3148    
3149 zoff99 28 /*
3150 zoff99 30 // dbg(0,"lines count2=%lld\n", draw_lines_count_2);
3151     // dbg(0,"lines count3=%lld\n", draw_lines_count_3);
3152     // dbg(0,"lines count4=%lld\n", draw_lines_count_4);
3153     draw_lines_count_2 = 0;
3154     draw_lines_count_3 = 0;
3155     draw_lines_count_4 = 0;
3156     // dbg(0,"MT:7.3.3 - bridges start\n");
3157     */
3158 zoff99 28
3159 zoff99 34 }
3160    
3161     //dbg(0,"a2 fast_draw_mode=%d run_type=%d\n", fast_draw_mode, run_type);
3162    
3163    
3164     if (fast_draw_mode == 0)
3165     {
3166     run_type = 3;
3167     }
3168     else
3169     {
3170     run_type = 99;
3171     }
3172    
3173     //dbg(0,"a3 fast_draw_mode=%d run_type=%d\n", fast_draw_mode, run_type);
3174    
3175 zoff99 28 itms = lay->itemgras;
3176     while (itms)
3177     {
3178     // stop drawing is requested
3179     if (cancel_drawing_global == 1)
3180     {
3181 zoff99 30 //DBG // dbg(0, "** STOP MD 002 **\n");
3182 zoff99 28 break;
3183     }
3184    
3185     itm = itms->data;
3186     //if (order_corrected >= itm->order.min && order_corrected <= itm->order.max)
3187     if (order_corrected_2 >= itm->order.min && order_corrected_2 <= itm->order.max)
3188     {
3189     xdisplay_draw_elements(gra, display_list, itm, run_type);
3190     }
3191     itms = g_list_next(itms);
3192     }
3193    
3194     /*
3195 zoff99 30 // dbg(0,"lines count2=%lld\n", draw_lines_count_2);
3196     // dbg(0,"lines count3=%lld\n", draw_lines_count_3);
3197     // dbg(0,"lines count4=%lld\n", draw_lines_count_4);
3198     draw_lines_count_2 = 0;
3199     draw_lines_count_3 = 0;
3200     draw_lines_count_4 = 0;
3201     // dbg(0,"MT:7.3.4 - ready\n");
3202     */
3203 zoff99 28
3204 zoff99 27 }
3205 zoff99 28 else
3206 zoff99 27 {
3207 zoff99 28 run_type = 99;
3208     itms = lay->itemgras;
3209     while (itms)
3210     {
3211     // stop drawing is requested
3212     if (cancel_drawing_global == 1)
3213     {
3214 zoff99 30 //DBG // dbg(0, "** STOP MD 002 **\n");
3215 zoff99 28 break;
3216     }
3217    
3218     itm = itms->data;
3219     //if (order_corrected >= itm->order.min && order_corrected <= itm->order.max)
3220     if (order_corrected_2 >= itm->order.min && order_corrected_2 <= itm->order.max)
3221     {
3222     xdisplay_draw_elements(gra, display_list, itm, run_type);
3223     }
3224     itms = g_list_next(itms);
3225     }
3226 zoff99 27 }
3227 zoff99 28
3228     //if (strncmp("streets__tunnel", lay->name, 15) == 0)
3229     //{
3230     //}
3231     //else if (strncmp("streets__bridge", lay->name, 15) == 0)
3232     //{
3233     //}
3234    
3235 zoff99 27 // dirty hack to draw "waypoint(s)" ---------------------------
3236 zoff99 28 if (strncmp("Internal", lay->name, 8) == 0)
3237 zoff99 27 {
3238 zoff99 41 // if (global_routing_engine != 1)
3239 zoff99 27 {
3240 zoff99 41 if (global_navit->route)
3241 zoff99 2 {
3242 zoff99 41 if (global_navit->destination_valid == 1)
3243 zoff99 27 {
3244 zoff99 41 int count_ = 0;
3245     int curr_ = 0;
3246     count_ = g_list_length(global_navit->route->destinations);
3247     if (count_ > 1)
3248 zoff99 27 {
3249 zoff99 41 if (!global_img_waypoint)
3250     {
3251     char *path2;
3252     path2 = graphics_icon_path("nav_waypoint_bk_center.png");
3253     global_img_waypoint = graphics_image_new_scaled_rotated(gra, path2, 59, 59, 0);
3254 zoff99 34
3255 zoff99 41 // compensate for streched images on high dpi devices
3256     global_img_waypoint->hot.x = (int)((float)global_img_waypoint->width / 2.0f / (float)global_dpi_factor);
3257     global_img_waypoint->hot.y = (int)((float)global_img_waypoint->height / 2.0f / (float)global_dpi_factor);
3258 zoff99 34
3259 zoff99 41 //dbg(0, "img_factor=%f\n", (float)global_dpi_factor);
3260     //dbg(0, "img_h=%d\n", global_img_waypoint->height);
3261     //dbg(0, "img_w=%d\n", global_img_waypoint->width);
3262     //dbg(0, "img_hotx=%d\n", global_img_waypoint->hot.x);
3263     //dbg(0, "img_hoty=%d\n", global_img_waypoint->hot.y);
3264 zoff99 34
3265 zoff99 41 g_free(path2);
3266     }
3267 zoff99 27
3268 zoff99 41 struct point p2;
3269     struct coord pc77;
3270     GList *ldest = global_navit->route->destinations;
3271     while (ldest)
3272 zoff99 27 {
3273 zoff99 41 curr_++;
3274     if (curr_ < count_)
3275     {
3276     struct route_info *dst = ldest->data;
3277     pc77.x = dst->c.x;
3278     pc77.y = dst->c.y;
3279     //// dbg(0, "draw1 curr=%d x y: %d %d\n", curr_, dst->c.x, dst->c.y);
3280     enum projection pro = transform_get_projection(global_navit->trans_cursor);
3281     transform(global_navit->trans, pro, &pc77, &p2, 1, 0, 0, NULL);
3282     // transform(global_navit->trans, projection_mg, &pc77, &p2, 1, 0, 0, NULL);
3283     p2.x = p2.x - global_img_waypoint->hot.x; // hot = 29
3284     p2.y = p2.y - global_img_waypoint->hot.y; // hot = 29
3285     gra->meth.draw_image(gra->priv, gra->gc[0]->priv, &p2, global_img_waypoint->priv);
3286     }
3287     // next dest. / waypoint
3288     ldest = g_list_next(ldest);
3289 zoff99 27 }
3290     }
3291     }
3292 zoff99 2 }
3293 zoff99 27 }
3294 zoff99 40
3295    
3296 zoff99 41 #ifdef NAVIT_ROUTING_DEBUG_PRINT
3297     enum projection pro3 = transform_get_projection(global_navit->trans_cursor);
3298     struct point *p_temp = g_alloca(sizeof(struct point) * (2 + 1));
3299     #else
3300     #ifdef NAVIT_DEBUG_COORD_LIST
3301     enum projection pro3 = transform_get_projection(global_navit->trans_cursor);
3302     struct point *p_temp = g_alloca(sizeof(struct point) * (2 + 1));
3303     #endif
3304     #endif
3305 zoff99 40
3306 zoff99 41
3307     #ifdef NAVIT_TRACKING_SHOW_REAL_GPS_POS
3308    
3309     if (global_tracking_show_real_gps_pos == 1)
3310     {
3311    
3312 zoff99 40 // -------- DEBUG -------- draw real GPS position ---------
3313     // -------- DEBUG -------- draw real GPS position ---------
3314     // -------- DEBUG -------- draw real GPS position ---------
3315     if (!global_img_waypoint)
3316     {
3317     char *path2;
3318     path2 = graphics_icon_path("nav_waypoint_bk_center.png");
3319     global_img_waypoint = graphics_image_new_scaled_rotated(gra, path2, 59, 59, 0);
3320    
3321     // compensate for streched images on high dpi devices
3322     global_img_waypoint->hot.x = (int)((float)global_img_waypoint->width / 2.0f / (float)global_dpi_factor);
3323     global_img_waypoint->hot.y = (int)((float)global_img_waypoint->height / 2.0f / (float)global_dpi_factor);
3324    
3325     g_free(path2);
3326     }
3327    
3328     struct coord_geo g33;
3329     struct coord c33;
3330     struct point p2;
3331     g33.lat = global_v_pos_lat;
3332     g33.lng = global_v_pos_lng;
3333    
3334     transform_from_geo(projection_mg, &g33, &c33);
3335     enum projection pro = transform_get_projection(global_navit->trans_cursor);
3336    
3337    
3338     // cos = x
3339     // sin = y
3340     struct point *p_temp3 = g_alloca(sizeof(struct point) * (2 + 1));
3341     struct color debug_red2 = { 0xfafa,0x1010,0x0000,0xffff }; // RR GG BB AA
3342    
3343     transform(global_navit->trans, pro, &c33, &p2, 1, 0, 0, NULL);
3344     p_temp3[0].x = p2.x;
3345     p_temp3[0].y = p2.y;
3346    
3347     double dd = tracking_get_direction(global_navit->tracking);
3348     double temp_4 = (global_v_pos_dir - dd) - 90.0f;
3349    
3350     p_temp3[0].x = p_temp3[0].x + 36 * (navit_cos(temp_4 * M_PI / 180));
3351     p_temp3[0].y = p_temp3[0].y + 36 * (navit_sin(temp_4 * M_PI / 180));
3352    
3353     p_temp3[1].x = p_temp3[0].x;
3354     p_temp3[1].y = p_temp3[0].y;
3355    
3356     p_temp3[1].x = p_temp3[1].x + 35 * (navit_cos(temp_4 * M_PI / 180));
3357     p_temp3[1].y = p_temp3[1].y + 35 * (navit_sin(temp_4 * M_PI / 180));
3358    
3359     gra->meth.draw_lines3(gra->priv, gra->gc[0]->priv, p_temp3, 2, 15, 14, 0, &debug_red2, global_clinedrawing_active, 1);
3360    
3361    
3362 zoff99 41 #if 0
3363     // WINNER Segment on route segment --------------
3364     struct point *p_temp_win_3 = g_alloca(sizeof(struct point) * (2 + 1));
3365     struct color debug_win_blue2 = { 0x0000,0x0000,0xfafa,0xffff }; // RR GG BB AA
3366     struct point p_win2;
3367    
3368     transform(global_navit->trans, pro, &global_debug_route_seg_winner_p_start, &p_win2, 1, 0, 0, NULL);
3369     p_temp_win_3[0].x = p_win2.x - 140;
3370     p_temp_win_3[0].y = p_win2.y;
3371    
3372     p_temp_win_3[1].x = p_win2.x + 140;
3373     p_temp_win_3[1].y = p_win2.y;
3374    
3375     gra->meth.draw_lines3(gra->priv, gra->gc[0]->priv, p_temp_win_3, 2, 15, 4, 0, &debug_win_blue2, global_clinedrawing_active, 1);
3376    
3377     p_temp_win_3[0].x = p_win2.x;
3378     p_temp_win_3[0].y = p_win2.y - 140;
3379    
3380     p_temp_win_3[1].x = p_win2.x;
3381     p_temp_win_3[1].y = p_win2.y + 140;
3382    
3383     gra->meth.draw_lines3(gra->priv, gra->gc[0]->priv, p_temp_win_3, 2, 15, 4, 0, &debug_win_blue2, global_clinedrawing_active, 1);
3384    
3385     // WINNER Segment on route segment --------------
3386     #endif
3387    
3388     #if 0
3389     // WINNER route segment direction --------------
3390    
3391     struct color debug_win_green2 = { 0x0000,0xfafa,0x0000,0xffff }; // RR GG BB AA
3392    
3393     transform(global_navit->trans, pro, &global_debug_route_seg_winner_start, &p_win2, 1, 0, 0, NULL);
3394    
3395     p_temp_win_3[0].x = p_win2.x - 90;
3396     p_temp_win_3[0].y = p_win2.y;
3397    
3398     p_temp_win_3[1].x = p_win2.x + 90;
3399     p_temp_win_3[1].y = p_win2.y;
3400    
3401     gra->meth.draw_lines3(gra->priv, gra->gc[0]->priv, p_temp_win_3, 2, 15, 12, 0, &debug_win_green2, global_clinedrawing_active, 1);
3402    
3403    
3404    
3405     p_temp_win_3[0].x = p_win2.x;
3406     p_temp_win_3[0].y = p_win2.y;
3407    
3408     transform(global_navit->trans, pro, &global_debug_route_seg_winner_end, &p_win2, 1, 0, 0, NULL);
3409    
3410     p_temp_win_3[1].x = p_win2.x;
3411     p_temp_win_3[1].y = p_win2.y;
3412    
3413     gra->meth.draw_lines3(gra->priv, gra->gc[0]->priv, p_temp_win_3, 2, 15, 42, 0, &debug_win_green2, global_clinedrawing_active, 1);
3414    
3415     // WINNER route segment direction --------------
3416     #endif
3417    
3418    
3419    
3420 zoff99 40 // ------ text -------
3421     graphics_gc_set_foreground(gra->gc[0], &debug_red2);
3422     graphics_gc_set_linewidth(gra->gc[0], 8);
3423     struct point p7;
3424     struct graphics_font *font8 = get_font(gra, 21);
3425     char *dir_label=g_strdup_printf("%4.1f : %4.1f", (float)global_v_pos_dir, (float)dd);
3426     p7.x = p2.x + 25; // move text label a bit to the right, so it does not overlap the circle
3427     p7.y = p2.y - 160; // move label a bit up (y-axis)
3428     gra->meth.draw_text(gra->priv, gra->gc[0]->priv, NULL, font8->priv, dir_label, &p7, 0x10000, 0);
3429     g_free(dir_label);
3430     // ------ text -------
3431    
3432    
3433     p2.x = p2.x - global_img_waypoint->hot.x; // hot = 29
3434     p2.y = p2.y - global_img_waypoint->hot.y; // hot = 29
3435     gra->meth.draw_image(gra->priv, gra->gc[0]->priv, &p2, global_img_waypoint->priv);
3436    
3437     // -------- DEBUG -------- draw real GPS position ---------
3438     // -------- DEBUG -------- draw real GPS position ---------
3439     // -------- DEBUG -------- draw real GPS position ---------
3440    
3441 zoff99 41 }
3442 zoff99 40
3443 zoff99 41 #endif
3444    
3445     #ifdef NAVIT_ROUTING_DEBUG_PRINT
3446    
3447 zoff99 40 // -------- DEBUG -------- draw winner track segment ---------
3448     // -------- DEBUG -------- draw winner track segment ---------
3449     // -------- DEBUG -------- draw winner track segment ---------
3450     struct color debug_orange = { 0xffff,0x4040,0x0000,0xffff }; // RR GG BB AA
3451    
3452     if (global_navit->route)
3453     {
3454     if (global_navit->destination_valid == 1)
3455     {
3456     transform(global_navit->trans, pro3, &global_debug_route_seg_winner_start, &p_temp[0], 1, 0, 0, NULL);
3457     transform(global_navit->trans, pro3, &global_debug_route_seg_winner_end, &p_temp[1], 1, 0, 0, NULL);
3458     gra->meth.draw_lines3(gra->priv, gra->gc[0]->priv, p_temp, 2, 15, 30, 0, &debug_orange, global_clinedrawing_active, 1);
3459     }
3460     }
3461    
3462     struct color debug_turkoise = { 0x0404,0xb4b4,0xaeae,0xffff }; // RR GG BB AA
3463     transform(global_navit->trans, pro3, &global_debug_seg_winner_start, &p_temp[0], 1, 0, 0, NULL);
3464     transform(global_navit->trans, pro3, &global_debug_seg_winner_end, &p_temp[1], 1, 0, 0, NULL);
3465     gra->meth.draw_lines3(gra->priv, gra->gc[0]->priv, p_temp, 2, 15, 20, 0, &debug_turkoise, global_clinedrawing_active, 1);
3466    
3467    
3468     if (global_navit->route)
3469     {
3470     if (global_navit->destination_valid == 1)
3471     {
3472     struct color debug_red = { 0xffff,0x0000,0x0000,0xffff }; // RR GG BB AA
3473     graphics_gc_set_foreground(gra->gc[0], &debug_red);
3474     graphics_gc_set_linewidth(gra->gc[0], 10);
3475     transform(global_navit->trans, pro3, &global_debug_route_seg_winner_p_start, &p_temp[0], 1, 0, 0, NULL);
3476     gra->meth.draw_circle(gra->priv, gra->gc[0]->priv, &p_temp[0], 44);
3477     }
3478     }
3479    
3480     struct color debug_green = { 0x0000,0xffff,0x0000,0xffff }; // RR GG BB AA
3481     graphics_gc_set_foreground(gra->gc[0], &debug_green);
3482     graphics_gc_set_linewidth(gra->gc[0], 8);
3483     transform(global_navit->trans, pro3, &global_debug_seg_winner_p_start, &p_temp[0], 1, 0, 0, NULL);
3484     gra->meth.draw_circle(gra->priv, gra->gc[0]->priv, &p_temp[0], 36);
3485    
3486     if (global_navit->route)
3487     {
3488     if (global_navit->destination_valid == 1)
3489     {
3490     struct color debug_yellow = { 0xf7f7,0xfefe,0x2e2e,0xffff }; // RR GG BB AA
3491     transform(global_navit->trans, pro3, &global_debug_seg_route_start, &p_temp[0], 1, 0, 0, NULL);
3492     transform(global_navit->trans, pro3, &global_debug_seg_route_end, &p_temp[1], 1, 0, 0, NULL);
3493     gra->meth.draw_lines3(gra->priv, gra->gc[0]->priv, p_temp, 2, 15, 8, 0, &debug_yellow, global_clinedrawing_active, 1);
3494     }
3495     }
3496    
3497 zoff99 41 // -------- DEBUG -------- draw winner track segment ---------
3498     // -------- DEBUG -------- draw winner track segment ---------
3499     // -------- DEBUG -------- draw winner track segment ---------
3500     #endif
3501 zoff99 40
3502    
3503     // ============================== debug lines ==============================
3504     // ============================== debug lines ==============================
3505     // ============================== debug lines ==============================
3506 zoff99 41 #ifdef NAVIT_DEBUG_COORD_LIST
3507 zoff99 40 struct color debug_purple = { 0xffff,0x0000,0xffff,0xffff }; // RR GG BB AA
3508     transform(global_navit->trans, pro3, &global_debug_trlast_start, &p_temp[0], 1, 0, 0, NULL);
3509     transform(global_navit->trans, pro3, &global_debug_trlast_end, &p_temp[1], 1, 0, 0, NULL);
3510     gra->meth.draw_lines3(gra->priv, gra->gc[0]->priv, p_temp, 2, 15, 18, 0, &debug_purple, global_clinedrawing_active, 1);
3511    
3512    
3513     struct color debug_purple0 = { 0x1010,0xfefe,0xefef,0xffff }; // RR GG BB AA
3514     struct color debug_purple1 = { 0x3030,0xaeae,0x4f4f,0xffff }; // RR GG BB AA
3515     struct color debug_purple2 = { 0x1010,0x7878,0x3030,0xffff }; // RR GG BB AA
3516     struct color debug_red3 = { 0xffff,0x0000,0x0000,0xffff }; // RR GG BB AA
3517     struct color *debug_color_pp;
3518     int ii2;
3519     int jj;
3520    
3521     //dbg(0,"global_debug_coord_list:LOOP:num=%d\n", global_debug_coord_list_items);
3522    
3523     for (ii2 = 0; ii2 < global_debug_coord_list_items; ii2++)
3524     {
3525    
3526     //dbg(0,"global_debug_coord_list:LOOP:coord_list=%d\n", ii2);
3527    
3528     transform(global_navit->trans, pro3, &global_debug_coord_list[ii2], &p_temp[0], 1, 0, 0, NULL);
3529     ii2++;
3530     transform(global_navit->trans, pro3, &global_debug_coord_list[ii2], &p_temp[1], 1, 0, 0, NULL);
3531    
3532     jj = ((ii2 - 1) % 3);
3533     if (jj == 0)
3534     {
3535     debug_color_pp = &debug_purple0;
3536     }
3537     else if (jj == 1)
3538     {
3539     debug_color_pp = &debug_purple1;
3540     }
3541     else
3542     {
3543     debug_color_pp = &debug_purple2;
3544     }
3545    
3546    
3547     gra->meth.draw_lines3(gra->priv, gra->gc[0]->priv, p_temp, 2, 15, 6, 0, debug_color_pp, global_clinedrawing_active, 1);
3548    
3549     // ------ text -------
3550     graphics_gc_set_foreground(gra->gc[0], &debug_red3);
3551     graphics_gc_set_linewidth(gra->gc[0], 6);
3552     struct point p7;
3553     struct graphics_font *font8 = get_font(gra, 21);
3554     char *dir_label=g_strdup_printf("%d", (ii2 - 1));
3555     p7.x = p_temp[0].x + 0; // move text label a bit to the right, so it does not overlap the circle
3556     p7.y = p_temp[0].y + 0; // move label a bit down (y-axis)
3557     gra->meth.draw_text(gra->priv, gra->gc[0]->priv, NULL, font8->priv, dir_label, &p7, 0x10000, 0);
3558     g_free(dir_label);
3559     // ------ text -------
3560    
3561     // ------ text -------
3562     //graphics_gc_set_foreground(gra->gc[0], &debug_red3);
3563     //graphics_gc_set_linewidth(gra->gc[0], 6);
3564     //struct point p7;
3565     //struct graphics_font *font8 = get_font(gra, 21);
3566     dir_label=g_strdup_printf("%d", ii2);
3567     p7.x = p_temp[1].x + 8; // move text label a bit to the right, so it does not overlap the circle
3568     p7.y = p_temp[1].y + 8; // move label a bit down (y-axis)
3569     gra->meth.draw_text(gra->priv, gra->gc[0]->priv, NULL, font8->priv, dir_label, &p7, 0x10000, 0);
3570     g_free(dir_label);
3571     // ------ text -------
3572    
3573     }
3574     #endif
3575     // ============================== debug lines ==============================
3576     // ============================== debug lines ==============================
3577     // ============================== debug lines ==============================
3578    
3579    
3580    
3581 zoff99 2 }
3582 zoff99 27 // dirty hack to draw "waypoint(s)" ---------------------------
3583 zoff99 40 // dirty hack to draw "route arrows" ---------------------------
3584     else if (strncmp("RouteArrows", lay->name, 11) == 0)
3585     {
3586     if (global_navit->route)
3587     {
3588     if (global_navit->destination_valid == 1)
3589     {
3590 zoff99 29
3591 zoff99 40 #define MAX_ROUTE_ARROW_LINE_LENGTH 50.0f
3592     #define MAX_ROUTE_ARROW_LINE_LENGTH_SQ 2500
3593     #define MIN_ROUTE_ARROW_LINE_LENGTH_SQ 2000
3594     #define MAX_ROUTE_ARROW_TO_SHOW 2 // default 2
3595 zoff99 29
3596 zoff99 40 struct navigation *nav = NULL;
3597     struct map *map=NULL;
3598     struct map_rect *mr=NULL;
3599     struct item *item8 =NULL;
3600     struct attr attr8;
3601     struct coord c8;
3602     struct coord c11;
3603     struct color route_arrrow_green_1 = { 0x0404,0xb4b4,0xaeae,0xffff }; // RR GG BB AA first line and arrow
3604     struct color route_arrrow_green_2 = { 0x0909,0x8484,0x7f7f,0xffff }; // RR GG BB AA all the next lines and arrows
3605     struct color *route_arrrow_green = &route_arrrow_green_1;
3606     struct point *p8 = g_alloca(sizeof(struct point));
3607     struct point *p9_temp = g_alloca(sizeof(struct point) * (2 + 1));
3608     struct point *p11_temp = g_alloca(sizeof(struct point) * (2 + 1));
3609     enum projection pro3 = transform_get_projection(global_navit->trans_cursor);
3610     int route_arrow_count = 0;
3611     int arrow_waiting = 0;
3612    
3613    
3614     #ifdef NAVIT_SHOW_ROUTE_ARROWS
3615    
3616     graphics_gc_set_foreground(gra->gc[0], route_arrrow_green);
3617     graphics_gc_set_linewidth(gra->gc[0], 8);
3618    
3619     nav = navit_get_navigation(global_navit);
3620     if (nav)
3621     {
3622     map = navigation_get_map(nav);
3623     if (map)
3624     {
3625     mr = map_rect_new(map,NULL);
3626     if (mr)
3627     {
3628     while ((item8 = map_rect_get_item(mr)))
3629     {
3630    
3631     if (item8->type == type_nav_destination)
3632     {
3633     break;
3634     }
3635    
3636     if (item_attr_get(item8, attr_navigation_long, &attr8))
3637     {
3638     route_arrow_count++;
3639    
3640     if (route_arrow_count > MAX_ROUTE_ARROW_TO_SHOW)
3641     {
3642     break;
3643     }
3644     else if (route_arrow_count == 2)
3645     {
3646     route_arrrow_green = &route_arrrow_green_2;
3647     }
3648    
3649     item_coord_get(item8, &c8, 1);
3650    
3651     #if 0
3652     graphics_gc_set_foreground(gra->gc[0], &route_arrrow_green);
3653     graphics_gc_set_linewidth(gra->gc[0], 8);
3654     transform(global_navit->trans, pro3, &c8, p8, 1, 0, 0, NULL);
3655     gra->meth.draw_circle(gra->priv, gra->gc[0]->priv, p8, 45);
3656    
3657     struct graphics_font *font8 = get_font(gra, 25);
3658     char *arrow_label=g_strdup_printf("%d", route_arrow_count);
3659    
3660     p8->x = p8->x + 45; // move text label a bit to the right, so it does not overlap the circle
3661     p8->y = p8->y + (int)(25 / 2); // move label a bit down, so that it is in the middle of the circle (on y-axis)
3662    
3663     gra->meth.draw_text(gra->priv, gra->gc[0]->priv, NULL, font8->priv, arrow_label, p8, 0x10000, 0);
3664     g_free(arrow_label);
3665     #endif
3666    
3667    
3668     // --- find the segments for this maneuver ---
3669     struct route *route2 = NULL;
3670     struct map *route_map2 = NULL;
3671     struct map_rect *mr2 = NULL;
3672     struct item *item2 = NULL;
3673     struct coord c2;
3674     struct coord c2_prev;
3675     float route_line_length_sq;
3676     int first2 = 1;
3677     int first3 = 0;
3678     int found_seg = 0;
3679     float dx, dy;
3680     int added_seg = 0;
3681    
3682     c2.x = 0;
3683     c2.y = 0;
3684     c2_prev.x = c2.x;
3685     c2_prev.y = c2.y;
3686    
3687     route2 = navit_get_route(global_navit);
3688     if (route2)
3689     {
3690     route_map2 = route_get_map(route2);
3691     if (route_map2)
3692     {
3693     mr2 = map_rect_new(route_map2, NULL);
3694     if (mr2)
3695     {
3696     item2 = map_rect_get_item(mr2);
3697     while (item2)
3698     {
3699     if (!item_coord_get(item2, &c2, 1))
3700     {
3701     first3 = 1;
3702     item2 = map_rect_get_item(mr2);
3703     continue;
3704     }
3705    
3706     // loop all coords of the route ----------------------
3707     if (first3 == 1)
3708     {
3709     first3 = 0;
3710     }
3711     else
3712     {
3713     if ( ((c2.x == c8.x) && (c2.y == c8.y)) || (found_seg == 1) )
3714     {
3715     //if (first2 == 1)
3716     //{
3717     // first2 = 0;
3718     //}
3719     //else
3720     {
3721     //dbg(0, "11draw:c2.x=%d c2.y=%d c2_prev.x=%d c2_prev.y=%d\n", c2.x, c2.y, c2_prev.x, c2_prev.y);
3722     if (found_seg == 1)
3723     {
3724     // draw arrow head at the end
3725    
3726     route_line_length_sq = (float)transform_distance_sq(&c2_prev, &c2);
3727     if ((added_seg == 0) && (route_line_length_sq < MIN_ROUTE_ARROW_LINE_LENGTH_SQ))
3728     {
3729     // draw line
3730     transform(global_navit->trans, pro3, &c2_prev, &p9_temp[0], 1, 0, 0, NULL);
3731     transform(global_navit->trans, pro3, &c2, &p9_temp[1], 1, 0, 0, NULL);
3732     gra->meth.draw_lines3(gra->priv, gra->gc[0]->priv, p9_temp, 2, 15, 28, 0, route_arrrow_green, global_clinedrawing_active, 1);
3733    
3734     // add next coord to line/arrow
3735     found_seg = 0;
3736     added_seg = 1;
3737     }
3738     else
3739     {
3740     if (route_line_length_sq > MAX_ROUTE_ARROW_LINE_LENGTH_SQ)
3741     {
3742     route_line_length_sq = sqrt(route_line_length_sq);
3743     // make line shorter (move coord c2 backward)
3744     dx = ((float)(c2.x - c2_prev.x)) / route_line_length_sq;
3745     dy = ((float)(c2.y - c2_prev.y)) / route_line_length_sq;
3746     c2.x = c2_prev.x + (int)(dx * MAX_ROUTE_ARROW_LINE_LENGTH);
3747     c2.y = c2_prev.y + (int)(dy * MAX_ROUTE_ARROW_LINE_LENGTH);
3748     }
3749    
3750     transform(global_navit->trans, pro3, &c2_prev, &p9_temp[0], 1, 0, 0, NULL);
3751     transform(global_navit->trans, pro3, &c2, &p9_temp[1], 1, 0, 0, NULL);
3752     arrow_waiting = 1;
3753     p11_temp[0].x = p9_temp[0].x;
3754     p11_temp[0].y = p9_temp[0].y;
3755     p11_temp[1].x = p9_temp[1].x;
3756     p11_temp[1].y = p9_temp[1].y;
3757     c11.x = c2.x;
3758     c11.y = c2.y;
3759     // gra->meth.draw_lines3(gra->priv, gra->gc[0]->priv, p9_temp, 2, 15, 28, 0, route_arrrow_green, global_clinedrawing_active, 4);
3760     }
3761     }
3762     else
3763     {
3764     route_line_length_sq = (float)transform_distance_sq(&c2_prev, &c2);
3765     if (route_line_length_sq > MAX_ROUTE_ARROW_LINE_LENGTH_SQ)
3766     {
3767     route_line_length_sq = sqrt(route_line_length_sq);
3768     // make line shorter (move coord c2_prev forward)
3769     dx = ((float)(c2.x - c2_prev.x)) / route_line_length_sq;
3770     dy = ((float)(c2.y - c2_prev.y)) / route_line_length_sq;
3771     c2_prev.x = c2.x - (int)(dx * MAX_ROUTE_ARROW_LINE_LENGTH);
3772     c2_prev.y = c2.y - (int)(dy * MAX_ROUTE_ARROW_LINE_LENGTH);
3773     }
3774    
3775     transform(global_navit->trans, pro3, &c2_prev, &p9_temp[0], 1, 0, 0, NULL);
3776     transform(global_navit->trans, pro3, &c2, &p9_temp[1], 1, 0, 0, NULL);
3777    
3778     gra->meth.draw_lines3(gra->priv, gra->gc[0]->priv, p9_temp, 2, 15, 28, 0, route_arrrow_green, global_clinedrawing_active, 1);
3779    
3780     if (arrow_waiting == 1)
3781     {
3782     arrow_waiting = 0;
3783     if (((abs(c2.x - c11.x)<4) && (abs(c2.y - c11.y)<4)) || ((abs(c2_prev.x - c11.x)<4) && (abs(c2_prev.y - c11.y)<4)))
3784     {
3785     gra->meth.draw_lines3(gra->priv, gra->gc[0]->priv, p11_temp, 2, 15, 28, 0, route_arrrow_green, global_clinedrawing_active, 1);
3786     }
3787     else
3788     {
3789     if (route_arrow_count == 2)
3790     {
3791     gra->meth.draw_lines3(gra->priv, gra->gc[0]->priv, p11_temp, 2, 15, 28, 0, &route_arrrow_green_1, global_clinedrawing_active, 4);
3792     }
3793     else
3794     {
3795     gra->meth.draw_lines3(gra->priv, gra->gc[0]->priv, p11_temp, 2, 15, 28, 0, &route_arrrow_green_2, global_clinedrawing_active, 4);
3796     }
3797     }
3798     }
3799    
3800     }
3801     }
3802    
3803     if (found_seg == 0)
3804     {
3805     found_seg++;
3806     }
3807     else if (found_seg == 1)
3808     {
3809     break;
3810     }
3811    
3812     }
3813     }
3814     c2_prev.x = c2.x;
3815     c2_prev.y = c2.y;
3816    
3817     // loop all coords of the route ----------------------
3818     }
3819     map_rect_destroy(mr2);
3820     }
3821     }
3822     }
3823     // --- find the segments for this maneuver ---
3824    
3825     }
3826     }
3827     map_rect_destroy(mr);
3828    
3829     if (arrow_waiting == 1)
3830     {
3831     // if there is still an arrow to be drawn, draw it now
3832     arrow_waiting = 0;
3833     gra->meth.draw_lines3(gra->priv, gra->gc[0]->priv, p11_temp, 2, 15, 28, 0, route_arrrow_green, global_clinedrawing_active, 4);
3834     }
3835    
3836     }
3837     }
3838     }
3839    
3840     #endif
3841    
3842    
3843    
3844     #ifdef NAVIT_FREE_TEXT_DEBUG_PRINT
3845     // ------- free text list ----------
3846     // ------- free text list ----------
3847    
3848     struct color debug_blue2a = { 0x0000,0x0000,0xffff,0xffff }; // RR GG BB AA
3849     struct color debug_black2a = { 0x0000,0x0000,0x0000,0xffff }; // RR GG BB AA
3850     struct point *p_temp13a = g_alloca(sizeof(struct point));
3851     struct point *p9_temp13a = g_alloca(sizeof(struct point) * (2 + 1));
3852     enum projection pro4a = transform_get_projection(global_navit->trans_cursor);
3853     graphics_gc_set_linewidth(gra->gc[0], 8);
3854    
3855     int ij1a;
3856     for (ij1a=0; ij1a < global_freetext_list_count; ij1a++)
3857     {
3858     transform(global_navit->trans, pro4a, &global_freetext_list[ij1a].c1, p_temp13a, 1, 0, 0, NULL);
3859     graphics_gc_set_foreground(gra->gc[0], &debug_blue2a);
3860     gra->meth.draw_circle(gra->priv, gra->gc[0]->priv, p_temp13a, 36);
3861    
3862     // ------ text -------
3863     struct point p7a;
3864     struct graphics_font *font8a = get_font(gra, 10);
3865     graphics_gc_set_foreground(gra->gc[0], &debug_black2a);
3866     p7a.x = p_temp13a->x + 25; // move text label a bit to the right, so it does not overlap the circle
3867     p7a.y = p_temp13a->y + 25; // move label a bit down (y-axis)
3868     gra->meth.draw_text(gra->priv, gra->gc[0]->priv, NULL, font8a->priv, global_freetext_list[ij1a].text, &p7a, 0x10000, 0);
3869     // ------ text -------
3870     }
3871    
3872     // ------- free text list ----------
3873     // ------- free text list ----------
3874     #endif
3875    
3876    
3877    
3878    
3879    
3880    
3881     // ------- sharp turn angle list ----------
3882     // ------- sharp turn angle list ----------
3883     #ifdef NAVIT_ANGLE_LIST_DEBUG_PRINT_DRAW
3884     struct color debug_green2 = { 0x0000,0xffff,0x0000,0xffff }; // RR GG BB AA
3885     struct color debug_blue2 = { 0x0000,0x0000,0xffff,0xffff }; // RR GG BB AA
3886     struct color debug_red2 = { 0xffff,0x0000,0x0000,0xffff }; // RR GG BB AA
3887     struct point *p_temp13 = g_alloca(sizeof(struct point));
3888     struct point *p9_temp13 = g_alloca(sizeof(struct point) * (2 + 1));
3889     enum projection pro4 = transform_get_projection(global_navit->trans_cursor);
3890     graphics_gc_set_linewidth(gra->gc[0], 8);
3891    
3892     int ij1;
3893     for (ij1=0; ij1 < global_sharp_turn_list_count;ij1++)
3894     {
3895     transform(global_navit->trans, pro4, &global_sharp_turn_list[ij1].c1, p_temp13, 1, 0, 0, NULL);
3896     if (global_sharp_turn_list[ij1].dir == 1)
3897     {
3898     graphics_gc_set_foreground(gra->gc[0], &debug_green2);
3899     }
3900     else
3901     {
3902     graphics_gc_set_foreground(gra->gc[0], &debug_blue2);
3903     }
3904     gra->meth.draw_circle(gra->priv, gra->gc[0]->priv, p_temp13, 36);
3905    
3906    
3907     // --- line of turn angle ---
3908     p9_temp13[0].x = p_temp13->x;
3909     p9_temp13[0].y = p_temp13->y;
3910     transform(global_navit->trans, pro3, &global_sharp_turn_list[ij1].cs, &p9_temp13[1], 1, 0, 0, NULL);
3911     gra->meth.draw_lines3(gra->priv, gra->gc[0]->priv, p9_temp13, 2, 15, 12, 0, &debug_red2, global_clinedrawing_active, 1);
3912     transform(global_navit->trans, pro3, &global_sharp_turn_list[ij1].ce, &p9_temp13[1], 1, 0, 0, NULL);
3913     gra->meth.draw_lines3(gra->priv, gra->gc[0]->priv, p9_temp13, 2, 15, 5, 0, &debug_green2, global_clinedrawing_active, 1);
3914     // --- line of turn angle ---
3915    
3916    
3917    
3918     // ------ text -------
3919     // graphics_gc_set_foreground(gra->gc[0], &debug_red2);
3920     // graphics_gc_set_linewidth(gra->gc[0], 8);
3921     struct point p7;
3922 zoff99 41 struct graphics_font *font8 = get_font(gra, 24);
3923 zoff99 40 char *dir_label=g_strdup_printf("%d", global_sharp_turn_list[ij1].angle);
3924 zoff99 41 // dbg(0, "st.angle(2)=%d\n", global_sharp_turn_list[ij1].angle);
3925 zoff99 40
3926     if (global_sharp_turn_list[ij1].angle > 0)
3927     {
3928     p7.x = p_temp13->x + 25; // move text label a bit to the right, so it does not overlap the circle
3929 zoff99 41 p7.y = p_temp13->y + 25;
3930     // p7.y = p_temp13->y + 25 + (int)((float)global_sharp_turn_list[ij1].angle / 2.0f); // move label a bit down (y-axis)
3931 zoff99 40 }
3932     else
3933     {
3934     p7.x = p_temp13->x + 25; // move text label a bit to the right, so it does not overlap the circle
3935 zoff99 41 p7.y = p_temp13->y + 0;
3936     // p7.y = p_temp13->y + 0 + (int)((float)global_sharp_turn_list[ij1].angle / 2.0f); // move label a bit down (y-axis)
3937 zoff99 40 }
3938     gra->meth.draw_text(gra->priv, gra->gc[0]->priv, NULL, font8->priv, dir_label, &p7, 0x10000, 0);
3939     g_free(dir_label);
3940     // ------ text -------
3941    
3942     }
3943     #endif
3944     // ------- sharp turn angle list ----------
3945     // ------- sharp turn angle list ----------
3946    
3947     }
3948     }
3949     }
3950     // dirty hack to draw "route arrows" ---------------------------
3951    
3952    
3953 zoff99 29 if (send_refresh == 1)
3954     {
3955     // dummy "ready" signal ------------------------------------------
3956 zoff99 30 // dbg(0, "dummy \"ready\" signal (layers)\n");
3957 zoff99 40 gra->meth.draw_lines4(gra->priv, NULL, NULL, NULL, 1, 1, 96, 0, NULL, 1);
3958 zoff99 29 // dummy "ready" signal ------------------------------------------
3959     }
3960    
3961 zoff99 2 }
3962    
3963     /**
3964     * FIXME
3965     * @param <>
3966     * @returns <>
3967     * @author Martin Schaller (04/2008)
3968 zoff99 27 */
3969 zoff99 2 static void xdisplay_draw(struct displaylist *display_list, struct graphics *gra, struct layout *l, int order)
3970     {
3971 zoff99 40 __F_START__
3972 zoff99 2
3973     GList *lays;
3974     struct layer *lay;
3975    
3976 zoff99 34 // int draw_vector_map = 1;
3977 zoff99 27
3978 zoff99 2 // if zoomed out too much then use prerendered map tiles
3979 zoff99 34 //if (display_list->order < ORDER_USE_PRERENDERED_MAP)
3980     //{
3981     // draw_vector_map = 0;
3982     //}
3983 zoff99 2
3984 zoff99 34 #if 0
3985 zoff99 2 if (!draw_vector_map)
3986     {
3987     // draw prerendered big mapimage --- HERE ---
3988     struct transformation *t;
3989 zoff99 27 t = display_list->dc.trans;
3990 zoff99 2 struct coord *cp;
3991 zoff99 27 cp = transform_get_center(t);
3992 zoff99 2 struct attr attr;
3993 zoff99 27 struct config
3994     {
3995     struct attr **attrs;
3996     struct callback_list *cbl;
3997     }*config;
3998 zoff99 2 struct point p;
3999 zoff99 27 int valid = 0;
4000 zoff99 2 if (global_navit)
4001     {
4002 zoff99 27 if ((global_navit->vehicle) && (global_navit->vehicle->vehicle))
4003 zoff99 2 {
4004 zoff99 28 //int a, s;
4005     //struct point pnt2;
4006     //vehicle_get_cursor_data(global_navit->vehicle->vehicle, &pnt2, &a, &s);
4007 zoff99 2
4008 zoff99 28 //struct attr pos_attr;
4009     //if (vehicle_get_attr(global_navit->vehicle->vehicle, attr_position_coord_geo, &pos_attr, NULL))
4010     //{
4011 zoff99 30 // ////DBG // dbg(0,"1 lat=%f, lng=%f\n",pos_attr.u.coord_geo->lat,pos_attr.u.coord_geo->lng);
4012 zoff99 28 //}
4013 zoff99 2
4014 zoff99 27 valid = 1;
4015 zoff99 2 }
4016     }
4017    
4018     struct coord *c;
4019 zoff99 27 c = &(t->map_center);
4020 zoff99 2
4021 zoff99 27 enum projection pro = transform_get_projection(global_navit->trans_cursor);
4022 zoff99 2 struct coord_geo g22;
4023     struct coord *c22;
4024     struct point mcenter_pnt;
4025 zoff99 27 c22 = &(t->map_center);
4026 zoff99 2 transform_to_geo(projection_mg, c22, &g22);
4027     transform(global_navit->trans, pro, c22, &mcenter_pnt, 1, 0, 0, NULL);
4028    
4029     struct coord c99;
4030     struct coord_geo g99;
4031     struct point cursor_pnt;
4032     struct point p99;
4033 zoff99 28 long my_scale;
4034 zoff99 2
4035 zoff99 28 my_scale = transform_get_scale(global_navit->trans);
4036 zoff99 2
4037 zoff99 27 g99.lat = 0.0;
4038     g99.lng = 0.0;
4039 zoff99 28 // g99.lat = 80.0;
4040     // g99.lng = -174.0;
4041 zoff99 2 transform_from_geo(pro, &g99, &c99);
4042     transform(global_navit->trans, pro, &c99, &cursor_pnt, 1, 0, 0, NULL);
4043    
4044     // now really draw it
4045 zoff99 27 struct graphics *gra22 = display_list->dc.gra;
4046     struct graphics_gc *gc22 = display_list->dc.gc;
4047     if (!gc22)
4048 zoff99 2 {
4049 zoff99 27 gc22 = graphics_gc_new(gra22);
4050 zoff99 2 }
4051 zoff99 28 // 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);
4052 zoff99 30 graphics_draw_bigmap(gra22, gc22, -t->yaw, (int) (my_scale / 100), 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);
4053 zoff99 2 }
4054 zoff99 34 #endif
4055 zoff99 2
4056 zoff99 28 // reset value; --> not sure here, maybe it should NOT be reset here!!!???
4057 zoff99 30 // cancel_drawing_global = 0;
4058 zoff99 2
4059 zoff99 27 lays = l->layers;
4060     while (lays)
4061     {
4062 zoff99 30 // stop drawing is requested
4063     if (cancel_drawing_global == 1)
4064     {
4065     break;
4066     }
4067    
4068 zoff99 27 lay = lays->data;
4069 zoff99 2 if (lay->active)
4070 zoff99 27 {
4071 zoff99 2 xdisplay_draw_layer(display_list, gra, lay, order);
4072 zoff99 27 }
4073     lays = g_list_next(lays);
4074 zoff99 2 }
4075    
4076 zoff99 27 // reset value;
4077 zoff99 30 // cancel_drawing_global = 0;
4078 zoff99 27
4079 zoff99 29 // dummy "start" signal ------------------------------------------
4080 zoff99 30 // // dbg(0, "dummy \"start\" signal\n");
4081 zoff99 40 // gra->meth.draw_lines4(gra->priv, NULL, NULL, NULL, 1, 1, 97, 0);
4082 zoff99 29 // dummy "start" signal ------------------------------------------
4083    
4084 zoff99 40 __F_END__
4085 zoff99 2 }
4086    
4087     /**
4088     * FIXME
4089     * @param <>
4090     * @returns <>
4091     * @author Martin Schaller (04/2008)
4092 zoff99 27 */
4093 zoff99 2 extern void *route_selection;
4094    
4095 zoff99 27 static void displaylist_update_layers(struct displaylist *displaylist, GList *layers, int order)
4096 zoff99 2 {
4097 zoff99 30 ////DBG // dbg(0,"ooo enter ooo\n");
4098 zoff99 2
4099 zoff99 28 int order_corrected = order + shift_order;
4100 zoff99 2 //int saved=displaylist->order;
4101 zoff99 27 if (order < limit_order_corrected)
4102 zoff99 2 {
4103 zoff99 27 order_corrected = limit_order_corrected;
4104 zoff99 2 // displaylist->order=0;
4105     }
4106 zoff99 27
4107     while (layers)
4108     {
4109     struct layer *layer = layers->data;
4110     GList *itemgras = layer->itemgras;
4111     while (itemgras)
4112     {
4113     struct itemgra *itemgra = itemgras->data;
4114     GList *types = itemgra->type;
4115 zoff99 2 if (itemgra->order.min <= order_corrected && itemgra->order.max >= order_corrected)
4116     {
4117 zoff99 27 while (types)
4118     {
4119     enum item_type type = (enum item_type) types->data;
4120 zoff99 2 set_hash_entry(displaylist, type);
4121 zoff99 27 types = g_list_next(types);
4122 zoff99 2 }
4123     }
4124 zoff99 27 itemgras = g_list_next(itemgras);
4125 zoff99 2 }
4126 zoff99 27 layers = g_list_next(layers);
4127 zoff99 2 }
4128     // displaylist->order=saved;
4129     }
4130    
4131 zoff99 27 static void displaylist_update_hash(struct displaylist *displaylist)
4132 zoff99 2 {
4133 zoff99 30 ////DBG // dbg(0,"ooo enter ooo\n");
4134 zoff99 2
4135 zoff99 27 displaylist->max_offset = 0;
4136 zoff99 2 clear_hash(displaylist);
4137     displaylist_update_layers(displaylist, displaylist->layout->layers, displaylist->order);
4138 zoff99 27 // dbg(1, "max offset %d\n", displaylist->max_offset);
4139 zoff99 2 }
4140    
4141 zoff99 27 static void do_draw(struct displaylist *displaylist, int cancel, int flags)
4142 zoff99 2 {
4143 zoff99 28
4144 zoff99 40 __F_START__
4145 zoff99 28
4146 zoff99 31 // int rnd = rand();
4147 zoff99 30 // dbg(0, "DO__DRAW:%d enter\n", rnd);
4148    
4149     // try to cancel any previous drawing that might be going on ...
4150     // try to cancel any previous drawing that might be going on ...
4151     // try to cancel any previous drawing that might be going on ...
4152     // dbg(0, "DO__DRAW:%d cancel_drawing_global 1=%d\n", rnd, cancel_drawing_global);
4153     cancel_drawing_global = 1;
4154     // dbg(0, "DO__DRAW:%d cancel_drawing_global 2=%d\n", rnd, cancel_drawing_global);
4155     // try to cancel any previous drawing that might be going on ...
4156     // try to cancel any previous drawing that might be going on ...
4157     // try to cancel any previous drawing that might be going on ...
4158    
4159    
4160     // dbg(0, "DO__DRAW:%d lock mutex\n", rnd);
4161     pthread_mutex_lock(&uiConditionMutex);
4162     // dbg(0, "DO__DRAW:%d OK lock mutex\n", rnd);
4163    
4164     // drawing is now starting ...
4165     // drawing is now starting ...
4166     // drawing is now starting ...
4167     // dbg(0, "DO__DRAW:%d cancel_drawing_global 3=%d\n", rnd, cancel_drawing_global);
4168     cancel_drawing_global = 0;
4169     // dbg(0, "DO__DRAW:%d cancel_drawing_global 4=%d\n", rnd, cancel_drawing_global);
4170     // drawing is now starting ...
4171     // drawing is now starting ...
4172     // drawing is now starting ...
4173    
4174    
4175 zoff99 28 #ifdef HAVE_API_ANDROID
4176     // ---- disable map view -----
4177     // ---- disable map view -----
4178     // ---- disable map view -----
4179     if (disable_map_drawing == 1)
4180     {
4181 zoff99 30 //android_return_generic_int(2, 0);
4182 zoff99 28
4183 zoff99 30 //// dbg(0,"set:0:displaylist->busy=%d\n",displaylist->busy);
4184 zoff99 28 displaylist->busy = 0;
4185    
4186 zoff99 30 // dbg(0,"DO__DRAW:%d UN-lock mutex 001\n", rnd);
4187     pthread_mutex_unlock(&uiConditionMutex);
4188     // dbg(0,"DO__DRAW:%d OK UN-lock mutex 001\n", rnd);
4189    
4190     // dbg(0,"DO__DRAW:%d return 001\n", rnd);
4191 zoff99 40 return2;
4192 zoff99 28 }
4193     // ---- disable map view -----
4194     // ---- disable map view -----
4195     // ---- disable map view -----
4196     #endif
4197    
4198     clock_t s_;
4199     #ifdef NAVIT_MEASURE_TIME_DEBUG
4200     s_ = debug_measure_start();
4201     #endif
4202    
4203 zoff99 2 struct item *item;
4204 zoff99 27 int count, max = displaylist->dc.maxlen, workload = 0;
4205     struct coord *ca = g_alloca(sizeof(struct coord) * max);
4206     struct attr attr, attr2;
4207 zoff99 2 enum projection pro;
4208 zoff99 27 int draw_vector_map = 1; // do we draw the vecotor map, or not? 0=false, 1=true
4209 zoff99 34 int draw_tile_map = 1; // do we draw the prerendered tile map? 0=false, 1=true
4210 zoff99 27 int mapset_counter = 0;
4211     int mapset_need_draw = 0;
4212 zoff99 34 int only_labels = 0;
4213 zoff99 2
4214 zoff99 34 // int r_, g_, b_, a_;
4215     unsigned int col_int_value;
4216     struct attr attr_cc;
4217    
4218 zoff99 30 // // dbg(0,"ooo enter ooo %d\n",displaylist->order);
4219 zoff99 2
4220 zoff99 28 int order_corrected = displaylist->order + shift_order;
4221 zoff99 27 int saved = displaylist->order;
4222     if (order_corrected < limit_order_corrected)
4223 zoff99 2 {
4224 zoff99 27 order_corrected = limit_order_corrected;
4225 zoff99 2 }
4226    
4227     if (displaylist->order != displaylist->order_hashed || displaylist->layout != displaylist->layout_hashed)
4228     {
4229     displaylist_update_hash(displaylist);
4230 zoff99 27 displaylist->order_hashed = displaylist->order;
4231     displaylist->layout_hashed = displaylist->layout;
4232 zoff99 2 }
4233    
4234 zoff99 27 pro = transform_get_projection(displaylist->dc.trans);
4235 zoff99 2
4236     // if zoomed out too much then use prerendered map tiles
4237 zoff99 40 if (global_clinedrawing_active)
4238 zoff99 2 {
4239 zoff99 40 if (displaylist->order_hashed < ORDER_USE_PRERENDERED_MAP__C)
4240     {
4241     draw_vector_map = 0;
4242     }
4243    
4244     if (displaylist->order_hashed > ORDER_USE_NORMAL_MAP__C)
4245     {
4246     draw_tile_map = 0;
4247     }
4248 zoff99 2 }
4249 zoff99 40 else
4250     {
4251     if (displaylist->order_hashed < ORDER_USE_PRERENDERED_MAP) // ==5 , (4,3,2,1,0)--> no vector map
4252     {
4253     draw_vector_map = 0;
4254     }
4255 zoff99 2
4256 zoff99 40 if (displaylist->order_hashed > ORDER_USE_NORMAL_MAP) // ==6 , (7,8,9, ...)--> no tile map
4257     {
4258     draw_tile_map = 0;
4259     }
4260 zoff99 34 }
4261    
4262 zoff99 46 if (global_show_maps_debug_view)
4263     {
4264     draw_vector_map = 1;
4265     draw_tile_map = 0;
4266     }
4267    
4268 zoff99 27 displaylist->order = order_corrected;
4269 zoff99 2
4270 zoff99 30 //DBG // dbg(0, "XXXXXYYYYYYY Draw: 003\n");
4271 zoff99 27
4272     // reset value;
4273 zoff99 30 // cancel_drawing_global = 0;
4274 zoff99 27
4275 zoff99 40 char *ttt22 = NULL;
4276    
4277    
4278 zoff99 2 while (!cancel)
4279     {
4280     if (!displaylist->msh)
4281 zoff99 27 {
4282     displaylist->msh = mapset_open(displaylist->ms);
4283     }
4284    
4285     if (!displaylist->m)
4286     {
4287     displaylist->m = mapset_next(displaylist->msh, 1);
4288     if (!displaylist->m)
4289     {
4290 zoff99 2 mapset_close(displaylist->msh);
4291 zoff99 27 displaylist->msh = NULL;
4292 zoff99 2 break;
4293     }
4294    
4295     mapset_counter++;
4296 zoff99 27 mapset_need_draw = 1;
4297 zoff99 34 only_labels = 0;
4298    
4299 zoff99 2 struct attr map_name_attr;
4300 zoff99 27
4301     if (map_get_attr(displaylist->m, attr_name, &map_name_attr, NULL))
4302 zoff99 2 {
4303 zoff99 40 // dbg(0,"MAP:#+* start reading map file #+*=%s\n", map_name_attr.u.str);
4304     if (ttt22)
4305     {
4306     g_free(ttt22);
4307     }
4308     ttt22 = g_strdup(map_name_attr.u.str);
4309    
4310 zoff99 2 if (strncmp("_ms_sdcard_map:", map_name_attr.u.str, 15) == 0)
4311     {
4312     if (strncmp("_ms_sdcard_map:/sdcard/zanavi/maps/borders.bin", map_name_attr.u.str, 41) == 0)
4313     {
4314 zoff99 34 if (draw_tile_map == 1)
4315     {
4316     // if its the countryborder map
4317     mapset_need_draw = 0;
4318     }
4319     else if (displaylist->order_hashed >= ORDER_USE_BORDERS_MAP)
4320     {
4321     // on high detail -> dont draw bordermap anymore. it sometimes causes heavy slowdowns!!
4322     mapset_need_draw = 0;
4323     }
4324 zoff99 2 }
4325 zoff99 34 else if (strncmp("_ms_sdcard_map:/sdcard/zanavi/maps/coastline.bin", map_name_attr.u.str, 48) == 0)
4326     {
4327     if (draw_tile_map == 1)
4328     {
4329     // if its the countryborder map
4330     mapset_need_draw = 0;
4331     }
4332     }
4333     #if 0
4334     else if (strncmp("_ms_sdcard_map:-special-:worldmap6.txt", map_name_attr.u.str, 38) == 0)
4335     {
4336     // if its a worldmapX.txt
4337     if (draw_vector_map == 1)
4338     {
4339     //dbg(0, "wm5: v=1");
4340     mapset_need_draw = 0;
4341     }
4342     else
4343     {
4344     //dbg(0, "wm5: v=0");
4345    
4346     if (displaylist->order_hashed < 4)
4347     {
4348     //dbg(0, "wm5: nd=0");
4349     mapset_need_draw = 0;
4350     }
4351     else
4352     {
4353     //dbg(0, "wm5: nd=1");
4354     mapset_need_draw = 1;
4355     }
4356     }
4357     }
4358     #endif
4359     else if (strncmp("_ms_sdcard_map:-special-:worldmap5.txt", map_name_attr.u.str, 38) == 0)
4360     {
4361     // if its a worldmapX.txt
4362     if (draw_tile_map == 0)
4363     {
4364     mapset_need_draw = 0;
4365     }
4366     else
4367     {
4368     if (displaylist->order_hashed < 3)
4369     {
4370     mapset_need_draw = 0;
4371     }
4372     else
4373     {
4374     mapset_need_draw = 1;
4375     }
4376     }
4377     }
4378     else if (strncmp("_ms_sdcard_map:-special-:worldmap2.txt", map_name_attr.u.str, 38) == 0)
4379     {
4380     // if its a worldmapX.txt
4381     if (draw_tile_map == 0)
4382     {
4383     mapset_need_draw = 0;
4384     }
4385     else
4386     {
4387     if (displaylist->order_hashed < 3)
4388     {
4389     mapset_need_draw = 1;
4390     }
4391     else
4392     {
4393     mapset_need_draw = 0;
4394     }
4395     }
4396     }
4397 zoff99 2 else
4398     {
4399 zoff99 34 // if its an sdcard street map
4400     if (draw_vector_map == 1)
4401     {
4402     mapset_need_draw = 1;
4403     if (draw_tile_map == 1)
4404     {
4405     only_labels = 1;
4406     }
4407     }
4408     else
4409     {
4410     mapset_need_draw = 0;
4411     }
4412 zoff99 2 }
4413     }
4414     }
4415    
4416 zoff99 30 ////DBG // dbg(0,"---------==============>>>>>>>>>> ***** %d ****",mapset_counter);
4417 zoff99 2
4418 zoff99 27 displaylist->dc.pro = map_projection(displaylist->m);
4419     displaylist->conv = map_requires_conversion(displaylist->m);
4420 zoff99 2 if (route_selection)
4421     {
4422 zoff99 27 displaylist->sel = route_selection;
4423 zoff99 2 }
4424     else
4425     {
4426 zoff99 27 displaylist->sel = transform_get_selection(displaylist->dc.trans, displaylist->dc.pro, displaylist->order);
4427 zoff99 2 }
4428 zoff99 27 displaylist->mr = map_rect_new(displaylist->m, displaylist->sel);
4429 zoff99 2 }
4430 zoff99 27
4431 zoff99 40
4432 zoff99 2 if (displaylist->mr)
4433     {
4434 zoff99 40 // dbg(0,"MAP:001:map=%s\n", ttt22);
4435 zoff99 2 // draw vector map, or not?
4436 zoff99 34 // dbg(0,"draw_vector_map=%d mapset_need_draw=%d\n", draw_vector_map, mapset_need_draw);
4437     // ****** if ((draw_vector_map) || (mapset_need_draw == 1))
4438     if (mapset_need_draw == 1)
4439 zoff99 2 {
4440 zoff99 40 //dbg(0,"MAP:002:map=%s\n", ttt22);
4441 zoff99 27
4442 zoff99 30 //// dbg(0, "XXXXXYYYYYYY Draw: A.01\n");
4443 zoff99 27
4444 zoff99 28
4445     // ------ READ all items in this map rectangle ---------
4446     // ------ READ all items in this map rectangle ---------
4447     // ------ READ all items in this map rectangle ---------
4448     // ------ READ all items in this map rectangle ---------
4449     // ------ READ all items in this map rectangle ---------
4450 zoff99 31 // dbg(0,"#+* start reading map file #+*\n");
4451 zoff99 28 int _item_counter_ = 0;
4452 zoff99 27 while ((item = map_rect_get_item(displaylist->mr)))
4453 zoff99 2 {
4454 zoff99 40 //dbg(0,"MAP:003:map=%s\n", ttt22);
4455    
4456 zoff99 28 _item_counter_++;
4457    
4458 zoff99 27 int label_count = 0;
4459 zoff99 34 char *labels[3];
4460 zoff99 2 struct hash_entry *entry;
4461    
4462 zoff99 27 if (cancel_drawing_global == 1)
4463     {
4464     // stop drawing map is requested
4465 zoff99 30 //DBG // dbg(0, "** STOP MD 001 **\n");
4466 zoff99 27 break;
4467     }
4468    
4469 zoff99 2 if (item == &busy_item)
4470     {
4471     if (displaylist->workload)
4472     {
4473     // restore order :-)
4474 zoff99 27 displaylist->order = saved;
4475 zoff99 28
4476 zoff99 30 //// dbg(0,"set:0:displaylist->busy=%d\n",displaylist->busy);
4477 zoff99 28 displaylist->busy = 0;
4478    
4479 zoff99 30 // dbg(0, "DO__DRAW:%d UN-lock mutex 002\n", rnd);
4480     pthread_mutex_unlock(&uiConditionMutex);
4481     // dbg(0, "DO__DRAW:%d OK UN-lock mutex 002\n", rnd);
4482    
4483     //// dbg(0,"return 002\n");
4484     // dbg(0, "DO__DRAW:%d return 002\n", rnd);
4485 zoff99 40 return2;
4486 zoff99 2 }
4487     else
4488 zoff99 27 {
4489 zoff99 2 continue;
4490 zoff99 27 }
4491 zoff99 2 }
4492    
4493 zoff99 34 if (only_labels == 1)
4494     {
4495     if ((!item_is_town(*item)) && (!item_is_district(*item)))
4496     {
4497     // if its not a label, dont draw it
4498     continue;
4499     }
4500     }
4501    
4502 zoff99 27 entry = get_hash_entry(displaylist, item->type);
4503 zoff99 2
4504 zoff99 30 //// dbg(0, "XXXXXYYYYYYY Draw: A.item1 %p %i\n", entry, item->type);
4505 zoff99 27
4506     // DEBUG -------- zoffzoff
4507     // DEBUG -------- zoffzoff
4508     // DEBUG -------- zoffzoff
4509     //item_dump_attr_stdout(item, displaylist->m);
4510     // DEBUG -------- zoffzoff
4511     // DEBUG -------- zoffzoff
4512     // DEBUG -------- zoffzoff
4513    
4514 zoff99 2 if (!entry)
4515 zoff99 27 {
4516 zoff99 2 continue;
4517 zoff99 27 }
4518 zoff99 2
4519 zoff99 27 count = item_coord_get_within_selection(item, ca, item->type < type_line ? 1 : max, displaylist->sel);
4520 zoff99 2
4521 zoff99 27 if (!count)
4522     {
4523 zoff99 2 continue;
4524 zoff99 27 }
4525 zoff99 2
4526 zoff99 40 //dbg(0,"MAP:004:map=%s\n", ttt22);
4527    
4528 zoff99 30 //// dbg(0, "XXXXXYYYYYYY Draw: A.item2\n");
4529 zoff99 27
4530 zoff99 2 if (displaylist->dc.pro != pro)
4531 zoff99 28 {
4532 zoff99 34 //dbg(0,"from to\n");
4533 zoff99 2 transform_from_to_count(ca, displaylist->dc.pro, ca, pro, count);
4534 zoff99 28 }
4535 zoff99 2
4536     if (count == max)
4537     {
4538 zoff99 30 //DBG // dbg(0,"point count overflow %d for %s "ITEM_ID_FMT"\n", count,item_to_name(item->type),ITEM_ID_ARGS(*item));
4539 zoff99 27 displaylist->dc.maxlen = max * 2;
4540 zoff99 2 }
4541    
4542 zoff99 34 //if (item_is_custom_poi(*item))
4543     //{
4544     // if (item_attr_get(item, attr_icon_src, &attr2))
4545     // {
4546     // labels[1] = map_convert_string(displaylist->m, attr2.u.str);
4547     // }
4548     // else
4549     // {
4550     // labels[1] = NULL;
4551     // }
4552     // label_count = 2;
4553     //}
4554     //else
4555     //{
4556     labels[0] = NULL;
4557 zoff99 27 labels[1] = NULL;
4558 zoff99 34 labels[2] = NULL;
4559 zoff99 27 label_count = 0;
4560 zoff99 34 //}
4561 zoff99 2
4562 zoff99 31 // DEBUG -------- zoffzoff
4563     // DEBUG -------- zoffzoff
4564     // DEBUG -------- zoffzoff
4565     // item_dump_attr_stdout(item, displaylist->m);
4566     // DEBUG -------- zoffzoff
4567     // DEBUG -------- zoffzoff
4568     // DEBUG -------- zoffzoff
4569    
4570 zoff99 34
4571    
4572    
4573    
4574    
4575     // --------======== LABELS ========--------
4576     // --------======== LABELS ========--------
4577 zoff99 2 if (item_attr_get(item, attr_label, &attr))
4578     {
4579 zoff99 34 if (global_show_english_labels < 2)
4580 zoff99 27 {
4581 zoff99 34 // NORMAL
4582     //dbg(0, "c:%d name=%s\n", label_count, attr.u.str);
4583     labels[label_count] = attr.u.str;
4584     label_count++;
4585 zoff99 27 }
4586 zoff99 2 }
4587 zoff99 34
4588     if (item_attr_get(item, attr_street_name_match, &attr))
4589     {
4590     if ((global_show_english_labels == 1)||(global_show_english_labels == 2))
4591     {
4592     // ENGLISH or alternate
4593     //dbg(0, "c:%d street_en_name=%s\n", label_count, attr.u.str);
4594     labels[label_count] = attr.u.str;
4595     label_count++;
4596     }
4597     }
4598     else if (item_attr_get(item, attr_town_name_match, &attr))
4599     {
4600     if ((global_show_english_labels == 1)||(global_show_english_labels == 2))
4601     {
4602     // ENGLISH or alternate
4603     //dbg(0, "c:%d town_en_name=%s\n", label_count, attr.u.str);
4604     labels[label_count] = attr.u.str;
4605     label_count++;
4606     }
4607     }
4608 zoff99 2 else
4609     {
4610 zoff99 34 if (global_show_english_labels == 2)
4611     {
4612     // we want ENGLISH labels, but the item does not have it
4613     // --> so show normal label instead (item should not be nameless on map)
4614     if (item_attr_get(item, attr_label, &attr))
4615     {
4616     // NORMAL
4617     //dbg(0, "c:%d name=%s\n", label_count, attr.u.str);
4618     labels[label_count] = attr.u.str;
4619     label_count++;
4620     }
4621     }
4622 zoff99 2 }
4623 zoff99 34 // --------======== LABELS ========--------
4624     // --------======== LABELS ========--------
4625 zoff99 2
4626 zoff99 34
4627    
4628    
4629    
4630    
4631 zoff99 27 // DEBUG -------- zoffzoff
4632     // DEBUG -------- zoffzoff
4633     // DEBUG -------- zoffzoff
4634     // item_dump_attr_stdout(item, displaylist->m);
4635     // DEBUG -------- zoffzoff
4636     // DEBUG -------- zoffzoff
4637     // DEBUG -------- zoffzoff
4638 zoff99 2
4639     struct attr attr_77;
4640     if (item_attr_get(item, attr_flags, &attr_77))
4641     {
4642 zoff99 30 // // dbg(0,"uuuuuuuuuuuuu %s uuuuu %d\n",item_to_name(item->type), attr_77.u.num);
4643 zoff99 27 item->flags = attr_77.u.num;
4644 zoff99 2 }
4645     else
4646     {
4647 zoff99 27 item->flags = 0;
4648 zoff99 2 }
4649    
4650     //struct attr *attr88;
4651     //if (item_attr_get(item, attr_flags, &attr88))
4652     //{
4653 zoff99 30 ////DBG // dbg(0,"item flags=%d\n",attr88->u.num);
4654 zoff99 2 //}
4655     //attr88=NULL;
4656    
4657 zoff99 27
4658     /*
4659 zoff99 34 if (item->flags & NAVIT_AF_UNDERGROUND)
4660 zoff99 30 {
4661     // dbg(0,"is UNDERGROUND\n");
4662     }
4663 zoff99 34 else if (item->flags & NAVIT_AF_BRIDGE)
4664 zoff99 30 {
4665     // dbg(0,"is BRIDGE\n");
4666     }
4667     */
4668 zoff99 27
4669 zoff99 34 // a_=0;
4670     if (item_attr_get(item, attr_colour2, &attr_cc))
4671 zoff99 2 {
4672 zoff99 34
4673     col_int_value = (unsigned int)attr_cc.u.num;
4674     //dbg(0, "ccooll:1 c=%d\n", col_int_value);
4675    
4676     //r_= (col_int_value >> 16) & 0xff;
4677     //g_= (col_int_value >> 8) & 0xff;
4678     //b_= col_int_value & 0xff;
4679    
4680     //dbg(0, "ccooll:2 r=%d g=%d b=%d\n", r_,g_,b_);
4681    
4682     //r_ = r_ << 8;
4683     //g_ = g_ << 8;
4684     //b_ = b_ << 8;
4685    
4686     //dbg(0, "ccooll:3 r=%d g=%d b=%d\n", r_,g_,b_);
4687    
4688     //a_ = 0xffff;
4689 zoff99 2 }
4690     else
4691     {
4692 zoff99 34 col_int_value = 0;
4693 zoff99 2 }
4694    
4695 zoff99 40
4696     struct attr attr_88;
4697 zoff99 41 if ((item->type == type_street_route) || (item->type == type_street_route_waypoint))
4698 zoff99 40 {
4699     if (item_attr_get(item, attr_direction, &attr_88))
4700     {
4701     //dbg(0, "direction(1a1)=%d %x\n", attr_88.u.num, col_int_value);
4702     col_int_value = col_int_value & 0xffffff;
4703     //dbg(0, "direction(1a2)=%x %x\n", attr_88.u.num, col_int_value);
4704     //dbg(0, "direction(1a2.1)=%x %x\n", (attr_88.u.num & 3), ((attr_88.u.num & 3) << 24));
4705     col_int_value = col_int_value | ((attr_88.u.num & 3) << 24);
4706     //dbg(0, "direction(1a3)=%x %x\n", attr_88.u.num, col_int_value);
4707     }
4708     else
4709     {
4710     //dbg(0, "direction(1b1)=%x\n", col_int_value);
4711     col_int_value = col_int_value & 0xffffff;
4712     //dbg(0, "direction(1b2)=%x\n", col_int_value);
4713     }
4714    
4715     if (item_attr_get(item, attr_details, &attr_88))
4716     {
4717     // dbg(0, "direction(0)=%x\n", attr_88.u.num);
4718    
4719     // #define NAVIT_AF_ONEWAY (1<<0)
4720     // #define NAVIT_AF_ONEWAYREV (1<<1)
4721     // #define NAVIT_AF_ONEWAY_BICYCLE_NO (1<<16)
4722    
4723     if (attr_88.u.num & NAVIT_AF_ONEWAY_BICYCLE_NO)
4724     {
4725     // dbg(0, "direction(0)=%x\n", (attr_88.u.num & (NAVIT_AF_ONEWAY|NAVIT_AF_ONEWAYREV)));
4726     // dbg(0, "direction(0.1)=%x %x\n", col_int_value, (attr_88.u.num & (NAVIT_AF_ONEWAY|NAVIT_AF_ONEWAYREV)) << 26 );
4727     col_int_value = col_int_value | ((attr_88.u.num & (NAVIT_AF_ONEWAY|NAVIT_AF_ONEWAYREV)) << 26);
4728     }
4729     }
4730     }
4731    
4732    
4733 zoff99 34 // --------======== LABELS ========--------
4734     // --------======== LABELS ========--------
4735     if (label_count > 0)
4736 zoff99 2 {
4737 zoff99 34 labels[0] = map_convert_string(displaylist->m, labels[0]);
4738     }
4739     if (label_count > 1)
4740     {
4741     labels[1] = map_convert_string(displaylist->m, labels[1]);
4742     }
4743     display_add(entry, item, count, ca, labels, label_count, 1, col_int_value);
4744     if (label_count > 0)
4745     {
4746     map_convert_free(labels[0]);
4747     }
4748     if (label_count > 1)
4749     {
4750 zoff99 2 map_convert_free(labels[1]);
4751     }
4752    
4753 zoff99 34 //if (displaylist->conv && label_count)
4754     //{
4755     // labels[0] = map_convert_string(displaylist->m, labels[0]);
4756     // display_add(entry, item, count, ca, labels, label_count, 1, col_int_value);
4757     // map_convert_free(labels[0]);
4758     //}
4759     //else
4760     //{
4761     // display_add(entry, item, count, ca, labels, label_count, 1, col_int_value);
4762     //}
4763     //if (labels[1])
4764     //{
4765     // map_convert_free(labels[1]);
4766     //}
4767     // --------======== LABELS ========--------
4768     // --------======== LABELS ========--------
4769    
4770    
4771 zoff99 28 //workload++;
4772     /*
4773 zoff99 30 if (workload == displaylist->workload)
4774     {
4775     // restore order :-)
4776     displaylist->order = saved;
4777     // reset value;
4778     cancel_drawing_global = 0;
4779 zoff99 28
4780 zoff99 30 // dbg(0,"set:0:displaylist->busy=%d\n",displaylist->busy);
4781     displaylist->busy = 0;
4782 zoff99 28
4783 zoff99 30 // dbg(0,"return 003\n");
4784 zoff99 40 return2;
4785 zoff99 30 }
4786     */
4787 zoff99 31
4788 zoff99 27 } // while item=map_rect_get_item
4789 zoff99 28 // ------ READ all items in this map rectangle ---------
4790     // ------ READ all items in this map rectangle ---------
4791     // ------ READ all items in this map rectangle ---------
4792     // ------ READ all items in this map rectangle ---------
4793     // ------ READ all items in this map rectangle ---------
4794 zoff99 27
4795 zoff99 40 //dbg(0,"MAP:013:map=%s\n", ttt22);
4796 zoff99 28
4797 zoff99 30 ////DBG // dbg(0, "XXXXXYYYYYYY Draw: A.02\n");
4798 zoff99 27
4799 zoff99 34 // ************** map_rect_destroy(displaylist->mr);
4800 zoff99 2 }
4801 zoff99 34
4802     map_rect_destroy(displaylist->mr);
4803 zoff99 2 }
4804    
4805 zoff99 34
4806 zoff99 2 if (!route_selection)
4807     {
4808     map_selection_destroy(displaylist->sel);
4809     }
4810    
4811 zoff99 27 displaylist->mr = NULL;
4812     displaylist->sel = NULL;
4813     displaylist->m = NULL;
4814 zoff99 2 } // while ----
4815    
4816 zoff99 28
4817 zoff99 30 // dbg(0, "DO__DRAW:%d load ready\n", rnd);
4818 zoff99 28
4819     #ifdef NAVIT_MEASURE_TIME_DEBUG
4820     debug_mrp("do_draw:load", debug_measure_end(s_));
4821     #endif
4822     s_ = debug_measure_start();
4823    
4824 zoff99 40
4825    
4826     // dbg(0, "DO__DRAW:%d dummy \"draw-start\" signal\n", rnd);
4827     #ifdef HAVE_API_ANDROID
4828     android_return_generic_int(2, 77);
4829     #endif
4830    
4831 zoff99 29 // remove the "wait" screen
4832 zoff99 30 //#ifdef HAVE_API_ANDROID
4833     // android_return_generic_int(2, 0);
4834     //#endif
4835 zoff99 29
4836 zoff99 30 //DBG // dbg(0, "XXXXXYYYYYYY Draw: 004\n");
4837 zoff99 29
4838 zoff99 27 // reset value;
4839 zoff99 30 // cancel_drawing_global = 0;
4840 zoff99 27
4841 zoff99 2 // restore order :-)
4842 zoff99 27 displaylist->order = saved;
4843 zoff99 2
4844 zoff99 27 // profile(1,"process_selection\n");
4845    
4846 zoff99 30
4847 zoff99 2 if (displaylist->idle_ev)
4848 zoff99 27 {
4849 zoff99 2 event_remove_idle(displaylist->idle_ev);
4850 zoff99 30 displaylist->idle_ev = NULL;
4851 zoff99 27 }
4852 zoff99 29
4853 zoff99 30 if (displaylist->idle_cb)
4854     {
4855     callback_destroy(displaylist->idle_cb);
4856     displaylist->idle_cb = NULL;
4857     }
4858    
4859     //// dbg(0,"set:0:displaylist->busy=%d\n",displaylist->busy);
4860 zoff99 28 //displaylist->busy = 0;
4861 zoff99 2
4862     // graphics_process_selection(displaylist->dc.gra, displaylist);
4863    
4864 zoff99 27 //profile(1, "draw\n");
4865    
4866 zoff99 30 //DBG // dbg(0, "XXXXXYYYYYYY Draw: 005\n");
4867 zoff99 27
4868     if (!cancel)
4869 zoff99 2 {
4870     int flags2 = flags;
4871     if (!(flags2 & 2))
4872     {
4873 zoff99 34 // -- now always clean bg of screen!! 2013-07-08 Zoff
4874     //if (!draw_vector_map)
4875     //{
4876     // // dont clean bg of screen when drawing prerendered tiles
4877     // flags2 = flags2 + 2;
4878     //}
4879 zoff99 2 }
4880 zoff99 30 //DBG // dbg(0,"call graphics_displaylist_draw 3")
4881     //// dbg(0,"# MT:002 #\n");
4882    
4883     // stop drawing is requested
4884     if (cancel_drawing_global != 1)
4885     {
4886     graphics_displaylist_draw(displaylist->dc.gra, displaylist, displaylist->dc.trans, displaylist->layout, flags2);
4887     }
4888     //// dbg(0,"# MT:003 #\n");
4889 zoff99 2 }
4890    
4891 zoff99 28 #ifdef NAVIT_MEASURE_TIME_DEBUG
4892     debug_mrp("do_draw:draw", debug_measure_end(s_));
4893     #endif
4894    
4895 zoff99 30 // dbg(0, "DO__DRAW:%d draw ready\n", rnd);
4896    
4897 zoff99 28 #ifdef HAVE_API_ANDROID
4898     if (cur_mapdraw_time_index < 11)
4899     {
4900     mapdraw_time[cur_mapdraw_time_index] = debug_measure_end_tsecs(s_);
4901 zoff99 30 // // dbg(0,"maptime: %d\n", mapdraw_time[cur_mapdraw_time_index]);
4902 zoff99 28 cur_mapdraw_time_index++;
4903     }
4904    
4905     if (cur_mapdraw_time_index > 10)
4906     {
4907     cur_mapdraw_time_index = 0;
4908     int jk;
4909     int mean_time = 0;
4910     for (jk=0;jk<11;jk++)
4911     {
4912     mean_time = mean_time + mapdraw_time[jk];
4913     }
4914     android_return_generic_int(6, (int)((float)mean_time / (float)10));
4915     }
4916     #endif
4917    
4918 zoff99 30 //// dbg(0,"set:0:displaylist->busy=%d\n",displaylist->busy);
4919 zoff99 28 displaylist->busy = 0;
4920    
4921 zoff99 30 //DBG // dbg(0, "XXXXXYYYYYYY Draw: 006\n");
4922 zoff99 27
4923 zoff99 2 map_rect_destroy(displaylist->mr);
4924     if (!route_selection)
4925 zoff99 28 {
4926 zoff99 2 map_selection_destroy(displaylist->sel);
4927 zoff99 28 }
4928 zoff99 2 mapset_close(displaylist->msh);
4929 zoff99 27 displaylist->mr = NULL;
4930     displaylist->sel = NULL;
4931     displaylist->m = NULL;
4932     displaylist->msh = NULL;
4933 zoff99 28
4934 zoff99 30 //dbg(0, "callback\n");
4935 zoff99 28
4936 zoff99 30 // only some old crap need this!! ----------
4937     // only some old crap need this!! ----------
4938     /// **** callback_call_1(displaylist->cb, cancel);
4939     // only some old crap need this!! ----------
4940     // only some old crap need this!! ----------
4941    
4942    
4943     // dbg(0, "DO__DRAW:%d UN-lock mutex leave\n", rnd);
4944     pthread_mutex_unlock(&uiConditionMutex);
4945     // dbg(0, "DO__DRAW:%d OK UN-lock mutex leave\n", rnd);
4946    
4947     // dbg(0, "DO__DRAW:%d cancel_drawing_global 99=%d\n", rnd, cancel_drawing_global);
4948    
4949     if (cancel_drawing_global != 1)
4950     {
4951     // dummy "ready" signal ------------------------------------------
4952     // dbg(0, "DO__DRAW:%d dummy \"ready\" signal\n", rnd);
4953     // gra->meth.draw_lines4(displaylist->dc.gra, NULL, NULL, NULL, 1, 1, 99);
4954     #ifdef HAVE_API_ANDROID
4955     android_return_generic_int(2, 2);
4956     #endif
4957     // dummy "ready" signal ------------------------------------------
4958     }
4959     else
4960     {
4961     // dummy "cancel" signal ------------------------------------------
4962     // dbg(0, "DO__DRAW:%d dummy \"cancel\" signal\n", rnd);
4963     //gra->meth.draw_lines4(displaylist->dc.gra, NULL, NULL, NULL, 1, 1, 95);
4964     #ifdef HAVE_API_ANDROID
4965     android_return_generic_int(2, 3);
4966     #endif
4967     // dummy "ready" signal ------------------------------------------
4968     }
4969    
4970     // dbg(0, "DO__DRAW:%d leave\n", rnd);
4971     // dbg(0, "DO__DRAW:%d __\n", rnd);
4972    
4973 zoff99 40 __F_END__
4974 zoff99 2 }
4975    
4976     /**
4977     * FIXME
4978     * @param <>
4979     * @returns <>
4980     * @author Martin Schaller (04/2008)
4981 zoff99 27 */
4982 zoff99 2 void graphics_displaylist_draw(struct graphics *gra, struct displaylist *displaylist, struct transformation *trans, struct layout *l, int flags)
4983     {
4984 zoff99 40 __F_START__
4985 zoff99 2
4986 zoff99 30 // // dbg(0,"ooo enter ooo flags=%d\n", flags);
4987 zoff99 28
4988 zoff99 30
4989 zoff99 27 int order = transform_get_order(trans);
4990     displaylist->dc.trans = trans;
4991     displaylist->dc.gra = gra;
4992 zoff99 28
4993     // *********DISABLED*******
4994     // *********DISABLED*******
4995     // *********DISABLED*******
4996 zoff99 31 // set min. distancte of 2 points on line at which a point will be left out when zoomed out too much!!
4997 zoff99 28 // *********DISABLED******* displaylist->dc.mindist = transform_get_scale(trans) / 2;
4998 zoff99 30 //// dbg(0,"mindist would be:%d\n", (int)(transform_get_scale(trans) / 2));
4999 zoff99 28 displaylist->dc.mindist = 0;
5000 zoff99 34 if (order < 6)
5001 zoff99 28 {
5002 zoff99 34 displaylist->dc.mindist = transform_get_scale(trans) * 4;
5003 zoff99 31 }
5004 zoff99 34 else if (order < 9)
5005     {
5006     displaylist->dc.mindist = transform_get_scale(trans) * 3;
5007     }
5008 zoff99 31 else if (order < 13)
5009     {
5010 zoff99 34 displaylist->dc.mindist = transform_get_scale(trans) * 2;
5011 zoff99 28 }
5012     // *********DISABLED*******
5013     // *********DISABLED*******
5014     // *********DISABLED*******
5015    
5016    
5017 zoff99 2 // FIXME find a better place to set the background color
5018     if (l)
5019     {
5020     graphics_gc_set_background(gra->gc[0], &l->color);
5021     graphics_gc_set_foreground(gra->gc[0], &l->color);
5022     gra->default_font = g_strdup(l->font);
5023     }
5024 zoff99 34
5025 zoff99 2 graphics_background_gc(gra, gra->gc[0]);
5026 zoff99 34
5027 zoff99 2 if (flags & 1)
5028     {
5029 zoff99 28 // calls -> navit.c navit_predraw --> draw all vehicles
5030 zoff99 40 // *********++-- DISABLED --++******* // callback_list_call_attr_0(gra->cbl, attr_predraw);
5031     navit_predraw(global_navit);
5032 zoff99 2 }
5033 zoff99 34
5034 zoff99 27 gra->meth.draw_mode(gra->priv, (flags & 8) ? draw_mode_begin_clear : draw_mode_begin);
5035 zoff99 34
5036 zoff99 2 if (!(flags & 2))
5037 zoff99 27 {
5038 zoff99 29 // clear the gfx object pipeline ------------------------------
5039 zoff99 30 // // dbg(0, "clear the gfx object pipeline\n");
5040     // gra->meth.draw_lines4(gra->priv, NULL, NULL, NULL, 1, 1, 98);
5041 zoff99 29
5042 zoff99 2 // clear the display/screen/whatever here
5043 zoff99 30 // dbg(0, "clear the screen: rectangle=%d,%d - %d,%d\n", gra->r.lu.x, gra->r.lu.y, gra->r.rl.x, gra->r.rl.y);
5044 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);
5045     }
5046 zoff99 34
5047 zoff99 2 if (l)
5048     {
5049 zoff99 28 // draw the mapitems
5050 zoff99 30 // // dbg(0,"o , l->d = %d , %d\n",order,l->order_delta);
5051 zoff99 27 xdisplay_draw(displaylist, gra, l, order + l->order_delta);
5052 zoff99 2 }
5053 zoff99 34
5054 zoff99 2 if (flags & 1)
5055     {
5056 zoff99 40 // calls: "graphics_displaylist_draw"
5057     // ***********++-- DISABLED --++*********** // callback_list_call_attr_0(gra->cbl, attr_postdraw);
5058 zoff99 2 }
5059 zoff99 34
5060 zoff99 2 if (!(flags & 4))
5061 zoff99 27 {
5062 zoff99 2 gra->meth.draw_mode(gra->priv, draw_mode_end);
5063 zoff99 27 }
5064    
5065 zoff99 40 __F_END__
5066 zoff99 2 }
5067    
5068     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)
5069     {
5070 zoff99 40 __F_START__
5071 zoff99 30
5072 zoff99 27 int order = transform_get_order(trans);
5073 zoff99 2
5074     if (displaylist->busy)
5075     {
5076     if (async == 1)
5077     {
5078 zoff99 40 return2;
5079 zoff99 2 }
5080 zoff99 40 return2;
5081 zoff99 2 }
5082     xdisplay_free(displaylist);
5083    
5084 zoff99 27 displaylist->dc.gra = gra;
5085     displaylist->ms = mapset;
5086     displaylist->dc.trans = trans;
5087     displaylist->workload = async ? 100 : 0;
5088     displaylist->cb = cb;
5089 zoff99 2 displaylist->seq++;
5090    
5091     if (l)
5092     {
5093 zoff99 27 order += l->order_delta;
5094 zoff99 2 }
5095 zoff99 27 displaylist->order = order;
5096     displaylist->busy = 1;
5097     displaylist->layout = l;
5098 zoff99 2
5099 zoff99 30 // ---------- DISABLED ------ no more async!!
5100     /*
5101     if (async)
5102     {
5103     //DBG // dbg(0,"§§async");
5104     if (!displaylist->idle_cb)
5105     {
5106     //DBG // dbg(0,"§§async --> callback");
5107     displaylist->idle_cb = callback_new_3(callback_cast(do_draw), displaylist, 0, flags);
5108     }
5109     //DBG // dbg(0,"§§async --> add idle");
5110     displaylist->idle_ev = event_add_idle(50, displaylist->idle_cb);
5111     }
5112     else
5113     {
5114     //DBG // dbg(0,"@@sync");
5115     do_draw(displaylist, 0, flags);
5116     }
5117     */
5118 zoff99 28
5119 zoff99 2 if (async)
5120     {
5121 zoff99 40 //if (!displaylist->idle_cb)
5122     //{
5123     // this calls "do_draw"
5124     // *++*-- DISABLED --*++* // displaylist->idle_cb = callback_new_3(callback_cast(do_draw), displaylist, 0, flags);
5125     // *++*-- DISABLED --*++* // callback_add_names(displaylist->idle_cb, "graphics_load_mapset", "do_draw");
5126     do_draw(displaylist, 0, flags);
5127     //}
5128 zoff99 30 //dbg(0, "DO__DRAW:call 003 (async callback)\n");
5129 zoff99 40 // *++*-- DISABLED --*++* // displaylist->idle_ev = event_add_idle(1000, displaylist->idle_cb);
5130 zoff99 28 }
5131     else
5132     {
5133 zoff99 30 //// dbg(0,"**draw 2.b5\n");
5134     // dbg(0, "DO__DRAW:call 001\n");
5135 zoff99 28 do_draw(displaylist, 0, flags);
5136     }
5137 zoff99 30
5138 zoff99 40 __F_END__
5139 zoff99 2 }
5140    
5141     /**
5142     * FIXME
5143     * @param <>
5144     * @returns <>
5145     * @author Martin Schaller (04/2008)
5146 zoff99 27 */
5147 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)
5148     {
5149 zoff99 40 __F_START__
5150 zoff99 30 //// dbg(0,"ooo enter ooo\n");
5151 zoff99 2
5152 zoff99 30 // dbg(0, "DO__DRAW:gras_draw enter\n");
5153 zoff99 2 graphics_load_mapset(gra, displaylist, mapset, trans, l, async, cb, flags);
5154 zoff99 30 // dbg(0, "DO__DRAW:gras_draw leave\n");
5155 zoff99 40 __F_END__
5156 zoff99 2 }
5157    
5158 zoff99 27 int graphics_draw_cancel(struct graphics *gra, struct displaylist *displaylist)
5159 zoff99 2 {
5160 zoff99 40 __F_START__
5161 zoff99 2
5162     if (!displaylist->busy)
5163 zoff99 30 {
5164 zoff99 40 return2 0;
5165 zoff99 30 }
5166     // dbg(0, "DO__DRAW:call 002\n");
5167 zoff99 2 do_draw(displaylist, 1, 0);
5168 zoff99 40 return2 1;
5169    
5170     __F_END__
5171 zoff99 2 }
5172    
5173     /**
5174     * FIXME
5175     * @param <>
5176     * @returns <>
5177     * @author Martin Schaller (04/2008)
5178 zoff99 27 */
5179     struct displaylist_handle
5180     {
5181 zoff99 2 struct displaylist *dl;
5182     struct displayitem *di;
5183     int hashidx;
5184     };
5185    
5186     /**
5187     * FIXME
5188     * @param <>
5189     * @returns <>
5190     * @author Martin Schaller (04/2008)
5191 zoff99 27 */
5192 zoff99 2 struct displaylist_handle * graphics_displaylist_open(struct displaylist *displaylist)
5193     {
5194     struct displaylist_handle *ret;
5195    
5196     ret=g_new0(struct displaylist_handle, 1);
5197 zoff99 27 ret->dl = displaylist;
5198 zoff99 2
5199     return ret;
5200     }
5201    
5202     /**
5203     * FIXME
5204     * @param <>
5205     * @returns <>
5206     * @author Martin Schaller (04/2008)
5207 zoff99 27 */
5208 zoff99 2 struct displayitem * graphics_displaylist_next(struct displaylist_handle *dlh)
5209     {
5210     struct displayitem *ret;
5211     if (!dlh)
5212     return NULL;
5213 zoff99 27 for (;;)
5214     {
5215     if (dlh->di)
5216     {
5217     ret = dlh->di;
5218     dlh->di = ret->next;
5219 zoff99 2 break;
5220     }
5221 zoff99 27 if (dlh->hashidx == HASH_SIZE_GRAPHICS_)
5222     {
5223     ret = NULL;
5224 zoff99 2 break;
5225     }
5226     if (dlh->dl->hash_entries[dlh->hashidx].type)
5227 zoff99 27 dlh->di = dlh->dl->hash_entries[dlh->hashidx].di;
5228 zoff99 2 dlh->hashidx++;
5229     }
5230     return ret;
5231     }
5232    
5233     /**
5234     * FIXME
5235     * @param <>
5236     * @returns <>
5237     * @author Martin Schaller (04/2008)
5238 zoff99 27 */
5239 zoff99 2 void graphics_displaylist_close(struct displaylist_handle *dlh)
5240     {
5241     g_free(dlh);
5242     }
5243    
5244     /**
5245     * FIXME
5246     * @param <>
5247     * @returns <>
5248     * @author Martin Schaller (04/2008)
5249 zoff99 27 */
5250 zoff99 2 struct displaylist * graphics_displaylist_new(void)
5251     {
5252     struct displaylist *ret=g_new0(struct displaylist, 1);
5253    
5254 zoff99 27 ret->dc.maxlen = 16384;
5255 zoff99 28 ret->busy = 0;
5256 zoff99 2
5257     return ret;
5258     }
5259    
5260     /**
5261     * FIXME
5262     * @param <>
5263     * @returns <>
5264     * @author Martin Schaller (04/2008)
5265 zoff99 27 */
5266 zoff99 2 struct item * graphics_displayitem_get_item(struct displayitem *di)
5267     {
5268     return &di->item;
5269     }
5270    
5271 zoff99 27 int graphics_displayitem_get_coord_count(struct displayitem *di)
5272 zoff99 2 {
5273     return di->count;
5274     }
5275    
5276     /**
5277     * FIXME
5278     * @param <>
5279     * @returns <>
5280     * @author Martin Schaller (04/2008)
5281 zoff99 27 */
5282 zoff99 2 char * graphics_displayitem_get_label(struct displayitem *di)
5283     {
5284     return di->label;
5285     }
5286    
5287 zoff99 27 int graphics_displayitem_get_displayed(struct displayitem *di)
5288 zoff99 2 {
5289     return 1;
5290     }
5291    
5292     /**
5293     * FIXME
5294     * @param <>
5295     * @returns <>
5296     * @author Martin Schaller (04/2008)
5297 zoff99 27 */
5298 zoff99 2 static int within_dist_point(struct point *p0, struct point *p1, int dist)
5299     {
5300     if (p0->x == 32767 || p0->y == 32767 || p1->x == 32767 || p1->y == 32767)
5301     return 0;
5302     if (p0->x == -32768 || p0->y == -32768 || p1->x == -32768 || p1->y == -32768)
5303     return 0;
5304 zoff99 27 if ((p0->x - p1->x) * (p0->x - p1->x) + (p0->y - p1->y) * (p0->y - p1->y) <= dist * dist)
5305     {
5306     return 1;
5307     }
5308     return 0;
5309 zoff99 2 }
5310    
5311     /**
5312     * FIXME
5313     * @param <>
5314     * @returns <>
5315     * @author Martin Schaller (04/2008)
5316 zoff99 27 */
5317 zoff99 2 static int within_dist_line(struct point *p, struct point *line_p0, struct point *line_p1, int dist)
5318     {
5319 zoff99 27 int vx, vy, wx, wy;
5320     int c1, c2;
5321 zoff99 2 struct point line_p;
5322    
5323 zoff99 27 if (line_p0->x < line_p1->x)
5324     {
5325 zoff99 2 if (p->x < line_p0->x - dist)
5326     return 0;
5327     if (p->x > line_p1->x + dist)
5328     return 0;
5329 zoff99 27 }
5330     else
5331     {
5332 zoff99 2 if (p->x < line_p1->x - dist)
5333     return 0;
5334     if (p->x > line_p0->x + dist)
5335     return 0;
5336     }
5337 zoff99 27 if (line_p0->y < line_p1->y)
5338     {
5339 zoff99 2 if (p->y < line_p0->y - dist)
5340     return 0;
5341     if (p->y > line_p1->y + dist)
5342     return 0;
5343 zoff99 27 }
5344     else
5345     {
5346 zoff99 2 if (p->y < line_p1->y - dist)
5347     return 0;
5348     if (p->y > line_p0->y + dist)
5349     return 0;
5350     }
5351    
5352 zoff99 27 vx = line_p1->x - line_p0->x;
5353     vy = line_p1->y - line_p0->y;
5354     wx = p->x - line_p0->x;
5355     wy = p->y - line_p0->y;
5356 zoff99 2
5357 zoff99 27 c1 = vx * wx + vy * wy;
5358     if (c1 <= 0)
5359 zoff99 2 return within_dist_point(p, line_p0, dist);
5360 zoff99 27 c2 = vx * vx + vy * vy;
5361     if (c2 <= c1)
5362 zoff99 2 return within_dist_point(p, line_p1, dist);
5363    
5364 zoff99 27 line_p.x = line_p0->x + vx * c1 / c2;
5365     line_p.y = line_p0->y + vy * c1 / c2;
5366 zoff99 2 return within_dist_point(p, &line_p, dist);
5367     }
5368    
5369     /**
5370     * FIXME
5371     * @param <>
5372     * @returns <>
5373     * @author Martin Schaller (04/2008)
5374 zoff99 27 */
5375 zoff99 2 static int within_dist_polyline(struct point *p, struct point *line_pnt, int count, int dist, int close)
5376     {
5377     int i;
5378 zoff99 27 for (i = 0; i < count - 1; i++)
5379     {
5380     if (within_dist_line(p, line_pnt + i, line_pnt + i + 1, dist))
5381     {
5382 zoff99 2 return 1;
5383     }
5384     }
5385     if (close)
5386 zoff99 27 return (within_dist_line(p, line_pnt, line_pnt + count - 1, dist));
5387 zoff99 2 return 0;
5388     }
5389    
5390     /**
5391     * FIXME
5392     * @param <>
5393     * @returns <>
5394     * @author Martin Schaller (04/2008)
5395 zoff99 27 */
5396 zoff99 2 static int within_dist_polygon(struct point *p, struct point *poly_pnt, int count, int dist)
5397     {
5398     int i, j, c = 0;
5399 zoff99 27 for (i = 0, j = count - 1; i < count; j = i++)
5400     {
5401     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))
5402     c = !c;
5403     }
5404     if (!c)
5405 zoff99 2 return within_dist_polyline(p, poly_pnt, count, dist, 1);
5406 zoff99 27 return c;
5407 zoff99 2 }
5408    
5409     /**
5410     * FIXME
5411     * @param <>
5412     * @returns <>
5413     * @author Martin Schaller (04/2008)
5414 zoff99 27 */
5415 zoff99 2 int graphics_displayitem_within_dist(struct displaylist *displaylist, struct displayitem *di, struct point *p, int dist)
5416     {
5417 zoff99 27 struct point *pa = g_alloca(sizeof(struct point) * displaylist->dc.maxlen);
5418 zoff99 2 int count;
5419    
5420 zoff99 27 count = transform(displaylist->dc.trans, displaylist->dc.pro, di->c, pa, di->count, 1, 0, NULL);
5421 zoff99 2
5422 zoff99 27 if (di->item.type < type_line)
5423     {
5424 zoff99 2 return within_dist_point(p, &pa[0], dist);
5425     }
5426 zoff99 27 if (di->item.type < type_area)
5427     {
5428 zoff99 2 return within_dist_polyline(p, pa, count, dist, 0);
5429     }
5430     return within_dist_polygon(p, pa, count, dist);
5431     }
5432    
5433 zoff99 27 static void graphics_process_selection_item(struct displaylist *dl, struct item *item)
5434 zoff99 2 {
5435     #if 0 /* FIXME */
5436     struct displayitem di,*di_res;
5437     GHashTable *h;
5438     int count,max=dl->dc.maxlen;
5439     struct coord ca[max];
5440     struct attr attr;
5441     struct map_rect *mr;
5442    
5443     di.item=*item;
5444     di.label=NULL;
5445     di.count=0;
5446     h=g_hash_table_lookup(dl->dl, GINT_TO_POINTER(di.item.type));
5447 zoff99 27 if (h)
5448     {
5449 zoff99 2 di_res=g_hash_table_lookup(h, &di);
5450 zoff99 27 if (di_res)
5451     {
5452 zoff99 2 di.item.type=(enum item_type)item->priv_data;
5453     display_add(dl, &di.item, di_res->count, di_res->c, NULL, 0);
5454     return;
5455     }
5456     }
5457     mr=map_rect_new(item->map, NULL);
5458     item=map_rect_get_item_byid(mr, item->id_hi, item->id_lo);
5459     count=item_coord_get(item, ca, item->type < type_line ? 1: max);
5460     if (!item_attr_get(item, attr_label, &attr))
5461 zoff99 27 attr.u.str=NULL;
5462     if (dl->conv && attr.u.str && attr.u.str[0])
5463     {
5464 zoff99 2 char *str=map_convert_string(item->map, attr.u.str);
5465     display_add(dl, item, count, ca, &str, 1);
5466     map_convert_free(str);
5467 zoff99 27 }
5468     else
5469     display_add(dl, item, count, ca, &attr.u.str, 1);
5470 zoff99 2 map_rect_destroy(mr);
5471     #endif
5472     }
5473    
5474 zoff99 27 void graphics_add_selection(struct graphics *gra, struct item *item, enum item_type type, struct displaylist *dl)
5475 zoff99 2 {
5476     struct item *item_dup=g_new(struct item, 1);
5477 zoff99 27 *item_dup = *item;
5478     item_dup->priv_data = (void *) type;
5479     gra->selection = g_list_append(gra->selection, item_dup);
5480 zoff99 2 if (dl)
5481     graphics_process_selection_item(dl, item_dup);
5482     }
5483    
5484 zoff99 27 void graphics_remove_selection(struct graphics *gra, struct item *item, enum item_type type, struct displaylist *dl)
5485 zoff99 2 {
5486     GList *curr;
5487     int found;
5488    
5489 zoff99 27 for (;;)
5490     {
5491     curr = gra->selection;
5492     found = 0;
5493     while (curr)
5494     {
5495     struct item *sitem = curr->data;
5496     if (item_is_equal(*item, *sitem))
5497     {
5498     if (dl)
5499     {
5500 zoff99 2 struct displayitem di;
5501     /* Unused Variable
5502 zoff99 27 GHashTable *h; */
5503     di.item = *sitem;
5504     di.label = NULL;
5505     di.count = 0;
5506     di.item.type = type;
5507 zoff99 2 #if 0 /* FIXME */
5508     h=g_hash_table_lookup(dl->dl, GINT_TO_POINTER(di.item.type));
5509     if (h)
5510 zoff99 27 g_hash_table_remove(h, &di);
5511 zoff99 2 #endif
5512     }
5513     g_free(sitem);
5514 zoff99 27 gra->selection = g_list_remove(gra->selection, curr->data);
5515     found = 1;
5516 zoff99 2 break;
5517     }
5518     }
5519     if (!found)
5520     return;
5521     }
5522     }
5523    
5524 zoff99 27 void graphics_clear_selection(struct graphics *gra, struct displaylist *dl)
5525 zoff99 2 {
5526 zoff99 27 while (gra->selection)
5527     {
5528     struct item *item = (struct item *) gra->selection->data;
5529     graphics_remove_selection(gra, item, (enum item_type) item->priv_data, dl);
5530 zoff99 2 }
5531     }
5532    
5533 zoff99 27 static void graphics_process_selection(struct graphics *gra, struct displaylist *dl)
5534 zoff99 2 {
5535     GList *curr;
5536    
5537 zoff99 27 curr = gra->selection;
5538     while (curr)
5539     {
5540     struct item *item = curr->data;
5541 zoff99 2 graphics_process_selection_item(dl, item);
5542 zoff99 27 curr = g_list_next(curr);
5543 zoff99 2 }
5544     }

   
Visit the ZANavi Wiki