Opened 20 years ago

Closed 20 years ago

Last modified 20 years ago

#663 closed defect (fixed)

pointObj::draw doesn't respect dynamically set style color

Reported by: sgillies@… Owned by: sgillies@…
Priority: high Milestone:
Component: MapScript Version: 4.2
Severity: critical Keywords:
Cc: eric@…

Description

Programming the color of a class style has no effect on the
output of pointObj::draw.  Here's an example

Python 2.3.3 (#1, Jan  4 2004, 11:27:28) 
[GCC 3.2.2 20030222 (Red Hat Linux 3.2.2-5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mapscript
>>> test_map = mapscript.Map('../../tests/test.map')
>>> img = test_map.draw()

The above draws a map, including a single inline point.
Below we are going to dynamically draw a point according
to the layer named INLINE, and will change the first
style's foreground color from black to red.

>>> inline = test_map.getLayerByName('INLINE')
>>> inline.getClass(0).getStyle(0).color.setRGB(255,0,0)
0
>>> inline.getClass(0).getStyle(0).color.toHex()        
'#ff0000'
>>> p = mapscript.Point(0.2,51.5)
>>> p.draw(test_map, inline, img, 0, "foo")
0
>>> img.save('test_new_point.png')

Draws a new black point when we expect red.  Will attach the file.

Attachments (1)

test_new_point.png (597 bytes ) - added by sgillies@… 20 years ago.
drawn map

Download all attachments as: .zip

Change History (6)

by sgillies@…, 20 years ago

Attachment: test_new_point.png added

drawn map

comment:1 by sgillies@…, 20 years ago

Severity: majorcritical
Status: newassigned
I've figured it out.  Has to do with the MapServer "pens", when setting
style colors we are not resetting the value of pens, hence the set color
appears to stick.  The following works:

    def testDrawPoints(self):
        points = [mapscript.pointObj(-0.2, 51.5),
                  mapscript.pointObj(0.0, 51.0),
                  mapscript.pointObj(0.2, 51.5)]
        colors = [mapscript.colorObj(255,0,0),
                  mapscript.colorObj(0,255,0),
                  mapscript.colorObj(0,0,255)]
        img = self.mapobj1.prepareImage()
        layer = self.mapobj1.getLayerByName('POINT')
        class0 = layer.getClass(0)
        for i in range(len(points)):
            style0 = class0.getStyle(0)
            style0.color = colors[i]
            style0.color.pen = -4
            assert style0.color.toHex() == colors[i].toHex()
            points[i].draw(self.mapobj1, layer, img, 0, "foo")
        img.save('test_draw_points.png')

and results in red, green, and blue points.  I'm going to find a solution
that's better than explicitly setting the pen attribute of a color.

BTW, this to me is another troublesome quirk of MapServer's objects.
How can a Color have a Pen?  Wouldn't we be better off having Pens
with Colors?  Our current design works but is sorta inside-out.

Raising the severity because I think this bug needs to be fixed in 4.2
and perhaps even back into 4.0.


comment:2 by sgillies@…, 20 years ago

Resolution: fixed
Status: assignedclosed
Resolution for 4.2 has been to set colors pen value to MS_PEN_UNSET
in the colorObj() constructor as well as setRGB, and setHex.

Anyone who changes a style color like

style.color.red = red
style.color.green = green
style.color.blue = blue

must then follow up with a 

style.color.pen = -4

otherwise their colors will have no effect
on the mapserver pens.  It would probably be possible
in the future to attach setting the pen to the
individual color get/setters using SWIG directors,
but there are no directors implemented for Perl.

Best practice is to use setRGB() or setHex() or to
assign style.color to a pre-defined colorObj instance.

Will commit this to the main branch as well.

PHP issues may remain?

comment:3 by dmorissette, 20 years ago

PHP doesn't allow you to set the members directly, you can only call setRGB(),
so this is not an issue there.

comment:4 by eric@…, 20 years ago

Cc: eric@… added

comment:5 by dmorissette, 20 years ago

OOppps... I should have read more carefully... there was indeed an issue in
php_mapscript with the pen not being set to MS_PEN_UNSET.

I have fixed this in php_mapscript.c (in 4.2 and 4.3) by using the
MS_INIT_COLOR() macro which ensures that in case of future changes to the
colorObj this won't happen again.

I also modified mapscript.i (v4.3 CVS only) to use MS_INIT_COLOR() instead of
setting color members directly, for the same reasons.
Note: See TracTickets for help on using tickets.