1 /** \file cssdef.h
2     \brief Cascading Style Sheet definitions
3 
4     Defines enums and structures for subset of CSS2 properties.
5 
6     CoolReader Engine
7 
8     (c) Vadim Lopatin, 2000-2006
9 
10     This source code is distributed under the terms of
11     GNU General Public License.
12 
13     See LICENSE file for details.
14 */
15 
16 #if !defined(__CSS_DEF_H_INCLUDED__)
17 #define __CSS_DEF_H_INCLUDED__
18 
19 #include "lvtypes.h"
20 #include "lvref.h"
21 #include "lvstring.h"
22 
23 // The order of items in following enums should match the order in the tables in src/lvstsheet.cpp
24 /// display property values
25 
26 // Especially don't change the order of these ones, as we use "style->display > css_d_something" like tests
27 enum css_display_t {
28     css_d_inherit, // Inheritance not implemented: should not be seen, unless specified in CSS, which then behave as inline
29     css_d_ruby,    // Behave as inline, but inner content might be wrapped in a table like structure
30     css_d_run_in,  // Rarely used display type (but used as a solution to inline FB2 footnotes)
31     css_d_inline,  // All elements starts being css_d_inline, unless otherwise specified in fb2def.h
32     // Above are those that define a mostly inline container, below those that define a mostly block container
33     css_d_block,
34     css_d_list_item_legacy, // display: -cr-list-item-final (was used before 20180524 for display: list-item)
35     css_d_list_item_block,  // display: list-item
36     css_d_inline_block,
37     css_d_inline_table, // (needs to be before css_d_table, as we use tests like if: (style->display > css_d_table))
38     css_d_table,
39     css_d_table_row_group,
40     css_d_table_header_group,
41     css_d_table_footer_group,
42     css_d_table_row,
43     css_d_table_column_group,
44     css_d_table_column,
45     css_d_table_cell,
46     css_d_table_caption,
47     css_d_none
48 };
49 
50 // https://www.w3.org/TR/CSS2/text.html#white-space-prop
51 // https://florian.rivoal.net/talks/line-breaking/
52 // https://developer.mozilla.org/en-US/docs/Web/CSS/white-space
53 //      Behaviors: New lines   Spaces/tabs End-of-line spaces Text wrap
54 // normal          Collapse    Collapse    Remove             Wrap
55 // nowrap          Collapse    Collapse    Remove             No wrap
56 // pre-line        Preserve    Collapse    Remove             Wrap
57 // pre             Preserve    Preserve    Preserve           No wrap
58 // pre-wrap        Preserve    Preserve    Hang               Wrap
59 // break-spaces    Preserve    Preserve    Wrap               Wrap
60 //
61 // crengine ensures the 3 first behaviors at XML parsing time, initially only for:
62 //   'normal' : replace new lines and tabs by spaces, replace consecutive spaces
63 //              by only one, remove spaces at start and end if "display: block"
64 //   'pre' : preserve spaces and newlines, expands tabs to 8-spaces tabstops
65 // A change of the white-space value for a single node will make the DOM stalled,
66 // and a full reload should be done to get the correct result.
67 //
68 // The last behavior (text wrap) happens at text rendering time, and
69 // we always wrap to fit text into the container or screen width.
70 //
71 // We can approximate support for the other values:
72 // 'nowrap' is mostly like 'normal', but need some additional care:
73 //   - in lvtextfm, to prevent wrap where it would be allowed, but
74 //     still accounting for normal wrap points to be used if no other
75 //     non-nowrap text node on the line provides a wrap opportunity.
76 //   - in getRenderedWidths(), where it can impact the widths of
77 //     table cells and floats
78 // 'pre-line' might be parsed just like 'pre', but rendered just
79 //     like normal (lvtextfm will collapse spaces and wrap on \n)
80 // 'pre-wrap' is just like 'pre', as we would always wrap to fit
81 //     in the container/screen width
82 // 'break-spaces' is very similar to 'pre-wrap', except that spaces
83 //     should not be dropped on wrap. We don't ensure that.
84 //
85 /// white-space property values: keep them ordered this way for easier checks
86 enum css_white_space_t {
87     css_ws_inherit,
88     css_ws_normal,
89     css_ws_nowrap,
90         /* parse XML as 'normal' before this, as 'pre' after this */
91     css_ws_pre_line,
92         /* render text as 'normal' before this, as 'pre' after this */
93     css_ws_pre,
94     css_ws_pre_wrap,
95     css_ws_break_spaces
96 };
97 
98 /// text-align property values
99 enum css_text_align_t {
100     css_ta_inherit,
101     css_ta_left,
102     css_ta_right,
103     css_ta_center,
104     css_ta_justify,
105     css_ta_start, // = left if LTR, right if RTL
106     css_ta_end,   // = right if LTR, left if LTR
107     // Next ones are only accepted with text-align-last
108     css_ta_auto,
109     css_ta_left_if_not_first,    // These non standard keywords allow text-align-last
110     css_ta_right_if_not_first,   // to not apply to a single line. The previous normal
111     css_ta_center_if_not_first,  // keywords apply to a single line (which is alone,
112     css_ta_justify_if_not_first, // so the last) according to the specs.
113     css_ta_start_if_not_first,
114     css_ta_end_if_not_first
115 };
116 
117 /// vertical-align property values
118 enum css_vertical_align_t {
119     css_va_inherit,
120     css_va_baseline,
121     css_va_sub,
122     css_va_super,
123     css_va_top,
124     css_va_text_top,
125     css_va_middle,
126     css_va_bottom,
127     css_va_text_bottom
128 };
129 
130 /// text-decoration property values
131 enum css_text_decoration_t {
132     // TODO: support multiple flags
133     css_td_inherit = 0,
134     css_td_none = 1,
135     css_td_underline = 2,
136     css_td_overline = 3,
137     css_td_line_through = 4,
138     css_td_blink = 5
139 };
140 
141 /// text-transform property values
142 enum css_text_transform_t {
143     css_tt_inherit = 0,
144     css_tt_none = 1,
145     css_tt_uppercase = 2,
146     css_tt_lowercase = 3,
147     css_tt_capitalize = 4,
148     css_tt_full_width = 5
149 };
150 
151 /// hyphenate property values
152 enum css_hyphenate_t {
153     css_hyph_inherit = 0,
154     css_hyph_none = 1,
155     css_hyph_auto = 2
156 };
157 
158 /// font-style property values
159 enum css_font_style_t {
160     css_fs_inherit,
161     css_fs_normal,
162     css_fs_italic,
163     css_fs_oblique
164 };
165 
166 /// font-weight property values
167 enum css_font_weight_t {
168     css_fw_inherit,
169     css_fw_normal,
170     css_fw_bold,
171     css_fw_bolder,
172     css_fw_lighter,
173     css_fw_100,
174     css_fw_200,
175     css_fw_300,
176     css_fw_400,
177     css_fw_500,
178     css_fw_600,
179     css_fw_700,
180     css_fw_800,
181     css_fw_900
182 };
183 
184 /// font-family property values
185 enum css_font_family_t {
186     css_ff_inherit,
187     css_ff_serif,
188     css_ff_sans_serif,
189     css_ff_cursive,
190     css_ff_fantasy,
191     css_ff_monospace
192 };
193 
194 /// page split property values
195 enum css_page_break_t {
196     css_pb_inherit,
197     css_pb_auto,
198     css_pb_avoid, // those after this one are not supported by page-break-inside
199     css_pb_always,
200     css_pb_left,
201     css_pb_right,
202     css_pb_page,
203     css_pb_recto,
204     css_pb_verso
205 };
206 
207 /// list-style-type property values
208 enum css_list_style_type_t {
209     css_lst_inherit,
210     css_lst_disc,
211     css_lst_circle,
212     css_lst_square,
213     css_lst_decimal,
214     css_lst_lower_roman,
215     css_lst_upper_roman,
216     css_lst_lower_alpha,
217     css_lst_upper_alpha,
218     css_lst_none
219 };
220 
221 /// list-style-position property values
222 enum css_list_style_position_t {
223     css_lsp_inherit,
224     css_lsp_inside,
225     css_lsp_outside
226 };
227 
228 /// css length value types, see:
229 //  https://developer.mozilla.org/en-US/docs/Web/CSS/length
230 //  https://www.w3.org/Style/Examples/007/units.en.html
231 enum css_value_type_t {
232     css_val_inherited,
233     css_val_unspecified,
234     css_val_px,  // css px (1 css px = 1 screen px at 96 DPI)
235     css_val_em,  // relative to font size of the current element
236     css_val_ex,  // 1ex =~ 0.5em in many fonts (https://developer.mozilla.org/en-US/docs/Web/CSS/length)
237     css_val_rem, // 'root em', relative to font-size of the root element (typically <html>)
238     css_val_in,  // 2.54 cm   1in = 96 css px
239     css_val_cm,  //        2.54cm = 96 css px
240     css_val_mm,  //        25.4mm = 96 css px
241     css_val_pt,  // 1/72 in  72pt = 96 css px
242     css_val_pc,  // 12 pt     6pc = 96 css px
243     css_val_percent,
244     css_val_color,
245     css_val_screen_px  // screen px, for already scaled values
246 };
247 
248 /// css border style values
249 enum css_border_style_type_t {
250     css_border_solid,
251     css_border_dotted,
252     css_border_dashed,
253     css_border_double,
254     css_border_groove,
255     css_border_ridge,
256     css_border_inset,
257     css_border_outset,
258     css_border_none
259 };
260 /// css background property values
261 enum css_background_repeat_value_t {
262     css_background_repeat,
263     css_background_repeat_x,
264     css_background_repeat_y,
265     css_background_no_repeat,
266     css_background_r_initial,
267     css_background_r_inherit,
268     css_background_r_none
269 };
270 enum css_background_position_value_t {
271     css_background_left_top,
272     css_background_left_center,
273     css_background_left_bottom,
274     css_background_right_top,
275     css_background_right_center,
276     css_background_right_bottom,
277     css_background_center_top,
278     css_background_center_center,
279     css_background_center_bottom,
280     css_background_p_initial,
281     css_background_p_inherit,
282     css_background_p_none
283 };
284 
285 enum css_border_collapse_value_t {
286     css_border_seperate,
287     css_border_collapse,
288     css_border_c_initial,
289     css_border_c_inherit,
290     css_border_c_none
291 };
292 
293 enum css_orphans_widows_value_t { // supported only if in range 1-9
294     css_orphans_widows_inherit,
295     css_orphans_widows_1,
296     css_orphans_widows_2,
297     css_orphans_widows_3,
298     css_orphans_widows_4,
299     css_orphans_widows_5,
300     css_orphans_widows_6,
301     css_orphans_widows_7,
302     css_orphans_widows_8,
303     css_orphans_widows_9
304 };
305 
306 /// float property values
307 enum css_float_t {
308     css_f_inherit,
309     css_f_none,
310     css_f_left,
311     css_f_right
312 };
313 
314 /// clear property values
315 enum css_clear_t {
316     css_c_inherit,
317     css_c_none,
318     css_c_left,
319     css_c_right,
320     css_c_both
321 };
322 
323 /// direction property values
324 enum css_direction_t {
325     css_dir_inherit,
326     css_dir_unset,
327     css_dir_ltr,
328     css_dir_rtl
329 };
330 
331 enum css_generic_value_t {
332     css_generic_auto = -1,        // (css_val_unspecified, css_generic_auto), for "margin: auto"
333     css_generic_normal = -2,      // (css_val_unspecified, css_generic_normal), for "line-height: normal"
334     css_generic_transparent = -3, // (css_val_unspecified, css_generic_transparent), for "color: transparent"
335     css_generic_contain = -4,     // (css_val_unspecified, css_generic_contain), for "background-size: contain"
336     css_generic_cover = -5        // (css_val_unspecified, css_generic_cover), for "background-size: cover"
337 };
338 
339 // -cr-hint is a non standard property for providing hints to crengine via style tweaks
340 // Handled as a bitmap, with a flag for each hint, as we might set multiple on a same node (max 31 bits)
341 #define CSS_CR_HINT_NONE                    0x00000000 // default value
342 
343 // Reset any hint previously set and don't inherit any from parent
344 #define CSS_CR_HINT_NONE_NO_INHERIT         0x00000001 // -cr-hint: none
345 
346 // Text and images should not overflow/modify their paragraph strut baseline and height
347 // (it could have been a non-standard named value for line-height:, but we want to be
348 // able to not override existing line-height: values)
349 #define CSS_CR_HINT_STRUT_CONFINED          0x00000002 // -cr-hint: strut-confined (inheritable)
350 // Glyphs should not overflow line edges, and across text nodes or over images
351 // (it can also be used to disable hanging punctuation on the targeted nodes).
352 #define CSS_CR_HINT_FIT_GLYPHS              0x00000004 // -cr-hint: fit-glyphs (inheritable)
353 
354 // A node with these should be considered as TOC item of level N when building alternate TOC
355 #define CSS_CR_HINT_TOC_LEVEL1              0x00000100 // -cr-hint: toc-level1
356 #define CSS_CR_HINT_TOC_LEVEL2              0x00000200 // -cr-hint: toc-level2
357 #define CSS_CR_HINT_TOC_LEVEL3              0x00000400 // -cr-hint: toc-level3
358 #define CSS_CR_HINT_TOC_LEVEL4              0x00000800 // -cr-hint: toc-level4
359 #define CSS_CR_HINT_TOC_LEVEL5              0x00001000 // -cr-hint: toc-level5
360 #define CSS_CR_HINT_TOC_LEVEL6              0x00002000 // -cr-hint: toc-level6
361 #define CSS_CR_HINT_TOC_LEVELS_MASK         0x00003F00
362 // Ignore H1...H6 that have this when building alternate TOC
363 #define CSS_CR_HINT_TOC_IGNORE              0x00004000 // -cr-hint: toc-ignore
364 
365 // Tweak text selection behaviour when traversing a node with these hints
366 #define CSS_CR_HINT_TEXT_SELECTION_INLINE   0x00010000 // -cr-hint: text-selection-inline  don't add a '\n' before inner text
367                                                        //                                  (even if the node happens to be block)
368 #define CSS_CR_HINT_TEXT_SELECTION_BLOCK    0x00020000 // -cr-hint: text-selection-block   add a '\n' before inner text (even
369                                                        //                                  if the node happens to be inline)
370 #define CSS_CR_HINT_TEXT_SELECTION_SKIP     0x00040000 // -cr-hint: text-selection-skip    don't include inner text in selection
371 
372 // To be set on a block element: it is a footnote (must be a full footnote block container),
373 // and to be displayed at the bottom of all pages that contain a link to it.
374 #define CSS_CR_HINT_FOOTNOTE_INPAGE         0x00080000 // -cr-hint: footnote-inpage
375 
376 // For footnote popup detection by koreader-base/cre.cpp
377 #define CSS_CR_HINT_NOTEREF                 0x01000000 // -cr-hint: noteref         link is to a footnote
378 #define CSS_CR_HINT_NOTEREF_IGNORE          0x02000000 // -cr-hint: noteref-ignore  link is not to a footnote (even if
379                                                        //                           everything else indicates it is)
380 #define CSS_CR_HINT_FOOTNOTE                0x04000000 // -cr-hint: footnote        block is a footnote (must be a full
381                                                        //                           footnote block container)
382 #define CSS_CR_HINT_FOOTNOTE_IGNORE         0x08000000 // -cr-hint: footnote-ignore block is not a footnote (even if
383                                                        //                           everything else indicates it is)
384 
385 // A few of them are inheritable, most are not.
386 #define CSS_CR_HINT_INHERITABLE_MASK        0x00000006
387 
388 // Macro for easier checking
389 #define STYLE_HAS_CR_HINT(s, h)     ( (bool)(s->cr_hint.value & CSS_CR_HINT_##h) )
390 
391 /// css length value
392 typedef struct css_length_tag {
393     css_value_type_t type;  ///< type of value
394     int         value;      ///< value: *256 for all types (to allow for fractional px and %), except css_val_screen_px
395                             // allow for values -/+ 524288.0 (32bits -8 for fraction -4 for pack -1 for sign)
css_length_tagcss_length_tag396     css_length_tag()
397         : type (css_val_screen_px), value (0)
398     {
399     }
css_length_tagcss_length_tag400     css_length_tag( int px_value )
401         : type (css_val_screen_px), value (px_value)
402     {
403     }
css_length_tagcss_length_tag404     css_length_tag(css_value_type_t n_type, int n_value) // expects caller to do << 8
405         : type(n_type), value(n_value)
406     {
407     }
408     bool operator == ( const css_length_tag & v ) const
409     {
410         return type == v.type
411             && value == v.value;
412     }
413     // used only in hash calculation
packcss_length_tag414     lUInt32 pack() { return (lUInt32)type + (((lUInt32)value)<<4); }
415 } css_length_t;
416 
417 #endif // __CSS_DEF_H_INCLUDED__
418