void PixMap::copy(const PixMap& pix) { if (size() != pix.size()) { throw Exception("Mismatch in PixMap sizes"); } for (int i = 0; i < size().height; ++i) { memcpy(mutable_row(i), pix.row(i), size().width * sizeof(RgbColor)); } }
void PixMap::composite(const PixMap& pix) { if (size() != pix.size()) { throw Exception("Mismatch in PixMap sizes"); } for (int y = 0; y < size().height; ++y) { for (int x = 0; x < size().width; ++x) { const RgbColor& over = pix.get(x, y); const double oa = over.alpha / 255.0; const RgbColor& under = get(x, y); const double ua = under.alpha / 255.0; // TODO(sfiera): if we're going to do anything like this in the long run, we should // require that alpha be pre-multiplied with the color components. We should probably // also use integral arithmetic. double red = (over.red * oa) + ((under.red * ua) * (1.0 - oa)); double green = (over.green * oa) + ((under.green * ua) * (1.0 - oa)); double blue = (over.blue * oa) + ((under.blue * ua) * (1.0 - oa)); double alpha = oa + (ua * (1.0 - oa)); set(x, y, RgbColor(alpha * 255, red / alpha, green / alpha, blue / alpha)); } } }
void copy_world(PixMap& to, PixMap& from, Rect bounds) { bounds.clip_to(to.size().as_rect()); to.view(bounds).copy(from.view(bounds)); }