aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.hgignore80
-rw-r--r--ChangeLog18
-rw-r--r--Makefile.am2
-rw-r--r--config.h.in21
-rw-r--r--configure.in120
-rw-r--r--d_size.h24
-rw-r--r--dillorc7
-rw-r--r--dlib/Makefile.am4
-rw-r--r--doc/README2
-rw-r--r--doc/dillo.118
-rw-r--r--doc/dw-layout-widgets.doc4
-rw-r--r--doc/dw-usage.doc2
-rw-r--r--doc/dw-widget-sizes.doc4
-rw-r--r--doc/user_help.html8
-rw-r--r--dpi/Makefile.am39
-rw-r--r--dpi/bookmarks.c3
-rw-r--r--dpi/downloads.cc205
-rw-r--r--dpi/file.c10
-rw-r--r--dpi/https.c37
-rw-r--r--dpid/Makefile.am12
-rw-r--r--dpip/Makefile.am3
-rw-r--r--dpip/dpip.c1
-rw-r--r--dw/Makefile.am3
-rw-r--r--dw/fltkimgbuf.cc2
-rw-r--r--dw/fltkplatform.cc47
-rw-r--r--dw/fltkui.cc5
-rw-r--r--dw/fltkviewbase.cc79
-rw-r--r--dw/fltkviewbase.hh4
-rw-r--r--dw/layout.cc24
-rw-r--r--dw/layout.hh5
-rw-r--r--dw/ruler.cc1
-rw-r--r--dw/style.cc453
-rw-r--r--dw/style.hh24
-rw-r--r--dw/table.cc1
-rw-r--r--dw/textblock.cc48
-rw-r--r--dw/types.cc74
-rw-r--r--dw/ui.cc14
-rw-r--r--dw/ui.hh2
-rw-r--r--dw/view.hh4
-rw-r--r--dw/widget.cc13
-rw-r--r--dw/widget.hh6
-rw-r--r--lout/Makefile.am3
-rw-r--r--lout/misc.hh5
-rw-r--r--lout/object.cc1
-rw-r--r--src/IO/Makefile.am4
-rw-r--r--src/IO/mime.c1
-rw-r--r--src/cache.c14
-rw-r--r--src/capi.c14
-rw-r--r--src/cookies.h1
-rw-r--r--src/css.cc34
-rw-r--r--src/css.hh22
-rw-r--r--src/cssparser.cc205
-rw-r--r--src/cssparser.hh3
-rw-r--r--src/dillo.cc1
-rw-r--r--src/form.cc9
-rw-r--r--src/gif.c14
-rw-r--r--src/html.cc355
-rw-r--r--src/html_common.hh14
-rw-r--r--src/jpeg.c3
-rw-r--r--src/misc.c7
-rw-r--r--src/nav.c4
-rw-r--r--src/png.c22
-rw-r--r--src/prefs.c1
-rw-r--r--src/prefs.h1
-rw-r--r--src/prefsparser.cc7
-rw-r--r--src/styleengine.cc290
-rw-r--r--src/styleengine.hh49
-rw-r--r--src/table.cc249
-rw-r--r--src/uicmd.cc12
-rw-r--r--src/url.c1
-rw-r--r--src/url.h1
-rw-r--r--src/web.cc15
-rw-r--r--test/Makefile.am130
73 files changed, 1928 insertions, 997 deletions
diff --git a/.hgignore b/.hgignore
index cac1f7df..35198815 100644
--- a/.hgignore
+++ b/.hgignore
@@ -1,46 +1,40 @@
(^|/)CVS($|/)
(^|/)\.hg($|/)
(^|/)\.deps($|/)
-(^|/)\html($|/)
-.*\.a
-.*\.o
-config\..*
-autom4te.cache
-Makefile
-Makefile.in
-configure
-aclocal.m4
-depcomp
-install-sh
-stamp-h1
-missing
-tags
-dillo
-d_size.h
-dpi/bookmarks.dpi
-dpi/cookies.dpi
-dpi/datauri.filter.dpi
-dpi/downloads.dpi
-dpi/file.dpi
-dpi/ftp.filter.dpi
-dpi/hello.filter.dpi
-dpi/https.filter.dpi
-dpid/dpid
-test/cookies
-test/dw-anchors-test
-test/dw-border-test
-test/dw-example
-test/dw-find-test
-test/dw-images-scaled
-test/dw-images-scaled2
-test/dw-images-simple
-test/dw-imgbuf-mem-test
-test/dw-links
-test/dw-links2
-test/dw-lists
-test/dw-resource-test
-test/dw-table
-test/dw-table-aligned
-test/dw-ui-test
-test/fltk-browser
-test/shapes
+(^|/)html($|/)
+\.a$
+\.o$
+^config\.
+^autom4te\.cache$
+(^|/)Makefile$
+(^|/)Makefile\.in$
+^configure$
+^aclocal\.m4$
+^depcomp$
+^install-sh$
+^stamp-h1$
+^missing$
+(^|/)tags$
+^src/dillo$
+^dpi/[^/]*\.dpi$
+^dpid/dpid$
+^dpid/dpidc$
+^dpid/dpidrc$
+^test/cookies$
+^test/dw-anchors-test$
+^test/dw-border-test$
+^test/dw-example$
+^test/dw-find-test$
+^test/dw-images-scaled$
+^test/dw-images-scaled2$
+^test/dw-images-simple$
+^test/dw-imgbuf-mem-test$
+^test/dw-links$
+^test/dw-links2$
+^test/dw-lists$
+^test/dw-resource-test$
+^test/dw-table$
+^test/dw-table-aligned$
+^test/dw-ui-test$
+^test/fltk-browser$
+^test/shapes$
diff --git a/ChangeLog b/ChangeLog
index 911a715f..febfd507 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,7 +5,10 @@ Dillo project
dillo-2.2.1 [not released yet]
+- Implemented "View source" as a dpi.
- Patch: Jorge Arellano Cid
+ - Accept application/xhtml+xml.
+ - Small caps support.
+ - Border-collapse, border-style properties.
+ Patches: Jorge Arellano Cid
+- Configurable User-Agent HTTP header.
Patch: Alexander Voigt, corvid
+- Include Accept header in HTTP queries.
@@ -19,9 +22,20 @@ dillo-2.2.1 [not released yet]
- Handle white-space: pre-wrap and pre-line.
- Support for the word-spacing property.
- Fix segfault with https and self-signed certificates.
+ - Text-indent property.
Patches: corvid
++- Reintroduce bg_color dillorc option.
+ - Make Dillo compile with Clang.
+ - Fix Textblock flushing.
+ Patches: Johannes Hofmann
+- Implement line-height.
- Patch: Johannes Hofmann, corvid
+ - Draw image maps when image not loaded.
+ Patches: Johannes Hofmann, corvid
++- Support @media rules.
+ - Implement media-conditional @import rules.
+ - Configure/Makefile cleanup.
+ - Fix meta refresh looping.
+ Patches: Jeremy Henty
-----------------------------------------------------------------------------
diff --git a/Makefile.am b/Makefile.am
index 52acc2af..3cc1a098 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,5 +1,5 @@
SUBDIRS = lout dw dlib dpip src doc dpid dpi test
-EXTRA_DIST = Doxyfile dillorc install-dpi-local
+EXTRA_DIST = Doxyfile dillorc install-dpi-local d_size.h
sysconf_DATA = dillorc
diff --git a/config.h.in b/config.h.in
index 54501855..371d658f 100644
--- a/config.h.in
+++ b/config.h.in
@@ -105,8 +105,29 @@
/* Version number of package */
#undef VERSION
+/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+ #define below would cause a syntax error. */
+#undef _UINT32_T
+
/* Use char pointers for newer libiconv */
#undef inbuf_t
+/* Define to the type of a signed integer type of width exactly 16 bits if
+ such a type exists and the standard includes do not define it. */
+#undef int16_t
+
+/* Define to the type of a signed integer type of width exactly 32 bits if
+ such a type exists and the standard includes do not define it. */
+#undef int32_t
+
/* Define the real type of socklen_t */
#undef socklen_t
+
+/* Define to the type of an unsigned integer type of width exactly 16 bits if
+ such a type exists and the standard includes do not define it. */
+#undef uint16_t
+
+/* Define to the type of an unsigned integer type of width exactly 32 bits if
+ such a type exists and the standard includes do not define it. */
+#undef uint32_t
diff --git a/configure.in b/configure.in
index a7fef723..6ddf8642 100644
--- a/configure.in
+++ b/configure.in
@@ -1,12 +1,14 @@
dnl Process this file with aclocal, autoconf and automake.
-AC_INIT(src/dillo.cc)
+AC_INIT([dillo], [2.2])
-dnl Detect the canonical host and target build environment
-AC_CANONICAL_SYSTEM
+dnl Detect the canonical target build environment
+AC_CANONICAL_TARGET
+
+AM_INIT_AUTOMAKE
+AC_CONFIG_SRCDIR([src/dillo.cc])
+AC_CONFIG_HEADERS([config.h])
-AM_INIT_AUTOMAKE(dillo, 2.2)
-AM_CONFIG_HEADER(config.h)
sysconfdir=${sysconfdir}/${PACKAGE}
dnl Options
@@ -38,7 +40,6 @@ AC_ARG_ENABLE(threaded-dns,[ --disable-threaded-dns Disable the advantage of a
AC_ARG_ENABLE(rtfl, [ --enable-rtfl Build with rtfl messages])
AC_PROG_CC
AC_PROG_CXX
-AM_PROG_CC_STDC
AC_PROG_RANLIB
AC_PROG_CPP
@@ -52,43 +53,10 @@ AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(void *)
-case 2 in
-$ac_cv_sizeof_short) gint16=short;;
-$ac_cv_sizeof_int) gint16=int;;
-esac
-case 4 in
-$ac_cv_sizeof_short) gint32=short;;
-$ac_cv_sizeof_int) gint32=int;;
-$ac_cv_sizeof_long) gint32=long;;
-esac
-
-cat >d_size.h <<_______EOF
-#ifndef __D_SIZE_H__
-#define __D_SIZE_H__
-
-
-#include "config.h"
-
-#if HAVE_STDINT_H == 0
-#include <stdint.h>
-#elif defined(HAVE_INTTYPES_H)
-#include <inttypes.h>
-#else
-typedef signed $gint16 int16_t;
-typedef unsigned $gint16 uint16_t;
-typedef signed $gint32 int32_t;
-typedef unsigned $gint32 uint32_t;
-#endif
-typedef unsigned char uchar_t;
-typedef unsigned short ushort_t;
-typedef unsigned long ulong_t;
-typedef unsigned int uint_t;
-typedef unsigned char bool_t;
-
-
-#endif /* __D_SIZE_H__ */
-_______EOF
-
+AC_TYPE_INT16_T
+AC_TYPE_UINT16_T
+AC_TYPE_INT32_T
+AC_TYPE_UINT32_T
dnl --------------------------------------
dnl Check whether to add /usr/local or not
@@ -114,21 +82,21 @@ dnl --------------------
dnl
AC_MSG_CHECKING([for socklen_t])
ac_cv_socklen_t=""
-AC_TRY_COMPILE([
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <sys/socket.h>
-],[
+]],[[
socklen_t a=0;
getsockname(0,(struct sockaddr*)0, &a);
-],
+]])],
ac_cv_socklen_t="socklen_t",
-AC_TRY_COMPILE([
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <sys/socket.h>
-],[
+]],[[
int a=0;
getsockname(0,(struct sockaddr*)0, &a);
-],
+]])],
ac_cv_socklen_t="int",
ac_cv_socklen_t="size_t"
)
@@ -150,9 +118,9 @@ if sh -c "fltk2-config --version" >/dev/null 2>&1
then AC_MSG_RESULT(yes)
LIBFLTK_CXXFLAGS=`fltk2-config --cxxflags`
LIBFLTK_CFLAGS=`fltk2-config --cflags`
- LIBFLTK_LIBS=`fltk2-config --use-images --ldflags`
+ LIBFLTK_LIBS=`fltk2-config --ldflags`
else AC_MSG_RESULT(no)
- AC_ERROR(FLTK2 must be installed!)
+ AC_MSG_ERROR(FLTK2 must be installed!)
fi
@@ -201,7 +169,7 @@ fi
if test "x$libz_ok" = xyes; then
LIBZ_LIBS="-lz"
else
- AC_ERROR(zlib must be installed!)
+ AC_MSG_ERROR(zlib must be installed!)
fi
dnl ---------------
@@ -317,8 +285,12 @@ if test "x$iconv_ok" = "xno"; then
dnl Test for OpenBSD
old_libs="$LIBS"
LIBS="$old_libs -liconv"
- AC_TRY_COMPILE([#include <iconv.h>],[iconv_open("","");],
- iconv_ok=yes, iconv_ok=no)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <iconv.h>
+]],[[
+iconv_open("","");
+]])],
+iconv_ok=yes,iconv_ok=no)
LIBS="$old_libs"
if test "x$iconv_ok" = "xyes"; then
LIBICONV_LIBS="-liconv"
@@ -326,7 +298,7 @@ if test "x$iconv_ok" = "xno"; then
fi
if test "x$iconv_ok" = "xno"; then
- AC_ERROR(libiconv must be installed!)
+ AC_MSG_ERROR(libiconv must be installed!)
fi
dnl ----------------------
@@ -340,14 +312,15 @@ if test "x$iconv_ok" = "xyes"; then
old_cflags="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
AC_LANG_PUSH([C++])
- AC_TRY_COMPILE([#include <iconv.h>],
-[
- const char *inPtr;
- char *outPtr;
- size_t inLeft = 0, outRoom = 0;
- iconv_t encoder = iconv_open("ASCII", "UTF-8");
- iconv(encoder, &inPtr, &inLeft, &outPtr, &outRoom);
-],
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <iconv.h>
+]],[[
+const char *inPtr;
+char *outPtr;
+size_t inLeft = 0, outRoom = 0;
+iconv_t encoder = iconv_open("ASCII", "UTF-8");
+iconv(encoder, &inPtr, &inLeft, &outPtr, &outRoom);
+]])],
iconv_old=yes,iconv_old=no)
AC_LANG_POP([C++])
LIBS="$old_libs"
@@ -386,7 +359,8 @@ case $target in
AC_MSG_CHECKING(whether threads work with -pthread)
LDSAVEFLAGS=$LDFLAGS
LDFLAGS="$LDFLAGS -pthread"
- AC_TRY_LINK_FUNC(pthread_create, pthread_ok=yes, pthread_ok=no)
+ AC_LINK_IFELSE([AC_LANG_CALL([],[pthread_create])],
+pthread_ok=yes, pthread_ok=no)
LDFLAGS=$LDSAVEFLAGS
if test "x$pthread_ok" = "xyes"; then
@@ -448,7 +422,6 @@ dnl -----------------------
dnl Checks for header files
dnl -----------------------
dnl
-AC_HEADER_STDC
AC_CHECK_HEADERS(fcntl.h unistd.h sys/uio.h)
dnl --------------------------
@@ -511,5 +484,18 @@ AC_SUBST(LIBFLTK_LIBS)
AC_SUBST(LIBICONV_LIBS)
AC_SUBST(datadir)
-AC_OUTPUT(Makefile dlib/Makefile dpip/Makefile dpid/Makefile dpi/Makefile doc/Makefile dw/Makefile lout/Makefile src/Makefile src/IO/Makefile test/Makefile)
-
+AC_CONFIG_FILES([
+ Makefile
+ dlib/Makefile
+ dpip/Makefile
+ dpid/Makefile
+ dpi/Makefile
+ doc/Makefile
+ dw/Makefile
+ lout/Makefile
+ src/Makefile
+ src/IO/Makefile
+ test/Makefile
+])
+
+AC_OUTPUT
diff --git a/d_size.h b/d_size.h
new file mode 100644
index 00000000..2e2019e7
--- /dev/null
+++ b/d_size.h
@@ -0,0 +1,24 @@
+#ifndef __D_SIZE_H__
+#define __D_SIZE_H__
+
+
+#include "config.h"
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#else
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#else
+/* config.h defines {int,uint}*_t */
+#endif /* HAVE_INTTYPES_H */
+#endif /*HAVE_STDINT_H */
+
+typedef unsigned char uchar_t;
+typedef unsigned short ushort_t;
+typedef unsigned long ulong_t;
+typedef unsigned int uint_t;
+typedef unsigned char bool_t;
+
+
+#endif /* __D_SIZE_H__ */
diff --git a/dillorc b/dillorc
index ba132ba0..fccb7932 100644
--- a/dillorc
+++ b/dillorc
@@ -112,7 +112,7 @@
# "%s" is replaced with the search keywords separated by '+'.
# search_url="http://www.wikipedia.org/wiki/Special:Search?search=%s"
# search_url="http://search.lycos.com/?query=%s"
-# search_url="http://www.alltheweb.com/search?cat=web&query=%s"
+# search_url="http://duckduckgo.com/html?q=%s"
#search_url="http://www.google.com/search?ie=UTF-8&oe=UTF-8&q=%s"
# If set, dillo will ask web servers to send pages in this language.
@@ -170,6 +170,11 @@
# COLORS SECTION
#-------------------------------------------------------------------------
+# Set the background color
+# bg_color=gray
+# bg_color=0xd6d6c0
+#bg_color=0xdcd1ba
+
# If your eyes suffer with white backgrounds, change this.
#allow_white_bg=YES
diff --git a/dlib/Makefile.am b/dlib/Makefile.am
index 378cd785..0d44c139 100644
--- a/dlib/Makefile.am
+++ b/dlib/Makefile.am
@@ -1,6 +1,8 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir)
+
noinst_LIBRARIES = libDlib.a
libDlib_a_SOURCES = \
dlib.h \
dlib.c
-
diff --git a/doc/README b/doc/README
index 8b0a8d63..8af9a877 100644
--- a/doc/README
+++ b/doc/README
@@ -47,5 +47,5 @@ Jorge.-
* Please submit your patches with 'hg diff'.
- Happy coding!
+ Happy coding!
--Jcid
diff --git a/doc/dillo.1 b/doc/dillo.1
index 6e96cf99..2342d76a 100644
--- a/doc/dillo.1
+++ b/doc/dillo.1
@@ -61,38 +61,38 @@ User's home directory.
URL of proxy to send HTTP traffic through.
.SH FILES
.TP
-.I dpid
+.I dpid
Dillo plugin daemon
.TP
-.I dpidc
+.I dpidc
Control program for dpid.
.TP
-.I ~/.dillo/bm.txt
+.I ~/.dillo/bm.txt
User bookmarks
.TP
.I ~/.dillo/certs/
Saved certificates for HTTPS.
.TP
-.I ~/.dillo/cookies.txt
+.I ~/.dillo/cookies.txt
Stored cookies
.TP
-.I ~/.dillo/cookiesrc
+.I ~/.dillo/cookiesrc
Cookie settings
.TP
-.I ~/.dillo/dillorc
+.I ~/.dillo/dillorc
Configuration file.
.TP
.I ~/.dillo/dpid_comm_keys
Keys used in dpi daemon communication.
.TP
-.I ~/.dillo/dpidrc
+.I ~/.dillo/dpidrc
Contains name of directory containing dpis, and associates
dpi files with protocols.
.TP
-.I ~/.dillo/keysrc
+.I ~/.dillo/keysrc
Keybindings.
.TP
-.I ~/.dillo/style.css
+.I ~/.dillo/style.css
User style sheet
.SH SEE ALSO
.BR wget (1)
diff --git a/doc/dw-layout-widgets.doc b/doc/dw-layout-widgets.doc
index d488efd8..e0215562 100644
--- a/doc/dw-layout-widgets.doc
+++ b/doc/dw-layout-widgets.doc
@@ -5,7 +5,7 @@ widgets. A widget represents a given part of the document, e.g. a text
block, a table, or an image. Widgets may be nested, so layouting and
drawing may be delegated by one widget to its child widgets.
-Where do define the borders of a widget, wheather to combine different
+Where to define the borders of a widget, whether to combine different
widgets to one, or to split one widget into multiple ones, should be
considered based on different concerns:
@@ -22,7 +22,7 @@ considered based on different concerns:
<li> Since some widgets are already rather complex, an important goal
is to keep the implementation of the widget simple.
-<li> Furthermore, the granularity should not be to fine, because of the
+<li> Furthermore, the granularity should not be too fine, because of the
overhead each single widget adds.
</ul>
diff --git a/doc/dw-usage.doc b/doc/dw-usage.doc
index 913a4862..32080d74 100644
--- a/doc/dw-usage.doc
+++ b/doc/dw-usage.doc
@@ -222,7 +222,7 @@ called, within timeouts, idles, I/O functions etc. Notice that Dw is
not thread safe, so that everything should be done within one thread.
With the exception, that you have to call dw::Textblock::flush,
-everything gets imediately visible, within reasonable times; Dw has
+everything gets immediately visible, within reasonable times; Dw has
been optimized for frequent updates.
diff --git a/doc/dw-widget-sizes.doc b/doc/dw-widget-sizes.doc
index c93ce541..419a4a73 100644
--- a/doc/dw-widget-sizes.doc
+++ b/doc/dw-widget-sizes.doc
@@ -41,7 +41,7 @@ In the example in the image, the widget has the following allocation:
The current allocation of a widget is hold in
dw::core::Widget::allocation. It can be set from outside by
-callcalling dw::core::Widget::sizeAllocate. This is a concrete method,
+calling dw::core::Widget::sizeAllocate. This is a concrete method,
which will call dw::core::Widget::sizeAllocateImpl (see code of
dw::core::Widget::sizeAllocate for details).
@@ -93,7 +93,7 @@ Some widgets do not have an inherent size, but depend on the context,
e.g. the viewport size. These widgets should adhere to <i>size hints</i>,
i.e. implement the methods dw::core::Widget::setWidth,
dw::core::Widget::setAscent and dw::core::Widget::setDescent. The values
-passed to the calles are
+passed to the callees are
<ul>
<li> the viewport size (ascent is the heigt here, while descent is 0) for
diff --git a/doc/user_help.html b/doc/user_help.html
index 296b0c5a..91dc748f 100644
--- a/doc/user_help.html
+++ b/doc/user_help.html
@@ -41,7 +41,7 @@
</ul>
</td></tr>
</table>
-
+
<table WIDTH="100%" BORDER=1 CELLSPACING=0 CELLPADDING=3>
<tr ALIGN=LEFT VALIGN=TOP><td bgcolor="wheat">
<h4><font color="green">Usage:</font></h4>
@@ -61,8 +61,8 @@
<li> <b>Configuration:</b> If you want to change Dillo's
appearance or behaviour, look at the options in your
<b><font color="#5040a0">dillorc</font></b>
- file (if you don't have a copy in your ~/.dillo/ directory, get it
- <a href='http://www.dillo.org/dillorc'>here</a>).
+ file (if you don't have a copy in your ~/.dillo/ directory, get it
+ <a href='http://www.dillo.org/dillorc'>here</a>).
<li> Clicking the "Reload" button always requests an end-to-end reload
of the page currently viewed, but it will *not* reload embedded
images during this process.
@@ -224,7 +224,7 @@
(<a href='http://www.dillo.org/dpi1.html'>dpi</a>) framework.
This should be transparent to the end user. Please note that:
<ul>
- <li>It is a good idea to keep a backup of your
+ <li>It is a good idea to keep a backup of your
<code>~/.dillo/bm.txt</code>
<li>The server will stay alive after closing dillo.
<li>You can stop the server by sending it a KILL signal. Dillo
diff --git a/dpi/Makefile.am b/dpi/Makefile.am
index 34e07483..ade14854 100644
--- a/dpi/Makefile.am
+++ b/dpi/Makefile.am
@@ -1,3 +1,6 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir)
+
bookmarksdir = $(libdir)/dillo/dpi/bookmarks
downloadsdir = $(libdir)/dillo/dpi/downloads
ftpdir = $(libdir)/dillo/dpi/ftp
@@ -17,15 +20,33 @@ file_PROGRAMS = file.dpi
cookies_PROGRAMS = cookies.dpi
datauri_PROGRAMS = datauri.filter.dpi
-bookmarks_dpi_LDADD = ../dpip/libDpip.a ../dlib/libDlib.a
-downloads_dpi_LDADD = @LIBFLTK_LIBS@ ../dpip/libDpip.a ../dlib/libDlib.a
-ftp_filter_dpi_LDADD = ../dpip/libDpip.a ../dlib/libDlib.a
-https_filter_dpi_LDADD = @LIBSSL_LIBS@ ../dpip/libDpip.a ../dlib/libDlib.a
-hello_filter_dpi_LDADD = ../dpip/libDpip.a ../dlib/libDlib.a
-vsource_filter_dpi_LDADD = ../dpip/libDpip.a ../dlib/libDlib.a
-file_dpi_LDADD = ../dpip/libDpip.a ../dlib/libDlib.a
-cookies_dpi_LDADD = ../dpip/libDpip.a ../dlib/libDlib.a
-datauri_filter_dpi_LDADD = ../dpip/libDpip.a ../dlib/libDlib.a
+bookmarks_dpi_LDADD = \
+ $(top_builddir)/dpip/libDpip.a \
+ $(top_builddir)/dlib/libDlib.a
+downloads_dpi_LDADD = @LIBFLTK_LIBS@ \
+ $(top_builddir)/dpip/libDpip.a \
+ $(top_builddir)/dlib/libDlib.a
+ftp_filter_dpi_LDADD = \
+ $(top_builddir)/dpip/libDpip.a \
+ $(top_builddir)/dlib/libDlib.a
+https_filter_dpi_LDADD = @LIBSSL_LIBS@ \
+ $(top_builddir)/dpip/libDpip.a \
+ $(top_builddir)/dlib/libDlib.a
+hello_filter_dpi_LDADD = \
+ $(top_builddir)/dpip/libDpip.a \
+ $(top_builddir)/dlib/libDlib.a
+vsource_filter_dpi_LDADD = \
+ $(top_builddir)/dpip/libDpip.a \
+ $(top_builddir)/dlib/libDlib.a
+file_dpi_LDADD = \
+ $(top_builddir)/dpip/libDpip.a \
+ $(top_builddir)/dlib/libDlib.a
+cookies_dpi_LDADD = \
+ $(top_builddir)/dpip/libDpip.a \
+ $(top_builddir)/dlib/libDlib.a
+datauri_filter_dpi_LDADD = \
+ $(top_builddir)/dpip/libDpip.a \
+ $(top_builddir)/dlib/libDlib.a
downloads_dpi_CXXFLAGS = @LIBFLTK_CXXFLAGS@
diff --git a/dpi/bookmarks.c b/dpi/bookmarks.c
index 58fc59f5..6e9cb3df 100644
--- a/dpi/bookmarks.c
+++ b/dpi/bookmarks.c
@@ -1628,16 +1628,19 @@ static int Bmsrv_parse_token(Dsh *sh, char *Buf)
if (strcmp(url, "dpi:/bm/modify") == 0) {
st = Bmsrv_send_modify_answer(sh, url);
+ dFree(url);
return st;
} else if (strncmp(url, "dpi:/bm/modify?", 15) == 0) {
/* process request */
st = Bmsrv_process_modify_request(sh, url);
+ dFree(url);
return st;
}
d_cmd = a_Dpip_build_cmd("cmd=%s url=%s", "start_send_page", url);
+ dFree(url);
st = a_Dpip_dsh_write_str(sh, 1, d_cmd);
dFree(d_cmd);
if (st != 0)
diff --git a/dpi/downloads.cc b/dpi/downloads.cc
index 5aa7a87c..1a70d235 100644
--- a/dpi/downloads.cc
+++ b/dpi/downloads.cc
@@ -72,33 +72,33 @@ typedef enum {
// class FL_API ProgressBar : public Widget {
class ProgressBar : public Widget {
protected:
- double mMin;
- double mMax;
- double mPresent;
- double mStep;
- bool mShowPct, mShowMsg;
- char mMsg[64];
- Color mTextColor;
- void draw();
+ double mMin;
+ double mMax;
+ double mPresent;
+ double mStep;
+ bool mShowPct, mShowMsg;
+ char mMsg[64];
+ Color mTextColor;
+ void draw();
public:
- ProgressBar(int x, int y, int w, int h, const char *lbl = 0);
- void range(double min, double max, double step = 1) {
- mMin = min; mMax = max; mStep = step;
- };
- void step(double step) { mPresent += step; redraw(); };
- void move(double step);
- double minimum() { return mMin; }
- double maximum() { return mMax; }
- void minimum(double nm) { mMin = nm; };
- void maximum(double nm) { mMax = nm; };
- double position () { return mPresent; }
- double step() { return mStep; }
- void position(double pos) { mPresent = pos; redraw(); }
- void showtext(bool st) { mShowPct = st; }
- void message(char *msg) { mShowMsg = true; strncpy(mMsg,msg,63); redraw(); }
- bool showtext() { return mShowPct; }
- void text_color(Color col) { mTextColor = col; }
- Color text_color() { return mTextColor; }
+ ProgressBar(int x, int y, int w, int h, const char *lbl = 0);
+ void range(double min, double max, double step = 1) {
+ mMin = min; mMax = max; mStep = step;
+ };
+ void step(double step) { mPresent += step; redraw(); };
+ void move(double step);
+ double minimum() { return mMin; }
+ double maximum() { return mMax; }
+ void minimum(double nm) { mMin = nm; };
+ void maximum(double nm) { mMax = nm; };
+ double position () { return mPresent; }
+ double step() { return mStep; }
+ void position(double pos) { mPresent = pos; redraw(); }
+ void showtext(bool st) { mShowPct = st; }
+ void message(char *msg) { mShowMsg = true; strncpy(mMsg,msg,63); redraw(); }
+ bool showtext() { return mShowPct; }
+ void text_color(Color col) { mTextColor = col; }
+ Color text_color() { return mTextColor; }
};
// Download-item class -------------------------------------------------------
@@ -261,7 +261,7 @@ void ProgressBar::draw()
} else {
Rectangle r2(int (r.w() * pct), 0, int (w() * .1), h());
push_clip(r2);
- fillrect(r);
+ fillrect(r);
pop_clip();
}
@@ -318,6 +318,8 @@ DLItem::DLItem(const char *full_filename, const char *url, DLAction action)
// Init value. Reset later, upon the first data bytes arrival
init_time = time(NULL);
+ twosec_time = onesec_time = init_time;
+
// BUG:? test a URL with ' inside.
/* escape "'" character for the shell. Is it necessary? */
esc_url = Escape_uri_str(url, "'");
@@ -349,71 +351,72 @@ DLItem::DLItem(const char *full_filename, const char *url, DLAction action)
gw = 400, gh = 70;
group = new Group(0,0,gw,gh);
group->begin();
- prTitle = new Widget(24, 7, 290, 23, shortname);
- prTitle->box(RSHADOW_BOX);
- prTitle->align(ALIGN_LEFT|ALIGN_INSIDE|ALIGN_CLIP);
- // Attach this 'log_text' to the tooltip
- log_text_add("Target File: ", 13);
- log_text_add(fullname, strlen(fullname));
- log_text_add("\n\n", 2);
-
- prBar = new ProgressBar(24, 40, 92, 20);
- prBar->box(BORDER_BOX); // ENGRAVED_BOX
- prBar->tooltip("Progress Status");
-
- int ix = 122, iy = 36, iw = 50, ih = 14;
- Widget *o = new Widget(ix,iy,iw,ih, "Got");
- o->box(RFLAT_BOX);
- o->color((Color)0xc0c0c000);
- o->tooltip("Downloaded Size");
- prGot = new Widget(ix,iy+14,iw,ih, "0KB");
- prGot->align(ALIGN_CENTER|ALIGN_INSIDE);
- prGot->labelcolor((Color)0x6c6cbd00);
- prGot->box(NO_BOX);
-
- ix += iw;
- o = new Widget(ix,iy,iw,ih, "Size");
- o->box(RFLAT_BOX);
- o->color((Color)0xc0c0c000);
- o->tooltip("Total Size");
- prSize = new Widget(ix,iy+14,iw,ih, "??");
- prSize->align(ALIGN_CENTER|ALIGN_INSIDE);
- prSize->box(NO_BOX);
-
- ix += iw;
- o = new Widget(ix,iy,iw,ih, "Rate");
- o->box(RFLAT_BOX);
- o->color((Color)0xc0c0c000);
- o->tooltip("Current transfer Rate (KBytes/sec)");
- prRate = new Widget(ix,iy+14,iw,ih, "??");
- prRate->align(ALIGN_CENTER|ALIGN_INSIDE);
- prRate->box(NO_BOX);
-
- ix += iw;
- o = new Widget(ix,iy,iw,ih, "~Rate");
- o->box(RFLAT_BOX);
- o->color((Color)0xc0c0c000);
- o->tooltip("Average transfer Rate (KBytes/sec)");
- pr_Rate = new Widget(ix,iy+14,iw,ih, "??");
- pr_Rate->align(ALIGN_CENTER|ALIGN_INSIDE);
- pr_Rate->box(NO_BOX);
-
- ix += iw;
- prETAt = o = new Widget(ix,iy,iw,ih, "ETA");
- o->box(RFLAT_BOX);
- o->color((Color)0xc0c0c000);
- o->tooltip("Estimated Time of Arrival");
- prETA = new Widget(ix,iy+14,iw,ih, "??");
- prETA->align(ALIGN_CENTER|ALIGN_INSIDE);
- prETA->box(NO_BOX);
-
- //ix += 50;
- //prButton = new HighlightButton(ix, 41, 38, 19, "Stop");
- prButton = new HighlightButton(328, 9, 38, 19, "Stop");
- prButton->tooltip("Stop this transfer");
- prButton->box(UP_BOX);
- prButton->clear_tab_to_focus();
- prButton->callback(prButton_scb, this);
+ prTitle = new Widget(24, 7, 290, 23, shortname);
+ prTitle->box(RSHADOW_BOX);
+ prTitle->align(ALIGN_LEFT|ALIGN_INSIDE|ALIGN_CLIP);
+ prTitle->set_flag (RAW_LABEL);
+ // Attach this 'log_text' to the tooltip
+ log_text_add("Target File: ", 13);
+ log_text_add(fullname, strlen(fullname));
+ log_text_add("\n\n", 2);
+
+ prBar = new ProgressBar(24, 40, 92, 20);
+ prBar->box(BORDER_BOX); // ENGRAVED_BOX
+ prBar->tooltip("Progress Status");
+
+ int ix = 122, iy = 36, iw = 50, ih = 14;
+ Widget *o = new Widget(ix,iy,iw,ih, "Got");
+ o->box(RFLAT_BOX);
+ o->color((Color)0xc0c0c000);
+ o->tooltip("Downloaded Size");
+ prGot = new Widget(ix,iy+14,iw,ih, "0KB");
+ prGot->align(ALIGN_CENTER|ALIGN_INSIDE);
+ prGot->labelcolor((Color)0x6c6cbd00);
+ prGot->box(NO_BOX);
+
+ ix += iw;
+ o = new Widget(ix,iy,iw,ih, "Size");
+ o->box(RFLAT_BOX);
+ o->color((Color)0xc0c0c000);
+ o->tooltip("Total Size");
+ prSize = new Widget(ix,iy+14,iw,ih, "??");
+ prSize->align(ALIGN_CENTER|ALIGN_INSIDE);
+ prSize->box(NO_BOX);
+
+ ix += iw;
+ o = new Widget(ix,iy,iw,ih, "Rate");
+ o->box(RFLAT_BOX);
+ o->color((Color)0xc0c0c000);
+ o->tooltip("Current transfer Rate (KBytes/sec)");
+ prRate = new Widget(ix,iy+14,iw,ih, "??");
+ prRate->align(ALIGN_CENTER|ALIGN_INSIDE);
+ prRate->box(NO_BOX);
+
+ ix += iw;
+ o = new Widget(ix,iy,iw,ih, "~Rate");
+ o->box(RFLAT_BOX);
+ o->color((Color)0xc0c0c000);
+ o->tooltip("Average transfer Rate (KBytes/sec)");
+ pr_Rate = new Widget(ix,iy+14,iw,ih, "??");
+ pr_Rate->align(ALIGN_CENTER|ALIGN_INSIDE);
+ pr_Rate->box(NO_BOX);
+
+ ix += iw;
+ prETAt = o = new Widget(ix,iy,iw,ih, "ETA");
+ o->box(RFLAT_BOX);
+ o->color((Color)0xc0c0c000);
+ o->tooltip("Estimated Time of Arrival");
+ prETA = new Widget(ix,iy+14,iw,ih, "??");
+ prETA->align(ALIGN_CENTER|ALIGN_INSIDE);
+ prETA->box(NO_BOX);
+
+ //ix += 50;
+ //prButton = new HighlightButton(ix, 41, 38, 19, "Stop");
+ prButton = new HighlightButton(328, 9, 38, 19, "Stop");
+ prButton->tooltip("Stop this transfer");
+ prButton->box(UP_BOX);
+ prButton->clear_tab_to_focus();
+ prButton->callback(prButton_scb, this);
group->box(ROUND_UP_BOX);
group->end();
@@ -593,7 +596,7 @@ void DLItem::update_size(int new_sz)
static void read_log_cb(int fd_in, void *data)
{
DLItem *dl_item = (DLItem *)data;
- int BufLen = 4096;
+ const int BufLen = 4096;
char Buf[BufLen];
ssize_t st;
int ret = -1;
@@ -919,7 +922,7 @@ static void read_req_cb(int req_fd, void *)
}
action = dl_win->check_filename(&dl_dest);
if (action != DL_ABORT) {
- // Start the whole thing whithin FLTK.
+ // Start the whole thing within FLTK.
dl_win->add(dl_dest, url, action);
} else if (dl_win->num() == 0) {
exit(0);
@@ -1077,13 +1080,13 @@ DLWin::DLWin(int ww, int wh) {
// Create the empty main window
mWin = new Window(ww, wh, "Downloads:");
mWin->begin();
- mScroll = new ScrollGroup(0,0,ww,wh);
- mScroll->begin();
- mPG = new PackedGroup(0,0,ww,wh);
- mPG->end();
- //mPG->spacing(10);
- mScroll->end();
- mScroll->type(ScrollGroup::VERTICAL);
+ mScroll = new ScrollGroup(0,0,ww,wh);
+ mScroll->begin();
+ mPG = new PackedGroup(0,0,ww,wh);
+ mPG->end();
+ //mPG->spacing(10);
+ mScroll->end();
+ mScroll->type(ScrollGroup::VERTICAL);
mWin->end();
mWin->resizable(mScroll);
mWin->callback(dlwin_esc_cb, NULL);
diff --git a/dpi/file.c b/dpi/file.c
index 1e70e9ef..64f06bf5 100644
--- a/dpi/file.c
+++ b/dpi/file.c
@@ -478,12 +478,10 @@ static void File_send_dir(ClientInfo *client)
File_info2html(client, dList_nth_data(Ddir->flist,n), n+1);
}
- if (dList_length(Ddir->flist)) {
- if (client->old_style) {
- a_Dpip_dsh_write_str(client->sh, 0, "</pre>\n");
- } else {
- a_Dpip_dsh_write_str(client->sh, 0, "</table>\n");
- }
+ if (client->old_style) {
+ a_Dpip_dsh_write_str(client->sh, 0, "</pre>\n");
+ } else if (dList_length(Ddir->flist)) {
+ a_Dpip_dsh_write_str(client->sh, 0, "</table>\n");
}
a_Dpip_dsh_write_str(client->sh, 1, "</BODY></HTML>\n");
diff --git a/dpi/https.c b/dpi/https.c
index 3f474b81..71b0c0f9 100644
--- a/dpi/https.c
+++ b/dpi/https.c
@@ -409,6 +409,9 @@ static int get_network_connection(char * url)
* allow the user to decide what to do. It may save the
* certificate to the user's .dillo directory if it is
* trusted.
+ *
+ * TODO: Rearrange this to get rid of redundancy.
+ *
* Return value: -1 on abort, 0 or higher on continue
*/
static int handle_certificate_problem(SSL * ssl_connection)
@@ -613,6 +616,40 @@ static int handle_certificate_problem(SSL * ssl_connection)
"Continue", "Cancel");
a_Dpip_dsh_write_str(sh, 1, d_cmd);
dFree(d_cmd);
+ response_number = dialog_get_answer_number();
+ if (response_number == 1) {
+ ret = 0;
+ }
+ break;
+ case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
+ d_cmd = a_Dpip_build_cmd(
+ "cmd=%s msg=%s alt1=%s alt2=%s",
+ "dialog",
+ "Self signed certificate in certificate chain. The certificate "
+ "chain could be built up using the untrusted certificates but the "
+ "root could not be found locally.",
+ "Continue", "Cancel");
+ a_Dpip_dsh_write_str(sh, 1, d_cmd);
+ dFree(d_cmd);
+ response_number = dialog_get_answer_number();
+ if (response_number == 1) {
+ ret = 0;
+ }
+ break;
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
+ d_cmd = a_Dpip_build_cmd(
+ "cmd=%s msg=%s alt1=%s alt2=%s",
+ "dialog",
+ "Unable to get local issuer certificate. The issuer certificate "
+ "of an untrusted certificate cannot be found.",
+ "Continue", "Cancel");
+ a_Dpip_dsh_write_str(sh, 1, d_cmd);
+ dFree(d_cmd);
+ response_number = dialog_get_answer_number();
+ if (response_number == 1) {
+ ret = 0;
+ }
+ break;
default: /*Need to add more options later*/
snprintf(buf, 80,
"The remote certificate cannot be verified (code %ld)", st);
diff --git a/dpid/Makefile.am b/dpid/Makefile.am
index 2b81a98a..a59fa083 100644
--- a/dpid/Makefile.am
+++ b/dpid/Makefile.am
@@ -1,8 +1,14 @@
-AM_CPPFLAGS=-DDPIDRC_SYS='"$(sysconfdir)/dpidrc"'
+AM_CPPFLAGS = \
+ -I$(top_srcdir) \
+ -DDPIDRC_SYS='"$(sysconfdir)/dpidrc"'
bin_PROGRAMS = dpid dpidc
-dpid_LDADD = ../dpip/libDpip.a ../dlib/libDlib.a
-dpidc_LDADD = ../dpip/libDpip.a ../dlib/libDlib.a
+dpid_LDADD = \
+ $(top_builddir)/dpip/libDpip.a \
+ $(top_builddir)/dlib/libDlib.a
+dpidc_LDADD = \
+ $(top_builddir)/dpip/libDpip.a \
+ $(top_builddir)/dlib/libDlib.a
EXTRA_DIST = dpidrc.in
diff --git a/dpip/Makefile.am b/dpip/Makefile.am
index 099ac7d4..e88da0a1 100644
--- a/dpip/Makefile.am
+++ b/dpip/Makefile.am
@@ -1,3 +1,6 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir)
+
noinst_LIBRARIES = libDpip.a
libDpip_a_SOURCES = \
diff --git a/dpip/dpip.c b/dpip/dpip.c
index 46ce6ec8..a5517784 100644
--- a/dpip/dpip.c
+++ b/dpip/dpip.c
@@ -33,7 +33,6 @@
* Local variables
*/
static const char Quote = '\'';
-static const int DpipTag = 1;
/*
* Basically the syntax of a dpip tag is:
diff --git a/dw/Makefile.am b/dw/Makefile.am
index 7150fce9..3014b35d 100644
--- a/dw/Makefile.am
+++ b/dw/Makefile.am
@@ -1,3 +1,6 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir)
+
noinst_LIBRARIES = \
libDw-core.a \
libDw-fltk.a \
diff --git a/dw/fltkimgbuf.cc b/dw/fltkimgbuf.cc
index 6ba7ff1d..e3be41a9 100644
--- a/dw/fltkimgbuf.cc
+++ b/dw/fltkimgbuf.cc
@@ -193,7 +193,7 @@ core::Imgbuf* FltkImgbuf::getScaledBuf (int width, int height)
*/
if (width <= 0 || height <= 0 ||
width > IMAGE_MAX_AREA / height) {
- MSG("FltkImgbuf::getScaledBuf: suspicious image size request %dx%d\n",
+ MSG("FltkImgbuf::getScaledBuf: suspicious image size request %d x %d\n",
width, height);
ref ();
return this;
diff --git a/dw/fltkplatform.cc b/dw/fltkplatform.cc
index 97e10710..17eb5d51 100644
--- a/dw/fltkplatform.cc
+++ b/dw/fltkplatform.cc
@@ -17,6 +17,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <stdio.h>
+#include <wchar.h>
+#include <wctype.h>
#include "../lout/msg.h"
#include "fltkcore.hh"
@@ -28,7 +31,6 @@
#include <fltk/InvisibleBox.h>
#include <fltk/Tooltip.h>
#include <fltk/utf.h>
-#include <stdio.h>
namespace dw {
namespace fltk {
@@ -351,20 +353,45 @@ void FltkPlatform::detachView (core::View *view)
int FltkPlatform::textWidth (core::style::Font *font, const char *text,
int len)
{
- int width;
+ char chbuf[4];
+ wchar_t wc, wcu;
+ int width = 0;
FltkFont *ff = (FltkFont*) font;
- setfont (ff->font, ff->size);
- width = (int) getwidth (text, len);
+ int curr = 0, next = 0, nb;
- if (font->letterSpacing) {
- int curr = 0, next = 0;
-
- while (next < len) {
+ if (font->fontVariant == 1) {
+ int sc_fontsize = lout::misc::roundInt(ff->size * 0.78);
+ for (curr = 0; next < len; curr = next) {
next = nextGlyph(text, curr);
- width += font->letterSpacing;
- curr = next;
+ wc = utf8decode(text + curr, text + next, &nb);
+ if ((wcu = towupper(wc)) == wc) {
+ /* already uppercase, just draw the character */
+ setfont(ff->font, ff->size);
+ width += font->letterSpacing;
+ width += (int)getwidth(text + curr, next - curr);
+ } else {
+ /* make utf8 string for converted char */
+ nb = utf8encode(wcu, chbuf);
+ setfont(ff->font, sc_fontsize);
+ width += font->letterSpacing;
+ width += (int)getwidth(chbuf, nb);
+ }
+ }
+ } else {
+ setfont (ff->font, ff->size);
+ width = (int) getwidth (text, len);
+
+ if (font->letterSpacing) {
+ int curr = 0, next = 0;
+
+ while (next < len) {
+ next = nextGlyph(text, curr);
+ width += font->letterSpacing;
+ curr = next;
+ }
}
}
+
return width;
}
diff --git a/dw/fltkui.cc b/dw/fltkui.cc
index c1bfd873..ff80e14c 100644
--- a/dw/fltkui.cc
+++ b/dw/fltkui.cc
@@ -524,7 +524,7 @@ void FltkEntryResource::widgetCallback (::fltk::Widget *widget,
* The Back or Forward, buttons, or the first click on a rendered
* page. BUG: this must be investigated and reported to FLTK2 team
*/
- MSG("when = %d\n", widget->when ());
+ _MSG("when = %d\n", widget->when ());
if ((widget->when () & ::fltk::WHEN_ENTER_KEY_ALWAYS) &&
(::fltk::event_key() == ::fltk::ReturnKey))
((FltkEntryResource*)data)->emitActivate ();
@@ -989,7 +989,7 @@ template <class I> void FltkSelectionResource<I>::addItem (const char *str,
itemWidget->set_selected();
if (setSelectedItems ()) {
// Handle multiple item selection.
- int pos[widgetStack->stack->size ()];
+ int *pos = new int[widgetStack->stack->size ()];
int i;
Iterator <TypedPointer < ::fltk::Menu> > it;
for (it = widgetStack->stack->iterator (),
@@ -1000,6 +1000,7 @@ template <class I> void FltkSelectionResource<I>::addItem (const char *str,
pos[i] = p->getTypedValue()->children () - 1;
}
widgetStack->widget->set_item (pos, widgetStack->stack->size ());
+ delete [] pos;
}
}
}
diff --git a/dw/fltkviewbase.cc b/dw/fltkviewbase.cc
index 7d519f05..cab22cf4 100644
--- a/dw/fltkviewbase.cc
+++ b/dw/fltkviewbase.cc
@@ -27,8 +27,11 @@
#include <fltk/events.h>
#include <fltk/Cursor.h>
#include <fltk/run.h>
+#include <fltk/utf.h>
#include <stdio.h>
+#include <wchar.h>
+#include <wctype.h>
#include "../lout/msg.h"
using namespace fltk;
@@ -366,6 +369,39 @@ void FltkViewBase::drawLine (core::style::Color *color,
translateCanvasXToViewX (x2), translateCanvasYToViewY (y2));
}
+void FltkViewBase::drawTypedLine (core::style::Color *color,
+ core::style::Color::Shading shading,
+ core::style::LineType type, int width,
+ int x1, int y1, int x2, int y2)
+{
+ char dashes[3], w, ng, d, gap, len;
+ const int f = 2;
+
+ w = (width == 1) ? 0 : width;
+ if (type == core::style::LINE_DOTTED) {
+ /* customized drawing for dotted lines */
+ len = (x2 == x1) ? y2 - y1 + 1 : (y2 == y1) ? x2 - x1 + 1 : 0;
+ ng = len / f*width;
+ d = len % f*width;
+ gap = ng ? d/ng + (w > 3 ? 2 : 0) : 0;
+ dashes[0] = 1; dashes[1] = f*width-gap; dashes[2] = 0;
+ line_style(::fltk::DASH + ::fltk::CAP_ROUND, w, dashes);
+
+ /* These formulas also work, but ain't pretty ;)
+ * line_style(::fltk::DOT + ::fltk::CAP_ROUND, w);
+ * dashes[0] = 1; dashes[1] = 3*width-2; dashes[2] = 0;
+ */
+ } else if (type == core::style::LINE_DASHED) {
+ line_style(::fltk::DASH + ::fltk::CAP_ROUND, w);
+ }
+
+ setcolor(((FltkColor*)color)->colors[shading]);
+ drawLine (color, shading, x1, y1, x2, y2);
+
+ if (type != core::style::LINE_NORMAL)
+ line_style(::fltk::SOLID);
+}
+
void FltkViewBase::drawRectangle (core::style::Color *color,
core::style::Color::Shading shading,
bool filled,
@@ -386,7 +422,7 @@ void FltkViewBase::drawRectangle (core::style::Color *color,
int x2 = translateCanvasXToViewX (x + width);
int y2 = translateCanvasYToViewY (y + height);
- // We only support rectangles with line width 1px, so we clip with
+ // We only support rectangles with line width 1px, so we clip with
// a rectangle 1px wider and higher than what we actually expose.
// This is only really necessary for non-filled rectangles.
clipPoint (&x1, &y1, 1);
@@ -483,20 +519,45 @@ void FltkWidgetView::drawText (core::style::Font *font,
setfont(ff->font, ff->size);
setcolor(((FltkColor*)color)->colors[shading]);
- if (!font->letterSpacing) {
+ if (!font->letterSpacing && !font->fontVariant) {
drawtext(text, len,
translateCanvasXToViewX (x), translateCanvasYToViewY (y));
} else {
/* Nonzero letter spacing adjustment, draw each glyph individually */
int viewX = translateCanvasXToViewX (x),
viewY = translateCanvasYToViewY (y);
- int curr = 0, next = 0;
-
- while (next < len) {
- next = theLayout->nextGlyph(text, curr);
- drawtext(text + curr, next - curr, viewX, viewY);
- viewX += font->letterSpacing + (int)getwidth(text + curr,next - curr);
- curr = next;
+ int curr = 0, next = 0, nb;
+ char chbuf[4];
+ wchar_t wc, wcu;
+
+ if (font->fontVariant == 1) {
+ int sc_fontsize = lout::misc::roundInt(ff->size * 0.78);
+ for (curr = 0; next < len; curr = next) {
+ next = theLayout->nextGlyph(text, curr);
+ wc = utf8decode(text + curr, text + next, &nb);
+ if ((wcu = towupper(wc)) == wc) {
+ /* already uppercase, just draw the character */
+ setfont(ff->font, ff->size);
+ drawtext(text + curr, next - curr, viewX, viewY);
+ viewX += font->letterSpacing;
+ viewX += (int)getwidth(text + curr, next - curr);
+ } else {
+ /* make utf8 string for converted char */
+ nb = utf8encode(wcu, chbuf);
+ setfont(ff->font, sc_fontsize);
+ drawtext(chbuf, nb, viewX, viewY);
+ viewX += font->letterSpacing;
+ viewX += (int)getwidth(chbuf, nb);
+ }
+ }
+ } else {
+ while (next < len) {
+ next = theLayout->nextGlyph(text, curr);
+ drawtext(text + curr, next - curr, viewX, viewY);
+ viewX += font->letterSpacing +
+ (int)getwidth(text + curr,next - curr);
+ curr = next;
+ }
}
}
}
diff --git a/dw/fltkviewbase.hh b/dw/fltkviewbase.hh
index 5e1981f8..b5c3ab5e 100644
--- a/dw/fltkviewbase.hh
+++ b/dw/fltkviewbase.hh
@@ -72,6 +72,10 @@ public:
void drawLine (core::style::Color *color,
core::style::Color::Shading shading,
int x1, int y1, int x2, int y2);
+ void drawTypedLine (core::style::Color *color,
+ core::style::Color::Shading shading,
+ core::style::LineType type, int width,
+ int x1, int y1, int x2, int y2);
void drawRectangle (core::style::Color *color,
core::style::Color::Shading shading, bool filled,
int x, int y, int width, int height);
diff --git a/dw/layout.cc b/dw/layout.cc
index d8b96d55..8f67e895 100644
--- a/dw/layout.cc
+++ b/dw/layout.cc
@@ -223,7 +223,8 @@ Layout::~Layout ()
platform->removeIdle (scrollIdleId);
if (resizeIdleId != -1)
platform->removeIdle (resizeIdleId);
-
+ if (bgColor)
+ bgColor->unref ();
if (topLevel)
delete topLevel;
delete platform;
@@ -247,7 +248,6 @@ void Layout::addWidget (Widget *widget)
canvasHeightGreater = false;
setSizeHints ();
- updateBgColor ();
queueResize ();
}
@@ -610,17 +610,17 @@ void Layout::updateCursor ()
setCursor (style::CURSOR_DEFAULT);
}
-void Layout::updateBgColor ()
+void Layout::setBgColor (style::Color *color)
{
- /* The toplevel widget should always have a defined background color,
- * except at the beginning. Searching a defined background is not
- * necessary. */
- if (topLevel && topLevel->getStyle() &&
- topLevel->getStyle()->backgroundColor)
- bgColor = topLevel->getStyle()->backgroundColor;
- else
- bgColor = NULL;
- view->setBgColor (bgColor);
+ color->ref ();
+
+ if (bgColor)
+ bgColor->unref ();
+
+ bgColor = color;
+
+ if (view)
+ view->setBgColor (bgColor);
}
void Layout::resizeIdle ()
diff --git a/dw/layout.hh b/dw/layout.hh
index 304cf166..dc9bf227 100644
--- a/dw/layout.hh
+++ b/dw/layout.hh
@@ -202,7 +202,6 @@ private:
void removeAnchor (Widget *widget, char* name);
void setCursor (style::Cursor cursor);
void updateCursor ();
- void updateBgColor ();
void queueDraw (int x, int y, int width, int height);
void queueDrawExcept (int x, int y, int width, int height,
int ex, int ey, int ewidth, int eheight);
@@ -362,6 +361,10 @@ public:
/** \brief See dw::core::FindtextState::resetSearch. */
inline void resetSearch () { findtextState.resetSearch (); }
+
+ void setBgColor (style::Color *color);
+
+ inline style::Color* getBgColor () { return bgColor; }
};
} // namespace dw
diff --git a/dw/ruler.cc b/dw/ruler.cc
index 6dce07d0..115dfaa5 100644
--- a/dw/ruler.cc
+++ b/dw/ruler.cc
@@ -28,6 +28,7 @@ namespace dw {
Ruler::Ruler ()
{
+ setFlags (BLOCK_LEVEL);
unsetFlags (HAS_CONTENTS);
}
diff --git a/dw/style.cc b/dw/style.cc
index c5866372..ae0f4526 100644
--- a/dw/style.cc
+++ b/dw/style.cc
@@ -21,6 +21,7 @@
#include <string.h>
#include <unistd.h>
#include <ctype.h>
+#include <math.h>
#include "core.hh"
#include "../lout/msg.h"
@@ -46,9 +47,11 @@ void StyleAttrs::initValues ()
width = height = lineHeight = LENGTH_AUTO;
vloat = FLOAT_NONE;
clear = CLEAR_NONE;
+ textIndent = 0;
margin.setVal (0);
borderWidth.setVal (0);
padding.setVal (0);
+ borderCollapse = BORDER_MODEL_SEPARATE;
setBorderColor (NULL);
setBorderStyle (BORDER_NONE);
hBorderSpacing = 0;
@@ -124,9 +127,11 @@ bool StyleAttrs::equals (object::Object *other) {
width == otherAttrs->width &&
height == otherAttrs->height &&
lineHeight == otherAttrs->lineHeight &&
+ textIndent == otherAttrs->textIndent &&
margin.equals (&otherAttrs->margin) &&
borderWidth.equals (&otherAttrs->borderWidth) &&
padding.equals (&otherAttrs->padding) &&
+ borderCollapse == otherAttrs->borderCollapse &&
borderColor.top == otherAttrs->borderColor.top &&
borderColor.right == otherAttrs->borderColor.right &&
borderColor.bottom == otherAttrs->borderColor.bottom &&
@@ -161,9 +166,11 @@ int StyleAttrs::hashValue () {
width +
height +
lineHeight +
+ textIndent +
margin.hashValue () +
borderWidth.hashValue () +
padding.hashValue () +
+ borderCollapse +
(intptr_t) borderColor.top +
(intptr_t) borderColor.right +
(intptr_t) borderColor.bottom +
@@ -251,9 +258,11 @@ void Style::copyAttrs (StyleAttrs *attrs)
width = attrs->width;
height = attrs->height;
lineHeight = attrs->lineHeight;
+ textIndent = attrs->textIndent;
margin = attrs->margin;
borderWidth = attrs->borderWidth;
padding = attrs->padding;
+ borderCollapse = attrs->borderCollapse;
borderColor = attrs->borderColor;
borderStyle = attrs->borderStyle;
display = attrs->display;
@@ -277,6 +286,7 @@ bool FontAttrs::equals(object::Object *other)
weight == otherAttrs->weight &&
style == otherAttrs->style &&
letterSpacing == otherAttrs->letterSpacing &&
+ fontVariant == otherAttrs->fontVariant &&
strcmp (name, otherAttrs->name) == 0);
}
@@ -287,6 +297,7 @@ int FontAttrs::hashValue()
h = (h << 5) - h + weight;
h = (h << 5) - h + style;
h = (h << 5) - h + letterSpacing;
+ h = (h << 5) - h + fontVariant;
return h;
}
@@ -302,6 +313,7 @@ void Font::copyAttrs (FontAttrs *attrs)
weight = attrs->weight;
style = attrs->style;
letterSpacing = attrs->letterSpacing;
+ fontVariant = attrs->fontVariant;
}
Font *Font::create0 (Layout *layout, FontAttrs *attrs,
@@ -408,18 +420,373 @@ Tooltip *Tooltip::create (Layout *layout, const char *text)
// ----------------------------------------------------------------------
-static void drawTriangle (View *view, Color *color, Color::Shading shading,
- int x1, int y1, int x2, int y2, int x3, int y3) {
- int points[3][2];
+/*
+ * The drawBorder{Top,Bottom,Left,Right} functions are similar. They
+ * use a trapezium as draw polygon, or drawTypedLine() for dots and dashes.
+ * Although the concept is simple, achieving pixel accuracy is laborious [1].
+ *
+ * [1] http://www.dillo.org/css_compat/tests/border-style.html
+ */
+static void drawBorderTop(View *view, Style *style,
+ int x1, int y1, int x2, int y2)
+
+{
+ int points[4][2], d, w;
+ bool ridge = false, inset = false, dotted = false;
+ Color::Shading shading = Color::SHADING_NORMAL;
+
+ if (!style->borderColor.top || style->borderWidth.top == 0)
+ return;
+
+ switch (style->borderStyle.top) {
+ case BORDER_NONE:
+ case BORDER_HIDDEN:
+ break;
+ case BORDER_DOTTED:
+ dotted = true;
+ case BORDER_DASHED:
+ w = style->borderWidth.top;
+ view->drawTypedLine(style->borderColor.top, shading,
+ dotted ? LINE_DOTTED : LINE_DASHED,
+ w, x1+w/2, y1+w/2, x2-w/2, y2+w/2);
+ break;
+ case BORDER_SOLID:
+ case BORDER_INSET:
+ inset = true;
+ case BORDER_OUTSET:
+ if (style->borderStyle.top != BORDER_SOLID)
+ shading = (inset) ? Color::SHADING_DARK : Color::SHADING_LIGHT;
+
+ if (style->borderWidth.top == 1) {
+ view->drawLine(style->borderColor.top, shading, x1, y1, x2, y2);
+ } else {
+ points[0][0] = x1;
+ points[1][0] = x2 + 1;
+ points[0][1] = points[1][1] = y1;
+ points[2][0] = points[1][0] - style->borderWidth.right;
+ points[3][0] = x1 + style->borderWidth.left;
+ points[2][1] = points[3][1] = points[0][1] + style->borderWidth.top;
+ view->drawPolygon (style->borderColor.top, shading, true, points, 4);
+ }
+ break;
+ case BORDER_RIDGE:
+ ridge = true;
+ case BORDER_GROOVE:
+ d = style->borderWidth.top & 1;
+ points[0][0] = x1;
+ points[1][0] = x2 + 1;
+ points[0][1] = points[1][1] = y1;
+ points[2][0] = x2 - style->borderWidth.right / 2;
+ points[3][0] = x1 + style->borderWidth.left / 2;
+ points[2][1] = points[3][1] = y1 + style->borderWidth.top / 2 + d;
+ shading = (ridge) ? Color::SHADING_LIGHT : Color::SHADING_DARK;
+ view->drawPolygon (style->borderColor.top, shading, true, points, 4);
+ points[0][0] = x1 + style->borderWidth.left / 2 + d;
+ points[1][0] = x2 - style->borderWidth.right / 2 + 1 - d;
+ points[0][1] = points[1][1] = y1 + style->borderWidth.top / 2 + d;
+ points[2][0] = x2 - style->borderWidth.right + 1 - d;
+ points[3][0] = x1 + style->borderWidth.left;
+ points[2][1] = points[3][1] = y1 + style->borderWidth.top;
+ shading = (ridge) ? Color::SHADING_DARK : Color::SHADING_LIGHT;
+ view->drawPolygon (style->borderColor.top, shading, true, points, 4);
+ break;
+ case BORDER_DOUBLE:
+ w = (int) rint(style->borderWidth.top / 3.0);
+ d = w ? style->borderWidth.top - 2 * w : 0;
+ int w_l = (int) rint(style->borderWidth.left / 3.0);
+ int w_r = (int) rint(style->borderWidth.right / 3.0);
+ if (style->borderWidth.top == 1) {
+ view->drawLine(style->borderColor.top, shading, x1, y1, x2, y2);
+ break;
+ }
+ points[0][0] = x1;
+ points[1][0] = x2 + 1;
+ points[0][1] = points[1][1] = y1;
+ points[2][0] = points[1][0] - w_r;
+ points[3][0] = points[0][0] + w_l;
+ points[2][1] = points[3][1] = points[0][1] + w;
+ view->drawPolygon (style->borderColor.top, shading, true, points, 4);
+ points[0][0] = x1 + style->borderWidth.left - w_l;
+ points[1][0] = x2 + 1 - style->borderWidth.right + w_r;
+ points[0][1] = points[1][1] = y1 + w + d;
+ points[2][0] = x2 + 1 - style->borderWidth.right;
+ points[3][0] = x1 + style->borderWidth.left;
+ points[2][1] = points[3][1] = y1 + style->borderWidth.top;
+ view->drawPolygon (style->borderColor.top, shading, true, points, 4);
+ break;
+ }
+}
+
+static void drawBorderBottom(View *view, Style *style,
+ int x1, int y1, int x2, int y2)
+
+{
+ int points[4][2], d, w;
+ bool ridge = false, inset = false, dotted = false;
+ Color::Shading shading = Color::SHADING_NORMAL;
+
+ if (!style->borderColor.bottom || style->borderWidth.bottom == 0)
+ return;
+
+ switch (style->borderStyle.bottom) {
+ case BORDER_NONE:
+ case BORDER_HIDDEN:
+ break;
+ case BORDER_DOTTED:
+ dotted = true;
+ case BORDER_DASHED:
+ w = style->borderWidth.bottom;
+ view->drawTypedLine(style->borderColor.bottom, shading,
+ dotted ? LINE_DOTTED : LINE_DASHED,
+ w, x1+w/2, y1-w/2, x2-w/2, y2-w/2);
+ break;
+ case BORDER_SOLID:
+ case BORDER_INSET:
+ inset = true;
+ case BORDER_OUTSET:
+ if (style->borderStyle.bottom != BORDER_SOLID)
+ shading = (inset) ? Color::SHADING_LIGHT : Color::SHADING_DARK;
+
+ if (style->borderWidth.bottom == 1) { /* 1 pixel line */
+ view->drawLine(style->borderColor.bottom, shading, x1, y1, x2, y2);
+ } else {
+ points[0][0] = x1 - 1;
+ points[1][0] = x2 + 2;
+ points[0][1] = points[1][1] = y1 + 1;
+ points[2][0] = points[1][0] - style->borderWidth.right;
+ points[3][0] = points[0][0] + style->borderWidth.left;
+ points[2][1] = points[3][1] = points[0][1]-style->borderWidth.bottom;
+ view->drawPolygon (style->borderColor.bottom, shading, true, points, 4);
+ }
+ break;
+ case BORDER_RIDGE:
+ ridge = true;
+ case BORDER_GROOVE:
+ w = style->borderWidth.bottom;
+ d = w & 1;
+ points[0][0] = x1 - 1;
+ points[1][0] = x2 + 2 - d;
+ points[0][1] = points[1][1] = y1 + 1;
+ points[2][0] = points[1][0] - style->borderWidth.right / 2;
+ points[3][0] = points[0][0] + style->borderWidth.left / 2 + d;
+ points[2][1] = points[3][1] = points[0][1] - w/2 - d;
+ shading = (ridge) ? Color::SHADING_DARK : Color::SHADING_LIGHT;
+ view->drawPolygon (style->borderColor.bottom, shading, true, points, 4);
+ // clockwise
+ points[0][0] = x1 + style->borderWidth.left - 1;
+ points[1][0] = x2 + 1 - style->borderWidth.right + 1;
+ points[0][1] = points[1][1] = y1 - w + 1;
+ points[2][0] = points[1][0] + style->borderWidth.right / 2;
+ points[3][0] = points[0][0] - style->borderWidth.left / 2;
+ points[2][1] = points[3][1] = points[0][1] + w/2;
+ shading = (ridge) ? Color::SHADING_LIGHT : Color::SHADING_DARK;
+ view->drawPolygon (style->borderColor.bottom, shading, true, points, 4);
+ break;
+ case BORDER_DOUBLE:
+ w = (int) rint(style->borderWidth.bottom / 3.0);
+ d = w ? style->borderWidth.bottom - 2 * w : 0;
+ int w_l = (int) rint(style->borderWidth.left / 3.0);
+ int w_r = (int) rint(style->borderWidth.right / 3.0);
+ if (style->borderWidth.bottom == 1) {
+ view->drawLine(style->borderColor.bottom, shading, x1, y1, x2, y2);
+ break;
+ }
+ points[0][0] = x2 + 2;
+ points[1][0] = x1 - 1;
+ points[0][1] = points[1][1] = y1 + 1;
+ points[2][0] = points[1][0] + w_l;
+ points[3][0] = points[0][0] - w_r;
+ points[2][1] = points[3][1] = points[0][1] - w;
+ view->drawPolygon (style->borderColor.bottom, shading, true, points, 4);
+ points[0][0] = x2 + 2 - style->borderWidth.right + w_r;
+ points[1][0] = x1 - 1 + style->borderWidth.left - w_l;
+ points[0][1] = points[1][1] = y1 + 1 - w - d;
+ points[2][0] = x1 - 1 + style->borderWidth.left;
+ points[3][0] = x2 + 2 - style->borderWidth.right;
+ points[2][1] = points[3][1] = y1 + 1 - style->borderWidth.bottom;
+ view->drawPolygon (style->borderColor.bottom, shading, true, points, 4);
+ break;
+ }
+}
+
+static void drawBorderLeft(View *view, Style *style,
+ int x1, int y1, int x2, int y2)
+
+{
+ int points[4][2], d, w;
+ bool ridge = false, inset = false, dotted = false;
+ Color::Shading shading = Color::SHADING_NORMAL;
+
+ if (!style->borderColor.left || style->borderWidth.left == 0)
+ return;
- points[0][0] = x1;
- points[0][1] = y1;
- points[1][0] = x2;
- points[1][1] = y2;
- points[2][0] = x3;
- points[2][1] = y3;
+ switch (style->borderStyle.left) {
+ case BORDER_NONE:
+ case BORDER_HIDDEN:
+ break;
+ case BORDER_DOTTED:
+ dotted = true;
+ case BORDER_DASHED:
+ w = style->borderWidth.left;
+ view->drawTypedLine(style->borderColor.left, shading,
+ dotted ? LINE_DOTTED : LINE_DASHED,
+ w, x1+w/2, y1+w/2, x1+w/2, y2-w/2);
+ break;
+ case BORDER_SOLID:
+ case BORDER_INSET:
+ inset = true;
+ case BORDER_OUTSET:
+ if (style->borderStyle.left != BORDER_SOLID)
+ shading = (inset) ? Color::SHADING_DARK : Color::SHADING_LIGHT;
+ if (style->borderWidth.left == 1) { /* 1 pixel line */
+ view->drawLine(style->borderColor.left, shading, x1, y1, x2, y2);
+ } else {
+ points[0][0] = points[1][0] = x1;
+ points[0][1] = y1 - 1;
+ points[1][1] = y2 + 1;
+ points[2][0] = points[3][0] = points[0][0] + style->borderWidth.left;
+ points[2][1] = points[1][1] - style->borderWidth.bottom;
+ points[3][1] = points[0][1] + style->borderWidth.top;
+ view->drawPolygon (style->borderColor.left, shading, true, points, 4);
+ }
+ break;
+ case BORDER_RIDGE:
+ ridge = true;
+ case BORDER_GROOVE:
+ w = style->borderWidth.left;
+ d = w & 1;
+ points[0][0] = points[1][0] = x1;
+ points[0][1] = y1;
+ points[1][1] = y2;
+ points[2][0] = points[3][0] = x1 + w / 2 + d;
+ points[2][1] = y2 - style->borderWidth.bottom / 2;
+ points[3][1] = y1 + style->borderWidth.top / 2;
+ shading = (ridge) ? Color::SHADING_LIGHT : Color::SHADING_DARK;
+ view->drawPolygon (style->borderColor.left, shading, true, points, 4);
+ points[0][0] = points[1][0] = x1 + w / 2 + d;
+ points[0][1] = y1 + style->borderWidth.top / 2;
+ points[1][1] = y2 - style->borderWidth.bottom / 2;
+ points[2][0] = points[3][0] = x1 + w;
+ points[2][1] = y2 - style->borderWidth.bottom;
+ points[3][1] = y1 + style->borderWidth.top;
+ shading = (ridge) ? Color::SHADING_DARK : Color::SHADING_LIGHT;
+ view->drawPolygon (style->borderColor.left, shading, true, points, 4);
+ break;
+ case BORDER_DOUBLE:
+ w = (int) rint(style->borderWidth.left / 3.0);
+ d = w ? style->borderWidth.left - 2 * w : 0;
+ int w_b = (int) rint(style->borderWidth.bottom / 3.0);
+ int w_t = (int) rint(style->borderWidth.top / 3.0);
+ if (style->borderWidth.left == 1) {
+ view->drawLine(style->borderColor.left, shading, x1, y1, x2, y2-1);
+ break;
+ }
+ points[0][0] = points[1][0] = x1;
+ points[0][1] = y1 - 1;
+ points[1][1] = y2 + 1;
+ points[2][0] = points[3][0] = points[0][0] + w;
+ points[2][1] = points[1][1] - w_b;
+ points[3][1] = points[0][1] + w_t;
+ view->drawPolygon (style->borderColor.left, shading, true, points, 4);
+ points[0][0] = points[1][0] = x1 + w + d;
+ points[0][1] = y1 - 1 + style->borderWidth.top - w_t;
+ points[1][1] = y2 + 1 - style->borderWidth.bottom + w_b;
+ points[2][0] = points[3][0] = points[0][0] + w;
+ points[2][1] = y2 + 1 - style->borderWidth.bottom;
+ points[3][1] = y1 - 1 + style->borderWidth.top;
+ view->drawPolygon (style->borderColor.left, shading, true, points, 4);
+ break;
+ }
+}
- view->drawPolygon (color, shading, true, points, 3);
+static void drawBorderRight(View *view, Style *style,
+ int x1, int y1, int x2, int y2)
+
+{
+ int points[4][2], d, w;
+ bool ridge = false, inset = false, dotted = false;
+ Color::Shading shading = Color::SHADING_NORMAL;
+
+ if (!style->borderColor.right || style->borderWidth.right == 0)
+ return;
+
+ switch (style->borderStyle.right) {
+ case BORDER_NONE:
+ case BORDER_HIDDEN:
+ break;
+ case BORDER_DOTTED:
+ dotted = true;
+ case BORDER_DASHED:
+ w = style->borderWidth.right;
+ view->drawTypedLine(style->borderColor.right, shading,
+ dotted ? LINE_DOTTED : LINE_DASHED,
+ w, x1 - w/2, y1 + w/2, x1 - w/2, y2 - w/2);
+ break;
+ case BORDER_SOLID:
+ case BORDER_INSET:
+ inset = true;
+ case BORDER_OUTSET:
+ if (style->borderStyle.right != BORDER_SOLID)
+ shading = (inset) ? Color::SHADING_LIGHT : Color::SHADING_DARK;
+ if (style->borderWidth.right == 1) { /* 1 pixel line */
+ view->drawLine(style->borderColor.right, shading, x1, y1, x2, y2);
+ } else {
+ points[0][0] = points[1][0] = x1 + 1;
+ points[0][1] = y1 - 1;
+ points[1][1] = y2 + 1;
+ points[2][0] = points[3][0] = points[0][0]-style->borderWidth.right;
+ points[2][1] = points[1][1] - style->borderWidth.bottom;
+ points[3][1] = points[0][1] + style->borderWidth.top;
+ view->drawPolygon (style->borderColor.right, shading, true,points,4);
+ }
+ break;
+ case BORDER_RIDGE:
+ ridge = true;
+ case BORDER_GROOVE:
+ w = style->borderWidth.right;
+ d = w & 1;
+ points[0][0] = points[1][0] = x1 + 1;
+ points[0][1] = y1;
+ points[1][1] = y2;
+ points[2][0] = points[3][0] = points[0][0] - w / 2 - d;
+ points[2][1] = y2 - style->borderWidth.bottom / 2;
+ points[3][1] = points[0][1] + style->borderWidth.top / 2;
+ shading = (ridge) ? Color::SHADING_DARK : Color::SHADING_LIGHT;
+ view->drawPolygon (style->borderColor.right, shading, true, points, 4);
+ points[0][0] = points[1][0] = x1 + 1 - w / 2 - d;
+ points[0][1] = y1 + style->borderWidth.top / 2;
+ points[1][1] = y2 - style->borderWidth.bottom / 2;
+ points[2][0] = points[3][0] = x1 + 1 - w;
+ points[2][1] = y2 - style->borderWidth.bottom;
+ points[3][1] = y1 + style->borderWidth.top;
+ shading = (ridge) ? Color::SHADING_LIGHT: Color::SHADING_DARK;
+ view->drawPolygon (style->borderColor.right, shading, true, points, 4);
+ break;
+ case BORDER_DOUBLE:
+ w = (int) rint(style->borderWidth.right / 3.0);
+ d = w ? style->borderWidth.right - 2 * w : 0;
+ int w_b = (int) rint(style->borderWidth.bottom / 3.0);
+ int w_t = (int) rint(style->borderWidth.top / 3.0);
+ if (style->borderWidth.right == 1) {
+ view->drawLine(style->borderColor.right, shading, x1, y1, x2, y2);
+ break;
+ }
+ points[0][0] = points[1][0] = x1 + 1;
+ points[0][1] = y1 - 1;
+ points[1][1] = y2 + 1;
+ points[2][0] = points[3][0] = points[0][0] - w;
+ points[2][1] = points[1][1] - w_b;
+ points[3][1] = points[0][1] + w_t;
+ view->drawPolygon (style->borderColor.right, shading, true, points, 4);
+ points[0][0] = points[1][0] = x1 + 1 - w - d;
+ points[0][1] = y1 - 1 + style->borderWidth.top - w_t;
+ points[1][1] = y2 + 1 - style->borderWidth.bottom + w_b;
+ points[2][0] = points[3][0] = points[0][0] - w;
+ points[2][1] = y2 + 1 - style->borderWidth.bottom;
+ points[3][1] = y1 - 1 + style->borderWidth.top;
+ view->drawPolygon (style->borderColor.right, shading, true, points, 4);
+ break;
+ }
}
/**
@@ -433,14 +800,13 @@ void drawBorder (View *view, Rectangle *area,
{
/** \todo a lot! */
Color::Shading dark, light, normal;
- Color::Shading top, right, bottom, left;
int xb1, yb1, xb2, yb2, xp1, yp1, xp2, yp2;
// top left and bottom right point of outer border boundary
xb1 = x + style->margin.left;
yb1 = y + style->margin.top;
- xb2 = x + width - style->margin.right;
- yb2 = y + height - style->margin.bottom;
+ xb2 = x + (width > 0 ? width - 1 : 0) - style->margin.right;
+ yb2 = y + (height > 0 ? height - 1 : 0) - style->margin.bottom;
// top left and bottom right point of inner border boundary
xp1 = xb1 + style->borderWidth.left;
@@ -452,63 +818,10 @@ void drawBorder (View *view, Rectangle *area,
dark = inverse ? Color::SHADING_LIGHT : Color::SHADING_DARK;
normal = inverse ? Color::SHADING_INVERSE : Color::SHADING_NORMAL;
- switch (style->borderStyle.top) {
- case BORDER_INSET:
- top = left = dark;
- right = bottom = light;
- break;
-
- case BORDER_OUTSET:
- top = left = light;
- right = bottom = dark;
- break;
-
- default:
- top = right = bottom = left = normal;
- break;
- }
-
- if (style->borderStyle.top != BORDER_NONE && style->borderColor.top)
- view->drawRectangle(style->borderColor.top, top, true,
- xb1, yb1, xb2 - xb1, style->borderWidth.top);
-
- if (style->borderStyle.bottom != BORDER_NONE && style->borderColor.bottom)
- view->drawRectangle(style->borderColor.bottom, bottom, true,
- xb1, yb2, xb2 - xb1, - style->borderWidth.bottom);
-
- if (style->borderStyle.left != BORDER_NONE && style->borderColor.left)
- view->drawRectangle(style->borderColor.left, left, true,
- xb1, yp1, style->borderWidth.left, yp2 - yp1);
-
- if (style->borderWidth.left > 1) {
- if (style->borderWidth.top > 1 &&
- (style->borderColor.left != style->borderColor.top ||
- left != top))
- drawTriangle (view, style->borderColor.left, left,
- xb1, yp1, xp1, yp1, xb1, yb1);
- if (style->borderWidth.bottom > 1 &&
- (style->borderColor.left != style->borderColor.bottom ||
- left != bottom))
- drawTriangle (view, style->borderColor.left, left,
- xb1, yp2, xp1, yp2, xb1, yb2);
- }
-
- if (style->borderStyle.right != BORDER_NONE && style->borderColor.right)
- view->drawRectangle(style->borderColor.right, right, true,
- xb2, yp1, - style->borderWidth.right, yp2 - yp1);
-
- if (style->borderWidth.right > 1) {
- if (style->borderWidth.top > 1 &&
- (style->borderColor.right != style->borderColor.top ||
- right != top))
- drawTriangle (view, style->borderColor.right, right,
- xb2, yp1, xp2, yp1, xb2, yb1);
- if (style->borderWidth.bottom > 1 &&
- (style->borderColor.right != style->borderColor.bottom ||
- right != bottom))
- drawTriangle (view, style->borderColor.right, right,
- xb2, yp2, xp2, yp2, xb2, yb2);
- }
+ drawBorderRight(view, style, xb2, yb1, xb2, yb2);
+ drawBorderLeft(view, style, xb1, yb1, xb1, yb2);
+ drawBorderTop(view, style, xb1, yb1, xb2, yb1);
+ drawBorderBottom(view, style, xb1, yb2, xb2, yb2);
}
diff --git a/dw/style.hh b/dw/style.hh
index 57ee1d10..370d8d1b 100644
--- a/dw/style.hh
+++ b/dw/style.hh
@@ -64,7 +64,7 @@ namespace core {
* attribute, which is supported by dillo, will refer to an attribute in
* dw::core::style::Style. For this reason, the attributes in
* dw::core::style::Style get the names from the CSS attributes, with
- * "camelCase" instead of hythens (e.g. "background-color" becomes
+ * "camelCase" instead of hyphens (e.g. "background-color" becomes
* "backgroundColor").
*
* However, dw::core::style::Style will be extended by some more
@@ -193,7 +193,7 @@ namespace core {
namespace style {
enum Cursor {
- CURSOR_COSSHAIR,
+ CURSOR_CROSSHAIR,
CURSOR_DEFAULT,
CURSOR_POINTER,
CURSOR_MOVE,
@@ -210,6 +210,11 @@ enum Cursor {
CURSOR_HELP
};
+enum BorderCollapse {
+ BORDER_MODEL_SEPARATE,
+ BORDER_MODEL_COLLAPSE
+};
+
enum BorderStyle {
BORDER_NONE,
BORDER_HIDDEN,
@@ -258,6 +263,12 @@ enum DisplayType {
DISPLAY_TABLE_CELL
};
+enum LineType {
+ LINE_NORMAL,
+ LINE_DOTTED,
+ LINE_DASHED
+};
+
enum ListStylePosition {
LIST_STYLE_POSITION_INSIDE,
LIST_STYLE_POSITION_OUTSIDE
@@ -292,6 +303,11 @@ enum FontStyle {
FONT_STYLE_OBLIQUE
};
+enum FontVariant {
+ FONT_VARIANT_NORMAL,
+ FONT_VARIANT_SMALL_CAPS
+};
+
enum TextDecoration {
TEXT_DECORATION_NONE = 0,
TEXT_DECORATION_UNDERLINE = 1 << 0,
@@ -442,9 +458,10 @@ public:
ClearType clear;
int hBorderSpacing, vBorderSpacing, wordSpacing;
- Length width, height, lineHeight;
+ Length width, height, lineHeight, textIndent;
Box margin, borderWidth, padding;
+ BorderCollapse borderCollapse;
struct { Color *top, *right, *bottom, *left; } borderColor;
struct { BorderStyle top, right, bottom, left; } borderStyle;
@@ -573,6 +590,7 @@ public:
int size;
int weight;
int letterSpacing;
+ FontVariant fontVariant;
FontStyle style;
bool equals(lout::object::Object *other);
diff --git a/dw/table.cc b/dw/table.cc
index 51718587..6708b3f0 100644
--- a/dw/table.cc
+++ b/dw/table.cc
@@ -34,6 +34,7 @@ int Table::CLASS_ID = -1;
Table::Table(bool limitTextWidth)
{
registerName ("dw::Table", &CLASS_ID);
+ setFlags (BLOCK_LEVEL);
setFlags (USES_HINTS);
setButtonSensitive(false);
diff --git a/dw/textblock.cc b/dw/textblock.cc
index 32c39671..fffbac2f 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -35,6 +35,7 @@ int Textblock::CLASS_ID = -1;
Textblock::Textblock (bool limitTextWidth)
{
registerName ("dw::Textblock", &CLASS_ID);
+ setFlags (BLOCK_LEVEL);
setFlags (USES_HINTS);
setButtonSensitive(true);
@@ -260,10 +261,9 @@ void Textblock::getExtremesImpl (core::Extremes *extremes)
word = words->getRef (wordIndex);
getWordExtremes (word, &wordExtremes);
- /* For the first word, we simply add the line1_offset. */
- /* This test looks questionable */
- if (ignoreLine1OffsetSometimes && wordIndex == 0) {
- wordExtremes.minWidth += line1Offset;
+ if (wordIndex == 0) {
+ wordExtremes.minWidth += line1OffsetEff;
+ wordExtremes.maxWidth += line1OffsetEff;
//DEBUG_MSG (DEBUG_SIZE_LEVEL + 1,
// " (next plus %d)\n", page->line1_offset);
}
@@ -965,7 +965,20 @@ void Textblock::wordWrap(int wordIndex)
line1Offset + word->size.width > availWidth) {
line1OffsetEff = 0;
} else {
- line1OffsetEff = line1Offset;
+ int indent = 0;
+
+ if (word->content.type == core::Content::WIDGET &&
+ word->content.widget->blockLevel() == true) {
+ /* don't use text-indent when nesting blocks */
+ } else {
+ if (core::style::isPerLength(getStyle()->textIndent)) {
+ indent = misc::roundInt(this->availWidth *
+ core::style::perLengthVal (getStyle()->textIndent));
+ } else {
+ indent = core::style::absLengthVal (getStyle()->textIndent);
+ }
+ }
+ line1OffsetEff = line1Offset + indent;
}
}
@@ -1314,20 +1327,20 @@ void Textblock::decorateText(core::View *view, core::style::Style *style,
core::style::Color::Shading shading,
int x, int yBase, int width)
{
- int y;
+ int y, height;
+ height = 1 + style->font->xHeight / 12;
if (style->textDecoration & core::style::TEXT_DECORATION_UNDERLINE) {
- y = yBase + 1;
- view->drawLine (style->color, shading, x, y, x + width - 1, y);
+ y = yBase + style->font->descent / 3;
+ view->drawRectangle (style->color, shading, true, x, y, width, height);
}
if (style->textDecoration & core::style::TEXT_DECORATION_OVERLINE) {
- y = yBase - style->font->ascent + 1;
- view->drawLine (style->color, shading, x, y, x + width - 1, y);
+ y = yBase - style->font->ascent;
+ view->drawRectangle (style->color, shading, true, x, y, width, height);
}
if (style->textDecoration & core::style::TEXT_DECORATION_LINE_THROUGH) {
- int height = 1 + style->font->xHeight / 10;
-
- y = yBase + (style->font->descent - style->font->ascent) / 2;
+ y = yBase + (style->font->descent - style->font->ascent) / 2 +
+ style->font->descent / 4;
view->drawRectangle (style->color, shading, true, x, y, width, height);
}
}
@@ -1693,8 +1706,8 @@ void Textblock::calcTextSize (const char *text, size_t len,
factor /= (style->font->ascent + style->font->descent);
- size->ascent = size->ascent * factor + 0.5;
- size->descent = size->descent * factor + 0.5;
+ size->ascent = lout::misc::roundInt(size->ascent * factor);
+ size->descent = lout::misc::roundInt(size->descent * factor);
/* TODO: The containing block's line-height property gives a minimum
* height for the line boxes. (Even when it's set to 'normal', i.e.,
@@ -1704,8 +1717,9 @@ void Textblock::calcTextSize (const char *text, size_t len,
if (core::style::isAbsLength (style->lineHeight))
height = core::style::absLengthVal(style->lineHeight);
else
- height = core::style::perLengthVal(style->lineHeight) *
- style->font->size;
+ height = lout::misc::roundInt (
+ core::style::perLengthVal(style->lineHeight) *
+ style->font->size);
leading = height - style->font->size;
size->ascent += leading / 2;
diff --git a/dw/types.cc b/dw/types.cc
index 672ec7f6..4d94f494 100644
--- a/dw/types.cc
+++ b/dw/types.cc
@@ -1,7 +1,3 @@
-// Rectangle::intersectsWith() has code that was derived from gdkrectangle.c.
-// gdkrectangle.c bears the notice that GDK, the GIMP Drawing Kit, is
-// "Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald".
-
/*
* Dillo Widget
*
@@ -56,55 +52,24 @@ void Rectangle::draw (core::View *view, core::style::Style *style, int x,int y)
*/
bool Rectangle::intersectsWith (Rectangle *otherRect, Rectangle *dest)
{
- Rectangle *src1 = this, *src2 = otherRect, *temp;
- int src1_x2, src1_y2;
- int src2_x2, src2_y2;
- bool return_val;
-
- return_val = false;
-
- if (src2->x < src1->x) {
- temp = src1;
- src1 = src2;
- src2 = temp;
+ bool doIntersect =
+ this->x < otherRect->x + otherRect->width &&
+ this->y < otherRect->y + otherRect->height &&
+ otherRect->x < this->x + this->width &&
+ otherRect->y < this->y + this->height;
+
+ if (doIntersect) {
+ dest->x = misc::max(this->x, otherRect->x);
+ dest->y = misc::max(this->y, otherRect->y);
+ dest->width = misc::min(this->x + this->width,
+ otherRect->x + otherRect->width) - dest->x;
+ dest->height = misc::min(this->y + this->height,
+ otherRect->y + otherRect->height) - dest->y;
+ } else {
+ dest->x = dest->y = dest->width = dest->height = 0;
}
- dest->x = src2->x;
-
- src1_x2 = src1->x + src1->width;
- src2_x2 = src2->x + src2->width;
-
- if (src2->x < src1_x2) {
- if (src1_x2 < src2_x2)
- dest->width = src1_x2 - dest->x;
- else
- dest->width = src2_x2 - dest->x;
-
- if (src2->y < src1->y) {
- temp = src1;
- src1 = src2;
- src2 = temp;
- }
- dest->y = src2->y;
-
- src1_y2 = src1->y + src1->height;
- src2_y2 = src2->y + src2->height;
- if (src2->y < src1_y2) {
- return_val = true;
-
- if (src1_y2 < src2_y2)
- dest->height = src1_y2 - dest->y;
- else
- dest->height = src2_y2 - dest->y;
-
- if (dest->height == 0)
- return_val = false;
- if (dest->width == 0)
- return_val = false;
- }
- }
-
- return return_val;
+ return doIntersect;
}
/*
@@ -212,9 +177,10 @@ bool Polygon::linesCross0(int ax1, int ay1, int ax2, int ay2,
/** TODO Some more description */
// If the scalar product is 0, it means that one point is on the second
// line, so we check for <= 0, not < 0.
- return
- zOfVectorProduct (ax1 - bx1, ay1 - by1, bx2 - bx1, by2 - by1) *
- zOfVectorProduct (ax2 - bx1, ay2 - by1, bx2 - bx1, by2 - by1) <= 0;
+ int z1 = zOfVectorProduct (ax1 - bx1, ay1 - by1, bx2 - bx1, by2 - by1);
+ int z2 = zOfVectorProduct (ax2 - bx1, ay2 - by1, bx2 - bx1, by2 - by1);
+
+ return (z1 <= 0 && z2 >= 0) || (z1 >= 0 && z2 <= 0);
}
/**
diff --git a/dw/ui.cc b/dw/ui.cc
index 058dfde8..5d5d2bf6 100644
--- a/dw/ui.cc
+++ b/dw/ui.cc
@@ -280,7 +280,7 @@ ComplexButtonResource::ComplexButtonResource ()
void ComplexButtonResource::init (Widget *widget)
{
- this->widget = widget;
+ this->childWidget = widget;
layout = new Layout (createPlatform ());
setLayout (layout);
@@ -292,7 +292,7 @@ void ComplexButtonResource::setEmbed (Embed *embed)
{
ButtonResource::setEmbed (embed);
- if (widget->usesHints ())
+ if (childWidget->usesHints ())
embed->setUsesHints ();
}
@@ -304,7 +304,7 @@ ComplexButtonResource::~ComplexButtonResource ()
void ComplexButtonResource::sizeRequest (Requisition *requisition)
{
Requisition widgetRequisition;
- widget->sizeRequest (&widgetRequisition);
+ childWidget->sizeRequest (&widgetRequisition);
requisition->width = widgetRequisition.width + 2 * reliefXThickness ();
requisition->ascent = widgetRequisition.ascent + reliefYThickness ();
requisition->descent = widgetRequisition.descent + reliefYThickness ();
@@ -313,7 +313,7 @@ void ComplexButtonResource::sizeRequest (Requisition *requisition)
void ComplexButtonResource::getExtremes (Extremes *extremes)
{
Extremes widgetExtremes;
- widget->getExtremes (&widgetExtremes);
+ childWidget->getExtremes (&widgetExtremes);
extremes->minWidth = widgetExtremes.minWidth + 2 * reliefXThickness ();
extremes->maxWidth = widgetExtremes.maxWidth + 2 * reliefXThickness ();
}
@@ -324,17 +324,17 @@ void ComplexButtonResource::sizeAllocate (Allocation *allocation)
void ComplexButtonResource::setWidth (int width)
{
- widget->setWidth (width - 2 * reliefXThickness ());
+ childWidget->setWidth (width - 2 * reliefXThickness ());
}
void ComplexButtonResource::setAscent (int ascent)
{
- widget->setAscent (ascent - reliefYThickness ());
+ childWidget->setAscent (ascent - reliefYThickness ());
}
void ComplexButtonResource::setDescent (int descent)
{
- widget->setDescent (descent - reliefYThickness ());
+ childWidget->setDescent (descent - reliefYThickness ());
}
Iterator *ComplexButtonResource::iterator (Content::Type mask, bool atEnd)
diff --git a/dw/ui.hh b/dw/ui.hh
index 02aab093..b0a22cbf 100644
--- a/dw/ui.hh
+++ b/dw/ui.hh
@@ -382,7 +382,7 @@ private:
friend class LayoutReceiver;
LayoutReceiver layoutReceiver;
- Widget *widget;
+ Widget *childWidget;
protected:
Layout *layout;
diff --git a/dw/view.hh b/dw/view.hh
index d0f6c6b9..08853323 100644
--- a/dw/view.hh
+++ b/dw/view.hh
@@ -166,6 +166,10 @@ public:
virtual void drawLine (style::Color *color,
style::Color::Shading shading,
int x1, int y1, int x2, int y2) = 0;
+ virtual void drawTypedLine (style::Color *color,
+ style::Color::Shading shading,
+ style::LineType type, int width,
+ int x1, int y1, int x2, int y2) = 0;
virtual void drawRectangle (style::Color *color,
style::Color::Shading shading, bool filled,
int x, int y, int width, int height) = 0;
diff --git a/dw/widget.cc b/dw/widget.cc
index 751cdcdf..cc73b32b 100644
--- a/dw/widget.cc
+++ b/dw/widget.cc
@@ -294,18 +294,17 @@ void Widget::setStyle (style::Style *style)
{
bool sizeChanged;
+ style->ref ();
+
if (this->style) {
sizeChanged = this->style->sizeDiffs (style);
this->style->unref ();
} else
sizeChanged = true;
- style->ref ();
this->style = style;
if (layout != NULL) {
- if (parent == NULL)
- layout->updateBgColor ();
layout->updateCursor ();
}
@@ -341,9 +340,7 @@ style::Color *Widget::getBgColor ()
widget = widget->parent;
}
- MSG_WARN("No background color found!\n");
- return NULL;
-
+ return layout->getBgColor ();
}
@@ -401,7 +398,9 @@ void Widget::drawWidgetBox (View *view, Rectangle *area, bool inverse)
* widget->style->background_color is NULL (shining through).
*/
/** \todo Background images? */
- if (parent && style->backgroundColor)
+
+ if (style->backgroundColor &&
+ (parent || layout->getBgColor () != style->backgroundColor))
style::drawBackground (view, &viewArea, allocation.x, allocation.y,
allocation.width, getHeight (), style, inverse);
}
diff --git a/dw/widget.hh b/dw/widget.hh
index 013be27b..3034b982 100644
--- a/dw/widget.hh
+++ b/dw/widget.hh
@@ -67,6 +67,11 @@ protected:
* The dw::Image widget uses this flag, see dw::Image::setBuffer.
*/
WAS_ALLOCATED = 1 << 5,
+
+ /**
+ * \brief Set for block-level widgets (as opposed to inline widgets)
+ */
+ BLOCK_LEVEL = 1 << 6,
};
private:
@@ -241,6 +246,7 @@ public:
inline bool wasAllocated () { return flags & WAS_ALLOCATED; }
inline bool usesHints () { return flags & USES_HINTS; }
inline bool hasContents () { return flags & HAS_CONTENTS; }
+ inline bool blockLevel () { return flags & BLOCK_LEVEL; }
void setParent (Widget *parent);
diff --git a/lout/Makefile.am b/lout/Makefile.am
index 5a246708..a3f947db 100644
--- a/lout/Makefile.am
+++ b/lout/Makefile.am
@@ -1,3 +1,6 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir)
+
noinst_LIBRARIES = liblout.a
liblout_a_SOURCES = \
diff --git a/lout/misc.hh b/lout/misc.hh
index 393bac0c..e78e7576 100644
--- a/lout/misc.hh
+++ b/lout/misc.hh
@@ -38,6 +38,11 @@ inline void assertNotReached ()
abort ();
}
+inline int roundInt(double d)
+{
+ return (int) ((d > 0) ? (d + 0.5) : (d - 0.5));
+}
+
/**
* \brief Instances of a sub class of this interface may be compared (less,
* greater).
diff --git a/lout/object.cc b/lout/object.cc
index 9eec028e..d72b1eec 100644
--- a/lout/object.cc
+++ b/lout/object.cc
@@ -21,6 +21,7 @@
#include "object.hh"
#include <stdio.h>
+#include <config.h>
namespace lout {
diff --git a/src/IO/Makefile.am b/src/IO/Makefile.am
index b168073c..c889dae8 100644
--- a/src/IO/Makefile.am
+++ b/src/IO/Makefile.am
@@ -1,4 +1,6 @@
-AM_CPPFLAGS=-DDILLO_BINDIR='"$(bindir)/"'
+AM_CPPFLAGS = \
+ -I$(top_srcdir) \
+ -DDILLO_BINDIR='"$(bindir)/"'
AM_CFLAGS = @LIBFLTK_CFLAGS@
AM_CXXFLAGS = @LIBFLTK_CXXFLAGS@
diff --git a/src/IO/mime.c b/src/IO/mime.c
index 9bffd619..19dc601a 100644
--- a/src/IO/mime.c
+++ b/src/IO/mime.c
@@ -108,6 +108,7 @@ void a_Mime_init()
Mime_add_minor_type("image/x-png", a_Dicache_png_image); /* deprecated */
#endif
Mime_add_minor_type("text/html", a_Html_text);
+ Mime_add_minor_type("application/xhtml+xml", a_Html_text);
/* Add a major type to handle all the text stuff */
Mime_add_major_type("text", a_Plain_text);
diff --git a/src/cache.c b/src/cache.c
index fcd27a05..d26ae610 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -311,6 +311,10 @@ static void Cache_entry_free(CacheEntry_t *entry)
dStr_free(entry->UTF8Data, 1);
if (entry->CharsetDecoder)
a_Decode_free(entry->CharsetDecoder);
+ if (entry->TransferDecoder)
+ a_Decode_free(entry->TransferDecoder);
+ if (entry->ContentDecoder)
+ a_Decode_free(entry->ContentDecoder);
dFree(entry);
}
@@ -516,6 +520,10 @@ const char *a_Cache_set_content_type(const DilloUrl *url, const char *ctype,
((!major || !*major) && (!minor || !*minor))) {
/* META only gives charset; use detected MIME type too */
entry->TypeNorm = dStrconcat(entry->TypeDet, ctype, NULL);
+ } else if (*from == 'm' &&
+ !dStrncasecmp(ctype, "text/xhtml", 10)) {
+ /* WORKAROUND: doxygen uses "text/xhtml" in META */
+ entry->TypeNorm = dStrdup(entry->TypeDet);
}
if (charset) {
if (entry->CharsetDecoder)
@@ -932,7 +940,7 @@ static int Cache_redirect(CacheEntry_t *entry, int Flags, BrowserWindow *bw)
(entry->Flags & CA_ForceRedirect || entry->Flags & CA_TempRedirect ||
!entry->Data->len || entry->Data->len < 1024)) {
- _MSG(">>>Redirect from: %s\n to %s\n",
+ _MSG(">>>> Redirect from: %s\n to %s <<<<\n",
URL_STR_(entry->Url), URL_STR_(entry->Location));
_MSG("%s", entry->Header->str);
@@ -946,9 +954,9 @@ static int Cache_redirect(CacheEntry_t *entry, int Flags, BrowserWindow *bw)
} else {
/* Sub entity redirection (most probably an image) */
if (!entry->Data->len) {
- _MSG(">>>Image redirection without entity-content<<<\n");
+ _MSG(">>>> Image redirection without entity-content <<<<\n");
} else {
- _MSG(">>>Image redirection with entity-content<<<\n");
+ _MSG(">>>> Image redirection with entity-content <<<<\n");
}
}
}
diff --git a/src/capi.c b/src/capi.c
index 3df48628..5e2928e3 100644
--- a/src/capi.c
+++ b/src/capi.c
@@ -362,9 +362,9 @@ static void Capi_dpi_send_source(BrowserWindow *bw, DilloUrl *url)
* For a user request, the action will be permitted.
* For an automatic request, permission to load depends on the filter set
* by the user.
- */
-static bool_t Capi_filters_allow(const DilloUrl *wanted,
- const DilloUrl *requester)
+ */
+static bool_t Capi_filters_test(const DilloUrl *wanted,
+ const DilloUrl *requester)
{
bool_t ret;
@@ -392,8 +392,8 @@ static bool_t Capi_filters_allow(const DilloUrl *wanted,
ret = dStrcasecmp(req_suffix, want_suffix) == 0;
}
- MSG("Capi_filters_allow: from %s to %s: %s\n", req_host, want_host,
- ret ? "ALLOWED" : "DENIED");
+ MSG("Capi_filters_test: %s from '%s' to '%s'\n",
+ ret ? "ALLOW" : "DENY", req_host, want_host);
break;
}
case PREFS_FILTER_ALLOW_ALL:
@@ -422,7 +422,7 @@ int a_Capi_open_url(DilloWeb *web, CA_Callback_t Call, void *CbData)
int safe = 0, ret = 0, use_cache = 0;
dReturn_val_if_fail((a_Capi_get_flags(web->url) & CAPI_IsCached) ||
- Capi_filters_allow(web->url, web->requester), 0);
+ Capi_filters_test(web->url, web->requester), 0);
/* reload test */
reload = (!(a_Capi_get_flags(web->url) & CAPI_IsCached) ||
@@ -480,7 +480,7 @@ int a_Capi_open_url(DilloWeb *web, CA_Callback_t Call, void *CbData)
/* create a new connection and start the CCC operations */
conn = Capi_conn_new(web->url, web->bw, "http", "none");
/* start the reception branch before the query one because the DNS
- * may callback immediatly. This may avoid a race condition. */
+ * may callback immediately. This may avoid a race condition. */
a_Capi_ccc(OpStart, 2, BCK, a_Chain_new(), conn, "http");
a_Capi_ccc(OpStart, 1, BCK, a_Chain_new(), conn, web);
}
diff --git a/src/cookies.h b/src/cookies.h
index 482aa5ae..d6ee1ccd 100644
--- a/src/cookies.h
+++ b/src/cookies.h
@@ -8,6 +8,7 @@ extern "C" {
#ifdef DISABLE_COOKIES
# define a_Cookies_get_query(url) dStrdup("")
+# define a_Cookies_set() ;
# define a_Cookies_init() ;
# define a_Cookies_freeall() ;
#else
diff --git a/src/css.cc b/src/css.cc
index 988d0dc6..cb0864fd 100644
--- a/src/css.cc
+++ b/src/css.cc
@@ -25,6 +25,28 @@ void CssProperty::print () {
(int)value.intVal);
}
+CssPropertyList::CssPropertyList (const CssPropertyList &p, bool deep) :
+ lout::misc::SimpleVector <CssProperty> (p)
+{
+ refCount = 0;
+ if (deep) {
+ for (int i = 0; i < size (); i++) {
+ CssProperty *p = getRef(i);
+ switch (p->type) {
+ case CSS_TYPE_STRING:
+ case CSS_TYPE_SYMBOL:
+ p->value.strVal = dStrdup (p->value.strVal);
+ break;
+ default:
+ break;
+ }
+ }
+ ownerOfStrings = true;
+ } else {
+ ownerOfStrings = false;
+ }
+};
+
CssPropertyList::~CssPropertyList () {
if (ownerOfStrings)
for (int i = 0; i < size (); i++)
@@ -428,7 +450,7 @@ void CssStyleSheet::apply (CssPropertyList *props,
}
}
- ruleList[numLists] = elementTable[docTree->top ()->element];
+ ruleList[numLists] = elementTable[node->element];
if (ruleList[numLists])
numLists++;
@@ -512,9 +534,8 @@ CssContext::~CssContext () {
* This allows e.g. user styles to overwrite author styles.
*/
void CssContext::apply (CssPropertyList *props, Doctree *docTree,
+ DoctreeNode *node,
CssPropertyList *tagStyle, CssPropertyList *nonCssHints) {
- const DoctreeNode *node = docTree->top ();
-
if (sheet[CSS_PRIMARY_USER_AGENT])
sheet[CSS_PRIMARY_USER_AGENT]->apply (props, docTree, node);
@@ -558,8 +579,7 @@ void CssContext::addRule (CssSelector *sel, CssPropertyList *props,
*/
void CssContext::buildUserAgentStyle () {
const char *cssBuf =
- "body {background-color: #e0e0a3; font-family: sans-serif; color: black;"
- " margin: 5px}"
+ "body {margin: 5px}"
"big {font-size: 1.17em}"
"blockquote, dd {margin-left: 40px; margin-right: 40px}"
"center {text-align: center}"
@@ -589,8 +609,8 @@ void CssContext::buildUserAgentStyle () {
"sub {vertical-align: sub}"
"sup {vertical-align: super}"
"s, strike, del {text-decoration: line-through}"
- "table {border-style: outset; border-spacing: 1px}"
- "td, th {border-style: inset; padding: 2px}"
+ "table {border-spacing: 2px}"
+ "td, th {padding: 2px}"
"thead, tbody, tfoot {vertical-align: middle}"
"th {font-weight: bolder; text-align: center}"
"code, tt, pre, samp, kbd {font-family: monospace}"
diff --git a/src/css.hh b/src/css.hh
index b23eb9a3..bf7d3c1d 100644
--- a/src/css.hh
+++ b/src/css.hh
@@ -90,7 +90,7 @@ inline CssLength CSS_CREATE_LENGTH (float v, CssLengthType t) {
switch (t) {
case CSS_LENGTH_TYPE_PX:
- iv = (int) (v + 0.5);
+ iv = lout::misc::roundInt(v);
if (iv > CSS_LENGTH_INT_MAX)
iv = CSS_LENGTH_INT_MAX;
else if (iv < -CSS_LENGTH_INT_MAX)
@@ -304,25 +304,11 @@ class CssPropertyList : public lout::misc::SimpleVector <CssProperty> {
refCount = 0;
this->ownerOfStrings = ownerOfStrings;
};
- inline CssPropertyList(const CssPropertyList &p) :
- lout::misc::SimpleVector <CssProperty> (p) {
- refCount = 0;
- ownerOfStrings = false;
- };
+ CssPropertyList(const CssPropertyList &p, bool deep = false);
~CssPropertyList ();
void set (CssPropertyName name, CssValueType type,
CssPropertyValue value);
- inline void set (CssPropertyName name, CssValueType type, char *value) {
- CssPropertyValue v;
- v.strVal = value;
- set (name, type, v);
- };
- inline void set (CssPropertyName name, CssValueType type, int value) {
- CssPropertyValue v;
- v.intVal = value;
- set (name, type, v);
- };
void apply (CssPropertyList *props);
void print ();
inline void ref () { refCount++; }
@@ -476,7 +462,7 @@ class CssContext {
static CssStyleSheet *userStyle;
static CssStyleSheet *userImportantStyle;
CssStyleSheet *sheet[CSS_PRIMARY_USER_IMPORTANT + 1];
- int pos;
+ int pos;
void buildUserAgentStyle ();
void buildUserStyle ();
@@ -488,7 +474,7 @@ class CssContext {
void addRule (CssSelector *sel, CssPropertyList *props,
CssPrimaryOrder order);
void apply (CssPropertyList *props,
- Doctree *docTree,
+ Doctree *docTree, DoctreeNode *node,
CssPropertyList *tagStyle, CssPropertyList *nonCssHints);
};
diff --git a/src/cssparser.cc b/src/cssparser.cc
index 9d141293..7b522c8c 100644
--- a/src/cssparser.cc
+++ b/src/cssparser.cc
@@ -47,6 +47,14 @@ typedef struct {
const char *const *enum_symbols;
} CssPropertyInfo;
+static const char *const Css_border_collapse_enum_vals[] = {
+ "separate", "collapse", NULL
+};
+
+static const char *const Css_border_color_enum_vals[] = {
+ "transparent", NULL
+};
+
static const char *const Css_border_style_enum_vals[] = {
"none", "hidden", "dotted", "dashed", "solid", "double", "groove",
"ridge", "inset", "outset", NULL
@@ -81,6 +89,10 @@ static const char *const Css_font_style_enum_vals[] = {
"normal", "italic", "oblique", NULL
};
+static const char *const Css_font_variant_enum_vals[] = {
+ "normal", "small-caps", NULL
+};
+
static const char *const Css_font_weight_enum_vals[] = {
"bold", "bolder", "light", "lighter", "normal", NULL
};
@@ -132,24 +144,29 @@ const CssPropertyInfo Css_property_info[CSS_PROPERTY_LAST] = {
{"background-image", {CSS_TYPE_UNUSED}, NULL},
{"background-position", {CSS_TYPE_UNUSED}, NULL},
{"background-repeat", {CSS_TYPE_UNUSED}, NULL},
- {"border-bottom-color", {CSS_TYPE_COLOR, CSS_TYPE_UNUSED}, NULL},
+ {"border-bottom-color", {CSS_TYPE_ENUM, CSS_TYPE_COLOR, CSS_TYPE_UNUSED},
+ Css_border_color_enum_vals},
{"border-bottom-style", {CSS_TYPE_ENUM, CSS_TYPE_UNUSED},
Css_border_style_enum_vals},
{"border-bottom-width", {CSS_TYPE_ENUM, CSS_TYPE_LENGTH, CSS_TYPE_UNUSED},
Css_border_width_enum_vals},
- {"border-collapse", {CSS_TYPE_UNUSED}, NULL},
- {"border-left-color", {CSS_TYPE_COLOR, CSS_TYPE_UNUSED}, NULL},
+ {"border-collapse", {CSS_TYPE_ENUM, CSS_TYPE_UNUSED},
+ Css_border_collapse_enum_vals},
+ {"border-left-color", {CSS_TYPE_ENUM, CSS_TYPE_COLOR, CSS_TYPE_UNUSED},
+ Css_border_color_enum_vals},
{"border-left-style", {CSS_TYPE_ENUM, CSS_TYPE_UNUSED},
Css_border_style_enum_vals},
{"border-left-width", {CSS_TYPE_ENUM, CSS_TYPE_LENGTH, CSS_TYPE_UNUSED},
Css_border_width_enum_vals},
- {"border-right-color", {CSS_TYPE_COLOR, CSS_TYPE_UNUSED}, NULL},
+ {"border-right-color", {CSS_TYPE_ENUM, CSS_TYPE_COLOR, CSS_TYPE_UNUSED},
+ Css_border_color_enum_vals},
{"border-right-style", {CSS_TYPE_ENUM, CSS_TYPE_UNUSED},
Css_border_style_enum_vals},
{"border-rigth-width", {CSS_TYPE_ENUM, CSS_TYPE_LENGTH, CSS_TYPE_UNUSED},
Css_border_width_enum_vals},
{"border-spacing", {CSS_TYPE_LENGTH, CSS_TYPE_UNUSED}, NULL},
- {"border-top-color", {CSS_TYPE_COLOR, CSS_TYPE_UNUSED}, NULL},
+ {"border-top-color", {CSS_TYPE_ENUM, CSS_TYPE_COLOR, CSS_TYPE_UNUSED},
+ Css_border_color_enum_vals},
{"border-top-style", {CSS_TYPE_ENUM, CSS_TYPE_UNUSED},
Css_border_style_enum_vals},
{"border-top-width", {CSS_TYPE_ENUM, CSS_TYPE_LENGTH, CSS_TYPE_UNUSED},
@@ -173,7 +190,8 @@ const CssPropertyInfo Css_property_info[CSS_PROPERTY_LAST] = {
{"font-size-adjust", {CSS_TYPE_UNUSED}, NULL},
{"font-stretch", {CSS_TYPE_UNUSED}, NULL},
{"font-style", {CSS_TYPE_ENUM, CSS_TYPE_UNUSED}, Css_font_style_enum_vals},
- {"font-variant", {CSS_TYPE_UNUSED}, NULL},
+ {"font-variant", {CSS_TYPE_ENUM, CSS_TYPE_UNUSED},
+ Css_font_variant_enum_vals},
{"font-weight", {CSS_TYPE_ENUM, CSS_TYPE_FONT_WEIGHT, CSS_TYPE_UNUSED},
Css_font_weight_enum_vals},
{"height", {CSS_TYPE_LENGTH_PERCENTAGE, CSS_TYPE_UNUSED}, NULL},
@@ -212,7 +230,7 @@ const CssPropertyInfo Css_property_info[CSS_PROPERTY_LAST] = {
{"text-align", {CSS_TYPE_ENUM, CSS_TYPE_UNUSED}, Css_text_align_enum_vals},
{"text-decoration", {CSS_TYPE_MULTI_ENUM, CSS_TYPE_UNUSED},
Css_text_decoration_enum_vals},
- {"text-indent", {CSS_TYPE_UNUSED}, NULL},
+ {"text-indent", {CSS_TYPE_LENGTH_PERCENTAGE, CSS_TYPE_UNUSED}, NULL},
{"text-shadow", {CSS_TYPE_UNUSED}, NULL},
{"text-transform", {CSS_TYPE_UNUSED}, NULL},
{"top", {CSS_TYPE_UNUSED}, NULL},
@@ -441,21 +459,21 @@ void CssParser::ungetChar()
/*
* Skip string str if it is found in the input buffer.
+ * If string is found leave bufptr pointing to last matched char.
* If not wind back. The first char is passed as parameter c
* to avoid unnecessary getChar() / ungetChar() calls.
*/
inline bool CssParser::skipString(int c, const char *str)
{
- int n = 0;
+ for (int n = 0; str[n]; n++) {
+ if (n > 0)
+ c = getChar();
- while (str[n]) {
if (str[n] != c) {
while (n--)
ungetChar();
return false;
}
- c = getChar();
- n++;
}
return true;
@@ -663,9 +681,9 @@ bool CssParser::tokenMatchesProperty(CssPropertyName prop, CssValueType *type)
case CSS_TYPE_MULTI_ENUM:
if (ttype == CSS_TK_SYMBOL) {
- if (dStrcasecmp(tval, "none") == 0)
- return true;
- else {
+ if (dStrcasecmp(tval, "none") == 0) {
+ return true;
+ } else {
for (i = 0; Css_property_info[prop].enum_symbols[i]; i++) {
if (dStrcasecmp(tval,
Css_property_info[prop].enum_symbols[i]) == 0)
@@ -1409,54 +1427,171 @@ char * CssParser::parseUrl()
void CssParser::parseImport(DilloHtml *html, DilloUrl *baseUrl)
{
char *urlStr = NULL;
+ bool importSyntaxIsOK = false;
+ bool mediaSyntaxIsOK = true;
+ bool mediaIsSelected = true;
- if (html != NULL &&
- ttype == CSS_TK_SYMBOL &&
- dStrcasecmp(tval, "import") == 0) {
- nextToken();
+ nextToken();
- if (ttype == CSS_TK_SYMBOL &&
- dStrcasecmp(tval, "url") == 0)
- urlStr = parseUrl();
- else if (ttype == CSS_TK_STRING)
- urlStr = dStrdup (tval);
+ if (ttype == CSS_TK_SYMBOL &&
+ dStrcasecmp(tval, "url") == 0)
+ urlStr = parseUrl();
+ else if (ttype == CSS_TK_STRING)
+ urlStr = dStrdup (tval);
- /* Skip all tokens until the expected end. */
- while (!(ttype == CSS_TK_END ||
- (ttype == CSS_TK_CHAR && (tval[0] == ';'))))
+ nextToken();
+
+ /* parse a comma-separated list of media */
+ if (ttype == CSS_TK_SYMBOL) {
+ mediaSyntaxIsOK = false;
+ mediaIsSelected = false;
+ while (ttype == CSS_TK_SYMBOL) {
+ if (dStrcasecmp(tval, "all") == 0 ||
+ dStrcasecmp(tval, "screen") == 0)
+ mediaIsSelected = true;
nextToken();
+ if (ttype == CSS_TK_CHAR && tval[0] == ',') {
+ nextToken();
+ } else {
+ mediaSyntaxIsOK = true;
+ break;
+ }
+ }
+ }
+ if (mediaSyntaxIsOK &&
+ ttype == CSS_TK_CHAR &&
+ tval[0] == ';') {
+ importSyntaxIsOK = true;
nextToken();
+ } else
+ ignoreStatement();
- if (urlStr) {
+ if (urlStr) {
+ if (importSyntaxIsOK && mediaIsSelected) {
MSG("CssParser::parseImport(): @import %s\n", urlStr);
DilloUrl *url = a_Html_url_new (html, urlStr, a_Url_str(baseUrl),
baseUrl ? 1 : 0);
a_Html_load_stylesheet(html, url);
a_Url_free(url);
- dFree (urlStr);
+ }
+ dFree (urlStr);
+ }
+}
+
+void CssParser::parseMedia()
+{
+ bool mediaSyntaxIsOK = false;
+ bool mediaIsSelected = false;
+
+ nextToken();
+
+ /* parse a comma-separated list of media */
+ while (ttype == CSS_TK_SYMBOL) {
+ if (dStrcasecmp(tval, "all") == 0 ||
+ dStrcasecmp(tval, "screen") == 0)
+ mediaIsSelected = true;
+ nextToken();
+ if (ttype == CSS_TK_CHAR && tval[0] == ',') {
+ nextToken();
+ } else {
+ mediaSyntaxIsOK = true;
+ break;
}
}
+
+ /* check that the syntax is OK so far */
+ if (!(mediaSyntaxIsOK &&
+ ttype == CSS_TK_CHAR &&
+ tval[0] == '{')) {
+ ignoreStatement();
+ return;
+ }
+
+ /* parse/ignore the block as required */
+ if (mediaIsSelected) {
+ nextToken();
+ while (ttype != CSS_TK_END) {
+ parseRuleset();
+ if (ttype == CSS_TK_CHAR && tval[0] == '}') {
+ nextToken();
+ break;
+ }
+ }
+ } else
+ ignoreBlock();
}
const char * CssParser::propertyNameString(CssPropertyName name)
{
return Css_property_info[name].symbol;
}
+
+void CssParser::ignoreBlock()
+{
+ int depth = 0;
+
+ while (ttype != CSS_TK_END) {
+ if (ttype == CSS_TK_CHAR) {
+ if (tval[0] == '{') {
+ depth++;
+ } else if (tval[0] == '}') {
+ depth--;
+ if (depth == 0) {
+ nextToken();
+ return;
+ }
+ }
+ }
+ nextToken();
+ }
+}
+
+void CssParser::ignoreStatement()
+{
+ while (ttype != CSS_TK_END) {
+ if (ttype == CSS_TK_CHAR) {
+ if (tval[0] == ';') {
+ nextToken();
+ return;
+ } else if (tval[0] =='{') {
+ ignoreBlock();
+ return;
+ }
+ }
+ nextToken();
+ }
+}
void CssParser::parse(DilloHtml *html, DilloUrl *url, CssContext * context,
const char *buf,
int buflen, CssOrigin origin)
{
CssParser parser (context, origin, buf, buflen);
-
- while (parser.ttype == CSS_TK_CHAR && parser.tval[0] == '@') {
- parser.nextToken();
- parser.parseImport(html, url);
+ bool importsAreAllowed = true;
+
+ while (parser.ttype != CSS_TK_END) {
+ if (parser.ttype == CSS_TK_CHAR &&
+ parser.tval[0] == '@') {
+ parser.nextToken();
+ if (parser.ttype == CSS_TK_SYMBOL) {
+ if (dStrcasecmp(parser.tval, "import") == 0 &&
+ html != NULL &&
+ importsAreAllowed) {
+ parser.parseImport(html, url);
+ } else if (dStrcasecmp(parser.tval, "media") == 0) {
+ parser.parseMedia();
+ } else {
+ parser.ignoreStatement();
+ }
+ } else {
+ parser.ignoreStatement();
+ }
+ } else {
+ importsAreAllowed = false;
+ parser.parseRuleset();
+ }
}
-
- while (parser.ttype != CSS_TK_END)
- parser.parseRuleset();
}
CssPropertyList *CssParser::parseDeclarationBlock(const char *buf, int buflen)
diff --git a/src/cssparser.hh b/src/cssparser.hh
index 1e471c68..1542405d 100644
--- a/src/cssparser.hh
+++ b/src/cssparser.hh
@@ -40,8 +40,11 @@ class CssParser {
bool parseSimpleSelector(CssSimpleSelector *selector);
char *parseUrl();
void parseImport(DilloHtml *html, DilloUrl *url);
+ void parseMedia();
CssSelector *parseSelector();
void parseRuleset();
+ void ignoreBlock();
+ void ignoreStatement();
public:
static CssPropertyList *parseDeclarationBlock(const char *buf,
diff --git a/src/dillo.cc b/src/dillo.cc
index a42b0dab..3159674e 100644
--- a/src/dillo.cc
+++ b/src/dillo.cc
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <time.h>
#include <signal.h>
+#include <locale.h>
#include <fltk/Window.h>
#include <fltk/TabGroup.h>
diff --git a/src/form.cc b/src/form.cc
index 38afea8f..18441fb8 100644
--- a/src/form.cc
+++ b/src/form.cc
@@ -554,12 +554,9 @@ void Html_tag_open_input(DilloHtml *html, const char *tag, int tagsize)
}
if (prefs.show_tooltip &&
(attrbuf = a_Html_get_attr(html, tag, tagsize, "title"))) {
- CssPropertyList props;
- char *tooltip_str = dStrdup(attrbuf);
- props.set (PROPERTY_X_TOOLTIP, CSS_TYPE_STRING, tooltip_str);
- html->styleEngine->setNonCssHints (&props);
- dFree(tooltip_str);
+ html->styleEngine->setNonCssHint (PROPERTY_X_TOOLTIP, CSS_TYPE_STRING,
+ attrbuf);
}
HT2TB(html)->addWidget (embed, html->styleEngine->backgroundStyle());
}
@@ -930,7 +927,7 @@ DilloHtmlForm::~DilloHtmlForm ()
void DilloHtmlForm::eventHandler(Resource *resource, EventButton *event)
{
- MSG("DilloHtmlForm::eventHandler\n");
+ _MSG("DilloHtmlForm::eventHandler\n");
if (event && (event->button == 3)) {
a_UIcmd_form_popup(html->bw, html->page_url, this, showing_hiddens);
} else {
diff --git a/src/gif.c b/src/gif.c
index 3df83d20..b5486c46 100644
--- a/src/gif.c
+++ b/src/gif.c
@@ -351,8 +351,6 @@ static size_t Gif_do_extension(DilloGif *gif, uint_t Label,
return Gif_data_blocks(buf, BSize);
case Txt_Ext: /* Plain text Extension */
- /* This extension allows (rcm thinks) the image to be rendered as text.
- */
case App_Ext: /* Application Extension */
default:
return Gif_do_generic_ext(buf, BSize); /*Ignore Extension */
@@ -428,16 +426,6 @@ static void Gif_emit_line(DilloGif *gif, const uchar_t *linebuf)
}
/*
- * I apologize for the large size of this routine and the goto error
- * construct - I almost _never_ do that. I offer the excuse of
- * optimizing for speed.
- *
- * RCM -- busted these down into smaller subroutines... still very hard to
- * read.
- */
-
-
-/*
* Decode the packetized lwz bytes
*/
static void Gif_literal(DilloGif *gif, uint_t code)
@@ -816,7 +804,7 @@ static size_t Gif_do_img_desc(DilloGif *gif, void *Buf,
/* check max image size */
if (gif->Width <= 0 || gif->Height <= 0 ||
gif->Width > IMAGE_MAX_AREA / gif->Height) {
- MSG("Gif_do_img_desc: suspicious image size request %ux%u\n",
+ MSG("Gif_do_img_desc: suspicious image size request %u x %u\n",
gif->Width, gif->Height);
gif->state = 999;
return 0;
diff --git a/src/html.cc b/src/html.cc
index 25942514..bcefe14b 100644
--- a/src/html.cc
+++ b/src/html.cc
@@ -68,9 +68,8 @@ using namespace dw::core::style;
* Typedefs
*---------------------------------------------------------------------------*/
class DilloHtml;
-typedef void (*TagOpenFunct) (DilloHtml *Html, const char *Tag, int Tagsize);
-typedef void (*TagCloseFunct) (DilloHtml *Html, int TagIdx);
-typedef struct _DilloHtmlClass DilloHtmlClass;
+typedef void (*TagOpenFunct) (DilloHtml *html, const char *tag, int tagsize);
+typedef void (*TagCloseFunct) (DilloHtml *html, int TagIdx);
typedef enum {
SEEK_ATTR_START,
@@ -305,9 +304,7 @@ static void Html_add_new_htmlimage(DilloHtml *html,
* Evaluates the ALIGN attribute (left|center|right|justify) and
* sets the style at the top of the stack.
*/
-void a_Html_tag_set_align_attr(DilloHtml *html,
- CssPropertyList *props,
- const char *tag, int tagsize)
+void a_Html_tag_set_align_attr(DilloHtml *html, const char *tag, int tagsize)
{
const char *align;
@@ -340,7 +337,8 @@ void a_Html_tag_set_align_attr(DilloHtml *html,
style_attrs.textAlignChar = '.';
}
#endif
- props->set (CSS_PROPERTY_TEXT_ALIGN, CSS_TYPE_ENUM, textAlignType);
+ html->styleEngine->setNonCssHint(CSS_PROPERTY_TEXT_ALIGN, CSS_TYPE_ENUM,
+ textAlignType);
}
}
@@ -348,8 +346,7 @@ void a_Html_tag_set_align_attr(DilloHtml *html,
* Evaluates the VALIGN attribute (top|bottom|middle|baseline) and
* sets the style in style_attrs. Returns true when set.
*/
-bool a_Html_tag_set_valign_attr(DilloHtml *html, const char *tag,
- int tagsize, CssPropertyList *props)
+bool a_Html_tag_set_valign_attr(DilloHtml *html, const char *tag, int tagsize)
{
const char *attr;
VAlignType valign;
@@ -364,7 +361,8 @@ bool a_Html_tag_set_valign_attr(DilloHtml *html, const char *tag,
else
valign = VALIGN_MIDDLE;
- props->set (CSS_PROPERTY_VERTICAL_ALIGN, CSS_TYPE_ENUM, valign);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_VERTICAL_ALIGN,
+ CSS_TYPE_ENUM, valign);
return true;
} else
return false;
@@ -433,9 +431,9 @@ DilloHtml::DilloHtml(BrowserWindow *p_bw, const DilloUrl *url,
stack = new misc::SimpleVector <DilloHtmlState> (16);
stack->increase();
- stack->getRef(0)->table_cell_props = NULL;
stack->getRef(0)->parse_mode = DILLO_HTML_PARSE_MODE_INIT;
stack->getRef(0)->table_mode = DILLO_HTML_TABLE_MODE_NONE;
+ stack->getRef(0)->table_border_mode = DILLO_HTML_TABLE_BORDER_SEPARATE;
stack->getRef(0)->cell_text_align_set = false;
stack->getRef(0)->list_type = HTML_LIST_NONE;
stack->getRef(0)->list_number = 0;
@@ -586,9 +584,6 @@ int DilloHtml::getCurTagLineNumber()
*/
void DilloHtml::freeParseData()
{
- for (int i = stack->size () - 1; i >= 0; i--)
- if (stack->getRef (i)->table_cell_props)
- stack->getRef (i)->table_cell_props->unref ();
delete(stack);
dStr_free(Stash, TRUE);
@@ -1189,13 +1184,13 @@ static void Html_process_word(DilloHtml *html, const char *word, int size)
dFree(Pword);
} else {
- const char *word2, *word2_end;
+ const char *word2, *beyond_word2;
Pword = NULL;
if (!memchr(word,'&', size)) {
/* No entities */
word2 = word;
- word2_end = word + size - 1;
+ beyond_word2 = word + size;
} else {
/* Collapse white-space entities inside the word (except &nbsp;) */
Pword = a_Html_parse_entities(html, word, size);
@@ -1210,7 +1205,7 @@ static void Html_process_word(DilloHtml *html, const char *word, int size)
}
}
word2 = Pword;
- word2_end = word2 + strlen(word2) - 1;
+ beyond_word2 = word2 + strlen(word2);
}
for (start = i = 0; word2[i]; start = i) {
int len;
@@ -1220,7 +1215,7 @@ static void Html_process_word(DilloHtml *html, const char *word, int size)
Html_process_space(html, word2 + start, i - start);
} else if (!strncmp(word2+i, utf8_zero_width_space, 3)) {
i += 3;
- } else if (a_Utf8_ideographic(word2+i, word2_end, &len)) {
+ } else if (a_Utf8_ideographic(word2+i, beyond_word2, &len)) {
i += len;
HT2TB(html)->addText(word2 + start, i - start,
html->styleEngine->wordStyle ());
@@ -1229,7 +1224,7 @@ static void Html_process_word(DilloHtml *html, const char *word, int size)
i += len;
} while (word2[i] && !isspace(word2[i]) &&
strncmp(word2+i, utf8_zero_width_space, 3) &&
- (!a_Utf8_ideographic(word2+i, word2_end, &len)));
+ (!a_Utf8_ideographic(word2+i, beyond_word2, &len)));
HT2TB(html)->addText(word2 + start, i - start,
html->styleEngine->wordStyle ());
}
@@ -1284,8 +1279,6 @@ static void Html_push_tag(DilloHtml *html, int tag_idx)
* instead of copying all fields except for tag. --Jcid */
*html->stack->getRef(n_items) = *html->stack->getRef(n_items - 1);
html->stack->getRef(n_items)->tag_idx = tag_idx;
- if (S_TOP(html)->table_cell_props)
- S_TOP(html)->table_cell_props->ref ();
html->dw = S_TOP(html)->textblock;
}
@@ -1307,8 +1300,6 @@ static void Html_real_pop_tag(DilloHtml *html)
bool hand_over_break;
html->styleEngine->endElement (S_TOP(html)->tag_idx);
- if (S_TOP(html)->table_cell_props)
- S_TOP(html)->table_cell_props->unref ();
hand_over_break = S_TOP(html)->hand_over_break;
html->stack->setSize (html->stack->size() - 1);
Html_eventually_pop_dw(html, hand_over_break);
@@ -1505,7 +1496,8 @@ static int
*/
static void Html_parse_doctype(DilloHtml *html, const char *tag, int tagsize)
{
- static const char HTML_sig [] = "<!DOCTYPE HTML PUBLIC ";
+ static const char HTML_SGML_sig [] = "<!DOCTYPE HTML PUBLIC ";
+ static const char HTML5_sig [] = "<!DOCTYPE html>";
static const char HTML20 [] = "-//IETF//DTD HTML 2.0";
static const char HTML32 [] = "-//W3C//DTD HTML 3.2";
static const char HTML40 [] = "-//W3C//DTD HTML 4.0";
@@ -1541,8 +1533,8 @@ static void Html_parse_doctype(DilloHtml *html, const char *tag, int tagsize)
_MSG("New: {%s}\n", ntag);
/* The default DT_NONE type is TagSoup */
- if (!dStrncasecmp(ntag, HTML_sig, strlen(HTML_sig))) {
- p = ntag + strlen(HTML_sig) + 1;
+ if (!dStrncasecmp(ntag, HTML_SGML_sig, strlen(HTML_SGML_sig))) {
+ p = ntag + strlen(HTML_SGML_sig) + 1;
if (!strncmp(p, HTML401, strlen(HTML401)) &&
dStristr(p + strlen(HTML401), HTML401_url)) {
html->DocType = DT_HTML;
@@ -1565,6 +1557,10 @@ static void Html_parse_doctype(DilloHtml *html, const char *tag, int tagsize)
html->DocType = DT_HTML;
html->DocTypeVersion = 2.0f;
}
+ } else if (!dStrcasecmp(ntag, HTML5_sig)) {
+ BUG_MSG("Document follows HTML5 working draft; treating as HTML4.\n");
+ html->DocType = DT_HTML;
+ html->DocTypeVersion = 5.0f;
}
dFree(ntag);
@@ -1728,9 +1724,9 @@ static void Html_tag_open_body(DilloHtml *html, const char *tag, int tagsize)
{
const char *attrbuf;
Textblock *textblock;
- CssPropertyList props;
int32_t color;
int tag_index_a = a_Html_tag_index ("a");
+ style::Color *bgColor;
if (!(html->InFlags & IN_BODY))
html->InFlags |= IN_BODY;
@@ -1750,24 +1746,32 @@ static void Html_tag_open_body(DilloHtml *html, const char *tag, int tagsize)
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "bgcolor"))) {
color = a_Html_color_parse(html, attrbuf, -1);
if (color != -1)
- props.set (CSS_PROPERTY_BACKGROUND_COLOR, CSS_TYPE_COLOR, color);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BACKGROUND_COLOR,
+ CSS_TYPE_COLOR, color);
}
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "text"))) {
color = a_Html_color_parse(html, attrbuf, -1);
if (color != -1)
- props.set (CSS_PROPERTY_COLOR, CSS_TYPE_COLOR, color);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_COLOR,
+ CSS_TYPE_COLOR, color);
}
+ html->styleEngine->restyle ();
+
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "link")))
html->non_css_link_color = a_Html_color_parse(html, attrbuf, -1);
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "vlink")))
html->non_css_visited_color = a_Html_color_parse(html, attrbuf, -1);
- html->styleEngine->setNonCssHints (&props);
html->dw->setStyle (html->styleEngine->style ());
+ bgColor = html->styleEngine->backgroundColor ();
+
+ if (bgColor)
+ HT2LT(html)->setBgColor(bgColor);
+
/* Determine a color for visited links.
* This color is computed once per page and used for immediate feedback
* when clicking a link.
@@ -1777,10 +1781,8 @@ static void Html_tag_open_body(DilloHtml *html, const char *tag, int tagsize)
html->styleEngine->startElement (tag_index_a);
html->styleEngine->setPseudoVisited ();
if (html->non_css_visited_color != -1) {
- CssPropertyList vprops;
- vprops.set (CSS_PROPERTY_COLOR, CSS_TYPE_COLOR,
- html->non_css_visited_color);
- html->styleEngine->setNonCssHints (&vprops);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_COLOR, CSS_TYPE_COLOR,
+ html->non_css_visited_color);
}
html->visited_color = html->styleEngine->style ()->color->getColor ();
html->styleEngine->endElement (tag_index_a);
@@ -1794,6 +1796,7 @@ static void Html_tag_open_body(DilloHtml *html, const char *tag, int tagsize)
html->styleEngine->backgroundStyle()->backgroundColor->getColor());
}
+
S_TOP(html)->parse_mode = DILLO_HTML_PARSE_MODE_BODY;
}
@@ -1817,9 +1820,8 @@ static void Html_tag_open_p(DilloHtml *html, const char *tag, int tagsize)
{
CssPropertyList props;
- a_Html_tag_set_align_attr (html, &props, tag, tagsize);
+ a_Html_tag_set_align_attr (html, tag, tagsize);
html->styleEngine->inheritBackgroundColor ();
- html->styleEngine->setNonCssHints (&props);
HT2TB(html)->addParbreak (9, html->styleEngine->wordStyle ());
}
@@ -1855,8 +1857,8 @@ static void Html_tag_open_frame (DilloHtml *html, const char *tag, int tagsize)
html->styleEngine->setPseudoLink ();
}
- props.set (PROPERTY_X_LINK, CSS_TYPE_INTEGER, Html_set_new_link(html,&url));
- html->styleEngine->setNonCssHints (&props);
+ html->styleEngine->setNonCssHint (PROPERTY_X_LINK, CSS_TYPE_INTEGER,
+ Html_set_new_link(html,&url));
textblock->addParbreak (5, html->styleEngine->wordStyle ());
@@ -1902,12 +1904,8 @@ static void Html_tag_open_frameset (DilloHtml *html,
*/
static void Html_tag_open_h(DilloHtml *html, const char *tag, int tagsize)
{
- CssPropertyList props;
-
-
html->styleEngine->inheritBackgroundColor ();
- a_Html_tag_set_align_attr (html, &props, tag, tagsize);
- html->styleEngine->setNonCssHints (&props);
+ a_Html_tag_set_align_attr (html, tag, tagsize);
HT2TB(html)->addParbreak (9, html->styleEngine->wordStyle ());
@@ -1932,7 +1930,6 @@ static void Html_tag_open_font(DilloHtml *html, const char *tag, int tagsize)
const char *attrbuf;
char *fontFamily = NULL;
int32_t color;
- CssPropertyList props;
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "color"))) {
if (prefs.contrast_visited_color && html->InVisitedLink) {
@@ -1942,15 +1939,16 @@ static void Html_tag_open_font(DilloHtml *html, const char *tag, int tagsize)
color = a_Html_color_parse(html, attrbuf, -1);
}
if (color != -1)
- props.set (CSS_PROPERTY_COLOR, CSS_TYPE_COLOR, color);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_COLOR,
+ CSS_TYPE_COLOR, color);
}
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "face"))) {
fontFamily = dStrdup(attrbuf);
- props.set (CSS_PROPERTY_FONT_FAMILY, CSS_TYPE_SYMBOL, fontFamily);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_FONT_FAMILY,
+ CSS_TYPE_SYMBOL, fontFamily);
}
- html->styleEngine->setNonCssHints (&props);
dFree(fontFamily);
}
@@ -1961,14 +1959,13 @@ static void Html_tag_open_abbr(DilloHtml *html, const char *tag, int tagsize)
{
const char *attrbuf;
+ html->styleEngine->inheritBackgroundColor ();
+
if (prefs.show_tooltip &&
(attrbuf = a_Html_get_attr(html, tag, tagsize, "title"))) {
- CssPropertyList props;
- char *tooltip_str = dStrdup(attrbuf);
- props.set (PROPERTY_X_TOOLTIP, CSS_TYPE_STRING, tooltip_str);
- html->styleEngine->setNonCssHints (&props);
- dFree(tooltip_str);
+ html->styleEngine->setNonCssHint (PROPERTY_X_TOOLTIP, CSS_TYPE_STRING,
+ attrbuf);
}
}
@@ -1977,6 +1974,7 @@ static void Html_tag_open_abbr(DilloHtml *html, const char *tag, int tagsize)
*/
static void Html_tag_open_center(DilloHtml *html, const char *tag, int tagsize)
{
+ html->styleEngine->inheritBackgroundColor ();
HT2TB(html)->addParbreak (0, html->styleEngine->wordStyle ());
}
@@ -1994,6 +1992,7 @@ static void Html_tag_close_center(DilloHtml *html, int TagIdx)
static void Html_tag_open_address(DilloHtml *html,
const char *tag, int tagsize)
{
+ html->styleEngine->inheritBackgroundColor ();
HT2TB(html)->addParbreak (9, html->styleEngine->wordStyle ());
}
@@ -2010,13 +2009,11 @@ DilloImage *a_Html_image_new(DilloHtml *html, const char *tag,
CssLength l_h = CSS_CREATE_LENGTH(0.0, CSS_LENGTH_TYPE_AUTO);
int space, border, w = 0, h = 0;
bool load_now;
- CssPropertyList props;
- char *tooltip_str = NULL;
if (prefs.show_tooltip &&
(attrbuf = a_Html_get_attr(html, tag, tagsize, "title"))) {
- tooltip_str = dStrdup(attrbuf);
- props.set (PROPERTY_X_TOOLTIP, CSS_TYPE_STRING, tooltip_str);
+ html->styleEngine->setNonCssHint(PROPERTY_X_TOOLTIP, CSS_TYPE_STRING,
+ attrbuf);
}
alt_ptr = a_Html_get_attr_wdef(html, tag, tagsize, "alt", NULL);
if ((!alt_ptr || !*alt_ptr) && !prefs.load_images) {
@@ -2052,12 +2049,14 @@ DilloImage *a_Html_image_new(DilloHtml *html, const char *tag,
dFree(width_ptr);
dFree(height_ptr);
width_ptr = height_ptr = NULL;
- MSG("a_Html_image_new: suspicious image size request %dx%d\n", w, h);
+ MSG("a_Html_image_new: suspicious image size request %d x %d\n", w, h);
} else {
if (CSS_LENGTH_TYPE(l_w) != CSS_LENGTH_TYPE_AUTO)
- props.set (CSS_PROPERTY_WIDTH, CSS_TYPE_LENGTH_PERCENTAGE, l_w);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_WIDTH,
+ CSS_TYPE_LENGTH_PERCENTAGE, l_w);
if (CSS_LENGTH_TYPE(l_h) != CSS_LENGTH_TYPE_AUTO)
- props.set (CSS_PROPERTY_HEIGHT, CSS_TYPE_LENGTH_PERCENTAGE, l_h);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_HEIGHT,
+ CSS_TYPE_LENGTH_PERCENTAGE, l_h);
}
/* TODO: we should scale the image respecting its ratio.
@@ -2072,10 +2071,10 @@ DilloImage *a_Html_image_new(DilloHtml *html, const char *tag,
space = strtol(attrbuf, NULL, 10);
if (space > 0) {
space = CSS_CREATE_LENGTH(space, CSS_LENGTH_TYPE_PX);
- props.set (CSS_PROPERTY_MARGIN_LEFT, CSS_TYPE_LENGTH_PERCENTAGE,
- space);
- props.set (CSS_PROPERTY_MARGIN_RIGHT, CSS_TYPE_LENGTH_PERCENTAGE,
- space);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_MARGIN_LEFT,
+ CSS_TYPE_LENGTH_PERCENTAGE, space);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_MARGIN_RIGHT,
+ CSS_TYPE_LENGTH_PERCENTAGE, space);
}
}
@@ -2084,10 +2083,10 @@ DilloImage *a_Html_image_new(DilloHtml *html, const char *tag,
space = strtol(attrbuf, NULL, 10);
if (space > 0) {
space = CSS_CREATE_LENGTH(space, CSS_LENGTH_TYPE_PX);
- props.set (CSS_PROPERTY_MARGIN_TOP, CSS_TYPE_LENGTH_PERCENTAGE,
- space);
- props.set (CSS_PROPERTY_MARGIN_BOTTOM, CSS_TYPE_LENGTH_PERCENTAGE,
- space);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_MARGIN_TOP,
+ CSS_TYPE_LENGTH_PERCENTAGE, space);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_MARGIN_BOTTOM,
+ CSS_TYPE_LENGTH_PERCENTAGE, space);
}
}
@@ -2096,31 +2095,30 @@ DilloImage *a_Html_image_new(DilloHtml *html, const char *tag,
border = strtol(attrbuf, NULL, 10);
if (border >= 0) {
border = CSS_CREATE_LENGTH(border, CSS_LENGTH_TYPE_PX);
- props.set (CSS_PROPERTY_BORDER_TOP_WIDTH, CSS_TYPE_LENGTH_PERCENTAGE,
- border);
- props.set (CSS_PROPERTY_BORDER_BOTTOM_WIDTH,
- CSS_TYPE_LENGTH_PERCENTAGE, border);
- props.set (CSS_PROPERTY_BORDER_LEFT_WIDTH,
- CSS_TYPE_LENGTH_PERCENTAGE, border);
- props.set (CSS_PROPERTY_BORDER_RIGHT_WIDTH,
- CSS_TYPE_LENGTH_PERCENTAGE, border);
-
- props.set (CSS_PROPERTY_BORDER_TOP_STYLE, CSS_TYPE_ENUM,
- BORDER_SOLID);
- props.set (CSS_PROPERTY_BORDER_BOTTOM_STYLE, CSS_TYPE_ENUM,
- BORDER_SOLID);
- props.set (CSS_PROPERTY_BORDER_LEFT_STYLE, CSS_TYPE_ENUM,
- BORDER_SOLID);
- props.set (CSS_PROPERTY_BORDER_RIGHT_STYLE, CSS_TYPE_ENUM,
- BORDER_SOLID);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_TOP_WIDTH,
+ CSS_TYPE_LENGTH_PERCENTAGE, border);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_BOTTOM_WIDTH,
+ CSS_TYPE_LENGTH_PERCENTAGE, border);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_LEFT_WIDTH,
+ CSS_TYPE_LENGTH_PERCENTAGE, border);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_RIGHT_WIDTH,
+ CSS_TYPE_LENGTH_PERCENTAGE, border);
+
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_TOP_STYLE,
+ CSS_TYPE_ENUM, BORDER_SOLID);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_BOTTOM_STYLE,
+ CSS_TYPE_ENUM, BORDER_SOLID);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_LEFT_STYLE,
+ CSS_TYPE_ENUM, BORDER_SOLID);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_RIGHT_STYLE,
+ CSS_TYPE_ENUM, BORDER_SOLID);
}
}
/* x_img is an index to a list of {url,image} pairs.
* We know Html_add_new_htmlimage() will use size() as its next index */
- props.set (PROPERTY_X_IMG, CSS_TYPE_INTEGER, html->images->size());
-
- html->styleEngine->setNonCssHints(&props);
+ html->styleEngine->setNonCssHint (PROPERTY_X_IMG, CSS_TYPE_INTEGER,
+ html->images->size());
/* Add a new image widget to this page */
Image = a_Image_new(alt_ptr, 0);
@@ -2135,7 +2133,6 @@ DilloImage *a_Html_image_new(DilloHtml *html, const char *tag,
loading = Html_load_image(html->bw, url, html->page_url, Image);
Html_add_new_htmlimage(html, &url, loading ? NULL : Image);
- dFree(tooltip_str);
dFree(width_ptr);
dFree(height_ptr);
dFree(alt_ptr);
@@ -2279,7 +2276,7 @@ misc::SimpleVector<int> *Html_read_coords(DilloHtml *html, const char *str)
if (!*newtail)
break;
if (*newtail != ',') {
- BUG_MSG("usemap coords MUST be separated by commas.\n");
+ BUG_MSG("area coords must be integers separated by commas.\n");
}
tail = newtail + 1;
}
@@ -2347,10 +2344,6 @@ static void Html_tag_open_area(DilloHtml *html, const char *tag, int tagsize)
shape = poly = new Polygon();
for (i = 0; i < (coords->size() / 2); i++)
poly->addPoint(coords->get(2*i), coords->get(2*i + 1));
- if (i) {
- /* be sure to close it */
- poly->addPoint(coords->get(0), coords->get(1));
- }
}
delete(coords);
}
@@ -2379,7 +2372,6 @@ static void Html_tag_open_object(DilloHtml *html, const char *tag, int tagsize)
{
DilloUrl *url, *base_url = NULL;
const char *attrbuf;
- CssPropertyList props;
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "codebase"))) {
base_url = a_Html_url_new(html, attrbuf, NULL, 0);
@@ -2396,9 +2388,8 @@ static void Html_tag_open_object(DilloHtml *html, const char *tag, int tagsize)
html->styleEngine->setPseudoLink ();
}
- props.set(PROPERTY_X_LINK, CSS_TYPE_INTEGER,
- Html_set_new_link(html, &url));
- html->styleEngine->setNonCssHints (&props);
+ html->styleEngine->setNonCssHint(PROPERTY_X_LINK, CSS_TYPE_INTEGER,
+ Html_set_new_link(html, &url));
HT2TB(html)->addText("[OBJECT]", html->styleEngine->wordStyle ());
}
@@ -2452,8 +2443,6 @@ static void Html_add_anchor(DilloHtml *html, const char *name)
static void Html_tag_open_a(DilloHtml *html, const char *tag, int tagsize)
{
DilloUrl *url;
- char *tooltip_str = NULL;
- CssPropertyList props;
const char *attrbuf;
/* TODO: add support for MAP with A HREF */
@@ -2472,25 +2461,23 @@ static void Html_tag_open_a(DilloHtml *html, const char *tag, int tagsize)
html->InVisitedLink = true;
html->styleEngine->setPseudoVisited ();
if (html->non_css_visited_color != -1)
- props.set (CSS_PROPERTY_COLOR, CSS_TYPE_COLOR,
- html->non_css_visited_color);
+ html->styleEngine->setNonCssHint(CSS_PROPERTY_COLOR, CSS_TYPE_COLOR,
+ html->non_css_visited_color);
} else {
html->styleEngine->setPseudoLink ();
if (html->non_css_link_color != -1)
- props.set (CSS_PROPERTY_COLOR, CSS_TYPE_COLOR,
- html->non_css_link_color);
+ html->styleEngine->setNonCssHint(CSS_PROPERTY_COLOR, CSS_TYPE_COLOR,
+ html->non_css_link_color);
}
- props.set (PROPERTY_X_LINK, CSS_TYPE_INTEGER,
- Html_set_new_link(html, &url));
+ html->styleEngine->setNonCssHint (PROPERTY_X_LINK, CSS_TYPE_INTEGER,
+ Html_set_new_link(html, &url));
}
if (prefs.show_tooltip &&
(attrbuf = a_Html_get_attr(html, tag, tagsize, "title"))) {
- tooltip_str = dStrdup(attrbuf);
- props.set (PROPERTY_X_TOOLTIP, CSS_TYPE_STRING, tooltip_str);
+ html->styleEngine->setNonCssHint (PROPERTY_X_TOOLTIP, CSS_TYPE_STRING,
+ attrbuf);
}
- html->styleEngine->setNonCssHints (&props);
- dFree(tooltip_str);
html->styleEngine->inheritBackgroundColor ();
@@ -2538,13 +2525,14 @@ static void Html_tag_open_blockquote(DilloHtml *html,
*/
static void Html_tag_open_q(DilloHtml *html, const char *tag, int tagsize)
{
- /*
- * Left Double Quotation Mark, which is wrong in many cases, but
- * should at least be widely recognized.
- */
- const char *U201C = "\xe2\x80\x9c";
+ /*
+ * Left Double Quotation Mark, which is wrong in many cases, but
+ * should at least be widely recognized.
+ */
+ const char *U201C = "\xe2\x80\x9c";
- HT2TB(html)->addText (U201C, html->styleEngine->wordStyle ());
+ html->styleEngine->inheritBackgroundColor ();
+ HT2TB(html)->addText (U201C, html->styleEngine->wordStyle ());
}
/*
@@ -2567,7 +2555,6 @@ static void Html_tag_open_ul(DilloHtml *html, const char *tag, int tagsize)
ListStyleType list_style_type;
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "type"))) {
- CssPropertyList props;
/* list_style_type explicitly defined */
if (dStrcasecmp(attrbuf, "disc") == 0)
@@ -2580,8 +2567,8 @@ static void Html_tag_open_ul(DilloHtml *html, const char *tag, int tagsize)
/* invalid value */
list_style_type = LIST_STYLE_TYPE_DISC;
- props.set(CSS_PROPERTY_LIST_STYLE_TYPE, CSS_TYPE_ENUM, list_style_type);
- html->styleEngine->setNonCssHints (&props);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_LIST_STYLE_TYPE,
+ CSS_TYPE_ENUM, list_style_type);
}
Html_add_textblock(html, 9);
@@ -2597,6 +2584,7 @@ static void Html_tag_open_ul(DilloHtml *html, const char *tag, int tagsize)
*/
static void Html_tag_open_dir(DilloHtml *html, const char *tag, int tagsize)
{
+ html->styleEngine->inheritBackgroundColor ();
HT2TB(html)->addParbreak (9, html->styleEngine->wordStyle ());
S_TOP(html)->list_type = HTML_LIST_UNORDERED;
@@ -2624,7 +2612,6 @@ static void Html_tag_open_ol(DilloHtml *html, const char *tag, int tagsize)
int n = 1;
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "type"))) {
- CssPropertyList props;
ListStyleType listStyleType = LIST_STYLE_TYPE_DECIMAL;
if (*attrbuf == '1')
@@ -2638,8 +2625,8 @@ static void Html_tag_open_ol(DilloHtml *html, const char *tag, int tagsize)
else if (*attrbuf == 'I')
listStyleType = LIST_STYLE_TYPE_UPPER_ROMAN;
- props.set (CSS_PROPERTY_LIST_STYLE_TYPE, CSS_TYPE_ENUM, listStyleType);
- html->styleEngine->setNonCssHints (&props);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_LIST_STYLE_TYPE,
+ CSS_TYPE_ENUM, listStyleType);
}
Html_add_textblock(html, 9);
@@ -2717,29 +2704,33 @@ static void Html_tag_close_li(DilloHtml *html, int TagIdx)
static void Html_tag_open_hr(DilloHtml *html, const char *tag, int tagsize)
{
Widget *hruler;
- CssPropertyList props;
char *width_ptr;
const char *attrbuf;
int32_t size = 0;
width_ptr = a_Html_get_attr_wdef(html, tag, tagsize, "width", NULL);
if (width_ptr) {
- props.set (CSS_PROPERTY_WIDTH, CSS_TYPE_LENGTH_PERCENTAGE,
- a_Html_parse_length (html, width_ptr));
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_WIDTH,
+ CSS_TYPE_LENGTH_PERCENTAGE,
+ a_Html_parse_length (html, width_ptr));
dFree(width_ptr);
}
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "size")))
size = strtol(attrbuf, NULL, 10);
- a_Html_tag_set_align_attr(html, &props, tag, tagsize);
+ a_Html_tag_set_align_attr(html, tag, tagsize);
/* TODO: evaluate attribute */
if (a_Html_get_attr(html, tag, tagsize, "noshade")) {
- props.set (CSS_PROPERTY_BORDER_TOP_STYLE, CSS_TYPE_ENUM, BORDER_SOLID);
- props.set (CSS_PROPERTY_BORDER_BOTTOM_STYLE,CSS_TYPE_ENUM,BORDER_SOLID);
- props.set (CSS_PROPERTY_BORDER_LEFT_STYLE, CSS_TYPE_ENUM, BORDER_SOLID);
- props.set (CSS_PROPERTY_BORDER_RIGHT_STYLE, CSS_TYPE_ENUM, BORDER_SOLID);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_TOP_STYLE,
+ CSS_TYPE_ENUM, BORDER_SOLID);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_BOTTOM_STYLE,
+ CSS_TYPE_ENUM, BORDER_SOLID);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_LEFT_STYLE,
+ CSS_TYPE_ENUM, BORDER_SOLID);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_RIGHT_STYLE,
+ CSS_TYPE_ENUM, BORDER_SOLID);
if (size <= 0)
size = 1;
@@ -2748,18 +2739,16 @@ static void Html_tag_open_hr(DilloHtml *html, const char *tag, int tagsize)
if (size > 0) {
CssLength size_top = CSS_CREATE_LENGTH ((size+1)/2, CSS_LENGTH_TYPE_PX);
CssLength size_bottom = CSS_CREATE_LENGTH (size / 2, CSS_LENGTH_TYPE_PX);
- props.set (CSS_PROPERTY_BORDER_TOP_WIDTH, CSS_TYPE_LENGTH_PERCENTAGE,
- size_top);
- props.set (CSS_PROPERTY_BORDER_LEFT_WIDTH, CSS_TYPE_LENGTH_PERCENTAGE,
- size_top);
- props.set (CSS_PROPERTY_BORDER_BOTTOM_WIDTH, CSS_TYPE_LENGTH_PERCENTAGE,
- size_bottom);
- props.set (CSS_PROPERTY_BORDER_RIGHT_WIDTH, CSS_TYPE_LENGTH_PERCENTAGE,
- size_bottom);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_TOP_WIDTH,
+ CSS_TYPE_LENGTH_PERCENTAGE, size_top);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_LEFT_WIDTH,
+ CSS_TYPE_LENGTH_PERCENTAGE, size_top);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_BOTTOM_WIDTH,
+ CSS_TYPE_LENGTH_PERCENTAGE, size_bottom);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_RIGHT_WIDTH,
+ CSS_TYPE_LENGTH_PERCENTAGE, size_bottom);
}
- html->styleEngine->setNonCssHints (&props);
-
HT2TB(html)->addParbreak (5, html->styleEngine->wordStyle ());
hruler = new Ruler();
@@ -2774,6 +2763,7 @@ static void Html_tag_open_hr(DilloHtml *html, const char *tag, int tagsize)
static void Html_tag_open_dl(DilloHtml *html, const char *tag, int tagsize)
{
/* may want to actually do some stuff here. */
+ html->styleEngine->inheritBackgroundColor ();
HT2TB(html)->addParbreak (9, html->styleEngine->wordStyle ());
}
@@ -2782,6 +2772,7 @@ static void Html_tag_open_dl(DilloHtml *html, const char *tag, int tagsize)
*/
static void Html_tag_open_dt(DilloHtml *html, const char *tag, int tagsize)
{
+ html->styleEngine->inheritBackgroundColor ();
HT2TB(html)->addParbreak (9, html->styleEngine->wordStyle ());
}
@@ -2798,6 +2789,7 @@ static void Html_tag_open_dd(DilloHtml *html, const char *tag, int tagsize)
*/
static void Html_tag_open_pre(DilloHtml *html, const char *tag, int tagsize)
{
+ html->styleEngine->inheritBackgroundColor ();
HT2TB(html)->addParbreak (9, html->styleEngine->wordStyle ());
html->InFlags |= IN_PRE;
@@ -2879,41 +2871,44 @@ static void Html_tag_open_meta(DilloHtml *html, const char *tag, int tagsize)
}
/* Skip to anything after "URL=" */
while (*content && *(content++) != '=') ;
- /* Handle the case of a quoted URL */
- if (*content == '"' || *content == '\'') {
- if ((p = strchr(content + 1, *content)))
- mr_url = dStrndup(content + 1, p - content - 1);
- else
- mr_url = dStrdup(content + 1);
- } else {
- mr_url = dStrdup(content);
- }
+ if (*content) {
- if (delay == 0) {
- /* zero-delay redirection */
- html->stop_parser = true;
- DilloUrl *new_url = a_Url_new(mr_url, URL_STR(html->base_url));
- if (a_Capi_dpi_verify_request(html->bw, new_url))
- a_UIcmd_redirection0((void*)html->bw, new_url);
- a_Url_free(new_url);
- } else {
- /* Send a custom HTML message.
- * TODO: This is a hairy hack,
- * It'd be much better to build a widget. */
- Dstr *ds_msg = dStr_sized_new(256);
- dStr_sprintf(ds_msg, meta_template, mr_url, delay_str);
- {
- int o_InFlags = html->InFlags;
- int o_TagSoup = html->TagSoup;
- html->InFlags = IN_BODY;
- html->TagSoup = false;
- Html_write_raw(html, ds_msg->str, ds_msg->len, 0);
- html->TagSoup = o_TagSoup;
- html->InFlags = o_InFlags;
+ /* Handle the case of a quoted URL */
+ if (*content == '"' || *content == '\'') {
+ if ((p = strchr(content + 1, *content)))
+ mr_url = dStrndup(content + 1, p - content - 1);
+ else
+ mr_url = dStrdup(content + 1);
+ } else {
+ mr_url = dStrdup(content);
+ }
+
+ if (delay == 0) {
+ /* zero-delay redirection */
+ html->stop_parser = true;
+ DilloUrl *new_url = a_Url_new(mr_url, URL_STR(html->base_url));
+ if (a_Capi_dpi_verify_request(html->bw, new_url))
+ a_UIcmd_redirection0((void*)html->bw, new_url);
+ a_Url_free(new_url);
+ } else {
+ /* Send a custom HTML message.
+ * TODO: This is a hairy hack,
+ * It'd be much better to build a widget. */
+ Dstr *ds_msg = dStr_sized_new(256);
+ dStr_sprintf(ds_msg, meta_template, mr_url, delay_str);
+ {
+ int o_InFlags = html->InFlags;
+ int o_TagSoup = html->TagSoup;
+ html->InFlags = IN_BODY;
+ html->TagSoup = false;
+ Html_write_raw(html, ds_msg->str, ds_msg->len, 0);
+ html->TagSoup = o_TagSoup;
+ html->InFlags = o_InFlags;
+ }
+ dStr_free(ds_msg, 1);
}
- dStr_free(ds_msg, 1);
+ dFree(mr_url);
}
- dFree(mr_url);
} else if (!dStrcasecmp(equiv, "content-type") &&
(content = a_Html_get_attr(html, tag, tagsize, "content"))) {
@@ -3095,10 +3090,7 @@ static void Html_tag_open_default(DilloHtml *html,const char *tag,int tagsize)
*/
static void Html_tag_open_div(DilloHtml *html, const char *tag, int tagsize)
{
- CssPropertyList props;
-
- a_Html_tag_set_align_attr (html, &props, tag, tagsize);
- html->styleEngine->setNonCssHints (&props);
+ a_Html_tag_set_align_attr (html, tag, tagsize);
Html_add_textblock(html, 0);
}
@@ -3137,14 +3129,6 @@ static void Html_tag_close_par(DilloHtml *html, int TagIdx)
* - Empty elements have both inline and block container clear.
* (flow have both set)
*/
-struct _TagInfo{
- const char *name;
- unsigned char Flags;
- char EndTag;
- uchar_t TagLevel;
- TagOpenFunct open;
- TagCloseFunct close;
-};
const TagInfo Tags[] = {
@@ -3739,11 +3723,8 @@ static void Html_callback(int Op, CacheClient_t *Client)
static int Html_write_raw(DilloHtml *html, char *buf, int bufsize, int Eof)
{
char ch = 0, *p, *text;
- Textblock *textblock;
int token_start, buf_index;
- dReturn_val_if_fail ((textblock = HT2TB(html)) != NULL, 0);
-
/* Now, 'buf' and 'bufsize' define a buffer aligned to start at a token
* boundary. Iterate through tokens until end of buffer is reached. */
buf_index = 0;
@@ -3862,7 +3843,7 @@ static int Html_write_raw(DilloHtml *html, char *buf, int bufsize, int Eof)
}
}/*while*/
- textblock->flush ();
+ HT2TB(html)->flush ();
return token_start;
}
diff --git a/src/html_common.hh b/src/html_common.hh
index 3cca82de..cf5c8114 100644
--- a/src/html_common.hh
+++ b/src/html_common.hh
@@ -64,6 +64,11 @@ typedef enum {
} DilloHtmlTableMode;
typedef enum {
+ DILLO_HTML_TABLE_BORDER_SEPARATE,
+ DILLO_HTML_TABLE_BORDER_COLLAPSE
+} DilloHtmlTableBorderMode;
+
+typedef enum {
HTML_LIST_NONE,
HTML_LIST_UNORDERED,
HTML_LIST_ORDERED
@@ -94,10 +99,11 @@ struct _DilloHtmlImage {
};
struct _DilloHtmlState {
- CssPropertyList *table_cell_props;
DilloHtmlParseMode parse_mode;
DilloHtmlTableMode table_mode;
+ DilloHtmlTableBorderMode table_border_mode;
bool cell_text_align_set;
+
DilloHtmlListMode list_type;
int list_number;
@@ -242,11 +248,9 @@ int32_t a_Html_color_parse(DilloHtml *html,
const char *subtag, int32_t default_color);
dw::core::style::Length a_Html_parse_length (DilloHtml *html,
const char *attr);
-void a_Html_tag_set_align_attr(DilloHtml *html, CssPropertyList *props,
- const char *tag, int tagsize);
+void a_Html_tag_set_align_attr(DilloHtml *html, const char *tag, int tagsize);
bool a_Html_tag_set_valign_attr(DilloHtml *html,
- const char *tag, int tagsize,
- CssPropertyList *props);
+ const char *tag, int tagsize);
void a_Html_load_stylesheet(DilloHtml *html, DilloUrl *url);
diff --git a/src/jpeg.c b/src/jpeg.c
index 262a1346..93d9df07 100644
--- a/src/jpeg.c
+++ b/src/jpeg.c
@@ -1,7 +1,6 @@
/*
* File: jpeg.c
*
- * Copyright (C) 1997 Raph Levien <raph@acm.org>
* Copyright (C) 2000-2007 Jorge Arellano Cid <jcid@dillo.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -292,7 +291,7 @@ static void Jpeg_write(DilloJpeg *jpeg, void *Buf, uint_t BufSize)
if (jpeg->cinfo.image_width <= 0 || jpeg->cinfo.image_height <= 0 ||
jpeg->cinfo.image_width >
IMAGE_MAX_AREA / jpeg->cinfo.image_height) {
- MSG("Jpeg_write: suspicious image size request %ux%u\n",
+ MSG("Jpeg_write: suspicious image size request %u x %u\n",
(uint_t)jpeg->cinfo.image_width,
(uint_t)jpeg->cinfo.image_height);
jpeg->state = DILLO_JPEG_ERROR;
diff --git a/src/misc.c b/src/misc.c
index 9ba8c9b9..213b0ada 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -1,7 +1,6 @@
/*
* File: misc.c
*
- * Copyright (C) 2000 Jörgen Viksell <vsksga@hotmail.com>
* Copyright (C) 2000-2007 Jorge Arellano Cid <jcid@dillo.org>,
*
* This program is free software; you can redistribute it and/or modify
@@ -105,6 +104,7 @@ typedef struct ContentType_ {
static const ContentType_t MimeTypes[] = {
{ "application/octet-stream", 24 },
+ { "application/xhtml+xml", 21 },
{ "text/html", 9 },
{ "text/plain", 10 },
{ "image/gif", 9 },
@@ -342,7 +342,12 @@ int a_Misc_content_type_check(const char *EntryType, const char *DetectedType)
dStrncasecmp(DetectedType, "application/", 12)) {
/* Not an application sent as text */
st = 0;
+ } else if (dStrncasecmp(EntryType, "application/xhtml+xml", 21) &&
+ dStrncasecmp(DetectedType, "text/html", 9)) {
+ /* XML version of HTML */
+ st = 0;
}
+ _MSG("Type check: %s\n", st == 0 ? "MATCH" : "MISMATCH");
return st;
}
diff --git a/src/nav.c b/src/nav.c
index 740bc565..c5311cfb 100644
--- a/src/nav.c
+++ b/src/nav.c
@@ -395,7 +395,7 @@ static void Nav_repush_callback(void *data)
void a_Nav_repush(BrowserWindow *bw)
{
dReturn_if_fail (bw != NULL);
- MSG(">>> a_Nav_repush <<<<\n");
+ MSG(">>>> a_Nav_repush <<<<\n");
a_Timeout_add(0.0, Nav_repush_callback, (void*)bw);
}
@@ -424,7 +424,7 @@ static void Nav_redirection0_callback(void *data)
void a_Nav_redirection0(BrowserWindow *bw, const DilloUrl *new_url)
{
dReturn_if_fail (bw != NULL);
- _MSG(">>> a_Nav_redirection0 <<<<\n");
+ _MSG(">>>> a_Nav_redirection0 <<<<\n");
a_Url_free(bw->meta_refresh_url);
bw->meta_refresh_url = a_Url_dup(new_url);
diff --git a/src/png.c b/src/png.c
index 15f26e3b..bf9de2ef 100644
--- a/src/png.c
+++ b/src/png.c
@@ -65,8 +65,8 @@ struct _DilloPng {
int version; /* Secondary Key for the dicache */
double display_exponent; /* gamma correction */
- ulong_t width; /* png image width */
- ulong_t height; /* png image height */
+ png_uint_32 width; /* png image width */
+ png_uint_32 height; /* png image height */
png_structp png_ptr; /* libpng private data */
png_infop info_ptr; /* libpng private info */
uchar_t *image_data; /* decoded image data */
@@ -135,17 +135,17 @@ Png_datainfo_callback(png_structp png_ptr, png_infop info_ptr)
&bit_depth, &color_type, &interlace_type, NULL, NULL);
/* check max image size */
- if (png->width <= 0 || png->height <= 0 ||
+ if (png->width == 0 || png->height == 0 ||
png->width > IMAGE_MAX_AREA / png->height) {
- MSG("Png_datainfo_callback: suspicious image size request %ldx%ld\n",
- png->width, png->height);
+ MSG("Png_datainfo_callback: suspicious image size request %lu x %lu\n",
+ (ulong_t) png->width, (ulong_t) png->height);
Png_error_handling(png_ptr, "Aborting...");
return; /* not reached */
}
- _MSG("Png_datainfo_callback: png->width = %ld\n"
- "Png_datainfo_callback: png->height = %ld\n",
- png->width, png->height);
+ _MSG("Png_datainfo_callback: png->width = %lu\n"
+ "Png_datainfo_callback: png->height = %lu\n",
+ (ulong_t) png->width, (ulong_t) png->height);
/* we need RGB/RGBA in the end */
if (color_type == PNG_COLOR_TYPE_PALETTE && bit_depth <= 8) {
@@ -193,9 +193,9 @@ Png_datainfo_callback(png_structp png_ptr, png_infop info_ptr)
/* init Dillo specifics */
_MSG("Png_datainfo_callback: rowbytes = %d\n"
- "Png_datainfo_callback: width = %ld\n"
- "Png_datainfo_callback: height = %ld\n",
- png->rowbytes, png->width, png->height);
+ "Png_datainfo_callback: width = %lu\n"
+ "Png_datainfo_callback: height = %lu\n",
+ png->rowbytes, (ulong_t) png->width, (ulong_t) png->height);
png->image_data = (uchar_t *) dMalloc(png->rowbytes * png->height);
png->row_pointers = (uchar_t **) dMalloc(png->height * sizeof(uchar_t *));
diff --git a/src/prefs.c b/src/prefs.c
index 5514c01a..f968710a 100644
--- a/src/prefs.c
+++ b/src/prefs.c
@@ -36,6 +36,7 @@ DilloPrefs prefs;
void a_Prefs_init(void)
{
prefs.allow_white_bg = TRUE;
+ prefs.bg_color = 0xdcd1ba;
prefs.buffered_drawing = 1;
prefs.contrast_visited_color = TRUE;
prefs.enterpress_forces_submit = FALSE;
diff --git a/src/prefs.h b/src/prefs.h
index 684262ed..4009925c 100644
--- a/src/prefs.h
+++ b/src/prefs.h
@@ -46,6 +46,7 @@ struct _DilloPrefs {
DilloUrl *start_page;
DilloUrl *home;
bool_t allow_white_bg;
+ int32_t bg_color;
bool_t contrast_visited_color;
bool_t show_tooltip;
int panel_size;
diff --git a/src/prefsparser.cc b/src/prefsparser.cc
index 78cade0b..95f98c16 100644
--- a/src/prefsparser.cc
+++ b/src/prefsparser.cc
@@ -16,11 +16,13 @@
#include "prefs.h"
#include "misc.h"
#include "msg.h"
+#include "colors.h"
#include "prefsparser.hh"
typedef enum {
PREFS_BOOL,
+ PREFS_COLOR,
PREFS_STRING,
PREFS_URL,
PREFS_INT32,
@@ -43,10 +45,12 @@ int PrefsParser::parseOption(char *name, char *value)
{
const SymNode_t *node;
uint_t i;
+ int st;
/* Symbol array, sorted alphabetically */
const SymNode_t symbols[] = {
{ "allow_white_bg", &prefs.allow_white_bg, PREFS_BOOL },
+ { "bg_color", &prefs.bg_color, PREFS_COLOR },
{ "buffered_drawing", &prefs.buffered_drawing, PREFS_INT32 },
{ "contrast_visited_color", &prefs.contrast_visited_color, PREFS_BOOL },
{ "enterpress_forces_submit", &prefs.enterpress_forces_submit,
@@ -122,6 +126,9 @@ int PrefsParser::parseOption(char *name, char *value)
*(bool_t *)node->pref = (!dStrcasecmp(value, "yes") ||
!dStrcasecmp(value, "true"));
break;
+ case PREFS_COLOR:
+ *(int32_t *)node->pref = a_Color_parse(value, *(int32_t*)node->pref,&st);
+ break;
case PREFS_STRING:
dFree(*(char **)node->pref);
*(char **)node->pref = dStrdup(value);
diff --git a/src/styleengine.cc b/src/styleengine.cc
index b861e717..776c1694 100644
--- a/src/styleengine.cc
+++ b/src/styleengine.cc
@@ -15,6 +15,7 @@
#include "html_common.hh"
#include "styleengine.hh"
+using namespace lout::misc;
using namespace dw::core::style;
StyleEngine::StyleEngine (dw::core::Layout *layout) {
@@ -32,7 +33,7 @@ StyleEngine::StyleEngine (dw::core::Layout *layout) {
/* Create a dummy font, attribute, and tag for the bottom of the stack. */
font_attrs.name = prefs.font_sans_serif;
- font_attrs.size = (int) (14 * prefs.font_factor + 0.5);
+ font_attrs.size = roundInt(14 * prefs.font_factor);
if (font_attrs.size < prefs.font_min_size)
font_attrs.size = prefs.font_min_size;
if (font_attrs.size > prefs.font_max_size)
@@ -40,6 +41,7 @@ StyleEngine::StyleEngine (dw::core::Layout *layout) {
font_attrs.weight = 400;
font_attrs.style = FONT_STYLE_NORMAL;
font_attrs.letterSpacing = 0;
+ font_attrs.fontVariant = FONT_VARIANT_NORMAL;
style_attrs.initValues ();
style_attrs.font = Font::create (layout, &font_attrs);
@@ -48,13 +50,23 @@ StyleEngine::StyleEngine (dw::core::Layout *layout) {
n->style = Style::create (layout, &style_attrs);
n->wordStyle = NULL;
- n->styleAttribute = NULL;
+ n->backgroundStyle = NULL;
+ n->styleAttrProperties = NULL;
+ n->nonCssProperties = NULL;
n->inheritBackgroundColor = false;
}
StyleEngine::~StyleEngine () {
while (doctree->top ())
endElement (doctree->top ()->element);
+ assert (stack->size () == 1); // dummy node on the bottom of the stack
+ Node *n = stack->getRef (stack->size () - 1);
+ if (n->style)
+ n->style->unref ();
+ if (n->wordStyle)
+ n->wordStyle->unref ();
+ if (n->backgroundStyle)
+ n->backgroundStyle->unref ();
delete stack;
delete doctree;
delete cssContext;
@@ -65,17 +77,20 @@ StyleEngine::~StyleEngine () {
*/
void StyleEngine::startElement (int element) {
if (stack->getRef (stack->size () - 1)->style == NULL)
- style0 ();
+ style0 (stack->size () - 1);
stack->increase ();
Node *n = stack->getRef (stack->size () - 1);
+ n->styleAttrProperties = NULL;
+ n->nonCssProperties = NULL;
n->style = NULL;
n->wordStyle = NULL;
- n->styleAttribute = NULL;
+ n->backgroundStyle = NULL;
n->inheritBackgroundColor = false;
DoctreeNode *dn = doctree->push ();
dn->element = element;
+ n->doctreeNode = dn;
}
void StyleEngine::startElement (const char *tagname) {
@@ -119,20 +134,36 @@ void StyleEngine::setClass (const char *klass) {
dn->klass = splitStr (klass, ' ');
};
-void StyleEngine::setStyle (const char *style) {
+void StyleEngine::setStyle (const char *styleAttr) {
Node *n = stack->getRef (stack->size () - 1);
- assert (n->styleAttribute == NULL);
- n->styleAttribute = dStrdup (style);
+ assert (n->styleAttrProperties == NULL);
+ // parse style information from style="" attribute, if it exists
+ if (styleAttr && prefs.parse_embedded_css)
+ n->styleAttrProperties =
+ CssParser::parseDeclarationBlock (styleAttr,
+ strlen (styleAttr));
};
/**
- * \brief set properties that were definded using (mostly deprecated) HTML
- * attributes (e.g. bgColor).
+ * \brief Instruct StyleEngine to use the nonCssHints from parent element
+ * This is only used for tables where nonCssHints on the TABLE-element
+ * (e.g. border=1) also affect child elements like TD.
*/
-void StyleEngine::setNonCssHints (CssPropertyList *nonCssHints) {
- if (stack->getRef (stack->size () - 1)->style)
- stack->getRef (stack->size () - 1)->style->unref ();
- style0 (nonCssHints); // evaluate now, so caller can free nonCssHints
+void StyleEngine::inheritNonCssHints () {
+ Node *pn = stack->getRef (stack->size () - 2);
+ Node *n = stack->getRef (stack->size () - 1);
+
+ if (pn->nonCssProperties)
+ n->nonCssProperties = new CssPropertyList (*pn->nonCssProperties, true);
+}
+
+void StyleEngine::clearNonCssHints () {
+ Node *n = stack->getRef (stack->size () - 1);
+
+ if (n->nonCssProperties) {
+ delete n->nonCssProperties;
+ n->nonCssProperties = NULL;
+ }
}
/**
@@ -145,6 +176,17 @@ void StyleEngine::inheritBackgroundColor () {
stack->getRef (stack->size () - 1)->inheritBackgroundColor = true;
}
+dw::core::style::Color *StyleEngine::backgroundColor () {
+ for (int i = 1; i < stack->size (); i++) {
+ Node *n = stack->getRef (i);
+
+ if (n->style && n->style->backgroundColor)
+ return n->style->backgroundColor;
+ }
+
+ return NULL;
+}
+
/**
* \brief set the CSS pseudo class :link.
*/
@@ -165,32 +207,80 @@ void StyleEngine::setPseudoVisited () {
* \brief tell the styleEngine that a html element has ended.
*/
void StyleEngine::endElement (int element) {
- assert (stack->size () > 0);
assert (element == doctree->top ()->element);
Node *n = stack->getRef (stack->size () - 1);
+ if (n->styleAttrProperties)
+ delete n->styleAttrProperties;
+ if (n->nonCssProperties)
+ delete n->nonCssProperties;
if (n->style)
n->style->unref ();
if (n->wordStyle)
n->wordStyle->unref ();
- if (n->styleAttribute)
- dFree ((void*) n->styleAttribute);
+ if (n->backgroundStyle)
+ n->backgroundStyle->unref ();
doctree->pop ();
stack->setSize (stack->size () - 1);
}
+void StyleEngine::preprocessAttrs (dw::core::style::StyleAttrs *attrs) {
+ /* workaround for styling of inline elements */
+ if (stack->getRef (stack->size () - 2)->inheritBackgroundColor) {
+ attrs->backgroundColor =
+ stack->getRef (stack->size () - 2)->style->backgroundColor;
+
+ attrs->valign = stack->getRef (stack->size () - 2)->style->valign;
+ }
+ attrs->borderColor.top = (Color *) -1;
+ attrs->borderColor.bottom = (Color *) -1;
+ attrs->borderColor.left = (Color *) -1;
+ attrs->borderColor.right = (Color *) -1;
+ /* initial value of border-width is 'medium' */
+ attrs->borderWidth.top = 2;
+ attrs->borderWidth.bottom = 2;
+ attrs->borderWidth.left = 2;
+ attrs->borderWidth.right = 2;
+}
+
+void StyleEngine::postprocessAttrs (dw::core::style::StyleAttrs *attrs) {
+ /* if border-color is not specified, use color as computed value */
+ if (attrs->borderColor.top == (Color *) -1)
+ attrs->borderColor.top = attrs->color;
+ if (attrs->borderColor.bottom == (Color *) -1)
+ attrs->borderColor.bottom = attrs->color;
+ if (attrs->borderColor.left == (Color *) -1)
+ attrs->borderColor.left = attrs->color;
+ if (attrs->borderColor.right == (Color *) -1)
+ attrs->borderColor.right = attrs->color;
+ /* computed value of border-width is 0 if border-style
+ is 'none' or 'hidden' */
+ if (attrs->borderStyle.top == BORDER_NONE ||
+ attrs->borderStyle.top == BORDER_HIDDEN)
+ attrs->borderWidth.top = 0;
+ if (attrs->borderStyle.bottom == BORDER_NONE ||
+ attrs->borderStyle.bottom == BORDER_HIDDEN)
+ attrs->borderWidth.bottom = 0;
+ if (attrs->borderStyle.left == BORDER_NONE ||
+ attrs->borderStyle.left == BORDER_HIDDEN)
+ attrs->borderWidth.left = 0;
+ if (attrs->borderStyle.right == BORDER_NONE ||
+ attrs->borderStyle.right == BORDER_HIDDEN)
+ attrs->borderWidth.right = 0;
+}
+
/**
* \brief Make changes to StyleAttrs attrs according to CssPropertyList props.
*/
-void StyleEngine::apply (StyleAttrs *attrs, CssPropertyList *props) {
+void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props) {
FontAttrs fontAttrs = *attrs->font;
- Font *parentFont = stack->get (stack->size () - 2).style->font;
+ Font *parentFont = stack->get (i - 1).style->font;
char *c, *fontName;
int lineHeight;
- /* Determine font first so it can be used to resolve relative lenths. */
+ /* Determine font first so it can be used to resolve relative lengths. */
for (int i = 0; i < props->size (); i++) {
CssProperty *p = props->getRef (i);
@@ -233,31 +323,30 @@ void StyleEngine::apply (StyleAttrs *attrs, CssPropertyList *props) {
if (p->type == CSS_TYPE_ENUM) {
switch (p->value.intVal) {
case CSS_FONT_SIZE_XX_SMALL:
- fontAttrs.size = (int) (11.0 * prefs.font_factor + 0.5);
+ fontAttrs.size = roundInt(11.0 * prefs.font_factor);
break;
case CSS_FONT_SIZE_X_SMALL:
- fontAttrs.size = (int) (12.0 * prefs.font_factor + 0.5);
+ fontAttrs.size = roundInt(12.0 * prefs.font_factor);
break;
case CSS_FONT_SIZE_SMALL:
- fontAttrs.size = (int) (13.0 * prefs.font_factor + 0.5);
+ fontAttrs.size = roundInt(13.0 * prefs.font_factor);
break;
case CSS_FONT_SIZE_MEDIUM:
- fontAttrs.size = (int) (14.0 * prefs.font_factor + 0.5);
+ fontAttrs.size = roundInt(14.0 * prefs.font_factor);
break;
case CSS_FONT_SIZE_LARGE:
- fontAttrs.size = (int) (15.0 * prefs.font_factor + 0.5);
break;
case CSS_FONT_SIZE_X_LARGE:
- fontAttrs.size = (int) (16.0 * prefs.font_factor + 0.5);
+ fontAttrs.size = roundInt(16.0 * prefs.font_factor);
break;
case CSS_FONT_SIZE_XX_LARGE:
- fontAttrs.size = (int) (17.0 * prefs.font_factor + 0.5);
+ fontAttrs.size = roundInt(17.0 * prefs.font_factor);
break;
case CSS_FONT_SIZE_SMALLER:
- fontAttrs.size -= (int) (1.0 * prefs.font_factor + 0.5);
+ fontAttrs.size -= roundInt(1.0 * prefs.font_factor);
break;
case CSS_FONT_SIZE_LARGER:
- fontAttrs.size += (int) (1.0 * prefs.font_factor + 0.5);
+ fontAttrs.size += roundInt(1.0 * prefs.font_factor);
break;
default:
assert(false); // invalid font-size enum
@@ -327,6 +416,9 @@ void StyleEngine::apply (StyleAttrs *attrs, CssPropertyList *props) {
else if (fontAttrs.letterSpacing < -1000)
fontAttrs.letterSpacing = -1000;
break;
+ case CSS_PROPERTY_FONT_VARIANT:
+ fontAttrs.fontVariant = (FontVariant) p->value.intVal;
+ break;
default:
break;
}
@@ -346,21 +438,24 @@ void StyleEngine::apply (StyleAttrs *attrs, CssPropertyList *props) {
//attrs->backgroundColor = Color::create(layout, 0xdcd1ba);
attrs->backgroundColor = Color::create(layout, 0xe0e0a3);
break;
+ case CSS_PROPERTY_BORDER_COLLAPSE:
+ attrs->borderCollapse = (BorderCollapse) p->value.intVal;
+ break;
case CSS_PROPERTY_BORDER_TOP_COLOR:
- attrs->borderColor.top =
- Color::create (layout, p->value.intVal);
+ attrs->borderColor.top = (p->type == CSS_TYPE_ENUM) ? NULL :
+ Color::create (layout, p->value.intVal);
break;
case CSS_PROPERTY_BORDER_BOTTOM_COLOR:
- attrs->borderColor.bottom =
- Color::create (layout, p->value.intVal);
+ attrs->borderColor.bottom = (p->type == CSS_TYPE_ENUM) ? NULL :
+ Color::create (layout, p->value.intVal);
break;
case CSS_PROPERTY_BORDER_LEFT_COLOR:
- attrs->borderColor.left =
- Color::create (layout, p->value.intVal);
+ attrs->borderColor.left = (p->type == CSS_TYPE_ENUM) ? NULL :
+ Color::create (layout, p->value.intVal);
break;
case CSS_PROPERTY_BORDER_RIGHT_COLOR:
- attrs->borderColor.right =
- Color::create (layout, p->value.intVal);
+ attrs->borderColor.right = (p->type == CSS_TYPE_ENUM) ? NULL :
+ Color::create (layout, p->value.intVal);
break;
case CSS_PROPERTY_BORDER_BOTTOM_STYLE:
attrs->borderStyle.bottom = (BorderStyle) p->value.intVal;
@@ -409,9 +504,8 @@ void StyleEngine::apply (StyleAttrs *attrs, CssPropertyList *props) {
if (CSS_LENGTH_TYPE (p->value.intVal) == CSS_LENGTH_TYPE_NONE) {
attrs->lineHeight =
createPerLength(CSS_LENGTH_VALUE(p->value.intVal));
- } else {
- computeValue (&lineHeight, p->value.intVal, attrs->font,
- attrs->font->size);
+ } else if (computeValue (&lineHeight, p->value.intVal,
+ attrs->font, attrs->font->size)) {
attrs->lineHeight = createAbsLength(lineHeight);
}
}
@@ -460,6 +554,9 @@ void StyleEngine::apply (StyleAttrs *attrs, CssPropertyList *props) {
case CSS_PROPERTY_TEXT_DECORATION:
attrs->textDecoration |= p->value.intVal;
break;
+ case CSS_PROPERTY_TEXT_INDENT:
+ computeLength (&attrs->textIndent, p->value.intVal, attrs->font);
+ break;
case CSS_PROPERTY_VERTICAL_ALIGN:
attrs->valign = (VAlignType) p->value.intVal;
break;
@@ -501,16 +598,6 @@ void StyleEngine::apply (StyleAttrs *attrs, CssPropertyList *props) {
}
}
- /* make sure border colors are set */
- if (attrs->borderColor.top == NULL)
- attrs->borderColor.top = attrs->color;
- if (attrs->borderColor.bottom == NULL)
- attrs->borderColor.bottom = attrs->color;
- if (attrs->borderColor.left == NULL)
- attrs->borderColor.left = attrs->color;
- if (attrs->borderColor.right == NULL)
- attrs->borderColor.right = attrs->color;
-
}
/**
@@ -527,14 +614,21 @@ bool StyleEngine::computeValue (int *dest, CssLength value, Font *font) {
*dest = (int) CSS_LENGTH_VALUE (value);
return true;
case CSS_LENGTH_TYPE_MM:
- *dest = (int) (CSS_LENGTH_VALUE (value) * dpmm + 0.5);
- return true;
+ *dest = roundInt (CSS_LENGTH_VALUE (value) * dpmm);
+ return true;
case CSS_LENGTH_TYPE_EM:
- *dest = (int) (CSS_LENGTH_VALUE (value) * font->size + 0.5);
- return true;
+ *dest = roundInt (CSS_LENGTH_VALUE (value) * font->size);
+ return true;
case CSS_LENGTH_TYPE_EX:
- *dest = (int) (CSS_LENGTH_VALUE(value) * font->xHeight + 0.5);
- return true;
+ *dest = roundInt (CSS_LENGTH_VALUE(value) * font->xHeight);
+ return true;
+ case CSS_LENGTH_TYPE_NONE:
+ // length values other than 0 without unit are only allowed
+ // in special cases (line-height) and have to be handled
+ // separately.
+ assert ((int) CSS_LENGTH_VALUE (value) == 0);
+ *dest = 0;
+ return true;
default:
break;
}
@@ -545,7 +639,7 @@ bool StyleEngine::computeValue (int *dest, CssLength value, Font *font) {
bool StyleEngine::computeValue (int *dest, CssLength value, Font *font,
int percentageBase) {
if (CSS_LENGTH_TYPE (value) == CSS_LENGTH_TYPE_PERCENTAGE) {
- *dest = (int) (CSS_LENGTH_VALUE (value) * percentageBase + 0.5);
+ *dest = roundInt (CSS_LENGTH_VALUE (value) * percentageBase);
return true;
} else
return computeValue (dest, value, font);
@@ -596,13 +690,17 @@ void StyleEngine::computeBorderWidth (int *dest, CssProperty *p,
* background. This method ensures that backgroundColor is set.
*/
Style * StyleEngine::backgroundStyle () {
- StyleAttrs attrs = *style ();
+ if (!stack->getRef (stack->size () - 1)->backgroundStyle) {
+ StyleAttrs attrs = *style ();
- for (int i = stack->size () - 1; i >= 0 && ! attrs.backgroundColor; i--)
- attrs.backgroundColor = stack->getRef (i)->style->backgroundColor;
+ for (int i = stack->size () - 1; i >= 0 && ! attrs.backgroundColor; i--)
+ attrs.backgroundColor = stack->getRef (i)->style->backgroundColor;
- assert (attrs.backgroundColor);
- return Style::create (layout, &attrs);
+ assert (attrs.backgroundColor);
+ stack->getRef (stack->size () - 1)->backgroundStyle =
+ Style::create (layout, &attrs);
+ }
+ return stack->getRef (stack->size () - 1)->backgroundStyle;
}
/**
@@ -610,56 +708,45 @@ Style * StyleEngine::backgroundStyle () {
* HTML elements and the nonCssProperties that have been set.
* This method is private. Call style() to get a current style object.
*/
-Style * StyleEngine::style0 (CssPropertyList *nonCssProperties) {
- CssPropertyList props, *styleAttributeProps = NULL;
- const char *styleAttribute =
- stack->getRef (stack->size () - 1)->styleAttribute;
+Style * StyleEngine::style0 (int i) {
+ CssPropertyList props, *styleAttrProperties, *nonCssProperties;
// get previous style from the stack
- StyleAttrs attrs = *stack->getRef (stack->size () - 2)->style;
+ StyleAttrs attrs = *stack->getRef (i - 1)->style;
// Ensure that StyleEngine::style0() has not been called before for
// this element.
// Style computation is expensive so limit it as much as possible.
// If this assertion is hit, you need to rearrange the code that is
- // doing styleEngine calls to call setNonCssHints() before calling
+ // doing styleEngine calls to call setNonCssHint() before calling
// style() or wordStyle() for each new element.
- assert (stack->getRef (stack->size () - 1)->style == NULL);
+ assert (stack->getRef (i)->style == NULL);
// reset values that are not inherited according to CSS
attrs.resetValues ();
+ preprocessAttrs (&attrs);
- if (stack->getRef (stack->size () - 2)->inheritBackgroundColor) {
- attrs.backgroundColor =
- stack->getRef (stack->size () - 2)->style->backgroundColor;
-
- attrs.valign = stack->getRef (stack->size () - 2)->style->valign;
- }
-
- // parse style information from style="" attribute, if it exists
- if (styleAttribute && prefs.parse_embedded_css)
- styleAttributeProps =
- CssParser::parseDeclarationBlock (styleAttribute,
- strlen (styleAttribute));
+ styleAttrProperties = stack->getRef (i)->styleAttrProperties;
+ nonCssProperties = stack->getRef (i)->nonCssProperties;
// merge style information
- cssContext->apply (&props, doctree, styleAttributeProps, nonCssProperties);
+ cssContext->apply (&props, doctree, stack->getRef(i)->doctreeNode,
+ styleAttrProperties, nonCssProperties);
// apply style
- apply (&attrs, &props);
+ apply (i, &attrs, &props);
- stack->getRef (stack->size () - 1)->style = Style::create (layout, &attrs);
+ postprocessAttrs (&attrs);
- if (styleAttributeProps)
- delete styleAttributeProps;
+ stack->getRef (i)->style = Style::create (layout, &attrs);
- return stack->getRef (stack->size () - 1)->style;
+ return stack->getRef (i)->style;
}
-Style * StyleEngine::wordStyle0 (CssPropertyList *nonCssProperties) {
+Style * StyleEngine::wordStyle0 () {
StyleAttrs attrs = *style ();
attrs.resetValues ();
- if (stack->getRef (stack->size () - 1)->inheritBackgroundColor)
+ if (stack->getRef (stack->size() - 1)->inheritBackgroundColor)
attrs.backgroundColor = style ()->backgroundColor;
attrs.valign = style ()->valign;
@@ -668,6 +755,33 @@ Style * StyleEngine::wordStyle0 (CssPropertyList *nonCssProperties) {
return stack->getRef (stack->size () - 1)->wordStyle;
}
+/**
+ * \brief Recompute all style information from scratch
+ * This is used to take into account CSS styles for the HTML-element.
+ * The CSS data is only completely available after parsing the HEAD-section
+ * and thereby after the HTML-element has been opened.
+ * Note that restyle() does not change any styles in the widget tree.
+ */
+void StyleEngine::restyle () {
+ for (int i = 1; i < stack->size (); i++) {
+ Node *n = stack->getRef (i);
+ if (n->style) {
+ n->style->unref ();
+ n->style = NULL;
+ }
+ if (n->wordStyle) {
+ n->wordStyle->unref ();
+ n->wordStyle = NULL;
+ }
+ if (n->backgroundStyle) {
+ n->backgroundStyle->unref ();
+ n->backgroundStyle = NULL;
+ }
+
+ style0 (i);
+ }
+}
+
void StyleEngine::parse (DilloHtml *html, DilloUrl *url, const char *buf,
int buflen, CssOrigin origin) {
if (importDepth > 10) { // avoid looping with recursive @import directives
diff --git a/src/styleengine.hh b/src/styleengine.hh
index 66f28cee..e37aeed1 100644
--- a/src/styleengine.hh
+++ b/src/styleengine.hh
@@ -19,12 +19,14 @@ class StyleEngine;
*/
class StyleEngine {
private:
- class Node {
- public:
- dw::core::style::Style *style;
- dw::core::style::Style *wordStyle;
- const char *styleAttribute;
- bool inheritBackgroundColor;
+ struct Node {
+ CssPropertyList *styleAttrProperties;
+ CssPropertyList *nonCssProperties;
+ dw::core::style::Style *style;
+ dw::core::style::Style *wordStyle;
+ dw::core::style::Style *backgroundStyle;
+ bool inheritBackgroundColor;
+ DoctreeNode *doctreeNode;
};
dw::core::Layout *layout;
@@ -33,9 +35,19 @@ class StyleEngine {
Doctree *doctree;
int importDepth;
- dw::core::style::Style *style0 (CssPropertyList *nonCssHints = NULL);
- dw::core::style::Style *wordStyle0 (CssPropertyList *nonCssHints = NULL);
- void apply (dw::core::style::StyleAttrs *attrs, CssPropertyList *props);
+ dw::core::style::Style *style0 (int i);
+ dw::core::style::Style *wordStyle0 ();
+ inline void setNonCssHint(CssPropertyName name, CssValueType type,
+ CssPropertyValue value) {
+ Node *n = stack->getRef (stack->size () - 1);
+
+ if (!n->nonCssProperties)
+ n->nonCssProperties = new CssPropertyList (true);
+ n->nonCssProperties->set(name, type, value);
+ }
+ void preprocessAttrs (dw::core::style::StyleAttrs *attrs);
+ void postprocessAttrs (dw::core::style::StyleAttrs *attrs);
+ void apply (int i, dw::core::style::StyleAttrs *attrs, CssPropertyList *props);
bool computeValue (int *dest, CssLength value,
dw::core::style::Font *font);
bool computeValue (int *dest, CssLength value,
@@ -60,16 +72,31 @@ class StyleEngine {
void endElement (int tag);
void setPseudoLink ();
void setPseudoVisited ();
- void setNonCssHints (CssPropertyList *nonCssHints);
+ inline void setNonCssHint(CssPropertyName name, CssValueType type,
+ int value) {
+ CssPropertyValue v;
+ v.intVal = value;
+ setNonCssHint (name, type, v);
+ }
+ inline void setNonCssHint(CssPropertyName name, CssValueType type,
+ const char *value) {
+ CssPropertyValue v;
+ v.strVal = dStrdup(value);
+ setNonCssHint (name, type, v);
+ }
+ void inheritNonCssHints ();
+ void clearNonCssHints ();
+ void restyle ();
void inheritBackgroundColor (); /* \todo get rid of this somehow */
dw::core::style::Style *backgroundStyle ();
+ dw::core::style::Color *backgroundColor ();
inline dw::core::style::Style *style () {
dw::core::style::Style *s = stack->getRef (stack->size () - 1)->style;
if (s)
return s;
else
- return style0 ();
+ return style0 (stack->size () - 1);
};
inline dw::core::style::Style *wordStyle () {
diff --git a/src/table.cc b/src/table.cc
index 43304206..58cdf22e 100644
--- a/src/table.cc
+++ b/src/table.cc
@@ -38,7 +38,6 @@ static void Html_tag_open_table_cell(DilloHtml *html,
void Html_tag_open_table(DilloHtml *html, const char *tag, int tagsize)
{
dw::core::Widget *table;
- CssPropertyList props, *table_cell_props;
const char *attrbuf;
int32_t border = -1, cellspacing = -1, cellpadding = -1, bgcolor = -1;
CssLength cssLength;
@@ -52,81 +51,95 @@ void Html_tag_open_table(DilloHtml *html, const char *tag, int tagsize)
if (border != -1) {
cssLength = CSS_CREATE_LENGTH (border, CSS_LENGTH_TYPE_PX);
- props.set (CSS_PROPERTY_BORDER_TOP_WIDTH, CSS_TYPE_LENGTH_PERCENTAGE,
- cssLength);
- props.set (CSS_PROPERTY_BORDER_BOTTOM_WIDTH, CSS_TYPE_LENGTH_PERCENTAGE,
- cssLength);
- props.set (CSS_PROPERTY_BORDER_LEFT_WIDTH, CSS_TYPE_LENGTH_PERCENTAGE,
- cssLength);
- props.set (CSS_PROPERTY_BORDER_RIGHT_WIDTH, CSS_TYPE_LENGTH_PERCENTAGE,
- cssLength);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_TOP_WIDTH,
+ CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_BOTTOM_WIDTH,
+ CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_LEFT_WIDTH,
+ CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_RIGHT_WIDTH,
+ CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_TOP_STYLE,
+ CSS_TYPE_ENUM, BORDER_OUTSET);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_BOTTOM_STYLE,
+ CSS_TYPE_ENUM, BORDER_OUTSET);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_LEFT_STYLE,
+ CSS_TYPE_ENUM, BORDER_OUTSET);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_RIGHT_STYLE,
+ CSS_TYPE_ENUM, BORDER_OUTSET);
}
if (cellspacing != -1) {
cssLength = CSS_CREATE_LENGTH (cellspacing, CSS_LENGTH_TYPE_PX);
- props.set (CSS_PROPERTY_BORDER_SPACING, CSS_TYPE_LENGTH_PERCENTAGE,
- cssLength);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_SPACING,
+ CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
}
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "width")))
- props.set (CSS_PROPERTY_WIDTH, CSS_TYPE_LENGTH_PERCENTAGE,
- a_Html_parse_length (html, attrbuf));
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_WIDTH,
+ CSS_TYPE_LENGTH_PERCENTAGE,
+ a_Html_parse_length (html, attrbuf));
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "align"))) {
if (dStrcasecmp (attrbuf, "left") == 0)
- props.set (CSS_PROPERTY_TEXT_ALIGN, CSS_TYPE_ENUM, TEXT_ALIGN_LEFT);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_TEXT_ALIGN,
+ CSS_TYPE_ENUM, TEXT_ALIGN_LEFT);
else if (dStrcasecmp (attrbuf, "right") == 0)
- props.set (CSS_PROPERTY_TEXT_ALIGN, CSS_TYPE_ENUM, TEXT_ALIGN_RIGHT);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_TEXT_ALIGN,
+ CSS_TYPE_ENUM, TEXT_ALIGN_RIGHT);
else if (dStrcasecmp (attrbuf, "center") == 0)
- props.set (CSS_PROPERTY_TEXT_ALIGN, CSS_TYPE_ENUM, TEXT_ALIGN_CENTER);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_TEXT_ALIGN,
+ CSS_TYPE_ENUM, TEXT_ALIGN_CENTER);
}
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "bgcolor"))) {
bgcolor = a_Html_color_parse(html, attrbuf, -1);
if (bgcolor != -1)
- props.set (CSS_PROPERTY_BACKGROUND_COLOR, CSS_TYPE_COLOR, bgcolor);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BACKGROUND_COLOR,
+ CSS_TYPE_COLOR, bgcolor);
}
- html->styleEngine->setNonCssHints (&props);
-
HT2TB(html)->addParbreak (0, html->styleEngine->wordStyle ());
/* The style for the cells */
- table_cell_props = new CssPropertyList ();
+ html->styleEngine->clearNonCssHints ();
if (border > 0) {
cssLength = CSS_CREATE_LENGTH (1, CSS_LENGTH_TYPE_PX);
- table_cell_props->set (CSS_PROPERTY_BORDER_TOP_WIDTH,
- CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
- table_cell_props->set (CSS_PROPERTY_BORDER_BOTTOM_WIDTH,
- CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
- table_cell_props->set (CSS_PROPERTY_BORDER_LEFT_WIDTH,
- CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
- table_cell_props->set (CSS_PROPERTY_BORDER_RIGHT_WIDTH,
- CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_TOP_WIDTH,
+ CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_BOTTOM_WIDTH,
+ CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_LEFT_WIDTH,
+ CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_RIGHT_WIDTH,
+ CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_TOP_STYLE,
+ CSS_TYPE_ENUM, BORDER_INSET);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_BOTTOM_STYLE,
+ CSS_TYPE_ENUM, BORDER_INSET);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_LEFT_STYLE,
+ CSS_TYPE_ENUM, BORDER_INSET);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_RIGHT_STYLE,
+ CSS_TYPE_ENUM, BORDER_INSET);
}
if (cellpadding != -1) {
cssLength = CSS_CREATE_LENGTH (cellpadding, CSS_LENGTH_TYPE_PX);
- table_cell_props->set (CSS_PROPERTY_PADDING_TOP,
- CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
- table_cell_props->set (CSS_PROPERTY_PADDING_BOTTOM,
- CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
- table_cell_props->set (CSS_PROPERTY_PADDING_LEFT,
- CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
- table_cell_props->set (CSS_PROPERTY_PADDING_RIGHT,
- CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_PADDING_TOP,
+ CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_PADDING_BOTTOM,
+ CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_PADDING_LEFT,
+ CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_PADDING_RIGHT,
+ CSS_TYPE_LENGTH_PERCENTAGE, cssLength);
}
- if (S_TOP(html)->table_cell_props)
- S_TOP(html)->table_cell_props->unref ();
-
- S_TOP(html)->table_cell_props = table_cell_props;
- S_TOP(html)->table_cell_props->ref ();
-
table = new dw::Table(prefs.limit_text_width);
HT2TB(html)->addWidget (table, html->styleEngine->style ());
S_TOP(html)->table_mode = DILLO_HTML_TABLE_MODE_TOP;
+ S_TOP(html)->table_border_mode = DILLO_HTML_TABLE_BORDER_SEPARATE;
S_TOP(html)->cell_text_align_set = FALSE;
S_TOP(html)->table = table;
}
@@ -139,7 +152,8 @@ void Html_tag_open_tr(DilloHtml *html, const char *tag, int tagsize)
const char *attrbuf;
int32_t bgcolor = -1;
bool new_style = false;
- CssPropertyList props, *table_cell_props;
+
+ html->styleEngine->inheritNonCssHints ();
switch (S_TOP(html)->table_mode) {
case DILLO_HTML_TABLE_MODE_NONE:
@@ -153,34 +167,26 @@ void Html_tag_open_tr(DilloHtml *html, const char *tag, int tagsize)
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "bgcolor"))) {
bgcolor = a_Html_color_parse(html, attrbuf, -1);
if (bgcolor != -1)
- props.set (CSS_PROPERTY_BACKGROUND_COLOR, CSS_TYPE_COLOR, bgcolor);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BACKGROUND_COLOR,
+ CSS_TYPE_COLOR, bgcolor);
}
if (a_Html_get_attr (html, tag, tagsize, "align")) {
S_TOP(html)->cell_text_align_set = TRUE;
- a_Html_tag_set_align_attr (html, &props, tag, tagsize);
+ a_Html_tag_set_align_attr (html, tag, tagsize);
}
html->styleEngine->inheritBackgroundColor ();
- html->styleEngine->setNonCssHints (&props);
((dw::Table*)S_TOP(html)->table)->addRow (html->styleEngine->style ());
- table_cell_props = new CssPropertyList (*S_TOP(html)->table_cell_props);
if (bgcolor != -1) {
- table_cell_props->set (CSS_PROPERTY_BACKGROUND_COLOR,
- CSS_TYPE_COLOR, bgcolor);
+ html->styleEngine->setNonCssHint(CSS_PROPERTY_BACKGROUND_COLOR,
+ CSS_TYPE_COLOR, bgcolor);
new_style = true;
}
- if (a_Html_tag_set_valign_attr (html, tag, tagsize, table_cell_props))
+ if (a_Html_tag_set_valign_attr (html, tag, tagsize))
new_style = true;
- if (new_style) {
- S_TOP(html)->table_cell_props->unref ();
- S_TOP(html)->table_cell_props = table_cell_props;
- S_TOP(html)->table_cell_props->ref ();
- } else {
- delete table_cell_props;
- }
break;
default:
break;
@@ -212,6 +218,96 @@ void Html_tag_open_th(DilloHtml *html, const char *tag, int tagsize)
*/
/*
+ * The table border model is stored in the table's stack item
+ */
+static int Html_table_get_border_model(DilloHtml *html)
+{
+ static int i_TABLE = -1;
+ if (i_TABLE == -1)
+ i_TABLE = a_Html_tag_index("table");
+
+ int s_idx = html->stack->size();
+ while (--s_idx > 0 && html->stack->getRef(s_idx)->tag_idx != i_TABLE)
+ ;
+ return html->stack->getRef(s_idx)->table_border_mode;
+}
+
+/*
+ * Set current table's border model
+ */
+static void Html_table_set_border_model(DilloHtml *html,
+ DilloHtmlTableBorderMode mode)
+{
+ int s_idx = html->stack->size(), i_TABLE = a_Html_tag_index("table");
+
+ while (--s_idx > 0 && html->stack->getRef(s_idx)->tag_idx != i_TABLE) ;
+ if (s_idx > 0)
+ html->stack->getRef(s_idx)->table_border_mode = mode;
+}
+
+/* WORKAROUND: collapsing border model requires moving rendering code from
+ * the cell to the table, and making table-code aware of each
+ * cell style.
+ * This workaround mimics collapsing model within separate model. This is not
+ * a complete emulation but should be enough for most cases.
+ */
+static void Html_set_collapsing_border_model(DilloHtml *html, Widget *col_tb)
+{
+ dw::core::style::Style *collapseStyle, *tableStyle;
+ dw::core::style::StyleAttrs collapseCellAttrs, collapseTableAttrs;
+ int borderWidth, marginWidth;
+
+ tableStyle = ((dw::Table*)S_TOP(html)->table)->getStyle ();
+ borderWidth = html->styleEngine->style ()->borderWidth.top;
+ marginWidth = tableStyle->margin.top;
+
+ collapseCellAttrs = *(html->styleEngine->style ());
+ collapseCellAttrs.margin.setVal (0);
+ collapseCellAttrs.borderWidth.left = 0;
+ collapseCellAttrs.borderWidth.top = 0;
+ collapseCellAttrs.borderWidth.right = borderWidth;
+ collapseCellAttrs.borderWidth.bottom = borderWidth;
+ collapseCellAttrs.hBorderSpacing = 0;
+ collapseCellAttrs.vBorderSpacing = 0;
+ collapseStyle = Style::create(HT2LT(html), &collapseCellAttrs);
+ col_tb->setStyle (collapseStyle);
+
+ if (Html_table_get_border_model(html) != DILLO_HTML_TABLE_BORDER_COLLAPSE) {
+ Html_table_set_border_model(html, DILLO_HTML_TABLE_BORDER_COLLAPSE);
+ collapseTableAttrs = *tableStyle;
+ collapseTableAttrs.margin.setVal (marginWidth);
+ collapseTableAttrs.borderWidth.left = borderWidth;
+ collapseTableAttrs.borderWidth.top = borderWidth;
+ collapseTableAttrs.borderWidth.right = 0;
+ collapseTableAttrs.borderWidth.bottom = 0;
+ collapseTableAttrs.hBorderSpacing = 0;
+ collapseTableAttrs.vBorderSpacing = 0;
+ collapseTableAttrs.borderColor = collapseCellAttrs.borderColor;
+ collapseTableAttrs.borderStyle = collapseCellAttrs.borderStyle;
+ /* CSS2 17.6.2: table does not have padding (in collapsing mode) */
+ collapseTableAttrs.padding.setVal (0);
+ collapseStyle = Style::create(HT2LT(html), &collapseTableAttrs);
+ ((dw::Table*)S_TOP(html)->table)->setStyle (collapseStyle);
+ }
+}
+
+/*
+ * Adjust style for separate border model.
+ * (Dw uses this model internally).
+ */
+static void Html_set_separate_border_model(DilloHtml *html, Widget *col_tb)
+{
+ dw::core::style::Style *separateStyle;
+ dw::core::style::StyleAttrs separateCellAttrs;
+
+ separateCellAttrs = *(html->styleEngine->style ());
+ /* CSS2 17.5: Internal table elements do not have margins */
+ separateCellAttrs.margin.setVal (0);
+ separateStyle = Style::create(HT2LT(html), &separateCellAttrs);
+ col_tb->setStyle (separateStyle);
+}
+
+/*
* used by <TD> and <TH>
*/
static void Html_tag_open_table_cell(DilloHtml *html,
@@ -224,6 +320,8 @@ static void Html_tag_open_table_cell(DilloHtml *html,
int32_t bgcolor;
bool_t new_style;
+ html->styleEngine->inheritNonCssHints ();
+
switch (S_TOP(html)->table_mode) {
case DILLO_HTML_TABLE_MODE_NONE:
BUG_MSG("<td> or <th> outside <table>\n");
@@ -245,41 +343,36 @@ static void Html_tag_open_table_cell(DilloHtml *html,
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "rowspan")))
rowspan = MAX(1, strtol (attrbuf, NULL, 10));
- CssPropertyList *props;
- // \todo any shorter way to do this?
- if (S_TOP(html)->table_cell_props != NULL)
- props = new CssPropertyList (*S_TOP(html)->table_cell_props);
- else
- props = new CssPropertyList ();
-
/* text style */
if (!S_TOP(html)->cell_text_align_set) {
- props->set (CSS_PROPERTY_TEXT_ALIGN, CSS_TYPE_ENUM, text_align);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_TEXT_ALIGN,
+ CSS_TYPE_ENUM, text_align);
}
if (a_Html_get_attr(html, tag, tagsize, "nowrap"))
- props->set(CSS_PROPERTY_WHITE_SPACE,CSS_TYPE_ENUM,WHITE_SPACE_NOWRAP);
+ html->styleEngine->setNonCssHint(CSS_PROPERTY_WHITE_SPACE,
+ CSS_TYPE_ENUM, WHITE_SPACE_NOWRAP);
else
- props->set(CSS_PROPERTY_WHITE_SPACE,CSS_TYPE_ENUM,WHITE_SPACE_NORMAL);
+ html->styleEngine->setNonCssHint(CSS_PROPERTY_WHITE_SPACE,
+ CSS_TYPE_ENUM, WHITE_SPACE_NORMAL);
- a_Html_tag_set_align_attr (html, props, tag, tagsize);
+ a_Html_tag_set_align_attr (html, tag, tagsize);
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "width"))) {
- props->set (CSS_PROPERTY_WIDTH, CSS_TYPE_LENGTH_PERCENTAGE,
- a_Html_parse_length (html, attrbuf));
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_WIDTH,
+ CSS_TYPE_LENGTH_PERCENTAGE,
+ a_Html_parse_length (html, attrbuf));
}
- if (a_Html_tag_set_valign_attr (html, tag, tagsize, props))
+ if (a_Html_tag_set_valign_attr (html, tag, tagsize))
new_style = TRUE;
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "bgcolor"))) {
bgcolor = a_Html_color_parse(html, attrbuf, -1);
if (bgcolor != -1)
- props->set (CSS_PROPERTY_BACKGROUND_COLOR, CSS_TYPE_COLOR,bgcolor);
+ html->styleEngine->setNonCssHint (CSS_PROPERTY_BACKGROUND_COLOR,
+ CSS_TYPE_COLOR, bgcolor);
}
- html->styleEngine->setNonCssHints (props);
- delete props;
-
if (html->styleEngine->style ()->textAlign
== TEXT_ALIGN_STRING)
col_tb = new dw::TableCell (
@@ -288,7 +381,11 @@ static void Html_tag_open_table_cell(DilloHtml *html,
else
col_tb = new Textblock (prefs.limit_text_width);
- col_tb->setStyle (html->styleEngine->style ());
+ if (html->styleEngine->style()->borderCollapse == BORDER_MODEL_COLLAPSE){
+ Html_set_collapsing_border_model(html, col_tb);
+ } else {
+ Html_set_separate_border_model(html, col_tb);
+ }
((dw::Table*)S_TOP(html)->table)->addCell (col_tb, colspan, rowspan);
S_TOP(html)->textblock = html->dw = col_tb;
diff --git a/src/uicmd.cc b/src/uicmd.cc
index 93836735..5573db11 100644
--- a/src/uicmd.cc
+++ b/src/uicmd.cc
@@ -449,6 +449,8 @@ BrowserWindow *a_UIcmd_browser_window_new(int ww, int wh,
// Now create the Dw render layout and viewport
FltkPlatform *platform = new FltkPlatform ();
Layout *layout = new Layout (platform);
+ style::Color *bgColor = style::Color::create (layout, prefs.bg_color);
+ layout->setBgColor (bgColor);
FltkViewport *viewport = new FltkViewport (0, 0, 1, 1);
if (prefs.buffered_drawing == 1)
@@ -507,6 +509,8 @@ static BrowserWindow *UIcmd_tab_new(const void *vbw)
// Now create the Dw render layout and viewport
FltkPlatform *platform = new FltkPlatform ();
Layout *layout = new Layout (platform);
+ style::Color *bgColor = style::Color::create (layout, prefs.bg_color);
+ layout->setBgColor (bgColor);
FltkViewport *viewport = new FltkViewport (0, 0, 1, 1);
@@ -1296,14 +1300,14 @@ void a_UIcmd_fullscreen_toggle(BrowserWindow *bw)
* Search for next/previous occurrence of key.
*/
void a_UIcmd_findtext_search(BrowserWindow *bw, const char *key,
- int case_sens, int backwards)
+ int case_sens, int backward)
{
Layout *l = (Layout *)bw->render_layout;
- switch (l->search(key, case_sens, backwards)) {
+ switch (l->search(key, case_sens, backward)) {
case FindtextState::RESTART:
- a_UIcmd_set_msg(bw, "No further occurrences of \"%s\". "
- "Restarting from the top.", key);
+ a_UIcmd_set_msg(bw, backward?"Top reached; restarting from the bottom."
+ :"Bottom reached; restarting from the top.");
break;
case FindtextState::NOT_FOUND:
a_UIcmd_set_msg(bw, "\"%s\" not found.", key);
diff --git a/src/url.c b/src/url.c
index acc8aa72..ae1f131b 100644
--- a/src/url.c
+++ b/src/url.c
@@ -1,7 +1,6 @@
/*
* File: url.c
*
- * Copyright (C) 2001 Livio Baldini Soares <livio@linux.ime.usp.br>
* Copyright (C) 2001-2009 Jorge Arellano Cid <jcid@dillo.org>
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/url.h b/src/url.h
index 503eec60..5688287a 100644
--- a/src/url.h
+++ b/src/url.h
@@ -2,7 +2,6 @@
* File : url.h - Dillo
*
* Copyright (C) 2001 Jorge Arellano Cid <jcid@dillo.org>
- * 2001 Livio Baldini Soares <livio@linux.ime.usp.br>
*
* Parse and normalize all URL's inside Dillo.
*/
diff --git a/src/web.cc b/src/web.cc
index 17302b1c..83700845 100644
--- a/src/web.cc
+++ b/src/web.cc
@@ -61,10 +61,13 @@ int a_Web_dispatch_by_type (const char *Type, DilloWeb *Web,
if (Web->flags & WEB_RootUrl) {
/* We have RootUrl! */
+ style::Color *bgColor = style::Color::create (layout, prefs.bg_color);
+ Web->bgColor = bgColor->getColor ();
+ layout->setBgColor (bgColor);
+
/* Set a style for the widget */
StyleEngine styleEngine (layout);
styleEngine.startElement ("body");
- Web->bgColor= styleEngine.backgroundStyle()->backgroundColor->getColor();
dw = (Widget*) a_Mime_set_viewer(Type, Web, Call, Data);
if (dw == NULL)
@@ -89,12 +92,12 @@ int a_Web_dispatch_by_type (const char *Type, DilloWeb *Web,
} else {
/* A non-RootUrl. At this moment we only handle image-children */
- if (!dStrncasecmp(Type, "image/", 6))
+ if (!dStrncasecmp(Type, "image/", 6)) {
dw = (Widget*) a_Mime_set_viewer(Type, Web, Call, Data);
- }
-
- if (!dw) {
- MSG_HTTP("unhandled MIME type: \"%s\"\n", Type);
+ } else {
+ MSG_HTTP("'%s' cannot be displayed as image; has media type '%s'\n",
+ URL_STR(Web->url), Type);
+ }
}
return (dw ? 1 : -1);
}
diff --git a/test/Makefile.am b/test/Makefile.am
index 709196f4..c95bad98 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,3 +1,5 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir)
AM_CFLAGS = @LIBFLTK_CFLAGS@
AM_CXXFLAGS = @LIBFLTK_CXXFLAGS@
@@ -24,26 +26,26 @@ noinst_PROGRAMS = \
dw_anchors_test_SOURCES = dw_anchors_test.cc
dw_anchors_test_LDADD = \
- ../dw/libDw-widgets.a \
- ../dw/libDw-fltk.a \
- ../dw/libDw-core.a \
- ../lout/liblout.a \
+ $(top_builddir)/dw/libDw-widgets.a \
+ $(top_builddir)/dw/libDw-fltk.a \
+ $(top_builddir)/dw/libDw-core.a \
+ $(top_builddir)/lout/liblout.a \
@LIBFLTK_LIBS@
dw_example_SOURCES = dw_example.cc
dw_example_LDADD = \
- ../dw/libDw-widgets.a \
- ../dw/libDw-fltk.a \
- ../dw/libDw-core.a \
- ../lout/liblout.a \
+ $(top_builddir)/dw/libDw-widgets.a \
+ $(top_builddir)/dw/libDw-fltk.a \
+ $(top_builddir)/dw/libDw-core.a \
+ $(top_builddir)/lout/liblout.a \
@LIBFLTK_LIBS@
dw_find_test_SOURCES = dw_find_test.cc
dw_find_test_LDADD = \
- ../dw/libDw-widgets.a \
- ../dw/libDw-fltk.a \
- ../dw/libDw-core.a \
- ../lout/liblout.a \
+ $(top_builddir)/dw/libDw-widgets.a \
+ $(top_builddir)/dw/libDw-fltk.a \
+ $(top_builddir)/dw/libDw-core.a \
+ $(top_builddir)/lout/liblout.a \
@LIBFLTK_LIBS@
dw_float_test_SOURCES = dw_float_test.cc
@@ -56,91 +58,91 @@ dw_float_test_LDADD = \
dw_links_SOURCES = dw_links.cc
dw_links_LDADD = \
- ../dw/libDw-widgets.a \
- ../dw/libDw-fltk.a \
- ../dw/libDw-core.a \
- ../lout/liblout.a \
+ $(top_builddir)/dw/libDw-widgets.a \
+ $(top_builddir)/dw/libDw-fltk.a \
+ $(top_builddir)/dw/libDw-core.a \
+ $(top_builddir)/lout/liblout.a \
@LIBFLTK_LIBS@
dw_links2_SOURCES = dw_links2.cc
dw_links2_LDADD = \
- ../dw/libDw-widgets.a \
- ../dw/libDw-fltk.a \
- ../dw/libDw-core.a \
- ../lout/liblout.a \
+ $(top_builddir)/dw/libDw-widgets.a \
+ $(top_builddir)/dw/libDw-fltk.a \
+ $(top_builddir)/dw/libDw-core.a \
+ $(top_builddir)/lout/liblout.a \
@LIBFLTK_LIBS@
dw_images_simple_SOURCES = dw_images_simple.cc
dw_images_simple_LDADD = \
- ../dw/libDw-widgets.a \
- ../dw/libDw-fltk.a \
- ../dw/libDw-core.a \
- ../lout/liblout.a \
+ $(top_builddir)/dw/libDw-widgets.a \
+ $(top_builddir)/dw/libDw-fltk.a \
+ $(top_builddir)/dw/libDw-core.a \
+ $(top_builddir)/lout/liblout.a \
@LIBFLTK_LIBS@
dw_images_scaled_SOURCES = dw_images_scaled.cc
dw_images_scaled_LDADD = \
- ../dw/libDw-widgets.a \
- ../dw/libDw-fltk.a \
- ../dw/libDw-core.a \
- ../lout/liblout.a \
+ $(top_builddir)/dw/libDw-widgets.a \
+ $(top_builddir)/dw/libDw-fltk.a \
+ $(top_builddir)/dw/libDw-core.a \
+ $(top_builddir)/lout/liblout.a \
@LIBFLTK_LIBS@
dw_images_scaled2_SOURCES = dw_images_scaled2.cc
dw_images_scaled2_LDADD = \
- ../dw/libDw-widgets.a \
- ../dw/libDw-fltk.a \
- ../dw/libDw-core.a \
- ../lout/liblout.a \
+ $(top_builddir)/dw/libDw-widgets.a \
+ $(top_builddir)/dw/libDw-fltk.a \
+ $(top_builddir)/dw/libDw-core.a \
+ $(top_builddir)/lout/liblout.a \
@LIBFLTK_LIBS@
dw_lists_SOURCES = dw_lists.cc
dw_lists_LDADD = \
- ../dw/libDw-widgets.a \
- ../dw/libDw-fltk.a \
- ../dw/libDw-core.a \
- ../lout/liblout.a \
+ $(top_builddir)/dw/libDw-widgets.a \
+ $(top_builddir)/dw/libDw-fltk.a \
+ $(top_builddir)/dw/libDw-core.a \
+ $(top_builddir)/lout/liblout.a \
@LIBFLTK_LIBS@
dw_table_aligned_SOURCES = dw_table_aligned.cc
dw_table_aligned_LDADD = \
- ../dw/libDw-widgets.a \
- ../dw/libDw-fltk.a \
- ../dw/libDw-core.a \
- ../lout/liblout.a \
+ $(top_builddir)/dw/libDw-widgets.a \
+ $(top_builddir)/dw/libDw-fltk.a \
+ $(top_builddir)/dw/libDw-core.a \
+ $(top_builddir)/lout/liblout.a \
@LIBFLTK_LIBS@
dw_table_SOURCES = dw_table.cc
dw_table_LDADD = \
- ../dw/libDw-widgets.a \
- ../dw/libDw-fltk.a \
- ../dw/libDw-core.a \
- ../lout/liblout.a \
+ $(top_builddir)/dw/libDw-widgets.a \
+ $(top_builddir)/dw/libDw-fltk.a \
+ $(top_builddir)/dw/libDw-core.a \
+ $(top_builddir)/lout/liblout.a \
@LIBFLTK_LIBS@
dw_border_test_SOURCES = dw_border_test.cc
dw_border_test_LDADD = \
- ../dw/libDw-widgets.a \
- ../dw/libDw-fltk.a \
- ../dw/libDw-core.a \
- ../lout/liblout.a \
+ $(top_builddir)/dw/libDw-widgets.a \
+ $(top_builddir)/dw/libDw-fltk.a \
+ $(top_builddir)/dw/libDw-core.a \
+ $(top_builddir)/lout/liblout.a \
@LIBFLTK_LIBS@
dw_imgbuf_mem_test_SOURCES = dw_imgbuf_mem_test.cc
dw_imgbuf_mem_test_LDADD = \
- ../dw/libDw-widgets.a \
- ../dw/libDw-fltk.a \
- ../dw/libDw-core.a \
- ../lout/liblout.a \
+ $(top_builddir)/dw/libDw-widgets.a \
+ $(top_builddir)/dw/libDw-fltk.a \
+ $(top_builddir)/dw/libDw-core.a \
+ $(top_builddir)/lout/liblout.a \
@LIBFLTK_LIBS@
dw_resource_test_SOURCES = dw_resource_test.cc
dw_resource_test_LDADD = \
- ../dw/libDw-widgets.a \
- ../dw/libDw-fltk.a \
- ../dw/libDw-core.a \
- ../lout/liblout.a \
+ $(top_builddir)/dw/libDw-widgets.a \
+ $(top_builddir)/dw/libDw-fltk.a \
+ $(top_builddir)/dw/libDw-core.a \
+ $(top_builddir)/lout/liblout.a \
@LIBFLTK_LIBS@
dw_ui_test_SOURCES = \
@@ -148,10 +150,10 @@ dw_ui_test_SOURCES = \
form.cc \
form.hh
dw_ui_test_LDADD = \
- ../dw/libDw-widgets.a \
- ../dw/libDw-fltk.a \
- ../dw/libDw-core.a \
- ../lout/liblout.a \
+ $(top_builddir)/dw/libDw-widgets.a \
+ $(top_builddir)/dw/libDw-fltk.a \
+ $(top_builddir)/dw/libDw-core.a \
+ $(top_builddir)/lout/liblout.a \
@LIBFLTK_LIBS@
fltk_browser_SOURCES = fltk_browser.cc
@@ -159,10 +161,10 @@ fltk_browser_LDADD = @LIBFLTK_LIBS@
shapes_SOURCES = shapes.cc
shapes_LDADD = \
- ../dw/libDw-core.a \
- ../lout/liblout.a
+ $(top_builddir)/dw/libDw-core.a \
+ $(top_builddir)/lout/liblout.a
cookies_SOURCES = cookies.c
cookies_LDADD = \
- ../dpip/libDpip.a \
- ../dlib/libDlib.a
+ $(top_builddir)/dpip/libDpip.a \
+ $(top_builddir)/dlib/libDlib.a