From 148021246ecc7369f648ccd29be5a0ff18ed172f Mon Sep 17 00:00:00 2001 From: Corran Webster Date: Thu, 13 Apr 2023 13:16:02 +0100 Subject: [PATCH 1/2] Remove OpenGL backend The OpenGL backend requires a lot of effort to maintain, is not complete and doesn't seem to be be being used in practice. Fixes #1010 --- .gitignore | 2 - README.rst | 2 - ci/edmtool.py | 1 - ci/requirements_3.8.txt | 2 - enable/__init__.py | 4 +- enable/gcbench/opengl.py | 39 - enable/gl_graphics_context.py | 19 - enable/qt4/gl.py | 60 - enable/wx/gl.py | 90 - kiva/examples/kiva/pyglet_gl.py | 64 - kiva/gl/LICENSES/LICENSE_Agg | 65 - kiva/gl/LICENSES/LICENSE_Matplotlib | 99 -- kiva/gl/__init__.py | 584 ------- kiva/gl/gl.i | 21 - kiva/gl/src/agg/agg_array.h | 1119 ------------ kiva/gl/src/agg/agg_basics.h | 560 ------ kiva/gl/src/agg/agg_bezier_arc.cpp | 255 --- kiva/gl/src/agg/agg_bezier_arc.h | 154 -- kiva/gl/src/agg/agg_color_rgba.h | 1351 --------------- kiva/gl/src/agg/agg_config.h | 44 - kiva/gl/src/agg/agg_conv_transform.h | 67 - kiva/gl/src/agg/agg_gamma_functions.h | 128 -- kiva/gl/src/agg/agg_gamma_lut.h | 305 ---- kiva/gl/src/agg/agg_math.h | 437 ----- kiva/gl/src/agg/agg_path_storage.h | 1539 ----------------- kiva/gl/src/agg/agg_sqrt_tables.cpp | 115 -- kiva/gl/src/agg/agg_trans_affine.cpp | 190 -- kiva/gl/src/agg/agg_trans_affine.h | 518 ------ kiva/gl/src/kiva_gl_affine_helpers.cpp | 64 - kiva/gl/src/kiva_gl_affine_helpers.h | 24 - kiva/gl/src/kiva_gl_basics.h | 134 -- kiva/gl/src/kiva_gl_compiled_path.cpp | 339 ---- kiva/gl/src/kiva_gl_compiled_path.h | 138 -- kiva/gl/src/kiva_gl_constants.h | 152 -- kiva/gl/src/kiva_gl_dash_type.h | 63 - kiva/gl/src/kiva_gl_exceptions.h | 25 - kiva/gl/src/kiva_gl_font_type.cpp | 130 -- kiva/gl/src/kiva_gl_font_type.h | 65 - kiva/gl/src/kiva_gl_graphics_context.cpp | 1220 ------------- kiva/gl/src/kiva_gl_graphics_context.h | 164 -- kiva/gl/src/kiva_gl_graphics_context_base.cpp | 435 ----- kiva/gl/src/kiva_gl_graphics_context_base.h | 248 --- kiva/gl/src/kiva_gl_graphics_state.h | 106 -- kiva/gl/src/kiva_gl_rect.cpp | 301 ---- kiva/gl/src/kiva_gl_rect.h | 121 -- kiva/gl/src/swig/affine_matrix.i | 227 --- kiva/gl/src/swig/agg_std_string.i | 42 - kiva/gl/src/swig/agg_typemaps.i | 322 ---- kiva/gl/src/swig/compiled_path.i | 131 -- kiva/gl/src/swig/constants.i | 152 -- kiva/gl/src/swig/font_type.i | 81 - kiva/gl/src/swig/graphics_context.i | 396 ----- kiva/gl/src/swig/numpy.i | 361 ---- kiva/gl/src/swig/rect.i | 47 - kiva/gl/src/swig/rgba.i | 104 -- kiva/gl/src/swig/rgba_array.i | 101 -- kiva/gl/src/swig/sequence_to_array.i | 44 - kiva/tests/test_gl_drawing.py | 85 - setup.py | 75 +- tox.ini | 1 - 60 files changed, 2 insertions(+), 13730 deletions(-) delete mode 100644 enable/gcbench/opengl.py delete mode 100644 enable/gl_graphics_context.py delete mode 100644 enable/qt4/gl.py delete mode 100644 enable/wx/gl.py delete mode 100644 kiva/examples/kiva/pyglet_gl.py delete mode 100644 kiva/gl/LICENSES/LICENSE_Agg delete mode 100644 kiva/gl/LICENSES/LICENSE_Matplotlib delete mode 100644 kiva/gl/__init__.py delete mode 100644 kiva/gl/gl.i delete mode 100644 kiva/gl/src/agg/agg_array.h delete mode 100644 kiva/gl/src/agg/agg_basics.h delete mode 100644 kiva/gl/src/agg/agg_bezier_arc.cpp delete mode 100644 kiva/gl/src/agg/agg_bezier_arc.h delete mode 100644 kiva/gl/src/agg/agg_color_rgba.h delete mode 100644 kiva/gl/src/agg/agg_config.h delete mode 100644 kiva/gl/src/agg/agg_conv_transform.h delete mode 100644 kiva/gl/src/agg/agg_gamma_functions.h delete mode 100644 kiva/gl/src/agg/agg_gamma_lut.h delete mode 100644 kiva/gl/src/agg/agg_math.h delete mode 100644 kiva/gl/src/agg/agg_path_storage.h delete mode 100644 kiva/gl/src/agg/agg_sqrt_tables.cpp delete mode 100644 kiva/gl/src/agg/agg_trans_affine.cpp delete mode 100644 kiva/gl/src/agg/agg_trans_affine.h delete mode 100644 kiva/gl/src/kiva_gl_affine_helpers.cpp delete mode 100644 kiva/gl/src/kiva_gl_affine_helpers.h delete mode 100644 kiva/gl/src/kiva_gl_basics.h delete mode 100644 kiva/gl/src/kiva_gl_compiled_path.cpp delete mode 100644 kiva/gl/src/kiva_gl_compiled_path.h delete mode 100644 kiva/gl/src/kiva_gl_constants.h delete mode 100644 kiva/gl/src/kiva_gl_dash_type.h delete mode 100644 kiva/gl/src/kiva_gl_exceptions.h delete mode 100755 kiva/gl/src/kiva_gl_font_type.cpp delete mode 100644 kiva/gl/src/kiva_gl_font_type.h delete mode 100644 kiva/gl/src/kiva_gl_graphics_context.cpp delete mode 100644 kiva/gl/src/kiva_gl_graphics_context.h delete mode 100755 kiva/gl/src/kiva_gl_graphics_context_base.cpp delete mode 100644 kiva/gl/src/kiva_gl_graphics_context_base.h delete mode 100644 kiva/gl/src/kiva_gl_graphics_state.h delete mode 100755 kiva/gl/src/kiva_gl_rect.cpp delete mode 100644 kiva/gl/src/kiva_gl_rect.h delete mode 100644 kiva/gl/src/swig/affine_matrix.i delete mode 100644 kiva/gl/src/swig/agg_std_string.i delete mode 100644 kiva/gl/src/swig/agg_typemaps.i delete mode 100644 kiva/gl/src/swig/compiled_path.i delete mode 100644 kiva/gl/src/swig/constants.i delete mode 100644 kiva/gl/src/swig/font_type.i delete mode 100644 kiva/gl/src/swig/graphics_context.i delete mode 100644 kiva/gl/src/swig/numpy.i delete mode 100644 kiva/gl/src/swig/rect.i delete mode 100644 kiva/gl/src/swig/rgba.i delete mode 100644 kiva/gl/src/swig/rgba_array.i delete mode 100644 kiva/gl/src/swig/sequence_to_array.i delete mode 100644 kiva/tests/test_gl_drawing.py diff --git a/.gitignore b/.gitignore index 1ccf897c2..e5e0ddf9f 100644 --- a/.gitignore +++ b/.gitignore @@ -26,8 +26,6 @@ kiva/agg/src/gtk1/plat_support_wrap.cpp kiva/agg/src/osx/plat_support_wrap.cpp kiva/agg/src/win32/plat_support_wrap.cpp kiva/agg/src/x11/plat_support_wrap.cpp -kiva/gl/gl.py -kiva/gl/gl_wrap.cpp kiva/quartz/ABCGI.c kiva/quartz/CTFont.c diff --git a/README.rst b/README.rst index 7744a2b94..dced7bdec 100644 --- a/README.rst +++ b/README.rst @@ -89,8 +89,6 @@ Enable/Kiva also have the following requirements: - `apptools `_ - (Qt backend) `PySide `_ or `PyQt4 `_ - (WX backend) `WxPython `_ -- (GL backend) `pyglet `_ -- (GL backend) `pygarrayimage `_ - (SVG backend) `PyParsing `_ - (PDF backend) `ReportLab Toolkit `_ - (Cairo backend) `PyCairo `_ diff --git a/ci/edmtool.py b/ci/edmtool.py index ceff9c4d3..edfb2920d 100644 --- a/ci/edmtool.py +++ b/ci/edmtool.py @@ -287,7 +287,6 @@ def docs(runtime, toolkit, environment): "kiva/qpainter.py", "kiva/svg.py", "kiva/agg", - "kiva/gl", "kiva/quartz", "*/tests", ]) diff --git a/ci/requirements_3.8.txt b/ci/requirements_3.8.txt index bde71b04e..2a49d052f 100644 --- a/ci/requirements_3.8.txt +++ b/ci/requirements_3.8.txt @@ -1,4 +1,2 @@ -pygarrayimage -pyglet<2.0 pypdf2<3.0 reportlab diff --git a/enable/__init__.py b/enable/__init__.py index 8ec8cd4d4..d1c36566d 100644 --- a/enable/__init__.py +++ b/enable/__init__.py @@ -23,9 +23,7 @@ # Dependencies for documentation "docs": ["enthought-sphinx-theme", "sphinx", "sphinx-copybutton"], # Dependencies for running enable/kiva's examples - "examples": ["chaco", "mayavi", "scipy", "kiwisolver", "pyglet"], - # Dependencies for GL backend support - "gl": ["pygarrayimage", "pyglet<2.0"], + "examples": ["chaco", "mayavi", "scipy", "kiwisolver"], # Dependencies for constrained layout "layout": ["kiwisolver"], # Dependencies for PDF backend diff --git a/enable/gcbench/opengl.py b/enable/gcbench/opengl.py deleted file mode 100644 index db0dc2a3d..000000000 --- a/enable/gcbench/opengl.py +++ /dev/null @@ -1,39 +0,0 @@ -# (C) Copyright 2005-2022 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 pyglet -from pyglet.image.codecs.png import PNGImageEncoder - -import kiva.gl as gl_backend - -# Pass it along -CompiledPath = gl_backend.CompiledPath - - -class GraphicsContext(gl_backend.GraphicsContext): - """ This is a wrapper of the GL GraphicsContext which works in headless - mode. - """ - def __init__(self, size, *args, **kw): - width, height = size - self.__window = pyglet.window.Window(width=width, height=height) - super().__init__((width, height), base_pixel_scale=1.0) - self.gl_init() - - def clear(self, *args): - self.__window.clear() - - def save(self, filename, *args, **kw): - buffer = pyglet.image.get_buffer_manager() - with open(filename, mode="wb") as fp: - buffer.get_color_buffer().save( - filename, - file=fp, - encoder=PNGImageEncoder(), - ) diff --git a/enable/gl_graphics_context.py b/enable/gl_graphics_context.py deleted file mode 100644 index e0f79241c..000000000 --- a/enable/gl_graphics_context.py +++ /dev/null @@ -1,19 +0,0 @@ -# (C) Copyright 2005-2022 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.gl import GraphicsContext -from .graphics_context import GraphicsContextEnable - - -class GLGraphicsContextEnable(GraphicsContextEnable, GraphicsContext): - """ This class just binds the GraphicsContextEnable to a Kiva - GL graphics context. - """ - - pass diff --git a/enable/qt4/gl.py b/enable/qt4/gl.py deleted file mode 100644 index 71c4032db..000000000 --- a/enable/qt4/gl.py +++ /dev/null @@ -1,60 +0,0 @@ -# (C) Copyright 2005-2022 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 enable.qt4.base_window import BaseGLWindow -from enable.qt4.scrollbar import NativeScrollBar -from kiva.gl import CompiledPath, FakePygletContext, GraphicsContext - - -class Window(BaseGLWindow): - def _create_gc(self, size, pix_format=None): - """ Create a GraphicsContext instance. - """ - gc = GraphicsContext( - (size[0] + 1, size[1] + 1), - base_pixel_scale=self.base_pixel_scale, - ) - self._fake_pyglet_context = FakePygletContext() - gc.gl_init() - gc.translate_ctm(0.5, 0.5) - return gc - - def _init_gc(self): - """ Gives the GC a chance to initialize itself before components - perform layout and draw. - - This is called every time through the paint loop. - """ - self.control.makeCurrent() - self._fake_pyglet_context.set_current() - super()._init_gc() - - def _paint(self, event=None): - """ Paint the contents of the window. - """ - if self.control is None: - return - - size = self._get_control_size() - self._size = tuple(size) - self._gc = self._create_gc(size) - self._init_gc() - if hasattr(self.component, "do_layout"): - self.component.do_layout() - self._gc.clear(self.bgcolor_) - self.component.draw(self._gc, view_bounds=(0, 0, size[0], size[1])) - self._update_region = [] - - -def font_metrics_provider(): - from kiva.api import Font - - gc = GraphicsContext((1, 1)) - gc.set_font(Font()) - return gc diff --git a/enable/wx/gl.py b/enable/wx/gl.py deleted file mode 100644 index 91ad66bf4..000000000 --- a/enable/wx/gl.py +++ /dev/null @@ -1,90 +0,0 @@ -# (C) Copyright 2005-2022 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 wx - -import pyglet - -pyglet.options["shadow_window"] = False -from wx.glcanvas import GLCanvas - -from traits.api import Instance -from kiva.gl import CompiledPath, FakePygletContext, GraphicsContext - -from .base_window import BaseWindow -from .scrollbar import NativeScrollBar - - -class Window(BaseWindow): - - control = Instance(GLCanvas) - - def __init__(self, *args, **kw): - super().__init__(*args, **kw) - - # If we are using the GL backend, we will need to have a pyglet - # GL context - self._pyglet_gl_context = None - - self._gc = None - - def _create_control(self, parent, wid, pos=wx.DefaultPosition, - size=wx.DefaultSize): - return GLCanvas( - parent, wid, pos, size, style=wx.CLIP_CHILDREN | wx.WANTS_CHARS - ) - - def _create_gc(self, size, pix_format=None): - """ Create a GraphicsContext instance. - """ - gc = GraphicsContext( - (size[0] + 1, size[1] + 1), - base_pixel_scale=self.base_pixel_scale, - ) - if self._pyglet_gl_context is None: - self._pyglet_gl_context = FakePygletContext() - gc.gl_init() - gc.translate_ctm(0.5, 0.5) - return gc - - def _init_gc(self): - """ Gives the GC a chance to initialize itself before components - perform layout and draw. This is called every time through the paint - loop. - """ - dc = wx.PaintDC(self.control) - self._pyglet_gl_context.set_current() - self.control.SetCurrent() - super()._init_gc() - - def _paint(self, event=None): - """ Paint the contents of the window. - """ - if self.control is None: - event.Skip() - return - - size = self._get_control_size() - self._size = tuple(size) - self._gc = self._create_gc(size) - self._init_gc() - if hasattr(self.component, "do_layout"): - self.component.do_layout() - self._gc.clear(self.bgcolor_) - self.component.draw(self._gc, view_bounds=(0, 0, size[0], size[1])) - self._update_region = [] - self.control.SwapBuffers() - - -def font_metrics_provider(): - from kiva.api import Font - - gc = GraphicsContext((1, 1)) - gc.set_font(Font()) - return gc diff --git a/kiva/examples/kiva/pyglet_gl.py b/kiva/examples/kiva/pyglet_gl.py deleted file mode 100644 index 3fad3cd10..000000000 --- a/kiva/examples/kiva/pyglet_gl.py +++ /dev/null @@ -1,64 +0,0 @@ -# (C) Copyright 2005-2022 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 numpy import array -from pyglet.window import key, Window - -from kiva.api import STROKE - -try: - from kiva.gl import GraphicsContext -except ImportError as e: - raise Exception(e) - - -class TestWindow(Window): - """ Press Q or Escape to exit - """ - - def __init__(self, *args, **kw): - Window.__init__(self, *args, **kw) - self.init_window() - - def init_window(self): - self.gc = GraphicsContext(size=(self.width, self.height)) - self.gc.gl_init() - - def on_key_press(self, symbol, modifiers): - if symbol in (key.ESCAPE, key.Q): - self.has_exit = True - - def draw(self): - gc = self.gc - with gc: - gc.clear((0, 1, 0, 1)) - gc.set_stroke_color((1, 1, 1, 1)) - gc.set_line_width(2) - pts = array([[50, 50], [50, 100], [100, 100], [100, 50]]) - gc.begin_path() - gc.lines(pts) - gc.close_path() - gc.draw_path(STROKE) - gc.flush() - - -def main(): - win = TestWindow(width=640, height=480) - exit = False - while not exit: - win.switch_to() - win.dispatch_events() - win.clear() - win.draw() - win.flip() - exit = win.has_exit - - -if __name__ == "__main__": - main() diff --git a/kiva/gl/LICENSES/LICENSE_Agg b/kiva/gl/LICENSES/LICENSE_Agg deleted file mode 100644 index f17681401..000000000 --- a/kiva/gl/LICENSES/LICENSE_Agg +++ /dev/null @@ -1,65 +0,0 @@ -The Anti-Grain Geometry Project -A high quality rendering engine for C++ -http://antigrain.com - -Anti-Grain Geometry has dual licensing model. The Modified BSD -License was first added in version v2.4 just for convenience. -It is a simple, permissive non-copyleft free software license, -compatible with the GNU GPL. It's well proven and recognizable. -See http://www.fsf.org/licensing/licenses/index_html#ModifiedBSD -for details. - -Note that the Modified BSD license DOES NOT restrict your rights -if you choose the Anti-Grain Geometry Public License. - - - - -Anti-Grain Geometry Public License -==================================================== - -Anti-Grain Geometry - Version 2.4 -Copyright (C) 2002-2005 Maxim Shemanarev (McSeem) - -Permission to copy, use, modify, sell and distribute this software -is granted provided this copyright notice appears in all copies. -This software is provided "as is" without express or implied -warranty, and with no claim as to its suitability for any purpose. - - - - - -Modified BSD License -==================================================== -Anti-Grain Geometry - Version 2.4 -Copyright (C) 2002-2005 Maxim Shemanarev (McSeem) - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - 3. The name of the author may not be used to endorse or promote - products derived from this software without specific prior - written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - diff --git a/kiva/gl/LICENSES/LICENSE_Matplotlib b/kiva/gl/LICENSES/LICENSE_Matplotlib deleted file mode 100644 index ec51537db..000000000 --- a/kiva/gl/LICENSES/LICENSE_Matplotlib +++ /dev/null @@ -1,99 +0,0 @@ -License agreement for matplotlib versions 1.3.0 and later -========================================================= - -1. This LICENSE AGREEMENT is between the Matplotlib Development Team -("MDT"), and the Individual or Organization ("Licensee") accessing and -otherwise using matplotlib software in source or binary form and its -associated documentation. - -2. Subject to the terms and conditions of this License Agreement, MDT -hereby grants Licensee a nonexclusive, royalty-free, world-wide license -to reproduce, analyze, test, perform and/or display publicly, prepare -derivative works, distribute, and otherwise use matplotlib -alone or in any derivative version, provided, however, that MDT's -License Agreement and MDT's notice of copyright, i.e., "Copyright (c) -2012- Matplotlib Development Team; All Rights Reserved" are retained in -matplotlib alone or in any derivative version prepared by -Licensee. - -3. In the event Licensee prepares a derivative work that is based on or -incorporates matplotlib or any part thereof, and wants to -make the derivative work available to others as provided herein, then -Licensee hereby agrees to include in any such work a brief summary of -the changes made to matplotlib . - -4. MDT is making matplotlib available to Licensee on an "AS -IS" basis. MDT MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR -IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, MDT MAKES NO AND -DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS -FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF MATPLOTLIB -WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. - -5. MDT SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF MATPLOTLIB - FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR -LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING -MATPLOTLIB , OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF -THE POSSIBILITY THEREOF. - -6. This License Agreement will automatically terminate upon a material -breach of its terms and conditions. - -7. Nothing in this License Agreement shall be deemed to create any -relationship of agency, partnership, or joint venture between MDT and -Licensee. This License Agreement does not grant permission to use MDT -trademarks or trade name in a trademark sense to endorse or promote -products or services of Licensee, or any third party. - -8. By copying, installing or otherwise using matplotlib , -Licensee agrees to be bound by the terms and conditions of this License -Agreement. - -License agreement for matplotlib versions prior to 1.3.0 -======================================================== - -1. This LICENSE AGREEMENT is between John D. Hunter ("JDH"), and the -Individual or Organization ("Licensee") accessing and otherwise using -matplotlib software in source or binary form and its associated -documentation. - -2. Subject to the terms and conditions of this License Agreement, JDH -hereby grants Licensee a nonexclusive, royalty-free, world-wide license -to reproduce, analyze, test, perform and/or display publicly, prepare -derivative works, distribute, and otherwise use matplotlib -alone or in any derivative version, provided, however, that JDH's -License Agreement and JDH's notice of copyright, i.e., "Copyright (c) -2002-2011 John D. Hunter; All Rights Reserved" are retained in -matplotlib alone or in any derivative version prepared by -Licensee. - -3. In the event Licensee prepares a derivative work that is based on or -incorporates matplotlib or any part thereof, and wants to -make the derivative work available to others as provided herein, then -Licensee hereby agrees to include in any such work a brief summary of -the changes made to matplotlib. - -4. JDH is making matplotlib available to Licensee on an "AS -IS" basis. JDH MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR -IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, JDH MAKES NO AND -DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS -FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF MATPLOTLIB -WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. - -5. JDH SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF MATPLOTLIB - FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR -LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING -MATPLOTLIB , OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF -THE POSSIBILITY THEREOF. - -6. This License Agreement will automatically terminate upon a material -breach of its terms and conditions. - -7. Nothing in this License Agreement shall be deemed to create any -relationship of agency, partnership, or joint venture between JDH and -Licensee. This License Agreement does not grant permission to use JDH -trademarks or trade name in a trademark sense to endorse or promote -products or services of Licensee, or any third party. - -8. By copying, installing or otherwise using matplotlib, -Licensee agrees to be bound by the terms and conditions of this License -Agreement. \ No newline at end of file diff --git a/kiva/gl/__init__.py b/kiva/gl/__init__.py deleted file mode 100644 index 985e52ee4..000000000 --- a/kiva/gl/__init__.py +++ /dev/null @@ -1,584 +0,0 @@ -# (C) Copyright 2005-2022 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 ctypes -import logging -from math import floor -import sys - -from numpy import array, ndarray - -# Local kiva imports -from kiva.affine import affine_from_values, transform_points -from kiva.constants import BOLD, bold_styles, italic_styles -from kiva.fonttools import Font -from kiva.gl.gl import CompiledPath, GraphicsContextGL, KivaGLFontType - - -logger = logging.getLogger(__name__) - - -def image_as_array(img): - """ Adapt an image object into a numpy array. - - Typically, this is used to adapt an agg GraphicsContextArray which has been - used for image storage in Kiva applications. - """ - from PIL import Image - - if hasattr(img, "bmp_array"): - # Yup, a GraphicsContextArray. - img = Image.fromarray(img.bmp_array) - elif isinstance(img, ndarray): - img = Image.fromarray(img) - elif isinstance(img, Image.Image): - pass - else: - msg = "can't convert %r into a numpy array" % (img,) - raise NotImplementedError(msg) - - # Ensure RGB or RGBA formats - if not img.mode.startswith("RGB"): - img = img.convert("RGB") - return array(img) - - -def get_dpi(): - """ Returns the appropriate DPI setting for the system""" - pass - - -class MRU(dict): - def __init__(self, *args, **kw): - # An ordering of keys in self; the last item was the most recently used - self.__order__ = [] - self.__maxlength__ = 30 - dict.__init__(self, *args, **kw) - - def __getitem__(self, key): - val = dict.__getitem__(self, key) - # If we get here, then key was found in our dict - self.__touch__(key) - return val - - def __setitem__(self, key, value): - dict.__setitem__(self, key, value) - self.__touch__(key) - - def __delitem__(self, key): - dict.__delitem__(self, key) - if key in self.__order__: - self.__order__.remove(key) - - def __touch__(self, key): - """ Puts **key** as the most recently used item """ - if len(self.__order__) == 0: - self.__order__.append(key) - if (len(self.__order__) == self.__maxlength__ and - key not in self.__order__): - # The MRU is full, so pop the oldest element - del self[self.__order__[0]] - if key != self.__order__[-1]: - try: - ndx = self.__order__.index(key) - self.__order__[ndx:-1] = self.__order__[ndx + 1:] - self.__order__[-1] = key - except ValueError: - # new key that's not already in the cache - if len(self.__order__) == self.__maxlength__: - self.__order__ = self.__order__[1:] + [key] - else: - self.__order__.append(key) - - -# Pyglet and pyglet-related imports -# Before we import anything else from pyglet, we need to set the shadow_window -# option to False, so that it does not conflict with WX, in case someone is -# trying to use the kiva GL GraphicsContext from within WX. -# This is necessary as of pyglet 1.1. -try: - import pyglet - - pyglet.options["shadow_window"] = False - - from pyglet.text import Label - from pyglet.font import load as load_font - from pyglet.font.base import Font as PygletFont - from pyglet import gl - from pygarrayimage.arrayimage import ArrayInterfaceImage - - class _ObjectSpace(object): - """ Object space mocker - - Source: https://github.com/ColinDuquesnoy/QPygletWidget - """ - - def __init__(self): - # Textures and buffers scheduled for deletion the next time this - # object space is active. - self._doomed_textures = [] - self._doomed_buffers = [] - - class FakePygletContext(object): - """ pyglet.gl.Context mocker. - - This is used to make pyglet believe that a valid context has already - been setup. (Qt takes care of creating the open gl context) - - _Most of the methods are empty, there is just the minimum required to - make it look like a duck..._ - - Source: https://github.com/ColinDuquesnoy/QPygletWidget - """ - - # define the same class attribute as pyglet.gl.Context - CONTEXT_SHARE_NONE = None - CONTEXT_SHARE_EXISTING = 1 - _gl_begin = False - _info = None - _workaround_checks = [ - ( - "_workaround_unpack_row_length", - lambda info: info.get_renderer() == "GDI Generic", - ), - ( - "_workaround_vbo", - lambda info: info.get_renderer().startswith("ATI Radeon X"), - ), - ( - "_workaround_vbo_finish", - lambda info: ( - "ATI" in info.get_renderer() - and info.have_version(1, 5) - and sys.platform == "darwin" - ), - ), - ] - - def __init__(self, context_share=None): - """ Setup workaround attr and object spaces - (again to mock what is done in pyglet context) - """ - self.object_space = _ObjectSpace() - for attr, check in self._workaround_checks: - setattr(self, attr, None) - - def __repr__(self): - return "%s()" % self.__class__.__name__ - - def set_current(self): - gl.current_context = self - - def destroy(self): - pass - - def delete_texture(self, texture_id): - pass - - def delete_buffer(self, buffer_id): - pass - - class ArrayImage(ArrayInterfaceImage): - """ pyglet ImageData made from numpy arrays. - - Customized from pygarrayimage's ArrayInterfaceImage to override the - texture creation. - """ - - def create_texture(self, cls, rectangle=False, force_rectangle=False): - """ Create a texture containing this image. - - If the image's dimensions are not powers of 2, a TextureRegion of - a larger Texture will be returned that matches the dimensions of - this image. - - :Parameters: - `cls` : class (subclass of Texture) - Class to construct. - `rectangle` : bool - ``True`` if a rectangle can be created; see - `AbstractImage.get_texture`. - - :rtype: cls or cls.region_class - """ - - _is_pow2 = (lambda v: (v & (v - 1)) == 0) - - target = gl.GL_TEXTURE_2D - if (rectangle - and not (_is_pow2(self.width) and _is_pow2(self.height))): - if gl.gl_info.have_extension("GL_ARB_texture_rectangle"): - target = gl.GL_TEXTURE_RECTANGLE_ARB - elif gl.gl_info.have_extension("GL_NV_texture_rectangle"): - target = gl.GL_TEXTURE_RECTANGLE_NV - - texture = cls.create_for_size(target, self.width, self.height) - subimage = False - if texture.width != self.width or texture.height != self.height: - texture = texture.get_region(0, 0, self.width, self.height) - subimage = True - - internalformat = self._get_internalformat(self.format) - - gl.glBindTexture(texture.target, texture.id) - gl.glTexParameteri( - texture.target, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE - ) - gl.glTexParameteri( - texture.target, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE - ) - gl.glTexParameteri( - texture.target, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR - ) - gl.glTexParameteri( - texture.target, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR - ) - - if subimage: - width = texture.owner.width - height = texture.owner.height - blank = (ctypes.c_ubyte * (width * height * 4))() - gl.glTexImage2D( - texture.target, - texture.level, - internalformat, - width, - height, - 1, - gl.GL_RGBA, - gl.GL_UNSIGNED_BYTE, - blank, - ) - internalformat = None - - self.blit_to_texture( - texture.target, texture.level, 0, 0, 0, internalformat - ) - - return texture - - def blit_to_texture(self, target, level, x, y, z, internalformat=None): - """Draw this image to to the currently bound texture at `target`. - - If `internalformat` is specified, glTexImage is used to initialise - the texture; otherwise, glTexSubImage is used to update a region. - """ - - data_format = self.format - data_pitch = abs(self._current_pitch) - - # Determine pixel format from format string - matrix = None - format, type = self._get_gl_format_and_type(data_format) - if format is None: - if (len(data_format) in (3, 4) - and gl.gl_info.have_extension("GL_ARB_imaging")): - - # Construct a color matrix to convert to GL_RGBA - def component_column(component): - try: - pos = "RGBA".index(component) - return [0] * pos + [1] + [0] * (3 - pos) - except ValueError: - return [0, 0, 0, 0] - - # pad to avoid index exceptions - lookup_format = data_format + "XXX" - matrix = ( - component_column(lookup_format[0]) - + component_column(lookup_format[1]) - + component_column(lookup_format[2]) - + component_column(lookup_format[3]) - ) - format = {3: gl.GL_RGB, 4: gl.GL_RGBA}.get( - len(data_format) - ) - type = gl.GL_UNSIGNED_BYTE - - gl.glMatrixMode(gl.GL_COLOR) - gl.glPushMatrix() - gl.glLoadMatrixf((gl.GLfloat * 16)(*matrix)) - else: - # Need to convert data to a standard form - data_format = {1: "L", 2: "LA", 3: "RGB", 4: "RGBA"}.get( - len(data_format) - ) - format, type = self._get_gl_format_and_type(data_format) - - # Workaround: don't use GL_UNPACK_ROW_LENGTH - if gl.current_context._workaround_unpack_row_length: - data_pitch = self.width * len(data_format) - - # Get data in required format (hopefully will be the same format - # it's already in, unless that's an obscure format, upside-down or - # the driver is old). - data = self._convert(data_format, data_pitch) - - if data_pitch & 0x1: - alignment = 1 - elif data_pitch & 0x2: - alignment = 2 - else: - alignment = 4 - row_length = data_pitch / len(data_format) - gl.glPushClientAttrib(gl.GL_CLIENT_PIXEL_STORE_BIT) - gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, alignment) - gl.glPixelStorei(gl.GL_UNPACK_ROW_LENGTH, row_length) - self._apply_region_unpack() - gl.glTexParameteri( - target, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE - ) - gl.glTexParameteri( - target, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE - ) - gl.glTexParameteri(target, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) - gl.glTexParameteri(target, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) - - if target == gl.GL_TEXTURE_3D: - assert not internalformat - gl.glTexSubImage3D( - target, - level, - x, - y, - z, - self.width, - self.height, - 1, - format, - type, - data, - ) - elif internalformat: - gl.glTexImage2D( - target, - level, - internalformat, - self.width, - self.height, - 0, - format, - type, - data, - ) - else: - gl.glTexSubImage2D( - target, - level, - x, - y, - self.width, - self.height, - format, - type, - data, - ) - gl.glPopClientAttrib() - - if matrix: - gl.glPopMatrix() - gl.glMatrixMode(gl.GL_MODELVIEW) - - # Use a singleton for the font cache - GlobalFontCache = MRU() - - def GetFont(font): - """ Returns a Pylget Font object for the given Agg or Kiva font """ - if isinstance(font, PygletFont): - pyglet_font = font - else: - # KivaGLFontType - key = (font.name, font.size, font.family, font.style) - if key not in GlobalFontCache: - if isinstance(font, KivaGLFontType): - kiva_gl_font = font - font = Font( - face_name=kiva_gl_font.name, - size=kiva_gl_font.size, - family=kiva_gl_font.family, - style=kiva_gl_font.style, - ) - bold = font.is_bold() - italic = font.style in italic_styles - pyglet_font = load_font( - font.findfontname(), font.size, bold, italic - ) - GlobalFontCache[key] = pyglet_font - else: - pyglet_font = GlobalFontCache[key] - return pyglet_font - - # Because Pyglet 1.1 uses persistent Label objects to efficiently lay - # out and render text, we cache these globally to minimize the creation - # time. An MRU is not really the right structure to use here, though. - # (We typically expect that the same numbers of labels will be rendered.) - GlobalTextCache = MRU() - GlobalTextCache.__maxlength__ = 100 - - def GetLabel(text, pyglet_font): - """ Returns a Pyglet Label object for the given text and font """ - key = (text, pyglet_font) - if key not in GlobalTextCache: - # Use anchor_y="bottom" because by default, pyglet sets the - # baseline to the y coordinate given. Unfortunately, it doesn't - # expose a per-Text descent (only a per-Font descent), so it's - # impossible to know how to offset the y value properly for a - # given string. - label = Label( - text, - font_name=pyglet_font.name, - font_size=pyglet_font.size, - anchor_y="bottom", - ) - GlobalTextCache[key] = label - else: - label = GlobalTextCache[key] - return label - - -except ImportError as exc: - # Pyglet is not available, so we forgo some features - logger.exception( - "Error importing Pyglet, some features not available in gl backend" - ) - ArrayImage = None - GetFont = None - GetLabel = None - gl = None - - -class GraphicsContext(GraphicsContextGL): - def __init__(self, size, *args, **kw): - # Ignore the pix_format argument for now - kw.pop("pix_format", None) - base_scale = kw.pop("base_pixel_scale", 1) - GraphicsContextGL.__init__(self, size[0], size[1], *args, **kw) - self.corner_pixel_origin = True - - # For HiDPI support - self.scale_ctm(base_scale, base_scale) - - self._font_stack = [] - self._current_font = None - self._text_pos = (0, 0) - - def save_state(self): - super().save_state() - self._font_stack.append(self._current_font) - - def restore_state(self): - super().restore_state() - self._current_font = self._font_stack.pop() - - def set_font(self, font): - self._current_font = font - - def get_text_extent(self, text): - if self._current_font is None: - return (0, 0, 0, 0) - - pyglet_font = GetFont(self._current_font) - label = GetLabel(text, pyglet_font) - return (0, 0, label.content_width, label.content_height) - - def set_text_position(self, x, y): - self._text_pos = (x, y) - - def show_text(self, text, point=None): - if point is None: - point = self._text_pos - return self.show_text_at_point(text, *point) - - def show_text_at_point(self, text, x, y): - if self._current_font is None: - return - - pyglet_font = GetFont(self._current_font) - label = GetLabel(text, pyglet_font) - - xform = self.get_ctm() - x0 = xform[4] - y0 = xform[5] - - # The GL backend places the center of a pixel at (0.5, 0.5); however, - # for show_text_at_point, we don't actually want to render the text - # offset by half a pixel. There is probably a better, more uniform way - # to handle this across all of Kiva, because this is probably a common - # issue that will arise, but for now, we just round the position down. - x = floor(x + x0) - y = floor(y + y0) - - label.x = x - label.y = y - c = self.get_fill_color() - label.color = ( - int(c[0] * 255), - int(c[1] * 255), - int(c[2] * 255), - int(c[3] * 255), - ) - label.draw() - return True - - def linear_gradient(self, x1, y1, x2, y2, stops, spread_method, - units="userSpaceOnUse"): - """ Not implemented. - """ - pass - - def radial_gradient(self, cx, cy, r, fx, fy, stops, spread_method, - units="userSpaceOnUse"): - """ Not implemented. - """ - pass - - def draw_image(self, img, rect=None, force_copy=False): - """ Renders a GraphicsContextArray into this GC """ - xform = self.get_ctm() - - image = image_as_array(img) - shape = image.shape - if shape[2] == 4: - fmt = "RGBA" - else: - fmt = "RGB" - aii = ArrayImage(image, format=fmt) - texture = aii.texture - - # The texture coords consists of (u,v,r) for each corner of the - # texture rectangle. The coordinates are stored in the order - # bottom left, bottom right, top right, top left. - x, y, w, h = rect - texture.width = w - texture.height = h - t = texture.tex_coords - points = array([[x, y + h], [x + w, y + h], [x + w, y], [x, y]]) - p = transform_points(affine_from_values(*xform), points) - a = (gl.GLfloat*32)( - t[0], t[1], t[2], 1., - p[0, 0], p[0, 1], 0, 1., - t[3], t[4], t[5], 1., - p[1, 0], p[1, 1], 0, 1., - t[6], t[7], t[8], 1., - p[2, 0], p[2, 1], 0, 1., - t[9], t[10], t[11], 1., - p[3, 0], p[3, 1], 0, 1., - ) - gl.glPushAttrib(gl.GL_ENABLE_BIT) - gl.glEnable(texture.target) - gl.glBindTexture(texture.target, texture.id) - gl.glPushClientAttrib(gl.GL_CLIENT_VERTEX_ARRAY_BIT) - gl.glInterleavedArrays(gl.GL_T4F_V4F, 0, a) - gl.glDrawArrays(gl.GL_QUADS, 0, 4) - gl.glPopClientAttrib() - gl.glPopAttrib() - - -def font_metrics_provider(): - return GraphicsContext((1, 1)) diff --git a/kiva/gl/gl.i b/kiva/gl/gl.i deleted file mode 100644 index cba55880b..000000000 --- a/kiva/gl/gl.i +++ /dev/null @@ -1,21 +0,0 @@ -/* -*- c++ -*- */ -// (C) Copyright 2005-2022 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! - -%module gl - -%feature("compactdefaultargs"); - -%include "constants.i" -%include "rgba.i" -%include "affine_matrix.i" -%include "compiled_path.i" -%include "font_type.i" -%include "graphics_context.i" diff --git a/kiva/gl/src/agg/agg_array.h b/kiva/gl/src/agg/agg_array.h deleted file mode 100644 index 485347c56..000000000 --- a/kiva/gl/src/agg/agg_array.h +++ /dev/null @@ -1,1119 +0,0 @@ -//---------------------------------------------------------------------------- -// Anti-Grain Geometry - Version 2.4 -// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) -// -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. -// This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -#ifndef AGG_ARRAY_INCLUDED -#define AGG_ARRAY_INCLUDED - -#include -#include -#include "agg_basics.h" - -namespace kiva_gl_agg -{ - - //-------------------------------------------------------pod_array_adaptor - template class pod_array_adaptor - { - public: - typedef T value_type; - pod_array_adaptor(T* array, unsigned size) : - m_array(array), m_size(size) {} - - unsigned size() const { return m_size; } - const T& operator [] (unsigned i) const { return m_array[i]; } - T& operator [] (unsigned i) { return m_array[i]; } - const T& at(unsigned i) const { return m_array[i]; } - T& at(unsigned i) { return m_array[i]; } - T value_at(unsigned i) const { return m_array[i]; } - - private: - T* m_array; - unsigned m_size; - }; - - - //---------------------------------------------------------pod_auto_array - template class pod_auto_array - { - public: - typedef T value_type; - typedef pod_auto_array self_type; - - pod_auto_array() {} - explicit pod_auto_array(const T* c) - { - memcpy(m_array, c, sizeof(T) * Size); - } - - const self_type& operator = (const T* c) - { - memcpy(m_array, c, sizeof(T) * Size); - return *this; - } - - static unsigned size() { return Size; } - const T& operator [] (unsigned i) const { return m_array[i]; } - T& operator [] (unsigned i) { return m_array[i]; } - const T& at(unsigned i) const { return m_array[i]; } - T& at(unsigned i) { return m_array[i]; } - T value_at(unsigned i) const { return m_array[i]; } - - private: - T m_array[Size]; - }; - - - //--------------------------------------------------------pod_auto_vector - template class pod_auto_vector - { - public: - typedef T value_type; - typedef pod_auto_vector self_type; - - pod_auto_vector() : m_size(0) {} - - void remove_all() { m_size = 0; } - void clear() { m_size = 0; } - void add(const T& v) { m_array[m_size++] = v; } - void push_back(const T& v) { m_array[m_size++] = v; } - void inc_size(unsigned size) { m_size += size; } - - unsigned size() const { return m_size; } - const T& operator [] (unsigned i) const { return m_array[i]; } - T& operator [] (unsigned i) { return m_array[i]; } - const T& at(unsigned i) const { return m_array[i]; } - T& at(unsigned i) { return m_array[i]; } - T value_at(unsigned i) const { return m_array[i]; } - - private: - T m_array[Size]; - unsigned m_size; - }; - - - //---------------------------------------------------------------pod_array - template class pod_array - { - public: - typedef T value_type; - typedef pod_array self_type; - - ~pod_array() { pod_allocator::deallocate(m_array, m_size); } - pod_array() : m_array(0), m_size(0) {} - - pod_array(unsigned size) : - m_array(pod_allocator::allocate(size)), - m_size(size) - {} - - pod_array(const self_type& v) : - m_array(pod_allocator::allocate(v.m_size)), - m_size(v.m_size) - { - memcpy(m_array, v.m_array, sizeof(T) * m_size); - } - - void resize(unsigned size) - { - if(size != m_size) - { - pod_allocator::deallocate(m_array, m_size); - m_array = pod_allocator::allocate(m_size = size); - } - } - const self_type& operator = (const self_type& v) - { - resize(v.size()); - memcpy(m_array, v.m_array, sizeof(T) * m_size); - return *this; - } - - unsigned size() const { return m_size; } - const T& operator [] (unsigned i) const { return m_array[i]; } - T& operator [] (unsigned i) { return m_array[i]; } - const T& at(unsigned i) const { return m_array[i]; } - T& at(unsigned i) { return m_array[i]; } - T value_at(unsigned i) const { return m_array[i]; } - - const T* data() const { return m_array; } - T* data() { return m_array; } - private: - T* m_array; - unsigned m_size; - }; - - - - //--------------------------------------------------------------pod_vector - // A simple class template to store Plain Old Data, a vector - // of a fixed size. The data is continous in memory - //------------------------------------------------------------------------ - template class pod_vector - { - public: - typedef T value_type; - - ~pod_vector() { pod_allocator::deallocate(m_array, m_capacity); } - pod_vector() : m_size(0), m_capacity(0), m_array(0) {} - pod_vector(unsigned cap, unsigned extra_tail=0); - - // Copying - pod_vector(const pod_vector&); - const pod_vector& operator = (const pod_vector&); - - // Set new capacity. All data is lost, size is set to zero. - void capacity(unsigned cap, unsigned extra_tail=0); - unsigned capacity() const { return m_capacity; } - - // Allocate n elements. All data is lost, - // but elements can be accessed in range 0...size-1. - void allocate(unsigned size, unsigned extra_tail=0); - - // Resize keeping the content. - void resize(unsigned new_size); - - void zero() - { - memset(m_array, 0, sizeof(T) * m_size); - } - - void add(const T& v) { m_array[m_size++] = v; } - void push_back(const T& v) { m_array[m_size++] = v; } - void insert_at(unsigned pos, const T& val); - void inc_size(unsigned size) { m_size += size; } - unsigned size() const { return m_size; } - unsigned byte_size() const { return m_size * sizeof(T); } - void serialize(int8u* ptr) const; - void deserialize(const int8u* data, unsigned byte_size); - const T& operator [] (unsigned i) const { return m_array[i]; } - T& operator [] (unsigned i) { return m_array[i]; } - const T& at(unsigned i) const { return m_array[i]; } - T& at(unsigned i) { return m_array[i]; } - T value_at(unsigned i) const { return m_array[i]; } - - const T* data() const { return m_array; } - T* data() { return m_array; } - - void remove_all() { m_size = 0; } - void clear() { m_size = 0; } - void cut_at(unsigned num) { if(num < m_size) m_size = num; } - - private: - unsigned m_size; - unsigned m_capacity; - T* m_array; - }; - - //------------------------------------------------------------------------ - template - void pod_vector::capacity(unsigned cap, unsigned extra_tail) - { - m_size = 0; - if(cap > m_capacity) - { - pod_allocator::deallocate(m_array, m_capacity); - m_capacity = cap + extra_tail; - m_array = m_capacity ? pod_allocator::allocate(m_capacity) : 0; - } - } - - //------------------------------------------------------------------------ - template - void pod_vector::allocate(unsigned size, unsigned extra_tail) - { - capacity(size, extra_tail); - m_size = size; - } - - - //------------------------------------------------------------------------ - template - void pod_vector::resize(unsigned new_size) - { - if(new_size > m_size) - { - if(new_size > m_capacity) - { - T* data = pod_allocator::allocate(new_size); - memcpy(data, m_array, m_size * sizeof(T)); - pod_allocator::deallocate(m_array, m_capacity); - m_array = data; - } - } - else - { - m_size = new_size; - } - } - - //------------------------------------------------------------------------ - template pod_vector::pod_vector(unsigned cap, unsigned extra_tail) : - m_size(0), - m_capacity(cap + extra_tail), - m_array(pod_allocator::allocate(m_capacity)) {} - - //------------------------------------------------------------------------ - template pod_vector::pod_vector(const pod_vector& v) : - m_size(v.m_size), - m_capacity(v.m_capacity), - m_array(v.m_capacity ? pod_allocator::allocate(v.m_capacity) : 0) - { - memcpy(m_array, v.m_array, sizeof(T) * v.m_size); - } - - //------------------------------------------------------------------------ - template const pod_vector& - pod_vector::operator = (const pod_vector&v) - { - allocate(v.m_size); - if(v.m_size) memcpy(m_array, v.m_array, sizeof(T) * v.m_size); - return *this; - } - - //------------------------------------------------------------------------ - template void pod_vector::serialize(int8u* ptr) const - { - if(m_size) memcpy(ptr, m_array, m_size * sizeof(T)); - } - - //------------------------------------------------------------------------ - template - void pod_vector::deserialize(const int8u* data, unsigned byte_size) - { - byte_size /= sizeof(T); - allocate(byte_size); - if(byte_size) memcpy(m_array, data, byte_size * sizeof(T)); - } - - //------------------------------------------------------------------------ - template - void pod_vector::insert_at(unsigned pos, const T& val) - { - if(pos >= m_size) - { - m_array[m_size] = val; - } - else - { - memmove(m_array + pos + 1, m_array + pos, (m_size - pos) * sizeof(T)); - m_array[pos] = val; - } - ++m_size; - } - - //---------------------------------------------------------------pod_bvector - // A simple class template to store Plain Old Data, similar to std::deque - // It doesn't reallocate memory but instead, uses blocks of data of size - // of (1 << S), that is, power of two. The data is NOT contiguous in memory, - // so the only valid access method is operator [] or curr(), prev(), next() - // - // There reallocs occure only when the pool of pointers to blocks needs - // to be extended (it happens very rarely). You can control the value - // of increment to reallocate the pointer buffer. See the second constructor. - // By default, the incremeent value equals (1 << S), i.e., the block size. - //------------------------------------------------------------------------ - template class pod_bvector - { - public: - enum block_scale_e - { - block_shift = S, - block_size = 1 << block_shift, - block_mask = block_size - 1 - }; - - typedef T value_type; - - ~pod_bvector(); - pod_bvector(); - pod_bvector(unsigned block_ptr_inc); - - // Copying - pod_bvector(const pod_bvector& v); - const pod_bvector& operator = (const pod_bvector& v); - - void remove_all() { m_size = 0; } - void clear() { m_size = 0; } - void free_all() { free_tail(0); } - void free_tail(unsigned size); - void add(const T& val); - void push_back(const T& val) { add(val); } - void modify_last(const T& val); - void remove_last(); - - int allocate_continuous_block(unsigned num_elements); - - void add_array(const T* ptr, unsigned num_elem) - { - while(num_elem--) - { - add(*ptr++); - } - } - - template void add_data(DataAccessor& data) - { - while(data.size()) - { - add(*data); - ++data; - } - } - - void cut_at(unsigned size) - { - if(size < m_size) m_size = size; - } - - unsigned size() const { return m_size; } - - const T& operator [] (unsigned i) const - { - return m_blocks[i >> block_shift][i & block_mask]; - } - - T& operator [] (unsigned i) - { - return m_blocks[i >> block_shift][i & block_mask]; - } - - const T& at(unsigned i) const - { - return m_blocks[i >> block_shift][i & block_mask]; - } - - T& at(unsigned i) - { - return m_blocks[i >> block_shift][i & block_mask]; - } - - T value_at(unsigned i) const - { - return m_blocks[i >> block_shift][i & block_mask]; - } - - const T& curr(unsigned idx) const - { - return (*this)[idx]; - } - - T& curr(unsigned idx) - { - return (*this)[idx]; - } - - const T& prev(unsigned idx) const - { - return (*this)[(idx + m_size - 1) % m_size]; - } - - T& prev(unsigned idx) - { - return (*this)[(idx + m_size - 1) % m_size]; - } - - const T& next(unsigned idx) const - { - return (*this)[(idx + 1) % m_size]; - } - - T& next(unsigned idx) - { - return (*this)[(idx + 1) % m_size]; - } - - const T& last() const - { - return (*this)[m_size - 1]; - } - - T& last() - { - return (*this)[m_size - 1]; - } - - unsigned byte_size() const; - void serialize(int8u* ptr) const; - void deserialize(const int8u* data, unsigned byte_size); - void deserialize(unsigned start, const T& empty_val, - const int8u* data, unsigned byte_size); - - template - void deserialize(ByteAccessor data) - { - remove_all(); - unsigned elem_size = data.size() / sizeof(T); - - for(unsigned i = 0; i < elem_size; ++i) - { - int8u* ptr = (int8u*)data_ptr(); - for(unsigned j = 0; j < sizeof(T); ++j) - { - *ptr++ = *data; - ++data; - } - ++m_size; - } - } - - template - void deserialize(unsigned start, const T& empty_val, ByteAccessor data) - { - while(m_size < start) - { - add(empty_val); - } - - unsigned elem_size = data.size() / sizeof(T); - for(unsigned i = 0; i < elem_size; ++i) - { - int8u* ptr; - if(start + i < m_size) - { - ptr = (int8u*)(&((*this)[start + i])); - } - else - { - ptr = (int8u*)data_ptr(); - ++m_size; - } - for(unsigned j = 0; j < sizeof(T); ++j) - { - *ptr++ = *data; - ++data; - } - } - } - - const T* block(unsigned nb) const { return m_blocks[nb]; } - - private: - void allocate_block(unsigned nb); - T* data_ptr(); - - unsigned m_size; - unsigned m_num_blocks; - unsigned m_max_blocks; - T** m_blocks; - unsigned m_block_ptr_inc; - }; - - - //------------------------------------------------------------------------ - template pod_bvector::~pod_bvector() - { - if(m_num_blocks) - { - T** blk = m_blocks + m_num_blocks - 1; - while(m_num_blocks--) - { - pod_allocator::deallocate(*blk, block_size); - --blk; - } - } - pod_allocator::deallocate(m_blocks, m_max_blocks); - } - - - //------------------------------------------------------------------------ - template - void pod_bvector::free_tail(unsigned size) - { - if(size < m_size) - { - unsigned nb = (size + block_mask) >> block_shift; - while(m_num_blocks > nb) - { - pod_allocator::deallocate(m_blocks[--m_num_blocks], block_size); - } - if(m_num_blocks == 0) - { - pod_allocator::deallocate(m_blocks, m_max_blocks); - m_blocks = 0; - m_max_blocks = 0; - } - m_size = size; - } - } - - - //------------------------------------------------------------------------ - template pod_bvector::pod_bvector() : - m_size(0), - m_num_blocks(0), - m_max_blocks(0), - m_blocks(0), - m_block_ptr_inc(block_size) - { - } - - - //------------------------------------------------------------------------ - template - pod_bvector::pod_bvector(unsigned block_ptr_inc) : - m_size(0), - m_num_blocks(0), - m_max_blocks(0), - m_blocks(0), - m_block_ptr_inc(block_ptr_inc) - { - } - - - //------------------------------------------------------------------------ - template - pod_bvector::pod_bvector(const pod_bvector& v) : - m_size(v.m_size), - m_num_blocks(v.m_num_blocks), - m_max_blocks(v.m_max_blocks), - m_blocks(v.m_max_blocks ? - pod_allocator::allocate(v.m_max_blocks) : - 0), - m_block_ptr_inc(v.m_block_ptr_inc) - { - unsigned i; - for(i = 0; i < v.m_num_blocks; ++i) - { - m_blocks[i] = pod_allocator::allocate(block_size); - memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T)); - } - } - - - //------------------------------------------------------------------------ - template - const pod_bvector& - pod_bvector::operator = (const pod_bvector& v) - { - unsigned i; - for(i = m_num_blocks; i < v.m_num_blocks; ++i) - { - allocate_block(i); - } - for(i = 0; i < v.m_num_blocks; ++i) - { - memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T)); - } - m_size = v.m_size; - return *this; - } - - - //------------------------------------------------------------------------ - template - void pod_bvector::allocate_block(unsigned nb) - { - if(nb >= m_max_blocks) - { - T** new_blocks = pod_allocator::allocate(m_max_blocks + m_block_ptr_inc); - - if(m_blocks) - { - memcpy(new_blocks, - m_blocks, - m_num_blocks * sizeof(T*)); - - pod_allocator::deallocate(m_blocks, m_max_blocks); - } - m_blocks = new_blocks; - m_max_blocks += m_block_ptr_inc; - } - m_blocks[nb] = pod_allocator::allocate(block_size); - m_num_blocks++; - } - - - - //------------------------------------------------------------------------ - template - inline T* pod_bvector::data_ptr() - { - unsigned nb = m_size >> block_shift; - if(nb >= m_num_blocks) - { - allocate_block(nb); - } - return m_blocks[nb] + (m_size & block_mask); - } - - - - //------------------------------------------------------------------------ - template - inline void pod_bvector::add(const T& val) - { - *data_ptr() = val; - ++m_size; - } - - - //------------------------------------------------------------------------ - template - inline void pod_bvector::remove_last() - { - if(m_size) --m_size; - } - - - //------------------------------------------------------------------------ - template - void pod_bvector::modify_last(const T& val) - { - remove_last(); - add(val); - } - - - //------------------------------------------------------------------------ - template - int pod_bvector::allocate_continuous_block(unsigned num_elements) - { - if(num_elements < block_size) - { - data_ptr(); // Allocate initial block if necessary - unsigned rest = block_size - (m_size & block_mask); - unsigned index; - if(num_elements <= rest) - { - // The rest of the block is good, we can use it - //----------------- - index = m_size; - m_size += num_elements; - return index; - } - - // New block - //--------------- - m_size += rest; - data_ptr(); - index = m_size; - m_size += num_elements; - return index; - } - return -1; // Impossible to allocate - } - - - //------------------------------------------------------------------------ - template - unsigned pod_bvector::byte_size() const - { - return m_size * sizeof(T); - } - - - //------------------------------------------------------------------------ - template - void pod_bvector::serialize(int8u* ptr) const - { - unsigned i; - for(i = 0; i < m_size; i++) - { - memcpy(ptr, &(*this)[i], sizeof(T)); - ptr += sizeof(T); - } - } - - //------------------------------------------------------------------------ - template - void pod_bvector::deserialize(const int8u* data, unsigned byte_size) - { - remove_all(); - byte_size /= sizeof(T); - for(unsigned i = 0; i < byte_size; ++i) - { - T* ptr = data_ptr(); - memcpy(ptr, data, sizeof(T)); - ++m_size; - data += sizeof(T); - } - } - - - // Replace or add a number of elements starting from "start" position - //------------------------------------------------------------------------ - template - void pod_bvector::deserialize(unsigned start, const T& empty_val, - const int8u* data, unsigned byte_size) - { - while(m_size < start) - { - add(empty_val); - } - - byte_size /= sizeof(T); - for(unsigned i = 0; i < byte_size; ++i) - { - if(start + i < m_size) - { - memcpy(&((*this)[start + i]), data, sizeof(T)); - } - else - { - T* ptr = data_ptr(); - memcpy(ptr, data, sizeof(T)); - ++m_size; - } - data += sizeof(T); - } - } - - - //---------------------------------------------------------block_allocator - // Allocator for arbitrary POD data. Most usable in different cache - // systems for efficient memory allocations. - // Memory is allocated with blocks of fixed size ("block_size" in - // the constructor). If required size exceeds the block size the allocator - // creates a new block of the required size. However, the most efficient - // use is when the average reqired size is much less than the block size. - //------------------------------------------------------------------------ - class block_allocator - { - struct block_type - { - int8u* data; - unsigned size; - }; - - public: - void remove_all() - { - if(m_num_blocks) - { - block_type* blk = m_blocks + m_num_blocks - 1; - while(m_num_blocks--) - { - pod_allocator::deallocate(blk->data, blk->size); - --blk; - } - pod_allocator::deallocate(m_blocks, m_max_blocks); - } - m_num_blocks = 0; - m_max_blocks = 0; - m_blocks = 0; - m_buf_ptr = 0; - m_rest = 0; - } - - ~block_allocator() - { - remove_all(); - } - - block_allocator(unsigned block_size, unsigned block_ptr_inc=256-8) : - m_block_size(block_size), - m_block_ptr_inc(block_ptr_inc), - m_num_blocks(0), - m_max_blocks(0), - m_blocks(0), - m_buf_ptr(0), - m_rest(0) - { - } - - - int8u* allocate(unsigned size, unsigned alignment=1) - { - if(size == 0) return 0; - if(size <= m_rest) - { - int8u* ptr = m_buf_ptr; - if(alignment > 1) - { - unsigned align = - (alignment - unsigned((size_t)ptr) % alignment) % alignment; - - size += align; - ptr += align; - if(size <= m_rest) - { - m_rest -= size; - m_buf_ptr += size; - return ptr; - } - allocate_block(size); - return allocate(size - align, alignment); - } - m_rest -= size; - m_buf_ptr += size; - return ptr; - } - allocate_block(size + alignment - 1); - return allocate(size, alignment); - } - - - private: - void allocate_block(unsigned size) - { - if(size < m_block_size) size = m_block_size; - if(m_num_blocks >= m_max_blocks) - { - block_type* new_blocks = - pod_allocator::allocate(m_max_blocks + m_block_ptr_inc); - - if(m_blocks) - { - memcpy(new_blocks, - m_blocks, - m_num_blocks * sizeof(block_type)); - pod_allocator::deallocate(m_blocks, m_max_blocks); - } - m_blocks = new_blocks; - m_max_blocks += m_block_ptr_inc; - } - - m_blocks[m_num_blocks].size = size; - m_blocks[m_num_blocks].data = - m_buf_ptr = - pod_allocator::allocate(size); - - m_num_blocks++; - m_rest = size; - } - - unsigned m_block_size; - unsigned m_block_ptr_inc; - unsigned m_num_blocks; - unsigned m_max_blocks; - block_type* m_blocks; - int8u* m_buf_ptr; - unsigned m_rest; - }; - - - - - - - - - //------------------------------------------------------------------------ - enum quick_sort_threshold_e - { - quick_sort_threshold = 9 - }; - - - //-----------------------------------------------------------swap_elements - template inline void swap_elements(T& a, T& b) - { - T temp = a; - a = b; - b = temp; - } - - - //--------------------------------------------------------------quick_sort - template - void quick_sort(Array& arr, Less less) - { - if(arr.size() < 2) return; - - typename Array::value_type* e1; - typename Array::value_type* e2; - - int stack[80]; - int* top = stack; - int limit = arr.size(); - int base = 0; - - for(;;) - { - int len = limit - base; - - int i; - int j; - int pivot; - - if(len > quick_sort_threshold) - { - // we use base + len/2 as the pivot - pivot = base + len / 2; - swap_elements(arr[base], arr[pivot]); - - i = base + 1; - j = limit - 1; - - // now ensure that *i <= *base <= *j - e1 = &(arr[j]); - e2 = &(arr[i]); - if(less(*e1, *e2)) swap_elements(*e1, *e2); - - e1 = &(arr[base]); - e2 = &(arr[i]); - if(less(*e1, *e2)) swap_elements(*e1, *e2); - - e1 = &(arr[j]); - e2 = &(arr[base]); - if(less(*e1, *e2)) swap_elements(*e1, *e2); - - for(;;) - { - do i++; while( less(arr[i], arr[base]) ); - do j--; while( less(arr[base], arr[j]) ); - - if( i > j ) - { - break; - } - - swap_elements(arr[i], arr[j]); - } - - swap_elements(arr[base], arr[j]); - - // now, push the largest sub-array - if(j - base > limit - i) - { - top[0] = base; - top[1] = j; - base = i; - } - else - { - top[0] = i; - top[1] = limit; - limit = j; - } - top += 2; - } - else - { - // the sub-array is small, perform insertion sort - j = base; - i = j + 1; - - for(; i < limit; j = i, i++) - { - for(; less(*(e1 = &(arr[j + 1])), *(e2 = &(arr[j]))); j--) - { - swap_elements(*e1, *e2); - if(j == base) - { - break; - } - } - } - if(top > stack) - { - top -= 2; - base = top[0]; - limit = top[1]; - } - else - { - break; - } - } - } - } - - - - - //------------------------------------------------------remove_duplicates - // Remove duplicates from a sorted array. It doesn't cut the - // tail of the array, it just returns the number of remaining elements. - //----------------------------------------------------------------------- - template - unsigned remove_duplicates(Array& arr, Equal equal) - { - if(arr.size() < 2) return arr.size(); - - unsigned i, j; - for(i = 1, j = 1; i < arr.size(); i++) - { - typename Array::value_type& e = arr[i]; - if(!equal(e, arr[i - 1])) - { - arr[j++] = e; - } - } - return j; - } - - //--------------------------------------------------------invert_container - template void invert_container(Array& arr) - { - int i = 0; - int j = arr.size() - 1; - while(i < j) - { - swap_elements(arr[i++], arr[j--]); - } - } - - //------------------------------------------------------binary_search_pos - template - unsigned binary_search_pos(const Array& arr, const Value& val, Less less) - { - if(arr.size() == 0) return 0; - - unsigned beg = 0; - unsigned end = arr.size() - 1; - - if(less(val, arr[0])) return 0; - if(less(arr[end], val)) return end + 1; - - while(end - beg > 1) - { - unsigned mid = (end + beg) >> 1; - if(less(val, arr[mid])) end = mid; - else beg = mid; - } - - //if(beg <= 0 && less(val, arr[0])) return 0; - //if(end >= arr.size() - 1 && less(arr[end], val)) ++end; - - return end; - } - - //----------------------------------------------------------range_adaptor - template class range_adaptor - { - public: - typedef typename Array::value_type value_type; - - range_adaptor(Array& array, unsigned start, unsigned size) : - m_array(array), m_start(start), m_size(size) - {} - - unsigned size() const { return m_size; } - const value_type& operator [] (unsigned i) const { return m_array[m_start + i]; } - value_type& operator [] (unsigned i) { return m_array[m_start + i]; } - const value_type& at(unsigned i) const { return m_array[m_start + i]; } - value_type& at(unsigned i) { return m_array[m_start + i]; } - value_type value_at(unsigned i) const { return m_array[m_start + i]; } - - private: - Array& m_array; - unsigned m_start; - unsigned m_size; - }; - - //---------------------------------------------------------------int_less - inline bool int_less(int a, int b) { return a < b; } - - //------------------------------------------------------------int_greater - inline bool int_greater(int a, int b) { return a > b; } - - //----------------------------------------------------------unsigned_less - inline bool unsigned_less(unsigned a, unsigned b) { return a < b; } - - //-------------------------------------------------------unsigned_greater - inline bool unsigned_greater(unsigned a, unsigned b) { return a > b; } -} - -#endif diff --git a/kiva/gl/src/agg/agg_basics.h b/kiva/gl/src/agg/agg_basics.h deleted file mode 100644 index 88930fd47..000000000 --- a/kiva/gl/src/agg/agg_basics.h +++ /dev/null @@ -1,560 +0,0 @@ -//---------------------------------------------------------------------------- -// Anti-Grain Geometry - Version 2.4 -// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) -// -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. -// This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_BASICS_INCLUDED -#define AGG_BASICS_INCLUDED - -#include -#include "agg_config.h" - -//---------------------------------------------------------AGG_CUSTOM_ALLOCATOR -#ifdef AGG_CUSTOM_ALLOCATOR -#include "agg_allocator.h" -#else -namespace kiva_gl_agg -{ - // The policy of all AGG containers and memory allocation strategy - // in general is that no allocated data requires explicit construction. - // It means that the allocator can be really simple; you can even - // replace new/delete to malloc/free. The constructors and destructors - // won't be called in this case, however everything will remain working. - // The second argument of deallocate() is the size of the allocated - // block. You can use this information if you wish. - //------------------------------------------------------------pod_allocator - template struct pod_allocator - { - static T* allocate(unsigned num) { return new T [num]; } - static void deallocate(T* ptr, unsigned) { delete [] ptr; } - }; - - // Single object allocator. It's also can be replaced with your custom - // allocator. The difference is that it can only allocate a single - // object and the constructor and destructor must be called. - // In AGG there is no need to allocate an array of objects with - // calling their constructors (only single ones). So that, if you - // replace these new/delete to malloc/free make sure that the in-place - // new is called and take care of calling the destructor too. - //------------------------------------------------------------obj_allocator - template struct obj_allocator - { - static T* allocate() { return new T; } - static void deallocate(T* ptr) { delete ptr; } - }; -} -#endif - - -//-------------------------------------------------------- Default basic types -// -// If the compiler has different capacity of the basic types you can redefine -// them via the compiler command line or by generating agg_config.h that is -// empty by default. -// -#ifndef AGG_INT8 -#define AGG_INT8 signed char -#endif - -#ifndef AGG_INT8U -#define AGG_INT8U unsigned char -#endif - -#ifndef AGG_INT16 -#define AGG_INT16 short -#endif - -#ifndef AGG_INT16U -#define AGG_INT16U unsigned short -#endif - -#ifndef AGG_INT32 -#define AGG_INT32 int -#endif - -#ifndef AGG_INT32U -#define AGG_INT32U unsigned -#endif - -#ifndef AGG_INT64 -#if defined(_MSC_VER) || defined(__BORLANDC__) -#define AGG_INT64 signed __int64 -#else -#define AGG_INT64 signed long long -#endif -#endif - -#ifndef AGG_INT64U -#if defined(_MSC_VER) || defined(__BORLANDC__) -#define AGG_INT64U unsigned __int64 -#else -#define AGG_INT64U unsigned long long -#endif -#endif - -//------------------------------------------------ Some fixes for MS Visual C++ -#if defined(_MSC_VER) -#pragma warning(disable:4786) // Identifier was truncated... -#endif - -#if defined(_MSC_VER) -#define AGG_INLINE __forceinline -#else -#define AGG_INLINE inline -#endif - -namespace kiva_gl_agg -{ - //------------------------------------------------------------------------- - typedef AGG_INT8 int8; //----int8 - typedef AGG_INT8U int8u; //----int8u - typedef AGG_INT16 int16; //----int16 - typedef AGG_INT16U int16u; //----int16u - typedef AGG_INT32 int32; //----int32 - typedef AGG_INT32U int32u; //----int32u - typedef AGG_INT64 int64; //----int64 - typedef AGG_INT64U int64u; //----int64u - -#if defined(AGG_FISTP) -#pragma warning(push) -#pragma warning(disable : 4035) //Disable warning "no return value" - AGG_INLINE int iround(double v) //-------iround - { - int t; - __asm fld qword ptr [v] - __asm fistp dword ptr [t] - __asm mov eax, dword ptr [t] - } - AGG_INLINE unsigned uround(double v) //-------uround - { - unsigned t; - __asm fld qword ptr [v] - __asm fistp dword ptr [t] - __asm mov eax, dword ptr [t] - } -#pragma warning(pop) - AGG_INLINE int ifloor(double v) - { - return int(floor(v)); - } - AGG_INLINE unsigned ufloor(double v) //-------ufloor - { - return unsigned(floor(v)); - } - AGG_INLINE int iceil(double v) - { - return int(ceil(v)); - } - AGG_INLINE unsigned uceil(double v) //--------uceil - { - return unsigned(ceil(v)); - } -#elif defined(AGG_QIFIST) - AGG_INLINE int iround(double v) - { - return int(v); - } - AGG_INLINE int uround(double v) - { - return unsigned(v); - } - AGG_INLINE int ifloor(double v) - { - return int(floor(v)); - } - AGG_INLINE unsigned ufloor(double v) - { - return unsigned(floor(v)); - } - AGG_INLINE int iceil(double v) - { - return int(ceil(v)); - } - AGG_INLINE unsigned uceil(double v) - { - return unsigned(ceil(v)); - } -#else - AGG_INLINE int iround(double v) - { - return int((v < 0.0) ? v - 0.5 : v + 0.5); - } - AGG_INLINE int uround(double v) - { - return unsigned(v + 0.5); - } - AGG_INLINE int ifloor(double v) - { - int i = int(v); - return i - (i > v); - } - AGG_INLINE unsigned ufloor(double v) - { - return unsigned(v); - } - AGG_INLINE int iceil(double v) - { - return int(ceil(v)); - } - AGG_INLINE unsigned uceil(double v) - { - return unsigned(ceil(v)); - } -#endif - - //---------------------------------------------------------------saturation - template struct saturation - { - AGG_INLINE static int iround(double v) - { - if(v < double(-Limit)) return -Limit; - if(v > double( Limit)) return Limit; - return kiva_gl_agg::iround(v); - } - }; - - //------------------------------------------------------------------mul_one - template struct mul_one - { - AGG_INLINE static unsigned mul(unsigned a, unsigned b) - { - register unsigned q = a * b + (1 << (Shift-1)); - return (q + (q >> Shift)) >> Shift; - } - }; - - //------------------------------------------------------------------------- - typedef unsigned char cover_type; //----cover_type - enum cover_scale_e - { - cover_shift = 8, //----cover_shift - cover_size = 1 << cover_shift, //----cover_size - cover_mask = cover_size - 1, //----cover_mask - cover_none = 0, //----cover_none - cover_full = cover_mask //----cover_full - }; - - //----------------------------------------------------poly_subpixel_scale_e - // These constants determine the subpixel accuracy, to be more precise, - // the number of bits of the fractional part of the coordinates. - // The possible coordinate capacity in bits can be calculated by formula: - // sizeof(int) * 8 - poly_subpixel_shift, i.e, for 32-bit integers and - // 8-bits fractional part the capacity is 24 bits. - enum poly_subpixel_scale_e - { - poly_subpixel_shift = 8, //----poly_subpixel_shift - poly_subpixel_scale = 1< struct rect_base - { - typedef T value_type; - typedef rect_base self_type; - T x1, y1, x2, y2; - - rect_base() {} - rect_base(T x1_, T y1_, T x2_, T y2_) : - x1(x1_), y1(y1_), x2(x2_), y2(y2_) {} - - void init(T x1_, T y1_, T x2_, T y2_) - { - x1 = x1_; y1 = y1_; x2 = x2_; y2 = y2_; - } - - const self_type& normalize() - { - T t; - if(x1 > x2) { t = x1; x1 = x2; x2 = t; } - if(y1 > y2) { t = y1; y1 = y2; y2 = t; } - return *this; - } - - bool clip(const self_type& r) - { - if(x2 > r.x2) x2 = r.x2; - if(y2 > r.y2) y2 = r.y2; - if(x1 < r.x1) x1 = r.x1; - if(y1 < r.y1) y1 = r.y1; - return x1 <= x2 && y1 <= y2; - } - - bool is_valid() const - { - return x1 <= x2 && y1 <= y2; - } - - bool hit_test(T x, T y) const - { - return (x >= x1 && x <= x2 && y >= y1 && y <= y2); - } - - bool overlaps(const self_type& r) const - { - return !(r.x1 > x2 || r.x2 < x1 - || r.y1 > y2 || r.y2 < y1); - } - }; - - //-----------------------------------------------------intersect_rectangles - template - inline Rect intersect_rectangles(const Rect& r1, const Rect& r2) - { - Rect r = r1; - - // First process x2,y2 because the other order - // results in Internal Compiler Error under - // Microsoft Visual C++ .NET 2003 69462-335-0000007-18038 in - // case of "Maximize Speed" optimization option. - //----------------- - if(r.x2 > r2.x2) r.x2 = r2.x2; - if(r.y2 > r2.y2) r.y2 = r2.y2; - if(r.x1 < r2.x1) r.x1 = r2.x1; - if(r.y1 < r2.y1) r.y1 = r2.y1; - return r; - } - - - //---------------------------------------------------------unite_rectangles - template - inline Rect unite_rectangles(const Rect& r1, const Rect& r2) - { - Rect r = r1; - if(r.x2 < r2.x2) r.x2 = r2.x2; - if(r.y2 < r2.y2) r.y2 = r2.y2; - if(r.x1 > r2.x1) r.x1 = r2.x1; - if(r.y1 > r2.y1) r.y1 = r2.y1; - return r; - } - - typedef rect_base rect_i; //----rect_i - typedef rect_base rect_f; //----rect_f - typedef rect_base rect_d; //----rect_d - - //---------------------------------------------------------path_commands_e - enum path_commands_e - { - path_cmd_stop = 0, //----path_cmd_stop - path_cmd_move_to = 1, //----path_cmd_move_to - path_cmd_line_to = 2, //----path_cmd_line_to - path_cmd_curve3 = 3, //----path_cmd_curve3 - path_cmd_curve4 = 4, //----path_cmd_curve4 - path_cmd_curveN = 5, //----path_cmd_curveN - path_cmd_catrom = 6, //----path_cmd_catrom - path_cmd_ubspline = 7, //----path_cmd_ubspline - path_cmd_end_poly = 0x0F, //----path_cmd_end_poly - path_cmd_mask = 0x0F //----path_cmd_mask - }; - - //------------------------------------------------------------path_flags_e - enum path_flags_e - { - path_flags_none = 0, //----path_flags_none - path_flags_ccw = 0x10, //----path_flags_ccw - path_flags_cw = 0x20, //----path_flags_cw - path_flags_close = 0x40, //----path_flags_close - path_flags_mask = 0xF0 //----path_flags_mask - }; - - //---------------------------------------------------------------is_vertex - inline bool is_vertex(unsigned c) - { - return c >= path_cmd_move_to && c < path_cmd_end_poly; - } - - //--------------------------------------------------------------is_drawing - inline bool is_drawing(unsigned c) - { - return c >= path_cmd_line_to && c < path_cmd_end_poly; - } - - //-----------------------------------------------------------------is_stop - inline bool is_stop(unsigned c) - { - return c == path_cmd_stop; - } - - //--------------------------------------------------------------is_move_to - inline bool is_move_to(unsigned c) - { - return c == path_cmd_move_to; - } - - //--------------------------------------------------------------is_line_to - inline bool is_line_to(unsigned c) - { - return c == path_cmd_line_to; - } - - //----------------------------------------------------------------is_curve - inline bool is_curve(unsigned c) - { - return c == path_cmd_curve3 || c == path_cmd_curve4; - } - - //---------------------------------------------------------------is_curve3 - inline bool is_curve3(unsigned c) - { - return c == path_cmd_curve3; - } - - //---------------------------------------------------------------is_curve4 - inline bool is_curve4(unsigned c) - { - return c == path_cmd_curve4; - } - - //-------------------------------------------------------------is_end_poly - inline bool is_end_poly(unsigned c) - { - return (c & path_cmd_mask) == path_cmd_end_poly; - } - - //----------------------------------------------------------------is_close - inline bool is_close(unsigned c) - { - return (c & ~(path_flags_cw | path_flags_ccw)) == - (path_cmd_end_poly | path_flags_close); - } - - //------------------------------------------------------------is_next_poly - inline bool is_next_poly(unsigned c) - { - return is_stop(c) || is_move_to(c) || is_end_poly(c); - } - - //-------------------------------------------------------------------is_cw - inline bool is_cw(unsigned c) - { - return (c & path_flags_cw) != 0; - } - - //------------------------------------------------------------------is_ccw - inline bool is_ccw(unsigned c) - { - return (c & path_flags_ccw) != 0; - } - - //-------------------------------------------------------------is_oriented - inline bool is_oriented(unsigned c) - { - return (c & (path_flags_cw | path_flags_ccw)) != 0; - } - - //---------------------------------------------------------------is_closed - inline bool is_closed(unsigned c) - { - return (c & path_flags_close) != 0; - } - - //----------------------------------------------------------get_close_flag - inline unsigned get_close_flag(unsigned c) - { - return c & path_flags_close; - } - - //-------------------------------------------------------clear_orientation - inline unsigned clear_orientation(unsigned c) - { - return c & ~(path_flags_cw | path_flags_ccw); - } - - //---------------------------------------------------------get_orientation - inline unsigned get_orientation(unsigned c) - { - return c & (path_flags_cw | path_flags_ccw); - } - - //---------------------------------------------------------set_orientation - inline unsigned set_orientation(unsigned c, unsigned o) - { - return clear_orientation(c) | o; - } - - //--------------------------------------------------------------point_base - template struct point_base - { - typedef T value_type; - T x,y; - point_base() {} - point_base(T x_, T y_) : x(x_), y(y_) {} - }; - typedef point_base point_i; //-----point_i - typedef point_base point_f; //-----point_f - typedef point_base point_d; //-----point_d - - //-------------------------------------------------------------vertex_base - template struct vertex_base - { - typedef T value_type; - T x,y; - unsigned cmd; - vertex_base() {} - vertex_base(T x_, T y_, unsigned cmd_) : x(x_), y(y_), cmd(cmd_) {} - }; - typedef vertex_base vertex_i; //-----vertex_i - typedef vertex_base vertex_f; //-----vertex_f - typedef vertex_base vertex_d; //-----vertex_d - - //----------------------------------------------------------------row_info - template struct row_info - { - int x1, x2; - T* ptr; - row_info() {} - row_info(int x1_, int x2_, T* ptr_) : x1(x1_), x2(x2_), ptr(ptr_) {} - }; - - //----------------------------------------------------------const_row_info - template struct const_row_info - { - int x1, x2; - const T* ptr; - const_row_info() {} - const_row_info(int x1_, int x2_, const T* ptr_) : - x1(x1_), x2(x2_), ptr(ptr_) {} - }; - - //------------------------------------------------------------is_equal_eps - template inline bool is_equal_eps(T v1, T v2, T epsilon) - { - return fabs(v1 - v2) <= double(epsilon); - } -} - - -#endif - diff --git a/kiva/gl/src/agg/agg_bezier_arc.cpp b/kiva/gl/src/agg/agg_bezier_arc.cpp deleted file mode 100644 index c499c23a8..000000000 --- a/kiva/gl/src/agg/agg_bezier_arc.cpp +++ /dev/null @@ -1,255 +0,0 @@ -//---------------------------------------------------------------------------- -// Anti-Grain Geometry - Version 2.4 -// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) -// -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. -// This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// Arc generator. Produces at most 4 consecutive cubic bezier curves, i.e., -// 4, 7, 10, or 13 vertices. -// -//---------------------------------------------------------------------------- - -#include -#include "agg_bezier_arc.h" - -namespace kiva_gl_agg -{ - - // This epsilon is used to prevent us from adding degenerate curves - // (converging to a single point). - // The value isn't very critical. Function arc_to_bezier() has a limit - // of the sweep_angle. If fabs(sweep_angle) exceeds pi/2 the curve - // becomes inaccurate. But slight exceeding is quite appropriate. - //-------------------------------------------------bezier_arc_angle_epsilon - const double bezier_arc_angle_epsilon = 0.01; - - //------------------------------------------------------------arc_to_bezier - void arc_to_bezier(double cx, double cy, double rx, double ry, - double start_angle, double sweep_angle, - double* curve) - { - double x0 = cos(sweep_angle / 2.0); - double y0 = sin(sweep_angle / 2.0); - double tx = (1.0 - x0) * 4.0 / 3.0; - double ty = y0 - tx * x0 / y0; - double px[4]; - double py[4]; - px[0] = x0; - py[0] = -y0; - px[1] = x0 + tx; - py[1] = -ty; - px[2] = x0 + tx; - py[2] = ty; - px[3] = x0; - py[3] = y0; - - double sn = sin(start_angle + sweep_angle / 2.0); - double cs = cos(start_angle + sweep_angle / 2.0); - - unsigned i; - for(i = 0; i < 4; i++) - { - curve[i * 2] = cx + rx * (px[i] * cs - py[i] * sn); - curve[i * 2 + 1] = cy + ry * (px[i] * sn + py[i] * cs); - } - } - - - - //------------------------------------------------------------------------ - void bezier_arc::init(double x, double y, - double rx, double ry, - double start_angle, - double sweep_angle) - { - start_angle = fmod(start_angle, 2.0 * pi); - if(sweep_angle >= 2.0 * pi) sweep_angle = 2.0 * pi; - if(sweep_angle <= -2.0 * pi) sweep_angle = -2.0 * pi; - - if(fabs(sweep_angle) < 1e-10) - { - m_num_vertices = 4; - m_cmd = path_cmd_line_to; - m_vertices[0] = x + rx * cos(start_angle); - m_vertices[1] = y + ry * sin(start_angle); - m_vertices[2] = x + rx * cos(start_angle + sweep_angle); - m_vertices[3] = y + ry * sin(start_angle + sweep_angle); - return; - } - - double total_sweep = 0.0; - double local_sweep = 0.0; - double prev_sweep; - m_num_vertices = 2; - m_cmd = path_cmd_curve4; - bool done = false; - do - { - if(sweep_angle < 0.0) - { - prev_sweep = total_sweep; - local_sweep = -pi * 0.5; - total_sweep -= pi * 0.5; - if(total_sweep <= sweep_angle + bezier_arc_angle_epsilon) - { - local_sweep = sweep_angle - prev_sweep; - done = true; - } - } - else - { - prev_sweep = total_sweep; - local_sweep = pi * 0.5; - total_sweep += pi * 0.5; - if(total_sweep >= sweep_angle - bezier_arc_angle_epsilon) - { - local_sweep = sweep_angle - prev_sweep; - done = true; - } - } - - arc_to_bezier(x, y, rx, ry, - start_angle, - local_sweep, - m_vertices + m_num_vertices - 2); - - m_num_vertices += 6; - start_angle += local_sweep; - } - while(!done && m_num_vertices < 26); - } - - - - - //-------------------------------------------------------------------- - void bezier_arc_svg::init(double x0, double y0, - double rx, double ry, - double angle, - bool large_arc_flag, - bool sweep_flag, - double x2, double y2) - { - m_radii_ok = true; - - if(rx < 0.0) rx = -rx; - if(ry < 0.0) ry = -rx; - - // Calculate the middle point between - // the current and the final points - //------------------------ - double dx2 = (x0 - x2) / 2.0; - double dy2 = (y0 - y2) / 2.0; - - double cos_a = cos(angle); - double sin_a = sin(angle); - - // Calculate (x1, y1) - //------------------------ - double x1 = cos_a * dx2 + sin_a * dy2; - double y1 = -sin_a * dx2 + cos_a * dy2; - - // Ensure radii are large enough - //------------------------ - double prx = rx * rx; - double pry = ry * ry; - double px1 = x1 * x1; - double py1 = y1 * y1; - - // Check that radii are large enough - //------------------------ - double radii_check = px1/prx + py1/pry; - if(radii_check > 1.0) - { - rx = sqrt(radii_check) * rx; - ry = sqrt(radii_check) * ry; - prx = rx * rx; - pry = ry * ry; - if(radii_check > 10.0) m_radii_ok = false; - } - - // Calculate (cx1, cy1) - //------------------------ - double sign = (large_arc_flag == sweep_flag) ? -1.0 : 1.0; - double sq = (prx*pry - prx*py1 - pry*px1) / (prx*py1 + pry*px1); - double coef = sign * sqrt((sq < 0) ? 0 : sq); - double cx1 = coef * ((rx * y1) / ry); - double cy1 = coef * -((ry * x1) / rx); - - // - // Calculate (cx, cy) from (cx1, cy1) - //------------------------ - double sx2 = (x0 + x2) / 2.0; - double sy2 = (y0 + y2) / 2.0; - double cx = sx2 + (cos_a * cx1 - sin_a * cy1); - double cy = sy2 + (sin_a * cx1 + cos_a * cy1); - - // Calculate the start_angle (angle1) and the sweep_angle (dangle) - //------------------------ - double ux = (x1 - cx1) / rx; - double uy = (y1 - cy1) / ry; - double vx = (-x1 - cx1) / rx; - double vy = (-y1 - cy1) / ry; - double p, n; - - // Calculate the angle start - //------------------------ - n = sqrt(ux*ux + uy*uy); - p = ux; // (1 * ux) + (0 * uy) - sign = (uy < 0) ? -1.0 : 1.0; - double v = p / n; - if(v < -1.0) v = -1.0; - if(v > 1.0) v = 1.0; - double start_angle = sign * acos(v); - - // Calculate the sweep angle - //------------------------ - n = sqrt((ux*ux + uy*uy) * (vx*vx + vy*vy)); - p = ux * vx + uy * vy; - sign = (ux * vy - uy * vx < 0) ? -1.0 : 1.0; - v = p / n; - if(v < -1.0) v = -1.0; - if(v > 1.0) v = 1.0; - double sweep_angle = sign * acos(v); - if(!sweep_flag && sweep_angle > 0) - { - sweep_angle -= pi * 2.0; - } - else - if (sweep_flag && sweep_angle < 0) - { - sweep_angle += pi * 2.0; - } - - // We can now build and transform the resulting arc - //------------------------ - m_arc.init(0.0, 0.0, rx, ry, start_angle, sweep_angle); - trans_affine mtx = trans_affine_rotation(angle); - mtx *= trans_affine_translation(cx, cy); - - for(unsigned i = 2; i < m_arc.num_vertices()-2; i += 2) - { - mtx.transform(m_arc.vertices() + i, m_arc.vertices() + i + 1); - } - - // We must make sure that the starting and ending points - // exactly coincide with the initial (x0,y0) and (x2,y2) - m_arc.vertices()[0] = x0; - m_arc.vertices()[1] = y0; - if(m_arc.num_vertices() > 2) - { - m_arc.vertices()[m_arc.num_vertices() - 2] = x2; - m_arc.vertices()[m_arc.num_vertices() - 1] = y2; - } - } - -} diff --git a/kiva/gl/src/agg/agg_bezier_arc.h b/kiva/gl/src/agg/agg_bezier_arc.h deleted file mode 100644 index 85fba1c0e..000000000 --- a/kiva/gl/src/agg/agg_bezier_arc.h +++ /dev/null @@ -1,154 +0,0 @@ -//---------------------------------------------------------------------------- -// Anti-Grain Geometry - Version 2.4 -// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) -// -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. -// This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// Arc generator. Produces at most 4 consecutive cubic bezier curves, i.e., -// 4, 7, 10, or 13 vertices. -// -//---------------------------------------------------------------------------- - -#ifndef AGG_BEZIER_ARC_INCLUDED -#define AGG_BEZIER_ARC_INCLUDED - -#include "agg_conv_transform.h" - -namespace kiva_gl_agg -{ - - //----------------------------------------------------------------------- - void arc_to_bezier(double cx, double cy, double rx, double ry, - double start_angle, double sweep_angle, - double* curve); - - //==============================================================bezier_arc - // - // See implemantaion agg_bezier_arc.cpp - // - class bezier_arc - { - public: - //-------------------------------------------------------------------- - bezier_arc() : m_vertex(26), m_num_vertices(0), m_cmd(path_cmd_line_to) {} - bezier_arc(double x, double y, - double rx, double ry, - double start_angle, - double sweep_angle) - { - init(x, y, rx, ry, start_angle, sweep_angle); - } - - //-------------------------------------------------------------------- - void init(double x, double y, - double rx, double ry, - double start_angle, - double sweep_angle); - - //-------------------------------------------------------------------- - void rewind(unsigned) - { - m_vertex = 0; - } - - //-------------------------------------------------------------------- - unsigned vertex(double* x, double* y) - { - if(m_vertex >= m_num_vertices) return path_cmd_stop; - *x = m_vertices[m_vertex]; - *y = m_vertices[m_vertex + 1]; - m_vertex += 2; - return (m_vertex == 2) ? path_cmd_move_to : m_cmd; - } - - // Supplemantary functions. num_vertices() actually returns doubled - // number of vertices. That is, for 1 vertex it returns 2. - //-------------------------------------------------------------------- - unsigned num_vertices() const { return m_num_vertices; } - const double* vertices() const { return m_vertices; } - double* vertices() { return m_vertices; } - - private: - unsigned m_vertex; - unsigned m_num_vertices; - double m_vertices[26]; - unsigned m_cmd; - }; - - - - //==========================================================bezier_arc_svg - // Compute an SVG-style bezier arc. - // - // Computes an elliptical arc from (x1, y1) to (x2, y2). The size and - // orientation of the ellipse are defined by two radii (rx, ry) - // and an x-axis-rotation, which indicates how the ellipse as a whole - // is rotated relative to the current coordinate system. The center - // (cx, cy) of the ellipse is calculated automatically to satisfy the - // constraints imposed by the other parameters. - // large-arc-flag and sweep-flag contribute to the automatic calculations - // and help determine how the arc is drawn. - class bezier_arc_svg - { - public: - //-------------------------------------------------------------------- - bezier_arc_svg() : m_arc(), m_radii_ok(false) {} - - bezier_arc_svg(double x1, double y1, - double rx, double ry, - double angle, - bool large_arc_flag, - bool sweep_flag, - double x2, double y2) : - m_arc(), m_radii_ok(false) - { - init(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2); - } - - //-------------------------------------------------------------------- - void init(double x1, double y1, - double rx, double ry, - double angle, - bool large_arc_flag, - bool sweep_flag, - double x2, double y2); - - //-------------------------------------------------------------------- - bool radii_ok() const { return m_radii_ok; } - - //-------------------------------------------------------------------- - void rewind(unsigned) - { - m_arc.rewind(0); - } - - //-------------------------------------------------------------------- - unsigned vertex(double* x, double* y) - { - return m_arc.vertex(x, y); - } - - // Supplemantary functions. num_vertices() actually returns doubled - // number of vertices. That is, for 1 vertex it returns 2. - //-------------------------------------------------------------------- - unsigned num_vertices() const { return m_arc.num_vertices(); } - const double* vertices() const { return m_arc.vertices(); } - double* vertices() { return m_arc.vertices(); } - - private: - bezier_arc m_arc; - bool m_radii_ok; - }; - -} - -#endif diff --git a/kiva/gl/src/agg/agg_color_rgba.h b/kiva/gl/src/agg/agg_color_rgba.h deleted file mode 100644 index f2987884a..000000000 --- a/kiva/gl/src/agg/agg_color_rgba.h +++ /dev/null @@ -1,1351 +0,0 @@ -//---------------------------------------------------------------------------- -// Anti-Grain Geometry - Version 2.4 -// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) -// -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. -// This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -//---------------------------------------------------------------------------- -// -// Adaptation for high precision colors has been sponsored by -// Liberty Technology Systems, Inc., visit http://lib-sys.com -// -// Liberty Technology Systems, Inc. is the provider of -// PostScript and PDF technology for software developers. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_COLOR_RGBA_INCLUDED -#define AGG_COLOR_RGBA_INCLUDED - -#include -#include "agg_basics.h" -#include "agg_gamma_lut.h" - -namespace kiva_gl_agg -{ - // Supported component orders for RGB and RGBA pixel formats - //======================================================================= - struct order_rgb { enum rgb_e { R=0, G=1, B=2, N=3 }; }; - struct order_bgr { enum bgr_e { B=0, G=1, R=2, N=3 }; }; - struct order_rgba { enum rgba_e { R=0, G=1, B=2, A=3, N=4 }; }; - struct order_argb { enum argb_e { A=0, R=1, G=2, B=3, N=4 }; }; - struct order_abgr { enum abgr_e { A=0, B=1, G=2, R=3, N=4 }; }; - struct order_bgra { enum bgra_e { B=0, G=1, R=2, A=3, N=4 }; }; - - // Colorspace tag types. - struct linear {}; - struct sRGB {}; - - //====================================================================rgba - struct rgba - { - typedef double value_type; - - double r; - double g; - double b; - double a; - - //-------------------------------------------------------------------- - rgba() {} - - //-------------------------------------------------------------------- - rgba(double r_, double g_, double b_, double a_=1.0) : - r(r_), g(g_), b(b_), a(a_) {} - - //-------------------------------------------------------------------- - rgba(const rgba& c, double a_) : r(c.r), g(c.g), b(c.b), a(a_) {} - - //-------------------------------------------------------------------- - rgba& clear() - { - r = g = b = a = 0; - return *this; - } - - //-------------------------------------------------------------------- - rgba& transparent() - { - a = 0; - return *this; - } - - //-------------------------------------------------------------------- - rgba& opacity(double a_) - { - if (a_ < 0) a = 0; - else if (a_ > 1) a = 1; - else a = a_; - return *this; - } - - //-------------------------------------------------------------------- - double opacity() const - { - return a; - } - - //-------------------------------------------------------------------- - rgba& premultiply() - { - r *= a; - g *= a; - b *= a; - return *this; - } - - //-------------------------------------------------------------------- - rgba& premultiply(double a_) - { - if (a <= 0 || a_ <= 0) - { - r = g = b = a = 0; - } - else - { - a_ /= a; - r *= a_; - g *= a_; - b *= a_; - a = a_; - } - return *this; - } - - //-------------------------------------------------------------------- - rgba& demultiply() - { - if (a == 0) - { - r = g = b = 0; - } - else - { - double a_ = 1.0 / a; - r *= a_; - g *= a_; - b *= a_; - } - return *this; - } - - - //-------------------------------------------------------------------- - rgba gradient(rgba c, double k) const - { - rgba ret; - ret.r = r + (c.r - r) * k; - ret.g = g + (c.g - g) * k; - ret.b = b + (c.b - b) * k; - ret.a = a + (c.a - a) * k; - return ret; - } - - rgba& operator+=(const rgba& c) - { - r += c.r; - g += c.g; - b += c.b; - a += c.a; - return *this; - } - - rgba& operator*=(double k) - { - r *= k; - g *= k; - b *= k; - a *= k; - return *this; - } - - //-------------------------------------------------------------------- - static rgba no_color() { return rgba(0,0,0,0); } - - //-------------------------------------------------------------------- - static rgba from_wavelength(double wl, double gamma = 1.0); - - //-------------------------------------------------------------------- - explicit rgba(double wavelen, double gamma=1.0) - { - *this = from_wavelength(wavelen, gamma); - } - - }; - - inline rgba operator+(const rgba& a, const rgba& b) - { - return rgba(a) += b; - } - - inline rgba operator*(const rgba& a, double b) - { - return rgba(a) *= b; - } - - //------------------------------------------------------------------------ - inline rgba rgba::from_wavelength(double wl, double gamma) - { - rgba t(0.0, 0.0, 0.0); - - if (wl >= 380.0 && wl <= 440.0) - { - t.r = -1.0 * (wl - 440.0) / (440.0 - 380.0); - t.b = 1.0; - } - else if (wl >= 440.0 && wl <= 490.0) - { - t.g = (wl - 440.0) / (490.0 - 440.0); - t.b = 1.0; - } - else if (wl >= 490.0 && wl <= 510.0) - { - t.g = 1.0; - t.b = -1.0 * (wl - 510.0) / (510.0 - 490.0); - } - else if (wl >= 510.0 && wl <= 580.0) - { - t.r = (wl - 510.0) / (580.0 - 510.0); - t.g = 1.0; - } - else if (wl >= 580.0 && wl <= 645.0) - { - t.r = 1.0; - t.g = -1.0 * (wl - 645.0) / (645.0 - 580.0); - } - else if (wl >= 645.0 && wl <= 780.0) - { - t.r = 1.0; - } - - double s = 1.0; - if (wl > 700.0) s = 0.3 + 0.7 * (780.0 - wl) / (780.0 - 700.0); - else if (wl < 420.0) s = 0.3 + 0.7 * (wl - 380.0) / (420.0 - 380.0); - - t.r = pow(t.r * s, gamma); - t.g = pow(t.g * s, gamma); - t.b = pow(t.b * s, gamma); - return t; - } - - inline rgba rgba_pre(double r, double g, double b, double a) - { - return rgba(r, g, b, a).premultiply(); - } - - - //===================================================================rgba8 - template - struct rgba8T - { - typedef int8u value_type; - typedef int32u calc_type; - typedef int32 long_type; - enum base_scale_e - { - base_shift = 8, - base_scale = 1 << base_shift, - base_mask = base_scale - 1, - base_MSB = 1 << (base_shift - 1) - }; - typedef rgba8T self_type; - - - value_type r; - value_type g; - value_type b; - value_type a; - - static void convert(rgba8T& dst, const rgba8T& src) - { - dst.r = sRGB_conv::rgb_from_sRGB(src.r); - dst.g = sRGB_conv::rgb_from_sRGB(src.g); - dst.b = sRGB_conv::rgb_from_sRGB(src.b); - dst.a = src.a; - } - - static void convert(rgba8T& dst, const rgba8T& src) - { - dst.r = sRGB_conv::rgb_to_sRGB(src.r); - dst.g = sRGB_conv::rgb_to_sRGB(src.g); - dst.b = sRGB_conv::rgb_to_sRGB(src.b); - dst.a = src.a; - } - - static void convert(rgba8T& dst, const rgba& src) - { - dst.r = value_type(uround(src.r * base_mask)); - dst.g = value_type(uround(src.g * base_mask)); - dst.b = value_type(uround(src.b * base_mask)); - dst.a = value_type(uround(src.a * base_mask)); - } - - static void convert(rgba8T& dst, const rgba& src) - { - // Use the "float" table. - dst.r = sRGB_conv::rgb_to_sRGB(float(src.r)); - dst.g = sRGB_conv::rgb_to_sRGB(float(src.g)); - dst.b = sRGB_conv::rgb_to_sRGB(float(src.b)); - dst.a = sRGB_conv::alpha_to_sRGB(float(src.a)); - } - - static void convert(rgba& dst, const rgba8T& src) - { - dst.r = src.r / 255.0; - dst.g = src.g / 255.0; - dst.b = src.b / 255.0; - dst.a = src.a / 255.0; - } - - static void convert(rgba& dst, const rgba8T& src) - { - // Use the "float" table. - dst.r = sRGB_conv::rgb_from_sRGB(src.r); - dst.g = sRGB_conv::rgb_from_sRGB(src.g); - dst.b = sRGB_conv::rgb_from_sRGB(src.b); - dst.a = sRGB_conv::alpha_from_sRGB(src.a); - } - - //-------------------------------------------------------------------- - rgba8T() {} - - //-------------------------------------------------------------------- - rgba8T(unsigned r_, unsigned g_, unsigned b_, unsigned a_ = base_mask) : - r(value_type(r_)), - g(value_type(g_)), - b(value_type(b_)), - a(value_type(a_)) {} - - //-------------------------------------------------------------------- - rgba8T(const rgba& c) - { - convert(*this, c); - } - - //-------------------------------------------------------------------- - rgba8T(const self_type& c, unsigned a_) : - r(c.r), g(c.g), b(c.b), a(value_type(a_)) {} - - //-------------------------------------------------------------------- - template - rgba8T(const rgba8T& c) - { - convert(*this, c); - } - - //-------------------------------------------------------------------- - operator rgba() const - { - rgba c; - convert(c, *this); - return c; - } - - //-------------------------------------------------------------------- - static AGG_INLINE double to_double(value_type a) - { - return double(a) / base_mask; - } - - //-------------------------------------------------------------------- - static AGG_INLINE value_type from_double(double a) - { - return value_type(uround(a * base_mask)); - } - - //-------------------------------------------------------------------- - static AGG_INLINE value_type empty_value() - { - return 0; - } - - //-------------------------------------------------------------------- - static AGG_INLINE value_type full_value() - { - return base_mask; - } - - //-------------------------------------------------------------------- - AGG_INLINE bool is_transparent() const - { - return a == 0; - } - - //-------------------------------------------------------------------- - AGG_INLINE bool is_opaque() const - { - return a == base_mask; - } - - //-------------------------------------------------------------------- - static AGG_INLINE value_type invert(value_type x) - { - return base_mask - x; - } - - //-------------------------------------------------------------------- - // Fixed-point multiply, exact over int8u. - static AGG_INLINE value_type multiply(value_type a, value_type b) - { - calc_type t = a * b + base_MSB; - return value_type(((t >> base_shift) + t) >> base_shift); - } - - //-------------------------------------------------------------------- - static AGG_INLINE value_type demultiply(value_type a, value_type b) - { - if (a * b == 0) - { - return 0; - } - else if (a >= b) - { - return base_mask; - } - else return value_type((a * base_mask + (b >> 1)) / b); - } - - //-------------------------------------------------------------------- - template - static AGG_INLINE T downscale(T a) - { - return a >> base_shift; - } - - //-------------------------------------------------------------------- - template - static AGG_INLINE T downshift(T a, unsigned n) - { - return a >> n; - } - - //-------------------------------------------------------------------- - // Fixed-point multiply, exact over int8u. - // Specifically for multiplying a color component by a cover. - static AGG_INLINE value_type mult_cover(value_type a, cover_type b) - { - return multiply(a, b); - } - - //-------------------------------------------------------------------- - static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) - { - return multiply(b, a); - } - - //-------------------------------------------------------------------- - // Interpolate p to q by a, assuming q is premultiplied by a. - static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) - { - return p + q - multiply(p, a); - } - - //-------------------------------------------------------------------- - // Interpolate p to q by a. - static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) - { - int t = (q - p) * a + base_MSB - (p > q); - return value_type(p + (((t >> base_shift) + t) >> base_shift)); - } - - //-------------------------------------------------------------------- - self_type& clear() - { - r = g = b = a = 0; - return *this; - } - - //-------------------------------------------------------------------- - self_type& transparent() - { - a = 0; - return *this; - } - - //-------------------------------------------------------------------- - self_type& opacity(double a_) - { - if (a_ < 0) a = 0; - else if (a_ > 1) a = 1; - else a = (value_type)uround(a_ * double(base_mask)); - return *this; - } - - //-------------------------------------------------------------------- - double opacity() const - { - return double(a) / double(base_mask); - } - - //-------------------------------------------------------------------- - AGG_INLINE self_type& premultiply() - { - if (a != base_mask) - { - if (a == 0) - { - r = g = b = 0; - } - else - { - r = multiply(r, a); - g = multiply(g, a); - b = multiply(b, a); - } - } - return *this; - } - - //-------------------------------------------------------------------- - AGG_INLINE self_type& premultiply(unsigned a_) - { - if (a != base_mask || a_ < base_mask) - { - if (a == 0 || a_ == 0) - { - r = g = b = a = 0; - } - else - { - calc_type r_ = (calc_type(r) * a_) / a; - calc_type g_ = (calc_type(g) * a_) / a; - calc_type b_ = (calc_type(b) * a_) / a; - r = value_type((r_ > a_) ? a_ : r_); - g = value_type((g_ > a_) ? a_ : g_); - b = value_type((b_ > a_) ? a_ : b_); - a = value_type(a_); - } - } - return *this; - } - - //-------------------------------------------------------------------- - AGG_INLINE self_type& demultiply() - { - if (a < base_mask) - { - if (a == 0) - { - r = g = b = 0; - } - else - { - calc_type r_ = (calc_type(r) * base_mask) / a; - calc_type g_ = (calc_type(g) * base_mask) / a; - calc_type b_ = (calc_type(b) * base_mask) / a; - r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_); - g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_); - b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_); - } - } - return *this; - } - - //-------------------------------------------------------------------- - AGG_INLINE self_type gradient(const self_type& c, double k) const - { - self_type ret; - calc_type ik = uround(k * base_mask); - ret.r = lerp(r, c.r, ik); - ret.g = lerp(g, c.g, ik); - ret.b = lerp(b, c.b, ik); - ret.a = lerp(a, c.a, ik); - return ret; - } - - //-------------------------------------------------------------------- - AGG_INLINE void add(const self_type& c, unsigned cover) - { - calc_type cr, cg, cb, ca; - if (cover == cover_mask) - { - if (c.a == base_mask) - { - *this = c; - return; - } - else - { - cr = r + c.r; - cg = g + c.g; - cb = b + c.b; - ca = a + c.a; - } - } - else - { - cr = r + mult_cover(c.r, cover); - cg = g + mult_cover(c.g, cover); - cb = b + mult_cover(c.b, cover); - ca = a + mult_cover(c.a, cover); - } - r = (value_type)((cr > calc_type(base_mask)) ? calc_type(base_mask) : cr); - g = (value_type)((cg > calc_type(base_mask)) ? calc_type(base_mask) : cg); - b = (value_type)((cb > calc_type(base_mask)) ? calc_type(base_mask) : cb); - a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca); - } - - //-------------------------------------------------------------------- - template - AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma) - { - r = gamma.dir(r); - g = gamma.dir(g); - b = gamma.dir(b); - } - - //-------------------------------------------------------------------- - template - AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma) - { - r = gamma.inv(r); - g = gamma.inv(g); - b = gamma.inv(b); - } - - //-------------------------------------------------------------------- - static self_type no_color() { return self_type(0,0,0,0); } - - //-------------------------------------------------------------------- - static self_type from_wavelength(double wl, double gamma = 1.0) - { - return self_type(rgba::from_wavelength(wl, gamma)); - } - }; - - typedef rgba8T rgba8; - typedef rgba8T srgba8; - - - //-------------------------------------------------------------rgb8_packed - inline rgba8 rgb8_packed(unsigned v) - { - return rgba8((v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF); - } - - //-------------------------------------------------------------bgr8_packed - inline rgba8 bgr8_packed(unsigned v) - { - return rgba8(v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF); - } - - //------------------------------------------------------------argb8_packed - inline rgba8 argb8_packed(unsigned v) - { - return rgba8((v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF, v >> 24); - } - - //---------------------------------------------------------rgba8_gamma_dir - template - rgba8 rgba8_gamma_dir(rgba8 c, const GammaLUT& gamma) - { - return rgba8(gamma.dir(c.r), gamma.dir(c.g), gamma.dir(c.b), c.a); - } - - //---------------------------------------------------------rgba8_gamma_inv - template - rgba8 rgba8_gamma_inv(rgba8 c, const GammaLUT& gamma) - { - return rgba8(gamma.inv(c.r), gamma.inv(c.g), gamma.inv(c.b), c.a); - } - - - - //==================================================================rgba16 - struct rgba16 - { - typedef int16u value_type; - typedef int32u calc_type; - typedef int64 long_type; - enum base_scale_e - { - base_shift = 16, - base_scale = 1 << base_shift, - base_mask = base_scale - 1, - base_MSB = 1 << (base_shift - 1) - }; - typedef rgba16 self_type; - - value_type r; - value_type g; - value_type b; - value_type a; - - //-------------------------------------------------------------------- - rgba16() {} - - //-------------------------------------------------------------------- - rgba16(unsigned r_, unsigned g_, unsigned b_, unsigned a_=base_mask) : - r(value_type(r_)), - g(value_type(g_)), - b(value_type(b_)), - a(value_type(a_)) {} - - //-------------------------------------------------------------------- - rgba16(const self_type& c, unsigned a_) : - r(c.r), g(c.g), b(c.b), a(value_type(a_)) {} - - //-------------------------------------------------------------------- - rgba16(const rgba& c) : - r((value_type)uround(c.r * double(base_mask))), - g((value_type)uround(c.g * double(base_mask))), - b((value_type)uround(c.b * double(base_mask))), - a((value_type)uround(c.a * double(base_mask))) {} - - //-------------------------------------------------------------------- - rgba16(const rgba8& c) : - r(value_type((value_type(c.r) << 8) | c.r)), - g(value_type((value_type(c.g) << 8) | c.g)), - b(value_type((value_type(c.b) << 8) | c.b)), - a(value_type((value_type(c.a) << 8) | c.a)) {} - - //-------------------------------------------------------------------- - rgba16(const srgba8& c) : - r(sRGB_conv::rgb_from_sRGB(c.r)), - g(sRGB_conv::rgb_from_sRGB(c.g)), - b(sRGB_conv::rgb_from_sRGB(c.b)), - a(sRGB_conv::alpha_from_sRGB(c.a)) {} - - //-------------------------------------------------------------------- - operator rgba() const - { - return rgba( - r / 65535.0, - g / 65535.0, - b / 65535.0, - a / 65535.0); - } - - //-------------------------------------------------------------------- - operator rgba8() const - { - return rgba8(r >> 8, g >> 8, b >> 8, a >> 8); - } - - //-------------------------------------------------------------------- - operator srgba8() const - { - // Return (non-premultiplied) sRGB values. - return srgba8( - sRGB_conv::rgb_to_sRGB(r), - sRGB_conv::rgb_to_sRGB(g), - sRGB_conv::rgb_to_sRGB(b), - sRGB_conv::alpha_to_sRGB(a)); - } - - //-------------------------------------------------------------------- - static AGG_INLINE double to_double(value_type a) - { - return double(a) / base_mask; - } - - //-------------------------------------------------------------------- - static AGG_INLINE value_type from_double(double a) - { - return value_type(uround(a * base_mask)); - } - - //-------------------------------------------------------------------- - static AGG_INLINE value_type empty_value() - { - return 0; - } - - //-------------------------------------------------------------------- - static AGG_INLINE value_type full_value() - { - return base_mask; - } - - //-------------------------------------------------------------------- - AGG_INLINE bool is_transparent() const - { - return a == 0; - } - - //-------------------------------------------------------------------- - AGG_INLINE bool is_opaque() const - { - return a == base_mask; - } - - //-------------------------------------------------------------------- - static AGG_INLINE value_type invert(value_type x) - { - return base_mask - x; - } - - //-------------------------------------------------------------------- - // Fixed-point multiply, exact over int16u. - static AGG_INLINE value_type multiply(value_type a, value_type b) - { - calc_type t = a * b + base_MSB; - return value_type(((t >> base_shift) + t) >> base_shift); - } - - //-------------------------------------------------------------------- - static AGG_INLINE value_type demultiply(value_type a, value_type b) - { - if (a * b == 0) - { - return 0; - } - else if (a >= b) - { - return base_mask; - } - else return value_type((a * base_mask + (b >> 1)) / b); - } - - //-------------------------------------------------------------------- - template - static AGG_INLINE T downscale(T a) - { - return a >> base_shift; - } - - //-------------------------------------------------------------------- - template - static AGG_INLINE T downshift(T a, unsigned n) - { - return a >> n; - } - - //-------------------------------------------------------------------- - // Fixed-point multiply, almost exact over int16u. - // Specifically for multiplying a color component by a cover. - static AGG_INLINE value_type mult_cover(value_type a, cover_type b) - { - return multiply(a, (b << 8) | b); - } - - //-------------------------------------------------------------------- - static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) - { - return multiply((a << 8) | a, b) >> 8; - } - - //-------------------------------------------------------------------- - // Interpolate p to q by a, assuming q is premultiplied by a. - static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) - { - return p + q - multiply(p, a); - } - - //-------------------------------------------------------------------- - // Interpolate p to q by a. - static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) - { - int t = (q - p) * a + base_MSB - (p > q); - return value_type(p + (((t >> base_shift) + t) >> base_shift)); - } - - //-------------------------------------------------------------------- - self_type& clear() - { - r = g = b = a = 0; - return *this; - } - - //-------------------------------------------------------------------- - self_type& transparent() - { - a = 0; - return *this; - } - - //-------------------------------------------------------------------- - AGG_INLINE self_type& opacity(double a_) - { - if (a_ < 0) a = 0; - if (a_ > 1) a = 1; - a = value_type(uround(a_ * double(base_mask))); - return *this; - } - - //-------------------------------------------------------------------- - double opacity() const - { - return double(a) / double(base_mask); - } - - //-------------------------------------------------------------------- - AGG_INLINE self_type& premultiply() - { - if (a != base_mask) - { - if (a == 0) - { - r = g = b = 0; - } - else - { - r = multiply(r, a); - g = multiply(g, a); - b = multiply(b, a); - } - } - return *this; - } - - //-------------------------------------------------------------------- - AGG_INLINE self_type& premultiply(unsigned a_) - { - if (a < base_mask || a_ < base_mask) - { - if (a == 0 || a_ == 0) - { - r = g = b = a = 0; - } - else - { - calc_type r_ = (calc_type(r) * a_) / a; - calc_type g_ = (calc_type(g) * a_) / a; - calc_type b_ = (calc_type(b) * a_) / a; - r = value_type((r_ > a_) ? a_ : r_); - g = value_type((g_ > a_) ? a_ : g_); - b = value_type((b_ > a_) ? a_ : b_); - a = value_type(a_); - } - } - return *this; - } - - //-------------------------------------------------------------------- - AGG_INLINE self_type& demultiply() - { - if (a < base_mask) - { - if (a == 0) - { - r = g = b = 0; - } - else - { - calc_type r_ = (calc_type(r) * base_mask) / a; - calc_type g_ = (calc_type(g) * base_mask) / a; - calc_type b_ = (calc_type(b) * base_mask) / a; - r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_); - g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_); - b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_); - } - } - return *this; - } - - //-------------------------------------------------------------------- - AGG_INLINE self_type gradient(const self_type& c, double k) const - { - self_type ret; - calc_type ik = uround(k * base_mask); - ret.r = lerp(r, c.r, ik); - ret.g = lerp(g, c.g, ik); - ret.b = lerp(b, c.b, ik); - ret.a = lerp(a, c.a, ik); - return ret; - } - - //-------------------------------------------------------------------- - AGG_INLINE void add(const self_type& c, unsigned cover) - { - calc_type cr, cg, cb, ca; - if (cover == cover_mask) - { - if (c.a == base_mask) - { - *this = c; - return; - } - else - { - cr = r + c.r; - cg = g + c.g; - cb = b + c.b; - ca = a + c.a; - } - } - else - { - cr = r + mult_cover(c.r, cover); - cg = g + mult_cover(c.g, cover); - cb = b + mult_cover(c.b, cover); - ca = a + mult_cover(c.a, cover); - } - r = (value_type)((cr > calc_type(base_mask)) ? calc_type(base_mask) : cr); - g = (value_type)((cg > calc_type(base_mask)) ? calc_type(base_mask) : cg); - b = (value_type)((cb > calc_type(base_mask)) ? calc_type(base_mask) : cb); - a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca); - } - - //-------------------------------------------------------------------- - template - AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma) - { - r = gamma.dir(r); - g = gamma.dir(g); - b = gamma.dir(b); - } - - //-------------------------------------------------------------------- - template - AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma) - { - r = gamma.inv(r); - g = gamma.inv(g); - b = gamma.inv(b); - } - - //-------------------------------------------------------------------- - static self_type no_color() { return self_type(0,0,0,0); } - - //-------------------------------------------------------------------- - static self_type from_wavelength(double wl, double gamma = 1.0) - { - return self_type(rgba::from_wavelength(wl, gamma)); - } - }; - - - //------------------------------------------------------rgba16_gamma_dir - template - rgba16 rgba16_gamma_dir(rgba16 c, const GammaLUT& gamma) - { - return rgba16(gamma.dir(c.r), gamma.dir(c.g), gamma.dir(c.b), c.a); - } - - //------------------------------------------------------rgba16_gamma_inv - template - rgba16 rgba16_gamma_inv(rgba16 c, const GammaLUT& gamma) - { - return rgba16(gamma.inv(c.r), gamma.inv(c.g), gamma.inv(c.b), c.a); - } - - //====================================================================rgba32 - struct rgba32 - { - typedef float value_type; - typedef double calc_type; - typedef double long_type; - typedef rgba32 self_type; - - value_type r; - value_type g; - value_type b; - value_type a; - - //-------------------------------------------------------------------- - rgba32() {} - - //-------------------------------------------------------------------- - rgba32(value_type r_, value_type g_, value_type b_, value_type a_= 1) : - r(r_), g(g_), b(b_), a(a_) {} - - //-------------------------------------------------------------------- - rgba32(const self_type& c, float a_) : - r(c.r), g(c.g), b(c.b), a(a_) {} - - //-------------------------------------------------------------------- - rgba32(const rgba& c) : - r(value_type(c.r)), g(value_type(c.g)), b(value_type(c.b)), a(value_type(c.a)) {} - - //-------------------------------------------------------------------- - rgba32(const rgba8& c) : - r(value_type(c.r / 255.0)), - g(value_type(c.g / 255.0)), - b(value_type(c.b / 255.0)), - a(value_type(c.a / 255.0)) {} - - //-------------------------------------------------------------------- - rgba32(const srgba8& c) : - r(sRGB_conv::rgb_from_sRGB(c.r)), - g(sRGB_conv::rgb_from_sRGB(c.g)), - b(sRGB_conv::rgb_from_sRGB(c.b)), - a(sRGB_conv::alpha_from_sRGB(c.a)) {} - - //-------------------------------------------------------------------- - rgba32(const rgba16& c) : - r(value_type(c.r / 65535.0)), - g(value_type(c.g / 65535.0)), - b(value_type(c.b / 65535.0)), - a(value_type(c.a / 65535.0)) {} - - //-------------------------------------------------------------------- - operator rgba() const - { - return rgba(r, g, b, a); - } - - //-------------------------------------------------------------------- - operator rgba8() const - { - return rgba8( - uround(r * 255.0), - uround(g * 255.0), - uround(b * 255.0), - uround(a * 255.0)); - } - - //-------------------------------------------------------------------- - operator srgba8() const - { - return srgba8( - sRGB_conv::rgb_to_sRGB(r), - sRGB_conv::rgb_to_sRGB(g), - sRGB_conv::rgb_to_sRGB(b), - sRGB_conv::alpha_to_sRGB(a)); - } - - //-------------------------------------------------------------------- - operator rgba16() const - { - return rgba8( - uround(r * 65535.0), - uround(g * 65535.0), - uround(b * 65535.0), - uround(a * 65535.0)); - } - - //-------------------------------------------------------------------- - static AGG_INLINE double to_double(value_type a) - { - return a; - } - - //-------------------------------------------------------------------- - static AGG_INLINE value_type from_double(double a) - { - return value_type(a); - } - - //-------------------------------------------------------------------- - static AGG_INLINE value_type empty_value() - { - return 0; - } - - //-------------------------------------------------------------------- - static AGG_INLINE value_type full_value() - { - return 1; - } - - //-------------------------------------------------------------------- - AGG_INLINE bool is_transparent() const - { - return a <= 0; - } - - //-------------------------------------------------------------------- - AGG_INLINE bool is_opaque() const - { - return a >= 1; - } - - //-------------------------------------------------------------------- - static AGG_INLINE value_type invert(value_type x) - { - return 1 - x; - } - - //-------------------------------------------------------------------- - static AGG_INLINE value_type multiply(value_type a, value_type b) - { - return value_type(a * b); - } - - //-------------------------------------------------------------------- - static AGG_INLINE value_type demultiply(value_type a, value_type b) - { - return (b == 0) ? 0 : value_type(a / b); - } - - //-------------------------------------------------------------------- - template - static AGG_INLINE T downscale(T a) - { - return a; - } - - //-------------------------------------------------------------------- - template - static AGG_INLINE T downshift(T a, unsigned n) - { - return n > 0 ? a / (1 << n) : a; - } - - //-------------------------------------------------------------------- - static AGG_INLINE value_type mult_cover(value_type a, cover_type b) - { - return value_type(a * b / cover_mask); - } - - //-------------------------------------------------------------------- - static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) - { - return cover_type(uround(a * b)); - } - - //-------------------------------------------------------------------- - // Interpolate p to q by a, assuming q is premultiplied by a. - static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) - { - return (1 - a) * p + q; // more accurate than "p + q - p * a" - } - - //-------------------------------------------------------------------- - // Interpolate p to q by a. - static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) - { - // The form "p + a * (q - p)" avoids a multiplication, but may produce an - // inaccurate result. For example, "p + (q - p)" may not be exactly equal - // to q. Therefore, stick to the basic expression, which at least produces - // the correct result at either extreme. - return (1 - a) * p + a * q; - } - - //-------------------------------------------------------------------- - self_type& clear() - { - r = g = b = a = 0; - return *this; - } - - //-------------------------------------------------------------------- - self_type& transparent() - { - a = 0; - return *this; - } - - //-------------------------------------------------------------------- - AGG_INLINE self_type& opacity(double a_) - { - if (a_ < 0) a = 0; - else if (a_ > 1) a = 1; - else a = value_type(a_); - return *this; - } - - //-------------------------------------------------------------------- - double opacity() const - { - return a; - } - - //-------------------------------------------------------------------- - AGG_INLINE self_type& premultiply() - { - if (a < 1) - { - if (a <= 0) - { - r = g = b = 0; - } - else - { - r *= a; - g *= a; - b *= a; - } - } - return *this; - } - - //-------------------------------------------------------------------- - AGG_INLINE self_type& demultiply() - { - if (a < 1) - { - if (a <= 0) - { - r = g = b = 0; - } - else - { - r /= a; - g /= a; - b /= a; - } - } - return *this; - } - - //-------------------------------------------------------------------- - AGG_INLINE self_type gradient(const self_type& c, double k) const - { - self_type ret; - ret.r = value_type(r + (c.r - r) * k); - ret.g = value_type(g + (c.g - g) * k); - ret.b = value_type(b + (c.b - b) * k); - ret.a = value_type(a + (c.a - a) * k); - return ret; - } - - //-------------------------------------------------------------------- - AGG_INLINE void add(const self_type& c, unsigned cover) - { - if (cover == cover_mask) - { - if (c.is_opaque()) - { - *this = c; - return; - } - else - { - r += c.r; - g += c.g; - b += c.b; - a += c.a; - } - } - else - { - r += mult_cover(c.r, cover); - g += mult_cover(c.g, cover); - b += mult_cover(c.b, cover); - a += mult_cover(c.a, cover); - } - if (a > 1) a = 1; - if (r > a) r = a; - if (g > a) g = a; - if (b > a) b = a; - } - - //-------------------------------------------------------------------- - template - AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma) - { - r = gamma.dir(r); - g = gamma.dir(g); - b = gamma.dir(b); - } - - //-------------------------------------------------------------------- - template - AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma) - { - r = gamma.inv(r); - g = gamma.inv(g); - b = gamma.inv(b); - } - - //-------------------------------------------------------------------- - static self_type no_color() { return self_type(0,0,0,0); } - - //-------------------------------------------------------------------- - static self_type from_wavelength(double wl, double gamma = 1) - { - return self_type(rgba::from_wavelength(wl, gamma)); - } - }; -} - -#endif diff --git a/kiva/gl/src/agg/agg_config.h b/kiva/gl/src/agg/agg_config.h deleted file mode 100644 index 40205e827..000000000 --- a/kiva/gl/src/agg/agg_config.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef AGG_CONFIG_INCLUDED -#define AGG_CONFIG_INCLUDED - -// This file can be used to redefine certain data types. - -//--------------------------------------- -// 1. Default basic types such as: -// -// AGG_INT8 -// AGG_INT8U -// AGG_INT16 -// AGG_INT16U -// AGG_INT32 -// AGG_INT32U -// AGG_INT64 -// AGG_INT64U -// -// Just replace this file with new defines if necessary. -// For example, if your compiler doesn't have a 64 bit integer type -// you can still use AGG if you define the follows: -// -// #define AGG_INT64 int -// #define AGG_INT64U unsigned -// -// It will result in overflow in 16 bit-per-component image/pattern resampling -// but it won't result any crash and the rest of the library will remain -// fully functional. - - -//--------------------------------------- -// 2. Default rendering_buffer type. Can be: -// -// Provides faster access for massive pixel operations, -// such as blur, image filtering: -// #define AGG_RENDERING_BUFFER row_ptr_cache -// -// Provides cheaper creation and destruction (no mem allocs): -// #define AGG_RENDERING_BUFFER row_accessor -// -// You can still use both of them simultaneously in your applications -// This #define is used only for default rendering_buffer type, -// in short hand typedefs like pixfmt_rgba32. - -#endif diff --git a/kiva/gl/src/agg/agg_conv_transform.h b/kiva/gl/src/agg/agg_conv_transform.h deleted file mode 100644 index b3fda33f3..000000000 --- a/kiva/gl/src/agg/agg_conv_transform.h +++ /dev/null @@ -1,67 +0,0 @@ -//---------------------------------------------------------------------------- -// Anti-Grain Geometry - Version 2.4 -// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) -// -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. -// This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// class conv_transform -// -//---------------------------------------------------------------------------- -#ifndef AGG_CONV_TRANSFORM_INCLUDED -#define AGG_CONV_TRANSFORM_INCLUDED - -#include "agg_basics.h" -#include "agg_trans_affine.h" - -namespace kiva_gl_agg -{ - - //----------------------------------------------------------conv_transform - template class conv_transform - { - public: - conv_transform(VertexSource& source, Transformer& tr) : - m_source(&source), m_trans(&tr) {} - void attach(VertexSource& source) { m_source = &source; } - - void rewind(unsigned path_id) - { - m_source->rewind(path_id); - } - - unsigned vertex(double* x, double* y) - { - unsigned cmd = m_source->vertex(x, y); - if(is_vertex(cmd)) - { - m_trans->transform(x, y); - } - return cmd; - } - - void transformer(Transformer& tr) - { - m_trans = &tr; - } - - private: - conv_transform(const conv_transform&); - const conv_transform& - operator = (const conv_transform&); - - VertexSource* m_source; - Transformer* m_trans; - }; - -} - -#endif diff --git a/kiva/gl/src/agg/agg_gamma_functions.h b/kiva/gl/src/agg/agg_gamma_functions.h deleted file mode 100644 index 36676e00f..000000000 --- a/kiva/gl/src/agg/agg_gamma_functions.h +++ /dev/null @@ -1,128 +0,0 @@ -//---------------------------------------------------------------------------- -// Anti-Grain Geometry - Version 2.4 -// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) -// -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. -// This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_GAMMA_FUNCTIONS_INCLUDED -#define AGG_GAMMA_FUNCTIONS_INCLUDED - -#include -#include "agg_basics.h" - -namespace kiva_gl_agg -{ - //===============================================================gamma_none - struct gamma_none - { - double operator()(double x) const { return x; } - }; - - //==============================================================gamma_power - class gamma_power - { - public: - gamma_power() : m_gamma(1.0) {} - gamma_power(double g) : m_gamma(g) {} - - void gamma(double g) { m_gamma = g; } - double gamma() const { return m_gamma; } - - double operator() (double x) const - { - return pow(x, m_gamma); - } - - private: - double m_gamma; - }; - - - //==========================================================gamma_threshold - class gamma_threshold - { - public: - gamma_threshold() : m_threshold(0.5) {} - gamma_threshold(double t) : m_threshold(t) {} - - void threshold(double t) { m_threshold = t; } - double threshold() const { return m_threshold; } - - double operator() (double x) const - { - return (x < m_threshold) ? 0.0 : 1.0; - } - - private: - double m_threshold; - }; - - - //============================================================gamma_linear - class gamma_linear - { - public: - gamma_linear() : m_start(0.0), m_end(1.0) {} - gamma_linear(double s, double e) : m_start(s), m_end(e) {} - - void set(double s, double e) { m_start = s; m_end = e; } - void start(double s) { m_start = s; } - void end(double e) { m_end = e; } - double start() const { return m_start; } - double end() const { return m_end; } - - double operator() (double x) const - { - if(x < m_start) return 0.0; - if(x > m_end) return 1.0; - return (x - m_start) / (m_end - m_start); - } - - private: - double m_start; - double m_end; - }; - - - //==========================================================gamma_multiply - class gamma_multiply - { - public: - gamma_multiply() : m_mul(1.0) {} - gamma_multiply(double v) : m_mul(v) {} - - void value(double v) { m_mul = v; } - double value() const { return m_mul; } - - double operator() (double x) const - { - double y = x * m_mul; - if(y > 1.0) y = 1.0; - return y; - } - - private: - double m_mul; - }; - - inline double sRGB_to_linear(double x) - { - return (x <= 0.04045) ? (x / 12.92) : pow((x + 0.055) / (1.055), 2.4); - } - - inline double linear_to_sRGB(double x) - { - return (x <= 0.0031308) ? (x * 12.92) : (1.055 * pow(x, 1 / 2.4) - 0.055); - } -} - -#endif diff --git a/kiva/gl/src/agg/agg_gamma_lut.h b/kiva/gl/src/agg/agg_gamma_lut.h deleted file mode 100644 index 25570fef2..000000000 --- a/kiva/gl/src/agg/agg_gamma_lut.h +++ /dev/null @@ -1,305 +0,0 @@ -//---------------------------------------------------------------------------- -// Anti-Grain Geometry - Version 2.4 -// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) -// -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. -// This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_GAMMA_LUT_INCLUDED -#define AGG_GAMMA_LUT_INCLUDED - -#include -#include "agg_basics.h" -#include "agg_gamma_functions.h" - -namespace kiva_gl_agg -{ - template class gamma_lut - { - public: - typedef gamma_lut self_type; - - enum gamma_scale_e - { - gamma_shift = GammaShift, - gamma_size = 1 << gamma_shift, - gamma_mask = gamma_size - 1 - }; - - enum hi_res_scale_e - { - hi_res_shift = HiResShift, - hi_res_size = 1 << hi_res_shift, - hi_res_mask = hi_res_size - 1 - }; - - ~gamma_lut() - { - pod_allocator::deallocate(m_inv_gamma, hi_res_size); - pod_allocator::deallocate(m_dir_gamma, gamma_size); - } - - gamma_lut() : - m_gamma(1.0), - m_dir_gamma(pod_allocator::allocate(gamma_size)), - m_inv_gamma(pod_allocator::allocate(hi_res_size)) - { - unsigned i; - for(i = 0; i < gamma_size; i++) - { - m_dir_gamma[i] = HiResT(i << (hi_res_shift - gamma_shift)); - } - - for(i = 0; i < hi_res_size; i++) - { - m_inv_gamma[i] = LoResT(i >> (hi_res_shift - gamma_shift)); - } - } - - gamma_lut(double g) : - m_gamma(1.0), - m_dir_gamma(pod_allocator::allocate(gamma_size)), - m_inv_gamma(pod_allocator::allocate(hi_res_size)) - { - gamma(g); - } - - void gamma(double g) - { - m_gamma = g; - - unsigned i; - for(i = 0; i < gamma_size; i++) - { - m_dir_gamma[i] = (HiResT) - uround(pow(i / double(gamma_mask), m_gamma) * double(hi_res_mask)); - } - - double inv_g = 1.0 / g; - for(i = 0; i < hi_res_size; i++) - { - m_inv_gamma[i] = (LoResT) - uround(pow(i / double(hi_res_mask), inv_g) * double(gamma_mask)); - } - } - - double gamma() const - { - return m_gamma; - } - - HiResT dir(LoResT v) const - { - return m_dir_gamma[unsigned(v)]; - } - - LoResT inv(HiResT v) const - { - return m_inv_gamma[unsigned(v)]; - } - - private: - gamma_lut(const self_type&); - const self_type& operator = (const self_type&); - - double m_gamma; - HiResT* m_dir_gamma; - LoResT* m_inv_gamma; - }; - - // - // sRGB support classes - // - - // Optimized sRGB lookup table. The direct conversion (sRGB to linear) - // is a straightforward lookup. The inverse conversion (linear to sRGB) - // is implemented using binary search. - template - class sRGB_lut_base - { - public: - LinearType dir(int8u v) const - { - return m_dir_table[v]; - } - - int8u inv(LinearType v) const - { - // Unrolled binary search. - int8u x = 0; - if (v > m_inv_table[128]) x = 128; - if (v > m_inv_table[x + 64]) x += 64; - if (v > m_inv_table[x + 32]) x += 32; - if (v > m_inv_table[x + 16]) x += 16; - if (v > m_inv_table[x + 8]) x += 8; - if (v > m_inv_table[x + 4]) x += 4; - if (v > m_inv_table[x + 2]) x += 2; - if (v > m_inv_table[x + 1]) x += 1; - return x; - } - - protected: - LinearType m_dir_table[256]; - LinearType m_inv_table[256]; - - // Only derived classes may instantiate. - sRGB_lut_base() - { - } - }; - - // sRGB_lut - implements sRGB conversion for the various types. - // Base template is undefined, specializations are provided below. - template - class sRGB_lut; - - template<> - class sRGB_lut : public sRGB_lut_base - { - public: - sRGB_lut() - { - // Generate lookup tables. - m_dir_table[0] = 0; - m_inv_table[0] = 0; - for (unsigned i = 1; i <= 255; ++i) - { - // Floating-point RGB is in range [0,1]. - m_dir_table[i] = float(sRGB_to_linear(i / 255.0)); - m_inv_table[i] = float(sRGB_to_linear((i - 0.5) / 255.0)); - } - } - }; - - template<> - class sRGB_lut : public sRGB_lut_base - { - public: - sRGB_lut() - { - // Generate lookup tables. - m_dir_table[0] = 0; - m_inv_table[0] = 0; - for (unsigned i = 1; i <= 255; ++i) - { - // 16-bit RGB is in range [0,65535]. - m_dir_table[i] = uround(65535.0 * sRGB_to_linear(i / 255.0)); - m_inv_table[i] = uround(65535.0 * sRGB_to_linear((i - 0.5) / 255.0)); - } - } - }; - - template<> - class sRGB_lut : public sRGB_lut_base - { - public: - sRGB_lut() - { - // Generate lookup tables. - m_dir_table[0] = 0; - m_inv_table[0] = 0; - for (unsigned i = 1; i <= 255; ++i) - { - // 8-bit RGB is handled with simple bidirectional lookup tables. - m_dir_table[i] = uround(255.0 * sRGB_to_linear(i / 255.0)); - m_inv_table[i] = uround(255.0 * linear_to_sRGB(i / 255.0)); - } - } - - int8u inv(int8u v) const - { - // In this case, the inverse transform is a simple lookup. - return m_inv_table[v]; - } - }; - - // Common base class for sRGB_conv objects. Defines an internal - // sRGB_lut object so that users don't have to. - template - class sRGB_conv_base - { - public: - static T rgb_from_sRGB(int8u x) - { - return lut.dir(x); - } - - static int8u rgb_to_sRGB(T x) - { - return lut.inv(x); - } - - private: - static sRGB_lut lut; - }; - - // Definition of sRGB_conv_base::lut. Due to the fact that this a template, - // we don't need to place the definition in a cpp file. Hurrah. - template - sRGB_lut sRGB_conv_base::lut; - - // Wrapper for sRGB-linear conversion. - // Base template is undefined, specializations are provided below. - template - class sRGB_conv; - - template<> - class sRGB_conv : public sRGB_conv_base - { - public: - static float alpha_from_sRGB(int8u x) - { - return float(x / 255.0); - } - - static int8u alpha_to_sRGB(float x) - { - if (x <= 0) return 0; - else if (x >= 1) return 255; - else return int8u(0.5 + x * 255); - } - }; - - template<> - class sRGB_conv : public sRGB_conv_base - { - public: - static int16u alpha_from_sRGB(int8u x) - { - return (x << 8) | x; - } - - static int8u alpha_to_sRGB(int16u x) - { - return x >> 8; - } - }; - - template<> - class sRGB_conv : public sRGB_conv_base - { - public: - static int8u alpha_from_sRGB(int8u x) - { - return x; - } - - static int8u alpha_to_sRGB(int8u x) - { - return x; - } - }; -} - -#endif diff --git a/kiva/gl/src/agg/agg_math.h b/kiva/gl/src/agg/agg_math.h deleted file mode 100644 index 6336c6f9a..000000000 --- a/kiva/gl/src/agg/agg_math.h +++ /dev/null @@ -1,437 +0,0 @@ -//---------------------------------------------------------------------------- -// Anti-Grain Geometry - Version 2.4 -// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) -// -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. -// This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// Bessel function (besj) was adapted for use in AGG library by Andy Wilk -// Contact: castor.vulgaris@gmail.com -//---------------------------------------------------------------------------- - -#ifndef AGG_MATH_INCLUDED -#define AGG_MATH_INCLUDED - -#include -#include "agg_basics.h" - -namespace kiva_gl_agg -{ - - //------------------------------------------------------vertex_dist_epsilon - // Coinciding points maximal distance (Epsilon) - const double vertex_dist_epsilon = 1e-14; - - //-----------------------------------------------------intersection_epsilon - // See calc_intersection - const double intersection_epsilon = 1.0e-30; - - //------------------------------------------------------------cross_product - AGG_INLINE double cross_product(double x1, double y1, - double x2, double y2, - double x, double y) - { - return (x - x2) * (y2 - y1) - (y - y2) * (x2 - x1); - } - - //--------------------------------------------------------point_in_triangle - AGG_INLINE bool point_in_triangle(double x1, double y1, - double x2, double y2, - double x3, double y3, - double x, double y) - { - bool cp1 = cross_product(x1, y1, x2, y2, x, y) < 0.0; - bool cp2 = cross_product(x2, y2, x3, y3, x, y) < 0.0; - bool cp3 = cross_product(x3, y3, x1, y1, x, y) < 0.0; - return cp1 == cp2 && cp2 == cp3 && cp3 == cp1; - } - - //-----------------------------------------------------------calc_distance - AGG_INLINE double calc_distance(double x1, double y1, double x2, double y2) - { - double dx = x2-x1; - double dy = y2-y1; - return sqrt(dx * dx + dy * dy); - } - - //--------------------------------------------------------calc_sq_distance - AGG_INLINE double calc_sq_distance(double x1, double y1, double x2, double y2) - { - double dx = x2-x1; - double dy = y2-y1; - return dx * dx + dy * dy; - } - - //------------------------------------------------calc_line_point_distance - AGG_INLINE double calc_line_point_distance(double x1, double y1, - double x2, double y2, - double x, double y) - { - double dx = x2-x1; - double dy = y2-y1; - double d = sqrt(dx * dx + dy * dy); - if(d < vertex_dist_epsilon) - { - return calc_distance(x1, y1, x, y); - } - return ((x - x2) * dy - (y - y2) * dx) / d; - } - - //-------------------------------------------------------calc_line_point_u - AGG_INLINE double calc_segment_point_u(double x1, double y1, - double x2, double y2, - double x, double y) - { - double dx = x2 - x1; - double dy = y2 - y1; - - if(dx == 0 && dy == 0) - { - return 0; - } - - double pdx = x - x1; - double pdy = y - y1; - - return (pdx * dx + pdy * dy) / (dx * dx + dy * dy); - } - - //---------------------------------------------calc_line_point_sq_distance - AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1, - double x2, double y2, - double x, double y, - double u) - { - if(u <= 0) - { - return calc_sq_distance(x, y, x1, y1); - } - else - if(u >= 1) - { - return calc_sq_distance(x, y, x2, y2); - } - return calc_sq_distance(x, y, x1 + u * (x2 - x1), y1 + u * (y2 - y1)); - } - - //---------------------------------------------calc_line_point_sq_distance - AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1, - double x2, double y2, - double x, double y) - { - return - calc_segment_point_sq_distance( - x1, y1, x2, y2, x, y, - calc_segment_point_u(x1, y1, x2, y2, x, y)); - } - - //-------------------------------------------------------calc_intersection - AGG_INLINE bool calc_intersection(double ax, double ay, double bx, double by, - double cx, double cy, double dx, double dy, - double* x, double* y) - { - double num = (ay-cy) * (dx-cx) - (ax-cx) * (dy-cy); - double den = (bx-ax) * (dy-cy) - (by-ay) * (dx-cx); - if(fabs(den) < intersection_epsilon) return false; - double r = num / den; - *x = ax + r * (bx-ax); - *y = ay + r * (by-ay); - return true; - } - - //-----------------------------------------------------intersection_exists - AGG_INLINE bool intersection_exists(double x1, double y1, double x2, double y2, - double x3, double y3, double x4, double y4) - { - // It's less expensive but you can't control the - // boundary conditions: Less or LessEqual - double dx1 = x2 - x1; - double dy1 = y2 - y1; - double dx2 = x4 - x3; - double dy2 = y4 - y3; - return ((x3 - x2) * dy1 - (y3 - y2) * dx1 < 0.0) != - ((x4 - x2) * dy1 - (y4 - y2) * dx1 < 0.0) && - ((x1 - x4) * dy2 - (y1 - y4) * dx2 < 0.0) != - ((x2 - x4) * dy2 - (y2 - y4) * dx2 < 0.0); - - // It's is more expensive but more flexible - // in terms of boundary conditions. - //-------------------- - //double den = (x2-x1) * (y4-y3) - (y2-y1) * (x4-x3); - //if(fabs(den) < intersection_epsilon) return false; - //double nom1 = (x4-x3) * (y1-y3) - (y4-y3) * (x1-x3); - //double nom2 = (x2-x1) * (y1-y3) - (y2-y1) * (x1-x3); - //double ua = nom1 / den; - //double ub = nom2 / den; - //return ua >= 0.0 && ua <= 1.0 && ub >= 0.0 && ub <= 1.0; - } - - //--------------------------------------------------------calc_orthogonal - AGG_INLINE void calc_orthogonal(double thickness, - double x1, double y1, - double x2, double y2, - double* x, double* y) - { - double dx = x2 - x1; - double dy = y2 - y1; - double d = sqrt(dx*dx + dy*dy); - *x = thickness * dy / d; - *y = -thickness * dx / d; - } - - //--------------------------------------------------------dilate_triangle - AGG_INLINE void dilate_triangle(double x1, double y1, - double x2, double y2, - double x3, double y3, - double *x, double* y, - double d) - { - double dx1=0.0; - double dy1=0.0; - double dx2=0.0; - double dy2=0.0; - double dx3=0.0; - double dy3=0.0; - double loc = cross_product(x1, y1, x2, y2, x3, y3); - if(fabs(loc) > intersection_epsilon) - { - if(cross_product(x1, y1, x2, y2, x3, y3) > 0.0) - { - d = -d; - } - calc_orthogonal(d, x1, y1, x2, y2, &dx1, &dy1); - calc_orthogonal(d, x2, y2, x3, y3, &dx2, &dy2); - calc_orthogonal(d, x3, y3, x1, y1, &dx3, &dy3); - } - *x++ = x1 + dx1; *y++ = y1 + dy1; - *x++ = x2 + dx1; *y++ = y2 + dy1; - *x++ = x2 + dx2; *y++ = y2 + dy2; - *x++ = x3 + dx2; *y++ = y3 + dy2; - *x++ = x3 + dx3; *y++ = y3 + dy3; - *x++ = x1 + dx3; *y++ = y1 + dy3; - } - - //------------------------------------------------------calc_triangle_area - AGG_INLINE double calc_triangle_area(double x1, double y1, - double x2, double y2, - double x3, double y3) - { - return (x1*y2 - x2*y1 + x2*y3 - x3*y2 + x3*y1 - x1*y3) * 0.5; - } - - //-------------------------------------------------------calc_polygon_area - template double calc_polygon_area(const Storage& st) - { - unsigned i; - double sum = 0.0; - double x = st[0].x; - double y = st[0].y; - double xs = x; - double ys = y; - - for(i = 1; i < st.size(); i++) - { - const typename Storage::value_type& v = st[i]; - sum += x * v.y - y * v.x; - x = v.x; - y = v.y; - } - return (sum + x * ys - y * xs) * 0.5; - } - - //------------------------------------------------------------------------ - // Tables for fast sqrt - extern int16u g_sqrt_table[1024]; - extern int8 g_elder_bit_table[256]; - - - //---------------------------------------------------------------fast_sqrt - //Fast integer Sqrt - really fast: no cycles, divisions or multiplications - #if defined(_MSC_VER) - #pragma warning(push) - #pragma warning(disable : 4035) //Disable warning "no return value" - #endif - AGG_INLINE unsigned fast_sqrt(unsigned val) - { - #if defined(_M_IX86) && defined(_MSC_VER) && !defined(AGG_NO_ASM) - //For Ix86 family processors this assembler code is used. - //The key command here is bsr - determination the number of the most - //significant bit of the value. For other processors - //(and maybe compilers) the pure C "#else" section is used. - __asm - { - mov ebx, val - mov edx, 11 - bsr ecx, ebx - sub ecx, 9 - jle less_than_9_bits - shr ecx, 1 - adc ecx, 0 - sub edx, ecx - shl ecx, 1 - shr ebx, cl - less_than_9_bits: - xor eax, eax - mov ax, g_sqrt_table[ebx*2] - mov ecx, edx - shr eax, cl - } - #else - - //This code is actually pure C and portable to most - //arcitectures including 64bit ones. - unsigned t = val; - int bit=0; - unsigned shift = 11; - - //The following piece of code is just an emulation of the - //Ix86 assembler command "bsr" (see above). However on old - //Intels (like Intel MMX 233MHz) this code is about twice - //faster (sic!) then just one "bsr". On PIII and PIV the - //bsr is optimized quite well. - bit = t >> 24; - if(bit) - { - bit = g_elder_bit_table[bit] + 24; - } - else - { - bit = (t >> 16) & 0xFF; - if(bit) - { - bit = g_elder_bit_table[bit] + 16; - } - else - { - bit = (t >> 8) & 0xFF; - if(bit) - { - bit = g_elder_bit_table[bit] + 8; - } - else - { - bit = g_elder_bit_table[t]; - } - } - } - - //This code calculates the sqrt. - bit -= 9; - if(bit > 0) - { - bit = (bit >> 1) + (bit & 1); - shift -= bit; - val >>= (bit << 1); - } - return g_sqrt_table[val] >> shift; - #endif - } - #if defined(_MSC_VER) - #pragma warning(pop) - #endif - - - - - //--------------------------------------------------------------------besj - // Function BESJ calculates Bessel function of first kind of order n - // Arguments: - // n - an integer (>=0), the order - // x - value at which the Bessel function is required - //-------------------- - // C++ Mathematical Library - // Convereted from equivalent FORTRAN library - // Converetd by Gareth Walker for use by course 392 computational project - // All functions tested and yield the same results as the corresponding - // FORTRAN versions. - // - // If you have any problems using these functions please report them to - // M.Muldoon@UMIST.ac.uk - // - // Documentation available on the web - // http://www.ma.umist.ac.uk/mrm/Teaching/392/libs/392.html - // Version 1.0 8/98 - // 29 October, 1999 - //-------------------- - // Adapted for use in AGG library by Andy Wilk (castor.vulgaris@gmail.com) - //------------------------------------------------------------------------ - inline double besj(double x, int n) - { - if(n < 0) - { - return 0; - } - double d = 1E-6; - double b = 0; - if(fabs(x) <= d) - { - if(n != 0) return 0; - return 1; - } - double b1 = 0; // b1 is the value from the previous iteration - // Set up a starting order for recurrence - int m1 = (int)fabs(x) + 6; - if(fabs(x) > 5) - { - m1 = (int)(fabs(1.4 * x + 60 / x)); - } - int m2 = (int)(n + 2 + fabs(x) / 4); - if (m1 > m2) - { - m2 = m1; - } - - // Apply recurrence down from curent max order - for(;;) - { - double c3 = 0; - double c2 = 1E-30; - double c4 = 0; - int m8 = 1; - if (m2 / 2 * 2 == m2) - { - m8 = -1; - } - int imax = m2 - 2; - for (int i = 1; i <= imax; i++) - { - double c6 = 2 * (m2 - i) * c2 / x - c3; - c3 = c2; - c2 = c6; - if(m2 - i - 1 == n) - { - b = c6; - } - m8 = -1 * m8; - if (m8 > 0) - { - c4 = c4 + 2 * c6; - } - } - double c6 = 2 * c2 / x - c3; - if(n == 0) - { - b = c6; - } - c4 += c6; - b /= c4; - if(fabs(b - b1) < d) - { - return b; - } - b1 = b; - m2 += 3; - } - } - -} - - -#endif diff --git a/kiva/gl/src/agg/agg_path_storage.h b/kiva/gl/src/agg/agg_path_storage.h deleted file mode 100644 index f908c1626..000000000 --- a/kiva/gl/src/agg/agg_path_storage.h +++ /dev/null @@ -1,1539 +0,0 @@ -//---------------------------------------------------------------------------- -// Anti-Grain Geometry - Version 2.4 -// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) -// -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. -// This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- - -#ifndef AGG_PATH_STORAGE_INCLUDED -#define AGG_PATH_STORAGE_INCLUDED - -#include -#include -#include "agg_math.h" -#include "agg_array.h" -#include "agg_bezier_arc.h" - -namespace kiva_gl_agg -{ - - //----------------------------------------------------vertex_block_storage - template - class vertex_block_storage - { - public: - // Allocation parameters - enum block_scale_e - { - block_shift = BlockShift, - block_size = 1 << block_shift, - block_mask = block_size - 1, - block_pool = BlockPool - }; - - typedef T value_type; - typedef vertex_block_storage self_type; - - ~vertex_block_storage(); - vertex_block_storage(); - vertex_block_storage(const self_type& v); - const self_type& operator = (const self_type& ps); - - void remove_all(); - void free_all(); - - void add_vertex(double x, double y, unsigned cmd); - void modify_vertex(unsigned idx, double x, double y); - void modify_vertex(unsigned idx, double x, double y, unsigned cmd); - void modify_command(unsigned idx, unsigned cmd); - void swap_vertices(unsigned v1, unsigned v2); - - unsigned last_command() const; - unsigned last_vertex(double* x, double* y) const; - unsigned prev_vertex(double* x, double* y) const; - - double last_x() const; - double last_y() const; - - unsigned total_vertices() const; - unsigned vertex(unsigned idx, double* x, double* y) const; - unsigned command(unsigned idx) const; - - private: - void allocate_block(unsigned nb); - int8u* storage_ptrs(T** xy_ptr); - - private: - unsigned m_total_vertices; - unsigned m_total_blocks; - unsigned m_max_blocks; - T** m_coord_blocks; - int8u** m_cmd_blocks; - }; - - - //------------------------------------------------------------------------ - template - void vertex_block_storage::free_all() - { - if(m_total_blocks) - { - T** coord_blk = m_coord_blocks + m_total_blocks - 1; - while(m_total_blocks--) - { - pod_allocator::deallocate( - *coord_blk, - block_size * 2 + - block_size / (sizeof(T) / sizeof(unsigned char))); - --coord_blk; - } - pod_allocator::deallocate(m_coord_blocks, m_max_blocks * 2); - m_total_blocks = 0; - m_max_blocks = 0; - m_coord_blocks = 0; - m_cmd_blocks = 0; - m_total_vertices = 0; - } - } - - //------------------------------------------------------------------------ - template - vertex_block_storage::~vertex_block_storage() - { - free_all(); - } - - //------------------------------------------------------------------------ - template - vertex_block_storage::vertex_block_storage() : - m_total_vertices(0), - m_total_blocks(0), - m_max_blocks(0), - m_coord_blocks(0), - m_cmd_blocks(0) - { - } - - //------------------------------------------------------------------------ - template - vertex_block_storage::vertex_block_storage(const vertex_block_storage& v) : - m_total_vertices(0), - m_total_blocks(0), - m_max_blocks(0), - m_coord_blocks(0), - m_cmd_blocks(0) - { - *this = v; - } - - //------------------------------------------------------------------------ - template - const vertex_block_storage& - vertex_block_storage::operator = (const vertex_block_storage& v) - { - remove_all(); - unsigned i; - for(i = 0; i < v.total_vertices(); ++i) - { - double x, y; - unsigned cmd = v.vertex(i, &x, &y); - add_vertex(x, y, cmd); - } - return *this; - } - - //------------------------------------------------------------------------ - template - inline void vertex_block_storage::remove_all() - { - m_total_vertices = 0; - } - - //------------------------------------------------------------------------ - template - inline void vertex_block_storage::add_vertex(double x, double y, - unsigned cmd) - { - T* coord_ptr = 0; - *storage_ptrs(&coord_ptr) = (int8u)cmd; - coord_ptr[0] = T(x); - coord_ptr[1] = T(y); - m_total_vertices++; - } - - //------------------------------------------------------------------------ - template - inline void vertex_block_storage::modify_vertex(unsigned idx, - double x, double y) - { - T* pv = m_coord_blocks[idx >> block_shift] + ((idx & block_mask) << 1); - pv[0] = T(x); - pv[1] = T(y); - } - - //------------------------------------------------------------------------ - template - inline void vertex_block_storage::modify_vertex(unsigned idx, - double x, double y, - unsigned cmd) - { - unsigned block = idx >> block_shift; - unsigned offset = idx & block_mask; - T* pv = m_coord_blocks[block] + (offset << 1); - pv[0] = T(x); - pv[1] = T(y); - m_cmd_blocks[block][offset] = (int8u)cmd; - } - - //------------------------------------------------------------------------ - template - inline void vertex_block_storage::modify_command(unsigned idx, - unsigned cmd) - { - m_cmd_blocks[idx >> block_shift][idx & block_mask] = (int8u)cmd; - } - - //------------------------------------------------------------------------ - template - inline void vertex_block_storage::swap_vertices(unsigned v1, unsigned v2) - { - unsigned b1 = v1 >> block_shift; - unsigned b2 = v2 >> block_shift; - unsigned o1 = v1 & block_mask; - unsigned o2 = v2 & block_mask; - T* pv1 = m_coord_blocks[b1] + (o1 << 1); - T* pv2 = m_coord_blocks[b2] + (o2 << 1); - T val; - val = pv1[0]; pv1[0] = pv2[0]; pv2[0] = val; - val = pv1[1]; pv1[1] = pv2[1]; pv2[1] = val; - int8u cmd = m_cmd_blocks[b1][o1]; - m_cmd_blocks[b1][o1] = m_cmd_blocks[b2][o2]; - m_cmd_blocks[b2][o2] = cmd; - } - - //------------------------------------------------------------------------ - template - inline unsigned vertex_block_storage::last_command() const - { - if(m_total_vertices) return command(m_total_vertices - 1); - return path_cmd_stop; - } - - //------------------------------------------------------------------------ - template - inline unsigned vertex_block_storage::last_vertex(double* x, double* y) const - { - if(m_total_vertices) return vertex(m_total_vertices - 1, x, y); - return path_cmd_stop; - } - - //------------------------------------------------------------------------ - template - inline unsigned vertex_block_storage::prev_vertex(double* x, double* y) const - { - if(m_total_vertices > 1) return vertex(m_total_vertices - 2, x, y); - return path_cmd_stop; - } - - //------------------------------------------------------------------------ - template - inline double vertex_block_storage::last_x() const - { - if(m_total_vertices) - { - unsigned idx = m_total_vertices - 1; - return m_coord_blocks[idx >> block_shift][(idx & block_mask) << 1]; - } - return 0.0; - } - - //------------------------------------------------------------------------ - template - inline double vertex_block_storage::last_y() const - { - if(m_total_vertices) - { - unsigned idx = m_total_vertices - 1; - return m_coord_blocks[idx >> block_shift][((idx & block_mask) << 1) + 1]; - } - return 0.0; - } - - //------------------------------------------------------------------------ - template - inline unsigned vertex_block_storage::total_vertices() const - { - return m_total_vertices; - } - - //------------------------------------------------------------------------ - template - inline unsigned vertex_block_storage::vertex(unsigned idx, - double* x, double* y) const - { - unsigned nb = idx >> block_shift; - const T* pv = m_coord_blocks[nb] + ((idx & block_mask) << 1); - *x = pv[0]; - *y = pv[1]; - return m_cmd_blocks[nb][idx & block_mask]; - } - - //------------------------------------------------------------------------ - template - inline unsigned vertex_block_storage::command(unsigned idx) const - { - return m_cmd_blocks[idx >> block_shift][idx & block_mask]; - } - - //------------------------------------------------------------------------ - template - void vertex_block_storage::allocate_block(unsigned nb) - { - if(nb >= m_max_blocks) - { - T** new_coords = - pod_allocator::allocate((m_max_blocks + block_pool) * 2); - - unsigned char** new_cmds = - (unsigned char**)(new_coords + m_max_blocks + block_pool); - - if(m_coord_blocks) - { - memcpy(new_coords, - m_coord_blocks, - m_max_blocks * sizeof(T*)); - - memcpy(new_cmds, - m_cmd_blocks, - m_max_blocks * sizeof(unsigned char*)); - - pod_allocator::deallocate(m_coord_blocks, m_max_blocks * 2); - } - m_coord_blocks = new_coords; - m_cmd_blocks = new_cmds; - m_max_blocks += block_pool; - } - m_coord_blocks[nb] = - pod_allocator::allocate(block_size * 2 + - block_size / (sizeof(T) / sizeof(unsigned char))); - - m_cmd_blocks[nb] = - (unsigned char*)(m_coord_blocks[nb] + block_size * 2); - - m_total_blocks++; - } - - //------------------------------------------------------------------------ - template - int8u* vertex_block_storage::storage_ptrs(T** xy_ptr) - { - unsigned nb = m_total_vertices >> block_shift; - if(nb >= m_total_blocks) - { - allocate_block(nb); - } - *xy_ptr = m_coord_blocks[nb] + ((m_total_vertices & block_mask) << 1); - return m_cmd_blocks[nb] + (m_total_vertices & block_mask); - } - - - - - //-----------------------------------------------------poly_plain_adaptor - template class poly_plain_adaptor - { - public: - typedef T value_type; - - poly_plain_adaptor() : - m_data(0), - m_ptr(0), - m_end(0), - m_closed(false), - m_stop(false) - {} - - poly_plain_adaptor(const T* data, unsigned num_points, bool closed) : - m_data(data), - m_ptr(data), - m_end(data + num_points * 2), - m_closed(closed), - m_stop(false) - {} - - void init(const T* data, unsigned num_points, bool closed) - { - m_data = data; - m_ptr = data; - m_end = data + num_points * 2; - m_closed = closed; - m_stop = false; - } - - void rewind(unsigned) - { - m_ptr = m_data; - m_stop = false; - } - - unsigned vertex(double* x, double* y) - { - if(m_ptr < m_end) - { - bool first = m_ptr == m_data; - *x = *m_ptr++; - *y = *m_ptr++; - return first ? path_cmd_move_to : path_cmd_line_to; - } - *x = *y = 0.0; - if(m_closed && !m_stop) - { - m_stop = true; - return path_cmd_end_poly | path_flags_close; - } - return path_cmd_stop; - } - - private: - const T* m_data; - const T* m_ptr; - const T* m_end; - bool m_closed; - bool m_stop; - }; - - - - - - //-------------------------------------------------poly_container_adaptor - template class poly_container_adaptor - { - public: - typedef typename Container::value_type vertex_type; - - poly_container_adaptor() : - m_container(0), - m_index(0), - m_closed(false), - m_stop(false) - {} - - poly_container_adaptor(const Container& data, bool closed) : - m_container(&data), - m_index(0), - m_closed(closed), - m_stop(false) - {} - - void init(const Container& data, bool closed) - { - m_container = &data; - m_index = 0; - m_closed = closed; - m_stop = false; - } - - void rewind(unsigned) - { - m_index = 0; - m_stop = false; - } - - unsigned vertex(double* x, double* y) - { - if(m_index < m_container->size()) - { - bool first = m_index == 0; - const vertex_type& v = (*m_container)[m_index++]; - *x = v.x; - *y = v.y; - return first ? path_cmd_move_to : path_cmd_line_to; - } - *x = *y = 0.0; - if(m_closed && !m_stop) - { - m_stop = true; - return path_cmd_end_poly | path_flags_close; - } - return path_cmd_stop; - } - - private: - const Container* m_container; - unsigned m_index; - bool m_closed; - bool m_stop; - }; - - - - //-----------------------------------------poly_container_reverse_adaptor - template class poly_container_reverse_adaptor - { - public: - typedef typename Container::value_type vertex_type; - - poly_container_reverse_adaptor() : - m_container(0), - m_index(-1), - m_closed(false), - m_stop(false) - {} - - poly_container_reverse_adaptor(Container& data, bool closed) : - m_container(&data), - m_index(-1), - m_closed(closed), - m_stop(false) - {} - - void init(Container& data, bool closed) - { - m_container = &data; - m_index = m_container->size() - 1; - m_closed = closed; - m_stop = false; - } - - void rewind(unsigned) - { - m_index = m_container->size() - 1; - m_stop = false; - } - - unsigned vertex(double* x, double* y) - { - if(m_index >= 0) - { - bool first = m_index == int(m_container->size() - 1); - const vertex_type& v = (*m_container)[m_index--]; - *x = v.x; - *y = v.y; - return first ? path_cmd_move_to : path_cmd_line_to; - } - *x = *y = 0.0; - if(m_closed && !m_stop) - { - m_stop = true; - return path_cmd_end_poly | path_flags_close; - } - return path_cmd_stop; - } - - private: - Container* m_container; - int m_index; - bool m_closed; - bool m_stop; - }; - - - - - - //--------------------------------------------------------line_adaptor - class line_adaptor - { - public: - typedef double value_type; - - line_adaptor() : m_line(m_coord, 2, false) {} - line_adaptor(double x1, double y1, double x2, double y2) : - m_line(m_coord, 2, false) - { - m_coord[0] = x1; - m_coord[1] = y1; - m_coord[2] = x2; - m_coord[3] = y2; - } - - void init(double x1, double y1, double x2, double y2) - { - m_coord[0] = x1; - m_coord[1] = y1; - m_coord[2] = x2; - m_coord[3] = y2; - m_line.rewind(0); - } - - void rewind(unsigned) - { - m_line.rewind(0); - } - - unsigned vertex(double* x, double* y) - { - return m_line.vertex(x, y); - } - - private: - double m_coord[4]; - poly_plain_adaptor m_line; - }; - - - - - - - - - - - - - - //---------------------------------------------------------------path_base - // A container to store vertices with their flags. - // A path consists of a number of contours separated with "move_to" - // commands. The path storage can keep and maintain more than one - // path. - // To navigate to the beginning of a particular path, use rewind(path_id); - // Where path_id is what start_new_path() returns. So, when you call - // start_new_path() you need to store its return value somewhere else - // to navigate to the path afterwards. - // - // See also: vertex_source concept - //------------------------------------------------------------------------ - template class path_base - { - public: - typedef VertexContainer container_type; - typedef path_base self_type; - - //-------------------------------------------------------------------- - path_base() : m_vertices(), m_iterator(0) {} - void remove_all() { m_vertices.remove_all(); m_iterator = 0; } - void free_all() { m_vertices.free_all(); m_iterator = 0; } - - // Make path functions - //-------------------------------------------------------------------- - unsigned start_new_path(); - - void move_to(double x, double y); - void move_rel(double dx, double dy); - - void line_to(double x, double y); - void line_rel(double dx, double dy); - - void hline_to(double x); - void hline_rel(double dx); - - void vline_to(double y); - void vline_rel(double dy); - - void arc_to(double rx, double ry, - double angle, - bool large_arc_flag, - bool sweep_flag, - double x, double y); - - void arc_rel(double rx, double ry, - double angle, - bool large_arc_flag, - bool sweep_flag, - double dx, double dy); - - void curve3(double x_ctrl, double y_ctrl, - double x_to, double y_to); - - void curve3_rel(double dx_ctrl, double dy_ctrl, - double dx_to, double dy_to); - - void curve3(double x_to, double y_to); - - void curve3_rel(double dx_to, double dy_to); - - void curve4(double x_ctrl1, double y_ctrl1, - double x_ctrl2, double y_ctrl2, - double x_to, double y_to); - - void curve4_rel(double dx_ctrl1, double dy_ctrl1, - double dx_ctrl2, double dy_ctrl2, - double dx_to, double dy_to); - - void curve4(double x_ctrl2, double y_ctrl2, - double x_to, double y_to); - - void curve4_rel(double x_ctrl2, double y_ctrl2, - double x_to, double y_to); - - - void end_poly(unsigned flags = path_flags_close); - void close_polygon(unsigned flags = path_flags_none); - - // Accessors - //-------------------------------------------------------------------- - const container_type& vertices() const { return m_vertices; } - container_type& vertices() { return m_vertices; } - - unsigned total_vertices() const; - - void rel_to_abs(double* x, double* y) const; - - unsigned last_vertex(double* x, double* y) const; - unsigned prev_vertex(double* x, double* y) const; - - double last_x() const; - double last_y() const; - - unsigned vertex(unsigned idx, double* x, double* y) const; - unsigned command(unsigned idx) const; - - void modify_vertex(unsigned idx, double x, double y); - void modify_vertex(unsigned idx, double x, double y, unsigned cmd); - void modify_command(unsigned idx, unsigned cmd); - - // VertexSource interface - //-------------------------------------------------------------------- - void rewind(unsigned path_id); - unsigned vertex(double* x, double* y); - - // Arrange the orientation of a polygon, all polygons in a path, - // or in all paths. After calling arrange_orientations() or - // arrange_orientations_all_paths(), all the polygons will have - // the same orientation, i.e. path_flags_cw or path_flags_ccw - //-------------------------------------------------------------------- - unsigned arrange_polygon_orientation(unsigned start, path_flags_e orientation); - unsigned arrange_orientations(unsigned path_id, path_flags_e orientation); - void arrange_orientations_all_paths(path_flags_e orientation); - void invert_polygon(unsigned start); - - // Flip all vertices horizontally or vertically, - // between x1 and x2, or between y1 and y2 respectively - //-------------------------------------------------------------------- - void flip_x(double x1, double x2); - void flip_y(double y1, double y2); - - // Concatenate path. The path is added as is. - //-------------------------------------------------------------------- - template - void concat_path(VertexSource& vs, unsigned path_id = 0) - { - double x, y; - unsigned cmd; - vs.rewind(path_id); - while(!is_stop(cmd = vs.vertex(&x, &y))) - { - m_vertices.add_vertex(x, y, cmd); - } - } - - //-------------------------------------------------------------------- - // Join path. The path is joined with the existing one, that is, - // it behaves as if the pen of a plotter was always down (drawing) - template - void join_path(VertexSource& vs, unsigned path_id = 0) - { - double x, y; - unsigned cmd; - vs.rewind(path_id); - cmd = vs.vertex(&x, &y); - if(!is_stop(cmd)) - { - if(is_vertex(cmd)) - { - double x0, y0; - unsigned cmd0 = last_vertex(&x0, &y0); - if(is_vertex(cmd0)) - { - if(calc_distance(x, y, x0, y0) > vertex_dist_epsilon) - { - if(is_move_to(cmd)) cmd = path_cmd_line_to; - m_vertices.add_vertex(x, y, cmd); - } - } - else - { - if(is_stop(cmd0)) - { - cmd = path_cmd_move_to; - } - else - { - if(is_move_to(cmd)) cmd = path_cmd_line_to; - } - m_vertices.add_vertex(x, y, cmd); - } - } - while(!is_stop(cmd = vs.vertex(&x, &y))) - { - m_vertices.add_vertex(x, y, is_move_to(cmd) ? - unsigned(path_cmd_line_to) : - cmd); - } - } - } - - // Concatenate polygon/polyline. - //-------------------------------------------------------------------- - template void concat_poly(const T* data, - unsigned num_points, - bool closed) - { - poly_plain_adaptor poly(data, num_points, closed); - concat_path(poly); - } - - // Join polygon/polyline continuously. - //-------------------------------------------------------------------- - template void join_poly(const T* data, - unsigned num_points, - bool closed) - { - poly_plain_adaptor poly(data, num_points, closed); - join_path(poly); - } - - //-------------------------------------------------------------------- - void translate(double dx, double dy, unsigned path_id=0); - void translate_all_paths(double dx, double dy); - - //-------------------------------------------------------------------- - template - void transform(const Trans& trans, unsigned path_id=0) - { - unsigned num_ver = m_vertices.total_vertices(); - for(; path_id < num_ver; path_id++) - { - double x, y; - unsigned cmd = m_vertices.vertex(path_id, &x, &y); - if(is_stop(cmd)) break; - if(is_vertex(cmd)) - { - trans.transform(&x, &y); - m_vertices.modify_vertex(path_id, x, y); - } - } - } - - //-------------------------------------------------------------------- - template - void transform_all_paths(const Trans& trans) - { - unsigned idx; - unsigned num_ver = m_vertices.total_vertices(); - for(idx = 0; idx < num_ver; idx++) - { - double x, y; - if(is_vertex(m_vertices.vertex(idx, &x, &y))) - { - trans.transform(&x, &y); - m_vertices.modify_vertex(idx, x, y); - } - } - } - - - - private: - unsigned perceive_polygon_orientation(unsigned start, unsigned end); - void invert_polygon(unsigned start, unsigned end); - - VertexContainer m_vertices; - unsigned m_iterator; - }; - - //------------------------------------------------------------------------ - template - unsigned path_base::start_new_path() - { - if(!is_stop(m_vertices.last_command())) - { - m_vertices.add_vertex(0.0, 0.0, path_cmd_stop); - } - return m_vertices.total_vertices(); - } - - - //------------------------------------------------------------------------ - template - inline void path_base::rel_to_abs(double* x, double* y) const - { - if(m_vertices.total_vertices()) - { - double x2; - double y2; - if(is_vertex(m_vertices.last_vertex(&x2, &y2))) - { - *x += x2; - *y += y2; - } - } - } - - //------------------------------------------------------------------------ - template - inline void path_base::move_to(double x, double y) - { - m_vertices.add_vertex(x, y, path_cmd_move_to); - } - - //------------------------------------------------------------------------ - template - inline void path_base::move_rel(double dx, double dy) - { - rel_to_abs(&dx, &dy); - m_vertices.add_vertex(dx, dy, path_cmd_move_to); - } - - //------------------------------------------------------------------------ - template - inline void path_base::line_to(double x, double y) - { - m_vertices.add_vertex(x, y, path_cmd_line_to); - } - - //------------------------------------------------------------------------ - template - inline void path_base::line_rel(double dx, double dy) - { - rel_to_abs(&dx, &dy); - m_vertices.add_vertex(dx, dy, path_cmd_line_to); - } - - //------------------------------------------------------------------------ - template - inline void path_base::hline_to(double x) - { - m_vertices.add_vertex(x, last_y(), path_cmd_line_to); - } - - //------------------------------------------------------------------------ - template - inline void path_base::hline_rel(double dx) - { - double dy = 0; - rel_to_abs(&dx, &dy); - m_vertices.add_vertex(dx, dy, path_cmd_line_to); - } - - //------------------------------------------------------------------------ - template - inline void path_base::vline_to(double y) - { - m_vertices.add_vertex(last_x(), y, path_cmd_line_to); - } - - //------------------------------------------------------------------------ - template - inline void path_base::vline_rel(double dy) - { - double dx = 0; - rel_to_abs(&dx, &dy); - m_vertices.add_vertex(dx, dy, path_cmd_line_to); - } - - //------------------------------------------------------------------------ - template - void path_base::arc_to(double rx, double ry, - double angle, - bool large_arc_flag, - bool sweep_flag, - double x, double y) - { - if(m_vertices.total_vertices() && is_vertex(m_vertices.last_command())) - { - const double epsilon = 1e-30; - double x0 = 0.0; - double y0 = 0.0; - m_vertices.last_vertex(&x0, &y0); - - rx = fabs(rx); - ry = fabs(ry); - - // Ensure radii are valid - //------------------------- - if(rx < epsilon || ry < epsilon) - { - line_to(x, y); - return; - } - - if(calc_distance(x0, y0, x, y) < epsilon) - { - // If the endpoints (x, y) and (x0, y0) are identical, then this - // is equivalent to omitting the elliptical arc segment entirely. - return; - } - bezier_arc_svg a(x0, y0, rx, ry, angle, large_arc_flag, sweep_flag, x, y); - if(a.radii_ok()) - { - join_path(a); - } - else - { - line_to(x, y); - } - } - else - { - move_to(x, y); - } - } - - //------------------------------------------------------------------------ - template - void path_base::arc_rel(double rx, double ry, - double angle, - bool large_arc_flag, - bool sweep_flag, - double dx, double dy) - { - rel_to_abs(&dx, &dy); - arc_to(rx, ry, angle, large_arc_flag, sweep_flag, dx, dy); - } - - //------------------------------------------------------------------------ - template - void path_base::curve3(double x_ctrl, double y_ctrl, - double x_to, double y_to) - { - m_vertices.add_vertex(x_ctrl, y_ctrl, path_cmd_curve3); - m_vertices.add_vertex(x_to, y_to, path_cmd_curve3); - } - - //------------------------------------------------------------------------ - template - void path_base::curve3_rel(double dx_ctrl, double dy_ctrl, - double dx_to, double dy_to) - { - rel_to_abs(&dx_ctrl, &dy_ctrl); - rel_to_abs(&dx_to, &dy_to); - m_vertices.add_vertex(dx_ctrl, dy_ctrl, path_cmd_curve3); - m_vertices.add_vertex(dx_to, dy_to, path_cmd_curve3); - } - - //------------------------------------------------------------------------ - template - void path_base::curve3(double x_to, double y_to) - { - double x0; - double y0; - if(is_vertex(m_vertices.last_vertex(&x0, &y0))) - { - double x_ctrl; - double y_ctrl; - unsigned cmd = m_vertices.prev_vertex(&x_ctrl, &y_ctrl); - if(is_curve(cmd)) - { - x_ctrl = x0 + x0 - x_ctrl; - y_ctrl = y0 + y0 - y_ctrl; - } - else - { - x_ctrl = x0; - y_ctrl = y0; - } - curve3(x_ctrl, y_ctrl, x_to, y_to); - } - } - - //------------------------------------------------------------------------ - template - void path_base::curve3_rel(double dx_to, double dy_to) - { - rel_to_abs(&dx_to, &dy_to); - curve3(dx_to, dy_to); - } - - //------------------------------------------------------------------------ - template - void path_base::curve4(double x_ctrl1, double y_ctrl1, - double x_ctrl2, double y_ctrl2, - double x_to, double y_to) - { - m_vertices.add_vertex(x_ctrl1, y_ctrl1, path_cmd_curve4); - m_vertices.add_vertex(x_ctrl2, y_ctrl2, path_cmd_curve4); - m_vertices.add_vertex(x_to, y_to, path_cmd_curve4); - } - - //------------------------------------------------------------------------ - template - void path_base::curve4_rel(double dx_ctrl1, double dy_ctrl1, - double dx_ctrl2, double dy_ctrl2, - double dx_to, double dy_to) - { - rel_to_abs(&dx_ctrl1, &dy_ctrl1); - rel_to_abs(&dx_ctrl2, &dy_ctrl2); - rel_to_abs(&dx_to, &dy_to); - m_vertices.add_vertex(dx_ctrl1, dy_ctrl1, path_cmd_curve4); - m_vertices.add_vertex(dx_ctrl2, dy_ctrl2, path_cmd_curve4); - m_vertices.add_vertex(dx_to, dy_to, path_cmd_curve4); - } - - //------------------------------------------------------------------------ - template - void path_base::curve4(double x_ctrl2, double y_ctrl2, - double x_to, double y_to) - { - double x0; - double y0; - if(is_vertex(last_vertex(&x0, &y0))) - { - double x_ctrl1; - double y_ctrl1; - unsigned cmd = prev_vertex(&x_ctrl1, &y_ctrl1); - if(is_curve(cmd)) - { - x_ctrl1 = x0 + x0 - x_ctrl1; - y_ctrl1 = y0 + y0 - y_ctrl1; - } - else - { - x_ctrl1 = x0; - y_ctrl1 = y0; - } - curve4(x_ctrl1, y_ctrl1, x_ctrl2, y_ctrl2, x_to, y_to); - } - } - - //------------------------------------------------------------------------ - template - void path_base::curve4_rel(double dx_ctrl2, double dy_ctrl2, - double dx_to, double dy_to) - { - rel_to_abs(&dx_ctrl2, &dy_ctrl2); - rel_to_abs(&dx_to, &dy_to); - curve4(dx_ctrl2, dy_ctrl2, dx_to, dy_to); - } - - //------------------------------------------------------------------------ - template - inline void path_base::end_poly(unsigned flags) - { - if(is_vertex(m_vertices.last_command())) - { - m_vertices.add_vertex(0.0, 0.0, path_cmd_end_poly | flags); - } - } - - //------------------------------------------------------------------------ - template - inline void path_base::close_polygon(unsigned flags) - { - end_poly(path_flags_close | flags); - } - - //------------------------------------------------------------------------ - template - inline unsigned path_base::total_vertices() const - { - return m_vertices.total_vertices(); - } - - //------------------------------------------------------------------------ - template - inline unsigned path_base::last_vertex(double* x, double* y) const - { - return m_vertices.last_vertex(x, y); - } - - //------------------------------------------------------------------------ - template - inline unsigned path_base::prev_vertex(double* x, double* y) const - { - return m_vertices.prev_vertex(x, y); - } - - //------------------------------------------------------------------------ - template - inline double path_base::last_x() const - { - return m_vertices.last_x(); - } - - //------------------------------------------------------------------------ - template - inline double path_base::last_y() const - { - return m_vertices.last_y(); - } - - //------------------------------------------------------------------------ - template - inline unsigned path_base::vertex(unsigned idx, double* x, double* y) const - { - return m_vertices.vertex(idx, x, y); - } - - //------------------------------------------------------------------------ - template - inline unsigned path_base::command(unsigned idx) const - { - return m_vertices.command(idx); - } - - //------------------------------------------------------------------------ - template - void path_base::modify_vertex(unsigned idx, double x, double y) - { - m_vertices.modify_vertex(idx, x, y); - } - - //------------------------------------------------------------------------ - template - void path_base::modify_vertex(unsigned idx, double x, double y, unsigned cmd) - { - m_vertices.modify_vertex(idx, x, y, cmd); - } - - //------------------------------------------------------------------------ - template - void path_base::modify_command(unsigned idx, unsigned cmd) - { - m_vertices.modify_command(idx, cmd); - } - - //------------------------------------------------------------------------ - template - inline void path_base::rewind(unsigned path_id) - { - m_iterator = path_id; - } - - //------------------------------------------------------------------------ - template - inline unsigned path_base::vertex(double* x, double* y) - { - if(m_iterator >= m_vertices.total_vertices()) return path_cmd_stop; - return m_vertices.vertex(m_iterator++, x, y); - } - - //------------------------------------------------------------------------ - template - unsigned path_base::perceive_polygon_orientation(unsigned start, - unsigned end) - { - // Calculate signed area (double area to be exact) - //--------------------- - unsigned np = end - start; - double area = 0.0; - unsigned i; - for(i = 0; i < np; ++i) - { - double x1, y1, x2, y2; - m_vertices.vertex(start + i, &x1, &y1); - m_vertices.vertex(start + (i + 1) % np, &x2, &y2); - area += x1 * y2 - y1 * x2; - } - return (area < 0.0) ? path_flags_cw : path_flags_ccw; - } - - //------------------------------------------------------------------------ - template - void path_base::invert_polygon(unsigned start, unsigned end) - { - unsigned i; - unsigned tmp_cmd = m_vertices.command(start); - - --end; // Make "end" inclusive - - // Shift all commands to one position - for(i = start; i < end; ++i) - { - m_vertices.modify_command(i, m_vertices.command(i + 1)); - } - - // Assign starting command to the ending command - m_vertices.modify_command(end, tmp_cmd); - - // Reverse the polygon - while(end > start) - { - m_vertices.swap_vertices(start++, end--); - } - } - - //------------------------------------------------------------------------ - template - void path_base::invert_polygon(unsigned start) - { - // Skip all non-vertices at the beginning - while(start < m_vertices.total_vertices() && - !is_vertex(m_vertices.command(start))) ++start; - - // Skip all insignificant move_to - while(start+1 < m_vertices.total_vertices() && - is_move_to(m_vertices.command(start)) && - is_move_to(m_vertices.command(start+1))) ++start; - - // Find the last vertex - unsigned end = start + 1; - while(end < m_vertices.total_vertices() && - !is_next_poly(m_vertices.command(end))) ++end; - - invert_polygon(start, end); - } - - //------------------------------------------------------------------------ - template - unsigned path_base::arrange_polygon_orientation(unsigned start, - path_flags_e orientation) - { - if(orientation == path_flags_none) return start; - - // Skip all non-vertices at the beginning - while(start < m_vertices.total_vertices() && - !is_vertex(m_vertices.command(start))) ++start; - - // Skip all insignificant move_to - while(start+1 < m_vertices.total_vertices() && - is_move_to(m_vertices.command(start)) && - is_move_to(m_vertices.command(start+1))) ++start; - - // Find the last vertex - unsigned end = start + 1; - while(end < m_vertices.total_vertices() && - !is_next_poly(m_vertices.command(end))) ++end; - - if(end - start > 2) - { - if(perceive_polygon_orientation(start, end) != unsigned(orientation)) - { - // Invert polygon, set orientation flag, and skip all end_poly - invert_polygon(start, end); - unsigned cmd; - while(end < m_vertices.total_vertices() && - is_end_poly(cmd = m_vertices.command(end))) - { - m_vertices.modify_command(end++, set_orientation(cmd, orientation)); - } - } - } - return end; - } - - //------------------------------------------------------------------------ - template - unsigned path_base::arrange_orientations(unsigned start, - path_flags_e orientation) - { - if(orientation != path_flags_none) - { - while(start < m_vertices.total_vertices()) - { - start = arrange_polygon_orientation(start, orientation); - if(is_stop(m_vertices.command(start))) - { - ++start; - break; - } - } - } - return start; - } - - //------------------------------------------------------------------------ - template - void path_base::arrange_orientations_all_paths(path_flags_e orientation) - { - if(orientation != path_flags_none) - { - unsigned start = 0; - while(start < m_vertices.total_vertices()) - { - start = arrange_orientations(start, orientation); - } - } - } - - //------------------------------------------------------------------------ - template - void path_base::flip_x(double x1, double x2) - { - unsigned i; - double x, y; - for(i = 0; i < m_vertices.total_vertices(); ++i) - { - unsigned cmd = m_vertices.vertex(i, &x, &y); - if(is_vertex(cmd)) - { - m_vertices.modify_vertex(i, x2 - x + x1, y); - } - } - } - - //------------------------------------------------------------------------ - template - void path_base::flip_y(double y1, double y2) - { - unsigned i; - double x, y; - for(i = 0; i < m_vertices.total_vertices(); ++i) - { - unsigned cmd = m_vertices.vertex(i, &x, &y); - if(is_vertex(cmd)) - { - m_vertices.modify_vertex(i, x, y2 - y + y1); - } - } - } - - //------------------------------------------------------------------------ - template - void path_base::translate(double dx, double dy, unsigned path_id) - { - unsigned num_ver = m_vertices.total_vertices(); - for(; path_id < num_ver; path_id++) - { - double x, y; - unsigned cmd = m_vertices.vertex(path_id, &x, &y); - if(is_stop(cmd)) break; - if(is_vertex(cmd)) - { - x += dx; - y += dy; - m_vertices.modify_vertex(path_id, x, y); - } - } - } - - //------------------------------------------------------------------------ - template - void path_base::translate_all_paths(double dx, double dy) - { - unsigned idx; - unsigned num_ver = m_vertices.total_vertices(); - for(idx = 0; idx < num_ver; idx++) - { - double x, y; - if(is_vertex(m_vertices.vertex(idx, &x, &y))) - { - x += dx; - y += dy; - m_vertices.modify_vertex(idx, x, y); - } - } - } - - //-----------------------------------------------------vertex_stl_storage - template class vertex_stl_storage - { - public: - typedef typename Container::value_type vertex_type; - typedef typename vertex_type::value_type value_type; - - void remove_all() { m_vertices.clear(); } - void free_all() { m_vertices.clear(); } - - void add_vertex(double x, double y, unsigned cmd) - { - m_vertices.push_back(vertex_type(value_type(x), - value_type(y), - int8u(cmd))); - } - - void modify_vertex(unsigned idx, double x, double y) - { - vertex_type& v = m_vertices[idx]; - v.x = value_type(x); - v.y = value_type(y); - } - - void modify_vertex(unsigned idx, double x, double y, unsigned cmd) - { - vertex_type& v = m_vertices[idx]; - v.x = value_type(x); - v.y = value_type(y); - v.cmd = int8u(cmd); - } - - void modify_command(unsigned idx, unsigned cmd) - { - m_vertices[idx].cmd = int8u(cmd); - } - - void swap_vertices(unsigned v1, unsigned v2) - { - vertex_type t = m_vertices[v1]; - m_vertices[v1] = m_vertices[v2]; - m_vertices[v2] = t; - } - - unsigned last_command() const - { - return m_vertices.size() ? - m_vertices[m_vertices.size() - 1].cmd : - path_cmd_stop; - } - - unsigned last_vertex(double* x, double* y) const - { - if(m_vertices.size() == 0) - { - *x = *y = 0.0; - return path_cmd_stop; - } - return vertex(m_vertices.size() - 1, x, y); - } - - unsigned prev_vertex(double* x, double* y) const - { - if(m_vertices.size() < 2) - { - *x = *y = 0.0; - return path_cmd_stop; - } - return vertex(m_vertices.size() - 2, x, y); - } - - double last_x() const - { - return m_vertices.size() ? m_vertices[m_vertices.size() - 1].x : 0.0; - } - - double last_y() const - { - return m_vertices.size() ? m_vertices[m_vertices.size() - 1].y : 0.0; - } - - unsigned total_vertices() const - { - return m_vertices.size(); - } - - unsigned vertex(unsigned idx, double* x, double* y) const - { - const vertex_type& v = m_vertices[idx]; - *x = v.x; - *y = v.y; - return v.cmd; - } - - unsigned command(unsigned idx) const - { - return m_vertices[idx].cmd; - } - - private: - Container m_vertices; - }; - - //-----------------------------------------------------------path_storage - typedef path_base > path_storage; - - // Example of declarations path_storage with pod_bvector as a container - //----------------------------------------------------------------------- - //typedef path_base > > path_storage; - -} - -// Example of declarations path_storage with std::vector as a container -//--------------------------------------------------------------------------- -//#include -//namespace kiva_gl_agg -//{ -// typedef path_base > > stl_path_storage; -//} - -#endif diff --git a/kiva/gl/src/agg/agg_sqrt_tables.cpp b/kiva/gl/src/agg/agg_sqrt_tables.cpp deleted file mode 100644 index 6811448e8..000000000 --- a/kiva/gl/src/agg/agg_sqrt_tables.cpp +++ /dev/null @@ -1,115 +0,0 @@ -//---------------------------------------------------------------------------- -// Anti-Grain Geometry - Version 2.4 -// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) -// -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. -// This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// static tables for fast integer sqrt -// -//---------------------------------------------------------------------------- - -#include "agg_basics.h" - -namespace kiva_gl_agg -{ - int16u g_sqrt_table[1024] = //----------g_sqrt_table - { - 0, - 2048,2896,3547,4096,4579,5017,5418,5793,6144,6476,6792,7094,7384,7663,7932,8192,8444, - 8689,8927,9159,9385,9606,9822,10033,10240,10443,10642,10837,11029,11217,11403,11585, - 11765,11942,12116,12288,12457,12625,12790,12953,13114,13273,13430,13585,13738,13890, - 14040,14189,14336,14482,14626,14768,14910,15050,15188,15326,15462,15597,15731,15864, - 15995,16126,16255,16384,16512,16638,16764,16888,17012,17135,17257,17378,17498,17618, - 17736,17854,17971,18087,18203,18318,18432,18545,18658,18770,18882,18992,19102,19212, - 19321,19429,19537,19644,19750,19856,19961,20066,20170,20274,20377,20480,20582,20684, - 20785,20886,20986,21085,21185,21283,21382,21480,21577,21674,21771,21867,21962,22058, - 22153,22247,22341,22435,22528,22621,22713,22806,22897,22989,23080,23170,23261,23351, - 23440,23530,23619,23707,23796,23884,23971,24059,24146,24232,24319,24405,24491,24576, - 24661,24746,24831,24915,24999,25083,25166,25249,25332,25415,25497,25580,25661,25743, - 25824,25905,25986,26067,26147,26227,26307,26387,26466,26545,26624,26703,26781,26859, - 26937,27015,27092,27170,27247,27324,27400,27477,27553,27629,27705,27780,27856,27931, - 28006,28081,28155,28230,28304,28378,28452,28525,28599,28672,28745,28818,28891,28963, - 29035,29108,29180,29251,29323,29394,29466,29537,29608,29678,29749,29819,29890,29960, - 30030,30099,30169,30238,30308,30377,30446,30515,30583,30652,30720,30788,30856,30924, - 30992,31059,31127,31194,31261,31328,31395,31462,31529,31595,31661,31727,31794,31859, - 31925,31991,32056,32122,32187,32252,32317,32382,32446,32511,32575,32640,32704,32768, - 32832,32896,32959,33023,33086,33150,33213,33276,33339,33402,33465,33527,33590,33652, - 33714,33776,33839,33900,33962,34024,34086,34147,34208,34270,34331,34392,34453,34514, - 34574,34635,34695,34756,34816,34876,34936,34996,35056,35116,35176,35235,35295,35354, - 35413,35472,35531,35590,35649,35708,35767,35825,35884,35942,36001,36059,36117,36175, - 36233,36291,36348,36406,36464,36521,36578,36636,36693,36750,36807,36864,36921,36978, - 37034,37091,37147,37204,37260,37316,37372,37429,37485,37540,37596,37652,37708,37763, - 37819,37874,37929,37985,38040,38095,38150,38205,38260,38315,38369,38424,38478,38533, - 38587,38642,38696,38750,38804,38858,38912,38966,39020,39073,39127,39181,39234,39287, - 39341,39394,39447,39500,39553,39606,39659,39712,39765,39818,39870,39923,39975,40028, - 40080,40132,40185,40237,40289,40341,40393,40445,40497,40548,40600,40652,40703,40755, - 40806,40857,40909,40960,41011,41062,41113,41164,41215,41266,41317,41368,41418,41469, - 41519,41570,41620,41671,41721,41771,41821,41871,41922,41972,42021,42071,42121,42171, - 42221,42270,42320,42369,42419,42468,42518,42567,42616,42665,42714,42763,42813,42861, - 42910,42959,43008,43057,43105,43154,43203,43251,43300,43348,43396,43445,43493,43541, - 43589,43637,43685,43733,43781,43829,43877,43925,43972,44020,44068,44115,44163,44210, - 44258,44305,44352,44400,44447,44494,44541,44588,44635,44682,44729,44776,44823,44869, - 44916,44963,45009,45056,45103,45149,45195,45242,45288,45334,45381,45427,45473,45519, - 45565,45611,45657,45703,45749,45795,45840,45886,45932,45977,46023,46069,46114,46160, - 46205,46250,46296,46341,46386,46431,46477,46522,46567,46612,46657,46702,46746,46791, - 46836,46881,46926,46970,47015,47059,47104,47149,47193,47237,47282,47326,47370,47415, - 47459,47503,47547,47591,47635,47679,47723,47767,47811,47855,47899,47942,47986,48030, - 48074,48117,48161,48204,48248,48291,48335,48378,48421,48465,48508,48551,48594,48637, - 48680,48723,48766,48809,48852,48895,48938,48981,49024,49067,49109,49152,49195,49237, - 49280,49322,49365,49407,49450,49492,49535,49577,49619,49661,49704,49746,49788,49830, - 49872,49914,49956,49998,50040,50082,50124,50166,50207,50249,50291,50332,50374,50416, - 50457,50499,50540,50582,50623,50665,50706,50747,50789,50830,50871,50912,50954,50995, - 51036,51077,51118,51159,51200,51241,51282,51323,51364,51404,51445,51486,51527,51567, - 51608,51649,51689,51730,51770,51811,51851,51892,51932,51972,52013,52053,52093,52134, - 52174,52214,52254,52294,52334,52374,52414,52454,52494,52534,52574,52614,52654,52694, - 52734,52773,52813,52853,52892,52932,52972,53011,53051,53090,53130,53169,53209,53248, - 53287,53327,53366,53405,53445,53484,53523,53562,53601,53640,53679,53719,53758,53797, - 53836,53874,53913,53952,53991,54030,54069,54108,54146,54185,54224,54262,54301,54340, - 54378,54417,54455,54494,54532,54571,54609,54647,54686,54724,54762,54801,54839,54877, - 54915,54954,54992,55030,55068,55106,55144,55182,55220,55258,55296,55334,55372,55410, - 55447,55485,55523,55561,55599,55636,55674,55712,55749,55787,55824,55862,55900,55937, - 55975,56012,56049,56087,56124,56162,56199,56236,56273,56311,56348,56385,56422,56459, - 56497,56534,56571,56608,56645,56682,56719,56756,56793,56830,56867,56903,56940,56977, - 57014,57051,57087,57124,57161,57198,57234,57271,57307,57344,57381,57417,57454,57490, - 57527,57563,57599,57636,57672,57709,57745,57781,57817,57854,57890,57926,57962,57999, - 58035,58071,58107,58143,58179,58215,58251,58287,58323,58359,58395,58431,58467,58503, - 58538,58574,58610,58646,58682,58717,58753,58789,58824,58860,58896,58931,58967,59002, - 59038,59073,59109,59144,59180,59215,59251,59286,59321,59357,59392,59427,59463,59498, - 59533,59568,59603,59639,59674,59709,59744,59779,59814,59849,59884,59919,59954,59989, - 60024,60059,60094,60129,60164,60199,60233,60268,60303,60338,60373,60407,60442,60477, - 60511,60546,60581,60615,60650,60684,60719,60753,60788,60822,60857,60891,60926,60960, - 60995,61029,61063,61098,61132,61166,61201,61235,61269,61303,61338,61372,61406,61440, - 61474,61508,61542,61576,61610,61644,61678,61712,61746,61780,61814,61848,61882,61916, - 61950,61984,62018,62051,62085,62119,62153,62186,62220,62254,62287,62321,62355,62388, - 62422,62456,62489,62523,62556,62590,62623,62657,62690,62724,62757,62790,62824,62857, - 62891,62924,62957,62991,63024,63057,63090,63124,63157,63190,63223,63256,63289,63323, - 63356,63389,63422,63455,63488,63521,63554,63587,63620,63653,63686,63719,63752,63785, - 63817,63850,63883,63916,63949,63982,64014,64047,64080,64113,64145,64178,64211,64243, - 64276,64309,64341,64374,64406,64439,64471,64504,64536,64569,64601,64634,64666,64699, - 64731,64763,64796,64828,64861,64893,64925,64957,64990,65022,65054,65086,65119,65151, - 65183,65215,65247,65279,65312,65344,65376,65408,65440,65472,65504 - }; - - - int8 g_elder_bit_table[256] = //---------g_elder_bit_table - { - 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, - 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 - }; - -} diff --git a/kiva/gl/src/agg/agg_trans_affine.cpp b/kiva/gl/src/agg/agg_trans_affine.cpp deleted file mode 100644 index d9f6d9888..000000000 --- a/kiva/gl/src/agg/agg_trans_affine.cpp +++ /dev/null @@ -1,190 +0,0 @@ -//---------------------------------------------------------------------------- -// Anti-Grain Geometry - Version 2.4 -// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) -// -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. -// This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// Affine transformations -// -//---------------------------------------------------------------------------- -#include "agg_trans_affine.h" - -namespace kiva_gl_agg -{ - - //------------------------------------------------------------------------ - const trans_affine& trans_affine::parl_to_parl(const double* src, - const double* dst) - { - sx = src[2] - src[0]; - shy = src[3] - src[1]; - shx = src[4] - src[0]; - sy = src[5] - src[1]; - tx = src[0]; - ty = src[1]; - invert(); - multiply(trans_affine(dst[2] - dst[0], dst[3] - dst[1], - dst[4] - dst[0], dst[5] - dst[1], - dst[0], dst[1])); - return *this; - } - - //------------------------------------------------------------------------ - const trans_affine& trans_affine::rect_to_parl(double x1, double y1, - double x2, double y2, - const double* parl) - { - double src[6]; - src[0] = x1; src[1] = y1; - src[2] = x2; src[3] = y1; - src[4] = x2; src[5] = y2; - parl_to_parl(src, parl); - return *this; - } - - //------------------------------------------------------------------------ - const trans_affine& trans_affine::parl_to_rect(const double* parl, - double x1, double y1, - double x2, double y2) - { - double dst[6]; - dst[0] = x1; dst[1] = y1; - dst[2] = x2; dst[3] = y1; - dst[4] = x2; dst[5] = y2; - parl_to_parl(parl, dst); - return *this; - } - - //------------------------------------------------------------------------ - const trans_affine& trans_affine::multiply(const trans_affine& m) - { - double t0 = sx * m.sx + shy * m.shx; - double t2 = shx * m.sx + sy * m.shx; - double t4 = tx * m.sx + ty * m.shx + m.tx; - shy = sx * m.shy + shy * m.sy; - sy = shx * m.shy + sy * m.sy; - ty = tx * m.shy + ty * m.sy + m.ty; - sx = t0; - shx = t2; - tx = t4; - return *this; - } - - - //------------------------------------------------------------------------ - const trans_affine& trans_affine::invert() - { - double d = determinant_reciprocal(); - - double t0 = sy * d; - sy = sx * d; - shy = -shy * d; - shx = -shx * d; - - double t4 = -tx * t0 - ty * shx; - ty = -tx * shy - ty * sy; - - sx = t0; - tx = t4; - return *this; - } - - - //------------------------------------------------------------------------ - const trans_affine& trans_affine::flip_x() - { - sx = -sx; - shy = -shy; - tx = -tx; - return *this; - } - - //------------------------------------------------------------------------ - const trans_affine& trans_affine::flip_y() - { - shx = -shx; - sy = -sy; - ty = -ty; - return *this; - } - - //------------------------------------------------------------------------ - const trans_affine& trans_affine::reset() - { - sx = sy = 1.0; - shy = shx = tx = ty = 0.0; - return *this; - } - - //------------------------------------------------------------------------ - bool trans_affine::is_identity(double epsilon) const - { - return is_equal_eps(sx, 1.0, epsilon) && - is_equal_eps(shy, 0.0, epsilon) && - is_equal_eps(shx, 0.0, epsilon) && - is_equal_eps(sy, 1.0, epsilon) && - is_equal_eps(tx, 0.0, epsilon) && - is_equal_eps(ty, 0.0, epsilon); - } - - //------------------------------------------------------------------------ - bool trans_affine::is_valid(double epsilon) const - { - return fabs(sx) > epsilon && fabs(sy) > epsilon; - } - - //------------------------------------------------------------------------ - bool trans_affine::is_equal(const trans_affine& m, double epsilon) const - { - return is_equal_eps(sx, m.sx, epsilon) && - is_equal_eps(shy, m.shy, epsilon) && - is_equal_eps(shx, m.shx, epsilon) && - is_equal_eps(sy, m.sy, epsilon) && - is_equal_eps(tx, m.tx, epsilon) && - is_equal_eps(ty, m.ty, epsilon); - } - - //------------------------------------------------------------------------ - double trans_affine::rotation() const - { - double x1 = 0.0; - double y1 = 0.0; - double x2 = 1.0; - double y2 = 0.0; - transform(&x1, &y1); - transform(&x2, &y2); - return atan2(y2-y1, x2-x1); - } - - //------------------------------------------------------------------------ - void trans_affine::translation(double* dx, double* dy) const - { - *dx = tx; - *dy = ty; - } - - //------------------------------------------------------------------------ - void trans_affine::scaling(double* x, double* y) const - { - double x1 = 0.0; - double y1 = 0.0; - double x2 = 1.0; - double y2 = 1.0; - trans_affine t(*this); - t *= trans_affine_rotation(-rotation()); - t.transform(&x1, &y1); - t.transform(&x2, &y2); - *x = x2 - x1; - *y = y2 - y1; - } - -} diff --git a/kiva/gl/src/agg/agg_trans_affine.h b/kiva/gl/src/agg/agg_trans_affine.h deleted file mode 100644 index 13bb8af0f..000000000 --- a/kiva/gl/src/agg/agg_trans_affine.h +++ /dev/null @@ -1,518 +0,0 @@ -//---------------------------------------------------------------------------- -// Anti-Grain Geometry - Version 2.4 -// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) -// -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. -// This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -//---------------------------------------------------------------------------- -// -// Affine transformation classes. -// -//---------------------------------------------------------------------------- -#ifndef AGG_TRANS_AFFINE_INCLUDED -#define AGG_TRANS_AFFINE_INCLUDED - -#include -#include "agg_basics.h" - -namespace kiva_gl_agg -{ - const double affine_epsilon = 1e-14; - - //============================================================trans_affine - // - // See Implementation agg_trans_affine.cpp - // - // Affine transformation are linear transformations in Cartesian coordinates - // (strictly speaking not only in Cartesian, but for the beginning we will - // think so). They are rotation, scaling, translation and skewing. - // After any affine transformation a line segment remains a line segment - // and it will never become a curve. - // - // There will be no math about matrix calculations, since it has been - // described many times. Ask yourself a very simple question: - // "why do we need to understand and use some matrix stuff instead of just - // rotating, scaling and so on". The answers are: - // - // 1. Any combination of transformations can be done by only 4 multiplications - // and 4 additions in floating point. - // 2. One matrix transformation is equivalent to the number of consecutive - // discrete transformations, i.e. the matrix "accumulates" all transformations - // in the order of their settings. Suppose we have 4 transformations: - // * rotate by 30 degrees, - // * scale X to 2.0, - // * scale Y to 1.5, - // * move to (100, 100). - // The result will depend on the order of these transformations, - // and the advantage of matrix is that the sequence of discret calls: - // rotate(30), scaleX(2.0), scaleY(1.5), move(100,100) - // will have exactly the same result as the following matrix transformations: - // - // affine_matrix m; - // m *= rotate_matrix(30); - // m *= scaleX_matrix(2.0); - // m *= scaleY_matrix(1.5); - // m *= move_matrix(100,100); - // - // m.transform_my_point_at_last(x, y); - // - // What is the good of it? In real life we will set-up the matrix only once - // and then transform many points, let alone the convenience to set any - // combination of transformations. - // - // So, how to use it? Very easy - literally as it's shown above. Not quite, - // let us write a correct example: - // - // kiva_gl_agg::trans_affine m; - // m *= kiva_gl_agg::trans_affine_rotation(30.0 * 3.1415926 / 180.0); - // m *= kiva_gl_agg::trans_affine_scaling(2.0, 1.5); - // m *= kiva_gl_agg::trans_affine_translation(100.0, 100.0); - // m.transform(&x, &y); - // - // The affine matrix is all you need to perform any linear transformation, - // but all transformations have origin point (0,0). It means that we need to - // use 2 translations if we want to rotate someting around (100,100): - // - // m *= kiva_gl_agg::trans_affine_translation(-100.0, -100.0); // move to (0,0) - // m *= kiva_gl_agg::trans_affine_rotation(30.0 * 3.1415926 / 180.0); // rotate - // m *= kiva_gl_agg::trans_affine_translation(100.0, 100.0); // move back to (100,100) - //---------------------------------------------------------------------- - struct trans_affine - { - double sx, shy, shx, sy, tx, ty; - - //------------------------------------------ Construction - // Identity matrix - trans_affine() : - sx(1.0), shy(0.0), shx(0.0), sy(1.0), tx(0.0), ty(0.0) - {} - - // Custom matrix. Usually used in derived classes - trans_affine(double v0, double v1, double v2, - double v3, double v4, double v5) : - sx(v0), shy(v1), shx(v2), sy(v3), tx(v4), ty(v5) - {} - - // Custom matrix from m[6] - explicit trans_affine(const double* m) : - sx(m[0]), shy(m[1]), shx(m[2]), sy(m[3]), tx(m[4]), ty(m[5]) - {} - - // Rectangle to a parallelogram. - trans_affine(double x1, double y1, double x2, double y2, - const double* parl) - { - rect_to_parl(x1, y1, x2, y2, parl); - } - - // Parallelogram to a rectangle. - trans_affine(const double* parl, - double x1, double y1, double x2, double y2) - { - parl_to_rect(parl, x1, y1, x2, y2); - } - - // Arbitrary parallelogram transformation. - trans_affine(const double* src, const double* dst) - { - parl_to_parl(src, dst); - } - - //---------------------------------- Parellelogram transformations - // transform a parallelogram to another one. Src and dst are - // pointers to arrays of three points (double[6], x1,y1,...) that - // identify three corners of the parallelograms assuming implicit - // fourth point. The arguments are arrays of double[6] mapped - // to x1,y1, x2,y2, x3,y3 where the coordinates are: - // *-----------------* - // / (x3,y3)/ - // / / - // /(x1,y1) (x2,y2)/ - // *-----------------* - const trans_affine& parl_to_parl(const double* src, - const double* dst); - - const trans_affine& rect_to_parl(double x1, double y1, - double x2, double y2, - const double* parl); - - const trans_affine& parl_to_rect(const double* parl, - double x1, double y1, - double x2, double y2); - - - //------------------------------------------ Operations - // Reset - load an identity matrix - const trans_affine& reset(); - - // Direct transformations operations - const trans_affine& translate(double x, double y); - const trans_affine& rotate(double a); - const trans_affine& scale(double s); - const trans_affine& scale(double x, double y); - - // Multiply matrix to another one - const trans_affine& multiply(const trans_affine& m); - - // Multiply "m" to "this" and assign the result to "this" - const trans_affine& premultiply(const trans_affine& m); - - // Multiply matrix to inverse of another one - const trans_affine& multiply_inv(const trans_affine& m); - - // Multiply inverse of "m" to "this" and assign the result to "this" - const trans_affine& premultiply_inv(const trans_affine& m); - - // Invert matrix. Do not try to invert degenerate matrices, - // there's no check for validity. If you set scale to 0 and - // then try to invert matrix, expect unpredictable result. - const trans_affine& invert(); - - // Mirroring around X - const trans_affine& flip_x(); - - // Mirroring around Y - const trans_affine& flip_y(); - - //------------------------------------------- Load/Store - // Store matrix to an array [6] of double - void store_to(double* m) const - { - *m++ = sx; *m++ = shy; *m++ = shx; *m++ = sy; *m++ = tx; *m++ = ty; - } - - // Load matrix from an array [6] of double - const trans_affine& load_from(const double* m) - { - sx = *m++; shy = *m++; shx = *m++; sy = *m++; tx = *m++; ty = *m++; - return *this; - } - - //------------------------------------------- Operators - - // Multiply the matrix by another one - const trans_affine& operator *= (const trans_affine& m) - { - return multiply(m); - } - - // Multiply the matrix by inverse of another one - const trans_affine& operator /= (const trans_affine& m) - { - return multiply_inv(m); - } - - // Multiply the matrix by another one and return - // the result in a separete matrix. - trans_affine operator * (const trans_affine& m) const - { - return trans_affine(*this).multiply(m); - } - - // Multiply the matrix by inverse of another one - // and return the result in a separete matrix. - trans_affine operator / (const trans_affine& m) const - { - return trans_affine(*this).multiply_inv(m); - } - - // Calculate and return the inverse matrix - trans_affine operator ~ () const - { - trans_affine ret = *this; - return ret.invert(); - } - - // Equal operator with default epsilon - bool operator == (const trans_affine& m) const - { - return is_equal(m, affine_epsilon); - } - - // Not Equal operator with default epsilon - bool operator != (const trans_affine& m) const - { - return !is_equal(m, affine_epsilon); - } - - //-------------------------------------------- Transformations - // Direct transformation of x and y - void transform(double* x, double* y) const; - - // Direct transformation of x and y, 2x2 matrix only, no translation - void transform_2x2(double* x, double* y) const; - - // Inverse transformation of x and y. It works slower than the - // direct transformation. For massive operations it's better to - // invert() the matrix and then use direct transformations. - void inverse_transform(double* x, double* y) const; - - //-------------------------------------------- Auxiliary - // Calculate the determinant of matrix - double determinant() const - { - return sx * sy - shy * shx; - } - - // Calculate the reciprocal of the determinant - double determinant_reciprocal() const - { - return 1.0 / (sx * sy - shy * shx); - } - - // Get the average scale (by X and Y). - // Basically used to calculate the approximation_scale when - // decomposinting curves into line segments. - double scale() const; - - // Check to see if the matrix is not degenerate - bool is_valid(double epsilon = affine_epsilon) const; - - // Check to see if it's an identity matrix - bool is_identity(double epsilon = affine_epsilon) const; - - // Check to see if two matrices are equal - bool is_equal(const trans_affine& m, double epsilon = affine_epsilon) const; - - // Determine the major parameters. Use with caution considering - // possible degenerate cases. - double rotation() const; - void translation(double* dx, double* dy) const; - void scaling(double* x, double* y) const; - void scaling_abs(double* x, double* y) const; - }; - - //------------------------------------------------------------------------ - inline void trans_affine::transform(double* x, double* y) const - { - register double tmp = *x; - *x = tmp * sx + *y * shx + tx; - *y = tmp * shy + *y * sy + ty; - } - - //------------------------------------------------------------------------ - inline void trans_affine::transform_2x2(double* x, double* y) const - { - register double tmp = *x; - *x = tmp * sx + *y * shx; - *y = tmp * shy + *y * sy; - } - - //------------------------------------------------------------------------ - inline void trans_affine::inverse_transform(double* x, double* y) const - { - register double d = determinant_reciprocal(); - register double a = (*x - tx) * d; - register double b = (*y - ty) * d; - *x = a * sy - b * shx; - *y = b * sx - a * shy; - } - - //------------------------------------------------------------------------ - inline double trans_affine::scale() const - { - double x = 0.707106781 * sx + 0.707106781 * shx; - double y = 0.707106781 * shy + 0.707106781 * sy; - return sqrt(x*x + y*y); - } - - //------------------------------------------------------------------------ - inline const trans_affine& trans_affine::translate(double x, double y) - { - tx += x; - ty += y; - return *this; - } - - //------------------------------------------------------------------------ - inline const trans_affine& trans_affine::rotate(double a) - { - double ca = cos(a); - double sa = sin(a); - double t0 = sx * ca - shy * sa; - double t2 = shx * ca - sy * sa; - double t4 = tx * ca - ty * sa; - shy = sx * sa + shy * ca; - sy = shx * sa + sy * ca; - ty = tx * sa + ty * ca; - sx = t0; - shx = t2; - tx = t4; - return *this; - } - - //------------------------------------------------------------------------ - inline const trans_affine& trans_affine::scale(double x, double y) - { - double mm0 = x; // Possible hint for the optimizer - double mm3 = y; - sx *= mm0; - shx *= mm0; - tx *= mm0; - shy *= mm3; - sy *= mm3; - ty *= mm3; - return *this; - } - - //------------------------------------------------------------------------ - inline const trans_affine& trans_affine::scale(double s) - { - double m = s; // Possible hint for the optimizer - sx *= m; - shx *= m; - tx *= m; - shy *= m; - sy *= m; - ty *= m; - return *this; - } - - //------------------------------------------------------------------------ - inline const trans_affine& trans_affine::premultiply(const trans_affine& m) - { - trans_affine t = m; - return *this = t.multiply(*this); - } - - //------------------------------------------------------------------------ - inline const trans_affine& trans_affine::multiply_inv(const trans_affine& m) - { - trans_affine t = m; - t.invert(); - return multiply(t); - } - - //------------------------------------------------------------------------ - inline const trans_affine& trans_affine::premultiply_inv(const trans_affine& m) - { - trans_affine t = m; - t.invert(); - return *this = t.multiply(*this); - } - - //------------------------------------------------------------------------ - inline void trans_affine::scaling_abs(double* x, double* y) const - { - // Used to calculate scaling coefficients in image resampling. - // When there is considerable shear this method gives us much - // better estimation than just sx, sy. - *x = sqrt(sx * sx + shx * shx); - *y = sqrt(shy * shy + sy * sy); - } - - //====================================================trans_affine_rotation - // Rotation matrix. sin() and cos() are calculated twice for the same angle. - // There's no harm because the performance of sin()/cos() is very good on all - // modern processors. Besides, this operation is not going to be invoked too - // often. - class trans_affine_rotation : public trans_affine - { - public: - trans_affine_rotation(double a) : - trans_affine(cos(a), sin(a), -sin(a), cos(a), 0.0, 0.0) - {} - }; - - //====================================================trans_affine_scaling - // Scaling matrix. x, y - scale coefficients by X and Y respectively - class trans_affine_scaling : public trans_affine - { - public: - trans_affine_scaling(double x, double y) : - trans_affine(x, 0.0, 0.0, y, 0.0, 0.0) - {} - - trans_affine_scaling(double s) : - trans_affine(s, 0.0, 0.0, s, 0.0, 0.0) - {} - }; - - //================================================trans_affine_translation - // Translation matrix - class trans_affine_translation : public trans_affine - { - public: - trans_affine_translation(double x, double y) : - trans_affine(1.0, 0.0, 0.0, 1.0, x, y) - {} - }; - - //====================================================trans_affine_skewing - // Sckewing (shear) matrix - class trans_affine_skewing : public trans_affine - { - public: - trans_affine_skewing(double x, double y) : - trans_affine(1.0, tan(y), tan(x), 1.0, 0.0, 0.0) - {} - }; - - - //===============================================trans_affine_line_segment - // Rotate, Scale and Translate, associating 0...dist with line segment - // x1,y1,x2,y2 - class trans_affine_line_segment : public trans_affine - { - public: - trans_affine_line_segment(double x1, double y1, double x2, double y2, - double dist) - { - double dx = x2 - x1; - double dy = y2 - y1; - if(dist > 0.0) - { - multiply(trans_affine_scaling(sqrt(dx * dx + dy * dy) / dist)); - } - multiply(trans_affine_rotation(atan2(dy, dx))); - multiply(trans_affine_translation(x1, y1)); - } - }; - - - //============================================trans_affine_reflection_unit - // Reflection matrix. Reflect coordinates across the line through - // the origin containing the unit vector (ux, uy). - // Contributed by John Horigan - class trans_affine_reflection_unit : public trans_affine - { - public: - trans_affine_reflection_unit(double ux, double uy) : - trans_affine(2.0 * ux * ux - 1.0, - 2.0 * ux * uy, - 2.0 * ux * uy, - 2.0 * uy * uy - 1.0, - 0.0, 0.0) - {} - }; - - - //=================================================trans_affine_reflection - // Reflection matrix. Reflect coordinates across the line through - // the origin at the angle a or containing the non-unit vector (x, y). - // Contributed by John Horigan - class trans_affine_reflection : public trans_affine_reflection_unit - { - public: - trans_affine_reflection(double a) : - trans_affine_reflection_unit(cos(a), sin(a)) - {} - - - trans_affine_reflection(double x, double y) : - trans_affine_reflection_unit(x / sqrt(x * x + y * y), y / sqrt(x * x + y * y)) - {} - }; - -} - - -#endif - diff --git a/kiva/gl/src/kiva_gl_affine_helpers.cpp b/kiva/gl/src/kiva_gl_affine_helpers.cpp deleted file mode 100644 index a053a4a3b..000000000 --- a/kiva/gl/src/kiva_gl_affine_helpers.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// (C) Copyright 2005-2022 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! -#include "kiva_gl_affine_helpers.h" -#include - -#define f_eq(a,b) (fabs((a)-(b)) < epsilon) - -namespace kiva_gl -{ - bool - is_identity(kiva_gl_agg::trans_affine& mat, double epsilon) - { - double temp[6]; - mat.store_to(temp); - return (f_eq(temp[0], 1.0) && f_eq(temp[1], 0.0) && - f_eq(temp[2], 0.0) && f_eq(temp[3], 1.0) && - f_eq(temp[4], 0.0) && f_eq(temp[5], 0.0)); - } - - bool - only_translation(kiva_gl_agg::trans_affine& mat, double epsilon) - { - double temp[6]; - mat.store_to(temp); - return (f_eq(temp[0], 1.0) && f_eq(temp[1], 0.0) && - f_eq(temp[2], 0.0) && f_eq(temp[3], 1.0)); - } - - bool - only_scale_and_translation(kiva_gl_agg::trans_affine& mat, double epsilon) - { - double temp[6]; - mat.store_to(temp); - return (f_eq(temp[1], 0.0) && f_eq(temp[2], 0.0)); - } - - void - get_translation(kiva_gl_agg::trans_affine& m, double* tx, double* ty) - { - double temp[6]; - m.store_to(temp); - *tx = temp[4]; - *ty = temp[5]; - } - - void - get_scale(kiva_gl_agg::trans_affine& m, double* dx, double* dy) - { - { - double temp[6]; - m.store_to(temp); - *dx = temp[0]; - *dy = temp[3]; - } - } - -} diff --git a/kiva/gl/src/kiva_gl_affine_helpers.h b/kiva/gl/src/kiva_gl_affine_helpers.h deleted file mode 100644 index 90be044d0..000000000 --- a/kiva/gl/src/kiva_gl_affine_helpers.h +++ /dev/null @@ -1,24 +0,0 @@ -// (C) Copyright 2005-2022 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! -#ifndef KIVA_GL_AFFINE_MATRIX_H -#define KIVA_GL_AFFINE_MATRIX_H - -#include "agg_trans_affine.h" - -namespace kiva_gl -{ - bool is_identity(kiva_gl_agg::trans_affine& mat, double epsilon=1e-3); - bool only_translation(kiva_gl_agg::trans_affine& mat, double epsilon=1e-3); - bool only_scale_and_translation(kiva_gl_agg::trans_affine& mat, double epsilon=1e-3); - void get_translation(kiva_gl_agg::trans_affine& m, double* tx, double* ty); - void get_scale(kiva_gl_agg::trans_affine& m, double* dx, double* dy); -} - -#endif diff --git a/kiva/gl/src/kiva_gl_basics.h b/kiva/gl/src/kiva_gl_basics.h deleted file mode 100644 index d39095c39..000000000 --- a/kiva/gl/src/kiva_gl_basics.h +++ /dev/null @@ -1,134 +0,0 @@ -// (C) Copyright 2005-2022 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! -#ifndef KIVA_GL_BASICS_H -#define KIVA_GL_BASICS_H - -#include "kiva_gl_constants.h" - -namespace kiva_gl -{ - -#ifdef _MSC_VER - #if _MSC_VER => 1300 - typedef signed __int64 INT64, *PINT64; - #else - #ifndef INT64 - #define INT64 __int64 - #endif - #endif -#endif -#ifdef __GNUC__ - typedef long long INT64; -#endif - -#ifdef max - #undef max -#endif -#ifdef min - #undef min -#endif - - - inline double max(double a, double b) - { - if (a>b) return a; - else return b; - } - - inline double min(double a, double b) - { - if (a=0) - { - if (y>=0) return 1; - else return 4; - } - else - { - if (y>=0) return 2; - else return 3; - } - } - - - // Determines whether or not two floating point numbers are - // essentially equal. This uses an aspect of the IEEE floating- - // point spec described in - // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm - // The code for both functions are from this same page. - // - // The basic idea is to cast the floats to ints and look at then - // number of floating point numbers between them. This take advantage - // of the fact that the IEEE representation puts the mantissa on the right, - // meaning that incrementing an int representation of a float yields the - // next representable float. The two's complement stuff is to ensure - // that comparisons across the 0 boundary work. - - // For floating point, a maxUlps (ULP=units in last place) is roughly - // equivalent to a precision of 1/8,000,000 to 1/16,000,000 - inline bool almost_equal(float A, float B, int maxUlps = 100) - { - if (A==B) return true; - // Make sure maxUlps is non-negative and small enough that the - // default NAN won't compare as equal to anything. - //assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024); - - int aInt = *(int*)&A; - // Make aInt lexicographically ordered as a twos-complement int - if (aInt < 0) - aInt = 0x80000000 - aInt; - - // Make bInt lexicographically ordered as a twos-complement int - int bInt = *(int*)&B; - if (bInt < 0) - bInt = 0x80000000 - bInt; - int intDiff = aInt - bInt; - if (intDiff < 0) - intDiff = -intDiff; - if (intDiff <= maxUlps) - return true; - return false; - } - - // For double, a maxUlps (ULP=units in last place) is roughly - // equivalent to a precision of 1/4e15 to 1/8e15. - inline bool almost_equal(double A, double B, int maxUlps = 10000) - { - // Make sure maxUlps is non-negative and small enough that the - // default NAN won't compare as equal to anything. - //assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024); - - if (A==B) return true; - - INT64 aInt = *(INT64*)&A; - // Make aInt lexicographically ordered as a twos-complement int - if (aInt < 0) - aInt = 0x80000000 - aInt; - - // Make bInt lexicographically ordered as a twos-complement int - INT64 bInt = *(INT64*)&B; - if (bInt < 0) - bInt = 0x80000000 - bInt; - INT64 intDiff = aInt - bInt; - if (intDiff < 0) - intDiff = -intDiff; - if (intDiff <= maxUlps) - return true; - return false; - } - -} - -#endif /* KIVA_GL_BASICS_H */ diff --git a/kiva/gl/src/kiva_gl_compiled_path.cpp b/kiva/gl/src/kiva_gl_compiled_path.cpp deleted file mode 100644 index a418e069e..000000000 --- a/kiva/gl/src/kiva_gl_compiled_path.cpp +++ /dev/null @@ -1,339 +0,0 @@ -// (C) Copyright 2005-2022 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! -#include "agg_bezier_arc.h" - -#include "kiva_gl_compiled_path.h" -#include "kiva_gl_basics.h" - -#include -#include - -using namespace kiva_gl; - -void -compiled_path::remove_all() -{ - //kiva_gl_agg::path_storage::remove_all(); - // fix me: call to base:: to appease VC++6.0 - this->base::remove_all(); - this->_has_curves = false; - //ptm = kiva_gl_agg::trans_affine(); -} - -void -compiled_path::begin_path() -{ - this->remove_all(); -} - -void -compiled_path::close_path() -{ - this->close_polygon(); -} - -void -compiled_path::move_to(double x, double y) -{ - this->ptm.transform(&x, &y); - // fix me: call to base:: to appease VC++6.0 - this->base::move_to(x, y); -} - -void -compiled_path::line_to(double x, double y) -{ - this->ptm.transform(&x, &y); - // fix me: call to base:: to appease VC++6.0 - this->base::line_to(x, y); -} - -void -compiled_path::quad_curve_to(double x_ctrl, double y_ctrl, - double x_to, double y_to) -{ - this->ptm.transform(&x_ctrl, &y_ctrl); - this->ptm.transform(&x_to, &y_to); - // fix me: call to base:: to appease VC++6.0 - this->base::curve3(x_ctrl, y_ctrl, x_to, y_to); - this->_has_curves = true; -} - -void -compiled_path::curve_to(double x_ctrl1, double y_ctrl1, - double x_ctrl2, double y_ctrl2, - double x_to, double y_to) -{ - this->ptm.transform(&x_ctrl1, &y_ctrl1); - this->ptm.transform(&x_ctrl2, &y_ctrl2); - this->ptm.transform(&x_to, &y_to); - // fix me: call to base:: to appease VC++6.0 - this->base::curve4(x_ctrl1, y_ctrl1, - x_ctrl2, y_ctrl2, - x_to, y_to); - this->_has_curves = true; -} - -void -compiled_path::arc(double x, double y, double radius, double start_angle, - double end_angle, bool cw) -{ - // Rather than try to transform the center and scale the axes correctly, - // we'll just create an untransformed agg curve, grab its Bezier control - // points, transform them, and manually add them to the path. - double sweep_angle = end_angle - start_angle; - if (cw) - { - sweep_angle = -(2*kiva_gl_agg::pi - sweep_angle); - } - kiva_gl_agg::bezier_arc aggarc(x, y, radius, radius, start_angle, sweep_angle); - - // Now manually transform each vertex and add it. For some reason, trying - // to transform aggarc in place and then using this->base::add_path() - // causes an access violation if cw=true (but works fine if cw=false). - int numverts = aggarc.num_vertices(); - container_type& vertices = this->vertices(); - double vx, vy; - unsigned int cmd; - aggarc.rewind(0); - for (int i = 0; i <= numverts/2; ++i) - { - cmd = aggarc.vertex(&vx, &vy); - if (!kiva_gl_agg::is_stop(cmd)) - { - this->ptm.transform(&vx, &vy); - vertices.add_vertex(vx, vy, cmd); - } - } - - this->_has_curves = true; -} - -void -compiled_path::arc_to(double x1, double y1, double x2, double y2, - double radius) -{ - // We have to do some work above and beyond what Agg offers. The Agg - // arc_to() happily creates rotated elliptical arcs, but to match the - // DisplayPDF spec, we need to compute the correct tangent points on - // the tangent lines defined by (cur_x,cur_y), (x1,y1), and (x2,y2) such - // that a circular arc of the given radius will be created. - - // The general approach is to transform the coordinates of the three - // points so that x1,y1 is at the origin, x0,y0 is to the right of x1,y1, - // and y0==y1. This should be just a translation followed by a rotation. - // We then compute the relative position of the circle's center as well - // as the start angle and then inverse transform these back. (The angular - // sweep of the arc is unchanged.) - - double x0=0, y0=0; - this->last_vertex(&x0, &y0); - this->ptm.inverse_transform(&x0, &y0); - - // Calculate the offset and rotation so that x1,y1, is at the origin (0,0), - // and x0, y0 sites on the positive x axis (right side of x1,y1). - kiva_gl_agg::trans_affine_translation xform(-x1, -y1); - double xform_angle = -atan2(y0-y1, x0-x1); - if (!kiva_gl::almost_equal(fmod(xform_angle, 2*kiva_gl_agg::pi), 0.0)) - { - xform *= kiva_gl_agg::trans_affine_rotation(xform_angle); - } - - // Transform and rotate the points. - xform.transform(&x0, &y0); - xform.transform(&x1, &y1); - xform.transform(&x2, &y2); - - assert(kiva_gl::almost_equal(y1, 0.0)); - assert(kiva_gl::almost_equal(x1, 0.0)); - - double cx, cy; // location of circle's center - double center_angle = atan2(y2, x2) / 2; - bool sweep_flag = (center_angle >= 0) ? false : true; - double hypotenuse = fabs(radius / sin(center_angle)); - cx = hypotenuse * cos(center_angle); - cy = hypotenuse * sin(center_angle); - - // determine if we need to draw a line to the first tangent point - // from the current pen position. - if (!kiva_gl::almost_equal(x0, cx)) - { - x0 = cx; - xform.inverse_transform(&x0, &y0); - this->line_to(x0, y0); - } - else - { - xform.inverse_transform(&x0, &y0); - } - - // determine the second tangent point - double point2_scale = cx / sqrt(x2*x2 + y2*y2); - x2 *= point2_scale; - y2 *= point2_scale; - xform.inverse_transform(&x2, &y2); - kiva_gl_agg::bezier_arc_svg aggarc(x0, y0, radius, radius, 0.0, false, sweep_flag, x2, y2); - - int numverts = aggarc.num_vertices(); - double *vertices = aggarc.vertices(); - double *v = NULL; - for (int i = 0; i <= numverts/2; ++i) - { - v = vertices + i*2; - this->ptm.transform(v, v+1); - } - - // I believe join_path is equivalent to the old add_path() with solid_path=true - this->join_path(aggarc, 0); - // This is the alternative call. - //this->concat_path(aggarc, 0); - - this->_has_curves = true; -} - -void -compiled_path::add_path(compiled_path& other_path) -{ - container_type& vertices = this->vertices(); - double x=0.0; - double y=0.0; - unsigned cmd; - - other_path.rewind(0); - cmd = other_path.vertex(&x, &y); - while (!kiva_gl_agg::is_stop(cmd)) - { - this->_has_curves |= kiva_gl_agg::is_curve(cmd); - this->ptm.transform(&x, &y); - vertices.add_vertex(x, y, cmd); - cmd = other_path.vertex(&x, &y); - } - this->concat_ctm(other_path.ptm); -} - -void -compiled_path::lines(double* pts, int Npts) -{ - this->move_to(pts[0], pts[1]); - for (int i=2; i < Npts*2; i+=2) - { - this->line_to(pts[i], pts[i+1]); - } -} - -void -compiled_path::line_set(double* start, int Nstart, double* end, int Nend) -{ - int num_pts = (Nstart > Nend) ? Nend : Nstart; - for (int i=0; i < num_pts*2; i += 2) - { - this->move_to(start[i], start[i+1]); - this->line_to(end[i], end[i+1]); - } -} - -void -compiled_path::rect(double x, double y, double sx, double sy) -{ - this->move_to(x, y); - this->line_to(x, y+sy); - this->line_to(x+sx, y+sy); - this->line_to(x+sx, y); - this->close_path(); -} - -void -compiled_path::rect(kiva_gl::rect_type &r) -{ - this->rect(r.x, r.y, r.w, r.h); -} - -void -compiled_path::rects(double* all_rects, int Nrects) -{ - double *tmp; - for (int i = 0; i < Nrects*4; i+=4) - { - tmp = &all_rects[i]; - this->rect(tmp[0], tmp[1], tmp[2], tmp[3]); - } -} - -void -compiled_path::rects(kiva_gl::rect_list_type &rectlist) -{ - for (kiva_gl::rect_list_type::iterator it=rectlist.begin(); it != rectlist.end(); ++it) - { - this->rect(it->x, it->y, it->w, it->h); - } -} - -void -compiled_path::_transform_ctm(kiva_gl_agg::trans_affine& m) -{ - this->ptm.premultiply(m); -} - -void -compiled_path::translate_ctm(double x, double y) -{ - kiva_gl_agg::trans_affine_translation m(x, y); - this->_transform_ctm(m); -} - -void -compiled_path::rotate_ctm(double angle) -{ - kiva_gl_agg::trans_affine_rotation m(angle); - this->_transform_ctm(m); -} - -void -compiled_path::scale_ctm(double sx, double sy) -{ - kiva_gl_agg::trans_affine_scaling m(sx, sy); - this->_transform_ctm(m); -} - -void -compiled_path::concat_ctm(kiva_gl_agg::trans_affine& m) -{ - kiva_gl_agg::trans_affine m_copy(m); - this->_transform_ctm(m_copy); -} - -void -compiled_path::set_ctm(kiva_gl_agg::trans_affine& m) -{ - this->ptm = kiva_gl_agg::trans_affine(m); -} - -kiva_gl_agg::trans_affine -compiled_path::get_ctm() -{ - return this->ptm; -} - -void -compiled_path::save_ctm() -{ - this->ptm_stack.push(this->ptm); -} - -void -compiled_path::restore_ctm() -{ - // !! need to check what error should be on empty stack. - if (!this->ptm_stack.empty()) - { - this->ptm = this->ptm_stack.top(); - this->ptm_stack.pop(); - } -} diff --git a/kiva/gl/src/kiva_gl_compiled_path.h b/kiva/gl/src/kiva_gl_compiled_path.h deleted file mode 100644 index cdb7cca1f..000000000 --- a/kiva/gl/src/kiva_gl_compiled_path.h +++ /dev/null @@ -1,138 +0,0 @@ -// (C) Copyright 2005-2022 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! -#ifndef KIVA_GL_COMPILED_PATH_H -#define KIVA_GL_COMPILED_PATH_H - -#include -#include - -#include "agg_basics.h" -#include "agg_path_storage.h" -#include "agg_trans_affine.h" - -#include "kiva_gl_rect.h" - - -namespace kiva_gl -{ - - class compiled_path : public kiva_gl_agg::path_storage - { - - /*------------------------------------------------------------------- - This extends the standard kiva_gl_agg::path_storage class to include - matrix transforms within the path definition. Doing so requires - overriding a number of methods to apply the matrix transformation - to vertices added to the path. - - The overridden methods are: - move_to - line_to - add_path - curve3 - curve4 - add_path - - There are a few others that need to be looked at also... - - In addition, we need to add several methods: - translate_ctm - rotate_ctm - scale_ctm - concat_ctm - set_ctm - get_ctm - save_ctm - restore_ctm - -------------------------------------------------------------------*/ - - // hack to get VC++ 6.0 to compile correctly - typedef kiva_gl_agg::path_storage base; - - /*------------------------------------------------------------------- - ptm -- path transform matrix. - - This is used to transform each point added to the path. It begins - as an identity matrix and accumulates every transform made during the - path formation. At the end of the path creation, the ptm holds - the total transformation seen during the path formation. It - can thus be multiplied with the ctm to determine what the ctm - should be after the compiled_path has been drawn. - - Todo: Should this default to the identity matrix or the current ctm? - -------------------------------------------------------------------*/ - kiva_gl_agg::trans_affine ptm; - - // ptm_stack is used for save/restore of the ptm - std::stack ptm_stack; - - // If the path contains curves, this value is true; - bool _has_curves; - - public: - // constructor - compiled_path() : base(), ptm(kiva_gl_agg::trans_affine()) - {} - - //--------------------------------------------------------------- - // path_storage interface - //--------------------------------------------------------------- - void remove_all(); - - void begin_path(); - void close_path(); - void move_to(double x, double y); - void line_to(double x, double y); - void quad_curve_to(double x_ctrl, double y_ctrl, - double x_to, double y_to); - void curve_to(double x_ctrl1, double y_ctrl1, - double x_ctrl2, double y_ctrl2, - double x_to, double y_to); - - // see graphics_context_base for descriptions of these functions - void arc(double x, double y, double radius, double start_angle, - double end_angle, bool cw=false); - void arc_to(double x1, double y1, double x2, double y2, - double radius); - - void add_path(compiled_path& other_path); - void lines(double* pts, int Npts); - void line_set(double* start, int Nstart, double* end, int Nend); - void rect(double x, double y, double sx, double sy); - void rect(kiva_gl::rect_type &rect); - void rects(double* all_rects, int Nrects); - void rects(kiva_gl::rect_list_type &rectlist); - - //--------------------------------------------------------------- - // compiled_path interface - //--------------------------------------------------------------- - - void _transform_ctm(kiva_gl_agg::trans_affine& m); - void translate_ctm(double x, double y); - void rotate_ctm(double angle); - void scale_ctm(double sx, double sy); - void concat_ctm(kiva_gl_agg::trans_affine& m); - void set_ctm(kiva_gl_agg::trans_affine& m); - kiva_gl_agg::trans_affine get_ctm(); - - //--------------------------------------------------------------- - // save/restore ptm methods - //--------------------------------------------------------------- - void save_ctm(); - void restore_ctm(); - - //--------------------------------------------------------------- - // Test whether curves exist in path. - //--------------------------------------------------------------- - inline bool has_curves() { return this->_has_curves;} - }; -} - -#endif diff --git a/kiva/gl/src/kiva_gl_constants.h b/kiva/gl/src/kiva_gl_constants.h deleted file mode 100644 index 56192ff96..000000000 --- a/kiva/gl/src/kiva_gl_constants.h +++ /dev/null @@ -1,152 +0,0 @@ -// (C) Copyright 2005-2022 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! -#ifndef KIVA_GL_CONSTANTS_H -#define KIVA_GL_CONSTANTS_H - -namespace kiva_gl -{ - - //----------------------------------------------------------------------- - // Line Cap Constants - //----------------------------------------------------------------------- - - enum line_cap_e - { - CAP_ROUND = 0, - CAP_BUTT = 1, - CAP_SQUARE = 2 - }; - - //----------------------------------------------------------------------- - // Line Join Constants - //----------------------------------------------------------------------- - - enum line_join_e - { - JOIN_ROUND = 0, - JOIN_BEVEL = 1, - JOIN_MITER = 2 - }; - - //----------------------------------------------------------------------- - // Path Drawing Mode Constants - // - // Path drawing modes for path drawing methods. - // The values are chosen so that bit flags can be checked in a later - // C version. - //----------------------------------------------------------------------- - - enum draw_mode_e - { - FILL = 1, - EOF_FILL = 2, - STROKE = 4, - FILL_STROKE = 5, - EOF_FILL_STROKE = 6 - }; - - //----------------------------------------------------------------------- - // The following enums are Agg-specific, and might not be applicable - // to other backends. - //----------------------------------------------------------------------- - - enum interpolation_e - { - nearest = 0, - bilinear = 1, - bicubic = 2, - spline16 = 3, - spline36 = 4, - sinc64 = 5, - sinc144 = 6, - sinc256 = 7, - blackman64 = 8, - blackman100 = 9, - blackman256 = 10 - }; - - enum pix_format_e - { - pix_format_undefined = 0, // By default. No conversions are applied - pix_format_gray8, // Simple 256 level grayscale - pix_format_rgb555, // 15 bit rgb. Depends on the byte ordering! - pix_format_rgb565, // 16 bit rgb. Depends on the byte ordering! - pix_format_rgb24, // R-G-B, one byte per color component - pix_format_bgr24, // B-G-R, native win32 BMP format. - pix_format_rgba32, // R-G-B-A, one byte per color component - pix_format_argb32, // A-R-G-B, native MAC format - pix_format_abgr32, // A-B-G-R, one byte per color component - pix_format_bgra32, // B-G-R-A, native win32 BMP format - - end_of_pix_formats - }; - - enum blend_mode_e - { - blend_normal, // pdf nrmal blending mode. - blend_copy, // overright destination with src ignoring any alpha setting. - /* - // these are copies from agg -- but not yet supported. - blend_clear, //----clear - blend_src, //----src - blend_dst, //----dst - blend_src_over, //----src_over - blend_dst_over, //----dst_over - blend_src_in, //----src_in - blend_dst_in, //----dst_in - blend_src_out, //----src_out - blend_dst_out, //----dst_out - blend_src_atop, //----src_atop - blend_dst_atop, //----dst_atop - blend_xor, //----xor - blend_plus, //----plus - blend_minus, //----minus - blend_multiply, //----multiply - blend_screen, //----screen - blend_overlay, //----overlay - blend_darken, //----darken - blend_lighten, //----lighten - blend_color_dodge, //----color_dodge - blend_color_burn, //----color_burn - blend_hard_light, //----hard_light - blend_soft_light, //----soft_light - blend_difference, //----difference - blend_exclusion, //----exclusion - blend_contrast, //----contrast - */ - end_of_e - }; - - enum marker_e - { - marker_square, - marker_diamond, - marker_circle, - marker_crossed_circle, - marker_semiellipse_left, - marker_semiellipse_right, - marker_semiellipse_up, - marker_semiellipse_down, - marker_triangle_left, - marker_triangle_right, - marker_triangle_up, - marker_triangle_down, - marker_four_rays, - marker_cross, - marker_x, - marker_dash, - marker_dot, - marker_pixel, - - end_of_markers - }; - -} -#endif diff --git a/kiva/gl/src/kiva_gl_dash_type.h b/kiva/gl/src/kiva_gl_dash_type.h deleted file mode 100644 index 474f69ef0..000000000 --- a/kiva/gl/src/kiva_gl_dash_type.h +++ /dev/null @@ -1,63 +0,0 @@ -// (C) Copyright 2005-2022 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! -#ifndef KIVA_GL_DASH_TYPE_H -#define KIVA_GL_DASH_TYPE_H - -#include - -namespace kiva_gl -{ - //----------------------------------------------------------------------- - // line dash type - //----------------------------------------------------------------------- - - class dash_type - { - public: - double phase; - std::vector pattern; - - // constructor - dash_type() - : phase(0) - , pattern(2, 0) - { - } - - // this forces even length of pattern - dash_type(double _phase, double* _pattern, int n) - : phase(_phase) - , pattern(n % 2 ? n+1 : n) - { - for (int i = 0; i < n; ++i) - { - pattern[i] = _pattern[i]; - } - - // for odd length patterns, use the first entry as the - // last gap size. (this is arbitrary) - if (n % 2) - { - pattern[n] = _pattern[0]; - } - } - - ~dash_type() {} - - bool is_solid() - { - return (pattern.size() == 2 && pattern[0] == 0.0); - } - - // TODO-PZW: define a copy constructor - }; -} - -#endif diff --git a/kiva/gl/src/kiva_gl_exceptions.h b/kiva/gl/src/kiva_gl_exceptions.h deleted file mode 100644 index c7546a4db..000000000 --- a/kiva/gl/src/kiva_gl_exceptions.h +++ /dev/null @@ -1,25 +0,0 @@ -// (C) Copyright 2005-2022 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! -#ifndef KIVA_GL_EXCEPTIONS_H -#define KIVA_GL_EXCEPTIONS_H - -namespace kiva_gl -{ - // exception codes used in graphics_context - enum { - not_implemented_error = 0, - ctm_rotation_error, - bad_clip_state_error, - even_odd_clip_error, - clipping_path_unsupported - }; -} - -#endif diff --git a/kiva/gl/src/kiva_gl_font_type.cpp b/kiva/gl/src/kiva_gl_font_type.cpp deleted file mode 100755 index d4ade8f2f..000000000 --- a/kiva/gl/src/kiva_gl_font_type.cpp +++ /dev/null @@ -1,130 +0,0 @@ -// (C) Copyright 2005-2022 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! -#include - -#include "kiva_gl_font_type.h" - -// In the python layer, the enthought.freetype library is used for font lookup. -// Since we can't use that, we emulate the functionality here. -#ifdef _WIN32 - const char* font_dirs[] = { - "c:/windows/fonts/", - "./", - "c:/winnt/fonts/", - "c:/windows/system32/fonts/", - }; -#elif defined SUNOS - const char* font_dirs[] = { - "/usr/openwin/lib/X11/fonts", - }; -#elif defined DARWIN - const char* font_dirs[] = { - "/Library/Fonts/", - }; -#else - const char* font_dirs[] = { - "./", - "/usr/lib/X11/fonts/", - "/usr/share/fonts/truetype/", - "/usr/share/fonts/msttcorefonts/", - "/var/lib/defoma/x-ttcidfont-conf.d/dirs/TrueType/", - "/usr/share/fonts/truetype/msttcorefonts/", -}; -#endif - -const char* freetype_suffixes[] = { ".ttf", ".pfa", ".pfb" }; - -// This really only for testing purposes. Font searching is superceded by the code borrowed from -// matplotlib, however, since that is in python, we can't load a font from C++ for C++ tests. -// Therefore this simple function is left in. -kiva_gl::font_type::font_type(std::string _name, int _size, int _family, - int _style, int _encoding, bool validate) -: name(_name) -, size(_size) -, family(_family) -, style(_style) -, encoding(_encoding) -, _is_loaded(false) -{ - std::string full_file_name; - if (validate) - { - if (this->name == "") - { - this->_is_loaded = false; - } - else - { - for (unsigned int d=0; d < sizeof(font_dirs) / sizeof(char*); d++) - { - for (unsigned int e=0; e < sizeof(freetype_suffixes) / sizeof(char*); e++) - { - full_file_name = font_dirs[d]; - full_file_name.append(this->name); - full_file_name.append(freetype_suffixes[e]); - FILE *f = fopen(full_file_name.c_str(), "rb"); - if (f != NULL) - { - fclose(f); - this->filename = full_file_name; - this->_is_loaded = true; - break; - } - } - } - } - this->filename = ""; - this->name = ""; - this->_is_loaded = false; - } - else - { - this->filename = this->name; - this->_is_loaded = true; - } -} - -kiva_gl::font_type::font_type(const kiva_gl::font_type &font) -: name(font.name) -, filename(font.filename) -, size(font.size) -, _is_loaded(font.is_loaded()) -{ - this->family = font.family; - this->style = font.style; -} - -kiva_gl::font_type& -kiva_gl::font_type::operator=(const kiva_gl::font_type& font) -{ - this->size = font.size; - this->family = font.family; - this->style = font.style; - this->encoding = font.encoding; - this->name = font.name; - this->filename = font.filename; - this->_is_loaded = font.is_loaded(); - return *this; -} - -int -kiva_gl::font_type::change_filename(std::string _filename) -{ - FILE *f = fopen(_filename.c_str(), "rb"); - if (f != NULL) - { - fclose(f); - this->filename = _filename; - this->_is_loaded = true; - return 1; - } - - return 0; -} diff --git a/kiva/gl/src/kiva_gl_font_type.h b/kiva/gl/src/kiva_gl_font_type.h deleted file mode 100644 index 5ddaa1383..000000000 --- a/kiva/gl/src/kiva_gl_font_type.h +++ /dev/null @@ -1,65 +0,0 @@ -// (C) Copyright 2005-2022 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! -#ifndef KIVA_GL_FONT_TYPE_H -#define KIVA_GL_FONT_TYPE_H - -#include - -#ifdef _MSC_VER -// Turn off MSDEV warning about truncated long identifiers -#pragma warning(disable:4786) -#endif - -namespace kiva_gl -{ - class font_type - { - public: - std::string name; - std::string filename; - int size; - int family; - int style; - int encoding; - - // Constructors - - // Creates a font object. By default, searches the hardcoded - // font paths for a file named like the face name; to override - // this, set validate=false. - font_type(std::string _name="Arial", - int _size=12, - int _family=0, - int _style=0, - int _encoding=0, - bool validate=true); - - font_type(const font_type &font); - font_type &operator=(const font_type& font); - - int change_filename(std::string _filename); - - // Is the font loaded properly? - inline bool is_loaded() const { return _is_loaded; } - - private: - bool _is_loaded; - }; - - inline bool operator==(font_type &a, font_type &b) - { - return (a.size == b.size) && (a.name == b.name) && - (a.style == b.style) && (a.encoding == b.encoding) && - (a.family == b.family); - } - -} - -#endif diff --git a/kiva/gl/src/kiva_gl_graphics_context.cpp b/kiva/gl/src/kiva_gl_graphics_context.cpp deleted file mode 100644 index e35656703..000000000 --- a/kiva/gl/src/kiva_gl_graphics_context.cpp +++ /dev/null @@ -1,1220 +0,0 @@ -// (C) Copyright 2005-2022 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! - -// #ifndef MULTI_DRAW_ELEMENTS -// #define MULTI_DRAW_ELEMENTS glMultiDrawElements -// #endif - -#include -#include -#include - -#include "kiva_gl_affine_helpers.h" -#include "kiva_gl_exceptions.h" -#include "kiva_gl_rect.h" -#include "kiva_gl_graphics_context.h" - -using namespace kiva_gl; - -#ifndef CALLBACK -#define CALLBACK -#endif -#ifndef M_PI -#define M_PI 3.1415926535 -#endif - -#define EXPAND_COLOR(c) c->r, c->g, c->b, (c->a * this->state.alpha) - -typedef double VertexType; -struct PointType { VertexType x,y,z; }; -typedef std::vector PointListType; - -static void _submit_path_points(PointListType const & points, - bool polygon, bool fill); -static void CALLBACK _combine_callback(GLdouble coords[3], GLdouble *vert_data[4], - GLfloat weight[4], GLdouble **dataOut); -static void CALLBACK _vertex_callback(GLvoid *vertex); - -gl_graphics_context::gl_graphics_context(int width, int height, - kiva_gl::pix_format_e format) -: graphics_context_base(kiva_gl::nearest) -, m_width(width) -, m_height(height) -, m_gl_initialized(false) -, m_pixfmt(format) -{ -} - -gl_graphics_context::~gl_graphics_context() -{ - if (m_gl_initialized) - { - this->gl_cleanup(); - } -} - -int -gl_graphics_context::width() -{ - return m_width; -} - -int -gl_graphics_context::height() -{ - return m_height; -} - -int -gl_graphics_context::stride() -{ - return 1; -} - -void -gl_graphics_context::gl_init() -{ - glViewport(0, 0, m_width, m_height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, m_width, 0, m_height, 1, -1); - glMatrixMode(GL_MODELVIEW); - //glPushMatrix(); - glLoadIdentity(); - - // Use scissors to implement clipping - glEnable(GL_SCISSOR_TEST); - - // Need to set up blending for antialiasing - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE); - glHint(GL_POLYGON_SMOOTH_HINT, GL_DONT_CARE); - - // Clear the clip region - // This is important. Since GL maintains a persistent, global context - // across the application, we may very well inherit the scissor mask - // from a clip_to_rect() call on a previous GC. - clip_to_rect(0, 0, m_width, m_height); -} - -void -gl_graphics_context::gl_cleanup() -{ - //glMatrixMode(GL_MODELVIEW); - //glPopMatrix(); -} - -kiva_gl::pix_format_e -gl_graphics_context::format() -{ - return m_pixfmt; -} - -void -gl_graphics_context::save_state() -{ - graphics_context_base::save_state(); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); -} - -void -gl_graphics_context::restore_state() -{ - if (this->state_stack.size() == 0) - { - return; - } - - this->state = this->state_stack.top(); - this->state_stack.pop(); - this->path.restore_ctm(); - - // Restore the clip state: - // Compute the intersection of all the rects and use those as - // the clip box - if (this->state.use_rect_clipping()) - { - if (this->state.device_space_clip_rects.size() > 0) - { - kiva_gl::rect_list_type rects = disjoint_intersect(this->state.device_space_clip_rects); - - // XXX: Right now we don't support disjoint clip rects. To implement - // this, we would probably want to use a mask or stencil, or just - // re-render with each clip rect set as the scissor. - // XXX: figure out better way to round out the floating-point - // dimensions for kiva_rect than just casting to int(). - kiva_gl::rect_iterator it = rects.begin(); - glScissor(int(it->x), int(it->y), int(it->w), int(it->h)); - } - } - else - { - throw clipping_path_unsupported; - } - - // Restore the transformation matrices - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - -} - -void -gl_graphics_context::begin_page() -{ - glClearColor(1.f, 1.f, 1.f, 0.f); - glClear(GL_COLOR_BUFFER_BIT); -} - -void -gl_graphics_context::clip() -{ - throw kiva_gl::not_implemented_error; -} - -void -gl_graphics_context::even_odd_clip() -{ - throw kiva_gl::not_implemented_error; -} - -void -gl_graphics_context::clip_to_rect(double x, double y, double sx, double sy) -{ - kiva_gl::rect_type tmp(x, y, sx, sy); - clip_to_rect(tmp); -} - -void -gl_graphics_context::clip_to_rect(kiva_gl::rect_type &rect) -{ - this->path.remove_all(); - if (!this->state.use_rect_clipping()) - { - throw clipping_path_unsupported; - } - - kiva_gl::rect_type device_rect(transform_clip_rectangle(rect)); - if (this->state.device_space_clip_rects.size() == 1) - { - kiva_gl::rect_type old(this->state.device_space_clip_rects.back()); - this->state.device_space_clip_rects.pop_back(); - kiva_gl::rect_type newrect(kiva_gl::disjoint_intersect(old, device_rect)); - if ((newrect.w < 0) || (newrect.h < 0)) - { - // new clip rectangle doesn't intersect anything, so we push on - // an empty rect as the new clipping region. - glScissor(0, 0, 0, 0); - this->state.device_space_clip_rects.push_back(kiva_gl::rect_type(0, 0, -1, -1)); - } - else - { - glScissor(int(newrect.x), int(newrect.y), - int(newrect.w), int(newrect.h)); - this->state.device_space_clip_rects.push_back(newrect); - } - } - else - { - // we need to compute the intersection of the new rectangle with - // the current set of clip rectangles. we assume that the existing - // clip_rects are a disjoint set. - this->state.device_space_clip_rects = kiva_gl::disjoint_intersect( - this->state.device_space_clip_rects, device_rect); - - if (this->state.device_space_clip_rects.size() == 0) - { - glScissor(0, 0, 0, 0); - this->state.device_space_clip_rects.push_back(kiva_gl::rect_type(0, 0, -1, -1)); - } - else - { - kiva_gl::rect_list_type rects = disjoint_intersect(this->state.device_space_clip_rects); - - // XXX: Right now we don't support disjoint clip rects. - // (same problem as in restore_state()) - kiva_gl::rect_iterator it = rects.begin(); - glScissor(int(it->x), int(it->y), int(it->w), int(it->h)); - } - } -} - -void -gl_graphics_context::clip_to_rects(double* new_rects, int Nrects) -{ - printf("Clip to rects() unsupported\n"); -} - -void -gl_graphics_context::clip_to_rects(kiva_gl::rect_list_type &rects) -{ - printf("Clip to rects() unsupported\n"); -} - -void -gl_graphics_context::clear_clip_path() -{ - // clear the existing clipping paths - this->state.clipping_path.remove_all(); - this->state.device_space_clip_rects.clear(); - - // set everything visible again. - glScissor(0, 0, m_width, m_height); - - // store the new clipping rectangle back into the first - // rectangle of the graphics state clipping rects. - this->state.device_space_clip_rects.push_back(kiva_gl::rect_type(0, 0, m_width, m_height)); -} - -// XXX: This is cut and paste from graphics_context.h; refactor into base -// class. -kiva_gl::rect_type -gl_graphics_context::transform_clip_rectangle(const kiva_gl::rect_type &rect) -{ - // This only works if the ctm doesn't have any rotation. - // otherwise, we need to use a clipping path. Test for this. - kiva_gl_agg::trans_affine tmp(this->path.get_ctm()); - if (!only_scale_and_translation(tmp)) - { - throw kiva_gl::ctm_rotation_error; - } - - double x = rect.x; - double y = rect.y; - double x2 = rect.x2(); - double y2 = rect.y2(); - this->path.get_ctm().transform(&x, &y); - this->path.get_ctm().transform(&x2, &y2); - - // fix me: How should we round here? - // maybe we should lrint, but I don't think it is portable. See - // here: http://www.cs.unc.edu/~sud/tips/Programming_Tips.html - x = int(floor(x+0.5)); - y = int(floor(y+0.5)); - - // subtract 1 to account for agg (inclusive) vs. kiva (exclusive) clipping - x2 = int(floor(x2+0.5))-1; - y2 = int(floor(y2+0.5))-1; - - return kiva_gl::rect_type(x, y, x2-x, y2-y); -} - -int -gl_graphics_context::get_num_clip_regions() -{ - return this->state.device_space_clip_rects.size(); -} - -kiva_gl::rect_type -gl_graphics_context::get_clip_region(unsigned int i) -{ - throw kiva_gl::not_implemented_error; -} - -void -gl_graphics_context::clear(kiva_gl_agg::rgba value) -{ - glClearColor(float(value.r), float(value.g), float(value.b), float(value.a)); - glClear(GL_COLOR_BUFFER_BIT); -} - -void -gl_graphics_context::fill_path() -{ - draw_path(FILL); -} - -void -gl_graphics_context::eof_fill_path() -{ - draw_path(EOF_FILL); -} - -void -gl_graphics_context::stroke_path() -{ - draw_path(STROKE); -} - -void -gl_graphics_context::gl_render_path(kiva_gl::compiled_path *path, bool polygon, bool fill) -{ - if ((path == NULL) || (path->total_vertices() == 0)) - { - return; - } - - unsigned command = 0; - PointListType pointList; - - // Set the matrix mode so we support move_to commands - glMatrixMode(GL_MODELVIEW); - - // Records the last move_to command position so that when - // we finally encounter the first line_to, we can use this - // vertex as the starting vertex. - bool first_vertex_drawn = false; - PointType v0 = {0.f, 0.f, 0.f}; - PointType v = {0.f, 0.f, 0.f}; - PointType vv = {0.f, 0.f, 0.f}; - VertexType c1x, c1y, ccx, ccy, c2x, c2y, c3x, c3y; - VertexType t, t2, t3, u, u2, u3; - unsigned int j; - unsigned int _Npoints = 100; - - // make space for points - pointList.reserve(path->total_vertices()); - - for (unsigned int i=0; i < path->total_vertices(); ++i) - { - command = path->vertex(i, &v.x, &v.y); - switch (command & kiva_gl_agg::path_cmd_mask) - { - case kiva_gl_agg::path_cmd_line_to: - if (!first_vertex_drawn) - { - pointList.push_back(v0); - first_vertex_drawn = true; - } - pointList.push_back(v); - break; - - case kiva_gl_agg::path_cmd_end_poly: - // We shouldn't need to do anything because if this is a closed path - // - //if (command & kiva_gl_agg::path_flags_close) - // glVertex2f(x0, y0); - break; - - case kiva_gl_agg::path_cmd_curve3: - // FIXME: refactor! - if (!first_vertex_drawn) - { - pointList.push_back(v0); - first_vertex_drawn = true; - } - path->vertex(i+1, &ccx, &ccy); - path->vertex(i+2, &c3x, &c3y); - i += 2; - c1x = (v.x + ccx + ccx) / 3.0; - c1y = (v.y + ccy + ccy) / 3.0; - c2x = (c3x + ccx + ccx) / 3.0; - c2y = (c3y + ccy + ccy) / 3.0; - for (j=1; j<=_Npoints; ++j) - { - t = ((VertexType)j) / _Npoints; - t2 = t*t; - t3 = t2*t; - u = 1 - t; - u2 = u*u; - u3 = u2*u; - vv.x = v.x * u3 + 3*(c1x*t*u2 + c2x*t2*u) + c3x*t3; - vv.y = v.y * u3 + 3*(c1y*t*u2 + c2y*t2*u) + c3y*t3; - pointList.push_back(vv); - } - break; - - case kiva_gl_agg::path_cmd_curve4: - if (!first_vertex_drawn) - { - pointList.push_back(v0); - first_vertex_drawn = true; - } - // The current point is implicitly the first control point - v0 = pointList.back(); - c1x = v.x; c1y = v.y; - v.x = v0.x; v.y = v0.y; - path->vertex(i+1, &c2x, &c2y); - path->vertex(i+2, &c3x, &c3y); - i += 2; - for (j=1; j<=_Npoints; ++j) - { - t = ((VertexType)j) / _Npoints; - t2 = t*t; - t3 = t2*t; - u = 1 - t; - u2 = u*u; - u3 = u2*u; - vv.x = v.x * u3 + 3*(c1x*t*u2 + c2x*t2*u) + c3x*t3; - vv.y = v.y * u3 + 3*(c1y*t*u2 + c2y*t2*u) + c3y*t3; - pointList.push_back(vv); - } - break; - - // The following commands are ignored. - case kiva_gl_agg::path_cmd_move_to: - if (!pointList.empty()) - { - // do a full glBegin/glEnd sequence for the points in the buffer - _submit_path_points(pointList, polygon, fill); - // flush - pointList.clear(); - } - v0.x = v.x; - v0.y = v.y; - first_vertex_drawn = false; - break; - - case kiva_gl_agg::path_cmd_ubspline: - break; - - // XXX: This case number is already used?? - //case kiva_gl_agg::path_cmd_mask: - // break; - - // Unsupported - // XXX: We need to have better error handling/reporting from the C++ - // layer up to the Python layer. - case kiva_gl_agg::path_cmd_catrom: - case kiva_gl_agg::path_cmd_curveN: - break; - - } - } - - // submit the points - if (!pointList.empty()) - { - _submit_path_points(pointList, polygon, fill); - } -} - -void -gl_graphics_context::gl_render_points(double** points, bool polygon, - bool fill, kiva_gl::draw_mode_e mode) -{ -} - -void -gl_graphics_context::draw_path(draw_mode_e mode) -{ - // XXX: This is a direct transcription from basecore2d. The algorithm - // and approach can probably be improved tremendously for OpenGL. - - kiva_gl_agg::rgba *line_color = &this->state.line_color; - kiva_gl_agg::rgba *fill_color = &this->state.fill_color; - - // CNP - if (this->state.should_antialias) - { - glEnable(GL_LINE_SMOOTH); - glEnable(GL_POLYGON_SMOOTH); - } - else - { - glDisable(GL_LINE_SMOOTH); - glDisable(GL_POLYGON_SMOOTH); - } - - // Check to see if we have closed polygons - typedef kiva_gl_agg::path_storage::container_type::value_type VertexType; - unsigned numvertices = this->path.total_vertices(); - bool polygon = false; - if (numvertices > 1) - { - // Get the first vertex - VertexType x0, y0, xf, yf; - this->path.vertex(0, &x0, &y0); - - // Go backwards from the last vertex until we find an actual line_to - // or curve3 or curve4 comand. - for (int i=numvertices-1; i>0; --i) - { - unsigned cmd = this->path.vertex(i, &xf, &yf); - if (((cmd & kiva_gl_agg::path_cmd_mask) == kiva_gl_agg::path_cmd_curve3) || - ((cmd & kiva_gl_agg::path_cmd_mask) == kiva_gl_agg::path_cmd_curve4) || - ((cmd & kiva_gl_agg::path_cmd_mask) == kiva_gl_agg::path_cmd_line_to)) - { - if ((x0 == xf) && (y0 == yf)) - { - polygon = true; - } - break; - } - - if ((cmd & kiva_gl_agg::path_cmd_mask) == kiva_gl_agg::path_cmd_end_poly) - { - polygon = true; - break; - } - } - } - - // Fill the path, if necessary - if (mode != STROKE) - { - // device_update_fill_state - glColor4f(EXPAND_COLOR(fill_color)); - - // call gl_render_path() - gl_render_path(&this->path, true, true); - } - - // Stroke the path, if necessary - if (mode != FILL) - { - // CNP - // device_update_line_state - glColor4f(EXPAND_COLOR(line_color)); - glLineWidth(this->state.line_width); - - if (this->state.line_dash.is_solid()) - { - glDisable(GL_LINE_STIPPLE); - } - else - { - glDisable(GL_LINE_STIPPLE); - } - - gl_render_path(&this->path, polygon, false); - } - - this->path.remove_all(); -} - -void -gl_graphics_context::draw_rect(double rect[4], draw_mode_e mode) -{ - kiva_gl_agg::rgba *line_color = &this->state.line_color; - kiva_gl_agg::rgba *fill_color = &this->state.fill_color; - - // CNP - if (this->state.should_antialias) - { - glEnable(GL_LINE_SMOOTH); - glEnable(GL_POLYGON_SMOOTH); - } - else - { - glDisable(GL_LINE_SMOOTH); - glDisable(GL_POLYGON_SMOOTH); - } - - this->path.get_ctm().translation(rect, rect+1); - - // Fill the rect first - if (mode != STROKE) - { - glColor4f(EXPAND_COLOR(fill_color)); - glRectf(rect[0], rect[1], rect[0]+rect[2], rect[1]+rect[3]); - } - - // Stroke the path - if (mode != FILL) - { - // CNP - glColor4f(EXPAND_COLOR(line_color)); - glLineWidth(this->state.line_width); - - if (this->state.line_dash.is_solid()) - { - glDisable(GL_LINE_STIPPLE); - } - else - { - glDisable(GL_LINE_STIPPLE); - } - - glBegin(GL_LINE_LOOP); - glVertex2f(rect[0], rect[1]); - glVertex2f(rect[0], rect[1] + rect[3]); - glVertex2f(rect[0] + rect[2], rect[1] + rect[3]); - glVertex2f(rect[0] + rect[2], rect[1]); - glEnd(); - } - this->path.remove_all(); -} - -int -gl_graphics_context::draw_marker_at_points(double *pts, int Npts, - int size, kiva_gl::marker_e type) -{ - kiva_gl_agg::rgba *line_color = &this->state.line_color; - kiva_gl_agg::rgba *fill_color = &this->state.fill_color; - bool do_fill = (fill_color->a != 0); - bool do_stroke = ((line_color->a != 0) && (this->state.line_width > 0.0)); - - if (do_stroke) - { - glLineWidth(this->state.line_width); - } - - // Get the current origin - double x0=0.0, y0=0.0; - this->path.get_ctm().translation(&x0, &y0); - - kiva_gl::draw_mode_e draw_mode = FILL; - if (do_fill & !do_stroke) - { - draw_mode = FILL; - } - else if (do_stroke & !do_fill) - { - draw_mode = STROKE; - } - else if (do_fill & do_stroke) - { - draw_mode = FILL_STROKE; - } - GLuint fill_list, stroke_list; - bool list_created = false; - - switch (type) - { - // Simple paths that only need to be stroked - case kiva_gl::marker_x: - draw_x_marker(pts, Npts, size, draw_mode, x0, y0); - break; - - case kiva_gl::marker_cross: - draw_cross(pts, Npts, size, draw_mode, x0, y0); - break; - - case kiva_gl::marker_dot: - draw_dot(pts, Npts, size, draw_mode, x0, y0); - break; - - case kiva_gl::marker_pixel: - draw_pixel(pts, Npts, size, draw_mode, x0, y0); - break; - - // Paths that need to be filled and stroked - // There are experimental approaches taken for drawing squares and - // diamonds, so they are in their own block here. There's no reason - // why they cannot be treated in the same way as the circle and - // triangle markers. - case kiva_gl::marker_square: - draw_square(pts, Npts, size, draw_mode, x0, y0); - break; - - case kiva_gl::marker_diamond: - draw_diamond(pts, Npts, size, draw_mode, x0, y0); - break; - - case kiva_gl::marker_crossed_circle: - draw_crossed_circle(pts, Npts, size, draw_mode, x0, y0); - break; - - case kiva_gl::marker_circle: - fill_list = make_marker_lists(&kiva_gl::gl_graphics_context::circle_path_func, draw_mode, size); - list_created = true; - // Fall through to next case - case kiva_gl::marker_triangle_up: - if (!list_created) - { - fill_list = make_marker_lists(&kiva_gl::gl_graphics_context::triangle_up_func, draw_mode, size); - list_created = true; - } - // Fall through to next case - case kiva_gl::marker_triangle_down: - if (!list_created) - { - fill_list = make_marker_lists(&kiva_gl::gl_graphics_context::triangle_down_func, draw_mode, size); - list_created = true; - } - stroke_list = fill_list + 1; - draw_display_list_at_pts(fill_list, stroke_list, pts, Npts, draw_mode, x0, y0); - glDeleteLists(fill_list, 2); - break; - - default: - return 0; - } - // Indicate success - return 1; -} - -void -gl_graphics_context::draw_path_at_points(double *pts, int Npts, - kiva_gl::compiled_path &marker, - draw_mode_e mode) -{ - return; -} - -int -gl_graphics_context::draw_image(kiva_gl::graphics_context_base* img, - double rect[4], bool force_copy) -{ - return 0; -} - -int gl_graphics_context::draw_image(kiva_gl::graphics_context_base* img) -{ - return 0; -} - -//--------------------------------------------------------------------------- -// Marker drawing methods -//--------------------------------------------------------------------------- - -void -gl_graphics_context::draw_display_list_at_pts(GLuint list, double *pts, int Npts, - kiva_gl::draw_mode_e mode, - double x0, double y0) -{ - draw_display_list_at_pts(list, list, pts, Npts, mode, x0, y0); -} - -void -gl_graphics_context::draw_display_list_at_pts(GLuint fill_list, GLuint stroke_list, - double *pts, int Npts, - kiva_gl::draw_mode_e mode, - double x0, double y0) -{ - kiva_gl_agg::rgba *colors[2] = { &this->state.fill_color, &this->state.line_color }; - GLuint lists[2] = { fill_list, stroke_list }; - float x = 0.f, y = 0.f; - for (int pass=0; pass < 2; ++pass) - { - if (((pass == 0) && ((mode == FILL) || (mode == FILL_STROKE))) || - ((pass == 1) && ((mode == STROKE) || (mode == FILL_STROKE)))) - { - glColor4f(EXPAND_COLOR(colors[pass])); - for (int i=0; i < Npts; ++i) - { - x = pts[i*2] + x0; - y = pts[i*2 + 1] + y0; - glTranslatef(x, y, 0.0); - glCallList(lists[pass]); - glTranslatef(-x, -y, 0.0); - } - } - } - -#if 0 - if ((mode == FILL) || (mode == FILL_STROKE)) - { - glColor4f(EXPAND_COLOR(fill_color)); - for (int i=0; i < Npts; ++i) - { - x = pts[i*2] + x0; - y = pts[i*2 + 1] + y0; - glTranslatef(x, y, 0.0); - glCallList(stroke_list); - glTranslatef(-x, -y, 0.0); - } - } - if ((mode == STROKE) || (mode == FILL_STROKE)) - { - glColor4f(EXPAND_COLOR(line_color)); - for (int i=0; i < Npts; ++i) - { - x = pts[i*2] + x0; - y = pts[i*2 + 1] + y0; - glTranslatef(x, y, 0.0); - glCallList(fill_list); - glTranslatef(-x, -y, 0.0); - } - } -#endif -} - -GLuint -gl_graphics_context::make_marker_lists(PathDefinitionFunc path_func, - kiva_gl::draw_mode_e mode, - int size) -{ - GLuint fill_list = glGenLists(2); - GLuint stroke_list = fill_list + 1; - for (int dummy=0; dummy < 2; ++dummy) - { - if (dummy == 0) - { - glNewList(fill_list, GL_COMPILE); - glBegin(GL_POLYGON); - } - else - { - glNewList(stroke_list, GL_COMPILE); - glBegin(GL_LINE_LOOP); - } - ((this)->*(path_func))(size); - glEnd(); - glEndList(); - } - - return fill_list; -} - -void -gl_graphics_context::draw_square(double *pts, int Npts, int size, - kiva_gl::draw_mode_e mode, - double x0, double y0) -{ - kiva_gl_agg::rgba *line_color = &this->state.line_color; - kiva_gl_agg::rgba *fill_color = &this->state.fill_color; - - // We build up a VertexArray of the vertices of all the squares. - // We then use glDrawElements with GL_QUADS or GL_LINE_LOOP to fill - // and stroke the markers. - - // The vertex array contains all the vertices in all the rects. - // The convention is that each rect's vertices are stored - // clockwise, starting with the lower-left vertex. - GLdouble *vertices = new GLdouble[Npts*4*2]; - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_DOUBLE, 0, vertices); - for (int i=0; istate.line_color; - kiva_gl_agg::rgba *fill_color = &this->state.fill_color; - - // Each marker consists of four vertices in this order: left, top, right, bottom. - GLdouble *vertices = new GLdouble[Npts * 4 * 2]; - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_DOUBLE, 0, vertices); - - float s = size / 2.0; - for (int i=0; istate.line_color; - glColor4f(EXPAND_COLOR(line_color)); - - glBegin(GL_POINTS); - for (int i=0; i < Npts; ++i) - { - glVertex2f(pts[i*2] + x0, pts[i*2+1] + y0); - } - glEnd(); -} - -void -_submit_path_points(PointListType const & points, bool polygon, bool fill) -{ - // Uncomment this when we turn the glPolygonMode calls back on (below) - //glPushAttrib(GL_POLYGON_BIT); - if (polygon) - { - if (fill) - { -#if defined(_MSC_VER) || defined(__MINGW32__) - typedef void (__stdcall*cbFunc)(void); -#else - typedef void (*cbFunc)(); -#endif - GLUtesselator* pTess = gluNewTess(); - gluTessCallback(pTess, GLU_TESS_VERTEX, (cbFunc)&_vertex_callback); - gluTessCallback(pTess, GLU_TESS_BEGIN, (cbFunc)&glBegin); - gluTessCallback(pTess, GLU_TESS_END, (cbFunc)&glEnd); - gluTessCallback(pTess, GLU_TESS_COMBINE, (cbFunc)&_combine_callback); - gluTessBeginPolygon(pTess, NULL); - gluTessBeginContour(pTess); - - // XXX: For some reason setting the polygon mode breaks pyglet's - // font rendering. It doesn't really have an effect on any of - // Kiva's rendering right now, so it's commented out for now. - //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - - for (int i=0; i < points.size(); ++i) - { - VertexType * pV = (VertexType *)&points[i]; - gluTessVertex(pTess, (GLdouble*)pV, (GLvoid*)pV); - } - - gluTessEndContour(pTess); - gluTessEndPolygon(pTess); - gluDeleteTess(pTess); - } - else - { - glBegin(GL_LINE_LOOP); - //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - - for (int i=0; i < points.size(); ++i) - { - glVertex2dv((VertexType *)&points[i]); - } - - glEnd(); - } - } - else - { - glBegin(GL_LINE_STRIP); - - for (int i=0; i < points.size(); ++i) - { - glVertex2dv((VertexType *)&points[i]); - } - - glEnd(); - } - - //glPopAttrib(); -} - -void -CALLBACK -_combine_callback(GLdouble coords[3], GLdouble *vert_data[4], - GLfloat weight[4], GLdouble **dataOut) -{ - GLdouble *vertex = (GLdouble *)malloc(3 * sizeof(GLdouble)); - vertex[0] = coords[0]; - vertex[1] = coords[1]; - vertex[2] = coords[2]; - - *dataOut = vertex; -} - -void -CALLBACK -_vertex_callback(GLvoid *vertex) -{ - GLdouble *ptr = (GLdouble *)vertex; - glVertex3dv(ptr); -} diff --git a/kiva/gl/src/kiva_gl_graphics_context.h b/kiva/gl/src/kiva_gl_graphics_context.h deleted file mode 100644 index 616f30c82..000000000 --- a/kiva/gl/src/kiva_gl_graphics_context.h +++ /dev/null @@ -1,164 +0,0 @@ -// (C) Copyright 2005-2022 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! -#ifndef KIVA_GL_GRAPHICS_CONTEXT_H -#define KIVA_GL_GRAPHICS_CONTEXT_H - -#ifdef _MSC_VER -#pragma warning(disable:4786) -#endif - -#ifdef __DARWIN__ - #include - #include -#else - #ifdef _MSC_VER - #include - #endif - #include - #include - - // The following mechanism is necessary in order to use MultiDrawElements - // on Windows with mingw. - // 11/24/2010: glMultiDrawElements is not being used right now in the GL - // backend, so comment this out for the time being, especially since it - // causes build problems with 64-bit mingw. - //#ifdef __MINGW32__ - // #define GL_GLEXT_PROTOTYPES 1 - // #include - // #define MULTI_DRAW_ELEMENTS glMultiDrawElementsEXT - //#endif -#endif - -#include "agg_basics.h" - -#include "kiva_gl_compiled_path.h" -#include "kiva_gl_graphics_context_base.h" - - -namespace kiva_gl -{ - // This function pointer is used by various draw_marker functions - class gl_graphics_context; - typedef void(gl_graphics_context::* PathDefinitionFunc)(int); - - class gl_graphics_context : public graphics_context_base - { - public: - - gl_graphics_context(int width, int height, - kiva_gl::pix_format_e format=kiva_gl::pix_format_rgb24); - ~gl_graphics_context(); - - int width(); - int height(); - int stride(); - - //--------------------------------------------------------------- - // GL-specific methods - //--------------------------------------------------------------- - void gl_init(); - void gl_cleanup(); - void begin_page(); - void gl_render_path(kiva_gl::compiled_path *path, bool polygon=false, bool fill=false); - void gl_render_points(double** points, bool polygon, bool fill, - kiva_gl::draw_mode_e mode = FILL); - - //--------------------------------------------------------------- - // GraphicsContextBase interface - //--------------------------------------------------------------- - - kiva_gl::pix_format_e format(); - void save_state(); - void restore_state(); - - //--------------------------------------------------------------- - // Clipping path manipulation - //--------------------------------------------------------------- - void clip(); - void even_odd_clip(); - void clip_to_rect(double x, double y, double sx, double sy); - void clip_to_rect(kiva_gl::rect_type &rect); - void clip_to_rects(double* new_rects, int Nrects); - void clip_to_rects(kiva_gl::rect_list_type &rects); - kiva_gl::rect_type transform_clip_rectangle(const kiva_gl::rect_type &rect); - void clear_clip_path(); - - int get_num_clip_regions(); - kiva_gl::rect_type get_clip_region(unsigned int i); - - //--------------------------------------------------------------- - // Painting paths (drawing and filling contours) - //--------------------------------------------------------------- - void clear(kiva_gl_agg::rgba value=kiva_gl_agg::rgba(1, 1, 1, 1)); - void fill_path(); - void eof_fill_path(); - void stroke_path(); - // empty function; for some reason this is abstract in the base class - inline void _stroke_path() {} - - void draw_path(draw_mode_e mode=FILL_STROKE); - void draw_rect(double rect[4], draw_mode_e mode=FILL_STROKE); - - int draw_marker_at_points(double* pts,int Npts,int size, - kiva_gl::marker_e type=kiva_gl::marker_square); - - void draw_path_at_points(double* pts,int Npts, - kiva_gl::compiled_path& marker, - draw_mode_e mode); - - int draw_image(kiva_gl::graphics_context_base* img, double rect[4], bool force_copy=false); - int draw_image(kiva_gl::graphics_context_base* img); - - protected: - - void draw_display_list_at_pts(GLuint list, double *pts, int Npts, - kiva_gl::draw_mode_e mode, - double x0, double y0); - void draw_display_list_at_pts(GLuint fill_list, GLuint stroke_list, - double *pts, int Npts, - kiva_gl::draw_mode_e mode, - double x0, double y0); - - // Given a path function, returns two OpenGL display lists representing - // the list to fill and the list to stroke. The caller is responsible - // for calling glDeleteLists on the two. - // Only the list name of the first list (fill list) will be returned; - // the stroke list can be accessed by just adding 1. - GLuint make_marker_lists(kiva_gl::PathDefinitionFunc path_func, - kiva_gl::draw_mode_e mode, int size); - - void circle_path_func(int size); - void triangle_up_func(int size); - void triangle_down_func(int size); - - void draw_square(double *pts, int Npts, int size, - kiva_gl::draw_mode_e mode, double x0, double y0); - void draw_diamond(double *pts, int Npts, int size, - kiva_gl::draw_mode_e mode, double x0, double y0); - void draw_crossed_circle(double *pts, int Npts, int size, - kiva_gl::draw_mode_e mode, double x0, double y0); - void draw_x_marker(double *pts, int Npts, int size, - kiva_gl::draw_mode_e mode, double x0, double y0); - void draw_cross(double *pts, int Npts, int size, - kiva_gl::draw_mode_e mode, double x0, double y0); - void draw_dot(double *pts, int Npts, int size, - kiva_gl::draw_mode_e mode, double x0, double y0); - void draw_pixel(double *pts, int Npts, int size, - kiva_gl::draw_mode_e mode, double x0, double y0); - - private: - int m_width; - int m_height; - bool m_gl_initialized; - kiva_gl::pix_format_e m_pixfmt; - }; -} - -#endif /* KIVA_GL_GRAPHICS_CONTEXT_H */ diff --git a/kiva/gl/src/kiva_gl_graphics_context_base.cpp b/kiva/gl/src/kiva_gl_graphics_context_base.cpp deleted file mode 100755 index 20a692695..000000000 --- a/kiva/gl/src/kiva_gl_graphics_context_base.cpp +++ /dev/null @@ -1,435 +0,0 @@ -// (C) Copyright 2005-2022 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! - -#include - -#include "agg_path_storage.h" - -#include "kiva_gl_exceptions.h" -#include "kiva_gl_graphics_context_base.h" - -using namespace kiva_gl; - -graphics_context_base::graphics_context_base(interpolation_e interp) -: _image_interpolation(interp) -{ -} - -graphics_context_base::~graphics_context_base() -{ -} - -int -graphics_context_base::width() -{ - return 0; -} - -int -graphics_context_base::height() -{ - return 0; -} - -int -graphics_context_base::stride() -{ - return 1; -} - -int -graphics_context_base::bottom_up() -{ - return (this->stride() > 0 ? 0 : 1); -} - -kiva_gl::interpolation_e -graphics_context_base::get_image_interpolation() -{ - return this->_image_interpolation; -} - -void -graphics_context_base::set_image_interpolation(kiva_gl::interpolation_e interpolation) -{ - this->_image_interpolation = interpolation; -} - -//--------------------------------------------------------------- -// set graphics_state values -//--------------------------------------------------------------- - -void -graphics_context_base::set_stroke_color(kiva_gl_agg::rgba& value) -{ - this->state.line_color = value; -} - -kiva_gl_agg::rgba& -graphics_context_base::get_stroke_color() -{ - return this->state.line_color; -} - -void -graphics_context_base::set_line_width(double value) -{ - this->state.line_width = value; -} - -void -graphics_context_base::set_line_join(kiva_gl::line_join_e value) -{ - this->state.line_join = value; -} - -void -graphics_context_base::set_line_cap(kiva_gl::line_cap_e value) -{ - this->state.line_cap = value; -} - -void -graphics_context_base::set_line_dash(double* pattern, int n, double phase) -{ - this->state.line_dash = kiva_gl::dash_type(phase, pattern, n); -} - -void -graphics_context_base::set_blend_mode(kiva_gl::blend_mode_e value) -{ - this->state.blend_mode = value; -} - -kiva_gl::blend_mode_e -graphics_context_base::get_blend_mode() -{ - return this->state.blend_mode; -} - -void -graphics_context_base::set_fill_color(kiva_gl_agg::rgba& value) -{ - this->state.fill_color = value; -} - -kiva_gl_agg::rgba& -graphics_context_base::get_fill_color() -{ - return this->state.fill_color; -} - -void -graphics_context_base::set_alpha(double value) -{ - // alpha should be between 0 and 1, so clamp: - if (value < 0.0) - { - value = 0.0; - } - else if (value > 1.0) - { - value = 1.0; - } - this->state.alpha = value; -} - -double -graphics_context_base::get_alpha() -{ - return this->state.alpha; -} - -void -graphics_context_base::set_antialias(int value) -{ - this->state.should_antialias = value; -} - -int -graphics_context_base::get_antialias() -{ - return this->state.should_antialias; -} - -void -graphics_context_base::set_miter_limit(double value) -{ - this->state.miter_limit = value; -} - -void -graphics_context_base::set_flatness(double value) -{ - this->state.flatness = value; -} - -//--------------------------------------------------------------- -// save/restore graphics state -//--------------------------------------------------------------- - -void -graphics_context_base::save_state() -{ - this->state_stack.push(this->state); - this->path.save_ctm(); -} - -//--------------------------------------------------------------- -// coordinate transform matrix transforms -//--------------------------------------------------------------- - -void -graphics_context_base::translate_ctm(double x, double y) -{ - this->path.translate_ctm(x, y); -} - -void -graphics_context_base::rotate_ctm(double angle) -{ - this->path.rotate_ctm(angle); -} - -void -graphics_context_base::scale_ctm(double sx, double sy) -{ - this->path.scale_ctm(sx, sy); -} - -void -graphics_context_base::concat_ctm(kiva_gl_agg::trans_affine& m) -{ - this->path.concat_ctm(m); -} - -void -graphics_context_base::set_ctm(kiva_gl_agg::trans_affine& m) -{ - this->path.set_ctm(m); -} - -kiva_gl_agg::trans_affine -graphics_context_base::get_ctm() -{ - return this->path.get_ctm(); -} - -//--------------------------------------------------------------- -// Sending drawing data to a device -//--------------------------------------------------------------- - -void -graphics_context_base::flush() -{ - // TODO-PZW: clarify this and other "not sure if anything is needed" functions - // not sure if anything is needed. -} - -void -graphics_context_base::synchronize() -{ - // not sure if anything is needed. -} - -//--------------------------------------------------------------- -// Page Definitions -//--------------------------------------------------------------- - -void -graphics_context_base::begin_page() -{ - // not sure if anything is needed. -} - -void -graphics_context_base::end_page() -{ - // not sure if anything is needed. -} - -//--------------------------------------------------------------- -// Path operations -//--------------------------------------------------------------- - -void -graphics_context_base::begin_path() -{ - this->path.begin_path(); -} - -void -graphics_context_base::move_to(double x, double y) -{ - this->path.move_to(x, y); -} - -void -graphics_context_base::line_to( double x, double y) -{ - this->path.line_to(x, y); -} - -void -graphics_context_base::curve_to(double cpx1, double cpy1, - double cpx2, double cpy2, - double x, double y) -{ - this->path.curve_to(cpx1, cpy1, cpx2, cpy2, x, y); -} - -void -graphics_context_base::quad_curve_to(double cpx, double cpy, double x, double y) -{ - this->path.quad_curve_to(cpx, cpy, x, y); -} - -void -graphics_context_base::arc(double x, double y, double radius, - double start_angle, double end_angle, - bool cw) -{ - this->path.arc(x, y, radius, start_angle, end_angle, cw); -} - -void -graphics_context_base::arc_to(double x1, double y1, double x2, double y2, - double radius) -{ - this->path.arc_to(x1, y1, x2, y2, radius); -} - -void -graphics_context_base::close_path() -{ - this->path.close_polygon(); -} - -void -graphics_context_base::add_path(kiva_gl::compiled_path& other_path) -{ - this->path.add_path(other_path); -} - -void -graphics_context_base::lines(double* pts, int Npts) -{ - this->path.lines(pts, Npts); -} - -void -graphics_context_base::line_set(double* start, int Nstart, double* end, int Nend) -{ - this->path.line_set(start, Nstart, end, Nend); -} - -void -graphics_context_base::rect(double x, double y, double sx, double sy) -{ - this->path.rect(x, y, sx, sy); -} - -void -graphics_context_base::rect(kiva_gl::rect_type &rect) -{ - this->path.rect(rect); -} - -void -graphics_context_base::rects(double* all_rects, int Nrects) -{ - this->path.rects(all_rects, Nrects); -} - -void -graphics_context_base::rects(kiva_gl::rect_list_type &rectlist) -{ - this->path.rects(rectlist); -} - -kiva_gl::compiled_path -graphics_context_base::_get_path() -{ - return this->path; -} - -kiva_gl::rect_type -graphics_context_base::_get_path_bounds() -{ - double xmin = 0., ymin = 0., xmax = 0., ymax = 0.; - double x = 0., y = 0.; - - for (unsigned i = 0; i < this->path.total_vertices(); ++i) - { - this->path.vertex(i, &x, &y); - - if (i == 0) - { - xmin = xmax = x; - ymin = ymax = y; - continue; - } - - if (x < xmin) - { - xmin = x; - } - else if (xmax < x) - { - xmax = x; - } - if (y < ymin) - { - ymin = y; - } - else if (ymax < y) - { - ymax = y; - } - } - - return kiva_gl::rect_type(xmin, ymin, xmax-xmin, ymax-ymin); -} - -kiva_gl_agg::path_storage -graphics_context_base::boundary_path(kiva_gl_agg::trans_affine& affine_mtx) -{ - // Return the path that outlines the image in device space - // This is used in _draw to specify the device area - // that should be rendered. - kiva_gl_agg::path_storage clip_path; - double p0x = 0; - double p0y = 0; - double p1x = this->width(); - double p1y = 0; - double p2x = this->width(); - double p2y = this->height(); - double p3x = 0; - double p3y = this->height(); - - affine_mtx.transform(&p0x, &p0y); - affine_mtx.transform(&p1x, &p1y); - affine_mtx.transform(&p2x, &p2y); - affine_mtx.transform(&p3x, &p3y); - - clip_path.move_to(p0x, p0y); - clip_path.line_to(p1x, p1y); - clip_path.line_to(p2x, p2y); - clip_path.line_to(p3x, p3y); - clip_path.close_polygon(); - return clip_path; -} - -int -graphics_context_base::draw_image(kiva_gl::graphics_context_base* img) -{ - double tmp[] = {0, 0, img->width(), img->height()}; - return this->draw_image(img, tmp); -} diff --git a/kiva/gl/src/kiva_gl_graphics_context_base.h b/kiva/gl/src/kiva_gl_graphics_context_base.h deleted file mode 100644 index 1dff17597..000000000 --- a/kiva/gl/src/kiva_gl_graphics_context_base.h +++ /dev/null @@ -1,248 +0,0 @@ -// (C) Copyright 2005-2022 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! -#ifndef KIVA_GL_GRAPHICS_CONTEXT_BASE_H -#define KIVA_GL_GRAPHICS_CONTEXT_BASE_H - -#include -#include - -#include "agg_basics.h" -#include "agg_color_rgba.h" - -#include "kiva_gl_constants.h" -#include "kiva_gl_rect.h" -#include "kiva_gl_graphics_state.h" -#include "kiva_gl_affine_helpers.h" - -namespace kiva_gl -{ - class graphics_context_base - { - public: - // The current path. This also includes the ctm. - kiva_gl::compiled_path path; - - kiva_gl::graphics_state state; - std::stack state_stack; - - // fix me: Not sure this should be here, but, putting it here completely - // unifies images and graphics contexts. - // (TODO-PZW: revisit this) - kiva_gl::interpolation_e _image_interpolation; - - graphics_context_base(kiva_gl::interpolation_e interp); - virtual ~graphics_context_base(); - - int width(); - int height(); - int stride(); - int bottom_up(); - - virtual kiva_gl::pix_format_e format() = 0; - - kiva_gl::interpolation_e get_image_interpolation(); - void set_image_interpolation(interpolation_e interpolation); - - //--------------------------------------------------------------- - // set graphics_state values - //--------------------------------------------------------------- - - void set_stroke_color(kiva_gl_agg::rgba& value); - kiva_gl_agg::rgba& get_stroke_color(); - - // TODO-PZW: do we need corresponding get() functions for - // all of the following? - - void set_line_width(double value); - void set_line_join(line_join_e value); - void set_line_cap(line_cap_e value); - void set_line_dash(double* pattern, int n, double phase=0); - - // fix me: Blend mode is *barely* supported and - // probably abused (my copy setting). - void set_blend_mode(blend_mode_e value); - kiva_gl::blend_mode_e get_blend_mode(); - - void set_fill_color(kiva_gl_agg::rgba& value); - - // need get method for freetype renderer. - // should I return a reference?? - kiva_gl_agg::rgba& get_fill_color(); - - // need get method for freetype renderer. - // fix me: Is the get method still needed? - void set_alpha(double value); - double get_alpha(); - - // need get method for freetype renderer. - // fix me: Is the get method still needed? - void set_antialias(int value); - int get_antialias(); - - // TODO-PZW: get() functions needed? - void set_miter_limit(double value); - void set_flatness(double value); - - //--------------------------------------------------------------- - // save/restore graphics state - //--------------------------------------------------------------- - - void save_state(); - virtual void restore_state() = 0; - - //--------------------------------------------------------------- - // coordinate transform matrix transforms - //--------------------------------------------------------------- - - void translate_ctm(double x, double y); - void rotate_ctm(double angle); - void scale_ctm(double sx, double sy); - void concat_ctm(kiva_gl_agg::trans_affine& m); - void set_ctm(kiva_gl_agg::trans_affine& m); - kiva_gl_agg::trans_affine get_ctm(); - - //--------------------------------------------------------------- - // Sending drawing data to a device - //--------------------------------------------------------------- - - void flush(); - void synchronize(); - - //--------------------------------------------------------------- - // Page Definitions - //--------------------------------------------------------------- - - void begin_page(); - void end_page(); - - //--------------------------------------------------------------- - // Path operations - //--------------------------------------------------------------- - - void begin_path(); - void move_to(double x, double y); - void line_to( double x, double y); - void curve_to(double cpx1, double cpy1, - double cpx2, double cpy2, - double x, double y); - - void quad_curve_to(double cpx, double cpy, - double x, double y); - - // arc() and arc_to() draw circular segments. When the arc - // is added to the current path, it may become an elliptical - // arc depending on the CTM. - - // Draws a circular segment centered at the point (x,y) with the - // given radius. - void arc(double x, double y, double radius, double start_angle, - double end_angle, bool cw=false); - - // Sweeps a circular arc from the pen position to a point on the - // line from (x1,y1) to (x2,y2). - // The arc is tangent to the line from the current pen position - // to (x1,y1), and it is also tangent to the line from (x1,y1) - // to (x2,y2). (x1,y1) is the imaginary intersection point of - // the two lines tangent to the arc at the current point and - // at (x2,y2). - // If the tangent point on the line from the current pen position - // to (x1,y1) is not equal to the current pen position, a line is - // drawn to it. Depending on the supplied radius, the tangent - // point on the line fron (x1,y1) to (x2,y2) may or may not be - // (x2,y2). In either case, the arc is drawn to the point of - // tangency, which is also the new pen position. - // - // Consider the common case of rounding a rectangle's upper left - // corner. Let "r" be the radius of rounding. Let the current - // pen position be (x_left + r, y_top). Then (x2,y2) would be - // (x_left, y_top - radius), and (x1,y1) would be (x_left, y_top). - void arc_to(double x1, double y1, double x2, double y2, double radius); - - void close_path(); - void add_path(kiva_gl::compiled_path& other_path); - compiled_path _get_path(); - kiva_gl::rect_type _get_path_bounds(); - - void lines(double* pts, int Npts); - void line_set(double* start, int Nstart, double* end, int Nend); - - void rect(double x, double y, double sx, double sy); - void rect(kiva_gl::rect_type &rect); - void rects(double* all_rects, int Nrects); - void rects(kiva_gl::rect_list_type &rectlist); - - kiva_gl_agg::path_storage boundary_path(kiva_gl_agg::trans_affine& affine_mtx); - - //--------------------------------------------------------------- - // Clipping path manipulation - //--------------------------------------------------------------- - virtual void clip() = 0; - virtual void even_odd_clip() = 0; - virtual void clip_to_rect(double x, double y, double sx, double sy) = 0; - virtual void clip_to_rect(kiva_gl::rect_type &rect) = 0; - virtual void clip_to_rects(double* new_rects, int Nrects) = 0; - virtual void clip_to_rects(kiva_gl::rect_list_type &rects) = 0; - virtual void clear_clip_path() = 0; - - // The following two are meant for debugging purposes, and are not part - // of the formal interface for GraphicsContexts. - virtual int get_num_clip_regions() = 0; - virtual kiva_gl::rect_type get_clip_region(unsigned int i) = 0; - - //--------------------------------------------------------------- - // Painting paths (drawing and filling contours) - //--------------------------------------------------------------- - virtual void clear(kiva_gl_agg::rgba value=kiva_gl_agg::rgba(1, 1, 1, 1)) = 0; - - virtual void fill_path() = 0; - virtual void eof_fill_path() = 0; - - virtual void stroke_path() = 0; - virtual void _stroke_path() = 0; - - virtual void draw_path(draw_mode_e mode=FILL_STROKE) = 0; - virtual void draw_rect(double rect[4], - draw_mode_e mode=FILL_STROKE) = 0; - - // Draw a marker at all the points in the list. This is a - // very fast function that only works in special cases. - // The succeeds if the line_width != 0.0 or 1.0, the line_join - // is set to JOIN_MITER (!! NOT CURRENTLY ENFORCED), and the - // ctm only has translational components. - // - // Typically this is called before trying the more general - // draw_path_at_points() command. It is typically 5-10 times - // faster. - // - // Returns: int - // 0 on failure - // 1 on success - virtual int draw_marker_at_points(double* pts,int Npts,int size, - kiva_gl::marker_e type=kiva_gl::marker_square) = 0; - - virtual void draw_path_at_points(double* pts,int Npts, - kiva_gl::compiled_path& marker, - draw_mode_e mode) = 0; - - //--------------------------------------------------------------- - // Image handling - //--------------------------------------------------------------- - - // Draws an image into the rectangle specified as (x, y, width, height); - // The image is scaled and/or stretched to fit inside the rectangle area - // specified. - virtual int draw_image(kiva_gl::graphics_context_base* img, double rect[4], bool force_copy=false) = 0; - int draw_image(kiva_gl::graphics_context_base* img); - - }; - -} - -#endif /* KIVA_GL_GRAPHICS_CONTEXT_BASE_H */ diff --git a/kiva/gl/src/kiva_gl_graphics_state.h b/kiva/gl/src/kiva_gl_graphics_state.h deleted file mode 100644 index 246080a0c..000000000 --- a/kiva/gl/src/kiva_gl_graphics_state.h +++ /dev/null @@ -1,106 +0,0 @@ -// (C) Copyright 2005-2022 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! -#ifndef KIVA_GL_GRAPHICS_STATE_H -#define KIVA_GL_GRAPHICS_STATE_H - -#include -#include "agg_trans_affine.h" - -#include "kiva_gl_constants.h" -#include "kiva_gl_dash_type.h" -#include "kiva_gl_compiled_path.h" - -#include - -namespace kiva_gl -{ - //----------------------------------------------------------------------- - // graphics_state class - //----------------------------------------------------------------------- - - class graphics_state - { - public: - - // line attributes - kiva_gl_agg::rgba line_color; - double line_width; - kiva_gl::line_cap_e line_cap; - kiva_gl::line_join_e line_join; - kiva_gl::dash_type line_dash; - - // other attributes - kiva_gl::blend_mode_e blend_mode; - kiva_gl_agg::rgba fill_color; - double alpha; - - // clipping path - // In general, we need a path to store the clipping region. - // However, in most cases, the clipping region can be represented - // by a list of rectangles. The graphics state can support one or - // the other, but not both. By default, device_space_clip_rects is - // used; but as soon as a non-rectangular clip path is added to - // the graphics state or the rectangular region is rotated, then - // it becomes an arbitrary clipping path. - // - // device_space_clip_rects always contains at least one rectangle. - // In the event that everything is clipped out, the clip rectangle - // will have dimensions (0,0). - // - // The function use_rect_clipping is used to determine whether or - // not to use device_space_clip_rects. 'true' means to use it, 'false' - // means ot use clipping_path; - kiva_gl::compiled_path clipping_path; - std::vector device_space_clip_rects; - inline bool use_rect_clipping(); - - double current_point[2]; // !! not sure about this. - int should_antialias; - double miter_limit; - double flatness; // !! not sure about this type. - - // double rendering_intent; // !! I know this type is wrong... - - graphics_state() - : line_color(kiva_gl_agg::rgba(0.0, 0.0, 0.0)) - , line_width(1.0) - , line_cap(kiva_gl::CAP_BUTT) - , line_join(kiva_gl::JOIN_MITER) - , blend_mode(kiva_gl::blend_normal) - , fill_color(kiva_gl_agg::rgba(0.0, 0.0, 0.0)) - , alpha(1.0) - , should_antialias(1) - { - } - - ~graphics_state() - { - } - - inline bool is_singleclip() - { - return (device_space_clip_rects.size() <= 1 ? true : false); - } - }; - - inline bool graphics_state::use_rect_clipping() - { - if (clipping_path.total_vertices() > 0) - { - std::cout << "clipping path has vertices" << std::endl; - return false; - } - - return true; - } - -} - -#endif diff --git a/kiva/gl/src/kiva_gl_rect.cpp b/kiva/gl/src/kiva_gl_rect.cpp deleted file mode 100755 index 10ee2d8f1..000000000 --- a/kiva/gl/src/kiva_gl_rect.cpp +++ /dev/null @@ -1,301 +0,0 @@ -// (C) Copyright 2005-2022 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! -#include "kiva_gl_rect.h" -#include -#include -#include -#include - -namespace kiva_gl -{ - - rect_type - disjoint_intersect(const rect_type &a, const rect_type &b) - { - double xl = max(a.x, b.x); - double yb = max(a.y, b.y); - double xr = min(a.x2(), b.x2()); - double yt = min(a.y2(), b.y2()); - if ((xr >= xl) && (yt >= yb)) - { - return rect_type(xl, yb, xr-xl, yt-yb); - } - else - { - return rect_type(xl, yb, -1, -1); - } - } - - rect_list_type - disjoint_intersect(const rect_list_type &rects) - { - if (rects.size() < 2) - { - return rects; - } - - rect_list_type result_list; - result_list.push_back(rects[0]); - for (unsigned int i=1; i= 0) && (result_rect.h >= 0)) - { - result_list.push_back(result_rect); - } - } - - return result_list; - } - - - rect_list_type - disjoint_union(const rect_type &a, const rect_type &b) - { - rect_list_type rlist; - rlist.push_back(a); - return disjoint_union(rlist, b); - } - - rect_list_type - disjoint_union(const rect_list_type &rects) - { - if (rects.size() < 2) - { - return rects; - } - - rect_list_type rlist; - rlist.push_back(rects[0]); - for (unsigned int i=1; ix; - double yb1 = cur_todo->y; - double xr1 = cur_todo->x2(); - double yt1 = cur_todo->y2(); - - double xl2, yb2, xr2, yt2; - - unsigned int orig_count = 0; - while (orig_count < original_list.size()) - { - rect_type *cur_orig = &original_list[orig_count]; - xl2 = cur_orig->x; - yb2 = cur_orig->y; - xr2 = cur_orig->x2(); - yt2 = cur_orig->y2(); - - // Test for non-overlapping - if ((xl1 >= xr2) || (xr1 <= xl2) || (yb1 >= yt2) || (yt1 <= yb2)) - { - orig_count++; - continue; - } - - // Test for new rect being wholly contained in an existing one - bool x1inx2 = ((xl1 >= xl2) && (xr1 <= xr2)); - bool y1iny2 = ((yb1 >= yb2) && (yt1 <= yt2)); - if (x1inx2 && y1iny2) - { - use_leftover = false; - break; - } - - // Test for existing rect being wholly contained in new rect - bool x2inx1 = ((xl2 >= xl1) && (xr2 <= xr1)); - bool y2iny1 = ((yb2 >= yb1) && (yt2 <= yt1)); - if (x2inx1 && y2iny1) - { - // Erase the existing rectangle from the original_list - // and set the iterator to the next one. - original_list.erase(original_list.begin() + orig_count); - continue; - } - - // Test for rect 1 being within rect 2 along the x-axis: - if (x1inx2) - { - if (yb1 < yb2) - { - if (yt1 > yt2) - { - todo.push_back(rect_type(xl1, yt2, xr1-xl1, yt1-yt2)); - } - yt1 = yb2; - } - else - { - yb1 = yt2; - } - orig_count++; - continue; - } - - // Test for rect 2 being within rect 1 along the x-axis: - if (x2inx1) - { - if (yb2 < yb1) - { - if (yt2 > yt1) - { - original_list.insert(original_list.begin() + orig_count, - rect_type(xl2, yt1, xr2-xl2, yt2-yt1)); - orig_count++; - } - original_list[orig_count] = rect_type(xl2, yb2, xr2-xl2, yb1-yb2); - } - else - { - original_list[orig_count] = rect_type(xl2, yt1, xr2-xl2, yt2-yt1); - } - orig_count++; - continue; - } - - // Test for rect 1 being within rect 2 along the y-axis: - if (y1iny2) - { - if (xl1 < xl2) - { - if (xr1 > xr2) - { - todo.push_back(rect_type(xr2, yb1, xr1-xr2, yt1-yb1)); - } - xr1 = xl2; - } - else - { - xl1 = xr2; - } - orig_count++; - continue; - } - - // Test for rect 2 being within rect 1 along the y-axis: - if (y2iny1) - { - if (xl2 < xl1) - { - if (xr2 > xr1) - { - original_list.insert(original_list.begin() + orig_count, - rect_type(xr1, yb2, xr2-xr1, yt2-yb2)); - orig_count++; - } - original_list[orig_count] = rect_type(xl2, yb2, xl1-xl2, yt2-yb2); - } - else - { - original_list[orig_count] = rect_type(xr1, yb2, xr2-xr1, yt2-yb2); - } - orig_count++; - continue; - } - - // Handle a 'corner' overlap of rect 1 and rect 2: - double xl, yb, xr, yt; - if (xl1 < xl2) - { - xl = xl1; - xr = xl2; - } - else - { - xl = xr2; - xr = xr1; - } - - if (yb1 < yb2) - { - yb = yb2; - yt = yt1; - yt1 = yb2; - } - else - { - yb = yb1; - yt = yt2; - yb1 = yt2; - } - - todo.push_back(rect_type(xl, yb, xr-xl, yt-yb)); - - orig_count++; - } - - if (use_leftover) - { - additional_rects.push_back(rect_type(xl1, yb1, xr1-xl1, yt1-yb1)); - } - todo_count++; - } - - for (rect_list_type::iterator it = additional_rects.begin(); it != additional_rects.end(); ++it) - { - original_list.push_back(*it); - } - - return original_list; - } - - bool - rect_list_contains(rect_list_type &l, rect_type &r) - { - return (std::find(l.begin(), l.end(), r) != l.end()); - } -} diff --git a/kiva/gl/src/kiva_gl_rect.h b/kiva/gl/src/kiva_gl_rect.h deleted file mode 100644 index 7d4a3dc62..000000000 --- a/kiva/gl/src/kiva_gl_rect.h +++ /dev/null @@ -1,121 +0,0 @@ -// (C) Copyright 2005-2022 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! -#ifndef KIVA_GL_RECT_H -#define KIVA_GL_RECT_H - -#include - -#include "agg_basics.h" -#include "kiva_gl_basics.h" - -namespace kiva_gl -{ - - //----------------------------------------------------------------------- - // graphics_state class - //----------------------------------------------------------------------- - - class rect_type { - public: - // constructors - inline rect_type(): x(0), y(0), w(-1), h(-1) { } - inline rect_type(double newx, double newy, double neww, double newh) - : x(newx), y(newy), w(neww), h(newh) { } - inline rect_type(kiva_gl_agg::rect_i r) { *this = r; } - inline rect_type(kiva_gl_agg::rect_d r) { *this = r; } - - // conversion from kiva_gl_agg::rect - inline rect_type& operator=(kiva_gl_agg::rect_i &r) - { - x = int(r.x1); - y = int(r.y1); - w = int(r.x2 - r.x1); - h = int(r.y2 - r.y1); - return *this; - } - - inline rect_type& operator=(kiva_gl_agg::rect_d &r) - { - x = r.x1; - y = r.y1; - w = r.x2 - r.x1; - h = r.y2 - r.y1; - return *this; - } - - inline bool operator==(rect_type& other) - { - return ((x == other.x) && (y == other.y) && (w == other.w) && (h == other.h)); - } - - inline bool operator!=(rect_type& other) - { - return !(*this == other); - } - - // conversion to kiva_gl_agg::rect - inline operator kiva_gl_agg::rect_i() const { return kiva_gl_agg::rect_i(int(x), int(y), int(w), int(h)); } - inline operator kiva_gl_agg::rect_d() const { return kiva_gl_agg::rect_d(x, y, w, h); } - - // conversion to double[4] - inline double operator[](unsigned int ndx) const - { - switch (ndx) - { - case 0: return x; - case 1: return y; - case 2: return w; - case 3: return h; - } - } - - // comparison - inline bool operator==(const rect_type &b) const - { - return ((this->x == b.x) && (this->y == b.y) && (this->w == b.w) && (this->h == b.h)); - } - - // utility functions: - inline double x2() const { return x+w; } - inline double y2() const { return y+h; } - - double x, y, w, h; - }; - - typedef std::vector rect_list_type; - typedef rect_list_type::iterator rect_iterator; - - // This returns the rectangle representing the overlapping area between - // rectangles a and b. If they do not overlap, the returned rectangle - // will have width and height -1. - // - // (We use -1 instead of 0 because Agg will accept clip rectangles of - // size 0.) - rect_type disjoint_intersect(const rect_type &a, const rect_type &b); - - // Returns a list of rectangles resulting from the intersection of the - // input list of rectangles. If there are no intersection regions, - // returns an empty list. - rect_list_type disjoint_intersect(const rect_list_type &rects); - - // Intersects a single rectangle against a list of existing, non- - // intersecting rectangles, and returns a list of the intersection regions. - // If there are no intersection regions, returns an empty list. - rect_list_type disjoint_intersect(const rect_list_type &original_list, - const rect_type &new_rect); - - rect_list_type disjoint_union(const rect_type &a, const rect_type &b); - rect_list_type disjoint_union(const rect_list_type &rects); - rect_list_type disjoint_union(rect_list_type original_list, - const rect_type &new_rect); - -} - -#endif diff --git a/kiva/gl/src/swig/affine_matrix.i b/kiva/gl/src/swig/affine_matrix.i deleted file mode 100644 index 16fc9c8a2..000000000 --- a/kiva/gl/src/swig/affine_matrix.i +++ /dev/null @@ -1,227 +0,0 @@ -/* -*- c -*- */ -// (C) Copyright 2005-2022 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! -/* AffineMatrix class wrapper - - 1. C++ class 'trans_affine' is renamed to python '_AffineMatrix' - - 2. All methods accept 'transform' and 'inverse_transform' are - wrapped. - - 3. __repr__ and __str__ methods are added to print out an - _AffineMatrix object as: "AffineMatrix(a,b,c,d,tx,ty)" - - 4. A subclass called 'AffineMatrix' is derived from '_AffineMatrix' - using a %pythoncode directive. This is so that __init__ can be - overloadeded to convert a sequence into the appropriate argument - convention for the _AffineMatrix constructor. - - 5. Classes such as trans_affine_rotation were converted to factory - functions so that they return an trans_affine class instead of - having a new class type (such as RotationMatrix). - - Notes: - !! 1. - !! (4) is a hack to get around the fact that I couldn't - !! figure out how to get the overloaded constructor for trans_affine - !! to accept a numpy array as input -- even if I added a function - !! new_AffineMatrix(double ary[6]); and then put the - !! trans_affine(double ary[6]) signature in the class interface. It - !! appears that SWIG is a little overzealous in its type checking - !! in the constructor call, only allowing double* pointers through - !! instead of allowing any sequence through. This is the correct - !! default behavior, but I couldn't figure out how to overload it with - !! my own test. - !! - !! 2. - !! The C++ operator *= is definitely broken -- probably not setting the - !! thisown property correctly on returned pointers. It is currently - !! set to return void so that it can't cause any mischief, but it also - !! breaks its functionality. - !! FIX: I have just created this function in Python and call the - !! C++ multiply() method. -*/ - -%include "numpy.i" -%include "sequence_to_array.i" - - -%{ -#include "numpy/arrayobject.h" -#include "agg_trans_affine.h" - -// These factories mimic the functionality of like-named classes in agg. -// Making them functions that return trans_affine types leads to a cleaner -// and easier to maintain Python interface. - - -kiva_gl_agg::trans_affine* trans_affine_rotation(double a) -{ - return new kiva_gl_agg::trans_affine(cos(a), sin(a), -sin(a), cos(a), 0.0, 0.0); -} - -kiva_gl_agg::trans_affine* trans_affine_scaling(double sx, double sy) -{ - return new kiva_gl_agg::trans_affine(sx, 0.0, 0.0, sy, 0.0, 0.0); -} - -kiva_gl_agg::trans_affine* trans_affine_translation(double tx, double ty) -{ - return new kiva_gl_agg::trans_affine(1.0, 0.0, 0.0, 1.0, tx, ty); -} - -kiva_gl_agg::trans_affine* trans_affine_skewing(double sx, double sy) -{ - return new kiva_gl_agg::trans_affine(1.0, tan(sy), tan(sx), 1.0, 0.0, 0.0); -} - -%} - -%newobject trans_affine_rotation; -%rename(rotation_matrix) trans_affine_rotation(double); -kiva_gl_agg::trans_affine* trans_affine_rotation(double a); - -%newobject trans_affine_scaling; -%rename(scaling_matrix) trans_affine_scaling(double, double); -kiva_gl_agg::trans_affine* trans_affine_scaling(double sx, double sy); - -%newobject trans_affine_translation; -%rename(translation_matrix) trans_affine_translation(double, double); -kiva_gl_agg::trans_affine* trans_affine_translation(double tx, double ty); - -%newobject trans_affine_skewing; -%rename(skewing_matrix) trans_affine_skewing(double, double); -kiva_gl_agg::trans_affine* trans_affine_skewing(double sx, double sy); - - -%include "agg_typemaps.i" -%apply (double* array6) {(double* out)}; - -// used by __getitem__ -%typemap(check) (int affine_index) -{ - if ($1 < 0 || $1 > 5) - { - PyErr_Format(PyExc_IndexError, - "affine matrices are indexed 0 to 5. Received %d", $1); - return NULL; - } -} - -%apply owned_pointer { kiva_gl_agg::trans_affine* }; - - -namespace kiva_gl_agg -{ - %rename(_AffineMatrix) trans_affine; - %rename(asarray) trans_affine::store_to(double*) const; - - class trans_affine - { - public: - trans_affine(); - trans_affine(const trans_affine& m); - trans_affine(double v0, double v1, double v2, double v3, - double v4, double v5); - trans_affine operator ~ () const; - // I added this to trans_affine -- it really isn't there. - // trans_affine operator *(const trans_affine& m); - - // Returning trans_affine& causes problems, so these are all - // changed to void. - //const trans_affine& operator *= (const trans_affine& m); - //const trans_affine& reset(); - // const trans_affine& multiply(const trans_affine& m); - // const trans_affine& invert(); - // const trans_affine& flip_x(); - // const trans_affine& flip_y(); - //void operator *= (const trans_affine& m); - void reset(); - void multiply(const trans_affine& m); - void invert(); - void flip_x(); - void flip_y(); - - double scale() const; - double determinant() const; - - void store_to(double* out) const; - //const trans_affine& load_from(double ary[6]); - void load_from(double ary[6]); - - // !! omitted - //void transform(double* x, double* y) const; - //void inverse_transform(double* x, double* y) const; - }; -}; - -%pythoncode %{ -def is_sequence(arg): - try: - len(arg) - return 1 - except: - return 0 - -# AffineMatrix sub-class to get around problems with adding -# a AffineMatrix constructor that accepts a numpy array -# as input. -class AffineMatrix(_AffineMatrix): - def __init__(self, *args): - if len(args) == 1 and is_sequence(args[0]): - args = tuple(args[0]) - if len(args) != 6: - raise ValueError("array argument must be 1x6") - _AffineMatrix.__init__(self,*args) - - def __imul__(self, other): - """ inplace multiply - - We don't use the C++ version of this because it ends up - deleting the object out from under itself. - """ - self.multiply(other) - return self -%} - -%extend kiva_gl_agg::trans_affine -{ - char *__repr__() - { - // Write out elements of trans_affine in a, b, c, d, tx, ty order - // !! We should work to make output formatting conform to - // !! whatever it numpy does (which needs to be cleaned up also). - static char tmp[1024]; - double m[6]; - self->store_to(m); - sprintf(tmp,"AffineMatrix(%g, %g, %g, %g, %g, %g)", m[0], m[1], m[2], - m[3], m[4], m[5]); - return tmp; - } - - double __getitem__(int affine_index) - { - double ary[6]; - self->store_to(ary); - return ary[affine_index]; - } - - int __eq__(kiva_gl_agg::trans_affine& other) - { - double ary1[6], ary2[6]; - self->store_to(ary1); - other.store_to(ary2); - int eq = 1; - for (int i = 0; i < 6; i++) - eq &= (ary1[i] == ary2[i]); - return eq; - } -} - diff --git a/kiva/gl/src/swig/agg_std_string.i b/kiva/gl/src/swig/agg_std_string.i deleted file mode 100644 index 5c9d2a0cd..000000000 --- a/kiva/gl/src/swig/agg_std_string.i +++ /dev/null @@ -1,42 +0,0 @@ -// (C) Copyright 2005-2022 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! - -%include "std_string.i" - -// These typemaps are needed to handle member access to font_type.name -// and friends. They really should by part of std_string.i, shouldn't -// they? -#ifdef SWIGPYTHON -%typemap(in) std::string * { - if (PyBytes_Check ($input)) - { - $1 = new std::string((char *)PyBytes_AsString($input)); - } - else if (PyUnicode_Check($input)) - { - $1 = new std::string((char *)PyUnicode_AsUTF8($input)); - } - else - { - PyErr_SetString (PyExc_TypeError, "not a String"); - return NULL; - } -} -%typemap(out) std::string * { - $result = SWIG_Python_str_FromChar((const char *)$1->c_str()); -} -%typemap(freearg) std::string * { - if ($1) - { - delete $1; - } -} - -#endif /* SWIGPYTHON */ diff --git a/kiva/gl/src/swig/agg_typemaps.i b/kiva/gl/src/swig/agg_typemaps.i deleted file mode 100644 index 25e9c2f9d..000000000 --- a/kiva/gl/src/swig/agg_typemaps.i +++ /dev/null @@ -1,322 +0,0 @@ -// (C) Copyright 2005-2022 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! -// -------------------------------------------------------------------------- -// Generic typemap to handle enumerated types. -// -// Both agg and kiva have quite a few enumerated types. SWIG will wrap -// functions that use these as arguments to require a pointer to an -// enumerated type object. This isn't very convenient. It is much nicer -// to just pass an integer. this generic converter can be used in to -// allow this. -// -// To apply it to a type, for example kiva_gl::marker_e, do the following -// -// %apply(kiva_enum_typemap) { kiva_gl::marker_e } -// -// Now any function that expects a marker_e will accept integer values as -// input. -// -------------------------------------------------------------------------- - -%include "numpy.i" - -%typemap(in) kiva_enum_typemap type { - - int temp = PyInt_AsLong($input); - if (PyErr_Occurred()) SWIG_fail; - $1 = $1_ltype(temp); -} - - -// -------------------------------------------------------------------------- -// Typemaps for (double x, double y) points -// -// For: * -// -// This is useful for places where ints may be passed in and need to -// be converted. Python 2.6 requires this -// -------------------------------------------------------------------------- -%typemap(in) double x, double y -{ - if (PyNumber_Check($input)) - { - $1 = static_cast(PyFloat_AsDouble($input)); - } - else - { - SWIG_exception(SWIG_TypeError, "Expected argument $argnum of type '$1_type'"); - } -} - -// -------------------------------------------------------------------------- -// Typemaps for (double* pts, int Npts) used in lines() -// -// For: compiled_path and graphics_context -// -// This typemap takes any Nx2 input (nested sequences or an Nx2 array). If -// the input has the wrong shape or can't be converted to a double, an -// exception is raised. It is more efficient if the input passed in is a -// contiguous array, so if you're calling lines(pts) a lot of times, make -// pts an array. -// -// -------------------------------------------------------------------------- - -%typemap(in) (double* point_array, int point_count) (PyArrayObject* ary=NULL, - int is_new_object=0) -{ - ary = obj_to_array_contiguous_allow_conversion($input, PyArray_DOUBLE, - is_new_object); - int size[2] = {-1,2}; - if (!ary || - !require_dimensions(ary,2) || - !require_size(ary,size,2)) - { - goto fail; - } - $1 = (double*) ary->data; - $2 = ary->dimensions[0]; -} - -%typemap(freearg) (double* point_array, int point_count) -{ - if (is_new_object$argnum) - { - Py_XDECREF(ary$argnum); - } -} - -// -------------------------------------------------------------------------- -// Typemaps for (unsigned char* results, int Nresults) -// -// For: points_in_polygon -// -// This typemap takes any N input. -// -// -------------------------------------------------------------------------- - -%typemap(in) (unsigned char* results, int Nresults) (PyArrayObject* ary=NULL, - int is_new_object=0) -{ - ary = obj_to_array_contiguous_allow_conversion($input, PyArray_BOOL, - is_new_object); - int size[1] = {-1}; - if (!ary || - !require_dimensions(ary,1) || - !require_size(ary,size,1)) - { - goto fail; - } - $1 = (unsigned char*) ary->data; - $2 = ary->dimensions[0]; -} - -%typemap(freearg) (unsigned char* results, int Nresults) -{ - if (is_new_object$argnum) - { - Py_XDECREF(ary$argnum); - } -} - - -/* Typemaps for rects(double* all_rects, int Nrects) - - For: compiled_path and graphics_context - - This typemap takes any Nx4 input (nested sequences or an Nx4 array). If - the input has the wrong shape or can't be converted to a double, an - exception is raised. It is more efficient if the input passed in is a - contiguous array, so if you're calling rects(all_rects) a lot of times, - make all_rects an array. -*/ -%typemap(in) (double* rect_array, int rect_count) (PyArrayObject* ary=NULL, - int is_new_object=0) -{ - ary = obj_to_array_contiguous_allow_conversion($input, PyArray_DOUBLE, - is_new_object); - int size[2] = {-1,4}; - if (!ary || - !require_dimensions(ary,2) || - !require_size(ary,size,2)) - { - goto fail; - } - $1 = (double*) ary->data; - $2 = ary->dimensions[0]; -} - -%typemap(freearg) (double* rect_array, int rect_count) -{ - if (is_new_object$argnum) - { - Py_XDECREF(ary$argnum); - } -} - -// -------------------------------------------------------------------------- -// -// vertex() returns ( pt, cmd) where pt is a tuple (x,y) -// -// This tells SWIG to treat an double * argument with name 'x' as -// an output value. We'll append the value to the current result which -// is guaranteed to be a List object by SWIG. -// -------------------------------------------------------------------------- -%typemap(in,numinputs=0) (double *vertex_x, double* vertex_y)(double temp1, - double temp2) -{ - temp1 = 0; $1 = &temp1; - temp2 = 0; $2 = &temp2; -} - -%typemap(argout) (double *vertex_x, double* vertex_y) -{ - PyObject *px = PyFloat_FromDouble(*$1); - PyObject *py = PyFloat_FromDouble(*$2); - PyObject *pt = PyTuple_New(2); - PyTuple_SetItem(pt,0,px); - PyTuple_SetItem(pt,1,py); - PyObject *return_val = PyTuple_New(2); - PyTuple_SetItem(return_val,0,pt); - // result is what was returned from vertex - PyTuple_SetItem(return_val,1,$result); - //Py_DECREF($result); - $result = return_val; -} - -// -------------------------------------------------------------------------- -// map to output arguments into a 2-tuple -// -------------------------------------------------------------------------- -%typemap(in,numinputs=0) (double *pt_x, double* pt_y)(double temp1, - double temp2) -{ - temp1 = 0; $1 = &temp1; - temp2 = 0; $2 = &temp2; -} -%typemap(argout) (double *pt_x, double *pt_y) -{ - PyObject *px = PyFloat_FromDouble(*$1); - PyObject *py = PyFloat_FromDouble(*$2); - PyObject *pt = PyTuple_New(2); - PyTuple_SetItem(pt,0,px); - PyTuple_SetItem(pt,1,py); - //Py_DECREF($result); - $result = pt; -} - -// -------------------------------------------------------------------------- -// map an 6 element double* output into a numpy array. -// -------------------------------------------------------------------------- -%typemap(in, numinputs=0) double *array6 (double temp[6]) { - $1 = temp; -} - -%typemap(argout) double *array6 { - // Append output value $1 to $result - npy_intp dims = 6; - PyArrayObject* ary_obj = (PyArrayObject*) PyArray_SimpleNew(1,&dims,PyArray_DOUBLE); - if( ary_obj == NULL ) - return NULL; - double* data = (double*)ary_obj->data; - for (int i=0; i < 6;i++) - data[i] = $1[i]; - Py_DECREF($result); - $result = PyArray_Return(ary_obj); -} - -// -------------------------------------------------------------------------- -// Typemaps for graphics_context.set_line_dash() -// -// For: -// -// This typemap takes None or any N element input (sequence or array). If -// the input is None, it passes a 2 element array of zeros to in as the -// pattern. If the input is a sequence and isn't 1D or can't be converted -// to a double, an exception is raised. -// -------------------------------------------------------------------------- - -%typemap(in) (double* dash_pattern, int n) (PyArrayObject* ary=NULL, - int is_new_object=0, - double temp[2]) -{ - is_new_object = 0; - if ($input == Py_None) - { - temp[0] = 0.0; - temp[1] = 0.0; - $1 = temp; - $2 = 2; - } - else - { - ary = obj_to_array_contiguous_allow_conversion($input, PyArray_DOUBLE, - is_new_object); - if (!ary || - !require_dimensions(ary,1)) - { - goto fail; - } - $1 = (double*) ary->data; - $2 = ary->dimensions[0]; - } -} - -%typemap(freearg) (double* dash_pattern, int n) -{ - if (is_new_object$argnum) - { - Py_XDECREF(ary$argnum); - } -} - -// -------------------------------------------------------------------------- -// Image typemaps -// -// Currently, this requires a contiguous array. It should be fixed to -// allow arrays that are only contiguous along the last two dimensions. -// This is because the windows bitmap format requires that each row of -// pixels (scan line) is word aligned (16 bit boundaries). As a result, rgb -// images compatible with this format potentially -// need a pad byte at the end of each scanline. -// -------------------------------------------------------------------------- - -%typemap(in) (unsigned char *image_data=NULL, int width, int height, int stride) -{ - PyArrayObject* ary = obj_to_array_no_conversion($input, PyArray_UBYTE); - int dimensions[2] = {2,3}; -// !! No longer requiring contiguity because some bitmaps are padded at the -// !! end (i.e. Windows). We should probably special case that one though, -// !! and re-instate the contiguous policy... -// if (!ary || -// !require_dimensions(ary,dimensions,2) || -// !require_contiguous(ary)) - if (!ary || - !require_dimensions(ary,dimensions,2)) - { - goto fail; - } - $1 = (unsigned char*) ary->data; - // notice reversed orders... - $2 = ary->dimensions[1]; - $3 = ary->dimensions[0]; - $4 = ary->strides[0]; -} - -// -------------------------------------------------------------------------- -// Some functions create new objects and return these to python. By -// default, SWIG sets these objects as "unowned" by the shadow class -// created to represent them in python. The result is that these objects -// are not freed when the shadow object calls its __del__ method. Here -// the thisown flag is set to 1 so that the object will be destroyed on -// destruction. -// -------------------------------------------------------------------------- - -%typemap(out) owned_pointer -{ - $result = SWIG_NewPointerObj((void *) $1, $1_descriptor, 1); -} diff --git a/kiva/gl/src/swig/compiled_path.i b/kiva/gl/src/swig/compiled_path.i deleted file mode 100644 index 5a4b3fba1..000000000 --- a/kiva/gl/src/swig/compiled_path.i +++ /dev/null @@ -1,131 +0,0 @@ -// (C) Copyright 2005-2022 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! -%{ - #include "kiva_gl_compiled_path.h" -%} - -// handle kiva_gl::rect declarations - -%include "rect.i" - -%include "agg_typemaps.i" -%apply (double* point_array, int point_count) {(double* pts, int Npts)}; -%apply (double* point_array, int point_count) {(double* start, int Nstart)}; -%apply (double* point_array, int point_count) {(double* end, int Nend)}; -%apply (double* rect_array, int rect_count) {(double* all_rects, int Nrects)}; -%apply (double *vertex_x, double* vertex_y) {(double* x, double *y)}; - - - -namespace kiva_gl -{ - %rename(CompiledPath) compiled_path; - - class compiled_path - { - public: - compiled_path(); - void remove_all(); - void begin_path(); - void close_path(); - void move_to(double x, double y); - void line_to(double x, double y); - void quad_curve_to(double x_ctrl, double y_ctrl, - double x_to, double y_to); - void curve_to(double x_ctrl1, double y_ctrl1, - double x_ctrl2, double y_ctrl2, - double x_to, double y_to); - void arc(double x, double y, double radius, double start_angle, - double end_angle, bool cw=false); - void arc_to(double x1, double y1, double x2, double y2, double radius); - - void add_path(compiled_path& vs); - void lines(double* pts, int Npts); - void line_set(double* start, int Nstart, double* end, int Nend); - void rect(kiva_gl::rect_type &rect); - void rect(double x, double y, double sx, double sy); - void rects(double* all_rects, int Nrects); - void translate_ctm(double x, double y); - void rotate_ctm(double angle); - void scale_ctm(double sx, double sy); - %rename(concat_ctm_agg) concat_ctm(kiva_gl_agg::trans_affine&); - void concat_ctm(kiva_gl_agg::trans_affine& m); - %rename(set_ctm_agg) set_ctm(kiva_gl_agg::trans_affine&); - void set_ctm(kiva_gl_agg::trans_affine& m); - %pythoncode - %{ - def kivaaffine_to_aggaffine(self, ctm): - return AffineMatrix(ctm[0,0], ctm[0,1], ctm[1,0], ctm[1,1], - ctm[2,0], ctm[2,1]) - def concat_ctm(self, ctm): - # This is really tortured and may cause performance problems. - # Unfortunately I don't see a much better way right now. - if '__class__' in dir(ctm) and ctm.__class__.__name__.count('AffineMatrix'): - self.concat_ctm_agg(ctm) - else: - self.concat_ctm_agg(self.kivaaffine_to_aggaffine(ctm)) - def set_ctm(self, ctm): - if '__class__' in dir(ctm) and ctm.__class__.__name__.count('AffineMatrix'): - self.set_ctm_agg(ctm) - else: - self.set_ctm_agg(self.kivaaffine_to_aggaffine(ctm)) - %} - kiva_gl_agg::trans_affine get_ctm(); - void save_ctm(); - void restore_ctm(); - - // methods from kiva_gl_agg::path_storage that are used in testing - unsigned total_vertices() const; - %rename(_rewind) rewind(unsigned); - void rewind(unsigned start=0); - - %rename (_vertex) vertex(unsigned, double*, double*); - unsigned vertex(unsigned idx, double* x, double* y) const; - - %rename (_vertex) vertex(double*, double*); - unsigned vertex(double* x, double* y); - - }; -} - -%pythoncode { -from numpy import array, float64 -def _vertices(self): - """ This is only used for testing. It allows us to retrieve - all the vertices in the path at once. The vertices are - returned as an Nx4 array of the following format. - - x0, y0, cmd0, flag0 - x1, y1, cmd0, flag1 - ... - """ - vertices = [] - self._rewind() - cmd_flag = 1 - while cmd_flag != 0: - pt, cmd_flag = self._vertex() - cmd, flag = _gl.path_cmd(cmd_flag), _gl.path_flags(cmd_flag) - vertices.append((pt[0],pt[1], cmd, flag)) - return array(vertices) - -CompiledPath._vertices = _vertices - - -def get_kiva_ctm(self): - aff = self.get_ctm() - return array([[aff[0], aff[1], 0], - [aff[2], aff[3], 0], - [aff[4], aff[5], 1]], float64) - -CompiledPath.get_kiva_ctm = get_kiva_ctm - -} - -%clear (double *x, double *y); diff --git a/kiva/gl/src/swig/constants.i b/kiva/gl/src/swig/constants.i deleted file mode 100644 index b4754e034..000000000 --- a/kiva/gl/src/swig/constants.i +++ /dev/null @@ -1,152 +0,0 @@ -// (C) Copyright 2005-2022 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! - -///////////////////////////////////////////////////////////////////////////// -// -// 1) Wraps constants and enumerated types commonly used in agg and kiva. -// 2) Provides typemaps to accpet integer inputs for enumerated types. -// 3) Provides python dictionaries to map back and forth between enumerated -// types and more descriptive strings that can be used in python. -// -// A number of constants (and some functions and types) are defined in -// agg_basics.h and kiva_constants.h. -// -// agg_renderer_markers.h is used for rendering simple shapes at multiple -// data points. It is useful for generating scatter plots in simple cases. -// This wrapper is used to pick up the enumerated types for markers such -// as marker_square, marker_circle, etc. The only classes in the header are -// template definitions so they are all ignored by swig. -// -// -///////////////////////////////////////////////////////////////////////////// - -%{ -#include "agg_basics.h" -#include "kiva_gl_constants.h" -%} - -%include "agg_basics.h" -%include "kiva_gl_constants.h" - -%{ - inline unsigned path_cmd(unsigned c) { return c & kiva_gl_agg::path_cmd_mask; } - inline unsigned path_flags(unsigned c) { return c & kiva_gl_agg::path_flags_mask; } -%} - -%include "agg_typemaps.i" - -%apply(kiva_enum_typemap) { kiva_gl_agg::path_flags_e }; -%apply(kiva_enum_typemap) { kiva_gl::marker_e }; -%apply(kiva_enum_typemap) { kiva_gl::draw_mode_e mode, kiva_gl::line_join_e, - kiva_gl::line_cap_e, kiva_gl::blend_mode_e }; -%apply(kiva_enum_typemap) { kiva_gl::pix_format_e, kiva_gl::interpolation_e }; -%apply(kiva_enum_typemap) { kiva_gl::blend_mode_e mode}; - -unsigned path_cmd(unsigned c); -unsigned path_flags(unsigned c); - -%pythoncode %{ - -#---------------------------------------------------------------------------- -# -# map strings values to the marker enumerated values and back with: -# marker_string_map[string] = enum -# marker_enum_map[enum] = string -# -#---------------------------------------------------------------------------- - -kiva_marker_to_agg = {} -kiva_marker_to_agg[1] = marker_square -kiva_marker_to_agg[2] = marker_diamond -kiva_marker_to_agg[3] = marker_circle -kiva_marker_to_agg[4] = marker_crossed_circle -kiva_marker_to_agg[5] = marker_x -kiva_marker_to_agg[6] = marker_triangle_up -kiva_marker_to_agg[7] = marker_triangle_down -kiva_marker_to_agg[8] = marker_cross # "plus" sign; Agg calls this "cross" -kiva_marker_to_agg[9] = marker_dot -kiva_marker_to_agg[10] = marker_pixel - - -#---------------------------------------------------------------------------- -# -# Map strings values to the pix_format enumerated values and back with: -# pix_format_string_map[string] = enum -# pix_format_enum_map[enum] = string -# -#---------------------------------------------------------------------------- - -pix_format_string_map = {} -pix_format_string_map["gray8"] = pix_format_gray8 -pix_format_string_map["rgb555"] = pix_format_rgb555 -pix_format_string_map["rgb565"] = pix_format_rgb565 -pix_format_string_map["rgb24"] = pix_format_rgb24 -pix_format_string_map["bgr24"] = pix_format_bgr24 -pix_format_string_map["rgba32"] = pix_format_rgba32 -pix_format_string_map["argb32"] = pix_format_argb32 -pix_format_string_map["abgr32"] = pix_format_abgr32 -pix_format_string_map["bgra32"] = pix_format_bgra32 - -pix_format_enum_map = {} -for key,value in pix_format_string_map.items(): - pix_format_enum_map[value] = key - -#---------------------------------------------------------------------------- -# Map a pix format string value to the number of bytes per pixel -#---------------------------------------------------------------------------- - -pix_format_bytes = {} -pix_format_bytes["gray8"] = 1 -pix_format_bytes["rgb555"] = 2 -pix_format_bytes["rgb565"] = 2 -pix_format_bytes["rgb24"] = 3 -pix_format_bytes["bgr24"] = 3 -pix_format_bytes["rgba32"] = 4 -pix_format_bytes["argb32"] = 4 -pix_format_bytes["abgr32"] = 4 -pix_format_bytes["bgra32"] = 4 - -pix_format_bits = {} -pix_format_bits["gray8"] = 8 -pix_format_bits["rgb555"] = 15 -pix_format_bits["rgb565"] = 16 -pix_format_bits["rgb24"] = 24 -pix_format_bits["bgr24"] = 24 -pix_format_bits["rgba32"] = 32 -pix_format_bits["argb32"] = 32 -pix_format_bits["abgr32"] = 32 -pix_format_bits["bgra32"] = 32 - -#---------------------------------------------------------------------------- -# -# Map strings values to the interpolation enumerated values and back with: -# interp_string_map[string] = enum -# interp_enum_map[enum] = string -# -#---------------------------------------------------------------------------- - -interp_string_map = {} -interp_string_map["nearest"] = nearest -interp_string_map["bilinear"] = bilinear -interp_string_map["bicubic"] = bicubic -interp_string_map["spline16"] = spline16 -interp_string_map["spline36"] = spline36 -interp_string_map["sinc64"] = sinc64 -interp_string_map["sinc144"] = sinc144 -interp_string_map["sinc256"] = sinc256 -interp_string_map["blackman64"] = blackman64 -interp_string_map["blackman100"] = blackman100 -interp_string_map["blackman256"] = blackman256 - -interp_enum_map = {} -for key,value in interp_string_map.items(): - interp_enum_map[value] = key - -%} diff --git a/kiva/gl/src/swig/font_type.i b/kiva/gl/src/swig/font_type.i deleted file mode 100644 index d70f9cdbe..000000000 --- a/kiva/gl/src/swig/font_type.i +++ /dev/null @@ -1,81 +0,0 @@ -// (C) Copyright 2005-2022 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! -%{ - #include "kiva_gl_font_type.h" -%} - -%include "agg_std_string.i" - -namespace kiva_gl -{ - %rename(KivaGLFontType) font_type; - class font_type - { - public: - %mutable; - int size; - std::string name; - int family; - int style; - int encoding; - std::string filename; - - // constructor - font_type(std::string _name="Arial", - int _size=12, - int _family=0, - int _style=0, - int _encoding=0, - bool validate=true); - - int change_filename(std::string _filename); - - bool is_loaded(); - }; -} -%extend kiva_gl::font_type -{ - char *__repr__() - { - static char tmp[1024]; - // Write out elements of font_type in name, family, size, style, encoding order - // !! We should work to make output formatting conform to - // !! whatever it Numeric does (which needs to be cleaned up also). - sprintf(tmp, "Font(%s, %d, %d, %d, %d)", self->name.c_str(), self->family, - self->size, self->style, - self->encoding); - return tmp; - } - int __eq__(kiva_gl::font_type& other) - { - return (self->name == other.name && - self->family == other.family && - self->size == other.size && - self->style == other.style && - self->encoding == other.encoding); - } -} - -%pythoncode -%{ -def unicode_safe_init(self, _name="Arial", _size=12, _family=0, _style=0, - _encoding=0, validate=True): - ### HACK: C++ stuff expects a string (not unicode) for the face_name, so fix - ### if needed. - if isinstance(_name, bytes): - _name = _name.decode() - obj = _gl.new_KivaGLFontType(_name, _size, _family, _style, - _encoding, validate) - self.this = obj - self.thisown = 1 - -# This is a crappy way of overriding the constructor -KivaGLFontType.__init__ = unicode_safe_init -%} diff --git a/kiva/gl/src/swig/graphics_context.i b/kiva/gl/src/swig/graphics_context.i deleted file mode 100644 index 472c0c2ba..000000000 --- a/kiva/gl/src/swig/graphics_context.i +++ /dev/null @@ -1,396 +0,0 @@ -// (C) Copyright 2005-2022 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! - -// typemaps for many enumerated types used in graphics_contexts -%include "constants.i" - -// Language independent exception handler -%include exception.i - -// handle kiva_gl::rect declarations -%include "rect.i" -//%apply kiva_gl::rect_type {kiva_gl::rect_type}; - -%include "agg_typemaps.i" -%apply (double* point_array, int point_count) {(double* pts, int Npts)}; -%apply (double* point_array, int point_count) {(double* start, int Nstart)}; -%apply (double* point_array, int point_count) {(double* end, int Nend)}; -%apply (double* rect_array, int rect_count) {(double* rects, int Nrects)}; -%apply (double* pt_x, double* pt_y) {(double* tx, double* ty)}; -%apply (double* array6) {(double* out)}; -%apply (double* dash_pattern, int n) { (double* pattern, int n)}; -%apply (unsigned char *image_data, int width, int height, int stride) { - (unsigned char *data, int width, int height, int stride) }; -%apply (owned_pointer) { kiva_gl::graphics_context* }; - -// typemaps for double ary[] -%include "sequence_to_array.i" - -%include "rgba_array.i" -%apply rgba_as_array {kiva_gl_agg::rgba&}; -%{ - kiva_gl_agg::rgba _clear_color = kiva_gl_agg::rgba(1,1,1,1); -%} - -%typemap(out) PyObject* -{ - $result = $1; -} - -%{ -#include "kiva_gl_graphics_context.h" -%} - -namespace kiva_gl { - - %rename(GraphicsContextGL) gl_graphics_context; - - class gl_graphics_context : public graphics_context_base - { - public: - gl_graphics_context(int width, int height, - kiva_gl::pix_format_e format=kiva_gl::pix_format_rgb24); - - ~gl_graphics_context(); - - //--------------------------------------------------------------- - // GL-specific methods - //--------------------------------------------------------------- - void gl_init(); - void gl_cleanup(); - void gl_render_path(kiva_gl::compiled_path *path, bool polygon=false, bool fill=false); - void gl_render_points(double** points, bool polygon, bool fill, - kiva_gl::draw_mode_e mode = FILL); - - //--------------------------------------------------------------- - // GraphicsContextBase interface - //--------------------------------------------------------------- - - int bottom_up(); - int width(); - int height(); - int stride(); - - void save_state(); - void restore_state(); - - void flush(); - void synchronize(); - - void begin_page(); - void end_page(); - - void translate_ctm(double x, double y); - void rotate_ctm(double angle); - void scale_ctm(double sx, double sy); - - %feature("shadow") concat_ctm(kiva_gl_agg::trans_affine& m) - %{ - def concat_ctm(self, m): - if isinstance(m, tuple): - _gl.GraphicsContextGL_concat_ctm(self, _AffineMatrix(*m)) - else: - _gl.GraphicsContextGL_concat_ctm(self, m) - %} - void concat_ctm(kiva_gl_agg::trans_affine& m); - - %feature("shadow") set_ctm(kiva_gl_agg::trans_affine& m) - %{ - def set_ctm(self, m): - if isinstance(m, tuple): - _gl.GraphicsContextGL_set_ctm(self, _AffineMatrix(*m)) - else: - _gl.GraphicsContextGL_set_ctm(self, m) - %} - void set_ctm(kiva_gl_agg::trans_affine& m); - - %feature("shadow") get_ctm() - %{ - def get_ctm(self): - tmp = _gl.GraphicsContextGL_get_ctm(self) - return (tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5]) - %} - kiva_gl_agg::trans_affine get_ctm(); - - %feature("shadow") format() - %{ - def format(self): - enum = _gl.GraphicsContextGL_format(self) - return pix_format_enum_map[enum] - %} - kiva_gl::pix_format_e format(); - - %feature("shadow") get_image_interpolation() - %{ - def get_image_interpolation(self): - enum = _gl.GraphicsContextGL_get_image_interpolation(self) - return interp_enum_map[enum] - %} - interpolation_e get_image_interpolation(); - - %feature("shadow") set_image_interpolation(kiva_gl::interpolation_e interpolation) - %{ - def set_image_interpolation(self,interp): - enum = interp_string_map[interp] - _gl.GraphicsContextGL_set_image_interpolation(self, enum) - %} - void set_image_interpolation(kiva_gl::interpolation_e interpolation); - - %feature("shadow") set_stroke_color(kiva_gl_agg::rgba& rgba_in) - %{ - def set_stroke_color(self, color): - if is_array(color) and len(color) == 3: - ary = color - r, g, b = ary - color = Rgba(r, g, b) - elif is_array(color) and len(color) == 4: - ary = color - r, g, b, a = ary - color = Rgba(r, g, b, a) - _gl.GraphicsContextGL_set_stroke_color(self, color) - %} - void set_stroke_color(kiva_gl_agg::rgba& rgba_in); - kiva_gl_agg::rgba& get_stroke_color(); - - %feature("shadow") set_fill_color(kiva_gl_agg::rgba& rgba_in) - %{ - def set_fill_color(self, color): - if is_array(color) and len(color) == 3: - ary = color - r, g, b = ary - color = Rgba(r, g, b) - elif is_array(color) and len(color) == 4: - ary = color - r, g, b, a = ary - color = Rgba(r, g, b, a) - _gl.GraphicsContextGL_set_fill_color(self, color) - %} - void set_fill_color(kiva_gl_agg::rgba& rgba_in); - kiva_gl_agg::rgba& get_fill_color(); - - void set_alpha(double value); - double get_alpha(); - void set_antialias(int value); - int get_antialias(); - void set_miter_limit(double value); - void set_flatness(double value); - void set_line_width(double value); - void set_line_join(kiva_gl::line_join_e value); - void set_line_cap(kiva_gl::line_cap_e value); - void set_line_dash(double* pattern, int n, double phase=0); - void set_blend_mode(kiva_gl::blend_mode_e value); - kiva_gl::blend_mode_e get_blend_mode(); - - //--------------------------------------------------------------- - // Path manipulation - //--------------------------------------------------------------- - - void begin_path(); - void move_to(double x, double y); - void line_to( double x, double y); - void curve_to(double cpx1, double cpy1, - double cpx2, double cpy2, - double x, double y); - void quad_curve_to(double cpx, double cpy, double x, double y); - - void arc(double x, double y, double radius, double start_angle, - double end_angle, bool cw=false); - void arc_to(double x1, double y1, double x2, double y2, double radius); - - void close_path(); - void add_path(kiva_gl::compiled_path& other_path); - void lines(double* pts, int Npts); - void line_set(double* start, int Nstart, double* end, int Nend); - void rect(kiva_gl::rect_type &rect); - void rect(double x, double y, double sx, double sy); - void rects(double* all_rects, int Nrects); - compiled_path _get_path(); - - //--------------------------------------------------------------- - // Clipping path manipulation - //--------------------------------------------------------------- - - void clip(); - void even_odd_clip(); - void clip_to_rect(double x, double y, double sx, double sy); - void clip_to_rect(kiva_gl::rect_type &rect); - void clip_to_rects(double* new_rects, int Nrects); - void clip_to_rects(kiva_gl::rect_list_type &rects); - kiva_gl::rect_type transform_clip_rectangle(const kiva_gl::rect_type &rect); - void clear_clip_path(); - - int get_num_clip_regions(); - kiva_gl::rect_type get_clip_region(unsigned int i); - - //--------------------------------------------------------------- - // Painting paths (drawing and filling contours) - //--------------------------------------------------------------- - - // Declare clear() to pass by reference so that the typemap applies, - // even though it is pass by value in the actual C++ class - void clear(kiva_gl_agg::rgba& value=_clear_color); - - void fill_path(); - void eof_fill_path(); - void stroke_path(); - // empty function; for some reason this is abstract in the base class - inline void _stroke_path() { } - - void draw_path(draw_mode_e mode=FILL_STROKE); - void draw_rect(double rect[4], draw_mode_e mode=FILL_STROKE); - - %feature("shadow") draw_marker_at_points(double* pts,int Npts, int size, - kiva_gl::marker_e type = kiva_gl::marker_square) - %{ - def draw_marker_at_points(self, pts, size, kiva_marker_type): - marker = kiva_marker_to_agg.get(kiva_marker_type, None) - if marker is None: - success = 0 - else: - args = (self, pts, int(size), marker) - success = _gl.GraphicsContextGL_draw_marker_at_points( - self, pts, int(size), marker - ) - return success - %} - int draw_marker_at_points(double* pts,int Npts,int size, - kiva_gl::marker_e type=kiva_gl::marker_square); - - void draw_path_at_points(double* pts,int Npts, - kiva_gl::compiled_path& marker, - draw_mode_e mode); - - //--------------------------------------------------------------- - // Image rendering - //--------------------------------------------------------------- - - int draw_image(kiva_gl::graphics_context_base* img, double rect[4], bool force_copy=false); - int draw_image(kiva_gl::graphics_context_base* img); - - //--------------------------------------------------------------- - // Text rendering (NOTE: disabled) - //--------------------------------------------------------------- - - %pythoncode - %{ - def show_text(self, text, point = None): - """Displays text at point, or at the current text pen position - if point is None. Returns true if text displayed properly, - false if there was a font issue or a glyph could not be - rendered. Will handle multi-line text separated by backslash-ns - """ - raise RuntimeError("Text is not supported by OpenGL.") - - def show_text_at_point(self, text, dx, dy): - raise RuntimeError("Text is not supported by OpenGL.") - - def get_text_extent(self, text): - raise RuntimeError("Text is not supported by OpenGL.") - - def get_full_text_extent(self, text): - raise RuntimeError("Text is not supported by OpenGL.") - - def get_font(self): - raise RuntimeError("Text is not supported by OpenGL.") - - def set_font(self, font): - raise RuntimeError("Unable to load font.") - - def is_font_initialized(self): - raise RuntimeError("Font not loaded/initialized.") - - def set_font_size(self, size): - raise RuntimeError("Font not loaded/initialized.") - - def get_freetype_text_matrix(self, *args): - raise RuntimeError("Text is not supported by OpenGL.") - - def get_text_matrix(self, matrix): - raise RuntimeError("Text is not supported by OpenGL.") - - def set_text_matrix(self, matrix): - raise RuntimeError("Text is not supported by OpenGL.") - - def set_text_position(self, tx, ty): - raise RuntimeError("Text is not supported by OpenGL") - - def get_text_position(self): - raise RuntimeError("Text is not supported by OpenGL") - - def set_character_spacing(self, value): - raise RuntimeError("Text is not supported by OpenGL.") - - def get_character_spacing(self): - raise RuntimeError("Text is not supported by OpenGL.") - - def set_text_drawing_mode(self, value): - raise RuntimeError("Text is not supported by OpenGL.") - - %} - - //--------------------------------------------------------------------- - // Gradient support (raises NotImplementedError) - //--------------------------------------------------------------------- - - %pythoncode - %{ - def linear_gradient(self, x1, y1, x2, y2, stops, spread_method, units="userSpaceOnUse"): - raise NotImplementedError("Gradient fills are not supported by OpenGL") - - def radial_gradient(self, cx, cy, r, fx, fy, stops, spread_method, units="userSpaceOnUse"): - raise NotImplementedError("Gradient fills are not supported by OpenGL") - - %} - - //--------------------------------------------------------------- - // Additional methods (added as pure python) - //--------------------------------------------------------------- - - %pythoncode - %{ - def get_empty_path(self): - return CompiledPath() - - def convert_pixel_format(self, pix_format, inplace=0): - """ Convert gc from one pixel format to another. - - NOTE: This has never worked on OpenGL, because draw_image has never - been implemented. It used to inherit the GraphicsContextArry - implementation, which relied on the context having a working - implementation of draw_image which would handle the pixel format - conversion. - """ - return self.__class__(self.width(), self.height(), pix_format=pix_format) - - def save(self, filename, file_format=None, pil_options=None): - """ Save the GraphicsContext to a file. - - NOTE: This has never worked on OpenGL, because it draws this - context into an image context by using the agg `rendering_buffer` - as a source of pixel data. The buffer is never used with OpenGL, - so it is always blank. - """ - raise RuntimeError("Saving is not supported by OpenGL.") - - #---------------------------------------------------------------- - # context manager interface - #---------------------------------------------------------------- - - def __enter__(self): - self.save_state() - - def __exit__(self, type, value, traceback): - self.restore_state() - - %} - - }; - -} diff --git a/kiva/gl/src/swig/numpy.i b/kiva/gl/src/swig/numpy.i deleted file mode 100644 index b87bec735..000000000 --- a/kiva/gl/src/swig/numpy.i +++ /dev/null @@ -1,361 +0,0 @@ -/* -*- c -*- */ -// (C) Copyright 2005-2022 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! - -/* Set the input argument to point to a temporary variable */ - -/* -Here are the typemap helper functions for numpy arrays: - - PyArrayObject* obj_to_array_no_conversion(PyObject* input, int typecode) - PyArrayObject* obj_to_array_allow_conversion(PyObject* input, int typecode, - int& is_new_object) - PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject* input, - int typecode, - int& is_new_object) - PyArrayObject* make_contiguous(PyArrayObject* ary, int& is_new_object, - int min_dims = 0, int max_dims = 0) - int require_contiguous(PyArrayObject* ary) - int require_last_dimensions_contiguous(PyArrayObject* ary, int dim_count) - int require_dimensions(PyArrayObject* ary, int exact_dimensions) - int require_dimensions(PyArrayObject* ary, int* exact_dimensions, int n) - int require_size(PyArrayObject* ary, int* size, int n) -*/ - -%{ -#include "numpy/arrayobject.h" -#include - -#define is_array(a) ((a) && PyArray_Check((PyArrayObject *)a)) -#define array_type(a) (int)(((PyArrayObject *)a)->descr->type_num) -#define array_dimensions(a) (((PyArrayObject *)a)->nd) -#define array_size(a,i) (((PyArrayObject *)a)->dimensions[i]) -#define array_is_contiguous(a) (PyArray_ISCONTIGUOUS(ary)) - -std::string pytype_string(PyObject* py_obj) -{ - if(py_obj == NULL) return "C NULL value"; - if(PyCallable_Check(py_obj)) return "callable"; - if(PyString_Check(py_obj)) return "string"; - if(PyInt_Check(py_obj)) return "int"; - if(PyFloat_Check(py_obj)) return "float"; - if(PyDict_Check(py_obj)) return "dict"; - if(PyList_Check(py_obj)) return "list"; - if(PyTuple_Check(py_obj)) return "tuple"; - /*if(PyFile_Check(py_obj)) return "file";*/ - if(PyModule_Check(py_obj)) return "module"; - - //should probably do more intergation (and thinking) on these. - /*if(PyCallable_Check(py_obj) && PyInstance_Check(py_obj)) return "callable"; - if(PyInstance_Check(py_obj)) return "instance";*/ - if(PyCallable_Check(py_obj)) return "callable"; - return "unkown type"; -} - -std::string typecode_string(int typecode) -{ - std::string type_names[20] = {"char", "unsigned byte", "byte", "short", - "unsigned short", "int", "unsigned int", - "long", "float", "double", "complex float", - "complex double", "object", "ntype", - "unknown"}; - return type_names[typecode]; -} - -int type_match(int actual_type, int desired_type) -{ - int match; - // Make sure input has correct numpy type. Allow character and byte to - // match also allow int and long to match. - if (actual_type != desired_type && - !(desired_type == PyArray_INT && actual_type == PyArray_LONG) && - !(desired_type == PyArray_LONG && actual_type == PyArray_INT)) - { - match = 0; - } - else - { - match = 1; - } - return match; -} - -PyArrayObject* obj_to_array_no_conversion(PyObject* input, int typecode) -{ - PyArrayObject* ary = NULL; - if (is_array(input) && array_type(input) == typecode) - { - ary = (PyArrayObject*) input; - } - else if is_array(input) - { - char msg[255] = "Array of type '%s' required. Array of type '%s' given"; - std::string desired_type = typecode_string(typecode); - std::string actual_type = typecode_string(array_type(input)); - PyErr_Format(PyExc_TypeError, msg, - desired_type.c_str(), actual_type.c_str()); - ary = NULL; - } - else - { - char msg[255] = "Array of type '%s' required. A %s was given"; - std::string desired_type = typecode_string(typecode); - std::string actual_type = pytype_string(input); - PyErr_Format(PyExc_TypeError, msg, - desired_type.c_str(), actual_type.c_str()); - ary = NULL; - } - return ary; -} - -PyArrayObject* obj_to_array_allow_conversion(PyObject* input, int typecode, - int& is_new_object) -{ - // Convert object to a numpy array with the given typecode. - // - // Return: - // On Success, return a valid PyArrayObject* with the correct type. - // On failure, return NULL. A python error will have been set. - - PyArrayObject* ary = NULL; - if (is_array(input) && type_match(array_type(input),typecode)) - { - ary = (PyArrayObject*) input; - is_new_object = 0; - } - else - { - PyObject* py_obj = PyArray_FromObject(input, typecode, 0, 0); - // If NULL, PyArray_FromObject will have set python error value. - ary = (PyArrayObject*) py_obj; - is_new_object = 1; - } - - return ary; -} - -PyArrayObject* make_contiguous(PyArrayObject* ary, int& is_new_object, - int min_dims = 0, int max_dims = 0) -{ - PyArrayObject* result; - if (array_is_contiguous(ary)) - { - result = ary; - is_new_object = 0; - } - else - { - result = (PyArrayObject*) PyArray_ContiguousFromObject( - (PyObject*)ary, - array_type(ary), - min_dims, - max_dims); - is_new_object = 1; - } - - return result; -} - -PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject* input, - int typecode, - int& is_new_object) -{ - int is_new1 = 0; - int is_new2 = 0; - PyArrayObject* ary1 = obj_to_array_allow_conversion(input, typecode, - is_new1); - if (ary1) - { - PyArrayObject* ary2 = make_contiguous(ary1, is_new2); - - if ( is_new1 && is_new2) - { - Py_DECREF(ary1); - } - ary1 = ary2; - } - - is_new_object = is_new1 || is_new2; - return ary1; -} - - -int require_contiguous(PyArrayObject* ary) -{ - // Test whether a python object is contiguous. - // - // Return: - // 1 if array is contiguous. - // Otherwise, return 0 and set python exception. - int contiguous = 1; - if (!array_is_contiguous(ary)) - { - char msg[255] = "Array must be contiguous. A discontiguous array was given"; - PyErr_SetString(PyExc_TypeError, msg); - contiguous = 0; - } - return contiguous; -} - -// Useful for allowing images with discontiguous first dimension. -// This sort of array is used for arrays mapped to Windows bitmaps. -/* -int require_last_dimensions_contiguous(PyArrayObject* ary, int dim_count) -{ - int contiguous = 1; - if (array_is_contiguous(ary)) - { - char msg[255] = "Array must be contiguous. A discontiguous array was given"; - PyErr_SetString(PyExc_TypeError, msg); - contiguous = 0; - } - return contiguous; -} -*/ - -int require_dimensions(PyArrayObject* ary, int exact_dimensions) -{ - int success = 1; - if (array_dimensions(ary) != exact_dimensions) - { - char msg[255] = "Array must be have %d dimensions. Given array has %d dimensions"; - PyErr_Format(PyExc_TypeError, msg, - exact_dimensions, array_dimensions(ary)); - success = 0; - } - return success; -} - -int require_dimensions(PyArrayObject* ary, int* exact_dimensions, int n) -{ - int success = 0; - int i; - for (i = 0; i < n && !success; i++) - { - if (array_dimensions(ary) == exact_dimensions[i]) - { - success = 1; - } - } - if (!success) - { - char dims_str[255] = ""; - char s[255]; - for (int i = 0; i < n-1; i++) - { - sprintf(s, "%d, ", exact_dimensions[i]); - strcat(dims_str,s); - } - sprintf(s, " or %d", exact_dimensions[n-1]); - strcat(dims_str,s); - char msg[255] = "Array must be have %s dimensions. Given array has %d dimensions"; - PyErr_Format(PyExc_TypeError, msg, dims_str, array_dimensions(ary)); - } - return success; -} - -int require_size(PyArrayObject* ary, int* size, int n) - -{ - int i; - int success = 1; - for(i=0; i < n;i++) - { - if (size[i] != -1 && size[i] != array_size(ary,i)) - { - success = 0; - } - } - - if (!success) - { - int len; - char desired_dims[255] = "["; - char s[255]; - for (i = 0; i < n; i++) - { - if (size[i] == -1) - { - sprintf(s, "*,"); - } - else - { - sprintf(s, "%d,", size[i]); - } - strcat(desired_dims,s); - } - len = strlen(desired_dims); - desired_dims[len-1] = ']'; - - char actual_dims[255] = "["; - for (i = 0; i < n; i++) - { - sprintf(s, "%d,", (int)array_size(ary,i)); - strcat(actual_dims,s); - } - len = strlen(actual_dims); - actual_dims[len-1] = ']'; - - char msg[255] = "Array must be have shape of %s. Given array has shape of %s"; - PyErr_Format(PyExc_TypeError, msg, desired_dims, actual_dims); - } - return success; -} - - -%} - -%pythoncode %{ -from numpy import ndarray - -def is_array(obj): - return type(obj) is ndarray - -def is_correct_type(obj, numpy_type): - return is_array(obj) and (obj.dtype == numpy_type) - -def numpy_check(obj, typecode, - exact_size = [], - must_be_contiguous = 1, - allow_coersion = 0): - - if is_correct_type(obj, typecode): - ary = obj - elif allow_coersion: - ary = asarray(obj,typecode) - else: - raise TypeError("input is not an array or the array has the wrong type") - - if must_be_contiguous and not ary.flags["CONTIGUOUS"]: - if allow_coersion: - ary = ary.copy() - else: - raise TypeError("input array must be contiguous") - - # check number of dimensions - required_dims = len(exact_size) - if required_dims and required_dims != len(ary.shape): - raise ValueError("The input array does not have the correct shape") - - # check exact shape of each dimension - cnt = 0 - for desired,actual in zip(exact_size,ary.shape): - if desired != -1 and desired != actual: - raise ValueError("The %d dimensions of the array has the wrong shape" % (cnt)) - cnt += 1 - - return ary -%} - -%init %{ - Py_Initialize(); - import_array(); - PyImport_ImportModule("numpy"); -%} diff --git a/kiva/gl/src/swig/rect.i b/kiva/gl/src/swig/rect.i deleted file mode 100644 index 8879098cf..000000000 --- a/kiva/gl/src/swig/rect.i +++ /dev/null @@ -1,47 +0,0 @@ -// (C) Copyright 2005-2022 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! -%{ -#include "kiva_gl_rect.h" -%} - -%typemap(in) (kiva_gl::rect_type &rect) -{ - PyArrayObject* ary=NULL; - int is_new_object; - ary = obj_to_array_contiguous_allow_conversion($input, PyArray_DOUBLE, - is_new_object); - - int size[1] = {4}; - if (!ary || - !require_dimensions(ary, 1) || - !require_size(ary, size, 1)) - { - goto fail; - } - - double* data = (double*)(ary->data); - kiva_gl::rect_type rect(data[0], data[1], data[2], data[3]); - $1 = ▭ - - if (is_new_object) - { - Py_DECREF(ary); - } -} - -%typemap(out) kiva_gl::rect_type -{ - PyObject *pt = PyTuple_New(4); - PyTuple_SetItem(pt,0,PyFloat_FromDouble($1.x)); - PyTuple_SetItem(pt,1,PyFloat_FromDouble($1.y)); - PyTuple_SetItem(pt,2,PyFloat_FromDouble($1.w)); - PyTuple_SetItem(pt,3,PyFloat_FromDouble($1.h)); - $result = pt; -} diff --git a/kiva/gl/src/swig/rgba.i b/kiva/gl/src/swig/rgba.i deleted file mode 100644 index 38aa790d1..000000000 --- a/kiva/gl/src/swig/rgba.i +++ /dev/null @@ -1,104 +0,0 @@ -// (C) Copyright 2005-2022 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! -%{ -#include "agg_color_rgba.h" -%} - -%include "numpy.i" - -%typemap(in, numinputs=0) double* out (double temp[4]) { - $1 = temp; -} - -%typemap(argout) double *out { - // Append output value $1 to $result - npy_intp dims = 4; - PyArrayObject* ary_obj = (PyArrayObject*) PyArray_SimpleNew(1, &dims, PyArray_DOUBLE); - if( ary_obj == NULL ) - return NULL; - double* data = (double*)ary_obj->data; - for (int i=0; i < 4;i++) - data[i] = $1[i]; - Py_DECREF($result); - $result = PyArray_Return(ary_obj); -} - -%typemap(check) (double r) -{ - if ($1 < 0.0 || $1 > 1.0) - { - PyErr_Format(PyExc_ValueError, - "color values must be between 0.0 and 1.0, Got: %g", $1); - } -} - -%apply (double r) {double g, double b, double a}; - - -namespace kiva_gl_agg -{ - %rename(_Rgba) rgba; - struct rgba - { - double r; - double g; - double b; - double a; - - rgba(double r_=0.0, double g_=0.0, double b_=0.0, double a_=1.0); - //void opacity(double a_); - //double opacity() const; - rgba gradient(rgba c, double k) const; - const rgba &premultiply(); - }; -} - -%extend kiva_gl_agg::rgba -{ - char *__repr__() - { - static char tmp[1024]; - sprintf(tmp,"Rgba(%g, %g, %g, %g)", self->r, self->g, self->b, self->a); - return tmp; - } - int __eq__(kiva_gl_agg::rgba& o) - { - return (self->r == o.r && self->g == o.g && - self->b == o.b && self->a == o.a); - } - void asarray(double* out) - { - out[0] = self->r; - out[1] = self->g; - out[2] = self->b; - out[3] = self->a; - } -} - - -%pythoncode %{ -def is_sequence(arg): - try: - len(arg) - return 1 - except: - return 0 - -# Use sub-class to allow sequence as input -class Rgba(_Rgba): - def __init__(self,*args): - if len(args) == 1 and is_sequence(args[0]): - args = tuple(args[0]) - if len(args) not in [3,4]: - raise ValueError("array argument must be 1x3 or 1x4") - _Rgba.__init__(self,*args) -%} - -%clear double r, double g, double b, double a; diff --git a/kiva/gl/src/swig/rgba_array.i b/kiva/gl/src/swig/rgba_array.i deleted file mode 100644 index f488c8b6b..000000000 --- a/kiva/gl/src/swig/rgba_array.i +++ /dev/null @@ -1,101 +0,0 @@ -// (C) Copyright 2005-2022 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! - -// -------------------------------------------------------------------------- -// -// Convert kiva_gl_agg::rgba types to/from Numeric arrays. The rgba_as_array -// typemap will accept any 3 or 4 element sequence of float compatible -// objects and convert them into an kiva_gl_agg::rgba object. -// -// The typemap also converts any rgba output value back to a numeric array -// in python. This is a more useful representation for numerical -// manipulation. -// -// -------------------------------------------------------------------------- - -%{ - #include "agg_color_rgba.h" -%} - -%include "numpy.i" - -#ifdef SWIGPYTHON - -%typemap(in) rgba_as_array (int must_free=0) -{ - must_free = 0; - if ((SWIG_ConvertPtr($input,(void **) &$1, SWIGTYPE_p_kiva_gl_agg__rgba, - SWIG_POINTER_EXCEPTION | 0 )) == -1) - { - PyErr_Clear(); - if (!PySequence_Check($input)) - { - PyErr_SetString(PyExc_TypeError,"Expecting a sequence"); - return NULL; - } - - int seq_len = PyObject_Length($input); - if (seq_len != 3 && seq_len != 4) - { - PyErr_SetString(PyExc_ValueError, - "Expecting a sequence with 3 or 4 elements"); - return NULL; - } - - double temp[4] = {0.0,0.0,0.0,1.0}; - for (int i =0; i < seq_len; i++) - { - PyObject *o = PySequence_GetItem($input,i); - if (PyFloat_Check(o)) - { - temp[i] = PyFloat_AsDouble(o); - } - else - { - PyObject* converted = PyNumber_Float(o); - if (!converted) - { - PyErr_SetString(PyExc_TypeError, - "Expecting a sequence of floats"); - return NULL; - } - temp[i] = PyFloat_AsDouble(converted); - Py_DECREF(converted); - } - if ((temp[i] < 0.0) || (temp [i] > 1.0)) - { - PyErr_SetString(PyExc_ValueError, - "Color values must be between 0.0 an 1.0"); - return NULL; - } - } - $1 = new kiva_gl_agg::rgba(temp[0],temp[1],temp[2],temp[3]); - must_free = 1; - } -} - -%typemap(freearg) rgba_as_array { - if (must_free$argnum) - delete $1; -} - -%typemap(out) rgba_as_array -{ - npy_intp size = 4; - $result = PyArray_SimpleNew(1, &size, PyArray_DOUBLE); - double* data = (double*)((PyArrayObject*)$result)->data; - data[0] = $1->r; - data[1] = $1->g; - data[2] = $1->b; - data[3] = $1->a; -} - -#endif - diff --git a/kiva/gl/src/swig/sequence_to_array.i b/kiva/gl/src/swig/sequence_to_array.i deleted file mode 100644 index 1762bd83d..000000000 --- a/kiva/gl/src/swig/sequence_to_array.i +++ /dev/null @@ -1,44 +0,0 @@ -// (C) Copyright 2005-2022 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! - -// Map a Python sequence into any sized C double array -// This handles arrays and sequences with non-float values correctly. -// !! Optimize for array conversion?? - -#ifdef SWIGPYTHON - -%typemap(in) double[ANY](double temp[$1_dim0]) { - if (!PySequence_Check($input)) { - PyErr_SetString(PyExc_TypeError, "Expecting a sequence"); - return NULL; - } - if (PyObject_Length($input) != $1_dim0) { - PyErr_SetString(PyExc_ValueError, "Expecting a sequence with $1_dim0 elements"); - return NULL; - } - for (int i=0; i < $1_dim0; ++i) { - PyObject *o = PySequence_GetItem($input, i); - if (PyFloat_Check(o)) { - temp[i] = PyFloat_AsDouble(o); - } - else { - PyObject* converted = PyNumber_Float(o); - if (!converted) { - PyErr_SetString(PyExc_TypeError, "Expecting a sequence of floats"); - return NULL; - } - temp[i] = PyFloat_AsDouble(converted); - Py_DECREF(converted); - } - } - $1 = &temp[0]; -} - -#endif diff --git a/kiva/tests/test_gl_drawing.py b/kiva/tests/test_gl_drawing.py deleted file mode 100644 index 9be0f0fce..000000000 --- a/kiva/tests/test_gl_drawing.py +++ /dev/null @@ -1,85 +0,0 @@ -# (C) Copyright 2005-2022 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 contextlib -import sys -import unittest - -try: - import pyglet -except ImportError: - PYGLET_NOT_AVAILABLE = True -else: - PYGLET_NOT_AVAILABLE = False - -from kiva.tests.drawing_tester import DrawingImageTester - -is_linux = (sys.platform == "linux") - - -@unittest.skipIf(not is_linux, "Pyglet/GL backend issues on most platforms") -@unittest.skipIf(PYGLET_NOT_AVAILABLE, "Cannot import pyglet") -class TestGLDrawing(DrawingImageTester, unittest.TestCase): - def tearDown(self): - if hasattr(self, "window") and self.window is not None: - self.window.close() - del self.window - DrawingImageTester.tearDown(self) - - def create_graphics_context(self, width=600, height=600, pixel_scale=2.0): - from kiva.gl import GraphicsContext - - # XXX: Ignore scaling in the unit tests so this works on CI. - # But really, we should just get rid of this rotted backend. - self.window = pyglet.window.Window(width=width, height=height) - gc = GraphicsContext((width, height), base_pixel_scale=1.0) - gc.gl_init() - return gc - - @unittest.expectedFailure - def test_image(self): - """ gl image drawing is broken. It depends on pygarrayimage, which - is not actively maintained and appears to be broken now. - """ - DrawingImageTester.test_image() - - @unittest.skip("gl graphics context does not support star_clip (#164)") - def test_star_clip(self): - # FIXME: overriding test since it segfaults - DrawingImageTester.test_star_clip(self) - - @unittest.skipIf( - sys.platform == "darwin", - "Error getting sfnt font name on OSX (enthought/enable#541)", - ) - def test_text(self): - DrawingImageTester.test_text(self) - - @unittest.skip("gl graphics context does not clip text properly (#165)") - def test_text_clip(self): - # gl graphics context does not clip text properly (#165). - # may actually work under Wx? - DrawingImageTester.test_text_clip(self) - - @contextlib.contextmanager - def draw_and_check(self): - from pyglet.image.codecs.png import PNGImageEncoder - - self.window.clear() - self.window.switch_to() - self.window.dispatch_events() - yield - self.window.dispatch_events() - filename = "{0}.png".format(self.filename) - buffer = pyglet.image.get_buffer_manager() - with open(filename, mode="wb") as file_handle: - buffer.get_color_buffer().save( - filename, file=file_handle, encoder=PNGImageEncoder() - ) - self.assertImageSavedWithContent(filename) diff --git a/setup.py b/setup.py index de76a7fbe..d1c2efefd 100644 --- a/setup.py +++ b/setup.py @@ -303,79 +303,6 @@ def base_extensions(): ] -def gl_extensions(): - kiva_gl_dir = os.path.join('kiva', 'gl') - agg_dir = os.path.join(kiva_gl_dir, 'src', 'agg') - - kiva_gl_libraries = [] - define_macros = [] - extra_compile_args = [] - extra_link_args = [] - include_dirs = [] - - if sys.platform == 'win32': - kiva_gl_libraries += ['opengl32', 'glu32'] - elif sys.platform == 'darwin': - # Options to make macOS link OpenGL - darwin_frameworks = ['ApplicationServices', 'OpenGL'] - for framework in darwin_frameworks: - extra_link_args.extend(['-framework', framework]) - - include_dirs += [ - '/System/Library/Frameworks/%s.framework/Versions/A/Headers' % x - for x in darwin_frameworks - ] - define_macros += [ - ('__DARWIN__', None), - # OpenGL is deprecated starting with macOS 10.14 and gone in 10.15 - # But that doesn't mean we want to hear about it. We know, Apple. - ('GL_SILENCE_DEPRECATION', None), - ] - extra_compile_args = [ - '-Wfatal-errors', - '-Wno-unused-function', - ] - else: - # This should work for most linux distributions - kiva_gl_libraries += ['GL', 'GLU'] - extra_compile_args = [ - '-Wfatal-errors', - '-Wno-unused-function', - ] - - kiva_gl_sources = [ - *glob.glob(os.path.join(kiva_gl_dir, 'src', 'kiva_gl_*.cpp')), - *glob.glob(os.path.join(agg_dir, '*.cpp')), - ] - include_dirs += [ - os.path.join(kiva_gl_dir, 'src'), - agg_dir, - numpy.get_include(), - ] - swig_opts = [ - '-I' + os.path.join(kiva_gl_dir, 'src', 'swig'), - '-I' + os.path.join(kiva_gl_dir, 'src'), - '-I' + agg_dir, - '-c++', - ] - - return [ - Extension( - 'kiva.gl._gl', - sources=[ - os.path.join(kiva_gl_dir, 'gl.i'), - ] + kiva_gl_sources, - swig_opts=swig_opts, - include_dirs=include_dirs, - extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args, - define_macros=define_macros, - libraries=kiva_gl_libraries, - language='c++', - ), - ] - - def macos_extensions(): extra_link_args = [] frameworks = [ @@ -449,7 +376,7 @@ def macos_extensions(): long_description = fp.read() # Collect extensions - ext_modules = base_extensions() + agg_extensions() + gl_extensions() + ext_modules = base_extensions() + agg_extensions() if sys.platform == 'darwin': ext_modules += macos_extensions() diff --git a/tox.ini b/tox.ini index 778f990ee..e2efc827a 100644 --- a/tox.ini +++ b/tox.ini @@ -5,7 +5,6 @@ import-order-style = appnexus per-file-ignores = # SWIG generated kiva/agg/agg.py: E,F,I,W - kiva/gl/gl.py: E,F,I,W # Vendored kiva/agg/freetype2/*: E,F,I,W kiva/_fontdata.py: E,F,I,W From 5d1397922110b2508e660d7a2e3d6a3f2cbe8020 Mon Sep 17 00:00:00 2001 From: Corran Webster Date: Tue, 18 Apr 2023 16:25:08 +0100 Subject: [PATCH 2/2] Hunt down more OpenGL references and specific code. --- .github/workflows/bleeding-edge.yml | 4 +--- .github/workflows/test-with-edm.yml | 2 -- .github/workflows/test-with-pip.yml | 4 +--- README.rst | 1 - docs/source/enable/overview.rst | 3 +-- docs/source/kiva/overview.rst | 10 +++------- enable/component.py | 6 +----- enable/gcbench/bench.py | 1 - kiva/basecore2d.py | 15 ++++++--------- kiva/constants.py | 2 -- 10 files changed, 13 insertions(+), 35 deletions(-) diff --git a/.github/workflows/bleeding-edge.yml b/.github/workflows/bleeding-edge.yml index def91f6b7..4c801c754 100644 --- a/.github/workflows/bleeding-edge.yml +++ b/.github/workflows/bleeding-edge.yml @@ -34,8 +34,6 @@ jobs: if: matrix.toolkit != 'wx' && matrix.toolkit != 'null' - name: Install dependencies for Linux run: | - # needed for GL - sudo apt-get install libglu1-mesa-dev # needed for Celiagg sudo apt-get install libfreetype-dev libharfbuzz-dev # needed for Cairo @@ -49,7 +47,7 @@ jobs: run: | python -m pip install --upgrade pip wheel - name: Install local packages - run: pip install ".[cairo,gl,layout,pdf,svg,test,${{ matrix.toolkit }}]" + run: pip install ".[cairo,layout,pdf,svg,test,${{ matrix.toolkit }}]" - name: Install source dependencies run: | python -m pip install git+https://github.com/enthought/traits.git diff --git a/.github/workflows/test-with-edm.yml b/.github/workflows/test-with-edm.yml index d9bc87da3..c180e64c1 100644 --- a/.github/workflows/test-with-edm.yml +++ b/.github/workflows/test-with-edm.yml @@ -23,8 +23,6 @@ jobs: - name: Install Qt dependencies uses: ./.github/actions/install-qt-support if: matrix.toolkit != 'wx' - - name: Install GL dependencies for Linux - run: sudo apt-get install libglu1-mesa-dev - name: Cache EDM packages uses: actions/cache@v2 with: diff --git a/.github/workflows/test-with-pip.yml b/.github/workflows/test-with-pip.yml index a343b8cb7..13c39354b 100644 --- a/.github/workflows/test-with-pip.yml +++ b/.github/workflows/test-with-pip.yml @@ -40,8 +40,6 @@ jobs: if: matrix.toolkit != 'wx' && matrix.toolkit != 'null' - name: Install dependencies for Linux run: | - # needed for GL - sudo apt-get install libglu1-mesa-dev # needed for Celiagg sudo apt-get install libfreetype-dev libharfbuzz-dev # needed for Cairo @@ -55,7 +53,7 @@ jobs: run: | python -m pip install --upgrade pip wheel - name: Install local packages - run: pip install ".[cairo,gl,layout,pdf,svg,test,${{ matrix.toolkit }}]" + run: pip install ".[cairo,layout,pdf,svg,test,${{ matrix.toolkit }}]" - name: Install celiagg manually # This is needed until new release of celiagg # - numpy is needed for install in current released version diff --git a/README.rst b/README.rst index dced7bdec..f908207e3 100644 --- a/README.rst +++ b/README.rst @@ -71,7 +71,6 @@ the Enable/Kiva project: - `SWIG `_ - `fonttools `_ - (on Linux) X11-devel (development tools for X11) -- (on Linux) libglu1-mesa-dev (OpenGL utility library for development) - (on Mac OS X) `Cython `_ Enable/Kiva also have the following requirements: diff --git a/docs/source/enable/overview.rst b/docs/source/enable/overview.rst index 21e78d139..f9960ce2c 100644 --- a/docs/source/enable/overview.rst +++ b/docs/source/enable/overview.rst @@ -260,8 +260,7 @@ Backbuffer A backbuffer provides the ability to render into an offscreen buffer, which is blitted on every draw, until it is invalidated. Various traits such as :attr:`use_backbuffer` and :attr:`backbuffer_padding` control the behavior of -the backbuffer. A backbuffer is used for non-OpenGL backends, such as `agg` -and on OS X. If :attr:`use_backbuffer` is False, a backbuffer is never used, +the backbuffer. If :attr:`use_backbuffer` is False, a backbuffer is never used, even if a backbuffer is referenced by a component. Users typically subclass Chaco :class:`PlotComponent`, but may need features diff --git a/docs/source/kiva/overview.rst b/docs/source/kiva/overview.rst index f285a72a0..1e4220b8e 100644 --- a/docs/source/kiva/overview.rst +++ b/docs/source/kiva/overview.rst @@ -8,10 +8,9 @@ Kiva is a 2D vector drawing interface providing functionality similar to `Quartz `_, `Cairo `_, the `Qt QPainter interface `_, -the 2D drawing routines of `OpenGL `_ , the HTML5 -Canvas element and many other similar 2D vector drawing APIs. Rather than -re-implementing everything, Kiva is a Python interface layer that sits on top -of many different back-ends, some of which are in fact provided by some of +the HTML5 Canvas element and many other similar 2D vector drawing APIs. Rather +than re-implementing everything, Kiva is a Python interface layer that sits on +top of many different back-ends, some of which are in fact provided by some of these libraries. Which back-ends are available depends on the platform, GUI toolkit, and capabilities of the system. For example the Quartz backend is only available on Mac OS systems, while the QPainter backend is available if PyQt @@ -410,9 +409,6 @@ celiagg kiva/enable. It is planned that this will become the default image backend in a future release. -gl - OpenGL drawing. This backend is quite limited compared to others. - qpainter Qt ``QPainter`` drawing. This is only availble with the Qt toolkit. diff --git a/enable/component.py b/enable/component.py index 768789e5c..d1826a8c2 100644 --- a/enable/component.py +++ b/enable/component.py @@ -729,11 +729,7 @@ def _draw(self, gc, view_bounds=None, mode="default"): self.drawn_outer_position = list(self.outer_position[:]) self.drawn_outer_bounds = list(self.outer_bounds[:]) - # OpenGL-based graphics-contexts have a `gl_init()` method. We - # test for this to avoid having to import the OpenGL - # GraphicsContext just to do an isinstance() check. - is_gl = hasattr(gc, "gl_init") - if self.use_backbuffer and (not is_gl): + if self.use_backbuffer: if self.backbuffer_padding: x, y = self.outer_position width, height = self.outer_bounds diff --git a/enable/gcbench/bench.py b/enable/gcbench/bench.py index a31025cb5..b628335ba 100644 --- a/enable/gcbench/bench.py +++ b/enable/gcbench/bench.py @@ -25,7 +25,6 @@ "blend2d": "enable.null.blend2d", "cairo": "enable.null.cairo", "celiagg": "enable.null.celiagg", - "opengl": "enable.gcbench.opengl", "qpainter": "enable.null.qpainter", "quartz": "enable.null.quartz", }, diff --git a/kiva/basecore2d.py b/kiva/basecore2d.py index 1de3ed4a6..9181f1c77 100644 --- a/kiva/basecore2d.py +++ b/kiva/basecore2d.py @@ -22,9 +22,8 @@ treat any alpha value greater than 0 as fully opaque. transform currently a 3x3 array. This is not the - most convenient in some backends. Mac and OpenGL - use a 1-D 6 element array. We need to either make - transform a class or always use accessor functions + most convenient in some backends. Quartz uses a 1-D 6 element array. + We need to either make transform a class or always use accessor functions to access its values. Currently, I do the latter. """ @@ -134,8 +133,7 @@ def __init__(self, *args, **kwargs): # We're currently maintaining a couple of copies of the ctm around. # The state.ctm is used mainly for user querying, etc. We also have # something called the device_ctm which is actually used in the - # drawing of objects. In some implementation (OpenGL), the - # device_ctm is actually maintained in hardware. + # drawing of objects. # -------------------------------------------------------------------- self.device_prepare_device_ctm() @@ -1204,9 +1202,8 @@ def device_prepare_device_ctm(self): def device_transform_device_ctm(self, func, args): """ Default implementation for handling scaling matrices. - Many implementations will just use this function. Others, like - OpenGL, can benefit from overriding the method and using - hardware acceleration. + Many implementations will just use this function. Others can + benefit from overriding the method and using hardware acceleration. """ if func == SCALE_CTM: self.device_ctm = affine.scale(self.device_ctm, args[0], args[1]) @@ -1227,7 +1224,7 @@ def device_draw_rect(self, x, y, sx, sy, mode): self._new_subpath() # When rectangles are rotated, they have to be drawn as a polygon # on most devices. We'll need to specialize this on API's that - # can handle rotated rects such as Quartz and OpenGL(?). + # can handle rotated rects such as Quartz. # All transformations are done in the call to lines(). pts = array( ((x, y), (x, y + sy), (x + sx, y + sy), (x + sx, y), (x, y)) diff --git a/kiva/constants.py b/kiva/constants.py index 7d8dc4bbb..3b9588bf1 100644 --- a/kiva/constants.py +++ b/kiva/constants.py @@ -115,8 +115,6 @@ # ----------------------------------------------------------------------------- # Subpath CTM Constants # -# These are added so its possible for OpenGL to do the matrix transformations -# on the data (its much faster than doing it with Numeric). # ----------------------------------------------------------------------------- SCALE_CTM = 5