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