int main () { /* Test case n = 0. */ u16_possible_linebreaks (NULL, 0, "GB18030", NULL); { static const uint16_t input[61] = /* "Grüß Gott. Здравствуйте! x=(-b±sqrt(b²-4ac))/(2a) 日本語,中文,한글" */ { 'G', 'r', 0x00FC, 0x00DF, ' ', 'G', 'o', 't', 't', '.', ' ', 0x0417, 0x0434, 0x0440, 0x0430, 0x0432, 0x0441, 0x0442, 0x0432, 0x0443, 0x0439, 0x0442, 0x0435, '!', ' ', 'x', '=', '(', '-', 'b', 0x00B1, 's', 'q', 'r', 't', '(', 'b', 0x00B2, '-', '4', 'a', 'c', ')', ')', '/', '(', '2', 'a', ')', ' ', ' ', 0x65E5, 0x672C, 0x8A9E, ',', 0x4E2D, 0x6587, ',', 0xD55C, 0xAE00, '\n' }; { char *p = (char *) malloc (SIZEOF (input)); size_t i; u16_possible_linebreaks (input, SIZEOF (input), "GB18030", p); for (i = 0; i < 61; i++) { ASSERT (p[i] == (i == 60 ? UC_BREAK_MANDATORY : i == 5 || i == 11 || i == 25 || i == 27 || i == 29 || i == 30 || i == 35 || i == 45 || i == 51 || i == 52 || i == 53 || i == 55 || i == 56 || i == 58 || i == 59 ? UC_BREAK_POSSIBLE : UC_BREAK_PROHIBITED)); } free (p); } { char *p = (char *) malloc (SIZEOF (input)); size_t i; u16_possible_linebreaks (input, SIZEOF (input), "GB2312", p); for (i = 0; i < 61; i++) { ASSERT (p[i] == (i == 60 ? UC_BREAK_MANDATORY : i == 5 || i == 11 || i == 25 || i == 27 || i == 29 || i == 30 || i == 35 || i == 37 || i == 45 || i == 51 || i == 52 || i == 53 || i == 55 || i == 56 || i == 58 || i == 59 ? UC_BREAK_POSSIBLE : UC_BREAK_PROHIBITED)); } free (p); } } return 0; }
int u16_width_linebreaks (const uint16_t *s, size_t n, int width, int start_column, int at_end_columns, const char *o, const char *encoding, char *p) { const uint16_t *s_end; char *last_p; int last_column; int piece_width; u16_possible_linebreaks (s, n, encoding, p); s_end = s + n; last_p = NULL; last_column = start_column; piece_width = 0; while (s < s_end) { ucs4_t uc; int count = u16_mbtouc_unsafe (&uc, s, s_end - s); /* Respect the override. */ if (o != NULL && *o != UC_BREAK_UNDEFINED) *p = *o; if (*p == UC_BREAK_POSSIBLE || *p == UC_BREAK_MANDATORY) { /* An atomic piece of text ends here. */ if (last_p != NULL && last_column + piece_width > width) { /* Insert a line break. */ *last_p = UC_BREAK_POSSIBLE; last_column = 0; } } if (*p == UC_BREAK_MANDATORY) { /* uc is a line break character. */ /* Start a new piece at column 0. */ last_p = NULL; last_column = 0; piece_width = 0; } else { /* uc is not a line break character. */ int w; if (*p == UC_BREAK_POSSIBLE) { /* Start a new piece. */ last_p = p; last_column += piece_width; piece_width = 0; /* No line break for the moment, may be turned into UC_BREAK_POSSIBLE later, via last_p. */ } *p = UC_BREAK_PROHIBITED; w = uc_width (uc, encoding); if (w >= 0) /* ignore control characters in the string */ piece_width += w; } s += count; p += count; if (o != NULL) o += count; } /* The last atomic piece of text ends here. */ if (last_p != NULL && last_column + piece_width + at_end_columns > width) { /* Insert a line break. */ *last_p = UC_BREAK_POSSIBLE; last_column = 0; } return last_column + piece_width; }