diff options
-rw-r--r-- | dw/layout.cc | 38 | ||||
-rw-r--r-- | dw/layout.hh | 9 | ||||
-rw-r--r-- | dw/style.cc | 155 | ||||
-rw-r--r-- | dw/style.hh | 7 | ||||
-rw-r--r-- | test/dw_image_background.cc | 14 |
5 files changed, 154 insertions, 69 deletions
diff --git a/dw/layout.cc b/dw/layout.cc index 3f493d8a..61ff8a38 100644 --- a/dw/layout.cc +++ b/dw/layout.cc @@ -189,6 +189,7 @@ Layout::Layout (Platform *platform) DBG_OBJ_CREATE (this, "DwRenderLayout"); bgColor = NULL; + bgImage = NULL; cursor = style::CURSOR_DEFAULT; canvasWidth = canvasAscent = canvasDescent = 0; @@ -228,6 +229,8 @@ Layout::~Layout () platform->removeIdle (resizeIdleId); if (bgColor) bgColor->unref (); + if (bgImage) + bgImage->unref (); if (topLevel) { Widget *w = topLevel; topLevel = NULL; @@ -508,6 +511,23 @@ void Layout::draw (View *view, Rectangle *area) { Rectangle widgetArea, intersection, widgetDrawArea; + // First of all, draw background image. (Unlike background *color*, + // this is not a feature of the views.) + if (bgImage != NULL && bgImage->getImgbuf() != NULL) + style::drawBackgroundImage (view, bgImage, bgRepeat, bgAttachment, + bgPositionX, bgPositionY, + area->x, area->y, area->width, + area->height, 0, 0, + // Reference area: maximum of canvas size and + // viewport size. + misc::max (viewportWidth + - (canvasHeightGreater ? + vScrollbarThickness : 0), + canvasWidth), + misc::max (viewportHeight + - hScrollbarThickness, + canvasAscent + canvasDescent)); + if (scrollIdleId != -1) { /* scroll is pending, defer draw until after scrollIdle() */ drawAfterScrollReq = true; @@ -650,6 +670,24 @@ void Layout::setBgColor (style::Color *color) view->setBgColor (bgColor); } +void Layout::setBgImage (style::StyleImage *bgImage, + style::BackgroundRepeat bgRepeat, + style::BackgroundAttachment bgAttachment, + style::Length bgPositionX, style::Length bgPositionY) +{ + bgImage->ref (); + + if (this->bgImage) + this->bgImage->unref (); + + this->bgImage = bgImage; + this->bgRepeat = bgRepeat; + this->bgAttachment = bgAttachment; + this->bgPositionX = bgPositionX; + this->bgPositionY = bgPositionY; +} + + void Layout::resizeIdle () { //static int calls = 0; diff --git a/dw/layout.hh b/dw/layout.hh index 51d764a4..9687a2da 100644 --- a/dw/layout.hh +++ b/dw/layout.hh @@ -135,6 +135,11 @@ private: /* The state, which must be projected into the view. */ style::Color *bgColor; + style::StyleImage *bgImage; + style::BackgroundRepeat bgRepeat; + style::BackgroundAttachment bgAttachment; + style::Length bgPositionX, bgPositionY; + style::Cursor cursor; int canvasWidth, canvasAscent, canvasDescent; @@ -386,6 +391,10 @@ public: inline void resetSearch () { findtextState.resetSearch (); } void setBgColor (style::Color *color); + void setBgImage (style::StyleImage *bgImage, + style::BackgroundRepeat bgRepeat, + style::BackgroundAttachment bgAttachment, + style::Length bgPositionX, style::Length bgPositionY); inline style::Color* getBgColor () { return bgColor; } }; diff --git a/dw/style.cc b/dw/style.cc index e443ab61..cc885a59 100644 --- a/dw/style.cc +++ b/dw/style.cc @@ -34,11 +34,17 @@ namespace dw { namespace core { namespace style { -static void calcBackgroundRelatedValues (Style *style, int xDraw, int yDraw, - int widthDraw, int heightDraw, - int xRef, int yRef, int widthRef, - int heightRef, bool *repeatX, - bool *repeatY, int *origX, int *origY, +static void calcBackgroundRelatedValues (StyleImage *backgroundImage, + BackgroundRepeat backgroundRepeat, + BackgroundAttachment + backgroundAttachment, + Length backgroundPositionX, + Length backgroundPositionY, + int xDraw, int yDraw, int widthDraw, + int heightDraw, int xRef, int yRef, + int widthRef, int heightRef, + bool *repeatX, bool *repeatY, + int *origX, int *origY, int *tileX1, int *tileX2, int *tileY1, int *tileY2, bool *doDraw); @@ -528,7 +534,12 @@ void StyleImage::ExternalImgRenderer::drawRow (int row) bool repeatX, repeatY, doDraw; int origX, origY, tileX1, tileX2, tileY1, tileY2; - calcBackgroundRelatedValues (style, xDraw, yDraw, widthDraw, heightDraw, + calcBackgroundRelatedValues (style->backgroundImage, + style->backgroundRepeat, + style->backgroundAttachment, + style->backgroundPositionX, + style->backgroundPositionY, + xDraw, yDraw, widthDraw, heightDraw, xRef, yRef, widthRef, heightRef, &repeatX, &repeatY, &origX, &origY, &tileX1, &tileX2, &tileY1, &tileY2, &doDraw); @@ -1050,73 +1061,93 @@ void drawBackground (View *view, Layout *layout, Rectangle *area, true, intersection.x, intersection.y, intersection.width, intersection.height); - if (bgImage) { - Imgbuf *imgbuf = style->backgroundImage->getImgbuf(); - int imgWidth = imgbuf->getRootWidth (); - int imgHeight = imgbuf->getRootHeight (); - - bool repeatX, repeatY, doDraw; - int origX, origY, tileX1, tileX2, tileY1, tileY2; - - calcBackgroundRelatedValues (style, intersection.x, intersection.y, - intersection.width, - intersection.height, xRef, yRef, - widthRef, heightRef, &repeatX, - &repeatY, &origX, &origY, &tileX1, - &tileX2, &tileY1, &tileY2, &doDraw); - - //printf ("tileX1 = %d, tileX2 = %d, tileY1 = %d, tileY2 = %d\n", - // tileX1, tileX2, tileY1, tileY2); - - if (doDraw) - for (int tileX = tileX1; tileX <= tileX2; tileX++) - for (int tileY = tileY1; tileY <= tileY2; tileY++) { - int x = origX + tileX * imgWidth; - int x1 = misc::max (x, intersection.x); - int x2 = misc::min (x + imgWidth, - intersection.x + intersection.width); - int y = origY + tileY * imgHeight; - int y1 = misc::max (y, intersection.y); - int y2 = misc::min (y + imgHeight, - intersection.y + intersection.height); - - //printf (" (%d, %d) => (%d, %d - %d) / (%d, %d - %d)\n", - // tileX, tileY, x, x1, x2, y, y1, y2); - //printf (" => drawImage (%d, %d, %d, %d, %d, %d)\n", - // x, y, x - x, y1 - y, x2 - x1, y2 - y1); - - view->drawImage (imgbuf, x, y, x1 - x, y1 - y, - x2 - x1, y2 - y1); - } - } + if (bgImage) + drawBackgroundImage (view, style->backgroundImage, + style->backgroundRepeat, + style->backgroundAttachment, + style->backgroundPositionX, + style->backgroundPositionY, + intersection.x, intersection.y, + intersection.width, intersection.height, + xRef, yRef, widthRef, heightRef); + } } } -void calcBackgroundRelatedValues (Style *style, int xDraw, int yDraw, - int widthDraw, int heightDraw, int xRef, - int yRef, int widthRef, int heightRef, - bool *repeatX, bool *repeatY, int *origX, - int *origY, int *tileX1, int *tileX2, - int *tileY1, int *tileY2, bool *doDraw) +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) +{ + Imgbuf *imgbuf = backgroundImage->getImgbuf(); + int imgWidth = imgbuf->getRootWidth (); + int imgHeight = imgbuf->getRootHeight (); + + //printf ("drawBackrgoundImage (..., [img: %d, %d], ..., (%d, %d), %d x %d, " + // "(%d, %d), %d x %d)\n", imgWidth, imgHeight, x, y, width, height, + // xRef, yRef, widthRef, heightRef); + + bool repeatX, repeatY, doDraw; + int origX, origY, tileX1, tileX2, tileY1, tileY2; + + calcBackgroundRelatedValues (backgroundImage, backgroundRepeat, + backgroundAttachment, backgroundPositionX, + backgroundPositionY, x, y, width, height, + xRef, yRef, widthRef, heightRef, + &repeatX, &repeatY, &origX, &origY, + &tileX1, &tileX2, &tileY1, &tileY2, &doDraw); + + //printf ("tileX1 = %d, tileX2 = %d, tileY1 = %d, tileY2 = %d\n", + // tileX1, tileX2, tileY1, tileY2); + + if (doDraw) + for (int tileX = tileX1; tileX <= tileX2; tileX++) + for (int tileY = tileY1; tileY <= tileY2; tileY++) { + int xt = origX + tileX * imgWidth; + int x1 = misc::max (xt, x); + int x2 = misc::min (xt + imgWidth, x + width); + int yt = origY + tileY * imgHeight; + int y1 = misc::max (yt, y); + int y2 = misc::min (yt + imgHeight, y + height); + + view->drawImage (imgbuf, xt, yt, x1 - xt, y1 - yt, + x2 - x1, y2 - y1); + } +} + +void calcBackgroundRelatedValues (StyleImage *backgroundImage, + BackgroundRepeat backgroundRepeat, + BackgroundAttachment backgroundAttachment, + Length backgroundPositionX, + Length backgroundPositionY, + int xDraw, int yDraw, int widthDraw, + int heightDraw, int xRef, int yRef, + int widthRef, int heightRef, bool *repeatX, + bool *repeatY, int *origX, int *origY, + int *tileX1, int *tileX2, int *tileY1, + int *tileY2, bool *doDraw) { - Imgbuf *imgbuf = style->backgroundImage->getImgbuf(); + Imgbuf *imgbuf = backgroundImage->getImgbuf(); int imgWidth = imgbuf->getRootWidth (); int imgHeight = imgbuf->getRootHeight (); - *repeatX = style->backgroundRepeat == BACKGROUND_REPEAT || - style->backgroundRepeat == BACKGROUND_REPEAT_X; - *repeatY = style->backgroundRepeat == BACKGROUND_REPEAT || - style->backgroundRepeat == BACKGROUND_REPEAT_Y; + *repeatX = backgroundRepeat == BACKGROUND_REPEAT || + backgroundRepeat == BACKGROUND_REPEAT_X; + *repeatY = backgroundRepeat == BACKGROUND_REPEAT || + backgroundRepeat == BACKGROUND_REPEAT_Y; *origX = xRef + - (isPerLength (style->backgroundPositionX) ? - perLengthVal (style->backgroundPositionX) * (widthRef - imgWidth) : - absLengthVal (style->backgroundPositionX)); + (isPerLength (backgroundPositionX) ? + perLengthVal (backgroundPositionX) * (widthRef - imgWidth) : + absLengthVal (backgroundPositionX)); *origY = yRef + - (isPerLength (style->backgroundPositionY) ? - perLengthVal (style->backgroundPositionY) * (heightRef - imgHeight) : - absLengthVal (style->backgroundPositionY)); + (isPerLength (backgroundPositionY) ? + perLengthVal (backgroundPositionY) * (heightRef - imgHeight) : + absLengthVal (backgroundPositionY)); *tileX1 = xDraw < *origX ? - (*origX - xDraw + imgWidth - 1) / imgWidth : diff --git a/dw/style.hh b/dw/style.hh index 27bcf579..fbc726ef 100644 --- a/dw/style.hh +++ b/dw/style.hh @@ -794,6 +794,13 @@ 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, 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 diff --git a/test/dw_image_background.cc b/test/dw_image_background.cc index 3b692901..391d6fe1 100644 --- a/test/dw_image_background.cc +++ b/test/dw_image_background.cc @@ -115,6 +115,12 @@ int main(int argc, char **argv) FltkViewport *viewport = new FltkViewport (0, 0, 200, 300); layout->attachView (viewport); + image1 = StyleImage::create (); + image1->connectDeletion (&isdr); + layout->setBgImage (image1, BACKGROUND_REPEAT_Y, + BACKGROUND_ATTACHMENT_SCROLL, createPerLength (0.5), + createAbsLength (30)); + StyleAttrs styleAttrs; styleAttrs.initValues (); styleAttrs.margin.setVal (5); @@ -129,13 +135,7 @@ int main(int argc, char **argv) styleAttrs.font = style::Font::create (layout, &fontAttrs); styleAttrs.color = Color::create (layout, 0x000000); - styleAttrs.backgroundColor = Color::create (layout, 0xffffff); - - image1 = styleAttrs.backgroundImage = StyleImage::create (); - image1->connectDeletion (&isdr); - styleAttrs.backgroundRepeat = BACKGROUND_REPEAT_Y; - styleAttrs.backgroundPositionX = createPerLength (0.5); - styleAttrs.backgroundPositionY = createAbsLength (30); + //styleAttrs.backgroundColor = Color::create (layout, 0xffffff); Style *widgetStyle = Style::create (&styleAttrs); |