Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/mintty/mintty
Browse files Browse the repository at this point in the history
  • Loading branch information
paolo-sz committed Apr 23, 2019
2 parents d2d8a57 + f5f08a7 commit 5a9c340
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 105 deletions.
28 changes: 0 additions & 28 deletions COPYING

This file was deleted.

30 changes: 28 additions & 2 deletions src/minibidi.c
Original file line number Diff line number Diff line change
Expand Up @@ -507,9 +507,11 @@ do_bidi(bool autodir, int paragraphLevel, bool explicitRTL, bool box_mirror,
int i, j;

uchar bidi_class_of(int i) {
ucschar c = line[i].wc;

#ifdef try_to_handle_CJK_here
#warning does not always work in RTL mode, now filtered before calling do_bidi
if (i && line[i].wc == UCSWIDE) {
if (i && c == UCSWIDE) {
// try to fix double-width within right-to-left
if (currentEmbedding & 1)
i--;
Expand All @@ -520,9 +522,23 @@ do_bidi(bool autodir, int paragraphLevel, bool explicitRTL, bool box_mirror,
// not displayed in RTL: U+FF1C (class default -> ON)
}
#endif

#ifdef check_emoji
if (c == 0x200D
|| (c >= 0x2600 && c < 0x2800)
|| (c >= 0x1F300 && c < 0x20000)
)
return EN;
#endif
#ifdef check_emojilen
if (line[i].emojilen)
return EN;
#endif

if (explicitRTL)
return R;
return bidi_class(line[i].wc);

return bidi_class(c);
}

/* Rule (P1) NOT IMPLEMENTED
Expand Down Expand Up @@ -1276,6 +1292,16 @@ do_bidi(bool autodir, int paragraphLevel, bool explicitRTL, bool box_mirror,
// (3)
for (i = 0; i < count; i++) {
tempType = bidi_class_of(i);
#ifdef check_emojiseq
if (line[i].emojilen) {
// raise emoji sequence to LTR level, as a rough approximation of
// HL3. Emulate explicit directional formatting characters.
for (j = i; j < i + line[i].emojilen && j < count && line[j].emojilen; j++) {
levels[j] = leastGreaterEven(levels[i]);
}
}
else
#endif
if (tempType == WS) {
j = i;
while (j < count && (bidi_class_of(j) == WS || skip[j])) {
Expand Down
1 change: 1 addition & 0 deletions src/minibidi.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ typedef struct {
ucschar origwc, wc;
short index;
bool wide;
uchar emojilen: 7;
} bidi_char;

int do_bidi(bool autodir, int para_level, bool explicitRTL, bool box_mirror, bidi_char * line, int count);
Expand Down
141 changes: 77 additions & 64 deletions src/term.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ term_reset(struct term* term, bool full)
term->tabs[i] = (i % 8 == 0);
}
if (full) {
term->newtab = 1; // set default tabs on resize
term->rvideo = 0; // not reset by xterm
term->bell_taskbar = cfg.bell_taskbar; // not reset by xterm
term->bell_popup = cfg.bell_popup; // not reset by xterm
Expand Down Expand Up @@ -993,7 +994,7 @@ term_resize(struct term* term, int newrows, int newcols)
// Reset tab stops
term->tabs = renewn(term->tabs, newcols);
for (int i = (term->cols > 0 ? term->cols : 0); i < newcols; i++)
term->tabs[i] = (i % 8 == 0);
term->tabs[i] = term->newtab && (i % 8 == 0);

// Check that the cursor positions are still valid.
assert(0 <= curs->y && curs->y < newrows);
Expand Down Expand Up @@ -1803,9 +1804,83 @@ term_paint(struct term* term)
for (int i = 0; i < term->rows; i++) {
pos scrpos;
scrpos.y = i + term->disptop;
termline *line = fetch_line(term, scrpos.y);

/*
* Pre-loop: identify emojis and emoji sequences.
*/
// Prevent nested emoji sequence matching from matching partial subseqs
int emoji_col = 0; // column from which to match for emoji sequences
for (int j = 0; j < term->cols; j++) {
termchar *d = line->chars + j;
cattr tattr = d->attr;

if (j < term->cols - 1 && d[1].chr == UCSWIDE)
tattr.attr |= ATTR_WIDE;

/* Match emoji sequences
* and replace by emoji indicators
*/
if (cfg.emojis && j >= emoji_col) {
struct emoji e;
if ((tattr.attr & TATTR_EMOJI) && !(tattr.attr & ATTR_FGMASK)) {
// previously marked subsequent emoji sequence component
e.len = 0;
}
else
e = match_emoji(d, term->cols - j);
if (e.len) { // we have matched an emoji (sequence)
// avoid subsequent matching of a partial emoji subsequence
emoji_col = j + e.len;

// check whether emoji graphics exist for the emoji
bool ok = check_emoji(e);

// check whether all emoji components have the same attributes
bool equalattrs = true;
for (int i = 1; i < e.len && equalattrs; i++) {
# define IGNATTR (ATTR_WIDE | ATTR_FGMASK | TATTR_COMBINING)
if ((d[i].attr.attr & ~IGNATTR) != (d->attr.attr & ~IGNATTR)
|| d[i].attr.truebg != d->attr.truebg
)
equalattrs = false;
}
#ifdef debug_emojis
printf("matched len %d seq %d idx %d ok %d atr %d\n", e.len, e.seq, e.idx, ok, equalattrs);
#endif

// modify character data to trigger later emoji display
if (ok && equalattrs) {
d->attr.attr &= ~ATTR_FGMASK;
d->attr.attr |= TATTR_EMOJI | e.len;

//d->attr.truefg = (uint)e;
struct emoji * ee = &e;
uint em = *(uint *)ee;
d->attr.truefg = em;

// refresh cached copy to avoid display delay
if (tattr.attr & TATTR_SELECTED) {
tattr = d->attr;
// need to propagate this to enable emoji highlighting
tattr.attr |= TATTR_SELECTED;
}
else
tattr = d->attr;
// inhibit rendering of subsequent emoji sequence components
for (int i = 1; i < e.len; i++) {
d[i].attr.attr &= ~ATTR_FGMASK;
d[i].attr.attr |= TATTR_EMOJI;
d[i].attr.truefg = em;
}
}
}
}

d->attr = tattr;
}

/* Do Arabic shaping and bidi. */
termline *line = fetch_line(term, scrpos.y);
termchar *chars = term_bidi_line(term, line, i);
int *backward = chars ? term->post_bidi_cache[i].backward : 0;
int *forward = chars ? term->post_bidi_cache[i].forward : 0;
Expand All @@ -1815,9 +1890,6 @@ term_paint(struct term* term)
termchar *dispchars = displine->chars;
termchar newchars[term->cols];

// Prevent nested emoji sequence matching from matching partial subseqs
int emoji_col = 0; // column from which to match for emoji sequences

/*
* First loop: work along the line deciding what we want
* each character cell to look like.
Expand Down Expand Up @@ -1930,65 +2002,6 @@ term_paint(struct term* term)
tattr.attr &= ~ATTR_BLINK2;
}

/* Match emoji sequences
* and replace by emoji indicators
*/
if (cfg.emojis && j >= emoji_col) {
struct emoji e;
if ((tattr.attr & TATTR_EMOJI) && !(tattr.attr & ATTR_FGMASK)) {
// previously marked subsequent emoji sequence component
e.len = 0;
}
else
e = match_emoji(d, term->cols - j);
if (e.len) { // we have matched an emoji (sequence)
// avoid subsequent matching of a partial emoji subsequence
emoji_col = j + e.len;

// check whether emoji graphics exist for the emoji
bool ok = check_emoji(e);

// check whether all emoji components have the same attributes
bool equalattrs = true;
for (int i = 1; i < e.len && equalattrs; i++) {
# define IGNATTR (ATTR_WIDE | ATTR_FGMASK | TATTR_COMBINING)
if ((d[i].attr.attr & ~IGNATTR) != (d->attr.attr & ~IGNATTR)
|| d[i].attr.truebg != d->attr.truebg
)
equalattrs = false;
}
#ifdef debug_emojis
printf("matched len %d seq %d idx %d ok %d atr %d\n", e.len, e.seq, e.idx, ok, equalattrs);
#endif

// modify character data to trigger later emoji display
if (ok && equalattrs) {
d->attr.attr &= ~ATTR_FGMASK;
d->attr.attr |= TATTR_EMOJI | e.len;

//d->attr.truefg = (uint)e;
struct emoji * ee = &e;
uint em = *(uint *)ee;
d->attr.truefg = em;

// refresh cached copy to avoid display delay
if (tattr.attr & TATTR_SELECTED) {
tattr = d->attr;
// need to propagate this to enable emoji highlighting
tattr.attr |= TATTR_SELECTED;
}
else
tattr = d->attr;
// inhibit rendering of subsequent emoji sequence components
for (int i = 1; i < e.len; i++) {
d[i].attr.attr &= ~ATTR_FGMASK;
d[i].attr.attr |= TATTR_EMOJI;
d[i].attr.truefg = em;
}
}
}
}

/* Mark box drawing, block and some other characters
* that should connect to their neighbour cells and thus
* be zoomed to the actual cell size including spacing (padding);
Expand Down
1 change: 1 addition & 0 deletions src/term.h
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,7 @@ struct term {
int dcs_cmd;

uchar *tabs;
bool newtab;

enum {
NORMAL, ESCAPE, CSI_ARGS,
Expand Down
Loading

0 comments on commit 5a9c340

Please sign in to comment.