NetSurf
layout_internal.h
Go to the documentation of this file.
1/*
2 * Copyright 2003 James Bursa <bursa@users.sourceforge.net>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf 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
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/**
20 * \file
21 * HTML layout private interface.
22 */
23
24#ifndef NETSURF_HTML_LAYOUT_INTERNAL_H
25#define NETSURF_HTML_LAYOUT_INTERNAL_H
26
27#define AUTO INT_MIN
28
29/**
30 * Layout a block formatting context.
31 *
32 * \param block BLOCK, INLINE_BLOCK, or TABLE_CELL to layout
33 * \param viewport_height Height of viewport in pixels or -ve if unknown
34 * \param content Memory pool for any new boxes
35 * \return true on success, false on memory exhaustion
36 *
37 * This function carries out layout of a block and its children, as described
38 * in CSS 2.1 9.4.1.
39 */
41 struct box *block,
42 int viewport_height,
44
45/**
46 * Layout a table.
47 *
48 * \param table table to layout
49 * \param available_width width of containing block
50 * \param content memory pool for any new boxes
51 * \return true on success, false on memory exhaustion
52 */
53bool layout_table(
54 struct box *table,
55 int available_width,
57
58/**
59 * Layout a flex container.
60 *
61 * \param[in] flex table to layout
62 * \param[in] available_width width of containing block
63 * \param[in] content memory pool for any new boxes
64 * \return true on success, false on memory exhaustion
65 */
66bool layout_flex(
67 struct box *flex,
68 int available_width,
70
71typedef uint8_t (*css_len_func)(
72 const css_computed_style *style,
73 css_fixed *length, css_unit *unit);
74typedef uint8_t (*css_border_style_func)(
75 const css_computed_style *style);
76typedef uint8_t (*css_border_color_func)(
77 const css_computed_style *style,
78 css_color *color);
79
80/** Array of per-side access functions for computed style margins. */
81extern const css_len_func margin_funcs[4];
82
83/** Array of per-side access functions for computed style paddings. */
84extern const css_len_func padding_funcs[4];
85
86/** Array of per-side access functions for computed style border_widths. */
87extern const css_len_func border_width_funcs[4];
88
89/** Array of per-side access functions for computed style border styles. */
91
92/** Array of per-side access functions for computed style border colors. */
94
95/** Layout helper: Check whether box is a float. */
96static inline bool lh__box_is_float_box(const struct box *b)
97{
98 return b->type == BOX_FLOAT_LEFT ||
100}
101
102/** Layout helper: Check whether box takes part in inline flow. */
103static inline bool lh__box_is_inline_flow(const struct box *b)
104{
105 return b->type == BOX_INLINE ||
106 b->type == BOX_INLINE_FLEX ||
107 b->type == BOX_INLINE_BLOCK ||
108 b->type == BOX_TEXT ||
109 b->type == BOX_INLINE_END;
110}
111
112/** Layout helper: Check whether box takes part in inline flow. */
113static inline bool lh__box_is_flex_container(const struct box *b)
114{
115 return b->type == BOX_FLEX ||
116 b->type == BOX_INLINE_FLEX;
117}
118
119/** Layout helper: Check whether box takes part in inline flow. */
120static inline bool lh__box_is_flex_item(const struct box *b)
121{
122 return (b->parent != NULL) && lh__box_is_flex_container(b->parent);
123}
124
125/** Layout helper: Check whether box is inline level. (Includes BR.) */
126static inline bool lh__box_is_inline_level(const struct box *b)
127{
128 return lh__box_is_inline_flow(b) ||
129 b->type == BOX_BR;
130}
131
132/** Layout helper: Check whether box is inline level. (Includes BR, floats.) */
133static inline bool lh__box_is_inline_content(const struct box *b)
134{
135 return lh__box_is_float_box(b) ||
137}
138
139/** Layout helper: Check whether box is an object. */
140static inline bool lh__box_is_object(const struct box *b)
141{
142 return b->object ||
143 (b->flags & (IFRAME | REPLACE_DIM));
144}
145
146/** Layout helper: Check whether box is replaced. */
147static inline bool lh__box_is_replace(const struct box *b)
148{
149 return b->gadget ||
151}
152
153/** Layout helper: Check for CSS border on given side. */
154static inline bool lh__have_border(
155 enum box_side side,
156 const css_computed_style *style)
157{
158 return border_style_funcs[side](style) != CSS_BORDER_STYLE_NONE;
159}
160
161static inline bool lh__box_is_absolute(const struct box *b)
162{
163 return css_computed_position(b->style) == CSS_POSITION_ABSOLUTE ||
164 css_computed_position(b->style) == CSS_POSITION_FIXED;
165}
166
167static inline bool lh__flex_main_is_horizontal(const struct box *flex)
168{
169 const css_computed_style *style = flex->style;
170
171 assert(style != NULL);
172
173 switch (css_computed_flex_direction(style)) {
174 default: /* Fallthrough. */
175 case CSS_FLEX_DIRECTION_ROW: /* Fallthrough. */
176 case CSS_FLEX_DIRECTION_ROW_REVERSE:
177 return true;
178 case CSS_FLEX_DIRECTION_COLUMN: /* Fallthrough. */
179 case CSS_FLEX_DIRECTION_COLUMN_REVERSE:
180 return false;
181 }
182}
183
184static inline bool lh__flex_direction_reversed(const struct box *flex)
185{
186 switch (css_computed_flex_direction(flex->style)) {
187 default: /* Fallthrough. */
188 case CSS_FLEX_DIRECTION_ROW_REVERSE: /* Fallthrough. */
189 case CSS_FLEX_DIRECTION_COLUMN_REVERSE:
190 return true;
191 case CSS_FLEX_DIRECTION_ROW: /* Fallthrough. */
192 case CSS_FLEX_DIRECTION_COLUMN:
193 return false;
194 }
195}
196
197static inline int lh__non_auto_margin(const struct box *b, enum box_side side)
198{
199 return (b->margin[side] == AUTO) ? 0 : b->margin[side];
200}
201
202static inline int lh__delta_outer_height(const struct box *b)
203{
204 return b->padding[TOP] +
205 b->padding[BOTTOM] +
206 b->border[TOP].width +
207 b->border[BOTTOM].width +
210}
211
212static inline int lh__delta_outer_width(const struct box *b)
213{
214 return b->padding[LEFT] +
215 b->padding[RIGHT] +
216 b->border[LEFT].width +
217 b->border[RIGHT].width +
220}
221
222static inline int lh__delta_outer_main(
223 const struct box *flex,
224 const struct box *b)
225{
226 if (lh__flex_main_is_horizontal(flex)) {
227 return lh__delta_outer_width(b);
228 } else {
229 return lh__delta_outer_height(b);
230 }
231}
232
233static inline int lh__delta_outer_cross(
234 const struct box *flex,
235 const struct box *b)
236{
237 if (lh__flex_main_is_horizontal(flex) == false) {
238 return lh__delta_outer_width(b);
239 } else {
240 return lh__delta_outer_height(b);
241 }
242}
243
244static inline int *lh__box_size_main_ptr(
245 bool horizontal,
246 struct box *b)
247{
248 return horizontal ? &b->width : &b->height;
249}
250
251static inline int *lh__box_size_cross_ptr(
252 bool horizontal,
253 struct box *b)
254{
255 return horizontal ? &b->height : &b->width;
256}
257
258static inline int lh__box_size_main(
259 bool horizontal,
260 const struct box *b)
261{
262 return horizontal ? b->width : b->height;
263}
264
265static inline int lh__box_size_cross(
266 bool horizontal,
267 const struct box *b)
268{
269 return horizontal ? b->height : b->width;
270}
271
272static inline bool lh__box_size_cross_is_auto(
273 bool horizontal,
274 struct box *b)
275{
276 css_fixed length;
277 css_unit unit;
278
279 if (horizontal) {
280 return css_computed_height(b->style,
281 &length, &unit) == CSS_HEIGHT_AUTO;
282 } else {
283 return css_computed_width(b->style,
284 &length, &unit) == CSS_WIDTH_AUTO;
285 }
286}
287
288static inline enum css_align_self_e lh__box_align_self(
289 const struct box *flex,
290 const struct box *item)
291{
292 enum css_align_self_e align_self = css_computed_align_self(item->style);
293
294 if (align_self == CSS_ALIGN_SELF_AUTO) {
295 align_self = css_computed_align_items(flex->style);
296 }
297
298 return align_self;
299}
300
301/**
302 * Determine width of margin, borders, and padding on one side of a box.
303 *
304 * \param unit_len_ctx CSS length conversion context for document
305 * \param style style to measure
306 * \param side side of box to measure
307 * \param margin whether margin width is required
308 * \param border whether border width is required
309 * \param padding whether padding width is required
310 * \param fixed increased by sum of fixed margin, border, and padding
311 * \param frac increased by sum of fractional margin and padding
312 */
313static inline void calculate_mbp_width(
314 const css_unit_ctx *unit_len_ctx,
315 const css_computed_style *style,
316 unsigned int side,
317 bool margin,
318 bool border,
319 bool padding,
320 int *fixed,
321 float *frac)
322{
323 css_fixed value = 0;
324 css_unit unit = CSS_UNIT_PX;
325
326 assert(style);
327
328 /* margin */
329 if (margin) {
330 enum css_margin_e type;
331
332 type = margin_funcs[side](style, &value, &unit);
333 if (type == CSS_MARGIN_SET) {
334 if (unit == CSS_UNIT_PCT) {
335 *frac += FIXTOFLT(FDIV(value, F_100));
336 } else {
337 *fixed += FIXTOINT(css_unit_len2device_px(
338 style, unit_len_ctx,
339 value, unit));
340 }
341 }
342 }
343
344 /* border */
345 if (border) {
346 if (lh__have_border(side, style)) {
347 border_width_funcs[side](style, &value, &unit);
348
349 *fixed += FIXTOINT(css_unit_len2device_px(
350 style, unit_len_ctx,
351 value, unit));
352 }
353 }
354
355 /* padding */
356 if (padding) {
357 padding_funcs[side](style, &value, &unit);
358 if (unit == CSS_UNIT_PCT) {
359 *frac += FIXTOFLT(FDIV(value, F_100));
360 } else {
361 *fixed += FIXTOINT(css_unit_len2device_px(
362 style, unit_len_ctx,
363 value, unit));
364 }
365 }
366}
367
368/**
369 * Adjust a specified width or height for the box-sizing property.
370 *
371 * This turns the specified dimension into a content-box dimension.
372 *
373 * \param unit_len_ctx Length conversion context
374 * \param box gadget to adjust dimensions of
375 * \param available_width width of containing block
376 * \param setwidth set true if the dimension to be tweaked is a width,
377 * else set false for a height
378 * \param dimension current value for given width/height dimension.
379 * updated to new value after consideration of
380 * gadget properties.
381 */
382static inline void layout_handle_box_sizing(
383 const css_unit_ctx *unit_len_ctx,
384 const struct box *box,
385 int available_width,
386 bool setwidth,
387 int *dimension)
388{
389 enum css_box_sizing_e bs;
390
391 assert(box && box->style);
392
393 bs = css_computed_box_sizing(box->style);
394
395 if (bs == CSS_BOX_SIZING_BORDER_BOX) {
396 int orig = *dimension;
397 int fixed = 0;
398 float frac = 0;
399
400 calculate_mbp_width(unit_len_ctx, box->style,
401 setwidth ? LEFT : TOP,
402 false, true, true, &fixed, &frac);
403 calculate_mbp_width(unit_len_ctx, box->style,
404 setwidth ? RIGHT : BOTTOM,
405 false, true, true, &fixed, &frac);
406 orig -= frac * available_width + fixed;
407 *dimension = orig > 0 ? orig : 0;
408 }
409}
410
411/**
412 * Calculate width, height, and thickness of margins, paddings, and borders.
413 *
414 * \param unit_len_ctx Length conversion context
415 * \param available_width width of containing block
416 * \param viewport_height height of viewport in pixels or -ve if unknown
417 * \param box current box
418 * \param style style giving width, height, margins, paddings,
419 * and borders
420 * \param width updated to width, may be NULL
421 * \param height updated to height, may be NULL
422 * \param max_width updated to max-width, may be NULL
423 * \param min_width updated to min-width, may be NULL
424 * \param max_height updated to max-height, may be NULL
425 * \param min_height updated to min-height, may be NULL
426 * \param margin filled with margins, may be NULL
427 * \param padding filled with paddings, may be NULL
428 * \param border filled with border widths, may be NULL
429 */
430static inline void layout_find_dimensions(
431 const css_unit_ctx *unit_len_ctx,
432 int available_width,
433 int viewport_height,
434 const struct box *box,
435 const css_computed_style *style,
436 int *width,
437 int *height,
438 int *max_width,
439 int *min_width,
440 int *max_height,
441 int *min_height,
442 int margin[4],
443 int padding[4],
444 struct box_border border[4])
445{
446 struct box *containing_block = NULL;
447 unsigned int i;
448
449 if (width) {
450 if (css_computed_width_px(style, unit_len_ctx,
451 available_width, width) == CSS_WIDTH_SET) {
452 layout_handle_box_sizing(unit_len_ctx, box,
453 available_width, true, width);
454 } else {
455 *width = AUTO;
456 }
457 }
458
459 if (height) {
460 enum css_height_e htype;
461 css_fixed value = 0;
462 css_unit unit = CSS_UNIT_PX;
463
464 htype = css_computed_height(style, &value, &unit);
465
466 if (htype == CSS_HEIGHT_SET) {
467 if (unit == CSS_UNIT_PCT) {
468 enum css_height_e cbhtype;
469
470 if (css_computed_position(box->style) ==
471 CSS_POSITION_ABSOLUTE &&
472 box->parent) {
473 /* Box is absolutely positioned */
474 assert(box->float_container);
475 containing_block = box->float_container;
476 } else if (box->float_container &&
477 css_computed_position(box->style) !=
478 CSS_POSITION_ABSOLUTE &&
479 (css_computed_float(box->style) ==
480 CSS_FLOAT_LEFT ||
481 css_computed_float(box->style) ==
482 CSS_FLOAT_RIGHT)) {
483 /* Box is a float */
484 assert(box->parent &&
485 box->parent->parent &&
487
488 containing_block =
490 } else if (box->parent && box->parent->type !=
492 /* Box is a block level element */
493 containing_block = box->parent;
494 } else if (box->parent && box->parent->type ==
496 /* Box is an inline block */
497 assert(box->parent->parent);
498 containing_block = box->parent->parent;
499 }
500
501 if (containing_block) {
502 css_fixed f = 0;
503 css_unit u = CSS_UNIT_PX;
504
505 cbhtype = css_computed_height(
506 containing_block->style,
507 &f, &u);
508 }
509
510 if (containing_block &&
511 containing_block->height != AUTO &&
512 (css_computed_position(box->style) ==
513 CSS_POSITION_ABSOLUTE ||
514 cbhtype == CSS_HEIGHT_SET)) {
515 /* Box is absolutely positioned or its
516 * containing block has a valid
517 * specified height.
518 * (CSS 2.1 Section 10.5) */
519 *height = FPCT_OF_INT_TOINT(value,
520 containing_block->height);
521 } else if ((!box->parent ||
522 !box->parent->parent) &&
523 viewport_height >= 0) {
524 /* If root element or it's child
525 * (HTML or BODY) */
526 *height = FPCT_OF_INT_TOINT(value,
527 viewport_height);
528 } else {
529 /* precentage height not permissible
530 * treat height as auto */
531 *height = AUTO;
532 }
533 } else {
534 *height = FIXTOINT(css_unit_len2device_px(
535 style, unit_len_ctx,
536 value, unit));
537 }
538 } else {
539 *height = AUTO;
540 }
541
542 if (*height != AUTO) {
543 layout_handle_box_sizing(unit_len_ctx, box,
544 available_width, false, height);
545 }
546 }
547
548 if (max_width) {
549 enum css_max_width_e type;
550 css_fixed value = 0;
551 css_unit unit = CSS_UNIT_PX;
552
553 type = css_computed_max_width(style, &value, &unit);
554
555 if (type == CSS_MAX_WIDTH_SET) {
556 if (unit == CSS_UNIT_PCT) {
557 *max_width = FPCT_OF_INT_TOINT(value,
558 available_width);
559 } else {
560 *max_width = FIXTOINT(css_unit_len2device_px(
561 style, unit_len_ctx,
562 value, unit));
563 }
564 } else {
565 /* Inadmissible */
566 *max_width = -1;
567 }
568
569 if (*max_width != -1) {
570 layout_handle_box_sizing(unit_len_ctx, box,
571 available_width, true, max_width);
572 }
573 }
574
575 if (min_width) {
576 enum css_min_width_e type;
577 css_fixed value = 0;
578 css_unit unit = CSS_UNIT_PX;
579
580 type = ns_computed_min_width(style, &value, &unit);
581
582 if (type == CSS_MIN_WIDTH_SET) {
583 if (unit == CSS_UNIT_PCT) {
584 *min_width = FPCT_OF_INT_TOINT(value,
585 available_width);
586 } else {
587 *min_width = FIXTOINT(css_unit_len2device_px(
588 style, unit_len_ctx,
589 value, unit));
590 }
591 } else {
592 /* Inadmissible */
593 *min_width = 0;
594 }
595
596 if (*min_width != 0) {
597 layout_handle_box_sizing(unit_len_ctx, box,
598 available_width, true, min_width);
599 }
600 }
601
602 if (max_height) {
603 enum css_max_height_e type;
604 css_fixed value = 0;
605 css_unit unit = CSS_UNIT_PX;
606
607 type = css_computed_max_height(style, &value, &unit);
608
609 if (type == CSS_MAX_HEIGHT_SET) {
610 if (unit == CSS_UNIT_PCT) {
611 /* TODO: handle percentage */
612 *max_height = -1;
613 } else {
614 *max_height = FIXTOINT(css_unit_len2device_px(
615 style, unit_len_ctx,
616 value, unit));
617 }
618 } else {
619 /* Inadmissible */
620 *max_height = -1;
621 }
622 }
623
624 if (min_height) {
625 enum css_min_height_e type;
626 css_fixed value = 0;
627 css_unit unit = CSS_UNIT_PX;
628
629 type = ns_computed_min_height(style, &value, &unit);
630
631 if (type == CSS_MIN_HEIGHT_SET) {
632 if (unit == CSS_UNIT_PCT) {
633 /* TODO: handle percentage */
634 *min_height = 0;
635 } else {
636 *min_height = FIXTOINT(css_unit_len2device_px(
637 style, unit_len_ctx,
638 value, unit));
639 }
640 } else {
641 /* Inadmissible */
642 *min_height = 0;
643 }
644 }
645
646 for (i = 0; i != 4; i++) {
647 if (margin) {
648 enum css_margin_e type = CSS_MARGIN_AUTO;
649 css_fixed value = 0;
650 css_unit unit = CSS_UNIT_PX;
651
652 type = margin_funcs[i](style, &value, &unit);
653
654 if (type == CSS_MARGIN_SET) {
655 if (unit == CSS_UNIT_PCT) {
656 margin[i] = FPCT_OF_INT_TOINT(value,
657 available_width);
658 } else {
659 margin[i] = FIXTOINT(css_unit_len2device_px(
660 style, unit_len_ctx,
661 value, unit));
662 }
663 } else {
664 margin[i] = AUTO;
665 }
666 }
667
668 if (padding) {
669 css_fixed value = 0;
670 css_unit unit = CSS_UNIT_PX;
671
672 padding_funcs[i](style, &value, &unit);
673
674 if (unit == CSS_UNIT_PCT) {
675 padding[i] = FPCT_OF_INT_TOINT(value,
676 available_width);
677 } else {
678 padding[i] = FIXTOINT(css_unit_len2device_px(
679 style, unit_len_ctx,
680 value, unit));
681 }
682 }
683
684 /* Table cell borders are populated in table.c */
685 if (border && box->type != BOX_TABLE_CELL) {
686 enum css_border_style_e bstyle = CSS_BORDER_STYLE_NONE;
687 css_color color = 0;
688 css_fixed value = 0;
689 css_unit unit = CSS_UNIT_PX;
690
691 border_width_funcs[i](style, &value, &unit);
692 bstyle = border_style_funcs[i](style);
693 border_color_funcs[i](style, &color);
694
695 border[i].style = bstyle;
696 border[i].c = color;
697
698 if (bstyle == CSS_BORDER_STYLE_HIDDEN ||
699 bstyle == CSS_BORDER_STYLE_NONE)
700 /* spec unclear: following Mozilla */
701 border[i].width = 0;
702 else
703 border[i].width = FIXTOINT(css_unit_len2device_px(
704 style, unit_len_ctx,
705 value, unit));
706
707 /* Special case for border-collapse: make all borders
708 * on table/table-row-group/table-row zero width. */
709 if (css_computed_border_collapse(style) ==
710 CSS_BORDER_COLLAPSE_COLLAPSE &&
711 (box->type == BOX_TABLE ||
714 border[i].width = 0;
715 }
716 }
717}
718
719#endif
@ BOX_FLOAT_LEFT
Definition: box.h:63
@ BOX_INLINE_BLOCK
Definition: box.h:65
@ BOX_FLOAT_RIGHT
Definition: box.h:64
@ BOX_INLINE_CONTAINER
Definition: box.h:57
@ BOX_TABLE_CELL
Definition: box.h:61
@ BOX_TABLE_ROW_GROUP
Definition: box.h:62
@ BOX_INLINE_END
Definition: box.h:68
@ BOX_TABLE
Definition: box.h:59
@ BOX_INLINE
Definition: box.h:58
@ BOX_TABLE_ROW
Definition: box.h:60
@ BOX_TEXT
Definition: box.h:67
@ BOX_INLINE_FLEX
Definition: box.h:71
@ BOX_BR
Definition: box.h:66
@ BOX_FLEX
Definition: box.h:70
@ IFRAME
Definition: box.h:89
@ REPLACE_DIM
Definition: box.h:88
box_side
Sides of a box.
Definition: box.h:98
@ TOP
Definition: box.h:98
@ BOTTOM
Definition: box.h:98
@ LEFT
Definition: box.h:98
@ RIGHT
Definition: box.h:98
static uint8_t ns_computed_min_height(const css_computed_style *style, css_fixed *length, css_unit *unit)
Definition: utils.h:75
static uint8_t ns_computed_min_width(const css_computed_style *style, css_fixed *length, css_unit *unit)
Definition: utils.h:91
const char * type
Definition: filetype.cpp:44
static bool lh__flex_direction_reversed(const struct box *flex)
static bool lh__flex_main_is_horizontal(const struct box *flex)
#define AUTO
static bool lh__box_is_object(const struct box *b)
Layout helper: Check whether box is an object.
static int lh__delta_outer_main(const struct box *flex, const struct box *b)
uint8_t(* css_border_style_func)(const css_computed_style *style)
static bool lh__box_is_flex_container(const struct box *b)
Layout helper: Check whether box takes part in inline flow.
static bool lh__box_is_replace(const struct box *b)
Layout helper: Check whether box is replaced.
bool layout_block_context(struct box *block, int viewport_height, html_content *content)
Layout a block formatting context.
Definition: layout.c:3508
const css_border_style_func border_style_funcs[4]
Array of per-side access functions for computed style border styles.
Definition: layout.c:98
static int * lh__box_size_cross_ptr(bool horizontal, struct box *b)
static int * lh__box_size_main_ptr(bool horizontal, struct box *b)
bool layout_flex(struct box *flex, int available_width, html_content *content)
Layout a flex container.
Definition: layout_flex.c:1046
static void calculate_mbp_width(const css_unit_ctx *unit_len_ctx, const css_computed_style *style, unsigned int side, bool margin, bool border, bool padding, int *fixed, float *frac)
Determine width of margin, borders, and padding on one side of a box.
static bool lh__box_is_absolute(const struct box *b)
bool layout_table(struct box *table, int available_width, html_content *content)
Layout a table.
Definition: layout.c:1591
static bool lh__have_border(enum box_side side, const css_computed_style *style)
Layout helper: Check for CSS border on given side.
static int lh__box_size_main(bool horizontal, const struct box *b)
static void layout_handle_box_sizing(const css_unit_ctx *unit_len_ctx, const struct box *box, int available_width, bool setwidth, int *dimension)
Adjust a specified width or height for the box-sizing property.
const css_border_color_func border_color_funcs[4]
Array of per-side access functions for computed style border colors.
Definition: layout.c:106
uint8_t(* css_len_func)(const css_computed_style *style, css_fixed *length, css_unit *unit)
const css_len_func border_width_funcs[4]
Array of per-side access functions for computed style border_widths.
Definition: layout.c:90
static int lh__delta_outer_height(const struct box *b)
static int lh__box_size_cross(bool horizontal, const struct box *b)
static bool lh__box_is_inline_content(const struct box *b)
Layout helper: Check whether box is inline level.
static void layout_find_dimensions(const css_unit_ctx *unit_len_ctx, int available_width, int viewport_height, const struct box *box, const css_computed_style *style, int *width, int *height, int *max_width, int *min_width, int *max_height, int *min_height, int margin[4], int padding[4], struct box_border border[4])
Calculate width, height, and thickness of margins, paddings, and borders.
static enum css_align_self_e lh__box_align_self(const struct box *flex, const struct box *item)
static bool lh__box_is_flex_item(const struct box *b)
Layout helper: Check whether box takes part in inline flow.
static int lh__delta_outer_width(const struct box *b)
static bool lh__box_is_inline_level(const struct box *b)
Layout helper: Check whether box is inline level.
static int lh__delta_outer_cross(const struct box *flex, const struct box *b)
static int lh__non_auto_margin(const struct box *b, enum box_side side)
static bool lh__box_is_inline_flow(const struct box *b)
Layout helper: Check whether box takes part in inline flow.
uint8_t(* css_border_color_func)(const css_computed_style *style, css_color *color)
const css_len_func padding_funcs[4]
Array of per-side access functions for computed style paddings.
Definition: layout.c:82
static bool lh__box_is_float_box(const struct box *b)
Layout helper: Check whether box is a float.
const css_len_func margin_funcs[4]
Array of per-side access functions for computed style margins.
Definition: layout.c:74
static bool lh__box_size_cross_is_auto(bool horizontal, struct box *b)
int width
Definition: gui.c:160
int height
Definition: gui.c:161
Container for border values during table border calculations.
Definition: table.c:42
enum css_border_style_e style
border-style
Definition: table.c:43
css_fixed width
border-width length
Definition: table.c:46
css_color c
border-color value
Definition: table.c:45
Container for box border details.
Definition: box.h:104
int width
border-width (pixels)
Definition: box.h:107
Node in box tree.
Definition: box.h:177
struct box_border border[4]
Border: TOP, RIGHT, BOTTOM, LEFT.
Definition: box.h:327
int min_width
Width of box taking all line breaks (including margins etc).
Definition: box.h:343
int width
Width of content box (excluding padding etc.).
Definition: box.h:289
struct box * parent
Parent box, or NULL.
Definition: box.h:236
int height
Height of content box (excluding padding etc.).
Definition: box.h:293
struct box * float_container
If box is a float, points to box's containing block.
Definition: box.h:261
int margin[4]
Margin: TOP, RIGHT, BOTTOM, LEFT.
Definition: box.h:317
int max_width
Width that would be taken with no line breaks.
Definition: box.h:349
box_type type
Type of box.
Definition: box.h:181
css_computed_style * style
Style for this box.
Definition: box.h:205
struct hlcache_handle * object
Object in this box (usually an image), or NULL if none.
Definition: box.h:441
int padding[4]
Padding: TOP, RIGHT, BOTTOM, LEFT.
Definition: box.h:322
box_flags flags
Box flags.
Definition: box.h:186
struct form_control * gadget
Form control data, or NULL if not a form control.
Definition: box.h:423
Content which corresponds to a single URL.
Data specific to CONTENT_HTML.
Definition: private.h:93