/********************************************************************* * * _Draw */ static void _Draw(void) { int x, y, xSize, ySize; LCD_PIXELINDEX* pData; const GUI_BITMAP GUI_UNI_PTR * pBM; GUI_LOCK(); if (_hBuffer) { /* Save bitmap data */ pBM = _pCursor->pBitmap; pData = (LCD_PIXELINDEX*)GUI_ALLOC_h2p(_hBuffer); xSize = _Rect.x1 - _Rect.x0 + 1; ySize = _Rect.y1 - _Rect.y0 + 1; for (y = 0; y < ySize; y++) { for (x = 0; x < xSize; x++) { int BitmapPixel; *(pData + x) = _GetPixelIndex(_Rect.x0 + x, _Rect.y0 + y); BitmapPixel = GUI_GetBitmapPixelIndex(pBM, x, y); if (BitmapPixel) { _SetPixelIndex(_Rect.x0 + x, _Rect.y0 + y, _Log2Phys(BitmapPixel)); } } pData += pBM->XSize; } } GUI_UNLOCK(); }
/********************************************************************* * * GL_DrawBitmapEx */ static void GL_DrawBitmapEx(const GUI_BITMAP GUI_UNI_PTR * pBitmap, int x0, int y0, int xCenter, int yCenter, int xMag, int yMag) { LCD_PIXELINDEX Index, IndexPrev = 0; LCD_COLOR Color; int x, y, xi, yi, xSize, ySize, xAct, xStart, xMagAbs, xiMag, yMin, yMax, yEnd, yPrev, yStep; char Cached, HasTrans = 0; /* Use clipping rect to reduce calculation */ yMin = GUI_Context.ClipRect.y0; yMax = GUI_Context.ClipRect.y1; /* Init some values */ xSize = pBitmap->XSize; ySize = pBitmap->YSize; xMagAbs = ((xMag < 0) ? -xMag : xMag); x0 -= (I32)((xMag < 0) ? xSize - xCenter - 1 : xCenter) * (I32)(xMagAbs) / (I32)(1000); yEnd = y0 + GUI__DivideRound32(((I32)(-yCenter) * (I32)(yMag)), 1000); yPrev = yEnd + 1; yStep = (yMag < 0) ? -1 : 1; if (pBitmap->pPal) { if (pBitmap->pPal->HasTrans) { HasTrans = 1; } } for (yi = 0; yi < ySize; yi++) { y = yEnd; yEnd = y0 + GUI__DivideRound32(((I32)(yi + 1 - yCenter) * (I32)(yMag)), 1000); if (y != yPrev) { yPrev = y; do { if ((y >= yMin) && (y <= yMax)) { xStart = -1; x = 0; xiMag = 0; Cached = 0; for (xi = 0; xi < xSize; xi++) { xiMag += xMagAbs; if (xiMag >= 1000) { xAct = (xMag > 0) ? xi : xSize - xi - 1; Index = GUI_GetBitmapPixelIndex(pBitmap, xAct, yi); if (Index != IndexPrev || xStart == -1) { if ((Index == 0) && HasTrans) { /* Transparent color ... clear cache */ if (Cached) { LCD_DrawHLine(x0 + xStart, y, x0 + x - 1); Cached = 0; } } else { /* Another color ... draw contents of cache */ if (Cached && xStart != -1) { LCD_DrawHLine(x0 + xStart, y, x0 + x - 1); } xStart = x; Cached = 1; if (pBitmap->pMethods) { Color = pBitmap->pMethods->pfIndex2Color(Index); } else { Color = pBitmap->pPal->pPalEntries[Index]; } LCD_SetColorIndex(LCDDEV_L0_Color2Index(Color)); } IndexPrev = Index; } do { x++; xiMag -= 1000; } while (xiMag >= 1000); } } /* Clear cache */ if (Cached) { LCD_DrawHLine(x0 + xStart, y, x0 + x - 1); } } y += yStep; } while ((yMag < 0) ? (y > yEnd) : (y < yEnd)); } } }
/********************************************************************* * * GUI_CURSOR_SetPosition */ void GUI_CURSOR_SetPosition(int xNewPos, int yNewPos) { int x, xStart, xStep, xEnd, xOff, xOverlapMin, xOverlapMax; int y, yStart, yStep, yEnd, yOff, yOverlapMin, yOverlapMax; int xSize; LCD_PIXELINDEX* pData; GUI_LOCK(); if (_hBuffer) { if ((_x != xNewPos) | (_y != yNewPos)) { if (_CursorOn) { const GUI_BITMAP GUI_UNI_PTR * pBM = _pCursor->pBitmap; /* Save & set clip rect */ /* Compute helper variables */ pData = (LCD_PIXELINDEX*)GUI_ALLOC_h2p(_hBuffer); xSize = _pCursor->pBitmap->XSize; xOff = xNewPos - _x; if (xOff > 0) { xStep = 1; xStart = 0; xEnd = _pCursor->pBitmap->XSize; xOverlapMax = xEnd -1; xOverlapMin = xOff; } else { xStep = -1; xStart = xSize - 1; xEnd = -1; xOverlapMin = 0; xOverlapMax = xStart + xOff; } yOff = yNewPos - _y; if (yOff > 0) { yStep = 1; yStart = 0; yEnd = _pCursor->pBitmap->YSize; yOverlapMax = yEnd -1; yOverlapMin = yOff; } else { yStep = -1; yStart = _pCursor->pBitmap->YSize - 1; yEnd = -1; yOverlapMin = 0; yOverlapMax = yStart + yOff; } /* Restore & Draw */ for (y = yStart; y != yEnd; y += yStep) { char yOverlaps; char yNewOverlaps; int yNew = y + yOff; yOverlaps = (y >= yOverlapMin) && (y <= yOverlapMax); yNewOverlaps = (yNew >= yOverlapMin) && (yNew <= yOverlapMax); for (x= xStart; x != xEnd; x += xStep) { char xyOverlaps, xyNewOverlaps; int BitmapPixel; LCD_PIXELINDEX Pixel; LCD_PIXELINDEX* pSave = pData + x + y * xSize; int xNew = x + xOff; BitmapPixel = GUI_GetBitmapPixelIndex(pBM, x, y); xyOverlaps = (x >= xOverlapMin) && (x <= xOverlapMax) && yOverlaps; xyNewOverlaps = (xNew >= xOverlapMin) && (xNew <= xOverlapMax) && yNewOverlaps; /* Restore old pixel if it was not transparent */ if (BitmapPixel) { if (!xyOverlaps || (GUI_GetBitmapPixelIndex(pBM, x - xOff, y - yOff) == 0)) { _SetPixelIndex(x + _Rect.x0, y + _Rect.y0, *(pSave)); } } /* Save */ if (xyNewOverlaps) { Pixel = *(pData + xNew + yNew * xSize); } else { Pixel = _GetPixelIndex(_Rect.x0 + xNew, _Rect.y0 + yNew); } *pSave = Pixel; /* Write new ... We could write pixel by pixel here */ if (BitmapPixel) { LCD_PIXELINDEX NewPixel = _Log2Phys(BitmapPixel); _SetPixelIndex(_Rect.x0 + xNew, _Rect.y0 + yNew, NewPixel); } } } } _x = xNewPos; _y = yNewPos; _CalcRect(); } } GUI_UNLOCK(); }