1 | /* Pango |
2 | * pango-ot-buffer.c: Buffer of glyphs for shaping/positioning |
3 | * |
4 | * Copyright (C) 2004 Red Hat Software |
5 | * |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Library General Public |
8 | * License as published by the Free Software Foundation; either |
9 | * version 2 of the License, or (at your option) any later version. |
10 | * |
11 | * This library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Library General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Library General Public |
17 | * License along with this library; if not, write to the |
18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
19 | * Boston, MA 02111-1307, USA. |
20 | */ |
21 | |
22 | #include "config.h" |
23 | |
24 | #include "pango-ot-private.h" |
25 | |
26 | static PangoOTBuffer * |
27 | pango_ot_buffer_copy (PangoOTBuffer *src) |
28 | { |
29 | PangoOTBuffer *dst = g_slice_new (PangoOTBuffer); |
30 | |
31 | dst->buffer = hb_buffer_reference (buffer: src->buffer); |
32 | |
33 | return dst; |
34 | } |
35 | |
36 | G_DEFINE_BOXED_TYPE (PangoOTBuffer, pango_ot_buffer, |
37 | pango_ot_buffer_copy, |
38 | pango_ot_buffer_destroy) |
39 | |
40 | /** |
41 | * pango_ot_buffer_new: |
42 | * @font: a `PangoFcFont` |
43 | * |
44 | * Creates a new `PangoOTBuffer` for the given OpenType font. |
45 | * |
46 | * Return value: the newly allocated `PangoOTBuffer`, which should |
47 | * be freed with [method@PangoOT.Buffer.destroy]. |
48 | * |
49 | * Since: 1.4 |
50 | */ |
51 | PangoOTBuffer * |
52 | pango_ot_buffer_new (PangoFcFont *font) |
53 | { |
54 | PangoOTBuffer *buffer = g_slice_new (PangoOTBuffer); |
55 | |
56 | buffer->buffer = hb_buffer_create (); |
57 | |
58 | return buffer; |
59 | } |
60 | |
61 | /** |
62 | * pango_ot_buffer_destroy: |
63 | * @buffer: a `PangoOTBuffer` |
64 | * |
65 | * Destroys a `PangoOTBuffer` and free all associated memory. |
66 | * |
67 | * Since: 1.4 |
68 | */ |
69 | void |
70 | pango_ot_buffer_destroy (PangoOTBuffer *buffer) |
71 | { |
72 | hb_buffer_destroy (buffer: buffer->buffer); |
73 | g_slice_free (PangoOTBuffer, buffer); |
74 | } |
75 | |
76 | /** |
77 | * pango_ot_buffer_clear: |
78 | * @buffer: a `PangoOTBuffer` |
79 | * |
80 | * Empties a `PangoOTBuffer`, make it ready to add glyphs to. |
81 | * |
82 | * Since: 1.4 |
83 | */ |
84 | void |
85 | pango_ot_buffer_clear (PangoOTBuffer *buffer) |
86 | { |
87 | hb_buffer_reset (buffer: buffer->buffer); |
88 | } |
89 | |
90 | /** |
91 | * pango_ot_buffer_add_glyph: |
92 | * @buffer: a `PangoOTBuffer` |
93 | * @glyph: the glyph index to add, like a `PangoGlyph` |
94 | * @properties: the glyph properties |
95 | * @cluster: the cluster that this glyph belongs to |
96 | * |
97 | * Appends a glyph to a `PangoOTBuffer`, with @properties identifying which |
98 | * features should be applied on this glyph. |
99 | * |
100 | * See [method@PangoOT.Ruleset.add_feature]. |
101 | * |
102 | * Since: 1.4 |
103 | */ |
104 | void |
105 | pango_ot_buffer_add_glyph (PangoOTBuffer *buffer, |
106 | guint glyph, |
107 | guint properties, |
108 | guint cluster) |
109 | { |
110 | hb_buffer_add (buffer: buffer->buffer, codepoint: glyph, cluster); |
111 | } |
112 | |
113 | /** |
114 | * pango_ot_buffer_set_rtl: |
115 | * @buffer: a `PangoOTBuffer` |
116 | * @rtl: %TRUE for right-to-left text |
117 | * |
118 | * Sets whether glyphs will be rendered right-to-left. |
119 | * |
120 | * This setting is needed for proper horizontal positioning |
121 | * of right-to-left scripts. |
122 | * |
123 | * Since: 1.4 |
124 | */ |
125 | void |
126 | pango_ot_buffer_set_rtl (PangoOTBuffer *buffer, |
127 | gboolean rtl) |
128 | { |
129 | hb_buffer_set_direction (buffer: buffer->buffer, direction: rtl ? HB_DIRECTION_RTL : HB_DIRECTION_LTR); |
130 | } |
131 | |
132 | /** |
133 | * pango_ot_buffer_set_zero_width_marks |
134 | * @buffer: a `PangoOTBuffer` |
135 | * @zero_width_marks: %TRUE if characters with a mark class should |
136 | * be forced to zero width |
137 | * |
138 | * Sets whether characters with a mark class should be forced to zero width. |
139 | * |
140 | * This setting is needed for proper positioning of Arabic accents, |
141 | * but will produce incorrect results with standard OpenType Indic |
142 | * fonts. |
143 | * |
144 | * Since: 1.6 |
145 | */ |
146 | void |
147 | pango_ot_buffer_set_zero_width_marks (PangoOTBuffer *buffer, |
148 | gboolean zero_width_marks) |
149 | { |
150 | } |
151 | |
152 | /** |
153 | * pango_ot_buffer_get_glyphs |
154 | * @buffer: a `PangoOTBuffer` |
155 | * @glyphs: (array length=n_glyphs) (out) (optional): location to |
156 | * store the array of glyphs |
157 | * @n_glyphs: (out) (optional): location to store the number of glyphs |
158 | * |
159 | * Gets the glyph array contained in a `PangoOTBuffer`. |
160 | * |
161 | * The glyphs are owned by the buffer and should not be freed, |
162 | * and are only valid as long as buffer is not modified. |
163 | * |
164 | * Since: 1.4 |
165 | */ |
166 | void |
167 | pango_ot_buffer_get_glyphs (const PangoOTBuffer *buffer, |
168 | PangoOTGlyph **glyphs, |
169 | int *n_glyphs) |
170 | { |
171 | if (glyphs) |
172 | *glyphs = (PangoOTGlyph *) hb_buffer_get_glyph_infos (buffer: buffer->buffer, NULL); |
173 | |
174 | if (n_glyphs) |
175 | *n_glyphs = hb_buffer_get_length (buffer: buffer->buffer); |
176 | } |
177 | |
178 | /** |
179 | * pango_ot_buffer_output |
180 | * @buffer: a `PangoOTBuffer` |
181 | * @glyphs: a `PangoGlyphString` |
182 | * |
183 | * Exports the glyphs in a `PangoOTBuffer` into a `PangoGlyphString`. |
184 | * |
185 | * This is typically used after the OpenType layout processing |
186 | * is over, to convert the resulting glyphs into a generic Pango |
187 | * glyph string. |
188 | * |
189 | * Since: 1.4 |
190 | */ |
191 | void |
192 | pango_ot_buffer_output (const PangoOTBuffer *buffer, |
193 | PangoGlyphString *glyphs) |
194 | { |
195 | unsigned int i; |
196 | int last_cluster; |
197 | |
198 | unsigned int num_glyphs; |
199 | hb_buffer_t *hb_buffer = buffer->buffer; |
200 | hb_glyph_info_t *hb_glyph; |
201 | hb_glyph_position_t *hb_position; |
202 | |
203 | if (HB_DIRECTION_IS_BACKWARD (hb_buffer_get_direction (buffer->buffer))) |
204 | hb_buffer_reverse (buffer: buffer->buffer); |
205 | |
206 | /* Copy glyphs into output glyph string */ |
207 | num_glyphs = hb_buffer_get_length (buffer: hb_buffer); |
208 | hb_glyph = hb_buffer_get_glyph_infos (buffer: hb_buffer, NULL); |
209 | hb_position = hb_buffer_get_glyph_positions (buffer: hb_buffer, NULL); |
210 | pango_glyph_string_set_size (string: glyphs, new_len: num_glyphs); |
211 | last_cluster = -1; |
212 | for (i = 0; i < num_glyphs; i++) |
213 | { |
214 | glyphs->glyphs[i].glyph = hb_glyph->codepoint; |
215 | glyphs->log_clusters[i] = hb_glyph->cluster; |
216 | glyphs->glyphs[i].attr.is_cluster_start = glyphs->log_clusters[i] != last_cluster; |
217 | last_cluster = glyphs->log_clusters[i]; |
218 | |
219 | glyphs->glyphs[i].geometry.width = hb_position->x_advance; |
220 | glyphs->glyphs[i].geometry.x_offset = hb_position->x_offset; |
221 | glyphs->glyphs[i].geometry.y_offset = hb_position->y_offset; |
222 | |
223 | hb_glyph++; |
224 | hb_position++; |
225 | } |
226 | |
227 | if (HB_DIRECTION_IS_BACKWARD (hb_buffer_get_direction (buffer->buffer))) |
228 | hb_buffer_reverse (buffer: buffer->buffer); |
229 | } |
230 | |