Example #1
0
/**
 * aSrcRect: Rect relative to the aSrc surface
 * aDestPoint: Point inside aDest surface
 */
void
CopyRect(DataSourceSurface* aSrc, DataSourceSurface* aDest,
         IntRect aSrcRect, IntPoint aDestPoint)
{
  if (aSrcRect.Overflows() ||
      IntRect(aDestPoint, aSrcRect.Size()).Overflows()) {
    MOZ_CRASH("we should never be getting invalid rects at this point");
  }

  MOZ_RELEASE_ASSERT(aSrc->GetFormat() == aDest->GetFormat(),
                     "different surface formats");
  MOZ_RELEASE_ASSERT(IntRect(IntPoint(), aSrc->GetSize()).Contains(aSrcRect),
                     "source rect too big for source surface");
  MOZ_RELEASE_ASSERT(IntRect(IntPoint(), aDest->GetSize()).Contains(IntRect(aDestPoint, aSrcRect.Size())),
                     "dest surface too small");

  if (aSrcRect.IsEmpty()) {
    return;
  }

  DataSourceSurface::ScopedMap srcMap(aSrc, DataSourceSurface::READ);
  DataSourceSurface::ScopedMap destMap(aDest, DataSourceSurface::WRITE);
  if (MOZ2D_WARN_IF(!srcMap.IsMapped() || !destMap.IsMapped())) {
    return;
  }

  uint8_t* sourceData = DataAtOffset(aSrc, srcMap.GetMappedSurface(), aSrcRect.TopLeft());
  uint32_t sourceStride = srcMap.GetStride();
  uint8_t* destData = DataAtOffset(aDest, destMap.GetMappedSurface(), aDestPoint);
  uint32_t destStride = destMap.GetStride();

  if (BytesPerPixel(aSrc->GetFormat()) == 4) {
    for (int32_t y = 0; y < aSrcRect.height; y++) {
      PodCopy((int32_t*)destData, (int32_t*)sourceData, aSrcRect.width);
      sourceData += sourceStride;
      destData += destStride;
    }
  } else if (BytesPerPixel(aSrc->GetFormat()) == 1) {
    for (int32_t y = 0; y < aSrcRect.height; y++) {
      PodCopy(destData, sourceData, aSrcRect.width);
      sourceData += sourceStride;
      destData += destStride;
    }
  }
}