summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorfrosch <frosch@openttd.org>2011-04-02 16:39:30 +0000
committerfrosch <frosch@openttd.org>2011-04-02 16:39:30 +0000
commitb18211bb9d1f8f758e814a5b5f6dc74e78183c51 (patch)
tree1fa7d4f5b289ca68bb97d0e167b36a80ee9b4eae /src
parent7659575cfa52b6fd9eea9c1256b325f84261e29f (diff)
downloadopenttd-b18211bb9d1f8f758e814a5b5f6dc74e78183c51.tar.xz
(svn r22291) -Add: a linewidth argument to GfxDrawLine() and Blitter::DrawLine().
Diffstat (limited to 'src')
-rw-r--r--src/blitter/base.cpp83
-rw-r--r--src/blitter/base.hpp2
-rw-r--r--src/gfx.cpp16
-rw-r--r--src/gfx_func.h2
4 files changed, 78 insertions, 25 deletions
diff --git a/src/blitter/base.cpp b/src/blitter/base.cpp
index 9b2d007bf..312ec1025 100644
--- a/src/blitter/base.cpp
+++ b/src/blitter/base.cpp
@@ -11,6 +11,7 @@
#include "../stdafx.h"
#include "base.hpp"
+#include "../core/math_func.hpp"
/**
* Draw a line with a given colour.
@@ -22,14 +23,14 @@
* @param screen_width The width of the screen you are drawing in (to avoid buffer-overflows).
* @param screen_height The height of the screen you are drawing in (to avoid buffer-overflows).
* @param colour A 8bpp mapping colour.
+ * @param width Line width.
*/
-void Blitter::DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour)
+void Blitter::DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width)
{
int dy;
int dx;
int stepx;
int stepy;
- int frac;
dy = (y2 - y) * 2;
if (dy < 0) {
@@ -47,29 +48,79 @@ void Blitter::DrawLine(void *video, int x, int y, int x2, int y2, int screen_wid
stepx = 1;
}
+ int frac_diff = width * max(dx, dy);
+ if (width > 1) {
+ int frac_sq = width * width * (dx * dx + dy * dy);
+ while (frac_diff * frac_diff < frac_sq) frac_diff++;
+ }
+
if (dx > dy) {
- frac = dy - (dx / 2);
- x2 += stepx; // Make x2 the first column to not draw to
+ int y_low = y;
+ int y_high = y;
+ int frac_low = dy - frac_diff / 2;
+ int frac_high = dy + frac_diff / 2;
+
+ while (frac_low + dx / 2 < 0) {
+ frac_low += dx;
+ y_low -= stepy;
+ }
+ while (frac_high - dx / 2 > 0) {
+ frac_high -= dx;
+ y_high += stepy;
+ }
+ x2 += stepx;
+
while (x != x2) {
- if (x >= 0 && y >= 0 && x < screen_width && y < screen_height) this->SetPixel(video, x, y, colour);
- if (frac >= 0) {
- y += stepy;
- frac -= dx;
+ if (x >= 0 && x < screen_width) {
+ for (int y = y_low; y != y_high; y += stepy) {
+ if (y >= 0 && y < screen_height) this->SetPixel(video, x, y, colour);
+ }
+ }
+ if (frac_low >= 0) {
+ y_low += stepy;
+ frac_low -= dx;
+ }
+ if (frac_high >= 0) {
+ y_high += stepy;
+ frac_high -= dx;
}
x += stepx;
- frac += dy;
+ frac_low += dy;
+ frac_high += dy;
}
} else {
- frac = dx - (dy / 2);
- y2 += stepy; // Make y2 the first row to not draw to
+ int x_low = x;
+ int x_high = x;
+ int frac_low = dx - frac_diff / 2;
+ int frac_high = dx + frac_diff / 2;
+
+ while (frac_low + dy / 2 < 0) {
+ frac_low += dy;
+ x_low -= stepx;
+ }
+ while (frac_high - dy / 2 > 0) {
+ frac_high -= dy;
+ x_high += stepx;
+ }
+ y2 += stepy;
+
while (y != y2) {
- if (x >= 0 && y >= 0 && x < screen_width && y < screen_height) this->SetPixel(video, x, y, colour);
- if (frac >= 0) {
- x += stepx;
- frac -= dy;
+ if (y >= 0 && y < screen_height) {
+ for (int x = x_low; x != x_high; x += stepx) {
+ if (x >= 0 && x < screen_width) this->SetPixel(video, x, y, colour);
+ }
+ }
+ if (frac_low >= 0) {
+ x_low += stepx;
+ frac_low -= dy;
+ }
+ if (frac_high >= 0) {
+ x_high += stepx;
+ frac_high -= dy;
}
y += stepy;
- frac += dx;
+ frac_low += dx;
+ frac_high += dx;
}
}
}
diff --git a/src/blitter/base.hpp b/src/blitter/base.hpp
index 3af376a15..cb76f856e 100644
--- a/src/blitter/base.hpp
+++ b/src/blitter/base.hpp
@@ -101,7 +101,7 @@ public:
*/
virtual void DrawRect(void *video, int width, int height, uint8 colour) = 0;
- void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour);
+ void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width);
/**
* Copy from a buffer to the screen.
diff --git a/src/gfx.cpp b/src/gfx.cpp
index 6253238a3..62b8b024a 100644
--- a/src/gfx.cpp
+++ b/src/gfx.cpp
@@ -192,23 +192,25 @@ void GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectM
}
}
-void GfxDrawLine(int x, int y, int x2, int y2, int colour)
+void GfxDrawLine(int x, int y, int x2, int y2, int colour, int width)
{
Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter();
DrawPixelInfo *dpi = _cur_dpi;
+ assert(width > 0);
+
x -= dpi->left;
x2 -= dpi->left;
y -= dpi->top;
y2 -= dpi->top;
/* Check clipping */
- if (x < 0 && x2 < 0) return;
- if (y < 0 && y2 < 0) return;
- if (x > dpi->width && x2 > dpi->width) return;
- if (y > dpi->height && y2 > dpi->height) return;
+ if (x + width / 2 < 0 && x2 + width / 2 < 0 ) return;
+ if (y + width / 2 < 0 && y2 + width / 2 < 0 ) return;
+ if (x - width / 2 > dpi->width && x2 - width / 2 > dpi->width ) return;
+ if (y - width / 2 > dpi->height && y2 - width / 2 > dpi->height) return;
- blitter->DrawLine(dpi->dst_ptr, x, y, x2, y2, dpi->width, dpi->height, colour);
+ blitter->DrawLine(dpi->dst_ptr, x, y, x2, y2, dpi->width, dpi->height, colour, width);
}
void GfxDrawLineUnscaled(int x, int y, int x2, int y2, int colour)
@@ -229,7 +231,7 @@ void GfxDrawLineUnscaled(int x, int y, int x2, int y2, int colour)
blitter->DrawLine(dpi->dst_ptr, UnScaleByZoom(x, dpi->zoom), UnScaleByZoom(y, dpi->zoom),
UnScaleByZoom(x2, dpi->zoom), UnScaleByZoom(y2, dpi->zoom),
- UnScaleByZoom(dpi->width, dpi->zoom), UnScaleByZoom(dpi->height, dpi->zoom), colour);
+ UnScaleByZoom(dpi->width, dpi->zoom), UnScaleByZoom(dpi->height, dpi->zoom), colour, 1);
}
/**
diff --git a/src/gfx_func.h b/src/gfx_func.h
index 9a0c3e63f..afc0a083f 100644
--- a/src/gfx_func.h
+++ b/src/gfx_func.h
@@ -118,7 +118,7 @@ int DrawStringMultiLine(int left, int right, int top, int bottom, StringID str,
void DrawCharCentered(uint32 c, int x, int y, TextColour colour);
void GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectMode mode = FILLRECT_OPAQUE);
-void GfxDrawLine(int left, int top, int right, int bottom, int colour);
+void GfxDrawLine(int left, int top, int right, int bottom, int colour, int width = 1);
void DrawBox(int x, int y, int dx1, int dy1, int dx2, int dy2, int dx3, int dy3);
Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize = FS_NORMAL);