|
From: Andrea A. <aa...@op...> - 2009-05-11 10:52:09
|
Hi all,
making the MapServer/GeoServer performance comparison back in September
2008 Steve Lime made me notice how GeoServer was rendering line widths
and fonts sizes differently than MapServer, and how MapServer was in
fact respecting the SLD standard better than GeoServer in that respect.
In particular, GeoServer was rendering overly thin lines, and smaller
than expected fonts. I've attached to this mail a reference SLD,
the output the streaming renderer is currently producing, and the
expected one.
The thin line is due to an optimization I put while back, before
antialiased rendering was even attempted, that I made optional
in 2.5.x and I'm going to remove in trunk.
The font issue is that SLD specifieds font sizes in pixels, whilst
Java font sizes are specified in points. And points are generally
speaking smaller, so you say 14 in SLD and you get a font that's
10 pixel high.
Now, does anybody of you know of a reliable way to make the font
size conversion? I could not find anything specific online,
but the two following ways seem to work (assuming javaFont
is configured with the font size coming from SLD, and trying
to find a compensation for it).
First way, render a capital M and see how big it really is,
compensate for the difference assuming a linear relationship
between point and pixel size:
float size = ... // get from SLD
// configure java font so that it uses the sld size
float height = (float)
javaFont.layoutGlyphVector(graphics.getFontRenderContext(), new char[]
{'M'}, 0, 1,
java.awt.Font.LAYOUT_RIGHT_TO_LEFT).getVisualBounds().getHeight();
javaFont = javaFont.deriveFont(size / height * size);
What I don't like much about this approach is that it's
assuming the M is going to be representative, and with
symbol fonts it may not be.
Another approach is using intrinsic properties of the
font given by its FontMetric, in particular its
ascent (distance between baseline and top of any
char), too bad the ascent is taking into account eventual
accents placed on top of capital letters...
I noticed that the descent (distance between the
baseline and the bottom of chars such as g,p,q)
is about the same size as the accent area, so the
following works too in practice:
float size = ... // get from SLD
// configure java font so that it uses the sld size
FontMetri metric = // get the font metrics
float height = metric.getAscent() - metric.getDescent()
javaFont = javaFont.deriveFont(size / height * size);
What I don't like much about this approach is that
it's completely empirical, there is nothing in the
Java API confirming it makes any sense.
Anyone with a better solution? I looked around on
the net and in the java font handling APIs but could
not find any other.
Let me know
Cheers
Andrea
--
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.
|