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