~ubuntu-branches/ubuntu/precise/navit/precise

« back to all changes in this revision

Viewing changes to navit/graphics.c

  • Committer: Bazaar Package Importer
  • Author(s): Gilles Filippini
  • Date: 2010-07-27 22:36:40 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20100727223640-jlgmnnwtx2siv1pr
Tags: 0.2.0~svn3501+dfsg.1-1
* New upstream snapshot:
  + Support for autoloaded plugins
  + Many memory leaks fixed
* Refresh patches

* New patch path_max to try fixing the FTBFS on hurd-i386. 

* debian/control: bumped Standards-Version to 3.9.1 (no change needed)

Show diffs side-by-side

added added

removed removed

Lines of Context:
87
87
        int maxlen;
88
88
};
89
89
 
 
90
#define HASH_SIZE 1024
 
91
struct hash_entry
 
92
{
 
93
        enum item_type type;
 
94
        struct displayitem *di;
 
95
};
 
96
 
 
97
 
90
98
struct displaylist {
91
 
        GHashTable *dl;
92
99
        int busy;
93
100
        int workload;
94
101
        struct callback *cb;
95
 
        struct layout *layout;
 
102
        struct layout *layout, *layout_hashed;
96
103
        struct display_context dc;
97
 
        int order;
 
104
        int order, order_hashed, max_offset;
98
105
        struct mapset *ms;
99
106
        struct mapset_handle *msh;
100
107
        struct map *m;
104
111
        struct callback *idle_cb;
105
112
        struct event_idle *idle_ev;
106
113
        unsigned int seq;
 
114
        struct hash_entry hash_entries[HASH_SIZE];
107
115
};
108
116
 
109
117
 
116
124
static void graphics_process_selection(struct graphics *gra, struct displaylist *dl);
117
125
static void graphics_gc_init(struct graphics *this_);
118
126
 
 
127
static void
 
128
clear_hash(struct displaylist *dl)
 
129
{
 
130
        int i;
 
131
        for (i = 0 ; i < HASH_SIZE ; i++)
 
132
                dl->hash_entries[i].type=type_none;
 
133
}
 
134
 
 
135
static struct hash_entry *
 
136
get_hash_entry(struct displaylist *dl, enum item_type type)
 
137
{
 
138
        int hashidx=(type*2654435761UL) & (HASH_SIZE-1);
 
139
        int offset=dl->max_offset;
 
140
        do {
 
141
                if (!dl->hash_entries[hashidx].type)
 
142
                        return NULL;
 
143
                if (dl->hash_entries[hashidx].type == type)
 
144
                        return &dl->hash_entries[hashidx];
 
145
                hashidx=(hashidx+1)&(HASH_SIZE-1);
 
146
        } while (offset-- > 0);
 
147
        return NULL;
 
148
}
 
149
 
 
150
static struct hash_entry *
 
151
set_hash_entry(struct displaylist *dl, enum item_type type)
 
152
{
 
153
        int hashidx=(type*2654435761UL) & (HASH_SIZE-1);
 
154
        int offset=0;
 
155
        for (;;) {
 
156
                if (!dl->hash_entries[hashidx].type) {
 
157
                        dl->hash_entries[hashidx].type=type;
 
158
                        if (dl->max_offset < offset)
 
159
                                dl->max_offset=offset;
 
160
                        return &dl->hash_entries[hashidx];
 
161
                }
 
162
                if (dl->hash_entries[hashidx].type == type)
 
163
                        return &dl->hash_entries[hashidx];
 
164
                hashidx=(hashidx+1)&(HASH_SIZE-1);
 
165
                offset++;
 
166
        }
 
167
        return NULL;
 
168
}
 
169
 
119
170
static int
120
171
graphics_set_attr_do(struct graphics *gra, struct attr *attr)
121
172
{
288
339
 * @returns <>
289
340
 * @author Martin Schaller (04/2008)
290
341
*/
291
 
void * graphics_get_data(struct graphics *this_, char *type)
 
342
void * graphics_get_data(struct graphics *this_, const char *type)
292
343
{
293
344
        return (this_->meth.get_data(this_->priv, type));
294
345
}
741
792
 * @author Martin Schaller (04/2008)
742
793
*/
743
794
struct displayitem {
 
795
        struct displayitem *next;
744
796
        struct item item;
745
797
        char *label;
746
 
        int displayed;
747
798
        int count;
748
799
        struct coord c[0];
749
800
};
754
805
 * @returns <>
755
806
 * @author Martin Schaller (04/2008)
756
807
*/
757
 
static int xdisplay_free_list(gpointer key, gpointer value, gpointer user_data)
758
 
{
759
 
        GHashTable *hash=value;
760
 
        if (hash) 
761
 
                g_hash_table_destroy(hash);
762
 
        return TRUE;
763
 
}
764
 
 
765
 
/**
766
 
 * FIXME
767
 
 * @param <>
768
 
 * @returns <>
769
 
 * @author Martin Schaller (04/2008)
770
 
*/
771
 
static void xdisplay_free(GHashTable *display_list)
772
 
{
773
 
        g_hash_table_foreach_remove(display_list, xdisplay_free_list, NULL);
774
 
}
775
 
 
776
 
static guint
777
 
displayitem_hash(gconstpointer key)
778
 
{
779
 
        const struct displayitem *di=key;
780
 
        return (di->item.id_hi^di->item.id_lo^(GPOINTER_TO_INT(di->item.map)));
781
 
}
782
 
 
783
 
static gboolean
784
 
displayitem_equal(gconstpointer a, gconstpointer b)
785
 
{
786
 
        const struct displayitem *dia=a;
787
 
        const struct displayitem *dib=b;
788
 
        if (item_is_equal(dia->item, dib->item))
789
 
                return TRUE;
790
 
        return FALSE;
791
 
}
792
 
 
793
 
 
794
 
/**
795
 
 * FIXME
796
 
 * @param <>
797
 
 * @returns <>
798
 
 * @author Martin Schaller (04/2008)
799
 
*/
800
 
static void display_add(struct displaylist *displaylist, struct item *item, int count, struct coord *c, char **label, int label_count)
 
808
static void xdisplay_free(struct displaylist *dl)
 
809
{
 
810
        int i;
 
811
        for (i = 0 ; i < HASH_SIZE ; i++) {
 
812
                struct displayitem *di=dl->hash_entries[i].di;
 
813
                while (di) {
 
814
                        struct displayitem *next=di->next;
 
815
                        g_free(di);
 
816
                        di=next;
 
817
                }
 
818
                dl->hash_entries[i].di=NULL;
 
819
        }
 
820
}
 
821
 
 
822
/**
 
823
 * FIXME
 
824
 * @param <>
 
825
 * @returns <>
 
826
 * @author Martin Schaller (04/2008)
 
827
*/
 
828
static void display_add(struct hash_entry *entry, struct item *item, int count, struct coord *c, char **label, int label_count)
801
829
{
802
830
        struct displayitem *di;
803
831
        int len,i;
804
 
        GHashTable *h;
805
832
        char *p;
806
833
 
807
834
        len=sizeof(*di)+count*sizeof(*c);
816
843
        p=g_malloc(len);
817
844
 
818
845
        di=(struct displayitem *)p;
819
 
        di->displayed=0;
820
846
        p+=sizeof(*di)+count*sizeof(*c);
821
847
        di->item=*item;
822
848
        if (label && label_count) {
832
858
                di->label=NULL;
833
859
        di->count=count;
834
860
        memcpy(di->c, c, count*sizeof(*c));
835
 
 
836
 
        h=g_hash_table_lookup(displaylist->dl, GINT_TO_POINTER(item->type));
837
 
        if (! h) {
838
 
                h=g_hash_table_new_full(displayitem_hash, displayitem_equal, g_free, NULL);
839
 
                g_hash_table_insert(displaylist->dl, GINT_TO_POINTER(item->type), h);
840
 
        }
841
 
        g_hash_table_replace(h, di, di);
 
861
        di->next=entry->di;
 
862
        entry->di=di;
842
863
}
843
864
 
844
865
 
1592
1613
displayitem_draw(struct displayitem *di, void *dummy, struct display_context *dc)
1593
1614
{
1594
1615
        int width[dc->maxlen];
1595
 
        int i,count=di->count,mindist=dc->mindist;
1596
1616
        struct point pa[dc->maxlen];
1597
1617
        struct graphics *gra=dc->gra;
1598
1618
        struct graphics_gc *gc=dc->gc;
1601
1621
        struct point p;
1602
1622
        char *path;
1603
1623
 
1604
 
        di->displayed=1;
 
1624
        while (di) {
 
1625
        int i,count=di->count,mindist=dc->mindist;
 
1626
 
1605
1627
        if (! gc) {
1606
1628
                gc=graphics_gc_new(gra);
1607
1629
                graphics_gc_set_foreground(gc, &e->color);
1665
1687
                                if (item_is_custom_poi(di->item)) {
1666
1688
                                        char *icon;
1667
1689
                                        char *src;
1668
 
                                        dbg(0,"custom\n");
1669
1690
                                        if (img)
1670
1691
                                                graphics_image_free(dc->gra, img);
1671
1692
                                        src=e->u.icon.src;
1677
1698
                                } else
1678
1699
                                        path=graphics_icon_path(e->u.icon.src); 
1679
1700
                                img=graphics_image_new_scaled_rotated(gra, path, e->u.icon.width, e->u.icon.height, e->u.icon.rotation);
1680
 
                                g_free(path);
1681
1701
                                if (img)
1682
1702
                                        dc->img=img;
1683
1703
                                else
1684
 
                                        dbg(0,"failed to load icon '%s'\n", e->u.icon.src);
 
1704
                                        dbg(0,"failed to load icon '%s'\n", path);
 
1705
                                g_free(path);
1685
1706
                        }
1686
1707
                        if (img) {
1687
1708
                                p.x=pa[0].x - img->hot.x;
1704
1725
                printf("Unhandled element type %d\n", e->type);
1705
1726
        
1706
1727
        }
 
1728
        di=di->next;
 
1729
        }
1707
1730
}
1708
1731
/**
1709
1732
 * FIXME
1715
1738
{
1716
1739
        struct element *e;
1717
1740
        GList *es,*types;
1718
 
        GHashTable *h;
1719
1741
        struct display_context *dc=&display_list->dc;
 
1742
        struct hash_entry *entry;
1720
1743
 
1721
1744
        es=itm->elements;
1722
1745
        while (es) {
1725
1748
                types=itm->type;
1726
1749
                while (types) {
1727
1750
                        dc->type=GPOINTER_TO_INT(types->data);
1728
 
                        h=g_hash_table_lookup(display_list->dl, GINT_TO_POINTER(dc->type));
1729
 
                        if (h) {
1730
 
                                g_hash_table_foreach(h, (GHFunc)displayitem_draw, dc);
 
1751
                        entry=get_hash_entry(display_list, dc->type);
 
1752
                        if (entry && entry->di) {
 
1753
                                displayitem_draw(entry->di, NULL, dc);
1731
1754
                                display_context_free(dc);
1732
1755
                        }
1733
1756
                        types=g_list_next(types);
1750
1773
        di->item.id_lo=0;
1751
1774
        di->item.map=NULL;
1752
1775
        di->label=NULL;
1753
 
        di->displayed=0;
1754
1776
        dc.gra=gra;
1755
1777
        dc.gc=NULL;
1756
1778
        dc.img=NULL;
1774
1796
                        di->count=1;
1775
1797
                }
1776
1798
                dc.e=e;
 
1799
                di->next=NULL;
1777
1800
                displayitem_draw(di, NULL, &dc);
1778
1801
                display_context_free(&dc);
1779
1802
                es=g_list_next(es);
1830
1853
extern void *route_selection;
1831
1854
 
1832
1855
static void
 
1856
displaylist_update_hash(struct displaylist *displaylist)
 
1857
{
 
1858
        GList *layers=displaylist->layout->layers;
 
1859
        int order=displaylist->order;
 
1860
        displaylist->max_offset=0;
 
1861
        clear_hash(displaylist);
 
1862
        while (layers) {
 
1863
                struct layer *layer=layers->data;
 
1864
                GList *itemgras=layer->itemgras;
 
1865
                while (itemgras) {
 
1866
                        struct itemgra *itemgra=itemgras->data;
 
1867
                        GList *types=itemgra->type;
 
1868
                        if (itemgra->order.min <= order && itemgra->order.max >= order) {
 
1869
                                while (types) {
 
1870
                                        enum item_type type=(enum item_type) types->data;
 
1871
                                        set_hash_entry(displaylist, type);
 
1872
                                        types=g_list_next(types);
 
1873
                                }
 
1874
                        }
 
1875
                        itemgras=g_list_next(itemgras);
 
1876
                }
 
1877
                layers=g_list_next(layers);
 
1878
        }
 
1879
        dbg(1,"max offset %d\n",displaylist->max_offset);
 
1880
}
 
1881
 
 
1882
 
 
1883
 
 
1884
static void
1833
1885
do_draw(struct displaylist *displaylist, int cancel, int flags)
1834
1886
{
1835
1887
        struct item *item;
1838
1890
        struct attr attr,attr2;
1839
1891
        enum projection pro;
1840
1892
 
 
1893
        if (displaylist->order != displaylist->order_hashed || displaylist->layout != displaylist->layout_hashed) {
 
1894
                displaylist_update_hash(displaylist);
 
1895
                displaylist->order_hashed=displaylist->order;
 
1896
                displaylist->layout_hashed=displaylist->layout;
 
1897
        }
1841
1898
        profile(0,NULL);
1842
1899
        pro=transform_get_projection(displaylist->dc.trans);
1843
1900
        while (!cancel) {
1852
1909
                        }
1853
1910
                        displaylist->dc.pro=map_projection(displaylist->m);
1854
1911
                        displaylist->conv=map_requires_conversion(displaylist->m);
1855
 
                        displaylist->sel=transform_get_selection(displaylist->dc.trans, displaylist->dc.pro, displaylist->order);
 
1912
                        if (route_selection)
 
1913
                                displaylist->sel=route_selection;
 
1914
                        else
 
1915
                                displaylist->sel=transform_get_selection(displaylist->dc.trans, displaylist->dc.pro, displaylist->order);
1856
1916
                        displaylist->mr=map_rect_new(displaylist->m, displaylist->sel);
1857
1917
                }
1858
1918
                if (displaylist->mr) {
1859
1919
                        while ((item=map_rect_get_item(displaylist->mr))) {
1860
1920
                                int label_count=0;
1861
1921
                                char *labels[2];
 
1922
                                struct hash_entry *entry=get_hash_entry(displaylist, item->type);
 
1923
                                if (!entry) 
 
1924
                                        continue;
1862
1925
                                count=item_coord_get_within_selection(item, ca, item->type < type_line ? 1: max, displaylist->sel);
1863
1926
                                if (! count)
1864
1927
                                        continue;
1869
1932
                                        displaylist->dc.maxlen=max*2;
1870
1933
                                }
1871
1934
                                if (item_is_custom_poi(*item)) {
1872
 
                                        dbg(0,"custom\n");
1873
1935
                                        if (item_attr_get(item, attr_icon_src, &attr2))
1874
1936
                                                labels[1]=map_convert_string(displaylist->m, attr2.u.str);
1875
1937
                                        else
1887
1949
                                        labels[0]=NULL;
1888
1950
                                if (displaylist->conv && label_count) {
1889
1951
                                        labels[0]=map_convert_string(displaylist->m, labels[0]);
1890
 
                                        display_add(displaylist, item, count, ca, labels, label_count);
 
1952
                                        display_add(entry, item, count, ca, labels, label_count);
1891
1953
                                        map_convert_free(labels[0]);
1892
1954
                                } else
1893
 
                                        display_add(displaylist, item, count, ca, labels, label_count);
 
1955
                                        display_add(entry, item, count, ca, labels, label_count);
1894
1956
                                if (labels[1])
1895
1957
                                        map_convert_free(labels[1]);
1896
1958
                                workload++;
1899
1961
                        }
1900
1962
                        map_rect_destroy(displaylist->mr);
1901
1963
                }
1902
 
                map_selection_destroy(displaylist->sel);
 
1964
                if (!route_selection)
 
1965
                        map_selection_destroy(displaylist->sel);
1903
1966
                displaylist->mr=NULL;
1904
1967
                displaylist->sel=NULL;
1905
1968
                displaylist->m=NULL;
1906
1969
        }
1907
1970
        profile(1,"process_selection\n");
1908
 
        event_remove_idle(displaylist->idle_ev);
 
1971
        if (displaylist->idle_ev)
 
1972
                event_remove_idle(displaylist->idle_ev);
1909
1973
        displaylist->idle_ev=NULL;
1910
1974
        callback_destroy(displaylist->idle_cb);
1911
1975
        displaylist->idle_cb=NULL;
1915
1979
        if (! cancel) 
1916
1980
                graphics_displaylist_draw(displaylist->dc.gra, displaylist, displaylist->dc.trans, displaylist->layout, flags);
1917
1981
        map_rect_destroy(displaylist->mr);
1918
 
        map_selection_destroy(displaylist->sel);
 
1982
        if (!route_selection)
 
1983
                map_selection_destroy(displaylist->sel);
1919
1984
        mapset_close(displaylist->msh);
1920
1985
        displaylist->mr=NULL;
1921
1986
        displaylist->sel=NULL;
1966
2031
                        return;
1967
2032
                do_draw(displaylist, 1, flags);
1968
2033
        }
1969
 
        xdisplay_free(displaylist->dl);
 
2034
        xdisplay_free(displaylist);
1970
2035
        dbg(1,"order=%d\n", order);
1971
2036
 
1972
2037
        displaylist->dc.gra=gra;
2014
2079
 * @author Martin Schaller (04/2008)
2015
2080
*/
2016
2081
struct displaylist_handle {
2017
 
        GList *hl_head,*hl,*l_head,*l;
 
2082
        struct displaylist *dl;
 
2083
        struct displayitem *di;
 
2084
        int hashidx;
2018
2085
};
2019
2086
 
2020
2087
/**
2028
2095
        struct displaylist_handle *ret;
2029
2096
 
2030
2097
        ret=g_new0(struct displaylist_handle, 1);
2031
 
        if (!displaylist->dl)
2032
 
                return NULL;
2033
 
        ret->hl_head=ret->hl=g_hash_to_list(displaylist->dl);
2034
 
        if (!ret->hl) {
2035
 
                g_free(ret);
2036
 
                return NULL;
2037
 
        }
2038
 
        ret->l_head=ret->l=g_hash_to_list_keys(ret->hl->data);
 
2098
        ret->dl=displaylist;
2039
2099
 
2040
2100
        return ret;
2041
2101
}
2051
2111
        struct displayitem *ret;
2052
2112
        if (!dlh)
2053
2113
                return NULL;
2054
 
        if (! dlh->l) {
2055
 
                dlh->hl=g_list_next(dlh->hl);
2056
 
                if (!dlh->hl)
2057
 
                        return NULL;
2058
 
                g_list_free(dlh->l_head);
2059
 
                dlh->l_head=dlh->l=g_hash_to_list_keys(dlh->hl->data);
 
2114
        for (;;) {
 
2115
                if (dlh->di) {
 
2116
                        ret=dlh->di;
 
2117
                        dlh->di=ret->next;
 
2118
                        break;
 
2119
                }
 
2120
                if (dlh->hashidx == HASH_SIZE) {
 
2121
                        ret=NULL;
 
2122
                        break;
 
2123
                }
 
2124
                if (dlh->dl->hash_entries[dlh->hashidx].type)
 
2125
                        dlh->di=dlh->dl->hash_entries[dlh->hashidx].di;
 
2126
                dlh->hashidx++;
2060
2127
        }
2061
 
        ret=dlh->l->data;
2062
 
        dlh->l=g_list_next(dlh->l);
2063
2128
        return ret;
2064
2129
}
2065
2130
 
2071
2136
*/
2072
2137
void graphics_displaylist_close(struct displaylist_handle *dlh)
2073
2138
{
2074
 
        if (dlh) {
2075
 
                g_list_free(dlh->hl_head);
2076
 
                g_list_free(dlh->l_head);
2077
 
                g_free(dlh);
2078
 
        }
 
2139
        g_free(dlh);
2079
2140
}
2080
2141
 
2081
2142
/**
2088
2149
{
2089
2150
        struct displaylist *ret=g_new0(struct displaylist, 1);
2090
2151
 
2091
 
        ret->dl=g_hash_table_new(NULL,NULL);
2092
2152
        ret->dc.maxlen=16384;
2093
2153
 
2094
2154
        return ret;
2125
2185
int
2126
2186
graphics_displayitem_get_displayed(struct displayitem *di)
2127
2187
{
2128
 
        return di->displayed;
 
2188
        return 1;       
2129
2189
}
2130
2190
 
2131
2191
/**
2263
2323
static void
2264
2324
graphics_process_selection_item(struct displaylist *dl, struct item *item)
2265
2325
{
 
2326
#if 0 /* FIXME */
2266
2327
        struct displayitem di,*di_res;
2267
2328
        GHashTable *h;
2268
2329
        int count,max=dl->dc.maxlen;
2272
2333
 
2273
2334
        di.item=*item;
2274
2335
        di.label=NULL;
2275
 
        di.displayed=0;
2276
2336
        di.count=0;
2277
2337
        h=g_hash_table_lookup(dl->dl, GINT_TO_POINTER(di.item.type));
2278
2338
        if (h) {
2295
2355
        } else
2296
2356
                display_add(dl, item, count, ca, &attr.u.str, 1);
2297
2357
        map_rect_destroy(mr);
 
2358
#endif
2298
2359
}
2299
2360
 
2300
2361
void
2325
2386
                                        GHashTable *h;
2326
2387
                                        di.item=*sitem;
2327
2388
                                        di.label=NULL;
2328
 
                                        di.displayed=0;
2329
2389
                                        di.count=0;
2330
2390
                                        di.item.type=type;
 
2391
#if 0 /* FIXME */
2331
2392
                                        h=g_hash_table_lookup(dl->dl, GINT_TO_POINTER(di.item.type));
2332
2393
                                        if (h)
2333
2394
                                                g_hash_table_remove(h, &di);
 
2395
#endif
2334
2396
                                }
2335
2397
                                g_free(sitem);
2336
2398
                                gra->selection=g_list_remove(gra->selection, curr->data);