1
0
mirror of https://github.com/GNS3/gns3-server synced 2024-11-13 20:08:55 +00:00

Tune how to get the size of SVG images. Ref https://github.com/GNS3/gns3-gui/issues/2674.

* Default for missing height/width is "100%" as defined in the SVG specification
* Better error message, if viewBox attribute is missing
* Removal of "%" in percent more fault tolerant by using rstrip("%")
This commit is contained in:
grossmj 2019-01-21 16:01:03 +07:00
parent 456ef1348b
commit e3757a8955
3 changed files with 27 additions and 13 deletions

View File

@ -265,7 +265,7 @@ class Node:
try:
self._width, self._height, filetype = self._project.controller.symbols.get_size(val)
except (ValueError, OSError) as e:
log.error("Could not write symbol: {}".format(e))
log.error("Could not set symbol: {}".format(e))
# If symbol is invalid we replace it by the default
self.symbol = ":/symbols/computer.svg"
if self._label is None:

View File

@ -62,7 +62,7 @@ class SymbolHandler:
r"/symbols/{symbol_id:.+}/raw",
description="Write the symbol file",
status_codes={
200: "Symbol returned"
200: "Symbol written"
},
raw=True)
async def upload(request, response):
@ -80,6 +80,7 @@ class SymbolHandler:
f.write(chunk)
except (UnicodeEncodeError, OSError) as e:
raise aiohttp.web.HTTPConflict(text="Could not write symbol file '{}': {}".format(path, e))
# Reset the symbol list
controller.symbols.list()
response.set_status(204)

View File

@ -15,6 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import re
import io
import struct
from xml.etree.ElementTree import ElementTree, ParseError
@ -103,25 +104,34 @@ def get_size(data, default_width=0, default_height=0):
root = tree.getroot()
try:
width_attr = root.attrib.get("width", "0")
height_attr = root.attrib.get("height", "0")
width_attr = root.attrib.get("width", "100%")
height_attr = root.attrib.get("height", "100%")
if width_attr.endswith("%") or height_attr.endswith("%"):
# check to viewBox attribute if width or height value is a percentage
_, _, width_attr, height_attr = root.attrib.get("viewBox").split()
else:
width = _svg_convert_size(width_attr)
height = _svg_convert_size(height_attr)
viewbox = root.attrib.get("viewBox")
if not viewbox:
raise ValueError("Invalid SVG file: missing viewBox attribute")
_, _, viewbox_width, viewbox_height = re.split(r'[\s,]+', viewbox)
if width_attr.endswith("%"):
width = _svg_convert_size(viewbox_width, width_attr)
else:
width = _svg_convert_size(width_attr)
if height_attr.endswith("%"):
height = _svg_convert_size(viewbox_height, height_attr)
else:
height = _svg_convert_size(height_attr)
except (AttributeError, IndexError) as e:
raise ValueError("Invalid SVG file: {}".format(e))
return width, height, filetype
def _svg_convert_size(size):
def _svg_convert_size(size, percent=None):
"""
Convert svg size to the px version
:param size: String with the size
:param percent: String with the percentage, None = 100%
"""
# https://www.w3.org/TR/SVG/coords.html#Units
@ -133,8 +143,11 @@ def _svg_convert_size(size):
"in": 90,
"px": 1
}
if len(size) > 3:
factor = 1.0
if len(size) >= 3:
if size[-2:] in conversion_table:
return round(float(size[:-2]) * conversion_table[size[-2:]])
return round(float(size))
factor = conversion_table[size[-2:]]
size = size[:-2]
if percent:
factor *= float(percent.rstrip("%")) / 100.0
return round(float(size) * factor)