svg: use our Json SVG converter from kete

A few minor changes like passing in a filename and fixing the different
spellings of the orientations.

In order to use it from kete though we have to mess with the PYTHONPATH. But
since it's a in-tree tool only anyway... meh.

This loses the ability to disable pressure on tablets. I think that's just a
leftover from before we knew how to handle pressure in SVG exports. We should
just fix that properly instead of having a config option here.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
pull/170/head
Peter Hutterer 2019-08-14 11:07:43 +10:00
parent ac811920b8
commit 64fcf04e32
3 changed files with 22 additions and 80 deletions

View File

@ -25,11 +25,19 @@ import readline
import struct import struct
import threading import threading
import time import time
import svgwrite
import xdg.BaseDirectory import xdg.BaseDirectory
import configparser import configparser
from pathlib import Path from pathlib import Path
try:
from tuhi.svg import JsonSvg
except ModuleNotFoundError:
# If PYTHONPATH isn't set up or we never installed Tuhi, the module
# isn't available. And since we don't install kete, we can assume that
# we're still in the git repo, so messing with the path is "fine".
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '/..') # noqa
from tuhi.svg import JsonSvg
CONFIG_PATH = Path(xdg.BaseDirectory.xdg_data_home, 'tuhi-kete') CONFIG_PATH = Path(xdg.BaseDirectory.xdg_data_home, 'tuhi-kete')
@ -582,7 +590,6 @@ class Fetcher(Worker):
config[address] = {} config[address] = {}
self.orientation = config[address].get('Orientation', 'Landscape') self.orientation = config[address].get('Orientation', 'Landscape')
self.handle_pressure = config[address].getboolean('HandlePressure', False)
for d in manager.devices: for d in manager.devices:
if d.address == address: if d.address == address:
@ -614,74 +621,9 @@ class Fetcher(Worker):
t = time.localtime(data['timestamp']) t = time.localtime(data['timestamp'])
t = time.strftime('%Y-%m-%d-%H-%M', t) t = time.strftime('%Y-%m-%d-%H-%M', t)
path = f'{data["devicename"]}-{t}.svg' path = f'{data["devicename"]}-{t}.svg'
self.json_to_svg(data, path) JsonSvg(data, self.orientation, filename=path)
logger.info(f'{data["devicename"]}: saved file "{path}"') logger.info(f'{data["devicename"]}: saved file "{path}"')
def json_to_svg(self, js, filename):
dimensions = js['dimensions']
if dimensions == [0, 0]:
width, height = 100, 100
else:
# Original dimensions are too big for SVG Standard
# so we normalize them to mm
width, height = dimensions[0] / 1000, dimensions[1] / 1000
if self.orientation in ['Portrait', 'Reverse-Portrait']:
svg = svgwrite.Drawing(filename=filename, size=(height, width))
else:
svg = svgwrite.Drawing(filename=filename, size=(width, height))
g = svgwrite.container.Group(id='layer0')
for stroke_num, s in enumerate(js['strokes']):
points_with_sk_width = []
for p in s['points']:
x, y = p['position']
# Normalize coordinates too
x, y = x / 1000, y / 1000
if self.orientation == 'Reverse-Portrait':
x, y = y, width - x
elif self.orientation == 'Portrait':
x, y = height - y, x
elif self.orientation == 'Reverse-Landscape':
x, y = width - x, height - y
# Pressure normalized range is [0, 0xffff]
delta = (p['pressure'] - 0x8000) / 0x8000
stroke_width = 0.4 + 0.20 * delta
points_with_sk_width.append((x, y, stroke_width))
if self.handle_pressure:
lines = svgwrite.container.Group(id=f'strokes_{stroke_num}', stroke='black')
for i, (x, y, stroke_width) in enumerate(points_with_sk_width):
if i != 0:
xp, yp, stroke_width_p = points_with_sk_width[i - 1]
lines.add(
svg.line(
start=(xp, yp),
end=(x, y),
stroke_width=stroke_width,
style='fill:none'
)
)
else:
lines = svgwrite.path.Path(
d="M",
stroke='black',
stroke_width=0.2,
style='fill:none'
)
for x, y, stroke_width in points_with_sk_width:
lines.push(x, y)
g.add(lines)
svg.add(g)
svg.save()
class LiveChanger(Worker): class LiveChanger(Worker):
def __init__(self, manager, args): def __init__(self, manager, args):

View File

@ -14,12 +14,17 @@
from gettext import gettext as _ from gettext import gettext as _
from gi.repository import GObject, Gtk, GdkPixbuf, Gdk from gi.repository import GObject, Gtk, GdkPixbuf, Gdk
import xdg.BaseDirectory
import os
from pathlib import Path
from .config import Config from .config import Config
from tuhi.svg import JsonSvg from tuhi.svg import JsonSvg
import gi import gi
gi.require_version("Gtk", "3.0") gi.require_version("Gtk", "3.0")
DATA_PATH = Path(xdg.BaseDirectory.xdg_cache_home, 'tuhi', 'svg')
@Gtk.Template(resource_path='/org/freedesktop/Tuhi/ui/Drawing.ui') @Gtk.Template(resource_path='/org/freedesktop/Tuhi/ui/Drawing.ui')
class Drawing(Gtk.EventBox): class Drawing(Gtk.EventBox):
@ -34,6 +39,7 @@ class Drawing(Gtk.EventBox):
super().__init__() super().__init__()
self.orientation = Config.instance().orientation self.orientation = Config.instance().orientation
Config.instance().connect('notify::orientation', self._on_orientation_changed) Config.instance().connect('notify::orientation', self._on_orientation_changed)
DATA_PATH.mkdir(parents=True, exist_ok=True)
self.json_data = json_data self.json_data = json_data
self._zoom = 0 self._zoom = 0
@ -47,7 +53,8 @@ class Drawing(Gtk.EventBox):
self.refresh() self.refresh()
def refresh(self): def refresh(self):
self.svg = JsonSvg(self.json_data, self.orientation) path = os.fspath(Path(DATA_PATH, f'{self.json_data["timestamp"]}.svg'))
self.svg = JsonSvg(self.json_data, self.orientation, path)
width, height = -1, -1 width, height = -1, -1
if 'portrait' in self.orientation: if 'portrait' in self.orientation:
height = 1000 height = 1000

View File

@ -13,24 +13,17 @@
from gi.repository import GObject from gi.repository import GObject
import xdg.BaseDirectory
import svgwrite import svgwrite
import os
from pathlib import Path
from svgwrite import mm from svgwrite import mm
DATA_PATH = Path(xdg.BaseDirectory.xdg_cache_home, 'tuhi', 'svg')
class JsonSvg(GObject.Object): class JsonSvg(GObject.Object):
def __init__(self, json, orientation, *args, **kwargs): def __init__(self, json, orientation, filename, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.json = json self.json = json
DATA_PATH.mkdir(parents=True, exist_ok=True)
self.timestamp = json['timestamp'] self.timestamp = json['timestamp']
self.filename = os.fspath(Path(DATA_PATH, f'{self.timestamp}.svg')) self.filename = filename
self.orientation = orientation self.orientation = orientation.lower()
self._convert() self._convert()
def _convert(self): def _convert(self):
@ -43,7 +36,7 @@ class JsonSvg(GObject.Object):
# so we normalize them # so we normalize them
width, height = dimensions[0] / 1000, dimensions[1] / 1000 width, height = dimensions[0] / 1000, dimensions[1] / 1000
if self.orientation in ['portrait', 'reverse-Portrait']: if self.orientation in ['portrait', 'reverse-portrait']:
size = (height * mm, width * mm) size = (height * mm, width * mm)
else: else:
size = (width * mm, height * mm) size = (width * mm, height * mm)