diff options
Diffstat (limited to 'src/ui/text.c')
-rw-r--r-- | src/ui/text.c | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/src/ui/text.c b/src/ui/text.c index c0661ee8..618f3d79 100644 --- a/src/ui/text.c +++ b/src/ui/text.c | |||
@@ -657,17 +657,27 @@ enum iScript { | |||
657 | arabic_Script, | 657 | arabic_Script, |
658 | bengali_Script, | 658 | bengali_Script, |
659 | devanagari_Script, | 659 | devanagari_Script, |
660 | han_Script, | ||
661 | hiragana_Script, | ||
662 | katakana_Script, | ||
660 | oriya_Script, | 663 | oriya_Script, |
661 | tamil_Script, | 664 | tamil_Script, |
662 | max_Script | 665 | max_Script |
663 | }; | 666 | }; |
664 | 667 | ||
668 | iLocalDef iBool isCJK_Script_(enum iScript d) { | ||
669 | return d == han_Script || d == hiragana_Script || d == katakana_Script; | ||
670 | } | ||
671 | |||
665 | #if defined (LAGRANGE_ENABLE_HARFBUZZ) | 672 | #if defined (LAGRANGE_ENABLE_HARFBUZZ) |
666 | static const hb_script_t hbScripts_[max_Script] = { | 673 | static const hb_script_t hbScripts_[max_Script] = { |
667 | 0, | 674 | 0, |
668 | HB_SCRIPT_ARABIC, | 675 | HB_SCRIPT_ARABIC, |
669 | HB_SCRIPT_BENGALI, | 676 | HB_SCRIPT_BENGALI, |
670 | HB_SCRIPT_DEVANAGARI, | 677 | HB_SCRIPT_DEVANAGARI, |
678 | HB_SCRIPT_HAN, | ||
679 | HB_SCRIPT_HIRAGANA, | ||
680 | HB_SCRIPT_KATAKANA, | ||
671 | HB_SCRIPT_ORIYA, | 681 | HB_SCRIPT_ORIYA, |
672 | HB_SCRIPT_TAMIL, | 682 | HB_SCRIPT_TAMIL, |
673 | }; | 683 | }; |
@@ -1006,7 +1016,6 @@ static void prepare_AttributedText_(iAttributedText *d, int overrideBaseDir, iCh | |||
1006 | #endif | 1016 | #endif |
1007 | } | 1017 | } |
1008 | /* Detect the script. */ | 1018 | /* Detect the script. */ |
1009 | // printf("Char %08x %lc => %s\n", ch, (int) ch, script_Char(ch)); | ||
1010 | #if defined (LAGRANGE_ENABLE_FRIBIDI) | 1019 | #if defined (LAGRANGE_ENABLE_FRIBIDI) |
1011 | if (fribidi_get_bidi_type(ch) == FRIBIDI_TYPE_AL) { | 1020 | if (fribidi_get_bidi_type(ch) == FRIBIDI_TYPE_AL) { |
1012 | run.flags.script = arabic_Script; | 1021 | run.flags.script = arabic_Script; |
@@ -1015,12 +1024,22 @@ static void prepare_AttributedText_(iAttributedText *d, int overrideBaseDir, iCh | |||
1015 | #endif | 1024 | #endif |
1016 | { | 1025 | { |
1017 | const char *scr = script_Char(ch); | 1026 | const char *scr = script_Char(ch); |
1027 | // printf("Char %08x %lc => %s\n", ch, (int) ch, scr); | ||
1018 | if (!iCmpStr(scr, "Bengali")) { | 1028 | if (!iCmpStr(scr, "Bengali")) { |
1019 | run.flags.script = bengali_Script; | 1029 | run.flags.script = bengali_Script; |
1020 | } | 1030 | } |
1021 | else if (!iCmpStr(scr, "Devanagari")) { | 1031 | else if (!iCmpStr(scr, "Devanagari")) { |
1022 | run.flags.script = devanagari_Script; | 1032 | run.flags.script = devanagari_Script; |
1023 | } | 1033 | } |
1034 | else if (!iCmpStr(scr, "Han")) { | ||
1035 | run.flags.script = han_Script; | ||
1036 | } | ||
1037 | else if (!iCmpStr(scr, "Hiragana")) { | ||
1038 | run.flags.script = hiragana_Script; | ||
1039 | } | ||
1040 | else if (!iCmpStr(scr, "Katakana")) { | ||
1041 | run.flags.script = katakana_Script; | ||
1042 | } | ||
1024 | else if (!iCmpStr(scr, "Oriya")) { | 1043 | else if (!iCmpStr(scr, "Oriya")) { |
1025 | run.flags.script = oriya_Script; | 1044 | run.flags.script = oriya_Script; |
1026 | } | 1045 | } |
@@ -1538,8 +1557,11 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) { | |||
1538 | const float xOffset = run->font->xScale * buf->glyphPos[i].x_offset; | 1557 | const float xOffset = run->font->xScale * buf->glyphPos[i].x_offset; |
1539 | const float xAdvance = run->font->xScale * buf->glyphPos[i].x_advance; | 1558 | const float xAdvance = run->font->xScale * buf->glyphPos[i].x_advance; |
1540 | const iChar ch = logicalText[logPos]; | 1559 | const iChar ch = logicalText[logPos]; |
1560 | const enum iWrapTextMode wrapMode = isCJK_Script_(run->flags.script) | ||
1561 | ? anyCharacter_WrapTextMode | ||
1562 | : args->wrap->mode; | ||
1541 | iAssert(xAdvance >= 0); | 1563 | iAssert(xAdvance >= 0); |
1542 | if (args->wrap->mode == word_WrapTextMode) { | 1564 | if (wrapMode == word_WrapTextMode) { |
1543 | /* When word wrapping, only consider certain places breakable. */ | 1565 | /* When word wrapping, only consider certain places breakable. */ |
1544 | if ((prevCh == '-' || prevCh == '/') && !isPunct_Char(ch)) { | 1566 | if ((prevCh == '-' || prevCh == '/') && !isPunct_Char(ch)) { |
1545 | safeBreakPos = logPos; | 1567 | safeBreakPos = logPos; |
@@ -1584,7 +1606,7 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) { | |||
1584 | wrapPosRange.end = safeBreakPos; | 1606 | wrapPosRange.end = safeBreakPos; |
1585 | } | 1607 | } |
1586 | else { | 1608 | else { |
1587 | if (args->wrap->mode == word_WrapTextMode && run->logical.start > wrapPosRange.start) { | 1609 | if (wrapMode == word_WrapTextMode && run->logical.start > wrapPosRange.start) { |
1588 | /* Don't have a word break position, so the whole run needs | 1610 | /* Don't have a word break position, so the whole run needs |
1589 | to be cut. */ | 1611 | to be cut. */ |
1590 | wrapPosRange.end = run->logical.start; | 1612 | wrapPosRange.end = run->logical.start; |
@@ -1598,7 +1620,7 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) { | |||
1598 | breakRunIndex = runIndex; | 1620 | breakRunIndex = runIndex; |
1599 | } | 1621 | } |
1600 | wrapResumePos = wrapPosRange.end; | 1622 | wrapResumePos = wrapPosRange.end; |
1601 | if (args->wrap->mode != anyCharacter_WrapTextMode) { | 1623 | if (wrapMode != anyCharacter_WrapTextMode) { |
1602 | while (wrapResumePos < textLen && isSpace_Char(logicalText[wrapResumePos])) { | 1624 | while (wrapResumePos < textLen && isSpace_Char(logicalText[wrapResumePos])) { |
1603 | wrapResumePos++; /* skip space */ | 1625 | wrapResumePos++; /* skip space */ |
1604 | } | 1626 | } |
@@ -1737,12 +1759,13 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) { | |||
1737 | /* Already handled this part of the run. */ | 1759 | /* Already handled this part of the run. */ |
1738 | continue; | 1760 | continue; |
1739 | } | 1761 | } |
1740 | const float xOffset = run->font->xScale * buf->glyphPos[i].x_offset; | 1762 | const float xOffset = run->font->xScale * buf->glyphPos[i].x_offset; |
1741 | const float yOffset = run->font->yScale * buf->glyphPos[i].y_offset; | 1763 | float yOffset = run->font->yScale * buf->glyphPos[i].y_offset; |
1742 | const float xAdvance = run->font->xScale * buf->glyphPos[i].x_advance; | 1764 | const float xAdvance = run->font->xScale * buf->glyphPos[i].x_advance; |
1743 | const float yAdvance = run->font->yScale * buf->glyphPos[i].y_advance; | 1765 | const float yAdvance = run->font->yScale * buf->glyphPos[i].y_advance; |
1744 | const iGlyph *glyph = glyphByIndex_Font_(run->font, glyphId); | 1766 | const iGlyph *glyph = glyphByIndex_Font_(run->font, glyphId); |
1745 | if (logicalText[logPos] == '\t') { | 1767 | const iChar ch = logicalText[logPos]; |
1768 | if (ch == '\t') { | ||
1746 | #if 0 | 1769 | #if 0 |
1747 | if (mode & draw_RunMode) { | 1770 | if (mode & draw_RunMode) { |
1748 | /* Tab indicator. */ | 1771 | /* Tab indicator. */ |
@@ -1761,6 +1784,13 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) { | |||
1761 | } | 1784 | } |
1762 | const float xf = xCursor + xOffset; | 1785 | const float xf = xCursor + xOffset; |
1763 | const int hoff = enableHalfPixelGlyphs_Text ? (xf - ((int) xf) > 0.5f ? 1 : 0) : 0; | 1786 | const int hoff = enableHalfPixelGlyphs_Text ? (xf - ((int) xf) > 0.5f ? 1 : 0) : 0; |
1787 | if (ch == 0x3001 || ch == 0x3002) { | ||
1788 | /* Vertical misalignment?? */ | ||
1789 | if (yOffset == 0.0f) { | ||
1790 | /* Move down to baseline. Why doesn't HarfBuzz do this? */ | ||
1791 | yOffset = glyph->d[hoff].y + glyph->rect[hoff].size.y + glyph->d[hoff].y / 4; | ||
1792 | } | ||
1793 | } | ||
1764 | /* Output position for the glyph. */ | 1794 | /* Output position for the glyph. */ |
1765 | SDL_Rect dst = { orig.x + xCursor + xOffset + glyph->d[hoff].x, | 1795 | SDL_Rect dst = { orig.x + xCursor + xOffset + glyph->d[hoff].x, |
1766 | orig.y + yCursor - yOffset + glyph->font->baseline + glyph->d[hoff].y, | 1796 | orig.y + yCursor - yOffset + glyph->font->baseline + glyph->d[hoff].y, |