Path: blob/master/src/java.desktop/share/native/libharfbuzz/hb-buffer-serialize.cc
41152 views
/*1* Copyright © 2012,2013 Google, Inc.2*3* This is part of HarfBuzz, a text shaping library.4*5* Permission is hereby granted, without written agreement and without6* license or royalty fees, to use, copy, modify, and distribute this7* software and its documentation for any purpose, provided that the8* above copyright notice and the following two paragraphs appear in9* all copies of this software.10*11* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR12* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES13* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN14* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH15* DAMAGE.16*17* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,18* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND19* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS20* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO21* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.22*23* Google Author(s): Behdad Esfahbod24*/2526#include "hb.hh"2728#ifndef HB_NO_BUFFER_SERIALIZE2930#include "hb-buffer.hh"313233static const char *serialize_formats[] = {34"text",35"json",36nullptr37};3839/**40* hb_buffer_serialize_list_formats:41*42* Returns a list of supported buffer serialization formats.43*44* Return value: (transfer none):45* A string array of buffer serialization formats. Should not be freed.46*47* Since: 0.9.748**/49const char **50hb_buffer_serialize_list_formats ()51{52return serialize_formats;53}5455/**56* hb_buffer_serialize_format_from_string:57* @str: (array length=len) (element-type uint8_t): a string to parse58* @len: length of @str, or -1 if string is %NULL terminated59*60* Parses a string into an #hb_buffer_serialize_format_t. Does not check if61* @str is a valid buffer serialization format, use62* hb_buffer_serialize_list_formats() to get the list of supported formats.63*64* Return value:65* The parsed #hb_buffer_serialize_format_t.66*67* Since: 0.9.768**/69hb_buffer_serialize_format_t70hb_buffer_serialize_format_from_string (const char *str, int len)71{72/* Upper-case it. */73return (hb_buffer_serialize_format_t) (hb_tag_from_string (str, len) & ~0x20202020u);74}7576/**77* hb_buffer_serialize_format_to_string:78* @format: an #hb_buffer_serialize_format_t to convert.79*80* Converts @format to the string corresponding it, or %NULL if it is not a valid81* #hb_buffer_serialize_format_t.82*83* Return value: (transfer none):84* A %NULL terminated string corresponding to @format. Should not be freed.85*86* Since: 0.9.787**/88const char *89hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format)90{91switch ((unsigned) format)92{93case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0];94case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1];95default:96case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return nullptr;97}98}99100static unsigned int101_hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,102unsigned int start,103unsigned int end,104char *buf,105unsigned int buf_size,106unsigned int *buf_consumed,107hb_font_t *font,108hb_buffer_serialize_flags_t flags)109{110hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);111hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ?112nullptr : hb_buffer_get_glyph_positions (buffer, nullptr);113114*buf_consumed = 0;115hb_position_t x = 0, y = 0;116for (unsigned int i = start; i < end; i++)117{118char b[1024];119char *p = b;120121/* In the following code, we know b is large enough that no overflow can happen. */122123#define APPEND(s) HB_STMT_START { strcpy (p, s); p += strlen (s); } HB_STMT_END124125if (i)126*p++ = ',';127else128*p++ = '[';129130*p++ = '{';131132APPEND ("\"g\":");133if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES))134{135char g[128];136hb_font_glyph_to_string (font, info[i].codepoint, g, sizeof (g));137*p++ = '"';138for (char *q = g; *q; q++)139{140if (unlikely (*q == '"' || *q == '\\'))141*p++ = '\\';142*p++ = *q;143}144*p++ = '"';145}146else147p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));148149if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {150p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster));151}152153if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))154{155p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d",156x+pos[i].x_offset, y+pos[i].y_offset));157if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))158p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d",159pos[i].x_advance, pos[i].y_advance));160}161162if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS)163{164if (info[i].mask & HB_GLYPH_FLAG_DEFINED)165p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"fl\":%u", info[i].mask & HB_GLYPH_FLAG_DEFINED));166}167168if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS)169{170hb_glyph_extents_t extents;171hb_font_get_glyph_extents(font, info[i].codepoint, &extents);172p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d",173extents.x_bearing, extents.y_bearing));174p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d",175extents.width, extents.height));176}177178*p++ = '}';179if (i == end-1)180*p++ = ']';181182unsigned int l = p - b;183if (buf_size > l)184{185memcpy (buf, b, l);186buf += l;187buf_size -= l;188*buf_consumed += l;189*buf = '\0';190} else191return i - start;192193if (pos && (flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))194{195x += pos[i].x_advance;196y += pos[i].y_advance;197}198}199200return end - start;201}202203static unsigned int204_hb_buffer_serialize_unicode_json (hb_buffer_t *buffer,205unsigned int start,206unsigned int end,207char *buf,208unsigned int buf_size,209unsigned int *buf_consumed,210hb_buffer_serialize_flags_t flags)211{212hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);213214*buf_consumed = 0;215for (unsigned int i = start; i < end; i++)216{217char b[1024];218char *p = b;219220if (i)221*p++ = ',';222else223*p++ = '[';224225*p++ = '{';226227APPEND ("\"u\":");228229p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));230231if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {232p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster));233}234235*p++ = '}';236237if (i == end-1)238*p++ = ']';239240unsigned int l = p - b;241if (buf_size > l)242{243memcpy (buf, b, l);244buf += l;245buf_size -= l;246*buf_consumed += l;247*buf = '\0';248} else249return i - start;250251}252253return end - start;254}255256static unsigned int257_hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,258unsigned int start,259unsigned int end,260char *buf,261unsigned int buf_size,262unsigned int *buf_consumed,263hb_font_t *font,264hb_buffer_serialize_flags_t flags)265{266hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);267hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ?268nullptr : hb_buffer_get_glyph_positions (buffer, nullptr);269270*buf_consumed = 0;271hb_position_t x = 0, y = 0;272for (unsigned int i = start; i < end; i++)273{274char b[1024];275char *p = b;276277/* In the following code, we know b is large enough that no overflow can happen. */278279if (i)280*p++ = '|';281else282*p++ = '[';283284if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES))285{286/* TODO Escape delimiters we use. */287hb_font_glyph_to_string (font, info[i].codepoint, p, 128);288p += strlen (p);289}290else291p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));292293if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {294p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster));295}296297if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))298{299if (x+pos[i].x_offset || y+pos[i].y_offset)300p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", x+pos[i].x_offset, y+pos[i].y_offset));301302if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))303{304*p++ = '+';305p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance));306if (pos[i].y_advance)307p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance));308}309}310311if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS)312{313if (info[i].mask & HB_GLYPH_FLAG_DEFINED)314p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "#%X", info[i].mask &HB_GLYPH_FLAG_DEFINED));315}316317if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS)318{319hb_glyph_extents_t extents;320hb_font_get_glyph_extents(font, info[i].codepoint, &extents);321p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height));322}323324if (i == end-1) {325*p++ = ']';326}327328unsigned int l = p - b;329if (buf_size > l)330{331memcpy (buf, b, l);332buf += l;333buf_size -= l;334*buf_consumed += l;335*buf = '\0';336} else337return i - start;338339if (pos && (flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))340{341x += pos[i].x_advance;342y += pos[i].y_advance;343}344}345346return end - start;347}348349350static unsigned int351_hb_buffer_serialize_unicode_text (hb_buffer_t *buffer,352unsigned int start,353unsigned int end,354char *buf,355unsigned int buf_size,356unsigned int *buf_consumed,357hb_buffer_serialize_flags_t flags)358{359hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);360*buf_consumed = 0;361for (unsigned int i = start; i < end; i++)362{363char b[1024];364char *p = b;365366if (i)367*p++ = '|';368else369*p++ = '<';370371p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "U+%04X", info[i].codepoint));372373if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {374p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster));375}376377if (i == end-1)378*p++ = '>';379380unsigned int l = p - b;381if (buf_size > l)382{383memcpy (buf, b, l);384buf += l;385buf_size -= l;386*buf_consumed += l;387*buf = '\0';388} else389return i - start;390}391return end - start;392}393394/**395* hb_buffer_serialize_glyphs:396* @buffer: an #hb_buffer_t buffer.397* @start: the first item in @buffer to serialize.398* @end: the last item in @buffer to serialize.399* @buf: (out) (array length=buf_size) (element-type uint8_t): output string to400* write serialized buffer into.401* @buf_size: the size of @buf.402* @buf_consumed: (out) (optional): if not %NULL, will be set to the number of byes written into @buf.403* @font: (nullable): the #hb_font_t used to shape this buffer, needed to404* read glyph names and extents. If %NULL, and empty font will be used.405* @format: the #hb_buffer_serialize_format_t to use for formatting the output.406* @flags: the #hb_buffer_serialize_flags_t that control what glyph properties407* to serialize.408*409* Serializes @buffer into a textual representation of its glyph content,410* useful for showing the contents of the buffer, for example during debugging.411* There are currently two supported serialization formats:412*413* ## text414* A human-readable, plain text format.415* The serialized glyphs will look something like:416*417* ```418* [uni0651=0@518,0+0|uni0628=0+1897]419* ```420*421* - The serialized glyphs are delimited with `[` and `]`.422* - Glyphs are separated with `|`423* - Each glyph starts with glyph name, or glyph index if424* #HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES flag is set. Then,425* - If #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set, `=` then #hb_glyph_info_t.cluster.426* - If #HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS is not set, the #hb_glyph_position_t in the format:427* - If both #hb_glyph_position_t.x_offset and #hb_glyph_position_t.y_offset are not 0, `@x_offset,y_offset`. Then,428* - `+x_advance`, then `,y_advance` if #hb_glyph_position_t.y_advance is not 0. Then,429* - If #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set, the #hb_glyph_extents_t in the format `<x_bearing,y_bearing,width,height>`430*431* ## json432* A machine-readable, structured format.433* The serialized glyphs will look something like:434*435* ```436* [{"g":"uni0651","cl":0,"dx":518,"dy":0,"ax":0,"ay":0},437* {"g":"uni0628","cl":0,"dx":0,"dy":0,"ax":1897,"ay":0}]438* ```439*440* Each glyph is a JSON object, with the following properties:441* - `g`: the glyph name or glyph index if442* #HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES flag is set.443* - `cl`: #hb_glyph_info_t.cluster if444* #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set.445* - `dx`,`dy`,`ax`,`ay`: #hb_glyph_position_t.x_offset, #hb_glyph_position_t.y_offset,446* #hb_glyph_position_t.x_advance and #hb_glyph_position_t.y_advance447* respectively, if #HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS is not set.448* - `xb`,`yb`,`w`,`h`: #hb_glyph_extents_t.x_bearing, #hb_glyph_extents_t.y_bearing,449* #hb_glyph_extents_t.width and #hb_glyph_extents_t.height respectively if450* #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set.451*452* Return value:453* The number of serialized items.454*455* Since: 0.9.7456**/457unsigned int458hb_buffer_serialize_glyphs (hb_buffer_t *buffer,459unsigned int start,460unsigned int end,461char *buf,462unsigned int buf_size,463unsigned int *buf_consumed,464hb_font_t *font,465hb_buffer_serialize_format_t format,466hb_buffer_serialize_flags_t flags)467{468end = hb_clamp (end, start, buffer->len);469start = hb_min (start, end);470471unsigned int sconsumed;472if (!buf_consumed)473buf_consumed = &sconsumed;474*buf_consumed = 0;475if (buf_size)476*buf = '\0';477478buffer->assert_glyphs ();479480if (!buffer->have_positions)481flags |= HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS;482483if (unlikely (start == end))484return 0;485486if (!font)487font = hb_font_get_empty ();488489switch (format)490{491case HB_BUFFER_SERIALIZE_FORMAT_TEXT:492return _hb_buffer_serialize_glyphs_text (buffer, start, end,493buf, buf_size, buf_consumed,494font, flags);495496case HB_BUFFER_SERIALIZE_FORMAT_JSON:497return _hb_buffer_serialize_glyphs_json (buffer, start, end,498buf, buf_size, buf_consumed,499font, flags);500501default:502case HB_BUFFER_SERIALIZE_FORMAT_INVALID:503return 0;504505}506}507508/**509* hb_buffer_serialize_unicode:510* @buffer: an #hb_buffer_t buffer.511* @start: the first item in @buffer to serialize.512* @end: the last item in @buffer to serialize.513* @buf: (out) (array length=buf_size) (element-type uint8_t): output string to514* write serialized buffer into.515* @buf_size: the size of @buf.516* @buf_consumed: (out) (optional): if not %NULL, will be set to the number of byes written into @buf.517* @format: the #hb_buffer_serialize_format_t to use for formatting the output.518* @flags: the #hb_buffer_serialize_flags_t that control what glyph properties519* to serialize.520*521* Serializes @buffer into a textual representation of its content,522* when the buffer contains Unicode codepoints (i.e., before shaping). This is523* useful for showing the contents of the buffer, for example during debugging.524* There are currently two supported serialization formats:525*526* ## text527* A human-readable, plain text format.528* The serialized codepoints will look something like:529*530* ```531* <U+0651=0|U+0628=1>532* ```533*534* - Glyphs are separated with `|`535* - Unicode codepoints are expressed as zero-padded four (or more)536* digit hexadecimal numbers preceded by `U+`537* - If #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set, the cluster538* will be indicated with a `=` then #hb_glyph_info_t.cluster.539*540* ## json541* A machine-readable, structured format.542* The serialized codepoints will be a list of objects with the following543* properties:544* - `u`: the Unicode codepoint as a decimal integer545* - `cl`: #hb_glyph_info_t.cluster if546* #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set.547*548* For example:549*550* ```551* [{u:1617,cl:0},{u:1576,cl:1}]552* ```553*554* Return value:555* The number of serialized items.556*557* Since: 2.7.3558**/559unsigned int560hb_buffer_serialize_unicode (hb_buffer_t *buffer,561unsigned int start,562unsigned int end,563char *buf,564unsigned int buf_size,565unsigned int *buf_consumed,566hb_buffer_serialize_format_t format,567hb_buffer_serialize_flags_t flags)568{569end = hb_clamp (end, start, buffer->len);570start = hb_min (start, end);571572unsigned int sconsumed;573if (!buf_consumed)574buf_consumed = &sconsumed;575*buf_consumed = 0;576if (buf_size)577*buf = '\0';578579buffer->assert_unicode ();580581if (unlikely (start == end))582return 0;583584switch (format)585{586case HB_BUFFER_SERIALIZE_FORMAT_TEXT:587return _hb_buffer_serialize_unicode_text (buffer, start, end,588buf, buf_size, buf_consumed, flags);589590case HB_BUFFER_SERIALIZE_FORMAT_JSON:591return _hb_buffer_serialize_unicode_json (buffer, start, end,592buf, buf_size, buf_consumed, flags);593594default:595case HB_BUFFER_SERIALIZE_FORMAT_INVALID:596return 0;597598}599}600601static unsigned int602_hb_buffer_serialize_invalid (hb_buffer_t *buffer,603unsigned int start,604unsigned int end,605char *buf,606unsigned int buf_size,607unsigned int *buf_consumed,608hb_buffer_serialize_format_t format,609hb_buffer_serialize_flags_t flags)610{611assert (!buffer->len);612613unsigned int sconsumed;614if (!buf_consumed)615buf_consumed = &sconsumed;616if (buf_size < 3)617return 0;618if (format == HB_BUFFER_SERIALIZE_FORMAT_JSON) {619*buf++ = '[';620*buf++ = ']';621*buf = '\0';622} else if (format == HB_BUFFER_SERIALIZE_FORMAT_TEXT) {623*buf++ = '!';624*buf++ = '!';625*buf = '\0';626}627*buf_consumed = 2;628return 0;629}630631/**632* hb_buffer_serialize:633* @buffer: an #hb_buffer_t buffer.634* @start: the first item in @buffer to serialize.635* @end: the last item in @buffer to serialize.636* @buf: (out) (array length=buf_size) (element-type uint8_t): output string to637* write serialized buffer into.638* @buf_size: the size of @buf.639* @buf_consumed: (out) (optional): if not %NULL, will be set to the number of byes written into @buf.640* @font: (nullable): the #hb_font_t used to shape this buffer, needed to641* read glyph names and extents. If %NULL, and empty font will be used.642* @format: the #hb_buffer_serialize_format_t to use for formatting the output.643* @flags: the #hb_buffer_serialize_flags_t that control what glyph properties644* to serialize.645*646* Serializes @buffer into a textual representation of its content, whether647* Unicode codepoints or glyph identifiers and positioning information. This is648* useful for showing the contents of the buffer, for example during debugging.649* See the documentation of hb_buffer_serialize_unicode() and650* hb_buffer_serialize_glyphs() for a description of the output format.651*652* Return value:653* The number of serialized items.654*655* Since: 2.7.3656**/657unsigned int658hb_buffer_serialize (hb_buffer_t *buffer,659unsigned int start,660unsigned int end,661char *buf,662unsigned int buf_size,663unsigned int *buf_consumed,664hb_font_t *font,665hb_buffer_serialize_format_t format,666hb_buffer_serialize_flags_t flags)667{668switch (buffer->content_type)669{670671case HB_BUFFER_CONTENT_TYPE_GLYPHS:672return hb_buffer_serialize_glyphs (buffer, start, end, buf, buf_size,673buf_consumed, font, format, flags);674675case HB_BUFFER_CONTENT_TYPE_UNICODE:676return hb_buffer_serialize_unicode (buffer, start, end, buf, buf_size,677buf_consumed, format, flags);678679case HB_BUFFER_CONTENT_TYPE_INVALID:680default:681return _hb_buffer_serialize_invalid (buffer, start, end, buf, buf_size,682buf_consumed, format, flags);683}684}685686static bool687parse_int (const char *pp, const char *end, int32_t *pv)688{689int v;690const char *p = pp;691if (unlikely (!hb_parse_int (&p, end, &v, true/* whole buffer */)))692return false;693694*pv = v;695return true;696}697698static bool699parse_uint (const char *pp, const char *end, uint32_t *pv)700{701unsigned int v;702const char *p = pp;703if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */)))704return false;705706*pv = v;707return true;708}709710static bool711parse_hex (const char *pp, const char *end, uint32_t *pv)712{713unsigned int v;714const char *p = pp;715if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */, 16)))716return false;717718*pv = v;719return true;720}721722#include "hb-buffer-deserialize-json.hh"723#include "hb-buffer-deserialize-text.hh"724725/**726* hb_buffer_deserialize_glyphs:727* @buffer: an #hb_buffer_t buffer.728* @buf: (array length=buf_len): string to deserialize729* @buf_len: the size of @buf, or -1 if it is %NULL-terminated730* @end_ptr: (out) (optional): output pointer to the character after last731* consumed one.732* @font: (nullable): font for getting glyph IDs733* @format: the #hb_buffer_serialize_format_t of the input @buf734*735* Deserializes glyphs @buffer from textual representation in the format736* produced by hb_buffer_serialize_glyphs().737*738* Return value: %true if @buf is not fully consumed, %false otherwise.739*740* Since: 0.9.7741**/742hb_bool_t743hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,744const char *buf,745int buf_len, /* -1 means nul-terminated */746const char **end_ptr, /* May be NULL */747hb_font_t *font, /* May be NULL */748hb_buffer_serialize_format_t format)749{750const char *end;751if (!end_ptr)752end_ptr = &end;753*end_ptr = buf;754755buffer->assert_glyphs ();756757if (unlikely (hb_object_is_immutable (buffer)))758{759if (end_ptr)760*end_ptr = buf;761return false;762}763764if (buf_len == -1)765buf_len = strlen (buf);766767if (!buf_len)768{769*end_ptr = buf;770return false;771}772773hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_GLYPHS);774775if (!font)776font = hb_font_get_empty ();777778switch (format)779{780case HB_BUFFER_SERIALIZE_FORMAT_TEXT:781return _hb_buffer_deserialize_text (buffer,782buf, buf_len, end_ptr,783font);784785case HB_BUFFER_SERIALIZE_FORMAT_JSON:786return _hb_buffer_deserialize_json (buffer,787buf, buf_len, end_ptr,788font);789790default:791case HB_BUFFER_SERIALIZE_FORMAT_INVALID:792return false;793794}795}796797798/**799* hb_buffer_deserialize_unicode:800* @buffer: an #hb_buffer_t buffer.801* @buf: (array length=buf_len): string to deserialize802* @buf_len: the size of @buf, or -1 if it is %NULL-terminated803* @end_ptr: (out) (optional): output pointer to the character after last804* consumed one.805* @format: the #hb_buffer_serialize_format_t of the input @buf806*807* Deserializes Unicode @buffer from textual representation in the format808* produced by hb_buffer_serialize_unicode().809*810* Return value: %true if @buf is not fully consumed, %false otherwise.811*812* Since: 2.7.3813**/814hb_bool_t815hb_buffer_deserialize_unicode (hb_buffer_t *buffer,816const char *buf,817int buf_len, /* -1 means nul-terminated */818const char **end_ptr, /* May be NULL */819hb_buffer_serialize_format_t format)820{821const char *end;822if (!end_ptr)823end_ptr = &end;824*end_ptr = buf;825826buffer->assert_unicode ();827828if (unlikely (hb_object_is_immutable (buffer)))829{830if (end_ptr)831*end_ptr = buf;832return false;833}834835if (buf_len == -1)836buf_len = strlen (buf);837838if (!buf_len)839{840*end_ptr = buf;841return false;842}843844hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_UNICODE);845846hb_font_t* font = hb_font_get_empty ();847848switch (format)849{850case HB_BUFFER_SERIALIZE_FORMAT_TEXT:851return _hb_buffer_deserialize_text (buffer,852buf, buf_len, end_ptr,853font);854855case HB_BUFFER_SERIALIZE_FORMAT_JSON:856return _hb_buffer_deserialize_json (buffer,857buf, buf_len, end_ptr,858font);859860default:861case HB_BUFFER_SERIALIZE_FORMAT_INVALID:862return false;863864}865}866867868#endif869870871