Skip to content

Commit 7005f92

Browse files
author
csaba
committed
Fix for [971a266013]: Xlib emulation for macOS causes many visual artifacts.
2 parents bb8b09c + 14f1e74 commit 7005f92

1 file changed

Lines changed: 122 additions & 36 deletions

File tree

macosx/tkMacOSXDraw.c

Lines changed: 122 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -391,34 +391,65 @@ XDrawLines(
391391
{
392392
MacDrawable *macWin = (MacDrawable *)d;
393393
TkMacOSXDrawingContext dc;
394-
int i, lw = gc->line_width;
395394

396-
if (npoints < 2) {
395+
if (npoints < 2 || (mode != CoordModeOrigin && mode != CoordModePrevious)) {
397396
return BadValue;
398397
}
399398

400399
LastKnownRequestProcessed(display)++;
401400
if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
402401
return BadDrawable;
403402
}
403+
404404
if (dc.context) {
405-
double prevx, prevy;
406-
double o = (lw % 2) ? .5 : 0;
405+
double o = (gc->line_width % 2) ? .5 : 0;
406+
short x0 = points[0].x, y0 = points[0].y;
407+
short x1 = (mode == CoordModeOrigin) ? points[1].x : x0 + points[1].x;
408+
short y1 = (mode == CoordModeOrigin) ? points[1].y : y0 + points[1].y;
409+
double prevx = macWin->xOff + x0 + o, prevy = macWin->yOff + y0 + o;
410+
int i;
407411

408412
CGContextBeginPath(dc.context);
409-
prevx = macWin->xOff + points[0].x + o;
410-
prevy = macWin->yOff + points[0].y + o;
413+
if (y1 == y0) { /* horiz. line */
414+
if (x0 <= x1) {
415+
prevx = macWin->xOff + x0;
416+
} else {
417+
prevx = macWin->xOff + x0 + 1;
418+
}
419+
} else if (x1 == x0) { /* vert. line */
420+
if (y0 <= y1) {
421+
prevy = macWin->yOff + y0;
422+
} else {
423+
prevy = macWin->yOff + y0 + 1;
424+
}
425+
}
411426
CGContextMoveToPoint(dc.context, prevx, prevy);
427+
412428
for (i = 1; i < npoints; i++) {
413-
if (mode == CoordModeOrigin) {
414-
CGContextAddLineToPoint(dc.context,
415-
macWin->xOff + points[i].x + o,
416-
macWin->yOff + points[i].y + o);
417-
} else {
418-
prevx += points[i].x;
419-
prevy += points[i].y;
420-
CGContextAddLineToPoint(dc.context, prevx, prevy);
429+
double nextx, nexty;
430+
431+
x1 = (mode == CoordModeOrigin) ? points[i].x : x0 + points[i].x;
432+
y1 = (mode == CoordModeOrigin) ? points[i].y : y0 + points[i].y;
433+
nextx = macWin->xOff + x1 + o;
434+
nexty = macWin->yOff + y1 + o;
435+
436+
if (i == npoints-1) {
437+
if (y1 == y0) { /* horiz. line */
438+
if (x0 <= x1) {
439+
nextx = macWin->xOff + x1 + 1;
440+
} else {
441+
nextx = macWin->xOff + x1;
442+
}
443+
} else if (x1 == x0) { /* vert. line */
444+
if (y0 <= y1) {
445+
nexty = macWin->yOff + y1 + 1;
446+
} else {
447+
nexty = macWin->yOff + y1;
448+
}
449+
}
421450
}
451+
CGContextAddLineToPoint(dc.context, nextx, nexty);
452+
x0 = x1; y0 = y1;
422453
}
423454

424455
/*
@@ -427,8 +458,7 @@ XDrawLines(
427458
* this needs telling CoreGraphics that the path is closed.
428459
*/
429460

430-
if ((points[0].x == points[npoints-1].x) &&
431-
(points[0].y == points[npoints-1].y)) {
461+
if (points[0].x == x1 && points[0].y == y1) {
432462
CGContextClosePath(dc.context);
433463
}
434464
CGContextStrokePath(dc.context);
@@ -463,23 +493,43 @@ XDrawSegments(
463493
{
464494
MacDrawable *macWin = (MacDrawable *)d;
465495
TkMacOSXDrawingContext dc;
466-
int i, lw = gc->line_width;
467496

468497
LastKnownRequestProcessed(display)++;
469498
if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
470499
return BadDrawable;
471500
}
501+
472502
if (dc.context) {
473-
double o = (lw % 2) ? .5 : 0;
503+
int i;
504+
double o = (gc->line_width % 2) ? .5 : 0;
474505

475506
for (i = 0; i < nsegments; i++) {
507+
double prevx = macWin->xOff + segments[i].x1 + o;
508+
double prevy = macWin->yOff + segments[i].y1 + o;
509+
double nextx = macWin->xOff + segments[i].x2 + o;
510+
double nexty = macWin->yOff + segments[i].y2 + o;
511+
512+
if (segments[i].y2 == segments[i].y1) { /* horiz. line */
513+
if (segments[i].x1 <= segments[i].x2) {
514+
prevx = macWin->xOff + segments[i].x1;
515+
nextx = macWin->xOff + segments[i].x2 + 1;
516+
} else {
517+
prevx = macWin->xOff + segments[i].x1 + 1;
518+
nextx = macWin->xOff + segments[i].x2;
519+
}
520+
} else if (segments[i].x2 == segments[i].x1) { /* vert. line */
521+
if (segments[i].y1 <= segments[i].y2) {
522+
prevy = macWin->yOff + segments[i].y1;
523+
nexty = macWin->yOff + segments[i].y2 + 1;
524+
} else {
525+
prevy = macWin->yOff + segments[i].y1 + 1;
526+
nexty = macWin->yOff + segments[i].y2;
527+
}
528+
}
529+
476530
CGContextBeginPath(dc.context);
477-
CGContextMoveToPoint(dc.context,
478-
macWin->xOff + segments[i].x1 + o,
479-
macWin->yOff + segments[i].y1 + o);
480-
CGContextAddLineToPoint(dc.context,
481-
macWin->xOff + segments[i].x2 + o,
482-
macWin->yOff + segments[i].y2 + o);
531+
CGContextMoveToPoint(dc.context, prevx, prevy);
532+
CGContextAddLineToPoint(dc.context, nextx, nexty);
483533
CGContextStrokePath(dc.context);
484534
}
485535
}
@@ -515,31 +565,67 @@ XFillPolygon(
515565
{
516566
MacDrawable *macWin = (MacDrawable *)d;
517567
TkMacOSXDrawingContext dc;
518-
int i;
568+
569+
if (npoints < 2 || (mode != CoordModeOrigin && mode != CoordModePrevious)) {
570+
return BadValue;
571+
}
519572

520573
LastKnownRequestProcessed(display)++;
521574
if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
522575
return BadDrawable;
523576
}
577+
524578
if (dc.context) {
525-
double prevx, prevy;
526579
double o = (gc->line_width % 2) ? .5 : 0;
580+
short x0 = points[0].x, y0 = points[0].y;
581+
short x1 = (mode == CoordModeOrigin) ? points[1].x : x0 + points[1].x;
582+
short y1 = (mode == CoordModeOrigin) ? points[1].y : y0 + points[1].y;
583+
double prevx = macWin->xOff + x0 + o, prevy = macWin->yOff + y0 + o;
584+
int i;
527585

528586
CGContextBeginPath(dc.context);
529-
prevx = macWin->xOff + points[0].x + o;
530-
prevy = macWin->yOff + points[0].y + o;
587+
if (y1 == y0) { /* horiz. line */
588+
if (x0 <= x1) {
589+
prevx = macWin->xOff + x0;
590+
} else {
591+
prevx = macWin->xOff + x0 + 1;
592+
}
593+
} else if (x1 == x0) { /* vert. line */
594+
if (y0 <= y1) {
595+
prevy = macWin->yOff + y0;
596+
} else {
597+
prevy = macWin->yOff + y0 + 1;
598+
}
599+
}
531600
CGContextMoveToPoint(dc.context, prevx, prevy);
601+
532602
for (i = 1; i < npoints; i++) {
533-
if (mode == CoordModeOrigin) {
534-
CGContextAddLineToPoint(dc.context,
535-
macWin->xOff + points[i].x + o,
536-
macWin->yOff + points[i].y + o);
537-
} else {
538-
prevx += points[i].x;
539-
prevy += points[i].y;
540-
CGContextAddLineToPoint(dc.context, prevx, prevy);
603+
double nextx, nexty;
604+
605+
x1 = (mode == CoordModeOrigin) ? points[i].x : x0 + points[i].x;
606+
y1 = (mode == CoordModeOrigin) ? points[i].y : y0 + points[i].y;
607+
nextx = macWin->xOff + x1 + o;
608+
nexty = macWin->yOff + y1 + o;
609+
610+
if (i == npoints-1) {
611+
if (y1 == y0) { /* horiz. line */
612+
if (x0 <= x1) {
613+
nextx = macWin->xOff + x1 + 1;
614+
} else {
615+
nextx = macWin->xOff + x1;
616+
}
617+
} else if (x1 == x0) { /* vert. line */
618+
if (y0 <= y1) {
619+
nexty = macWin->yOff + y1 + 1;
620+
} else {
621+
nexty = macWin->yOff + y1;
622+
}
623+
}
541624
}
625+
CGContextAddLineToPoint(dc.context, nextx, nexty);
626+
x0 = x1; y0 = y1;
542627
}
628+
543629
(gc->fill_rule == EvenOddRule)
544630
? CGContextEOFillPath(dc.context)
545631
: CGContextFillPath(dc.context);

0 commit comments

Comments
 (0)