| 170 | } |
| 171 | |
| 172 | static void |
| 173 | shift_bitmap (const lay::Bitmap *from, lay::Bitmap *to, int dx, int dy) |
| 174 | { |
| 175 | tl_assert (from->width () == to->width ()); |
| 176 | tl_assert (from->height () == to->height ()); |
| 177 | |
| 178 | to->clear (); |
| 179 | |
| 180 | if (dy <= -int (from->height()) || dy >= int (from->height ()) || |
| 181 | dx <= -int (from->width()) || dx >= int (from->width ())) { |
| 182 | return; |
| 183 | } |
| 184 | |
| 185 | int nn = int (to->height ()) - std::max (0, dy); |
| 186 | for (int n = std::max (-dy, 0); n < nn; ++n) { |
| 187 | |
| 188 | if (from->is_scanline_empty (n)) { |
| 189 | continue; |
| 190 | } |
| 191 | |
| 192 | const uint32_t *sl_from = from->scanline (n); |
| 193 | uint32_t *sl_to = to->scanline (n + dy); |
| 194 | |
| 195 | if (dx < 0) { |
| 196 | |
| 197 | unsigned int mo = ((unsigned int) -dx) / 32; |
| 198 | unsigned int m = (to->width () + 31) / 32 - mo; |
| 199 | sl_from += mo; |
| 200 | |
| 201 | unsigned int s1 = ((unsigned int) -dx) % 32; |
| 202 | if (! s1) { |
| 203 | for (unsigned int i = 0; i < m; ++i) { |
| 204 | *sl_to++ = *sl_from++; |
| 205 | } |
| 206 | } else { |
| 207 | unsigned int s2 = 32 - s1; |
| 208 | for (unsigned int i = 1; i < m; ++i) { |
| 209 | *sl_to++ = (sl_from[0] >> s1) | (sl_from[1] << s2); |
| 210 | ++sl_from; |
| 211 | } |
| 212 | if (m) { |
| 213 | *sl_to++ = (sl_from[0] >> s1); |
| 214 | } |
| 215 | } |
| 216 | |
| 217 | } else { |
| 218 | |
| 219 | unsigned int mo = ((unsigned int) dx) / 32; |
| 220 | unsigned int m = (to->width () + 31) / 32 - mo; |
| 221 | sl_to += mo; |
| 222 | |
| 223 | unsigned int s1 = ((unsigned int) dx) % 32; |
| 224 | if (! s1) { |
| 225 | for (unsigned int i = 0; i < m; ++i) { |
| 226 | *sl_to++ = *sl_from++; |
| 227 | } |
| 228 | } else { |
| 229 | unsigned int s2 = 32 - s1; |