1 /* Line breaking of UTF-16 strings.
2 Copyright (C) 2001-2003, 2006-2017 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2001.
5 This program is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Lesser General Public License as published
7 by the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
26 #include "unilbrk/lbrktables.h"
27 #include "uniwidth/cjk.h"
31 u16_possible_linebreaks (const uint16_t *s
, size_t n
, const char *encoding
, char *p
)
33 int LBP_AI_REPLACEMENT
= (is_cjk_encoding (encoding
) ? LBP_ID
: LBP_AL
);
34 const uint16_t *s_end
= s
+ n
;
35 int last_prop
= LBP_BK
; /* line break property of last non-space character */
36 char *seen_space
= NULL
; /* Was a space seen after the last non-space character? */
37 char *seen_space2
= NULL
; /* At least two spaces after the last non-space? */
39 /* Don't break inside multibyte characters. */
40 memset (p
, UC_BREAK_PROHIBITED
, n
);
45 int count
= u16_mbtouc_unsafe (&uc
, s
, s_end
- s
);
46 int prop
= unilbrkprop_lookup (uc
);
50 /* Mandatory break. */
51 *p
= UC_BREAK_MANDATORY
;
60 /* Resolve property values whose behaviour is not fixed. */
64 /* Resolve ambiguous. */
65 prop
= LBP_AI_REPLACEMENT
;
68 /* This is arbitrary. */
72 /* We don't handle complex scripts yet.
73 Treat LBP_SA like LBP_XX. */
75 /* This is arbitrary. */
80 /* Deal with spaces and combining characters. */
84 /* Don't break just before a space. */
85 *p
= UC_BREAK_PROHIBITED
;
86 seen_space2
= seen_space
;
89 else if (prop
== LBP_ZW
)
91 /* Don't break just before a zero-width space. */
92 *p
= UC_BREAK_PROHIBITED
;
97 else if (prop
== LBP_CM
)
99 /* Don't break just before a combining character, except immediately after a
101 if (last_prop
== LBP_ZW
)
103 /* Break after zero-width space. */
104 *p
= UC_BREAK_POSSIBLE
;
105 /* A combining character turns a preceding space into LBP_ID. */
110 *p
= UC_BREAK_PROHIBITED
;
111 /* A combining character turns a preceding space into LBP_ID. */
112 if (seen_space
!= NULL
)
115 seen_space
= seen_space2
;
117 goto lookup_via_table
;
124 /* prop must be usable as an index for table 7.3 of UTR #14. */
125 if (!(prop
>= 0 && prop
< sizeof (unilbrk_table
) / sizeof (unilbrk_table
[0])))
128 if (last_prop
== LBP_BK
)
130 /* Don't break at the beginning of a line. */
131 *q
= UC_BREAK_PROHIBITED
;
133 else if (last_prop
== LBP_ZW
)
135 /* Break after zero-width space. */
136 *q
= UC_BREAK_POSSIBLE
;
140 switch (unilbrk_table
[last_prop
] [prop
])
143 *q
= UC_BREAK_POSSIBLE
;
146 *q
= (seen_space
!= NULL
? UC_BREAK_POSSIBLE
: UC_BREAK_PROHIBITED
);
149 *q
= UC_BREAK_PROHIBITED
;