ChevalierJoseph commited on
Commit
43c3d14
·
verified ·
1 Parent(s): 0b0a809

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +36 -81
app.py CHANGED
@@ -10,7 +10,7 @@ import tempfile
10
  import os
11
  import glob
12
  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
  from svgpathtools.path import Path as SvgPath
@@ -89,9 +89,7 @@ def build_ufo_from_glyphs(glyphs):
89
  font = Font()
90
  font.info.familyName = "TipTopType"
91
  font.info.styleName = "Regular"
92
- # Définir les unités par em (standard pour les polices)
93
  font.info.unitsPerEm = 1000
94
- # Définir d'autres propriétés de la police
95
  font.info.ascender = 800
96
  font.info.descender = -200
97
  font.info.capHeight = 700
@@ -105,91 +103,54 @@ def build_ufo_from_glyphs(glyphs):
105
  glyph.unicode = ord(letter)
106
  pen = glyph.getPen()
107
  try:
108
- # Analyser le chemin SVG
109
  path = parse_path(path_data)
110
- # Créer un nouveau chemin SVG pour normaliser et simplifier
111
- normalized_path = SvgPath()
112
  for segment in path:
113
  if segment.length() == 0:
114
  continue
115
- # Commencer un nouveau sous-chemin
116
- if not normalized_path or not normalized_path[-1].end == segment.start:
117
- normalized_path.append(Line(start=segment.start, end=segment.start))
118
- # Ajouter le segment au chemin normalisé
119
- if isinstance(segment, Line):
120
- normalized_path.append(Line(start=normalized_path[-1].end, end=segment.end))
121
- elif isinstance(segment, CubicBezier):
122
- normalized_path.append(CubicBezier(
123
- start=normalized_path[-1].end,
124
- control1=segment.control1,
125
- control2=segment.control2,
126
- end=segment.end
127
- ))
128
- elif isinstance(segment, QuadraticBezier):
129
- # Convertir la courbe quadratique en courbe cubique
130
- start = normalized_path[-1].end
131
- end = segment.end
132
- control = segment.control
133
- # Approximation simple: diviser la courbe quadratique en deux segments cubiques
134
- control1 = start + (control - start) * 2/3
135
- control2 = end + (control - end) * 2/3
136
- normalized_path.append(CubicBezier(
137
- start=start,
138
- control1=control1,
139
- control2=control2,
140
- end=end
141
- ))
142
- elif isinstance(segment, Arc):
143
- # Convertir l'arc en une série de courbes cubiques
144
- # Pour simplifier, nous allons approximer l'arc avec une ligne droite
145
- normalized_path.append(Line(start=normalized_path[-1].end, end=segment.end))
146
- # Dessiner le chemin normalisé dans le glyphe
147
  if normalized_path:
148
- # Calculer les limites du chemin pour centrer et mettre à l'échelle
149
- bounds = normalized_path.bbox()
 
 
 
 
150
  if bounds and (bounds.width > 0) and (bounds.height > 0):
151
- # Définir la largeur du glyphe (par exemple, 80% de 1000 unités)
152
  glyph_width = 800
153
- glyph_height = 1000 # unités par em
154
- # Calculer le facteur d'échelle pour que le glyphe tienne dans la hauteur
155
  scale_factor = glyph_height * 0.8 / bounds.height
156
- # Calculer le décalage pour centrer le glyphe horizontalement
157
  offset_x = (glyph_width - bounds.width * scale_factor) / 2
158
- offset_y = -bounds.bottom * scale_factor # décalage pour positionner la base sur la ligne de base
159
- # Appliquer la transformation aux points du chemin
160
- for segment in normalized_path:
161
- # Appliquer la transformation aux points du segment
162
- def transform_point(point):
163
- x = point.real
164
- y = point.imag
165
- # Appliquer la mise à l'échelle et le décalage
166
- new_x = x * scale_factor + offset_x
167
- new_y = y * scale_factor + offset_y
168
- return (new_x, -new_y) # Inverser Y car les systèmes de coordonnées sont différents
169
- start_point = transform_point(segment.start)
170
- if len(normalized_path) == 1 or segment == normalized_path[0]:
171
- pen.moveTo(start_point)
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
- # Fermer le chemin si nécessaire
181
- if normalized_path.isclosed():
182
- pen.closePath()
183
- # Définir la largeur du glyphe
184
  glyph.width = glyph_width
185
  print(f"Glyph {letter} created with SVG path.")
186
  except Exception as e:
187
  print(f"Error injecting SVG for {letter}: {e}")
188
- # En cas d'erreur, dessiner un rectangle pour visualiser le problème
189
- pen.moveTo((100, 0))
190
- pen.lineTo((900, 0))
191
- pen.lineTo((900, 1000))
192
- pen.lineTo((100, 1000))
193
  pen.closePath()
194
  glyph.width = 1000
195
  font.insertGlyph(glyph)
@@ -206,26 +167,20 @@ def save_otf_font(glyphs, font_name="TipTopType-Regular.otf"):
206
  font = build_ufo_from_glyphs(glyphs)
207
  font.save(ufo_path)
208
  print(f"UFO file saved at: {ufo_path}")
209
-
210
  output_dir = os.path.join(tmpdir, "out")
211
  os.makedirs(output_dir, exist_ok=True)
212
-
213
  project = FontProject()
214
  project.run_from_ufos([ufo_path], output=["otf"], output_dir=output_dir)
215
  print("Fontmake ran successfully.")
216
-
217
  otf_files = glob.glob(os.path.join(output_dir, "**/*.otf"), recursive=True)
218
  if not otf_files:
219
  print("No OTF files generated by fontmake.")
220
  return None
221
-
222
  generated_path = otf_files[0]
223
  print(f"OTF file generated at: {generated_path}")
224
-
225
  final_path = os.path.join(tempfile.gettempdir(), font_name)
226
  os.replace(generated_path, final_path)
227
  print(f"OTF file moved to: {final_path}")
228
-
229
  return final_path
230
  except Exception as e:
231
  print(f"Error in save_otf_font: {e}")
 
10
  import os
11
  import glob
12
  from fontmake.font_project import FontProject
13
+ from defcon import Font, Glyph, Point
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
 
89
  font = Font()
90
  font.info.familyName = "TipTopType"
91
  font.info.styleName = "Regular"
 
92
  font.info.unitsPerEm = 1000
 
93
  font.info.ascender = 800
94
  font.info.descender = -200
95
  font.info.capHeight = 700
 
103
  glyph.unicode = ord(letter)
104
  pen = glyph.getPen()
105
  try:
 
106
  path = parse_path(path_data)
107
+ normalized_path = []
 
108
  for segment in path:
109
  if segment.length() == 0:
110
  continue
111
+ normalized_path.append(segment)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  if normalized_path:
113
+ bounds = None
114
+ for segment in normalized_path:
115
+ if bounds is None:
116
+ bounds = segment.bbox()
117
+ else:
118
+ bounds |= segment.bbox()
119
  if bounds and (bounds.width > 0) and (bounds.height > 0):
 
120
  glyph_width = 800
121
+ glyph_height = 1000
 
122
  scale_factor = glyph_height * 0.8 / bounds.height
 
123
  offset_x = (glyph_width - bounds.width * scale_factor) / 2
124
+ offset_y = -bounds.bottom * scale_factor
125
+ def transform_point(point):
126
+ x = point.real
127
+ y = point.imag
128
+ new_x = x * scale_factor + offset_x
129
+ new_y = y * scale_factor + offset_y
130
+ return Point((new_x, -new_y))
131
+ if normalized_path:
132
+ start_segment = normalized_path[0]
133
+ start_point = transform_point(start_segment.start)
134
+ pen.moveTo(start_point)
135
+ for segment in normalized_path:
136
+ if isinstance(segment, Line):
137
+ end_point = transform_point(segment.end)
138
+ pen.lineTo(end_point)
139
+ elif isinstance(segment, CubicBezier):
140
+ control1 = transform_point(segment.control1)
141
+ control2 = transform_point(segment.control2)
142
+ end_point = transform_point(segment.end)
143
+ pen.curveTo(control1, control2, end_point)
144
+ if normalized_path and normalized_path[-1].end == normalized_path[0].start:
145
+ pen.closePath()
 
 
 
 
146
  glyph.width = glyph_width
147
  print(f"Glyph {letter} created with SVG path.")
148
  except Exception as e:
149
  print(f"Error injecting SVG for {letter}: {e}")
150
+ pen.moveTo(Point((100, 0)))
151
+ pen.lineTo(Point((900, 0)))
152
+ pen.lineTo(Point((900, 1000)))
153
+ pen.lineTo(Point((100, 1000)))
 
154
  pen.closePath()
155
  glyph.width = 1000
156
  font.insertGlyph(glyph)
 
167
  font = build_ufo_from_glyphs(glyphs)
168
  font.save(ufo_path)
169
  print(f"UFO file saved at: {ufo_path}")
 
170
  output_dir = os.path.join(tmpdir, "out")
171
  os.makedirs(output_dir, exist_ok=True)
 
172
  project = FontProject()
173
  project.run_from_ufos([ufo_path], output=["otf"], output_dir=output_dir)
174
  print("Fontmake ran successfully.")
 
175
  otf_files = glob.glob(os.path.join(output_dir, "**/*.otf"), recursive=True)
176
  if not otf_files:
177
  print("No OTF files generated by fontmake.")
178
  return None
 
179
  generated_path = otf_files[0]
180
  print(f"OTF file generated at: {generated_path}")
 
181
  final_path = os.path.join(tempfile.gettempdir(), font_name)
182
  os.replace(generated_path, final_path)
183
  print(f"OTF file moved to: {final_path}")
 
184
  return final_path
185
  except Exception as e:
186
  print(f"Error in save_otf_font: {e}")