support for rgba() color string in opengl renderer and <1px lines

This commit is contained in:
Laura Klünder 2017-11-07 12:24:31 +01:00
parent 2d7cc52941
commit d0abf2a282
2 changed files with 22 additions and 11 deletions

View file

@ -54,8 +54,13 @@ class RenderEngine(ABC):
pass pass
@staticmethod @staticmethod
def hex_to_rgb(hexcolor): def color_to_rgb(color, alpha=None):
return tuple(int(hexcolor[i:i + 2], 16)/255 for i in range(1, 6, 2)) if color.startswith('#'):
return (*(int(color[i:i + 2], 16) / 255 for i in range(1, 6, 2)), 1 if alpha is None else alpha)
if color.startswith('rgba('):
color = tuple(float(i.strip()) for i in color.strip()[5:-1].split(','))
return (*(i/255 for i in color[:3]), color[3] if alpha is None else alpha)
raise ValueError('invalid color string!')
def clip_altitudes(self, new_geometry, new_altitude=None): def clip_altitudes(self, new_geometry, new_altitude=None):
# register new geometry with an altitude # register new geometry with an altitude

View file

@ -31,8 +31,8 @@ class OpenGLEngine(RenderEngine):
self.ctx.vertex_shader(''' self.ctx.vertex_shader('''
#version 330 #version 330
in vec2 in_vert; in vec2 in_vert;
in vec3 in_color; in vec4 in_color;
out vec3 v_color; out vec4 v_color;
void main() { void main() {
gl_Position = vec4(in_vert, 0.0, 1.0); gl_Position = vec4(in_vert, 0.0, 1.0);
v_color = in_color; v_color = in_color;
@ -40,10 +40,10 @@ class OpenGLEngine(RenderEngine):
'''), '''),
self.ctx.fragment_shader(''' self.ctx.fragment_shader('''
#version 330 #version 330
in vec3 v_color; in vec4 v_color;
out vec4 f_color; out vec4 f_color;
void main() { void main() {
f_color = vec4(v_color, 1.0); f_color = v_color;
} }
'''), '''),
]) ])
@ -78,17 +78,23 @@ class OpenGLEngine(RenderEngine):
geometry = geometry.buffer(max(stroke.width, (stroke.min_px or 0) / self.scale), geometry = geometry.buffer(max(stroke.width, (stroke.min_px or 0) / self.scale),
cap_style=CAP_STYLE.flat, join_style=JOIN_STYLE.mitre) cap_style=CAP_STYLE.flat, join_style=JOIN_STYLE.mitre)
stroke = None stroke = None
self.vertices.append(self._create_geometry(geometry, self.hex_to_rgb(fill.color))) self.vertices.append(self._create_geometry(geometry, self.color_to_rgb(fill.color)))
if stroke is not None and stroke.color.startswith('#'): if stroke is not None:
lines = tuple(chain(*( lines = tuple(chain(*(
((geom.exterior, *geom.interiors) if isinstance(geom, Polygon) else geom) ((geom.exterior, *geom.interiors) if isinstance(geom, Polygon) else geom)
for geom in getattr(geometry, 'geoms', (geometry, )) for geom in getattr(geometry, 'geoms', (geometry, ))
))) )))
one_pixel = 1 / self.scale / 2
width = max(stroke.width, (stroke.min_px or 0) / self.scale) / 2
if width < one_pixel:
alpha = width/one_pixel
width = one_pixel
else:
alpha = 1
self.vertices.append(self._create_geometry( self.vertices.append(self._create_geometry(
unary_union(lines).buffer(max(stroke.width, (stroke.min_px or 0) / self.scale)/2, unary_union(lines).buffer(width, cap_style=CAP_STYLE.flat, join_style=JOIN_STYLE.mitre),
cap_style=CAP_STYLE.flat, join_style=JOIN_STYLE.mitre), self.color_to_rgb(stroke.color, alpha=alpha)
self.hex_to_rgb(stroke.color)
)) ))
def get_png(self) -> bytes: def get_png(self) -> bytes: