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);
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
);
61 int *pos
= ren_position(s
);
62 int ret
= n
? pos
[n
- 1] : 0;
67 /* find the next character after visual position p; if cur start from p itself */
68 static int pos_next(int *pos
, int n
, int p
, int cur
)
71 for (i
= 0; i
< n
; i
++)
72 if (pos
[i
] - !cur
>= p
&& (ret
< 0 || pos
[i
] < pos
[ret
]))
74 return ret
>= 0 ? pos
[ret
] : -1;
77 /* find the previous character after visual position p; if cur start from p itself */
78 static int pos_prev(int *pos
, int n
, int p
, int cur
)
81 for (i
= 0; i
< n
; i
++)
82 if (pos
[i
] + !cur
<= p
&& (ret
< 0 || pos
[i
] > pos
[ret
]))
84 return ret
>= 0 ? pos
[ret
] : -1;
87 /* convert visual position to character offset */
88 int ren_pos(char *s
, int off
)
91 int *pos
= ren_position(s
);
92 int ret
= off
< n
? pos
[off
] : 0;
97 /* convert visual position to character offset */
98 int ren_off(char *s
, int p
)
102 int *pos
= ren_position(s
);
104 p
= pos_prev(pos
, n
, p
, 1);
105 for (i
= 0; i
< n
; i
++)
109 return off
>= 0 ? off
: 0;
112 /* adjust cursor position */
113 int ren_cursor(char *s
, int p
)
120 pos
= ren_position(s
);
121 p
= pos_prev(pos
, n
, p
, 1);
122 next
= pos_next(pos
, n
, p
, 0);
123 p
= (next
>= 0 ? next
: pos
[n
]) - 1;
125 return p
>= 0 ? p
: 0;
128 /* the position of the next character */
129 int ren_next(char *s
, int p
, int dir
)
132 int *pos
= ren_position(s
);
133 p
= pos_prev(pos
, n
, p
, 1);
135 p
= pos_next(pos
, n
, p
, 0);
137 p
= pos_prev(pos
, n
, p
, 0);
142 static void swap(int *i1
, int *i2
)
149 /* the region specified by two visual positions */
150 int ren_region(char *s
, int c1
, int c2
, int *l1
, int *l2
, int closed
)
152 int *ord
; /* ord[i]: the order of the i-th char on the screen */
157 if (c1
== c2
&& !closed
) {
158 *l1
= ren_off(s
, c1
);
159 *l2
= ren_off(s
, c2
);
162 ord
= malloc(n
* sizeof(ord
[0]));
163 for (i
= 0; i
< n
; i
++)
170 c2
= ren_next(s
, c2
, -1);
171 beg
= ren_off(s
, c1
);
172 end
= ren_off(s
, c2
);
179 for (i
= beg
; i
<= end
; i
++)
180 if (ord
[i
] < o1
|| ord
[i
] > o2
)