static void GetLeftRightCounts(DocTocItem *node, int& l2r, int& r2l) { if (!node) return; if (node->title) { for (const WCHAR *c = node->title; *c; c++) { if (ISLEFTTORIGHTCHAR(*c)) l2r++; else if (ISRIGHTTOLEFTCHAR(*c)) r2l++; } } GetLeftRightCounts(node->child, l2r, r2l); GetLeftRightCounts(node->next, l2r, r2l); }
static void fixup_text_span(fz_text_span *span) { int i; for (i = 0; i < span->len; i++) { switch (span->text[i].c) { /* recombine characters and their accents */ case 0x00A8: /* diaeresis/umlaut */ case 0x00B4: /* accute accent */ case 0x0060: /* grave accent */ case 0x005E: case 0x02C6: /* circumflex accent */ case 0x02DA: /* ring above */ if (i + 1 < span->len) { int newC = 0; if (span->text[i + 1].c != 32 || i + 2 == span->len) newC = ornate_character(&span->text[i], &span->text[i + 1]); else if ((newC = ornate_character(&span->text[i], &span->text[i + 2]))) delete_character(span, i + 1); if (newC) { delete_character(span, i); span->text[i].c = newC; } } break; default: /* cf. http://code.google.com/p/sumatrapdf/issues/detail?id=733 */ /* reverse words written in RTL languages */ if (ISRIGHTTOLEFTCHAR(span->text[i].c)) { int j = i + 1; while (j < span->len && span->text[j - 1].bbox.x0 <= span->text[j].bbox.x0 && !ISLEFTTORIGHTCHAR(span->text[i].c)) j++; reverse_characters(span, i, j - 1); i = j; } } } }
static void fixuptextspan(fz_text_span *head) { fz_text_span *span; int i; for (span = head; span; span = span->next) { for (i = 0; i < span->len; i++) { switch (span->text[i].c) { /* recombine characters and their accents */ case 0x00A8: /* ?*/ case 0x00B4: /* ?*/ case 0x0060: /* ` */ case 0x005E: /* ^ */ case 0x02DA: /* ?*/ if (span->next && span->next->len > 0 && (i + 1 == span->len || i + 2 == span->len && span->text[i + 1].c == 32)) { mergetwospans(span); } if (i + 1 < span->len) { int newC = 0; if (span->text[i + 1].c != 32 || i + 2 >= span->len) newC = ornatecharacter(span->text[i].c, span->text[i + 1].c); else if ((newC = ornatecharacter(span->text[i].c, span->text[i + 2].c))) deletecharacter(span, i + 1); if (newC) { deletecharacter(span, i); span->text[i].c = newC; } } break; default: /* cf. http://code.google.com/p/sumatrapdf/issues/detail?id=733 */ /* reverse words written in RTL languages */ if (ISRIGHTTOLEFTCHAR(span->text[i].c)) { int j = i + 1; while (j < span->len && span->text[j - 1].bbox.x0 <= span->text[j].bbox.x0 && !ISLEFTTORIGHTCHAR(span->text[i].c)) j++; reversecharacters(span, i, j - 1); i = j; } } } } /* cf. http://code.google.com/p/sumatrapdf/issues/detail?id=734 */ /* remove duplicate character sequences in (almost) the same spot */ for (span = head; span; span = span->next) { if (span->size < 5) /* doglyphsoverlap fails too often for small fonts */ continue; for (i = 0; i < span->len; i++) { fz_text_span *span2; int newlines, j; for (span2 = span, j = i + 1, newlines = 0; span2 && newlines < 2; newlines += span2->eol, span2 = span2->next, j = 0) for (; j < span2->len; j++) if (span->text[i].c != 32 && doglyphsoverlap(span, i, span2, j)) goto fixup_delete_duplicates; continue; fixup_delete_duplicates: do deletecharacter(span, i); while (doglyphsoverlap(span, i, span2, ++j)); if (i < span->len && span->text[i].c == 32) deletecharacter(span, i); else if (i == span->len && span->eol) span->eol = 0; i--; } } }