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 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 /* HarfBuzz-Internal API */ | 171 /* HarfBuzz-Internal API */ |
172 | 172 |
173 void | 173 void |
174 hb_buffer_t::reset (void) | 174 hb_buffer_t::reset (void) |
175 { | 175 { |
176 if (unlikely (hb_object_is_inert (this))) | 176 if (unlikely (hb_object_is_inert (this))) |
177 return; | 177 return; |
178 | 178 |
179 hb_unicode_funcs_destroy (unicode); | 179 hb_unicode_funcs_destroy (unicode); |
180 unicode = hb_unicode_funcs_get_default (); | 180 unicode = hb_unicode_funcs_get_default (); |
| 181 replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT; |
181 | 182 |
182 clear (); | 183 clear (); |
183 } | 184 } |
184 | 185 |
185 void | 186 void |
186 hb_buffer_t::clear (void) | 187 hb_buffer_t::clear (void) |
187 { | 188 { |
188 if (unlikely (hb_object_is_inert (this))) | 189 if (unlikely (hb_object_is_inert (this))) |
189 return; | 190 return; |
190 | 191 |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 last_cluster = info[i].cluster; | 494 last_cluster = info[i].cluster; |
494 } | 495 } |
495 } | 496 } |
496 reverse_range (start, i); | 497 reverse_range (start, i); |
497 } | 498 } |
498 | 499 |
499 void | 500 void |
500 hb_buffer_t::merge_clusters (unsigned int start, | 501 hb_buffer_t::merge_clusters (unsigned int start, |
501 unsigned int end) | 502 unsigned int end) |
502 { | 503 { |
| 504 #ifdef HB_NO_MERGE_CLUSTERS |
| 505 return; |
| 506 #endif |
| 507 |
503 if (unlikely (end - start < 2)) | 508 if (unlikely (end - start < 2)) |
504 return; | 509 return; |
505 | 510 |
506 unsigned int cluster = info[start].cluster; | 511 unsigned int cluster = info[start].cluster; |
507 | 512 |
508 for (unsigned int i = start + 1; i < end; i++) | 513 for (unsigned int i = start + 1; i < end; i++) |
509 cluster = MIN (cluster, info[i].cluster); | 514 cluster = MIN (cluster, info[i].cluster); |
510 | 515 |
511 /* Extend end */ | 516 /* Extend end */ |
512 while (end < len && info[end - 1].cluster == info[end].cluster) | 517 while (end < len && info[end - 1].cluster == info[end].cluster) |
513 end++; | 518 end++; |
514 | 519 |
515 /* Extend start */ | 520 /* Extend start */ |
516 while (idx < start && info[start - 1].cluster == info[start].cluster) | 521 while (idx < start && info[start - 1].cluster == info[start].cluster) |
517 start--; | 522 start--; |
518 | 523 |
519 /* If we hit the start of buffer, continue in out-buffer. */ | 524 /* If we hit the start of buffer, continue in out-buffer. */ |
520 if (idx == start) | 525 if (idx == start) |
521 for (unsigned i = out_len; i && out_info[i - 1].cluster == info[start].clust
er; i--) | 526 for (unsigned i = out_len; i && out_info[i - 1].cluster == info[start].clust
er; i--) |
522 out_info[i - 1].cluster = cluster; | 527 out_info[i - 1].cluster = cluster; |
523 | 528 |
524 for (unsigned int i = start; i < end; i++) | 529 for (unsigned int i = start; i < end; i++) |
525 info[i].cluster = cluster; | 530 info[i].cluster = cluster; |
526 } | 531 } |
527 void | 532 void |
528 hb_buffer_t::merge_out_clusters (unsigned int start, | 533 hb_buffer_t::merge_out_clusters (unsigned int start, |
529 unsigned int end) | 534 unsigned int end) |
530 { | 535 { |
| 536 #ifdef HB_NO_MERGE_CLUSTERS |
| 537 return; |
| 538 #endif |
| 539 |
531 if (unlikely (end - start < 2)) | 540 if (unlikely (end - start < 2)) |
532 return; | 541 return; |
533 | 542 |
534 unsigned int cluster = out_info[start].cluster; | 543 unsigned int cluster = out_info[start].cluster; |
535 | 544 |
536 for (unsigned int i = start + 1; i < end; i++) | 545 for (unsigned int i = start + 1; i < end; i++) |
537 cluster = MIN (cluster, out_info[i].cluster); | 546 cluster = MIN (cluster, out_info[i].cluster); |
538 | 547 |
539 /* Extend start */ | 548 /* Extend start */ |
540 while (start && out_info[start - 1].cluster == out_info[start].cluster) | 549 while (start && out_info[start - 1].cluster == out_info[start].cluster) |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
688 **/ | 697 **/ |
689 hb_buffer_t * | 698 hb_buffer_t * |
690 hb_buffer_get_empty (void) | 699 hb_buffer_get_empty (void) |
691 { | 700 { |
692 static const hb_buffer_t _hb_buffer_nil = { | 701 static const hb_buffer_t _hb_buffer_nil = { |
693 HB_OBJECT_HEADER_STATIC, | 702 HB_OBJECT_HEADER_STATIC, |
694 | 703 |
695 const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil), | 704 const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil), |
696 HB_SEGMENT_PROPERTIES_DEFAULT, | 705 HB_SEGMENT_PROPERTIES_DEFAULT, |
697 HB_BUFFER_FLAG_DEFAULT, | 706 HB_BUFFER_FLAG_DEFAULT, |
| 707 HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT, |
698 | 708 |
699 HB_BUFFER_CONTENT_TYPE_INVALID, | 709 HB_BUFFER_CONTENT_TYPE_INVALID, |
700 true, /* in_error */ | 710 true, /* in_error */ |
701 true, /* have_output */ | 711 true, /* have_output */ |
702 true /* have_positions */ | 712 true /* have_positions */ |
703 | 713 |
704 /* Zero is good enough for everything else. */ | 714 /* Zero is good enough for everything else. */ |
705 }; | 715 }; |
706 | 716 |
707 return const_cast<hb_buffer_t *> (&_hb_buffer_nil); | 717 return const_cast<hb_buffer_t *> (&_hb_buffer_nil); |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1033 * Since: 1.0 | 1043 * Since: 1.0 |
1034 **/ | 1044 **/ |
1035 hb_buffer_flags_t | 1045 hb_buffer_flags_t |
1036 hb_buffer_get_flags (hb_buffer_t *buffer) | 1046 hb_buffer_get_flags (hb_buffer_t *buffer) |
1037 { | 1047 { |
1038 return buffer->flags; | 1048 return buffer->flags; |
1039 } | 1049 } |
1040 | 1050 |
1041 | 1051 |
1042 /** | 1052 /** |
| 1053 * hb_buffer_set_replacement_codepoint: |
| 1054 * @buffer: a buffer. |
| 1055 * @replacement: |
| 1056 * |
| 1057 * |
| 1058 * |
| 1059 * Since: 1.0 |
| 1060 **/ |
| 1061 void |
| 1062 hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer, |
| 1063 hb_codepoint_t replacement) |
| 1064 { |
| 1065 if (unlikely (hb_object_is_inert (buffer))) |
| 1066 return; |
| 1067 |
| 1068 buffer->replacement = replacement; |
| 1069 } |
| 1070 |
| 1071 /** |
| 1072 * hb_buffer_get_replacement_codepoint: |
| 1073 * @buffer: a buffer. |
| 1074 * |
| 1075 * |
| 1076 * |
| 1077 * Return value: |
| 1078 * |
| 1079 * Since: 1.0 |
| 1080 **/ |
| 1081 hb_codepoint_t |
| 1082 hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer) |
| 1083 { |
| 1084 return buffer->replacement; |
| 1085 } |
| 1086 |
| 1087 |
| 1088 /** |
1043 * hb_buffer_reset: | 1089 * hb_buffer_reset: |
1044 * @buffer: a buffer. | 1090 * @buffer: a buffer. |
1045 * | 1091 * |
1046 * | 1092 * |
1047 * | 1093 * |
1048 * Since: 1.0 | 1094 * Since: 1.0 |
1049 **/ | 1095 **/ |
1050 void | 1096 void |
1051 hb_buffer_reset (hb_buffer_t *buffer) | 1097 hb_buffer_reset (hb_buffer_t *buffer) |
1052 { | 1098 { |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1275 * taking buffer script into consideration when choosing a language. | 1321 * taking buffer script into consideration when choosing a language. |
1276 * | 1322 * |
1277 * Since: 1.0 | 1323 * Since: 1.0 |
1278 **/ | 1324 **/ |
1279 void | 1325 void |
1280 hb_buffer_guess_segment_properties (hb_buffer_t *buffer) | 1326 hb_buffer_guess_segment_properties (hb_buffer_t *buffer) |
1281 { | 1327 { |
1282 buffer->guess_segment_properties (); | 1328 buffer->guess_segment_properties (); |
1283 } | 1329 } |
1284 | 1330 |
1285 template <typename T> | 1331 template <bool validate, typename T> |
1286 static inline void | 1332 static inline void |
1287 hb_buffer_add_utf (hb_buffer_t *buffer, | 1333 hb_buffer_add_utf (hb_buffer_t *buffer, |
1288 const T *text, | 1334 const T *text, |
1289 int text_length, | 1335 int text_length, |
1290 unsigned int item_offset, | 1336 unsigned int item_offset, |
1291 int item_length) | 1337 int item_length) |
1292 { | 1338 { |
| 1339 typedef hb_utf_t<T, true> utf_t; |
| 1340 const hb_codepoint_t replacement = buffer->replacement; |
| 1341 |
1293 assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE || | 1342 assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE || |
1294 (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALI
D)); | 1343 (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALI
D)); |
1295 | 1344 |
1296 if (unlikely (hb_object_is_inert (buffer))) | 1345 if (unlikely (hb_object_is_inert (buffer))) |
1297 return; | 1346 return; |
1298 | 1347 |
1299 if (text_length == -1) | 1348 if (text_length == -1) |
1300 text_length = hb_utf_strlen (text); | 1349 text_length = utf_t::strlen (text); |
1301 | 1350 |
1302 if (item_length == -1) | 1351 if (item_length == -1) |
1303 item_length = text_length - item_offset; | 1352 item_length = text_length - item_offset; |
1304 | 1353 |
1305 buffer->ensure (buffer->len + item_length * sizeof (T) / 4); | 1354 buffer->ensure (buffer->len + item_length * sizeof (T) / 4); |
1306 | 1355 |
1307 /* If buffer is empty and pre-context provided, install it. | 1356 /* If buffer is empty and pre-context provided, install it. |
1308 * This check is written this way, to make sure people can | 1357 * This check is written this way, to make sure people can |
1309 * provide pre-context in one add_utf() call, then provide | 1358 * provide pre-context in one add_utf() call, then provide |
1310 * text in a follow-up call. See: | 1359 * text in a follow-up call. See: |
1311 * | 1360 * |
1312 * https://bugzilla.mozilla.org/show_bug.cgi?id=801410#c13 | 1361 * https://bugzilla.mozilla.org/show_bug.cgi?id=801410#c13 |
1313 */ | 1362 */ |
1314 if (!buffer->len && item_offset > 0) | 1363 if (!buffer->len && item_offset > 0) |
1315 { | 1364 { |
1316 /* Add pre-context */ | 1365 /* Add pre-context */ |
1317 buffer->clear_context (0); | 1366 buffer->clear_context (0); |
1318 const T *prev = text + item_offset; | 1367 const T *prev = text + item_offset; |
1319 const T *start = text; | 1368 const T *start = text; |
1320 while (start < prev && buffer->context_len[0] < buffer->CONTEXT_LENGTH) | 1369 while (start < prev && buffer->context_len[0] < buffer->CONTEXT_LENGTH) |
1321 { | 1370 { |
1322 hb_codepoint_t u; | 1371 hb_codepoint_t u; |
1323 prev = hb_utf_prev (prev, start, &u); | 1372 prev = utf_t::prev (prev, start, &u, replacement); |
1324 buffer->context[0][buffer->context_len[0]++] = u; | 1373 buffer->context[0][buffer->context_len[0]++] = u; |
1325 } | 1374 } |
1326 } | 1375 } |
1327 | 1376 |
1328 const T *next = text + item_offset; | 1377 const T *next = text + item_offset; |
1329 const T *end = next + item_length; | 1378 const T *end = next + item_length; |
1330 while (next < end) | 1379 while (next < end) |
1331 { | 1380 { |
1332 hb_codepoint_t u; | 1381 hb_codepoint_t u; |
1333 const T *old_next = next; | 1382 const T *old_next = next; |
1334 next = hb_utf_next (next, end, &u); | 1383 next = utf_t::next (next, end, &u, replacement); |
1335 buffer->add (u, old_next - (const T *) text); | 1384 buffer->add (u, old_next - (const T *) text); |
1336 } | 1385 } |
1337 | 1386 |
1338 /* Add post-context */ | 1387 /* Add post-context */ |
1339 buffer->clear_context (1); | 1388 buffer->clear_context (1); |
1340 end = text + text_length; | 1389 end = text + text_length; |
1341 while (next < end && buffer->context_len[1] < buffer->CONTEXT_LENGTH) | 1390 while (next < end && buffer->context_len[1] < buffer->CONTEXT_LENGTH) |
1342 { | 1391 { |
1343 hb_codepoint_t u; | 1392 hb_codepoint_t u; |
1344 next = hb_utf_next (next, end, &u); | 1393 next = utf_t::next (next, end, &u, replacement); |
1345 buffer->context[1][buffer->context_len[1]++] = u; | 1394 buffer->context[1][buffer->context_len[1]++] = u; |
1346 } | 1395 } |
1347 | 1396 |
1348 buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE; | 1397 buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE; |
1349 } | 1398 } |
1350 | 1399 |
1351 /** | 1400 /** |
1352 * hb_buffer_add_utf8: | 1401 * hb_buffer_add_utf8: |
1353 * @buffer: a buffer. | 1402 * @buffer: a buffer. |
1354 * @text: (array length=text_length): | 1403 * @text: (array length=text_length): |
1355 * @text_length: | 1404 * @text_length: |
1356 * @item_offset: | 1405 * @item_offset: |
1357 * @item_length: | 1406 * @item_length: |
1358 * | 1407 * |
1359 * | 1408 * |
1360 * | 1409 * |
1361 * Since: 1.0 | 1410 * Since: 1.0 |
1362 **/ | 1411 **/ |
1363 void | 1412 void |
1364 hb_buffer_add_utf8 (hb_buffer_t *buffer, | 1413 hb_buffer_add_utf8 (hb_buffer_t *buffer, |
1365 const char *text, | 1414 const char *text, |
1366 int text_length, | 1415 int text_length, |
1367 unsigned int item_offset, | 1416 unsigned int item_offset, |
1368 int item_length) | 1417 int item_length) |
1369 { | 1418 { |
1370 hb_buffer_add_utf (buffer, (const uint8_t *) text, text_length, item_offset, i
tem_length); | 1419 hb_buffer_add_utf<true> (buffer, (const uint8_t *) text, text_length, item_off
set, item_length); |
1371 } | 1420 } |
1372 | 1421 |
1373 /** | 1422 /** |
1374 * hb_buffer_add_utf16: | 1423 * hb_buffer_add_utf16: |
1375 * @buffer: a buffer. | 1424 * @buffer: a buffer. |
1376 * @text: (array length=text_length): | 1425 * @text: (array length=text_length): |
1377 * @text_length: | 1426 * @text_length: |
1378 * @item_offset: | 1427 * @item_offset: |
1379 * @item_length: | 1428 * @item_length: |
1380 * | 1429 * |
1381 * | 1430 * |
1382 * | 1431 * |
1383 * Since: 1.0 | 1432 * Since: 1.0 |
1384 **/ | 1433 **/ |
1385 void | 1434 void |
1386 hb_buffer_add_utf16 (hb_buffer_t *buffer, | 1435 hb_buffer_add_utf16 (hb_buffer_t *buffer, |
1387 const uint16_t *text, | 1436 const uint16_t *text, |
1388 int text_length, | 1437 int text_length, |
1389 unsigned int item_offset, | 1438 unsigned int item_offset, |
1390 int item_length) | 1439 int item_length) |
1391 { | 1440 { |
1392 hb_buffer_add_utf (buffer, text, text_length, item_offset, item_length); | 1441 hb_buffer_add_utf<true> (buffer, text, text_length, item_offset, item_length); |
1393 } | 1442 } |
1394 | 1443 |
1395 /** | 1444 /** |
1396 * hb_buffer_add_utf32: | 1445 * hb_buffer_add_utf32: |
1397 * @buffer: a buffer. | 1446 * @buffer: a buffer. |
1398 * @text: (array length=text_length): | 1447 * @text: (array length=text_length): |
1399 * @text_length: | 1448 * @text_length: |
1400 * @item_offset: | 1449 * @item_offset: |
1401 * @item_length: | 1450 * @item_length: |
1402 * | 1451 * |
1403 * | 1452 * |
1404 * | 1453 * |
1405 * Since: 1.0 | 1454 * Since: 1.0 |
1406 **/ | 1455 **/ |
1407 void | 1456 void |
1408 hb_buffer_add_utf32 (hb_buffer_t *buffer, | 1457 hb_buffer_add_utf32 (hb_buffer_t *buffer, |
1409 const uint32_t *text, | 1458 const uint32_t *text, |
1410 int text_length, | 1459 int text_length, |
1411 unsigned int item_offset, | 1460 unsigned int item_offset, |
1412 int item_length) | 1461 int item_length) |
1413 { | 1462 { |
1414 hb_buffer_add_utf (buffer, text, text_length, item_offset, item_length); | 1463 hb_buffer_add_utf<true> (buffer, text, text_length, item_offset, item_length); |
| 1464 } |
| 1465 |
| 1466 /** |
| 1467 * hb_buffer_add_codepoints: |
| 1468 * @buffer: a buffer. |
| 1469 * @text: (array length=text_length): |
| 1470 * @text_length: |
| 1471 * @item_offset: |
| 1472 * @item_length: |
| 1473 * |
| 1474 * |
| 1475 * |
| 1476 * Since: 1.0 |
| 1477 **/ |
| 1478 void |
| 1479 hb_buffer_add_codepoints (hb_buffer_t *buffer, |
| 1480 » » » const hb_codepoint_t *text, |
| 1481 » » » int text_length, |
| 1482 » » » unsigned int item_offset, |
| 1483 » » » int item_length) |
| 1484 { |
| 1485 hb_buffer_add_utf<false> (buffer, text, text_length, item_offset, item_length)
; |
1415 } | 1486 } |
1416 | 1487 |
1417 | 1488 |
1418 static int | 1489 static int |
1419 compare_info_codepoint (const hb_glyph_info_t *pa, | 1490 compare_info_codepoint (const hb_glyph_info_t *pa, |
1420 const hb_glyph_info_t *pb) | 1491 const hb_glyph_info_t *pb) |
1421 { | 1492 { |
1422 return (int) pb->codepoint - (int) pa->codepoint; | 1493 return (int) pb->codepoint - (int) pa->codepoint; |
1423 } | 1494 } |
1424 | 1495 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1492 | 1563 |
1493 unsigned int start = 0; | 1564 unsigned int start = 0; |
1494 unsigned int end; | 1565 unsigned int end; |
1495 for (end = start + 1; end < count; end++) | 1566 for (end = start + 1; end < count; end++) |
1496 if (info[start].cluster != info[end].cluster) { | 1567 if (info[start].cluster != info[end].cluster) { |
1497 normalize_glyphs_cluster (buffer, start, end, backward); | 1568 normalize_glyphs_cluster (buffer, start, end, backward); |
1498 start = end; | 1569 start = end; |
1499 } | 1570 } |
1500 normalize_glyphs_cluster (buffer, start, end, backward); | 1571 normalize_glyphs_cluster (buffer, start, end, backward); |
1501 } | 1572 } |
OLD | NEW |