annotate dynamin/painting/text_layout.d @ 106:acdbb30fee7e

Port to D2. Most of the effort was dealing with immutable and const.
author Jordan Miner <jminer7@gmail.com>
date Mon, 17 Dec 2012 23:41:50 -0600
parents 97997a544ac0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
90
41b430aa319f Add license boilerplate to top of text_layout.d
Jordan Miner <jminer7@gmail.com>
parents: 85
diff changeset
1
41b430aa319f Add license boilerplate to top of text_layout.d
Jordan Miner <jminer7@gmail.com>
parents: 85
diff changeset
2 /*
103
73060bc3f004 Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents: 102
diff changeset
3 * Copyright Jordan Miner
90
41b430aa319f Add license boilerplate to top of text_layout.d
Jordan Miner <jminer7@gmail.com>
parents: 85
diff changeset
4 *
103
73060bc3f004 Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents: 102
diff changeset
5 * This Source Code Form is subject to the terms of the Mozilla Public
73060bc3f004 Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents: 102
diff changeset
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
73060bc3f004 Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents: 102
diff changeset
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
90
41b430aa319f Add license boilerplate to top of text_layout.d
Jordan Miner <jminer7@gmail.com>
parents: 85
diff changeset
8 *
41b430aa319f Add license boilerplate to top of text_layout.d
Jordan Miner <jminer7@gmail.com>
parents: 85
diff changeset
9 */
41b430aa319f Add license boilerplate to top of text_layout.d
Jordan Miner <jminer7@gmail.com>
parents: 85
diff changeset
10
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
11 module dynamin.painting.text_layout;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
12
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
13 import dynamin.painting_backend;
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
14 import dynamin.core.list;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
15 import dynamin.core.string;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
16 import dynamin.painting.color;
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
17 import dynamin.painting.coordinates;
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
18 import tango.text.convert.Utf;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
19 import tango.io.Stdout;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
20
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
21 //version = TextLayoutDebug;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
22
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
23 //{{{ character formatting types
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
24 /// The line style of an underline, strikethrough, or overline.
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
25 // TODO: add images of what these line styles look like
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
26 enum LineStyle {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
27 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
28 None,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
29 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
30 Single,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
31 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
32 Double,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
33 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
34 Dotted,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
35 ///
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
36 //Dashed,
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
37 ///
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
38 //Wavy
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
39 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
40
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
41 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
42 enum SmallType {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
43 // Specifies normal text.
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
44 Normal,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
45 // Specifies text smaller than normal and raised above the normal baseline.
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
46 Superscript,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
47 // Specifies text smaller than normal and lowered below the normal baseline.
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
48 Subscript
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
49 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
50
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
51 /// A change in character formatting.
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
52 struct FormatChange {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
53 uint index;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
54 FormatType type;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
55 FormatData data;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
56
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
57 static FormatChange opCall(uint i, FormatType t, FormatData d) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
58 FormatChange c;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
59 c.index = i;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
60 c.type = t;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
61 c.data = d;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
62 return c;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
63 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
64 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
65 /**
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
66 * Returns true if data1 is equal to data2.
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
67 */
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
68 bool formatDataEqual(FormatType type, FormatData data1, FormatData data2) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
69 if(type == FormatType.FontFamily)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
70 return data1.family == data2.family;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
71 else if(type == FormatType.FontSize)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
72 return data1.size == data2.size;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
73 else if(type == FormatType.Bold || type == FormatType.Italic)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
74 return data1.on == data2.on;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
75 else if(type == FormatType.Underline || type == FormatType.Strikethrough ||
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
76 type == FormatType.Overline)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
77 return data1.style == data2.style;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
78 else if(type == FormatType.Small)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
79 return data1.type == data2.type;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
80 else if(type == FormatType.ForeColor || type == FormatType.BackColor)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
81 return data1.color == data2.color;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
82 else if(type == FormatType.Spacing)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
83 return data1.multiple == data2.multiple;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
84 else
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
85 throw new Exception("unknown type");
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
86 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
87
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
88 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
89 enum FormatType : ubyte {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
90 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
91 FontFamily = 1,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
92 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
93 FontSize,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
94 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
95 Bold,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
96 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
97 Italic,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
98 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
99 Underline,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
100 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
101 Strikethrough,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
102 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
103 Overline,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
104 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
105 Small,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
106 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
107 ForeColor,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
108 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
109 BackColor,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
110 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
111 Spacing
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
112 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
113
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
114 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
115 union FormatData {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
116 /// Valid for FontFamily
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
117 string family;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
118 /// Valid for FontSize
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
119 double size;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
120 /// Valid for Bold and Italic
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
121 bool on;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
122 /// Valid for Underline, Strikethrough, and Overline
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
123 LineStyle style;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
124 /// Valid for Small
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
125 SmallType type;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
126 /// Valid for ForeColor and BackColor
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
127 Color color;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
128 /// Valid for Spacing
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
129 double multiple;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
130 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
131
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
132 struct Format {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
133 string fontFamily; // no default
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
134 double fontSize; // no default
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
135 bool bold = false;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
136 bool italic = false;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
137 LineStyle underline = LineStyle.None;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
138 LineStyle strikethrough = LineStyle.None;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
139 LineStyle overline = LineStyle.None;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
140 SmallType small = SmallType.Normal;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
141 Color foreColor = Color(255, 0, 0, 0); // black
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
142 Color backColor = Color( 0, 0, 0, 0); // transparent
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
143 double spacing = 1.0;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
144
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
145 FormatData getDataForType(FormatType type) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
146 FormatData data;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
147 if(type == FormatType.FontFamily)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
148 data.family = fontFamily;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
149 else if(type == FormatType.FontSize)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
150 data.size = fontSize;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
151 else if(type == FormatType.Bold)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
152 data.on = bold;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
153 else if(type == FormatType.Italic)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
154 data.on = italic;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
155 else if(type == FormatType.Underline)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
156 data.style = underline;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
157 else if(type == FormatType.Strikethrough)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
158 data.style = strikethrough;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
159 else if(type == FormatType.Overline)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
160 data.style = overline;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
161 else if(type == FormatType.Small)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
162 data.type = small;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
163 else if(type == FormatType.ForeColor)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
164 data.color = foreColor;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
165 else if(type == FormatType.BackColor)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
166 data.color = backColor;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
167 else if(type == FormatType.Spacing)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
168 data.multiple = spacing;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
169 else
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
170 throw new Exception("unknown type");
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
171 return data;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
172 }
91
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
173 void setDataForType(FormatType type, FormatData data) {
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
174 if(type == FormatType.FontFamily)
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
175 fontFamily = data.family;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
176 else if(type == FormatType.FontSize)
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
177 fontSize = data.size;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
178 else if(type == FormatType.Bold)
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
179 bold = data.on;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
180 else if(type == FormatType.Italic)
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
181 italic = data.on;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
182 else if(type == FormatType.Underline)
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
183 underline = data.style;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
184 else if(type == FormatType.Strikethrough)
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
185 strikethrough = data.style;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
186 else if(type == FormatType.Overline)
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
187 overline = data.style;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
188 else if(type == FormatType.Small)
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
189 small = data.type;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
190 else if(type == FormatType.ForeColor)
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
191 foreColor = data.color;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
192 else if(type == FormatType.BackColor)
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
193 backColor = data.color;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
194 else if(type == FormatType.Spacing)
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
195 spacing = data.multiple;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
196 else
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
197 throw new Exception("unknown type");
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
198 }
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
199 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
200 //}}}
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
201
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
202 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
203 enum TextAlignment {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
204 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
205 Left,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
206 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
207 Center,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
208 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
209 Right,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
210 ///
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
211 /// The last line of justified text will be natural aligned.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
212 Justify,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
213 /// Left aligned for left-to-right text and right aligned for right-to-left text.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
214 Natural
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
215 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
216
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
217 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
218 enum TabStopType {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
219 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
220 Left,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
221 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
222 Center,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
223 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
224 Right,
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
225 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
226 Decimal
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
227 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
228
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
229 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
230 struct TabStop {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
231 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
232 uint location;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
233 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
234 TabStopType type = TabStopType.Left;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
235 ///
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
236 char leading = '.';
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
237 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
238
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
239 struct Run {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
240 cairo_scaled_font_t* font;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
241 float baseline; // distance from position.y down to the baseline
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
242 float height;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
243 Point position; // the top-left corner of the run
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
244 uint start; // the first UTF-8 code unit in this run
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
245 uint length; // the number of UTF-8 code units in this run
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
246 bool rightToLeft;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
247 uint[] clusterMap; // map from UTF-8 code units to the beginning of the glyph cluster they're in
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
248 uint[] glyphs; // glyphs are in visual order
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
249 float[] advanceWidths;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
250
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
251 uint end() { return start + length; }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
252 float width() {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
253 float sum = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
254 foreach(w; advanceWidths)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
255 sum += w;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
256 return sum;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
257 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
258 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
259 struct LogAttr {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
260 private ubyte data;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
261 // true if the line can be broken at this index
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
262 bool softBreak() {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
263 return cast(bool)(data & 1);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
264 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
265 void softBreak(bool b) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
266 b ? (data |= 1) : (data &= ~1);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
267 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
268 // true if the caret can be placed at this index
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
269 bool clusterStart() {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
270 return cast(bool)(data & 2);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
271 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
272 void clusterStart(bool b) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
273 b ? (data |= 2) : (data &= ~2);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
274 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
275 // true if the caret can be placed at this index when moving to the beginning of a word
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
276 bool wordStart() {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
277 return cast(bool)(data & 4);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
278 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
279 void wordStart(bool b) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
280 b ? (data |= 4) : (data &= ~4);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
281 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
282 }
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
283 /**
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
284 * Normally, at least for situations when paragraphs need to be formatted differently (e.g. one
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
285 * centered and another justified), a separate TextLayout object is used for each paragraph.
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
286 */
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
287 class TextLayout {
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
288 private:
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
289 mixin TextLayoutBackend;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
290 public:
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
291 string text;
92
27445f24d5fd Add TextLayout.layoutBoxes API, but not implementation
Jordan Miner <jminer7@gmail.com>
parents: 91
diff changeset
292 Rect[] layoutBoxes;
27445f24d5fd Add TextLayout.layoutBoxes API, but not implementation
Jordan Miner <jminer7@gmail.com>
parents: 91
diff changeset
293 ///
27445f24d5fd Add TextLayout.layoutBoxes API, but not implementation
Jordan Miner <jminer7@gmail.com>
parents: 91
diff changeset
294 void delegate(Rect line, List!(Rect) boxes) getLineBoxes;
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
295
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
296 // character formatting
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
297 List!(FormatChange) formatting; // Always sorted by FormatChange.index
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
298 Format initialFormat;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
299
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
300 // paragraph formatting
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
301 double lineSpacing = 1.0;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
302 double defaultTabStopLocations = 0; // 0 means default tabs every (4 * width of character '0')
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
303 TabStop[] tabStops;
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
304 TextAlignment alignment = TextAlignment.Natural;
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
305
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
306 List!(Run) runs; // runs are in logical order
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
307 LogAttr[] logAttrs;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
308 void clearRuns() {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
309 while(runs.count > 0)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
310 releaseScaledFont(runs.pop().font);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
311 }
92
27445f24d5fd Add TextLayout.layoutBoxes API, but not implementation
Jordan Miner <jminer7@gmail.com>
parents: 91
diff changeset
312 void defaultGetLineBoxes(Rect line, List!(Rect) boxes) {
27445f24d5fd Add TextLayout.layoutBoxes API, but not implementation
Jordan Miner <jminer7@gmail.com>
parents: 91
diff changeset
313 boxes.add(line);
27445f24d5fd Add TextLayout.layoutBoxes API, but not implementation
Jordan Miner <jminer7@gmail.com>
parents: 91
diff changeset
314 }
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
315 this(string fontFamily, double fontSize) {
92
27445f24d5fd Add TextLayout.layoutBoxes API, but not implementation
Jordan Miner <jminer7@gmail.com>
parents: 91
diff changeset
316 getLineBoxes = &defaultGetLineBoxes;
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
317 runs = new List!(Run);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
318 if(!runLists)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
319 runLists = new List!(List!(Run));
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
320 runLists.add(runs); // to keep the runs list around until the destructor is called
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
321
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
322 formatting = new List!(FormatChange);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
323 initialFormat.fontFamily = fontFamily;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
324 initialFormat.fontSize = fontSize;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
325 }
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
326 ~this() {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
327 clearRuns(); // have to call releaseScaledFont() so unused ones don't stay in font cache
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
328 runLists.remove(runs);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
329 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
330 /*invariant { // TODO: uncomment this when D no longer calls it right before the destructor
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
331 // ensure that formatting is sorted correctly
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
332 uint index = 0;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
333 foreach(change; formatting) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
334 assert(change.index >= index);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
335 index = change.index;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
336 }
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
337 }*/
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
338 // The first number is the index of the run to put at the left of the first line.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
339 // The second number is the index of the run to put just right of that, and so on.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
340 uint[] visToLogMap; // length == runs.count
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
341 // Narrow down the visual to logical map to just the logical runs between startRun and endRun.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
342 // startRun is inclusive; endRun is exclusive
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
343 // The first number in the return map is index of the run (between startRun and
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
344 // endRun) that goes first visually. The second index goes just to right of it, and so on.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
345 void getVisualToLogicalMap(uint startRun, uint endRun, uint[] map) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
346 assert(map.length == endRun - startRun);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
347 uint mapIndex = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
348 for(int i = 0; i < visToLogMap.length; ++i) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
349 // we are basically removing all numbers from visToLogMap except ones >= start and < end
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
350 if(visToLogMap[i] >= startRun && visToLogMap[i] < endRun) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
351 map[mapIndex] = visToLogMap[i];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
352 mapIndex++;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
353 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
354 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
355 assert(mapIndex == map.length - 1);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
356
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
357 // To use a logical to visual map to implement this function, you'd have to
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
358 // loop through the entire map and find the smallest index. Then put that in the
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
359 // return array. Then loop through and find the second smallest index, and put that in
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
360 // the return array. Repeat until it is filled.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
361 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
362 // Splits this run into two runs. This Run is the second one, and the first run is returned.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
363 void splitRun(uint runIndex, uint splitIndex) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
364 // TODO: need to update visToLogMap
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
365 // TODO: rename position to location?
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
366 version(TextLayoutDebug) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
367 Stdout.format("splitRun(): runIndex: {0}, text: {1}",
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
368 runIndex, text[runs[runIndex].start..runs[runIndex].end]).newline;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
369 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
370 assert(splitIndex != runs[runIndex].start && splitIndex != runs[runIndex].end);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
371 assert(logAttrs[splitIndex].clusterStart);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
372
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
373 runs.insert(runs[runIndex], runIndex);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
374
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
375 Run* run1 = &runs.data[runIndex];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
376 auto glyphIndex = run1.clusterMap[splitIndex - run1.start];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
377 run1.length = splitIndex - run1.start;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
378 run1.glyphs = run1.glyphs[0..glyphIndex];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
379 run1.advanceWidths = run1.advanceWidths[0..glyphIndex];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
380 run1.clusterMap = run1.clusterMap[0..run1.length];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
381 cairo_scaled_font_reference(run1.font);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
382
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
383 Run* run2 = &runs.data[runIndex+1];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
384 run2.length = (run2.start + run2.length) - splitIndex;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
385 run2.start = splitIndex;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
386 run2.glyphs = run2.glyphs[glyphIndex..$];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
387 run2.advanceWidths = run2.advanceWidths[glyphIndex..$];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
388 run2.clusterMap = run2.clusterMap[run1.length..$];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
389 // need to change the cluster map to account for the glyphs removed
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
390 for(int i = 0; i < run2.clusterMap.length; ++i)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
391 run2.clusterMap[i] -= glyphIndex;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
392
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
393 backend_splitRun(runIndex, splitIndex);
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
394 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
395
91
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
396 ///
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
397 struct FormatRunsIter {
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
398 private:
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
399 TextLayout owner;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
400 FormatType[] filter;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
401 int delegate(uint index) splitter;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
402 public:
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
403 ///
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
404 int opApply(int delegate(ref uint start, ref uint length, ref Format format) dg) {
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
405 bool inFilter(FormatType type) {
102
604d20cac836 Add dynamin.core.array and put contains() there.
Jordan Miner <jminer7@gmail.com>
parents: 96
diff changeset
406 return filter.length == 0 || filter.contains(type);
91
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
407 }
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
408 with(owner) {
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
409 int result;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
410 uint fIndex = 0; // index of formatting array
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
411 uint sIndex = 0; // index passed to splitter
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
412 Format format = initialFormat;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
413
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
414 uint start = 0;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
415 uint end;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
416 while(start != text.length) {
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
417 end = text.length;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
418 // stop looping when one is found that is greater than start and in the filter
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
419 while(fIndex < formatting.count && (formatting[fIndex].index <= start ||
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
420 !inFilter(formatting[fIndex].type))) {
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
421 // the only ones that are greater are ones skipped due to filter
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
422 assert(formatting[fIndex].index >= start);
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
423 format.setDataForType(formatting[fIndex].type, formatting[fIndex].data);
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
424 fIndex++;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
425 }
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
426 if(fIndex < formatting.count)
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
427 end = formatting[fIndex].index;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
428
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
429 if(splitter) {
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
430 while(splitter(sIndex) != -1 && splitter(sIndex) <= start)
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
431 sIndex++;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
432 if(splitter(sIndex) != -1 && splitter(sIndex) < end)
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
433 end = splitter(sIndex);
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
434 }
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
435 if(end == start)
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
436 end = text.length;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
437
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
438 uint _start = start;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
439 uint _length = end - start;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
440 result = dg(_start, _length, format);
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
441 if(result)
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
442 break;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
443
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
444 start = end;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
445 }
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
446
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
447 return result;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
448 }
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
449 }
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
450 }
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
451
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
452 /**
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
453 * Returns an iterator struct that can be used with foreach. The struct will iterate over
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
454 * each range of the text that has the same formatting.
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
455 *
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
456 * The difference between formatRuns and fontFormatRuns is that fontFormatRuns ignores
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
457 * all formatting except FontFamily, FontSize, Bold, Italic, and Small, whereas formatRuns
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
458 * does not ignore any formatting.
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
459 *
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
460 * If the optional delegate is specified, it will be called with index = 0, then index = 1,
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
461 * and so on. The delegate should return an index to split the ranges at. When there are no
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
462 * more indexes to split the ranges at, the delegate should return -1. It is a way of
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
463 * giving an array of indexes to split at without allocating an array.
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
464 *
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
465 * Example:
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
466 * -----
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
467 * foreach(start, length, format; textLayout.formatRuns) {
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
468 * // code goes here
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
469 * }
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
470 * -----
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
471 */
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
472 FormatRunsIter formatRuns(int delegate(uint index) splitter = null) {
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
473 FormatRunsIter iter;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
474 iter.owner = this;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
475 iter.splitter = splitter;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
476 return iter;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
477 }
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
478
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
479 /// ditto
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
480 FormatRunsIter fontFormatRuns(int delegate(uint index) splitter = null) {
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
481 FormatRunsIter iter;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
482 iter.owner = this;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
483 iter.filter = [FormatType.FontFamily,
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
484 FormatType.FontSize,
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
485 FormatType.Bold,
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
486 FormatType.Italic,
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
487 FormatType.Small];
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
488 iter.splitter = splitter;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
489 return iter;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
490 }
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
491
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
492 /**
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
493 *
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
494 */
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
495 TextAlignment naturalAlignment() {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
496 return TextAlignment.Left; // TODO:
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
497 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
498 /**
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
499 *
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
500 */
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
501 TextAlignment resolvedAlignment() {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
502 if(alignment == TextAlignment.Left || alignment == TextAlignment.Right)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
503 return alignment;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
504 else
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
505 return naturalAlignment;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
506 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
507
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
508 /*
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
509 Point indexToPoint(uint index) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
510 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
511 uint pointToIndex(Point pt) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
512 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
513 uint nextLeft(uint index) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
514 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
515 uint nextRight(uint index) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
516 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
517 uint nextWordLeft(uint index) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
518 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
519 uint nextWordRight(uint index) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
520 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
521 */
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
522
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
523 //{{{ character formatting
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
524 void setFontFamily(string family, uint start, uint length) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
525 FormatData data;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
526 data.family = family;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
527 setFormat(FormatType.FontFamily, data, start, length);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
528 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
529 void setFontSize(double size, uint start, uint length) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
530 FormatData data;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
531 data.size = size;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
532 setFormat(FormatType.FontSize, data, start, length);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
533 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
534
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
535 void setBold(bool on, uint start, uint length) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
536 FormatData data;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
537 data.on = on;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
538 setFormat(FormatType.Bold, data, start, length);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
539 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
540 void setItalic(bool on, uint start, uint length) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
541 FormatData data;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
542 data.on = on;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
543 setFormat(FormatType.Italic, data, start, length);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
544 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
545 void setUnderline(LineStyle style, uint start, uint length) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
546 FormatData data;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
547 data.style = style;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
548 setFormat(FormatType.Underline, data, start, length);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
549 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
550 void setStrikethrough(LineStyle style, uint start, uint length) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
551 FormatData data;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
552 data.style = style;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
553 setFormat(FormatType.Strikethrough, data, start, length);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
554 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
555 void setOverline(LineStyle style, uint start, uint length) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
556 FormatData data;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
557 data.style = style;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
558 setFormat(FormatType.Overline, data, start, length);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
559 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
560
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
561 /// Sets the text either superscript or subscript.
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
562 void setSmall(SmallType type, uint start, uint length) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
563 FormatData data;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
564 data.type = type;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
565 setFormat(FormatType.Small, data, start, length);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
566 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
567 // see http://en.wikipedia.org/wiki/Subscript_and_superscript#Desktop_publishing for
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
568 // info on positioning superscript and subscript
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
569
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
570 void setForeColor(Color color, uint start, uint length) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
571 FormatData data;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
572 data.color = color;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
573 setFormat(FormatType.ForeColor, data, start, length);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
574 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
575 void setBackColor(Color color, uint start, uint length) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
576 FormatData data;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
577 data.color = color;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
578 setFormat(FormatType.BackColor, data, start, length);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
579 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
580
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
581 /**
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
582 * Sets the spacing between characters, given in multiples of a character's width.
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
583 * For example, a multiple of 2.0 would make drawn text take twice as much space
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
584 * horizontally, due to twice as much space being given to each character.
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
585 */
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
586 void setSpacing(double multiple, uint start, uint length) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
587 FormatData data;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
588 data.multiple = multiple;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
589 setFormat(FormatType.Spacing, data, start, length);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
590 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
591
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
592 void setFormat(FormatType type, FormatData data, uint start, uint length) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
593 uint end = start + length;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
594 checkIndex(start);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
595 checkIndex(end);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
596
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
597 FormatData endData = getFormat(type, end);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
598
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
599 for(int i = formatting.count-1; i >= 0; --i) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
600 if(formatting[i].type == type && formatting[i].index <= end) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
601 if(formatting[i].index >= start)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
602 formatting.removeAt(i);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
603 else
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
604 break;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
605 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
606 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
607
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
608 if(!formatDataEqual(type, getFormat(type, start), data)) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
609 insertFormatChange(FormatChange(start, type, data));
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
610 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
611
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
612 // make sure that the formatting >= end stays the same as it was
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
613 if(!formatDataEqual(type, endData, getFormat(type, end))) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
614 insertFormatChange(FormatChange(end, type, endData));
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
615 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
616 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
617 FormatData getFormat(FormatType type, uint index) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
618 checkIndex(index);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
619 FormatData data = initialFormat.getDataForType(type);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
620 for(int i = 0; i < formatting.count; ++i) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
621 if(formatting[i].index > index)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
622 break;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
623 if(formatting[i].type == type)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
624 data = formatting[i].data;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
625 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
626 return data;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
627 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
628 private void insertFormatChange(FormatChange change) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
629 int i = 0;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
630 while(i < formatting.count && formatting[i].index <= change.index)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
631 ++i;
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
632 formatting.insert(change, i);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
633 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
634 //}}}
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
635
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
636 private void checkIndex(uint index) {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
637 if(index == 0)
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
638 return;
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
639 // NOTE: Do not use cropRight(). It is broken. It will cut off an ending code point even
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
640 // when it is a perfectly valid string. Thankfully, cropLeft() works.
106
acdbb30fee7e Port to D2.
Jordan Miner <jminer7@gmail.com>
parents: 105
diff changeset
641 if(cropLeft!(char)(cast(mstring)text[index..$]).length != text.length-index)
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
642 throw new Exception("index must be at a valid code point, not inside one");
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
643 }
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
644
105
97997a544ac0 Add a couple TODOs and clean up a logging statement.
Jordan Miner <jminer7@gmail.com>
parents: 103
diff changeset
645 // {{{ layout()
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
646 protected void layout(Graphics g) {
105
97997a544ac0 Add a couple TODOs and clean up a logging statement.
Jordan Miner <jminer7@gmail.com>
parents: 103
diff changeset
647 if(layoutBoxes.length == 0)
97997a544ac0 Add a couple TODOs and clean up a logging statement.
Jordan Miner <jminer7@gmail.com>
parents: 103
diff changeset
648 throw new Exception("layoutBoxes must be set");
97997a544ac0 Add a couple TODOs and clean up a logging statement.
Jordan Miner <jminer7@gmail.com>
parents: 103
diff changeset
649 // TODO: need to be able to set just one rect, not an array of layoutBoxes
97997a544ac0 Add a couple TODOs and clean up a logging statement.
Jordan Miner <jminer7@gmail.com>
parents: 103
diff changeset
650
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
651 backend_preprocess(g);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
652
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
653 version(TextLayoutDebug)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
654 Stdout("-----layout start-----").newline;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
655 int lastRunIndex = 0; // used in case of a bug
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
656 LayoutProgress progress;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
657 lineLoop:
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
658 // loop once for each line until done laying out text
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
659 while(progress.runIndex < runs.count) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
660 // Try laying out the line at the height of the first run.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
661 // If a taller run is found, try the line at that height, and so on
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
662 // If no taller run is found, or if laying out the line at the taller height didn't
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
663 // fit more characters on, then we've found the height that works best.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
664 double baseline;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
665 double height = 0; // height of the line
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
666 uint prevLength = 0; // how many chars fit on when the line is that tall
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
667 double heightToTry = runs[progress.runIndex].height;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
668 while(true) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
669 baseline = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
670 double newHeightToTry = heightToTry;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
671 uint length = layoutLine(newHeightToTry, baseline, progress, true);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
672 if(length == 0) { // we ran out of layout boxes--no place to put text
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
673 while(runs.count > progress.runIndex)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
674 runs.removeAt(runs.count-1);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
675 break lineLoop;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
676 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
677 version(TextLayoutDebug)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
678 Stdout.format("^ length: {0}, runIndex: {1}, y: {2}", length, progress.runIndex, progress.y).newline;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
679 if(length > prevLength) { // if more fit on at heightToTry than height
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
680 height = heightToTry;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
681 prevLength = length;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
682 if(newHeightToTry <= heightToTry) // if no need to try again
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
683 break;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
684 heightToTry = newHeightToTry;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
685 } else {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
686 break;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
687 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
688 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
689 // now that we have found the right height and baseline for the line,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
690 // actually do the layout
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
691 layoutLine(height, baseline, progress, false);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
692
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
693 version(TextLayoutDebug) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
694 Stdout.format("^^ rI: {0}, y: {1}", progress.runIndex, progress.y).newline;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
695 if(runIndex == lastRunIndex)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
696 Stdout("assert failed").newline;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
697 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
698 assert(progress.runIndex > lastRunIndex);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
699 // should never happen, but if there is a bug, it is better than an infinite loop
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
700 if(progress.runIndex == lastRunIndex)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
701 break;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
702 lastRunIndex = progress.runIndex;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
703 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
704 // if wrapping around an object, a tab should go on the other side of the object
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
705 }
105
97997a544ac0 Add a couple TODOs and clean up a logging statement.
Jordan Miner <jminer7@gmail.com>
parents: 103
diff changeset
706 // }}}
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
707
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
708 struct LayoutProgress {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
709 int runIndex = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
710 int boxIndex = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
711 double y = 0; // y is relative to the top of the layout box
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
712 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
713
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
714 // {{{ layoutLine()
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
715 // Returns how many chars fit on the line when it is the specified height tall.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
716 // When this method returns, height will have been set to a new height that layoutLine() can
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
717 // be called with.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
718 // runIndex and totalY are only updated if dryRun is false
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
719 // totalY is the total height of text layed out before this
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
720 // note that this includes empty space at the bottom of a layout box where a line couldn't fit
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
721 List!(Rect) lineBoxes; // try to reuse the same memory for each call
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
722 uint layoutLine(ref double height, ref double baseline,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
723 ref LayoutProgress progress, bool dryRun) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
724 // make local copies in case of dryRun
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
725 int boxIndex = progress.boxIndex;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
726 double y = progress.y; // for now, y is relative to the top of the layout box
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
727 // if the line won't fit on, go to the top of the next box
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
728 while(y + height > layoutBoxes[boxIndex].height) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
729 boxIndex++;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
730 if(boxIndex == layoutBoxes.length)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
731 return 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
732 y = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
733 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
734 Rect layoutBox = layoutBoxes[boxIndex];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
735 if(!dryRun) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
736 progress.boxIndex = boxIndex;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
737 progress.y = y + height; // top of line after this one
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
738 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
739 // change y to absolute
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
740 y += layoutBox.y;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
741
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
742 /*
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
743 double top = totalY; // top will be the space from layoutBox.y to the top of the line
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
744 foreach(i, box; layoutBoxes) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
745 layoutBox = box; // use the last box if we never break
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
746 if(top >= box.height) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
747 top -= box.height;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
748 if(i == layoutBoxes.length - 1)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
749 return 0; // if we are out of layout boxes, there is no place to put text
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
750 } else if(top + height > box.height) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
751 // add on empty space at bottom of box
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
752 totalY += dryRun ? 0 : top + height - box.height;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
753 top = 0; // loop to next box, then break
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
754 if(i == layoutBoxes.length - 1)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
755 return 0; // if we are out of layout boxes, there is no place to put text
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
756 } else {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
757 break;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
758 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
759 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
760 totalY += dryRun ? 0 : height;*/
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
761
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
762 if(!lineBoxes)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
763 lineBoxes = new List!(Rect);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
764 lineBoxes.clear();
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
765 getLineBoxes(Rect(layoutBox.x, y, layoutBox.width, height), lineBoxes);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
766
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
767
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
768 version(TextLayoutDebug) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
769 Stdout.format("layoutLine(): height: {0}, runIndex: {1}, dryRun: {2}, runs[rI]: {3}",
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
770 height, runIndex, dryRun,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
771 text[runs[runIndex].start..runs[runIndex].end]).newline;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
772 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
773 int totalWidth = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
774 foreach(box; lineBoxes)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
775 totalWidth += box.width;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
776 wordsLoop:
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
777 for(int words = getMaxWords(progress.runIndex, totalWidth); words >= 1; --words) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
778 // then for right-aligned, start with the last line box and last run, and work left
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
779 // for left-aligned, start with the first line box and first run, and work right
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
780
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
781 // loop over each glyph/char from left to right
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
782 //
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
783 int endRun, runSplit;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
784 getRuns(words, progress.runIndex, endRun, runSplit);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
785 version(TextLayoutDebug) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
786 Stdout.format(" words: {0}, endRun: {1}, runSplit: {2}",
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
787 words, endRun, runSplit).newline;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
788 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
789 assert(runSplit > 0);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
790
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
791 GlyphIter lastSoftBreak;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
792 GlyphIter iter;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
793 iter.runs = runs;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
794 iter.startRun = progress.runIndex;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
795 iter.endRun = endRun;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
796 iter.endSplit = runSplit;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
797 lastSoftBreak = iter;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
798
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
799 int boxI = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
800
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
801 int lastRunIndex = iter.runIndex;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
802 cairo_font_extents_t lastRunExtents;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
803 lastRunExtents.ascent = lastRunExtents.descent = lastRunExtents.height = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
804
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
805 float x = lineBoxes[0].x;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
806 while(iter.next()) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
807 if(iter.runIndex != lastRunIndex) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
808 // If this isn't a dry run, blindly trust the height and baseline.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
809 // nothing we could do if they were wrong
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
810 if(!dryRun) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
811 iter.run.position = Point(x, y);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
812 iter.run.baseline = baseline;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
813 } else {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
814 // if this new run is taller, return the taller height and baseline
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
815 cairo_font_extents_t extents;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
816 cairo_scaled_font_extents(iter.run.font, &extents);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
817 auto below = max(extents.height-extents.ascent,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
818 lastRunExtents.height-lastRunExtents.ascent);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
819 baseline = max(baseline, extents.ascent, lastRunExtents.ascent);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
820 // floats aren't exact, so require a tenth of a pixel higher
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
821 if(baseline + below > height + 0.1) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
822 height = baseline + below;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
823 return iter.charCount;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
824 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
825 lastRunExtents = extents;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
826 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
827 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
828 lastRunIndex = iter.runIndex;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
829
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
830 if(logAttrs[iter.charIndex+iter.run.start].softBreak)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
831 lastSoftBreak = iter;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
832
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
833 x += iter.advanceWidth;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
834 // we always have to put at least one word per line
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
835 if(x > lineBoxes[boxI].right && words > 1) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
836 version(TextLayoutDebug)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
837 Stdout.format(" hit end of line box, boxI: {0}", boxI).newline;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
838 boxI++;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
839 if(boxI == lineBoxes.count) // we failed at getting all the text on
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
840 continue wordsLoop; // try again with one fewer word
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
841 x = lineBoxes[boxI].x;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
842
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
843 if(!dryRun) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
844 splitRun(lastSoftBreak.runIndex, lastSoftBreak.charIndex+lastSoftBreak.run.start);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
845 lastSoftBreak.endRun += 1;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
846 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
847 iter = lastSoftBreak;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
848 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
849 // if LTR, loop over clusterMap and logAttrs forward; if RTL, loop reverse
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
850 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
851 // getting to here means that we were successful in getting the text on
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
852
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
853
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
854 if(!dryRun) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
855 if(runSplit != 0 && runSplit != runs[iter.endRun-1].length) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
856 splitRun(iter.endRun-1, runSplit+runs[iter.endRun-1].start);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
857 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
858 // now that we know for sure what runs are on the line, set their height
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
859 for(int i = progress.runIndex; i < iter.endRun; ++i)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
860 runs.data[i].height = height;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
861 progress.runIndex = iter.endRun;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
862 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
863 return iter.charCount;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
864
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
865 /*if(resolvedAlignment == TextAlignment.Left) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
866 } else if(resolvedAlignment == TextAlignment.Right) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
867 } else {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
868 assert(false);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
869 }*/
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
870 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
871 assert(false, "reached end of layoutLine()");
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
872 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
873 // }}}
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
874
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
875 // {{{ getMaxWords()
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
876 // returns the maximum number of words, starting at runIndex, that could fit in
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
877 // the specified width
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
878 int getMaxWords(int runIndex, float width) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
879 int start = runs[runIndex].start;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
880
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
881 // find out how many glyphs will fit in the width
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
882 int glyphIndex;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
883 both:
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
884 for(; runIndex < runs.count; ++runIndex) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
885 // have to go over runs and glyphs in logical order because all the characters on
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
886 // the first line are logically before all the runs on the second line, and so on.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
887 glyphIndex = runs[runIndex].rightToLeft ? runs[runIndex].glyphs.length-1 : 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
888 while(glyphIndex >= 0 && glyphIndex < runs[runIndex].glyphs.length) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
889 width -= runs[runIndex].advanceWidths[glyphIndex];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
890 if(width < 0)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
891 break both;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
892 glyphIndex += runs[runIndex].rightToLeft ? -1 : 1;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
893 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
894 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
895 if(runIndex == runs.count)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
896 runIndex--;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
897
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
898 // find which character goes with the last glyph
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
899 int charIndex = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
900 while(charIndex < runs[runIndex].length) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
901 if(runs[runIndex].rightToLeft && runs[runIndex].clusterMap[charIndex] < glyphIndex)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
902 break;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
903 if(!runs[runIndex].rightToLeft && runs[runIndex].clusterMap[charIndex] > glyphIndex)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
904 break;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
905 charIndex++;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
906 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
907 int end = charIndex + runs[runIndex].start;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
908
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
909 // find out how many words are in the character range (and thus in the glyphs)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
910 int words = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
911 for(int i = start; i < end; ++i) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
912 if(logAttrs[i].softBreak)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
913 words++;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
914 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
915 if(end == text.length || words == 0) // consider the end as the start of another word
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
916 words++;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
917 return words;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
918 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
919 // }}}
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
920
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
921 // {{{ struct GlyphIter
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
922 // TODO: need to loop using visualToLogicalOrder
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
923 struct GlyphIter {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
924 List!(Run) runs;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
925 void startRun(int index) { runIndex = index - 1; }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
926 int endRun;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
927 int endGlyphSplit; // the number of glyphs in the last run
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
928 // sets the number of characters in the last run
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
929 void endSplit(int split) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
930 assert(split <= runs[endRun-1].length);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
931 if(split == runs[endRun-1].length)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
932 endGlyphSplit = runs[endRun-1].glyphs.length;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
933 else
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
934 endGlyphSplit = runs[endRun-1].clusterMap[split];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
935 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
936
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
937 int runIndex = -1;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
938 // usually the character that produced the current glyph (except when reordered)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
939 int charIndex = 0; // counting from the start of the run
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
940 int glyphIndex = -1;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
941 int charCount = 1; // charIndex starts at 0; it has already advanced to the first char
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
942
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
943 Run* run() { return &runs.data[runIndex]; }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
944
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
945 // need to call once before getting the first glyph
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
946 // returns true if there is another valid glyph to use
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
947 // if false is returned, do not access any more glyphs or call next() again
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
948 bool next() {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
949 assert(runIndex < endRun);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
950 //Stdout("glyphIndex: ")(glyphIndex)(" runIndex: ")(runIndex).newline;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
951
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
952 if(glyphIndex == -1 || glyphIndex == runs[runIndex].glyphs.length-1) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
953 runIndex++;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
954 if(runIndex == endRun)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
955 return false;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
956 glyphIndex = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
957 charCount += run.rightToLeft ? charIndex : run.length-charIndex;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
958 charIndex = run.rightToLeft ? run.length-1 : 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
959 if(runIndex == endRun-1 && runs[runIndex].rightToLeft)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
960 glyphIndex = endGlyphSplit-1;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
961 } else {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
962 glyphIndex++;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
963 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
964 if(runIndex == endRun-1) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
965 if(!runs[runIndex].rightToLeft && glyphIndex == endGlyphSplit)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
966 return false;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
967 if(runs[runIndex].rightToLeft && glyphIndex == runs[runIndex].glyphs.length)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
968 return false;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
969 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
970
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
971 // advance charIndex, if needed
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
972 auto newChar = charIndex;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
973 while(newChar >= 0 && newChar < run.length) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
974 // if we found the next cluster
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
975 if(run.clusterMap[newChar] != run.clusterMap[charIndex]) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
976 // if the next char produced a glyph after where we are, then stay put
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
977 if(run.clusterMap[newChar] > glyphIndex)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
978 break;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
979 charCount += newChar-charIndex > 0 ? newChar-charIndex : charIndex-newChar;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
980 charIndex = newChar;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
981 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
982 newChar += run.rightToLeft ? -1 : 1;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
983 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
984
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
985 //Stdout(" *glyphIndex: ")(glyphIndex)(" runIndex: ")(runIndex).newline;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
986 return true;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
987 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
988 float advanceWidth() { return runs[runIndex].advanceWidths[glyphIndex]; }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
989 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
990 // }}}
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
991
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
992 // words is the number of words the runs should contain
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
993 // startRun is the index of the first run to count words for
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
994 // endRun is the index of the last run plus 1 (the last run exclusive)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
995 // endRunSplit is how many characters in the last run it takes to get the specified word count
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
996 void getRuns(int words, int startRun, out int lastRun, out int lastRunSplit) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
997 assert(words >= 1); // TODO: change endRun to lastRun and make it inclusive
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
998 lastRun = startRun;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
999 // add 1 to start with so that if a run begins with a word, it doesn't count
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1000 for(int i = runs[startRun].start + 1; i < text.length; ++i) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1001 if(runs[lastRun].end < i)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1002 lastRun++;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1003 if(logAttrs[i].softBreak) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1004 words--;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1005 if(words == 0) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1006 lastRunSplit = i - runs[lastRun].start;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1007 lastRun++; // TODO: hack
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1008 return;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1009 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1010 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1011 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1012 lastRun = runs.count - 1;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1013 lastRunSplit = runs[lastRun].length;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1014 lastRun++; //hack
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1015 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1016
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1017 // {{{ draw()
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1018 // TODO: make layout() protected
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1019 // functions should call it automatically when needed
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1020 List!(cairo_glyph_t) glyphs;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1021 void draw(Graphics g) { // TODO: take a layoutBoxIndex parameter to only draw one of them?
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1022 layout(g); // TODO: fix to only call if needed
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1023
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1024 if(!glyphs)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1025 glyphs = new List!(cairo_glyph_t)(80);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1026
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1027 /*
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1028 * If runs are removed because not all the text will fit in the layout boxes,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1029 * then we need to split at the end of the last one in splitter(), and break out
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1030 * of the loop when we reach the last run, since otherwise it goes to the end of
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1031 * the text.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1032 */
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1033 int splitter(uint i) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1034 return i < runs.count ? runs[i].start : (i == runs.count ? runs[runs.count-1].end : -1);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1035 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1036 int runIndex = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1037 double x = runs[runIndex].position.x;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1038 foreach(start, length, format; formatRuns(&splitter)) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1039 uint end = start + length;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1040
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1041 if(runs[runIndex].end == start) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1042 runIndex++;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1043 if(runIndex == runs.count) // happens if runs were removed because they didn't fit
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1044 break;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1045 x = runs[runIndex].position.x;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1046 if(runs[runIndex].rightToLeft)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1047 x += runs[runIndex].width;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1048 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1049 Run* r = &runs[runIndex];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1050 assert(r.end >= end);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1051
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1052 cairo_matrix_t ctm;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1053 cairo_get_matrix(g.handle, &ctm);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1054 double x0 = ctm.x0, y0 = ctm.y0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1055 cairo_scaled_font_get_ctm(r.font, &ctm);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1056 ctm.x0 = x0, ctm.y0 = y0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1057 cairo_set_matrix(g.handle, &ctm);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1058 cairo_set_scaled_font(g.handle, r.font);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1059
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1060 //Stdout(r.position)(" ")(text[start..end]).newline;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1061 // note: using 'length' in a slice doesn't mean the 'length' in scope--it means the
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1062 // length of the array you are slicing...arg, wasted 15 minutes
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1063
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1064 // find glyphs to draw
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1065 int glyphStart;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1066 int glyphEnd;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1067 // TODO: I believe this setting glyphStart/End works right, but can it be shortened?
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1068 // besides the places the index equals the length, could just swap gStart and gEnd?
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1069 if(r.rightToLeft) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1070 if(start-r.start == 0)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1071 glyphEnd = r.glyphs.length;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1072 else
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1073 glyphEnd = r.clusterMap[start-r.start];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1074 if(end-r.start == r.clusterMap.length)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1075 glyphStart = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1076 else
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1077 glyphStart = r.clusterMap[end-r.start];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1078 } else {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1079 glyphStart = r.clusterMap[start-r.start];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1080 if(end-r.start == r.clusterMap.length)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1081 glyphEnd = r.glyphs.length;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1082 else
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1083 glyphEnd = r.clusterMap[end-r.start];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1084 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1085 //if(r.rightToLeft)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1086 // Stdout(glyphStart)(" -- ")(glyphEnd).newline;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1087
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1088 // draw backColor
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1089 float width = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1090 for(int i = glyphStart; i < glyphEnd; ++i)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1091 width += r.advanceWidths[i];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1092 Rect rect = Rect(r.rightToLeft ? x-width : x, r.position.y, width, r.height);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1093 g.source = format.backColor;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1094 g.rectangle(rect);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1095 g.fill();
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1096
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1097 // draw glyphs
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1098 int j = r.rightToLeft ? glyphEnd-1 : glyphStart;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1099 while(j >= glyphStart && j < glyphEnd) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1100 if(r.rightToLeft)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1101 x -= r.advanceWidths[j];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1102 cairo_glyph_t cairoGlyph;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1103 cairoGlyph.index = r.glyphs[j];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1104 cairoGlyph.x = x;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1105 cairoGlyph.y = r.position.y + r.baseline;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1106 //Stdout.format("x {0} y {1}", cairoGlyph.x, cairoGlyph.y).newline;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1107 glyphs.add(cairoGlyph);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1108 if(!r.rightToLeft)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1109 x += r.advanceWidths[j];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1110 r.rightToLeft ? j-- : j++;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1111 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1112 //Stdout.format("start {0}, color: {1}", start, format.foreColor.B).newline;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1113 g.source = format.foreColor;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1114 cairo_show_glyphs(g.handle, glyphs.data.ptr, glyphs.count);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1115 glyphs.clear();
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1116 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1117 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1118 // }}}
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1119
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1120 private:
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1121 // {{{ font cache
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1122 // Returns a scaled font matching the specified look. If the font is in the font cache
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1123 // it will be returned from there. If it isn't in the cache, it will be created using a
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1124 // backend specific function.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1125 // Note that the reference count on the scaled font is increased each time this function
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1126 // is called. Therefore, releaseScaledFont() needs to be called once for each time
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1127 // getScaledFont() is called.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1128 static cairo_scaled_font_t* getScaledFont(string family,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1129 double size,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1130 bool bold,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1131 bool italic,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1132 cairo_matrix_t ctm) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1133 if(!fontCache)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1134 fontCache = new List!(FontCacheEntry);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1135 // set the translation to zero so that
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1136 // 1. entryCtm == ctm can be used when searching through the cache, and it will still
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1137 // ignore the translation
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1138 // 2. the CTM of every scaled font in the font cache has a translation of zero
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1139 ctm.x0 = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1140 ctm.y0 = 0;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1141 foreach(entry; fontCache) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1142 if(entry.family == family && entry.size == size &&
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1143 entry.bold == bold && entry.italic == italic) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1144 cairo_matrix_t entryCtm;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1145 cairo_scaled_font_get_ctm(entry.font, &entryCtm);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1146 // a font can only match another if they have the same CTM (except the
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1147 // transformation can be different), so check that the CTMs are the same
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1148 if(entryCtm == ctm) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1149 cairo_scaled_font_reference(entry.font);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1150 return entry.font;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1151 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1152 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1153 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1154
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1155 // since a matching font wasn't found in the cache, create it and add it to the cache
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1156 FontCacheEntry entry;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1157 entry.font = backend_createScaledFont(family, size, bold, italic, &ctm);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1158 entry.family = family;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1159 entry.size = size;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1160 entry.bold = bold;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1161 entry.italic = italic;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1162 fontCache.add(entry);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1163 return entry.font;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1164 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1165 // Decreases the reference count of the scaled font and removes it from the cache when its
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1166 // reference count reaches zero.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1167 static void releaseScaledFont(cairo_scaled_font_t* font) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1168 if(cairo_scaled_font_get_reference_count(font) == 1) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1169 bool found = false;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1170 foreach(i, entry; fontCache) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1171 if(entry.font == font) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1172 fontCache.removeAt(i);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1173 found = true;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1174 break;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1175 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1176 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1177 assert(found);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1178 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1179 cairo_scaled_font_destroy(font);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1180 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1181 //}}}
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1182 }
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1183
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1184 struct FontCacheEntry {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1185 cairo_scaled_font_t* font;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1186 string family;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1187 double size;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1188 bool bold;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1189 bool italic;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1190 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1191
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1192 private List!(FontCacheEntry) fontCache; // global in D1, thread local in D2
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1193
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1194 // this is to keep the TextLayout.runs List around until the destructor is called
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1195 List!(List!(Run)) runLists;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1196
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1197 unittest {
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1198 auto t = new TextLayout("Tahoma", 15);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1199 t.text = "How are you doing today?";
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1200 t.setBold(true, 4, 3); // "are"
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1201 assert(t.formatting.count == 2);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1202 t.setBold(true, 7, 4); // " you"
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1203 assert(t.formatting.count == 2);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1204 t.setBold(true, 1, 3); // "ow "
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1205 assert(t.formatting.count == 2);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1206 t.setBold(true, 8, 9); // "you doing"
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1207 assert(t.formatting.count == 2);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1208 t.setBold(true, 0, 18); // "How are you doing "
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1209 assert(t.formatting.count == 2);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1210 assert(t.formatting[0].type == FormatType.Bold);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1211 assert(t.formatting[0].data.on == true);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1212 assert(t.formatting[1].type == FormatType.Bold);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1213 assert(t.formatting[1].data.on == false);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1214 t.setBold(false, 0, 24);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1215 assert(t.formatting.count == 0);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1216
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1217 t.setBold(true, 4, 3); // "are"
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1218 assert(t.formatting.count == 2);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1219 t.setBold(true, 8, 3); // "you"
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1220 assert(t.formatting.count == 4);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1221 t.setBold(true, 1, 16); // "ow are you doing"
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1222 assert(t.formatting.count == 2);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1223 t.setBold(false, 4, 8); // "are you "
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1224 assert(t.formatting.count == 4);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1225 assert(t.formatting[0].index == 1);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1226 assert(t.formatting[0].data.on == true);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1227 assert(t.formatting[1].index == 4);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1228 assert(t.formatting[1].data.on == false);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1229 assert(t.formatting[2].index == 12);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1230 assert(t.formatting[2].data.on == true);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1231 assert(t.formatting[3].index == 17);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1232 assert(t.formatting[3].data.on == false);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1233 t.setBold(false, 1, 3); // "ow "
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1234 assert(t.formatting.count == 2);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1235 t.setUnderline(LineStyle.Double, 8, 9); // "you doing"
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1236 assert(t.formatting.count == 4);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1237 t.setBold(false, 0, 20); // "How are you doing t"
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1238 assert(t.formatting.count == 2);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1239 assert(t.formatting[0].type == FormatType.Underline);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1240 assert(t.formatting[1].type == FormatType.Underline);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1241 t.setUnderline(LineStyle.Single, 12, 11); // "doing today"
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1242 assert(t.formatting.count == 3);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1243 assert(t.formatting[0].data.style == LineStyle.Double);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1244 assert(t.formatting[1].data.style == LineStyle.Single);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1245 assert(t.formatting[2].data.style == LineStyle.None);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1246 t.setUnderline(LineStyle.None, 4, 14); // "are you doing "
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1247 assert(t.formatting.count == 2);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1248 assert(t.formatting[0].data.style == LineStyle.Single);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1249 assert(t.formatting[0].index == 18);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1250 t.setUnderline(LineStyle.None, 4, 20); // "are you doing today?"
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1251 assert(t.formatting.count == 0);
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1252 }
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1253
91
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1254 unittest {
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1255 auto t = new TextLayout("Arial", 14);
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1256 t.text = "The computer is black.";
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1257 int[][] runs = [[0, 22]];
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1258 int delegate(uint index) splitter;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1259 void checkRuns() {
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1260 int i = 0;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1261 foreach(s, l, f; t.formatRuns(splitter)) {
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1262 assert(runs[i][0] == s && runs[i][1] == l);
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1263 i++;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1264 }
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1265 }
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1266 // no formatting or splitter
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1267 checkRuns();
85
ded31d46f75f Add TextLayout. So far, it handles character formatting and does not draw.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1268
91
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1269 // with a splitter but no formatting
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1270 splitter = delegate int(uint i) { return [0, -1][i]; };
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1271 checkRuns();
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1272 splitter = delegate int(uint i) { return [22, -1][i]; };
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1273 checkRuns();
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1274 splitter = delegate int(uint i) { return [10, 15, -1][i]; };
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1275 runs = [[0, 10], [10, 5], [15, 7]];
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1276 checkRuns();
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1277 splitter = null;
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1278
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1279 // with formatting but no splitter
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1280 t.setFontFamily("Tahoma", 4, 8); // "computer"
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1281 runs = [[0, 4], [4, 8], [12, 10]];
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1282 checkRuns();
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1283
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1284 t.setUnderline(LineStyle.Single, 12, 3); // " is"
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1285 runs = [[0, 4], [4, 8], [12, 3], [15,7]];
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1286 checkRuns(); // test two FormatChanges at the same index
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1287
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1288 t.setUnderline(LineStyle.Double, 0, 22);
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1289 runs = [[0, 4], [4, 8], [12, 10]];
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1290 checkRuns(); // test a FormatChange at beginning and at end
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1291
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1292 splitter = delegate int(uint i) { return [2, 4, 21, -1][i]; };
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1293 runs = [[0, 2], [2, 2], [4, 8], [12, 9], [21, 1]];
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1294 checkRuns(); // test a split in middle of a format run and at the same index as a format run
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1295
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1296 // TODO: test fontFormatRuns
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1297 }
85cd0b04777c Add TextLayout.formatRuns and fontFormatRuns, and tests for formatRuns
Jordan Miner <jminer7@gmail.com>
parents: 90
diff changeset
1298
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1299 unittest {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1300 auto surf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1301 auto cr = cairo_create(surf);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1302 cairo_surface_destroy(surf);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1303 auto g = new Graphics(cr);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1304 cairo_destroy(cr);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1305
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1306 // with 0 being the first line
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1307 void assertLineRange(TextLayout t, int line, int start, int length) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1308 float lastLineY;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1309 int startAct = -1, lengthAct = -1; // actual start and length of line
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1310 foreach(run; t.runs) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1311 if(run.position.y != lastLineY) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1312 line--;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1313 if(line == -1) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1314 startAct = run.start;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1315 } else if(line == -2) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1316 lengthAct = run.start - startAct;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1317 break;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1318 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1319 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1320 lastLineY = run.position.y;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1321 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1322 assert(startAct >= 0);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1323 if(lengthAct == -1)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1324 lengthAct = t.text.length - startAct;
105
97997a544ac0 Add a couple TODOs and clean up a logging statement.
Jordan Miner <jminer7@gmail.com>
parents: 103
diff changeset
1325 Stdout.format("test start: {0} len: {1} startAct: {2} lenAct: {3}", start, length, startAct, lengthAct).newline;
96
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1326 assert(start == startAct && length == lengthAct);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1327 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1328 void assertLinePosition(TextLayout t, int line, float x, float y) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1329 float lastLineY;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1330 foreach(run; t.runs) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1331 if(run.position.y != lastLineY) {
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1332 line--;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1333 if(line == -1) // test the x of the first run on the line
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1334 assert(run.position.x < x+0.01 && run.position.x > x-0.01);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1335 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1336 if(line == -1) // and test the y of every run on the line
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1337 assert(run.position.y < y+0.01 && run.position.y > y-0.01);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1338 else if(line < -1)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1339 break;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1340 lastLineY = run.position.y;
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1341 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1342 assert(line < 0); // assert that there were enough lines
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1343 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1344
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1345 auto t = new TextLayout("Ahem", 10);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1346 t.text = "The quick brown fox jumps over the lazy dog.";
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1347
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1348 // Test that lines are moved down when text on them is larger than the beginning.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1349 // Test that the second line is not too tall, since no text on it is larger.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1350 // Test that having a one character run at the end is handled correctly. (doesn't crash)
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1351 t.setFontSize(12, 15, 1); // " "
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1352 t.setFontSize(13, 16, 4); // "fox "
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1353 t.setFontSize( 8, 43, 1); // "."
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1354 t.layoutBoxes = [Rect(40, 30, 225, 100)];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1355 //The quick brown fox /jumps over the lazy /dog./
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1356 t.draw(g);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1357 assertLineRange(t, 0, 0, 20); // line 0 has first 20 chars
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1358 assertLineRange(t, 1, 20, 20); // line 1 has next 20 chars
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1359 assertLineRange(t, 2, 40, 4); // line 2 has next 4 chars
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1360 assertLinePosition(t, 0, 40, 30);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1361 assertLinePosition(t, 1, 40, 43);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1362 assertLinePosition(t, 2, 40, 53);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1363
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1364 // Test that when runs are cut off due to not fitting in layout boxes,
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1365 // there is no assert failure in draw()
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1366 t.layoutBoxes = [Rect(40, 30, 225, 24)];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1367 t.draw(g);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1368
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1369 // Test that layout boxes work:
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1370 // that lines are wrapped to the width of the layout box and
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1371 // that they are positioned correctly vertically.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1372 t.setFontSize(10, 0, t.text.length);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1373 t.layoutBoxes = [Rect(20, 20, 170, 24), Rect(200, 1000, 60, 33)];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1374 //The quick brown /fox jumps over /the /lazy /dog./
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1375 t.draw(g);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1376 assertLineRange(t, 0, 0, 16);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1377 assertLineRange(t, 1, 16, 15);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1378 assertLineRange(t, 2, 31, 4);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1379 assertLineRange(t, 3, 35, 5);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1380 assertLineRange(t, 4, 40, 4);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1381 assertLinePosition(t, 0, 20, 20);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1382 assertLinePosition(t, 1, 20, 30);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1383 assertLinePosition(t, 2, 200, 1000);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1384 assertLinePosition(t, 3, 200, 1010);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1385 assertLinePosition(t, 4, 200, 1020);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1386
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1387 /*
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1388 test that the height of a run on a line is not set to the height of the line (stays the height of the text
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1389 test that having taller text on a line, then shorter text, then that the next line is the right height
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1390 test that text is broken for line boxes
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1391 test having bigger text near end of line, and when line is moved down, first line box is smaller, so text is broken sooner
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1392 test that if text needs to be moved down and fewer chars fit on, that it is not moved down
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1393 */
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1394
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1395 // Test that a whole word is put on a line, even when the layout box is not wide enough.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1396 // Test that there is no crash when the first word is wider than the layout box.
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1397 t.text = "Somebodyforgottousespaces, oh, thisisbad, I say.";
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1398 t.layoutBoxes = [Rect(40, 30, 85, 50)];
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1399 t.draw(g);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1400 assertLineRange(t, 0, 0, 27);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1401 assertLineRange(t, 1, 27, 4);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1402 assertLineRange(t, 2, 31, 11);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1403 assertLineRange(t, 3, 42, 6);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1404 assertLinePosition(t, 0, 40, 30);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1405 assertLinePosition(t, 1, 40, 40);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1406 assertLinePosition(t, 2, 40, 50);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1407 assertLinePosition(t, 3, 40, 60);
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1408
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1409 // write manual tests into showcase
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1410 }
301e077da540 Add the beginnings of a Windows Uniscribe text backend.
Jordan Miner <jminer7@gmail.com>
parents: 92
diff changeset
1411