Discussion:
[cairo] Aliased corner with rounded rectangle
Lorenzo
2018-08-08 15:16:13 UTC
Permalink
Hi,

i have a problem with the creation of a rounded rectangle with cairo.

Environment info:

cairo version: 1.14.8-1

OS: linux


A linux client creates a rounded rectangle with the following code:

        let x = 0.0
        let y = 0.0
        let w = Double(size.w)
        let h = Double(size.h)
        let r = 20.0

        logger.verbose("rounded rectangle
x=\(x),y=\(y),w=\(w),h=\(h),r=\(r)")

        cairo_move_to(context, x, y + r)
        cairo_arc(context, x + r, y + r, r, Double.pi, -Double.pi / 2.0)
        cairo_line_to(context, x + w - r, y)
        cairo_arc(context, x + w - r, y + r, r, -Double.pi / 2.0, 0.0)
        cairo_line_to(context, x + w, y + h - r)
        cairo_arc(context, x + w - r, y + h - r, r, 0.0, Double.pi / 2.0)
        cairo_line_to(context, x + r, y + h)
        cairo_arc(context, x + r, y + h - r, r, Double.pi / 2.0, Double.pi)
        cairo_close_path(context)


        cairo_set_source_rgba(context, cl.red, cl.green, cl.blue,
cl.alpha);
        cairo_fill(context)


After the surface fill  i have 2 different operations to be performed:

    - write the png on the disk using
"cairo_surface_write_to_png(surface, "testcairo.png")"

    - display the png with opengl es 3.0 as a texture (done by copy the
surface raw bytes with cairo_image_surface_get_data(surface)

      in a shared memory used by the opengl server program)


Save the image on disk is ok, the image is good.

Display the image as a texture with opengl results in an ugly image:
corners have some black pixels around them.

Why this difference?


I have done some checks:

- data obtained with cairo_image_surface_get_data are the same that the
graphics server loads from the shared memory (checked PixelxPixel) so
the data transfer don't is the problem (checked also any signed/unsigned
byte conversion)

- loading the disk png as a texture instead of loading data from the
shared memory results in a good image with no problems.


My opinion is that the cairo_surface_write_to_png performs an
antialiasing algorithm and accessing raw data bypass it taking the
original image.


Is my opinion correct? If yes, any advice to solve the problem?


Regards,

Lorenzo.
--
cairo mailing list
***@cairographics.org
https://
Bill Spitzak
2018-08-08 17:59:49 UTC
Permalink
You have to change the OpenGL compositing to over the premultiplied image.
I think glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR) is what you need.
Post by Lorenzo
Hi,
i have a problem with the creation of a rounded rectangle with cairo.
cairo version: 1.14.8-1
OS: linux
let x = 0.0
let y = 0.0
let w = Double(size.w)
let h = Double(size.h)
let r = 20.0
logger.verbose("rounded rectangle x=\(x),y=\(y),w=\(w),h=\(h),r=
\(r)")
cairo_move_to(context, x, y + r)
cairo_arc(context, x + r, y + r, r, Double.pi, -Double.pi / 2.0)
cairo_line_to(context, x + w - r, y)
cairo_arc(context, x + w - r, y + r, r, -Double.pi / 2.0, 0.0)
cairo_line_to(context, x + w, y + h - r)
cairo_arc(context, x + w - r, y + h - r, r, 0.0, Double.pi / 2.0)
cairo_line_to(context, x + r, y + h)
cairo_arc(context, x + r, y + h - r, r, Double.pi / 2.0, Double.pi)
cairo_close_path(context)
cairo_set_source_rgba(context, cl.red, cl.green, cl.blue,
cl.alpha);
cairo_fill(context)
- write the png on the disk using "cairo_surface_write_to_png(surface,
"testcairo.png")"
- display the png with opengl es 3.0 as a texture (done by copy the
surface raw bytes with cairo_image_surface_get_data(surface)
in a shared memory used by the opengl server program)
Save the image on disk is ok, the image is good.
corners have some black pixels around them.
Why this difference?
- data obtained with cairo_image_surface_get_data are the same that the
graphics server loads from the shared memory (checked PixelxPixel) so the
data transfer don't is the problem (checked also any signed/unsigned byte
conversion)
- loading the disk png as a texture instead of loading data from the
shared memory results in a good image with no problems.
My opinion is that the cairo_surface_write_to_png performs an antialiasing
algorithm and accessing raw data bypass it taking the original image.
Is my opinion correct? If yes, any advice to solve the problem?
Regards,
Lorenzo.
--
cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
Bill Spitzak
2018-08-08 18:00:22 UTC
Permalink
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Sorry, I managed to cut & paste the one example I had that did not say
"ALPHA"
Post by Bill Spitzak
You have to change the OpenGL compositing to over the premultiplied image.
I think glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR) is what you need.
Post by Lorenzo
Hi,
i have a problem with the creation of a rounded rectangle with cairo.
cairo version: 1.14.8-1
OS: linux
let x = 0.0
let y = 0.0
let w = Double(size.w)
let h = Double(size.h)
let r = 20.0
logger.verbose("rounded rectangle x=\(x),y=\(y),w=\(w),h=\(h),r=
\(r)")
cairo_move_to(context, x, y + r)
cairo_arc(context, x + r, y + r, r, Double.pi, -Double.pi / 2.0)
cairo_line_to(context, x + w - r, y)
cairo_arc(context, x + w - r, y + r, r, -Double.pi / 2.0, 0.0)
cairo_line_to(context, x + w, y + h - r)
cairo_arc(context, x + w - r, y + h - r, r, 0.0, Double.pi / 2.0)
cairo_line_to(context, x + r, y + h)
cairo_arc(context, x + r, y + h - r, r, Double.pi / 2.0, Double.pi)
cairo_close_path(context)
cairo_set_source_rgba(context, cl.red, cl.green, cl.blue,
cl.alpha);
cairo_fill(context)
- write the png on the disk using "cairo_surface_write_to_png(surface,
"testcairo.png")"
- display the png with opengl es 3.0 as a texture (done by copy the
surface raw bytes with cairo_image_surface_get_data(surface)
in a shared memory used by the opengl server program)
Save the image on disk is ok, the image is good.
corners have some black pixels around them.
Why this difference?
- data obtained with cairo_image_surface_get_data are the same that the
graphics server loads from the shared memory (checked PixelxPixel) so the
data transfer don't is the problem (checked also any signed/unsigned byte
conversion)
- loading the disk png as a texture instead of loading data from the
shared memory results in a good image with no problems.
My opinion is that the cairo_surface_write_to_png performs an
antialiasing algorithm and accessing raw data bypass it taking the original
image.
Is my opinion correct? If yes, any advice to solve the problem?
Regards,
Lorenzo.
--
cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
Lorenzo
2018-08-09 13:07:43 UTC
Permalink
Sorry, by i already have the BlendFunc method.

I initialize my opengl system with this code:

glViewport(0, 0, drm->rect()->w, drm->rect()->h);
glDisable(GL_CULL_FACE);
glEnable(GL_LESS);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);


Lorenzo.
Post by Bill Spitzak
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Sorry, I managed to cut & paste the one example I had that did not say
"ALPHA"
You have to change the OpenGL compositing to over the
premultiplied image. I think glBlendFunc(GL_ONE,
GL_ONE_MINUS_SRC_COLOR) is what you need.
Hi,
i have a problem with the creation of a rounded rectangle with cairo.
cairo version: 1.14.8-1
OS: linux
        let x = 0.0
        let y = 0.0
        let w = Double(size.w)
        let h = Double(size.h)
        let r = 20.0
        logger.verbose("rounded rectangle
x=\(x),y=\(y),w=\(w),h=\(h),r=\(r)")
        cairo_move_to(context, x, y + r)
        cairo_arc(context, x + r, y + r, r, Double.pi,
-Double.pi / 2.0)
        cairo_line_to(context, x + w - r, y)
        cairo_arc(context, x + w - r, y + r, r, -Double.pi /
2.0, 0.0)
        cairo_line_to(context, x + w, y + h - r)
        cairo_arc(context, x + w - r, y + h - r, r, 0.0,
Double.pi / 2.0)
        cairo_line_to(context, x + r, y + h)
        cairo_arc(context, x + r, y + h - r, r, Double.pi /
2.0, Double.pi)
        cairo_close_path(context)
        cairo_set_source_rgba(context, cl.red, cl.green,
cl.blue, cl.alpha);
        cairo_fill(context)
After the surface fill  i have 2 different operations to be
    - write the png on the disk using
"cairo_surface_write_to_png(surface, "testcairo.png")"
    - display the png with opengl es 3.0 as a texture (done by
copy the surface raw bytes with
cairo_image_surface_get_data(surface)
      in a shared memory used by the opengl server program)
Save the image on disk is ok, the image is good.
Display the image as a texture with opengl results in an ugly
image: corners have some black pixels around them.
Why this difference?
- data obtained with cairo_image_surface_get_data are the same
that the graphics server loads from the shared memory (checked
PixelxPixel) so the data transfer don't is the problem
(checked also any signed/unsigned byte conversion)
- loading the disk png as a texture instead of loading data
from the shared memory results in a good image with no problems.
My opinion is that the cairo_surface_write_to_png performs an
antialiasing algorithm and accessing raw data bypass it taking
the original image.
Is my opinion correct? If yes, any advice to solve the problem?
Regards,
Lorenzo.
--
cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
<https://lists.cairographics.org/mailman/listinfo/cairo>
Bill Spitzak
2018-08-09 15:55:44 UTC
Permalink
Though I would not expect it to look as bad as described, you want the
first argument to be GL_ONE, not GL_SRC_ALPHA.
Post by Lorenzo
Sorry, by i already have the BlendFunc method.
glViewport(0, 0, drm->rect()->w, drm->rect()->h);
glDisable(GL_CULL_FACE);
glEnable(GL_LESS);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Lorenzo.
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Sorry, I managed to cut & paste the one example I had that did not say
"ALPHA"
Post by Bill Spitzak
You have to change the OpenGL compositing to over the premultiplied
image. I think glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR) is what you need.
Post by Lorenzo
Hi,
i have a problem with the creation of a rounded rectangle with cairo.
cairo version: 1.14.8-1
OS: linux
let x = 0.0
let y = 0.0
let w = Double(size.w)
let h = Double(size.h)
let r = 20.0
logger.verbose("rounded rectangle x=\(x),y=\(y),w=\(w),h=\(h),r=
\(r)")
cairo_move_to(context, x, y + r)
cairo_arc(context, x + r, y + r, r, Double.pi, -Double.pi / 2.0)
cairo_line_to(context, x + w - r, y)
cairo_arc(context, x + w - r, y + r, r, -Double.pi / 2.0, 0.0)
cairo_line_to(context, x + w, y + h - r)
cairo_arc(context, x + w - r, y + h - r, r, 0.0, Double.pi / 2.0)
cairo_line_to(context, x + r, y + h)
cairo_arc(context, x + r, y + h - r, r, Double.pi / 2.0, Double.pi)
cairo_close_path(context)
cairo_set_source_rgba(context, cl.red, cl.green, cl.blue,
cl.alpha);
cairo_fill(context)
- write the png on the disk using "cairo_surface_write_to_png(surface,
"testcairo.png")"
- display the png with opengl es 3.0 as a texture (done by copy the
surface raw bytes with cairo_image_surface_get_data(surface)
in a shared memory used by the opengl server program)
Save the image on disk is ok, the image is good.
corners have some black pixels around them.
Why this difference?
- data obtained with cairo_image_surface_get_data are the same that the
graphics server loads from the shared memory (checked PixelxPixel) so the
data transfer don't is the problem (checked also any signed/unsigned byte
conversion)
- loading the disk png as a texture instead of loading data from the
shared memory results in a good image with no problems.
My opinion is that the cairo_surface_write_to_png performs an
antialiasing algorithm and accessing raw data bypass it taking the original
image.
Is my opinion correct? If yes, any advice to solve the problem?
Regards,
Lorenzo.
--
cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
Lorenzo
2018-08-10 09:24:53 UTC
Permalink
You can see the image with black  pixel at this url:

https://ibb.co/gbuXrU


This is done using glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Instead, using GL_ONE the image is showing perfectly!


Thank you very much for your help.

Lorenzo
Post by Bill Spitzak
Though I would not expect it to look as bad as described, you want the
first argument to be GL_ONE, not GL_SRC_ALPHA.
Sorry, by i already have the BlendFunc method.
glViewport(0, 0, drm->rect()->w, drm->rect()->h);
glDisable(GL_CULL_FACE);
glEnable(GL_LESS);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Lorenzo.
Post by Bill Spitzak
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Sorry, I managed to cut & paste the one example I had that did
not say "ALPHA"
You have to change the OpenGL compositing to over the
premultiplied image. I think glBlendFunc(GL_ONE,
GL_ONE_MINUS_SRC_COLOR) is what you need.
Hi,
i have a problem with the creation of a rounded rectangle
with cairo.
cairo version: 1.14.8-1
OS: linux
A linux client creates a rounded rectangle with the
        let x = 0.0
        let y = 0.0
        let w = Double(size.w)
        let h = Double(size.h)
        let r = 20.0
        logger.verbose("rounded rectangle
x=\(x),y=\(y),w=\(w),h=\(h),r=\(r)")
        cairo_move_to(context, x, y + r)
        cairo_arc(context, x + r, y + r, r, Double.pi,
-Double.pi / 2.0)
        cairo_line_to(context, x + w - r, y)
        cairo_arc(context, x + w - r, y + r, r,
-Double.pi / 2.0, 0.0)
        cairo_line_to(context, x + w, y + h - r)
        cairo_arc(context, x + w - r, y + h - r, r, 0.0,
Double.pi / 2.0)
        cairo_line_to(context, x + r, y + h)
        cairo_arc(context, x + r, y + h - r, r, Double.pi
/ 2.0, Double.pi)
        cairo_close_path(context)
cairo_set_source_rgba(context, cl.red, cl.green, cl.blue,
cl.alpha);
        cairo_fill(context)
After the surface fill  i have 2 different operations to
    - write the png on the disk using
"cairo_surface_write_to_png(surface, "testcairo.png")"
    - display the png with opengl es 3.0 as a texture
(done by copy the surface raw bytes with
cairo_image_surface_get_data(surface)
      in a shared memory used by the opengl server program)
Save the image on disk is ok, the image is good.
Display the image as a texture with opengl results in an
ugly image: corners have some black pixels around them.
Why this difference?
- data obtained with cairo_image_surface_get_data are the
same that the graphics server loads from the shared
memory (checked PixelxPixel) so the data transfer don't
is the problem (checked also any signed/unsigned byte
conversion)
- loading the disk png as a texture instead of loading
data from the shared memory results in a good image with
no problems.
My opinion is that the cairo_surface_write_to_png
performs an antialiasing algorithm and accessing raw data
bypass it taking the original image.
Is my opinion correct? If yes, any advice to solve the problem?
Regards,
Lorenzo.
--
cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
<https://lists.cairographics.org/mailman/listinfo/cairo>
Loading...