281 lines
7.9 KiB
C
281 lines
7.9 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 : GUIAALib.C
|
|
Purpose : Antialiasing library
|
|
---------------------------END-OF-HEADER------------------------------
|
|
*/
|
|
|
|
#include "GUI_Private.h"
|
|
#include "LCD_ConfDefaults.h" /* Required in order to know max. XSize so we do not waste memory */
|
|
|
|
#if GUI_SUPPORT_AA
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Defines, config defaults
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
|
|
#ifndef GUI_AA_LINEBUFFER_SIZE
|
|
#define GUI_AA_LINEBUFFER_SIZE LCD_XSIZE
|
|
#endif
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Static data
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
|
|
static U8 abAABuffer[GUI_AA_LINEBUFFER_SIZE]; /* This could be changed to dynamic memory ... */
|
|
static U8* pabAABuffer;
|
|
static int _x0, _x1, _y, _x0_InUse, _x1_InUse;
|
|
static GUI_RECT ClipRect_HL;
|
|
|
|
static tLCD_HL_APIList DrawAPICopy; /* Copy of device function ptr list */
|
|
static const tLCD_HL_APIList* pLCD_HLPrev; /* Copy of device function ptr list */
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Static code
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
/*********************************************************************
|
|
*
|
|
* _CleanLine
|
|
*/
|
|
static void _CleanLine(void) {
|
|
GUI_MEMSET(pabAABuffer,0, _x1 - _x0+1);
|
|
_y = -16383; /* Invalidate */
|
|
_x0_InUse = 16383;
|
|
_x1_InUse = -16383;
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* _FlushLine
|
|
*/
|
|
static void _FlushLine(void) {
|
|
int i;
|
|
int iEnd = _x1_InUse-_x0;
|
|
int IMax = GUI_Context.AA_Factor * GUI_Context.AA_Factor;
|
|
for (i =_x0_InUse-_x0; i<=iEnd; i++) {
|
|
int Intens = *(pabAABuffer+i);
|
|
if (Intens) {
|
|
/* Check we can use line draw */
|
|
if (Intens == IMax) {
|
|
int j;
|
|
for (j=i; j<iEnd; ) {
|
|
if (*(pabAABuffer+j+1) != IMax) {
|
|
break;
|
|
}
|
|
j++;
|
|
}
|
|
/* Draw the full pixel(s) */
|
|
if (j!=i) {
|
|
pLCD_HLPrev->pfDrawHLine(_x0+i, _y, _x0+j);
|
|
i = j; /*xxx*/
|
|
} else {
|
|
LCD_HL_DrawPixel (_x0+i,_y);
|
|
}
|
|
} else {
|
|
LCD_SetPixelAA(_x0+i,_y, (15*Intens+IMax/2)/IMax);
|
|
}
|
|
}
|
|
}
|
|
_CleanLine();
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* _DrawHLine
|
|
*
|
|
* Purpose:
|
|
* This is the redirected DrawHLine routine which is called
|
|
* instead of the default output routine. Its job is to do
|
|
* antialiasing and then perform the drawing operations.
|
|
*/
|
|
static void _DrawHLine (int x0, int y, int x1) {
|
|
int x0Real, x1Real;
|
|
/* Make sure there is something to do */
|
|
if (x1<x0)
|
|
return;
|
|
/* Flush line if we are in an other pixel (real) line */
|
|
if (y/GUI_Context.AA_Factor != _y) {
|
|
_FlushLine();
|
|
_y = y/GUI_Context.AA_Factor;
|
|
}
|
|
x0Real = x0/GUI_Context.AA_Factor;
|
|
x1Real = x1/GUI_Context.AA_Factor;
|
|
/* Handle used area (speed optimization for drawing) */
|
|
if (x0Real < _x0_InUse)
|
|
_x0_InUse = x0Real;
|
|
if (x1Real > _x1_InUse)
|
|
_x1_InUse = x1Real;
|
|
/* Clip (should not be necessary ... Just to be on the safe side ! */
|
|
if (x0Real < _x0) {
|
|
x0 = _x0 * GUI_Context.AA_Factor;
|
|
}
|
|
if (x1Real > _x1) {
|
|
x1 = (_x1+1)*GUI_Context.AA_Factor-1;
|
|
}
|
|
/* Make sure there is still something to do (after clipping) */
|
|
if (x1<x0)
|
|
return;
|
|
/* Inc. hit counters in buffer */
|
|
{
|
|
int x0_Off = x0/GUI_Context.AA_Factor-_x0;
|
|
int x1_Off = x1/GUI_Context.AA_Factor-_x0;
|
|
int iRem = x1_Off-x0_Off+1;
|
|
U8 *pDest = pabAABuffer+x0_Off;
|
|
if (iRem ==1) {
|
|
*(pDest) += x1-x0+1;
|
|
} else {
|
|
/* First Pixel */
|
|
*pDest++ += ((x0_Off+_x0+1)*GUI_Context.AA_Factor-x0);
|
|
/* Middle Pixels */
|
|
for (;--iRem>1; ) {
|
|
*pDest++ +=GUI_Context.AA_Factor;
|
|
}
|
|
/* Last Pixel */
|
|
*pDest += (1+x1- (x1_Off+_x0) *GUI_Context.AA_Factor);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* CalcClipRectHL
|
|
*/
|
|
static void CalcClipRectHL(void) {
|
|
ClipRect_HL.x0 = GUI_Context.ClipRect.x0 * GUI_Context.AA_Factor;
|
|
ClipRect_HL.y0 = GUI_Context.ClipRect.y0 * GUI_Context.AA_Factor;
|
|
ClipRect_HL.x1 = (GUI_Context.ClipRect.x1+1) * GUI_Context.AA_Factor -1;
|
|
ClipRect_HL.y1 = (GUI_Context.ClipRect.y1+1) * GUI_Context.AA_Factor -1;
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Public code
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
/*********************************************************************
|
|
*
|
|
* GUI_AA_Init
|
|
*/
|
|
int GUI_AA_Init(int x0, int x1) {
|
|
int r =0;
|
|
/* Bounds checking:
|
|
Make sure x0, x1 are in legal range ...
|
|
(The important point is that they span no more than configured as
|
|
buffer size)
|
|
*/
|
|
if (x0<0)
|
|
x0 =0;
|
|
if (x1-x0 > GUI_AA_LINEBUFFER_SIZE-1)
|
|
x1 = x0+GUI_AA_LINEBUFFER_SIZE-1;
|
|
/* Is there anything to do at all ??? */
|
|
if (x1 < x0) {
|
|
x1 = x0; /* Not really ... */
|
|
r =1;
|
|
}
|
|
DrawAPICopy = *GUI_Context.pLCD_HL; /* Copy API table */
|
|
pLCD_HLPrev = GUI_Context.pLCD_HL; /* Remember list ptr (for restore) */
|
|
DrawAPICopy.pfDrawHLine = _DrawHLine; /* modify function ptr. for hline */
|
|
GUI_Context.pLCD_HL = &DrawAPICopy; /* Use copy of fp-list */
|
|
pabAABuffer = abAABuffer;
|
|
_x0 = x0;
|
|
_x1 = x1;
|
|
_CleanLine();
|
|
CalcClipRectHL();
|
|
GUI_Context.pClipRect_HL = &ClipRect_HL;
|
|
return r;
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* GUI_AA_Init_HiRes
|
|
*/
|
|
int GUI_AA_Init_HiRes(int x0, int x1) {
|
|
x0 /= GUI_Context.AA_Factor;
|
|
x1 /= GUI_Context.AA_Factor;
|
|
return GUI_AA_Init(x0, x1);
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* GUI_AA_SetFactor
|
|
*/
|
|
void GUI_AA_SetFactor(int Factor) {
|
|
GUI_Context.AA_Factor = Factor;
|
|
CalcClipRectHL(); /* High level clipping depends on quality factor */
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* GUI_AA_GetFactor
|
|
*/
|
|
int GUI_AA_GetFactor(void) {
|
|
return GUI_Context.AA_Factor;
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* GUI_AA_DisableHiRes
|
|
*/
|
|
void GUI_AA_DisableHiRes(void) {
|
|
GUI_Context.AA_HiResEnable = 0;
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* GUI_AA_EnableHiRes
|
|
*/
|
|
void GUI_AA_EnableHiRes(void) {
|
|
GUI_Context.AA_HiResEnable =1;
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* GUI_AA_HiRes2Pixel
|
|
*/
|
|
I16 GUI_AA_HiRes2Pixel(int HiRes) {
|
|
return GUI_Context.AA_Factor ? (HiRes / GUI_Context.AA_Factor) : HiRes;
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* GUI_AA_Exit
|
|
*/
|
|
void GUI_AA_Exit(void) {
|
|
_FlushLine();
|
|
/* restore previous settings */
|
|
GUI_Context.pLCD_HL = pLCD_HLPrev;
|
|
GUI_Context.pClipRect_HL = &GUI_Context.ClipRect;
|
|
}
|
|
|
|
#else /* Avoid problems with empty object modules */
|
|
void GUIAALib_C(void);
|
|
void GUIAALib_C(void) {}
|
|
#endif /* GUI_SUPPORT_AA */
|
|
|
|
/*************************** End of file ****************************/
|