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
++)
19 off
= malloc(n
* sizeof(off
[0]));
20 for (i
= 0; i
< n
; i
++)
22 for (i
= 0; i
< n
; i
++) {
25 diff
+= 8 - (pos
[off
[i
]] & 7) - 1;
35 int *pos
= ren_position(s
);
42 char *ren_translate(char *s
)
44 struct sbuf
*sb
= sbuf_make();
47 char *c
= uc_shape(s
, r
);
58 /* find the next character after visual position p; if cur start from p itself */
59 static int pos_next(int *pos
, int n
, int p
, int cur
)
62 for (i
= 0; i
< n
; i
++)
63 if (pos
[i
] - !cur
>= p
&& (ret
< 0 || pos
[i
] < pos
[ret
]))
65 return ret
>= 0 ? pos
[ret
] : -1;
68 /* find the previous character after visual position p; if cur start from p itself */
69 static int pos_prev(int *pos
, int n
, int p
, int cur
)
72 for (i
= 0; i
< n
; i
++)
73 if (pos
[i
] + !cur
<= p
&& (ret
< 0 || pos
[i
] > pos
[ret
]))
75 return ret
>= 0 ? pos
[ret
] : -1;
78 /* convert visual position to character offset */
79 int ren_pos(char *s
, int off
)
82 int *pos
= ren_position(s
);
83 int ret
= off
< n
? pos
[off
] : 0;
88 /* convert visual position to character offset */
89 int ren_off(char *s
, int p
)
93 int *pos
= ren_position(s
);
95 p
= pos_prev(pos
, n
, p
, 1);
96 for (i
= 0; i
< n
; i
++)
100 return off
>= 0 ? off
: 0;
103 /* adjust cursor position */
104 int ren_cursor(char *s
, int p
)
111 pos
= ren_position(s
);
112 p
= pos_prev(pos
, n
, p
, 1);
113 next
= pos_next(pos
, n
, p
, 0);
114 p
= (next
>= 0 ? next
: pos
[n
]) - 1;
116 return p
>= 0 ? p
: 0;
119 /* the position of the next character */
120 int ren_next(char *s
, int p
, int dir
)
123 int *pos
= ren_position(s
);
124 p
= pos_prev(pos
, n
, p
, 1);
126 p
= pos_next(pos
, n
, p
, 0);
128 p
= pos_prev(pos
, n
, p
, 0);
133 static void swap(int *i1
, int *i2
)
140 /* the region specified by two visual positions */
141 int ren_region(char *s
, int c1
, int c2
, int *l1
, int *l2
, int closed
)
143 int *ord
; /* ord[i]: the order of the i-th char on the screen */
148 if (c1
== c2
&& !closed
) {
149 *l1
= ren_off(s
, c1
);
150 *l2
= ren_off(s
, c2
);
153 ord
= malloc(n
* sizeof(ord
[0]));
154 for (i
= 0; i
< n
; i
++)
161 c2
= ren_next(s
, c2
, -1);
162 beg
= ren_off(s
, c1
);
163 end
= ren_off(s
, c2
);
170 for (i
= beg
; i
<= end
; i
++)
171 if (ord
[i
] < o1
|| ord
[i
] > o2
)