Opened 21 years ago
Closed 21 years ago
#267 closed defect (fixed)
Lines of SIZE > 1 not displayed with 24-bit output (nor with 8-bit with layer transparency set)
Reported by: | Owned by: | warmerdam | |
---|---|---|---|
Priority: | high | Milestone: | |
Component: | GDAL Support | Version: | 4.0 |
Severity: | normal | Keywords: | |
Cc: |
Description
When using 24-bit output, lines with thickness > 1 are not displayed. This also happens with 8-bit output if TRANSPARENCY is set for any of the layers. By "thickness" I mean using the circle symbol and giving it a size value (see roads layer definition below). Any SIZE definition > 1 will result in that class not being displayed. In the example below, the "Paved" class is not displayed. It *is* displayed if I change SIZE from 2 to 1. Figured I should submit this as a new bug since the description of the problem is buried within bug 231. LAYER NAME roads GROUP "BASE DATA" TYPE LINE STATUS DEFAULT DATA road83 CLASSITEM "LEGEND" CLASS NAME "Paved" EXPRESSION /Paved/ #contains "Paved" COLOR 0 0 0 SYMBOL 'circle' SIZE 2 END CLASS NAME "Gravel" EXPRESSION /Gravel/ #contains "Gravel" COLOR 100 100 100 SYMBOL 'circle' SIZE 1 END CLASS NAME "Closed" EXPRESSION /Closed/ #contains "Closed" COLOR 190 190 190 SYMBOL 'circle' SIZE 1 END END LAYER NAME ONP_boundary TYPE POLYGON STATUS DEFAULT DATA onp_bnd_83 TRANSPARENCY 60 #if set, lines of SIZE > 1 not displayed CLASS NAME "ONP boundary" OUTLINECOLOR 0 0 0 COLOR 243 248 245 END END
Change History (7)
comment:2 by , 21 years ago
OK, I have looked into the problem and found a few things. First, please use at least GD 2.0.11, old versions of GD 2.0.x have significant bugs some of which are fixed in 2.0.11. Second, the gdImageBrushApply() function has a bug laying 8bit brushes on true color images ... in particular, the transparent values are generally not recognised properly. While I have emailed Thomas Boutell about this, I don't know if or when a fix will make it into GD. In the meantime, I have tested a change to msDrawLineSymbolGD() to create 24bit brushes instead of 8bit brushes. It looks like this and does solve the problem. if((brush = searchImageCache(symbolset->imagecache, style->symbol, fc, size)) == NULL) { // not in cache, create if( !gdImageTrueColor(img) ) { brush = gdImageCreate(x, y); brush_bc = gdImageColorAllocate(brush,gdImageRed(img,0), gdImageGreen(img, 0), gdImageBlue(img, 0)); gdImageColorTransparent(brush,0); brush_fc = gdImageColorAllocate(brush, style->color.red, style->color.green, style->color.blue); } #if GD2_VERS > 1 else { brush = gdImageCreateTrueColor(x,y); gdImageAlphaBlending( brush, 0 ); gdImageFilledRectangle( brush, 0, 0, x, y, -1 ); brush_bc = -1; brush_fc = gdTrueColor( style->color.red, style->color.green, style->color.blue ); } #endif I have not yet committed this change mainly because it seems there are roughly 10 other places in mapgd.c where similar sorts of changes might be required. The question then is, should I go ahead and try to make these changes everywhere? It will be pretty hard for me to test! It is possible that only the brushes will require the fix ... not too sure, in which case it might only be five or six places to fix. PS. Whatever the solution, I would like to add more tests to the msautotest for these cases when we are finished.
comment:3 by , 21 years ago
I was using GD 2.0.9. Apparently my line thickness problem was related to the recent fixes that went into GD, because upgrading to 2.0.11 solved the problem. Thanks.
comment:4 by , 21 years ago
This is a killer for both GD and us. Can't release 3.7 with the issue seeing as 24-bit output is of great interest. Aside from the pain in the ass factor, I'm wondering if there might be some other benefits to explicitly creating a brush in the matching color depth. Might there be a performance gain in not having the GD code have to do color lookups? What about a brush creation function? Just pass a size, a color depth and a color to make transparent and return a gdImagePtr. At least the code would remain semi-readable and might make moving to something other than GD easier in the future. I assume populating the brush would be unchanged then. We might also need to convert PIXMAP symbols to the appropriate color depth for line and polygon rendering. I like the thought of a createBrush(...) function. What do you guys think?
comment:5 by , 21 years ago
I've got a potential brush function. I've tested with polygon fills, both with ellipse and vector symbols, and with/without a background color and it seems to work fine. It's based on Frank's code looks like: static gdImagePtr createBrush(gdImagePtr img, int width, int height, styleObj *style, int *fgcolor, int *bgcolor) { gdImagePtr brush; #if GD2_VERS > 1 if(!gdImageTrueColor(img)) { brush = gdImageCreate(width, height); if(style->backgroundcolor.pen >= 0) *bgcolor = gdImageColorAllocate(brush, style->backgroundcolor.red, style->backgroundcolor.green, style->backgroundcolor.blue); else { *bgcolor = gdImageColorAllocate(brush, gdImageRed(img,0), gdImageGreen(img, 0), gdImageBlue(img, 0)); gdImageColorTransparent(brush,0); } *fgcolor = gdImageColorAllocate(brush, style->color.red, style->color.green, style->color.blue); } else { brush = gdImageCreateTrueColor(width, height); gdImageAlphaBlending(brush, 0); if(style->backgroundcolor.pen >= 0) *bgcolor = gdTrueColor(style->backgroundcolor.red, style->backgroundcolor.green, style->backgroundcolor.blue); else *bgcolor = -1; gdImageFilledRectangle(brush, 0, 0, width, height, *bgcolor); *fgcolor = gdTrueColor(style->color.red, style->color.green, style->color.blue); } #else brush = gdImageCreate(width, height); if(style->backgroundcolor.pen >= 0) *bgcolor = gdImageColorAllocate(brush, style->backgroundcolor.red, style->backgroundcolor.green, style->backgroundcolor.blue); else { *bgcolor = gdImageColorAllocate(brush, gdImageRed(img,0), gdImageGreen(img, 0), gdImageBlue(img, 0)); gdImageColorTransparent(brush,0); } *fgcolor = gdImageColorAllocate(brush, style->color.red, style->color.green, style->color.blue); #endif return(brush); } I'll continue testing with lines and if all is well will commit if everyone is cool with the change. Please let me know.
comment:7 by , 21 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
I committed the changes to mapgd.c so that all brushing and tiling uses the createBrush function. That means the circle (shade/line), and shape (shade/line) functions *should* work fine now. Marking as fixed for the moment... Note I didn't change anything with markers. Sounded as if Boutell's changes for GD 2.0.10 fixed image copying. Steve
Note:
See TracTickets
for help on using tickets.