#!/usr/bin/python
# Written By Marcio Teixeira 2018 - Aleph Objects, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# To view a copy of the GNU General Public License, go to the following
# location: .
from __future__ import print_function
import argparse,re,sys
usage = '''
This program extracts line segments from a SVG file and writes
them as coordinates in a C array. The x and y values will be
scaled from 0x0000 to 0xFFFE. 0xFFFF is used as path separator.
This program can only interpret straight segments, not curves.
It also cannot handle SVG transform attributes. To convert an
SVG file into the proper format, use the following procedure:
- Load SVG file into Inkscape
- Convert all Objects to Paths (Path -> Object to Path)
- Convert all Strokes to Paths (Path -> Stroke to Path)
- Combine all paths into one (Path -> Combine) [1]
- Convert all curves into short line segments
(Extensions -> Modify Paths -> Flatten Beziers...)
- Save as new SVG
- Convert into a header file using this utility
- To give paths individual names, break apart paths and
use the XML Editor to set the "id" attributes.
[1] Combining paths is necessary to remove transforms. You
could also use inkscape-applytransforms Inkscape extension.
'''
header = '''
/****************************************************************************
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: . *
****************************************************************************/
/**
* This file was auto-generated using "svg2cpp.py"
*
* The encoding consists of x,y pairs with the min and max scaled to
* 0x0000 and 0xFFFE. A single 0xFFFF in the data stream indicates the
* start of a new closed path.
*/
#pragma once
'''
class ComputeBoundingBox:
def reset(self):
self.x_min = float(" inf")
self.y_min = float(" inf")
self.x_max = float("-inf")
self.y_max = float("-inf")
self.n_points = 0
self.n_paths = 0
def command(self, type, x, y):
self.x_min = min(self.x_min, x)
self.x_max = max(self.x_max, x)
self.y_min = min(self.y_min, y)
self.y_max = max(self.y_max, y)
if type == "M":
self.n_paths += 1
self.n_points += 1
def scale(self, x, y):
x -= self.x_min
y -= self.y_min
x /= self.x_max - self.x_min
y /= self.y_max - self.y_min
#y = 1 - y # Flip upside down
return (x, y)
def path_finished(self, id):
pass
def write(self):
print("constexpr float x_min = %f;" % self.x_min)
print("constexpr float x_max = %f;" % self.x_max)
print("constexpr float y_min = %f;" % self.y_min)
print("constexpr float y_max = %f;" % self.y_max)
print()
def from_svg_view_box(self, svg):
s = re.search('