signwriting 0.1.1__py3-none-any.whl → 0.1.3__py3-none-any.whl
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.
- signwriting/mouthing/mouthing.py +15 -3
- signwriting/mouthing/server.py +9 -4
- signwriting/visualizer/visualize.py +19 -7
- {signwriting-0.1.1.dist-info → signwriting-0.1.3.dist-info}/METADATA +4 -4
- {signwriting-0.1.1.dist-info → signwriting-0.1.3.dist-info}/RECORD +8 -8
- {signwriting-0.1.1.dist-info → signwriting-0.1.3.dist-info}/WHEEL +1 -1
- {signwriting-0.1.1.dist-info → signwriting-0.1.3.dist-info}/licenses/LICENSE +0 -0
- {signwriting-0.1.1.dist-info → signwriting-0.1.3.dist-info}/top_level.txt +0 -0
signwriting/mouthing/mouthing.py
CHANGED
|
@@ -2,18 +2,27 @@ import copy
|
|
|
2
2
|
import functools
|
|
3
3
|
import json
|
|
4
4
|
import re
|
|
5
|
+
from dataclasses import dataclass
|
|
5
6
|
from pathlib import Path
|
|
6
|
-
from typing import Union
|
|
7
|
+
from typing import Union, Optional
|
|
7
8
|
|
|
8
9
|
from epitran import Epitran
|
|
9
10
|
|
|
10
11
|
from signwriting.formats.fsw_to_sign import fsw_to_sign
|
|
11
12
|
from signwriting.formats.sign_to_fsw import sign_to_fsw
|
|
13
|
+
from signwriting.formats.fsw_to_swu import fsw2swu
|
|
12
14
|
from signwriting.utils.join_signs import join_signs_horizontal, sign_from_symbols
|
|
13
15
|
|
|
14
16
|
MOUTHING_INDEX = Path(__file__).parent / "mouthing.json"
|
|
15
17
|
|
|
16
18
|
|
|
19
|
+
@dataclass
|
|
20
|
+
class MouthingResult:
|
|
21
|
+
ipa: str
|
|
22
|
+
fsw: Optional[str]
|
|
23
|
+
swu: Optional[str]
|
|
24
|
+
|
|
25
|
+
|
|
17
26
|
@functools.lru_cache()
|
|
18
27
|
def get_mouthings():
|
|
19
28
|
with open(MOUTHING_INDEX, "r", encoding="utf-8") as f:
|
|
@@ -74,14 +83,17 @@ def mouth_ipa(characters: str, aspiration=False) -> Union[str, None]:
|
|
|
74
83
|
return join_signs_horizontal(*words, spacing=10)
|
|
75
84
|
|
|
76
85
|
|
|
77
|
-
def mouth(word: str, language: str, aspiration=False):
|
|
86
|
+
def mouth(word: str, language: str, aspiration=False) -> MouthingResult:
|
|
78
87
|
epi = Epitran(language, ligatures=True)
|
|
79
88
|
ipa = epi.transliterate(word)
|
|
80
89
|
|
|
81
90
|
mouthing_fsw = mouth_ipa(ipa, aspiration=aspiration)
|
|
82
91
|
if mouthing_fsw is None:
|
|
83
92
|
print(f"Failed to mouth {word}, IPA: {ipa}")
|
|
84
|
-
|
|
93
|
+
|
|
94
|
+
mouthing_swu = fsw2swu(mouthing_fsw) if mouthing_fsw else None
|
|
95
|
+
|
|
96
|
+
return MouthingResult(ipa=ipa, fsw=mouthing_fsw, swu=mouthing_swu)
|
|
85
97
|
|
|
86
98
|
|
|
87
99
|
if __name__ == "__main__":
|
signwriting/mouthing/server.py
CHANGED
|
@@ -4,8 +4,8 @@ from flask_restful import Resource, reqparse
|
|
|
4
4
|
from signwriting.mouthing.mouthing import mouth
|
|
5
5
|
|
|
6
6
|
parser = reqparse.RequestParser()
|
|
7
|
-
parser.add_argument('text', type=str, required=True, help='Text to mouth')
|
|
8
|
-
parser.add_argument('spoken_language', type=str, required=True,
|
|
7
|
+
parser.add_argument('text', type=str, required=True, location='args', help='Text to mouth')
|
|
8
|
+
parser.add_argument('spoken_language', type=str, required=True, location='args',
|
|
9
9
|
help='Spoken Language code. See "Language Support" at https://pypi.org/project/epitran/')
|
|
10
10
|
|
|
11
11
|
|
|
@@ -13,5 +13,10 @@ class Mouthing(Resource):
|
|
|
13
13
|
def get(self):
|
|
14
14
|
args = parser.parse_args()
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
result = mouth(args["text"], language=args["spoken_language"])
|
|
17
|
+
|
|
18
|
+
return make_response(jsonify({
|
|
19
|
+
"ipa": result.ipa,
|
|
20
|
+
"fsw": result.fsw,
|
|
21
|
+
"swu": result.swu
|
|
22
|
+
}), 200)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import os
|
|
2
|
+
from functools import cache
|
|
2
3
|
from pathlib import Path
|
|
3
4
|
from typing import Tuple, List, Literal, Union
|
|
4
5
|
|
|
@@ -13,13 +14,13 @@ from signwriting.formats.swu_to_fsw import swu2fsw
|
|
|
13
14
|
RGBA = Tuple[int, int, int, int]
|
|
14
15
|
|
|
15
16
|
|
|
16
|
-
@
|
|
17
|
+
@cache
|
|
17
18
|
def get_font(font_name: str) -> ImageFont.FreeTypeFont:
|
|
18
19
|
font_path = Path(__file__).parent / f'{font_name}.ttf'
|
|
19
20
|
return ImageFont.truetype(str(font_path), 30)
|
|
20
21
|
|
|
21
22
|
|
|
22
|
-
@
|
|
23
|
+
@cache
|
|
23
24
|
def get_symbol_size(symbol: str):
|
|
24
25
|
font = get_font('SuttonSignWritingLine')
|
|
25
26
|
line_id = symbol_line(key2id(symbol))
|
|
@@ -27,6 +28,17 @@ def get_symbol_size(symbol: str):
|
|
|
27
28
|
return right - left, bottom - top
|
|
28
29
|
|
|
29
30
|
|
|
31
|
+
def _clear_caches_after_fork():
|
|
32
|
+
# ImageFont objects cached by lru_cache can become corrupted after fork(),
|
|
33
|
+
# causing garbage data (e.g., wrong image dimensions). Clear caches in child
|
|
34
|
+
# processes so fonts are reloaded fresh.
|
|
35
|
+
get_font.cache_clear()
|
|
36
|
+
get_symbol_size.cache_clear()
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
os.register_at_fork(after_in_child=_clear_caches_after_fork)
|
|
40
|
+
|
|
41
|
+
|
|
30
42
|
# pylint: disable=too-many-locals, too-many-arguments
|
|
31
43
|
def signwriting_to_image(fsw: Union[str, List[str]], antialiasing=True, trust_box=True, embedded_color=False,
|
|
32
44
|
line_color: RGBA = (0, 0, 0, 255),
|
|
@@ -87,14 +99,14 @@ def layout_signwriting(images: List[Image.Image], direction: str) -> Image.Image
|
|
|
87
99
|
max_height = max(img.height for img in images)
|
|
88
100
|
total_width = sum(img.width for img in images) + GAP * (len(images) - 1)
|
|
89
101
|
size = (total_width, max_height)
|
|
90
|
-
paste_position = lambda offset, img: (offset, (max_height - img.height) // 2)
|
|
91
|
-
offset_increment = lambda img: img.width + GAP
|
|
102
|
+
paste_position = lambda offset, img: (offset, (max_height - img.height) // 2) # noqa: E731
|
|
103
|
+
offset_increment = lambda img: img.width + GAP # noqa: E731
|
|
92
104
|
else:
|
|
93
105
|
max_width = max(img.width for img in images)
|
|
94
106
|
total_height = sum(img.height for img in images) + GAP * (len(images) - 1)
|
|
95
107
|
size = (max_width, total_height)
|
|
96
|
-
paste_position = lambda offset, img: ((max_width - img.width) // 2, offset)
|
|
97
|
-
offset_increment = lambda img: img.height + GAP
|
|
108
|
+
paste_position = lambda offset, img: ((max_width - img.width) // 2, offset) # noqa: E731
|
|
109
|
+
offset_increment = lambda img: img.height + GAP # noqa: E731
|
|
98
110
|
|
|
99
111
|
layout_image = Image.new("RGBA", size, (255, 255, 255, 0))
|
|
100
112
|
offset = 0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: signwriting
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: Python utilities for SignWriting.
|
|
5
5
|
Author-email: Amit Moryossef <amitmoryossef@gmail.com>
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -116,7 +116,7 @@ signwriting_to_image(fsw)
|
|
|
116
116
|

|
|
117
117
|
|
|
118
118
|
To use the visualizer with the server, you can hit:
|
|
119
|
-
https://signwriting-sxie2r74ua-uc.a.run.app
|
|
119
|
+
https://signwriting-sxie2r74ua-uc.a.run.app/visualizer?fsw=M525x535S2e748483x510S10011501x466S2e704510x500S10019476x475
|
|
120
120
|
|
|
121
121
|
### `signwriting.utils`
|
|
122
122
|
|
|
@@ -149,7 +149,7 @@ spell(word, language)
|
|
|
149
149
|
```
|
|
150
150
|
|
|
151
151
|
To use the fingerspelling with the server, you can hit:
|
|
152
|
-
https://signwriting-sxie2r74ua-uc.a.run.app
|
|
152
|
+
https://signwriting-sxie2r74ua-uc.a.run.app/fingerspelling?text=hello&signed_language=ase
|
|
153
153
|
|
|
154
154
|
### `signwriting.mouthing`
|
|
155
155
|
|
|
@@ -168,7 +168,7 @@ Note: Installing English support for `epitran` requires extra steps,
|
|
|
168
168
|
see "Install flite" at [mouthing/README.md](signwriting/mouthing/README.md).
|
|
169
169
|
|
|
170
170
|
To use the mouthing with the server, you can hit:
|
|
171
|
-
https://signwriting-sxie2r74ua-uc.a.run.app
|
|
171
|
+
https://signwriting-sxie2r74ua-uc.a.run.app/mouthing?text=hello&spoken_language=eng-Latn
|
|
172
172
|
|
|
173
173
|
|
|
174
174
|
## Cite
|
|
@@ -41,8 +41,8 @@ signwriting/formats/test_swu_to_fsw.py,sha256=0nb4LY_m2oVkX1dkGyISryKEz1xnCA8fDF
|
|
|
41
41
|
signwriting/hamnosys/parallel.json,sha256=-099tSenNNf1mv6QzvkObJCuK9FwrTPQk_2H3EK3V2w,938851
|
|
42
42
|
signwriting/mouthing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
43
|
signwriting/mouthing/mouthing.json,sha256=fGL-JHzvNk_J0zB9lncX_PowcTlBUmrr91PL8bvTpZw,16875
|
|
44
|
-
signwriting/mouthing/mouthing.py,sha256=
|
|
45
|
-
signwriting/mouthing/server.py,sha256=
|
|
44
|
+
signwriting/mouthing/mouthing.py,sha256=QNpE4pqKjUWzfTR1vfidz8J1UxT8vK6c7vgXl4XLc9c,4159
|
|
45
|
+
signwriting/mouthing/server.py,sha256=Z3SuRw3Dsx2mpoSHIJG1WRI-CIbW_qTbVpUH7RFvkFQ,756
|
|
46
46
|
signwriting/mouthing/visualize_mouthing.py,sha256=6y8Gh4T_IyVWktwdVAX_l_C_ujUII8XnMkxFsldD9u8,1868
|
|
47
47
|
signwriting/tokenizer/__init__.py,sha256=A9S7lTIGy9Ki9BQx9OS91-LSEWueM3N7iUQQX0VaYPA,228
|
|
48
48
|
signwriting/tokenizer/base_tokenizer.py,sha256=UvSsgULyBaDbFygYJP80KSSF4Q8B6hQ9ggRSIGCZPmI,2196
|
|
@@ -59,9 +59,9 @@ signwriting/visualizer/SuttonSignWritingOneD.ttf,sha256=R-1Kih4jwVOovKdSbVDh9BmA
|
|
|
59
59
|
signwriting/visualizer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
60
60
|
signwriting/visualizer/server.py,sha256=qWgN7kIei7BE1K-kpiS5Dx47t1qNKuU5YfrjKs7douo,1603
|
|
61
61
|
signwriting/visualizer/test_visualize.py,sha256=eH4D89bEb8DpRgNVpd3uLIHuIw5kPosWlVl9ry0y9g4,4059
|
|
62
|
-
signwriting/visualizer/visualize.py,sha256=
|
|
63
|
-
signwriting-0.1.
|
|
64
|
-
signwriting-0.1.
|
|
65
|
-
signwriting-0.1.
|
|
66
|
-
signwriting-0.1.
|
|
67
|
-
signwriting-0.1.
|
|
62
|
+
signwriting/visualizer/visualize.py,sha256=BiDWcRyv36N8rgZZJDcmE5O3f8_xiAVoC7jV1atNUno,4362
|
|
63
|
+
signwriting-0.1.3.dist-info/licenses/LICENSE,sha256=5DdbOXGaeoF-PL0-HkJOUmegksP13HD8FRy6-1m-D-o,1081
|
|
64
|
+
signwriting-0.1.3.dist-info/METADATA,sha256=hGcPEGjgsLqjC1w3FfeFVumbJontpSMfY7OV44-l2MA,5969
|
|
65
|
+
signwriting-0.1.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
66
|
+
signwriting-0.1.3.dist-info/top_level.txt,sha256=MbwynBxqcjJN-XMzTmwzp7wgQ0mzu7X-bjVQZMrOvGw,12
|
|
67
|
+
signwriting-0.1.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|