yay! new layouter *almost* working
[xreader.git] / xreaderfmt.d
blob399bcaa07c1dac5a3ec8dc3173eb5ad20f08faea
1 /* Written by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
2 * Understanding is not required. Only obedience.
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 module xreaderfmt;
19 import core.atomic;
20 import core.time;
22 import std.concurrency;
23 import std.stdio;
25 import iv.strex;
27 import arsd.simpledisplay;
28 import arsd.color;
29 import arsd.png;
30 import arsd.jpeg;
32 import iv.nanovg;
33 import iv.nanovg.oui.blendish;
35 import iv.vfs;
37 import xmodel;
38 import xiniz;
40 import booktext;
42 import xreadercfg;
43 import xlayouter;
46 // ////////////////////////////////////////////////////////////////////////// //
47 __gshared LayoutFonts laf; // layouter font stash
50 // ////////////////////////////////////////////////////////////////////////// //
51 void loadFmtFonts () {
52 laf = new LayoutFonts();
54 void loadFont (string name, string path) {
55 int fid = laf.fs.fonsAddFont(name, path);
56 if (fid < 0) throw new Exception("can't load font '"~name~"' from '"~path~"'");
59 loadFont("text", textFontName);
60 loadFont("texti", textiFontName);
61 loadFont("textb", textbFontName);
62 loadFont("textz", textzFontName);
64 loadFont("mono", monoFontName);
65 loadFont("monoi", monoiFontName);
66 loadFont("monob", monobFontName);
67 loadFont("monoz", monozFontName);
71 // ////////////////////////////////////////////////////////////////////////// //
72 // messages
73 struct ReformatWork {
74 shared BookText booktext;
75 int w, h;
78 struct ReformatWorkDone {
79 int w, h;
80 shared(LayText) laytext;
83 struct QuitWork {
87 // ////////////////////////////////////////////////////////////////////////// //
88 void reformatThreadFn (Tid ownerTid) {
89 bool doQuit = false;
90 ReformatWork cw;
91 loadFmtFonts();
92 while (!doQuit) {
93 cw = cw.init;
94 receive(
95 (ReformatWork w) {
96 cw = w;
98 (QuitWork w) {
99 doQuit = true;
102 if (!doQuit && cw.w > 0 && cw.h > 0 && cw.booktext !is null) {
103 try {
104 auto book = cast(BookText)cw.booktext;
105 int maxWidth = cw.w-4-2-BND_SCROLLBAR_WIDTH-2;
106 if (maxWidth < 64) maxWidth = 64;
107 // layout text
108 writeln("layouting...");
109 auto stt = MonoTime.currTime;
110 auto lay = new LayText(laf, maxWidth);
111 lay.size = fsizeText;
112 lay.normJustify = optJustify;
114 void putItaBold (uint flags) {
115 if (flags&0x01) lay.put(LayText.ItalicOnCh);
116 if (flags&0x02) lay.put(LayText.BoldOnCh);
119 void unputItaBold (uint flags) {
120 if (flags&0x01) lay.put(LayText.ItalicOffCh);
121 if (flags&0x02) lay.put(LayText.BoldOffCh);
125 foreach (immutable sidx, BookText.Section sc; book.secs) {
126 // save section starting word
127 lay.put(lay.NormalTextCh);
128 lay.sections ~= lay.curWordIndex;
129 foreach (BookText.Line tp; sc.title) {
130 lay.put(lay.TitleCh);
131 foreach (immutable widx, dstring w; tp.words) {
132 putItaBold(tp.itabold[widx]);
133 lay.put(w);
134 if (tp.needspace[widx]) lay.put(' ');
135 unputItaBold(tp.itabold[widx]);
138 foreach (BookText.Line ep; sc.epi) {
139 lay.put(lay.EpigraphCh);
140 foreach (immutable widx, dstring w; ep.words) {
141 putItaBold(ep.itabold[widx]);
142 lay.put(w);
143 if (ep.needspace[widx]) lay.put(' ');
144 unputItaBold(ep.itabold[widx]);
147 foreach (immutable pidx, BookText.Line ps; sc.pars) {
148 lay.put(lay.NormalTextCh);
149 foreach (immutable widx, dstring w; ps.words) {
150 putItaBold(ps.itabold[widx]);
151 lay.put(w);
152 if (ps.needspace[widx]) lay.put(' ');
153 unputItaBold(ps.itabold[widx]);
157 lay.finalize();
159 writeln("layouted in ", (MonoTime.currTime-stt).total!"msecs", " milliseconds");
160 auto res = ReformatWorkDone(cw.w, cw.h, cast(shared)lay);
161 send(ownerTid, res);
162 } catch (Throwable e) {
163 // here, we are dead and fucked (the exact order doesn't matter)
164 import core.stdc.stdlib : abort;
165 import core.stdc.stdio : fprintf, stderr;
166 import core.memory : GC;
167 import core.thread : thread_suspendAll;
168 GC.disable(); // yeah
169 thread_suspendAll(); // stop right here, you criminal scum!
170 auto s = e.toString();
171 fprintf(stderr, "\n=== FATAL ===\n%.*s\n", cast(uint)s.length, s.ptr);
172 abort(); // die, you bitch!
176 send(ownerTid, QuitWork());