Opened 21 years ago
Closed 21 years ago
#445 closed defect (fixed)
Outlinecolor problem in label for RGB outputformat
Reported by: | Owned by: | warmerdam | |
---|---|---|---|
Priority: | high | Milestone: | |
Component: | GDAL Support | Version: | 4.0 |
Severity: | normal | Keywords: | |
Cc: | claude.philipona@… |
Description
There is a bug when OUTLINECOLOR is set with truetype label in RGB OUTPUTFORMAT (jpeg/png24). There outline appears as "square" instaed as "line" around the letters label. All the where made with a simple call to a mapfile, using Mapserver4.0/PHPMapscript. You'll find the mapfile at the end of this message. GD 2.0.15 Freetype 2.1.5 Gdal 1.1.9 Result with IMAGETYPE png (8bit), everything is ok, the outline is present: http://www.camptocamp.com/~claude/mapserver/test_label_png.png Result with IMAGETYPE png24 (24bit), no outlines, but square: http://www.camptocamp.com/~claude/mapserver/test_label_png24.png Result with IMAGETYPE jpeg (24bit) same as png 24 (squares instead of outlines): http://www.camptocamp.com/~claude/mapserver/test_label_jpg.jpg Then I tried several configuration: When I set POSTLABELCACHE ON and TRANSPARENCY 100 on the layer, the OUTLINES are ok, but now (of course) label collision occurs: http://www.camptocamp.com/~claude/mapserver/test_label__post_label_cache_transpa rency_100_png24.png With POSTLABELCACHE ON or TRANSPARENCY 100 settings alone, the outlines are not set properly either: http://www.camptocamp.com/~claude/mapserver/test_label_transparency_100_png24.pn g http://www.camptocamp.com/~claude/mapserver/test_label__post_label_cache_png24.p ng This behaviour is quite annoying, because it is apperently impossible to have nice OUTLINES in RGB formats without POSTLABELCACHE ON and TRANSPARENCY 100, and often we don't want to use these two settings becaus of the side effect. Test mapfile: NAME TEST STATUS ON SIZE 600 450 SYMBOLSET "symbols_1.sym" EXTENT 532500 152180 534340 152880 UNITS METERS SHAPEPATH "../shapes" TRANSPARENT OFF IMAGETYPE png24 IMAGECOLOR 210 190 190 FONTSET "etc/fonts.txt" WEB MINSCALE 0 MAXSCALE 40000 IMAGEPATH "/var/www/test2/htdocs/tmp/" IMAGEURL "/test2/tmp/" END # WEB LAYER NAME buildings TYPE POLYGON STATUS ON DATA "buildings" TRANSPARENCY 60 CLASS NAME "BAT" STYLE COLOR 50 200 50 OUTLINECOLOR 152 227 152 SYMBOL 0 SIZE 1 END END END LAYER NAME "roads_label" TYPE ANNOTATION STATUS ON DATA "roads_label.shp" LABELITEM "Nom" #POSTLABELCACHE ON #TRANSPARENCY 100 CLASS LABEL TYPE truetype FONT "arial" SIZE 10 MINDISTANCE 300 ANTIALIAS TRUE POSITION cc ANGLE AUTO COLOR 100 100 100 OUTLINECOLOR 230 230 230 END END END END # Mapfile
Change History (3)
comment:2 by , 21 years ago
To: support@boutell.com Hi, Support contract: #30723 I am trying to use gdImageStringFT() to draw into a truecolor gdImage. The problem is that the background areas of the text are being filled in when we should see the underlying text through them. An example of the results not working: http://www.camptocamp.com/~claude/mapserver/test_label_png24.png Working properly: http://www.camptocamp.com/~claude/mapserver/test_label_png.png Tracking through, the problem seems to be in gdft_draw_bitmap(), used to burn the greyscale bitmap that came from freetype into the 24bit image. In the 24bit case, level comes out of this as 0 for portions of the bitmap that are background: if (bitmap.pixel_mode == ft_pixel_mode_grays) { /* * Scale to 128 levels of alpha for gd use. * alpha 0 is opacity, so be sure to invert at the end */ level = (bitmap.buffer[pc] * gdAlphaMax / (bitmap.num_grays - 1)); } Later level is inverted: level = gdAlphaMax - level; Then we get to this: if (im->alphaBlendingFlag) { *tpixel = gdAlphaBlend (*tpixel, (level << 24) + (fg & 0xFFFFFF)); } else { *tpixel = (level << 24) + (fg & 0xFFFFFF); } If alpha blending is turned on, the level causes the overlay to be treated as transparent and no change is made (good). But if alphablending is turned off, the output pixel is replaced by the input value even though the input pixel is trasparent. I *think* this is an error, but I could be mixed up about what gdft_bitmap_draw() is really intended to do. My perception is that the function should not copy transparent pixels to the output bitmap. If we look through the 8bit (not truecolor) case below we see this test: if (tc_key.pixel > 0) /* if not background */ basically, background pixels are not copied to the output. I think similar logic should be placed in the truecolor case. Locally I patched things to look like this, and it worked in my case. I am not completely confident this is the right solution though (and it doesn't address the ft_pixel_mode_mono case). if (bitmap.pixel_mode == ft_pixel_mode_grays) { /* * Scale to 128 levels of alpha for gd use. * alpha 0 is opacity, so be sure to invert at the end */ level = (bitmap.buffer[pc] * gdAlphaMax / (bitmap.num_grays - 1)); if( level == 0 ) continue; } For my problem I will experiment with turning on alpha blending as I think that is what I would want anyways, but I would like you to consider patching gd for the 2.0.16 release. Best regards, -- ---------------------------------------+-------------------------------------- I set the clouds in motion - turn up | Frank Warmerdam, warmerdam@pobox.com light and sound - activate the windows | http://pobox.com/~warmerdam and watch the world go round - Rush | Geospatial Programmer for Rent
comment:3 by , 21 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
I have discovered that the alpha blending flag on the gdImage was not being set till after the outlining had been done. While I have submitted a bug report to the GD maintainer, it seems that practically speaking, the MapServer solution is to move the alpha blending enable call up before the outline draws. In my test map this seems to have resolved the problem. Please rebuild from CVS (you need mapgd.c:1.47) and see if the problem is resolved. Please re-open if the problem persists.
Note:
See TracTickets
for help on using tickets.