/*------------------------------------------------------------------
L E O N A R D O : Statische Linkbibliothek mit Routinen zur
Handhabung von DIBs (Device-Independend-Bitmaps) |
|
im Anwendungsprogramm |
|
(C) 1993-1995 Dipl. Ing. Bernd Herd |
|
Ketteler Str. 35 |
|
68642 Bürstadt |
|
rotate.c: Rotiere Bitmap |
|
------------------------------------------------------------------*/ |
|
#include <windows.h> |
|
#include "Leonardo.h" |
// Headerfile für Anwendungsprogramme |
#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; |
|
} |