aboutsummaryrefslogtreecommitdiff
path: root/generic/Draw.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/Draw.c')
-rw-r--r--generic/Draw.c59
1 files changed, 46 insertions, 13 deletions
diff --git a/generic/Draw.c b/generic/Draw.c
index 92b22b5..b408446 100644
--- a/generic/Draw.c
+++ b/generic/Draw.c
@@ -993,7 +993,7 @@ ZnRenderPolygonRelief(WidgetInfo *wi,
ZnBool smooth,
ZnPoint *points,
int num_points,
- int line_width)
+ ZnReal line_width)
{
PolygonData pd;
@@ -1013,7 +1013,7 @@ void
ZnRenderPolyline(WidgetInfo *wi,
ZnPoint *points,
int num_points,
- int line_width,
+ ZnReal line_width,
LineStyle line_style,
int cap_style,
int join_style,
@@ -1024,7 +1024,7 @@ ZnRenderPolyline(WidgetInfo *wi,
int num_clips = ZnListSize(wi->clip_stack);
ZnPoint end_points[LINE_END_POINTS];
ZnBool need_rcaps, thin, closed;
- int pass, i, k, m;
+ int pass, num_passes, i, k, m;
ZnPoint c1, c2;
XColor *color;
int alpha;
@@ -1045,14 +1045,41 @@ ZnRenderPolyline(WidgetInfo *wi,
glColor4us(color->red, color->green, color->blue, alpha);
ZnSetLineStyle(wi, line_style);
glLineWidth(line_width);
- glPointSize(line_width);
+ if (thin && (alpha != 65535)) {
+ /*
+ * This makes a special case for transparent lines.
+ * In this case we need to avoid drawing twice a
+ * single pixel. To achieve this we use the stencil
+ * buffer to protect already drawn pixels, unfortunately
+ * using antialiasing write in the stencil even if
+ * the pixel area is not fully covered resulting in
+ * a crack that can't be covered by points later on.
+ * To handle this case we need to disable the stencil
+ * which in turn result in erroneous alpha coverage.
+ *
+ * We have chosen to drawn transparent lines with a
+ * correct coverage but NOT antialiased.
+ */
+ glPointSize(line_width>1?line_width-1:line_width);
+ glDisable(GL_LINE_SMOOTH);
+ }
+ else {
+ glPointSize(line_width);
+ }
- for (pass = 0; pass < 2; pass++) {
- if (pass == 0) {
- GLX_START_CLIP(num_clips, True);
- }
- else {
- GLX_RESTORE_STENCIL(num_clips, False);
+ num_passes = 1;
+ if (alpha != 65535) {
+ num_passes = 2;
+ }
+
+ for (pass = 0; pass < num_passes; pass++) {
+ if (alpha != 65535) {
+ if (pass == 0) {
+ GLX_START_CLIP(num_clips, True);
+ }
+ else {
+ GLX_RESTORE_STENCIL(num_clips, False);
+ }
}
if (first_end) {
GetLineEnd(&points[0], &points[1], line_width, cap_style,
@@ -1092,13 +1119,13 @@ ZnRenderPolyline(WidgetInfo *wi,
glEnd();
}
- if (pass == 0) {
+ /* if (pass == 0) {
GLX_RENDER_CLIPPED();
}
else {
GLX_END_CLIP(num_clips);
- return;
- }
+ break;
+ }*/
need_rcaps = ((line_width > 1) && (cap_style == CapRound));
i = 0;
k = num_points;
@@ -1111,6 +1138,7 @@ ZnRenderPolyline(WidgetInfo *wi,
if ((!need_rcaps && !closed) || last_end) {
k--;
}
+
if (thin) {
glBegin(GL_POINTS);
for ( ; i < k; i++) {
@@ -1135,6 +1163,11 @@ ZnRenderPolyline(WidgetInfo *wi,
}
}
}
+
+ GLX_END_CLIP(num_clips);
+ if (thin) {
+ glEnable(GL_LINE_SMOOTH);
+ }
}