//******************************************************************************* void dispOutlineEllipse( int xCenter, int yCenter, int xRadius, int yRadius) { int xx = 0; int yy = yRadius; long a2 = (long)xRadius * xRadius; long b2 = (long)yRadius * yRadius; long crit1 = -(a2 / 4 + xRadius % 2 + b2); long crit2 = -(b2 / 4 + yRadius % 2 + a2); long crit3 = -(b2 / 4 + yRadius % 2); long t = -a2 * yy; /* e(x+1/2,y-1/2) - (a^2+b^2)/4 */ long dxt = 2 * b2 * xx; long dyt = -2 * a2 * yy; long d2xt = 2 * b2; long d2yt = 2 * a2; while (yy >= 0 && xx <= xRadius) { dispPixel(xCenter + xx, yCenter + yy); if (xx != 0 || yy != 0) { dispPixel(xCenter - xx, yCenter - yy); } if (xx != 0 && yy != 0) { dispPixel(xCenter + xx, yCenter - yy); dispPixel(xCenter - xx, yCenter + yy); } if (t + b2 * xx <= crit1 || /* e(x+1,y-1/2) <= 0 */ t + a2 * yy <= crit3) /* e(x+1/2,y) <= 0 */ { incx(); } else if (t - a2 * yy > crit2) /* e(x+1/2,y-1) > 0 */ { incy(); } else { incx(); incy(); } } }
//******************************************************************************* //* returns TRUE if image was drawn char bmp_draw_imageN(int imageIndex, int xLoc, int yLoc) { unsigned long bmp_loc; unsigned char bmp_buff[DATAFLASH_PAGESIZE]; int bmpWidth; int bmpHeight; long length; int byteCnt; int pixelX, pixelY; long longByte1, longByte2, longByte3, longByte4; FLASH_FILE_ENTRY myFileEntry; char imageOK; imageOK = FALSE; cli(); //disable interrupts GetFlashFileEntry(imageIndex, &myFileEntry); if (myFileEntry.fileName[0] >= 0x20) { //* OK, it looks like a valid file imageOK = TRUE; #ifdef _USE_7LETTER_NAMES_ longByte1 = (myFileEntry.flashOffsetByte1 & 0x0ff); longByte2 = (myFileEntry.flashOffsetByte2 & 0x0ff); longByte3 = (myFileEntry.flashOffsetByte3 & 0x0ff); longByte4 = (myFileEntry.flashOffsetByte4 & 0x0ff); bmp_loc = longByte1 << 24; bmp_loc |= longByte2 << 16; bmp_loc |= longByte3 << 8; bmp_loc |= longByte4; #else bmp_loc = myFileEntry.flashOffset; #endif /* Get the width and height */ dataflash_read_block(bmp_buff, bmp_loc, 2); longByte1 = bmp_buff[0]; longByte2 = bmp_buff[1]; // longByte3 = bmp_buff[2]; // longByte4 = bmp_buff[3]; bmpWidth = longByte1 & 0x0ff; bmpHeight = longByte2 & 0x0ff; length = (uint32_t)bmpWidth * (uint32_t)bmpHeight; //* Incremement the bmp pointer passed the width/height bmp_loc += 2; dataflash_read_block(bmp_buff, bmp_loc, DATAFLASH_PAGESIZE); byteCnt = 0; if ((xLoc == -1) && (yLoc == -1)) { //* if xLoc and yLoc are -1, then CENTER the image xLoc = (gWidth - bmpWidth) / 2; yLoc = (gHeight - bmpHeight) / 2; if (xLoc < 0) { xLoc = 0; } if (yLoc < 0) { yLoc = 0; } GraphicsColor.red = 0; GraphicsColor.blue = 0; GraphicsColor.green = 0; dispRectangle(0, 0, gWidth-1, gHeight-1); } pixelX = 0; pixelY = 0; while ((pixelY < bmpHeight) && (length > 0)) { GraphicsColor.red = bmp_buff[byteCnt++]; GraphicsColor.blue = bmp_buff[byteCnt++]; GraphicsColor.green = bmp_buff[byteCnt++]; dispPixel(xLoc + pixelX, yLoc + pixelY); pixelX++; if (pixelX >= bmpWidth) { pixelX = 0; pixelY++; } if (byteCnt >= DATAFLASH_PAGESIZE) { bmp_loc += DATAFLASH_PAGESIZE; dataflash_read_block(bmp_buff, bmp_loc, DATAFLASH_PAGESIZE); byteCnt = 0; } length--; } } sei(); //enable interrupts return(imageOK); }
//********************************************************* //* Dec 26, 2008 Run Length Encoding for RGB void DisplayRLE_RGB(unsigned char *rleBuff, COLOR *colorFade, boolean fillBack, int startY) { COLOR bgColor; COLOR rleColor; int ii, jj; int cc; int rlePixCount; int pixelX, pixelY; int rleColorValue; int pixlesWide, pixelsTall; int rowCount; int byte1, byte2, byte3, byte4; int adjusted_Red; int adjusted_Green; int adjusted_Blue; cc = 0; byte1 = rleBuff[cc++] & 0x00ff; byte2 = rleBuff[cc++] & 0x00ff; byte3 = rleBuff[cc++] & 0x00ff; byte4 = rleBuff[cc++] & 0x00ff; pixlesWide = (byte1 << 8) + byte2; pixelsTall = (byte3 << 8) + byte4; adjusted_Red = (rleBuff[cc++] & 0x00ff) - colorFade->red; adjusted_Green = (rleBuff[cc++] & 0x00ff) - colorFade->green; adjusted_Blue = (rleBuff[cc++] & 0x00ff) - colorFade->blue; cc++; //* 1 filler char if (adjusted_Red < 0) adjusted_Red = 0; if (adjusted_Green < 0) adjusted_Green = 0; if (adjusted_Blue < 0) adjusted_Blue = 0; bgColor.red = adjusted_Red; bgColor.green = adjusted_Green; bgColor.blue = adjusted_Blue; pixelX = (kSCREEN_X_size / 2) - (pixlesWide / 2); pixelY = (kSCREEN_Y_size / 2) - (pixelsTall / 2); //* is the background supposed to be filled in if (fillBack) { dispColor(bgColor); for (jj=startY; jj<pixelY; jj++) { for (ii=0; ii<=kSCREEN_X_size; ii++) { dispPixel(ii, jj); } } } rowCount = 0; while ((cc < 5000) && (rowCount < pixelsTall)) { adjusted_Red = (rleBuff[cc] & 0x00ff) - colorFade->red; adjusted_Green = (rleBuff[cc + 1] & 0x00ff) - colorFade->green; adjusted_Blue = (rleBuff[cc + 2] & 0x00ff) - colorFade->blue; if (adjusted_Red < 0) adjusted_Red = 0; if (adjusted_Green < 0) adjusted_Green = 0; if (adjusted_Blue < 0) adjusted_Blue = 0; rleColor.red = adjusted_Red; rleColor.green = adjusted_Green; rleColor.blue = adjusted_Blue; rlePixCount = rleBuff[cc + 3] & 0x00ff; if ((rleColor.red == 0) && (rleColor.green == 0) && (rleColor.blue == 0) && (rlePixCount == 0)) { //* we have a new line rowCount++; pixelX = (kSCREEN_X_size / 2) - (pixlesWide / 2); //* as good a time as any to fill in the rest of the row if (fillBack) { dispColor(bgColor); for (ii=0; ii<pixelX; ii++) { dispPixel(ii, pixelY); } for (ii=(pixelX + pixlesWide); ii<kSCREEN_X_size; ii++) { dispPixel(ii, pixelY); } } pixelY++; } else if ((rlePixCount > 0) && (rlePixCount < 256)) { dispColor(rleColor); for (jj=0; jj<rlePixCount; jj++) { dispPixel(pixelX, pixelY); pixelX++; } } cc += 4; } if (fillBack) { dispColor(bgColor); for (jj=pixelY; jj<=kSCREEN_Y_size; jj++) { for (ii=0; ii<=kSCREEN_X_size; ii++) { dispPixel(ii, jj); } } } }
void dispLine(display_coord_t x1, display_coord_t y1, display_coord_t x2, display_coord_t y2, display_color_t color) { display_coord_t dx, dy; dx = abs(x2-x1); dy = abs(y2-y1); if((dx == 0) && (dy == 0)) // Point dispPixel(x1, y1, color); else if(dy == 0) // Horizontal { display_coord_t x; for(x=x1; x<=x2; x++) dispPixel(x, y1, color); } else if(dx == 0) // Vertical { display_coord_t y; for(y=y1; y<=y2; y++) dispPixel(x1, y, color); // TODO Optimize it! } else if(dy < dx) // Horizontal longest { if(x2 < x1) { // Swap coordinates display_coord_t t; t = x1; x1 = x2; x2 = t; t = y1; y1 = y2; y2 = t; } display_coord_t x, y, sy; if(y1 < y2) sy = 1; else sy = -1; display_coord_t e = 0; y = y1; for(x=x1; x<=x2; x++) { dispPixel(x, y, color); e += dy; if(2*e >= dx) { y += sy; e -= dx; } } } else // Vertical longest { if(y2 < y1) { // Swap coordinates display_coord_t t; t = x1; x1 = x2; x2 = t; t = y1; y1 = y2; y2 = t; } display_coord_t x, y, sx; if(x1 < x2) sx = 1; else sx = -1; display_coord_t e = 0; x = x1; for(y=y1; y<=y2; y++) { dispPixel(x, y, color); e += dx; if(2*e >= dy) { x += sx; e -= dy; } } } }
//******************************************************************************* //There's definitely an easier way to do this, but for now I'll use some help from: //http://www.codeproject.com/KB/GDI/antialias.aspx#dwuln //Edited by inthebitz //******************************************************************************* void dispWuLine( int X0, int Y0, int X1, int Y1) { unsigned short IntensityShift, ErrorAdj, ErrorAcc; unsigned short ErrorAccTemp, Weighting, WeightingComplementMask; short DeltaX, DeltaY, Temp, XDir; short BaseColor = 0; short NumLevels = 2; unsigned short IntensityBits = 2; /* Make sure the line runs top to bottom */ if (Y0 > Y1) { Temp = Y0; Y0 = Y1; Y1 = Temp; Temp = X0; X0 = X1; X1 = Temp; } /* Draw the initial pixel, which is always exactly intersected by the line and so needs no weighting */ dispPixel(X0, Y0); if ((DeltaX = X1 - X0) >= 0) { XDir = 1; } else { XDir = -1; DeltaX = -DeltaX; /* make DeltaX positive */ } /* Special-case horizontal, vertical, and diagonal lines, which require no weighting because they go right through the center of every pixel */ if ((DeltaY = Y1 - Y0) == 0) { /* Horizontal line */ while (DeltaX-- != 0) { X0 += XDir; dispPixel(X0, Y0); } return; } if (DeltaX == 0) { /* Vertical line */ do { Y0++; dispPixel(X0, Y0); } while (--DeltaY != 0); return; } if (DeltaX == DeltaY) { /* Diagonal line */ do { X0 += XDir; Y0++; dispPixel(X0, Y0); } while (--DeltaY != 0); return; } /* Line is not horizontal, diagonal, or vertical */ ErrorAcc = 0; /* initialize the line error accumulator to 0 */ /* # of bits by which to shift ErrorAcc to get intensity level */ IntensityShift = 16 - IntensityBits; /* Mask used to flip all bits in an intensity weighting, producing the result (1 - intensity weighting) */ WeightingComplementMask = NumLevels - 1; /* Is this an X-major or Y-major line? */ if (DeltaY > DeltaX) { /* Y-major line; calculate 16-bit fixed-point fractional part of a pixel that X advances each time Y advances 1 pixel, truncating the result so that we won't overrun the endpoint along the X axis */ ErrorAdj = ((unsigned long) DeltaX << 16) / (unsigned long) DeltaY; /* Draw all pixels other than the first and last */ while (--DeltaY) { ErrorAccTemp = ErrorAcc; /* remember currrent accumulated error */ ErrorAcc += ErrorAdj; /* calculate error for next pixel */ if (ErrorAcc <= ErrorAccTemp) { /* The error accumulator turned over, so advance the X coord */ X0 += XDir; } Y0++; /* Y-major, so always advance Y */ /* The IntensityBits most significant bits of ErrorAcc give us the intensity weighting for this pixel, and the complement of the weighting for the paired pixel */ Weighting = ErrorAcc >> IntensityShift; ////////////////////////////////////////////////////// dispPixel(X0, Y0); //dispPixel(X0 + XDir, Y0, mycolora); //dispPixel(X0, Y0, BaseColor + Weighting); //dispPixel(X0 + XDir, Y0, // BaseColor + (Weighting ^ WeightingComplementMask)); } /* Draw the final pixel, which is always exactly intersected by the line and so needs no weighting */ dispPixel(X1, Y1); return; }