Commit 416d2e2f authored by Maurits Rijk's avatar Maurits Rijk
Browse files

Fix for #124158. (always show both the Paint

and Select Tab). Also first attempt to split this hug file into
smaller pieces to make this plug-in a bit more manageable.
parent 9407ecba
2003-10-19 Maurits Rijk <lpeek.mrijk@consunet.nl>
* Makefile.am
* plug-ins/gfig/gfig_*.[ch]: new files split from gfig.c
* plug-ins/gfig/gfig.c: fix for #124158 (always show both the Paint
and Select Tab). Also first attempt to split this hug file into
smaller pieces to make this plug-in a bit more manageable.
2003-10-19 Sven Neumann <sven@gimp.org>
 
* app/config/Makefile.am
......@@ -14,6 +14,23 @@ libexec_PROGRAMS = gfig
gfig_SOURCES = \
gfig.c \
gfig.h \
gfig_arc.c \
gfig_arc.h \
gfig_bezier.c \
gfig_bezier.h \
gfig_circle.c \
gfig_circle.h \
gfig_ellipse.c \
gfig_ellipse.h \
gfig_line.c \
gfig_line.h \
gfig_poly.c \
gfig_poly.h \
gfig_spiral.c \
gfig_spiral.h \
gfig_star.c \
gfig_star.h \
gfig-stock.c \
gfig-stock.h \
pix_data.h
......
This diff is collapsed.
/*
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This is a plug-in for the GIMP.
*
* Generates images containing vector type drawings.
*
* Copyright (C) 1997 Andy Thomas alt@picnic.demon.co.uk
*
* 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 __GFIG_H__
#define __GFIG_H__
#include "gfig_dobject.h"
#define MAX_LOAD_LINE 256
extern gint line_no;
extern gint preview_width, preview_height;
extern gint drawing_pic;
extern gint need_to_scale;
extern gint32 gfig_image;
extern gint32 gfig_drawable;
extern GdkGC *gfig_gc;
extern gdouble scale_x_factor, scale_y_factor;
extern GtkWidget *gfig_preview;
extern GtkWidget *pic_preview;
extern Dobject *tmp_line;
typedef enum
{
RECT_GRID = 0,
POLAR_GRID,
ISO_GRID
} GridType;
typedef struct
{
gint gridspacing;
GridType gridtype;
gboolean drawgrid;
gboolean snap2grid;
gboolean lockongrid;
gboolean showcontrol;
} GfigOpts;
typedef enum
{
ADD = 0,
SUBTRACT,
REPLACE,
INTERSECT
} SelectionType;
typedef enum
{
ARC_SEGMENT = 0,
ARC_SECTOR
} ArcType;
typedef enum
{
FILL_FOREGROUND = 0,
FILL_BACKGROUND,
FILL_PATTERN
} FillType;
typedef enum
{
FILL_EACH = 0,
FILL_AFTER
} FillWhen;
typedef struct
{
SelectionType type; /* ADD etc .. */
gint antia; /* Boolean for Antia */
gint feather; /* Feather it ? */
gdouble feather_radius; /* Radius to feather */
ArcType as_pie; /* Arc type selection segment/sector */
FillType fill_type; /* Fill type for selection */
FillWhen fill_when; /* Fill on each selection or after all? */
gdouble fill_opacity; /* You can guess this one */
} selection_option;
typedef enum
{
ORIGINAL_LAYER = 0,
SINGLE_LAYER,
MULTI_LAYER
} DrawonLayers;
typedef enum
{
LAYER_TRANS_BG = 0,
LAYER_BG_BG,
LAYER_FG_BG,
LAYER_WHITE_BG,
LAYER_COPY_BG
} LayersBGType;
typedef enum
{
PAINT_BRUSH_TYPE = 0,
PAINT_SELECTION_TYPE,
PAINT_SELECTION_FILL_TYPE
} PaintType;
typedef enum
{
BRUSH_BRUSH_TYPE = 0,
BRUSH_PENCIL_TYPE,
BRUSH_AIRBRUSH_TYPE,
BRUSH_PATTERN_TYPE
} BrushType;
typedef struct
{
GfigOpts opts;
gboolean showimage;
gint maxundo;
gboolean showpos;
gdouble brushfade;
gdouble brushgradient;
gdouble airbrushpressure;
DrawonLayers onlayers;
LayersBGType onlayerbg;
PaintType painttype;
gboolean reverselines;
gboolean scaletoimage;
gdouble scaletoimagefp;
gboolean approxcircles;
BrushType brshtype;
DobjType otype;
} SelectItVals;
typedef struct DAllObjs
{
struct DAllObjs *next;
Dobject *obj; /* Object on list */
} DAllObjs;
typedef struct DFigObj
{
gchar *name; /* Trailing name of file */
gchar *filename; /* Filename itself */
gchar *draw_name; /* Name of the drawing */
gfloat version; /* Version number of data file */
GfigOpts opts; /* Options enforced when fig saved */
DAllObjs *obj_list; /* Objects that make up this list */
gint obj_status; /* See above for possible values */
GtkWidget *list_item;
GtkWidget *label_widget;
GtkWidget *pixmap_widget;
} GFigObj;
extern GFigObj *current_obj;
extern selection_option selopt;
extern SelectItVals selvals;
void add_to_all_obj (GFigObj * fobj, Dobject *obj);
gchar *get_line (gchar *buf,
gint s,
FILE *from,
gint init);
gint gfig_scale_x (gint x);
gint gfig_scale_y (gint y);
void scale_to_xy (gdouble *list,
gint size);
void scale_to_original_xy (gdouble *list,
gint size);
gint adjust_pic_coords (gint coord,
gint ratio);
void reverse_pairs_list (gdouble *list,
gint size);
void gfig_paint (BrushType brush_type,
gint32 drawable_ID,
gint seg_count,
gdouble line_pnts[]);
void draw_circle (GdkPoint *p);
void draw_sqr (GdkPoint *p);
void num_sides_dialog (gchar *d_title,
gint *num_sides,
gint *which_way,
gint adj_min,
gint adj_max);
#endif /* __GFIG_H__ */
/*
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This is a plug-in for the GIMP.
*
* Generates images containing vector type drawings.
*
* Copyright (C) 1997 Andy Thomas alt@picnic.demon.co.uk
*
* 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 <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
#include "config.h"
#include "libgimp/stdplugins-intl.h"
#include "gfig.h"
#include "gfig_line.h"
static Dobject * d_new_arc (gint x, gint y);
/* Distance between two lines */
static gdouble
dist (gdouble x1,
gdouble y1,
gdouble x2,
gdouble y2)
{
double s1 = x1 - x2;
double s2 = y1 - y2;
return sqrt (s1 * s1 + s2 * s2);
}
/* Mid point of line returned */
static void
mid_point (gdouble x1,
gdouble y1,
gdouble x2,
gdouble y2,
gdouble *mx,
gdouble *my)
{
*mx = ((double) (x1 - x2))/2.0 + (double)x2;
*my = ((double) (y1 - y2))/2.0 + (double)y2;
}
/* Careful about infinite grads */
static gdouble
line_grad (gdouble x1,
gdouble y1,
gdouble x2,
gdouble y2)
{
double dx, dy;
dx = x1 - x2;
dy = y1 - y2;
return (dx == 0.0) ? 0.0 : dy / dx;
}
/* Constant of line that goes through x, y with grad lgrad */
static gdouble
line_cons (gdouble x,
gdouble y,
gdouble lgrad)
{
return y - lgrad * x;
}
/*Get grad & const for perpend. line to given points */
static void
line_definition (gdouble x1,
gdouble y1,
gdouble x2,
gdouble y2,
gdouble *lgrad,
gdouble *lconst)
{
double grad1;
double midx, midy;
grad1 = line_grad (x1, y1, x2, y2);
if (grad1 == 0.0)
{
#ifdef DEBUG
printf ("Infinite grad....\n");
#endif /* DEBUG */
return;
}
mid_point (x1, y1, x2, y2, &midx, &midy);
/* Invert grad for perpen gradient */
*lgrad = -1.0/grad1;
*lconst = line_cons (midx, midy,*lgrad);
}
/* Arch details
* Given three points get arc radius and the co-ords
* of center point.
*/
static void
arc_details (GdkPoint *vert_a,
GdkPoint *vert_b,
GdkPoint *vert_c,
GdkPoint *center_pnt,
gdouble *radius)
{
/* Only vertices are in whole numbers - everything else is in doubles */
double ax, ay;
double bx, by;
double cx, cy;
double len_a, len_b, len_c;
double sum_sides2;
double area;
double circumcircle_R;
double line1_grad, line1_const;
double line2_grad, line2_const;
double inter_x=0.0, inter_y=0.0;
int got_x=0, got_y=0;
ax = (double) (vert_a->x);
ay = (double) (vert_a->y);
bx = (double) (vert_b->x);
by = (double) (vert_b->y);
cx = (double) (vert_c->x);
cy = (double) (vert_c->y);
#ifdef DEBUG
printf ("Vertices (%f,%f), (%f,%f), (%f,%f)\n", ax, ay, bx, by, cx, cy);
#endif /* DEBUG */
len_a = dist (ax, ay, bx, by);
len_b = dist (bx, by, cx, cy);
len_c = dist (cx, cy, ax, ay);
#ifdef DEBUG
printf ("len_a = %f, len_b = %f, len_c = %f\n", len_a, len_b, len_c);
#endif /* DEBUG */
sum_sides2 = (fabs (len_a) + fabs (len_b) + fabs (len_c))/2;
#ifdef DEBUG
printf ("Sum sides / 2 = %f\n", sum_sides2);
#endif /* DEBUG */
/* Area */
area = sqrt (sum_sides2*(sum_sides2 - len_a)*(sum_sides2 - len_b)*(sum_sides2 - len_c));
#ifdef DEBUG
printf ("Area of triangle = %f\n", area);
#endif /* DEBUG */
/* Circumcircle */
circumcircle_R = len_a*len_b*len_c/(4*area);
*radius = circumcircle_R;
#ifdef DEBUG
printf ("Circumcircle radius = %f\n", circumcircle_R);
#endif /* DEBUG */
/* Deal with exceptions - I hate exceptions */
if (ax == bx || ax == cx || cx == bx)
{
/* vert line -> mid point gives inter_x */
if (ax == bx && bx == cx)
{
/* Straight line */
double miny = ay;
double maxy = ay;
if (by > maxy)
maxy = by;
if (by < miny)
miny = by;
if (cy > maxy)
maxy = cy;
if (cy < miny)
miny = cy;
inter_y = (maxy - miny)/2 + miny;
}
else if (ax == bx)
{
inter_y = (ay - by)/2 + by;
}
else if (bx == cx)
{
inter_y = (by - cy)/2 + cy;
}
else
{
inter_y = (cy - ay)/2 + ay;
}
got_y = 1;
}
if (ay == by || by == cy || ay == cy)
{
/* Horz line -> midpoint gives inter_y */
if (ax == bx && bx == cx)
{
/* Straight line */
double minx = ax;
double maxx = ax;
if (bx > maxx)
maxx = bx;
if (bx < minx)
minx = bx;
if (cx > maxx)
maxx = cx;
if (cx < minx)
minx = cx;
inter_x = (maxx - minx)/2 + minx;
}
else if (ay == by)
{
inter_x = (ax - bx)/2 + bx;
}
else if (by == cy)
{
inter_x = (bx - cx)/2 + cx;
}
else
{
inter_x = (cx - ax)/2 + ax;
}
got_x = 1;
}
if (!got_x || !got_y)
{
/* At least two of the lines are not parallel to the axis */
/*first line */
if (ax != bx && ay != by)
line_definition (ax, ay, bx, by, &line1_grad, &line1_const);
else
line_definition (ax, ay, cx, cy, &line1_grad, &line1_const);
/* second line */
if (bx != cx && by != cy)
line_definition (bx, by, cx, cy, &line2_grad, &line2_const);
else
line_definition (ax, ay, cx, cy, &line2_grad, &line2_const);
}
/* Intersection point */
if (!got_x)
inter_x = /*rint*/((line2_const - line1_const)/(line1_grad - line2_grad));
if (!got_y)
inter_y = /*rint*/((line1_grad * inter_x + line1_const));
#ifdef DEBUG
printf ("Intersection point is (%f,%f)\n", inter_x, inter_y);
#endif /* DEBUG */
center_pnt->x = (gint16)inter_x;
center_pnt->y = (gint16)inter_y;
}
static gdouble
arc_angle (GdkPoint *pnt,
GdkPoint *center)
{
/* Get angle (in degress) of point given origin of center */
gint16 shift_x;
gint16 shift_y;
gdouble offset_angle;
shift_x = pnt->x - center->x;
shift_y = -pnt->y + center->y;
offset_angle = atan2 (shift_y, shift_x);
#ifdef DEBUG
printf ("offset_ang = %f\n", offset_angle);
#endif /* DEBUG */
if (offset_angle < 0)
offset_angle += 2*G_PI;
return (offset_angle*360/(2*G_PI));
}
static void
d_save_arc (Dobject *obj,
FILE *to)
{
DobjPoints * spnt;
spnt = obj->points;
if (!spnt)
return;
fprintf (to, "<ARC>\n");
while (spnt)
{
fprintf (to, "%d %d\n",
spnt->pnt.x,
spnt->pnt.y);
spnt = spnt->next;
}
fprintf (to, "</ARC>\n");
}
Dobject *
d_load_arc (FILE *from)
{
Dobject *new_obj = NULL;
gint xpnt;
gint ypnt;
gchar buf[MAX_LOAD_LINE];
gint num_pnts = 0;
#ifdef DEBUG
printf ("Load arc called\n");
#endif /* DEBUG */
while (get_line (buf, MAX_LOAD_LINE, from, 0))
{
if (sscanf (buf, "%d %d", &xpnt, &ypnt) != 2)
{
/* Must be the end */
if (strcmp ("</ARC>", buf) || num_pnts != 3)
{