Bug 29356 - Application needs to call both XDrawArc and XFillArc to get symmetrical filled circle.
Summary: Application needs to call both XDrawArc and XFillArc to get symmetrical fille...
Status: RESOLVED MOVED
Alias: None
Product: xorg
Classification: Unclassified
Component: Server/General (show other bugs)
Version: 7.1 (2006.05)
Hardware: x86-64 (AMD64) Linux (All)
: medium minor
Assignee: Xorg Project Team
QA Contact: Xorg Project Team
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-08-02 05:47 UTC by Stef Van Vlierberghe
Modified: 2018-12-13 22:24 UTC (History)
1 user (show)

See Also:
i915 platform:
i915 features:


Attachments
Rendering of drawn and filled circles using code in description. (9.98 KB, image/x-png)
2010-08-02 05:47 UTC, Stef Van Vlierberghe
no flags Details

Description Stef Van Vlierberghe 2010-08-02 05:47:50 UTC
Created attachment 37519 [details]
Rendering of drawn and filled circles using code in description.

There seems to be a bug/feature/limitation (not sure which one applies)
with XFillArc, the small bit of code below illustrates the problem by
using 5 different techniques to show a circle :

1- fill
2- draw
3- draw+fill
4- drap polygon approximated
5- fill polygon approximated

The attachment shows an xmag blow-up of the result, and this clearly
shows that only 2..4 create a result that is both symmetrical around x
and y axis, as one would expect for all "good" renderings of a circle.

The reason why 1 and 5 lack this symmetry has probably to do with the
pixel coordinate system : drawing a line from (0,0) to (l,0) is in fact
equivalent to filling a rectange (0,0), (l+1,0), (l+1,1), (0,1), so the
drawings always show an "offset" toward bottom-right of the drawing one
would get if one could draw infinitely thin lines. [ See Volume 1, Xlib Programming Manual, 6.1.4 "Filling", which only explains this effect when drawing and filling rectangles ]

Somehow this offset creates an asymmetry in the filled polygons that is
not visible in the drawn polygons, but I can't see where this effect is
documented.

What it a least a bit bizarre is that somebody who wants symmetrically
filled circles (i.e. technique 3- draw+fill) needs to send 2
instructions to the server, one to draw and one to fill, while an extra
option (e.g. a parameter fill_quality, similar to the Convex option of
XFillPolygon) would obviously suffice to reduce this overhead. So in case this is not a bug, it is at least a source of unnecessary runtime overheap due to limitations of the API, and a lack of clarity in the documentation. 

static void draw_graphics (void) {
  GC mygc;
  int i,j,x;
  XGCValues values;

  XMapRaised (display, win);

  values.line_width=0;  
  values.line_style=LineSolid;
  values.cap_style=CapRound;
  values.join_style=JoinRound;

  mygc = XCreateGC (display, win, (GCLineWidth|GCLineStyle|GCCapStyle|
GCJoinStyle), &values);
  XSetForeground (display, mygc, BlackPixel (display, screen));
  XSetBackground (display, mygc, WhitePixel (display, screen));
  XClearWindow (display, win);

  x=10;

  for (i=1;i <= 20; i++)
    { int diam = i;
      int space = 3;
      int y = 50;
      XPoint points[33];
      int pt;
      int inner;

      /* 1- fill circle */
      XFillArc (display, win, mygc, x, y, diam, diam, 0, 360 * 64);
      XFlush (display);
      y=y+diam+space;

      /* 2- draw circle */
      XDrawArc (display, win, mygc, x, y, diam, diam, 0, 360 * 64);
      XFlush (display);
      y=y+diam+space;

      /* 3- draw circle with inner fill */

      XDrawArc (display, win, mygc, x, y, diam, diam, 0, 360 * 64);
      XFillArc (display, win, mygc, x, y, diam, diam, 0, 360 * 64);
      XFlush (display);
      y=y+diam+space;

      /* 4- draw approx circle by 32 sided polygon */ 
      for (pt=0;pt<33;pt++)
        {
          points[pt].x=x+diam
+lround(diam/2.0*cos(2*3.14159265358979323844*pt/32.0));
          points[pt].y=y+diam
+lround(diam/2.0*sin(2*3.14159265358979323844*pt/32.0));
         }
      XDrawLines (display, win, mygc, points, 33, CoordModeOrigin);
      XFlush (display);
      y=y+diam+space;

      /* 5- fill approx circle by 32 sided polygon */ 
      for (pt=0;pt<33;pt++)
        {
          points[pt].x=x+diam
+lround(diam/2.0*cos(-2*3.14159265358979323844*pt/32.0));
          points[pt].y=y+diam
+lround(diam/2.0*sin(-2*3.14159265358979323844*pt/32.0));
         }
      XFillPolygon (display, win, mygc, points, 33, Convex,
CoordModeOrigin);
      XFlush (display);
      y=y+diam+space;


      x=x+2*diam+5;
    }

  XFlush (display);
  XFreeGC (display, mygc);
}

I've seen the effect both in Linux Redhat EL5 and Linux Fedora 11 and HP-UX, using 3 different graphics cards and a virtual frame buffer, so it looks like this problem is not specific to OS or graphics hardware.

for reference xdpyinfo shows :
name of display:    :0.0
version number:    11.0
vendor string:    The X.Org Foundation
vendor release number:    70101000
X.Org version: 7.1.1
maximum request size:  262140 bytes
motion buffer size:  256
bitmap unit, bit order, padding:    32, LSBFirst, 32
image byte order:    LSBFirst
number of supported pixmap formats:    7
supported pixmap formats:
    depth 1, bits_per_pixel 1, scanline_pad 32
    depth 4, bits_per_pixel 8, scanline_pad 32
    depth 8, bits_per_pixel 8, scanline_pad 32
    depth 15, bits_per_pixel 16, scanline_pad 32
    depth 16, bits_per_pixel 16, scanline_pad 32
    depth 24, bits_per_pixel 32, scanline_pad 32
    depth 32, bits_per_pixel 32, scanline_pad 32
keycode range:    minimum 8, maximum 255
focus:  window 0x3201beb, revert to Parent
number of extensions:    16
    Composite
    DAMAGE
    GLX
    MIT-SHM
    NV-CONTROL
    NV-GLX
    RANDR
    RENDER
    SECURITY
    VNC-EXTENSION
    XC-APPGROUP
    XFIXES
    XFree86-Bigfont
    XInputExtension
    XKEYBOARD
    XTEST
default screen number:    0
number of screens:    1
Comment 1 GitLab Migration User 2018-12-13 22:24:22 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/xorg/xserver/issues/404.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.