From 6ee2d18e4a31905c9f961ef6dc7c8b1d0965fc1a Mon Sep 17 00:00:00 2001
From: ehennes <[EMAIL PROTECTED]>
Date: Tue, 14 Oct 2008 17:45:16 -0700
Subject: [PATCH] Changed postscript output functions to use generic hatch
algorithms.
Changed both box and circle postscript output functions to use the generic
hatching algorithms.
---
libgeda/src/o_box_basic.c | 130 +++++++-----------------------------------
libgeda/src/o_circle_basic.c | 71 +++++++----------------
2 files changed, 43 insertions(+), 158 deletions(-)
diff --git a/libgeda/src/o_box_basic.c b/libgeda/src/o_box_basic.c
index 6d6a78e..b7a32f4 100644
--- a/libgeda/src/o_box_basic.c
+++ b/libgeda/src/o_box_basic.c
@@ -1302,11 +1302,12 @@ void o_box_print_hatch(TOPLEVEL *toplevel, FILE *fp,
int angle2, int pitch2,
int origin_x, int origin_y)
{
- int x3, y3, x4, y4;
- double cos_a_, sin_a_;
- double x0, y0, r;
- double x1, y1, x2, y2;
- double amin, amax, a[4], min1, min2, max1, max2;
+ BOX box;
+ gint index;
+ GArray *lines;
+
+ g_return_if_fail(toplevel != NULL);
+ g_return_if_fail(fp != NULL);
if (toplevel->print_color) {
f_print_set_color(fp, color);
@@ -1315,114 +1316,25 @@ void o_box_print_hatch(TOPLEVEL *toplevel, FILE *fp,
/* Avoid printing line widths too small */
if (fill_width <= 1) fill_width = 2;
- /* The cosinus and sinus of <B>angle1</B> are computed once and reused
later. */
- cos_a_ = cos(((double) angle1) * M_PI/180);
- sin_a_ = sin(((double) angle1) * M_PI/180);
+ lines = g_array_new(FALSE, FALSE, sizeof(LINE));
- /*! \note
- * The function considers the smallest circle around the box. Its radius
- * is given by the following relation. Its center is given by the point
- * at the middle of the box horizontally and vertically (intersection of
- * its two diagonals).
- */
- r = sqrt((double) (pow(width, 2) + pow(height, 2))) / 2;
+ box.upper_x = x;
+ box.upper_y = y;
+ box.lower_x = x + width;
+ box.lower_y = y - height; /* Hmmm... */
- /*
- * When drawing a line in a circle there is two intersections. With the
- * previously described circle, these intersections are out of the box.
- * They can be easily calculated, the first by resolution of an equation
- * and the second one by symetry in relation to the vertical axis going
- * through the center of the circle.
- *
- * These two points are then rotated of angle <B>angle1</B> using the matrix
- * previously mentioned.
- */
- y0 = 0;
- while(y0 < r) {
- x0 = pow(r, 2) - pow(y0, 2);
- x0 = sqrt(x0);
-
- x1 = (x0*cos_a_ - y0*sin_a_);
- y1 = (x0*sin_a_ + y0*cos_a_);
- x2 = ((-x0)*cos_a_ - y0*sin_a_);
- y2 = ((-x0)*sin_a_ + y0*cos_a_);
-
- /*
- * It now parametrizes the segment : first intersection is given the
- * value of 0 and the second is given the value of 1. The four values for
- * each intersection of the segment and the four sides (vertical or
- * horizontal) of the box are given by the following relations :
- */
- if((int) (x2 - x1) != 0) {
- a[0] = ((-width/2) - x1) / (x2 - x1);
- a[1] = ((width/2) - x1) / (x2 - x1);
- } else {
- a[0] = 0; a[1] = 1;
- }
-
- if((int) (y2 - y1) != 0) {
- a[2] = ((-height/2) - y1) / (y2 - y1);
- a[3] = ((height/2) - y1) / (y2 - y1);
- } else {
- a[2] = 0; a[3] = 1;
- }
+ m_hatch_box(&box, angle1, pitch1, lines);
- /*
- * It now has to check which of these four values are for intersections
- * with the sides of the box (some values may be for intersections out of
- * the box). This is made by a min/max function.
- */
- if(a[0] < a[1]) {
- min1 = a[0]; max1 = a[1];
- } else {
- min1 = a[1]; max1 = a[0];
- }
-
- if(a[2] < a[3]) {
- min2 = a[2]; max2 = a[3];
- } else {
- min2 = a[3]; max2 = a[2];
- }
-
- amin = (min1 < min2) ? min2 : min1;
- amin = (amin < 0) ? 0 : amin;
-
- amax = (max1 < max2) ? max1 : max2;
- amax = (amax < 1) ? amax : 1;
-
- /*
- * If the segment really go through the box it prints the line. It also
- * takes the opportunity of the symetry in the box in relation to its
- * center to print the second line at the same time.
- *
- * If there is no intersection of the segment with any of the sides, then
- * there is no need to continue : there would be no more segment in the
- * box to print.
- */
- if((amax > amin) && (amax != 1) && (amin != 0)) {
- /* There is intersection between the line and the box edges */
- x3 = (int) (x1 + amin*(x2 - x1));
- y3 = (int) (y1 + amin*(y2 - y1));
-
- x4 = (int) (x1 + amax*(x2 - x1));
- y4 = (int) (y1 + amax*(y2 - y1));
-
- fprintf(fp,"%d %d %d %d %d line\n",
- x3 + (x + width/2), y3 + (y - height/2),
- x4 + (x + width/2), y4 + (y - height/2),
- fill_width);
-
- fprintf(fp,"%d %d %d %d %d line\n",
- -x3 + (x + width/2), -y3 + (y - height/2),
- -x4 + (x + width/2), -y4 + (y - height/2),
- fill_width);
-
- } else {
- break;
- }
-
- y0 = y0 + pitch1;
+ for(index=0; index<lines->len; index++) {
+ LINE *line = &g_array_index(lines, LINE, index);
+
+ fprintf(fp,"%d %d %d %d %d line\n",
+ line->x[0], line->y[0],
+ line->x[1], line->y[1],
+ fill_width);
}
+
+ g_array_free(lines, TRUE);
}
/*! \brief Calculates the distance between the given point and the closest
diff --git a/libgeda/src/o_circle_basic.c b/libgeda/src/o_circle_basic.c
index 503060a..f78b101 100644
--- a/libgeda/src/o_circle_basic.c
+++ b/libgeda/src/o_circle_basic.c
@@ -1059,65 +1059,38 @@ void o_circle_print_hatch(TOPLEVEL *toplevel, FILE *fp,
int angle2, int pitch2,
int origin_x, int origin_y)
{
- double x0, y0, x1, y1, x2, y2;
- double cos_a_, sin_a_;
+ CIRCLE circle;
+ gint index;
+ GArray *lines;
+
+ g_return_if_fail(toplevel != NULL);
+ g_return_if_fail(fp != NULL);
if (toplevel->print_color) {
f_print_set_color(fp, color);
}
- /*
- * The values of the cosinus and sinus of the angle
- * <B>angle1</B> are calculated for future usage (repetitive).
- */
- cos_a_ = cos(((double) angle1) * M_PI/180);
- sin_a_ = sin(((double) angle1) * M_PI/180);
+ /* Avoid printing line widths too small */
+ if (fill_width <= 1) fill_width = 2;
- /*
- * When printing a line in a circle there is two intersections.
- * It looks for the coordinates of one of these points when the
- * line is horizontal. The second one can be easily obtained by
- * symmetry in relation to the vertical axis going through the
- * centre of the circle.
- *
- * These two points are therefore rotated of angle <B>angle1</B>
- * using the elements previously computed.
- *
- * The corresponding line can be printed providing that the
- * coordinates are rounded.
- *
- * These operations are repeated for every horizontal line that
- * can fit in the upper half of the circle (using and incrementing
- * the variable #y0).
- */
- y0 = 0;
- while(y0 < (double) radius) {
- x0 = pow((double) radius, 2) - pow(y0, 2);
- x0 = sqrt(x0);
+ lines = g_array_new(FALSE, FALSE, sizeof(LINE));
- x1 = (x0*cos_a_ - y0*sin_a_) + x;
- y1 = y + (x0*sin_a_ + y0*cos_a_);
- x2 = ((-x0)*cos_a_ - y0*sin_a_) + x;
- y2 = y + ((-x0)*sin_a_ + y0*cos_a_);
+ circle.center_x = x;
+ circle.center_y = y;
+ circle.radius = radius;
- fprintf(fp, "%d %d %d %d %d line\n",
- (int) x1, (int) y1, (int) x2, (int) y2, fill_width);
+ m_hatch_circle(&circle, angle1, pitch1, lines);
- /*
- * The function uses the symetry in relation to the centre of the
- * circle. It avoid repetitive computation for the second half of
- * the surface of the circle.
- */
- x1 = x + (x0*cos_a_ - (-y0)*sin_a_);
- y1 = y + (x0*sin_a_ + (-y0)*cos_a_);
- x2 = x + ((-x0)*cos_a_ - (-y0)*sin_a_);
- y2 = y + ((-x0)*sin_a_ + (-y0)*cos_a_);
-
- fprintf(fp, "%d %d %d %d %d line\n",
- (int) x1, (int) y1, (int) x2, (int) y2, fill_width);
-
- y0 = y0 + pitch1;
+ for(index=0; index<lines->len; index++) {
+ LINE *line = &g_array_index(lines, LINE, index);
+
+ fprintf(fp,"%d %d %d %d %d line\n",
+ line->x[0], line->y[0],
+ line->x[1], line->y[1],
+ fill_width);
}
+
+ g_array_free(lines, TRUE);
}
/*! \brief Calculates the distance between the given point and the closest
--
1.5.4.3
_______________________________________________
geda-dev mailing list
[email protected]
http://www.seul.org/cgi-bin/mailman/listinfo/geda-dev