diff options
Diffstat (limited to 'dw/style.hh')
-rw-r--r-- | dw/style.hh | 907 |
1 files changed, 907 insertions, 0 deletions
diff --git a/dw/style.hh b/dw/style.hh new file mode 100644 index 0000000..230baa2 --- /dev/null +++ b/dw/style.hh @@ -0,0 +1,907 @@ +#ifndef __DW_STYLE_HH__ +#define __DW_STYLE_HH__ + +#include <stdint.h> + +#ifndef __INCLUDED_FROM_DW_CORE_HH__ +# error Do not include this file directly, use "core.hh" instead. +#endif + +#include "../lout/signal.hh" +#include "../lout/debug.hh" + +namespace dw { +namespace core { + +/** + * \brief Anything related to Dillo %Widget styles is defined here. + * + * <h3>Overview</h3> + * + * dw::core::style::Style provides some resources and attributes for + * drawing widgets, as well as for parts of a widget (e.g., dw::Textblock + * uses styles for its words). Creating a style is done by filling a + * dw::core::style::StyleAttrs with the attributes and calling + * dw::core::style::Style::create: + * + * \code + * dw::core::style::Style styleAttrs; + * dw::core::style::Style *style; + * dw::core::Layout *layout; + * + * // ... + * + * styleAttrs.foo = bar; + * // etc. + * style = dw::core::style::Style::create (&styleAttrs, layout); + * // do something with style + * \endcode + * + * After this, the attributes of a dw::core::style::Style should not be + * changed anymore, since styles are often shared between different + * widgets etc. (see below). Most times, you simply copy the attributes + * of another style (possible, since dw::core::style::Style is a sub + * class of dw::core::style::StyleAttrs), modify them and create a new + * style: + * + * \code + * styleAttrs = *anotherStyle; + * styleAttrs.foo = baz; + * style = dw::core::style::Style::create (&styleAttrs, layout); + * \endcode + * + * The dw::core::style::Font structure can be created by + * dw::core::style::Font::create, in a similar, with + * dw::core::style::FontAttrs, and colors by + * dw::core::style::Color::create, passing 0xrrggbb as an + * argument. Furthermore, there is dw::core::style::Tooltip, created by + * dw::core::style::Tooltip::create. + * + * Notice that fonts, colors and tooltips are only intended to be used in + * conjunction with dw::core::style::Style. + * + * + * <h3>Naming</h3> + * + * dw::core::style::Style will become important for CSS, each CSS + * attribute, which is supported by dillo, will refer to an attribute in + * dw::core::style::Style. For this reason, the attributes in + * dw::core::style::Style get the names from the CSS attributes, with + * "camelCase" instead of hyphens (e.g. "background-color" becomes + * "backgroundColor"). + * + * However, dw::core::style::Style will be extended by some more + * attributes, which are not defined by CSS. To distinguish them, they + * get the prefix "x_", e.g. dw::core::style::Style::x_link. + * + * + * <h3>Lengths and Percentages</h3> + * + * dw::core::style::Length is a simple data type for lengths and + * percentages: + * + * <ul> + * <li> A length refers to an absolute measurement. It is used to + * represent the HTML type %Pixels; and the CSS type \<length\>. + * + * For CSS lengths, there are two units: (i) pixels and absolute + * units, which have to be converted to pixels (a pixel is, unlike + * in the CSS specification, treated as absolute unit), and (ii) the + * relative units "em" and "ex" (see below). + * + * <li> A percentage refers to a value relative to another value. It is + * used for the HTML type %Length; (except %Pixels;), and the CSS + * type \<percentage\>. + * + * <li> A relative length can be used in lists of HTML MultiLengths. + * </ul> + * + * Since many values in CSS may be either lengths or percentages, a + * single type is very useful. + * + * <h4>Useful Functions</h4> + * + * Creating lengths: + * + * <ul> + * <li> dw::core::style::createAbsLength + * <li> dw::core::style::createPerLength + * <li> dw::core::style::createRelLength + * </ul> + * + * Examine lengths: + * + * <ul> + * <li> dw::core::style::isAbsLength + * <li> dw::core::style::isPerLength + * <li> dw::core::style::isRelLength + * <li> dw::core::style::absLengthVal + * <li> dw::core::style::perLengthVal + * <li> dw::core::style::relLengthVal + * </ul> + * + * + * <h3>Boxes</h3> + * + * <h4>The CSS %Box Model</h4> + * + * For borders, margins etc., the box model defined by CSS2 is + * used. dw::core::style::Style contains some members defining these + * attributes. A dw::core::Widget must use these values for any + * calculation of sizes. There are some helper functions (see + * dw/style.hh). A dw::core::style::Style box looks quite similar to a + * CSS box: + * + * \image html dw-style-box-model.png + * + * <h4>Background colors</h4> + * + * The background color is stored in + * dw::core::style::Style::backgroundColor, which may be NULL (the + * background color of the parent widget is shining through). + * + * For toplevel widgets, this color is set as the background color of the + * views (dw::core::View::setBgColor), for other widgets, a filled + * rectangle is drawn, covering the content and padding. (This is + * compliant with CSS2, the background color of the toplevel element + * covers the whole canvas.) + * + * <h4>Drawing</h4> + * + * The following methods may be useful: + * + * <ul> + * <li> dw::core::Widget::drawWidgetBox for drawing the box of a widget + * (typically at the beginning of the implementation of + * dw::core::Widget::draw), and + * + * <li> dw::core::Widget::drawBox, for drawing parts of a widget (e.g. + * dw::Textblock::Word, which has its own dw::Textblock::Word::style). + * </ul> + * + * + * <h3>Notes on Memory Management</h3> + * + * Memory management is done by reference counting, + * dw::core::style::Style::create returns a pointer to + * dw::core::style::Style with an increased reference counter, so you + * should care about calling dw::core::style::Style::unref if it is not + * used anymore. You do \em not need to care about the reference counters + * of fonts and styles. + * + * In detail: + * + * <ul> + * <li> dw::core::style::Style::ref is called in + * + * <ul> + * <li> dw::core::Widget::setStyle to assign a style to a widget, + * <li> dw::Textblock::addText, dw::Textblock::addWidget, + * dw::Textblock::addAnchor, dw::Textblock::addSpace, + * dw::Textblock::addParbreak and dw::Textblock::addLinebreak, + * to assign a style to a dw::Textblock::Word, and + * <li> by the HTML parser, when pushing an element on the stack. + * </ul> + * + * <li> dw::core::style::Style::unref is called in + * + * <ul> + * <li> dw::core::Widget::~Widget, dw::Textblock::~Textblock, by the + * HTML parser, when popping an element fom the stack, and + * <li> dw::core::Widget::setStyle, dw::Textblock::addText etc., + * these methods overwrite an existing style. + * </ul> + * </ul> + */ +namespace style { + +enum Cursor { + CURSOR_CROSSHAIR, + CURSOR_DEFAULT, + CURSOR_POINTER, + CURSOR_MOVE, + CURSOR_E_RESIZE, + CURSOR_NE_RESIZE, + CURSOR_NW_RESIZE, + CURSOR_N_RESIZE, + CURSOR_SE_RESIZE, + CURSOR_SW_RESIZE, + CURSOR_S_RESIZE, + CURSOR_W_RESIZE, + CURSOR_TEXT, + CURSOR_WAIT, + CURSOR_HELP +}; + +enum BorderCollapse { + BORDER_MODEL_SEPARATE, + BORDER_MODEL_COLLAPSE +}; + +enum BorderStyle { + BORDER_NONE, + BORDER_HIDDEN, + BORDER_DOTTED, + BORDER_DASHED, + BORDER_SOLID, + BORDER_DOUBLE, + BORDER_GROOVE, + BORDER_RIDGE, + BORDER_INSET, + BORDER_OUTSET +}; + +enum BackgroundRepeat { + BACKGROUND_REPEAT, + BACKGROUND_REPEAT_X, + BACKGROUND_REPEAT_Y, + BACKGROUND_NO_REPEAT +}; + +enum BackgroundAttachment { + BACKGROUND_ATTACHMENT_SCROLL, + BACKGROUND_ATTACHMENT_FIXED +}; + +enum TextAlignType { + TEXT_ALIGN_LEFT, + TEXT_ALIGN_RIGHT, + TEXT_ALIGN_CENTER, + TEXT_ALIGN_JUSTIFY, + TEXT_ALIGN_STRING +}; + +enum VAlignType { + VALIGN_TOP, + VALIGN_BOTTOM, + VALIGN_MIDDLE, + VALIGN_BASELINE, + VALIGN_SUB, + VALIGN_SUPER, + VALIGN_TEXT_TOP, + VALIGN_TEXT_BOTTOM, +}; + +enum TextTransform { + TEXT_TRANSFORM_NONE, + TEXT_TRANSFORM_CAPITALIZE, + TEXT_TRANSFORM_UPPERCASE, + TEXT_TRANSFORM_LOWERCASE, +}; + +/** + * \todo Incomplete. Has to be completed for a CSS implementation. + */ +enum DisplayType { + DISPLAY_BLOCK, + DISPLAY_INLINE, + DISPLAY_INLINE_BLOCK, + DISPLAY_LIST_ITEM, + DISPLAY_NONE, + DISPLAY_TABLE, + DISPLAY_TABLE_ROW_GROUP, + DISPLAY_TABLE_HEADER_GROUP, + DISPLAY_TABLE_FOOTER_GROUP, + DISPLAY_TABLE_ROW, + DISPLAY_TABLE_CELL +}; + +enum LineType { + LINE_NORMAL, + LINE_DOTTED, + LINE_DASHED +}; + +enum ListStylePosition { + LIST_STYLE_POSITION_INSIDE, + LIST_STYLE_POSITION_OUTSIDE +}; +enum ListStyleType { + LIST_STYLE_TYPE_DISC, + LIST_STYLE_TYPE_CIRCLE, + LIST_STYLE_TYPE_SQUARE, + LIST_STYLE_TYPE_DECIMAL, + LIST_STYLE_TYPE_DECIMAL_LEADING_ZERO, + LIST_STYLE_TYPE_LOWER_ROMAN, + LIST_STYLE_TYPE_UPPER_ROMAN, + LIST_STYLE_TYPE_LOWER_GREEK, + LIST_STYLE_TYPE_LOWER_ALPHA, + LIST_STYLE_TYPE_LOWER_LATIN, + LIST_STYLE_TYPE_UPPER_ALPHA, + LIST_STYLE_TYPE_UPPER_LATIN, + LIST_STYLE_TYPE_HEBREW, + LIST_STYLE_TYPE_ARMENIAN, + LIST_STYLE_TYPE_GEORGIAN, + LIST_STYLE_TYPE_CJK_IDEOGRAPHIC, + LIST_STYLE_TYPE_HIRAGANA, + LIST_STYLE_TYPE_KATAKANA, + LIST_STYLE_TYPE_HIRAGANA_IROHA, + LIST_STYLE_TYPE_KATAKANA_IROHA, + LIST_STYLE_TYPE_NONE +}; + +enum FontStyle { + FONT_STYLE_NORMAL, + FONT_STYLE_ITALIC, + FONT_STYLE_OBLIQUE +}; + +enum FontVariant { + FONT_VARIANT_NORMAL, + FONT_VARIANT_SMALL_CAPS +}; + +enum Overflow { + OVERFLOW_VISIBLE, + OVERFLOW_HIDDEN, + OVERFLOW_SCROLL, + OVERFLOW_AUTO +}; + +enum Position { + POSITION_STATIC, + POSITION_RELATIVE, + POSITION_ABSOLUTE, + POSITION_FIXED, +}; + +enum TextDecoration { + TEXT_DECORATION_NONE = 0, + TEXT_DECORATION_UNDERLINE = 1 << 0, + TEXT_DECORATION_OVERLINE = 1 << 1, + TEXT_DECORATION_LINE_THROUGH = 1 << 2, + TEXT_DECORATION_BLINK = 1 << 3 +}; + +enum WhiteSpace { + WHITE_SPACE_NORMAL, + WHITE_SPACE_PRE, + WHITE_SPACE_NOWRAP, + WHITE_SPACE_PRE_WRAP, + WHITE_SPACE_PRE_LINE, +}; + +enum FloatType { + FLOAT_NONE, + FLOAT_LEFT, + FLOAT_RIGHT +}; + +enum ClearType { + CLEAR_LEFT, + CLEAR_RIGHT, + CLEAR_BOTH, + CLEAR_NONE +}; + +/** + * \brief Type for representing all lengths within dw::core::style. + * + * Lengths are int's. Absolute lengths are represented in the following way: + * + * \image html dw-style-length-absolute.png + * + * Percentages: + * + * \image html dw-style-length-percentage.png + * + * Relative lengths (only used in HTML): + * + * \image html dw-style-length-relative.png + * + * This is an implementation detail, use one of the following functions: + * + * Creating lengths: + * + * <ul> + * <li> dw::core::style::createAbsLength + * <li> dw::core::style::createPerLength + * <li> dw::core::style::createRelLength + * </ul> + * + * Examine lengths: + * + * <ul> + * <li> dw::core::style::isAbsLength + * <li> dw::core::style::isPerLength + * <li> dw::core::style::isRelLength + * <li> dw::core::style::absLengthVal + * <li> dw::core::style::perLengthVal + * <li> dw::core::style::relLengthVal + * </ul> + * + * "auto" lengths are represented as dw::core::style::LENGTH_AUTO. + */ +typedef int Length; + +/** \brief Returns a length of \em n pixels. */ +inline Length createAbsLength(int n) { return (n << 2) | 1; } + +/** \brief Returns a percentage, \em v is relative to 1, not to 100. */ +inline Length createPerLength(double v) { + return ((int)(v * (1 << 18)) & ~3) | 2; } + +/** \brief Returns a relative length. */ +inline Length createRelLength(double v) { + return ((int)(v * (1 << 18)) & ~3) | 3; } + +/** \brief Returns true if \em l is an absolute length. */ +inline bool isAbsLength(Length l) { return (l & 3) == 1; } + +/** \brief Returns true if \em l is a percentage. */ +inline bool isPerLength(Length l) { return (l & 3) == 2; } + +/** \brief Returns true if \em l is a relative length. */ +inline bool isRelLength(Length l) { return (l & 3) == 3; } + +/** \brief Returns the value of a length in pixels, as an integer. */ +inline int absLengthVal(Length l) { return l >> 2; } + +/** \brief Returns the value of a percentage, relative to 1, as a double. + * + * When possible, do not use this function directly; it may be removed + * soon. Instead, use multiplyWithPerLength or multiplyWithPerLengthRounded. + */ +inline double perLengthVal_useThisOnlyForDebugging(Length l) +{ return (double)(l & ~3) / (1 << 18); } + +/** \brief Returns the value of a relative length, as a float. + * + * When possible, do not use this function directly; it may be removed + * soon. + */ +inline double relLengthVal(Length l) { return (double)(l & ~3) / (1 << 18); } + +/** + * \brief Multiply an int with a percentage length, returning int. + * + * Use this instead of perLengthVal, when possible. + */ +inline int multiplyWithPerLength(int x, Length l) { + return x * perLengthVal_useThisOnlyForDebugging (l); +} + +/** + * \brief Like multiplyWithPerLength, but rounds to nearest integer + * instead of down. + * + * (This function exists for backward compatibility.) + */ +inline int multiplyWithPerLengthRounded(int x, Length l) { + return lout::misc::roundInt (x * perLengthVal_useThisOnlyForDebugging (l)); +} + +inline int multiplyWithRelLength(int x, Length l) { + return x * relLengthVal(l); +} + + +enum { + /** \brief Represents "auto" lengths. */ + LENGTH_AUTO = 0 +}; + +/** + * \brief Represents a dimension box according to the CSS box model. + * + * Used for dw::core::style::Style::margin, + * dw::core::style::Style::borderWidth, and dw::core::style::Style::padding. + */ +class Box +{ +public: + /* in future also percentages */ + int top, right, bottom, left; + + inline void setVal(int val) { top = right = bottom = left = val; } + inline bool equals (Box *other) { + return top == other->top && + right == other->right && + bottom == other->bottom && + left == other->left; + } + inline int hashValue () { + return top + right + bottom + left; + } +}; + +class Tooltip; +class Font; +class Color; +class StyleImage; + +/** + * \sa dw::core::style + */ +class StyleAttrs : public lout::object::Object +{ +public: + Font *font; + int textDecoration; /* No TextDecoration because of problems converting + * TextDecoration <-> int */ + Color *color, *backgroundColor; + StyleImage *backgroundImage; + BackgroundRepeat backgroundRepeat; + BackgroundAttachment backgroundAttachment; + Length backgroundPositionX; // "left" defined by "0%" etc. (see CSS spec) + Length backgroundPositionY; // "top" defined by "0%" etc. (see CSS spec) + + TextAlignType textAlign; + VAlignType valign; + char textAlignChar; /* In future, strings will be supported. */ + TextTransform textTransform; + + FloatType vloat; /* "float" is a keyword. */ + ClearType clear; + + Overflow overflow; + + Position position; + Length top, bottom, left, right; + + int hBorderSpacing, vBorderSpacing, wordSpacing; + Length width, height, lineHeight, textIndent; + Length minWidth, maxWidth, minHeight, maxHeight; + + Box margin, borderWidth, padding; + BorderCollapse borderCollapse; + struct { Color *top, *right, *bottom, *left; } borderColor; + struct { BorderStyle top, right, bottom, left; } borderStyle; + + DisplayType display; + WhiteSpace whiteSpace; + ListStylePosition listStylePosition; + ListStyleType listStyleType; + Cursor cursor; + + int x_link; + int x_img; + Tooltip *x_tooltip; + char x_lang[2]; /* Either x_lang[0] == x_lang[1] == 0 (no language + set), or x_lang contains the RFC 1766 country + code in lower case letters. (Only two letters + allowed, currently.) */ + + void initValues (); + void resetValues (); + + bool sizeDiffs (StyleAttrs *otherStyleAttrs); + + inline void setBorderColor(Color *val) { + borderColor.top = borderColor.right = borderColor.bottom + = borderColor.left = val; } + inline void setBorderStyle(BorderStyle val) { + borderStyle.top = borderStyle.right = borderStyle.bottom + = borderStyle.left = val; } + + inline int boxOffsetX () + { return margin.left + borderWidth.left + padding.left; } + inline int boxRestWidth () + { return margin.right + borderWidth.right + padding.right; } + inline int boxDiffWidth () { return boxOffsetX () + boxRestWidth (); } + inline int boxOffsetY () + { return margin.top + borderWidth.top + padding.top; } + inline int boxRestHeight () + { return margin.bottom + borderWidth.bottom + padding.bottom; } + inline int boxDiffHeight () { return boxOffsetY () + boxRestHeight (); } + + inline bool hasBackground () + { return backgroundColor != NULL || backgroundImage != NULL; } + + bool equals (lout::object::Object *other); + int hashValue (); +}; + + +/** + * \sa dw::core::style + */ +class Style: public StyleAttrs +{ +private: + static int totalRef; + int refCount; + static lout::container::typed::HashTable <StyleAttrs, Style> *styleTable; + + Style (StyleAttrs *attrs); + +protected: + ~Style(); + + void copyAttrs (StyleAttrs *attrs); + +public: + inline static Style *create (StyleAttrs *attrs) + { + Style *style = styleTable->get (attrs); + if (style) { + style->ref (); + } else { + style = new Style (attrs); + styleTable->put(style, style); + } + return style; + } + + inline void ref () { refCount++; } + inline void unref () { if (--refCount == 0) delete this; } +}; + + +/** + * \sa dw::core::style + */ +class TooltipAttrs: public lout::object::String +{ +public: + TooltipAttrs(const char *text): lout::object::String(text) { } +}; + +/** + * \sa dw::core::style + */ +class Tooltip: public TooltipAttrs +{ +private: + int refCount; + +protected: + Tooltip (const char *text): TooltipAttrs(text) { refCount = 0; } + +public: + static Tooltip *create (dw::core::Layout *layout, const char *text); + inline void ref () { refCount++; } + inline void unref () + { if (--refCount == 0) delete this; } + + inline virtual void onEnter () { } + inline virtual void onLeave () { } + inline virtual void onMotion () { } +}; + + +/** + * \sa dw::core::style + */ +class FontAttrs: public lout::object::Object +{ +public: + const char *name; + int size; + int weight; + int letterSpacing; + FontVariant fontVariant; + FontStyle style; + + bool equals(lout::object::Object *other); + int hashValue(); +}; + + +/** + * \sa dw::core::style + */ +class Font: public FontAttrs +{ +private: + int refCount; + + static Font *create0 (Layout *layout, FontAttrs *attrs, bool tryEverything); + +protected: + inline Font () { + DBG_OBJ_CREATE ("dw::core::style::Font"); + refCount = 0; + } + virtual ~Font (); + + void copyAttrs (FontAttrs *attrs); + +public: + int ascent, descent; + int spaceWidth; + int xHeight; + + static Font *create (Layout *layout, FontAttrs *attrs); + static bool exists (Layout *layout, const char *name); + + inline void ref () { refCount++; } + inline void unref () { if (--refCount == 0) delete this; } +}; + + +/** + * \sa dw::core::style + */ +class ColorAttrs: public lout::object::Object +{ +protected: + int color; + +public: + inline ColorAttrs(int color) + { + this->color = color; + } + + inline int getColor () { return color; } + + bool equals(lout::object::Object *other); + int hashValue(); +}; + + +/** + * \sa dw::core::style + */ +class Color: public ColorAttrs +{ +private: + int refCount; + + void remove(dw::core::Layout *layout); + int shadeColor (int color, int d); + +protected: + inline Color (int color): ColorAttrs (color) { + DBG_OBJ_CREATE ("dw::core::style::Color"); + refCount = 0; + } + virtual ~Color (); + +public: + enum Shading { SHADING_NORMAL, SHADING_INVERSE, SHADING_DARK, SHADING_LIGHT, + SHADING_NUM }; + +protected: + int shadeColor (int color, Shading shading); + +public: + static Color *create (Layout *layout, int color); + + inline void ref () { refCount++; } + inline void unref () + { if (--refCount == 0) delete this; } +}; + + +class StyleImage: public lout::signal::ObservedObject +{ +private: + class StyleImgRenderer: public ImgRenderer + { + private: + StyleImage *image; + + public: + inline StyleImgRenderer (StyleImage *image) { this->image = image; } + + void setBuffer (core::Imgbuf *buffer, bool resize); + void drawRow (int row); + void finish (); + void fatal (); + }; + + int refCount, tilesX, tilesY; + Imgbuf *imgbufSrc, *imgbufTiled; + ImgRendererDist *imgRendererDist; + StyleImgRenderer *styleImgRenderer; + + StyleImage (); + ~StyleImage (); + +public: + /** + * \brief Useful (but not mandatory) base class for updates of + * areas with background images. + */ + class ExternalImgRenderer: public ImgRenderer + { + public: + void setBuffer (core::Imgbuf *buffer, bool resize); + void drawRow (int row); + void finish (); + void fatal (); + + /** + * \brief If this method returns false, nothing is done at all. + */ + virtual bool readyToDraw () = 0; + + /** + * \brief Return the area covered by the background image. + */ + virtual void getBgArea (int *x, int *y, int *width, int *height) = 0; + + /** + * \brief Return the "reference area". + * + * See comment of "drawBackground". + */ + virtual void getRefArea (int *xRef, int *yRef, int *widthRef, + int *heightRef) = 0; + + virtual StyleImage *getBackgroundImage () = 0; + virtual BackgroundRepeat getBackgroundRepeat () = 0; + virtual BackgroundAttachment getBackgroundAttachment () = 0; + virtual Length getBackgroundPositionX () = 0; + virtual Length getBackgroundPositionY () = 0; + + /** + * \brief Draw (or queue for drawing) an area, which is given in + * canvas coordinates. + */ + virtual void draw (int x, int y, int width, int height) = 0; + }; + + /** + * \brief Suitable for widgets and parts of widgets. + */ + class ExternalWidgetImgRenderer: public ExternalImgRenderer + { + public: + void getPaddingArea (int *x, int *y, int *width, int *height); + + StyleImage *getBackgroundImage (); + BackgroundRepeat getBackgroundRepeat (); + BackgroundAttachment getBackgroundAttachment (); + Length getBackgroundPositionX (); + Length getBackgroundPositionY (); + + /** + * \brief Return the style this background image is part of. + */ + virtual Style *getStyle () = 0; + }; + + static StyleImage *create () { return new StyleImage (); } + + inline void ref () { refCount++; } + inline void unref () + { if (--refCount == 0) delete this; } + + inline Imgbuf *getImgbufSrc () { return imgbufSrc; } + inline Imgbuf *getImgbufTiled (bool repeatX, bool repeatY) + { return (imgbufTiled && repeatX && repeatY) ? imgbufTiled : imgbufSrc; } + inline int getTilesX (bool repeatX, bool repeatY) + { return (imgbufTiled && repeatX && repeatY) ? tilesX : 1; } + inline int getTilesY (bool repeatX, bool repeatY) + { return (imgbufTiled && repeatX && repeatY) ? tilesY : 1; } + inline ImgRenderer *getMainImgRenderer () { return imgRendererDist; } + + /** + * \brief Add an additional ImgRenderer, especially used for + * drawing. + */ + inline void putExternalImgRenderer (ImgRenderer *ir) + { imgRendererDist->put (ir); } + + /** + * \brief Remove a previously added additional ImgRenderer. + */ + inline void removeExternalImgRenderer (ImgRenderer *ir) + { imgRendererDist->remove (ir); } +}; + +void drawBorder (View *view, Layout *layout, Rectangle *area, + int x, int y, int width, int height, + Style *style, bool inverse); +void drawBackground (View *view, Layout *layout, Rectangle *area, + int x, int y, int width, int height, + int xRef, int yRef, int widthRef, int heightRef, + Style *style, Color *bgColor, bool inverse, bool atTop); +void drawBackgroundImage (View *view, StyleImage *backgroundImage, + BackgroundRepeat backgroundRepeat, + BackgroundAttachment backgroundAttachment, + Length backgroundPositionX, + Length backgroundPositionY, + int x, int y, int width, int height, + int xRef, int yRef, int widthRef, int heightRef); +void numtostr (int num, char *buf, int buflen, ListStyleType listStyleType); + +} // namespace style +} // namespace core +} // namespace dw + +#endif // __DW_STYLE_HH__ + |