Path: blob/master/thirdparty/harfbuzz/src/hb-buffer-serialize.cc
9913 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 *_hb_buffer_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 _hb_buffer_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 _hb_buffer_serialize_formats[0];94case HB_BUFFER_SERIALIZE_FORMAT_JSON: return _hb_buffer_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;171if (hb_font_get_glyph_extents(font, info[i].codepoint, &extents))172{173p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d",174extents.x_bearing, extents.y_bearing));175p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d",176extents.width, extents.height));177}178}179180*p++ = '}';181if (i == end-1)182*p++ = ']';183184unsigned int l = p - b;185if (buf_size > l)186{187hb_memcpy (buf, b, l);188buf += l;189buf_size -= l;190*buf_consumed += l;191*buf = '\0';192} else193return i - start;194195if (pos && (flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))196{197x += pos[i].x_advance;198y += pos[i].y_advance;199}200}201202return end - start;203}204205static unsigned int206_hb_buffer_serialize_unicode_json (hb_buffer_t *buffer,207unsigned int start,208unsigned int end,209char *buf,210unsigned int buf_size,211unsigned int *buf_consumed,212hb_buffer_serialize_flags_t flags)213{214hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);215216*buf_consumed = 0;217for (unsigned int i = start; i < end; i++)218{219char b[1024];220char *p = b;221222if (i)223*p++ = ',';224else225*p++ = '[';226227*p++ = '{';228229APPEND ("\"u\":");230231p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));232233if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {234p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster));235}236237*p++ = '}';238239if (i == end-1)240*p++ = ']';241242unsigned int l = p - b;243if (buf_size > l)244{245hb_memcpy (buf, b, l);246buf += l;247buf_size -= l;248*buf_consumed += l;249*buf = '\0';250} else251return i - start;252253}254255return end - start;256}257258static unsigned int259_hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,260unsigned int start,261unsigned int end,262char *buf,263unsigned int buf_size,264unsigned int *buf_consumed,265hb_font_t *font,266hb_buffer_serialize_flags_t flags)267{268hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);269hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ?270nullptr : hb_buffer_get_glyph_positions (buffer, nullptr);271272*buf_consumed = 0;273hb_position_t x = 0, y = 0;274for (unsigned int i = start; i < end; i++)275{276char b[1024];277char *p = b;278279/* In the following code, we know b is large enough that no overflow can happen. */280281if (i)282*p++ = '|';283else284*p++ = '[';285286if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES))287{288/* TODO Escape delimiters we use. */289hb_font_glyph_to_string (font, info[i].codepoint, p, 128);290p += strlen (p);291}292else293p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));294295if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {296p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster));297}298299if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))300{301if (x+pos[i].x_offset || y+pos[i].y_offset)302p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", x+pos[i].x_offset, y+pos[i].y_offset));303304if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))305{306*p++ = '+';307p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance));308if (pos[i].y_advance)309p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance));310}311}312313if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS)314{315if (info[i].mask & HB_GLYPH_FLAG_DEFINED)316p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "#%X", info[i].mask &HB_GLYPH_FLAG_DEFINED));317}318319if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS)320{321hb_glyph_extents_t extents;322if (hb_font_get_glyph_extents(font, info[i].codepoint, &extents))323p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height));324}325326if (i == end-1) {327*p++ = ']';328}329330unsigned int l = p - b;331if (buf_size > l)332{333hb_memcpy (buf, b, l);334buf += l;335buf_size -= l;336*buf_consumed += l;337*buf = '\0';338} else339return i - start;340341if (pos && (flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))342{343x += pos[i].x_advance;344y += pos[i].y_advance;345}346}347348return end - start;349}350351352static unsigned int353_hb_buffer_serialize_unicode_text (hb_buffer_t *buffer,354unsigned int start,355unsigned int end,356char *buf,357unsigned int buf_size,358unsigned int *buf_consumed,359hb_buffer_serialize_flags_t flags)360{361hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);362*buf_consumed = 0;363for (unsigned int i = start; i < end; i++)364{365char b[1024];366char *p = b;367368if (i)369*p++ = '|';370else371*p++ = '<';372373p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "U+%04X", info[i].codepoint));374375if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {376p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster));377}378379if (i == end-1)380*p++ = '>';381382unsigned int l = p - b;383if (buf_size > l)384{385hb_memcpy (buf, b, l);386buf += l;387buf_size -= l;388*buf_consumed += l;389*buf = '\0';390} else391return i - start;392}393return end - start;394}395396/**397* hb_buffer_serialize_glyphs:398* @buffer: an #hb_buffer_t buffer.399* @start: the first item in @buffer to serialize.400* @end: the last item in @buffer to serialize.401* @buf: (out) (array length=buf_size) (element-type uint8_t): output string to402* write serialized buffer into.403* @buf_size: the size of @buf.404* @buf_consumed: (out) (optional): if not `NULL`, will be set to the number of bytes written into @buf.405* @font: (nullable): the #hb_font_t used to shape this buffer, needed to406* read glyph names and extents. If `NULL`, an empty font will be used.407* @format: the #hb_buffer_serialize_format_t to use for formatting the output.408* @flags: the #hb_buffer_serialize_flags_t that control what glyph properties409* to serialize.410*411* Serializes @buffer into a textual representation of its glyph content,412* useful for showing the contents of the buffer, for example during debugging.413* There are currently two supported serialization formats:414*415* ## text416* A human-readable, plain text format.417* The serialized glyphs will look something like:418*419* ```420* [uni0651=0@518,0+0|uni0628=0+1897]421* ```422*423* - The serialized glyphs are delimited with `[` and `]`.424* - Glyphs are separated with `|`425* - Each glyph starts with glyph name, or glyph index if426* #HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES flag is set. Then,427* - If #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set, `=` then #hb_glyph_info_t.cluster.428* - If #HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS is not set, the #hb_glyph_position_t in the format:429* - If both #hb_glyph_position_t.x_offset and #hb_glyph_position_t.y_offset are not 0, `@x_offset,y_offset`. Then,430* - `+x_advance`, then `,y_advance` if #hb_glyph_position_t.y_advance is not 0. Then,431* - If #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set, the #hb_glyph_extents_t in the format `<x_bearing,y_bearing,width,height>`432*433* ## json434* A machine-readable, structured format.435* The serialized glyphs will look something like:436*437* ```438* [{"g":"uni0651","cl":0,"dx":518,"dy":0,"ax":0,"ay":0},439* {"g":"uni0628","cl":0,"dx":0,"dy":0,"ax":1897,"ay":0}]440* ```441*442* Each glyph is a JSON object, with the following properties:443* - `g`: the glyph name or glyph index if444* #HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES flag is set.445* - `cl`: #hb_glyph_info_t.cluster if446* #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set.447* - `dx`,`dy`,`ax`,`ay`: #hb_glyph_position_t.x_offset, #hb_glyph_position_t.y_offset,448* #hb_glyph_position_t.x_advance and #hb_glyph_position_t.y_advance449* respectively, if #HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS is not set.450* - `xb`,`yb`,`w`,`h`: #hb_glyph_extents_t.x_bearing, #hb_glyph_extents_t.y_bearing,451* #hb_glyph_extents_t.width and #hb_glyph_extents_t.height respectively if452* #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set.453*454* Return value:455* The number of serialized items.456*457* Since: 0.9.7458**/459unsigned int460hb_buffer_serialize_glyphs (hb_buffer_t *buffer,461unsigned int start,462unsigned int end,463char *buf,464unsigned int buf_size,465unsigned int *buf_consumed,466hb_font_t *font,467hb_buffer_serialize_format_t format,468hb_buffer_serialize_flags_t flags)469{470end = hb_clamp (end, start, buffer->len);471start = hb_min (start, end);472473unsigned int sconsumed;474if (!buf_consumed)475buf_consumed = &sconsumed;476*buf_consumed = 0;477if (buf_size)478*buf = '\0';479480buffer->assert_glyphs ();481482if (!buffer->have_positions)483flags |= HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS;484485if (unlikely (start == end))486return 0;487488if (!font)489font = hb_font_get_empty ();490491switch (format)492{493case HB_BUFFER_SERIALIZE_FORMAT_TEXT:494return _hb_buffer_serialize_glyphs_text (buffer, start, end,495buf, buf_size, buf_consumed,496font, flags);497498case HB_BUFFER_SERIALIZE_FORMAT_JSON:499return _hb_buffer_serialize_glyphs_json (buffer, start, end,500buf, buf_size, buf_consumed,501font, flags);502503default:504case HB_BUFFER_SERIALIZE_FORMAT_INVALID:505return 0;506507}508}509510/**511* hb_buffer_serialize_unicode:512* @buffer: an #hb_buffer_t buffer.513* @start: the first item in @buffer to serialize.514* @end: the last item in @buffer to serialize.515* @buf: (out) (array length=buf_size) (element-type uint8_t): output string to516* write serialized buffer into.517* @buf_size: the size of @buf.518* @buf_consumed: (out) (optional): if not `NULL`, will be set to the number of bytes written into @buf.519* @format: the #hb_buffer_serialize_format_t to use for formatting the output.520* @flags: the #hb_buffer_serialize_flags_t that control what glyph properties521* to serialize.522*523* Serializes @buffer into a textual representation of its content,524* when the buffer contains Unicode codepoints (i.e., before shaping). This is525* useful for showing the contents of the buffer, for example during debugging.526* There are currently two supported serialization formats:527*528* ## text529* A human-readable, plain text format.530* The serialized codepoints will look something like:531*532* ```533* <U+0651=0|U+0628=1>534* ```535*536* - Glyphs are separated with `|`537* - Unicode codepoints are expressed as zero-padded four (or more)538* digit hexadecimal numbers preceded by `U+`539* - If #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set, the cluster540* will be indicated with a `=` then #hb_glyph_info_t.cluster.541*542* ## json543* A machine-readable, structured format.544* The serialized codepoints will be a list of objects with the following545* properties:546* - `u`: the Unicode codepoint as a decimal integer547* - `cl`: #hb_glyph_info_t.cluster if548* #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set.549*550* For example:551*552* ```553* [{u:1617,cl:0},{u:1576,cl:1}]554* ```555*556* Return value:557* The number of serialized items.558*559* Since: 2.7.3560**/561unsigned int562hb_buffer_serialize_unicode (hb_buffer_t *buffer,563unsigned int start,564unsigned int end,565char *buf,566unsigned int buf_size,567unsigned int *buf_consumed,568hb_buffer_serialize_format_t format,569hb_buffer_serialize_flags_t flags)570{571end = hb_clamp (end, start, buffer->len);572start = hb_min (start, end);573574unsigned int sconsumed;575if (!buf_consumed)576buf_consumed = &sconsumed;577*buf_consumed = 0;578if (buf_size)579*buf = '\0';580581buffer->assert_unicode ();582583if (unlikely (start == end))584return 0;585586switch (format)587{588case HB_BUFFER_SERIALIZE_FORMAT_TEXT:589return _hb_buffer_serialize_unicode_text (buffer, start, end,590buf, buf_size, buf_consumed, flags);591592case HB_BUFFER_SERIALIZE_FORMAT_JSON:593return _hb_buffer_serialize_unicode_json (buffer, start, end,594buf, buf_size, buf_consumed, flags);595596default:597case HB_BUFFER_SERIALIZE_FORMAT_INVALID:598return 0;599600}601}602603static unsigned int604_hb_buffer_serialize_invalid (hb_buffer_t *buffer,605unsigned int start,606unsigned int end,607char *buf,608unsigned int buf_size,609unsigned int *buf_consumed,610hb_buffer_serialize_format_t format,611hb_buffer_serialize_flags_t flags)612{613assert (!buffer->len);614615unsigned int sconsumed;616if (!buf_consumed)617buf_consumed = &sconsumed;618if (buf_size < 3)619return 0;620if (format == HB_BUFFER_SERIALIZE_FORMAT_JSON) {621*buf++ = '[';622*buf++ = ']';623*buf = '\0';624} else if (format == HB_BUFFER_SERIALIZE_FORMAT_TEXT) {625*buf++ = '!';626*buf++ = '!';627*buf = '\0';628}629*buf_consumed = 2;630return 0;631}632633/**634* hb_buffer_serialize:635* @buffer: an #hb_buffer_t buffer.636* @start: the first item in @buffer to serialize.637* @end: the last item in @buffer to serialize.638* @buf: (out) (array length=buf_size) (element-type uint8_t): output string to639* write serialized buffer into.640* @buf_size: the size of @buf.641* @buf_consumed: (out) (optional): if not `NULL`, will be set to the number of bytes written into @buf.642* @font: (nullable): the #hb_font_t used to shape this buffer, needed to643* read glyph names and extents. If `NULL`, an empty font will be used.644* @format: the #hb_buffer_serialize_format_t to use for formatting the output.645* @flags: the #hb_buffer_serialize_flags_t that control what glyph properties646* to serialize.647*648* Serializes @buffer into a textual representation of its content, whether649* Unicode codepoints or glyph identifiers and positioning information. This is650* useful for showing the contents of the buffer, for example during debugging.651* See the documentation of hb_buffer_serialize_unicode() and652* hb_buffer_serialize_glyphs() for a description of the output format.653*654* Return value:655* The number of serialized items.656*657* Since: 2.7.3658**/659unsigned int660hb_buffer_serialize (hb_buffer_t *buffer,661unsigned int start,662unsigned int end,663char *buf,664unsigned int buf_size,665unsigned int *buf_consumed,666hb_font_t *font,667hb_buffer_serialize_format_t format,668hb_buffer_serialize_flags_t flags)669{670switch (buffer->content_type)671{672673case HB_BUFFER_CONTENT_TYPE_GLYPHS:674return hb_buffer_serialize_glyphs (buffer, start, end, buf, buf_size,675buf_consumed, font, format, flags);676677case HB_BUFFER_CONTENT_TYPE_UNICODE:678return hb_buffer_serialize_unicode (buffer, start, end, buf, buf_size,679buf_consumed, format, flags);680681case HB_BUFFER_CONTENT_TYPE_INVALID:682default:683return _hb_buffer_serialize_invalid (buffer, start, end, buf, buf_size,684buf_consumed, format, flags);685}686}687688static bool689parse_int (const char *pp, const char *end, int32_t *pv)690{691int v;692const char *p = pp;693if (unlikely (!hb_parse_int (&p, end, &v, true/* whole buffer */)))694return false;695696*pv = v;697return true;698}699700static bool701parse_uint (const char *pp, const char *end, uint32_t *pv)702{703unsigned int v;704const char *p = pp;705if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */)))706return false;707708*pv = v;709return true;710}711712static bool713parse_hex (const char *pp, const char *end, uint32_t *pv)714{715unsigned int v;716const char *p = pp;717if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */, 16)))718return false;719720*pv = v;721return true;722}723724#include "hb-buffer-deserialize-json.hh"725#include "hb-buffer-deserialize-text-glyphs.hh"726#include "hb-buffer-deserialize-text-unicode.hh"727728/**729* hb_buffer_deserialize_glyphs:730* @buffer: an #hb_buffer_t buffer.731* @buf: (array length=buf_len): string to deserialize732* @buf_len: the size of @buf, or -1 if it is `NULL`-terminated733* @end_ptr: (out) (optional): output pointer to the character after last734* consumed one.735* @font: (nullable): font for getting glyph IDs736* @format: the #hb_buffer_serialize_format_t of the input @buf737*738* Deserializes glyphs @buffer from textual representation in the format739* produced by hb_buffer_serialize_glyphs().740*741* Return value: `true` if the full string was parsed, `false` otherwise.742*743* Since: 0.9.7744**/745hb_bool_t746hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,747const char *buf,748int buf_len, /* -1 means nul-terminated */749const char **end_ptr, /* May be NULL */750hb_font_t *font, /* May be NULL */751hb_buffer_serialize_format_t format)752{753const char *end;754if (!end_ptr)755end_ptr = &end;756*end_ptr = buf;757758buffer->assert_glyphs ();759760if (unlikely (hb_object_is_immutable (buffer)))761{762if (end_ptr)763*end_ptr = buf;764return false;765}766767if (buf_len == -1)768buf_len = strlen (buf);769770if (!buf_len)771{772*end_ptr = buf;773return false;774}775776hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_GLYPHS);777778if (!font)779font = hb_font_get_empty ();780781switch (format)782{783case HB_BUFFER_SERIALIZE_FORMAT_TEXT:784return _hb_buffer_deserialize_text_glyphs (buffer,785buf, buf_len, end_ptr,786font);787788case HB_BUFFER_SERIALIZE_FORMAT_JSON:789return _hb_buffer_deserialize_json (buffer,790buf, buf_len, end_ptr,791font);792793default:794case HB_BUFFER_SERIALIZE_FORMAT_INVALID:795return false;796797}798}799800801/**802* hb_buffer_deserialize_unicode:803* @buffer: an #hb_buffer_t buffer.804* @buf: (array length=buf_len): string to deserialize805* @buf_len: the size of @buf, or -1 if it is `NULL`-terminated806* @end_ptr: (out) (optional): output pointer to the character after last807* consumed one.808* @format: the #hb_buffer_serialize_format_t of the input @buf809*810* Deserializes Unicode @buffer from textual representation in the format811* produced by hb_buffer_serialize_unicode().812*813* Return value: `true` if the full string was parsed, `false` otherwise.814*815* Since: 2.7.3816**/817hb_bool_t818hb_buffer_deserialize_unicode (hb_buffer_t *buffer,819const char *buf,820int buf_len, /* -1 means nul-terminated */821const char **end_ptr, /* May be NULL */822hb_buffer_serialize_format_t format)823{824const char *end;825if (!end_ptr)826end_ptr = &end;827*end_ptr = buf;828829buffer->assert_unicode ();830831if (unlikely (hb_object_is_immutable (buffer)))832{833if (end_ptr)834*end_ptr = buf;835return false;836}837838if (buf_len == -1)839buf_len = strlen (buf);840841if (!buf_len)842{843*end_ptr = buf;844return false;845}846847hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_UNICODE);848849hb_font_t* font = hb_font_get_empty ();850851switch (format)852{853case HB_BUFFER_SERIALIZE_FORMAT_TEXT:854return _hb_buffer_deserialize_text_unicode (buffer,855buf, buf_len, end_ptr,856font);857858case HB_BUFFER_SERIALIZE_FORMAT_JSON:859return _hb_buffer_deserialize_json (buffer,860buf, buf_len, end_ptr,861font);862863default:864case HB_BUFFER_SERIALIZE_FORMAT_INVALID:865return false;866867}868}869870871#endif872873874