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 |