src/bmlist.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- VF_BitmapListInit
- VF_BitmapListPut
- VF_BitmapListCompose
- VF_BitmapListFinish
- vf_bitmaplist_init
- vf_bitmaplist_finish
- vf_bitmaplist_put
- vf_bitmaplist_compose
- vf_bitmaplist_compose_accumlate
1 /*
2 * bmlist.c - bitmap list
3 * by Hirotsugu Kakugawa
4 */
5 /*
6 * Copyright (C) 1997-1998 Hirotsugu Kakugawa.
7 * All rights reserved.
8 *
9 * This file is part of the VFlib Library. This library is free
10 * software; you can redistribute it and/or modify it under the terms of
11 * the GNU Library General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your
13 * option) any later version. This library is distributed in the hope
14 * that it will be useful, but WITHOUT ANY WARRANTY; without even the
15 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21 #include <stdio.h>
22 #include <stdlib.h>
23 #ifdef HAVE_UNISTD_H
24 # include <unistd.h>
25 #endif
26 #include <math.h>
27 #include "config.h"
28 #include "VFlib-3_6.h"
29 #include "VFsys.h"
30 #include "bitmap.h"
31 #include "bmlist.h"
32
33
34 Private void vf_bitmaplist_compose_accumlate(VF_BITMAP,VF_BITMAP,int,int);
35
36
37 Public int
38 VF_BitmapListInit(VF_BITMAPLIST bmlist)
/* [<][>][^][v][top][bottom][index][help] */
39 {
40 return vf_bitmaplist_init(bmlist);
41 }
42
43 Public int
44 VF_BitmapListPut(VF_BITMAPLIST bmlist, VF_BITMAP bm, long xoff, long yoff)
/* [<][>][^][v][top][bottom][index][help] */
45 {
46 return vf_bitmaplist_put(bmlist, bm, xoff, yoff);
47 }
48
49 Public VF_BITMAP
50 VF_BitmapListCompose(VF_BITMAPLIST bmlist)
/* [<][>][^][v][top][bottom][index][help] */
51 {
52 return vf_bitmaplist_compose(bmlist);
53 }
54
55 Public int
56 VF_BitmapListFinish(VF_BITMAPLIST bmlist)
/* [<][>][^][v][top][bottom][index][help] */
57 {
58 return vf_bitmaplist_finish(bmlist);
59 }
60
61
62
63 Glocal int
64 vf_bitmaplist_init(VF_BITMAPLIST bmlist)
/* [<][>][^][v][top][bottom][index][help] */
65 {
66 bmlist->next = NULL;
67 return 0;
68 }
69
70 Glocal int
71 vf_bitmaplist_finish(VF_BITMAPLIST bmlist)
/* [<][>][^][v][top][bottom][index][help] */
72 {
73 VF_BITMAPLIST elem, elem_next;
74
75 elem = bmlist->next;
76 while (elem != NULL){
77 elem_next = elem->next;
78 VF_FreeBitmap(elem->bitmap);
79 vf_free(elem);
80 elem = elem_next;
81 }
82
83 bmlist->next = NULL;
84
85 return 0;
86 }
87
88 Glocal int
89 vf_bitmaplist_put(VF_BITMAPLIST bmlist, VF_BITMAP bitmap,
/* [<][>][^][v][top][bottom][index][help] */
90 long off_x, long off_y)
91 {
92 VF_BITMAPLIST elem;
93
94 ALLOC_IF_ERR(elem, struct vf_s_bitmaplist){
95 vf_error = VF_ERR_NO_MEMORY;
96 return -1;
97 }
98 elem->off_x = off_x;
99 elem->off_y = off_y;
100 elem->bitmap = bitmap;
101 elem->next = bmlist->next;
102 bmlist->next = elem;
103
104 return 0;
105 }
106
107 Glocal VF_BITMAP
108 vf_bitmaplist_compose(VF_BITMAPLIST bmlist)
/* [<][>][^][v][top][bottom][index][help] */
109 {
110 VF_BITMAPLIST elem, elem_a, elem_z;
111 VF_BITMAP composed_bm;
112 int bbx_llx, bbx_lly, bbx_urx, bbx_ury;
113 int llx, lly, urx, ury;
114
115 if (bmlist->next == NULL){
116 if ((composed_bm = vf_alloc_bitmap(1, 1)) == NULL)
117 return NULL;
118 composed_bm->off_x = 0;
119 composed_bm->off_y = 0;
120 composed_bm->mv_x = 0;
121 composed_bm->mv_y = 0;
122 return composed_bm;
123 }
124
125 elem_a = bmlist->next;
126 for (elem_z = elem_a; elem_z->next != NULL; elem_z = elem_z->next)
127 ;
128
129 elem = elem_a;
130 bbx_llx = elem->off_x + elem->bitmap->off_x;
131 bbx_lly = elem->off_y + elem->bitmap->off_y - elem->bitmap->bbx_height;
132 bbx_urx = elem->off_x + elem->bitmap->off_x + elem->bitmap->bbx_width;
133 bbx_ury = elem->off_y + elem->bitmap->off_y;
134 for (elem = elem->next; elem != NULL; elem = elem->next){
135 llx = elem->off_x + elem->bitmap->off_x;
136 lly = elem->off_y + elem->bitmap->off_y - elem->bitmap->bbx_height;
137 urx = elem->off_x + elem->bitmap->off_x + elem->bitmap->bbx_width;
138 ury = elem->off_y + elem->bitmap->off_y;
139 if (llx < bbx_llx)
140 bbx_llx = llx;
141 if (lly < bbx_lly)
142 bbx_lly = lly;
143 if (urx > bbx_urx)
144 bbx_urx = urx;
145 if (ury > bbx_ury)
146 bbx_ury = ury;
147 }
148
149 composed_bm = vf_alloc_bitmap(bbx_urx - bbx_llx + 1, bbx_ury - bbx_lly + 1);
150 if (composed_bm == NULL)
151 return NULL;
152
153 composed_bm->off_x = bbx_llx; /* == bbx_ulx */
154 composed_bm->off_y = bbx_ury; /* == bbx_uly */
155 composed_bm->mv_x = elem_a->off_x - elem_z->off_x + elem_a->bitmap->mv_x;
156 composed_bm->mv_y = elem_a->off_y - elem_z->off_y + elem_a->bitmap->mv_y;
157
158 for (elem = bmlist->next; elem != NULL; elem = elem->next){
159 vf_bitmaplist_compose_accumlate(composed_bm, elem->bitmap,
160 elem->off_x, elem->off_y);
161 }
162
163 return composed_bm;
164 }
165
166 Private void
167 vf_bitmaplist_compose_accumlate(VF_BITMAP bm_acc,
/* [<][>][^][v][top][bottom][index][help] */
168 VF_BITMAP bm_put, int off_x, int off_y)
169 {
170 int asx, asy, asxw, asxmr, asxml, pxw, nb;
171 unsigned char *al, *pl;
172 int px, py, ay;
173 unsigned char mask[] = {
174 0xff, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
175
176 asx = bm_put->off_x + off_x - bm_acc->off_x;
177 asy = -(bm_put->off_y + off_y - bm_acc->off_y);
178 asxw = asx / 8;
179 asxmr = asx % 8;
180 asxml = 8 - asxmr;
181 pxw = (bm_put->bbx_width+7)/8;
182
183 if (asxmr == 0){
184 for (py = 0, ay = asy; py < bm_put->bbx_height; py++, ay++){
185 al = &bm_acc->bitmap[bm_acc->raster*ay + asxw];
186 pl = &bm_put->bitmap[bm_put->raster*py];
187 for (px = pxw; px > 0; --px)
188 *(al++) |= *(pl++);
189 }
190 } else {
191 nb = (asx + bm_put->bbx_width + 7)/8 - (asx/8);
192 for (py = 0, ay = asy; py < bm_put->bbx_height; py++, ay++){
193 al = &bm_acc->bitmap[bm_acc->raster*ay + asxw];
194 pl = &bm_put->bitmap[bm_put->raster*py];
195 for (px = nb; px > 1; --px){
196 *(al+1) |= (*pl << asxml);
197 *(al++) |= (*(pl++) >> asxmr);
198 }
199 *al |= ((*pl >> asxmr) & mask[(asx + bm_put->bbx_width) % 8]);
200 }
201 }
202 }
203
204 /*EOF*/