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

Contents of /navit/navit/graphics.c

Parent Directory Parent Directory | Revision Log Revision Log


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

   
Visit the ZANavi Wiki