diff --git a/source/Cosmos.System2/Graphics/Canvas.cs b/source/Cosmos.System2/Graphics/Canvas.cs
index 8ce2470e84..a6ac312140 100644
--- a/source/Cosmos.System2/Graphics/Canvas.cs
+++ b/source/Cosmos.System2/Graphics/Canvas.cs
@@ -117,7 +117,6 @@ public virtual void Clear(Color color)
/// The X coordinate.
/// The Y coordinate.
public abstract Color GetPointColor(int x, int y);
-
///
/// Gets the index of the pixel at the given coordinates.
///
@@ -530,13 +529,17 @@ public virtual void DrawRectangle(Color color, int x, int y, int width, int heig
/// The starting point Y coordinate.
/// The width of the rectangle.
/// The height of the rectangle.
- public virtual void DrawFilledRectangle(Color color, int xStart, int yStart, int width, int height)
+ public virtual void DrawFilledRectangle(Color color, int xStart, int yStart, int width, int height, bool preventOffBoundPixels = true)
{
if (height == -1)
{
height = width;
}
-
+ if (preventOffBoundPixels)
+ {
+ width = Math.Min(width, (int)Mode.Width - xStart);
+ height = Math.Min(height, (int)Mode.Height - yStart);
+ }
for (int y = yStart; y < yStart + height; y++)
{
DrawLine(color, xStart, y, xStart + width - 1, y);
@@ -566,16 +569,31 @@ public virtual void DrawTriangle(Color color, int v1x, int v1y, int v2x, int v2y
/// The image to draw.
/// The origin X coordinate.
/// The origin Y coordinate.
- public virtual void DrawImage(Image image, int x, int y)
+ public virtual void DrawImage(Image image, int x, int y, bool preventOffBoundPixels = true)
{
Color color;
-
- for (int xi = 0; xi < image.Width; xi++)
+ if (preventOffBoundPixels)
{
- for (int yi = 0; yi < image.Height; yi++)
+ var maxWidth = Math.Min(image.Width, (int)Mode.Width - x);
+ var maxHeight = Math.Min(image.Height, (int)Mode.Height - y);
+ for (int xi = 0; xi < maxWidth; xi++)
{
- color = Color.FromArgb(image.RawData[xi + (yi * image.Width)]);
- DrawPoint(color, x + xi, y + yi);
+ for (int yi = 0; yi < maxHeight; yi++)
+ {
+ color = Color.FromArgb(image.RawData[xi + (yi * image.Width)]);
+ DrawPoint(color, x + xi, y + yi);
+ }
+ }
+ }
+ else
+ {
+ for (int xi = 0; xi < image.Width; xi++)
+ {
+ for (int yi = 0; yi < image.Height; yi++)
+ {
+ color = Color.FromArgb(image.RawData[xi + (yi * image.Width)]);
+ DrawPoint(color, x + xi, y + yi);
+ }
}
}
}
@@ -611,17 +629,33 @@ static int[] ScaleImage(Image image, int newWidth, int newHeight)
/// The Y coordinate.
/// The desired width to scale the image to before drawing.
/// The desired height to scale the image to before drawing
- public virtual void DrawImage(Image image, int x, int y, int w, int h)
+ public virtual void DrawImage(Image image, int x, int y, int w, int h, bool preventOffBoundPixels = true)
{
Color color;
int[] pixels = ScaleImage(image, w, h);
- for (int xi = 0; xi < w; xi++)
+ if (preventOffBoundPixels)
+ {
+ var maxWidth = Math.Min(w, (int)Mode.Width - x);
+ var maxHeight = Math.Min(h, (int)Mode.Height - y);
+ for (int xi = 0; xi < maxWidth; xi++)
+ {
+ for (int yi = 0; yi < maxHeight; yi++)
+ {
+ color = Color.FromArgb(pixels[xi + (yi * w)]);
+ DrawPoint(color, x + xi, y + yi);
+ }
+ }
+ }
+ else
{
- for (int yi = 0; yi < h; yi++)
+ for (int xi = 0; xi < w; xi++)
{
- color = Color.FromArgb(pixels[xi + (yi * w)]);
- DrawPoint(color, x + xi, y + yi);
+ for (int yi = 0; yi < h; yi++)
+ {
+ color = Color.FromArgb(pixels[xi + (yi * w)]);
+ DrawPoint(color, x + xi, y + yi);
+ }
}
}
}
@@ -632,16 +666,31 @@ public virtual void DrawImage(Image image, int x, int y, int w, int h)
/// The image to draw.
/// The X coordinate.
/// The Y coordinate.
- public void DrawImageAlpha(Image image, int x, int y)
+ public void DrawImageAlpha(Image image, int x, int y, bool preventOffBoundPixels = true)
{
Color color;
-
- for (int xi = 0; xi < image.Width; xi++)
+ if (preventOffBoundPixels)
{
- for (int yi = 0; yi < image.Height; yi++)
+ var maxWidth = Math.Min(image.Width, (int)Mode.Width - x);
+ var maxHeight = Math.Min(image.Height, (int)Mode.Height - y);
+ for (int xi = 0; xi < maxWidth; xi++)
{
- color = Color.FromArgb(image.RawData[xi + (yi * image.Width)]);
- DrawPoint(color, x + xi, y + yi);
+ for (int yi = 0; yi < maxHeight; yi++)
+ {
+ color = Color.FromArgb(image.RawData[xi + (yi * image.Width)]);
+ DrawPoint(color, x + xi, y + yi);
+ }
+ }
+ }
+ else
+ {
+ for (int xi = 0; xi < image.Width; xi++)
+ {
+ for (int yi = 0; yi < image.Height; yi++)
+ {
+ color = Color.FromArgb(image.RawData[xi + (yi * image.Width)]);
+ DrawPoint(color, x + xi, y + yi);
+ }
}
}
}
@@ -845,4 +894,4 @@ public static Color AlphaBlend(Color to, Color from, byte alpha)
return Color.FromArgb(R, G, B);
}
}
-}
+}
\ No newline at end of file
diff --git a/source/Cosmos.System2/Graphics/SVGAIICanvas.cs b/source/Cosmos.System2/Graphics/SVGAIICanvas.cs
index 256769c303..32a01de9fe 100644
--- a/source/Cosmos.System2/Graphics/SVGAIICanvas.cs
+++ b/source/Cosmos.System2/Graphics/SVGAIICanvas.cs
@@ -80,12 +80,17 @@ public override void DrawPoint(Color color, int x, int y)
driver.SetPixel((uint)x, (uint)y, (uint)color.ToArgb());
}
- public override void DrawFilledRectangle(Color color, int xStart, int yStart, int width, int height)
+ public override void DrawFilledRectangle(Color color, int xStart, int yStart, int width, int height, bool preventOffBoundPixels = true)
{
var argb = color.ToArgb();
var frameSize = (int)driver.FrameSize;
+ if(preventOffBoundPixels)
+ {
+ width = Math.Min(width, (int)mode.Width - xStart);
+ height = Math.Min(height, (int)mode.Height - yStart);
+ }
+
- // For now write directly into video memory, once _xSVGADriver.Fill will be faster it will have to be changed
for (int i = yStart; i < yStart + height; i++)
{
driver.videoMemory.Fill(GetPointOffset(xStart, i) + (int)frameSize, width, argb);
@@ -346,17 +351,29 @@ public override void DrawChar(char c, Font font, Color color, int x, int y)
}
}
- public override void DrawImage(Image image, int x, int y)
+ public override void DrawImage(Image image, int x, int y, bool preventOffBoundPixels = true)
{
var width = (int)image.Width;
var height = (int)image.Height;
var frameSize = (int)driver.FrameSize;
var data = image.RawData;
+ if (preventOffBoundPixels)
+ {
+ var maxWidth = Math.Min(width, (int)mode.Width - x);
+ var maxHeight = Math.Min(height, (int)mode.Height - y);
- for (int i = 0; i < height; i++)
+ for (int i = 0; i < maxHeight; i++)
+ {
+ driver.videoMemory.Copy(GetPointOffset(x, y + i) + frameSize, data, i * width, maxWidth);
+ }
+ }
+ else
{
- driver.videoMemory.Copy(GetPointOffset(x, y + i) + frameSize, data, i * width, width);
+ for (int i = 0; i < height; i++)
+ {
+ driver.videoMemory.Copy(GetPointOffset(x, y + i) + frameSize, data, i * width, width);
+ }
}
}
}
-}
+}
\ No newline at end of file
diff --git a/source/Cosmos.System2/Graphics/VBECanvas.cs b/source/Cosmos.System2/Graphics/VBECanvas.cs
index bd507873f3..bb86dbf1be 100644
--- a/source/Cosmos.System2/Graphics/VBECanvas.cs
+++ b/source/Cosmos.System2/Graphics/VBECanvas.cs
@@ -248,9 +248,10 @@ public override void DrawArray(Color[] aColors, int aX, int aY, int aWidth, int
}
}
- public override void DrawFilledRectangle(Color aColor, int aX, int aY, int aWidth, int aHeight)
+ public override void DrawFilledRectangle(Color aColor, int aX, int aY, int aWidth, int aHeight, bool preventOffBoundPixels = true)
{
// ClearVRAM clears one uint at a time. So we clear pixelwise not byte wise. That's why we divide by 32 and not 8.
+ if(preventOffBoundPixels)
aWidth = (int)(Math.Min(aWidth, Mode.Width - aX) * (int)Mode.ColorDepth / 32);
var color = aColor.ToArgb();
@@ -260,18 +261,30 @@ public override void DrawFilledRectangle(Color aColor, int aX, int aY, int aWidt
}
}
- public override void DrawImage(Image aImage, int aX, int aY)
+ public override void DrawImage(Image aImage, int aX, int aY, bool preventOffBoundPixels = true)
{
var xBitmap = aImage.RawData;
var xWidth = (int)aImage.Width;
var xHeight = (int)aImage.Height;
-
- int xOffset = GetPointOffset(aX, aY);
-
- for (int i = 0; i < xHeight; i++)
+ if (preventOffBoundPixels)
{
- driver.CopyVRAM((i * (int)Mode.Width) + xOffset, xBitmap, i * xWidth, xWidth);
+ var maxWidth = Math.Min(xWidth, (int)mode.Width - aX);
+ var maxHeight = Math.Min(xHeight, (int)mode.Height - aY);
+ int xOffset = aY * (int)Mode.Width + aX;
+ for (int i = 0; i < maxHeight; i++)
+ {
+ driver.CopyVRAM((i * (int)Mode.Width) + xOffset, xBitmap, i * xWidth, maxWidth);
+ }
}
+ else
+ {
+ int xOffset = aY * xHeight + aX;
+ for (int i = 0; i < Mode.Height; i++)
+ {
+ driver.CopyVRAM((i * (int)Mode.Width) + xOffset, xBitmap, i * xWidth, xWidth);
+ }
+ }
+
}
#endregion
diff --git a/source/Cosmos.System2/Graphics/VGACanvas.cs b/source/Cosmos.System2/Graphics/VGACanvas.cs
index 50934b030a..2157e06dee 100644
--- a/source/Cosmos.System2/Graphics/VGACanvas.cs
+++ b/source/Cosmos.System2/Graphics/VGACanvas.cs
@@ -86,8 +86,13 @@ public override void Disable()
}
}
- public override void DrawFilledRectangle(Color aColor, int aXStart, int aYStart, int aWidth, int aHeight)
+ public override void DrawFilledRectangle(Color aColor, int aXStart, int aYStart, int aWidth, int aHeight, bool preventOffBoundPixels = true)
{
+ if (preventOffBoundPixels)
+ {
+ aWidth = Math.Min(aWidth, (int)Mode.Width - aXStart);
+ aHeight = Math.Min(aHeight, (int)Mode.Height - aYStart);
+ }
driver.DrawFilledRectangle(aXStart, aYStart, aWidth, aHeight, driver.GetClosestColorInPalette(aColor));
}