X-Git-Url: http://git.rohieb.name/hackover2013-badge-firmware.git/blobdiff_plain/bb58af2076c30e41d353ec193deddf54f6c3b8e8..1ee47540d67648bc4f9f530c62bc96f29b53e2f6:/drivers/lcd/tft/drawing.c diff --git a/drivers/lcd/tft/drawing.c b/drivers/lcd/tft/drawing.c index 201df6c..e90a8e6 100644 --- a/drivers/lcd/tft/drawing.c +++ b/drivers/lcd/tft/drawing.c @@ -53,42 +53,60 @@ /* */ /**************************************************************************/ +/**************************************************************************/ +/*! + @brief Swaps values a and b +*/ +/**************************************************************************/ +void drawSwap(uint32_t a, uint32_t b) +{ + uint32_t t; + t = a; + a = b; + b = t; +} + /**************************************************************************/ /*! @brief Draws a single bitmap character */ /**************************************************************************/ -void drawCharBitmap(const uint16_t xPixel, const uint16_t yPixel, uint16_t color, const uint8_t *glyph, uint8_t glyphHeightPages, uint8_t glyphWidthBits) +void drawCharBitmap(const uint16_t xPixel, const uint16_t yPixel, uint16_t color, const char *glyph, uint8_t cols, uint8_t rows) { - uint16_t verticalPage, horizBit, currentY, currentX; - uint16_t indexIntoGlyph; + uint16_t currentY, currentX, indexIntoGlyph; + uint16_t _row, _col, _colPages; // set initial current y currentY = yPixel; currentX = xPixel; - // for each page of the glyph - for (verticalPage = glyphHeightPages; verticalPage > 0; --verticalPage) + // Figure out how many columns worth of data we have + if (cols % 8) + _colPages = cols / 8 + 1; + else + _colPages = cols / 8; + + for (_row = 0; _row < rows; _row++) { - // for each horizontol bit - for (horizBit = 0; horizBit < glyphWidthBits; ++horizBit) + for (_col = 0; _col < _colPages; _col++) { - // next byte - indexIntoGlyph = (glyphHeightPages * horizBit) + verticalPage - 1; - - currentX = xPixel + (horizBit); + if (_row == 0) + indexIntoGlyph = _col; + else + indexIntoGlyph = (_row * _colPages) + _col; + + currentY = yPixel + _row; + currentX = xPixel + (_col*8); // send the data byte if (glyph[indexIntoGlyph] & (0X80)) drawPixel(currentX, currentY, color); - if (glyph[indexIntoGlyph] & (0X40)) drawPixel(currentX, currentY - 1, color); - if (glyph[indexIntoGlyph] & (0X20)) drawPixel(currentX, currentY - 2, color); - if (glyph[indexIntoGlyph] & (0X10)) drawPixel(currentX, currentY - 3, color); - if (glyph[indexIntoGlyph] & (0X08)) drawPixel(currentX, currentY - 4, color); - if (glyph[indexIntoGlyph] & (0X04)) drawPixel(currentX, currentY - 5, color); - if (glyph[indexIntoGlyph] & (0X02)) drawPixel(currentX, currentY - 6, color); - if (glyph[indexIntoGlyph] & (0X01)) drawPixel(currentX, currentY - 7, color); + if (glyph[indexIntoGlyph] & (0X40)) drawPixel(currentX+1, currentY, color); + if (glyph[indexIntoGlyph] & (0X20)) drawPixel(currentX+2, currentY, color); + if (glyph[indexIntoGlyph] & (0X10)) drawPixel(currentX+3, currentY, color); + if (glyph[indexIntoGlyph] & (0X08)) drawPixel(currentX+4, currentY, color); + if (glyph[indexIntoGlyph] & (0X04)) drawPixel(currentX+5, currentY, color); + if (glyph[indexIntoGlyph] & (0X02)) drawPixel(currentX+6, currentY, color); + if (glyph[indexIntoGlyph] & (0X01)) drawPixel(currentX+7, currentY, color); } - // next line of pages - currentY += 8; } } @@ -330,7 +348,9 @@ void drawString(uint16_t x, uint16_t y, uint16_t color, const FONT_INFO *fontInf } // Send individual characters - drawCharBitmap(currentX, y, color, &fontInfo->data[charOffset], fontInfo->heightPages, charWidth); + // We need to manually calculate width in pages since this is screwy with variable width fonts + //uint8_t heightPages = charWidth % 8 ? charWidth / 8 : charWidth / 8 + 1; + drawCharBitmap(currentX, y, color, (const char *)(&fontInfo->data[charOffset]), charWidth, fontInfo->height); // next char X currentX += charWidth + 1; @@ -379,8 +399,8 @@ uint16_t drawGetStringWidth(const FONT_INFO *fontInfo, char *str) } } - /* return the wdith */ - return width; + /* return the width */ + return width > 0 ? width - 1 : width; } /**************************************************************************/ @@ -450,9 +470,6 @@ void drawLineDotted ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16 // Check if we can use the optimised vertical line method. // This can make a huge difference in performance, but may // not work properly on every LCD controller: - // ex.: drawCircleFilled(120, 160, 50, COLOR_RED); - // = 678834 cycles using lcdDrawVLine w/ILI9328 = 9.43mS @ 72MHz - // = 7546261 w/o lcdDrawVLine, setting each pixel = 104.8mS @ 72MHz if ((x0 == x1) && (empty == 0)) { // Warning: This may actually be slower than drawing individual pixels on @@ -649,6 +666,86 @@ void drawCircleFilled (uint16_t xCenter, uint16_t yCenter, uint16_t radius, uint } } +/**************************************************************************/ +/*! + @brief Draws a filled rounded corner + + @param[in] xCenter + The horizontal center of the circle + @param[in] yCenter + The vertical center of the circle + @param[in] radius + The circle's radius in pixels + @param[in] position + The position of the corner, which affects how it will + be rendered + @param[in] color + Color used when drawing +*/ +/**************************************************************************/ +void drawCornerFilled (uint16_t xCenter, uint16_t yCenter, uint16_t radius, drawCornerPosition_t position, uint16_t color) +{ + int16_t f = 1 - radius; + int16_t ddF_x = 1; + int16_t ddF_y = -2 * radius; + int16_t x = 0; + int16_t y = radius; + int16_t xc_px, yc_my, xc_mx, xc_py, yc_mx, xc_my; + int16_t lcdWidth = lcdGetWidth(); + + switch (position) + { + case DRAW_CORNERPOSITION_TOPRIGHT: + case DRAW_CORNERPOSITION_TOPLEFT: + if (xCenter < lcdWidth) drawLine(xCenter, yCenter-radius < 0 ? 0 : yCenter-radius, xCenter, yCenter, color); + break; + case DRAW_CORNERPOSITION_BOTTOMRIGHT: + case DRAW_CORNERPOSITION_BOTTOMLEFT: + if (xCenter < lcdWidth) drawLine(xCenter, yCenter-radius < 0 ? 0 : yCenter, xCenter, (yCenter-radius) + (2*radius), color); + break; + } + + while (x= 0) + { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x; + + xc_px = xCenter+x; + xc_mx = xCenter-x; + xc_py = xCenter+y; + xc_my = xCenter-y; + yc_mx = yCenter-x; + yc_my = yCenter-y; + + switch (position) + { + case DRAW_CORNERPOSITION_TOPRIGHT: + if ((xc_px < lcdWidth) && (xc_px >= 0)) drawLine(xc_px, yc_my, xc_px, yCenter, color); + if ((xc_py < lcdWidth) && (xc_py >= 0)) drawLine(xc_py, yc_mx, xc_py, yCenter, color); + break; + case DRAW_CORNERPOSITION_BOTTOMRIGHT: + if ((xc_px < lcdWidth) && (xc_px >= 0)) drawLine(xc_px, yCenter, xc_px, yc_my + 2*y, color); + if ((xc_py < lcdWidth) && (xc_py >= 0)) drawLine(xc_py, yCenter, xc_py, yc_mx + 2*x, color); + break; + case DRAW_CORNERPOSITION_TOPLEFT: + if ((xc_mx < lcdWidth) && (xc_mx >= 0)) drawLine(xc_mx, yc_my, xc_mx, yCenter, color); + if ((xc_my < lcdWidth) && (xc_my >= 0)) drawLine(xc_my, yc_mx, xc_my, yCenter, color); + break; + case DRAW_CORNERPOSITION_BOTTOMLEFT: + if ((xc_mx < lcdWidth) && (xc_mx >= 0)) drawLine(xc_mx, yCenter, xc_mx, yc_my + 2*y, color); + if ((xc_my < lcdWidth) && (xc_my >= 0)) drawLine(xc_my, yCenter, xc_my, yc_mx + 2*x, color); + break; + } + } +} + /**************************************************************************/ /*! @brief Draws a simple arrow of the specified width @@ -919,7 +1016,7 @@ void drawTriangle ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t /**************************************************************************/ /*! - @brief Draws a triangle + @brief Draws a filled triangle @param[in] x0 x co-ordinate for point 0 @@ -952,7 +1049,16 @@ void drawTriangle ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t /**************************************************************************/ void drawTriangleFilled ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) { - // ToDo: re-order vertices by ascending Y values (smallest first) + // Re-order vertices by ascending Y values (smallest first) + if (y0 > y1) { + drawSwap(y0, y1); drawSwap(x0, x1); + } + if (y1 > y2) { + drawSwap(y2, y1); drawSwap(x2, x1); + } + if (y0 > y1) { + drawSwap(y0, y1); drawSwap(x0, x1); + } int32_t dx1, dx2, dx3; // Interpolation deltas int32_t sx1, sx2, sy; // Scanline co-ordinates @@ -1169,11 +1275,11 @@ void drawProgressBar ( uint16_t x, uint16_t y, uint16_t width, uint16_t height, @code #include "drivers/lcd/tft/drawing.h" - #include "drivers/lcd/tft/fonts/dejavusansbold9.h" + #include "drivers/lcd/tft/fonts/dejavusans9.h" // Draw two buttons using Vera Sans Bold 9 - drawButton(20, 195, 200, 35, &dejaVuSansBold9ptFontInfo, 7, COLOR_DARKERGRAY, COLOR_DARKERGRAY, COLOR_WHITE, "System Settings"); - drawButton(20, 235, 200, 35, &dejaVuSansBold9ptFontInfo, 7, COLOR_LIMEGREENDIM, COLOR_LIMEGREEN, COLOR_BLACK, "System Settings"); + drawButton(20, 195, 200, 35, &dejaVuSans9ptFontInfo, 7, COLOR_GRAY_80, COLOR_GRAY_80, COLOR_WHITE, "System Settings"); + drawButton(20, 235, 200, 35, &dejaVuSans9ptFontInfo, 7, COLOR_THEME_LIMEGREEN_DARKER, COLOR_THEME_LIMEGREEN_BASE, COLOR_BLACK, "System Settings"); @endcode */