blob: 64217a041f4ec10ec805c770f5d6229ed3fe8860 [file] [log] [blame]
Behdad Esfahbod5cecfe82023-02-23 13:58:40 -07001/*
2 * Copyright © 2023 Behdad Esfahbod
3 *
4 * This is part of HarfBuzz, a text shaping library.
5 *
6 * Permission is hereby granted, without written agreement and without
7 * license or royalty fees, to use, copy, modify, and distribute this
8 * software and its documentation for any purpose, provided that the
9 * above copyright notice and the following two paragraphs appear in
10 * all copies of this software.
11 *
12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16 * DAMAGE.
17 *
18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23 */
24
25#ifndef HB_WASM_API_BUFFER_HH
26#define HB_WASM_API_BUFFER_HH
27
28#include "hb-wasm-api.hh"
29
30#include "hb-buffer.hh"
31
32namespace hb {
33namespace wasm {
34
Behdad Esfahbodc1dc1122023-02-23 15:47:56 -070035static_assert (sizeof (glyph_info_t) == sizeof (hb_glyph_info_t), "");
36static_assert (sizeof (glyph_position_t) == sizeof (hb_glyph_position_t), "");
Behdad Esfahbod5cecfe82023-02-23 13:58:40 -070037
Behdad Esfahbod16ecb962023-02-24 19:53:47 -070038HB_WASM_API (bool_t, buffer_contents_realloc) (HB_WASM_EXEC_ENV
39 ptr_d(buffer_contents_t, contents),
40 uint32_t size)
Behdad Esfahbod2d295182023-02-24 09:20:42 -070041{
Behdad Esfahbod9f8ad392023-02-24 14:16:11 -070042 HB_PTR_PARAM (buffer_contents_t, contents);
Behdad Esfahbod2d295182023-02-24 09:20:42 -070043 if (unlikely (!contents))
Behdad Esfahbod16ecb962023-02-24 19:53:47 -070044 return false;
Behdad Esfahbod2d295182023-02-24 09:20:42 -070045
46 if (size <= contents->length)
Behdad Esfahbod16ecb962023-02-24 19:53:47 -070047 return true;
Behdad Esfahbod2d295182023-02-24 09:20:42 -070048
49 unsigned bytes;
50 if (hb_unsigned_mul_overflows (size, sizeof (glyph_info_t), &bytes))
Behdad Esfahbod16ecb962023-02-24 19:53:47 -070051 return false;
Behdad Esfahbod2d295182023-02-24 09:20:42 -070052
Behdad Esfahbod196c6b62023-02-25 14:05:15 -070053 glyph_info_t *info = HB_ARRAY_APP2NATIVE (glyph_info_t, contents->info, contents->length);
54 glyph_position_t *pos = HB_ARRAY_APP2NATIVE (glyph_position_t, contents->pos, contents->length);
Behdad Esfahbod16ecb962023-02-24 19:53:47 -070055
Behdad Esfahbod196c6b62023-02-25 14:05:15 -070056 if (unlikely (!info || !pos))
57 return false;
Behdad Esfahbod2d295182023-02-24 09:20:42 -070058
Behdad Esfahbod196c6b62023-02-25 14:05:15 -070059 glyph_info_t *new_info = nullptr;
60 uint32_t new_inforef = module_malloc (bytes, (void **) &new_info);
61 glyph_position_t *new_pos = nullptr;
62 uint32_t new_posref = module_malloc (bytes, (void **) &new_pos);
Behdad Esfahbod2d295182023-02-24 09:20:42 -070063
Behdad Esfahbod196c6b62023-02-25 14:05:15 -070064 unsigned old_bytes = contents->length * sizeof (glyph_info_t);
65 if (likely (new_inforef))
Behdad Esfahbod16ecb962023-02-24 19:53:47 -070066 {
Behdad Esfahbod1fc128f2023-06-26 18:34:27 -060067 hb_memcpy (new_info, info, old_bytes);
Behdad Esfahbod196c6b62023-02-25 14:05:15 -070068 module_free (contents->info);
69 contents->info = new_inforef;
Behdad Esfahbod16ecb962023-02-24 19:53:47 -070070 }
Behdad Esfahbod196c6b62023-02-25 14:05:15 -070071 if (likely (new_posref))
Behdad Esfahbod16ecb962023-02-24 19:53:47 -070072 {
Behdad Esfahbod1fc128f2023-06-26 18:34:27 -060073 hb_memcpy (new_pos, pos, old_bytes);
Behdad Esfahbod196c6b62023-02-25 14:05:15 -070074 module_free (contents->pos);
75 contents->pos = new_posref;
Behdad Esfahbod16ecb962023-02-24 19:53:47 -070076 }
Behdad Esfahbod2d295182023-02-24 09:20:42 -070077
Behdad Esfahbod16ecb962023-02-24 19:53:47 -070078 if (likely (new_info && new_pos))
79 {
80 contents->length = size;
81 return true;
82 }
83
84 return false;
Behdad Esfahbod2d295182023-02-24 09:20:42 -070085}
86
Behdad Esfahbod39f87032023-02-24 12:42:22 -070087HB_WASM_API (void, buffer_contents_free) (HB_WASM_EXEC_ENV
88 ptr_d(buffer_contents_t, contents))
89{
Behdad Esfahbod9f8ad392023-02-24 14:16:11 -070090 HB_PTR_PARAM (buffer_contents_t, contents);
Behdad Esfahbod39f87032023-02-24 12:42:22 -070091 if (unlikely (!contents))
92 return;
93
94 module_free (contents->info);
95 module_free (contents->pos);
96
97 contents->info = nullref;
98 contents->pos = nullref;
99 contents->length = 0;
100}
101
Behdad Esfahbodb5b577f2023-02-25 08:12:16 -0700102HB_WASM_API (bool_t, buffer_copy_contents) (HB_WASM_EXEC_ENV
103 ptr_d(buffer_t, buffer),
104 ptr_d(buffer_contents_t, contents))
Behdad Esfahbod5cecfe82023-02-23 13:58:40 -0700105{
Behdad Esfahbod5cecfe82023-02-23 13:58:40 -0700106 HB_REF2OBJ (buffer);
Behdad Esfahbodb5b577f2023-02-25 08:12:16 -0700107 HB_PTR_PARAM (buffer_contents_t, contents);
108 if (unlikely (!contents))
109 return false;
Behdad Esfahbod5cecfe82023-02-23 13:58:40 -0700110
111 if (buffer->have_output)
112 buffer->sync ();
Behdad Esfahbode7540042023-02-25 09:18:40 -0700113 if (!buffer->have_positions)
114 buffer->clear_positions ();
Behdad Esfahbod5cecfe82023-02-23 13:58:40 -0700115
Behdad Esfahbod5cecfe82023-02-23 13:58:40 -0700116 unsigned length = buffer->len;
Behdad Esfahbode7540042023-02-25 09:18:40 -0700117
118 if (length <= contents->length)
119 {
Behdad Esfahbod4260de12023-02-25 10:43:27 -0700120 glyph_info_t *info = HB_ARRAY_APP2NATIVE (glyph_info_t, contents->info, length);
121 glyph_position_t *pos = HB_ARRAY_APP2NATIVE (glyph_position_t, contents->pos, length);
Behdad Esfahbode7540042023-02-25 09:18:40 -0700122
123 if (unlikely (!info || !pos))
124 {
125 contents->length = 0;
126 return false;
127 }
128
Behdad Esfahbod4260de12023-02-25 10:43:27 -0700129 unsigned bytes = length * sizeof (hb_glyph_info_t);
Behdad Esfahbod1fc128f2023-06-26 18:34:27 -0600130 hb_memcpy (info, buffer->info, bytes);
131 hb_memcpy (pos, buffer->pos, bytes);
Behdad Esfahbode7540042023-02-25 09:18:40 -0700132
133 return true;
134 }
135
Behdad Esfahbod41362cc2023-02-25 10:08:22 -0700136 module_free (contents->info);
137 module_free (contents->pos);
Behdad Esfahbodb0802612023-02-25 09:34:03 -0700138
Behdad Esfahbodb5b577f2023-02-25 08:12:16 -0700139 contents->length = length;
Behdad Esfahbod91eb2f42023-02-25 10:44:45 -0700140 unsigned bytes = length * sizeof (hb_glyph_info_t);
141 contents->info = wasm_runtime_module_dup_data (module_inst, (const char *) buffer->info, bytes);
142 contents->pos = wasm_runtime_module_dup_data (module_inst, (const char *) buffer->pos, bytes);
Behdad Esfahbodcb382e42023-02-24 17:56:14 -0700143
Behdad Esfahbodb5b577f2023-02-25 08:12:16 -0700144 if (length && (!contents->info || !contents->pos))
145 {
146 contents->length = 0;
147 return false;
148 }
149
150 return true;
Behdad Esfahbod5cecfe82023-02-23 13:58:40 -0700151}
152
Behdad Esfahbod39f87032023-02-24 12:42:22 -0700153HB_WASM_API (bool_t, buffer_set_contents) (HB_WASM_EXEC_ENV
154 ptr_d(buffer_t, buffer),
155 ptr_d(const buffer_contents_t, contents))
Behdad Esfahbodc1dc1122023-02-23 15:47:56 -0700156{
157 HB_REF2OBJ (buffer);
Behdad Esfahbod9f8ad392023-02-24 14:16:11 -0700158 HB_PTR_PARAM (buffer_contents_t, contents);
Behdad Esfahbodc1dc1122023-02-23 15:47:56 -0700159 if (unlikely (!contents))
160 return false;
161
162 unsigned length = contents->length;
163 unsigned bytes;
164 if (unlikely (hb_unsigned_mul_overflows (length, sizeof (buffer->info[0]), &bytes)))
165 return false;
166
167 if (unlikely (!buffer->resize (length)))
168 return false;
169
170 glyph_info_t *info = (glyph_info_t *) (validate_app_addr (contents->info, bytes) ? addr_app_to_native (contents->info) : nullptr);
171 glyph_position_t *pos = (glyph_position_t *) (validate_app_addr (contents->pos, bytes) ? addr_app_to_native (contents->pos) : nullptr);
172
Behdad Esfahbode7540042023-02-25 09:18:40 -0700173 if (!buffer->have_positions)
174 buffer->clear_positions (); /* This is wasteful. */
175
Behdad Esfahbod1fc128f2023-06-26 18:34:27 -0600176 hb_memcpy (buffer->info, info, bytes);
177 hb_memcpy (buffer->pos, pos, bytes);
Behdad Esfahbodc1dc1122023-02-23 15:47:56 -0700178 buffer->len = length;
179
180 return true;
181}
182
Behdad Esfahbod39f87032023-02-24 12:42:22 -0700183HB_WASM_API (direction_t, buffer_get_direction) (HB_WASM_EXEC_ENV
184 ptr_d(buffer_t, buffer))
Behdad Esfahbod0a51ed32023-02-24 10:07:59 -0700185{
186 HB_REF2OBJ (buffer);
187
188 return (direction_t) hb_buffer_get_direction (buffer);
189}
190
Behdad Esfahbodec3270c2023-02-24 13:31:10 -0700191HB_WASM_API (script_t, buffer_get_script) (HB_WASM_EXEC_ENV
192 ptr_d(buffer_t, buffer))
193{
194 HB_REF2OBJ (buffer);
195
196 return hb_script_to_iso15924_tag (hb_buffer_get_script (buffer));
197}
198
Behdad Esfahbod39f87032023-02-24 12:42:22 -0700199HB_WASM_API (void, buffer_reverse) (HB_WASM_EXEC_ENV
200 ptr_d(buffer_t, buffer))
Behdad Esfahbodb3b6e8d2023-02-24 12:03:53 -0700201{
202 HB_REF2OBJ (buffer);
203
204 hb_buffer_reverse (buffer);
205}
206
Behdad Esfahbod39f87032023-02-24 12:42:22 -0700207HB_WASM_API (void, buffer_reverse_clusters) (HB_WASM_EXEC_ENV
208 ptr_d(buffer_t, buffer))
Behdad Esfahboda08dbf42023-02-24 10:13:21 -0700209{
210 HB_REF2OBJ (buffer);
211
212 hb_buffer_reverse_clusters (buffer);
213}
Behdad Esfahbod0a51ed32023-02-24 10:07:59 -0700214
Behdad Esfahbod5cecfe82023-02-23 13:58:40 -0700215}}
216
217#endif /* HB_WASM_API_BUFFER_HH */