public void DrawPoly(Bitmap screen, Point[] points, Color borderColor, short borderWidth, Color fillColor, PolyFill polyFill)
{
if (points.Length < 3) return; // we need at least 3 point for poly
if (borderWidth < 1)
borderWidth = 1;
Color fgColor, bgColor;
if (fillColor == Color.Black)
{
fgColor = Color.Black;
bgColor = Color.White;
}
else
{
fgColor = Color.White;
bgColor = Color.Black;
}
if (polyFill == PolyFill.POLYFILL_EMPTY)
_DrawUnfilledPoly(screen, points, borderColor, borderWidth, new Point(0, 0));
else
{
Point br = new Point(0, 0), tl = new Point(screen.Width, screen.Height);
// find bounding box
for (int i = 0; i < points.Length; ++i)
{
tl.X = (tl.X > points[i].X) ? points[i].X : tl.X;
tl.Y = (tl.Y > points[i].Y) ? points[i].Y : tl.Y;
br.X = (br.X < points[i].X) ? points[i].X : br.X;
br.Y = (br.Y < points[i].Y) ? points[i].Y : br.Y;
}
// adjust binding box to fit thick border. Foê some reason SPOT.Bitmap double the border width (at least on emulator)
if (borderWidth > 1)
{
tl.X = (short)((tl.X > borderWidth) ? tl.X - borderWidth * 2 : 0);
tl.Y = (short)((tl.Y > borderWidth) ? tl.Y - borderWidth * 2 : 0);
br.X = (short)((br.X + borderWidth < (screen.Width - 1)) ? br.X + borderWidth * 1.5 : 0);
br.Y = (short)((br.Y + borderWidth < (screen.Width - 1)) ? br.Y + borderWidth * 1.5 : 0);
}
// we need separate bitmap to draw poly as one specififed can have some drawing already and we won't be able to detect border properly
Bitmap buffer = new Bitmap((br.X - tl.X + 1), (br.Y - tl.Y + 1));
// fill bitmap with color opposite to border color
if (borderColor == Color.Black)
buffer.DrawRectangle(Color.White, 0, 0, 0, buffer.Width, buffer.Height, 0, 0, Color.White, 0, 0, Color.White, buffer.Width, buffer.Height, 0xFF);
else
buffer.DrawRectangle(Color.Black, 0, 0, 0, buffer.Width, buffer.Height, 0, 0, Color.Black, 0, 0, Color.Black, buffer.Width, buffer.Height, 0xFF);
_DrawUnfilledPoly(buffer, points, borderColor, borderWidth, tl);
// scan created bitmap
bool isInside = false, onBorder = false;
int startX = -1, borderStart = -1;
for (int y = 0; y < buffer.Height; ++y)
{
isInside = false;
onBorder = false;
startX = -1;
borderStart = -1;
for (int x = 0; x < buffer.Width; ++x)
{
if (buffer.GetPixel(x, y) == borderColor)
{
if (onBorder)
{
// still on border
screen.SetPixel(x + tl.X, y + tl.Y, borderColor);
}
else
{
// we have reached border from inside/outside
if (isInside)
{
//isInside = false;
if (startX >= 0)
{
// draw pattern line
for (int k = startX; k < x; ++k)
{
if (polyFill == PolyFill.POLYFILL_SOLID) screen.SetPixel(k + tl.X, y + tl.Y, fgColor);
else if (polyFill == PolyFill.POLYFILL_HORIZONTAL)
screen.SetPixel(k + tl.X, y + tl.Y, (polyfill_horizontal[k % 3 + 3 * (y % 3)] == 0xFF) ? fgColor : bgColor);
else if (polyFill == PolyFill.POLYFILL_HORIZONTAL)
screen.SetPixel(k + tl.X, y + tl.Y, (polyfill_horizontal[k % 3 + 3 * (y % 3)] == 0xFF) ? fgColor : bgColor);
else if (polyFill == PolyFill.POLYFILL_VERTICAL)
screen.SetPixel(k + tl.X, y + tl.Y, (polyfill_vertical[k % 3 + 3 * (y % 3)] == 0xFF) ? fgColor : bgColor);
else if (polyFill == PolyFill.POLYFILL_DOTS)
screen.SetPixel(k + tl.X, y + tl.Y, (polyfill_dots[k % 3 + 3 * (y % 3)] == 0xFF) ? fgColor : bgColor);
else if (polyFill == PolyFill.POLYFILL_GRID)
screen.SetPixel(k + tl.X, y + tl.Y, (polyfill_grid[k % 3 + 3 * (y % 3)] == 0xFF) ? fgColor : bgColor);
else if (polyFill == PolyFill.POLYFILL_CROSS_LEFT)
screen.SetPixel(k + tl.X, y + tl.Y, (polyfill_cross_left[k % 3 + 3 * (y % 3)] == 0xFF) ? fgColor : bgColor);
else if (polyFill == PolyFill.POLYFILL_CROSS_RIGHT)
screen.SetPixel(k + tl.X, y + tl.Y, (polyfill_cross_right[k % 3 + 3 * (y % 3)] == 0xFF) ? fgColor : bgColor);
}
startX = -1;
}
}
onBorder = true;
borderStart = x;
screen.SetPixel(x + tl.X, y + tl.Y, borderColor);
}
}
else
{
if (onBorder)
{
// end of border
if (!((x - borderStart) > borderWidth * 4))
// if long this is not border, this is poly edge - we are still on the same side
isInside = !isInside;
onBorder = false;
borderStart = -1;
if (isInside)
startX = x;
}
}
}
}
buffer.Dispose();
}
}