aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--playground/calculate/.gitignore1
-rwxr-xr-xplayground/calculate/run.sh2
-rw-r--r--schemas_json/messages.yaml1
-rw-r--r--src_py/opcut/common.py3
-rw-r--r--src_py/opcut/main.py6
-rw-r--r--src_py/opcut/output.py192
6 files changed, 95 insertions, 110 deletions
diff --git a/playground/calculate/.gitignore b/playground/calculate/.gitignore
index 7f98a9c..70dafff 100644
--- a/playground/calculate/.gitignore
+++ b/playground/calculate/.gitignore
@@ -1,2 +1,3 @@
/result.yaml
/output.pdf
+/output.svg
diff --git a/playground/calculate/run.sh b/playground/calculate/run.sh
index b62fc9e..008fa43 100755
--- a/playground/calculate/run.sh
+++ b/playground/calculate/run.sh
@@ -1,4 +1,4 @@
#!/bin/bash
export PYTHONPATH=../../src_py
-python -m opcut.main calculate --params params.yaml --result result.yaml --output-pdf output.pdf $*
+python -m opcut.main calculate --params params.yaml --result result.yaml --output output.pdf $*
diff --git a/schemas_json/messages.yaml b/schemas_json/messages.yaml
index 7a4d210..b1a3169 100644
--- a/schemas_json/messages.yaml
+++ b/schemas_json/messages.yaml
@@ -42,6 +42,7 @@ definitions:
output_type:
enum:
- PDF
+ - SVG
panel:
type:
- "null"
diff --git a/src_py/opcut/common.py b/src_py/opcut/common.py
index 3f24109..5749a92 100644
--- a/src_py/opcut/common.py
+++ b/src_py/opcut/common.py
@@ -59,7 +59,8 @@ Method = enum.Enum('Method', [
'FORWARD_GREEDY'])
OutputType = enum.Enum('OutputType', [
- 'PDF'])
+ 'PDF',
+ 'SVG'])
class UnresolvableError(Exception):
diff --git a/src_py/opcut/main.py b/src_py/opcut/main.py
index 7e39212..b5abdfa 100644
--- a/src_py/opcut/main.py
+++ b/src_py/opcut/main.py
@@ -83,7 +83,8 @@ def output(args):
result_json_data = yaml.safe_load(f)
opcut.json_validator.validate(result_json_data, 'opcut://result.yaml#')
result = common.json_data_to_result(result_json_data)
- output_bytes = opcut.output.generate_output(result, args.output_type,
+ output_type = common.OutputType[args.output_type]
+ output_bytes = opcut.output.generate_output(result, output_type,
args.output_panel_id)
with open(args.output_path, 'wb') as f:
f.write(output_bytes)
@@ -130,8 +131,7 @@ def _create_parser():
help="calculate result file path "
"(specified by opcut://result.yaml#)")
p.add_argument(
- '--output-type', dest='output_type', type=common.OutputType,
- default=common.OutputType.PDF,
+ '--output-type', dest='output_type', default='PDF',
choices=list(map(lambda x: x.name, common.OutputType)),
help="output type (default PDF)")
p.add_argument(
diff --git a/src_py/opcut/output.py b/src_py/opcut/output.py
index a66b90f..53bbe7a 100644
--- a/src_py/opcut/output.py
+++ b/src_py/opcut/output.py
@@ -20,111 +20,93 @@ def generate_output(result, output_type, panel_id=None,
"""
ret = io.BytesIO()
- with cairo.PDFSurface(ret, settings.pagesize[0],
- settings.pagesize[1]) as surface:
- ctx = cairo.Context(surface)
- # TODO
+ surface_cls = {common.OutputType.PDF: cairo.PDFSurface,
+ common.OutputType.SVG: cairo.SVGSurface}[output_type]
+ with surface_cls(ret, settings.pagesize[0],
+ settings.pagesize[1]) as surface:
+ for panel in result.params.panels:
+ if panel_id and panel.id != panel_id:
+ continue
+ _write_panel(surface, settings, result, panel)
+ surface.show_page()
return ret.getvalue()
-# def generate_pdf(result, pagesize_mm=(210, 297),
-# margin_top_mm=10, margin_bottom_mm=20,
-# margin_left_mm=10, margin_right_mm=10):
-# """Generate PDF output
-#
-# Args:
-# result (opcut.common.Result): result
-# pagesize (Tuple[float,float]): page size as (with, height) in mm
-# margin_top_mm (float): margin top in mm
-# margin_bottom_mm (float): margin bottom in mm
-# margin_left_mm (float): margin left in mm
-# margin_right_mm (float): margin right in mm
-#
-# Returns:
-# bytes
-#
-# """
-# pagesize = tuple(map(lambda x: x * mm, pagesize_mm))
-# margin = _Margin(top=margin_top_mm * mm,
-# right=margin_right_mm * mm,
-# bottom=margin_bottom_mm * mm,
-# left=margin_left_mm * mm)
-# ret = io.BytesIO()
-# c = canvas.Canvas(ret, pagesize=pagesize)
-# c.setFillColorRGB(0.9, 0.9, 0.9)
-# for panel in result.params.panels:
-# _pdf_write_panel(c, pagesize, margin, result, panel)
-# c.save()
-# return ret.getvalue()
-#
-#
-# def generate_csv(result):
-# """Generate CSV output
-#
-# Args:
-# result (opcut.common.Result): result
-#
-# Returns:
-# bytes
-#
-# """
-# return b''
-#
-#
-# _Margin = util.namedtuple('_Margin', 'top', 'right', 'bottom', 'left')
-#
-#
-# def _pdf_write_panel(c, pagesize, margin, result, panel):
-# if (panel.width / panel.height >
-# (pagesize[0] - margin.left - margin.right) /
-# (pagesize[1] - margin.top - margin.bottom)):
-# scale = (
-# (pagesize[0] - (margin.left + margin.right) * mm) /
-# panel.width)
-# else:
-# scale = (
-# (pagesize[1] - (margin.top + margin.bottom) * mm) /
-# panel.height)
-# width = panel.width * scale
-# height = panel.height * scale
-# x0 = ((pagesize[0] - width) * margin.left /
-# (margin.left + margin.right))
-# y0 = ((pagesize[1] - height) * margin.bottom /
-# (margin.top + margin.bottom))
-# c.setFillColorRGB(0.5, 0.5, 0.5)
-# c.rect(x0, y0, width, height, stroke=1, fill=1)
-# for used in result.used:
-# if used.panel != panel:
-# continue
-# _pdf_write_used(c, x0, y0, scale, result, used)
-# for unused in result.unused:
-# if unused.panel != panel:
-# continue
-# _pdf_write_unused(c, x0, y0, scale, result, unused)
-# c.setFillColorRGB(0, 0, 0)
-# c.drawCentredString(pagesize[0] / 2, margin.bottom / 2,
-# panel.id)
-# c.showPage()
-#
-#
-# def _pdf_write_used(c, x0, y0, scale, result, used):
-# width = used.item.width * scale
-# height = used.item.height * scale
-# if used.rotate:
-# width, height = height, width
-# x = used.x * scale + x0
-# y = (used.panel.height - used.y) * scale + y0 - height
-# c.setFillColorRGB(1, 1, 1)
-# c.rect(x, y, width, height, stroke=0, fill=1)
-# c.setFillColorRGB(0, 0, 0)
-# c.drawCentredString(x + width / 2, y + height / 2 - 6, used.item.id)
-#
-#
-# def _pdf_write_unused(c, x0, y0, scale, result, unused):
-# width = unused.width * scale
-# height = unused.height * scale
-# x = unused.x * scale + x0
-# y = (unused.panel.height - unused.y) * scale + y0 - height
-# c.setFillColorRGB(0.9, 0.9, 0.9)
-# c.rect(x, y, width, height, stroke=0, fill=1)
-#
+def _write_panel(surface, settings, result, panel):
+ scale = _calculate_scale(settings, panel)
+ width = panel.width * scale
+ height = panel.height * scale
+ x0 = ((settings.pagesize[0] - width) * settings.margin_left /
+ (settings.margin_left + settings.margin_right))
+ y0 = ((settings.pagesize[1] - height) * settings.margin_top /
+ (settings.margin_top + settings.margin_bottom))
+
+ ctx = cairo.Context(surface)
+ ctx.set_line_width(0)
+ ctx.set_source_rgb(0.5, 0.5, 0.5)
+ ctx.rectangle(x0, y0, width, height)
+ ctx.fill()
+
+ for used in result.used:
+ if used.panel != panel:
+ continue
+ _write_used(surface, scale, x0, y0, used)
+
+ for unused in result.unused:
+ if unused.panel != panel:
+ continue
+ _write_unused(surface, scale, x0, y0, unused)
+
+ _write_centered_text(surface, settings.pagesize[0] / 2,
+ settings.pagesize[1] - settings.margin_bottom / 2,
+ panel.id)
+
+
+def _write_used(surface, scale, x0, y0, used):
+ width = used.item.width * scale
+ height = used.item.height * scale
+ if used.rotate:
+ width, height = height, width
+ x = x0 + used.x * scale
+ y = y0 + used.y * scale
+
+ ctx = cairo.Context(surface)
+ ctx.set_line_width(0)
+ ctx.set_source_rgb(0.9, 0.9, 0.9)
+ ctx.rectangle(x, y, width, height)
+ ctx.fill()
+
+ _write_centered_text(surface, x + width / 2, y + height / 2, used.item.id)
+
+
+def _write_unused(surface, scale, x0, y0, unused):
+ width = unused.width * scale
+ height = unused.height * scale
+ x = x0 + unused.x * scale
+ y = y0 + unused.y * scale
+
+ ctx = cairo.Context(surface)
+ ctx.set_line_width(0)
+ ctx.set_source_rgb(0.7, 0.7, 0.7)
+ ctx.rectangle(x, y, width, height)
+ ctx.fill()
+
+
+def _write_centered_text(surface, x, y, text):
+ ctx = cairo.Context(surface)
+ ctx.set_source_rgb(0, 0, 0)
+ text_ext = ctx.text_extents(text)
+ ctx.move_to(x - text_ext.width / 2,
+ y + text_ext.height / 2)
+ ctx.show_text(text)
+
+
+def _calculate_scale(settings, panel):
+ page_width = (settings.pagesize[0] - settings.margin_left -
+ settings.margin_right)
+ page_height = (settings.pagesize[1] - settings.margin_top -
+ settings.margin_bottom)
+ page_ratio = page_width / page_height
+ panel_ratio = panel.width / panel.height
+ return (page_width / panel.width if panel_ratio > page_ratio
+ else page_height / panel.height)