summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/dw-images-and-backgrounds.doc25
-rw-r--r--dw/image.cc10
-rw-r--r--dw/image.hh3
-rw-r--r--dw/imgrenderer.cc19
-rw-r--r--dw/imgrenderer.hh17
-rw-r--r--dw/style.cc111
-rw-r--r--dw/style.hh4
-rw-r--r--src/dicache.c5
-rw-r--r--src/image.cc10
-rw-r--r--src/image.hh1
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