kaxe 1.4.6.dev0__tar.gz → 1.4.8__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.6.dev0/src/kaxe.egg-info → kaxe-1.4.8}/PKG-INFO +1 -1
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/pyproject.toml +1 -1
- kaxe-1.4.8/src/kaxe/core/bounds.py +143 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/d3/openglrender.py +2 -5
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/window.py +16 -12
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/d2/function.py +82 -2
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/d3/function.py +94 -1
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/function.py +6 -1
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/plot/polar.py +27 -2
- {kaxe-1.4.6.dev0 → kaxe-1.4.8/src/kaxe.egg-info}/PKG-INFO +1 -1
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe.egg-info/SOURCES.txt +1 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/LICENSE +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/MANIFEST.in +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/README.md +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/setup.cfg +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/__init__.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/chart/__init__.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/chart/bar.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/chart/box.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/chart/pie.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/chart/qqplot.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/__init__.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/axis.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/color.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/d3/backend.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/d3/camera.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/d3/helper.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/d3/hud.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/d3/objects/__init__.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/d3/objects/color.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/d3/objects/line.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/d3/objects/point.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/d3/objects/pointer.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/d3/objects/triangle.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/d3/translator.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/draw.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/fileloader.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/helper.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/legend.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/line.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/marker.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/profiler.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/round.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/shapes.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/styles.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/svg.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/svg_pdf.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/symbol.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/core/text.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/data/__init__.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/data/excel.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/__init__.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/_lazy.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/d2/__init__.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/d2/arrow.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/d2/bubble.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/d2/contour.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/d2/equation.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/d2/fill.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/d2/map.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/d2/parameter.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/d2/pillar.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/d2/point.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/d3/__init__.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/d3/base.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/d3/mesh.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/d3/point.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/d3/potato.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/legend.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/mapdata.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/point.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/objects/text.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/plot/__init__.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/plot/_lazy.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/plot/box.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/plot/constants.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/plot/d3/__init__.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/plot/d3/axes.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/plot/d3/geometry.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/plot/d3/plot3d.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/plot/d3/variants.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/plot/double.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/plot/empty.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/plot/grid.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/plot/log.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/plot/standard.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/plot/themes.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/plot/zoom.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/plot/zoom_connector.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/__init__.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/__init__.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.bright-oblique.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.bright-roman.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.bright-semibold.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.bright-semiboldoblique.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.classical-serif-italic.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.concrete-bold.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.concrete-bolditalic.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.concrete-italic.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.concrete-roman.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-bold.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-boldoblique.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-demi-condensed-demicondensed.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-medium.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-oblique.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.serif-bold.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.serif-bolditalic.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.serif-extra-boldslanted.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.serif-extra-romanslanted.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.serif-italic.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.serif-roman.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.serif-upright-italic-uprightitalic.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-bold.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-bolditalic.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-italic.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-light.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-lightoblique.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-regular.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-variable-width-italic.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-variable-width-medium.ttf +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/readme.txt +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/logo-small.png +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/symbolcross.png +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/symboldonut.png +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/symbollollipop.png +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/symboltriangle.png +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe.egg-info/dependency_links.txt +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe.egg-info/requires.txt +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe.egg-info/top_level.txt +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/tests/test.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/tests/test2.py +0 -0
- {kaxe-1.4.6.dev0 → kaxe-1.4.8}/tests/test3.py +0 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"""Coarse sampling helpers for auto-scaling plot windows from functions."""
|
|
2
|
+
|
|
3
|
+
import math
|
|
4
|
+
from typing import Callable, Optional, Sequence, Tuple
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
from .helper import isRealNumber
|
|
9
|
+
|
|
10
|
+
DEFAULT_DOMAIN_1D = (-10.0, 10.0)
|
|
11
|
+
DEFAULT_DOMAIN_2D = (-10.0, 10.0, -10.0, 10.0)
|
|
12
|
+
DEFAULT_MARGIN = 0.05
|
|
13
|
+
BOUNDS_SAMPLES_1D = 128
|
|
14
|
+
BOUNDS_SAMPLES_2D = 32
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def is_finite(value) -> bool:
|
|
18
|
+
return isRealNumber(value) and math.isfinite(value)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def apply_margin(lo: float, hi: float, fraction: float = DEFAULT_MARGIN) -> Tuple[float, float]:
|
|
22
|
+
if lo == hi:
|
|
23
|
+
return lo - 1.0, hi + 1.0
|
|
24
|
+
span = hi - lo
|
|
25
|
+
pad = span * fraction
|
|
26
|
+
return lo - pad, hi + pad
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def resolve_interval(
|
|
30
|
+
user_domain: Optional[Sequence[float]],
|
|
31
|
+
plot_lo,
|
|
32
|
+
plot_hi,
|
|
33
|
+
default: Tuple[float, float],
|
|
34
|
+
) -> Tuple[float, float]:
|
|
35
|
+
if plot_lo is not None and plot_hi is not None:
|
|
36
|
+
return float(plot_lo), float(plot_hi)
|
|
37
|
+
if user_domain is not None:
|
|
38
|
+
return float(user_domain[0]), float(user_domain[1])
|
|
39
|
+
return default
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def sample_1d(
|
|
43
|
+
f: Callable,
|
|
44
|
+
x0: float,
|
|
45
|
+
x1: float,
|
|
46
|
+
n: int = BOUNDS_SAMPLES_1D,
|
|
47
|
+
) -> Tuple[Optional[float], Optional[float], Optional[float], Optional[float]]:
|
|
48
|
+
if x0 == x1:
|
|
49
|
+
x0 -= 0.5
|
|
50
|
+
x1 += 0.5
|
|
51
|
+
|
|
52
|
+
xs = np.linspace(x0, x1, n)
|
|
53
|
+
ys = []
|
|
54
|
+
for x in xs:
|
|
55
|
+
try:
|
|
56
|
+
y = f(float(x))
|
|
57
|
+
except Exception:
|
|
58
|
+
continue
|
|
59
|
+
if is_finite(y):
|
|
60
|
+
ys.append(float(y))
|
|
61
|
+
|
|
62
|
+
if not ys:
|
|
63
|
+
return None, None, None, None
|
|
64
|
+
|
|
65
|
+
return float(x0), float(x1), min(ys), max(ys)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def sample_2d(
|
|
69
|
+
f: Callable,
|
|
70
|
+
x0: float,
|
|
71
|
+
x1: float,
|
|
72
|
+
y0: float,
|
|
73
|
+
y1: float,
|
|
74
|
+
n: int = BOUNDS_SAMPLES_2D,
|
|
75
|
+
) -> Tuple[
|
|
76
|
+
Optional[float],
|
|
77
|
+
Optional[float],
|
|
78
|
+
Optional[float],
|
|
79
|
+
Optional[float],
|
|
80
|
+
Optional[float],
|
|
81
|
+
Optional[float],
|
|
82
|
+
]:
|
|
83
|
+
if x0 == x1:
|
|
84
|
+
x0 -= 0.5
|
|
85
|
+
x1 += 0.5
|
|
86
|
+
if y0 == y1:
|
|
87
|
+
y0 -= 0.5
|
|
88
|
+
y1 += 0.5
|
|
89
|
+
|
|
90
|
+
xs = np.linspace(x0, x1, n)
|
|
91
|
+
ys = np.linspace(y0, y1, n)
|
|
92
|
+
x_grid, y_grid = np.meshgrid(xs, ys, indexing="ij")
|
|
93
|
+
|
|
94
|
+
zs = []
|
|
95
|
+
try:
|
|
96
|
+
z_vals = np.asarray(f(x_grid, y_grid), dtype=np.float64)
|
|
97
|
+
if z_vals.shape == x_grid.shape and np.issubdtype(z_vals.dtype, np.floating):
|
|
98
|
+
for z in z_vals.ravel():
|
|
99
|
+
if is_finite(z):
|
|
100
|
+
zs.append(float(z))
|
|
101
|
+
except Exception:
|
|
102
|
+
for x in xs:
|
|
103
|
+
for y in ys:
|
|
104
|
+
try:
|
|
105
|
+
z = f(float(x), float(y))
|
|
106
|
+
except Exception:
|
|
107
|
+
continue
|
|
108
|
+
if is_finite(z):
|
|
109
|
+
zs.append(float(z))
|
|
110
|
+
|
|
111
|
+
if not zs:
|
|
112
|
+
return None, None, None, None, None, None
|
|
113
|
+
|
|
114
|
+
return float(x0), float(x1), float(y0), float(y1), min(zs), max(zs)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def sample_polar_1d(
|
|
118
|
+
f: Callable,
|
|
119
|
+
n: int = BOUNDS_SAMPLES_1D,
|
|
120
|
+
) -> Tuple[Optional[float], Optional[float]]:
|
|
121
|
+
rs = []
|
|
122
|
+
for i in range(n):
|
|
123
|
+
theta = 2.0 * math.pi * i / n
|
|
124
|
+
try:
|
|
125
|
+
r = f(theta)
|
|
126
|
+
except Exception:
|
|
127
|
+
continue
|
|
128
|
+
if is_finite(r):
|
|
129
|
+
rs.append(float(r))
|
|
130
|
+
|
|
131
|
+
if not rs:
|
|
132
|
+
return None, None
|
|
133
|
+
|
|
134
|
+
r_min = min(0.0, min(rs))
|
|
135
|
+
r_max = max(rs)
|
|
136
|
+
return apply_margin(r_min, r_max)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def append_axis_values(values: list, lo, hi):
|
|
140
|
+
if lo is not None:
|
|
141
|
+
values.append(lo)
|
|
142
|
+
if hi is not None:
|
|
143
|
+
values.append(hi)
|
|
@@ -13,7 +13,6 @@ from .objects.line import Line3D, FlatLine3D, Line3DObject, FlatLine3DObject
|
|
|
13
13
|
from .objects.point import Point3D, Point3DObject
|
|
14
14
|
import psutil
|
|
15
15
|
process = psutil.Process()
|
|
16
|
-
import sys
|
|
17
16
|
import sdl2
|
|
18
17
|
import sdl2.ext
|
|
19
18
|
import sdl2.video
|
|
@@ -994,14 +993,12 @@ class OpenGLRender:
|
|
|
994
993
|
lasttime = time.time()
|
|
995
994
|
while sdl2.SDL_PollEvent(event):
|
|
996
995
|
if event.type == sdl2.SDL_QUIT:
|
|
997
|
-
running = False
|
|
998
996
|
self.quit(gl_context, window)
|
|
999
|
-
|
|
997
|
+
return
|
|
1000
998
|
elif event.type == sdl2.SDL_KEYDOWN:
|
|
1001
999
|
if event.key.keysym.sym == sdl2.SDLK_ESCAPE:
|
|
1002
1000
|
self.quit(gl_context, window)
|
|
1003
|
-
|
|
1004
|
-
sys.exit()
|
|
1001
|
+
return
|
|
1005
1002
|
|
|
1006
1003
|
if event.key.keysym.sym == sdl2.SDLK_RETURN and (event.key.keysym.mod & sdl2.KMOD_ALT):
|
|
1007
1004
|
# Toggle fullscreen on Alt+Enter
|
|
@@ -268,23 +268,27 @@ class Window(AttrObject):
|
|
|
268
268
|
if len(self.windowAxis) != 6:
|
|
269
269
|
[self.windowAxis.append(None) for _ in range(6 - len(self.windowAxis))]
|
|
270
270
|
|
|
271
|
-
# har ingen effekt på 3D
|
|
272
271
|
if sorted(self.windowAxis, key=lambda x: x==None)[-1] == None:
|
|
273
272
|
x = []
|
|
274
273
|
y = []
|
|
275
274
|
z = []
|
|
276
275
|
for i in self.objects:
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
276
|
+
bounds_fn = getattr(i, 'bounds', None)
|
|
277
|
+
if callable(bounds_fn):
|
|
278
|
+
bounds = bounds_fn(plot_window=self.windowAxis, plot=self)
|
|
279
|
+
if bounds:
|
|
280
|
+
if bounds[0] is not None:
|
|
281
|
+
x.append(bounds[0])
|
|
282
|
+
if len(bounds) > 1 and bounds[1] is not None:
|
|
283
|
+
x.append(bounds[1])
|
|
284
|
+
if len(bounds) > 2 and bounds[2] is not None:
|
|
285
|
+
y.append(bounds[2])
|
|
286
|
+
if len(bounds) > 3 and bounds[3] is not None:
|
|
287
|
+
y.append(bounds[3])
|
|
288
|
+
if len(bounds) > 4 and bounds[4] is not None:
|
|
289
|
+
z.append(bounds[4])
|
|
290
|
+
if len(bounds) > 5 and bounds[5] is not None:
|
|
291
|
+
z.append(bounds[5])
|
|
288
292
|
continue
|
|
289
293
|
|
|
290
294
|
try:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
from typing import Callable
|
|
2
|
+
from typing import Callable, Optional, Sequence, Tuple, Union
|
|
3
3
|
from .point import Points2D
|
|
4
4
|
from ...core.styles import getRandomColor
|
|
5
5
|
from ...core.color import to_rgba
|
|
@@ -7,9 +7,16 @@ from ...core.helper import *
|
|
|
7
7
|
from ...core.shapes import shapes
|
|
8
8
|
from ...core.symbol import symbol
|
|
9
9
|
from ...core.helper import isRealNumber
|
|
10
|
+
from ...core.bounds import (
|
|
11
|
+
DEFAULT_DOMAIN_1D,
|
|
12
|
+
DEFAULT_MARGIN,
|
|
13
|
+
apply_margin,
|
|
14
|
+
resolve_interval,
|
|
15
|
+
sample_1d,
|
|
16
|
+
sample_polar_1d,
|
|
17
|
+
)
|
|
10
18
|
from ...plot import identities
|
|
11
19
|
from random import randint
|
|
12
|
-
from typing import Union
|
|
13
20
|
|
|
14
21
|
class Function2D:
|
|
15
22
|
"""
|
|
@@ -30,6 +37,11 @@ class Function2D:
|
|
|
30
37
|
If greater than 0, the function plot line will be dotted with the specified distance between dots. Default is 0.
|
|
31
38
|
dashed : int, optional
|
|
32
39
|
If greater than 0, the function plot line will be dashed with the specified distance between dashes. Default is 0.
|
|
40
|
+
domain : tuple, optional
|
|
41
|
+
Sampling interval ``(x0, x1)`` for auto-scaled x when the plot window
|
|
42
|
+
does not fix x. Default is ``(-10, 10)``.
|
|
43
|
+
range : tuple, optional
|
|
44
|
+
Fixed output interval ``(y0, y1)`` for the y axis when auto-scaling.
|
|
33
45
|
args : tuple, optional
|
|
34
46
|
Additional positional arguments to be passed to the function f.
|
|
35
47
|
kwargs : dict, optional
|
|
@@ -56,6 +68,8 @@ class Function2D:
|
|
|
56
68
|
width:int=10,
|
|
57
69
|
dotted:int=0,
|
|
58
70
|
dashed:int=0,
|
|
71
|
+
domain:Optional[Sequence[float]]=None,
|
|
72
|
+
range:Optional[Sequence[float]]=None,
|
|
59
73
|
*args,
|
|
60
74
|
**kwargs
|
|
61
75
|
):
|
|
@@ -90,9 +104,75 @@ class Function2D:
|
|
|
90
104
|
self.otherArgs = args
|
|
91
105
|
self.otherKwargs = kwargs
|
|
92
106
|
|
|
107
|
+
self.domain = tuple(domain) if domain is not None else None
|
|
108
|
+
self.range = tuple(range) if range is not None else None
|
|
109
|
+
|
|
93
110
|
self.supports = [identities.XYPLOT, identities.POLAR, identities.LOGPLOT]
|
|
94
111
|
|
|
95
112
|
|
|
113
|
+
def _call(self, x):
|
|
114
|
+
return self.function(x, *self.otherArgs, **self.otherKwargs)
|
|
115
|
+
|
|
116
|
+
def bounds(self, plot_window=None, plot=None):
|
|
117
|
+
"""
|
|
118
|
+
Estimate data bounds for auto-scaling.
|
|
119
|
+
|
|
120
|
+
Returns up to six values ``[x0, x1, y0, y1, z0, z1]``. Entries are
|
|
121
|
+
``None`` when that axis is fixed by the plot window or not applicable.
|
|
122
|
+
"""
|
|
123
|
+
if plot_window is None and plot is not None:
|
|
124
|
+
plot_window = getattr(plot, 'windowAxis', None)
|
|
125
|
+
|
|
126
|
+
plot_identity = getattr(plot, 'identity', None) if plot is not None else None
|
|
127
|
+
first_axis_log = getattr(plot, 'firstAxisLog', False) if plot is not None else False
|
|
128
|
+
second_axis_log = getattr(plot, 'secondAxisLog', False) if plot is not None else False
|
|
129
|
+
|
|
130
|
+
if plot_identity == identities.POLAR:
|
|
131
|
+
wa = plot_window or [None, None]
|
|
132
|
+
if wa[0] is not None and wa[1] is not None:
|
|
133
|
+
return [wa[0], wa[1], None, None]
|
|
134
|
+
r0, r1 = sample_polar_1d(self._call)
|
|
135
|
+
if r0 is None:
|
|
136
|
+
return [None, None, None, None]
|
|
137
|
+
return [r0, r1, None, None]
|
|
138
|
+
|
|
139
|
+
wa = list(plot_window or [None, None, None, None])
|
|
140
|
+
while len(wa) < 4:
|
|
141
|
+
wa.append(None)
|
|
142
|
+
|
|
143
|
+
default_x = (0.01, 10.0) if first_axis_log else DEFAULT_DOMAIN_1D
|
|
144
|
+
x0, x1 = resolve_interval(self.domain, wa[0], wa[1], default_x)
|
|
145
|
+
if first_axis_log and x0 <= 0:
|
|
146
|
+
x0 = 0.01
|
|
147
|
+
|
|
148
|
+
auto_x = wa[0] is None or wa[1] is None
|
|
149
|
+
auto_y = wa[2] is None or wa[3] is None
|
|
150
|
+
|
|
151
|
+
if self.range is not None:
|
|
152
|
+
y0, y1 = float(self.range[0]), float(self.range[1])
|
|
153
|
+
elif auto_y:
|
|
154
|
+
_, _, y0, y1 = sample_1d(self._call, x0, x1)
|
|
155
|
+
if y0 is None:
|
|
156
|
+
return [None, None, None, None]
|
|
157
|
+
if second_axis_log:
|
|
158
|
+
if y0 <= 0:
|
|
159
|
+
y0 = 0.01
|
|
160
|
+
if y1 <= 0:
|
|
161
|
+
y1 = 0.01
|
|
162
|
+
y0, y1 = apply_margin(y0, y1)
|
|
163
|
+
else:
|
|
164
|
+
y0, y1 = None, None
|
|
165
|
+
|
|
166
|
+
if auto_x:
|
|
167
|
+
x0, x1 = apply_margin(x0, x1)
|
|
168
|
+
if first_axis_log and x0 <= 0:
|
|
169
|
+
x0 = 0.01
|
|
170
|
+
else:
|
|
171
|
+
x0, x1 = None, None
|
|
172
|
+
|
|
173
|
+
return [x0, x1, y0, y1]
|
|
174
|
+
|
|
175
|
+
|
|
96
176
|
def __call__(self, x):
|
|
97
177
|
return self.function(x, *self.otherArgs, **self.otherKwargs)
|
|
98
178
|
|
|
@@ -13,6 +13,14 @@ import numpy as np
|
|
|
13
13
|
import math
|
|
14
14
|
import numbers
|
|
15
15
|
import time
|
|
16
|
+
from typing import Optional, Sequence
|
|
17
|
+
|
|
18
|
+
from ...core.bounds import (
|
|
19
|
+
DEFAULT_DOMAIN_1D,
|
|
20
|
+
apply_margin,
|
|
21
|
+
resolve_interval,
|
|
22
|
+
sample_2d,
|
|
23
|
+
)
|
|
16
24
|
|
|
17
25
|
|
|
18
26
|
|
|
@@ -75,6 +83,14 @@ class Function3D(Base3DObject):
|
|
|
75
83
|
Whether to fill the plot. default is True
|
|
76
84
|
drawDiagonalLines: bool
|
|
77
85
|
Whether to draw diagonal lines in triangles when fill is False. default is False
|
|
86
|
+
domain : tuple, optional
|
|
87
|
+
Sampling interval for the two independent axes. For ``axis="xy"`` this is
|
|
88
|
+
``(x0, x1, y0, y1)``; for ``axis="xz"`` it is ``(x0, x1, z0, z1)``; for
|
|
89
|
+
``axis="yz"`` it is ``(y0, y1, z0, z1)``. Defaults to ``(-10, 10)`` on
|
|
90
|
+
each independent axis when the plot window does not fix them.
|
|
91
|
+
range : tuple, optional
|
|
92
|
+
Fixed interval ``(lo, hi)`` on the dependent axis (z for ``axis="xy"``,
|
|
93
|
+
y for ``axis="xz"``, x for ``axis="yz"``).
|
|
78
94
|
excludeLight : bool, optional
|
|
79
95
|
Whether to exclude lighting effects. Default is True.
|
|
80
96
|
|
|
@@ -93,6 +109,8 @@ class Function3D(Base3DObject):
|
|
|
93
109
|
drawDiagonalLines:bool=False,
|
|
94
110
|
axis="xy",
|
|
95
111
|
excludeLight=True,
|
|
112
|
+
domain:Optional[Sequence[float]]=None,
|
|
113
|
+
range:Optional[Sequence[float]]=None,
|
|
96
114
|
*args,
|
|
97
115
|
**kwargs
|
|
98
116
|
):
|
|
@@ -106,6 +124,9 @@ class Function3D(Base3DObject):
|
|
|
106
124
|
self.otherKwargs = kwargs
|
|
107
125
|
self.excludeLight = excludeLight
|
|
108
126
|
|
|
127
|
+
self.domain = tuple(domain) if domain is not None else None
|
|
128
|
+
self.range = tuple(range) if range is not None else None
|
|
129
|
+
|
|
109
130
|
self.fill = fill
|
|
110
131
|
self.drawDiagonalLines = drawDiagonalLines
|
|
111
132
|
|
|
@@ -124,8 +145,80 @@ class Function3D(Base3DObject):
|
|
|
124
145
|
self.numPoints = 25
|
|
125
146
|
|
|
126
147
|
|
|
127
|
-
|
|
148
|
+
_AXIS_IDX = {'x': (0, 1), 'y': (2, 3), 'z': (4, 5)}
|
|
149
|
+
|
|
150
|
+
def _call(self, a, b):
|
|
151
|
+
return self.f(a, b, *self.otherArgs, **self.otherKwargs)
|
|
152
|
+
|
|
153
|
+
def _resolve_axis_interval(self, axis_name, plot_window, domain_slice):
|
|
154
|
+
lo_i, hi_i = self._AXIS_IDX[axis_name]
|
|
155
|
+
plot_lo = plot_window[lo_i] if len(plot_window) > lo_i else None
|
|
156
|
+
plot_hi = plot_window[hi_i] if len(plot_window) > hi_i else None
|
|
157
|
+
user = domain_slice if domain_slice is not None else None
|
|
158
|
+
return resolve_interval(user, plot_lo, plot_hi, DEFAULT_DOMAIN_1D)
|
|
159
|
+
|
|
160
|
+
def _axis_auto(self, axis_name, plot_window):
|
|
161
|
+
lo_i, hi_i = self._AXIS_IDX[axis_name]
|
|
162
|
+
if len(plot_window) <= hi_i:
|
|
163
|
+
return True
|
|
164
|
+
return plot_window[lo_i] is None or plot_window[hi_i] is None
|
|
165
|
+
|
|
166
|
+
def bounds(self, plot_window=None, plot=None):
|
|
167
|
+
"""
|
|
168
|
+
Estimate data bounds for auto-scaling 3D plots.
|
|
169
|
+
|
|
170
|
+
Returns ``[x0, x1, y0, y1, z0, z1]`` with ``None`` for fixed axes.
|
|
171
|
+
"""
|
|
172
|
+
if plot_window is None and plot is not None:
|
|
173
|
+
plot_window = getattr(plot, 'windowAxis', None)
|
|
174
|
+
|
|
175
|
+
wa = list(plot_window or [None] * 6)
|
|
176
|
+
while len(wa) < 6:
|
|
177
|
+
wa.append(None)
|
|
178
|
+
|
|
179
|
+
ind0, ind1 = self.axis[0], self.axis[1]
|
|
180
|
+
dep = self.dependantVariable
|
|
128
181
|
|
|
182
|
+
domain = self.domain
|
|
183
|
+
d0 = domain[0:2] if domain is not None else None
|
|
184
|
+
d1 = domain[2:4] if domain is not None else None
|
|
185
|
+
|
|
186
|
+
if self.axis == 'xy':
|
|
187
|
+
u_axis, v_axis = 'x', 'y'
|
|
188
|
+
elif self.axis == 'xz':
|
|
189
|
+
u_axis, v_axis = 'x', 'z'
|
|
190
|
+
else:
|
|
191
|
+
u_axis, v_axis = 'y', 'z'
|
|
192
|
+
|
|
193
|
+
u0, u1 = self._resolve_axis_interval(u_axis, wa, d0)
|
|
194
|
+
v0, v1 = self._resolve_axis_interval(v_axis, wa, d1)
|
|
195
|
+
|
|
196
|
+
result = [None] * 6
|
|
197
|
+
|
|
198
|
+
for axis_name, lo, hi in ((u_axis, u0, u1), (v_axis, v0, v1)):
|
|
199
|
+
if not self._axis_auto(axis_name, wa):
|
|
200
|
+
continue
|
|
201
|
+
lo, hi = apply_margin(lo, hi)
|
|
202
|
+
lo_i, hi_i = self._AXIS_IDX[axis_name]
|
|
203
|
+
result[lo_i] = lo
|
|
204
|
+
result[hi_i] = hi
|
|
205
|
+
|
|
206
|
+
if self.range is not None:
|
|
207
|
+
dep_lo, dep_hi = float(self.range[0]), float(self.range[1])
|
|
208
|
+
elif self._axis_auto(dep, wa):
|
|
209
|
+
_, _, _, _, dep_lo, dep_hi = sample_2d(self._call, u0, u1, v0, v1)
|
|
210
|
+
if dep_lo is None:
|
|
211
|
+
return result
|
|
212
|
+
dep_lo, dep_hi = apply_margin(dep_lo, dep_hi)
|
|
213
|
+
else:
|
|
214
|
+
return result
|
|
215
|
+
|
|
216
|
+
dep_lo_i, dep_hi_i = self._AXIS_IDX[dep]
|
|
217
|
+
result[dep_lo_i] = dep_lo
|
|
218
|
+
result[dep_hi_i] = dep_hi
|
|
219
|
+
return result
|
|
220
|
+
|
|
221
|
+
|
|
129
222
|
def __addTriangle__(self, render, p1, p2, p3, color, isRealpoint):
|
|
130
223
|
|
|
131
224
|
# dont draw vertical vertices
|
|
@@ -19,6 +19,11 @@ class Function:
|
|
|
19
19
|
The number of points to plot for 3D functions. Default is None.
|
|
20
20
|
fill : bool, optional
|
|
21
21
|
Whether to fill the area under the function plot for 3D functions. Default is True.
|
|
22
|
+
domain : tuple, optional
|
|
23
|
+
Sampling interval for auto-scaled axes. See :class:`kaxe.Function2D` and
|
|
24
|
+
:class:`kaxe.Function3D`.
|
|
25
|
+
range : tuple, optional
|
|
26
|
+
Fixed output interval on the dependent axis when auto-scaling.
|
|
22
27
|
*args : tuple
|
|
23
28
|
Additional positional arguments to pass to the function f.
|
|
24
29
|
**kwargs : dict
|
|
@@ -53,5 +58,5 @@ class Function:
|
|
|
53
58
|
|
|
54
59
|
if n == 2:
|
|
55
60
|
from .d3.function import Function3D
|
|
56
|
-
return Function3D(f, color=color, numPoints=numPoints, fill=fill)
|
|
61
|
+
return Function3D(f, color=color, numPoints=numPoints, fill=fill, *args, **kwargs)
|
|
57
62
|
|
|
@@ -61,8 +61,33 @@ class PolarPlot(Window):
|
|
|
61
61
|
|
|
62
62
|
# creating plotting window
|
|
63
63
|
def __calculateWindowBorders__(self):
|
|
64
|
-
if self.windowAxis[0] is None:
|
|
65
|
-
|
|
64
|
+
if self.windowAxis[0] is None:
|
|
65
|
+
self.windowAxis[0] = 0
|
|
66
|
+
|
|
67
|
+
if self.windowAxis[1] is not None:
|
|
68
|
+
return
|
|
69
|
+
|
|
70
|
+
r_vals = []
|
|
71
|
+
for obj in self.objects:
|
|
72
|
+
bounds_fn = getattr(obj, 'bounds', None)
|
|
73
|
+
if callable(bounds_fn):
|
|
74
|
+
bounds = bounds_fn(plot_window=self.windowAxis, plot=self)
|
|
75
|
+
if bounds:
|
|
76
|
+
if bounds[0] is not None:
|
|
77
|
+
r_vals.append(bounds[0])
|
|
78
|
+
if bounds[1] is not None:
|
|
79
|
+
r_vals.append(bounds[1])
|
|
80
|
+
continue
|
|
81
|
+
try:
|
|
82
|
+
r_vals.append(obj.farLeft)
|
|
83
|
+
r_vals.append(obj.farRight)
|
|
84
|
+
except AttributeError:
|
|
85
|
+
continue
|
|
86
|
+
|
|
87
|
+
if r_vals:
|
|
88
|
+
self.windowAxis[1] = max(r_vals)
|
|
89
|
+
else:
|
|
90
|
+
self.windowAxis[1] = 10
|
|
66
91
|
|
|
67
92
|
|
|
68
93
|
def __addRoundLines__(self):
|
|
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.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.bright-oblique.ttf
RENAMED
|
File without changes
|
{kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.bright-roman.ttf
RENAMED
|
File without changes
|
{kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.bright-semibold.ttf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.concrete-bold.ttf
RENAMED
|
File without changes
|
{kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.concrete-bolditalic.ttf
RENAMED
|
File without changes
|
{kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.concrete-italic.ttf
RENAMED
|
File without changes
|
{kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.concrete-roman.ttf
RENAMED
|
File without changes
|
{kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-bold.ttf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-medium.ttf
RENAMED
|
File without changes
|
{kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-oblique.ttf
RENAMED
|
File without changes
|
|
File without changes
|
{kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.serif-bolditalic.ttf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kaxe-1.4.6.dev0 → kaxe-1.4.8}/src/kaxe/resources/computer-modern-family/cmu.serif-italic.ttf
RENAMED
|
File without changes
|
{kaxe-1.4.6.dev0 → kaxe-1.4.8}/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
|