OLD | NEW |
1 /* | 1 /* |
2 This file is part of LilyPond, the GNU music typesetter. | 2 This file is part of LilyPond, the GNU music typesetter. |
3 | 3 |
4 Copyright (C) 2004--2020 Han-Wen Nienhuys <hanwen@xs4all.nl> | 4 Copyright (C) 2004--2020 Han-Wen Nienhuys <hanwen@xs4all.nl> |
5 | 5 |
6 LilyPond is free software: you can redistribute it and/or modify | 6 LilyPond is free software: you can redistribute it and/or modify |
7 it under the terms of the GNU General Public License as published by | 7 it under the terms of the GNU General Public License as published by |
8 the Free Software Foundation, either version 3 of the License, or | 8 the Free Software Foundation, either version 3 of the License, or |
9 (at your option) any later version. | 9 (at your option) any later version. |
10 | 10 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 FT_Load_Glyph (face, idx, FT_LOAD_NO_SCALE); | 94 FT_Load_Glyph (face, idx, FT_LOAD_NO_SCALE); |
95 | 95 |
96 if (!(face->glyph->format == FT_GLYPH_FORMAT_OUTLINE)) | 96 if (!(face->glyph->format == FT_GLYPH_FORMAT_OUTLINE)) |
97 { | 97 { |
98 // no warnings; this happens a lot | 98 // no warnings; this happens a lot |
99 Box b = ly_FT_get_unscaled_indexed_char_dimensions (face, signed_idx); | 99 Box b = ly_FT_get_unscaled_indexed_char_dimensions (face, signed_idx); |
100 lazy->add_box (transform, b); | 100 lazy->add_box (transform, b); |
101 return; | 101 return; |
102 } | 102 } |
103 | 103 |
| 104 // TrueType and PS fonts have opposite ideas about contour |
| 105 // orientation. |
| 106 bool is_tt = std::string ("TrueType") == FT_Get_Font_Format (face); |
| 107 Orientation orientation = is_tt ? CW : CCW; |
| 108 |
104 FT_Outline *outline = &(face->glyph->outline); | 109 FT_Outline *outline = &(face->glyph->outline); |
105 int contour_start = 0; | 110 int contour_start = 0; |
106 for (short c = 0; c < outline->n_contours; c++) | 111 for (short c = 0; c < outline->n_contours; c++) |
107 { | 112 { |
108 Offset firstpos; | 113 Offset firstpos; |
109 Offset lastpos; | 114 Offset lastpos; |
110 | 115 |
111 int sz = outline->contours[c] - contour_start + 1; | 116 int sz = outline->contours[c] - contour_start + 1; |
112 FT_Vector *contour = outline->points + contour_start; | 117 FT_Vector *contour = outline->points + contour_start; |
113 char *ctags = outline->tags + contour_start; | 118 char *ctags = outline->tags + contour_start; |
114 contour_start += sz; | 119 contour_start += sz; |
115 int j = 0; | 120 int j = 0; |
116 while (j < sz) | 121 while (j < sz) |
117 { | 122 { |
118 if (j == 0) | 123 if (j == 0) |
119 { | 124 { |
120 firstpos = ftvector2offset (contour[j]); | 125 firstpos = ftvector2offset (contour[j]); |
121 lastpos = firstpos; | 126 lastpos = firstpos; |
122 j++; | 127 j++; |
123 } | 128 } |
124 else if (ctags[j] & 1) | 129 else if (ctags[j] & 1) |
125 { | 130 { |
126 // it is a line | 131 // it is a line |
127 Offset p = ftvector2offset (contour[j]); | 132 Offset p = ftvector2offset (contour[j]); |
128 lazy->add_segment (transform, lastpos, p); | 133 lazy->add_contour_segment (transform, orientation, lastpos, p); |
129 lastpos = p; | 134 lastpos = p; |
130 j++; | 135 j++; |
131 } | 136 } |
132 else if (ctags[j] & 2) | 137 else if (ctags[j] & 2) |
133 { | 138 { |
134 // it is a third order bezier. | 139 // it is a third order bezier. |
135 Bezier curve; | 140 Bezier curve; |
136 curve.control_[0] = {lastpos}; | 141 curve.control_[0] = {lastpos}; |
137 for (int i = 0; i < 3; i++) | 142 for (int i = 0; i < 3; i++) |
138 { | 143 { |
139 curve.control_[i + 1] | 144 curve.control_[i + 1] |
140 = ftvector2offset (contour[(j + i) % sz]); | 145 = ftvector2offset (contour[(j + i) % sz]); |
141 } | 146 } |
142 lastpos = curve.control_[3]; | 147 lastpos = curve.control_[3]; |
143 j += 3; | 148 j += 3; |
144 | 149 |
145 Offset start = transform (curve.control_[0]); | 150 Offset start = transform (curve.control_[0]); |
146 Offset end = transform (curve.control_[3]); | 151 Offset end = transform (curve.control_[3]); |
147 size_t quantization | 152 size_t quantization |
148 = std::max (2, int ((end - start).length () / 0.2)); | 153 = std::max (2, int ((end - start).length () / 0.2)); |
149 | 154 |
150 Offset last; | 155 Offset last; |
151 for (vsize i = 0; i <= quantization; i++) | 156 for (vsize i = 0; i <= quantization; i++) |
152 { | 157 { |
153 // This would be faster if we did the Bezier computation in in
tegers. | 158 // This would be faster if we did the Bezier computation in in
tegers. |
154 Offset pt = curve.curve_point ( | 159 Offset pt = curve.curve_point ( |
155 static_cast<Real> (i) / static_cast<Real> (quantization)); | 160 static_cast<Real> (i) / static_cast<Real> (quantization)); |
156 lazy->add_segment (transform, last, pt); | 161 lazy->add_contour_segment (transform, orientation, last, pt); |
157 last = pt; | 162 last = pt; |
158 } | 163 } |
159 } | 164 } |
160 else | 165 else |
161 { | 166 { |
162 // It is a second order bezier. We don't have code to | 167 // It is a second order bezier. We don't have code to |
163 // handle these. Substitute a line segment instead. | 168 // handle these. Substitute a line segment instead. |
164 Offset p = ftvector2offset (contour[(j + 1) % sz]); | 169 Offset p = ftvector2offset (contour[(j + 1) % sz]); |
165 lazy->add_segment (transform, lastpos, p); | 170 lazy->add_contour_segment (transform, orientation, lastpos, p); |
166 lastpos = p; | 171 lastpos = p; |
167 j += 2; | 172 j += 2; |
168 } | 173 } |
169 } | 174 } |
170 lazy->add_segment (transform, lastpos, firstpos); | 175 lazy->add_contour_segment (transform, orientation, lastpos, firstpos); |
171 } | 176 } |
172 } | 177 } |
OLD | NEW |