diff --git a/ChangeLog b/ChangeLog index e994f85c15..f1ebb0ea32 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2003-09-07 Michael Natterer + + * app/tools/airbrush_blob.[ch]: removed the last traces of + xinput_airbrush. + 2003-09-07 Sven Neumann * plug-ins/common/aa.c: set the tile cache size to speed up pixel diff --git a/app/tools/airbrush_blob.c b/app/tools/airbrush_blob.c deleted file mode 100644 index d82887b4a7..0000000000 --- a/app/tools/airbrush_blob.c +++ /dev/null @@ -1,1843 +0,0 @@ -/* airbrush_blob.c: routines for manipulating scan converted convex - * polygons. - * - * Copyright 1998-1999, Owen Taylor - * - * > Please contact the above author before modifying the copy < - * > of this file in the GIMP distribution. Thanks. < - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "config.h" - -#include - -#include -#include -#include - -#include "libgimpmath/gimpmath.h" - -#include "airbrush_blob.h" - - -#define SUBSAMPLE 8.0 -#define SU 8.0 - - -static AirBrushBlob * -airbrush_blob_new (int y, int height) -{ - - AirBrushBlob *result; - - result = g_malloc (sizeof (AirBrushBlob) + sizeof(AirBrushBlobSpan) * (height-1)); - result->y = y; - result->height = height; - return result; -} - - -static AirBlob * -airblob_new(int y) -{ - AirBlob *result; - - result = g_malloc (sizeof (AirBlob)); - return result; -} - -static AirLine * -airline_new(int y) -{ - AirLine *result; - - result = g_malloc(sizeof (AirLine)); - return result; -} - - - - - -typedef enum { - EDGE_NONE = 0, - EDGE_LEFT = 1 << 0, - EDGE_RIGHT = 1 << 1 -} EdgeType; - -static void -airbrush_blob_fill (AirBrushBlob *b, EdgeType *present) -{ - - int start; - int x1, x2, i1, i2; - int i; - - /* Mark empty lines at top and bottom as unused */ - - start = 0; - while (!(present[start])) - { - b->data[start].left = 0; - b->data[start].right = -1; - start++; - } - if (present[start] != (EDGE_RIGHT | EDGE_LEFT)) - { - if (present[start] == EDGE_RIGHT) - b->data[start].left = b->data[start].right; - else - b->data[start].right = b->data[start].left; - - present[start] = EDGE_RIGHT | EDGE_LEFT; - } - - for (i=b->height-1;!present[i];i--) - { - b->data[i].left = 0; - b->data[i].right = -1; - } - if (present[i] != (EDGE_RIGHT | EDGE_LEFT)) - { - if (present[i] == EDGE_RIGHT) - b->data[i].left = b->data[i].right; - else - b->data[i].right = b->data[i].left; - - present[i] = EDGE_RIGHT | EDGE_LEFT; - } - - - /* Restore missing edges */ - - /* We fill only interior regions of convex hull, as if we were filling - polygons. But since we draw ellipses with nearest points, not interior - points, maybe it would look better if we did the same here. Probably - not a big deal either way after anti-aliasing */ - - /* left edge */ - for (i1=start; i1height-2; i1++) - { - /* Find empty gaps */ - if (!(present[i1+1] & EDGE_LEFT)) - { - int increment; /* fractional part */ - int denom; /* denominator of fraction */ - int step; /* integral step */ - int frac; /* fractional step */ - int reverse; - - /* find bottom of gap */ - i2 = i1+2; - while (!(present[i2] & EDGE_LEFT) && i2 < b->height) i2++; - - if (i2 < b->height) - { - denom = i2-i1; - x1 = b->data[i1].left; - x2 = b->data[i2].left; - step = (x2-x1)/denom; - frac = x2-x1 - step*denom; - if (frac < 0) - { - frac = -frac; - reverse = 1; - } - else - reverse = 0; - - increment = 0; - for (i=i1+1; i= denom) - { - increment -= denom; - x1 += reverse ? -1 : 1; - } - if (increment == 0 || reverse) - b->data[i].left = x1; - else - b->data[i].left = x1 + 1; - } - } - i1 = i2-1; /* advance to next possibility */ - } - } - - /* right edge */ - for (i1=start; i1height-2; i1++) - { - /* Find empty gaps */ - if (!(present[i1+1] & EDGE_RIGHT)) - { - int increment; /* fractional part */ - int denom; /* denominator of fraction */ - int step; /* integral step */ - int frac; /* fractional step */ - int reverse; - - /* find bottom of gap */ - i2 = i1+2; - while (!(present[i2] & EDGE_RIGHT) && i2 < b->height) i2++; - - if (i2 < b->height) - { - denom = i2-i1; - x1 = b->data[i1].right; - x2 = b->data[i2].right; - step = (x2-x1)/denom; - frac = x2-x1 - step*denom; - if (frac < 0) - { - frac = -frac; - reverse = 1; - } - else - reverse = 0; - - increment = 0; - for (i=i1+1; i= denom) - { - increment -= denom; - x1 += reverse ? -1 : 1; - } - if (reverse && increment != 0) - b->data[i].right = x1 - 1; - else - b->data[i].right = x1; - } - } - i1 = i2-1; /* advance to next possibility */ - } - } - -} - -static void -airbrush_blob_make_convex (AirBrushBlob *b, EdgeType *present) -{ - int x1, x2, y1, y2, i1, i2; - int i; - int start; - - /* Walk through edges, deleting points that aren't on convex hull */ - - start = 0; - while (!(present[start])) start++; - - /* left edge */ - - i1 = start-1; - i2 = start; - x1 = b->data[start].left - b->data[start].right; - y1 = 0; - - for (i=start+1;iheight;i++) - { - if (!(present[i] & EDGE_LEFT)) - continue; - - x2 = b->data[i].left - b->data[i2].left; - y2 = i-i2; - - while (x2*y1 - x1*y2 < 0) /* clockwise rotation */ - { - present[i2] &= ~EDGE_LEFT; - i2 = i1; - while (!(present[--i1] & EDGE_LEFT) && i1>=start); - - if (i1data[start].left - b->data[start].right; - y1 = 0; - } - else - { - x1 = b->data[i2].left - b->data[i1].left; - y1 = i2 - i1; - } - x2 = b->data[i].left - b->data[i2].left; - y2 = i - i2; - } - x1 = x2; - y1 = y2; - i1 = i2; - i2 = i; - } - - /* Right edge */ - - i1 = start -1; - i2 = start; - x1 = b->data[start].right - b->data[start].left; - y1 = 0; - - for (i=start+1;iheight;i++) - { - if (!(present[i] & EDGE_RIGHT)) - continue; - - x2 = b->data[i].right - b->data[i2].right; - y2 = i-i2; - - while (x2*y1 - x1*y2 > 0) /* counter-clockwise rotation */ - { - present[i2] &= ~EDGE_RIGHT; - i2 = i1; - while (!(present[--i1] & EDGE_RIGHT) && i1>=start); - - if (i1data[start].right - b->data[start].left; - y1 = 0; - } - else - { - x1 = b->data[i2].right - b->data[i1].right; - y1 = i2 - i1; - } - x2 = b->data[i].right - b->data[i2].right; - y2 = i - i2; - } - x1 = x2; - y1 = y2; - i1 = i2; - i2 = i; - } - - airbrush_blob_fill (b, present); -} - -AirBrushBlob * -airbrush_blob_convex_union (AirBrushBlob *b1, AirBrushBlob *b2) -{ - AirBrushBlob *result; - int y; - int i, j; - EdgeType *present; - - - /* Create the storage for the result */ - - y = MIN(b1->y,b2->y); - result = airbrush_blob_new (y, MAX(b1->y+b1->height,b2->y+b2->height)-y); - - if (result->height == 0) - return result; - - present = g_new0 (EdgeType, result->height); - - /* Initialize spans from original objects */ - - for (i=0, j=b1->y-y; iheight; i++,j++) - { - if (b1->data[i].right >= b1->data[i].left) - { - present[j] = EDGE_LEFT | EDGE_RIGHT; - result->data[j].left = b1->data[i].left; - result->data[j].right = b1->data[i].right; - } - } - - for (i=0, j=b2->y-y; iheight; i++,j++) - { - if (b2->data[i].right >= b2->data[i].left) - { - if (present[j]) - { - if (result->data[j].left > b2->data[i].left) - result->data[j].left = b2->data[i].left; - if (result->data[j].right < b2->data[i].right) - result->data[j].right = b2->data[i].right; - } - else - { - present[j] = EDGE_LEFT | EDGE_RIGHT; - result->data[j].left = b2->data[i].left; - result->data[j].right = b2->data[i].right; - } - } - } - - airbrush_blob_make_convex (result, present); - - g_free (present); - return result; -} - -/* You must be able to divide TABLE_SIZE with 4*/ - -#define TABLE_SIZE 256 -#define TABLE_QUARTER TABLE_SIZE/4 - -#define ELLIPSE_SHIFT 2 -#define TABLE_SHIFT 14 -#define TOTAL_SHIFT (ELLIPSE_SHIFT + TABLE_SHIFT) - -static int trig_initialized = 0; -static int trig_table[TABLE_SIZE]; -#define POWFAC 0.999 - - - -/* Scan convert an ellipse specified by _offsets_ of major and - minor axes, and by center into a airbrush_blob */ - -/* Warning UGLY code ahead :-)*/ - -AirBrushBlob * -airbrush_blob_ellipse (double xc, double yc, double xt, double yt, double xr, double yr, double xb, double yb, double xl, double yl) -{ - int i; - AirBrushBlob *rma, *rmi, *rtot; - gint maxyma, minyma, maxymi, minymi; - gint step; - double max_radius; - double ma_ang1, ma_ang2; - double x1, x2, y1, y2; - double xtotma, ytotma; - double xcma, ycma, ytma, xrma, ybma, xlma; - double xcmi, ycmi, ytmi, xrmi, ybmi, xlmi; - double mapoint_i, mapoint; - - gint xcma_shift, ycma_shift; - gint xcmi_shift, ycmi_shift; - gint ytma_shift, ytmi_shift; - gint xrma_shift, xrmi_shift; - gint ybma_shift, ybmi_shift; - gint xlma_shift, xlmi_shift; - - EdgeType *presentma; - EdgeType *presentmi; - - - if ((yt == yb) && (xr == xl) && (yt == xr)) - { - /*Zero*/ - - ytma = ytmi = xrma = xrmi = ybma = ybmi = xlma = xlmi = yt; - ycma = ycmi = yc; - xcma = xcmi = xc; - - } - else if (xr == xl) - { - if (yt > yb) - { - /*South*/ - - /*The Max circle*/ - ytma = ybma = xrma = xlma = xl; - mapoint_i = (((yt * yt) / yb) - yt); - mapoint = mapoint_i * pow(POWFAC, mapoint_i); - xcma = xc; - ycma = yc + mapoint; - - /*The Min Circle*/ - ytmi = xrmi = ybmi = xlmi = xl/2; - xcmi = xc; - ycmi = yc - mapoint/2; - - } - else - { - /*North*/ - - /*The Max circle*/ - ytma = ybma = xrma = xlma = xl; - mapoint_i = (((yb * yb) / yt) - yb); - mapoint = mapoint_i * pow(POWFAC, mapoint_i); - xcma = xc; - ycma = yc - mapoint; - - /*The Min Circle*/ - ytmi = xrmi = ybmi = xlmi = xl/2; - xcmi = xc; - ycmi = yc + mapoint/2; - - } - } - else if (yt == yb) - { - if (xr > xl) - { - /*East*/ - - /*The Max circle*/ - ytma = ybma = xrma = xlma = yt; - mapoint_i = (((xr * xr) /xl) -xr); - mapoint = mapoint_i * pow(POWFAC, mapoint_i); - xcma = mapoint + xc; - ycma = yc; - - /*The Min Circle*/ - ytmi = ybmi = xrmi = xlmi = yt/2; - xcmi = xc - mapoint/2; - ycmi = yc; - - } - else - { - /*West*/ - - /*The Max circle*/ - ytma = ybma = xrma = xlma = yt; - mapoint_i = (((xl * xl) /xr) - xl); - mapoint = mapoint_i * pow(POWFAC, mapoint_i); - xcma = xc - mapoint; - ycma = yc; - - - /*The Min Circle*/ - ytmi = ybmi = xrmi = xlmi = yt/2; - xcmi = xc + mapoint/2; - ycmi = yc; - - } - } - else if ((yt > yb) && (xr > xl)) - { - /*SouthEast*/ - - /*The Max circle*/ - ma_ang1 = atan(yt/xr); - x1 = cos(ma_ang1) * xl; - y1 = sin(ma_ang1) * yt; - ma_ang2 = G_PI_2 - ma_ang1; - x2 = cos(ma_ang2) * xr; - y2 = sin(ma_ang2) * yb; - xtotma = x1 + x2; - ytotma = y1 + y2; - ytma = ybma = xrma = xlma = hypot(ytotma, xtotma)/2; - mapoint_i = (((yt * yt + xr * xr) / hypot(yb, xl)) - hypot(yt, xr)); - mapoint = mapoint_i * pow(POWFAC , mapoint_i); - xcma = xc + (cos(ma_ang1) * mapoint); - ycma = yc + (sin(ma_ang1) * mapoint); - - /*The Min Circle*/ - ytmi = xrmi = ybmi = xlmi = hypot(yb, xl)/2; - xcmi = xc - (cos(ma_ang1) * mapoint * 0.5); - ycmi = yc - (sin(ma_ang1) * mapoint * 0.5); - - } - else if ((yt > yb) && (xl > xr)) - { - /*SouthWest*/ - - /*The Max circle*/ - ma_ang1 = atan(yt/xl); - x1 = cos(ma_ang1) * xr; - y1 = sin(ma_ang1) * yt; - ma_ang2 = G_PI_2 - ma_ang1; - x2 = cos(ma_ang2) * xl; - y2 = sin(ma_ang2) * yb; - xtotma = x1 + x2; - ytotma = y1 + y2; - ytma = ybma = xrma = xlma = hypot(ytotma, xtotma)/2; - mapoint_i = (((yt * yt + xl * xl) / hypot(yb, xr)) - hypot(yt, xl)); - mapoint = mapoint_i * pow(POWFAC, mapoint_i); - xcma = xc - (cos(ma_ang1) * mapoint); - ycma = yc + (sin(ma_ang1) * mapoint); - - /*The Min Circle*/ - ytmi = xrmi = ybmi = xlmi = hypot(yb, xr)/2; - xcmi = xc + (cos(ma_ang1) * mapoint * 0.5); - ycmi = yc - (sin(ma_ang1) * mapoint * 0.5); - - } - else if ((yb > yt) && (xl > xr)) - { - /*NorthWest*/ - - /*The Max circle*/ - ma_ang1 = atan(yb/xl); - x1 = cos(ma_ang1) * xl; - y1 = sin(ma_ang1) * yt; - ma_ang2 = G_PI_2 - ma_ang1; - x2 = cos(ma_ang2) * xr; - y2 = sin(ma_ang2) * yb; - xtotma = x1 + x2; - ytotma = y1 + y2; - ytma = ybma = xrma = xlma = hypot(ytotma, xtotma)/2; - mapoint_i = (((yb * yb + xl * xl) / hypot(yt, xr)) - hypot(yb, xl)); - mapoint = mapoint_i * pow(POWFAC, mapoint_i); - xcma = xc - (cos(ma_ang1) * mapoint); - ycma = yc - (sin(ma_ang1) * mapoint); - - /*The Min Circle*/ - ytmi = xrmi = ybmi = xlmi = hypot(yt, xr)/2; - xcmi = xc + (cos(ma_ang1) * mapoint * 0.5); - ycmi = yc + (sin(ma_ang1) * mapoint * 0.5); - - } - else -/*if ((yb > yt) && (xr > xl))*/ - { - /*NorthEast*/ - - /*The Max circle*/ - ma_ang1 = atan(yb/xr); - x1 = cos(ma_ang1) * xr; - y1 = sin(ma_ang1) * yt; - ma_ang2 = G_PI_2 - ma_ang1; - x2 = cos(ma_ang2) * xl; - y2 = sin(ma_ang2) * yb; - xtotma = x1 + x2; - ytotma = y1 + y2; - ytma = ybma = xrma = xlma = hypot(ytotma, xtotma)/2; - mapoint_i = (((yb * yb + xr * xr) / hypot(yt, xl)) - hypot(yb, xr)); - mapoint = mapoint_i * pow(POWFAC, mapoint_i); - xcma = xc + (cos(ma_ang1) * mapoint); - ycma = yc - (sin(ma_ang1) * mapoint); - - /*The Min Circle*/ - ytmi = xrmi = ybmi = xlmi = hypot(yt, xl)/2; - xcmi = xc - (cos(ma_ang1) * mapoint * 0.5); - ycmi = yc + (sin(ma_ang1) * mapoint * 0.5); - - } - if (ytmi <= 0) - { - ytmi = ybmi = xrmi = xlmi = 1; - } - - if (ytma <= 0) - { - ytma = ybma = xrma = xlma = 1; - } - - if (!trig_initialized) - { - trig_initialized = 1; - for (i=0; i<256; i++) - trig_table[i] = 0.5 + sin(i * (G_PI / 128.0)) * (1 << TABLE_SHIFT); - } - - -/*Make the Max circle*/ - - maxyma = ceil (ycma + fabs (ytma)); - minyma = floor (ycma - fabs (ybma)); - - - - rma = airbrush_blob_new (minyma, maxyma - minyma + 1); - - - presentma = g_new0 (EdgeType, rma->height); - - max_radius = ytma; - - step = TABLE_SIZE; - - while (step > 1 && (TABLE_SIZE / step < 4*max_radius)) - step >>= 1; - - /* Fill in the edge points */ - - xcma_shift = 0.5 + xcma * (1 << TOTAL_SHIFT); - ycma_shift = 0.5 + ycma * (1 << TOTAL_SHIFT); - ytma_shift = 0.5 + ytma * (1 << ELLIPSE_SHIFT); - xrma_shift = 0.5 + xrma * (1 << ELLIPSE_SHIFT); - ybma_shift = 0.5 + ybma * (1 << ELLIPSE_SHIFT); - xlma_shift = 0.5 + xlma * (1 << ELLIPSE_SHIFT); - - - for (i = 0 ; i < TABLE_SIZE ; i += step) - { - - gint x, y, yi, dydi; - - gint s = trig_table[i]; - gint c = trig_table[(TABLE_SIZE + TABLE_SIZE/4 - i) % TABLE_SIZE]; - - if (i < TABLE_QUARTER ) - { - x = (xcma_shift + c * xrma_shift + - (1 << (TOTAL_SHIFT - 1))) >> TOTAL_SHIFT; - yi = (ycma_shift + s * ytma_shift + - (1 << (TOTAL_SHIFT - 1))) >> TOTAL_SHIFT; - y = yi - rma->y; - dydi = 1; - - } - else if ( i < (2 * TABLE_QUARTER) ) - { - x = (xcma_shift + c * xlma_shift + - (1 << (TOTAL_SHIFT - 1))) >> TOTAL_SHIFT; - yi = (ycma_shift + s * ytma_shift + - (1 << (TOTAL_SHIFT - 1))) >> TOTAL_SHIFT; - - y = yi - rma->y; - - dydi = -1; - } - else if ( i < (3 * TABLE_QUARTER) ) - { - x = (xcma_shift + c * xlma_shift + - (1 << (TOTAL_SHIFT - 1))) >> TOTAL_SHIFT; - yi = (ycma_shift + s * ybma_shift + - (1 << (TOTAL_SHIFT - 1))) >> TOTAL_SHIFT; - y = yi - rma->y; - dydi = -1; - - } - else - { - x = (xcma_shift + c * xrma_shift + - (1 << (TOTAL_SHIFT - 1))) >> TOTAL_SHIFT; - y = ((ycma_shift + s * ybma_shift + - (1 << (TOTAL_SHIFT - 1))) >> TOTAL_SHIFT) - rma->y; - - dydi = 1; - - } - - - - - if (dydi <= 0) /* left edge */ - { - if (presentma[y] & EDGE_LEFT) - { - rma->data[y].left = MIN (rma->data[y].left, x); - } - else - { - presentma[y] |= EDGE_LEFT; - rma->data[y].left = x; - } - } - - if (dydi > 0) /* right edge */ - { - if (presentma[y] & EDGE_RIGHT) - { - rma->data[y].right = MAX (rma->data[y].right, x); - } - else - { - presentma[y] |= EDGE_RIGHT; - rma->data[y].right = x; - } - } - } - - /* Now fill in missing points */ - - airbrush_blob_fill (rma, presentma); - g_free (presentma); - -/*Make the Min circle*/ - - - maxymi = ceil (ycmi + fabs (ytmi)); - minymi = floor (ycmi - fabs (ybmi)); - - - rmi = airbrush_blob_new (minymi, maxymi - minymi + 1); - - - presentmi = g_new0 (EdgeType, rmi->height); - - max_radius = ytmi; - - step = TABLE_SIZE; - - while (step > 1 && (TABLE_SIZE / step < 4*max_radius)) - step >>= 1; - - /* Fill in the edge points */ - - xcmi_shift = 0.5 + xcmi * (1 << TOTAL_SHIFT); - ycmi_shift = 0.5 + ycmi * (1 << TOTAL_SHIFT); - ytmi_shift = 0.5 + ytmi * (1 << ELLIPSE_SHIFT); - xrmi_shift = 0.5 + xrmi * (1 << ELLIPSE_SHIFT); - ybmi_shift = 0.5 + ybmi * (1 << ELLIPSE_SHIFT); - xlmi_shift = 0.5 + xlmi * (1 << ELLIPSE_SHIFT); - - - - for (i = 0 ; i < TABLE_SIZE ; i += step) - { - - gint x, y, yi, dydi; - - gint s = trig_table[i]; - gint c = trig_table[(TABLE_SIZE + TABLE_SIZE/4 - i) % TABLE_SIZE]; - - if (i < TABLE_QUARTER ) - { - x = (xcmi_shift + c * xrmi_shift + - (1 << (TOTAL_SHIFT - 1))) >> TOTAL_SHIFT; - yi = (ycmi_shift + s * ytmi_shift + - (1 << (TOTAL_SHIFT - 1))) >> TOTAL_SHIFT; - y = yi - rmi->y; - dydi = 1; - - } - else if ( i < (2 * TABLE_QUARTER) ) - { - x = (xcmi_shift + c * xlmi_shift + - (1 << (TOTAL_SHIFT - 1))) >> TOTAL_SHIFT; - yi = (ycmi_shift + s * ytmi_shift + - (1 << (TOTAL_SHIFT - 1))) >> TOTAL_SHIFT; - - y = yi - rmi->y; - - dydi = -1; - } - else if ( i < (3 * TABLE_QUARTER) ) - { - x = (xcmi_shift + c * xlmi_shift + - (1 << (TOTAL_SHIFT - 1))) >> TOTAL_SHIFT; - yi = (ycmi_shift + s * ybmi_shift + - (1 << (TOTAL_SHIFT - 1))) >> TOTAL_SHIFT; - y = yi - rmi->y; - dydi = -1; - - } - else - { - x = (xcmi_shift + c * xrmi_shift + - (1 << (TOTAL_SHIFT - 1))) >> TOTAL_SHIFT; - y = ((ycmi_shift + s * ybmi_shift + - (1 << (TOTAL_SHIFT - 1))) >> TOTAL_SHIFT) - rmi->y; - - dydi = 1; - - } - - - - - if (dydi <= 0) /* left edge */ - { - if (presentmi[y] & EDGE_LEFT) - { - rmi->data[y].left = MIN (rmi->data[y].left, x); - } - else - { - presentmi[y] |= EDGE_LEFT; - rmi->data[y].left = x; - } - } - - if (dydi > 0) /* right edge */ - { - if (presentmi[y] & EDGE_RIGHT) - { - rmi->data[y].right = MAX (rmi->data[y].right, x); - } - else - { - presentmi[y] |= EDGE_RIGHT; - rmi->data[y].right = x; - } - } - } - - /* Now fill in missing points */ - - airbrush_blob_fill (rmi, presentmi); - g_free (presentmi); - - rtot = airbrush_blob_convex_union(rma, rmi); - - g_free (rma); - g_free (rmi); - - return rtot; -} - -void -airbrush_blob_bounds(AirBrushBlob *b, int *x, int *y, int *width, int *height) -{ - int i; - int x0, x1, y0, y1; - - i = 0; - while (iheight && b->data[i].left > b->data[i].right) - i++; - - if (iheight) - { - y0 = b->y + i; - x0 = b->data[i].left; - x1 = b->data[i].right + 1; - while (iheight && b->data[i].left <= b->data[i].right) - { - x0 = MIN(b->data[i].left, x0); - x1 = MAX(b->data[i].right+1, x1); - i++; - } - y1 = b->y + i; - } - else - { - x0 = y0 = 0; - x1 = y1 = 0; - } - - *x = x0; - *y = y0; - *width = x1 - x0; - *height = y1 - y0; -} - -void -airbrush_blob_dump(AirBrushBlob *b) { - - int i,j; - - - for (i=0; iheight; i++) - { - for (j=0;jdata[i].left;j++) - putchar(' '); - for (j=b->data[i].left;j<=b->data[i].right;j++) - putchar('*'); - putchar('\n'); - } -} - -/* This is just a first try to see how it works i.e ugly code :-) */ - - -AirBlob * -create_air_blob (double xc, - double yc, - double xt, - double yt, - double xr, - double yr, - double xb, - double yb, - double xl, - double yl, - double direction_abs, - double direction) -{ - AirBlob *air_blob; - double ma_ang1, ma_ang2; - double x1, x2, y1, y2; - double xtotma, ytotma; - double xcma, ycma, ytma, xrma, ybma, xlma; - double xcmi, ycmi, ytmi, xrmi, ybmi, xlmi; - double mapoint_i, mapoint; - - air_blob = airblob_new(1); - - air_blob->direction_abs = direction_abs; - air_blob->direction = direction; - air_blob->ycenter = yc; - air_blob->xcenter = xc; - - if ((yt == yb) && (xr == xl) && (yt == xr)) - { - /*Zero*/ - - ytma = ytmi = xrma = xrmi = ybma = ybmi = xlma = xlmi = yt; - ycma = ycmi = yc; - xcma = xcmi = xc; - - air_blob->main_line.size = yt; - air_blob->minor_line.size = yt; - - air_blob->maincross_line.size = yt * 2; - air_blob->maincross_line.dist = 0.0; - - air_blob->minorcross_line.size = yt * 2; - air_blob->minorcross_line.dist = 0.0; - - air_blob->direction = G_PI_2; - - } - else if (xr == xl) - { - if (yt > yb) - { - /*South*/ - - /*The Max circle*/ - ytma = ybma = xrma = xlma = xl; - mapoint_i = (((yt * yt) / yb) - yt); - mapoint = mapoint_i * pow(POWFAC, mapoint_i); - xcma = xc; - ycma = yc + mapoint; - - /*The Min Circle*/ - ytmi = xrmi = ybmi = xlmi = xl/2; - xcmi = xc; - ycmi = yc - mapoint/2; - - air_blob->main_line.size = mapoint + xl; - air_blob->minor_line.size = mapoint/2 + xl/2; - - air_blob->maincross_line.size = xl * 2; - air_blob->maincross_line.dist = mapoint; - - air_blob->minorcross_line.size = xl/2; - air_blob->minorcross_line.dist = mapoint/2; - - - - } - else - { - /*North*/ - - /*The Max circle*/ - ytma = ybma = xrma = xlma = xl; - mapoint_i = (((yb * yb) / yt) - yb); - mapoint = mapoint_i * pow(POWFAC, mapoint_i); - xcma = xc; - ycma = yc - mapoint; - - /*The Min Circle*/ - ytmi = xrmi = ybmi = xlmi = xl/2; - xcmi = xc; - ycmi = yc + mapoint/2; - - - air_blob->main_line.size = mapoint + xl; - air_blob->minor_line.size = mapoint/2 + xl/2; - - air_blob->maincross_line.size = xl * 2; - air_blob->maincross_line.dist = mapoint; - - air_blob->minorcross_line.size = xl/2; - air_blob->minorcross_line.dist = mapoint/2; - - - } - } - else if (yt == yb) - { - if (xr > xl) - { - /*East*/ - - /*The Max circle*/ - ytma = ybma = xrma = xlma = yt; - mapoint_i = (((xr * xr) /xl) -xr); - mapoint = mapoint_i * pow(POWFAC, mapoint_i); - xcma = mapoint + xc; - ycma = yc; - - /*The Min Circle*/ - ytmi = ybmi = xrmi = xlmi = yt/2; - xcmi = xc - mapoint/2; - ycmi = yc; - - air_blob->main_line.size = mapoint + yt; - air_blob->minor_line.size = mapoint/2 + yt/2; - - air_blob->maincross_line.size = xl * 2; - air_blob->maincross_line.dist = mapoint; - - air_blob->minorcross_line.size = xl/2; - air_blob->minorcross_line.dist = mapoint/2; - - - } - else - { - /*West*/ - - /*The Max circle*/ - ytma = ybma = xrma = xlma = yt; - mapoint_i = (((xl * xl) /xr) - xl); - mapoint = mapoint_i * pow(POWFAC, mapoint_i); - xcma = xc - mapoint; - ycma = yc; - - - /*The Min Circle*/ - ytmi = ybmi = xrmi = xlmi = yt/2; - xcmi = xc + mapoint/2; - ycmi = yc; - - air_blob->main_line.size = mapoint + yt; - air_blob->minor_line.size = mapoint/2 + yt/2; - - air_blob->maincross_line.size = xl * 2; - air_blob->maincross_line.dist = mapoint; - - air_blob->minorcross_line.size = xl/2; - air_blob->minorcross_line.dist = mapoint/2; - - - } - } - else if ((yt > yb) && (xr > xl)) - { - /*SouthEast*/ - - /*The Max circle*/ - ma_ang1 = atan(yt/xr); - x1 = cos(ma_ang1) * xl; - y1 = sin(ma_ang1) * yt; - ma_ang2 = G_PI_2 - ma_ang1; - x2 = cos(ma_ang2) * xr; - y2 = sin(ma_ang2) * yb; - xtotma = x1 + x2; - ytotma = y1 + y2; - ytma = ybma = xrma = xlma = hypot(ytotma, xtotma)/2; - mapoint_i = (((yt * yt + xr * xr) / hypot(yb, xl)) - hypot(yt, xr)); - mapoint = mapoint_i * pow(POWFAC , mapoint_i); - xcma = xc + (cos(ma_ang1) * mapoint); - ycma = yc + (sin(ma_ang1) * mapoint); - - /*The Min Circle*/ - ytmi = xrmi = ybmi = xlmi = hypot(yb, xl)/2; - xcmi = xc - (cos(ma_ang1) * mapoint * 0.5); - ycmi = yc - (sin(ma_ang1) * mapoint * 0.5); - - - air_blob->main_line.size = mapoint + xlma; - air_blob->minor_line.size = mapoint/2 + xlmi; - - - air_blob->maincross_line.size = xlma * 2; - air_blob->maincross_line.dist = mapoint; - - air_blob->minorcross_line.size = xlmi; - air_blob->minorcross_line.dist = mapoint/2; - - - - - } - else if ((yt > yb) && (xl > xr)) - { - /*SouthWest*/ - - /*The Max circle*/ - ma_ang1 = atan(yt/xl); - x1 = cos(ma_ang1) * xr; - y1 = sin(ma_ang1) * yt; - ma_ang2 = G_PI_2 - ma_ang1; - x2 = cos(ma_ang2) * xl; - y2 = sin(ma_ang2) * yb; - xtotma = x1 + x2; - ytotma = y1 + y2; - ytma = ybma = xrma = xlma = hypot(ytotma, xtotma)/2; - mapoint_i = (((yt * yt + xl * xl) / hypot(yb, xr)) - hypot(yt, xl)); - mapoint = mapoint_i * pow(POWFAC, mapoint_i); - xcma = xc - (cos(ma_ang1) * mapoint); - ycma = yc + (sin(ma_ang1) * mapoint); - - /*The Min Circle*/ - ytmi = xrmi = ybmi = xlmi = hypot(yb, xr)/2; - xcmi = xc + (cos(ma_ang1) * mapoint * 0.5); - ycmi = yc - (sin(ma_ang1) * mapoint * 0.5); - - air_blob->main_line.size = mapoint + xlma; - air_blob->minor_line.size = mapoint/2 + xlmi; - - air_blob->maincross_line.size = xlma * 2; - air_blob->maincross_line.dist = mapoint; - - air_blob->minorcross_line.size = xlmi; - air_blob->minorcross_line.dist = mapoint/2; - - } - else if ((yb > yt) && (xl > xr)) - { - /*NorthWest*/ - - /*The Max circle*/ - ma_ang1 = atan(yb/xl); - x1 = cos(ma_ang1) * xl; - y1 = sin(ma_ang1) * yt; - ma_ang2 = G_PI_2 - ma_ang1; - x2 = cos(ma_ang2) * xr; - y2 = sin(ma_ang2) * yb; - xtotma = x1 + x2; - ytotma = y1 + y2; - ytma = ybma = xrma = xlma = hypot(ytotma, xtotma)/2; - mapoint_i = (((yb * yb + xl * xl) / hypot(yt, xr)) - hypot(yb, xl)); - mapoint = mapoint_i * pow(POWFAC, mapoint_i); - xcma = xc - (cos(ma_ang1) * mapoint); - ycma = yc - (sin(ma_ang1) * mapoint); - - /*The Min Circle*/ - ytmi = xrmi = ybmi = xlmi = hypot(yt, xr)/2; - xcmi = xc + (cos(ma_ang1) * mapoint * 0.5); - ycmi = yc + (sin(ma_ang1) * mapoint * 0.5); - - air_blob->main_line.size = mapoint + xlma; - air_blob->minor_line.size = mapoint/2 + xlmi; - - air_blob->maincross_line.size = xlma * 2; - air_blob->maincross_line.dist = mapoint; - - air_blob->minorcross_line.size = xlmi; - air_blob->minorcross_line.dist = mapoint/2; - - - - - } - else -/*if ((yb > yt) && (xr > xl))*/ - { - /*NorthEast*/ - - /*The Max circle*/ - ma_ang1 = atan(yb/xr); - x1 = cos(ma_ang1) * xr; - y1 = sin(ma_ang1) * yt; - ma_ang2 = G_PI_2 - ma_ang1; - x2 = cos(ma_ang2) * xl; - y2 = sin(ma_ang2) * yb; - xtotma = x1 + x2; - ytotma = y1 + y2; - ytma = ybma = xrma = xlma = hypot(ytotma, xtotma)/2; - mapoint_i = (((yb * yb + xr * xr) / hypot(yt, xl)) - hypot(yb, xr)); - mapoint = mapoint_i * pow(POWFAC, mapoint_i); - xcma = xc + (cos(ma_ang1) * mapoint); - ycma = yc - (sin(ma_ang1) * mapoint); - - /*The Min Circle*/ - ytmi = xrmi = ybmi = xlmi = hypot(yt, xl)/2; - xcmi = xc - (cos(ma_ang1) * mapoint * 0.5); - ycmi = yc + (sin(ma_ang1) * mapoint * 0.5); - - air_blob->main_line.size = mapoint + xlma; - air_blob->minor_line.size = mapoint/2 + xlmi; - - - air_blob->maincross_line.size = xlma * 2; - air_blob->maincross_line.dist = mapoint; - - air_blob->minorcross_line.size = xlmi; - air_blob->minorcross_line.dist = mapoint/2; - - - } - - return air_blob; -} - -AirLine * -create_air_line(AirBlob *airblob) -{ - - int i; - double xcenter, ycenter; - - double direction; - - double masupport, misupport; - double ma_angsupport, mi_angsupport, iang; - - int min_x, max_x; - int min_y, max_y; - - AirLine *airline; - - /* - Yes I know I can do a cal of number of lines, but it is for - the moment much easier to just set a side mem for 16 lines - */ - - airline = airline_new(1); - - xcenter = airblob->xcenter; - ycenter = airblob->ycenter; - - airline->xcenter = xcenter/SUBSAMPLE; - airline->ycenter = ycenter/SUBSAMPLE; - - direction = airblob->direction_abs; - - /* - printf("Direction: %f\n", direction); - printf("Xcenter: %f\n",xcenter/SUBSAMPLE); - printf("Ycenter: %f\n",ycenter/SUBSAMPLE); - printf("MaCr.dist: %f\n",airblob->maincross_line.dist); - printf("MaCr.size: %f\n",airblob->maincross_line.size); - printf("MiCr.dist: %f\n",airblob->minorcross_line.dist); - printf("MiCr.size: %f\n",airblob->minorcross_line.size); - printf("Ma.size: %f\n",airblob->main_line.size); - printf("Mi.size: %f\n",airblob->minor_line.size); - */ - - if (direction == G_PI_2 || direction == G_PI) - { - direction = direction - 0.001; - } - - if (direction == -G_PI_2 || direction == -G_PI) - { - direction = direction + 0.001; - } - - if(direction == 0.0) - - { - - airline->line[0].x = (xcenter + airblob->maincross_line.dist)/SUBSAMPLE; - airline->line[0].y = (ycenter - airblob->maincross_line.size/2)/SUBSAMPLE; - airline->line[1].x = (xcenter - airblob->minorcross_line.dist)/SUBSAMPLE; - airline->line[1].y = (ycenter + airblob->minorcross_line.size/2)/SUBSAMPLE; - - airline->line[2].x = (xcenter + airblob->main_line.size)/SUBSAMPLE; - airline->line[2].y = (ycenter)/SUBSAMPLE; - airline->line[3].x = (xcenter - airblob->minor_line.size)/SUBSAMPLE; - airline->line[3].y = (ycenter)/SUBSAMPLE; - - airline->line[4].x = (xcenter + airblob->maincross_line.dist)/SUBSAMPLE; - airline->line[4].y = (ycenter + airblob->maincross_line.size/2)/SUBSAMPLE; - airline->line[5].x = (xcenter - airblob->minorcross_line.dist)/SUBSAMPLE; - airline->line[5].y = (ycenter - airblob->minorcross_line.size/2)/SUBSAMPLE; - - airline->nlines = 6; - - - } - - else if(direction == G_PI_2) - - { - - airline->line[0].x = (xcenter - airblob->maincross_line.size/2)/SUBSAMPLE; - airline->line[0].y = (ycenter - airblob->maincross_line.dist)/SUBSAMPLE; - airline->line[1].x = (xcenter + airblob->minorcross_line.dist)/SUBSAMPLE; - airline->line[1].y = (ycenter + airblob->minorcross_line.size/2)/SUBSAMPLE; - - airline->line[2].x = (xcenter)/SUBSAMPLE; - airline->line[2].y = (ycenter - airblob->main_line.size)/SUBSAMPLE; - airline->line[3].x = (xcenter)/SUBSAMPLE; - airline->line[3].y = (ycenter + airblob->minor_line.size)/SUBSAMPLE; - - airline->line[4].x = (xcenter + airblob->maincross_line.dist)/SUBSAMPLE; - airline->line[4].y = (ycenter - airblob->maincross_line.size/2)/SUBSAMPLE; - airline->line[5].x = (xcenter - airblob->minorcross_line.dist)/SUBSAMPLE; - airline->line[5].y = (ycenter + airblob->minorcross_line.size/2)/SUBSAMPLE; - - airline->nlines = 6; - printf("Hmm bummer G_PI_2\n"); - - } - - - else if(direction == G_PI) - - { - airline->line[0].x = (xcenter - airblob->maincross_line.dist)/SUBSAMPLE; - airline->line[0].y = (ycenter + airblob->maincross_line.size/2)/SUBSAMPLE; - airline->line[1].x = (xcenter + airblob->minorcross_line.dist)/SUBSAMPLE; - airline->line[1].y = (ycenter - airblob->minorcross_line.size/2)/SUBSAMPLE; - - airline->line[2].x = (xcenter - airblob->main_line.size)/SUBSAMPLE; - airline->line[2].y = (ycenter)/SUBSAMPLE; - airline->line[3].x = (xcenter + airblob->minor_line.size)/SUBSAMPLE; - airline->line[3].y = (ycenter)/SUBSAMPLE; - - airline->line[4].x = (xcenter - airblob->maincross_line.dist)/SUBSAMPLE; - airline->line[4].y = (ycenter - airblob->maincross_line.size/2)/SUBSAMPLE; - airline->line[5].x = (xcenter + airblob->minorcross_line.dist)/SUBSAMPLE; - airline->line[5].y = (ycenter + airblob->minorcross_line.size/2)/SUBSAMPLE; - - airline->nlines = 6; - - printf("Hmm bummer G_PI\n"); - - - } - - else if(direction == -G_PI_2) - - { - airline->line[0].x = (xcenter - airblob->maincross_line.dist)/SUBSAMPLE; - airline->line[0].y = (ycenter + airblob->maincross_line.size/2)/SUBSAMPLE; - airline->line[1].x = (xcenter + airblob->minorcross_line.dist)/SUBSAMPLE; - airline->line[1].y = (ycenter - airblob->minorcross_line.size/2)/SUBSAMPLE; - - airline->line[2].x = (xcenter)/SUBSAMPLE; - airline->line[2].y = (ycenter + airblob->main_line.size)/SUBSAMPLE; - airline->line[3].x = (xcenter)/SUBSAMPLE; - airline->line[3].y = (ycenter - airblob->minor_line.size)/SUBSAMPLE; - - airline->line[4].x = (xcenter + airblob->maincross_line.dist)/SUBSAMPLE; - airline->line[4].y = (ycenter + airblob->maincross_line.size/2)/SUBSAMPLE; - airline->line[5].x = (xcenter - airblob->minorcross_line.dist)/SUBSAMPLE; - airline->line[5].y = (ycenter - airblob->minorcross_line.size/2)/SUBSAMPLE; - - airline->nlines = 6; - - printf("Hmm bummer -G_PI_2\n"); - - - - } - - - else if(direction == -G_PI) - - { - airline->line[0].x = (xcenter - airblob->maincross_line.dist)/SUBSAMPLE; - airline->line[0].y = (ycenter + airblob->maincross_line.size/2)/SUBSAMPLE; - airline->line[1].x = (xcenter + airblob->minorcross_line.dist)/SUBSAMPLE; - airline->line[1].y = (ycenter - airblob->minorcross_line.size/2)/SUBSAMPLE; - - airline->line[2].x = (xcenter - airblob->main_line.size)/SUBSAMPLE; - airline->line[2].y = (ycenter)/SUBSAMPLE; - airline->line[3].x = (xcenter + airblob->minor_line.size)/SUBSAMPLE; - airline->line[3].y = (ycenter)/SUBSAMPLE; - - airline->line[4].x = (xcenter - airblob->maincross_line.dist)/SUBSAMPLE; - airline->line[4].y = (ycenter - airblob->maincross_line.size/2)/SUBSAMPLE; - airline->line[5].x = (xcenter + airblob->minorcross_line.dist)/SUBSAMPLE; - airline->line[5].y = (ycenter + airblob->minorcross_line.size/2)/SUBSAMPLE; - - airline->nlines = 6; - - printf("Hmm bummer -G_PI\n"); - - - } - - - else if ((direction < G_PI) && (direction > G_PI_2)) - - { - - - masupport = hypot(airblob->maincross_line.dist, airblob->maincross_line.size/2); - misupport = hypot(airblob->minorcross_line.dist,airblob->minorcross_line.size/2); - - ma_angsupport = atan(airblob->maincross_line.size/2/airblob->maincross_line.dist); - mi_angsupport = atan(airblob->minorcross_line.size/2/airblob->minorcross_line.dist); - - iang = airblob->direction_abs - G_PI_2; - - airline->line[0].x = (xcenter - sin(iang + ma_angsupport) * masupport)/SUBSAMPLE; - airline->line[0].y = (ycenter - cos(iang + ma_angsupport) * masupport)/SUBSAMPLE; - airline->line[1].x = (xcenter + sin(iang + mi_angsupport) * misupport)/SUBSAMPLE; - airline->line[1].y = (ycenter + cos(iang + mi_angsupport) * misupport)/SUBSAMPLE; - - airline->line[2].x = (xcenter - sin(iang) * airblob->main_line.size)/SUBSAMPLE; - airline->line[2].y = (ycenter - cos(iang) * airblob->main_line.size)/SUBSAMPLE; - airline->line[3].x = (xcenter + sin(iang) * airblob->minor_line.size)/SUBSAMPLE; - airline->line[3].y = (ycenter + cos(iang) * airblob->minor_line.size)/SUBSAMPLE; - - airline->line[4].x = (xcenter - sin(iang - ma_angsupport) * masupport)/SUBSAMPLE; - airline->line[4].y = (ycenter - cos(iang - ma_angsupport) * masupport)/SUBSAMPLE; - airline->line[5].x = (xcenter + sin(iang - mi_angsupport) * misupport)/SUBSAMPLE; - airline->line[5].y = (ycenter + cos(iang - mi_angsupport) * misupport)/SUBSAMPLE; - - /*airline->line[6].x = (xcenter - sin(iang + ma_angsupport/2.) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - airline->line[6].y = (ycenter - cos(iang + ma_angsupport/2.) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - airline->line[7].x = (xcenter - sin(iang - ma_angsupport/2.) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - airline->line[7].y = (ycenter - cos(iang - ma_angsupport/2.) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - - airline->line[8].x = (xcenter - sin(iang + ma_angsupport/4.) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - airline->line[8].y = (ycenter - cos(iang + ma_angsupport/4.) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - airline->line[9].x = (xcenter - sin(iang - ma_angsupport/4.) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - airline->line[9].y = (ycenter - cos(iang - ma_angsupport/4.) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - - airline->line[10].x = (xcenter - sin(iang + ma_angsupport/2. + ma_angsupport) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - airline->line[10].y = (ycenter - cos(iang + ma_angsupport/2. + ma_angsupport) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - airline->line[11].x = (xcenter - sin(iang - ma_angsupport/2. - ma_angsupport) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - airline->line[11].y = (ycenter - cos(iang - ma_angsupport/2. - ma_angsupport) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE;*/ - - - airline->nlines = 6; - - } - - else if ((direction < G_PI_2) && (direction > 0.0)) - - { - - - masupport = hypot(airblob->maincross_line.dist, airblob->maincross_line.size/2); - misupport = hypot(airblob->minorcross_line.dist,airblob->minorcross_line.size/2); - - ma_angsupport = atan(airblob->maincross_line.size/2/airblob->maincross_line.dist); - mi_angsupport = atan(airblob->minorcross_line.size/2/airblob->minorcross_line.dist); - - iang = airblob->direction_abs; - - airline->line[0].x = (xcenter + cos(iang + ma_angsupport) * masupport)/SUBSAMPLE; - airline->line[0].y = (ycenter - sin(iang + ma_angsupport) * masupport)/SUBSAMPLE; - airline->line[1].x = (xcenter - cos(iang + mi_angsupport) * misupport)/SUBSAMPLE; - airline->line[1].y = (ycenter + sin(iang + mi_angsupport) * misupport)/SUBSAMPLE; - - airline->line[2].x = (xcenter + cos(iang) * airblob->main_line.size)/SUBSAMPLE; - airline->line[2].y = (ycenter - sin(iang) * airblob->main_line.size)/SUBSAMPLE; - airline->line[3].x = (xcenter - cos(iang) * airblob->minor_line.size)/SUBSAMPLE; - airline->line[3].y = (ycenter + sin(iang) * airblob->minor_line.size)/SUBSAMPLE; - - airline->line[4].x = (xcenter + cos(iang - ma_angsupport) * masupport)/SUBSAMPLE; - airline->line[4].y = (ycenter - sin(iang - ma_angsupport) * masupport)/SUBSAMPLE; - airline->line[5].x = (xcenter - cos(iang - mi_angsupport) * misupport)/SUBSAMPLE; - airline->line[5].y = (ycenter + sin(iang - mi_angsupport) * misupport)/SUBSAMPLE; - - - /*airline->line[6].x = (xcenter + cos(iang + ma_angsupport/2.) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - airline->line[6].y = (ycenter - sin(iang + ma_angsupport/2.) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - airline->line[7].x = (xcenter + cos(iang - ma_angsupport/2.) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - airline->line[7].y = (ycenter - sin(iang - ma_angsupport/2.) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - - airline->line[8].x = (xcenter + cos(iang + ma_angsupport/4.) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - airline->line[8].y = (ycenter - sin(iang + ma_angsupport/4.) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - airline->line[9].x = (xcenter + cos(iang - ma_angsupport/4.) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - airline->line[9].y = (ycenter - sin(iang - ma_angsupport/4.) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - - airline->line[10].x = (xcenter + cos(iang + ma_angsupport/2. + ma_angsupport) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - airline->line[10].y = (ycenter - sin(iang + ma_angsupport/2. + ma_angsupport) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - airline->line[11].x = (xcenter + cos(iang - ma_angsupport/2. + ma_angsupport) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - airline->line[11].y = (ycenter - sin(iang - ma_angsupport/2. + ma_angsupport) * (masupport + (airblob->main_line.size - masupport)/2.0))/SUBSAMPLE; - - airline->line[12].x = airline->line[2].x + (airline->line[4].x - airline->line[2].x)/4; - airline->line[12].y = airline->line[2].y + (airline->line[4].y - airline->line[2].y)/4; - airline->line[13].x = airline->line[2].x + 3 * (airline->line[4].x - airline->line[2].x)/4; - airline->line[13].y = airline->line[2].y + 3 * (airline->line[4].y - airline->line[2].y)/4; - */ - - - - airline->nlines = 6; - - - } - - - else if ((direction < 0.0) && (direction > -G_PI_2)) - - { - - - masupport = hypot(airblob->maincross_line.dist, airblob->maincross_line.size/2); - misupport = hypot(airblob->minorcross_line.dist,airblob->minorcross_line.size/2); - - ma_angsupport = atan(airblob->maincross_line.size/2/airblob->maincross_line.dist); - mi_angsupport = atan(airblob->minorcross_line.size/2/airblob->minorcross_line.dist); - - iang = fabs(airblob->direction_abs); - - airline->line[0].x = (xcenter + cos(iang + ma_angsupport) * masupport)/SUBSAMPLE; - airline->line[0].y = (ycenter + sin(iang + ma_angsupport) * masupport)/SUBSAMPLE; - airline->line[1].x = (xcenter - cos(iang + mi_angsupport) * misupport)/SUBSAMPLE; - airline->line[1].y = (ycenter - sin(iang + mi_angsupport) * misupport)/SUBSAMPLE; - - airline->line[2].x = (xcenter + cos(iang) * airblob->main_line.size)/SUBSAMPLE; - airline->line[2].y = (ycenter + sin(iang) * airblob->main_line.size)/SUBSAMPLE; - airline->line[3].x = (xcenter - cos(iang) * airblob->minor_line.size)/SUBSAMPLE; - airline->line[3].y = (ycenter - sin(iang) * airblob->minor_line.size)/SUBSAMPLE; - - airline->line[4].x = (xcenter + cos(iang - ma_angsupport) * masupport)/SUBSAMPLE; - airline->line[4].y = (ycenter + sin(iang - ma_angsupport) * masupport)/SUBSAMPLE; - airline->line[5].x = (xcenter - cos(iang - mi_angsupport) * misupport)/SUBSAMPLE; - airline->line[5].y = (ycenter - sin(iang - mi_angsupport) * misupport)/SUBSAMPLE; - - airline->nlines = 6; - - } - - - else if ((direction < -G_PI_2) && (direction > -G_PI)) - - { - - - masupport = hypot(airblob->maincross_line.dist, airblob->maincross_line.size/2); - misupport = hypot(airblob->minorcross_line.dist,airblob->minorcross_line.size/2); - - ma_angsupport = atan(airblob->maincross_line.size/2/airblob->maincross_line.dist); - mi_angsupport = atan(airblob->minorcross_line.size/2/airblob->minorcross_line.dist); - - iang = fabs(airblob->direction_abs) - G_PI_2; - - airline->line[0].x = (xcenter - sin(iang + ma_angsupport) * masupport)/SUBSAMPLE; - airline->line[0].y = (ycenter + cos(iang + ma_angsupport) * masupport)/SUBSAMPLE; - airline->line[1].x = (xcenter + sin(iang + mi_angsupport) * misupport)/SUBSAMPLE; - airline->line[1].y = (ycenter - cos(iang + mi_angsupport) * misupport)/SUBSAMPLE; - - airline->line[2].x = (xcenter - sin(iang) * airblob->main_line.size)/SUBSAMPLE; - airline->line[2].y = (ycenter + cos(iang) * airblob->main_line.size)/SUBSAMPLE; - airline->line[3].x = (xcenter + sin(iang) * airblob->minor_line.size)/SUBSAMPLE; - airline->line[3].y = (ycenter - cos(iang) * airblob->minor_line.size)/SUBSAMPLE; - - airline->line[4].x = (xcenter - sin(iang - ma_angsupport) * masupport)/SUBSAMPLE; - airline->line[4].y = (ycenter + cos(iang - ma_angsupport) * masupport)/SUBSAMPLE; - airline->line[5].x = (xcenter + sin(iang - mi_angsupport) * misupport)/SUBSAMPLE; - airline->line[5].y = (ycenter - cos(iang - mi_angsupport) * misupport)/SUBSAMPLE; - - airline->nlines = 6; - - } - else - { - printf("Hmm a bug in the create_air_line"); - } - - - - - - min_x = max_x = airline->xcenter; - min_y = max_y = airline->ycenter; - - /* - - for (i=0; i < airline->nlines ; i++) - { - printf("x%d, value %d\n", i, airline->line[i].x); - printf("y%d, value %d\n", i, airline->line[i].y); - } - - printf("The xcenter %d\n",airline->xcenter); - printf("The ycenter %d\n",airline->ycenter); - - */ - - for (i=0; i < airline->nlines ; i++) - { - min_x = MIN(airline->line[i].x, min_x); - max_x = MAX(airline->line[i].x, max_x); - min_y = MIN(airline->line[i].y, min_y); - max_y = MAX(airline->line[i].y, max_y); - } - - airline->width = max_x - min_x + 1; - airline->height = max_y - min_y + 1; - - airline->min_x = min_x; - airline->min_y = min_y; - airline->max_x = max_x; - airline->max_y = max_y; - - return airline; - -} - -AirBlob * -trans_air_blob(AirBlob *airblob_last, AirBlob *airblob_present, double dist, int xcen, int ycen) -{ - - AirBlob *trans_airblob; - - double direction_last_abs, direction_present_abs; - double idirection_abs; - - double direction_last, direction_present; - double idirection; - - double main_line_present, main_line_last; - - - double minor_line_present, minor_line_last; - - - double maincross_line_dist_present, maincross_line_dist_last; - - double minorcross_line_dist_present, minorcross_line_dist_last; - - - double maincross_line_size_present, maincross_line_size_last; - - double minorcross_line_size_present, minorcross_line_size_last; - - - - trans_airblob = airblob_new(1); - - direction_last_abs = airblob_last->direction_abs + G_PI; - direction_present_abs = airblob_present->direction_abs + G_PI; - - idirection_abs = direction_present_abs - direction_last_abs; - - direction_last = airblob_last->direction + G_PI_2; - direction_present = airblob_present->direction + G_PI_2; - - idirection = direction_present - direction_last; - - main_line_present = airblob_present->main_line.size; - main_line_last = airblob_last->main_line.size; - - minor_line_present = airblob_present->minor_line.size; - minor_line_last = airblob_last->minor_line.size; - - maincross_line_dist_present = airblob_present->maincross_line.dist; - maincross_line_size_present = airblob_present->maincross_line.size; - minorcross_line_dist_present = airblob_present->minorcross_line.dist; - minorcross_line_size_present = airblob_present->minorcross_line.size; - - maincross_line_dist_last = airblob_last->maincross_line.dist; - maincross_line_size_last = airblob_last->maincross_line.size; - minorcross_line_dist_last = airblob_last->minorcross_line.dist; - minorcross_line_size_last = airblob_last->minorcross_line.size; - - - - - /* - Now we have to guess a little :-). Why? - Well we can't know if the users is painting - up/down or if she is painting a circle at high speed. - As you may notice it be so that the last airblob has - a direction more or less G_PI rad differernt from the - present airblob. But we can't know if she tured the - airbrush quickly (so that there was no mouse capture - during the turn) or if she paints just up and down the - same direction. - - There for we guess that we want to pait up and down - when the diff in direction is bigger than 171 deg and - smaller than 189 deg. - - */ - - if ((fabs(idirection_abs) > (G_PI - 0.1571)) && (fabs(idirection_abs) < (G_PI + 0.1571))) - { - /* We asume that the artist meant to paint in a "strait line" by just tilting the airbrush*/ - - idirection_abs = idirection_abs - G_PI; - - if ((idirection_abs * dist) > (idirection_abs/2)) - { - if ((direction_present_abs - idirection_abs * dist) > 2 * G_PI) - { - trans_airblob->direction_abs = direction_present_abs - idirection_abs * dist - 2 * G_PI - G_PI; - } - else if ((direction_present_abs - idirection_abs * dist) < 0.0) - { - trans_airblob->direction_abs = direction_present_abs - idirection_abs * dist + 2 * G_PI - G_PI; - } - else - { - trans_airblob->direction_abs = direction_present_abs - idirection_abs * dist - G_PI; - } - } - else - { - if ((direction_present_abs + idirection_abs * dist) > 2 * G_PI) - { - trans_airblob->direction_abs = direction_present_abs + idirection_abs * dist - 2 * G_PI - G_PI; - } - else if ((direction_present_abs + idirection_abs * dist) < 0.0) - { - trans_airblob->direction_abs = direction_present_abs + idirection_abs * dist + 2 * G_PI - G_PI; - } - else - { - trans_airblob->direction_abs = direction_present_abs + idirection_abs * dist - G_PI; - } - } - - trans_airblob->main_line.size = main_line_last + ((minor_line_present - main_line_last) * dist); - trans_airblob->minor_line.size = minor_line_last + ((main_line_present - minor_line_last) * dist); - - trans_airblob->maincross_line.dist = maincross_line_dist_last + ((minorcross_line_dist_present - maincross_line_dist_last) * dist); - trans_airblob->maincross_line.size = maincross_line_size_last + ((minorcross_line_size_present - maincross_line_size_last) * dist); - - trans_airblob->minorcross_line.dist = minorcross_line_dist_last + ((maincross_line_dist_present - minorcross_line_dist_last) * dist); - trans_airblob->minorcross_line.size = minorcross_line_size_last + ((maincross_line_size_present - minorcross_line_size_last) * dist); - - } - - else if (fabs(idirection_abs) < (G_PI - 0.1571)) - { - if ((direction_last_abs + idirection_abs * dist) > 2*G_PI) - { - trans_airblob->direction_abs = direction_last_abs + idirection_abs * dist - 2 * G_PI - G_PI; - } - else if((direction_last_abs + idirection_abs * dist) < 0.0) - { - trans_airblob->direction_abs = direction_last_abs + idirection_abs * dist + 2 * G_PI - G_PI; - } - else - { - trans_airblob->direction_abs = direction_last_abs + idirection_abs * dist - G_PI; - } - - trans_airblob->main_line.size = main_line_last + ((main_line_present - main_line_last) * dist); - trans_airblob->minor_line.size = minor_line_last + ((minor_line_present - minor_line_last) * dist); - - trans_airblob->maincross_line.dist = maincross_line_dist_last + ((maincross_line_dist_present - maincross_line_dist_last) * dist); - trans_airblob->maincross_line.size = maincross_line_size_last + ((maincross_line_size_present - maincross_line_size_last) * dist); - - trans_airblob->minorcross_line.dist = minorcross_line_dist_last + ((minorcross_line_dist_present - minorcross_line_dist_last) * dist); - trans_airblob->minorcross_line.size = minorcross_line_size_last + ((minorcross_line_size_present - minorcross_line_size_last) * dist); - } - else - { - - /* We asume that the artist always travels the shortest way around the "clock" */ - - idirection_abs = idirection_abs - G_PI; - - if ((direction_last_abs + idirection_abs * dist) > 2*G_PI) - { - trans_airblob->direction_abs = direction_last_abs + idirection_abs * dist - 2 * G_PI - G_PI; - } - else if((direction_last_abs + idirection_abs * dist) < 0.0) - { - trans_airblob->direction_abs = direction_last_abs + idirection_abs * dist + 2 * G_PI - G_PI; - } - else - { - trans_airblob->direction_abs = direction_last_abs + idirection_abs * dist - G_PI; - } - - trans_airblob->main_line.size = main_line_last + ((main_line_present - main_line_last) * dist); - trans_airblob->minor_line.size = minor_line_last + ((minor_line_present - minor_line_last) * dist); - - trans_airblob->maincross_line.dist = maincross_line_dist_last + ((maincross_line_dist_present - maincross_line_dist_last) * dist); - trans_airblob->maincross_line.size = maincross_line_size_last + ((maincross_line_size_present - maincross_line_size_last) * dist); - - trans_airblob->minorcross_line.dist = minorcross_line_dist_last + ((minorcross_line_dist_present - minorcross_line_dist_last) * dist); - trans_airblob->minorcross_line.size = minorcross_line_size_last + ((minorcross_line_size_present - minorcross_line_size_last) * dist); - - } - - - trans_airblob->xcenter = xcen * SUBSAMPLE; - trans_airblob->ycenter = ycen * SUBSAMPLE; - - return trans_airblob; - -} - - - - - - - - - - - - - - - - diff --git a/app/tools/airbrush_blob.h b/app/tools/airbrush_blob.h deleted file mode 100644 index d11a566537..0000000000 --- a/app/tools/airbrush_blob.h +++ /dev/null @@ -1,153 +0,0 @@ -/* airbrush_blob.h: routines for manipulating scan converted convex - * polygons. - * - * Copyright 1998, Owen Taylor - * - * > Please contact the above author before modifying the copy < - * > of this file in the GIMP distribution. Thanks. < - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * -*/ - -#ifndef __AIRBRUSHBLOB_H__ -#define __AIRBRUSHBLOB_H__ - -typedef enum { - CROSS = 0, - CROSS_LEFT = 1, - CROSS_RIGHT = 2, - CROSS_WHOLE_LINE = 3, - CROSS_NORMAL = 4 -} CrossType; - -typedef enum { - RIGHT_LEFT = 0, - LEFT_RIGHT = 1, - TOP_BOT = 2, - BOT_TOP = 3, - NONE = 4 -} MoveType; - -/* The AirBlob, which is a abstract of a real AirBrushBlob */ - -typedef struct _AirBlob AirBlob; -typedef struct _AirPoint AirPoint; -typedef struct _SupportLine SupportLine; - - -struct _AirPoint { - int x; - int y; -}; - -struct _SupportLine { - double size; - double dist; -}; - -struct _AirBlob { - double direction_abs; - double direction; - double ycenter; - double xcenter; - SupportLine main_line; - SupportLine minor_line; - SupportLine maincross_line; - SupportLine minorcross_line; -}; - - -/* The AirLine is a reslut of a AirBlob */ -typedef struct _AirLine AirLine; - -struct _AirLine { - int xcenter; - int ycenter; - AirPoint line[16]; - int min_x, min_y; - int max_x, max_y; - int width, height; - int nlines; -}; - - -typedef struct _AirBrushBlobPoint AirBrushBlobPoint; -typedef struct _AirBrushBlobSpan AirBrushBlobSpan; -typedef struct _AirBrushBlob AirBrushBlob; - -struct _AirBrushBlobPoint { - int x; - int y; -}; - -struct _AirBrushBlobSpan { - int left; - double angle_left; - double angle_left_abs; - double dist_left; - int right; - double angle_right; - double angle_right_abs; - double dist_right; - - CrossType cross_type; - int x_cross; - - int center; - double dist; - -}; - -struct _AirBrushBlob { - int y; - int height; - int width; - int min_x; - int max_x; - MoveType move; - double direction_abs; - double direction; - CrossType cross; - AirBrushBlobSpan data[1]; -}; - - -typedef struct _AirBrush AirBrush; - -struct _AirBrush { - AirBrushBlob airbrush_blob; - AirBlob airblob; -}; - - - - -AirBlob *create_air_blob (double xc, double yc, double xt, double yt, double xr, double yr, double xb, double yb, double xl, double yl, double direction_abs, double direction); -AirBlob *trans_air_blob(AirBlob *airblob_last, AirBlob *airblob_present, double dist, int xc, int yc); -AirLine *create_air_line(AirBlob *airblob); - - - - - -AirBrushBlob *airbrush_blob_convex_union (AirBrushBlob *b1, AirBrushBlob *b2); -AirBrushBlob *airbrush_blob_ellipse (double xc, double yc, double xt, double yt, double xr, double yr, double xb, double yb, double xl, double yl); -void airbrush_blob_bounds (AirBrushBlob *b, int *x, int *y, int *width, int *height); - - - - -#endif /* __AIRBRUSHBLOB_H__ */