update to 1.5.2
--HG-- branch : openttd
This commit is contained in:
39
src/gfx.cpp
39
src/gfx.cpp
@@ -1,4 +1,4 @@
|
||||
/* $Id: gfx.cpp 27172 2015-02-28 17:13:07Z frosch $ */
|
||||
/* $Id: gfx.cpp 27351 2015-07-30 18:53:31Z frosch $ */
|
||||
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
@@ -175,40 +175,35 @@ static inline void GfxDoDrawLine(void *video, int x, int y, int x2, int y2, int
|
||||
|
||||
assert(width > 0);
|
||||
|
||||
if (y2 == y) {
|
||||
/* Special case: horizontal line. */
|
||||
blitter->DrawLine(video,
|
||||
Clamp(x, 0, screen_width), y,
|
||||
Clamp(x2, 0, screen_width), y2,
|
||||
screen_width, screen_height, colour, width, dash);
|
||||
return;
|
||||
}
|
||||
if (x2 == x) {
|
||||
/* Special case: vertical line. */
|
||||
blitter->DrawLine(video,
|
||||
x, Clamp(y, 0, screen_height),
|
||||
x2, Clamp(y2, 0, screen_height),
|
||||
screen_width, screen_height, colour, width, dash);
|
||||
if (y2 == y || x2 == x) {
|
||||
/* Special case: horizontal/vertical line. All checks already done in GfxPreprocessLine. */
|
||||
blitter->DrawLine(video, x, y, x2, y2, screen_width, screen_height, colour, width, dash);
|
||||
return;
|
||||
}
|
||||
|
||||
int grade_y = y2 - y;
|
||||
int grade_x = x2 - x;
|
||||
|
||||
/* Clipping rectangle. Slightly extended so we can ignore the width of the line. */
|
||||
uint extra = CeilDiv(3 * width, 4); // not less then "width * sqrt(2) / 2"
|
||||
Rect clip = { -extra, -extra, screen_width - 1 + extra, screen_height - 1 + extra };
|
||||
|
||||
/* prevent integer overflows. */
|
||||
int margin = 1;
|
||||
while (INT_MAX / abs(grade_y) < max(abs(x), abs(screen_width - x))) {
|
||||
while (INT_MAX / abs(grade_y) < max(abs(clip.left - x), abs(clip.right - x))) {
|
||||
grade_y /= 2;
|
||||
grade_x /= 2;
|
||||
margin *= 2; // account for rounding errors
|
||||
}
|
||||
|
||||
/* If the line is outside the screen on the same side at X positions 0
|
||||
* and screen_width, we don't need to draw anything. */
|
||||
int offset_0 = y - x * grade_y / grade_x;
|
||||
int offset_width = y + (screen_width - x) * grade_y / grade_x;
|
||||
if ((offset_0 > screen_height + width / 2 + margin && offset_width > screen_height + width / 2 + margin) ||
|
||||
(offset_0 < -width / 2 - margin && offset_width < -width / 2 - margin)) {
|
||||
/* Imagine that the line is infinitely long and it intersects with
|
||||
* infinitely long left and right edges of the clipping rectangle.
|
||||
* If both intersection points are outside the clipping rectangle
|
||||
* and both on the same side of it, we don't need to draw anything. */
|
||||
int left_isec_y = y + (clip.left - x) * grade_y / grade_x;
|
||||
int right_isec_y = y + (clip.right - x) * grade_y / grade_x;
|
||||
if ((left_isec_y > clip.bottom + margin && right_isec_y > clip.bottom + margin) ||
|
||||
(left_isec_y < clip.top - margin && right_isec_y < clip.top - margin)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user