| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright © 1998-2004 David Turner and Werner Lemberg | 2 * Copyright © 1998-2004 David Turner and Werner Lemberg |
| 3 * Copyright © 2004,2007,2009,2010 Red Hat, Inc. | 3 * Copyright © 2004,2007,2009,2010 Red Hat, Inc. |
| 4 * Copyright © 2011,2012 Google, Inc. | 4 * Copyright © 2011,2012 Google, Inc. |
| 5 * | 5 * |
| 6 * This is part of HarfBuzz, a text shaping library. | 6 * This is part of HarfBuzz, a text shaping library. |
| 7 * | 7 * |
| 8 * Permission is hereby granted, without written agreement and without | 8 * Permission is hereby granted, without written agreement and without |
| 9 * license or royalty fees, to use, copy, modify, and distribute this | 9 * license or royalty fees, to use, copy, modify, and distribute this |
| 10 * software and its documentation for any purpose, provided that the | 10 * software and its documentation for any purpose, provided that the |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 | 208 |
| 209 memset (glyph, 0, sizeof (*glyph)); | 209 memset (glyph, 0, sizeof (*glyph)); |
| 210 glyph->codepoint = codepoint; | 210 glyph->codepoint = codepoint; |
| 211 glyph->mask = 1; | 211 glyph->mask = 1; |
| 212 glyph->cluster = cluster; | 212 glyph->cluster = cluster; |
| 213 | 213 |
| 214 len++; | 214 len++; |
| 215 } | 215 } |
| 216 | 216 |
| 217 void | 217 void |
| 218 hb_buffer_t::add_info (const hb_glyph_info_t &glyph_info) |
| 219 { |
| 220 if (unlikely (!ensure (len + 1))) return; |
| 221 |
| 222 info[len] = glyph_info; |
| 223 |
| 224 len++; |
| 225 } |
| 226 |
| 227 |
| 228 void |
| 218 hb_buffer_t::remove_output (void) | 229 hb_buffer_t::remove_output (void) |
| 219 { | 230 { |
| 220 if (unlikely (hb_object_is_inert (this))) | 231 if (unlikely (hb_object_is_inert (this))) |
| 221 return; | 232 return; |
| 222 | 233 |
| 223 have_output = false; | 234 have_output = false; |
| 224 have_positions = false; | 235 have_positions = false; |
| 225 | 236 |
| 226 out_len = 0; | 237 out_len = 0; |
| 227 out_info = info; | 238 out_info = info; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 { | 319 { |
| 309 if (unlikely (!make_room_for (0, 1))) return; | 320 if (unlikely (!make_room_for (0, 1))) return; |
| 310 | 321 |
| 311 out_info[out_len] = info[idx]; | 322 out_info[out_len] = info[idx]; |
| 312 out_info[out_len].codepoint = glyph_index; | 323 out_info[out_len].codepoint = glyph_index; |
| 313 | 324 |
| 314 out_len++; | 325 out_len++; |
| 315 } | 326 } |
| 316 | 327 |
| 317 void | 328 void |
| 318 hb_buffer_t::output_info (hb_glyph_info_t &glyph_info) | 329 hb_buffer_t::output_info (const hb_glyph_info_t &glyph_info) |
| 319 { | 330 { |
| 320 if (unlikely (!make_room_for (0, 1))) return; | 331 if (unlikely (!make_room_for (0, 1))) return; |
| 321 | 332 |
| 322 out_info[out_len] = glyph_info; | 333 out_info[out_len] = glyph_info; |
| 323 | 334 |
| 324 out_len++; | 335 out_len++; |
| 325 } | 336 } |
| 326 | 337 |
| 327 void | 338 void |
| 328 hb_buffer_t::copy_glyph (void) | 339 hb_buffer_t::copy_glyph (void) |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 } | 794 } |
| 784 | 795 |
| 785 | 796 |
| 786 void | 797 void |
| 787 hb_buffer_reset (hb_buffer_t *buffer) | 798 hb_buffer_reset (hb_buffer_t *buffer) |
| 788 { | 799 { |
| 789 buffer->reset (); | 800 buffer->reset (); |
| 790 } | 801 } |
| 791 | 802 |
| 792 void | 803 void |
| 793 hb_buffer_clear (hb_buffer_t *buffer) | 804 hb_buffer_clear_contents (hb_buffer_t *buffer) |
| 794 { | 805 { |
| 795 buffer->clear (); | 806 buffer->clear (); |
| 796 } | 807 } |
| 797 | 808 |
| 798 hb_bool_t | 809 hb_bool_t |
| 799 hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size) | 810 hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size) |
| 800 { | 811 { |
| 801 return buffer->ensure (size); | 812 return buffer->ensure (size); |
| 802 } | 813 } |
| 803 | 814 |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1057 | 1068 |
| 1058 unsigned int start = 0; | 1069 unsigned int start = 0; |
| 1059 unsigned int end; | 1070 unsigned int end; |
| 1060 for (end = start + 1; end < count; end++) | 1071 for (end = start + 1; end < count; end++) |
| 1061 if (info[start].cluster != info[end].cluster) { | 1072 if (info[start].cluster != info[end].cluster) { |
| 1062 normalize_glyphs_cluster (buffer, start, end, backward); | 1073 normalize_glyphs_cluster (buffer, start, end, backward); |
| 1063 start = end; | 1074 start = end; |
| 1064 } | 1075 } |
| 1065 normalize_glyphs_cluster (buffer, start, end, backward); | 1076 normalize_glyphs_cluster (buffer, start, end, backward); |
| 1066 } | 1077 } |
| 1067 | |
| 1068 | |
| 1069 /* | |
| 1070 * Serialize | |
| 1071 */ | |
| 1072 | |
| 1073 static const char *serialize_formats[] = { | |
| 1074 "text", | |
| 1075 "json", | |
| 1076 NULL | |
| 1077 }; | |
| 1078 | |
| 1079 const char ** | |
| 1080 hb_buffer_serialize_list_formats (void) | |
| 1081 { | |
| 1082 return serialize_formats; | |
| 1083 } | |
| 1084 | |
| 1085 hb_buffer_serialize_format_t | |
| 1086 hb_buffer_serialize_format_from_string (const char *str, int len) | |
| 1087 { | |
| 1088 /* Upper-case it. */ | |
| 1089 return (hb_buffer_serialize_format_t) (hb_tag_from_string (str, len) & ~0x2020
2020); | |
| 1090 } | |
| 1091 | |
| 1092 const char * | |
| 1093 hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format) | |
| 1094 { | |
| 1095 switch (format) | |
| 1096 { | |
| 1097 case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0]; | |
| 1098 case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1]; | |
| 1099 default: | |
| 1100 case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return NULL; | |
| 1101 } | |
| 1102 } | |
| 1103 | |
| 1104 static unsigned int | |
| 1105 _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, | |
| 1106 unsigned int start, | |
| 1107 unsigned int end, | |
| 1108 char *buf, | |
| 1109 unsigned int buf_size, | |
| 1110 unsigned int *buf_consumed, | |
| 1111 hb_font_t *font, | |
| 1112 hb_buffer_serialize_flags_t flags) | |
| 1113 { | |
| 1114 hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL); | |
| 1115 hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL); | |
| 1116 | |
| 1117 *buf_consumed = 0; | |
| 1118 for (unsigned int i = start; i < end; i++) | |
| 1119 { | |
| 1120 char b[1024]; | |
| 1121 char *p = b; | |
| 1122 | |
| 1123 /* In the following code, we know b is large enough that no overflow can hap
pen. */ | |
| 1124 | |
| 1125 #define APPEND(s) HB_STMT_START { strcpy (p, s); p += strlen (s); } HB_STMT_END | |
| 1126 | |
| 1127 if (i) | |
| 1128 *p++ = ','; | |
| 1129 | |
| 1130 *p++ = '{'; | |
| 1131 | |
| 1132 APPEND ("\"g\":"); | |
| 1133 if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES)) | |
| 1134 { | |
| 1135 char g[128]; | |
| 1136 hb_font_glyph_to_string (font, info[i].codepoint, g, sizeof (g)); | |
| 1137 *p++ = '"'; | |
| 1138 for (char *q = g; *q; q++) { | |
| 1139 if (*q == '"') | |
| 1140 *p++ = '\\'; | |
| 1141 *p++ = *q; | |
| 1142 } | |
| 1143 *p++ = '"'; | |
| 1144 } | |
| 1145 else | |
| 1146 p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint); | |
| 1147 | |
| 1148 if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) { | |
| 1149 p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluste
r); | |
| 1150 } | |
| 1151 | |
| 1152 if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) | |
| 1153 { | |
| 1154 p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d", | |
| 1155 pos[i].x_offset, pos[i].y_offset); | |
| 1156 p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d", | |
| 1157 pos[i].x_advance, pos[i].y_advance); | |
| 1158 } | |
| 1159 | |
| 1160 *p++ = '}'; | |
| 1161 | |
| 1162 if (buf_size > (p - b)) | |
| 1163 { | |
| 1164 unsigned int l = p - b; | |
| 1165 memcpy (buf, b, l); | |
| 1166 buf += l; | |
| 1167 buf_size -= l; | |
| 1168 *buf_consumed += l; | |
| 1169 *buf = '\0'; | |
| 1170 } else | |
| 1171 return i - start; | |
| 1172 } | |
| 1173 | |
| 1174 return end - start; | |
| 1175 } | |
| 1176 | |
| 1177 static unsigned int | |
| 1178 _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, | |
| 1179 unsigned int start, | |
| 1180 unsigned int end, | |
| 1181 char *buf, | |
| 1182 unsigned int buf_size, | |
| 1183 unsigned int *buf_consumed, | |
| 1184 hb_font_t *font, | |
| 1185 hb_buffer_serialize_flags_t flags) | |
| 1186 { | |
| 1187 hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL); | |
| 1188 hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL); | |
| 1189 hb_direction_t direction = hb_buffer_get_direction (buffer); | |
| 1190 | |
| 1191 *buf_consumed = 0; | |
| 1192 for (unsigned int i = start; i < end; i++) | |
| 1193 { | |
| 1194 char b[1024]; | |
| 1195 char *p = b; | |
| 1196 | |
| 1197 /* In the following code, we know b is large enough that no overflow can hap
pen. */ | |
| 1198 | |
| 1199 if (i) | |
| 1200 *p++ = '|'; | |
| 1201 | |
| 1202 if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES)) | |
| 1203 { | |
| 1204 hb_font_glyph_to_string (font, info[i].codepoint, p, 128); | |
| 1205 p += strlen (p); | |
| 1206 } | |
| 1207 else | |
| 1208 p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint); | |
| 1209 | |
| 1210 if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) { | |
| 1211 p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster); | |
| 1212 } | |
| 1213 | |
| 1214 if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) | |
| 1215 { | |
| 1216 if (pos[i].x_offset || pos[i].y_offset) | |
| 1217 p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", pos[i].x_offset,
pos[i].y_offset); | |
| 1218 | |
| 1219 *p++ = '+'; | |
| 1220 if (HB_DIRECTION_IS_HORIZONTAL (direction) || pos[i].x_advance) | |
| 1221 p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance); | |
| 1222 if (HB_DIRECTION_IS_VERTICAL (direction) || pos->y_advance) | |
| 1223 p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance); | |
| 1224 } | |
| 1225 | |
| 1226 if (buf_size > (p - b)) | |
| 1227 { | |
| 1228 unsigned int l = p - b; | |
| 1229 memcpy (buf, b, l); | |
| 1230 buf += l; | |
| 1231 buf_size -= l; | |
| 1232 *buf_consumed += l; | |
| 1233 *buf = '\0'; | |
| 1234 } else | |
| 1235 return i - start; | |
| 1236 } | |
| 1237 | |
| 1238 return end - start; | |
| 1239 } | |
| 1240 | |
| 1241 /* Returns number of items, starting at start, that were serialized. */ | |
| 1242 unsigned int | |
| 1243 hb_buffer_serialize_glyphs (hb_buffer_t *buffer, | |
| 1244 unsigned int start, | |
| 1245 unsigned int end, | |
| 1246 char *buf, | |
| 1247 unsigned int buf_size, | |
| 1248 unsigned int *buf_consumed, | |
| 1249 hb_font_t *font, /* May be NULL */ | |
| 1250 hb_buffer_serialize_format_t format, | |
| 1251 hb_buffer_serialize_flags_t flags) | |
| 1252 { | |
| 1253 assert (start <= end && end <= buffer->len); | |
| 1254 | |
| 1255 *buf_consumed = 0; | |
| 1256 | |
| 1257 assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALI
D) || | |
| 1258 buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS); | |
| 1259 | |
| 1260 if (unlikely (start == end)) | |
| 1261 return 0; | |
| 1262 | |
| 1263 if (!font) | |
| 1264 font = hb_font_get_empty (); | |
| 1265 | |
| 1266 switch (format) | |
| 1267 { | |
| 1268 case HB_BUFFER_SERIALIZE_FORMAT_TEXT: | |
| 1269 return _hb_buffer_serialize_glyphs_text (buffer, start, end, | |
| 1270 buf, buf_size, buf_consumed, | |
| 1271 font, flags); | |
| 1272 | |
| 1273 case HB_BUFFER_SERIALIZE_FORMAT_JSON: | |
| 1274 return _hb_buffer_serialize_glyphs_json (buffer, start, end, | |
| 1275 buf, buf_size, buf_consumed, | |
| 1276 font, flags); | |
| 1277 | |
| 1278 default: | |
| 1279 case HB_BUFFER_SERIALIZE_FORMAT_INVALID: | |
| 1280 return 0; | |
| 1281 | |
| 1282 } | |
| 1283 } | |
| 1284 | |
| 1285 hb_bool_t | |
| 1286 hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, | |
| 1287 const char *buf, | |
| 1288 unsigned int buf_len, | |
| 1289 unsigned int *buf_consumed, | |
| 1290 hb_font_t *font, /* May be NULL */ | |
| 1291 hb_buffer_serialize_format_t format) | |
| 1292 { | |
| 1293 return false; | |
| 1294 } | |
| OLD | NEW |