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) {
240 return FPCT_OF_INT_TOINT(value,
width);
242 return FIXTOINT(css_unit_len2device_px(style, unit_len_ctx,
263 int border_spacing_h = 0;
264 int table_min = 0, table_max = 0;
266 float extra_frac = 0;
268 struct box *row_group, *row, *cell;
275 NSLOG(netsurf, ERROR,
276 "Could not establish table column types.");
282 for (i = 0; i != table->
columns; i++) {
283 if (
col[i].
type == COLUMN_WIDTH_FIXED)
290 if (css_computed_border_collapse(table->
style) ==
291 CSS_BORDER_COLLAPSE_SEPARATE) {
292 css_fixed h = 0, v = 0;
293 css_unit hu = CSS_UNIT_PX, vu = CSS_UNIT_PX;
295 css_computed_border_spacing(table->
style, &h, &hu, &v, &vu);
297 border_spacing_h = FIXTOINT(css_unit_len2device_px(
304 for (row_group = table->
children; row_group; row_group =row_group->
next)
319 if (
col[i].positioned)
330 for (row_group = table->
children; row_group; row_group =row_group->
next)
333 unsigned int flexible_columns = 0;
334 int min = 0,
max = 0, fixed_width = 0, extra;
344 for (j = 0; j != cell->
columns; j++) {
346 if (
col[i + j].
type == COLUMN_WIDTH_FIXED)
351 min += (cell->
columns - 1) * border_spacing_h;
355 if (flexible_columns == 0) {
358 for (j = 0; j != cell->
columns; j++) {
366 for (j = 0; j != cell->
columns; j++) {
368 COLUMN_WIDTH_FIXED) {
380 for (j = 0; j != cell->
columns; j++)
382 max += (cell->
columns - 1) * border_spacing_h;
385 if (max < cell->
max_width && flexible_columns) {
387 for (j = 0; j != cell->
columns; j++)
388 if (
col[i + j].
type != COLUMN_WIDTH_FIXED)
393 for (i = 0; i != table->
columns; i++) {
403 if (css_computed_width_px(table->
style, &
content->unit_len_ctx,
404 -1, &
width) == CSS_WIDTH_SET) {
405 if (table_min <
width)
407 if (table_max <
width)
414 &extra_fixed, &extra_frac);
417 &extra_fixed, &extra_frac);
422 if (1.0 <= extra_frac)
424 table->
min_width = (table_min + extra_fixed) / (1.0 - extra_frac);
425 table->
max_width = (table_max + extra_fixed) / (1.0 - extra_frac);
440 css_unit unit = CSS_UNIT_PX;
441 enum css_max_width_e
type;
446 type = css_computed_max_width(b->
style, &value, &unit);
447 return ((
type == CSS_MAX_WIDTH_SET) && (unit == CSS_UNIT_PCT));
467 bool *line_has_height,
484 no_wrap = (css_computed_white_space(block->
style) ==
485 CSS_WHITE_SPACE_NOWRAP ||
486 css_computed_white_space(block->
style) ==
487 CSS_WHITE_SPACE_PRE);
489 *line_has_height =
false;
492 for (b = first; b; b = b->
next) {
493 enum css_width_e wtype;
494 enum css_height_e htype;
495 enum css_box_sizing_e bs;
497 css_unit unit = CSS_UNIT_PX;
501 NSLOG(layout, DEBUG,
"%p: min %i, max %i", b,
min,
max);
531 *line_has_height =
true;
552 *line_has_height =
true;
565 font_func->
width(&fstyle,
" ", 1,
571 *line_has_height =
true;
581 no_wrap_box = (css_computed_white_space(b->
style) ==
582 CSS_WHITE_SPACE_NOWRAP ||
583 css_computed_white_space(b->
style) ==
584 CSS_WHITE_SPACE_PRE);
594 int opt_maxwidth = 0;
601 font_func->
width(&fstyle,
606 if (opt_maxwidth < opt_width)
607 opt_maxwidth =opt_width;
610 b->
width = opt_maxwidth;
623 font_func->
width(&fstyle,
" ", 1,
634 }
else if (no_wrap_box) {
647 for (j = i; j != b->
length &&
648 b->
text[j] !=
' '; j++)
658 *line_has_height =
true;
666 bs = css_computed_box_sizing(block->
style);
669 wtype = css_computed_width_px(b->
style,
671 if (wtype == CSS_WIDTH_SET) {
672 if (bs == CSS_BOX_SIZING_BORDER_BOX) {
693 htype = css_computed_height(b->
style, &
value, &unit);
694 if (htype == CSS_HEIGHT_SET) {
695 height = FIXTOINT(css_unit_len2device_px(
707 &
width, &temp_height,
713 if (bs == CSS_BOX_SIZING_BORDER_BOX) {
732 if (0 <
width + fixed)
740 if (bs == CSS_BOX_SIZING_BORDER_BOX) {
760 if (0 <
width + fixed)
766 width = FIXTOINT(css_unit_len2device_px(
769 INTTOFIX(1), CSS_UNIT_EM));
777 *line_has_height =
true;
785 min = (
min + text_indent < 0) ? 0 :
min + text_indent;
786 max = (
max + text_indent < 0) ? 0 :
max + text_indent;
792 NSLOG(layout, DEBUG,
"line_min %i, line_max %i",
min,
max);
795 assert(0 <= *line_min);
796 assert(*line_min <= *line_max);
817 int line_min = 0, line_max = 0;
819 bool first_line =
true;
820 bool line_has_height;
830 for (child = inline_container->
children; child; ) {
832 first_line, &line_has_height, font_func,
839 *has_height |= line_has_height;
845 assert(0 <= inline_container->
min_width &&
867 float extra_frac = 0;
868 enum css_width_e wtype = CSS_WIDTH_AUTO;
870 css_unit wunit = CSS_UNIT_PX;
871 enum css_height_e htype = CSS_HEIGHT_AUTO;
873 css_unit hunit = CSS_UNIT_PX;
874 enum css_box_sizing_e bs = CSS_BOX_SIZING_CONTENT_BOX;
875 bool using_min_border_box =
false;
876 bool using_max_border_box =
false;
877 bool child_has_height =
false;
889 if (block->
style != NULL) {
890 wtype = css_computed_width(block->
style, &
width, &wunit);
891 htype = css_computed_height(block->
style, &
height, &hunit);
892 bs = css_computed_box_sizing(block->
style);
899 wtype != CSS_WIDTH_SET) {
906 wtype != CSS_WIDTH_SET) {
918 block->
style && wtype == CSS_WIDTH_AUTO) {
919 css_fixed size = INTTOFIX(10);
920 css_unit unit = CSS_UNIT_EM;
922 min =
max = FIXTOINT(css_unit_len2device_px(block->
style,
923 &
content->unit_len_ctx, size, unit));
930 block->
style && wtype == CSS_WIDTH_AUTO) {
931 css_fixed size = INTTOFIX(1);
932 css_unit unit = CSS_UNIT_EM;
936 min =
max = FIXTOINT(css_unit_len2device_px(block->
style,
937 &
content->unit_len_ctx, size, unit));
959 for (child = block->
children; child; child = child->
next) {
960 switch (child->
type) {
966 child_has_height =
true;
973 &child_has_height, font_func,
975 if (child_has_height &&
985 child_has_height =
true;
994 (css_computed_position(child->
style) ==
995 CSS_POSITION_ABSOLUTE ||
996 css_computed_position(child->
style) ==
997 CSS_POSITION_FIXED)) {
1005 if (block->
style != NULL &&
1006 css_computed_flex_wrap(block->
style) ==
1007 CSS_FLEX_WRAP_NOWRAP) {
1022 if (child_has_height)
1034 bool border_box = bs == CSS_BOX_SIZING_BORDER_BOX;
1035 enum css_max_width_e max_type;
1036 enum css_min_width_e min_type;
1037 css_unit unit = CSS_UNIT_PX;
1038 css_fixed value = 0;
1041 if (css_computed_width_px(block->
style, &
content->unit_len_ctx,
1042 -1, &
width) == CSS_WIDTH_SET) {
1044 using_max_border_box = border_box;
1045 using_min_border_box = border_box;
1048 min_type = css_computed_min_width(block->
style, &value, &unit);
1049 if (min_type == CSS_MIN_WIDTH_SET && unit != CSS_UNIT_PCT) {
1050 int val = FIXTOINT(css_unit_len2device_px(block->
style,
1051 &
content->unit_len_ctx, value, unit));
1055 using_min_border_box = border_box;
1059 max_type = css_computed_max_width(block->
style, &value, &unit);
1060 if (max_type == CSS_MAX_WIDTH_SET && unit != CSS_UNIT_PCT) {
1061 int val = FIXTOINT(css_unit_len2device_px(block->
style,
1062 &
content->unit_len_ctx, value, unit));
1064 if (val >= 0 &&
max > val) {
1066 using_max_border_box = border_box;
1071 if (htype == CSS_HEIGHT_SET && hunit != CSS_UNIT_PCT &&
1081 false,
true,
true, &extra_fixed, &extra_frac);
1083 false,
true,
true, &extra_fixed, &extra_frac);
1085 if (using_max_border_box) {
1090 if (using_min_border_box) {
1100 true,
false,
false, &extra_fixed, &extra_frac);
1102 true,
false,
false, &extra_fixed, &extra_frac);
1104 if (extra_fixed < 0)
1108 if (1.0 <= extra_frac)
1110 if (block->
style != NULL &&
1111 (css_computed_float(block->
style) == CSS_FLOAT_LEFT ||
1112 css_computed_float(block->
style) == CSS_FLOAT_RIGHT)) {
1118 block->
min_width = (
min + extra_fixed) / (1.0 - extra_frac);
1119 block->
max_width = (
max + extra_fixed) / (1.0 - extra_frac);
1142 int viewport_height,
1143 int *max_pos_margin,
1144 int *max_neg_margin)
1146 assert(block != NULL);
1148 while (
box != NULL) {
1151 (css_computed_position(
box->
style) !=
1152 CSS_POSITION_ABSOLUTE &&
1153 css_computed_position(
box->
style) !=
1154 CSS_POSITION_FIXED))) {
1161 viewport_height,
box,
1163 NULL, NULL, NULL, NULL,
1170 else if (*max_neg_margin < -box->
margin[
TOP])
1180 css_computed_overflow_y(
box->
style) !=
1181 CSS_OVERFLOW_VISIBLE) ||
1193 css_computed_overflow_y(
box->
style) ==
1194 CSS_OVERFLOW_VISIBLE) {
1203 if (*max_pos_margin <
1207 else if (*max_neg_margin <
1236 viewport_height,
box,
1238 NULL, NULL, NULL, NULL,
1260 if ((clear == CSS_CLEAR_LEFT || clear == CSS_CLEAR_BOTH) &&
1264 if ((clear == CSS_CLEAR_RIGHT || clear == CSS_CLEAR_BOTH) &&
1291 int fy0, fy1, fx0, fx1;
1293 NSLOG(layout, DEBUG,
"y0 %i, y1 %i, x0 %i, x1 %i", y0, y1, *x0, *x1);
1305 if (y0 < fy1 && fy0 <= y1) {
1322 NSLOG(layout, DEBUG,
"x0 %i, x1 %i, left %p, right %p", *x0, *x1,
1347 int available_width,
1354 bool auto_width =
false;
1369 if (margin_left ==
AUTO) {
1372 if (margin_right ==
AUTO) {
1376 width = available_width -
1415 case CSS_TEXT_ALIGN_LIBCSS_RIGHT:
1419 case CSS_TEXT_ALIGN_LIBCSS_CENTER:
1422 case CSS_TEXT_ALIGN_LIBCSS_LEFT:
1435 (available_width - lm - rm -
1485 int available_width,
1486 int viewport_height,
1492 int height, max_height, min_height;
1500 &max_height, &min_height, margin, padding,
border);
1506 min_width, max_width, min_height, max_height);
1510 max_width, min_width);
1528 enum css_overflow_e overflow_x, overflow_y;
1535 overflow_x = css_computed_overflow_x(
box->
style);
1536 overflow_y = css_computed_overflow_y(
box->
style);
1539 (overflow_x == CSS_OVERFLOW_SCROLL ||
1540 overflow_x == CSS_OVERFLOW_AUTO ||
1545 (overflow_x == CSS_OVERFLOW_SCROLL ||
1550 }
else if (which ==
RIGHT &&
1551 (overflow_y == CSS_OVERFLOW_SCROLL ||
1552 overflow_y == CSS_OVERFLOW_AUTO ||
1556 enum css_height_e htype;
1558 css_unit hunit = CSS_UNIT_PX;
1562 htype == CSS_HEIGHT_SET &&
1563 (overflow_y == CSS_OVERFLOW_SCROLL ||
1593 int available_width,
1598 unsigned int *row_span;
1600 int table_width, min_width = 0, max_width = 0;
1601 int required_width = 0;
1602 int x, remainder = 0,
count = 0;
1603 int table_height = 0;
1608 int relative_sum = 0;
1609 int border_spacing_h = 0, border_spacing_v = 0;
1611 int positioned_columns = 0;
1612 struct box *containing_block = NULL;
1615 struct box *row_group;
1616 struct box **row_span_cell;
1618 const css_computed_style *style = table->
style;
1619 enum css_height_e htype;
1620 css_fixed value = 0;
1621 css_unit unit = CSS_UNIT_PX;
1629 col = malloc(
columns *
sizeof col[0]);
1630 excess_y = malloc(
columns *
sizeof excess_y[0]);
1631 row_span = malloc(
columns *
sizeof row_span[0]);
1632 row_span_cell = malloc(
columns *
sizeof row_span_cell[0]);
1633 xs = malloc((
columns + 1) *
sizeof xs[0]);
1634 if (!col || !xs || !row_span || !excess_y || !row_span_cell) {
1638 free(row_span_cell);
1643 memcpy(col, table->
col,
sizeof(col[0]) *
columns);
1649 for (row_group = table->
children; row_group;
1650 row_group = row_group->
next) {
1651 for (row = row_group->
children; row; row = row->
next) {
1653 enum css_overflow_e overflow_x;
1654 enum css_overflow_e overflow_y;
1660 available_width, -1, c,
1661 c->
style, 0, 0, 0, 0, 0, 0,
1664 overflow_x = css_computed_overflow_x(c->
style);
1665 overflow_y = css_computed_overflow_y(c->
style);
1667 if (overflow_x == CSS_OVERFLOW_SCROLL ||
1669 CSS_OVERFLOW_AUTO) {
1672 if (overflow_y == CSS_OVERFLOW_SCROLL ||
1674 CSS_OVERFLOW_AUTO) {
1682 if (css_computed_border_collapse(style) ==
1683 CSS_BORDER_COLLAPSE_SEPARATE) {
1684 css_fixed h = 0, v = 0;
1685 css_unit hu = CSS_UNIT_PX, vu = CSS_UNIT_PX;
1687 css_computed_border_spacing(style, &h, &hu, &v, &vu);
1689 border_spacing_h = FIXTOINT(css_unit_len2device_px(
1690 style, &
content->unit_len_ctx, h, hu));
1691 border_spacing_v = FIXTOINT(css_unit_len2device_px(
1692 style, &
content->unit_len_ctx, v, vu));
1696 if (css_computed_width_px(style, &
content->unit_len_ctx,
1697 available_width, &table_width) == CSS_WIDTH_SET) {
1701 table_width = table_width < 0 ? 0 : table_width;
1703 auto_width = table_width;
1706 auto_width = available_width -
1718 htype = css_computed_height(style, &value, &unit);
1719 if (htype == CSS_HEIGHT_SET) {
1720 if (unit == CSS_UNIT_PCT) {
1723 if (css_computed_position(table->
style) ==
1724 CSS_POSITION_ABSOLUTE) {
1729 css_computed_position(table->
style) !=
1730 CSS_POSITION_ABSOLUTE &&
1731 (css_computed_float(table->
style) ==
1733 css_computed_float(table->
style) ==
1743 containing_block = table->
parent;
1751 if (containing_block) {
1752 css_fixed ignored = 0;
1754 htype = css_computed_height(
1755 containing_block->
style,
1759 if (containing_block &&
1761 (css_computed_position(table->
style) ==
1762 CSS_POSITION_ABSOLUTE ||
1763 htype == CSS_HEIGHT_SET)) {
1767 min_height = FPCT_OF_INT_TOINT(value,
1768 containing_block->
height);
1773 min_height = FIXTOINT(css_unit_len2device_px(
1774 style, &
content->unit_len_ctx,
1780 for (i = 0; i !=
columns; i++) {
1782 NSLOG(layout, DEBUG,
1783 "table %p, column %u: type %s, width %i, min %i, max %i",
1799 positioned_columns++;
1806 required_width += col[i].
width;
1812 required_width += col[i].
min;
1814 NSLOG(layout, DEBUG,
"required_width %i", required_width);
1816 required_width += (
columns + 1 - positioned_columns) *
1819 NSLOG(layout, DEBUG,
1820 "width %i, min %i, max %i, auto %i, required %i", table_width,
1823 if (auto_width < required_width) {
1826 for (i = 0; i !=
columns; i++) {
1830 col[i].
max = auto_width * col[i].
width / 100;
1831 if (col[i].
max < col[i].
min)
1834 min_width += col[i].
min;
1835 max_width += col[i].
max;
1839 for (i = 0; i !=
columns; i++) {
1849 min_width += col[i].
min;
1850 max_width += col[i].
max;
1855 spare_width = auto_width;
1856 for (i = 0; i !=
columns; i++) {
1858 relative_sum += col[i].
width;
1860 spare_width -= col[i].
width;
1862 spare_width -= col[i].
min;
1864 spare_width -= (
columns + 1) * border_spacing_h;
1865 if (relative_sum != 0) {
1866 if (spare_width < 0)
1868 for (i = 0; i !=
columns; i++) {
1870 col[i].
min = ceil(col[i].
max =
1872 * (
float) col[i].
width
1874 min_width += col[i].
min;
1875 max_width += col[i].
max;
1879 min_width += (
columns + 1) * border_spacing_h;
1880 max_width += (
columns + 1) * border_spacing_h;
1882 if (auto_width <= min_width) {
1884 for (i = 0; i <
columns; i++) {
1887 table_width = min_width;
1888 }
else if (max_width <= auto_width) {
1890 if (table_width ==
AUTO) {
1892 for (i = 0; i <
columns; i++) {
1895 table_width = max_width;
1899 unsigned int flexible_columns = 0;
1900 for (i = 0; i !=
columns; i++)
1903 if (flexible_columns == 0) {
1904 int extra = (table_width - max_width) /
columns;
1905 remainder = (table_width - max_width) -
1907 for (i = 0; i !=
columns; i++) {
1917 int extra = (table_width - max_width) /
1919 remainder = (table_width - max_width) -
1920 (extra * flexible_columns);
1921 for (i = 0; i !=
columns; i++)
1928 count += flexible_columns;
1935 float scale = (float) (auto_width - min_width) /
1936 (float) (max_width - min_width);
1938 for (i = 0; i <
columns; i++) {
1939 col[i].
width = col[i].
min + (int) (0.5 +
1940 (col[i].
max - col[i].
min) * scale);
1942 table_width = auto_width;
1945 xs[0] = x = border_spacing_h;
1946 for (i = 0; i !=
columns; i++) {
1948 x += col[i].
width + border_spacing_h;
1952 row_span_cell[i] = 0;
1956 table_height = border_spacing_v;
1957 for (row_group = table->
children; row_group;
1958 row_group = row_group->
next) {
1959 int row_group_height = 0;
1960 for (row = row_group->
children; row; row = row->
next) {
1963 htype = css_computed_height(row->
style, &value, &unit);
1964 if (htype == CSS_HEIGHT_SET && unit != CSS_UNIT_PCT) {
1965 row_height = FIXTOINT(css_unit_len2device_px(
1987 free(row_span_cell);
1997 htype = css_computed_height(c->
style,
2000 if (htype == CSS_HEIGHT_SET &&
2001 unit != CSS_UNIT_PCT) {
2005 int h = FIXTOINT(css_unit_len2device_px(
2014 if (c->
height < row_height)
2019 for (i = 0; i != c->
columns; i++) {
2036 for (i = 0; i !=
columns; i++)
2037 if (row_span[i] != 0)
2040 row_span_cell[i] = 0;
2041 if (row->
next || row_group->
next) {
2044 for (i = 0; i !=
columns; i++)
2045 if (row_span[i] == 0 && row_height <
2047 row_height = excess_y[i];
2050 for (i = 0; i !=
columns; i++)
2051 if (row_height < excess_y[i])
2052 row_height = excess_y[i];
2054 for (i = 0; i !=
columns; i++) {
2055 if (row_height < excess_y[i])
2056 excess_y[i] -= row_height;
2059 if (row_span_cell[i] != 0)
2066 row->
y = row_group_height;
2067 row->
width = table_width;
2068 row->
height = row_height;
2069 row_group_height += row_height + border_spacing_v;
2072 row_group->
y = table_height;
2073 row_group->
width = table_width;
2074 row_group->
height = row_group_height;
2075 table_height += row_group_height;
2079 table_height =
max(table_height, min_height);
2083 for (row_group = table->
children; row_group;
2084 row_group = row_group->
next) {
2085 for (row = row_group->
children; row; row = row->
next) {
2087 enum css_vertical_align_e vertical_align;
2096 vertical_align = css_computed_vertical_align(
2097 c->
style, &value, &unit);
2099 switch (vertical_align) {
2100 case CSS_VERTICAL_ALIGN_SUB:
2101 case CSS_VERTICAL_ALIGN_SUPER:
2102 case CSS_VERTICAL_ALIGN_TEXT_TOP:
2103 case CSS_VERTICAL_ALIGN_TEXT_BOTTOM:
2104 case CSS_VERTICAL_ALIGN_SET:
2105 case CSS_VERTICAL_ALIGN_BASELINE:
2108 case CSS_VERTICAL_ALIGN_TOP:
2110 case CSS_VERTICAL_ALIGN_MIDDLE:
2116 case CSS_VERTICAL_ALIGN_BOTTOM:
2122 case CSS_VERTICAL_ALIGN_INHERIT:
2139 free(row_span_cell);
2142 table->
width = table_width;
2143 table->
height = table_height;
2159 const css_unit_ctx *unit_len_ctx,
2161 struct box *container)
2164 struct box *containing_block = NULL;
2165 bool updated =
false;
2169 CSS_POSITION_ABSOLUTE) {
2172 containing_block = container;
2174 (css_computed_float(
box->
style) == CSS_FLOAT_LEFT ||
2175 css_computed_float(
box->
style) == CSS_FLOAT_RIGHT)) {
2190 enum css_height_e htype = CSS_HEIGHT_AUTO;
2191 css_fixed value = 0;
2192 css_unit unit = CSS_UNIT_PX;
2194 if (containing_block) {
2195 htype = css_computed_height(containing_block->
style,
2200 if (css_computed_max_height(
box->
style, &value, &unit) ==
2201 CSS_MAX_HEIGHT_SET) {
2202 if (unit == CSS_UNIT_PCT) {
2203 if (containing_block &&
2205 (css_computed_position(
box->
style) ==
2206 CSS_POSITION_ABSOLUTE ||
2207 htype == CSS_HEIGHT_SET)) {
2212 h = FPCT_OF_INT_TOINT(value,
2213 containing_block->
height);
2220 h = FIXTOINT(css_unit_len2device_px(
2232 CSS_MIN_HEIGHT_SET) {
2233 if (unit == CSS_UNIT_PCT) {
2234 if (containing_block &&
2236 (css_computed_position(
box->
style) ==
2237 CSS_POSITION_ABSOLUTE ||
2238 htype == CSS_HEIGHT_SET)) {
2243 h = FPCT_OF_INT_TOINT(value,
2244 containing_block->
height);
2251 h = FIXTOINT(css_unit_len2device_px(
2282 NSLOG(layout, DEBUG,
"block %p, object %p, width %i", block,
2308 int b_bottom = b->
y + b->
height;
2351 struct box *split_box,
2355 int space_width = split_box->
space;
2358 bool space = (split_box->
text[new_length] ==
' ');
2359 int used_length = new_length + (space ? 1 : 0);
2361 if ((space && space_width == 0) || space_width ==
UNKNOWN_WIDTH) {
2365 font_func->
width(fstyle,
" ", 1, &space_width);
2369 split_box->
space = space_width;
2380 c2->
text += used_length;
2383 c2->
width -= new_width + space_width;
2384 c2->
flags &= ~MEASURED;
2388 split_box->
width = new_width;
2390 split_box->
length = new_length;
2391 split_box->
space = space_width;
2395 split_box->
next = c2;
2396 c2->
prev = split_box;
2402 NSLOG(layout, DEBUG,
2403 "split_box %p len: %" PRIsizet " \"%.*s\"",
2408 NSLOG(layout, DEBUG,
2409 " new_box %p len: %" PRIsizet " \"%.*s\"",
2432 const css_unit_ctx *unit_len_ctx,
2433 int available_width,
2434 const css_computed_style *style,
2437 int width,
height, max_width, min_width, max_height, min_height;
2441 enum css_overflow_e overflow_x = css_computed_overflow_x(
style);
2442 enum css_overflow_e overflow_y = css_computed_overflow_y(
style);
2443 int scrollbar_width_x =
2444 (overflow_x == CSS_OVERFLOW_SCROLL ||
2445 overflow_x == CSS_OVERFLOW_AUTO) ?
2447 int scrollbar_width_y =
2448 (overflow_y == CSS_OVERFLOW_SCROLL ||
2449 overflow_y == CSS_OVERFLOW_AUTO) ?
2454 &max_height, &min_height, margin, padding,
border);
2462 padding[
RIGHT] += scrollbar_width_y;
2463 padding[
BOTTOM] += scrollbar_width_x;
2471 min_width, max_width, min_height, max_height);
2477 css_unit unit = CSS_UNIT_EM;
2487 size = INTTOFIX(10);
2488 width = FIXTOINT(css_unit_len2device_px(
2494 size = FLTTOFIX(1.5);
2495 height = FIXTOINT(css_unit_len2device_px(
2502 size = INTTOFIX(10);
2503 width = FIXTOINT(css_unit_len2device_px(
2509 height = FIXTOINT(css_unit_len2device_px(
2520 if (
width == available_width) {
2533 true,
true,
true, &fixed, &frac);
2535 true,
true,
true, &fixed, &frac);
2542 if (max_width >= 0 &&
width > max_width)
width = max_width;
2543 if (min_width > 0 &&
width < min_width)
width = min_width;
2546 if (max_width >= 0 &&
width > max_width)
width = max_width;
2547 if (min_width > 0 &&
width < min_width)
width = min_width;
2548 width -= scrollbar_width_y;
2619 NSLOG(layout, DEBUG,
2620 "c %p, width %i, cx %i, y %i, cont %p", c,
2629 if (left != 0 && right != 0) {
2630 yy = (left->
y + left->
height <
2634 }
else if (left == 0 && right != 0) {
2635 yy = right->
y + right->
height;
2636 }
else if (left != 0 && right == 0) {
2639 }
while ((left != 0 || right != 0) && (c->
width > x1 - x0));
2655 const css_unit_ctx *unit_len_ctx,
2656 const css_computed_style *
style)
2658 enum css_line_height_e lhtype;
2659 css_fixed lhvalue = 0;
2660 css_unit lhunit = CSS_UNIT_PX;
2665 lhtype = css_computed_line_height(
style, &lhvalue, &lhunit);
2666 if (lhtype == CSS_LINE_HEIGHT_NORMAL) {
2668 lhvalue = FLTTOFIX(1.3);
2669 lhtype = CSS_LINE_HEIGHT_NUMBER;
2672 if (lhtype == CSS_LINE_HEIGHT_NUMBER ||
2673 lhunit == CSS_UNIT_PCT) {
2675 lhvalue, CSS_UNIT_EM);
2677 if (lhtype != CSS_LINE_HEIGHT_NUMBER)
2680 assert(lhunit != CSS_UNIT_PCT);
2714 bool has_text_children,
2716 struct box **next_box)
2721 int x, h, x_previous;
2726 struct box *split_box = 0;
2728 struct box *br_box = 0;
2729 bool move_y =
false;
2730 bool place_below =
false;
2731 int space_before = 0, space_after = 0;
2732 unsigned int inline_count = 0;
2737 NSLOG(layout, DEBUG,
2738 "first %p, first->text '%.*s', width %i, y %i, cx %i, cy %i",
2770 used_height =
height = 0;
2776 NSLOG(layout, DEBUG,
"x0 %i, x1 %i, x1 - x0 %i", x0, x1, x1 - x0);
2779 for (x = 0, b = first; x <= x1 - x0 && b != 0; b = b->
next) {
2780 int min_width, max_width, min_height, max_height;
2784 NSLOG(layout, DEBUG,
"pass 1: b %p, x %i", b, x);
2792 (css_computed_position(b->
style) ==
2793 CSS_POSITION_ABSOLUTE ||
2794 css_computed_position(b->
style) ==
2795 CSS_POSITION_FIXED))
2798 assert(b->
style != NULL);
2827 for (i = 0; i != 4; i++)
2846 font_func->
width(&fstyle,
" ", 1, &b->
space);
2849 space_after = b->
space;
2878 int opt_maxwidth = 0;
2885 font_func->
width(&fstyle,
2890 if (opt_maxwidth < opt_width)
2891 opt_maxwidth =opt_width;
2893 b->
width = opt_maxwidth;
2907 if (b->
text && (x + b->
width < x1 - x0) &&
2917 font_func->
width(&fstyle,
" ", 1, &b->
space);
2920 space_after = b->
space;
2932 &max_width, &min_width,
2933 &max_height, &min_height,
2938 min_width, max_width,
2939 min_height, max_height);
2952 b->
width = FIXTOINT(css_unit_len2device_px(
2954 &
content->unit_len_ctx, INTTOFIX(1),
2957 b->
height = FIXTOINT(css_unit_len2device_px(
2959 &
content->unit_len_ctx, INTTOFIX(1),
2967 css_fixed
value = 0;
2968 css_unit unit = CSS_UNIT_PX;
2969 enum css_height_e htype = css_computed_height(b->
style,
2974 if (htype == CSS_HEIGHT_AUTO)
2999 space_after = space_before = 0;
3003 NSLOG(layout, DEBUG,
"x0 %i, x1 %i, x1 - x0 %i", x0, x1, x1 - x0);
3005 for (x = x_previous = 0, b = first; x <= x1 - x0 && b; b = b->
next) {
3007 NSLOG(layout, DEBUG,
"pass 2: b %p, x %i", b, x);
3010 (css_computed_position(b->
style) ==
3011 CSS_POSITION_ABSOLUTE ||
3012 css_computed_position(b->
style) ==
3013 CSS_POSITION_FIXED)) {
3014 b->
x = x + space_after;
3043 space_before = space_after;
3053 font_func->
width(&fstyle,
" ", 1,
3056 space_after = b->
space;
3074 NSLOG(layout, DEBUG,
"float %p", b);
3084 NSLOG(layout, DEBUG,
3103 if (b->
width > (x1 - x0) - x)
3105 if (d->
style && (css_computed_clear(d->
style) ==
3107 (css_computed_clear(d->
style) ==
3108 CSS_CLEAR_LEFT && left == 0) ||
3109 (css_computed_clear(d->
style) ==
3112 (css_computed_clear(d->
style) ==
3114 left == 0 && right == 0)) &&
3116 (left == 0 && right == 0 && x == 0)) &&
3132 b->
x = cx + x1 - b->
width;
3146 fy = (fy > fcy) ? fy : fcy;
3147 fy = (fy == cy) ? fy +
height : fy;
3152 (css_computed_clear(d->
style) ==
3153 CSS_CLEAR_LEFT && left != 0) ||
3154 (css_computed_clear(d->
style) ==
3157 (css_computed_clear(d->
style) ==
3159 (left != 0 || right != 0)))) {
3168 css_computed_clear(d->
style));
3185 if (x1 - x0 < x && split_box) {
3189 bool no_wrap = css_computed_white_space(
3190 split_box->
style) == CSS_WHITE_SPACE_NOWRAP ||
3191 css_computed_white_space(
3192 split_box->
style) == CSS_WHITE_SPACE_PRE;
3205 split_box->
style, &fstyle);
3207 font_func->
split(&fstyle,
3210 x1 - x0 - x - space_before,
3218 w = split_box->
width;
3221 NSLOG(layout, DEBUG,
3222 "splitting: split_box %p \"%.*s\", spilt %"PRIsizet
3223 ", w %i, left %p, right %p, inline_count %u",
3233 if ((split == 0 || x1 - x0 <= x + space_before + w) &&
3234 !left && !right && inline_count == 1) {
3237 if (split == 0 || split == split_box->
length) {
3240 b = split_box->
next;
3244 split_box, split, w))
3246 b = split_box->
next;
3248 x += space_before + w;
3250 NSLOG(layout, DEBUG,
"forcing");
3252 }
else if ((split == 0 || x1 - x0 <= x + space_before + w) &&
3253 inline_count == 1) {
3256 assert(left || right);
3260 NSLOG(layout, DEBUG,
3261 "cy %i, left->y %i, left->height %i",
3266 used_height = left->
y + left->
height - cy + 1;
3268 NSLOG(layout, DEBUG,
"used_height %i",
3272 if (right && used_height <
3273 right->
y + right->
height - cy + 1)
3274 used_height = right->
y + right->
height - cy + 1;
3276 if (used_height < 0)
3281 NSLOG(layout, DEBUG,
"moving below float");
3283 }
else if (split == 0 || x1 - x0 <= x + space_before + w) {
3288 NSLOG(layout, DEBUG,
"leaving for next line");
3294 NSLOG(layout, DEBUG,
3299 if (split != split_box->
length) {
3301 split_box, split, w))
3303 b = split_box->
next;
3305 x += space_before + w;
3307 NSLOG(layout, DEBUG,
"fitting words");
3315 case CSS_TEXT_ALIGN_RIGHT:
3316 case CSS_TEXT_ALIGN_LIBCSS_RIGHT:
3319 case CSS_TEXT_ALIGN_CENTER:
3320 case CSS_TEXT_ALIGN_LIBCSS_CENTER:
3321 x0 = (x0 + (x1 - x)) / 2;
3323 case CSS_TEXT_ALIGN_LEFT:
3324 case CSS_TEXT_ALIGN_LIBCSS_LEFT:
3325 case CSS_TEXT_ALIGN_JUSTIFY:
3328 case CSS_TEXT_ALIGN_DEFAULT:
3331 case CSS_DIRECTION_LTR:
3334 case CSS_DIRECTION_RTL:
3341 for (d = first; d != b; d = d->
next) {
3342 d->
flags &= ~NEW_LINE;
3345 (css_computed_position(d->
style) ==
3346 CSS_POSITION_ABSOLUTE ||
3347 css_computed_position(d->
style) ==
3348 CSS_POSITION_FIXED)) {
3378 if (used_height < h)
3385 assert(b != first || (move_y && 0 < used_height && (left || right)));
3389 for (d = first; d != b; d = d->
next) {
3394 css_fixed
value = 0;
3395 css_unit unit = CSS_UNIT_PX;
3396 switch (css_computed_vertical_align(d->
style, &
value,
3398 case CSS_VERTICAL_ALIGN_SUPER:
3399 case CSS_VERTICAL_ALIGN_TOP:
3400 case CSS_VERTICAL_ALIGN_TEXT_TOP:
3403 case CSS_VERTICAL_ALIGN_SUB:
3404 case CSS_VERTICAL_ALIGN_BOTTOM:
3405 case CSS_VERTICAL_ALIGN_TEXT_BOTTOM:
3406 d->
y += used_height - d->
height;
3409 case CSS_VERTICAL_ALIGN_BASELINE:
3410 d->
y += 0.75 * (used_height - d->
height);
3417 if (br_box && css_computed_clear(br_box->
style) != CSS_CLEAR_NONE) {
3419 css_computed_clear(br_box->
style));
3420 if (used_height < clear_y - cy)
3421 used_height = clear_y - cy;
3446 bool first_line =
true;
3447 bool has_text_children;
3450 int curwidth,maxwidth =
width;
3454 NSLOG(layout, DEBUG,
3455 "inline_container %p, width %i, cont %p, cx %i, cy %i",
3463 has_text_children =
false;
3465 bool is_pre =
false;
3468 enum css_white_space_e whitespace;
3470 whitespace = css_computed_white_space(c->
style);
3472 is_pre = (whitespace == CSS_WHITE_SPACE_PRE ||
3473 whitespace == CSS_WHITE_SPACE_PRE_LINE ||
3474 whitespace == CSS_WHITE_SPACE_PRE_WRAP);
3480 has_text_children =
true;
3487 for (c = inline_container->
children; c; ) {
3489 NSLOG(layout, DEBUG,
"c %p", c);
3491 curwidth = inline_container->
width;
3492 if (!
layout_line(c, &curwidth, &
y, cx, cy +
y, cont, first_line,
3495 maxwidth =
max(maxwidth,curwidth);
3500 inline_container->
width = maxwidth;
3510 int viewport_height,
3515 int max_pos_margin = 0;
3516 int max_neg_margin = 0;
3519 struct box *margin_collapse = NULL;
3520 bool in_margin =
false;
3521 css_fixed gadget_size;
3522 css_unit gadget_unit;
3538 int temp_width = block->
width;
3542 &block->
height, INT_MIN, INT_MAX,
3554 gadget_unit = CSS_UNIT_EM;
3555 gadget_size = INTTOFIX(1);
3557 block->
height = FIXTOINT(css_unit_len2device_px(
3560 gadget_size, gadget_unit));
3594 enum css_overflow_e overflow_x = CSS_OVERFLOW_VISIBLE;
3595 enum css_overflow_e overflow_y = CSS_OVERFLOW_VISIBLE;
3611 (css_computed_position(
box->
style) ==
3612 CSS_POSITION_ABSOLUTE ||
3613 css_computed_position(
box->
style) ==
3614 CSS_POSITION_FIXED)) {
3619 goto advance_to_next_box;
3624 if (margin_collapse == NULL) {
3628 &max_pos_margin, &max_neg_margin);
3642 overflow_x = css_computed_overflow_x(
box->
style);
3643 overflow_y = css_computed_overflow_y(
box->
style);
3655 (overflow_x != CSS_OVERFLOW_VISIBLE ||
3656 overflow_y != CSS_OVERFLOW_VISIBLE)) {
3661 struct box *left, *right;
3662 top = cy + max_pos_margin - max_neg_margin;
3663 top = (top >
y) ? top :
y;
3669 &x0, &x1, &left, &right);
3680 viewport_height, lm, rm,
box);
3687 enum css_width_e wtype;
3688 css_fixed
width = 0;
3689 css_unit unit = CSS_UNIT_PX;
3694 if (wtype == CSS_WIDTH_AUTO) {
3698 struct box *left, *right;
3699 top = cy + max_pos_margin -
3701 top = (top >
y) ? top :
y;
3742 margin_collapse ==
box) &&
3743 in_margin ==
true) {
3745 cy += max_pos_margin - max_neg_margin;
3746 box->
y += max_pos_margin - max_neg_margin;
3750 max_pos_margin = max_neg_margin = 0;
3755 (
y > 0) && (cy <
y)) {
3765 (overflow_x != CSS_OVERFLOW_VISIBLE ||
3766 overflow_y != CSS_OVERFLOW_VISIBLE))) {
3793 goto advance_to_next_box;
3796 NSLOG(layout, DEBUG,
"box %p, cx %i, cy %i, width %i",
3813 struct box *left, *right;
3816 enum css_width_e wtype;
3817 css_fixed
width = 0;
3818 css_unit unit = CSS_UNIT_PX;
3820 wtype = css_computed_width(
box->
style,
3827 &x0, &x1, &left, &right);
3828 if (wtype == CSS_WIDTH_AUTO)
3832 if (!left && !right)
3838 else if (left->
y + left->
height <
3855 if (
box == margin_collapse) {
3858 margin_collapse = NULL;
3882 advance_to_next_box:
3888 if (
box == margin_collapse) {
3891 margin_collapse = NULL;
3908 margin_collapse = NULL;
3910 max_pos_margin = max_neg_margin = 0;
3926 css_computed_position(
box->
style) !=
3927 CSS_POSITION_ABSOLUTE &&
3951 if (
box == margin_collapse) {
3954 margin_collapse = NULL;
3967 cy += max_pos_margin - max_neg_margin;
3983 if (block->
style && css_computed_position(block->
style) !=
3984 CSS_POSITION_ABSOLUTE) {
3999 block->
style, &fstyle);
4002 &fstyle, ta_width, ta_height,
4019 const dom_node *
node,
4020 dom_html_element_type *
type)
4022 dom_html_element_type element_type;
4023 dom_node_type node_type;
4026 exc = dom_node_get_node_type(
node, &node_type);
4027 if (exc != DOM_NO_ERR ||
4028 node_type != DOM_ELEMENT_NODE) {
4032 exc = dom_html_element_get_tag_type(
node, &element_type);
4033 if (exc != DOM_NO_ERR) {
4037 *
type = element_type;
4051 const dom_node *
node,
4052 dom_html_element_type
type)
4054 dom_html_element_type element_type;
4060 return element_type ==
type;
4087 exc = dom_element_has_attribute(li_node,
4088 corestring_dom_value,
4090 if (exc != DOM_NO_ERR || has_value ==
false) {
4094 exc = dom_html_li_element_get_value(
4095 (dom_html_li_element *)li_node,
4097 if (exc != DOM_NO_ERR) {
4123 exc = dom_element_has_attribute(ol_node,
4124 corestring_dom_start,
4126 if (exc != DOM_NO_ERR || has_start ==
false) {
4130 exc = dom_html_olist_element_get_start(
4131 (dom_html_olist_element *)ol_node,
4133 if (exc != DOM_NO_ERR) {
4154 exc = dom_element_has_attribute(ol_node,
4155 corestring_dom_reversed,
4157 if (exc != DOM_NO_ERR) {
4161 return has_reversed;
4174 dom_node *list_owner, dom_long *count_out)
4176 dom_html_element_type tag_type;
4181 if (list_owner == NULL) {
4189 if (tag_type != DOM_HTML_ELEMENT_TYPE_OL &&
4190 tag_type != DOM_HTML_ELEMENT_TYPE_UL) {
4194 exc = dom_node_get_first_child(list_owner, &child);
4195 if (exc != DOM_NO_ERR) {
4200 while (child != NULL) {
4201 dom_node *temp_node;
4204 DOM_HTML_ELEMENT_TYPE_LI)) {
4205 struct box *child_box;
4206 if (dom_node_get_user_data(child,
4207 corestring_dom___ns_key_box_node_data,
4208 &child_box) != DOM_NO_ERR) {
4209 dom_node_unref(child);
4213 if (child_box != NULL &&
4219 exc = dom_node_get_next_sibling(child, &temp_node);
4220 dom_node_unref(child);
4221 if (exc != DOM_NO_ERR) {
4242 dom_html_element_type tag_type;
4256 if (tag_type != DOM_HTML_ELEMENT_TYPE_OL &&
4257 tag_type != DOM_HTML_ELEMENT_TYPE_UL) {
4262 if (tag_type == DOM_HTML_ELEMENT_TYPE_OL) {
4266 if (have_reversed) {
4270 if (!have_start && have_reversed) {
4275 exc = dom_node_get_first_child(
box->
node, &child);
4276 if (exc != DOM_NO_ERR) {
4280 while (child != NULL) {
4281 dom_node *temp_node;
4284 DOM_HTML_ELEMENT_TYPE_LI)) {
4285 struct box *child_box;
4287 if (dom_node_get_user_data(child,
4288 corestring_dom___ns_key_box_node_data,
4289 &child_box) != DOM_NO_ERR) {
4290 dom_node_unref(child);
4294 if (child_box != NULL &&
4308 exc = dom_node_get_next_sibling(child, &temp_node);
4309 dom_node_unref(child);
4310 if (exc != DOM_NO_ERR) {
4339 LIST_MARKER_SIZE = 20,
4343 if (marker->
text == NULL) {
4348 marker->
text, LIST_MARKER_SIZE, &counter_len);
4349 if (css_res == CSS_OK) {
4350 if (counter_len > LIST_MARKER_SIZE) {
4357 if (marker->
text == NULL) {
4360 css_computed_format_list_style(
box->
style,
4362 counter_len, &counter_len);
4364 marker->
length = counter_len;
4376 const struct box *b)
4378 enum css_list_style_type_e t = css_computed_list_style_type(b->
style);
4381 case CSS_LIST_STYLE_TYPE_DISC:
4382 case CSS_LIST_STYLE_TYPE_CIRCLE:
4383 case CSS_LIST_STYLE_TYPE_SQUARE:
4384 case CSS_LIST_STYLE_TYPE_NONE:
4407 if (marker->
text == NULL) {
4415 marker->
x = -marker->
width;
4422 }
else if (marker->
text) {
4435 marker->
x = -marker->
width;
4471 struct box *containing_block,
4478 css_fixed value = 0;
4479 css_unit unit = CSS_UNIT_PX;
4482 assert(containing_block->
width !=
AUTO);
4487 if (
type == CSS_LEFT_SET) {
4488 if (unit == CSS_UNIT_PCT) {
4489 *left = FPCT_OF_INT_TOINT(value,
4490 containing_block->
width);
4492 *left = FIXTOINT(css_unit_len2device_px(
4502 if (
type == CSS_RIGHT_SET) {
4503 if (unit == CSS_UNIT_PCT) {
4504 *right = FPCT_OF_INT_TOINT(value,
4505 containing_block->
width);
4507 *right = FIXTOINT(css_unit_len2device_px(
4517 if (
type == CSS_TOP_SET) {
4518 if (unit == CSS_UNIT_PCT) {
4519 *top = FPCT_OF_INT_TOINT(value,
4520 containing_block->
height);
4522 *top = FIXTOINT(css_unit_len2device_px(
4532 if (
type == CSS_BOTTOM_SET) {
4533 if (unit == CSS_UNIT_PCT) {
4534 *bottom = FPCT_OF_INT_TOINT(value,
4535 containing_block->
height);
4537 *bottom = FIXTOINT(css_unit_len2device_px(
4559 struct box *containing_block,
4563 int static_left, static_top;
4564 int top, right, bottom, left;
4569 int available_width = containing_block->
width;
4580 static_left = cx +
box->
x;
4581 static_top = cy +
box->
y;
4596 &top, &right, &bottom, &left);
4604 &max_width, &min_width, 0, 0,
4605 margin, padding,
border);
4609 NSLOG(layout, DEBUG,
4610 "%i + %i + %i + %i + %i + %i + %i + %i + %i = %i",
4613 containing_block->
width);
4630 if (max_width >= 0 &&
width > max_width)
width = max_width;
4633 right = containing_block->
width -
4641 if (max_width >= 0 &&
width > max_width)
width = max_width;
4642 if (min_width > 0 &&
width < min_width)
width = min_width;
4645 space = containing_block->
width -
4651 margin[
RIGHT] = space;
4653 margin[
LEFT] = margin[
RIGHT] = space / 2;
4656 margin[
LEFT] = containing_block->
width -
4663 left - margin[
LEFT] -
4668 right = containing_block->
width -
4669 left - margin[
LEFT] -
4681 available_width -= right;
4690 if (max_width >= 0 &&
width > max_width)
4692 if (
width < min_width)
4695 left = containing_block->
width -
4703 if (max_width >= 0 &&
width > max_width)
4705 if (min_width > 0 &&
width < min_width)
4709 right = containing_block->
width -
4710 left - margin[
LEFT] -
4715 available_width -= left;
4724 if (max_width >= 0 &&
width > max_width)
4726 if (
width < min_width)
4729 right = containing_block->
width -
4730 left - margin[
LEFT] -
4737 if (max_width >= 0 &&
width > max_width)
4739 if (
width < min_width)
4742 left = containing_block->
width -
4749 left - margin[
LEFT] -
4756 if (max_width >= 0 &&
width > max_width)
4758 if (
width < min_width)
4764 if (max_width >= 0 &&
width > max_width)
4766 if (
width < min_width)
4769 right = containing_block->
width -
4770 left - margin[
LEFT] -
4777 NSLOG(layout, DEBUG,
4778 "%i + %i + %i + %i + %i + %i + %i + %i + %i = %i",
4781 containing_block->
width);
4820 NSLOG(layout, DEBUG,
4821 "%i + %i + %i + %i + %i + %i + %i + %i + %i = %i",
4824 containing_block->
height);
4833 bottom = containing_block->
height -
4839 space = containing_block->
height -
4843 margin[
TOP] = margin[
BOTTOM] = space / 2;
4844 }
else if (margin[
TOP] ==
AUTO) {
4845 margin[
TOP] = containing_block->
height -
4857 bottom = containing_block->
height -
4870 top = containing_block->
height -
4877 bottom = containing_block->
height -
4884 bottom = containing_block->
height -
4890 top = containing_block->
height -
4902 bottom = containing_block->
height -
4910 NSLOG(layout, DEBUG,
4911 "%i + %i + %i + %i + %i + %i + %i + %i + %i = %i",
4914 containing_block->
height);
4945 struct box *containing_block,
4956 (css_computed_position(c->
style) ==
4957 CSS_POSITION_ABSOLUTE ||
4958 css_computed_position(c->
style) ==
4959 CSS_POSITION_FIXED)) {
4965 }
else if (c->
style && css_computed_position(c->
style) ==
4966 CSS_POSITION_RELATIVE) {
4971 if (c->
style && (css_computed_float(c->
style) ==
4973 css_computed_float(c->
style) ==
5012 const css_unit_ctx *unit_len_ctx,
5017 int left, right, top, bottom;
5018 struct box *containing_block;
5021 css_computed_position(
box->
style) ==
5022 CSS_POSITION_RELATIVE);
5025 (css_computed_float(
box->
style) == CSS_FLOAT_LEFT ||
5026 css_computed_float(
box->
style) == CSS_FLOAT_RIGHT)) {
5033 &top, &right, &bottom, &left);
5037 else if (left ==
AUTO)
5040 else if (right ==
AUTO)
5046 if (containing_block->
style &&
5047 css_computed_direction(
5048 containing_block->
style) ==
5049 CSS_DIRECTION_RTL) {
5058 assert(left == -right);
5060 if (top ==
AUTO && bottom ==
AUTO) {
5062 }
else if (top ==
AUTO) {
5069 NSLOG(layout, DEBUG,
"left %i, right %i, top %i, bottom %i", left,
5070 right, top, bottom);
5093 const css_unit_ctx *unit_len_ctx,
5120 CSS_POSITION_RELATIVE)
5122 unit_len_ctx,
box, &
x, &
y);
5133 (fx != 0 || fy != 0)) {
5162 css_computed_position(
box->
style) !=
5163 CSS_POSITION_RELATIVE))
5196 const css_unit_ctx *unit_len_ctx,
5198 int *desc_x0,
int *desc_y0,
5199 int *desc_x1,
int *desc_y1)
5211 css_computed_overflow_y(
box->
style) ==
5212 CSS_OVERFLOW_VISIBLE &&
5214 css_fixed font_size = 0;
5215 css_unit font_unit = CSS_UNIT_PT;
5218 css_computed_font_size(
box->
style, &font_size, &font_unit);
5219 text_height = css_unit_len2device_px(
box->
style, unit_len_ctx,
5220 font_size, font_unit);
5221 text_height = FIXTOINT(text_height * 3 / 4);
5222 *desc_y0 = (*desc_y0 < -text_height) ? *desc_y0 : -text_height;
5238 const css_unit_ctx *unit_len_ctx,
5244 int child_desc_x0, child_desc_y0, child_desc_x1, child_desc_y1;
5247 int child_x = child->
x - off_x;
5248 int child_y = child->
y - off_y;
5250 bool html_object = (child->
object &&
5253 enum css_overflow_e overflow_x = CSS_OVERFLOW_VISIBLE;
5254 enum css_overflow_e overflow_y = CSS_OVERFLOW_VISIBLE;
5256 if (child->
style != NULL) {
5257 overflow_x = css_computed_overflow_x(child->
style);
5258 overflow_y = css_computed_overflow_y(child->
style);
5263 &child_desc_x0, &child_desc_y0,
5264 &child_desc_x1, &child_desc_y1);
5266 if (overflow_x == CSS_OVERFLOW_VISIBLE &&
5267 html_object ==
false) {
5272 if (overflow_y == CSS_OVERFLOW_VISIBLE &&
5273 html_object ==
false) {
5279 child_desc_x0 += child_x;
5280 child_desc_y0 += child_y;
5281 child_desc_x1 += child_x;
5282 child_desc_y1 += child_y;
5304 const css_unit_ctx *unit_len_ctx,
5342 for (child =
box->
next; child;
5343 child = child->
next) {
5369 CSS_OVERFLOW_HIDDEN &&
5370 css_computed_overflow_y(
box->
style) ==
5371 CSS_OVERFLOW_HIDDEN)
5402 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.
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.