Commit 0b45edb7 authored by Philip Lafleur's avatar Philip Lafleur Committed by Philip Lafleur
Browse files

Really fixed all cases of the perspective tool preview breaking with

2004-10-27  Philip Lafleur <plafleur@cvs.gnome.org>

	* app/display/gimpdisplayshell-preview.c: Really fixed all cases
	of the perspective tool preview breaking with certain orientations by
	using triangles instead of quads.
parent 2f307391
2004-10-27 Philip Lafleur <plafleur@cvs.gnome.org>
* app/display/gimpdisplayshell-preview.c: Really fixed all cases
of the perspective tool preview breaking with certain orientations by
using triangles instead of quads.
2004-10-27 Philip Lafleur <plafleur@cvs.gnome.org>
 
* app/display/gimpdisplayshell-preview.c: Hopefully fixed all cases
......
......@@ -49,7 +49,16 @@ static void gimp_display_shell_draw_quad (GimpDrawable *texture,
gint *y,
gfloat *u,
gfloat *v);
static void gimp_display_shell_draw_quad_row (GimpDrawable *texture,
static void gimp_display_shell_draw_tri (GimpDrawable *texture,
GdkDrawable *dest,
GimpChannel *mask,
gint mask_offx,
gint mask_offy,
gint *x,
gint *y,
gfloat *u,
gfloat *v);
static void gimp_display_shell_draw_tri_row (GimpDrawable *texture,
GdkDrawable *dest,
GdkPixbuf *row,
gint x1,
......@@ -59,7 +68,7 @@ static void gimp_display_shell_draw_quad_row (GimpDrawable *texture,
gfloat u2,
gfloat v2,
gint y);
static void gimp_display_shell_draw_quad_row_mask (GimpDrawable *texture,
static void gimp_display_shell_draw_tri_row_mask (GimpDrawable *texture,
GdkDrawable *dest,
GdkPixbuf *row,
GimpChannel *mask,
......@@ -72,7 +81,7 @@ static void gimp_display_shell_draw_quad_row_mask (GimpDrawable *texture,
gfloat u2,
gfloat v2,
gint y);
static void gimp_display_shell_trace_quad_edge (gint *dest,
static void gimp_display_shell_trace_tri_edge (gint *dest,
gint x1,
gint y1,
gint x2,
......@@ -176,8 +185,32 @@ gimp_display_shell_draw_quad (GimpDrawable *texture,
gint mask_offy,
gint *x,
gint *y,
gfloat *u, /* texture coords */
gfloat *v) /* 0.0 ... tex width, height */
gfloat *u,
gfloat *v)
{
gint x2 [3], y2 [3];
gfloat u2 [3], v2 [3];
x2 [0] = x [3]; y2 [0] = y [3]; u2 [0] = u [3]; v2 [0] = v [3];
x2 [1] = x [2]; y2 [1] = y [2]; u2 [1] = u [2]; v2 [1] = v [2];
x2 [2] = x [1]; y2 [2] = y [1]; u2 [2] = u [1]; v2 [2] = v [1];
gimp_display_shell_draw_tri (texture, dest, mask, mask_offx, mask_offy,
x, y, u, v);
gimp_display_shell_draw_tri (texture, dest, mask, mask_offx, mask_offy,
x2, y2, u2, v2);
}
static void
gimp_display_shell_draw_tri (GimpDrawable *texture,
GdkDrawable *dest,
GimpChannel *mask,
gint mask_offx,
gint mask_offy,
gint *x,
gint *y,
gfloat *u, /* texture coords */
gfloat *v) /* 0.0 ... tex width, height */
{
GdkPixbuf *row;
gint dwidth, dheight; /* clip boundary */
......@@ -200,33 +233,6 @@ gimp_display_shell_draw_quad (GimpDrawable *texture,
gdk_drawable_get_size (dest, &dwidth, &dheight);
/* is the preview in the window? */
{
gboolean in_window_x, in_window_y;
in_window_x = in_window_y = FALSE;
for (j = 0; j < 4; j++)
{
if (x [j] >= 0)
in_window_x = TRUE;
if (y [j] >= 0)
in_window_y = TRUE;
}
if (! (in_window_x && in_window_y))
return;
in_window_x = in_window_y = FALSE;
for (j = 0; j < 4; j++)
{
if (x [j] < dwidth)
in_window_x = TRUE;
if (y [j] < dheight)
in_window_y = TRUE;
}
if (! (in_window_x && in_window_y))
return;
}
row = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
mask ? TRUE : gimp_drawable_has_alpha (texture),
8, dwidth, 1);
......@@ -234,8 +240,8 @@ gimp_display_shell_draw_quad (GimpDrawable *texture,
/* sort vertices in order of y-coordinate */
for (j = 0; j < 4; j++)
for (k = j + 1; k < 4; k++)
for (j = 0; j < 3; j++)
for (k = j + 1; k < 3; k++)
if (y [k] < y [j])
{
gint tmp;
......@@ -247,139 +253,107 @@ gimp_display_shell_draw_quad (GimpDrawable *texture,
ftmp = v [k]; v [k] = v [j]; v [j] = ftmp;
}
if (y [3] == y [0])
if (y [2] == y [0])
return;
l_edge = g_malloc ((y [3] - y [0]) * sizeof (gint));
r_edge = g_malloc ((y [3] - y [0]) * sizeof (gint));
/* draw the quad */
#define QUAD_TRACE_L_EDGE(a, b) \
if (y [a] != y [b]) \
{ \
gimp_display_shell_trace_quad_edge (l_edge, \
x [a], y [a], \
x [b], y [b]); \
left = l_edge; \
dul = (u [b] - u [a]) / (y [b] - y [a]); \
dvl = (v [b] - v [a]) / (y [b] - y [a]); \
u_l = u [a]; \
v_l = v [a]; \
}
l_edge = g_malloc ((y [2] - y [0]) * sizeof (gint));
r_edge = g_malloc ((y [2] - y [0]) * sizeof (gint));
#define QUAD_TRACE_R_EDGE(a, b) \
if (y [a] != y [b]) \
{ \
gimp_display_shell_trace_quad_edge (r_edge, \
x [a], y [a], \
x [b], y [b]); \
right = r_edge; \
dur = (u [b] - u [a]) / (y [b] - y [a]); \
dvr = (v [b] - v [a]) / (y [b] - y [a]); \
u_r = u [a]; \
v_r = v [a]; \
}
/* draw the triangle */
gimp_display_shell_trace_tri_edge (l_edge,
x [0], y [0],
x [2], y [2]);
left = l_edge;
dul = (u [2] - u [0]) / (y [2] - y [0]);
dvl = (v [2] - v [0]) / (y [2] - y [0]);
u_l = u [0];
v_l = v [0];
#define QUAD_DRAW_SECTION(a, b) \
if (y [a] != y [b]) \
for (ry = y [a]; ry < y [b]; ry++) \
{ \
if (ry >= 0 && ry < dheight) \
{ \
if (mask) \
gimp_display_shell_draw_quad_row_mask \
(texture, dest, row, \
mask, mask_offx, mask_offy,\
*left, u_l, v_l, \
*right, u_r, v_r, \
ry); \
else \
gimp_display_shell_draw_quad_row (texture, dest, row, \
*left, u_l, v_l, \
*right, u_r, v_r, \
ry); \
} \
left ++; right ++; \
u_l += dul; v_l += dvl; \
u_r += dur; v_r += dvr; \
} \
if ((((x [0] > x [1]) && (x [3] > x [2])) ||
((x [0] < x [1]) && (x [3] < x [2]))) &&
(! (((x [0] > x [2]) && (x [0] < x [1]) && (x [3] < x [2])) ||
((x [0] < x [2]) && (x [0] > x [1]) && (x [3] > x [2])) ||
((x [3] > x [1]) && (x [3] < x [2]) && (x [0] < x [1])) ||
((x [3] < x [1]) && (x [3] > x [2]) && (x [0] > x [2])))))
if (y [0] != y [1])
{
/*
* v0
* |--__
* _____ |....--_ v1 ____
* | |
* | |
* _____ |.....__| ______
* |__--- v2
* v3
*/
QUAD_TRACE_L_EDGE (0, 3);
QUAD_TRACE_R_EDGE (0, 1);
QUAD_DRAW_SECTION (0, 1); /* top section */
QUAD_TRACE_R_EDGE (1, 2);
QUAD_DRAW_SECTION (1, 2); /* middle section */
QUAD_TRACE_R_EDGE (2, 3);
QUAD_DRAW_SECTION (2, 3); /* bottom section */
gimp_display_shell_trace_tri_edge (r_edge,
x [0], y [0],
x [1], y [1]);
right = r_edge;
dur = (u [1] - u [0]) / (y [1] - y [0]);
dvr = (v [1] - v [0]) / (y [1] - y [0]);
u_r = u [0];
v_r = v [0];
for (ry = y [0]; ry < y [1]; ry++)
{
if (ry >= 0 && ry < dheight)
{
if (mask)
gimp_display_shell_draw_tri_row_mask
(texture, dest, row,
mask, mask_offx, mask_offy,
*left, u_l, v_l,
*right, u_r, v_r,
ry);
else
gimp_display_shell_draw_tri_row (texture, dest, row,
*left, u_l, v_l,
*right, u_r, v_r,
ry);
}
left ++; right ++;
u_l += dul; v_l += dvl;
u_r += dur; v_r += dvr;
}
}
else
{
/*
* v0
* /-___
* -------- /.....-- v1 ---
* / /
* ___ v2 /__...../________
* ---_/
* v3
*/
QUAD_TRACE_L_EDGE (0, 2);
QUAD_TRACE_R_EDGE (0, 1);
QUAD_DRAW_SECTION (0, 1); /* top section */
QUAD_TRACE_R_EDGE (1, 3);
QUAD_DRAW_SECTION (1, 2); /* middle section */
QUAD_TRACE_L_EDGE (2, 3);
QUAD_DRAW_SECTION (2, 3); /* bottom section */
if (y [1] != y [2])
{
gimp_display_shell_trace_tri_edge (r_edge,
x [1], y [1],
x [2], y [2]);
right = r_edge;
dur = (u [2] - u [1]) / (y [2] - y [1]);
dvr = (v [2] - v [1]) / (y [2] - y [1]);
u_r = u [1];
v_r = v [1];
for (ry = y [1]; ry < y [2]; ry++)
{
if (ry >= 0 && ry < dheight)
{
if (mask)
gimp_display_shell_draw_tri_row_mask
(texture, dest, row,
mask, mask_offx, mask_offy,
*left, u_l, v_l,
*right, u_r, v_r,
ry);
else
gimp_display_shell_draw_tri_row (texture, dest, row,
*left, u_l, v_l,
*right, u_r, v_r,
ry);
}
left ++; right ++;
u_l += dul; v_l += dvl;
u_r += dur; v_r += dvr;
}
}
#undef QUAD_TRACE_L_EDGE
#undef QUAD_TRACE_R_EDGE
#undef QUAD_DRAW_SECTION
g_object_unref (row);
g_free (l_edge);
g_free (r_edge);
}
static void
gimp_display_shell_draw_quad_row (GimpDrawable *texture,
GdkDrawable *dest,
GdkPixbuf *row,
gint x1,
gfloat u1,
gfloat v1,
gint x2,
gfloat u2,
gfloat v2,
gint y)
gimp_display_shell_draw_tri_row (GimpDrawable *texture,
GdkDrawable *dest,
GdkPixbuf *row,
gint x1,
gfloat u1,
gfloat v1,
gint x2,
gfloat u2,
gfloat v2,
gint y)
{
TileManager *tiles;
guchar *pptr;
......@@ -527,19 +501,19 @@ gimp_display_shell_draw_quad_row (GimpDrawable *texture,
}
static void
gimp_display_shell_draw_quad_row_mask (GimpDrawable *texture,
GdkDrawable *dest,
GdkPixbuf *row,
GimpChannel *mask,
gint mask_offx,
gint mask_offy,
gint x1,
gfloat u1,
gfloat v1,
gint x2,
gfloat u2,
gfloat v2,
gint y)
gimp_display_shell_draw_tri_row_mask (GimpDrawable *texture,
GdkDrawable *dest,
GdkPixbuf *row,
GimpChannel *mask,
gint mask_offx,
gint mask_offy,
gint x1,
gfloat u1,
gfloat v1,
gint x2,
gfloat u2,
gfloat v2,
gint y)
{
TileManager *tiles, *masktiles;
guchar *pptr;
......@@ -722,11 +696,11 @@ gimp_display_shell_draw_quad_row_mask (GimpDrawable *texture,
}
static void
gimp_display_shell_trace_quad_edge (gint *dest,
gint x1,
gint y1,
gint x2,
gint y2)
gimp_display_shell_trace_tri_edge (gint *dest,
gint x1,
gint y1,
gint x2,
gint y2)
{
const gint dy = y2 - y1;
gint dx;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment