75 [
TOP] = css_computed_margin_top,
76 [
RIGHT] = css_computed_margin_right,
77 [
BOTTOM] = css_computed_margin_bottom,
78 [
LEFT] = css_computed_margin_left,
83 [
TOP] = css_computed_padding_top,
84 [
RIGHT] = css_computed_padding_right,
85 [
BOTTOM] = css_computed_padding_bottom,
86 [
LEFT] = css_computed_padding_left,
91 [
TOP] = css_computed_border_top_width,
92 [
RIGHT] = css_computed_border_right_width,
93 [
BOTTOM] = css_computed_border_bottom_width,
94 [
LEFT] = css_computed_border_left_width,
99 [
TOP] = css_computed_border_top_style,
100 [
RIGHT] = css_computed_border_right_style,
101 [
BOTTOM] = css_computed_border_bottom_style,
102 [
LEFT] = css_computed_border_left_style,
107 [
TOP] = css_computed_border_top_color,
108 [
RIGHT] = css_computed_border_right_color,
109 [
BOTTOM] = css_computed_border_bottom_color,
110 [
LEFT] = css_computed_border_left_color,
136 int min_width,
int max_width,
137 int min_height,
int max_height)
150 *
width = intrinsic_width;
151 *
height = intrinsic_height;
154 if (min_width > 0 && min_width > *
width) {
158 if (max_width >= 0 && max_width < *
width) {
163 if (scaled && (intrinsic_width != 0)) {
171 if (min_height > 0 && min_height > *
height) {
175 if (max_height >= 0 && max_height < *
height) {
180 if (scaled && (intrinsic_height != 0)) {
192 if (intrinsic_height != 0)
196 *
width = intrinsic_width;
198 if (min_width > 0 && min_width > *
width)
200 if (max_width >= 0 && max_width < *
width)
209 if (min_width > 0 && min_width > *
width)
211 if (max_width >= 0 && max_width < *
width)
214 if (intrinsic_width != 0)
218 *
height = intrinsic_height;
231 const css_unit_ctx *unit_len_ctx,
232 const css_computed_style *style,
int width)
235 css_unit unit = CSS_UNIT_PX;
237 css_computed_text_indent(style, &value, &unit);
239 if (unit == CSS_UNIT_PCT) {
242 return FIXTOINT(css_unit_len2device_px(style, unit_len_ctx,
262 int border_spacing_h = 0;
263 int table_min = 0, table_max = 0;
265 float extra_frac = 0;
267 struct box *row_group, *row, *cell;
268 enum css_width_e wtype;
270 css_unit unit = CSS_UNIT_PX;
277 NSLOG(netsurf, ERROR,
278 "Could not establish table column types.");
284 for (i = 0; i != table->
columns; i++) {
285 if (
col[i].
type == COLUMN_WIDTH_FIXED)
292 if (css_computed_border_collapse(table->
style) ==
293 CSS_BORDER_COLLAPSE_SEPARATE) {
294 css_fixed h = 0, v = 0;
295 css_unit hu = CSS_UNIT_PX, vu = CSS_UNIT_PX;
297 css_computed_border_spacing(table->
style, &h, &hu, &v, &vu);
299 border_spacing_h = FIXTOINT(css_unit_len2device_px(
306 for (row_group = table->
children; row_group; row_group =row_group->
next)
321 if (
col[i].positioned)
332 for (row_group = table->
children; row_group; row_group =row_group->
next)
335 unsigned int flexible_columns = 0;
336 int min = 0,
max = 0, fixed_width = 0, extra;
346 for (j = 0; j != cell->
columns; j++) {
348 if (
col[i + j].
type == COLUMN_WIDTH_FIXED)
353 min += (cell->
columns - 1) * border_spacing_h;
357 if (flexible_columns == 0) {
360 for (j = 0; j != cell->
columns; j++) {
368 for (j = 0; j != cell->
columns; j++) {
370 COLUMN_WIDTH_FIXED) {
382 for (j = 0; j != cell->
columns; j++)
384 max += (cell->
columns - 1) * border_spacing_h;
387 if (max < cell->
max_width && flexible_columns) {
389 for (j = 0; j != cell->
columns; j++)
390 if (
col[i + j].
type != COLUMN_WIDTH_FIXED)
395 for (i = 0; i != table->
columns; i++) {
405 wtype = css_computed_width(table->
style, &value, &unit);
406 if (wtype == CSS_WIDTH_SET && unit != CSS_UNIT_PCT) {
407 int width = FIXTOINT(css_unit_len2device_px(
411 if (table_min <
width)
413 if (table_max <
width)
420 &extra_fixed, &extra_frac);
423 &extra_fixed, &extra_frac);
428 if (1.0 <= extra_frac)
430 table->
min_width = (table_min + extra_fixed) / (1.0 - extra_frac);
431 table->
max_width = (table_max + extra_fixed) / (1.0 - extra_frac);
446 css_unit unit = CSS_UNIT_PX;
447 enum css_max_width_e
type;
452 type = css_computed_max_width(b->
style, &value, &unit);
453 return ((
type == CSS_MAX_WIDTH_SET) && (unit == CSS_UNIT_PCT));
473 bool *line_has_height,
490 no_wrap = (css_computed_white_space(block->
style) ==
491 CSS_WHITE_SPACE_NOWRAP ||
492 css_computed_white_space(block->
style) ==
493 CSS_WHITE_SPACE_PRE);
495 *line_has_height =
false;
498 for (b = first; b; b = b->
next) {
499 enum css_width_e wtype;
500 enum css_height_e htype;
501 enum css_box_sizing_e bs;
503 css_unit unit = CSS_UNIT_PX;
507 NSLOG(layout, DEBUG,
"%p: min %i, max %i", b,
min,
max);
537 *line_has_height =
true;
558 *line_has_height =
true;
571 font_func->
width(&fstyle,
" ", 1,
577 *line_has_height =
true;
587 no_wrap_box = (css_computed_white_space(b->
style) ==
588 CSS_WHITE_SPACE_NOWRAP ||
589 css_computed_white_space(b->
style) ==
590 CSS_WHITE_SPACE_PRE);
600 int opt_maxwidth = 0;
607 font_func->
width(&fstyle,
612 if (opt_maxwidth < opt_width)
613 opt_maxwidth =opt_width;
616 b->
width = opt_maxwidth;
629 font_func->
width(&fstyle,
" ", 1,
640 }
else if (no_wrap_box) {
653 for (j = i; j != b->
length &&
654 b->
text[j] !=
' '; j++)
664 *line_has_height =
true;
673 wtype = css_computed_width(b->
style, &
value, &unit);
674 bs = css_computed_box_sizing(block->
style);
675 if (wtype == CSS_WIDTH_SET) {
676 if (unit == CSS_UNIT_PCT) {
679 width = FIXTOINT(css_unit_len2device_px(
684 if (bs == CSS_BOX_SIZING_BORDER_BOX) {
706 htype = css_computed_height(b->
style, &
value, &unit);
707 if (htype == CSS_HEIGHT_SET) {
708 height = FIXTOINT(css_unit_len2device_px(
720 &
width, &temp_height,
726 if (bs == CSS_BOX_SIZING_BORDER_BOX) {
745 if (0 <
width + fixed)
753 if (bs == CSS_BOX_SIZING_BORDER_BOX) {
773 if (0 <
width + fixed)
779 width = FIXTOINT(css_unit_len2device_px(
782 INTTOFIX(1), CSS_UNIT_EM));
790 *line_has_height =
true;
798 min = (
min + text_indent < 0) ? 0 :
min + text_indent;
799 max = (
max + text_indent < 0) ? 0 :
max + text_indent;
805 NSLOG(layout, DEBUG,
"line_min %i, line_max %i",
min,
max);
808 assert(0 <= *line_min);
809 assert(*line_min <= *line_max);
830 int line_min = 0, line_max = 0;
832 bool first_line =
true;
833 bool line_has_height;
843 for (child = inline_container->
children; child; ) {
845 first_line, &line_has_height, font_func,
852 *has_height |= line_has_height;
858 assert(0 <= inline_container->
min_width &&
880 float extra_frac = 0;
881 enum css_width_e wtype = CSS_WIDTH_AUTO;
883 css_unit wunit = CSS_UNIT_PX;
884 enum css_height_e htype = CSS_HEIGHT_AUTO;
886 css_unit hunit = CSS_UNIT_PX;
887 enum css_box_sizing_e bs = CSS_BOX_SIZING_CONTENT_BOX;
888 bool using_min_border_box =
false;
889 bool using_max_border_box =
false;
890 bool child_has_height =
false;
902 if (block->
style != NULL) {
903 wtype = css_computed_width(block->
style, &
width, &wunit);
904 htype = css_computed_height(block->
style, &
height, &hunit);
905 bs = css_computed_box_sizing(block->
style);
912 wtype != CSS_WIDTH_SET) {
919 wtype != CSS_WIDTH_SET) {
931 block->
style && wtype == CSS_WIDTH_AUTO) {
932 css_fixed size = INTTOFIX(10);
933 css_unit unit = CSS_UNIT_EM;
935 min =
max = FIXTOINT(css_unit_len2device_px(block->
style,
936 &
content->unit_len_ctx, size, unit));
943 block->
style && wtype == CSS_WIDTH_AUTO) {
944 css_fixed size = INTTOFIX(1);
945 css_unit unit = CSS_UNIT_EM;
949 min =
max = FIXTOINT(css_unit_len2device_px(block->
style,
950 &
content->unit_len_ctx, size, unit));
972 for (child = block->
children; child; child = child->
next) {
973 switch (child->
type) {
979 child_has_height =
true;
986 &child_has_height, font_func,
988 if (child_has_height &&
998 child_has_height =
true;
1007 (css_computed_position(child->
style) ==
1008 CSS_POSITION_ABSOLUTE ||
1009 css_computed_position(child->
style) ==
1010 CSS_POSITION_FIXED)) {
1018 if (block->
style != NULL &&
1019 css_computed_flex_wrap(block->
style) ==
1020 CSS_FLEX_WRAP_NOWRAP) {
1035 if (child_has_height)
1047 bool border_box = bs == CSS_BOX_SIZING_BORDER_BOX;
1048 enum css_max_width_e max_type;
1049 enum css_min_width_e min_type;
1050 css_unit unit = CSS_UNIT_PX;
1051 css_fixed value = 0;
1053 if (wtype == CSS_WIDTH_SET && wunit != CSS_UNIT_PCT) {
1055 css_unit_len2device_px(block->
style,
1057 using_max_border_box = border_box;
1058 using_min_border_box = border_box;
1061 min_type = css_computed_min_width(block->
style, &value, &unit);
1062 if (min_type == CSS_MIN_WIDTH_SET && unit != CSS_UNIT_PCT) {
1063 int val = FIXTOINT(css_unit_len2device_px(block->
style,
1064 &
content->unit_len_ctx, value, unit));
1068 using_min_border_box = border_box;
1072 max_type = css_computed_max_width(block->
style, &value, &unit);
1073 if (max_type == CSS_MAX_WIDTH_SET && unit != CSS_UNIT_PCT) {
1074 int val = FIXTOINT(css_unit_len2device_px(block->
style,
1075 &
content->unit_len_ctx, value, unit));
1077 if (val >= 0 &&
max > val) {
1079 using_max_border_box = border_box;
1084 if (htype == CSS_HEIGHT_SET && hunit != CSS_UNIT_PCT &&
1094 false,
true,
true, &extra_fixed, &extra_frac);
1096 false,
true,
true, &extra_fixed, &extra_frac);
1098 if (using_max_border_box) {
1103 if (using_min_border_box) {
1113 true,
false,
false, &extra_fixed, &extra_frac);
1115 true,
false,
false, &extra_fixed, &extra_frac);
1117 if (extra_fixed < 0)
1121 if (1.0 <= extra_frac)
1123 if (block->
style != NULL &&
1124 (css_computed_float(block->
style) == CSS_FLOAT_LEFT ||
1125 css_computed_float(block->
style) == CSS_FLOAT_RIGHT)) {
1131 block->
min_width = (
min + extra_fixed) / (1.0 - extra_frac);
1132 block->
max_width = (
max + extra_fixed) / (1.0 - extra_frac);
1155 int viewport_height,
1156 int *max_pos_margin,
1157 int *max_neg_margin)
1159 assert(block != NULL);
1161 while (
box != NULL) {
1164 (css_computed_position(
box->
style) !=
1165 CSS_POSITION_ABSOLUTE &&
1166 css_computed_position(
box->
style) !=
1167 CSS_POSITION_FIXED))) {
1174 viewport_height,
box,
1176 NULL, NULL, NULL, NULL,
1183 else if (*max_neg_margin < -box->
margin[
TOP])
1193 css_computed_overflow_y(
box->
style) !=
1194 CSS_OVERFLOW_VISIBLE) ||
1206 css_computed_overflow_y(
box->
style) ==
1207 CSS_OVERFLOW_VISIBLE) {
1216 if (*max_pos_margin <
1220 else if (*max_neg_margin <
1249 viewport_height,
box,
1251 NULL, NULL, NULL, NULL,
1273 if ((clear == CSS_CLEAR_LEFT || clear == CSS_CLEAR_BOTH) &&
1277 if ((clear == CSS_CLEAR_RIGHT || clear == CSS_CLEAR_BOTH) &&
1304 int fy0, fy1, fx0, fx1;
1306 NSLOG(layout, DEBUG,
"y0 %i, y1 %i, x0 %i, x1 %i", y0, y1, *x0, *x1);
1318 if (y0 < fy1 && fy0 <= y1) {
1335 NSLOG(layout, DEBUG,
"x0 %i, x1 %i, left %p, right %p", *x0, *x1,
1360 int available_width,
1367 bool auto_width =
false;
1382 if (margin_left ==
AUTO) {
1385 if (margin_right ==
AUTO) {
1389 width = available_width -
1428 case CSS_TEXT_ALIGN_LIBCSS_RIGHT:
1432 case CSS_TEXT_ALIGN_LIBCSS_CENTER:
1435 case CSS_TEXT_ALIGN_LIBCSS_LEFT:
1448 (available_width - lm - rm -
1498 int available_width,
1499 int viewport_height,
1505 int height, max_height, min_height;
1513 &max_height, &min_height, margin, padding,
border);
1519 min_width, max_width, min_height, max_height);
1523 max_width, min_width);
1541 enum css_overflow_e overflow_x, overflow_y;
1548 overflow_x = css_computed_overflow_x(
box->
style);
1549 overflow_y = css_computed_overflow_y(
box->
style);
1552 (overflow_x == CSS_OVERFLOW_SCROLL ||
1553 overflow_x == CSS_OVERFLOW_AUTO ||
1558 (overflow_x == CSS_OVERFLOW_SCROLL ||
1563 }
else if (which ==
RIGHT &&
1564 (overflow_y == CSS_OVERFLOW_SCROLL ||
1565 overflow_y == CSS_OVERFLOW_AUTO ||
1569 enum css_height_e htype;
1571 css_unit hunit = CSS_UNIT_PX;
1575 htype == CSS_HEIGHT_SET &&
1576 (overflow_y == CSS_OVERFLOW_SCROLL ||
1606 int available_width,
1611 unsigned int *row_span;
1613 int table_width, min_width = 0, max_width = 0;
1614 int required_width = 0;
1615 int x, remainder = 0,
count = 0;
1616 int table_height = 0;
1621 int relative_sum = 0;
1622 int border_spacing_h = 0, border_spacing_v = 0;
1624 int positioned_columns = 0;
1625 struct box *containing_block = NULL;
1628 struct box *row_group;
1629 struct box **row_span_cell;
1631 const css_computed_style *style = table->
style;
1632 enum css_width_e wtype;
1633 enum css_height_e htype;
1634 css_fixed value = 0;
1635 css_unit unit = CSS_UNIT_PX;
1643 col = malloc(
columns *
sizeof col[0]);
1644 excess_y = malloc(
columns *
sizeof excess_y[0]);
1645 row_span = malloc(
columns *
sizeof row_span[0]);
1646 row_span_cell = malloc(
columns *
sizeof row_span_cell[0]);
1647 xs = malloc((
columns + 1) *
sizeof xs[0]);
1648 if (!col || !xs || !row_span || !excess_y || !row_span_cell) {
1652 free(row_span_cell);
1657 memcpy(col, table->
col,
sizeof(col[0]) *
columns);
1663 for (row_group = table->
children; row_group;
1664 row_group = row_group->
next) {
1665 for (row = row_group->
children; row; row = row->
next) {
1667 enum css_overflow_e overflow_x;
1668 enum css_overflow_e overflow_y;
1674 available_width, -1, c,
1675 c->
style, 0, 0, 0, 0, 0, 0,
1678 overflow_x = css_computed_overflow_x(c->
style);
1679 overflow_y = css_computed_overflow_y(c->
style);
1681 if (overflow_x == CSS_OVERFLOW_SCROLL ||
1683 CSS_OVERFLOW_AUTO) {
1686 if (overflow_y == CSS_OVERFLOW_SCROLL ||
1688 CSS_OVERFLOW_AUTO) {
1696 if (css_computed_border_collapse(style) ==
1697 CSS_BORDER_COLLAPSE_SEPARATE) {
1698 css_fixed h = 0, v = 0;
1699 css_unit hu = CSS_UNIT_PX, vu = CSS_UNIT_PX;
1701 css_computed_border_spacing(style, &h, &hu, &v, &vu);
1703 border_spacing_h = FIXTOINT(css_unit_len2device_px(
1704 style, &
content->unit_len_ctx, h, hu));
1705 border_spacing_v = FIXTOINT(css_unit_len2device_px(
1706 style, &
content->unit_len_ctx, v, vu));
1710 wtype = css_computed_width(style, &value, &unit);
1711 if (wtype == CSS_WIDTH_SET) {
1712 if (unit == CSS_UNIT_PCT) {
1716 FIXTOINT(css_unit_len2device_px(
1717 style, &
content->unit_len_ctx,
1724 table_width = table_width < 0 ? 0 : table_width;
1726 auto_width = table_width;
1729 auto_width = available_width -
1741 htype = css_computed_height(style, &value, &unit);
1742 if (htype == CSS_HEIGHT_SET) {
1743 if (unit == CSS_UNIT_PCT) {
1746 if (css_computed_position(table->
style) ==
1747 CSS_POSITION_ABSOLUTE) {
1752 css_computed_position(table->
style) !=
1753 CSS_POSITION_ABSOLUTE &&
1754 (css_computed_float(table->
style) ==
1756 css_computed_float(table->
style) ==
1766 containing_block = table->
parent;
1774 if (containing_block) {
1775 css_fixed ignored = 0;
1777 htype = css_computed_height(
1778 containing_block->
style,
1782 if (containing_block &&
1784 (css_computed_position(table->
style) ==
1785 CSS_POSITION_ABSOLUTE ||
1786 htype == CSS_HEIGHT_SET)) {
1791 containing_block->
height);
1796 min_height = FIXTOINT(css_unit_len2device_px(
1797 style, &
content->unit_len_ctx,
1803 for (i = 0; i !=
columns; i++) {
1805 NSLOG(layout, DEBUG,
1806 "table %p, column %u: type %s, width %i, min %i, max %i",
1822 positioned_columns++;
1829 required_width += col[i].
width;
1835 required_width += col[i].
min;
1837 NSLOG(layout, DEBUG,
"required_width %i", required_width);
1839 required_width += (
columns + 1 - positioned_columns) *
1842 NSLOG(layout, DEBUG,
1843 "width %i, min %i, max %i, auto %i, required %i", table_width,
1846 if (auto_width < required_width) {
1849 for (i = 0; i !=
columns; i++) {
1853 col[i].
max = auto_width * col[i].
width / 100;
1854 if (col[i].
max < col[i].
min)
1857 min_width += col[i].
min;
1858 max_width += col[i].
max;
1862 for (i = 0; i !=
columns; i++) {
1872 min_width += col[i].
min;
1873 max_width += col[i].
max;
1878 spare_width = auto_width;
1879 for (i = 0; i !=
columns; i++) {
1881 relative_sum += col[i].
width;
1883 spare_width -= col[i].
width;
1885 spare_width -= col[i].
min;
1887 spare_width -= (
columns + 1) * border_spacing_h;
1888 if (relative_sum != 0) {
1889 if (spare_width < 0)
1891 for (i = 0; i !=
columns; i++) {
1893 col[i].
min = ceil(col[i].
max =
1895 * (
float) col[i].
width
1897 min_width += col[i].
min;
1898 max_width += col[i].
max;
1902 min_width += (
columns + 1) * border_spacing_h;
1903 max_width += (
columns + 1) * border_spacing_h;
1905 if (auto_width <= min_width) {
1907 for (i = 0; i <
columns; i++) {
1910 table_width = min_width;
1911 }
else if (max_width <= auto_width) {
1913 if (table_width ==
AUTO) {
1915 for (i = 0; i <
columns; i++) {
1918 table_width = max_width;
1922 unsigned int flexible_columns = 0;
1923 for (i = 0; i !=
columns; i++)
1926 if (flexible_columns == 0) {
1927 int extra = (table_width - max_width) /
columns;
1928 remainder = (table_width - max_width) -
1930 for (i = 0; i !=
columns; i++) {
1940 int extra = (table_width - max_width) /
1942 remainder = (table_width - max_width) -
1943 (extra * flexible_columns);
1944 for (i = 0; i !=
columns; i++)
1951 count += flexible_columns;
1958 float scale = (float) (auto_width - min_width) /
1959 (float) (max_width - min_width);
1961 for (i = 0; i <
columns; i++) {
1962 col[i].
width = col[i].
min + (int) (0.5 +
1963 (col[i].
max - col[i].
min) * scale);
1965 table_width = auto_width;
1968 xs[0] = x = border_spacing_h;
1969 for (i = 0; i !=
columns; i++) {
1971 x += col[i].
width + border_spacing_h;
1975 row_span_cell[i] = 0;
1979 table_height = border_spacing_v;
1980 for (row_group = table->
children; row_group;
1981 row_group = row_group->
next) {
1982 int row_group_height = 0;
1983 for (row = row_group->
children; row; row = row->
next) {
1986 htype = css_computed_height(row->
style, &value, &unit);
1987 if (htype == CSS_HEIGHT_SET && unit != CSS_UNIT_PCT) {
1988 row_height = FIXTOINT(css_unit_len2device_px(
2010 free(row_span_cell);
2020 htype = css_computed_height(c->
style,
2023 if (htype == CSS_HEIGHT_SET &&
2024 unit != CSS_UNIT_PCT) {
2028 int h = FIXTOINT(css_unit_len2device_px(
2037 if (c->
height < row_height)
2042 for (i = 0; i != c->
columns; i++) {
2059 for (i = 0; i !=
columns; i++)
2060 if (row_span[i] != 0)
2063 row_span_cell[i] = 0;
2064 if (row->
next || row_group->
next) {
2067 for (i = 0; i !=
columns; i++)
2068 if (row_span[i] == 0 && row_height <
2070 row_height = excess_y[i];
2073 for (i = 0; i !=
columns; i++)
2074 if (row_height < excess_y[i])
2075 row_height = excess_y[i];
2077 for (i = 0; i !=
columns; i++) {
2078 if (row_height < excess_y[i])
2079 excess_y[i] -= row_height;
2082 if (row_span_cell[i] != 0)
2089 row->
y = row_group_height;
2090 row->
width = table_width;
2091 row->
height = row_height;
2092 row_group_height += row_height + border_spacing_v;
2095 row_group->
y = table_height;
2096 row_group->
width = table_width;
2097 row_group->
height = row_group_height;
2098 table_height += row_group_height;
2102 table_height =
max(table_height, min_height);
2106 for (row_group = table->
children; row_group;
2107 row_group = row_group->
next) {
2108 for (row = row_group->
children; row; row = row->
next) {
2110 enum css_vertical_align_e vertical_align;
2119 vertical_align = css_computed_vertical_align(
2120 c->
style, &value, &unit);
2122 switch (vertical_align) {
2123 case CSS_VERTICAL_ALIGN_SUB:
2124 case CSS_VERTICAL_ALIGN_SUPER:
2125 case CSS_VERTICAL_ALIGN_TEXT_TOP:
2126 case CSS_VERTICAL_ALIGN_TEXT_BOTTOM:
2127 case CSS_VERTICAL_ALIGN_SET:
2128 case CSS_VERTICAL_ALIGN_BASELINE:
2131 case CSS_VERTICAL_ALIGN_TOP:
2133 case CSS_VERTICAL_ALIGN_MIDDLE:
2139 case CSS_VERTICAL_ALIGN_BOTTOM:
2145 case CSS_VERTICAL_ALIGN_INHERIT:
2162 free(row_span_cell);
2165 table->
width = table_width;
2166 table->
height = table_height;
2182 const css_unit_ctx *unit_len_ctx,
2184 struct box *container)
2187 struct box *containing_block = NULL;
2188 bool updated =
false;
2192 CSS_POSITION_ABSOLUTE) {
2195 containing_block = container;
2197 (css_computed_float(
box->
style) == CSS_FLOAT_LEFT ||
2198 css_computed_float(
box->
style) == CSS_FLOAT_RIGHT)) {
2213 enum css_height_e htype = CSS_HEIGHT_AUTO;
2214 css_fixed value = 0;
2215 css_unit unit = CSS_UNIT_PX;
2217 if (containing_block) {
2218 htype = css_computed_height(containing_block->
style,
2223 if (css_computed_max_height(
box->
style, &value, &unit) ==
2224 CSS_MAX_HEIGHT_SET) {
2225 if (unit == CSS_UNIT_PCT) {
2226 if (containing_block &&
2228 (css_computed_position(
box->
style) ==
2229 CSS_POSITION_ABSOLUTE ||
2230 htype == CSS_HEIGHT_SET)) {
2236 containing_block->
height);
2243 h = FIXTOINT(css_unit_len2device_px(
2255 CSS_MIN_HEIGHT_SET) {
2256 if (unit == CSS_UNIT_PCT) {
2257 if (containing_block &&
2259 (css_computed_position(
box->
style) ==
2260 CSS_POSITION_ABSOLUTE ||
2261 htype == CSS_HEIGHT_SET)) {
2267 containing_block->
height);
2274 h = FIXTOINT(css_unit_len2device_px(
2305 NSLOG(layout, DEBUG,
"block %p, object %p, width %i", block,
2331 int b_bottom = b->
y + b->
height;
2374 struct box *split_box,
2378 int space_width = split_box->
space;
2381 bool space = (split_box->
text[new_length] ==
' ');
2382 int used_length = new_length + (space ? 1 : 0);
2384 if ((space && space_width == 0) || space_width ==
UNKNOWN_WIDTH) {
2388 font_func->
width(fstyle,
" ", 1, &space_width);
2392 split_box->
space = space_width;
2403 c2->
text += used_length;
2406 c2->
width -= new_width + space_width;
2407 c2->
flags &= ~MEASURED;
2411 split_box->
width = new_width;
2413 split_box->
length = new_length;
2414 split_box->
space = space_width;
2418 split_box->
next = c2;
2419 c2->
prev = split_box;
2425 NSLOG(layout, DEBUG,
2426 "split_box %p len: %" PRIsizet " \"%.*s\"",
2431 NSLOG(layout, DEBUG,
2432 " new_box %p len: %" PRIsizet " \"%.*s\"",
2455 const css_unit_ctx *unit_len_ctx,
2456 int available_width,
2457 const css_computed_style *style,
2460 int width,
height, max_width, min_width, max_height, min_height;
2464 enum css_overflow_e overflow_x = css_computed_overflow_x(
style);
2465 enum css_overflow_e overflow_y = css_computed_overflow_y(
style);
2466 int scrollbar_width_x =
2467 (overflow_x == CSS_OVERFLOW_SCROLL ||
2468 overflow_x == CSS_OVERFLOW_AUTO) ?
2470 int scrollbar_width_y =
2471 (overflow_y == CSS_OVERFLOW_SCROLL ||
2472 overflow_y == CSS_OVERFLOW_AUTO) ?
2477 &max_height, &min_height, margin, padding,
border);
2485 padding[
RIGHT] += scrollbar_width_y;
2486 padding[
BOTTOM] += scrollbar_width_x;
2494 min_width, max_width, min_height, max_height);
2500 css_unit unit = CSS_UNIT_EM;
2510 size = INTTOFIX(10);
2511 width = FIXTOINT(css_unit_len2device_px(
2517 size = FLTTOFIX(1.5);
2518 height = FIXTOINT(css_unit_len2device_px(
2525 size = INTTOFIX(10);
2526 width = FIXTOINT(css_unit_len2device_px(
2532 height = FIXTOINT(css_unit_len2device_px(
2543 if (
width == available_width) {
2556 true,
true,
true, &fixed, &frac);
2558 true,
true,
true, &fixed, &frac);
2565 if (max_width >= 0 &&
width > max_width)
width = max_width;
2566 if (min_width > 0 &&
width < min_width)
width = min_width;
2569 if (max_width >= 0 &&
width > max_width)
width = max_width;
2570 if (min_width > 0 &&
width < min_width)
width = min_width;
2571 width -= scrollbar_width_y;
2642 NSLOG(layout, DEBUG,
2643 "c %p, width %i, cx %i, y %i, cont %p", c,
2652 if (left != 0 && right != 0) {
2653 yy = (left->
y + left->
height <
2657 }
else if (left == 0 && right != 0) {
2658 yy = right->
y + right->
height;
2659 }
else if (left != 0 && right == 0) {
2662 }
while ((left != 0 || right != 0) && (c->
width > x1 - x0));
2678 const css_unit_ctx *unit_len_ctx,
2679 const css_computed_style *
style)
2681 enum css_line_height_e lhtype;
2682 css_fixed lhvalue = 0;
2683 css_unit lhunit = CSS_UNIT_PX;
2688 lhtype = css_computed_line_height(
style, &lhvalue, &lhunit);
2689 if (lhtype == CSS_LINE_HEIGHT_NORMAL) {
2691 lhvalue = FLTTOFIX(1.3);
2692 lhtype = CSS_LINE_HEIGHT_NUMBER;
2695 if (lhtype == CSS_LINE_HEIGHT_NUMBER ||
2696 lhunit == CSS_UNIT_PCT) {
2698 lhvalue, CSS_UNIT_EM);
2700 if (lhtype != CSS_LINE_HEIGHT_NUMBER)
2703 assert(lhunit != CSS_UNIT_PCT);
2737 bool has_text_children,
2739 struct box **next_box)
2744 int x, h, x_previous;
2749 struct box *split_box = 0;
2751 struct box *br_box = 0;
2752 bool move_y =
false;
2753 bool place_below =
false;
2754 int space_before = 0, space_after = 0;
2755 unsigned int inline_count = 0;
2760 NSLOG(layout, DEBUG,
2761 "first %p, first->text '%.*s', width %i, y %i, cx %i, cy %i",
2793 used_height =
height = 0;
2799 NSLOG(layout, DEBUG,
"x0 %i, x1 %i, x1 - x0 %i", x0, x1, x1 - x0);
2802 for (x = 0, b = first; x <= x1 - x0 && b != 0; b = b->
next) {
2803 int min_width, max_width, min_height, max_height;
2807 NSLOG(layout, DEBUG,
"pass 1: b %p, x %i", b, x);
2815 (css_computed_position(b->
style) ==
2816 CSS_POSITION_ABSOLUTE ||
2817 css_computed_position(b->
style) ==
2818 CSS_POSITION_FIXED))
2821 assert(b->
style != NULL);
2850 for (i = 0; i != 4; i++)
2869 font_func->
width(&fstyle,
" ", 1, &b->
space);
2872 space_after = b->
space;
2901 int opt_maxwidth = 0;
2908 font_func->
width(&fstyle,
2913 if (opt_maxwidth < opt_width)
2914 opt_maxwidth =opt_width;
2916 b->
width = opt_maxwidth;
2930 if (b->
text && (x + b->
width < x1 - x0) &&
2940 font_func->
width(&fstyle,
" ", 1, &b->
space);
2943 space_after = b->
space;
2955 &max_width, &min_width,
2956 &max_height, &min_height,
2961 min_width, max_width,
2962 min_height, max_height);
2975 b->
width = FIXTOINT(css_unit_len2device_px(
2977 &
content->unit_len_ctx, INTTOFIX(1),
2980 b->
height = FIXTOINT(css_unit_len2device_px(
2982 &
content->unit_len_ctx, INTTOFIX(1),
2990 css_fixed
value = 0;
2991 css_unit unit = CSS_UNIT_PX;
2992 enum css_height_e htype = css_computed_height(b->
style,
2997 if (htype == CSS_HEIGHT_AUTO)
3022 space_after = space_before = 0;
3026 NSLOG(layout, DEBUG,
"x0 %i, x1 %i, x1 - x0 %i", x0, x1, x1 - x0);
3028 for (x = x_previous = 0, b = first; x <= x1 - x0 && b; b = b->
next) {
3030 NSLOG(layout, DEBUG,
"pass 2: b %p, x %i", b, x);
3033 (css_computed_position(b->
style) ==
3034 CSS_POSITION_ABSOLUTE ||
3035 css_computed_position(b->
style) ==
3036 CSS_POSITION_FIXED)) {
3037 b->
x = x + space_after;
3066 space_before = space_after;
3076 font_func->
width(&fstyle,
" ", 1,
3079 space_after = b->
space;
3097 NSLOG(layout, DEBUG,
"float %p", b);
3107 NSLOG(layout, DEBUG,
3126 if (b->
width > (x1 - x0) - x)
3128 if (d->
style && (css_computed_clear(d->
style) ==
3130 (css_computed_clear(d->
style) ==
3131 CSS_CLEAR_LEFT && left == 0) ||
3132 (css_computed_clear(d->
style) ==
3135 (css_computed_clear(d->
style) ==
3137 left == 0 && right == 0)) &&
3139 (left == 0 && right == 0 && x == 0)) &&
3155 b->
x = cx + x1 - b->
width;
3169 fy = (fy > fcy) ? fy : fcy;
3170 fy = (fy == cy) ? fy +
height : fy;
3175 (css_computed_clear(d->
style) ==
3176 CSS_CLEAR_LEFT && left != 0) ||
3177 (css_computed_clear(d->
style) ==
3180 (css_computed_clear(d->
style) ==
3182 (left != 0 || right != 0)))) {
3191 css_computed_clear(d->
style));
3208 if (x1 - x0 < x && split_box) {
3212 bool no_wrap = css_computed_white_space(
3213 split_box->
style) == CSS_WHITE_SPACE_NOWRAP ||
3214 css_computed_white_space(
3215 split_box->
style) == CSS_WHITE_SPACE_PRE;
3228 split_box->
style, &fstyle);
3230 font_func->
split(&fstyle,
3233 x1 - x0 - x - space_before,
3241 w = split_box->
width;
3244 NSLOG(layout, DEBUG,
3245 "splitting: split_box %p \"%.*s\", spilt %"PRIsizet
3246 ", w %i, left %p, right %p, inline_count %u",
3256 if ((split == 0 || x1 - x0 <= x + space_before + w) &&
3257 !left && !right && inline_count == 1) {
3260 if (split == 0 || split == split_box->
length) {
3263 b = split_box->
next;
3267 split_box, split, w))
3269 b = split_box->
next;
3271 x += space_before + w;
3273 NSLOG(layout, DEBUG,
"forcing");
3275 }
else if ((split == 0 || x1 - x0 <= x + space_before + w) &&
3276 inline_count == 1) {
3279 assert(left || right);
3283 NSLOG(layout, DEBUG,
3284 "cy %i, left->y %i, left->height %i",
3289 used_height = left->
y + left->
height - cy + 1;
3291 NSLOG(layout, DEBUG,
"used_height %i",
3295 if (right && used_height <
3296 right->
y + right->
height - cy + 1)
3297 used_height = right->
y + right->
height - cy + 1;
3299 if (used_height < 0)
3304 NSLOG(layout, DEBUG,
"moving below float");
3306 }
else if (split == 0 || x1 - x0 <= x + space_before + w) {
3311 NSLOG(layout, DEBUG,
"leaving for next line");
3317 NSLOG(layout, DEBUG,
3322 if (split != split_box->
length) {
3324 split_box, split, w))
3326 b = split_box->
next;
3328 x += space_before + w;
3330 NSLOG(layout, DEBUG,
"fitting words");
3338 case CSS_TEXT_ALIGN_RIGHT:
3339 case CSS_TEXT_ALIGN_LIBCSS_RIGHT:
3342 case CSS_TEXT_ALIGN_CENTER:
3343 case CSS_TEXT_ALIGN_LIBCSS_CENTER:
3344 x0 = (x0 + (x1 - x)) / 2;
3346 case CSS_TEXT_ALIGN_LEFT:
3347 case CSS_TEXT_ALIGN_LIBCSS_LEFT:
3348 case CSS_TEXT_ALIGN_JUSTIFY:
3351 case CSS_TEXT_ALIGN_DEFAULT:
3354 case CSS_DIRECTION_LTR:
3357 case CSS_DIRECTION_RTL:
3364 for (d = first; d != b; d = d->
next) {
3365 d->
flags &= ~NEW_LINE;
3368 (css_computed_position(d->
style) ==
3369 CSS_POSITION_ABSOLUTE ||
3370 css_computed_position(d->
style) ==
3371 CSS_POSITION_FIXED)) {
3401 if (used_height < h)
3408 assert(b != first || (move_y && 0 < used_height && (left || right)));
3412 for (d = first; d != b; d = d->
next) {
3417 css_fixed
value = 0;
3418 css_unit unit = CSS_UNIT_PX;
3419 switch (css_computed_vertical_align(d->
style, &
value,
3421 case CSS_VERTICAL_ALIGN_SUPER:
3422 case CSS_VERTICAL_ALIGN_TOP:
3423 case CSS_VERTICAL_ALIGN_TEXT_TOP:
3426 case CSS_VERTICAL_ALIGN_SUB:
3427 case CSS_VERTICAL_ALIGN_BOTTOM:
3428 case CSS_VERTICAL_ALIGN_TEXT_BOTTOM:
3429 d->
y += used_height - d->
height;
3432 case CSS_VERTICAL_ALIGN_BASELINE:
3433 d->
y += 0.75 * (used_height - d->
height);
3440 if (br_box && css_computed_clear(br_box->
style) != CSS_CLEAR_NONE) {
3442 css_computed_clear(br_box->
style));
3443 if (used_height < clear_y - cy)
3444 used_height = clear_y - cy;
3469 bool first_line =
true;
3470 bool has_text_children;
3473 int curwidth,maxwidth =
width;
3477 NSLOG(layout, DEBUG,
3478 "inline_container %p, width %i, cont %p, cx %i, cy %i",
3486 has_text_children =
false;
3488 bool is_pre =
false;
3491 enum css_white_space_e whitespace;
3493 whitespace = css_computed_white_space(c->
style);
3495 is_pre = (whitespace == CSS_WHITE_SPACE_PRE ||
3496 whitespace == CSS_WHITE_SPACE_PRE_LINE ||
3497 whitespace == CSS_WHITE_SPACE_PRE_WRAP);
3503 has_text_children =
true;
3510 for (c = inline_container->
children; c; ) {
3512 NSLOG(layout, DEBUG,
"c %p", c);
3514 curwidth = inline_container->
width;
3515 if (!
layout_line(c, &curwidth, &
y, cx, cy +
y, cont, first_line,
3518 maxwidth =
max(maxwidth,curwidth);
3523 inline_container->
width = maxwidth;
3533 int viewport_height,
3538 int max_pos_margin = 0;
3539 int max_neg_margin = 0;
3542 struct box *margin_collapse = NULL;
3543 bool in_margin =
false;
3544 css_fixed gadget_size;
3545 css_unit gadget_unit;
3561 int temp_width = block->
width;
3565 &block->
height, INT_MIN, INT_MAX,
3577 gadget_unit = CSS_UNIT_EM;
3578 gadget_size = INTTOFIX(1);
3580 block->
height = FIXTOINT(css_unit_len2device_px(
3583 gadget_size, gadget_unit));
3617 enum css_overflow_e overflow_x = CSS_OVERFLOW_VISIBLE;
3618 enum css_overflow_e overflow_y = CSS_OVERFLOW_VISIBLE;
3634 (css_computed_position(
box->
style) ==
3635 CSS_POSITION_ABSOLUTE ||
3636 css_computed_position(
box->
style) ==
3637 CSS_POSITION_FIXED)) {
3642 goto advance_to_next_box;
3647 if (margin_collapse == NULL) {
3651 &max_pos_margin, &max_neg_margin);
3665 overflow_x = css_computed_overflow_x(
box->
style);
3666 overflow_y = css_computed_overflow_y(
box->
style);
3678 (overflow_x != CSS_OVERFLOW_VISIBLE ||
3679 overflow_y != CSS_OVERFLOW_VISIBLE)) {
3684 struct box *left, *right;
3685 top = cy + max_pos_margin - max_neg_margin;
3686 top = (top >
y) ? top :
y;
3692 &x0, &x1, &left, &right);
3703 viewport_height, lm, rm,
box);
3710 enum css_width_e wtype;
3711 css_fixed
width = 0;
3712 css_unit unit = CSS_UNIT_PX;
3717 if (wtype == CSS_WIDTH_AUTO) {
3721 struct box *left, *right;
3722 top = cy + max_pos_margin -
3724 top = (top >
y) ? top :
y;
3765 margin_collapse ==
box) &&
3766 in_margin ==
true) {
3768 cy += max_pos_margin - max_neg_margin;
3769 box->
y += max_pos_margin - max_neg_margin;
3773 max_pos_margin = max_neg_margin = 0;
3778 (
y > 0) && (cy <
y)) {
3788 (overflow_x != CSS_OVERFLOW_VISIBLE ||
3789 overflow_y != CSS_OVERFLOW_VISIBLE))) {
3816 goto advance_to_next_box;
3819 NSLOG(layout, DEBUG,
"box %p, cx %i, cy %i, width %i",
3836 struct box *left, *right;
3839 enum css_width_e wtype;
3840 css_fixed
width = 0;
3841 css_unit unit = CSS_UNIT_PX;
3843 wtype = css_computed_width(
box->
style,
3850 &x0, &x1, &left, &right);
3851 if (wtype == CSS_WIDTH_AUTO)
3855 if (!left && !right)
3861 else if (left->
y + left->
height <
3878 if (
box == margin_collapse) {
3881 margin_collapse = NULL;
3905 advance_to_next_box:
3911 if (
box == margin_collapse) {
3914 margin_collapse = NULL;
3931 margin_collapse = NULL;
3933 max_pos_margin = max_neg_margin = 0;
3949 css_computed_position(
box->
style) !=
3950 CSS_POSITION_ABSOLUTE &&
3974 if (
box == margin_collapse) {
3977 margin_collapse = NULL;
3990 cy += max_pos_margin - max_neg_margin;
4006 if (block->
style && css_computed_position(block->
style) !=
4007 CSS_POSITION_ABSOLUTE) {
4022 block->
style, &fstyle);
4025 &fstyle, ta_width, ta_height,
4042 const dom_node *
node,
4043 dom_html_element_type *
type)
4045 dom_html_element_type element_type;
4046 dom_node_type node_type;
4049 exc = dom_node_get_node_type(
node, &node_type);
4050 if (exc != DOM_NO_ERR ||
4051 node_type != DOM_ELEMENT_NODE) {
4055 exc = dom_html_element_get_tag_type(
node, &element_type);
4056 if (exc != DOM_NO_ERR) {
4060 *
type = element_type;
4074 const dom_node *
node,
4075 dom_html_element_type
type)
4077 dom_html_element_type element_type;
4083 return element_type ==
type;
4110 exc = dom_element_has_attribute(li_node,
4111 corestring_dom_value,
4113 if (exc != DOM_NO_ERR || has_value ==
false) {
4117 exc = dom_html_li_element_get_value(
4118 (dom_html_li_element *)li_node,
4120 if (exc != DOM_NO_ERR) {
4146 exc = dom_element_has_attribute(ol_node,
4147 corestring_dom_start,
4149 if (exc != DOM_NO_ERR || has_start ==
false) {
4153 exc = dom_html_olist_element_get_start(
4154 (dom_html_olist_element *)ol_node,
4156 if (exc != DOM_NO_ERR) {
4177 exc = dom_element_has_attribute(ol_node,
4178 corestring_dom_reversed,
4180 if (exc != DOM_NO_ERR) {
4184 return has_reversed;
4197 dom_node *list_owner, dom_long *count_out)
4199 dom_html_element_type tag_type;
4204 if (list_owner == NULL) {
4212 if (tag_type != DOM_HTML_ELEMENT_TYPE_OL &&
4213 tag_type != DOM_HTML_ELEMENT_TYPE_UL) {
4217 exc = dom_node_get_first_child(list_owner, &child);
4218 if (exc != DOM_NO_ERR) {
4223 while (child != NULL) {
4224 dom_node *temp_node;
4227 DOM_HTML_ELEMENT_TYPE_LI)) {
4228 struct box *child_box;
4229 if (dom_node_get_user_data(child,
4230 corestring_dom___ns_key_box_node_data,
4231 &child_box) != DOM_NO_ERR) {
4232 dom_node_unref(child);
4236 if (child_box != NULL &&
4242 exc = dom_node_get_next_sibling(child, &temp_node);
4243 dom_node_unref(child);
4244 if (exc != DOM_NO_ERR) {
4265 dom_html_element_type tag_type;
4279 if (tag_type != DOM_HTML_ELEMENT_TYPE_OL &&
4280 tag_type != DOM_HTML_ELEMENT_TYPE_UL) {
4285 if (tag_type == DOM_HTML_ELEMENT_TYPE_OL) {
4289 if (have_reversed) {
4293 if (!have_start && have_reversed) {
4298 exc = dom_node_get_first_child(
box->
node, &child);
4299 if (exc != DOM_NO_ERR) {
4303 while (child != NULL) {
4304 dom_node *temp_node;
4307 DOM_HTML_ELEMENT_TYPE_LI)) {
4308 struct box *child_box;
4310 if (dom_node_get_user_data(child,
4311 corestring_dom___ns_key_box_node_data,
4312 &child_box) != DOM_NO_ERR) {
4313 dom_node_unref(child);
4317 if (child_box != NULL &&
4331 exc = dom_node_get_next_sibling(child, &temp_node);
4332 dom_node_unref(child);
4333 if (exc != DOM_NO_ERR) {
4362 LIST_MARKER_SIZE = 20,
4366 if (marker->
text == NULL) {
4371 marker->
text, LIST_MARKER_SIZE, &counter_len);
4372 if (css_res == CSS_OK) {
4373 if (counter_len > LIST_MARKER_SIZE) {
4380 if (marker->
text == NULL) {
4383 css_computed_format_list_style(
box->
style,
4385 counter_len, &counter_len);
4387 marker->
length = counter_len;
4399 const struct box *b)
4401 enum css_list_style_type_e t = css_computed_list_style_type(b->
style);
4404 case CSS_LIST_STYLE_TYPE_DISC:
4405 case CSS_LIST_STYLE_TYPE_CIRCLE:
4406 case CSS_LIST_STYLE_TYPE_SQUARE:
4407 case CSS_LIST_STYLE_TYPE_NONE:
4430 if (marker->
text == NULL) {
4438 marker->
x = -marker->
width;
4445 }
else if (marker->
text) {
4458 marker->
x = -marker->
width;
4494 struct box *containing_block,
4501 css_fixed value = 0;
4502 css_unit unit = CSS_UNIT_PX;
4505 assert(containing_block->
width !=
AUTO);
4510 if (
type == CSS_LEFT_SET) {
4511 if (unit == CSS_UNIT_PCT) {
4513 containing_block->
width);
4515 *left = FIXTOINT(css_unit_len2device_px(
4525 if (
type == CSS_RIGHT_SET) {
4526 if (unit == CSS_UNIT_PCT) {
4528 containing_block->
width);
4530 *right = FIXTOINT(css_unit_len2device_px(
4540 if (
type == CSS_TOP_SET) {
4541 if (unit == CSS_UNIT_PCT) {
4543 containing_block->
height);
4545 *top = FIXTOINT(css_unit_len2device_px(
4555 if (
type == CSS_BOTTOM_SET) {
4556 if (unit == CSS_UNIT_PCT) {
4558 containing_block->
height);
4560 *bottom = FIXTOINT(css_unit_len2device_px(
4582 struct box *containing_block,
4586 int static_left, static_top;
4587 int top, right, bottom, left;
4592 int available_width = containing_block->
width;
4603 static_left = cx +
box->
x;
4604 static_top = cy +
box->
y;
4619 &top, &right, &bottom, &left);
4627 &max_width, &min_width, 0, 0,
4628 margin, padding,
border);
4632 NSLOG(layout, DEBUG,
4633 "%i + %i + %i + %i + %i + %i + %i + %i + %i = %i",
4636 containing_block->
width);
4653 if (max_width >= 0 &&
width > max_width)
width = max_width;
4656 right = containing_block->
width -
4664 if (max_width >= 0 &&
width > max_width)
width = max_width;
4665 if (min_width > 0 &&
width < min_width)
width = min_width;
4668 space = containing_block->
width -
4674 margin[
RIGHT] = space;
4676 margin[
LEFT] = margin[
RIGHT] = space / 2;
4679 margin[
LEFT] = containing_block->
width -
4686 left - margin[
LEFT] -
4691 right = containing_block->
width -
4692 left - margin[
LEFT] -
4704 available_width -= right;
4713 if (max_width >= 0 &&
width > max_width)
4715 if (
width < min_width)
4718 left = containing_block->
width -
4726 if (max_width >= 0 &&
width > max_width)
4728 if (min_width > 0 &&
width < min_width)
4732 right = containing_block->
width -
4733 left - margin[
LEFT] -
4738 available_width -= left;
4747 if (max_width >= 0 &&
width > max_width)
4749 if (
width < min_width)
4752 right = containing_block->
width -
4753 left - margin[
LEFT] -
4760 if (max_width >= 0 &&
width > max_width)
4762 if (
width < min_width)
4765 left = containing_block->
width -
4772 left - margin[
LEFT] -
4779 if (max_width >= 0 &&
width > max_width)
4781 if (
width < min_width)
4787 if (max_width >= 0 &&
width > max_width)
4789 if (
width < min_width)
4792 right = containing_block->
width -
4793 left - margin[
LEFT] -
4800 NSLOG(layout, DEBUG,
4801 "%i + %i + %i + %i + %i + %i + %i + %i + %i = %i",
4804 containing_block->
width);
4843 NSLOG(layout, DEBUG,
4844 "%i + %i + %i + %i + %i + %i + %i + %i + %i = %i",
4847 containing_block->
height);
4856 bottom = containing_block->
height -
4862 space = containing_block->
height -
4866 margin[
TOP] = margin[
BOTTOM] = space / 2;
4867 }
else if (margin[
TOP] ==
AUTO) {
4868 margin[
TOP] = containing_block->
height -
4880 bottom = containing_block->
height -
4893 top = containing_block->
height -
4900 bottom = containing_block->
height -
4907 bottom = containing_block->
height -
4913 top = containing_block->
height -
4925 bottom = containing_block->
height -
4933 NSLOG(layout, DEBUG,
4934 "%i + %i + %i + %i + %i + %i + %i + %i + %i = %i",
4937 containing_block->
height);
4968 struct box *containing_block,
4979 (css_computed_position(c->
style) ==
4980 CSS_POSITION_ABSOLUTE ||
4981 css_computed_position(c->
style) ==
4982 CSS_POSITION_FIXED)) {
4988 }
else if (c->
style && css_computed_position(c->
style) ==
4989 CSS_POSITION_RELATIVE) {
4994 if (c->
style && (css_computed_float(c->
style) ==
4996 css_computed_float(c->
style) ==
5035 const css_unit_ctx *unit_len_ctx,
5040 int left, right, top, bottom;
5041 struct box *containing_block;
5044 css_computed_position(
box->
style) ==
5045 CSS_POSITION_RELATIVE);
5048 (css_computed_float(
box->
style) == CSS_FLOAT_LEFT ||
5049 css_computed_float(
box->
style) == CSS_FLOAT_RIGHT)) {
5056 &top, &right, &bottom, &left);
5060 else if (left ==
AUTO)
5063 else if (right ==
AUTO)
5069 if (containing_block->
style &&
5070 css_computed_direction(
5071 containing_block->
style) ==
5072 CSS_DIRECTION_RTL) {
5081 assert(left == -right);
5083 if (top ==
AUTO && bottom ==
AUTO) {
5085 }
else if (top ==
AUTO) {
5092 NSLOG(layout, DEBUG,
"left %i, right %i, top %i, bottom %i", left,
5093 right, top, bottom);
5116 const css_unit_ctx *unit_len_ctx,
5143 CSS_POSITION_RELATIVE)
5145 unit_len_ctx,
box, &
x, &
y);
5156 (fx != 0 || fy != 0)) {
5185 css_computed_position(
box->
style) !=
5186 CSS_POSITION_RELATIVE))
5219 const css_unit_ctx *unit_len_ctx,
5221 int *desc_x0,
int *desc_y0,
5222 int *desc_x1,
int *desc_y1)
5234 css_computed_overflow_y(
box->
style) ==
5235 CSS_OVERFLOW_VISIBLE &&
5237 css_fixed font_size = 0;
5238 css_unit font_unit = CSS_UNIT_PT;
5241 css_computed_font_size(
box->
style, &font_size, &font_unit);
5242 text_height = css_unit_len2device_px(
box->
style, unit_len_ctx,
5243 font_size, font_unit);
5244 text_height = FIXTOINT(text_height * 3 / 4);
5245 *desc_y0 = (*desc_y0 < -text_height) ? *desc_y0 : -text_height;
5261 const css_unit_ctx *unit_len_ctx,
5267 int child_desc_x0, child_desc_y0, child_desc_x1, child_desc_y1;
5270 int child_x = child->
x - off_x;
5271 int child_y = child->
y - off_y;
5273 bool html_object = (child->
object &&
5276 enum css_overflow_e overflow_x = CSS_OVERFLOW_VISIBLE;
5277 enum css_overflow_e overflow_y = CSS_OVERFLOW_VISIBLE;
5279 if (child->
style != NULL) {
5280 overflow_x = css_computed_overflow_x(child->
style);
5281 overflow_y = css_computed_overflow_y(child->
style);
5286 &child_desc_x0, &child_desc_y0,
5287 &child_desc_x1, &child_desc_y1);
5289 if (overflow_x == CSS_OVERFLOW_VISIBLE &&
5290 html_object ==
false) {
5295 if (overflow_y == CSS_OVERFLOW_VISIBLE &&
5296 html_object ==
false) {
5302 child_desc_x0 += child_x;
5303 child_desc_y0 += child_y;
5304 child_desc_x1 += child_x;
5305 child_desc_y1 += child_y;
5327 const css_unit_ctx *unit_len_ctx,
5365 for (child =
box->
next; child;
5366 child = child->
next) {
5392 CSS_OVERFLOW_HIDDEN &&
5393 css_computed_overflow_y(
box->
style) ==
5394 CSS_OVERFLOW_HIDDEN)
5425 NSLOG(layout, DEBUG,
"Doing layout to %ix%i of %s",
#define UNKNOWN_MAX_WIDTH
bool box_hscrollbar_present(const struct box *const box)
Determine if a box has a horizontal scrollbar.
bool box_vscrollbar_present(const struct box *const box)
Determine if a box has a vertical scrollbar.
void box_coords(struct box *box, int *x, int *y)
Find the absolute coordinates of a box.
void box_dump(FILE *stream, struct box *box, unsigned int depth, bool style)
Print a box tree to a file.
HTML Box tree inspection interface.
static bool box_is_first_child(struct box *b)
Check if layout box is a first child.
Browser window creation and manipulation interface.
void browser_window_set_position(struct browser_window *bw, int x, int y)
Set the position of the current browser window with respect to the parent browser window.
void browser_window_set_dimensions(struct browser_window *bw, int width, int height)
Set the dimensions of the area a browser window occupies.
void browser_window_reformat(struct browser_window *bw, bool background, int width, int height)
Reformat a browser window contents to a new width or height.
static uint32_t count(const http_directive *list, lwc_string *key)
Content handling interface.
static uint8_t ns_computed_min_height(const css_computed_style *style, css_fixed *length, css_unit *unit)
void font_plot_style_from_css(const css_unit_ctx *unit_len_ctx, const css_computed_style *css, plot_font_style_t *fstyle)
Populate a font style using data from a computed CSS style.
Internal font handling interfaces.
static bool layout__get_li_value(dom_node *li_node, dom_long *value_out)
Helper to get attribute value from a LI node.
static bool layout__get_ol_reversed(dom_node *ol_node)
Helper to get reversed attribute value from a OL node.
static void layout_minmax_table(struct box *table, const struct gui_layout_table *font_func, const html_content *content)
Calculate minimum and maximum width of a table.
static void layout_move_children(struct box *box, int x, int y)
Moves the children of a box by a specified amount.
static void layout_block_add_scrollbar(struct box *box, int which)
Manipulate a block's [RB]padding/height/width to accommodate scrollbars.
static bool layout_position_absolute(struct box *box, struct box *containing_block, int cx, int cy, html_content *content)
Recursively layout and position absolutely positioned boxes.
static bool layout_float(struct box *b, int width, html_content *content)
Layout the contents of a float or inline block.
static void layout_position_relative(const css_unit_ctx *unit_len_ctx, struct box *root, struct box *fp, int fx, int fy)
Adjust positions of relatively positioned boxes.
static bool layout_block_object(struct box *block)
Layout a block which contains an object.
bool layout_block_context(struct box *block, int viewport_height, html_content *content)
Layout a block formatting context.
static void layout_compute_offsets(const css_unit_ctx *unit_len_ctx, struct box *box, struct box *containing_block, int *top, int *right, int *bottom, int *left)
Compute box offsets for a relatively or absolutely positioned box with respect to a box.
static int line_height(const css_unit_ctx *unit_len_ctx, const css_computed_style *style)
Calculate line height from a style.
const css_border_style_func border_style_funcs[4]
Array of per-side access functions for computed style border styles.
static void layout_get_box_bbox(const css_unit_ctx *unit_len_ctx, struct box *box, int *desc_x0, int *desc_y0, int *desc_x1, int *desc_y1)
Find a box's bounding box relative to itself, i.e.
static void layout_get_object_dimensions(struct box *box, int *width, int *height, int min_width, int max_width, int min_height, int max_height)
Compute the size of replaced boxes with auto dimensions, according to content.
static bool layout__list_item_is_numerical(const struct box *b)
Find out if box's style represents a numerical list style type.
static bool layout_line(struct box *first, int *width, int *y, int cx, int cy, struct box *cont, bool indent, bool has_text_children, html_content *content, struct box **next_box)
Position a line of boxes in inline formatting context.
static void layout_compute_relative_offset(const css_unit_ctx *unit_len_ctx, struct box *box, int *x, int *y)
Compute a box's relative offset as per CSS 2.1 9.4.3.
static void layout__ordered_list_count(struct box *box)
Handle list item counting, if this is a list owner box.
static void layout__set_numerical_marker_text(const html_content *content, struct box *box)
Set up the marker text for a numerical list item.
static void place_float_below(struct box *c, int width, int cx, int y, struct box *cont)
Position a float in the first available space.
bool layout_table(struct box *table, int available_width, html_content *content)
Layout a table.
static bool box_has_percentage_max_width(struct box *b)
Helper to check if a box has percentage max width.
static bool layout_inline_container(struct box *inline_container, int width, struct box *cont, int cx, int cy, html_content *content)
Layout lines of text or inline boxes with floats.
static void add_float_to_container(struct box *cont, struct box *b)
Insert a float into a container.
static bool layout__get_list_item_count(dom_node *list_owner, dom_long *count_out)
Get the number of list items for a list owner.
static int layout_text_indent(const css_unit_ctx *unit_len_ctx, const css_computed_style *style, int width)
Calculate the text-indent length.
const css_border_color_func border_color_funcs[4]
Array of per-side access functions for computed style border colors.
static void layout_block_find_dimensions(const css_unit_ctx *unit_len_ctx, int available_width, int viewport_height, int lm, int rm, struct box *box)
Compute dimensions of box, margins, paddings, and borders for a block-level element.
static bool layout__get_ol_start(dom_node *ol_node, dom_long *start_out)
Helper to get start attribute value from a OL node.
static void layout_calculate_descendant_bboxes(const css_unit_ctx *unit_len_ctx, struct box *box)
Recursively calculate the descendant_[xy][01] values for a laid-out box tree and inform iframe browse...
const css_len_func border_width_funcs[4]
Array of per-side access functions for computed style border_widths.
static struct box * layout_minmax_line(struct box *first, int *line_min, int *line_max, bool first_line, bool *line_has_height, const struct gui_layout_table *font_func, const html_content *content)
Calculate minimum and maximum width of a line.
static void layout_minmax_block(struct box *block, const struct gui_layout_table *font_func, const html_content *content)
Calculate minimum and maximum width of a block.
bool layout_document(html_content *content, int width, int height)
Calculate positions of boxes in a document.
static void find_sides(struct box *fl, int y0, int y1, int *x0, int *x1, struct box **left, struct box **right)
Find left and right edges in a vertical range.
static struct box * layout_next_margin_block(const css_unit_ctx *unit_len_ctx, struct box *box, struct box *block, int viewport_height, int *max_pos_margin, int *max_neg_margin)
Find next block that current margin collapses to.
static bool layout_text_box_split(html_content *content, plot_font_style_t *fstyle, struct box *split_box, size_t new_length, int new_width)
Split a text box.
const css_len_func padding_funcs[4]
Array of per-side access functions for computed style paddings.
static void layout_float_find_dimensions(const css_unit_ctx *unit_len_ctx, int available_width, const css_computed_style *style, struct box *box)
Compute dimensions of box, margins, paddings, and borders for a floating element using shrink-to-fit.
static void layout_minmax_inline_container(struct box *inline_container, bool *has_height, const struct gui_layout_table *font_func, const html_content *content)
Calculate minimum and maximum width of an inline container.
static void layout_update_descendant_bbox(const css_unit_ctx *unit_len_ctx, struct box *box, struct box *child, int off_x, int off_y)
Apply changes to box descendant_[xy][01] values due to given child.
static int layout_clear(struct box *fl, enum css_clear_e clear)
Find y coordinate which clears all floats on left and/or right.
static int layout_solve_width(struct box *box, int available_width, int width, int lm, int rm, int max_width, int min_width)
Solve the width constraint as given in CSS 2.1 section 10.3.3.
static bool layout_apply_minmax_height(const css_unit_ctx *unit_len_ctx, struct box *box, struct box *container)
Manimpulate box height according to CSS min-height and max-height properties.
static bool layout__check_element_type(const dom_node *node, dom_html_element_type type)
Check a node's tag type.
static bool layout_absolute(struct box *box, struct box *containing_block, int cx, int cy, html_content *content)
Layout and position an absolutely positioned box.
const css_len_func margin_funcs[4]
Array of per-side access functions for computed style margins.
static void layout_lists(const html_content *content, struct box *box)
Layout list markers.
static bool layout__get_element_tag(const dom_node *node, dom_html_element_type *type)
Get a dom node's element tag type.
interface to HTML layout.
nsurl * content_get_url(struct content *c)
Retrieve URL associated with content.
bool content_can_reformat(hlcache_handle *h)
Get whether a content can reformat.
void content_reformat(hlcache_handle *h, bool background, int width, int height)
Reformat to new size.
int content_get_available_width(hlcache_handle *h)
Retrieve available width of content.
Protected interface to Content handling.
@ CONTENT_HTML
content is HTML
Useful interned string pointers (interface).
void textarea_set_layout(struct textarea *ta, const plot_font_style_t *fstyle, int width, int height, int top, int right, int bottom, int left)
Set the dimensions and padding of a textarea.
Single/Multi-line UTF-8 text area interface.
static struct directory * root
struct box * html_get_box_tree(hlcache_handle *h)
Retrieve box tree.
Interface to text/html content handler.
Interface to HTML content handler to save documents.
Public content interface.
struct nsurl * hlcache_handle_get_url(const struct hlcache_handle *handle)
Retrieve the URL associated with a high level cache handle.
int content_get_height(struct hlcache_handle *h)
Retrieve height of content.
int content_get_width(struct hlcache_handle *h)
Retrieve width of content.
content_type content_get_type(struct hlcache_handle *h)
Retrieve computed type of content.
Interface to platform-specific layout operation table.
Netsurf additional integer type formatting macros.
#define PRIsizet
c99 standard printf formatting for size_t type
bool layout_flex(struct box *flex, int available_width, html_content *content)
Layout a flex container.
HTML layout private interface.
#define FPCT_OF_INT_TOINT(a, b)
static bool lh__flex_main_is_horizontal(const struct box *flex)
static bool lh__box_is_object(const struct box *b)
Layout helper: Check whether box is an object.
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.
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.
uint8_t(* css_len_func)(const css_computed_style *style, css_fixed *length, css_unit *unit)
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 bool lh__box_is_flex_item(const struct box *b)
Layout helper: Check whether box takes part in inline flow.
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)
static bool lh__box_is_float_box(const struct box *b)
Layout helper: Check whether box is a float.
#define NSLOG(catname, level, logmsg, args...)
NetSurf URL handling (interface).
const char * nsurl_access(const nsurl *url)
Access a NetSurf URL object as a string.
#define NS_TRANSPARENT
Transparent colour value.
Private data for text/html content.
Interface to utility string handling.
Container for border values during table border calculations.
css_fixed width
border-width length
Container for box border details.
enum css_border_style_e style
border-style
css_color c
border-color value
int width
border-width (pixels)
int descendant_y1
bottom edge of descendants
struct box_border border[4]
Border: TOP, RIGHT, BOTTOM, LEFT.
int list_value
List item value.
int min_width
Width of box taking all line breaks (including margins etc).
int width
Width of content box (excluding padding etc.).
struct box * parent
Parent box, or NULL.
struct column * col
Array of table column data for TABLE only.
struct box * inline_end
INLINE_END box corresponding to this INLINE box, or INLINE box corresponding to this INLINE_END box.
struct box * children
First child box, or NULL.
int height
Height of content box (excluding padding etc.).
struct box * float_container
If box is a float, points to box's containing block.
struct box * prev
Previous sibling box, or NULL.
struct box * list_marker
List marker box if this is a list-item, or NULL.
int margin[4]
Margin: TOP, RIGHT, BOTTOM, LEFT.
int max_width
Width that would be taken with no line breaks.
int clear_level
Level below which subsequent floats must be cleared.
struct box * next_float
Next sibling float box.
struct box * last
Last child box, or NULL.
struct box * next
Next sibling box, or NULL.
int descendant_x0
left edge of descendants
unsigned int start_column
Start column for TABLE_CELL only.
box_type type
Type of box.
struct box * float_children
First float child box, or NULL.
int descendant_x1
right edge of descendants
struct browser_window * iframe
Iframe's browser_window, or NULL if none.
css_computed_style * style
Style for this box.
size_t length
Length of text.
struct hlcache_handle * object
Object in this box (usually an image), or NULL if none.
char * text
Text, or NULL if none.
int padding[4]
Padding: TOP, RIGHT, BOTTOM, LEFT.
int x
Coordinate of left padding edge relative to parent box, or relative to ancestor that contains this bo...
box_flags flags
Box flags.
int space
Width of space after current text (depends on font and size).
int cached_place_below_level
Level below which floats have been placed.
struct form_control * gadget
Form control data, or NULL if not a form control.
int descendant_y0
top edge of descendants
unsigned int rows
Number of rows for TABLE only.
struct dom_node * node
DOM node that generated this box or NULL.
unsigned int columns
Number of columns for TABLE / TABLE_CELL.
int y
Coordinate of top padding edge, relative as for x.
bool positioned
Whether all of column's cells are css positioned.
int width
Preferred width of column.
int max
Maximum width of content.
enum column::@131 type
Type of column.
int min
Minimum width of content.
Column record for a table.
Content which corresponds to a single URL.
int width
Width dimension, if applicable.
nserror(* width)(const struct plot_font_style *fstyle, const char *string, size_t length, int *width)
Measure the width of a string.
nserror(* split)(const struct plot_font_style *fstyle, const char *string, size_t length, int x, size_t *char_offset, int *actual_x)
Find where to split a string to make it fit a width.
Data specific to CONTENT_HTML.
colour background
Background colour to blend to, if appropriate.
bool table_calculate_column_types(const css_unit_ctx *unit_len_ctx, struct box *table)
Determine the column width types for a table.
void table_used_border_for_cell(const css_unit_ctx *unit_len_ctx, struct box *cell)
Calculate used values of border-{trbl}-{style,color,width} for table cells.
Interface to HTML table processing and layout.
#define talloc_realloc(ctx, p, type, count)
#define talloc_array(ctx, type, count)
#define talloc_memdup(t, p, size)
Option reading and saving interface.
#define nsoption_bool(OPTION)
Get the value of a boolean option.
Interface to a number of general purpose functionality.