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