svg-ultralight 0.40.1__tar.gz → 0.41.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of svg-ultralight might be problematic. Click here for more details.
- {svg_ultralight-0.40.1/src/svg_ultralight.egg-info → svg_ultralight-0.41.0}/PKG-INFO +1 -1
- svg_ultralight-0.41.0/experiments/encode_fonts3.py +248 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/pyproject.toml +2 -2
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/font_tools/font_info.py +4 -4
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0/src/svg_ultralight.egg-info}/PKG-INFO +1 -1
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight.egg-info/SOURCES.txt +2 -1
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/.gitignore +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/.pre-commit-config.yaml +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/README.md +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/dev-requirements.txt +0 -0
- {svg_ultralight-0.40.1/src/svg_ultralight/font_tools → svg_ultralight-0.41.0/experiments}/font_css.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/setup.cfg +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/__init__.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/animate.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/bounding_boxes/__init__.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/bounding_boxes/bound_helpers.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/bounding_boxes/padded_text_initializers.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/bounding_boxes/supports_bounds.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/bounding_boxes/type_bound_collection.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/bounding_boxes/type_bound_element.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/bounding_boxes/type_bounding_box.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/bounding_boxes/type_padded_text.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/constructors/__init__.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/constructors/new_element.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/font_tools/__init__.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/font_tools/comp_results.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/font_tools/globs.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/image_ops.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/inkscape.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/layout.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/main.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/metadata.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/nsmap.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/py.typed +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/query.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/root_elements.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/string_conversion.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/strings/__init__.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/strings/svg_strings.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/transformations.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/unit_conversion.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight.egg-info/dependency_links.txt +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight.egg-info/requires.txt +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight.egg-info/top_level.txt +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/tests/__init__.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/tests/conftest.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/tests/resources/arrow.svg +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/tests/test_bounding.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/tests/test_inkscape.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/tests/test_layout.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/tests/test_matrices.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/tests/test_metadata.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/tests/test_new_element.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/tests/test_padded_text_initializers.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/tests/test_padding.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/tests/test_queries.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/tests/test_root_elements.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/tests/test_string_conversion.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/tests/test_svg_ultralight.py +0 -0
- {svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/tox.ini +0 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"""Deterministically encode a font into a base64 string for CSS.
|
|
2
|
+
|
|
3
|
+
This works fine for a browser, but there is little point. There is no way to
|
|
4
|
+
rasterize a css file with an embedded font like this. Learned some things doing it,
|
|
5
|
+
but Inkscape, Gimp, and everything else I've tried *except* a browser will ignore an
|
|
6
|
+
embedded or locally linked file in a `<style>` element.
|
|
7
|
+
|
|
8
|
+
:author: Shay Hill
|
|
9
|
+
:created: 2025-06-15
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
# pyright: reportMissingTypeStubs = false
|
|
13
|
+
# pyright: reportUnknownMemberType = false
|
|
14
|
+
# pyright: reportUnknownVariableType = false
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import cssutils
|
|
19
|
+
import base64
|
|
20
|
+
import os
|
|
21
|
+
import tempfile
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
|
|
24
|
+
from svg_ultralight.string_conversion import (
|
|
25
|
+
encode_to_css_class_name,
|
|
26
|
+
decode_from_css_class_name,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
from fontTools.subset import Subsetter
|
|
30
|
+
from fontTools.ttLib import TTFont
|
|
31
|
+
from fontTools.ttLib.woff2 import compress
|
|
32
|
+
import string
|
|
33
|
+
import warnings
|
|
34
|
+
from typing import Iterable, TYPE_CHECKING
|
|
35
|
+
|
|
36
|
+
if TYPE_CHECKING:
|
|
37
|
+
from lxml.etree import (
|
|
38
|
+
_Element as EtreeElement, # pyright: ignore[reportPrivateUsage]
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
_WESTERN_UTF8_CHAR_SETS = [
|
|
43
|
+
string.ascii_lowercase,
|
|
44
|
+
string.ascii_uppercase,
|
|
45
|
+
string.digits,
|
|
46
|
+
string.punctuation,
|
|
47
|
+
"áÁéÉíÍóÓúÚñÑäÄëËïÏöÖüÜçÇàÀèÈìÌòÒùÙâÂêÊîÎôÔûÛãÃõÕåÅæÆøØœŒßÿŸ",
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def get_robust_char_subset(
|
|
52
|
+
text: str, char_sets: Iterable[Iterable[str]] = _WESTERN_UTF8_CHAR_SETS
|
|
53
|
+
) -> str | None:
|
|
54
|
+
"""Infer a subset of characters likely to be used from a sample text.
|
|
55
|
+
|
|
56
|
+
:param text: Sample text to infer the subset from.
|
|
57
|
+
:param char_sets: List of character sets to use for inference. Each set is a
|
|
58
|
+
string of characters. The default is a list of common western UTF-8
|
|
59
|
+
character sets. Include all characters from any set that is used in the text.
|
|
60
|
+
:return: A string of characters that are likely to be used in the text. Default
|
|
61
|
+
subsets to include are lowercase, uppercase, digits, punctuation, and a set
|
|
62
|
+
of common western diacritics. Space is always included.
|
|
63
|
+
|
|
64
|
+
This function is for selecting which characters will be encoded inside a css
|
|
65
|
+
class--which is itself inside an svg file.
|
|
66
|
+
|
|
67
|
+
Fonts can be large. The smallest solution is to only encode the characters used
|
|
68
|
+
in the text, but that can be inflexible. A robust subset allows characters that
|
|
69
|
+
are similar to the text, so there is a little room to correct spelling or alter
|
|
70
|
+
the text.
|
|
71
|
+
"""
|
|
72
|
+
char_sets_ = [set(x) for x in char_sets]
|
|
73
|
+
chars_known = {" "}.union(*char_sets)
|
|
74
|
+
chars_used = set(text)
|
|
75
|
+
if chars_used - chars_known:
|
|
76
|
+
warnings.warn("Cannot create subset char sets. Returning None.")
|
|
77
|
+
return None
|
|
78
|
+
|
|
79
|
+
subset = {" "}
|
|
80
|
+
for char_set in char_sets_:
|
|
81
|
+
if chars_used & char_set:
|
|
82
|
+
subset |= char_set
|
|
83
|
+
return "".join(sorted(subset))
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def font_to_woff2(
|
|
87
|
+
font_path: str | os.PathLike[str],
|
|
88
|
+
woff2_path: str | os.PathLike[str],
|
|
89
|
+
subset: str | None = None,
|
|
90
|
+
) -> None:
|
|
91
|
+
"""Convert a (subset of a) font to woff2.
|
|
92
|
+
|
|
93
|
+
:param font_path: Path to the original font file. Ttf and otf both work, but otf
|
|
94
|
+
may show warnings (implemented as logging messages in fontTools. I have not
|
|
95
|
+
silenced these. It may be a better idea to avoid subsetting otf fonts.
|
|
96
|
+
:param woff2_path: Path to output.
|
|
97
|
+
:param subset: String of characters to include in the subset. If None, the entire
|
|
98
|
+
font is used.
|
|
99
|
+
"""
|
|
100
|
+
font = TTFont(font_path, recalcTimestamp=False)
|
|
101
|
+
font.flavor = "woff2"
|
|
102
|
+
|
|
103
|
+
if subset is not None:
|
|
104
|
+
subsetter = Subsetter()
|
|
105
|
+
unicodes = set(map(ord, subset))
|
|
106
|
+
subsetter.populate(unicodes=unicodes)
|
|
107
|
+
subsetter.subset(font)
|
|
108
|
+
|
|
109
|
+
font.save(woff2_path)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def encode_font_to_woff2_base64(
|
|
113
|
+
font_path: str | os.PathLike[str], subset: str | None = None
|
|
114
|
+
) -> str:
|
|
115
|
+
"""Encode a WOFF2 font file to a base64 string useable in CSS.
|
|
116
|
+
|
|
117
|
+
:param font_path: Path to the original font file. Ttf and otf both work, but otf
|
|
118
|
+
may show warnings (implemented as logging messages in fontTools. I have not
|
|
119
|
+
silenced these. It may be a better idea to avoid subsetting otf fonts.
|
|
120
|
+
:param subset: String of characters to include in the subset. If None, the entire
|
|
121
|
+
font is used.
|
|
122
|
+
"""
|
|
123
|
+
with tempfile.NamedTemporaryFile(suffix=".woff2", delete=False) as f:
|
|
124
|
+
woff2_path = f.name
|
|
125
|
+
with tempfile.NamedTemporaryFile(suffix=".woff2", delete=False) as f:
|
|
126
|
+
woff2_compressed = f.name
|
|
127
|
+
|
|
128
|
+
try:
|
|
129
|
+
font_to_woff2(font_path, woff2_path, subset)
|
|
130
|
+
compress(woff2_path, woff2_compressed)
|
|
131
|
+
with open(woff2_compressed, "rb") as woff2_file:
|
|
132
|
+
woff2_data = woff2_file.read()
|
|
133
|
+
return base64.b64encode(woff2_data).decode("utf-8")
|
|
134
|
+
finally:
|
|
135
|
+
os.unlink(woff2_path)
|
|
136
|
+
os.unlink(woff2_compressed)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def _find_font_file(name: str, *font_dirs: str | os.PathLike[str]) -> Path | None:
|
|
140
|
+
"""Find a font file in the given directories.
|
|
141
|
+
|
|
142
|
+
:param name: The name of the font file to find.
|
|
143
|
+
:param font_dirs: Directories to search for the font file.
|
|
144
|
+
:return: The path to the font file if found, otherwise None.
|
|
145
|
+
"""
|
|
146
|
+
if not font_dirs:
|
|
147
|
+
return None
|
|
148
|
+
for file in Path(font_dirs[0]).glob("*"):
|
|
149
|
+
if file.is_file() and file.name == name:
|
|
150
|
+
return Path(file)
|
|
151
|
+
return _find_font_file(name, *font_dirs[1:])
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def encode_local_fonts(root: EtreeElement, *font_dirs: str | os.PathLike[str]) -> None:
|
|
155
|
+
"""Encode all local fonts in the given SVG root element.
|
|
156
|
+
|
|
157
|
+
:param root: The root element of the SVG document.
|
|
158
|
+
:param font_dirs: directories to search for local fonts.
|
|
159
|
+
"""
|
|
160
|
+
font2text: dict[str, set[str]] = {}
|
|
161
|
+
for elem in root.iterdescendants("text"):
|
|
162
|
+
elem_class = elem.attrib.get("class", "")
|
|
163
|
+
if elem_class[-7:].lower() not in {"_2e_ttf", "_2e_otf"}:
|
|
164
|
+
continue
|
|
165
|
+
_ = font2text.setdefault(elem_class, set())
|
|
166
|
+
font2text[elem_class] |= set(elem.text or "")
|
|
167
|
+
|
|
168
|
+
if not font2text:
|
|
169
|
+
return
|
|
170
|
+
|
|
171
|
+
encoded: list[tuple[str, str]] = []
|
|
172
|
+
for font_class, chars in font2text.items():
|
|
173
|
+
font_name = decode_from_css_class_name(font_class)
|
|
174
|
+
font_file = _find_font_file(font_name, *font_dirs)
|
|
175
|
+
if font_file is None:
|
|
176
|
+
msg = f"Font file '{font_name}' not found in specified directories."
|
|
177
|
+
raise FileNotFoundError(msg)
|
|
178
|
+
|
|
179
|
+
base64 = encode_font_to_woff2_base64(font_file, subset="".join(chars))
|
|
180
|
+
encoded.append((font_class, base64))
|
|
181
|
+
|
|
182
|
+
style = root.find("style")
|
|
183
|
+
if style is None:
|
|
184
|
+
style = new_element("style", type="text/css")
|
|
185
|
+
root.insert(0, style)
|
|
186
|
+
css = style.text or ""
|
|
187
|
+
stylesheet = cssutils.parseString(css)
|
|
188
|
+
|
|
189
|
+
for font_class, base64 in encoded:
|
|
190
|
+
font_face_rule = cssutils.css.CSSFontFaceRule()
|
|
191
|
+
font_face_rule.style = cssutils.css.CSSStyleDeclaration()
|
|
192
|
+
font_face_rule.style["font-family"] = f'{font_class}'
|
|
193
|
+
font_face_rule.style["src"] = f"url('data:font/woff2;base64,{base64}') format('woff2')"
|
|
194
|
+
stylesheet.add(font_face_rule)
|
|
195
|
+
|
|
196
|
+
style_rule = cssutils.css.CSSStyleRule(selectorText=f".{font_class}")
|
|
197
|
+
style_rule.style = cssutils.css.CSSStyleDeclaration()
|
|
198
|
+
style_rule.style["font-family"] = f'"{font_class}"'
|
|
199
|
+
stylesheet.add(style_rule)
|
|
200
|
+
|
|
201
|
+
style.text = stylesheet.cssText.decode("utf-8")
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
from svg_ultralight.main import new_svg_root
|
|
205
|
+
from svg_ultralight.constructors import new_element, new_sub_element
|
|
206
|
+
|
|
207
|
+
root = new_svg_root(x_=0, y_=-10, width_=100, height_=100)
|
|
208
|
+
|
|
209
|
+
class_ = encode_to_css_class_name("AGENCYB.TTF")
|
|
210
|
+
for i in range(6):
|
|
211
|
+
_ = new_sub_element(root, "text", text=f"Hello World {i}", class_=class_)
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
FONTS_DIRS = [
|
|
215
|
+
Path(r"C:\Windows\Fonts"),
|
|
216
|
+
Path(r"C:\Users\shaya\AppData\Local\Microsoft\Windows\Fonts"),
|
|
217
|
+
]
|
|
218
|
+
|
|
219
|
+
encode_local_fonts(root, *FONTS_DIRS)
|
|
220
|
+
|
|
221
|
+
from svg_ultralight.main import write_svg
|
|
222
|
+
|
|
223
|
+
# _ = write_svg("temp.svg", root)
|
|
224
|
+
|
|
225
|
+
import time
|
|
226
|
+
|
|
227
|
+
# Example usage:
|
|
228
|
+
from pathlib import Path
|
|
229
|
+
import random
|
|
230
|
+
|
|
231
|
+
# input_font = str(Path("C:/Windows/Fonts/AGENCYB.TTF"))
|
|
232
|
+
# aaa = None
|
|
233
|
+
# bbb = None
|
|
234
|
+
# for i in range(10):
|
|
235
|
+
# if i % 3 == 0:
|
|
236
|
+
# chars = "".join(list(set(input_font)))
|
|
237
|
+
# elif i % 3 == 1:
|
|
238
|
+
# chars = get_robust_char_subset(input_font)
|
|
239
|
+
# else:
|
|
240
|
+
# chars = None
|
|
241
|
+
# print(chars)
|
|
242
|
+
# result = encode_woff2_to_base64(input_font, chars)
|
|
243
|
+
# bbb = result
|
|
244
|
+
# aaa = aaa or bbb
|
|
245
|
+
# print(aaa == bbb)
|
|
246
|
+
# print(len(bbb))
|
|
247
|
+
# aaa = bbb
|
|
248
|
+
# time.sleep(1) # Sleep for 1 second to avoid rapid file creation
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "svg-ultralight"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.41.0"
|
|
4
4
|
description = "a sensible way to create svg files with Python"
|
|
5
5
|
authors = [{ name = "Shay Hill", email = "shay_public@hotmail.com" }]
|
|
6
6
|
license = { text = "MIT" }
|
|
@@ -49,7 +49,7 @@ convention = "pep257"
|
|
|
49
49
|
|
|
50
50
|
[tool.commitizen]
|
|
51
51
|
name = "cz_conventional_commits"
|
|
52
|
-
version = "0.
|
|
52
|
+
version = "0.41.0"
|
|
53
53
|
tag_format = "$version"
|
|
54
54
|
version_files = ["pyproject.toml:^version"]
|
|
55
55
|
annotated_tag = true
|
|
@@ -383,7 +383,7 @@ class FTTextInfo:
|
|
|
383
383
|
@property
|
|
384
384
|
def bpad(self) -> float:
|
|
385
385
|
"""Return the bottom padding for the text."""
|
|
386
|
-
return self.descent - self.bbox.y2
|
|
386
|
+
return -self.descent - self.bbox.y2
|
|
387
387
|
|
|
388
388
|
@property
|
|
389
389
|
def lpad(self) -> float:
|
|
@@ -433,8 +433,8 @@ def get_padded_text_info(
|
|
|
433
433
|
:param font_size: the font size to use.
|
|
434
434
|
:param ascent: the ascent of the font. If not provided, it will be calculated
|
|
435
435
|
from the font file.
|
|
436
|
-
:param descent: the descent of the font
|
|
437
|
-
from the font file.
|
|
436
|
+
:param descent: the descent of the font, usually a negative number. If not
|
|
437
|
+
provided, it will be calculated from the font file.
|
|
438
438
|
:param y_bounds_reference: optional character or string to use as a reference
|
|
439
439
|
for the ascent and descent. If provided, the ascent and descent will be the y
|
|
440
440
|
extents of the capline reference. This argument is provided to mimic the
|
|
@@ -447,7 +447,7 @@ def get_padded_text_info(
|
|
|
447
447
|
if y_bounds_reference:
|
|
448
448
|
capline_info = FTTextInfo(font_info, y_bounds_reference, font_size)
|
|
449
449
|
ascent = -capline_info.bbox.y
|
|
450
|
-
descent = capline_info.bbox.y2
|
|
450
|
+
descent = -capline_info.bbox.y2
|
|
451
451
|
|
|
452
452
|
return FTTextInfo(font_info, text, font_size, ascent, descent)
|
|
453
453
|
|
|
@@ -4,6 +4,8 @@ README.md
|
|
|
4
4
|
dev-requirements.txt
|
|
5
5
|
pyproject.toml
|
|
6
6
|
tox.ini
|
|
7
|
+
experiments/encode_fonts3.py
|
|
8
|
+
experiments/font_css.py
|
|
7
9
|
src/svg_ultralight/__init__.py
|
|
8
10
|
src/svg_ultralight/animate.py
|
|
9
11
|
src/svg_ultralight/image_ops.py
|
|
@@ -35,7 +37,6 @@ src/svg_ultralight/constructors/__init__.py
|
|
|
35
37
|
src/svg_ultralight/constructors/new_element.py
|
|
36
38
|
src/svg_ultralight/font_tools/__init__.py
|
|
37
39
|
src/svg_ultralight/font_tools/comp_results.py
|
|
38
|
-
src/svg_ultralight/font_tools/font_css.py
|
|
39
40
|
src/svg_ultralight/font_tools/font_info.py
|
|
40
41
|
src/svg_ultralight/font_tools/globs.py
|
|
41
42
|
src/svg_ultralight/strings/__init__.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/bounding_boxes/__init__.py
RENAMED
|
File without changes
|
{svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/bounding_boxes/bound_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
{svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/bounding_boxes/supports_bounds.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/constructors/new_element.py
RENAMED
|
File without changes
|
|
File without changes
|
{svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight/font_tools/comp_results.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{svg_ultralight-0.40.1 → svg_ultralight-0.41.0}/src/svg_ultralight.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|