diff options
author | Sebastian Geerken <devnull@localhost> | 2013-07-03 00:16:38 +0200 |
---|---|---|
committer | Sebastian Geerken <devnull@localhost> | 2013-07-03 00:16:38 +0200 |
commit | 63e61cd2c2f85b1bf66a3932d23f7231a876f62c (patch) | |
tree | c43a898c425d3d07b2b5d0e926419967b2a9babc | |
parent | fa25119df4ad93bff4edbe592ba26d7ffb5daa22 (diff) | |
parent | 97b5864b9b2a06c7cba9704206769fe8e0333d34 (diff) |
Merge with floats repo.
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | configure.ac | 31 | ||||
-rw-r--r-- | dw/core.hh | 3 | ||||
-rw-r--r-- | dw/fltkcore.hh | 11 | ||||
-rw-r--r-- | dw/fltkimgbuf.cc | 324 | ||||
-rw-r--r-- | dw/fltkimgbuf.hh | 31 | ||||
-rw-r--r-- | dw/fltkplatform.cc | 4 | ||||
-rw-r--r-- | dw/fltkplatform.hh | 3 | ||||
-rw-r--r-- | dw/layout.hh | 5 | ||||
-rw-r--r-- | dw/outofflowmgr.hh | 5 | ||||
-rw-r--r-- | dw/platform.hh | 11 | ||||
-rw-r--r-- | dw/tablecell.cc | 6 | ||||
-rw-r--r-- | dw/tablecell.hh | 2 | ||||
-rw-r--r-- | dw/textblock.cc | 55 | ||||
-rw-r--r-- | dw/textblock.hh | 32 | ||||
-rw-r--r-- | dw/textblock_linebreaking.cc | 141 | ||||
-rw-r--r-- | dw/widget.cc | 4 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/dicache.c | 5 | ||||
-rw-r--r-- | src/dicache.h | 3 | ||||
-rw-r--r-- | src/dillo.cc | 2 | ||||
-rw-r--r-- | src/gif.c | 4 | ||||
-rw-r--r-- | src/imgbuf.cc | 5 | ||||
-rw-r--r-- | src/imgbuf.hh | 3 | ||||
-rw-r--r-- | src/jpeg.c | 3 | ||||
-rw-r--r-- | src/png.c | 8 | ||||
-rw-r--r-- | src/xembed.cc | 1 | ||||
-rw-r--r-- | test/dw_images_scaled.cc | 2 | ||||
-rw-r--r-- | test/dw_images_scaled2.cc | 2 | ||||
-rw-r--r-- | test/dw_images_simple.cc | 2 | ||||
-rw-r--r-- | test/dw_imgbuf_mem_test.cc | 6 |
31 files changed, 520 insertions, 202 deletions
@@ -11,6 +11,12 @@ dillo-3.0.4 [not released yet] +- Implemented <optgroup>. Patch: corvid ++- Make embedding into other applications more reliable (BUG#1127). + Patch: Johannes Hofmann ++- Better scaling (down) of images, even with consideration of gamma correction + - Fixed (possibly security) problem of FltkImgBuf caused by integer overflow + (BUG#1129). + Patches: Sebastian Geerken ----------------------------------------------------------------------------- diff --git a/configure.ac b/configure.ac index f8e21e9e..0c4dd953 100644 --- a/configure.ac +++ b/configure.ac @@ -106,9 +106,9 @@ if test "$ac_cv_socklen_t" != "socklen_t"; then fi -dnl ---------------------- +dnl ------------------------- dnl Test for FLTK 1.3 library -dnl ---------------------- +dnl ------------------------- dnl dnl For debugging and to be user friendly AC_MSG_CHECKING([FLTK 1.3]) @@ -124,6 +124,32 @@ case $fltk_version in AC_MSG_ERROR(FLTK 1.3 required; fltk-config not found) esac +dnl ----------------------------------- +dnl Test for X11 (only on some systems) +dnl ----------------------------------- +AC_MSG_CHECKING([whether to link to X11]) +AC_LANG_PUSH([C++]) +old_libs=$LIBS +old_cxxflags=$CXXFLAGS +LIBS=$LIBFLTK_LIBS +CXXFLAGS=$LIBFLTK_CXXFLAGS +AC_RUN_IFELSE([AC_LANG_PROGRAM([[ +#define FL_INTERNALS +#include <FL/x.H> +]],[[ +#ifdef X_PROTOCOL + return 0; +#else + return 1; +#endif +]])], [AC_MSG_RESULT(yes) + LIBX11_LIBS="-lX11"], + [AC_MSG_RESULT(no)], + [AC_MSG_RESULT(no) + AC_MSG_WARN([*** Test for X11 not possible when cross-compiling. ***])]) +CXXFLAGS=$old_cxxflags +LIBS=$old_libs +AC_LANG_POP([C++]) dnl ---------------- dnl Test for libjpeg @@ -469,6 +495,7 @@ AC_SUBST(LIBFLTK_CXXFLAGS) AC_SUBST(LIBFLTK_CFLAGS) AC_SUBST(LIBFLTK_LIBS) AC_SUBST(LIBICONV_LIBS) +AC_SUBST(LIBX11_LIBS) AC_SUBST(datadir) AC_CONFIG_FILES([ @@ -26,6 +26,9 @@ class View; class Widget; class Iterator; +// Nothing yet to free. +inline void freeall () { } + namespace ui { class ResourceFactory; diff --git a/dw/fltkcore.hh b/dw/fltkcore.hh index 2a20a610..5ac619b0 100644 --- a/dw/fltkcore.hh +++ b/dw/fltkcore.hh @@ -20,6 +20,17 @@ class FltkResource; #include "fltkplatform.hh" #include "fltkui.hh" +namespace dw { +namespace fltk { + +inline void freeall () +{ + FltkImgbuf::freeall (); +} + +} // namespace fltk +} // namespace dw + #undef __INCLUDED_FROM_DW_FLTK_CORE_HH__ #endif // __DW_FLTK_CORE_HH__ diff --git a/dw/fltkimgbuf.cc b/dw/fltkimgbuf.cc index 3c3c9236..81d2dc2d 100644 --- a/dw/fltkimgbuf.cc +++ b/dw/fltkimgbuf.cc @@ -1,7 +1,7 @@ /* * Dillo Widget * - * Copyright 2005-2007 Sebastian Geerken <sgeerken@dillo.org> + * Copyright 2005-2007, 2012-2013 Sebastian Geerken <sgeerken@dillo.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,66 +17,139 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - - #include "fltkcore.hh" #include "../lout/msg.h" #include "../lout/misc.hh" #include <FL/fl_draw.H> +#include <math.h> #define IMAGE_MAX_AREA (6000 * 6000) +#define MAX_WIDTH 0x8000 +#define MAX_HEIGHT 0x8000 + namespace dw { namespace fltk { using namespace lout::container::typed; -FltkImgbuf::FltkImgbuf (Type type, int width, int height) +const enum ScaleMode { SIMPLE, BEAUTIFUL, BEAUTIFUL_GAMMA } + scaleMode = BEAUTIFUL_GAMMA; + +Vector <FltkImgbuf::GammaCorrectionTable> *FltkImgbuf::gammaCorrectionTables + = new Vector <FltkImgbuf::GammaCorrectionTable> (true, 2); + +uchar *FltkImgbuf::findGammaCorrectionTable (double gamma) +{ + // Since the number of possible keys is low, a linear search is + // sufficiently fast. + + for (int i = 0; i < gammaCorrectionTables->size(); i++) { + GammaCorrectionTable *gct = gammaCorrectionTables->get(i); + if (gct->gamma == gamma) + return gct->map; + } + + _MSG("Creating new table for gamma = %g\n", gamma); + + GammaCorrectionTable *gct = new GammaCorrectionTable(); + gct->gamma = gamma; + + for (int i = 0; i < 256; i++) + gct->map[i] = 255 * pow((double)i / 255, gamma); + + gammaCorrectionTables->put (gct); + return gct->map; +} + +bool FltkImgbuf::excessiveImageDimensions (int width, int height) +{ + return width <= 0 || height <= 0 || + width > IMAGE_MAX_AREA / height; +} + +void FltkImgbuf::freeall () +{ + _MSG("Deleting gammaCorrectionTables\n"); + delete gammaCorrectionTables; + gammaCorrectionTables = NULL; +} + +FltkImgbuf::FltkImgbuf (Type type, int width, int height, double gamma) { _MSG("FltkImgbuf: new root %p\n", this); - init (type, width, height, NULL); + init (type, width, height, gamma, NULL); } -FltkImgbuf::FltkImgbuf (Type type, int width, int height, FltkImgbuf *root) +FltkImgbuf::FltkImgbuf (Type type, int width, int height, double gamma, + FltkImgbuf *root) { _MSG("FltkImgbuf: new scaled %p, root is %p\n", this, root); - init (type, width, height, root); + init (type, width, height, gamma, root); } -void FltkImgbuf::init (Type type, int width, int height, FltkImgbuf *root) +void FltkImgbuf::init (Type type, int width, int height, double gamma, + FltkImgbuf *root) { - this->root = root; - this->type = type; - this->width = width; - this->height = height; - - // TODO: Maybe this is only for root buffers - switch (type) { + if (excessiveImageDimensions (width, height)) { + // Excessive image sizes which would cause crashes due to too + // big allocations for the image buffer (for root buffers, when + // the image was specially prepared). In this case we use a 1 x + // 1 size. + MSG("FltkImgbuf::init: suspicious image size request %d x %d\n", + width, height); + init (type, 1, 1, gamma, root); + } else if (width > MAX_WIDTH) { + // Too large dimensions cause dangerous overflow errors, so we + // limit dimensions to harmless values. + // + // Example: 65535 * 65536 / 65536 (see scaling below) results in + // the negative value -1. + + MSG("FltkImgbuf::init: cannot handle large width %d\n", width); + init (type, MAX_WIDTH, height, gamma, root); + } else if (height > MAX_HEIGHT) { + MSG("FltkImgbuf::init: cannot handle large height %d\n", height); + init (type, width, MAX_HEIGHT, gamma, root); + } else if (gamma <= 0) { + MSG("FltkImgbuf::init: non-positive gamma %g\n", gamma); + init (type, width, height, 1, root); + } else { + this->root = root; + this->type = type; + this->width = width; + this->height = height; + this->gamma = gamma; + + // TODO: Maybe this is only for root buffers + switch (type) { case RGBA: bpp = 4; break; case RGB: bpp = 3; break; default: bpp = 1; break; - } - _MSG("FltkImgbuf::init width=%d height=%d bpp=%d\n", width, height, bpp); - rawdata = new uchar[bpp * width * height]; - // Set light-gray as interim background color. - memset(rawdata, 222, width*height*bpp); - - refCount = 1; - deleteOnUnref = true; - copiedRows = new lout::misc::BitSet (height); - - // The list is only used for root buffers. - if (isRoot()) - scaledBuffers = new lout::container::typed::List <FltkImgbuf> (true); - else - scaledBuffers = NULL; - - if (!isRoot()) { - // Scaling - for (int row = 0; row < root->height; row++) { - if (root->copiedRows->get (row)) - scaleRow (row, root->rawdata + row*root->width*root->bpp); + } + _MSG("FltkImgbuf::init width=%d height=%d bpp=%d gamma=%g\n", + width, height, bpp, gamma); + rawdata = new uchar[bpp * width * height]; + // Set light-gray as interim background color. + memset(rawdata, 222, width*height*bpp); + + refCount = 1; + deleteOnUnref = true; + copiedRows = new lout::misc::BitSet (height); + + // The list is only used for root buffers. + if (isRoot()) + scaledBuffers = new lout::container::typed::List <FltkImgbuf> (true); + else + scaledBuffers = NULL; + + if (!isRoot()) { + // Scaling + for (int row = 0; row < root->height; row++) { + if (root->copiedRows->get (row)) + scaleRow (row, root->rawdata + row*root->width*root->bpp); + } } } } @@ -119,6 +192,16 @@ void FltkImgbuf::setCMap (int *colors, int num_colors) inline void FltkImgbuf::scaleRow (int row, const core::byte *data) { + if (row < root->height) { + if (scaleMode == SIMPLE) + scaleRowSimple (row, data); + else + scaleRowBeautiful (row, data); + } +} + +inline void FltkImgbuf::scaleRowSimple (int row, const core::byte *data) +{ int sr1 = scaledY (row); int sr2 = scaledY (row + 1); @@ -141,18 +224,112 @@ inline void FltkImgbuf::scaleRow (int row, const core::byte *data) } } +inline void FltkImgbuf::scaleRowBeautiful (int row, const core::byte *data) +{ + int sr1 = scaledY (row); + int sr2 = scaledY (row + 1); + + for (int sr = sr1; sr < sr2; sr++) + copiedRows->set (sr, true); + + if (height > root->height) + scaleBuffer (data, root->width, 1, + rawdata + sr1 * width * bpp, width, sr2 - sr1, + bpp, gamma); + else { + assert (sr1 ==sr2 || sr1 + 1 == sr2); + int row1 = backscaledY(sr1), row2 = backscaledY(sr1 + 1); + + // Draw only when all original lines are retrieved (speed). + bool allRootRows = true; + for (int r = row1; allRootRows && r < row2; r++) + allRootRows = allRootRows && root->copiedRows->get(r); + + if (allRootRows) + // We have to access root->rawdata (which has to be up to + // date), since a larger area than the single row is accessed + // here. + scaleBuffer (root->rawdata + row1 * root->width * bpp, + root->width, row2 - row1, + rawdata + sr1 * width * bpp, width, 1, + bpp, gamma); + } +} + +/** + * General method to scale an image buffer. Used to scale single lines + * in scaleRowBeautiful. + * + * The algorithm is rather simple. If the scaled buffer is smaller + * (both width and height) than the original buffer, each pixel in the + * scaled buffer is assigned a rectangle of pixels in the original + * buffer; the resulting pixel value (red, green, blue) is simply the + * average of all pixel values. This is pretty fast and leads to + * rather good results. + * + * Nothing special (like interpolation) is done when scaling up. + * + * If scaleMode is set to BEAUTIFUL_GAMMA, gamma correction is + * considered, see <http://www.4p8.com/eric.brasseur/gamma.html>. + * + * TODO Could be optimized as in scaleRowSimple: when the destination + * image is larger, calculate only one row/column, and copy it to the + * other rows/columns. + */ +inline void FltkImgbuf::scaleBuffer (const core::byte *src, int srcWidth, + int srcHeight, core::byte *dest, + int destWidth, int destHeight, int bpp, + double gamma) +{ + uchar *gammaMap1, *gammaMap2; + + if (scaleMode == BEAUTIFUL_GAMMA) { + gammaMap1 = findGammaCorrectionTable (gamma); + gammaMap2 = findGammaCorrectionTable (1 / gamma); + } + + for(int x = 0; x < destWidth; x++) + for(int y = 0; y < destHeight; y++) { + int xo1 = x * srcWidth / destWidth; + int xo2 = lout::misc::max ((x + 1) * srcWidth / destWidth, xo1 + 1); + int yo1 = y * srcHeight / destHeight; + int yo2 = lout::misc::max ((y + 1) * srcHeight / destHeight, yo1 + 1); + int n = (xo2 - xo1) * (yo2 - yo1); + + int v[bpp]; + for(int i = 0; i < bpp; i++) + v[i] = 0; + + for(int xo = xo1; xo < xo2; xo++) + for(int yo = yo1; yo < yo2; yo++) { + const core::byte *ps = src + bpp * (yo * srcWidth + xo); + for(int i = 0; i < bpp; i++) + v[i] += + (scaleMode == BEAUTIFUL_GAMMA ? gammaMap2[ps[i]] : ps[i]); + } + + core::byte *pd = dest + bpp * (y * destWidth + x); + for(int i = 0; i < bpp; i++) + pd[i] = + scaleMode == BEAUTIFUL_GAMMA ? gammaMap1[v[i] / n] : v[i] / n; + } +} + void FltkImgbuf::copyRow (int row, const core::byte *data) { assert (isRoot()); - // Flag the row done and copy its data. - copiedRows->set (row, true); - memcpy(rawdata + row * width * bpp, data, width * bpp); - - // Update all the scaled buffers of this root image. - for (Iterator <FltkImgbuf> it = scaledBuffers->iterator(); it.hasNext(); ) { - FltkImgbuf *sb = it.getNext (); - sb->scaleRow(row, data); + if (row < height) { + // Flag the row done and copy its data. + copiedRows->set (row, true); + memcpy(rawdata + row * width * bpp, data, width * bpp); + + // Update all the scaled buffers of this root image. + for (Iterator <FltkImgbuf> it = scaledBuffers->iterator(); + it.hasNext(); ) { + FltkImgbuf *sb = it.getNext (); + sb->scaleRow(row, data); + } } } @@ -171,6 +348,16 @@ core::Imgbuf* FltkImgbuf::getScaledBuf (int width, int height) if (!isRoot()) return root->getScaledBuf (width, height); + if (width > MAX_WIDTH) { + // Similar to init. + MSG("FltkImgbuf::getScaledBuf: cannot handle large width %d\n", width); + return getScaledBuf (MAX_WIDTH, height); + } + if (height > MAX_HEIGHT) { + MSG("FltkImgbuf::getScaledBuf: cannot handle large height %d\n", height); + return getScaledBuf (width, MAX_HEIGHT); + } + if (width == this->width && height == this->height) { ref (); return this; @@ -184,20 +371,18 @@ core::Imgbuf* FltkImgbuf::getScaledBuf (int width, int height) } } - /* Check for excessive image sizes which would cause crashes due to - * too big allocations for the image buffer. - * In this case we return a pointer to the unscaled image buffer. - */ - if (width <= 0 || height <= 0 || - width > IMAGE_MAX_AREA / height) { + // Check for excessive image sizes which would cause crashes due to + // too big allocations for the image buffer. In this case we return + // a pointer to the unscaled image buffer. + if (excessiveImageDimensions (width, height)) { MSG("FltkImgbuf::getScaledBuf: suspicious image size request %d x %d\n", width, height); ref (); return this; } - /* This size is not yet used, so a new buffer has to be created. */ - FltkImgbuf *sb = new FltkImgbuf (type, width, height, this); + // This size is not yet used, so a new buffer has to be created. + FltkImgbuf *sb = new FltkImgbuf (type, width, height, gamma, this); scaledBuffers->append (sb); return sb; } @@ -215,16 +400,20 @@ void FltkImgbuf::getRowArea (int row, dw::core::Rectangle *area) _MSG("::getRowArea: area x=%d y=%d width=%d height=%d\n", area->x, area->y, area->width, area->height); } else { - // scaled buffer - int sr1 = scaledY (row); - int sr2 = scaledY (row + 1); - - area->x = 0; - area->y = sr1; - area->width = width; - area->height = sr2 - sr1; - _MSG("::getRowArea: area x=%d y=%d width=%d height=%d\n", - area->x, area->y, area->width, area->height); + if (row > root->height) + area->x = area->y = area->width = area->height = 0; + else { + // scaled buffer + int sr1 = scaledY (row); + int sr2 = scaledY (row + 1); + + area->x = 0; + area->y = sr1; + area->width = width; + area->height = sr2 - sr1; + _MSG("::getRowArea: area x=%d y=%d width=%d height=%d\n", + area->x, area->y, area->width, area->height); + } } } @@ -299,6 +488,17 @@ int FltkImgbuf::scaledY(int ySrc) return ySrc * height / root->height; } +int FltkImgbuf::backscaledY(int yScaled) +{ + assert (root != NULL); + + // Notice that rounding errors because of integers do not play a + // role. This method cannot be the exact inverse of scaledY, since + // scaleY is not bijective, and so not invertible. Instead, both + // values always return the smallest value. + return yScaled * root->height / height; +} + void FltkImgbuf::draw (Fl_Widget *target, int xRoot, int yRoot, int x, int y, int width, int height) { diff --git a/dw/fltkimgbuf.hh b/dw/fltkimgbuf.hh index 34c6bfd8..ee5ae922 100644 --- a/dw/fltkimgbuf.hh +++ b/dw/fltkimgbuf.hh @@ -11,6 +11,13 @@ namespace fltk { class FltkImgbuf: public core::Imgbuf { private: + class GammaCorrectionTable: public lout::object::Object + { + public: + double gamma; + uchar map[256]; + }; + FltkImgbuf *root; int refCount; bool deleteOnUnref; @@ -18,6 +25,7 @@ private: int width, height; Type type; + double gamma; //{ int bpp; @@ -28,9 +36,17 @@ private: // the image buffer. lout::misc::BitSet *copiedRows; - FltkImgbuf (Type type, int width, int height, FltkImgbuf *root); - void init (Type type, int width, int height, FltkImgbuf *root); + static lout::container::typed::Vector <GammaCorrectionTable> + *gammaCorrectionTables; + + static uchar *findGammaCorrectionTable (double gamma); + static bool excessiveImageDimensions (int width, int height); + + FltkImgbuf (Type type, int width, int height, double gamma, + FltkImgbuf *root); + void init (Type type, int width, int height, double gamma, FltkImgbuf *root); int scaledY(int ySrc); + int backscaledY(int yScaled); int isRoot() { return (root == NULL); } void detachScaledBuf (FltkImgbuf *scaledBuf); @@ -38,10 +54,19 @@ protected: ~FltkImgbuf (); public: - FltkImgbuf (Type type, int width, int height); + FltkImgbuf (Type type, int width, int height, double gamma); + + static void freeall (); void setCMap (int *colors, int num_colors); inline void scaleRow (int row, const core::byte *data); + inline void scaleRowSimple (int row, const core::byte *data); + inline void scaleRowBeautiful (int row, const core::byte *data); + inline static void scaleBuffer (const core::byte *src, int srcWidth, + int srcHeight, core::byte *dest, + int destWidth, int destHeight, int bpp, + double gamma); + void newScan (); void copyRow (int row, const core::byte *data); core::Imgbuf* getScaledBuf (int width, int height); diff --git a/dw/fltkplatform.cc b/dw/fltkplatform.cc index 7dd87a18..1d77e289 100644 --- a/dw/fltkplatform.cc +++ b/dw/fltkplatform.cc @@ -704,9 +704,9 @@ void FltkPlatform::copySelection(const char *text) } core::Imgbuf *FltkPlatform::createImgbuf (core::Imgbuf::Type type, - int width, int height) + int width, int height, double gamma) { - return new FltkImgbuf (type, width, height); + return new FltkImgbuf (type, width, height, gamma); } core::ui::ResourceFactory *FltkPlatform::getResourceFactory () diff --git a/dw/fltkplatform.hh b/dw/fltkplatform.hh index 64605b68..2fb95633 100644 --- a/dw/fltkplatform.hh +++ b/dw/fltkplatform.hh @@ -169,7 +169,8 @@ public: core::style::Tooltip *createTooltip (const char *text); void cancelTooltip(); - core::Imgbuf *createImgbuf (core::Imgbuf::Type type, int width, int height); + core::Imgbuf *createImgbuf (core::Imgbuf::Type type, int width, int height, + double gamma); void copySelection(const char *text); diff --git a/dw/layout.hh b/dw/layout.hh index d3ace03a..51d764a4 100644 --- a/dw/layout.hh +++ b/dw/layout.hh @@ -358,9 +358,10 @@ public: return platform->cancelTooltip (); } - inline Imgbuf *createImgbuf (Imgbuf::Type type, int width, int height) + inline Imgbuf *createImgbuf (Imgbuf::Type type, int width, int height, + double gamma) { - return platform->createImgbuf (type, width, height); + return platform->createImgbuf (type, width, height, gamma); } inline void copySelection(const char *text) diff --git a/dw/outofflowmgr.hh b/dw/outofflowmgr.hh index fd3b4f59..c19f0428 100644 --- a/dw/outofflowmgr.hh +++ b/dw/outofflowmgr.hh @@ -351,6 +351,11 @@ public: return absolutelyPositioned->get(i - (leftFloatsAll->size() + rightFloatsAll->size()))->widget; } + + inline bool affectsLeftBorder (core::Widget *widget) { + return widget->getStyle()->vloat == core::style::FLOAT_LEFT; } + inline bool affectsRightBorder (core::Widget *widget) { + return widget->getStyle()->vloat == core::style::FLOAT_RIGHT; } }; } // namespace dw diff --git a/dw/platform.hh b/dw/platform.hh index 1e16dcfe..227cda33 100644 --- a/dw/platform.hh +++ b/dw/platform.hh @@ -146,12 +146,13 @@ public: */ virtual void cancelTooltip () = 0; - /* - * -------------------- - * Image Buffers - * -------------------- + /** + * \brief Create a (platform speficic) image buffer. + * + * "gamma" is the value by which the image data is gamma-encoded. */ - virtual Imgbuf *createImgbuf (Imgbuf::Type type, int width, int height) = 0; + virtual Imgbuf *createImgbuf (Imgbuf::Type type, int width, int height, + double gamma) = 0; /** * \brief Copy selected text (0-terminated). diff --git a/dw/tablecell.cc b/dw/tablecell.cc index d1a8e3e1..66f86576 100644 --- a/dw/tablecell.cc +++ b/dw/tablecell.cc @@ -42,12 +42,12 @@ TableCell::~TableCell() { } -void TableCell::wordWrap(int wordIndex, bool wrapAll) +bool TableCell::wordWrap(int wordIndex, bool wrapAll) { Textblock::Word *word; const char *p; - Textblock::wordWrap (wordIndex, wrapAll); + bool ret = Textblock::wordWrap (wordIndex, wrapAll); if (charWordIndex == -1) { word = words->getRef (wordIndex); @@ -66,6 +66,8 @@ void TableCell::wordWrap(int wordIndex, bool wrapAll) if (wordIndex == charWordIndex) updateValue (); + + return ret; } int TableCell::getValue () diff --git a/dw/tablecell.hh b/dw/tablecell.hh index 4bb8633c..f7c6042e 100644 --- a/dw/tablecell.hh +++ b/dw/tablecell.hh @@ -12,7 +12,7 @@ private: int charWordIndex, charWordPos; protected: - void wordWrap (int wordIndex, bool wrapAll); + bool wordWrap (int wordIndex, bool wrapAll); int getValue (); void setMaxValue (int maxValue, int value); diff --git a/dw/textblock.cc b/dw/textblock.cc index 583aaaec..683bdce5 100644 --- a/dw/textblock.cc +++ b/dw/textblock.cc @@ -2051,21 +2051,31 @@ void Textblock::setBreakOption (Word *word, core::style::Style *style, // TODO: lineMustBeBroken should be independent of the penalty // index? Otherwise, examine the last line. if (!word->badnessAndPenalty.lineMustBeBroken(0)) { - switch (style->whiteSpace) { - case core::style::WHITE_SPACE_NORMAL: - case core::style::WHITE_SPACE_PRE_LINE: - case core::style::WHITE_SPACE_PRE_WRAP: + if (isBreakAllowed (word)) word->badnessAndPenalty.setPenalties (breakPenalty1, breakPenalty2); - break; - - case core::style::WHITE_SPACE_PRE: - case core::style::WHITE_SPACE_NOWRAP: + else word->badnessAndPenalty.setPenalty (PENALTY_PROHIBIT_BREAK); - break; - } } } +bool Textblock::isBreakAllowed (Word *word) +{ + switch (word->style->whiteSpace) { + case core::style::WHITE_SPACE_NORMAL: + case core::style::WHITE_SPACE_PRE_LINE: + case core::style::WHITE_SPACE_PRE_WRAP: + return true; + + case core::style::WHITE_SPACE_PRE: + case core::style::WHITE_SPACE_NOWRAP: + return false; + } + + // compiler happiness + lout::misc::assertNotReached (); + return false; +} + /** * Cause a paragraph break @@ -2525,9 +2535,7 @@ int Textblock::heightOfPossiblyMissingLine (int lineNo) return line->boxAscent + line->boxDescent; } else { PRINTF (" Exist but is not finished.\n"); - return accumulateLineHeight (lines->size() > 0 ? - lines->getLastRef()->lastWord + 1 : 0, - words->size() - 1); + return misc::max (1, newLineAscent + newLineDescent); } } else if (lineNo == lines->size()) { // The line to be constructed: some words exist, but not the @@ -2537,28 +2545,9 @@ int Textblock::heightOfPossiblyMissingLine (int lineNo) // see doc/dw-out-of-flow.doc. -- Still the case? PRINTF (" Does not exist.\n"); - return accumulateLineHeight (lines->size() > 0 ? - lines->getLastRef()->lastWord + 1 : 0, - words->size() - 1); + return misc::max (1, newLineAscent + newLineDescent); } else return 1; } -int Textblock::accumulateLineHeight (int firstWord, int lastWord) -{ - // TODO Could be faster by accumulating them when words are added. - int h = 1; - PRINTF (" Accumulating words from %d to %d\n", firstWord, lastWord); - for (int i = firstWord; i <= lastWord; i++) { - Word *word = words->getRef (i); - h = misc::max (h, word->size.ascent + word->size.descent); - //printf (" word %d: ", i); - //printWordShort (word); - //printf (" => %d + %d = %d\n", word->size.ascent, word->size.descent, - // word->size.ascent + word->size.descent); - } - PRINTF (" => %d\n", h); - return h; -} - } // namespace dw diff --git a/dw/textblock.hh b/dw/textblock.hh index bcf31d67..1989ecdb 100644 --- a/dw/textblock.hh +++ b/dw/textblock.hh @@ -249,9 +249,6 @@ protected: int firstWord; /* first word's index in word vector */ int lastWord; /* last word's index in word vector */ - // TODO Adjust comments. Short note: maxParMin/maxParMax is - // is never smaller than parMin/parMax. - /* * General remark: all values include the last hyphen width, but * not the last space; these values are, however corrected, when @@ -263,15 +260,16 @@ protected: */ int parMin; /* The sum of all word minima (plus spaces, - hyphen width etc.) of the last c */ + hyphen width etc.) since the last possible + break within this paragraph. */ int parMax; /* The sum of all word maxima in this * paragraph (plus spaces, hyphen width * etc.). */ - int maxParMin; /* Maximum of all paragraph minima, including - * this line. */ - int maxParMax; /* Maximum of all paragraph maxima (value of "parMax"), - * including this one. */ + int maxParMin; /* Maximum of all paragraph minima (value of + * "parMin), including this paragraph. */ + int maxParMax; /* Maximum of all paragraph maxima (value of + * "parMax"), including this paragraph. */ }; struct Line @@ -463,6 +461,12 @@ protected: or 0, if outOfFlowMgr is NULL */ + // Ascent and descent of the newly constructed line, i. e. maximum + // of all words ascent/descent since the end of the last line. Not + // neccessary the ascent and descent of the newly added line, since + // not all words are added to it. + int newLineAscent, newLineDescent; + lout::misc::SimpleVector <Line> *lines; lout::misc::SimpleVector <Paragraph> *paragraphs; int nonTemporaryLines; @@ -514,6 +518,7 @@ protected: void fillSpace (Word *word, core::style::Style *style); void setBreakOption (Word *word, core::style::Style *style, int breakPenalty1, int breakPenalty2); + bool isBreakAllowed (Word *word); int textWidth (const char *text, int start, int len, core::style::Style *style, bool isStart, bool isEnd); void calcTextSize (const char *text, size_t len, core::style::Style *style, @@ -586,7 +591,6 @@ protected: Textblock *getTextblockForLine (int firstWord, int lastWord); int topOfPossiblyMissingLine (int lineNo); int heightOfPossiblyMissingLine (int lineNo); - int accumulateLineHeight (int firstWord, int lastWord); bool sendSelectionEvent (core::SelectionState::EventType eventType, core::MousePositionEvent *event); @@ -594,11 +598,11 @@ protected: void accumulateWordExtremes (int firstWord, int lastWord, int *maxOfMinWidth, int *sumOfMaxWidth); void processWord (int wordIndex); - virtual void wordWrap (int wordIndex, bool wrapAll); - void wrapWordInFlow (int wordIndex, bool wrapAll); - void checkPossibleLighHeightChange (int wordIndex); - void wrapWordOofRef (int wordIndex, bool wrapAll); - void updateBorders (int wordIndex); + virtual bool wordWrap (int wordIndex, bool wrapAll); + bool wrapWordInFlow (int wordIndex, bool wrapAll); + void checkPossibleLineHeightChange (int wordIndex); + bool wrapWordOofRef (int wordIndex, bool wrapAll); + void updateBorders (int wordIndex, bool left, bool right); int searchMinBap (int firstWord, int lastWordm, int penaltyIndex, bool correctAtEnd); int considerHyphenation (int firstIndex, int breakPos); diff --git a/dw/textblock_linebreaking.cc b/dw/textblock_linebreaking.cc index 3372485e..3f06cb6d 100644 --- a/dw/textblock_linebreaking.cc +++ b/dw/textblock_linebreaking.cc @@ -473,7 +473,26 @@ void Textblock::accumulateWordExtremes (int firstWord, int lastWord, void Textblock::processWord (int wordIndex) { - wordWrap (wordIndex, false); + bool wordListChanged = wordWrap (wordIndex, false); + + if (wordListChanged) { + // If wordWrap has called hyphenateWord here, this has an effect + // on the call of handleWordExtremes. To avoid adding values + // more than one time (original un-hyphenated word, plus all + // parts of the hyphenated word, except the first one), the + // whole paragraph is recalculated again. + + int firstWord; + if (paragraphs->size() > 0) { + firstWord = paragraphs->getLastRef()->firstWord; + paragraphs->setSize (paragraphs->size() - 1); + } else + firstWord = 0; + + for (int i = firstWord; i <= wordIndex - 1; i++) + handleWordExtremes (i); + } + handleWordExtremes (wordIndex); } @@ -481,8 +500,11 @@ void Textblock::processWord (int wordIndex) * This method is called in two cases: (i) when a word is added * (ii) when a page has to be (partially) rewrapped. It does word wrap, * and adds new lines if necessary. + * + * Returns whether the words list has changed at, or before, the word + * index. */ -void Textblock::wordWrap (int wordIndex, bool wrapAll) +bool Textblock::wordWrap (int wordIndex, bool wrapAll) { PRINTF ("[%p] WORD_WRAP (%d, %s)\n", this, wordIndex, wrapAll ? "true" : "false"); @@ -503,21 +525,23 @@ void Textblock::wordWrap (int wordIndex, bool wrapAll) switch (word->content.type) { case core::Content::WIDGET_OOF_REF: - wrapWordOofRef (wordIndex, wrapAll); + return wrapWordOofRef (wordIndex, wrapAll); break; default: - wrapWordInFlow (wordIndex, wrapAll); + return wrapWordInFlow (wordIndex, wrapAll); break; } } -void Textblock::wrapWordInFlow (int wordIndex, bool wrapAll) +bool Textblock::wrapWordInFlow (int wordIndex, bool wrapAll) { Word *word = words->getRef (wordIndex); + bool wordListChanged = false; + int penaltyIndex = calcPenaltyIndexForNewLine (); - checkPossibleLighHeightChange (wordIndex); + checkPossibleLineHeightChange (wordIndex); bool newLine; do { @@ -651,6 +675,9 @@ void Textblock::wrapWordInFlow (int wordIndex, bool wrapAll) // update word pointer as hyphenateWord() can trigger a // reorganization of the words structure word = words->getRef (wordIndex); + + if (n > 0 && hyphenatedWord <= wordIndex) + wordListChanged = true; } PRINTF ("[%p] accumulating again from %d to %d\n", @@ -686,84 +713,87 @@ void Textblock::wrapWordInFlow (int wordIndex, bool wrapAll) word->content.widget->parentRef); } } + + return wordListChanged; } /** * Check wheather the newly wrapped word will change the height of the * newly constructed line. If yes, the borders due to floats may * change. (Line height is an argument to the calculation of borders.) + * + * Also update newLineAscent and newLineDescent with values of the new + * word. */ -void Textblock::checkPossibleLighHeightChange (int wordIndex) +void Textblock::checkPossibleLineHeightChange (int wordIndex) { - if (containingBlock->outOfFlowMgr) { - int firstIndex = - lines->size() == 0 ? 0 : lines->getLastRef()->lastWord + 1; + Word *w = words->getRef (wordIndex); + bool heightIncreased = + containingBlock->outOfFlowMgr && + (w->size.ascent > newLineAscent || w->size.descent >= newLineDescent); - // Notice, that firstIndex may be larger than wordIndex, due to - // hyphenation. This means, that the word with the index - // wordIndex is already part of a line. Nothing to do then. + newLineAscent = misc::max (newLineAscent, w->size.ascent); + newLineDescent = misc::max (newLineDescent, w->size.descent); - /** \todo The reasons are found somewhere else. Is this a problem? */ - - Word *w1 = words->getRef (wordIndex); - // It is sufficient to find a word which is equally high or - // higher, to negate the assumtion. This loop should in most - // cases be cancelled rather soon, so that peformance hopefully - // does not matter. - bool equalOrGreaterFound = false; - for (int i = firstIndex; !equalOrGreaterFound && i < wordIndex; i++) { - Word *w2 = words->getRef (i); - if (w2->size.ascent >= w1->size.ascent || - w2->size.descent >= w1->size.descent) - equalOrGreaterFound = true; - } - - if (!equalOrGreaterFound) - updateBorders (wordIndex); - } + if (heightIncreased) + updateBorders (wordIndex, true, true); } -void Textblock::wrapWordOofRef (int wordIndex, bool wrapAll) +bool Textblock::wrapWordOofRef (int wordIndex, bool wrapAll) { assert (containingBlock->outOfFlowMgr); int y = topOfPossiblyMissingLine (lines->size ()); - containingBlock->outOfFlowMgr->tellPosition - (words->getRef(wordIndex)->content.widget, y); + Widget *widget = words->getRef(wordIndex)->content.widget; + containingBlock->outOfFlowMgr->tellPosition (widget, y); + + // For better performance: Ignore OOF references which do not have + // an effect on borders (e. g. soon absolute positions); and also + // distinguish between left and right border. - // Suggestion for better performance: One could ignore OOF - // references which do not have an effect on borders (e. g. soon - // absolute positions); and also distinguish between left and right - // border. OutOfFlowMgr should provide methods for this: - // affectsLeftBorder and affectsRightBorder. + bool left = containingBlock->outOfFlowMgr->affectsLeftBorder (widget); + bool right = containingBlock->outOfFlowMgr->affectsRightBorder (widget); + if (left || right) + updateBorders (wordIndex, left, right); - updateBorders (wordIndex); + return false; // Actually, the words list is never changed here. } /** * Recalculate borders (due to floats) for new line. */ -void Textblock::updateBorders (int wordIndex) +void Textblock::updateBorders (int wordIndex, bool left, bool right) { + assert (left || right); + int y = topOfPossiblyMissingLine (lines->size ()); int h = heightOfPossiblyMissingLine (lines->size ()); - newLineHasFloatLeft = - containingBlock->outOfFlowMgr->hasFloatLeft (this, y, h, this, wordIndex); - newLineHasFloatRight = - containingBlock->outOfFlowMgr->hasFloatRight (this, y, h, this, - wordIndex); - newLineLeftBorder = - containingBlock->outOfFlowMgr->getLeftBorder (this, y, h, this, - wordIndex); - newLineRightBorder = - containingBlock->outOfFlowMgr->getRightBorder (this, y, h, this, - wordIndex); + if (left) { + newLineHasFloatLeft = + containingBlock->outOfFlowMgr->hasFloatLeft (this, y, h, this, + wordIndex); + newLineHasFloatRight = + containingBlock->outOfFlowMgr->hasFloatRight (this, y, h, this, + wordIndex); + } + + if (right) { + newLineLeftBorder = + containingBlock->outOfFlowMgr->getLeftBorder (this, y, h, this, + wordIndex); + newLineRightBorder = + containingBlock->outOfFlowMgr->getRightBorder (this, y, h, this, + wordIndex); + } int firstIndex = lines->size() == 0 ? 0 : lines->getLastRef()->lastWord + 1; - // Again, it may be that firstIndex > wordIndex. See - // checkPossibleLighHeightChange. + + // Notice, that firstIndex may be larger than wordIndex, due to + // hyphenation. This means, that the word with the index + // wordIndex is already part of a line. Nothing to do then. + for (int i = firstIndex; i <= wordIndex; i++) accumulateWordData (i); } @@ -866,6 +896,7 @@ bool Textblock::isHyphenationCandidate (Word *word) { return (word->flags & Word::CAN_BE_HYPHENATED) && word->style->x_lang[0] && + isBreakAllowed(word) && word->content.type == core::Content::TEXT && Hyphenator::isHyphenationCandidate (word->content.text); } @@ -1434,6 +1465,8 @@ void Textblock::initNewLine () PRINTF ("[%p] INIT_NEW_LINE: no CB or OOFM\n", this); } + + newLineAscent = newLineDescent = 0; } void Textblock::showMissingLines () diff --git a/dw/widget.cc b/dw/widget.cc index 3ea80a0e..12430f01 100644 --- a/dw/widget.cc +++ b/dw/widget.cc @@ -111,8 +111,8 @@ void Widget::setParent (Widget *parent) notifySetParent(); //DBG_OBJ_ASSOC (widget, parent); - printf ("The %s %p becomes a child of the %s %p\n", - getClassName(), this, parent->getClassName(), parent); + //printf ("The %s %p becomes a child of the %s %p\n", + // getClassName(), this, parent->getClassName(), parent); } void Widget::queueDrawArea (int x, int y, int width, int height) diff --git a/src/Makefile.am b/src/Makefile.am index c4c7949a..65a42cad 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,7 +19,7 @@ dillo_LDADD = \ $(top_builddir)/dw/libDw-core.a \ $(top_builddir)/lout/liblout.a \ @LIBJPEG_LIBS@ @LIBPNG_LIBS@ @LIBFLTK_LIBS@ @LIBZ_LIBS@ \ - @LIBICONV_LIBS@ @LIBPTHREAD_LIBS@ + @LIBICONV_LIBS@ @LIBPTHREAD_LIBS@ @LIBX11_LIBS@ dillo_SOURCES = \ dillo.cc \ diff --git a/src/dicache.c b/src/dicache.c index 23721685..55232846 100644 --- a/src/dicache.c +++ b/src/dicache.c @@ -259,7 +259,8 @@ void a_Dicache_invalidate_entry(const DilloUrl *Url) * (By now, we'll use the image information despite the html tags --Jcid) */ void a_Dicache_set_parms(DilloUrl *url, int version, DilloImage *Image, - uint_t width, uint_t height, DilloImgType type) + uint_t width, uint_t height, DilloImgType type, + double gamma) { DICacheEntry *DicEntry; @@ -275,7 +276,7 @@ void a_Dicache_set_parms(DilloUrl *url, int version, DilloImage *Image, /* BUG: there's just one image-type now */ #define I_RGB 0 - DicEntry->v_imgbuf = a_Imgbuf_new(Image->dw, I_RGB, width, height); + DicEntry->v_imgbuf = a_Imgbuf_new(Image->dw, I_RGB, width, height, gamma); DicEntry->TotalSize = width * height * 3; DicEntry->width = width; diff --git a/src/dicache.h b/src/dicache.h index 76fdba92..df8a8b89 100644 --- a/src/dicache.h +++ b/src/dicache.h @@ -59,7 +59,8 @@ void *a_Dicache_jpeg_image(const char *Type, void *Ptr, CA_Callback_t *Call, void a_Dicache_callback(int Op, CacheClient_t *Client); void a_Dicache_set_parms(DilloUrl *url, int version, DilloImage *Image, - uint_t width, uint_t height, DilloImgType type); + uint_t width, uint_t height, DilloImgType type, + double gamma); void a_Dicache_set_cmap(DilloUrl *url, int version, DilloImage *Image, const uchar_t *cmap, uint_t num_colors, int num_colors_max, int bg_index); diff --git a/src/dillo.cc b/src/dillo.cc index bf25d315..5c1e7364 100644 --- a/src/dillo.cc +++ b/src/dillo.cc @@ -516,6 +516,8 @@ int main(int argc, char **argv) a_Prefs_freeall(); Keys::free(); Paths::free(); + dw::core::freeall(); + dw::fltk::freeall(); /* TODO: auth, css */ //a_Dpi_dillo_exit(); @@ -814,8 +814,10 @@ static size_t Gif_do_img_desc(DilloGif *gif, void *Buf, return 0; } + /** \todo Gamma for GIF? */ a_Dicache_set_parms(gif->url, gif->version, gif->Image, - gif->Width, gif->Height, DILLO_IMG_TYPE_INDEXED); + gif->Width, gif->Height, DILLO_IMG_TYPE_INDEXED, + 1 / 2.2); Flags = buf[8]; diff --git a/src/imgbuf.cc b/src/imgbuf.cc index 51f86b74..16eb5c31 100644 --- a/src/imgbuf.cc +++ b/src/imgbuf.cc @@ -90,7 +90,8 @@ void a_Imgbuf_unref(void *v_imgbuf) /* * Create a new Imgbuf */ -void *a_Imgbuf_new(void *v_dw, int img_type, uint_t width, uint_t height) +void *a_Imgbuf_new(void *v_dw, int img_type, uint_t width, uint_t height, + double gamma) { Layout *layout = ((Widget*)v_dw)->getLayout(); if (!layout) { @@ -103,7 +104,7 @@ void *a_Imgbuf_new(void *v_dw, int img_type, uint_t width, uint_t height) linebuf = (uchar_t*) dRealloc(linebuf, linebuf_size); } - return (void*)layout->createImgbuf(Imgbuf::RGB, width, height); + return (void*)layout->createImgbuf(Imgbuf::RGB, width, height, gamma); } /* diff --git a/src/imgbuf.hh b/src/imgbuf.hh index 9a6e3ff7..af0bf9a6 100644 --- a/src/imgbuf.hh +++ b/src/imgbuf.hh @@ -16,7 +16,8 @@ extern "C" { */ void a_Imgbuf_ref(void *v_imgbuf); void a_Imgbuf_unref(void *v_imgbuf); -void *a_Imgbuf_new(void *v_dw, int img_type, uint_t width, uint_t height); +void *a_Imgbuf_new(void *v_dw, int img_type, uint_t width, uint_t height, + double gamma); int a_Imgbuf_last_reference(void *v_imgbuf); void a_Imgbuf_update(void *v_imgbuf, const uchar_t *buf, DilloImgType type, uchar_t *cmap, uint_t width, uint_t height, uint_t y); @@ -299,10 +299,11 @@ static void Jpeg_write(DilloJpeg *jpeg, void *Buf, uint_t BufSize) return; } + /** \todo Gamma for JPEG? */ a_Dicache_set_parms(jpeg->url, jpeg->version, jpeg->Image, (uint_t)jpeg->cinfo.image_width, (uint_t)jpeg->cinfo.image_height, - type); + type, 1 / 2.2); /* decompression step 4 (see libjpeg.doc) */ jpeg->state = DILLO_JPEG_STARTING; @@ -119,7 +119,7 @@ Png_datainfo_callback(png_structp png_ptr, png_infop info_ptr) int bit_depth; int interlace_type; uint_t i; - double gamma; + double file_gamma = 1 / 2.2; _MSG("Png_datainfo_callback:\n"); @@ -163,8 +163,8 @@ Png_datainfo_callback(png_structp png_ptr, png_infop info_ptr) /* Get and set gamma information. Beware: gamma correction 2.2 will only work on PC's. TODO: select screen gamma correction for other platforms. */ - if (png_get_gAMA(png_ptr, info_ptr, &gamma)) - png_set_gamma(png_ptr, 2.2, gamma); + if (png_get_gAMA(png_ptr, info_ptr, &file_gamma)) + png_set_gamma(png_ptr, 2.2, file_gamma); /* Convert gray scale to RGB */ if (color_type == PNG_COLOR_TYPE_GRAY || @@ -203,7 +203,7 @@ Png_datainfo_callback(png_structp png_ptr, png_infop info_ptr) /* Initialize the dicache-entry here */ a_Dicache_set_parms(png->url, png->version, png->Image, (uint_t)png->width, (uint_t)png->height, - DILLO_IMG_TYPE_RGB); + DILLO_IMG_TYPE_RGB, file_gamma); } static void diff --git a/src/xembed.cc b/src/xembed.cc index f180d81d..88494495 100644 --- a/src/xembed.cc +++ b/src/xembed.cc @@ -108,6 +108,7 @@ void Xembed::show() { createInternal(xid); setXembedInfo(1); Fl::event_dispatch(event_handler); + Fl_Window::show(); } void Xembed::createInternal(uint32_t parent) { diff --git a/test/dw_images_scaled.cc b/test/dw_images_scaled.cc index 34a72c21..e31abfaa 100644 --- a/test/dw_images_scaled.cc +++ b/test/dw_images_scaled.cc @@ -41,7 +41,7 @@ static int imgRow = 0; static void imageInitTimeout (void *data) { //imgbuf = layout->createImgbuf (Imgbuf::RGBA, 400, 200); - imgbuf = layout->createImgbuf (Imgbuf::RGB, 400, 200); + imgbuf = layout->createImgbuf (Imgbuf::RGB, 400, 200, 1); image->setBuffer (imgbuf); } diff --git a/test/dw_images_scaled2.cc b/test/dw_images_scaled2.cc index 81cdd2e8..01a55bcf 100644 --- a/test/dw_images_scaled2.cc +++ b/test/dw_images_scaled2.cc @@ -40,7 +40,7 @@ static int imgRow = 0; static void imageInitTimeout (void *data) { - imgbuf = layout->createImgbuf (Imgbuf::RGB, 400, 200); + imgbuf = layout->createImgbuf (Imgbuf::RGB, 400, 200, 1); image1->setBuffer (imgbuf); image2->setBuffer (imgbuf); } diff --git a/test/dw_images_simple.cc b/test/dw_images_simple.cc index 34de20ea..361ede68 100644 --- a/test/dw_images_simple.cc +++ b/test/dw_images_simple.cc @@ -42,7 +42,7 @@ static void imageInitTimeout (void *data) { const bool resize = true; //imgbuf = layout->createImgbuf (Imgbuf::RGBA, 400, 200); - imgbuf = layout->createImgbuf (Imgbuf::RGB, 400, 200); + imgbuf = layout->createImgbuf (Imgbuf::RGB, 400, 200, 1); image->setBuffer (imgbuf, resize); } diff --git a/test/dw_imgbuf_mem_test.cc b/test/dw_imgbuf_mem_test.cc index 45beef8b..e2532ea7 100644 --- a/test/dw_imgbuf_mem_test.cc +++ b/test/dw_imgbuf_mem_test.cc @@ -29,7 +29,7 @@ void solution1 () FltkPlatform *platform = new FltkPlatform (); Layout *layout = new Layout (platform); - Imgbuf *rootbuf = layout->createImgbuf (Imgbuf::RGB, 100, 100); + Imgbuf *rootbuf = layout->createImgbuf (Imgbuf::RGB, 100, 100, 1); rootbuf->ref (); // Extra reference by the dicache. printf ("=== Can be deleted? %s.\n", rootbuf->lastReference () ? "Yes" : "No"); @@ -52,7 +52,7 @@ void solution2 () FltkPlatform *platform = new FltkPlatform (); Layout *layout = new Layout (platform); - Imgbuf *rootbuf = layout->createImgbuf (Imgbuf::RGB, 100, 100); + Imgbuf *rootbuf = layout->createImgbuf (Imgbuf::RGB, 100, 100, 1); rootbuf->setDeleteOnUnref (false); printf ("=== Can be deleted? %s.\n", !rootbuf->isReferred () ? "Yes" : "No"); @@ -86,7 +86,7 @@ void solution3 () FltkPlatform *platform = new FltkPlatform (); Layout *layout = new Layout (platform); - Imgbuf *rootbuf = layout->createImgbuf (Imgbuf::RGB, 100, 100); + Imgbuf *rootbuf = layout->createImgbuf (Imgbuf::RGB, 100, 100, 1); rootbuf->connectDeletion (new RootbufDeletionReceiver ()); Imgbuf *scaledbuf = rootbuf->getScaledBuf (50, 50); rootbuf->unref (); |