Text gets clipped incorrectly by WRasterImage-gm drawText in some cases, e.g. when rendering WCartesianChart titles
With some fonts and vertical alignments, attempting to drawText() with a font size close to the size of the specified rectangle can result in clipping of the text. In particular, this can occur with the descenders of titles on WCartesianCharts when using the WRasterImage-gm paint device.
I encountered the issue while exporting a WCartesianChart as a PNG, but it should also be possible to observe the descender clipping with the charts.wt "Category Chart" sample by setting a title with descenders and modifying the chart to use RenderMethod::PngImage.
Attached are two sample apps that may be helpful with this issue. The first shows a layout with three WCartesianCharts -- one for each RenderMethod. The PngImage (in the center) should appear with clipped descenders.
The second example demonstrates the clipping issue with various combinations of RenderMethod and vertical alignment.
Also, attached, is a patch for your review that seems to help in limited testing. Although the patch is in FontSupportPango.C, I believe the only impact is to on WRasterImage-gm.C drawText() -- you may want to verify this. Additional notes are on the patch.
Testing was done with Wt version 4.5.0-rc1-31-gb592bf5e on Linux with Pango and GraphicsMagick.
Updated by Korneel Dumon over 1 year ago
- Status changed from New to InProgress
Your change certainly seems to make things consistent. Although there are some letters which require this extra ascender space (like Å), it seems that they also get clipped in canvas. Canvas is using the HTML textBaseline property to align things at the top, so I think it's valid to try and be consistent with this.
Updated by Bruce Toll over 1 year ago
Before submitting this patch, I was using a crude workaround in WCartesianChart that set the drawText rectangle height to 1.5 the font's sizeLength and reduced the padding. The 1.5 was based on similar code in WCartesian3DChart.C for initTitle() and WCartesianChart.C renderLegend(). It worked for my needs, but I ran into issues testing with the charts.wt example and it seemed like the wrong approach since the other paint devices didn't clip descenders.
Reflecting on your comment, it seems the actual problem is that a font's sizeLength is not sufficient for the drawText rectangle and that the existing Top alignment code in RasterImage-gm may actually be more correct than the other paint devices. Still, it would be significantly more work to modify (and test) Top alignment behavior in the other paint devices and it would likely present issues with backwards compatibility.
Updated by Roel Standaert about 1 year ago
The clipping is because Pango's bitmap to paint on is not big enough, so we made the bitmap bigger (we just took 50% in every direction, which is not the perfect solution, but it's an improvement).
There does indeed also seem to be an issue with Pango not drawing the text in the same place as SVG or
<canvas> would. Maybe that's something that's addressed by your patch...