| Herd Software Development
|=
DaVinci Graphics Library
|==
DaVinci Documentation Home Search Order


Simplified source code for RotateDIB

Source includes a sample callback implementation to show how the function can be applied.
/*------------------------------------------------------------------
      L E O N A R D O : Statische Linkbibliothek mit Routinen zur
			Handhabung von DIBs (Device-Independend-Bitmaps)
			im Anwendungsprogramm
	  (C) 1993-1998	Dipl. Ing. Bernd Herd
			Rudolf-Virchow-Str. 8
			68642 Bürstadt
	rotate.c:  	Rotiere Bitmap
  ------------------------------------------------------------------*/
#include <windows.h>
#include "Leonardo.h"			// Headerfile for applications
#include "Leonardi.h"			// Bibliotheksinterner Headerfile
#pragma hdrstop
#include <string.h>
#include <math.h>
#define SCALE 10000
#define PI 3.141592655

// ---------- Übergabedaten Callback --------------------
typedef struct {
	RECT rc;			// Lage des Ziel-Rechtecks im Quell-Rechteck
	int  sinval, cosval;		// Sinus und Cosinus des Drehwinkels
	} ROTPARAM;

BOOL CALLBACK RotateCallback(UINT msg, LPPOINT lppt, LONG lParam)
{ ROTPARAM FAR *rtp = (ROTPARAM FAR *) lParam;
  POINT         pt;
  if (msg == TRFM_PIXEL) {
     pt  = *lppt;
     pt.x += rtp->rc.left;
     pt.y += rtp->rc.bottom;
/*     pt.y = (int) ((fabs(sin(pt.y * PI/2 / (rtp->rc.top-rtp->rc.bottom) )) * (rtp->rc.top  -rtp->rc.bottom)));
     pt.x = (int) ((fabs(cos(pt.x * PI/2 / (rtp->rc.right-rtp->rc.left) )) * (rtp->rc.right-rtp->rc.left  ))); */
     lppt->x = MulDiv(pt.x,  rtp->cosval, SCALE) + MulDiv(pt.y, rtp->sinval, SCALE);
     lppt->y = MulDiv(pt.x, -rtp->sinval, SCALE) + MulDiv(pt.y, rtp->cosval, SCALE);
  }
  return TRUE;
}


/* RotateDIB -------------------------------------------------------------
   Erzeugt eine neue DIB gleichen Aufbaus die eine gedrehte Darstellung
   der übergebenen DIB enthält. Benutzt DIBTransform
   hdib  : Handle der zu drehenden DIB
   Angle : Winkel in 1/10 Grad, Positiv für Linksdrehung 
   RückGabe  : NULL	         Wenn erfolglos
	       hDIB		 Wenn erfolgreich
  -------------------------------------------------------------------------*/
HDIB API RotateDIB(HDIB hdib, int Angle, COLORREF clBkColor)
{ LPBITMAPINFOHEADER lpbmi;
  HDIB		     hnewdib=NULL;
  UINT		     Width, Height;
  POINT		     rect[4];
  int		     sinval = (int) (sin(Angle * (PI / 180.0 / 10.0)) * SCALE),
		     cosval = (int) (cos(Angle * (PI / 180.0 / 10.0)) * SCALE);
  int 		     i;
  POINT 	     pt;
  RECT		     rc;
  ROTPARAM	     rtp;
  if (NULL != hdib &&
      NULL != (lpbmi = (LPBITMAPINFOHEADER) GlobalLock(hdib) )
     ) {
     Width = (int) lpbmi->biWidth;
     Height= (int) lpbmi->biHeight;
     // --------- Berechnen gedrehte Randkoordinaten ----------
     rect[0].x =                         rect[3].x =
     rect[0].y = rect[1].y = 0;
		 rect[1].x = rect[2].x =	     Width -1;
			     rect[2].y = rect[3].y = Height-1;
     SetRect(&rc, 32767, -32767, -32767, 32767);
     for (i=0; i<4; ++i) {
       pt.x = MulDiv(rect[i].x, cosval, SCALE) + MulDiv(rect[i].y, -sinval, SCALE);
       pt.y = MulDiv(rect[i].x, sinval, SCALE) + MulDiv(rect[i].y,  cosval, SCALE);
       rect[i] = pt;
       // --------- Neue Bitmapgröße und- Lage ------------------
       if (pt.x < rc.left)  rc.left =pt.x;
       if (pt.x > rc.right) rc.right=pt.x;
       if (pt.y < rc.bottom)rc.bottom=pt.y;
       if (pt.y > rc.top)   rc.top   =pt.y;
     }
     // ----------- Erzeuge DIB der neuen Größe ---------------
     hnewdib = CreateCompatibleDIB(hdib, rc.right-rc.left, rc.top-rc.bottom);
     if (hnewdib) {
	rtp.rc     = rc;
	rtp.sinval = sinval;
	rtp.cosval = cosval;
	TransformDIB(hdib, hnewdib, RotateCallback, NULL, (LPARAM) (LPSTR) &rtp, clBkColor);
     }
     GlobalUnlock(hdib);
  }
  return hnewdib;
}