From b18211bb9d1f8f758e814a5b5f6dc74e78183c51 Mon Sep 17 00:00:00 2001 From: frosch Date: Sat, 2 Apr 2011 16:39:30 +0000 Subject: (svn r22291) -Add: a linewidth argument to GfxDrawLine() and Blitter::DrawLine(). --- src/blitter/base.cpp | 83 ++++++++++++++++++++++++++++++++++++++++++---------- src/blitter/base.hpp | 2 +- src/gfx.cpp | 16 +++++----- src/gfx_func.h | 2 +- 4 files changed, 78 insertions(+), 25 deletions(-) (limited to 'src') 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); -- cgit v1.2.3-54-g00ecf