-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create an independent renderer for draw_marker_at_points (#724)
- Loading branch information
Showing
28 changed files
with
11,967 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# (C) Copyright 2005-2021 Enthought, Inc., Austin, TX | ||
# All rights reserved. | ||
# | ||
# This software is provided without warranty under the terms of the BSD | ||
# license included in LICENSE.txt and may be redistributed only under | ||
# the conditions described in the aforementioned license. The license | ||
# is also available online at http://www.enthought.com/licenses/BSD.txt | ||
# | ||
# Thanks for using Enthought open source! | ||
from libcpp cimport bool | ||
|
||
cdef extern from "marker_renderer.h" namespace "agg24markers": | ||
cdef cppclass pixfmt_abgr32: | ||
pass | ||
cdef cppclass pixfmt_argb32: | ||
pass | ||
cdef cppclass pixfmt_bgra32: | ||
pass | ||
cdef cppclass pixfmt_rgba32: | ||
pass | ||
cdef cppclass pixfmt_bgr24: | ||
pass | ||
cdef cppclass pixfmt_rgb24: | ||
pass | ||
|
||
|
||
cdef extern from "marker_renderer.h" namespace "kiva_markers": | ||
# This is just here for the type signature | ||
cdef enum marker_type: | ||
pass | ||
|
||
# Abstract base class | ||
cdef cppclass marker_renderer_base: | ||
bool draw_markers(double* pts, unsigned Npts, | ||
unsigned size, marker_type marker, | ||
double* fill, double* stroke) | ||
void transform(double sx, double sy, | ||
double shx, double shy, | ||
double tx, double ty) | ||
|
||
# Template class | ||
cdef cppclass marker_renderer[pixfmt_T]: | ||
marker_renderer(unsigned char* buf, unsigned width, unsigned height, | ||
int stride, bool bottom_up) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
# (C) Copyright 2005-2021 Enthought, Inc., Austin, TX | ||
# All rights reserved. | ||
# | ||
# This software is provided without warranty under the terms of the BSD | ||
# license included in LICENSE.txt and may be redistributed only under | ||
# the conditions described in the aforementioned license. The license | ||
# is also available online at http://www.enthought.com/licenses/BSD.txt | ||
# | ||
# Thanks for using Enthought open source! | ||
import cython | ||
import numpy as np | ||
from numpy cimport uint8_t | ||
|
||
cimport _marker_renderer | ||
|
||
ctypedef _marker_renderer.marker_renderer_base renderer_base_t | ||
|
||
@cython.internal | ||
cdef class MarkerRendererBase: | ||
cdef renderer_base_t* _this | ||
cdef object py_array | ||
|
||
def __dealloc__(self): | ||
del self._this | ||
|
||
cdef int base_init(self, image) except -1: | ||
if image is None: | ||
raise ValueError('image argument must not be None.') | ||
|
||
# Retain a reference to the memory view supplied to the constructor | ||
# so that it lives as long as this object | ||
self.py_array = image | ||
|
||
def draw_markers(self, points, size, marker, fill, stroke): | ||
"""draw_markers(points, size, marker, fill, stroke) | ||
Draw markers at a collection of points. | ||
:param points: An Nx2 iterable of (x, y) points for marker positions | ||
:param size: An integer pixel size for each marker | ||
:param marker: A Kiva marker enum integer | ||
:param fill: Fill color given as an iterable of 4 numbers (R, G, B, A) | ||
:param stroke: Line color given as an iterable of 4 numbers (R, G, B, A) | ||
:returns: True if any markers were drawn, False otherwise | ||
""" | ||
cdef: | ||
double[:,::1] _points = np.asarray(points, dtype=np.float64, order='c') | ||
double[::1] _fill = np.asarray(fill, dtype=np.float64, order='c') | ||
double[::1] _stroke = np.asarray(stroke, dtype=np.float64, order='c') | ||
unsigned _size = <unsigned>size | ||
_marker_renderer.marker_type _marker = <_marker_renderer.marker_type>marker | ||
|
||
if _points.shape[1] != 2: | ||
msg = "points argument must be an iterable of (x, y) pairs." | ||
raise ValueError(msg) | ||
if _stroke.shape[0] != 4: | ||
msg = "stroke argument must be an iterable of 4 numbers." | ||
raise ValueError(msg) | ||
if _fill.shape[0] != 4: | ||
msg = "fill argument must be an iterable of 4 numbers." | ||
raise ValueError(msg) | ||
|
||
return self._this.draw_markers( | ||
&_points[0][0], _points.shape[0], _size, _marker, | ||
&_fill[0], &_stroke[0] | ||
) | ||
|
||
def transform(self, sx, sy, shx, shy, tx, ty): | ||
"""transform(sx, sy, shx, shy, tx, ty) | ||
Set the transform to be applied to the marker points and size. | ||
:param sx: Scale in X | ||
:param sy: Scale in Y | ||
:param shx: Shear in X | ||
:param shy: Shear in Y | ||
:param tx: Translation in X | ||
:param ty: Translation in Y | ||
""" | ||
cdef: | ||
double _sx = <double>sx | ||
double _sy = <double>sy | ||
double _shx = <double>shx | ||
double _shy = <double>shy | ||
double _tx = <double>tx | ||
double _ty = <double>ty | ||
|
||
self._this.transform(_sx, _sy, _shx, _shy, _tx, _ty) | ||
|
||
|
||
# Template specializations | ||
ctypedef _marker_renderer.marker_renderer[_marker_renderer.pixfmt_abgr32] renderer_abgr32_t | ||
ctypedef _marker_renderer.marker_renderer[_marker_renderer.pixfmt_argb32] renderer_argb32_t | ||
ctypedef _marker_renderer.marker_renderer[_marker_renderer.pixfmt_bgra32] renderer_bgra32_t | ||
ctypedef _marker_renderer.marker_renderer[_marker_renderer.pixfmt_rgba32] renderer_rgba32_t | ||
ctypedef _marker_renderer.marker_renderer[_marker_renderer.pixfmt_bgr24] renderer_bgr24_t | ||
ctypedef _marker_renderer.marker_renderer[_marker_renderer.pixfmt_rgb24] renderer_rgb24_t | ||
|
||
cdef class MarkerRendererABGR32(MarkerRendererBase): | ||
def __cinit__(self, uint8_t[:,:,::1] image, bottom_up=True): | ||
self.base_init(image) | ||
self._this = <renderer_base_t*> new renderer_abgr32_t( | ||
&image[0][0][0], image.shape[1], image.shape[0], image.strides[0], bottom_up | ||
) | ||
|
||
cdef class MarkerRendererARGB32(MarkerRendererBase): | ||
def __cinit__(self, uint8_t[:,:,::1] image, bottom_up=True): | ||
self.base_init(image) | ||
self._this = <renderer_base_t*> new renderer_argb32_t( | ||
&image[0][0][0], image.shape[1], image.shape[0], image.strides[0], bottom_up | ||
) | ||
|
||
cdef class MarkerRendererBGRA32(MarkerRendererBase): | ||
def __cinit__(self, uint8_t[:,:,::1] image, bottom_up=True): | ||
self.base_init(image) | ||
self._this = <renderer_base_t*> new renderer_bgra32_t( | ||
&image[0][0][0], image.shape[1], image.shape[0], image.strides[0], bottom_up | ||
) | ||
|
||
cdef class MarkerRendererRGBA32(MarkerRendererBase): | ||
def __cinit__(self, uint8_t[:,:,::1] image, bottom_up=True): | ||
self.base_init(image) | ||
self._this = <renderer_base_t*> new renderer_rgba32_t( | ||
&image[0][0][0], image.shape[1], image.shape[0], image.strides[0], bottom_up | ||
) | ||
|
||
cdef class MarkerRendererBGR24(MarkerRendererBase): | ||
def __cinit__(self, uint8_t[:,:,::1] image, bottom_up=True): | ||
self.base_init(image) | ||
self._this = <renderer_base_t*> new renderer_bgr24_t( | ||
&image[0][0][0], image.shape[1], image.shape[0], image.strides[0], bottom_up | ||
) | ||
|
||
cdef class MarkerRendererRGB24(MarkerRendererBase): | ||
def __cinit__(self, uint8_t[:,:,::1] image, bottom_up=True): | ||
self.base_init(image) | ||
self._this = <renderer_base_t*> new renderer_rgb24_t( | ||
&image[0][0][0], image.shape[1], image.shape[0], image.strides[0], bottom_up | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# (C) Copyright 2005-2021 Enthought, Inc., Austin, TX | ||
# All rights reserved. | ||
# | ||
# This software is provided without warranty under the terms of the BSD | ||
# license included in LICENSE.txt and may be redistributed only under | ||
# the conditions described in the aforementioned license. The license | ||
# is also available online at http://www.enthought.com/licenses/BSD.txt | ||
# | ||
# Thanks for using Enthought open source! | ||
from kiva._marker_renderer import ( | ||
MarkerRendererABGR32, MarkerRendererARGB32, MarkerRendererBGR24, | ||
MarkerRendererBGRA32, MarkerRendererRGB24, MarkerRendererRGBA32, | ||
) | ||
|
||
__all__ = ["MarkerRenderer"] | ||
|
||
_renderers = { | ||
"abgr32": (MarkerRendererABGR32, 4), | ||
"argb32": (MarkerRendererARGB32, 4), | ||
"bgra32": (MarkerRendererBGRA32, 4), | ||
"rgba32": (MarkerRendererRGBA32, 4), | ||
"bgr24": (MarkerRendererBGR24, 3), | ||
"rgb24": (MarkerRendererRGB24, 3), | ||
} | ||
|
||
|
||
def MarkerRenderer(buffer, pix_format="bgra32", bottom_up=True): | ||
""" MarkerRenderer(buffer, pix_format="bgra32", bottom_up=True) | ||
Create a specialized renderer for implementing ``draw_marker_at_points``. | ||
Parameters | ||
---------- | ||
buffer : ndarray | ||
A MxNx{3,4} numpy array of uint8 to be used as the backing pixel store | ||
pix_format : str | ||
A string specifying the pixel format. Same as what it passed to | ||
``GraphicsContext``. | ||
bottom_up : bool [optional, defaults to True] | ||
If True, the origin is bottom-left instead of top-left. | ||
Returns | ||
------- | ||
renderer : A new MarkerRenderer instance. | ||
""" | ||
klass, components = _renderers.get(pix_format, (None, 0)) | ||
if klass is None: | ||
raise ValueError(f"{pix_format} is not a supported pixel format") | ||
|
||
if (str(buffer.dtype) != "uint8" or buffer.ndim != 3 | ||
or buffer.shape[2] != components): | ||
raise ValueError(f"Pixel buffer must be MxNx{components} and uint8") | ||
|
||
return klass(buffer, bottom_up=bottom_up) |
Oops, something went wrong.