1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/* 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Copyright © 2012,2013 Google, Inc. 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * This is part of HarfBuzz, a text shaping library. 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Permission is hereby granted, without written agreement and without 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * license or royalty fees, to use, copy, modify, and distribute this 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * software and its documentation for any purpose, provided that the 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * above copyright notice and the following two paragraphs appear in 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * all copies of this software. 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * DAMAGE. 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Google Author(s): Behdad Esfahbod 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */ 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "hb-buffer-private.hh" 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static const char *serialize_formats[] = { 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "text", 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "json", 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NULL 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char ** 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)hb_buffer_serialize_list_formats (void) 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return serialize_formats; 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)hb_buffer_serialize_format_t 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)hb_buffer_serialize_format_from_string (const char *str, int len) 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* Upper-case it. */ 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return (hb_buffer_serialize_format_t) (hb_tag_from_string (str, len) & ~0x20202020); 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char * 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format) 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (format) 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0]; 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1]; 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default: 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return NULL; 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static unsigned int 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)_hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int start, 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int end, 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char *buf, 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int buf_size, 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int *buf_consumed, 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_font_t *font, 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_buffer_serialize_flags_t flags) 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL); 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL); 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *buf_consumed = 0; 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (unsigned int i = start; i < end; i++) 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char b[1024]; 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char *p = b; 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* In the following code, we know b is large enough that no overflow can happen. */ 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define APPEND(s) HB_STMT_START { strcpy (p, s); p += strlen (s); } HB_STMT_END 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (i) 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *p++ = ','; 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *p++ = '{'; 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) APPEND ("\"g\":"); 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES)) 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char g[128]; 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_font_glyph_to_string (font, info[i].codepoint, g, sizeof (g)); 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *p++ = '"'; 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (char *q = g; *q; q++) { 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (*q == '"') 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *p++ = '\\'; 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *p++ = *q; 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *p++ = '"'; 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint); 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) { 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster); 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d", 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pos[i].x_offset, pos[i].y_offset); 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d", 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pos[i].x_advance, pos[i].y_advance); 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *p++ = '}'; 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (buf_size > (p - b)) 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int l = p - b; 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) memcpy (buf, b, l); 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) buf += l; 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) buf_size -= l; 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *buf_consumed += l; 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *buf = '\0'; 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return i - start; 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return end - start; 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static unsigned int 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)_hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int start, 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int end, 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char *buf, 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int buf_size, 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int *buf_consumed, 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_font_t *font, 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_buffer_serialize_flags_t flags) 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL); 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL); 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *buf_consumed = 0; 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (unsigned int i = start; i < end; i++) 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char b[1024]; 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char *p = b; 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* In the following code, we know b is large enough that no overflow can happen. */ 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (i) 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *p++ = '|'; 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES)) 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_font_glyph_to_string (font, info[i].codepoint, p, 128); 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) p += strlen (p); 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint); 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) { 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster); 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (pos[i].x_offset || pos[i].y_offset) 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", pos[i].x_offset, pos[i].y_offset); 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *p++ = '+'; 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance); 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (pos->y_advance) 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance); 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (buf_size > (p - b)) 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int l = p - b; 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) memcpy (buf, b, l); 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) buf += l; 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) buf_size -= l; 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *buf_consumed += l; 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *buf = '\0'; 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return i - start; 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return end - start; 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/* Returns number of items, starting at start, that were serialized. */ 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)unsigned int 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)hb_buffer_serialize_glyphs (hb_buffer_t *buffer, 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int start, 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int end, 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char *buf, 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int buf_size, 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int *buf_consumed, /* May be NULL */ 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_font_t *font, /* May be NULL */ 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_buffer_serialize_format_t format, 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_buffer_serialize_flags_t flags) 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) assert (start <= end && end <= buffer->len); 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int sconsumed; 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!buf_consumed) 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) buf_consumed = &sconsumed; 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *buf_consumed = 0; 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) || 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS); 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (unlikely (start == end)) 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 0; 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!font) 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) font = hb_font_get_empty (); 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (format) 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case HB_BUFFER_SERIALIZE_FORMAT_TEXT: 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return _hb_buffer_serialize_glyphs_text (buffer, start, end, 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) buf, buf_size, buf_consumed, 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) font, flags); 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case HB_BUFFER_SERIALIZE_FORMAT_JSON: 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return _hb_buffer_serialize_glyphs_json (buffer, start, end, 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) buf, buf_size, buf_consumed, 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) font, flags); 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default: 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case HB_BUFFER_SERIALIZE_FORMAT_INVALID: 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 0; 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static hb_bool_t 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)parse_uint (const char *pp, const char *end, uint32_t *pv) 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char buf[32]; 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp)); 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) strncpy (buf, pp, len); 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) buf[len] = '\0'; 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char *p = buf; 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char *pend = p; 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint32_t v; 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) errno = 0; 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) v = strtol (p, &pend, 10); 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (errno || p == pend || pend - p != end - pp) 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *pv = v; 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static hb_bool_t 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)parse_int (const char *pp, const char *end, int32_t *pv) 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char buf[32]; 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp)); 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) strncpy (buf, pp, len); 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) buf[len] = '\0'; 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char *p = buf; 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char *pend = p; 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int32_t v; 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) errno = 0; 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) v = strtol (p, &pend, 10); 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (errno || p == pend || pend - p != end - pp) 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *pv = v; 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "hb-buffer-deserialize-json.hh" 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "hb-buffer-deserialize-text.hh" 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)hb_bool_t 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char *buf, 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int buf_len, /* -1 means nul-terminated */ 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char **end_ptr, /* May be NULL */ 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_font_t *font, /* May be NULL */ 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_buffer_serialize_format_t format) 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char *end; 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!end_ptr) 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) end_ptr = &end; 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *end_ptr = buf; 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) || 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS); 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (buf_len == -1) 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) buf_len = strlen (buf); 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!buf_len) 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *end_ptr = buf; 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_GLYPHS); 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!font) 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) font = hb_font_get_empty (); 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (format) 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case HB_BUFFER_SERIALIZE_FORMAT_TEXT: 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return _hb_buffer_deserialize_glyphs_text (buffer, 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) buf, buf_len, end_ptr, 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) font); 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case HB_BUFFER_SERIALIZE_FORMAT_JSON: 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return _hb_buffer_deserialize_glyphs_json (buffer, 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) buf, buf_len, end_ptr, 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) font); 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default: 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case HB_BUFFER_SERIALIZE_FORMAT_INVALID: 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 337