266 lines
7.4 KiB
C
266 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_Rotate180.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);
|
|
x -= Diff;
|
|
switch (GUI_Context.DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) {
|
|
case 0:
|
|
do {
|
|
LCDDEV_L0_SetPixelIndex(x--, y, (*p & (0x80 >> Diff)) ? Index1 : Index0);
|
|
if (++Diff == 8) {
|
|
Diff = 0;
|
|
p++;
|
|
}
|
|
} while (--xsize);
|
|
break;
|
|
case LCD_DRAWMODE_TRANS:
|
|
do {
|
|
if (*p & (0x80 >> Diff))
|
|
LCDDEV_L0_SetPixelIndex(x, y, Index1);
|
|
x--;
|
|
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);
|
|
}
|
|
x--;
|
|
if (++Diff == 8) {
|
|
Diff = 0;
|
|
p++;
|
|
}
|
|
} while (--xsize);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* _DrawBitmap
|
|
*
|
|
* Purpose:
|
|
* Draws a bitmap (1bpp) rotated by 180 degrees.
|
|
*/
|
|
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, y0 - i, 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) {
|
|
GUI_USE_PARA(pRect);
|
|
/* nothing to do in case of rotating text by 180 degrees */
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* _TransformPoint180
|
|
*
|
|
* 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 _TransformPoint180(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;
|
|
/* Handle rotation of text rectangle */
|
|
*pXPos = ClientRect.x0 + GUI_RectDispString.x1 - (xPos - GUI_RectDispString.x0);
|
|
*pYPos = ClientRect.y0 + GUI_RectDispString.y1 - (yPos - GUI_RectDispString.y0);
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* _DrawBitmap180
|
|
*/
|
|
static void _DrawBitmap180(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 */
|
|
_TransformPoint180(&x0, &y0);
|
|
_TransformPoint180(&x1, &y1);
|
|
/* Handle BITMAP without magnification */
|
|
if ((xMul == 1) && (yMul == 1)) {
|
|
int Diff;
|
|
/* Clip top */
|
|
if (y0 > GUI_Context.ClipRect.y1) {
|
|
int Diff = y0 - GUI_Context.ClipRect.y1;
|
|
y0 = GUI_Context.ClipRect.y1;
|
|
pPixel += Diff * BytesPerLine;
|
|
ysize -= Diff;
|
|
}
|
|
/* Clip bottom */
|
|
if (y1 < GUI_Context.ClipRect.y0) {
|
|
int Diff = GUI_Context.ClipRect.y0 - y1;
|
|
ysize -= Diff;
|
|
}
|
|
if (ysize <= 0) {
|
|
return;
|
|
}
|
|
/* Clip right side */
|
|
if (x1 < GUI_Context.ClipRect.x0) {
|
|
int Diff = GUI_Context.ClipRect.x0 - x1;
|
|
xsize -= Diff;
|
|
}
|
|
/* Clip left side */
|
|
Diff = 0;
|
|
if (x0 > GUI_Context.ClipRect.x1) {
|
|
Diff = x0 - GUI_Context.ClipRect.x1;
|
|
xsize -= Diff;
|
|
switch (BitsPerPixel) {
|
|
case 1:
|
|
pPixel += (Diff >> 3); x0 += (Diff >> 3) << 3; Diff &= 7;
|
|
break;
|
|
}
|
|
}
|
|
if (xsize <= 0) {
|
|
return;
|
|
}
|
|
_DrawBitmap(x0, y0, xsize, ysize, BitsPerPixel, BytesPerLine, pPixel, Diff, pTrans);
|
|
} else {
|
|
/* Handle BITMAP with magnification */
|
|
int x, y;
|
|
int yi;
|
|
int Shift = 8 - BitsPerPixel;
|
|
for (y = y0, yi = 0; yi < ysize; yi++, y -= yMul, pPixel += BytesPerLine) {
|
|
int yMax = y + yMul - 1;
|
|
/* Draw if within clip area (Optimization ... "if" is not required !) */
|
|
if ((yMax >= GUI_Context.ClipRect.y0) && (y <= GUI_Context.ClipRect.y1)) {
|
|
int BitsLeft = 0;
|
|
int xi;
|
|
const U8 GUI_UNI_PTR * pDataLine = pPixel;
|
|
for (x = x0, xi = 0; xi < xsize; xi++, x -= 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(x - xMul + 1, y, x, yMax);
|
|
LCD_COLORINDEX = OldColor;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Global data
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
/*********************************************************************
|
|
*
|
|
* LCD_APIList180
|
|
*
|
|
* Purpose:
|
|
* Function pointer table for rotating text 180
|
|
*/
|
|
tLCD_APIList LCD_APIList180 = {
|
|
(tLCD_DrawBitmap*)&_DrawBitmap180,
|
|
&_Rect2TextRect
|
|
};
|
|
|
|
#else
|
|
void LCD_Rotate180_C(void);
|
|
void LCD_Rotate180_C(void){}
|
|
#endif
|
|
|