Imported Upstream version 1.22.4
[platform/upstream/groff.git] / src / roff / troff / charinfo.h
1 // -*- C++ -*-
2 /* Copyright (C) 1989-2018 Free Software Foundation, Inc.
3      Written by James Clark (jjc@jclark.com)
4
5 This file is part of groff.
6
7 groff is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 groff is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program.  If not, see <http://www.gnu.org/licenses/>. */
19
20 #include <vector>
21 #include <utility>
22
23 extern int class_flag;  // set if there was a call to '.class'
24 extern void get_flags();
25
26 class macro;
27
28 class charinfo : glyph {
29   static int next_index;
30   charinfo *translation;
31   macro *mac;
32   unsigned char special_translation;
33   unsigned char hyphenation_code;
34   unsigned int flags;
35   unsigned char ascii_code;
36   unsigned char asciify_code;
37   char not_found;
38   char transparent_translate;   // non-zero means translation applies
39                                 // to transparent throughput
40   char translate_input;         // non-zero means that asciify_code is
41                                 // active for .asciify (set by .trin)
42   char_mode mode;
43   // Unicode character classes
44   std::vector<std::pair<int, int> > ranges;
45   std::vector<charinfo *> nested_classes;
46 public:
47   enum {                // Values for the flags bitmask.  See groff
48                         // manual, description of the '.cflags' request.
49     ENDS_SENTENCE = 0x01,
50     BREAK_BEFORE = 0x02,
51     BREAK_AFTER = 0x04,
52     OVERLAPS_HORIZONTALLY = 0x08,
53     OVERLAPS_VERTICALLY = 0x10,
54     TRANSPARENT = 0x20,
55     IGNORE_HCODES = 0x40,
56     DONT_BREAK_BEFORE = 0x80,
57     DONT_BREAK_AFTER = 0x100,
58     INTER_CHAR_SPACE = 0x200
59   };
60   enum {
61     TRANSLATE_NONE,
62     TRANSLATE_SPACE,
63     TRANSLATE_DUMMY,
64     TRANSLATE_STRETCHABLE_SPACE,
65     TRANSLATE_HYPHEN_INDICATOR
66   };
67   symbol nm;
68   charinfo(symbol);
69   glyph *as_glyph();
70   int ends_sentence();
71   int overlaps_vertically();
72   int overlaps_horizontally();
73   int can_break_before();
74   int can_break_after();
75   int transparent();
76   int ignore_hcodes();
77   int prohibit_break_before();
78   int prohibit_break_after();
79   int inter_char_space();
80   unsigned char get_hyphenation_code();
81   unsigned char get_ascii_code();
82   unsigned char get_asciify_code();
83   int get_unicode_code();
84   void set_hyphenation_code(unsigned char);
85   void set_ascii_code(unsigned char);
86   void set_asciify_code(unsigned char);
87   void set_translation_input();
88   int get_translation_input();
89   charinfo *get_translation(int = 0);
90   void set_translation(charinfo *, int, int);
91   void get_flags();
92   void set_flags(unsigned int);
93   void set_special_translation(int, int);
94   int get_special_translation(int = 0);
95   macro *set_macro(macro *);
96   macro *setx_macro(macro *, char_mode);
97   macro *get_macro();
98   int first_time_not_found();
99   void set_number(int);
100   int get_number();
101   int numbered();
102   int is_normal();
103   int is_fallback();
104   int is_special();
105   symbol *get_symbol();
106   void add_to_class(int);
107   void add_to_class(int, int);
108   void add_to_class(charinfo *);
109   bool is_class();
110   bool contains(int, bool = false);
111   bool contains(symbol, bool = false);
112   bool contains(charinfo *, bool = false);
113 };
114
115 charinfo *get_charinfo(symbol);
116 extern charinfo *charset_table[];
117 charinfo *get_charinfo_by_number(int);
118
119 inline int charinfo::overlaps_horizontally()
120 {
121   if (class_flag)
122     ::get_flags();
123   return flags & OVERLAPS_HORIZONTALLY;
124 }
125
126 inline int charinfo::overlaps_vertically()
127 {
128   if (class_flag)
129     ::get_flags();
130   return flags & OVERLAPS_VERTICALLY;
131 }
132
133 inline int charinfo::can_break_before()
134 {
135   if (class_flag)
136     ::get_flags();
137   return flags & BREAK_BEFORE;
138 }
139
140 inline int charinfo::can_break_after()
141 {
142   if (class_flag)
143     ::get_flags();
144   return flags & BREAK_AFTER;
145 }
146
147 inline int charinfo::ends_sentence()
148 {
149   if (class_flag)
150     ::get_flags();
151   return flags & ENDS_SENTENCE;
152 }
153
154 inline int charinfo::transparent()
155 {
156   if (class_flag)
157     ::get_flags();
158   return flags & TRANSPARENT;
159 }
160
161 inline int charinfo::ignore_hcodes()
162 {
163   if (class_flag)
164     ::get_flags();
165   return flags & IGNORE_HCODES;
166 }
167
168 inline int charinfo::prohibit_break_before()
169 {
170   if (class_flag)
171     ::get_flags();
172   return flags & DONT_BREAK_BEFORE;
173 }
174
175 inline int charinfo::prohibit_break_after()
176 {
177   if (class_flag)
178     ::get_flags();
179   return flags & DONT_BREAK_AFTER;
180 }
181
182 inline int charinfo::inter_char_space()
183 {
184   if (class_flag)
185     ::get_flags();
186   return flags & INTER_CHAR_SPACE;
187 }
188
189 inline int charinfo::numbered()
190 {
191   return number >= 0;
192 }
193
194 inline int charinfo::is_normal()
195 {
196   return mode == CHAR_NORMAL;
197 }
198
199 inline int charinfo::is_fallback()
200 {
201   return mode == CHAR_FALLBACK;
202 }
203
204 inline int charinfo::is_special()
205 {
206   return mode == CHAR_SPECIAL;
207 }
208
209 inline charinfo *charinfo::get_translation(int transparent_throughput)
210 {
211   return (transparent_throughput && !transparent_translate
212           ? 0
213           : translation);
214 }
215
216 inline unsigned char charinfo::get_hyphenation_code()
217 {
218   return hyphenation_code;
219 }
220
221 inline unsigned char charinfo::get_ascii_code()
222 {
223   return ascii_code;
224 }
225
226 inline unsigned char charinfo::get_asciify_code()
227 {
228   return (translate_input ? asciify_code : 0);
229 }
230
231 inline void charinfo::set_flags(unsigned int c)
232 {
233   flags = c;
234 }
235
236 inline glyph *charinfo::as_glyph()
237 {
238   return this;
239 }
240
241 inline void charinfo::set_translation_input()
242 {
243   translate_input = 1;
244 }
245
246 inline int charinfo::get_translation_input()
247 {
248   return translate_input;
249 }
250
251 inline int charinfo::get_special_translation(int transparent_throughput)
252 {
253   return (transparent_throughput && !transparent_translate
254           ? int(TRANSLATE_NONE)
255           : special_translation);
256 }
257
258 inline macro *charinfo::get_macro()
259 {
260   return mac;
261 }
262
263 inline int charinfo::first_time_not_found()
264 {
265   if (not_found)
266     return 0;
267   else {
268     not_found = 1;
269     return 1;
270   }
271 }
272
273 inline symbol *charinfo::get_symbol()
274 {
275   return &nm;
276 }
277
278 inline void charinfo::add_to_class(int c)
279 {
280   class_flag = 1;
281   // TODO ranges cumbersome for single characters?
282   ranges.push_back(std::pair<int, int>(c, c));
283 }
284
285 inline void charinfo::add_to_class(int lo,
286                                    int hi)
287 {
288   class_flag = 1;
289   ranges.push_back(std::pair<int, int>(lo, hi));
290 }
291
292 inline void charinfo::add_to_class(charinfo *ci)
293 {
294   class_flag = 1;
295   nested_classes.push_back(ci);
296 }
297
298 inline bool charinfo::is_class()
299 {
300   return (!ranges.empty() || !nested_classes.empty());
301 }