def test_invalid_setters(self): valid_path = Path(__file__).parent.joinpath('output/valid.png') invalid_path = Path(__file__).parent.joinpath('output/invalid.wat') with self.assertRaises(RuntimeError): canvas_builder = CanvasBuilder() canvas_builder.set_size(Cu.from_mm(1), Cu.from_mm(1)) canvas_builder.set_path(invalid_path) with self.assertRaises(RuntimeError): canvas_builder = CanvasBuilder() canvas_builder.set_path(valid_path) canvas_builder.set_size(Cu.from_mm(-1), Cu.from_mm(1)) with self.assertRaises(RuntimeError): canvas_builder = CanvasBuilder() canvas_builder.set_path(valid_path) canvas_builder.set_size(Cu.from_mm(1), Cu.from_mm(-1)) with self.assertRaises(RuntimeError): canvas_builder = CanvasBuilder() canvas_builder.set_path(valid_path) canvas_builder.set_size(Cu.from_mm(1), Cu.from_mm(1)) canvas_builder.set_anti_alias_mode(-1) with self.assertRaises(RuntimeError): canvas_builder = CanvasBuilder() canvas_builder.set_path(valid_path) canvas_builder.set_size(Cu.from_mm(1), Cu.from_mm(1)) canvas_builder.set_anti_alias_mode(7)
def test_output_translate_rotate_scale(self): path = Path(__file__).parent.joinpath('output/svg_trs.svg') path.unlink(missing_ok=True) canvas_builder = CanvasBuilder() canvas_builder.set_path(path) canvas_builder.set_size( Cu.from_cm(4), Cu.from_cm(4) ) canvas = canvas_builder.build() background = Background() background.color = (0.8, 1, 0.8, 1) background.draw(canvas) svg = Svg(Path(__file__).parent.joinpath('test_svg_grid.svg')) svg_size = svg.read_svg_size() # Should set the origin of the image to the center. svg.svg_origin = Cc(svg_size[0] / 2, svg_size[1] / 2) # Should position the image in the center of the screen. svg.position = Cc.from_cm(2, 2) # Should rotate the image clock-wise. svg.rotation = math.pi / 8 # Resizes the image to almost the size of the canvas, but not exactly. svg.width = Cu.from_cm(3) svg.height = Cu.from_cm(3) svg.draw(canvas) canvas.close() assert path.exists()
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
def test_scaling_outputs(self): surface_types = [('pdf', 1), ('svg', 1), ('png', 0.5), ('png', 1), ('png', 2)] units = ['pt', 'in', 'cm', 'mm', 'px'] for (surface_type, pixel_scale_factor) in surface_types: for unit in units: canvas_builder = CanvasBuilder() # We want to test all units, but some sizes are just too big # and will take up lots of disk space. So we make an exception # for inches and centimeters. expected_size_in_unit: int expected_size: Optional[CanvasUnit] if unit in ['in', 'cm']: expected_size_in_unit = 4 expected_size = Cu.from_unit(4, unit) # Setting to a smaller size to avoid disk space issues canvas_builder.set_size(expected_size, expected_size) else: expected_size_in_unit = 100 expected_size = CanvasUnit.from_unit(100, unit) canvas_builder.set_size(expected_size, expected_size) path = Path(__file__).parent \ .joinpath( 'output/canvas_builder_%s_%d%s_x%s.%s' % ( surface_type, expected_size_in_unit, unit, pixel_scale_factor, surface_type ) ) path.unlink(missing_ok=True) canvas_builder.set_path(path) canvas_builder.set_pixel_scale_factor(pixel_scale_factor) canvas = canvas_builder.build() self.draw_rectangle_top_left(canvas, unit) canvas.close() assert path.exists() actual = self.get_file_dimensions_and_scale(path) if surface_type == 'pdf': self.assert_match(expected_size_in_unit, unit, surface_type, 1, actual, expected_size.pt) elif surface_type == 'svg': self.assert_match(expected_size_in_unit, unit, surface_type, 1, actual, expected_size.pt) elif surface_type == 'png': self.assert_match(expected_size_in_unit, unit, surface_type, pixel_scale_factor, actual, expected_size.px)
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
def test_unset_size(self): path = Path(__file__).parent.joinpath( 'output/canvas_builder_invalid_sizes.png') canvas_builder = CanvasBuilder() canvas_builder.set_path(path) with self.assertRaises(RuntimeError): canvas_builder.build() assert not path.exists()
def test_unset_paths(self): path = Path(__file__).parent.joinpath( 'invalid_output_dir/canvas_builder_invalid_path.png') canvas_builder = CanvasBuilder() canvas_builder.set_path(path) canvas_builder.set_size(Cu.from_px(100), Cu.from_px(100)) with self.assertRaises(RuntimeError): canvas_builder.build() assert not path.exists()
def test_svg(self): path = Path(__file__).parent.joinpath('output/canvas_builder.pdf') path.unlink(missing_ok=True) canvas_builder = CanvasBuilder() canvas_builder.set_path(path) canvas_builder.set_size(Cu.from_mm(100), Cu.from_mm(100)) canvas = canvas_builder.build() canvas.close() assert path.exists()
def test_validating_pixel_scale_factor(self): path = Path(__file__).parent.joinpath( 'output/canvas_builder_pixel_scale_factor.svg') canvas_builder = CanvasBuilder() canvas_builder.set_path(path) canvas_builder.set_size(Cu.from_px(100), Cu.from_px(100)) canvas_builder.set_pixel_scale_factor(2) with self.assertRaises(RuntimeError): canvas_builder.build() assert not path.exists()
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
def test_unit_scale(self): surface_types = ['png', 'svg', 'pdf'] for surface_type in surface_types: path = Path(__file__).parent\ .joinpath('output/canvas_builder_unit_scale.%s' % surface_type) path.unlink(missing_ok=True) canvas_builder = CanvasBuilder() canvas_builder.set_path(path) canvas_builder.set_size(CanvasUnit.from_in(1), CanvasUnit.from_in(1)) canvas = canvas_builder.build() UnitScale().draw(canvas) canvas.close() assert path.exists()
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%)')
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
def test_scale(self): path = Path(__file__).parent.joinpath('output/svg_scale.svg') path.unlink(missing_ok=True) canvas_builder = CanvasBuilder() canvas_builder.set_path(path) canvas_builder.set_size( Cu.from_cm(9), Cu.from_cm(6) ) canvas = canvas_builder.build() background = Background() background.color = (1, 0.8, 0.8, 1) background.draw(canvas) # No scaling svg = Svg(Path(__file__).parent.joinpath('test_svg.svg')) svg.position = Cc.from_cm(1, 1) svg.draw(canvas) # Scale 2x by height svg = Svg(Path(__file__).parent.joinpath('test_svg.svg')) svg.position = Cc.from_cm(5, 1) svg.width = Cu.from_cm(3) svg.draw(canvas) # Scale 2x by height svg = Svg(Path(__file__).parent.joinpath('test_svg.svg')) svg.position = Cc.from_cm(1, 4) svg.height = Cu.from_cm(1) svg.draw(canvas) # Scale without ratio preservation svg = Svg(Path(__file__).parent.joinpath('test_svg.svg')) svg.position = Cc.from_cm(5, 4) svg.width = Cu.from_cm(3) svg.height = Cu.from_cm(1) svg.draw(canvas) canvas.close() assert path.exists()
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 build_canvas(self, name: str) -> Canvas: name = re.sub(r'[^0-9A-Za-z_-]', '', name) path = Path(__file__).parent.joinpath( 'output/azimuthal_rendering_%s.svg' % name ) path.unlink(missing_ok=True) canvas_builder = CanvasBuilder() canvas_builder.set_path(path) canvas_builder.set_size( Cu.from_px( self.margin * 3 + self.azimuthal_width + self.wgs84_width ), Cu.from_px( self.margin * 2 + self.azimuthal_height ) ) return canvas_builder.build()
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
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