A BitBlt-Like Function With Rotation Angle: ROTBlt

Environment: Visual C++

Description

RotBlt is a function that works like BitBlt. It's different in that it has an additional param theta which is the angle in degrees by which the source DC is rotated when blitted onto the destination.

I wrote this in about 10 minutes, out of which I spent about 6 creating the Win32 app to test the code. So it is slow. (It took 1 second to rotate a 150x150x16bpp DC on a 333MHz Celeron.)

So if you wanted to rotate 1024x768x32 bits, umm, well....

Besides, I wrote this because I saw Hans Buhler's 90 degree rotate dc code which I assume has some issues with Win 95/98 and that seems to be for buttons and stuff. And then, why just 90 degrees??? Why not 3.635 degrees?

So, here's rotblt.

This is the code that generated this image.

  Rectangle (memDC,50,50,100,100);

  BitBlt(dc, 0,0,150,150,memDC,0,0,SRCAND);
  RotBlt(dc, 0,0,150,150,memDC,200,0, 45, SRCAND);

  TextOut(dc, 0,140,"BitBlt",strlen("BitBlt"));
  TextOut(dc, 200,140,"RotBlt 45 degs",strlen("RotBlt 45 degs"));



Function  : RotBlt
Parameters :
  HDC destDC, //destDC onto which to perform blt operation
  int srcx1,  //start x coordinate of src DC
  int srcy1,  //start y coordinate of src DC
  int srcx2,  //end x coordinate of src DC
              //remember this isn't width
  int srcy2,  //end y coordinate of src DC
              //remember this isn't height
  HDC srcDC , //srcDC
  int destx1, //left Xcoordinate of destDC where rotated DC will
              //be blt (top -left)
  int desty1 ,//top Ycoordinate of destDC where rotated DC will
              //be blt (top - left)
  int thetaInDegrees , // angle in degrees in which to rotate srcDC
  DWORD mode  //ROp code same as Bitblt


Return value : NULL

Body :

void RotBlt(HDC destDC, int srcx1, int srcy1, int srcx2, int srcy2,
  HDC srcDC , int destx1, int desty1 ,int thetaInDegrees ,DWORD mode)
{
  double theta = thetaInDegrees * (3.14159/180);
  //multiply degrees by PI/180 to convert to radians

  //determine width and height of source
  int width = srcx2 - srcx1;
  int height = srcy2 - srcy1;

  //determine centre/pivot point ofsource
  int centreX = int(float(srcx2 + srcx1)/2);
  int centreY = int(float(srcy2 + srcy1)/2);

  //since image is rotated we need to allocate a rectangle
  //which can hold the image in any orientation
  if(width>height)height = width;
  else
    width = height;


  //allocate memory and blah blah
  HDC memDC = CreateCompatibleDC(destDC);
  HBITMAP memBmp = CreateCompatibleBitmap(destDC, width, height);

  HBITMAP obmp = (HBITMAP) SelectObject(memDC, memBmp);

  //pivot point of our mem DC
  int newCentre = int(float(width)/2);

  //hmmm here's the rotation code. X std maths :|
  for(int x = srcx1; x<=srcx2; x++)
    for(int y = srcy1; y<=srcy2; y++)
    {
      COLORREF col = GetPixel(srcDC,x,y);

      int newX = int((x-centreX)*sin(theta)+(y-centreY)*cos(theta));
      int newY = int((x-centreX)*cos(theta)-(y-centreY)*sin(theta));


      SetPixel(memDC , newX + newCentre, newY + newCentre, col);
    }

  //splash onto the destination
  BitBlt(destDC, destx1, desty1, width, height, memDC, 0,0,mode);


  //free mem and blah
  SelectObject(memDC, obmp);

  DeleteDC(memDC);
  DeleteObject(memBmp);
}