416 lines
10 KiB
C
416 lines
10 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.c
|
|
Purpose : Link between GUI and LCD_L0
|
|
Performs most of the clipping.
|
|
---------------------------END-OF-HEADER------------------------------
|
|
*/
|
|
|
|
#define LCD_C
|
|
|
|
#include <stdio.h>
|
|
#include "GUI_Private.h"
|
|
#include "LCD_Private.h"
|
|
#include "GUIDebug.h"
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Defines
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
|
|
#define RETURN_IF_Y_OUT() \
|
|
if (y < GUI_Context.ClipRect.y0) \
|
|
return; \
|
|
if (y > GUI_Context.ClipRect.y1) \
|
|
return;
|
|
|
|
#define RETURN_IF_X_OUT() \
|
|
if (x < GUI_Context.ClipRect.x0) \
|
|
return; \
|
|
if (x > GUI_Context.ClipRect.x1) \
|
|
return;
|
|
|
|
#define CLIP_X() \
|
|
if (x0 < GUI_Context.ClipRect.x0) \
|
|
{ \
|
|
x0 = GUI_Context.ClipRect.x0; \
|
|
} \
|
|
if (x1 > GUI_Context.ClipRect.x1) \
|
|
{ \
|
|
x1 = GUI_Context.ClipRect.x1; \
|
|
}
|
|
|
|
#define CLIP_Y() \
|
|
if (y0 < GUI_Context.ClipRect.y0) \
|
|
{ \
|
|
y0 = GUI_Context.ClipRect.y0; \
|
|
} \
|
|
if (y1 > GUI_Context.ClipRect.y1) \
|
|
{ \
|
|
y1 = GUI_Context.ClipRect.y1; \
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Static code
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
/*********************************************************************
|
|
*
|
|
* _GetColorIndex
|
|
*/
|
|
static int _GetColorIndex(int i) /* i is 0 or 1 */
|
|
{
|
|
return (GUI_Context.DrawMode & LCD_DRAWMODE_REV) ? i - 1 : i;
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Public code
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
/*********************************************************************
|
|
*
|
|
* LCD_SetColorIndex
|
|
*/
|
|
void LCD_SetColorIndex(int Index)
|
|
{
|
|
LCD_ACOLORINDEX[_GetColorIndex(1)] = Index;
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* LCD_SetBkColorIndex
|
|
*/
|
|
void LCD_SetBkColorIndex(int Index)
|
|
{
|
|
LCD_ACOLORINDEX[_GetColorIndex(0)] = Index;
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* LCD_SetDrawMode
|
|
*/
|
|
LCD_DRAWMODE LCD_SetDrawMode(LCD_DRAWMODE dm)
|
|
{
|
|
LCD_DRAWMODE OldDM = GUI_Context.DrawMode;
|
|
if ((GUI_Context.DrawMode ^ dm) & LCD_DRAWMODE_REV)
|
|
{
|
|
LCD_PIXELINDEX temp = LCD_BKCOLORINDEX;
|
|
LCD_BKCOLORINDEX = LCD_COLORINDEX;
|
|
LCD_COLORINDEX = temp;
|
|
}
|
|
GUI_Context.DrawMode = dm;
|
|
return OldDM;
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* LCD_DrawPixel
|
|
*/
|
|
void LCD_DrawPixel(int x, int y)
|
|
{
|
|
RETURN_IF_Y_OUT();
|
|
RETURN_IF_X_OUT();
|
|
if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR)
|
|
{
|
|
LCDDEV_L0_XorPixel(x, y);
|
|
}
|
|
else
|
|
{
|
|
LCDDEV_L0_SetPixelIndex(x, y, LCD_COLORINDEX);
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* LCD_DrawHLine
|
|
*/
|
|
void LCD_DrawHLine(int x0, int y, int x1)
|
|
{
|
|
/* Perform clipping and check if there is something to do */
|
|
RETURN_IF_Y_OUT();
|
|
CLIP_X();
|
|
if (x1 < x0)
|
|
return;
|
|
/* Call driver to draw */
|
|
LCDDEV_L0_DrawHLine(x0, y, x1);
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* LCD_FillRect
|
|
*/
|
|
void LCD_FillRect(int x0, int y0, int x1, int y1)
|
|
{
|
|
/* Perform clipping and check if there is something to do */
|
|
CLIP_X();
|
|
if (x1 < x0)
|
|
return;
|
|
CLIP_Y();
|
|
if (y1 < y0)
|
|
return;
|
|
/* Call driver to draw */
|
|
LCDDEV_L0_FillRect(x0, y0, x1, y1);
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* LCD_DrawBitmap
|
|
*/
|
|
void LCD_DrawBitmap(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 rotation if necessary */
|
|
#if GUI_SUPPORT_ROTATION
|
|
if (GUI_pLCD_APIList)
|
|
{
|
|
GUI_pLCD_APIList->pfDrawBitmap(x0, y0, xsize, ysize, xMul, yMul, BitsPerPixel, BytesPerLine, pPixel, pTrans);
|
|
return;
|
|
}
|
|
#endif
|
|
/* Handle the optional Y-magnification */
|
|
y1 = y0 + ysize - 1;
|
|
x1 = x0 + xsize - 1;
|
|
/* Handle BITMAP without magnification */
|
|
if ((xMul | yMul) == 1)
|
|
{
|
|
int Diff;
|
|
/* Clip y0 (top) */
|
|
Diff = GUI_Context.ClipRect.y0 - y0;
|
|
if (Diff > 0)
|
|
{
|
|
ysize -= Diff;
|
|
if (ysize <= 0)
|
|
{
|
|
return;
|
|
}
|
|
y0 = GUI_Context.ClipRect.y0;
|
|
#if GUI_SUPPORT_LARGE_BITMAPS /* Required only for 16 bit CPUs if some bitmaps are >64kByte */
|
|
pPixel += (U32)Diff * (U32)BytesPerLine;
|
|
#else
|
|
pPixel += (unsigned)Diff * (unsigned)BytesPerLine;
|
|
#endif
|
|
}
|
|
/* Clip y1 (bottom) */
|
|
Diff = y1 - GUI_Context.ClipRect.y1;
|
|
if (Diff > 0)
|
|
{
|
|
ysize -= Diff;
|
|
if (ysize <= 0)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
/* Clip right side */
|
|
Diff = x1 - GUI_Context.ClipRect.x1;
|
|
if (Diff > 0)
|
|
{
|
|
xsize -= Diff;
|
|
}
|
|
/* Clip left side ... (The difficult side ...) */
|
|
Diff = 0;
|
|
if (x0 < GUI_Context.ClipRect.x0)
|
|
{
|
|
Diff = GUI_Context.ClipRect.x0 - x0;
|
|
xsize -= Diff;
|
|
switch (BitsPerPixel)
|
|
{
|
|
case 1:
|
|
pPixel += (Diff >> 3);
|
|
x0 += (Diff >> 3) << 3;
|
|
Diff &= 7;
|
|
break;
|
|
case 2:
|
|
pPixel += (Diff >> 2);
|
|
x0 += (Diff >> 2) << 2;
|
|
Diff &= 3;
|
|
break;
|
|
case 4:
|
|
pPixel += (Diff >> 1);
|
|
x0 += (Diff >> 1) << 1;
|
|
Diff &= 1;
|
|
break;
|
|
case 8:
|
|
pPixel += Diff;
|
|
x0 += Diff;
|
|
Diff = 0;
|
|
break;
|
|
case 16:
|
|
pPixel += (Diff << 1);
|
|
x0 += Diff;
|
|
Diff = 0;
|
|
break;
|
|
}
|
|
}
|
|
if (xsize <= 0)
|
|
{
|
|
return;
|
|
}
|
|
LCDDEV_L0_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, y, x + xMul - 1, yMax);
|
|
LCD_COLORINDEX = OldColor;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* LCD_SetClipRectMax
|
|
*/
|
|
void LCD_SetClipRectMax(void)
|
|
{
|
|
LCDDEV_L0_GetRect(&GUI_Context.ClipRect);
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* LCD_Init
|
|
*/
|
|
int LCD_Init(void)
|
|
{
|
|
int r = 0;
|
|
GUI_DEBUG_LOG("\nLCD_Init...");
|
|
LCD_SetClipRectMax();
|
|
r |= LCD_L0_Init();
|
|
#if GUI_NUM_LAYERS > 1
|
|
r |= LCD_L0_1_Init();
|
|
#endif
|
|
#if GUI_NUM_LAYERS > 2
|
|
r |= LCD_L0_2_Init();
|
|
#endif
|
|
#if GUI_NUM_LAYERS > 3
|
|
r |= LCD_L0_3_Init();
|
|
#endif
|
|
#if GUI_NUM_LAYERS > 4
|
|
r |= LCD_L0_4_Init();
|
|
#endif
|
|
LCD_InitLUT();
|
|
{
|
|
#if GUI_NUM_LAYERS > 1
|
|
int i;
|
|
for (i = GUI_NUM_LAYERS - 1; i >= 0; i--)
|
|
{
|
|
GUI_SelectLayer(i);
|
|
#else
|
|
{
|
|
#endif
|
|
#if (GUI_DEFAULT_BKCOLOR != GUI_INVALID_COLOR)
|
|
/* Clear video memory */
|
|
LCD_SetDrawMode(GUI_DRAWMODE_REV);
|
|
// LCD_FillRect(0,0, GUI_XMAX, GUI_YMAX); // xsh:??????????????????
|
|
LCD_SetDrawMode(0);
|
|
#endif
|
|
}
|
|
}
|
|
/* Switch LCD on */
|
|
LCD_On();
|
|
return r;
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* LCD_Color2Index
|
|
*/
|
|
int LCD_Color2Index(LCD_COLOR Color)
|
|
{
|
|
return LCDDEV_L0_Color2Index(Color);
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* LCD_Index2Color
|
|
*/
|
|
LCD_COLOR LCD_Index2Color(int Index)
|
|
{
|
|
return LCDDEV_L0_Index2Color(Index);
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* LCD_SetBkColor
|
|
*/
|
|
void LCD_SetBkColor(GUI_COLOR color)
|
|
{
|
|
if (GUI_Context.BkColor != color)
|
|
{
|
|
GUI_Context.BkColor = color;
|
|
LCD_SetBkColorIndex(LCD_Color2Index(color));
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* LCD_SetColor
|
|
*/
|
|
void LCD_SetColor(GUI_COLOR color)
|
|
{
|
|
if (GUI_Context.Color != color)
|
|
{
|
|
GUI_Context.Color = color;
|
|
LCD_SetColorIndex(LCD_Color2Index(color));
|
|
}
|
|
}
|
|
|
|
/*************************** End of file ****************************/
|