Bug 16216

Summary: Fill don't work properly
Product: cairo Reporter: marco <marcofal>
Component: xlib backendAssignee: Carl Worth <cworth>
Status: RESOLVED NOTABUG QA Contact: cairo-bugs mailing list <cairo-bugs>
Severity: minor    
Priority: medium    
Version: 1.4.14   
Hardware: x86 (IA32)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Attachments: Screenshot of strange fill behavior
photo of lcd rendering

Description marco 2008-06-03 00:32:00 UTC
Hi,
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...

marco

/*****************************************************************************/

#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.

-Carl
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

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

marco
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
Hi,
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.

marco
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.