90
#define HASH_SIZE 1024
94
struct displayitem *di;
90
98
struct displaylist {
94
101
struct callback *cb;
95
struct layout *layout;
102
struct layout *layout, *layout_hashed;
96
103
struct display_context dc;
104
int order, order_hashed, max_offset;
98
105
struct mapset *ms;
99
106
struct mapset_handle *msh;
116
124
static void graphics_process_selection(struct graphics *gra, struct displaylist *dl);
117
125
static void graphics_gc_init(struct graphics *this_);
128
clear_hash(struct displaylist *dl)
131
for (i = 0 ; i < HASH_SIZE ; i++)
132
dl->hash_entries[i].type=type_none;
135
static struct hash_entry *
136
get_hash_entry(struct displaylist *dl, enum item_type type)
138
int hashidx=(type*2654435761UL) & (HASH_SIZE-1);
139
int offset=dl->max_offset;
141
if (!dl->hash_entries[hashidx].type)
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);
150
static struct hash_entry *
151
set_hash_entry(struct displaylist *dl, enum item_type type)
153
int hashidx=(type*2654435761UL) & (HASH_SIZE-1);
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];
162
if (dl->hash_entries[hashidx].type == type)
163
return &dl->hash_entries[hashidx];
164
hashidx=(hashidx+1)&(HASH_SIZE-1);
120
171
graphics_set_attr_do(struct graphics *gra, struct attr *attr)
289
340
* @author Martin Schaller (04/2008)
291
void * graphics_get_data(struct graphics *this_, char *type)
342
void * graphics_get_data(struct graphics *this_, const char *type)
293
344
return (this_->meth.get_data(this_->priv, type));
755
806
* @author Martin Schaller (04/2008)
757
static int xdisplay_free_list(gpointer key, gpointer value, gpointer user_data)
759
GHashTable *hash=value;
761
g_hash_table_destroy(hash);
769
* @author Martin Schaller (04/2008)
771
static void xdisplay_free(GHashTable *display_list)
773
g_hash_table_foreach_remove(display_list, xdisplay_free_list, NULL);
777
displayitem_hash(gconstpointer key)
779
const struct displayitem *di=key;
780
return (di->item.id_hi^di->item.id_lo^(GPOINTER_TO_INT(di->item.map)));
784
displayitem_equal(gconstpointer a, gconstpointer b)
786
const struct displayitem *dia=a;
787
const struct displayitem *dib=b;
788
if (item_is_equal(dia->item, dib->item))
798
* @author Martin Schaller (04/2008)
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)
811
for (i = 0 ; i < HASH_SIZE ; i++) {
812
struct displayitem *di=dl->hash_entries[i].di;
814
struct displayitem *next=di->next;
818
dl->hash_entries[i].di=NULL;
826
* @author Martin Schaller (04/2008)
828
static void display_add(struct hash_entry *entry, struct item *item, int count, struct coord *c, char **label, int label_count)
802
830
struct displayitem *di;
807
834
len=sizeof(*di)+count*sizeof(*c);
834
860
memcpy(di->c, c, count*sizeof(*c));
836
h=g_hash_table_lookup(displaylist->dl, GINT_TO_POINTER(item->type));
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);
841
g_hash_table_replace(h, di, di);
1592
1613
displayitem_draw(struct displayitem *di, void *dummy, struct display_context *dc)
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;
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);
1684
dbg(0,"failed to load icon '%s'\n", e->u.icon.src);
1704
dbg(0,"failed to load icon '%s'\n", path);
1687
1708
p.x=pa[0].x - img->hot.x;
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));
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);
1733
1756
types=g_list_next(types);
1830
1853
extern void *route_selection;
1856
displaylist_update_hash(struct displaylist *displaylist)
1858
GList *layers=displaylist->layout->layers;
1859
int order=displaylist->order;
1860
displaylist->max_offset=0;
1861
clear_hash(displaylist);
1863
struct layer *layer=layers->data;
1864
GList *itemgras=layer->itemgras;
1866
struct itemgra *itemgra=itemgras->data;
1867
GList *types=itemgra->type;
1868
if (itemgra->order.min <= order && itemgra->order.max >= order) {
1870
enum item_type type=(enum item_type) types->data;
1871
set_hash_entry(displaylist, type);
1872
types=g_list_next(types);
1875
itemgras=g_list_next(itemgras);
1877
layers=g_list_next(layers);
1879
dbg(1,"max offset %d\n",displaylist->max_offset);
1833
1885
do_draw(struct displaylist *displaylist, int cancel, int flags)
1835
1887
struct item *item;
1838
1890
struct attr attr,attr2;
1839
1891
enum projection pro;
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;
1841
1898
profile(0,NULL);
1842
1899
pro=transform_get_projection(displaylist->dc.trans);
1843
1900
while (!cancel) {
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;
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);
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);
1862
1925
count=item_coord_get_within_selection(item, ca, item->type < type_line ? 1: max, displaylist->sel);
1869
1932
displaylist->dc.maxlen=max*2;
1871
1934
if (item_is_custom_poi(*item)) {
1873
1935
if (item_attr_get(item, attr_icon_src, &attr2))
1874
1936
labels[1]=map_convert_string(displaylist->m, attr2.u.str);
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]);
1893
display_add(displaylist, item, count, ca, labels, label_count);
1955
display_add(entry, item, count, ca, labels, label_count);
1895
1957
map_convert_free(labels[1]);
1900
1962
map_rect_destroy(displaylist->mr);
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;
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;
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;
1967
2032
do_draw(displaylist, 1, flags);
1969
xdisplay_free(displaylist->dl);
2034
xdisplay_free(displaylist);
1970
2035
dbg(1,"order=%d\n", order);
1972
2037
displaylist->dc.gra=gra;
2028
2095
struct displaylist_handle *ret;
2030
2097
ret=g_new0(struct displaylist_handle, 1);
2031
if (!displaylist->dl)
2033
ret->hl_head=ret->hl=g_hash_to_list(displaylist->dl);
2038
ret->l_head=ret->l=g_hash_to_list_keys(ret->hl->data);
2098
ret->dl=displaylist;
2051
2111
struct displayitem *ret;
2055
dlh->hl=g_list_next(dlh->hl);
2058
g_list_free(dlh->l_head);
2059
dlh->l_head=dlh->l=g_hash_to_list_keys(dlh->hl->data);
2120
if (dlh->hashidx == HASH_SIZE) {
2124
if (dlh->dl->hash_entries[dlh->hashidx].type)
2125
dlh->di=dlh->dl->hash_entries[dlh->hashidx].di;
2062
dlh->l=g_list_next(dlh->l);
2264
2324
graphics_process_selection_item(struct displaylist *dl, struct item *item)
2266
2327
struct displayitem di,*di_res;
2268
2329
int count,max=dl->dc.maxlen;
2326
2387
di.item=*sitem;
2330
2390
di.item.type=type;
2331
2392
h=g_hash_table_lookup(dl->dl, GINT_TO_POINTER(di.item.type));
2333
2394
g_hash_table_remove(h, &di);
2336
2398
gra->selection=g_list_remove(gra->selection, curr->data);