annotate dynamin/painting/windows_text_layout.d @ 96:301e077da540

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