rotateSurface90Degrees function

Pointer<SdlSurface> rotateSurface90Degrees(
  1. Pointer<SdlSurface> src,
  2. int numClockwiseTurns
)

Implementation

Pointer<SdlSurface> rotateSurface90Degrees(
  Pointer<SdlSurface> src,
  int numClockwiseTurns,
) {
  int row;
  int col;
  int newWidth;
  int newHeight;
  int bpp;
  int bpr;
  Pointer<SdlSurface> dst;
  int normalizedClockwiseTurns;
  /* Has to be a valid surface pointer and be a Nbit surface where n is divisible by 8 */
  if (src == nullptr) {
    print('NULL source surface');
    return nullptr;
  }
  final details = sdlGetPixelFormatDetails(src.ref.format);
  if (details == nullptr) {
    print('NULL source surface format');
    return nullptr;
  }
  if ((details.ref.bitsPerPixel % 8) != 0) {
    //  if ((src.ref.format.ref.bitsPerPixel % 8) != 0) {
    print('Invalid source surface bit depth');
    return nullptr;
  }

  /* normalize numClockwiseTurns */
  normalizedClockwiseTurns = numClockwiseTurns % 4;
  if (normalizedClockwiseTurns < 0) {
    normalizedClockwiseTurns += 4;
  }

  /* If turns are even, our new width/height will be the same as the source surface */
  if (normalizedClockwiseTurns % 2 != 0) {
    newWidth = src.ref.h;
    newHeight = src.ref.w;
  } else {
    newWidth = src.ref.w;
    newHeight = src.ref.h;
  }
  dst = sdlCreateSurface(newWidth, newHeight, 0);
  //dst = sdlCreateRgbSurface(
  //    src.ref.flags,
  //    newWidth,
  //    newHeight,
  //    src.ref.format.ref.bitsPerPixel,
  //    src.ref.format.ref.rmask,
  //    src.ref.format.ref.gmask,
  //    src.ref.format.ref.bmask,
  //    src.ref.format.ref.amask);
  if (dst == nullptr) {
    print('Could not create destination surface');
    return nullptr;
  }

  //if (SDL_MUSTLOCK(src)) {
  sdlLockSurface(src);
  //}
  //if (SDL_MUSTLOCK(dst)) {
  sdlLockSurface(dst);
  //}

  /* Calculate byte-per-pixel */
  bpp = details.ref.bitsPerPixel ~/ 8;
  //  bpp = src.ref.format.ref.bitsPerPixel ~/ 8;

  final srcBuf = calloc<Pointer<Uint8>>();
  final dstBuf = calloc<Pointer<Uint8>>();

  print(normalizedClockwiseTurns);
  switch (normalizedClockwiseTurns) {
    case 0: /* Make a copy of the surface */
      {
        /* Unfortunately SDL_BlitSurface cannot be used to make a copy of the surface
			since it does not preserve alpha. */

        if (src.ref.pitch == dst.ref.pitch) {
          /* If the pitch is the same for both surfaces, the memory can be copied all at once. */
          sdlMemcpy(dst.ref.pixels, src.ref.pixels, src.ref.h * src.ref.pitch);
        } else {
          /* If the pitch differs, copy each row separately */
          srcBuf.value = src.ref.pixels.cast<Uint8>();
          dstBuf.value = dst.ref.pixels.cast<Uint8>();
          bpr = src.ref.w * bpp;
          for (row = 0; row < src.ref.h; row++) {
            sdlMemcpy(dstBuf.value, srcBuf.value, bpr);
            srcBuf.value = srcBuf.value + src.ref.pitch;
            dstBuf.value = dstBuf.value + dst.ref.pitch;
          }
        }
      }

    /* rotate clockwise */
    case 1: /* rotated 90 degrees clockwise */
      {
        for (row = 0; row < src.ref.h; ++row) {
          srcBuf
            ..value = src.ref.pixels.cast<Uint8>()
            ..value = srcBuf.value + row * src.ref.pitch;
          dstBuf
            ..value = dst.ref.pixels.cast<Uint8>()
            ..value = dstBuf.value + (dst.ref.w - row - 1) * bpp;
          for (col = 0; col < src.ref.w; ++col) {
            sdlMemcpy(dstBuf.value, srcBuf.value, bpp);
            srcBuf.value = srcBuf.value + bpp;
            dstBuf.value = dstBuf.value + dst.ref.pitch;
          }
        }
      }

    case 2: /* rotated 180 degrees clockwise */
      {
        for (row = 0; row < src.ref.h; ++row) {
          srcBuf
            ..value = src.ref.pixels.cast<Uint8>()
            ..value = srcBuf.value + row * src.ref.pitch;
          dstBuf
            ..value = dst.ref.pixels.cast<Uint8>()
            ..value =
                dstBuf.value +
                (dst.ref.h - row - 1) * dst.ref.pitch +
                (dst.ref.w - 1) * bpp;
          for (col = 0; col < src.ref.w; ++col) {
            sdlMemcpy(dstBuf.value, srcBuf.value, bpp);
            srcBuf.value = srcBuf.value + bpp;
            dstBuf.value = dstBuf.value - bpp;
          }
        }
      }

    case 3: /* rotated 270 degrees clockwise */
      {
        for (row = 0; row < src.ref.h; ++row) {
          srcBuf
            ..value = src.ref.pixels.cast<Uint8>()
            ..value = srcBuf.value + row * src.ref.pitch;
          dstBuf
            ..value = dst.ref.pixels.cast<Uint8>()
            ..value =
                dstBuf.value + (row * bpp) + ((dst.ref.h - 1) * dst.ref.pitch);
          for (col = 0; col < src.ref.w; ++col) {
            sdlMemcpy(dstBuf.value, srcBuf.value, bpp);
            srcBuf.value = srcBuf.value + bpp;
            dstBuf.value = dstBuf.value - dst.ref.pitch;
          }
        }
      }
  }
  /* end switch */

  //if (SDL_MUSTLOCK(src)) {
  sdlUnlockSurface(src);
  //}
  //if (SDL_MUSTLOCK(dst)) {
  sdlUnlockSurface(dst);
  //}
  calloc
    ..free(srcBuf)
    ..free(dstBuf);
  return dst;
}