| 87 | } |
| 88 | |
| 89 | int XDrawable::copyImageData(KThread* thread, const std::shared_ptr<XGC>& gc, U32 data, U32 bytes_per_line, S32 bits_per_pixel, S32 src_x, S32 src_y, S32 dst_x, S32 dst_y, U32 width, U32 height) { |
| 90 | if (bits_per_pixel != this->visual->bits_per_rgb) { |
| 91 | return BadMatch; |
| 92 | } |
| 93 | if (gc && (gc->clip_rects.size() || gc->values.clip_mask || gc->values.clip_x_origin || gc->values.clip_y_origin)) { |
| 94 | //klog("XDrawable::copyImageData clipping not implemented"); |
| 95 | } |
| 96 | BOXEDWINE_CRITICAL_SECTION_WITH_MUTEX(mutex); |
| 97 | U32 src = data + bytes_per_line * src_y + (bits_per_pixel * src_x + 7) / 8; |
| 98 | U8* dst = this->data + this->bytes_per_line * dst_y + (bits_per_pixel * dst_x + 7) / 8; |
| 99 | KMemory* memory = thread->memory; |
| 100 | if (dst_x + width > w) { |
| 101 | if ((S32)w < dst_x) { |
| 102 | return Success; |
| 103 | } |
| 104 | width = w - dst_x; |
| 105 | } |
| 106 | if (dst_y + (S32)height > (S32)h) { |
| 107 | if ((S32)h < dst_y) { |
| 108 | return Success; |
| 109 | } |
| 110 | height = h - dst_y; |
| 111 | } |
| 112 | U32 copyPerLine = (bits_per_pixel * width + 7) / 8; |
| 113 | |
| 114 | if (!gc || gc->values.function == GXcopy) { |
| 115 | for (U32 y = 0; y < height; y++) { |
| 116 | if (!memory->canRead(src, copyPerLine)) { |
| 117 | return BadValue; |
| 118 | } |
| 119 | memory->memcpy(dst, src, copyPerLine); |
| 120 | src += bytes_per_line; |
| 121 | dst += this->bytes_per_line; |
| 122 | } |
| 123 | } else if (gc->values.function == GXxor && bits_per_pixel == 32) { |
| 124 | for (U32 y = 0; y < height; y++) { |
| 125 | if (!memory->canRead(src, copyPerLine)) { |
| 126 | return BadValue; |
| 127 | } |
| 128 | U32* dstPixel = (U32*)dst; |
| 129 | for (U32 x = 0; x < width; x++) { |
| 130 | dstPixel[x] ^= memory->readd(src + x * 4); |
| 131 | } |
| 132 | src += bytes_per_line; |
| 133 | dst += this->bytes_per_line; |
| 134 | } |
| 135 | } |
| 136 | setDirty(); |
| 137 | return Success; |
| 138 | } |
| 139 | |
| 140 | int XDrawable::copy(KThread* thread, const std::shared_ptr<XGC>& gc, const std::shared_ptr<XDrawable>& srcDrawable, S32 srcX, S32 srcY, U32 width, U32 height, S32 dstX, S32 dstY) { |
| 141 | if (srcDrawable->visual->bits_per_rgb != this->visual->bits_per_rgb) { |
no test coverage detected