aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--configure.ac31
-rw-r--r--dw/core.hh3
-rw-r--r--dw/fltkcore.hh11
-rw-r--r--dw/fltkimgbuf.cc324
-rw-r--r--dw/fltkimgbuf.hh31
-rw-r--r--dw/fltkplatform.cc4
-rw-r--r--dw/fltkplatform.hh3
-rw-r--r--dw/layout.hh5
-rw-r--r--dw/outofflowmgr.hh5
-rw-r--r--dw/platform.hh11
-rw-r--r--dw/tablecell.cc6
-rw-r--r--dw/tablecell.hh2
-rw-r--r--dw/textblock.cc55
-rw-r--r--dw/textblock.hh32
-rw-r--r--dw/textblock_linebreaking.cc141
-rw-r--r--dw/widget.cc4
-rw-r--r--src/Makefile.am2
-rw-r--r--src/dicache.c5
-rw-r--r--src/dicache.h3
-rw-r--r--src/dillo.cc2
-rw-r--r--src/gif.c4
-rw-r--r--src/imgbuf.cc5
-rw-r--r--src/imgbuf.hh3
-rw-r--r--src/jpeg.c3
-rw-r--r--src/png.c8
-rw-r--r--src/xembed.cc1
-rw-r--r--test/dw_images_scaled.cc2
-rw-r--r--test/dw_images_scaled2.cc2
-rw-r--r--test/dw_images_simple.cc2
-rw-r--r--test/dw_imgbuf_mem_test.cc6
31 files changed, 520 insertions, 202 deletions
diff --git a/ChangeLog b/ChangeLog
index ff765f04..082f801a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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([
diff --git a/dw/core.hh b/dw/core.hh
index 13545bfe..f39c38cc 100644
--- a/dw/core.hh
+++ b/dw/core.hh
@@ -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();
diff --git a/src/gif.c b/src/gif.c
index 554ffa83..69fcf5d3 100644
--- a/src/gif.c
+++ b/src/gif.c
@@ -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);
diff --git a/src/jpeg.c b/src/jpeg.c
index c81afe1d..625808fb 100644
--- a/src/jpeg.c
+++ b/src/jpeg.c
@@ -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;
diff --git a/src/png.c b/src/png.c
index 995725cd..4f5da1c2 100644
--- a/src/png.c
+++ b/src/png.c
@@ -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 ();