GFXprim
2D bitmap graphics library with emphasis on speed and correctness
Loading...
Searching...
No Matches
gp_utf_pos.h
Go to the documentation of this file.
1// SPDX-License-Identifier: LGPL-2.1-or-later
2/*
3 * Copyright (C) 2022 Cyril Hrubis <metan@ucw.cz>
4 */
5
14#ifndef UTILS_GP_UTF_POS_H
15#define UTILS_GP_UTF_POS_H
16
17#include <utils/gp_utf.h>
18#include <stdint.h>
19#include <stddef.h>
20#include <unistd.h>
21
25typedef struct gp_utf8_pos {
27 size_t bytes;
29 size_t chars;
31
37static inline gp_utf8_pos gp_utf8_pos_first(void)
38{
39 return (gp_utf8_pos){0, 0};
40}
41
51static inline gp_utf8_pos gp_utf8_pos_last(const char *str)
52{
53 gp_utf8_pos ret = {0, 0};
54
55 for (;;) {
56 int8_t chsz = gp_utf8_next_chsz(str, ret.bytes);
57
58 if (chsz <= 0)
59 return ret;
60
61 ret.bytes += chsz;
62 ret.chars++;
63 }
64}
65
73static inline int gp_utf8_pos_at_end(const char *str, gp_utf8_pos pos)
74{
75 return !str[pos.bytes];
76}
77
84static inline int gp_utf8_pos_at_home(gp_utf8_pos pos)
85{
86 return !pos.bytes;
87}
88
96static inline int gp_utf8_pos_eq(gp_utf8_pos a, gp_utf8_pos b)
97{
98 return a.bytes == b.bytes;
99}
100
109{
110 return a.bytes > b.bytes;
111}
112
121{
122 return a.bytes >= b.bytes;
123}
124
133{
134 gp_utf8_pos res = {
135 .bytes = a.bytes - b.bytes,
136 .chars = a.chars - b.chars,
137 };
138
139 return res;
140}
141
150{
151 gp_utf8_pos res = {
152 .bytes = a.bytes + b.bytes,
153 .chars = a.chars + b.chars,
154 };
155
156 return res;
157}
158
167{
168 if (a.bytes < b.bytes)
169 return a;
170 else
171 return b;
172}
173
182{
183 if (a.bytes > b.bytes)
184 return a;
185 else
186 return b;
187}
188
200static inline ssize_t gp_utf8_pos_move(const char *str, gp_utf8_pos *cur_pos, ssize_t dir)
201{
202 ssize_t dirs = dir;
203
204 if (dir > 0) {
205 while (dir > 0) {
206 int8_t chsz = gp_utf8_next_chsz(str, cur_pos->bytes);
207
208 if (chsz <= 0)
209 return dirs - dir;
210
211 cur_pos->bytes += chsz;
212 cur_pos->chars++;
213
214 dir--;
215 }
216
217 return dirs;
218 }
219
220 if (dir < 0) {
221 while (dir < 0) {
222 int8_t chsz = gp_utf8_prev_chsz(str, cur_pos->bytes);
223
224 if (chsz <= 0)
225 return dir - dirs;
226
227 cur_pos->bytes -= chsz;
228 cur_pos->chars--;
229
230 dir++;
231 }
232
233 return -dirs;
234 }
235
236 return 0;
237}
238
249static inline uint32_t gp_utf8_pos_prev(const char *str, gp_utf8_pos *pos) {
250 int8_t chsz;
251
252 if (!pos->bytes)
253 return 0;
254
255 chsz = gp_utf8_prev_chsz(str, pos->bytes);
256 if (chsz <= 0)
257 return 0;
258
259 pos->bytes -= chsz;
260 pos->chars--;
261
262 str += pos->bytes;
263
264 return gp_utf8_next(&str);
265}
266
277static inline uint32_t gp_utf8_pos_next(const char *str, gp_utf8_pos *pos)
278{
279 int8_t chsz;
280
281 chsz = gp_utf8_next_chsz(str, pos->bytes);
282 if (chsz <= 0)
283 return 0;
284
285 str += pos->bytes;
286
287 pos->bytes += chsz;
288 pos->chars++;
289
290 return gp_utf8_next(&str);
291}
292
293#endif /* UTILS_GP_UTF_POS_H */
Unicode helper macros and functions.
static uint32_t gp_utf8_next(const char **str)
Parses next unicode character in UTF-8 string.
Definition gp_utf.h:35
int8_t gp_utf8_prev_chsz(const char *str, size_t off)
Returns number of bytes previous character is occupying in an UTF-8 string.
int8_t gp_utf8_next_chsz(const char *str, size_t off)
Returns number of bytes next character is occupying in an UTF-8 string.
static gp_utf8_pos gp_utf8_pos_add(gp_utf8_pos a, gp_utf8_pos b)
Adds two positions.
Definition gp_utf_pos.h:149
static uint32_t gp_utf8_pos_prev(const char *str, gp_utf8_pos *pos)
Moves a single character towards the string start and returns current character.
Definition gp_utf_pos.h:249
static gp_utf8_pos gp_utf8_pos_last(const char *str)
Moves the position to the end of the string.
Definition gp_utf_pos.h:51
static int gp_utf8_pos_gt(gp_utf8_pos a, gp_utf8_pos b)
Returns true if position a is greater than position b.
Definition gp_utf_pos.h:108
static int gp_utf8_pos_eq(gp_utf8_pos a, gp_utf8_pos b)
Returns true if two positions are equal.
Definition gp_utf_pos.h:96
static int gp_utf8_pos_at_home(gp_utf8_pos pos)
Returns true if the position points to the start of the string.
Definition gp_utf_pos.h:84
static ssize_t gp_utf8_pos_move(const char *str, gp_utf8_pos *cur_pos, ssize_t dir)
Moves a position in a string by dir characters.
Definition gp_utf_pos.h:200
static uint32_t gp_utf8_pos_next(const char *str, gp_utf8_pos *pos)
Moves a single character towards the string end and returns current character.
Definition gp_utf_pos.h:277
static int gp_utf8_pos_at_end(const char *str, gp_utf8_pos pos)
Returns true if the position points to the end of the string.
Definition gp_utf_pos.h:73
static gp_utf8_pos gp_utf8_pos_first(void)
Moves the position to the start of the string.
Definition gp_utf_pos.h:37
static int gp_utf8_pos_ge(gp_utf8_pos a, gp_utf8_pos b)
Returns true if position a is greater or equal to position b.
Definition gp_utf_pos.h:120
static gp_utf8_pos gp_utf8_pos_sub(gp_utf8_pos a, gp_utf8_pos b)
Substracts two positions.
Definition gp_utf_pos.h:132
static gp_utf8_pos gp_utf8_pos_max(gp_utf8_pos a, gp_utf8_pos b)
Returns bigger of two positions.
Definition gp_utf_pos.h:181
static gp_utf8_pos gp_utf8_pos_min(gp_utf8_pos a, gp_utf8_pos b)
Returns smaller of two positions.
Definition gp_utf_pos.h:166
Position in an UTF-8 string.
Definition gp_utf_pos.h:25
size_t bytes
Definition gp_utf_pos.h:27
size_t chars
Definition gp_utf_pos.h:29