(svn r22291) -Add: a linewidth argument to GfxDrawLine() and Blitter::DrawLine().

This commit is contained in:
frosch 2011-04-02 16:39:30 +00:00
parent 7659575cfa
commit b18211bb9d
4 changed files with 78 additions and 25 deletions

View File

@ -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;
}
}
}

View File

@ -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.

View File

@ -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);
}
/**

View File

@ -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);