1 /**
2 Not really optimised pixel font module. 
3 Contains 2 fonts. Probably going to be 
4 transformed to read "bitmaps" and moved in
5 it's own module
6 ---
7 5x6 
8 █▀▀▀▀   ▀    ▀█   ▄   ▄  
9 ▀▀▀▀█   █     █   ▀▄ ▄▀  
10 ▄▄▄▄█   █     █     █    
11 3x4 
12 ██▀  █  █   █▄█  
13 ▄▄█  █  █▄▄  █   
14 ---
15 */
16 module sily.logger.pixelfont;
17 
18 import std.algorithm.searching: canFind;
19 import std.stdio: writeln;
20 import std.array: join, split;
21 import std.uni: toUpper;
22 
23 import sily.terminal: terminalWidth;
24 import sily.string: splitStringWidth;
25 
26 /** 
27 Prints/Returns string in big unicode letters with size 4x6
28 Params:
29   s = String to print/get
30 Example:
31 ---
32 print5x6("Fox");
33 // prints:
34 █▀▀▀▀  ▄▄▄  ▄   ▄ 
35 █▀▀▀▀ █   █  ▀▄▀  
36 █     ▀▄▄▄▀ ▄▀ ▀▄ 
37 ---
38 Allowed Characters:
39 ---
40 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz `~!@#$%^&*()-_+=[]{}\|,.<>?/;:'"
41 ---
42  */
43 void print5x6(string s) { 
44     dstring[] lines = getPixelSetWidth!(5, 3)(s, terminalWidth, pixelFont5x6); 
45     foreach (line; lines) writeln(line);
46 }
47 /// Ditto
48 dstring get5x6(string s) { 
49     return getPixelSetWidth!(5, 3)(s, terminalWidth, pixelFont5x6).join('\n'); 
50 }
51 /// Ditto
52 void print3x4(string s) { 
53     dstring[] lines = getPixelSetWidth!(3, 2)(s.toUpper, terminalWidth, pixelFont3x4); 
54     foreach (line; lines) writeln(line);
55 }
56 /// Ditto
57 dstring get3x4(string s) { 
58     return getPixelSetWidth!(3, 2)(s.toUpper, terminalWidth, pixelFont3x4).join('\n'); 
59 }
60 
61 private dstring[] getPixelSetWidth(int charw, int charh)(string s, int w, ref const(dstring[char]) table) {
62     string[] lines = splitStringWidth(s, w / (charw + 1));
63     dstring[] outlines;
64     foreach (line; lines) {
65         dstring l = getPixelSet!(charw, charh)(line, table);
66         if (l.length > 0) outlines ~= l;
67     }
68     return outlines;
69 }
70 
71 private dstring getPixelSet(int charw, int charh)(string s, ref const(dstring[char]) table) {
72     if (s.length == 0) return "";
73     dstring[] lines = new dstring[](charh + 1);
74     for (int i = 0; i < charh + 1; ++i) {
75         lines[i] = "";
76     }
77 
78     foreach (c; s) {
79         if (table.keys.canFind(c)) {
80             for (int i = 0; i < charh + 1; ++i) {
81                 int charf = i * (charw + 1);
82                 int chart = charf + charw + 1;
83                 lines[i] ~= table[c][charf..chart];
84             }
85         } else {
86             for (int i = 0; i < charh + 1; ++i) {
87                 int charf = i * (charw + 1);
88                 int chart = charf + charw + 1;
89                 lines[i] ~= table['\0'][charf..chart];
90             }
91         }
92     }
93     
94     return lines.join('\n');
95 }
96 
97 private const dstring[char] pixelFont5x6;
98 private const dstring[char] pixelFont3x4;
99 
100 static this() { 
101     pixelFont5x6 = [
102     '\0':"      " ~ 
103          "      " ~ 
104          "      " ~ 
105          "      ",
106     ' ': "      " ~ 
107          "      " ~ 
108          "      " ~ 
109          "      ",
110     'A': "      " ~ 
111          "▄▀▀▀█ " ~ 
112          "█▄▄▄█ " ~ 
113          "█   █ ",
114     'a': "      " ~ 
115          " ▄▄▄▄ " ~ 
116          "█   █ " ~ 
117          "▀▄▄▄█ ",
118     'B': "      " ~ 
119          "█▀▀▀▄ " ~ 
120          "█▀▀▀▄ " ~ 
121          "█▄▄▄█ ",
122     'b': "      " ~ 
123          "█     " ~ 
124          "█▀▀▀▄ " ~ 
125          "█▄▄▄▀ ",
126     'C': "      " ~ 
127          "▄▀▀▀▄ " ~ 
128          "█     " ~ 
129          "▀▄▄▄▀ ",
130     'c': "      " ~ 
131          " ▄▄▄  " ~ 
132          "█   ▀ " ~ 
133          "▀▄▄▄▀ ",
134     'D': "      " ~ 
135          "█▀▀▀▄ " ~ 
136          "█   █ " ~ 
137          "█▄▄▄▀ ",
138     'd': "      " ~ 
139          "    █ " ~ 
140          "▄▀▀▀█ " ~ 
141          "▀▄▄▄█ ",
142     'E': "      " ~ 
143          "█▀▀▀▀ " ~ 
144          "█▀▀▀▀ " ~ 
145          "█▄▄▄▄ ",
146     'e': "      " ~ 
147          " ▄▄▄  " ~ 
148          "█▄▄▄█ " ~ 
149          "▀▄▄▄  ",
150     'F': "      " ~ 
151          "█▀▀▀▀ " ~ 
152          "█▀▀▀▀ " ~ 
153          "█     ",
154     'f': "      " ~ 
155          " ▄▄▄▄ " ~ 
156          "█▄▄▄  " ~ 
157          "█     ",
158     'G': "      " ~ 
159          "▄▀▀▀▄ " ~ 
160          "█  ▄▄ " ~ 
161          "▀▄▄▄█ ",
162     'g': "      " ~ 
163          " ▄▄▄  " ~ 
164          "▀▄▄▄█ " ~ 
165          " ▄▄▄▀ ",
166     'H': "      " ~ 
167          "█   █ " ~ 
168          "█▀▀▀█ " ~ 
169          "█   █ ",
170     'h': "      " ~ 
171          "█     " ~ 
172          "█▀▀▀▄ " ~ 
173          "█   █ ",
174     'I': "      " ~ 
175          "▀▀█▀▀ " ~ 
176          "  █   " ~ 
177          "▄▄█▄▄ ",
178     'i': "      " ~ 
179          "  ▀   " ~ 
180          "  █   " ~ 
181          "  █   ",
182     'J': "      " ~ 
183          "▀▀█▀▀ " ~ 
184          "  █   " ~ 
185          "▄▄▀   ",
186     'j': "      " ~ 
187          "  ▀   " ~ 
188          "  █   " ~ 
189          " ▄▀   ",
190     'K': "      " ~ 
191          "█ ▄▀▀ " ~ 
192          "██    " ~ 
193          "█ ▀▄▄ ",
194     'k': "      " ~ 
195          "█  ▄  " ~ 
196          "█▄▀   " ~ 
197          "█ ▀▄▄ ",
198     'L': "      " ~ 
199          "█     " ~ 
200          "█     " ~ 
201          "█▄▄▄▄ ",
202     'l': "      " ~ 
203          " ▀█   " ~ 
204          "  █   " ~ 
205          "  █   ",
206     'M': "      " ~ 
207          "█▄ ▄█ " ~ 
208          "█ █ █ " ~ 
209          "█   █ ",
210     'm': "      " ~ 
211          "▄▄ ▄  " ~ 
212          "█ █ █ " ~ 
213          "█   █ ",
214     'N': "      " ~ 
215          "█▄  █ " ~ 
216          "█ █ █ " ~ 
217          "█  ▀█ ",
218     'n': "      " ~ 
219          "▄▄▄▄  " ~ 
220          "█   █ " ~ 
221          "█   █ ",
222     'O': "      " ~ 
223          "▄▀▀▀▄ " ~ 
224          "█   █ " ~ 
225          "▀▄▄▄▀ ",
226     'o': "      " ~ 
227          " ▄▄▄  " ~ 
228          "█   █ " ~ 
229          "▀▄▄▄▀ ",
230     'P': "      " ~ 
231          "█▀▀▀▄ " ~ 
232          "█▄▄▄▀ " ~ 
233          "█     ",
234     'p': "      " ~ 
235          "▄▄▄▄  " ~ 
236          "█▄▄▄▀ " ~ 
237          "█     ",
238     'Q': "      " ~ 
239          "▄▀▀▀▄ " ~ 
240          "█   █ " ~ 
241          "▀▄▄██ ",
242     'q': "      " ~ 
243          " ▄▄▄▄ " ~ 
244          "▀▄▄▄█ " ~ 
245          "    █ ",
246     'R': "      " ~ 
247          "█▀▀▀▄ " ~ 
248          "█▄▄▄▀ " ~ 
249          "█   █ ",
250     'r': "      " ~ 
251          "▄▄▄▄  " ~ 
252          "█▄▄▄▀ " ~ 
253          "█   █ ",
254     'S': "      " ~ 
255          "█▀▀▀▀ " ~ 
256          "▀▀▀▀█ " ~ 
257          "▄▄▄▄█ ",
258     's': "      " ~ 
259          " ▄▄▄▄ " ~ 
260          "▀▄▄▄  " ~ 
261          "▄▄▄▄▀ ",
262     'T': "      " ~ 
263          "▀▀█▀▀ " ~ 
264          "  █   " ~ 
265          "  █   ",
266     't': "      " ~ 
267          "  █   " ~ 
268          "▀▀█▀▀ " ~ 
269          "  █   ",
270     'U': "      " ~ 
271          "█   █ " ~ 
272          "█   █ " ~ 
273          "▀▄▄▄█ ",
274     'u': "      " ~ 
275          "▄   ▄ " ~ 
276          "█   █ " ~ 
277          "▀▄▄▄█ ",
278     'V': "      " ~ 
279          "█   █ " ~ 
280          "█   █ " ~ 
281          " ▀▄▀  ",
282     'v': "      " ~ 
283          "▄   ▄ " ~ 
284          "█   █ " ~ 
285          " ▀▄▀  ",
286     'W': "      " ~ 
287          "█   █ " ~ 
288          "█ ▄ █ " ~ 
289          "▀▄▀▄▀ ",
290     'w': "      " ~ 
291          "▄   ▄ " ~
292          "█ ▄ █ " ~ 
293          "▀▄▀▄▀ ", 
294     'X': "      " ~ 
295          "▀▄ ▄▀ " ~ 
296          " ▄▀▄  " ~ 
297          "█   █ ",
298     'x': "      " ~ 
299          "▄   ▄ " ~ 
300          " ▀▄▀  " ~ 
301          "▄▀ ▀▄ ",
302     'Y': "      " ~ 
303          "█   █ " ~ 
304          " ▀▄▀  " ~ 
305          "  █   ",
306     'y': "      " ~ 
307          "▄   ▄ " ~ 
308          "▀▄ ▄▀ " ~ 
309          "  █   ",
310     'Z': "      " ~ 
311          "▀▀▀▀█ " ~ 
312          " ▄▀▀  " ~ 
313          "█▄▄▄▄ ",
314     'z': "      " ~ 
315          "▄▄▄▄▄ " ~ 
316          "  ▄▀  " ~ 
317          "▄█▄▄▄ ",
318     '0': "      " ~ 
319          "▄▀▀█▄ " ~ 
320          "█ █ █ " ~ 
321          "▀█▄▄▀ ",
322     '1': "      " ~ 
323          " ▄█   " ~ 
324          "  █   " ~ 
325          "  █   ",
326     '2': "      " ~ 
327          "▄▀▀▀▄ " ~ 
328          " ▄▄▀  " ~ 
329          "█▄▄▄▄ ",
330     '3': "      " ~ 
331          "▄▀▀▀▄ " ~ 
332          "   ▀▄ " ~ 
333          "▀▄▄▄▀ ",
334     '4': "      " ~ 
335          "█   █ " ~ 
336          "▀▀▀▀█ " ~ 
337          "    █ ",
338     '5': "      " ~ 
339          "█▀▀▀▀ " ~ 
340          "▀▀▀▀▄ " ~ 
341          "▄▄▄▄▀ ",
342     '6': "      " ~ 
343          "▄▀▀▀  " ~ 
344          "█▀▀▀▄ " ~ 
345          "▀▄▄▄▀ ",
346     '7': "      " ~ 
347          "▀▀▀▀█ " ~ 
348          "  ▄▀  " ~ 
349          "  █   ",
350     '8': "      " ~ 
351          "▄▀▀▀▄ " ~ 
352          "▄▀▀▀▄ " ~ 
353          "▀▄▄▄▀ ",
354     '9': "      " ~ 
355          "▄▀▀▀▄ " ~ 
356          "▀▄▄▄█ " ~ 
357          " ▄▄▄▀ ",
358     '&': "      " ~ 
359          "▄▀▀▄  " ~ 
360          "▀▄▀▄  " ~ 
361          "▀▄▄█▄ ",
362     '*': "      " ~ 
363          " ▄ ▄  " ~ 
364          " ▄▀▄  " ~ 
365          "      ",
366     '+': "      " ~ 
367          "  ▄   " ~ 
368          " ▀█▀  " ~ 
369          "      ",
370     '-': "      " ~ 
371          "      " ~ 
372          " ▀▀▀  " ~ 
373          "      ",
374     '~': "      " ~ 
375          "  ▄ ▄ " ~ 
376          " ▀ ▀  " ~ 
377          "      ",
378     '_': "      " ~ 
379          "      " ~ 
380          "      " ~ 
381          " ▄▄▄  ",
382     '=': "      " ~ 
383          " ▀▀▀  " ~ 
384          " ▀▀▀  " ~ 
385          "      ",
386     '.': "      " ~ 
387          "      " ~  
388          "      " ~  
389          "  ▄   ",
390     '!': "      " ~ 
391          "  █   " ~ 
392          "  █   " ~
393          "  ▄   ", 
394     '"': "      " ~ 
395          "  █ █ " ~ 
396          "      " ~  
397          "      ",
398     '\'':"      " ~ 
399          "   █  " ~ 
400          "      " ~  
401          "      ",
402     '`': "      " ~ 
403          "  ▀▄  " ~ 
404          "      " ~  
405          "      ",
406     '#': "      " ~ 
407          "▄█▄█▄ " ~ 
408          " █ █  " ~ 
409          "▀█▀█▀ ",
410     '$': "      " ~ 
411          "▄▀█▀▀ " ~ 
412          "▀▀█▀█ " ~ 
413          "▄▄█▄▀ ",
414     '%': "      " ~ 
415          "▄  ▄▀ " ~ 
416          "  █   " ~ 
417          "▄▀  ▀ ",
418     '^': "      " ~ 
419          " ▄▀▄  " ~ 
420          "      " ~  
421          "      ",
422     ',': "      " ~ 
423          "      " ~  
424          "      " ~  
425          "  ▄▀  ",
426     ':': "      " ~ 
427          "   ▄  " ~ 
428          "      " ~  
429          "  ▄▀  ",
430     ';': "      " ~ 
431          "  ▄   " ~ 
432          "      " ~  
433          "  ▀   ",
434     '?': "      " ~ 
435          "▄▀▀▀▄ " ~ 
436          "  ▄▄▀ " ~
437          "  ▄   ", 
438     '@': "      " ~ 
439          " ▄▄▄  " ~ 
440          "██▀ █ " ~ 
441          "▀▄██▄ ",
442     '/': "      " ~ 
443          "   ▄▀ " ~ 
444          "  █   " ~ 
445          "▄▀    ",
446     '<': "      " ~ 
447          " ▄▄▀▀ " ~ 
448          "▀▄▄   " ~ 
449          "   ▀▀ ",
450     '>': "      " ~ 
451          "▀▀▄▄  " ~ 
452          "  ▄▄▀ " ~ 
453          "▀▀    ",
454     '|': "      " ~ 
455          "  █   " ~ 
456          "  █   " ~
457          "  █   ", 
458     '\\':"      " ~ 
459          "▀▄    " ~ 
460          "  █   " ~ 
461          "   ▀▄ ",
462     '(': "      " ~ 
463          " ▄▀▀  " ~ 
464          " █    " ~ 
465          " ▀▄▄  ",
466     ')': "      " ~ 
467          " ▀▀▄  " ~ 
468          "   █  " ~ 
469          " ▄▄▀  ",
470     '[': "      " ~ 
471          " █▀▀  " ~ 
472          " █    " ~ 
473          " █▄▄  ",
474     ']': "      " ~ 
475          " ▀▀█  " ~ 
476          "   █  " ~ 
477          " ▄▄█  ",
478     '{': "      " ~ 
479          " ▄▀▀  " ~ 
480          "▀█    " ~ 
481          " ▀▄▄  ",
482     '}': "      " ~ 
483          " ▀▀▄  " ~ 
484          "   █▀ " ~ 
485          " ▄▄▀  ",
486     ];
487     /* -------------------------------------------------------------------------- */
488     pixelFont3x4 = [
489     '\0':"    " ~ 
490          "    " ~ 
491          "    ",
492     ' ': "    " ~ 
493          "    " ~ 
494          "    " ~ 
495          "    ",
496     'A': "    " ~ 
497          "▄▀█ " ~ 
498          "█▀█ ",
499     'B': "    " ~ 
500          "█▄▄ " ~ 
501          "█▄█ ",
502     'C': "    " ~ 
503          "█▀▀ " ~ 
504          "█▄▄ ",
505     'D': "    " ~ 
506          "█▀▄ " ~ 
507          "█▄▀ ",
508     'E': "    " ~ 
509          "█▀▀ " ~ 
510          "██▄ ",
511     'F': "    " ~ 
512          "█▀▀ " ~ 
513          "█▀  ",
514     'G': "    " ~ 
515          "█▀▀ " ~ 
516          "█▄█ ",
517     'H': "    " ~ 
518          "█ █ " ~ 
519          "█▀█ ",
520     'I': "    " ~ 
521          " █  " ~ 
522          " █  ",
523     'J': "    " ~ 
524          "  █ " ~ 
525          "█▄█ ",
526     'K': "    " ~ 
527          "█▄▀ " ~ 
528          "█ █ ",
529     'L': "    " ~ 
530          "█   " ~ 
531          "█▄▄ ",
532     'M': "    " ~ 
533          "█▄█ " ~ 
534          "█ █ ",
535     'N': "    " ~ 
536          "█▀█ " ~ 
537          "█ █ ",
538     'O': "    " ~ 
539          "█▀█ " ~ 
540          "█▄█ ",
541     'P': "    " ~ 
542          "█▀█ " ~ 
543          "█▀▀ ",
544     'Q': "    " ~ 
545          "█▀█ " ~ 
546          "▀▀█ ",
547     'R': "    " ~ 
548          "█▀█ " ~ 
549          "█▀▄ ",
550     'S': "    " ~ 
551          "██▀ " ~ 
552          "▄▄█ ",
553     'T': "    " ~ 
554          "▀█▀ " ~ 
555          " █  ",
556     'U': "    " ~ 
557          "█ █ " ~ 
558          "█▄█ ",
559     'V': "    " ~ 
560          "█ █ " ~ 
561          "▀▄▀ ",
562     'W': "    " ~ 
563          "█ █ " ~ 
564          "▀██ ",
565     'X': "    " ~ 
566          "▀▄▀ " ~ 
567          "█ █ ",
568     'Y': "    " ~ 
569          "█▄█ " ~ 
570          " █  ",
571     'Z': "    " ~ 
572          "▀██ " ~ 
573          "█▄▄ ",
574     '0': "    " ~ 
575          "█▀█ " ~ 
576          "█▄█ ",
577     '1': "    " ~ 
578          "▄█  " ~ 
579          " █  ",
580     '2': "    " ~ 
581          "▀██ " ~ 
582          "█▄▄ ",
583     '3': "    " ~ 
584          "▀▀█ " ~ 
585          "▄██ ",
586     '4': "    " ~ 
587          "█ █ " ~ 
588          "▀▀█ ",
589     '5': "    " ~ 
590          "██▀ " ~ 
591          "▄▄█ ",
592     '6': "    " ~ 
593          "█▄▄ " ~ 
594          "█▄█ ",
595     '7': "    " ~ 
596          "▀▀█ " ~ 
597          "  █ ",
598     '8': "    " ~ 
599          "█▀█ " ~ 
600          "███ ",
601     '9': "    " ~ 
602          "█▀█ " ~ 
603          "▀▀█ ",
604     '&': "    " ~ 
605          "▄▀█ " ~ 
606          "██▄ ",
607     '*': "    " ~ 
608          "▀▄▀ " ~ 
609          "▀ ▀ ",
610     '+': "    " ~ 
611          "▄█▄ " ~ 
612          " ▀  ",
613     '-': "    " ~ 
614          "▄▄▄ " ~ 
615          "    ",
616     '~': "    " ~ 
617          "    " ~ 
618          "▄▀▀ ",
619     '_': "    " ~ 
620          "    " ~ 
621          "▄▄▄ ",
622     '=': "    " ~ 
623          "▄▄▄ " ~ 
624          "▄▄▄ ",
625     '.': "    " ~ 
626          "    " ~  
627          " ▄  ",
628     '!': "    " ~ 
629          " █  " ~
630          " ▄  ", 
631     '"': "    " ~ 
632          "▀ ▀ " ~  
633          "    ",
634     '\'':"    " ~ 
635          " ▀  " ~  
636          "    ",
637     '`': "    " ~ 
638          " ▀▄ " ~  
639          "    ",
640     '#': "    " ~ 
641          "█▄█ " ~ 
642          "█▀█ ",
643     '$': "    " ~ 
644          "██▀ " ~ 
645          "▄██ ",
646     '%': "    " ~ 
647          "▀▄▀ " ~ 
648          "█ ▄ ",
649     '^': "    " ~ 
650          " ▄  " ~  
651          "▀ ▀ ",
652     ',': "    " ~ 
653          "    " ~  
654          " ▄▀ ",
655     ':': "    " ~ 
656          " ▀  " ~  
657          " ▄  ",
658     ';': "    " ~ 
659          " ▀  " ~  
660          " ▄▀ ",
661     '?': "    " ~ 
662          "▀█  " ~
663          " ▄  ", 
664     '@': "    " ~ 
665          "▄▀█ " ~ 
666          "█▄█ ",
667     '/': "    " ~ 
668          " ▄▀ " ~ 
669          "█   ",
670     '<': "    " ~ 
671          " ▄▄ " ~ 
672          "▀▄▄ ",
673     '>': "    " ~ 
674          "▄▄  " ~ 
675          "▄▄▀ ",
676     '|': "    " ~ 
677          " █  " ~
678          " █  ", 
679     '\\':"    " ~ 
680          "▀▄  " ~ 
681          "  █ ",
682     '(': "    " ~ 
683          "▄▀  " ~ 
684          "▀▄  ",
685     ')': "    " ~ 
686          " ▀▄ " ~ 
687          " ▄▀ ",
688     '[': "    " ~ 
689          "█▀  " ~ 
690          "█▄  ",
691     ']': "    " ~ 
692          " ▀█ " ~ 
693          " ▄█ ",
694     '{': "    " ~ 
695          "▄▀  " ~ 
696          "█▄  ",
697     '}': "    " ~ 
698          " ▀▄ " ~ 
699          " ▄█ ",
700     ];
701     cast(void) pixelFont5x6.rehash;
702     cast(void) pixelFont3x4.rehash;
703 }
704 
705 // TODO 3x4?
706 
707 // ▄▀█ █▄▄ █▀▀ █▀▄ █▀▀ █▀▀ █▀▀ █ █ █   █ █▄▀ █   █▀▄▀█ █▄ █ █▀█ █▀█ █▀█ █▀█ █▀ ▀█▀ █ █ █ █ █ █ █ ▀▄▀ █▄█ ▀█
708 // █▀█ █▄█ █▄▄ █▄▀ ██▄ █▀  █▄█ █▀█ █ █▄█ █ █ █▄▄ █ ▀ █ █ ▀█ █▄█ █▀▀ ▀▀█ █▀▄ ▄█  █  █▄█ ▀▄▀ ▀▄▀▄▀ █ █  █  █▄
709 
710 //  ▄█ ▀█ ▀█ █ █ █▀ █▄▄ ▀▀█ █▀█ █▀█ █▀█
711 //   █ █▄ ██ ▀▀█ ▄█ █▄█   █ ███ ▀▀█ █▄█ 
712 
713 //  ▄▄ ▄█▄ ▀▀ ▀█ ▀ ▄▀ █ █ █▀ ▀█ ▀▄ 
714 //      ▀  ▀▀  ▄ ▄▀ ▄ █ ▄ █▄ ▄█   ▀▄
715