bkhmsi commited on
Commit
f265950
1 Parent(s): bf0a375

now supports any font

Browse files
.gitattributes CHANGED
@@ -32,3 +32,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
32
  *.zip filter=lfs diff=lfs merge=lfs -text
33
  *.zst filter=lfs diff=lfs merge=lfs -text
34
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
32
  *.zip filter=lfs diff=lfs merge=lfs -text
33
  *.zst filter=lfs diff=lfs merge=lfs -text
34
  *tfevents* filter=lfs diff=lfs merge=lfs -text
35
+ code/data/fonts/chinese/ZhiMangXing-Regular.ttf filter=lfs diff=lfs merge=lfs -text
app.py CHANGED
@@ -9,6 +9,7 @@ import numpy.random as npr
9
  import sys
10
  import imageio
11
  import numpy as np
 
12
 
13
  # sys.path.append('./code')
14
 
@@ -32,7 +33,7 @@ from diffusers import StableDiffusionPipeline
32
  device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
33
 
34
  model = None
35
- model = StableDiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5").to(device)
36
 
37
  from typing import Mapping
38
  from tqdm import tqdm
@@ -52,11 +53,11 @@ from utils import (
52
  combine_word)
53
  import warnings
54
 
55
- TITLE="""<h1 style="font-size: 42px;" align="center">Word-To-Image: Morphing Arabic Text to a Visual Representation</h1>"""
56
 
57
 
58
- DESCRIPTION="""This demo builds on the [Word-As-Image for Semantic Typography](https://wordasimage.github.io/Word-As-Image-Page/) work to support Arabic fonts and morphing whole words and phrases to a visual representation of a semantic concept. This is part of an ongoing effort with the [ARBML](https://arbml.github.io/website/) community to build open-source Arabic tools using machine learning."""
59
-
60
  # DESCRIPTION += '\n<p>This demo is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"> Creative Commons Attribution-ShareAlike 4.0 International License</a>.</p>'
61
  DESCRIPTION += '\n<p>Note: it takes about 5 minutes for 250 iterations to generate the final GIF. For faster inference without waiting in queue, you can <a href="https://colab.research.google.com/drive/1wobOAsnLpkIzaRxG5yac8NcV7iCrlycP"><img style="display: inline; margin-top: 0em; margin-bottom: 0em" src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a></p>'
62
 
@@ -66,8 +67,7 @@ if (SPACE_ID := os.getenv('SPACE_ID')) is not None:
66
  else:
67
  DESCRIPTION = DESCRIPTION.replace("either", "")
68
 
69
- DESCRIPTION += "<img src='https://raw.githubusercontent.com/BKHMSI/Word-As-Image-Ar/main/collage.gif' alt='Example of Outputs'/>"
70
-
71
 
72
  warnings.filterwarnings("ignore")
73
 
@@ -75,11 +75,11 @@ pydiffvg.set_print_timing(False)
75
  gamma = 1.0
76
 
77
 
78
- def set_config(semantic_concept, word, prompt_suffix, font_name, num_steps, seed, dist_loss_weight, pixel_dist_kernel_blur, pixel_dist_sigma, angeles_w):
79
 
80
  cfg_d = edict()
81
  cfg_d.config = "code/config/base.yaml"
82
- cfg_d.experiment = "demo"
83
 
84
  with open(cfg_d.config, 'r') as f:
85
  cfg_full = yaml.load(f, Loader=yaml.FullLoader)
@@ -99,8 +99,18 @@ def set_config(semantic_concept, word, prompt_suffix, font_name, num_steps, seed
99
  cfg.prompt_suffix = prompt_suffix
100
  cfg.word = word
101
  cfg.optimized_letter = word
102
- cfg.font = font_name
103
- cfg.seed = int(seed)
 
 
 
 
 
 
 
 
 
 
104
  cfg.num_iter = num_steps
105
  cfg.batch_size = 1
106
  cfg.loss.tone.dist_loss_weight = int(dist_loss_weight)
@@ -110,7 +120,7 @@ def set_config(semantic_concept, word, prompt_suffix, font_name, num_steps, seed
110
 
111
 
112
  cfg.caption = f"a {cfg.semantic_concept}. {cfg.prompt_suffix}"
113
- cfg.log_dir = f"output/{cfg.experiment}_{cfg.word}"
114
  if cfg.optimized_letter in cfg.word:
115
  cfg.optimized_letter = cfg.optimized_letter
116
  else:
@@ -120,12 +130,14 @@ def set_config(semantic_concept, word, prompt_suffix, font_name, num_steps, seed
120
  # cfg.optimized_letter = cfg.optimized_letter.replace(' ', '_')
121
 
122
  cfg.letter = f"{cfg.font}_{cfg.optimized_letter}_scaled"
123
- cfg.target = f"code/data/init/{cfg.letter.replace(' ', '_')}"
 
 
124
 
125
  # set experiment dir
126
- signature = f"{cfg.letter}_concept_{cfg.semantic_concept}_seed_{cfg.seed}"
127
- cfg.experiment_dir = \
128
- osp.join(cfg.log_dir, cfg.font, signature)
129
  configfile = osp.join(cfg.experiment_dir, 'config.yaml')
130
 
131
  # create experiment dir and save config
@@ -159,14 +171,14 @@ def init_shapes(svg_path, trainable: Mapping[str, bool]):
159
  return shapes_init, shape_groups_init, parameters
160
 
161
 
162
- def run_main_ex(word, semantic_concept, num_steps, seed):
163
  prompt_suffix = "minimal flat 2d vector. lineal color. trending on artstation"
164
- font_name = "ArefRuqaa"
165
- return list(next(run_main_app(semantic_concept, word, prompt_suffix, font_name, num_steps, seed, 100, 201, 30, 0.5, 0)))
166
 
167
- def run_main_app(semantic_concept, word, prompt_suffix, font_name, num_steps, seed, dist_loss_weight, pixel_dist_kernel_blur, pixel_dist_sigma, angeles_w, example=0):
168
 
169
- cfg = set_config(semantic_concept, word, prompt_suffix, font_name, num_steps, seed, dist_loss_weight, pixel_dist_kernel_blur, pixel_dist_sigma, angeles_w)
170
 
171
  pydiffvg.set_use_gpu(torch.cuda.is_available())
172
 
@@ -174,7 +186,7 @@ def run_main_app(semantic_concept, word, prompt_suffix, font_name, num_steps, se
174
  preprocess(cfg.font, cfg.word, cfg.optimized_letter, cfg.level_of_cc)
175
  filename_init = os.path.join("code/data/init/", f"{cfg.font}_{cfg.word}_scaled.svg").replace(" ", "_")
176
  if not example:
177
- yield gr.update(value=filename_init,visible=True),gr.update(visible=True, label='Initializing'),gr.update(visible=False)
178
 
179
  sds_loss = SDSLoss(cfg, device, model)
180
 
@@ -234,7 +246,7 @@ def run_main_app(semantic_concept, word, prompt_suffix, font_name, num_steps, se
234
  check_and_create_dir(filename)
235
  save_svg.save_svg(filename, w, h, shapes, shape_groups)
236
  if not example:
237
- yield gr.update(visible=True),gr.update(value=filename, label=f'iters: {step} / {num_iter}', visible=True),gr.update(visible=False)
238
 
239
  x = img.unsqueeze(0).permute(0, 3, 1, 2) # HWC -> NCHW
240
  x = x.repeat(cfg.batch_size, 1, 1, 1)
@@ -269,14 +281,9 @@ def run_main_app(semantic_concept, word, prompt_suffix, font_name, num_steps, se
269
  # writer.close()
270
  imageio.mimsave(filename, np.array(gif_frames).astype(np.uint8))
271
 
272
- yield gr.update(value=filename_init,visible=True),gr.update(visible=False),gr.update(value=filename,visible=True)
273
 
274
 
275
- def change_prompt(concept, prompt_suffix):
276
- if concept == "":
277
- concept = "{concept}"
278
- return f"a {concept}. {prompt_suffix}"
279
-
280
  with gr.Blocks() as demo:
281
 
282
  gr.HTML(TITLE)
@@ -289,14 +296,20 @@ with gr.Blocks() as demo:
289
  label='Text',
290
  max_lines=1,
291
  placeholder=
292
- 'Enter text. For example: حصان'
293
  )
294
 
295
  semantic_concept = gr.Text(
296
  label='Concept',
297
  max_lines=1,
298
  placeholder=
299
- 'Enter a semantic concept that you want your text to morph into (in English). For example: horse'
 
 
 
 
 
 
300
  )
301
 
302
 
@@ -306,20 +319,17 @@ with gr.Blocks() as demo:
306
  value="minimal flat 2d vector. lineal color. trending on artstation"
307
  )
308
 
309
- prompt = gr.Text(
310
- label='Prompt',
311
- max_lines=1,
312
- value="a {concept}. minimal flat 2d vector. lineal color. trending on artstation."
313
- )
314
-
315
  with gr.Row():
316
 
317
  with gr.Accordion("Advanced Parameters", open=False, visible=True):
318
-
319
- seed = gr.Number(
320
- label='Seed',
321
- value=42
322
- )
 
 
 
323
 
324
  angeles_w = gr.Number(
325
  label='ACAP Deformation Loss Weight',
@@ -342,10 +352,6 @@ with gr.Blocks() as demo:
342
  )
343
 
344
 
345
-
346
- semantic_concept.change(change_prompt, [semantic_concept, prompt_suffix], prompt)
347
- prompt_suffix.change(change_prompt, [semantic_concept, prompt_suffix], prompt)
348
-
349
  num_steps = gr.Slider(label='Optimization Iterations',
350
  minimum=0,
351
  maximum=500,
@@ -363,6 +369,23 @@ with gr.Blocks() as demo:
363
  run = gr.Button('Generate')
364
 
365
  with gr.Column():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
366
  result0 = gr.Image(type="filepath", label="Initial Word").style(height=250)
367
  result1 = gr.Image(type="filepath", label="Optimization Process").style(height=300)
368
  result2 = gr.Image(type="filepath", label="Final GIF",visible=False).style(height=300)
@@ -371,16 +394,19 @@ with gr.Blocks() as demo:
371
  with gr.Row():
372
  # examples
373
  examples = [
374
- ["قطة", "Cat", 250, 42],
375
- ["جمل جميل", "Camel", 250, 42],
376
- ["كلب", "Dog", 250, 42],
377
- ["أخطبوط", "Octopus", 250, 42],
 
378
  ]
379
- demo.queue(max_size=10, concurrency_count=1)
 
380
  gr.Examples(examples=examples,
381
  inputs=[
382
  word,
383
  semantic_concept,
 
384
  num_steps,
385
  seed
386
  ],
@@ -397,10 +423,12 @@ with gr.Blocks() as demo:
397
  inputs = [
398
  semantic_concept,
399
  word,
 
400
  prompt_suffix,
401
  font_name,
402
  num_steps,
403
  seed,
 
404
  dist_loss_weight,
405
  pixel_dist_kernel_blur,
406
  pixel_dist_sigma,
@@ -410,7 +438,9 @@ with gr.Blocks() as demo:
410
  outputs = [
411
  result0,
412
  result1,
413
- result2
 
 
414
  ]
415
 
416
  run.click(fn=run_main_app, inputs=inputs, outputs=outputs, queue=True)
 
9
  import sys
10
  import imageio
11
  import numpy as np
12
+ from glob import glob
13
 
14
  # sys.path.append('./code')
15
 
 
33
  device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
34
 
35
  model = None
36
+ model = StableDiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5", torch_dtype=torch.float16).to(device)
37
 
38
  from typing import Mapping
39
  from tqdm import tqdm
 
53
  combine_word)
54
  import warnings
55
 
56
+ TITLE="""<h1 style="font-size: 42px;" align="center">Font-To-Sketch: Morphing Any Font to a Visual Representation</h1>"""
57
 
58
 
59
+ DESCRIPTION="""This demo builds on the [Word-As-Image for Semantic Typography](https://wordasimage.github.io/Word-As-Image-Page/) work to support **any** font and morphing whole words and phrases to a visual representation of a given semantic concept. This project started as part of an ongoing effort with the [ARBML](https://arbml.github.io/website/) community to build open-source Arabic tools using machine learning."""
60
+ DESCRIPTION+="""The demo currently supports the following scripts: **Arabic**, **Simplified Chinese**, **Cyrillic**, **Greek**, **Latin**, **Tamil**. Therefore you can write the text in any language using those scripts. To add support for more fonts please check the [GitHub ReadMe](https://raw.githubusercontent.com/BKHMSI/Font-To-Sketch)."""
61
  # DESCRIPTION += '\n<p>This demo is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"> Creative Commons Attribution-ShareAlike 4.0 International License</a>.</p>'
62
  DESCRIPTION += '\n<p>Note: it takes about 5 minutes for 250 iterations to generate the final GIF. For faster inference without waiting in queue, you can <a href="https://colab.research.google.com/drive/1wobOAsnLpkIzaRxG5yac8NcV7iCrlycP"><img style="display: inline; margin-top: 0em; margin-bottom: 0em" src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a></p>'
63
 
 
67
  else:
68
  DESCRIPTION = DESCRIPTION.replace("either", "")
69
 
70
+ DESCRIPTION += "<img src='https://raw.githubusercontent.com/BKHMSI/Font-To-Sketch/main/images/animals_7.gif' alt='Example of Outputs'/>"
 
71
 
72
  warnings.filterwarnings("ignore")
73
 
 
75
  gamma = 1.0
76
 
77
 
78
+ def set_config(semantic_concept, word, script, prompt_suffix, font_name, num_steps, seed, is_seed_rand, dist_loss_weight, pixel_dist_kernel_blur, pixel_dist_sigma, angeles_w):
79
 
80
  cfg_d = edict()
81
  cfg_d.config = "code/config/base.yaml"
82
+ cfg_d.experiment = "default"
83
 
84
  with open(cfg_d.config, 'r') as f:
85
  cfg_full = yaml.load(f, Loader=yaml.FullLoader)
 
99
  cfg.prompt_suffix = prompt_suffix
100
  cfg.word = word
101
  cfg.optimized_letter = word
102
+ cfg.script = script.lower()
103
+
104
+ script_path = f"code/data/fonts/{cfg.script}"
105
+ if cfg.font == "none":
106
+ cfg.font = osp.basename(glob(f"{script_path}/*.ttf")[0])[:-4]
107
+
108
+ if is_seed_rand == "Random Seed":
109
+ cfg.seed = np.random.randint(10000)
110
+ else:
111
+ cfg.seed = int(seed)
112
+
113
+
114
  cfg.num_iter = num_steps
115
  cfg.batch_size = 1
116
  cfg.loss.tone.dist_loss_weight = int(dist_loss_weight)
 
120
 
121
 
122
  cfg.caption = f"a {cfg.semantic_concept}. {cfg.prompt_suffix}"
123
+ cfg.log_dir = f"{cfg.script}"
124
  if cfg.optimized_letter in cfg.word:
125
  cfg.optimized_letter = cfg.optimized_letter
126
  else:
 
130
  # cfg.optimized_letter = cfg.optimized_letter.replace(' ', '_')
131
 
132
  cfg.letter = f"{cfg.font}_{cfg.optimized_letter}_scaled"
133
+ cfg.target = f"code/data/init/{cfg.letter}"
134
+ if ' ' in cfg.target:
135
+ cfg.target = cfg.target.replace(' ', '_')
136
 
137
  # set experiment dir
138
+ signature = f"{cfg.word}_{cfg.semantic_concept}_{cfg.seed}"
139
+
140
+ cfg.experiment_dir = osp.join(cfg.log_dir, cfg.font, signature)
141
  configfile = osp.join(cfg.experiment_dir, 'config.yaml')
142
 
143
  # create experiment dir and save config
 
171
  return shapes_init, shape_groups_init, parameters
172
 
173
 
174
+ def run_main_ex(word, semantic_concept, script, num_steps, seed):
175
  prompt_suffix = "minimal flat 2d vector. lineal color. trending on artstation"
176
+ is_seed_rand = "Use Set Value"
177
+ return list(next(run_main_app(semantic_concept, word, script, prompt_suffix, font_name, num_steps, seed, is_seed_rand, 100, 201, 30, 0.5, 0)))
178
 
179
+ def run_main_app(semantic_concept, word, script, prompt_suffix, font_name, num_steps, seed, is_seed_rand, dist_loss_weight, pixel_dist_kernel_blur, pixel_dist_sigma, angeles_w, example=0):
180
 
181
+ cfg = set_config(semantic_concept, word, script, prompt_suffix, font_name, num_steps, seed, is_seed_rand, dist_loss_weight, pixel_dist_kernel_blur, pixel_dist_sigma, angeles_w)
182
 
183
  pydiffvg.set_use_gpu(torch.cuda.is_available())
184
 
 
186
  preprocess(cfg.font, cfg.word, cfg.optimized_letter, cfg.level_of_cc)
187
  filename_init = os.path.join("code/data/init/", f"{cfg.font}_{cfg.word}_scaled.svg").replace(" ", "_")
188
  if not example:
189
+ yield gr.update(value=filename_init,visible=True),gr.update(visible=True, label='Initializing'),gr.update(visible=False),gr.update(value=cfg.caption,visible=True),gr.update(value=cfg.seed,visible=True)
190
 
191
  sds_loss = SDSLoss(cfg, device, model)
192
 
 
246
  check_and_create_dir(filename)
247
  save_svg.save_svg(filename, w, h, shapes, shape_groups)
248
  if not example:
249
+ yield gr.update(visible=True),gr.update(value=filename, label=f'iters: {step} / {num_iter}', visible=True),gr.update(visible=False),gr.update(value=cfg.caption,visible=True),gr.update(value=cfg.seed,visible=True)
250
 
251
  x = img.unsqueeze(0).permute(0, 3, 1, 2) # HWC -> NCHW
252
  x = x.repeat(cfg.batch_size, 1, 1, 1)
 
281
  # writer.close()
282
  imageio.mimsave(filename, np.array(gif_frames).astype(np.uint8))
283
 
284
+ yield gr.update(value=filename_init,visible=True),gr.update(visible=False),gr.update(value=filename,visible=True),gr.update(value=cfg.caption,visible=True),gr.update(value=cfg.seed,visible=True)
285
 
286
 
 
 
 
 
 
287
  with gr.Blocks() as demo:
288
 
289
  gr.HTML(TITLE)
 
296
  label='Text',
297
  max_lines=1,
298
  placeholder=
299
+ 'Enter text. For example: قطة|猫|γάτα|кошка|பூனை|Cat'
300
  )
301
 
302
  semantic_concept = gr.Text(
303
  label='Concept',
304
  max_lines=1,
305
  placeholder=
306
+ 'Enter a semantic concept that you want your text to morph into (in English). For example: cat'
307
+ )
308
+
309
+ script = gr.Dropdown(
310
+ ["Arabic", "Simplified Chinese", "Cyrillic", "Greek", "Latin", "Tamil"],
311
+ value="Arabic",
312
+ label="Font Script"
313
  )
314
 
315
 
 
319
  value="minimal flat 2d vector. lineal color. trending on artstation"
320
  )
321
 
 
 
 
 
 
 
322
  with gr.Row():
323
 
324
  with gr.Accordion("Advanced Parameters", open=False, visible=True):
325
+
326
+ with gr.Row():
327
+ is_seed_rand = gr.Radio(["Random Seed", "Use Set Value"], label="Use Random Seed", value="Random Seed")
328
+
329
+ seed = gr.Number(
330
+ label='Seed (Set Value)',
331
+ value=42
332
+ )
333
 
334
  angeles_w = gr.Number(
335
  label='ACAP Deformation Loss Weight',
 
352
  )
353
 
354
 
 
 
 
 
355
  num_steps = gr.Slider(label='Optimization Iterations',
356
  minimum=0,
357
  maximum=500,
 
369
  run = gr.Button('Generate')
370
 
371
  with gr.Column():
372
+
373
+ with gr.Row():
374
+ prompt = gr.Text(
375
+ label='Prompt',
376
+ visible=False,
377
+ max_lines=1,
378
+ interactive=False,
379
+ )
380
+
381
+ seed_value = gr.Text(
382
+ label='Seed Used',
383
+ visible=False,
384
+ max_lines=1,
385
+ interactive=False,
386
+ )
387
+
388
+
389
  result0 = gr.Image(type="filepath", label="Initial Word").style(height=250)
390
  result1 = gr.Image(type="filepath", label="Optimization Process").style(height=300)
391
  result2 = gr.Image(type="filepath", label="Final GIF",visible=False).style(height=300)
 
394
  with gr.Row():
395
  # examples
396
  examples = [
397
+ ["قطة", "Cat", "Arabic", 250, 42],
398
+ ["猫", "Cat", "Simplified Chinese", 250, 42],
399
+ ["γάτα", "Cat", "Greek", 250, 42],
400
+ ["кошка", "Cat", "Cyrillic", 250, 42],
401
+ ["பூனை", "Cat", "Tamil", 250, 42],
402
  ]
403
+
404
+ demo.queue(max_size=10, concurrency_count=2)
405
  gr.Examples(examples=examples,
406
  inputs=[
407
  word,
408
  semantic_concept,
409
+ script,
410
  num_steps,
411
  seed
412
  ],
 
423
  inputs = [
424
  semantic_concept,
425
  word,
426
+ script,
427
  prompt_suffix,
428
  font_name,
429
  num_steps,
430
  seed,
431
+ is_seed_rand,
432
  dist_loss_weight,
433
  pixel_dist_kernel_blur,
434
  pixel_dist_sigma,
 
438
  outputs = [
439
  result0,
440
  result1,
441
+ result2,
442
+ prompt,
443
+ seed_value
444
  ]
445
 
446
  run.click(fn=run_main_app, inputs=inputs, outputs=outputs, queue=True)
code/collage.py CHANGED
@@ -2,40 +2,52 @@ import os
2
  import imageio
3
  import numpy as np
4
  from glob import glob
5
- from PIL import Image, ImageSequence
 
6
 
7
  if __name__ == "__main__":
8
 
9
  path = "/Users/bkhmsi/Desktop/Animal-Words/*.gif"
10
- save_path = os.path.join(os.path.dirname(path), "collage.gif")
11
 
12
 
13
- width, height = 400, 400
 
14
  nx, ny = 5, 5
15
  n_frames = 67
16
- collage = np.ones((n_frames+10, width*nx, height*ny)).astype(np.uint8)
17
 
18
- filenames = [p for p in glob(path) if os.path.basename(p)[:-4] not in ["palestine", "amin", "collage"]]
19
  print(f"> {len(filenames)} Files Found")
20
- for file in filenames:
21
- print(os.path.basename(file))
22
 
23
- assert nx*ny <= len(filenames)
 
 
 
 
 
 
 
 
24
 
25
  for i in range(nx):
26
- for j in range(ny):
27
- image = Image.open(filenames[i*ny+j])
28
  assert image.is_animated
29
  idx = 0
30
- for frame_idx in range(image.n_frames):
31
  image.seek(frame_idx)
32
  frame = image.convert('L').copy()
33
- if frame_idx == 0 or frame_idx == image.n_frames-1:
34
- for _ in range(5):
35
- collage[idx, i*width:(i+1)*width,j*height:(j+1)*height] = np.asarray(frame)[100:500, 100:500]
36
- idx += 1
37
- else:
38
- collage[idx, i*width:(i+1)*width,j*height:(j+1)*height] = np.asarray(frame)[100:500, 100:500]
39
- idx += 1
 
 
 
 
40
 
41
  imageio.mimsave(save_path, collage)
 
2
  import imageio
3
  import numpy as np
4
  from glob import glob
5
+ from tqdm import tqdm
6
+ from PIL import Image
7
 
8
  if __name__ == "__main__":
9
 
10
  path = "/Users/bkhmsi/Desktop/Animal-Words/*.gif"
11
+ save_path = os.path.join(os.path.dirname(path), "collage_loop_25_3.gif")
12
 
13
 
14
+ width, height = 250, 250
15
+ # width, height = 100, 100
16
  nx, ny = 5, 5
17
  n_frames = 67
18
+ collage = np.ones((n_frames*2, width*nx, height*ny)).astype(np.uint8)*255
19
 
20
+ filenames = [p for p in glob(path) if os.path.basename(p)[:-4] not in ["palestine", "amin", "collage", "collage_loop_25", "collage_loop_25_2", "collage_loop_25_3a", "collage_loop_7", "collage_1d"]]
21
  print(f"> {len(filenames)} Files Found")
 
 
22
 
23
+ f_filenames = filenames
24
+ filter = ["horse.gif", "giraffe.gif", "duck.gif", "turtle.gif", "camel.gif", "octopus.gif", "shark.gif"]
25
+ # f_filenames = []
26
+ # for file in filenames:
27
+ # basename = os.path.basename(file)
28
+ # if basename in filter:
29
+ # f_filenames += [file]
30
+
31
+ assert nx*ny <= len(f_filenames)
32
 
33
  for i in range(nx):
34
+ for j in tqdm(range(ny)):
35
+ image = Image.open(f_filenames[i*ny+j])
36
  assert image.is_animated
37
  idx = 0
38
+ for frame_idx in range(n_frames):
39
  image.seek(frame_idx)
40
  frame = image.convert('L').copy()
41
+ frame = frame.resize((300,300))
42
+ collage[idx, i*width:(i+1)*width,j*height:(j+1)*height] = np.asarray(frame)[25:275, 25:275]
43
+ idx += 1
44
+
45
+ for frame_idx in reversed(range(n_frames)):
46
+ image.seek(frame_idx)
47
+ frame = image.convert('L').copy()
48
+ frame = frame.resize((300,300))
49
+ collage[idx, i*width:(i+1)*width,j*height:(j+1)*height] = np.asarray(frame)[25:275, 25:275]
50
+ idx += 1
51
+
52
 
53
  imageio.mimsave(save_path, collage)
code/collage_langs.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import imageio
3
+ import numpy as np
4
+ from glob import glob
5
+ from tqdm import tqdm
6
+ from PIL import Image, ImageDraw, ImageFont
7
+
8
+ def create_image(size, text, font):
9
+ W, H = size
10
+ image = Image.new('L', size, 255)
11
+ draw = ImageDraw.Draw(image)
12
+ _, _, w, h = draw.textbbox((0, 0), text, font=font)
13
+ draw.text(((W-w)/2, (H-h)/2), text, font=font, fill=0)
14
+ return image
15
+
16
+ if __name__ == "__main__":
17
+
18
+ languages = ['arabic', 'greek', 'chinese', 'russian', 'tamil', 'english']
19
+ scripts = ['arabic', 'greek', 'chinese', 'cyrillic', 'tamil', 'latin']
20
+ concepts = ['panda', 'car', 'music', 'bird', 'star', 'cloud']
21
+
22
+ width, height = 160, 160
23
+ n_frames = 67
24
+ freeze = 5
25
+ text_height = 40
26
+ nx, ny = len(concepts), len(scripts)
27
+ collage = np.ones((n_frames*2+freeze-1, text_height+width*nx, height*ny)).astype(np.uint8)*255
28
+
29
+ savepath = "../images/languages.gif"
30
+ dirpath = "../examples/concepts"
31
+
32
+ font = ImageFont.truetype('data/fonts/latin/Roboto-Regular.ttf', 28)
33
+ for i in tqdm(range(ny)):
34
+ background = create_image((width, text_height), languages[i].capitalize(), font)
35
+ lang_image = np.asarray(background)
36
+ for idx in range(n_frames*2+freeze-1):
37
+ collage[idx, :text_height, i*width:(i+1)*width] = lang_image
38
+
39
+ for i, concept in tqdm(enumerate(concepts), total=len(concepts)):
40
+ for j, script in enumerate(scripts):
41
+ filepath = os.path.join(dirpath, concept, f"{script}.gif")
42
+ image = Image.open(filepath)
43
+ assert image.is_animated
44
+ image.seek(0)
45
+ frame = image.convert('L').copy()
46
+ frame = frame.resize((width,height))
47
+ for idx in range(freeze):
48
+ collage[idx, text_height+i*width:text_height+(i+1)*width,j*height:(j+1)*height] = np.asarray(frame)
49
+
50
+ for frame_idx in range(n_frames):
51
+ image.seek(frame_idx)
52
+ frame = image.convert('L').copy()
53
+ frame = frame.resize((width,height))
54
+ collage[idx, text_height+i*width:text_height+(i+1)*width,j*height:(j+1)*height] = np.asarray(frame)
55
+ idx += 1
56
+
57
+ for frame_idx in reversed(range(n_frames)):
58
+ image.seek(frame_idx)
59
+ frame = image.convert('L').copy()
60
+ frame = frame.resize((width,height))
61
+ collage[idx, text_height+i*width:text_height+(i+1)*width,j*height:(j+1)*height] = np.asarray(frame)
62
+ idx += 1
63
+
64
+ imageio.mimsave(savepath, collage)
code/config.py CHANGED
@@ -12,6 +12,7 @@ from utils import (
12
  import wandb
13
  import warnings
14
  warnings.filterwarnings("ignore")
 
15
 
16
 
17
  def parse_args():
@@ -23,8 +24,8 @@ def parse_args():
23
  parser.add_argument('--font', type=str, default="none", help="font name")
24
  parser.add_argument('--semantic_concept', type=str, help="the semantic concept to insert")
25
  parser.add_argument('--word', type=str, default="none", help="the text to work on")
26
- parser.add_argument('--prompt_suffix', type=str, default="minimal flat 2d vector. lineal color."
27
- " trending on artstation")
28
  parser.add_argument('--optimized_letter', type=str, default="none", help="the letter in the word to optimize")
29
  parser.add_argument('--batch_size', type=int, default=1)
30
  parser.add_argument('--use_wandb', type=int, default=0)
@@ -34,30 +35,44 @@ def parse_args():
34
  args = parser.parse_args()
35
  with open('TOKEN', 'r') as f:
36
  setattr(args, 'token', f.read().replace('\n', ''))
 
37
  cfg.config = args.config
38
  cfg.experiment = args.experiment
39
  cfg.seed = args.seed
40
  cfg.font = args.font
41
  cfg.semantic_concept = args.semantic_concept
42
  cfg.word = cfg.semantic_concept if args.word == "none" else args.word
 
 
 
 
 
 
 
 
43
  # if " " in cfg.word:
44
  # raise ValueError(f'no spaces are allowed')
 
45
  if "jpeg" in args.semantic_concept:
46
  cfg.caption = args.semantic_concept
47
  else:
48
  cfg.caption = f"a {args.semantic_concept}. {args.prompt_suffix}"
49
 
50
- cfg.log_dir = f"{args.log_dir}/{args.experiment}_{cfg.word}"
 
51
  if args.optimized_letter in cfg.word:
52
  cfg.optimized_letter = args.optimized_letter
53
  else:
54
  raise ValueError(f'letter should be in word')
 
55
  cfg.batch_size = args.batch_size
56
  cfg.token = args.token
57
  cfg.use_wandb = args.use_wandb
58
  cfg.wandb_user = args.wandb_user
59
- cfg.letter = f"{args.font}_{args.optimized_letter}_scaled"
60
  cfg.target = f"code/data/init/{cfg.letter}"
 
 
61
 
62
  return cfg
63
 
@@ -82,9 +97,8 @@ def set_config():
82
  del cfgs
83
 
84
  # set experiment dir
85
- signature = f"{cfg.letter}_concept_{cfg.semantic_concept}_seed_{cfg.seed}"
86
- cfg.experiment_dir = \
87
- osp.join(cfg.log_dir, cfg.font, signature)
88
  configfile = osp.join(cfg.experiment_dir, 'config.yaml')
89
  print('Config:', cfg)
90
 
@@ -94,7 +108,7 @@ def set_config():
94
  yaml.dump(edict_2_dict(cfg), f)
95
 
96
  if cfg.use_wandb:
97
- wandb.init(project="Word-As-Image", entity=cfg.wandb_user,
98
  config=cfg, name=f"{signature}", id=wandb.util.generate_id())
99
 
100
  if cfg.seed is not None:
 
12
  import wandb
13
  import warnings
14
  warnings.filterwarnings("ignore")
15
+ from glob import glob
16
 
17
 
18
  def parse_args():
 
24
  parser.add_argument('--font', type=str, default="none", help="font name")
25
  parser.add_argument('--semantic_concept', type=str, help="the semantic concept to insert")
26
  parser.add_argument('--word', type=str, default="none", help="the text to work on")
27
+ parser.add_argument('--script', type=str, default="arabic", help="script")
28
+ parser.add_argument('--prompt_suffix', type=str, default="minimal flat 2d vector. lineal color. trending on artstation")
29
  parser.add_argument('--optimized_letter', type=str, default="none", help="the letter in the word to optimize")
30
  parser.add_argument('--batch_size', type=int, default=1)
31
  parser.add_argument('--use_wandb', type=int, default=0)
 
35
  args = parser.parse_args()
36
  with open('TOKEN', 'r') as f:
37
  setattr(args, 'token', f.read().replace('\n', ''))
38
+
39
  cfg.config = args.config
40
  cfg.experiment = args.experiment
41
  cfg.seed = args.seed
42
  cfg.font = args.font
43
  cfg.semantic_concept = args.semantic_concept
44
  cfg.word = cfg.semantic_concept if args.word == "none" else args.word
45
+ cfg.letter = cfg.word
46
+ cfg.script = args.script
47
+
48
+ script_path = f"code/data/fonts/{cfg.script}"
49
+ if cfg.font == "none":
50
+ cfg.font = osp.basename(glob(f"{script_path}/*.ttf")[0])[:-4]
51
+
52
+
53
  # if " " in cfg.word:
54
  # raise ValueError(f'no spaces are allowed')
55
+
56
  if "jpeg" in args.semantic_concept:
57
  cfg.caption = args.semantic_concept
58
  else:
59
  cfg.caption = f"a {args.semantic_concept}. {args.prompt_suffix}"
60
 
61
+ # cfg.log_dir = f"{args.log_dir}/{args.experiment}_{cfg.word}"
62
+ cfg.log_dir = f"{args.log_dir}/{cfg.script}"
63
  if args.optimized_letter in cfg.word:
64
  cfg.optimized_letter = args.optimized_letter
65
  else:
66
  raise ValueError(f'letter should be in word')
67
+
68
  cfg.batch_size = args.batch_size
69
  cfg.token = args.token
70
  cfg.use_wandb = args.use_wandb
71
  cfg.wandb_user = args.wandb_user
72
+ cfg.letter = f"{cfg.font}_{args.optimized_letter}_scaled"
73
  cfg.target = f"code/data/init/{cfg.letter}"
74
+ if ' ' in cfg.target:
75
+ cfg.target = cfg.target.replace(' ', '_')
76
 
77
  return cfg
78
 
 
97
  del cfgs
98
 
99
  # set experiment dir
100
+ signature = f"{cfg.word}_{cfg.semantic_concept}_{cfg.seed}"
101
+ cfg.experiment_dir = osp.join(cfg.log_dir, signature)
 
102
  configfile = osp.join(cfg.experiment_dir, 'config.yaml')
103
  print('Config:', cfg)
104
 
 
108
  yaml.dump(edict_2_dict(cfg), f)
109
 
110
  if cfg.use_wandb:
111
+ wandb.init(project="Font-To-Image", entity=cfg.wandb_user,
112
  config=cfg, name=f"{signature}", id=wandb.util.generate_id())
113
 
114
  if cfg.seed is not None:
code/config/base.yaml CHANGED
@@ -30,24 +30,9 @@ baseline:
30
  conformal:
31
  use_conformal_loss: false
32
 
33
- conformal_0.5_dist_pixel_100_kernel201:
34
  parent_config: baseline
35
  level_of_cc: 1
36
- loss:
37
- tone:
38
- use_tone_loss: true
39
- dist_loss_weight: 100
40
- pixel_dist_kernel_blur: 201
41
- pixel_dist_sigma: 30
42
- conformal:
43
- use_conformal_loss: true
44
- angeles_w: 0.5
45
-
46
- demo:
47
- parent_config: baseline
48
- batch_size: 1
49
- token: false
50
- level_of_cc: 1
51
  num_iter: 500
52
  loss:
53
  tone:
 
30
  conformal:
31
  use_conformal_loss: false
32
 
33
+ default:
34
  parent_config: baseline
35
  level_of_cc: 1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  num_iter: 500
37
  loss:
38
  tone:
code/data/fonts/Bell MT.ttf DELETED
Binary file (84.8 kB)
 
code/data/fonts/DeliusUnicase-Regular.ttf DELETED
Binary file (31.5 kB)
 
code/data/fonts/HobeauxRococeaux-Sherman.ttf DELETED
Binary file (117 kB)
 
code/data/fonts/IndieFlower-Regular.ttf DELETED
Binary file (55.4 kB)
 
code/data/fonts/JosefinSans-Light.ttf DELETED
Binary file (59.3 kB)
 
code/data/fonts/KaushanScript-Regular.ttf DELETED
Binary file (184 kB)
 
code/data/fonts/LuckiestGuy-Regular.ttf DELETED
Binary file (58.3 kB)
 
code/data/fonts/Noteworthy-Bold.ttf DELETED
Binary file (248 kB)
 
code/data/fonts/Quicksand.ttf DELETED
Binary file (124 kB)
 
code/data/fonts/Saira-Regular.ttf DELETED
Binary file (82.8 kB)
 
code/data/fonts/{ArefRuqaa.ttf → arabic/ArefRuqaa-Regular.ttf} RENAMED
Binary files a/code/data/fonts/ArefRuqaa.ttf and b/code/data/fonts/arabic/ArefRuqaa-Regular.ttf differ
 
code/data/fonts/arabic/OFL.txt ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright 2015-2020 The Aref Ruqaa Project Authors (https://github.com/alif-type/aref-ruqaa), with Reserved Font Name EURM10.
2
+
3
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
+ This license is copied below, and is also available with a FAQ at:
5
+ http://scripts.sil.org/OFL
6
+
7
+
8
+ -----------------------------------------------------------
9
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10
+ -----------------------------------------------------------
11
+
12
+ PREAMBLE
13
+ The goals of the Open Font License (OFL) are to stimulate worldwide
14
+ development of collaborative font projects, to support the font creation
15
+ efforts of academic and linguistic communities, and to provide a free and
16
+ open framework in which fonts may be shared and improved in partnership
17
+ with others.
18
+
19
+ The OFL allows the licensed fonts to be used, studied, modified and
20
+ redistributed freely as long as they are not sold by themselves. The
21
+ fonts, including any derivative works, can be bundled, embedded,
22
+ redistributed and/or sold with any software provided that any reserved
23
+ names are not used by derivative works. The fonts and derivatives,
24
+ however, cannot be released under any other type of license. The
25
+ requirement for fonts to remain under this license does not apply
26
+ to any document created using the fonts or their derivatives.
27
+
28
+ DEFINITIONS
29
+ "Font Software" refers to the set of files released by the Copyright
30
+ Holder(s) under this license and clearly marked as such. This may
31
+ include source files, build scripts and documentation.
32
+
33
+ "Reserved Font Name" refers to any names specified as such after the
34
+ copyright statement(s).
35
+
36
+ "Original Version" refers to the collection of Font Software components as
37
+ distributed by the Copyright Holder(s).
38
+
39
+ "Modified Version" refers to any derivative made by adding to, deleting,
40
+ or substituting -- in part or in whole -- any of the components of the
41
+ Original Version, by changing formats or by porting the Font Software to a
42
+ new environment.
43
+
44
+ "Author" refers to any designer, engineer, programmer, technical
45
+ writer or other person who contributed to the Font Software.
46
+
47
+ PERMISSION & CONDITIONS
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
50
+ redistribute, and sell modified and unmodified copies of the Font
51
+ Software, subject to the following conditions:
52
+
53
+ 1) Neither the Font Software nor any of its individual components,
54
+ in Original or Modified Versions, may be sold by itself.
55
+
56
+ 2) Original or Modified Versions of the Font Software may be bundled,
57
+ redistributed and/or sold with any software, provided that each copy
58
+ contains the above copyright notice and this license. These can be
59
+ included either as stand-alone text files, human-readable headers or
60
+ in the appropriate machine-readable metadata fields within text or
61
+ binary files as long as those fields can be easily viewed by the user.
62
+
63
+ 3) No Modified Version of the Font Software may use the Reserved Font
64
+ Name(s) unless explicit written permission is granted by the corresponding
65
+ Copyright Holder. This restriction only applies to the primary font name as
66
+ presented to the users.
67
+
68
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69
+ Software shall not be used to promote, endorse or advertise any
70
+ Modified Version, except to acknowledge the contribution(s) of the
71
+ Copyright Holder(s) and the Author(s) or with their explicit written
72
+ permission.
73
+
74
+ 5) The Font Software, modified or unmodified, in part or in whole,
75
+ must be distributed entirely under this license, and must not be
76
+ distributed under any other license. The requirement for fonts to
77
+ remain under this license does not apply to any document created
78
+ using the Font Software.
79
+
80
+ TERMINATION
81
+ This license becomes null and void if any of the above conditions are
82
+ not met.
83
+
84
+ DISCLAIMER
85
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93
+ OTHER DEALINGS IN THE FONT SOFTWARE.
code/data/{arabic-fonts/dl-fonts.sh → fonts/arabic/download_fonts.sh} RENAMED
File without changes
code/data/{arabic-fonts → fonts/arabic}/font_names.txt RENAMED
@@ -1,3 +1,4 @@
 
1
  ديواني جلي
2
  ديواني مشكل
3
  ديواني طويل
 
1
+ رقعة عارف
2
  ديواني جلي
3
  ديواني مشكل
4
  ديواني طويل
code/data/fonts/chinese/OFL.txt ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright 2018 The Zhi Mang Xing Project Authors (https://github.com/googlefonts/zhimangxing)
2
+
3
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
+ This license is copied below, and is also available with a FAQ at:
5
+ http://scripts.sil.org/OFL
6
+
7
+
8
+ -----------------------------------------------------------
9
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10
+ -----------------------------------------------------------
11
+
12
+ PREAMBLE
13
+ The goals of the Open Font License (OFL) are to stimulate worldwide
14
+ development of collaborative font projects, to support the font creation
15
+ efforts of academic and linguistic communities, and to provide a free and
16
+ open framework in which fonts may be shared and improved in partnership
17
+ with others.
18
+
19
+ The OFL allows the licensed fonts to be used, studied, modified and
20
+ redistributed freely as long as they are not sold by themselves. The
21
+ fonts, including any derivative works, can be bundled, embedded,
22
+ redistributed and/or sold with any software provided that any reserved
23
+ names are not used by derivative works. The fonts and derivatives,
24
+ however, cannot be released under any other type of license. The
25
+ requirement for fonts to remain under this license does not apply
26
+ to any document created using the fonts or their derivatives.
27
+
28
+ DEFINITIONS
29
+ "Font Software" refers to the set of files released by the Copyright
30
+ Holder(s) under this license and clearly marked as such. This may
31
+ include source files, build scripts and documentation.
32
+
33
+ "Reserved Font Name" refers to any names specified as such after the
34
+ copyright statement(s).
35
+
36
+ "Original Version" refers to the collection of Font Software components as
37
+ distributed by the Copyright Holder(s).
38
+
39
+ "Modified Version" refers to any derivative made by adding to, deleting,
40
+ or substituting -- in part or in whole -- any of the components of the
41
+ Original Version, by changing formats or by porting the Font Software to a
42
+ new environment.
43
+
44
+ "Author" refers to any designer, engineer, programmer, technical
45
+ writer or other person who contributed to the Font Software.
46
+
47
+ PERMISSION & CONDITIONS
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
50
+ redistribute, and sell modified and unmodified copies of the Font
51
+ Software, subject to the following conditions:
52
+
53
+ 1) Neither the Font Software nor any of its individual components,
54
+ in Original or Modified Versions, may be sold by itself.
55
+
56
+ 2) Original or Modified Versions of the Font Software may be bundled,
57
+ redistributed and/or sold with any software, provided that each copy
58
+ contains the above copyright notice and this license. These can be
59
+ included either as stand-alone text files, human-readable headers or
60
+ in the appropriate machine-readable metadata fields within text or
61
+ binary files as long as those fields can be easily viewed by the user.
62
+
63
+ 3) No Modified Version of the Font Software may use the Reserved Font
64
+ Name(s) unless explicit written permission is granted by the corresponding
65
+ Copyright Holder. This restriction only applies to the primary font name as
66
+ presented to the users.
67
+
68
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69
+ Software shall not be used to promote, endorse or advertise any
70
+ Modified Version, except to acknowledge the contribution(s) of the
71
+ Copyright Holder(s) and the Author(s) or with their explicit written
72
+ permission.
73
+
74
+ 5) The Font Software, modified or unmodified, in part or in whole,
75
+ must be distributed entirely under this license, and must not be
76
+ distributed under any other license. The requirement for fonts to
77
+ remain under this license does not apply to any document created
78
+ using the Font Software.
79
+
80
+ TERMINATION
81
+ This license becomes null and void if any of the above conditions are
82
+ not met.
83
+
84
+ DISCLAIMER
85
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93
+ OTHER DEALINGS IN THE FONT SOFTWARE.
code/data/fonts/chinese/ZhiMangXing-Regular.ttf ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b4ca573ec88909424f38a96dc402c61950f6987c57e92bbe88cf4c1360625d2f
3
+ size 4052388
code/data/fonts/cyrillic/Geologica_Auto-Regular.ttf ADDED
Binary file (136 kB). View file
 
code/data/fonts/cyrillic/OFL.txt ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright 2020 The Geologisk Project Authors (https://github.com/monokromskriftforlag/geologisk)
2
+
3
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
+ This license is copied below, and is also available with a FAQ at:
5
+ http://scripts.sil.org/OFL
6
+
7
+
8
+ -----------------------------------------------------------
9
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10
+ -----------------------------------------------------------
11
+
12
+ PREAMBLE
13
+ The goals of the Open Font License (OFL) are to stimulate worldwide
14
+ development of collaborative font projects, to support the font creation
15
+ efforts of academic and linguistic communities, and to provide a free and
16
+ open framework in which fonts may be shared and improved in partnership
17
+ with others.
18
+
19
+ The OFL allows the licensed fonts to be used, studied, modified and
20
+ redistributed freely as long as they are not sold by themselves. The
21
+ fonts, including any derivative works, can be bundled, embedded,
22
+ redistributed and/or sold with any software provided that any reserved
23
+ names are not used by derivative works. The fonts and derivatives,
24
+ however, cannot be released under any other type of license. The
25
+ requirement for fonts to remain under this license does not apply
26
+ to any document created using the fonts or their derivatives.
27
+
28
+ DEFINITIONS
29
+ "Font Software" refers to the set of files released by the Copyright
30
+ Holder(s) under this license and clearly marked as such. This may
31
+ include source files, build scripts and documentation.
32
+
33
+ "Reserved Font Name" refers to any names specified as such after the
34
+ copyright statement(s).
35
+
36
+ "Original Version" refers to the collection of Font Software components as
37
+ distributed by the Copyright Holder(s).
38
+
39
+ "Modified Version" refers to any derivative made by adding to, deleting,
40
+ or substituting -- in part or in whole -- any of the components of the
41
+ Original Version, by changing formats or by porting the Font Software to a
42
+ new environment.
43
+
44
+ "Author" refers to any designer, engineer, programmer, technical
45
+ writer or other person who contributed to the Font Software.
46
+
47
+ PERMISSION & CONDITIONS
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
50
+ redistribute, and sell modified and unmodified copies of the Font
51
+ Software, subject to the following conditions:
52
+
53
+ 1) Neither the Font Software nor any of its individual components,
54
+ in Original or Modified Versions, may be sold by itself.
55
+
56
+ 2) Original or Modified Versions of the Font Software may be bundled,
57
+ redistributed and/or sold with any software, provided that each copy
58
+ contains the above copyright notice and this license. These can be
59
+ included either as stand-alone text files, human-readable headers or
60
+ in the appropriate machine-readable metadata fields within text or
61
+ binary files as long as those fields can be easily viewed by the user.
62
+
63
+ 3) No Modified Version of the Font Software may use the Reserved Font
64
+ Name(s) unless explicit written permission is granted by the corresponding
65
+ Copyright Holder. This restriction only applies to the primary font name as
66
+ presented to the users.
67
+
68
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69
+ Software shall not be used to promote, endorse or advertise any
70
+ Modified Version, except to acknowledge the contribution(s) of the
71
+ Copyright Holder(s) and the Author(s) or with their explicit written
72
+ permission.
73
+
74
+ 5) The Font Software, modified or unmodified, in part or in whole,
75
+ must be distributed entirely under this license, and must not be
76
+ distributed under any other license. The requirement for fonts to
77
+ remain under this license does not apply to any document created
78
+ using the Font Software.
79
+
80
+ TERMINATION
81
+ This license becomes null and void if any of the above conditions are
82
+ not met.
83
+
84
+ DISCLAIMER
85
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93
+ OTHER DEALINGS IN THE FONT SOFTWARE.
code/data/fonts/greek/EBGaramond-Regular.ttf ADDED
Binary file (561 kB). View file
 
code/data/fonts/greek/OFL.txt ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright 2017 The EB Garamond Project Authors (https://github.com/octaviopardo/EBGaramond12)
2
+
3
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
+ This license is copied below, and is also available with a FAQ at:
5
+ http://scripts.sil.org/OFL
6
+
7
+
8
+ -----------------------------------------------------------
9
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10
+ -----------------------------------------------------------
11
+
12
+ PREAMBLE
13
+ The goals of the Open Font License (OFL) are to stimulate worldwide
14
+ development of collaborative font projects, to support the font creation
15
+ efforts of academic and linguistic communities, and to provide a free and
16
+ open framework in which fonts may be shared and improved in partnership
17
+ with others.
18
+
19
+ The OFL allows the licensed fonts to be used, studied, modified and
20
+ redistributed freely as long as they are not sold by themselves. The
21
+ fonts, including any derivative works, can be bundled, embedded,
22
+ redistributed and/or sold with any software provided that any reserved
23
+ names are not used by derivative works. The fonts and derivatives,
24
+ however, cannot be released under any other type of license. The
25
+ requirement for fonts to remain under this license does not apply
26
+ to any document created using the fonts or their derivatives.
27
+
28
+ DEFINITIONS
29
+ "Font Software" refers to the set of files released by the Copyright
30
+ Holder(s) under this license and clearly marked as such. This may
31
+ include source files, build scripts and documentation.
32
+
33
+ "Reserved Font Name" refers to any names specified as such after the
34
+ copyright statement(s).
35
+
36
+ "Original Version" refers to the collection of Font Software components as
37
+ distributed by the Copyright Holder(s).
38
+
39
+ "Modified Version" refers to any derivative made by adding to, deleting,
40
+ or substituting -- in part or in whole -- any of the components of the
41
+ Original Version, by changing formats or by porting the Font Software to a
42
+ new environment.
43
+
44
+ "Author" refers to any designer, engineer, programmer, technical
45
+ writer or other person who contributed to the Font Software.
46
+
47
+ PERMISSION & CONDITIONS
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
50
+ redistribute, and sell modified and unmodified copies of the Font
51
+ Software, subject to the following conditions:
52
+
53
+ 1) Neither the Font Software nor any of its individual components,
54
+ in Original or Modified Versions, may be sold by itself.
55
+
56
+ 2) Original or Modified Versions of the Font Software may be bundled,
57
+ redistributed and/or sold with any software, provided that each copy
58
+ contains the above copyright notice and this license. These can be
59
+ included either as stand-alone text files, human-readable headers or
60
+ in the appropriate machine-readable metadata fields within text or
61
+ binary files as long as those fields can be easily viewed by the user.
62
+
63
+ 3) No Modified Version of the Font Software may use the Reserved Font
64
+ Name(s) unless explicit written permission is granted by the corresponding
65
+ Copyright Holder. This restriction only applies to the primary font name as
66
+ presented to the users.
67
+
68
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69
+ Software shall not be used to promote, endorse or advertise any
70
+ Modified Version, except to acknowledge the contribution(s) of the
71
+ Copyright Holder(s) and the Author(s) or with their explicit written
72
+ permission.
73
+
74
+ 5) The Font Software, modified or unmodified, in part or in whole,
75
+ must be distributed entirely under this license, and must not be
76
+ distributed under any other license. The requirement for fonts to
77
+ remain under this license does not apply to any document created
78
+ using the Font Software.
79
+
80
+ TERMINATION
81
+ This license becomes null and void if any of the above conditions are
82
+ not met.
83
+
84
+ DISCLAIMER
85
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93
+ OTHER DEALINGS IN THE FONT SOFTWARE.
code/data/fonts/latin/LICENSE.txt ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
178
+
179
+ APPENDIX: How to apply the Apache License to your work.
180
+
181
+ To apply the Apache License to your work, attach the following
182
+ boilerplate notice, with the fields enclosed by brackets "[]"
183
+ replaced with your own identifying information. (Don't include
184
+ the brackets!) The text should be enclosed in the appropriate
185
+ comment syntax for the file format. We also recommend that a
186
+ file or class name and description of purpose be included on the
187
+ same "printed page" as the copyright notice for easier
188
+ identification within third-party archives.
189
+
190
+ Copyright [yyyy] [name of copyright owner]
191
+
192
+ Licensed under the Apache License, Version 2.0 (the "License");
193
+ you may not use this file except in compliance with the License.
194
+ You may obtain a copy of the License at
195
+
196
+ http://www.apache.org/licenses/LICENSE-2.0
197
+
198
+ Unless required by applicable law or agreed to in writing, software
199
+ distributed under the License is distributed on an "AS IS" BASIS,
200
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201
+ See the License for the specific language governing permissions and
202
+ limitations under the License.
code/data/fonts/latin/Roboto-Regular.ttf ADDED
Binary file (168 kB). View file
 
code/data/fonts/tamil/HindMadurai-Regular.ttf ADDED
Binary file (133 kB). View file
 
code/data/fonts/tamil/OFL.txt ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2015 Indian Type Foundry (info@indiantypefoundry.com)
2
+
3
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
+ This license is copied below, and is also available with a FAQ at:
5
+ http://scripts.sil.org/OFL
6
+
7
+
8
+ -----------------------------------------------------------
9
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10
+ -----------------------------------------------------------
11
+
12
+ PREAMBLE
13
+ The goals of the Open Font License (OFL) are to stimulate worldwide
14
+ development of collaborative font projects, to support the font creation
15
+ efforts of academic and linguistic communities, and to provide a free and
16
+ open framework in which fonts may be shared and improved in partnership
17
+ with others.
18
+
19
+ The OFL allows the licensed fonts to be used, studied, modified and
20
+ redistributed freely as long as they are not sold by themselves. The
21
+ fonts, including any derivative works, can be bundled, embedded,
22
+ redistributed and/or sold with any software provided that any reserved
23
+ names are not used by derivative works. The fonts and derivatives,
24
+ however, cannot be released under any other type of license. The
25
+ requirement for fonts to remain under this license does not apply
26
+ to any document created using the fonts or their derivatives.
27
+
28
+ DEFINITIONS
29
+ "Font Software" refers to the set of files released by the Copyright
30
+ Holder(s) under this license and clearly marked as such. This may
31
+ include source files, build scripts and documentation.
32
+
33
+ "Reserved Font Name" refers to any names specified as such after the
34
+ copyright statement(s).
35
+
36
+ "Original Version" refers to the collection of Font Software components as
37
+ distributed by the Copyright Holder(s).
38
+
39
+ "Modified Version" refers to any derivative made by adding to, deleting,
40
+ or substituting -- in part or in whole -- any of the components of the
41
+ Original Version, by changing formats or by porting the Font Software to a
42
+ new environment.
43
+
44
+ "Author" refers to any designer, engineer, programmer, technical
45
+ writer or other person who contributed to the Font Software.
46
+
47
+ PERMISSION & CONDITIONS
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
50
+ redistribute, and sell modified and unmodified copies of the Font
51
+ Software, subject to the following conditions:
52
+
53
+ 1) Neither the Font Software nor any of its individual components,
54
+ in Original or Modified Versions, may be sold by itself.
55
+
56
+ 2) Original or Modified Versions of the Font Software may be bundled,
57
+ redistributed and/or sold with any software, provided that each copy
58
+ contains the above copyright notice and this license. These can be
59
+ included either as stand-alone text files, human-readable headers or
60
+ in the appropriate machine-readable metadata fields within text or
61
+ binary files as long as those fields can be easily viewed by the user.
62
+
63
+ 3) No Modified Version of the Font Software may use the Reserved Font
64
+ Name(s) unless explicit written permission is granted by the corresponding
65
+ Copyright Holder. This restriction only applies to the primary font name as
66
+ presented to the users.
67
+
68
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69
+ Software shall not be used to promote, endorse or advertise any
70
+ Modified Version, except to acknowledge the contribution(s) of the
71
+ Copyright Holder(s) and the Author(s) or with their explicit written
72
+ permission.
73
+
74
+ 5) The Font Software, modified or unmodified, in part or in whole,
75
+ must be distributed entirely under this license, and must not be
76
+ distributed under any other license. The requirement for fonts to
77
+ remain under this license does not apply to any document created
78
+ using the Font Software.
79
+
80
+ TERMINATION
81
+ This license becomes null and void if any of the above conditions are
82
+ not met.
83
+
84
+ DISCLAIMER
85
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93
+ OTHER DEALINGS IN THE FONT SOFTWARE.
code/losses.py CHANGED
@@ -7,6 +7,11 @@ from torch.nn import functional as nnf
7
  from easydict import EasyDict
8
  from shapely.geometry import Point
9
  from shapely.geometry.polygon import Polygon
 
 
 
 
 
10
 
11
  class SDSLoss(nn.Module):
12
  def __init__(self, cfg, device, model):
@@ -38,11 +43,11 @@ class SDSLoss(nn.Module):
38
  with torch.no_grad():
39
  text_embeddings = self.pipe.text_encoder(text_input.input_ids.to(self.device))[0]
40
  uncond_embeddings = self.pipe.text_encoder(uncond_input.input_ids.to(self.device))[0]
41
-
42
  self.text_embeddings = torch.cat([uncond_embeddings, text_embeddings])
43
  self.text_embeddings = self.text_embeddings.repeat_interleave(self.cfg.batch_size, 0)
44
- # del self.pipe.tokenizer
45
- # del self.pipe.text_encoder
46
 
47
 
48
  def forward(self, x_aug):
@@ -152,10 +157,11 @@ class ConformalLoss:
152
 
153
  def init_faces(self, device: torch.device) -> torch.tensor:
154
  faces_ = []
 
155
  for j, c in enumerate(self.target_letter):
156
  points_np = [self.parameters.point[i].clone().detach().cpu().numpy() for i in range(len(self.parameters.point))]
157
  start_ind, end_ind, shapes_per_letter = self.get_letter_inds(c)
158
- print(c, start_ind, end_ind)
159
  holes = []
160
  if shapes_per_letter > 1:
161
  holes = points_np[start_ind+1:end_ind]
@@ -165,6 +171,9 @@ class ConformalLoss:
165
  faces = Delaunay(points_np).simplices
166
  is_intersect = np.array([poly.contains(Point(points_np[face].mean(0))) for face in faces], dtype=np.bool_)
167
  faces_.append(torch.from_numpy(faces[is_intersect]).to(device, dtype=torch.int64))
 
 
 
168
  return faces_
169
 
170
  def __call__(self) -> torch.Tensor:
@@ -173,8 +182,4 @@ class ConformalLoss:
173
  angles = self.get_angles(points)
174
  for i in range(len(self.faces)):
175
  loss_angles += (nnf.mse_loss(angles[i], self.angles[i]))
176
- return loss_angles
177
-
178
-
179
-
180
-
 
7
  from easydict import EasyDict
8
  from shapely.geometry import Point
9
  from shapely.geometry.polygon import Polygon
10
+ from torchvision import transforms
11
+ from PIL import Image
12
+ from transformers import CLIPProcessor, CLIPModel
13
+
14
+ from diffusers import StableDiffusionPipeline
15
 
16
  class SDSLoss(nn.Module):
17
  def __init__(self, cfg, device, model):
 
43
  with torch.no_grad():
44
  text_embeddings = self.pipe.text_encoder(text_input.input_ids.to(self.device))[0]
45
  uncond_embeddings = self.pipe.text_encoder(uncond_input.input_ids.to(self.device))[0]
46
+
47
  self.text_embeddings = torch.cat([uncond_embeddings, text_embeddings])
48
  self.text_embeddings = self.text_embeddings.repeat_interleave(self.cfg.batch_size, 0)
49
+ del self.pipe.tokenizer
50
+ del self.pipe.text_encoder
51
 
52
 
53
  def forward(self, x_aug):
 
157
 
158
  def init_faces(self, device: torch.device) -> torch.tensor:
159
  faces_ = []
160
+ num_shapes = 0
161
  for j, c in enumerate(self.target_letter):
162
  points_np = [self.parameters.point[i].clone().detach().cpu().numpy() for i in range(len(self.parameters.point))]
163
  start_ind, end_ind, shapes_per_letter = self.get_letter_inds(c)
164
+ print(c, start_ind, end_ind, shapes_per_letter)
165
  holes = []
166
  if shapes_per_letter > 1:
167
  holes = points_np[start_ind+1:end_ind]
 
171
  faces = Delaunay(points_np).simplices
172
  is_intersect = np.array([poly.contains(Point(points_np[face].mean(0))) for face in faces], dtype=np.bool_)
173
  faces_.append(torch.from_numpy(faces[is_intersect]).to(device, dtype=torch.int64))
174
+ num_shapes += shapes_per_letter
175
+ if num_shapes >= len(self.target_letter):
176
+ break
177
  return faces_
178
 
179
  def __call__(self) -> torch.Tensor:
 
182
  angles = self.get_angles(points)
183
  for i in range(len(self.faces)):
184
  loss_angles += (nnf.mse_loss(angles[i], self.angles[i]))
185
+ return loss_angles
 
 
 
 
code/main.py CHANGED
@@ -50,10 +50,8 @@ if __name__ == "__main__":
50
  pydiffvg.set_use_gpu(torch.cuda.is_available())
51
  device = pydiffvg.get_device()
52
 
53
- # cfg.word = cfg.word[::-1]
54
-
55
  print("preprocessing")
56
- preprocess(cfg.font, cfg.word, cfg.optimized_letter, cfg.level_of_cc)
57
 
58
  if cfg.loss.use_sds_loss:
59
  sds_loss = SDSLoss(cfg, device)
@@ -163,7 +161,7 @@ if __name__ == "__main__":
163
  save_svg.save_svg(
164
  filename, w, h, shapes, shape_groups)
165
 
166
- combine_word(cfg.word, cfg.optimized_letter, cfg.font, cfg.experiment_dir)
167
 
168
  if cfg.save.image:
169
  filename = os.path.join(
 
50
  pydiffvg.set_use_gpu(torch.cuda.is_available())
51
  device = pydiffvg.get_device()
52
 
 
 
53
  print("preprocessing")
54
+ preprocess(cfg.font, cfg.word, cfg.optimized_letter, cfg.script, cfg.level_of_cc)
55
 
56
  if cfg.loss.use_sds_loss:
57
  sds_loss = SDSLoss(cfg, device)
 
161
  save_svg.save_svg(
162
  filename, w, h, shapes, shape_groups)
163
 
164
+ # combine_word(cfg.word, cfg.optimized_letter, cfg.font, cfg.experiment_dir)
165
 
166
  if cfg.save.image:
167
  filename = os.path.join(
code/utils.py CHANGED
@@ -44,7 +44,7 @@ def update(d, u):
44
  return d
45
 
46
 
47
- def preprocess(font, word, letter, level_of_cc=1):
48
 
49
  if level_of_cc == 0:
50
  target_cp = None
@@ -65,12 +65,9 @@ def preprocess(font, word, letter, level_of_cc=1):
65
  "y": 120, "z": 120
66
  }
67
  target_cp = {k: v * level_of_cc for k, v in target_cp.items()}
68
-
69
  print(f"======= {font} =======")
70
- if font[0] in ['0', '1', '2']:
71
- font_path = f"code/data/arabic-fonts/{font}.ttf"
72
- else:
73
- font_path = f"code/data/fonts/{font}.ttf"
74
 
75
  init_path = f"code/data/init"
76
  subdivision_thresh = None
@@ -142,7 +139,7 @@ def get_letter_ids(letter, word, shape_groups):
142
  return group.shape_ids
143
 
144
 
145
- def combine_word(word, letter, font, experiment_dir, device='cuda'):
146
  word_svg_scaled = f"./code/data/init/{font}_{word}_scaled.svg"
147
  canvas_width_word, canvas_height_word, shapes_word, shape_groups_word = pydiffvg.svg_to_scene(word_svg_scaled)
148
 
@@ -202,7 +199,7 @@ def combine_word(word, letter, font, experiment_dir, device='cuda'):
202
  scene_args = pydiffvg.RenderFunction.serialize_scene(canvas_width, canvas_height, shapes_word, shape_groups_word)
203
  img = render(canvas_width, canvas_height, 2, 2, 0, None, *scene_args)
204
  img = img[:, :, 3:4] * img[:, :, :3] + \
205
- torch.ones(img.shape[0], img.shape[1], 3, device=device) * (1 - img[:, :, 3:4])
206
  img = img[:, :, :3]
207
  save_image(img, f"{experiment_dir}/{font}_{word}_{letter}.png")
208
 
 
44
  return d
45
 
46
 
47
+ def preprocess(font, word, letter, script, level_of_cc=1):
48
 
49
  if level_of_cc == 0:
50
  target_cp = None
 
65
  "y": 120, "z": 120
66
  }
67
  target_cp = {k: v * level_of_cc for k, v in target_cp.items()}
68
+
69
  print(f"======= {font} =======")
70
+ font_path = f"code/data/fonts/{script}/{font}.ttf"
 
 
 
71
 
72
  init_path = f"code/data/init"
73
  subdivision_thresh = None
 
139
  return group.shape_ids
140
 
141
 
142
+ def combine_word(word, letter, font, experiment_dir):
143
  word_svg_scaled = f"./code/data/init/{font}_{word}_scaled.svg"
144
  canvas_width_word, canvas_height_word, shapes_word, shape_groups_word = pydiffvg.svg_to_scene(word_svg_scaled)
145
 
 
199
  scene_args = pydiffvg.RenderFunction.serialize_scene(canvas_width, canvas_height, shapes_word, shape_groups_word)
200
  img = render(canvas_width, canvas_height, 2, 2, 0, None, *scene_args)
201
  img = img[:, :, 3:4] * img[:, :, :3] + \
202
+ torch.ones(img.shape[0], img.shape[1], 3, device="cuda:0") * (1 - img[:, :, 3:4])
203
  img = img[:, :, :3]
204
  save_image(img, f"{experiment_dir}/{font}_{word}_{letter}.png")
205