New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Text halo not correctly rendered after Cairo scaling #585

Closed
artemp opened this Issue Oct 11, 2011 · 13 comments

Comments

Projects
None yet
7 participants
@artemp
Member

artemp commented Oct 11, 2011

In MapOSMatic, we are currently working on a new version of our map rendering engine (still based on Mapnik, of course ;-). We are running into a weird issue with the halo_radius attribute of the TextSymbolizer. It appears the halo is not properly rendered across Cairo scaling, which we didn't do before.

Now, we tell Mapnik to render its map in a "big enough" surface that is then scaled down with Cairo (using CairoContext.scale) to fit into a certain area on the Cairo surface.

I'm not sure how to describe the problem, but the halo (which apparently is a thin white path following the glyph of each letter) doesn't behave properly when rescaled. Attached are screenshots of the PDF and SVG outputs.

We have another problem with text rendering when scaling that only happens when rendering to PNG. I'm not sure if it's related, so I'll create a separate ticket with another screenshot for it.

@artemp

This comment has been minimized.

Show comment
Hide comment
@artemp

artemp Oct 11, 2011

Member

[maxime] If you want to try rendering the same location, the screenshots are from "Saint-Rémy-les-Chevreuse, France" : http://osm.org/go/0BM6kuSl--

Member

artemp commented Oct 11, 2011

[maxime] If you want to try rendering the same location, the screenshots are from "Saint-Rémy-les-Chevreuse, France" : http://osm.org/go/0BM6kuSl--

@artemp

This comment has been minimized.

Show comment
Hide comment
@artemp

artemp Oct 11, 2011

Member

[springmeyer] adding carlos to the cc - I know he encountered something similar with trying to scale cairo fonts internally in mapnik for his gsoc project. the issue was not resolved at the time, but maybe he might can more ideas now.

Member

artemp commented Oct 11, 2011

[springmeyer] adding carlos to the cc - I know he encountered something similar with trying to scale cairo fonts internally in mapnik for his gsoc project. the issue was not resolved at the time, but maybe he might can more ideas now.

@artemp

This comment has been minimized.

Show comment
Hide comment
@artemp

artemp Oct 11, 2011

Member

[thjc] #586 has some further analysis and a patch that should avoid this issue.

Member

artemp commented Oct 11, 2011

[thjc] #586 has some further analysis and a patch that should avoid this issue.

@DavidDecotigny

This comment has been minimized.

Show comment
Hide comment
@DavidDecotigny

DavidDecotigny Feb 20, 2012

With the following stripped-down and updated version of python snippet from http://173.255.217.246:8000/mapnik_trac/ticket/586 :

import os, mapnik2
import cairo

srs = '+init=epsg:32630'
m = mapnik2.Map(300,300,srs)
m.background = mapnik2.Color('gray')

# Populated Places
lyr = mapnik2.Layer('Populated Places')
lyr.srs = srs 
#"+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs"
lyr.datasource = mapnik2.Ogr(file='points.json',layer_by_index=0) 
#mapnik2.Shapefile(file='tests/data/shp/arrows.shp',encoding='latin1')

style = mapnik2.Style()
rule = mapnik2.Rule()

ts = mapnik2.TextSymbolizer(mapnik2.Expression('[label]'),
                           "DejaVu Sans Book",
                           40,
                           mapnik2.Color("blue"))
ts.allow_overlap = True
ts.halo_radius = 4
ts.halo_fill = mapnik2.Color("green")

rule.symbols.append(ts)
style.rules.append(rule)
lyr.styles.append('popplaces')

m.append_style('popplaces', style)
m.layers.append(lyr)
m.zoom_to_box(mapnik2.Box2d(-5,-5,10,10))

# s2 = cairo.SVGSurface('demo.svg', 400,400)
s2 = cairo.PDFSurface('demo.pdf', 400,400)
ctx=cairo.Context(s2)

ctx.save()
ctx.scale(100.0/m.width,100.0/m.height)
mapnik2.render(m, ctx)
ctx.restore()

s2.finish()

With mapnik-2.0.0 and following stripped-down json from previous URL:

{
"type": "FeatureCollection",
"features": [
    { "type": "Feature",     
        "properties": { "x": 0, "y": 0, "label": " " },
        "geometry"  : { "type": "Point", "coordinates": [ 0, 0 ] }
    },
    { "type": "Feature", 
        "properties": { "x": 0, "y": 0, "label": "|" },
        "geometry"  : { "type": "Point", "coordinates": [ 0, 0 ] }
    }, ]  }

Symptoms:

  • halo for 1st feature is rendered correctly (well: empty for above json, but would be rendered Ok with "abs", etc.)
  • halo for 2nd feature is rendered incorrectly ONLY for characters that were not in 1st feature.

And with mapnik git and following json:

{
"type": "FeatureCollection",
"features": [
    { "type": "Feature",     
        "properties": { "x": 0, "y": 0, "label": "xox" },
        "geometry"  : { "type": "Point", "coordinates": [ 0, 0 ] }
    }, ]  }

Symptoms:

  • halo for both "x" is correct
  • halo for "o" is wrong

This tends to indicate there is a cache-like effect going on. But I didn't get very far trying to find the root cause.

I could manage to work around the bug by disabling the cache in mapnik::face_manager<mapnik::freetype_engine>::get_face(std::string const&):

      ///// faces_.insert(make_pair(name,face));

We didn't benchmark, but I'd bet perfs s(t)ink.

Does it ring any bell to anyone?

With the following stripped-down and updated version of python snippet from http://173.255.217.246:8000/mapnik_trac/ticket/586 :

import os, mapnik2
import cairo

srs = '+init=epsg:32630'
m = mapnik2.Map(300,300,srs)
m.background = mapnik2.Color('gray')

# Populated Places
lyr = mapnik2.Layer('Populated Places')
lyr.srs = srs 
#"+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs"
lyr.datasource = mapnik2.Ogr(file='points.json',layer_by_index=0) 
#mapnik2.Shapefile(file='tests/data/shp/arrows.shp',encoding='latin1')

style = mapnik2.Style()
rule = mapnik2.Rule()

ts = mapnik2.TextSymbolizer(mapnik2.Expression('[label]'),
                           "DejaVu Sans Book",
                           40,
                           mapnik2.Color("blue"))
ts.allow_overlap = True
ts.halo_radius = 4
ts.halo_fill = mapnik2.Color("green")

rule.symbols.append(ts)
style.rules.append(rule)
lyr.styles.append('popplaces')

m.append_style('popplaces', style)
m.layers.append(lyr)
m.zoom_to_box(mapnik2.Box2d(-5,-5,10,10))

# s2 = cairo.SVGSurface('demo.svg', 400,400)
s2 = cairo.PDFSurface('demo.pdf', 400,400)
ctx=cairo.Context(s2)

ctx.save()
ctx.scale(100.0/m.width,100.0/m.height)
mapnik2.render(m, ctx)
ctx.restore()

s2.finish()

With mapnik-2.0.0 and following stripped-down json from previous URL:

{
"type": "FeatureCollection",
"features": [
    { "type": "Feature",     
        "properties": { "x": 0, "y": 0, "label": " " },
        "geometry"  : { "type": "Point", "coordinates": [ 0, 0 ] }
    },
    { "type": "Feature", 
        "properties": { "x": 0, "y": 0, "label": "|" },
        "geometry"  : { "type": "Point", "coordinates": [ 0, 0 ] }
    }, ]  }

Symptoms:

  • halo for 1st feature is rendered correctly (well: empty for above json, but would be rendered Ok with "abs", etc.)
  • halo for 2nd feature is rendered incorrectly ONLY for characters that were not in 1st feature.

And with mapnik git and following json:

{
"type": "FeatureCollection",
"features": [
    { "type": "Feature",     
        "properties": { "x": 0, "y": 0, "label": "xox" },
        "geometry"  : { "type": "Point", "coordinates": [ 0, 0 ] }
    }, ]  }

Symptoms:

  • halo for both "x" is correct
  • halo for "o" is wrong

This tends to indicate there is a cache-like effect going on. But I didn't get very far trying to find the root cause.

I could manage to work around the bug by disabling the cache in mapnik::face_manager<mapnik::freetype_engine>::get_face(std::string const&):

      ///// faces_.insert(make_pair(name,face));

We didn't benchmark, but I'd bet perfs s(t)ink.

Does it ring any bell to anyone?

@tpetazzoni

This comment has been minimized.

Show comment
Hide comment
@tpetazzoni

tpetazzoni Mar 25, 2012

Any comments or ideas to help us fixing this problem which is really problematic for MapOSMatic usage of Mapnik?

Any comments or ideas to help us fixing this problem which is really problematic for MapOSMatic usage of Mapnik?

@springmeyer

This comment has been minimized.

Show comment
Hide comment
@springmeyer

springmeyer Sep 6, 2014

Member

Fix for this landed in Mapnik 3.x, closing.

Member

springmeyer commented Sep 6, 2014

Fix for this landed in Mapnik 3.x, closing.

@springmeyer springmeyer closed this Sep 6, 2014

@mapz-sdu

This comment has been minimized.

Show comment
Hide comment
@mapz-sdu

mapz-sdu Oct 19, 2017

Hey, we got exactly the same problem with Mapnik3. Exporting with cairo produces too large halo effects for only some characters.
Did others report the same with Mapnik3 and is there any approach?

Hey, we got exactly the same problem with Mapnik3. Exporting with cairo produces too large halo effects for only some characters.
Did others report the same with Mapnik3 and is there any approach?

@talaj

This comment has been minimized.

Show comment
Hide comment
@talaj

talaj Oct 19, 2017

Member

@mapz-sdu Can you make a minimal test style? I can try to reproduce it with latest Mapnik then.

Member

talaj commented Oct 19, 2017

@mapz-sdu Can you make a minimal test style? I can try to reproduce it with latest Mapnik then.

@mapz-sdu

This comment has been minimized.

Show comment
Hide comment
@mapz-sdu

mapz-sdu Oct 19, 2017

That would be great, thanks!
I made a minimal style with city names from a shp file. I did an export in Zoom Level 5, it is included in the attachment. There you can see the inaccurate halo effect.
We are working with magnacarto to generate the mapnik xml from CartoCSS. I hope that xml is fine for you.
halo_style.zip

That would be great, thanks!
I made a minimal style with city names from a shp file. I did an export in Zoom Level 5, it is included in the attachment. There you can see the inaccurate halo effect.
We are working with magnacarto to generate the mapnik xml from CartoCSS. I hope that xml is fine for you.
halo_style.zip

@talaj

This comment has been minimized.

Show comment
Hide comment
@talaj

talaj Oct 19, 2017

Member

Thanks for the style, but I was not able to reproduce it with latest Mapnik so far.

Here how it looks with AGG rednerer:

magnacarto-style-1044559323-512-256-1 5-agg-reference

Here is PDF from Cairo renderer:

pdf

I was using scale factor 1.5.

Member

talaj commented Oct 19, 2017

Thanks for the style, but I was not able to reproduce it with latest Mapnik so far.

Here how it looks with AGG rednerer:

magnacarto-style-1044559323-512-256-1 5-agg-reference

Here is PDF from Cairo renderer:

pdf

I was using scale factor 1.5.

@mapz-sdu

This comment has been minimized.

Show comment
Hide comment
@mapz-sdu

mapz-sdu Nov 8, 2017

Finally we found the cause of the problem: Scaling with Cairo.
Now, we use a workaround to scale the completed file with an external tool (pdfjam) to achieve everything we want.
Thanks for your immediate help!

mapz-sdu commented Nov 8, 2017

Finally we found the cause of the problem: Scaling with Cairo.
Now, we use a workaround to scale the completed file with an external tool (pdfjam) to achieve everything we want.
Thanks for your immediate help!

@talaj

This comment has been minimized.

Show comment
Hide comment
@talaj

talaj Nov 8, 2017

Member

It's a pity we haven't been able to isolate the problem in Mapnik. Scaling should work with Cairo.

Member

talaj commented Nov 8, 2017

It's a pity we haven't been able to isolate the problem in Mapnik. Scaling should work with Cairo.

@talaj

This comment has been minimized.

Show comment
Hide comment
@talaj

talaj May 22, 2018

Member

I have also encountered this issue and fixed it by updating to the latest Cairo release.

Member

talaj commented May 22, 2018

I have also encountered this issue and fixed it by updating to the latest Cairo release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment