aboutsummaryrefslogtreecommitdiff
path: root/generic/Draw.c
diff options
context:
space:
mode:
authorlecoanet2000-03-09 13:39:37 +0000
committerlecoanet2000-03-09 13:39:37 +0000
commit320e8e0b54d6218191abc5835b4d8cc397a24920 (patch)
tree87d334bba21017357484c9c88d7ecba38c9ac16c /generic/Draw.c
parent188d6923db788c2cb06b485b64697788300f404a (diff)
downloadtkzinc-320e8e0b54d6218191abc5835b4d8cc397a24920.zip
tkzinc-320e8e0b54d6218191abc5835b4d8cc397a24920.tar.gz
tkzinc-320e8e0b54d6218191abc5835b4d8cc397a24920.tar.bz2
tkzinc-320e8e0b54d6218191abc5835b4d8cc397a24920.tar.xz
* Suppression de DrawRectangleRelief.
* Am�lioration de la stabilit� de g�n�ration des faces dans DrawPolygonRelief (il reste des cas pathologiques - plein meme). * Traitement de la lumi�re par DrawPolygonRelief.
Diffstat (limited to 'generic/Draw.c')
-rw-r--r--generic/Draw.c221
1 files changed, 111 insertions, 110 deletions
diff --git a/generic/Draw.c b/generic/Draw.c
index 26d952f..037e745 100644
--- a/generic/Draw.c
+++ b/generic/Draw.c
@@ -311,87 +311,53 @@ DrawLineShape(Display *display,
/*
- **********************************************************************************
- *
- * DrawRectangleRelief --
- * Draw the bevels inside bbox.
- *
- **********************************************************************************
+ * ReliefIndexOfSegment --
*/
-void
-DrawRectangleRelief(WidgetInfo *wi,
- ReliefStyle relief,
- ZnColorGradient gradient,
- XRectangle *bbox,
- unsigned int line_width)
+static long
+ReliefColorOfSegment(ZnReal x1,
+ ZnReal y1,
+ ZnReal x2,
+ ZnReal y2,
+ ReliefStyle relief,
+ ZnColorGradient gradient,
+ WidgetInfo *wi)
{
- XGCValues gc_values;
- XPoint top_points[7];
+ ZnReal angle, angle_step, origin;
+ int color_index, num_colors;
- /*
- * If we haven't enough space to draw, exit.
- */
- if ((bbox->width < 2*line_width) || (bbox->height < 2*line_width)) {
- return;
- }
-
- /*
- * Grooves and ridges are drawn with two recursives calls with
- * half the width of the original one.
- */
- if ((relief == RELIEF_RIDGE) || (relief == RELIEF_GROOVE)) {
- unsigned int new_line_width;
- int offset;
- XRectangle internal_bbox;
-
- new_line_width = line_width/2;
- offset = line_width - new_line_width;
- DrawRectangleRelief(wi,
- (relief==RELIEF_GROOVE)?RELIEF_BEVEL_IN:RELIEF_BEVEL_OUT,
- gradient, bbox, new_line_width);
- internal_bbox = *bbox;
- internal_bbox.x +=offset;
- internal_bbox.y += offset;
- internal_bbox.width -= offset*2;
- internal_bbox.height -= offset*2;
- DrawRectangleRelief(wi,
- (relief==RELIEF_GROOVE)?RELIEF_BEVEL_OUT:RELIEF_BEVEL_IN,
- gradient, &internal_bbox, new_line_width);
- return;
- }
-
- gc_values.fill_style = FillSolid;
+ num_colors = ZnColorGradientSpan(gradient);
+ angle_step = M_PI / (num_colors-1);
+ origin = -(DegreesToRadian(wi->light_angle))-(angle_step/2.0);
if (relief == RELIEF_BEVEL_IN) {
- gc_values.foreground = ZnColorGradientPixel(gradient, wi->win, -1);
+ origin += M_PI;
}
- else {
- gc_values.foreground = ZnColorGradientPixel(gradient, wi->win, 0);
- }
- XChangeGC(wi->dpy, wi->gc, GCFillStyle|GCForeground, &gc_values);
- XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc,
- bbox->x, bbox->y + bbox->height - line_width,
- bbox->width, line_width);
- XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc,
- bbox->x + bbox->width - line_width, bbox->y,
- line_width, bbox->height);
- if (relief == RELIEF_BEVEL_IN) {
- gc_values.foreground = ZnColorGradientPixel(gradient, wi->win, 0);
+ angle = (ProjectionToAngle(y1 - y2, x2 - x1) + M_PI - origin);
+ while (angle < 0.0) {
+ angle += 2*M_PI;
}
- else {
- gc_values.foreground = ZnColorGradientPixel(gradient, wi->win, -1);
+ while (angle > 2*M_PI) {
+ angle -= 2*M_PI;
+ }
+ color_index = (int) (angle/angle_step);
+ if (color_index > num_colors-1) {
+ color_index = 2*(num_colors-1)-color_index;
+ }
+ if ((color_index < 0) || (color_index >= num_colors)) {
+ printf("Color index out of gradient (should not happen).\n");
+ if (color_index < 0) {
+ color_index = 0;
+ }
+ if (color_index >= num_colors) {
+ color_index = num_colors-1;
+ }
}
- XChangeGC(wi->dpy, wi->gc, GCFillStyle|GCForeground, &gc_values);
- top_points[0].x = top_points[1].x = top_points[6].x = bbox->x;
- top_points[0].y = top_points[6].y = bbox->y + bbox->height;
- top_points[1].y = top_points[2].y = bbox->y;
- top_points[2].x = bbox->x + bbox->width;
- top_points[3].x = bbox->x + bbox->width - line_width;
- top_points[3].y = top_points[4].y = bbox->y + line_width;
- top_points[4].x = top_points[5].x = bbox->x + line_width;
- top_points[5].y = bbox->y + bbox->height - line_width;
- XFillPolygon(wi->dpy, wi->draw_buffer, wi->gc, top_points, 7,
- Nonconvex, CoordModeOrigin);
+ /*printf("color index %d(), angle %g(), origin %g\n",
+ color_index,
+ RadianToDegrees(angle),
+ RadianToDegrees(origin));*/
+
+ return ZnColorGradientPixel(gradient, wi->win, color_index);
}
@@ -407,8 +373,8 @@ DoPolygonRelief(ZnPoint *p,
ZnPoint pp1, pp2, new_pp1, new_pp2;
ZnPoint perp, c, shift1, shift2;
ZnPoint bevel_points[4];
- XPoint bevel_xpoints[4];
- ZnBool parallel, closed;
+ XPoint bevel_xpoints[5];
+ ZnBool folded, closed, colinear;
WidgetInfo *wi = NULL;
ReliefStyle relief = 0;
ZnColorGradient gradient = NULL;
@@ -416,7 +382,11 @@ DoPolygonRelief(ZnPoint *p,
double *dist = NULL;
ZnBBox *bbox = NULL;
va_list var;
-
+#if 0
+ ZnBool toggle=True;
+#endif
+ ZnReal dx, dy;
+
va_start(var, what_to_do);
if (what_to_do == POLYGON_RELIEF_DIST) {
pp = va_arg(var, ZnPoint *);
@@ -449,7 +419,8 @@ DoPolygonRelief(ZnPoint *p,
closed = True;
num_points--;
}
-
+ /*printf("num_points=%d(%s)\n\n", num_points, closed?"closed":"");*/
+
/*
* We loop on all vertices of the polygon.
* At each step we try to compute the corresponding border
@@ -480,7 +451,7 @@ DoPolygonRelief(ZnPoint *p,
* process two points). This is why we start at the point before the last
* and then wrap to the first point.
* The algorithm discards any duplicate contiguous points.
- * It makes a special case if two consecutives edges are parallel:
+ * It makes a special case if two consecutives edges are folded:
*
* bevel[1] pp1 pp2 a bevel[2]
* *-----------*--------------*----------*
@@ -494,8 +465,8 @@ DoPolygonRelief(ZnPoint *p,
* ----------*-----------*-------------*
* new_pp1 new_pp2 c
*
- * In such a case we need to compute a, b, corner from pp1, pp2, new_pp1
- * and new_pp2. We compute the perpendicular to p&,p2 through p1, intersect
+ * In such a case we need to compute a, c, corner from pp1, pp2, new_pp1
+ * and new_pp2. We compute the perpendicular to p1,p2 through p1, intersect
* it with pp1,pp2 to obtain a, intersect it with new_pp1, new_pp2 to
* obtain c, shift a,c and intersect it with p1,p2 to obtain corner.
*
@@ -510,7 +481,7 @@ DoPolygonRelief(ZnPoint *p,
i = -2;
p1 = &p[num_points-2];
}
- for (p2 = p1+1; i < num_points; i++, p1 = p2, p2++) {
+ for (p2 = p1+1; i < num_points; i++, p2++) {
/*
* When it is time to wrap, do it
*/
@@ -519,15 +490,18 @@ DoPolygonRelief(ZnPoint *p,
}
/*
- * Skip over duplicate vertices.
+ * Skip over close vertices.
*/
- if ((p2->x == p1->x) && (p2->y == p1->y)) {
+ dx = p2->x - p1->x;
+ dy = p2->y - p1->y;
+ if ((ABS(dx) < 1.0) && (ABS(dy) < 1.0)) {
continue;
}
ShiftLine(p1, p2, line_width, &new_pp1, &new_pp2);
bevel_points[3] = *p1;
- parallel = False;
+ folded = False;
+ colinear = False;
/*
* The first two cases are for `open' polygons. We compute
* a bevel closure that is perpendicular to the path.
@@ -543,14 +517,36 @@ DoPolygonRelief(ZnPoint *p,
IntersectLines(p1, &perp, &pp1, &pp2, &bevel_points[2]);
}
else if (processed_points >= 1) {
- parallel = !IntersectLines(&new_pp1, &new_pp2, &pp1, &pp2, &bevel_points[2]);
- if (parallel) {
+ ZnReal dotp, dist, odx, ody;
+
+ /*
+ * The dot product of the two faces tell if the are
+ * folded or colinear. The
+ */
+ odx = (p1-1)->x - p1->x;
+ ody = (p1-1)->y - p1->y;
+ dotp = odx*dx + ody*dy;
+ dist = LineToPointDist(p1-1, p2, p1);
+ if ((dist < 4.0) && (dotp <= 0)) {
perp.x = p1->x + (p2->y - p1->y);
perp.y = p1->y - (p2->x - p1->x);
- IntersectLines(p1, &perp, &pp1, &pp2, &bevel_points[2]);
- IntersectLines(p1, &perp, &new_pp1, &new_pp2, &c);
- ShiftLine(p1, &perp, line_width, &shift1, &shift2);
- IntersectLines(p1, p2, &shift1, &shift2, &bevel_points[3]);
+ IntersectLines(p1, &perp, &new_pp1, &new_pp2, &bevel_points[2]);
+ colinear = True;
+ }
+ else {
+ folded = !IntersectLines(&new_pp1, &new_pp2, &pp1, &pp2, &bevel_points[2]);
+ folded = folded && (dotp < 0);
+ if (folded) {
+ /*printf("DoPolygonRelief: folded edges detected, %g@%g, %g@%g, %g@%g, %g@%g\n",
+ pp1.x, pp1.y, pp2.x, pp2.y, new_pp1.x, new_pp1.y,
+ new_pp2.x, new_pp2.y);*/
+ perp.x = p1->x + (p2->y - p1->y);
+ perp.y = p1->y - (p2->x - p1->x);
+ IntersectLines(p1, &perp, &pp1, &pp2, &bevel_points[2]);
+ IntersectLines(p1, &perp, &new_pp1, &new_pp2, &c);
+ ShiftLine(p1, &perp, line_width, &shift1, &shift2);
+ IntersectLines(p1, p2, &shift1, &shift2, &bevel_points[3]);
+ }
}
}
@@ -586,41 +582,46 @@ DoPolygonRelief(ZnPoint *p,
}
}
else if (what_to_do == POLYGON_RELIEF_DRAW) {
- ZnReal dx, dy;
- ZnBool light_on_left;
XGCValues gc_values;
-
- dx = bevel_points[3].x - bevel_points[0].x;
- dy = bevel_points[3].y - bevel_points[0].y;
- if (dx > 0.0) {
- light_on_left = (dy <= dx);
- }
- else {
- light_on_left = (dy < dx);
- }
-
+#if 1
+ gc_values.foreground = ReliefColorOfSegment(bevel_points[0].x, bevel_points[0].y,
+ bevel_points[3].x, bevel_points[3].y,
+ relief, gradient, wi);
+#endif
+#if 0
+ gc_values.foreground = toggle ? WhitePixelOfScreen(wi->screen):BlackPixelOfScreen(wi->screen);
+#endif
+#if 0
+ gc_values.foreground = colinear ? WhitePixelOfScreen(wi->screen):BlackPixelOfScreen(wi->screen);
+#endif
+#if 0
+ toggle = !toggle;
+#endif
gc_values.fill_style = FillSolid;
- if (light_on_left ^ (relief == RELIEF_BEVEL_OUT)) {
- gc_values.foreground = ZnColorGradientPixel(gradient, wi->win, -1);
- }
- else {
- gc_values.foreground = ZnColorGradientPixel(gradient, wi->win, 0);
- }
- XChangeGC(wi->dpy, wi->gc, GCFillStyle|GCForeground, &gc_values);
+ gc_values.line_width = 0;
+ XChangeGC(wi->dpy, wi->gc, GCLineWidth|GCFillStyle|GCForeground, &gc_values);
for (j = 0; j < 4; j++) {
bevel_xpoints[j].x = REAL_TO_INT(bevel_points[j].x);
bevel_xpoints[j].y = REAL_TO_INT(bevel_points[j].y);
}
+#if 1
XFillPolygon(wi->dpy, wi->draw_buffer, wi->gc, bevel_xpoints, 4,
Convex, CoordModeOrigin);
+#endif
+#if 0
+ bevel_xpoints[4] = bevel_xpoints[0];
+ XDrawLines(wi->dpy, wi->draw_buffer, wi->gc, bevel_xpoints, 5,
+ CoordModeOrigin);
+#endif
}
}
+ p1 = p2;
pp1 = new_pp1;
pp2 = new_pp2;
bevel_points[0] = bevel_points[3];
- if (parallel) {
+ if (folded) {
bevel_points[1] = c;
}
else if ((processed_points >= 1) || !closed) {