diff options
author | Sebastian Geerken <devnull@localhost> | 2013-10-22 10:33:03 +0200 |
---|---|---|
committer | Sebastian Geerken <devnull@localhost> | 2013-10-22 10:33:03 +0200 |
commit | 10934cb7dbb3eeaa30a9041228cf26c1c790bf5d (patch) | |
tree | b11e3a90642ef171963f0b9e9e60f06183b5a455 | |
parent | 385e55080f609bd86dc6d61113810773761e0b09 (diff) |
Extended ImgRenderer; new option (in the code) for drawing background images at once.
-rw-r--r-- | doc/dw-images-and-backgrounds.doc | 25 | ||||
-rw-r--r-- | dw/image.cc | 10 | ||||
-rw-r--r-- | dw/image.hh | 3 | ||||
-rw-r--r-- | dw/imgrenderer.cc | 19 | ||||
-rw-r--r-- | dw/imgrenderer.hh | 17 | ||||
-rw-r--r-- | dw/style.cc | 111 | ||||
-rw-r--r-- | dw/style.hh | 4 | ||||
-rw-r--r-- | src/dicache.c | 5 | ||||
-rw-r--r-- | src/image.cc | 10 | ||||
-rw-r--r-- | src/image.hh | 1 |
10 files changed, 154 insertions, 51 deletions
diff --git a/doc/dw-images-and-backgrounds.doc b/doc/dw-images-and-backgrounds.doc index e2a75981..bf1eda27 100644 --- a/doc/dw-images-and-backgrounds.doc +++ b/doc/dw-images-and-backgrounds.doc @@ -40,13 +40,10 @@ similar; only the implementation of dw::core::ImgRenderer differs. At this time, dw::core::ImgRenderer has got two methods (see more documentation there): -- dw::core::ImgRenderer::setBuffer and -- dw::core::ImgRenderer::drawRow. - -Possible extensions: - -- ''finished'': when all image data has been retrieved; -- ''fatal'': when there are problems with the retrieval of image data. +- dw::core::ImgRenderer::setBuffer, +- dw::core::ImgRenderer::drawRow, +- dw::core::ImgRenderer::finish, and +- dw::core::ImgRenderer::fatal. Images @@ -211,9 +208,17 @@ dw::core::View::drawImage, which may become slow. Solution: Create a new image buffer, which contains several copies of the original image. **Drawing background images row by row** may become slow. As an -alternative, the *finished* method (proposed above) in -dw::core::ImgRenderer could be used. However, drawing row by row could -become an option. +alternative, dw::core::ImgRenderer::finish could be used. However, +drawing row by row could become an option. **Update:** There is now +dw::core::style::drawBackgroundLineByLine, which can be changed in the +code. + +(For image widgets, this could also become an option: in contexts, +when image data is retrieved in a very fast way.) + +**Calls to dw::core::ImgRenderer::fatal** are incomplete. As an +example, it is not called, when connecting to a server fails. (And so, +as far as I see, no cache client is started.) Low Priority diff --git a/dw/image.cc b/dw/image.cc index 1cb9ce39..acb2779e 100644 --- a/dw/image.cc +++ b/dw/image.cc @@ -450,6 +450,16 @@ void Image::drawRow (int row) area.width, area.height); } +void Image::finish () +{ + // Nothing to do; images are always drawn line by line. +} + +void Image::fatal () +{ + // Could display an error. +} + /** * \brief Sets image as server side image map. diff --git a/dw/image.hh b/dw/image.hh index 7ac05c20..a712936e 100644 --- a/dw/image.hh +++ b/dw/image.hh @@ -157,6 +157,9 @@ public: void drawRow (int row); + void finish (); + void fatal (); + void setIsMap (); void setUseMap (ImageMapsList *list, Object *key); diff --git a/dw/imgrenderer.cc b/dw/imgrenderer.cc index c5e6ea07..285a8dcd 100644 --- a/dw/imgrenderer.cc +++ b/dw/imgrenderer.cc @@ -25,5 +25,24 @@ void ImgRendererDist::drawRow (int row) } +void ImgRendererDist::finish () +{ + for (typed::Iterator <TypedPointer <ImgRenderer> > it = + children->iterator (); it.hasNext (); ) { + TypedPointer <ImgRenderer> *tp = it.getNext (); + tp->getTypedValue()->finish (); + } +} + +void ImgRendererDist::fatal () +{ + for (typed::Iterator <TypedPointer <ImgRenderer> > it = + children->iterator (); it.hasNext (); ) { + TypedPointer <ImgRenderer> *tp = it.getNext (); + tp->getTypedValue()->fatal (); + } +} + + } // namespace core } // namespace dw diff --git a/dw/imgrenderer.hh b/dw/imgrenderer.hh index e254ae66..325a1998 100644 --- a/dw/imgrenderer.hh +++ b/dw/imgrenderer.hh @@ -32,6 +32,21 @@ public: * The implementation will typically queue the respective area for drawing. */ virtual void drawRow (int row) = 0; + + /** + * \brief Called, when all image data has been retrieved. + * + * The implementation may use this instead of "drawRow" for drawing, to + * limit the number of draws. + */ + virtual void finish () = 0; + + /** + * \brief Called, when there are problems with the retrieval of image data. + * + * The implementation may use this to indicate an error. + */ + virtual void fatal () = 0; }; /** @@ -54,6 +69,8 @@ public: void setBuffer (core::Imgbuf *buffer, bool resize); void drawRow (int row); + void finish (); + void fatal (); void put (ImgRenderer *child) { children->put (new lout::object::TypedPointer <ImgRenderer> (child)); } diff --git a/dw/style.cc b/dw/style.cc index d1c2f183..a9ce7544 100644 --- a/dw/style.cc +++ b/dw/style.cc @@ -34,6 +34,8 @@ namespace dw { namespace core { namespace style { +const bool drawBackgroundLineByLine = true; + static void calcBackgroundRelatedValues (StyleImage *backgroundImage, BackgroundRepeat backgroundRepeat, BackgroundAttachment @@ -480,6 +482,16 @@ void StyleImage::StyleImgRenderer::drawRow (int row) // Nothing to do. } +void StyleImage::StyleImgRenderer::finish () +{ + // Nothing to do. +} + +void StyleImage::StyleImgRenderer::fatal () +{ + // Nothing to do. +} + StyleImage::StyleImage () { //printf ("new StyleImage %p\n", this); @@ -511,50 +523,69 @@ void StyleImage::ExternalImgRenderer::setBuffer (core::Imgbuf *buffer, void StyleImage::ExternalImgRenderer::drawRow (int row) { - StyleImage *backgroundImage; - if (readyToDraw () && (backgroundImage = getBackgroundImage ())) { - // All single rows are drawn. - - Imgbuf *imgbuf = backgroundImage->getImgbuf(); - int imgWidth = imgbuf->getRootWidth (); - int imgHeight = imgbuf->getRootHeight (); - - int x, y, width, height; - getBgArea (&x, &y, &width, &height); - - int xRef, yRef, widthRef, heightRef; - getRefArea (&xRef, &yRef, &widthRef, &heightRef); - - bool repeatX, repeatY, doDraw; - int origX, origY, tileX1, tileX2, tileY1, tileY2; - - calcBackgroundRelatedValues (backgroundImage, - getBackgroundRepeat (), - getBackgroundAttachment (), - getBackgroundPositionX (), - getBackgroundPositionY (), - 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) - // Only iterate over y, because the rows can be combined - // horizontically. - for (int tileY = tileY1; tileY <= tileY2; tileY++) { - int x1 = misc::max (origX + tileX1 * imgWidth, x); - int x2 = misc::min (origX + (tileX2 + 1) * imgWidth, x + width); + if (drawBackgroundLineByLine) { + StyleImage *backgroundImage; + if (readyToDraw () && (backgroundImage = getBackgroundImage ())) { + // All single rows are drawn. + + Imgbuf *imgbuf = backgroundImage->getImgbuf(); + int imgWidth = imgbuf->getRootWidth (); + int imgHeight = imgbuf->getRootHeight (); + + int x, y, width, height; + getBgArea (&x, &y, &width, &height); + + int xRef, yRef, widthRef, heightRef; + getRefArea (&xRef, &yRef, &widthRef, &heightRef); + + bool repeatX, repeatY, doDraw; + int origX, origY, tileX1, tileX2, tileY1, tileY2; + + calcBackgroundRelatedValues (backgroundImage, + getBackgroundRepeat (), + getBackgroundAttachment (), + getBackgroundPositionX (), + getBackgroundPositionY (), + 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) + // Only iterate over y, because the rows can be combined + // horizontically. + for (int tileY = tileY1; tileY <= tileY2; tileY++) { + int x1 = misc::max (origX + tileX1 * imgWidth, x); + int x2 = misc::min (origX + (tileX2 + 1) * imgWidth, x + width); + + int yt = origY + tileY * imgHeight + row; + if (yt >= y && yt < y + height) + draw (x1, yt, x2 - x1, 1); + } + } + } +} - int yt = origY + tileY * imgHeight + row; - if (yt >= y && yt < y + height) - draw (x1, yt, x2 - x1, 1); - } +void StyleImage::ExternalImgRenderer::finish () +{ + if (!drawBackgroundLineByLine) { + if (readyToDraw ()) { + // Draw total area, as a whole. + int x, y, width, height; + getBgArea (&x, &y, &width, &height); + draw (x, y, width, height); + } } } +void StyleImage::ExternalImgRenderer::fatal () +{ + // Nothing to do. +} + // ---------------------------------------------------------------------- StyleImage *StyleImage::ExternalWidgetImgRenderer::getBackgroundImage () diff --git a/dw/style.hh b/dw/style.hh index 361741be..b284d191 100644 --- a/dw/style.hh +++ b/dw/style.hh @@ -712,6 +712,8 @@ private: void setBuffer (core::Imgbuf *buffer, bool resize); void drawRow (int row); + void finish (); + void fatal (); }; int refCount; @@ -732,6 +734,8 @@ public: 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. diff --git a/src/dicache.c b/src/dicache.c index 673d5907..ec63df1f 100644 --- a/src/dicache.c +++ b/src/dicache.c @@ -517,9 +517,12 @@ void a_Dicache_callback(int Op, CacheClient_t *Client) Image->ScanNumber = DicEntry->ScanNumber; } } - } else if (Op == CA_Close || Op == CA_Abort) { + } else if (Op == CA_Close) { a_Image_close(Image); a_Bw_close_client(Web->bw, Client->Key); + } else if (Op == CA_Abort) { + a_Image_abort(Image); + a_Bw_close_client(Web->bw, Client->Key); } } diff --git a/src/image.cc b/src/image.cc index 570c012a..04d89a82 100644 --- a/src/image.cc +++ b/src/image.cc @@ -118,5 +118,15 @@ void a_Image_write(DilloImage *Image, uint_t y) void a_Image_close(DilloImage *Image) { _MSG("a_Image_close\n"); + I2IR(Image)->finish(); +} + +/* + * Implement the abort method + */ +void a_Image_abort(DilloImage *Image) +{ + _MSG("a_Image_abort\n"); + I2IR(Image)->fatal(); } diff --git a/src/image.hh b/src/image.hh index 80f23461..fd105a7e 100644 --- a/src/image.hh +++ b/src/image.hh @@ -71,6 +71,7 @@ void a_Image_set_parms(DilloImage *Image, void *v_imgbuf, DilloUrl *url, DilloImgType type); void a_Image_write(DilloImage *Image, uint_t y); void a_Image_close(DilloImage *Image); +void a_Image_abort(DilloImage *Image); #ifdef __cplusplus |