annotate dynamin/painting/windows_text_layout.d @ 103:73060bc3f004

Change license to Boost 1.0 and MPL 2.0.
author Jordan Miner <jminer7@gmail.com>
date Tue, 15 May 2012 22:06:02 -0500
parents 604d20cac836
children acdbb30fee7e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
2 /*
103
73060bc3f004 Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents: 102
diff changeset
3 * Copyright Jordan Miner
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
4 *
103
73060bc3f004 Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents: 102
diff changeset
5 * This Source Code Form is subject to the terms of the Mozilla Public
73060bc3f004 Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents: 102
diff changeset
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
73060bc3f004 Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents: 102
diff changeset
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
8 *
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
9 */
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
10
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
11 module dynamin.painting.windows_text_layout;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
12
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
13 public import dynamin.c.cairo;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
14 public import dynamin.c.cairo_win32;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
15 public import dynamin.c.windows;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
16 public import dynamin.c.uniscribe;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
17 public import dynamin.painting.graphics;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
18 public import tango.io.Stdout;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
19 public import tango.text.convert.Utf;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
20 public import tango.math.Math;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
21
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
22 //version = TextLayoutDebug;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
23
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
24 template TextLayoutBackend() {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
25 uint charToWcharIndex(uint index) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
26 uint wcharIndex = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
27 foreach(wchar c; text[0..index])
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
28 wcharIndex++;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
29 return wcharIndex;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
30 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
31 uint wcharToCharIndex(uint wcharIndex) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
32 uint decoded = 0, ate = 0, index = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
33 while(decoded < wcharIndex) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
34 decoded += (decode(text[index..$], ate) <= 0xFFFF ? 1 : 2);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
35 index += ate;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
36 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
37 return index;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
38 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
39
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
40 uint nextRight(uint index) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
41 uint wIndex = charToWcharIndex(index);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
42 // this requires using the output from ScriptLayout to move in visual order
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
43 return 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
44 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
45
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
46 //{{{ font fallback
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
47 static {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
48 int Latin;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
49 int Greek;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
50 int Cyrillic;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
51 int Armenian;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
52 int Georgian;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
53 int Hebrew;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
54 int Arabic;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
55 int Syriac;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
56 int Thaana;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
57 int Thai;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
58 int Devanagari;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
59 int Tamil;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
60 int Bengali;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
61 int Gurmukhi;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
62 int Gujarati;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
63 int Oriya;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
64 int Telugu;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
65 int Kannada;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
66 int Malayalam;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
67 int Lao;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
68 int Tibetan;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
69 //int Japanese;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
70 int Bopomofo;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
71 int CjkIdeographs;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
72 int CjkSymbols;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
73 int KoreanHangul;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
74 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
75 static this() {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
76 Latin = getUniscribeScript("JKL");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
77 Greek = getUniscribeScript("ΠΡΣ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
78 Cyrillic = getUniscribeScript("КЛМ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
79 Armenian = getUniscribeScript("ԺԻԼ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
80 Georgian = getUniscribeScript("ႩႪႫ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
81 Hebrew = getUniscribeScript("הוז");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
82 Arabic = getUniscribeScript("ثجح");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
83 Syriac = getUniscribeScript("ܕܗܚ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
84 Thaana = getUniscribeScript("ގޏސ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
85 Thai = getUniscribeScript("ฆงจ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
86 Devanagari = getUniscribeScript("जझञ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
87 Tamil = getUniscribeScript("ஜஞட");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
88 Bengali = getUniscribeScript("জঝঞ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
89 Gurmukhi = getUniscribeScript("ਜਝਞ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
90 Gujarati = getUniscribeScript("જઝઞ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
91 Oriya = getUniscribeScript("ଜଝଞ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
92 Telugu = getUniscribeScript("జఝఞ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
93 Kannada = getUniscribeScript("ಜಝಞ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
94 Malayalam = getUniscribeScript("ജഝഞ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
95 Lao = getUniscribeScript("ຄງຈ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
96 Tibetan = getUniscribeScript("ཇཉཊ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
97 //Japanese = getUniscribeScript("せゼカ"); // TODO: on XP, returned more than 1 item
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
98 Bopomofo = getUniscribeScript("ㄐㄓㄗ"); // Chinese
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
99 CjkIdeographs = getUniscribeScript("丛东丝");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
100 CjkSymbols = getUniscribeScript("、〜㈬");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
101 KoreanHangul = getUniscribeScript("갠흯㉡");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
102 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
103 // returns the Uniscribe script number (SCRIPT_ANALYSIS.eScript) from the specified sample text
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
104 static int getUniscribeScript(wchar[] sample) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
105 SCRIPT_ITEM[5] items;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
106 int itemsProcessed;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
107 HRESULT r = ScriptItemize(sample.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
108 sample.length,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
109 items.length-1,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
110 null,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
111 null,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
112 items.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
113 &itemsProcessed);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
114 assert(r == 0);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
115 assert(itemsProcessed == 1);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
116 return items[0].a.eScript.get();
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
117 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
118
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
119 // adds fallback fonts to the specified fallbacks array
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
120 void getFontFallbacks(int script, wchar[][] fallbacks) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
121 int i = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
122 void addFallback(wchar[] str) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
123 fallbacks[i++] = str;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
124 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
125 if(script == Latin || script == Greek || script == Cyrillic)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
126 addFallback("Times New Roman");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
127 else if(script == Hebrew || script == Arabic)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
128 addFallback("Times New Roman");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
129 else if(script == Armenian || script == Georgian)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
130 addFallback("Sylfaen"); // fits in well with English fonts
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
131 else if(script == Bengali)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
132 addFallback("Vrinda");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
133 else if(Devanagari)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
134 addFallback("Mangal");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
135 else if(script == Gujarati)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
136 addFallback("Shruti");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
137 else if(script == Gurmukhi)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
138 addFallback("Raavi");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
139 else if(script == Kannada)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
140 addFallback("Tunga");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
141 else if(script == Malayalam)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
142 addFallback("Kartika");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
143 else if(script == Syriac)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
144 addFallback("Estrangelo Edessa");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
145 else if(script == Tamil)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
146 addFallback("Latha");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
147 else if(script == Telugu)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
148 addFallback("Gautami");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
149 else if(script == Thaana)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
150 addFallback("MV Boli");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
151 else if(script == Thai)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
152 addFallback("Tahoma"); // fits in well with English fonts
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
153 //else if(script == Japanese)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
154 // addFallback("MS Mincho"); // Meiryo doesn't fit in with SimSun...
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
155 else if(script == Bopomofo || script == CjkIdeographs || script == CjkSymbols)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
156 addFallback("SimSun");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
157 else if(script == KoreanHangul)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
158 addFallback("Batang");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
159 else if(script == Oriya)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
160 addFallback("Kalinga"); // new with Vista
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
161 else if(script == Lao)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
162 addFallback("DokChampa"); // new with Vista
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
163 else if(script == Tibetan)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
164 addFallback("Microsoft Himalaya"); // new with Vista
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
165
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
166 // Arial Unicode MS is not shipped with Windows, but is with Office
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
167 addFallback("Arial Unicode MS");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
168 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
169 //}}}
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
170
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
171 /*bool isRightAligned() {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
172 return alignment == TextAlignment.Right ||
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
173 ((alignment == TextAlignment.Justify || alignment == TextAlignment.Natural) &&
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
174 items[0].a.fRTL);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
175 }*/
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
176 /*struct Run {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
177 double height;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
178 int wtextIndex;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
179 int itemIndex;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
180 WORD[] logClusters; // length == length of text as UTF-16
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
181 WORD[] glyphs;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
182 SCRIPT_VISATTR[] visAttrs; // length == glyphs.length
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
183 int[] advanceWidths; // length == glyphs.length
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
184 GOFFSET[] offsets; // length == glyphs.length
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
185 }*/
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
186 // TODO: should save memory if logClusters, glyphs, visAttrs, advanceWidths, & offsets
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
187 // were made as one big array and these were just slices of them
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
188 // Then reuse the big array every time in layout()
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
189
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
190 void backend_splitRun(uint runIndex, uint splitIndex) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
191 visAttrs.insert(visAttrs[runIndex], runIndex);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
192 visAttrs[runIndex] = visAttrs[runIndex][0..runs[runIndex].glyphs.length];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
193 visAttrs[runIndex+1] = visAttrs[runIndex+1][runs[runIndex].glyphs.length..$];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
194
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
195 offsets.insert(offsets[runIndex], runIndex);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
196 offsets[runIndex] = offsets[runIndex][0..runs[runIndex].glyphs.length];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
197 offsets[runIndex+1] = offsets[runIndex+1][runs[runIndex].glyphs.length..$];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
198 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
199 // returns the number of UTF-8 code units (bytes) it takes to encode the
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
200 // specified UTF-16 code unit; returns 4 for a high surrogate and 0 for a low surrogate
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
201 int getUtf8Width(wchar c) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
202 if(c >= 0x00 && c <= 0x7F) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
203 return 1;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
204 } else if(c >= 0x0080 && c <= 0x07FF) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
205 return 2;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
206 } else if(isHighSurrogate(c)) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
207 return 4;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
208 } else if(isLowSurrogate(c)) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
209 return 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
210 } else {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
211 return 3;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
212 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
213 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
214
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
215 SCRIPT_ITEM[] items;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
216 List!(SCRIPT_VISATTR[]) visAttrs; // one for each Run, same length as Run.glyphs
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
217 List!(GOFFSET[]) offsets; // one for each Run, same length as Run.glyphs
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
218 void backend_preprocess(Graphics g) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
219 wchar[] wtext = toString16(text);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
220
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
221 //{{{ call ScriptItemize() and ScriptBreak()
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
222 SCRIPT_CONTROL scriptControl;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
223 SCRIPT_STATE scriptState;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
224 // TODO: digit substitution?
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
225
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
226 if(items.length < 50)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
227 items.length = 50;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
228 int itemsProcessed;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
229 // On 7, ScriptItemize returns E_OUTOFMEMORY outright if the 3rd param isn't at least 12.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
230 // Every period, question mark, quotation mark, start of number, etc. starts a new item.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
231 // A short English sentence can easily have 10 items.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
232 while(ScriptItemize(wtext.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
233 wtext.length,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
234 items.length-1,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
235 &scriptControl,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
236 &scriptState,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
237 items.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
238 &itemsProcessed) == E_OUTOFMEMORY) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
239 items.length = items.length * 2;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
240 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
241 items = items[0..itemsProcessed+1]; // last item is the end of string
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
242
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
243 for(int i = 0; i < logAttrs.length; ++i) // clear array from previous use
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
244 logAttrs[i] = LogAttr.init;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
245 logAttrs.length = text.length;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
246 int laIndex = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
247
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
248 SCRIPT_LOGATTR[] tmpAttrs;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
249 bool lastWhitespace = false;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
250 for(int i = 0; i < items.length-1; ++i) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
251 wchar[] itemText = wtext[items[i].iCharPos..items[i+1].iCharPos];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
252 tmpAttrs.length = itemText.length;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
253 HRESULT result = ScriptBreak(itemText.ptr, itemText.length, &items[i].a, tmpAttrs.ptr);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
254 if(FAILED(result))
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
255 throw new Exception("ScriptBreak() failed");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
256
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
257 // ScriptBreak() does not set fSoftBreak for the first character of items, even
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
258 // when it needs to be (it doesn't know what comes before them...). This loop sets
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
259 // it for characters after a breakable whitespace.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
260 for(int j = 0; j < tmpAttrs.length; ++j) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
261 if(tmpAttrs[j].fWhiteSpace.get()) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
262 lastWhitespace = true;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
263 } else {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
264 if(lastWhitespace) // not whitespace, but last char was
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
265 tmpAttrs[j].fSoftBreak.set(true);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
266 lastWhitespace = false;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
267 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
268
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
269 // have to convert the SCRIPT_LOGATTR array, which corresponds with the UTF-16
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
270 // encoding, to the LogAttr array, which corresponds with the UTF-8 encoding
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
271 if(tmpAttrs[j].fSoftBreak.get())
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
272 logAttrs[laIndex].softBreak = true;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
273 if(tmpAttrs[j].fCharStop.get())
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
274 logAttrs[laIndex].clusterStart = true;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
275 if(tmpAttrs[j].fWordStop.get())
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
276 logAttrs[laIndex].wordStart = true;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
277
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
278 laIndex += getUtf8Width(itemText[j]);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
279 if(isHighSurrogate(itemText[j]))
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
280 j++; // skip the low surrogate
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
281 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
282 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
283 assert(laIndex == logAttrs.length);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
284 //}}}
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
285
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
286 // ScriptShape and some other functions need an HDC. If the target surface is win32,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
287 // just use its DC. Otherwise, create a 1x1 DIB and use its DC.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
288 cairo_surface_t* targetSurface = cairo_get_target(g.handle);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
289 cairo_surface_flush(targetSurface);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
290 cairo_t* cr = g.handle;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
291 HDC hdc = cairo_win32_surface_get_dc(targetSurface);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
292 cairo_surface_t* tmpSurface;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
293 if(!hdc) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
294 cairo_format_t format = CAIRO_FORMAT_ARGB32;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
295 if(cairo_surface_get_type(targetSurface) == CAIRO_SURFACE_TYPE_IMAGE)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
296 format = cairo_image_surface_get_format(targetSurface);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
297 tmpSurface = cairo_win32_surface_create_with_dib(format, 1, 1);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
298 cr = cairo_create(tmpSurface);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
299 hdc = cairo_win32_surface_get_dc(tmpSurface);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
300 assert(hdc != null);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
301 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
302 scope(exit) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
303 if(tmpSurface) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
304 cairo_destroy(cr);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
305 cairo_surface_destroy(tmpSurface);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
306 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
307 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
308
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
309 clearRuns(); // releaseScaledFont() must be called when a run is removed
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
310
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
311 if(!visAttrs)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
312 visAttrs = new List!(SCRIPT_VISATTR[]);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
313 visAttrs.clear();
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
314 if(!offsets)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
315 offsets = new List!(GOFFSET[]);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
316 offsets.clear();
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
317 List!(BYTE) levels = new List!(BYTE)(items.length+4); // 4 gives padding for 2 formattings
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
318
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
319 SaveDC(hdc);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
320 int splitter(uint i) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
321 return i < items.length ? wcharToCharIndex(items[i].iCharPos) : -1;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
322 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
323 int itemIndex = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
324 // Merge the SCRIPT_ITEMs with runs that have the same format
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
325 // The only formats that matter here are the ones that affect the size or
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
326 // shape of characters, so use &fontFormatRuns
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
327 foreach(start, length, format; fontFormatRuns(&splitter)) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
328 uint wstart = charToWcharIndex(start);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
329 uint wend = charToWcharIndex(start+length);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
330 if(items[itemIndex+1].iCharPos == wstart)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
331 itemIndex++;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
332
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
333 levels.add(items[itemIndex].a.s.uBidiLevel.get());
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
334
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
335 cairo_matrix_t ctm;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
336 cairo_get_matrix(cr, &ctm);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
337 cairo_scaled_font_t* font = getScaledFont(format.fontFamily,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
338 format.fontSize,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
339 format.bold,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
340 format.italic,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
341 ctm);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
342 cairo_win32_scaled_font_select_font(font, hdc);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
343 // Cairo sets up the HDC to be scaled 32 times larger than stuff will be drawn.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
344 // get_metrics_factor returns the factor necessary to convert to font space units.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
345 // Font space units need multiplied by the font size to get device units
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
346 // multipling by to_dev converts from logical units to device units
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
347 double to_dev = cairo_win32_scaled_font_get_metrics_factor(font) * format.fontSize;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
348
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
349 SCRIPT_CACHE cache = null;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
350 scope(exit) ScriptFreeCache(&cache);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
351
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
352 wchar[] range = wtext[wstart..wend];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
353
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
354 WORD[] outGlyphs = new WORD[range.length * 3 / 2 + 16];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
355 WORD[] logClust = new WORD[range.length];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
356 SCRIPT_VISATTR[] sva = new SCRIPT_VISATTR[outGlyphs.length];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
357 int glyphsReturned;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
358 do {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
359 HRESULT result = ScriptShape(hdc,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
360 &cache,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
361 range.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
362 range.length,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
363 outGlyphs.length,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
364 &items[itemIndex].a,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
365 outGlyphs.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
366 logClust.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
367 sva.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
368 &glyphsReturned);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
369 if(result == E_OUTOFMEMORY) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
370 outGlyphs.length = outGlyphs.length * 3 / 2;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
371 sva.length = outGlyphs.length;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
372 continue;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
373 } else if(result == USP_E_SCRIPT_NOT_IN_FONT) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
374 // TODO: font fallback
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
375 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
376 /*SCRIPT_FONTPROPERTIES fontProps;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
377 ScriptGetFontProperties(hdc, &cache, &fontProps);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
378 Stdout("*****Blank: ")(fontProps.wgBlank).newline;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
379 Stdout(fontProps.wgDefault).newline;*/
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
380 } while(false);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
381 outGlyphs = outGlyphs[0..glyphsReturned];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
382 sva = sva[0..glyphsReturned];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
383 visAttrs.add(sva);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
384
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
385 int[] advance = new int[outGlyphs.length];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
386 GOFFSET[] goffset = new GOFFSET[outGlyphs.length];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
387 // the docs mistakenly say the GOFFSET array is optional,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
388 // but it is actually the ABC structure
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
389 if(FAILED(ScriptPlace(hdc,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
390 &cache,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
391 outGlyphs.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
392 outGlyphs.length,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
393 sva.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
394 &items[itemIndex].a,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
395 advance.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
396 goffset.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
397 null)))
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
398 throw new Exception("ScriptPlace failed");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
399 for(int i = 0; i < goffset.length; ++i) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
400 goffset[i].du = cast(LONG)(goffset[i].du * to_dev);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
401 goffset[i].dv = cast(LONG)(goffset[i].dv * to_dev);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
402 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
403 offsets.add(goffset);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
404 // TODO: handle errors well
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
405 // TODO: kerning here
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
406
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
407 Run run;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
408 run.font = font;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
409 cairo_font_extents_t extents;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
410 cairo_scaled_font_extents(run.font, &extents);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
411 run.height = extents.height;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
412
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
413 run.start = start;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
414 run.length = length;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
415 run.rightToLeft = items[itemIndex].a.fRTL.get() ? true : false;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
416
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
417 run.clusterMap = new uint[run.length];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
418 int clusterIndex = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
419 for(int i = 0; i < logClust.length; ++i) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
420 int width = getUtf8Width(range[i]);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
421 if(isHighSurrogate(range[i]))
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
422 i++; // skip the low surrogate
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
423 for(; width > 0; --width) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
424 run.clusterMap[clusterIndex] = logClust[i];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
425 clusterIndex++;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
426 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
427 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
428 assert(clusterIndex == run.length);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
429
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
430 run.glyphs = new uint[outGlyphs.length];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
431 for(int i = 0; i < outGlyphs.length; ++i)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
432 run.glyphs[i] = outGlyphs[i];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
433
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
434 run.advanceWidths = new float[advance.length];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
435 for(int i = 0; i < advance.length; ++i)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
436 run.advanceWidths[i] = advance[i] * to_dev;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
437
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
438 runs.add(run);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
439
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
440 cairo_win32_scaled_font_done_font(font);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
441
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
442 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
443 RestoreDC(hdc, -1);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
444 assert(itemIndex == items.length-2); // last item is end of string
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
445
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
446 // fill in visToLogMap
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
447 visToLogMap = new uint[runs.count];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
448 if(FAILED( ScriptLayout(levels.count, levels.data.ptr, cast(int*)visToLogMap.ptr, null) ))
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
449 throw new Exception("ScriptLayout() failed");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
450
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
451 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
452
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
453 static cairo_scaled_font_t* backend_createScaledFont(string family,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
454 double size,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
455 bool bold,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
456 bool italic,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
457 cairo_matrix_t* ctm) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
458 LOGFONT lf;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
459 lf.lfHeight = -cast(int)size; // is this ignored by cairo? uses font_matrix instead?
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
460 lf.lfWeight = bold ? 700 : 400;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
461 lf.lfItalic = italic;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
462 lf.lfCharSet = 1; // DEFAULT_CHARSET
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
463 auto tmp = toString16(family);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
464 lf.lfFaceName[0..tmp.length] = tmp;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
465 lf.lfFaceName[tmp.length] = '\0';
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
466
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
467 auto face = cairo_win32_font_face_create_for_logfontw(&lf);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
468 scope(exit) cairo_font_face_destroy(face);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
469
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
470 cairo_matrix_t font_matrix;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
471 cairo_matrix_init_scale(&font_matrix, size, size);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
472 return cairo_scaled_font_create(face, &font_matrix, ctm, cairo_font_options_create());
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
473 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
474 }