Herd Software Development
DaVinci Graphics Library
DaVinci Documentation
Simplified source code for RotateDIB/*------------------------------------------------------------------
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;
}