Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -13,13 +13,14 @@ from fontmake.font_project import FontProject
|
|
| 13 |
from defcon import Font, Glyph
|
| 14 |
from fontTools.pens.svgPathPen import SVGPathPen
|
| 15 |
from svgpathtools import parse_path, Path, Line, CubicBezier, QuadraticBezier, Arc
|
|
|
|
| 16 |
|
| 17 |
# ------------------------
|
| 18 |
# MODELE
|
| 19 |
# ------------------------
|
| 20 |
def load_model():
|
| 21 |
-
tokenizer = AutoTokenizer.from_pretrained("ChevalierJoseph/
|
| 22 |
-
model = AutoModelForCausalLM.from_pretrained("ChevalierJoseph/
|
| 23 |
return tokenizer, model
|
| 24 |
|
| 25 |
# ------------------------
|
|
@@ -80,43 +81,119 @@ def build_ufo_from_glyphs(glyphs):
|
|
| 80 |
font = Font()
|
| 81 |
font.info.familyName = "TipTopType"
|
| 82 |
font.info.styleName = "Regular"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
for letter, path_data in glyphs:
|
| 84 |
glyph = Glyph()
|
| 85 |
glyph.name = letter
|
| 86 |
glyph.unicode = ord(letter)
|
| 87 |
pen = glyph.getPen()
|
|
|
|
| 88 |
try:
|
|
|
|
| 89 |
path = parse_path(path_data)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 90 |
for segment in path:
|
| 91 |
if segment.length() == 0:
|
| 92 |
continue
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
|
|
|
|
|
|
| 97 |
if isinstance(segment, Line):
|
| 98 |
-
|
| 99 |
-
pen.lineTo(end_point)
|
| 100 |
elif isinstance(segment, CubicBezier):
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
|
|
|
|
|
|
| 105 |
elif isinstance(segment, QuadraticBezier):
|
| 106 |
# Convertir la courbe quadratique en courbe cubique
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
elif isinstance(segment, Arc):
|
| 111 |
-
#
|
| 112 |
-
# Pour simplifier, nous allons approximer avec une ligne droite
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
print(f"Glyph {letter} created with SVG path.")
|
| 118 |
except Exception as e:
|
| 119 |
print(f"Error injecting SVG for {letter}: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
font.insertGlyph(glyph)
|
| 121 |
print(f"Total glyphs in font: {len(font)}")
|
| 122 |
return font
|
|
|
|
| 13 |
from defcon import Font, Glyph
|
| 14 |
from fontTools.pens.svgPathPen import SVGPathPen
|
| 15 |
from svgpathtools import parse_path, Path, Line, CubicBezier, QuadraticBezier, Arc
|
| 16 |
+
from svgpathtools.path import Path as SvgPath
|
| 17 |
|
| 18 |
# ------------------------
|
| 19 |
# MODELE
|
| 20 |
# ------------------------
|
| 21 |
def load_model():
|
| 22 |
+
tokenizer = AutoTokenizer.from_pretrained("ChevalierJoseph/typtop")
|
| 23 |
+
model = AutoModelForCausalLM.from_pretrained("ChevalierJoseph/typtop")
|
| 24 |
return tokenizer, model
|
| 25 |
|
| 26 |
# ------------------------
|
|
|
|
| 81 |
font = Font()
|
| 82 |
font.info.familyName = "TipTopType"
|
| 83 |
font.info.styleName = "Regular"
|
| 84 |
+
# Définir les unités par em (standard pour les polices)
|
| 85 |
+
font.info.unitsPerEm = 1000
|
| 86 |
+
# Définir d'autres propriétés de la police
|
| 87 |
+
font.info.ascender = 800
|
| 88 |
+
font.info.descender = -200
|
| 89 |
+
font.info.capHeight = 700
|
| 90 |
+
font.info.xHeight = 500
|
| 91 |
+
|
| 92 |
for letter, path_data in glyphs:
|
| 93 |
glyph = Glyph()
|
| 94 |
glyph.name = letter
|
| 95 |
glyph.unicode = ord(letter)
|
| 96 |
pen = glyph.getPen()
|
| 97 |
+
|
| 98 |
try:
|
| 99 |
+
# Analyser le chemin SVG
|
| 100 |
path = parse_path(path_data)
|
| 101 |
+
|
| 102 |
+
# Créer un nouveau chemin SVG pour normaliser et simplifier
|
| 103 |
+
normalized_path = SvgPath()
|
| 104 |
+
|
| 105 |
for segment in path:
|
| 106 |
if segment.length() == 0:
|
| 107 |
continue
|
| 108 |
+
|
| 109 |
+
# Commencer un nouveau sous-chemin
|
| 110 |
+
if not normalized_path or not normalized_path[-1].end == segment.start:
|
| 111 |
+
normalized_path.append(Line(start=segment.start, end=segment.start))
|
| 112 |
+
|
| 113 |
+
# Ajouter le segment au chemin normalisé
|
| 114 |
if isinstance(segment, Line):
|
| 115 |
+
normalized_path.append(Line(start=normalized_path[-1].end, end=segment.end))
|
|
|
|
| 116 |
elif isinstance(segment, CubicBezier):
|
| 117 |
+
normalized_path.append(CubicBezier(
|
| 118 |
+
start=normalized_path[-1].end,
|
| 119 |
+
control1=segment.control1,
|
| 120 |
+
control2=segment.control2,
|
| 121 |
+
end=segment.end
|
| 122 |
+
))
|
| 123 |
elif isinstance(segment, QuadraticBezier):
|
| 124 |
# Convertir la courbe quadratique en courbe cubique
|
| 125 |
+
start = normalized_path[-1].end
|
| 126 |
+
end = segment.end
|
| 127 |
+
control = segment.control
|
| 128 |
+
# Approximation simple: diviser la courbe quadratique en deux segments cubiques
|
| 129 |
+
control1 = start + (control - start) * 2/3
|
| 130 |
+
control2 = end + (control - end) * 2/3
|
| 131 |
+
normalized_path.append(CubicBezier(
|
| 132 |
+
start=start,
|
| 133 |
+
control1=control1,
|
| 134 |
+
control2=control2,
|
| 135 |
+
end=end
|
| 136 |
+
))
|
| 137 |
elif isinstance(segment, Arc):
|
| 138 |
+
# Convertir l'arc en une série de courbes cubiques
|
| 139 |
+
# Pour simplifier, nous allons approximer l'arc avec une ligne droite
|
| 140 |
+
normalized_path.append(Line(start=normalized_path[-1].end, end=segment.end))
|
| 141 |
+
|
| 142 |
+
# Dessiner le chemin normalisé dans le glyphe
|
| 143 |
+
if normalized_path:
|
| 144 |
+
# Calculer les limites du chemin pour centrer et mettre à l'échelle
|
| 145 |
+
bounds = normalized_path.bbox()
|
| 146 |
+
if bounds and (bounds.width > 0) and (bounds.height > 0):
|
| 147 |
+
# Définir la largeur du glyphe (par exemple, 80% de 1000 unités)
|
| 148 |
+
glyph_width = 800
|
| 149 |
+
glyph_height = 1000 # unités par em
|
| 150 |
+
|
| 151 |
+
# Calculer le facteur d'échelle pour que le glyphe tienne dans la hauteur
|
| 152 |
+
scale_factor = glyph_height * 0.8 / bounds.height
|
| 153 |
+
# Calculer le décalage pour centrer le glyphe horizontalement
|
| 154 |
+
offset_x = (glyph_width - bounds.width * scale_factor) / 2
|
| 155 |
+
offset_y = -bounds.bottom * scale_factor # décalage pour positionner la base sur la ligne de base
|
| 156 |
+
|
| 157 |
+
# Appliquer la transformation aux points du chemin
|
| 158 |
+
for segment in normalized_path:
|
| 159 |
+
# Appliquer la transformation aux points du segment
|
| 160 |
+
def transform_point(point):
|
| 161 |
+
x = point.real
|
| 162 |
+
y = point.imag
|
| 163 |
+
# Appliquer la mise à l'échelle et le décalage
|
| 164 |
+
new_x = x * scale_factor + offset_x
|
| 165 |
+
new_y = y * scale_factor + offset_y
|
| 166 |
+
return (new_x, -new_y) # Inverser Y car les systèmes de coordonnées sont différents
|
| 167 |
+
|
| 168 |
+
start_point = transform_point(segment.start)
|
| 169 |
+
if len(normalized_path) == 1 or segment == normalized_path[0]:
|
| 170 |
+
pen.moveTo(start_point)
|
| 171 |
+
|
| 172 |
+
if isinstance(segment, Line):
|
| 173 |
+
end_point = transform_point(segment.end)
|
| 174 |
+
pen.lineTo(end_point)
|
| 175 |
+
elif isinstance(segment, CubicBezier):
|
| 176 |
+
control1 = transform_point(segment.control1)
|
| 177 |
+
control2 = transform_point(segment.control2)
|
| 178 |
+
end_point = transform_point(segment.end)
|
| 179 |
+
pen.curveTo(control1, control2, end_point)
|
| 180 |
+
|
| 181 |
+
# Fermer le chemin si nécessaire
|
| 182 |
+
if normalized_path.isclosed():
|
| 183 |
+
pen.closePath()
|
| 184 |
+
|
| 185 |
+
# Définir la largeur du glyphe
|
| 186 |
+
glyph.width = glyph_width
|
| 187 |
print(f"Glyph {letter} created with SVG path.")
|
| 188 |
except Exception as e:
|
| 189 |
print(f"Error injecting SVG for {letter}: {e}")
|
| 190 |
+
# En cas d'erreur, dessiner un rectangle pour visualiser le problème
|
| 191 |
+
pen.moveTo((100, 0))
|
| 192 |
+
pen.lineTo((900, 0))
|
| 193 |
+
pen.lineTo((900, 1000))
|
| 194 |
+
pen.lineTo((100, 1000))
|
| 195 |
+
pen.closePath()
|
| 196 |
+
glyph.width = 1000
|
| 197 |
font.insertGlyph(glyph)
|
| 198 |
print(f"Total glyphs in font: {len(font)}")
|
| 199 |
return font
|