270 lines
7.4 KiB
C
270 lines
7.4 KiB
C
/*
|
|
*********************************************************************************************************
|
|
* uC/GUI
|
|
* Universal graphic software for embedded applications
|
|
*
|
|
* (c) Copyright 2002, Micrium Inc., Weston, FL
|
|
* (c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
|
|
*
|
|
* µC/GUI is protected by international copyright laws. Knowledge of the
|
|
* source code may not be used to write a similar product. This file may
|
|
* only be used in accordance with a license and should not be redistributed
|
|
* in any way. We appreciate your understanding and fairness.
|
|
*
|
|
----------------------------------------------------------------------
|
|
File : LCD_RotateCW.c
|
|
Purpose : Implementation of GUI_SetRotation
|
|
---------------------------END-OF-HEADER------------------------------
|
|
*/
|
|
|
|
#include "GUI_Private.h"
|
|
#include "LCD.h"
|
|
#if GUI_WINSUPPORT
|
|
#include "WM.h"
|
|
#endif
|
|
|
|
#if GUI_SUPPORT_ROTATION
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Static code
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
/*********************************************************************
|
|
*
|
|
* _DrawBitLine1BPP
|
|
*/
|
|
static void _DrawBitLine1BPP(int x, int y, U8 const GUI_UNI_PTR *p, int Diff, int xsize, const LCD_PIXELINDEX*pTrans) {
|
|
LCD_PIXELINDEX Index0 = *(pTrans+0);
|
|
LCD_PIXELINDEX Index1 = *(pTrans+1);
|
|
y -= Diff;
|
|
switch (GUI_Context.DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) {
|
|
case 0:
|
|
do {
|
|
LCDDEV_L0_SetPixelIndex(x, y, (*p & (0x80 >> Diff)) ? Index1 : Index0);
|
|
y++;
|
|
if (++Diff == 8) {
|
|
Diff = 0;
|
|
p++;
|
|
}
|
|
} while (--xsize);
|
|
break;
|
|
case LCD_DRAWMODE_TRANS:
|
|
do {
|
|
if (*p & (0x80 >> Diff))
|
|
LCDDEV_L0_SetPixelIndex(x, y, Index1);
|
|
y++;
|
|
if (++Diff == 8) {
|
|
Diff = 0;
|
|
p++;
|
|
}
|
|
} while (--xsize);
|
|
break;
|
|
case LCD_DRAWMODE_XOR:;
|
|
do {
|
|
if (*p & (0x80 >> Diff)) {
|
|
int Pixel = LCD_L0_GetPixelIndex(x, y);
|
|
LCDDEV_L0_SetPixelIndex(x, y, LCD_NUM_COLORS - 1 - Pixel);
|
|
}
|
|
y++;
|
|
if (++Diff == 8) {
|
|
Diff = 0;
|
|
p++;
|
|
}
|
|
} while (--xsize);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* _DrawBitmap
|
|
*
|
|
* Purpose:
|
|
* Draws a bitmap (1bpp) clockwise.
|
|
*/
|
|
static void _DrawBitmap(int x0, int y0,
|
|
int xsize, int ysize,
|
|
int BitsPerPixel,
|
|
int BytesPerLine,
|
|
const U8 GUI_UNI_PTR * pData, int Diff,
|
|
const LCD_PIXELINDEX* pTrans)
|
|
{
|
|
int i;
|
|
/* Use _DrawBitLineXBPP */
|
|
for (i = 0; i < ysize; i++) {
|
|
switch (BitsPerPixel) {
|
|
case 1:
|
|
_DrawBitLine1BPP(x0 - i, y0, pData, Diff, xsize, pTrans);
|
|
break;
|
|
}
|
|
pData += BytesPerLine;
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* _Rect2TextRect
|
|
*
|
|
* Purpose:
|
|
* This function transforms a given rectangle (window coordinates)
|
|
* to the rectangle used to clip the text.
|
|
*/
|
|
static void _Rect2TextRect(GUI_RECT * pRect) {
|
|
int x1, y1;
|
|
x1 = pRect->x1;
|
|
y1 = pRect->y1;
|
|
pRect->x1 = pRect->x0 + (y1 - pRect->y0);
|
|
pRect->y1 = pRect->y0 + (x1 - pRect->x0);
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* _TransformPointCW
|
|
*
|
|
* Purpose:
|
|
* This function transforms an unrotated point (window
|
|
* coordinates) into a rotated point in desktop coordinates
|
|
* and handles the rotation of the current text rectangle.
|
|
*/
|
|
static void _TransformPointCW(int * pXPos, int * pYPos) {
|
|
GUI_RECT ClientRect = {0};
|
|
int xPos, yPos, xNumPixel, yNumPixel;
|
|
/* Get the client rectangle */
|
|
#if GUI_WINSUPPORT
|
|
WM_GetWindowRect(&ClientRect);
|
|
#else
|
|
GUI_GetClientRect(&ClientRect);
|
|
#endif
|
|
xNumPixel = LCD_GetXSize() - 1;
|
|
yNumPixel = LCD_GetYSize() - 1;
|
|
if (ClientRect.x1 > xNumPixel) {
|
|
ClientRect.x1 = xNumPixel;
|
|
}
|
|
if (ClientRect.y1 > yNumPixel) {
|
|
ClientRect.y1 = yNumPixel;
|
|
}
|
|
/* Save old positions */
|
|
xPos = *pXPos;
|
|
yPos = *pYPos;
|
|
/* Rotate and add window origin */
|
|
*pXPos = ClientRect.x0 - yPos;
|
|
*pYPos = ClientRect.y0 + xPos;
|
|
/* Handle rotation of text rectangle */
|
|
*pXPos = *pXPos + GUI_RectDispString.x1 + GUI_RectDispString.y0;
|
|
*pYPos = *pYPos + GUI_RectDispString.y0 - GUI_RectDispString.x0;
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* _DrawBitmapCW
|
|
*/
|
|
static void _DrawBitmapCW(int x0, int y0, int xsize, int ysize, int xMul, int yMul,
|
|
int BitsPerPixel, int BytesPerLine,
|
|
const U8 GUI_UNI_PTR * pPixel, const LCD_PIXELINDEX* pTrans)
|
|
{
|
|
U8 Data = 0;
|
|
int x1, y1;
|
|
/* Handle the optional Y-magnification */
|
|
y1 = y0 + ysize - 1;
|
|
x1 = x0 + xsize - 1;
|
|
/* Rotate positions */
|
|
_TransformPointCW(&x0, &y0);
|
|
_TransformPointCW(&x1, &y1);
|
|
/* Handle BITMAP without magnification */
|
|
if ((xMul == 1) && (yMul == 1)) {
|
|
int Diff = 0;
|
|
/* Clip top */
|
|
if (y1 > GUI_Context.ClipRect.y1) {
|
|
int Diff = y1 - GUI_Context.ClipRect.y1;
|
|
xsize -= Diff;
|
|
}
|
|
/* Clip bottom */
|
|
if (y0 < GUI_Context.ClipRect.y0) {
|
|
Diff = GUI_Context.ClipRect.y1 - y0;
|
|
xsize -= Diff;
|
|
switch (BitsPerPixel) {
|
|
case 1:
|
|
pPixel += (Diff >> 3); y0 -= (Diff >> 3) << 3; Diff &= 7;
|
|
break;
|
|
}
|
|
}
|
|
if (ysize <=0) {
|
|
return;
|
|
}
|
|
/* Clip right side */
|
|
if (x0 > GUI_Context.ClipRect.x1) {
|
|
int Diff = x0 - GUI_Context.ClipRect.x1;
|
|
ysize -= Diff;
|
|
x0 -= Diff;
|
|
pPixel += Diff * BytesPerLine;
|
|
}
|
|
/* Clip left side */
|
|
if (x1 < GUI_Context.ClipRect.x0) {
|
|
int Diff = GUI_Context.ClipRect.x0 - x1;
|
|
x1 += Diff;
|
|
ysize -= Diff;
|
|
}
|
|
if (xsize <= 0) {
|
|
return;
|
|
}
|
|
_DrawBitmap(x0, y0, xsize, ysize, BitsPerPixel, BytesPerLine, pPixel, Diff, pTrans);
|
|
} else {
|
|
/* Handle BITMAP with magnification */
|
|
int x, y, xi, yi;
|
|
int Shift = 8 - BitsPerPixel;
|
|
for (x = x0, xi = 0; xi < ysize; xi++, x -= yMul, pPixel += BytesPerLine) {
|
|
int xMax = x - yMul + 1;
|
|
if ((xMax >= GUI_Context.ClipRect.x0) && (x <= GUI_Context.ClipRect.x1)) {
|
|
int BitsLeft = 0;
|
|
const U8 GUI_UNI_PTR * pDataLine = pPixel;
|
|
for (y = y0, yi = 0; yi < xsize; yi++, y += xMul) {
|
|
U8 Index;
|
|
if (!BitsLeft) {
|
|
Data = *pDataLine++;
|
|
BitsLeft =8;
|
|
}
|
|
Index = Data >> Shift;
|
|
Data <<= BitsPerPixel;
|
|
BitsLeft -= BitsPerPixel;
|
|
if (Index || ((GUI_Context.DrawMode & LCD_DRAWMODE_TRANS) == 0)) {
|
|
LCD_PIXELINDEX OldColor = LCD_COLORINDEX;
|
|
if (pTrans) {
|
|
LCD_COLORINDEX = *(pTrans + Index);
|
|
} else {
|
|
LCD_COLORINDEX = Index;
|
|
}
|
|
LCD_FillRect(xMax, y, x, y + xMul - 1);
|
|
LCD_COLORINDEX = OldColor;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Global data
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
/*********************************************************************
|
|
*
|
|
* LCD_APIListCW
|
|
*
|
|
* Purpose:
|
|
* Function pointer table for rotating text CW
|
|
*/
|
|
tLCD_APIList LCD_APIListCW = {
|
|
(tLCD_DrawBitmap*)&_DrawBitmapCW,
|
|
&_Rect2TextRect
|
|
};
|
|
|
|
#else
|
|
void LCD_RotateCW_C(void);
|
|
void LCD_RotateCW_C(void){}
|
|
#endif
|
|
|