annotate dynamin/painting/windows_text_layout.d @ 102:604d20cac836

Add dynamin.core.array and put contains() there.
author Jordan Miner <jminer7@gmail.com>
date Tue, 15 May 2012 21:14:48 -0500
parents 301e077da540
children 73060bc3f004
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 // Written in the D programming language
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
2 // www.digitalmars.com/d/
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
3
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
4 /*
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
5 * The contents of this file are subject to the Mozilla Public License Version
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
6 * 1.1 (the "License"); you may not use this file except in compliance with
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
7 * the License. You may obtain a copy of the License at
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
8 * http://www.mozilla.org/MPL/
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 * Software distributed under the License is distributed on an "AS IS" basis,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
12 * for the specific language governing rights and limitations under the
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
13 * License.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
14 *
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
15 * The Original Code is the Dynamin library.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
16 *
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
17 * The Initial Developer of the Original Code is Jordan Miner.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
18 * Portions created by the Initial Developer are Copyright (C) 2007-2012
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
19 * the Initial Developer. All Rights Reserved.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
20 *
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
21 * Contributor(s):
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
22 * Jordan Miner <jminer7@gmail.com>
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 */
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
25
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
26 module dynamin.painting.windows_text_layout;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
27
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
28 public import dynamin.c.cairo;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
29 public import dynamin.c.cairo_win32;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
30 public import dynamin.c.windows;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
31 public import dynamin.c.uniscribe;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
32 public import dynamin.painting.graphics;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
33 public import tango.io.Stdout;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
34 public import tango.text.convert.Utf;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
35 public import tango.math.Math;
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 //version = TextLayoutDebug;
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 template TextLayoutBackend() {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
40 uint charToWcharIndex(uint index) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
41 uint wcharIndex = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
42 foreach(wchar c; text[0..index])
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
43 wcharIndex++;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
44 return wcharIndex;
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 uint wcharToCharIndex(uint wcharIndex) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
47 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
48 while(decoded < wcharIndex) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
49 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
50 index += ate;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
51 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
52 return index;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
53 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
54
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
55 uint nextRight(uint index) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
56 uint wIndex = charToWcharIndex(index);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
57 // 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
58 return 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
59 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
60
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
61 //{{{ font fallback
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
62 static {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
63 int Latin;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
64 int Greek;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
65 int Cyrillic;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
66 int Armenian;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
67 int Georgian;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
68 int Hebrew;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
69 int Arabic;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
70 int Syriac;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
71 int Thaana;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
72 int Thai;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
73 int Devanagari;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
74 int Tamil;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
75 int Bengali;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
76 int Gurmukhi;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
77 int Gujarati;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
78 int Oriya;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
79 int Telugu;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
80 int Kannada;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
81 int Malayalam;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
82 int Lao;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
83 int Tibetan;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
84 //int Japanese;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
85 int Bopomofo;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
86 int CjkIdeographs;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
87 int CjkSymbols;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
88 int KoreanHangul;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
89 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
90 static this() {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
91 Latin = getUniscribeScript("JKL");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
92 Greek = getUniscribeScript("ΠΡΣ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
93 Cyrillic = getUniscribeScript("КЛМ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
94 Armenian = getUniscribeScript("ԺԻԼ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
95 Georgian = getUniscribeScript("ႩႪႫ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
96 Hebrew = getUniscribeScript("הוז");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
97 Arabic = getUniscribeScript("ثجح");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
98 Syriac = getUniscribeScript("ܕܗܚ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
99 Thaana = getUniscribeScript("ގޏސ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
100 Thai = getUniscribeScript("ฆงจ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
101 Devanagari = getUniscribeScript("जझञ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
102 Tamil = getUniscribeScript("ஜஞட");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
103 Bengali = getUniscribeScript("জঝঞ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
104 Gurmukhi = getUniscribeScript("ਜਝਞ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
105 Gujarati = getUniscribeScript("જઝઞ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
106 Oriya = getUniscribeScript("ଜଝଞ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
107 Telugu = getUniscribeScript("జఝఞ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
108 Kannada = getUniscribeScript("ಜಝಞ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
109 Malayalam = getUniscribeScript("ജഝഞ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
110 Lao = getUniscribeScript("ຄງຈ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
111 Tibetan = getUniscribeScript("ཇཉཊ");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
112 //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
113 Bopomofo = getUniscribeScript("ㄐㄓㄗ"); // Chinese
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
114 CjkIdeographs = getUniscribeScript("丛东丝");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
115 CjkSymbols = getUniscribeScript("、〜㈬");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
116 KoreanHangul = getUniscribeScript("갠흯㉡");
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 // 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
119 static int getUniscribeScript(wchar[] sample) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
120 SCRIPT_ITEM[5] items;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
121 int itemsProcessed;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
122 HRESULT r = ScriptItemize(sample.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
123 sample.length,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
124 items.length-1,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
125 null,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
126 null,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
127 items.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
128 &itemsProcessed);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
129 assert(r == 0);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
130 assert(itemsProcessed == 1);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
131 return items[0].a.eScript.get();
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
132 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
133
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
134 // 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
135 void getFontFallbacks(int script, wchar[][] fallbacks) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
136 int i = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
137 void addFallback(wchar[] str) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
138 fallbacks[i++] = str;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
139 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
140 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
141 addFallback("Times New Roman");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
142 else if(script == Hebrew || script == Arabic)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
143 addFallback("Times New Roman");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
144 else if(script == Armenian || script == Georgian)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
145 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
146 else if(script == Bengali)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
147 addFallback("Vrinda");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
148 else if(Devanagari)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
149 addFallback("Mangal");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
150 else if(script == Gujarati)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
151 addFallback("Shruti");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
152 else if(script == Gurmukhi)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
153 addFallback("Raavi");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
154 else if(script == Kannada)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
155 addFallback("Tunga");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
156 else if(script == Malayalam)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
157 addFallback("Kartika");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
158 else if(script == Syriac)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
159 addFallback("Estrangelo Edessa");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
160 else if(script == Tamil)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
161 addFallback("Latha");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
162 else if(script == Telugu)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
163 addFallback("Gautami");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
164 else if(script == Thaana)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
165 addFallback("MV Boli");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
166 else if(script == Thai)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
167 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
168 //else if(script == Japanese)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
169 // 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
170 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
171 addFallback("SimSun");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
172 else if(script == KoreanHangul)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
173 addFallback("Batang");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
174 else if(script == Oriya)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
175 addFallback("Kalinga"); // new with Vista
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
176 else if(script == Lao)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
177 addFallback("DokChampa"); // new with Vista
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
178 else if(script == Tibetan)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
179 addFallback("Microsoft Himalaya"); // new with Vista
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
180
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
181 // 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
182 addFallback("Arial Unicode MS");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
183 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
184 //}}}
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 /*bool isRightAligned() {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
187 return alignment == TextAlignment.Right ||
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
188 ((alignment == TextAlignment.Justify || alignment == TextAlignment.Natural) &&
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
189 items[0].a.fRTL);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
190 }*/
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
191 /*struct Run {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
192 double height;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
193 int wtextIndex;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
194 int itemIndex;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
195 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
196 WORD[] glyphs;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
197 SCRIPT_VISATTR[] visAttrs; // length == glyphs.length
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
198 int[] advanceWidths; // length == glyphs.length
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
199 GOFFSET[] offsets; // length == glyphs.length
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
200 }*/
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
201 // 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
202 // 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
203 // 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
204
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
205 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
206 visAttrs.insert(visAttrs[runIndex], runIndex);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
207 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
208 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
209
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
210 offsets.insert(offsets[runIndex], runIndex);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
211 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
212 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
213 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
214 // 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
215 // 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
216 int getUtf8Width(wchar c) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
217 if(c >= 0x00 && c <= 0x7F) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
218 return 1;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
219 } else if(c >= 0x0080 && c <= 0x07FF) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
220 return 2;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
221 } else if(isHighSurrogate(c)) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
222 return 4;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
223 } else if(isLowSurrogate(c)) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
224 return 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
225 } else {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
226 return 3;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
227 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
228 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
229
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
230 SCRIPT_ITEM[] items;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
231 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
232 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
233 void backend_preprocess(Graphics g) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
234 wchar[] wtext = toString16(text);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
235
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
236 //{{{ call ScriptItemize() and ScriptBreak()
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
237 SCRIPT_CONTROL scriptControl;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
238 SCRIPT_STATE scriptState;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
239 // TODO: digit substitution?
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 if(items.length < 50)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
242 items.length = 50;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
243 int itemsProcessed;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
244 // 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
245 // 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
246 // 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
247 while(ScriptItemize(wtext.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
248 wtext.length,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
249 items.length-1,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
250 &scriptControl,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
251 &scriptState,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
252 items.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
253 &itemsProcessed) == E_OUTOFMEMORY) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
254 items.length = items.length * 2;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
255 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
256 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
257
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
258 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
259 logAttrs[i] = LogAttr.init;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
260 logAttrs.length = text.length;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
261 int laIndex = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
262
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
263 SCRIPT_LOGATTR[] tmpAttrs;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
264 bool lastWhitespace = false;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
265 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
266 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
267 tmpAttrs.length = itemText.length;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
268 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
269 if(FAILED(result))
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
270 throw new Exception("ScriptBreak() failed");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
271
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
272 // 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
273 // 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
274 // 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
275 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
276 if(tmpAttrs[j].fWhiteSpace.get()) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
277 lastWhitespace = true;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
278 } else {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
279 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
280 tmpAttrs[j].fSoftBreak.set(true);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
281 lastWhitespace = false;
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
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
284 // 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
285 // 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
286 if(tmpAttrs[j].fSoftBreak.get())
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
287 logAttrs[laIndex].softBreak = true;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
288 if(tmpAttrs[j].fCharStop.get())
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
289 logAttrs[laIndex].clusterStart = true;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
290 if(tmpAttrs[j].fWordStop.get())
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
291 logAttrs[laIndex].wordStart = true;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
292
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
293 laIndex += getUtf8Width(itemText[j]);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
294 if(isHighSurrogate(itemText[j]))
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
295 j++; // skip the low surrogate
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
296 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
297 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
298 assert(laIndex == logAttrs.length);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
299 //}}}
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
300
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
301 // 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
302 // 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
303 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
304 cairo_surface_flush(targetSurface);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
305 cairo_t* cr = g.handle;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
306 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
307 cairo_surface_t* tmpSurface;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
308 if(!hdc) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
309 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
310 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
311 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
312 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
313 cr = cairo_create(tmpSurface);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
314 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
315 assert(hdc != null);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
316 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
317 scope(exit) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
318 if(tmpSurface) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
319 cairo_destroy(cr);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
320 cairo_surface_destroy(tmpSurface);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
321 }
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
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
324 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
325
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
326 if(!visAttrs)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
327 visAttrs = new List!(SCRIPT_VISATTR[]);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
328 visAttrs.clear();
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
329 if(!offsets)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
330 offsets = new List!(GOFFSET[]);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
331 offsets.clear();
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
332 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
333
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
334 SaveDC(hdc);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
335 int splitter(uint i) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
336 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
337 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
338 int itemIndex = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
339 // 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
340 // 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
341 // shape of characters, so use &fontFormatRuns
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
342 foreach(start, length, format; fontFormatRuns(&splitter)) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
343 uint wstart = charToWcharIndex(start);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
344 uint wend = charToWcharIndex(start+length);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
345 if(items[itemIndex+1].iCharPos == wstart)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
346 itemIndex++;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
347
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
348 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
349
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
350 cairo_matrix_t ctm;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
351 cairo_get_matrix(cr, &ctm);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
352 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
353 format.fontSize,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
354 format.bold,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
355 format.italic,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
356 ctm);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
357 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
358 // 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
359 // 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
360 // 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
361 // 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
362 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
363
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
364 SCRIPT_CACHE cache = null;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
365 scope(exit) ScriptFreeCache(&cache);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
366
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
367 wchar[] range = wtext[wstart..wend];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
368
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
369 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
370 WORD[] logClust = new WORD[range.length];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
371 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
372 int glyphsReturned;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
373 do {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
374 HRESULT result = ScriptShape(hdc,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
375 &cache,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
376 range.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
377 range.length,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
378 outGlyphs.length,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
379 &items[itemIndex].a,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
380 outGlyphs.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
381 logClust.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
382 sva.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
383 &glyphsReturned);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
384 if(result == E_OUTOFMEMORY) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
385 outGlyphs.length = outGlyphs.length * 3 / 2;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
386 sva.length = outGlyphs.length;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
387 continue;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
388 } 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
389 // TODO: font fallback
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
390 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
391 /*SCRIPT_FONTPROPERTIES fontProps;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
392 ScriptGetFontProperties(hdc, &cache, &fontProps);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
393 Stdout("*****Blank: ")(fontProps.wgBlank).newline;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
394 Stdout(fontProps.wgDefault).newline;*/
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
395 } while(false);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
396 outGlyphs = outGlyphs[0..glyphsReturned];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
397 sva = sva[0..glyphsReturned];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
398 visAttrs.add(sva);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
399
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
400 int[] advance = new int[outGlyphs.length];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
401 GOFFSET[] goffset = new GOFFSET[outGlyphs.length];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
402 // 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
403 // 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
404 if(FAILED(ScriptPlace(hdc,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
405 &cache,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
406 outGlyphs.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
407 outGlyphs.length,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
408 sva.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
409 &items[itemIndex].a,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
410 advance.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
411 goffset.ptr,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
412 null)))
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
413 throw new Exception("ScriptPlace failed");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
414 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
415 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
416 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
417 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
418 offsets.add(goffset);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
419 // TODO: handle errors well
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
420 // TODO: kerning here
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
421
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
422 Run run;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
423 run.font = font;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
424 cairo_font_extents_t extents;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
425 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
426 run.height = extents.height;
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 run.start = start;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
429 run.length = length;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
430 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
431
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
432 run.clusterMap = new uint[run.length];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
433 int clusterIndex = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
434 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
435 int width = getUtf8Width(range[i]);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
436 if(isHighSurrogate(range[i]))
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
437 i++; // skip the low surrogate
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
438 for(; width > 0; --width) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
439 run.clusterMap[clusterIndex] = logClust[i];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
440 clusterIndex++;
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 assert(clusterIndex == run.length);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
444
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
445 run.glyphs = new uint[outGlyphs.length];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
446 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
447 run.glyphs[i] = outGlyphs[i];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
448
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
449 run.advanceWidths = new float[advance.length];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
450 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
451 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
452
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
453 runs.add(run);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
454
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
455 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
456
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
457 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
458 RestoreDC(hdc, -1);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
459 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
460
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
461 // fill in visToLogMap
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
462 visToLogMap = new uint[runs.count];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
463 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
464 throw new Exception("ScriptLayout() failed");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
465
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
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
468 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
469 double size,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
470 bool bold,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
471 bool italic,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
472 cairo_matrix_t* ctm) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
473 LOGFONT lf;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
474 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
475 lf.lfWeight = bold ? 700 : 400;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
476 lf.lfItalic = italic;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
477 lf.lfCharSet = 1; // DEFAULT_CHARSET
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
478 auto tmp = toString16(family);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
479 lf.lfFaceName[0..tmp.length] = tmp;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
480 lf.lfFaceName[tmp.length] = '\0';
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
481
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
482 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
483 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
484
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
485 cairo_matrix_t font_matrix;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
486 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
487 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
488 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
489 }