1 /*
2     Copyright © 2020, Inochi2D Project
3     Distributed under the 2-Clause BSD License, see LICENSE file.
4     
5     Authors: Luna Nielsen
6 */
7 module creator.core.font;
8 import creator.core;
9 import bindbc.imgui;
10 import core.stdc.stdlib : malloc;
11 import core.stdc.string : memcpy;
12 import std.string;
13 import std.array;
14 
15 private {
16     ImFontAtlas* atlas;
17 
18     version (NoUIScaling) { } else { float uiScale; }
19 
20     FontEntry[] families;
21     void _incInitFontList() {
22         string fontsPath = incGetAppFontsPath();
23         // TODO: load fonts
24     }
25 
26     void _incAddFontData(string name, ref ubyte[] data, float size = 14, const ImWchar* ranges = null, ImVec2 offset = ImVec2(0f, 0f)) {
27         auto cfg = ImFontConfig_ImFontConfig();
28         cfg.FontBuilderFlags = 1 << 9;
29         cfg.FontDataOwnedByAtlas = false;
30         cfg.MergeMode = atlas.Fonts.empty() ? false : true;
31         cfg.GlyphOffset = offset;
32         cfg.OversampleH = 3;
33         cfg.OversampleV = 2;
34 
35         char[40] nameDat;
36         nameDat[0..name.length] = name[0..name.length];
37         cfg.Name = nameDat;
38         ImFontAtlas_AddFontFromMemoryTTF(atlas, cast(void*)data.ptr, cast(int)data.length, size, cfg, ranges);
39     }
40 
41     ubyte[] OPEN_DYSLEXIC = cast(ubyte[])import("OpenDyslexic.otf");
42     ubyte[] NOTO = cast(ubyte[])import("NotoSans-Regular.ttf");
43     ubyte[] NOTO_CJK = cast(ubyte[])import("NotoSansCJK-Regular.ttc");
44     ubyte[] ICONS = cast(ubyte[])import("MaterialIcons.ttf");
45 }
46 
47 /**
48     A font entry in the fonts list
49 */
50 struct FontEntry {
51     /**
52         Family name of the font
53     */
54     string name;
55     
56     /**
57         Main language of the font
58     */
59     string lang;
60 
61     /**
62         The file of the font
63     */
64     string file;
65 }
66 
67 /**
68     Initializes fonts
69 */
70 void incInitFonts() {
71     _incInitFontList();
72     atlas = igGetIO().Fonts;
73         if (incSettingsGet!bool("useOpenDyslexic")) {
74 
75             // Use OpenDyslexic for Latin
76             _incAddFontData("APP\0", OPEN_DYSLEXIC, 24, (cast(ImWchar[])[
77                 0x0020, 0x024F, // Basic Latin + Latin Supplement & Extended
78                 0]).ptr,
79                 ImVec2(0, -8)
80             );
81 
82             // Everything else will have to be NOTO
83             _incAddFontData("APP\0", NOTO, 26, (cast(ImWchar[])[
84                 0x0250, 0x036F, // IPA Extensions + Spacings + Diacritical Marks
85                 0x0370, 0x03FF, // Greek and Coptic
86                 0x0400, 0x052F, // Cyrillic + Supplementary
87                 0x2000, 0x206F, // General Punctuation
88                 0xFFFD, 0xFFFD, // Invalid
89                 0]).ptr,
90                 ImVec2(0, -6)
91             );
92         } else {
93             _incAddFontData("APP\0", NOTO, 26, (cast(ImWchar[])[
94                 0x0020, 0x024F, // Basic Latin + Latin Supplement & Extended
95                 0x0250, 0x036F, // IPA Extensions + Spacings + Diacritical Marks
96                 0x0370, 0x03FF, // Greek and Coptic
97                 0x0400, 0x052F, // Cyrillic + Supplementary
98                 0x2000, 0x206F, // General Punctuation
99                 0xFFFD, 0xFFFD, // Invalid
100                 0]).ptr,
101                 ImVec2(0, -6)
102             );
103         }
104 
105         _incAddFontData("APP\0", NOTO_CJK, 26, (cast(ImWchar[])[
106             0x3000, 0x30FF, // CJK Symbols and Punctuations, Hiragana, Katakana
107             0x31F0, 0x31FF, // Katakana Phonetic Extensions
108             0xFF00, 0xFFEF, // Half-width characters
109             0x4E00, 0x9FAF, // CJK Ideograms
110             0]).ptr,
111             ImVec2(0, -6)
112         );
113 
114         _incAddFontData(
115             "Icons", 
116             ICONS, 
117             32, 
118             [
119                 cast(ImWchar)0xE000, 
120                 cast(ImWchar)0xF23B
121             ].ptr, 
122             ImVec2(0, 2)
123         );
124     ImFontAtlas_Build(atlas);
125 
126     // Half size because the extra size is for scaling
127     igGetIO().FontGlobalScale = 0.5;
128 }
129 
130 /**
131     Returns a list of fonts
132 */
133 FontEntry[] incFontsGet() {
134     return families;
135 }