netsurf: branch chris/extmem updated. release/3.5-73-gce3b92b
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/ce3b92b65fc9a6503ea9f...
...commit http://git.netsurf-browser.org/netsurf.git/commit/ce3b92b65fc9a6503ea9f3a...
...tree http://git.netsurf-browser.org/netsurf.git/tree/ce3b92b65fc9a6503ea9f3a01...
The branch, chris/extmem has been updated
via ce3b92b65fc9a6503ea9f3a01155a9ecd521bed0 (commit)
via 180295936b686d194b7b4c25b9a0dc2038ffc4cb (commit)
via e5a05f1c0e1bb7e7388d4fedb584d8ec71be6628 (commit)
via cae22b17ac28ba77d72ecf9d6bd33614981713cf (commit)
via d6b6dafe50807138da5ad340157042318bc36615 (commit)
via e44bd09ac3a28823d9947c54949d115619003fe4 (commit)
via 68938664411ac2ee82e39e11fe855a6cd1b32c7c (commit)
via 8fd04922cc25bfd2205881fc5d4220c84b2c6fe0 (commit)
via 6a36d4ec2b6fd8ac52da2c3883b4776aec14ba2d (commit)
via 69cea38f41b411ca9e55db365cf94339f4be891c (commit)
via dd14807c8cdff2f486f5da832490ff958c87ba62 (commit)
via 7ec49463dafc20f915ce68c789f36458579783c3 (commit)
via 5c427ba8459b46bcb63daa74e4e03f2e22ed6deb (commit)
via bf3ee089cb57765c48065423027eb4fffbe297f1 (commit)
via 638e07f026d85de0c01630217570d4148aaaced5 (commit)
via 713430f6e5ef49960cb85fa917e73a131d69c7c8 (commit)
via f90ed33501485663a091baefe41a87db93d2db91 (commit)
via d8b6de50d6da9a965df70ad758e9631c15be9728 (commit)
via 9ce01d2024e12881e29f4efd28845f12e56e7b67 (commit)
via 5c567d4f2034ac227350b2d72647cd0d37ebee68 (commit)
via 7677901edfc72228572e72f0858a55ab012f860a (commit)
via 6ddb66ccfbf2c5627e04b9fc6a70661b764d9a93 (commit)
via c9d9537941a9b5b5a2b2557fd775201a2979f428 (commit)
via f687eb888637c76796ff5a07177dfe0e225f268b (commit)
via 0b7edfd252423edf097d82b8354ef34946a1a290 (commit)
via ae01f3661938b14b44a907113b6b65c0e3d1721d (commit)
via 922faa743b16fcfe661d18be9efcaf329186fbe9 (commit)
via 974a4a21e16a2da85a66aae9b80eeca15ca26dd6 (commit)
via cdd53bcffb00819360b3e62ef41de6607aca2c76 (commit)
via a828150d9c1c481cc227656e83d6e34e592e31ce (commit)
via 04841668f0f467740de03ae482a9d9ba87c6fce8 (commit)
via 2bb68cb87431047c564e4572de620c37f43aaac9 (commit)
via 608c0529145806c692d42b8498a2110b3db13989 (commit)
via a74778302fa58c1470e2b182f51861dc1f0671a5 (commit)
via 7d9c9dba3610bb14c0de6acb1bdaf9ec49a66f33 (commit)
via 3488e337b64f7444f3021ca98f391d4ded3326e4 (commit)
via 6560384a2c02370f2c649dbb718c3b97f87918d0 (commit)
via 16dde3c704c36a943d8e36584dc6b52051d156db (commit)
via 77a1b4b5e01846e2c9684f57fda1bac0d6d854e5 (commit)
via 377652e0474d45904e9796fda547dcad7877bb4f (commit)
via 86aff2154f5ae5a3984fdb6accf11ab371029a19 (commit)
via f33d9dcc8cd6b0e46908d506fda34eae398f0272 (commit)
via dd31499bf969baa68e66fca81b9f95447b6f3f2a (commit)
via 7ba291037b1dbd0cd205ba07e6444293596a3761 (commit)
via 10ef7b3f1dad2798af7c0c9e0311ea30c26bdf51 (commit)
via 917714326645b0e02fb9a9714ebd897e8f9398e9 (commit)
via ea08caccb9607b10e19f763076e0e9fd71f57bb4 (commit)
via a6dd92c57137eeabf3e5dc92edeb472ac2c60c96 (commit)
via 31de1c251b5c6f6a39f6f7500e28c6086b807953 (commit)
via 3930d00519bbcee968a804b1f445c1638531cc15 (commit)
via 759c34b32447417faeec20513a0e586230f246cd (commit)
via dee7426656b3cdbf644f65a2dd99c7c93cf0e6d2 (commit)
via d29bccdb3a582a08c84fffea66d197d78048ece2 (commit)
via 798654f9106387a697f4269575eaf700a180b1a9 (commit)
via afea659fefe263040088e6dc8813cb18a6f3d219 (commit)
via 1bc010665e53bdf226370ab12a7ae3f87250df4d (commit)
via 4f38963337cfa6170249898d11d45b329b2c186d (commit)
via 836ea5679e5a817e0c6a2654d5a29a053a602593 (commit)
via 46e1061ef3b156016c689698d35bbbbbebf17471 (commit)
via 392307bb1fdf4186f26300631fe3710d895cf7ce (commit)
via 34f6aa13234a618c3b1add75899af2ca1f6a08e9 (commit)
via d2dd574106554db31aa4ed7a53dc3dcf80c64a9a (commit)
via 695853c192048e83aa7381b5c7fd555dfc87b88b (commit)
via ade0cd8bb95ce20b520cb3b13600d04130f52976 (commit)
via 810e9153d1b4d9ed8e208eece4ee88b0d3867ec0 (commit)
via 7dee1cb7d66610b6b82f745d937a7ea4d0bc15d8 (commit)
via 0bc5d2ca4cee4e6ace987d424098d643e40f1ca1 (commit)
via 33c7df0c40023cb1b0c17084680a21ee8e0229ea (commit)
via 7b78985983216e940415a8bb8711e3e8b55f54b0 (commit)
via 86450ed8a2fe93dba662ca146de625ad0a5801e0 (commit)
via 3a5b4571b419087f8adfeb1dfe6b0c3f32dd9985 (commit)
via d6ad20a2c466daf5deee402100ef217497fc555e (commit)
via b2a32c3ea27aec8345d4d579cc85654cdecad6c0 (commit)
via 281fe7674c04cc9b5216a405a104abb14c9d1778 (commit)
via 0368935cd31fd08b6383f3941c1f64ecb4c9ef90 (commit)
from 5d705f521dd09415de4fe29d1695a6924971b8ce (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=ce3b92b65fc9a6503ea...
commit ce3b92b65fc9a6503ea9f3a01155a9ecd521bed0
Merge: 5d705f5 1802959
Author: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Commit: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Merge branch 'master' of git://git.netsurf-browser.org/netsurf into chris/extmem
Conflicts:
amiga/bitmap.c
diff --cc amiga/bitmap.c
index cbe1643,6ef5157..b977bc4
--- a/amiga/bitmap.c
+++ b/amiga/bitmap.c
@@@ -29,8 -30,15 +30,16 @@@
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/utility.h>
+
+ #include <proto/guigfx.h>
+ #include <guigfx/guigfx.h>
+ #include <render/render.h>
+ #ifndef __amigaos4__
+ #include <inline/guigfx.h>
+ #endif
+
#ifdef __amigaos4__
+#include <exec/extmem.h>
#include <sys/param.h>
#endif
#include "assert.h"
@@@ -173,23 -150,11 +187,20 @@@ void amiga_bitmap_destroy(void *bitmap
ami_rtg_freebitmap(bm->nativebm);
}
- if(bm->dto) {
- /**\todo find out why this crashes on exit but not during normal program execution */
- DisposeDTObject(bm->dto);
- }
-
if(bm->native_mask) FreeRaster(bm->native_mask, bm->width, bm->height);
+
+#ifdef __amigaos4__
+ if(nsoption_bool(use_extmem) == true) {
+ amiga_bitmap_unmap_buffer(bm);
+ FreeSysObject(ASOT_EXTMEM, bm->iextmem);
+ } else
+#endif
+ {
+ FreeVec(bm->pixdata);
+ }
+
+ if(bm->drawhandle) ReleaseDrawHandle(bm->drawhandle);
+ if(bm->psm) DeletePenShareMap(bm->psm);
- FreeVec(bm->pixdata);
-
if(bm->url) nsurl_unref(bm->url);
if(bm->title) free(bm->title);
@@@ -236,17 -202,15 +248,17 @@@ void amiga_bitmap_modified(void *bitmap
{
struct bitmap *bm = bitmap;
- if((bm->nativebm)) // && (bm->native == AMI_NSBM_TRUECOLOUR))
- ami_rtg_freebitmap(bm->nativebm);
-
+#ifdef __amigaos4__
+ amiga_bitmap_unmap_buffer(bm);
+#endif
+
- if((bm->nativebm) && (bm->native == AMI_NSBM_TRUECOLOUR))
- ami_rtg_freebitmap(bm->nativebm);
-
- if(bm->dto) DisposeDTObject(bm->dto);
++ if(bm->nativebm) ami_rtg_freebitmap(bm->nativebm);
+ if(bm->drawhandle) ReleaseDrawHandle(bm->drawhandle);
+ if(bm->psm) DeletePenShareMap(bm->psm);
if(bm->native_mask) FreeRaster(bm->native_mask, bm->width, bm->height);
bm->nativebm = NULL;
- bm->dto = NULL;
+ bm->drawhandle = NULL;
+ bm->psm = NULL;
bm->native_mask = NULL;
bm->native = AMI_NSBM_NONE;
}
-----------------------------------------------------------------------
Summary of changes:
Makefile | 2 +-
amiga/Makefile.target | 6 +-
amiga/arexx.c | 8 +-
amiga/bitmap.c | 223 +-
amiga/bitmap.h | 10 -
amiga/clipboard.c | 3 +
amiga/ctxmenu.c | 22 +-
amiga/download.c | 2 +
amiga/dt_anim.c | 5 +-
amiga/dt_picture.c | 5 +-
amiga/dt_sound.c | 4 +-
amiga/file.c | 2 +
amiga/font.c | 17 +-
amiga/font.h | 10 +-
amiga/font_bullet.c | 24 +-
amiga/font_cache.c | 2 +-
amiga/font_diskfont.c | 33 +-
amiga/gui.c | 68 +-
amiga/gui.h | 10 +-
amiga/gui_options.c | 6 +-
amiga/icon.c | 4 +-
amiga/libs.c | 12 +-
amiga/login.c | 1 +
amiga/menu.c | 5 +-
amiga/menu.h | 14 +-
amiga/misc.c | 9 +-
amiga/misc.h | 13 +
amiga/pkg/netsurf.readme | 4 +-
amiga/pkg/netsurf_os3.readme | 4 +-
amiga/plotters.c | 17 +-
amiga/plotters.h | 2 +
amiga/plugin_hack.c | 6 +-
amiga/print.c | 7 +-
amiga/theme.c | 1 +
amiga/tree.c | 1 +
amiga/version.c | 5 +-
atari/about.c | 1 +
atari/certview.c | 22 +-
atari/cookies.c | 58 +-
atari/ctxmenu.c | 20 +-
atari/deskmenu.c | 5 +-
atari/download.c | 12 +-
atari/file.c | 1 +
atari/findfile.c | 10 +-
atari/font.c | 153 +-
atari/font.h | 1 +
atari/gui.c | 99 +-
atari/gui.h | 2 +
atari/history.c | 77 +-
atari/login.c | 1 +
atari/misc.c | 60 +-
atari/misc.h | 40 +-
atari/plot/font_internal.c | 1 +
atari/plot/plot.c | 2 +
atari/rootwin.c | 28 +-
atari/schedule.c | 2 +-
atari/search.h | 2 +
atari/settings.c | 6 +-
atari/toolbar.c | 23 +-
beos/Makefile.target | 3 +-
beos/bitmap.cpp | 24 +-
beos/download.cpp | 2 +
beos/fetch_rsrc.cpp | 1 +
beos/font.cpp | 229 +-
beos/font.h | 11 +-
beos/gui.cpp | 70 +-
beos/plotters.cpp | 1 -
beos/scaffolding.cpp | 1 -
beos/window.cpp | 2 +-
cocoa/Makefile.target | 5 +-
cocoa/NetsurfApp.m | 4 +-
cocoa/apple_image.m | 2 +-
cocoa/font.h | 4 +-
cocoa/font.m | 53 +-
cocoa/gui.h | 2 +-
cocoa/gui.m | 22 +-
cocoa/utils.m | 30 -
content/content.c | 42 +-
content/content.h | 20 +-
desktop/version.c => content/content_debug.h | 26 +-
content/content_factory.c | 2 +
content/content_factory.h | 1 -
content/content_protected.h | 29 +-
content/fetch.c | 7 +-
content/fetchers.h | 2 +-
content/fetchers/about.c | 32 +-
content/fetchers/curl.c | 35 +-
content/fetchers/data.c | 26 +-
content/fetchers/file.c | 56 +-
content/fetchers/resource.c | 17 +-
content/fs_backing_store.c | 6 +-
content/hlcache.c | 6 +-
content/llcache.c | 90 +-
content/urldb.c | 24 +-
desktop/browser.c | 59 +-
desktop/browser_history.c | 15 +-
desktop/browser_private.h | 2 +-
desktop/frames.c | 39 +-
desktop/frames.h | 11 +-
desktop/gui_factory.c | 76 +-
desktop/gui_fetch.h | 4 +-
desktop/{font.h => gui_layout.h} | 70 +-
desktop/gui_misc.h | 19 +-
desktop/gui_table.h | 55 +-
desktop/hotlist.c | 19 +-
desktop/knockout.c | 1 +
desktop/netsurf.c | 6 +-
desktop/plot_style.h | 2 +-
desktop/print.c | 3 +-
desktop/print.h | 9 +-
desktop/save_complete.c | 39 +-
desktop/save_pdf.c | 20 +-
desktop/save_pdf.h | 2 +-
desktop/scrollbar.c | 10 +-
desktop/scrollbar.h | 6 +-
desktop/searchweb.c | 3 +
desktop/textarea.c | 28 +-
desktop/tree.c | 20 +-
desktop/treeview.c | 22 +-
desktop/version.c | 4 +-
framebuffer/Makefile.target | 2 +-
framebuffer/fbtk/fbtk.c | 1 +
framebuffer/fbtk/text.c | 13 +-
framebuffer/font.h | 36 +-
framebuffer/font_freetype.c | 66 +-
framebuffer/font_internal.c | 57 +-
framebuffer/font_internal.h | 4 +-
framebuffer/framebuffer.c | 1 +
framebuffer/gui.c | 45 +-
framebuffer/misc.c | 33 -
framebuffer/schedule.c | 2 +-
gtk/Makefile.target | 4 +-
gtk/about.c | 4 +-
gtk/bitmap.c | 2 +
gtk/completion.c | 3 +-
gtk/download.c | 4 +-
gtk/gui.c | 17 +-
gtk/history.c | 1 +
gtk/{font_pango.c => layout_pango.c} | 133 +-
gtk/{font_pango.h => layout_pango.h} | 28 +-
gtk/menu.c | 49 +-
gtk/plotters.c | 17 +-
gtk/preferences.c | 1 +
gtk/print.c | 7 +-
gtk/scaffolding.c | 53 +-
gtk/search.c | 3 +-
gtk/toolbar.c | 60 +-
gtk/treeview.c | 4 +-
gtk/viewdata.c | 5 +-
gtk/viewsource.c | 1 +
desktop/version.c => gtk/warn.h | 20 +-
gtk/window.c | 6 +-
image/bmp.c | 1 +
image/gif.c | 11 +-
image/ico.c | 1 +
image/image.c | 1 +
image/image_cache.c | 8 +-
image/jpeg.c | 3 +-
image/nssprite.c | 3 +-
image/png.c | 3 +-
image/rsvg.c | 3 +-
image/svg.c | 2 +-
javascript/content.c | 2 +-
javascript/duktape/dukky.c | 1 +
javascript/fetcher.c | 28 +-
monkey/Makefile.target | 4 +-
monkey/browser.c | 2 +
monkey/download.c | 1 +
monkey/{font.c => layout.c} | 35 +-
atari/about.h => monkey/layout.h | 10 +-
monkey/main.c | 16 +-
monkey/schedule.c | 2 +-
monkey/utils.c | 30 -
render/box.c | 26 +-
render/box_construct.c | 17 +-
render/form.c | 18 +-
render/html.c | 38 +-
render/html_css.c | 6 +-
render/html_interaction.c | 27 +-
render/html_internal.h | 6 +-
render/html_object.c | 59 +-
render/html_redraw.c | 44 +-
render/layout.c | 8266 +++++++++++++-------------
render/layout.h | 47 +-
render/search.c | 9 +-
render/textplain.c | 43 +-
riscos/401login.c | 8 +-
riscos/bitmap.c | 16 +-
riscos/configure.c | 8 +-
riscos/configure/con_fonts.c | 3 +-
riscos/configure/con_image.c | 2 +-
riscos/configure/con_language.c | 4 +-
riscos/configure/con_theme.c | 21 +-
riscos/content-handlers/artworks.c | 4 +-
riscos/content-handlers/draw.c | 4 +-
riscos/content-handlers/sprite.c | 4 +-
riscos/dialog.c | 22 +-
riscos/download.c | 77 +-
riscos/filetype.c | 8 +-
riscos/font.c | 249 +-
riscos/font.h | 2 +
riscos/gui.c | 87 +-
riscos/gui.h | 1 +
riscos/gui/button_bar.c | 12 +-
riscos/gui/throbber.c | 7 +-
riscos/gui/url_bar.c | 30 +-
riscos/help.c | 12 +-
riscos/history.c | 28 +-
riscos/hotlist.c | 2 +-
riscos/iconbar.c | 4 +-
riscos/image.c | 3 +-
riscos/menus.c | 18 +-
riscos/message.c | 7 +-
riscos/mouse.c | 11 +-
riscos/print.c | 29 +-
riscos/query.c | 10 +-
riscos/save.c | 46 +-
riscos/save_draw.c | 14 +-
riscos/search.c | 2 +-
riscos/sslcert.c | 4 +-
riscos/textselection.c | 21 +-
riscos/theme.c | 28 +-
riscos/theme_install.c | 12 +-
riscos/toolbar.c | 24 +-
riscos/treeview.c | 34 +-
riscos/ucstables.c | 1 +
riscos/uri.c | 2 +-
riscos/url_complete.c | 36 +-
riscos/url_protocol.c | 19 +-
riscos/wimp.c | 76 +-
riscos/wimp_event.c | 16 +-
riscos/window.c | 150 +-
test/Makefile | 52 +-
test/llcache.c | 14 -
test/urldbtest.c | 11 -
utils/config.h | 17 +-
desktop/version.c => utils/dirent.h | 33 +-
utils/file.c | 1 +
utils/filename.c | 3 +-
utils/filepath.c | 1 +
utils/idna.c | 1 +
utils/inet.h | 62 +
utils/log.c | 2 +-
utils/messages.c | 1 +
utils/string.h | 115 +
utils/sys_time.h | 53 +
utils/time.h | 32 +-
utils/url.c | 2 +-
utils/utils.c | 151 +-
utils/utils.h | 168 +-
windows/Makefile.target | 2 +-
windows/about.c | 5 +-
windows/download.c | 19 +-
windows/file.c | 1 +
windows/font.c | 38 +-
windows/font.h | 1 +
windows/gui.c | 12 +-
windows/gui.h | 23 +-
windows/main.c | 10 +-
windows/misc.c | 40 -
windows/prefs.c | 4 +-
windows/res/installer.nsi | 2 +-
windows/schedule.c | 3 +-
windows/window.c | 12 +-
264 files changed, 7299 insertions(+), 6849 deletions(-)
delete mode 100644 cocoa/utils.m
copy desktop/version.c => content/content_debug.h (64%)
rename desktop/{font.h => gui_layout.h} (51%)
delete mode 100644 framebuffer/misc.c
rename gtk/{font_pango.c => layout_pango.c} (71%)
rename gtk/{font_pango.h => layout_pango.h} (62%)
copy desktop/version.c => gtk/warn.h (64%)
rename monkey/{font.c => layout.c} (82%)
copy atari/about.h => monkey/layout.h (76%)
delete mode 100644 monkey/utils.c
copy desktop/version.c => utils/dirent.h (51%)
create mode 100644 utils/inet.h
create mode 100644 utils/string.h
create mode 100644 utils/sys_time.h
delete mode 100644 windows/misc.c
diff --git a/Makefile b/Makefile
index 2f71c02..d0c0723 100644
--- a/Makefile
+++ b/Makefile
@@ -663,7 +663,7 @@ ifeq ($(TARGET),beos)
$(Q)$(BEOS_SETVER) $(EXETARGET) \
-app $(VERSION_MAJ) $(VERSION_MIN) 0 d 0 \
-short "NetSurf $(VERSION_FULL)" \
- -long "NetSurf $(VERSION_FULL) © 2003 - 2014 The NetSurf Developers"
+ -long "NetSurf $(VERSION_FULL) © 2003 - 2016 The NetSurf Developers"
$(VQ)echo " MIMESET: $(EXETARGET)"
$(Q)$(BEOS_MIMESET) $(EXETARGET)
endif
diff --git a/amiga/Makefile.target b/amiga/Makefile.target
index 8e16780..54957f7 100644
--- a/amiga/Makefile.target
+++ b/amiga/Makefile.target
@@ -50,10 +50,10 @@ else
LDFLAGS += $(shell $(PKG_CONFIG) --libs tre)
LDFLAGS += -L$(GCCSDK_INSTALL_ENV)/lib
+ LDFLAGS += -lpbl -liconv
+
ifeq ($(SUBTARGET),os3)
- LDFLAGS += -lpbl -liconv -lamiga
- else
- LDFLAGS += -lpbl -liconv
+ LDFLAGS += -lamiga -lm
endif
endif
diff --git a/amiga/arexx.c b/amiga/arexx.c
index 412fc40..dec40e0 100644
--- a/amiga/arexx.c
+++ b/amiga/arexx.c
@@ -29,13 +29,15 @@
#include <gadgets/clicktab.h>
#include <reaction/reaction_macros.h>
+#include "utils/utils.h"
+#include "utils/log.h"
+#include "utils/nsoption.h"
+#include "utils/nsurl.h"
+#include "content/hlcache.h"
#include "desktop/browser.h"
#include "desktop/gui_window.h"
#include "desktop/version.h"
-#include "utils/log.h"
-#include "utils/nsoption.h"
-
#include "amiga/arexx.h"
#include "amiga/download.h"
#include "amiga/gui.h"
diff --git a/amiga/bitmap.c b/amiga/bitmap.c
index cbe1643..b977bc4 100644
--- a/amiga/bitmap.c
+++ b/amiga/bitmap.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008, 2009, 2012 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
+ * Copyright 2008, 2009, 2012, 2016 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -18,6 +18,7 @@
#include "amiga/os3support.h"
+#include <stdlib.h>
#include <proto/exec.h>
#ifdef __amigaos4__
#include <graphics/blitattr.h>
@@ -29,15 +30,25 @@
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/utility.h>
+
+#include <proto/guigfx.h>
+#include <guigfx/guigfx.h>
+#include <render/render.h>
+#ifndef __amigaos4__
+#include <inline/guigfx.h>
+#endif
+
#ifdef __amigaos4__
#include <exec/extmem.h>
#include <sys/param.h>
#endif
#include "assert.h"
+#include "utils/log.h"
#include "utils/nsoption.h"
#include "utils/nsurl.h"
#include "utils/messages.h"
+#include "content/hlcache.h"
#include "desktop/mouse.h"
#include "desktop/gui_window.h"
#include "image/bitmap.h"
@@ -61,6 +72,8 @@ struct bitmap {
int nativebmheight;
PLANEPTR native_mask;
Object *dto;
+ APTR drawhandle;
+ APTR psm;
struct nsurl *url; /* temporary storage space */
char *title; /* temporary storage space */
ULONG *icondata; /* for appicons */
@@ -113,7 +126,8 @@ void *amiga_bitmap_create(int width, int height, unsigned int state)
bitmap->nativebmwidth = 0;
bitmap->nativebmheight = 0;
bitmap->native_mask = NULL;
- bitmap->dto = NULL;
+ bitmap->drawhandle = NULL;
+ bitmap->psm = NULL;
bitmap->url = NULL;
bitmap->title = NULL;
bitmap->icondata = NULL;
@@ -169,15 +183,10 @@ void amiga_bitmap_destroy(void *bitmap)
if(bm)
{
- if((bm->nativebm) && (bm->native == AMI_NSBM_TRUECOLOUR)) {
+ if((bm->nativebm)) { // && (bm->native == AMI_NSBM_TRUECOLOUR)) {
ami_rtg_freebitmap(bm->nativebm);
}
- if(bm->dto) {
- /**\todo find out why this crashes on exit but not during normal program execution */
- DisposeDTObject(bm->dto);
- }
-
if(bm->native_mask) FreeRaster(bm->native_mask, bm->width, bm->height);
#ifdef __amigaos4__
@@ -190,13 +199,16 @@ void amiga_bitmap_destroy(void *bitmap)
FreeVec(bm->pixdata);
}
+ if(bm->drawhandle) ReleaseDrawHandle(bm->drawhandle);
+ if(bm->psm) DeletePenShareMap(bm->psm);
if(bm->url) nsurl_unref(bm->url);
if(bm->title) free(bm->title);
bm->pixdata = NULL;
bm->nativebm = NULL;
bm->native_mask = NULL;
- bm->dto = NULL;
+ bm->drawhandle = NULL;
+ bm->psm = NULL;
bm->url = NULL;
bm->title = NULL;
@@ -240,13 +252,13 @@ void amiga_bitmap_modified(void *bitmap)
amiga_bitmap_unmap_buffer(bm);
#endif
- if((bm->nativebm) && (bm->native == AMI_NSBM_TRUECOLOUR))
- ami_rtg_freebitmap(bm->nativebm);
-
- if(bm->dto) DisposeDTObject(bm->dto);
+ if(bm->nativebm) ami_rtg_freebitmap(bm->nativebm);
+ if(bm->drawhandle) ReleaseDrawHandle(bm->drawhandle);
+ if(bm->psm) DeletePenShareMap(bm->psm);
if(bm->native_mask) FreeRaster(bm->native_mask, bm->width, bm->height);
bm->nativebm = NULL;
- bm->dto = NULL;
+ bm->drawhandle = NULL;
+ bm->psm = NULL;
bm->native_mask = NULL;
bm->native = AMI_NSBM_NONE;
}
@@ -336,17 +348,25 @@ static size_t bitmap_get_bpp(void *vbitmap)
return 4;
}
-#ifdef __amigaos4__
static void ami_bitmap_argb_to_rgba(struct bitmap *bm)
{
if(bm == NULL) return;
ULONG *data = (ULONG *)amiga_bitmap_get_buffer(bm);
- for(int i = 0; i < ((amiga_bitmap_get_rowstride(bm) / sizeof(ULONG)) * bm->height); i++) {
+ for(int i = 0; i < (bm->width * bm->height); i++) {
data[i] = (data[i] << 8) | (data[i] >> 24);
}
}
-#endif
+
+static void ami_bitmap_rgba_to_argb(struct bitmap *bm)
+{
+ if(bm == NULL) return;
+
+ ULONG *data = (ULONG *)amiga_bitmap_get_buffer(bm);
+ for(int i = 0; i < (bm->width * bm->height); i++) {
+ data[i] = (data[i] >> 8) | (data[i] << 24);
+ }
+}
#ifdef BITMAP_DUMP
void bitmap_dump(struct bitmap *bitmap)
@@ -388,7 +408,7 @@ Object *ami_datatype_object_from_bitmap(struct bitmap *bitmap)
}
SetDTAttrs(dto,NULL,NULL,
- DTA_ObjName,nsurl_access(bitmap->url),
+ DTA_ObjName, bitmap->url ? nsurl_access(bitmap->url) : "",
DTA_ObjAnnotation,bitmap->title,
DTA_ObjAuthor,messages_get("NetSurf"),
DTA_NominalHoriz,bitmap_get_width(bitmap),
@@ -441,41 +461,64 @@ struct bitmap *ami_bitmap_from_datatype(char *filename)
return bm;
}
-static inline struct BitMap *ami_bitmap_get_truecolour(struct bitmap *bitmap,int width,int height,struct BitMap *friendbm)
+static inline struct BitMap *ami_bitmap_get_generic(struct bitmap *bitmap, int width, int height, struct BitMap *friendbm, int type)
{
struct BitMap *tbm = NULL;
- if(!bitmap) return NULL;
-
- if((bitmap->native != AMI_NSBM_NONE) && (bitmap->native != AMI_NSBM_TRUECOLOUR)) {
- amiga_bitmap_modified(bitmap);
- }
-
if(bitmap->nativebm)
{
- if((bitmap->nativebmwidth == width) && (bitmap->nativebmheight==height))
- {
+ if((bitmap->nativebmwidth == width) && (bitmap->nativebmheight == height)) {
tbm = bitmap->nativebm;
return tbm;
- }
- else if((bitmap->nativebmwidth == bitmap->width) && (bitmap->nativebmheight==bitmap->height))
- {
+ } else if((bitmap->nativebmwidth == bitmap->width) &&
+ (bitmap->nativebmheight == bitmap->height)) { // >= width/height ?
tbm = bitmap->nativebm;
- }
- else
- {
- if(bitmap->nativebm) ami_rtg_freebitmap(bitmap->nativebm);
- bitmap->nativebm = NULL;
+ } else {
+ if(bitmap->nativebm) amiga_bitmap_modified(bitmap);
}
}
- if(!tbm)
- {
- if((tbm = ami_rtg_allocbitmap(bitmap->width, bitmap->height, 32, 0,
- friendbm, AMI_BITMAP_FORMAT))) {
- ami_rtg_writepixelarray(amiga_bitmap_get_buffer(bitmap),
- tbm, bitmap->width, bitmap->height,
- bitmap->width * 4, AMI_BITMAP_FORMAT);
+ if(tbm == NULL) {
+ if(type == AMI_NSBM_TRUECOLOUR) {
+ if((tbm = ami_rtg_allocbitmap(bitmap->width, bitmap->height, 32, 0,
+ friendbm, AMI_BITMAP_FORMAT))) {
+ ami_rtg_writepixelarray(amiga_bitmap_get_buffer(bitmap),
+ tbm, bitmap->width, bitmap->height,
+ bitmap->width * 4, AMI_BITMAP_FORMAT);
+ }
+ } else {
+ if((tbm = ami_rtg_allocbitmap(bitmap->width, bitmap->height,
+ 8, 0, friendbm, AMI_BITMAP_FORMAT))) {
+
+ struct RastPort rp;
+ InitRastPort(&rp);
+ rp.BitMap = tbm;
+ ULONG dithermode = DITHERMODE_NONE;
+
+ if(nsoption_int(dither_quality) == 1) {
+ dithermode = DITHERMODE_EDD;
+ } else if(nsoption_int(dither_quality) == 2) {
+ dithermode = DITHERMODE_FS;
+ }
+
+ ami_bitmap_rgba_to_argb(bitmap);
+ bitmap->psm = CreatePenShareMap(TAG_DONE);
+ AddPixelArray(bitmap->psm, (ULONG *)amiga_bitmap_get_buffer(bitmap),
+ bitmap->width, bitmap->height,
+ GGFX_PixelFormat, PIXFMT_0RGB_32, TAG_DONE);
+
+ bitmap->drawhandle = ObtainDrawHandle(bitmap->psm, &rp, scrn->ViewPort.ColorMap,
+ GGFX_DitherMode, dithermode,
+ TAG_DONE);
+
+ APTR ddh = CreateDirectDrawHandle(bitmap->drawhandle,
+ bitmap->width, bitmap->height,
+ bitmap->width, bitmap->height, NULL);
+
+ DirectDrawTrueColor(ddh, (ULONG *)amiga_bitmap_get_buffer(bitmap), 0, 0, TAG_DONE);
+ DeleteDirectDrawHandle(ddh);
+ ami_bitmap_argb_to_rgba(bitmap);
+ }
}
if(nsoption_int(cache_bitmaps) == 2)
@@ -483,7 +526,7 @@ static inline struct BitMap *ami_bitmap_get_truecolour(struct bitmap *bitmap,int
bitmap->nativebm = tbm;
bitmap->nativebmwidth = bitmap->width;
bitmap->nativebmheight = bitmap->height;
- bitmap->native = AMI_NSBM_TRUECOLOUR;
+ bitmap->native = type;
}
}
@@ -491,25 +534,29 @@ static inline struct BitMap *ami_bitmap_get_truecolour(struct bitmap *bitmap,int
{
struct BitMap *scaledbm;
struct BitScaleArgs bsa;
+ int depth = 32;
+ if(type == AMI_NSBM_PALETTEMAPPED) depth = 8;
- scaledbm = ami_rtg_allocbitmap(width, height, 32, 0,
+ scaledbm = ami_rtg_allocbitmap(width, height, depth, 0,
friendbm, AMI_BITMAP_FORMAT);
#ifdef __amigaos4__
- if(__builtin_expect(GfxBase->LibNode.lib_Version >= 53, 1)) {
- /* AutoDoc says v52, but this function isn't in OS4.0, so checking for v53 (OS4.1) */
+ if(__builtin_expect(((GfxBase->LibNode.lib_Version >= 53) &&
+ (type == AMI_NSBM_TRUECOLOUR)), 1)) {
+ /* AutoDoc says v52, but this function isn't in OS4.0, so checking for v53 (OS4.1)
+ * Additionally, when we use friend BitMaps in non 32-bit modes it freezes the OS */
uint32 flags = 0;
if(nsoption_bool(scale_quality)) flags |= COMPFLAG_SrcFilter;
CompositeTags(COMPOSITE_Src, tbm, scaledbm,
- COMPTAG_ScaleX,COMP_FLOAT_TO_FIX((float)width/bitmap->width),
- COMPTAG_ScaleY,COMP_FLOAT_TO_FIX((float)height/bitmap->height),
+ COMPTAG_ScaleX, COMP_FLOAT_TO_FIX((float)width/bitmap->width),
+ COMPTAG_ScaleY, COMP_FLOAT_TO_FIX((float)height/bitmap->height),
COMPTAG_Flags, flags,
- COMPTAG_DestX,0,
- COMPTAG_DestY,0,
- COMPTAG_DestWidth,width,
- COMPTAG_DestHeight,height,
- COMPTAG_OffsetX,0,
- COMPTAG_OffsetY,0,
+ COMPTAG_DestX, 0,
+ COMPTAG_DestY, 0,
+ COMPTAG_DestWidth, width,
+ COMPTAG_DestHeight, height,
+ COMPTAG_OffsetX, 0,
+ COMPTAG_OffsetY, 0,
COMPTAG_FriendBitMap, scrn->RastPort.BitMap,
TAG_DONE);
} else /* Do it the old-fashioned way. This is pretty slow, even on OS4.1 */
@@ -543,7 +590,7 @@ static inline struct BitMap *ami_bitmap_get_truecolour(struct bitmap *bitmap,int
bitmap->nativebm = tbm;
bitmap->nativebmwidth = width;
bitmap->nativebmheight = height;
- bitmap->native = AMI_NSBM_TRUECOLOUR;
+ bitmap->native = type;
}
}
@@ -554,6 +601,16 @@ static inline struct BitMap *ami_bitmap_get_truecolour(struct bitmap *bitmap,int
return tbm;
}
+
+static inline struct BitMap *ami_bitmap_get_truecolour(struct bitmap *bitmap,int width,int height,struct BitMap *friendbm)
+{
+ if((bitmap->native != AMI_NSBM_NONE) && (bitmap->native != AMI_NSBM_TRUECOLOUR)) {
+ amiga_bitmap_modified(bitmap);
+ }
+
+ return ami_bitmap_get_generic(bitmap, width, height, friendbm, AMI_NSBM_TRUECOLOUR);
+}
+
PLANEPTR ami_bitmap_get_mask(struct bitmap *bitmap, int width,
int height, struct BitMap *n_bm)
{
@@ -585,62 +642,22 @@ PLANEPTR ami_bitmap_get_mask(struct bitmap *bitmap, int width,
}
static inline struct BitMap *ami_bitmap_get_palettemapped(struct bitmap *bitmap,
- int width, int height)
+ int width, int height, struct BitMap *friendbm)
{
- struct BitMap *dtbm;
-
if((bitmap->native != AMI_NSBM_NONE) && (bitmap->native != AMI_NSBM_PALETTEMAPPED)) {
amiga_bitmap_modified(bitmap);
}
- /* Dispose the DataTypes object if we've performed a layout already,
- and we need to scale, as scaling can only be performed before
- the first GM_LAYOUT */
-
- if(bitmap->dto &&
- ((bitmap->nativebmwidth != width) ||
- (bitmap->nativebmheight != height))) {
- DisposeDTObject(bitmap->dto);
- bitmap->dto = NULL;
- }
-
- if(bitmap->dto == NULL) {
- bitmap->dto = ami_datatype_object_from_bitmap(bitmap);
-
- SetDTAttrs(bitmap->dto, NULL, NULL,
- PDTA_Screen, scrn,
- PDTA_ScaleQuality, nsoption_bool(scale_quality),
- PDTA_DitherQuality, nsoption_int(dither_quality),
- PDTA_FreeSourceBitMap, TRUE,
- TAG_DONE);
-
- if((bitmap->width != width) || (bitmap->height != height)) {
- IDoMethod(bitmap->dto, PDTM_SCALE, width, height, 0);
- }
-
- if((DoDTMethod(bitmap->dto, 0, 0, DTM_PROCLAYOUT, 0, 1)) == 0)
- return NULL;
- }
-
- GetDTAttrs(bitmap->dto,
- PDTA_DestBitMap, &dtbm,
- TAG_END);
-
- bitmap->nativebmwidth = width;
- bitmap->nativebmheight = height;
-
- /**\todo Native bitmaps are stored as DataTypes Objects here?
- This is sub-optimal and they should be cached as BitMaps according to user
- preferences */
- bitmap->native = AMI_NSBM_PALETTEMAPPED;
- return dtbm;
+ return ami_bitmap_get_generic(bitmap, width, height, friendbm, AMI_NSBM_PALETTEMAPPED);
}
struct BitMap *ami_bitmap_get_native(struct bitmap *bitmap,
int width, int height, struct BitMap *friendbm)
{
+ if(bitmap == NULL) return NULL;
+
if(__builtin_expect(ami_plot_screen_is_palettemapped() == true, 0)) {
- return ami_bitmap_get_palettemapped(bitmap, width, height);
+ return ami_bitmap_get_palettemapped(bitmap, width, height, friendbm);
} else {
return ami_bitmap_get_truecolour(bitmap, width, height, friendbm);
}
@@ -737,12 +754,6 @@ void ami_bitmap_set_icondata(struct bitmap *bm, ULONG *icondata)
bm->icondata = icondata;
}
-bool ami_bitmap_has_dto(struct bitmap *bm)
-{
- if(bm->dto) return true;
- else return false;
-}
-
bool ami_bitmap_is_nativebm(struct bitmap *bm, struct BitMap *nbm)
{
if(bm->nativebm == nbm) return true;
diff --git a/amiga/bitmap.h b/amiga/bitmap.h
index 743cd8f..d7dd70b 100755
--- a/amiga/bitmap.h
+++ b/amiga/bitmap.h
@@ -83,16 +83,6 @@ ULONG *ami_bitmap_get_icondata(struct bitmap *bm);
void ami_bitmap_set_icondata(struct bitmap *bm, ULONG *icondata);
/**
- * Test if a bitmap has an associated DataTypes object.
- *
- * \param bm a bitmap, as returned by bitmap_create()
- * \return true if the BitMap has a DataTypes object
- *
- * This function probably shouldn't be used!
- */
-bool ami_bitmap_has_dto(struct bitmap *bm);
-
-/**
* Test if a BitMap is owned by a bitmap.
*
* \param bm a bitmap, as returned by bitmap_create()
diff --git a/amiga/clipboard.c b/amiga/clipboard.c
index 92bf4df..12ceb0f 100644
--- a/amiga/clipboard.c
+++ b/amiga/clipboard.c
@@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <stdlib.h>
#include <proto/iffparse.h>
#include <proto/intuition.h>
#include <proto/exec.h>
@@ -28,6 +29,8 @@
#include "utils/nsoption.h"
#include "utils/utf8.h"
+#include "utils/nsurl.h"
+#include "content/hlcache.h"
#include "desktop/browser.h"
#include "desktop/plotters.h"
#include "desktop/textinput.h"
diff --git a/amiga/ctxmenu.c b/amiga/ctxmenu.c
index b49ba80..9320fac 100644
--- a/amiga/ctxmenu.c
+++ b/amiga/ctxmenu.c
@@ -23,6 +23,7 @@
#ifdef __amigaos4__
#include <string.h>
+#include <stdlib.h>
#include <proto/exec.h>
#include <proto/intuition.h>
@@ -34,6 +35,18 @@
#include <intuition/menuclass.h>
#include <reaction/reaction_macros.h>
+#include "utils/utils.h"
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "utils/nsoption.h"
+#include "utils/nsurl.h"
+#include "content/hlcache.h"
+#include "desktop/browser.h"
+#include "desktop/browser_history.h"
+#include "desktop/mouse.h"
+#include "desktop/searchweb.h"
+#include "desktop/textinput.h"
+
#include "amiga/bitmap.h"
#include "amiga/clipboard.h"
#include "amiga/ctxmenu.h"
@@ -44,15 +57,6 @@
#include "amiga/theme.h"
#include "amiga/utf8.h"
-#include "desktop/browser.h"
-#include "desktop/browser_history.h"
-#include "desktop/mouse.h"
-#include "desktop/searchweb.h"
-#include "desktop/textinput.h"
-
-#include "utils/log.h"
-#include "utils/messages.h"
-#include "utils/nsoption.h"
enum {
AMI_CTX_ID_NONE = 0,
diff --git a/amiga/download.c b/amiga/download.c
index faa71db..21c21ca 100644
--- a/amiga/download.c
+++ b/amiga/download.c
@@ -42,10 +42,12 @@
#include <reaction/reaction_macros.h>
#include "utils/errors.h"
+#include "utils/nsurl.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/utils.h"
#include "utils/nsoption.h"
+#include "utils/string.h"
#include "desktop/download.h"
#include "desktop/save_complete.h"
#include "desktop/browser.h"
diff --git a/amiga/dt_anim.c b/amiga/dt_anim.c
index d6f1f36..a3bfb1d 100644
--- a/amiga/dt_anim.c
+++ b/amiga/dt_anim.c
@@ -23,6 +23,7 @@
#ifdef WITH_AMIGA_DATATYPES
#include "amiga/os3support.h"
+#include <stdlib.h>
#include <proto/datatypes.h>
#include <proto/dos.h>
#include <proto/exec.h>
@@ -61,7 +62,7 @@ typedef struct amiga_dt_anim_content {
APTR ami_colormap_to_clut(struct ColorMap *cmap);
static nserror amiga_dt_anim_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c);
static bool amiga_dt_anim_convert(struct content *c);
@@ -135,7 +136,7 @@ nserror amiga_dt_anim_init(void)
}
nserror amiga_dt_anim_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c)
{
diff --git a/amiga/dt_picture.c b/amiga/dt_picture.c
index b3dbb34..aa2418d 100644
--- a/amiga/dt_picture.c
+++ b/amiga/dt_picture.c
@@ -24,6 +24,7 @@
#include "amiga/os3support.h"
#include <stdbool.h>
+#include <stdlib.h>
#include <proto/datatypes.h>
#include <proto/dos.h>
#include <proto/intuition.h>
@@ -43,7 +44,7 @@
static nserror amiga_dt_picture_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c);
static bool amiga_dt_picture_convert(struct content *c);
@@ -104,7 +105,7 @@ nserror amiga_dt_picture_init(void)
}
nserror amiga_dt_picture_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c)
{
diff --git a/amiga/dt_sound.c b/amiga/dt_sound.c
index 6c49f09..fe1b1fc 100644
--- a/amiga/dt_sound.c
+++ b/amiga/dt_sound.c
@@ -45,7 +45,7 @@ typedef struct amiga_dt_sound_content {
} amiga_dt_sound_content;
static nserror amiga_dt_sound_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c);
static bool amiga_dt_sound_convert(struct content *c);
@@ -115,7 +115,7 @@ nserror amiga_dt_sound_init(void)
}
nserror amiga_dt_sound_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c)
{
diff --git a/amiga/file.c b/amiga/file.c
index d26b4be..267ebae 100644
--- a/amiga/file.c
+++ b/amiga/file.c
@@ -22,9 +22,11 @@
#include <proto/icon.h>
#include <workbench/icon.h>
+#include "utils/utils.h"
#include "utils/nsoption.h"
#include "utils/file.h"
#include "utils/messages.h"
+#include "content/hlcache.h"
#include "content/content.h"
#include "content/fetch.h"
#include "desktop/browser.h"
diff --git a/amiga/font.c b/amiga/font.c
index 39cb386..1c9702a 100644
--- a/amiga/font.c
+++ b/amiga/font.c
@@ -25,7 +25,7 @@
#include "utils/log.h"
#include "utils/nsoption.h"
#include "desktop/browser.h"
-#include "desktop/font.h"
+#include "desktop/gui_layout.h"
#include "amiga/font.h"
#include "amiga/font_bullet.h"
@@ -119,7 +119,7 @@ void ami_font_fini(void)
}
/* Stub entry points */
-static bool nsfont_width(const plot_font_style_t *fstyle,
+static nserror ami_font_width(const plot_font_style_t *fstyle,
const char *string, size_t length,
int *width)
{
@@ -127,7 +127,7 @@ static bool nsfont_width(const plot_font_style_t *fstyle,
return ami_nsfont->width(fstyle, string, length, width);
}
-static bool nsfont_position_in_string(const plot_font_style_t *fstyle,
+static nserror ami_font_position(const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x)
{
@@ -135,7 +135,7 @@ static bool nsfont_position_in_string(const plot_font_style_t *fstyle,
return ami_nsfont->posn(fstyle, string, length, x, char_offset, actual_x);
}
-static bool nsfont_split(const plot_font_style_t *fstyle,
+static nserror ami_font_split(const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x)
{
@@ -143,9 +143,10 @@ static bool nsfont_split(const plot_font_style_t *fstyle,
return ami_nsfont->split(fstyle, string, length, x, char_offset, actual_x);
}
-const struct font_functions nsfont = {
- nsfont_width,
- nsfont_position_in_string,
- nsfont_split
+static struct gui_layout_table layout_table = {
+ .width = ami_font_width,
+ .position = ami_font_position,
+ .split = ami_font_split,
};
+struct gui_layout_table *ami_layout_table = &layout_table;
diff --git a/amiga/font.h b/amiga/font.h
index da23b59..cd52605 100755
--- a/amiga/font.h
+++ b/amiga/font.h
@@ -20,6 +20,7 @@
#define AMIGA_FONT_H
#include "desktop/plotters.h"
+#include "utils/errors.h"
#include <graphics/rastport.h>
#include <graphics/text.h>
@@ -37,15 +38,15 @@ void ami_font_close_disk_font(struct TextFont *tfont);
/* Font engine tables */
struct ami_font_functions {
- bool (*width)(const plot_font_style_t *fstyle,
+ nserror (*width)(const plot_font_style_t *fstyle,
const char *string, size_t length,
int *width);
- bool (*posn)(const plot_font_style_t *fstyle,
+ nserror (*posn)(const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x);
- bool (*split)(const plot_font_style_t *fstyle,
+ nserror (*split)(const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x);
@@ -55,5 +56,8 @@ struct ami_font_functions {
};
const struct ami_font_functions *ami_nsfont;
+
+struct gui_layout_table *ami_layout_table;
+
#endif
diff --git a/amiga/font_bullet.c b/amiga/font_bullet.c
index f634552..81d41dd 100644
--- a/amiga/font_bullet.c
+++ b/amiga/font_bullet.c
@@ -155,7 +155,7 @@ static inline uint32 amiga_nsfont_decode_surrogate(const uint16 *char1)
}
}
-static bool amiga_nsfont_width(const plot_font_style_t *fstyle,
+static nserror amiga_nsfont_width(const plot_font_style_t *fstyle,
const char *string, size_t length,
int *width)
{
@@ -163,7 +163,7 @@ static bool amiga_nsfont_width(const plot_font_style_t *fstyle,
if(*width <= 0) *width == length; // fudge
- return true;
+ return NSERROR_OK;
}
/**
@@ -178,7 +178,7 @@ static bool amiga_nsfont_width(const plot_font_style_t *fstyle,
* \return true on success, false on error and error reported
*/
-static bool amiga_nsfont_position_in_string(const plot_font_style_t *fstyle,
+static nserror amiga_nsfont_position_in_string(const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x)
{
@@ -191,9 +191,9 @@ static bool amiga_nsfont_position_in_string(const plot_font_style_t *fstyle,
ULONG emwidth = (ULONG)NSA_FONT_EMWIDTH(fstyle->size);
int32 tempx;
- if(utf8_to_enc(string,"UTF-16",length,(char **)&utf16) != NSERROR_OK) return false;
+ if(utf8_to_enc(string,"UTF-16",length,(char **)&utf16) != NSERROR_OK) return NSERROR_INVALID;
outf16 = utf16;
- if(!(ofont = ami_open_outline_font(fstyle, 0))) return false;
+ if(!(ofont = ami_open_outline_font(fstyle, 0))) return NSERROR_INVALID;
*char_offset = 0;
*actual_x = 0;
@@ -226,7 +226,7 @@ static bool amiga_nsfont_position_in_string(const plot_font_style_t *fstyle,
*char_offset = utf8_pos;
}
free(outf16);
- return true;
+ return NSERROR_OK;
}
}
@@ -234,7 +234,7 @@ static bool amiga_nsfont_position_in_string(const plot_font_style_t *fstyle,
*char_offset = length;
free(outf16);
- return true;
+ return NSERROR_OK;
}
@@ -261,7 +261,7 @@ static bool amiga_nsfont_position_in_string(const plot_font_style_t *fstyle,
* Returning char_offset == length means no split possible
*/
-static bool amiga_nsfont_split(const plot_font_style_t *fstyle,
+static nserror amiga_nsfont_split(const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x)
{
@@ -277,11 +277,11 @@ static bool amiga_nsfont_split(const plot_font_style_t *fstyle,
/* Get utf16 conversion of string for glyph measuring routines */
if (utf8_to_enc(string, "UTF-16", length, (char **)&utf16_str) !=
NSERROR_OK)
- return false;
+ return NSERROR_INVALID;
utf16 = utf16_str;
if (!(ofont = ami_open_outline_font(fstyle, 0)))
- return false;
+ return NSERROR_INVALID;
*char_offset = 0;
*actual_x = 0;
@@ -317,7 +317,7 @@ static bool amiga_nsfont_split(const plot_font_style_t *fstyle,
/* Reached available width, and a space was found;
* split there. */
free(utf16_str);
- return true;
+ return NSERROR_OK;
}
utf16 = utf16next;
@@ -331,7 +331,7 @@ static bool amiga_nsfont_split(const plot_font_style_t *fstyle,
*char_offset = length;
*actual_x = tx;
- return true;
+ return NSERROR_OK;
}
/**
diff --git a/amiga/font_cache.c b/amiga/font_cache.c
index e3f107d..ea28573 100644
--- a/amiga/font_cache.c
+++ b/amiga/font_cache.c
@@ -69,7 +69,7 @@ static void ami_font_cache_cleanup(struct SkipList *skiplist)
SubTime(&curtime, &node->lastused);
if(curtime.Seconds > 300)
{
- LOG("Freeing font %lx not used for %ld seconds", node->skip_node.sn_Key, curtime.Seconds);
+ LOG("Freeing font %p not used for %ld seconds", node->skip_node.sn_Key, curtime.Seconds);
ami_font_bullet_close(node);
RemoveSkipNode(skiplist, node->skip_node.sn_Key);
}
diff --git a/amiga/font_diskfont.c b/amiga/font_diskfont.c
index 6beae57..a64674b 100644
--- a/amiga/font_diskfont.c
+++ b/amiga/font_diskfont.c
@@ -18,6 +18,8 @@
#include "amiga/os3support.h"
+#include <stdlib.h>
+#include <string.h>
#include <proto/diskfont.h>
#include <proto/exec.h>
#include <proto/graphics.h>
@@ -28,7 +30,6 @@
#include "utils/log.h"
#include "utils/utf8.h"
#include "utils/nsoption.h"
-#include "desktop/font.h"
#include "amiga/font.h"
#include "amiga/font_diskfont.h"
@@ -110,21 +111,21 @@ static size_t ami_font_bm_convert_local_to_utf8_offset(const char *utf8string, s
}
-static bool amiga_bm_nsfont_width(const plot_font_style_t *fstyle,
+static nserror amiga_bm_nsfont_width(const plot_font_style_t *fstyle,
const char *string, size_t length,
int *width)
{
char *localtext = NULL;
- if((glob == NULL) || (glob->rp == NULL)) return false;
+ if((glob == NULL) || (glob->rp == NULL)) return NSERROR_INVALID;
*width = length;
struct TextFont *bmfont = ami_font_bm_open(glob->rp, fstyle);
- if(bmfont == NULL) return false;
+ if(bmfont == NULL) return NSERROR_INVALID;
if(utf8_to_local_encoding(string, length, &localtext) != NSERROR_OK) {
ami_font_bm_close(bmfont);
- return false;
+ return NSERROR_INVALID;
}
*width = TextLength(glob->rp, localtext, (UWORD)strlen(localtext));
@@ -132,7 +133,7 @@ static bool amiga_bm_nsfont_width(const plot_font_style_t *fstyle,
ami_font_bm_close(bmfont);
- return true;
+ return NSERROR_OK;
}
/**
@@ -147,7 +148,7 @@ static bool amiga_bm_nsfont_width(const plot_font_style_t *fstyle,
* \return true on success, false on error and error reported
*/
-static bool amiga_bm_nsfont_position_in_string(const plot_font_style_t *fstyle,
+static nserror amiga_bm_nsfont_position_in_string(const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x)
{
@@ -156,14 +157,14 @@ static bool amiga_bm_nsfont_position_in_string(const plot_font_style_t *fstyle,
char *localtext = NULL;
UWORD co = 0;
- if((glob == NULL) || (glob->rp == NULL)) return false;
+ if((glob == NULL) || (glob->rp == NULL)) return NSERROR_INVALID;
bmfont = ami_font_bm_open(glob->rp, fstyle);
- if(bmfont == NULL) return false;
+ if(bmfont == NULL) return NSERROR_INVALID;
if(utf8_to_local_encoding(string, length, &localtext) != NSERROR_OK) {
ami_font_bm_close(bmfont);
- return false;
+ return NSERROR_INVALID;
}
co = TextFit(glob->rp, localtext, (UWORD)strlen(localtext),
@@ -174,7 +175,7 @@ static bool amiga_bm_nsfont_position_in_string(const plot_font_style_t *fstyle,
free(localtext);
ami_font_bm_close(bmfont);
- return true;
+ return NSERROR_OK;
}
@@ -201,7 +202,7 @@ static bool amiga_bm_nsfont_position_in_string(const plot_font_style_t *fstyle,
* Returning char_offset == length means no split possible
*/
-static bool amiga_bm_nsfont_split(const plot_font_style_t *fstyle,
+static nserror amiga_bm_nsfont_split(const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x)
{
@@ -210,14 +211,14 @@ static bool amiga_bm_nsfont_split(const plot_font_style_t *fstyle,
char *charp;
char *localtext;
- if((glob == NULL) || (glob->rp == NULL)) return false;
+ if((glob == NULL) || (glob->rp == NULL)) return NSERROR_INVALID;
struct TextFont *bmfont = ami_font_bm_open(glob->rp, fstyle);
- if(bmfont == NULL) return false;
+ if(bmfont == NULL) return NSERROR_INVALID;
if(utf8_to_local_encoding(string, length, &localtext) != NSERROR_OK) {
ami_font_bm_close(bmfont);
- return false;
+ return NSERROR_INVALID;
}
offset = TextFit(glob->rp, localtext, (UWORD)strlen(localtext),
@@ -252,7 +253,7 @@ static bool amiga_bm_nsfont_split(const plot_font_style_t *fstyle,
free(localtext);
ami_font_bm_close(bmfont);
- return true;
+ return NSERROR_OK;
}
static ULONG amiga_bm_nsfont_text(struct RastPort *rp, const char *string, ULONG length,
diff --git a/amiga/gui.c b/amiga/gui.c
index ec76735..9c89084 100644
--- a/amiga/gui.c
+++ b/amiga/gui.c
@@ -95,6 +95,7 @@
#include "utils/utils.h"
#include "utils/nsurl.h"
#include "utils/file.h"
+#include "content/hlcache.h"
#include "content/backing_store.h"
#include "content/fetchers.h"
#include "content/fetchers/resource.h"
@@ -974,7 +975,7 @@ static void gui_init2(int argc, char** argv)
nsurl_unref(url);
}
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ amiga_warn_user(messages_get_errorcode(error), 0);
}
free(temp_homepage_url);
}
@@ -1033,7 +1034,7 @@ static void gui_init2(int argc, char** argv)
}
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ amiga_warn_user(messages_get_errorcode(error), 0);
}
free(temp_homepage_url);
temp_homepage_url = NULL;
@@ -1113,7 +1114,7 @@ static void gui_init2(int argc, char** argv)
nsurl_unref(url);
}
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ amiga_warn_user(messages_get_errorcode(error), 0);
}
}
}
@@ -1423,7 +1424,7 @@ bool ami_mouse_to_ns_coords(struct gui_window_2 *gwin, int *x, int *y,
ami_gui_free_space_box(bbox);
} else {
- warn_user("NoMemory", "");
+ amiga_warn_user("NoMemory", "");
return false;
}
@@ -1447,7 +1448,7 @@ static void ami_gui_scroll_internal(struct gui_window_2 *gwin, int xs, int ys)
&gwin->gw->scrolly);
if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- warn_user("NoMemory", "");
+ amiga_warn_user("NoMemory", "");
return;
}
@@ -1514,7 +1515,7 @@ static struct IBox *ami_ns_rect_to_ibox(struct gui_window_2 *gwin, const struct
if(ibox == NULL) return NULL;
if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- warn_user("NoMemory", "");
+ amiga_warn_user("NoMemory", "");
return NULL;
}
@@ -1589,7 +1590,7 @@ static void gui_window_get_dimensions(struct gui_window *g, int *width, int *hei
if(!g) return;
if(ami_gui_get_space_box((Object *)g->shared->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- warn_user("NoMemory", "");
+ amiga_warn_user("NoMemory", "");
return;
}
@@ -1781,7 +1782,7 @@ static void gui_window_set_icon(struct gui_window *g, hlcache_handle *icon)
}
if(ami_gui_get_space_box((Object *)g->shared->objects[GID_ICON], &bbox) != NSERROR_OK) {
- warn_user("NoMemory", "");
+ amiga_warn_user("NoMemory", "");
return;
}
@@ -1970,7 +1971,7 @@ static void ami_handle_msg(void)
drag_y_move = 0;
if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- warn_user("NoMemory", "");
+ amiga_warn_user("NoMemory", "");
break;
}
@@ -2033,7 +2034,7 @@ static void ami_handle_msg(void)
case WMHI_MOUSEBUTTONS:
if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- warn_user("NoMemory", "");
+ amiga_warn_user("NoMemory", "");
return;
}
@@ -2229,7 +2230,7 @@ static void ami_handle_msg(void)
nsurl_unref(url);
}
if (ret != NSERROR_OK) {
- warn_user(messages_get_errorcode(ret), 0);
+ amiga_warn_user(messages_get_errorcode(ret), 0);
}
}
break;
@@ -2268,7 +2269,7 @@ static void ami_handle_msg(void)
nsurl_unref(url);
}
if (ret != NSERROR_OK) {
- warn_user(messages_get_errorcode(ret), 0);
+ amiga_warn_user(messages_get_errorcode(ret), 0);
}
}
@@ -2277,7 +2278,7 @@ static void ami_handle_msg(void)
case GID_HOME:
{
if (nsurl_create(nsoption_charp(homepage_url), &url) != NSERROR_OK) {
- warn_user("NoMemory", 0);
+ amiga_warn_user("NoMemory", 0);
} else {
browser_window_navigate(gwin->gw->bw,
url,
@@ -2598,7 +2599,7 @@ static void ami_handle_appmsg(void)
nsurl *url;
if (netsurf_path_to_nsurl(filename, &url) != NSERROR_OK) {
- warn_user("NoMemory", 0);
+ amiga_warn_user("NoMemory", 0);
}
else
{
@@ -2633,7 +2634,7 @@ static void ami_handle_appmsg(void)
nsurl *url;
if (netsurf_path_to_nsurl(filename, &url) != NSERROR_OK) {
- warn_user("NoMemory", 0);
+ amiga_warn_user("NoMemory", 0);
}
else
{
@@ -2700,7 +2701,7 @@ static void ami_handle_applib(void)
nsurl_unref(url);
}
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ amiga_warn_user(messages_get_errorcode(error), 0);
}
}
break;
@@ -2720,7 +2721,7 @@ static void ami_handle_applib(void)
nsurl_unref(url);
}
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ amiga_warn_user(messages_get_errorcode(error), 0);
}
}
break;
@@ -2869,7 +2870,7 @@ void ami_switch_tab(struct gui_window_2 *gwin, bool redraw)
cur_gw = gwin->gw;
if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- warn_user("NoMemory", "");
+ amiga_warn_user("NoMemory", "");
return;
}
@@ -3487,7 +3488,7 @@ nserror ami_gui_new_blank_tab(struct gui_window_2 *gwin)
nsurl_unref(url);
}
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ amiga_warn_user(messages_get_errorcode(error), 0);
return error;
}
@@ -3617,7 +3618,7 @@ static void ami_do_redraw_limits(struct gui_window *g, struct browser_window *bw
if(g != g->shared->gw) return;
if(ami_gui_get_space_box((Object *)g->shared->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- warn_user("NoMemory", "");
+ amiga_warn_user("NoMemory", "");
return;
}
@@ -3643,7 +3644,7 @@ static void ami_refresh_window(struct gui_window_2 *gwin)
ami_set_pointer(gwin, GUI_POINTER_WAIT, false);
if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- warn_user("NoMemory", "");
+ amiga_warn_user("NoMemory", "");
return;
}
@@ -3805,7 +3806,7 @@ gui_window_create(struct browser_window *bw,
if(!g)
{
- warn_user("NoMemory","");
+ amiga_warn_user("NoMemory","");
return NULL;
}
@@ -3878,7 +3879,7 @@ gui_window_create(struct browser_window *bw,
if(!g->shared)
{
- warn_user("NoMemory","");
+ amiga_warn_user("NoMemory","");
return NULL;
}
@@ -3920,6 +3921,7 @@ gui_window_create(struct browser_window *bw,
(strcmp(nsoption_charp(pubscreen_name), "Workbench") == 0))
iconifygadget = TRUE;
+ LOG("Creating menu");
struct Menu *menu = ami_menu_create(g->shared);
NewList(&g->shared->tab_list);
@@ -4327,7 +4329,7 @@ gui_window_create(struct browser_window *bw,
if(!g->shared->win)
{
- warn_user("NoMemory","");
+ amiga_warn_user("NoMemory","");
FreeVec(g->shared);
FreeVec(g);
return NULL;
@@ -4757,7 +4759,7 @@ static void amiga_window_reformat(struct gui_window *gw)
if (gw != NULL) {
if(ami_gui_get_space_box((Object *)gw->shared->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- warn_user("NoMemory", "");
+ amiga_warn_user("NoMemory", "");
return;
}
browser_window_reformat(gw->bw, false, bbox->Width, bbox->Height);
@@ -4782,7 +4784,7 @@ static void ami_do_redraw(struct gui_window_2 *gwin)
gwin->gw->scrolly = vcurrent;
if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- warn_user("NoMemory", "");
+ amiga_warn_user("NoMemory", "");
return;
}
@@ -4929,7 +4931,7 @@ static void gui_window_set_scroll(struct gui_window *g, int sx, int sy)
if(!g->bw || browser_window_has_content(g->bw) == false) return;
if(ami_gui_get_space_box((Object *)g->shared->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- warn_user("NoMemory", "");
+ amiga_warn_user("NoMemory", "");
return;
}
@@ -4984,7 +4986,7 @@ static void gui_window_update_extent(struct gui_window *g)
if(g == g->shared->gw) {
int width, height;
if(ami_gui_get_space_box((Object *)g->shared->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- warn_user("NoMemory", "");
+ amiga_warn_user("NoMemory", "");
return;
}
@@ -5169,7 +5171,7 @@ static void gui_window_place_caret(struct gui_window *g, int x, int y, int heigh
SetAPen(g->shared->win->RPort,3);
if(ami_gui_get_space_box((Object *)g->shared->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- warn_user("NoMemory", "");
+ amiga_warn_user("NoMemory", "");
return;
}
@@ -5264,7 +5266,7 @@ bool ami_text_box_at_point(struct gui_window_2 *gwin, ULONG *x, ULONG *y)
struct browser_window_features data;
if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- warn_user("NoMemory", "");
+ amiga_warn_user("NoMemory", "");
return false;
}
@@ -5466,8 +5468,9 @@ static struct gui_search_web_table amiga_search_web_table = {
.provider_update = gui_search_web_provider_update,
};
-static struct gui_browser_table amiga_browser_table = {
+static struct gui_misc_table amiga_misc_table = {
.schedule = ami_schedule,
+ .warning = amiga_warn_user,
.quit = gui_quit,
.launch_url = gui_launch_url,
@@ -5490,7 +5493,7 @@ int main(int argc, char** argv)
char *nargv = NULL;
struct netsurf_table amiga_table = {
- .browser = &amiga_browser_table,
+ .misc = &amiga_misc_table,
.window = &amiga_window_table,
.clipboard = amiga_clipboard_table,
.download = amiga_download_table,
@@ -5501,6 +5504,7 @@ int main(int argc, char** argv)
.search_web = &amiga_search_web_table,
.llcache = filesystem_llcache_table,
.bitmap = amiga_bitmap_table,
+ .layout = ami_layout_table,
};
#ifdef __amigaos4__
diff --git a/amiga/gui.h b/amiga/gui.h
index 172a858..d301ac5 100644
--- a/amiga/gui.h
+++ b/amiga/gui.h
@@ -18,16 +18,20 @@
#ifndef AMIGA_GUI_H
#define AMIGA_GUI_H
+
#include <stdbool.h>
#include <graphics/rastport.h>
#include <intuition/classusr.h>
#include <dos/dos.h>
#include <devices/inputevent.h>
+
+#include "desktop/gui_window.h"
+#include "desktop/mouse.h"
+
#include "amiga/menu.h"
#include "amiga/object.h"
#include "amiga/os3support.h"
#include "amiga/plotters.h"
-#include "desktop/gui_window.h"
#ifdef __amigaos4__
#define HOOKF(ret,func,type,ptr,msgtype) static ret func(struct Hook *hook, type ptr, msgtype msg)
@@ -158,7 +162,7 @@ struct gui_window
int scrolly;
struct history_window *hw;
struct List dllist;
- hlcache_handle *favicon;
+ struct hlcache_handle *favicon;
bool throbbing;
char *tabtitle;
APTR deferred_rects_pool;
@@ -183,7 +187,7 @@ void ami_gui_tabs_toggle_all(void);
bool ami_locate_resource(char *fullpath, const char *file);
void ami_gui_update_hotlist_button(struct gui_window_2 *gwin);
nserror ami_gui_new_blank_tab(struct gui_window_2 *gwin);
-char *ami_gui_get_cache_favicon_name(nsurl *url, bool only_if_avail);
+char *ami_gui_get_cache_favicon_name(struct nsurl *url, bool only_if_avail);
int ami_gui_count_windows(int window, int *tabs);
void ami_gui_set_scale(struct gui_window *gw, float scale);
diff --git a/amiga/gui_options.c b/amiga/gui_options.c
index 3be0cd5..221b0da 100755
--- a/amiga/gui_options.c
+++ b/amiga/gui_options.c
@@ -18,6 +18,7 @@
#include <stdbool.h>
#include <string.h>
+#include <stdlib.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/utility.h>
@@ -57,6 +58,7 @@
#include <reaction/reaction.h>
#include <reaction/reaction_macros.h>
+#include "utils/nsurl.h"
#include "utils/messages.h"
#include "utils/nsoption.h"
#include "desktop/browser.h"
@@ -503,7 +505,7 @@ void ami_gui_opts_open(void)
BOOL proxyhostdisabled = TRUE, proxyauthdisabled = TRUE, proxybypassdisabled = FALSE;
BOOL disableanims, animspeeddisabled = FALSE, acceptlangdisabled = FALSE;
BOOL scaleselected = nsoption_bool(scale_quality), scaledisabled = FALSE;
- BOOL ditherdisable = TRUE, nativebm_disable = FALSE;
+ BOOL ditherdisable = TRUE;
BOOL download_notify_disabled = FALSE, tab_always_show_disabled = FALSE;
BOOL ptr_disable = FALSE;
char animspeed[10];
@@ -552,7 +554,6 @@ void ami_gui_opts_open(void)
if(ami_plot_screen_is_palettemapped() == true) {
ditherdisable = FALSE;
- nativebm_disable = TRUE;
}
if(nsoption_bool(http_proxy) == true)
@@ -1020,7 +1021,6 @@ void ami_gui_opts_open(void)
LAYOUT_AddChild, gow->objects[GID_OPTS_NATIVEBM] = ChooserObj,
GA_ID, GID_OPTS_NATIVEBM,
GA_RelVerify, TRUE,
- GA_Disabled, nativebm_disable,
CHOOSER_PopUp, TRUE,
#ifdef __amigaos4__
CHOOSER_LabelArray, nativebmopts,
diff --git a/amiga/icon.c b/amiga/icon.c
index 1370c3c..e75bf82 100644
--- a/amiga/icon.c
+++ b/amiga/icon.c
@@ -65,7 +65,7 @@ typedef struct amiga_icon_content {
} amiga_icon_content;
static nserror amiga_icon_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c);
static bool amiga_icon_convert(struct content *c);
@@ -103,7 +103,7 @@ CONTENT_FACTORY_REGISTER_TYPES(amiga_icon, amiga_icon_types,
amiga_icon_content_handler)
nserror amiga_icon_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c)
{
diff --git a/amiga/libs.c b/amiga/libs.c
index 7c130a8..2303d35 100644
--- a/amiga/libs.c
+++ b/amiga/libs.c
@@ -169,6 +169,8 @@ AMINS_LIB_STRUCT(Locale);
AMINS_LIB_STRUCT(P96);
AMINS_LIB_STRUCT(Workbench);
+AMINS_LIB_STRUCT(GuiGFX);
+
AMINS_CLASS_STRUCT(ARexx);
AMINS_CLASS_STRUCT(Bevel);
AMINS_CLASS_STRUCT(BitMap);
@@ -224,14 +226,16 @@ bool ami_libs_open(void)
if(GfxBase->LibNode.lib_Version < 54)
AMINS_LIB_OPEN("Picasso96API.library", 0, P96, "main", 1, false)
+ /* Non-OS provided libraries */
+ AMINS_LIB_OPEN("guigfx.library", 9, GuiGFX, "main", 1, true)
+
/* NB: timer.device is opened in schedule.c (ultimately by the scheduler process).
* The library base and interface are obtained there, rather than here, due to
* the additional complexities of opening devices, which aren't important here
* (as we only need the library interface), but are important for the scheduler
* (as it also uses the device interface). We trust that the scheduler has
- * initialised before any other code requires the timer's library interface
- * (this is ensured by waiting for the scheduler to start up) and that it is
- * OK to use a child process' timer interface, to avoid opening it twice.
+ * initialised before any other code requires the timer's library interface,
+ * to avoid opening it twice.
*/
/* BOOPSI classes.
@@ -298,6 +302,8 @@ void ami_libs_close(void)
AMINS_CLASS_CLOSE(Window)
/* Libraries */
+ AMINS_LIB_CLOSE(GuiGFX)
+
AMINS_LIB_CLOSE(Asl)
AMINS_LIB_CLOSE(DataTypes)
AMINS_LIB_CLOSE(Diskfont)
diff --git a/amiga/login.c b/amiga/login.c
index 4cf9ba8..a4c0d62 100755
--- a/amiga/login.c
+++ b/amiga/login.c
@@ -20,6 +20,7 @@
#include <assert.h>
#include <stdlib.h>
+#include <string.h>
#include <proto/exec.h>
#include <proto/intuition.h>
diff --git a/amiga/menu.c b/amiga/menu.c
index f851e44..e2dc414 100644
--- a/amiga/menu.c
+++ b/amiga/menu.c
@@ -19,6 +19,7 @@
#include "amiga/os3support.h"
#include <string.h>
+#include <stdlib.h>
#include <proto/dos.h>
#include <proto/asl.h>
@@ -44,7 +45,9 @@
#include "utils/nsoption.h"
#include "utils/messages.h"
#include "utils/log.h"
-
+#include "utils/utils.h"
+#include "utils/nsurl.h"
+#include "content/hlcache.h"
#include "desktop/hotlist.h"
#include "desktop/browser.h"
#include "desktop/mouse.h"
diff --git a/amiga/menu.h b/amiga/menu.h
index cff42dd..3bec113 100755
--- a/amiga/menu.h
+++ b/amiga/menu.h
@@ -18,18 +18,20 @@
#ifndef AMIGA_MENU_H
#define AMIGA_MENU_H
+
#include <exec/types.h>
#include <intuition/intuition.h>
#include <libraries/gadtools.h>
-#include "content/hlcache.h"
-/* Maximum number of hotlist items (somewhat arbitrary value) */
+struct hlcache_handle;
+
+/** Maximum number of hotlist items (somewhat arbitrary value) */
#define AMI_HOTLIST_ITEMS 60
-/* Maximum number of ARexx menu items (somewhat arbitrary value) */
+/** Maximum number of ARexx menu items (somewhat arbitrary value) */
#define AMI_MENU_AREXX_ITEMS 20
-/* enum menu structure, has to be here as we need it below. */
+/** enum menu structure, has to be here as we need it below. */
enum {
/* Project menu */
M_PROJECT = 0,
@@ -127,7 +129,7 @@ enum {
#define AMI_MENU_BACKIMG FULLMENUNUM(2,8,1)
#define AMI_MENU_JS FULLMENUNUM(2,9,0)
-/* A special value for ami_menu_window_close */
+/** A special value for ami_menu_window_close */
#define AMI_MENU_WINDOW_CLOSE_ALL (void *)1
struct gui_window;
@@ -140,7 +142,7 @@ void ami_free_menulabs(struct gui_window_2 *gwin);
struct Menu *ami_menu_create(struct gui_window_2 *gwin);
void ami_menu_refresh(struct gui_window_2 *gwin);
void ami_menu_update_checked(struct gui_window_2 *gwin);
-void ami_menu_update_disabled(struct gui_window *g, hlcache_handle *c);
+void ami_menu_update_disabled(struct gui_window *g, struct hlcache_handle *c);
void ami_menu_free_glyphs(void);
void ami_menu_free(struct gui_window_2 *gwin);
diff --git a/amiga/misc.c b/amiga/misc.c
index aa9d119..8618fd8 100755
--- a/amiga/misc.c
+++ b/amiga/misc.c
@@ -16,6 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <stdlib.h>
+#include <string.h>
#include <sys/stat.h>
#include <proto/dos.h>
@@ -26,10 +28,12 @@
#include <proto/intuition.h> // for EasyRequest
#endif
+#include "utils/utils.h"
#include "utils/corestrings.h"
#include "utils/log.h"
#include "utils/file.h"
#include "utils/messages.h"
+#include "utils/nsurl.h"
#include "utils/url.h"
#include "desktop/gui_window.h"
@@ -122,7 +126,8 @@ void ami_misc_fatal_error(const char *message)
ami_misc_req(message, TDRIMAGE_ERROR);
}
-void warn_user(const char *warning, const char *detail)
+/* exported interface documented in amiga/misc.h */
+nserror amiga_warn_user(const char *warning, const char *detail)
{
char *utf8warning = ami_utf8_easy(messages_get(warning));
STRPTR bodytext = ASPrintf("\33b%s\33n\n%s",
@@ -132,6 +137,8 @@ void warn_user(const char *warning, const char *detail)
if(bodytext) FreeVec(bodytext);
if(utf8warning) free(utf8warning);
+
+ return NSERROR_OK;
}
int32 ami_warn_user_multi(const char *body, const char *opt1, const char *opt2, struct Window *win)
diff --git a/amiga/misc.h b/amiga/misc.h
index 2544c77..e8f58fa 100644
--- a/amiga/misc.h
+++ b/amiga/misc.h
@@ -18,11 +18,24 @@
#ifndef AMIGA_MISC_H
#define AMIGA_MISC_H
+
#include <exec/types.h>
+#include "utils/errors.h"
+
extern struct gui_file_table *amiga_file_table;
struct Window;
+/**
+ * Warn the user of an event.
+ *
+ * \param[in] message A warning looked up in the message translation table
+ * \param[in] detail Additional text to be displayed or NULL.
+ * \return NSERROR_OK on success or error code if there was a
+ * faliure displaying the message to the user.
+ */
+nserror amiga_warn_user(const char *warning, const char *detail);
+
void *ami_misc_allocvec_clear(int size, UBYTE value);
/* Itempool cross-compatibility */
diff --git a/amiga/pkg/netsurf.readme b/amiga/pkg/netsurf.readme
index 61b8899..e686548 100755
--- a/amiga/pkg/netsurf.readme
+++ b/amiga/pkg/netsurf.readme
@@ -2,10 +2,10 @@ Short: Fast CSS capable web browser
Uploader: chris(a)unsatisfactorysoftware.co.uk (Chris Young)
Author: NetSurf contributors (OS4 port by Chris Young)
Type: comm/www
-Version: 3.5
+Version: 3.6
Architecture: ppc-amigaos >= 4.0.0
-This is NetSurf 3.5 for AmigaOS 4 (native frontend).
+This is NetSurf 3.6 for AmigaOS 4 (native frontend).
For the latest version, visit http://www.netsurf-browser.org
*******************************************
diff --git a/amiga/pkg/netsurf_os3.readme b/amiga/pkg/netsurf_os3.readme
index 62cf8f2..de8734e 100644
--- a/amiga/pkg/netsurf_os3.readme
+++ b/amiga/pkg/netsurf_os3.readme
@@ -2,10 +2,10 @@ Short: Fast CSS capable web browser
Uploader: chris(a)unsatisfactorysoftware.co.uk (Chris Young)
Author: NetSurf contributors (OS4 port by Chris Young)
Type: comm/www
-Version: 3.5 BETA
+Version: 3.6 BETA
Architecture: m68k-amigaos >= 3.5.0
-This is NetSurf 3.5 BETA for AmigaOS 3.
+This is NetSurf 3.6 BETA for AmigaOS 3.
It is built off of the OS4 (Reaction) frontend.
Requirements are AmigaOS 3.5 or 3.9, 32MB RAM.
diff --git a/amiga/plotters.c b/amiga/plotters.c
index 8d59f81..9c3c3c7 100644
--- a/amiga/plotters.c
+++ b/amiga/plotters.c
@@ -49,6 +49,8 @@
#include "amiga/rtg.h"
#include "amiga/utf8.h"
+//#define AMI_PLOTTER_DEBUG 1
+
HOOKF(void, ami_bitmap_tile_hook, struct RastPort *, rp, struct BackFillMessage *);
struct bfbitmap {
@@ -153,6 +155,8 @@ void ami_init_layers(struct gui_globals *gg, ULONG width, ULONG height, bool for
/* Screen depth is reported as 24 even when it's actually 32-bit.
* We get freezes and other problems on OS4 if we befriend at any
* other depths, hence this check.
+ * \todo use friend BitMaps but avoid CompositeTags() at non-32-bit
+ * as that seems to be the cause of the problems.
*/
if((depth >= 24) && (force32bit == false)) friend = scrn->RastPort.BitMap;
#endif
@@ -190,6 +194,8 @@ void ami_init_layers(struct gui_globals *gg, ULONG width, ULONG height, bool for
gg->apen = 0x00000000;
gg->open = 0x00000000;
+ gg->apen_num = -1;
+ gg->open_num = -1;
init_layers_count++;
LOG("Layer initialised (total: %d)", init_layers_count);
@@ -275,6 +281,8 @@ void ami_plot_release_pens(struct MinList *shared_pens)
glob->apen = 0x00000000;
glob->open = 0x00000000;
+ glob->apen_num = -1;
+ glob->open_num = -1;
}
static void ami_plot_setapen(struct RastPort *rp, ULONG colr)
@@ -290,7 +298,7 @@ static void ami_plot_setapen(struct RastPort *rp, ULONG colr)
#endif
{
LONG pen = ami_plot_obtain_pen(glob->shared_pens, colr);
- if(pen != -1) SetAPen(rp, pen);
+ if((pen != -1) && (pen != glob->apen_num)) SetAPen(rp, pen);
}
glob->apen = colr;
@@ -309,7 +317,7 @@ static void ami_plot_setopen(struct RastPort *rp, ULONG colr)
#endif
{
LONG pen = ami_plot_obtain_pen(glob->shared_pens, colr);
- if(pen != -1) SetOPen(rp, pen);
+ if((pen != -1) && (pen != glob->open_num)) SetOPen(rp, pen);
}
glob->open = colr;
@@ -609,8 +617,7 @@ static bool ami_bitmap(int x, int y, int width, int height, struct bitmap *bitma
#endif
}
- if((ami_bitmap_has_dto(bitmap) == false) && (ami_bitmap_is_nativebm(bitmap, tbm) == false)) {
- /**\todo is this logic logical? */
+ if((ami_bitmap_is_nativebm(bitmap, tbm) == false)) {
ami_rtg_freebitmap(tbm);
}
@@ -715,7 +722,7 @@ static bool ami_bitmap_tile(int x, int y, int width, int height,
#endif
FreeVec(bfh);
- if((ami_bitmap_has_dto(bitmap) == false) && (ami_bitmap_is_nativebm(bitmap, tbm) == false)) {
+ if((ami_bitmap_is_nativebm(bitmap, tbm) == false)) {
/**\todo is this logic logical? */
ami_rtg_freebitmap(tbm);
}
diff --git a/amiga/plotters.h b/amiga/plotters.h
index c674474..7baa21f 100644
--- a/amiga/plotters.h
+++ b/amiga/plotters.h
@@ -36,6 +36,8 @@ struct gui_globals
bool palette_mapped;
ULONG apen;
ULONG open;
+ LONG apen_num;
+ LONG open_num;
int width; /* size of bm and */
int height; /* associated memory */
};
diff --git a/amiga/plugin_hack.c b/amiga/plugin_hack.c
index ad4bfaa..21f4da1 100644
--- a/amiga/plugin_hack.c
+++ b/amiga/plugin_hack.c
@@ -22,6 +22,8 @@
#include "amiga/os3support.h"
+#include <stdlib.h>
+
#include "amiga/filetype.h"
#include "amiga/plugin_hack.h"
#include "content/content_protected.h"
@@ -40,7 +42,7 @@ typedef struct amiga_plugin_hack_content {
} amiga_plugin_hack_content;
static nserror amiga_plugin_hack_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c);
static bool amiga_plugin_hack_convert(struct content *c);
@@ -95,7 +97,7 @@ nserror amiga_plugin_hack_init(void)
}
nserror amiga_plugin_hack_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c)
{
diff --git a/amiga/print.c b/amiga/print.c
index 84cca8f..908b026 100644
--- a/amiga/print.c
+++ b/amiga/print.c
@@ -18,6 +18,7 @@
#include "amiga/os3support.h"
+#include <string.h>
#include <proto/utility.h>
#include <proto/iffparse.h>
#include <proto/dos.h>
@@ -49,11 +50,13 @@
#include "utils/messages.h"
#include "utils/utils.h"
#include "desktop/printer.h"
-#include "desktop/font.h"
+#include "desktop/gui_layout.h"
#include "desktop/mouse.h"
#include "desktop/gui_window.h"
+#include "content/hlcache.h"
#include "amiga/plotters.h"
+#include "amiga/font.h"
#include "amiga/gui.h"
#include "amiga/libs.h"
#include "amiga/misc.h"
@@ -412,7 +415,7 @@ void ami_print(struct hlcache_handle *c, int copies)
ami_print_info.PD = (struct PrinterData *)ami_print_info.PReq->io_Device;
ami_print_info.PED = &ami_print_info.PD->pd_SegmentData->ps_PED;
- ami_print_info.ps = print_make_settings(PRINT_DEFAULT, nsurl_access(hlcache_handle_get_url(c)), &nsfont);
+ ami_print_info.ps = print_make_settings(PRINT_DEFAULT, nsurl_access(hlcache_handle_get_url(c)), ami_layout_table);
ami_print_info.ps->page_width = ami_print_info.PED->ped_MaxXDots;
ami_print_info.ps->page_height = ami_print_info.PED->ped_MaxYDots;
ami_print_info.ps->scale = scale;
diff --git a/amiga/theme.c b/amiga/theme.c
index 97b6bab..399a116 100644
--- a/amiga/theme.c
+++ b/amiga/theme.c
@@ -18,6 +18,7 @@
#include "amiga/os3support.h"
+#include <stdlib.h>
#include <string.h>
#include <proto/clicktab.h>
diff --git a/amiga/tree.c b/amiga/tree.c
index fd0a5a6..48b1521 100644
--- a/amiga/tree.c
+++ b/amiga/tree.c
@@ -18,6 +18,7 @@
#include "amiga/os3support.h"
+#include <stdlib.h>
#include <proto/window.h>
#include <proto/layout.h>
#include <proto/space.h>
diff --git a/amiga/version.c b/amiga/version.c
index 3b6b86b..bc31d0c 100644
--- a/amiga/version.c
+++ b/amiga/version.c
@@ -25,14 +25,15 @@
* they are higher than CI builds, and make this (slightly) less confusing.
*/
#define NETSURF_VERSION_MAJOR "3"
+#define NETSURF_VERSION_MINOR_EXTERNAL "6"
#if defined(CI_BUILD)
#define NETSURF_VERSION_MINOR CI_BUILD
#else
-#define NETSURF_VERSION_MINOR "6000" "5"
+#define NETSURF_VERSION_MINOR "6000" NETSURF_VERSION_MINOR_EXTERNAL
#endif
static const __attribute__((used)) char *verstag = "\0$VER: NetSurf " NETSURF_VERSION_MAJOR "." NETSURF_VERSION_MINOR " (" WT_COMPILEDATE ")\0";
const char * const verdate = WT_COMPILEDATE;
-const char * const verarexx = NETSURF_VERSION_MAJOR "." NETSURF_VERSION_MINOR;
+const char * const verarexx = NETSURF_VERSION_MAJOR "." NETSURF_VERSION_MINOR_EXTERNAL;
const char * const wt_revid = WT_REVID;
diff --git a/atari/about.c b/atari/about.c
index 46772a9..c7db7b2 100644
--- a/atari/about.c
+++ b/atari/about.c
@@ -33,6 +33,7 @@
#include "curl/curlver.h"
#include "cflib.h"
+#include "atari/gui.h"
#include "atari/misc.h"
#include "atari/plot/plot.h"
#include "atari/gemtk/gemtk.h"
diff --git a/atari/certview.c b/atari/certview.c
index d649c02..7f0a295 100644
--- a/atari/certview.c
+++ b/atari/certview.c
@@ -58,12 +58,12 @@ static void atari_sslcert_viewer_draw(struct core_window *cw, int x,
static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8]);
static struct atari_treeview_callbacks atari_sslcert_viewer_treeview_callbacks = {
- .init_phase2 = atari_sslcert_viewer_init_phase2,
- .finish = atari_sslcert_viewer_finish,
- .draw = atari_sslcert_viewer_draw,
- .keypress = atari_sslcert_viewer_keypress,
- .mouse_action = atari_sslcert_viewer_mouse_action,
- .gemtk_user_func = handle_event
+ .init_phase2 = atari_sslcert_viewer_init_phase2,
+ .finish = atari_sslcert_viewer_finish,
+ .draw = atari_sslcert_viewer_draw,
+ .keypress = atari_sslcert_viewer_keypress,
+ .mouse_action = atari_sslcert_viewer_mouse_action,
+ .gemtk_user_func = handle_event
};
/* static functions */
@@ -84,7 +84,7 @@ static nserror atari_sslcert_viewer_init_phase2(struct core_window *cw,
assert(ssl_d);
- LOG("");
+ LOG("cw %p", cw);
return(sslcert_viewer_init(cb_t, cw, ssl_d));
}
@@ -100,7 +100,7 @@ static void atari_sslcert_viewer_finish(struct core_window *cw)
/* This will also free the session data: */
sslcert_viewer_fini(cvwin->ssl_session_data);
- LOG("");
+ LOG("cw %p", cw);
}
static void atari_sslcert_viewer_draw(struct core_window *cw, int x,
@@ -126,7 +126,7 @@ static void atari_sslcert_viewer_keypress(struct core_window *cw, uint32_t ucs4)
cvwin = (struct atari_sslcert_viewer_s *)atari_treeview_get_user_data(cw);
- LOG("ucs4: %lu\n", ucs4);
+ LOG("ucs4: %"PRIu32, ucs4);
sslcert_viewer_keypress(cvwin->ssl_session_data, ucs4);
}
@@ -153,7 +153,7 @@ static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8])
short retval = 0;
OBJECT *toolbar;
- LOG("");
+ LOG("win %p", win);
if(ev_out->emo_events & MU_MESAG){
switch (msg[0]) {
@@ -283,7 +283,7 @@ static void atari_sslcert_viewer_destroy(struct atari_sslcert_viewer_s * cvwin)
assert(cvwin->init);
assert(cvwin->window);
- LOG("");
+ LOG("cvwin %p", cvwin);
if (atari_treeview_is_open(cvwin->tv))
atari_treeview_close(cvwin->tv);
diff --git a/atari/cookies.c b/atari/cookies.c
index 4578f38..6019b47 100644
--- a/atari/cookies.c
+++ b/atari/cookies.c
@@ -16,29 +16,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <ctype.h>
-#include <string.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
+#include <assert.h>
#include "utils/log.h"
#include "utils/messages.h"
-#include "utils/utils.h"
-#include "utils/nsoption.h"
-#include "content/content.h"
-#include "content/hlcache.h"
-#include "content/urldb.h"
+#include "desktop/mouse.h"
+#include "desktop/plotters.h"
#include "desktop/cookie_manager.h"
-#include "desktop/tree.h"
#include "desktop/core_window.h"
-#include "atari/gui.h"
-#include "atari/misc.h"
#include "atari/treeview.h"
#include "atari/cookies.h"
-#include "atari/findfile.h"
#include "atari/gemtk/gemtk.h"
#include "atari/res/netsurf.rsh"
@@ -71,35 +59,45 @@ static struct atari_treeview_callbacks atari_cookie_manager_treeview_callbacks =
};
-static nserror atari_cookie_manager_init_phase2(struct core_window *cw,
- struct core_window_callback_table *cb_t)
+static nserror
+atari_cookie_manager_init_phase2(struct core_window *cw,
+ struct core_window_callback_table *cb_t)
{
- LOG("");
+ LOG("cw %p",cw);
return(cookie_manager_init(cb_t, cw));
}
-static void atari_cookie_manager_finish(struct core_window *cw)
+
+static void
+atari_cookie_manager_finish(struct core_window *cw)
{
- LOG("");
+ LOG("cw %p",cw);
cookie_manager_fini();
}
-static void atari_cookie_manager_draw(struct core_window *cw, int x,
- int y, struct rect *clip,
- const struct redraw_context *ctx)
+
+static void
+atari_cookie_manager_draw(struct core_window *cw,
+ int x, int y,
+ struct rect *clip,
+ const struct redraw_context *ctx)
{
cookie_manager_redraw(x, y, clip, ctx);
}
-static void atari_cookie_manager_keypress(struct core_window *cw, uint32_t ucs4)
+
+static void
+atari_cookie_manager_keypress(struct core_window *cw, uint32_t ucs4)
{
- LOG("ucs4: %lu\n", ucs4);
+ LOG("ucs4: %"PRIu32, ucs4);
cookie_manager_keypress(ucs4);
}
-static void atari_cookie_manager_mouse_action(struct core_window *cw,
- browser_mouse_state mouse,
- int x, int y)
+
+static void
+atari_cookie_manager_mouse_action(struct core_window *cw,
+ browser_mouse_state mouse,
+ int x, int y)
{
cookie_manager_mouse_action(mouse, x, y);
}
@@ -110,9 +108,9 @@ static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8])
{
short retval = 0;
- LOG("");
+ LOG("win %p", win);
- if(ev_out->emo_events & MU_MESAG){
+ if (ev_out->emo_events & MU_MESAG) {
switch (msg[0]) {
case WM_TOOLBAR:
diff --git a/atari/ctxmenu.c b/atari/ctxmenu.c
index 7106fab..aecf3d1 100644
--- a/atari/ctxmenu.c
+++ b/atari/ctxmenu.c
@@ -16,33 +16,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <limits.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdbool.h>
-#include <assert.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <mint/osbind.h>
-#include <cflib.h>
-
#include "utils/log.h"
#include "utils/messages.h"
-#include "utils/utils.h"
+#include "utils/nsoption.h"
#include "desktop/browser.h"
-#include "desktop/mouse.h"
#include "desktop/textinput.h"
-#include "content/content.h"
#include "content/hlcache.h"
-#include "content/urldb.h"
#include "atari/gui.h"
#include "atari/rootwin.h"
-#include "atari/misc.h"
#include "atari/clipboard.h"
-#include "utils/nsoption.h"
+#include "atari/gemtk/gemtk.h"
#include "atari/res/netsurf.rsh"
#include "atari/ctxmenu.h"
diff --git a/atari/deskmenu.c b/atari/deskmenu.c
index c2994ce..17fa33c 100644
--- a/atari/deskmenu.c
+++ b/atari/deskmenu.c
@@ -20,10 +20,12 @@
#include <cflib.h>
#include "utils/log.h"
+#include "utils/nsurl.h"
#include "utils/messages.h"
#include "utils/nsoption.h"
#include "desktop/browser.h"
#include "desktop/save_complete.h"
+#include "desktop/textinput.h"
#include "atari/res/netsurf.rsh"
#include "atari/gemtk/gemtk.h"
@@ -659,7 +661,8 @@ static void register_menu_str( struct s_menu_item_evnt * mi )
}
}
- LOG("Registered keyboard shortcut for \"%s\" => mod: %d, ""keycode: %d, ascii: %c\n", str, accel->mod, accel->keycode, accel->ascii);
+ LOG("Registered keyboard shortcut for \"%s\" => mod: %d, ""keycode: %ld, ascii: %c\n",
+ str, accel->mod, accel->keycode, accel->ascii);
}
}
diff --git a/atari/download.c b/atari/download.c
index ce56d66..dad5d1f 100644
--- a/atari/download.c
+++ b/atari/download.c
@@ -29,6 +29,7 @@
#include "utils/messages.h"
#include "utils/utils.h"
#include "utils/nsoption.h"
+#include "utils/string.h"
#include "content/urldb.h"
#include "content/fetch.h"
#include "desktop/save_complete.h"
@@ -195,9 +196,8 @@ static void on_close(struct gui_download_window * dw)
static void gui_download_window_destroy( struct gui_download_window * gdw)
{
+ LOG("gdw %p", gdw);
-
- LOG("");
if (gdw->status == NSATARI_DOWNLOAD_WORKING) {
download_context_abort(gdw->ctx);
}
@@ -355,14 +355,13 @@ gui_download_window_create(download_context *ctx, struct gui_window *parent)
static nserror gui_download_window_data(struct gui_download_window *dw,
const char *data, unsigned int size)
{
-
uint32_t clck = clock();
uint32_t tnow = clck / (CLOCKS_PER_SEC>>3);
uint32_t sdiff = (clck / (CLOCKS_PER_SEC)) - dw->start;
- LOG("");
+ LOG("dw %p",dw);
- if(dw->abort == true){
+ if (dw->abort == true){
dw->status = NSATARI_DOWNLOAD_CANCELED;
dw->abort = false;
download_context_abort(dw->ctx);
@@ -409,6 +408,7 @@ static void gui_download_window_error(struct gui_download_window *dw,
const char *error_msg)
{
LOG("%s", error_msg);
+
strncpy((char*)&dw->lbl_file, error_msg, MAX_SLEN_LBL_FILE-1);
dw->status = NSATARI_DOWNLOAD_ERROR;
gemtk_wm_exec_redraw(dw->guiwin, NULL);
@@ -418,7 +418,7 @@ static void gui_download_window_error(struct gui_download_window *dw,
static void gui_download_window_done(struct gui_download_window *dw)
{
- LOG("");
+ LOG("dw %p", dw);
// TODO: change abort to close
dw->status = NSATARI_DOWNLOAD_COMPLETE;
diff --git a/atari/file.c b/atari/file.c
index b6d465f..499edd6 100644
--- a/atari/file.c
+++ b/atari/file.c
@@ -29,6 +29,7 @@
#include "utils/url.h"
#include "utils/nsurl.h"
#include "utils/file.h"
+#include "utils/string.h"
/**
* \file
diff --git a/atari/findfile.c b/atari/findfile.c
index 89f858c..45ca6d9 100644
--- a/atari/findfile.c
+++ b/atari/findfile.c
@@ -16,20 +16,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <limits.h>
#include <unistd.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <curl/curl.h>
#include "utils/log.h"
#include "utils/corestrings.h"
+
#include "atari/gemtk/gemtk.h"
#include "atari/findfile.h"
-#include "atari/misc.h"
+#include "atari/gui.h"
#include "atari/osspec.h"
char * local_file_to_url( const char * filename )
diff --git a/atari/font.c b/atari/font.c
index 729986c..cb0c574 100644
--- a/atari/font.c
+++ b/atari/font.c
@@ -19,11 +19,12 @@
#include <inttypes.h>
#include <assert.h>
#include <stdbool.h>
+#include <stdlib.h>
-#include "desktop/font.h"
#include "utils/utf8.h"
#include "utils/log.h"
#include "utils/nsoption.h"
+#include "desktop/gui_layout.h"
#include "desktop/mouse.h"
#include "desktop/plotters.h"
@@ -35,61 +36,121 @@
extern FONT_PLOTTER fplotter;
-static bool atari_font_position_in_string(const plot_font_style_t * fstyle,const char *string,
- size_t length,int x, size_t *char_offset, int *actual_x )
-{
- float scale = plot_get_scale();
-
- if (scale != 1.0) {
- plot_font_style_t newstyle = *fstyle;
- newstyle.size = (int)((float)fstyle->size*scale);
- fplotter->pixel_pos(fplotter, &newstyle, string, length, x, char_offset, actual_x);
- } else {
- fplotter->pixel_pos(fplotter, fstyle, string, length, x, char_offset, actual_x);
- }
- return( true );
-}
-
-static bool atari_font_split( const plot_font_style_t * fstyle, const char *string,
- size_t length,int x, size_t *char_offset, int *actual_x )
+/**
+ * Find the position in a string where an x coordinate falls.
+ *
+ * \param[in] fstyle style for this text
+ * \param[in] string UTF-8 string to measure
+ * \param[in] length length of string, in bytes
+ * \param[in] x coordinate to search for
+ * \param[out] char_offset updated to offset in string of actual_x, [0..length]
+ * \param[out] actual_x updated to x coordinate of character closest to x
+ * \return NSERROR_OK and char_offset and actual_x updated or appropriate error code on faliure
+ */
+static nserror
+atari_font_position(const plot_font_style_t *fstyle,
+ const char *string,
+ size_t length,
+ int x,
+ size_t *char_offset,
+ int *actual_x)
{
- float scale = plot_get_scale();
-
- if (scale != 1.0) {
- plot_font_style_t newstyle = *fstyle;
- newstyle.size = (int)((float)fstyle->size*scale);
- fplotter->str_split(fplotter, &newstyle, string, length, x, char_offset,
- actual_x);
- } else {
- fplotter->str_split(fplotter, fstyle, string, length, x, char_offset,
- actual_x);
- }
+ float scale = plot_get_scale();
+
+ if (scale != 1.0) {
+ plot_font_style_t newstyle = *fstyle;
+ newstyle.size = (int)((float)fstyle->size*scale);
+ fplotter->pixel_pos(fplotter, &newstyle, string, length, x,
+ char_offset, actual_x);
+ } else {
+ fplotter->pixel_pos(fplotter, fstyle, string, length, x,
+ char_offset, actual_x);
+ }
+
+ return NSERROR_OK;
+}
- return( true );
+/**
+ * Find where to split a string to make it fit a width.
+ *
+ * \param[in] fstyle style for this text
+ * \param[in] string UTF-8 string to measure
+ * \param[in] length length of string, in bytes
+ * \param[in] x width available
+ * \param[out] char_offset updated to offset in string of actual_x, [1..length]
+ * \param[out] actual_x updated to x coordinate of character closest to x
+ * \return NSERROR_OK or appropriate error code on faliure
+ *
+ * On exit, char_offset indicates first character after split point.
+ *
+ * \note char_offset of 0 must never be returned.
+ *
+ * Returns:
+ * char_offset giving split point closest to x, where actual_x <= x
+ * else
+ * char_offset giving split point closest to x, where actual_x > x
+ *
+ * Returning char_offset == length means no split possible
+ */
+static nserror
+atari_font_split(const plot_font_style_t *fstyle,
+ const char *string,
+ size_t length,
+ int x,
+ size_t *char_offset,
+ int *actual_x)
+{
+ float scale = plot_get_scale();
+
+ if (scale != 1.0) {
+ plot_font_style_t newstyle = *fstyle;
+ newstyle.size = (int)((float)fstyle->size*scale);
+ fplotter->str_split(fplotter, &newstyle, string, length, x,
+ char_offset, actual_x);
+ } else {
+ fplotter->str_split(fplotter, fstyle, string, length, x,
+ char_offset, actual_x);
+ }
+
+ return NSERROR_OK;
}
-static bool atari_font_width( const plot_font_style_t *fstyle, const char * str,
- size_t length, int * width )
-{
- float scale = plot_get_scale();
- if (scale != 1.0) {
- plot_font_style_t newstyle = *fstyle;
- newstyle.size = (int)((float)fstyle->size*scale);
- fplotter->str_width(fplotter, &newstyle, str, length, width);
- } else {
- fplotter->str_width(fplotter, fstyle, str, length, width);
- }
+/**
+ * Measure the width of a string.
+ *
+ * \param[in] fstyle plot style for this text
+ * \param[in] string UTF-8 string to measure
+ * \param[in] length length of string, in bytes
+ * \param[out] width updated to width of string[0..length)
+ * \return NSERROR_OK and width updated or appropriate error code on faliure
+ */
+static nserror
+atari_font_width(const plot_font_style_t *fstyle,
+ const char *str,
+ size_t length,
+ int * width)
+{
+ float scale = plot_get_scale();
+ if (scale != 1.0) {
+ plot_font_style_t newstyle = *fstyle;
+ newstyle.size = (int)((float)fstyle->size*scale);
+ fplotter->str_width(fplotter, &newstyle, str, length, width);
+ } else {
+ fplotter->str_width(fplotter, fstyle, str, length, width);
+ }
- return( true );
+ return NSERROR_OK;
}
-const struct font_functions nsfont = {
- atari_font_width,
- atari_font_position_in_string,
- atari_font_split
+
+static struct gui_layout_table layout_table = {
+ .width = atari_font_width,
+ .position = atari_font_position,
+ .split = atari_font_split,
};
+struct gui_layout_table *atari_layout_table = &layout_table;
diff --git a/atari/font.h b/atari/font.h
index 065a35a..a01d000 100644
--- a/atari/font.h
+++ b/atari/font.h
@@ -19,6 +19,7 @@
#ifndef NS_ATARI_FONT_H
#define NS_ATARI_FONT_H
+struct gui_layout_table *atari_layout_table;
#endif /* NETSURF_FB_FONT_H */
diff --git a/atari/gui.c b/atari/gui.c
index 265ae5a..810c764 100644
--- a/atari/gui.c
+++ b/atari/gui.c
@@ -24,30 +24,18 @@
#include <sys/types.h>
#include <sys/stat.h>
-#include <fcntl.h>
-#include <time.h>
-#include <limits.h>
#include <unistd.h>
-#include <string.h>
-#include <stdbool.h>
-#include <hubbub/hubbub.h>
#include "utils/log.h"
#include "utils/messages.h"
-#include "utils/utils.h"
-#include "utils/nsoption.h"
#include "utils/corestrings.h"
#include "content/urldb.h"
-#include "content/fetch.h"
-#include "content/fetchers/resource.h"
+#include "content/content.h"
#include "content/backing_store.h"
-#include "desktop/mouse.h"
-#include "desktop/plotters.h"
-#include "desktop/save_complete.h"
-#include "desktop/textinput.h"
+#include "content/hlcache.h"
#include "desktop/treeview.h"
#include "desktop/browser.h"
-#include "desktop/font.h"
+#include "desktop/gui_layout.h"
#include "desktop/gui_window.h"
#include "desktop/gui_clipboard.h"
#include "desktop/gui_fetch.h"
@@ -78,6 +66,7 @@
#include "atari/file.h"
#include "atari/filetype.h"
#include "atari/bitmap.h"
+#include "atari/font.h"
#include "cflib.h"
static bool atari_quit = false;
@@ -766,19 +755,19 @@ static void gui_set_clipboard(const char *buffer, size_t length,
static void gui_401login_open(nsurl *url, const char *realm,
nserror (*cb)(bool proceed, void *pw), void *cbpw)
{
- bool bres;
- char * out = NULL;
- bres = login_form_do( url, (char*)realm, &out);
- if (bres) {
- LOG("url: %s, realm: %s, auth: %s\n", url, realm, out);
- urldb_set_auth_details(url, realm, out);
- }
- if (out != NULL) {
- free( out );
- }
- if (cb != NULL) {
- cb(bres, cbpw);
- }
+ bool bres;
+ char * out = NULL;
+ bres = login_form_do( url, (char*)realm, &out);
+ if (bres) {
+ LOG("url: %s, realm: %s, auth: %s\n", nsurl_access(url), realm, out);
+ urldb_set_auth_details(url, realm, out);
+ }
+ if (out != NULL) {
+ free( out );
+ }
+ if (cb != NULL) {
+ cb(bres, cbpw);
+ }
}
@@ -787,25 +776,25 @@ gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
unsigned long num, nserror (*cb)(bool proceed, void *pw),
void *cbpw)
{
- struct sslcert_session_data *data;
- LOG("");
-
- // TODO: localize string
- int b = form_alert(1, "[2][SSL Verify failed, continue?][Continue|Abort|Details...]");
- if(b == 1){
- // Accept
- urldb_set_cert_permissions(url, true);
- cb(true, cbpw);
- } else if(b == 2) {
- // Reject
- urldb_set_cert_permissions(url, false);
- cb(false, cbpw);
- } else if(b == 3) {
- // Inspect
- sslcert_viewer_create_session_data(num, url, cb, cbpw, certs,
- &data);
- atari_sslcert_viewer_open(data);
- }
+ struct sslcert_session_data *data;
+ LOG("url %s", nsurl_access(url));
+
+ // TODO: localize string
+ int b = form_alert(1, "[2][SSL Verify failed, continue?][Continue|Abort|Details...]");
+ if(b == 1){
+ // Accept
+ urldb_set_cert_permissions(url, true);
+ cb(true, cbpw);
+ } else if(b == 2) {
+ // Reject
+ urldb_set_cert_permissions(url, false);
+ cb(false, cbpw);
+ } else if(b == 3) {
+ // Inspect
+ sslcert_viewer_create_session_data(num, url, cb, cbpw, certs,
+ &data);
+ atari_sslcert_viewer_open(data);
+ }
}
@@ -822,10 +811,10 @@ struct gui_window * gui_get_input_window(void)
static void gui_quit(void)
{
- LOG("");
+ LOG("quitting");
- struct gui_window * gw = window_list;
- struct gui_window * tmp = window_list;
+ struct gui_window *gw = window_list;
+ struct gui_window *tmp = window_list;
/* Destroy all remaining browser windows: */
while (gw) {
@@ -1094,8 +1083,9 @@ static struct gui_fetch_table atari_fetch_table = {
.get_resource_url = gui_get_resource_url,
};
-static struct gui_browser_table atari_browser_table = {
+static struct gui_misc_table atari_misc_table = {
.schedule = atari_schedule,
+ .warning = atari_warn_user,
.quit = gui_quit,
.cert_verify = gui_cert_verify,
@@ -1121,7 +1111,7 @@ int main(int argc, char** argv)
nserror ret;
struct netsurf_table atari_table = {
- .browser = &atari_browser_table,
+ .misc = &atari_misc_table,
.window = &atari_window_table,
.clipboard = &atari_clipboard_table,
.download = atari_download_table,
@@ -1130,7 +1120,8 @@ int main(int argc, char** argv)
.utf8 = atari_utf8_table,
.search = atari_search_table,
.llcache = filesystem_llcache_table,
- .bitmap = atari_bitmap_table
+ .bitmap = atari_bitmap_table,
+ .layout = atari_layout_table
};
ret = netsurf_register(&atari_table);
@@ -1203,7 +1194,7 @@ int main(int argc, char** argv)
nsurl_unref(url);
}
if (ret != NSERROR_OK) {
- warn_user(messages_get_errorcode(ret), 0);
+ atari_warn_user(messages_get_errorcode(ret), 0);
} else {
LOG("Entering Atari event mainloop...");
while (!atari_quit) {
diff --git a/atari/gui.h b/atari/gui.h
index ed76adc..50184d0 100644
--- a/atari/gui.h
+++ b/atari/gui.h
@@ -22,6 +22,8 @@
#include <stdbool.h>
#include <mt_gem.h>
+#include "desktop/mouse.h"
+
#include "atari/redrawslots.h"
#include "atari/gemtk/gemtk.h"
diff --git a/atari/history.c b/atari/history.c
index f048b0b..ba72c7f 100644
--- a/atari/history.c
+++ b/atari/history.c
@@ -16,29 +16,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <ctype.h>
-#include <string.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
+#include <assert.h>
+#include <inttypes.h>
#include "utils/log.h"
#include "utils/messages.h"
-#include "utils/utils.h"
-#include "utils/nsoption.h"
-#include "content/content.h"
-#include "content/hlcache.h"
-#include "content/urldb.h"
+#include "desktop/mouse.h"
#include "desktop/global_history.h"
-#include "desktop/tree.h"
#include "desktop/core_window.h"
-#include "atari/gui.h"
-#include "atari/misc.h"
#include "atari/treeview.h"
#include "atari/history.h"
-#include "atari/findfile.h"
#include "atari/gemtk/gemtk.h"
#include "atari/res/netsurf.rsh"
@@ -47,38 +35,18 @@ extern GRECT desk_area;
struct atari_global_history_s atari_global_history;
/* Setup Atari Treeview Callbacks: */
-static nserror atari_global_history_init_phase2(struct core_window *cw,
- struct core_window_callback_table * default_callbacks);
-static void atari_global_history_finish(struct core_window *cw);
-static void atari_global_history_keypress(struct core_window *cw,
- uint32_t ucs4);
-static void atari_global_history_mouse_action(struct core_window *cw,
- browser_mouse_state mouse,
- int x, int y);
-static void atari_global_history_draw(struct core_window *cw, int x,
- int y, struct rect *clip,
- const struct redraw_context *ctx);
-static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8]);
-static struct atari_treeview_callbacks atari_global_history_treeview_callbacks = {
- .init_phase2 = atari_global_history_init_phase2,
- .finish = atari_global_history_finish,
- .draw = atari_global_history_draw,
- .keypress = atari_global_history_keypress,
- .mouse_action = atari_global_history_mouse_action,
- .gemtk_user_func = handle_event
-};
-
-static nserror atari_global_history_init_phase2(struct core_window *cw,
- struct core_window_callback_table *cb_t)
+static nserror
+atari_global_history_init_phase2(struct core_window *cw,
+ struct core_window_callback_table *cb_t)
{
- LOG("");
+ LOG("cw %p", cw);
return(global_history_init(cb_t, cw));
}
static void atari_global_history_finish(struct core_window *cw)
{
- LOG("");
+ LOG("cw %p", cw);
global_history_fini();
}
@@ -91,27 +59,31 @@ static void atari_global_history_draw(struct core_window *cw, int x,
static void atari_global_history_keypress(struct core_window *cw, uint32_t ucs4)
{
- LOG("ucs4: %lu\n", ucs4);
+ LOG("ucs4: %"PRIu32, ucs4);
global_history_keypress(ucs4);
}
-static void atari_global_history_mouse_action(struct core_window *cw,
- browser_mouse_state mouse,
- int x, int y)
+static void
+atari_global_history_mouse_action(struct core_window *cw,
+ browser_mouse_state mouse,
+ int x, int y)
{
LOG("x: %d, y: %d\n", x, y);
global_history_mouse_action(mouse, x, y);
-
}
+void atari_global_history_close(void)
+{
+ atari_treeview_close(atari_global_history.tv);
+}
static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8])
{
short retval = 0;
- LOG("");
+ LOG("win %p", win);
if (ev_out->emo_events & MU_MESAG) {
switch (msg[0]) {
@@ -127,7 +99,14 @@ static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8])
return(retval);
}
-
+static struct atari_treeview_callbacks atari_global_history_treeview_callbacks = {
+ .init_phase2 = atari_global_history_init_phase2,
+ .finish = atari_global_history_finish,
+ .draw = atari_global_history_draw,
+ .keypress = atari_global_history_keypress,
+ .mouse_action = atari_global_history_mouse_action,
+ .gemtk_user_func = handle_event
+};
void atari_global_history_init(void)
{
@@ -186,10 +165,6 @@ void atari_global_history_open(void)
}
}
-void atari_global_history_close(void)
-{
- atari_treeview_close(atari_global_history.tv);
-}
void atari_global_history_destroy(void)
{
diff --git a/atari/login.c b/atari/login.c
index 66e0217..c44b077 100644
--- a/atari/login.c
+++ b/atari/login.c
@@ -32,6 +32,7 @@
#include "content/urldb.h"
#include "content/fetch.h"
+#include "atari/gui.h"
#include "atari/misc.h"
#include "atari/login.h"
#include "atari/res/netsurf.rsh"
diff --git a/atari/misc.c b/atari/misc.c
index e3c358b..8c94091 100644
--- a/atari/misc.c
+++ b/atari/misc.c
@@ -25,6 +25,7 @@
#include <sys/types.h>
#include <mint/osbind.h>
+#include "utils/dirent.h"
#include "content/content.h"
#include "content/hlcache.h"
#include "desktop/cookie_manager.h"
@@ -52,7 +53,8 @@ struct is_process_running_callback_data {
bool found;
};
-void warn_user(const char *warning, const char *detail)
+/* exported function documented in atari/misc/h */
+nserror atari_warn_user(const char *warning, const char *detail)
{
size_t len = 1 + ((warning != NULL) ? strlen(messages_get(warning)) :
0) + ((detail != 0) ? strlen(detail) : 0);
@@ -61,6 +63,8 @@ void warn_user(const char *warning, const char *detail)
printf("%s\n", message);
gemtk_msg_box_show(GEMTK_MSG_BOX_ALERT, message);
+
+ return NSERROR_OK;
}
void die(const char *error)
@@ -201,60 +205,6 @@ static nserror load_icon_callback(hlcache_handle *handle,
}
-/**
- * utility function. Copied from NetSurf tree API.
- *
- * \param name the name of the loaded icon, if it's not a full path
- * the icon is looked for in the directory specified by
- * icons_dir.
- * \param cb callback function to deal with hlcache callback.
- * \param pw Context pointer to be passed to callback.
- * \return the icon in form of a content or NULL on failure
- */
-hlcache_handle *
-load_icon(const char *name, hlcache_handle_callback cb, void *pw)
-{
- hlcache_handle *c;
- nserror err;
- nsurl *icon_nsurl;
- char * icons_dir = nsoption_charp(tree_icons_path);
-
- /** @todo something like bitmap_from_disc is needed here */
-
- if (!strncmp(name, "file://", 7)) {
- err = nsurl_create(name, &icon_nsurl);
- } else {
- char *native_path = NULL;
-
- if (icons_dir == NULL)
- return NULL;
-
- err = netsurf_mkpath(&native_path, NULL, 2, icons_dir, name);
- if (err == NSERROR_OK) {
- /* Convert native path to URL */
- err = netsurf_path_to_nsurl(native_path, &icon_nsurl);
- free(native_path);
- }
- }
-
- if (err != NSERROR_OK) {
- warn_user(messages_get_errorcode(err), 0);
- return NULL;
- }
-
- /* Fetch the icon */
- err = hlcache_handle_retrieve(icon_nsurl, 0, 0, 0,
- ((cb != NULL) ? cb : load_icon_callback), pw, 0,
- CONTENT_IMAGE, &c);
-
- nsurl_unref(icon_nsurl);
-
- if (err != NSERROR_OK) {
- return NULL;
- }
-
- return c;
-}
void gem_set_cursor( MFORM_EX * cursor )
{
diff --git a/atari/misc.h b/atari/misc.h
index 418f283..0ccaaa7 100644
--- a/atari/misc.h
+++ b/atari/misc.h
@@ -19,11 +19,6 @@
#ifndef NS_ATARI_MISC_H
#define NS_ATARI_MISC_H
-#include "cflib.h"
-#include "content/content.h"
-#include "content/hlcache.h"
-#include "desktop/textinput.h"
-#include "atari/gui.h"
#define SBUF8_TO_LBUF8(sbuf,lbuf)\
lbuf[0] = (long)sbuf[0];\
@@ -47,23 +42,42 @@
#define BY_WINDOM_HANDLE 0x0
#define BY_GEM_HANDLE 0x1
+/**
+ */
typedef int (*scan_process_callback)(int pid, void *data);
+/**
+ */
struct gui_window * find_guiwin_by_aes_handle(short handle);
+
+/**
+ */
bool is_process_running(const char * name);
+
+/**
+ */
void gem_set_cursor( MFORM_EX * cursor );
-hlcache_handle *load_icon( const char *name, hlcache_handle_callback cb,
- void * pw );
+
+/**
+ */
void dbg_grect(const char * str, GRECT * r);
+
+/**
+ */
void dbg_pxy(const char * str, short * pxy);
+
+/**
+ */
void dbg_rect(const char * str, int * pxy);
+/**
+ */
const char * file_select(const char * title, const char * name);
/**
* Convert NKC (atari normalized key code) to netsurf
* Input key code and/or to ucs4 (depends on keycode).
-*/
+ */
long nkc_to_input_key(short nkc, long * ucs4_out);
/**
@@ -75,4 +89,14 @@ long nkc_to_input_key(short nkc, long * ucs4_out);
*/
void die(const char * const error) __attribute__ ((noreturn));
+/**
+ * Warn the user of an event.
+ *
+ * \param[in] message A warning looked up in the message translation table
+ * \param[in] detail Additional text to be displayed or NULL.
+ * \return NSERROR_OK on success or error code if there was a
+ * faliure displaying the message to the user.
+ */
+nserror atari_warn_user(const char *warning, const char *detail);
+
#endif
diff --git a/atari/plot/font_internal.c b/atari/plot/font_internal.c
index 1578b39..89a56d0 100644
--- a/atari/plot/font_internal.c
+++ b/atari/plot/font_internal.c
@@ -19,6 +19,7 @@
#ifdef WITH_INTERNAL_FONT_DRIVER
+#include <assert.h>
#include <unistd.h>
#include "utils/utf8.h"
diff --git a/atari/plot/plot.c b/atari/plot/plot.c
index 1ac3ee9..45e4cea 100644
--- a/atari/plot/plot.c
+++ b/atari/plot/plot.c
@@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <assert.h>
#include <sys/types.h>
#include <stdint.h>
#include <string.h>
@@ -32,6 +33,7 @@
#include "desktop/plotters.h"
#include "desktop/mouse.h"
+#include "atari/gui.h"
#include "atari/osspec.h"
#include "atari/misc.h"
#include "atari/bitmap.h"
diff --git a/atari/rootwin.c b/atari/rootwin.c
index c9f5071..605ce45 100644
--- a/atari/rootwin.c
+++ b/atari/rootwin.c
@@ -405,26 +405,26 @@ void window_restore_active_gui_window(ROOTWIN *rootwin)
GRECT tb_area;
struct gui_window *gw;
- LOG("");
+ LOG("rootwin %p", rootwin);
assert(rootwin->active_gui_window);
gw = rootwin->active_gui_window;
- window_set_icon(rootwin, gw->icon);
- window_set_stauts(rootwin, gw->status);
- window_set_title(rootwin, gw->title);
+ window_set_icon(rootwin, gw->icon);
+ window_set_stauts(rootwin, gw->status);
+ window_set_title(rootwin, gw->title);
if (gw->search != NULL) {
// TODO: update search session (especially browser window)
- }
+ }
toolbar_get_grect(rootwin->toolbar, 0, &tb_area);
gemtk_wm_set_toolbar_size(rootwin->win, tb_area.g_h);
window_update_back_forward(rootwin);
- toolbar_set_url(rootwin->toolbar, gw->url);
+ toolbar_set_url(rootwin->toolbar, gw->url);
}
@@ -564,14 +564,14 @@ void window_set_active_gui_window(ROOTWIN *rootwin, struct gui_window *gw)
{
struct gui_window *old_gw = rootwin->active_gui_window;
- LOG("");
+ LOG("gw %p",gw);
- if (rootwin->active_gui_window != NULL) {
- if(rootwin->active_gui_window == gw) {
- LOG("nothing to do...");
- return;
+ if (rootwin->active_gui_window != NULL) {
+ if(rootwin->active_gui_window == gw) {
+ LOG("nothing to do...");
+ return;
+ }
}
- }
// TODO: when the window isn't on top, initiate WM_TOPPED.
@@ -652,7 +652,7 @@ void window_open_search(ROOTWIN *rootwin, bool reformat)
GRECT area;
OBJECT *obj;
- LOG("");
+ LOG("rootwin %p", rootwin);
gw = rootwin->active_gui_window;
bw = gw->browser->bw;
@@ -1469,7 +1469,7 @@ static void on_file_dropped(ROOTWIN *rootwin, short msg[8])
buff[size] = 0;
- LOG("file: %s, ext: %s, size: %d dropped at: %d,%d\n", (char *)buff, (char *)&ext, size, mx, my);
+ LOG("file: %s, ext: %s, size: %ld dropped at: %d,%d\n", (char *)buff, (char *)&ext, size, mx, my);
gui_window_get_scroll(gw, &sx, &sy);
diff --git a/atari/schedule.c b/atari/schedule.c
index 5c652d5..4898042 100644
--- a/atari/schedule.c
+++ b/atari/schedule.c
@@ -19,9 +19,9 @@
#include <stdlib.h>
#include <string.h>
-#include <sys/time.h>
#include <time.h>
+#include "utils/sys_time.h"
#include "utils/errors.h"
#include "atari/schedule.h"
diff --git a/atari/search.h b/atari/search.h
index ee52567..04dfed4 100644
--- a/atari/search.h
+++ b/atari/search.h
@@ -25,6 +25,8 @@
struct gui_window;
struct browser_window;
+#include "desktop/search.h"
+
struct s_search_form_state {
char text[32];
uint32_t flags;
diff --git a/atari/settings.c b/atari/settings.c
index e921da2..3bfa4bb 100644
--- a/atari/settings.c
+++ b/atari/settings.c
@@ -17,9 +17,9 @@
*
*/
+#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <dirent.h>
#include <fcntl.h>
#include <time.h>
#include <limits.h>
@@ -29,10 +29,12 @@
#include <cflib.h>
#include <gem.h>
+#include "utils/dirent.h"
#include "utils/nsoption.h"
#include "utils/log.h"
#include "desktop/plot_style.h"
+#include "atari/gui.h"
#include "atari/res/netsurf.rsh"
#include "atari/settings.h"
#include "atari/deskmenu.h"
@@ -977,7 +979,7 @@ void open_settings(void)
void close_settings(void)
{
- LOG("");
+ LOG("closing");
gemtk_wm_remove(settings_guiwin);
settings_guiwin = NULL;
wind_close(h_aes_win);
diff --git a/atari/toolbar.c b/atari/toolbar.c
index e830679..eefab5f 100644
--- a/atari/toolbar.c
+++ b/atari/toolbar.c
@@ -272,7 +272,7 @@ struct s_toolbar *toolbar_create(struct s_gui_win_root *owner)
int i;
struct s_toolbar *t;
- LOG("");
+ LOG("owner %p", owner);
assert(init == true);
@@ -330,7 +330,8 @@ struct s_toolbar *toolbar_create(struct s_gui_win_root *owner)
t->throbber.max_index = THROBBER_MAX_INDEX;
t->throbber.running = false;
- LOG("created toolbar: %p, root: %p, textarea: %p, throbber: %p", t, owner, t->url.textarea, t->throbber);
+ LOG("created toolbar: %p, root: %p, textarea: %p, throbber: %p",
+ t, owner, t->url.textarea, &t->throbber);
return( t );
}
@@ -455,10 +456,12 @@ void toolbar_redraw(struct s_toolbar *tb, GRECT *clip)
}
-void toolbar_update_buttons(struct s_toolbar *tb, struct browser_window *bw,
- short button)
+void
+toolbar_update_buttons(struct s_toolbar *tb,
+ struct browser_window *bw,
+ short button)
{
- LOG("");
+ LOG("tb %p", tb);
struct s_tb_button * bt;
bool enable = false;
@@ -580,9 +583,10 @@ void toolbar_set_dimensions(struct s_toolbar *tb, GRECT *area)
}
-void toolbar_set_url(struct s_toolbar *tb, const char * text)
+void toolbar_set_url(struct s_toolbar *tb, const char *text)
{
- LOG("");
+ LOG("tb %p", tb);
+
textarea_set_text(tb->url.textarea, text);
if (tb->attached && tb->visible) {
@@ -667,7 +671,7 @@ bool toolbar_text_input(struct s_toolbar *tb, char *text)
{
bool handled = true;
- LOG("");
+ LOG("tb %p", tb);
return(handled);
}
@@ -752,11 +756,12 @@ bool toolbar_key_input(struct s_toolbar *tb, short nkc)
void toolbar_mouse_input(struct s_toolbar *tb, short obj, short button)
{
- LOG("");
GRECT work;
short mx, my, mb, kstat;
struct gui_window * gw;
+ LOG("tb %p", tb);
+
if (obj==TOOLBAR_AREA_URL) {
graf_mkstate(&mx, &my, &mb, &kstat);
diff --git a/beos/Makefile.target b/beos/Makefile.target
index 38ec279..382b327 100644
--- a/beos/Makefile.target
+++ b/beos/Makefile.target
@@ -24,7 +24,8 @@ BEOS_RC := rc
BEOS_XRES := xres
BEOS_SETVER := setversion
BEOS_MIMESET := mimeset
-VERSION_FULL := $(shell sed -n '/"/{s/.*"\(.*\)".*/\1/;p;}' desktop/version.c)
+
+VERSION_FULL := $(shell sed -n '/_version.*=.*"/{s/.*"\(.*\)".*/\1/;p;}' desktop/version.c)
VERSION_MAJ := $(shell sed -n '/_major/{s/.* = \([0-9]*\).*/\1/;p;}' desktop/version.c)
VERSION_MIN := $(shell sed -n '/_minor/{s/.* = \([0-9]*\).*/\1/;p;}' desktop/version.c)
diff --git a/beos/bitmap.cpp b/beos/bitmap.cpp
index b39da7c..26b7a39 100644
--- a/beos/bitmap.cpp
+++ b/beos/bitmap.cpp
@@ -34,6 +34,7 @@
#include <TranslatorFormats.h>
#include <TranslatorRoster.h>
#include <View.h>
+#include <stdlib.h>
extern "C" {
#include "utils/log.h"
@@ -41,7 +42,6 @@ extern "C" {
#include "content/urldb.h"
#include "desktop/plotters.h"
#include "desktop/browser.h"
-#include "desktop/font.h"
#include "image/bitmap.h"
}
@@ -118,7 +118,7 @@ static inline void nsbeos_rgba_to_bgra(void *src,
* \param state a flag word indicating the initial state
* \return an opaque struct bitmap, or NULL on memory exhaustion
*/
-void *bitmap_create(int width, int height, unsigned int state)
+static void *bitmap_create(int width, int height, unsigned int state)
{
struct bitmap *bmp = (struct bitmap *)malloc(sizeof(struct bitmap));
if (bmp == NULL)
@@ -147,7 +147,7 @@ void *bitmap_create(int width, int height, unsigned int state)
* \param vbitmap a bitmap, as returned by bitmap_create()
* \param opaque whether the bitmap should be plotted opaque
*/
-void bitmap_set_opaque(void *vbitmap, bool opaque)
+static void bitmap_set_opaque(void *vbitmap, bool opaque)
{
struct bitmap *bitmap = (struct bitmap *)vbitmap;
assert(bitmap);
@@ -161,7 +161,7 @@ void bitmap_set_opaque(void *vbitmap, bool opaque)
* \param vbitmap a bitmap, as returned by bitmap_create()
* \return whether the bitmap is opaque
*/
-bool bitmap_test_opaque(void *vbitmap)
+static bool bitmap_test_opaque(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *)vbitmap;
assert(bitmap);
@@ -175,7 +175,7 @@ bool bitmap_test_opaque(void *vbitmap)
*
* \param vbitmap a bitmap, as returned by bitmap_create()
*/
-bool bitmap_get_opaque(void *vbitmap)
+static bool bitmap_get_opaque(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *)vbitmap;
assert(bitmap);
@@ -193,7 +193,7 @@ bool bitmap_get_opaque(void *vbitmap)
* of rows. The width of a row in bytes is given by bitmap_get_rowstride().
*/
-unsigned char *bitmap_get_buffer(void *vbitmap)
+static unsigned char *bitmap_get_buffer(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *)vbitmap;
assert(bitmap);
@@ -207,7 +207,7 @@ unsigned char *bitmap_get_buffer(void *vbitmap)
* \param vbitmap a bitmap, as returned by bitmap_create()
* \return width of a pixel row in the bitmap
*/
-size_t bitmap_get_rowstride(void *vbitmap)
+static size_t bitmap_get_rowstride(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *)vbitmap;
assert(bitmap);
@@ -221,7 +221,7 @@ size_t bitmap_get_rowstride(void *vbitmap)
* \param vbitmap a bitmap, as returned by bitmap_create()
* \return bytes per pixels of the bitmap
*/
-size_t bitmap_get_bpp(void *vbitmap)
+static size_t bitmap_get_bpp(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *)vbitmap;
assert(bitmap);
@@ -249,7 +249,7 @@ static void nsbeos_bitmap_free_pretiles(struct bitmap *bitmap)
*
* \param vbitmap a bitmap, as returned by bitmap_create()
*/
-void bitmap_destroy(void *vbitmap)
+static void bitmap_destroy(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *)vbitmap;
assert(bitmap);
@@ -268,7 +268,7 @@ void bitmap_destroy(void *vbitmap)
* \param flags modify the behaviour of the save
* \return true on success, false on error and error reported
*/
-bool bitmap_save(void *vbitmap, const char *path, unsigned flags)
+static bool bitmap_save(void *vbitmap, const char *path, unsigned flags)
{
struct bitmap *bitmap = (struct bitmap *)vbitmap;
BTranslatorRoster *roster = BTranslatorRoster::Default();
@@ -303,14 +303,14 @@ void bitmap_modified(void *vbitmap)
}
-int bitmap_get_width(void *vbitmap)
+static int bitmap_get_width(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *)vbitmap;
return bitmap->primary->Bounds().Width() + 1;
}
-int bitmap_get_height(void *vbitmap)
+static int bitmap_get_height(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *)vbitmap;
return bitmap->primary->Bounds().Height() + 1;
diff --git a/beos/download.cpp b/beos/download.cpp
index 791da35..ea0271e 100644
--- a/beos/download.cpp
+++ b/beos/download.cpp
@@ -19,11 +19,13 @@
#define __STDBOOL_H__ 1
#include <stdbool.h>
#include <sys/types.h>
+#include <stdlib.h>
extern "C" {
#include "desktop/download.h"
#include "desktop/gui_download.h"
#include "utils/utils.h"
+#include "utils/string.h"
}
#include "beos/download.h"
diff --git a/beos/fetch_rsrc.cpp b/beos/fetch_rsrc.cpp
index 917e759..a2c8184 100644
--- a/beos/fetch_rsrc.cpp
+++ b/beos/fetch_rsrc.cpp
@@ -20,6 +20,7 @@
/* rsrc: URL handling. */
#define __STDBOOL_H__ 1
+#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <stdbool.h>
diff --git a/beos/font.cpp b/beos/font.cpp
index cba3e4d..87c2346 100644
--- a/beos/font.cpp
+++ b/beos/font.cpp
@@ -30,33 +30,112 @@
#include <Font.h>
#include <String.h>
#include <View.h>
+
extern "C" {
-#include "desktop/font.h"
#include "utils/utils.h"
#include "utils/log.h"
#include "utils/nsoption.h"
#include "utils/nsurl.h"
+#include "desktop/gui_layout.h"
}
#include "beos/gui.h"
#include "beos/font.h"
#include "beos/plotters.h"
-static bool nsfont_width(const plot_font_style_t *fstyle,
- const char *string, size_t length,
- int *width);
-static bool nsfont_position_in_string(const plot_font_style_t *fstyle,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x);
-static bool nsfont_split(const plot_font_style_t *fstyle,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x);
-const struct font_functions nsfont = {
- nsfont_width,
- nsfont_position_in_string,
- nsfont_split
-};
+/**
+ * Convert a font style to a PangoFontDescription.
+ *
+ * \param font Beos font object.
+ * \param fstyle style for this text
+ */
+void nsbeos_style_to_font(BFont &font, const struct plot_font_style *fstyle)
+{
+ float size;
+ uint16 face = 0;
+ const char *family;
+
+ switch (fstyle->family) {
+ case PLOT_FONT_FAMILY_SERIF:
+ family = nsoption_charp(font_serif);
+ break;
+ case PLOT_FONT_FAMILY_MONOSPACE:
+ family = nsoption_charp(font_mono);
+ break;
+ case PLOT_FONT_FAMILY_CURSIVE:
+ family = nsoption_charp(font_cursive);
+ break;
+ case PLOT_FONT_FAMILY_FANTASY:
+ family = nsoption_charp(font_fantasy);
+ break;
+ case PLOT_FONT_FAMILY_SANS_SERIF:
+ default:
+ family = nsoption_charp(font_sans);
+ break;
+ }
+
+ if ((fstyle->flags & FONTF_ITALIC)) {
+ face = B_ITALIC_FACE;
+ } else if ((fstyle->flags & FONTF_OBLIQUE)) {
+ face = B_ITALIC_FACE;
+ // XXX: no OBLIQUE flag ??
+ // maybe find "Oblique" style
+ // or use SetShear() ?
+ }
+
+#ifndef __HAIKU__XXX
+ if (fstyle->weight >= 600) {
+ face |= B_BOLD_FACE;
+ }
+#else
+ if (fstyle->weight >= 600) {
+ if (fstyle->weight >= 800)
+ face |= B_HEAVY_FACE;
+ else
+ face |= B_BOLD_FACE;
+ } else if (fstyle->weight <= 300) {
+ face |= B_LIGHT_FACE;
+ }
+#endif
+/*
+ case CSS_FONT_WEIGHT_100: weight = 100; break;
+ case CSS_FONT_WEIGHT_200: weight = 200; break;
+ case CSS_FONT_WEIGHT_300: weight = 300; break;
+ case CSS_FONT_WEIGHT_400: weight = 400; break;
+ case CSS_FONT_WEIGHT_500: weight = 500; break;
+ case CSS_FONT_WEIGHT_600: weight = 600; break;
+ case CSS_FONT_WEIGHT_700: weight = 700; break;
+ case CSS_FONT_WEIGHT_800: weight = 800; break;
+ case CSS_FONT_WEIGHT_900: weight = 900; break;
+*/
+
+ if (!face)
+ face = B_REGULAR_FACE;
+
+//fprintf(stderr, "nsbeos_style_to_font: %d, %d, %d -> '%s' %04x\n", style->font_family, style->font_style, style->font_weight, family, face);
+
+ if (family) {
+ font_family beos_family;
+
+ strncpy(beos_family, family, B_FONT_FAMILY_LENGTH);
+ // Ensure it's terminated
+ beos_family[B_FONT_FAMILY_LENGTH] = '\0';
+
+ font.SetFamilyAndFace(beos_family, face);
+ } else {
+ //XXX not used
+ font = be_plain_font;
+ font.SetFace(face);
+ }
+
+//fprintf(stderr, "nsbeos_style_to_font: value %f unit %d\n", style->font_size.value.length.value, style->font_size.value.length.unit);
+ size = fstyle->size / FONT_SIZE_SCALE;
+
+//fprintf(stderr, "nsbeos_style_to_font: %f %d\n", size, style->font_size.value.length.unit);
+
+ font.SetSize(size);
+}
/**
@@ -68,8 +147,7 @@ const struct font_functions nsfont = {
* \param width updated to width of string[0..length)
* \return true on success, false on error and error reported
*/
-
-bool nsfont_width(const plot_font_style_t *fstyle,
+static nserror beos_font_width(const plot_font_style_t *fstyle,
const char *string, size_t length,
int *width)
{
@@ -78,12 +156,13 @@ bool nsfont_width(const plot_font_style_t *fstyle,
if (length == 0) {
*width = 0;
- return true;
+ return NSERROR_OK;
}
nsbeos_style_to_font(font, fstyle);
*width = (int)font.StringWidth(string, length);
- return true;
+
+ return NSERROR_OK;
}
@@ -93,6 +172,7 @@ static int utf8_char_len(const char *c)
uint8 m = 0xE0;
uint8 v = 0xC0;
int i;
+
if (!*p)
return 0;
if ((*p & 0x80) == 0)
@@ -120,8 +200,7 @@ static int utf8_char_len(const char *c)
* \param actual_x updated to x coordinate of character closest to x
* \return true on success, false on error and error reported
*/
-
-bool nsfont_position_in_string(const plot_font_style_t *fstyle,
+static nserror beos_font_position(const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x)
{
@@ -137,6 +216,7 @@ bool nsfont_position_in_string(const plot_font_style_t *fstyle,
float esc = 0.0;
float current = 0.0;
int i;
+
index = 0;
font.GetEscapements(string, len, escapements);
// slow but it should work
@@ -151,7 +231,7 @@ bool nsfont_position_in_string(const plot_font_style_t *fstyle,
*actual_x = (int)current;
*char_offset = i; //index;
- return true;
+ return NSERROR_OK;
}
@@ -177,8 +257,7 @@ bool nsfont_position_in_string(const plot_font_style_t *fstyle,
*
* Returning char_offset == length means no split possible
*/
-
-bool nsfont_split(const plot_font_style_t *fstyle,
+static nserror beos_font_split(const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x)
{
@@ -196,6 +275,7 @@ bool nsfont_split(const plot_font_style_t *fstyle,
float last_x = 0.0;
int i;
int last_space = 0;
+
font.GetEscapements(string, len, escapements);
// very slow but it should work
for (i = 0; string[index] && i < len; i++) {
@@ -206,7 +286,7 @@ bool nsfont_split(const plot_font_style_t *fstyle,
if (x < current && last_space != 0) {
*actual_x = (int)last_x;
*char_offset = last_space;
- return true;
+ return NSERROR_OK;;
}
esc += escapements[i];
current = font.Size() * esc;
@@ -215,7 +295,7 @@ bool nsfont_split(const plot_font_style_t *fstyle,
*actual_x = MIN(*actual_x, (int)current);
*char_offset = index;
- return true;
+ return NSERROR_OK;
}
@@ -285,95 +365,10 @@ bool nsfont_paint(const plot_font_style_t *fstyle,
}
-/**
- * Convert a font style to a PangoFontDescription.
- *
- * \param font Beos font object.
- * \param fstyle style for this text
- */
-void nsbeos_style_to_font(BFont &font, const plot_font_style_t *fstyle)
-{
- float size;
- uint16 face = 0;
- const char *family;
-
- switch (fstyle->family) {
- case PLOT_FONT_FAMILY_SERIF:
- family = nsoption_charp(font_serif);
- break;
- case PLOT_FONT_FAMILY_MONOSPACE:
- family = nsoption_charp(font_mono);
- break;
- case PLOT_FONT_FAMILY_CURSIVE:
- family = nsoption_charp(font_cursive);
- break;
- case PLOT_FONT_FAMILY_FANTASY:
- family = nsoption_charp(font_fantasy);
- break;
- case PLOT_FONT_FAMILY_SANS_SERIF:
- default:
- family = nsoption_charp(font_sans);
- break;
- }
-
- if ((fstyle->flags & FONTF_ITALIC)) {
- face = B_ITALIC_FACE;
- } else if ((fstyle->flags & FONTF_OBLIQUE)) {
- face = B_ITALIC_FACE;
- // XXX: no OBLIQUE flag ??
- // maybe find "Oblique" style
- // or use SetShear() ?
- }
-
-#ifndef __HAIKU__XXX
- if (fstyle->weight >= 600) {
- face |= B_BOLD_FACE;
- }
-#else
- if (fstyle->weight >= 600) {
- if (fstyle->weight >= 800)
- face |= B_HEAVY_FACE;
- else
- face |= B_BOLD_FACE;
- } else if (fstyle->weight <= 300) {
- face |= B_LIGHT_FACE;
- }
-#endif
-/*
- case CSS_FONT_WEIGHT_100: weight = 100; break;
- case CSS_FONT_WEIGHT_200: weight = 200; break;
- case CSS_FONT_WEIGHT_300: weight = 300; break;
- case CSS_FONT_WEIGHT_400: weight = 400; break;
- case CSS_FONT_WEIGHT_500: weight = 500; break;
- case CSS_FONT_WEIGHT_600: weight = 600; break;
- case CSS_FONT_WEIGHT_700: weight = 700; break;
- case CSS_FONT_WEIGHT_800: weight = 800; break;
- case CSS_FONT_WEIGHT_900: weight = 900; break;
-*/
-
- if (!face)
- face = B_REGULAR_FACE;
-
-//fprintf(stderr, "nsbeos_style_to_font: %d, %d, %d -> '%s' %04x\n", style->font_family, style->font_style, style->font_weight, family, face);
-
- if (family) {
- font_family beos_family;
-
- strncpy(beos_family, family, B_FONT_FAMILY_LENGTH);
- // Ensure it's terminated
- beos_family[B_FONT_FAMILY_LENGTH] = '\0';
-
- font.SetFamilyAndFace(beos_family, face);
- } else {
- //XXX not used
- font = be_plain_font;
- font.SetFace(face);
- }
-
-//fprintf(stderr, "nsbeos_style_to_font: value %f unit %d\n", style->font_size.value.length.value, style->font_size.value.length.unit);
- size = fstyle->size / FONT_SIZE_SCALE;
-
-//fprintf(stderr, "nsbeos_style_to_font: %f %d\n", size, style->font_size.value.length.unit);
+static struct gui_layout_table layout_table = {
+ /*.width = */beos_font_width,
+ /*.position = */beos_font_position,
+ /*.split = */beos_font_split
+};
- font.SetSize(size);
-}
+struct gui_layout_table *beos_layout_table = &layout_table;
diff --git a/beos/font.h b/beos/font.h
index aefd898..75f0c3a 100644
--- a/beos/font.h
+++ b/beos/font.h
@@ -17,9 +17,12 @@
*/
/** \file
- * Font handling (GTK interface).
+ * Beos font layout handling interface.
*/
+#ifndef NS_BEOS_FONT_H
+#define NS_BEOS_FONT_H
+
#include <stdbool.h>
#include "desktop/plotters.h"
@@ -28,4 +31,8 @@ bool nsfont_paint(const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, int y);
-void nsbeos_style_to_font(BFont &font, const plot_font_style_t *fstyle);
+void nsbeos_style_to_font(BFont &font, const struct plot_font_style *fstyle);
+
+extern struct gui_layout_table *beos_layout_table;
+
+#endif
diff --git a/beos/gui.cpp b/beos/gui.cpp
index 1e653a0..fde0495 100644
--- a/beos/gui.cpp
+++ b/beos/gui.cpp
@@ -82,6 +82,7 @@ extern "C" {
#include "beos/fetch_rsrc.h"
#include "beos/scaffolding.h"
#include "beos/bitmap.h"
+#include "beos/font.h"
//TODO: use resources
// enable using resources instead of files
@@ -112,6 +113,29 @@ static int sEventPipe[2];
// #pragma mark - class NSBrowserFrameView
+/**
+ * Display a warning for a serious problem (eg memory exhaustion).
+ *
+ * \param warning message key for warning message
+ * \param detail additional message, or 0
+ */
+static nserror beos_warn_user(const char *warning, const char *detail)
+{
+ LOG("warn_user: %s (%s)", warning, detail);
+ BAlert *alert;
+ BString text(warning);
+ if (detail)
+ text << ":\n" << detail;
+
+ alert = new BAlert("NetSurf Warning", text.String(), "Debug", "Ok",
+ NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
+ if (alert->Go() < 1) {
+ debugger("warn_user");
+ }
+
+ return NSERROR_OK;
+}
+
NSBrowserApplication::NSBrowserApplication()
: BApplication("application/x-vnd.NetSurf")
{
@@ -671,7 +695,7 @@ static void gui_init(int argc, char** argv)
nsurl_unref(url);
}
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ beos_warn_user(messages_get_errorcode(error), 0);
}
if (gFirstRefsReceived) {
@@ -803,7 +827,7 @@ void nsbeos_gui_view_source(struct hlcache_handle *content)
const char *source = content_get_source_data(content, &size);
if (!content || !source) {
- warn_user("MiscError", "No document source");
+ beos_warn_user("MiscError", "No document source");
return;
}
@@ -825,7 +849,7 @@ void nsbeos_gui_view_source(struct hlcache_handle *content)
* filename. */
const char *filename = filename_request();
if (!filename) {
- warn_user("NoMemory", 0);
+ beos_warn_user("NoMemory", 0);
return;
}
path.SetTo(TEMP_FILENAME_PREFIX);
@@ -833,12 +857,12 @@ void nsbeos_gui_view_source(struct hlcache_handle *content)
BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE);
err = file.InitCheck();
if (err < B_OK) {
- warn_user("IOError", strerror(err));
+ beos_warn_user("IOError", strerror(err));
return;
}
err = file.Write(source, size);
if (err < B_OK) {
- warn_user("IOError", strerror(err));
+ beos_warn_user("IOError", strerror(err));
return;
}
lwc_string *mime = content_get_mime_type(content);
@@ -908,31 +932,11 @@ static nserror gui_launch_url(struct nsurl *url)
char *args[2] = { (char *)nsurl_access(url), NULL };
status = be_roster->Launch(mimeType.String(), 1, args);
if (status < B_OK)
- warn_user("Cannot launch url", strerror(status));
+ beos_warn_user("Cannot launch url", strerror(status));
return NSERROR_OK;
}
-/**
- * Display a warning for a serious problem (eg memory exhaustion).
- *
- * \param warning message key for warning message
- * \param detail additional message, or 0
- */
-
-void warn_user(const char *warning, const char *detail)
-{
- LOG("warn_user: %s (%s)", warning, detail);
- BAlert *alert;
- BString text(warning);
- if (detail)
- text << ":\n" << detail;
-
- alert = new BAlert("NetSurf Warning", text.String(), "Debug", "Ok", NULL,
- B_WIDTH_AS_USUAL, B_WARNING_ALERT);
- if (alert->Go() < 1)
- debugger("warn_user");
-}
void die(const char * const error)
{
@@ -962,13 +966,13 @@ static struct gui_fetch_table beos_fetch_table = {
NULL, // fetch_mimetype
};
-static struct gui_browser_table beos_browser_table = {
+static struct gui_misc_table beos_misc_table = {
beos_schedule,
+ beos_warn_user,
gui_quit,
gui_launch_url,
NULL, //cert_verify
gui_401login_open,
- NULL, // warning
NULL, // pdf_password (if we have Haru support)
};
@@ -979,7 +983,7 @@ int main(int argc, char** argv)
nserror ret;
BPath options;
struct netsurf_table beos_table = {
- &beos_browser_table,
+ &beos_misc_table,
beos_window_table,
beos_download_table,
&beos_clipboard_table,
@@ -989,7 +993,8 @@ int main(int argc, char** argv)
NULL, /* default search */
NULL, /* default web search */
NULL, /* default low level cache persistant storage */
- beos_bitmap_table
+ beos_bitmap_table,
+ beos_layout_table
};
ret = netsurf_register(&beos_table);
@@ -1059,7 +1064,7 @@ int gui_init_replicant(int argc, char** argv)
nserror ret;
BPath options;
struct netsurf_table beos_table = {
- &beos_browser_table,
+ &beos_misc_table,
beos_window_table,
beos_download_table,
&beos_clipboard_table,
@@ -1069,7 +1074,8 @@ int gui_init_replicant(int argc, char** argv)
NULL, /* default search */
NULL, /* default web search */
NULL, /* default low level cache persistant storage */
- beos_bitmap_table
+ beos_bitmap_table,
+ beos_layout_table
};
ret = netsurf_register(&beos_table);
diff --git a/beos/plotters.cpp b/beos/plotters.cpp
index f63d734..b7d1a2b 100644
--- a/beos/plotters.cpp
+++ b/beos/plotters.cpp
@@ -32,7 +32,6 @@
#include <Shape.h>
extern "C" {
#include "desktop/plotters.h"
-#include "desktop/font.h"
#include "utils/log.h"
#include "utils/utils.h"
#include "utils/nsoption.h"
diff --git a/beos/scaffolding.cpp b/beos/scaffolding.cpp
index 61e5f13..d189e9a 100644
--- a/beos/scaffolding.cpp
+++ b/beos/scaffolding.cpp
@@ -62,7 +62,6 @@ extern "C" {
#include "desktop/plotters.h"
#include "utils/nsoption.h"
#include "desktop/textinput.h"
-#include "desktop/font.h"
#include "render/form.h"
#include "utils/messages.h"
#include "utils/utils.h"
diff --git a/beos/window.cpp b/beos/window.cpp
index ebf250a..23ae283 100644
--- a/beos/window.cpp
+++ b/beos/window.cpp
@@ -19,6 +19,7 @@
*/
#define __STDBOOL_H__ 1
+#include <stdlib.h>
#include <assert.h>
extern "C" {
#include "content/content.h"
@@ -27,7 +28,6 @@ extern "C" {
#include "desktop/mouse.h"
#include "utils/nsoption.h"
#include "desktop/textinput.h"
-#include "desktop/font.h"
#include "utils/log.h"
#include "utils/utf8.h"
#include "utils/utils.h"
diff --git a/cocoa/Makefile.target b/cocoa/Makefile.target
index ad2d917..615c007 100644
--- a/cocoa/Makefile.target
+++ b/cocoa/Makefile.target
@@ -40,9 +40,7 @@ CFLAGS += -Dnscocoa -D_BSD_SOURCE -D_POSIX_C_SOURCE -std=c99 -g -Os
CFLAGS += -I/usr/X11/include
CFLAGS += -include cocoa/Prefix.pch
-# VERSION_FULL := $(shell sed -n '/\"/{s/.*"\(.*\)\".*/\1/;p;}' desktop/version.c)
-# TODO: this needs fixing properly everywhere
-VERSION_FULL := "3.4 (Dev)"
+VERSION_FULL := $(shell sed -n '/_version.*=.*"/{s/.*"\(.*\)".*/\1/;p;}' desktop/version.c)
VERSION_MAJ := $(shell sed -n '/_major/{s/.* = \([0-9]*\).*/\1/;p;}' desktop/version.c)
VERSION_MIN := $(shell sed -n '/_minor/{s/.* = \([0-9]*\).*/\1/;p;}' desktop/version.c)
@@ -96,7 +94,6 @@ S_COCOA := \
plotter.m \
schedule.m \
selection.m \
- utils.m \
ArrowBox.m \
ArrowWindow.m \
BlackScroller.m \
diff --git a/cocoa/NetsurfApp.m b/cocoa/NetsurfApp.m
index 034ffda..ec798be 100644
--- a/cocoa/NetsurfApp.m
+++ b/cocoa/NetsurfApp.m
@@ -25,6 +25,7 @@
#import "cocoa/selection.h"
#import "cocoa/fetch.h"
#import "cocoa/bitmap.h"
+#import "cocoa/font.h"
#import "utils/filename.h"
#import "utils/log.h"
@@ -228,13 +229,14 @@ int main( int argc, char **argv )
nsurl *url;
nserror error;
struct netsurf_table cocoa_table = {
- .browser = cocoa_browser_table,
+ .misc = cocoa_misc_table,
.window = cocoa_window_table,
.clipboard = cocoa_clipboard_table,
.download = cocoa_download_table,
.fetch = cocoa_fetch_table,
.search = cocoa_search_table,
.bitmap = cocoa_bitmap_table,
+ .layout = cocoa_layout_table,
};
error = netsurf_register(&cocoa_table);
diff --git a/cocoa/apple_image.m b/cocoa/apple_image.m
index 91dfcb4..8261e8b 100644
--- a/cocoa/apple_image.m
+++ b/cocoa/apple_image.m
@@ -48,7 +48,7 @@ static void *apple_image_get_internal(const struct content *c, void *context)
}
static nserror apple_image_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c)
{
diff --git a/cocoa/font.h b/cocoa/font.h
index 2a31e2c..cabd2b9 100644
--- a/cocoa/font.h
+++ b/cocoa/font.h
@@ -21,6 +21,8 @@
#import "desktop/plot_style.h"
-void cocoa_draw_string( CGFloat x, CGFloat y, const char *bytes, size_t length, const plot_font_style_t *style );
+void cocoa_draw_string( CGFloat x, CGFloat y, const char *bytes, size_t length, const struct plot_font_style *style );
+
+struct gui_layout_table *cocoa_layout_table;
#endif
diff --git a/cocoa/font.m b/cocoa/font.m
index 338339b..f52ec85 100644
--- a/cocoa/font.m
+++ b/cocoa/font.m
@@ -22,7 +22,7 @@
#import "cocoa/font.h"
#import "utils/nsoption.h"
-#import "desktop/font.h"
+#import "desktop/gui_layout.h"
#import "desktop/plotters.h"
@@ -38,21 +38,24 @@ static NSDictionary *cocoa_font_attributes( const plot_font_style_t *style );
static NSTextStorage *cocoa_text_storage = nil;
static NSTextContainer *cocoa_text_container = nil;
-static bool nsfont_width(const plot_font_style_t *style,
- const char *string, size_t length,
- int *width)
+static nserror cocoa_font_width(const plot_font_style_t *style,
+ const char *string, size_t length,
+ int *width)
{
- NSLayoutManager *layout = cocoa_prepare_layout_manager( string, length, style );
+ NSLayoutManager *layout;
+ layout = cocoa_prepare_layout_manager( string, length, style );
*width = cocoa_layout_width( layout );
- return true;
+ return NSERROR_OK;
}
-static bool nsfont_position_in_string(const plot_font_style_t *style,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x)
+static nserror cocoa_font_position(const plot_font_style_t *style,
+ const char *string, size_t length,
+ int x, size_t *char_offset, int *actual_x)
{
NSLayoutManager *layout = cocoa_prepare_layout_manager( string, length, style );
- if (layout == nil) return false;
+ if (layout == nil) {
+ return NSERROR_BAD_PARAMETER;
+ }
NSUInteger glyphIndex = cocoa_glyph_for_location( layout, x );
NSUInteger chars = [layout characterIndexForGlyphAtIndex: glyphIndex];
@@ -61,17 +64,17 @@ static bool nsfont_position_in_string(const plot_font_style_t *style,
else *char_offset = cocoa_bytes_for_characters( string, chars );
*actual_x = cocoa_pt_to_px( NSMaxX( [layout boundingRectForGlyphRange: NSMakeRange( glyphIndex - 1, 1 )
- inTextContainer: cocoa_text_container] ) );
+ inTextContainer: cocoa_text_container] ) );
- return true;
+ return NSERROR_OK;
}
-static bool nsfont_split(const plot_font_style_t *style,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x)
+static nserror cocoa_font_split(const plot_font_style_t *style,
+ const char *string, size_t length,
+ int x, size_t *char_offset, int *actual_x)
{
NSLayoutManager *layout = cocoa_prepare_layout_manager( string, length, style );
- if (layout == nil) return false;
+ if (layout == nil) return NSERROR_BAD_PARAMETER;
NSUInteger glyphIndex = cocoa_glyph_for_location( layout, x );
NSUInteger chars = [layout characterIndexForGlyphAtIndex: glyphIndex];
@@ -79,7 +82,7 @@ static bool nsfont_split(const plot_font_style_t *style,
if (chars >= [cocoa_text_storage length]) {
*char_offset = length;
*actual_x = cocoa_layout_width( layout );
- return true;
+ return NSERROR_OK;
}
@@ -87,21 +90,25 @@ static bool nsfont_split(const plot_font_style_t *style,
if (chars == NSNotFound) {
*char_offset = 0;
*actual_x = 0;
- return true;
+ return NSERROR_OK;
}
*char_offset = cocoa_bytes_for_characters( string, chars );
*actual_x = cocoa_layout_width_chars( layout, chars );
- return true;
+ return NSERROR_OK;
}
-const struct font_functions nsfont = {
- nsfont_width,
- nsfont_position_in_string,
- nsfont_split
+
+static struct gui_layout_table layout_table = {
+ .width = cocoa_font_width,
+ .position = cocoa_font_position,
+ .split = cocoa_font_split,
};
+struct gui_layout_table *cocoa_layout_table = &layout_table;
+
+
#pragma mark -
void cocoa_draw_string( CGFloat x, CGFloat y, const char *bytes, size_t length, const plot_font_style_t *style )
diff --git a/cocoa/gui.h b/cocoa/gui.h
index 7571400..b0ff648 100644
--- a/cocoa/gui.h
+++ b/cocoa/gui.h
@@ -20,7 +20,7 @@
extern struct gui_window_table *cocoa_window_table;
extern struct gui_clipboard_table *cocoa_clipboard_table;
-extern struct gui_browser_table *cocoa_browser_table;
+extern struct gui_misc_table *cocoa_misc_table;
extern NSString * const kCookiesFileOption;
extern NSString * const kURLsFileOption;
diff --git a/cocoa/gui.m b/cocoa/gui.m
index 0cd3d80..78b4147 100644
--- a/cocoa/gui.m
+++ b/cocoa/gui.m
@@ -52,6 +52,17 @@ NSString * const kAlwaysCloseMultipleTabs = @"AlwaysCloseMultipleTabs";
struct browser_window;
+static nserror cocoa_warn_user(const char *warning, const char *detail)
+{
+ NSRunAlertPanel( NSLocalizedString( @"Warning", @"Warning title" ),
+ NSLocalizedString( @"Warning %s%s%s", @"Warning message" ),
+ NSLocalizedString( @"OK", @"" ), nil, nil,
+ warning, detail != NULL ? ": " : "",
+ detail != NULL ? detail : "" );
+ return NSERROR_OK;
+}
+
+
static struct gui_window *
gui_window_create(struct browser_window *bw,
struct gui_window *existing,
@@ -279,7 +290,7 @@ static struct gui_window_table window_table = {
.set_scroll = gui_window_set_scroll,
.get_dimensions = gui_window_get_dimensions,
.update_extent = gui_window_update_extent,
- .reformat = cocoa_window_reformat,
+ .reformat = cocoa_window_reformat,
.set_title = gui_window_set_title,
.set_url = gui_window_set_url,
@@ -288,7 +299,7 @@ static struct gui_window_table window_table = {
.set_pointer = gui_window_set_pointer,
.place_caret = gui_window_place_caret,
.remove_caret = gui_window_remove_caret,
- .new_content = gui_window_new_content,
+ .new_content = gui_window_new_content,
.start_throbber = gui_window_start_throbber,
.stop_throbber = gui_window_stop_throbber,
.create_form_select_menu = gui_create_form_select_menu,
@@ -297,11 +308,12 @@ static struct gui_window_table window_table = {
struct gui_window_table *cocoa_window_table = &window_table;
-static struct gui_browser_table browser_table = {
- .schedule = cocoa_schedule,
+static struct gui_misc_table browser_table = {
+ .schedule = cocoa_schedule,
+ .warning = cocoa_warn_user,
.launch_url = gui_launch_url,
.cert_verify = gui_cert_verify,
};
-struct gui_browser_table *cocoa_browser_table = &browser_table;
+struct gui_misc_table *cocoa_misc_table = &browser_table;
diff --git a/cocoa/utils.m b/cocoa/utils.m
deleted file mode 100644
index 2c73e9b..0000000
--- a/cocoa/utils.m
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2011 Sven Weidauer <sven.weidauer(a)gmail.com>
- *
- * This file is part of NetSurf, http://www.netsurf-browser.org/
- *
- * NetSurf is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * NetSurf is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#import <Cocoa/Cocoa.h>
-
-#import "utils/utils.h"
-
-void warn_user(const char *warning, const char *detail)
-{
- NSRunAlertPanel( NSLocalizedString( @"Warning", @"Warning title" ),
- NSLocalizedString( @"Warning %s%s%s", @"Warning message" ),
- NSLocalizedString( @"OK", @"" ), nil, nil,
- warning, detail != NULL ? ": " : "",
- detail != NULL ? detail : "" );
-}
diff --git a/content/content.c b/content/content.c
index 3d06f8e..e112f38 100644
--- a/content/content.c
+++ b/content/content.c
@@ -16,33 +16,27 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
+/**
+ * \file
* Content handling implementation.
*/
-#include <assert.h>
#include <inttypes.h>
-#include <stdarg.h>
-#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <time.h>
+#include <nsutils/time.h>
-#include "utils/config.h"
-#include "content/content_protected.h"
-#include "content/hlcache.h"
-#include "image/bitmap.h"
-#include "desktop/knockout.h"
-#include "desktop/browser.h"
+#include "utils/utils.h"
+#include "utils/log.h"
+#include "utils/messages.h"
#include "desktop/plotters.h"
+#include "desktop/knockout.h"
#include "desktop/gui_internal.h"
-#include "utils/nsoption.h"
+#include "desktop/browser.h"
+#include "image/bitmap.h"
-#include "utils/http.h"
-#include "utils/log.h"
-#include "utils/messages.h"
-#include "utils/utils.h"
+#include "content/content_protected.h"
+#include "content/content_debug.h"
+#include "content/hlcache.h"
#define URL_FMT_SPC "%.140s"
@@ -72,7 +66,7 @@ static void content_convert(struct content *c);
*/
nserror content__init(struct content *c, const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks)
{
@@ -103,7 +97,7 @@ nserror content__init(struct content *c, const content_handler *handler,
c->available_width = 0;
c->quirks = quirks;
c->refresh = 0;
- c->time = wallclock();
+ nsu_getmonotonic_ms(&c->time);
c->size = 0;
c->title = NULL;
c->active = 0;
@@ -222,10 +216,9 @@ static void content_update_status(struct content *c)
c->sub_status[0] != '\0' ? ", " : " ",
c->sub_status);
} else {
- unsigned int time = c->time;
snprintf(c->status_message, sizeof (c->status_message),
"%s (%.1fs)", messages_get("Done"),
- (float) time / 100);
+ (float) c->time / 1000);
}
}
@@ -318,9 +311,12 @@ void content_set_ready(struct content *c)
void content_set_done(struct content *c)
{
union content_msg_data msg_data;
+ uint64_t now_ms;
+
+ nsu_getmonotonic_ms(&now_ms);
c->status = CONTENT_STATUS_DONE;
- c->time = wallclock() - c->time;
+ c->time = now_ms - c->time;
content_update_status(c);
content_broadcast(c, CONTENT_MSG_DONE, msg_data);
}
diff --git a/content/content.h b/content/content.h
index 6c05df9..cdd7283 100644
--- a/content/content.h
+++ b/content/content.h
@@ -26,19 +26,14 @@
#ifndef _NETSURF_CONTENT_CONTENT_H_
#define _NETSURF_CONTENT_CONTENT_H_
-#include <stdbool.h>
-#include <stdio.h>
-
#include <libwapcaplet/libwapcaplet.h>
-#include "utils/config.h"
#include "utils/errors.h"
-#include "utils/http.h"
#include "content/content_factory.h"
#include "content/content_type.h"
-#include "desktop/search.h"
-#include "desktop/mouse.h"
-#include "desktop/plot_style.h"
+#include "desktop/search.h" /* search flags enum */
+#include "desktop/mouse.h" /* mouse state enums */
+#include "desktop/plot_style.h" /* color typedef */
struct browser_window;
struct browser_window_features;
@@ -318,15 +313,6 @@ void content_search(struct hlcache_handle *h, void *context,
void content_search_clear(struct hlcache_handle *h);
/**
- * Dump debug information to file.
- *
- * \param h content handle to debug.
- * \param f File to write output to.
- * \param op Debug operation type.
- */
-nserror content_debug_dump(struct hlcache_handle *h, FILE *f, enum content_debug op);
-
-/**
* Control debug con a content.
*
* \param h content handle to debug.
diff --git a/desktop/version.c b/content/content_debug.h
similarity index 64%
copy from desktop/version.c
copy to content/content_debug.h
index e456aac..b08f730 100644
--- a/desktop/version.c
+++ b/content/content_debug.h
@@ -16,15 +16,23 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "testament.h"
+/**
+ * \file
+ * Interface to content handling debug.
+ */
+
+#ifndef _NETSURF_CONTENT_CONTENT_DEBUG_H_
+#define _NETSURF_CONTENT_CONTENT_DEBUG_H_
+
+#include <stdio.h>
-#include "desktop/version.h"
+/**
+ * Dump debug information to file.
+ *
+ * \param h content handle to debug.
+ * \param f File to write output to.
+ * \param op Debug operation type.
+ */
+nserror content_debug_dump(struct hlcache_handle *h, FILE *f, enum content_debug op);
-const char * const netsurf_version = "3.5 (Dev"
-#if defined(CI_BUILD)
- " CI #" CI_BUILD
#endif
- ")"
- ;
-const int netsurf_version_major = 3;
-const int netsurf_version_minor = 4;
diff --git a/content/content_factory.c b/content/content_factory.c
index 8da7333..2242207 100644
--- a/content/content_factory.c
+++ b/content/content_factory.c
@@ -24,6 +24,8 @@
#include <stdlib.h>
#include <string.h>
+#include "utils/http.h"
+
#include "content/content.h"
#include "content/content_factory.h"
#include "content/content_protected.h"
diff --git a/content/content_factory.h b/content/content_factory.h
index 94de376..22205dc 100644
--- a/content/content_factory.h
+++ b/content/content_factory.h
@@ -25,7 +25,6 @@
#include "content/content_type.h"
#include "utils/errors.h"
-#include "utils/utils.h"
#define CONTENT_FACTORY_REGISTER_TYPES(HNAME, HTYPELIST, HHANDLER) \
\
diff --git a/content/content_protected.h b/content/content_protected.h
index e5ff1ca..fb810bd 100644
--- a/content/content_protected.h
+++ b/content/content_protected.h
@@ -28,6 +28,8 @@
#include <stdint.h>
#include <time.h>
+#include <stdio.h>
+
#include "utils/config.h"
#include "content/content.h"
#include "content/content_factory.h"
@@ -38,15 +40,17 @@ struct bitmap;
struct content;
struct rect;
struct redraw_context;
+struct http_parameter;
struct content_handler {
void (*fini)(void);
nserror (*create)(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
- llcache_handle *llcache,
- const char *fallback_charset, bool quirks,
- struct content **c);
+ lwc_string *imime_type,
+ const struct http_parameter *params,
+ llcache_handle *llcache,
+ const char *fallback_charset, bool quirks,
+ struct content **c);
bool (*process_data)(struct content *c,
const char *data, unsigned int size);
@@ -104,7 +108,7 @@ struct content_user
/** Corresponds to a single URL. */
struct content {
- llcache_handle *llcache; /**< Low-level cache object */
+ llcache_handle *llcache; /**< Low-level cache object */
lwc_string *mime_type; /**< Original MIME type of data */
@@ -122,13 +126,14 @@ struct content {
struct content_rfc5988_link *links; /**< list of metadata links */
- unsigned int time; /**< Creation time,
- if LOADING or READY,
- otherwise total time. */
+ /** Creation timestamp when LOADING or READY.
+ * Total time in ms when DONE.
+ */
+ uint64_t time;
- unsigned int reformat_time; /**< Earliest time to attempt a
- period reflow while fetching a
- page's objects. */
+ uint64_t reformat_time; /**< Earliest time to attempt a period
+ * reflow while fetching a page's objects.
+ */
unsigned int size; /**< Estimated size of all data
associated with this content */
@@ -157,7 +162,7 @@ extern const char * const content_type_name[];
extern const char * const content_status_name[];
nserror content__init(struct content *c, const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
struct llcache_handle *llcache, const char *fallback_charset,
bool quirks);
nserror content__clone(const struct content *c, struct content *nc);
diff --git a/content/fetch.c b/content/fetch.c
index 47e6fc8..9c2933b 100644
--- a/content/fetch.c
+++ b/content/fetch.c
@@ -31,6 +31,7 @@
* fetches are stored in the ::queue_ring waiting for use.
*/
+#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <stdbool.h>
@@ -277,7 +278,7 @@ static void fetcher_poll(void *unused)
}
/* schedule active fetchers to run again in 10ms */
- guit->browser->schedule(SCHEDULE_TIME, fetcher_poll, NULL);
+ guit->misc->schedule(SCHEDULE_TIME, fetcher_poll, NULL);
}
}
@@ -428,7 +429,7 @@ nserror fetcher_fdset(fd_set *read_fd_set,
* select on. All the other fetchers continue to need
* polling frequently.
*/
- guit->browser->schedule(FDSET_TIMEOUT, fetcher_poll, NULL);
+ guit->misc->schedule(FDSET_TIMEOUT, fetcher_poll, NULL);
}
*maxfd_out = maxfd;
@@ -565,7 +566,7 @@ fetch_start(nsurl *url,
if (fetch_dispatch_jobs()) {
FETCH_LOG("scheduling poll");
/* schedule active fetchers to run again in 10ms */
- guit->browser->schedule(10, fetcher_poll, NULL);
+ guit->misc->schedule(10, fetcher_poll, NULL);
}
*fetch_out = fetch;
diff --git a/content/fetchers.h b/content/fetchers.h
index c8f8300..92b11dc 100644
--- a/content/fetchers.h
+++ b/content/fetchers.h
@@ -25,7 +25,7 @@
#ifndef _NETSURF_DESKTOP_FETCHERS_H_
#define _NETSURF_DESKTOP_FETCHERS_H_
-#include "utils/config.h"
+#include "utils/inet.h" /* this is necessary for the fd_set definition */
#include <libwapcaplet/libwapcaplet.h>
struct nsurl;
diff --git a/content/fetchers/about.c b/content/fetchers/about.c
index eeea3d9..605d3a8 100644
--- a/content/fetchers/about.c
+++ b/content/fetchers/about.c
@@ -16,7 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file content/fetchers/about.c
+/**
+ * \file
*
* URL handling for the "about" scheme.
*
@@ -25,39 +26,24 @@
* information from the browser from a known, fixed URL.
*/
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <assert.h>
-#include <errno.h>
-#include <stdbool.h>
-#include <inttypes.h>
+#include <stdlib.h>
#include <string.h>
-#include <strings.h>
-#include <time.h>
#include <stdio.h>
-#include <dirent.h>
-#include <limits.h>
#include <stdarg.h>
-#include <libwapcaplet/libwapcaplet.h>
-
#include "testament.h"
+#include "utils/corestrings.h"
+#include "utils/nsoption.h"
+#include "utils/utils.h"
+#include "utils/ring.h"
-#include "utils/config.h"
#include "content/fetch.h"
#include "content/fetchers.h"
#include "content/fetchers/about.h"
-#include "content/urldb.h"
-#include "utils/nsoption.h"
-#include "utils/corestrings.h"
-#include "utils/log.h"
-#include "utils/messages.h"
-#include "utils/utils.h"
-#include "utils/ring.h"
+#include "content/content_type.h"
#include "image/image_cache.h"
+
struct fetch_about_context;
typedef bool (*fetch_about_handler)(struct fetch_about_context *);
diff --git a/content/fetchers/curl.c b/content/fetchers/curl.c
index 88c8bbe..b94a3f2 100644
--- a/content/fetchers/curl.c
+++ b/content/fetchers/curl.c
@@ -27,7 +27,8 @@
* The CURL handles are cached in the curl_handle_ring.
*/
-#include "utils/config.h"
+/* must come first to ensure winsock2.h vs windows.h ordering issues */
+#include "utils/inet.h"
#include <assert.h>
#include <errno.h>
@@ -40,6 +41,7 @@
#include <openssl/ssl.h>
#include <libwapcaplet/libwapcaplet.h>
+#include <nsutils/time.h>
#include "utils/corestrings.h"
#include "utils/nsoption.h"
@@ -49,7 +51,9 @@
#include "utils/ring.h"
#include "utils/useragent.h"
#include "utils/file.h"
+#include "utils/string.h"
#include "desktop/gui_fetch.h"
+#include "desktop/gui_misc.h"
#include "desktop/gui_internal.h"
#include "content/fetch.h"
@@ -57,6 +61,8 @@
#include "content/fetchers/curl.h"
#include "content/urldb.h"
+/** maximum number of progress notifications per second */
+#define UPDATES_PER_SECOND 2
/** SSL certificate info */
struct cert_info {
@@ -85,7 +91,7 @@ struct curl_fetch_info {
struct curl_httppost *post_multipart; /**< Multipart post data, or 0. */
#define MAX_CERTS 10
struct cert_info cert_data[MAX_CERTS]; /**< HTTPS certificate data */
- unsigned int last_progress_update; /**< Time of last progress update */
+ uint64_t last_progress_update; /**< Time of last progress update */
};
struct cache_handle {
@@ -756,8 +762,7 @@ static bool fetch_curl_process_headers(struct curl_fetch_info *f)
f->had_headers = true;
- if (!f->http_code)
- {
+ if (!f->http_code) {
code = curl_easy_getinfo(f->curl_handle, CURLINFO_HTTP_CODE,
&f->http_code);
fetch_set_http_code(f->fetch_handle, f->http_code);
@@ -1049,7 +1054,7 @@ static void fetch_curl_poll(lwc_string *scheme_ignored)
codem = curl_multi_perform(fetch_curl_multi, &running);
if (codem != CURLM_OK && codem != CURLM_CALL_MULTI_PERFORM) {
LOG("curl_multi_perform: %i %s", codem, curl_multi_strerror(codem));
- warn_user("MiscError", curl_multi_strerror(codem));
+ guit->misc->warning("MiscError", curl_multi_strerror(codem));
return;
}
} while (codem == CURLM_CALL_MULTI_PERFORM);
@@ -1081,24 +1086,24 @@ static int fetch_curl_progress(void *clientp, double dltotal, double dlnow,
{
static char fetch_progress_buffer[256]; /**< Progress buffer for cURL */
struct curl_fetch_info *f = (struct curl_fetch_info *) clientp;
- unsigned int time_now_cs;
+ uint64_t time_now_ms;
fetch_msg msg;
- if (f->abort)
+ if (f->abort) {
return 0;
+ }
msg.type = FETCH_PROGRESS;
msg.data.progress = fetch_progress_buffer;
- /* Rate limit each fetch's progress notifications to 2 a second */
-#define UPDATES_PER_SECOND 2
-#define UPDATE_DELAY_CS (100 / UPDATES_PER_SECOND)
- time_now_cs = wallclock();
- if (time_now_cs - f->last_progress_update < UPDATE_DELAY_CS)
+ /* Rate limit each fetch's progress notifications */
+ nsu_getmonotonic_ms(&time_now_ms);
+#define UPDATE_DELAY_MS (1000 / UPDATES_PER_SECOND)
+ if (time_now_ms - f->last_progress_update < UPDATE_DELAY_MS) {
return 0;
- f->last_progress_update = time_now_cs;
-#undef UPDATE_DELAY_CS
-#undef UPDATES_PERS_SECOND
+ }
+#undef UPDATE_DELAY_MS
+ f->last_progress_update = time_now_ms;
if (dltotal > 0) {
snprintf(fetch_progress_buffer, 255,
diff --git a/content/fetchers/data.c b/content/fetchers/data.c
index 6c18911..84d0aa3 100644
--- a/content/fetchers/data.c
+++ b/content/fetchers/data.c
@@ -16,32 +16,28 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* data: URL handling. See http://tools.ietf.org/html/rfc2397 */
+/**
+ * \file
+ * data scheme handling. See http://tools.ietf.org/html/rfc2397
+ */
-#include <assert.h>
-#include <errno.h>
#include <stdbool.h>
#include <string.h>
-#include <strings.h>
-#include <time.h>
-
-#include <curl/curl.h> /* for URL unescaping functions */
-
+#include <stdlib.h>
+#include <curl/curl.h> /* for URL unescaping functions */
#include <libwapcaplet/libwapcaplet.h>
-#include "utils/config.h"
-#include "content/fetch.h"
-#include "content/fetchers.h"
-#include "content/fetchers/data.h"
-#include "content/urldb.h"
+#include "utils/nsurl.h"
#include "utils/corestrings.h"
-#include "utils/nsoption.h"
#include "utils/log.h"
-#include "utils/messages.h"
#include "utils/utils.h"
#include "utils/ring.h"
#include "utils/base64.h"
+#include "content/fetch.h"
+#include "content/fetchers.h"
+#include "content/fetchers/data.h"
+
struct fetch_data_context {
struct fetch *parent_fetch;
char *url;
diff --git a/content/fetchers/file.c b/content/fetchers/file.c
index c2f8bed..8cfe3a0 100644
--- a/content/fetchers/file.c
+++ b/content/fetchers/file.c
@@ -24,32 +24,27 @@
#include "utils/config.h"
+#include <stdlib.h>
+#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
-#include <assert.h>
#include <errno.h>
#include <stdbool.h>
-#include <inttypes.h>
#include <string.h>
#include <strings.h>
#include <time.h>
#include <stdio.h>
-#include <dirent.h>
-#include <limits.h>
#include <stdarg.h>
-
#ifdef HAVE_MMAP
#include <sys/mman.h>
#endif
-
#include <libwapcaplet/libwapcaplet.h>
+#include "utils/nsurl.h"
+#include "utils/dirent.h"
#include "utils/corestrings.h"
-#include "utils/nsoption.h"
-#include "utils/errors.h"
-#include "utils/log.h"
#include "utils/messages.h"
#include "utils/utils.h"
#include "utils/ring.h"
@@ -60,7 +55,6 @@
#include "content/dirlist.h"
#include "content/fetch.h"
#include "content/fetchers.h"
-#include "content/urldb.h"
#include "content/fetchers/file.h"
/* Maximum size of read buffer */
@@ -601,6 +595,48 @@ process_dir_ent(struct fetch_file_context *ctx,
return NSERROR_OK;
}
+/**
+ * Comparison function for sorting directories.
+ *
+ * Correctly orders non zero-padded numerical parts.
+ * ie. produces "file1, file2, file10" rather than "file1, file10, file2".
+ *
+ * \param d1 first directory entry
+ * \param d2 second directory entry
+ */
+static int dir_sort_alpha(const struct dirent **d1, const struct dirent **d2)
+{
+ const char *s1 = (*d1)->d_name;
+ const char *s2 = (*d2)->d_name;
+
+ while (*s1 != '\0' && *s2 != '\0') {
+ if ((*s1 >= '0' && *s1 <= '9') &&
+ (*s2 >= '0' && *s2 <= '9')) {
+ int n1 = 0, n2 = 0;
+ while (*s1 >= '0' && *s1 <= '9') {
+ n1 = n1 * 10 + (*s1) - '0';
+ s1++;
+ }
+ while (*s2 >= '0' && *s2 <= '9') {
+ n2 = n2 * 10 + (*s2) - '0';
+ s2++;
+ }
+ if (n1 != n2) {
+ return n1 - n2;
+ }
+ if (*s1 == '\0' || *s2 == '\0')
+ break;
+ }
+ if (tolower(*s1) != tolower(*s2))
+ break;
+
+ s1++;
+ s2++;
+ }
+
+ return tolower(*s1) - tolower(*s2);
+}
+
static void fetch_file_process_dir(struct fetch_file_context *ctx,
struct stat *fdstat)
{
diff --git a/content/fetchers/resource.c b/content/fetchers/resource.c
index 7a55b54..72ed887 100644
--- a/content/fetchers/resource.c
+++ b/content/fetchers/resource.c
@@ -21,28 +21,16 @@
* resource scheme URL handling. Based on the data fetcher by Rob Kendrick
*/
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <assert.h>
-#include <errno.h>
+#include <stdlib.h>
#include <stdbool.h>
-#include <inttypes.h>
#include <string.h>
#include <strings.h>
-#include <time.h>
#include <stdio.h>
-#include <dirent.h>
-#include <limits.h>
#include <stdarg.h>
-
#include <libwapcaplet/libwapcaplet.h>
-#include "utils/config.h"
-#include "utils/errors.h"
+#include "utils/nsurl.h"
#include "utils/corestrings.h"
-#include "utils/nsoption.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/utils.h"
@@ -53,7 +41,6 @@
#include "content/fetch.h"
#include "content/fetchers.h"
#include "content/fetchers/resource.h"
-#include "content/urldb.h"
#define DIRECT_ETAG_VALUE 123456
diff --git a/content/fs_backing_store.c b/content/fs_backing_store.c
index b9490dd..0c76596 100644
--- a/content/fs_backing_store.c
+++ b/content/fs_backing_store.c
@@ -911,7 +911,7 @@ get_store_entry(struct store_state *state, nsurl *url, struct store_entry **bse)
state->entries_dirty = true;
- guit->browser->schedule(CONTROL_MAINT_TIME, control_maintinance, state);
+ guit->misc->schedule(CONTROL_MAINT_TIME, control_maintinance, state);
return NSERROR_OK;
}
@@ -1052,7 +1052,7 @@ set_store_entry(struct store_state *state,
/* ensure control maintinance scheduled. */
state->entries_dirty = true;
- guit->browser->schedule(CONTROL_MAINT_TIME, control_maintinance, state);
+ guit->misc->schedule(CONTROL_MAINT_TIME, control_maintinance, state);
*bse = se;
@@ -1587,7 +1587,7 @@ finalise(void)
unsigned int op_count;
if (storestate != NULL) {
- guit->browser->schedule(-1, control_maintinance, storestate);
+ guit->misc->schedule(-1, control_maintinance, storestate);
write_entries(storestate);
write_blocks(storestate);
diff --git a/content/hlcache.c b/content/hlcache.c
index 3f0e810..06d9f6d 100644
--- a/content/hlcache.c
+++ b/content/hlcache.c
@@ -146,7 +146,7 @@ static void hlcache_clean(void *ignored)
llcache_clean(false);
/* Re-schedule ourselves */
- guit->browser->schedule(hlcache->params.bg_clean_time, hlcache_clean, NULL);
+ guit->misc->schedule(hlcache->params.bg_clean_time, hlcache_clean, NULL);
}
/**
@@ -537,7 +537,7 @@ hlcache_initialise(const struct hlcache_parameters *hlcache_parameters)
hlcache->params = *hlcache_parameters;
/* Schedule the cache cleanup */
- guit->browser->schedule(hlcache->params.bg_clean_time, hlcache_clean, NULL);
+ guit->misc->schedule(hlcache->params.bg_clean_time, hlcache_clean, NULL);
return NSERROR_OK;
}
@@ -546,7 +546,7 @@ hlcache_initialise(const struct hlcache_parameters *hlcache_parameters)
void hlcache_stop(void)
{
/* Remove the hlcache_clean schedule */
- guit->browser->schedule(-1, hlcache_clean, NULL);
+ guit->misc->schedule(-1, hlcache_clean, NULL);
}
/* See hlcache.h for documentation */
diff --git a/content/llcache.c b/content/llcache.c
index 6e8b401..9381ce9 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -37,7 +37,6 @@
#include <strings.h>
#include <inttypes.h>
-#include <curl/curl.h>
#include <nsutils/time.h>
#include "utils/config.h"
@@ -590,59 +589,79 @@ static nserror llcache_fetch_split_header(const uint8_t *data, size_t len,
static nserror llcache_fetch_parse_header(llcache_object *object,
const uint8_t *data, size_t len, char **name, char **value)
{
- nserror error;
+ nserror res;
/* Set fetch response time if not already set */
- if (object->cache.res_time == 0)
+ if (object->cache.res_time == 0) {
object->cache.res_time = time(NULL);
+ }
/* Decompose header into name-value pair */
- error = llcache_fetch_split_header(data, len, name, value);
- if (error != NSERROR_OK)
- return error;
+ res = llcache_fetch_split_header(data, len, name, value);
+ if (res != NSERROR_OK) {
+ return res;
+ }
/* Parse cache headers to populate cache control data */
-#define SKIP_ST(p) while (*p != '\0' && (*p == ' ' || *p == '\t')) p++
- if (5 < len && strcasecmp(*name, "Date") == 0) {
+ if ((5 < len) &&
+ strcasecmp(*name, "Date") == 0) {
/* extract Date header */
- object->cache.date = curl_getdate(*value, NULL);
- } else if (4 < len && strcasecmp(*name, "Age") == 0) {
+ nsc_strntimet(*value,
+ strlen(*value),
+ &object->cache.date);
+ } else if ((4 < len) &&
+ strcasecmp(*name, "Age") == 0) {
/* extract Age header */
- if ('0' <= **value && **value <= '9')
+ if ('0' <= **value && **value <= '9') {
object->cache.age = atoi(*value);
- } else if (8 < len && strcasecmp(*name, "Expires") == 0) {
+ }
+ } else if ((8 < len) &&
+ strcasecmp(*name, "Expires") == 0) {
/* extract Expires header */
- object->cache.expires = curl_getdate(*value, NULL);
- } else if (14 < len && strcasecmp(*name, "Cache-Control") == 0) {
+ res = nsc_strntimet(*value,
+ strlen(*value),
+ &object->cache.expires);
+ if (res != NSERROR_OK) {
+ object->cache.expires = (time_t)0x7fffffff;
+ }
+ } else if ((14 < len) &&
+ strcasecmp(*name, "Cache-Control") == 0) {
/* extract and parse Cache-Control header */
const char *start = *value;
const char *comma = *value;
while (*comma != '\0') {
- while (*comma != '\0' && *comma != ',')
+ while (*comma != '\0' && *comma != ',') {
comma++;
-
- if (8 < comma - start && (strncasecmp(start,
- "no-cache", 8) == 0 ||
- strncasecmp(start, "no-store", 8) == 0))
- /* When we get a disk cache we should
- * distinguish between these two */
+ }
+
+ if ((8 < comma - start) &&
+ (strncasecmp(start, "no-cache", 8) == 0 ||
+ strncasecmp(start, "no-store", 8) == 0)) {
+ /**
+ * \todo When we get a disk cache we should
+ * distinguish between these two.
+ */
object->cache.no_cache = LLCACHE_VALIDATE_ALWAYS;
- else if (7 < comma - start &&
- strncasecmp(start, "max-age", 7) == 0) {
+ } else if ((7 < comma - start) &&
+ strncasecmp(start, "max-age", 7) == 0) {
/* Find '=' */
- while (start < comma && *start != '=')
+ while (start < comma && *start != '=') {
start++;
+ }
/* Skip over it */
start++;
+#define SKIP_ST(p) while (*p != '\0' && (*p == ' ' || *p == '\t')) p++
+
/* Skip whitespace */
SKIP_ST(start);
- if (start < comma)
+ if (start < comma) {
object->cache.max_age = atoi(start);
+ }
}
if (*comma != '\0') {
@@ -652,10 +671,13 @@ static nserror llcache_fetch_parse_header(llcache_object *object,
SKIP_ST(comma);
}
+#undef SKIP_ST
+
/* Set start for next token */
start = comma;
}
- } else if (5 < len && strcasecmp(*name, "ETag") == 0) {
+ } else if ((5 < len) &&
+ (strcasecmp(*name, "ETag") == 0)) {
/* extract ETag header */
free(object->cache.etag);
object->cache.etag = strdup(*value);
@@ -664,12 +686,14 @@ static nserror llcache_fetch_parse_header(llcache_object *object,
free(*value);
return NSERROR_NOMEM;
}
- } else if (14 < len && strcasecmp(*name, "Last-Modified") == 0) {
+ } else if ((14 < len) &&
+ (strcasecmp(*name, "Last-Modified") == 0)) {
/* extract Last-Modified header */
- object->cache.last_modified = curl_getdate(*value, NULL);
+ nsc_strntimet(*value,
+ strlen(*value),
+ &object->cache.last_modified);
}
-#undef SKIP_ST
return NSERROR_OK;
}
@@ -2529,7 +2553,7 @@ static void llcache_persist(void *p)
* Schedule a check in the future to see if
* overall performance is too slow to be useful.
*/
- guit->browser->schedule(
+ guit->misc->schedule(
llcache->time_quantum * 100,
llcache_persist_slowcheck,
NULL);
@@ -2582,7 +2606,7 @@ static void llcache_persist(void *p)
total_written, total_elapsed, total_bandwidth);
LLCACHE_LOG("Rescheduling writeout in %dms", next);
- guit->browser->schedule(next, llcache_persist, NULL);
+ guit->misc->schedule(next, llcache_persist, NULL);
}
@@ -2657,7 +2681,7 @@ static void llcache_fetch_callback(const fetch_msg *msg, void *p)
/* record when the fetch finished */
object->cache.fin_time = time(NULL);
- guit->browser->schedule(5000, llcache_persist, NULL);
+ guit->misc->schedule(5000, llcache_persist, NULL);
}
break;
@@ -3440,7 +3464,7 @@ static void llcache_users_not_caught_up(void)
{
if (llcache->all_caught_up) {
llcache->all_caught_up = false;
- guit->browser->schedule(0, llcache_catch_up_all_users, NULL);
+ guit->misc->schedule(0, llcache_catch_up_all_users, NULL);
}
}
diff --git a/content/urldb.c b/content/urldb.c
index edb49b5..0b59e1f 100644
--- a/content/urldb.c
+++ b/content/urldb.c
@@ -95,14 +95,15 @@
#include <string.h>
#include <strings.h>
#include <time.h>
-#include <curl/curl.h>
+#include "utils/inet.h"
#include "utils/nsoption.h"
#include "utils/log.h"
#include "utils/corestrings.h"
#include "utils/url.h"
#include "utils/utils.h"
#include "utils/bloom.h"
+#include "utils/time.h"
#include "image/bitmap.h"
#include "desktop/cookie_manager.h"
#include "desktop/gui_internal.h"
@@ -1587,22 +1588,21 @@ static bool urldb_parse_avpair(struct cookie_internal_data *c, char *n,
} else if (strcasecmp(n, "Expires") == 0) {
char *datenoday;
time_t expires;
+ nserror res;
- /* Strip dayname from date (these are hugely
- * variable and liable to break the parser.
- * They also serve no useful purpose) */
+ /* Strip dayname from date (these are hugely variable
+ * and liable to break the parser. They also serve no
+ * useful purpose) */
for (datenoday = v; *datenoday && !isdigit(*datenoday);
datenoday++)
; /* do nothing */
- expires = curl_getdate(datenoday, NULL);
- if (expires == -1) {
- /* assume we have an unrepresentable
- * date => force it to the maximum
- * possible value of a 32bit time_t
- * (this may break in 2038. We'll
- * deal with that once we come to
- * it) */
+ res = nsc_strntimet(datenoday, strlen(datenoday), &expires);
+ if (res != NSERROR_OK) {
+ /* assume we have an unrepresentable date =>
+ * force it to the maximum possible value of a
+ * 32bit time_t (this may break in 2038. We'll
+ * deal with that once we come to it) */
expires = (time_t)0x7fffffff;
}
c->expires = expires;
diff --git a/desktop/browser.c b/desktop/browser.c
index 04e8efb..4cd017d 100644
--- a/desktop/browser.c
+++ b/desktop/browser.c
@@ -38,6 +38,7 @@
#include <string.h>
#include <strings.h>
#include <math.h>
+#include <nsutils/time.h>
#include "utils/corestrings.h"
#include "utils/log.h"
@@ -47,6 +48,7 @@
#include "utils/utf8.h"
#include "utils/nsoption.h"
#include "content/content.h"
+#include "content/content_debug.h"
#include "content/fetch.h"
#include "content/hlcache.h"
#include "content/urldb.h"
@@ -841,9 +843,11 @@ nserror browser_window_create(enum browser_window_create_flags flags,
ret->scrolling = BW_SCROLLING_YES;
ret->border = true;
ret->no_resize = true;
- ret->last_action = wallclock();
ret->focus = ret;
+ /* initialise last action with creation time */
+ nsu_getmonotonic_ms(&ret->last_action);
+
/* The existing gui_window is on the top-level existing
* browser_window. */
existing = browser_window_get_root(existing);
@@ -958,7 +962,7 @@ browser_window_download(struct browser_window *bw,
NULL, NULL, &l);
if (error == NSERROR_NO_FETCH_HANDLER) {
/* no internal handler for this type, call out to frontend */
- error = guit->browser->launch_url(url);
+ error = guit->misc->launch_url(url);
} else if (error != NSERROR_OK) {
LOG("Failed to fetch download: %d", error);
} else {
@@ -1201,7 +1205,7 @@ browser_window_callback_errorcode(hlcache_handle *c,
/* Only warn the user about errors in top-level windows */
if (bw->browser_window_type == BROWSER_WINDOW_NORMAL) {
- warn_user(message, 0);
+ guit->misc->warning(message, NULL);
}
if (c == bw->loading_content) {
@@ -1307,6 +1311,7 @@ static nserror browser_window_callback(hlcache_handle *c,
const hlcache_event *event, void *pw)
{
struct browser_window *bw = pw;
+ nserror res = NSERROR_OK;
switch (event->type) {
case CONTENT_MSG_DOWNLOAD:
@@ -1410,10 +1415,11 @@ static nserror browser_window_callback(hlcache_handle *c,
}
/* frames */
- if (content_get_type(c) == CONTENT_HTML &&
- html_get_frameset(c) != NULL)
- browser_window_create_frameset(bw,
+ if ((content_get_type(c) == CONTENT_HTML) &&
+ (html_get_frameset(c) != NULL)) {
+ res = browser_window_create_frameset(bw,
html_get_frameset(c));
+ }
if (content_get_type(c) == CONTENT_HTML &&
html_get_iframe(c) != NULL)
browser_window_create_iframes(bw, html_get_iframe(c));
@@ -1440,7 +1446,7 @@ static nserror browser_window_callback(hlcache_handle *c,
hotlist_update_url(hlcache_handle_get_url(c));
if (bw->refresh_interval != -1) {
- guit->browser->schedule(bw->refresh_interval * 10,
+ guit->misc->schedule(bw->refresh_interval * 10,
browser_window_refresh, bw);
}
break;
@@ -1453,8 +1459,9 @@ static nserror browser_window_callback(hlcache_handle *c,
browser_window_set_status(bw, event->data.error);
/* Only warn the user about errors in top-level windows */
- if (bw->browser_window_type == BROWSER_WINDOW_NORMAL)
- warn_user(event->data.error, 0);
+ if (bw->browser_window_type == BROWSER_WINDOW_NORMAL) {
+ guit->misc->warning(event->data.error, NULL);
+ }
if (c == bw->loading_content)
bw->loading_content = NULL;
@@ -1700,7 +1707,7 @@ static nserror browser_window_callback(hlcache_handle *c,
break;
}
- return NSERROR_OK;
+ return res;
}
@@ -1759,12 +1766,12 @@ static void browser_window_destroy_internal(struct browser_window *bw)
}
/* clear any pending callbacks */
- guit->browser->schedule(-1, browser_window_refresh, bw);
+ guit->misc->schedule(-1, browser_window_refresh, bw);
/* The ugly cast here is so the reformat function can be
* passed a gui window pointer in its API rather than void*
*/
LOG("Clearing schedule %p(%p)", guit->window->reformat, bw->window);
- guit->browser->schedule(-1, (void(*)(void*))guit->window->reformat, bw->window);
+ guit->misc->schedule(-1, (void(*)(void*))guit->window->reformat, bw->window);
/* If this brower window is not the root window, and has focus, unset
* the root browser window's focus pointer. */
@@ -2061,13 +2068,13 @@ nserror browser_window_navigate(struct browser_window *bw,
/** \todo does this always try and download even
* unverifiable content?
*/
- error = guit->browser->launch_url(url);
+ error = guit->misc->launch_url(url);
break;
default: /* report error to user */
browser_window_set_status(bw, messages_get_errorcode(error));
/** @todo should the caller report the error? */
- warn_user(messages_get_errorcode(error), 0);
+ guit->misc->warning(messages_get_errorcode(error), NULL);
break;
}
@@ -2078,7 +2085,7 @@ nserror browser_window_navigate(struct browser_window *bw,
}
/* Record time */
- bw->last_action = wallclock();
+ nsu_getmonotonic_ms(&bw->last_action);
return error;
}
@@ -2383,7 +2390,7 @@ void browser_window_stop(struct browser_window *bw)
assert(error == NSERROR_OK);
}
- guit->browser->schedule(-1, browser_window_refresh, bw);
+ guit->misc->schedule(-1, browser_window_refresh, bw);
if (bw->children) {
children = bw->rows * bw->cols;
@@ -2491,25 +2498,29 @@ void browser_window_set_pointer(struct browser_window *bw,
struct browser_window *root = browser_window_get_root(bw);
gui_pointer_shape gui_shape;
bool loading;
+ uint64_t ms_now;
assert(root);
assert(root->window);
- loading = (bw->loading_content != NULL || (bw->current_content &&
- content_get_status(bw->current_content) ==
- CONTENT_STATUS_READY));
+ loading = ((bw->loading_content != NULL) ||
+ ((bw->current_content != NULL) &&
+ (content_get_status(bw->current_content) == CONTENT_STATUS_READY)));
+
+ nsu_getmonotonic_ms(&ms_now);
- if (wallclock() - bw->last_action < 100 && loading) {
+ if (loading && ((ms_now - bw->last_action) < 1000)) {
/* If loading and less than 1 second since last link followed,
* force progress indicator pointer */
gui_shape = GUI_POINTER_PROGRESS;
} else if (shape == BROWSER_POINTER_AUTO) {
/* Up to browser window to decide */
- if (loading)
+ if (loading) {
gui_shape = GUI_POINTER_PROGRESS;
- else
+ } else {
gui_shape = GUI_POINTER_DEFAULT;
+ }
} else {
/* Use what we were told */
@@ -2525,7 +2536,7 @@ nserror browser_window_schedule_reformat(struct browser_window *bw)
/* The ugly cast here is so the reformat function can be
* passed a gui window pointer in its API rather than void*
*/
- guit->browser->schedule(0, (void(*)(void*))guit->window->reformat, bw->window);
+ guit->misc->schedule(0, (void(*)(void*))guit->window->reformat, bw->window);
return NSERROR_OK;
}
@@ -2804,7 +2815,7 @@ struct browser_window *browser_window_find_target(struct browser_window *bw,
if (target[0] != '_') {
bw_target->name = strdup(target);
if (!bw_target->name)
- warn_user("NoMemory", 0);
+ guit->misc->warning("NoMemory", NULL);
}
return bw_target;
}
diff --git a/desktop/browser_history.c b/desktop/browser_history.c
index 1ee8000..f2b0fb3 100644
--- a/desktop/browser_history.c
+++ b/desktop/browser_history.c
@@ -37,11 +37,11 @@
#include "css/css.h"
#include "image/bitmap.h"
+#include "desktop/gui_layout.h"
#include "desktop/gui_internal.h"
#include "desktop/browser_history.h"
#include "desktop/browser_private.h"
#include "desktop/plotters.h"
-#include "desktop/font.h"
#define WIDTH 100
#define HEIGHT 86
@@ -273,6 +273,7 @@ browser_window_history__redraw_entry(struct history *history,
.stroke_width = entry == history->current ? 3 : 1,
};
plot_font_style_t fstyle = *plot_style_font;
+ nserror res;
if (clip) {
struct rect rect;
@@ -292,17 +293,21 @@ browser_window_history__redraw_entry(struct history *history,
WIDTH, HEIGHT,
entry->bitmap, 0xffffff, 0);
}
+
if (!plot->rectangle(entry->x - 1 + xoffset,
entry->y - 1 + yoffset,
entry->x + xoffset + WIDTH,
entry->y + yoffset + HEIGHT,
- &pstyle_history_rect))
+ &pstyle_history_rect)) {
return false;
+ }
- if (!nsfont.font_position_in_string(plot_style_font, entry->page.title,
- strlen(entry->page.title), WIDTH,
- &char_offset, &actual_x))
+ res = guit->layout->position(plot_style_font, entry->page.title,
+ strlen(entry->page.title), WIDTH,
+ &char_offset, &actual_x);
+ if (res != NSERROR_OK) {
return false;
+ }
fstyle.background = HISTORY_COLOUR_BACKGROUND;
fstyle.foreground = c;
diff --git a/desktop/browser_private.h b/desktop/browser_private.h
index 43f4402..efd875f 100644
--- a/desktop/browser_private.h
+++ b/desktop/browser_private.h
@@ -141,7 +141,7 @@ struct browser_window {
struct browser_window *focus;
/** Last time a link was followed in this window */
- unsigned int last_action;
+ uint64_t last_action;
/** Current selection */
struct {
diff --git a/desktop/frames.c b/desktop/frames.c
index 253e842..7be75ce 100644
--- a/desktop/frames.c
+++ b/desktop/frames.c
@@ -147,10 +147,11 @@ void browser_window_handle_scrollbars(struct browser_window *bw)
if (bw->scroll_y == NULL) {
/* create vertical scrollbar */
- if (!scrollbar_create(false, length, c_height, visible,
- bw, browser_window_scroll_callback,
- &(bw->scroll_y)))
+ if (scrollbar_create(false, length, c_height, visible,
+ bw, browser_window_scroll_callback,
+ &(bw->scroll_y)) != NSERROR_OK) {
return;
+ }
} else {
/* update vertical scrollbar */
scrollbar_set_extents(bw->scroll_y, length,
@@ -164,10 +165,11 @@ void browser_window_handle_scrollbars(struct browser_window *bw)
if (bw->scroll_x == NULL) {
/* create horizontal scrollbar */
- if (!scrollbar_create(true, length, c_width, visible,
- bw, browser_window_scroll_callback,
- &(bw->scroll_x)))
+ if (scrollbar_create(true, length, c_width, visible,
+ bw, browser_window_scroll_callback,
+ &(bw->scroll_x)) != NSERROR_OK) {
return;
+ }
} else {
/* update horizontal scrollbar */
scrollbar_set_extents(bw->scroll_x, length,
@@ -291,14 +293,8 @@ void browser_window_recalculate_iframes(struct browser_window *bw)
}
-/**
- * Create and open a frameset for a browser window.
- *
- * \param bw The browser window to create the frameset for
- * \param frameset The frameset to create
- */
-
-void browser_window_create_frameset(struct browser_window *bw,
+/* exported interface documented in desktop/frames.h */
+nserror browser_window_create_frameset(struct browser_window *bw,
struct content_html_frames *frameset)
{
int row, col, index;
@@ -313,8 +309,10 @@ void browser_window_create_frameset(struct browser_window *bw,
assert(frameset->cols + frameset->rows != 0);
bw->children = calloc((frameset->cols * frameset->rows), sizeof(*bw));
- if (!bw->children)
- return;
+ if (!bw->children) {
+ return NSERROR_NOMEM;
+ }
+
bw->cols = frameset->cols;
bw->rows = frameset->rows;
for (row = 0; row < bw->rows; row++) {
@@ -344,8 +342,11 @@ void browser_window_create_frameset(struct browser_window *bw,
window->margin_height = frame->margin_height;
if (frame->name) {
window->name = strdup(frame->name);
- if (!window->name)
- warn_user("NoMemory", 0);
+ if (!window->name) {
+ free(bw->children);
+ bw->children = NULL;
+ return NSERROR_NOMEM;
+ }
}
window->scale = bw->scale;
@@ -406,6 +407,8 @@ void browser_window_create_frameset(struct browser_window *bw,
}
}
}
+
+ return NSERROR_OK;
}
diff --git a/desktop/frames.h b/desktop/frames.h
index 02c513c..b39c8a8 100644
--- a/desktop/frames.h
+++ b/desktop/frames.h
@@ -35,8 +35,17 @@ struct scrollbar_msg_data;
nserror browser_window_create_iframes(struct browser_window *bw,
struct content_html_iframe *iframe);
void browser_window_recalculate_iframes(struct browser_window *bw);
-void browser_window_create_frameset(struct browser_window *bw,
+
+/**
+ * Create and open a frameset for a browser window.
+ *
+ * \param[in,out] bw The browser window to create the frameset for
+ * \param[in] frameset The frameset to create
+ * \return NSERROR_OK or error code on faliure
+ */
+nserror browser_window_create_frameset(struct browser_window *bw,
struct content_html_frames *frameset);
+
void browser_window_recalculate_frameset(struct browser_window *bw);
bool browser_window_frame_resize_start(struct browser_window *bw,
browser_mouse_state mouse, int x, int y,
diff --git a/desktop/gui_factory.c b/desktop/gui_factory.c
index 22364ab..956c508 100644
--- a/desktop/gui_factory.c
+++ b/desktop/gui_factory.c
@@ -20,6 +20,7 @@
#include <stdint.h>
#include <stdbool.h>
+#include "utils/config.h"
#include "utils/errors.h"
#include "utils/file.h"
#include "image/bitmap.h"
@@ -36,6 +37,7 @@
#include "desktop/gui_search.h"
#include "desktop/gui_clipboard.h"
#include "desktop/gui_utf8.h"
+#include "desktop/gui_layout.h"
#include "desktop/netsurf.h"
/**
@@ -643,6 +645,35 @@ static nserror verify_bitmap_register(struct gui_bitmap_table *gbt)
return NSERROR_OK;
}
+/**
+ * verify layout table is valid
+ *
+ * \param glt The layout table to verify.
+ * \return NSERROR_OK if the table is valid else NSERROR_BAD_PARAMETER.
+ */
+static nserror verify_layout_register(struct gui_layout_table *glt)
+{
+ /* check table is present */
+ if (glt == NULL) {
+ return NSERROR_BAD_PARAMETER;
+ }
+
+ /* check the mandantory fields are set */
+ if (glt->width == NULL) {
+ return NSERROR_BAD_PARAMETER;
+ }
+
+ if (glt->position == NULL) {
+ return NSERROR_BAD_PARAMETER;
+ }
+
+ if (glt->split == NULL) {
+ return NSERROR_BAD_PARAMETER;
+ }
+
+ return NSERROR_OK;
+}
+
static void gui_default_quit(void)
{
}
@@ -676,34 +707,37 @@ gui_default_pdf_password(char **owner_pass, char **user_pass, char *path)
save_pdf(path);
}
-/** verify browser table is valid */
-static nserror verify_browser_register(struct gui_browser_table *gbt)
+/** verify misc table is valid */
+static nserror verify_misc_register(struct gui_misc_table *gmt)
{
/* check table is present */
- if (gbt == NULL) {
+ if (gmt == NULL) {
return NSERROR_BAD_PARAMETER;
}
/* check the mandantory fields are set */
- if (gbt->schedule == NULL) {
+ if (gmt->schedule == NULL) {
+ return NSERROR_BAD_PARAMETER;
+ }
+ if (gmt->warning == NULL) {
return NSERROR_BAD_PARAMETER;
}
/* fill in the optional entries with defaults */
- if (gbt->quit == NULL) {
- gbt->quit = gui_default_quit;
+ if (gmt->quit == NULL) {
+ gmt->quit = gui_default_quit;
}
- if (gbt->launch_url == NULL) {
- gbt->launch_url = gui_default_launch_url;
+ if (gmt->launch_url == NULL) {
+ gmt->launch_url = gui_default_launch_url;
}
- if (gbt->cert_verify == NULL) {
- gbt->cert_verify = gui_default_cert_verify;
+ if (gmt->cert_verify == NULL) {
+ gmt->cert_verify = gui_default_cert_verify;
}
- if (gbt->login == NULL) {
- gbt->login = gui_default_401login_open;
+ if (gmt->login == NULL) {
+ gmt->login = gui_default_401login_open;
}
- if (gbt->pdf_password == NULL) {
- gbt->pdf_password = gui_default_pdf_password;
+ if (gmt->pdf_password == NULL) {
+ gmt->pdf_password = gui_default_pdf_password;
}
return NSERROR_OK;
}
@@ -724,8 +758,10 @@ nserror netsurf_register(struct netsurf_table *gt)
return NSERROR_BAD_PARAMETER;
}
- /* browser table */
- err = verify_browser_register(gt->browser);
+ /* mandantory tables */
+
+ /* miscellaneous table */
+ err = verify_misc_register(gt->misc);
if (err != NSERROR_OK) {
return err;
}
@@ -748,6 +784,14 @@ nserror netsurf_register(struct netsurf_table *gt)
return err;
}
+ /* layout table */
+ err = verify_layout_register(gt->layout);
+ if (err != NSERROR_OK) {
+ return err;
+ }
+
+ /* optional tables */
+
/* file table */
if (gt->file == NULL) {
gt->file = default_file_table;
diff --git a/desktop/gui_fetch.h b/desktop/gui_fetch.h
index 20db39d..22c5e6a 100644
--- a/desktop/gui_fetch.h
+++ b/desktop/gui_fetch.h
@@ -91,8 +91,8 @@ struct gui_fetch_table {
/**
* Find a MIME type for a local file
*
- * @note only used in curl fetcher on RISC OS otherwise its a
- * strdup of filetype.
+ * @note only used in curl fetcher in form file controls on
+ * RISC OS otherwise its a strdup of a filetype call.
*
* \param ro_path RISC OS style path to file on disk
* \return MIME type string (on heap, caller should free), or NULL
diff --git a/desktop/font.h b/desktop/gui_layout.h
similarity index 51%
rename from desktop/font.h
rename to desktop/gui_layout.h
index c883f8a..1696aee 100644
--- a/desktop/font.h
+++ b/desktop/gui_layout.h
@@ -1,7 +1,5 @@
/*
- * Copyright 2003 Phil Mellor <monkeyson(a)users.sourceforge.net>
- * Copyright 2005 James Bursa <bursa(a)users.sourceforge.net>
- * Copyright 2004 John Tytgat <joty(a)netsurf-browser.org>
+ * Copyright 2016 Vincent Sanders <vince(a)netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -18,26 +16,25 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
- * Font handling interface.
+/**
+ * \file
*
- * These functions provide font related services. They all work on
- * UTF-8 strings with lengths given.
+ * Interface to platform-specific layout operation table.
*
- * Note that an interface to painting is not defined here. Painting is
- * redirected through platform-dependent plotters anyway, so there is
- * no gain in abstracting it here.
+ * This table is part of the layout used to measure glyphs before
+ * rendering, previously referred to as font functions.
+ *
+ * \note This is an old interface within the browser, it has been
+ * broken out purely to make the API obvious not as an indication this
+ * is the correct approach.
*/
-#ifndef _NETSURF_DESKTOP_FONT_H_
-#define _NETSURF_DESKTOP_FONT_H_
-
-#include <stdbool.h>
-#include <stddef.h>
+#ifndef _NETSURF_DESKTOP_GUI_LAYOUT_H_
+#define _NETSURF_DESKTOP_GUI_LAYOUT_H_
-#include "desktop/plot_style.h"
+struct plot_font_style;
-struct font_functions
+struct gui_layout_table
{
/**
* Measure the width of a string.
@@ -46,11 +43,12 @@ struct font_functions
* \param[in] string UTF-8 string to measure
* \param[in] length length of string, in bytes
* \param[out] width updated to width of string[0..length)
- * \return true on success and width updated else false.
+ * \return NSERROR_OK and width updated or appropriate error
+ * code on faliure
*/
- bool (*font_width)(const plot_font_style_t *fstyle,
- const char *string, size_t length,
- int *width);
+ nserror (*width)(const struct plot_font_style *fstyle, const char *string, size_t length, int *width);
+
+
/**
* Find the position in a string where an x coordinate falls.
*
@@ -60,25 +58,25 @@ struct font_functions
* \param[in] x coordinate to search for
* \param[out] char_offset updated to offset in string of actual_x, [0..length]
* \param[out] actual_x updated to x coordinate of character closest to x
- * \return true on success, false on error and error reported
+ * \return NSERROR_OK and char_offset and actual_x updated or appropriate error code on faliure
*/
- bool (*font_position_in_string)(const plot_font_style_t *fstyle,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x);
+ nserror (*position)(const struct plot_font_style *fstyle, const char *string, size_t length, int x, size_t *char_offset, int *actual_x);
+
+
/**
* Find where to split a string to make it fit a width.
*
- * \param fstyle style for this text
- * \param string UTF-8 string to measure
- * \param length length of string, in bytes
- * \param x width available
- * \param char_offset updated to offset in string of actual_x, [1..length]
- * \param actual_x updated to x coordinate of character closest to x
- * \return true on success, false on error and error reported
+ * \param[in] fstyle style for this text
+ * \param[in] string UTF-8 string to measure
+ * \param[in] length length of string, in bytes
+ * \param[in] x width available
+ * \param[out] char_offset updated to offset in string of actual_x, [1..length]
+ * \param[out] actual_x updated to x coordinate of character closest to x
+ * \return NSERROR_OK or appropriate error code on faliure
*
* On exit, char_offset indicates first character after split point.
*
- * Note: char_offset of 0 should never be returned.
+ * \note char_offset of 0 must never be returned.
*
* Returns:
* char_offset giving split point closest to x, where actual_x <= x
@@ -87,11 +85,7 @@ struct font_functions
*
* Returning char_offset == length means no split possible
*/
- bool (*font_split)(const plot_font_style_t *fstyle,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x);
+ nserror (*split)(const struct plot_font_style *fstyle, const char *string, size_t length, int x, size_t *char_offset, int *actual_x);
};
-extern const struct font_functions nsfont;
-
#endif
diff --git a/desktop/gui_misc.h b/desktop/gui_misc.h
index a35ee51..399d938 100644
--- a/desktop/gui_misc.h
+++ b/desktop/gui_misc.h
@@ -36,7 +36,7 @@ struct nsurl;
* function table implementing GUI interface to miscelaneous browser
* functionality
*/
-struct gui_browser_table {
+struct gui_misc_table {
/* Mandantory entries */
/**
@@ -57,6 +57,18 @@ struct gui_browser_table {
*/
nserror (*schedule)(int t, void (*callback)(void *p), void *p);
+ /**
+ * Warn the user of an event.
+ *
+ * \param[in] message A warning looked up in the message
+ * translation table
+ * \param[in] detail Additional text to be displayed or NULL.
+ * \return NSERROR_OK on success or error code if there was a
+ * faliure displaying the message to the user.
+ */
+ nserror (*warning)(const char *message, const char *detail);
+
+
/* Optional entries */
/**
@@ -87,11 +99,6 @@ struct gui_browser_table {
nserror (*cb)(bool proceed, void *pw), void *cbpw);
/**
- * Warn the user of an event.
- */
- void (*warning)(const char *warning, const char *detail);
-
- /**
* Prompt the user for a password for a PDF.
*/
void (*pdf_password)(char **owner_pass, char **user_pass, char *path);
diff --git a/desktop/gui_table.h b/desktop/gui_table.h
index 52cdde2..0ac9f04 100644
--- a/desktop/gui_table.h
+++ b/desktop/gui_table.h
@@ -27,7 +27,7 @@
#ifndef _NETSURF_DESKTOP_GUI_TABLE_H_
#define _NETSURF_DESKTOP_GUI_TABLE_H_
-struct gui_browser_table;
+struct gui_misc_table;
struct gui_window_table;
struct gui_download_table;
struct gui_clipboard_table;
@@ -38,6 +38,7 @@ struct gui_search_table;
struct gui_search_web_table;
struct gui_llcache_table;
struct gui_bitmap_table;
+struct gui_layout_table;
/**
* NetSurf operation function table
@@ -49,15 +50,18 @@ struct netsurf_table {
/**
* Browser table.
*
- * Provides miscellaneous browser functionality. The table
- * is mandantory and must be provided.
+ * Provides miscellaneous browser functionality.
+ *
+ * The table is mandantory and must be provided.
*/
- struct gui_browser_table *browser;
+ struct gui_misc_table *misc;
/**
* Window table.
*
* Provides all operations which affect a frontends display window.
+ *
+ * The table is mandantory and must be provided.
*/
struct gui_window_table *window;
@@ -75,15 +79,18 @@ struct netsurf_table {
/**
* Fetcher table
+ *
+ * The table is mandantory and must be provided.
*/
struct gui_fetch_table *fetch;
/**
* File table
*
- * Provides file and filename operations to the core. The
- * table is optional and may be NULL in which case the default
- * posix compliant operations will be used.
+ * Provides file and filename operations to the core.
+ *
+ * The table is optional and may be NULL in which case the
+ * default posix compliant operations will be used.
*/
struct gui_file_table *file;
@@ -91,8 +98,10 @@ struct netsurf_table {
* UTF8 table.
*
* Provides for conversion between the gui local character
- * encoding and utf8. The table optional and may be NULL which
- * implies the local encoding is utf8.
+ * encoding and utf8.
+ *
+ * The table optional and may be NULL which implies the local
+ * encoding is utf8.
*/
struct gui_utf8_table *utf8;
@@ -106,9 +115,10 @@ struct netsurf_table {
/**
* Web search table.
*
- * Used by the web search provider system. The table is
- * optional and may be NULL which uses the default empty
- * implementation.
+ * Used by the web search provider system.
+ *
+ * The table is optional and may be NULL which uses the
+ * default empty implementation.
*/
struct gui_search_web_table *search_web;
@@ -116,8 +126,10 @@ struct netsurf_table {
* Low level cache table.
*
* Used by the low level cache to push objects to persistant
- * storage. The table is optional and may be NULL which
- * uses the default implementation.
+ * storage.
+ *
+ * The table is optional and may be NULL which uses the
+ * default implementation.
*/
struct gui_llcache_table *llcache;
@@ -125,10 +137,21 @@ struct netsurf_table {
* Bitmap table.
*
* Used by the image convertors as a generic interface to
- * native platform-specific image formats. The table
- * is mandantory and must be provided.
+ * native platform-specific image formats.
+ *
+ * The table is mandantory and must be provided.
*/
struct gui_bitmap_table *bitmap;
+
+ /**
+ * Layout table
+ *
+ * Used by the layout process to measure glyphs in a frontend
+ * specific manner.
+ *
+ * The table is mandantory and must be provided.
+ */
+ struct gui_layout_table *layout;
};
#endif
diff --git a/desktop/hotlist.c b/desktop/hotlist.c
index e6e11e4..98d5f9c 100644
--- a/desktop/hotlist.c
+++ b/desktop/hotlist.c
@@ -25,16 +25,19 @@
#include <dom/dom.h>
#include <dom/bindings/hubbub/parser.h>
-#include "content/urldb.h"
-#include "desktop/hotlist.h"
-#include "desktop/treeview.h"
-#include "desktop/browser.h"
#include "utils/corestrings.h"
#include "utils/messages.h"
#include "utils/utils.h"
#include "utils/utf8.h"
#include "utils/libdom.h"
#include "utils/log.h"
+#include "content/urldb.h"
+
+#include "desktop/gui_misc.h"
+#include "desktop/gui_internal.h"
+#include "desktop/hotlist.h"
+#include "desktop/treeview.h"
+#include "desktop/browser.h"
#define N_DAYS 28
#define N_SEC_PER_DAY (60 * 60 * 24)
@@ -799,7 +802,7 @@ static nserror hotlist_load(const char *path, bool *loaded)
corestring_lwc_html);
if (html == NULL) {
dom_node_unref(document);
- warn_user("TreeLoadError", "(<html> not found)");
+ guit->misc->warning("TreeLoadError", "(<html> not found)");
return NSERROR_OK;
}
@@ -808,7 +811,7 @@ static nserror hotlist_load(const char *path, bool *loaded)
if (body == NULL) {
dom_node_unref(html);
dom_node_unref(document);
- warn_user("TreeLoadError", "(<html>...<body> not found)");
+ guit->misc->warning("TreeLoadError", "(<html>...<body> not found)");
return NSERROR_OK;
}
@@ -818,7 +821,7 @@ static nserror hotlist_load(const char *path, bool *loaded)
dom_node_unref(body);
dom_node_unref(html);
dom_node_unref(document);
- warn_user("TreeLoadError",
+ guit->misc->warning("TreeLoadError",
"(<html>...<body>...<ul> not found.)");
return NSERROR_OK;
}
@@ -843,7 +846,7 @@ static nserror hotlist_load(const char *path, bool *loaded)
dom_node_unref(document);
if (err != NSERROR_OK) {
- warn_user("TreeLoadError", "(Failed building tree.)");
+ guit->misc->warning("TreeLoadError", "(Failed building tree.)");
return NSERROR_OK;
}
diff --git a/desktop/knockout.c b/desktop/knockout.c
index b213998..54e371c 100644
--- a/desktop/knockout.c
+++ b/desktop/knockout.c
@@ -66,6 +66,7 @@
#include <string.h>
#include <stdio.h>
+#include "utils/utils.h"
#include "utils/log.h"
#include "utils/errors.h"
#include "image/bitmap.h"
diff --git a/desktop/netsurf.c b/desktop/netsurf.c
index 2b01053..46d8d67 100644
--- a/desktop/netsurf.c
+++ b/desktop/netsurf.c
@@ -106,14 +106,14 @@ static nserror netsurf_llcache_query_handler(const llcache_query *query,
{
switch (query->type) {
case LLCACHE_QUERY_AUTH:
- guit->browser->login(query->url, query->data.auth.realm, cb, cbpw);
+ guit->misc->login(query->url, query->data.auth.realm, cb, cbpw);
break;
case LLCACHE_QUERY_REDIRECT:
/** \todo Need redirect query dialog */
/* For now, do nothing, as this query type isn't emitted yet */
break;
case LLCACHE_QUERY_SSL:
- guit->browser->cert_verify(query->url, query->data.ssl.certs,
+ guit->misc->cert_verify(query->url, query->data.ssl.certs,
query->data.ssl.num, cb, cbpw);
break;
}
@@ -245,7 +245,7 @@ void netsurf_exit(void)
hlcache_stop();
LOG("Closing GUI");
- guit->browser->quit();
+ guit->misc->quit();
LOG("Finalising JavaScript");
js_finalise();
diff --git a/desktop/plot_style.h b/desktop/plot_style.h
index 45813d4..af54e79 100644
--- a/desktop/plot_style.h
+++ b/desktop/plot_style.h
@@ -150,7 +150,7 @@ typedef unsigned long plot_font_flags_t;
/**
* Font style for plotting
*/
-typedef struct {
+typedef struct plot_font_style {
plot_font_generic_family_t family; /**< Generic family to plot with */
int size; /**< Font size, in points * FONT_SIZE_SCALE */
int weight; /**< Font weight: value in range [100,900] as per CSS */
diff --git a/desktop/print.c b/desktop/print.c
index f3a1a69..55caf51 100644
--- a/desktop/print.c
+++ b/desktop/print.c
@@ -26,6 +26,7 @@
#include <string.h>
#include <dom/dom.h>
+#include "utils/utils.h"
#include "utils/nsoption.h"
#include "utils/log.h"
#include "utils/talloc.h"
@@ -245,7 +246,7 @@ bool print_cleanup(hlcache_handle *content, const struct printer *printer,
* configuration or lack of memory.
*/
struct print_settings *print_make_settings(print_configuration configuration,
- const char *filename, const struct font_functions *font_func)
+ const char *filename, const struct gui_layout_table *font_func)
{
struct print_settings *settings;
css_fixed length = 0;
diff --git a/desktop/print.h b/desktop/print.h
index 63c2935..5c51981 100644
--- a/desktop/print.h
+++ b/desktop/print.h
@@ -38,6 +38,7 @@
struct hlcache_handle;
struct printer;
+struct gui_layout_table;
enum { MARGINLEFT = 0, MARGINRIGHT = 1, MARGINTOP = 2, MARGINBOTTOM = 3};
@@ -60,7 +61,7 @@ struct print_settings{
const char *output;
/*the functions used to measure fonts*/
- const struct font_functions *font_func;
+ const struct gui_layout_table *font_func;
};
@@ -73,8 +74,10 @@ bool print_draw_next_page(const struct printer *printer,
bool print_cleanup(struct hlcache_handle *, const struct printer *,
struct print_settings *settings);
-struct print_settings *print_make_settings(print_configuration configuration,
- const char *url, const struct font_functions *font_func);
+/**
+ * Setup print settings for print render operation.
+ */
+struct print_settings *print_make_settings(print_configuration configuration, const char *url, const struct gui_layout_table *font_func);
/*is the content currently redrawn for printing?*/
extern bool html_redraw_printing;
diff --git a/desktop/save_complete.c b/desktop/save_complete.c
index 58c1d21..98b0304 100644
--- a/desktop/save_complete.c
+++ b/desktop/save_complete.c
@@ -45,6 +45,8 @@
#include "render/box.h"
#include "render/html.h"
+#include "desktop/gui_misc.h"
+#include "desktop/gui_internal.h"
#include "desktop/save_complete.h"
regex_t save_complete_import_re;
@@ -150,7 +152,7 @@ static bool save_complete_save_buffer(save_complete_ctx *ctx,
ret = netsurf_mkpath(&fname, NULL, 2, ctx->path, leafname);
if (ret != NSERROR_OK) {
- warn_user(messages_get_errorcode(ret), 0);
+ guit->misc->warning(messages_get_errorcode(ret), 0);
return false;
}
@@ -158,7 +160,7 @@ static bool save_complete_save_buffer(save_complete_ctx *ctx,
if (fp == NULL) {
free(fname);
LOG("fopen(): errno = %i", errno);
- warn_user("SaveError", strerror(errno));
+ guit->misc->warning("SaveError", strerror(errno));
return false;
}
@@ -316,7 +318,7 @@ static bool save_complete_save_stylesheet(save_complete_ctx *ctx,
return true;
if (save_complete_ctx_add_content(ctx, css) == false) {
- warn_user("NoMemory", 0);
+ guit->misc->warning("NoMemory", 0);
return false;
}
@@ -329,7 +331,7 @@ static bool save_complete_save_stylesheet(save_complete_ctx *ctx,
source = save_complete_rewrite_stylesheet_urls(ctx, css_data, css_size,
hlcache_handle_get_url(css), &source_len);
if (source == NULL) {
- warn_user("NoMemory", 0);
+ guit->misc->warning("NoMemory", 0);
return false;
}
@@ -412,7 +414,7 @@ static bool save_complete_save_html_object(save_complete_ctx *ctx,
return true;
if (save_complete_ctx_add_content(ctx, obj) == false) {
- warn_user("NoMemory", 0);
+ guit->misc->warning("NoMemory", 0);
return false;
}
@@ -1056,7 +1058,7 @@ static bool save_complete_save_html_document(save_complete_ctx *ctx,
ret = netsurf_mkpath(&fname, NULL, 2, ctx->path, filename);
if (ret != NSERROR_OK) {
- warn_user(messages_get_errorcode(ret), NULL);
+ guit->misc->warning(messages_get_errorcode(ret), NULL);
return false;
}
@@ -1064,7 +1066,7 @@ static bool save_complete_save_html_document(save_complete_ctx *ctx,
if (fp == NULL) {
free(fname);
LOG("fopen(): errno = %i", errno);
- warn_user("SaveError", strerror(errno));
+ guit->misc->warning("SaveError", strerror(errno));
return false;
}
@@ -1077,7 +1079,7 @@ static bool save_complete_save_html_document(save_complete_ctx *ctx,
if (save_complete_libdom_treewalk((dom_node *) doc,
save_complete_node_handler, ctx) == false) {
free(fname);
- warn_user("NoMemory", 0);
+ guit->misc->warning("NoMemory", 0);
fclose(fp);
return false;
}
@@ -1143,7 +1145,7 @@ static bool save_complete_inventory(save_complete_ctx *ctx)
free(fname);
if (fp == NULL) {
LOG("fopen(): errno = %i", errno);
- warn_user("SaveError", strerror(errno));
+ guit->misc->warning("SaveError", strerror(errno));
return false;
}
@@ -1158,6 +1160,25 @@ static bool save_complete_inventory(save_complete_ctx *ctx)
return true;
}
+/**
+ * Compile a regular expression, handling errors.
+ *
+ * Parameters as for regcomp(), see man regex.
+ */
+static nserror regcomp_wrapper(regex_t *preg, const char *regex, int cflags)
+{
+ int r;
+ r = regcomp(preg, regex, cflags);
+ if (r) {
+ char errbuf[200];
+ regerror(r, preg, errbuf, sizeof errbuf);
+ LOG("Failed to compile regexp '%s': %s\n", regex, errbuf);
+ return NSERROR_INIT_FAILED;
+ }
+ return NSERROR_OK;
+}
+
+
/* Documented in save_complete.h */
void save_complete_init(void)
{
diff --git a/desktop/save_pdf.c b/desktop/save_pdf.c
index aeec9ce..8fd6795 100644
--- a/desktop/save_pdf.c
+++ b/desktop/save_pdf.c
@@ -774,7 +774,7 @@ void pdf_end(void)
/*Encryption on*/
if (option_enable_PDF_password)
- guit->browser->pdf_password(&owner_pass, &user_pass,
+ guit->misc->pdf_password(&owner_pass, &user_pass,
(void *)settings->output);
else
save_pdf(settings->output);
@@ -784,9 +784,9 @@ void pdf_end(void)
}
/** saves the pdf with optional encryption */
-void save_pdf(const char *path)
+nserror save_pdf(const char *path)
{
- bool success = false;
+ nserror res = NSERROR_OK;
if (option_enable_PDF_password && owner_pass != NULL ) {
HPDF_SetPassword(pdf_doc, owner_pass, user_pass);
@@ -796,17 +796,16 @@ void save_pdf(const char *path)
}
if (path != NULL) {
- if (HPDF_SaveToFile(pdf_doc, path) != HPDF_OK)
+ if (HPDF_SaveToFile(pdf_doc, path) != HPDF_OK) {
remove(path);
- else
- success = true;
+ res = NSERROR_SAVE_FAILED;
+ }
}
- if (!success)
- warn_user("Unable to save PDF file.", 0);
-
HPDF_Free(pdf_doc);
pdf_doc = NULL;
+
+ return res;
}
@@ -982,7 +981,8 @@ void pdfw_gs_dash(HPDF_Page page, DashPattern_e dash)
}
#else
-void save_pdf(const char *path)
+nserror save_pdf(const char *path)
{
+ return NSERROR_NOT_IMPLEMENTED;
}
#endif /* WITH_PDF_EXPORT */
diff --git a/desktop/save_pdf.h b/desktop/save_pdf.h
index d02c356..b90c5a9 100644
--- a/desktop/save_pdf.h
+++ b/desktop/save_pdf.h
@@ -36,6 +36,6 @@ bool pdf_next_page(void);
/**Close pdf document and save changes to file*/
void pdf_end(void);
-void save_pdf(const char *path);
+nserror save_pdf(const char *path);
#endif /*NETSURF_PDF_PLOTTERS_H*/
diff --git a/desktop/scrollbar.c b/desktop/scrollbar.c
index caed13f..82fcac1 100644
--- a/desktop/scrollbar.c
+++ b/desktop/scrollbar.c
@@ -70,9 +70,9 @@ struct scrollbar {
/*
- * Exported function. Documented in scrollbar.h
+ * Exported function. Documented in desktop/scrollbar.h
*/
-bool scrollbar_create(bool horizontal, int length, int full_size,
+nserror scrollbar_create(bool horizontal, int length, int full_size,
int visible_size, void *client_data,
scrollbar_client_callback client_callback,
struct scrollbar **s)
@@ -82,10 +82,8 @@ bool scrollbar_create(bool horizontal, int length, int full_size,
scrollbar = malloc(sizeof(struct scrollbar));
if (scrollbar == NULL) {
- LOG("malloc failed");
- warn_user("NoMemory", 0);
*s = NULL;
- return false;
+ return NSERROR_NOMEM;
}
scrollbar->horizontal = horizontal;
@@ -109,7 +107,7 @@ bool scrollbar_create(bool horizontal, int length, int full_size,
*s = scrollbar;
- return true;
+ return NSERROR_OK;
}
diff --git a/desktop/scrollbar.h b/desktop/scrollbar.h
index bfe90d9..d277be2 100644
--- a/desktop/scrollbar.h
+++ b/desktop/scrollbar.h
@@ -73,10 +73,10 @@ typedef void(*scrollbar_client_callback)(void *client_data,
* \param client_data data for the client callback
* \param client_callback client callback for scrollbar events
* \param s updated to point at the newly created scrollbar
- * \return true if scrollbar has been created succesfully or false on
- * memory exhaustion
+ * \return NSERROR_OK and s updated if scrollbar has been created
+ * succesfully or eror code and s set to NULL on faliure;
*/
-bool scrollbar_create(bool horizontal, int length, int full_size,
+nserror scrollbar_create(bool horizontal, int length, int full_size,
int visible_size, void *client_data,
scrollbar_client_callback client_callback,
struct scrollbar **s);
diff --git a/desktop/searchweb.c b/desktop/searchweb.c
index 4033f8e..83a19c3 100644
--- a/desktop/searchweb.c
+++ b/desktop/searchweb.c
@@ -21,6 +21,9 @@
* \brief core web search facilities implementation.
*/
+#include <stdlib.h>
+
+#include "utils/utils.h"
#include "utils/log.h"
#include "utils/url.h"
#include "utils/nsoption.h"
diff --git a/desktop/textarea.c b/desktop/textarea.c
index 9970bd6..467965d 100644
--- a/desktop/textarea.c
+++ b/desktop/textarea.c
@@ -37,8 +37,8 @@
#include "desktop/textinput.h"
#include "desktop/plotters.h"
#include "desktop/scrollbar.h"
-#include "desktop/font.h"
#include "desktop/gui_clipboard.h"
+#include "desktop/gui_layout.h"
#include "desktop/gui_internal.h"
#define CARET_COLOR 0x0000FF
@@ -404,7 +404,7 @@ static bool textarea_set_caret_internal(struct textarea *ta, int caret_b)
/* find byte offset of caret position */
b_off = index;
- nsfont.font_width(&ta->fstyle,
+ guit->layout->width(&ta->fstyle,
ta->show->data +
ta->lines[ta->caret_pos.line].b_start,
b_off - ta->lines[ta->caret_pos.line].b_start,
@@ -873,12 +873,12 @@ static bool textarea_reflow_singleline(struct textarea *ta, size_t b_off,
}
/* Measure new width */
- nsfont.font_width(&ta->fstyle, ta->show->data,
+ guit->layout->width(&ta->fstyle, ta->show->data,
ta->show->len - 1, &x);
/* Get width of retained text */
if (b_off != ta->lines[0].b_length) {
- nsfont.font_width(&ta->fstyle, ta->show->data,
+ guit->layout->width(&ta->fstyle, ta->show->data,
b_off, &retained_width);
} else {
retained_width = ta->lines[0].width;
@@ -1019,7 +1019,7 @@ static bool textarea_reflow_multiline(struct textarea *ta,
}
/* Wrap current line in paragraph */
- nsfont.font_split(&ta->fstyle, text, para_end - text,
+ guit->layout->split(&ta->fstyle, text, para_end - text,
avail_width, &b_off, &x);
/* b_off now marks space, or end of paragraph */
@@ -1029,10 +1029,11 @@ static bool textarea_reflow_multiline(struct textarea *ta,
if (x > avail_width && ta->bar_x == NULL) {
/* We need to insert a horizontal scrollbar */
int w = ta->vis_width - 2 * ta->border_width;
- if (!scrollbar_create(true, w, w, w,
+ if (scrollbar_create(true, w, w, w,
ta, textarea_scrollbar_callback,
- &(ta->bar_x)))
+ &(ta->bar_x)) != NSERROR_OK) {
return false;
+ }
if (ta->bar_y != NULL)
scrollbar_make_pair(ta->bar_x,
ta->bar_y);
@@ -1120,10 +1121,11 @@ static bool textarea_reflow_multiline(struct textarea *ta,
if (line > scroll_lines && ta->bar_y == NULL) {
/* Add vertical scrollbar */
int h = ta->vis_height - 2 * ta->border_width;
- if (!scrollbar_create(false, h, h, h,
- ta, textarea_scrollbar_callback,
- &(ta->bar_y)))
+ if (scrollbar_create(false, h, h, h,
+ ta, textarea_scrollbar_callback,
+ &(ta->bar_y)) != NSERROR_OK) {
return false;
+ }
if (ta->bar_x != NULL)
scrollbar_make_pair(ta->bar_x,
ta->bar_y);
@@ -1201,7 +1203,7 @@ static bool textarea_reflow_multiline(struct textarea *ta,
ta->lines[start].b_start;
text = ta->text.data + ta->lines[start].b_start;
- nsfont.font_width(&ta->fstyle, text,
+ guit->layout->width(&ta->fstyle, text,
retain_end, &retained_width);
r->x0 = max(r->x0,
@@ -1252,7 +1254,7 @@ static size_t textarea_get_b_off_xy(struct textarea *ta, int x, int y,
line = 0;
/* Get byte position */
- nsfont.font_position_in_string(&ta->fstyle,
+ guit->layout->position(&ta->fstyle,
ta->show->data + ta->lines[line].b_start,
ta->lines[line].b_length, x, &bpos, &x);
@@ -2303,7 +2305,7 @@ void textarea_redraw(struct textarea *ta, int x, int y, colour bg, float scale,
/* find clip left/right for this part of line */
left = right;
if (b_len_part != b_len) {
- nsfont.font_width(&fstyle, line_text, b_end,
+ guit->layout->width(&fstyle, line_text, b_end,
&right);
} else {
right = ta->lines[line].width;
diff --git a/desktop/tree.c b/desktop/tree.c
index eac9201..c5bca61 100644
--- a/desktop/tree.c
+++ b/desktop/tree.c
@@ -45,6 +45,8 @@ struct tree {
void *client_data; /* User assigned data for the callbacks */
};
+#include "desktop/gui_misc.h"
+#include "desktop/gui_internal.h"
#include "desktop/treeview.h"
#include "desktop/hotlist.h"
#include "desktop/cookie_manager.h"
@@ -139,24 +141,24 @@ static bool treeview_test_init(struct tree *tree)
"sslcert viewers");
err = cookie_manager_init(&cw_t, (struct core_window *)tree);
if (err != NSERROR_OK)
- warn_user("Couldn't init new cookie manager.", 0);
+ guit->misc->warning("Couldn't init new cookie manager.", 0);
break;
case TREE_HISTORY:
err = global_history_init(&cw_t, (struct core_window *)tree);
if (err != NSERROR_OK)
- warn_user("Couldn't init new global history.", 0);
+ guit->misc->warning("Couldn't init new global history.", 0);
break;
case TREE_HOTLIST:
err = hotlist_init(&cw_t, (struct core_window *)tree,
tree_hotlist_path);
if (err != NSERROR_OK)
- warn_user("Couldn't init new hotlist.", 0);
+ guit->misc->warning("Couldn't init new hotlist.", 0);
break;
case TREE_SSLCERT:
err = sslcert_viewer_init(&cw_t, (struct core_window *)tree,
ssl_current_session);
if (err != NSERROR_OK)
- warn_user("Couldn't init new sslcert viewer.", 0);
+ guit->misc->warning("Couldn't init new sslcert viewer.", 0);
break;
}
@@ -171,17 +173,17 @@ static bool treeview_test_fini(struct tree *tree)
case TREE_COOKIES:
err = cookie_manager_fini();
if (err != NSERROR_OK)
- warn_user("Couldn't finalise cookie manager.", 0);
+ guit->misc->warning("Couldn't finalise cookie manager.", 0);
break;
case TREE_HISTORY:
err = global_history_fini();
if (err != NSERROR_OK)
- warn_user("Couldn't finalise cookie manager.", 0);
+ guit->misc->warning("Couldn't finalise cookie manager.", 0);
break;
case TREE_HOTLIST:
err = hotlist_fini(tree_hotlist_path);
if (err != NSERROR_OK)
- warn_user("Couldn't finalise hotlist.", 0);
+ guit->misc->warning("Couldn't finalise hotlist.", 0);
break;
case TREE_SSLCERT:
assert(ssl_current_session != NULL &&
@@ -189,7 +191,7 @@ static bool treeview_test_fini(struct tree *tree)
err = sslcert_viewer_fini(ssl_current_session);
ssl_current_session = NULL;
if (err != NSERROR_OK)
- warn_user("Couldn't finalise sslcert viewer.", 0);
+ guit->misc->warning("Couldn't finalise sslcert viewer.", 0);
break;
}
@@ -287,7 +289,7 @@ struct tree *tree_create(unsigned int flags,
tree = calloc(sizeof(struct tree), 1);
if (tree == NULL) {
LOG("calloc failed");
- warn_user(messages_get_errorcode(NSERROR_NOMEM), 0);
+ guit->misc->warning(messages_get_errorcode(NSERROR_NOMEM), 0);
return NULL;
}
diff --git a/desktop/treeview.c b/desktop/treeview.c
index 210c6f9..97cf30d 100644
--- a/desktop/treeview.c
+++ b/desktop/treeview.c
@@ -32,8 +32,8 @@
#include "desktop/plotters.h"
#include "desktop/textarea.h"
#include "desktop/treeview.h"
-#include "desktop/font.h"
#include "desktop/gui_clipboard.h"
+#include "desktop/gui_layout.h"
#include "desktop/gui_internal.h"
/** @todo get rid of REDRAW_MAX -- need to be able to know window size */
@@ -540,10 +540,10 @@ static inline void treeview_insert_node(treeview_node *a,
/* Parent is expanded, so inserted node will be visible and
* affect layout */
if (a->text.width == 0) {
- nsfont.font_width(&plot_style_odd.text,
- a->text.data,
- a->text.len,
- &(a->text.width));
+ guit->layout->width(&plot_style_odd.text,
+ a->text.data,
+ a->text.len,
+ &(a->text.width));
}
do {
@@ -644,7 +644,7 @@ nserror treeview_update_node_folder(treeview *tree,
if (folder->parent->flags & TV_NFLAGS_EXPANDED) {
/* Text will be seen, get its width */
- nsfont.font_width(&plot_style_odd.text,
+ guit->layout->width(&plot_style_odd.text,
folder->text.data,
folder->text.len,
&(folder->text.width));
@@ -694,7 +694,7 @@ nserror treeview_update_node_entry(treeview *tree,
if (entry->parent->flags & TV_NFLAGS_EXPANDED) {
/* Text will be seen, get its width */
- nsfont.font_width(&plot_style_odd.text,
+ guit->layout->width(&plot_style_odd.text,
entry->text.data,
entry->text.len,
&(entry->text.width));
@@ -714,7 +714,7 @@ nserror treeview_update_node_entry(treeview *tree,
if (entry->flags & TV_NFLAGS_EXPANDED) {
/* Text will be seen, get its width */
- nsfont.font_width(&plot_style_odd.text,
+ guit->layout->width(&plot_style_odd.text,
e->fields[i - 1].value.data,
e->fields[i - 1].value.len,
&(e->fields[i - 1].value.width));
@@ -1311,7 +1311,7 @@ nserror treeview_create(treeview **tree,
f->value.data = lwc_string_data(fields[i].field);
f->value.len = lwc_string_length(fields[i].field);
- nsfont.font_width(&plot_style_odd.text, f->value.data,
+ guit->layout->width(&plot_style_odd.text, f->value.data,
f->value.len, &(f->value.width));
if (f->flags & TREE_FLAG_SHOW_NAME)
@@ -1411,7 +1411,7 @@ static nserror treeview_node_expand_internal(treeview *tree,
do {
assert((child->flags & TV_NFLAGS_EXPANDED) == false);
if (child->text.width == 0) {
- nsfont.font_width(&plot_style_odd.text,
+ guit->layout->width(&plot_style_odd.text,
child->text.data,
child->text.len,
&(child->text.width));
@@ -1432,7 +1432,7 @@ static nserror treeview_node_expand_internal(treeview *tree,
for (i = 0; i < tree->n_fields - 1; i++) {
if (e->fields[i].value.width == 0) {
- nsfont.font_width(&plot_style_odd.text,
+ guit->layout->width(&plot_style_odd.text,
e->fields[i].value.data,
e->fields[i].value.len,
&(e->fields[i].value.width));
diff --git a/desktop/version.c b/desktop/version.c
index e456aac..6828f82 100644
--- a/desktop/version.c
+++ b/desktop/version.c
@@ -20,11 +20,11 @@
#include "desktop/version.h"
-const char * const netsurf_version = "3.5 (Dev"
+const char * const netsurf_version = "3.6 (Dev"
#if defined(CI_BUILD)
" CI #" CI_BUILD
#endif
")"
;
const int netsurf_version_major = 3;
-const int netsurf_version_minor = 4;
+const int netsurf_version_minor = 6;
diff --git a/framebuffer/Makefile.target b/framebuffer/Makefile.target
index c0f5e22..44fa5aa 100644
--- a/framebuffer/Makefile.target
+++ b/framebuffer/Makefile.target
@@ -174,7 +174,7 @@ $(eval $(foreach V,$(filter FB_FONT_$(NETSURF_FB_FONTLIB)_%,$(.VARIABLES)),$(cal
# ----------------------------------------------------------------------------
# S_FRAMEBUFFER are sources purely for the framebuffer build
-S_FRAMEBUFFER := gui.c framebuffer.c schedule.c misc.c bitmap.c fetch.c \
+S_FRAMEBUFFER := gui.c framebuffer.c schedule.c bitmap.c fetch.c \
findfile.c localhistory.c clipboard.c
S_FRAMEBUFFER_FBTK := fbtk.c event.c fill.c bitmap.c user.c window.c \
diff --git a/framebuffer/fbtk/fbtk.c b/framebuffer/fbtk/fbtk.c
index 882e5e5..db1c1f1 100644
--- a/framebuffer/fbtk/fbtk.c
+++ b/framebuffer/fbtk/fbtk.c
@@ -18,6 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <stdlib.h>
#include <sys/types.h>
#include <assert.h>
#include <stdint.h>
diff --git a/framebuffer/fbtk/text.c b/framebuffer/fbtk/text.c
index f15586a..3d35583 100644
--- a/framebuffer/fbtk/text.c
+++ b/framebuffer/fbtk/text.c
@@ -29,7 +29,6 @@
#include "utils/log.h"
#include "desktop/browser.h"
-#include "desktop/font.h"
#include "framebuffer/gui.h"
#include "framebuffer/fbtk.h"
@@ -342,7 +341,7 @@ text_input(fbtk_widget_t *widget, fbtk_callback_info *cbi)
widget->u.text.len--;
widget->u.text.text[widget->u.text.len] = 0;
- nsfont.font_width(&font_style, widget->u.text.text,
+ fb_font_width(&font_style, widget->u.text.text,
widget->u.text.len, &widget->u.text.width);
caret_moved = true;
@@ -428,14 +427,14 @@ text_input(fbtk_widget_t *widget, fbtk_callback_info *cbi)
widget->u.text.len++;
widget->u.text.text[widget->u.text.len] = '\0';
- nsfont.font_width(&font_style, widget->u.text.text,
+ fb_font_width(&font_style, widget->u.text.text,
widget->u.text.len, &widget->u.text.width);
caret_moved = true;
break;
}
if (caret_moved) {
- nsfont.font_width(&font_style, widget->u.text.text,
+ fb_font_width(&font_style, widget->u.text.text,
widget->u.text.idx, &widget->u.text.idx_offset);
fbtk_set_caret(widget, true,
widget->u.text.idx_offset + border,
@@ -467,7 +466,7 @@ text_input_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
widget->u.text.idx = widget->u.text.len;
- nsfont.font_position_in_string(&font_style, widget->u.text.text,
+ fb_font_position(&font_style, widget->u.text.text,
widget->u.text.len, cbi->x - border,
&idx,
&widget->u.text.idx_offset);
@@ -529,9 +528,9 @@ fbtk_set_text(fbtk_widget_t *widget, const char *text)
fb_text_font_style(widget, &fh, &border, &font_style);
- nsfont.font_width(&font_style, widget->u.text.text,
+ fb_font_width(&font_style, widget->u.text.text,
widget->u.text.len, &widget->u.text.width);
- nsfont.font_width(&font_style, widget->u.text.text,
+ fb_font_width(&font_style, widget->u.text.text,
widget->u.text.idx, &widget->u.text.idx_offset);
if (fbtk_get_caret(widget, &c_x, &c_y, &c_h)) {
diff --git a/framebuffer/font.h b/framebuffer/font.h
index 6350421..722a604 100644
--- a/framebuffer/font.h
+++ b/framebuffer/font.h
@@ -19,13 +19,45 @@
#ifndef NETSURF_FB_FONT_H
#define NETSURF_FB_FONT_H
-#include "utils/utf8.h"
-
+extern struct gui_layout_table *framebuffer_layout_table;
extern struct gui_utf8_table *framebuffer_utf8_table;
+/**
+ * Initialise framebuffer font handling.
+ */
bool fb_font_init(void);
+
+/**
+ * Finalise framebuffer font handling.
+ */
bool fb_font_finalise(void);
+/**
+ * Find the position in a string where an x coordinate falls.
+ *
+ * \param[in] fstyle style for this text
+ * \param[in] string UTF-8 string to measure
+ * \param[in] length length of string, in bytes
+ * \param[in] x coordinate to search for
+ * \param[out] char_offset updated to offset in string of actual_x, [0..length]
+ * \param[out] actual_x updated to x coordinate of character closest to x
+ * \return NSERROR_OK and char_offset and actual_x updated or
+ * appropriate error code on faliure
+ */
+nserror fb_font_position(const struct plot_font_style *fstyle, const char *string, size_t length, int x, size_t *char_offset, int *actual_x);
+
+/**
+ * Measure the width of a string.
+ *
+ * \param[in] fstyle plot style for this text
+ * \param[in] string UTF-8 string to measure
+ * \param[in] length length of string, in bytes
+ * \param[out] width updated to width of string[0..length)
+ * \return NSERROR_OK and width updated or appropriate error code on faliure
+ */
+nserror fb_font_width(const struct plot_font_style *fstyle, const char *string, size_t length, int *width);
+
+
#ifdef FB_USE_FREETYPE
#include "framebuffer/font_freetype.h"
#else
diff --git a/framebuffer/font_freetype.c b/framebuffer/font_freetype.c
index ec3ceab..7756ae7 100644
--- a/framebuffer/font_freetype.c
+++ b/framebuffer/font_freetype.c
@@ -28,7 +28,7 @@
#include "utils/log.h"
#include "utils/nsoption.h"
#include "desktop/gui_utf8.h"
-#include "desktop/font.h"
+#include "desktop/gui_layout.h"
#include "desktop/browser.h"
#include "framebuffer/gui.h"
@@ -74,8 +74,14 @@ enum fb_face_e {
static fb_faceid_t *fb_faces[FB_FACE_COUNT];
-/* map cache manager handle to face id */
-static FT_Error ft_face_requester(FTC_FaceID face_id, FT_Library library, FT_Pointer request_data, FT_Face *face )
+/**
+ * map cache manager handle to face id
+ */
+static FT_Error
+ft_face_requester(FTC_FaceID face_id,
+ FT_Library library,
+ FT_Pointer request_data,
+ FT_Face *face )
{
FT_Error error;
fb_faceid_t *fb_face = (fb_faceid_t *)face_id;
@@ -103,7 +109,9 @@ static FT_Error ft_face_requester(FTC_FaceID face_id, FT_Library library, FT_Po
return error;
}
-/* create new framebuffer face and cause it to be loaded to check its ok */
+/**
+ * create new framebuffer face and cause it to be loaded to check its ok
+ */
static fb_faceid_t *
fb_new_face(const char *option, const char *resname, const char *fontname)
{
@@ -132,7 +140,7 @@ fb_new_face(const char *option, const char *resname, const char *fontname)
return newf;
}
-/* initialise font handling */
+/* exported interface documented in framebuffer/font.h */
bool fb_font_init(void)
{
FT_Error error;
@@ -298,6 +306,7 @@ bool fb_font_init(void)
return true;
}
+/* exported interface documented in framebuffer/font.h */
bool fb_font_finalise(void)
{
int i, j;
@@ -324,6 +333,9 @@ bool fb_font_finalise(void)
return true;
}
+/**
+ * fill freetype scalar
+ */
static void fb_fill_scalar(const plot_font_style_t *fstyle, FTC_Scaler srec)
{
int selected_face = FB_FACE_DEFAULT;
@@ -380,6 +392,7 @@ static void fb_fill_scalar(const plot_font_style_t *fstyle, FTC_Scaler srec)
srec->x_res = srec->y_res = browser_get_dpi();
}
+/* exported interface documented in framebuffer/freetype_font.h */
FT_Glyph fb_getglyph(const plot_font_style_t *fstyle, uint32_t ucs4)
{
FT_UInt glyph_index;
@@ -410,16 +423,9 @@ FT_Glyph fb_getglyph(const plot_font_style_t *fstyle, uint32_t ucs4)
}
-/**
- * Measure the width of a string.
- *
- * \param fstyle style for this text
- * \param string UTF-8 string to measure
- * \param length length of string
- * \param width updated to width of string[0..length)
- * \return true on success, false on error and error reported
- */
-static bool nsfont_width(const plot_font_style_t *fstyle,
+/* exported interface documented in framebuffer/freetype_font.h */
+nserror
+fb_font_width(const plot_font_style_t *fstyle,
const char *string, size_t length,
int *width)
{
@@ -442,19 +448,10 @@ static bool nsfont_width(const plot_font_style_t *fstyle,
return true;
}
-/**
- * Find the position in a string where an x coordinate falls.
- *
- * \param fstyle style for this text
- * \param string UTF-8 string to measure
- * \param length length of string
- * \param x x coordinate to search for
- * \param char_offset updated to offset in string of actual_x, [0..length]
- * \param actual_x updated to x coordinate of character closest to x
- * \return true on success, false on error and error reported
- */
-static bool nsfont_position_in_string(const plot_font_style_t *fstyle,
+/* exported interface documented in framebuffer/freetype_font.h */
+nserror
+fb_font_position(const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x)
{
@@ -510,8 +507,8 @@ static bool nsfont_position_in_string(const plot_font_style_t *fstyle,
*
* Returning char_offset == length means no split possible
*/
-
-static bool nsfont_split(const plot_font_style_t *fstyle,
+static nserror
+fb_font_split(const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x)
{
@@ -551,12 +548,15 @@ static bool nsfont_split(const plot_font_style_t *fstyle,
return true;
}
-const struct font_functions nsfont = {
- nsfont_width,
- nsfont_position_in_string,
- nsfont_split
+static struct gui_layout_table layout_table = {
+ .width = fb_font_width,
+ .position = fb_font_position,
+ .split = fb_font_split,
};
+struct gui_layout_table *framebuffer_layout_table = &layout_table;
+
+
struct gui_utf8_table *framebuffer_utf8_table = NULL;
/*
diff --git a/framebuffer/font_internal.c b/framebuffer/font_internal.c
index fba298f..7578e64 100644
--- a/framebuffer/font_internal.c
+++ b/framebuffer/font_internal.c
@@ -25,7 +25,7 @@
#include "utils/nsoption.h"
#include "utils/utf8.h"
#include "desktop/gui_utf8.h"
-#include "desktop/font.h"
+#include "desktop/gui_layout.h"
#include "framebuffer/gui.h"
#include "framebuffer/font.h"
@@ -343,9 +343,12 @@ static nserror utf8_from_local(const char *string,
}
-static bool nsfont_width(const plot_font_style_t *fstyle,
- const char *string, size_t length,
- int *width)
+/* exported interface documented in framebuffer/freetype_font.h */
+nserror
+fb_font_width(const plot_font_style_t *fstyle,
+ const char *string,
+ size_t length,
+ int *width)
{
size_t nxtchr = 0;
@@ -364,21 +367,15 @@ static bool nsfont_width(const plot_font_style_t *fstyle,
return true;
}
-/**
- * Find the position in a string where an x coordinate falls.
- *
- * \param fstyle style for this text
- * \param string UTF-8 string to measure
- * \param length length of string
- * \param x x coordinate to search for
- * \param char_offset updated to offset in string of actual_x, [0..length]
- * \param actual_x updated to x coordinate of character closest to x
- * \return true on success, false on error and error reported
- */
-static bool nsfont_position_in_string(const plot_font_style_t *fstyle,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x)
+/* exported interface documented in framebuffer/freetype_font.h */
+nserror
+fb_font_position(const plot_font_style_t *fstyle,
+ const char *string,
+ size_t length,
+ int x,
+ size_t *char_offset,
+ int *actual_x)
{
const int width = fb_get_font_size(fstyle) * FB_FONT_WIDTH;
size_t nxtchr = 0;
@@ -404,7 +401,6 @@ static bool nsfont_position_in_string(const plot_font_style_t *fstyle,
}
-
/**
* Find where to split a string to make it fit a width.
*
@@ -427,10 +423,13 @@ static bool nsfont_position_in_string(const plot_font_style_t *fstyle,
*
* Returning char_offset == length means no split possible
*/
-
-static bool nsfont_split(const plot_font_style_t *fstyle,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x)
+static nserror
+fb_font_split(const plot_font_style_t *fstyle,
+ const char *string,
+ size_t length,
+ int x,
+ size_t *char_offset,
+ int *actual_x)
{
const int width = fb_get_font_size(fstyle) * FB_FONT_WIDTH;
size_t nxtchr = 0;
@@ -467,12 +466,16 @@ static bool nsfont_split(const plot_font_style_t *fstyle,
return true;
}
-const struct font_functions nsfont = {
- nsfont_width,
- nsfont_position_in_string,
- nsfont_split
+
+static struct gui_layout_table layout_table = {
+ .width = fb_font_width,
+ .position = fb_font_position,
+ .split = fb_font_split,
};
+struct gui_layout_table *framebuffer_layout_table = &layout_table;
+
+
static struct gui_utf8_table utf8_table = {
.utf8_to_local = utf8_to_local,
.local_to_utf8 = utf8_from_local,
diff --git a/framebuffer/font_internal.h b/framebuffer/font_internal.h
index d066f6b..f25df8d 100644
--- a/framebuffer/font_internal.h
+++ b/framebuffer/font_internal.h
@@ -40,10 +40,10 @@ enum fb_font_style {
enum fb_font_style fb_get_font_style(const plot_font_style_t *fstyle);
int fb_get_font_size(const plot_font_style_t *fstyle);
-const uint8_t *fb_get_glyph(uint32_t ucs4, enum fb_font_style style, int scale);
-
#define codepoint_displayable(u) \
(!(u >= 0x200b && u <= 0x200f))
+const uint8_t *fb_get_glyph(uint32_t ucs4, enum fb_font_style style, int scale);
+
#endif /* NETSURF_FB_FONT_INTERNAL_H */
diff --git a/framebuffer/framebuffer.c b/framebuffer/framebuffer.c
index 97760cf..7d811aa 100644
--- a/framebuffer/framebuffer.c
+++ b/framebuffer/framebuffer.c
@@ -30,6 +30,7 @@
#include "utils/utils.h"
#include "utils/log.h"
+#include "utils/utf8.h"
#include "desktop/browser.h"
#include "image/bitmap.h"
diff --git a/framebuffer/gui.c b/framebuffer/gui.c
index ef1d8c6..7e48b65 100644
--- a/framebuffer/gui.c
+++ b/framebuffer/gui.c
@@ -16,12 +16,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <stdint.h>
#include <limits.h>
#include <getopt.h>
#include <assert.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
+#include <nsutils/time.h>
#include <libnsfb.h>
#include <libnsfb_plot.h>
@@ -106,6 +108,21 @@ static void die(const char *error)
exit(1);
}
+
+/**
+ * Warn the user of an event.
+ *
+ * \param[in] message A warning looked up in the message translation table
+ * \param[in] detail Additional text to be displayed or NULL.
+ * \return NSERROR_OK on success or error code if there was a
+ * faliure displaying the message to the user.
+ */
+static nserror fb_warn_user(const char *warning, const char *detail)
+{
+ LOG("%s %s", warning, detail);
+ return NSERROR_OK;
+}
+
/* queue a redraw operation, co-ordinates are relative to the window */
static void
fb_queue_redraw(struct fbtk_widget_s *widget, int x0, int y0, int x1, int y1)
@@ -611,10 +628,10 @@ fb_browser_window_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
float scale = browser_window_get_scale(gw->bw);
int x = (cbi->x + bwidget->scrollx) / scale;
int y = (cbi->y + bwidget->scrolly) / scale;
- unsigned int time_now;
+ uint64_t time_now;
static struct {
enum { CLICK_SINGLE, CLICK_DOUBLE, CLICK_TRIPLE } type;
- unsigned int time;
+ uint64_t time;
} last_click;
if (cbi->event->type != NSFB_EVENT_KEY_DOWN &&
@@ -667,7 +684,7 @@ fb_browser_window_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
case NSFB_EVENT_KEY_UP:
mouse = 0;
- time_now = wallclock();
+ nsu_getmonotonic_ms(&time_now);
switch (cbi->event->value.keycode) {
case NSFB_KEY_MOUSE_1:
@@ -719,10 +736,11 @@ fb_browser_window_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
}
/* Determine if it's a double or triple click, allowing
- * 0.5 seconds (50cs) between clicks */
- if (time_now < last_click.time + 50 &&
- cbi->event->value.keycode != NSFB_KEY_MOUSE_4 &&
- cbi->event->value.keycode != NSFB_KEY_MOUSE_5) {
+ * 0.5 seconds (500ms) between clicks
+ */
+ if ((time_now < (last_click.time + 500)) &&
+ (cbi->event->value.keycode != NSFB_KEY_MOUSE_4) &&
+ (cbi->event->value.keycode != NSFB_KEY_MOUSE_5)) {
if (last_click.type == CLICK_SINGLE) {
/* Set double click */
mouse |= BROWSER_MOUSE_DOUBLE_CLICK;
@@ -740,8 +758,9 @@ fb_browser_window_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
last_click.type = CLICK_SINGLE;
}
- if (mouse)
+ if (mouse) {
browser_window_mouse_click(gw->bw, mouse, x, y);
+ }
last_click.time = time_now;
@@ -1099,7 +1118,7 @@ fb_url_enter(void *pw, char *text)
error = nsurl_create(text, &url);
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ fb_warn_user(messages_get_errorcode(error), 0);
} else {
browser_window_navigate(bw, url, NULL, BW_NAVIGATE_HISTORY,
NULL, NULL, NULL);
@@ -2050,8 +2069,9 @@ static struct gui_window_table framebuffer_window_table = {
};
-static struct gui_browser_table framebuffer_browser_table = {
+static struct gui_misc_table framebuffer_misc_table = {
.schedule = framebuffer_schedule,
+ .warning = fb_warn_user,
.quit = gui_quit,
};
@@ -2072,12 +2092,13 @@ main(int argc, char** argv)
nserror ret;
nsfb_t *nsfb;
struct netsurf_table framebuffer_table = {
- .browser = &framebuffer_browser_table,
+ .misc = &framebuffer_misc_table,
.window = &framebuffer_window_table,
.clipboard = framebuffer_clipboard_table,
.fetch = framebuffer_fetch_table,
.utf8 = framebuffer_utf8_table,
.bitmap = framebuffer_bitmap_table,
+ .layout = framebuffer_layout_table,
};
ret = netsurf_register(&framebuffer_table);
@@ -2151,7 +2172,7 @@ main(int argc, char** argv)
nsurl_unref(url);
}
if (ret != NSERROR_OK) {
- warn_user(messages_get_errorcode(ret), 0);
+ fb_warn_user(messages_get_errorcode(ret), 0);
} else {
framebuffer_run();
diff --git a/framebuffer/misc.c b/framebuffer/misc.c
deleted file mode 100644
index f1f9681..0000000
--- a/framebuffer/misc.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2008 Vincent Sanders <vince(a)simtec.co.uk>
- *
- * This file is part of NetSurf, http://www.netsurf-browser.org/
- *
- * NetSurf is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * NetSurf is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <sys/types.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "utils/log.h"
-#include "utils/messages.h"
-#include "utils/utils.h"
-
-void warn_user(const char *warning, const char *detail)
-{
- LOG("%s %s", warning, detail);
-}
-
-
diff --git a/framebuffer/schedule.c b/framebuffer/schedule.c
index d814679..581ad72 100644
--- a/framebuffer/schedule.c
+++ b/framebuffer/schedule.c
@@ -16,10 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <sys/time.h>
#include <time.h>
#include <stdlib.h>
+#include "utils/sys_time.h"
#include "utils/log.h"
#include "framebuffer/schedule.h"
diff --git a/gtk/Makefile.target b/gtk/Makefile.target
index bade14d..e450135 100644
--- a/gtk/Makefile.target
+++ b/gtk/Makefile.target
@@ -176,10 +176,10 @@ endif
# ----------------------------------------------------------------------------
# S_GTK are sources purely for the GTK build
-S_GTK := font_pango.c bitmap.c gui.c schedule.c plotters.c \
+S_GTK := gui.c schedule.c layout_pango.c bitmap.c plotters.c \
treeview.c scaffolding.c gdk.c completion.c login.c throbber.c \
selection.c history.c window.c fetch.c download.c menu.c \
- print.c search.c tabs.c toolbar.c gettext.c \
+ print.c search.c tabs.c toolbar.c gettext.c \
compat.c cookies.c hotlist.c viewdata.c viewsource.c \
preferences.c about.c ssl_cert.c resources.c
diff --git a/gtk/about.c b/gtk/about.c
index b2f5a52..52672d5 100644
--- a/gtk/about.c
+++ b/gtk/about.c
@@ -22,6 +22,7 @@
* Implementation of gtk about dialog.
*/
+#include <stdlib.h>
#include <stdint.h>
#include "utils/utils.h"
@@ -31,6 +32,7 @@
#include "desktop/browser.h"
#include "desktop/version.h"
+#include "gtk/warn.h"
#include "gtk/compat.h"
#include "gtk/about.h"
@@ -60,7 +62,7 @@ static void about_open(const char *url_text)
}
if (ret != NSERROR_OK) {
- warn_user(messages_get_errorcode(ret), 0);
+ nsgtk_warning(messages_get_errorcode(ret), 0);
}
}
diff --git a/gtk/bitmap.c b/gtk/bitmap.c
index fa86ff1..f8dcf1d 100644
--- a/gtk/bitmap.c
+++ b/gtk/bitmap.c
@@ -26,9 +26,11 @@
#include <assert.h>
#include <stdbool.h>
#include <string.h>
+#include <stdlib.h>
#include <cairo.h>
#include <gtk/gtk.h>
+#include "utils/utils.h"
#include "utils/log.h"
#include "content/content.h"
#include "image/bitmap.h"
diff --git a/gtk/completion.c b/gtk/completion.c
index 1f86cc7..76880da 100644
--- a/gtk/completion.c
+++ b/gtk/completion.c
@@ -31,6 +31,7 @@
#include "desktop/searchweb.h"
#include "desktop/browser.h"
+#include "gtk/warn.h"
#include "gtk/window.h"
#include "gtk/completion.h"
@@ -99,7 +100,7 @@ nsgtk_completion_match_select(GtkEntryCompletion *widget,
nsurl_unref(url);
}
if (ret != NSERROR_OK) {
- warn_user(messages_get_errorcode(ret), 0);
+ nsgtk_warning(messages_get_errorcode(ret), 0);
}
return TRUE;
diff --git a/gtk/download.c b/gtk/download.c
index 23832de..b7eea25 100644
--- a/gtk/download.c
+++ b/gtk/download.c
@@ -28,9 +28,11 @@
#include "utils/nsurl.h"
#include "utils/messages.h"
#include "utils/nsoption.h"
+#include "utils/string.h"
#include "desktop/download.h"
#include "desktop/gui_download.h"
+#include "gtk/warn.h"
#include "gtk/scaffolding.h"
#include "gtk/window.h"
#include "gtk/compat.h"
@@ -636,7 +638,7 @@ static gchar* nsgtk_download_dialog_show (const gchar *filename, const gchar *do
destination = malloc(strlen(nsoption_charp(downloads_directory))
+ strlen(filename) + SLEN("/") + 1);
if (destination == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
break;
}
sprintf(destination, "%s/%s",
diff --git a/gtk/gui.c b/gtk/gui.c
index ef83f96..e705918 100644
--- a/gtk/gui.c
+++ b/gtk/gui.c
@@ -1,6 +1,6 @@
/*
* Copyright 2004-2010 James Bursa <bursa(a)users.sourceforge.net>
- * Copyright 2010 Vincent Sanders <vince(a)debian.org>
+ * Copyright 2010-2016 Vincent Sanders <vince(a)netsurf-browser.org>
* Copyright 2004-2009 John-Mark Bell <jmb(a)netsurf-browser.org>
* Copyright 2009 Paul Blokus <paul_pl(a)users.sourceforge.net>
* Copyright 2006-2009 Daniel Silverstone <dsilvers(a)netsurf-browser.org>
@@ -52,6 +52,7 @@
#include "desktop/netsurf.h"
#include "gtk/compat.h"
+#include "gtk/warn.h"
#include "gtk/completion.h"
#include "gtk/cookies.h"
#include "gtk/download.h"
@@ -69,6 +70,7 @@
#include "gtk/bitmap.h"
#include "gtk/resources.h"
#include "gtk/login.h"
+#include "gtk/layout_pango.h"
bool nsgtk_complete = false;
@@ -473,13 +475,14 @@ static nserror gui_launch_url(struct nsurl *url)
}
if (error) {
- warn_user(messages_get("URIOpenError"), error->message);
+ nsgtk_warning(messages_get("URIOpenError"), error->message);
g_error_free(error);
}
return NSERROR_NO_FETCH_HANDLER;
}
-void warn_user(const char *warning, const char *detail)
+/* exported function documented in gtk/warn.h */
+nserror nsgtk_warning(const char *warning, const char *detail)
{
char buf[300]; /* 300 is the size the RISC OS GUI uses */
static GtkWindow *nsgtk_warning_window;
@@ -499,6 +502,8 @@ void warn_user(const char *warning, const char *detail)
gtk_label_set_text(WarningLabel, buf);
gtk_widget_show_all(GTK_WIDGET(nsgtk_warning_window));
+
+ return NSERROR_OK;
}
@@ -1010,8 +1015,9 @@ static nserror nsgtk_option_init(int *pargc, char** argv)
return NSERROR_OK;
}
-static struct gui_browser_table nsgtk_browser_table = {
+static struct gui_misc_table nsgtk_misc_table = {
.schedule = nsgtk_schedule,
+ .warning = nsgtk_warning,
.quit = gui_quit,
.launch_url = gui_launch_url,
@@ -1049,7 +1055,7 @@ int main(int argc, char** argv)
char *cache_home = NULL;
nserror ret;
struct netsurf_table nsgtk_table = {
- .browser = &nsgtk_browser_table,
+ .misc = &nsgtk_misc_table,
.window = nsgtk_window_table,
.clipboard = nsgtk_clipboard_table,
.download = nsgtk_download_table,
@@ -1058,6 +1064,7 @@ int main(int argc, char** argv)
.search = nsgtk_search_table,
.search_web = nsgtk_search_web_table,
.bitmap = nsgtk_bitmap_table,
+ .layout = nsgtk_layout_table,
};
ret = netsurf_register(&nsgtk_table);
diff --git a/gtk/history.c b/gtk/history.c
index db30c5b..2f11042 100644
--- a/gtk/history.c
+++ b/gtk/history.c
@@ -17,6 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <stdlib.h>
#include <gtk/gtk.h>
#include "utils/log.h"
diff --git a/gtk/font_pango.c b/gtk/layout_pango.c
similarity index 71%
rename from gtk/font_pango.c
rename to gtk/layout_pango.c
index b28d883..f3f0e07 100644
--- a/gtk/font_pango.c
+++ b/gtk/layout_pango.c
@@ -16,8 +16,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
- * Font handling (GTK implementation).
+/**
+ * \file
+ * GTK implementation of layout handling using pango.
*
* Pango is used handle and render fonts.
*/
@@ -30,29 +31,11 @@
#include "utils/utils.h"
#include "utils/log.h"
#include "utils/nsoption.h"
-#include "desktop/font.h"
+#include "desktop/gui_layout.h"
-#include "gtk/font_pango.h"
+#include "gtk/layout_pango.h"
#include "gtk/plotters.h"
-static bool nsfont_width(const plot_font_style_t *fstyle,
- const char *string, size_t length,
- int *width);
-
-static bool nsfont_position_in_string(const plot_font_style_t *fstyle,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x);
-
-static bool nsfont_split(const plot_font_style_t *style,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x);
-
-const struct font_functions nsfont = {
- nsfont_width,
- nsfont_position_in_string,
- nsfont_split
-};
-
static PangoContext *nsfont_pango_context = NULL;
static PangoLayout *nsfont_pango_layout = NULL;
@@ -72,22 +55,23 @@ static inline void nsfont_pango_check(void)
/**
* Measure the width of a string.
*
- * \param fstyle plot style for this text
- * \param string UTF-8 string to measure
- * \param length length of string
- * \param width updated to width of string[0..length)
- * \return true on success, false on error and error reported
+ * \param[in] fstyle plot style for this text
+ * \param[in] string UTF-8 string to measure
+ * \param[in] length length of string, in bytes
+ * \param[out] width updated to width of string[0..length)
+ * \return NSERROR_OK and width updated or appropriate error code on faliure
*/
-
-bool nsfont_width(const plot_font_style_t *fstyle,
- const char *string, size_t length,
- int *width)
+static nserror
+nsfont_width(const plot_font_style_t *fstyle,
+ const char *string,
+ size_t length,
+ int *width)
{
PangoFontDescription *desc;
if (length == 0) {
*width = 0;
- return true;
+ return NSERROR_OK;
}
nsfont_pango_check();
@@ -104,25 +88,29 @@ bool nsfont_width(const plot_font_style_t *fstyle,
fstyle, length, string, length, *width);
*/
- return true;
+ return NSERROR_OK;
}
/**
* Find the position in a string where an x coordinate falls.
*
- * \param fstyle plot style for this text
- * \param string UTF-8 string to measure
- * \param length length of string
- * \param x x coordinate to search for
- * \param char_offset updated to offset in string of actual_x, [0..length]
- * \param actual_x updated to x coordinate of character closest to x
- * \return true on success, false on error and error reported
+ * \param[in] fstyle style for this text
+ * \param[in] string UTF-8 string to measure
+ * \param[in] length length of string, in bytes
+ * \param[in] x coordinate to search for
+ * \param[out] char_offset updated to offset in string of actual_x, [0..length]
+ * \param[out] actual_x updated to x coordinate of character closest to x
+ * \return NSERROR_OK and char_offset and actual_x updated or appropriate
+ * error code on faliure
*/
-
-bool nsfont_position_in_string(const plot_font_style_t *fstyle,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x)
+static nserror
+nsfont_position_in_string(const plot_font_style_t *fstyle,
+ const char *string,
+ size_t length,
+ int x,
+ size_t *char_offset,
+ int *actual_x)
{
int index;
PangoFontDescription *desc;
@@ -136,33 +124,35 @@ bool nsfont_position_in_string(const plot_font_style_t *fstyle,
pango_layout_set_text(nsfont_pango_layout, string, length);
- if (pango_layout_xy_to_index(nsfont_pango_layout, x * PANGO_SCALE,
- 0, &index, 0) == FALSE)
+ if (pango_layout_xy_to_index(nsfont_pango_layout,
+ x * PANGO_SCALE,
+ 0, &index, 0) == FALSE) {
index = length;
+ }
pango_layout_index_to_pos(nsfont_pango_layout, index, &pos);
*char_offset = index;
*actual_x = PANGO_PIXELS(pos.x);
- return true;
+ return NSERROR_OK;
}
/**
* Find where to split a string to make it fit a width.
*
- * \param fstyle style for this text
- * \param string UTF-8 string to measure
- * \param length length of string, in bytes
- * \param x width available
- * \param char_offset updated to offset in string of actual_x, [1..length]
- * \param actual_x updated to x coordinate of character closest to x
- * \return true on success, false on error and error reported
+ * \param[in] fstyle style for this text
+ * \param[in] string UTF-8 string to measure
+ * \param[in] length length of string, in bytes
+ * \param[in] x width available
+ * \param[out] char_offset updated to offset in string of actual_x, [1..length]
+ * \param[out] actual_x updated to x coordinate of character closest to x
+ * \return NSERROR_OK or appropriate error code on faliure
*
* On exit, char_offset indicates first character after split point.
*
- * Note: char_offset of 0 should never be returned.
+ * \note char_offset of 0 must never be returned.
*
* Returns:
* char_offset giving split point closest to x, where actual_x <= x
@@ -171,10 +161,13 @@ bool nsfont_position_in_string(const plot_font_style_t *fstyle,
*
* Returning char_offset == length means no split possible
*/
-
-bool nsfont_split(const plot_font_style_t *fstyle,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x)
+static nserror
+nsfont_split(const plot_font_style_t *fstyle,
+ const char *string,
+ size_t length,
+ int x,
+ size_t *char_offset,
+ int *actual_x)
{
int index = length;
PangoFontDescription *desc;
@@ -215,7 +208,7 @@ bool nsfont_split(const plot_font_style_t *fstyle,
/* Obtain the pixel offset of the split character */
nsfont_width(fstyle, string, index, actual_x);
- return true;
+ return NSERROR_OK;
}
@@ -229,7 +222,6 @@ bool nsfont_split(const plot_font_style_t *fstyle,
* \param fstyle plot style for this text
* \return true on success, false on error and error reported
*/
-
bool nsfont_paint(int x, int y, const char *string, size_t length,
const plot_font_style_t *fstyle)
{
@@ -259,15 +251,9 @@ bool nsfont_paint(int x, int y, const char *string, size_t length,
}
-/**
- * Convert a plot style to a PangoFontDescription.
- *
- * \param fstyle plot style for this text
- * \return A new Pango font description
- */
-
-PangoFontDescription *nsfont_style_to_description(
- const plot_font_style_t *fstyle)
+/* exported interface documented in gtk/layout_pango.h */
+PangoFontDescription *
+nsfont_style_to_description(const plot_font_style_t *fstyle)
{
unsigned int size;
PangoFontDescription *desc;
@@ -315,3 +301,10 @@ PangoFontDescription *nsfont_style_to_description(
return desc;
}
+static struct gui_layout_table layout_table = {
+ .width = nsfont_width,
+ .position = nsfont_position_in_string,
+ .split = nsfont_split,
+};
+
+struct gui_layout_table *nsgtk_layout_table = &layout_table;
diff --git a/gtk/font_pango.h b/gtk/layout_pango.h
similarity index 62%
rename from gtk/font_pango.h
rename to gtk/layout_pango.h
index edcd19b..137cebe 100644
--- a/gtk/font_pango.h
+++ b/gtk/layout_pango.h
@@ -16,22 +16,28 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
- * Font handling (GTK interface).
+/**
+ * \file
+ * Interface to GTK layout handling using pango.
*/
-#ifndef _NETSURF_GTK_FONT_PANGO_H_
-#define _NETSURF_GTK_FONT_PANGO_H_
+#ifndef _NETSURF_GTK_LAYOUT_PANGO_H_
+#define _NETSURF_GTK_LAYOUT_PANGO_H_
#include <stdbool.h>
-#include "desktop/plot_style.h"
+struct plot_font_style;
-bool nsfont_paint(int x, int y, const char *string, size_t length,
- const plot_font_style_t *fstyle);
+extern struct gui_layout_table *nsgtk_layout_table;
+
+bool nsfont_paint(int x, int y, const char *string, size_t length, const struct plot_font_style *fstyle);
+
+/**
+ * Convert a plot style to a PangoFontDescription.
+ *
+ * \param fstyle plot style for this text
+ * \return A new Pango font description
+ */
+PangoFontDescription *nsfont_style_to_description(const struct plot_font_style *fstyle);
-PangoFontDescription *nsfont_style_to_description(
- const plot_font_style_t *fstyle);
-
-
#endif
diff --git a/gtk/menu.c b/gtk/menu.c
index 6052d14..041a5ec 100644
--- a/gtk/menu.c
+++ b/gtk/menu.c
@@ -26,6 +26,7 @@
#include "gtk/compat.h"
#include "gtk/menu.h"
+#include "gtk/warn.h"
/**
* Adds image menu item to a menu.
@@ -135,12 +136,12 @@ static struct nsgtk_export_submenu *nsgtk_menu_export_submenu(GtkAccelGroup *gro
struct nsgtk_export_submenu *ret = malloc(sizeof(struct
nsgtk_export_submenu));
if (ret == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
return NULL;
}
ret->export_menu = GTK_MENU(gtk_menu_new());
if (ret->export_menu == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
free(ret);
return NULL;
}
@@ -162,12 +163,12 @@ static struct nsgtk_scaleview_submenu *nsgtk_menu_scaleview_submenu(
struct nsgtk_scaleview_submenu *ret =
malloc(sizeof(struct nsgtk_scaleview_submenu));
if (ret == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
return NULL;
}
ret->scaleview_menu = GTK_MENU(gtk_menu_new());
if (ret->scaleview_menu == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
free(ret);
return NULL;
}
@@ -186,12 +187,12 @@ static struct nsgtk_tabs_submenu *nsgtk_menu_tabs_submenu(GtkAccelGroup *group)
{
struct nsgtk_tabs_submenu *ret = malloc(sizeof(struct nsgtk_tabs_submenu));
if (ret == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
return NULL;
}
ret->tabs_menu = GTK_MENU(gtk_menu_new());
if (ret->tabs_menu == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
free(ret);
return NULL;
}
@@ -212,12 +213,12 @@ static struct nsgtk_images_submenu *nsgtk_menu_images_submenu(GtkAccelGroup *gro
struct nsgtk_images_submenu *ret =
malloc(sizeof(struct nsgtk_images_submenu));
if (ret == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
return NULL;
}
ret->images_menu = GTK_MENU(gtk_menu_new());
if (ret->images_menu == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
free(ret);
return NULL;
}
@@ -237,12 +238,12 @@ static struct nsgtk_toolbars_submenu *nsgtk_menu_toolbars_submenu(
struct nsgtk_toolbars_submenu *ret =
malloc(sizeof(struct nsgtk_toolbars_submenu));
if (ret == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
return NULL;
}
ret->toolbars_menu = GTK_MENU(gtk_menu_new());
if (ret->toolbars_menu == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
free(ret);
return NULL;
}
@@ -266,12 +267,12 @@ static struct nsgtk_developer_submenu *nsgtk_menu_developer_submenu(
struct nsgtk_developer_submenu *dmenu =
malloc(sizeof(struct nsgtk_developer_submenu));
if (dmenu == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
return NULL;
}
dmenu->developer_menu = GTK_MENU(gtk_menu_new());
if (dmenu->developer_menu == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
free(dmenu);
return NULL;
}
@@ -296,13 +297,13 @@ static struct nsgtk_file_menu *nsgtk_menu_file_submenu(GtkAccelGroup *group)
fmenu = malloc(sizeof(struct nsgtk_file_menu));
if (fmenu == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
return NULL;
}
fmenu->file_menu = GTK_MENU(gtk_menu_new());
if (fmenu->file_menu == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
free(fmenu);
return NULL;
}
@@ -333,12 +334,12 @@ static struct nsgtk_edit_menu *nsgtk_menu_edit_submenu(GtkAccelGroup *group)
{
struct nsgtk_edit_menu *ret = malloc(sizeof(struct nsgtk_edit_menu));
if (ret == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
return NULL;
}
ret->edit_menu = GTK_MENU(gtk_menu_new());
if (ret->edit_menu == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
free(ret);
return NULL;
}
@@ -365,12 +366,12 @@ static struct nsgtk_view_menu *nsgtk_menu_view_submenu(GtkAccelGroup *group)
{
struct nsgtk_view_menu *ret = malloc(sizeof(struct nsgtk_view_menu));
if (ret == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
return NULL;
}
ret->view_menu = GTK_MENU(gtk_menu_new());
if (ret->view_menu == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
free(ret);
return NULL;
}
@@ -403,12 +404,12 @@ static struct nsgtk_nav_menu *nsgtk_menu_nav_submenu(GtkAccelGroup *group)
{
struct nsgtk_nav_menu *ret = malloc(sizeof(struct nsgtk_nav_menu));
if (ret == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
return NULL;
}
ret->nav_menu = GTK_MENU(gtk_menu_new());
if (ret->nav_menu == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
free(ret);
return NULL;
}
@@ -437,12 +438,12 @@ static struct nsgtk_tools_menu *nsgtk_menu_tools_submenu(GtkAccelGroup *group)
{
struct nsgtk_tools_menu *ret = malloc(sizeof(struct nsgtk_tools_menu));
if (ret == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
return NULL;
}
ret->tools_menu = GTK_MENU(gtk_menu_new());
if (ret->tools_menu == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
free(ret);
return NULL;
}
@@ -463,12 +464,12 @@ static struct nsgtk_help_menu *nsgtk_menu_help_submenu(GtkAccelGroup *group)
{
struct nsgtk_help_menu *ret = malloc(sizeof(struct nsgtk_help_menu));
if (ret == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
return NULL;
}
ret->help_menu = GTK_MENU(gtk_menu_new());
if (ret->help_menu == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
free(ret);
return NULL;
}
diff --git a/gtk/plotters.c b/gtk/plotters.c
index 33f4c65..1d8c198 100644
--- a/gtk/plotters.c
+++ b/gtk/plotters.c
@@ -17,13 +17,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
- * Target independent plotting (GDK / GTK+ and Cairo implementation).
- * Can use either GDK drawing primitives (which are mostly passed straight
- * to X to process, and thus accelerated) or Cairo drawing primitives (much
- * higher quality, not accelerated). Cairo's fast enough, so it defaults
- * to using it if it is available. It does this by checking for the
- * CAIRO_VERSION define that the cairo headers set.
+/**
+ * \file
+ * GTK and Cairo plotter implementations.
+ *
+ * Uses Cairo drawing primitives to render browser output.
+ * \todo remove the use of the gdk structure for clipping
*/
#include <math.h>
@@ -36,7 +35,7 @@
#include "desktop/plotters.h"
#include "utils/nsoption.h"
-#include "gtk/font_pango.h"
+#include "gtk/layout_pango.h"
#include "gtk/plotters.h"
#include "gtk/scaffolding.h"
#include "gtk/bitmap.h"
@@ -272,7 +271,7 @@ static bool nsgtk_plot_polygon(const int *p, unsigned int n, const plot_style_t
static bool nsgtk_plot_text(int x, int y, const char *text, size_t length,
- const plot_font_style_t *fstyle)
+ const struct plot_font_style *fstyle)
{
return nsfont_paint(x, y, text, length, fstyle);
}
diff --git a/gtk/preferences.c b/gtk/preferences.c
index 5e7c3c5..0f38506 100644
--- a/gtk/preferences.c
+++ b/gtk/preferences.c
@@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#include <string.h>
diff --git a/gtk/print.c b/gtk/print.c
index e5e9e84..a6e6399 100644
--- a/gtk/print.c
+++ b/gtk/print.c
@@ -39,9 +39,8 @@
#include "desktop/plotters.h"
#include "desktop/print.h"
#include "desktop/printer.h"
-#include "desktop/font.h"
-#include "gtk/font_pango.h"
+#include "gtk/layout_pango.h"
#include "gtk/bitmap.h"
#include "gtk/print.h"
#include "gtk/scaffolding.h"
@@ -562,8 +561,8 @@ void gtk_print_signal_begin_print (GtkPrintOperation *operation,
settings->margins[MARGINRIGHT] = 0;
settings->page_width = gtk_print_context_get_width(context);
settings->page_height = gtk_print_context_get_height(context);
- settings->scale = 0.7;/*at 0.7 the pages look the best*/
- settings->font_func = &nsfont;
+ settings->scale = 0.7; /* at 0.7 the pages look the best */
+ settings->font_func = nsgtk_layout_table;
if (print_set_up(content_to_print, >k_printer,
settings, &height_to_print) == false) {
diff --git a/gtk/scaffolding.c b/gtk/scaffolding.c
index 4eca4c1..7772567 100644
--- a/gtk/scaffolding.c
+++ b/gtk/scaffolding.c
@@ -26,6 +26,8 @@
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
+#include "utils/utils.h"
+#include "utils/dirent.h"
#include "utils/messages.h"
#include "utils/corestrings.h"
#include "utils/log.h"
@@ -44,10 +46,10 @@
#include "desktop/save_text.h"
#include "desktop/searchweb.h"
#include "desktop/textinput.h"
-#include "desktop/font.h"
#include "content/hlcache.h"
#include "gtk/compat.h"
+#include "gtk/warn.h"
#include "gtk/cookies.h"
#include "gtk/completion.h"
#include "gtk/preferences.h"
@@ -71,6 +73,7 @@
#include "gtk/schedule.h"
#include "gtk/viewdata.h"
#include "gtk/resources.h"
+#include "gtk/layout_pango.h"
/** Macro to define a handler for menu, button and activate events. */
#define MULTIHANDLER(q)\
@@ -407,7 +410,7 @@ gboolean nsgtk_window_url_activate_event(GtkWidget *widget, gpointer data)
nsurl_unref(url);
}
if (ret != NSERROR_OK) {
- warn_user(messages_get_errorcode(ret), 0);
+ nsgtk_warning(messages_get_errorcode(ret), 0);
}
return TRUE;
@@ -508,7 +511,7 @@ static void nsgtk_openfile_open(const char *filename)
error = nsurl_create(urltxt, &url);
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ nsgtk_warning(messages_get_errorcode(error), 0);
} else {
browser_window_navigate(bw,
url,
@@ -548,7 +551,7 @@ MULTIHANDLER(newwindow)
nsurl_unref(url);
}
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ nsgtk_warning(messages_get_errorcode(error), 0);
}
return TRUE;
@@ -569,7 +572,7 @@ nserror nsgtk_scaffolding_new_tab(struct gui_window *gw)
}
error = nsurl_create(addr, &url);
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ nsgtk_warning(messages_get_errorcode(error), 0);
}
}
@@ -591,7 +594,7 @@ MULTIHANDLER(newtab)
error = nsgtk_scaffolding_new_tab(g->top_level);
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ nsgtk_warning(messages_get_errorcode(error), 0);
}
return TRUE;
}
@@ -659,7 +662,7 @@ MULTIHANDLER(savepage)
if (res != NSERROR_OK) {
path = strdup(messages_get("SaveText"));
if (path == NULL) {
- warn_user("NoMemory", 0);
+ nsgtk_warning("NoMemory", 0);
return FALSE;
}
}
@@ -681,9 +684,9 @@ MULTIHANDLER(savepage)
if (d == NULL) {
LOG("Unable to open directory %s for complete save: %s", path, strerror(errno));
if (errno == ENOTDIR)
- warn_user("NoDirError", path);
+ nsgtk_warning("NoDirError", path);
else
- warn_user("gtkFileError", path);
+ nsgtk_warning("gtkFileError", path);
gtk_widget_destroy(fc);
g_free(path);
return TRUE;
@@ -715,7 +718,7 @@ MULTIHANDLER(pdf)
res = nsurl_nice(browser_window_get_url(bw), &url_name, true);
if (res != NSERROR_OK) {
- warn_user(messages_get_errorcode(res), 0);
+ nsgtk_warning(messages_get_errorcode(res), 0);
return TRUE;
}
@@ -755,7 +758,7 @@ MULTIHANDLER(pdf)
g_free(filename);
if (settings == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
gtk_widget_destroy(save_dialog);
return TRUE;
}
@@ -792,7 +795,7 @@ MULTIHANDLER(plaintext)
if (res != NSERROR_OK) {
filename = strdup(messages_get("SaveText"));
if (filename == NULL) {
- warn_user("NoMemory", 0);
+ nsgtk_warning("NoMemory", 0);
return FALSE;
}
}
@@ -844,7 +847,7 @@ MULTIHANDLER(print)
print_op = gtk_print_operation_new();
if (print_op == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
return TRUE;
}
@@ -865,14 +868,14 @@ MULTIHANDLER(print)
page_setup = gtk_print_run_page_setup_dialog(g->window, NULL, NULL);
if (page_setup == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
free(settings_fname);
g_object_unref(print_op);
return TRUE;
}
gtk_print_operation_set_default_page_setup(print_op, page_setup);
- nssettings = print_make_settings(PRINT_DEFAULT, NULL, &nsfont);
+ nssettings = print_make_settings(PRINT_DEFAULT, NULL, nsgtk_layout_table);
g_signal_connect(print_op, "begin_print",
G_CALLBACK(gtk_print_signal_begin_print), nssettings);
@@ -949,7 +952,7 @@ MENUHANDLER(savelink)
NULL,
NULL);
if (err != NSERROR_OK) {
- warn_user(messages_get_errorcode(err), 0);
+ nsgtk_warning(messages_get_errorcode(err), 0);
}
return TRUE;
@@ -971,7 +974,7 @@ MENUHANDLER(link_openwin)
err = browser_window_create(BW_CREATE_CLONE | BW_CREATE_HISTORY,
current_menu_features.link, NULL, bw, NULL);
if (err != NSERROR_OK) {
- warn_user(messages_get_errorcode(err), 0);
+ nsgtk_warning(messages_get_errorcode(err), 0);
}
return TRUE;
@@ -997,7 +1000,7 @@ MENUHANDLER(link_opentab)
BW_CREATE_TAB,
current_menu_features.link, NULL, bw, NULL);
if (err != NSERROR_OK) {
- warn_user(messages_get_errorcode(err), 0);
+ nsgtk_warning(messages_get_errorcode(err), 0);
}
temp_open_background = -1;
@@ -1172,7 +1175,7 @@ MULTIHANDLER(viewsource)
ret = nsgtk_viewsource(g->window, nsgtk_get_browser_window(g->top_level));
if (ret != NSERROR_OK) {
- warn_user(messages_get_errorcode(ret), 0);
+ nsgtk_warning(messages_get_errorcode(ret), 0);
}
return TRUE;
@@ -1315,7 +1318,7 @@ MULTIHANDLER(debugboxtree)
/* save data to temporary file */
f = fopen(fname, "w");
if (f == NULL) {
- warn_user("Error saving box tree dump.",
+ nsgtk_warning("Error saving box tree dump.",
"Unable to open file for writing.");
unlink(fname);
return TRUE;
@@ -1350,7 +1353,7 @@ MULTIHANDLER(debugdomtree)
/* save data to temporary file */
f = fopen(fname, "w");
if (f == NULL) {
- warn_user("Error saving box tree dump.",
+ nsgtk_warning("Error saving box tree dump.",
"Unable to open file for writing.");
unlink(fname);
return TRUE;
@@ -1442,7 +1445,7 @@ MULTIHANDLER(home)
error = nsurl_create(addr, &url);
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ nsgtk_warning(messages_get_errorcode(error), 0);
} else {
browser_window_navigate(bw,
url,
@@ -1559,7 +1562,7 @@ MULTIHANDLER(contents)
error = nsurl_create("http://www.netsurf-browser.org/documentation/", &url);
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ nsgtk_warning(messages_get_errorcode(error), 0);
} else {
browser_window_navigate(bw,
url,
@@ -1580,7 +1583,7 @@ MULTIHANDLER(guide)
nsurl *url;
if (nsurl_create("http://www.netsurf-browser.org/documentation/guide", &url) != NSERROR_OK) {
- warn_user("NoMemory", 0);
+ nsgtk_warning("NoMemory", 0);
} else {
browser_window_navigate(bw,
url,
@@ -1601,7 +1604,7 @@ MULTIHANDLER(info)
nsurl *url;
if (nsurl_create("http://www.netsurf-browser.org/documentation/info", &url) != NSERROR_OK) {
- warn_user("NoMemory", 0);
+ nsgtk_warning("NoMemory", 0);
} else {
browser_window_navigate(bw,
url,
diff --git a/gtk/search.c b/gtk/search.c
index 9582e25..9281312 100644
--- a/gtk/search.c
+++ b/gtk/search.c
@@ -36,6 +36,7 @@
#include "desktop/searchweb.h"
#include "desktop/gui_search.h"
+#include "gtk/warn.h"
#include "gtk/compat.h"
#include "gtk/search.h"
#include "gtk/scaffolding.h"
@@ -214,7 +215,7 @@ gboolean nsgtk_websearch_activate(GtkWidget *widget, gpointer data)
nsurl_unref(url);
}
if (ret != NSERROR_OK) {
- warn_user(messages_get_errorcode(ret), 0);
+ nsgtk_warning(messages_get_errorcode(ret), 0);
}
return TRUE;
diff --git a/gtk/toolbar.c b/gtk/toolbar.c
index f5aa7fd..208b5c0 100644
--- a/gtk/toolbar.c
+++ b/gtk/toolbar.c
@@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <gtk/gtk.h>
@@ -27,6 +28,7 @@
#include "utils/utils.h"
#include "gtk/gui.h"
+#include "gtk/warn.h"
#include "gtk/scaffolding.h"
#include "gtk/search.h"
#include "gtk/throbber.h"
@@ -91,6 +93,34 @@ struct nsgtk_theme {
};
/**
+ * returns a string without its underscores
+ *
+ * \param s The string to change.
+ * \param replacespace true to insert a space where there was an underscore
+ * \return The altered string
+ */
+static char *remove_underscores(const char *s, bool replacespace)
+{
+ size_t i, ii, len;
+ char *ret;
+ len = strlen(s);
+ ret = malloc(len + 1);
+ if (ret == NULL) {
+ return NULL;
+ }
+ for (i = 0, ii = 0; i < len; i++) {
+ if (s[i] != '_') {
+ ret[ii++] = s[i];
+ } else if (replacespace) {
+ ret[ii++] = ' ';
+ }
+ }
+ ret[ii] = '\0';
+ return ret;
+}
+
+
+/**
* get default image for buttons / menu items from gtk stock items.
*
* \param tbbutton button reference
@@ -190,7 +220,7 @@ static struct nsgtk_theme *nsgtk_theme_load(GtkIconSize iconsize)
int btnloop;
if (theme == NULL) {
- warn_user("NoMemory", 0);
+ nsgtk_warning("NoMemory", 0);
return NULL;
}
@@ -402,7 +432,7 @@ nsgtk_toolbar_make_widget(struct nsgtk_scaffolding *g,
w = GTK_WIDGET(gtk_tool_item_new());
if ((entry == NULL) || (w == NULL)) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
return NULL;
}
@@ -457,7 +487,7 @@ nsgtk_toolbar_make_widget(struct nsgtk_scaffolding *g,
w = GTK_WIDGET(gtk_tool_item_new());
if ((entry == NULL) || (w == NULL)) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
return NULL;
}
@@ -553,7 +583,7 @@ nsgtk_toolbar_data(GtkWidget *widget,
struct nsgtk_theme *theme =
nsgtk_theme_load(GTK_ICON_SIZE_LARGE_TOOLBAR);
if (theme == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
return TRUE;
}
if (nsgtk_scaffolding_button(g, window->currentbutton)->location
@@ -584,7 +614,7 @@ nsgtk_toolbar_data(GtkWidget *widget,
free(theme);
if (nsgtk_scaffolding_button(g, window->currentbutton)->button
== NULL) {
- warn_user("NoMemory", 0);
+ nsgtk_warning("NoMemory", 0);
return TRUE;
}
/* update logical schema */
@@ -706,7 +736,7 @@ static void nsgtk_toolbar_close(struct nsgtk_scaffolding *g)
while (list) {
theme = nsgtk_theme_load(GTK_ICON_SIZE_LARGE_TOOLBAR);
if (theme == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
continue;
}
/* clear toolbar */
@@ -781,7 +811,7 @@ static bool nsgtk_toolbar_add_store_widget(GtkWidget *widget)
if (window->numberh >= NSGTK_STORE_WIDTH) {
window->currentbar = gtk_toolbar_new();
if (window->currentbar == NULL) {
- warn_user("NoMemory", 0);
+ nsgtk_warning("NoMemory", 0);
return false;
}
gtk_toolbar_set_style(GTK_TOOLBAR(window->currentbar),
@@ -811,7 +841,7 @@ static void nsgtk_toolbar_customization_save(struct nsgtk_scaffolding *g)
int i;
FILE *f = fopen(toolbar_indices_file_location, "w");
if (f == NULL){
- warn_user("gtkFileError", toolbar_indices_file_location);
+ nsgtk_warning("gtkFileError", toolbar_indices_file_location);
return;
}
for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) {
@@ -967,7 +997,7 @@ static void nsgtk_toolbar_window_open(struct nsgtk_scaffolding *g)
theme = nsgtk_theme_load(GTK_ICON_SIZE_LARGE_TOOLBAR);
if (theme == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
nsgtk_toolbar_cancel_clicked(NULL, g);
return;
}
@@ -975,7 +1005,7 @@ static void nsgtk_toolbar_window_open(struct nsgtk_scaffolding *g)
res = nsgtk_builder_new_from_resname("toolbar", &window->builder);
if (res != NSERROR_OK) {
LOG("Toolbar UI builder init failed");
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
nsgtk_toolbar_cancel_clicked(NULL, g);
free(theme);
return;
@@ -986,7 +1016,7 @@ static void nsgtk_toolbar_window_open(struct nsgtk_scaffolding *g)
window->window = GTK_WIDGET(gtk_builder_get_object(window->builder,
"toolbarwindow"));
if (window->window == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
nsgtk_toolbar_cancel_clicked(NULL, g);
free(theme);
return;
@@ -995,7 +1025,7 @@ static void nsgtk_toolbar_window_open(struct nsgtk_scaffolding *g)
window->widgetvbox = GTK_WIDGET(gtk_builder_get_object(window->builder,
"widgetvbox"));
if (window->widgetvbox == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
nsgtk_toolbar_cancel_clicked(NULL, g);
free(theme);
return;
@@ -1013,7 +1043,7 @@ static void nsgtk_toolbar_window_open(struct nsgtk_scaffolding *g)
window->store_buttons[i] =
nsgtk_toolbar_make_widget(g, i, theme);
if (window->store_buttons[i] == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
continue;
}
nsgtk_toolbar_add_store_widget(window->store_buttons[i]);
@@ -1160,7 +1190,7 @@ void nsgtk_toolbar_set_physical(struct nsgtk_scaffolding *g)
struct nsgtk_theme *theme =
nsgtk_theme_load(GTK_ICON_SIZE_LARGE_TOOLBAR);
if (theme == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ nsgtk_warning(messages_get("NoMemory"), 0);
return;
}
/* simplest is to clear the toolbar then reload it from memory */
@@ -1360,7 +1390,7 @@ void nsgtk_toolbar_customization_load(struct nsgtk_scaffolding *g)
(i <= THROBBER_ITEM) ? i : -1;
FILE *f = fopen(toolbar_indices_file_location, "r");
if (f == NULL) {
- warn_user(messages_get("gtkFileError"),
+ nsgtk_warning(messages_get("gtkFileError"),
toolbar_indices_file_location);
return;
}
diff --git a/gtk/treeview.c b/gtk/treeview.c
index 2b2e6c7..43c9f28 100644
--- a/gtk/treeview.c
+++ b/gtk/treeview.c
@@ -21,6 +21,7 @@
* Generic tree handling (implementation).
*/
+#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include <limits.h>
@@ -35,6 +36,7 @@
#include "desktop/tree.h"
#include "desktop/plotters.h"
+#include "gtk/warn.h"
#include "gtk/compat.h"
#include "gtk/gui.h"
#include "gtk/plotters.h"
@@ -535,7 +537,7 @@ struct nsgtk_treeview *nsgtk_treeview_create(unsigned int flags,
tv = malloc(sizeof(struct nsgtk_treeview));
if (tv == NULL) {
LOG("malloc failed");
- warn_user("NoMemory", 0);
+ nsgtk_warning("NoMemory", 0);
return NULL;
}
diff --git a/gtk/viewdata.c b/gtk/viewdata.c
index 8879bca..55b2546 100644
--- a/gtk/viewdata.c
+++ b/gtk/viewdata.c
@@ -45,6 +45,7 @@
#include "content/hlcache.h"
#include "content/content.h"
+#include "gtk/warn.h"
#include "gtk/about.h"
#include "gtk/fetch.h"
#include "gtk/compat.h"
@@ -544,7 +545,7 @@ tab_init(const char *title,
/* save data to temporary file */
f = fopen(fname, "w");
if (f == NULL) {
- warn_user(messages_get("gtkSourceTabError"), 0);
+ nsgtk_warning(messages_get("gtkSourceTabError"), 0);
g_free(fname);
return NSERROR_SAVE_FAILED;
}
@@ -907,7 +908,7 @@ editor_init(const char *title,
/* save data to temporary file */
f = fopen(fname, "w");
if (f == NULL) {
- warn_user(messages_get("gtkSourceTabError"), 0);
+ nsgtk_warning(messages_get("gtkSourceTabError"), 0);
g_free(fname);
return NSERROR_SAVE_FAILED;
}
diff --git a/gtk/viewsource.c b/gtk/viewsource.c
index 62e5959..554cfbf 100644
--- a/gtk/viewsource.c
+++ b/gtk/viewsource.c
@@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <stdlib.h>
#include <gtk/gtk.h>
#include "utils/utils.h"
diff --git a/desktop/version.c b/gtk/warn.h
similarity index 64%
copy from desktop/version.c
copy to gtk/warn.h
index e456aac..d24f554 100644
--- a/desktop/version.c
+++ b/gtk/warn.h
@@ -16,15 +16,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "testament.h"
+#ifndef GTK_WARN_H
+#define GTK_WARN_H
-#include "desktop/version.h"
+/**
+ * Warn the user of an event.
+ *
+ * \param[in] warning A warning looked up in the message translation table
+ * \param[in] detail Additional text to be displayed or NULL.
+ * \return NSERROR_OK on success or error code if there was a
+ * faliure displaying the message to the user.
+ */
+nserror nsgtk_warning(const char *warning, const char *detail);
-const char * const netsurf_version = "3.5 (Dev"
-#if defined(CI_BUILD)
- " CI #" CI_BUILD
#endif
- ")"
- ;
-const int netsurf_version_major = 3;
-const int netsurf_version_minor = 4;
diff --git a/gtk/window.c b/gtk/window.c
index c50ed20..de333d1 100644
--- a/gtk/window.c
+++ b/gtk/window.c
@@ -22,6 +22,7 @@
* Implementation of gtk windowing.
*/
+#include <stdlib.h>
#include <inttypes.h>
#include <string.h>
#include <limits.h>
@@ -46,6 +47,7 @@
#include "desktop/plotters.h"
#include "render/form.h"
+#include "gtk/warn.h"
#include "gtk/compat.h"
#include "gtk/gui.h"
#include "gtk/scaffolding.h"
@@ -752,7 +754,7 @@ gui_window_create(struct browser_window *bw,
g = calloc(1, sizeof(*g));
if (!g) {
- warn_user("NoMemory", 0);
+ nsgtk_warning("NoMemory", 0);
g_object_unref(tab_builder);
return NULL;
}
@@ -776,7 +778,7 @@ gui_window_create(struct browser_window *bw,
g->scaffold = nsgtk_new_scaffolding(g);
}
if (g->scaffold == NULL) {
- warn_user("NoMemory", 0);
+ nsgtk_warning("NoMemory", 0);
free(g);
g_object_unref(tab_builder);
return NULL;
diff --git a/image/bmp.c b/image/bmp.c
index 7e992ae..2468b4d 100644
--- a/image/bmp.c
+++ b/image/bmp.c
@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <libnsbmp.h>
+#include "utils/utils.h"
#include "utils/messages.h"
#include "content/content_protected.h"
#include "desktop/gui_internal.h"
diff --git a/image/gif.c b/image/gif.c
index fb0985a..878a42a 100644
--- a/image/gif.c
+++ b/image/gif.c
@@ -36,6 +36,7 @@
#include <stdlib.h>
#include <libnsgif.h>
+#include "utils/utils.h"
#include "utils/messages.h"
#include "utils/nsoption.h"
#include "content/content_protected.h"
@@ -155,7 +156,7 @@ static void nsgif_animate(void *p)
delay = gif->gif->frames[gif->current_frame].frame_delay;
if (delay < nsoption_int(minimum_gif_delay))
delay = nsoption_int(minimum_gif_delay);
- guit->browser->schedule(delay * 10, nsgif_animate, gif);
+ guit->misc->schedule(delay * 10, nsgif_animate, gif);
}
if ((!nsoption_bool(animate_images)) ||
@@ -288,7 +289,7 @@ static bool nsgif_convert(struct content *c)
/* Schedule the animation if we have one */
gif->current_frame = 0;
if (gif->gif->frame_count_partial > 1)
- guit->browser->schedule(gif->gif->frames[0].frame_delay * 10,
+ guit->misc->schedule(gif->gif->frames[0].frame_delay * 10,
nsgif_animate,
c);
@@ -351,7 +352,7 @@ static void nsgif_destroy(struct content *c)
nsgif_content *gif = (nsgif_content *) c;
/* Free all the associated memory buffers */
- guit->browser->schedule(-1, nsgif_animate, c);
+ guit->misc->schedule(-1, nsgif_animate, c);
gif_finalise(gif->gif);
free(gif->gif);
}
@@ -403,7 +404,7 @@ static void nsgif_add_user(struct content *c)
if (content_count_users(c) == 1) {
/* First user, and content already converted, so start the animation. */
if (gif->gif->frame_count_partial > 1) {
- guit->browser->schedule(gif->gif->frames[0].frame_delay * 10,
+ guit->misc->schedule(gif->gif->frames[0].frame_delay * 10,
nsgif_animate, c);
}
}
@@ -413,7 +414,7 @@ static void nsgif_remove_user(struct content *c)
{
if (content_count_users(c) == 1) {
/* Last user is about to be removed from this content, so stop the animation. */
- guit->browser->schedule(-1, nsgif_animate, c);
+ guit->misc->schedule(-1, nsgif_animate, c);
}
}
diff --git a/image/ico.c b/image/ico.c
index cf74592..5f453bc 100644
--- a/image/ico.c
+++ b/image/ico.c
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <libnsbmp.h>
+#include "utils/utils.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "content/content_protected.h"
diff --git a/image/image.c b/image/image.c
index 1dac313..b9bcf1e 100644
--- a/image/image.c
+++ b/image/image.c
@@ -19,6 +19,7 @@
#include <stdbool.h>
#include <stdlib.h>
+#include "utils/utils.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "content/content.h"
diff --git a/image/image_cache.c b/image/image_cache.c
index 13ec3b9..9f217f8 100644
--- a/image/image_cache.c
+++ b/image/image_cache.c
@@ -21,7 +21,9 @@
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
+#include <stdlib.h>
+#include "utils/utils.h"
#include "utils/log.h"
#include "content/content_protected.h"
#include "desktop/gui_misc.h"
@@ -288,7 +290,7 @@ static void image_cache__background_update(void *p)
image_cache__clean(icache);
- guit->browser->schedule(icache->params.bg_clean_time,
+ guit->misc->schedule(icache->params.bg_clean_time,
image_cache__background_update,
icache);
}
@@ -370,7 +372,7 @@ image_cache_init(const struct image_cache_parameters *image_cache_parameters)
image_cache->params = *image_cache_parameters;
- guit->browser->schedule(image_cache->params.bg_clean_time,
+ guit->misc->schedule(image_cache->params.bg_clean_time,
image_cache__background_update,
image_cache);
@@ -385,7 +387,7 @@ nserror image_cache_fini(void)
{
unsigned int op_count;
- guit->browser->schedule(-1, image_cache__background_update, image_cache);
+ guit->misc->schedule(-1, image_cache__background_update, image_cache);
LOG("Size at finish %" PRIsizet " (in %d)",
image_cache->total_bitmap_size, image_cache->bitmap_count);
diff --git a/image/jpeg.c b/image/jpeg.c
index 8e6ac85..cf265b4 100644
--- a/image/jpeg.c
+++ b/image/jpeg.c
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <setjmp.h>
+#include "utils/utils.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "content/content_protected.h"
@@ -61,7 +62,7 @@ static unsigned char nsjpeg_eoi[] = { 0xff, JPEG_EOI };
* Content create entry point.
*/
static nserror nsjpeg_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c)
{
diff --git a/image/nssprite.c b/image/nssprite.c
index c0c6ff1..0fe2527 100644
--- a/image/nssprite.c
+++ b/image/nssprite.c
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <librosprite.h>
+#include "utils/utils.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "content/content_protected.h"
@@ -60,7 +61,7 @@ typedef struct nssprite_content {
static nserror nssprite_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c)
{
diff --git a/image/png.c b/image/png.c
index 934252b..1c78d30 100644
--- a/image/png.c
+++ b/image/png.c
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <png.h>
+#include "utils/utils.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "content/content_protected.h"
@@ -279,7 +280,7 @@ static nserror nspng_create_png_data(nspng_content *png_c)
}
static nserror nspng_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c)
{
diff --git a/image/rsvg.c b/image/rsvg.c
index 4ffb43a..b781125 100644
--- a/image/rsvg.c
+++ b/image/rsvg.c
@@ -27,6 +27,7 @@
* function to render it for redraw requests.
*/
+#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
#include <string.h>
@@ -77,7 +78,7 @@ static nserror rsvg_create_svg_data(rsvg_content *c)
static nserror rsvg_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c)
{
diff --git a/image/svg.c b/image/svg.c
index 0bffbe8..63cdb3b 100644
--- a/image/svg.c
+++ b/image/svg.c
@@ -70,7 +70,7 @@ no_memory:
*/
static nserror svg_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c)
{
diff --git a/javascript/content.c b/javascript/content.c
index ef1bedc..ef56140 100644
--- a/javascript/content.c
+++ b/javascript/content.c
@@ -38,7 +38,7 @@ typedef struct javascript_content {
} javascript_content;
static nserror javascript_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c)
{
diff --git a/javascript/duktape/dukky.c b/javascript/duktape/dukky.c
index ab86d01..7dd3bd7 100644
--- a/javascript/duktape/dukky.c
+++ b/javascript/duktape/dukky.c
@@ -29,6 +29,7 @@
#include "content/content.h"
+#include "utils/utils.h"
#include "utils/nsoption.h"
#include "utils/log.h"
#include "utils/corestrings.h"
diff --git a/javascript/fetcher.c b/javascript/fetcher.c
index de1ce66..839df26 100644
--- a/javascript/fetcher.c
+++ b/javascript/fetcher.c
@@ -22,37 +22,17 @@
* This fetcher implements http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html...
*/
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <assert.h>
-#include <errno.h>
#include <stdbool.h>
-#include <inttypes.h>
-#include <string.h>
-#include <strings.h>
-#include <time.h>
-#include <stdio.h>
-#include <dirent.h>
-#include <limits.h>
-#include <stdarg.h>
-
+#include <stdlib.h>
#include <libwapcaplet/libwapcaplet.h>
-#include "utils/config.h"
-#include "utils/errors.h"
+#include "utils/nsurl.h"
#include "utils/corestrings.h"
-#include "utils/nsoption.h"
-#include "utils/log.h"
-#include "utils/messages.h"
-#include "utils/utils.h"
#include "utils/ring.h"
-
#include "content/fetch.h"
#include "content/fetchers.h"
+
#include "javascript/fetcher.h"
-#include "content/urldb.h"
/** Context for an resource fetch */
struct fetch_javascript_context {
@@ -63,7 +43,7 @@ struct fetch_javascript_context {
bool aborted; /**< Flag indicating fetch has been aborted */
bool locked; /**< Flag indicating entry is already entered */
- nsurl *url;
+ nsurl *url; /**< The URL being fetched */
};
static struct fetch_javascript_context *ring = NULL;
diff --git a/monkey/Makefile.target b/monkey/Makefile.target
index 3c7b093..5813573 100644
--- a/monkey/Makefile.target
+++ b/monkey/Makefile.target
@@ -56,8 +56,8 @@ endif
# ----------------------------------------------------------------------------
# S_MONKEY are sources purely for the MONKEY build
-S_MONKEY := main.c utils.c filetype.c schedule.c bitmap.c plot.c browser.c \
- download.c 401login.c cert.c font.c dispatch.c fetch.c
+S_MONKEY := main.c filetype.c schedule.c bitmap.c plot.c browser.c \
+ download.c 401login.c cert.c layout.c dispatch.c fetch.c
S_MONKEY := $(addprefix monkey/,$(S_MONKEY))
diff --git a/monkey/browser.c b/monkey/browser.c
index a132621..85b3c62 100644
--- a/monkey/browser.c
+++ b/monkey/browser.c
@@ -19,7 +19,9 @@
/* Browser-related callbacks */
#include <stdio.h>
+#include <stdlib.h>
+#include "utils/utils.h"
#include "utils/ring.h"
#include "utils/log.h"
#include "utils/messages.h"
diff --git a/monkey/download.c b/monkey/download.c
index bc82074..2421366 100644
--- a/monkey/download.c
+++ b/monkey/download.c
@@ -18,6 +18,7 @@
#include <stdio.h>
#include <stdint.h>
+#include <stdlib.h>
#include "utils/errors.h"
#include "utils/ring.h"
diff --git a/monkey/font.c b/monkey/layout.c
similarity index 82%
rename from monkey/font.c
rename to monkey/layout.c
index 3b6ca4f..401ca15 100644
--- a/monkey/font.c
+++ b/monkey/layout.c
@@ -16,16 +16,25 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "utils/nsoption.h"
+/**
+ * \file
+ * monkey implementation of font layout.
+ */
+
+#include <stddef.h>
+
#include "utils/utf8.h"
-#include "desktop/font.h"
+#include "desktop/plot_style.h"
+#include "desktop/gui_layout.h"
+
+#include "monkey/layout.h"
-static bool nsfont_width(const plot_font_style_t *fstyle,
+static nserror nsfont_width(const plot_font_style_t *fstyle,
const char *string, size_t length,
int *width)
{
*width = (fstyle->size * utf8_bounded_length(string, length)) / FONT_SIZE_SCALE;
- return true;
+ return NSERROR_OK;
}
/**
@@ -40,7 +49,7 @@ static bool nsfont_width(const plot_font_style_t *fstyle,
* \return true on success, false on error and error reported
*/
-static bool nsfont_position_in_string(const plot_font_style_t *fstyle,
+static nserror nsfont_position_in_string(const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x)
{
@@ -48,7 +57,7 @@ static bool nsfont_position_in_string(const plot_font_style_t *fstyle,
if (*char_offset > length)
*char_offset = length;
*actual_x = *char_offset * (fstyle->size / FONT_SIZE_SCALE);
- return true;
+ return NSERROR_OK;
}
@@ -75,7 +84,7 @@ static bool nsfont_position_in_string(const plot_font_style_t *fstyle,
* Returning char_offset == length means no split possible
*/
-static bool nsfont_split(const plot_font_style_t *fstyle,
+static nserror nsfont_split(const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x)
{
@@ -96,11 +105,13 @@ static bool nsfont_split(const plot_font_style_t *fstyle,
}
}
*actual_x = *char_offset * (fstyle->size / FONT_SIZE_SCALE);
- return true;
+ return NSERROR_OK;
}
-const struct font_functions nsfont = {
- nsfont_width,
- nsfont_position_in_string,
- nsfont_split
+static struct gui_layout_table layout_table = {
+ .width = nsfont_width,
+ .position = nsfont_position_in_string,
+ .split = nsfont_split,
};
+
+struct gui_layout_table *monkey_layout_table = &layout_table;
diff --git a/atari/about.h b/monkey/layout.h
similarity index 76%
copy from atari/about.h
copy to monkey/layout.h
index dff6eae..1e713c2 100644
--- a/atari/about.h
+++ b/monkey/layout.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 Ole Loots <ole(a)monochrom.net>
+ * Copyright 2016 Vincent Sanders <vince(a)netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -16,9 +16,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NS_ATARI_ABOUT_H_INCLUDED
-#define NS_ATARI_ABOUT_H_INCLUDED
+#ifndef NS_MONKEY_LAYOUT_H
+#define NS_MONKEY_LAYOUT_H
-void atari_about_show(void);
+extern struct gui_layout_table *monkey_layout_table;
-#endif // NS_ATARI_ABOUT_H_INCLUDED
+#endif /* NS_MONKEY_LAYOUT_H */
diff --git a/monkey/main.c b/monkey/main.c
index 9569f97..7b38a38 100644
--- a/monkey/main.c
+++ b/monkey/main.c
@@ -20,11 +20,11 @@
#include <stdlib.h>
#include <limits.h>
#include <sys/select.h>
-#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include "utils/config.h"
+#include "utils/sys_time.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/filepath.h"
@@ -44,6 +44,7 @@
#include "monkey/fetch.h"
#include "monkey/schedule.h"
#include "monkey/bitmap.h"
+#include "monkey/layout.h"
/** maximum number of languages in language vector */
#define LANGV_SIZE 32
@@ -222,6 +223,13 @@ static nserror set_defaults(struct nsoption_s *defaults)
return NSERROR_OK;
}
+static nserror monkey_warn_user(const char *warning, const char *detail)
+{
+ fprintf(stderr, "WARN %s %s\n", warning, detail);
+ return NSERROR_OK;
+}
+
+
/**
* Ensures output logging stream is correctly configured
*/
@@ -233,8 +241,9 @@ static bool nslog_stream_configure(FILE *fptr)
return true;
}
-static struct gui_browser_table monkey_browser_table = {
+static struct gui_misc_table monkey_misc_table = {
.schedule = monkey_schedule,
+ .warning = monkey_warn_user,
.quit = monkey_quit,
.launch_url = gui_launch_url,
@@ -314,11 +323,12 @@ main(int argc, char **argv)
char buf[PATH_MAX];
nserror ret;
struct netsurf_table monkey_table = {
- .browser = &monkey_browser_table,
+ .misc = &monkey_misc_table,
.window = monkey_window_table,
.download = monkey_download_table,
.fetch = monkey_fetch_table,
.bitmap = monkey_bitmap_table,
+ .layout = monkey_layout_table,
};
ret = netsurf_register(&monkey_table);
diff --git a/monkey/schedule.c b/monkey/schedule.c
index e2d54e8..8c638c0 100644
--- a/monkey/schedule.c
+++ b/monkey/schedule.c
@@ -16,10 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <sys/time.h>
#include <time.h>
#include <stdlib.h>
+#include "utils/sys_time.h"
#include "utils/log.h"
#include "monkey/schedule.h"
diff --git a/monkey/utils.c b/monkey/utils.c
deleted file mode 100644
index 102f8ac..0000000
--- a/monkey/utils.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2011 Daniel Silverstone <dsilvers(a)digital-scurf.org>
- *
- * This file is part of NetSurf, http://www.netsurf-browser.org/
- *
- * NetSurf is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * NetSurf is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "utils/config.h"
-#include "utils/utils.h"
-
-void warn_user(const char *warning, const char *detail)
-{
- fprintf(stderr, "WARN %s %s\n", warning, detail);
-}
-
diff --git a/render/box.c b/render/box.c
index 7111f1a..bb1800b 100644
--- a/render/box.c
+++ b/render/box.c
@@ -28,19 +28,23 @@
#include <stdio.h>
#include <string.h>
#include <dom/dom.h>
+
+#include "utils/nsoption.h"
+#include "utils/log.h"
+#include "utils/talloc.h"
+#include "utils/utils.h"
#include "content/content_protected.h"
#include "content/hlcache.h"
#include "css/css.h"
#include "css/utils.h"
#include "css/dump.h"
#include "desktop/scrollbar.h"
-#include "utils/nsoption.h"
+#include "desktop/gui_misc.h"
+#include "desktop/gui_internal.h"
+
#include "render/box.h"
#include "render/form_internal.h"
#include "render/html_internal.h"
-#include "utils/log.h"
-#include "utils/talloc.h"
-#include "utils/utils.h"
#define box_is_float(box) (box->type == BOX_FLOAT_LEFT || \
box->type == BOX_FLOAT_RIGHT)
@@ -1146,16 +1150,17 @@ bool box_handle_scrollbars(struct content *c, struct box *box,
data = malloc(sizeof(struct html_scrollbar_data));
if (data == NULL) {
LOG("malloc failed");
- warn_user("NoMemory", 0);
+ guit->misc->warning("NoMemory", 0);
return false;
}
data->c = c;
data->box = box;
- if (!scrollbar_create(false, visible_height,
+ if (scrollbar_create(false, visible_height,
full_height, visible_height,
data, html_overflow_scroll_callback,
- &(box->scroll_y)))
+ &(box->scroll_y)) != NSERROR_OK) {
return false;
+ }
} else {
scrollbar_set_extents(box->scroll_y, visible_height,
visible_height, full_height);
@@ -1166,18 +1171,19 @@ bool box_handle_scrollbars(struct content *c, struct box *box,
data = malloc(sizeof(struct html_scrollbar_data));
if (data == NULL) {
LOG("malloc failed");
- warn_user("NoMemory", 0);
+ guit->misc->warning("NoMemory", 0);
return false;
}
data->c = c;
data->box = box;
- if (!scrollbar_create(true,
+ if (scrollbar_create(true,
visible_width -
(right ? SCROLLBAR_WIDTH : 0),
full_width, visible_width,
data, html_overflow_scroll_callback,
- &box->scroll_x))
+ &box->scroll_x) != NSERROR_OK) {
return false;
+ }
} else {
scrollbar_set_extents(box->scroll_x,
visible_width -
diff --git a/render/box_construct.c b/render/box_construct.c
index adb4509..7e982d7 100644
--- a/render/box_construct.c
+++ b/render/box_construct.c
@@ -22,7 +22,7 @@
/**
* \file
- * Conversion of XML tree to box tree (implementation).
+ * Implementation of conversion from DOM tree to box tree.
*/
#include <assert.h>
@@ -34,11 +34,6 @@
#include <strings.h>
#include "utils/config.h"
-#include "content/content_protected.h"
-#include "css/css.h"
-#include "css/hints.h"
-#include "css/select.h"
-#include "css/utils.h"
#include "utils/nsoption.h"
#include "utils/corestrings.h"
#include "utils/locale.h"
@@ -46,6 +41,12 @@
#include "utils/messages.h"
#include "utils/talloc.h"
#include "utils/utils.h"
+#include "utils/string.h"
+#include "content/content_protected.h"
+#include "css/css.h"
+#include "css/hints.h"
+#include "css/select.h"
+#include "css/utils.h"
#include "desktop/gui_misc.h"
#include "desktop/gui_internal.h"
@@ -187,7 +188,7 @@ nserror dom_to_box(dom_node *n, html_content *c, box_construct_complete_cb cb)
ctx->cb = cb;
ctx->bctx = c->bctx;
- return guit->browser->schedule(0, (void *)convert_xml_to_box, ctx);
+ return guit->misc->schedule(0, (void *)convert_xml_to_box, ctx);
}
/* mapping from CSS display to box type
@@ -448,7 +449,7 @@ void convert_xml_to_box(struct box_construct_ctx *ctx)
} while (++num_processed < max_processed_before_yield);
/* More work to do: schedule a continuation */
- guit->browser->schedule(0, (void *)convert_xml_to_box, ctx);
+ guit->misc->schedule(0, (void *)convert_xml_to_box, ctx);
}
/**
diff --git a/render/form.c b/render/form.c
index 1adce23..dce9064 100644
--- a/render/form.c
+++ b/render/form.c
@@ -51,6 +51,8 @@
#include "desktop/plotters.h"
#include "desktop/scrollbar.h"
#include "desktop/textarea.h"
+#include "desktop/gui_misc.h"
+#include "desktop/gui_internal.h"
#include "render/box.h"
#include "render/font.h"
@@ -1095,7 +1097,7 @@ bool form_open_select_menu(void *client_data,
menu = calloc(1, sizeof (struct form_select_menu));
if (menu == NULL) {
- warn_user("NoMemory", 0);
+ guit->misc->warning("NoMemory", 0);
return false;
}
@@ -1131,13 +1133,13 @@ bool form_open_select_menu(void *client_data,
}
menu->client_data = client_data;
menu->callback = callback;
- if (!scrollbar_create(false,
+ if (scrollbar_create(false,
menu->height,
total_height,
menu->height,
control,
form_select_menu_scroll_callback,
- &(menu->scrollbar))) {
+ &(menu->scrollbar)) != NSERROR_OK) {
free(menu);
return false;
}
@@ -1710,7 +1712,7 @@ void form_submit(nsurl *page_url, struct browser_window *target,
assert(form != NULL);
if (form_successful_controls_dom(form, submit_button, &success) == false) {
- warn_user("NoMemory", 0);
+ guit->misc->warning("NoMemory", 0);
return;
}
@@ -1718,7 +1720,7 @@ void form_submit(nsurl *page_url, struct browser_window *target,
if (nsurl_create(form->action, &action_url) != NSERROR_OK) {
free(data);
fetch_multipart_data_destroy(success);
- warn_user("NoMemory", 0);
+ guit->misc->warning("NoMemory", 0);
return;
}
@@ -1727,7 +1729,7 @@ void form_submit(nsurl *page_url, struct browser_window *target,
data = form_url_encode(form, success, true);
if (data == NULL) {
fetch_multipart_data_destroy(success);
- warn_user("NoMemory", 0);
+ guit->misc->warning("NoMemory", 0);
return;
}
@@ -1737,7 +1739,7 @@ void form_submit(nsurl *page_url, struct browser_window *target,
nsurl_unref(action_query);
free(data);
fetch_multipart_data_destroy(success);
- warn_user(messages_get_errorcode(error), 0);
+ guit->misc->warning(messages_get_errorcode(error), 0);
return;
}
@@ -1757,7 +1759,7 @@ void form_submit(nsurl *page_url, struct browser_window *target,
data = form_url_encode(form, success, false);
if (data == NULL) {
fetch_multipart_data_destroy(success);
- warn_user("NoMemory", 0);
+ guit->misc->warning("NoMemory", 0);
nsurl_unref(action_url);
return;
}
diff --git a/render/html.c b/render/html.c
index e7d2c48..c809ee1 100644
--- a/render/html.c
+++ b/render/html.c
@@ -17,7 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
+/**
+ * \file
* Content for text/html (implementation).
*/
@@ -27,6 +28,7 @@
#include <string.h>
#include <strings.h>
#include <stdlib.h>
+#include <nsutils/time.h>
#include "utils/config.h"
#include "utils/corestrings.h"
@@ -37,6 +39,7 @@
#include "utils/talloc.h"
#include "utils/utf8.h"
#include "utils/nsoption.h"
+#include "utils/string.h"
#include "content/content_protected.h"
#include "content/fetch.h"
#include "content/hlcache.h"
@@ -46,8 +49,9 @@
#include "image/bitmap.h"
#include "javascript/js.h"
#include "desktop/browser.h"
-#include "desktop/font.h"
#include "desktop/gui_utf8.h"
+#include "desktop/gui_layout.h"
+#include "desktop/gui_misc.h"
#include "desktop/gui_internal.h"
#include "render/box.h"
@@ -841,7 +845,7 @@ html_create_html_data(html_content *c, const http_parameter *params)
c->frameset = NULL;
c->iframe = NULL;
c->page = NULL;
- c->font_func = &nsfont;
+ c->font_func = guit->layout;
c->drag_type = HTML_DRAG_NONE;
c->drag_owner.no_owner = true;
c->selection_type = HTML_SELECTION_NONE;
@@ -1373,9 +1377,11 @@ static void html_reformat(struct content *c, int width, int height)
{
html_content *htmlc = (html_content *) c;
struct box *layout;
- unsigned int time_before, time_taken;
+ uint64_t ms_before;
+ uint64_t ms_after;
+ uint64_t ms_interval;
- time_before = wallclock();
+ nsu_getmonotonic_ms(&ms_before);
htmlc->reflowing = true;
@@ -1384,11 +1390,11 @@ static void html_reformat(struct content *c, int width, int height)
/* width and height are at least margin box of document */
c->width = layout->x + layout->padding[LEFT] + layout->width +
- layout->padding[RIGHT] + layout->border[RIGHT].width +
- layout->margin[RIGHT];
+ layout->padding[RIGHT] + layout->border[RIGHT].width +
+ layout->margin[RIGHT];
c->height = layout->y + layout->padding[TOP] + layout->height +
- layout->padding[BOTTOM] + layout->border[BOTTOM].width +
- layout->margin[BOTTOM];
+ layout->padding[BOTTOM] + layout->border[BOTTOM].width +
+ layout->margin[BOTTOM];
/* if boxes overflow right or bottom edge, expand to contain it */
if (c->width < layout->x + layout->descendant_x1)
@@ -1400,10 +1406,14 @@ static void html_reformat(struct content *c, int width, int height)
htmlc->reflowing = false;
- time_taken = wallclock() - time_before;
- c->reformat_time = wallclock() +
- ((time_taken * 3 < nsoption_uint(min_reflow_period) ?
- nsoption_uint(min_reflow_period) : time_taken * 3));
+ /* calculate next reflow time at three times what it took to reflow */
+ nsu_getmonotonic_ms(&ms_after);
+
+ ms_interval = (ms_before - ms_after) * 3;
+ if (ms_interval < (nsoption_uint(min_reflow_period) * 10)) {
+ ms_interval = nsoption_uint(min_reflow_period) * 10;
+ }
+ c->reformat_time = ms_after + ms_interval;
}
@@ -2069,7 +2079,7 @@ static bool html_drop_file_at_point(struct content *c, int x, int y, char *file)
assert(ret != NSERROR_BAD_ENCODING);
LOG("local to utf8 encoding failed");
free(buffer);
- warn_user("NoMemory", NULL);
+ guit->misc->warning("NoMemory", NULL);
return true;
}
diff --git a/render/html_css.c b/render/html_css.c
index a90ea63..6761a65 100644
--- a/render/html_css.c
+++ b/render/html_css.c
@@ -292,7 +292,7 @@ static void html_css_process_modified_styles(void *pw)
/* If we failed to process any sheet, schedule a retry */
if (all_done == false) {
- guit->browser->schedule(1000, html_css_process_modified_styles, c);
+ guit->misc->schedule(1000, html_css_process_modified_styles, c);
}
}
@@ -316,7 +316,7 @@ bool html_css_update_style(html_content *c, dom_node *style)
s->modified = true;
- guit->browser->schedule(0, html_css_process_modified_styles, c);
+ guit->misc->schedule(0, html_css_process_modified_styles, c);
return true;
}
@@ -445,7 +445,7 @@ nserror html_css_free_stylesheets(html_content *html)
{
unsigned int i;
- guit->browser->schedule(-1, html_css_process_modified_styles, html);
+ guit->misc->schedule(-1, html_css_process_modified_styles, html);
for (i = 0; i != html->stylesheet_count; i++) {
if (html->stylesheets[i].sheet != NULL) {
diff --git a/render/html_interaction.c b/render/html_interaction.c
index 397ce46..19e19f6 100644
--- a/render/html_interaction.c
+++ b/render/html_interaction.c
@@ -19,7 +19,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
+/**
+ * \file
* User interaction with a CONTENT_HTML (implementation).
*/
@@ -42,9 +43,9 @@
#include "desktop/selection.h"
#include "desktop/textarea.h"
#include "desktop/textinput.h"
-#include "desktop/font.h"
#include "javascript/js.h"
#include "desktop/gui_misc.h"
+#include "desktop/gui_layout.h"
#include "desktop/gui_internal.h"
#include "render/box.h"
@@ -209,8 +210,8 @@ static size_t html_selection_drag_end(struct html_content *html,
font_plot_style_from_css(box->style, &fstyle);
- nsfont.font_position_in_string(&fstyle, box->text, box->length,
- dx, &idx, &pixel_offset);
+ guit->layout->position(&fstyle, box->text, box->length,
+ dx, &idx, &pixel_offset);
idx += box->byte_offset;
}
@@ -416,9 +417,9 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
font_plot_style_from_css(box->style, &fstyle);
- nsfont.font_position_in_string(&fstyle,
- box->text, box->length,
- dx, &idx, &pixel_offset);
+ guit->layout->position(&fstyle,
+ box->text, box->length,
+ dx, &idx, &pixel_offset);
selection_track(&html->sel, mouse,
box->byte_offset + idx);
@@ -910,12 +911,12 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
font_plot_style_from_css(text_box->style,
&fstyle);
- nsfont.font_position_in_string(&fstyle,
- text_box->text,
- text_box->length,
- x - text_box_x,
- &idx,
- &pixel_offset);
+ guit->layout->position(&fstyle,
+ text_box->text,
+ text_box->length,
+ x - text_box_x,
+ &idx,
+ &pixel_offset);
if (selection_click(&html->sel, mouse,
text_box->byte_offset + idx)) {
diff --git a/render/html_internal.h b/render/html_internal.h
index 419fe41..de28726 100644
--- a/render/html_internal.h
+++ b/render/html_internal.h
@@ -27,6 +27,8 @@
#include "desktop/selection.h"
#include "render/html.h"
+struct gui_layout_table;
+
typedef enum {
HTML_DRAG_NONE, /** No drag */
HTML_DRAG_SELECTION, /** Own; Text selection */
@@ -36,6 +38,7 @@ typedef enum {
HTML_DRAG_CONTENT_SELECTION, /** Not own; drag in child content */
HTML_DRAG_CONTENT_SCROLL /** Not own; drag in child content */
} html_drag_type;
+
union html_drag_owner {
bool no_owner;
struct box *content;
@@ -109,8 +112,9 @@ typedef struct html_content {
struct box *layout;
/** Document background colour. */
colour background_colour;
+
/** Font callback table */
- const struct font_functions *font_func;
+ const struct gui_layout_table *font_func;
/** Number of entries in scripts */
unsigned int scripts_count;
diff --git a/render/html_object.c b/render/html_object.c
index 933950e..22c9b71 100644
--- a/render/html_object.c
+++ b/render/html_object.c
@@ -26,6 +26,7 @@
#include <string.h>
#include <strings.h>
#include <stdlib.h>
+#include <nsutils/time.h>
#include "utils/corestrings.h"
#include "utils/config.h"
@@ -322,7 +323,7 @@ html_object_callback(hlcache_handle *object,
case CONTENT_MSG_REFRESH:
if (content_get_type(object) == CONTENT_HTML) {
/* only for HTML objects */
- guit->browser->schedule(event->data.delay * 1000,
+ guit->misc->schedule(event->data.delay * 1000,
html_object_refresh, o);
}
@@ -433,32 +434,40 @@ html_object_callback(hlcache_handle *object,
break;
}
- if (c->base.status == CONTENT_STATUS_READY && c->base.active == 0 &&
- (event->type == CONTENT_MSG_LOADING ||
- event->type == CONTENT_MSG_DONE ||
- event->type == CONTENT_MSG_ERROR)) {
+ if (c->base.status == CONTENT_STATUS_READY &&
+ c->base.active == 0 &&
+ (event->type == CONTENT_MSG_LOADING ||
+ event->type == CONTENT_MSG_DONE ||
+ event->type == CONTENT_MSG_ERROR)) {
/* all objects have arrived */
content__reformat(&c->base, false, c->base.available_width,
c->base.height);
content_set_done(&c->base);
- }
-
- /* If 1) the configuration option to reflow pages while objects are
- * fetched is set
- * 2) an object is newly fetched & converted,
- * 3) the box's dimensions need to change due to being replaced
- * 4) the object's parent HTML is ready for reformat,
- * 5) the time since the previous reformat is more than the
- * configured minimum time between reformats
- * then reformat the page to display newly fetched objects */
- else if (nsoption_bool(incremental_reflow) &&
- event->type == CONTENT_MSG_DONE &&
- box != NULL && !(box->flags & REPLACE_DIM) &&
- (c->base.status == CONTENT_STATUS_READY ||
- c->base.status == CONTENT_STATUS_DONE) &&
- (wallclock() > c->base.reformat_time)) {
- content__reformat(&c->base, false, c->base.available_width,
- c->base.height);
+ } else if (nsoption_bool(incremental_reflow) &&
+ event->type == CONTENT_MSG_DONE &&
+ box != NULL &&
+ !(box->flags & REPLACE_DIM) &&
+ (c->base.status == CONTENT_STATUS_READY ||
+ c->base.status == CONTENT_STATUS_DONE)) {
+ /* 1) the configuration option to reflow pages while
+ * objects are fetched is set
+ * 2) an object is newly fetched & converted,
+ * 3) the box's dimensions need to change due to being replaced
+ * 4) the object's parent HTML is ready for reformat,
+ */
+ uint64_t ms_now;
+ nsu_getmonotonic_ms(&ms_now);
+ if (ms_now > c->base.reformat_time) {
+ /* The time since the previous reformat is
+ * more than the configured minimum time
+ * between reformats so reformat the page to
+ * display newly fetched objects
+ */
+ content__reformat(&c->base,
+ false,
+ c->base.available_width,
+ c->base.height);
+ }
}
return NSERROR_OK;
@@ -619,7 +628,7 @@ nserror html_object_close_objects(html_content *html)
continue;
if (content_get_type(object->content) == CONTENT_HTML) {
- guit->browser->schedule(-1, html_object_refresh, object);
+ guit->misc->schedule(-1, html_object_refresh, object);
}
content_close(object->content);
@@ -636,7 +645,7 @@ nserror html_object_free_objects(html_content *html)
LOG("object %p", victim->content);
if (content_get_type(victim->content) == CONTENT_HTML) {
- guit->browser->schedule(-1, html_object_refresh, victim);
+ guit->misc->schedule(-1, html_object_refresh, victim);
}
hlcache_handle_release(victim->content);
}
diff --git a/render/html_redraw.c b/render/html_redraw.c
index 091ece0..969b74f 100644
--- a/render/html_redraw.c
+++ b/render/html_redraw.c
@@ -49,8 +49,9 @@
#include "desktop/print.h"
#include "desktop/scrollbar.h"
#include "desktop/textarea.h"
-#include "desktop/font.h"
#include "image/bitmap.h"
+#include "desktop/gui_layout.h"
+#include "desktop/gui_internal.h"
#include "render/box.h"
#include "render/font.h"
@@ -194,6 +195,7 @@ bool text_redraw(const char *utf8_text, size_t utf8_len,
int startx, endx;
plot_style_t pstyle_fill_hback = *plot_style_fill_white;
plot_font_style_t fstyle_hback = plot_fstyle;
+ nserror res;
if (end_idx > utf8_len) {
/* adjust for trailing space, not present in
@@ -202,13 +204,19 @@ bool text_redraw(const char *utf8_text, size_t utf8_len,
endtxt_idx = utf8_len;
}
- if (!nsfont.font_width(fstyle, utf8_text, start_idx,
- &startx))
+ res = guit->layout->width(fstyle,
+ utf8_text, start_idx,
+ &startx);
+ if (res != NSERROR_OK) {
startx = 0;
+ }
- if (!nsfont.font_width(fstyle, utf8_text, endtxt_idx,
- &endx))
+ res = guit->layout->width(fstyle,
+ utf8_text, endtxt_idx,
+ &endx);
+ if (res != NSERROR_OK) {
endx = 0;
+ }
/* is there a trailing space that should be highlighted
* as well? */
@@ -1262,6 +1270,7 @@ static bool html_redraw_file(int x, int y, int width, int height,
const char *text;
size_t length;
plot_font_style_t fstyle;
+ nserror res;
font_plot_style_from_css(box->style, &fstyle);
fstyle.background = background_colour;
@@ -1272,13 +1281,16 @@ static bool html_redraw_file(int x, int y, int width, int height,
text = messages_get("Form_Drop");
length = strlen(text);
- if (!nsfont.font_width(&fstyle, text, length, &text_width))
+ res = guit->layout->width(&fstyle, text, length, &text_width);
+ if (res != NSERROR_OK) {
return false;
+ }
text_width *= scale;
- if (width < text_width + 8)
+ if (width < text_width + 8) {
x = x + width - text_width - 4;
- else
+ } else {
x = x + 4;
+ }
return ctx->plot->text(x, y + height * 0.75, text, length, &fstyle);
}
@@ -2425,17 +2437,25 @@ bool html_redraw_box(const html_content *html, struct box *box,
const char *obj = "\xef\xbf\xbc";
int obj_width;
int obj_x = x + padding_left;
+ nserror res;
+
if (!plot->rectangle(x + padding_left,
y + padding_top,
x + padding_left + width - 1,
y + padding_top + height - 1,
- plot_style_broken_object))
+ plot_style_broken_object)) {
return false;
- if (!nsfont.font_width(plot_fstyle_broken_object, obj,
- sizeof(obj) - 1, &obj_width))
+ }
+
+ res = guit->layout->width(plot_fstyle_broken_object,
+ obj,
+ sizeof(obj) - 1,
+ &obj_width);
+ if (res != NSERROR_OK) {
obj_x += 1;
- else
+ } else {
obj_x += width / 2 - obj_width / 2;
+ }
if (!plot->text(obj_x, y + padding_top + (int)
(height * 0.75),
diff --git a/render/layout.c b/render/layout.c
index 45d905f..e80ec99 100644
--- a/render/layout.c
+++ b/render/layout.c
@@ -19,8 +19,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
- * HTML layout (implementation).
+/**
+ * \file
+ * HTML layout implementation.
*
* Layout is carried out in two stages:
*
@@ -52,7 +53,7 @@
#include "desktop/browser.h"
#include "desktop/scrollbar.h"
#include "desktop/textarea.h"
-#include "desktop/font.h"
+#include "desktop/gui_layout.h"
#include "render/box.h"
#include "render/font.h"
@@ -70,619 +71,578 @@
/* Fixed point percentage (a) of an integer (b), to an integer */
#define FPCT_OF_INT_TOINT(a, b) (FIXTOINT(FDIV((a * b), F_100)))
-
-static bool layout_block_context(struct box *block, int viewport_height,
- html_content *content);
-static void layout_minmax_block(struct box *block,
- const struct font_functions *font_func);
-static struct box* layout_next_margin_block(struct box *box, struct box *block,
- int viewport_height, int *max_pos_margin, int *max_neg_margin);
-static bool layout_block_object(struct box *block);
-static void layout_get_object_dimensions(struct box *box,
- int *width, int *height, int min_width, int max_width,
- int min_height, int max_height);
-static void layout_block_find_dimensions(int available_width,
- int viewport_height, int lm, int rm,
- struct box *box);
-static bool layout_apply_minmax_height(struct box *box, struct box *container);
-static void layout_block_add_scrollbar(struct box *box, int which);
-static int layout_solve_width(struct box *box, int available_width, int width,
- int lm, int rm, int max_width, int min_width);
-static void layout_float_find_dimensions(int available_width,
- const css_computed_style *style, struct box *box);
-static void layout_find_dimensions(int available_width, int viewport_height,
- struct box *box, const css_computed_style *style,
- int *width, int *height, int *max_width, int *min_width,
- int *max_height, int *min_height, int margin[4], int padding[4],
- struct box_border border[4]);
-static void layout_tweak_form_dimensions(struct box *box, bool percentage,
- int available_width, bool setwidth, int *dimension);
-static int layout_clear(struct box *fl, enum css_clear_e clear);
-static void find_sides(struct box *fl, int y0, int y1,
- int *x0, int *x1, struct box **left, struct box **right);
-static void layout_minmax_inline_container(struct box *inline_container,
- bool *has_height, const struct font_functions *font_func);
-static int line_height(const css_computed_style *style);
-static bool layout_line(struct box *first, int *width, int *y,
- int cx, int cy, struct box *cont, bool indent,
- bool has_text_children,
- html_content *content, struct box **next_box);
-static struct box *layout_minmax_line(struct box *first, int *min, int *max,
- bool first_line, bool *line_has_height,
- const struct font_functions *font_func);
-static int layout_text_indent(const css_computed_style *style, int width);
-static bool layout_float(struct box *b, int width, html_content *content);
-static void place_float_below(struct box *c, int width, int cx, int y,
- struct box *cont);
-static bool layout_table(struct box *box, int available_width,
- html_content *content);
-static void layout_move_children(struct box *box, int x, int y);
-static void calculate_mbp_width(const css_computed_style *style,
- unsigned int side, bool margin, bool border, bool padding,
- int *fixed, float *frac);
-static void layout_lists(struct box *box,
- const struct font_functions *font_func);
-static void layout_position_relative(struct box *root, struct box *fp,
- int fx, int fy);
-static void layout_compute_relative_offset(struct box *box, int *x, int *y);
-static bool layout_position_absolute(struct box *box,
- struct box *containing_block,
- int cx, int cy,
- html_content *content);
-static bool layout_absolute(struct box *box, struct box *containing_block,
- int cx, int cy,
- html_content *content);
-static void layout_compute_offsets(struct box *box,
- struct box *containing_block,
- int *top, int *right, int *bottom, int *left);
+/* forward declaration to break cycles */
+static bool layout_block_context(struct box *block, int viewport_height, html_content *content);
+static void layout_minmax_block(struct box *block, const struct gui_layout_table *font_func);
/**
- * Calculate positions of boxes in a document.
+ * Compute the size of replaced boxes with auto dimensions, according to
+ * content.
+ *
+ * \param box Box with object
+ * \param width Width value in px or AUTO. If AUTO, updated to value in px.
+ * \param height Height value in px or AUTO. If AUTO, updated to value in px.
+ * \param min_width Box's min width, as given by layout_find_dimensions.
+ * \param max_width Box's max width, as given by layout_find_dimensions.
+ * \param min_height Box's min height, as given by layout_find_dimensions.
+ * \param max_height Box's max height, as given by layout_find_dimensions.
*
- * \param content content of type CONTENT_HTML
- * \param width available width
- * \param height available height
- * \return true on success, false on memory exhaustion
+ * See CSS 2.1 sections 10.3 and 10.6.
*/
-
-bool layout_document(html_content *content, int width, int height)
+static void
+layout_get_object_dimensions(struct box *box,
+ int *width, int *height,
+ int min_width, int max_width,
+ int min_height, int max_height)
{
- bool ret;
- struct box *doc = content->layout;
- const struct font_functions *font_func = content->font_func;
+ assert(box->object != NULL);
+ assert(width != NULL && height != NULL);
- layout_minmax_block(doc, font_func);
+ if (*width == AUTO && *height == AUTO) {
+ /* No given dimensions */
- layout_block_find_dimensions(width, height, 0, 0, doc);
- doc->x = doc->margin[LEFT] + doc->border[LEFT].width;
- doc->y = doc->margin[TOP] + doc->border[TOP].width;
- width -= doc->margin[LEFT] + doc->border[LEFT].width +
- doc->padding[LEFT] + doc->padding[RIGHT] +
- doc->border[RIGHT].width + doc->margin[RIGHT];
- if (width < 0)
- width = 0;
- doc->width = width;
+ bool scaled = false;
+ int intrinsic_width = content_get_width(box->object);
+ int intrinsic_height = content_get_height(box->object);
- ret = layout_block_context(doc, height, content);
+ /* use intrinsic dimensions */
+ *width = intrinsic_width;
+ *height = intrinsic_height;
- /* make <html> and <body> fill available height */
- if (doc->y + doc->padding[TOP] + doc->height + doc->padding[BOTTOM] +
- doc->border[BOTTOM].width + doc->margin[BOTTOM] <
- height) {
- doc->height = height - (doc->y + doc->padding[TOP] +
- doc->padding[BOTTOM] +
- doc->border[BOTTOM].width +
- doc->margin[BOTTOM]);
- if (doc->children)
- doc->children->height = doc->height -
- (doc->children->margin[TOP] +
- doc->children->border[TOP].width +
- doc->children->padding[TOP] +
- doc->children->padding[BOTTOM] +
- doc->children->border[BOTTOM].width +
- doc->children->margin[BOTTOM]);
- }
+ /* Deal with min/max-width first */
+ if (min_width > 0 && min_width > *width) {
+ *width = min_width;
+ scaled = true;
+ }
+ if (max_width >= 0 && max_width < *width) {
+ *width = max_width;
+ scaled = true;
+ }
- layout_lists(doc, font_func);
- layout_position_absolute(doc, doc, 0, 0, content);
- layout_position_relative(doc, doc, 0, 0);
+ if (scaled && (intrinsic_width != 0)) {
+ /* Update height */
+ *height = (*width * intrinsic_height) /
+ intrinsic_width;
+ }
- layout_calculate_descendant_bboxes(doc);
+ scaled = false;
+ /* Deal with min/max-height */
+ if (min_height > 0 && min_height > *height) {
+ *height = min_height;
+ scaled = true;
+ }
+ if (max_height >= 0 && max_height < *height) {
+ *height = max_height;
+ scaled = true;
+ }
- return ret;
+ if (scaled && (intrinsic_height != 0)) {
+ /* Update width */
+ *width = (*height * intrinsic_width) /
+ intrinsic_height;
+ }
+
+ } else if (*width == AUTO) {
+ /* Have given height; width is calculated from the given height
+ * and ratio of intrinsic dimensions */
+ int intrinsic_width = content_get_width(box->object);
+ int intrinsic_height = content_get_height(box->object);
+
+ if (intrinsic_height != 0)
+ *width = (*height * intrinsic_width) /
+ intrinsic_height;
+ else
+ *width = intrinsic_width;
+
+ if (min_width > 0 && min_width > *width)
+ *width = min_width;
+ if (max_width >= 0 && max_width < *width)
+ *width = max_width;
+
+ } else if (*height == AUTO) {
+ /* Have given width; height is calculated from the given width
+ * and ratio of intrinsic dimensions */
+ int intrinsic_width = content_get_width(box->object);
+ int intrinsic_height = content_get_height(box->object);
+
+ if (intrinsic_width != 0)
+ *height = (*width * intrinsic_height) /
+ intrinsic_width;
+ else
+ *height = intrinsic_height;
+ }
}
/**
- * Layout a block formatting context.
- *
- * \param block BLOCK, INLINE_BLOCK, or TABLE_CELL to layout
- * \param viewport_height Height of viewport in pixels or -ve if unknown
- * \param content Memory pool for any new boxes
- * \return true on success, false on memory exhaustion
+ * Calculate the text-indent length.
*
- * This function carries out layout of a block and its children, as described
- * in CSS 2.1 9.4.1.
+ * \param style style of block
+ * \param width width of containing block
+ * \return length of indent
*/
+static int layout_text_indent(const css_computed_style *style, int width)
+{
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
-bool layout_block_context(struct box *block, int viewport_height,
- html_content *content)
+ css_computed_text_indent(style, &value, &unit);
+
+ if (unit == CSS_UNIT_PCT) {
+ return FPCT_OF_INT_TOINT(value, width);
+ } else {
+ return FIXTOINT(nscss_len2px(value, unit, style));
+ }
+}
+
+
+/**
+ * Determine width of margin, borders, and padding on one side of a box.
+ *
+ * \param style style to measure
+ * \param side side of box to measure
+ * \param margin whether margin width is required
+ * \param border whether border width is required
+ * \param padding whether padding width is required
+ * \param fixed increased by sum of fixed margin, border, and padding
+ * \param frac increased by sum of fractional margin and padding
+ */
+static void
+calculate_mbp_width(const css_computed_style *style,
+ unsigned int side,
+ bool margin,
+ bool border,
+ bool padding,
+ int *fixed,
+ float *frac)
{
- struct box *box;
- int cx, cy; /**< current coordinates */
- int max_pos_margin = 0;
- int max_neg_margin = 0;
- int y = 0;
- int lm, rm;
- struct box *margin_collapse = NULL;
- bool in_margin = false;
- css_fixed gadget_size;
- css_unit gadget_unit; /* Checkbox / radio buttons */
+ typedef uint8_t (*len_func)(const css_computed_style *style,
+ css_fixed *length, css_unit *unit);
- assert(block->type == BOX_BLOCK ||
- block->type == BOX_INLINE_BLOCK ||
- block->type == BOX_TABLE_CELL);
- assert(block->width != UNKNOWN_WIDTH);
- assert(block->width != AUTO);
+ static len_func margin_funcs[4] = {
+ css_computed_margin_top,
+ css_computed_margin_right,
+ css_computed_margin_bottom,
+ css_computed_margin_left
+ };
+ static len_func padding_funcs[4] = {
+ css_computed_padding_top,
+ css_computed_padding_right,
+ css_computed_padding_bottom,
+ css_computed_padding_left
+ };
+ static struct {
+ len_func width;
+ uint8_t (*style)(const css_computed_style *style);
+ } border_funcs[4] = {
+ { css_computed_border_top_width,
+ css_computed_border_top_style },
+ { css_computed_border_right_width,
+ css_computed_border_right_style },
+ { css_computed_border_bottom_width,
+ css_computed_border_bottom_style },
+ { css_computed_border_left_width,
+ css_computed_border_left_style }
+ };
- block->float_children = NULL;
- block->cached_place_below_level = 0;
- block->clear_level = 0;
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
- /* special case if the block contains an object */
- if (block->object) {
- int temp_width = block->width;
- if (!layout_block_object(block))
- return false;
- layout_get_object_dimensions(block, &temp_width,
- &block->height, INT_MIN, INT_MAX,
- INT_MIN, INT_MAX);
- return true;
- } else if (block->flags & REPLACE_DIM) {
- return true;
- }
+ assert(style);
- /* special case if the block contains an radio button or checkbox */
- if (block->gadget && (block->gadget->type == GADGET_RADIO ||
- block->gadget->type == GADGET_CHECKBOX)) {
- /* form checkbox or radio button
- * if width or height is AUTO, set it to 1em */
- gadget_unit = CSS_UNIT_EM;
- gadget_size = INTTOFIX(1);
- if (block->height == AUTO)
- block->height = FIXTOINT(nscss_len2px(gadget_size,
- gadget_unit, block->style));
+ /* margin */
+ if (margin) {
+ enum css_margin_e type;
+
+ type = margin_funcs[side](style, &value, &unit);
+ if (type == CSS_MARGIN_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ *frac += FIXTOINT(FDIV(value, F_100));
+ } else {
+ *fixed += FIXTOINT(nscss_len2px(value, unit,
+ style));
+ }
+ }
}
- box = block->children;
- /* set current coordinates to top-left of the block */
- cx = 0;
- y = cy = block->padding[TOP];
- if (box)
- box->y = block->padding[TOP];
+ /* border */
+ if (border) {
+ if (border_funcs[side].style(style) !=
+ CSS_BORDER_STYLE_NONE) {
+ border_funcs[side].width(style, &value, &unit);
- /* Step through the descendants of the block in depth-first order, but
- * not into the children of boxes which aren't blocks. For example, if
- * the tree passed to this function looks like this (box->type shown):
- *
- * block -> BOX_BLOCK
- * BOX_BLOCK * (1)
- * BOX_INLINE_CONTAINER * (2)
- * BOX_INLINE
- * BOX_TEXT
- * ...
- * BOX_BLOCK * (3)
- * BOX_TABLE * (4)
- * BOX_TABLE_ROW
- * BOX_TABLE_CELL
- * ...
- * BOX_TABLE_CELL
- * ...
- * BOX_BLOCK * (5)
- * BOX_INLINE_CONTAINER * (6)
- * BOX_TEXT
- * ...
- * then the while loop will visit each box marked with *, setting box
- * to each in the order shown. */
- while (box) {
- enum css_overflow_e overflow_x = CSS_OVERFLOW_VISIBLE;
- enum css_overflow_e overflow_y = CSS_OVERFLOW_VISIBLE;
-
- assert(box->type == BOX_BLOCK || box->type == BOX_TABLE ||
- box->type == BOX_INLINE_CONTAINER);
-
- /* Tables are laid out before being positioned, because the
- * position depends on the width which is calculated in
- * table layout. Blocks and inline containers are positioned
- * before being laid out, because width is not dependent on
- * content, and the position is required during layout for
- * correct handling of floats.
- */
-
- if (box->style &&
- (css_computed_position(box->style) ==
- CSS_POSITION_ABSOLUTE ||
- css_computed_position(box->style) ==
- CSS_POSITION_FIXED)) {
- box->x = box->parent->padding[LEFT];
- /* absolute positioned; this element will establish
- * its own block context when it gets laid out later,
- * so no need to look at its children now. */
- goto advance_to_next_box;
+ *fixed += FIXTOINT(nscss_len2px(value, unit, style));
}
+ }
- /* If we don't know which box the current margin collapses
- * through to, find out. Update the pos/neg margin values. */
- if (margin_collapse == NULL) {
- margin_collapse = layout_next_margin_block(box, block,
- viewport_height,
- &max_pos_margin, &max_neg_margin);
- /* We have a margin that has not yet been applied. */
- in_margin = true;
+ /* padding */
+ if (padding) {
+ padding_funcs[side](style, &value, &unit);
+ if (unit == CSS_UNIT_PCT) {
+ *frac += FIXTOINT(FDIV(value, F_100));
+ } else {
+ *fixed += FIXTOINT(nscss_len2px(value, unit, style));
}
+ }
+}
- /* Clearance. */
- y = 0;
- if (box->style && css_computed_clear(box->style) !=
- CSS_CLEAR_NONE)
- y = layout_clear(block->float_children,
- css_computed_clear(box->style));
-
- /* Find box's overflow properties */
- if (box->style) {
- overflow_x = css_computed_overflow_x(box->style);
- overflow_y = css_computed_overflow_y(box->style);
- }
- /* Blocks establishing a block formatting context get minimum
- * left and right margins to avoid any floats. */
- lm = rm = 0;
+/**
+ * Calculate minimum and maximum width of a line.
+ *
+ * \param first a box in an inline container
+ * \param line_min updated to minimum width of line starting at first
+ * \param line_max updated to maximum width of line starting at first
+ * \param first_line true iff this is the first line in the inline container
+ * \param line_has_height updated to true or false, depending on line
+ * \param font_func Font functions.
+ * \return first box in next line, or 0 if no more lines
+ * \post 0 <= *line_min <= *line_max
+ */
+static struct box *
+layout_minmax_line(struct box *first,
+ int *line_min,
+ int *line_max,
+ bool first_line,
+ bool *line_has_height,
+ const struct gui_layout_table *font_func)
+{
+ int min = 0, max = 0, width, height, fixed;
+ float frac;
+ size_t i, j;
+ struct box *b;
+ struct box *block;
+ plot_font_style_t fstyle;
+ bool no_wrap;
- if (box->type == BOX_BLOCK || box->flags & IFRAME) {
- if (!box->object && !(box->flags & IFRAME) &&
- !(box->flags & REPLACE_DIM) &&
- box->style &&
- (overflow_x != CSS_OVERFLOW_VISIBLE ||
- overflow_y != CSS_OVERFLOW_VISIBLE)) {
- /* box establishes new block formatting context
- * so available width may be diminished due to
- * floats. */
- int x0, x1, top;
- struct box *left, *right;
- top = cy + max_pos_margin - max_neg_margin;
- top = (top > y) ? top : y;
- x0 = cx;
- x1 = cx + box->parent->width -
- box->parent->padding[LEFT] -
- box->parent->padding[RIGHT];
- find_sides(block->float_children, top, top,
- &x0, &x1, &left, &right);
- /* calculate min required left & right margins
- * needed to avoid floats */
- lm = x0 - cx;
- rm = cx + box->parent->width -
- box->parent->padding[LEFT] -
- box->parent->padding[RIGHT] -
- x1;
- }
- layout_block_find_dimensions(box->parent->width,
- viewport_height, lm, rm, box);
- if (box->type == BOX_BLOCK && !(box->flags & IFRAME)) {
- layout_block_add_scrollbar(box, RIGHT);
- layout_block_add_scrollbar(box, BOTTOM);
- }
- } else if (box->type == BOX_TABLE) {
- if (box->style != NULL) {
- enum css_width_e wtype;
- css_fixed width = 0;
- css_unit unit = CSS_UNIT_PX;
+ assert(first->parent);
+ assert(first->parent->parent);
+ assert(first->parent->parent->style);
- wtype = css_computed_width(box->style, &width,
- &unit);
+ block = first->parent->parent;
+ no_wrap = (css_computed_white_space(block->style) ==
+ CSS_WHITE_SPACE_NOWRAP ||
+ css_computed_white_space(block->style) ==
+ CSS_WHITE_SPACE_PRE);
- if (wtype == CSS_WIDTH_AUTO) {
- /* max available width may be
- * diminished due to floats. */
- int x0, x1, top;
- struct box *left, *right;
- top = cy + max_pos_margin -
- max_neg_margin;
- top = (top > y) ? top : y;
- x0 = cx;
- x1 = cx + box->parent->width -
- box->parent->padding[LEFT] -
- box->parent->padding[RIGHT];
- find_sides(block->float_children,
- top, top, &x0, &x1,
- &left, &right);
- /* calculate min required left & right
- * margins needed to avoid floats */
- lm = x0 - cx;
- rm = cx + box->parent->width -
- box->parent->padding[LEFT] -
- box->parent->padding[RIGHT] -
- x1;
- }
- }
- if (!layout_table(box, box->parent->width - lm - rm,
- content))
- return false;
- layout_solve_width(box, box->parent->width, box->width,
- lm, rm, -1, -1);
- }
+ *line_has_height = false;
- /* Position box: horizontal. */
- box->x = box->parent->padding[LEFT] + box->margin[LEFT] +
- box->border[LEFT].width;
- cx += box->x;
+ /* corresponds to the pass 1 loop in layout_line() */
+ for (b = first; b; b = b->next) {
+ enum css_width_e wtype;
+ enum css_height_e htype;
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
- /* Position box: vertical. */
- if (box->border[TOP].width) {
- box->y += box->border[TOP].width;
- cy += box->border[TOP].width;
- }
+ assert(b->type == BOX_INLINE || b->type == BOX_INLINE_BLOCK ||
+ b->type == BOX_FLOAT_LEFT ||
+ b->type == BOX_FLOAT_RIGHT ||
+ b->type == BOX_BR || b->type == BOX_TEXT ||
+ b->type == BOX_INLINE_END);
- /* Vertical margin */
- if (((box->type == BOX_BLOCK &&
- (box->flags & HAS_HEIGHT)) ||
- box->type == BOX_TABLE ||
- (box->type == BOX_INLINE_CONTAINER &&
- box != box->parent->children) ||
- margin_collapse == box) &&
- in_margin == true) {
- /* Margin goes above this box. */
- cy += max_pos_margin - max_neg_margin;
- box->y += max_pos_margin - max_neg_margin;
+#ifdef LAYOUT_DEBUG
+ LOG("%p: min %i, max %i", b, min, max);
+#endif
- /* Current margin has been applied. */
- in_margin = false;
- max_pos_margin = max_neg_margin = 0;
+ if (b->type == BOX_BR) {
+ b = b->next;
+ break;
}
- /* Handle clearance */
- if (box->type != BOX_INLINE_CONTAINER &&
- (y > 0) && (cy < y)) {
- /* box clears something*/
- box->y += y - cy;
- cy = y;
+ if (b->type == BOX_FLOAT_LEFT || b->type == BOX_FLOAT_RIGHT) {
+ assert(b->children);
+ if (b->children->type == BOX_BLOCK)
+ layout_minmax_block(b->children, font_func);
+ else
+ layout_minmax_table(b->children, font_func);
+ b->min_width = b->children->min_width;
+ b->max_width = b->children->max_width;
+ if (min < b->min_width)
+ min = b->min_width;
+ max += b->max_width;
+ continue;
}
- /* Unless the box has an overflow style of visible, the box
- * establishes a new block context. */
- if (box->type == BOX_BLOCK && box->style &&
- (overflow_x != CSS_OVERFLOW_VISIBLE ||
- overflow_y != CSS_OVERFLOW_VISIBLE)) {
+ if (b->type == BOX_INLINE_BLOCK) {
+ layout_minmax_block(b, font_func);
+ if (min < b->min_width)
+ min = b->min_width;
+ max += b->max_width;
- layout_block_context(box, viewport_height, content);
+ if (b->flags & HAS_HEIGHT)
+ *line_has_height = true;
+ continue;
+ }
- cy += box->padding[TOP];
+ assert(b->style);
+ font_plot_style_from_css(b->style, &fstyle);
- if (box->height == AUTO) {
- box->height = 0;
- layout_block_add_scrollbar(box, BOTTOM);
- }
+ if (b->type == BOX_INLINE && !b->object &&
+ !(b->flags & REPLACE_DIM) &&
+ !(b->flags & IFRAME)) {
+ fixed = frac = 0;
+ calculate_mbp_width(b->style, LEFT, true, true, true,
+ &fixed, &frac);
+ if (!b->inline_end)
+ calculate_mbp_width(b->style, RIGHT,
+ true, true, true,
+ &fixed, &frac);
+ if (0 < fixed)
+ max += fixed;
+ *line_has_height = true;
+ /* \todo update min width, consider fractional extra */
+ } else if (b->type == BOX_INLINE_END) {
+ fixed = frac = 0;
+ calculate_mbp_width(b->inline_end->style, RIGHT,
+ true, true, true,
+ &fixed, &frac);
+ if (0 < fixed)
+ max += fixed;
- cx -= box->x;
- cy += box->height + box->padding[BOTTOM] +
- box->border[BOTTOM].width;
- y = box->y + box->padding[TOP] + box->height +
- box->padding[BOTTOM] +
- box->border[BOTTOM].width;
+ if (b->next) {
+ if (b->space == UNKNOWN_WIDTH) {
+ font_func->width(&fstyle, " ", 1,
+ &b->space);
+ }
+ max += b->space;
+ }
- /* Skip children, because they are done in the new
- * block context */
- goto advance_to_next_box;
+ *line_has_height = true;
+ continue;
}
-#ifdef LAYOUT_DEBUG
- LOG("box %p, cx %i, cy %i", box, cx, cy);
-#endif
+ if (!b->object && !(b->flags & IFRAME) && !b->gadget &&
+ !(b->flags & REPLACE_DIM)) {
+ /* inline non-replaced, 10.3.1 and 10.6.1 */
+ bool no_wrap_box;
+ if (!b->text)
+ continue;
- /* Layout (except tables). */
- if (box->object) {
- if (!layout_block_object(box))
- return false;
+ no_wrap_box = (css_computed_white_space(b->style) ==
+ CSS_WHITE_SPACE_NOWRAP ||
+ css_computed_white_space(b->style) ==
+ CSS_WHITE_SPACE_PRE);
- } else if (box->type == BOX_INLINE_CONTAINER) {
- box->width = box->parent->width;
- if (!layout_inline_container(box, box->width, block,
- cx, cy, content))
- return false;
+ if (b->width == UNKNOWN_WIDTH) {
+ /** \todo handle errors */
- } else if (box->type == BOX_TABLE) {
- /* Move down to avoid floats if necessary. */
- int x0, x1;
- struct box *left, *right;
- y = cy;
- while (1) {
- enum css_width_e wtype;
- css_fixed width = 0;
- css_unit unit = CSS_UNIT_PX;
+ /* If it's a select element, we must use the
+ * width of the widest option text */
+ if (b->parent->parent->gadget &&
+ b->parent->parent->gadget->type
+ == GADGET_SELECT) {
+ int opt_maxwidth = 0;
+ struct form_option *o;
- wtype = css_computed_width(box->style,
- &width, &unit);
+ for (o = b->parent->parent->gadget->
+ data.select.items; o;
+ o = o->next) {
+ int opt_width;
+ font_func->width(&fstyle,
+ o->text,
+ strlen(o->text),
+ &opt_width);
- x0 = cx;
- x1 = cx + box->parent->width;
- find_sides(block->float_children, y,
- y + box->height,
- &x0, &x1, &left, &right);
- if (wtype == CSS_WIDTH_AUTO)
- break;
- if (box->width <= x1 - x0)
- break;
- if (!left && !right)
- break;
- else if (!left)
- y = right->y + right->height + 1;
- else if (!right)
- y = left->y + left->height + 1;
- else if (left->y + left->height <
- right->y + right->height)
- y = left->y + left->height + 1;
- else
- y = right->y + right->height + 1;
+ if (opt_maxwidth < opt_width)
+ opt_maxwidth =opt_width;
+ }
+
+ b->width = opt_maxwidth;
+ if (nsoption_bool(core_select_menu))
+ b->width += SCROLLBAR_WIDTH;
+
+ } else {
+ font_func->width(&fstyle, b->text,
+ b->length, &b->width);
+ b->flags |= MEASURED;
+ }
+ }
+ max += b->width;
+ if (b->next) {
+ if (b->space == UNKNOWN_WIDTH) {
+ font_func->width(&fstyle, " ", 1,
+ &b->space);
+ }
+ max += b->space;
}
- box->x += x0 - cx;
- cx = x0;
- box->y += y - cy;
- cy = y;
- }
- /* Advance to next box. */
- if (box->type == BOX_BLOCK && !box->object && !(box->iframe) &&
- box->children) {
- /* Down into children. */
+ if (no_wrap) {
+ /* Don't wrap due to block style,
+ * so min is the same as max */
+ min = max;
- if (box == margin_collapse) {
- /* Current margin collapsed though to this box.
- * Unset margin_collapse. */
- margin_collapse = NULL;
+ } else if (no_wrap_box) {
+ /* This inline box can't be wrapped,
+ * for min, consider box's width */
+ if (min < b->width)
+ min = b->width;
+
+ } else if (b->parent->flags & NEED_MIN) {
+ /* If we care what the minimum width is,
+ * calculate it. (It's only needed if we're
+ * shrinking-to-fit.) */
+ /* min = widest single word */
+ i = 0;
+ do {
+ for (j = i; j != b->length &&
+ b->text[j] != ' '; j++)
+ ;
+ font_func->width(&fstyle, b->text + i,
+ j - i, &width);
+ if (min < width)
+ min = width;
+ i = j + 1;
+ } while (j != b->length);
}
- y = box->padding[TOP];
- box = box->children;
- box->y = y;
- cy += y;
- continue;
- } else if (box->type == BOX_BLOCK || box->object ||
- box->flags & IFRAME)
- cy += box->padding[TOP];
+ *line_has_height = true;
- if (box->type == BOX_BLOCK && box->height == AUTO) {
- box->height = 0;
- layout_block_add_scrollbar(box, BOTTOM);
+ continue;
}
- cy += box->height + box->padding[BOTTOM] +
- box->border[BOTTOM].width;
- cx -= box->x;
- y = box->y + box->padding[TOP] + box->height +
- box->padding[BOTTOM] +
- box->border[BOTTOM].width;
+ /* inline replaced, 10.3.2 and 10.6.2 */
+ assert(b->style);
- advance_to_next_box:
- if (!box->next) {
- /* No more siblings:
- * up to first ancestor with a sibling. */
+ /* calculate box width */
+ wtype = css_computed_width(b->style, &value, &unit);
+ if (wtype == CSS_WIDTH_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ /*
+ b->width = FPCT_OF_INT_TOINT(value, width);
+ */
- do {
- if (box == margin_collapse) {
- /* Current margin collapsed though to
- * this box. Unset margin_collapse. */
- margin_collapse = NULL;
- }
+ width = AUTO;
+ } else {
+ width = FIXTOINT(nscss_len2px(value, unit,
+ b->style));
+ if (width < 0)
+ width = 0;
+ }
+ } else {
+ width = AUTO;
+ }
- /* Apply bottom margin */
- if (max_pos_margin < box->margin[BOTTOM])
- max_pos_margin = box->margin[BOTTOM];
- else if (max_neg_margin < -box->margin[BOTTOM])
- max_neg_margin = -box->margin[BOTTOM];
+ /* height */
+ htype = css_computed_height(b->style, &value, &unit);
+ if (htype == CSS_HEIGHT_SET) {
+ height = FIXTOINT(nscss_len2px(value, unit, b->style));
+ } else {
+ height = AUTO;
+ }
- box = box->parent;
- if (box == block)
- break;
+ if (b->object || (b->flags & REPLACE_DIM)) {
+ if (b->object) {
+ int temp_height = height;
+ layout_get_object_dimensions(b,
+ &width, &temp_height,
+ INT_MIN, INT_MAX,
+ INT_MIN, INT_MAX);
+ }
- /* Margin is invalidated if this is a box
- * margins can't collapse through. */
- if (box->type == BOX_BLOCK &&
- box->flags & MAKE_HEIGHT) {
- margin_collapse = NULL;
- in_margin = false;
- max_pos_margin = max_neg_margin = 0;
- }
+ fixed = frac = 0;
+ calculate_mbp_width(b->style, LEFT, true, true, true,
+ &fixed, &frac);
+ calculate_mbp_width(b->style, RIGHT, true, true, true,
+ &fixed, &frac);
- if (box->height == AUTO) {
- box->height = y - box->padding[TOP];
+ if (0 < width + fixed)
+ width += fixed;
+ } else if (b->flags & IFRAME) {
+ /* TODO: handle percentage widths properly */
+ if (width == AUTO)
+ width = 400;
- if (box->type == BOX_BLOCK)
- layout_block_add_scrollbar(box,
- BOTTOM);
- } else
- cy += box->height -
- (y - box->padding[TOP]);
+ fixed = frac = 0;
+ calculate_mbp_width(b->style, LEFT, true, true, true,
+ &fixed, &frac);
+ calculate_mbp_width(b->style, RIGHT, true, true, true,
+ &fixed, &frac);
- /* Apply any min-height and max-height to
- * boxes in normal flow */
- if (box->style &&
- css_computed_position(box->style) !=
- CSS_POSITION_ABSOLUTE &&
- layout_apply_minmax_height(box,
- NULL)) {
- /* Height altered */
- /* Set current cy */
- cy += box->height -
- (y - box->padding[TOP]);
- }
+ if (0 < width + fixed)
+ width += fixed;
+ } else {
+ /* form control with no object */
+ if (width == AUTO)
+ width = FIXTOINT(nscss_len2px(INTTOFIX(1),
+ CSS_UNIT_EM, b->style));
+ }
- cy += box->padding[BOTTOM] +
- box->border[BOTTOM].width;
- cx -= box->x;
- y = box->y + box->padding[TOP] + box->height +
- box->padding[BOTTOM] +
- box->border[BOTTOM].width;
+ if (min < width)
+ min = width;
+ max += width;
- } while (box->next == NULL);
- if (box == block)
- break;
- }
+ *line_has_height = true;
+ }
- /* To next sibling. */
+ if (first_line) {
+ /* todo: handle percentage values properly */
+ /* todo: handle text-indent interaction with floats */
+ int text_indent = layout_text_indent(
+ first->parent->parent->style, 100);
+ min = (min + text_indent < 0) ? 0 : min + text_indent;
+ max = (max + text_indent < 0) ? 0 : max + text_indent;
+ }
- if (box == margin_collapse) {
- /* Current margin collapsed though to this box.
- * Unset margin_collapse. */
- margin_collapse = NULL;
- }
+ *line_min = min;
+ *line_max = max;
- if (max_pos_margin < box->margin[BOTTOM])
- max_pos_margin = box->margin[BOTTOM];
- else if (max_neg_margin < -box->margin[BOTTOM])
- max_neg_margin = -box->margin[BOTTOM];
+#ifdef LAYOUT_DEBUG
+ LOG("line_min %i, line_max %i", min, max);
+#endif
- box = box->next;
- box->y = y;
- }
+ assert(b != first);
+ assert(0 <= *line_min);
+ assert(*line_min <= *line_max);
+ return b;
+}
- /* Account for bottom margin of last contained block */
- cy += max_pos_margin - max_neg_margin;
- /* Increase height to contain any floats inside (CSS 2.1 10.6.7). */
- for (box = block->float_children; box; box = box->next_float) {
- y = box->y + box->height + box->padding[BOTTOM] +
- box->border[BOTTOM].width + box->margin[BOTTOM];
- if (cy < y)
- cy = y;
- }
+/**
+ * Calculate minimum and maximum width of an inline container.
+ *
+ * \param inline_container box of type INLINE_CONTAINER
+ * \param[out] has_height set to true if container has height
+ * \param font_func Font functions.
+ * \post inline_container->min_width and inline_container->max_width filled in,
+ * 0 <= inline_container->min_width <= inline_container->max_width
+ */
+static void
+layout_minmax_inline_container(struct box *inline_container,
+ bool *has_height,
+ const struct gui_layout_table *font_func)
+{
+ struct box *child;
+ int line_min = 0, line_max = 0;
+ int min = 0, max = 0;
+ bool first_line = true;
+ bool line_has_height;
- if (block->height == AUTO) {
- block->height = cy - block->padding[TOP];
- if (block->type == BOX_BLOCK)
- layout_block_add_scrollbar(block, BOTTOM);
- }
+ assert(inline_container->type == BOX_INLINE_CONTAINER);
- if (block->style && css_computed_position(block->style) !=
- CSS_POSITION_ABSOLUTE) {
- /* Block is in normal flow */
- layout_apply_minmax_height(block, NULL);
- }
+ /* check if the widths have already been calculated */
+ if (inline_container->max_width != UNKNOWN_MAX_WIDTH)
+ return;
- if (block->gadget &&
- (block->gadget->type == GADGET_TEXTAREA ||
- block->gadget->type == GADGET_PASSWORD ||
- block->gadget->type == GADGET_TEXTBOX)) {
- int ta_width = block->padding[LEFT] + block->width +
- block->padding[RIGHT];
- int ta_height = block->padding[TOP] + block->height +
- block->padding[BOTTOM];
- textarea_set_layout(block->gadget->data.text.ta,
- ta_width, ta_height,
- block->padding[TOP], block->padding[RIGHT],
- block->padding[BOTTOM], block->padding[LEFT]);
+ *has_height = false;
+
+ for (child = inline_container->children; child; ) {
+ child = layout_minmax_line(child, &line_min, &line_max,
+ first_line, &line_has_height, font_func);
+ if (min < line_min)
+ min = line_min;
+ if (max < line_max)
+ max = line_max;
+ first_line = false;
+ *has_height |= line_has_height;
}
- return true;
+ inline_container->min_width = min;
+ inline_container->max_width = max;
+
+ assert(0 <= inline_container->min_width &&
+ inline_container->min_width <=
+ inline_container->max_width);
}
@@ -694,9 +654,8 @@ bool layout_block_context(struct box *block, int viewport_height,
* \post block->min_width and block->max_width filled in,
* 0 <= block->min_width <= block->max_width
*/
-
-void layout_minmax_block(struct box *block,
- const struct font_functions *font_func)
+static void
+layout_minmax_block(struct box *block, const struct gui_layout_table *font_func)
{
struct box *child;
int min = 0, max = 0;
@@ -891,561 +850,738 @@ void layout_minmax_block(struct box *block,
/**
- * Find next block that current margin collapses to.
+ * Under some circumstances, specified dimensions for form elements include
+ * borders and padding.
*
- * \param box box to start tree-order search from (top margin is included)
- * \param block box responsible for current block fromatting context
- * \param viewport_height height of viewport in px
- * \param max_pos_margin updated to to maximum positive margin encountered
- * \param max_neg_margin updated to to maximum negative margin encountered
- * \return next box that current margin collapses to, or NULL if none.
+ * \param box gadget to adjust dimensions of
+ * \param percentage whether the gadget has its dimension specified as a
+ * percentage
+ * \param available_width width of containing block
+ * \param setwidth set true if the dimension to be tweaked is a width,
+ * else set false for a height
+ * \param dimension current value for given width/height dimension.
+ * updated to new value after consideration of
+ * gadget properties.
*/
-
-struct box* layout_next_margin_block(struct box *box, struct box *block,
- int viewport_height, int *max_pos_margin, int *max_neg_margin)
+static void layout_tweak_form_dimensions(struct box *box, bool percentage,
+ int available_width, bool setwidth, int *dimension)
{
- assert(block != NULL);
+ int fixed = 0;
+ float frac = 0;
- while (box != NULL) {
+ assert(box && box->gadget);
- if (box->type == BOX_INLINE_CONTAINER || (box->style &&
- (css_computed_position(box->style) !=
- CSS_POSITION_ABSOLUTE &&
- css_computed_position(box->style) !=
- CSS_POSITION_FIXED))) {
- /* Not positioned */
+ /* specified gadget widths include borders and padding in some
+ * cases */
+ if (percentage || box->gadget->type == GADGET_SUBMIT ||
+ box->gadget->type == GADGET_RESET ||
+ box->gadget->type == GADGET_BUTTON) {
+ calculate_mbp_width(box->style, setwidth ? LEFT : TOP,
+ false, true, true, &fixed, &frac);
+ calculate_mbp_width(box->style, setwidth ? RIGHT : BOTTOM,
+ false, true, true, &fixed, &frac);
+ *dimension -= frac * available_width + fixed;
+ *dimension = *dimension > 0 ? *dimension : 0;
+ }
+}
- /* Get margins */
- if (box->style) {
- layout_find_dimensions(box->parent->width,
- viewport_height, box,
- box->style,
- NULL, NULL, NULL, NULL,
- NULL, NULL, box->margin,
- box->padding, box->border);
- /* Apply top margin */
- if (*max_pos_margin < box->margin[TOP])
- *max_pos_margin = box->margin[TOP];
- else if (*max_neg_margin < -box->margin[TOP])
- *max_neg_margin = -box->margin[TOP];
- }
+/**
+ * Calculate width, height, and thickness of margins, paddings, and borders.
+ *
+ * \param available_width width of containing block
+ * \param viewport_height height of viewport in pixels or -ve if unknown
+ * \param box current box
+ * \param style style giving width, height, margins, paddings,
+ * and borders
+ * \param width updated to width, may be NULL
+ * \param height updated to height, may be NULL
+ * \param max_width updated to max-width, may be NULL
+ * \param min_width updated to min-width, may be NULL
+ * \param max_height updated to max-height, may be NULL
+ * \param min_height updated to min-height, may be NULL
+ * \param margin filled with margins, may be NULL
+ * \param padding filled with paddings, may be NULL
+ * \param border filled with border widths, may be NULL
+ */
+static void
+layout_find_dimensions(int available_width,
+ int viewport_height,
+ struct box *box,
+ const css_computed_style *style,
+ int *width,
+ int *height,
+ int *max_width,
+ int *min_width,
+ int *max_height,
+ int *min_height,
+ int margin[4],
+ int padding[4],
+ struct box_border border[4])
+{
+ struct box *containing_block = NULL;
+ unsigned int i;
+ bool percentage;
- /* Check whether box is the box current margin collapses
- * to */
- if (box->flags & MAKE_HEIGHT ||
- box->border[TOP].width ||
- box->padding[TOP] ||
- (box->style &&
- css_computed_overflow_y(box->style) !=
- CSS_OVERFLOW_VISIBLE) ||
- (box->type == BOX_INLINE_CONTAINER &&
- box != box->parent->children)) {
- /* Collapse to this box; return it */
- return box;
+ if (width) {
+ enum css_width_e wtype;
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
+
+ wtype = css_computed_width(style, &value, &unit);
+
+ if (wtype == CSS_WIDTH_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ *width = FPCT_OF_INT_TOINT(
+ value, available_width);
+ } else {
+ *width = FIXTOINT(nscss_len2px(value, unit,
+ style));
}
+ } else {
+ *width = AUTO;
}
+ /* specified gadget widths include borders and padding in some
+ * cases */
+ if (box->gadget && *width != AUTO) {
+ percentage = unit == CSS_UNIT_PCT;
- /* Find next box */
- if (box->type == BOX_BLOCK && !box->object && box->children &&
- box->style &&
- css_computed_overflow_y(box->style) ==
- CSS_OVERFLOW_VISIBLE) {
- /* Down into children. */
- box = box->children;
- } else {
- if (!box->next) {
- /* No more siblings:
- * Go up to first ancestor with a sibling. */
- do {
- /* Apply bottom margin */
- if (*max_pos_margin <
- box->margin[BOTTOM])
- *max_pos_margin =
- box->margin[BOTTOM];
- else if (*max_neg_margin <
- -box->margin[BOTTOM])
- *max_neg_margin =
- -box->margin[BOTTOM];
-
- box = box->parent;
- } while (box != block && !box->next);
+ layout_tweak_form_dimensions(box, percentage,
+ available_width, true, width);
+ }
+ }
- if (box == block) {
- /* Margins don't collapse with stuff
- * outside the block formatting context
- */
- return block;
- }
- }
+ if (height) {
+ enum css_height_e htype;
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
- /* Apply bottom margin */
- if (*max_pos_margin < box->margin[BOTTOM])
- *max_pos_margin = box->margin[BOTTOM];
- else if (*max_neg_margin < -box->margin[BOTTOM])
- *max_neg_margin = -box->margin[BOTTOM];
+ htype = css_computed_height(style, &value, &unit);
- /* To next sibling. */
- box = box->next;
+ if (htype == CSS_HEIGHT_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ enum css_height_e cbhtype;
- /* Get margins */
- if (box->style) {
- layout_find_dimensions(box->parent->width,
- viewport_height, box,
- box->style,
- NULL, NULL, NULL, NULL,
- NULL, NULL, box->margin,
- box->padding, box->border);
- }
- }
- }
+ if (css_computed_position(box->style) ==
+ CSS_POSITION_ABSOLUTE &&
+ box->parent) {
+ /* Box is absolutely positioned */
+ assert(box->float_container);
+ containing_block = box->float_container;
+ } else if (box->float_container &&
+ css_computed_position(box->style) !=
+ CSS_POSITION_ABSOLUTE &&
+ (css_computed_float(box->style) ==
+ CSS_FLOAT_LEFT ||
+ css_computed_float(box->style) ==
+ CSS_FLOAT_RIGHT)) {
+ /* Box is a float */
+ assert(box->parent &&
+ box->parent->parent &&
+ box->parent->parent->parent);
- return NULL;
-}
+ containing_block =
+ box->parent->parent->parent;
+ } else if (box->parent && box->parent->type !=
+ BOX_INLINE_CONTAINER) {
+ /* Box is a block level element */
+ containing_block = box->parent;
+ } else if (box->parent && box->parent->type ==
+ BOX_INLINE_CONTAINER) {
+ /* Box is an inline block */
+ assert(box->parent->parent);
+ containing_block = box->parent->parent;
+ }
+ if (containing_block) {
+ css_fixed f = 0;
+ css_unit u = CSS_UNIT_PX;
-/**
- * Layout a block which contains an object.
- *
- * \param block box of type BLOCK, INLINE_BLOCK, TABLE, or TABLE_CELL
- * \return true on success, false on memory exhaustion
- */
+ cbhtype = css_computed_height(
+ containing_block->style,
+ &f, &u);
+ }
-bool layout_block_object(struct box *block)
-{
- assert(block);
- assert(block->type == BOX_BLOCK ||
- block->type == BOX_INLINE_BLOCK ||
- block->type == BOX_TABLE ||
- block->type == BOX_TABLE_CELL);
- assert(block->object);
+ if (containing_block &&
+ containing_block->height != AUTO &&
+ (css_computed_position(box->style) ==
+ CSS_POSITION_ABSOLUTE ||
+ cbhtype == CSS_HEIGHT_SET)) {
+ /* Box is absolutely positioned or its
+ * containing block has a valid
+ * specified height.
+ * (CSS 2.1 Section 10.5) */
+ *height = FPCT_OF_INT_TOINT(value,
+ containing_block->height);
+ } else if ((!box->parent ||
+ !box->parent->parent) &&
+ viewport_height >= 0) {
+ /* If root element or it's child
+ * (HTML or BODY) */
+ *height = FPCT_OF_INT_TOINT(value,
+ viewport_height);
+ } else {
+ /* precentage height not permissible
+ * treat height as auto */
+ *height = AUTO;
+ }
+ } else {
+ *height = FIXTOINT(nscss_len2px(value, unit,
+ style));
+ }
+ } else {
+ *height = AUTO;
+ }
-#ifdef LAYOUT_DEBUG
- LOG("block %p, object %s, width %i", block, hlcache_handle_get_url(block->object), block->width);
-#endif
+ /* specified gadget heights include borders and padding in
+ * some cases */
+ if (box->gadget && *height != AUTO) {
+ percentage = unit == CSS_UNIT_PCT;
- if (content_get_type(block->object) == CONTENT_HTML) {
- content_reformat(block->object, false, block->width, 1);
- } else {
- /* Non-HTML objects */
- /* this case handled already in
- * layout_block_find_dimensions() */
+ layout_tweak_form_dimensions(box, percentage,
+ available_width, false, height);
+ }
}
- return true;
-}
+ if (max_width) {
+ enum css_max_width_e type;
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
+ type = css_computed_max_width(style, &value, &unit);
-/**
- * Compute the size of replaced boxes with auto dimensions, according to
- * content.
- *
- * \param box Box with object
- * \param width Width value in px or AUTO. If AUTO, updated to value in px.
- * \param height Height value in px or AUTO. If AUTO, updated to value in px.
- * \param min_width Box's min width, as given by layout_find_dimensions.
- * \param max_width Box's max width, as given by layout_find_dimensions.
- * \param min_height Box's min height, as given by layout_find_dimensions.
- * \param max_height Box's max height, as given by layout_find_dimensions.
- *
- * See CSS 2.1 sections 10.3 and 10.6.
- */
+ if (type == CSS_MAX_WIDTH_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ *max_width = FPCT_OF_INT_TOINT(value,
+ available_width);
+ } else {
+ *max_width = FIXTOINT(nscss_len2px(value, unit,
+ style));
+ }
+ } else {
+ /* Inadmissible */
+ *max_width = -1;
+ }
-void layout_get_object_dimensions(struct box *box, int *width, int *height,
- int min_width, int max_width, int min_height, int max_height)
-{
- assert(box->object != NULL);
- assert(width != NULL && height != NULL);
+ /* specified gadget widths include borders and padding in some
+ * cases */
+ if (box->gadget && *max_width != -1) {
+ percentage = unit == CSS_UNIT_PCT;
- if (*width == AUTO && *height == AUTO) {
- /* No given dimensions */
+ layout_tweak_form_dimensions(box, percentage,
+ available_width, true, max_width);
+ }
+ }
- bool scaled = false;
- int intrinsic_width = content_get_width(box->object);
- int intrinsic_height = content_get_height(box->object);
+ if (min_width) {
+ enum css_min_width_e type;
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
- /* use intrinsic dimensions */
- *width = intrinsic_width;
- *height = intrinsic_height;
+ type = css_computed_min_width(style, &value, &unit);
- /* Deal with min/max-width first */
- if (min_width > 0 && min_width > *width) {
- *width = min_width;
- scaled = true;
- }
- if (max_width >= 0 && max_width < *width) {
- *width = max_width;
- scaled = true;
+ if (type == CSS_MIN_WIDTH_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ *min_width = FPCT_OF_INT_TOINT(value,
+ available_width);
+ } else {
+ *min_width = FIXTOINT(nscss_len2px(value, unit,
+ style));
+ }
+ } else {
+ /* Inadmissible */
+ *min_width = 0;
}
- if (scaled && (intrinsic_width != 0)) {
- /* Update height */
- *height = (*width * intrinsic_height) /
- intrinsic_width;
- }
+ /* specified gadget widths include borders and padding in some
+ * cases */
+ if (box->gadget && *min_width != 0) {
+ percentage = unit == CSS_UNIT_PCT;
- scaled = false;
- /* Deal with min/max-height */
- if (min_height > 0 && min_height > *height) {
- *height = min_height;
- scaled = true;
+ layout_tweak_form_dimensions(box, percentage,
+ available_width, true, min_width);
}
- if (max_height >= 0 && max_height < *height) {
- *height = max_height;
- scaled = true;
- }
-
- if (scaled && (intrinsic_height != 0)) {
- /* Update width */
- *width = (*height * intrinsic_width) /
- intrinsic_height;
- }
-
- } else if (*width == AUTO) {
- /* Have given height; width is calculated from the given height
- * and ratio of intrinsic dimensions */
- int intrinsic_width = content_get_width(box->object);
- int intrinsic_height = content_get_height(box->object);
-
- if (intrinsic_height != 0)
- *width = (*height * intrinsic_width) /
- intrinsic_height;
- else
- *width = intrinsic_width;
-
- if (min_width > 0 && min_width > *width)
- *width = min_width;
- if (max_width >= 0 && max_width < *width)
- *width = max_width;
-
- } else if (*height == AUTO) {
- /* Have given width; height is calculated from the given width
- * and ratio of intrinsic dimensions */
- int intrinsic_width = content_get_width(box->object);
- int intrinsic_height = content_get_height(box->object);
-
- if (intrinsic_width != 0)
- *height = (*width * intrinsic_height) /
- intrinsic_width;
- else
- *height = intrinsic_height;
- }
-}
-
-
-/**
- * Compute dimensions of box, margins, paddings, and borders for a block-level
- * element.
- *
- * \param available_width Max width available in pixels
- * \param viewport_height Height of viewport in pixels or -ve if unknown
- * \param lm min left margin required to avoid floats in px.
- * zero if not applicable
- * \param rm min right margin required to avoid floats in px.
- * zero if not applicable
- * \param box box to find dimensions of. updated with new width,
- * height, margins, borders and paddings
- *
- * See CSS 2.1 10.3.3, 10.3.4, 10.6.2, and 10.6.3.
- */
-
-void layout_block_find_dimensions(int available_width, int viewport_height,
- int lm, int rm, struct box *box)
-{
- int width, max_width, min_width;
- int height, max_height, min_height;
- int *margin = box->margin;
- int *padding = box->padding;
- struct box_border *border = box->border;
- const css_computed_style *style = box->style;
-
- layout_find_dimensions(available_width, viewport_height, box, style,
- &width, &height, &max_width, &min_width,
- &max_height, &min_height, margin, padding, border);
-
- if (box->object && !(box->flags & REPLACE_DIM) &&
- content_get_type(box->object) != CONTENT_HTML) {
- /* block-level replaced element, see 10.3.4 and 10.6.2 */
- layout_get_object_dimensions(box, &width, &height,
- min_width, max_width, min_height, max_height);
- }
-
- box->width = layout_solve_width(box, available_width, width, lm, rm,
- max_width, min_width);
- box->height = height;
-
- if (margin[TOP] == AUTO)
- margin[TOP] = 0;
- if (margin[BOTTOM] == AUTO)
- margin[BOTTOM] = 0;
-}
-
-/**
- * Manimpulate box height according to CSS min-height and max-height properties
- *
- * \param box block to modify with any min-height or max-height
- * \param container containing block for absolutely positioned elements, or
- * NULL for non absolutely positioned elements.
- * \return whether the height has been changed
- */
-
-bool layout_apply_minmax_height(struct box *box, struct box *container)
-{
- int h;
- struct box *containing_block = NULL;
- bool updated = false;
-
- /* Find containing block for percentage heights */
- if (box->style != NULL && css_computed_position(box->style) ==
- CSS_POSITION_ABSOLUTE) {
- /* Box is absolutely positioned */
- assert(container);
- containing_block = container;
- } else if (box->float_container && box->style != NULL &&
- (css_computed_float(box->style) == CSS_FLOAT_LEFT ||
- css_computed_float(box->style) == CSS_FLOAT_RIGHT)) {
- /* Box is a float */
- assert(box->parent && box->parent->parent &&
- box->parent->parent->parent);
- containing_block = box->parent->parent->parent;
- } else if (box->parent && box->parent->type != BOX_INLINE_CONTAINER) {
- /* Box is a block level element */
- containing_block = box->parent;
- } else if (box->parent && box->parent->type == BOX_INLINE_CONTAINER) {
- /* Box is an inline block */
- assert(box->parent->parent);
- containing_block = box->parent->parent;
}
- if (box->style) {
- enum css_height_e htype = CSS_HEIGHT_AUTO;
+ if (max_height) {
+ enum css_max_height_e type;
css_fixed value = 0;
css_unit unit = CSS_UNIT_PX;
- if (containing_block) {
- htype = css_computed_height(containing_block->style,
- &value, &unit);
- }
+ type = css_computed_max_height(style, &value, &unit);
- /* max-height */
- if (css_computed_max_height(box->style, &value, &unit) ==
- CSS_MAX_HEIGHT_SET) {
+ if (type == CSS_MAX_HEIGHT_SET) {
if (unit == CSS_UNIT_PCT) {
- if (containing_block &&
- containing_block->height != AUTO &&
- (css_computed_position(box->style) ==
- CSS_POSITION_ABSOLUTE ||
- htype == CSS_HEIGHT_SET)) {
- /* Box is absolutely positioned or its
- * containing block has a valid
- * specified height. (CSS 2.1
- * Section 10.5) */
- h = FPCT_OF_INT_TOINT(value,
- containing_block->height);
- if (h < box->height) {
- box->height = h;
- updated = true;
- }
- }
+ /* TODO: handle percentage */
+ *max_height = -1;
} else {
- h = FIXTOINT(nscss_len2px(value, unit,
- box->style));
- if (h < box->height) {
- box->height = h;
- updated = true;
- }
+ *max_height = FIXTOINT(nscss_len2px(value, unit,
+ style));
}
+ } else {
+ /* Inadmissible */
+ *max_height = -1;
}
+ }
- /* min-height */
- if (css_computed_min_height(box->style, &value, &unit) ==
- CSS_MIN_HEIGHT_SET) {
+ if (min_height) {
+ enum css_min_height_e type;
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
+
+ type = css_computed_min_height(style, &value, &unit);
+
+ if (type == CSS_MIN_HEIGHT_SET) {
if (unit == CSS_UNIT_PCT) {
- if (containing_block &&
- containing_block->height != AUTO &&
- (css_computed_position(box->style) ==
- CSS_POSITION_ABSOLUTE ||
- htype == CSS_HEIGHT_SET)) {
- /* Box is absolutely positioned or its
- * containing block has a valid
- * specified height. (CSS 2.1
- * Section 10.5) */
- h = FPCT_OF_INT_TOINT(value,
- containing_block->height);
- if (h > box->height) {
- box->height = h;
- updated = true;
- }
- }
+ /* TODO: handle percentage */
+ *min_height = 0;
} else {
- h = FIXTOINT(nscss_len2px(value, unit,
- box->style));
- if (h > box->height) {
- box->height = h;
- updated = true;
- }
+ *min_height = FIXTOINT(nscss_len2px(value, unit,
+ style));
}
+ } else {
+ /* Inadmissible */
+ *min_height = 0;
}
}
- return updated;
-}
-
-/**
- * Manipulate a block's [RB]padding/height/width to accommodate scrollbars
- *
- * \param box Box to apply scrollbar space too. Must be BOX_BLOCK.
- * \param which Which scrollbar to make space for. Must be RIGHT or BOTTOM.
- */
-void layout_block_add_scrollbar(struct box *box, int which)
-{
- enum css_overflow_e overflow_x, overflow_y;
+ for (i = 0; i != 4; i++) {
+ if (margin) {
+ enum css_margin_e type = CSS_MARGIN_AUTO;
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
- assert(box->type == BOX_BLOCK && (which == RIGHT || which == BOTTOM));
+ switch (i) {
+ case TOP:
+ type = css_computed_margin_top(style,
+ &value, &unit);
+ break;
+ case RIGHT:
+ type = css_computed_margin_right(style,
+ &value, &unit);
+ break;
+ case BOTTOM:
+ type = css_computed_margin_bottom(style,
+ &value, &unit);
+ break;
+ case LEFT:
+ type = css_computed_margin_left(style,
+ &value, &unit);
+ break;
+ }
- if (box->style == NULL)
- return;
+ if (type == CSS_MARGIN_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ margin[i] = FPCT_OF_INT_TOINT(value,
+ available_width);
+ } else {
+ margin[i] = FIXTOINT(nscss_len2px(value,
+ unit, style));
+ }
+ } else {
+ margin[i] = AUTO;
+ }
+ }
- overflow_x = css_computed_overflow_x(box->style);
- overflow_y = css_computed_overflow_y(box->style);
+ if (padding) {
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
- if (which == BOTTOM &&
- (overflow_x == CSS_OVERFLOW_SCROLL ||
- overflow_x == CSS_OVERFLOW_AUTO ||
- (box->object &&
- content_get_type(box->object) == CONTENT_HTML))) {
- /* make space for scrollbar, unless height is AUTO */
- if (box->height != AUTO &&
- (overflow_x == CSS_OVERFLOW_SCROLL ||
- box_hscrollbar_present(box))) {
- box->padding[BOTTOM] += SCROLLBAR_WIDTH;
+ switch (i) {
+ case TOP:
+ css_computed_padding_top(style, &value, &unit);
+ break;
+ case RIGHT:
+ css_computed_padding_right(style, &value,
+ &unit);
+ break;
+ case BOTTOM:
+ css_computed_padding_bottom(style, &value,
+ &unit);
+ break;
+ case LEFT:
+ css_computed_padding_left(style, &value, &unit);
+ break;
+ }
+
+ if (unit == CSS_UNIT_PCT) {
+ padding[i] = FPCT_OF_INT_TOINT(value,
+ available_width);
+ } else {
+ padding[i] = FIXTOINT(nscss_len2px(value, unit,
+ style));
+ }
}
- } else if (which == RIGHT &&
- (overflow_y == CSS_OVERFLOW_SCROLL ||
- overflow_y == CSS_OVERFLOW_AUTO ||
- (box->object &&
- content_get_type(box->object) == CONTENT_HTML))) {
- /* make space for scrollbars, unless width is AUTO */
- enum css_height_e htype;
- css_fixed height = 0;
- css_unit hunit = CSS_UNIT_PX;
- htype = css_computed_height(box->style, &height, &hunit);
+ /* Table cell borders are populated in table.c */
+ if (border && box->type != BOX_TABLE_CELL) {
+ enum css_border_style_e bstyle = CSS_BORDER_STYLE_NONE;
+ css_color color = 0;
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
- if (which == RIGHT && box->width != AUTO &&
- htype == CSS_HEIGHT_SET &&
- (overflow_y == CSS_OVERFLOW_SCROLL ||
- box_vscrollbar_present(box))) {
- box->width -= SCROLLBAR_WIDTH;
- box->padding[RIGHT] += SCROLLBAR_WIDTH;
+ switch (i) {
+ case TOP:
+ css_computed_border_top_width(style, &value,
+ &unit);
+ bstyle = css_computed_border_top_style(style);
+ css_computed_border_top_color(style, &color);
+ break;
+ case RIGHT:
+ css_computed_border_right_width(style, &value,
+ &unit);
+ bstyle = css_computed_border_right_style(style);
+ css_computed_border_right_color(style, &color);
+ break;
+ case BOTTOM:
+ css_computed_border_bottom_width(style, &value,
+ &unit);
+ bstyle = css_computed_border_bottom_style(
+ style);
+ css_computed_border_bottom_color(style, &color);
+ break;
+ case LEFT:
+ css_computed_border_left_width(style, &value,
+ &unit);
+ bstyle = css_computed_border_left_style(style);
+ css_computed_border_left_color(style, &color);
+ break;
+ }
+
+ border[i].style = bstyle;
+ border[i].c = color;
+
+ if (bstyle == CSS_BORDER_STYLE_HIDDEN ||
+ bstyle == CSS_BORDER_STYLE_NONE)
+ /* spec unclear: following Mozilla */
+ border[i].width = 0;
+ else
+ border[i].width = FIXTOINT(nscss_len2px(value,
+ unit, style));
+
+ /* Special case for border-collapse: make all borders
+ * on table/table-row-group/table-row zero width. */
+ if (css_computed_border_collapse(style) ==
+ CSS_BORDER_COLLAPSE_COLLAPSE &&
+ (box->type == BOX_TABLE ||
+ box->type == BOX_TABLE_ROW_GROUP ||
+ box->type == BOX_TABLE_ROW))
+ border[i].width = 0;
}
}
}
+
/**
- * Solve the width constraint as given in CSS 2.1 section 10.3.3.
- *
- * \param box Box to solve constraint for
- * \param available_width Max width available in pixels
- * \param width Current box width
- * \param lm Min left margin required to avoid floats in px.
- * zero if not applicable
- * \param rm Min right margin required to avoid floats in px.
- * zero if not applicable
- * \param max_width Box max-width ( -ve means no max-width to apply)
- * \param min_width Box min-width ( <=0 means no min-width to apply)
- * \return New box width
+ * Find next block that current margin collapses to.
*
- * \post \a box's left/right margins will be updated.
+ * \param box box to start tree-order search from (top margin is included)
+ * \param block box responsible for current block fromatting context
+ * \param viewport_height height of viewport in px
+ * \param max_pos_margin updated to to maximum positive margin encountered
+ * \param max_neg_margin updated to to maximum negative margin encountered
+ * \return next box that current margin collapses to, or NULL if none.
*/
-
-int layout_solve_width(struct box *box, int available_width, int width,
- int lm, int rm, int max_width, int min_width)
+static struct box*
+layout_next_margin_block(struct box *box,
+ struct box *block,
+ int viewport_height,
+ int *max_pos_margin,
+ int *max_neg_margin)
{
- bool auto_width = false;
-
- /* Increase specified left/right margins */
- if (box->margin[LEFT] != AUTO && box->margin[LEFT] < lm &&
- box->margin[LEFT] >= 0)
- box->margin[LEFT] = lm;
- if (box->margin[RIGHT] != AUTO && box->margin[RIGHT] < rm &&
- box->margin[RIGHT] >= 0)
- box->margin[RIGHT] = rm;
-
- /* Find width */
- if (width == AUTO) {
- /* any other 'auto' become 0 or the minimum required values */
- if (box->margin[LEFT] == AUTO)
- box->margin[LEFT] = lm;
- if (box->margin[RIGHT] == AUTO)
- box->margin[RIGHT] = rm;
-
- width = available_width -
- (box->margin[LEFT] + box->border[LEFT].width +
- box->padding[LEFT] + box->padding[RIGHT] +
- box->border[RIGHT].width + box->margin[RIGHT]);
- width = width < 0 ? 0 : width;
- auto_width = true;
- }
+ assert(block != NULL);
- if (max_width >= 0 && width > max_width) {
- /* max-width is admissable and width exceeds max-width */
- width = max_width;
- auto_width = false;
- }
+ while (box != NULL) {
- if (min_width > 0 && width < min_width) {
- /* min-width is admissable and width is less than max-width */
- width = min_width;
- auto_width = false;
- }
+ if (box->type == BOX_INLINE_CONTAINER || (box->style &&
+ (css_computed_position(box->style) !=
+ CSS_POSITION_ABSOLUTE &&
+ css_computed_position(box->style) !=
+ CSS_POSITION_FIXED))) {
+ /* Not positioned */
- /* Width was auto, and unconstrained by min/max width, so we're done */
- if (auto_width)
- return width;
+ /* Get margins */
+ if (box->style) {
+ layout_find_dimensions(box->parent->width,
+ viewport_height, box,
+ box->style,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, box->margin,
+ box->padding, box->border);
- /* Width was not auto, or was constrained by min/max width
- * Need to compute left/right margins */
+ /* Apply top margin */
+ if (*max_pos_margin < box->margin[TOP])
+ *max_pos_margin = box->margin[TOP];
+ else if (*max_neg_margin < -box->margin[TOP])
+ *max_neg_margin = -box->margin[TOP];
+ }
- /* HTML alignment (only applies to over-constrained boxes) */
- if (box->margin[LEFT] != AUTO && box->margin[RIGHT] != AUTO &&
- box->parent != NULL && box->parent->style != NULL) {
- switch (css_computed_text_align(box->parent->style)) {
- case CSS_TEXT_ALIGN_LIBCSS_RIGHT:
- box->margin[LEFT] = AUTO;
- box->margin[RIGHT] = 0;
- break;
- case CSS_TEXT_ALIGN_LIBCSS_CENTER:
- box->margin[LEFT] = box->margin[RIGHT] = AUTO;
- break;
- case CSS_TEXT_ALIGN_LIBCSS_LEFT:
- box->margin[LEFT] = 0;
- box->margin[RIGHT] = AUTO;
- break;
- default:
- /* Leave it alone; no HTML alignment */
- break;
+ /* Check whether box is the box current margin collapses
+ * to */
+ if (box->flags & MAKE_HEIGHT ||
+ box->border[TOP].width ||
+ box->padding[TOP] ||
+ (box->style &&
+ css_computed_overflow_y(box->style) !=
+ CSS_OVERFLOW_VISIBLE) ||
+ (box->type == BOX_INLINE_CONTAINER &&
+ box != box->parent->children)) {
+ /* Collapse to this box; return it */
+ return box;
+ }
}
- }
- if (box->margin[LEFT] == AUTO && box->margin[RIGHT] == AUTO) {
- /* make the margins equal, centering the element */
- box->margin[LEFT] = box->margin[RIGHT] =
- (available_width - lm - rm -
- (box->border[LEFT].width + box->padding[LEFT] +
- width + box->padding[RIGHT] +
- box->border[RIGHT].width)) / 2;
- if (box->margin[LEFT] < 0) {
- box->margin[RIGHT] += box->margin[LEFT];
- box->margin[LEFT] = 0;
- }
+ /* Find next box */
+ if (box->type == BOX_BLOCK && !box->object && box->children &&
+ box->style &&
+ css_computed_overflow_y(box->style) ==
+ CSS_OVERFLOW_VISIBLE) {
+ /* Down into children. */
+ box = box->children;
+ } else {
+ if (!box->next) {
+ /* No more siblings:
+ * Go up to first ancestor with a sibling. */
+ do {
+ /* Apply bottom margin */
+ if (*max_pos_margin <
+ box->margin[BOTTOM])
+ *max_pos_margin =
+ box->margin[BOTTOM];
+ else if (*max_neg_margin <
+ -box->margin[BOTTOM])
+ *max_neg_margin =
+ -box->margin[BOTTOM];
- box->margin[LEFT] += lm;
+ box = box->parent;
+ } while (box != block && !box->next);
- } else if (box->margin[LEFT] == AUTO) {
- box->margin[LEFT] = available_width - lm -
+ if (box == block) {
+ /* Margins don't collapse with stuff
+ * outside the block formatting context
+ */
+ return block;
+ }
+ }
+
+ /* Apply bottom margin */
+ if (*max_pos_margin < box->margin[BOTTOM])
+ *max_pos_margin = box->margin[BOTTOM];
+ else if (*max_neg_margin < -box->margin[BOTTOM])
+ *max_neg_margin = -box->margin[BOTTOM];
+
+ /* To next sibling. */
+ box = box->next;
+
+ /* Get margins */
+ if (box->style) {
+ layout_find_dimensions(box->parent->width,
+ viewport_height, box,
+ box->style,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, box->margin,
+ box->padding, box->border);
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+/**
+ * Find y coordinate which clears all floats on left and/or right.
+ *
+ * \param fl first float in float list
+ * \param clear type of clear
+ * \return y coordinate relative to ancestor box for floats
+ */
+static int layout_clear(struct box *fl, enum css_clear_e clear)
+{
+ int y = 0;
+ for (; fl; fl = fl->next_float) {
+ if ((clear == CSS_CLEAR_LEFT || clear == CSS_CLEAR_BOTH) &&
+ fl->type == BOX_FLOAT_LEFT)
+ if (y < fl->y + fl->height)
+ y = fl->y + fl->height;
+ if ((clear == CSS_CLEAR_RIGHT || clear == CSS_CLEAR_BOTH) &&
+ fl->type == BOX_FLOAT_RIGHT)
+ if (y < fl->y + fl->height)
+ y = fl->y + fl->height;
+ }
+ return y;
+}
+
+
+/**
+ * Find left and right edges in a vertical range.
+ *
+ * \param fl first float in float list
+ * \param y0 start of y range to search
+ * \param y1 end of y range to search
+ * \param x0 start left edge, updated to available left edge
+ * \param x1 start right edge, updated to available right edge
+ * \param left returns float on left if present
+ * \param right returns float on right if present
+ */
+static void
+find_sides(struct box *fl,
+ int y0, int y1,
+ int *x0, int *x1,
+ struct box **left,
+ struct box **right)
+{
+ int fy0, fy1, fx0, fx1;
+
+#ifdef LAYOUT_DEBUG
+ LOG("y0 %i, y1 %i, x0 %i, x1 %i", y0, y1, *x0, *x1);
+#endif
+
+ *left = *right = 0;
+ for (; fl; fl = fl->next_float) {
+ fy1 = fl->y + fl->height;
+ if (fy1 < y0) {
+ /* Floats are sorted in order of decreasing bottom pos.
+ * Past here, all floats will be too high to concern us.
+ */
+ return;
+ }
+ fy0 = fl->y;
+ if (y0 < fy1 && fy0 <= y1) {
+ if (fl->type == BOX_FLOAT_LEFT) {
+ fx1 = fl->x + fl->width;
+ if (*x0 < fx1) {
+ *x0 = fx1;
+ *left = fl;
+ }
+ } else {
+ fx0 = fl->x;
+ if (fx0 < *x1) {
+ *x1 = fx0;
+ *right = fl;
+ }
+ }
+ }
+ }
+
+#ifdef LAYOUT_DEBUG
+ LOG("x0 %i, x1 %i, left %p, right %p", *x0, *x1, *left, *right);
+#endif
+}
+
+
+
+
+/**
+ * Solve the width constraint as given in CSS 2.1 section 10.3.3.
+ *
+ * \param box Box to solve constraint for
+ * \param available_width Max width available in pixels
+ * \param width Current box width
+ * \param lm Min left margin required to avoid floats in px.
+ * zero if not applicable
+ * \param rm Min right margin required to avoid floats in px.
+ * zero if not applicable
+ * \param max_width Box max-width ( -ve means no max-width to apply)
+ * \param min_width Box min-width ( <=0 means no min-width to apply)
+ * \return New box width
+ *
+ * \post \a box's left/right margins will be updated.
+ */
+static int
+layout_solve_width(struct box *box,
+ int available_width,
+ int width,
+ int lm,
+ int rm,
+ int max_width,
+ int min_width)
+{
+ bool auto_width = false;
+
+ /* Increase specified left/right margins */
+ if (box->margin[LEFT] != AUTO && box->margin[LEFT] < lm &&
+ box->margin[LEFT] >= 0)
+ box->margin[LEFT] = lm;
+ if (box->margin[RIGHT] != AUTO && box->margin[RIGHT] < rm &&
+ box->margin[RIGHT] >= 0)
+ box->margin[RIGHT] = rm;
+
+ /* Find width */
+ if (width == AUTO) {
+ /* any other 'auto' become 0 or the minimum required values */
+ if (box->margin[LEFT] == AUTO)
+ box->margin[LEFT] = lm;
+ if (box->margin[RIGHT] == AUTO)
+ box->margin[RIGHT] = rm;
+
+ width = available_width -
+ (box->margin[LEFT] + box->border[LEFT].width +
+ box->padding[LEFT] + box->padding[RIGHT] +
+ box->border[RIGHT].width + box->margin[RIGHT]);
+ width = width < 0 ? 0 : width;
+ auto_width = true;
+ }
+
+ if (max_width >= 0 && width > max_width) {
+ /* max-width is admissable and width exceeds max-width */
+ width = max_width;
+ auto_width = false;
+ }
+
+ if (min_width > 0 && width < min_width) {
+ /* min-width is admissable and width is less than max-width */
+ width = min_width;
+ auto_width = false;
+ }
+
+ /* Width was auto, and unconstrained by min/max width, so we're done */
+ if (auto_width)
+ return width;
+
+ /* Width was not auto, or was constrained by min/max width
+ * Need to compute left/right margins */
+
+ /* HTML alignment (only applies to over-constrained boxes) */
+ if (box->margin[LEFT] != AUTO && box->margin[RIGHT] != AUTO &&
+ box->parent != NULL && box->parent->style != NULL) {
+ switch (css_computed_text_align(box->parent->style)) {
+ case CSS_TEXT_ALIGN_LIBCSS_RIGHT:
+ box->margin[LEFT] = AUTO;
+ box->margin[RIGHT] = 0;
+ break;
+ case CSS_TEXT_ALIGN_LIBCSS_CENTER:
+ box->margin[LEFT] = box->margin[RIGHT] = AUTO;
+ break;
+ case CSS_TEXT_ALIGN_LIBCSS_LEFT:
+ box->margin[LEFT] = 0;
+ box->margin[RIGHT] = AUTO;
+ break;
+ default:
+ /* Leave it alone; no HTML alignment */
+ break;
+ }
+ }
+
+ if (box->margin[LEFT] == AUTO && box->margin[RIGHT] == AUTO) {
+ /* make the margins equal, centering the element */
+ box->margin[LEFT] = box->margin[RIGHT] =
+ (available_width - lm - rm -
+ (box->border[LEFT].width + box->padding[LEFT] +
+ width + box->padding[RIGHT] +
+ box->border[RIGHT].width)) / 2;
+
+ if (box->margin[LEFT] < 0) {
+ box->margin[RIGHT] += box->margin[LEFT];
+ box->margin[LEFT] = 0;
+ }
+
+ box->margin[LEFT] += lm;
+
+ } else if (box->margin[LEFT] == AUTO) {
+ box->margin[LEFT] = available_width - lm -
(box->border[LEFT].width + box->padding[LEFT] +
width + box->padding[RIGHT] +
box->border[RIGHT].width + box->margin[RIGHT]);
@@ -1465,130 +1601,47 @@ int layout_solve_width(struct box *box, int available_width, int width,
/**
- * Compute dimensions of box, margins, paddings, and borders for a floating
- * element using shrink-to-fit. Also used for inline-blocks.
+ * Compute dimensions of box, margins, paddings, and borders for a block-level
+ * element.
*
* \param available_width Max width available in pixels
- * \param style Box's style
- * \param box Box for which to find dimensions
- * Box margins, borders, paddings, width and
- * height are updated.
+ * \param viewport_height Height of viewport in pixels or -ve if unknown
+ * \param lm min left margin required to avoid floats in px.
+ * zero if not applicable
+ * \param rm min right margin required to avoid floats in px.
+ * zero if not applicable
+ * \param box box to find dimensions of. updated with new width,
+ * height, margins, borders and paddings
+ *
+ * See CSS 2.1 10.3.3, 10.3.4, 10.6.2, and 10.6.3.
*/
-
-void layout_float_find_dimensions(int available_width,
- const css_computed_style *style, struct box *box)
+static void
+layout_block_find_dimensions(int available_width,
+ int viewport_height,
+ int lm,
+ int rm,
+ struct box *box)
{
- int width, height, max_width, min_width, max_height, min_height;
+ int width, max_width, min_width;
+ int height, max_height, min_height;
int *margin = box->margin;
int *padding = box->padding;
struct box_border *border = box->border;
- enum css_overflow_e overflow_x = css_computed_overflow_x(style);
- enum css_overflow_e overflow_y = css_computed_overflow_y(style);
- int scrollbar_width_x =
- (overflow_x == CSS_OVERFLOW_SCROLL ||
- overflow_x == CSS_OVERFLOW_AUTO) ?
- SCROLLBAR_WIDTH : 0;
- int scrollbar_width_y =
- (overflow_y == CSS_OVERFLOW_SCROLL ||
- overflow_y == CSS_OVERFLOW_AUTO) ?
- SCROLLBAR_WIDTH : 0;
-
- layout_find_dimensions(available_width, -1, box, style, &width, &height,
- &max_width, &min_width, &max_height, &min_height,
- margin, padding, border);
-
- if (margin[LEFT] == AUTO)
- margin[LEFT] = 0;
- if (margin[RIGHT] == AUTO)
- margin[RIGHT] = 0;
+ const css_computed_style *style = box->style;
- if (box->gadget == NULL) {
- padding[RIGHT] += scrollbar_width_y;
- padding[BOTTOM] += scrollbar_width_x;
- }
+ layout_find_dimensions(available_width, viewport_height, box, style,
+ &width, &height, &max_width, &min_width,
+ &max_height, &min_height, margin, padding, border);
if (box->object && !(box->flags & REPLACE_DIM) &&
content_get_type(box->object) != CONTENT_HTML) {
- /* Floating replaced element, with intrinsic width or height.
- * See 10.3.6 and 10.6.2 */
+ /* block-level replaced element, see 10.3.4 and 10.6.2 */
layout_get_object_dimensions(box, &width, &height,
min_width, max_width, min_height, max_height);
- } else if (box->gadget && (box->gadget->type == GADGET_TEXTBOX ||
- box->gadget->type == GADGET_PASSWORD ||
- box->gadget->type == GADGET_FILE ||
- box->gadget->type == GADGET_TEXTAREA)) {
- css_fixed size = 0;
- css_unit unit = CSS_UNIT_EM;
-
- /* Give sensible dimensions to gadgets, with auto width/height,
- * that don't shrink to fit contained text. */
- assert(box->style);
-
- if (box->gadget->type == GADGET_TEXTBOX ||
- box->gadget->type == GADGET_PASSWORD ||
- box->gadget->type == GADGET_FILE) {
- if (width == AUTO) {
- size = INTTOFIX(10);
- width = FIXTOINT(nscss_len2px(size, unit,
- box->style));
- }
- if (box->gadget->type == GADGET_FILE &&
- height == AUTO) {
- size = FLTTOFIX(1.5);
- height = FIXTOINT(nscss_len2px(size, unit,
- box->style));
- }
- }
- if (box->gadget->type == GADGET_TEXTAREA) {
- if (width == AUTO) {
- size = INTTOFIX(10);
- width = FIXTOINT(nscss_len2px(size, unit,
- box->style));
- }
- if (height == AUTO) {
- size = INTTOFIX(4);
- height = FIXTOINT(nscss_len2px(size, unit,
- box->style));
- }
- }
- } else if (width == AUTO) {
- /* CSS 2.1 section 10.3.5 */
- width = min(max(box->min_width, available_width),
- box->max_width);
-
- /* width includes margin, borders and padding */
- if (width == available_width) {
- width -= box->margin[LEFT] + box->border[LEFT].width +
- box->padding[LEFT] +
- box->padding[RIGHT] +
- box->border[RIGHT].width +
- box->margin[RIGHT];
- } else {
- /* width was obtained from a min_width or max_width
- * value, so need to use the same method for calculating
- * mbp as was used in layout_minmax_block() */
- int fixed = 0;
- float frac = 0;
- calculate_mbp_width(box->style, LEFT, true, true, true,
- &fixed, &frac);
- calculate_mbp_width(box->style, RIGHT, true, true, true,
- &fixed, &frac);
- if (fixed < 0)
- fixed = 0;
-
- width -= fixed;
- }
-
- if (max_width >= 0 && width > max_width) width = max_width;
- if (min_width > 0 && width < min_width) width = min_width;
-
- } else {
- if (max_width >= 0 && width > max_width) width = max_width;
- if (min_width > 0 && width < min_width) width = min_width;
- width -= scrollbar_width_y;
}
- box->width = width;
+ box->width = layout_solve_width(box, available_width, width, lm, rm,
+ max_width, min_width);
box->height = height;
if (margin[TOP] == AUTO)
@@ -1599,3464 +1652,3363 @@ void layout_float_find_dimensions(int available_width,
/**
- * Calculate width, height, and thickness of margins, paddings, and borders.
+ * Manipulate a block's [RB]padding/height/width to accommodate scrollbars
*
- * \param available_width width of containing block
- * \param viewport_height height of viewport in pixels or -ve if unknown
- * \param box current box
- * \param style style giving width, height, margins, paddings,
- * and borders
- * \param width updated to width, may be NULL
- * \param height updated to height, may be NULL
- * \param max_width updated to max-width, may be NULL
- * \param min_width updated to min-width, may be NULL
- * \param max_height updated to max-height, may be NULL
- * \param min_height updated to min-height, may be NULL
- * \param margin filled with margins, may be NULL
- * \param padding filled with paddings, may be NULL
- * \param border filled with border widths, may be NULL
+ * \param box Box to apply scrollbar space too. Must be BOX_BLOCK.
+ * \param which Which scrollbar to make space for. Must be RIGHT or BOTTOM.
*/
-
-void layout_find_dimensions(int available_width, int viewport_height,
- struct box *box, const css_computed_style *style,
- int *width, int *height, int *max_width, int *min_width,
- int *max_height, int *min_height, int margin[4], int padding[4],
- struct box_border border[4])
+static void layout_block_add_scrollbar(struct box *box, int which)
{
- struct box *containing_block = NULL;
- unsigned int i;
- bool percentage;
+ enum css_overflow_e overflow_x, overflow_y;
- if (width) {
- enum css_width_e wtype;
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
+ assert(box->type == BOX_BLOCK && (which == RIGHT || which == BOTTOM));
- wtype = css_computed_width(style, &value, &unit);
+ if (box->style == NULL)
+ return;
- if (wtype == CSS_WIDTH_SET) {
- if (unit == CSS_UNIT_PCT) {
- *width = FPCT_OF_INT_TOINT(
- value, available_width);
- } else {
- *width = FIXTOINT(nscss_len2px(value, unit,
- style));
- }
- } else {
- *width = AUTO;
+ overflow_x = css_computed_overflow_x(box->style);
+ overflow_y = css_computed_overflow_y(box->style);
+
+ if (which == BOTTOM &&
+ (overflow_x == CSS_OVERFLOW_SCROLL ||
+ overflow_x == CSS_OVERFLOW_AUTO ||
+ (box->object &&
+ content_get_type(box->object) == CONTENT_HTML))) {
+ /* make space for scrollbar, unless height is AUTO */
+ if (box->height != AUTO &&
+ (overflow_x == CSS_OVERFLOW_SCROLL ||
+ box_hscrollbar_present(box))) {
+ box->padding[BOTTOM] += SCROLLBAR_WIDTH;
}
- /* specified gadget widths include borders and padding in some
- * cases */
- if (box->gadget && *width != AUTO) {
- percentage = unit == CSS_UNIT_PCT;
+ } else if (which == RIGHT &&
+ (overflow_y == CSS_OVERFLOW_SCROLL ||
+ overflow_y == CSS_OVERFLOW_AUTO ||
+ (box->object &&
+ content_get_type(box->object) == CONTENT_HTML))) {
+ /* make space for scrollbars, unless width is AUTO */
+ enum css_height_e htype;
+ css_fixed height = 0;
+ css_unit hunit = CSS_UNIT_PX;
+ htype = css_computed_height(box->style, &height, &hunit);
- layout_tweak_form_dimensions(box, percentage,
- available_width, true, width);
+ if (which == RIGHT && box->width != AUTO &&
+ htype == CSS_HEIGHT_SET &&
+ (overflow_y == CSS_OVERFLOW_SCROLL ||
+ box_vscrollbar_present(box))) {
+ box->width -= SCROLLBAR_WIDTH;
+ box->padding[RIGHT] += SCROLLBAR_WIDTH;
}
}
+}
- if (height) {
- enum css_height_e htype;
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
-
- htype = css_computed_height(style, &value, &unit);
- if (htype == CSS_HEIGHT_SET) {
- if (unit == CSS_UNIT_PCT) {
- enum css_height_e cbhtype;
+/**
+ * Moves the children of a box by a specified amount
+ *
+ * \param box top of tree of boxes
+ * \param x the amount to move children by horizontally
+ * \param y the amount to move children by vertically
+ */
+static void layout_move_children(struct box *box, int x, int y)
+{
+ assert(box);
- if (css_computed_position(box->style) ==
- CSS_POSITION_ABSOLUTE &&
- box->parent) {
- /* Box is absolutely positioned */
- assert(box->float_container);
- containing_block = box->float_container;
- } else if (box->float_container &&
- css_computed_position(box->style) !=
- CSS_POSITION_ABSOLUTE &&
- (css_computed_float(box->style) ==
- CSS_FLOAT_LEFT ||
- css_computed_float(box->style) ==
- CSS_FLOAT_RIGHT)) {
- /* Box is a float */
- assert(box->parent &&
- box->parent->parent &&
- box->parent->parent->parent);
+ for (box = box->children; box; box = box->next) {
+ box->x += x;
+ box->y += y;
+ }
+}
- containing_block =
- box->parent->parent->parent;
- } else if (box->parent && box->parent->type !=
- BOX_INLINE_CONTAINER) {
- /* Box is a block level element */
- containing_block = box->parent;
- } else if (box->parent && box->parent->type ==
- BOX_INLINE_CONTAINER) {
- /* Box is an inline block */
- assert(box->parent->parent);
- containing_block = box->parent->parent;
- }
- if (containing_block) {
- css_fixed f = 0;
- css_unit u = CSS_UNIT_PX;
+/**
+ * Layout a table.
+ *
+ * \param table table to layout
+ * \param available_width width of containing block
+ * \param content memory pool for any new boxes
+ * \return true on success, false on memory exhaustion
+ */
+static bool layout_table(struct box *table, int available_width,
+ html_content *content)
+{
+ unsigned int columns = table->columns; /* total columns */
+ unsigned int i;
+ unsigned int *row_span;
+ int *excess_y;
+ int table_width, min_width = 0, max_width = 0;
+ int required_width = 0;
+ int x, remainder = 0, count = 0;
+ int table_height = 0;
+ int min_height = 0;
+ int *xs; /* array of column x positions */
+ int auto_width;
+ int spare_width;
+ int relative_sum = 0;
+ int border_spacing_h = 0, border_spacing_v = 0;
+ int spare_height;
+ int positioned_columns = 0;
+ struct box *containing_block = NULL;
+ struct box *c;
+ struct box *row;
+ struct box *row_group;
+ struct box **row_span_cell;
+ struct column *col;
+ const css_computed_style *style = table->style;
+ enum css_width_e wtype;
+ enum css_height_e htype;
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
- cbhtype = css_computed_height(
- containing_block->style,
- &f, &u);
- }
+ assert(table->type == BOX_TABLE);
+ assert(style);
+ assert(table->children && table->children->children);
+ assert(columns);
- if (containing_block &&
- containing_block->height != AUTO &&
- (css_computed_position(box->style) ==
- CSS_POSITION_ABSOLUTE ||
- cbhtype == CSS_HEIGHT_SET)) {
- /* Box is absolutely positioned or its
- * containing block has a valid
- * specified height.
- * (CSS 2.1 Section 10.5) */
- *height = FPCT_OF_INT_TOINT(value,
- containing_block->height);
- } else if ((!box->parent ||
- !box->parent->parent) &&
- viewport_height >= 0) {
- /* If root element or it's child
- * (HTML or BODY) */
- *height = FPCT_OF_INT_TOINT(value,
- viewport_height);
- } else {
- /* precentage height not permissible
- * treat height as auto */
- *height = AUTO;
- }
- } else {
- *height = FIXTOINT(nscss_len2px(value, unit,
- style));
- }
- } else {
- *height = AUTO;
- }
-
- /* specified gadget heights include borders and padding in
- * some cases */
- if (box->gadget && *height != AUTO) {
- percentage = unit == CSS_UNIT_PCT;
-
- layout_tweak_form_dimensions(box, percentage,
- available_width, false, height);
- }
+ /* allocate working buffers */
+ col = malloc(columns * sizeof col[0]);
+ excess_y = malloc(columns * sizeof excess_y[0]);
+ row_span = malloc(columns * sizeof row_span[0]);
+ row_span_cell = malloc(columns * sizeof row_span_cell[0]);
+ xs = malloc((columns + 1) * sizeof xs[0]);
+ if (!col || !xs || !row_span || !excess_y || !row_span_cell) {
+ free(col);
+ free(excess_y);
+ free(row_span);
+ free(row_span_cell);
+ free(xs);
+ return false;
}
- if (max_width) {
- enum css_max_width_e type;
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
+ memcpy(col, table->col, sizeof(col[0]) * columns);
- type = css_computed_max_width(style, &value, &unit);
+ /* find margins, paddings, and borders for table and cells */
+ layout_find_dimensions(available_width, -1, table, style, 0, 0, 0, 0,
+ 0, 0, table->margin, table->padding, table->border);
+ for (row_group = table->children; row_group;
+ row_group = row_group->next) {
+ for (row = row_group->children; row; row = row->next) {
+ for (c = row->children; c; c = c->next) {
+ enum css_overflow_e overflow_x;
+ enum css_overflow_e overflow_y;
- if (type == CSS_MAX_WIDTH_SET) {
- if (unit == CSS_UNIT_PCT) {
- *max_width = FPCT_OF_INT_TOINT(value,
- available_width);
- } else {
- *max_width = FIXTOINT(nscss_len2px(value, unit,
- style));
- }
- } else {
- /* Inadmissible */
- *max_width = -1;
- }
+ assert(c->style);
+ table_used_border_for_cell(c);
+ layout_find_dimensions(available_width, -1,
+ c, c->style, 0, 0, 0, 0, 0, 0,
+ 0, c->padding, c->border);
- /* specified gadget widths include borders and padding in some
- * cases */
- if (box->gadget && *max_width != -1) {
- percentage = unit == CSS_UNIT_PCT;
+ overflow_x = css_computed_overflow_x(c->style);
+ overflow_y = css_computed_overflow_y(c->style);
- layout_tweak_form_dimensions(box, percentage,
- available_width, true, max_width);
+ if (overflow_x == CSS_OVERFLOW_SCROLL ||
+ overflow_x ==
+ CSS_OVERFLOW_AUTO) {
+ c->padding[BOTTOM] += SCROLLBAR_WIDTH;
+ }
+ if (overflow_y == CSS_OVERFLOW_SCROLL ||
+ overflow_y ==
+ CSS_OVERFLOW_AUTO) {
+ c->padding[RIGHT] += SCROLLBAR_WIDTH;
+ }
+ }
}
}
- if (min_width) {
- enum css_min_width_e type;
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
+ /* border-spacing is used in the separated borders model */
+ if (css_computed_border_collapse(style) ==
+ CSS_BORDER_COLLAPSE_SEPARATE) {
+ css_fixed h = 0, v = 0;
+ css_unit hu = CSS_UNIT_PX, vu = CSS_UNIT_PX;
- type = css_computed_min_width(style, &value, &unit);
+ css_computed_border_spacing(style, &h, &hu, &v, &vu);
- if (type == CSS_MIN_WIDTH_SET) {
- if (unit == CSS_UNIT_PCT) {
- *min_width = FPCT_OF_INT_TOINT(value,
- available_width);
- } else {
- *min_width = FIXTOINT(nscss_len2px(value, unit,
- style));
- }
+ border_spacing_h = FIXTOINT(nscss_len2px(h, hu, style));
+ border_spacing_v = FIXTOINT(nscss_len2px(v, vu, style));
+ }
+
+ /* find specified table width, or available width if auto-width */
+ wtype = css_computed_width(style, &value, &unit);
+ if (wtype == CSS_WIDTH_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ table_width = FPCT_OF_INT_TOINT(value, available_width);
} else {
- /* Inadmissible */
- *min_width = 0;
+ table_width =
+ FIXTOINT(nscss_len2px(value, unit, style));
}
- /* specified gadget widths include borders and padding in some
- * cases */
- if (box->gadget && *min_width != 0) {
- percentage = unit == CSS_UNIT_PCT;
+ /* specified width includes border */
+ table_width -= table->border[LEFT].width +
+ table->border[RIGHT].width;
+ table_width = table_width < 0 ? 0 : table_width;
- layout_tweak_form_dimensions(box, percentage,
- available_width, true, min_width);
- }
+ auto_width = table_width;
+ } else {
+ table_width = AUTO;
+ auto_width = available_width -
+ ((table->margin[LEFT] == AUTO ? 0 :
+ table->margin[LEFT]) +
+ table->border[LEFT].width +
+ table->padding[LEFT] +
+ table->padding[RIGHT] +
+ table->border[RIGHT].width +
+ (table->margin[RIGHT] == AUTO ? 0 :
+ table->margin[RIGHT]));
}
- if (max_height) {
- enum css_max_height_e type;
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
-
- type = css_computed_max_height(style, &value, &unit);
-
- if (type == CSS_MAX_HEIGHT_SET) {
- if (unit == CSS_UNIT_PCT) {
- /* TODO: handle percentage */
- *max_height = -1;
- } else {
- *max_height = FIXTOINT(nscss_len2px(value, unit,
- style));
+ /* Find any table height specified within CSS/HTML */
+ htype = css_computed_height(style, &value, &unit);
+ if (htype == CSS_HEIGHT_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ /* This is the minimum height for the table
+ * (see 17.5.3) */
+ if (css_computed_position(table->style) ==
+ CSS_POSITION_ABSOLUTE) {
+ /* Table is absolutely positioned */
+ assert(table->float_container);
+ containing_block = table->float_container;
+ } else if (table->float_container &&
+ css_computed_position(table->style) !=
+ CSS_POSITION_ABSOLUTE &&
+ (css_computed_float(table->style) ==
+ CSS_FLOAT_LEFT ||
+ css_computed_float(table->style) ==
+ CSS_FLOAT_RIGHT)) {
+ /* Table is a float */
+ assert(table->parent && table->parent->parent &&
+ table->parent->parent->parent);
+ containing_block =
+ table->parent->parent->parent;
+ } else if (table->parent && table->parent->type !=
+ BOX_INLINE_CONTAINER) {
+ /* Table is a block level element */
+ containing_block = table->parent;
+ } else if (table->parent && table->parent->type ==
+ BOX_INLINE_CONTAINER) {
+ /* Table is an inline block */
+ assert(table->parent->parent);
+ containing_block = table->parent->parent;
}
- } else {
- /* Inadmissible */
- *max_height = -1;
- }
- }
- if (min_height) {
- enum css_min_height_e type;
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
+ if (containing_block) {
+ css_fixed ignored = 0;
- type = css_computed_min_height(style, &value, &unit);
+ htype = css_computed_height(
+ containing_block->style,
+ &ignored, &unit);
+ }
- if (type == CSS_MIN_HEIGHT_SET) {
- if (unit == CSS_UNIT_PCT) {
- /* TODO: handle percentage */
- *min_height = 0;
- } else {
- *min_height = FIXTOINT(nscss_len2px(value, unit,
- style));
+ if (containing_block &&
+ containing_block->height != AUTO &&
+ (css_computed_position(table->style) ==
+ CSS_POSITION_ABSOLUTE ||
+ htype == CSS_HEIGHT_SET)) {
+ /* Table is absolutely positioned or its
+ * containing block has a valid specified
+ * height. (CSS 2.1 Section 10.5) */
+ min_height = FPCT_OF_INT_TOINT(value,
+ containing_block->height);
}
} else {
- /* Inadmissible */
- *min_height = 0;
+ /* This is the minimum height for the table
+ * (see 17.5.3) */
+ min_height = FIXTOINT(nscss_len2px(value, unit, style));
}
}
- for (i = 0; i != 4; i++) {
- if (margin) {
- enum css_margin_e type = CSS_MARGIN_AUTO;
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
-
- switch (i) {
- case TOP:
- type = css_computed_margin_top(style,
- &value, &unit);
- break;
- case RIGHT:
- type = css_computed_margin_right(style,
- &value, &unit);
- break;
- case BOTTOM:
- type = css_computed_margin_bottom(style,
- &value, &unit);
- break;
- case LEFT:
- type = css_computed_margin_left(style,
- &value, &unit);
- break;
- }
-
- if (type == CSS_MARGIN_SET) {
- if (unit == CSS_UNIT_PCT) {
- margin[i] = FPCT_OF_INT_TOINT(value,
- available_width);
- } else {
- margin[i] = FIXTOINT(nscss_len2px(value,
- unit, style));
- }
- } else {
- margin[i] = AUTO;
- }
- }
-
- if (padding) {
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
-
- switch (i) {
- case TOP:
- css_computed_padding_top(style, &value, &unit);
- break;
- case RIGHT:
- css_computed_padding_right(style, &value,
- &unit);
- break;
- case BOTTOM:
- css_computed_padding_bottom(style, &value,
- &unit);
- break;
- case LEFT:
- css_computed_padding_left(style, &value, &unit);
- break;
- }
-
- if (unit == CSS_UNIT_PCT) {
- padding[i] = FPCT_OF_INT_TOINT(value,
- available_width);
- } else {
- padding[i] = FIXTOINT(nscss_len2px(value, unit,
- style));
- }
- }
-
- /* Table cell borders are populated in table.c */
- if (border && box->type != BOX_TABLE_CELL) {
- enum css_border_style_e bstyle = CSS_BORDER_STYLE_NONE;
- css_color color = 0;
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
-
- switch (i) {
- case TOP:
- css_computed_border_top_width(style, &value,
- &unit);
- bstyle = css_computed_border_top_style(style);
- css_computed_border_top_color(style, &color);
- break;
- case RIGHT:
- css_computed_border_right_width(style, &value,
- &unit);
- bstyle = css_computed_border_right_style(style);
- css_computed_border_right_color(style, &color);
- break;
- case BOTTOM:
- css_computed_border_bottom_width(style, &value,
- &unit);
- bstyle = css_computed_border_bottom_style(
- style);
- css_computed_border_bottom_color(style, &color);
- break;
- case LEFT:
- css_computed_border_left_width(style, &value,
- &unit);
- bstyle = css_computed_border_left_style(style);
- css_computed_border_left_color(style, &color);
- break;
- }
-
- border[i].style = bstyle;
- border[i].c = color;
-
- if (bstyle == CSS_BORDER_STYLE_HIDDEN ||
- bstyle == CSS_BORDER_STYLE_NONE)
- /* spec unclear: following Mozilla */
- border[i].width = 0;
- else
- border[i].width = FIXTOINT(nscss_len2px(value,
- unit, style));
-
- /* Special case for border-collapse: make all borders
- * on table/table-row-group/table-row zero width. */
- if (css_computed_border_collapse(style) ==
- CSS_BORDER_COLLAPSE_COLLAPSE &&
- (box->type == BOX_TABLE ||
- box->type == BOX_TABLE_ROW_GROUP ||
- box->type == BOX_TABLE_ROW))
- border[i].width = 0;
- }
- }
-}
-
-
-/**
- * Under some circumstances, specified dimensions for form elements include
- * borders and padding.
- *
- * \param box gadget to adjust dimensions of
- * \param percentage whether the gadget has its dimension specified as a
- * percentage
- * \param available_width width of containing block
- * \param setwidth set true if the dimension to be tweaked is a width,
- * else set false for a height
- * \param dimension current value for given width/height dimension.
- * updated to new value after consideration of
- * gadget properties.
- */
-
-void layout_tweak_form_dimensions(struct box *box, bool percentage,
- int available_width, bool setwidth, int *dimension)
-{
- int fixed = 0;
- float frac = 0;
-
- assert(box && box->gadget);
-
- /* specified gadget widths include borders and padding in some
- * cases */
- if (percentage || box->gadget->type == GADGET_SUBMIT ||
- box->gadget->type == GADGET_RESET ||
- box->gadget->type == GADGET_BUTTON) {
- calculate_mbp_width(box->style, setwidth ? LEFT : TOP,
- false, true, true, &fixed, &frac);
- calculate_mbp_width(box->style, setwidth ? RIGHT : BOTTOM,
- false, true, true, &fixed, &frac);
- *dimension -= frac * available_width + fixed;
- *dimension = *dimension > 0 ? *dimension : 0;
- }
-}
-
-
-/**
- * Find y coordinate which clears all floats on left and/or right.
- *
- * \param fl first float in float list
- * \param clear type of clear
- * \return y coordinate relative to ancestor box for floats
- */
-
-int layout_clear(struct box *fl, enum css_clear_e clear)
-{
- int y = 0;
- for (; fl; fl = fl->next_float) {
- if ((clear == CSS_CLEAR_LEFT || clear == CSS_CLEAR_BOTH) &&
- fl->type == BOX_FLOAT_LEFT)
- if (y < fl->y + fl->height)
- y = fl->y + fl->height;
- if ((clear == CSS_CLEAR_RIGHT || clear == CSS_CLEAR_BOTH) &&
- fl->type == BOX_FLOAT_RIGHT)
- if (y < fl->y + fl->height)
- y = fl->y + fl->height;
- }
- return y;
-}
-
-
-/**
- * Find left and right edges in a vertical range.
- *
- * \param fl first float in float list
- * \param y0 start of y range to search
- * \param y1 end of y range to search
- * \param x0 start left edge, updated to available left edge
- * \param x1 start right edge, updated to available right edge
- * \param left returns float on left if present
- * \param right returns float on right if present
- */
-
-void find_sides(struct box *fl, int y0, int y1,
- int *x0, int *x1, struct box **left, struct box **right)
-{
- int fy0, fy1, fx0, fx1;
-
-#ifdef LAYOUT_DEBUG
- LOG("y0 %i, y1 %i, x0 %i, x1 %i", y0, y1, *x0, *x1);
-#endif
-
- *left = *right = 0;
- for (; fl; fl = fl->next_float) {
- fy1 = fl->y + fl->height;
- if (fy1 < y0) {
- /* Floats are sorted in order of decreasing bottom pos.
- * Past here, all floats will be too high to concern us.
- */
- return;
- }
- fy0 = fl->y;
- if (y0 < fy1 && fy0 <= y1) {
- if (fl->type == BOX_FLOAT_LEFT) {
- fx1 = fl->x + fl->width;
- if (*x0 < fx1) {
- *x0 = fx1;
- *left = fl;
- }
- } else {
- fx0 = fl->x;
- if (fx0 < *x1) {
- *x1 = fx0;
- *right = fl;
- }
- }
- }
- }
-
-#ifdef LAYOUT_DEBUG
- LOG("x0 %i, x1 %i, left %p, right %p", *x0, *x1, *left, *right);
-#endif
-}
-
-
-/**
- * Insert a float into a container.
- *
- * \param cont block formatting context block, used to contain float
- * \param b box to add to float
- *
- * This sorts floats in order of descending bottom edges.
- */
-static void add_float_to_container(struct box *cont, struct box *b)
-{
- struct box *box = cont->float_children;
- int b_bottom = b->y + b->height;
-
- assert(b->type == BOX_FLOAT_LEFT || b->type == BOX_FLOAT_RIGHT);
-
- if (box == NULL) {
- /* No other float children */
- b->next_float = NULL;
- cont->float_children = b;
- return;
- } else if (b_bottom >= box->y + box->height) {
- /* Goes at start of list */
- b->next_float = cont->float_children;
- cont->float_children = b;
- } else {
- struct box *prev = NULL;
- while (box != NULL && b_bottom < box->y + box->height) {
- prev = box;
- box = box->next_float;
- }
- if (prev != NULL) {
- b->next_float = prev->next_float;
- prev->next_float = b;
- }
- }
-}
-
-
-/**
- * Layout lines of text or inline boxes with floats.
- *
- * \param inline_container inline container box
- * \param width horizontal space available
- * \param cont ancestor box which defines horizontal space, for floats
- * \param cx box position relative to cont
- * \param cy box position relative to cont
- * \param content memory pool for any new boxes
- * \return true on success, false on memory exhaustion
- */
-
-bool layout_inline_container(struct box *inline_container, int width,
- struct box *cont, int cx, int cy, html_content *content)
-{
- bool first_line = true;
- bool has_text_children;
- struct box *c, *next;
- int y = 0;
- int curwidth,maxwidth = width;
-
- assert(inline_container->type == BOX_INLINE_CONTAINER);
-
-#ifdef LAYOUT_DEBUG
- LOG("inline_container %p, width %i, cont %p, cx %i, cy %i", inline_container, width, cont, cx, cy);
-#endif
-
- has_text_children = false;
- for (c = inline_container->children; c; c = c->next) {
- bool is_pre = false;
-
- if (c->style) {
- enum css_white_space_e whitespace;
-
- whitespace = css_computed_white_space(c->style);
-
- is_pre = (whitespace == CSS_WHITE_SPACE_PRE ||
- whitespace == CSS_WHITE_SPACE_PRE_LINE ||
- whitespace == CSS_WHITE_SPACE_PRE_WRAP);
- }
-
- if ((!c->object && !(c->flags & REPLACE_DIM) &&
- !(c->flags & IFRAME) &&
- c->text && (c->length || is_pre)) ||
- c->type == BOX_BR)
- has_text_children = true;
- }
-
- /** \todo fix wrapping so that a box with horizontal scrollbar will
- * shrink back to 'width' if no word is wider than 'width' (Or just set
- * curwidth = width and have the multiword lines wrap to the min width)
- */
- for (c = inline_container->children; c; ) {
-#ifdef LAYOUT_DEBUG
- LOG("c %p", c);
-#endif
- curwidth = inline_container->width;
- if (!layout_line(c, &curwidth, &y, cx, cy + y, cont, first_line,
- has_text_children, content, &next))
- return false;
- maxwidth = max(maxwidth,curwidth);
- c = next;
- first_line = false;
- }
-
- inline_container->width = maxwidth;
- inline_container->height = y;
-
- return true;
-}
-
-
-/**
- * Calculate minimum and maximum width of an inline container.
- *
- * \param inline_container box of type INLINE_CONTAINER
- * \param[out] has_height set to true if container has height
- * \param font_func Font functions.
- * \post inline_container->min_width and inline_container->max_width filled in,
- * 0 <= inline_container->min_width <= inline_container->max_width
- */
-
-void layout_minmax_inline_container(struct box *inline_container,
- bool *has_height, const struct font_functions *font_func)
-{
- struct box *child;
- int line_min = 0, line_max = 0;
- int min = 0, max = 0;
- bool first_line = true;
- bool line_has_height;
-
- assert(inline_container->type == BOX_INLINE_CONTAINER);
-
- /* check if the widths have already been calculated */
- if (inline_container->max_width != UNKNOWN_MAX_WIDTH)
- return;
-
- *has_height = false;
-
- for (child = inline_container->children; child; ) {
- child = layout_minmax_line(child, &line_min, &line_max,
- first_line, &line_has_height, font_func);
- if (min < line_min)
- min = line_min;
- if (max < line_max)
- max = line_max;
- first_line = false;
- *has_height |= line_has_height;
- }
-
- inline_container->min_width = min;
- inline_container->max_width = max;
-
- assert(0 <= inline_container->min_width &&
- inline_container->min_width <=
- inline_container->max_width);
-}
-
-
-/**
- * Calculate line height from a style.
- */
-
-int line_height(const css_computed_style *style)
-{
- enum css_line_height_e lhtype;
- css_fixed lhvalue = 0;
- css_unit lhunit = CSS_UNIT_PX;
- css_fixed line_height;
-
- assert(style);
-
- lhtype = css_computed_line_height(style, &lhvalue, &lhunit);
- if (lhtype == CSS_LINE_HEIGHT_NORMAL) {
- /* Normal => use a constant of 1.3 * font-size */
- lhvalue = FLTTOFIX(1.3);
- lhtype = CSS_LINE_HEIGHT_NUMBER;
- }
-
- if (lhtype == CSS_LINE_HEIGHT_NUMBER ||
- lhunit == CSS_UNIT_PCT) {
- line_height = nscss_len2px(lhvalue, CSS_UNIT_EM, style);
-
- if (lhtype != CSS_LINE_HEIGHT_NUMBER)
- line_height = FDIV(line_height, F_100);
- } else {
- assert(lhunit != CSS_UNIT_PCT);
-
- line_height = nscss_len2px(lhvalue, lhunit, style);
- }
-
- return FIXTOINT(line_height);
-}
-
-
-/**
- * Split a text box.
- *
- * \param content memory pool for any new boxes
- * \param fstyle style for text in text box
- * \param split_box box with text to split
- * \param new_length new length for text in split_box, after splitting
- * \param new_width new width for text in split_box, after splitting
- * \return true on success, false on memory exhaustion
- *
- * A new box is created and inserted into the box tree after split_box,
- * containing the text after new_length excluding the initial space character.
- */
-
-static bool layout_text_box_split(html_content *content,
- plot_font_style_t *fstyle, struct box *split_box,
- size_t new_length, int new_width)
-{
- int space_width = split_box->space;
- struct box *c2;
- const struct font_functions *font_func = content->font_func;
- bool space = (split_box->text[new_length] == ' ');
- int used_length = new_length + (space ? 1 : 0);
-
- if ((space && space_width == 0) || space_width == UNKNOWN_WIDTH) {
- /* We're need to add a space, and we don't know how big
- * it's to be, OR we have a space of unknown width anyway;
- * Calculate space width */
- font_func->font_width(fstyle, " ", 1, &space_width);
- }
-
- if (split_box->space == UNKNOWN_WIDTH)
- split_box->space = space_width;
- if (!space)
- space_width = 0;
-
- /* Create clone of split_box, c2 */
- c2 = talloc_memdup(content->bctx, split_box, sizeof *c2);
- if (!c2)
- return false;
- c2->flags |= CLONE;
-
- /* Set remaining text in c2 */
- c2->text += used_length;
-
- /* Set c2 according to the remaining text */
- c2->width -= new_width + space_width;
- c2->flags &= ~MEASURED; /* width has been estimated */
- c2->length = split_box->length - used_length;
-
- /* Update split_box for its reduced text */
- split_box->width = new_width;
- split_box->flags |= MEASURED;
- split_box->length = new_length;
- split_box->space = space_width;
-
- /* Insert c2 into box list */
- c2->next = split_box->next;
- split_box->next = c2;
- c2->prev = split_box;
- if (c2->next)
- c2->next->prev = c2;
- else
- c2->parent->last = c2;
-#ifdef LAYOUT_DEBUG
- LOG("split_box %p len: %u \"%.*s\"", split_box, split_box->length, split_box->length, split_box->text);
- LOG(" new_box %p len: %u \"%.*s\"", c2, c2->length, c2->length, c2->text);
-#endif
- return true;
-}
-
-
-/**
- * Position a line of boxes in inline formatting context.
- *
- * \param first box at start of line
- * \param width available width on input, updated with actual width on output
- * (may be incorrect if the line gets split?)
- * \param y coordinate of top of line, updated on exit to bottom
- * \param cx coordinate of left of line relative to cont
- * \param cy coordinate of top of line relative to cont
- * \param cont ancestor box which defines horizontal space, for floats
- * \param indent apply any first-line indent
- * \param has_text_children at least one TEXT in the inline_container
- * \param next_box updated to first box for next line, or 0 at end
- * \param content memory pool for any new boxes
- * \return true on success, false on memory exhaustion
- */
-
-bool layout_line(struct box *first, int *width, int *y,
- int cx, int cy, struct box *cont, bool indent,
- bool has_text_children,
- html_content *content, struct box **next_box)
-{
- int height, used_height;
- int x0 = 0;
- int x1 = *width;
- int x, h, x_previous;
- int fy = cy;
- struct box *left;
- struct box *right;
- struct box *b;
- struct box *split_box = 0;
- struct box *d;
- struct box *br_box = 0;
- bool move_y = false;
- bool place_below = false;
- int space_before = 0, space_after = 0;
- unsigned int inline_count = 0;
- unsigned int i;
- const struct font_functions *font_func = content->font_func;
- plot_font_style_t fstyle;
-
+ /* calculate width required by cells */
+ for (i = 0; i != columns; i++) {
#ifdef LAYOUT_DEBUG
- LOG("first %p, first->text '%.*s', width %i, y %i, cx %i, cy %i", first, (int)first->length, first->text, *width, *y, cx, cy);
+ LOG("table %p, column %u: type %s, width %i, min %i, max %i", table, i, ((const char *[]){
+ "UNKNOWN",
+ "FIXED",
+ "AUTO",
+ "PERCENT",
+ "RELATIVE"
+ })[col[i].type], col[i].width, col[i].min, col[i].max);
#endif
- /* find sides at top of line */
- x0 += cx;
- x1 += cx;
- find_sides(cont->float_children, cy, cy, &x0, &x1, &left, &right);
- x0 -= cx;
- x1 -= cx;
-
- if (indent)
- x0 += layout_text_indent(first->parent->parent->style, *width);
-
- if (x1 < x0)
- x1 = x0;
-
- /* get minimum line height from containing block.
- * this is the line-height if there are text children and also in the
- * case of an initially empty text input */
- if (has_text_children || first->parent->parent->gadget)
- used_height = height =
- line_height(first->parent->parent->style);
- else
- /* inline containers with no text are usually for layout and
- * look better with no minimum line-height */
- used_height = height = 0;
+ if (col[i].positioned) {
+ positioned_columns++;
+ continue;
+ } else if (col[i].type == COLUMN_WIDTH_FIXED) {
+ if (col[i].width < col[i].min)
+ col[i].width = col[i].max = col[i].min;
+ else
+ col[i].min = col[i].max = col[i].width;
+ required_width += col[i].width;
+ } else if (col[i].type == COLUMN_WIDTH_PERCENT) {
+ int width = col[i].width * auto_width / 100;
+ required_width += col[i].min < width ? width :
+ col[i].min;
+ } else
+ required_width += col[i].min;
- /* pass 1: find height of line assuming sides at top of line: loop
- * body executed at least once
- * keep in sync with the loop in layout_minmax_line() */
#ifdef LAYOUT_DEBUG
- LOG("x0 %i, x1 %i, x1 - x0 %i", x0, x1, x1 - x0);
+ LOG("required_width %i", required_width);
#endif
-
- for (x = 0, b = first; x <= x1 - x0 && b != 0; b = b->next) {
- int min_width, max_width, min_height, max_height;
-
- assert(b->type == BOX_INLINE || b->type == BOX_INLINE_BLOCK ||
- b->type == BOX_FLOAT_LEFT ||
- b->type == BOX_FLOAT_RIGHT ||
- b->type == BOX_BR || b->type == BOX_TEXT ||
- b->type == BOX_INLINE_END);
+ }
+ required_width += (columns + 1 - positioned_columns) *
+ border_spacing_h;
#ifdef LAYOUT_DEBUG
- LOG("pass 1: b %p, x %i", b, x);
+ LOG("width %i, min %i, max %i, auto %i, required %i", table_width, table->min_width, table->max_width, auto_width, required_width);
#endif
- if (b->type == BOX_BR)
- break;
-
- if (b->type == BOX_FLOAT_LEFT || b->type == BOX_FLOAT_RIGHT)
- continue;
- if (b->type == BOX_INLINE_BLOCK &&
- (css_computed_position(b->style) ==
- CSS_POSITION_ABSOLUTE ||
- css_computed_position(b->style) ==
- CSS_POSITION_FIXED))
- continue;
-
- assert(b->style != NULL);
- font_plot_style_from_css(b->style, &fstyle);
-
- x += space_after;
-
- if (b->type == BOX_INLINE_BLOCK) {
- if (b->max_width != UNKNOWN_WIDTH)
- if (!layout_float(b, *width, content))
- return false;
- h = b->border[TOP].width + b->padding[TOP] + b->height +
- b->padding[BOTTOM] +
- b->border[BOTTOM].width;
- if (height < h)
- height = h;
- x += b->margin[LEFT] + b->border[LEFT].width +
- b->padding[LEFT] + b->width +
- b->padding[RIGHT] +
- b->border[RIGHT].width +
- b->margin[RIGHT];
- space_after = 0;
- continue;
- }
-
- if (b->type == BOX_INLINE) {
- /* calculate borders, margins, and padding */
- layout_find_dimensions(*width, -1, b, b->style, 0, 0,
- 0, 0, 0, 0, b->margin, b->padding,
- b->border);
- for (i = 0; i != 4; i++)
- if (b->margin[i] == AUTO)
- b->margin[i] = 0;
- x += b->margin[LEFT] + b->border[LEFT].width +
- b->padding[LEFT];
- if (b->inline_end) {
- b->inline_end->margin[RIGHT] = b->margin[RIGHT];
- b->inline_end->padding[RIGHT] =
- b->padding[RIGHT];
- b->inline_end->border[RIGHT] =
- b->border[RIGHT];
- } else {
- x += b->padding[RIGHT] +
- b->border[RIGHT].width +
- b->margin[RIGHT];
- }
- } else if (b->type == BOX_INLINE_END) {
- b->width = 0;
- if (b->space == UNKNOWN_WIDTH) {
- font_func->font_width(&fstyle, " ", 1,
- &b->space);
- /** \todo handle errors */
+ if (auto_width < required_width) {
+ /* table narrower than required width for columns:
+ * treat percentage widths as maximums */
+ for (i = 0; i != columns; i++) {
+ if (col[i].type == COLUMN_WIDTH_RELATIVE)
+ continue;
+ if (col[i].type == COLUMN_WIDTH_PERCENT) {
+ col[i].max = auto_width * col[i].width / 100;
+ if (col[i].max < col[i].min)
+ col[i].max = col[i].min;
}
- space_after = b->space;
-
- x += b->padding[RIGHT] + b->border[RIGHT].width +
- b->margin[RIGHT];
- continue;
+ min_width += col[i].min;
+ max_width += col[i].max;
}
-
- if (!b->object && !(b->flags & IFRAME) && !b->gadget &&
- !(b->flags & REPLACE_DIM)) {
- /* inline non-replaced, 10.3.1 and 10.6.1 */
- b->height = line_height(b->style ? b->style :
- b->parent->parent->style);
- if (height < b->height)
- height = b->height;
-
- if (!b->text) {
- b->width = 0;
- space_after = 0;
+ } else {
+ /* take percentages exactly */
+ for (i = 0; i != columns; i++) {
+ if (col[i].type == COLUMN_WIDTH_RELATIVE)
continue;
+ if (col[i].type == COLUMN_WIDTH_PERCENT) {
+ int width = auto_width * col[i].width / 100;
+ if (width < col[i].min)
+ width = col[i].min;
+ col[i].min = col[i].width = col[i].max = width;
+ col[i].type = COLUMN_WIDTH_FIXED;
}
+ min_width += col[i].min;
+ max_width += col[i].max;
+ }
+ }
- if (b->width == UNKNOWN_WIDTH) {
- /** \todo handle errors */
-
- /* If it's a select element, we must use the
- * width of the widest option text */
- if (b->parent->parent->gadget &&
- b->parent->parent->gadget->type
- == GADGET_SELECT) {
- int opt_maxwidth = 0;
- struct form_option *o;
-
- for (o = b->parent->parent->gadget->
- data.select.items; o;
- o = o->next) {
- int opt_width;
- font_func->font_width(&fstyle,
- o->text,
- strlen(o->text),
- &opt_width);
-
- if (opt_maxwidth < opt_width)
- opt_maxwidth =opt_width;
- }
- b->width = opt_maxwidth;
- if (nsoption_bool(core_select_menu))
- b->width += SCROLLBAR_WIDTH;
- } else {
- font_func->font_width(&fstyle, b->text,
- b->length, &b->width);
- b->flags |= MEASURED;
- }
+ /* allocate relative widths */
+ spare_width = auto_width;
+ for (i = 0; i != columns; i++) {
+ if (col[i].type == COLUMN_WIDTH_RELATIVE)
+ relative_sum += col[i].width;
+ else if (col[i].type == COLUMN_WIDTH_FIXED)
+ spare_width -= col[i].width;
+ else
+ spare_width -= col[i].min;
+ }
+ spare_width -= (columns + 1) * border_spacing_h;
+ if (relative_sum != 0) {
+ if (spare_width < 0)
+ spare_width = 0;
+ for (i = 0; i != columns; i++) {
+ if (col[i].type == COLUMN_WIDTH_RELATIVE) {
+ col[i].min = ceil(col[i].max =
+ (float) spare_width
+ * (float) col[i].width
+ / relative_sum);
+ min_width += col[i].min;
+ max_width += col[i].max;
}
+ }
+ }
+ min_width += (columns + 1) * border_spacing_h;
+ max_width += (columns + 1) * border_spacing_h;
- /* If the current text has not been measured (i.e. its
- * width was estimated after splitting), and it fits on
- * the line, measure it properly, so next box is placed
- * correctly. */
- if (b->text && (x + b->width < x1 - x0) &&
- !(b->flags & MEASURED) &&
- b->next) {
- font_func->font_width(&fstyle, b->text,
- b->length, &b->width);
- b->flags |= MEASURED;
+ if (auto_width <= min_width) {
+ /* not enough space: minimise column widths */
+ for (i = 0; i < columns; i++) {
+ col[i].width = col[i].min;
+ }
+ table_width = min_width;
+ } else if (max_width <= auto_width) {
+ /* more space than maximum width */
+ if (table_width == AUTO) {
+ /* for auto-width tables, make columns max width */
+ for (i = 0; i < columns; i++) {
+ col[i].width = col[i].max;
}
+ table_width = max_width;
+ } else {
+ /* for fixed-width tables, distribute the extra space
+ * too */
+ unsigned int flexible_columns = 0;
+ for (i = 0; i != columns; i++)
+ if (col[i].type != COLUMN_WIDTH_FIXED)
+ flexible_columns++;
+ if (flexible_columns == 0) {
+ int extra = (table_width - max_width) / columns;
+ remainder = (table_width - max_width) -
+ (extra * columns);
+ for (i = 0; i != columns; i++) {
+ col[i].width = col[i].max + extra;
+ count -= remainder;
+ if (count < 0) {
+ col[i].width++;
+ count += columns;
+ }
+ }
- x += b->width;
- if (b->space == UNKNOWN_WIDTH) {
- font_func->font_width(&fstyle, " ", 1,
- &b->space);
- /** \todo handle errors */
+ } else {
+ int extra = (table_width - max_width) /
+ flexible_columns;
+ remainder = (table_width - max_width) -
+ (extra * flexible_columns);
+ for (i = 0; i != columns; i++)
+ if (col[i].type != COLUMN_WIDTH_FIXED) {
+ col[i].width = col[i].max +
+ extra;
+ count -= remainder;
+ if (count < 0) {
+ col[i].width++;
+ count += flexible_columns;
+ }
+ }
}
- space_after = b->space;
- continue;
- }
-
- space_after = 0;
-
- /* inline replaced, 10.3.2 and 10.6.2 */
- assert(b->style);
-
- layout_find_dimensions(*width, -1, b, b->style,
- &b->width, &b->height, &max_width, &min_width,
- &max_height, &min_height, NULL, NULL, NULL);
-
- if (b->object && !(b->flags & REPLACE_DIM)) {
- layout_get_object_dimensions(b, &b->width, &b->height,
- min_width, max_width,
- min_height, max_height);
- } else if (b->flags & IFRAME) {
- /* TODO: should we look at the content dimensions? */
- if (b->width == AUTO)
- b->width = 400;
- if (b->height == AUTO)
- b->height = 300;
-
- /* We reformat the iframe browser window to new
- * dimensions in pass 2 */
- } else {
- /* form control with no object */
- if (b->width == AUTO)
- b->width = FIXTOINT(nscss_len2px(INTTOFIX(1),
- CSS_UNIT_EM, b->style));
- if (b->height == AUTO)
- b->height = FIXTOINT(nscss_len2px(INTTOFIX(1),
- CSS_UNIT_EM, b->style));
}
-
- /* Reformat object to new box size */
- if (b->object && content_get_type(b->object) == CONTENT_HTML &&
- b->width !=
- content_get_available_width(b->object)) {
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
- enum css_height_e htype = css_computed_height(b->style,
- &value, &unit);
-
- content_reformat(b->object, false, b->width, b->height);
-
- if (htype == CSS_HEIGHT_AUTO)
- b->height = content_get_height(b->object);
+ } else {
+ /* space between min and max: fill it exactly */
+ float scale = (float) (auto_width - min_width) /
+ (float) (max_width - min_width);
+ /* fprintf(stderr, "filling, scale %f\n", scale); */
+ for (i = 0; i < columns; i++) {
+ col[i].width = col[i].min + (int) (0.5 +
+ (col[i].max - col[i].min) * scale);
}
-
- if (height < b->height)
- height = b->height;
-
- x += b->width;
+ table_width = auto_width;
}
- /* find new sides using this height */
- x0 = cx;
- x1 = cx + *width;
- find_sides(cont->float_children, cy, cy + height, &x0, &x1,
- &left, &right);
- x0 -= cx;
- x1 -= cx;
+ xs[0] = x = border_spacing_h;
+ for (i = 0; i != columns; i++) {
+ if (!col[i].positioned)
+ x += col[i].width + border_spacing_h;
+ xs[i + 1] = x;
+ row_span[i] = 0;
+ excess_y[i] = 0;
+ row_span_cell[i] = 0;
+ }
- if (indent)
- x0 += layout_text_indent(first->parent->parent->style, *width);
+ /* position cells */
+ table_height = border_spacing_v;
+ for (row_group = table->children; row_group;
+ row_group = row_group->next) {
+ int row_group_height = 0;
+ for (row = row_group->children; row; row = row->next) {
+ int row_height = 0;
- if (x1 < x0)
- x1 = x0;
+ htype = css_computed_height(row->style, &value, &unit);
+ if (htype == CSS_HEIGHT_SET && unit != CSS_UNIT_PCT) {
+ row_height = FIXTOINT(nscss_len2px(value, unit,
+ row->style));
+ }
+ for (c = row->children; c; c = c->next) {
+ assert(c->style);
+ c->width = xs[c->start_column + c->columns] -
+ xs[c->start_column] -
+ border_spacing_h -
+ c->border[LEFT].width -
+ c->padding[LEFT] -
+ c->padding[RIGHT] -
+ c->border[RIGHT].width;
+ c->float_children = 0;
+ c->cached_place_below_level = 0;
- space_after = space_before = 0;
+ c->height = AUTO;
+ if (!layout_block_context(c, -1, content)) {
+ free(col);
+ free(excess_y);
+ free(row_span);
+ free(row_span_cell);
+ free(xs);
+ return false;
+ }
+ /* warning: c->descendant_y0 and
+ * c->descendant_y1 used as temporary storage
+ * until after vertical alignment is complete */
+ c->descendant_y0 = c->height;
+ c->descendant_y1 = c->padding[BOTTOM];
- /* pass 2: place boxes in line: loop body executed at least once */
-#ifdef LAYOUT_DEBUG
- LOG("x0 %i, x1 %i, x1 - x0 %i", x0, x1, x1 - x0);
-#endif
+ htype = css_computed_height(c->style,
+ &value, &unit);
- for (x = x_previous = 0, b = first; x <= x1 - x0 && b; b = b->next) {
-#ifdef LAYOUT_DEBUG
- LOG("pass 2: b %p, x %i", b, x);
-#endif
+ if (htype == CSS_HEIGHT_SET &&
+ unit != CSS_UNIT_PCT) {
+ /* some sites use height="1" or similar
+ * to attempt to make cells as small as
+ * possible, so treat it as a minimum */
+ int h = FIXTOINT(nscss_len2px(value,
+ unit, c->style));
+ if (c->height < h)
+ c->height = h;
+ }
+ /* specified row height is treated as a minimum
+ */
+ if (c->height < row_height)
+ c->height = row_height;
+ c->x = xs[c->start_column] +
+ c->border[LEFT].width;
+ c->y = c->border[TOP].width;
+ for (i = 0; i != c->columns; i++) {
+ row_span[c->start_column + i] = c->rows;
+ excess_y[c->start_column + i] =
+ c->border[TOP].width +
+ c->padding[TOP] +
+ c->height +
+ c->padding[BOTTOM] +
+ c->border[BOTTOM].width;
+ row_span_cell[c->start_column + i] = 0;
+ }
+ row_span_cell[c->start_column] = c;
+ c->padding[BOTTOM] = -border_spacing_v -
+ c->border[TOP].width -
+ c->padding[TOP] -
+ c->height -
+ c->border[BOTTOM].width;
+ }
+ for (i = 0; i != columns; i++)
+ if (row_span[i] != 0)
+ row_span[i]--;
+ else
+ row_span_cell[i] = 0;
+ if (row->next || row_group->next) {
+ /* row height is greatest excess of a cell
+ * which ends in this row */
+ for (i = 0; i != columns; i++)
+ if (row_span[i] == 0 && row_height <
+ excess_y[i])
+ row_height = excess_y[i];
+ } else {
+ /* except in the last row */
+ for (i = 0; i != columns; i++)
+ if (row_height < excess_y[i])
+ row_height = excess_y[i];
+ }
+ for (i = 0; i != columns; i++) {
+ if (row_height < excess_y[i])
+ excess_y[i] -= row_height;
+ else
+ excess_y[i] = 0;
+ if (row_span_cell[i] != 0)
+ row_span_cell[i]->padding[BOTTOM] +=
+ row_height +
+ border_spacing_v;
+ }
- if (b->type == BOX_INLINE_BLOCK &&
- (css_computed_position(b->style) ==
- CSS_POSITION_ABSOLUTE ||
- css_computed_position(b->style) ==
- CSS_POSITION_FIXED)) {
- b->x = x + space_after;
+ row->x = 0;
+ row->y = row_group_height;
+ row->width = table_width;
+ row->height = row_height;
+ row_group_height += row_height + border_spacing_v;
+ }
+ row_group->x = 0;
+ row_group->y = table_height;
+ row_group->width = table_width;
+ row_group->height = row_group_height;
+ table_height += row_group_height;
+ }
+ /* Table height is either the height of the contents, or specified
+ * height if greater */
+ table_height = max(table_height, min_height);
+ /** \todo distribute spare height over the row groups / rows / cells */
- } else if (b->type == BOX_INLINE ||
- b->type == BOX_INLINE_BLOCK ||
- b->type == BOX_TEXT ||
- b->type == BOX_INLINE_END) {
- assert(b->width != UNKNOWN_WIDTH);
+ /* perform vertical alignment */
+ for (row_group = table->children; row_group;
+ row_group = row_group->next) {
+ for (row = row_group->children; row; row = row->next) {
+ for (c = row->children; c; c = c->next) {
+ enum css_vertical_align_e vertical_align;
- x_previous = x;
- x += space_after;
- b->x = x;
+ /* unextended bottom padding is in
+ * c->descendant_y1, and unextended
+ * cell height is in c->descendant_y0 */
+ spare_height = (c->padding[BOTTOM] -
+ c->descendant_y1) +
+ (c->height - c->descendant_y0);
- if ((b->type == BOX_INLINE && !b->inline_end) ||
- b->type == BOX_INLINE_BLOCK) {
- b->x += b->margin[LEFT] + b->border[LEFT].width;
- x = b->x + b->padding[LEFT] + b->width +
- b->padding[RIGHT] +
- b->border[RIGHT].width +
- b->margin[RIGHT];
- } else if (b->type == BOX_INLINE) {
- b->x += b->margin[LEFT] + b->border[LEFT].width;
- x = b->x + b->padding[LEFT] + b->width;
- } else if (b->type == BOX_INLINE_END) {
- b->height = b->inline_end->height;
- x += b->padding[RIGHT] +
- b->border[RIGHT].width +
- b->margin[RIGHT];
- } else {
- x += b->width;
- }
+ vertical_align = css_computed_vertical_align(
+ c->style, &value, &unit);
- space_before = space_after;
- if (b->object || b->flags & REPLACE_DIM ||
- b->flags & IFRAME)
- space_after = 0;
- else if (b->text || b->type == BOX_INLINE_END) {
- if (b->space == UNKNOWN_WIDTH) {
- font_plot_style_from_css(b->style,
- &fstyle);
- /** \todo handle errors */
- font_func->font_width(&fstyle, " ", 1,
- &b->space);
+ switch (vertical_align) {
+ case CSS_VERTICAL_ALIGN_SUB:
+ case CSS_VERTICAL_ALIGN_SUPER:
+ case CSS_VERTICAL_ALIGN_TEXT_TOP:
+ case CSS_VERTICAL_ALIGN_TEXT_BOTTOM:
+ case CSS_VERTICAL_ALIGN_SET:
+ case CSS_VERTICAL_ALIGN_BASELINE:
+ /* todo: baseline alignment, for now
+ * just use ALIGN_TOP */
+ case CSS_VERTICAL_ALIGN_TOP:
+ break;
+ case CSS_VERTICAL_ALIGN_MIDDLE:
+ c->padding[TOP] += spare_height / 2;
+ c->padding[BOTTOM] -= spare_height / 2;
+ layout_move_children(c, 0,
+ spare_height / 2);
+ break;
+ case CSS_VERTICAL_ALIGN_BOTTOM:
+ c->padding[TOP] += spare_height;
+ c->padding[BOTTOM] -= spare_height;
+ layout_move_children(c, 0,
+ spare_height);
+ break;
+ case CSS_VERTICAL_ALIGN_INHERIT:
+ assert(0);
+ break;
}
- space_after = b->space;
- } else {
- space_after = 0;
}
- split_box = b;
- move_y = true;
- inline_count++;
- } else if (b->type == BOX_BR) {
- b->x = x;
- b->width = 0;
- br_box = b;
- b = b->next;
- split_box = 0;
- move_y = true;
- break;
+ }
+ }
- } else {
- /* float */
-#ifdef LAYOUT_DEBUG
- LOG("float %p", b);
-#endif
+ /* Top and bottom margins of 'auto' are set to 0. CSS2.1 10.6.3 */
+ if (table->margin[TOP] == AUTO)
+ table->margin[TOP] = 0;
+ if (table->margin[BOTTOM] == AUTO)
+ table->margin[BOTTOM] = 0;
- d = b->children;
- d->float_children = 0;
- d->cached_place_below_level = 0;
- b->float_container = d->float_container = cont;
+ free(col);
+ free(excess_y);
+ free(row_span);
+ free(row_span_cell);
+ free(xs);
- if (!layout_float(d, *width, content))
- return false;
+ table->width = table_width;
+ table->height = table_height;
-#ifdef LAYOUT_DEBUG
- LOG("%p : %d %d", d, d->margin[TOP], d->border[TOP].width);
-#endif
+ return true;
+}
- d->x = d->margin[LEFT] + d->border[LEFT].width;
- d->y = d->margin[TOP] + d->border[TOP].width;
- b->width = d->margin[LEFT] + d->border[LEFT].width +
- d->padding[LEFT] + d->width +
- d->padding[RIGHT] +
- d->border[RIGHT].width +
- d->margin[RIGHT];
- b->height = d->margin[TOP] + d->border[TOP].width +
- d->padding[TOP] + d->height +
- d->padding[BOTTOM] +
- d->border[BOTTOM].width +
- d->margin[BOTTOM];
- if (b->width > (x1 - x0) - x)
- place_below = true;
- if (d->style && (css_computed_clear(d->style) ==
- CSS_CLEAR_NONE ||
- (css_computed_clear(d->style) ==
- CSS_CLEAR_LEFT && left == 0) ||
- (css_computed_clear(d->style) ==
- CSS_CLEAR_RIGHT &&
- right == 0) ||
- (css_computed_clear(d->style) ==
- CSS_CLEAR_BOTH &&
- left == 0 && right == 0)) &&
- (!place_below ||
- (left == 0 && right == 0 && x == 0)) &&
- cy >= cont->clear_level &&
- cy >= cont->cached_place_below_level) {
- /* + not cleared or,
- * cleared and there are no floats to clear
- * + fits without needing to be placed below or,
- * this line is empty with no floats
- * + current y, cy, is below the clear level
- *
- * Float affects current line */
- if (b->type == BOX_FLOAT_LEFT) {
- b->x = cx + x0;
- if (b->width > 0)
- x0 += b->width;
- left = b;
- } else {
- b->x = cx + x1 - b->width;
- if (b->width > 0)
- x1 -= b->width;
- right = b;
- }
- b->y = cy;
- } else {
- /* cleared or doesn't fit on line */
- /* place below into next available space */
- int fcy = (cy > cont->clear_level) ? cy :
- cont->clear_level;
- fcy = (fcy > cont->cached_place_below_level) ?
- fcy :
- cont->cached_place_below_level;
- fy = (fy > fcy) ? fy : fcy;
- fy = (fy == cy) ? fy + height : fy;
+/**
+ * Manimpulate box height according to CSS min-height and max-height properties
+ *
+ * \param box block to modify with any min-height or max-height
+ * \param container containing block for absolutely positioned elements, or
+ * NULL for non absolutely positioned elements.
+ * \return whether the height has been changed
+ */
+static bool layout_apply_minmax_height(struct box *box, struct box *container)
+{
+ int h;
+ struct box *containing_block = NULL;
+ bool updated = false;
- place_float_below(b, *width, cx, fy, cont);
- fy = b->y;
- if (d->style && (
- (css_computed_clear(d->style) ==
- CSS_CLEAR_LEFT && left != 0) ||
- (css_computed_clear(d->style) ==
- CSS_CLEAR_RIGHT &&
- right != 0) ||
- (css_computed_clear(d->style) ==
- CSS_CLEAR_BOTH &&
- (left != 0 || right != 0)))) {
- /* to be cleared below existing
- * floats */
- if (b->type == BOX_FLOAT_LEFT)
- b->x = cx;
- else
- b->x = cx + *width - b->width;
+ /* Find containing block for percentage heights */
+ if (box->style != NULL && css_computed_position(box->style) ==
+ CSS_POSITION_ABSOLUTE) {
+ /* Box is absolutely positioned */
+ assert(container);
+ containing_block = container;
+ } else if (box->float_container && box->style != NULL &&
+ (css_computed_float(box->style) == CSS_FLOAT_LEFT ||
+ css_computed_float(box->style) == CSS_FLOAT_RIGHT)) {
+ /* Box is a float */
+ assert(box->parent && box->parent->parent &&
+ box->parent->parent->parent);
+ containing_block = box->parent->parent->parent;
+ } else if (box->parent && box->parent->type != BOX_INLINE_CONTAINER) {
+ /* Box is a block level element */
+ containing_block = box->parent;
+ } else if (box->parent && box->parent->type == BOX_INLINE_CONTAINER) {
+ /* Box is an inline block */
+ assert(box->parent->parent);
+ containing_block = box->parent->parent;
+ }
+
+ if (box->style) {
+ enum css_height_e htype = CSS_HEIGHT_AUTO;
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
- fcy = layout_clear(cont->float_children,
- css_computed_clear(d->style));
- if (fcy > cont->clear_level)
- cont->clear_level = fcy;
- if (b->y < fcy)
- b->y = fcy;
+ if (containing_block) {
+ htype = css_computed_height(containing_block->style,
+ &value, &unit);
+ }
+
+ /* max-height */
+ if (css_computed_max_height(box->style, &value, &unit) ==
+ CSS_MAX_HEIGHT_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ if (containing_block &&
+ containing_block->height != AUTO &&
+ (css_computed_position(box->style) ==
+ CSS_POSITION_ABSOLUTE ||
+ htype == CSS_HEIGHT_SET)) {
+ /* Box is absolutely positioned or its
+ * containing block has a valid
+ * specified height. (CSS 2.1
+ * Section 10.5) */
+ h = FPCT_OF_INT_TOINT(value,
+ containing_block->height);
+ if (h < box->height) {
+ box->height = h;
+ updated = true;
+ }
+ }
+ } else {
+ h = FIXTOINT(nscss_len2px(value, unit,
+ box->style));
+ if (h < box->height) {
+ box->height = h;
+ updated = true;
}
- if (b->type == BOX_FLOAT_LEFT)
- left = b;
- else
- right = b;
}
- add_float_to_container(cont, b);
+ }
- split_box = 0;
+ /* min-height */
+ if (css_computed_min_height(box->style, &value, &unit) ==
+ CSS_MIN_HEIGHT_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ if (containing_block &&
+ containing_block->height != AUTO &&
+ (css_computed_position(box->style) ==
+ CSS_POSITION_ABSOLUTE ||
+ htype == CSS_HEIGHT_SET)) {
+ /* Box is absolutely positioned or its
+ * containing block has a valid
+ * specified height. (CSS 2.1
+ * Section 10.5) */
+ h = FPCT_OF_INT_TOINT(value,
+ containing_block->height);
+ if (h > box->height) {
+ box->height = h;
+ updated = true;
+ }
+ }
+ } else {
+ h = FIXTOINT(nscss_len2px(value, unit,
+ box->style));
+ if (h > box->height) {
+ box->height = h;
+ updated = true;
+ }
+ }
}
}
+ return updated;
+}
- if (x1 - x0 < x && split_box) {
- /* the last box went over the end */
- size_t split = 0;
- int w;
- bool no_wrap = css_computed_white_space(
- split_box->style) == CSS_WHITE_SPACE_NOWRAP ||
- css_computed_white_space(
- split_box->style) == CSS_WHITE_SPACE_PRE;
- x = x_previous;
+/**
+ * Layout a block which contains an object.
+ *
+ * \param block box of type BLOCK, INLINE_BLOCK, TABLE, or TABLE_CELL
+ * \return true on success, false on memory exhaustion
+ */
+static bool layout_block_object(struct box *block)
+{
+ assert(block);
+ assert(block->type == BOX_BLOCK ||
+ block->type == BOX_INLINE_BLOCK ||
+ block->type == BOX_TABLE ||
+ block->type == BOX_TABLE_CELL);
+ assert(block->object);
- if (!no_wrap && (split_box->type == BOX_INLINE ||
- split_box->type == BOX_TEXT) &&
- !split_box->object &&
- !(split_box->flags & REPLACE_DIM) &&
- !(split_box->flags & IFRAME) &&
- !split_box->gadget && split_box->text) {
+#ifdef LAYOUT_DEBUG
+ LOG("block %p, object %s, width %i", block, hlcache_handle_get_url(block->object), block->width);
+#endif
- font_plot_style_from_css(split_box->style, &fstyle);
- /** \todo handle errors */
- font_func->font_split(&fstyle,
- split_box->text, split_box->length,
- x1 - x0 - x - space_before, &split, &w);
- }
+ if (content_get_type(block->object) == CONTENT_HTML) {
+ content_reformat(block->object, false, block->width, 1);
+ } else {
+ /* Non-HTML objects */
+ /* this case handled already in
+ * layout_block_find_dimensions() */
+ }
- /* split == 0 implies that text can't be split */
+ return true;
+}
- if (split == 0)
- w = split_box->width;
-#ifdef LAYOUT_DEBUG
- LOG("splitting: split_box %p \"%.*s\", spilt %zu, w %i, ""left %p, right %p, inline_count %u", split_box, (int)split_box->length, split_box->text, split, w, left, right, inline_count);
-#endif
+/**
+ * Layout a block formatting context.
+ *
+ * \param block BLOCK, INLINE_BLOCK, or TABLE_CELL to layout
+ * \param viewport_height Height of viewport in pixels or -ve if unknown
+ * \param content Memory pool for any new boxes
+ * \return true on success, false on memory exhaustion
+ *
+ * This function carries out layout of a block and its children, as described
+ * in CSS 2.1 9.4.1.
+ */
+static bool
+layout_block_context(struct box *block,
+ int viewport_height,
+ html_content *content)
+{
+ struct box *box;
+ int cx, cy; /**< current coordinates */
+ int max_pos_margin = 0;
+ int max_neg_margin = 0;
+ int y = 0;
+ int lm, rm;
+ struct box *margin_collapse = NULL;
+ bool in_margin = false;
+ css_fixed gadget_size;
+ css_unit gadget_unit; /* Checkbox / radio buttons */
- if ((split == 0 || x1 - x0 <= x + space_before + w) &&
- !left && !right && inline_count == 1) {
- /* first word of box doesn't fit, but no floats and
- * first box on line so force in */
- if (split == 0 || split == split_box->length) {
- /* only one word in this box, or not text
- * or white-space:nowrap */
- b = split_box->next;
- } else {
- /* cut off first word for this line */
- if (!layout_text_box_split(content, &fstyle,
- split_box, split, w))
- return false;
- b = split_box->next;
- }
- x += space_before + w;
-#ifdef LAYOUT_DEBUG
- LOG("forcing");
-#endif
- } else if ((split == 0 || x1 - x0 <= x + space_before + w) &&
- inline_count == 1) {
- /* first word of first box doesn't fit, but a float is
- * taking some of the width so move below it */
- assert(left || right);
- used_height = 0;
- if (left) {
-#ifdef LAYOUT_DEBUG
- LOG("cy %i, left->y %i, left->height %i", cy, left->y, left->height);
-#endif
- used_height = left->y + left->height - cy + 1;
-#ifdef LAYOUT_DEBUG
- LOG("used_height %i", used_height);
-#endif
- }
- if (right && used_height <
- right->y + right->height - cy + 1)
- used_height = right->y + right->height - cy + 1;
+ assert(block->type == BOX_BLOCK ||
+ block->type == BOX_INLINE_BLOCK ||
+ block->type == BOX_TABLE_CELL);
+ assert(block->width != UNKNOWN_WIDTH);
+ assert(block->width != AUTO);
- if (used_height < 0)
- used_height = 0;
+ block->float_children = NULL;
+ block->cached_place_below_level = 0;
+ block->clear_level = 0;
+
+ /* special case if the block contains an object */
+ if (block->object) {
+ int temp_width = block->width;
+ if (!layout_block_object(block))
+ return false;
+ layout_get_object_dimensions(block, &temp_width,
+ &block->height, INT_MIN, INT_MAX,
+ INT_MIN, INT_MAX);
+ return true;
+ } else if (block->flags & REPLACE_DIM) {
+ return true;
+ }
+
+ /* special case if the block contains an radio button or checkbox */
+ if (block->gadget && (block->gadget->type == GADGET_RADIO ||
+ block->gadget->type == GADGET_CHECKBOX)) {
+ /* form checkbox or radio button
+ * if width or height is AUTO, set it to 1em */
+ gadget_unit = CSS_UNIT_EM;
+ gadget_size = INTTOFIX(1);
+ if (block->height == AUTO)
+ block->height = FIXTOINT(nscss_len2px(gadget_size,
+ gadget_unit, block->style));
+ }
+
+ box = block->children;
+ /* set current coordinates to top-left of the block */
+ cx = 0;
+ y = cy = block->padding[TOP];
+ if (box)
+ box->y = block->padding[TOP];
+
+ /* Step through the descendants of the block in depth-first order, but
+ * not into the children of boxes which aren't blocks. For example, if
+ * the tree passed to this function looks like this (box->type shown):
+ *
+ * block -> BOX_BLOCK
+ * BOX_BLOCK * (1)
+ * BOX_INLINE_CONTAINER * (2)
+ * BOX_INLINE
+ * BOX_TEXT
+ * ...
+ * BOX_BLOCK * (3)
+ * BOX_TABLE * (4)
+ * BOX_TABLE_ROW
+ * BOX_TABLE_CELL
+ * ...
+ * BOX_TABLE_CELL
+ * ...
+ * BOX_BLOCK * (5)
+ * BOX_INLINE_CONTAINER * (6)
+ * BOX_TEXT
+ * ...
+ * then the while loop will visit each box marked with *, setting box
+ * to each in the order shown. */
+ while (box) {
+ enum css_overflow_e overflow_x = CSS_OVERFLOW_VISIBLE;
+ enum css_overflow_e overflow_y = CSS_OVERFLOW_VISIBLE;
+
+ assert(box->type == BOX_BLOCK || box->type == BOX_TABLE ||
+ box->type == BOX_INLINE_CONTAINER);
+
+ /* Tables are laid out before being positioned, because the
+ * position depends on the width which is calculated in
+ * table layout. Blocks and inline containers are positioned
+ * before being laid out, because width is not dependent on
+ * content, and the position is required during layout for
+ * correct handling of floats.
+ */
- b = split_box;
-#ifdef LAYOUT_DEBUG
- LOG("moving below float");
-#endif
- } else if (split == 0 || x1 - x0 <= x + space_before + w) {
- /* first word of box doesn't fit so leave box for next
- * line */
- b = split_box;
-#ifdef LAYOUT_DEBUG
- LOG("leaving for next line");
-#endif
- } else {
- /* fit as many words as possible */
- assert(split != 0);
-#ifdef LAYOUT_DEBUG
- LOG("'%.*s' %i %zu %i", (int)split_box->length, split_box->text, x1 - x0, split, w);
-#endif
- if (split != split_box->length) {
- if (!layout_text_box_split(content, &fstyle,
- split_box, split, w))
- return false;
- b = split_box->next;
- }
- x += space_before + w;
-#ifdef LAYOUT_DEBUG
- LOG("fitting words");
-#endif
+ if (box->style &&
+ (css_computed_position(box->style) ==
+ CSS_POSITION_ABSOLUTE ||
+ css_computed_position(box->style) ==
+ CSS_POSITION_FIXED)) {
+ box->x = box->parent->padding[LEFT];
+ /* absolute positioned; this element will establish
+ * its own block context when it gets laid out later,
+ * so no need to look at its children now. */
+ goto advance_to_next_box;
}
- move_y = true;
- }
- /* set positions */
- switch (css_computed_text_align(first->parent->parent->style)) {
- case CSS_TEXT_ALIGN_RIGHT:
- case CSS_TEXT_ALIGN_LIBCSS_RIGHT:
- x0 = x1 - x;
- break;
- case CSS_TEXT_ALIGN_CENTER:
- case CSS_TEXT_ALIGN_LIBCSS_CENTER:
- x0 = (x0 + (x1 - x)) / 2;
- break;
- case CSS_TEXT_ALIGN_LEFT:
- case CSS_TEXT_ALIGN_LIBCSS_LEFT:
- case CSS_TEXT_ALIGN_JUSTIFY:
- /* leave on left */
- break;
- case CSS_TEXT_ALIGN_DEFAULT:
- /* None; consider text direction */
- switch (css_computed_direction(first->parent->parent->style)) {
- case CSS_DIRECTION_LTR:
- /* leave on left */
- break;
- case CSS_DIRECTION_RTL:
- x0 = x1 - x;
- break;
+ /* If we don't know which box the current margin collapses
+ * through to, find out. Update the pos/neg margin values. */
+ if (margin_collapse == NULL) {
+ margin_collapse = layout_next_margin_block(box, block,
+ viewport_height,
+ &max_pos_margin, &max_neg_margin);
+ /* We have a margin that has not yet been applied. */
+ in_margin = true;
}
- break;
- }
-
- for (d = first; d != b; d = d->next) {
- d->flags &= ~NEW_LINE;
- if (d->type == BOX_INLINE_BLOCK &&
- (css_computed_position(d->style) ==
- CSS_POSITION_ABSOLUTE ||
- css_computed_position(d->style) ==
- CSS_POSITION_FIXED)) {
- /* positioned inline-blocks:
- * set static position (x,y) only, rest of positioning
- * is handled later */
- d->x += x0;
- d->y = *y;
- continue;
- } else if ((d->type == BOX_INLINE &&
- ((d->object || d->gadget) == false) &&
- !(d->flags & IFRAME) &&
- !(d->flags & REPLACE_DIM)) ||
- d->type == BOX_BR ||
- d->type == BOX_TEXT ||
- d->type == BOX_INLINE_END) {
- /* regular (non-replaced) inlines */
- d->x += x0;
- d->y = *y - d->padding[TOP];
+ /* Clearance. */
+ y = 0;
+ if (box->style && css_computed_clear(box->style) !=
+ CSS_CLEAR_NONE)
+ y = layout_clear(block->float_children,
+ css_computed_clear(box->style));
- if (d->type == BOX_TEXT && d->height > used_height) {
- /* text */
- used_height = d->height;
- }
- } else if ((d->type == BOX_INLINE) ||
- d->type == BOX_INLINE_BLOCK) {
- /* replaced inlines and inline-blocks */
- d->x += x0;
- d->y = *y + d->border[TOP].width + d->margin[TOP];
- h = d->margin[TOP] + d->border[TOP].width +
- d->padding[TOP] + d->height +
- d->padding[BOTTOM] +
- d->border[BOTTOM].width +
- d->margin[BOTTOM];
- if (used_height < h)
- used_height = h;
+ /* Find box's overflow properties */
+ if (box->style) {
+ overflow_x = css_computed_overflow_x(box->style);
+ overflow_y = css_computed_overflow_y(box->style);
}
- }
- first->flags |= NEW_LINE;
+ /* Blocks establishing a block formatting context get minimum
+ * left and right margins to avoid any floats. */
+ lm = rm = 0;
- assert(b != first || (move_y && 0 < used_height && (left || right)));
+ if (box->type == BOX_BLOCK || box->flags & IFRAME) {
+ if (!box->object && !(box->flags & IFRAME) &&
+ !(box->flags & REPLACE_DIM) &&
+ box->style &&
+ (overflow_x != CSS_OVERFLOW_VISIBLE ||
+ overflow_y != CSS_OVERFLOW_VISIBLE)) {
+ /* box establishes new block formatting context
+ * so available width may be diminished due to
+ * floats. */
+ int x0, x1, top;
+ struct box *left, *right;
+ top = cy + max_pos_margin - max_neg_margin;
+ top = (top > y) ? top : y;
+ x0 = cx;
+ x1 = cx + box->parent->width -
+ box->parent->padding[LEFT] -
+ box->parent->padding[RIGHT];
+ find_sides(block->float_children, top, top,
+ &x0, &x1, &left, &right);
+ /* calculate min required left & right margins
+ * needed to avoid floats */
+ lm = x0 - cx;
+ rm = cx + box->parent->width -
+ box->parent->padding[LEFT] -
+ box->parent->padding[RIGHT] -
+ x1;
+ }
+ layout_block_find_dimensions(box->parent->width,
+ viewport_height, lm, rm, box);
+ if (box->type == BOX_BLOCK && !(box->flags & IFRAME)) {
+ layout_block_add_scrollbar(box, RIGHT);
+ layout_block_add_scrollbar(box, BOTTOM);
+ }
+ } else if (box->type == BOX_TABLE) {
+ if (box->style != NULL) {
+ enum css_width_e wtype;
+ css_fixed width = 0;
+ css_unit unit = CSS_UNIT_PX;
- /* handle vertical-align by adjusting box y values */
- /** \todo proper vertical alignment handling */
- for (d = first; d != b; d = d->next) {
- if ((d->type == BOX_INLINE && d->inline_end) ||
- d->type == BOX_BR ||
- d->type == BOX_TEXT ||
- d->type == BOX_INLINE_END) {
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
- switch (css_computed_vertical_align(d->style, &value,
- &unit)) {
- case CSS_VERTICAL_ALIGN_SUPER:
- case CSS_VERTICAL_ALIGN_TOP:
- case CSS_VERTICAL_ALIGN_TEXT_TOP:
- /* already at top */
- break;
- case CSS_VERTICAL_ALIGN_SUB:
- case CSS_VERTICAL_ALIGN_BOTTOM:
- case CSS_VERTICAL_ALIGN_TEXT_BOTTOM:
- d->y += used_height - d->height;
- break;
- default:
- case CSS_VERTICAL_ALIGN_BASELINE:
- d->y += 0.75 * (used_height - d->height);
- break;
+ wtype = css_computed_width(box->style, &width,
+ &unit);
+
+ if (wtype == CSS_WIDTH_AUTO) {
+ /* max available width may be
+ * diminished due to floats. */
+ int x0, x1, top;
+ struct box *left, *right;
+ top = cy + max_pos_margin -
+ max_neg_margin;
+ top = (top > y) ? top : y;
+ x0 = cx;
+ x1 = cx + box->parent->width -
+ box->parent->padding[LEFT] -
+ box->parent->padding[RIGHT];
+ find_sides(block->float_children,
+ top, top, &x0, &x1,
+ &left, &right);
+ /* calculate min required left & right
+ * margins needed to avoid floats */
+ lm = x0 - cx;
+ rm = cx + box->parent->width -
+ box->parent->padding[LEFT] -
+ box->parent->padding[RIGHT] -
+ x1;
+ }
}
+ if (!layout_table(box, box->parent->width - lm - rm,
+ content))
+ return false;
+ layout_solve_width(box, box->parent->width, box->width,
+ lm, rm, -1, -1);
}
- }
- /* handle clearance for br */
- if (br_box && css_computed_clear(br_box->style) != CSS_CLEAR_NONE) {
- int clear_y = layout_clear(cont->float_children,
- css_computed_clear(br_box->style));
- if (used_height < clear_y - cy)
- used_height = clear_y - cy;
- }
+ /* Position box: horizontal. */
+ box->x = box->parent->padding[LEFT] + box->margin[LEFT] +
+ box->border[LEFT].width;
+ cx += box->x;
- if (move_y)
- *y += used_height;
- *next_box = b;
- *width = x; /* return actual width */
- return true;
-}
+ /* Position box: vertical. */
+ if (box->border[TOP].width) {
+ box->y += box->border[TOP].width;
+ cy += box->border[TOP].width;
+ }
+
+ /* Vertical margin */
+ if (((box->type == BOX_BLOCK &&
+ (box->flags & HAS_HEIGHT)) ||
+ box->type == BOX_TABLE ||
+ (box->type == BOX_INLINE_CONTAINER &&
+ box != box->parent->children) ||
+ margin_collapse == box) &&
+ in_margin == true) {
+ /* Margin goes above this box. */
+ cy += max_pos_margin - max_neg_margin;
+ box->y += max_pos_margin - max_neg_margin;
+ /* Current margin has been applied. */
+ in_margin = false;
+ max_pos_margin = max_neg_margin = 0;
+ }
-/**
- * Calculate minimum and maximum width of a line.
- *
- * \param first a box in an inline container
- * \param line_min updated to minimum width of line starting at first
- * \param line_max updated to maximum width of line starting at first
- * \param first_line true iff this is the first line in the inline container
- * \param line_has_height updated to true or false, depending on line
- * \param font_func Font functions.
- * \return first box in next line, or 0 if no more lines
- * \post 0 <= *line_min <= *line_max
- */
+ /* Handle clearance */
+ if (box->type != BOX_INLINE_CONTAINER &&
+ (y > 0) && (cy < y)) {
+ /* box clears something*/
+ box->y += y - cy;
+ cy = y;
+ }
-struct box *layout_minmax_line(struct box *first,
- int *line_min, int *line_max, bool first_line,
- bool *line_has_height, const struct font_functions *font_func)
-{
- int min = 0, max = 0, width, height, fixed;
- float frac;
- size_t i, j;
- struct box *b;
- struct box *block;
- plot_font_style_t fstyle;
- bool no_wrap;
+ /* Unless the box has an overflow style of visible, the box
+ * establishes a new block context. */
+ if (box->type == BOX_BLOCK && box->style &&
+ (overflow_x != CSS_OVERFLOW_VISIBLE ||
+ overflow_y != CSS_OVERFLOW_VISIBLE)) {
- assert(first->parent);
- assert(first->parent->parent);
- assert(first->parent->parent->style);
+ layout_block_context(box, viewport_height, content);
- block = first->parent->parent;
- no_wrap = (css_computed_white_space(block->style) ==
- CSS_WHITE_SPACE_NOWRAP ||
- css_computed_white_space(block->style) ==
- CSS_WHITE_SPACE_PRE);
+ cy += box->padding[TOP];
- *line_has_height = false;
+ if (box->height == AUTO) {
+ box->height = 0;
+ layout_block_add_scrollbar(box, BOTTOM);
+ }
- /* corresponds to the pass 1 loop in layout_line() */
- for (b = first; b; b = b->next) {
- enum css_width_e wtype;
- enum css_height_e htype;
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
+ cx -= box->x;
+ cy += box->height + box->padding[BOTTOM] +
+ box->border[BOTTOM].width;
+ y = box->y + box->padding[TOP] + box->height +
+ box->padding[BOTTOM] +
+ box->border[BOTTOM].width;
- assert(b->type == BOX_INLINE || b->type == BOX_INLINE_BLOCK ||
- b->type == BOX_FLOAT_LEFT ||
- b->type == BOX_FLOAT_RIGHT ||
- b->type == BOX_BR || b->type == BOX_TEXT ||
- b->type == BOX_INLINE_END);
+ /* Skip children, because they are done in the new
+ * block context */
+ goto advance_to_next_box;
+ }
#ifdef LAYOUT_DEBUG
- LOG("%p: min %i, max %i", b, min, max);
+ LOG("box %p, cx %i, cy %i", box, cx, cy);
#endif
- if (b->type == BOX_BR) {
- b = b->next;
- break;
- }
+ /* Layout (except tables). */
+ if (box->object) {
+ if (!layout_block_object(box))
+ return false;
- if (b->type == BOX_FLOAT_LEFT || b->type == BOX_FLOAT_RIGHT) {
- assert(b->children);
- if (b->children->type == BOX_BLOCK)
- layout_minmax_block(b->children, font_func);
- else
- layout_minmax_table(b->children, font_func);
- b->min_width = b->children->min_width;
- b->max_width = b->children->max_width;
- if (min < b->min_width)
- min = b->min_width;
- max += b->max_width;
- continue;
- }
+ } else if (box->type == BOX_INLINE_CONTAINER) {
+ box->width = box->parent->width;
+ if (!layout_inline_container(box, box->width, block,
+ cx, cy, content))
+ return false;
- if (b->type == BOX_INLINE_BLOCK) {
- layout_minmax_block(b, font_func);
- if (min < b->min_width)
- min = b->min_width;
- max += b->max_width;
+ } else if (box->type == BOX_TABLE) {
+ /* Move down to avoid floats if necessary. */
+ int x0, x1;
+ struct box *left, *right;
+ y = cy;
+ while (1) {
+ enum css_width_e wtype;
+ css_fixed width = 0;
+ css_unit unit = CSS_UNIT_PX;
- if (b->flags & HAS_HEIGHT)
- *line_has_height = true;
- continue;
- }
+ wtype = css_computed_width(box->style,
+ &width, &unit);
- assert(b->style);
- font_plot_style_from_css(b->style, &fstyle);
+ x0 = cx;
+ x1 = cx + box->parent->width;
+ find_sides(block->float_children, y,
+ y + box->height,
+ &x0, &x1, &left, &right);
+ if (wtype == CSS_WIDTH_AUTO)
+ break;
+ if (box->width <= x1 - x0)
+ break;
+ if (!left && !right)
+ break;
+ else if (!left)
+ y = right->y + right->height + 1;
+ else if (!right)
+ y = left->y + left->height + 1;
+ else if (left->y + left->height <
+ right->y + right->height)
+ y = left->y + left->height + 1;
+ else
+ y = right->y + right->height + 1;
+ }
+ box->x += x0 - cx;
+ cx = x0;
+ box->y += y - cy;
+ cy = y;
+ }
- if (b->type == BOX_INLINE && !b->object &&
- !(b->flags & REPLACE_DIM) &&
- !(b->flags & IFRAME)) {
- fixed = frac = 0;
- calculate_mbp_width(b->style, LEFT, true, true, true,
- &fixed, &frac);
- if (!b->inline_end)
- calculate_mbp_width(b->style, RIGHT,
- true, true, true,
- &fixed, &frac);
- if (0 < fixed)
- max += fixed;
- *line_has_height = true;
- /* \todo update min width, consider fractional extra */
- } else if (b->type == BOX_INLINE_END) {
- fixed = frac = 0;
- calculate_mbp_width(b->inline_end->style, RIGHT,
- true, true, true,
- &fixed, &frac);
- if (0 < fixed)
- max += fixed;
+ /* Advance to next box. */
+ if (box->type == BOX_BLOCK && !box->object && !(box->iframe) &&
+ box->children) {
+ /* Down into children. */
- if (b->next) {
- if (b->space == UNKNOWN_WIDTH) {
- font_func->font_width(&fstyle, " ", 1,
- &b->space);
- }
- max += b->space;
+ if (box == margin_collapse) {
+ /* Current margin collapsed though to this box.
+ * Unset margin_collapse. */
+ margin_collapse = NULL;
}
- *line_has_height = true;
+ y = box->padding[TOP];
+ box = box->children;
+ box->y = y;
+ cy += y;
continue;
+ } else if (box->type == BOX_BLOCK || box->object ||
+ box->flags & IFRAME)
+ cy += box->padding[TOP];
+
+ if (box->type == BOX_BLOCK && box->height == AUTO) {
+ box->height = 0;
+ layout_block_add_scrollbar(box, BOTTOM);
}
- if (!b->object && !(b->flags & IFRAME) && !b->gadget &&
- !(b->flags & REPLACE_DIM)) {
- /* inline non-replaced, 10.3.1 and 10.6.1 */
- bool no_wrap_box;
- if (!b->text)
- continue;
+ cy += box->height + box->padding[BOTTOM] +
+ box->border[BOTTOM].width;
+ cx -= box->x;
+ y = box->y + box->padding[TOP] + box->height +
+ box->padding[BOTTOM] +
+ box->border[BOTTOM].width;
- no_wrap_box = (css_computed_white_space(b->style) ==
- CSS_WHITE_SPACE_NOWRAP ||
- css_computed_white_space(b->style) ==
- CSS_WHITE_SPACE_PRE);
+ advance_to_next_box:
+ if (!box->next) {
+ /* No more siblings:
+ * up to first ancestor with a sibling. */
- if (b->width == UNKNOWN_WIDTH) {
- /** \todo handle errors */
+ do {
+ if (box == margin_collapse) {
+ /* Current margin collapsed though to
+ * this box. Unset margin_collapse. */
+ margin_collapse = NULL;
+ }
- /* If it's a select element, we must use the
- * width of the widest option text */
- if (b->parent->parent->gadget &&
- b->parent->parent->gadget->type
- == GADGET_SELECT) {
- int opt_maxwidth = 0;
- struct form_option *o;
+ /* Apply bottom margin */
+ if (max_pos_margin < box->margin[BOTTOM])
+ max_pos_margin = box->margin[BOTTOM];
+ else if (max_neg_margin < -box->margin[BOTTOM])
+ max_neg_margin = -box->margin[BOTTOM];
- for (o = b->parent->parent->gadget->
- data.select.items; o;
- o = o->next) {
- int opt_width;
- font_func->font_width(&fstyle,
- o->text,
- strlen(o->text),
- &opt_width);
+ box = box->parent;
+ if (box == block)
+ break;
- if (opt_maxwidth < opt_width)
- opt_maxwidth =opt_width;
- }
+ /* Margin is invalidated if this is a box
+ * margins can't collapse through. */
+ if (box->type == BOX_BLOCK &&
+ box->flags & MAKE_HEIGHT) {
+ margin_collapse = NULL;
+ in_margin = false;
+ max_pos_margin = max_neg_margin = 0;
+ }
+
+ if (box->height == AUTO) {
+ box->height = y - box->padding[TOP];
- b->width = opt_maxwidth;
- if (nsoption_bool(core_select_menu))
- b->width += SCROLLBAR_WIDTH;
+ if (box->type == BOX_BLOCK)
+ layout_block_add_scrollbar(box,
+ BOTTOM);
+ } else
+ cy += box->height -
+ (y - box->padding[TOP]);
- } else {
- font_func->font_width(&fstyle, b->text,
- b->length, &b->width);
- b->flags |= MEASURED;
- }
- }
- max += b->width;
- if (b->next) {
- if (b->space == UNKNOWN_WIDTH) {
- font_func->font_width(&fstyle, " ", 1,
- &b->space);
+ /* Apply any min-height and max-height to
+ * boxes in normal flow */
+ if (box->style &&
+ css_computed_position(box->style) !=
+ CSS_POSITION_ABSOLUTE &&
+ layout_apply_minmax_height(box,
+ NULL)) {
+ /* Height altered */
+ /* Set current cy */
+ cy += box->height -
+ (y - box->padding[TOP]);
}
- max += b->space;
- }
-
- if (no_wrap) {
- /* Don't wrap due to block style,
- * so min is the same as max */
- min = max;
- } else if (no_wrap_box) {
- /* This inline box can't be wrapped,
- * for min, consider box's width */
- if (min < b->width)
- min = b->width;
+ cy += box->padding[BOTTOM] +
+ box->border[BOTTOM].width;
+ cx -= box->x;
+ y = box->y + box->padding[TOP] + box->height +
+ box->padding[BOTTOM] +
+ box->border[BOTTOM].width;
- } else if (b->parent->flags & NEED_MIN) {
- /* If we care what the minimum width is,
- * calculate it. (It's only needed if we're
- * shrinking-to-fit.) */
- /* min = widest single word */
- i = 0;
- do {
- for (j = i; j != b->length &&
- b->text[j] != ' '; j++)
- ;
- font_func->font_width(&fstyle,
- b->text + i,
- j - i, &width);
- if (min < width)
- min = width;
- i = j + 1;
- } while (j != b->length);
- }
+ } while (box->next == NULL);
+ if (box == block)
+ break;
+ }
- *line_has_height = true;
+ /* To next sibling. */
- continue;
+ if (box == margin_collapse) {
+ /* Current margin collapsed though to this box.
+ * Unset margin_collapse. */
+ margin_collapse = NULL;
}
- /* inline replaced, 10.3.2 and 10.6.2 */
- assert(b->style);
+ if (max_pos_margin < box->margin[BOTTOM])
+ max_pos_margin = box->margin[BOTTOM];
+ else if (max_neg_margin < -box->margin[BOTTOM])
+ max_neg_margin = -box->margin[BOTTOM];
- /* calculate box width */
- wtype = css_computed_width(b->style, &value, &unit);
- if (wtype == CSS_WIDTH_SET) {
- if (unit == CSS_UNIT_PCT) {
- /*
- b->width = FPCT_OF_INT_TOINT(value, width);
- */
+ box = box->next;
+ box->y = y;
+ }
- width = AUTO;
- } else {
- width = FIXTOINT(nscss_len2px(value, unit,
- b->style));
- if (width < 0)
- width = 0;
- }
- } else {
- width = AUTO;
- }
+ /* Account for bottom margin of last contained block */
+ cy += max_pos_margin - max_neg_margin;
- /* height */
- htype = css_computed_height(b->style, &value, &unit);
- if (htype == CSS_HEIGHT_SET) {
- height = FIXTOINT(nscss_len2px(value, unit, b->style));
- } else {
- height = AUTO;
- }
+ /* Increase height to contain any floats inside (CSS 2.1 10.6.7). */
+ for (box = block->float_children; box; box = box->next_float) {
+ y = box->y + box->height + box->padding[BOTTOM] +
+ box->border[BOTTOM].width + box->margin[BOTTOM];
+ if (cy < y)
+ cy = y;
+ }
- if (b->object || (b->flags & REPLACE_DIM)) {
- if (b->object) {
- int temp_height = height;
- layout_get_object_dimensions(b,
- &width, &temp_height,
- INT_MIN, INT_MAX,
- INT_MIN, INT_MAX);
- }
+ if (block->height == AUTO) {
+ block->height = cy - block->padding[TOP];
+ if (block->type == BOX_BLOCK)
+ layout_block_add_scrollbar(block, BOTTOM);
+ }
- fixed = frac = 0;
- calculate_mbp_width(b->style, LEFT, true, true, true,
- &fixed, &frac);
- calculate_mbp_width(b->style, RIGHT, true, true, true,
- &fixed, &frac);
+ if (block->style && css_computed_position(block->style) !=
+ CSS_POSITION_ABSOLUTE) {
+ /* Block is in normal flow */
+ layout_apply_minmax_height(block, NULL);
+ }
- if (0 < width + fixed)
- width += fixed;
- } else if (b->flags & IFRAME) {
- /* TODO: handle percentage widths properly */
- if (width == AUTO)
- width = 400;
+ if (block->gadget &&
+ (block->gadget->type == GADGET_TEXTAREA ||
+ block->gadget->type == GADGET_PASSWORD ||
+ block->gadget->type == GADGET_TEXTBOX)) {
+ int ta_width = block->padding[LEFT] + block->width +
+ block->padding[RIGHT];
+ int ta_height = block->padding[TOP] + block->height +
+ block->padding[BOTTOM];
+ textarea_set_layout(block->gadget->data.text.ta,
+ ta_width, ta_height,
+ block->padding[TOP], block->padding[RIGHT],
+ block->padding[BOTTOM], block->padding[LEFT]);
+ }
- fixed = frac = 0;
- calculate_mbp_width(b->style, LEFT, true, true, true,
- &fixed, &frac);
- calculate_mbp_width(b->style, RIGHT, true, true, true,
- &fixed, &frac);
+ return true;
+}
- if (0 < width + fixed)
- width += fixed;
- } else {
- /* form control with no object */
- if (width == AUTO)
- width = FIXTOINT(nscss_len2px(INTTOFIX(1),
- CSS_UNIT_EM, b->style));
- }
- if (min < width)
- min = width;
- max += width;
+/**
+ * Calculate line height from a style.
+ */
+static int line_height(const css_computed_style *style)
+{
+ enum css_line_height_e lhtype;
+ css_fixed lhvalue = 0;
+ css_unit lhunit = CSS_UNIT_PX;
+ css_fixed line_height;
- *line_has_height = true;
+ assert(style);
+
+ lhtype = css_computed_line_height(style, &lhvalue, &lhunit);
+ if (lhtype == CSS_LINE_HEIGHT_NORMAL) {
+ /* Normal => use a constant of 1.3 * font-size */
+ lhvalue = FLTTOFIX(1.3);
+ lhtype = CSS_LINE_HEIGHT_NUMBER;
}
- if (first_line) {
- /* todo: handle percentage values properly */
- /* todo: handle text-indent interaction with floats */
- int text_indent = layout_text_indent(
- first->parent->parent->style, 100);
- min = (min + text_indent < 0) ? 0 : min + text_indent;
- max = (max + text_indent < 0) ? 0 : max + text_indent;
+ if (lhtype == CSS_LINE_HEIGHT_NUMBER ||
+ lhunit == CSS_UNIT_PCT) {
+ line_height = nscss_len2px(lhvalue, CSS_UNIT_EM, style);
+
+ if (lhtype != CSS_LINE_HEIGHT_NUMBER)
+ line_height = FDIV(line_height, F_100);
+ } else {
+ assert(lhunit != CSS_UNIT_PCT);
+
+ line_height = nscss_len2px(lhvalue, lhunit, style);
}
- *line_min = min;
- *line_max = max;
+ return FIXTOINT(line_height);
+}
-#ifdef LAYOUT_DEBUG
- LOG("line_min %i, line_max %i", min, max);
-#endif
- assert(b != first);
- assert(0 <= *line_min);
- assert(*line_min <= *line_max);
- return b;
+/**
+ * Layout list markers.
+ */
+static void
+layout_lists(struct box *box,
+ const struct gui_layout_table *font_func)
+{
+ struct box *child;
+ struct box *marker;
+ plot_font_style_t fstyle;
+
+ for (child = box->children; child; child = child->next) {
+ if (child->list_marker) {
+ marker = child->list_marker;
+ if (marker->object) {
+ marker->width =
+ content_get_width(marker->object);
+ marker->x = -marker->width;
+ marker->height =
+ content_get_height(marker->object);
+ marker->y = (line_height(marker->style) -
+ marker->height) / 2;
+ } else if (marker->text) {
+ if (marker->width == UNKNOWN_WIDTH) {
+ font_plot_style_from_css(marker->style,
+ &fstyle);
+ font_func->width(&fstyle,
+ marker->text,
+ marker->length,
+ &marker->width);
+ marker->flags |= MEASURED;
+ }
+ marker->x = -marker->width;
+ marker->y = 0;
+ marker->height = line_height(marker->style);
+ } else {
+ marker->x = 0;
+ marker->y = 0;
+ marker->width = 0;
+ marker->height = 0;
+ }
+ /* Gap between marker and content */
+ marker->x -= 4;
+ }
+ layout_lists(child, font_func);
+ }
}
/**
- * Calculate the text-indent length.
+ * Compute box offsets for a relatively or absolutely positioned box with
+ * respect to a box.
*
- * \param style style of block
- * \param width width of containing block
- * \return length of indent
+ * \param box box to compute offsets for
+ * \param containing_block box to compute percentages with respect to
+ * \param top updated to top offset, or AUTO
+ * \param right updated to right offset, or AUTO
+ * \param bottom updated to bottom offset, or AUTO
+ * \param left updated to left offset, or AUTO
+ *
+ * See CSS 2.1 9.3.2. containing_block must have width and height.
*/
-
-int layout_text_indent(const css_computed_style *style, int width)
+static void
+layout_compute_offsets(struct box *box,
+ struct box *containing_block,
+ int *top,
+ int *right,
+ int *bottom,
+ int *left)
{
+ uint32_t type;
css_fixed value = 0;
css_unit unit = CSS_UNIT_PX;
- css_computed_text_indent(style, &value, &unit);
+ assert(containing_block->width != UNKNOWN_WIDTH &&
+ containing_block->width != AUTO &&
+ containing_block->height != AUTO);
- if (unit == CSS_UNIT_PCT) {
- return FPCT_OF_INT_TOINT(value, width);
+ /* left */
+ type = css_computed_left(box->style, &value, &unit);
+ if (type == CSS_LEFT_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ *left = FPCT_OF_INT_TOINT(value,
+ containing_block->width);
+ } else {
+ *left = FIXTOINT(nscss_len2px(value, unit, box->style));
+ }
} else {
- return FIXTOINT(nscss_len2px(value, unit, style));
+ *left = AUTO;
}
-}
+ /* right */
+ type = css_computed_right(box->style, &value, &unit);
+ if (type == CSS_RIGHT_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ *right = FPCT_OF_INT_TOINT(value,
+ containing_block->width);
+ } else {
+ *right = FIXTOINT(nscss_len2px(value, unit,
+ box->style));
+ }
+ } else {
+ *right = AUTO;
+ }
-/**
- * Layout the contents of a float or inline block.
- *
- * \param b float or inline block box
- * \param width available width
- * \param content memory pool for any new boxes
- * \return true on success, false on memory exhaustion
- */
+ /* top */
+ type = css_computed_top(box->style, &value, &unit);
+ if (type == CSS_TOP_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ *top = FPCT_OF_INT_TOINT(value,
+ containing_block->height);
+ } else {
+ *top = FIXTOINT(nscss_len2px(value, unit, box->style));
+ }
+ } else {
+ *top = AUTO;
+ }
-bool layout_float(struct box *b, int width, html_content *content)
-{
- assert(b->type == BOX_TABLE || b->type == BOX_BLOCK ||
- b->type == BOX_INLINE_BLOCK);
- layout_float_find_dimensions(width, b->style, b);
- if (b->type == BOX_TABLE) {
- if (!layout_table(b, width, content))
- return false;
- if (b->margin[LEFT] == AUTO)
- b->margin[LEFT] = 0;
- if (b->margin[RIGHT] == AUTO)
- b->margin[RIGHT] = 0;
- if (b->margin[TOP] == AUTO)
- b->margin[TOP] = 0;
- if (b->margin[BOTTOM] == AUTO)
- b->margin[BOTTOM] = 0;
- } else
- return layout_block_context(b, -1, content);
- return true;
+ /* bottom */
+ type = css_computed_bottom(box->style, &value, &unit);
+ if (type == CSS_BOTTOM_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ *bottom = FPCT_OF_INT_TOINT(value,
+ containing_block->height);
+ } else {
+ *bottom = FIXTOINT(nscss_len2px(value, unit,
+ box->style));
+ }
+ } else {
+ *bottom = AUTO;
+ }
}
/**
- * Position a float in the first available space.
+ * Layout and position an absolutely positioned box.
*
- * \param c float box to position
- * \param width available width
- * \param cx x coordinate relative to cont to place float right of
- * \param y y coordinate relative to cont to place float below
- * \param cont ancestor box which defines horizontal space, for floats
+ * \param box absolute box to layout and position
+ * \param containing_block containing block
+ * \param cx position of box relative to containing_block
+ * \param cy position of box relative to containing_block
+ * \param content memory pool for any new boxes
+ * \return true on success, false on memory exhaustion
*/
-
-void place_float_below(struct box *c, int width, int cx, int y,
- struct box *cont)
+static bool
+layout_absolute(struct box *box,
+ struct box *containing_block,
+ int cx, int cy,
+ html_content *content)
{
- int x0, x1, yy;
- struct box *left;
- struct box *right;
-
- yy = y > cont->cached_place_below_level ?
- y : cont->cached_place_below_level;
+ int static_left, static_top; /* static position */
+ int top, right, bottom, left;
+ int width, height, max_width, min_width;
+ int *margin = box->margin;
+ int *padding = box->padding;
+ struct box_border *border = box->border;
+ int available_width = containing_block->width;
+ int space;
-#ifdef LAYOUT_DEBUG
- LOG("c %p, width %i, cx %i, y %i, cont %p", c, width, cx, y, cont);
-#endif
+ assert(box->type == BOX_BLOCK || box->type == BOX_TABLE ||
+ box->type == BOX_INLINE_BLOCK);
- do {
- y = yy;
- x0 = cx;
- x1 = cx + width;
- find_sides(cont->float_children, y, y + c->height, &x0, &x1,
- &left, &right);
- if (left != 0 && right != 0) {
- yy = (left->y + left->height <
- right->y + right->height ?
- left->y + left->height :
- right->y + right->height);
- } else if (left == 0 && right != 0) {
- yy = right->y + right->height;
- } else if (left != 0 && right == 0) {
- yy = left->y + left->height;
- }
- } while ((left != 0 || right != 0) && (c->width > x1 - x0));
+ /* The static position is where the box would be if it was not
+ * absolutely positioned. The x and y are filled in by
+ * layout_block_context(). */
+ static_left = cx + box->x;
+ static_top = cy + box->y;
- if (c->type == BOX_FLOAT_LEFT) {
- c->x = x0;
+ if (containing_block->type == BOX_BLOCK ||
+ containing_block->type == BOX_INLINE_BLOCK ||
+ containing_block->type == BOX_TABLE_CELL) {
+ /* Block level container => temporarily increase containing
+ * block dimensions to include padding (we restore this
+ * again at the end) */
+ containing_block->width += containing_block->padding[LEFT] +
+ containing_block->padding[RIGHT];
+ containing_block->height += containing_block->padding[TOP] +
+ containing_block->padding[BOTTOM];
} else {
- c->x = x1 - c->width;
+ /** \todo inline containers */
}
- c->y = y;
- cont->cached_place_below_level = y;
-}
+ layout_compute_offsets(box, containing_block,
+ &top, &right, &bottom, &left);
-/**
- * Layout a table.
- *
- * \param table table to layout
- * \param available_width width of containing block
- * \param content memory pool for any new boxes
- * \return true on success, false on memory exhaustion
- */
-
-bool layout_table(struct box *table, int available_width,
- html_content *content)
-{
- unsigned int columns = table->columns; /* total columns */
- unsigned int i;
- unsigned int *row_span;
- int *excess_y;
- int table_width, min_width = 0, max_width = 0;
- int required_width = 0;
- int x, remainder = 0, count = 0;
- int table_height = 0;
- int min_height = 0;
- int *xs; /* array of column x positions */
- int auto_width;
- int spare_width;
- int relative_sum = 0;
- int border_spacing_h = 0, border_spacing_v = 0;
- int spare_height;
- int positioned_columns = 0;
- struct box *containing_block = NULL;
- struct box *c;
- struct box *row;
- struct box *row_group;
- struct box **row_span_cell;
- struct column *col;
- const css_computed_style *style = table->style;
- enum css_width_e wtype;
- enum css_height_e htype;
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
+ /* Pass containing block into layout_find_dimensions via the float
+ * containing block box member. This is unused for absolutely positioned
+ * boxes because a box can't be floated and absolutely positioned. */
+ box->float_container = containing_block;
+ layout_find_dimensions(available_width, -1, box, box->style,
+ &width, &height, &max_width, &min_width,
+ 0, 0, margin, padding, border);
+ box->float_container = NULL;
- assert(table->type == BOX_TABLE);
- assert(style);
- assert(table->children && table->children->children);
- assert(columns);
+ /* 10.3.7 */
+#ifdef LAYOUT_DEBUG
+ LOG("%i + %i + %i + %i + %i + %i + %i + %i + %i = %i", left, margin[LEFT], border[LEFT].width, padding[LEFT], width, padding[RIGHT], border[RIGHT].width, margin[RIGHT], right, containing_block->width);
+#endif
- /* allocate working buffers */
- col = malloc(columns * sizeof col[0]);
- excess_y = malloc(columns * sizeof excess_y[0]);
- row_span = malloc(columns * sizeof row_span[0]);
- row_span_cell = malloc(columns * sizeof row_span_cell[0]);
- xs = malloc((columns + 1) * sizeof xs[0]);
- if (!col || !xs || !row_span || !excess_y || !row_span_cell) {
- free(col);
- free(excess_y);
- free(row_span);
- free(row_span_cell);
- free(xs);
- return false;
- }
+ if (left == AUTO && width == AUTO && right == AUTO) {
+ if (margin[LEFT] == AUTO)
+ margin[LEFT] = 0;
+ if (margin[RIGHT] == AUTO)
+ margin[RIGHT] = 0;
+ left = static_left;
- memcpy(col, table->col, sizeof(col[0]) * columns);
+ width = min(max(box->min_width, available_width),
+ box->max_width);
+ width -= box->margin[LEFT] + box->border[LEFT].width +
+ box->padding[LEFT] + box->padding[RIGHT] +
+ box->border[RIGHT].width + box->margin[RIGHT];
- /* find margins, paddings, and borders for table and cells */
- layout_find_dimensions(available_width, -1, table, style, 0, 0, 0, 0,
- 0, 0, table->margin, table->padding, table->border);
- for (row_group = table->children; row_group;
- row_group = row_group->next) {
- for (row = row_group->children; row; row = row->next) {
- for (c = row->children; c; c = c->next) {
- enum css_overflow_e overflow_x;
- enum css_overflow_e overflow_y;
+ /* Adjust for {min|max}-width */
+ if (max_width >= 0 && width > max_width) width = max_width;
+ if (min_width > 0 && width < min_width) width = min_width;
- assert(c->style);
- table_used_border_for_cell(c);
- layout_find_dimensions(available_width, -1,
- c, c->style, 0, 0, 0, 0, 0, 0,
- 0, c->padding, c->border);
+ right = containing_block->width -
+ left -
+ margin[LEFT] - border[LEFT].width - padding[LEFT] -
+ width -
+ padding[RIGHT] - border[RIGHT].width - margin[RIGHT];
+ } else if (left != AUTO && width != AUTO && right != AUTO) {
- overflow_x = css_computed_overflow_x(c->style);
- overflow_y = css_computed_overflow_y(c->style);
+ /* Adjust for {min|max}-width */
+ if (max_width >= 0 && width > max_width) width = max_width;
+ if (min_width > 0 && width < min_width) width = min_width;
- if (overflow_x == CSS_OVERFLOW_SCROLL ||
- overflow_x ==
- CSS_OVERFLOW_AUTO) {
- c->padding[BOTTOM] += SCROLLBAR_WIDTH;
- }
- if (overflow_y == CSS_OVERFLOW_SCROLL ||
- overflow_y ==
- CSS_OVERFLOW_AUTO) {
- c->padding[RIGHT] += SCROLLBAR_WIDTH;
- }
+ if (margin[LEFT] == AUTO && margin[RIGHT] == AUTO) {
+ space = containing_block->width -
+ left - border[LEFT].width -
+ padding[LEFT] - width - padding[RIGHT] -
+ border[RIGHT].width - right;
+ if (space < 0) {
+ margin[LEFT] = 0;
+ margin[RIGHT] = space;
+ } else {
+ margin[LEFT] = margin[RIGHT] = space / 2;
}
+ } else if (margin[LEFT] == AUTO) {
+ margin[LEFT] = containing_block->width -
+ left - border[LEFT].width -
+ padding[LEFT] - width - padding[RIGHT] -
+ border[RIGHT].width - margin[RIGHT] -
+ right;
+ } else if (margin[RIGHT] == AUTO) {
+ margin[RIGHT] = containing_block->width -
+ left - margin[LEFT] -
+ border[LEFT].width -
+ padding[LEFT] - width - padding[RIGHT] -
+ border[RIGHT].width - right;
+ } else {
+ right = containing_block->width -
+ left - margin[LEFT] -
+ border[LEFT].width -
+ padding[LEFT] - width - padding[RIGHT] -
+ border[RIGHT].width - margin[RIGHT];
}
- }
+ } else {
+ if (margin[LEFT] == AUTO)
+ margin[LEFT] = 0;
+ if (margin[RIGHT] == AUTO)
+ margin[RIGHT] = 0;
- /* border-spacing is used in the separated borders model */
- if (css_computed_border_collapse(style) ==
- CSS_BORDER_COLLAPSE_SEPARATE) {
- css_fixed h = 0, v = 0;
- css_unit hu = CSS_UNIT_PX, vu = CSS_UNIT_PX;
+ if (left == AUTO && width == AUTO && right != AUTO) {
+ available_width -= right;
- css_computed_border_spacing(style, &h, &hu, &v, &vu);
+ width = min(max(box->min_width, available_width),
+ box->max_width);
+ width -= box->margin[LEFT] + box->border[LEFT].width +
+ box->padding[LEFT] + box->padding[RIGHT] +
+ box->border[RIGHT].width + box->margin[RIGHT];
- border_spacing_h = FIXTOINT(nscss_len2px(h, hu, style));
- border_spacing_v = FIXTOINT(nscss_len2px(v, vu, style));
- }
+ /* Adjust for {min|max}-width */
+ if (max_width >= 0 && width > max_width)
+ width = max_width;
+ if (min_width > 0 && width < min_width)
+ width = min_width;
- /* find specified table width, or available width if auto-width */
- wtype = css_computed_width(style, &value, &unit);
- if (wtype == CSS_WIDTH_SET) {
- if (unit == CSS_UNIT_PCT) {
- table_width = FPCT_OF_INT_TOINT(value, available_width);
- } else {
- table_width =
- FIXTOINT(nscss_len2px(value, unit, style));
- }
+ left = containing_block->width -
+ margin[LEFT] - border[LEFT].width -
+ padding[LEFT] - width - padding[RIGHT] -
+ border[RIGHT].width - margin[RIGHT] -
+ right;
+ } else if (left == AUTO && width != AUTO && right == AUTO) {
- /* specified width includes border */
- table_width -= table->border[LEFT].width +
- table->border[RIGHT].width;
- table_width = table_width < 0 ? 0 : table_width;
+ /* Adjust for {min|max}-width */
+ if (max_width >= 0 && width > max_width)
+ width = max_width;
+ if (min_width > 0 && width < min_width)
+ width = min_width;
- auto_width = table_width;
- } else {
- table_width = AUTO;
- auto_width = available_width -
- ((table->margin[LEFT] == AUTO ? 0 :
- table->margin[LEFT]) +
- table->border[LEFT].width +
- table->padding[LEFT] +
- table->padding[RIGHT] +
- table->border[RIGHT].width +
- (table->margin[RIGHT] == AUTO ? 0 :
- table->margin[RIGHT]));
- }
+ left = static_left;
+ right = containing_block->width -
+ left - margin[LEFT] -
+ border[LEFT].width -
+ padding[LEFT] - width - padding[RIGHT] -
+ border[RIGHT].width - margin[RIGHT];
+ } else if (left != AUTO && width == AUTO && right == AUTO) {
+ available_width -= left;
- /* Find any table height specified within CSS/HTML */
- htype = css_computed_height(style, &value, &unit);
- if (htype == CSS_HEIGHT_SET) {
- if (unit == CSS_UNIT_PCT) {
- /* This is the minimum height for the table
- * (see 17.5.3) */
- if (css_computed_position(table->style) ==
- CSS_POSITION_ABSOLUTE) {
- /* Table is absolutely positioned */
- assert(table->float_container);
- containing_block = table->float_container;
- } else if (table->float_container &&
- css_computed_position(table->style) !=
- CSS_POSITION_ABSOLUTE &&
- (css_computed_float(table->style) ==
- CSS_FLOAT_LEFT ||
- css_computed_float(table->style) ==
- CSS_FLOAT_RIGHT)) {
- /* Table is a float */
- assert(table->parent && table->parent->parent &&
- table->parent->parent->parent);
- containing_block =
- table->parent->parent->parent;
- } else if (table->parent && table->parent->type !=
- BOX_INLINE_CONTAINER) {
- /* Table is a block level element */
- containing_block = table->parent;
- } else if (table->parent && table->parent->type ==
- BOX_INLINE_CONTAINER) {
- /* Table is an inline block */
- assert(table->parent->parent);
- containing_block = table->parent->parent;
- }
+ width = min(max(box->min_width, available_width),
+ box->max_width);
+ width -= box->margin[LEFT] + box->border[LEFT].width +
+ box->padding[LEFT] + box->padding[RIGHT] +
+ box->border[RIGHT].width + box->margin[RIGHT];
- if (containing_block) {
- css_fixed ignored = 0;
+ /* Adjust for {min|max}-width */
+ if (max_width >= 0 && width > max_width)
+ width = max_width;
+ if (min_width > 0 && width < min_width)
+ width = min_width;
- htype = css_computed_height(
- containing_block->style,
- &ignored, &unit);
- }
+ right = containing_block->width -
+ left - margin[LEFT] -
+ border[LEFT].width -
+ padding[LEFT] - width - padding[RIGHT] -
+ border[RIGHT].width - margin[RIGHT];
+ } else if (left == AUTO && width != AUTO && right != AUTO) {
- if (containing_block &&
- containing_block->height != AUTO &&
- (css_computed_position(table->style) ==
- CSS_POSITION_ABSOLUTE ||
- htype == CSS_HEIGHT_SET)) {
- /* Table is absolutely positioned or its
- * containing block has a valid specified
- * height. (CSS 2.1 Section 10.5) */
- min_height = FPCT_OF_INT_TOINT(value,
- containing_block->height);
- }
- } else {
- /* This is the minimum height for the table
- * (see 17.5.3) */
- min_height = FIXTOINT(nscss_len2px(value, unit, style));
- }
- }
+ /* Adjust for {min|max}-width */
+ if (max_width >= 0 && width > max_width)
+ width = max_width;
+ if (min_width > 0 && width < min_width)
+ width = min_width;
- /* calculate width required by cells */
- for (i = 0; i != columns; i++) {
-#ifdef LAYOUT_DEBUG
- LOG("table %p, column %u: type %s, width %i, min %i, max %i", table, i, ((const char *[]){
- "UNKNOWN",
- "FIXED",
- "AUTO",
- "PERCENT",
- "RELATIVE"
- })[col[i].type], col[i].width, col[i].min, col[i].max);
-#endif
+ left = containing_block->width -
+ margin[LEFT] - border[LEFT].width -
+ padding[LEFT] - width - padding[RIGHT] -
+ border[RIGHT].width - margin[RIGHT] -
+ right;
+ } else if (left != AUTO && width == AUTO && right != AUTO) {
+ width = containing_block->width -
+ left - margin[LEFT] -
+ border[LEFT].width -
+ padding[LEFT] - padding[RIGHT] -
+ border[RIGHT].width - margin[RIGHT] -
+ right;
- if (col[i].positioned) {
- positioned_columns++;
- continue;
- } else if (col[i].type == COLUMN_WIDTH_FIXED) {
- if (col[i].width < col[i].min)
- col[i].width = col[i].max = col[i].min;
- else
- col[i].min = col[i].max = col[i].width;
- required_width += col[i].width;
- } else if (col[i].type == COLUMN_WIDTH_PERCENT) {
- int width = col[i].width * auto_width / 100;
- required_width += col[i].min < width ? width :
- col[i].min;
- } else
- required_width += col[i].min;
+ /* Adjust for {min|max}-width */
+ if (max_width >= 0 && width > max_width)
+ width = max_width;
+ if (min_width > 0 && width < min_width)
+ width = min_width;
-#ifdef LAYOUT_DEBUG
- LOG("required_width %i", required_width);
-#endif
+ } else if (left != AUTO && width != AUTO && right == AUTO) {
+
+ /* Adjust for {min|max}-width */
+ if (max_width >= 0 && width > max_width)
+ width = max_width;
+ if (min_width > 0 && width < min_width)
+ width = min_width;
+
+ right = containing_block->width -
+ left - margin[LEFT] -
+ border[LEFT].width -
+ padding[LEFT] - width - padding[RIGHT] -
+ border[RIGHT].width - margin[RIGHT];
+ }
}
- required_width += (columns + 1 - positioned_columns) *
- border_spacing_h;
#ifdef LAYOUT_DEBUG
- LOG("width %i, min %i, max %i, auto %i, required %i", table_width, table->min_width, table->max_width, auto_width, required_width);
+ LOG("%i + %i + %i + %i + %i + %i + %i + %i + %i = %i", left, margin[LEFT], border[LEFT].width, padding[LEFT], width, padding[RIGHT], border[RIGHT].width, margin[RIGHT], right, containing_block->width);
#endif
- if (auto_width < required_width) {
- /* table narrower than required width for columns:
- * treat percentage widths as maximums */
- for (i = 0; i != columns; i++) {
- if (col[i].type == COLUMN_WIDTH_RELATIVE)
- continue;
- if (col[i].type == COLUMN_WIDTH_PERCENT) {
- col[i].max = auto_width * col[i].width / 100;
- if (col[i].max < col[i].min)
- col[i].max = col[i].min;
- }
- min_width += col[i].min;
- max_width += col[i].max;
- }
+ box->x = left + margin[LEFT] + border[LEFT].width - cx;
+ if (containing_block->type == BOX_BLOCK ||
+ containing_block->type == BOX_INLINE_BLOCK ||
+ containing_block->type == BOX_TABLE_CELL) {
+ /* Block-level ancestor => reset container's width */
+ containing_block->width -= containing_block->padding[LEFT] +
+ containing_block->padding[RIGHT];
} else {
- /* take percentages exactly */
- for (i = 0; i != columns; i++) {
- if (col[i].type == COLUMN_WIDTH_RELATIVE)
- continue;
- if (col[i].type == COLUMN_WIDTH_PERCENT) {
- int width = auto_width * col[i].width / 100;
- if (width < col[i].min)
- width = col[i].min;
- col[i].min = col[i].width = col[i].max = width;
- col[i].type = COLUMN_WIDTH_FIXED;
- }
- min_width += col[i].min;
- max_width += col[i].max;
- }
+ /** \todo inline ancestors */
}
+ box->width = width;
+ box->height = height;
- /* allocate relative widths */
- spare_width = auto_width;
- for (i = 0; i != columns; i++) {
- if (col[i].type == COLUMN_WIDTH_RELATIVE)
- relative_sum += col[i].width;
- else if (col[i].type == COLUMN_WIDTH_FIXED)
- spare_width -= col[i].width;
- else
- spare_width -= col[i].min;
- }
- spare_width -= (columns + 1) * border_spacing_h;
- if (relative_sum != 0) {
- if (spare_width < 0)
- spare_width = 0;
- for (i = 0; i != columns; i++) {
- if (col[i].type == COLUMN_WIDTH_RELATIVE) {
- col[i].min = ceil(col[i].max =
- (float) spare_width
- * (float) col[i].width
- / relative_sum);
- min_width += col[i].min;
- max_width += col[i].max;
- }
- }
+ if (box->type == BOX_BLOCK || box->type == BOX_INLINE_BLOCK ||
+ box->object || box->flags & IFRAME) {
+ if (!layout_block_context(box, -1, content))
+ return false;
+ } else if (box->type == BOX_TABLE) {
+ /* layout_table also expects the containing block to be
+ * stored in the float_container field */
+ box->float_container = containing_block;
+ /* \todo layout_table considers margins etc. again */
+ if (!layout_table(box, width, content))
+ return false;
+ box->float_container = NULL;
+ layout_solve_width(box, box->parent->width, box->width, 0, 0,
+ -1, -1);
}
- min_width += (columns + 1) * border_spacing_h;
- max_width += (columns + 1) * border_spacing_h;
- if (auto_width <= min_width) {
- /* not enough space: minimise column widths */
- for (i = 0; i < columns; i++) {
- col[i].width = col[i].min;
- }
- table_width = min_width;
- } else if (max_width <= auto_width) {
- /* more space than maximum width */
- if (table_width == AUTO) {
- /* for auto-width tables, make columns max width */
- for (i = 0; i < columns; i++) {
- col[i].width = col[i].max;
- }
- table_width = max_width;
- } else {
- /* for fixed-width tables, distribute the extra space
- * too */
- unsigned int flexible_columns = 0;
- for (i = 0; i != columns; i++)
- if (col[i].type != COLUMN_WIDTH_FIXED)
- flexible_columns++;
- if (flexible_columns == 0) {
- int extra = (table_width - max_width) / columns;
- remainder = (table_width - max_width) -
- (extra * columns);
- for (i = 0; i != columns; i++) {
- col[i].width = col[i].max + extra;
- count -= remainder;
- if (count < 0) {
- col[i].width++;
- count += columns;
- }
- }
+ /* 10.6.4 */
+#ifdef LAYOUT_DEBUG
+ LOG("%i + %i + %i + %i + %i + %i + %i + %i + %i = %i", top, margin[TOP], border[TOP].width, padding[TOP], height, padding[BOTTOM], border[BOTTOM].width, margin[BOTTOM], bottom, containing_block->height);
+#endif
- } else {
- int extra = (table_width - max_width) /
- flexible_columns;
- remainder = (table_width - max_width) -
- (extra * flexible_columns);
- for (i = 0; i != columns; i++)
- if (col[i].type != COLUMN_WIDTH_FIXED) {
- col[i].width = col[i].max +
- extra;
- count -= remainder;
- if (count < 0) {
- col[i].width++;
- count += flexible_columns;
- }
- }
- }
+ if (top == AUTO && height == AUTO && bottom == AUTO) {
+ top = static_top;
+ height = box->height;
+ if (margin[TOP] == AUTO)
+ margin[TOP] = 0;
+ if (margin[BOTTOM] == AUTO)
+ margin[BOTTOM] = 0;
+ bottom = containing_block->height -
+ top - margin[TOP] - border[TOP].width -
+ padding[TOP] - height - padding[BOTTOM] -
+ border[BOTTOM].width - margin[BOTTOM];
+ } else if (top != AUTO && height != AUTO && bottom != AUTO) {
+ if (margin[TOP] == AUTO && margin[BOTTOM] == AUTO) {
+ space = containing_block->height -
+ top - border[TOP].width - padding[TOP] -
+ height - padding[BOTTOM] -
+ border[BOTTOM].width - bottom;
+ margin[TOP] = margin[BOTTOM] = space / 2;
+ } else if (margin[TOP] == AUTO) {
+ margin[TOP] = containing_block->height -
+ top - border[TOP].width - padding[TOP] -
+ height - padding[BOTTOM] -
+ border[BOTTOM].width - margin[BOTTOM] -
+ bottom;
+ } else if (margin[BOTTOM] == AUTO) {
+ margin[BOTTOM] = containing_block->height -
+ top - margin[TOP] - border[TOP].width -
+ padding[TOP] - height -
+ padding[BOTTOM] - border[BOTTOM].width -
+ bottom;
+ } else {
+ bottom = containing_block->height -
+ top - margin[TOP] - border[TOP].width -
+ padding[TOP] - height -
+ padding[BOTTOM] - border[BOTTOM].width -
+ margin[BOTTOM];
}
} else {
- /* space between min and max: fill it exactly */
- float scale = (float) (auto_width - min_width) /
- (float) (max_width - min_width);
- /* fprintf(stderr, "filling, scale %f\n", scale); */
- for (i = 0; i < columns; i++) {
- col[i].width = col[i].min + (int) (0.5 +
- (col[i].max - col[i].min) * scale);
+ if (margin[TOP] == AUTO)
+ margin[TOP] = 0;
+ if (margin[BOTTOM] == AUTO)
+ margin[BOTTOM] = 0;
+ if (top == AUTO && height == AUTO && bottom != AUTO) {
+ height = box->height;
+ top = containing_block->height -
+ margin[TOP] - border[TOP].width -
+ padding[TOP] - height -
+ padding[BOTTOM] - border[BOTTOM].width -
+ margin[BOTTOM] - bottom;
+ } else if (top == AUTO && height != AUTO && bottom == AUTO) {
+ top = static_top;
+ bottom = containing_block->height -
+ top - margin[TOP] - border[TOP].width -
+ padding[TOP] - height -
+ padding[BOTTOM] - border[BOTTOM].width -
+ margin[BOTTOM];
+ } else if (top != AUTO && height == AUTO && bottom == AUTO) {
+ height = box->height;
+ bottom = containing_block->height -
+ top - margin[TOP] - border[TOP].width -
+ padding[TOP] - height -
+ padding[BOTTOM] - border[BOTTOM].width -
+ margin[BOTTOM];
+ } else if (top == AUTO && height != AUTO && bottom != AUTO) {
+ top = containing_block->height -
+ margin[TOP] - border[TOP].width -
+ padding[TOP] - height -
+ padding[BOTTOM] - border[BOTTOM].width -
+ margin[BOTTOM] - bottom;
+ } else if (top != AUTO && height == AUTO && bottom != AUTO) {
+ height = containing_block->height -
+ top - margin[TOP] - border[TOP].width -
+ padding[TOP] - padding[BOTTOM] -
+ border[BOTTOM].width - margin[BOTTOM] -
+ bottom;
+ } else if (top != AUTO && height != AUTO && bottom == AUTO) {
+ bottom = containing_block->height -
+ top - margin[TOP] - border[TOP].width -
+ padding[TOP] - height -
+ padding[BOTTOM] - border[BOTTOM].width -
+ margin[BOTTOM];
}
- table_width = auto_width;
}
- xs[0] = x = border_spacing_h;
- for (i = 0; i != columns; i++) {
- if (!col[i].positioned)
- x += col[i].width + border_spacing_h;
- xs[i + 1] = x;
- row_span[i] = 0;
- excess_y[i] = 0;
- row_span_cell[i] = 0;
+#ifdef LAYOUT_DEBUG
+ LOG("%i + %i + %i + %i + %i + %i + %i + %i + %i = %i", top, margin[TOP], border[TOP].width, padding[TOP], height, padding[BOTTOM], border[BOTTOM].width, margin[BOTTOM], bottom, containing_block->height);
+#endif
+
+ box->y = top + margin[TOP] + border[TOP].width - cy;
+ if (containing_block->type == BOX_BLOCK ||
+ containing_block->type == BOX_INLINE_BLOCK ||
+ containing_block->type == BOX_TABLE_CELL) {
+ /* Block-level ancestor => reset container's height */
+ containing_block->height -= containing_block->padding[TOP] +
+ containing_block->padding[BOTTOM];
+ } else {
+ /** \todo Inline ancestors */
}
+ box->height = height;
+ layout_apply_minmax_height(box, containing_block);
- /* position cells */
- table_height = border_spacing_v;
- for (row_group = table->children; row_group;
- row_group = row_group->next) {
- int row_group_height = 0;
- for (row = row_group->children; row; row = row->next) {
- int row_height = 0;
-
- htype = css_computed_height(row->style, &value, &unit);
- if (htype == CSS_HEIGHT_SET && unit != CSS_UNIT_PCT) {
- row_height = FIXTOINT(nscss_len2px(value, unit,
- row->style));
- }
- for (c = row->children; c; c = c->next) {
- assert(c->style);
- c->width = xs[c->start_column + c->columns] -
- xs[c->start_column] -
- border_spacing_h -
- c->border[LEFT].width -
- c->padding[LEFT] -
- c->padding[RIGHT] -
- c->border[RIGHT].width;
- c->float_children = 0;
- c->cached_place_below_level = 0;
+ return true;
+}
- c->height = AUTO;
- if (!layout_block_context(c, -1, content)) {
- free(col);
- free(excess_y);
- free(row_span);
- free(row_span_cell);
- free(xs);
- return false;
- }
- /* warning: c->descendant_y0 and
- * c->descendant_y1 used as temporary storage
- * until after vertical alignment is complete */
- c->descendant_y0 = c->height;
- c->descendant_y1 = c->padding[BOTTOM];
- htype = css_computed_height(c->style,
- &value, &unit);
+/**
+ * Recursively layout and position absolutely positioned boxes.
+ *
+ * \param box tree of boxes to layout
+ * \param containing_block current containing block
+ * \param cx position of box relative to containing_block
+ * \param cy position of box relative to containing_block
+ * \param content memory pool for any new boxes
+ * \return true on success, false on memory exhaustion
+ */
+static bool
+layout_position_absolute(struct box *box,
+ struct box *containing_block,
+ int cx, int cy,
+ html_content *content)
+{
+ struct box *c;
- if (htype == CSS_HEIGHT_SET &&
- unit != CSS_UNIT_PCT) {
- /* some sites use height="1" or similar
- * to attempt to make cells as small as
- * possible, so treat it as a minimum */
- int h = FIXTOINT(nscss_len2px(value,
- unit, c->style));
- if (c->height < h)
- c->height = h;
- }
- /* specified row height is treated as a minimum
- */
- if (c->height < row_height)
- c->height = row_height;
- c->x = xs[c->start_column] +
- c->border[LEFT].width;
- c->y = c->border[TOP].width;
- for (i = 0; i != c->columns; i++) {
- row_span[c->start_column + i] = c->rows;
- excess_y[c->start_column + i] =
- c->border[TOP].width +
- c->padding[TOP] +
- c->height +
- c->padding[BOTTOM] +
- c->border[BOTTOM].width;
- row_span_cell[c->start_column + i] = 0;
+ for (c = box->children; c; c = c->next) {
+ if ((c->type == BOX_BLOCK || c->type == BOX_TABLE ||
+ c->type == BOX_INLINE_BLOCK) &&
+ (css_computed_position(c->style) ==
+ CSS_POSITION_ABSOLUTE ||
+ css_computed_position(c->style) ==
+ CSS_POSITION_FIXED)) {
+ if (!layout_absolute(c, containing_block,
+ cx, cy, content))
+ return false;
+ if (!layout_position_absolute(c, c, 0, 0, content))
+ return false;
+ } else if (c->style && css_computed_position(c->style) ==
+ CSS_POSITION_RELATIVE) {
+ if (!layout_position_absolute(c, c, 0, 0, content))
+ return false;
+ } else {
+ int px, py;
+ if (c->style && (css_computed_float(c->style) ==
+ CSS_FLOAT_LEFT ||
+ css_computed_float(c->style) ==
+ CSS_FLOAT_RIGHT)) {
+ /* Float x/y coords are relative to nearest
+ * ansestor with float_children, rather than
+ * relative to parent. Need to get x/y relative
+ * to parent */
+ struct box *p;
+ px = c->x;
+ py = c->y;
+ for (p = box->parent; p && !p->float_children;
+ p = p->parent) {
+ px -= p->x;
+ py -= p->y;
}
- row_span_cell[c->start_column] = c;
- c->padding[BOTTOM] = -border_spacing_v -
- c->border[TOP].width -
- c->padding[TOP] -
- c->height -
- c->border[BOTTOM].width;
- }
- for (i = 0; i != columns; i++)
- if (row_span[i] != 0)
- row_span[i]--;
- else
- row_span_cell[i] = 0;
- if (row->next || row_group->next) {
- /* row height is greatest excess of a cell
- * which ends in this row */
- for (i = 0; i != columns; i++)
- if (row_span[i] == 0 && row_height <
- excess_y[i])
- row_height = excess_y[i];
} else {
- /* except in the last row */
- for (i = 0; i != columns; i++)
- if (row_height < excess_y[i])
- row_height = excess_y[i];
- }
- for (i = 0; i != columns; i++) {
- if (row_height < excess_y[i])
- excess_y[i] -= row_height;
- else
- excess_y[i] = 0;
- if (row_span_cell[i] != 0)
- row_span_cell[i]->padding[BOTTOM] +=
- row_height +
- border_spacing_v;
+ /* Not a float, so box x/y coords are relative
+ * to parent */
+ px = c->x;
+ py = c->y;
}
-
- row->x = 0;
- row->y = row_group_height;
- row->width = table_width;
- row->height = row_height;
- row_group_height += row_height + border_spacing_v;
+ if (!layout_position_absolute(c, containing_block,
+ cx + px, cy + py, content))
+ return false;
}
- row_group->x = 0;
- row_group->y = table_height;
- row_group->width = table_width;
- row_group->height = row_group_height;
- table_height += row_group_height;
}
- /* Table height is either the height of the contents, or specified
- * height if greater */
- table_height = max(table_height, min_height);
- /** \todo distribute spare height over the row groups / rows / cells */
- /* perform vertical alignment */
- for (row_group = table->children; row_group;
- row_group = row_group->next) {
- for (row = row_group->children; row; row = row->next) {
- for (c = row->children; c; c = c->next) {
- enum css_vertical_align_e vertical_align;
+ return true;
+}
- /* unextended bottom padding is in
- * c->descendant_y1, and unextended
- * cell height is in c->descendant_y0 */
- spare_height = (c->padding[BOTTOM] -
- c->descendant_y1) +
- (c->height - c->descendant_y0);
- vertical_align = css_computed_vertical_align(
- c->style, &value, &unit);
+/**
+ * Compute a box's relative offset as per CSS 2.1 9.4.3
+ *
+ * \param box Box to compute relative offsets for.
+ * \param x Receives relative offset in x.
+ * \param y Receives relative offset in y.
+ */
+static void layout_compute_relative_offset(struct box *box, int *x, int *y)
+{
+ int left, right, top, bottom;
+ struct box *containing_block;
- switch (vertical_align) {
- case CSS_VERTICAL_ALIGN_SUB:
- case CSS_VERTICAL_ALIGN_SUPER:
- case CSS_VERTICAL_ALIGN_TEXT_TOP:
- case CSS_VERTICAL_ALIGN_TEXT_BOTTOM:
- case CSS_VERTICAL_ALIGN_SET:
- case CSS_VERTICAL_ALIGN_BASELINE:
- /* todo: baseline alignment, for now
- * just use ALIGN_TOP */
- case CSS_VERTICAL_ALIGN_TOP:
- break;
- case CSS_VERTICAL_ALIGN_MIDDLE:
- c->padding[TOP] += spare_height / 2;
- c->padding[BOTTOM] -= spare_height / 2;
- layout_move_children(c, 0,
- spare_height / 2);
- break;
- case CSS_VERTICAL_ALIGN_BOTTOM:
- c->padding[TOP] += spare_height;
- c->padding[BOTTOM] -= spare_height;
- layout_move_children(c, 0,
- spare_height);
- break;
- case CSS_VERTICAL_ALIGN_INHERIT:
- assert(0);
- break;
- }
- }
+ assert(box && box->parent && box->style &&
+ css_computed_position(box->style) ==
+ CSS_POSITION_RELATIVE);
+
+ if (box->float_container &&
+ (css_computed_float(box->style) == CSS_FLOAT_LEFT ||
+ css_computed_float(box->style) == CSS_FLOAT_RIGHT)) {
+ containing_block = box->float_container;
+ } else {
+ containing_block = box->parent;
+ }
+
+ layout_compute_offsets(box, containing_block,
+ &top, &right, &bottom, &left);
+
+ if (left == AUTO && right == AUTO)
+ left = right = 0;
+ else if (left == AUTO)
+ /* left is auto => computed = -right */
+ left = -right;
+ else if (right == AUTO)
+ /* right is auto => computed = -left */
+ right = -left;
+ else {
+ /* over constrained => examine direction property
+ * of containing block */
+ if (containing_block->style &&
+ css_computed_direction(
+ containing_block->style) ==
+ CSS_DIRECTION_RTL) {
+ /* right wins */
+ left = -right;
+ } else {
+ /* assume LTR in all other cases */
+ right = -left;
}
}
- /* Top and bottom margins of 'auto' are set to 0. CSS2.1 10.6.3 */
- if (table->margin[TOP] == AUTO)
- table->margin[TOP] = 0;
- if (table->margin[BOTTOM] == AUTO)
- table->margin[BOTTOM] = 0;
+ assert(left == -right);
- free(col);
- free(excess_y);
- free(row_span);
- free(row_span_cell);
- free(xs);
+ if (top == AUTO && bottom == AUTO) {
+ top = bottom = 0;
+ } else if (top == AUTO) {
+ top = -bottom;
+ } else {
+ /* bottom is AUTO, or neither are AUTO */
+ bottom = -top;
+ }
- table->width = table_width;
- table->height = table_height;
+#ifdef LAYOUT_DEBUG
+ LOG("left %i, right %i, top %i, bottom %i", left, right, top, bottom);
+#endif
- return true;
+ *x = left;
+ *y = top;
}
/**
- * Calculate minimum and maximum width of a table.
+ * Adjust positions of relatively positioned boxes.
*
- * \param table box of type TABLE
- * \param font_func Font functions
- * \post table->min_width and table->max_width filled in,
- * 0 <= table->min_width <= table->max_width
+ * \param root box to adjust the position of
+ * \param fp box which forms the block formatting context for children of
+ * "root" which are floats
+ * \param fx x offset due to intervening relatively positioned boxes
+ * between current box, "root", and the block formatting context
+ * box, "fp", for float children of "root"
+ * \param fy y offset due to intervening relatively positioned boxes
+ * between current box, "root", and the block formatting context
+ * box, "fp", for float children of "root"
*/
-
-void layout_minmax_table(struct box *table,
- const struct font_functions *font_func)
+static void
+layout_position_relative(struct box *root, struct box *fp, int fx, int fy)
{
- unsigned int i, j;
- int border_spacing_h = 0;
- int table_min = 0, table_max = 0;
- int extra_fixed = 0;
- float extra_frac = 0;
- struct column *col = table->col;
- struct box *row_group, *row, *cell;
- enum css_width_e wtype;
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
-
- /* check if the widths have already been calculated */
- if (table->max_width != UNKNOWN_MAX_WIDTH)
- return;
-
- /* start with 0 except for fixed-width columns */
- for (i = 0; i != table->columns; i++) {
- if (col[i].type == COLUMN_WIDTH_FIXED)
- col[i].min = col[i].max = col[i].width;
- else
- col[i].min = col[i].max = 0;
- }
-
- /* border-spacing is used in the separated borders model */
- if (css_computed_border_collapse(table->style) ==
- CSS_BORDER_COLLAPSE_SEPARATE) {
- css_fixed h = 0, v = 0;
- css_unit hu = CSS_UNIT_PX, vu = CSS_UNIT_PX;
+ struct box *box; /* for children of "root" */
+ struct box *fn; /* for block formatting context box for children of
+ * "box" */
+ struct box *fc; /* for float children of the block formatting context,
+ * "fp" */
+ int x, y; /* for the offsets resulting from any relative
+ * positioning on the current block */
+ int fnx, fny; /* for affsets which apply to flat children of "box" */
- css_computed_border_spacing(table->style, &h, &hu, &v, &vu);
+ /**\todo ensure containing box is large enough after moving boxes */
- border_spacing_h = FIXTOINT(nscss_len2px(h, hu, table->style));
- }
+ assert(root);
- /* 1st pass: consider cells with colspan 1 only */
- for (row_group = table->children; row_group; row_group =row_group->next)
- for (row = row_group->children; row; row = row->next)
- for (cell = row->children; cell; cell = cell->next) {
- assert(cell->type == BOX_TABLE_CELL);
- assert(cell->style);
- /** TODO: Handle colspan="0" correctly.
- * It's currently converted to 1 in box normaisation */
- assert(cell->columns != 0);
+ /* Normal children */
+ for (box = root->children; box; box = box->next) {
- if (cell->columns != 1)
+ if (box->type == BOX_TEXT)
continue;
- layout_minmax_block(cell, font_func);
- i = cell->start_column;
+ /* If relatively positioned, get offsets */
+ if (box->style && css_computed_position(box->style) ==
+ CSS_POSITION_RELATIVE)
+ layout_compute_relative_offset(box, &x, &y);
+ else
+ x = y = 0;
- if (col[i].positioned)
- continue;
+ /* Adjust float coordinates.
+ * (note float x and y are relative to their block formatting
+ * context box and not their parent) */
+ if (box->style && (css_computed_float(box->style) ==
+ CSS_FLOAT_LEFT ||
+ css_computed_float(box->style) ==
+ CSS_FLOAT_RIGHT) &&
+ (fx != 0 || fy != 0)) {
+ /* box is a float and there is a float offset to
+ * apply */
+ for (fc = fp->float_children; fc; fc = fc->next_float) {
+ if (box == fc->children) {
+ /* Box is floated in the block
+ * formatting context block, fp.
+ * Apply float offsets. */
+ box->x += fx;
+ box->y += fy;
+ fx = fy = 0;
+ }
+ }
+ }
- /* update column min, max widths using cell widths */
- if (col[i].min < cell->min_width)
- col[i].min = cell->min_width;
- if (col[i].max < cell->max_width)
- col[i].max = cell->max_width;
- }
+ if (box->float_children) {
+ fn = box;
+ fnx = fny = 0;
+ } else {
+ fn = fp;
+ fnx = fx + x;
+ fny = fy + y;
+ }
- /* 2nd pass: cells which span multiple columns */
- for (row_group = table->children; row_group; row_group =row_group->next)
- for (row = row_group->children; row; row = row->next)
- for (cell = row->children; cell; cell = cell->next) {
- unsigned int flexible_columns = 0;
- int min = 0, max = 0, fixed_width = 0, extra;
+ /* recurse first */
+ layout_position_relative(box, fn, fnx, fny);
- if (cell->columns == 1)
+ /* Ignore things we're not interested in. */
+ if (!box->style || (box->style &&
+ css_computed_position(box->style) !=
+ CSS_POSITION_RELATIVE))
continue;
- layout_minmax_block(cell, font_func);
- i = cell->start_column;
-
- /* find min width so far of spanned columns, and count
- * number of non-fixed spanned columns and total fixed width */
- for (j = 0; j != cell->columns; j++) {
- min += col[i + j].min;
- if (col[i + j].type == COLUMN_WIDTH_FIXED)
- fixed_width += col[i + j].width;
- else
- flexible_columns++;
- }
- min += (cell->columns - 1) * border_spacing_h;
+ box->x += x;
+ box->y += y;
- /* distribute extra min to spanned columns */
- if (min < cell->min_width) {
- if (flexible_columns == 0) {
- extra = 1 + (cell->min_width - min) /
- cell->columns;
- for (j = 0; j != cell->columns; j++) {
- col[i + j].min += extra;
- if (col[i + j].max < col[i + j].min)
- col[i + j].max = col[i + j].min;
- }
- } else {
- extra = 1 + (cell->min_width - min) /
- flexible_columns;
- for (j = 0; j != cell->columns; j++) {
- if (col[i + j].type !=
- COLUMN_WIDTH_FIXED) {
- col[i + j].min += extra;
- if (col[i + j].max <
- col[i + j].min)
- col[i + j].max =
- col[i + j].min;
- }
- }
+ /* Handle INLINEs - their "children" are in fact
+ * the sibling boxes between the INLINE and
+ * INLINE_END boxes */
+ if (box->type == BOX_INLINE && box->inline_end) {
+ struct box *b;
+ for (b = box->next; b && b != box->inline_end;
+ b = b->next) {
+ b->x += x;
+ b->y += y;
}
}
+ }
+}
- /* find max width so far of spanned columns */
- for (j = 0; j != cell->columns; j++)
- max += col[i + j].max;
- max += (cell->columns - 1) * border_spacing_h;
- /* distribute extra max to spanned columns */
- if (max < cell->max_width && flexible_columns) {
- extra = 1 + (cell->max_width - max) / flexible_columns;
- for (j = 0; j != cell->columns; j++)
- if (col[i + j].type != COLUMN_WIDTH_FIXED)
- col[i + j].max += extra;
- }
+/* exported function documented in render/layout.h */
+bool layout_document(html_content *content, int width, int height)
+{
+ bool ret;
+ struct box *doc = content->layout;
+ const struct gui_layout_table *font_func = content->font_func;
+
+ layout_minmax_block(doc, font_func);
+
+ layout_block_find_dimensions(width, height, 0, 0, doc);
+ doc->x = doc->margin[LEFT] + doc->border[LEFT].width;
+ doc->y = doc->margin[TOP] + doc->border[TOP].width;
+ width -= doc->margin[LEFT] + doc->border[LEFT].width +
+ doc->padding[LEFT] + doc->padding[RIGHT] +
+ doc->border[RIGHT].width + doc->margin[RIGHT];
+ if (width < 0) {
+ width = 0;
}
+ doc->width = width;
- for (i = 0; i != table->columns; i++) {
- if (col[i].max < col[i].min) {
- box_dump(stderr, table, 0, true);
- assert(0);
- }
- table_min += col[i].min;
- table_max += col[i].max;
+ ret = layout_block_context(doc, height, content);
+
+ /* make <html> and <body> fill available height */
+ if (doc->y + doc->padding[TOP] + doc->height + doc->padding[BOTTOM] +
+ doc->border[BOTTOM].width + doc->margin[BOTTOM] <
+ height) {
+ doc->height = height - (doc->y + doc->padding[TOP] +
+ doc->padding[BOTTOM] +
+ doc->border[BOTTOM].width +
+ doc->margin[BOTTOM]);
+ if (doc->children)
+ doc->children->height = doc->height -
+ (doc->children->margin[TOP] +
+ doc->children->border[TOP].width +
+ doc->children->padding[TOP] +
+ doc->children->padding[BOTTOM] +
+ doc->children->border[BOTTOM].width +
+ doc->children->margin[BOTTOM]);
}
- /* fixed width takes priority, unless it is too narrow */
- wtype = css_computed_width(table->style, &value, &unit);
- if (wtype == CSS_WIDTH_SET && unit != CSS_UNIT_PCT) {
- int width = FIXTOINT(nscss_len2px(value, unit, table->style));
- if (table_min < width)
- table_min = width;
- if (table_max < width)
- table_max = width;
- }
+ layout_lists(doc, font_func);
+ layout_position_absolute(doc, doc, 0, 0, content);
+ layout_position_relative(doc, doc, 0, 0);
- /* add margins, border, padding to min, max widths */
- calculate_mbp_width(table->style, LEFT, true, true, true,
- &extra_fixed, &extra_frac);
- calculate_mbp_width(table->style, RIGHT, true, true, true,
- &extra_fixed, &extra_frac);
- if (extra_fixed < 0)
- extra_fixed = 0;
- if (extra_frac < 0)
- extra_frac = 0;
- if (1.0 <= extra_frac)
- extra_frac = 0.9;
- table->min_width = (table_min + extra_fixed) / (1.0 - extra_frac);
- table->max_width = (table_max + extra_fixed) / (1.0 - extra_frac);
- table->min_width += (table->columns + 1) * border_spacing_h;
- table->max_width += (table->columns + 1) * border_spacing_h;
+ layout_calculate_descendant_bboxes(doc);
- assert(0 <= table->min_width && table->min_width <= table->max_width);
+ return ret;
}
/**
- * Moves the children of a box by a specified amount
+ * Insert a float into a container.
*
- * \param box top of tree of boxes
- * \param x the amount to move children by horizontally
- * \param y the amount to move children by vertically
+ * \param cont block formatting context block, used to contain float
+ * \param b box to add to float
+ *
+ * This sorts floats in order of descending bottom edges.
*/
-
-void layout_move_children(struct box *box, int x, int y)
+static void add_float_to_container(struct box *cont, struct box *b)
{
- assert(box);
+ struct box *box = cont->float_children;
+ int b_bottom = b->y + b->height;
- for (box = box->children; box; box = box->next) {
- box->x += x;
- box->y += y;
+ assert(b->type == BOX_FLOAT_LEFT || b->type == BOX_FLOAT_RIGHT);
+
+ if (box == NULL) {
+ /* No other float children */
+ b->next_float = NULL;
+ cont->float_children = b;
+ return;
+ } else if (b_bottom >= box->y + box->height) {
+ /* Goes at start of list */
+ b->next_float = cont->float_children;
+ cont->float_children = b;
+ } else {
+ struct box *prev = NULL;
+ while (box != NULL && b_bottom < box->y + box->height) {
+ prev = box;
+ box = box->next_float;
+ }
+ if (prev != NULL) {
+ b->next_float = prev->next_float;
+ prev->next_float = b;
+ }
}
}
/**
- * Determine width of margin, borders, and padding on one side of a box.
+ * Split a text box.
*
- * \param style style to measure
- * \param side side of box to measure
- * \param margin whether margin width is required
- * \param border whether border width is required
- * \param padding whether padding width is required
- * \param fixed increased by sum of fixed margin, border, and padding
- * \param frac increased by sum of fractional margin and padding
+ * \param content memory pool for any new boxes
+ * \param fstyle style for text in text box
+ * \param split_box box with text to split
+ * \param new_length new length for text in split_box, after splitting
+ * \param new_width new width for text in split_box, after splitting
+ * \return true on success, false on memory exhaustion
+ *
+ * A new box is created and inserted into the box tree after split_box,
+ * containing the text after new_length excluding the initial space character.
*/
+static bool
+layout_text_box_split(html_content *content,
+ plot_font_style_t *fstyle,
+ struct box *split_box,
+ size_t new_length,
+ int new_width)
+{
+ int space_width = split_box->space;
+ struct box *c2;
+ const struct gui_layout_table *font_func = content->font_func;
+ bool space = (split_box->text[new_length] == ' ');
+ int used_length = new_length + (space ? 1 : 0);
+
+ if ((space && space_width == 0) || space_width == UNKNOWN_WIDTH) {
+ /* We're need to add a space, and we don't know how big
+ * it's to be, OR we have a space of unknown width anyway;
+ * Calculate space width */
+ font_func->width(fstyle, " ", 1, &space_width);
+ }
+
+ if (split_box->space == UNKNOWN_WIDTH)
+ split_box->space = space_width;
+ if (!space)
+ space_width = 0;
+
+ /* Create clone of split_box, c2 */
+ c2 = talloc_memdup(content->bctx, split_box, sizeof *c2);
+ if (!c2)
+ return false;
+ c2->flags |= CLONE;
+
+ /* Set remaining text in c2 */
+ c2->text += used_length;
+
+ /* Set c2 according to the remaining text */
+ c2->width -= new_width + space_width;
+ c2->flags &= ~MEASURED; /* width has been estimated */
+ c2->length = split_box->length - used_length;
+
+ /* Update split_box for its reduced text */
+ split_box->width = new_width;
+ split_box->flags |= MEASURED;
+ split_box->length = new_length;
+ split_box->space = space_width;
+
+ /* Insert c2 into box list */
+ c2->next = split_box->next;
+ split_box->next = c2;
+ c2->prev = split_box;
+ if (c2->next)
+ c2->next->prev = c2;
+ else
+ c2->parent->last = c2;
+#ifdef LAYOUT_DEBUG
+ LOG("split_box %p len: %u \"%.*s\"", split_box, split_box->length, split_box->length, split_box->text);
+ LOG(" new_box %p len: %u \"%.*s\"", c2, c2->length, c2->length, c2->text);
+#endif
+ return true;
+}
-void calculate_mbp_width(const css_computed_style *style, unsigned int side,
- bool margin, bool border, bool padding,
- int *fixed, float *frac)
+
+/**
+ * Compute dimensions of box, margins, paddings, and borders for a floating
+ * element using shrink-to-fit. Also used for inline-blocks.
+ *
+ * \param available_width Max width available in pixels
+ * \param style Box's style
+ * \param box Box for which to find dimensions
+ * Box margins, borders, paddings, width and
+ * height are updated.
+ */
+static void
+layout_float_find_dimensions(int available_width,
+ const css_computed_style *style,
+ struct box *box)
{
- typedef uint8_t (*len_func)(const css_computed_style *style,
- css_fixed *length, css_unit *unit);
+ int width, height, max_width, min_width, max_height, min_height;
+ int *margin = box->margin;
+ int *padding = box->padding;
+ struct box_border *border = box->border;
+ enum css_overflow_e overflow_x = css_computed_overflow_x(style);
+ enum css_overflow_e overflow_y = css_computed_overflow_y(style);
+ int scrollbar_width_x =
+ (overflow_x == CSS_OVERFLOW_SCROLL ||
+ overflow_x == CSS_OVERFLOW_AUTO) ?
+ SCROLLBAR_WIDTH : 0;
+ int scrollbar_width_y =
+ (overflow_y == CSS_OVERFLOW_SCROLL ||
+ overflow_y == CSS_OVERFLOW_AUTO) ?
+ SCROLLBAR_WIDTH : 0;
- static len_func margin_funcs[4] = {
- css_computed_margin_top,
- css_computed_margin_right,
- css_computed_margin_bottom,
- css_computed_margin_left
- };
- static len_func padding_funcs[4] = {
- css_computed_padding_top,
- css_computed_padding_right,
- css_computed_padding_bottom,
- css_computed_padding_left
- };
- static struct {
- len_func width;
- uint8_t (*style)(const css_computed_style *style);
- } border_funcs[4] = {
- { css_computed_border_top_width,
- css_computed_border_top_style },
- { css_computed_border_right_width,
- css_computed_border_right_style },
- { css_computed_border_bottom_width,
- css_computed_border_bottom_style },
- { css_computed_border_left_width,
- css_computed_border_left_style }
- };
+ layout_find_dimensions(available_width, -1, box, style, &width, &height,
+ &max_width, &min_width, &max_height, &min_height,
+ margin, padding, border);
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
+ if (margin[LEFT] == AUTO)
+ margin[LEFT] = 0;
+ if (margin[RIGHT] == AUTO)
+ margin[RIGHT] = 0;
- assert(style);
+ if (box->gadget == NULL) {
+ padding[RIGHT] += scrollbar_width_y;
+ padding[BOTTOM] += scrollbar_width_x;
+ }
- /* margin */
- if (margin) {
- enum css_margin_e type;
+ if (box->object && !(box->flags & REPLACE_DIM) &&
+ content_get_type(box->object) != CONTENT_HTML) {
+ /* Floating replaced element, with intrinsic width or height.
+ * See 10.3.6 and 10.6.2 */
+ layout_get_object_dimensions(box, &width, &height,
+ min_width, max_width, min_height, max_height);
+ } else if (box->gadget && (box->gadget->type == GADGET_TEXTBOX ||
+ box->gadget->type == GADGET_PASSWORD ||
+ box->gadget->type == GADGET_FILE ||
+ box->gadget->type == GADGET_TEXTAREA)) {
+ css_fixed size = 0;
+ css_unit unit = CSS_UNIT_EM;
- type = margin_funcs[side](style, &value, &unit);
- if (type == CSS_MARGIN_SET) {
- if (unit == CSS_UNIT_PCT) {
- *frac += FIXTOINT(FDIV(value, F_100));
- } else {
- *fixed += FIXTOINT(nscss_len2px(value, unit,
- style));
+ /* Give sensible dimensions to gadgets, with auto width/height,
+ * that don't shrink to fit contained text. */
+ assert(box->style);
+
+ if (box->gadget->type == GADGET_TEXTBOX ||
+ box->gadget->type == GADGET_PASSWORD ||
+ box->gadget->type == GADGET_FILE) {
+ if (width == AUTO) {
+ size = INTTOFIX(10);
+ width = FIXTOINT(nscss_len2px(size, unit,
+ box->style));
+ }
+ if (box->gadget->type == GADGET_FILE &&
+ height == AUTO) {
+ size = FLTTOFIX(1.5);
+ height = FIXTOINT(nscss_len2px(size, unit,
+ box->style));
+ }
+ }
+ if (box->gadget->type == GADGET_TEXTAREA) {
+ if (width == AUTO) {
+ size = INTTOFIX(10);
+ width = FIXTOINT(nscss_len2px(size, unit,
+ box->style));
+ }
+ if (height == AUTO) {
+ size = INTTOFIX(4);
+ height = FIXTOINT(nscss_len2px(size, unit,
+ box->style));
}
}
- }
+ } else if (width == AUTO) {
+ /* CSS 2.1 section 10.3.5 */
+ width = min(max(box->min_width, available_width),
+ box->max_width);
- /* border */
- if (border) {
- if (border_funcs[side].style(style) !=
- CSS_BORDER_STYLE_NONE) {
- border_funcs[side].width(style, &value, &unit);
+ /* width includes margin, borders and padding */
+ if (width == available_width) {
+ width -= box->margin[LEFT] + box->border[LEFT].width +
+ box->padding[LEFT] +
+ box->padding[RIGHT] +
+ box->border[RIGHT].width +
+ box->margin[RIGHT];
+ } else {
+ /* width was obtained from a min_width or max_width
+ * value, so need to use the same method for calculating
+ * mbp as was used in layout_minmax_block() */
+ int fixed = 0;
+ float frac = 0;
+ calculate_mbp_width(box->style, LEFT, true, true, true,
+ &fixed, &frac);
+ calculate_mbp_width(box->style, RIGHT, true, true, true,
+ &fixed, &frac);
+ if (fixed < 0)
+ fixed = 0;
- *fixed += FIXTOINT(nscss_len2px(value, unit, style));
+ width -= fixed;
}
- }
- /* padding */
- if (padding) {
- padding_funcs[side](style, &value, &unit);
- if (unit == CSS_UNIT_PCT) {
- *frac += FIXTOINT(FDIV(value, F_100));
- } else {
- *fixed += FIXTOINT(nscss_len2px(value, unit, style));
- }
+ if (max_width >= 0 && width > max_width) width = max_width;
+ if (min_width > 0 && width < min_width) width = min_width;
+
+ } else {
+ if (max_width >= 0 && width > max_width) width = max_width;
+ if (min_width > 0 && width < min_width) width = min_width;
+ width -= scrollbar_width_y;
}
+
+ box->width = width;
+ box->height = height;
+
+ if (margin[TOP] == AUTO)
+ margin[TOP] = 0;
+ if (margin[BOTTOM] == AUTO)
+ margin[BOTTOM] = 0;
}
/**
- * Layout list markers.
+ * Layout the contents of a float or inline block.
+ *
+ * \param b float or inline block box
+ * \param width available width
+ * \param content memory pool for any new boxes
+ * \return true on success, false on memory exhaustion
*/
+static bool layout_float(struct box *b, int width, html_content *content)
+{
+ assert(b->type == BOX_TABLE || b->type == BOX_BLOCK ||
+ b->type == BOX_INLINE_BLOCK);
+ layout_float_find_dimensions(width, b->style, b);
+ if (b->type == BOX_TABLE) {
+ if (!layout_table(b, width, content))
+ return false;
+ if (b->margin[LEFT] == AUTO)
+ b->margin[LEFT] = 0;
+ if (b->margin[RIGHT] == AUTO)
+ b->margin[RIGHT] = 0;
+ if (b->margin[TOP] == AUTO)
+ b->margin[TOP] = 0;
+ if (b->margin[BOTTOM] == AUTO)
+ b->margin[BOTTOM] = 0;
+ } else
+ return layout_block_context(b, -1, content);
+ return true;
+}
+
-void layout_lists(struct box *box,
- const struct font_functions *font_func)
+/**
+ * Position a float in the first available space.
+ *
+ * \param c float box to position
+ * \param width available width
+ * \param cx x coordinate relative to cont to place float right of
+ * \param y y coordinate relative to cont to place float below
+ * \param cont ancestor box which defines horizontal space, for floats
+ */
+static void
+place_float_below(struct box *c, int width, int cx, int y, struct box *cont)
{
- struct box *child;
- struct box *marker;
- plot_font_style_t fstyle;
+ int x0, x1, yy;
+ struct box *left;
+ struct box *right;
- for (child = box->children; child; child = child->next) {
- if (child->list_marker) {
- marker = child->list_marker;
- if (marker->object) {
- marker->width =
- content_get_width(marker->object);
- marker->x = -marker->width;
- marker->height =
- content_get_height(marker->object);
- marker->y = (line_height(marker->style) -
- marker->height) / 2;
- } else if (marker->text) {
- if (marker->width == UNKNOWN_WIDTH) {
- font_plot_style_from_css(marker->style,
- &fstyle);
- font_func->font_width(&fstyle,
- marker->text,
- marker->length,
- &marker->width);
- marker->flags |= MEASURED;
- }
- marker->x = -marker->width;
- marker->y = 0;
- marker->height = line_height(marker->style);
- } else {
- marker->x = 0;
- marker->y = 0;
- marker->width = 0;
- marker->height = 0;
- }
- /* Gap between marker and content */
- marker->x -= 4;
+ yy = y > cont->cached_place_below_level ?
+ y : cont->cached_place_below_level;
+
+#ifdef LAYOUT_DEBUG
+ LOG("c %p, width %i, cx %i, y %i, cont %p", c, width, cx, y, cont);
+#endif
+
+ do {
+ y = yy;
+ x0 = cx;
+ x1 = cx + width;
+ find_sides(cont->float_children, y, y + c->height, &x0, &x1,
+ &left, &right);
+ if (left != 0 && right != 0) {
+ yy = (left->y + left->height <
+ right->y + right->height ?
+ left->y + left->height :
+ right->y + right->height);
+ } else if (left == 0 && right != 0) {
+ yy = right->y + right->height;
+ } else if (left != 0 && right == 0) {
+ yy = left->y + left->height;
}
- layout_lists(child, font_func);
+ } while ((left != 0 || right != 0) && (c->width > x1 - x0));
+
+ if (c->type == BOX_FLOAT_LEFT) {
+ c->x = x0;
+ } else {
+ c->x = x1 - c->width;
}
+ c->y = y;
+ cont->cached_place_below_level = y;
}
/**
- * Adjust positions of relatively positioned boxes.
+ * Position a line of boxes in inline formatting context.
*
- * \param root box to adjust the position of
- * \param fp box which forms the block formatting context for children of
- * "root" which are floats
- * \param fx x offset due to intervening relatively positioned boxes
- * between current box, "root", and the block formatting context
- * box, "fp", for float children of "root"
- * \param fy y offset due to intervening relatively positioned boxes
- * between current box, "root", and the block formatting context
- * box, "fp", for float children of "root"
+ * \param first box at start of line
+ * \param width available width on input, updated with actual width on output
+ * (may be incorrect if the line gets split?)
+ * \param y coordinate of top of line, updated on exit to bottom
+ * \param cx coordinate of left of line relative to cont
+ * \param cy coordinate of top of line relative to cont
+ * \param cont ancestor box which defines horizontal space, for floats
+ * \param indent apply any first-line indent
+ * \param has_text_children at least one TEXT in the inline_container
+ * \param next_box updated to first box for next line, or 0 at end
+ * \param content memory pool for any new boxes
+ * \return true on success, false on memory exhaustion
*/
-
-void layout_position_relative(struct box *root, struct box *fp, int fx, int fy)
+static bool
+layout_line(struct box *first,
+ int *width,
+ int *y,
+ int cx,
+ int cy,
+ struct box *cont,
+ bool indent,
+ bool has_text_children,
+ html_content *content,
+ struct box **next_box)
{
- struct box *box; /* for children of "root" */
- struct box *fn; /* for block formatting context box for children of
- * "box" */
- struct box *fc; /* for float children of the block formatting context,
- * "fp" */
- int x, y; /* for the offsets resulting from any relative
- * positioning on the current block */
- int fnx, fny; /* for affsets which apply to flat children of "box" */
+ int height, used_height;
+ int x0 = 0;
+ int x1 = *width;
+ int x, h, x_previous;
+ int fy = cy;
+ struct box *left;
+ struct box *right;
+ struct box *b;
+ struct box *split_box = 0;
+ struct box *d;
+ struct box *br_box = 0;
+ bool move_y = false;
+ bool place_below = false;
+ int space_before = 0, space_after = 0;
+ unsigned int inline_count = 0;
+ unsigned int i;
+ const struct gui_layout_table *font_func = content->font_func;
+ plot_font_style_t fstyle;
- /**\todo ensure containing box is large enough after moving boxes */
+#ifdef LAYOUT_DEBUG
+ LOG("first %p, first->text '%.*s', width %i, y %i, cx %i, cy %i", first, (int)first->length, first->text, *width, *y, cx, cy);
+#endif
- assert(root);
+ /* find sides at top of line */
+ x0 += cx;
+ x1 += cx;
+ find_sides(cont->float_children, cy, cy, &x0, &x1, &left, &right);
+ x0 -= cx;
+ x1 -= cx;
- /* Normal children */
- for (box = root->children; box; box = box->next) {
+ if (indent)
+ x0 += layout_text_indent(first->parent->parent->style, *width);
+
+ if (x1 < x0)
+ x1 = x0;
+
+ /* get minimum line height from containing block.
+ * this is the line-height if there are text children and also in the
+ * case of an initially empty text input */
+ if (has_text_children || first->parent->parent->gadget)
+ used_height = height =
+ line_height(first->parent->parent->style);
+ else
+ /* inline containers with no text are usually for layout and
+ * look better with no minimum line-height */
+ used_height = height = 0;
+
+ /* pass 1: find height of line assuming sides at top of line: loop
+ * body executed at least once
+ * keep in sync with the loop in layout_minmax_line() */
+#ifdef LAYOUT_DEBUG
+ LOG("x0 %i, x1 %i, x1 - x0 %i", x0, x1, x1 - x0);
+#endif
+
+ for (x = 0, b = first; x <= x1 - x0 && b != 0; b = b->next) {
+ int min_width, max_width, min_height, max_height;
+
+ assert(b->type == BOX_INLINE || b->type == BOX_INLINE_BLOCK ||
+ b->type == BOX_FLOAT_LEFT ||
+ b->type == BOX_FLOAT_RIGHT ||
+ b->type == BOX_BR || b->type == BOX_TEXT ||
+ b->type == BOX_INLINE_END);
+
+#ifdef LAYOUT_DEBUG
+ LOG("pass 1: b %p, x %i", b, x);
+#endif
+
+ if (b->type == BOX_BR)
+ break;
- if (box->type == BOX_TEXT)
+ if (b->type == BOX_FLOAT_LEFT || b->type == BOX_FLOAT_RIGHT)
+ continue;
+ if (b->type == BOX_INLINE_BLOCK &&
+ (css_computed_position(b->style) ==
+ CSS_POSITION_ABSOLUTE ||
+ css_computed_position(b->style) ==
+ CSS_POSITION_FIXED))
continue;
- /* If relatively positioned, get offsets */
- if (box->style && css_computed_position(box->style) ==
- CSS_POSITION_RELATIVE)
- layout_compute_relative_offset(box, &x, &y);
- else
- x = y = 0;
+ assert(b->style != NULL);
+ font_plot_style_from_css(b->style, &fstyle);
- /* Adjust float coordinates.
- * (note float x and y are relative to their block formatting
- * context box and not their parent) */
- if (box->style && (css_computed_float(box->style) ==
- CSS_FLOAT_LEFT ||
- css_computed_float(box->style) ==
- CSS_FLOAT_RIGHT) &&
- (fx != 0 || fy != 0)) {
- /* box is a float and there is a float offset to
- * apply */
- for (fc = fp->float_children; fc; fc = fc->next_float) {
- if (box == fc->children) {
- /* Box is floated in the block
- * formatting context block, fp.
- * Apply float offsets. */
- box->x += fx;
- box->y += fy;
- fx = fy = 0;
- }
- }
- }
+ x += space_after;
- if (box->float_children) {
- fn = box;
- fnx = fny = 0;
- } else {
- fn = fp;
- fnx = fx + x;
- fny = fy + y;
+ if (b->type == BOX_INLINE_BLOCK) {
+ if (b->max_width != UNKNOWN_WIDTH)
+ if (!layout_float(b, *width, content))
+ return false;
+ h = b->border[TOP].width + b->padding[TOP] + b->height +
+ b->padding[BOTTOM] +
+ b->border[BOTTOM].width;
+ if (height < h)
+ height = h;
+ x += b->margin[LEFT] + b->border[LEFT].width +
+ b->padding[LEFT] + b->width +
+ b->padding[RIGHT] +
+ b->border[RIGHT].width +
+ b->margin[RIGHT];
+ space_after = 0;
+ continue;
}
- /* recurse first */
- layout_position_relative(box, fn, fnx, fny);
+ if (b->type == BOX_INLINE) {
+ /* calculate borders, margins, and padding */
+ layout_find_dimensions(*width, -1, b, b->style, 0, 0,
+ 0, 0, 0, 0, b->margin, b->padding,
+ b->border);
+ for (i = 0; i != 4; i++)
+ if (b->margin[i] == AUTO)
+ b->margin[i] = 0;
+ x += b->margin[LEFT] + b->border[LEFT].width +
+ b->padding[LEFT];
+ if (b->inline_end) {
+ b->inline_end->margin[RIGHT] = b->margin[RIGHT];
+ b->inline_end->padding[RIGHT] =
+ b->padding[RIGHT];
+ b->inline_end->border[RIGHT] =
+ b->border[RIGHT];
+ } else {
+ x += b->padding[RIGHT] +
+ b->border[RIGHT].width +
+ b->margin[RIGHT];
+ }
+ } else if (b->type == BOX_INLINE_END) {
+ b->width = 0;
+ if (b->space == UNKNOWN_WIDTH) {
+ font_func->width(&fstyle, " ", 1, &b->space);
+ /** \todo handle errors */
+ }
+ space_after = b->space;
- /* Ignore things we're not interested in. */
- if (!box->style || (box->style &&
- css_computed_position(box->style) !=
- CSS_POSITION_RELATIVE))
+ x += b->padding[RIGHT] + b->border[RIGHT].width +
+ b->margin[RIGHT];
continue;
+ }
- box->x += x;
- box->y += y;
+ if (!b->object && !(b->flags & IFRAME) && !b->gadget &&
+ !(b->flags & REPLACE_DIM)) {
+ /* inline non-replaced, 10.3.1 and 10.6.1 */
+ b->height = line_height(b->style ? b->style :
+ b->parent->parent->style);
+ if (height < b->height)
+ height = b->height;
- /* Handle INLINEs - their "children" are in fact
- * the sibling boxes between the INLINE and
- * INLINE_END boxes */
- if (box->type == BOX_INLINE && box->inline_end) {
- struct box *b;
- for (b = box->next; b && b != box->inline_end;
- b = b->next) {
- b->x += x;
- b->y += y;
+ if (!b->text) {
+ b->width = 0;
+ space_after = 0;
+ continue;
}
- }
- }
-}
+ if (b->width == UNKNOWN_WIDTH) {
+ /** \todo handle errors */
-/**
- * Compute a box's relative offset as per CSS 2.1 9.4.3
- *
- * \param box Box to compute relative offsets for.
- * \param x Receives relative offset in x.
- * \param y Receives relative offset in y.
- */
-
-void layout_compute_relative_offset(struct box *box, int *x, int *y)
-{
- int left, right, top, bottom;
- struct box *containing_block;
+ /* If it's a select element, we must use the
+ * width of the widest option text */
+ if (b->parent->parent->gadget &&
+ b->parent->parent->gadget->type
+ == GADGET_SELECT) {
+ int opt_maxwidth = 0;
+ struct form_option *o;
- assert(box && box->parent && box->style &&
- css_computed_position(box->style) ==
- CSS_POSITION_RELATIVE);
+ for (o = b->parent->parent->gadget->
+ data.select.items; o;
+ o = o->next) {
+ int opt_width;
+ font_func->width(&fstyle,
+ o->text,
+ strlen(o->text),
+ &opt_width);
- if (box->float_container &&
- (css_computed_float(box->style) == CSS_FLOAT_LEFT ||
- css_computed_float(box->style) == CSS_FLOAT_RIGHT)) {
- containing_block = box->float_container;
- } else {
- containing_block = box->parent;
- }
+ if (opt_maxwidth < opt_width)
+ opt_maxwidth =opt_width;
+ }
+ b->width = opt_maxwidth;
+ if (nsoption_bool(core_select_menu))
+ b->width += SCROLLBAR_WIDTH;
+ } else {
+ font_func->width(&fstyle, b->text,
+ b->length, &b->width);
+ b->flags |= MEASURED;
+ }
+ }
- layout_compute_offsets(box, containing_block,
- &top, &right, &bottom, &left);
+ /* If the current text has not been measured (i.e. its
+ * width was estimated after splitting), and it fits on
+ * the line, measure it properly, so next box is placed
+ * correctly. */
+ if (b->text && (x + b->width < x1 - x0) &&
+ !(b->flags & MEASURED) &&
+ b->next) {
+ font_func->width(&fstyle, b->text,
+ b->length, &b->width);
+ b->flags |= MEASURED;
+ }
- if (left == AUTO && right == AUTO)
- left = right = 0;
- else if (left == AUTO)
- /* left is auto => computed = -right */
- left = -right;
- else if (right == AUTO)
- /* right is auto => computed = -left */
- right = -left;
- else {
- /* over constrained => examine direction property
- * of containing block */
- if (containing_block->style &&
- css_computed_direction(
- containing_block->style) ==
- CSS_DIRECTION_RTL) {
- /* right wins */
- left = -right;
- } else {
- /* assume LTR in all other cases */
- right = -left;
+ x += b->width;
+ if (b->space == UNKNOWN_WIDTH) {
+ font_func->width(&fstyle, " ", 1, &b->space);
+ /** \todo handle errors */
+ }
+ space_after = b->space;
+ continue;
}
- }
- assert(left == -right);
+ space_after = 0;
- if (top == AUTO && bottom == AUTO) {
- top = bottom = 0;
- } else if (top == AUTO) {
- top = -bottom;
- } else {
- /* bottom is AUTO, or neither are AUTO */
- bottom = -top;
- }
+ /* inline replaced, 10.3.2 and 10.6.2 */
+ assert(b->style);
-#ifdef LAYOUT_DEBUG
- LOG("left %i, right %i, top %i, bottom %i", left, right, top, bottom);
-#endif
+ layout_find_dimensions(*width, -1, b, b->style,
+ &b->width, &b->height, &max_width, &min_width,
+ &max_height, &min_height, NULL, NULL, NULL);
- *x = left;
- *y = top;
-}
+ if (b->object && !(b->flags & REPLACE_DIM)) {
+ layout_get_object_dimensions(b, &b->width, &b->height,
+ min_width, max_width,
+ min_height, max_height);
+ } else if (b->flags & IFRAME) {
+ /* TODO: should we look at the content dimensions? */
+ if (b->width == AUTO)
+ b->width = 400;
+ if (b->height == AUTO)
+ b->height = 300;
+
+ /* We reformat the iframe browser window to new
+ * dimensions in pass 2 */
+ } else {
+ /* form control with no object */
+ if (b->width == AUTO)
+ b->width = FIXTOINT(nscss_len2px(INTTOFIX(1),
+ CSS_UNIT_EM, b->style));
+ if (b->height == AUTO)
+ b->height = FIXTOINT(nscss_len2px(INTTOFIX(1),
+ CSS_UNIT_EM, b->style));
+ }
+
+ /* Reformat object to new box size */
+ if (b->object && content_get_type(b->object) == CONTENT_HTML &&
+ b->width !=
+ content_get_available_width(b->object)) {
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
+ enum css_height_e htype = css_computed_height(b->style,
+ &value, &unit);
+ content_reformat(b->object, false, b->width, b->height);
-/**
- * Recursively layout and position absolutely positioned boxes.
- *
- * \param box tree of boxes to layout
- * \param containing_block current containing block
- * \param cx position of box relative to containing_block
- * \param cy position of box relative to containing_block
- * \param content memory pool for any new boxes
- * \return true on success, false on memory exhaustion
- */
+ if (htype == CSS_HEIGHT_AUTO)
+ b->height = content_get_height(b->object);
+ }
-bool layout_position_absolute(struct box *box,
- struct box *containing_block,
- int cx, int cy,
- html_content *content)
-{
- struct box *c;
+ if (height < b->height)
+ height = b->height;
- for (c = box->children; c; c = c->next) {
- if ((c->type == BOX_BLOCK || c->type == BOX_TABLE ||
- c->type == BOX_INLINE_BLOCK) &&
- (css_computed_position(c->style) ==
- CSS_POSITION_ABSOLUTE ||
- css_computed_position(c->style) ==
- CSS_POSITION_FIXED)) {
- if (!layout_absolute(c, containing_block,
- cx, cy, content))
- return false;
- if (!layout_position_absolute(c, c, 0, 0, content))
- return false;
- } else if (c->style && css_computed_position(c->style) ==
- CSS_POSITION_RELATIVE) {
- if (!layout_position_absolute(c, c, 0, 0, content))
- return false;
- } else {
- int px, py;
- if (c->style && (css_computed_float(c->style) ==
- CSS_FLOAT_LEFT ||
- css_computed_float(c->style) ==
- CSS_FLOAT_RIGHT)) {
- /* Float x/y coords are relative to nearest
- * ansestor with float_children, rather than
- * relative to parent. Need to get x/y relative
- * to parent */
- struct box *p;
- px = c->x;
- py = c->y;
- for (p = box->parent; p && !p->float_children;
- p = p->parent) {
- px -= p->x;
- py -= p->y;
- }
- } else {
- /* Not a float, so box x/y coords are relative
- * to parent */
- px = c->x;
- py = c->y;
- }
- if (!layout_position_absolute(c, containing_block,
- cx + px, cy + py, content))
- return false;
- }
+ x += b->width;
}
- return true;
-}
+ /* find new sides using this height */
+ x0 = cx;
+ x1 = cx + *width;
+ find_sides(cont->float_children, cy, cy + height, &x0, &x1,
+ &left, &right);
+ x0 -= cx;
+ x1 -= cx;
+ if (indent)
+ x0 += layout_text_indent(first->parent->parent->style, *width);
-/**
- * Layout and position an absolutely positioned box.
- *
- * \param box absolute box to layout and position
- * \param containing_block containing block
- * \param cx position of box relative to containing_block
- * \param cy position of box relative to containing_block
- * \param content memory pool for any new boxes
- * \return true on success, false on memory exhaustion
- */
+ if (x1 < x0)
+ x1 = x0;
-bool layout_absolute(struct box *box, struct box *containing_block,
- int cx, int cy,
- html_content *content)
-{
- int static_left, static_top; /* static position */
- int top, right, bottom, left;
- int width, height, max_width, min_width;
- int *margin = box->margin;
- int *padding = box->padding;
- struct box_border *border = box->border;
- int available_width = containing_block->width;
- int space;
+ space_after = space_before = 0;
- assert(box->type == BOX_BLOCK || box->type == BOX_TABLE ||
- box->type == BOX_INLINE_BLOCK);
+ /* pass 2: place boxes in line: loop body executed at least once */
+#ifdef LAYOUT_DEBUG
+ LOG("x0 %i, x1 %i, x1 - x0 %i", x0, x1, x1 - x0);
+#endif
- /* The static position is where the box would be if it was not
- * absolutely positioned. The x and y are filled in by
- * layout_block_context(). */
- static_left = cx + box->x;
- static_top = cy + box->y;
+ for (x = x_previous = 0, b = first; x <= x1 - x0 && b; b = b->next) {
+#ifdef LAYOUT_DEBUG
+ LOG("pass 2: b %p, x %i", b, x);
+#endif
- if (containing_block->type == BOX_BLOCK ||
- containing_block->type == BOX_INLINE_BLOCK ||
- containing_block->type == BOX_TABLE_CELL) {
- /* Block level container => temporarily increase containing
- * block dimensions to include padding (we restore this
- * again at the end) */
- containing_block->width += containing_block->padding[LEFT] +
- containing_block->padding[RIGHT];
- containing_block->height += containing_block->padding[TOP] +
- containing_block->padding[BOTTOM];
- } else {
- /** \todo inline containers */
- }
+ if (b->type == BOX_INLINE_BLOCK &&
+ (css_computed_position(b->style) ==
+ CSS_POSITION_ABSOLUTE ||
+ css_computed_position(b->style) ==
+ CSS_POSITION_FIXED)) {
+ b->x = x + space_after;
- layout_compute_offsets(box, containing_block,
- &top, &right, &bottom, &left);
+ } else if (b->type == BOX_INLINE ||
+ b->type == BOX_INLINE_BLOCK ||
+ b->type == BOX_TEXT ||
+ b->type == BOX_INLINE_END) {
+ assert(b->width != UNKNOWN_WIDTH);
- /* Pass containing block into layout_find_dimensions via the float
- * containing block box member. This is unused for absolutely positioned
- * boxes because a box can't be floated and absolutely positioned. */
- box->float_container = containing_block;
- layout_find_dimensions(available_width, -1, box, box->style,
- &width, &height, &max_width, &min_width,
- 0, 0, margin, padding, border);
- box->float_container = NULL;
+ x_previous = x;
+ x += space_after;
+ b->x = x;
- /* 10.3.7 */
+ if ((b->type == BOX_INLINE && !b->inline_end) ||
+ b->type == BOX_INLINE_BLOCK) {
+ b->x += b->margin[LEFT] + b->border[LEFT].width;
+ x = b->x + b->padding[LEFT] + b->width +
+ b->padding[RIGHT] +
+ b->border[RIGHT].width +
+ b->margin[RIGHT];
+ } else if (b->type == BOX_INLINE) {
+ b->x += b->margin[LEFT] + b->border[LEFT].width;
+ x = b->x + b->padding[LEFT] + b->width;
+ } else if (b->type == BOX_INLINE_END) {
+ b->height = b->inline_end->height;
+ x += b->padding[RIGHT] +
+ b->border[RIGHT].width +
+ b->margin[RIGHT];
+ } else {
+ x += b->width;
+ }
+
+ space_before = space_after;
+ if (b->object || b->flags & REPLACE_DIM ||
+ b->flags & IFRAME)
+ space_after = 0;
+ else if (b->text || b->type == BOX_INLINE_END) {
+ if (b->space == UNKNOWN_WIDTH) {
+ font_plot_style_from_css(b->style,
+ &fstyle);
+ /** \todo handle errors */
+ font_func->width(&fstyle, " ", 1,
+ &b->space);
+ }
+ space_after = b->space;
+ } else {
+ space_after = 0;
+ }
+ split_box = b;
+ move_y = true;
+ inline_count++;
+ } else if (b->type == BOX_BR) {
+ b->x = x;
+ b->width = 0;
+ br_box = b;
+ b = b->next;
+ split_box = 0;
+ move_y = true;
+ break;
+
+ } else {
+ /* float */
#ifdef LAYOUT_DEBUG
- LOG("%i + %i + %i + %i + %i + %i + %i + %i + %i = %i", left, margin[LEFT], border[LEFT].width, padding[LEFT], width, padding[RIGHT], border[RIGHT].width, margin[RIGHT], right, containing_block->width);
+ LOG("float %p", b);
#endif
- if (left == AUTO && width == AUTO && right == AUTO) {
- if (margin[LEFT] == AUTO)
- margin[LEFT] = 0;
- if (margin[RIGHT] == AUTO)
- margin[RIGHT] = 0;
- left = static_left;
+ d = b->children;
+ d->float_children = 0;
+ d->cached_place_below_level = 0;
+ b->float_container = d->float_container = cont;
- width = min(max(box->min_width, available_width),
- box->max_width);
- width -= box->margin[LEFT] + box->border[LEFT].width +
- box->padding[LEFT] + box->padding[RIGHT] +
- box->border[RIGHT].width + box->margin[RIGHT];
+ if (!layout_float(d, *width, content))
+ return false;
- /* Adjust for {min|max}-width */
- if (max_width >= 0 && width > max_width) width = max_width;
- if (min_width > 0 && width < min_width) width = min_width;
+#ifdef LAYOUT_DEBUG
+ LOG("%p : %d %d", d, d->margin[TOP], d->border[TOP].width);
+#endif
- right = containing_block->width -
- left -
- margin[LEFT] - border[LEFT].width - padding[LEFT] -
- width -
- padding[RIGHT] - border[RIGHT].width - margin[RIGHT];
- } else if (left != AUTO && width != AUTO && right != AUTO) {
+ d->x = d->margin[LEFT] + d->border[LEFT].width;
+ d->y = d->margin[TOP] + d->border[TOP].width;
+ b->width = d->margin[LEFT] + d->border[LEFT].width +
+ d->padding[LEFT] + d->width +
+ d->padding[RIGHT] +
+ d->border[RIGHT].width +
+ d->margin[RIGHT];
+ b->height = d->margin[TOP] + d->border[TOP].width +
+ d->padding[TOP] + d->height +
+ d->padding[BOTTOM] +
+ d->border[BOTTOM].width +
+ d->margin[BOTTOM];
+
+ if (b->width > (x1 - x0) - x)
+ place_below = true;
+ if (d->style && (css_computed_clear(d->style) ==
+ CSS_CLEAR_NONE ||
+ (css_computed_clear(d->style) ==
+ CSS_CLEAR_LEFT && left == 0) ||
+ (css_computed_clear(d->style) ==
+ CSS_CLEAR_RIGHT &&
+ right == 0) ||
+ (css_computed_clear(d->style) ==
+ CSS_CLEAR_BOTH &&
+ left == 0 && right == 0)) &&
+ (!place_below ||
+ (left == 0 && right == 0 && x == 0)) &&
+ cy >= cont->clear_level &&
+ cy >= cont->cached_place_below_level) {
+ /* + not cleared or,
+ * cleared and there are no floats to clear
+ * + fits without needing to be placed below or,
+ * this line is empty with no floats
+ * + current y, cy, is below the clear level
+ *
+ * Float affects current line */
+ if (b->type == BOX_FLOAT_LEFT) {
+ b->x = cx + x0;
+ if (b->width > 0)
+ x0 += b->width;
+ left = b;
+ } else {
+ b->x = cx + x1 - b->width;
+ if (b->width > 0)
+ x1 -= b->width;
+ right = b;
+ }
+ b->y = cy;
+ } else {
+ /* cleared or doesn't fit on line */
+ /* place below into next available space */
+ int fcy = (cy > cont->clear_level) ? cy :
+ cont->clear_level;
+ fcy = (fcy > cont->cached_place_below_level) ?
+ fcy :
+ cont->cached_place_below_level;
+ fy = (fy > fcy) ? fy : fcy;
+ fy = (fy == cy) ? fy + height : fy;
- /* Adjust for {min|max}-width */
- if (max_width >= 0 && width > max_width) width = max_width;
- if (min_width > 0 && width < min_width) width = min_width;
+ place_float_below(b, *width, cx, fy, cont);
+ fy = b->y;
+ if (d->style && (
+ (css_computed_clear(d->style) ==
+ CSS_CLEAR_LEFT && left != 0) ||
+ (css_computed_clear(d->style) ==
+ CSS_CLEAR_RIGHT &&
+ right != 0) ||
+ (css_computed_clear(d->style) ==
+ CSS_CLEAR_BOTH &&
+ (left != 0 || right != 0)))) {
+ /* to be cleared below existing
+ * floats */
+ if (b->type == BOX_FLOAT_LEFT)
+ b->x = cx;
+ else
+ b->x = cx + *width - b->width;
- if (margin[LEFT] == AUTO && margin[RIGHT] == AUTO) {
- space = containing_block->width -
- left - border[LEFT].width -
- padding[LEFT] - width - padding[RIGHT] -
- border[RIGHT].width - right;
- if (space < 0) {
- margin[LEFT] = 0;
- margin[RIGHT] = space;
- } else {
- margin[LEFT] = margin[RIGHT] = space / 2;
+ fcy = layout_clear(cont->float_children,
+ css_computed_clear(d->style));
+ if (fcy > cont->clear_level)
+ cont->clear_level = fcy;
+ if (b->y < fcy)
+ b->y = fcy;
+ }
+ if (b->type == BOX_FLOAT_LEFT)
+ left = b;
+ else
+ right = b;
}
- } else if (margin[LEFT] == AUTO) {
- margin[LEFT] = containing_block->width -
- left - border[LEFT].width -
- padding[LEFT] - width - padding[RIGHT] -
- border[RIGHT].width - margin[RIGHT] -
- right;
- } else if (margin[RIGHT] == AUTO) {
- margin[RIGHT] = containing_block->width -
- left - margin[LEFT] -
- border[LEFT].width -
- padding[LEFT] - width - padding[RIGHT] -
- border[RIGHT].width - right;
- } else {
- right = containing_block->width -
- left - margin[LEFT] -
- border[LEFT].width -
- padding[LEFT] - width - padding[RIGHT] -
- border[RIGHT].width - margin[RIGHT];
- }
- } else {
- if (margin[LEFT] == AUTO)
- margin[LEFT] = 0;
- if (margin[RIGHT] == AUTO)
- margin[RIGHT] = 0;
+ add_float_to_container(cont, b);
- if (left == AUTO && width == AUTO && right != AUTO) {
- available_width -= right;
+ split_box = 0;
+ }
+ }
- width = min(max(box->min_width, available_width),
- box->max_width);
- width -= box->margin[LEFT] + box->border[LEFT].width +
- box->padding[LEFT] + box->padding[RIGHT] +
- box->border[RIGHT].width + box->margin[RIGHT];
+ if (x1 - x0 < x && split_box) {
+ /* the last box went over the end */
+ size_t split = 0;
+ int w;
+ bool no_wrap = css_computed_white_space(
+ split_box->style) == CSS_WHITE_SPACE_NOWRAP ||
+ css_computed_white_space(
+ split_box->style) == CSS_WHITE_SPACE_PRE;
- /* Adjust for {min|max}-width */
- if (max_width >= 0 && width > max_width)
- width = max_width;
- if (min_width > 0 && width < min_width)
- width = min_width;
+ x = x_previous;
- left = containing_block->width -
- margin[LEFT] - border[LEFT].width -
- padding[LEFT] - width - padding[RIGHT] -
- border[RIGHT].width - margin[RIGHT] -
- right;
- } else if (left == AUTO && width != AUTO && right == AUTO) {
+ if (!no_wrap &&
+ (split_box->type == BOX_INLINE ||
+ split_box->type == BOX_TEXT) &&
+ !split_box->object &&
+ !(split_box->flags & REPLACE_DIM) &&
+ !(split_box->flags & IFRAME) &&
+ !split_box->gadget && split_box->text) {
- /* Adjust for {min|max}-width */
- if (max_width >= 0 && width > max_width)
- width = max_width;
- if (min_width > 0 && width < min_width)
- width = min_width;
+ font_plot_style_from_css(split_box->style, &fstyle);
+ /** \todo handle errors */
+ font_func->split(&fstyle,
+ split_box->text,
+ split_box->length,
+ x1 - x0 - x - space_before,
+ &split,
+ &w);
+ }
- left = static_left;
- right = containing_block->width -
- left - margin[LEFT] -
- border[LEFT].width -
- padding[LEFT] - width - padding[RIGHT] -
- border[RIGHT].width - margin[RIGHT];
- } else if (left != AUTO && width == AUTO && right == AUTO) {
- available_width -= left;
+ /* split == 0 implies that text can't be split */
- width = min(max(box->min_width, available_width),
- box->max_width);
- width -= box->margin[LEFT] + box->border[LEFT].width +
- box->padding[LEFT] + box->padding[RIGHT] +
- box->border[RIGHT].width + box->margin[RIGHT];
+ if (split == 0)
+ w = split_box->width;
- /* Adjust for {min|max}-width */
- if (max_width >= 0 && width > max_width)
- width = max_width;
- if (min_width > 0 && width < min_width)
- width = min_width;
+#ifdef LAYOUT_DEBUG
+ LOG("splitting: split_box %p \"%.*s\", spilt %zu, w %i, ""left %p, right %p, inline_count %u", split_box, (int)split_box->length, split_box->text, split, w, left, right, inline_count);
+#endif
- right = containing_block->width -
- left - margin[LEFT] -
- border[LEFT].width -
- padding[LEFT] - width - padding[RIGHT] -
- border[RIGHT].width - margin[RIGHT];
- } else if (left == AUTO && width != AUTO && right != AUTO) {
+ if ((split == 0 || x1 - x0 <= x + space_before + w) &&
+ !left && !right && inline_count == 1) {
+ /* first word of box doesn't fit, but no floats and
+ * first box on line so force in */
+ if (split == 0 || split == split_box->length) {
+ /* only one word in this box, or not text
+ * or white-space:nowrap */
+ b = split_box->next;
+ } else {
+ /* cut off first word for this line */
+ if (!layout_text_box_split(content, &fstyle,
+ split_box, split, w))
+ return false;
+ b = split_box->next;
+ }
+ x += space_before + w;
+#ifdef LAYOUT_DEBUG
+ LOG("forcing");
+#endif
+ } else if ((split == 0 || x1 - x0 <= x + space_before + w) &&
+ inline_count == 1) {
+ /* first word of first box doesn't fit, but a float is
+ * taking some of the width so move below it */
+ assert(left || right);
+ used_height = 0;
+ if (left) {
+#ifdef LAYOUT_DEBUG
+ LOG("cy %i, left->y %i, left->height %i", cy, left->y, left->height);
+#endif
+ used_height = left->y + left->height - cy + 1;
+#ifdef LAYOUT_DEBUG
+ LOG("used_height %i", used_height);
+#endif
+ }
+ if (right && used_height <
+ right->y + right->height - cy + 1)
+ used_height = right->y + right->height - cy + 1;
- /* Adjust for {min|max}-width */
- if (max_width >= 0 && width > max_width)
- width = max_width;
- if (min_width > 0 && width < min_width)
- width = min_width;
+ if (used_height < 0)
+ used_height = 0;
- left = containing_block->width -
- margin[LEFT] - border[LEFT].width -
- padding[LEFT] - width - padding[RIGHT] -
- border[RIGHT].width - margin[RIGHT] -
- right;
- } else if (left != AUTO && width == AUTO && right != AUTO) {
- width = containing_block->width -
- left - margin[LEFT] -
- border[LEFT].width -
- padding[LEFT] - padding[RIGHT] -
- border[RIGHT].width - margin[RIGHT] -
- right;
+ b = split_box;
+#ifdef LAYOUT_DEBUG
+ LOG("moving below float");
+#endif
+ } else if (split == 0 || x1 - x0 <= x + space_before + w) {
+ /* first word of box doesn't fit so leave box for next
+ * line */
+ b = split_box;
+#ifdef LAYOUT_DEBUG
+ LOG("leaving for next line");
+#endif
+ } else {
+ /* fit as many words as possible */
+ assert(split != 0);
+#ifdef LAYOUT_DEBUG
+ LOG("'%.*s' %i %zu %i", (int)split_box->length, split_box->text, x1 - x0, split, w);
+#endif
+ if (split != split_box->length) {
+ if (!layout_text_box_split(content, &fstyle,
+ split_box, split, w))
+ return false;
+ b = split_box->next;
+ }
+ x += space_before + w;
+#ifdef LAYOUT_DEBUG
+ LOG("fitting words");
+#endif
+ }
+ move_y = true;
+ }
- /* Adjust for {min|max}-width */
- if (max_width >= 0 && width > max_width)
- width = max_width;
- if (min_width > 0 && width < min_width)
- width = min_width;
+ /* set positions */
+ switch (css_computed_text_align(first->parent->parent->style)) {
+ case CSS_TEXT_ALIGN_RIGHT:
+ case CSS_TEXT_ALIGN_LIBCSS_RIGHT:
+ x0 = x1 - x;
+ break;
+ case CSS_TEXT_ALIGN_CENTER:
+ case CSS_TEXT_ALIGN_LIBCSS_CENTER:
+ x0 = (x0 + (x1 - x)) / 2;
+ break;
+ case CSS_TEXT_ALIGN_LEFT:
+ case CSS_TEXT_ALIGN_LIBCSS_LEFT:
+ case CSS_TEXT_ALIGN_JUSTIFY:
+ /* leave on left */
+ break;
+ case CSS_TEXT_ALIGN_DEFAULT:
+ /* None; consider text direction */
+ switch (css_computed_direction(first->parent->parent->style)) {
+ case CSS_DIRECTION_LTR:
+ /* leave on left */
+ break;
+ case CSS_DIRECTION_RTL:
+ x0 = x1 - x;
+ break;
+ }
+ break;
+ }
- } else if (left != AUTO && width != AUTO && right == AUTO) {
+ for (d = first; d != b; d = d->next) {
+ d->flags &= ~NEW_LINE;
- /* Adjust for {min|max}-width */
- if (max_width >= 0 && width > max_width)
- width = max_width;
- if (min_width > 0 && width < min_width)
- width = min_width;
+ if (d->type == BOX_INLINE_BLOCK &&
+ (css_computed_position(d->style) ==
+ CSS_POSITION_ABSOLUTE ||
+ css_computed_position(d->style) ==
+ CSS_POSITION_FIXED)) {
+ /* positioned inline-blocks:
+ * set static position (x,y) only, rest of positioning
+ * is handled later */
+ d->x += x0;
+ d->y = *y;
+ continue;
+ } else if ((d->type == BOX_INLINE &&
+ ((d->object || d->gadget) == false) &&
+ !(d->flags & IFRAME) &&
+ !(d->flags & REPLACE_DIM)) ||
+ d->type == BOX_BR ||
+ d->type == BOX_TEXT ||
+ d->type == BOX_INLINE_END) {
+ /* regular (non-replaced) inlines */
+ d->x += x0;
+ d->y = *y - d->padding[TOP];
- right = containing_block->width -
- left - margin[LEFT] -
- border[LEFT].width -
- padding[LEFT] - width - padding[RIGHT] -
- border[RIGHT].width - margin[RIGHT];
+ if (d->type == BOX_TEXT && d->height > used_height) {
+ /* text */
+ used_height = d->height;
+ }
+ } else if ((d->type == BOX_INLINE) ||
+ d->type == BOX_INLINE_BLOCK) {
+ /* replaced inlines and inline-blocks */
+ d->x += x0;
+ d->y = *y + d->border[TOP].width + d->margin[TOP];
+ h = d->margin[TOP] + d->border[TOP].width +
+ d->padding[TOP] + d->height +
+ d->padding[BOTTOM] +
+ d->border[BOTTOM].width +
+ d->margin[BOTTOM];
+ if (used_height < h)
+ used_height = h;
}
}
-#ifdef LAYOUT_DEBUG
- LOG("%i + %i + %i + %i + %i + %i + %i + %i + %i = %i", left, margin[LEFT], border[LEFT].width, padding[LEFT], width, padding[RIGHT], border[RIGHT].width, margin[RIGHT], right, containing_block->width);
-#endif
+ first->flags |= NEW_LINE;
- box->x = left + margin[LEFT] + border[LEFT].width - cx;
- if (containing_block->type == BOX_BLOCK ||
- containing_block->type == BOX_INLINE_BLOCK ||
- containing_block->type == BOX_TABLE_CELL) {
- /* Block-level ancestor => reset container's width */
- containing_block->width -= containing_block->padding[LEFT] +
- containing_block->padding[RIGHT];
- } else {
- /** \todo inline ancestors */
+ assert(b != first || (move_y && 0 < used_height && (left || right)));
+
+ /* handle vertical-align by adjusting box y values */
+ /** \todo proper vertical alignment handling */
+ for (d = first; d != b; d = d->next) {
+ if ((d->type == BOX_INLINE && d->inline_end) ||
+ d->type == BOX_BR ||
+ d->type == BOX_TEXT ||
+ d->type == BOX_INLINE_END) {
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
+ switch (css_computed_vertical_align(d->style, &value,
+ &unit)) {
+ case CSS_VERTICAL_ALIGN_SUPER:
+ case CSS_VERTICAL_ALIGN_TOP:
+ case CSS_VERTICAL_ALIGN_TEXT_TOP:
+ /* already at top */
+ break;
+ case CSS_VERTICAL_ALIGN_SUB:
+ case CSS_VERTICAL_ALIGN_BOTTOM:
+ case CSS_VERTICAL_ALIGN_TEXT_BOTTOM:
+ d->y += used_height - d->height;
+ break;
+ default:
+ case CSS_VERTICAL_ALIGN_BASELINE:
+ d->y += 0.75 * (used_height - d->height);
+ break;
+ }
+ }
}
- box->width = width;
- box->height = height;
- if (box->type == BOX_BLOCK || box->type == BOX_INLINE_BLOCK ||
- box->object || box->flags & IFRAME) {
- if (!layout_block_context(box, -1, content))
- return false;
- } else if (box->type == BOX_TABLE) {
- /* layout_table also expects the containing block to be
- * stored in the float_container field */
- box->float_container = containing_block;
- /* \todo layout_table considers margins etc. again */
- if (!layout_table(box, width, content))
- return false;
- box->float_container = NULL;
- layout_solve_width(box, box->parent->width, box->width, 0, 0,
- -1, -1);
+ /* handle clearance for br */
+ if (br_box && css_computed_clear(br_box->style) != CSS_CLEAR_NONE) {
+ int clear_y = layout_clear(cont->float_children,
+ css_computed_clear(br_box->style));
+ if (used_height < clear_y - cy)
+ used_height = clear_y - cy;
}
- /* 10.6.4 */
+ if (move_y)
+ *y += used_height;
+ *next_box = b;
+ *width = x; /* return actual width */
+ return true;
+}
+
+
+/* exported function documented in render/layout.h */
+bool layout_inline_container(struct box *inline_container, int width,
+ struct box *cont, int cx, int cy, html_content *content)
+{
+ bool first_line = true;
+ bool has_text_children;
+ struct box *c, *next;
+ int y = 0;
+ int curwidth,maxwidth = width;
+
+ assert(inline_container->type == BOX_INLINE_CONTAINER);
+
#ifdef LAYOUT_DEBUG
- LOG("%i + %i + %i + %i + %i + %i + %i + %i + %i = %i", top, margin[TOP], border[TOP].width, padding[TOP], height, padding[BOTTOM], border[BOTTOM].width, margin[BOTTOM], bottom, containing_block->height);
+ LOG("inline_container %p, width %i, cont %p, cx %i, cy %i", inline_container, width, cont, cx, cy);
#endif
- if (top == AUTO && height == AUTO && bottom == AUTO) {
- top = static_top;
- height = box->height;
- if (margin[TOP] == AUTO)
- margin[TOP] = 0;
- if (margin[BOTTOM] == AUTO)
- margin[BOTTOM] = 0;
- bottom = containing_block->height -
- top - margin[TOP] - border[TOP].width -
- padding[TOP] - height - padding[BOTTOM] -
- border[BOTTOM].width - margin[BOTTOM];
- } else if (top != AUTO && height != AUTO && bottom != AUTO) {
- if (margin[TOP] == AUTO && margin[BOTTOM] == AUTO) {
- space = containing_block->height -
- top - border[TOP].width - padding[TOP] -
- height - padding[BOTTOM] -
- border[BOTTOM].width - bottom;
- margin[TOP] = margin[BOTTOM] = space / 2;
- } else if (margin[TOP] == AUTO) {
- margin[TOP] = containing_block->height -
- top - border[TOP].width - padding[TOP] -
- height - padding[BOTTOM] -
- border[BOTTOM].width - margin[BOTTOM] -
- bottom;
- } else if (margin[BOTTOM] == AUTO) {
- margin[BOTTOM] = containing_block->height -
- top - margin[TOP] - border[TOP].width -
- padding[TOP] - height -
- padding[BOTTOM] - border[BOTTOM].width -
- bottom;
- } else {
- bottom = containing_block->height -
- top - margin[TOP] - border[TOP].width -
- padding[TOP] - height -
- padding[BOTTOM] - border[BOTTOM].width -
- margin[BOTTOM];
- }
- } else {
- if (margin[TOP] == AUTO)
- margin[TOP] = 0;
- if (margin[BOTTOM] == AUTO)
- margin[BOTTOM] = 0;
- if (top == AUTO && height == AUTO && bottom != AUTO) {
- height = box->height;
- top = containing_block->height -
- margin[TOP] - border[TOP].width -
- padding[TOP] - height -
- padding[BOTTOM] - border[BOTTOM].width -
- margin[BOTTOM] - bottom;
- } else if (top == AUTO && height != AUTO && bottom == AUTO) {
- top = static_top;
- bottom = containing_block->height -
- top - margin[TOP] - border[TOP].width -
- padding[TOP] - height -
- padding[BOTTOM] - border[BOTTOM].width -
- margin[BOTTOM];
- } else if (top != AUTO && height == AUTO && bottom == AUTO) {
- height = box->height;
- bottom = containing_block->height -
- top - margin[TOP] - border[TOP].width -
- padding[TOP] - height -
- padding[BOTTOM] - border[BOTTOM].width -
- margin[BOTTOM];
- } else if (top == AUTO && height != AUTO && bottom != AUTO) {
- top = containing_block->height -
- margin[TOP] - border[TOP].width -
- padding[TOP] - height -
- padding[BOTTOM] - border[BOTTOM].width -
- margin[BOTTOM] - bottom;
- } else if (top != AUTO && height == AUTO && bottom != AUTO) {
- height = containing_block->height -
- top - margin[TOP] - border[TOP].width -
- padding[TOP] - padding[BOTTOM] -
- border[BOTTOM].width - margin[BOTTOM] -
- bottom;
- } else if (top != AUTO && height != AUTO && bottom == AUTO) {
- bottom = containing_block->height -
- top - margin[TOP] - border[TOP].width -
- padding[TOP] - height -
- padding[BOTTOM] - border[BOTTOM].width -
- margin[BOTTOM];
+ has_text_children = false;
+ for (c = inline_container->children; c; c = c->next) {
+ bool is_pre = false;
+
+ if (c->style) {
+ enum css_white_space_e whitespace;
+
+ whitespace = css_computed_white_space(c->style);
+
+ is_pre = (whitespace == CSS_WHITE_SPACE_PRE ||
+ whitespace == CSS_WHITE_SPACE_PRE_LINE ||
+ whitespace == CSS_WHITE_SPACE_PRE_WRAP);
}
+
+ if ((!c->object && !(c->flags & REPLACE_DIM) &&
+ !(c->flags & IFRAME) &&
+ c->text && (c->length || is_pre)) ||
+ c->type == BOX_BR)
+ has_text_children = true;
}
+ /** \todo fix wrapping so that a box with horizontal scrollbar will
+ * shrink back to 'width' if no word is wider than 'width' (Or just set
+ * curwidth = width and have the multiword lines wrap to the min width)
+ */
+ for (c = inline_container->children; c; ) {
#ifdef LAYOUT_DEBUG
- LOG("%i + %i + %i + %i + %i + %i + %i + %i + %i = %i", top, margin[TOP], border[TOP].width, padding[TOP], height, padding[BOTTOM], border[BOTTOM].width, margin[BOTTOM], bottom, containing_block->height);
+ LOG("c %p", c);
#endif
-
- box->y = top + margin[TOP] + border[TOP].width - cy;
- if (containing_block->type == BOX_BLOCK ||
- containing_block->type == BOX_INLINE_BLOCK ||
- containing_block->type == BOX_TABLE_CELL) {
- /* Block-level ancestor => reset container's height */
- containing_block->height -= containing_block->padding[TOP] +
- containing_block->padding[BOTTOM];
- } else {
- /** \todo Inline ancestors */
+ curwidth = inline_container->width;
+ if (!layout_line(c, &curwidth, &y, cx, cy + y, cont, first_line,
+ has_text_children, content, &next))
+ return false;
+ maxwidth = max(maxwidth,curwidth);
+ c = next;
+ first_line = false;
}
- box->height = height;
- layout_apply_minmax_height(box, containing_block);
+
+ inline_container->width = maxwidth;
+ inline_container->height = y;
return true;
}
-/**
- * Compute box offsets for a relatively or absolutely positioned box with
- * respect to a box.
- *
- * \param box box to compute offsets for
- * \param containing_block box to compute percentages with respect to
- * \param top updated to top offset, or AUTO
- * \param right updated to right offset, or AUTO
- * \param bottom updated to bottom offset, or AUTO
- * \param left updated to left offset, or AUTO
- *
- * See CSS 2.1 9.3.2. containing_block must have width and height.
- */
-
-void layout_compute_offsets(struct box *box,
- struct box *containing_block,
- int *top, int *right, int *bottom, int *left)
+/* exported function documented in render/layout.h */
+void
+layout_minmax_table(struct box *table, const struct gui_layout_table *font_func)
{
- uint32_t type;
+ unsigned int i, j;
+ int border_spacing_h = 0;
+ int table_min = 0, table_max = 0;
+ int extra_fixed = 0;
+ float extra_frac = 0;
+ struct column *col = table->col;
+ struct box *row_group, *row, *cell;
+ enum css_width_e wtype;
css_fixed value = 0;
css_unit unit = CSS_UNIT_PX;
- assert(containing_block->width != UNKNOWN_WIDTH &&
- containing_block->width != AUTO &&
- containing_block->height != AUTO);
+ /* check if the widths have already been calculated */
+ if (table->max_width != UNKNOWN_MAX_WIDTH)
+ return;
- /* left */
- type = css_computed_left(box->style, &value, &unit);
- if (type == CSS_LEFT_SET) {
- if (unit == CSS_UNIT_PCT) {
- *left = FPCT_OF_INT_TOINT(value,
- containing_block->width);
- } else {
- *left = FIXTOINT(nscss_len2px(value, unit, box->style));
- }
- } else {
- *left = AUTO;
+ /* start with 0 except for fixed-width columns */
+ for (i = 0; i != table->columns; i++) {
+ if (col[i].type == COLUMN_WIDTH_FIXED)
+ col[i].min = col[i].max = col[i].width;
+ else
+ col[i].min = col[i].max = 0;
}
- /* right */
- type = css_computed_right(box->style, &value, &unit);
- if (type == CSS_RIGHT_SET) {
- if (unit == CSS_UNIT_PCT) {
- *right = FPCT_OF_INT_TOINT(value,
- containing_block->width);
- } else {
- *right = FIXTOINT(nscss_len2px(value, unit,
- box->style));
- }
- } else {
- *right = AUTO;
+ /* border-spacing is used in the separated borders model */
+ if (css_computed_border_collapse(table->style) ==
+ CSS_BORDER_COLLAPSE_SEPARATE) {
+ css_fixed h = 0, v = 0;
+ css_unit hu = CSS_UNIT_PX, vu = CSS_UNIT_PX;
+
+ css_computed_border_spacing(table->style, &h, &hu, &v, &vu);
+
+ border_spacing_h = FIXTOINT(nscss_len2px(h, hu, table->style));
}
- /* top */
- type = css_computed_top(box->style, &value, &unit);
- if (type == CSS_TOP_SET) {
- if (unit == CSS_UNIT_PCT) {
- *top = FPCT_OF_INT_TOINT(value,
- containing_block->height);
- } else {
- *top = FIXTOINT(nscss_len2px(value, unit, box->style));
+ /* 1st pass: consider cells with colspan 1 only */
+ for (row_group = table->children; row_group; row_group =row_group->next)
+ for (row = row_group->children; row; row = row->next)
+ for (cell = row->children; cell; cell = cell->next) {
+ assert(cell->type == BOX_TABLE_CELL);
+ assert(cell->style);
+ /** TODO: Handle colspan="0" correctly.
+ * It's currently converted to 1 in box normaisation */
+ assert(cell->columns != 0);
+
+ if (cell->columns != 1)
+ continue;
+
+ layout_minmax_block(cell, font_func);
+ i = cell->start_column;
+
+ if (col[i].positioned)
+ continue;
+
+ /* update column min, max widths using cell widths */
+ if (col[i].min < cell->min_width)
+ col[i].min = cell->min_width;
+ if (col[i].max < cell->max_width)
+ col[i].max = cell->max_width;
+ }
+
+ /* 2nd pass: cells which span multiple columns */
+ for (row_group = table->children; row_group; row_group =row_group->next)
+ for (row = row_group->children; row; row = row->next)
+ for (cell = row->children; cell; cell = cell->next) {
+ unsigned int flexible_columns = 0;
+ int min = 0, max = 0, fixed_width = 0, extra;
+
+ if (cell->columns == 1)
+ continue;
+
+ layout_minmax_block(cell, font_func);
+ i = cell->start_column;
+
+ /* find min width so far of spanned columns, and count
+ * number of non-fixed spanned columns and total fixed width */
+ for (j = 0; j != cell->columns; j++) {
+ min += col[i + j].min;
+ if (col[i + j].type == COLUMN_WIDTH_FIXED)
+ fixed_width += col[i + j].width;
+ else
+ flexible_columns++;
+ }
+ min += (cell->columns - 1) * border_spacing_h;
+
+ /* distribute extra min to spanned columns */
+ if (min < cell->min_width) {
+ if (flexible_columns == 0) {
+ extra = 1 + (cell->min_width - min) /
+ cell->columns;
+ for (j = 0; j != cell->columns; j++) {
+ col[i + j].min += extra;
+ if (col[i + j].max < col[i + j].min)
+ col[i + j].max = col[i + j].min;
+ }
+ } else {
+ extra = 1 + (cell->min_width - min) /
+ flexible_columns;
+ for (j = 0; j != cell->columns; j++) {
+ if (col[i + j].type !=
+ COLUMN_WIDTH_FIXED) {
+ col[i + j].min += extra;
+ if (col[i + j].max <
+ col[i + j].min)
+ col[i + j].max =
+ col[i + j].min;
+ }
+ }
+ }
+ }
+
+ /* find max width so far of spanned columns */
+ for (j = 0; j != cell->columns; j++)
+ max += col[i + j].max;
+ max += (cell->columns - 1) * border_spacing_h;
+
+ /* distribute extra max to spanned columns */
+ if (max < cell->max_width && flexible_columns) {
+ extra = 1 + (cell->max_width - max) / flexible_columns;
+ for (j = 0; j != cell->columns; j++)
+ if (col[i + j].type != COLUMN_WIDTH_FIXED)
+ col[i + j].max += extra;
}
- } else {
- *top = AUTO;
}
- /* bottom */
- type = css_computed_bottom(box->style, &value, &unit);
- if (type == CSS_BOTTOM_SET) {
- if (unit == CSS_UNIT_PCT) {
- *bottom = FPCT_OF_INT_TOINT(value,
- containing_block->height);
- } else {
- *bottom = FIXTOINT(nscss_len2px(value, unit,
- box->style));
+ for (i = 0; i != table->columns; i++) {
+ if (col[i].max < col[i].min) {
+ box_dump(stderr, table, 0, true);
+ assert(0);
}
- } else {
- *bottom = AUTO;
+ table_min += col[i].min;
+ table_max += col[i].max;
+ }
+
+ /* fixed width takes priority, unless it is too narrow */
+ wtype = css_computed_width(table->style, &value, &unit);
+ if (wtype == CSS_WIDTH_SET && unit != CSS_UNIT_PCT) {
+ int width = FIXTOINT(nscss_len2px(value, unit, table->style));
+ if (table_min < width)
+ table_min = width;
+ if (table_max < width)
+ table_max = width;
}
+
+ /* add margins, border, padding to min, max widths */
+ calculate_mbp_width(table->style, LEFT, true, true, true,
+ &extra_fixed, &extra_frac);
+ calculate_mbp_width(table->style, RIGHT, true, true, true,
+ &extra_fixed, &extra_frac);
+ if (extra_fixed < 0)
+ extra_fixed = 0;
+ if (extra_frac < 0)
+ extra_frac = 0;
+ if (1.0 <= extra_frac)
+ extra_frac = 0.9;
+ table->min_width = (table_min + extra_fixed) / (1.0 - extra_frac);
+ table->max_width = (table_max + extra_fixed) / (1.0 - extra_frac);
+ table->min_width += (table->columns + 1) * border_spacing_h;
+ table->max_width += (table->columns + 1) * border_spacing_h;
+
+ assert(0 <= table->min_width && table->min_width <= table->max_width);
}
@@ -5069,9 +5021,10 @@ void layout_compute_offsets(struct box *box,
* \param desc_x1 updated to right of box's bbox
* \param desc_y1 updated to bottom of box's bbox
*/
-
-static void layout_get_box_bbox(struct box *box, int *desc_x0, int *desc_y0,
- int *desc_x1, int *desc_y1)
+static void
+layout_get_box_bbox(struct box *box,
+ int *desc_x0, int *desc_y0,
+ int *desc_x1, int *desc_y1)
{
*desc_x0 = -box->border[LEFT].width;
*desc_y0 = -box->border[TOP].width;
@@ -5106,9 +5059,11 @@ static void layout_get_box_bbox(struct box *box, int *desc_x0, int *desc_y0,
* \param off_x offset to apply to child->x coord to treat as child of box
* \param off_y offset to apply to child->y coord to treat as child of box
*/
-
-static void layout_update_descendant_bbox(struct box *box, struct box *child,
- int off_x, int off_y)
+static void
+layout_update_descendant_bbox(struct box *box,
+ struct box *child,
+ int off_x,
+ int off_y)
{
int child_desc_x0, child_desc_y0, child_desc_x1, child_desc_y1;
@@ -5161,13 +5116,7 @@ static void layout_update_descendant_bbox(struct box *box, struct box *child,
}
-/**
- * Recursively calculate the descendant_[xy][01] values for a laid-out box tree
- * and inform iframe browser windows of their size and position.
- *
- * \param box tree of boxes to update
- */
-
+/* exported function documented in render/layout.h */
void layout_calculate_descendant_bboxes(struct box *box)
{
struct box *child;
@@ -5255,4 +5204,3 @@ void layout_calculate_descendant_bboxes(struct box *box)
layout_update_descendant_bbox(box, child, 0, 0);
}
}
-
diff --git a/render/layout.h b/render/layout.h
index f4117e2..ff0da5a 100644
--- a/render/layout.h
+++ b/render/layout.h
@@ -16,7 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
+/**
+ * \file
* HTML layout (interface).
*
* The main interface to the layout code is layout_document(), which takes a
@@ -29,11 +30,47 @@
struct box;
struct html_content;
+struct gui_layout_table;
+/**
+ * Calculate positions of boxes in a document.
+ *
+ * \param content content of type CONTENT_HTML
+ * \param width available width
+ * \param height available height
+ * \return true on success, false on memory exhaustion
+ */
bool layout_document(struct html_content *content, int width, int height);
-bool layout_inline_container(struct box *box, int width,
- struct box *cont, int cx, int cy, struct html_content *content);
+
+/**
+ * Layout lines of text or inline boxes with floats.
+ *
+ * \param inline_container inline container box
+ * \param width horizontal space available
+ * \param cont ancestor box which defines horizontal space, for floats
+ * \param cx box position relative to cont
+ * \param cy box position relative to cont
+ * \param content memory pool for any new boxes
+ * \return true on success, false on memory exhaustion
+ */
+bool layout_inline_container(struct box *box, int width, struct box *cont, int cx, int cy, struct html_content *content);
+
+/**
+ * Recursively calculate the descendant_[xy][01] values for a laid-out box tree
+ * and inform iframe browser windows of their size and position.
+ *
+ * \param box tree of boxes to update
+ */
void layout_calculate_descendant_bboxes(struct box *box);
-void layout_minmax_table(struct box *table,
- const struct font_functions *font_func);
+
+/**
+ * Calculate minimum and maximum width of a table.
+ *
+ * \param table box of type TABLE
+ * \param font_func Font functions
+ * \post table->min_width and table->max_width filled in,
+ * 0 <= table->min_width <= table->max_width
+ */
+void layout_minmax_table(struct box *table, const struct gui_layout_table *font_func);
+
#endif
diff --git a/render/search.c b/render/search.c
index b586ff5..f5e231a 100644
--- a/render/search.c
+++ b/render/search.c
@@ -34,6 +34,7 @@
#include "content/hlcache.h"
#include "desktop/selection.h"
#include "desktop/gui_search.h"
+#include "desktop/gui_misc.h"
#include "desktop/gui_internal.h"
#include "render/box.h"
@@ -85,13 +86,13 @@ struct search_context * search_create_context(struct content *c,
context = malloc(sizeof(struct search_context));
if (context == NULL) {
- warn_user("NoMemory", 0);
+ guit->misc->warning("NoMemory", 0);
return NULL;
}
search_head = malloc(sizeof(struct list_entry));
if (search_head == NULL) {
- warn_user("NoMemory", 0);
+ guit->misc->warning("NoMemory", 0);
free(context);
return NULL;
}
@@ -282,7 +283,7 @@ static struct list_entry *add_entry(unsigned start_idx, unsigned end_idx,
/* found string in box => add to list */
entry = calloc(1, sizeof(*entry));
if (!entry) {
- warn_user("NoMemory", 0);
+ guit->misc->warning("NoMemory", 0);
return NULL;
}
@@ -548,7 +549,7 @@ void search_step(struct search_context *context, search_flags_t flags,
int i = 0;
if (context == NULL) {
- warn_user("SearchError", 0);
+ guit->misc->warning("SearchError", 0);
return;
}
diff --git a/render/textplain.c b/render/textplain.c
index c9f83f9..c825b79 100644
--- a/render/textplain.c
+++ b/render/textplain.c
@@ -47,7 +47,8 @@
#include "desktop/search.h"
#include "desktop/selection.h"
#include "desktop/textinput.h"
-#include "desktop/font.h"
+#include "desktop/gui_layout.h"
+#include "desktop/gui_internal.h"
#include "render/search.h"
#include "render/textplain.h"
@@ -466,13 +467,20 @@ void textplain_reformat(struct content *c, int width, int height)
size_t columns = 80;
int character_width;
size_t line_start;
+ nserror res;
LOG("content %p w:%d h:%d", c, width, height);
/* compute available columns (assuming monospaced font) - use 8
- * characters for better accuracy */
- if (!nsfont.font_width(&textplain_style, "ABCDEFGH", 8, &character_width))
+ * characters for better accuracy
+ */
+ res = guit->layout->width(&textplain_style,
+ "ABCDEFGH", 8,
+ &character_width);
+ if (res != NSERROR_OK) {
return;
+ }
+
columns = (width - MARGIN - MARGIN) * 8 / character_width;
textplain_tab_width = (TAB_WIDTH * character_width) / 8;
@@ -916,6 +924,7 @@ bool textplain_redraw(struct content *c, struct content_redraw_data *data,
size_t next_offset = offset;
int width;
int ntx;
+ nserror res;
while (next_offset < length && text_d[next_offset] != '\t')
next_offset = utf8_next(text_d, length, next_offset);
@@ -932,10 +941,14 @@ bool textplain_redraw(struct content *c, struct content_redraw_data *data,
if (next_offset >= length)
break;
+ res = guit->layout->width(&textplain_style,
+ &text_d[offset],
+ next_offset - offset,
+ &width);
/* locate end of string and align to next tab position */
- if (nsfont.font_width(&textplain_style, &text_d[offset],
- next_offset - offset, &width))
+ if (res == NSERROR_OK) {
tx += (int)(width * data->scale);
+ }
ntx = x + ((1 + (tx - x) / tab_width) * tab_width);
@@ -1105,16 +1118,20 @@ size_t textplain_offset_from_coords(struct content *c, int x, int y, int dir)
while (next_offset < length && text[next_offset] != '\t')
next_offset = utf8_next(text, length, next_offset);
- if (next_offset < length)
- nsfont.font_width(&textplain_style, text, next_offset, &width);
+ if (next_offset < length) {
+ guit->layout->width(&textplain_style,
+ text,
+ next_offset,
+ &width);
+ }
if (x <= width) {
int pixel_offset;
size_t char_offset;
- nsfont.font_position_in_string(&textplain_style,
- text, next_offset, x,
- &char_offset, &pixel_offset);
+ guit->layout->position(&textplain_style,
+ text, next_offset, x,
+ &char_offset, &pixel_offset);
idx += char_offset;
break;
@@ -1192,10 +1209,12 @@ int textplain_coord_from_offset(const char *text, size_t offset, size_t length)
size_t next_offset = 0;
int tx;
- while (next_offset < offset && text[next_offset] != '\t')
+ while (next_offset < offset && text[next_offset] != '\t') {
next_offset = utf8_next(text, length, next_offset);
+ }
+
+ guit->layout->width(&textplain_style, text, next_offset, &tx);
- nsfont.font_width(&textplain_style, text, next_offset, &tx);
x += tx;
if (next_offset >= offset)
diff --git a/riscos/401login.c b/riscos/401login.c
index acb7a01..1494b85 100644
--- a/riscos/401login.c
+++ b/riscos/401login.c
@@ -99,7 +99,7 @@ void ro_gui_401login_open(nsurl *url, lwc_string *host, const char *realm,
session = calloc(1, sizeof(struct session_401));
if (!session) {
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return;
}
@@ -133,7 +133,7 @@ void ro_gui_401login_open(nsurl *url, lwc_string *host, const char *realm,
nsurl_unref(session->url);
lwc_string_unref(session->host);
free(session);
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return;
}
@@ -195,7 +195,7 @@ void ro_gui_401login_close(wimp_w w)
error = xwimp_delete_window(w);
if (error) {
LOG("xwimp_delete_window: 0x%x:%s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
ro_gui_wimp_event_finalise(w);
}
@@ -216,7 +216,7 @@ bool ro_gui_401login_apply(wimp_w w)
auth = malloc(strlen(session->uname) + strlen(session->pwd) + 2);
if (!auth) {
LOG("calloc failed");
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return false;
}
diff --git a/riscos/bitmap.c b/riscos/bitmap.c
index 162a8c6..8fa7265 100644
--- a/riscos/bitmap.c
+++ b/riscos/bitmap.c
@@ -274,7 +274,7 @@ bool riscos_bitmap_save(void *vbitmap, const char *path, unsigned flags)
os_error *error;
if (bitmap == NULL) {
- warn_user("SaveError", messages_get("SprIsNull"));
+ ro_warn_user("SaveError", messages_get("SprIsNull"));
return false;
}
@@ -289,7 +289,7 @@ bool riscos_bitmap_save(void *vbitmap, const char *path, unsigned flags)
(bitmap->sprite_area), path);
if (error) {
LOG("xosspriteop_save_sprite_file: 0x%x: %s", error->errnum, error->errmess);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
return false;
}
return true;
@@ -319,7 +319,7 @@ bool riscos_bitmap_save(void *vbitmap, const char *path, unsigned flags)
chunk_buf = malloc(SAVE_CHUNK_SIZE);
if (!chunk_buf) {
- warn_user("NoMemory", NULL);
+ ro_warn_user("NoMemory", NULL);
return false;
}
@@ -350,7 +350,7 @@ bool riscos_bitmap_save(void *vbitmap, const char *path, unsigned flags)
if (error) {
LOG("xosfind_openoutw: 0x%x: %s", error->errnum, error->errmess);
free(chunk_buf);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
return false;
}
@@ -365,7 +365,7 @@ bool riscos_bitmap_save(void *vbitmap, const char *path, unsigned flags)
LOG("xosgbpb_writew: 0x%x: %s", error->errnum, error->errmess);
free(chunk_buf);
xosfind_closew(fw);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
return false;
}
@@ -410,7 +410,7 @@ bool riscos_bitmap_save(void *vbitmap, const char *path, unsigned flags)
LOG("xosgbpb_writew: 0x%x: %s", error->errnum, error->errmess);
free(chunk_buf);
xosfind_closew(fw);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
return false;
}
}
@@ -418,13 +418,13 @@ bool riscos_bitmap_save(void *vbitmap, const char *path, unsigned flags)
error = xosfind_closew(fw);
if (error) {
LOG("xosfind_closew: 0x%x: %s", error->errnum, error->errmess);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
}
error = xosfile_set_type(path, osfile_TYPE_SPRITE);
if (error) {
LOG("xosfile_set_type: 0x%x: %s", error->errnum, error->errmess);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
}
free(chunk_buf);
diff --git a/riscos/configure.c b/riscos/configure.c
index 62937b5..9953fb9 100644
--- a/riscos/configure.c
+++ b/riscos/configure.c
@@ -185,7 +185,7 @@ void ro_gui_configure_open_window(wimp_open *open)
struct configure_tool *tool;
if (!ro_gui_configure_translate()) {
- warn_user("ro_gui_configure_translate failed", 0);
+ ro_warn_user("ro_gui_configure_translate failed", 0);
return;
}
@@ -226,7 +226,7 @@ void ro_gui_configure_open_window(wimp_open *open)
0, -16384, 16384, 0);
if (error) {
LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
@@ -249,7 +249,7 @@ void ro_gui_configure_open_window(wimp_open *open)
error = xwimp_set_extent(open->w, &extent);
if (error) {
LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
configure_height = height;
@@ -260,7 +260,7 @@ void ro_gui_configure_open_window(wimp_open *open)
error = xwimp_open_window(open);
if (error) {
LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
}
diff --git a/riscos/configure/con_fonts.c b/riscos/configure/con_fonts.c
index 5e1b270..fdae976 100644
--- a/riscos/configure/con_fonts.c
+++ b/riscos/configure/con_fonts.c
@@ -17,6 +17,7 @@
*/
#include <stdbool.h>
+#include <stddef.h>
#include "utils/nsoption.h"
#include "utils/messages.h"
@@ -193,7 +194,7 @@ bool ro_gui_options_fonts_init_menu(void)
default_menu = malloc(wimp_SIZEOF_MENU(5));
if (!default_menu) {
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return false;
}
default_menu->title_data.indirected_text.text =
diff --git a/riscos/configure/con_image.c b/riscos/configure/con_image.c
index 1c9531c..cab7ef0 100644
--- a/riscos/configure/con_image.c
+++ b/riscos/configure/con_image.c
@@ -153,7 +153,7 @@ void ro_gui_options_image_redraw(wimp_draw *redraw)
if (error) {
LOG("xwimp_get_icon_state: 0x%x: %s",
error->errnum, error->errmess);
- warn_user("MenuError", error->errmess);
+ ro_warn_user("MenuError", error->errmess);
return;
}
diff --git a/riscos/configure/con_language.c b/riscos/configure/con_language.c
index 48c20fc..b12a795 100644
--- a/riscos/configure/con_language.c
+++ b/riscos/configure/con_language.c
@@ -100,7 +100,7 @@ bool ro_gui_options_language_ok(wimp_w w)
nsoption_set_charp(language, temp);
} else {
LOG("No memory to duplicate language code");
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
}
}
}
@@ -115,7 +115,7 @@ bool ro_gui_options_language_ok(wimp_w w)
nsoption_set_charp(accept_language,temp);
} else {
LOG("No memory to duplicate language code");
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
}
}
}
diff --git a/riscos/configure/con_theme.c b/riscos/configure/con_theme.c
index bee2231..e805384 100644
--- a/riscos/configure/con_theme.c
+++ b/riscos/configure/con_theme.c
@@ -19,11 +19,17 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
-#include "oslib/osspriteop.h"
-#include "oslib/wimp.h"
-#include "oslib/wimpspriteop.h"
+#include <oslib/osspriteop.h>
+#include <oslib/wimp.h>
+#include <oslib/wimpspriteop.h>
+
#include "utils/config.h"
#include "utils/nsoption.h"
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "utils/utils.h"
+
+#include "riscos/gui.h"
#include "riscos/configure/configure.h"
#include "riscos/configure.h"
#include "riscos/dialog.h"
@@ -34,9 +40,6 @@
#include "riscos/wimp.h"
#include "riscos/wimp_event.h"
#include "riscos/wimputils.h"
-#include "utils/log.h"
-#include "utils/messages.h"
-#include "utils/utils.h"
#define THEME_PANE_AREA 0
@@ -175,7 +178,7 @@ void ro_gui_options_theme_finalise(wimp_w w)
error = xwimp_delete_window(theme_pane);
if (error) {
LOG("xwimp_delete_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
theme_pane = 0;
}
@@ -268,7 +271,7 @@ void ro_gui_options_theme_load(void)
toolbar_display = calloc(sizeof(struct toolbar_display), 1);
if (!toolbar_display) {
LOG("No memory for calloc()");
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return;
}
toolbar_display->toolbar = toolbar;
@@ -290,7 +293,7 @@ void ro_gui_options_theme_load(void)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
diff --git a/riscos/content-handlers/artworks.c b/riscos/content-handlers/artworks.c
index 9ec04a7..4b5d27a 100644
--- a/riscos/content-handlers/artworks.c
+++ b/riscos/content-handlers/artworks.c
@@ -104,7 +104,7 @@ extern os_error *awrender_render(const char *doc,
void *workspace);
static nserror artworks_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c);
static bool artworks_convert(struct content *c);
@@ -132,7 +132,7 @@ CONTENT_FACTORY_REGISTER_TYPES(artworks, artworks_types,
artworks_content_handler)
nserror artworks_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c)
{
diff --git a/riscos/content-handlers/draw.c b/riscos/content-handlers/draw.c
index c2524d4..37f6911 100644
--- a/riscos/content-handlers/draw.c
+++ b/riscos/content-handlers/draw.c
@@ -44,7 +44,7 @@ typedef struct draw_content {
} draw_content;
static nserror draw_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c);
static bool draw_convert(struct content *c);
@@ -74,7 +74,7 @@ static const char *draw_types[] = {
CONTENT_FACTORY_REGISTER_TYPES(draw, draw_types, draw_content_handler)
nserror draw_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c)
{
diff --git a/riscos/content-handlers/sprite.c b/riscos/content-handlers/sprite.c
index 2b28132..a1a6eb1 100644
--- a/riscos/content-handlers/sprite.c
+++ b/riscos/content-handlers/sprite.c
@@ -46,7 +46,7 @@ typedef struct sprite_content {
} sprite_content;
static nserror sprite_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c);
static bool sprite_convert(struct content *c);
@@ -73,7 +73,7 @@ static const char *sprite_types[] = {
CONTENT_FACTORY_REGISTER_TYPES(sprite, sprite_types, sprite_content_handler)
nserror sprite_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
+ lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c)
{
diff --git a/riscos/dialog.c b/riscos/dialog.c
index e5c972f..d3f6caf 100644
--- a/riscos/dialog.c
+++ b/riscos/dialog.c
@@ -306,7 +306,7 @@ void ro_gui_dialog_open(wimp_w w)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
dx = (state.visible.x1 - state.visible.x0) / 2;
@@ -353,7 +353,7 @@ void ro_gui_dialog_close(wimp_w close)
error = xwimp_get_caret_position(&caret);
if (error) {
LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
} else if (caret.w == close) {
/* Check if we are a persistent window */
if (i < MAX_PERSISTENT) {
@@ -364,7 +364,7 @@ void ro_gui_dialog_close(wimp_w close)
/* parent may have been closed first */
if ((error) && (error->errnum != 0x287)) {
LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
}
@@ -372,7 +372,7 @@ void ro_gui_dialog_close(wimp_w close)
error = xwimp_close_window(close);
if (error) {
LOG("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
@@ -406,7 +406,7 @@ bool ro_gui_dialog_open_top(wimp_w w, struct toolbar *toolbar,
state.w = w;
error = xwimp_get_window_state(&state);
if (error) {
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -457,7 +457,7 @@ void ro_gui_dialog_open_at_pointer(wimp_w w)
error = xwimp_get_pointer_info(&ptr);
if (error) {
LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -480,7 +480,7 @@ void ro_gui_dialog_open_xy(wimp_w w, int x, int y)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
dx = (state.visible.x1 - state.visible.x0);
@@ -495,7 +495,7 @@ void ro_gui_dialog_open_xy(wimp_w w, int x, int y)
error = xwimp_close_window(w);
if (error) {
LOG("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -523,7 +523,7 @@ void ro_gui_dialog_open_centre_parent(wimp_w parent, wimp_w child) {
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
scroll_width = ro_get_vscroll_width(parent);
@@ -540,7 +540,7 @@ void ro_gui_dialog_open_centre_parent(wimp_w parent, wimp_w child) {
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -770,7 +770,7 @@ bool ro_gui_dialog_openurl_apply(wimp_w w) {
nsurl_unref(url);
}
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ ro_warn_user(messages_get_errorcode(error), 0);
return false;
}
diff --git a/riscos/download.c b/riscos/download.c
index 6595874..cddb449 100644
--- a/riscos/download.c
+++ b/riscos/download.c
@@ -32,7 +32,6 @@
#include <assert.h>
#include <string.h>
-#include <sys/time.h>
#include <time.h>
#include <curl/curl.h>
#include <libwapcaplet/libwapcaplet.h>
@@ -46,12 +45,14 @@
#include "oslib/wimp.h"
#include "oslib/wimpspriteop.h"
+#include "utils/sys_time.h"
#include "utils/nsoption.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/nsurl.h"
#include "utils/utf8.h"
#include "utils/utils.h"
+#include "utils/string.h"
#include "utils/corestrings.h"
#include "desktop/gui_download.h"
#include "desktop/download.h"
@@ -260,7 +261,7 @@ static nserror download_ro_filetype(download_context *ctx, bits *ftype_out)
error = xmimemaptranslate_mime_type_to_filetype(mime_type, &ftype);
if (error) {
LOG("xmimemaptranslate_mime_type_to_filetype: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
ftype = 0xffd;
}
}
@@ -293,7 +294,7 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui)
dw = malloc(sizeof *dw);
if (!dw) {
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return 0;
}
@@ -322,7 +323,7 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui)
/* get filetype */
err = download_ro_filetype(ctx, &dw->file_type);
if (err != NSERROR_OK) {
- warn_user(messages_get_errorcode(err), 0);
+ ro_warn_user(messages_get_errorcode(err), 0);
free(dw);
return 0;
}
@@ -338,7 +339,7 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui)
temp_name, 0, &dw->file);
if (error) {
LOG("xosfind_openoutw: 0x%x: %s", error->errnum, error->errmess);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
free(dw);
return 0;
}
@@ -371,7 +372,7 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui)
if (filename == NULL) {
LOG("Failed to establish download filename.");
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
free(dw);
return 0;
}
@@ -403,7 +404,7 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui)
/* badenc should never happen */
assert(err !=NSERROR_BAD_ENCODING);
LOG("utf8_to_local_encoding failed");
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
free(dw);
return 0;
}
@@ -429,7 +430,7 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui)
error = xwimp_create_window(download_template, &dw->window);
if (error) {
LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
free(dw);
return 0;
}
@@ -452,7 +453,7 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui)
/* issue the warning now, so that it appears in front of the download
* window! */
if (space_warning)
- warn_user("DownloadWarn", messages_get("NoDiscSpace"));
+ ro_warn_user("DownloadWarn", messages_get("NoDiscSpace"));
return dw;
}
@@ -484,7 +485,7 @@ static void gui_download_window_error(struct gui_download_window *dw,
wimp_ICON_FG_COLOUR);
if (error) {
LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
/* grey out pathname icon */
@@ -492,7 +493,7 @@ static void gui_download_window_error(struct gui_download_window *dw,
wimp_ICON_SHADED, 0);
if (error) {
LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
/* grey out file icon */
@@ -500,7 +501,7 @@ static void gui_download_window_error(struct gui_download_window *dw,
wimp_ICON_SHADED, wimp_ICON_SHADED);
if (error) {
LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
ro_gui_download_window_hide_caret(dw);
@@ -538,7 +539,7 @@ static nserror gui_download_window_data(struct gui_download_window *dw,
return NSERROR_OK;
}
- warn_user("SaveError", msg);
+ ro_warn_user("SaveError", msg);
if (dw->saved) {
/* try to continue with the temporary file */
@@ -554,20 +555,20 @@ static nserror gui_download_window_data(struct gui_download_window *dw,
wimp_ICON_SHADED, 0);
if (error) {
LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_DESTINATION,
wimp_ICON_DELETED, wimp_ICON_DELETED);
if (error) {
LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
error = xwimp_set_icon_state(dw->window,
ICON_DOWNLOAD_PATH, wimp_ICON_DELETED, 0);
if (error) {
LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
continue;
@@ -716,13 +717,13 @@ void ro_gui_download_update_status(struct gui_download_window *dw)
download_progress_y1);
if (error) {
LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_STATUS, 0, 0);
if (error) {
LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
if (dw->ctx) {
@@ -758,13 +759,13 @@ void ro_gui_download_window_hide_caret(struct gui_download_window *dw)
error = xwimp_get_caret_position(&caret);
if (error) {
LOG("xwimp_get_caret_position: 0x%x : %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
else if (caret.w == dw->window) {
error = xwimp_set_caret_position(dw->window, (wimp_i)-1, 0, 0, 1 << 25, -1);
if (error) {
LOG("xwimp_get_caret_position: 0x%x : %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
}
@@ -790,7 +791,7 @@ static void gui_download_window_done(struct gui_download_window *dw)
error = xosfind_closew(dw->file);
if (error) {
LOG("xosfind_closew: 0x%x: %s", error->errnum, error->errmess);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
}
dw->file = 0;
@@ -799,7 +800,7 @@ static void gui_download_window_done(struct gui_download_window *dw)
dw->file_type);
if (error) {
LOG("xosfile_set_type: 0x%x: %s", error->errnum, error->errmess);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
}
if (dw->send_dataload) {
@@ -855,7 +856,7 @@ bool ro_gui_download_click(wimp_pointer *pointer)
error = xos_cli(command);
if (error) {
LOG("xos_cli: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
}
}
}
@@ -885,7 +886,7 @@ bool ro_gui_download_keypress(wimp_key *key)
const char *name = ro_gui_get_icon_string(dw->window,
ICON_DOWNLOAD_PATH);
if (!strrchr(name, '.')) {
- warn_user("NoPathError", NULL);
+ ro_warn_user("NoPathError", NULL);
return true;
}
ro_gui_convert_save_path(dw->path, sizeof dw->path, name);
@@ -928,7 +929,7 @@ static void ro_gui_download_drag_end(wimp_dragged *drag, void *data)
error = xwimp_get_pointer_info(&pointer);
if (error) {
LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -958,7 +959,7 @@ static void ro_gui_download_drag_end(wimp_dragged *drag, void *data)
pointer.w, pointer.i, 0);
if (error) {
LOG("xwimp_send_message_to_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
gui_current_drag_type = GUI_DRAG_DOWNLOAD_SAVE;
@@ -1178,7 +1179,7 @@ os_error *ro_gui_download_move(struct gui_download_window *dw,
fileswitch_ATTR_OWNER_WRITE);
if (error) {
LOG("xosfile_write: 0x%x: %s", error->errnum, error->errmess);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
}
error = xosfind_openupw(osfind_NO_PATH | osfind_ERROR_IF_DIR,
@@ -1200,7 +1201,7 @@ os_error *ro_gui_download_move(struct gui_download_window *dw,
dw->file_type);
if (error) {
LOG("xosfile_set_type: 0x%x: %s", error->errnum, error->errmess);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
}
}
@@ -1288,19 +1289,19 @@ bool ro_gui_download_save(struct gui_download_window *dw,
default:
error = xosfile_make_error(file_name, obj_type);
assert(error);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
return false;
}
}
if (!ro_gui_download_check_space(dw, file_name, temp_name)) {
- warn_user("SaveError", messages_get("NoDiscSpace"));
+ ro_warn_user("SaveError", messages_get("NoDiscSpace"));
return false;
}
error = ro_gui_download_move(dw, file_name, temp_name);
if (error) {
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
/* try to reopen at old location so that the download can continue
to the temporary file */
@@ -1335,7 +1336,7 @@ bool ro_gui_download_save(struct gui_download_window *dw,
wimp_ICON_SHADED, wimp_ICON_SHADED);
if (error) {
LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
/* hide writeable path icon and show destination icon
@@ -1348,13 +1349,13 @@ bool ro_gui_download_save(struct gui_download_window *dw,
wimp_ICON_DELETED, wimp_ICON_DELETED);
if (error) {
LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
error = xwimp_set_icon_state(dw->window,
ICON_DOWNLOAD_DESTINATION, wimp_ICON_DELETED, 0);
if (error) {
LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
ro_gui_download_window_hide_caret(dw);
@@ -1400,7 +1401,7 @@ void ro_gui_download_send_dataload(struct gui_download_window *dw)
*/
if (error && error->errnum != error_WIMP_BAD_HANDLE) {
LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
riscos_schedule(2000, ro_gui_download_window_destroy_wrapper, dw);
@@ -1481,7 +1482,7 @@ bool ro_gui_download_window_destroy(struct gui_download_window *dw, bool quit)
error = xwimp_delete_window(dw->window);
if (error) {
LOG("xwimp_delete_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
ro_gui_wimp_event_finalise(dw->window);
@@ -1490,7 +1491,7 @@ bool ro_gui_download_window_destroy(struct gui_download_window *dw, bool quit)
error = xosfind_closew(dw->file);
if (error) {
LOG("xosfind_closew: 0x%x: %s", error->errnum, error->errmess);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
}
}
@@ -1501,7 +1502,7 @@ bool ro_gui_download_window_destroy(struct gui_download_window *dw, bool quit)
error = xosfile_delete(temp_name, 0, 0, 0, 0, 0);
if (error) {
LOG("xosfile_delete: 0x%x: %s", error->errnum, error->errmess);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
}
}
diff --git a/riscos/filetype.c b/riscos/filetype.c
index 63f8a85..1a16df0 100644
--- a/riscos/filetype.c
+++ b/riscos/filetype.c
@@ -21,6 +21,7 @@
#include <unixlib/local.h>
#include "oslib/mimemap.h"
#include "oslib/osfile.h"
+
#include "content/content.h"
#include "content/fetch.h"
#include "content/hlcache.h"
@@ -28,6 +29,7 @@
#include "utils/config.h"
#include "utils/log.h"
#include "utils/utils.h"
+#include "riscos/gui.h"
/* type_map must be in sorted order by file_type */
struct type_entry {
@@ -73,7 +75,7 @@ const char *fetch_filetype(const char *unix_path)
if (!path) {
LOG("Insufficient memory for calloc");
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return "application/riscos";
}
@@ -156,7 +158,7 @@ char *fetch_mimetype(const char *ro_path)
if (!mime) {
LOG("Insufficient memory for calloc");
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return 0;
}
@@ -323,7 +325,7 @@ bits ro_filetype_from_unix_path(const char *unix_path)
if (!path) {
LOG("Insufficient memory for calloc");
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return osfile_TYPE_DATA;
}
diff --git a/riscos/font.c b/riscos/font.c
index 7947365..2f2ba9a 100644
--- a/riscos/font.c
+++ b/riscos/font.c
@@ -16,7 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
+/**
+ * \file
* RISC OS implementation of Font handling.
*
* The RUfl is used to handle and render fonts.
@@ -33,26 +34,11 @@
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/utils.h"
-#include "desktop/font.h"
+#include "desktop/gui_layout.h"
#include "riscos/gui.h"
#include "riscos/font.h"
-static void nsfont_check_option(char **option, const char *family,
- const char *fallback);
-static int nsfont_list_cmp(const void *keyval, const void *datum);
-static void nsfont_check_fonts(void);
-static void ro_gui_wimp_desktop_font(char *family, size_t bufsize, int *psize,
- rufl_style *pstyle);
-static bool nsfont_width(const plot_font_style_t *fstyle,
- const char *string, size_t length,
- int *width);
-static bool nsfont_position_in_string(const plot_font_style_t *fstyle,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x);
-static bool nsfont_split(const plot_font_style_t *fstyle,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x);
/** desktop font, size and style being used */
char ro_gui_desktop_font_family[80];
@@ -60,18 +46,70 @@ int ro_gui_desktop_font_size = 12;
rufl_style ro_gui_desktop_font_style = rufl_WEIGHT_400;
bool no_font_blending = false;
-const struct font_functions nsfont = {
- nsfont_width,
- nsfont_position_in_string,
- nsfont_split
-};
+
+/**
+ * Check that at least Homerton.Medium is available.
+ */
+static void nsfont_check_fonts(void)
+{
+ char s[252];
+ font_f font;
+ os_error *error;
+
+ error = xfont_find_font("Homerton.Medium\\ELatin1",
+ 160, 160, 0, 0, &font, 0, 0);
+ if (error) {
+ if (error->errnum == error_FILE_NOT_FOUND) {
+ xwimp_start_task("TaskWindow -wimpslot 200K -quit "
+ "<NetSurf$Dir>.FixFonts", 0);
+ die("FontBadInst");
+ } else {
+ LOG("xfont_find_font: 0x%x: %s", error->errnum, error->errmess);
+ snprintf(s, sizeof s, messages_get("FontError"),
+ error->errmess);
+ die(s);
+ }
+ }
+
+ error = xfont_lose_font(font);
+ if (error) {
+ LOG("xfont_lose_font: 0x%x: %s", error->errnum, error->errmess);
+ snprintf(s, sizeof s, messages_get("FontError"),
+ error->errmess);
+ die(s);
+ }
+}
+
+
+/**
+ * Check that a font option is valid, and fix it if not.
+ *
+ * \param option pointer to option, as used by options.[ch]
+ * \param family font family to use if option is not set, or the set
+ * family is not available
+ * \param fallback font family to use if family is not available either
+ */
+static void nsfont_check_option(char **option, const char *family,
+ const char *fallback)
+{
+ if (*option && !nsfont_exists(*option)) {
+ free(*option);
+ *option = 0;
+ }
+ if (!*option) {
+ if (nsfont_exists(family))
+ *option = strdup(family);
+ else
+ *option = strdup(fallback);
+ }
+}
+
/**
* Initialize font handling.
*
* Exits through die() on error.
*/
-
void nsfont_init(void)
{
const char *fallback;
@@ -133,28 +171,15 @@ const char *nsfont_fallback_font(void)
return fallback;
}
+
/**
- * Check that a font option is valid, and fix it if not.
- *
- * \param option pointer to option, as used by options.[ch]
- * \param family font family to use if option is not set, or the set
- * family is not available
- * \param fallback font family to use if family is not available either
+ * bsearch comparison routine
*/
-
-void nsfont_check_option(char **option, const char *family,
- const char *fallback)
+static int nsfont_list_cmp(const void *keyval, const void *datum)
{
- if (*option && !nsfont_exists(*option)) {
- free(*option);
- *option = 0;
- }
- if (!*option) {
- if (nsfont_exists(family))
- *option = strdup(family);
- else
- *option = strdup(fallback);
- }
+ const char *key = keyval;
+ const char * const *entry = datum;
+ return strcasecmp(key, *entry);
}
@@ -164,7 +189,6 @@ void nsfont_check_option(char **option, const char *family,
* \param font_family name of font family
* \return true if the family is available
*/
-
bool nsfont_exists(const char *font_family)
{
if (bsearch(font_family, rufl_family_list,
@@ -175,49 +199,6 @@ bool nsfont_exists(const char *font_family)
}
-int nsfont_list_cmp(const void *keyval, const void *datum)
-{
- const char *key = keyval;
- const char * const *entry = datum;
- return strcasecmp(key, *entry);
-}
-
-
-/**
- * Check that at least Homerton.Medium is available.
- */
-
-void nsfont_check_fonts(void)
-{
- char s[252];
- font_f font;
- os_error *error;
-
- error = xfont_find_font("Homerton.Medium\\ELatin1",
- 160, 160, 0, 0, &font, 0, 0);
- if (error) {
- if (error->errnum == error_FILE_NOT_FOUND) {
- xwimp_start_task("TaskWindow -wimpslot 200K -quit "
- "<NetSurf$Dir>.FixFonts", 0);
- die("FontBadInst");
- } else {
- LOG("xfont_find_font: 0x%x: %s", error->errnum, error->errmess);
- snprintf(s, sizeof s, messages_get("FontError"),
- error->errmess);
- die(s);
- }
- }
-
- error = xfont_lose_font(font);
- if (error) {
- LOG("xfont_lose_font: 0x%x: %s", error->errnum, error->errmess);
- snprintf(s, sizeof s, messages_get("FontError"),
- error->errmess);
- die(s);
- }
-}
-
-
/**
* Measure the width of a string.
*
@@ -227,8 +208,8 @@ void nsfont_check_fonts(void)
* \param width updated to width of string[0..length)
* \return true on success, false on error and error reported
*/
-
-bool nsfont_width(const plot_font_style_t *fstyle,
+static nserror
+ro_font_width(const plot_font_style_t *fstyle,
const char *string, size_t length,
int *width)
{
@@ -240,7 +221,7 @@ bool nsfont_width(const plot_font_style_t *fstyle,
nsfont_read_style(fstyle, &font_family, &font_size, &font_style);
if (font_size == 0) {
*width = 0;
- return true;
+ return NSERROR_OK;
}
code = rufl_width(font_family, font_style, font_size,
@@ -251,13 +232,13 @@ bool nsfont_width(const plot_font_style_t *fstyle,
LOG("rufl_width: rufl_FONT_MANAGER_ERROR: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess);
else
LOG("rufl_width: 0x%x", code);
-/* warn_user("MiscError", "font error"); */
+/* ro_warn_user("MiscError", "font error"); */
*width = 0;
- return false;
+ return NSERROR_INVALID;
}
*width /= 2;
- return true;
+ return NSERROR_OK;
}
@@ -272,8 +253,8 @@ bool nsfont_width(const plot_font_style_t *fstyle,
* \param actual_x updated to x coordinate of character closest to x
* \return true on success, false on error and error reported
*/
-
-bool nsfont_position_in_string(const plot_font_style_t *fstyle,
+static nserror
+ro_font_position(const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x)
{
@@ -286,7 +267,7 @@ bool nsfont_position_in_string(const plot_font_style_t *fstyle,
if (font_size == 0) {
*char_offset = 0;
*actual_x = 0;
- return true;
+ return NSERROR_OK;
}
code = rufl_x_to_offset(font_family, font_style, font_size,
@@ -297,14 +278,15 @@ bool nsfont_position_in_string(const plot_font_style_t *fstyle,
LOG("rufl_x_to_offset: rufl_FONT_MANAGER_ERROR: ""0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess);
else
LOG("rufl_x_to_offset: 0x%x", code);
-/* warn_user("MiscError", "font error"); */
+/* ro_warn_user("MiscError", "font error"); */
*char_offset = 0;
*actual_x = 0;
- return false;
+ return NSERROR_INVALID;
}
*actual_x /= 2;
- return true;
+
+ return NSERROR_OK;
}
@@ -330,8 +312,8 @@ bool nsfont_position_in_string(const plot_font_style_t *fstyle,
*
* Returning char_offset == length means no split possible
*/
-
-bool nsfont_split(const plot_font_style_t *fstyle,
+static nserror
+ro_font_split(const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x)
{
@@ -344,21 +326,23 @@ bool nsfont_split(const plot_font_style_t *fstyle,
if (font_size == 0) {
*char_offset = 0;
*actual_x = 0;
- return true;
+ return NSERROR_OK;
}
code = rufl_split(font_family, font_style, font_size,
string, length,
x * 2, char_offset, actual_x);
if (code != rufl_OK) {
- if (code == rufl_FONT_MANAGER_ERROR)
- LOG("rufl_split: rufl_FONT_MANAGER_ERROR: ""0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess);
- else
+ if (code == rufl_FONT_MANAGER_ERROR) {
+ LOG("rufl_split: rufl_FONT_MANAGER_ERROR: ""0x%x: %s",
+ rufl_fm_error->errnum, rufl_fm_error->errmess);
+ } else {
LOG("rufl_split: 0x%x", code);
-/* warn_user("MiscError", "font error"); */
+ }
+/* ro_warn_user("MiscError", "font error"); */
*char_offset = 0;
*actual_x = 0;
- return false;
+ return NSERROR_INVALID;
}
if (*char_offset != length) {
@@ -366,15 +350,17 @@ bool nsfont_split(const plot_font_style_t *fstyle,
size_t orig = *char_offset;
/* ensure a space at <= the split point we found */
- while (*char_offset && string[*char_offset] != ' ')
+ while (*char_offset && string[*char_offset] != ' ') {
(*char_offset)--;
+ }
/* nothing valid found <= split point, advance to next space */
if (*char_offset == 0) {
*char_offset = orig;
- while (*char_offset != length &&
- string[*char_offset] != ' ')
+ while ((*char_offset != length) &&
+ (string[*char_offset] != ' ')) {
(*char_offset)++;
+ }
}
}
@@ -382,18 +368,20 @@ bool nsfont_split(const plot_font_style_t *fstyle,
string, *char_offset,
actual_x);
if (code != rufl_OK) {
- if (code == rufl_FONT_MANAGER_ERROR)
- LOG("rufl_width: rufl_FONT_MANAGER_ERROR: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess);
- else
+ if (code == rufl_FONT_MANAGER_ERROR) {
+ LOG("rufl_width: rufl_FONT_MANAGER_ERROR: 0x%x: %s",
+ rufl_fm_error->errnum, rufl_fm_error->errmess);
+ } else {
LOG("rufl_width: 0x%x", code);
-/* warn_user("MiscError", "font error"); */
+ }
+/* ro_warn_user("MiscError", "font error"); */
*char_offset = 0;
*actual_x = 0;
- return false;
+ return NSERROR_INVALID;
}
*actual_x /= 2;
- return true;
+ return NSERROR_OK;
}
@@ -407,7 +395,6 @@ bool nsfont_split(const plot_font_style_t *fstyle,
* \param y y coordinate
* \return true on success, false on error and error reported
*/
-
bool nsfont_paint(const plot_font_style_t *fstyle, const char *string,
size_t length, int x, int y)
{
@@ -427,10 +414,11 @@ bool nsfont_paint(const plot_font_style_t *fstyle, const char *string,
code = rufl_paint(font_family, font_style, font_size,
string, length, x, y, flags);
if (code != rufl_OK) {
- if (code == rufl_FONT_MANAGER_ERROR)
+ if (code == rufl_FONT_MANAGER_ERROR) {
LOG("rufl_paint: rufl_FONT_MANAGER_ERROR: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess);
- else
+ } else {
LOG("rufl_paint: 0x%x", code);
+ }
}
return true;
@@ -445,7 +433,6 @@ bool nsfont_paint(const plot_font_style_t *fstyle, const char *string,
* \param font_size updated to font size
* \param font_style updated to font style
*/
-
void nsfont_read_style(const plot_font_style_t *fstyle,
const char **font_family, unsigned int *font_size,
rufl_style *font_style)
@@ -506,9 +493,11 @@ void nsfont_read_style(const plot_font_style_t *fstyle,
* \param psize receives the font size in 1/16 points
* \param pstyle receives the style settings to be passed to rufl
*/
-
-void ro_gui_wimp_desktop_font(char *family, size_t family_size, int *psize,
- rufl_style *pstyle)
+static void
+ro_gui_wimp_desktop_font(char *family,
+ size_t family_size,
+ int *psize,
+ rufl_style *pstyle)
{
rufl_style style = rufl_WEIGHT_400;
os_error *error;
@@ -524,7 +513,7 @@ void ro_gui_wimp_desktop_font(char *family, size_t family_size, int *psize,
error = xwimpreadsysinfo_font(&font_handle, NULL);
if (error) {
LOG("xwimpreadsysinfo_font: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
goto failsafe;
}
@@ -536,7 +525,7 @@ void ro_gui_wimp_desktop_font(char *family, size_t family_size, int *psize,
error = xfont_read_identifier(font_handle, NULL, &used);
if (error) {
LOG("xfont_read_identifier: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
goto failsafe;
}
@@ -549,7 +538,7 @@ void ro_gui_wimp_desktop_font(char *family, size_t family_size, int *psize,
&ptx, &pty, NULL, NULL, NULL, NULL);
if (error) {
LOG("xfont_read_defn: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
goto failsafe;
}
@@ -591,7 +580,6 @@ failsafe:
* Retrieve the current desktop font family, size and style from
* the WindowManager in a form suitable for passing to rufl
*/
-
void ro_gui_wimp_get_desktop_font(void)
{
ro_gui_wimp_desktop_font(ro_gui_desktop_font_family,
@@ -599,3 +587,12 @@ void ro_gui_wimp_get_desktop_font(void)
&ro_gui_desktop_font_size,
&ro_gui_desktop_font_style);
}
+
+
+static struct gui_layout_table layout_table = {
+ .width = ro_font_width,
+ .position = ro_font_position,
+ .split = ro_font_split,
+};
+
+struct gui_layout_table *riscos_layout_table = &layout_table;
diff --git a/riscos/font.h b/riscos/font.h
index 4a1fe4c..0319a7e 100644
--- a/riscos/font.h
+++ b/riscos/font.h
@@ -25,6 +25,8 @@
#include <rufl.h>
+struct gui_layout_table *riscos_layout_table;
+
/** desktop font, size and style being used */
extern char ro_gui_desktop_font_family[];
extern int ro_gui_desktop_font_size;
diff --git a/riscos/gui.c b/riscos/gui.c
index 01fa7b5..309f27b 100644
--- a/riscos/gui.c
+++ b/riscos/gui.c
@@ -529,7 +529,7 @@ static char *ro_gui_uri_file_parse(const char *file_name, char **uri_title)
fp = fopen(file_name, "rb");
if (!fp) {
LOG("fopen(\"%s\", \"rb\"): %i: %s", file_name, errno, strerror(errno));
- warn_user("LoadError", strerror(errno));
+ ro_warn_user("LoadError", strerror(errno));
return 0;
}
@@ -548,7 +548,7 @@ static char *ro_gui_uri_file_parse(const char *file_name, char **uri_title)
url = strdup(line);
if (!url) {
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
fclose(fp);
return 0;
}
@@ -559,7 +559,7 @@ static char *ro_gui_uri_file_parse(const char *file_name, char **uri_title)
if (uri_title && line[0] && ((line[0] != '*') || line[1])) {
*uri_title = strdup(line);
if (!*uri_title) /* non-fatal */
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
}
fclose(fp);
@@ -570,7 +570,7 @@ uri_free:
uri_syntax_error:
fclose(fp);
- warn_user("URIError", 0);
+ ro_warn_user("URIError", 0);
return 0;
}
@@ -590,16 +590,16 @@ static char *ro_gui_url_file_parse(const char *file_name)
fp = fopen(file_name, "r");
if (!fp) {
LOG("fopen(\"%s\", \"r\"): %i: %s", file_name, errno, strerror(errno));
- warn_user("LoadError", strerror(errno));
+ ro_warn_user("LoadError", strerror(errno));
return 0;
}
if (!fgets(line, sizeof line, fp)) {
if (ferror(fp)) {
LOG("fgets: %i: %s", errno, strerror(errno));
- warn_user("LoadError", strerror(errno));
+ ro_warn_user("LoadError", strerror(errno));
} else
- warn_user("LoadError", messages_get("EmptyError"));
+ ro_warn_user("LoadError", messages_get("EmptyError"));
fclose(fp);
return 0;
}
@@ -611,7 +611,7 @@ static char *ro_gui_url_file_parse(const char *file_name)
url = strdup(line);
if (!url) {
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return 0;
}
@@ -634,7 +634,7 @@ static char *ro_gui_ieurl_file_parse(const char *file_name)
fp = fopen(file_name, "r");
if (!fp) {
LOG("fopen(\"%s\", \"r\"): %i: %s", file_name, errno, strerror(errno));
- warn_user("LoadError", strerror(errno));
+ ro_warn_user("LoadError", strerror(errno));
return 0;
}
@@ -645,7 +645,7 @@ static char *ro_gui_ieurl_file_parse(const char *file_name)
url = strdup(line + 4);
if (!url) {
fclose(fp);
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return 0;
}
break;
@@ -653,7 +653,7 @@ static char *ro_gui_ieurl_file_parse(const char *file_name)
}
if (ferror(fp)) {
LOG("fgets: %i: %s", errno, strerror(errno));
- warn_user("LoadError", strerror(errno));
+ ro_warn_user("LoadError", strerror(errno));
fclose(fp);
return 0;
}
@@ -661,7 +661,7 @@ static char *ro_gui_ieurl_file_parse(const char *file_name)
fclose(fp);
if (!url)
- warn_user("URIError", 0);
+ ro_warn_user("URIError", 0);
return url;
}
@@ -725,12 +725,12 @@ static void ro_msg_dataopen(wimp_message *message)
oserror = xwimp_send_message(wimp_USER_MESSAGE, message, message->sender);
if (oserror) {
LOG("xwimp_send_message: 0x%x: %s", oserror->errnum, oserror->errmess);
- warn_user("WimpError", oserror->errmess);
+ ro_warn_user("WimpError", oserror->errmess);
return;
}
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ ro_warn_user(messages_get_errorcode(error), 0);
return;
}
@@ -742,7 +742,7 @@ static void ro_msg_dataopen(wimp_message *message)
NULL);
nsurl_unref(urlns);
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ ro_warn_user(messages_get_errorcode(error), 0);
}
}
@@ -815,7 +815,7 @@ static void ro_msg_dataload(wimp_message *message)
/* report error to user */
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ ro_warn_user(messages_get_errorcode(error), 0);
return;
}
@@ -837,7 +837,7 @@ static void ro_msg_dataload(wimp_message *message)
}
nsurl_unref(url);
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ ro_warn_user(messages_get_errorcode(error), 0);
}
@@ -848,7 +848,7 @@ static void ro_msg_dataload(wimp_message *message)
message->sender);
if (oserror) {
LOG("xwimp_send_message: 0x%x: %s", oserror->errnum, oserror->errmess);
- warn_user("WimpError", oserror->errmess);
+ ro_warn_user("WimpError", oserror->errmess);
return;
}
@@ -918,7 +918,7 @@ static void ro_msg_datasave(wimp_message *message)
error = xwimp_send_message(wimp_USER_MESSAGE, (wimp_message*)dataxfer, message->sender);
if (error) {
LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
break;
@@ -970,7 +970,7 @@ static void ro_msg_prequit(wimp_message *message)
message, message->sender);
if (error) {
LOG("xwimp_send_message: 0x%x:%s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
}
@@ -996,7 +996,7 @@ static void ro_msg_save_desktop(wimp_message *message)
if (error) {
LOG("xosgbpb_writew/xos_bputw: 0x%x:%s", error->errnum, error->errmess);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
/* we must cancel the save by acknowledging the message */
message->your_ref = message->my_ref;
@@ -1004,7 +1004,7 @@ static void ro_msg_save_desktop(wimp_message *message)
message, message->sender);
if (error) {
LOG("xwimp_send_message: 0x%x:%s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
}
@@ -1055,7 +1055,7 @@ static void ro_gui_get_screen_properties(void)
error = xos_read_vdu_variables(PTR_OS_VDU_VAR_LIST(&vars), vals);
if (error) {
LOG("xos_read_vdu_variables: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
return;
}
screen_info.width = (vals[0] + 1) << vals[2];
@@ -1074,7 +1074,7 @@ static void ro_gui_check_resolvers(void)
LOG("Inet$Resolvers '%s'", resolvers);
} else {
LOG("Inet$Resolvers not set or empty");
- warn_user("Resolvers", 0);
+ ro_warn_user("Resolvers", 0);
}
}
@@ -1414,7 +1414,7 @@ static nserror ro_path_to_nsurl(const char *path, struct nsurl **url_out)
error = xosfscontrol_canonicalise_path(path, 0, 0, 0, 0, &spare);
if (error) {
LOG("xosfscontrol_canonicalise_path failed: 0x%x: %s", error->errnum, error->errmess);
- warn_user("PathToURL", error->errmess);
+ ro_warn_user("PathToURL", error->errmess);
return NSERROR_NOT_FOUND;
}
@@ -1427,7 +1427,7 @@ static nserror ro_path_to_nsurl(const char *path, struct nsurl **url_out)
error = xosfscontrol_canonicalise_path(path, canonical_path, 0, 0, 1 - spare, 0);
if (error) {
LOG("xosfscontrol_canonicalise_path failed: 0x%x: %s", error->errnum, error->errmess);
- warn_user("PathToURL", error->errmess);
+ ro_warn_user("PathToURL", error->errmess);
free(canonical_path);
return NSERROR_NOT_FOUND;
}
@@ -1597,7 +1597,7 @@ static void ro_gui_keypress_cb(void *pw)
os_error *error = xwimp_process_key(key->c);
if (error) {
LOG("xwimp_process_key: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
@@ -1634,7 +1634,7 @@ static void ro_gui_keypress(wimp_key *key)
os_error *error = xwimp_process_key(key->c);
if (error) {
LOG("xwimp_process_key: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
}
@@ -1906,7 +1906,7 @@ void ro_gui_open_window_request(wimp_open *open)
error = xwimp_open_window(open);
if (error) {
LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
}
@@ -1927,7 +1927,7 @@ static void ro_gui_view_source_bounce(wimp_message *message)
error = xwimp_start_task(command, 0);
if (error) {
LOG("xwimp_start_task failed: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
@@ -1947,14 +1947,14 @@ void ro_gui_view_source(hlcache_handle *c)
unsigned long source_size;
if (!c) {
- warn_user("MiscError", "No document source");
+ ro_warn_user("MiscError", "No document source");
return;
}
source_data = content_get_source_data(c, &source_size);
if (!source_data) {
- warn_user("MiscError", "No document source");
+ ro_warn_user("MiscError", "No document source");
return;
}
@@ -1979,7 +1979,7 @@ void ro_gui_view_source(hlcache_handle *c)
char full_name[256];
const char *filename = filename_request();
if (!filename) {
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return;
}
@@ -2000,7 +2000,7 @@ void ro_gui_view_source(hlcache_handle *c)
(byte *) source_data + source_size);
if (error) {
LOG("xosfile_save_stamped failed: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
return;
}
}
@@ -2067,7 +2067,7 @@ static void ro_gui_choose_language(void)
* \param warning message key for warning message
* \param detail additional message, or 0
*/
-void warn_user(const char *warning, const char *detail)
+nserror ro_warn_user(const char *warning, const char *detail)
{
LOG("%s %s", warning, detail);
@@ -2083,8 +2083,7 @@ void warn_user(const char *warning, const char *detail)
wimp_ICON_DELETED, wimp_ICON_DELETED);
ro_gui_dialog_open(dialog_warning);
xos_bell();
- }
- else {
+ } else {
/* probably haven't initialised (properly), use a
non-multitasking error box */
os_error error;
@@ -2100,6 +2099,8 @@ void warn_user(const char *warning, const char *detail)
"NetSurf", "!netsurf",
(osspriteop_area *) 1, 0, 0);
}
+
+ return NSERROR_OK;
}
@@ -2350,7 +2351,7 @@ void ro_gui_dump_browser_window(struct browser_window *bw)
FILE *stream = fopen("<Wimp$ScrapDir>.WWW.NetSurf.dump", "w");
if (!stream) {
LOG("fopen: errno %i", errno);
- warn_user("SaveError", strerror(errno));
+ ro_warn_user("SaveError", strerror(errno));
return;
}
@@ -2363,7 +2364,7 @@ void ro_gui_dump_browser_window(struct browser_window *bw)
0);
if (error) {
LOG("xwimp_start_task failed: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
@@ -2383,8 +2384,9 @@ static struct gui_fetch_table riscos_fetch_table = {
.mimetype = fetch_mimetype,
};
-static struct gui_browser_table riscos_browser_table = {
+static struct gui_misc_table riscos_misc_table = {
.schedule = riscos_schedule,
+ .warning = ro_warn_user,
.quit = gui_quit,
.launch_url = gui_launch_url,
@@ -2424,7 +2426,7 @@ int main(int argc, char** argv)
os_error *error;
nserror ret;
struct netsurf_table riscos_table = {
- .browser = &riscos_browser_table,
+ .misc = &riscos_misc_table,
.window = riscos_window_table,
.clipboard = riscos_clipboard_table,
.download = riscos_download_table,
@@ -2434,6 +2436,7 @@ int main(int argc, char** argv)
.search = riscos_search_table,
.llcache = filesystem_llcache_table,
.bitmap = riscos_bitmap_table,
+ .layout = riscos_layout_table,
};
ret = netsurf_register(&riscos_table);
@@ -2506,7 +2509,7 @@ int main(int argc, char** argv)
ret = gui_init(argc, argv);
if (ret != NSERROR_OK) {
- warn_user(messages_get_errorcode(ret), 0);
+ ro_warn_user(messages_get_errorcode(ret), 0);
}
while (!riscos_done) {
diff --git a/riscos/gui.h b/riscos/gui.h
index 4e9ce65..624f9e2 100644
--- a/riscos/gui.h
+++ b/riscos/gui.h
@@ -118,6 +118,7 @@ void ro_gui_dump_browser_window(struct browser_window *bw);
void ro_gui_drag_box_start(wimp_pointer *pointer);
bool ro_gui_prequit(void);
const char *ro_gui_default_language(void);
+nserror ro_warn_user(const char *warning, const char *detail);
/**
* Cause an abnormal program termination.
diff --git a/riscos/gui/button_bar.c b/riscos/gui/button_bar.c
index e04bfc2..6f8920c 100644
--- a/riscos/gui/button_bar.c
+++ b/riscos/gui/button_bar.c
@@ -540,7 +540,7 @@ bool ro_gui_button_bar_icon_update(struct button_bar *button_bar)
error = xwimp_create_icon(&icon, &button->icon);
if (error) {
LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
button->icon = -1;
return false;
}
@@ -550,7 +550,7 @@ bool ro_gui_button_bar_icon_update(struct button_bar *button_bar)
button->icon);
if (error != NULL) {
LOG("xwimp_delete_icon: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -600,7 +600,7 @@ bool ro_gui_button_bar_icon_resize(struct button_bar *button_bar)
button->y_size);
if (error != NULL) {
LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
button->icon = -1;
return false;
}
@@ -872,7 +872,7 @@ void ro_gui_button_bar_drag_end(wimp_dragged *drag, void *data)
error = xwimp_get_pointer_info(&pointer);
if (error) {
LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -882,7 +882,7 @@ void ro_gui_button_bar_drag_end(wimp_dragged *drag, void *data)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1070,7 +1070,7 @@ char *ro_gui_button_bar_get_config(struct button_bar *button_bar)
config = malloc(size);
if (config == NULL) {
LOG("No memory for malloc()");
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return NULL;
}
diff --git a/riscos/gui/throbber.c b/riscos/gui/throbber.c
index 2eabb3e..437c4fa 100644
--- a/riscos/gui/throbber.c
+++ b/riscos/gui/throbber.c
@@ -35,6 +35,7 @@
#include "riscos/wimp.h"
#include "utils/log.h"
#include "utils/utils.h"
+#include "riscos/gui.h"
#define THROBBER_SPRITE_NAME_LENGTH 12
#define THROBBER_ANIMATE_INTERVAL 10
@@ -247,7 +248,7 @@ bool ro_gui_throbber_icon_update(struct throbber *throbber)
error = xwimp_create_icon(&icon, &throbber->icon);
if (error != NULL) {
LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
throbber->icon = -1;
return false;
}
@@ -258,7 +259,7 @@ bool ro_gui_throbber_icon_update(struct throbber *throbber)
error = xwimp_delete_icon(throbber->window, throbber->icon);
if (error != NULL) {
LOG("xwimp_delete_icon: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -294,7 +295,7 @@ bool ro_gui_throbber_icon_resize(struct throbber *throbber)
throbber->extent.x1, throbber->extent.y1);
if (error != NULL) {
LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
throbber->icon = -1;
return false;
}
diff --git a/riscos/gui/url_bar.c b/riscos/gui/url_bar.c
index adaa8c0..0530147 100644
--- a/riscos/gui/url_bar.c
+++ b/riscos/gui/url_bar.c
@@ -235,7 +235,7 @@ static bool ro_gui_url_bar_icon_resize(struct url_bar *url_bar, bool full)
x0, y0, x1, y1);
if (error != NULL) {
LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
url_bar->container_icon = -1;
return false;
}
@@ -255,7 +255,7 @@ static bool ro_gui_url_bar_icon_resize(struct url_bar *url_bar, bool full)
x0, y0, x1, y1);
if (error != NULL) {
LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
url_bar->suggest_icon = -1;
return false;
}
@@ -276,7 +276,7 @@ static bool ro_gui_url_bar_icon_resize(struct url_bar *url_bar, bool full)
x0, y0, x1, y1);
if (error != NULL) {
LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
url_bar->text_icon = -1;
return false;
}
@@ -357,7 +357,7 @@ static bool ro_gui_url_bar_icon_update(struct url_bar *url_bar)
error = xwimp_create_icon(&icon, &url_bar->container_icon);
if (error != NULL) {
LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
url_bar->container_icon = -1;
return false;
}
@@ -368,7 +368,7 @@ static bool ro_gui_url_bar_icon_update(struct url_bar *url_bar)
url_bar->container_icon);
if (error != NULL) {
LOG("xwimp_delete_icon: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -394,7 +394,7 @@ static bool ro_gui_url_bar_icon_update(struct url_bar *url_bar)
error = xwimp_create_icon(&icon, &url_bar->text_icon);
if (error) {
LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
url_bar->text_icon = -1;
return false;
}
@@ -405,7 +405,7 @@ static bool ro_gui_url_bar_icon_update(struct url_bar *url_bar)
url_bar->text_icon);
if (error != NULL) {
LOG("xwimp_delete_icon: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -425,7 +425,7 @@ static bool ro_gui_url_bar_icon_update(struct url_bar *url_bar)
error = xwimp_create_icon(&icon, &url_bar->suggest_icon);
if (error) {
LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -445,7 +445,7 @@ static bool ro_gui_url_bar_icon_update(struct url_bar *url_bar)
url_bar->suggest_icon);
if (error != NULL) {
LOG("xwimp_delete_icon: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -856,7 +856,7 @@ bool ro_gui_url_bar_menu_select(struct url_bar *url_bar, wimp_i i,
error = nsurl_create(urltxt, &url);
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ ro_warn_user(messages_get_errorcode(error), 0);
} else {
ro_gui_window_set_url(g, url);
@@ -935,7 +935,7 @@ bool ro_gui_url_bar_take_caret(struct url_bar *url_bar)
-1, -1, -1, 0);
if (error) {
LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -986,7 +986,7 @@ void ro_gui_url_bar_set_url(struct url_bar *url_bar, const char *url,
if (strlen(local_url) >= url_bar->text_size) {
url_bar->text_buffer[0] = '\0';
- warn_user("LongURL", NULL);
+ ro_warn_user("LongURL", NULL);
LOG("Long URL (%zu chars): %s", strlen(url), url);
} else {
strncpy(url_bar->text_buffer, local_url,
@@ -1016,7 +1016,7 @@ void ro_gui_url_bar_set_url(struct url_bar *url_bar, const char *url,
error = xwimp_get_caret_position(&caret);
if (error) {
LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1029,7 +1029,7 @@ void ro_gui_url_bar_set_url(struct url_bar *url_bar, const char *url,
url_bar->text_icon, 0, 0, -1, strlen(set_url));
if (error) {
LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
}
@@ -1118,7 +1118,7 @@ bool ro_gui_url_bar_get_url_extent(struct url_bar *url_bar, os_box *extent)
error = xwimp_get_icon_state(&state);
if (error) {
LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
diff --git a/riscos/help.c b/riscos/help.c
index c54af1d..3c9f548 100644
--- a/riscos/help.c
+++ b/riscos/help.c
@@ -168,7 +168,7 @@ void ro_gui_interactive_help_request(wimp_message *message)
&menu_tree, window, icon);
if (error) {
LOG("xwimp_get_menu_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
if (menu_tree.items[0] == -1)
@@ -271,7 +271,7 @@ static void ro_gui_interactive_help_broadcast(wimp_message *message,
reply->sender);
if (error) {
LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
@@ -299,7 +299,7 @@ bool ro_gui_interactive_help_available(void)
sizeof(taskmanager_task), &context, 0);
if (error) {
LOG("xtaskmanager_enumerate_tasks: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
}
/* we can't just use strcmp due to string termination issues */
@@ -336,7 +336,7 @@ void ro_gui_interactive_help_start(void)
error = xwimp_start_task("<Help$Start>", &task);
if (error) {
LOG("xwimp_start_tast: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
}
@@ -346,7 +346,7 @@ void ro_gui_interactive_help_start(void)
error = xwimp_start_task("Resources:$.Apps.!Help", &task);
if (error) {
LOG("xwimp_start_tast: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
}
@@ -356,7 +356,7 @@ void ro_gui_interactive_help_start(void)
error = xos_read_monotonic_time(&help_time);
if (error) {
LOG("xwimp_read_monotonic_time: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
}
diff --git a/riscos/history.c b/riscos/history.c
index 3dc9f0d..4b3bed2 100644
--- a/riscos/history.c
+++ b/riscos/history.c
@@ -101,7 +101,7 @@ void ro_gui_history_open(struct gui_window *g, bool at_pointer)
error = xwimp_set_extent(history_window, &box);
if (error) {
LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -110,7 +110,7 @@ void ro_gui_history_open(struct gui_window *g, bool at_pointer)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
state.visible.x0 = 0;
@@ -121,7 +121,7 @@ void ro_gui_history_open(struct gui_window *g, bool at_pointer)
error = xwimp_open_window(PTR_WIMP_OPEN(&state));
if (error) {
LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -146,7 +146,7 @@ void ro_gui_history_redraw(wimp_draw *redraw)
error = xwimp_redraw_window(redraw, &more);
if (error) {
LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
while (more) {
@@ -156,7 +156,7 @@ void ro_gui_history_redraw(wimp_draw *redraw)
error = xwimp_get_rectangle(redraw, &more);
if (error) {
LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
}
@@ -220,7 +220,7 @@ void ro_gui_history_mouse_at(wimp_pointer *pointer, void *data)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -232,7 +232,7 @@ void ro_gui_history_mouse_at(wimp_pointer *pointer, void *data)
error = xwimp_close_window(dialog_tooltip);
if (error) {
LOG("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
return;
@@ -244,7 +244,7 @@ void ro_gui_history_mouse_at(wimp_pointer *pointer, void *data)
&width);
if (error) {
LOG("xwimptextop_string_width: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -256,7 +256,7 @@ void ro_gui_history_mouse_at(wimp_pointer *pointer, void *data)
error = xwimp_get_icon_state(&ic);
if (error) {
LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
error = xwimp_resize_icon(dialog_tooltip, 0,
@@ -264,7 +264,7 @@ void ro_gui_history_mouse_at(wimp_pointer *pointer, void *data)
width + 16, ic.icon.extent.y1);
if (error) {
LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -272,7 +272,7 @@ void ro_gui_history_mouse_at(wimp_pointer *pointer, void *data)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -282,7 +282,7 @@ void ro_gui_history_mouse_at(wimp_pointer *pointer, void *data)
error = xwimp_set_extent(dialog_tooltip, &box);
if (error) {
LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -296,7 +296,7 @@ void ro_gui_history_mouse_at(wimp_pointer *pointer, void *data)
error = xwimp_open_window(PTR_WIMP_OPEN(&state));
if (error) {
LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
}
@@ -323,7 +323,7 @@ bool ro_gui_history_click(wimp_pointer *pointer)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return true;
}
diff --git a/riscos/hotlist.c b/riscos/hotlist.c
index 0ddc3c8..c728404 100644
--- a/riscos/hotlist.c
+++ b/riscos/hotlist.c
@@ -234,7 +234,7 @@ void ro_gui_hotlist_open(void)
return;
LOG("xos_cli: 0x%x: %s", error->errnum, error->errmess);
- warn_user("Failed to launch external hotlist: %s",
+ ro_warn_user("Failed to launch external hotlist: %s",
error->errmess);
}
diff --git a/riscos/iconbar.c b/riscos/iconbar.c
index 7b7bb25..6024ea9 100644
--- a/riscos/iconbar.c
+++ b/riscos/iconbar.c
@@ -144,7 +144,7 @@ bool ro_gui_iconbar_click(wimp_pointer *pointer)
nsurl_unref(url);
}
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ ro_warn_user(messages_get_errorcode(error), 0);
}
break;
@@ -215,7 +215,7 @@ bool ro_gui_iconbar_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
nsurl_unref(url);
}
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ ro_warn_user(messages_get_errorcode(error), 0);
}
return true;
diff --git a/riscos/image.c b/riscos/image.c
index 63e65f2..71d6334 100644
--- a/riscos/image.c
+++ b/riscos/image.c
@@ -18,6 +18,7 @@
#include <stdbool.h>
#include <swis.h>
+#include <stdlib.h>
#include <oslib/colourtrans.h>
#include <oslib/osspriteop.h>
@@ -183,7 +184,7 @@ bool image_redraw_os(osspriteop_id header, int x, int y, int req_width,
table = calloc(size, sizeof(char));
if (!table) {
LOG("malloc failed");
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return false;
}
diff --git a/riscos/menus.c b/riscos/menus.c
index b803f8c..dcb0bf9 100644
--- a/riscos/menus.c
+++ b/riscos/menus.c
@@ -224,7 +224,7 @@ void ro_gui_menu_create(wimp_menu *menu, int x, int y, wimp_w w)
definition = ro_gui_menu_find_menu(menu);
if (definition) {
if (!ro_gui_menu_translate(definition)) {
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return;
}
}
@@ -239,7 +239,7 @@ void ro_gui_menu_create(wimp_menu *menu, int x, int y, wimp_w w)
error = xwimp_create_menu(menu, x - 64, y);
if (error) {
LOG("xwimp_create_menu: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MenuError", error->errmess);
+ ro_warn_user("MenuError", error->errmess);
ro_gui_menu_closed();
}
}
@@ -265,14 +265,14 @@ void ro_gui_popup_menu(wimp_menu *menu, wimp_w w, wimp_i i)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MenuError", error->errmess);
+ ro_warn_user("MenuError", error->errmess);
return;
}
error = xwimp_get_icon_state(&icon_state);
if (error) {
LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MenuError", error->errmess);
+ ro_warn_user("MenuError", error->errmess);
return;
}
@@ -298,7 +298,7 @@ void ro_gui_menu_destroy(void)
error = xwimp_create_menu(wimp_CLOSE_MENU, 0, 0);
if (error) {
LOG("xwimp_create_menu: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MenuError", error->errmess);
+ ro_warn_user("MenuError", error->errmess);
}
ro_gui_menu_closed();
@@ -361,7 +361,7 @@ void ro_gui_menu_selection(wimp_selection *selection)
error = xwimp_get_pointer_info(&pointer);
if (error) {
LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
ro_gui_menu_closed();
return;
}
@@ -427,7 +427,7 @@ void ro_gui_menu_warning(wimp_message_menu_warning *warning)
warning->pos.x, warning->pos.y);
if (error) {
LOG("xwimp_create_sub_menu: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MenuError", error->errmess);
+ ro_warn_user("MenuError", error->errmess);
}
}
@@ -492,7 +492,7 @@ void ro_gui_menu_refresh(wimp_menu *menu)
error = xwimp_create_menu(current_menu, 0, 0);
if (error) {
LOG("xwimp_create_menu: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MenuError", error->errmess);
+ ro_warn_user("MenuError", error->errmess);
}
}
}
@@ -858,7 +858,7 @@ int ro_gui_menu_get_checksum(void)
&menu_tree, 0, 0);
if (error) {
LOG("xwimp_get_menu_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MenuError", error->errmess);
+ ro_warn_user("MenuError", error->errmess);
return 0;
}
diff --git a/riscos/message.c b/riscos/message.c
index c97434b..70efcc1 100644
--- a/riscos/message.c
+++ b/riscos/message.c
@@ -25,10 +25,11 @@
#include <stdlib.h>
#include "oslib/os.h"
#include "oslib/wimp.h"
+
#include "riscos/message.h"
#include "utils/log.h"
#include "utils/utils.h"
-
+#include "riscos/gui.h"
struct active_message {
unsigned int message_code;
@@ -64,7 +65,7 @@ bool ro_message_send_message(wimp_event_no event, wimp_message *message,
error = xwimp_send_message(event, message, task);
if (error) {
LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -101,7 +102,7 @@ bool ro_message_send_message_to_window(wimp_event_no event, wimp_message *messag
error = xwimp_send_message_to_window(event, message, to_w, to_i, to_t);
if (error) {
LOG("xwimp_send_message_to_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
diff --git a/riscos/mouse.c b/riscos/mouse.c
index e53a593..25db2ff 100644
--- a/riscos/mouse.c
+++ b/riscos/mouse.c
@@ -35,12 +35,15 @@
* - when the pointer leaves the window.
*/
-#include "oslib/wimp.h"
+#include <assert.h>
+#include <oslib/wimp.h>
-#include "riscos/mouse.h"
#include "utils/log.h"
#include "utils/utils.h"
+#include "riscos/mouse.h"
+#include "riscos/gui.h"
+
/* Data for the wimp drag handler. */
static void (*ro_mouse_drag_end_callback)(wimp_dragged *dragged, void *data)
@@ -80,7 +83,7 @@ void ro_mouse_poll(void)
error = xwimp_get_pointer_info(&pointer);
if (error) {
LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -145,7 +148,7 @@ void ro_mouse_drag_end(wimp_dragged *dragged)
if (ro_mouse_drag_end_callback != NULL)
ro_mouse_drag_end_callback(dragged, ro_mouse_drag_data);
else
- warn_user("WimpError", "No callback");
+ ro_warn_user("WimpError", "No callback");
/* Wimp_DragEnd is a one-shot event, so clear the data ready for
* another claimant.
diff --git a/riscos/print.c b/riscos/print.c
index 0fb9a9a..95730d6 100644
--- a/riscos/print.c
+++ b/riscos/print.c
@@ -29,6 +29,7 @@
#include <oslib/pdriver.h>
#include <oslib/wimp.h>
#include <rufl.h>
+#include <limits.h>
#include "utils/config.h"
#include "utils/log.h"
@@ -334,7 +335,7 @@ void print_send_printsave(hlcache_handle *h)
(wimp_message *)&m, 0);
if (e) {
LOG("xwimp_send_message: 0x%x: %s", e->errnum, e->errmess);
- warn_user("WimpError", e->errmess);
+ ro_warn_user("WimpError", e->errmess);
ro_print_cleanup();
}
print_prev_message = m.my_ref;
@@ -358,7 +359,7 @@ bool print_send_printtypeknown(wimp_message *m)
e = xwimp_send_message(wimp_USER_MESSAGE, m, m->sender);
if (e) {
LOG("xwimp_send_message: 0x%x: %s", e->errnum, e->errmess);
- warn_user("WimpError", e->errmess);
+ ro_warn_user("WimpError", e->errmess);
return false;
}
@@ -398,9 +399,9 @@ void ro_print_error(wimp_message *m)
return;
if (m->size == 20)
- warn_user("PrintErrorRO2", 0);
+ ro_warn_user("PrintErrorRO2", 0);
else
- warn_user("PrintError", p->errmess);
+ ro_warn_user("PrintError", p->errmess);
ro_print_cleanup();
}
@@ -464,7 +465,7 @@ bool ro_print_ack(wimp_message *m)
error = xpdriver_info(&info_type, 0, 0, 0, 0, 0, 0, 0);
if (error) {
LOG("xpdriver_info: 0x%x: %s", error->errnum, error->errmess);
- warn_user("PrintError", error->errmess);
+ ro_warn_user("PrintError", error->errmess);
ro_print_cleanup();
return true;
}
@@ -489,7 +490,7 @@ bool ro_print_ack(wimp_message *m)
error = xwimp_send_message(wimp_USER_MESSAGE_RECORDED, m, m->sender);
if (error) {
LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
/* and delete temporary file */
xosfile_delete(m->data.data_xfer.file_name,
0, 0, 0, 0, 0);
@@ -553,7 +554,7 @@ bool print_document(struct gui_window *g, const char *filename)
/* no point printing a blank page */
if (!h) {
- warn_user("PrintError", "nothing to print");
+ ro_warn_user("PrintError", "nothing to print");
return false;
}
@@ -561,7 +562,7 @@ bool print_document(struct gui_window *g, const char *filename)
error = xpdriver_info(0, 0, 0, &features, 0, 0, 0, 0);
if (error) {
LOG("xpdriver_info: 0x%x: %s", error->errnum, error->errmess);
- warn_user("PrintError", error->errmess);
+ ro_warn_user("PrintError", error->errmess);
return false;
}
@@ -569,7 +570,7 @@ bool print_document(struct gui_window *g, const char *filename)
error = xpdriver_page_size(0, 0, &left, &bottom, &right, &top);
if (error) {
LOG("xpdriver_page_size: 0x%x: %s", error->errnum, error->errmess);
- warn_user("PrintError", error->errmess);
+ ro_warn_user("PrintError", error->errmess);
return false;
}
@@ -592,7 +593,7 @@ bool print_document(struct gui_window *g, const char *filename)
osfind_ERROR_IF_ABSENT, filename, 0, &fhandle);
if (error) {
LOG("xosfind_openoutw: 0x%x: %s", error->errnum, error->errmess);
- warn_user("PrintError", error->errmess);
+ ro_warn_user("PrintError", error->errmess);
return false;
}
@@ -600,7 +601,7 @@ bool print_document(struct gui_window *g, const char *filename)
error = xpdriver_select_jobw(fhandle, "NetSurf", &old_job);
if (error) {
LOG("xpdriver_select_jobw: 0x%x: %s", error->errnum, error->errmess);
- warn_user("PrintError", error->errmess);
+ ro_warn_user("PrintError", error->errmess);
xosfind_closew(fhandle);
return false;
}
@@ -736,7 +737,7 @@ bool print_document(struct gui_window *g, const char *filename)
error = xosfind_closew(fhandle);
if (error) {
LOG("xosfind_closew: 0x%x: %s", error->errnum, error->errmess);
- warn_user("PrintError", error->errmess);
+ ro_warn_user("PrintError", error->errmess);
return false;
}
@@ -744,7 +745,7 @@ bool print_document(struct gui_window *g, const char *filename)
error = xpdriver_select_jobw(old_job, 0, 0);
if (error) {
LOG("xpdriver_select_jobw: 0x%x: %s", error->errnum, error->errmess);
- warn_user("PrintError", error->errmess);
+ ro_warn_user("PrintError", error->errmess);
/* the printing succeeded anyway */
return true;
}
@@ -768,7 +769,7 @@ error:
print_active = false;
ro_gui_current_redraw_gui = 0;
- warn_user("PrintError", error_message);
+ ro_warn_user("PrintError", error_message);
rufl_invalidate_cache();
diff --git a/riscos/query.c b/riscos/query.c
index 178dcaf..1d7cf51 100644
--- a/riscos/query.c
+++ b/riscos/query.c
@@ -156,7 +156,7 @@ query_id query_user_xy(const char *query, const char *detail,
qw = malloc(sizeof(struct gui_query_window));
if (!qw) {
- warn_user("NoMemory", NULL);
+ ro_warn_user("NoMemory", NULL);
return QUERY_INVALID;
}
@@ -232,7 +232,7 @@ query_id query_user_xy(const char *query, const char *detail,
error = xwimp_create_window(query_template, &qw->window);
if (error) {
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
free(qw);
return QUERY_INVALID;
}
@@ -264,7 +264,7 @@ query_id query_user_xy(const char *query, const char *detail,
error = xwimp_set_caret_position(qw->window, (wimp_i)-1, 0, 0, 1 << 25, -1);
if (error) {
LOG("xwimp_get_caret_position: 0x%x : %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
/* put this query window at the head of our list */
@@ -308,7 +308,7 @@ void ro_gui_query_window_bring_to_front(query_id id)
error = xwimp_set_caret_position(qw->window, (wimp_i)-1, 0, 0, 1 << 25, -1);
if (error) {
LOG("xwimp_get_caret_position: 0x%x : %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
}
@@ -328,7 +328,7 @@ void ro_gui_query_close(wimp_w w)
error = xwimp_delete_window(qw->window);
if (error) {
LOG("xwimp_delete_window: 0x%x:%s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
ro_gui_wimp_event_finalise(w);
diff --git a/riscos/save.c b/riscos/save.c
index 1816cec..d547e0e 100644
--- a/riscos/save.c
+++ b/riscos/save.c
@@ -191,7 +191,7 @@ wimp_w ro_gui_saveas_create(const char *template_name)
error = xosspriteop_clear_sprites(osspriteop_USER_AREA, saveas_area);
if (error) {
LOG("xosspriteop_clear_sprites: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
xosmodule_free(saveas_area);
saveas_area = NULL;
@@ -228,7 +228,7 @@ void ro_gui_saveas_quit(void)
os_error *error = xosmodule_free(saveas_area);
if (error) {
LOG("xosmodule_free: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
}
saveas_area = NULL;
}
@@ -337,7 +337,7 @@ bool ro_gui_save_ok(wimp_w w)
char path[256];
if (!strrchr(name, '.')) {
- warn_user("NoPathError", NULL);
+ ro_warn_user("NoPathError", NULL);
return false;
}
@@ -383,7 +383,7 @@ void gui_drag_save_object(struct gui_window *g, hlcache_handle *c,
error = xwimp_get_pointer_info(&pointer);
if (error) {
LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -421,7 +421,7 @@ void gui_drag_save_selection(struct gui_window *g, const char *selection)
error = xwimp_get_pointer_info(&pointer);
if (error) {
LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -474,7 +474,7 @@ void ro_gui_drag_save_link(gui_save_type save_type, const nsurl *url,
error = xwimp_get_pointer_info(&pointer);
if (error) {
LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -512,7 +512,7 @@ void ro_gui_drag_icon(int x, int y, const char *sprite)
if (error) {
if (error->errnum != error_SPRITE_OP_DOESNT_EXIST) {
LOG("xosspriteop_select_sprite: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
}
}
else
@@ -545,7 +545,7 @@ void ro_gui_drag_icon(int x, int y, const char *sprite)
if (error) {
LOG("xwimp_drag_box: 0x%x: %s", error->errnum, error->errmess);
- warn_user("DragError", error->errmess);
+ ro_warn_user("DragError", error->errmess);
}
else
dragbox_active = true;
@@ -584,14 +584,14 @@ void ro_gui_drag_box_cancel(void)
error = xdragasprite_stop();
if (error) {
LOG("xdragasprite_stop: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
else {
error = xwimp_drag_box(NULL);
if (error) {
LOG("xwimp_drag_box: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
dragbox_active = false;
@@ -621,7 +621,7 @@ static void ro_gui_save_drag_end(wimp_dragged *drag, void *data)
error = xwimp_get_pointer_info(&pointer);
if (error) {
LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -808,7 +808,7 @@ bool ro_gui_save_content(hlcache_handle *h, char *path, bool force_overwrite)
NULL, NULL, NULL, NULL, NULL);
if (error) {
LOG("xosfile_read_stamped: 0x%x:%s", error->errnum, error->errmess);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
return false;
}
@@ -825,7 +825,7 @@ bool ro_gui_save_content(hlcache_handle *h, char *path, bool force_overwrite)
default:
error = xosfile_make_error(path, obj_type);
assert(error);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
return false;
}
}
@@ -865,7 +865,7 @@ bool ro_gui_save_content(hlcache_handle *h, char *path, bool force_overwrite)
(byte *) source_data + source_size);
if (error) {
LOG("xosfile_save_stamped: 0x%x: %s", error->errnum, error->errmess);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
return false;
}
break;
@@ -941,7 +941,7 @@ void ro_gui_save_done(void)
message->sender);
if (error) {
LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
}
}
@@ -981,7 +981,7 @@ void ro_gui_save_done(void)
error = xwimp_create_menu(wimp_CLOSE_MENU, 0, 0);
if (error) {
LOG("xwimp_create_menu: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MenuError", error->errmess);
+ ro_warn_user("MenuError", error->errmess);
}
}
}
@@ -1025,7 +1025,7 @@ bool ro_gui_save_complete(hlcache_handle *h, char *path)
error = xosfile_create_dir(path, 0);
if (error) {
LOG("xosfile_create_dir: 0x%x: %s", error->errnum, error->errmess);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
return false;
}
@@ -1034,7 +1034,7 @@ bool ro_gui_save_complete(hlcache_handle *h, char *path)
fp = fopen(buf, "w");
if (!fp) {
LOG("fopen(): errno = %i", errno);
- warn_user("SaveError", strerror(errno));
+ ro_warn_user("SaveError", strerror(errno));
return false;
}
fprintf(fp, "IconSprites <Obey$Dir>.!Sprites\n");
@@ -1043,7 +1043,7 @@ bool ro_gui_save_complete(hlcache_handle *h, char *path)
error = xosfile_set_type(buf, 0xfeb);
if (error) {
LOG("xosfile_set_type: 0x%x: %s", error->errnum, error->errmess);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
return false;
}
@@ -1078,7 +1078,7 @@ bool ro_gui_save_complete(hlcache_handle *h, char *path)
error = xosspriteop_save_sprite_file(osspriteop_NAME, saveas_area, buf);
if (error) {
LOG("xosspriteop_save_sprite_file: 0x%x: %s", error->errnum, error->errmess);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
return false;
}
@@ -1110,7 +1110,7 @@ bool ro_gui_save_object_native(hlcache_handle *h, char *path)
(byte *) source_data + source_size);
if (error != NULL) {
LOG("xosfile_save_stamped: 0x%x: %s", error->errnum, error->errmess);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
return false;
}
} else {
@@ -1151,7 +1151,7 @@ bool ro_gui_save_link(const char *url, const char *title, link_format format,
FILE *fp = fopen(path, "w");
if (!fp) {
- warn_user("SaveError", strerror(errno));
+ ro_warn_user("SaveError", strerror(errno));
return false;
}
@@ -1309,7 +1309,7 @@ void ro_gui_save_set_state(hlcache_handle *h, gui_save_type save_type,
if (error) {
LOG("ro_gui_wimp_get_sprite: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
} else {
/* the sprite area should always be large enough for
* file_xxx sprites */
diff --git a/riscos/save_draw.c b/riscos/save_draw.c
index 8b8d72c..50febf3 100644
--- a/riscos/save_draw.c
+++ b/riscos/save_draw.c
@@ -103,7 +103,7 @@ bool save_as_draw(hlcache_handle *h, const char *path)
ro_save_draw_diagram = pencil_create();
if (!ro_save_draw_diagram) {
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return false;
}
@@ -132,7 +132,7 @@ bool save_as_draw(hlcache_handle *h, const char *path)
code = pencil_save_drawfile(ro_save_draw_diagram, "NetSurf",
&drawfile_buffer, &drawfile_size);
if (code != pencil_OK) {
- warn_user("SaveError", 0);
+ ro_warn_user("SaveError", 0);
pencil_free(ro_save_draw_diagram);
return false;
}
@@ -143,7 +143,7 @@ bool save_as_draw(hlcache_handle *h, const char *path)
(byte *) drawfile_buffer + drawfile_size);
if (error) {
LOG("xosfile_save_stamped failed: 0x%x: %s", error->errnum, error->errmess);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
pencil_free(ro_save_draw_diagram);
return false;
}
@@ -401,7 +401,7 @@ bool ro_save_draw_bitmap(int x, int y, int width, int height,
buffer = riscos_bitmap_get_buffer(bitmap);
if (!buffer) {
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return false;
}
@@ -456,15 +456,15 @@ bool ro_save_draw_error(pencil_code code)
assert(0);
break;
case pencil_OUT_OF_MEMORY:
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
break;
case pencil_FONT_MANAGER_ERROR:
- warn_user("SaveError", rufl_fm_error->errmess);
+ ro_warn_user("SaveError", rufl_fm_error->errmess);
break;
case pencil_FONT_NOT_FOUND:
case pencil_IO_ERROR:
case pencil_IO_EOF:
- warn_user("SaveError", "generating the DrawFile failed");
+ ro_warn_user("SaveError", "generating the DrawFile failed");
break;
}
diff --git a/riscos/search.c b/riscos/search.c
index 9c438bf..1a178f2 100644
--- a/riscos/search.c
+++ b/riscos/search.c
@@ -226,7 +226,7 @@ void ro_gui_search_add_recent(const char *search, void *p)
tmp = strdup(search);
if (!tmp) {
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return;
}
free(search_data.recent_searches[RECENT_SEARCHES - 1]);
diff --git a/riscos/sslcert.c b/riscos/sslcert.c
index 5812dff..31e81eb 100644
--- a/riscos/sslcert.c
+++ b/riscos/sslcert.c
@@ -336,12 +336,12 @@ void ro_gui_cert_release_window(struct ro_sslcert *s)
error = xwimp_delete_window(s->window);
if (error) {
LOG("xwimp_delete_window: 0x%x:%s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
error = xwimp_delete_window(s->pane);
if (error) {
LOG("xwimp_delete_window: 0x%x:%s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
free(s);
diff --git a/riscos/textselection.c b/riscos/textselection.c
index dc852a7..718171d 100644
--- a/riscos/textselection.c
+++ b/riscos/textselection.c
@@ -23,8 +23,9 @@
#include <assert.h>
#include <stdio.h>
#include <string.h>
-#include "oslib/osfile.h"
-#include "oslib/wimp.h"
+#include <stdlib.h>
+#include <oslib/osfile.h>
+#include <oslib/wimp.h>
#include "utils/log.h"
#include "utils/utf8.h"
@@ -97,7 +98,7 @@ void gui_start_selection(struct gui_window *g)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -111,7 +112,7 @@ void gui_start_selection(struct gui_window *g)
(wimp_message*)&msg, wimp_BROADCAST);
if (error) {
LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
owns_caret_and_selection = true;
@@ -141,7 +142,7 @@ void gui_start_selection(struct gui_window *g)
error = xwimp_drag_box(&drag);
if (error) {
LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
last_start_window = g;
}
@@ -170,13 +171,13 @@ static void ro_gui_selection_drag_end(wimp_dragged *drag, void *data)
error = xwimp_drag_box((wimp_drag*)-1);
if (error) {
LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
error = xwimp_get_pointer_info(&pointer);
if (error) {
LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -227,7 +228,7 @@ static void gui_set_clipboard(const char *buffer, size_t length,
(wimp_message*)&msg, wimp_BROADCAST);
if (error) {
LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
owns_clipboard = true;
}
@@ -512,7 +513,7 @@ bool ro_gui_save_clipboard(const char *path)
ret = utf8_to_local_encoding(clipboard, clip_length, &local_cb);
if (ret != NSERROR_OK) {
- warn_user("SaveError", "Could not convert");
+ ro_warn_user("SaveError", "Could not convert");
return false;
}
@@ -524,7 +525,7 @@ bool ro_gui_save_clipboard(const char *path)
if (error) {
LOG("xosfile_save_stamped: 0x%x: %s", error->errnum, error->errmess);
- warn_user("SaveError", error->errmess);
+ ro_warn_user("SaveError", error->errmess);
return false;
}
diff --git a/riscos/theme.c b/riscos/theme.c
index 333c9e6..7f2beea 100644
--- a/riscos/theme.c
+++ b/riscos/theme.c
@@ -186,7 +186,7 @@ static void ro_gui_theme_get_available_in_dir(const char *directory)
error->errnum, error->errmess);
if (error->errnum == 0xd6) /* no such dir */
return;
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
break;
}
@@ -367,7 +367,7 @@ bool ro_gui_theme_add_descriptor(const char *folder, const char *leafname)
filename = malloc(strlen(folder) + strlen(leafname) + 2);
if (!filename) {
LOG("No memory for malloc");
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return false;
}
sprintf(filename, "%s.%s", folder, leafname);
@@ -377,7 +377,7 @@ bool ro_gui_theme_add_descriptor(const char *folder, const char *leafname)
&file_handle);
if (error) {
LOG("xosfind_openinw: 0x%x: %s", error->errnum, error->errmess);
- warn_user("FileError", error->errmess);
+ ro_warn_user("FileError", error->errmess);
free(filename);
return false;
}
@@ -392,7 +392,7 @@ bool ro_gui_theme_add_descriptor(const char *folder, const char *leafname)
xosfind_closew(file_handle);
if (error) {
LOG("xosbgpb_read_atw: 0x%x: %s", error->errnum, error->errmess);
- warn_user("FileError", error->errmess);
+ ro_warn_user("FileError", error->errmess);
free(filename);
return false;
}
@@ -406,7 +406,7 @@ bool ro_gui_theme_add_descriptor(const char *folder, const char *leafname)
sizeof(struct theme_descriptor));
if (!current) {
LOG("calloc failed");
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
free(filename);
return false;
}
@@ -524,7 +524,7 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list)
sizeof(struct theme));
if (!descriptor->theme) {
LOG("calloc() failed");
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
continue;
}
descriptor->theme->users = 1;
@@ -534,7 +534,7 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list)
&obj_type, 0, 0, &file_size, 0, 0);
if (error) {
LOG("xosfile_read_stamped_no_path: 0x%x: %s", error->errnum, error->errmess);
- warn_user("FileError", error->errmess);
+ ro_warn_user("FileError", error->errmess);
continue;
}
if (obj_type != fileswitch_IS_FILE)
@@ -542,7 +542,7 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list)
raw_data = malloc(file_size);
if (!raw_data) {
LOG("malloc() failed");
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
continue;
}
error = xosfile_load_stamped_no_path(descriptor->filename,
@@ -550,7 +550,7 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list)
if (error) {
free(raw_data);
LOG("xosfile_load_stamped_no_path: 0x%x: %s", error->errnum, error->errmess);
- warn_user("FileError", error->errmess);
+ ro_warn_user("FileError", error->errmess);
continue;
}
@@ -559,7 +559,7 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list)
if (error) {
free(raw_data);
LOG("xsquash_decompress_return_sizes: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
continue;
}
decompressed = (osspriteop_area *)malloc(
@@ -569,7 +569,7 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list)
free(decompressed);
free(raw_data);
LOG("malloc() failed");
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
continue;
}
error = xsquash_decompress(squash_INPUT_ALL_PRESENT, workspace,
@@ -584,7 +584,7 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list)
if (error) {
free(decompressed);
LOG("xsquash_decompress: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
continue;
}
if (status != 0) {
@@ -602,7 +602,7 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list)
sprite_name, 16, i, 0);
if (error) {
LOG("xosspriteop_return_name: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
continue;
}
if (strncmp(sprite_name, "throbber", 8))
@@ -617,7 +617,7 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list)
(osbool *) 0, &mode);
if (error) {
LOG("xosspriteop_read_sprite_info: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
continue;
}
ro_convert_pixels_to_os_units(&dimensions, mode);
diff --git a/riscos/theme_install.c b/riscos/theme_install.c
index 5270bd3..05efce4 100644
--- a/riscos/theme_install.c
+++ b/riscos/theme_install.c
@@ -63,7 +63,7 @@ void theme_install_start(hlcache_handle *c)
assert(content_get_type(c) == CONTENT_THEME);
if (ro_gui_dialog_open_top(dialog_theme_install, NULL, 0, 0)) {
- warn_user("ThemeInstActive", 0);
+ ro_warn_user("ThemeInstActive", 0);
return;
}
@@ -102,7 +102,7 @@ nserror theme_install_callback(hlcache_handle *handle,
source_data = content_get_source_data(handle, &source_size);
if (!theme_install_read(source_data, source_size)) {
- warn_user("ThemeInvalid", 0);
+ ro_warn_user("ThemeInvalid", 0);
theme_install_close(dialog_theme_install);
break;
}
@@ -126,7 +126,7 @@ nserror theme_install_callback(hlcache_handle *handle,
case CONTENT_MSG_ERROR:
theme_install_close(dialog_theme_install);
- warn_user(event->data.error, 0);
+ ro_warn_user(event->data.error, 0);
break;
default:
@@ -185,7 +185,7 @@ bool ro_gui_theme_install_apply(wimp_w w)
theme_file = strdup(theme_install_descriptor.name);
if (!theme_file) {
LOG("malloc failed");
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return false;
}
for (fix = theme_file; *fix != '\0'; fix++)
@@ -206,7 +206,7 @@ bool ro_gui_theme_install_apply(wimp_w w)
(byte *) source_data + source_size);
if (error) {
LOG("xosfile_save_stamped: 0x%x: %s", error->errnum, error->errmess);
- warn_user("ThemeInstallErr", 0);
+ ro_warn_user("ThemeInstallErr", 0);
free(theme_file);
return false;
}
@@ -215,7 +215,7 @@ bool ro_gui_theme_install_apply(wimp_w w)
ro_gui_theme_get_available();
theme_install = ro_gui_theme_find(theme_file);
if (!theme_install || !ro_gui_theme_apply(theme_install)) {
- warn_user("ThemeApplyErr", 0);
+ ro_warn_user("ThemeApplyErr", 0);
} else {
nsoption_set_charp(theme, strdup(theme_install->leafname));
}
diff --git a/riscos/toolbar.c b/riscos/toolbar.c
index b6e1d91..173d437 100644
--- a/riscos/toolbar.c
+++ b/riscos/toolbar.c
@@ -232,7 +232,7 @@ struct toolbar *ro_toolbar_create(struct theme_descriptor *descriptor,
toolbar = calloc(sizeof(struct toolbar), 1);
if (toolbar == NULL) {
LOG("No memory for malloc()");
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return NULL;
}
@@ -380,7 +380,7 @@ bool ro_toolbar_rebuild(struct toolbar *toolbar)
&toolbar->toolbar_handle);
if (error) {
LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -498,7 +498,7 @@ bool ro_toolbar_rebuild(struct toolbar *toolbar)
error = xwimp_create_icon(&icon, &toolbar->editor_div1);
if (error) {
LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
toolbar->editor_div1 = -1;
}
}
@@ -563,7 +563,7 @@ bool ro_toolbar_attach(struct toolbar *toolbar, wimp_w parent)
<< wimp_CHILD_TS_EDGE_SHIFT);
if (error) {
LOG("xwimp_open_window_nested: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -573,7 +573,7 @@ bool ro_toolbar_attach(struct toolbar *toolbar, wimp_w parent)
error = xwimp_close_window(toolbar->toolbar_handle);
if (error) {
LOG("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
return true;
@@ -606,7 +606,7 @@ bool ro_toolbar_process(struct toolbar *toolbar, int width, bool reformat)
error = xwimp_get_window_outline(&outline);
if (error) {
LOG("xwimp_get_window_outline: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -626,7 +626,7 @@ bool ro_toolbar_process(struct toolbar *toolbar, int width, bool reformat)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -652,7 +652,7 @@ bool ro_toolbar_process(struct toolbar *toolbar, int width, bool reformat)
&extent);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
ro_toolbar_attach(toolbar, toolbar->parent_handle);
@@ -999,7 +999,7 @@ void ro_toolbar_redraw(wimp_draw *redraw)
error = xwimp_redraw_window(redraw, &more);
if (error) {
LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
while (more) {
@@ -1018,7 +1018,7 @@ void ro_toolbar_redraw(wimp_draw *redraw)
error = xwimp_get_rectangle(redraw, &more);
if (error) {
LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
}
@@ -1051,7 +1051,7 @@ bool ro_toolbar_click(wimp_pointer *pointer)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -1330,7 +1330,7 @@ const char *ro_toolbar_get_help_suffix(wimp_w w, wimp_i i, os_coord *pos,
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return NULL;
}
diff --git a/riscos/treeview.c b/riscos/treeview.c
index aa86d20..83c9f7e 100644
--- a/riscos/treeview.c
+++ b/riscos/treeview.c
@@ -312,7 +312,7 @@ void ro_treeview_redraw_request(int x, int y, int width, int height,
error = xwimp_update_window(&update, &more);
if (error) {
LOG("xwimp_update_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
ro_treeview_redraw_loop(&update, tv, more);
@@ -343,7 +343,7 @@ void ro_treeview_redraw(wimp_draw *redraw)
error = xwimp_redraw_window(redraw, &more);
if (error) {
LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -457,7 +457,7 @@ void ro_treeview_redraw_loop(wimp_draw *redraw, ro_treeview *tv, osbool more)
error = xwimp_get_rectangle(redraw, &more);
if (error) {
LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
}
@@ -510,7 +510,7 @@ void ro_treeview_scroll_visible(int y, int height, void *pw)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -548,7 +548,7 @@ void ro_treeview_scroll_visible(int y, int height, void *pw)
error = xwimp_open_window((wimp_open *) &state);
if (error) {
LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
}
@@ -575,7 +575,7 @@ void ro_treeview_get_window_dimensions(int *width, int *height,
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -617,7 +617,7 @@ void ro_treeview_set_window_extent(ro_treeview *tv, int width, int height)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -676,7 +676,7 @@ void ro_treeview_set_window_extent(ro_treeview *tv, int width, int height)
error = xwimp_open_window((wimp_open *) &state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -700,7 +700,7 @@ void ro_treeview_set_window_extent(ro_treeview *tv, int width, int height)
error = xwimp_set_extent(tv->w, &extent);
if (error) {
LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -753,7 +753,7 @@ static void ro_treeview_open(wimp_open *open)
error = xwimp_set_extent(tv->w, &extent);
if (error) {
LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -766,7 +766,7 @@ static void ro_treeview_open(wimp_open *open)
error = xwimp_open_window(open);
if (error) {
LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
if (tv->tb)
@@ -800,7 +800,7 @@ static bool ro_treeview_mouse_click(wimp_pointer *pointer)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -938,7 +938,7 @@ void ro_treeview_mouse_at(wimp_pointer *pointer, void *data)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1022,7 +1022,7 @@ static void ro_treeview_drag_start(ro_treeview *tv, wimp_pointer *pointer,
wimp_DRAG_BOX_KEEP_IN_LINE | wimp_DRAG_BOX_CLIP);
if (error) {
LOG("xwimp_drag_box: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
} else {
auto_scroll.w = tv->w;
auto_scroll.pause_zone_sizes.x0 = 80;
@@ -1037,7 +1037,7 @@ static void ro_treeview_drag_start(ro_treeview *tv, wimp_pointer *pointer,
&auto_scroll, NULL);
if (error) {
LOG("xwimp_auto_scroll: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
ro_mouse_drag_start(ro_treeview_drag_end, ro_treeview_mouse_at,
@@ -1061,13 +1061,13 @@ static void ro_treeview_drag_end(wimp_dragged *drag, void *data)
error = xwimp_drag_box((wimp_drag *) -1);
if (error) {
LOG("xwimp_drag_box: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
error = xwimp_auto_scroll(0, NULL, NULL);
if (error) {
LOG("xwimp_auto_scroll: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
diff --git a/riscos/ucstables.c b/riscos/ucstables.c
index c881437..7ac685d 100644
--- a/riscos/ucstables.c
+++ b/riscos/ucstables.c
@@ -23,6 +23,7 @@
#include <assert.h>
#include <limits.h>
#include <string.h>
+#include <stdlib.h>
#include <oslib/osbyte.h>
#include <oslib/territory.h>
diff --git a/riscos/uri.c b/riscos/uri.c
index 2c45d75..0e4c0b8 100644
--- a/riscos/uri.c
+++ b/riscos/uri.c
@@ -82,7 +82,7 @@ void ro_uri_message_received(wimp_message *msg)
nsurl_unref(url);
}
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ ro_warn_user(messages_get_errorcode(error), 0);
}
}
diff --git a/riscos/url_complete.c b/riscos/url_complete.c
index ff91b1c..2ed82e2 100644
--- a/riscos/url_complete.c
+++ b/riscos/url_complete.c
@@ -170,7 +170,7 @@ bool ro_gui_url_complete_keypress(struct toolbar *toolbar, uint32_t key)
65536, -url_complete_matches_selection * 44);
if (error) {
LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
/* clear our state */
@@ -209,7 +209,7 @@ bool ro_gui_url_complete_keypress(struct toolbar *toolbar, uint32_t key)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
url_complete_matches_reset = true;
@@ -227,7 +227,7 @@ bool ro_gui_url_complete_keypress(struct toolbar *toolbar, uint32_t key)
0, -(i + 1) * 44, 65536, -i * 44);
if (error) {
LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError",
+ ro_warn_user("WimpError",
error->errmess);
}
}
@@ -280,7 +280,7 @@ bool ro_gui_url_complete_keypress(struct toolbar *toolbar, uint32_t key)
65536, -old_selection * 44);
if (error) {
LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
error = xwimp_force_redraw(dialog_url_complete,
@@ -288,7 +288,7 @@ bool ro_gui_url_complete_keypress(struct toolbar *toolbar, uint32_t key)
65536, -url_complete_matches_selection * 44);
if (error) {
LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
if (old_selection == -1) {
@@ -319,7 +319,7 @@ bool ro_gui_url_complete_keypress(struct toolbar *toolbar, uint32_t key)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return true;
}
@@ -334,7 +334,7 @@ bool ro_gui_url_complete_keypress(struct toolbar *toolbar, uint32_t key)
error = xwimp_open_window(PTR_WIMP_OPEN(&state));
if (error) {
LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return true;
}
@@ -410,7 +410,7 @@ void ro_gui_url_complete_resize(struct toolbar *toolbar, wimp_open *open)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -422,7 +422,7 @@ void ro_gui_url_complete_resize(struct toolbar *toolbar, wimp_open *open)
error = xwimp_get_window_state(&toolbar_state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -437,7 +437,7 @@ void ro_gui_url_complete_resize(struct toolbar *toolbar, wimp_open *open)
error = xwimp_set_extent(dialog_url_complete, &extent);
if (error) {
LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -459,14 +459,14 @@ void ro_gui_url_complete_resize(struct toolbar *toolbar, wimp_open *open)
error = xwimp_close_window(dialog_url_complete);
if (error) {
LOG("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
} else {
error = xwimp_open_window_nested_with_flags(&state,
(wimp_w)-1, 0);
if (error) {
LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
open->next = dialog_url_complete;
@@ -506,7 +506,7 @@ bool ro_gui_url_complete_close(void)
error = xwimp_close_window(dialog_url_complete);
if (error) {
LOG("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
return currently_open;
@@ -581,7 +581,7 @@ void ro_gui_url_complete_redraw(wimp_draw *redraw)
error = xwimp_plot_icon(&url_complete_icon);
if (error) {
LOG("xwimp_plot_icon: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
data = urldb_get_url_data(url_complete_matches[line]);
@@ -603,7 +603,7 @@ void ro_gui_url_complete_redraw(wimp_draw *redraw)
error = xwimp_plot_icon(&url_complete_sprite);
if (error) {
LOG("xwimp_plot_icon: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
more = wimp_get_rectangle(redraw);
@@ -657,7 +657,7 @@ bool ro_gui_url_complete_click(wimp_pointer *pointer)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -684,14 +684,14 @@ bool ro_gui_url_complete_click(wimp_pointer *pointer)
65536, -old_selection * 44);
if (error) {
LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
error = xwimp_force_redraw(dialog_url_complete,
0, -(url_complete_matches_selection + 1) * 44,
65536, -url_complete_matches_selection * 44);
if (error) {
LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
if (!pointer->buttons)
diff --git a/riscos/url_protocol.c b/riscos/url_protocol.c
index 9fa8882..97c9e16 100644
--- a/riscos/url_protocol.c
+++ b/riscos/url_protocol.c
@@ -29,8 +29,9 @@
#include <ctype.h>
#include <stdio.h>
#include <string.h>
-#include "oslib/inetsuite.h"
-#include "oslib/wimp.h"
+#include <stdlib.h>
+#include <oslib/inetsuite.h>
+#include <oslib/wimp.h>
#include "utils/log.h"
#include "utils/messages.h"
@@ -64,7 +65,7 @@ void ro_url_message_received(wimp_message *message)
if (url_message->indirect.tag != 0) {
url = strndup(url_message->url, 236);
if (!url) {
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return;
}
/* terminate at first control character */
@@ -95,7 +96,7 @@ void ro_url_message_received(wimp_message *message)
url_message->indirect.url.offset,
236 - url_message->indirect.url.offset);
if (!url) {
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return;
}
for (i = 0; !iscntrl(url[i]); i++)
@@ -122,7 +123,7 @@ void ro_url_message_received(wimp_message *message)
message->sender);
if (error) {
LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
/* create new browser window */
@@ -135,7 +136,7 @@ void ro_url_message_received(wimp_message *message)
nsurl_unref(nsurl);
if (errorns != NSERROR_OK) {
- warn_user(messages_get_errorcode(errorns), 0);
+ ro_warn_user(messages_get_errorcode(errorns), 0);
}
}
@@ -165,7 +166,7 @@ void ro_url_broadcast(const char *url)
(wimp_message *) &message, 0);
if (error) {
LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
@@ -189,7 +190,7 @@ void ro_url_load(const char *url)
command = malloc(40 + (colon - url) + strlen(url));
if (!command) {
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return;
}
@@ -204,7 +205,7 @@ void ro_url_load(const char *url)
error = xwimp_start_task(command, 0);
if (error) {
LOG("xwimp_start_task: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
free(command);
diff --git a/riscos/wimp.c b/riscos/wimp.c
index 93fedc3..19e5aa7 100644
--- a/riscos/wimp.c
+++ b/riscos/wimp.c
@@ -105,7 +105,7 @@ void ro_gui_wimp_cache_furniture_sizes(wimp_w w)
error = xwimpextend_get_furniture_sizes(&furniture_sizes);
if (error) {
LOG("xwimpextend_get_furniture_sizes: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
@@ -125,13 +125,13 @@ bool ro_gui_wimp_read_eig_factors(os_mode mode, int *xeig, int *yeig)
error = xos_read_mode_variable(mode, os_MODEVAR_XEIG_FACTOR, xeig, 0);
if (error) {
LOG("xos_read_mode_variable: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
return false;
}
error = xos_read_mode_variable(mode, os_MODEVAR_YEIG_FACTOR, yeig, 0);
if (error) {
LOG("xos_read_mode_variable: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
return false;
}
return true;
@@ -198,14 +198,14 @@ void ro_gui_force_redraw_icon(wimp_w w, wimp_i i)
error = xwimp_get_icon_state(&ic);
if (error) {
LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
error = xwimp_force_redraw(w, ic.icon.extent.x0, ic.icon.extent.y0,
ic.icon.extent.x1, ic.icon.extent.y1);
if (error) {
LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
@@ -237,7 +237,7 @@ const char *ro_gui_get_icon_string(wimp_w w, wimp_i i)
error = xwimp_get_icon_state(&ic);
if (error) {
LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return NULL;
}
itext = (ic.icon.flags & wimp_ICON_INDIRECTED)
@@ -294,7 +294,7 @@ void ro_gui_set_icon_string(wimp_w w, wimp_i i, const char *text, bool is_utf8)
error = xwimp_get_icon_state(&ic);
if (error) {
LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
goto exit;
}
@@ -327,7 +327,7 @@ void ro_gui_set_icon_string(wimp_w w, wimp_i i, const char *text, bool is_utf8)
error = xwimp_get_caret_position(&caret);
if (error) {
LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
goto exit;
}
if ((caret.w == w) && (caret.i == i)) {
@@ -338,7 +338,7 @@ void ro_gui_set_icon_string(wimp_w w, wimp_i i, const char *text, bool is_utf8)
caret.pos.y, -1, caret.index);
if (error) {
LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
}
@@ -447,7 +447,7 @@ void ro_gui_set_icon_selected_state(wimp_w w, wimp_i i, bool state)
(state ? wimp_ICON_SELECTED : 0), wimp_ICON_SELECTED);
if (error) {
LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
@@ -466,7 +466,7 @@ bool ro_gui_get_icon_selected_state(wimp_w w, wimp_i i)
error = xwimp_get_icon_state(&ic);
if (error) {
LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
return ((ic.icon.flags & wimp_ICON_SELECTED) != 0);
@@ -492,7 +492,7 @@ void ro_gui_set_icon_shaded_state(wimp_w w, wimp_i i, bool state)
(state ? wimp_ICON_SHADED : 0), wimp_ICON_SHADED);
if (error) {
LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
if (!state)
return;
@@ -501,7 +501,7 @@ void ro_gui_set_icon_shaded_state(wimp_w w, wimp_i i, bool state)
error = xwimp_get_caret_position(&caret);
if (error) {
LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
if ((caret.w != w) || (caret.i != i))
@@ -513,7 +513,7 @@ void ro_gui_set_icon_shaded_state(wimp_w w, wimp_i i, bool state)
error = xwimp_set_caret_position((wimp_w)-1, (wimp_i)-1, -1, -1, -1, -1);
if (error) {
LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
}
@@ -554,7 +554,7 @@ void ro_gui_set_icon_deleted_state(wimp_w w, wimp_i i, bool state)
(state ? wimp_ICON_DELETED : 0), wimp_ICON_DELETED);
if (error) {
LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
if (!state)
return;
@@ -563,7 +563,7 @@ void ro_gui_set_icon_deleted_state(wimp_w w, wimp_i i, bool state)
error = xwimp_get_caret_position(&caret);
if (error) {
LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
if ((caret.w != w) || (caret.i != i))
@@ -575,7 +575,7 @@ void ro_gui_set_icon_deleted_state(wimp_w w, wimp_i i, bool state)
error = xwimp_set_caret_position((wimp_w)-1, (wimp_i)-1, -1, -1, -1, -1);
if (error) {
LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
}
@@ -611,7 +611,7 @@ void ro_gui_set_icon_button_type(wimp_w w, wimp_i i, int type)
(type << wimp_ICON_BUTTON_TYPE_SHIFT));
if (error) {
LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
@@ -636,7 +636,7 @@ void ro_gui_set_icon_sprite(wimp_w w, wimp_i i, osspriteop_area *area,
error = xwimp_get_icon_state(&ic);
if (error) {
LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -673,7 +673,7 @@ void ro_gui_set_window_title(wimp_w w, const char *text)
error = xwimp_get_window_info_header_only((wimp_window_info *)&window);
if (error) {
LOG("xwimp_get_window_info: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -700,7 +700,7 @@ void ro_gui_set_window_title(wimp_w w, const char *text)
error = xwimp_force_redraw_title(w);
if (error) {
LOG("xwimp_force_redraw_title: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -727,7 +727,7 @@ bool ro_gui_set_caret_first(wimp_w w)
error = xwimp_get_window_state(&win_state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
if (!(win_state.flags & wimp_WINDOW_OPEN))
@@ -738,7 +738,7 @@ bool ro_gui_set_caret_first(wimp_w w)
error = xwimp_get_window_info_header_only((wimp_window_info *)&window);
if (error) {
LOG("xwimp_get_window_info: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -749,7 +749,7 @@ bool ro_gui_set_caret_first(wimp_w w)
error = xwimp_get_icon_state(&state);
if (error) {
LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -766,7 +766,7 @@ bool ro_gui_set_caret_first(wimp_w w)
strlen(state.icon.data.indirected_text.text));
if (error) {
LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
return true;
}
@@ -792,17 +792,17 @@ osspriteop_area *ro_gui_load_sprite_file(const char *pathname)
&obj_type, 0, 0, &len, 0, 0);
if (error) {
LOG("xosfile_read_stamped_no_path: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
return 0;
}
if (obj_type != fileswitch_IS_FILE) {
- warn_user("FileError", pathname);
+ ro_warn_user("FileError", pathname);
return 0;
}
area = malloc(len + 4);
if (!area) {
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return 0;
}
@@ -815,7 +815,7 @@ osspriteop_area *ro_gui_load_sprite_file(const char *pathname)
area, pathname);
if (error) {
LOG("xosspriteop_load_sprite_file: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
free(area);
return 0;
}
@@ -845,7 +845,7 @@ bool ro_gui_wimp_sprite_exists(const char *sprite)
if (error) {
if (error->errnum != error_SPRITE_OP_DOESNT_EXIST) {
LOG("xwimpspriteop_select_sprite: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
}
return false;
}
@@ -918,7 +918,7 @@ bool ro_gui_wimp_get_sprite_dimensions(osspriteop_area *area, char *sprite,
*height = dimensions.y;
} else if (error->errnum != error_SPRITE_OP_DOESNT_EXIST) {
LOG("xosspriteop_read_sprite_info: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
return false;
}
@@ -943,7 +943,7 @@ void ro_gui_user_redraw(wimp_draw *redraw, bool user_fill,
error = xwimp_redraw_window(redraw, &more);
if (error) {
LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
while (more) {
@@ -953,14 +953,14 @@ void ro_gui_user_redraw(wimp_draw *redraw, bool user_fill,
os_ACTION_OVERWRITE, 0, 0);
if (error) {
LOG("xcolourtrans_set_gcol: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
}
os_clg();
}
error = xwimp_get_rectangle(redraw, &more);
if (error) {
LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
}
@@ -987,7 +987,7 @@ void ro_gui_wimp_update_window_furniture(wimp_w w, wimp_window_flags bic_mask,
error = xwimp_get_window_state_and_nesting(&state, &parent, &linkage);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1000,7 +1000,7 @@ void ro_gui_wimp_update_window_furniture(wimp_w w, wimp_window_flags bic_mask,
error = xwimp_open_window_nested_with_flags(&state, parent, linkage);
if (error) {
LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1008,7 +1008,7 @@ void ro_gui_wimp_update_window_furniture(wimp_w w, wimp_window_flags bic_mask,
error = xwimp_close_window(w);
if (error) {
LOG("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
}
@@ -1030,7 +1030,7 @@ bool ro_gui_wimp_check_window_furniture(wimp_w w, wimp_window_flags mask)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
return state.flags & mask;
diff --git a/riscos/wimp_event.c b/riscos/wimp_event.c
index 4951fb9..b266004 100644
--- a/riscos/wimp_event.c
+++ b/riscos/wimp_event.c
@@ -578,7 +578,7 @@ bool ro_gui_wimp_event_menu_selection(wimp_w w, wimp_i i, wimp_menu *menu,
error = xwimp_get_icon_state(&ic);
if (error) {
LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
button_type = (ic.icon.flags & wimp_ICON_BUTTON_TYPE) >> wimp_ICON_BUTTON_TYPE_SHIFT;
@@ -588,7 +588,7 @@ bool ro_gui_wimp_event_menu_selection(wimp_w w, wimp_i i, wimp_menu *menu,
error = xwimp_get_caret_position(&caret);
if (error) {
LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
if ((caret.w != window->w) || (caret.i != event->data.menu_gright.field)) {
@@ -596,7 +596,7 @@ bool ro_gui_wimp_event_menu_selection(wimp_w w, wimp_i i, wimp_menu *menu,
-1, -1, -1, strlen(menu_entry->data.indirected_text.text));
if (error) {
LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
if (window->keypress) {
@@ -705,13 +705,13 @@ bool ro_gui_wimp_event_mouse_click(wimp_pointer *pointer)
error = xwimp_get_window_state(&open);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
error = xwimp_get_caret_position(&caret);
if (error) {
LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
ro_gui_dialog_add_persistent(current_menu_window,
@@ -720,7 +720,7 @@ bool ro_gui_wimp_event_mouse_click(wimp_pointer *pointer)
error = xwimp_open_window(PTR_WIMP_OPEN(&open));
if (error) {
LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
if (caret.w == pointer->w) {
@@ -730,7 +730,7 @@ bool ro_gui_wimp_event_mouse_click(wimp_pointer *pointer)
-1, caret.index);
if (error) {
LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
}
@@ -798,7 +798,7 @@ void ro_gui_wimp_event_prepare_gright_menu(wimp_w w, struct icon_event *event)
error = xwimp_get_icon_state(&ic);
if (error) {
LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
button_type = (ic.icon.flags & wimp_ICON_BUTTON_TYPE)
diff --git a/riscos/window.c b/riscos/window.c
index ebb1b6a..ab1501c 100644
--- a/riscos/window.c
+++ b/riscos/window.c
@@ -22,8 +22,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
- * Browser window handling (implementation).
+/**
+ * \file
+ * Implementation of RISC OS browser window handling.
*/
#include <assert.h>
@@ -34,12 +35,13 @@
#include <stdbool.h>
#include <time.h>
#include <string.h>
-#include "oslib/colourtrans.h"
-#include "oslib/osbyte.h"
-#include "oslib/osfile.h"
-#include "oslib/osspriteop.h"
-#include "oslib/wimp.h"
-#include "oslib/wimpspriteop.h"
+#include <oslib/colourtrans.h>
+#include <oslib/osbyte.h>
+#include <oslib/osfile.h>
+#include <oslib/osspriteop.h>
+#include <oslib/wimp.h>
+#include <oslib/wimpspriteop.h>
+#include <nsutils/time.h>
#include "utils/config.h"
#include "utils/nsoption.h"
@@ -49,6 +51,7 @@
#include "utils/utf8.h"
#include "utils/utils.h"
#include "utils/messages.h"
+#include "utils/string.h"
#include "content/content.h"
#include "content/hlcache.h"
#include "content/urldb.h"
@@ -387,7 +390,7 @@ static void gui_window_place_caret(struct gui_window *g, int x, int y, int heigh
x * 2, -(y + height) * 2, height * 2, -1);
if (error) {
LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
@@ -414,7 +417,7 @@ static struct gui_window *gui_window_create(struct browser_window *bw,
g = malloc(sizeof *g);
if (!g) {
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return 0;
}
g->bw = bw;
@@ -436,7 +439,7 @@ static struct gui_window *gui_window_create(struct browser_window *bw,
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
window.visible.x0 = state.visible.x0;
window.visible.x1 = state.visible.x1;
@@ -540,7 +543,7 @@ static struct gui_window *gui_window_create(struct browser_window *bw,
error = xwimp_create_window(&window, &g->window);
if (error) {
LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
free(g);
return 0;
}
@@ -601,7 +604,7 @@ static struct gui_window *gui_window_create(struct browser_window *bw,
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return g;
}
@@ -660,7 +663,7 @@ static void gui_window_destroy(struct gui_window *g)
error = xwimp_delete_window(w);
if (error) {
LOG("xwimp_delete_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
ro_gui_wimp_event_finalise(w);
@@ -712,14 +715,14 @@ void gui_window_redraw_window(struct gui_window *g)
error = xwimp_get_window_info_header_only(&info);
if (error) {
LOG("xwimp_get_window_info_header_only: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
error = xwimp_force_redraw(g->window, info.extent.x0, info.extent.y0,
info.extent.x1, info.extent.y1);
if (error) {
LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
@@ -763,7 +766,7 @@ static void gui_window_update_box(struct gui_window *g, const struct rect *rect)
cur = malloc(sizeof(struct update_box));
if (!cur) {
LOG("No memory for malloc.");
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
return;
}
cur->x0 = x0;
@@ -798,7 +801,7 @@ static bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -829,7 +832,7 @@ static void gui_window_set_scroll(struct gui_window *g, int sx, int sy)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -865,7 +868,7 @@ static void gui_window_scroll_visible(struct gui_window *g, int x0, int y0, int
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -963,7 +966,7 @@ static void gui_window_update_extent(struct gui_window *g)
error = xwimp_get_window_info_header_only(&info);
if (error) {
LOG("xwimp_get_window_info_header_only: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1017,7 +1020,7 @@ void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape)
1, entry->xactive, entry->yactive, 0, 0);
if (error) {
LOG("xwimpspriteop_set_pointer_shape: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
} else {
/* pointer in our own sprite area */
@@ -1027,7 +1030,7 @@ void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape)
1, entry->xactive, entry->yactive, 0, 0);
if (error) {
LOG("xosspriteop_set_pointer_shape: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
}
@@ -1119,7 +1122,7 @@ static void gui_window_remove_caret(struct gui_window *g)
error = xwimp_get_caret_position(&caret);
if (error) {
LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1165,7 +1168,7 @@ static bool gui_window_scroll_start(struct gui_window *g)
error = xwimp_get_pointer_info(&pointer);
if (error) {
LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -1173,7 +1176,7 @@ static bool gui_window_scroll_start(struct gui_window *g)
error = xwimp_get_window_info_header_only((wimp_window_info*)&info);
if (error) {
LOG("xwimp_get_window_state: 0x%x : %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -1195,7 +1198,7 @@ static bool gui_window_scroll_start(struct gui_window *g)
error = xwimp_drag_box(&drag);
if (error) {
LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -1226,7 +1229,7 @@ static bool gui_window_drag_start(struct gui_window *g, gui_drag_type type,
os_error *error = xwimp_get_pointer_info(&pointer);
if (error) {
LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -1243,7 +1246,7 @@ static bool gui_window_drag_start(struct gui_window *g, gui_drag_type type,
error = xwimp_drag_box(&drag);
if (error) {
LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
}
@@ -1304,7 +1307,7 @@ void gui_window_set_extent(struct gui_window *g, int width, int height)
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
if (width == -1)
@@ -1335,7 +1338,7 @@ void gui_window_set_extent(struct gui_window *g, int width, int height)
error = xwimp_set_extent(g->window, &extent);
if (error) {
LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
}
@@ -1366,7 +1369,7 @@ static void gui_window_create_form_select_menu(struct gui_window *g,
error = xwimp_get_pointer_info(&pointer);
if (error) {
LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
ro_gui_menu_destroy();
return;
}
@@ -1408,7 +1411,7 @@ void ro_gui_window_redraw(wimp_draw *redraw)
error = xwimp_redraw_window(redraw, &more);
if (error) {
LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
while (more) {
@@ -1450,7 +1453,7 @@ void ro_gui_window_redraw(wimp_draw *redraw)
option.buffer_everything &&
error->errnum == error_WIMP_GET_RECT)) {
LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
ro_gui_current_redraw_gui = NULL;
return;
}
@@ -1501,7 +1504,7 @@ void ro_gui_window_open(wimp_open *open)
error = xwimp_get_window_state_and_nesting(&state, &parent, &linkage);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1606,7 +1609,7 @@ void ro_gui_window_open(wimp_open *open)
error = xwimp_open_window_nested_with_flags(&state, parent, linkage);
if (error) {
LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1645,7 +1648,7 @@ void ro_gui_window_close(wimp_w w)
error = xwimp_get_pointer_info(&pointer);
if (error) {
LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1673,7 +1676,7 @@ void ro_gui_window_close(wimp_w w)
error = xos_cli(temp_name);
if (error) {
LOG("xos_cli: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
return;
}
free(temp_name);
@@ -1863,7 +1866,7 @@ bool ro_gui_window_handle_local_keypress(struct gui_window *g, wimp_key *key,
ro_error = xwimp_get_pointer_info(&pointer);
if (ro_error) {
LOG("xwimp_get_pointer_info: 0x%x: %s\n", ro_error->errnum, ro_error->errmess);
- warn_user("WimpError", ro_error->errmess);
+ ro_warn_user("WimpError", ro_error->errmess);
return false;
}
@@ -1887,7 +1890,7 @@ bool ro_gui_window_handle_local_keypress(struct gui_window *g, wimp_key *key,
nsurl_unref(url);
}
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ ro_warn_user(messages_get_errorcode(error), 0);
}
return true;
}
@@ -2947,7 +2950,7 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
oserror = xwimp_get_window_state(&state);
if (oserror) {
LOG("xwimp_get_window_state: 0x%x: %s", oserror->errnum, oserror->errmess);
- warn_user("WimpError", oserror->errmess);
+ ro_warn_user("WimpError", oserror->errmess);
}
nsoption_set_int(window_x, state.visible.x0);
nsoption_set_int(window_y, state.visible.y0);
@@ -3002,7 +3005,7 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
}
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ ro_warn_user(messages_get_errorcode(error), 0);
}
return true;
@@ -3151,7 +3154,7 @@ void ro_gui_window_scroll_action(struct gui_window *g,
error = xwimp_get_pointer_info(&pointer);
if (error) {
LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
@@ -3309,7 +3312,7 @@ bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message)
error = xwimp_send_message(wimp_USER_MESSAGE, message, message->sender);
if (error) {
LOG("xwimp_send_message: 0x%x: %s\n", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
return true;
@@ -3375,7 +3378,7 @@ void ro_gui_window_iconise(struct gui_window *g,
NULL);
if (error) {
LOG("xosspriteop_read_sprite_info: 0x%x: %s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
overlay = NULL;
}
else if (sprite_bpp(overlay) != 8) {
@@ -3420,7 +3423,7 @@ void ro_gui_window_iconise(struct gui_window *g,
area, temp_fname);
if (error) {
LOG("xosspriteop_save_sprite_file: 0x%x:%s", error->errnum, error->errmess);
- warn_user("MiscError", error->errmess);
+ ro_warn_user("MiscError", error->errmess);
free(area);
return;
}
@@ -3428,7 +3431,7 @@ void ro_gui_window_iconise(struct gui_window *g,
error = xwimpspriteop_merge_sprite_file(temp_fname);
if (error) {
LOG("xwimpspriteop_merge_sprite_file: 0x%x:%s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
remove(temp_fname);
free(area);
return;
@@ -3453,7 +3456,7 @@ void ro_gui_window_iconise(struct gui_window *g,
wi->sender);
if (error) {
LOG("xwimp_send_message: 0x%x:%s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
else {
g->iconise_icon = id;
@@ -3484,20 +3487,20 @@ static void ro_gui_window_scroll_end(wimp_dragged *drag, void *data)
error = xwimp_drag_box((wimp_drag*)-1);
if (error) {
LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
error = xwimp_get_pointer_info(&pointer);
if (error) {
LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return;
}
error = xwimpspriteop_set_pointer_shape("ptr_default", 0x31, 0, 0, 0, 0);
if (error) {
LOG("xwimpspriteop_set_pointer_shape: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
if (ro_gui_window_to_window_pos(g, drag->final.x0, drag->final.y0, &pos))
@@ -3646,14 +3649,14 @@ void ro_gui_window_toolbar_click(void *data,
case TOOLBAR_BUTTON_UP:
err = browser_window_navigate_up(g->bw, false);
if (err != NSERROR_OK) {
- warn_user(messages_get_errorcode(err), NULL);
+ ro_warn_user(messages_get_errorcode(err), NULL);
}
break;
case TOOLBAR_BUTTON_UP_NEW:
err = browser_window_navigate_up(g->bw, true);
if (err != NSERROR_OK) {
- warn_user(messages_get_errorcode(err), NULL);
+ ro_warn_user(messages_get_errorcode(err), NULL);
}
break;
@@ -3690,7 +3693,7 @@ bool ro_gui_toolbar_dataload(struct gui_window *g, wimp_message *message)
message->sender);
if (error) {
LOG("xwimp_send_message: 0x%x: %s\n", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
}
return true;
}
@@ -3882,7 +3885,7 @@ void ro_gui_window_launch_url(struct gui_window *g, const char *url1)
error = nsurl_create(url1, &url);
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ ro_warn_user(messages_get_errorcode(error), 0);
} else {
ro_gui_window_set_url(g, url);
@@ -3925,7 +3928,7 @@ void ro_gui_window_action_home(struct gui_window *g)
nsurl_unref(url);
}
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ ro_warn_user(messages_get_errorcode(error), 0);
}
}
@@ -3948,7 +3951,7 @@ void ro_gui_window_action_new_window(struct gui_window *g)
NULL, g->bw, NULL);
if (error != NSERROR_OK) {
- warn_user(messages_get_errorcode(error), 0);
+ ro_warn_user(messages_get_errorcode(error), 0);
}
}
@@ -4161,7 +4164,7 @@ void ro_gui_window_update_boxes(void)
error = xwimp_update_window(&update, &more);
if (error) {
LOG("xwimp_update_window: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
continue;
}
@@ -4194,7 +4197,7 @@ void ro_gui_window_update_boxes(void)
if (error && !(use_buffer &&
error->errnum == error_WIMP_GET_RECT)) {
LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
ro_gui_current_redraw_gui = NULL;
continue;
}
@@ -4387,7 +4390,7 @@ bool ro_gui_window_import_text(struct gui_window *g, const char *filename)
&size, NULL, NULL);
if (error) {
LOG("xosfile_read_stamped: 0x%x:%s", error->errnum, error->errmess);
- warn_user("FileError", error->errmess);
+ ro_warn_user("FileError", error->errmess);
return true; /* was for us, but it didn't work! */
}
@@ -4397,7 +4400,7 @@ bool ro_gui_window_import_text(struct gui_window *g, const char *filename)
buf = calloc(size + 1, sizeof(char));
if (!buf) {
- warn_user("NoMemory", NULL);
+ ro_warn_user("NoMemory", NULL);
return true;
}
@@ -4406,7 +4409,7 @@ bool ro_gui_window_import_text(struct gui_window *g, const char *filename)
if (error) {
LOG("xosfile_load_stamped: 0x%x:%s", error->errnum, error->errmess);
- warn_user("LoadError", error->errmess);
+ ro_warn_user("LoadError", error->errmess);
free(buf);
return true;
}
@@ -4417,7 +4420,7 @@ bool ro_gui_window_import_text(struct gui_window *g, const char *filename)
assert(ret != NSERROR_BAD_ENCODING);
LOG("utf8_from_local_encoding failed");
free(buf);
- warn_user("NoMemory", NULL);
+ ro_warn_user("NoMemory", NULL);
return true;
}
size = strlen(utf8_buf);
@@ -4579,7 +4582,7 @@ bool ro_gui_window_prepare_form_select_menu(struct gui_window *g,
reopen = false;
gui_form_select_menu = malloc(wimp_SIZEOF_MENU(entries));
if (!gui_form_select_menu) {
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
ro_gui_menu_destroy();
return false;
}
@@ -4589,7 +4592,7 @@ bool ro_gui_window_prepare_form_select_menu(struct gui_window *g,
/* badenc should never happen */
assert(err != NSERROR_BAD_ENCODING);
LOG("utf8_to_local_encoding failed");
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
ro_gui_menu_destroy();
return false;
}
@@ -4615,7 +4618,7 @@ bool ro_gui_window_prepare_form_select_menu(struct gui_window *g,
temp = cnv_space2nbsp(option->text);
if (!temp) {
LOG("cnv_space2nbsp failed");
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
ro_gui_menu_destroy();
return false;
}
@@ -4627,7 +4630,7 @@ bool ro_gui_window_prepare_form_select_menu(struct gui_window *g,
* so assert this */
assert(err != NSERROR_BAD_ENCODING);
LOG("utf8_to_enc failed");
- warn_user("NoMemory", 0);
+ ro_warn_user("NoMemory", 0);
ro_gui_menu_destroy();
return false;
}
@@ -4738,7 +4741,7 @@ bool ro_gui_window_to_window_pos(struct gui_window *g, int x, int y,
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x:%s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
pos->x = (x - (state.visible.x0 - state.xscroll)) / 2 / g->scale;
@@ -4769,7 +4772,7 @@ bool ro_gui_window_to_screen_pos(struct gui_window *g, int x, int y,
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x:%s", error->errnum, error->errmess);
- warn_user("WimpError", error->errmess);
+ ro_warn_user("WimpError", error->errmess);
return false;
}
pos->x = (x * 2 * g->scale) + (state.visible.x0 - state.xscroll);
@@ -4800,7 +4803,7 @@ browser_mouse_state ro_gui_mouse_click_state(wimp_mouse_state buttons,
browser_mouse_state state = 0; /* Blank state with nothing set */
static struct {
enum { CLICK_SINGLE, CLICK_DOUBLE, CLICK_TRIPLE } type;
- unsigned int time;
+ uint64_t time;
} last_click;
switch (type) {
@@ -4850,7 +4853,10 @@ browser_mouse_state ro_gui_mouse_click_state(wimp_mouse_state buttons,
* it a triple click */
if (last_click.type == CLICK_DOUBLE) {
- if (wallclock() < last_click.time + 50) {
+ uint64_t ms_now;
+ nsu_getmonotonic_ms(&ms_now);
+
+ if (ms_now < (last_click.time + 500)) {
/* Triple click! Fire PRESS, CLICK, and
* TRIPLE_CLICK events together for
* "action on 3nd press" behaviour. */
@@ -4878,7 +4884,7 @@ browser_mouse_state ro_gui_mouse_click_state(wimp_mouse_state buttons,
last_click.type = CLICK_SINGLE;
} else {
last_click.type = CLICK_DOUBLE;
- last_click.time = wallclock();
+ nsu_getmonotonic_ms(&last_click.time);
}
} else {
last_click.type = CLICK_SINGLE;
diff --git a/test/Makefile b/test/Makefile
index f4ddb9d..ca6d692 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -11,6 +11,7 @@ nsurl_SRCS := utils/corestrings.c utils/nsurl.c utils/idna.c \
urldbtest_SRCS := content/urldb.c \
utils/idna.c utils/bloom.c utils/nsoption.c utils/nsurl.c \
utils/corestrings.c \
+ utils/hashtable.c utils/messages.c utils/utils.c \
test/log.c test/urldbtest.c
# low level cache sources
@@ -35,26 +36,59 @@ hashtable_SRCS := utils/hashtable.c test/log.c test/hashtable.c
# Coverage builds need additional flags
ifeq ($(MAKECMDGOALS),coverage)
- COVCFLAGS ?= -fprofile-arcs -ftest-coverage -O0
- COVCXXFLAGS ?= -fprofile-arcs -ftest-coverage -O0
- COVLDFLAGS ?= -lgcov -fprofile-arcs
+ COV_CFLAGS ?= -fprofile-arcs -ftest-coverage -O0
+ COV_CXXFLAGS ?= -fprofile-arcs -ftest-coverage -O0
+ COV_LDFLAGS ?= -lgcov -fprofile-arcs
TESTROOT := build-$(HOST)-coverage
else
- COVCFLAGS ?= -O0
- COVCXXFLAGS ?= -O0
+ COV_CFLAGS ?= -O0
+ COV_CXXFLAGS ?= -O0
TESTROOT := build-$(HOST)-test
endif
+
+# Extend flags with appropriate values from pkg-config for enabled features
+#
+# 1: pkg-config required modules for feature
+# 2: Human-readable name for the feature
+define pkg_cfg_detect_lib
+ ifeq ($$(PKG_CONFIG),)
+ $$(error pkg-config is required to auto-detect feature availability)
+ endif
+
+ PKG_CONFIG_$(1)_EXISTS := $$(shell $$(PKG_CONFIG) --exists $(1) && echo yes)
+
+ ifeq ($$(PKG_CONFIG_$(1)_EXISTS),yes)
+ LIB_CFLAGS += $$(shell $$(PKG_CONFIG) --cflags $(1))
+ LIB_CXXFLAGS += $$(shell $$(PKG_CONFIG) --cflags $(1))
+ LIB_LDFLAGS += $$(shell $$(PKG_CONFIG) --libs $(1))
+ ifneq ($(MAKECMDGOALS),clean)
+ $$(info PKG.CNFG: $(2) ($(1)) enabled)
+ endif
+ else
+ ifneq ($(MAKECMDGOALS),clean)
+ $$(info PKG.CNFG: $(2) ($(1)) disabled)
+ endif
+ endif
+endef
+
+
+$(eval $(call pkg_cfg_detect_lib,check,Check))
+
+
TESTCFLAGS := -std=c99 -g -Wall \
-D_BSD_SOURCE \
-D_POSIX_C_SOURCE=200809L \
-D_XOPEN_SOURCE=600 \
-Itest -I. -I.. \
-Dnsgtk \
- $(shell pkg-config --cflags libcurl check libparserutils libwapcaplet libdom libnsutils libutf8proc libidn) \
- $(COVCFLAGS)
-TESTLDFLAGS := $(shell pkg-config --libs libcurl check libparserutils libwapcaplet libdom libnsutils libutf8proc libidn) -lz \
- $(COVLDFLAGS)
+ $(shell pkg-config --cflags libcurl libparserutils libwapcaplet libdom libnsutils libutf8proc libidn) \
+ $(LIB_CFLAGS) \
+ $(COV_CFLAGS)
+
+TESTLDFLAGS := $(shell pkg-config --libs libcurl libparserutils libwapcaplet libdom libnsutils libutf8proc libidn) -lz \
+ $(LIB_LDFLAGS)\
+ $(COV_LDFLAGS)
# Source files for all tests being compiled
diff --git a/test/llcache.c b/test/llcache.c
index 42abb24..850f060 100644
--- a/test/llcache.c
+++ b/test/llcache.c
@@ -37,20 +37,6 @@
bool verbose_log;
/* utils/utils.h */
-void die(const char * const error)
-{
- fprintf(stderr, "%s\n", error);
-
- exit(1);
-}
-
-/* utils/utils.h */
-void warn_user(const char *warning, const char *detail)
-{
- fprintf(stderr, "%s %s\n", warning, detail);
-}
-
-/* utils/utils.h */
char *filename_from_path(char *path)
{
char *leafname;
diff --git a/test/urldbtest.c b/test/urldbtest.c
index aa3a2df..7a03379 100644
--- a/test/urldbtest.c
+++ b/test/urldbtest.c
@@ -62,17 +62,6 @@ void cookie_manager_remove(const struct cookie_data *data)
{
}
-void die(const char *error)
-{
- printf("die: %s\n", error);
- exit(1);
-}
-
-
-void warn_user(const char *warning, const char *detail)
-{
- printf("WARNING: %s %s\n", warning, detail);
-}
void bitmap_destroy(void *bitmap)
{
diff --git a/utils/config.h b/utils/config.h
index 5361468..ddd1c6e 100644
--- a/utils/config.h
+++ b/utils/config.h
@@ -20,7 +20,6 @@
#define _NETSURF_UTILS_CONFIG_H_
#include <stddef.h>
-#include <dirent.h>
/* Try to detect which features the target OS supports */
@@ -61,24 +60,16 @@ char *strchrnul(const char *s, int c);
#define HAVE_SYS_SELECT
#define HAVE_INETATON
+#define HAVE_POSIX_INET_HEADERS
#if (defined(_WIN32))
#undef HAVE_INETATON
#undef HAVE_SYS_SELECT
-#include <winsock2.h>
-#ifndef EAFNOSUPPORT
-#define EAFNOSUPPORT WSAEAFNOSUPPORT
-#endif
-int inet_aton(const char *cp, struct in_addr *inp);
-#else
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/select.h>
+#undef HAVE_POSIX_INET_HEADERS
#endif
#define HAVE_INETPTON
#if (defined(_WIN32))
#undef HAVE_INETPTON
-int inet_pton(int af, const char *src, void *dst);
#endif
#define HAVE_UTSNAME
@@ -115,10 +106,6 @@ char *realpath(const char *path, char *resolved_path);
#define HAVE_SCANDIR
#if (defined(_WIN32))
#undef HAVE_SCANDIR
-int alphasort(const struct dirent **d1, const struct dirent **d2);
-int scandir(const char *dir, struct dirent ***namelist,
- int (*sel)(const struct dirent *),
- int (*compar)(const struct dirent **, const struct dirent **));
#endif
/* This section toggles build options on and off.
diff --git a/desktop/version.c b/utils/dirent.h
similarity index 51%
copy from desktop/version.c
copy to utils/dirent.h
index e456aac..a22e21a 100644
--- a/desktop/version.c
+++ b/utils/dirent.h
@@ -16,15 +16,30 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "testament.h"
+/**
+ * \file directory traversal and entry
+ *
+ * This allows the obtaining of standard directory entry routines
+ * functions in a uniform way despite any oddities in headers and
+ * supported API between OS.
+ *
+ * \note This functionality was previously provided as a side effect of the
+ * utils config header include.
+ */
+
+#ifndef _NETSURF_UTILS_DIRENT_H_
+#define _NETSURF_UTILS_DIRENT_H_
-#include "desktop/version.h"
+#include "utils/config.h"
+
+#include <dirent.h>
+
+#ifndef HAVE_SCANDIR
+
+int alphasort(const struct dirent **d1, const struct dirent **d2);
+int scandir(const char *dir, struct dirent ***namelist,
+ int (*sel)(const struct dirent *),
+ int (*compar)(const struct dirent **, const struct dirent **));
+#endif
-const char * const netsurf_version = "3.5 (Dev"
-#if defined(CI_BUILD)
- " CI #" CI_BUILD
#endif
- ")"
- ;
-const int netsurf_version_major = 3;
-const int netsurf_version_minor = 4;
diff --git a/utils/file.c b/utils/file.c
index 00f8eef..8888110 100644
--- a/utils/file.c
+++ b/utils/file.c
@@ -33,6 +33,7 @@
#include "utils/corestrings.h"
#include "utils/url.h"
#include "utils/nsurl.h"
+#include "utils/string.h"
#include "utils/file.h"
/**
diff --git a/utils/filename.c b/utils/filename.c
index 19ee039..9c95901 100644
--- a/utils/filename.c
+++ b/utils/filename.c
@@ -24,7 +24,6 @@
#include <assert.h>
#include <sys/types.h>
-#include <dirent.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
@@ -33,7 +32,7 @@
#include <sys/stat.h>
#include <unistd.h>
-#include "utils/config.h"
+#include "utils/dirent.h"
#include "utils/filename.h"
#include "utils/log.h"
#include "utils/utils.h"
diff --git a/utils/filepath.c b/utils/filepath.c
index 9368c21..156ba2d 100644
--- a/utils/filepath.c
+++ b/utils/filepath.c
@@ -31,6 +31,7 @@
#include <unistd.h>
#include <string.h>
+#include "utils/dirent.h" /** \todo why is this necessary for atari to get PATH_MAX and is there a better way */
#include "utils/utils.h"
#include "utils/config.h"
#include "utils/filepath.h"
diff --git a/utils/idna.c b/utils/idna.c
index 545eff9..a23801b 100644
--- a/utils/idna.c
+++ b/utils/idna.c
@@ -21,6 +21,7 @@
* NetSurf international domain name handling implementation.
*/
+#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
diff --git a/utils/inet.h b/utils/inet.h
new file mode 100644
index 0000000..a79f293
--- /dev/null
+++ b/utils/inet.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2016 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file internet structures and defines
+ *
+ * This allows the obtaining of standard bsd sockets and associated
+ * functions in a uniform way despite any oddities in headers and
+ * supported API between OS.
+ *
+ * \note This functionality was previously provided as a side effect of the
+ * utils config header include.
+ */
+
+#ifndef _NETSURF_UTILS_INET_H_
+#define _NETSURF_UTILS_INET_H_
+
+#include "utils/config.h"
+
+#ifdef HAVE_POSIX_INET_HEADERS
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/select.h>
+
+#else
+
+#include <winsock2.h>
+#include <ws2tcpip.h>
+
+#ifndef EAFNOSUPPORT
+#define EAFNOSUPPORT WSAEAFNOSUPPORT
+#endif
+
+#endif
+
+
+#ifndef HAVE_INETATON
+int inet_aton(const char *cp, struct in_addr *inp);
+#endif
+
+#ifndef HAVE_INETPTON
+int inet_pton(int af, const char *src, void *dst);
+#endif
+
+#endif
diff --git a/utils/log.c b/utils/log.c
index 43bfbd5..15a7a9e 100644
--- a/utils/log.c
+++ b/utils/log.c
@@ -22,9 +22,9 @@
#include <stdarg.h>
#include <stdio.h>
-#include <sys/time.h>
#include "utils/config.h"
+#include "utils/sys_time.h"
#include "utils/utsname.h"
#include "desktop/version.h"
diff --git a/utils/messages.c b/utils/messages.c
index d652fef..d343cfc 100644
--- a/utils/messages.c
+++ b/utils/messages.c
@@ -25,6 +25,7 @@
* fast access.
*/
+#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <stdio.h>
diff --git a/utils/string.h b/utils/string.h
new file mode 100644
index 0000000..03d8917
--- /dev/null
+++ b/utils/string.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2016 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ * \brief Interface to utility string handling.
+ */
+
+#ifndef _NETSURF_UTILS_STRING_H_
+#define _NETSURF_UTILS_STRING_H_
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "utils/errors.h"
+
+
+/**
+ * Replace consecutive whitespace with a single space.
+ *
+ * @todo determine if squash_whitespace utf-8 safe and that it needs to be
+ *
+ * \param s source string
+ * \return heap allocated result, or NULL on memory exhaustion
+ */
+char *squash_whitespace(const char * s);
+
+
+/**
+ * Converts NUL terminated UTF-8 encoded string s containing zero or more
+ * spaces (char 32) or TABs (char 9) to non-breaking spaces
+ * (0xC2 + 0xA0 in UTF-8 encoding).
+ *
+ * Caller needs to free() result. Returns NULL in case of error. No
+ * checking is done on validness of the UTF-8 input string.
+ */
+char *cnv_space2nbsp(const char *s);
+
+
+/**
+ * Create a human readable representation of a size in bytes.
+ *
+ * Does a simple conversion which assumes the user speaks English.
+ * The buffer returned is one of three static ones so may change each
+ * time this call is made. Don't store the buffer for later use.
+ * It's done this way for convenience and to fight possible memory
+ * leaks, it is not necessarily pretty.
+ *
+ * @param bytesize The size in bytes.
+ * @return A human readable string representing the size.
+ */
+char *human_friendly_bytesize(unsigned long bytesize);
+
+
+/**
+ * Generate a string from one or more component elements separated with
+ * a single value.
+ *
+ * This is similar in intent to the perl join function creating a
+ * single delimited string from an array of several.
+ *
+ * @note If a string is allocated it must be freed by the caller.
+ *
+ * @param[in,out] str pointer to string pointer if this is NULL enough
+ * storage will be allocated for the complete path.
+ * @param[in,out] size The size of the space available if \a str not
+ * NULL on input and if not NULL set to the total
+ * output length on output.
+ * @param[in] sep The character to separate the elements with.
+ * @param[in] nelm The number of elements up to a maximum of 16.
+ * @param[in] ap The elements of the path as string pointers.
+ * @return NSERROR_OK and the complete path is written to str or error
+ * code on failure.
+ */
+nserror vsnstrjoin(char **str, size_t *size, char sep, size_t nelm, va_list ap);
+
+
+/**
+ * Generate a string from one or more component elements separated with
+ * a single value.
+ *
+ * This is similar in intent to the Perl join function creating a
+ * single delimited string from an array of several.
+ *
+ * @note If a string is allocated it must be freed by the caller.
+ *
+ * @param[in,out] str pointer to string pointer if this is NULL enough
+ * storage will be allocated for the complete path.
+ * @param[in,out] size The size of the space available if \a str not
+ * NULL on input and if not NULL set to the total
+ * output length on output.
+ * @param[in] sep The character to separate the elements with.
+ * @param[in] nelm The number of elements up to a maximum of 16.
+ * @param[in] ... The elements of the path as string pointers.
+ * @return NSERROR_OK and the complete path is written to str or error
+ * code on failure.
+ */
+nserror snstrjoin(char **str, size_t *size, char sep, size_t nelm, ...);
+
+#endif
diff --git a/utils/sys_time.h b/utils/sys_time.h
new file mode 100644
index 0000000..82d88fd
--- /dev/null
+++ b/utils/sys_time.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2016 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ * \brief BSD style time functions
+ */
+
+#ifndef _NETSURF_UTILS_SYS_TIME_H_
+#define _NETSURF_UTILS_SYS_TIME_H_
+
+#include <sys/time.h>
+
+#ifndef timeradd
+#define timeradd(a, aa, result) \
+ do { \
+ (result)->tv_sec = (a)->tv_sec + (aa)->tv_sec; \
+ (result)->tv_usec = (a)->tv_usec + (aa)->tv_usec; \
+ if ((result)->tv_usec >= 1000000) { \
+ ++(result)->tv_sec; \
+ (result)->tv_usec -= 1000000; \
+ } \
+ } while (0)
+#endif
+
+#ifndef timersub
+#define timersub(a, aa, result) \
+ do { \
+ (result)->tv_sec = (a)->tv_sec - (aa)->tv_sec; \
+ (result)->tv_usec = (a)->tv_usec - (aa)->tv_usec; \
+ if ((result)->tv_usec < 0) { \
+ --(result)->tv_sec; \
+ (result)->tv_usec += 1000000; \
+ } \
+ } while (0)
+#endif
+
+#endif
diff --git a/utils/time.h b/utils/time.h
index bde2ff6..24a3988 100644
--- a/utils/time.h
+++ b/utils/time.h
@@ -48,6 +48,36 @@ int nsc_sntimet(char *str, size_t size, time_t *timep);
* @param timep Pointer to result.
* @return NSERROR_OK on success or error code on faliure.
*/
-nserror nsc_snptimet(char *str, size_t size, time_t *timep);
+nserror nsc_snptimet(const char *str, size_t size, time_t *timep);
+
+
+/**
+ * Converts a date string to a number of seconds since epoch
+ *
+ * returns the number of seconds since the Epoch, January 1st 1970
+ * 00:00:00 in the UTC time zone, for the date and time that the
+ * \a str parameter specifies.
+ *
+ * datetime strings passed must be in one of the formats specified in:
+ * - RFC 822 (updated in RFC 1123) using time zone name or time zone delta
+ * - RFC 850 (obsoleted by RFC 1036)
+ * - ANSI C's asctime() format.
+ *
+ * @param[in] str The datetime string to parse
+ * @param[in] size The length of the source string
+ * @param[out] timep Pointer to result on success unmodified on error.
+ * @return NSERROR_OK on success and timep updated else
+ * NSERROR_INVALID if the string parsing failed otherwise a suitable
+ * error code
+ */
+nserror nsc_strntimet(const char *str, size_t size, time_t *timep);
+
+/**
+ * Create an RFC 1123 compliant date string from a Unix timestamp
+ *
+ * \param t The timestamp to consider
+ * \return Pointer to buffer containing string - invalidated by next call.
+ */
+const char *rfc1123_date(time_t t);
#endif
diff --git a/utils/url.c b/utils/url.c
index 450d471..1e3ef42 100644
--- a/utils/url.c
+++ b/utils/url.c
@@ -24,11 +24,11 @@
#include <ctype.h>
#include <string.h>
+#include <stdlib.h>
#include <curl/curl.h>
#include "utils/config.h"
#include "utils/log.h"
-#include "utils/utils.h"
#include "utils/url.h"
diff --git a/utils/utils.c b/utils/utils.c
index f97d14e..22af9d6 100644
--- a/utils/utils.c
+++ b/utils/utils.c
@@ -28,39 +28,28 @@
#include <strings.h>
#include <sys/stat.h>
#include <sys/types.h>
-#include <sys/time.h>
-#include <regex.h>
#include <time.h>
#include <errno.h>
+#include <curl/curl.h>
+
+/* required for depricated warn_user interface */
+#include <stdbool.h>
+#include "utils/errors.h"
+#include "desktop/gui_misc.h"
+#include "desktop/gui_internal.h"
#include "utils/config.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/utf8.h"
#include "utils/time.h"
+#include "utils/sys_time.h"
+#include "utils/inet.h"
+#include "utils/dirent.h"
+#include "utils/string.h"
#include "utils/utils.h"
/* exported interface documented in utils/utils.h */
-char *remove_underscores(const char *s, bool replacespace)
-{
- size_t i, ii, len;
- char *ret;
- len = strlen(s);
- ret = malloc(len + 1);
- if (ret == NULL)
- return NULL;
- for (i = 0, ii = 0; i < len; i++) {
- if (s[i] != '_')
- ret[ii++] = s[i];
- else if (replacespace)
- ret[ii++] = ' ';
- }
- ret[ii] = '\0';
- return ret;
-}
-
-
-/* exported interface documented in utils/utils.h */
char *squash_whitespace(const char *s)
{
char *c;
@@ -94,11 +83,14 @@ char *cnv_space2nbsp(const char *s)
char *d, *d0;
unsigned int numNBS;
/* Convert space & TAB into non breaking space character (0xA0) */
- for (numNBS = 0, srcP = (const char *)s; *srcP != '\0'; ++srcP)
- if (*srcP == ' ' || *srcP == '\t')
+ for (numNBS = 0, srcP = (const char *)s; *srcP != '\0'; ++srcP) {
+ if (*srcP == ' ' || *srcP == '\t') {
++numNBS;
- if ((d = (char *)malloc((srcP - s) + numNBS + 1)) == NULL)
+ }
+ }
+ if ((d = (char *)malloc((srcP - s) + numNBS + 1)) == NULL) {
return NULL;
+ }
for (d0 = d, srcP = (const char *)s; *srcP != '\0'; ++srcP) {
if (*srcP == ' ' || *srcP == '\t') {
*d0++ = 0xC2;
@@ -116,8 +108,9 @@ bool is_dir(const char *path)
{
struct stat s;
- if (stat(path, &s))
+ if (stat(path, &s)) {
return false;
+ }
return S_ISDIR(s.st_mode) ? true : false;
}
@@ -208,26 +201,11 @@ nserror snstrjoin(char **str, size_t *size, char sep, size_t nelm, ...)
}
-/* exported interface documented in utils/utils.h */
-nserror regcomp_wrapper(regex_t *preg, const char *regex, int cflags)
-{
- int r;
- r = regcomp(preg, regex, cflags);
- if (r) {
- char errbuf[200];
- regerror(r, preg, errbuf, sizeof errbuf);
- LOG("Failed to compile regexp '%s': %s\n", regex, errbuf);
- return NSERROR_INIT_FAILED;
- }
- return NSERROR_OK;
-}
-
-
/**
* The size of buffers within human_friendly_bytesize.
*
* We can have a fairly good estimate of how long the buffer needs to
- * be. The unsigned long can store a value representing a maximum
+ * be. The unsigned long can store a value representing a maximum
* size of around 4 GB. Therefore the greatest space required is to
* represent 1023MB. Currently that would be represented as "1023MB"
* so 12 including a null terminator. Ideally we would be able to
@@ -294,17 +272,6 @@ const char *rfc1123_date(time_t t)
}
-/* exported interface documented in utils/utils.h */
-unsigned int wallclock(void)
-{
- struct timeval tv;
-
- if (gettimeofday(&tv, NULL) == -1)
- return 0;
-
- return ((tv.tv_sec * 100) + (tv.tv_usec / 10000));
-}
-
#ifndef HAVE_STRCASESTR
/**
@@ -356,47 +323,15 @@ char *strndup(const char *s, size_t n)
#endif
-/* Exported interface, documented in utils.h */
-int dir_sort_alpha(const struct dirent **d1, const struct dirent **d2)
-{
- const char *s1 = (*d1)->d_name;
- const char *s2 = (*d2)->d_name;
-
- while (*s1 != '\0' && *s2 != '\0') {
- if ((*s1 >= '0' && *s1 <= '9') &&
- (*s2 >= '0' && *s2 <= '9')) {
- int n1 = 0, n2 = 0;
- while (*s1 >= '0' && *s1 <= '9') {
- n1 = n1 * 10 + (*s1) - '0';
- s1++;
- }
- while (*s2 >= '0' && *s2 <= '9') {
- n2 = n2 * 10 + (*s2) - '0';
- s2++;
- }
- if (n1 != n2) {
- return n1 - n2;
- }
- if (*s1 == '\0' || *s2 == '\0')
- break;
- }
- if (tolower(*s1) != tolower(*s2))
- break;
-
- s1++;
- s2++;
- }
-
- return tolower(*s1) - tolower(*s2);
-}
-
-
#ifndef HAVE_SCANDIR
+
+/* exported function documented in utils/dirent.h */
int alphasort(const struct dirent **d1, const struct dirent **d2)
{
return strcasecmp((*d1)->d_name, (*d2)->d_name);
}
+/* exported function documented in utils/dirent.h */
int scandir(const char *dir, struct dirent ***namelist,
int (*sel)(const struct dirent *),
int (*compar)(const struct dirent **, const struct dirent **))
@@ -500,7 +435,7 @@ int uname(struct utsname *buf) {
strcpy(buf->release,"release");
strcpy(buf->version,"version");
strcpy(buf->machine,"pc");
-
+
return 0;
}
#endif
@@ -526,7 +461,7 @@ int inet_aton(const char *cp, struct in_addr *inp)
unsigned int b1, b2, b3, b4;
unsigned char c;
- if (strspn(cp, "0123456789.") < strlen(cp))
+ if (strspn(cp, "0123456789.") < strlen(cp))
return 0;
if (sscanf(cp, "%3u.%3u.%3u.%3u%c", &b1, &b2, &b3, &b4, &c) != 4)
@@ -550,17 +485,17 @@ int inet_pton(int af, const char *src, void *dst)
if (af == AF_INET) {
ret = inet_aton(src, dst);
- }
+ }
#if !defined(NO_IPV6)
else if (af == AF_INET6) {
/* TODO: implement v6 address support */
ret = -1;
- errno = EAFNOSUPPORT;
- }
+ errno = EAFNOSUPPORT;
+ }
#endif
else {
ret = -1;
- errno = EAFNOSUPPORT;
+ errno = EAFNOSUPPORT;
}
return ret;
@@ -588,10 +523,11 @@ int nsc_sntimet(char *str, size_t size, time_t *timep)
}
return strftime(str, size, "%s", ltm);
-#endif
+#endif
}
-nserror nsc_snptimet(char *str, size_t size, time_t *timep)
+/* exported function documented in utils/time.h */
+nserror nsc_snptimet(const char *str, size_t size, time_t *timep)
{
time_t time_out;
@@ -628,3 +564,26 @@ nserror nsc_snptimet(char *str, size_t size, time_t *timep)
return NSERROR_OK;
}
+
+
+/* exported function documented in utils/time.h */
+nserror nsc_strntimet(const char *str, size_t size, time_t *timep)
+{
+ time_t result;
+
+ result = curl_getdate(str, NULL);
+
+ if (result == -1) {
+ return NSERROR_INVALID;
+ }
+
+ *timep = result;
+
+ return NSERROR_OK;
+}
+
+/* exported interface documented in utils/utils.h */
+void warn_user(const char *message, const char *detail)
+{
+ guit->misc->warning(message, detail);
+}
diff --git a/utils/utils.h b/utils/utils.h
index 4b5360c..ec4bb5c 100644
--- a/utils/utils.h
+++ b/utils/utils.h
@@ -18,7 +18,7 @@
*/
/**
- * \file utils/utils.h
+ * \file
* \brief Interface to a number of general purpose functionality.
* \todo Many of these functions and macros should have their own headers.
*/
@@ -28,15 +28,6 @@
#include <inttypes.h>
#include <stdbool.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <regex.h>
-#include <assert.h>
-#include <stdarg.h>
-
-#include "utils/errors.h"
/** Rectangle coordinates */
struct rect {
@@ -103,6 +94,7 @@ struct dirent;
#endif
#if defined(__HAIKU__) || defined(__BEOS__)
+#include <stdlib.h>
#define strtof(s,p) ((float)(strtod((s),(p))))
#endif
@@ -119,165 +111,21 @@ struct dirent;
#define SLEN(x) (sizeof((x)) - 1)
-#ifndef timeradd
-#define timeradd(a, aa, result) \
- do { \
- (result)->tv_sec = (a)->tv_sec + (aa)->tv_sec; \
- (result)->tv_usec = (a)->tv_usec + (aa)->tv_usec; \
- if ((result)->tv_usec >= 1000000) { \
- ++(result)->tv_sec; \
- (result)->tv_usec -= 1000000; \
- } \
- } while (0)
-#endif
-
-#ifndef timersub
-#define timersub(a, aa, result) \
- do { \
- (result)->tv_sec = (a)->tv_sec - (aa)->tv_sec; \
- (result)->tv_usec = (a)->tv_usec - (aa)->tv_usec; \
- if ((result)->tv_usec < 0) { \
- --(result)->tv_sec; \
- (result)->tv_usec += 1000000; \
- } \
- } while (0)
-#endif
-
-
-
-/**
- * Replace consecutive whitespace with a single space.
- *
- * @todo determine if squash_whitespace utf-8 safe and that it needs to be
- *
- * \param s source string
- * \return heap allocated result, or NULL on memory exhaustion
- */
-char * squash_whitespace(const char * s);
-
-/**
- * returns a string without its underscores
- *
- * \param s The string to change.
- * \param replacespace true to insert a space where there was an underscore
- * \return The altered string
- */
-char *remove_underscores(const char *s, bool replacespace);
-
-/**
- * Converts NUL terminated UTF-8 encoded string s containing zero or more
- * spaces (char 32) or TABs (char 9) to non-breaking spaces
- * (0xC2 + 0xA0 in UTF-8 encoding).
- *
- * Caller needs to free() result. Returns NULL in case of error. No
- * checking is done on validness of the UTF-8 input string.
- */
-char *cnv_space2nbsp(const char *s);
-
/**
* Check if a directory exists.
*/
bool is_dir(const char *path);
-/**
- * Compile a regular expression, handling errors.
- *
- * Parameters as for regcomp(), see man regex.
- */
-nserror regcomp_wrapper(regex_t *preg, const char *regex, int cflags);
/**
- * Create a human redable representation of a size in bytes.
- *
- * Does a simple conversion which assumes the user speaks English.
- * The buffer returned is one of three static ones so may change each
- * time this call is made. Don't store the buffer for later use.
- * It's done this way for convenience and to fight possible memory
- * leaks, it is not necessarily pretty.
+ * Warn the user of an event.
*
- * @todo This implementation is strange doe sit need
- * reconsidering?
+ * \warning depricated interface, this calls the warning entry in the
+ * miscellaneous gui table and discards the return code.
*
- * @param bytesize The size in bytes.
- * @return A human readable string representing the size.
+ * \param[in] message A warning looked up in the message translation table
+ * \param[in] detail Additional text to be displayed or NULL.
*/
-char *human_friendly_bytesize(unsigned long bytesize);
-
-/**
- * Create an RFC 1123 compliant date string from a Unix timestamp
- *
- * \param t The timestamp to consider
- * \return Pointer to buffer containing string - invalidated by next call.
- */
-const char *rfc1123_date(time_t t);
-
-/**
- * Returns a number of centiseconds, that increases in real time, for the
- * purposes of measuring how long something takes in wall-clock terms.
- *
- * The implementation uses gettimeofday() for this. Should the call
- * to gettimeofday() fail, it returns zero.
- *
- * \return number of centiseconds that increases monotonically
- */
-unsigned int wallclock(void);
-
-/**
- * Generate a string from one or more component elemnts separated with
- * a single value.
- *
- * This is similar in intent to the perl join function creating a
- * single delimited string from an array of several.
- *
- * @note If a string is allocated it must be freed by the caller.
- *
- * @param[in,out] str pointer to string pointer if this is NULL enough
- * storage will be allocated for the complete path.
- * @param[in,out] size The size of the space available if \a str not
- * NULL on input and if not NULL set to the total
- * output length on output.
- * @param[in] sep The character to separete the elemnts with.
- * @param[in] nelm The number of elements up to a maximum of 16.
- * @param[in] ap The elements of the path as string pointers.
- * @return NSERROR_OK and the complete path is written to str or error
- * code on faliure.
- */
-nserror vsnstrjoin(char **str, size_t *size, char sep, size_t nelm, va_list ap);
-
-/**
- * Generate a string from one or more component elemnts separated with
- * a single value.
- *
- * This is similar in intent to the perl join function creating a
- * single delimited string from an array of several.
- *
- * @note If a string is allocated it must be freed by the caller.
- *
- * @param[in,out] str pointer to string pointer if this is NULL enough
- * storage will be allocated for the complete path.
- * @param[in,out] size The size of the space available if \a str not
- * NULL on input and if not NULL set to the total
- * output length on output.
- * @param[in] sep The character to separete the elemnts with.
- * @param[in] nelm The number of elements up to a maximum of 16.
- * @param[in] ... The elements of the path as string pointers.
- * @return NSERROR_OK and the complete path is written to str or error
- * code on faliure.
- */
-nserror snstrjoin(char **str, size_t *size, char sep, size_t nelm, ...);
-
-/**
- * Comparison function for sorting directories.
- *
- * Correctly orders non zero-padded numerical parts.
- * ie. produces "file1, file2, file10" rather than "file1, file10, file2".
- *
- * d1 first directory entry
- * d2 second directory entry
- */
-int dir_sort_alpha(const struct dirent **d1, const struct dirent **d2);
-
-/* Platform specific functions */
-void warn_user(const char *warning, const char *detail);
+void warn_user(const char *message, const char *detail);
#endif
diff --git a/windows/Makefile.target b/windows/Makefile.target
index 6b8ce6a..1f2dcba 100644
--- a/windows/Makefile.target
+++ b/windows/Makefile.target
@@ -57,7 +57,7 @@ S_RESOURCES := windows_resource.o
# ----------------------------------------------------------------------------
# S_WINDOWS are sources purely for the windows build
-S_WINDOWS := main.c window.c gui.c drawable.c misc.c plot.c findfile.c \
+S_WINDOWS := main.c window.c gui.c drawable.c plot.c findfile.c \
font.c bitmap.c about.c prefs.c download.c filetype.c file.c \
localhistory.c schedule.c windbg.c pointers.c
S_WINDOWS := $(addprefix windows/,$(S_WINDOWS))
diff --git a/windows/about.c b/windows/about.c
index 686d350..4716a5c 100644
--- a/windows/about.c
+++ b/windows/about.c
@@ -27,11 +27,12 @@
#include <windows.h>
+#include "utils/log.h"
#include "utils/utils.h"
#include "utils/messages.h"
#include "desktop/version.h"
-#include "utils/log.h"
+#include "windows/gui.h"
#include "windows/window.h"
#include "windows/about.h"
#include "windows/resourceid.h"
@@ -144,7 +145,7 @@ void nsws_about_dialog_init(HINSTANCE hinst, HWND parent)
int ret = DialogBox(hinst, MAKEINTRESOURCE(IDD_DLG_ABOUT), parent,
nsws_about_event_callback);
if (ret == -1) {
- warn_user(messages_get("NoMemory"), 0);
+ win32_warning(messages_get("NoMemory"), 0);
return;
}
}
diff --git a/windows/download.c b/windows/download.c
index e1641ba..b281ea7 100644
--- a/windows/download.c
+++ b/windows/download.c
@@ -17,18 +17,19 @@
*/
#include <limits.h>
-#include <sys/time.h>
#include "utils/config.h"
#include <shlobj.h>
#include <windows.h>
+#include "utils/sys_time.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/url.h"
#include "utils/nsurl.h"
#include "utils/utils.h"
+#include "utils/string.h"
#include "content/fetch.h"
#include "desktop/gui_download.h"
#include "desktop/download.h"
@@ -85,14 +86,14 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui)
{
if (downloading) {
/* initial implementation */
- warn_user("1 download at a time please", 0);
+ win32_warning("1 download at a time please", 0);
return NULL;
}
downloading = true;
struct gui_download_window *w =
malloc(sizeof(struct gui_download_window));
if (w == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ win32_warning(messages_get("NoMemory"), 0);
return NULL;
}
int total_size = download_context_get_total_length(ctx);
@@ -107,7 +108,7 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui)
filename = strdup(messages_get("UnknownFile"));
}
if (filename == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ win32_warning(messages_get("NoMemory"), 0);
free(w);
return NULL;
}
@@ -118,14 +119,14 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui)
domain = strdup(messages_get("UnknownHost"));
}
if (domain == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ win32_warning(messages_get("NoMemory"), 0);
free(filename);
free(w);
return NULL;
}
destination = malloc(PATH_MAX);
if (destination == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ win32_warning(messages_get("NoMemory"), 0);
free(domain);
free(filename);
free(w);
@@ -143,7 +144,7 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui)
w->size = total_size;
w->total_size = strdup(size);
if (w->total_size == NULL) {
- warn_user(messages_get("NoMemory"), 0);
+ win32_warning(messages_get("NoMemory"), 0);
free(destination);
free(domain);
free(filename);
@@ -162,7 +163,7 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui)
w->window = gui;
w->file = fopen(destination, "wb");
if (w->file == NULL) {
- warn_user(messages_get("FileOpenWriteError"), destination);
+ win32_warning(messages_get("FileOpenWriteError"), destination);
free(destination);
free(domain);
free(filename);
@@ -174,7 +175,7 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui)
download1 = w;
if (nsws_download_window_up(w) == false) {
- warn_user(messages_get("NoMemory"), 0);
+ win32_warning(messages_get("NoMemory"), 0);
free(destination);
free(domain);
free(filename);
diff --git a/windows/file.c b/windows/file.c
index f8372b4..e9eb9ca 100644
--- a/windows/file.c
+++ b/windows/file.c
@@ -34,6 +34,7 @@
#include "utils/corestrings.h"
#include "utils/url.h"
#include "utils/file.h"
+#include "utils/string.h"
#include "desktop/browser.h"
#include "windows/file.h"
diff --git a/windows/font.c b/windows/font.c
index 9358d1a..f67205a 100644
--- a/windows/font.c
+++ b/windows/font.c
@@ -30,7 +30,7 @@
#include "utils/log.h"
#include "utils/nsoption.h"
#include "utils/utf8.h"
-#include "desktop/font.h"
+#include "desktop/gui_layout.h"
#include "desktop/gui_utf8.h"
#include "windows/font.h"
@@ -140,8 +140,8 @@ HFONT get_font(const plot_font_style_t *style)
* \param[out] width updated to width of string[0..length)
* \return true on success and width updated else false
*/
-static bool
-nsfont_width(const plot_font_style_t *style,
+static nserror
+win32_font_width(const plot_font_style_t *style,
const char *string,
size_t length,
int *width)
@@ -185,8 +185,8 @@ nsfont_width(const plot_font_style_t *style,
* \param actual_x updated to x coordinate of character closest to x
* \return true on success, false on error and error reported
*/
-static bool
-nsfont_position_in_string(const plot_font_style_t *style,
+static nserror
+win32_font_position(const plot_font_style_t *style,
const char *string,
size_t length,
int x,
@@ -240,8 +240,8 @@ nsfont_position_in_string(const plot_font_style_t *style,
* string[char_offset] == ' ' ||
* char_offset == length]
*/
-static bool
-nsfont_split(const plot_font_style_t *style,
+static nserror
+win32_font_split(const plot_font_style_t *style,
const char *string,
size_t length,
int x,
@@ -251,12 +251,7 @@ nsfont_split(const plot_font_style_t *style,
int c_off;
bool ret = false;
- if (nsfont_position_in_string(style,
- string,
- length,
- x,
- char_offset,
- actual_x)) {
+ if (win32_font_position(style, string, length, x, char_offset, actual_x)) {
c_off = *char_offset;
if (*char_offset == length) {
ret = true;
@@ -274,10 +269,7 @@ nsfont_split(const plot_font_style_t *style,
}
}
- ret = nsfont_width(style,
- string,
- *char_offset,
- actual_x);
+ ret = win32_font_width(style, string, *char_offset, actual_x);
}
}
@@ -288,12 +280,16 @@ nsfont_split(const plot_font_style_t *style,
return ret;
}
-const struct font_functions nsfont = {
- nsfont_width,
- nsfont_position_in_string,
- nsfont_split
+
+static struct gui_layout_table layout_table = {
+ .width = win32_font_width,
+ .position = win32_font_position,
+ .split = win32_font_split,
};
+struct gui_layout_table *win32_layout_table = &layout_table;
+
+
static struct gui_utf8_table utf8_table = {
.utf8_to_local = utf8_to_local_encoding,
.local_to_utf8 = utf8_from_local_encoding,
diff --git a/windows/font.h b/windows/font.h
index ec596f3..f2128af 100644
--- a/windows/font.h
+++ b/windows/font.h
@@ -33,6 +33,7 @@ struct font_desc {
const char *encoding;
};
+struct gui_layout_table *win32_layout_table;
struct gui_utf8_table *win32_utf8_table;
extern nserror utf8_to_font_encoding(const struct font_desc* font,
diff --git a/windows/gui.c b/windows/gui.c
index f9aca5a..9923ecf 100644
--- a/windows/gui.c
+++ b/windows/gui.c
@@ -30,6 +30,7 @@
#include "utils/corestrings.h"
#include "utils/url.h"
#include "utils/file.h"
+#include "utils/messages.h"
#include "desktop/browser.h"
#include "desktop/gui_clipboard.h"
@@ -90,8 +91,17 @@ void win32_run(void)
}
+/* exported function documented in windows/gui.h */
+nserror win32_warning(const char *warning, const char *detail)
+{
+ size_t len = 1 + ((warning != NULL) ? strlen(messages_get(warning)) :
+ 0) + ((detail != 0) ? strlen(detail) : 0);
+ char message[len];
+ snprintf(message, len, messages_get(warning), detail);
+ MessageBox(NULL, message, "Warning", MB_ICONWARNING);
-
+ return NSERROR_OK;
+}
/**
diff --git a/windows/gui.h b/windows/gui.h
index f72cb2c..4c3f360 100644
--- a/windows/gui.h
+++ b/windows/gui.h
@@ -25,6 +25,8 @@ struct gui_clipboard_table *win32_clipboard_table;
extern HINSTANCE hInstance;
+extern char *options_file_location;
+
/* bounding box */
typedef struct bbox_s {
int x0;
@@ -33,19 +35,24 @@ typedef struct bbox_s {
int y1;
} bbox_t;
-
-
-extern char *options_file_location;
-
-
-
-
/**
* Run the win32 message loop with scheduling
*/
void win32_run(void);
-/** cause the main message loop to exit */
+/**
+ * cause the main message loop to exit
+ */
void win32_set_quit(bool q);
+/**
+ * Warn the user of an event.
+ *
+ * \param[in] message A warning looked up in the message translation table
+ * \param[in] detail Additional text to be displayed or NULL.
+ * \return NSERROR_OK on success or error code if there was a
+ * faliure displaying the message to the user.
+ */
+nserror win32_warning(const char *warning, const char *detail);
+
#endif
diff --git a/windows/main.c b/windows/main.c
index 7a23f71..df64e48 100644
--- a/windows/main.c
+++ b/windows/main.c
@@ -21,6 +21,7 @@
#include <limits.h>
#include <stdbool.h>
#include <windows.h>
+#include <io.h>
#include "utils/utils.h"
#include "utils/log.h"
@@ -63,6 +64,7 @@ static void die(const char *error)
exit(1);
}
+
static nsurl *gui_get_resource_url(const char *path)
{
char buf[PATH_MAX];
@@ -132,8 +134,9 @@ static nserror set_defaults(struct nsoption_s *defaults)
}
-static struct gui_browser_table win32_browser_table = {
+static struct gui_misc_table win32_misc_table = {
.schedule = win32_schedule,
+ .warning = win32_warning,
};
@@ -152,7 +155,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hLastInstance, LPSTR lpcli, int ncmd)
const char *addr;
nsurl *url;
struct netsurf_table win32_table = {
- .browser = &win32_browser_table,
+ .misc = &win32_misc_table,
.window = win32_window_table,
.clipboard = win32_clipboard_table,
.download = win32_download_table,
@@ -160,6 +163,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hLastInstance, LPSTR lpcli, int ncmd)
.file = win32_file_table,
.utf8 = win32_utf8_table,
.bitmap = win32_bitmap_table,
+ .layout = win32_layout_table,
};
win32_fetch_table->get_resource_url = gui_get_resource_url;
@@ -254,7 +258,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hLastInstance, LPSTR lpcli, int ncmd)
}
if (ret != NSERROR_OK) {
- warn_user(messages_get_errorcode(ret), 0);
+ win32_warning(messages_get_errorcode(ret), 0);
} else {
win32_run();
}
diff --git a/windows/misc.c b/windows/misc.c
deleted file mode 100644
index ad7ce0d..0000000
--- a/windows/misc.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2008 Vincent Sanders <vince(a)simtec.co.uk>
- *
- * This file is part of NetSurf, http://www.netsurf-browser.org/
- *
- * NetSurf is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * NetSurf is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <sys/types.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "utils/config.h"
-
-#include <windows.h>
-
-#include "utils/messages.h"
-#include "utils/utils.h"
-
-void warn_user(const char *warning, const char *detail)
-{
- size_t len = 1 + ((warning != NULL) ? strlen(messages_get(warning)) :
- 0) + ((detail != 0) ? strlen(detail) : 0);
- char message[len];
- snprintf(message, len, messages_get(warning), detail);
- MessageBox(NULL, message, "Warning", MB_ICONWARNING);
-}
-
-
diff --git a/windows/prefs.c b/windows/prefs.c
index 1f8dfc9..adc0101 100644
--- a/windows/prefs.c
+++ b/windows/prefs.c
@@ -37,12 +37,12 @@ static CHOOSEFONT *nsws_prefs_font_prepare(int fontfamily, HWND parent)
{
CHOOSEFONT *cf = malloc(sizeof(CHOOSEFONT));
if (cf == NULL) {
- warn_user(messages_get("NoMemory"),0);
+ win32_warning(messages_get("NoMemory"),0);
return NULL;
}
LOGFONT *lf = malloc(sizeof(LOGFONT));
if (lf == NULL) {
- warn_user(messages_get("NoMemory"),0);
+ win32_warning(messages_get("NoMemory"),0);
free(cf);
return NULL;
}
diff --git a/windows/res/installer.nsi b/windows/res/installer.nsi
index 25e7e95..df726c8 100644
--- a/windows/res/installer.nsi
+++ b/windows/res/installer.nsi
@@ -8,7 +8,7 @@
!define DESCRIPTION "Web Browser"
# These three must be integers
!define VERSIONMAJOR 3
-!define VERSIONMINOR 4
+!define VERSIONMINOR 6
!define VERSIONBUILD 1
# These will be displayed by the "Click here for support information" link in "Add/Remove Programs"
# It is possible to use "mailto:" links in here to open the email client
diff --git a/windows/schedule.c b/windows/schedule.c
index eb9ed3b..5366add 100644
--- a/windows/schedule.c
+++ b/windows/schedule.c
@@ -16,9 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <sys/time.h>
+#include <stdlib.h>
#include <time.h>
+#include "utils/sys_time.h"
#include "utils/log.h"
#include "utils/utils.h"
#include "utils/errors.h"
diff --git a/windows/window.c b/windows/window.c
index 1dd2bfd..f5f13fe 100644
--- a/windows/window.c
+++ b/windows/window.c
@@ -921,7 +921,7 @@ nsws_window_command(HWND hwnd,
case IDM_FILE_OPEN_WINDOW:
ret = win32_open_new_window(gw);
if (ret != NSERROR_OK) {
- warn_user(messages_get_errorcode(ret), 0);
+ win32_warning(messages_get_errorcode(ret), 0);
}
break;
@@ -1027,7 +1027,7 @@ nsws_window_command(HWND hwnd,
nsurl *url;
if (nsurl_create(nsoption_charp(homepage_url), &url) != NSERROR_OK) {
- warn_user("NoMemory", 0);
+ win32_warning("NoMemory", 0);
} else {
browser_window_navigate(gw->bw,
url,
@@ -1110,7 +1110,7 @@ nsws_window_command(HWND hwnd,
gw->fullscreen = malloc(sizeof(RECT));
if ((desktop == NULL) ||
(gw->fullscreen == NULL)) {
- warn_user("NoMemory", 0);
+ win32_warning("NoMemory", 0);
break;
}
GetWindowRect(desktop, &rdesk);
@@ -1191,7 +1191,7 @@ nsws_window_command(HWND hwnd,
LOG("launching %s\n", addr);
if (nsurl_create(addr, &url) != NSERROR_OK) {
- warn_user("NoMemory", 0);
+ win32_warning("NoMemory", 0);
} else {
browser_window_navigate(gw->bw,
url,
@@ -1522,7 +1522,7 @@ static void win32_window_set_title(struct gui_window *w, const char *title)
char *fulltitle = malloc(strlen(title) +
SLEN(" - NetSurf") + 1);
if (fulltitle == NULL) {
- warn_user("NoMemory", 0);
+ win32_warning("NoMemory", 0);
return;
}
strcpy(fulltitle, title);
@@ -1707,7 +1707,7 @@ bool nsws_window_go(HWND hwnd, const char *urltxt)
return false;
if (nsurl_create(urltxt, &url) != NSERROR_OK) {
- warn_user("NoMemory", 0);
+ win32_warning("NoMemory", 0);
} else {
browser_window_navigate(gw->bw,
url,
--
NetSurf Browser