2 * Copyright © 2012,2013 Google, Inc.
4 * This is part of HarfBuzz, a text shaping library.
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.
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
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.
24 * Google Author(s): Behdad Esfahbod
27 #include "hb-buffer-private.hh"
30 static const char *serialize_formats
[] = {
37 hb_buffer_serialize_list_formats (void)
39 return serialize_formats
;
42 hb_buffer_serialize_format_t
43 hb_buffer_serialize_format_from_string (const char *str
, int len
)
46 return (hb_buffer_serialize_format_t
) (hb_tag_from_string (str
, len
) & ~0x20202020);
50 hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format
)
54 case HB_BUFFER_SERIALIZE_FORMAT_TEXT
: return serialize_formats
[0];
55 case HB_BUFFER_SERIALIZE_FORMAT_JSON
: return serialize_formats
[1];
57 case HB_BUFFER_SERIALIZE_FORMAT_INVALID
: return NULL
;
62 _hb_buffer_serialize_glyphs_json (hb_buffer_t
*buffer
,
66 unsigned int buf_size
,
67 unsigned int *buf_consumed
,
69 hb_buffer_serialize_flags_t flags
)
71 hb_glyph_info_t
*info
= hb_buffer_get_glyph_infos (buffer
, NULL
);
72 hb_glyph_position_t
*pos
= hb_buffer_get_glyph_positions (buffer
, NULL
);
75 for (unsigned int i
= start
; i
< end
; i
++)
80 /* In the following code, we know b is large enough that no overflow can happen. */
82 #define APPEND(s) HB_STMT_START { strcpy (p, s); p += strlen (s); } HB_STMT_END
90 if (!(flags
& HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES
))
93 hb_font_glyph_to_string (font
, info
[i
].codepoint
, g
, sizeof (g
));
95 for (char *q
= g
; *q
; q
++) {
103 p
+= snprintf (p
, ARRAY_LENGTH (b
) - (p
- b
), "%u", info
[i
].codepoint
);
105 if (!(flags
& HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS
)) {
106 p
+= snprintf (p
, ARRAY_LENGTH (b
) - (p
- b
), ",\"cl\":%u", info
[i
].cluster
);
109 if (!(flags
& HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS
))
111 p
+= snprintf (p
, ARRAY_LENGTH (b
) - (p
- b
), ",\"dx\":%d,\"dy\":%d",
112 pos
[i
].x_offset
, pos
[i
].y_offset
);
113 p
+= snprintf (p
, ARRAY_LENGTH (b
) - (p
- b
), ",\"ax\":%d,\"ay\":%d",
114 pos
[i
].x_advance
, pos
[i
].y_advance
);
119 if (buf_size
> (p
- b
))
121 unsigned int l
= p
- b
;
135 _hb_buffer_serialize_glyphs_text (hb_buffer_t
*buffer
,
139 unsigned int buf_size
,
140 unsigned int *buf_consumed
,
142 hb_buffer_serialize_flags_t flags
)
144 hb_glyph_info_t
*info
= hb_buffer_get_glyph_infos (buffer
, NULL
);
145 hb_glyph_position_t
*pos
= hb_buffer_get_glyph_positions (buffer
, NULL
);
148 for (unsigned int i
= start
; i
< end
; i
++)
153 /* In the following code, we know b is large enough that no overflow can happen. */
158 if (!(flags
& HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES
))
160 hb_font_glyph_to_string (font
, info
[i
].codepoint
, p
, 128);
164 p
+= snprintf (p
, ARRAY_LENGTH (b
) - (p
- b
), "%u", info
[i
].codepoint
);
166 if (!(flags
& HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS
)) {
167 p
+= snprintf (p
, ARRAY_LENGTH (b
) - (p
- b
), "=%u", info
[i
].cluster
);
170 if (!(flags
& HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS
))
172 if (pos
[i
].x_offset
|| pos
[i
].y_offset
)
173 p
+= snprintf (p
, ARRAY_LENGTH (b
) - (p
- b
), "@%d,%d", pos
[i
].x_offset
, pos
[i
].y_offset
);
176 p
+= snprintf (p
, ARRAY_LENGTH (b
) - (p
- b
), "%d", pos
[i
].x_advance
);
178 p
+= snprintf (p
, ARRAY_LENGTH (b
) - (p
- b
), ",%d", pos
[i
].y_advance
);
181 if (buf_size
> (p
- b
))
183 unsigned int l
= p
- b
;
196 /* Returns number of items, starting at start, that were serialized. */
198 hb_buffer_serialize_glyphs (hb_buffer_t
*buffer
,
202 unsigned int buf_size
,
203 unsigned int *buf_consumed
, /* May be NULL */
204 hb_font_t
*font
, /* May be NULL */
205 hb_buffer_serialize_format_t format
,
206 hb_buffer_serialize_flags_t flags
)
208 assert (start
<= end
&& end
<= buffer
->len
);
210 unsigned int sconsumed
;
212 buf_consumed
= &sconsumed
;
215 assert ((!buffer
->len
&& buffer
->content_type
== HB_BUFFER_CONTENT_TYPE_INVALID
) ||
216 buffer
->content_type
== HB_BUFFER_CONTENT_TYPE_GLYPHS
);
218 if (unlikely (start
== end
))
222 font
= hb_font_get_empty ();
226 case HB_BUFFER_SERIALIZE_FORMAT_TEXT
:
227 return _hb_buffer_serialize_glyphs_text (buffer
, start
, end
,
228 buf
, buf_size
, buf_consumed
,
231 case HB_BUFFER_SERIALIZE_FORMAT_JSON
:
232 return _hb_buffer_serialize_glyphs_json (buffer
, start
, end
,
233 buf
, buf_size
, buf_consumed
,
237 case HB_BUFFER_SERIALIZE_FORMAT_INVALID
:
245 parse_uint (const char *pp
, const char *end
, uint32_t *pv
)
248 unsigned int len
= MIN (ARRAY_LENGTH (buf
) - 1, (unsigned int) (end
- pp
));
249 strncpy (buf
, pp
, len
);
257 v
= strtol (p
, &pend
, 10);
258 if (errno
|| p
== pend
|| pend
- p
!= end
- pp
)
266 parse_int (const char *pp
, const char *end
, int32_t *pv
)
269 unsigned int len
= MIN (ARRAY_LENGTH (buf
) - 1, (unsigned int) (end
- pp
));
270 strncpy (buf
, pp
, len
);
278 v
= strtol (p
, &pend
, 10);
279 if (errno
|| p
== pend
|| pend
- p
!= end
- pp
)
286 #include "hb-buffer-deserialize-json.hh"
287 #include "hb-buffer-deserialize-text.hh"
290 hb_buffer_deserialize_glyphs (hb_buffer_t
*buffer
,
292 int buf_len
, /* -1 means nul-terminated */
293 const char **end_ptr
, /* May be NULL */
294 hb_font_t
*font
, /* May be NULL */
295 hb_buffer_serialize_format_t format
)
302 assert ((!buffer
->len
&& buffer
->content_type
== HB_BUFFER_CONTENT_TYPE_INVALID
) ||
303 buffer
->content_type
== HB_BUFFER_CONTENT_TYPE_GLYPHS
);
306 buf_len
= strlen (buf
);
314 hb_buffer_set_content_type (buffer
, HB_BUFFER_CONTENT_TYPE_GLYPHS
);
317 font
= hb_font_get_empty ();
321 case HB_BUFFER_SERIALIZE_FORMAT_TEXT
:
322 return _hb_buffer_deserialize_glyphs_text (buffer
,
323 buf
, buf_len
, end_ptr
,
326 case HB_BUFFER_SERIALIZE_FORMAT_JSON
:
327 return _hb_buffer_deserialize_glyphs_json (buffer
,
328 buf
, buf_len
, end_ptr
,
332 case HB_BUFFER_SERIALIZE_FORMAT_INVALID
: