kaxe 1.4.4.dev4__tar.gz → 1.4.4.dev5__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.
- {kaxe-1.4.4.dev4/src/kaxe.egg-info → kaxe-1.4.4.dev5}/PKG-INFO +2 -1
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/pyproject.toml +2 -2
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/svg_pdf.py +250 -40
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5/src/kaxe.egg-info}/PKG-INFO +2 -1
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe.egg-info/requires.txt +1 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/LICENSE +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/MANIFEST.in +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/README.md +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/setup.cfg +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/__init__.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/chart/__init__.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/chart/bar.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/chart/box.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/chart/pie.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/chart/qqplot.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/__init__.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/axis.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/color.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/d3/backend.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/d3/camera.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/d3/helper.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/d3/hud.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/d3/objects/__init__.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/d3/objects/color.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/d3/objects/line.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/d3/objects/point.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/d3/objects/pointer.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/d3/objects/triangle.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/d3/openglrender.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/d3/translator.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/draw.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/fileloader.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/helper.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/legend.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/line.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/marker.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/profiler.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/round.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/shapes.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/styles.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/svg.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/symbol.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/text.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/core/window.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/data/__init__.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/data/excel.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/__init__.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/_lazy.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/d2/__init__.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/d2/arrow.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/d2/bubble.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/d2/contour.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/d2/equation.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/d2/fill.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/d2/function.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/d2/map.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/d2/parameter.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/d2/pillar.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/d2/point.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/d3/__init__.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/d3/base.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/d3/function.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/d3/mesh.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/d3/point.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/d3/potato.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/function.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/legend.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/mapdata.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/point.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/objects/text.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/plot/__init__.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/plot/_lazy.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/plot/box.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/plot/constants.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/plot/d3/__init__.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/plot/d3/axes.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/plot/d3/geometry.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/plot/d3/plot3d.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/plot/d3/variants.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/plot/double.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/plot/empty.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/plot/grid.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/plot/log.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/plot/polar.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/plot/standard.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/plot/themes.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/plot/zoom.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/plot/zoom_connector.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/__init__.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/__init__.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.bright-oblique.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.bright-roman.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.bright-semibold.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.bright-semiboldoblique.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.classical-serif-italic.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.concrete-bold.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.concrete-bolditalic.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.concrete-italic.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.concrete-roman.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-bold.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-boldoblique.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-demi-condensed-demicondensed.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-medium.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-oblique.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.serif-bold.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.serif-bolditalic.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.serif-extra-boldslanted.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.serif-extra-romanslanted.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.serif-italic.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.serif-roman.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.serif-upright-italic-uprightitalic.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-bold.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-bolditalic.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-italic.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-light.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-lightoblique.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-regular.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-variable-width-italic.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-variable-width-medium.ttf +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/readme.txt +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/logo-small.png +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/symbolcross.png +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/symboldonut.png +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/symbollollipop.png +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/symboltriangle.png +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe.egg-info/SOURCES.txt +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe.egg-info/dependency_links.txt +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe.egg-info/top_level.txt +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/tests/test.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/tests/test2.py +0 -0
- {kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/tests/test3.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kaxe
|
|
3
|
-
Version: 1.4.4.
|
|
3
|
+
Version: 1.4.4.dev5
|
|
4
4
|
Summary: A small graphing tool for functions, points, equations and more
|
|
5
5
|
Author-email: Valter Yde Daugberg <valteryde@hotmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/valteryde/kaxe
|
|
@@ -27,6 +27,7 @@ Requires-Dist: psutil
|
|
|
27
27
|
Requires-Dist: opencv-python-headless
|
|
28
28
|
Provides-Extra: pdf
|
|
29
29
|
Requires-Dist: reportlab>=4.0; extra == "pdf"
|
|
30
|
+
Requires-Dist: fonttools>=4.0; extra == "pdf"
|
|
30
31
|
Dynamic: license-file
|
|
31
32
|
|
|
32
33
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "kaxe"
|
|
3
|
-
version = "1.4.4.
|
|
3
|
+
version = "1.4.4.dev5"
|
|
4
4
|
authors = [
|
|
5
5
|
{ name="Valter Yde Daugberg", email="valteryde@hotmail.com" },
|
|
6
6
|
]
|
|
@@ -30,7 +30,7 @@ dependencies = [
|
|
|
30
30
|
]
|
|
31
31
|
|
|
32
32
|
[project.optional-dependencies]
|
|
33
|
-
pdf = ["reportlab>=4.0"]
|
|
33
|
+
pdf = ["reportlab>=4.0", "fonttools>=4.0"]
|
|
34
34
|
|
|
35
35
|
[project.urls]
|
|
36
36
|
Homepage = "https://github.com/valteryde/kaxe"
|
|
@@ -21,6 +21,7 @@ if TYPE_CHECKING:
|
|
|
21
21
|
|
|
22
22
|
_PDF_INSTALL_HINT = "PDF export requires reportlab. Install with: pip install kaxe[pdf]"
|
|
23
23
|
_FONDI_FONTS_REGISTERED = False
|
|
24
|
+
_OTF_TTF_CACHE: dict[str, bytes] = {}
|
|
24
25
|
|
|
25
26
|
_TRANSFORM_RE = re.compile(
|
|
26
27
|
r"(translate|rotate|matrix)\s*\(([^)]*)\)"
|
|
@@ -71,6 +72,90 @@ def _rl_color(value: Optional[str], opacity: Optional[str] = None):
|
|
|
71
72
|
return Color(r / 255.0, g / 255.0, b / 255.0, alpha=alpha)
|
|
72
73
|
|
|
73
74
|
|
|
75
|
+
def _require_fonttools():
|
|
76
|
+
try:
|
|
77
|
+
import fontTools # noqa: F401
|
|
78
|
+
except ImportError as exc:
|
|
79
|
+
raise ImportError(
|
|
80
|
+
"PDF font embedding requires fonttools. Install with: pip install kaxe[pdf]"
|
|
81
|
+
) from exc
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def _convert_otf_to_ttf_bytes(otf_path: os.PathLike[str]) -> bytes:
|
|
85
|
+
path = os.fspath(otf_path)
|
|
86
|
+
cached = _OTF_TTF_CACHE.get(path)
|
|
87
|
+
if cached is not None:
|
|
88
|
+
return cached
|
|
89
|
+
|
|
90
|
+
_require_fonttools()
|
|
91
|
+
from fontTools.pens.cu2quPen import Cu2QuPen
|
|
92
|
+
from fontTools.pens.ttGlyphPen import TTGlyphPen
|
|
93
|
+
from fontTools.ttLib import TTFont, newTable
|
|
94
|
+
|
|
95
|
+
def _glyphs_to_quadratic(glyphs):
|
|
96
|
+
quad: dict = {}
|
|
97
|
+
for gname in glyphs.keys():
|
|
98
|
+
tt_pen = TTGlyphPen(glyphs)
|
|
99
|
+
cu2qu_pen = Cu2QuPen(tt_pen, 1.0, reverse_direction=True)
|
|
100
|
+
glyphs[gname].draw(cu2qu_pen)
|
|
101
|
+
quad[gname] = tt_pen.glyph()
|
|
102
|
+
return quad
|
|
103
|
+
|
|
104
|
+
font = TTFont(path)
|
|
105
|
+
if font.sfntVersion != "OTTO" or "CFF " not in font:
|
|
106
|
+
buf = io.BytesIO()
|
|
107
|
+
font.save(buf)
|
|
108
|
+
data = buf.getvalue()
|
|
109
|
+
_OTF_TTF_CACHE[path] = data
|
|
110
|
+
return data
|
|
111
|
+
|
|
112
|
+
glyph_order = font.getGlyphOrder()
|
|
113
|
+
font["loca"] = newTable("loca")
|
|
114
|
+
glyf = newTable("glyf")
|
|
115
|
+
glyf.glyphOrder = glyph_order
|
|
116
|
+
glyf.glyphs = _glyphs_to_quadratic(font.getGlyphSet())
|
|
117
|
+
font["glyf"] = glyf
|
|
118
|
+
del font["CFF "]
|
|
119
|
+
glyf.compile(font)
|
|
120
|
+
|
|
121
|
+
hmtx = font["hmtx"]
|
|
122
|
+
for glyph_name, glyph in glyf.glyphs.items():
|
|
123
|
+
if hasattr(glyph, "xMin"):
|
|
124
|
+
hmtx[glyph_name] = (hmtx[glyph_name][0], glyph.xMin)
|
|
125
|
+
|
|
126
|
+
maxp = newTable("maxp")
|
|
127
|
+
maxp.tableVersion = 0x00010000
|
|
128
|
+
maxp.maxZones = 1
|
|
129
|
+
maxp.maxTwilightPoints = 0
|
|
130
|
+
maxp.maxStorage = 0
|
|
131
|
+
maxp.maxFunctionDefs = 0
|
|
132
|
+
maxp.maxInstructionDefs = 0
|
|
133
|
+
maxp.maxStackElements = 0
|
|
134
|
+
maxp.maxSizeOfInstructions = 0
|
|
135
|
+
maxp.maxComponentElements = max(
|
|
136
|
+
len(g.components if hasattr(g, "components") else [])
|
|
137
|
+
for g in glyf.glyphs.values()
|
|
138
|
+
)
|
|
139
|
+
maxp.compile(font)
|
|
140
|
+
|
|
141
|
+
post = font["post"]
|
|
142
|
+
post.formatType = 2.0
|
|
143
|
+
post.extraNames = []
|
|
144
|
+
post.mapping = {}
|
|
145
|
+
post.glyphOrder = glyph_order
|
|
146
|
+
try:
|
|
147
|
+
post.compile(font)
|
|
148
|
+
except OverflowError:
|
|
149
|
+
post.formatType = 3
|
|
150
|
+
|
|
151
|
+
font.sfntVersion = "\000\001\000\000"
|
|
152
|
+
buf = io.BytesIO()
|
|
153
|
+
font.save(buf)
|
|
154
|
+
data = buf.getvalue()
|
|
155
|
+
_OTF_TTF_CACHE[path] = data
|
|
156
|
+
return data
|
|
157
|
+
|
|
158
|
+
|
|
74
159
|
def _register_fondi_fonts() -> None:
|
|
75
160
|
global _FONDI_FONTS_REGISTERED
|
|
76
161
|
if _FONDI_FONTS_REGISTERED:
|
|
@@ -83,22 +168,49 @@ def _register_fondi_fonts() -> None:
|
|
|
83
168
|
from reportlab.pdfbase.ttfonts import TTFont
|
|
84
169
|
|
|
85
170
|
resources = Path(fondi.__file__).parent / "resources"
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
171
|
+
regular_otf = resources / "NewCM10-Regular.otf"
|
|
172
|
+
italic_otf = resources / "NewCM10-Italic.otf"
|
|
173
|
+
fallback_ttf = resources / "cmu.serif-roman.ttf"
|
|
174
|
+
|
|
175
|
+
def _register(name: str, otf: Path, ttf_fallback: Optional[Path] = None) -> bool:
|
|
176
|
+
for candidate in (otf, ttf_fallback):
|
|
177
|
+
if not candidate or not candidate.is_file():
|
|
178
|
+
continue
|
|
179
|
+
try:
|
|
180
|
+
if candidate.suffix.lower() == ".otf":
|
|
181
|
+
data = _convert_otf_to_ttf_bytes(candidate)
|
|
182
|
+
else:
|
|
183
|
+
data = candidate.read_bytes()
|
|
184
|
+
pdfmetrics.registerFont(TTFont(name, io.BytesIO(data)))
|
|
185
|
+
return True
|
|
186
|
+
except Exception as exc:
|
|
187
|
+
logging.warning("Could not register PDF font %s from %s: %s", name, candidate, exc)
|
|
188
|
+
return False
|
|
189
|
+
|
|
190
|
+
if not _register("FondiNewCM", regular_otf, fallback_ttf):
|
|
191
|
+
logging.warning("Fondi regular font unavailable; PDF math labels will use Helvetica")
|
|
89
192
|
_FONDI_FONTS_REGISTERED = True
|
|
90
193
|
return
|
|
91
194
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
195
|
+
if _register("FondiNewCM-Italic", italic_otf):
|
|
196
|
+
pdfmetrics.registerFontFamily(
|
|
197
|
+
"FondiNewCM",
|
|
198
|
+
normal="FondiNewCM",
|
|
199
|
+
italic="FondiNewCM-Italic",
|
|
200
|
+
)
|
|
201
|
+
else:
|
|
202
|
+
pdfmetrics.registerFontFamily(
|
|
203
|
+
"FondiNewCM",
|
|
204
|
+
normal="FondiNewCM",
|
|
205
|
+
italic="FondiNewCM",
|
|
206
|
+
)
|
|
207
|
+
|
|
98
208
|
_FONDI_FONTS_REGISTERED = True
|
|
99
209
|
|
|
100
210
|
|
|
101
211
|
def _resolve_font_name(family: Optional[str], style: Optional[str]) -> str:
|
|
212
|
+
if family == "FondiNewCM" and style == "italic":
|
|
213
|
+
return "FondiNewCM-Italic"
|
|
102
214
|
if family == "FondiNewCM":
|
|
103
215
|
return "FondiNewCM"
|
|
104
216
|
if family:
|
|
@@ -132,6 +244,31 @@ class _Matrix:
|
|
|
132
244
|
)
|
|
133
245
|
|
|
134
246
|
|
|
247
|
+
def _is_identity(matrix: _Matrix, tol: float = 1e-9) -> bool:
|
|
248
|
+
return (
|
|
249
|
+
abs(matrix.a - 1.0) < tol
|
|
250
|
+
and abs(matrix.d - 1.0) < tol
|
|
251
|
+
and abs(matrix.b) < tol
|
|
252
|
+
and abs(matrix.c) < tol
|
|
253
|
+
and abs(matrix.e) < tol
|
|
254
|
+
and abs(matrix.f) < tol
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def _matrix_to_reportlab_transform(matrix: _Matrix, height: int, *, nested: bool) -> list[float]:
|
|
259
|
+
"""Map SVG-local y-down coords to ReportLab parent coords via Group.transform."""
|
|
260
|
+
# Conjugate y-down SVG affine with flip-to-y-up: T(height) * M * F, F:(x,y)->(x,-y)
|
|
261
|
+
f = height if not nested else 0.0
|
|
262
|
+
return [
|
|
263
|
+
matrix.a,
|
|
264
|
+
-matrix.b,
|
|
265
|
+
-matrix.c,
|
|
266
|
+
matrix.d,
|
|
267
|
+
matrix.e,
|
|
268
|
+
f + matrix.f,
|
|
269
|
+
]
|
|
270
|
+
|
|
271
|
+
|
|
135
272
|
def _parse_transform(transform: Optional[str]) -> _Matrix:
|
|
136
273
|
matrix = _Matrix()
|
|
137
274
|
if not transform:
|
|
@@ -178,14 +315,29 @@ class _PdfBuilder:
|
|
|
178
315
|
self.drawing = Drawing(width, height)
|
|
179
316
|
self._shapes: list[Any] = []
|
|
180
317
|
|
|
181
|
-
def _to_rl(
|
|
318
|
+
def _to_rl(
|
|
319
|
+
self,
|
|
320
|
+
matrix: _Matrix,
|
|
321
|
+
x: float,
|
|
322
|
+
y: float,
|
|
323
|
+
*,
|
|
324
|
+
local: bool = False,
|
|
325
|
+
) -> tuple[float, float]:
|
|
326
|
+
if local:
|
|
327
|
+
return x, -y
|
|
182
328
|
sx, sy = matrix.map_point(x, y)
|
|
183
329
|
return sx, self.height - sy
|
|
184
330
|
|
|
185
331
|
def _add(self, shape) -> None:
|
|
186
332
|
self._shapes.append(shape)
|
|
187
333
|
|
|
188
|
-
def _render_element(
|
|
334
|
+
def _render_element(
|
|
335
|
+
self,
|
|
336
|
+
el: ET.Element,
|
|
337
|
+
matrix: _Matrix,
|
|
338
|
+
*,
|
|
339
|
+
local: bool = False,
|
|
340
|
+
) -> None:
|
|
189
341
|
from reportlab.graphics.shapes import (
|
|
190
342
|
Circle,
|
|
191
343
|
Group,
|
|
@@ -203,13 +355,28 @@ class _PdfBuilder:
|
|
|
203
355
|
opacity = _attr(el, "opacity")
|
|
204
356
|
|
|
205
357
|
if tag == "g":
|
|
206
|
-
|
|
358
|
+
local_transform = _parse_transform(_attr(el, "transform"))
|
|
359
|
+
if _is_identity(local_transform):
|
|
360
|
+
for child in el:
|
|
361
|
+
self._render_element(
|
|
362
|
+
child,
|
|
363
|
+
matrix.multiply(local_transform),
|
|
364
|
+
local=local,
|
|
365
|
+
)
|
|
366
|
+
return
|
|
367
|
+
|
|
368
|
+
combined = matrix.multiply(local_transform)
|
|
207
369
|
group = Group()
|
|
370
|
+
group.transform = _matrix_to_reportlab_transform(
|
|
371
|
+
combined if not local else local_transform,
|
|
372
|
+
self.height,
|
|
373
|
+
nested=local,
|
|
374
|
+
)
|
|
208
375
|
child_shapes: list[Any] = []
|
|
209
376
|
saved = self._shapes
|
|
210
377
|
self._shapes = child_shapes
|
|
211
378
|
for child in el:
|
|
212
|
-
self._render_element(child,
|
|
379
|
+
self._render_element(child, _Matrix(), local=True)
|
|
213
380
|
self._shapes = saved
|
|
214
381
|
for shape in child_shapes:
|
|
215
382
|
group.add(shape)
|
|
@@ -222,8 +389,8 @@ class _PdfBuilder:
|
|
|
222
389
|
y = _parse_float(_attr(el, "y"))
|
|
223
390
|
w = _parse_float(_attr(el, "width"))
|
|
224
391
|
h = _parse_float(_attr(el, "height"))
|
|
225
|
-
x0, y0 = self._to_rl(matrix, x, y)
|
|
226
|
-
x1, y1 = self._to_rl(matrix, x + w, y + h)
|
|
392
|
+
x0, y0 = self._to_rl(matrix, x, y, local=local)
|
|
393
|
+
x1, y1 = self._to_rl(matrix, x + w, y + h, local=local)
|
|
227
394
|
rect = Rect(
|
|
228
395
|
min(x0, x1),
|
|
229
396
|
min(y0, y1),
|
|
@@ -236,15 +403,15 @@ class _PdfBuilder:
|
|
|
236
403
|
return
|
|
237
404
|
|
|
238
405
|
if tag == "line":
|
|
239
|
-
x1, y1 = self._to_rl(matrix, _parse_float(_attr(el, "x1")), _parse_float(_attr(el, "y1")))
|
|
240
|
-
x2, y2 = self._to_rl(matrix, _parse_float(_attr(el, "x2")), _parse_float(_attr(el, "y2")))
|
|
406
|
+
x1, y1 = self._to_rl(matrix, _parse_float(_attr(el, "x1")), _parse_float(_attr(el, "y1")), local=local)
|
|
407
|
+
x2, y2 = self._to_rl(matrix, _parse_float(_attr(el, "x2")), _parse_float(_attr(el, "y2")), local=local)
|
|
241
408
|
stroke = _rl_color(_attr(el, "stroke"), opacity)
|
|
242
409
|
width = _parse_float(_attr(el, "stroke-width"), 1.0)
|
|
243
410
|
self._add(Line(x1, y1, x2, y2, strokeColor=stroke, strokeWidth=width))
|
|
244
411
|
return
|
|
245
412
|
|
|
246
413
|
if tag == "circle":
|
|
247
|
-
cx, cy = self._to_rl(matrix, _parse_float(_attr(el, "cx")), _parse_float(_attr(el, "cy")))
|
|
414
|
+
cx, cy = self._to_rl(matrix, _parse_float(_attr(el, "cx")), _parse_float(_attr(el, "cy")), local=local)
|
|
248
415
|
radius = _parse_float(_attr(el, "r"))
|
|
249
416
|
fill = _attr(el, "fill")
|
|
250
417
|
if fill and fill != "none":
|
|
@@ -271,7 +438,7 @@ class _PdfBuilder:
|
|
|
271
438
|
return
|
|
272
439
|
|
|
273
440
|
if tag == "polygon":
|
|
274
|
-
points = self._parse_points(_attr(el, "points"), matrix)
|
|
441
|
+
points = self._parse_points(_attr(el, "points"), matrix, local=local)
|
|
275
442
|
self._add(
|
|
276
443
|
Polygon(
|
|
277
444
|
points,
|
|
@@ -282,7 +449,7 @@ class _PdfBuilder:
|
|
|
282
449
|
return
|
|
283
450
|
|
|
284
451
|
if tag == "polyline":
|
|
285
|
-
points = self._parse_points(_attr(el, "points"), matrix)
|
|
452
|
+
points = self._parse_points(_attr(el, "points"), matrix, local=local)
|
|
286
453
|
self._add(
|
|
287
454
|
PolyLine(
|
|
288
455
|
points,
|
|
@@ -294,7 +461,7 @@ class _PdfBuilder:
|
|
|
294
461
|
return
|
|
295
462
|
|
|
296
463
|
if tag == "path":
|
|
297
|
-
path = self._parse_path(_attr(el, "d"), matrix)
|
|
464
|
+
path = self._parse_path(_attr(el, "d"), matrix, local=local)
|
|
298
465
|
if path is not None:
|
|
299
466
|
path.fillColor = _rl_color(_attr(el, "fill"), opacity)
|
|
300
467
|
path.strokeColor = None
|
|
@@ -312,24 +479,58 @@ class _PdfBuilder:
|
|
|
312
479
|
y = _parse_float(_attr(el, "y"))
|
|
313
480
|
w = _parse_float(_attr(el, "width"), img.width)
|
|
314
481
|
h = _parse_float(_attr(el, "height"), img.height)
|
|
482
|
+
image_transform = _parse_transform(_attr(el, "transform"))
|
|
483
|
+
|
|
484
|
+
def _add_image_shape() -> None:
|
|
485
|
+
x0, y0 = self._to_rl(_Matrix(), x, y, local=True)
|
|
486
|
+
x1, y1 = self._to_rl(_Matrix(), x + w, y + h, local=True)
|
|
487
|
+
rl_img = RlImage(
|
|
488
|
+
min(x0, x1),
|
|
489
|
+
min(y0, y1),
|
|
490
|
+
abs(x1 - x0),
|
|
491
|
+
abs(y1 - y0),
|
|
492
|
+
path=ImageReader(io.BytesIO(raw)),
|
|
493
|
+
)
|
|
494
|
+
self._add(rl_img)
|
|
495
|
+
|
|
496
|
+
if _is_identity(image_transform):
|
|
497
|
+
if local:
|
|
498
|
+
_add_image_shape()
|
|
499
|
+
else:
|
|
500
|
+
x0, y0 = self._to_rl(matrix, x, y, local=False)
|
|
501
|
+
x1, y1 = self._to_rl(matrix, x + w, y + h, local=False)
|
|
502
|
+
self._add(
|
|
503
|
+
RlImage(
|
|
504
|
+
min(x0, x1),
|
|
505
|
+
min(y0, y1),
|
|
506
|
+
abs(x1 - x0),
|
|
507
|
+
abs(y1 - y0),
|
|
508
|
+
path=ImageReader(io.BytesIO(raw)),
|
|
509
|
+
)
|
|
510
|
+
)
|
|
511
|
+
return
|
|
315
512
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
abs(x1 - x0),
|
|
323
|
-
abs(y1 - y0),
|
|
324
|
-
path=ImageReader(io.BytesIO(raw)),
|
|
513
|
+
combined = matrix.multiply(image_transform)
|
|
514
|
+
group = Group()
|
|
515
|
+
group.transform = _matrix_to_reportlab_transform(
|
|
516
|
+
combined if not local else image_transform,
|
|
517
|
+
self.height,
|
|
518
|
+
nested=local,
|
|
325
519
|
)
|
|
326
|
-
|
|
520
|
+
child_shapes: list[Any] = []
|
|
521
|
+
saved = self._shapes
|
|
522
|
+
self._shapes = child_shapes
|
|
523
|
+
_add_image_shape()
|
|
524
|
+
self._shapes = saved
|
|
525
|
+
for shape in child_shapes:
|
|
526
|
+
group.add(shape)
|
|
527
|
+
self._add(group)
|
|
327
528
|
return
|
|
328
529
|
|
|
329
530
|
if tag == "text":
|
|
330
531
|
x = _parse_float(_attr(el, "x"))
|
|
331
532
|
y = _parse_float(_attr(el, "y"))
|
|
332
|
-
rl_x, rl_y = self._to_rl(matrix, x, y)
|
|
533
|
+
rl_x, rl_y = self._to_rl(matrix, x, y, local=local)
|
|
333
534
|
text = (el.text or "").strip()
|
|
334
535
|
if not text:
|
|
335
536
|
text = "".join(el.itertext())
|
|
@@ -350,17 +551,23 @@ class _PdfBuilder:
|
|
|
350
551
|
)
|
|
351
552
|
return
|
|
352
553
|
|
|
353
|
-
def _parse_points(
|
|
554
|
+
def _parse_points(
|
|
555
|
+
self,
|
|
556
|
+
value: Optional[str],
|
|
557
|
+
matrix: _Matrix,
|
|
558
|
+
*,
|
|
559
|
+
local: bool = False,
|
|
560
|
+
) -> list[float]:
|
|
354
561
|
if not value:
|
|
355
562
|
return []
|
|
356
563
|
nums = [float(n) for n in re.split(r"[\s,]+", value.strip()) if n]
|
|
357
564
|
points: list[float] = []
|
|
358
565
|
for i in range(0, len(nums) - 1, 2):
|
|
359
|
-
x, y = self._to_rl(matrix, nums[i], nums[i + 1])
|
|
566
|
+
x, y = self._to_rl(matrix, nums[i], nums[i + 1], local=local)
|
|
360
567
|
points.extend([x, y])
|
|
361
568
|
return points
|
|
362
569
|
|
|
363
|
-
def _parse_path(self, d: Optional[str], matrix: _Matrix):
|
|
570
|
+
def _parse_path(self, d: Optional[str], matrix: _Matrix, *, local: bool = False):
|
|
364
571
|
from reportlab.graphics.shapes import Path
|
|
365
572
|
|
|
366
573
|
if not d:
|
|
@@ -382,11 +589,11 @@ class _PdfBuilder:
|
|
|
382
589
|
current_x, current_y = nums[0], nums[1]
|
|
383
590
|
start_x, start_y = current_x, current_y
|
|
384
591
|
subpath_start_x, subpath_start_y = current_x, current_y
|
|
385
|
-
x, y = self._to_rl(matrix, current_x, current_y)
|
|
592
|
+
x, y = self._to_rl(matrix, current_x, current_y, local=local)
|
|
386
593
|
path.moveTo(x, y)
|
|
387
594
|
elif cmd == "L" and len(nums) >= 2:
|
|
388
595
|
current_x, current_y = nums[0], nums[1]
|
|
389
|
-
x, y = self._to_rl(matrix, current_x, current_y)
|
|
596
|
+
x, y = self._to_rl(matrix, current_x, current_y, local=local)
|
|
390
597
|
path.lineTo(x, y)
|
|
391
598
|
elif cmd == "A" and len(nums) >= 7:
|
|
392
599
|
rx, ry, _, large_arc, sweep, end_x, end_y = nums[:7]
|
|
@@ -401,11 +608,12 @@ class _PdfBuilder:
|
|
|
401
608
|
rx,
|
|
402
609
|
bool(int(large_arc)),
|
|
403
610
|
bool(int(sweep)),
|
|
611
|
+
local=local,
|
|
404
612
|
)
|
|
405
613
|
current_x, current_y = end_x, end_y
|
|
406
614
|
elif cmd == "Z":
|
|
407
615
|
current_x, current_y = subpath_start_x, subpath_start_y
|
|
408
|
-
x, y = self._to_rl(matrix, current_x, current_y)
|
|
616
|
+
x, y = self._to_rl(matrix, current_x, current_y, local=local)
|
|
409
617
|
path.lineTo(x, y)
|
|
410
618
|
path.closePath()
|
|
411
619
|
|
|
@@ -422,12 +630,14 @@ class _PdfBuilder:
|
|
|
422
630
|
radius: float,
|
|
423
631
|
large_arc: bool,
|
|
424
632
|
sweep: bool,
|
|
633
|
+
*,
|
|
634
|
+
local: bool = False,
|
|
425
635
|
) -> None:
|
|
426
636
|
dx = x2 - x1
|
|
427
637
|
dy = y2 - y1
|
|
428
638
|
dist = math.hypot(dx, dy)
|
|
429
639
|
if dist == 0 or radius == 0:
|
|
430
|
-
x, y = self._to_rl(matrix, x2, y2)
|
|
640
|
+
x, y = self._to_rl(matrix, x2, y2, local=local)
|
|
431
641
|
path.lineTo(x, y)
|
|
432
642
|
return
|
|
433
643
|
|
|
@@ -479,7 +689,7 @@ class _PdfBuilder:
|
|
|
479
689
|
t = start + (end - start) * (i / steps)
|
|
480
690
|
px = cx + radius * math.cos(t)
|
|
481
691
|
py = cy + radius * math.sin(t)
|
|
482
|
-
x, y = self._to_rl(matrix, px, py)
|
|
692
|
+
x, y = self._to_rl(matrix, px, py, local=local)
|
|
483
693
|
path.lineTo(x, y)
|
|
484
694
|
|
|
485
695
|
def build(self, elements: list[ET.Element]):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kaxe
|
|
3
|
-
Version: 1.4.4.
|
|
3
|
+
Version: 1.4.4.dev5
|
|
4
4
|
Summary: A small graphing tool for functions, points, equations and more
|
|
5
5
|
Author-email: Valter Yde Daugberg <valteryde@hotmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/valteryde/kaxe
|
|
@@ -27,6 +27,7 @@ Requires-Dist: psutil
|
|
|
27
27
|
Requires-Dist: opencv-python-headless
|
|
28
28
|
Provides-Extra: pdf
|
|
29
29
|
Requires-Dist: reportlab>=4.0; extra == "pdf"
|
|
30
|
+
Requires-Dist: fonttools>=4.0; extra == "pdf"
|
|
30
31
|
Dynamic: license-file
|
|
31
32
|
|
|
32
33
|
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
{kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.bright-oblique.ttf
RENAMED
|
File without changes
|
{kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.bright-roman.ttf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.concrete-bold.ttf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.concrete-roman.ttf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.serif-bold.ttf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.serif-italic.ttf
RENAMED
|
File without changes
|
{kaxe-1.4.4.dev4 → kaxe-1.4.4.dev5}/src/kaxe/resources/computer-modern-family/cmu.serif-roman.ttf
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|