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