Esempio n. 1
0
    def test_fill_preserve(self):
        path = Path(__file__).parent.joinpath(
            'output/polygon_drawer_fill_preserve.svg')
        path.unlink(missing_ok=True)
        canvas_builder = CanvasBuilder()
        canvas_builder.set_path(path)
        canvas_builder.set_size(Cu.from_pt(100), Cu.from_pt(100))

        canvas = canvas_builder.build()

        polygon_drawer = PolygonDrawer()
        polygon_drawer.fill_color = (1, 0, 0)
        polygon_drawer.stroke_color = (0, 1, 0)
        polygon_drawer.stroke_width = Cu.from_pt(2)
        polygon_drawer.geoms = [
            Polygon([
                (30, 30),
                (70, 30),
                (70, 70),
                (30, 70),
                (30, 30),
            ])
        ]
        polygon_drawer.draw(canvas)

        canvas.close()

        assert path.exists()

        with open(path, 'r') as file:
            data = file.read()
            assert data.find('M 30 30 L 70 30 L 70 70 L 30 70 Z M 30 30') != -1
            assert data.find('fill:rgb(100%,0%,0%)') != -1
            assert data.find('stroke-width:2') != -1
            assert data.find('stroke:rgb(0%,100%,0%);') != -1
Esempio n. 2
0
    def __init__(self,
                 path: Path,
                 surface_type: str,
                 width: float,
                 height: float,
                 scale: float = 1):
        self.width = width
        self.height = height
        self.scale = scale
        self.path_as_posix = path.as_posix()

        if surface_type == 'pdf':
            surface = cairo.PDFSurface(self.path_as_posix, width, height)
        elif surface_type == 'svg':
            surface = cairo.SVGSurface(self.path_as_posix, width, height)
        elif surface_type == 'png':
            surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width),
                                         int(height))
        else:
            raise Exception('Unexpected Format: %s' % surface_type)

        context = cairo.Context(surface)
        self.surface = surface
        self.context = context

        if isinstance(self.surface, cairo.ImageSurface):
            self.context.scale(
                CanvasUnit.from_pt(1).px * self.scale,
                CanvasUnit.from_pt(1).px * self.scale)
Esempio n. 3
0
 def logical_extents(self) -> CanvasBbox:
     extent = self._layout.get_extents()[1]
     x = CanvasUnit.from_pt(pangocffi.units_to_double(extent.x))
     y = CanvasUnit.from_pt(pangocffi.units_to_double(extent.y))
     x += self._position.x
     y += self._position.y
     width = CanvasUnit.from_pt(pangocffi.units_to_double(extent.width))
     height = CanvasUnit.from_pt(pangocffi.units_to_double(extent.height))
     return CanvasBbox(CanvasCoordinate(x, y), width, height)
    def test_identity(self):
        assert CanvasUnit.from_pt(1).pt == 1
        assert CanvasUnit.from_in(1).inches == 1
        assert CanvasUnit.from_cm(1).cm == 1
        assert CanvasUnit.from_mm(1).mm == 1
        assert CanvasUnit.from_px(1).px == 1
        assert CanvasUnit.from_pango(1).pango == 1

        assert CanvasUnit.from_pt(2).pt == 2
        assert CanvasUnit.from_in(2).inches == 2
        assert CanvasUnit.from_cm(2).cm == 2
        assert CanvasUnit.from_mm(2).mm == 2
        assert CanvasUnit.from_px(2).px == 2
        assert CanvasUnit.from_pango(2).pango == 2
Esempio n. 5
0
 def draw_symbol(self, key, point: Point, canvas: Canvas):
     canvas.context.set_source_rgba(point.x/100, point.y/100, 0, 1)
     CairoHelper.draw_point(
         canvas.context,
         point,
         Cu.from_pt(key).pt
     )
    def test_single_stripe(self):
        path = Path(__file__).parent.joinpath(
            'output/stripe_filled_polygon_drawer_single.svg')
        path.unlink(missing_ok=True)
        canvas_builder = CanvasBuilder()
        canvas_builder.set_path(path)
        canvas_builder.set_size(Cu.from_pt(100), Cu.from_pt(100))

        canvas = canvas_builder.build()

        drawer = StripeFilledPolygonDrawer()
        drawer.stripe_colors = [(0, 1, 0)]
        drawer.geoms = [
            Polygon([
                (30, 30),
                (70, 30),
                (70, 70),
                (30, 70),
                (30, 30),
            ])
        ]
        drawer.draw(canvas)

        drawer.geoms = [
            Polygon([
                (40, 40),
                (60, 40),
                (60, 60),
                (40, 60),
                (40, 40),
            ])
        ]
        drawer.stripe_colors = [None]
        drawer.draw(canvas)

        canvas.close()

        assert path.exists()

        with open(path, 'r') as file:
            data = file.read()
            assert data.find('M 30 30 L 70 30 L 70 70 L 30 70 Z M 30 30') != -1
            assert data.find('M 40 40 L 60 40 L 60 60 L 40 60 Z M 40 40') == -1
            assert data.find('fill:rgb(0%,100%,0%)') != -1
            assert data.find('stroke:none') != -1
            assert data.find('stroke-width:') == -1
Esempio n. 7
0
    def test_z_func(self):
        path = Path(__file__).parent.joinpath(
            'output/symbol_drawer_z_func.svg'
        )
        path.unlink(missing_ok=True)
        canvas_builder = CanvasBuilder()
        canvas_builder.set_path(path)
        canvas_builder.set_size(Cu.from_pt(100), Cu.from_pt(100))

        canvas = canvas_builder.build()

        class MySymbolDrawer(SymbolDrawer):
            def draw_symbol(self, key, point: Point, canvas: Canvas):
                canvas.context.set_source_rgba(point.x/100, point.y/100, 0, 1)
                CairoHelper.draw_point(
                    canvas.context,
                    point,
                    Cu.from_pt(20).pt
                )

        my_symbol_drawer = MySymbolDrawer()
        my_symbol_drawer.points = [
            Point(30, 70),
            Point(35, 60),
            Point(40, 50),
            Point(45, 40),
            Point(50, 30),
            Point(55, 40),
            Point(60, 50),
            Point(65, 60),
            Point(70, 70)
        ]
        my_symbol_drawer.draw(canvas)

        canvas.close()

        assert path.exists()

        with open(path, 'r') as file:
            data = file.read()
            # Assert that the symbols appear
            assert data.find('rgb(50%,30%,0%)') != -1
            assert data.find('rgb(50%,30%,0%)') < data.find('rgb(45%,40%,0%)')
            assert data.find('rgb(45%,40%,0%)') < data.find('rgb(55%,40%,0%)')
Esempio n. 8
0
    def test_can_iterate_dict(self):
        path = Path(__file__).parent.joinpath(
            'output/symbol_drawer_can_iterate_dict.svg'
        )
        path.unlink(missing_ok=True)
        canvas_builder = CanvasBuilder()
        canvas_builder.set_path(path)
        canvas_builder.set_size(Cu.from_pt(100), Cu.from_pt(100))

        canvas = canvas_builder.build()

        class MySymbolDrawer(SymbolDrawer):
            def draw_symbol(self, key, point: Point, canvas: Canvas):
                canvas.context.set_source_rgba(point.x/100, point.y/100, 0, 1)
                CairoHelper.draw_point(
                    canvas.context,
                    point,
                    Cu.from_pt(key).pt
                )

        my_symbol_drawer = MySymbolDrawer()
        my_symbol_drawer.points = {
            2: Point(30, 70),
            4: Point(35, 60),
            6: Point(40, 50),
            8: Point(45, 40),
            10: Point(50, 30),
            12: Point(55, 40),
            14: Point(60, 50),
            16: Point(65, 60),
            18: Point(70, 70)
        }
        my_symbol_drawer.draw(canvas)

        canvas.close()

        assert path.exists()

        with open(path, 'r') as file:
            data = file.read()
            # Assert that the symbols appear with correct size
            assert data.find('d="M 55 30 C') != -1
            assert data.find('d="M 79 70 C') != -1
    def test_validation(self):
        with self.assertRaisesRegex(
                Exception, 'length of width_arr is not the same as color_arr'):
            drawer = StripeFilledPolygonDrawer()
            drawer.stripe_colors = [(0, 1, 0), (0, 1, 0)]
            drawer.stripe_widths = [Cu.from_pt(10)]
            drawer.draw(MagicMock())

        with self.assertRaisesRegex(
                Exception, 'width_arr must contain at least one value'):
            drawer = StripeFilledPolygonDrawer()
            drawer.stripe_colors = []
            drawer.stripe_widths = []
            drawer.draw(MagicMock())

        with self.assertRaisesRegex(
                Exception, 'width_arr must be a positive non-zero length'):
            drawer = StripeFilledPolygonDrawer()
            drawer.stripe_colors = [(0, 1, 0), (0, 1, 0)]
            drawer.stripe_widths = [Cu.from_pt(10), Cu.from_pt(0)]
            drawer.draw(MagicMock())
Esempio n. 10
0
    def test_multi_line_string(self):
        path = Path(__file__).parent.joinpath(
            'output/line_drawer_multi_line_string.svg')
        path.unlink(missing_ok=True)
        canvas_builder = CanvasBuilder()
        canvas_builder.set_path(path)
        canvas_builder.set_size(Cu.from_pt(100), Cu.from_pt(100))

        canvas = canvas_builder.build()

        line_drawer = LineDrawer()
        line_drawer.stroke_color = (1, 0, 0)
        line_drawer.stroke_width = Cu.from_pt(1.5)
        line_drawer.geoms = [
            MultiLineString([[
                (30, 30),
                (70, 30),
                (70, 70),
                (30, 70),
            ], [
                (40, 40),
                (40, 60),
                (60, 60),
                (60, 40),
            ]])
        ]
        line_drawer.draw(canvas)

        canvas.close()

        assert path.exists()

        with open(path, 'r') as file:
            data = file.read()
            assert data.find('M 30 30 L 70 30 L 70 70 L 30 70') != -1
            assert data.find('M 40 40 L 40 60 L 60 60 L 60 40') != -1
            assert data.find('fill:none') != -1
            assert data.find('stroke-width:1.5') != -1
            assert data.find('stroke:rgb(100%,0%,0%);') != -1
    def test_two_vertical_stripes(self):
        path = Path(__file__).parent.joinpath(
            'output/stripe_filled_polygon_drawer_two_vertical_stripes.svg')
        path.unlink(missing_ok=True)
        canvas_builder = CanvasBuilder()
        canvas_builder.set_path(path)
        canvas_builder.set_size(Cu.from_pt(100), Cu.from_pt(100))

        canvas = canvas_builder.build()

        drawer = StripeFilledPolygonDrawer()
        drawer.stripe_colors = [(0, 1, 0), (0, 0, 1)]
        drawer.stripe_widths = [Cu.from_pt(20), Cu.from_pt(20)]
        drawer.stripe_origin = CanvasCoordinate.from_pt(30, 30)
        drawer.stripe_angle = math.pi / 2  # Vertical stripes
        drawer.geoms = [
            Polygon([
                (30, 30),
                (70, 30),
                (70, 70),
                (30, 70),
                (30, 30),
            ])
        ]
        drawer.draw(canvas)

        canvas.close()

        assert path.exists()

        with open(path, 'r') as file:
            data = file.read()
            assert data.find('M 30 30 L 30 70 L 50 70 L 50 30 Z M 30 30') != -1
            assert data.find('M 50 30 L 50 70 L 70 70 L 70 30 Z M 50 30') != -1
            assert data.find('fill:rgb(0%,100%,0%)') != -1
            assert data.find('fill:rgb(0%,0%,100%)') != -1
            assert data.find('stroke:none') != -1
            assert data.find('stroke-width:') == -1
    def test_multi_polygons(self):
        path = Path(__file__).parent.joinpath(
            'output/stripe_filled_polygon_drawer_multi_polygons.svg')
        path.unlink(missing_ok=True)
        canvas_builder = CanvasBuilder()
        canvas_builder.set_path(path)
        canvas_builder.set_size(Cu.from_pt(100), Cu.from_pt(100))

        canvas = canvas_builder.build()

        drawer = StripeFilledPolygonDrawer()
        drawer.stripe_colors = [(1, 1, 0), None, (0.7, 0, 0.7), (0, 0, 0)]
        drawer.stripe_widths = [
            Cu.from_pt(5),
            Cu.from_pt(5),
            Cu.from_pt(5),
            Cu.from_pt(5),
        ]
        drawer.stripe_origin = CanvasCoordinate.from_pt(30, 30)
        drawer.stripe_angle = math.pi / 8  # Vertical stripes
        drawer.geoms = [
            MultiPolygon([
                Polygon([
                    (30, 30),
                    (70, 30),
                    (70, 70),
                    (30, 70),
                    (30, 30),
                ], [[
                    (35, 35),
                    (65, 35),
                    (65, 65),
                    (35, 65),
                    (35, 35),
                ]]),
                Polygon([
                    (40, 40),
                    (60, 40),
                    (60, 60),
                    (40, 60),
                    (40, 40),
                ])
            ])
        ]
        drawer.draw(canvas)

        canvas.close()

        assert path.exists()

        with open(path, 'r') as file:
            data = file.read()
            assert data.find('fill:rgb(100%,100%,0%)') != -1
            assert data.find('fill:rgb(0%,0%,0%)') != -1
            assert data.find('fill:rgb(70%,0%,70%)') != -1
            assert data.find('stroke:none') != -1
            assert data.find('stroke-width:') == -1
Esempio n. 13
0
    def test_line_string(self):
        path = Path(__file__).parent.joinpath(
            'output/line_drawer_line_string.svg')
        path.unlink(missing_ok=True)
        canvas_builder = CanvasBuilder()
        canvas_builder.set_path(path)
        canvas_builder.set_size(Cu.from_pt(100), Cu.from_pt(100))

        canvas = canvas_builder.build()

        line_drawer = LineDrawer()
        line_drawer.stroke_color = (0, 1, 0)
        line_drawer.stroke_width = Cu.from_pt(1.5)
        line_drawer.stroke_dashes = ([
            Cu.from_pt(1),
            Cu.from_pt(3),
            Cu.from_pt(3),
            Cu.from_pt(3)
        ], Cu.from_pt(4))
        line_drawer.stroke_line_cap = cairocffi.constants.LINE_CAP_ROUND
        line_drawer.stroke_line_join = cairocffi.constants.LINE_JOIN_MITER
        line_drawer.geoms = [
            LineString([
                (30, 30),
                (70, 30),
                (70, 70),
                (30, 70),
            ])
        ]
        line_drawer.draw(canvas)

        canvas.close()

        assert path.exists()

        with open(path, 'r') as file:
            data = file.read()
            assert data.find('M 30 30 L 70 30 L 70 70 L 30 70') != -1
            assert data.find('fill:none') != -1
            assert data.find('stroke-width:1.5') != -1
            assert data.find('stroke:rgb(0%,100%,0%);') != -1
Esempio n. 14
0
    def draw_rectangle(self, canvas: Canvas, offset: int, unit: str):
        height = CanvasUnit.from_pt(10).pt
        width = CanvasUnit.from_unit(1, unit).pt
        offset_height = height * offset
        top_left = (0, offset_height)
        top_right = (width, offset_height)
        bottom_left = (0, offset_height + height)
        bottom_right = (width, offset_height + height)

        shape = Polygon([
            top_left,
            top_right,
            bottom_right,
            bottom_left,
            top_left
        ])

        canvas.context.set_source_rgba(*self.color)
        CairoHelper.draw_polygon(canvas.context, shape)
        canvas.context.set_source_rgba(0.5, 0.5, 0.5, 1)
        canvas.context.fill()
Esempio n. 15
0
    def test_setters_and_getters(self):
        # Create a canvas for the sake of instantiating a layout object. We do
        # this because that is how Pango actually resolves the font dimensions.
        path = Path(__file__).parent.joinpath(
            'output/layout_setters_and_getters.svg')
        canvas_builder = CanvasBuilder()
        canvas_builder.set_path(path)
        canvas_builder.set_size(Cu.from_pt(100), Cu.from_pt(100))
        canvas = canvas_builder.build()

        layout = Layout(canvas)
        layout.set_text('Hello world')
        layout.set_markup('<span weight="bold">Hello world!</span>')

        assert layout.width is None
        assert layout.height is None
        layout.width = Cu.from_pt(100)
        layout.height = Cu.from_pt(50)
        assert layout.width.pt == 100
        assert layout.height.pt == 50
        layout.reset_width()
        layout.reset_height()
        assert layout.width is None
        assert layout.height is None

        assert layout.position.x.pt == 0
        assert layout.position.y.pt == 0
        layout.position = CanvasCoordinate(Cu.from_pt(10), Cu.from_pt(5))
        assert layout.position.x.pt == 10
        assert layout.position.y.pt == 5

        assert layout.color == (0, 0, 0, 1)
        layout.color = (0, 1, 0, 0.5)
        assert layout.color == (0, 1, 0, 0.5)

        assert layout.alignment == Alignment.LEFT
        layout.alignment = Alignment.RIGHT
        assert layout.alignment == Alignment.RIGHT

        extents = layout.logical_extents
        assert extents.pos.x.pt == 10
        assert extents.pos.y.pt == 5
        assert extents.width.pt > 1
        assert extents.height.pt > 1
Esempio n. 16
0
 def height(self) -> Optional[CanvasUnit]:
     pango_height = self._layout.get_height()
     if pango_height == -1:
         return None
     return CanvasUnit.from_pt(pangocffi.units_to_double(pango_height))
Esempio n. 17
0
 def __init__(self):
     self.geoms = []
     self.stripe_widths = [CanvasUnit.from_pt(1)]
     self.stripe_colors = [(0, 0, 0, 1)]
     self.stripe_angle = 0
     self.stripe_origin = CanvasCoordinate.origin()
 def test_pango_units_are_not_floating_point(self):
     assert CanvasUnit.from_pt(1 / 4096).pango == 0
     assert CanvasUnit.from_pt(2 / 1024 - 1 / 4096).pango == 2
     assert CanvasUnit.from_pt(2 / 1024 + 1 / 4096).pango == 2
Esempio n. 19
0
 def read_svg_size(self) -> Tuple[CanvasUnit, CanvasUnit]:
     svg_surface = SvgSurface(self.path)
     return (
         CanvasUnit.from_pt(svg_surface.svg_width),
         CanvasUnit.from_pt(svg_surface.svg_height)
     )
Esempio n. 20
0
 def __init__(self):
     self.stroke_color = (0, 0, 0, 1)
     self.stroke_width = CanvasUnit.from_pt(1)
     self.stroke_dashes = None
     self.stroke_line_cap = None
     self.stroke_line_join = None
 def test_pango_scale_is_consistent_with_library(self):
     assert CanvasUnit.from_pt(2).pango == pangocffi.units_from_double(2)
     assert CanvasUnit.from_pango(512).pt == pangocffi.units_to_double(512)
 def test_comparisons(self):
     assert CanvasUnit.from_in(1).pt > CanvasUnit.from_cm(1).pt
     assert CanvasUnit.from_cm(1).pt > CanvasUnit.from_mm(1).pt
     assert CanvasUnit.from_mm(1).pt > CanvasUnit.from_pt(1).pt
     assert CanvasUnit.from_pt(1).pt > CanvasUnit.from_px(1).pt
     assert CanvasUnit.from_px(1).pt > CanvasUnit.from_pango(1).pt
Esempio n. 23
0
 def from_pt(cls, x: float, y: float) -> 'CanvasCoordinate':
     return CanvasCoordinate(CanvasUnit.from_pt(x), CanvasUnit.from_pt(y))
Esempio n. 24
0
 def width(self) -> Optional[CanvasUnit]:
     pango_width = self._layout.get_width()
     if pango_width == -1:
         return None
     return CanvasUnit.from_pt(pangocffi.units_to_double(pango_width))