aboutsummaryrefslogtreecommitdiff
path: root/dw/style.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dw/style.cc')
-rw-r--r--dw/style.cc272
1 files changed, 125 insertions, 147 deletions
diff --git a/dw/style.cc b/dw/style.cc
index 207c47a3..b361e068 100644
--- a/dw/style.cc
+++ b/dw/style.cc
@@ -14,8 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
@@ -24,6 +23,9 @@
#include <ctype.h>
#include "core.hh"
+#include "../lout/msg.h"
+
+using namespace lout;
namespace dw {
namespace core {
@@ -37,14 +39,13 @@ void StyleAttrs::initValues ()
textDecoration = TEXT_DECORATION_NONE;
textAlign = TEXT_ALIGN_LEFT;
textAlignChar = '.';
+ listStylePosition = LIST_STYLE_POSITION_OUTSIDE;
listStyleType = LIST_STYLE_TYPE_DISC;
- valign = VALIGN_MIDDLE;
+ valign = VALIGN_BASELINE;
backgroundColor = NULL;
- width = LENGTH_AUTO;
- height = LENGTH_AUTO;
+ width = height = lineHeight = LENGTH_AUTO;
vloat = FLOAT_NONE;
clear = CLEAR_NONE;
-
margin.setVal (0);
borderWidth.setVal (0);
padding.setVal (0);
@@ -52,6 +53,7 @@ void StyleAttrs::initValues ()
setBorderStyle (BORDER_NONE);
hBorderSpacing = 0;
vBorderSpacing = 0;
+ wordSpacing = 0;
display = DISPLAY_INLINE;
whiteSpace = WHITE_SPACE_NORMAL;
@@ -64,12 +66,9 @@ void StyleAttrs::initValues ()
*/
void StyleAttrs::resetValues ()
{
- x_link = -1;
x_img = -1;
- x_tooltip = NULL;
- textAlign = TEXT_ALIGN_LEFT; /* ??? */
- valign = VALIGN_MIDDLE;
+ valign = VALIGN_BASELINE;
textAlignChar = '.';
vloat = FLOAT_NONE; /** \todo Correct? Check specification. */
clear = CLEAR_NONE; /** \todo Correct? Check specification. */
@@ -86,8 +85,6 @@ void StyleAttrs::resetValues ()
vBorderSpacing = 0;
display = DISPLAY_INLINE;
- whiteSpace = WHITE_SPACE_NORMAL;
- cursor = CURSOR_DEFAULT; /** \todo Check CSS specification again. */
}
/**
@@ -121,8 +118,10 @@ bool StyleAttrs::equals (object::Object *other) {
textAlignChar == otherAttrs->textAlignChar &&
hBorderSpacing == otherAttrs->hBorderSpacing &&
vBorderSpacing == otherAttrs->vBorderSpacing &&
+ wordSpacing == otherAttrs->wordSpacing &&
width == otherAttrs->width &&
height == otherAttrs->height &&
+ lineHeight == otherAttrs->lineHeight &&
margin.equals (&otherAttrs->margin) &&
borderWidth.equals (&otherAttrs->borderWidth) &&
padding.equals (&otherAttrs->padding) &&
@@ -136,7 +135,9 @@ bool StyleAttrs::equals (object::Object *other) {
borderStyle.left == otherAttrs->borderStyle.left &&
display == otherAttrs->display &&
whiteSpace == otherAttrs->whiteSpace &&
+ listStylePosition == otherAttrs->listStylePosition &&
listStyleType == otherAttrs->listStyleType &&
+ cursor == otherAttrs->cursor &&
x_link == otherAttrs->x_link &&
x_img == otherAttrs->x_img &&
x_tooltip == otherAttrs->x_tooltip);
@@ -152,10 +153,12 @@ int StyleAttrs::hashValue () {
textAlignChar +
hBorderSpacing +
vBorderSpacing +
+ wordSpacing +
width +
height +
+ lineHeight +
margin.hashValue () +
- borderWidth.hashValue () +
+ borderWidth.hashValue () +
padding.hashValue () +
(intptr_t) borderColor.top +
(intptr_t) borderColor.right +
@@ -167,7 +170,9 @@ int StyleAttrs::hashValue () {
borderStyle.left +
display +
whiteSpace +
+ listStylePosition +
listStyleType +
+ cursor +
x_link +
x_img +
(intptr_t) x_tooltip;
@@ -222,7 +227,7 @@ Style::~Style ()
x_tooltip->unref();
styleTable->remove (this);
- totalRef--;
+ totalRef--;
}
void Style::copyAttrs (StyleAttrs *attrs)
@@ -238,8 +243,10 @@ void Style::copyAttrs (StyleAttrs *attrs)
clear = attrs->clear;
hBorderSpacing = attrs->hBorderSpacing;
vBorderSpacing = attrs->vBorderSpacing;
+ wordSpacing = attrs->wordSpacing;
width = attrs->width;
height = attrs->height;
+ lineHeight = attrs->lineHeight;
margin = attrs->margin;
borderWidth = attrs->borderWidth;
padding = attrs->padding;
@@ -247,6 +254,7 @@ void Style::copyAttrs (StyleAttrs *attrs)
borderStyle = attrs->borderStyle;
display = attrs->display;
whiteSpace = attrs->whiteSpace;
+ listStylePosition = attrs->listStylePosition;
listStyleType = attrs->listStyleType;
cursor = attrs->cursor;
x_link = attrs->x_link;
@@ -261,8 +269,11 @@ bool FontAttrs::equals(object::Object *other)
FontAttrs *otherAttrs = (FontAttrs*)other;
return
this == otherAttrs ||
- (size == otherAttrs->size && weight == otherAttrs->weight &&
- style == otherAttrs->style && strcmp (name, otherAttrs->name) == 0);
+ (size == otherAttrs->size &&
+ weight == otherAttrs->weight &&
+ style == otherAttrs->style &&
+ letterSpacing == otherAttrs->letterSpacing &&
+ strcmp (name, otherAttrs->name) == 0);
}
int FontAttrs::hashValue()
@@ -271,12 +282,13 @@ int FontAttrs::hashValue()
h = (h << 5) - h + size;
h = (h << 5) - h + weight;
h = (h << 5) - h + style;
+ h = (h << 5) - h + letterSpacing;
return h;
}
Font::~Font ()
{
- delete name;
+ free ((char*)name);
}
void Font::copyAttrs (FontAttrs *attrs)
@@ -285,6 +297,7 @@ void Font::copyAttrs (FontAttrs *attrs)
size = attrs->size;
weight = attrs->weight;
style = attrs->style;
+ letterSpacing = attrs->letterSpacing;
}
Font *Font::create0 (Layout *layout, FontAttrs *attrs,
@@ -298,43 +311,9 @@ Font *Font::create (Layout *layout, FontAttrs *attrs)
return create0 (layout, attrs, false);
}
-Font *Font::createFromList (Layout *layout, FontAttrs *attrs,
- char *defaultFamily)
+bool Font::exists (Layout *layout, const char *name)
{
- Font *font = NULL;
- FontAttrs attrs2;
- char *comma, *list, *current;
-
- attrs2 = *attrs;
- current = list = strdup (attrs->name);
-
- while (current && (font == NULL)) {
- comma = strchr (current, ',');
- if (comma) *comma = 0;
-
- attrs2.name = current;
- font = create0 (layout, &attrs2, false);
- if (font)
- break;
-
- if (comma) {
- current = comma + 1;
- while (isspace (*current)) current++;
- } else
- current = NULL;
- }
-
- delete list;
-
- if (font == NULL) {
- attrs2.name = defaultFamily;
- font = create0 (layout, &attrs2, true);
- }
-
- if (font == NULL)
- fprintf (stderr, "Could not find any font.\n");
-
- return font;
+ return layout->fontExists (name);
}
// ----------------------------------------------------------------------
@@ -342,12 +321,12 @@ Font *Font::createFromList (Layout *layout, FontAttrs *attrs,
bool ColorAttrs::equals(object::Object *other)
{
ColorAttrs *oc = (ColorAttrs*)other;
- return this == oc || (color == oc->color && type == oc->type);
+ return this == oc || (color == oc->color);
}
int ColorAttrs::hashValue()
{
- return color ^ type;
+ return color;
}
Color::~Color ()
@@ -410,72 +389,33 @@ int Color::shadeColor (int color, Shading shading)
}
}
-
-Color *Color::create (Layout *layout, int col, Type type)
+
+Color *Color::create (Layout *layout, int col)
{
- ColorAttrs attrs(col, type);
- Color *color = NULL;
-
- switch (type) {
- case TYPE_SIMPLE:
- color = layout->createSimpleColor (col);
- break;
- case TYPE_SHADED:
- color = layout->createShadedColor (col);
- break;
- }
+ ColorAttrs attrs(col);
- return color;
+ return layout->createColor (col);
+}
+
+Tooltip *Tooltip::create (Layout *layout, const char *text)
+{
+ return layout->createTooltip (text);
}
// ----------------------------------------------------------------------
-/**
- * \brief Draw a part of a border.
- */
-static void drawPolygon (View *view, Color *color, Color::Shading shading,
- int x1, int y1, int x2, int y2,
- int width, int w1, int w2)
-{
- int points[4][2];
-
- if (width != 0) {
- if (width == 1) {
- if (x1 == x2)
- view->drawLine (color, shading, x1, y1, x2, y2 - 1);
- else
- view->drawLine (color, shading, x1, y1, x2 - 1, y2);
- } else if (width == -1) {
- if (x1 == x2)
- view->drawLine (color, shading, x1 - 1, y1, x2 - 1, y2 - 1);
- else
- view->drawLine (color, shading, x1, y1 - 1, x2 - 1, y2 - 1);
- } else {
- points[0][0] = x1;
- points[0][1] = y1;
- points[1][0] = x2;
- points[1][1] = y2;
-
- if (x1 == x2) {
- points[2][0] = x1 + width;
- points[2][1] = y2 + w2;
- points[3][0] = x1 + width;
- points[3][1] = y1 + w1;
- } else {
- points[2][0] = x2 + w2;
- points[2][1] = y1 + width;
- points[3][0] = x1 + w1;
- points[3][1] = y1 + width;
- }
-
- /*
- printf ("drawPolygon: (%d, %d) .. (%d, %d) .. (%d, %d) .. (%d, %d)\n",
- points[0][0], points[0][1], points[1][0], points[1][1],
- points[2][0], points[2][1], points[3][0], points[3][1]);
- */
- view->drawPolygon (color, shading, true, points, 4);
- }
- }
+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];
+
+ points[0][0] = x1;
+ points[0][1] = y1;
+ points[1][0] = x2;
+ points[1][1] = y2;
+ points[2][0] = x3;
+ points[2][1] = y3;
+
+ view->drawPolygon (color, shading, true, points, 3);
}
/**
@@ -492,18 +432,17 @@ void drawBorder (View *view, Rectangle *area,
Color::Shading top, right, bottom, left;
int xb1, yb1, xb2, yb2, xp1, yp1, xp2, yp2;
- if (style->borderStyle.top == BORDER_NONE)
- return;
-
+ // top left and bottom right point of outer border boundary
xb1 = x + style->margin.left;
yb1 = y + style->margin.top;
- xb2 = xb1 + width - style->margin.left - style->margin.right;
- yb2 = yb1 + height - style->margin.top - style->margin.bottom;
+ xb2 = x + width - style->margin.right;
+ yb2 = y + height - style->margin.bottom;
- xp1 = xb1 + style->borderWidth.top;
- yp1 = yb1 + style->borderWidth.left;
- xp2 = xb2 + style->borderWidth.bottom;
- yp2 = yb2 + style->borderWidth.right;
+ // top left and bottom right point of inner border boundary
+ xp1 = xb1 + style->borderWidth.left;
+ yp1 = yb1 + style->borderWidth.top;
+ xp2 = xb2 - style->borderWidth.right;
+ yp2 = yb2 - style->borderWidth.bottom;
light = inverse ? Color::SHADING_DARK : Color::SHADING_LIGHT;
dark = inverse ? Color::SHADING_LIGHT : Color::SHADING_DARK;
@@ -525,18 +464,47 @@ void drawBorder (View *view, Rectangle *area,
break;
}
- drawPolygon (view, style->borderColor.top, top, xb1, yb1, xb2, yb1,
- style->borderWidth.top, style->borderWidth.left,
- - style->borderWidth.right);
- drawPolygon (view, style->borderColor.right, right, xb2, yb1, xb2, yb2,
- - style->borderWidth.right, style->borderWidth.top,
- - style->borderWidth.bottom);
- drawPolygon (view, style->borderColor.bottom, bottom, xb1, yb2, xb2, yb2,
- - style->borderWidth.bottom, style->borderWidth.left,
- - style->borderWidth.right);
- drawPolygon (view, style->borderColor.left, left, xb1, yb1, xb1, yb2,
- style->borderWidth.left, style->borderWidth.top,
- - style->borderWidth.bottom);
+ 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);
+ }
}
@@ -574,12 +542,12 @@ void drawBackground (View *view, Rectangle *area,
// ----------------------------------------------------------------------
static const char
- *roman_I0[] = { "","I","II","III","IV","V","VI","VII","VIII","IX" },
- *roman_I1[] = { "","X","XX","XXX","XL","L","LX","LXX","LXXX","XC" },
- *roman_I2[] = { "","C","CC","CCC","CD","D","DC","DCC","DCCC","CM" },
- *roman_I3[] = { "","M","MM","MMM","MMMM" };
+ *const roman_I0[] = { "","I","II","III","IV","V","VI","VII","VIII","IX" },
+ *const roman_I1[] = { "","X","XX","XXX","XL","L","LX","LXX","LXXX","XC" },
+ *const roman_I2[] = { "","C","CC","CCC","CD","D","DC","DCC","DCCC","CM" },
+ *const roman_I3[] = { "","M","MM","MMM","MMMM" };
-void strtolower (char *s)
+static void strtolower (char *s)
{
for ( ; *s; s++)
*s = tolower (*s);
@@ -596,16 +564,21 @@ void numtostr (int num, char *buf, int buflen, ListStyleType listStyleType)
bool low = false;
int start_ch = 'A';
+ if (buflen <= 0)
+ return;
+
switch(listStyleType){
case LIST_STYLE_TYPE_LOWER_ALPHA:
+ case LIST_STYLE_TYPE_LOWER_LATIN:
start_ch = 'a';
case LIST_STYLE_TYPE_UPPER_ALPHA:
+ case LIST_STYLE_TYPE_UPPER_LATIN:
i0 = num - 1;
i1 = i0/26 - 1; i2 = i1/26 - 1;
if (i2 > 25) /* more than 26+26^2+26^3=18278 elements ? */
- sprintf(buf, "****.");
+ snprintf(buf, buflen, "****.");
else
- sprintf(buf, "%c%c%c.",
+ snprintf(buf, buflen, "%c%c%c.",
i2<0 ? ' ' : start_ch + i2%26,
i1<0 ? ' ' : start_ch + i1%26,
i0<0 ? ' ' : start_ch + i0%26);
@@ -617,18 +590,23 @@ void numtostr (int num, char *buf, int buflen, ListStyleType listStyleType)
i1 = i0/10; i2 = i1/10; i3 = i2/10;
i0 %= 10; i1 %= 10; i2 %= 10;
if (num < 0 || i3 > 4) /* more than 4999 elements ? */
- sprintf(buf, "****.");
+ snprintf(buf, buflen, "****.");
else
snprintf(buf, buflen, "%s%s%s%s.", roman_I3[i3], roman_I2[i2],
roman_I1[i1], roman_I0[i0]);
- if (low)
- strtolower(buf);
break;
case LIST_STYLE_TYPE_DECIMAL:
default:
- sprintf(buf, "%d.", num);
+ snprintf(buf, buflen, "%d.", num);
break;
}
+
+ // ensure termination
+ buf[buflen - 1] = '\0';
+
+ if (low)
+ strtolower(buf);
+
}
} // namespace style