/* ********************************************************************************************************* * 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 #include /********************************************************************* * * 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; jpfDrawHLine(_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 _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 (x11; ) { *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 ****************************/