def composite_tile_over(self, dst, tx, ty, mipmap_level=0, opacity=1.0, mode=0): """ composite one tile of this surface over the array dst, modifying only dst """ if self.mipmap_level < mipmap_level: return self.mipmap.composite_tile_over(dst, tx, ty, mipmap_level, opacity) if not (tx,ty) in self.tiledict: return src = self.get_tile_memory(tx, ty, readonly=True) if dst.shape[2] == 4 and dst.dtype == 'uint16': # rarely used (for merging layers, also when exporting a transparent PNGs) # src (premultiplied) OVER dst (premultiplied) # dstColor = srcColor + (1.0 - srcAlpha) * dstColor one_minus_srcAlpha = (1<<15) - (opacity * src[:,:,3:4]).astype('uint32') dst[:,:,:] = opacity * src[:,:,:] + ((one_minus_srcAlpha * dst[:,:,:]) >> 15).astype('uint16') elif dst.shape[2] == 3 and dst.dtype == 'uint16': mypaintlib.tile_composite_rgba16_over_rgb16(src, dst, opacity) else: raise NotImplementedError
def composite_array_src_over(dst, src, mipmap_level=0, opacity=1.0): """The default "svg:src-over" layer composite op implementation. """ if dst.shape[2] == 4 and dst.dtype == 'uint16': # rarely used (for merging layers, also when exporting a transparent PNGs) # src (premultiplied) OVER dst (premultiplied) # cB = cA + (1.0 - aA) * cB # where B = dst, A = src srcAlpha = src[:,:,3:4].astype('float') * opacity / (1 << 15) dstAlpha = dst[:,:,3:4].astype('float') / (1 << 15) src_premult = src[:,:,0:3].astype('float') * opacity / (1<<15) dst_premult = dst[:,:,0:3].astype('float') / (1<<15) dst_c = clip(src_premult + (1.0 - srcAlpha) * dst_premult, 0.0, 1.0) dst_a = clip(srcAlpha + dstAlpha - srcAlpha * dstAlpha, 0.0, 1.0) dst[:,:,0:3] = clip(dst_c * (1<<15), 0, (1<<15) - 1).astype('uint16') dst[:,:,3:4] = clip(dst_a * (1<<15), 0, (1<<15) - 1).astype('uint16') elif dst.shape[2] == 3 and dst.dtype == 'uint16': mypaintlib.tile_composite_rgba16_over_rgb16(src, dst, opacity) else: raise NotImplementedError