gimp r25038 - in trunk: . app/display
- From: neo svn gnome org
- To: svn-commits-list gnome org
- Subject: gimp r25038 - in trunk: . app/display
- Date: Wed, 5 Mar 2008 20:44:19 +0000 (GMT)
Author: neo
Date: Wed Mar 5 20:44:19 2008
New Revision: 25038
URL: http://svn.gnome.org/viewvc/gimp?rev=25038&view=rev
Log:
2008-03-05 Sven Neumann <sven gimp org>
* app/display/gimpdisplayshell-preview.c: applied a modified and
further optimized version of the patch from Tom Lechner as
attached to bug #167926. This makes the transform preview take
the layer opacity into account. Needs some more work...
Modified:
trunk/ChangeLog
trunk/app/display/gimpdisplayshell-preview.c
Modified: trunk/app/display/gimpdisplayshell-preview.c
==============================================================================
--- trunk/app/display/gimpdisplayshell-preview.c (original)
+++ trunk/app/display/gimpdisplayshell-preview.c Wed Mar 5 20:44:19 2008
@@ -25,9 +25,10 @@
#include "display-types.h"
#include "tools/tools-types.h"
-#include "core/gimpimage.h"
-#include "core/gimpdrawable.h"
#include "core/gimpchannel.h"
+#include "core/gimpdrawable.h"
+#include "core/gimplayer.h"
+#include "core/gimpimage.h"
#include "base/tile-manager.h"
@@ -42,6 +43,10 @@
#include "gimpdisplayshell-transform.h"
+#define INT_MULT(a,b,t) ((t) = (a) * (b) + 0x80, ((((t) >> 8) + (t)) >> 8))
+#define INT_BLEND(a,b,alpha,tmp) (INT_MULT((a) - (b), alpha, tmp) + (b))
+
+
#define MAX_SUB_COLS 6 /* number of columns and */
#define MAX_SUB_ROWS 6 /* rows to use in perspective preview subdivision */
@@ -55,29 +60,39 @@
gint *x,
gint *y,
gfloat *u,
- gfloat *v);
+ gfloat *v,
+ guchar 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,
+ guchar 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,
+ guchar 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 +102,8 @@
gint x2,
gfloat u2,
gfloat v2,
- gint y);
+ gint y,
+ guchar opacity);
static void gimp_display_shell_trace_tri_edge (gint *dest,
gint x1,
gint y1,
@@ -96,187 +112,222 @@
/* 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)
{
+ 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];
+ guchar opacity = 255;
+
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;
+ if (! gimp_display_shell_get_show_transform (shell) || ! shell->canvas)
+ return;
- tool = tool_manager_get_active (shell->display->image->gimp);
+ tool = tool_manager_get_active (shell->display->image->gimp);
- if (! GIMP_IS_TRANSFORM_TOOL (tool) ||
- ! GIMP_IS_DRAWABLE (tool->drawable))
- return;
+ if (! GIMP_IS_TRANSFORM_TOOL (tool) ||
+ ! GIMP_IS_DRAWABLE (tool->drawable))
+ return;
- tr_tool = GIMP_TRANSFORM_TOOL (tool);
+ tr_tool = GIMP_TRANSFORM_TOOL (tool);
- if (! tr_tool->use_grid)
- return;
+ if (! tr_tool->use_grid)
+ 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));
+ 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 */
+ /* only draw convex polygons */
- 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);
+ if (! ((z1 * z2 > 0) && (z3 * z4 > 0))) return;
- gimp_item_offsets (GIMP_ITEM (tool->drawable),
- &mask_offx, &mask_offy);
- }
+ if (GIMP_IS_LAYER (tool->drawable))
+ opacity = gimp_layer_get_opacity (GIMP_LAYER (tool->drawable)) * 255.999;
- 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;
- }
+ mask = NULL;
+ mask_offx = mask_offy = 0;
- dx = (tr_tool->x2 - tr_tool->x1) / ((gfloat) columns);
- dy = (tr_tool->y2 - tr_tool->y1) / ((gfloat) rows);
+ if (gimp_drawable_mask_bounds (tool->drawable,
+ &mask_x1, &mask_y1,
+ &mask_x2, &mask_y2))
+ {
+ mask = gimp_image_get_mask (shell->display->image);
- du = (mask_x2 - mask_x1) / ((gfloat) columns);
- dv = (mask_y2 - mask_y1) / ((gfloat) rows);
+ gimp_item_offsets (GIMP_ITEM (tool->drawable),
+ &mask_offx, &mask_offy);
+ }
-#define CALC_VERTEX(col, row, sub, index) \
- { \
- 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))); \
-\
- 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; \
-\
- u[sub][index] = mask_x1 + (du * (col + (index & 1))); \
- v[sub][index] = mask_y1 + (dv * (row + (index >> 1))); \
- }
+ 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);
+
+ 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; \
+ \
+ 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_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))); \
+ }
#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],
+ 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 +337,118 @@
gint *x,
gint *y,
gfloat *u,
- gfloat *v)
+ gfloat *v,
+ guchar 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 */
+ guchar 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 +490,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 +532,69 @@
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,
+ guchar 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 */
gfloat u, v;
gfloat du, dv;
gint dx;
@@ -474,16 +607,13 @@
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);
- tiles = gimp_drawable_get_tiles (texture);
-
+ /* make sure the pixel run goes in the positive direction */
if (x1 > x2)
{
gint tmp;
@@ -500,123 +630,274 @@
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;
+ pptr = (gdk_pixbuf_get_pixels (area)
+ + (y - area_offy) * gdk_pixbuf_get_rowstride (area)
+ + (x1 - area_offx) * gdk_pixbuf_get_n_channels (area));
+
+ tiles = gimp_drawable_get_tiles (texture);
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];
+ offset = pixel[0] + pixel[0] + pixel[0];
- *pptr++ = cmap[offset];
- *pptr++ = cmap[offset + 1];
- *pptr++ = cmap[offset + 2];
+ pptr[0] = cmap[offset + 0];
+ pptr[1] = cmap[offset + 1];
+ pptr[2] = cmap[offset + 2];
- u += du;
- v += dv;
- }
+ pptr += 3;
+
+ u += du;
+ v += dv;
+ }
+ else
+ while (dx--)
+ {
+ register gulong tmp;
+
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+
+ offset = pixel[0] + pixel[0] + pixel[0];
+
+ pptr[0] = INT_BLEND (pptr[0], cmap[offset + 0], opacity, tmp);
+ pptr[1] = INT_BLEND (pptr[1], cmap[offset + 1], opacity, tmp);
+ pptr[2] = INT_BLEND (pptr[2], cmap[offset + 2], opacity, tmp);
+
+ pptr += 3;
+
+ 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);
+ if (opacity == 255)
+ while (dx--)
+ {
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+
+ offset = pixel[0] + pixel[0] + pixel[0];
+
+ pptr[0] = cmap[offset + 0];
+ pptr[1] = cmap[offset + 1];
+ pptr[2] = cmap[offset + 2];
+ pptr[3] = pixel[1];
- offset = pixel[0] + pixel[0] + pixel[0];
+ pptr += 4;
- *pptr++ = cmap[offset];
- *pptr++ = cmap[offset + 1];
- *pptr++ = cmap[offset + 2];
- *pptr++ = pixel[1];
+ u += du;
+ v += dv;
+ }
+ else
+ while (dx--)
+ {
+ register gulong tmp;
- u += du;
- v += dv;
- }
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+
+ offset = pixel[0] + pixel[0] + pixel[0];
+
+ pptr[0] = INT_BLEND (pptr[0], cmap[offset + 0], opacity, tmp);
+ pptr[1] = INT_BLEND (pptr[1], cmap[offset + 1], opacity, tmp);
+ pptr[2] = INT_BLEND (pptr[2], cmap[offset + 2], opacity, tmp);
+ pptr[3] = pixel[1];
+
+ pptr += 4;
+
+ 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[0] = pixel[0];
+ pptr[1] = pixel[0];
+ pptr[2] = pixel[0];
- *pptr++ = pixel[0];
- *pptr++ = pixel[0];
- *pptr++ = pixel[0];
+ pptr += 3;
- u += du;
- v += dv;
- }
+ u += du;
+ v += dv;
+ }
+ else
+ while (dx--)
+ {
+ register gulong tmp;
+
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+
+ pptr[0] = INT_BLEND (pptr[0], pixel[0], opacity, tmp);
+ pptr[1] = INT_BLEND (pptr[1], pixel[0], opacity, tmp);
+ pptr[2] = INT_BLEND (pptr[2], pixel[0], opacity, tmp);
+
+ pptr += 3;
+
+ u += du;
+ v += dv;
+ }
break;
case GIMP_GRAYA_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[0] = pixel[0];
+ pptr[1] = pixel[0];
+ pptr[2] = pixel[0];
+ pptr[3] = pixel[1];
- *pptr++ = pixel[0];
- *pptr++ = pixel[0];
- *pptr++ = pixel[0];
- *pptr++ = pixel[1];
+ pptr += 4;
- u += du;
- v += dv;
- }
+ u += du;
+ v += dv;
+ }
+ else
+ while (dx--)
+ {
+ register gulong tmp;
+
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+
+ pptr[0] = INT_BLEND (pptr[0], pixel[0], opacity, tmp);
+ pptr[1] = INT_BLEND (pptr[1], pixel[0], opacity, tmp);
+ pptr[2] = INT_BLEND (pptr[2], pixel[0], opacity, tmp);
+ pptr[3] = pixel[1];
+
+ pptr += 4;
+
+ u += du;
+ v += dv;
+ }
break;
case GIMP_RGB_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;
+
+ u += du;
+ v += dv;
+ }
+ else
+ while (dx--)
+ {
+ register gulong tmp;
+
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+
+ pptr[0] = INT_BLEND (pptr[0], pixel[0], opacity, tmp);
+ pptr[1] = INT_BLEND (pptr[1], pixel[1], opacity, tmp);
+ pptr[2] = INT_BLEND (pptr[2], pixel[2], opacity, tmp);
+
+ pptr += 3;
+
+ u += du;
+ v += dv;
+ }
+ break;
+
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[3] = pixel[3];
- pptr += bytes;
- u += du;
- v += dv;
- }
+ pptr += 4;
+
+ u += du;
+ v += dv;
+ }
+ else
+ while (dx--)
+ {
+ register gulong tmp;
+
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+
+ pptr[0] = INT_BLEND (pptr[0], pixel[0], opacity, tmp);
+ pptr[1] = INT_BLEND (pptr[1], pixel[1], opacity, tmp);
+ pptr[2] = INT_BLEND (pptr[2], pixel[2], opacity, tmp);
+ pptr[3] = pixel[3];
+
+ pptr += 4;
+
+ 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 +907,12 @@
gint x2,
gfloat u2,
gfloat v2,
- gint y)
+ gint y,
+ guchar 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 */
gfloat u, v;
gfloat mu, mv;
gfloat du, dv;
@@ -645,16 +927,11 @@
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);
-
- bytes = gdk_pixbuf_get_n_channels (row);
- alpha = bytes - 1;
- pptr = gdk_pixbuf_get_pixels (row);
- tiles = gimp_drawable_get_tiles (texture);
- masktiles = gimp_drawable_get_tiles (GIMP_DRAWABLE (mask));
+ 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);
+ /* make sure the pixel run goes in the positive direction */
if (x1 > x2)
{
gint tmp;
@@ -671,154 +948,315 @@
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;
mu = u + mask_offx;
mv = v + mask_offy;
+ pptr = (gdk_pixbuf_get_pixels (area)
+ + (y - area_offy) * gdk_pixbuf_get_rowstride (area)
+ + (x1 - area_offx) * gdk_pixbuf_get_n_channels (area));
+
+ tiles = gimp_drawable_get_tiles (texture);
+ masktiles = gimp_drawable_get_tiles (GIMP_DRAWABLE (mask));
+
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 + 3);
+
+ offset = pixel[0] + pixel[0] + pixel[0];
+
+ pptr[0] = cmap[offset + 0];
+ pptr[1] = cmap[offset + 1];
+ pptr[2] = cmap[offset + 2];
+
+ pptr += 4;
+
+ u += du;
+ v += dv;
+ mu += du;
+ mv += dv;
+ }
+ else
+ while (dx--)
+ {
+ register gulong tmp;
+
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+ read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, pptr + 3);
+
+ offset = pixel[0] + pixel[0] + pixel[0];
+
+ pptr[0] = INT_BLEND (pptr[0], cmap[offset + 0], opacity, tmp);
+ pptr[1] = INT_BLEND (pptr[1], cmap[offset + 1], opacity, tmp);
+ pptr[2] = INT_BLEND (pptr[2], cmap[offset + 2], opacity, tmp);
+
+ pptr += 4;
+
+ 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[0] = cmap[offset + 0];
+ pptr[1] = cmap[offset + 1];
+ pptr[2] = cmap[offset + 2];
+ pptr[3] = ((gint) maskval * pixel[1]) >> 8;
+
+ pptr += 4;
+
+ u += du;
+ v += dv;
+ mu += du;
+ mv += dv;
+ }
+ else
+ while (dx--)
+ {
+ register gulong tmp;
+
+ 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] = INT_BLEND (pptr[0], cmap[offset + 0], opacity, tmp);
+ pptr[1] = INT_BLEND (pptr[1], cmap[offset + 1], opacity, tmp);
+ pptr[2] = INT_BLEND (pptr[2], cmap[offset + 2], opacity, tmp);
+ pptr[3] = INT_MULT (maskval, pixel[1], tmp);
+
+ pptr += 4;
+
+ 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 + 3);
+
+ pptr[0] = pixel[0];
+ pptr[1] = pixel[0];
+ pptr[2] = pixel[0];
+
+ pptr += 4;
+
+ u += du;
+ v += dv;
+ mu += du;
+ mv += dv;
+ }
+ else
+ while (dx--)
+ {
+ register gulong tmp;
+
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+ read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, pptr + 3);
+
+ pptr[0] = INT_BLEND (pptr[0], pixel[0], opacity, tmp);
+ pptr[1] = INT_BLEND (pptr[1], pixel[0], opacity, tmp);
+ pptr[2] = INT_BLEND (pptr[2], pixel[0], opacity, tmp);
+
+ pptr += 4;
+
+ 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--)
+ {
+ register gulong tmp;
+
+ 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[0];
+ pptr[2] = pixel[0];
+ pptr[3] = INT_MULT (maskval, pixel[1], tmp);
+
+ pptr += 4;
+
+ u += du;
+ v += dv;
+ mu += du;
+ mv += dv;
+ }
+ else
+ while (dx--)
+ {
+ register gulong tmp;
+
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+ read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, &maskval);
+
+ pptr[0] = INT_BLEND (pptr[0], pixel[0], opacity, tmp);
+ pptr[1] = INT_BLEND (pptr[1], pixel[0], opacity, tmp);
+ pptr[2] = INT_BLEND (pptr[2], pixel[0], opacity, tmp);
+ pptr[3] = INT_MULT (maskval, pixel[1], tmp);
+
+ pptr += 4;
+
+ 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, pptr + 3);
+
+ pptr[0] = pixel[0];
+ pptr[1] = pixel[1];
+ pptr[2] = pixel[2];
+
+ pptr += 4;
+
+ u += du;
+ v += dv;
+ mu += du;
+ mv += dv;
+ }
+ else
+ while (dx--)
+ {
+ register gulong tmp;
+
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+ read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, pptr + 3);
+
+ pptr[0] = INT_BLEND (pptr[0], pixel[0], opacity, tmp);
+ pptr[1] = INT_BLEND (pptr[1], pixel[1], opacity, tmp);
+ pptr[2] = INT_BLEND (pptr[2], pixel[2], opacity, tmp);
+
+ pptr += 4;
+
+ 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--)
+ {
+ register gulong tmp;
+
+ 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[3] = INT_MULT (maskval, pixel[3], tmp);
+
+ pptr += 4;
+
+ u += du;
+ v += dv;
+ mu += du;
+ mv += dv;
+ }
+ else
+ while (dx--)
+ {
+ register gulong tmp;
+
+ read_pixel_data_1 (tiles, (gint) u, (gint) v, pixel);
+ read_pixel_data_1 (masktiles, (gint) mu, (gint) mv, &maskval);
+
+ pptr[0] = INT_BLEND (pptr[0], pixel[0], opacity, tmp);
+ pptr[1] = INT_BLEND (pptr[1], pixel[1], opacity, tmp);
+ pptr[2] = INT_BLEND (pptr[2], pixel[2], opacity, tmp);
+ pptr[3] = INT_MULT (maskval, pixel[3], tmp);
+
+ pptr += 4;
+
+ 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,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]