annotate lib/unilbrk/u16-width-linebreaks.c @ 40057:b06060465f09

maint: Run 'make update-copyright'
author Paul Eggert <eggert@cs.ucla.edu>
date Tue, 01 Jan 2019 00:25:11 +0100
parents 10eb9086bea0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
10041
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1 /* Line breaking of UTF-16 strings.
40057
b06060465f09 maint: Run 'make update-copyright'
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
2 Copyright (C) 2001-2003, 2006-2019 Free Software Foundation, Inc.
10041
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
3 Written by Bruno Haible <bruno@clisp.org>, 2001.
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
4
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
5 This program is free software: you can redistribute it and/or modify it
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
6 under the terms of the GNU Lesser General Public License as published
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
7 by the Free Software Foundation; either version 3 of the License, or
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8 (at your option) any later version.
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10 This program is distributed in the hope that it will be useful,
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13 Lesser General Public License for more details.
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
14
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
15 You should have received a copy of the GNU Lesser General Public License
19190
9759915b2aca all: prefer https: URLs
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
10041
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
17
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
18 #include <config.h>
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20 /* Specification. */
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21 #include "unilbrk.h"
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
22
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
23 #include "unistr.h"
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
24 #include "uniwidth.h"
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
25
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
26 int
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
27 u16_width_linebreaks (const uint16_t *s, size_t n,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
28 int width, int start_column, int at_end_columns,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
29 const char *o, const char *encoding,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
30 char *p)
10041
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
31 {
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
32 const uint16_t *s_end;
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
33 char *last_p;
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
34 int last_column;
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
35 int piece_width;
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
36
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
37 u16_possible_linebreaks (s, n, encoding, p);
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
38
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
39 s_end = s + n;
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
40 last_p = NULL;
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
41 last_column = start_column;
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
42 piece_width = 0;
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
43 while (s < s_end)
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
44 {
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
45 ucs4_t uc;
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
46 int count = u16_mbtouc_unsafe (&uc, s, s_end - s);
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
47
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
48 /* Respect the override. */
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
49 if (o != NULL && *o != UC_BREAK_UNDEFINED)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
50 *p = *o;
10041
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
51
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
52 if (*p == UC_BREAK_POSSIBLE || *p == UC_BREAK_MANDATORY)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
53 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
54 /* An atomic piece of text ends here. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
55 if (last_p != NULL && last_column + piece_width > width)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
56 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
57 /* Insert a line break. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
58 *last_p = UC_BREAK_POSSIBLE;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
59 last_column = 0;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
60 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
61 }
10041
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
62
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
63 if (*p == UC_BREAK_MANDATORY)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
64 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
65 /* uc is a line break character. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
66 /* Start a new piece at column 0. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
67 last_p = NULL;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
68 last_column = 0;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
69 piece_width = 0;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
70 }
10041
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
71 else
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
72 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
73 /* uc is not a line break character. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
74 int w;
10041
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
75
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
76 if (*p == UC_BREAK_POSSIBLE)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
77 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
78 /* Start a new piece. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
79 last_p = p;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
80 last_column += piece_width;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
81 piece_width = 0;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
82 /* No line break for the moment, may be turned into
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
83 UC_BREAK_POSSIBLE later, via last_p. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
84 }
10041
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
85
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
86 *p = UC_BREAK_PROHIBITED;
10041
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
87
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
88 w = uc_width (uc, encoding);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
89 if (w >= 0) /* ignore control characters in the string */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
90 piece_width += w;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
91 }
10041
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
92
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
93 s += count;
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
94 p += count;
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
95 if (o != NULL)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10041
diff changeset
96 o += count;
10041
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
97 }
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
98
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
99 /* The last atomic piece of text ends here. */
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
100 if (last_p != NULL && last_column + piece_width + at_end_columns > width)
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
101 {
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
102 /* Insert a line break. */
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
103 *last_p = UC_BREAK_POSSIBLE;
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
104 last_column = 0;
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
105 }
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
106
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
107 return last_column + piece_width;
db1d8acdb9c1 Split up the 'linebreak' module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
108 }