Bug 16216 - Fill don't work properly
Summary: Fill don't work properly
Alias: None
Product: cairo
Classification: Unclassified
Component: xlib backend (show other bugs)
Version: 1.4.14
Hardware: x86 (IA32) Linux (All)
: medium minor
Assignee: Carl Worth
QA Contact: cairo-bugs mailing list
Depends on:
Reported: 2008-06-03 00:32 UTC by marco
Modified: 2008-10-01 09:58 UTC (History)
0 users

See Also:
i915 platform:
i915 features:

Screenshot of strange fill behavior (11.52 KB, image/png)
2008-06-03 12:04 UTC, marco
photo of lcd rendering (65.45 KB, image/jpeg)
2008-06-03 12:36 UTC, Behdad Esfahbod

Description marco 2008-06-03 00:32:00 UTC
compile and run the program below. Why the left ellipses aren't properly filled ?
I tested with cairo 1.4.12, 1.4.14 on gentoo and cairo 1.4.2 on redhat 5, same output.
It is very strange...



#include <gtk/gtk.h>
#include <cairo.h>
#include <math.h>

#define RX  50
#define RY  40

static void 
make_ellipse (cairo_t *cr, double cx, double cy, double rx, double ry)
  cairo_new_path (cr);
  cairo_save (cr);
  cairo_translate (cr, cx, cy);
  cairo_scale (cr, rx, ry);
  cairo_arc (cr, 0.0, 0.0, 1.0, 0.0, 2.0 * M_PI);
  cairo_restore (cr);

static gboolean
expose (GtkWidget *widget, GdkEventExpose *event, gpointer data)
  cairo_t *cr;
  cr = gdk_cairo_create (widget->window);

  cairo_rectangle (cr, 0, 0 , event->area.width, event->area.height / 2);
  cairo_set_source_rgb (cr, 0, 0, 0);
  cairo_fill (cr);
  cairo_rectangle (cr, 0, event->area.height / 2 , event->area.width, event->area.height / 2);
  cairo_set_source_rgb (cr, 1, 1, 1);
  cairo_fill (cr);
  cairo_set_line_width (cr, 4.0);
  make_ellipse (cr, 100, 100, RX, RY);
  cairo_set_source_rgb (cr, 1, 0, 0);
  cairo_fill_preserve (cr);
  cairo_set_source_rgb (cr, 0, 0, 1);
  cairo_stroke (cr);      		     

  make_ellipse (cr, 300, 100, RX, RY);
  cairo_set_source_rgb (cr, 1, 0, 0);
  cairo_fill_preserve (cr);
  cairo_set_source_rgb (cr, 1, 1, 0);
  cairo_stroke (cr);      		     

  make_ellipse (cr, 100, 300, RX, RY);
  cairo_set_source_rgb (cr, 1, 0, 0);
  cairo_fill_preserve (cr);
  cairo_set_source_rgb (cr, 0, 0, 1);
  cairo_stroke (cr);      		     

  make_ellipse (cr, 300, 300, RX, RY);
  cairo_set_source_rgb (cr, 1, 0, 0);
  cairo_fill_preserve (cr);
  cairo_set_source_rgb (cr, 1, 1, 0);
  cairo_stroke (cr);      		     

  cairo_destroy (cr);
  return FALSE;

int main (int argc, char *argv[])
  GtkWidget *widget,*window;
  gtk_init (&argc, &argv);
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  g_signal_connect (G_OBJECT (window), "delete_event",
                    G_CALLBACK (gtk_main_quit), NULL);

  widget = gtk_drawing_area_new();
  gtk_widget_set_size_request (widget, 400, 400);
  g_signal_connect (widget, "expose_event",
			              G_CALLBACK (expose), NULL);  
  gtk_container_add (GTK_CONTAINER (window), widget);
  gtk_widget_show_all (GTK_WIDGET(window));

  gtk_main ();
  return 0;
Comment 1 Behdad Esfahbod 2008-06-03 09:00:27 UTC
Works for me with latest cairo and with 1.6.4.  1.4.x is unsupported.
Comment 2 Carl Worth 2008-06-03 11:50:00 UTC
While it's true that 1.4 is unsupported, a simple case like this should work
equally fine in 1.4 and 1.6.

And, in fact, I can't see any difference between the 1.4 and 1.6 behavior
for this case.

So, now, can you give us more information on what you're seeing wrong with
this example?

Here's one guess I have:

Are you viewing the result on an LCD monitor? And do you perceive
a "darkish seam" on the right-side boundary between the red and blue
colors? But no similar dark seam on the left side? And no similar seam
between red and yellow?

If so. Is this darkness not caused by an actual gap of an unlit green
subpixel element in the LCD between the red and blue subpixels? I've
checked the final color values on the left and right sides and they
seem equivalent to me.

Let me know if I'm totally off in my guesswork here.

Comment 3 Behdad Esfahbod 2008-06-03 11:55:24 UTC
Yeah, doesn't help that there's no screenshot of the broken output attached..
Comment 4 marco 2008-06-03 12:04:59 UTC
Created attachment 16892 [details]
Screenshot of strange fill behavior

sorry for my careess, here is the screenshot...

Comment 5 marco 2008-06-03 12:09:45 UTC
Comment on attachment 16892 [details]
Screenshot of strange fill behavior

I use a CRT monitor, at home and at work, the video card is nvidia gf7300, xorg version 7.2 at home, intel 833 and xorg 7.1 at work, with same output.
Comment 6 Behdad Esfahbod 2008-06-03 12:36:51 UTC
Created attachment 16894 [details]
photo of lcd rendering

I took two macro photos of your screenshot on my lcd, at about 17000dpi (resized down to about 4500dpi in the attached image).

The left side shows the left border of the ellipse, with a blue pixel to the left of the red pixel.  The subpixels are "rgBRgb" with capital letters being on and small off.  So, the blue and red regions touch perfectly.

The right side of the image shows the right border of the ellipse, with a red pixel to the left of a blue pixel.  Here the subpixels are "RgbrgB".  You can see that there are 4 off subpixels between the red and blue regions, showing a visible wider-than-pixel black gap.

To "fix" this we need to go as far as doing subpixel rendering of all the graphics.  Nothing impossible, but low prio and not on the horizon right now.  (the correct rendering will offset all the graphics by 1/3 pixel and render again, for each color component...)

The fact that you use CRT doesn't make much difference.  I know because I have photographed CRTs recently too, and the subpixel structure of all modern (say, last fifteen years) CRTs is the same as modern LCDs.

Hope that helps.
Comment 7 marco 2008-06-03 12:49:30 UTC
as far as I tested this problem happens only with blue & red. Really is not a problem, cairo is great anyway.
Thanks for yours attention.

Comment 8 Behdad Esfahbod 2008-06-03 12:54:29 UTC
Sure, only happens with red and blue because those are on the sides of the subpixel.  Green is in the middle so doesn't have as much problem.  Green is also more luminous than both of red and blue to the eye.

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.