1 /* rendering strings */
8 /* specify the screen position of the characters in s */
9 int *ren_position(char *s
)
12 char **chrs
= uc_chop(s
, &n
);
15 pos
= malloc((n
+ 1) * sizeof(pos
[0]));
16 for (i
= 0; i
< n
; i
++)
20 off
= malloc(n
* sizeof(off
[0]));
21 for (i
= 0; i
< n
; i
++)
23 for (i
= 0; i
< n
; i
++) {
25 cpos
+= ren_cwid(chrs
[off
[i
]], cpos
);
35 int *pos
= ren_position(s
);
42 /* find the next character after visual position p; if cur, start from p itself */
43 static int pos_next(int *pos
, int n
, int p
, int cur
)
46 for (i
= 0; i
< n
; i
++)
47 if (pos
[i
] - !cur
>= p
&& (ret
< 0 || pos
[i
] < pos
[ret
]))
49 return ret
>= 0 ? pos
[ret
] : -1;
52 /* find the previous character after visual position p; if cur, start from p itself */
53 static int pos_prev(int *pos
, int n
, int p
, int cur
)
56 for (i
= 0; i
< n
; i
++)
57 if (pos
[i
] + !cur
<= p
&& (ret
< 0 || pos
[i
] > pos
[ret
]))
59 return ret
>= 0 ? pos
[ret
] : -1;
62 /* convert character offset to visual position */
63 int ren_pos(char *s
, int off
)
66 int *pos
= ren_position(s
);
67 int ret
= off
< n
? pos
[off
] : 0;
72 /* convert visual position to character offset */
73 int ren_off(char *s
, int p
)
77 int *pos
= ren_position(s
);
79 p
= pos_prev(pos
, n
, p
, 1);
80 for (i
= 0; i
< n
; i
++)
84 return off
>= 0 ? off
: 0;
87 /* adjust cursor position */
88 int ren_cursor(char *s
, int p
)
95 pos
= ren_position(s
);
96 p
= pos_prev(pos
, n
, p
, 1);
97 if (uc_code(uc_chr(s
, ren_off(s
, p
))) == '\n')
98 p
= pos_prev(pos
, n
, p
, 0);
99 next
= pos_next(pos
, n
, p
, 0);
100 p
= (next
>= 0 ? next
: pos
[n
]) - 1;
102 return p
>= 0 ? p
: 0;
105 /* return an offset before EOL */
106 int ren_noeol(char *s
, int o
)
108 int n
= s
? uc_slen(s
) : 0;
111 return o
> 0 && uc_chr(s
, o
)[0] == '\n' ? o
- 1 : o
;
114 /* the position of the next character */
115 int ren_next(char *s
, int p
, int dir
)
118 int *pos
= ren_position(s
);
119 p
= pos_prev(pos
, n
, p
, 1);
121 p
= pos_next(pos
, n
, p
, 0);
123 p
= pos_prev(pos
, n
, p
, 0);
125 return s
&& uc_chr(s
, ren_off(s
, p
))[0] != '\n' ? p
: -1;
128 static char *ren_placeholder(char *s
)
133 for (i
= 0; !conf_placeholder(i
, &src
, &dst
, &wid
); i
++)
134 if (uc_code(src
) == c
)
139 memcpy(cbuf
, s
, uc_len(s
));
140 sprintf(buf
, "ـ%s", cbuf
);
148 int ren_cwid(char *s
, int pos
)
153 return 8 - (pos
& 7);
154 for (i
= 0; !conf_placeholder(i
, &src
, &dst
, &wid
); i
++)
155 if (uc_code(src
) == uc_code(s
))
160 char *ren_translate(char *s
, char *ln
)
162 char *p
= ren_placeholder(s
);
163 return p
|| !xshape
? p
: uc_shape(ln
, s
);