gimp r25033 - in branches/weskaggs: . app/display app/tools
- From: weskaggs svn gnome org
- To: svn-commits-list gnome org
- Subject: gimp r25033 - in branches/weskaggs: . app/display app/tools
- Date: Tue, 4 Mar 2008 19:17:18 +0000 (GMT)
Author: weskaggs
Date: Tue Mar 4 19:17:18 2008
New Revision: 25033
URL: http://svn.gnome.org/viewvc/gimp?rev=25033&view=rev
Log:
Bill Skaggs <weskaggs primate ucdavis edu>
* app/tools/gimptransformtool.[ch]
* app/tools/gimptransformoptions.[ch]
* app/display/gimpdisplayshell-preview.c: apply patch
from Tom Lechner (comment #35 in bug #167926) to allow
tranlucency in transform tool previews, for testing.
Modified:
branches/weskaggs/ChangeLog
branches/weskaggs/app/display/gimpdisplayshell-preview.c
branches/weskaggs/app/tools/gimptransformoptions.c
branches/weskaggs/app/tools/gimptransformoptions.h
branches/weskaggs/app/tools/gimptransformtool.c
branches/weskaggs/app/tools/gimptransformtool.h
Modified: branches/weskaggs/app/display/gimpdisplayshell-preview.c
==============================================================================
--- branches/weskaggs/app/display/gimpdisplayshell-preview.c (original)
+++ branches/weskaggs/app/display/gimpdisplayshell-preview.c Tue Mar 4 19:17:18 2008
@@ -28,10 +28,12 @@
#include "core/gimpimage.h"
#include "core/gimpdrawable.h"
#include "core/gimpchannel.h"
+#include "core/gimptoolinfo.h"
#include "base/tile-manager.h"
#include "tools/gimpperspectivetool.h"
+#include "tools/gimptransformoptions.h"
#include "tools/gimptransformtool.h"
#include "tools/tool_manager.h"
@@ -55,29 +57,39 @@
gint *x,
gint *y,
gfloat *u,
- gfloat *v);
+ gfloat *v,
+ gint opacity);
static void gimp_display_shell_draw_tri (GimpDrawable *texture,
GdkDrawable *dest,
+ GdkPixbuf *area,
+ gint area_offx,
+ gint area_offy,
GimpChannel *mask,
gint mask_offx,
gint mask_offy,
gint *x,
gint *y,
gfloat *u,
- gfloat *v);
+ gfloat *v,
+ gint opacity);
static void gimp_display_shell_draw_tri_row (GimpDrawable *texture,
GdkDrawable *dest,
- GdkPixbuf *row,
+ GdkPixbuf *area,
+ gint area_offx,
+ gint area_offy,
gint x1,
gfloat u1,
gfloat v1,
gint x2,
gfloat u2,
gfloat v2,
- gint y);
+ gint y,
+ gint opacity);
static void gimp_display_shell_draw_tri_row_mask (GimpDrawable *texture,
GdkDrawable *dest,
- GdkPixbuf *row,
+ GdkPixbuf *area,
+ gint area_offx,
+ gint area_offy,
GimpChannel *mask,
gint mask_offx,
gint mask_offy,
@@ -87,7 +99,8 @@
gint x2,
gfloat u2,
gfloat v2,
- gint y);
+ gint y,
+ gint opacity);
static void gimp_display_shell_trace_tri_edge (gint *dest,
gint x1,
gint y1,
@@ -96,187 +109,224 @@
/* public functions */
+/**
+ * gimp_display_shell_preview_transform:
+ * @shell: the #GimpDisplayShell
+ *
+ * If the active tool as reported by tool_manager_get_active() is a
+ * #GimpTransformTool and the tool has a valid drawable, and the tool has
+ * use_grid true (which, incidentally, is not the same thing as the preview
+ * type), and the area of the transformed preview is convex,
+ * then proceed with drawing the preview.
+ *
+ * The preview area is divided into 1 or more quadrilaterals, and drawn with
+ * gimp_display_shell_draw_quad(), which in turn breaks it down into 2
+ * triangles, and draws row by row. If the tool is the Perspective tool, then
+ * more small quadrilaterals are used to compensate for the little rectangles
+ * not being the same size. In other words, all the transform tools are
+ * affine transformations except perspective, so approximate it with a
+ * few subdivisions.
+ **/
void
gimp_display_shell_preview_transform (GimpDisplayShell *shell)
{
- g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
-
- if (gimp_display_shell_get_show_transform (shell))
- {
- GimpTool *tool;
- GimpTransformTool *tr_tool;
- gdouble z1, z2, z3, z4;
-
- tool = tool_manager_get_active (shell->display->image->gimp);
-
- if (! GIMP_IS_TRANSFORM_TOOL (tool) ||
- ! GIMP_IS_DRAWABLE (tool->drawable))
- return;
+ GimpTool *tool;
+ GimpTransformTool *tr_tool;
+ gdouble z1, z2, z3, z4;
+
+ GimpChannel *mask;
+ gint mask_x1, mask_y1;
+ gint mask_x2, mask_y2;
+ gint mask_offx, mask_offy;
+
+ gint columns, rows;
+ gint j, k, sub;
+
+ /* x and y get filled with the screen coordinates of each corner of
+ * each quadrilateral subdivision of the transformed area. u and v
+ * are the corresponding points in the mask
+ */
+ gfloat du, dv, dx, dy;
+ gint x[MAX_SUB_COLS * MAX_SUB_ROWS][4],
+ y[MAX_SUB_COLS * MAX_SUB_ROWS][4];
+ gfloat u[MAX_SUB_COLS * MAX_SUB_ROWS][4],
+ v[MAX_SUB_COLS * MAX_SUB_ROWS][4];
+ gint preview_opacity;
- tr_tool = GIMP_TRANSFORM_TOOL (tool);
+ g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
- if (! tr_tool->use_grid)
- return;
+ if (! gimp_display_shell_get_show_transform (shell) || ! shell->canvas)
+ return;
- z1 = ((tr_tool->tx2 - tr_tool->tx1) * (tr_tool->ty4 - tr_tool->ty1) -
- (tr_tool->tx4 - tr_tool->tx1) * (tr_tool->ty2 - tr_tool->ty1));
- z2 = ((tr_tool->tx4 - tr_tool->tx1) * (tr_tool->ty3 - tr_tool->ty1) -
- (tr_tool->tx3 - tr_tool->tx1) * (tr_tool->ty4 - tr_tool->ty1));
- z3 = ((tr_tool->tx4 - tr_tool->tx2) * (tr_tool->ty3 - tr_tool->ty2) -
- (tr_tool->tx3 - tr_tool->tx2) * (tr_tool->ty4 - tr_tool->ty2));
- z4 = ((tr_tool->tx3 - tr_tool->tx2) * (tr_tool->ty1 - tr_tool->ty2) -
- (tr_tool->tx1 - tr_tool->tx2) * (tr_tool->ty3 - tr_tool->ty2));
+ tool = tool_manager_get_active (shell->display->image->gimp);
- /* only draw convex polygons */
+ if (! GIMP_IS_TRANSFORM_TOOL (tool) ||
+ ! GIMP_IS_DRAWABLE (tool->drawable))
+ return;
- if ((z1 * z2 > 0) && (z3 * z4 > 0))
- {
- GimpChannel *mask;
- gint mask_x1, mask_y1;
- gint mask_x2, mask_y2;
- gint mask_offx, mask_offy;
-
- gint columns, rows;
- gint j, k, sub;
-
- gfloat du, dv, dx, dy;
- gint x[MAX_SUB_COLS * MAX_SUB_ROWS][4],
- y[MAX_SUB_COLS * MAX_SUB_ROWS][4];
- gfloat u[MAX_SUB_COLS * MAX_SUB_ROWS][4],
- v[MAX_SUB_COLS * MAX_SUB_ROWS][4];
-
- mask = NULL;
- mask_offx = mask_offy = 0;
-
- if (gimp_drawable_mask_bounds (tool->drawable,
- &mask_x1, &mask_y1,
- &mask_x2, &mask_y2))
- {
- mask = gimp_image_get_mask (shell->display->image);
+ tr_tool = GIMP_TRANSFORM_TOOL (tool);
- gimp_item_offsets (GIMP_ITEM (tool->drawable),
- &mask_offx, &mask_offy);
- }
+ if (! tr_tool->use_grid)
+ return;
- if (GIMP_IS_PERSPECTIVE_TOOL (tr_tool))
- {
- /* approximate perspective transform by subdivision
- *
- * increase number of columns/rows to increase precision
- */
- columns = MAX_SUB_COLS;
- rows = MAX_SUB_ROWS;
- }
- else
- {
- /* for affine transforms subdivision has no effect
- */
- columns = 1;
- rows = 1;
- }
+ z1 = ((tr_tool->tx2 - tr_tool->tx1) * (tr_tool->ty4 - tr_tool->ty1) -
+ (tr_tool->tx4 - tr_tool->tx1) * (tr_tool->ty2 - tr_tool->ty1));
+ z2 = ((tr_tool->tx4 - tr_tool->tx1) * (tr_tool->ty3 - tr_tool->ty1) -
+ (tr_tool->tx3 - tr_tool->tx1) * (tr_tool->ty4 - tr_tool->ty1));
+ z3 = ((tr_tool->tx4 - tr_tool->tx2) * (tr_tool->ty3 - tr_tool->ty2) -
+ (tr_tool->tx3 - tr_tool->tx2) * (tr_tool->ty4 - tr_tool->ty2));
+ z4 = ((tr_tool->tx3 - tr_tool->tx2) * (tr_tool->ty1 - tr_tool->ty2) -
+ (tr_tool->tx1 - tr_tool->tx2) * (tr_tool->ty3 - tr_tool->ty2));
+
+ /* only draw convex polygons */
+
+ if (! ((z1 * z2 > 0) && (z3 * z4 > 0))) return;
+
+ preview_opacity =
+ GIMP_TRANSFORM_OPTIONS (tool->tool_info->tool_options)
+ ->preview_opacity * 255 / 100;
+
+ mask = NULL;
+ mask_offx = mask_offy = 0;
+
+ if (gimp_drawable_mask_bounds (tool->drawable,
+ &mask_x1, &mask_y1,
+ &mask_x2, &mask_y2))
+ {
+ mask = gimp_image_get_mask (shell->display->image);
+
+ gimp_item_offsets (GIMP_ITEM (tool->drawable),
+ &mask_offx, &mask_offy);
+ }
+
+ if (GIMP_IS_PERSPECTIVE_TOOL (tr_tool))
+ {
+ /* approximate perspective transform by subdivision
+ *
+ * increase number of columns/rows to increase precision
+ */
+ columns = MAX_SUB_COLS;
+ rows = MAX_SUB_ROWS;
+ }
+ else
+ {
+ /* for affine transforms subdivision has no effect
+ */
+ columns = 1;
+ rows = 1;
+ }
- dx = (tr_tool->x2 - tr_tool->x1) / ((gfloat) columns);
- dy = (tr_tool->y2 - tr_tool->y1) / ((gfloat) rows);
+ dx = (tr_tool->x2 - tr_tool->x1) / ((gfloat) columns);
+ dy = (tr_tool->y2 - tr_tool->y1) / ((gfloat) rows);
- du = (mask_x2 - mask_x1) / ((gfloat) columns);
- dv = (mask_y2 - mask_y1) / ((gfloat) rows);
+ du = (mask_x2 - mask_x1) / ((gfloat) columns);
+ dv = (mask_y2 - mask_y1) / ((gfloat) rows);
#define CALC_VERTEX(col, row, sub, index) \
- { \
- gdouble tx1, ty1; \
- gdouble tx2, ty2; \
+ { \
+ gdouble tx1, ty1; \
+ gdouble tx2, ty2; \
\
- u[sub][index] = tr_tool->x1 + (dx * (col + (index & 1))); \
- v[sub][index] = tr_tool->y1 + (dy * (row + (index >> 1))); \
+ u[sub][index] = tr_tool->x1 + (dx * (col + (index & 1))); \
+ v[sub][index] = tr_tool->y1 + (dy * (row + (index >> 1))); \
\
- gimp_matrix3_transform_point (&tr_tool->transform, \
- u[sub][index], v[sub][index], \
- &tx1, &ty1); \
+ gimp_matrix3_transform_point (&tr_tool->transform, \
+ u[sub][index], v[sub][index], \
+ &tx1, &ty1); \
\
- gimp_display_shell_transform_xy_f (shell, \
- tx1, ty1, \
- &tx2, &ty2, \
- FALSE); \
- x[sub][index] = (gint) tx2; \
- y[sub][index] = (gint) ty2; \
+ gimp_display_shell_transform_xy_f (shell, \
+ tx1, ty1, \
+ &tx2, &ty2, \
+ FALSE); \
+ x[sub][index] = (gint) tx2; \
+ y[sub][index] = (gint) ty2; \
\
- u[sub][index] = mask_x1 + (du * (col + (index & 1))); \
- v[sub][index] = mask_y1 + (dv * (row + (index >> 1))); \
- }
+ u[sub][index] = mask_x1 + (du * (col + (index & 1))); \
+ v[sub][index] = mask_y1 + (dv * (row + (index >> 1))); \
+ }
#define COPY_VERTEX(subdest, idest, subsrc, isrc) \
- x[subdest][idest] = x[subsrc][isrc]; \
- y[subdest][idest] = y[subsrc][isrc]; \
- u[subdest][idest] = u[subsrc][isrc]; \
- v[subdest][idest] = v[subsrc][isrc];
-
- /*
- * upper left corner subdivision: calculate all vertices
- */
+ x[subdest][idest] = x[subsrc][isrc]; \
+ y[subdest][idest] = y[subsrc][isrc]; \
+ u[subdest][idest] = u[subsrc][isrc]; \
+ v[subdest][idest] = v[subsrc][isrc];
- for (j = 0; j < 4; j++)
- {
- CALC_VERTEX (0, 0, 0, j);
- }
+ /*
+ * upper left corner subdivision: calculate all vertices
+ */
- /*
- * top row subdivisions: calculate only right side vertices
- */
+ for (j = 0; j < 4; j++)
+ {
+ CALC_VERTEX (0, 0, 0, j);
+ }
- for (j = 1; j < columns; j++)
- {
- COPY_VERTEX (j, 0, j - 1, 1);
- CALC_VERTEX (j, 0, j, 1);
- COPY_VERTEX (j, 2, j - 1, 3);
- CALC_VERTEX (j, 0, j, 3);
- }
+ /*
+ * top row subdivisions: calculate only right side vertices
+ */
- /*
- * left column subdivisions: calculate only bottom side vertices
- */
+ for (j = 1; j < columns; j++)
+ {
+ COPY_VERTEX (j, 0, j - 1, 1);
+ CALC_VERTEX (j, 0, j, 1);
+ COPY_VERTEX (j, 2, j - 1, 3);
+ CALC_VERTEX (j, 0, j, 3);
+ }
- for (j = 1, sub = columns; j < rows; j++, sub += columns)
- {
- COPY_VERTEX (sub, 0, sub - columns, 2);
- COPY_VERTEX (sub, 1, sub - columns, 3);
- CALC_VERTEX (0, j, sub, 2);
- CALC_VERTEX (0, j, sub, 3);
- }
+ /*
+ * left column subdivisions: calculate only bottom side vertices
+ */
- /*
- * the rest: calculate only the bottom-right vertex
- */
+ for (j = 1, sub = columns; j < rows; j++, sub += columns)
+ {
+ COPY_VERTEX (sub, 0, sub - columns, 2);
+ COPY_VERTEX (sub, 1, sub - columns, 3);
+ CALC_VERTEX (0, j, sub, 2);
+ CALC_VERTEX (0, j, sub, 3);
+ }
- for (j = 1, sub = columns; j < rows; j++)
- {
- sub++;
+ /*
+ * the rest: calculate only the bottom-right vertex
+ */
- for (k = 1; k < columns; k++, sub++)
- {
- COPY_VERTEX (sub, 0, sub - 1, 1);
- COPY_VERTEX (sub, 1, sub - columns, 3);
- COPY_VERTEX (sub, 2, sub - 1, 3);
- CALC_VERTEX (k, j, sub, 3);
- }
- }
+ for (j = 1, sub = columns; j < rows; j++)
+ {
+ sub++;
+
+ for (k = 1; k < columns; k++, sub++)
+ {
+ COPY_VERTEX (sub, 0, sub - 1, 1);
+ COPY_VERTEX (sub, 1, sub - columns, 3);
+ COPY_VERTEX (sub, 2, sub - 1, 3);
+ CALC_VERTEX (k, j, sub, 3);
+ }
+ }
#undef CALC_VERTEX
#undef COPY_VERTEX
- k = columns * rows;
- for (j = 0; j < k; j++)
- gimp_display_shell_draw_quad (tool->drawable,
- GDK_DRAWABLE (GTK_WIDGET (shell->canvas)->window),
- mask, mask_offx, mask_offy,
- x[j], y[j], u[j], v[j]);
+ k = columns * rows;
+ for (j = 0; j < k; j++)
+ gimp_display_shell_draw_quad (tool->drawable,
+ GDK_DRAWABLE (GTK_WIDGET (shell->canvas)->window),
+ mask, mask_offx, mask_offy,
+ x[j], y[j], u[j], v[j],
+ preview_opacity);
- }
- }
}
/* private functions */
+/**
+ * gimp_display_shell_draw_quad:
+ * @texture: the #GimpDrawable to be previewed
+ * @dest: the #GdkDrawable for that @texture lives on
+ * @mask: a #GimpChannel
+ * @opacity: the opacity of the preview
+ *
+ * Take a quadrilateral, divide it into two triangles, and draw those
+ * with gimp_display_shell_draw_tri().
+ **/
static void
gimp_display_shell_draw_quad (GimpDrawable *texture,
GdkDrawable *dest,
@@ -286,62 +336,118 @@
gint *x,
gint *y,
gfloat *u,
- gfloat *v)
+ gfloat *v,
+ gint opacity)
{
- gint x2[3], y2[3];
- gfloat u2[3], v2[3];
+ gint x2[3], y2[3];
+ gfloat u2[3], v2[3];
+ gint minx, maxx, miny, maxy; /* screen bounds of the quad */
+ gint dwidth, dheight; /* dimensions of dest */
+ GdkPixbuf *area; /* quad sized area with dest pixels */
+ gint c;
+ g_return_if_fail(GDK_IS_DRAWABLE (dest));
+
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);
+ /* Allocate a box around the quad to compute preview data into
+ * and fill it with the original window contents.
+ */
+
+ gdk_drawable_get_size (dest, &dwidth, &dheight);
+
+ /* find bounds of quad in order to only grab as much of dest as needed */
+
+ minx = maxx = x[0];
+ miny = maxy = y[0];
+ for (c = 1; c < 4; c++)
+ {
+ if (x[c] < minx) minx = x[c];
+ else if (x[c] > maxx) maxx = x[c];
+
+ if (y[c] < miny) miny = y[c];
+ else if (y[c] > maxy) maxy = y[c];
+ }
+ if (minx < 0) minx = 0;
+ if (miny < 0) miny = 0;
+ if (maxx > dwidth - 1) maxx=dwidth - 1;
+ if (maxy > dheight - 1) maxy=dheight - 1;
+
+ area = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+ mask ? TRUE : gimp_drawable_has_alpha (texture),
+ 8, maxx - minx + 1, maxy - miny + 1);
+ g_return_if_fail (area != NULL);
+
+
+ /* get original data from dest in order to potentially take
+ * into account opacity
+ */
+
+ if (opacity != 255)
+ gdk_pixbuf_get_from_drawable (area, dest, NULL, minx, miny,
+ 0, 0, maxx - minx + 1, maxy - miny + 1);
+
+ gimp_display_shell_draw_tri (texture, dest, area, minx, miny,
+ mask, mask_offx, mask_offy,
+ x, y, u, v, opacity);
+ gimp_display_shell_draw_tri (texture, dest, area, minx, miny,
+ mask, mask_offx, mask_offy,
+ x2, y2, u2, v2, opacity);
+
+ g_object_unref (area);
}
+/**
+ * gimp_display_shell_draw_tri:
+ * @texture: the thing being transformed
+ * @dest: the #GdkDrawable for that @texture lives on
+ * @area: has prefetched pixel data of dest
+ * @area_offx: x coordinate of area in dest
+ * @area_offy: y coordinate of area in dest
+ * @x: Array of the three x coords of triangle
+ * @y: Array of the three y coords of triangle
+ *
+ * This draws a triangle onto dest by breaking it down into pixel rows, and
+ * then calling gimp_display_shell_draw_tri_row() and
+ * gimp_display_shell_draw_tri_row_mask() to do the actual pixel changing.
+ **/
static void
gimp_display_shell_draw_tri (GimpDrawable *texture,
GdkDrawable *dest,
+ GdkPixbuf *area,
+ gint area_offx,
+ gint area_offy,
GimpChannel *mask,
gint mask_offx,
gint mask_offy,
gint *x,
gint *y,
gfloat *u, /* texture coords */
- gfloat *v) /* 0.0 ... tex width, height */
+ gfloat *v, /* 0.0 ... tex width, height */
+ gint opacity)
{
- GdkPixbuf *row;
gint dwidth, dheight; /* clip boundary */
gint j, k;
gint ry;
gint *l_edge, *r_edge; /* arrays holding x-coords of edge pixels */
- gint *left, *right;
- gfloat dul, dvl, dur, dvr; /* left and right texture coord deltas */
- gfloat u_l, v_l, u_r, v_r; /* left and right texture coord pairs */
+ gint *left, *right; /* temp pointers into l_edge and r_edge */
+ gfloat dul, dvl, dur, dvr; /* left and right texture coord deltas */
+ gfloat u_l, v_l, u_r, v_r; /* left and right texture coord pairs */
- if (! GIMP_IS_DRAWABLE (texture) ||
- ! GDK_IS_DRAWABLE (dest))
- return;
+ g_return_if_fail (GIMP_IS_DRAWABLE (texture));
+ g_return_if_fail (GDK_IS_DRAWABLE (dest));
+ g_return_if_fail (GDK_IS_PIXBUF (area));
g_return_if_fail (x != NULL && y != NULL && u != NULL && v != NULL);
- gdk_drawable_get_size (dest, &dwidth, &dheight);
-
- if (dwidth > 0 && dheight > 0)
- row = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
- mask ? TRUE : gimp_drawable_has_alpha (texture),
- 8, dwidth, 1);
- else
- return;
-
- g_return_if_fail (row != NULL);
-
left = right = NULL;
dul = dvl = dur = dvr = 0;
u_l = v_l = u_r = v_r = 0;
+ gdk_drawable_get_size (dest, &dwidth, &dheight);
+
/* sort vertices in order of y-coordinate */
for (j = 0; j < 3; j++)
@@ -383,28 +489,36 @@
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,
+ if (mask)
+ for (ry = y[0]; ry < y[1]; ry++)
+ {
+ if (ry >= 0 && ry < dheight)
+ gimp_display_shell_draw_tri_row_mask
+ (texture, dest,
+ area, area_offx, area_offy,
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;
- }
+ ry,
+ opacity);
+ left ++; right ++;
+ u_l += dul; v_l += dvl;
+ u_r += dur; v_r += dvr;
+ }
+ else
+ for (ry = y[0]; ry < y[1]; ry++)
+ {
+ if (ry >= 0 && ry < dheight)
+ gimp_display_shell_draw_tri_row (texture, dest,
+ area, area_offx, area_offy,
+ *left, u_l, v_l,
+ *right, u_r, v_r,
+ ry,
+ opacity);
+ left ++; right ++;
+ u_l += dul; v_l += dvl;
+ u_r += dur; v_r += dvr;
+ }
}
if (y[1] != y[2])
@@ -417,51 +531,70 @@
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;
- }
+ if (mask)
+ for (ry = y[1]; ry < y[2]; ry++)
+ {
+ if (ry >= 0 && ry < dheight)
+ gimp_display_shell_draw_tri_row_mask
+ (texture, dest,
+ area, area_offx, area_offy,
+ mask, mask_offx, mask_offy,
+ *left, u_l, v_l,
+ *right, u_r, v_r,
+ ry,
+ opacity);
+ left ++; right ++;
+ u_l += dul; v_l += dvl;
+ u_r += dur; v_r += dvr;
+ }
+ else
+ for (ry = y[1]; ry < y[2]; ry++)
+ {
+ if (ry >= 0 && ry < dheight)
+ gimp_display_shell_draw_tri_row (texture, dest,
+ area, area_offx, area_offy,
+ *left, u_l, v_l,
+ *right, u_r, v_r,
+ ry,
+ opacity);
+ left ++; right ++;
+ u_l += dul; v_l += dvl;
+ u_r += dur; v_r += dvr;
+ }
}
g_free (l_edge);
g_free (r_edge);
-
- g_object_unref (row);
}
+/**
+ * gimp_display_shell_draw_tri_row:
+ * @texture: the thing being transformed
+ * @dest: the #GdkDrawable for that @texture lives on
+ * @area: has prefetched pixel data of dest
+ *
+ * Called from gimp_display_shell_draw_tri(), this draws a single row of a
+ * triangle onto dest when there is not a mask. The run (x1,y) to (x2,y) in
+ * dest corresponds to the run (u1,v1) to (u2,v2) in texture.
+ **/
static void
gimp_display_shell_draw_tri_row (GimpDrawable *texture,
GdkDrawable *dest,
- GdkPixbuf *row,
+ GdkPixbuf *area,
+ gint area_offx,
+ gint area_offy,
gint x1,
gfloat u1,
gfloat v1,
gint x2,
gfloat u2,
gfloat v2,
- gint y)
+ gint y,
+ gint opacity)
{
- TileManager *tiles;
- guchar *pptr;
- guchar bytes;
+ TileManager *tiles; /* used to get the source texture colors */
+ guchar *pptr; /* points into the pixels of a row of area */
+ guchar bytes; /* the number of channels of area */
gfloat u, v;
gfloat du, dv;
gint dx;
@@ -474,16 +607,17 @@
g_return_if_fail (GIMP_IS_DRAWABLE (texture));
g_return_if_fail (GDK_IS_DRAWABLE (dest));
- g_return_if_fail (GDK_IS_PIXBUF (row));
- g_return_if_fail (gdk_pixbuf_get_bits_per_sample (row) == 8);
- g_return_if_fail (gdk_pixbuf_get_colorspace (row) == GDK_COLORSPACE_RGB);
- g_return_if_fail (gdk_pixbuf_get_has_alpha (row) ==
+ g_return_if_fail (GDK_IS_PIXBUF (area));
+ g_return_if_fail (gdk_pixbuf_get_bits_per_sample (area) == 8);
+ g_return_if_fail (gdk_pixbuf_get_colorspace (area) == GDK_COLORSPACE_RGB);
+ g_return_if_fail (gdk_pixbuf_get_has_alpha (area) ==
gimp_drawable_has_alpha (texture));
- bytes = gdk_pixbuf_get_n_channels (row);
- pptr = gdk_pixbuf_get_pixels (row);
+ bytes = gdk_pixbuf_get_n_channels (area);
+ pptr = gdk_pixbuf_get_pixels (area);
tiles = gimp_drawable_get_tiles (texture);
+ /* make sure the pixel run goes in the positive direction */
if (x1 > x2)
{
gint tmp;
@@ -500,123 +634,244 @@
dv = (v2 - v1) / (x2 - x1);
/* don't calculate unseen pixels */
- if (x1 < 0)
+ if (x1 < area_offx)
{
- u += du * (0 - x1);
- v += dv * (0 - x1);
- x1 = 0;
+ u += du * (area_offx - x1);
+ v += dv * (area_offx - x1);
+ x1 = area_offx;
}
- else if (x1 > gdk_pixbuf_get_width (row))
+ else if (x1 > area_offx + gdk_pixbuf_get_width (area) - 1)
{
return;
}
- if (x2 < 0)
+ if (x2 < area_offx)
{
return;
}
- else if (x2 > gdk_pixbuf_get_width (row))
+ else if (x2 > area_offx + gdk_pixbuf_get_width (area) - 1)
{
- x2 = gdk_pixbuf_get_width (row);
+ x2 = area_offx + gdk_pixbuf_get_width (area) - 1;
}
dx = x2 - x1;
+ if (! dx) return;
- if (! dx)
- return;
+ /* set pptr to the proper position in area */
+ pptr += (y - area_offy) * gdk_pixbuf_get_rowstride(area)
+ + (x1 - area_offx)*bytes;
switch (gimp_drawable_type (texture))
{
case GIMP_INDEXED_IMAGE:
cmap = gimp_drawable_get_colormap (texture);
- while (dx--)
- {
- read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+ if (opacity == 255)
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+
+ offset = pixel[0] + pixel[0] + pixel[0];
+
+ *pptr++ = cmap[offset];
+ *pptr++ = cmap[offset + 1];
+ *pptr++ = cmap[offset + 2];
- offset = pixel[0] + pixel[0] + pixel[0];
-
- *pptr++ = cmap[offset];
- *pptr++ = cmap[offset + 1];
- *pptr++ = cmap[offset + 2];
+ u += du;
+ v += dv;
+ }
+ else
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+
+ offset = pixel[0] + pixel[0] + pixel[0];
+
+ pptr[0] = (pptr[0] * (255-opacity) + cmap[offset ] * opacity)>>8;
+ pptr[1] = (pptr[1] * (255-opacity) + cmap[offset+1] * opacity)>>8;
+ pptr[2] = (pptr[2] * (255-opacity) + cmap[offset+2] * opacity)>>8;
+ pptr += bytes;
- u += du;
- v += dv;
- }
+ u += du;
+ v += dv;
+ }
break;
case GIMP_INDEXEDA_IMAGE:
cmap = gimp_drawable_get_colormap (texture);
- while (dx--)
- {
- read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
-
- offset = pixel[0] + pixel[0] + pixel[0];
+ if (opacity == 255)
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+
+ offset = pixel[0] + pixel[0] + pixel[0];
+
+ *pptr++ = cmap[offset];
+ *pptr++ = cmap[offset + 1];
+ *pptr++ = cmap[offset + 2];
+ *pptr++ = pixel[1];
- *pptr++ = cmap[offset];
- *pptr++ = cmap[offset + 1];
- *pptr++ = cmap[offset + 2];
- *pptr++ = pixel[1];
+ u += du;
+ v += dv;
+ }
+ else
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+
+ offset = pixel[0] + pixel[0] + pixel[0];
+
+ pptr[0] = (pptr[0] * (255-opacity) + cmap[offset ] * opacity)>>8;
+ pptr[1] = (pptr[1] * (255-opacity) + cmap[offset+1] * opacity)>>8;
+ pptr[2] = (pptr[2] * (255-opacity) + cmap[offset+2] * opacity)>>8;
+ pptr[3] = pixel[1];
+ pptr += bytes;
- u += du;
- v += dv;
- }
+ u += du;
+ v += dv;
+ }
break;
case GIMP_GRAY_IMAGE:
- while (dx--)
- {
- read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+ if (opacity == 255)
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+
+ *pptr++ = pixel[0];
+ *pptr++ = pixel[0];
+ *pptr++ = pixel[0];
- *pptr++ = pixel[0];
- *pptr++ = pixel[0];
- *pptr++ = pixel[0];
+ u += du;
+ v += dv;
+ }
+ else
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+
+ pptr[0] = (pptr[0] * (255-opacity) + pixel[0] * opacity) >> 8;
+ pptr[1] = (pptr[1] * (255-opacity) + pixel[0] * opacity) >> 8;
+ pptr[2] = (pptr[2] * (255-opacity) + pixel[0] * opacity) >> 8;
+ pptr += bytes;
- u += du;
- v += dv;
- }
+ u += du;
+ v += dv;
+ }
break;
case GIMP_GRAYA_IMAGE:
- while (dx--)
- {
- read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
-
- *pptr++ = pixel[0];
- *pptr++ = pixel[0];
- *pptr++ = pixel[0];
- *pptr++ = pixel[1];
-
- u += du;
- v += dv;
- }
+ if (opacity == 255)
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+
+ *pptr++ = pixel[0];
+ *pptr++ = pixel[0];
+ *pptr++ = pixel[0];
+ *pptr++ = pixel[1];
+
+ u += du;
+ v += dv;
+ }
+ else
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+
+ pptr[0] = (pptr[0] * (255-opacity) + pixel[0] * opacity) >> 8;
+ pptr[1] = (pptr[1] * (255-opacity) + pixel[0] * opacity) >> 8;
+ pptr[2] = (pptr[2] * (255-opacity) + pixel[0] * opacity) >> 8;
+ pptr[3] = pixel[1];
+ pptr += bytes;
+
+ u += du;
+ v += dv;
+ }
break;
case GIMP_RGB_IMAGE:
- case GIMP_RGBA_IMAGE:
- while (dx--)
- {
- read_pixel_data_1 (tiles, (gint) u, (gint) v, pptr);
+ if (opacity == 255)
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+
+ pptr[0] = pixel[0];
+ pptr[1] = pixel[1];
+ pptr[2] = pixel[2];
+
+ pptr += bytes;
+ u += du;
+ v += dv;
+ }
+ else
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+
+ pptr[0] = (pptr[0] * (255-opacity) + pixel[0] * opacity) >> 8;
+ pptr[1] = (pptr[1] * (255-opacity) + pixel[1] * opacity) >> 8;
+ pptr[2] = (pptr[2] * (255-opacity) + pixel[2] * opacity) >> 8;
+
+ pptr += bytes;
+ u += du;
+ v += dv;
+ }
+ break;
- pptr += bytes;
- u += du;
- v += dv;
- }
+ case GIMP_RGBA_IMAGE:
+ if (opacity == 255)
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+
+ pptr[0] = pixel[0];
+ pptr[1] = pixel[1];
+ pptr[2] = pixel[2];
+ pptr[3] = pixel[3];
+
+ pptr += bytes;
+ u += du;
+ v += dv;
+ }
+ else
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+
+ pptr[0] = (pptr[0] * (255-opacity) + pixel[0] * opacity) >> 8;
+ pptr[1] = (pptr[1] * (255-opacity) + pixel[1] * opacity) >> 8;
+ pptr[2] = (pptr[2] * (255-opacity) + pixel[2] * opacity) >> 8;
+ pptr[3] = pixel[3];
+
+ pptr += bytes;
+ u += du;
+ v += dv;
+ }
break;
default:
return;
}
- gdk_draw_pixbuf (dest, NULL, row, 0, 0, x1, y, x2 - x1, 1,
+ gdk_draw_pixbuf (dest, NULL, area, x1 - area_offx, y - area_offy,
+ x1, y, x2 - x1, 1,
GDK_RGB_DITHER_NONE, 0, 0);
}
+/**
+ * gimp_display_shell_draw_tri_row_mask:
+ *
+ * Called from gimp_display_shell_draw_tri(), this draws a single row of a
+ * triangle onto dest, when there is a mask.
+ **/
static void
gimp_display_shell_draw_tri_row_mask (GimpDrawable *texture,
GdkDrawable *dest,
- GdkPixbuf *row,
+ GdkPixbuf *area,
+ gint area_offx,
+ gint area_offy,
GimpChannel *mask,
gint mask_offx,
gint mask_offy,
@@ -626,11 +881,13 @@
gint x2,
gfloat u2,
gfloat v2,
- gint y)
+ gint y,
+ gint opacity)
{
- TileManager *tiles, *masktiles;
- guchar *pptr;
- guchar bytes, alpha;
+
+ TileManager *tiles, *masktiles; /* used to get the source texture colors */
+ guchar *pptr; /* points into the pixels of area */
+ guchar bytes, alpha; /* channels in row, channel of alpha */
gfloat u, v;
gfloat mu, mv;
gfloat du, dv;
@@ -645,16 +902,18 @@
g_return_if_fail (GIMP_IS_DRAWABLE (texture));
g_return_if_fail (GIMP_IS_CHANNEL (mask));
g_return_if_fail (GDK_IS_DRAWABLE (dest));
- g_return_if_fail (GDK_IS_PIXBUF (row));
- g_return_if_fail (gdk_pixbuf_get_bits_per_sample (row) == 8);
- g_return_if_fail (gdk_pixbuf_get_colorspace (row) == GDK_COLORSPACE_RGB);
+ g_return_if_fail (GDK_IS_PIXBUF (area));
+ g_return_if_fail (gdk_pixbuf_get_bits_per_sample (area) == 8);
+ g_return_if_fail (gdk_pixbuf_get_colorspace (area) == GDK_COLORSPACE_RGB);
- bytes = gdk_pixbuf_get_n_channels (row);
+ bytes = gdk_pixbuf_get_n_channels (area);
alpha = bytes - 1;
- pptr = gdk_pixbuf_get_pixels (row);
+ pptr = gdk_pixbuf_get_pixels (area);
tiles = gimp_drawable_get_tiles (texture);
masktiles = gimp_drawable_get_tiles (GIMP_DRAWABLE (mask));
+
+ /* make sure the pixel run goes in the positive direction */
if (x1 > x2)
{
gint tmp;
@@ -671,154 +930,285 @@
dv = (v2 - v1) / (x2 - x1);
/* don't calculate unseen pixels */
- if (x1 < 0)
+ if (x1 < area_offx)
{
- u += du * (0 - x1);
- v += dv * (0 - x1);
- x1 = 0;
+ u += du * (area_offx - x1);
+ v += dv * (area_offx - x1);
+ x1 = area_offx;
}
- else if (x1 > gdk_pixbuf_get_width (row))
+ else if (x1 > area_offx + gdk_pixbuf_get_width (area) - 1)
{
return;
}
- if (x2 < 0)
+ if (x2 < area_offx)
{
return;
}
- else if (x2 > gdk_pixbuf_get_width (row))
+ else if (x2 > area_offx + gdk_pixbuf_get_width (area) - 1)
{
- x2 = gdk_pixbuf_get_width (row);
+ x2 = area_offx + gdk_pixbuf_get_width (area) - 1;
}
dx = x2 - x1;
-
- if (! dx)
+ if (! dx)
return;
mu = u + mask_offx;
mv = v + mask_offy;
+ /* set pptr to the proper position in area */
+ pptr += (y - area_offy) * gdk_pixbuf_get_rowstride(area)
+ + (x1 - area_offx) * bytes;
+
switch (gimp_drawable_type (texture))
{
case GIMP_INDEXED_IMAGE:
cmap = gimp_drawable_get_colormap (texture);
- while (dx--)
- {
- read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
- read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, pptr + alpha);
-
- offset = pixel[0] + pixel[0] + pixel[0];
-
- *pptr++ = cmap[offset];
- *pptr++ = cmap[offset + 1];
- *pptr++ = cmap[offset + 2];
-
- pptr ++;
- u += du;
- v += dv;
- mu += du;
- mv += dv;
- }
+ if (opacity == 255)
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+ read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, pptr + alpha);
+
+ offset = pixel[0] + pixel[0] + pixel[0];
+
+ *pptr++ = cmap[offset];
+ *pptr++ = cmap[offset + 1];
+ *pptr++ = cmap[offset + 2];
+
+ pptr ++;
+ u += du;
+ v += dv;
+ mu += du;
+ mv += dv;
+ }
+ else
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+ read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, pptr + alpha);
+
+ offset = pixel[0] + pixel[0] + pixel[0];
+
+ pptr[0] = (pptr[0] * (255-opacity) + cmap[offset] * opacity) >> 8;
+ pptr[1] = (pptr[1] * (255-opacity) + cmap[offset+1] * opacity)>>8;
+ pptr[2] = (pptr[2] * (255-opacity) + cmap[offset+2] * opacity)>>8;
+ pptr += 3;
+
+ pptr ++;
+ u += du;
+ v += dv;
+ mu += du;
+ mv += dv;
+ }
break;
case GIMP_INDEXEDA_IMAGE:
cmap = gimp_drawable_get_colormap (texture);
- while (dx--)
- {
- read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
- read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, &maskval);
-
- offset = pixel[0] + pixel[0] + pixel[0];
-
- *pptr++ = cmap[offset];
- *pptr++ = cmap[offset + 1];
- *pptr++ = cmap[offset + 2];
- *pptr++ = ((gint) maskval * pixel[1]) >> 8;
-
- u += du;
- v += dv;
- mu += du;
- mv += dv;
- }
+ if (opacity == 255)
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+ read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, &maskval);
+
+ offset = pixel[0] + pixel[0] + pixel[0];
+
+ *pptr++ = cmap[offset];
+ *pptr++ = cmap[offset + 1];
+ *pptr++ = cmap[offset + 2];
+
+ *pptr++ = ((gint) maskval * pixel[1]) >> 8;
+ u += du;
+ v += dv;
+ mu += du;
+ mv += dv;
+ }
+ else
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+ read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, &maskval);
+
+ offset = pixel[0] + pixel[0] + pixel[0];
+
+ pptr[0] = (pptr[0] * (255-opacity) + cmap[offset] * opacity)>>8;
+ pptr[1] = (pptr[1] * (255-opacity) + cmap[offset+1] * opacity)>>8;
+ pptr[2] = (pptr[2] * (255-opacity) + cmap[offset+2] * opacity)>>8;
+ pptr += 3;
+
+ *pptr++ = ((gint) maskval * pixel[1]) >> 8;
+ u += du;
+ v += dv;
+ mu += du;
+ mv += dv;
+ }
break;
case GIMP_GRAY_IMAGE:
- while (dx--)
- {
- read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
- read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, pptr + alpha);
-
- *pptr++ = pixel[0];
- *pptr++ = pixel[0];
- *pptr++ = pixel[0];
-
- pptr ++;
- u += du;
- v += dv;
- mu += du;
- mv += dv;
- }
+ if (opacity == 255)
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+ read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, pptr + alpha);
+
+ *pptr++ = pixel[0];
+ *pptr++ = pixel[0];
+ *pptr++ = pixel[0];
+ pptr ++;
+
+ u += du;
+ v += dv;
+ mu += du;
+ mv += dv;
+ }
+ else
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+ read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, pptr + alpha);
+
+ pptr[0] = (pptr[0] * (255-opacity) + pixel[0] * opacity) >> 8;
+ pptr[1] = (pptr[1] * (255-opacity) + pixel[0] * opacity) >> 8;
+ pptr[2] = (pptr[2] * (255-opacity) + pixel[0] * opacity) >> 8;
+ pptr += bytes;
+
+ u += du;
+ v += dv;
+ mu += du;
+ mv += dv;
+ }
break;
case GIMP_GRAYA_IMAGE:
- while (dx--)
- {
- read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
- read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, &maskval);
-
- *pptr++ = pixel[0];
- *pptr++ = pixel[0];
- *pptr++ = pixel[0];
- *pptr++ = ((gint) maskval * pixel[1]) >> 8;
-
- u += du;
- v += dv;
- mu += du;
- mv += dv;
- }
+ if (opacity == 255)
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+ read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, &maskval);
+
+ *pptr++ = pixel[0];
+ *pptr++ = pixel[0];
+ *pptr++ = pixel[0];
+ *pptr++ = ((gint) maskval * pixel[1]) >> 8;
+
+ u += du;
+ v += dv;
+ mu += du;
+ mv += dv;
+ }
+ else
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+ read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, &maskval);
+
+ pptr[0] = (pptr[0] * (255-opacity) + pixel[0] * opacity) >> 8;
+ pptr[1] = (pptr[1] * (255-opacity) + pixel[0] * opacity) >> 8;
+ pptr[2] = (pptr[2] * (255-opacity) + pixel[0] * opacity) >> 8;
+ pptr[3] = ((gint) maskval * pixel[1]) >> 8;
+ pptr += bytes;
+
+ u += du;
+ v += dv;
+ mu += du;
+ mv += dv;
+ }
break;
case GIMP_RGB_IMAGE:
- while (dx--)
- {
- read_pixel_data_1 (tiles, (gint) u, (gint) v, pptr);
- read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, pptr + alpha);
-
- pptr += bytes;
- u += du;
- v += dv;
- mu += du;
- mv += dv;
- }
+ if (opacity == 255)
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+ read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, &maskval);
+
+ pptr[0] = pixel[0];
+ pptr[1] = pixel[1];
+ pptr[2] = pixel[2];
+ pptr[alpha] = maskval;
+
+ pptr += bytes;
+ u += du;
+ v += dv;
+ mu += du;
+ mv += dv;
+ }
+ else
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+ read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, &maskval);
+
+ pptr[0] = (pptr[0] * (255-opacity) + pixel[0] * opacity) >> 8;
+ pptr[1] = (pptr[1] * (255-opacity) + pixel[1] * opacity) >> 8;
+ pptr[2] = (pptr[2] * (255-opacity) + pixel[2] * opacity) >> 8;
+ pptr[alpha] = maskval;
+
+ pptr += bytes;
+ u += du;
+ v += dv;
+ mu += du;
+ mv += dv;
+ }
break;
case GIMP_RGBA_IMAGE:
- while (dx--)
- {
- read_pixel_data_1 (tiles, (gint) u, (gint) v, pptr);
- read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, &maskval);
-
- pptr[alpha] = ((gint) maskval * pptr[alpha]) >> 8;
-
- pptr += bytes;
- u += du;
- v += dv;
- mu += du;
- mv += dv;
- }
+ if (opacity == 255)
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+ read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, &maskval);
+
+ pptr[0] = pixel[0];
+ pptr[1] = pixel[1];
+ pptr[2] = pixel[2];
+ pptr[alpha] = ((gint) maskval * pixel[alpha]) >> 8;
+
+ pptr += bytes;
+ u += du;
+ v += dv;
+ mu += du;
+ mv += dv;
+ }
+ else
+ while (dx --)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+ read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, &maskval);
+
+ pptr[0] = (pptr[0] * (255-opacity) + pixel[0] * opacity) >> 8;
+ pptr[1] = (pptr[1] * (255-opacity) + pixel[1] * opacity) >> 8;
+ pptr[2] = (pptr[2] * (255-opacity) + pixel[2] * opacity) >> 8;
+ pptr[alpha] = ((gint) maskval * pixel[alpha]) >> 8;
+
+ pptr += bytes;
+ u += du;
+ v += dv;
+ mu += du;
+ mv += dv;
+ }
break;
default:
return;
}
- gdk_draw_pixbuf (dest, NULL, row, 0, 0, x1, y, x2 - x1, 1,
+ gdk_draw_pixbuf (dest, NULL, area, x1 - area_offx, y - area_offy,
+ x1, y, x2 - x1, 1,
GDK_RGB_DITHER_NONE, 0, 0);
}
+/**
+ * gimp_display_shell_trace_tri_edge:
+ * @dest: x coordinates are placed in this array
+ *
+ * Find the x coordinates for a line that runs from (x1,y1) to (x2,y2),
+ * corresponding to the y coordinates y1 to y2-1. So
+ * dest must be large enough to hold y2-y1 values.
+ **/
static void
gimp_display_shell_trace_tri_edge (gint *dest,
gint x1,
Modified: branches/weskaggs/app/tools/gimptransformoptions.c
==============================================================================
--- branches/weskaggs/app/tools/gimptransformoptions.c (original)
+++ branches/weskaggs/app/tools/gimptransformoptions.c Tue Mar 4 19:17:18 2008
@@ -50,7 +50,8 @@
PROP_PREVIEW_TYPE,
PROP_GRID_TYPE,
PROP_GRID_SIZE,
- PROP_CONSTRAIN
+ PROP_CONSTRAIN,
+ PROP_PREVIEW_OPACITY
};
@@ -69,6 +70,10 @@
GParamSpec *pspec,
GtkWidget *density_box);
+static void gimp_transform_options_preview_opacity_notify (GimpTransformOptions *options,
+ GParamSpec *pspec,
+ GtkWidget *density_box);
+
G_DEFINE_TYPE (GimpTransformOptions, gimp_transform_options,
GIMP_TYPE_TOOL_OPTIONS)
@@ -125,6 +130,10 @@
"constrain", NULL,
FALSE,
GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_PREVIEW_OPACITY,
+ "preview-opacity", NULL,
+ 0, 100, 100,
+ GIMP_PARAM_STATIC_STRINGS);
}
static void
@@ -167,6 +176,9 @@
case PROP_CONSTRAIN:
options->constrain = g_value_get_boolean (value);
break;
+ case PROP_PREVIEW_OPACITY:
+ options->preview_opacity = g_value_get_int (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -207,6 +219,9 @@
case PROP_CONSTRAIN:
g_value_set_boolean (value, options->constrain);
break;
+ case PROP_PREVIEW_OPACITY:
+ g_value_set_int (value, options->preview_opacity);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -228,6 +243,12 @@
GIMP_TOOL_OPTIONS_CLASS (parent_class)->reset (tool_options);
}
+/**
+ * gimp_transform_options_gui:
+ * @tool_options: a #GimpToolOptions
+ *
+ * Build the Transform Tool Options dialog.
+ **/
GtkWidget *
gimp_transform_options_gui (GimpToolOptions *tool_options)
{
@@ -311,7 +332,17 @@
gtk_box_pack_start (GTK_BOX (button), table, FALSE, FALSE, 0);
gtk_widget_show (table);
- gtk_widget_set_sensitive (button,
+ gtk_widget_set_sensitive (combo,
+ options->preview_type ==
+ GIMP_TRANSFORM_PREVIEW_TYPE_GRID ||
+ options->preview_type ==
+ GIMP_TRANSFORM_PREVIEW_TYPE_IMAGE_GRID);
+
+ g_signal_connect (config, "notify::preview-type",
+ G_CALLBACK (gimp_transform_options_preview_notify),
+ combo);
+
+ gtk_widget_set_sensitive (table,
options->preview_type ==
GIMP_TRANSFORM_PREVIEW_TYPE_GRID ||
options->preview_type ==
@@ -319,7 +350,7 @@
g_signal_connect (config, "notify::preview-type",
G_CALLBACK (gimp_transform_options_preview_notify),
- button);
+ table);
gimp_prop_scale_entry_new (config, "grid-size",
GTK_TABLE (table), 0, 0,
@@ -327,6 +358,29 @@
1.0, 8.0, 0,
FALSE, 0.0, 0.0);
+ /* the preview opacity scale */
+ table = gtk_table_new (1, 3, FALSE);
+ gtk_table_set_col_spacing (GTK_TABLE (table), 1, 2);
+ gtk_box_pack_start (GTK_BOX (button), table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ gtk_widget_set_sensitive (table,
+ options->preview_type ==
+ GIMP_TRANSFORM_PREVIEW_TYPE_IMAGE ||
+ options->preview_type ==
+ GIMP_TRANSFORM_PREVIEW_TYPE_IMAGE_GRID);
+
+ g_signal_connect (config, "notify::preview-type",
+ G_CALLBACK (gimp_transform_options_preview_opacity_notify),
+ table);
+
+ gimp_prop_scale_entry_new (config, "preview-opacity",
+ GTK_TABLE (table), 0, 0,
+ _("Opacity:"),
+ 1.0, 8.0, 0,
+ FALSE, 0.0, 0.0);
+
+
if (tool_options->tool_info->tool_type == GIMP_TYPE_ROTATE_TOOL)
{
constrain = (_("15 degrees (%s)"));
@@ -365,3 +419,16 @@
options->preview_type ==
GIMP_TRANSFORM_PREVIEW_TYPE_IMAGE_GRID);
}
+
+static void
+gimp_transform_options_preview_opacity_notify (GimpTransformOptions *options,
+ GParamSpec *pspec,
+ GtkWidget *density_box)
+{
+ gtk_widget_set_sensitive (density_box,
+ options->preview_type ==
+ GIMP_TRANSFORM_PREVIEW_TYPE_IMAGE ||
+ options->preview_type ==
+ GIMP_TRANSFORM_PREVIEW_TYPE_IMAGE_GRID);
+}
+
Modified: branches/weskaggs/app/tools/gimptransformoptions.h
==============================================================================
--- branches/weskaggs/app/tools/gimptransformoptions.h (original)
+++ branches/weskaggs/app/tools/gimptransformoptions.h Tue Mar 4 19:17:18 2008
@@ -47,6 +47,7 @@
GimpTransformGridType grid_type;
gint grid_size;
gboolean constrain;
+ gint preview_opacity;
};
Modified: branches/weskaggs/app/tools/gimptransformtool.c
==============================================================================
--- branches/weskaggs/app/tools/gimptransformtool.c (original)
+++ branches/weskaggs/app/tools/gimptransformtool.c Tue Mar 4 19:17:18 2008
@@ -280,6 +280,10 @@
g_signal_connect_object (options, "notify::grid-size",
G_CALLBACK (gimp_transform_tool_notify_preview),
tr_tool, 0);
+ g_signal_connect_object (tool->tool_info->tool_options,
+ "notify::preview-opacity",
+ G_CALLBACK (gimp_transform_tool_notify_preview),
+ tr_tool, 0);
}
g_signal_connect_object (options, "notify::constrain",
@@ -1360,7 +1364,7 @@
static gint last_h = 0;
GimpDisplayShell *shell;
- gdouble dx [4], dy [4];
+ gdouble dx[4], dy[4];
gint area_x, area_y, area_w, area_h;
gint i;
@@ -1388,20 +1392,20 @@
dx + 3, dy + 3, FALSE);
/* find bounding box around preview */
- area_x = area_w = (gint) dx [0];
- area_y = area_h = (gint) dy [0];
+ area_x = area_w = (gint) dx[0];
+ area_y = area_h = (gint) dy[0];
for (i = 1; i < 4; i++)
{
- if (dx [i] < area_x)
- area_x = (gint) dx [i];
- else if (dx [i] > area_w)
- area_w = (gint) dx [i];
-
- if (dy [i] < area_y)
- area_y = (gint) dy [i];
- else if (dy [i] > area_h)
- area_h = (gint) dy [i];
+ if (dx[i] < area_x)
+ area_x = (gint) dx[i];
+ else if (dx[i] > area_w)
+ area_w = (gint) dx[i];
+
+ if (dy[i] < area_y)
+ area_y = (gint) dy[i];
+ else if (dy[i] > area_h)
+ area_h = (gint) dy[i];
}
area_w -= area_x;
Modified: branches/weskaggs/app/tools/gimptransformtool.h
==============================================================================
--- branches/weskaggs/app/tools/gimptransformtool.h (original)
+++ branches/weskaggs/app/tools/gimptransformtool.h Tue Mar 4 19:17:18 2008
@@ -62,7 +62,7 @@
gdouble cx, cy; /* center point (for rotation) */
gdouble aspect; /* original aspect ratio */
- gdouble tx1, ty1; /* transformed coords */
+ gdouble tx1, ty1; /* transformed handle coords */
gdouble tx2, ty2;
gdouble tx3, ty3;
gdouble tx4, ty4;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]