diff options
-rw-r--r-- | dw/fltkviewbase.cc | 33 | ||||
-rw-r--r-- | dw/fltkviewbase.hh | 4 | ||||
-rw-r--r-- | dw/style.cc | 446 | ||||
-rw-r--r-- | dw/style.hh | 7 | ||||
-rw-r--r-- | dw/view.hh | 4 | ||||
-rw-r--r-- | src/css.cc | 2 | ||||
-rw-r--r-- | src/html.cc | 1 | ||||
-rw-r--r-- | src/html_common.hh | 6 | ||||
-rw-r--r-- | src/table.cc | 34 |
9 files changed, 458 insertions, 79 deletions
diff --git a/dw/fltkviewbase.cc b/dw/fltkviewbase.cc index 3fb43cb1..373e5454 100644 --- a/dw/fltkviewbase.cc +++ b/dw/fltkviewbase.cc @@ -369,6 +369,39 @@ void FltkViewBase::drawLine (core::style::Color *color, translateCanvasXToViewX (x2), translateCanvasYToViewY (y2)); } +void FltkViewBase::drawTypedLine (core::style::Color *color, + core::style::Color::Shading shading, + core::style::LineType type, int width, + int x1, int y1, int x2, int y2) +{ + char dashes[3], w, ng, d, gap, len; + const int f = 2; + + w = (width == 1) ? 0 : width; + if (type == core::style::LINE_DOTTED) { + /* customized drawing for dotted lines */ + len = (x2 == x1) ? y2 - y1 + 1 : (y2 == y1) ? x2 - x1 + 1 : 0; + ng = len / f*width; + d = len % f*width; + gap = ng ? d/ng + (w > 3 ? 2 : 0) : 0; + dashes[0] = 1; dashes[1] = f*width-gap; dashes[2] = 0; + line_style(::fltk::DASH + ::fltk::CAP_ROUND, w, dashes); + + /* These formulas also work, but ain't pretty ;) + * line_style(::fltk::DOT + ::fltk::CAP_ROUND, w); + * dashes[0] = 1; dashes[1] = 3*width-2; dashes[2] = 0; + */ + } else if (type == core::style::LINE_DASHED) { + line_style(::fltk::DASH + ::fltk::CAP_ROUND, w); + } + + setcolor(((FltkColor*)color)->colors[shading]); + drawLine (color, shading, x1, y1, x2, y2); + + if (type != core::style::LINE_NORMAL) + line_style(::fltk::SOLID); +} + void FltkViewBase::drawRectangle (core::style::Color *color, core::style::Color::Shading shading, bool filled, diff --git a/dw/fltkviewbase.hh b/dw/fltkviewbase.hh index 5e1981f8..b5c3ab5e 100644 --- a/dw/fltkviewbase.hh +++ b/dw/fltkviewbase.hh @@ -72,6 +72,10 @@ public: void drawLine (core::style::Color *color, core::style::Color::Shading shading, int x1, int y1, int x2, int y2); + void drawTypedLine (core::style::Color *color, + core::style::Color::Shading shading, + core::style::LineType type, int width, + int x1, int y1, int x2, int y2); void drawRectangle (core::style::Color *color, core::style::Color::Shading shading, bool filled, int x, int y, int width, int height); diff --git a/dw/style.cc b/dw/style.cc index 205fa0b9..e04c91d2 100644 --- a/dw/style.cc +++ b/dw/style.cc @@ -23,6 +23,7 @@ #include <string.h> #include <unistd.h> #include <ctype.h> +#include <math.h> #include "core.hh" #include "../lout/msg.h" @@ -51,7 +52,6 @@ void StyleAttrs::initValues () borderWidth.setVal (0); padding.setVal (0); borderCollapse = BORDER_MODEL_SEPARATE; - collapseStyleSet = false; setBorderColor (NULL); setBorderStyle (BORDER_NONE); hBorderSpacing = 0; @@ -128,7 +128,6 @@ bool StyleAttrs::equals (object::Object *other) { borderWidth.equals (&otherAttrs->borderWidth) && padding.equals (&otherAttrs->padding) && borderCollapse == otherAttrs->borderCollapse && - collapseStyleSet == otherAttrs->collapseStyleSet && borderColor.top == otherAttrs->borderColor.top && borderColor.right == otherAttrs->borderColor.right && borderColor.bottom == otherAttrs->borderColor.bottom && @@ -166,7 +165,6 @@ int StyleAttrs::hashValue () { borderWidth.hashValue () + padding.hashValue () + borderCollapse + - collapseStyleSet + (intptr_t) borderColor.top + (intptr_t) borderColor.right + (intptr_t) borderColor.bottom + @@ -257,7 +255,6 @@ void Style::copyAttrs (StyleAttrs *attrs) borderWidth = attrs->borderWidth; padding = attrs->padding; borderCollapse = attrs->borderCollapse; - collapseStyleSet = attrs->collapseStyleSet; borderColor = attrs->borderColor; borderStyle = attrs->borderStyle; display = attrs->display; @@ -415,18 +412,373 @@ Tooltip *Tooltip::create (Layout *layout, const char *text) // ---------------------------------------------------------------------- -static void drawTriangle (View *view, Color *color, Color::Shading shading, - int x1, int y1, int x2, int y2, int x3, int y3) { - int points[3][2]; +/* + * The drawBorder{Top,Bottom,Left,Right} functions are similar. They + * use a trapezium as draw polygon, or drawTypedLine() for dots and dashes. + * Although the concept is simple, achieving pixel accuracy is laborious [1]. + * + * [1] http://www.dillo.org/css_compat/tests/border-style.html + */ +static void drawBorderTop(View *view, Style *style, + int x1, int y1, int x2, int y2) + +{ + int points[4][2], d, w; + bool ridge = false, inset = false, dotted = false; + Color::Shading shading = Color::SHADING_NORMAL; + + if (!style->borderColor.top) + return; + + switch (style->borderStyle.top) { + case BORDER_NONE: + case BORDER_HIDDEN: + break; + case BORDER_DOTTED: + dotted = true; + case BORDER_DASHED: + w = style->borderWidth.top; + view->drawTypedLine(style->borderColor.top, shading, + dotted ? LINE_DOTTED : LINE_DASHED, + w, x1+w/2, y1+w/2, x2-w/2, y2+w/2); + break; + case BORDER_SOLID: + case BORDER_INSET: + inset = true; + case BORDER_OUTSET: + if (style->borderStyle.top != BORDER_SOLID) + shading = (inset) ? Color::SHADING_DARK : Color::SHADING_LIGHT; + + if (style->borderWidth.top == 1) { + view->drawLine(style->borderColor.top, shading, x1, y1, x2, y2); + } else { + points[0][0] = x1; + points[1][0] = x2 + 1; + points[0][1] = points[1][1] = y1; + points[2][0] = points[1][0] - style->borderWidth.right; + points[3][0] = x1 + style->borderWidth.left; + points[2][1] = points[3][1] = points[0][1] + style->borderWidth.top; + view->drawPolygon (style->borderColor.top, shading, true, points, 4); + } + break; + case BORDER_RIDGE: + ridge = true; + case BORDER_GROOVE: + d = style->borderWidth.top & 1; + points[0][0] = x1; + points[1][0] = x2 + 1; + points[0][1] = points[1][1] = y1; + points[2][0] = x2 - style->borderWidth.right / 2; + points[3][0] = x1 + style->borderWidth.left / 2; + points[2][1] = points[3][1] = y1 + style->borderWidth.top / 2 + d; + shading = (ridge) ? Color::SHADING_LIGHT : Color::SHADING_DARK; + view->drawPolygon (style->borderColor.top, shading, true, points, 4); + points[0][0] = x1 + style->borderWidth.left / 2 + d; + points[1][0] = x2 - style->borderWidth.right / 2 + 1 - d; + points[0][1] = points[1][1] = y1 + style->borderWidth.top / 2 + d; + points[2][0] = x2 - style->borderWidth.right + 1 - d; + points[3][0] = x1 + style->borderWidth.left; + points[2][1] = points[3][1] = y1 + style->borderWidth.top; + shading = (ridge) ? Color::SHADING_DARK : Color::SHADING_LIGHT; + view->drawPolygon (style->borderColor.top, shading, true, points, 4); + break; + case BORDER_DOUBLE: + w = (int) rint(style->borderWidth.top / 3.0); + d = w ? style->borderWidth.top - 2 * w : 0; + int w_l = (int) rint(style->borderWidth.left / 3.0); + int w_r = (int) rint(style->borderWidth.right / 3.0); + if (style->borderWidth.top == 1) { + view->drawLine(style->borderColor.top, shading, x1, y1, x2, y2); + break; + } + points[0][0] = x1; + points[1][0] = x2 + 1; + points[0][1] = points[1][1] = y1; + points[2][0] = points[1][0] - w_r; + points[3][0] = points[0][0] + w_l; + points[2][1] = points[3][1] = points[0][1] + w; + view->drawPolygon (style->borderColor.top, shading, true, points, 4); + points[0][0] = x1 + style->borderWidth.left - w_l; + points[1][0] = x2 + 1 - style->borderWidth.right + w_r; + points[0][1] = points[1][1] = y1 + w + d; + points[2][0] = x2 + 1 - style->borderWidth.right; + points[3][0] = x1 + style->borderWidth.left; + points[2][1] = points[3][1] = y1 + style->borderWidth.top; + view->drawPolygon (style->borderColor.top, shading, true, points, 4); + break; + } +} + +static void drawBorderBottom(View *view, Style *style, + int x1, int y1, int x2, int y2) + +{ + int points[4][2], d, w; + bool ridge = false, inset = false, dotted = false; + Color::Shading shading = Color::SHADING_NORMAL; + + if (!style->borderColor.bottom) + return; + + switch (style->borderStyle.bottom) { + case BORDER_NONE: + case BORDER_HIDDEN: + break; + case BORDER_DOTTED: + dotted = true; + case BORDER_DASHED: + w = style->borderWidth.bottom; + view->drawTypedLine(style->borderColor.top, shading, + dotted ? LINE_DOTTED : LINE_DASHED, + w, x1+w/2, y1-w/2, x2-w/2, y2-w/2); + break; + case BORDER_SOLID: + case BORDER_INSET: + inset = true; + case BORDER_OUTSET: + if (style->borderStyle.bottom != BORDER_SOLID) + shading = (inset) ? Color::SHADING_LIGHT : Color::SHADING_DARK; + + if (style->borderWidth.bottom == 1) { /* 1 pixel line */ + view->drawLine(style->borderColor.bottom, shading, x1, y1, x2, y2); + } else { + points[0][0] = x1 - 1; + points[1][0] = x2 + 2; + points[0][1] = points[1][1] = y1 + 1; + points[2][0] = points[1][0] - style->borderWidth.right; + points[3][0] = points[0][0] + style->borderWidth.left; + points[2][1] = points[3][1] = points[0][1]-style->borderWidth.bottom; + view->drawPolygon (style->borderColor.top, shading, true, points, 4); + } + break; + case BORDER_RIDGE: + ridge = true; + case BORDER_GROOVE: + w = style->borderWidth.bottom; + d = w & 1; + points[0][0] = x1 - 1; + points[1][0] = x2 + 2 - d; + points[0][1] = points[1][1] = y1 + 1; + points[2][0] = points[1][0] - style->borderWidth.right / 2; + points[3][0] = points[0][0] + style->borderWidth.left / 2 + d; + points[2][1] = points[3][1] = points[0][1] - w/2 - d; + shading = (ridge) ? Color::SHADING_DARK : Color::SHADING_LIGHT; + view->drawPolygon (style->borderColor.bottom, shading, true, points, 4); + // clockwise + points[0][0] = x1 + style->borderWidth.left - 1; + points[1][0] = x2 + 1 - style->borderWidth.right + 1; + points[0][1] = points[1][1] = y1 - w + 1; + points[2][0] = points[1][0] + style->borderWidth.right / 2; + points[3][0] = points[0][0] - style->borderWidth.left / 2; + points[2][1] = points[3][1] = points[0][1] + w/2; + shading = (ridge) ? Color::SHADING_LIGHT : Color::SHADING_DARK; + view->drawPolygon (style->borderColor.top, shading, true, points, 4); + break; + case BORDER_DOUBLE: + w = (int) rint(style->borderWidth.bottom / 3.0); + d = w ? style->borderWidth.bottom - 2 * w : 0; + int w_l = (int) rint(style->borderWidth.left / 3.0); + int w_r = (int) rint(style->borderWidth.right / 3.0); + if (style->borderWidth.bottom == 1) { + view->drawLine(style->borderColor.bottom, shading, x1, y1, x2, y2); + break; + } + points[0][0] = x2 + 2; + points[1][0] = x1 - 1; + points[0][1] = points[1][1] = y1 + 1; + points[2][0] = points[1][0] + w_l; + points[3][0] = points[0][0] - w_r; + points[2][1] = points[3][1] = points[0][1] - w; + view->drawPolygon (style->borderColor.top, shading, true, points, 4); + points[0][0] = x2 + 2 - style->borderWidth.right + w_r; + points[1][0] = x1 - 1 + style->borderWidth.left - w_l; + points[0][1] = points[1][1] = y1 + 1 - w - d; + points[2][0] = x1 - 1 + style->borderWidth.left; + points[3][0] = x2 + 2 - style->borderWidth.right; + points[2][1] = points[3][1] = y1 + 1 - style->borderWidth.bottom; + view->drawPolygon (style->borderColor.top, shading, true, points, 4); + break; + } +} + +static void drawBorderLeft(View *view, Style *style, + int x1, int y1, int x2, int y2) + +{ + int points[4][2], d, w; + bool ridge = false, inset = false, dotted = false; + Color::Shading shading = Color::SHADING_NORMAL; + + if (!style->borderColor.left) + return; - points[0][0] = x1; - points[0][1] = y1; - points[1][0] = x2; - points[1][1] = y2; - points[2][0] = x3; - points[2][1] = y3; + switch (style->borderStyle.left) { + case BORDER_NONE: + case BORDER_HIDDEN: + break; + case BORDER_DOTTED: + dotted = true; + case BORDER_DASHED: + w = style->borderWidth.left; + view->drawTypedLine(style->borderColor.left, shading, + dotted ? LINE_DOTTED : LINE_DASHED, + w, x1+w/2, y1+w/2, x1+w/2, y2-w/2); + break; + case BORDER_SOLID: + case BORDER_INSET: + inset = true; + case BORDER_OUTSET: + if (style->borderStyle.left != BORDER_SOLID) + shading = (inset) ? Color::SHADING_DARK : Color::SHADING_LIGHT; + if (style->borderWidth.left == 1) { /* 1 pixel line */ + view->drawLine(style->borderColor.left, shading, x1, y1, x2, y2); + } else { + points[0][0] = points[1][0] = x1; + points[0][1] = y1 - 1; + points[1][1] = y2 + 1; + points[2][0] = points[3][0] = points[0][0] + style->borderWidth.left; + points[2][1] = points[1][1] - style->borderWidth.bottom; + points[3][1] = points[0][1] + style->borderWidth.top; + view->drawPolygon (style->borderColor.left, shading, true, points, 4); + } + break; + case BORDER_RIDGE: + ridge = true; + case BORDER_GROOVE: + w = style->borderWidth.left; + d = w & 1; + points[0][0] = points[1][0] = x1; + points[0][1] = y1; + points[1][1] = y2; + points[2][0] = points[3][0] = x1 + w / 2 + d; + points[2][1] = y2 - style->borderWidth.bottom / 2; + points[3][1] = y1 + style->borderWidth.top / 2; + shading = (ridge) ? Color::SHADING_LIGHT : Color::SHADING_DARK; + view->drawPolygon (style->borderColor.top, shading, true, points, 4); + points[0][0] = points[1][0] = x1 + w / 2 + d; + points[0][1] = y1 + style->borderWidth.top / 2; + points[1][1] = y2 - style->borderWidth.bottom / 2; + points[2][0] = points[3][0] = x1 + w; + points[2][1] = y2 - style->borderWidth.bottom; + points[3][1] = y1 + style->borderWidth.top; + shading = (ridge) ? Color::SHADING_DARK : Color::SHADING_LIGHT; + view->drawPolygon (style->borderColor.top, shading, true, points, 4); + break; + case BORDER_DOUBLE: + w = (int) rint(style->borderWidth.left / 3.0); + d = w ? style->borderWidth.left - 2 * w : 0; + int w_b = (int) rint(style->borderWidth.bottom / 3.0); + int w_t = (int) rint(style->borderWidth.top / 3.0); + if (style->borderWidth.left == 1) { + view->drawLine(style->borderColor.left, shading, x1, y1, x2, y2-1); + break; + } + points[0][0] = points[1][0] = x1; + points[0][1] = y1 - 1; + points[1][1] = y2 + 1; + points[2][0] = points[3][0] = points[0][0] + w; + points[2][1] = points[1][1] - w_b; + points[3][1] = points[0][1] + w_t; + view->drawPolygon (style->borderColor.left, shading, true, points, 4); + points[0][0] = points[1][0] = x1 + w + d; + points[0][1] = y1 - 1 + style->borderWidth.top - w_t; + points[1][1] = y2 + 1 - style->borderWidth.bottom + w_b; + points[2][0] = points[3][0] = points[0][0] + w; + points[2][1] = y2 + 1 - style->borderWidth.bottom; + points[3][1] = y1 - 1 + style->borderWidth.top; + view->drawPolygon (style->borderColor.left, shading, true, points, 4); + break; + } +} - view->drawPolygon (color, shading, true, points, 3); +static void drawBorderRight(View *view, Style *style, + int x1, int y1, int x2, int y2) + +{ + int points[4][2], d, w; + bool ridge = false, inset = false, dotted = false; + Color::Shading shading = Color::SHADING_NORMAL; + + if (!style->borderColor.right) + return; + + switch (style->borderStyle.right) { + case BORDER_NONE: + case BORDER_HIDDEN: + break; + case BORDER_DOTTED: + dotted = true; + case BORDER_DASHED: + w = style->borderWidth.right; + view->drawTypedLine(style->borderColor.right, shading, + dotted ? LINE_DOTTED : LINE_DASHED, + w, x1 - w/2, y1 + w/2, x1 - w/2, y2 - w/2); + break; + case BORDER_SOLID: + case BORDER_INSET: + inset = true; + case BORDER_OUTSET: + if (style->borderStyle.right != BORDER_SOLID) + shading = (inset) ? Color::SHADING_LIGHT : Color::SHADING_DARK; + if (style->borderWidth.right == 1) { /* 1 pixel line */ + view->drawLine(style->borderColor.right, shading, x1, y1, x2, y2); + } else { + points[0][0] = points[1][0] = x1 + 1; + points[0][1] = y1 - 1; + points[1][1] = y2 + 1; + points[2][0] = points[3][0] = points[0][0]-style->borderWidth.right; + points[2][1] = points[1][1] - style->borderWidth.bottom; + points[3][1] = points[0][1] + style->borderWidth.top; + view->drawPolygon (style->borderColor.right, shading, true,points,4); + } + break; + case BORDER_RIDGE: + ridge = true; + case BORDER_GROOVE: + w = style->borderWidth.right; + d = w & 1; + points[0][0] = points[1][0] = x1 + 1; + points[0][1] = y1; + points[1][1] = y2; + points[2][0] = points[3][0] = points[0][0] - w / 2 - d; + points[2][1] = y2 - style->borderWidth.bottom / 2; + points[3][1] = points[0][1] + style->borderWidth.top / 2; + shading = (ridge) ? Color::SHADING_DARK : Color::SHADING_LIGHT; + view->drawPolygon (style->borderColor.right, shading, true, points, 4); + points[0][0] = points[1][0] = x1 + 1 - w / 2 - d; + points[0][1] = y1 + style->borderWidth.top / 2; + points[1][1] = y2 - style->borderWidth.bottom / 2; + points[2][0] = points[3][0] = x1 + 1 - w; + points[2][1] = y2 - style->borderWidth.bottom; + points[3][1] = y1 + style->borderWidth.top; + shading = (ridge) ? Color::SHADING_LIGHT: Color::SHADING_DARK; + view->drawPolygon (style->borderColor.right, shading, true, points, 4); + break; + case BORDER_DOUBLE: + w = (int) rint(style->borderWidth.right / 3.0); + d = w ? style->borderWidth.right - 2 * w : 0; + int w_b = (int) rint(style->borderWidth.bottom / 3.0); + int w_t = (int) rint(style->borderWidth.top / 3.0); + if (style->borderWidth.right == 1) { + view->drawLine(style->borderColor.right, shading, x1, y1, x2, y2); + break; + } + points[0][0] = points[1][0] = x1 + 1; + points[0][1] = y1 - 1; + points[1][1] = y2 + 1; + points[2][0] = points[3][0] = points[0][0] - w; + points[2][1] = points[1][1] - w_b; + points[3][1] = points[0][1] + w_t; + view->drawPolygon (style->borderColor.right, shading, true, points, 4); + points[0][0] = points[1][0] = x1 + 1 - w - d; + points[0][1] = y1 - 1 + style->borderWidth.top - w_t; + points[1][1] = y2 + 1 - style->borderWidth.bottom + w_b; + points[2][0] = points[3][0] = points[0][0] - w; + points[2][1] = y2 + 1 - style->borderWidth.bottom; + points[3][1] = y1 - 1 + style->borderWidth.top; + view->drawPolygon (style->borderColor.right, shading, true, points, 4); + break; + } } /** @@ -440,14 +792,13 @@ void drawBorder (View *view, Rectangle *area, { /** \todo a lot! */ Color::Shading dark, light, normal; - Color::Shading top, right, bottom, left; int xb1, yb1, xb2, yb2, xp1, yp1, xp2, yp2; // top left and bottom right point of outer border boundary xb1 = x + style->margin.left; yb1 = y + style->margin.top; - xb2 = x + width - style->margin.right; - yb2 = y + height - style->margin.bottom; + xb2 = x + (width > 0 ? width - 1 : 0) - style->margin.right; + yb2 = y + (height > 0 ? height - 1 : 0) - style->margin.bottom; // top left and bottom right point of inner border boundary xp1 = xb1 + style->borderWidth.left; @@ -459,63 +810,10 @@ void drawBorder (View *view, Rectangle *area, dark = inverse ? Color::SHADING_LIGHT : Color::SHADING_DARK; normal = inverse ? Color::SHADING_INVERSE : Color::SHADING_NORMAL; - switch (style->borderStyle.top) { - case BORDER_INSET: - top = left = dark; - right = bottom = light; - break; - - case BORDER_OUTSET: - top = left = light; - right = bottom = dark; - break; - - default: - top = right = bottom = left = normal; - break; - } - - if (style->borderStyle.top != BORDER_NONE && style->borderColor.top) - view->drawRectangle(style->borderColor.top, top, true, - xb1, yb1, xb2 - xb1, style->borderWidth.top); - - if (style->borderStyle.bottom != BORDER_NONE && style->borderColor.bottom) - view->drawRectangle(style->borderColor.bottom, bottom, true, - xb1, yb2, xb2 - xb1, - style->borderWidth.bottom); - - if (style->borderStyle.left != BORDER_NONE && style->borderColor.left) - view->drawRectangle(style->borderColor.left, left, true, - xb1, yp1, style->borderWidth.left, yp2 - yp1); - - if (style->borderWidth.left > 1) { - if (style->borderWidth.top > 1 && - (style->borderColor.left != style->borderColor.top || - left != top)) - drawTriangle (view, style->borderColor.left, left, - xb1, yp1, xp1, yp1, xb1, yb1); - if (style->borderWidth.bottom > 1 && - (style->borderColor.left != style->borderColor.bottom || - left != bottom)) - drawTriangle (view, style->borderColor.left, left, - xb1, yp2, xp1, yp2, xb1, yb2); - } - - if (style->borderStyle.right != BORDER_NONE && style->borderColor.right) - view->drawRectangle(style->borderColor.right, right, true, - xb2, yp1, - style->borderWidth.right, yp2 - yp1); - - if (style->borderWidth.right > 1) { - if (style->borderWidth.top > 1 && - (style->borderColor.right != style->borderColor.top || - right != top)) - drawTriangle (view, style->borderColor.right, right, - xb2, yp1, xp2, yp1, xb2, yb1); - if (style->borderWidth.bottom > 1 && - (style->borderColor.right != style->borderColor.bottom || - right != bottom)) - drawTriangle (view, style->borderColor.right, right, - xb2, yp2, xp2, yp2, xb2, yb2); - } + drawBorderRight(view, style, xb2, yb1, xb2, yb2); + drawBorderLeft(view, style, xb1, yb1, xb1, yb2); + drawBorderTop(view, style, xb1, yb1, xb2, yb1); + drawBorderBottom(view, style, xb1, yb2, xb2, yb2); } diff --git a/dw/style.hh b/dw/style.hh index fe964dec..4ebb7bb5 100644 --- a/dw/style.hh +++ b/dw/style.hh @@ -263,6 +263,12 @@ enum DisplayType { DISPLAY_TABLE_CELL }; +enum LineType { + LINE_NORMAL, + LINE_DOTTED, + LINE_DASHED +}; + enum ListStylePosition { LIST_STYLE_POSITION_INSIDE, LIST_STYLE_POSITION_OUTSIDE @@ -441,7 +447,6 @@ public: Box margin, borderWidth, padding; BorderCollapse borderCollapse; - bool collapseStyleSet; struct { Color *top, *right, *bottom, *left; } borderColor; struct { BorderStyle top, right, bottom, left; } borderStyle; @@ -166,6 +166,10 @@ public: virtual void drawLine (style::Color *color, style::Color::Shading shading, int x1, int y1, int x2, int y2) = 0; + virtual void drawTypedLine (style::Color *color, + style::Color::Shading shading, + style::LineType type, int width, + int x1, int y1, int x2, int y2) = 0; virtual void drawRectangle (style::Color *color, style::Color::Shading shading, bool filled, int x, int y, int width, int height) = 0; @@ -609,7 +609,7 @@ void CssContext::buildUserAgentStyle () { "sub {vertical-align: sub}" "sup {vertical-align: super}" "s, strike, del {text-decoration: line-through}" - "table {border-spacing: 1px}" + "table {border-spacing: 2px}" "td, th {padding: 2px}" "thead, tbody, tfoot {vertical-align: middle}" "th {font-weight: bolder; text-align: center}" diff --git a/src/html.cc b/src/html.cc index 8019b4ef..11ad98e3 100644 --- a/src/html.cc +++ b/src/html.cc @@ -428,6 +428,7 @@ DilloHtml::DilloHtml(BrowserWindow *p_bw, const DilloUrl *url, stack->increase(); stack->getRef(0)->parse_mode = DILLO_HTML_PARSE_MODE_INIT; stack->getRef(0)->table_mode = DILLO_HTML_TABLE_MODE_NONE; + stack->getRef(0)->table_border_mode = DILLO_HTML_TABLE_BORDER_SEPARATE; stack->getRef(0)->cell_text_align_set = false; stack->getRef(0)->list_type = HTML_LIST_NONE; stack->getRef(0)->list_number = 0; diff --git a/src/html_common.hh b/src/html_common.hh index bfcb8123..cf5c8114 100644 --- a/src/html_common.hh +++ b/src/html_common.hh @@ -64,6 +64,11 @@ typedef enum { } DilloHtmlTableMode; typedef enum { + DILLO_HTML_TABLE_BORDER_SEPARATE, + DILLO_HTML_TABLE_BORDER_COLLAPSE +} DilloHtmlTableBorderMode; + +typedef enum { HTML_LIST_NONE, HTML_LIST_UNORDERED, HTML_LIST_ORDERED @@ -96,6 +101,7 @@ struct _DilloHtmlImage { struct _DilloHtmlState { DilloHtmlParseMode parse_mode; DilloHtmlTableMode table_mode; + DilloHtmlTableBorderMode table_border_mode; bool cell_text_align_set; DilloHtmlListMode list_type; diff --git a/src/table.cc b/src/table.cc index 1029c9f6..d21f8d74 100644 --- a/src/table.cc +++ b/src/table.cc @@ -139,6 +139,7 @@ void Html_tag_open_table(DilloHtml *html, const char *tag, int tagsize) HT2TB(html)->addWidget (table, html->styleEngine->style ()); S_TOP(html)->table_mode = DILLO_HTML_TABLE_MODE_TOP; + S_TOP(html)->table_border_mode = DILLO_HTML_TABLE_BORDER_SEPARATE; S_TOP(html)->cell_text_align_set = FALSE; S_TOP(html)->table = table; } @@ -216,6 +217,34 @@ void Html_tag_open_th(DilloHtml *html, const char *tag, int tagsize) * Utilities */ +/* + * The table border model is stored in the table's stack item + */ +static int Html_table_get_border_model(DilloHtml *html) +{ + static int i_TABLE = -1; + if (i_TABLE == -1) + i_TABLE = a_Html_tag_index("table"); + + int s_idx = html->stack->size(); + while (--s_idx > 0 && html->stack->getRef(s_idx)->tag_idx != i_TABLE) + ; + return html->stack->getRef(s_idx)->table_border_mode; +} + +/* + * Set current table's border model + */ +static void Html_table_set_border_model(DilloHtml *html, + DilloHtmlTableBorderMode mode) +{ + int s_idx = html->stack->size(), i_TABLE = a_Html_tag_index("table"); + + while (--s_idx > 0 && html->stack->getRef(s_idx)->tag_idx != i_TABLE) ; + if (s_idx > 0) + html->stack->getRef(s_idx)->table_border_mode = mode; +} + /* WORKAROUND: collapsing border model requires moving rendering code from * the cell to the table, and making table-code aware of each * cell style. @@ -243,11 +272,10 @@ static void Html_set_collapsing_border_model(DilloHtml *html, Widget *col_tb) collapseStyle = Style::create(HT2LT(html), &collapseCellAttrs); col_tb->setStyle (collapseStyle); - if (!tableStyle->collapseStyleSet) { + if (Html_table_get_border_model(html) != DILLO_HTML_TABLE_BORDER_COLLAPSE) { + Html_table_set_border_model(html, DILLO_HTML_TABLE_BORDER_COLLAPSE); collapseTableAttrs = *tableStyle; - collapseTableAttrs.collapseStyleSet = true; collapseTableAttrs.margin.setVal (marginWidth); - _MSG("COLLAPSING table margin set to %d\n", marginWidth); collapseTableAttrs.borderWidth.left = borderWidth; collapseTableAttrs.borderWidth.top = borderWidth; collapseTableAttrs.borderWidth.right = 0; |