diff options
author | Aidan MacDonald <amachronic@protonmail.com> | 2022-09-26 08:37:00 +0100 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2022-10-09 22:07:44 +0100 |
commit | 4b8fe8acd1c079e75bb9229791170c549188fc08 (patch) | |
tree | e3f3a8ab80a6a603488781a933bb16ba90e8a68e | |
parent | 70d5b2cd45b29e64ab17b04d995dce1080d7fca9 (diff) | |
download | rockbox-4b8fe8acd1c079e75bb9229791170c549188fc08.tar.gz rockbox-4b8fe8acd1c079e75bb9229791170c549188fc08.zip |
lcd: Consolidate in-viewport clipping routines
In-viewport clipping code is duplicated across 8 files, making
it a chore to change anything related to clipping; refactor the
clipping logic into dedicated functions.
Change-Id: I4ab20bb3c59b0406098d0c7d23833025f17a320a
-rw-r--r-- | firmware/drivers/lcd-16bit-common.c | 78 | ||||
-rw-r--r-- | firmware/drivers/lcd-16bit-vert.c | 110 | ||||
-rw-r--r-- | firmware/drivers/lcd-16bit.c | 107 | ||||
-rw-r--r-- | firmware/drivers/lcd-1bit-vert.c | 121 | ||||
-rw-r--r-- | firmware/drivers/lcd-24bit.c | 186 | ||||
-rw-r--r-- | firmware/drivers/lcd-2bit-horz.c | 144 | ||||
-rw-r--r-- | firmware/drivers/lcd-2bit-vert.c | 145 | ||||
-rw-r--r-- | firmware/drivers/lcd-2bit-vi.c | 145 | ||||
-rw-r--r-- | firmware/drivers/lcd-bitmap-common.c | 110 | ||||
-rw-r--r-- | firmware/drivers/lcd-color-common.c | 16 |
10 files changed, 214 insertions, 948 deletions
diff --git a/firmware/drivers/lcd-16bit-common.c b/firmware/drivers/lcd-16bit-common.c index 523354d5d2..ad41485dfe 100644 --- a/firmware/drivers/lcd-16bit-common.c +++ b/firmware/drivers/lcd-16bit-common.c | |||
@@ -133,31 +133,9 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
133 | fb_data *dst, *dst_end; | 133 | fb_data *dst, *dst_end; |
134 | int len, step; | 134 | int len, step; |
135 | 135 | ||
136 | /******************** In viewport clipping **********************/ | 136 | if (!lcd_clip_viewport_rect(&x, &y, &width, &height, NULL, NULL)) |
137 | /* nothing to draw? */ | ||
138 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || | ||
139 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) | ||
140 | return; | 137 | return; |
141 | 138 | ||
142 | if (x < 0) | ||
143 | { | ||
144 | width += x; | ||
145 | x = 0; | ||
146 | } | ||
147 | if (y < 0) | ||
148 | { | ||
149 | height += y; | ||
150 | y = 0; | ||
151 | } | ||
152 | if (x + width > lcd_current_viewport->width) | ||
153 | width = lcd_current_viewport->width - x; | ||
154 | if (y + height > lcd_current_viewport->height) | ||
155 | height = lcd_current_viewport->height - y; | ||
156 | |||
157 | /* adjust for viewport */ | ||
158 | x += lcd_current_viewport->x; | ||
159 | y += lcd_current_viewport->y; | ||
160 | |||
161 | /* drawmode and optimisation */ | 139 | /* drawmode and optimisation */ |
162 | if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID) | 140 | if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID) |
163 | { | 141 | { |
@@ -235,33 +213,9 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
235 | int src_y, int stride, int x, int y, | 213 | int src_y, int stride, int x, int y, |
236 | int width, int height) | 214 | int width, int height) |
237 | { | 215 | { |
238 | /******************** Image in viewport clipping **********************/ | 216 | if (!lcd_clip_viewport_rect(&x, &y, &width, &height, &src_x, &src_y)) |
239 | /* nothing to draw? */ | ||
240 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || | ||
241 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) | ||
242 | return; | 217 | return; |
243 | 218 | ||
244 | if (x < 0) | ||
245 | { | ||
246 | width += x; | ||
247 | src_x -= x; | ||
248 | x = 0; | ||
249 | } | ||
250 | if (y < 0) | ||
251 | { | ||
252 | height += y; | ||
253 | src_y -= y; | ||
254 | y = 0; | ||
255 | } | ||
256 | if (x + width > lcd_current_viewport->width) | ||
257 | width = lcd_current_viewport->width - x; | ||
258 | if (y + height > lcd_current_viewport->height) | ||
259 | height = lcd_current_viewport->height - y; | ||
260 | |||
261 | /* convert to viewport coordinates */ | ||
262 | x += lcd_current_viewport->x; | ||
263 | y += lcd_current_viewport->y; | ||
264 | |||
265 | /* move starting point */ | 219 | /* move starting point */ |
266 | src += stride * (src_y >> 3) + src_x; | 220 | src += stride * (src_y >> 3) + src_x; |
267 | src_y &= 7; | 221 | src_y &= 7; |
@@ -465,35 +419,13 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
465 | fb_data *dst, *dst_row; | 419 | fb_data *dst, *dst_row; |
466 | unsigned dmask = 0x00000000; | 420 | unsigned dmask = 0x00000000; |
467 | int drmode = lcd_current_viewport->drawmode; | 421 | int drmode = lcd_current_viewport->drawmode; |
468 | /* nothing to draw? */ | 422 | |
469 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || | 423 | if (!lcd_clip_viewport_rect(&x, &y, &width, &height, &src_x, &src_y)) |
470 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) | ||
471 | return; | 424 | return; |
425 | |||
472 | /* initialize blending */ | 426 | /* initialize blending */ |
473 | BLEND_INIT; | 427 | BLEND_INIT; |
474 | 428 | ||
475 | /* clipping */ | ||
476 | if (x < 0) | ||
477 | { | ||
478 | width += x; | ||
479 | src_x -= x; | ||
480 | x = 0; | ||
481 | } | ||
482 | if (y < 0) | ||
483 | { | ||
484 | height += y; | ||
485 | src_y -= y; | ||
486 | y = 0; | ||
487 | } | ||
488 | if (x + width > lcd_current_viewport->width) | ||
489 | width = lcd_current_viewport->width - x; | ||
490 | if (y + height > lcd_current_viewport->height) | ||
491 | height = lcd_current_viewport->height - y; | ||
492 | |||
493 | /* adjust for viewport */ | ||
494 | x += lcd_current_viewport->x; | ||
495 | y += lcd_current_viewport->y; | ||
496 | |||
497 | /* the following drawmode combinations are possible: | 429 | /* the following drawmode combinations are possible: |
498 | * 1) COMPLEMENT: just negates the framebuffer contents | 430 | * 1) COMPLEMENT: just negates the framebuffer contents |
499 | * 2) BG and BG+backdrop: draws _only_ background pixels with either | 431 | * 2) BG and BG+backdrop: draws _only_ background pixels with either |
diff --git a/firmware/drivers/lcd-16bit-vert.c b/firmware/drivers/lcd-16bit-vert.c index 166af02791..c721ef6302 100644 --- a/firmware/drivers/lcd-16bit-vert.c +++ b/firmware/drivers/lcd-16bit-vert.c | |||
@@ -54,46 +54,23 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
54 | int stride_image, int stride_src); | 54 | int stride_image, int stride_src); |
55 | 55 | ||
56 | #include "lcd-color-common.c" | 56 | #include "lcd-color-common.c" |
57 | #include "lcd-16bit-common.c" | ||
58 | #include "lcd-bitmap-common.c" | 57 | #include "lcd-bitmap-common.c" |
58 | #include "lcd-16bit-common.c" | ||
59 | 59 | ||
60 | /*** drawing functions ***/ | 60 | /*** drawing functions ***/ |
61 | 61 | ||
62 | /* Draw a horizontal line (optimised) */ | 62 | /* Draw a horizontal line (optimised) */ |
63 | void lcd_hline(int x1, int x2, int y) | 63 | void lcd_hline(int x1, int x2, int y) |
64 | { | 64 | { |
65 | int x; | ||
66 | fb_data *dst, *dst_end; | 65 | fb_data *dst, *dst_end; |
67 | int stride_dst; | 66 | int stride_dst; |
68 | 67 | ||
69 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[lcd_current_viewport->drawmode]; | 68 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[lcd_current_viewport->drawmode]; |
70 | 69 | ||
71 | /* direction flip */ | 70 | if (!lcd_clip_viewport_hline(&x1, &x2, &y)) |
72 | if (x2 < x1) | ||
73 | { | ||
74 | x = x1; | ||
75 | x1 = x2; | ||
76 | x2 = x; | ||
77 | } | ||
78 | |||
79 | /******************** In viewport clipping **********************/ | ||
80 | /* nothing to draw? */ | ||
81 | if (((unsigned)y >= (unsigned)lcd_current_viewport->height) || | ||
82 | (x1 >= lcd_current_viewport->width) || | ||
83 | (x2 < 0)) | ||
84 | return; | 71 | return; |
85 | 72 | ||
86 | if (x1 < 0) | 73 | dst = FBADDR(x1, y); |
87 | x1 = 0; | ||
88 | if (x2 >= lcd_current_viewport->width) | ||
89 | x2 = lcd_current_viewport->width-1; | ||
90 | |||
91 | /* Adjust x1 and y to viewport */ | ||
92 | x1 += lcd_current_viewport->x; | ||
93 | x2 += lcd_current_viewport->x; | ||
94 | y += lcd_current_viewport->y; | ||
95 | |||
96 | dst = FBADDR(x1 , y ); | ||
97 | stride_dst = lcd_current_viewport->buffer->stride; | 74 | stride_dst = lcd_current_viewport->buffer->stride; |
98 | dst_end = dst + (x2 - x1) * stride_dst; | 75 | dst_end = dst + (x2 - x1) * stride_dst; |
99 | 76 | ||
@@ -108,36 +85,14 @@ void lcd_hline(int x1, int x2, int y) | |||
108 | /* Draw a vertical line (optimised) */ | 85 | /* Draw a vertical line (optimised) */ |
109 | void lcd_vline(int x, int y1, int y2) | 86 | void lcd_vline(int x, int y1, int y2) |
110 | { | 87 | { |
111 | int y, height; | 88 | int height; |
112 | unsigned bits = 0; | 89 | unsigned bits = 0; |
113 | enum fill_opt fillopt = OPT_NONE; | 90 | enum fill_opt fillopt = OPT_NONE; |
114 | fb_data *dst, *dst_end; | 91 | fb_data *dst, *dst_end; |
115 | 92 | ||
116 | /* direction flip */ | 93 | if(!lcd_clip_viewport_vline(&x, &y1, &y2)) |
117 | if (y2 < y1) | ||
118 | { | ||
119 | y = y1; | ||
120 | y1 = y2; | ||
121 | y2 = y; | ||
122 | } | ||
123 | |||
124 | /******************** In viewport clipping **********************/ | ||
125 | /* nothing to draw? */ | ||
126 | if (((unsigned)x >= (unsigned)lcd_current_viewport->width) || | ||
127 | (y1 >= lcd_current_viewport->height) || | ||
128 | (y2 < 0)) | ||
129 | return; | 94 | return; |
130 | 95 | ||
131 | if (y1 < 0) | ||
132 | y1 = 0; | ||
133 | if (y2 >= lcd_current_viewport->height) | ||
134 | y2 = lcd_current_viewport->height-1; | ||
135 | |||
136 | /* adjust for viewport */ | ||
137 | x += lcd_current_viewport->x; | ||
138 | y1 += lcd_current_viewport->y; | ||
139 | y2 += lcd_current_viewport->y; | ||
140 | |||
141 | height = y2 - y1 + 1; | 96 | height = y2 - y1 + 1; |
142 | 97 | ||
143 | /* drawmode and optimisation */ | 98 | /* drawmode and optimisation */ |
@@ -194,33 +149,9 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y, | |||
194 | { | 149 | { |
195 | fb_data *dst; | 150 | fb_data *dst; |
196 | int stride_dst; | 151 | int stride_dst; |
197 | /******************** Image in viewport clipping **********************/ | ||
198 | /* nothing to draw? */ | ||
199 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || | ||
200 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) | ||
201 | return; | ||
202 | 152 | ||
203 | if (x < 0) | 153 | if (!lcd_clip_viewport_rect(&x, &y, &width, &height, &src_x, &src_y)) |
204 | { | 154 | return; |
205 | width += x; | ||
206 | src_x -= x; | ||
207 | x = 0; | ||
208 | } | ||
209 | if (y < 0) | ||
210 | { | ||
211 | height += y; | ||
212 | src_y -= y; | ||
213 | y = 0; | ||
214 | } | ||
215 | |||
216 | if (x + width > lcd_current_viewport->width) | ||
217 | width = lcd_current_viewport->width - x; | ||
218 | if (y + height > lcd_current_viewport->height) | ||
219 | height = lcd_current_viewport->height - y; | ||
220 | |||
221 | /* adjust for viewport */ | ||
222 | x += lcd_current_viewport->x; | ||
223 | y += lcd_current_viewport->y; | ||
224 | 155 | ||
225 | src += stride * src_x + src_y; /* move starting point */ | 156 | src += stride * src_x + src_y; /* move starting point */ |
226 | dst = FBADDR(x, y); | 157 | dst = FBADDR(x, y); |
@@ -244,34 +175,9 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x, | |||
244 | fb_data *dst, *dst_end; | 175 | fb_data *dst, *dst_end; |
245 | int stride_dst; | 176 | int stride_dst; |
246 | 177 | ||
247 | /******************** Image in viewport clipping **********************/ | 178 | if (!lcd_clip_viewport_rect(&x, &y, &width, &height, &src_x, &src_y)) |
248 | /* nothing to draw? */ | ||
249 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || | ||
250 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) | ||
251 | return; | 179 | return; |
252 | 180 | ||
253 | if (x < 0) | ||
254 | { | ||
255 | width += x; | ||
256 | src_x -= x; | ||
257 | x = 0; | ||
258 | } | ||
259 | if (y < 0) | ||
260 | { | ||
261 | height += y; | ||
262 | src_y -= y; | ||
263 | y = 0; | ||
264 | } | ||
265 | |||
266 | if (x + width > lcd_current_viewport->width) | ||
267 | width = lcd_current_viewport->width - x; | ||
268 | if (y + height > lcd_current_viewport->height) | ||
269 | height = lcd_current_viewport->height - y; | ||
270 | |||
271 | /* adjust for viewport */ | ||
272 | x += lcd_current_viewport->x; | ||
273 | y += lcd_current_viewport->y; | ||
274 | |||
275 | src += stride * src_x + src_y; /* move starting point */ | 181 | src += stride * src_x + src_y; /* move starting point */ |
276 | dst = FBADDR(x, y); | 182 | dst = FBADDR(x, y); |
277 | stride_dst = lcd_current_viewport->buffer->stride; | 183 | stride_dst = lcd_current_viewport->buffer->stride; |
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c index 6dff6f3b50..fd032c0956 100644 --- a/firmware/drivers/lcd-16bit.c +++ b/firmware/drivers/lcd-16bit.c | |||
@@ -62,36 +62,14 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
62 | /* Draw a horizontal line (optimised) */ | 62 | /* Draw a horizontal line (optimised) */ |
63 | void lcd_hline(int x1, int x2, int y) | 63 | void lcd_hline(int x1, int x2, int y) |
64 | { | 64 | { |
65 | int x, width; | 65 | int width; |
66 | unsigned bits = 0; | 66 | unsigned bits = 0; |
67 | enum fill_opt fillopt = OPT_NONE; | 67 | enum fill_opt fillopt = OPT_NONE; |
68 | fb_data *dst, *dst_end; | 68 | fb_data *dst, *dst_end; |
69 | 69 | ||
70 | /* direction flip */ | 70 | if (!lcd_clip_viewport_hline(&x1, &x2, &y)) |
71 | if (x2 < x1) | ||
72 | { | ||
73 | x = x1; | ||
74 | x1 = x2; | ||
75 | x2 = x; | ||
76 | } | ||
77 | |||
78 | /******************** In viewport clipping **********************/ | ||
79 | /* nothing to draw? */ | ||
80 | if (((unsigned)y >= (unsigned)lcd_current_viewport->height) || | ||
81 | (x1 >= lcd_current_viewport->width) || | ||
82 | (x2 < 0)) | ||
83 | return; | 71 | return; |
84 | 72 | ||
85 | if (x1 < 0) | ||
86 | x1 = 0; | ||
87 | if (x2 >= lcd_current_viewport->width) | ||
88 | x2 = lcd_current_viewport->width-1; | ||
89 | |||
90 | /* Adjust x1 and y to viewport */ | ||
91 | x1 += lcd_current_viewport->x; | ||
92 | x2 += lcd_current_viewport->x; | ||
93 | y += lcd_current_viewport->y; | ||
94 | |||
95 | width = x2 - x1 + 1; | 73 | width = x2 - x1 + 1; |
96 | 74 | ||
97 | /* drawmode and optimisation */ | 75 | /* drawmode and optimisation */ |
@@ -144,37 +122,14 @@ void lcd_hline(int x1, int x2, int y) | |||
144 | /* Draw a vertical line (optimised) */ | 122 | /* Draw a vertical line (optimised) */ |
145 | void lcd_vline(int x, int y1, int y2) | 123 | void lcd_vline(int x, int y1, int y2) |
146 | { | 124 | { |
147 | int y; | ||
148 | fb_data *dst, *dst_end; | 125 | fb_data *dst, *dst_end; |
149 | int stride_dst; | 126 | int stride_dst; |
150 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[lcd_current_viewport->drawmode]; | 127 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[lcd_current_viewport->drawmode]; |
151 | 128 | ||
152 | /* direction flip */ | 129 | if (!lcd_clip_viewport_vline(&x, &y1, &y2)) |
153 | if (y2 < y1) | ||
154 | { | ||
155 | y = y1; | ||
156 | y1 = y2; | ||
157 | y2 = y; | ||
158 | } | ||
159 | |||
160 | /******************** In viewport clipping **********************/ | ||
161 | /* nothing to draw? */ | ||
162 | if (((unsigned)x >= (unsigned)lcd_current_viewport->width) || | ||
163 | (y1 >= lcd_current_viewport->height) || | ||
164 | (y2 < 0)) | ||
165 | return; | 130 | return; |
166 | 131 | ||
167 | if (y1 < 0) | 132 | dst = FBADDR(x, y1); |
168 | y1 = 0; | ||
169 | if (y2 >= lcd_current_viewport->height) | ||
170 | y2 = lcd_current_viewport->height-1; | ||
171 | |||
172 | /* adjust for viewport */ | ||
173 | x += lcd_current_viewport->x; | ||
174 | y1 += lcd_current_viewport->y; | ||
175 | y2 += lcd_current_viewport->y; | ||
176 | |||
177 | dst = FBADDR(x , y1); | ||
178 | stride_dst = lcd_current_viewport->buffer->stride; | 133 | stride_dst = lcd_current_viewport->buffer->stride; |
179 | dst_end = dst + (y2 - y1) * stride_dst; | 134 | dst_end = dst + (y2 - y1) * stride_dst; |
180 | 135 | ||
@@ -194,34 +149,9 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y, | |||
194 | fb_data *dst; | 149 | fb_data *dst; |
195 | int stride_dst; | 150 | int stride_dst; |
196 | 151 | ||
197 | /******************** Image in viewport clipping **********************/ | 152 | if (!lcd_clip_viewport_rect(&x, &y, &width, &height, &src_x, &src_y)) |
198 | /* nothing to draw? */ | ||
199 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || | ||
200 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) | ||
201 | return; | 153 | return; |
202 | 154 | ||
203 | if (x < 0) | ||
204 | { | ||
205 | width += x; | ||
206 | src_x -= x; | ||
207 | x = 0; | ||
208 | } | ||
209 | if (y < 0) | ||
210 | { | ||
211 | height += y; | ||
212 | src_y -= y; | ||
213 | y = 0; | ||
214 | } | ||
215 | |||
216 | if (x + width > lcd_current_viewport->width) | ||
217 | width = lcd_current_viewport->width - x; | ||
218 | if (y + height > lcd_current_viewport->height) | ||
219 | height = lcd_current_viewport->height - y; | ||
220 | |||
221 | /* adjust for viewport */ | ||
222 | x += lcd_current_viewport->x; | ||
223 | y += lcd_current_viewport->y; | ||
224 | |||
225 | src += stride * src_y + src_x; /* move starting point */ | 155 | src += stride * src_y + src_x; /* move starting point */ |
226 | dst = FBADDR(x, y); | 156 | dst = FBADDR(x, y); |
227 | stride_dst = lcd_current_viewport->buffer->stride; | 157 | stride_dst = lcd_current_viewport->buffer->stride; |
@@ -244,34 +174,9 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x, | |||
244 | unsigned fg = lcd_current_viewport->fg_pattern; | 174 | unsigned fg = lcd_current_viewport->fg_pattern; |
245 | int stride_dst = lcd_current_viewport->buffer->stride; | 175 | int stride_dst = lcd_current_viewport->buffer->stride; |
246 | 176 | ||
247 | /******************** Image in viewport clipping **********************/ | 177 | if (!lcd_clip_viewport_rect(&x, &y, &width, &height, &src_x, &src_y)) |
248 | /* nothing to draw? */ | ||
249 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || | ||
250 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) | ||
251 | return; | 178 | return; |
252 | 179 | ||
253 | if (x < 0) | ||
254 | { | ||
255 | width += x; | ||
256 | src_x -= x; | ||
257 | x = 0; | ||
258 | } | ||
259 | if (y < 0) | ||
260 | { | ||
261 | height += y; | ||
262 | src_y -= y; | ||
263 | y = 0; | ||
264 | } | ||
265 | |||
266 | if (x + width > lcd_current_viewport->width) | ||
267 | width = lcd_current_viewport->width - x; | ||
268 | if (y + height > lcd_current_viewport->height) | ||
269 | height = lcd_current_viewport->height - y; | ||
270 | |||
271 | /* adjust for viewport */ | ||
272 | x += lcd_current_viewport->x; | ||
273 | y += lcd_current_viewport->y; | ||
274 | |||
275 | src += stride * src_y + src_x; /* move starting point */ | 180 | src += stride * src_y + src_x; /* move starting point */ |
276 | dst = FBADDR(x, y); | 181 | dst = FBADDR(x, y); |
277 | 182 | ||
diff --git a/firmware/drivers/lcd-1bit-vert.c b/firmware/drivers/lcd-1bit-vert.c index 49c15c041e..e1b65ca9c0 100644 --- a/firmware/drivers/lcd-1bit-vert.c +++ b/firmware/drivers/lcd-1bit-vert.c | |||
@@ -92,6 +92,8 @@ static void *LCDFN(frameaddress_default)(int x, int y) | |||
92 | return fb->FBFN(ptr) + element;/*(element % fb->elems);*/ | 92 | return fb->FBFN(ptr) + element;/*(element % fb->elems);*/ |
93 | } | 93 | } |
94 | 94 | ||
95 | #include "lcd-bitmap-common.c" | ||
96 | |||
95 | /* LCD init */ | 97 | /* LCD init */ |
96 | void LCDFN(init)(void) | 98 | void LCDFN(init)(void) |
97 | { | 99 | { |
@@ -272,10 +274,8 @@ void LCDFN(clear_viewport)(void) | |||
272 | /* Set a single pixel */ | 274 | /* Set a single pixel */ |
273 | void LCDFN(drawpixel)(int x, int y) | 275 | void LCDFN(drawpixel)(int x, int y) |
274 | { | 276 | { |
275 | if ( ((unsigned)x < (unsigned)CURRENT_VP->width) | 277 | if (LCDFN(clip_viewport_pixel)(&x, &y)) |
276 | && ((unsigned)y < (unsigned)CURRENT_VP->height) | 278 | LCDFN(pixelfuncs)[CURRENT_VP->drawmode](x, y); |
277 | ) | ||
278 | LCDFN(pixelfuncs)[CURRENT_VP->drawmode](CURRENT_VP->x + x, CURRENT_VP->y + y); | ||
279 | } | 279 | } |
280 | 280 | ||
281 | /* Draw a line */ | 281 | /* Draw a line */ |
@@ -287,6 +287,7 @@ void LCDFN(drawline)(int x1, int y1, int x2, int y2) | |||
287 | int d, dinc1, dinc2; | 287 | int d, dinc1, dinc2; |
288 | int x, xinc1, xinc2; | 288 | int x, xinc1, xinc2; |
289 | int y, yinc1, yinc2; | 289 | int y, yinc1, yinc2; |
290 | int x_vp, y_vp, w_vp, h_vp; | ||
290 | LCDFN(pixelfunc_type) *pfunc = LCDFN(pixelfuncs)[CURRENT_VP->drawmode]; | 291 | LCDFN(pixelfunc_type) *pfunc = LCDFN(pixelfuncs)[CURRENT_VP->drawmode]; |
291 | 292 | ||
292 | deltax = abs(x2 - x1); | 293 | deltax = abs(x2 - x1); |
@@ -341,12 +342,15 @@ void LCDFN(drawline)(int x1, int y1, int x2, int y2) | |||
341 | x = x1; | 342 | x = x1; |
342 | y = y1; | 343 | y = y1; |
343 | 344 | ||
345 | x_vp = CURRENT_VP->x; | ||
346 | y_vp = CURRENT_VP->y; | ||
347 | w_vp = CURRENT_VP->width; | ||
348 | h_vp = CURRENT_VP->height; | ||
349 | |||
344 | for (i = 0; i < numpixels; i++) | 350 | for (i = 0; i < numpixels; i++) |
345 | { | 351 | { |
346 | if ( ((unsigned)x < (unsigned)CURRENT_VP->width) | 352 | if (x >= 0 && y >= 0 && x < w_vp && y < h_vp) |
347 | && ((unsigned)y < (unsigned)CURRENT_VP->height) | 353 | pfunc(x + x_vp, y + y_vp); |
348 | ) | ||
349 | pfunc(CURRENT_VP->x + x, CURRENT_VP->y + y); | ||
350 | 354 | ||
351 | if (d < 0) | 355 | if (d < 0) |
352 | { | 356 | { |
@@ -366,35 +370,14 @@ void LCDFN(drawline)(int x1, int y1, int x2, int y2) | |||
366 | /* Draw a horizontal line (optimised) */ | 370 | /* Draw a horizontal line (optimised) */ |
367 | void LCDFN(hline)(int x1, int x2, int y) | 371 | void LCDFN(hline)(int x1, int x2, int y) |
368 | { | 372 | { |
369 | int x, width; | 373 | int width; |
370 | unsigned char *dst, *dst_end; | 374 | unsigned char *dst, *dst_end; |
371 | unsigned mask; | 375 | unsigned mask; |
372 | LCDFN(blockfunc_type) *bfunc; | 376 | LCDFN(blockfunc_type) *bfunc; |
373 | 377 | ||
374 | /* direction flip */ | 378 | if (!LCDFN(clip_viewport_hline)(&x1, &x2, &y)) |
375 | if (x2 < x1) | ||
376 | { | ||
377 | x = x1; | ||
378 | x1 = x2; | ||
379 | x2 = x; | ||
380 | } | ||
381 | |||
382 | /******************** In viewport clipping **********************/ | ||
383 | /* nothing to draw? */ | ||
384 | if (((unsigned)y >= (unsigned)CURRENT_VP->height) || (x1 >= CURRENT_VP->width) | ||
385 | || (x2 < 0)) | ||
386 | return; | 379 | return; |
387 | 380 | ||
388 | if (x1 < 0) | ||
389 | x1 = 0; | ||
390 | if (x2 >= CURRENT_VP->width) | ||
391 | x2 = CURRENT_VP->width-1; | ||
392 | |||
393 | /* adjust to viewport */ | ||
394 | x1 += CURRENT_VP->x; | ||
395 | x2 += CURRENT_VP->x; | ||
396 | y += CURRENT_VP->y; | ||
397 | |||
398 | width = x2 - x1 + 1; | 381 | width = x2 - x1 + 1; |
399 | 382 | ||
400 | bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode]; | 383 | bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode]; |
@@ -416,30 +399,9 @@ void LCDFN(vline)(int x, int y1, int y2) | |||
416 | unsigned mask, mask_bottom; | 399 | unsigned mask, mask_bottom; |
417 | LCDFN(blockfunc_type) *bfunc; | 400 | LCDFN(blockfunc_type) *bfunc; |
418 | 401 | ||
419 | /* direction flip */ | 402 | if (!LCDFN(clip_viewport_vline)(&x, &y1, &y2)) |
420 | if (y2 < y1) | ||
421 | { | ||
422 | ny = y1; | ||
423 | y1 = y2; | ||
424 | y2 = ny; | ||
425 | } | ||
426 | |||
427 | /******************** In viewport clipping **********************/ | ||
428 | /* nothing to draw? */ | ||
429 | if (((unsigned)x >= (unsigned)CURRENT_VP->width) || (y1 >= CURRENT_VP->height) | ||
430 | || (y2 < 0)) | ||
431 | return; | 403 | return; |
432 | 404 | ||
433 | if (y1 < 0) | ||
434 | y1 = 0; | ||
435 | if (y2 >= CURRENT_VP->height) | ||
436 | y2 = CURRENT_VP->height-1; | ||
437 | |||
438 | /* adjust for viewport */ | ||
439 | y1 += CURRENT_VP->y; | ||
440 | y2 += CURRENT_VP->y; | ||
441 | x += CURRENT_VP->x; | ||
442 | |||
443 | bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode]; | 405 | bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode]; |
444 | dst = LCDFB(x,y1>>3); | 406 | dst = LCDFB(x,y1>>3); |
445 | ny = y2 - (y1 & ~7); | 407 | ny = y2 - (y1 & ~7); |
@@ -483,31 +445,9 @@ void LCDFN(fillrect)(int x, int y, int width, int height) | |||
483 | LCDFN(blockfunc_type) *bfunc; | 445 | LCDFN(blockfunc_type) *bfunc; |
484 | bool fillopt = false; | 446 | bool fillopt = false; |
485 | 447 | ||
486 | /******************** In viewport clipping **********************/ | 448 | if (!LCDFN(clip_viewport_rect)(&x, &y, &width, &height, NULL, NULL)) |
487 | /* nothing to draw? */ | ||
488 | if ((width <= 0) || (height <= 0) || (x >= CURRENT_VP->width) | ||
489 | || (y >= CURRENT_VP->height) || (x + width <= 0) || (y + height <= 0)) | ||
490 | return; | 449 | return; |
491 | 450 | ||
492 | if (x < 0) | ||
493 | { | ||
494 | width += x; | ||
495 | x = 0; | ||
496 | } | ||
497 | if (y < 0) | ||
498 | { | ||
499 | height += y; | ||
500 | y = 0; | ||
501 | } | ||
502 | if (x + width > CURRENT_VP->width) | ||
503 | width = CURRENT_VP->width - x; | ||
504 | if (y + height > CURRENT_VP->height) | ||
505 | height = CURRENT_VP->height - y; | ||
506 | |||
507 | /* adjust for viewport */ | ||
508 | x += CURRENT_VP->x; | ||
509 | y += CURRENT_VP->y; | ||
510 | |||
511 | if (CURRENT_VP->drawmode & DRMODE_INVERSEVID) | 451 | if (CURRENT_VP->drawmode & DRMODE_INVERSEVID) |
512 | { | 452 | { |
513 | if (CURRENT_VP->drawmode & DRMODE_BG) | 453 | if (CURRENT_VP->drawmode & DRMODE_BG) |
@@ -582,34 +522,9 @@ void ICODE_ATTR LCDFN(bitmap_part)(const unsigned char *src, int src_x, | |||
582 | unsigned mask, mask_bottom; | 522 | unsigned mask, mask_bottom; |
583 | LCDFN(blockfunc_type) *bfunc; | 523 | LCDFN(blockfunc_type) *bfunc; |
584 | 524 | ||
585 | /******************** Image in viewport clipping **********************/ | 525 | if (!LCDFN(clip_viewport_rect)(&x, &y, &width, &height, &src_x, &src_y)) |
586 | /* nothing to draw? */ | ||
587 | if ((width <= 0) || (height <= 0) || (x >= CURRENT_VP->width) | ||
588 | || (y >= CURRENT_VP->height) || (x + width <= 0) || (y + height <= 0)) | ||
589 | return; | 526 | return; |
590 | 527 | ||
591 | /* clip image in viewport */ | ||
592 | if (x < 0) | ||
593 | { | ||
594 | width += x; | ||
595 | src_x -= x; | ||
596 | x = 0; | ||
597 | } | ||
598 | if (y < 0) | ||
599 | { | ||
600 | height += y; | ||
601 | src_y -= y; | ||
602 | y = 0; | ||
603 | } | ||
604 | if (x + width > CURRENT_VP->width) | ||
605 | width = CURRENT_VP->width - x; | ||
606 | if (y + height > CURRENT_VP->height) | ||
607 | height = CURRENT_VP->height - y; | ||
608 | |||
609 | /* adjust for viewport */ | ||
610 | x += CURRENT_VP->x; | ||
611 | y += CURRENT_VP->y; | ||
612 | |||
613 | src += stride * (src_y >> 3) + src_x; /* move starting point */ | 528 | src += stride * (src_y >> 3) + src_x; /* move starting point */ |
614 | src_y &= 7; | 529 | src_y &= 7; |
615 | y -= src_y; | 530 | y -= src_y; |
@@ -696,5 +611,3 @@ void LCDFN(bitmap)(const unsigned char *src, int x, int y, int width, | |||
696 | { | 611 | { |
697 | LCDFN(bitmap_part)(src, 0, 0, width, x, y, width, height); | 612 | LCDFN(bitmap_part)(src, 0, 0, width, x, y, width, height); |
698 | } | 613 | } |
699 | |||
700 | #include "lcd-bitmap-common.c" | ||
diff --git a/firmware/drivers/lcd-24bit.c b/firmware/drivers/lcd-24bit.c index 279ed5924a..d95415e957 100644 --- a/firmware/drivers/lcd-24bit.c +++ b/firmware/drivers/lcd-24bit.c | |||
@@ -173,31 +173,9 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
173 | fb_data bits; | 173 | fb_data bits; |
174 | memset(&bits, 0, sizeof(fb_data)); | 174 | memset(&bits, 0, sizeof(fb_data)); |
175 | 175 | ||
176 | /******************** In viewport clipping **********************/ | 176 | if (!lcd_clip_viewport_rect(&x, &y, &width, &height, NULL, NULL)) |
177 | /* nothing to draw? */ | ||
178 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || | ||
179 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) | ||
180 | return; | 177 | return; |
181 | 178 | ||
182 | if (x < 0) | ||
183 | { | ||
184 | width += x; | ||
185 | x = 0; | ||
186 | } | ||
187 | if (y < 0) | ||
188 | { | ||
189 | height += y; | ||
190 | y = 0; | ||
191 | } | ||
192 | if (x + width > lcd_current_viewport->width) | ||
193 | width = lcd_current_viewport->width - x; | ||
194 | if (y + height > lcd_current_viewport->height) | ||
195 | height = lcd_current_viewport->height - y; | ||
196 | |||
197 | /* adjust for viewport */ | ||
198 | x += lcd_current_viewport->x; | ||
199 | y += lcd_current_viewport->y; | ||
200 | |||
201 | /* drawmode and optimisation */ | 179 | /* drawmode and optimisation */ |
202 | if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID) | 180 | if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID) |
203 | { | 181 | { |
@@ -287,33 +265,9 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
287 | int drmode = lcd_current_viewport->drawmode; | 265 | int drmode = lcd_current_viewport->drawmode; |
288 | int row; | 266 | int row; |
289 | 267 | ||
290 | /******************** Image in viewport clipping **********************/ | 268 | if (!lcd_clip_viewport_rect(&x, &y, &width, &height, &src_x, &src_y)) |
291 | /* nothing to draw? */ | ||
292 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || | ||
293 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) | ||
294 | return; | 269 | return; |
295 | 270 | ||
296 | if (x < 0) | ||
297 | { | ||
298 | width += x; | ||
299 | src_x -= x; | ||
300 | x = 0; | ||
301 | } | ||
302 | if (y < 0) | ||
303 | { | ||
304 | height += y; | ||
305 | src_y -= y; | ||
306 | y = 0; | ||
307 | } | ||
308 | if (x + width > lcd_current_viewport->width) | ||
309 | width = lcd_current_viewport->width - x; | ||
310 | if (y + height > lcd_current_viewport->height) | ||
311 | height = lcd_current_viewport->height - y; | ||
312 | |||
313 | /* adjust for viewport */ | ||
314 | x += lcd_current_viewport->x; | ||
315 | y += lcd_current_viewport->y; | ||
316 | |||
317 | src += stride * (src_y >> 3) + src_x; /* move starting point */ | 271 | src += stride * (src_y >> 3) + src_x; /* move starting point */ |
318 | src_y &= 7; | 272 | src_y &= 7; |
319 | src_end = src + width; | 273 | src_end = src + width; |
@@ -491,32 +445,9 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
491 | fb_data *dst, *dst_row; | 445 | fb_data *dst, *dst_row; |
492 | unsigned dmask = 0x00000000; | 446 | unsigned dmask = 0x00000000; |
493 | int drmode = lcd_current_viewport->drawmode; | 447 | int drmode = lcd_current_viewport->drawmode; |
494 | /* nothing to draw? */ | ||
495 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || | ||
496 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) | ||
497 | return; | ||
498 | 448 | ||
499 | /* clipping */ | 449 | if (!lcd_clip_viewport_rect(&x, &y, &width, &height, &src_x, &src_y)) |
500 | if (x < 0) | 450 | return; |
501 | { | ||
502 | width += x; | ||
503 | src_x -= x; | ||
504 | x = 0; | ||
505 | } | ||
506 | if (y < 0) | ||
507 | { | ||
508 | height += y; | ||
509 | src_y -= y; | ||
510 | y = 0; | ||
511 | } | ||
512 | if (x + width > lcd_current_viewport->width) | ||
513 | width = lcd_current_viewport->width - x; | ||
514 | if (y + height > lcd_current_viewport->height) | ||
515 | height = lcd_current_viewport->height - y; | ||
516 | |||
517 | /* adjust for viewport */ | ||
518 | x += lcd_current_viewport->x; | ||
519 | y += lcd_current_viewport->y; | ||
520 | 451 | ||
521 | /* the following drawmode combinations are possible: | 452 | /* the following drawmode combinations are possible: |
522 | * 1) COMPLEMENT: just negates the framebuffer contents | 453 | * 1) COMPLEMENT: just negates the framebuffer contents |
@@ -758,38 +689,16 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
758 | /* Draw a horizontal line (optimised) */ | 689 | /* Draw a horizontal line (optimised) */ |
759 | void lcd_hline(int x1, int x2, int y) | 690 | void lcd_hline(int x1, int x2, int y) |
760 | { | 691 | { |
761 | int x, width; | 692 | int width; |
762 | fb_data *dst, *dst_end; | 693 | fb_data *dst, *dst_end; |
763 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[lcd_current_viewport->drawmode]; | 694 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[lcd_current_viewport->drawmode]; |
764 | 695 | ||
765 | /* direction flip */ | 696 | if (!lcd_clip_viewport_hline(&x1, &x2, &y)) |
766 | if (x2 < x1) | ||
767 | { | ||
768 | x = x1; | ||
769 | x1 = x2; | ||
770 | x2 = x; | ||
771 | } | ||
772 | |||
773 | /******************** In viewport clipping **********************/ | ||
774 | /* nothing to draw? */ | ||
775 | if (((unsigned)y >= (unsigned)lcd_current_viewport->height) || | ||
776 | (x1 >= lcd_current_viewport->width) || | ||
777 | (x2 < 0)) | ||
778 | return; | 697 | return; |
779 | 698 | ||
780 | if (x1 < 0) | ||
781 | x1 = 0; | ||
782 | if (x2 >= lcd_current_viewport->width) | ||
783 | x2 = lcd_current_viewport->width-1; | ||
784 | |||
785 | /* Adjust x1 and y to viewport */ | ||
786 | x1 += lcd_current_viewport->x; | ||
787 | x2 += lcd_current_viewport->x; | ||
788 | y += lcd_current_viewport->y; | ||
789 | |||
790 | width = x2 - x1 + 1; | 699 | width = x2 - x1 + 1; |
791 | 700 | ||
792 | dst = FBADDR(x1 , y); | 701 | dst = FBADDR(x1, y); |
793 | dst_end = dst + width; | 702 | dst_end = dst + width; |
794 | do | 703 | do |
795 | { | 704 | { |
@@ -801,36 +710,13 @@ void lcd_hline(int x1, int x2, int y) | |||
801 | /* Draw a vertical line (optimised) */ | 710 | /* Draw a vertical line (optimised) */ |
802 | void lcd_vline(int x, int y1, int y2) | 711 | void lcd_vline(int x, int y1, int y2) |
803 | { | 712 | { |
804 | int y; | ||
805 | fb_data *dst, *dst_end; | 713 | fb_data *dst, *dst_end; |
806 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[lcd_current_viewport->drawmode]; | 714 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[lcd_current_viewport->drawmode]; |
807 | 715 | ||
808 | /* direction flip */ | 716 | if (!lcd_clip_viewport_vline(&x, &y1, &y2)) |
809 | if (y2 < y1) | ||
810 | { | ||
811 | y = y1; | ||
812 | y1 = y2; | ||
813 | y2 = y; | ||
814 | } | ||
815 | |||
816 | /******************** In viewport clipping **********************/ | ||
817 | /* nothing to draw? */ | ||
818 | if (((unsigned)x >= (unsigned)lcd_current_viewport->width) || | ||
819 | (y1 >= lcd_current_viewport->height) || | ||
820 | (y2 < 0)) | ||
821 | return; | 717 | return; |
822 | 718 | ||
823 | if (y1 < 0) | 719 | dst = FBADDR(x, y1); |
824 | y1 = 0; | ||
825 | if (y2 >= lcd_current_viewport->height) | ||
826 | y2 = lcd_current_viewport->height-1; | ||
827 | |||
828 | /* adjust for viewport */ | ||
829 | x += lcd_current_viewport->x; | ||
830 | y1 += lcd_current_viewport->y; | ||
831 | y2 += lcd_current_viewport->y; | ||
832 | |||
833 | dst = FBADDR(x , y1); | ||
834 | dst_end = dst + (y2 - y1) * LCD_WIDTH; | 720 | dst_end = dst + (y2 - y1) * LCD_WIDTH; |
835 | 721 | ||
836 | do | 722 | do |
@@ -848,34 +734,9 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y, | |||
848 | { | 734 | { |
849 | fb_data *dst; | 735 | fb_data *dst; |
850 | 736 | ||
851 | /******************** Image in viewport clipping **********************/ | 737 | if (!lcd_clip_viewport_rect(&x, &y, &width, &height, &src_x, &src_y)) |
852 | /* nothing to draw? */ | ||
853 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || | ||
854 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) | ||
855 | return; | 738 | return; |
856 | 739 | ||
857 | if (x < 0) | ||
858 | { | ||
859 | width += x; | ||
860 | src_x -= x; | ||
861 | x = 0; | ||
862 | } | ||
863 | if (y < 0) | ||
864 | { | ||
865 | height += y; | ||
866 | src_y -= y; | ||
867 | y = 0; | ||
868 | } | ||
869 | |||
870 | if (x + width > lcd_current_viewport->width) | ||
871 | width = lcd_current_viewport->width - x; | ||
872 | if (y + height > lcd_current_viewport->height) | ||
873 | height = lcd_current_viewport->height - y; | ||
874 | |||
875 | /* adjust for viewport */ | ||
876 | x += lcd_current_viewport->x; | ||
877 | y += lcd_current_viewport->y; | ||
878 | |||
879 | src += stride * src_y + src_x; /* move starting point */ | 740 | src += stride * src_y + src_x; /* move starting point */ |
880 | dst = FBADDR(x, y); | 741 | dst = FBADDR(x, y); |
881 | 742 | ||
@@ -896,34 +757,9 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x, | |||
896 | fb_data *dst; | 757 | fb_data *dst; |
897 | fb_data fg, transparent, replacewithfg; | 758 | fb_data fg, transparent, replacewithfg; |
898 | 759 | ||
899 | /******************** Image in viewport clipping **********************/ | 760 | if (!lcd_clip_viewport_rect(&x, &y, &width, &height, &src_x, &src_y)) |
900 | /* nothing to draw? */ | ||
901 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || | ||
902 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) | ||
903 | return; | 761 | return; |
904 | 762 | ||
905 | if (x < 0) | ||
906 | { | ||
907 | width += x; | ||
908 | src_x -= x; | ||
909 | x = 0; | ||
910 | } | ||
911 | if (y < 0) | ||
912 | { | ||
913 | height += y; | ||
914 | src_y -= y; | ||
915 | y = 0; | ||
916 | } | ||
917 | |||
918 | if (x + width > lcd_current_viewport->width) | ||
919 | width = lcd_current_viewport->width - x; | ||
920 | if (y + height > lcd_current_viewport->height) | ||
921 | height = lcd_current_viewport->height - y; | ||
922 | |||
923 | /* adjust for viewport */ | ||
924 | x += lcd_current_viewport->x; | ||
925 | y += lcd_current_viewport->y; | ||
926 | |||
927 | src += stride * src_y + src_x; /* move starting point */ | 763 | src += stride * src_y + src_x; /* move starting point */ |
928 | dst = FBADDR(x, y); | 764 | dst = FBADDR(x, y); |
929 | 765 | ||
diff --git a/firmware/drivers/lcd-2bit-horz.c b/firmware/drivers/lcd-2bit-horz.c index 1bc489247c..37125679ad 100644 --- a/firmware/drivers/lcd-2bit-horz.c +++ b/firmware/drivers/lcd-2bit-horz.c | |||
@@ -89,6 +89,8 @@ static void *lcd_frameaddress_default(int x, int y) | |||
89 | return fb->fb_ptr + element;/*(element % fb->elems);*/ | 89 | return fb->fb_ptr + element;/*(element % fb->elems);*/ |
90 | } | 90 | } |
91 | 91 | ||
92 | #include "lcd-bitmap-common.c" | ||
93 | |||
92 | /* LCD init */ | 94 | /* LCD init */ |
93 | void lcd_init(void) | 95 | void lcd_init(void) |
94 | { | 96 | { |
@@ -418,10 +420,8 @@ void lcd_clear_viewport(void) | |||
418 | /* Set a single pixel */ | 420 | /* Set a single pixel */ |
419 | void lcd_drawpixel(int x, int y) | 421 | void lcd_drawpixel(int x, int y) |
420 | { | 422 | { |
421 | if ( ((unsigned)x < (unsigned)lcd_current_viewport->width) | 423 | if (lcd_clip_viewport_pixel(&x, &y)) |
422 | && ((unsigned)y < (unsigned)lcd_current_viewport->height) | 424 | lcd_pixelfuncs[lcd_current_viewport->drawmode](x, y); |
423 | ) | ||
424 | lcd_pixelfuncs[lcd_current_viewport->drawmode](lcd_current_viewport->x + x, lcd_current_viewport->y + y); | ||
425 | } | 425 | } |
426 | 426 | ||
427 | /* Draw a line */ | 427 | /* Draw a line */ |
@@ -433,6 +433,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2) | |||
433 | int d, dinc1, dinc2; | 433 | int d, dinc1, dinc2; |
434 | int x, xinc1, xinc2; | 434 | int x, xinc1, xinc2; |
435 | int y, yinc1, yinc2; | 435 | int y, yinc1, yinc2; |
436 | int x_vp, y_vp, w_vp, h_vp; | ||
436 | lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[lcd_current_viewport->drawmode]; | 437 | lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[lcd_current_viewport->drawmode]; |
437 | 438 | ||
438 | deltay = abs(y2 - y1); | 439 | deltay = abs(y2 - y1); |
@@ -487,12 +488,15 @@ void lcd_drawline(int x1, int y1, int x2, int y2) | |||
487 | x = x1; | 488 | x = x1; |
488 | y = y1; | 489 | y = y1; |
489 | 490 | ||
491 | x_vp = lcd_current_viewport->x; | ||
492 | y_vp = lcd_current_viewport->y; | ||
493 | w_vp = lcd_current_viewport->width; | ||
494 | h_vp = lcd_current_viewport->height; | ||
495 | |||
490 | for (i = 0; i < numpixels; i++) | 496 | for (i = 0; i < numpixels; i++) |
491 | { | 497 | { |
492 | if ( ((unsigned)x < (unsigned)lcd_current_viewport->width) | 498 | if (x >= 0 && y >= 0 && x < w_vp && y < h_vp) |
493 | && ((unsigned)y < (unsigned)lcd_current_viewport->height) | 499 | pfunc(x + x_vp, y + y_vp); |
494 | ) | ||
495 | pfunc(lcd_current_viewport->x + x, lcd_current_viewport->y + y); | ||
496 | 500 | ||
497 | if (d < 0) | 501 | if (d < 0) |
498 | { | 502 | { |
@@ -517,30 +521,9 @@ void lcd_hline(int x1, int x2, int y) | |||
517 | unsigned mask, mask_right; | 521 | unsigned mask, mask_right; |
518 | lcd_blockfunc_type *bfunc; | 522 | lcd_blockfunc_type *bfunc; |
519 | 523 | ||
520 | /* direction flip */ | 524 | if (!lcd_clip_viewport_hline(&x1, &x2, &y)) |
521 | if (x2 < x1) | ||
522 | { | ||
523 | nx = x1; | ||
524 | x1 = x2; | ||
525 | x2 = nx; | ||
526 | } | ||
527 | |||
528 | /******************** In viewport clipping **********************/ | ||
529 | /* nothing to draw? */ | ||
530 | if (((unsigned)y >= (unsigned)lcd_current_viewport->height) || (x1 >= lcd_current_viewport->width) | ||
531 | || (x2 < 0)) | ||
532 | return; | 525 | return; |
533 | 526 | ||
534 | if (x1 < 0) | ||
535 | x1 = 0; | ||
536 | if (x2 >= lcd_current_viewport->width) | ||
537 | x2 = lcd_current_viewport->width-1; | ||
538 | |||
539 | /* adjust to viewport */ | ||
540 | x1 += lcd_current_viewport->x; | ||
541 | x2 += lcd_current_viewport->x; | ||
542 | y += lcd_current_viewport->y; | ||
543 | |||
544 | bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode]; | 527 | bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode]; |
545 | dst = FBADDR(x1>>2,y); | 528 | dst = FBADDR(x1>>2,y); |
546 | nx = x2 - (x1 & ~3); | 529 | nx = x2 - (x1 & ~3); |
@@ -559,36 +542,14 @@ void lcd_hline(int x1, int x2, int y) | |||
559 | /* Draw a vertical line (optimised) */ | 542 | /* Draw a vertical line (optimised) */ |
560 | void lcd_vline(int x, int y1, int y2) | 543 | void lcd_vline(int x, int y1, int y2) |
561 | { | 544 | { |
562 | int y; | ||
563 | unsigned char *dst, *dst_end; | 545 | unsigned char *dst, *dst_end; |
564 | int stride_dst; | 546 | int stride_dst; |
565 | unsigned mask; | 547 | unsigned mask; |
566 | lcd_blockfunc_type *bfunc; | 548 | lcd_blockfunc_type *bfunc; |
567 | 549 | ||
568 | /* direction flip */ | 550 | if (!lcd_clip_viewport_vline(&x, &y1, &y2)) |
569 | if (y2 < y1) | ||
570 | { | ||
571 | y = y1; | ||
572 | y1 = y2; | ||
573 | y2 = y; | ||
574 | } | ||
575 | |||
576 | /******************** In viewport clipping **********************/ | ||
577 | /* nothing to draw? */ | ||
578 | if (((unsigned)x >= (unsigned)lcd_current_viewport->width) || (y1 >= lcd_current_viewport->height) | ||
579 | || (y2 < 0)) | ||
580 | return; | 551 | return; |
581 | 552 | ||
582 | if (y1 < 0) | ||
583 | y1 = 0; | ||
584 | if (y2 >= lcd_current_viewport->height) | ||
585 | y2 = lcd_current_viewport->height-1; | ||
586 | |||
587 | /* adjust for viewport */ | ||
588 | y1 += lcd_current_viewport->y; | ||
589 | y2 += lcd_current_viewport->y; | ||
590 | x += lcd_current_viewport->x; | ||
591 | |||
592 | bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode]; | 553 | bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode]; |
593 | dst = FBADDR(x>>2,y1); | 554 | dst = FBADDR(x>>2,y1); |
594 | stride_dst = LCD_FBSTRIDE(lcd_current_viewport->buffer->stride, 0); | 555 | stride_dst = LCD_FBSTRIDE(lcd_current_viewport->buffer->stride, 0); |
@@ -627,31 +588,9 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
627 | unsigned mask, mask_right; | 588 | unsigned mask, mask_right; |
628 | lcd_blockfunc_type *bfunc; | 589 | lcd_blockfunc_type *bfunc; |
629 | 590 | ||
630 | /******************** In viewport clipping **********************/ | 591 | if (!lcd_clip_viewport_rect(&x, &y, &width, &height, NULL, NULL)) |
631 | /* nothing to draw? */ | ||
632 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || (y >= lcd_current_viewport->height) | ||
633 | || (x + width <= 0) || (y + height <= 0)) | ||
634 | return; | 592 | return; |
635 | 593 | ||
636 | if (x < 0) | ||
637 | { | ||
638 | width += x; | ||
639 | x = 0; | ||
640 | } | ||
641 | if (y < 0) | ||
642 | { | ||
643 | height += y; | ||
644 | y = 0; | ||
645 | } | ||
646 | if (x + width > lcd_current_viewport->width) | ||
647 | width = lcd_current_viewport->width - x; | ||
648 | if (y + height > lcd_current_viewport->height) | ||
649 | height = lcd_current_viewport->height - y; | ||
650 | |||
651 | /* adjust for viewport */ | ||
652 | x += lcd_current_viewport->x; | ||
653 | y += lcd_current_viewport->y; | ||
654 | |||
655 | bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode]; | 594 | bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode]; |
656 | dst = FBADDR(x>>2,y); | 595 | dst = FBADDR(x>>2,y); |
657 | stride_dst = LCD_FBSTRIDE(lcd_current_viewport->buffer->stride, 0); | 596 | stride_dst = LCD_FBSTRIDE(lcd_current_viewport->buffer->stride, 0); |
@@ -706,32 +645,9 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
706 | unsigned dst_mask; | 645 | unsigned dst_mask; |
707 | int drmode = lcd_current_viewport->drawmode; | 646 | int drmode = lcd_current_viewport->drawmode; |
708 | 647 | ||
709 | /******************** Image in viewport clipping **********************/ | 648 | if (!lcd_clip_viewport_rect(&x, &y, &width, &height, &src_x, &src_y)) |
710 | /* nothing to draw? */ | ||
711 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || | ||
712 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) | ||
713 | return; | 649 | return; |
714 | 650 | ||
715 | if (x < 0) | ||
716 | { | ||
717 | width += x; | ||
718 | src_x -= x; | ||
719 | x = 0; | ||
720 | } | ||
721 | if (y < 0) | ||
722 | { | ||
723 | height += y; | ||
724 | src_y -= y; | ||
725 | y = 0; | ||
726 | } | ||
727 | if (x + width > lcd_current_viewport->width) | ||
728 | width = lcd_current_viewport->width - x; | ||
729 | if (y + height > lcd_current_viewport->height) | ||
730 | height = lcd_current_viewport->height - y; | ||
731 | |||
732 | x += lcd_current_viewport->x; /* adjust for viewport */ | ||
733 | y += lcd_current_viewport->y; /* adjust for viewport */ | ||
734 | |||
735 | src += stride * (src_y >> 3) + src_x; /* move starting point */ | 651 | src += stride * (src_y >> 3) + src_x; /* move starting point */ |
736 | src_y &= 7; | 652 | src_y &= 7; |
737 | src_end = src + width; | 653 | src_end = src + width; |
@@ -894,33 +810,9 @@ void ICODE_ATTR lcd_bitmap_part(const unsigned char *src, int src_x, | |||
894 | int stride_dst; | 810 | int stride_dst; |
895 | unsigned mask, mask_right; | 811 | unsigned mask, mask_right; |
896 | 812 | ||
897 | /******************** Image in viewport clipping **********************/ | 813 | if (!lcd_clip_viewport_rect(&x, &y, &width, &height, &src_x, &src_y)) |
898 | /* nothing to draw? */ | ||
899 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || | ||
900 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) | ||
901 | return; | 814 | return; |
902 | 815 | ||
903 | if (x < 0) | ||
904 | { | ||
905 | width += x; | ||
906 | src_x -= x; | ||
907 | x = 0; | ||
908 | } | ||
909 | if (y < 0) | ||
910 | { | ||
911 | height += y; | ||
912 | src_y -= y; | ||
913 | y = 0; | ||
914 | } | ||
915 | if (x + width > lcd_current_viewport->width) | ||
916 | width = lcd_current_viewport->width - x; | ||
917 | if (y + height > lcd_current_viewport->height) | ||
918 | height = lcd_current_viewport->height - y; | ||
919 | |||
920 | /* adjust for viewport */ | ||
921 | x += lcd_current_viewport->x; | ||
922 | y += lcd_current_viewport->y; | ||
923 | |||
924 | stride = LCD_FBSTRIDE(stride, 0); /* convert to no. of bytes */ | 816 | stride = LCD_FBSTRIDE(stride, 0); /* convert to no. of bytes */ |
925 | 817 | ||
926 | src += stride * src_y + (src_x >> 2); /* move starting point */ | 818 | src += stride * src_y + (src_x >> 2); /* move starting point */ |
@@ -971,5 +863,3 @@ void lcd_bitmap(const unsigned char *src, int x, int y, int width, int height) | |||
971 | { | 863 | { |
972 | lcd_bitmap_part(src, 0, 0, width, x, y, width, height); | 864 | lcd_bitmap_part(src, 0, 0, width, x, y, width, height); |
973 | } | 865 | } |
974 | |||
975 | #include "lcd-bitmap-common.c" | ||
diff --git a/firmware/drivers/lcd-2bit-vert.c b/firmware/drivers/lcd-2bit-vert.c index b206a2d816..5fd86c409a 100644 --- a/firmware/drivers/lcd-2bit-vert.c +++ b/firmware/drivers/lcd-2bit-vert.c | |||
@@ -91,6 +91,8 @@ static void *lcd_frameaddress_default(int x, int y) | |||
91 | return fb->fb_ptr + element; /*(element % fb->elems);*/ | 91 | return fb->fb_ptr + element; /*(element % fb->elems);*/ |
92 | } | 92 | } |
93 | 93 | ||
94 | #include "lcd-bitmap-common.c" | ||
95 | |||
94 | /* LCD init */ | 96 | /* LCD init */ |
95 | void lcd_init(void) | 97 | void lcd_init(void) |
96 | { | 98 | { |
@@ -420,10 +422,8 @@ void lcd_clear_viewport(void) | |||
420 | /* Set a single pixel */ | 422 | /* Set a single pixel */ |
421 | void lcd_drawpixel(int x, int y) | 423 | void lcd_drawpixel(int x, int y) |
422 | { | 424 | { |
423 | if ( ((unsigned)x < (unsigned)lcd_current_viewport->width) | 425 | if (lcd_clip_viewport_pixel(&x, &y)) |
424 | && ((unsigned)y < (unsigned)lcd_current_viewport->height) | 426 | lcd_pixelfuncs[lcd_current_viewport->drawmode](x, y); |
425 | ) | ||
426 | lcd_pixelfuncs[lcd_current_viewport->drawmode](lcd_current_viewport->x + x, lcd_current_viewport->y + y); | ||
427 | } | 427 | } |
428 | 428 | ||
429 | /* Draw a line */ | 429 | /* Draw a line */ |
@@ -435,6 +435,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2) | |||
435 | int d, dinc1, dinc2; | 435 | int d, dinc1, dinc2; |
436 | int x, xinc1, xinc2; | 436 | int x, xinc1, xinc2; |
437 | int y, yinc1, yinc2; | 437 | int y, yinc1, yinc2; |
438 | int x_vp, y_vp, w_vp, h_vp; | ||
438 | lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[lcd_current_viewport->drawmode]; | 439 | lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[lcd_current_viewport->drawmode]; |
439 | 440 | ||
440 | deltax = abs(x2 - x1); | 441 | deltax = abs(x2 - x1); |
@@ -489,12 +490,15 @@ void lcd_drawline(int x1, int y1, int x2, int y2) | |||
489 | x = x1; | 490 | x = x1; |
490 | y = y1; | 491 | y = y1; |
491 | 492 | ||
493 | x_vp = lcd_current_viewport->x; | ||
494 | y_vp = lcd_current_viewport->y; | ||
495 | w_vp = lcd_current_viewport->width; | ||
496 | h_vp = lcd_current_viewport->height; | ||
497 | |||
492 | for (i = 0; i < numpixels; i++) | 498 | for (i = 0; i < numpixels; i++) |
493 | { | 499 | { |
494 | if ( ((unsigned)x < (unsigned)lcd_current_viewport->width) | 500 | if (x >= 0 && y >= 0 && x < w_vp && y < h_vp) |
495 | && ((unsigned)y < (unsigned)lcd_current_viewport->height) | 501 | pfunc(x + x_vp, y + y_vp); |
496 | ) | ||
497 | pfunc(lcd_current_viewport->x + x, lcd_current_viewport->y + y); | ||
498 | 502 | ||
499 | if (d < 0) | 503 | if (d < 0) |
500 | { | 504 | { |
@@ -514,36 +518,14 @@ void lcd_drawline(int x1, int y1, int x2, int y2) | |||
514 | /* Draw a horizontal line (optimised) */ | 518 | /* Draw a horizontal line (optimised) */ |
515 | void lcd_hline(int x1, int x2, int y) | 519 | void lcd_hline(int x1, int x2, int y) |
516 | { | 520 | { |
517 | int x; | ||
518 | int width; | 521 | int width; |
519 | fb_data *dst, *dst_end; | 522 | fb_data *dst, *dst_end; |
520 | unsigned mask; | 523 | unsigned mask; |
521 | lcd_blockfunc_type *bfunc; | 524 | lcd_blockfunc_type *bfunc; |
522 | 525 | ||
523 | /* direction flip */ | 526 | if (!lcd_clip_viewport_hline(&x1, &x2, &y)) |
524 | if (x2 < x1) | ||
525 | { | ||
526 | x = x1; | ||
527 | x1 = x2; | ||
528 | x2 = x; | ||
529 | } | ||
530 | |||
531 | /******************** In viewport clipping **********************/ | ||
532 | /* nothing to draw? */ | ||
533 | if (((unsigned)y >= (unsigned)lcd_current_viewport->height) || (x1 >= lcd_current_viewport->width) | ||
534 | || (x2 < 0)) | ||
535 | return; | 527 | return; |
536 | 528 | ||
537 | if (x1 < 0) | ||
538 | x1 = 0; | ||
539 | if (x2 >= lcd_current_viewport->width) | ||
540 | x2 = lcd_current_viewport->width-1; | ||
541 | |||
542 | /* adjust x1 and y to viewport */ | ||
543 | x1 += lcd_current_viewport->x; | ||
544 | x2 += lcd_current_viewport->x; | ||
545 | y += lcd_current_viewport->y; | ||
546 | |||
547 | width = x2 - x1 + 1; | 529 | width = x2 - x1 + 1; |
548 | 530 | ||
549 | bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode]; | 531 | bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode]; |
@@ -565,30 +547,9 @@ void lcd_vline(int x, int y1, int y2) | |||
565 | unsigned mask, mask_bottom; | 547 | unsigned mask, mask_bottom; |
566 | lcd_blockfunc_type *bfunc; | 548 | lcd_blockfunc_type *bfunc; |
567 | 549 | ||
568 | /* direction flip */ | 550 | if (!lcd_clip_viewport_vline(&x, &y1, &y2)) |
569 | if (y2 < y1) | ||
570 | { | ||
571 | ny = y1; | ||
572 | y1 = y2; | ||
573 | y2 = ny; | ||
574 | } | ||
575 | |||
576 | /******************** In viewport clipping **********************/ | ||
577 | /* nothing to draw? */ | ||
578 | if (((unsigned)x >= (unsigned)lcd_current_viewport->width) || (y1 >= lcd_current_viewport->height) | ||
579 | || (y2 < 0)) | ||
580 | return; | 551 | return; |
581 | 552 | ||
582 | if (y1 < 0) | ||
583 | y1 = 0; | ||
584 | if (y2 >= lcd_current_viewport->height) | ||
585 | y2 = lcd_current_viewport->height-1; | ||
586 | |||
587 | /* adjust for viewport */ | ||
588 | y1 += lcd_current_viewport->y; | ||
589 | y2 += lcd_current_viewport->y; | ||
590 | x += lcd_current_viewport->x; | ||
591 | |||
592 | bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode]; | 553 | bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode]; |
593 | dst = FBADDR(x,y1>>2); | 554 | dst = FBADDR(x,y1>>2); |
594 | stride_dst = lcd_current_viewport->buffer->stride; | 555 | stride_dst = lcd_current_viewport->buffer->stride; |
@@ -632,31 +593,9 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
632 | lcd_blockfunc_type *bfunc; | 593 | lcd_blockfunc_type *bfunc; |
633 | bool fillopt = false; | 594 | bool fillopt = false; |
634 | 595 | ||
635 | /******************** In viewport clipping **********************/ | 596 | if (!lcd_clip_viewport_rect(&x, &y, &width, &height, NULL, NULL)) |
636 | /* nothing to draw? */ | ||
637 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) | ||
638 | || (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) | ||
639 | return; | 597 | return; |
640 | 598 | ||
641 | if (x < 0) | ||
642 | { | ||
643 | width += x; | ||
644 | x = 0; | ||
645 | } | ||
646 | if (y < 0) | ||
647 | { | ||
648 | height += y; | ||
649 | y = 0; | ||
650 | } | ||
651 | if (x + width > lcd_current_viewport->width) | ||
652 | width = lcd_current_viewport->width - x; | ||
653 | if (y + height > lcd_current_viewport->height) | ||
654 | height = lcd_current_viewport->height - y; | ||
655 | |||
656 | /* adjust for viewport */ | ||
657 | x += lcd_current_viewport->x; | ||
658 | y += lcd_current_viewport->y; | ||
659 | |||
660 | if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID) | 599 | if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID) |
661 | { | 600 | { |
662 | if ((lcd_current_viewport->drawmode & DRMODE_BG) && !lcd_backdrop) | 601 | if ((lcd_current_viewport->drawmode & DRMODE_BG) && !lcd_backdrop) |
@@ -732,33 +671,9 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
732 | unsigned mask, mask_bottom; | 671 | unsigned mask, mask_bottom; |
733 | lcd_blockfunc_type *bfunc; | 672 | lcd_blockfunc_type *bfunc; |
734 | 673 | ||
735 | /******************** Image in viewport clipping **********************/ | 674 | if (!lcd_clip_viewport_rect(&x, &y, &width, &height, &src_x, &src_y)) |
736 | /* nothing to draw? */ | ||
737 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || | ||
738 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) | ||
739 | return; | 675 | return; |
740 | 676 | ||
741 | if (x < 0) | ||
742 | { | ||
743 | width += x; | ||
744 | src_x -= x; | ||
745 | x = 0; | ||
746 | } | ||
747 | if (y < 0) | ||
748 | { | ||
749 | height += y; | ||
750 | src_y -= y; | ||
751 | y = 0; | ||
752 | } | ||
753 | if (x + width > lcd_current_viewport->width) | ||
754 | width = lcd_current_viewport->width - x; | ||
755 | if (y + height > lcd_current_viewport->height) | ||
756 | height = lcd_current_viewport->height - y; | ||
757 | |||
758 | /* adjust for viewport */ | ||
759 | x += lcd_current_viewport->x; | ||
760 | y += lcd_current_viewport->y; | ||
761 | |||
762 | src += stride * (src_y >> 3) + src_x; /* move starting point */ | 677 | src += stride * (src_y >> 3) + src_x; /* move starting point */ |
763 | src_y &= 7; | 678 | src_y &= 7; |
764 | y -= src_y; | 679 | y -= src_y; |
@@ -905,33 +820,9 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y, | |||
905 | int stride_dst; | 820 | int stride_dst; |
906 | unsigned mask, mask_bottom; | 821 | unsigned mask, mask_bottom; |
907 | 822 | ||
908 | /******************** Image in viewport clipping **********************/ | 823 | if (!lcd_clip_viewport_rect(&x, &y, &width, &height, &src_x, &src_y)) |
909 | /* nothing to draw? */ | ||
910 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) | ||
911 | || (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) | ||
912 | return; | 824 | return; |
913 | 825 | ||
914 | if (x < 0) | ||
915 | { | ||
916 | width += x; | ||
917 | src_x -= x; | ||
918 | x = 0; | ||
919 | } | ||
920 | if (y < 0) | ||
921 | { | ||
922 | height += y; | ||
923 | src_y -= y; | ||
924 | y = 0; | ||
925 | } | ||
926 | if (x + width > lcd_current_viewport->width) | ||
927 | width = lcd_current_viewport->width - x; | ||
928 | if (y + height > lcd_current_viewport->height) | ||
929 | height = lcd_current_viewport->height - y; | ||
930 | |||
931 | /* adjust for viewport */ | ||
932 | x += lcd_current_viewport->x; | ||
933 | y += lcd_current_viewport->y; | ||
934 | |||
935 | src += stride * (src_y >> 2) + src_x; /* move starting point */ | 826 | src += stride * (src_y >> 2) + src_x; /* move starting point */ |
936 | src_y &= 3; | 827 | src_y &= 3; |
937 | y -= src_y; | 828 | y -= src_y; |
@@ -1014,5 +905,3 @@ void lcd_bitmap(const fb_data *src, int x, int y, int width, int height) | |||
1014 | { | 905 | { |
1015 | lcd_bitmap_part(src, 0, 0, width, x, y, width, height); | 906 | lcd_bitmap_part(src, 0, 0, width, x, y, width, height); |
1016 | } | 907 | } |
1017 | |||
1018 | #include "lcd-bitmap-common.c" | ||
diff --git a/firmware/drivers/lcd-2bit-vi.c b/firmware/drivers/lcd-2bit-vi.c index 0580705a05..b19fdba266 100644 --- a/firmware/drivers/lcd-2bit-vi.c +++ b/firmware/drivers/lcd-2bit-vi.c | |||
@@ -103,6 +103,8 @@ static void *LCDFN(frameaddress_default)(int x, int y) | |||
103 | return fb->FBFN(ptr) + element;/*(element % fb->elems);*/ | 103 | return fb->FBFN(ptr) + element;/*(element % fb->elems);*/ |
104 | } | 104 | } |
105 | 105 | ||
106 | #include "lcd-bitmap-common.c" | ||
107 | |||
106 | /* LCD init */ | 108 | /* LCD init */ |
107 | void LCDFN(init)(void) | 109 | void LCDFN(init)(void) |
108 | { | 110 | { |
@@ -453,10 +455,8 @@ void LCDFN(clear_viewport)(void) | |||
453 | /* Set a single pixel */ | 455 | /* Set a single pixel */ |
454 | void LCDFN(drawpixel)(int x, int y) | 456 | void LCDFN(drawpixel)(int x, int y) |
455 | { | 457 | { |
456 | if ( ((unsigned)x < (unsigned)CURRENT_VP->width) | 458 | if (LCDFN(clip_viewport_pixel)(&x, &y)) |
457 | && ((unsigned)y < (unsigned)CURRENT_VP->height) | 459 | LCDFN(pixelfuncs)[CURRENT_VP->drawmode](x, y); |
458 | ) | ||
459 | LCDFN(pixelfuncs)[CURRENT_VP->drawmode](CURRENT_VP->x+x, CURRENT_VP->y+y); | ||
460 | } | 460 | } |
461 | 461 | ||
462 | /* Draw a line */ | 462 | /* Draw a line */ |
@@ -468,6 +468,7 @@ void LCDFN(drawline)(int x1, int y1, int x2, int y2) | |||
468 | int d, dinc1, dinc2; | 468 | int d, dinc1, dinc2; |
469 | int x, xinc1, xinc2; | 469 | int x, xinc1, xinc2; |
470 | int y, yinc1, yinc2; | 470 | int y, yinc1, yinc2; |
471 | int x_vp, y_vp, w_vp, h_vp; | ||
471 | LCDFN(pixelfunc_type) *pfunc = LCDFN(pixelfuncs)[CURRENT_VP->drawmode]; | 472 | LCDFN(pixelfunc_type) *pfunc = LCDFN(pixelfuncs)[CURRENT_VP->drawmode]; |
472 | 473 | ||
473 | deltax = abs(x2 - x1); | 474 | deltax = abs(x2 - x1); |
@@ -522,12 +523,15 @@ void LCDFN(drawline)(int x1, int y1, int x2, int y2) | |||
522 | x = x1; | 523 | x = x1; |
523 | y = y1; | 524 | y = y1; |
524 | 525 | ||
526 | x_vp = CURRENT_VP->x; | ||
527 | y_vp = CURRENT_VP->y; | ||
528 | w_vp = CURRENT_VP->width; | ||
529 | h_vp = CURRENT_VP->height; | ||
530 | |||
525 | for (i = 0; i < numpixels; i++) | 531 | for (i = 0; i < numpixels; i++) |
526 | { | 532 | { |
527 | if ( ((unsigned)x < (unsigned)CURRENT_VP->width) | 533 | if (x >= 0 && y >= 0 && x < w_vp && y < h_vp) |
528 | && ((unsigned)y < (unsigned)CURRENT_VP->height) | 534 | pfunc(x + x_vp, y + y_vp); |
529 | ) | ||
530 | pfunc(CURRENT_VP->x + x, CURRENT_VP->y + y); | ||
531 | 535 | ||
532 | if (d < 0) | 536 | if (d < 0) |
533 | { | 537 | { |
@@ -547,36 +551,14 @@ void LCDFN(drawline)(int x1, int y1, int x2, int y2) | |||
547 | /* Draw a horizontal line (optimised) */ | 551 | /* Draw a horizontal line (optimised) */ |
548 | void LCDFN(hline)(int x1, int x2, int y) | 552 | void LCDFN(hline)(int x1, int x2, int y) |
549 | { | 553 | { |
550 | int x; | ||
551 | int width; | 554 | int width; |
552 | FBFN(data) *dst, *dst_end; | 555 | FBFN(data) *dst, *dst_end; |
553 | unsigned mask; | 556 | unsigned mask; |
554 | LCDFN(blockfunc_type) *bfunc; | 557 | LCDFN(blockfunc_type) *bfunc; |
555 | 558 | ||
556 | /* direction flip */ | 559 | if (!LCDFN(clip_viewport_hline)(&x1, &x2, &y)) |
557 | if (x2 < x1) | ||
558 | { | ||
559 | x = x1; | ||
560 | x1 = x2; | ||
561 | x2 = x; | ||
562 | } | ||
563 | |||
564 | /******************** In viewport clipping **********************/ | ||
565 | /* nothing to draw? */ | ||
566 | if (((unsigned)y >= (unsigned)CURRENT_VP->height) || (x1 >= CURRENT_VP->width) | ||
567 | || (x2 < 0)) | ||
568 | return; | 560 | return; |
569 | 561 | ||
570 | if (x1 < 0) | ||
571 | x1 = 0; | ||
572 | if (x2 >= CURRENT_VP->width) | ||
573 | x2 = CURRENT_VP->width-1; | ||
574 | |||
575 | /* adjust x1 and y to viewport */ | ||
576 | x1 += CURRENT_VP->x; | ||
577 | x2 += CURRENT_VP->x; | ||
578 | y += CURRENT_VP->y; | ||
579 | |||
580 | width = x2 - x1 + 1; | 562 | width = x2 - x1 + 1; |
581 | 563 | ||
582 | bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode]; | 564 | bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode]; |
@@ -598,30 +580,9 @@ void LCDFN(vline)(int x, int y1, int y2) | |||
598 | unsigned mask, mask_bottom; | 580 | unsigned mask, mask_bottom; |
599 | LCDFN(blockfunc_type) *bfunc; | 581 | LCDFN(blockfunc_type) *bfunc; |
600 | 582 | ||
601 | /* direction flip */ | 583 | if (!LCDFN(clip_viewport_vline)(&x, &y1, &y2)) |
602 | if (y2 < y1) | ||
603 | { | ||
604 | ny = y1; | ||
605 | y1 = y2; | ||
606 | y2 = ny; | ||
607 | } | ||
608 | |||
609 | /******************** In viewport clipping **********************/ | ||
610 | /* nothing to draw? */ | ||
611 | if (((unsigned)x >= (unsigned)CURRENT_VP->width) || (y1 >= CURRENT_VP->height) | ||
612 | || (y2 < 0)) | ||
613 | return; | 584 | return; |
614 | 585 | ||
615 | if (y1 < 0) | ||
616 | y1 = 0; | ||
617 | if (y2 >= CURRENT_VP->height) | ||
618 | y2 = CURRENT_VP->height-1; | ||
619 | |||
620 | /* adjust for viewport */ | ||
621 | y1 += CURRENT_VP->y; | ||
622 | y2 += CURRENT_VP->y; | ||
623 | x += CURRENT_VP->x; | ||
624 | |||
625 | bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode]; | 586 | bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode]; |
626 | dst = LCDFB(x,y1>>3); | 587 | dst = LCDFB(x,y1>>3); |
627 | stride_dst = CURRENT_VP->buffer->stride; | 588 | stride_dst = CURRENT_VP->buffer->stride; |
@@ -667,31 +628,9 @@ void LCDFN(fillrect)(int x, int y, int width, int height) | |||
667 | LCDFN(blockfunc_type) *bfunc; | 628 | LCDFN(blockfunc_type) *bfunc; |
668 | bool fillopt = false; | 629 | bool fillopt = false; |
669 | 630 | ||
670 | /******************** In viewport clipping **********************/ | 631 | if (!LCDFN(clip_viewport_rect)(&x, &y, &width, &height, NULL, NULL)) |
671 | /* nothing to draw? */ | ||
672 | if ((width <= 0) || (height <= 0) || (x >= CURRENT_VP->width) | ||
673 | || (y >= CURRENT_VP->height) || (x + width <= 0) || (y + height <= 0)) | ||
674 | return; | 632 | return; |
675 | 633 | ||
676 | if (x < 0) | ||
677 | { | ||
678 | width += x; | ||
679 | x = 0; | ||
680 | } | ||
681 | if (y < 0) | ||
682 | { | ||
683 | height += y; | ||
684 | y = 0; | ||
685 | } | ||
686 | if (x + width > CURRENT_VP->width) | ||
687 | width = CURRENT_VP->width - x; | ||
688 | if (y + height > CURRENT_VP->height) | ||
689 | height = CURRENT_VP->height - y; | ||
690 | |||
691 | /* adjust for viewport */ | ||
692 | x += CURRENT_VP->x; | ||
693 | y += CURRENT_VP->y; | ||
694 | |||
695 | if (CURRENT_VP->drawmode & DRMODE_INVERSEVID) | 634 | if (CURRENT_VP->drawmode & DRMODE_INVERSEVID) |
696 | { | 635 | { |
697 | if ((CURRENT_VP->drawmode & DRMODE_BG) && !backdrop) | 636 | if ((CURRENT_VP->drawmode & DRMODE_BG) && !backdrop) |
@@ -769,33 +708,9 @@ void ICODE_ATTR LCDFN(mono_bitmap_part)(const unsigned char *src, int src_x, | |||
769 | unsigned data, mask, mask_bottom; | 708 | unsigned data, mask, mask_bottom; |
770 | LCDFN(blockfunc_type) *bfunc; | 709 | LCDFN(blockfunc_type) *bfunc; |
771 | 710 | ||
772 | /******************** Image in viewport clipping **********************/ | 711 | if (!LCDFN(clip_viewport_rect)(&x, &y, &width, &height, &src_x, &src_y)) |
773 | /* nothing to draw? */ | ||
774 | if ((width <= 0) || (height <= 0) || (x >= CURRENT_VP->width) || | ||
775 | (y >= CURRENT_VP->height) || (x + width <= 0) || (y + height <= 0)) | ||
776 | return; | 712 | return; |
777 | 713 | ||
778 | if (x < 0) | ||
779 | { | ||
780 | width += x; | ||
781 | src_x -= x; | ||
782 | x = 0; | ||
783 | } | ||
784 | if (y < 0) | ||
785 | { | ||
786 | height += y; | ||
787 | src_y -= y; | ||
788 | y = 0; | ||
789 | } | ||
790 | if (x + width > CURRENT_VP->width) | ||
791 | width = CURRENT_VP->width - x; | ||
792 | if (y + height > CURRENT_VP->height) | ||
793 | height = CURRENT_VP->height - y; | ||
794 | |||
795 | /* adjust for viewport */ | ||
796 | x += CURRENT_VP->x; | ||
797 | y += CURRENT_VP->y; | ||
798 | |||
799 | src += stride * (src_y >> 3) + src_x; /* move starting point */ | 714 | src += stride * (src_y >> 3) + src_x; /* move starting point */ |
800 | src_y &= 7; | 715 | src_y &= 7; |
801 | y -= src_y; | 716 | y -= src_y; |
@@ -913,33 +828,9 @@ void ICODE_ATTR LCDFN(bitmap_part)(const FBFN(data) *src, int src_x, | |||
913 | int stride_dst; | 828 | int stride_dst; |
914 | unsigned mask, mask_bottom; | 829 | unsigned mask, mask_bottom; |
915 | 830 | ||
916 | /******************** Image in viewport clipping **********************/ | 831 | if (!LCDFN(clip_viewport_rect)(&x, &y, &width, &height, &src_x, &src_y)) |
917 | /* nothing to draw? */ | ||
918 | if ((width <= 0) || (height <= 0) || (x >= CURRENT_VP->width) | ||
919 | || (y >= CURRENT_VP->height) || (x + width <= 0) || (y + height <= 0)) | ||
920 | return; | 832 | return; |
921 | 833 | ||
922 | if (x < 0) | ||
923 | { | ||
924 | width += x; | ||
925 | src_x -= x; | ||
926 | x = 0; | ||
927 | } | ||
928 | if (y < 0) | ||
929 | { | ||
930 | height += y; | ||
931 | src_y -= y; | ||
932 | y = 0; | ||
933 | } | ||
934 | if (x + width > CURRENT_VP->width) | ||
935 | width = CURRENT_VP->width - x; | ||
936 | if (y + height > CURRENT_VP->height) | ||
937 | height = CURRENT_VP->height - y; | ||
938 | |||
939 | /* adjust for viewport */ | ||
940 | x += CURRENT_VP->x; | ||
941 | y += CURRENT_VP->y; | ||
942 | |||
943 | src += stride * (src_y >> 3) + src_x; /* move starting point */ | 834 | src += stride * (src_y >> 3) + src_x; /* move starting point */ |
944 | src_y &= 7; | 835 | src_y &= 7; |
945 | y -= src_y; | 836 | y -= src_y; |
@@ -1036,5 +927,3 @@ void LCDFN(bitmap)(const FBFN(data) *src, int x, int y, int width, int height) | |||
1036 | { | 927 | { |
1037 | LCDFN(bitmap_part)(src, 0, 0, width, x, y, width, height); | 928 | LCDFN(bitmap_part)(src, 0, 0, width, x, y, width, height); |
1038 | } | 929 | } |
1039 | |||
1040 | #include "lcd-bitmap-common.c" | ||
diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c index 24b302b6d4..c867b214b5 100644 --- a/firmware/drivers/lcd-bitmap-common.c +++ b/firmware/drivers/lcd-bitmap-common.c | |||
@@ -53,6 +53,116 @@ | |||
53 | extern void viewport_set_buffer(struct viewport *vp, | 53 | extern void viewport_set_buffer(struct viewport *vp, |
54 | struct frame_buffer_t *buffer, | 54 | struct frame_buffer_t *buffer, |
55 | const enum screen_type screen); /* viewport.c */ | 55 | const enum screen_type screen); /* viewport.c */ |
56 | |||
57 | /* | ||
58 | * In-viewport clipping functions: | ||
59 | * | ||
60 | * These clip a primitive (pixel, line, rect) given in | ||
61 | * viewport-relative coordinates to the current viewport, | ||
62 | * and translate it to screen coordinates. They return | ||
63 | * false if the resulting primitive would be off-screen. | ||
64 | */ | ||
65 | |||
66 | static bool LCDFN(clip_viewport_pixel)(int *x, int *y) | ||
67 | { | ||
68 | struct viewport *vp = LCDFN(current_viewport); | ||
69 | |||
70 | if(*x >= vp->width || *y >= vp->height) | ||
71 | return false; | ||
72 | |||
73 | *x += vp->x; | ||
74 | *y += vp->y; | ||
75 | return true; | ||
76 | } | ||
77 | |||
78 | static bool LCDFN(clip_viewport_hline)(int *x1, int *x2, int *y) | ||
79 | { | ||
80 | struct viewport *vp = LCDFN(current_viewport); | ||
81 | |||
82 | if (*y < 0 || *y > vp->height) | ||
83 | return false; | ||
84 | |||
85 | if (*x2 < *x1) { | ||
86 | int tmp = *x2; | ||
87 | *x2 = *x1; | ||
88 | *x1 = tmp; | ||
89 | } | ||
90 | |||
91 | if (*x1 < 0) | ||
92 | *x1 = 0; | ||
93 | else if (*x1 >= vp->width) | ||
94 | return false; | ||
95 | |||
96 | if (*x2 < 0) | ||
97 | return false; | ||
98 | else if (*x2 >= vp->width) | ||
99 | *x2 = vp->width - 1; | ||
100 | |||
101 | *x1 += vp->x; | ||
102 | *x2 += vp->x; | ||
103 | *y += vp->y; | ||
104 | return true; | ||
105 | } | ||
106 | |||
107 | static bool LCDFN(clip_viewport_vline)(int *x, int *y1, int *y2) | ||
108 | { | ||
109 | struct viewport *vp = LCDFN(current_viewport); | ||
110 | |||
111 | if (*x < 0 || *x > vp->width) | ||
112 | return false; | ||
113 | |||
114 | if (*y2 < *y1) { | ||
115 | int tmp = *y2; | ||
116 | *y2 = *y1; | ||
117 | *y1 = tmp; | ||
118 | } | ||
119 | |||
120 | if (*y1 < 0) | ||
121 | *y1 = 0; | ||
122 | else if (*y1 >= vp->height) | ||
123 | return false; | ||
124 | |||
125 | if (*y2 < 0) | ||
126 | return false; | ||
127 | else if (*y2 >= vp->height) | ||
128 | *y2 = vp->height - 1; | ||
129 | |||
130 | *x += vp->x; | ||
131 | *y1 += vp->y; | ||
132 | *y2 += vp->y; | ||
133 | return true; | ||
134 | } | ||
135 | |||
136 | static bool LCDFN(clip_viewport_rect)(int *x, int *y, int *width, int *height, | ||
137 | int *src_x, int *src_y) | ||
138 | { | ||
139 | struct viewport *vp = LCDFN(current_viewport); | ||
140 | |||
141 | if (*x < 0) { | ||
142 | *width += *x; | ||
143 | if (src_x) | ||
144 | *src_x -= *x; | ||
145 | *x = 0; | ||
146 | } | ||
147 | |||
148 | if (*y < 0) { | ||
149 | *height += *y; | ||
150 | if (src_y) | ||
151 | *src_y -= *y; | ||
152 | *y = 0; | ||
153 | } | ||
154 | |||
155 | if (*x + *width > vp->width) | ||
156 | *width = vp->width - *x; | ||
157 | |||
158 | if (*y + *height > vp->height) | ||
159 | *height = vp->height - *y; | ||
160 | |||
161 | *x += vp->x; | ||
162 | *y += vp->y; | ||
163 | return *width > 0 && *height > 0; | ||
164 | } | ||
165 | |||
56 | /* | 166 | /* |
57 | * draws the borders of the current viewport | 167 | * draws the borders of the current viewport |
58 | **/ | 168 | **/ |
diff --git a/firmware/drivers/lcd-color-common.c b/firmware/drivers/lcd-color-common.c index 72ce7c209f..8a9ef64cea 100644 --- a/firmware/drivers/lcd-color-common.c +++ b/firmware/drivers/lcd-color-common.c | |||
@@ -40,6 +40,7 @@ static fb_data lcd_static_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] | |||
40 | IRAM_LCDFRAMEBUFFER CACHEALIGN_AT_LEAST_ATTR(16); | 40 | IRAM_LCDFRAMEBUFFER CACHEALIGN_AT_LEAST_ATTR(16); |
41 | 41 | ||
42 | static void *lcd_frameaddress_default(int x, int y); | 42 | static void *lcd_frameaddress_default(int x, int y); |
43 | static bool lcd_clip_viewport_pixel(int *x, int *y); | ||
43 | 44 | ||
44 | static fb_data* lcd_backdrop = NULL; | 45 | static fb_data* lcd_backdrop = NULL; |
45 | static long lcd_backdrop_offset IDATA_ATTR = 0; | 46 | static long lcd_backdrop_offset IDATA_ATTR = 0; |
@@ -196,10 +197,8 @@ fb_data* lcd_get_backdrop(void) | |||
196 | /* Set a single pixel */ | 197 | /* Set a single pixel */ |
197 | void lcd_drawpixel(int x, int y) | 198 | void lcd_drawpixel(int x, int y) |
198 | { | 199 | { |
199 | if ( ((unsigned)x < (unsigned)lcd_current_viewport->width) | 200 | if (lcd_clip_viewport_pixel(&x, &y)) |
200 | && ((unsigned)y < (unsigned)lcd_current_viewport->height) | 201 | lcd_fastpixelfuncs[lcd_current_viewport->drawmode](FBADDR(x, y)); |
201 | ) | ||
202 | lcd_fastpixelfuncs[lcd_current_viewport->drawmode](FBADDR(lcd_current_viewport->x+x, lcd_current_viewport->y+y)); | ||
203 | } | 202 | } |
204 | 203 | ||
205 | /* Draw a line */ | 204 | /* Draw a line */ |
@@ -274,11 +273,8 @@ void lcd_drawline(int x1, int y1, int x2, int y2) | |||
274 | 273 | ||
275 | for (i = 0; i < numpixels; i++) | 274 | for (i = 0; i < numpixels; i++) |
276 | { | 275 | { |
277 | if ((x >= 0 && y >= 0) | 276 | if (x >= 0 && y >= 0 && x < w_vp && y < h_vp) |
278 | && (x < w_vp) | 277 | pfunc(fbaddr(x + x_vp, y + y_vp)); |
279 | && (y < h_vp) | ||
280 | ) | ||
281 | pfunc(fbaddr( x + x_vp, y + y_vp)); | ||
282 | 278 | ||
283 | if (d < 0) | 279 | if (d < 0) |
284 | { | 280 | { |
@@ -401,7 +397,7 @@ void lcd_gradient_fillrect_part(int x, int y, int width, int height, | |||
401 | x1 = x; | 397 | x1 = x; |
402 | x2 = x + width; | 398 | x2 = x + width; |
403 | 399 | ||
404 | if (height == 0) return; | 400 | if (height <= 0) return; |
405 | 401 | ||
406 | step_mul = (1 << 16) / src_height; | 402 | step_mul = (1 << 16) / src_height; |
407 | int h_r = RGB_UNPACK_RED(start_rgb); | 403 | int h_r = RGB_UNPACK_RED(start_rgb); |