-
Notifications
You must be signed in to change notification settings - Fork 0
/
muTrueType.h
7600 lines (6483 loc) · 324 KB
/
muTrueType.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
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
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
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
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
muTrueType.h - Muukid
Public domain single-file C library for reading, rendering, and placing TrueType data.
https://github.com/Muukid/muTrueType
No warranty implied; use at your own risk.
Licensed under MIT License or public domain, whichever you prefer.
More explicit license information at the end of file.
@DOCBEGIN
# muTrueType v1.0.0
muTrueType (acronymized to "mutt") is a public domain single-file C library for retrieving data from the TrueType file format via its tables (the "[low-level API](#low-level-api)") and rasterizing glyphs to a bitmap (the "[raster API](#raster-api)"). Its header is automatically defined upon inclusion if not already included (`MUTT_H`), and the source code is defined if `MUTT_IMPLEMENTATION` is defined, following the internal structure of:
```c
#ifndef MUTT_H
#define MUTT_H
// (Header code)
#endif
#ifdef MUTT_IMPLEMENTATION
// (Source code)
#endif
```
Therefore, a standard inclusion of the file to get all automatic functionality looks like:
```c
#define MUTT_IMPLEMENTATION
#include "muTrueType.h"
```
More information about the general structure of a mu library is provided at [the mu library information GitHub repository](https://github.com/Muukid/mu-library-information).
# Demos
Demos are designed for mutt to both test its functionality and to allow users to get the basic idea of the structure of the library quickly without having to read the documentation in full. These demos are available in the `demos` folder.
## Demo resources
The demos use other files to operate correctly when running as a compiled executable. These other files can be found in the `resources` folder within `demos`, and this folder is expected to be in the same location that the program is executing from. For example, if a user compiles a demo into `main.exe`, and decides to run it, the `resources` folder from `demos` should be in the same directory as `main.exe`.
The resources' licenses may differ from the licensing of mutt itself; see the [license section that covers demo resources](#licensing-of-demo-resources).
## Demo include dependencies
Some demos use other include files to function properly. These files can be found in the `include` folder within `demos`, and should be within the user's include directory when compiling the demos.
# Licensing
mutt is licensed under public domain or MIT, whichever you prefer. More information is provided in the accompanying file `license.md` and at the bottom of `muTrueType.h`.
## Licensing of demo resources
The resources used by the demos may differ from licensing of the demos themselves; in that context, their licenses apply, with licensing of each file available as a separate file with the same name, but with no filename extension.
# Known bugs and limitations
This section covers all of the known bugs and limitations of mutt.
## Instruction support
Currently, mutt does not have any built-in way to execute any TrueType instructions.
## Limited table support
mutt is meant to be fairly simplistic for now, so it only supports reading information from all of the 9 required tables (besides post). Support for other tables may be added in future versions.
## Support for post table
mutt currently does not have support for reading values from the post table, which is one of the 9 required tables in the TrueType specification.
## Limited cmap format support
Currently, mutt only supports loading cmap formats 0, 4, and 12. This should be okay for most cases, with Apple's TrueType spec. saying, "Modern font generation tools might not need to be able to write general-purpose cmaps in formats other than 4 and 12."
## Optimal cmap conversions
mutt does not use the most efficient algorithms to convert codepoints to glyph IDs and vice versa for cmap formats.
## Fairly slow rendering
mutt is not particularly optimized extremely well in its rendering techniques, but could be optimized with fairly minimal effort in the future. It scans horizontal line by horizontal line, converting the glyph to a series of line segments and counting intersections. It considers each line segment for each horizontal line, which could be optimized by sorting the line segments in such a way that once a line is no longer being considered, every line before it is also not being considered. This optimization has yet to be implemented.
# TrueType documentation
Involved usage of the low-level API of mutt necessitates an understanding of the TrueType documentation. Terms from the TrueType documentation will be used with the assumption that the user has read it and understands these terms.
mutt is developed primarily off of these sources of documentation:
* [OpenType spec](https://learn.microsoft.com/en-us/typography/opentype/spec/).
* [TrueType reference manual](https://developer.apple.com/fonts/TrueType-Reference-Manual/).
@DOCEND
*/
#ifndef MUTT_H
#define MUTT_H
// @DOCLINE # Other library dependencies
// @DOCLINE mutt has a dependency on:
// @DOCLINE * [muUtility v2.0.1](https://github.com/Muukid/muUtility/releases/tag/v2.0.1).
// @IGNORE
#if !defined(MU_CHECK_VERSION_MISMATCHING) && defined(MUU_H) && \
(MUU_VERSION_MAJOR != 2 || MUU_VERSION_MINOR != 0 || MUU_VERSION_PATCH != 1)
#pragma message("[MUTT] muUtility's header has already been defined, but version doesn't match the version that this library is built for. This may lead to errors, warnings, or unexpected behavior. Define MU_CHECK_VERSION_MISMATCHING before this to turn off this message.")
#endif
#ifndef MUU_H
#define MUU_H
// @DOCLINE # Version
// @DOCLINE The macros `MUU_VERSION_MAJOR`, `MUU_VERSION_MINOR`, and `MUU_VERSION_PATCH` are defined to match its respective release version, following the formatting of `MAJOR.MINOR.PATCH`.
#define MUU_VERSION_MAJOR 2
#define MUU_VERSION_MINOR 0
#define MUU_VERSION_PATCH 1
// @DOCLINE # `MUDEF`
// @DOCLINE The `MUDEF` macro is used by virtually all mu libraries, and is generally added before a header-defined variable or function. Its default value is `extern`, but can be changed to `static` by defining `MU_STATIC` before the header section of muUtility is defined. Its value can also be overwritten entirely to anything else by directly defining `MUDEF`.
#ifndef MUDEF
#ifdef MU_STATIC
#define MUDEF static
#else
#define MUDEF extern
#endif
#endif
// @DOCLINE # Secure warnings
// @DOCLINE mu libraries often use non-secure functions that will trigger warnings on certain compilers. These warnings are, to put it lightly, dumb, so muUtility defines `_CRT_SECURE_NO_WARNINGS`. However, it is not guaranteed that this definition will actually turn the warnings off, which, at that point, they have to be manually turned off by the user. This functionality can be turned off by defining `MU_SECURE_WARNINGS`.
#if !defined(MU_SECURE_WARNINGS) && !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
// @DOCLINE # C++ extern
// @DOCLINE Every mu library's primary code externs "C" within the main chunks of their code; macros `MU_CPP_EXTERN_START` and `MU_CPP_EXTERN_END` are defined to make this process easier, and would read like this:
/* @DOCBEGIN
```
MU_CPP_EXTERN_START
// Library code goes here...
MU_CPP_EXTERN_END
```
@DOCEND */
#ifdef __cplusplus
#define MU_CPP_EXTERN_START extern "C" {
#define MU_CPP_EXTERN_END }
#else
#define MU_CPP_EXTERN_START
#define MU_CPP_EXTERN_END
#endif
MU_CPP_EXTERN_START
// @DOCLINE # C standard library dependencies
// @DOCLINE muUtility has several C standard library dependencies, all of which are overridable by defining them before the inclusion of the file. The following is a list of those dependencies.
// @DOCLINE ## `stdint.h` dependencies
#if !defined(int8_m) || \
!defined(uint8_m) || \
!defined(int16_m) || \
!defined(uint16_m) || \
!defined(int32_m) || \
!defined(uint32_m) || \
!defined(int64_m) || \
!defined(uint64_m) || \
!defined(MU_SIZE_MAX)
#define __STDC_LIMIT_MACROS
#define __STDC_CONSTANT_MACROS
#include <stdint.h>
// @DOCLINE * `int8_m` - equivalent to `int8_t` if `INT8_MAX` is defined; `char` if otherwise.
#ifndef int8_m
#ifdef INT8_MAX
#define int8_m int8_t
#else
#define int8_m char
#endif
#endif
// @DOCLINE * `uint8_m` - equivalent to `uint8_t` if `UINT8_MAX` is defined; `unsigned char` if otherwise.
#ifndef uint8_m
#ifdef UINT8_MAX
#define uint8_m uint8_t
#else
#define uint8_m unsigned char
#endif
#endif
// @DOCLINE * `int16_m` - equivalent to `int16_t` if `INT16_MAX` is defined; `short` if otherwise.
#ifndef int16_m
#ifdef INT16_MAX
#define int16_m int16_t
#else
#define int16_m short
#endif
#endif
// @DOCLINE * `uint16_m` - equivalent to `uint16_t` if `UINT16_MAX` is defined; `unsigned short` if otherwise.
#ifndef uint16_m
#ifdef UINT16_MAX
#define uint16_m uint16_t
#else
#define uint16_m unsigned short
#endif
#endif
// @DOCLINE * `int32_m` - equivalent to `int32_t` if `INT32_MAX` is defined; `long` if otherwise.
#ifndef int32_m
#ifdef INT32_MAX
#define int32_m int32_t
#else
#define int32_m long
#endif
#endif
// @DOCLINE * `uint32_m` - equivalent to `uint32_t` if `UINT32_MAX` is defined; `unsigned long` if otherwise.
#ifndef uint32_m
#ifdef UINT32_MAX
#define uint32_m uint32_t
#else
#define uint32_m unsigned long
#endif
#endif
// @DOCLINE * `int64_m` - equivalent to `int64_t` if `INT64_MAX` is defined; `long long` if otherwise.
#ifndef int64_m
#ifdef INT64_MAX
#define int64_m int64_t
#else
#define int64_m long long
#endif
#endif
// @DOCLINE * `uint64_m` - equivalent to `uint64_t` if `UINT64_MAX` is defined; `unsigned long long` if otherwise.
#ifndef uint64_m
#ifdef UINT64_MAX
#define uint64_m uint64_t
#else
#define uint64_m unsigned long long
#endif
#endif
// @DOCLINE * `MU_SIZE_MAX` - equivalent to `SIZE_MAX`.
#ifndef MU_SIZE_MAX
#define MU_SIZE_MAX SIZE_MAX
#endif
#endif /* stdint.h */
// @DOCLINE ## `stddef.h` dependencies
#if !defined(size_m)
#include <stddef.h>
// @DOCLINE * `size_m` - equivalent to `size_t`.
#ifndef size_m
#define size_m size_t
#endif
#endif /* stddef.h */
// @DOCLINE ## `stdbool.h` dependencies
#if !defined(muBool) || \
!defined(MU_TRUE) || \
!defined(MU_FALSE)
#include <stdbool.h>
// @DOCLINE * `muBool` - equivalent to `bool`.
#ifndef muBool
#define muBool bool
#endif
// @DOCLINE * `MU_TRUE` - equivalent to `true`.
#ifndef MU_TRUE
#define MU_TRUE true
#endif
// @DOCLINE * `MU_FALSE` - equivalent to `false`.
#ifndef MU_FALSE
#define MU_FALSE false
#endif
#endif /* stdbool.h */
// @DOCLINE # Zero struct
// @DOCLINE There are two macros, `MU_ZERO_STRUCT` and `MU_ZERO_STRUCT_CONST`, which are functions used to zero-out a struct's contents, with their only parameter being the struct type. The reason this needs to be defined is because the way C and C++ syntax handles an empty struct are different, and need to be adjusted for. These macros are overridable by defining them before `muUtility.h` is included.
#ifndef MU_ZERO_STRUCT
#ifdef __cplusplus
#define MU_ZERO_STRUCT(s) {}
#else
#define MU_ZERO_STRUCT(s) (s){0}
#endif
#endif
#ifndef MU_ZERO_STRUCT_CONST
#ifdef __cplusplus
#define MU_ZERO_STRUCT_CONST(s) {}
#else
#define MU_ZERO_STRUCT_CONST(s) {0}
#endif
#endif
// @DOCLINE # Byte manipulation
// @DOCLINE muUtility defines several inline functions that read a value from a given array of bytes. Internally, they're all defined with the prefix `muu_...`, and then a macro is defined for them as `MU_...` (with change in capitalization after the prefix as well). The macros for these functions can be overridden, and, in such case, the original function will go undefined. For example, the function `muu_rleu8` is primarily referenced via the macro `MU_RLEU8`, and if `MU_RLEU8` is overridden, `muu_rleu8` is never defined and is not referenceable.
// @DOCLINE All reading functions take in a pointer of bytes as their only parameter and have a return type of the fixed-width size of bits in question; for example, `muu_rleu8` is defined as:
/* @DOCBEGIN
```
MUDEF inline uint8_m muu_rleu8(muByte* b);
```
@DOCEND */
// @DOCLINE All writing functions take in a pointer of bytes as their first parameter, the number to be written as the second parameter, and have a return type of void; for example, `muu_wleu8` is defined as:
/* @DOCBEGIN
```
MUDEF inline void muu_wleu8(muByte* b, uint8_m n);
```
@DOCEND */
// @DOCLINE The exception to this is 24-bit, in which case, the fixed-width types are 32-bit (`uint32_m` / `int32_m`).
// @DOCLINE ## Byte type
// @DOCLINE muUtility defines the type `muByte` to refer to a byte. It is defined as `uint8_m`, and is overridable.
#ifndef muByte
#define muByte uint8_m
#endif
// @DOCLINE ## 8-bit
// @DOCLINE The following macros exist for byte manipulation regarding 8-bit integers:
// @DOCLINE * `MU_RLEU8` - reads an unsigned 8-bit integer from little-endian byte data; overridable macro to `muu_rleu8`.
#ifndef MU_RLEU8
MUDEF inline uint8_m muu_rleu8(muByte* b) {
return b[0];
}
#define MU_RLEU8 muu_rleu8
#endif
// @DOCLINE * `MU_WLEU8` - writes an unsigned 8-bit integer to little-endian byte data; overridable macro to `muu_wleu8`.
#ifndef MU_WLEU8
MUDEF inline void muu_wleu8(muByte* b, uint8_m n) {
b[0] = n;
}
#define MU_WLEU8 muu_wleu8
#endif
// @DOCLINE * `MU_RLES8` - reads a signed 8-bit integer from little-endian byte data; overridable macro to `muu_rles8`.
#ifndef MU_RLES8
MUDEF inline int8_m muu_rles8(muByte* b) {
// I'm PRETTY sure this is okay...
return *(int8_m*)b;
}
#define MU_RLES8 muu_rles8
#endif
// @DOCLINE * `MU_WLES8` - writes a signed 8-bit integer to little-endian byte data; overridable macro to `muu_wles8`.
#ifndef MU_WLES8
MUDEF inline void muu_wles8(muByte* b, int8_m n) {
((int8_m*)(b))[0] = n;
}
#define MU_WLES8 muu_wles8
#endif
// @DOCLINE * `MU_RBEU8` - reads an unsigned 8-bit integer from big-endian byte data; overridable macro to `muu_rbeu8`.
#ifndef MU_RBEU8
MUDEF inline uint8_m muu_rbeu8(muByte* b) {
return b[0];
}
#define MU_RBEU8 muu_rbeu8
#endif
// @DOCLINE * `MU_WBEU8` - writes an unsigned 8-bit integer to big-endian byte data; overridable macro to `muu_wbeu8`.
#ifndef MU_WBEU8
MUDEF inline void muu_wbeu8(muByte* b, uint8_m n) {
b[0] = n;
}
#define MU_WBEU8 muu_wbeu8
#endif
// @DOCLINE * `MU_RBES8` - reads a signed 8-bit integer from big-endian byte data; overridable macro to `muu_rbes8`.
#ifndef MU_RBES8
MUDEF inline int8_m muu_rbes8(muByte* b) {
return *(int8_m*)b;
}
#define MU_RBES8 muu_rbes8
#endif
// @DOCLINE * `MU_WBES8` - writes a signed 8-bit integer to big-endian byte data; overridable macro to `muu_wbes8`.
#ifndef MU_WBES8
MUDEF inline void muu_wbes8(muByte* b, int8_m n) {
((int8_m*)(b))[0] = n;
}
#define MU_WBES8 muu_wbes8
#endif
// @DOCLINE ## 16-bit
// @DOCLINE The following macros exist for byte manipulation regarding 16-bit integers:
// @DOCLINE * `MU_RLEU16` - reads an unsigned 16-bit integer from little-endian byte data; overridable macro to `muu_rleu16`.
#ifndef MU_RLEU16
MUDEF inline uint16_m muu_rleu16(muByte* b) {
return (
((uint16_m)(b[0]) << 0) |
((uint16_m)(b[1]) << 8)
);
}
#define MU_RLEU16 muu_rleu16
#endif
// @DOCLINE * `MU_WLEU16` - writes an unsigned 16-bit integer to little-endian byte data; overridable macro to `muu_wleu16`.
#ifndef MU_WLEU16
MUDEF inline void muu_wleu16(muByte* b, uint16_m n) {
b[0] = (uint8_m)(n >> 0);
b[1] = (uint8_m)(n >> 8);
}
#define MU_WLEU16 muu_wleu16
#endif
// @DOCLINE * `MU_RLES16` - reads a signed 16-bit integer from little-endian byte data; overridable macro to `muu_rles16`.
#ifndef MU_RLES16
MUDEF inline int16_m muu_rles16(muByte* b) {
uint16_m u16 = muu_rleu16(b);
return *(int16_m*)&u16;
}
#define MU_RLES16 muu_rles16
#endif
// @DOCLINE * `MU_WLES16` - writes a signed 16-bit integer to little-endian byte data; overridable macro to `muu_wles16`.
#ifndef MU_WLES16
MUDEF inline void muu_wles16(muByte* b, int16_m n) {
uint16_m un = *(uint16_m*)&n;
b[0] = (uint8_m)(un >> 0);
b[1] = (uint8_m)(un >> 8);
}
#define MU_WLES16 muu_wles16
#endif
// @DOCLINE * `MU_RBEU16` - reads an unsigned 16-bit integer from big-endian byte data; overridable macro to `muu_rbeu16`.
#ifndef MU_RBEU16
MUDEF inline uint16_m muu_rbeu16(muByte* b) {
return (
((uint16_m)(b[1]) << 0) |
((uint16_m)(b[0]) << 8)
);
}
#define MU_RBEU16 muu_rbeu16
#endif
// @DOCLINE * `MU_WBEU16` - writes an unsigned 16-bit integer to big-endian byte data; overridable macro to `muu_wbeu16`.
#ifndef MU_WBEU16
MUDEF inline void muu_wbeu16(muByte* b, uint16_m n) {
b[1] = (uint8_m)(n >> 0);
b[0] = (uint8_m)(n >> 8);
}
#define MU_WBEU16 muu_wbeu16
#endif
// @DOCLINE * `MU_RBES16` - reads a signed 16-bit integer from big-endian byte data; overridable macro to `muu_rbes16`.
#ifndef MU_RBES16
MUDEF inline int16_m muu_rbes16(muByte* b) {
uint16_m u16 = muu_rbeu16(b);
return *(int16_m*)&u16;
}
#define MU_RBES16 muu_rbes16
#endif
// @DOCLINE * `MU_WBES16` - writes a signed 16-bit integer to big-endian byte data; overridable macro to `muu_wbes16`.
#ifndef MU_WBES16
MUDEF inline void muu_wbes16(muByte* b, int16_m n) {
uint16_m un = *(uint16_m*)&n;
b[1] = (uint8_m)(un >> 0);
b[0] = (uint8_m)(un >> 8);
}
#define MU_WBES16 muu_wbes16
#endif
// @DOCLINE ## 24-bit
// @DOCLINE The following macros exist for byte manipulation regarding 24-bit integers:
// @DOCLINE * `MU_RLEU24` - reads an unsigned 24-bit integer from little-endian byte data; overridable macro to `muu_rleu24`.
#ifndef MU_RLEU24
MUDEF inline uint32_m muu_rleu24(muByte* b) {
return (
((uint32_m)(b[0]) << 0) |
((uint32_m)(b[1]) << 8) |
((uint32_m)(b[2]) << 16)
);
}
#define MU_RLEU24 muu_rleu24
#endif
// @DOCLINE * `MU_WLEU24` - writes an unsigned 24-bit integer to little-endian byte data; overridable macro to `muu_wleu24`.
#ifndef MU_WLEU24
MUDEF inline void muu_wleu24(muByte* b, uint32_m n) {
b[0] = (uint8_m)(n >> 0);
b[1] = (uint8_m)(n >> 8);
b[2] = (uint8_m)(n >> 16);
}
#define MU_WLEU24 muu_wleu24
#endif
// @DOCLINE * `MU_RLES24` - reads a signed 24-bit integer from little-endian byte data; overridable macro to `muu_rles24`.
#ifndef MU_RLES24
MUDEF inline int32_m muu_rles24(muByte* b) {
uint32_m u24 = muu_rleu24(b);
return *(int32_m*)&u24;
}
#define MU_RLES24 muu_rles24
#endif
// @DOCLINE * `MU_WLES24` - writes a signed 24-bit integer to little-endian byte data; overridable macro to `muu_wles24`.
#ifndef MU_WLES24
MUDEF inline void muu_wles24(muByte* b, int32_m n) {
// Probably definitely doesn't work with signed integers; fix later
uint32_m un = *(uint32_m*)&n;
b[0] = (uint8_m)(un >> 0);
b[1] = (uint8_m)(un >> 8);
b[2] = (uint8_m)(un >> 16);
}
#define MU_WLES24 muu_wles24
#endif
// @DOCLINE * `MU_RBEU24` - reads an unsigned 24-bit integer from big-endian byte data; overridable macro to `muu_rbeu24`.
#ifndef MU_RBEU24
MUDEF inline uint32_m muu_rbeu24(muByte* b) {
return (
((uint32_m)(b[2]) << 0) |
((uint32_m)(b[1]) << 8) |
((uint32_m)(b[0]) << 16)
);
}
#define MU_RBEU24 muu_rbeu24
#endif
// @DOCLINE * `MU_WBEU24` - writes an unsigned 24-bit integer to big-endian byte data; overridable macro to `muu_wbeu24`.
#ifndef MU_WBEU24
MUDEF inline void muu_wbeu24(muByte* b, uint32_m n) {
b[2] = (uint8_m)(n >> 0);
b[1] = (uint8_m)(n >> 8);
b[0] = (uint8_m)(n >> 16);
}
#define MU_WBEU24 muu_wbeu24
#endif
// @DOCLINE * `MU_RBES24` - reads a signed 24-bit integer from big-endian byte data; overridable macro to `muu_rbes24`.
#ifndef MU_RBES24
MUDEF inline int32_m muu_rbes24(muByte* b) {
uint32_m u24 = muu_rbeu24(b);
return *(int32_m*)&u24;
}
#define MU_RBES24 muu_rbes24
#endif
// @DOCLINE * `MU_WBES24` - writes a signed 24-bit integer to big-endian byte data; overridable macro to `muu_wbes24`.
#ifndef MU_WBES24
MUDEF inline void muu_wbes24(muByte* b, int32_m n) {
uint32_m un = *(uint32_m*)&n;
b[2] = (uint8_m)(un >> 0);
b[1] = (uint8_m)(un >> 8);
b[0] = (uint8_m)(un >> 16);
}
#define MU_WBES24 muu_wbes24
#endif
// @DOCLINE ## 32-bit
// @DOCLINE The following macros exist for byte manipulation regarding 32-bit integers:
// @DOCLINE * `MU_RLEU32` - reads an unsigned 32-bit integer from little-endian byte data; overridable macro to `muu_rleu32`.
#ifndef MU_RLEU32
MUDEF inline uint32_m muu_rleu32(muByte* b) {
return (
((uint32_m)(b[0]) << 0) |
((uint32_m)(b[1]) << 8) |
((uint32_m)(b[2]) << 16) |
((uint32_m)(b[3]) << 24)
);
}
#define MU_RLEU32 muu_rleu32
#endif
// @DOCLINE * `MU_WLEU32` - writes an unsigned 32-bit integer to little-endian byte data; overridable macro to `muu_wleu32`.
#ifndef MU_WLEU32
MUDEF inline void muu_wleu32(muByte* b, uint32_m n) {
b[0] = (uint8_m)(n >> 0);
b[1] = (uint8_m)(n >> 8);
b[2] = (uint8_m)(n >> 16);
b[3] = (uint8_m)(n >> 24);
}
#define MU_WLEU32 muu_wleu32
#endif
// @DOCLINE * `MU_RLES32` - reads a signed 32-bit integer from little-endian byte data; overridable macro to `muu_rles32`.
#ifndef MU_RLES32
MUDEF inline int32_m muu_rles32(muByte* b) {
uint32_m u32 = muu_rleu32(b);
return *(int32_m*)&u32;
}
#define MU_RLES32 muu_rles32
#endif
// @DOCLINE * `MU_WLES32` - writes a signed 32-bit integer to little-endian byte data; overridable macro to `muu_wles32`.
#ifndef MU_WLES32
MUDEF inline void muu_wles32(muByte* b, int32_m n) {
uint32_m un = *(uint32_m*)&n;
b[0] = (uint8_m)(un >> 0);
b[1] = (uint8_m)(un >> 8);
b[2] = (uint8_m)(un >> 16);
b[3] = (uint8_m)(un >> 24);
}
#define MU_WLES32 muu_wles32
#endif
// @DOCLINE * `MU_RBEU32` - reads an unsigned 32-bit integer from big-endian byte data; overridable macro to `muu_rbeu32`.
#ifndef MU_RBEU32
MUDEF inline uint32_m muu_rbeu32(muByte* b) {
return (
((uint32_m)(b[3]) << 0) |
((uint32_m)(b[2]) << 8) |
((uint32_m)(b[1]) << 16) |
((uint32_m)(b[0]) << 24)
);
}
#define MU_RBEU32 muu_rbeu32
#endif
// @DOCLINE * `MU_WBEU32` - writes an unsigned 32-bit integer to big-endian byte data; overridable macro to `muu_wbeu32`.
#ifndef MU_WBEU32
MUDEF inline void muu_wbeu32(muByte* b, uint32_m n) {
b[3] = (uint8_m)(n >> 0);
b[2] = (uint8_m)(n >> 8);
b[1] = (uint8_m)(n >> 16);
b[0] = (uint8_m)(n >> 24);
}
#define MU_WBEU32 muu_wbeu32
#endif
// @DOCLINE * `MU_RBES32` - reads a signed 32-bit integer from big-endian byte data; overridable macro to `muu_rbes32`.
#ifndef MU_RBES32
MUDEF inline int32_m muu_rbes32(muByte* b) {
uint32_m u32 = muu_rbeu32(b);
return *(int32_m*)&u32;
}
#define MU_RBES32 muu_rbes32
#endif
// @DOCLINE * `MU_WBES32` - writes a signed 32-bit integer to big-endian byte data; overridable macro to `muu_wbes32`.
#ifndef MU_WBES32
MUDEF inline void muu_wbes32(muByte* b, int32_m n) {
uint32_m un = *(uint32_m*)&n;
b[3] = (uint8_m)(un >> 0);
b[2] = (uint8_m)(un >> 8);
b[1] = (uint8_m)(un >> 16);
b[0] = (uint8_m)(un >> 24);
}
#define MU_WBES32 muu_wbes32
#endif
// @DOCLINE ## 64-bit
// @DOCLINE The following macros exist for byte manipulation regarding 64-bit integers:
// @DOCLINE * `MU_RLEU64` - reads an unsigned 64-bit integer from little-endian byte data; overridable macro to `muu_rleu64`.
#ifndef MU_RLEU64
MUDEF inline uint64_m muu_rleu64(muByte* b) {
return (
((uint64_m)(b[0]) << 0) |
((uint64_m)(b[1]) << 8) |
((uint64_m)(b[2]) << 16) |
((uint64_m)(b[3]) << 24) |
((uint64_m)(b[4]) << 32) |
((uint64_m)(b[5]) << 40) |
((uint64_m)(b[6]) << 48) |
((uint64_m)(b[7]) << 56)
);
}
#define MU_RLEU64 muu_rleu64
#endif
// @DOCLINE * `MU_WLEU64` - writes an unsigned 64-bit integer to little-endian byte data; overridable macro to `muu_wleu64`.
#ifndef MU_WLEU64
MUDEF inline void muu_wleu64(muByte* b, uint64_m n) {
b[0] = (uint8_m)(n >> 0);
b[1] = (uint8_m)(n >> 8);
b[2] = (uint8_m)(n >> 16);
b[3] = (uint8_m)(n >> 24);
b[4] = (uint8_m)(n >> 32);
b[5] = (uint8_m)(n >> 40);
b[6] = (uint8_m)(n >> 48);
b[7] = (uint8_m)(n >> 56);
}
#define MU_WLEU64 muu_wleu64
#endif
// @DOCLINE * `MU_RLES64` - reads a signed 64-bit integer from little-endian byte data; overridable macro to `muu_rles64`.
#ifndef MU_RLES64
MUDEF inline int64_m muu_rles64(muByte* b) {
uint64_m u64 = muu_rleu64(b);
return *(int64_m*)&u64;
}
#define MU_RLES64 muu_rles64
#endif
// @DOCLINE * `MU_WLES64` - writes a signed 64-bit integer to little-endian byte data; overridable macro to `muu_wles64`.
#ifndef MU_WLES64
MUDEF inline void muu_wles64(muByte* b, int64_m n) {
uint64_m un = *(uint64_m*)&n;
b[0] = (uint8_m)(un >> 0);
b[1] = (uint8_m)(un >> 8);
b[2] = (uint8_m)(un >> 16);
b[3] = (uint8_m)(un >> 24);
b[4] = (uint8_m)(un >> 32);
b[5] = (uint8_m)(un >> 40);
b[6] = (uint8_m)(un >> 48);
b[7] = (uint8_m)(un >> 56);
}
#define MU_WLES64 muu_wles64
#endif
// @DOCLINE * `MU_RBEU64` - reads an unsigned 64-bit integer from big-endian byte data; overridable macro to `muu_rbeu64`.
#ifndef MU_RBEU64
MUDEF inline uint64_m muu_rbeu64(muByte* b) {
return (
((uint64_m)(b[7]) << 0) |
((uint64_m)(b[6]) << 8) |
((uint64_m)(b[5]) << 16) |
((uint64_m)(b[4]) << 24) |
((uint64_m)(b[3]) << 32) |
((uint64_m)(b[2]) << 40) |
((uint64_m)(b[1]) << 48) |
((uint64_m)(b[0]) << 56)
);
}
#define MU_RBEU64 muu_rbeu64
#endif
// @DOCLINE * `MU_WBEU64` - writes an unsigned 64-bit integer to big-endian byte data; overridable macro to `muu_wbeu64`.
#ifndef MU_WBEU64
MUDEF inline void muu_wbeu64(muByte* b, uint64_m n) {
b[7] = (uint8_m)(n >> 0);
b[6] = (uint8_m)(n >> 8);
b[5] = (uint8_m)(n >> 16);
b[4] = (uint8_m)(n >> 24);
b[3] = (uint8_m)(n >> 32);
b[2] = (uint8_m)(n >> 40);
b[1] = (uint8_m)(n >> 48);
b[0] = (uint8_m)(n >> 56);
}
#define MU_WBEU64 muu_wbeu64
#endif
// @DOCLINE * `MU_RBES64` - reads a signed 64-bit integer from big-endian byte data; overridable macro to `muu_rbes64`.
#ifndef MU_RBES64
MUDEF inline int64_m muu_rbes64(muByte* b) {
uint64_m u64 = muu_rbeu64(b);
return *(int64_m*)&u64;
}
#define MU_RBES64 muu_rbes64
#endif
// @DOCLINE * `MU_WBES64` - writes a signed 64-bit integer to big-endian byte data; overridable macro to `muu_wbes64`.
#ifndef MU_WBES64
MUDEF inline void muu_wbes64(muByte* b, int64_m n) {
uint64_m un = *(uint64_m*)&n;
b[7] = (uint8_m)(un >> 0);
b[6] = (uint8_m)(un >> 8);
b[5] = (uint8_m)(un >> 16);
b[4] = (uint8_m)(un >> 24);
b[3] = (uint8_m)(un >> 32);
b[2] = (uint8_m)(un >> 40);
b[1] = (uint8_m)(un >> 48);
b[0] = (uint8_m)(un >> 56);
}
#define MU_WBES64 muu_wbes64
#endif
// @DOCLINE # Set result
/* @DOCBEGIN
The `MU_SET_RESULT(res, val)` macro is an overridable function that checks if the given parameter `res` is a null pointer. If it is, it does nothing, but if it isn't, it dereferences the pointer and sets the value to `val`. This macro saves a lot of code, shrinking down what would be this:
```c
if (result) {
*result = ...;
}
```
into this:
```c
MU_SET_RESULT(result, ...)
```
@DOCEND */
#ifndef MU_SET_RESULT
#define MU_SET_RESULT(res, val) if(res){*res=val;}
#endif
// @DOCLINE # Enum
/* @DOCBEGIN
The `MU_ENUM(name, ...)` macro is an overridable function used to declare an enumerator. `name` is the name of the enumerator type, and `...` are all of the values. The reason why one would prefer this over the traditional way of declaring enumerators is because it actually makes it a `size_m`, which can avoid errors on certain compilers (looking at you, Microsoft) in regards to treating enumerators like values. It expands like this:
```c
enum _##name {
__VA_ARGS__
};
typedef enum _##name _##name;
typedef size_m name;
```
@DOCEND */
#define MU_ENUM(name, ...) enum _##name{__VA_ARGS__};typedef enum _##name _##name;typedef size_m name;
// @DOCLINE # Operating system recognition
/* @DOCBEGIN
The macros `MU_WIN32` or `MU_LINUX` are defined (if neither were defined before) in order to allow mu libraries to easily check if they're running on a Windows or Linux system.
`MU_WIN32` will be defined if `WIN32` or `_WIN32` are defined, one of which is usually pre-defined on Windows systems.
`MU_LINUX` will be defined if `__linux__` is defined.
@DOCEND */
#if !defined(MU_WIN32) && !defined(MU_LINUX)
#if defined(WIN32) || defined(_WIN32)
#define MU_WIN32
#endif
#if defined(__linux__)
#define MU_LINUX
#endif
#endif
MU_CPP_EXTERN_END
#endif /* MUU_H */
// @ATTENTION
// @DOCLINE > Note that mu libraries store their dependencies within their files, so you don't need to import these dependencies yourself; this section is purely to provide more information about the contents that this file defines. The libraries listed may also have other dependencies that they also include that aren't explicitly listed here.
MU_CPP_EXTERN_START
// Typedefs explained later
typedef uint32_m muttResult;
// @DOCLINE # Loading a TrueType font
typedef struct muttFont muttFont;
// @DOCLINE All major parts of the mutt API rely on loading a TrueType font and then reading data from it, which is encapsulated in the `muttFont` struct, which is described [later in the lower-level API section](#font-struct). Most casual usage of the mutt API only needs to treat `muttFont` as a handle to the font itself.
// @DOCLINE ## Loading a font
typedef uint32_m muttLoadFlags;
// @DOCLINE To load a TrueType font into a `muttFont` struct, the function `mutt_load` is used, defined below: @NLNT
MUDEF muttResult mutt_load(muByte* data, uint64_m datalen, muttFont* font, muttLoadFlags load_flags);
// @DOCLINE `data` and `datalen` should be the raw binary data of the font file, and should be loaded by the user themselves. `font` is the `muttFont` struct to be filled in with information after loading. `load_flags` is a value whose bits indicate which tables to load; more elaboration on this is given in the [load flags section](#font-load-flags).
// @DOCLINE If the result returned by mutt is fatal, the contents of `font` are undefined. If the result returned by mutt isn't fatal, the font has been successfully loaded, and must be deloaded at some point.
// @DOCLINE Once this function has finished executing, there are no internal dependencies on the pointer to the data given, and can be safely freed.
// @DOCLINE ## Deloading a font
// @DOCLINE To deload a font, the function `mutt_deload` is used, defined below: @NLNT
MUDEF void mutt_deload(muttFont* font);
// @DOCLINE This function must be called on every successfully loaded font at some point. The contents of `font` are undefined after `mutt_deload` has been called on it.
// @DOCLINE ## Font load flags
// @DOCLINE To customize what tables are loaded when loading a TrueType font, the type `muttLoadFlags` exists (typedef for `uint32_m`) whose bits indicate what tables should be loaded. It has the following defined values:
// @DOCLINE * [0x00000001] `MUTT_LOAD_MAXP` - load the [maxp table](#maxp-table).
#define MUTT_LOAD_MAXP 0x00000001
// @DOCLINE * [0x00000002] `MUTT_LOAD_HEAD` - load the [head table](#head-table).
#define MUTT_LOAD_HEAD 0x00000002
// @DOCLINE * [0x00000004] `MUTT_LOAD_HHEA` - load the [hhea table](#hhea-table).
#define MUTT_LOAD_HHEA 0x00000004
// @DOCLINE * [0x00000008] `MUTT_LOAD_HMTX` - load the [hmtx table](#hmtx-table).
#define MUTT_LOAD_HMTX 0x00000008
// @DOCLINE * [0x00000010] `MUTT_LOAD_LOCA` - load the [loca table](#loca-table).
#define MUTT_LOAD_LOCA 0x00000010
// @DOCLINE * [0x00000020] `MUTT_LOAD_POST` - load the post table.
#define MUTT_LOAD_POST 0x00000020
// @DOCLINE * [0x00000040] `MUTT_LOAD_NAME` - load the [name table](#name-table).
#define MUTT_LOAD_NAME 0x00000040
// @DOCLINE * [0x00000080] `MUTT_LOAD_GLYF` - load the [glyf table](#glyf-table).
#define MUTT_LOAD_GLYF 0x00000080
// @DOCLINE * [0x00000100] `MUTT_LOAD_CMAP` - load the [cmap table](#cmap-table).
#define MUTT_LOAD_CMAP 0x00000100
// @DOCLINE To see which tables successfully loaded, see the [section covering the font struct](#font-struct).
// @DOCLINE ### Font load flag groups
// @DOCLINE For most users, it is unnecessary or confusing to specify all the tables they want manually, so several macros are defined that set the bits for several tables. These are the defined flag groups:
// @DOCLINE * [0x000001FF] `MUTT_LOAD_REQUIRED` - load the tables required by the TrueType specification (maxp, head, hhea, hmtx, loca, post, name, glyf, and cmap).
#define MUTT_LOAD_REQUIRED 0x000001FF
// @DOCLINE * [0xFFFFFFFF] `MUTT_LOAD_ALL` - loads all tables that could be supported by mutt.
#define MUTT_LOAD_ALL 0xFFFFFFFF
// @DOCLINE # Low-level API
// @DOCLINE The low-level API of mutt is designed to support reading information from the tables provided by TrueType. It is used internally by all other parts of the mutt API. All values provided by the low-level API have been checked to be valid, and are guaranteed to be valid once given to the user, unless explicitly stated otherwise.
// @DOCLINE ## Font struct
typedef struct muttDirectory muttDirectory;
typedef struct muttMaxp muttMaxp;
typedef struct muttHead muttHead;
typedef struct muttHhea muttHhea;
typedef struct muttHmtx muttHmtx;
typedef union muttLoca muttLoca;
typedef struct muttPost muttPost;
typedef struct muttName muttName;
typedef struct muttGlyf muttGlyf;
typedef struct muttCmap muttCmap;
// @DOCLINE The font struct, `muttFont`, is the primary way of reading information from TrueType tables, holding pointers to each table's defined data, and is automatically filled using the function [`mutt_load`](#loading-a-font). It has the following members:
struct muttFont {
// @DOCLINE * `@NLFT load_flags` - flags indicating which requested tables successfully loaded.
muttLoadFlags load_flags;
// @DOCLINE * `@NLFT fail_load_flags` - flags indicating which requested tables did not successfully load.
muttLoadFlags fail_load_flags;
// @DOCLINE * `@NLFT* directory` - a pointer to the [font directory](#font-directory).
muttDirectory* directory;
// @DOCLINE * `@NLFT* maxp` - a pointer to the [maxp table](#maxp-table).
muttMaxp* maxp;
// @DOCLINE * `@NLFT maxp_res` - the result of attempting to load the maxp table.
muttResult maxp_res;
// @DOCLINE * `@NLFT* head` - a pointer to the [head table](#head-table).
muttHead* head;
// @DOCLINE * `@NLFT head_res` - the result of attempting to load the head table.
muttResult head_res;
// @DOCLINE * `@NLFT* hhea` - a pointer to the [hhea table](#hhea-table).
muttHhea* hhea;
// @DOCLINE * `@NLFT hhea_res` - the result of attempting to load the hhea table.
muttResult hhea_res;
// @DOCLINE * `@NLFT* hmtx` - a pointer to the [hmtx table](#hmtx-table).
muttHmtx* hmtx;
// @DOCLINE * `@NLFT hmtx_res` - the result of attempting to load the hmtx table.
muttResult hmtx_res;
// @DOCLINE * `@NLFT* loca` - a pointer to the [loca table](#loca-table).
muttLoca* loca;
// @DOCLINE * `@NLFT loca_res` - the result of attempting to load the loca table.
muttResult loca_res;
// @DOCLINE * `@NLFT* post` - a pointer to the post table.
muttPost* post;
// @DOCLINE * `@NLFT post_res` - the result of attempting to load the post table.
muttResult post_res;
// @DOCLINE * `@NLFT* name` - a pointer to the [name table](#name-table).
muttName* name;
// @DOCLINE * `@NLFT name_res` - the result of attempting to load the name table.
muttResult name_res;
// @DOCLINE * `@NLFT* glyf` - a pointer to the [glyf table](#glyf-table).
muttGlyf* glyf;
// @DOCLINE * `@NLFT glyf_res` - the result of attempting to load the glyf table.
muttResult glyf_res;