Skip to content

Commit 294669d

Browse files
committed
Create SvgImage and tests, update license
1 parent 02cf680 commit 294669d

File tree

5 files changed

+120
-11
lines changed

5 files changed

+120
-11
lines changed

LICENSE.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Tcl License
2+
```
3+
Copyright (C) 2002-2004 Maxim Shemanarev http://antigrain.com
4+
Copyright (c) 2013-14 Mikko Mononen [email protected]
5+
Copyright (c) 2018 Christian Gollwitzer [email protected]
6+
Copyright (c) 2018 Christian Werner https://www.androwish.org/
7+
Copyright (c) 2018 Rene Zaumseil [email protected]
8+
Copyright (c) 2020 Juliette Monsel
9+
Copyright (c) 2021 RedFantom <[email protected]>
10+
11+
The authors hereby grant permission to use, copy, modify, distribute,
12+
and license this software and its documentation for any purpose, provided
13+
that existing copyright notices are retained in all copies and that this
14+
notice is included verbatim in any distributions. No written agreement,
15+
license, or royalty fee is required for any of the authorized uses.
16+
Modifications to this software may be copyrighted by their authors
17+
and need not follow the licensing terms described here, provided that
18+
the new terms are clearly indicated on the first page of each file where
19+
they apply.
20+
21+
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
22+
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
23+
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
24+
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
25+
POSSIBILITY OF SUCH DAMAGE.
26+
27+
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
28+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
29+
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
30+
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
31+
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
32+
MODIFICATIONS.
33+
34+
GOVERNMENT USE: If you are acquiring this software on behalf of the
35+
U.S. government, the Government shall have only "Restricted Rights"
36+
in the software and related documentation as defined in the Federal
37+
Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
38+
are acquiring the software on behalf of the Department of Defense, the
39+
software shall be classified as "Commercial Computer Software" and the
40+
Government shall have only "Restricted Rights" as defined in Clause
41+
252.227-7014 (b) (3) of DFARs. Notwithstanding the foregoing, the
42+
authors grant the U.S. Government and others acting in its behalf
43+
permission to use and distribute the software in accordance with the
44+
terms specified in this license.
45+
```
46+

README.md

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
1-
tksvg
2-
======
1+
# tksvg for Python's Tkinter
2+
[tksvg](https://github.com/oehhar/tksvg) is a package for Tcl/Tk that
3+
adds support for SVG image files. Tkinter makes use of Tcl/Tk under the
4+
hood, and thus can benefit from this addition. Note that SVG support
5+
has been included in Tk 8.7 and thus this package can be made obsolete
6+
in the future when Python gets distributed with Tk 8.7.
37

4-
This package adds support to read the SVG image format from Tk.
5-
The actual code to parse and raster the SVG comes from nanosvg.
68

7-
Example usage:
8-
9-
package require tksvg
10-
set img [image create photo -file orb.svg]
11-
pack [label .l -image $img]
12-

generic/tkImgSVG.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Copyright (c) 2018 Christian Werner https://www.androwish.org/
99
* Copyright (c) 2018 Rene Zaumseil [email protected]
1010
*
11-
* See the file "license.terms" for information on usage and redistribution of
11+
* See the file "LICENSE.md" for information on usage and redistribution of
1212
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
1313
*
1414
* This handler is build using the original nanosvg library files from

tests/test_tksvg.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,16 @@ def test_tksvg_load(self):
1616
tksvg.load(self.window)
1717
# Create test PhotoImage
1818
tk.PhotoImage(file="tests/orb.svg")
19+
20+
def test_svg_image(self):
21+
tksvg.load(self.window)
22+
image = tksvg.SvgImage(file="tests/orb.svg", scale=0.5)
23+
self.assertEqual(image.cget("scale"), 0.5)
24+
self.assertEqual(image.cget("scale"), image["scale"])
25+
26+
label = tk.Label(self.window, image=image)
27+
label.pack()
28+
self.window.update()
29+
30+
def tearDown(self):
31+
self.window.destroy()

tksvg/__init__.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,57 @@ def load(window: tk.Tk):
2424
with chdir(local):
2525
window.tk.eval("source pkgIndex.tcl")
2626
window.tk.eval("package require tksvg")
27+
window._tksvg_loaded = True
28+
29+
30+
class SvgImage(tk.PhotoImage):
31+
"""
32+
Sub-class of tk.PhotoImage with support for SVG image options
33+
34+
tksvg provides some options to control the rastering of SVG images.
35+
These are accessible when the images is created with this class.
36+
37+
This implementation is inspired by GitHub @j4321:
38+
<https://stackoverflow.com/a/64829808>
39+
"""
40+
_tksvg_loaded = False
41+
_svg_options = [("scale", float), ("scaletowidth", int), ("scaletoheight", int)]
42+
43+
def __init__(self, name=None, cnf={}, master=None, **kwargs):
44+
self._svg_options_current = dict()
45+
# Load TkSVG package if not yet loaded
46+
master = master or tk._default_root
47+
if master is None:
48+
raise tk.TclError("No Tk instance available to get interpreter from")
49+
if not getattr(master, "_tksvg_loaded", False) and not self._tksvg_loaded:
50+
load(master)
51+
self._tksvg_loaded = True
52+
# Pop SvgImage keyword arguments
53+
svg_options = {key: t(kwargs.pop(key)) for (key, t) in self._svg_options if key in kwargs}
54+
# Initialize as a PhotoImage
55+
tk.PhotoImage.__init__(self, name, cnf, master, **kwargs)
56+
self.configure(**svg_options)
57+
58+
def configure(self, **kwargs):
59+
"""Configure the image with SVG options and pass to PhotoImage.configure"""
60+
svg_options = {key: t(kwargs.pop(key)) for (key, t) in self._svg_options if key in kwargs}
61+
if kwargs: # len(kwargs) > 0
62+
tk.PhotoImage.configure(self, **kwargs)
63+
options = tuple()
64+
for key, value in svg_options.items():
65+
if value is not None:
66+
options += ("-"+key, str(value))
67+
self.tk.eval("%s configure -format {svg %s}" % (self.name, " ".join(options)))
68+
self._svg_options_current.update(svg_options)
69+
70+
def cget(self, option):
71+
"""Return the option set for an SVG property or pass to PhotoImage.cget"""
72+
if option in (k for k, _ in self._svg_options):
73+
return self._svg_options_current.get(option, None)
74+
return tk.PhotoImage.cget(self, option)
75+
76+
def __getitem__(self, key):
77+
return self.cget(key)
78+
79+
def __setitem__(self, key, value):
80+
return self.configure(**{key: value})

0 commit comments

Comments
 (0)