libnsgif: branch master updated. release/0.2.1-6-g6e42a24
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/libnsgif.git/shortlog/6e42a2495ac64e41434f...
...commit http://git.netsurf-browser.org/libnsgif.git/commit/6e42a2495ac64e41434f5e...
...tree http://git.netsurf-browser.org/libnsgif.git/tree/6e42a2495ac64e41434f5ec3...
The branch, master has been updated
via 6e42a2495ac64e41434f5ec3164bf5786d8d02ee (commit)
via 815676f00a4cb3c470970ea7b4cac3452b7f9d88 (commit)
via 1764ddb0017da494a7d7519802404d3fdd011c9a (commit)
from 3665353c4da1dfb7b4a1d9fa412f0dec2cb673d2 (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/libnsgif.git/commit/?id=6e42a2495ac64e4143...
commit 6e42a2495ac64e41434f5ec3164bf5786d8d02ee
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <michael.drake(a)codethink.co.uk>
libnsgif: Fix LZW Minimum Code Size check.
The passed value is now checked for validity in lzw_decode_init()
too, but checking here allows an early exit.
diff --git a/src/libnsgif.c b/src/libnsgif.c
index 49e790a..7c40eeb 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -418,7 +418,7 @@ static gif_result gif_initialise_frame(gif_animation *gif)
if (gif_bytes < 1) {
return GIF_INSUFFICIENT_FRAME_DATA;
}
- if (gif_data[0] > LZW_CODE_MAX) {
+ if (gif_data[0] >= LZW_CODE_MAX) {
return GIF_DATA_ERROR;
}
commitdiff http://git.netsurf-browser.org/libnsgif.git/commit/?id=815676f00a4cb3c470...
commit 815676f00a4cb3c470970ea7b4cac3452b7f9d88
Author: Michael Drake <michael.drake(a)codethink.co.uk>
Commit: Michael Drake <michael.drake(a)codethink.co.uk>
lzw: Reject bad LZW Minimum Code Size.
The libnsgif.c code was checking this incorrectly, so safest to
check it in the lzw.c code.
diff --git a/src/lzw.c b/src/lzw.c
index 50d1d22..1f85496 100644
--- a/src/lzw.c
+++ b/src/lzw.c
@@ -272,6 +272,10 @@ lzw_result lzw_decode_init(
{
struct lzw_dictionary_entry *table = ctx->table;
+ if (code_size >= LZW_CODE_MAX) {
+ return LZW_BAD_ICODE;
+ }
+
/* Initialise the input reading context */
ctx->input.data = compressed_data;
ctx->input.data_len = compressed_data_len;
commitdiff http://git.netsurf-browser.org/libnsgif.git/commit/?id=1764ddb0017da494a7...
commit 1764ddb0017da494a7d7519802404d3fdd011c9a
Author: Michael Drake <michael.drake(a)codethink.co.uk>
Commit: Michael Drake <michael.drake(a)codethink.co.uk>
lzw: Remove surplus semicolon.
diff --git a/src/lzw.c b/src/lzw.c
index 31cf7d4..50d1d22 100644
--- a/src/lzw.c
+++ b/src/lzw.c
@@ -230,7 +230,7 @@ static lzw_result lzw__clear_codes(
/* Reset dictionary building context */
ctx->current_code_size = ctx->initial_code_size + 1;
- ctx->current_code_size_max = (1 << ctx->current_code_size) - 1;;
+ ctx->current_code_size_max = (1 << ctx->current_code_size) - 1;
ctx->current_entry = (1 << ctx->initial_code_size) + 2;
/* There might be a sequence of clear codes, so process them all */
-----------------------------------------------------------------------
Summary of changes:
src/libnsgif.c | 2 +-
src/lzw.c | 6 +++++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/libnsgif.c b/src/libnsgif.c
index 49e790a..7c40eeb 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -418,7 +418,7 @@ static gif_result gif_initialise_frame(gif_animation *gif)
if (gif_bytes < 1) {
return GIF_INSUFFICIENT_FRAME_DATA;
}
- if (gif_data[0] > LZW_CODE_MAX) {
+ if (gif_data[0] >= LZW_CODE_MAX) {
return GIF_DATA_ERROR;
}
diff --git a/src/lzw.c b/src/lzw.c
index 31cf7d4..1f85496 100644
--- a/src/lzw.c
+++ b/src/lzw.c
@@ -230,7 +230,7 @@ static lzw_result lzw__clear_codes(
/* Reset dictionary building context */
ctx->current_code_size = ctx->initial_code_size + 1;
- ctx->current_code_size_max = (1 << ctx->current_code_size) - 1;;
+ ctx->current_code_size_max = (1 << ctx->current_code_size) - 1;
ctx->current_entry = (1 << ctx->initial_code_size) + 2;
/* There might be a sequence of clear codes, so process them all */
@@ -272,6 +272,10 @@ lzw_result lzw_decode_init(
{
struct lzw_dictionary_entry *table = ctx->table;
+ if (code_size >= LZW_CODE_MAX) {
+ return LZW_BAD_ICODE;
+ }
+
/* Initialise the input reading context */
ctx->input.data = compressed_data;
ctx->input.data_len = compressed_data_len;
--
NetSurf GIF Decoder
2 years, 5 months
netsurf: branch master updated. release/3.10-128-g5a2f693
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/5a2f69388c924dd0798e3...
...commit http://git.netsurf-browser.org/netsurf.git/commit/5a2f69388c924dd0798e372...
...tree http://git.netsurf-browser.org/netsurf.git/tree/5a2f69388c924dd0798e372f2...
The branch, master has been updated
via 5a2f69388c924dd0798e372f263af6f29cb44f10 (commit)
from 537f131ee3617614cba46dae2d893d209c0a95e3 (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=5a2f69388c924dd0798...
commit 5a2f69388c924dd0798e372f263af6f29cb44f10
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
hoist the Referer header generation logic up to the low level cache
This removes the need for the fetchers to have any interaction with
the Referer header. It has not been completely removed from the
fetch interface as fetch.c:fetch_set_cookie() still uses it for
unverifiable cookie decision logic. (There is an anchient todo here)
diff --git a/content/fetch.c b/content/fetch.c
index 533f75e..1fcc3f9 100644
--- a/content/fetch.c
+++ b/content/fetch.c
@@ -90,7 +90,6 @@ struct fetch {
fetch_callback callback;/**< Callback function. */
nsurl *url; /**< URL. */
nsurl *referer; /**< Referer URL. */
- bool send_referer; /**< Valid to send the referer */
bool verifiable; /**< Transaction is verifiable */
void *p; /**< Private data for callback. */
lwc_string *host; /**< Host part of URL, interned */
@@ -461,7 +460,6 @@ fetch_start(nsurl *url,
{
struct fetch *fetch;
lwc_string *scheme;
- bool match;
fetch = calloc(1, sizeof (*fetch));
if (fetch == NULL) {
@@ -474,8 +472,8 @@ fetch_start(nsurl *url,
/* try and obtain a fetcher for this scheme */
fetch->fetcherd = get_fetcher_for_scheme(scheme);
+ lwc_string_unref(scheme);
if (fetch->fetcherd == -1) {
- lwc_string_unref(scheme);
free(fetch);
return NSERROR_NO_FETCH_HANDLER;
}
@@ -490,48 +488,9 @@ fetch_start(nsurl *url,
fetch->host = nsurl_get_component(url, NSURL_HOST);
if (referer != NULL) {
- lwc_string *ref_scheme;
fetch->referer = nsurl_ref(referer);
-
- ref_scheme = nsurl_get_component(referer, NSURL_SCHEME);
- /* Not a problem if referer has no scheme */
-
- /* Determine whether to send the Referer header */
- if (nsoption_bool(send_referer) && ref_scheme != NULL) {
- /* User permits us to send the header
- * Only send it if:
- * 1) The fetch and referer schemes match
- * or 2) The fetch is https and the referer is http
- *
- * This ensures that referer information is only sent
- * across schemes in the special case of an https
- * request from a page served over http. The inverse
- * (https -> http) should not send the referer (15.1.3)
- */
- bool match1;
- bool match2;
- if (lwc_string_isequal(scheme, ref_scheme,
- &match) != lwc_error_ok) {
- match = false;
- }
- if (lwc_string_isequal(scheme, corestring_lwc_https,
- &match1) != lwc_error_ok) {
- match1 = false;
- }
- if (lwc_string_isequal(ref_scheme, corestring_lwc_http,
- &match2) != lwc_error_ok) {
- match2= false;
- }
- if (match == true || (match1 == true && match2 == true))
- fetch->send_referer = true;
- }
- if (ref_scheme != NULL)
- lwc_string_unref(ref_scheme);
}
- /* these aren't needed past here */
- lwc_string_unref(scheme);
-
/* try and set up the fetch */
fetch->fetcher_handle = fetchers[fetch->fetcherd].ops.setup(fetch, url,
only_2xx, downgrade_tls,
@@ -839,13 +798,6 @@ void fetch_set_http_code(struct fetch *fetch, long http_code)
fetch->http_code = http_code;
}
-/* exported interface documented in content/fetch.h */
-const char *fetch_get_referer_to_send(struct fetch *fetch)
-{
- if (fetch->send_referer)
- return nsurl_access(fetch->referer);
- return NULL;
-}
/* exported interface documented in content/fetch.h */
void fetch_set_cookie(struct fetch *fetch, const char *data)
diff --git a/content/fetch.h b/content/fetch.h
index fdb3bfb..843fec9 100644
--- a/content/fetch.h
+++ b/content/fetch.h
@@ -230,11 +230,6 @@ void fetch_free(struct fetch *f);
void fetch_set_http_code(struct fetch *fetch, long http_code);
/**
- * get the referer from the fetch
- */
-const char *fetch_get_referer_to_send(struct fetch *fetch);
-
-/**
* set cookie data on a fetch
*/
void fetch_set_cookie(struct fetch *fetch, const char *data);
diff --git a/content/fetchers/curl.c b/content/fetchers/curl.c
index f9cafae..d36f44c 100644
--- a/content/fetchers/curl.c
+++ b/content/fetchers/curl.c
@@ -889,7 +889,6 @@ static CURLcode fetch_curl_set_options(struct curl_fetch_info *f)
SETOPT(CURLOPT_WRITEDATA, f);
SETOPT(CURLOPT_WRITEHEADER, f);
SETOPT(CURLOPT_PROGRESSDATA, f);
- SETOPT(CURLOPT_REFERER, fetch_get_referer_to_send(f->fetch_handle));
SETOPT(CURLOPT_HTTPHEADER, f->headers);
if (f->post_urlenc) {
SETOPT(CURLOPT_HTTPPOST, NULL);
diff --git a/content/hlcache.c b/content/hlcache.c
index 2e15edd..d860015 100644
--- a/content/hlcache.c
+++ b/content/hlcache.c
@@ -673,11 +673,15 @@ void hlcache_finalise(void)
}
/* See hlcache.h for documentation */
-nserror hlcache_handle_retrieve(nsurl *url, uint32_t flags,
- nsurl *referer, llcache_post_data *post,
- hlcache_handle_callback cb, void *pw,
- hlcache_child_context *child,
- content_type accepted_types, hlcache_handle **result)
+nserror
+hlcache_handle_retrieve(nsurl *url,
+ uint32_t flags,
+ nsurl *referer,
+ llcache_post_data *post,
+ hlcache_handle_callback cb, void *pw,
+ hlcache_child_context *child,
+ content_type accepted_types,
+ hlcache_handle **result)
{
hlcache_retrieval_ctx *ctx;
nserror error;
diff --git a/content/llcache.c b/content/llcache.c
index c1ddea5..81e0838 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -47,6 +47,7 @@
#include "utils/utils.h"
#include "utils/time.h"
#include "utils/http.h"
+#include "utils/nsoption.h"
#include "netsurf/misc.h"
#include "desktop/gui_internal.h"
@@ -807,6 +808,87 @@ static nserror llcache_fetch_process_header(llcache_object *object,
}
/**
+ * construct a Referer header appropriate for the request
+ *
+ * \param url The url being navigated to
+ * \param referer The referring url
+ * \param header_out A pointer to receive the header. The buffer must
+ * be freed by the caller.
+ * \return NSERROR_OK and \a header_out updated on success else error code
+ */
+static nserror get_referer_header(nsurl *url, nsurl *referer, char **header_out)
+{
+ nserror res = NSERROR_INVALID;
+ lwc_string *ref_scheme;
+ lwc_string *scheme;
+ bool match;
+ bool match1;
+ bool match2;
+ char *header;
+
+ /* Determine whether to send the Referer header */
+ if (!nsoption_bool(send_referer)) {
+ return NSERROR_INVALID;
+ }
+
+ scheme = nsurl_get_component(url, NSURL_SCHEME);
+ if (scheme == NULL) {
+ return NSERROR_BAD_URL;
+ }
+
+ ref_scheme = nsurl_get_component(referer, NSURL_SCHEME);
+ if (ref_scheme == NULL) {
+ /* referer has no scheme so no header */
+ lwc_string_unref(scheme);
+ return NSERROR_INVALID;
+ }
+
+ /* User permits us to send the header
+ * Only send it if:
+ * 1) The fetch and referer schemes match
+ * or 2) The fetch is https and the referer is http
+ *
+ * This ensures that referer information is only sent
+ * across schemes in the special case of an https
+ * request from a page served over http. The inverse
+ * (https -> http) should not send the referer (15.1.3)
+ */
+ if (lwc_string_isequal(scheme, ref_scheme,
+ &match) != lwc_error_ok) {
+ match = false;
+ }
+ if (lwc_string_isequal(scheme, corestring_lwc_https,
+ &match1) != lwc_error_ok) {
+ match1 = false;
+ }
+ if (lwc_string_isequal(ref_scheme, corestring_lwc_http,
+ &match2) != lwc_error_ok) {
+ match2 = false;
+ }
+ if (match == true || (match1 == true && match2 == true)) {
+ const size_t len = SLEN("Referer: ") +
+ nsurl_length(referer) + 1;
+
+ header = malloc(len);
+ if (header == NULL) {
+ res = NSERROR_NOMEM;
+ } else {
+ snprintf(header, len, "Referer: %s",
+ nsurl_access(referer));
+
+ *header_out = header;
+ res = NSERROR_OK;
+ }
+ }
+
+
+ lwc_string_unref(scheme);
+ lwc_string_unref(ref_scheme);
+
+ return res;
+}
+
+/**
* (Re)fetch an object
*
* Sets up headers and attempts to start an actual fetch from the
@@ -834,12 +916,13 @@ static nserror llcache_object_refetch(llcache_object *object)
}
}
- /* Generate cache-control headers */
- headers = malloc(3 * sizeof(char *));
+ /* Generate headers */
+ headers = malloc(4 * sizeof(char *));
if (headers == NULL) {
return NSERROR_NOMEM;
}
+ /* cache-control header for etag */
if (object->cache.etag != NULL) {
const size_t len = SLEN("If-None-Match: ") +
strlen(object->cache.etag) + 1;
@@ -856,6 +939,7 @@ static nserror llcache_object_refetch(llcache_object *object)
header_idx++;
}
+ /* cache-control header for modification time */
if (object->cache.last_modified != 0) {
/* Maximum length of an RFC 1123 date is 29 bytes */
const size_t len = SLEN("If-Modified-Since: ") + 29 + 1;
@@ -873,6 +957,15 @@ static nserror llcache_object_refetch(llcache_object *object)
header_idx++;
}
+
+ /* Referer header */
+ if (object->fetch.referer != NULL) {
+ if (get_referer_header(object->url,
+ object->fetch.referer,
+ &headers[header_idx]) == NSERROR_OK) {
+ header_idx++;
+ }
+ }
headers[header_idx] = NULL;
/* Reset cache control data */
@@ -3571,6 +3664,46 @@ total_object_size(llcache_object *object)
return tot;
}
+/**
+ * Catch up the cache users with state changes from fetchers.
+ *
+ * \param ignored We ignore this because all our state comes from llcache.
+ */
+static void llcache_catch_up_all_users(void *ignored)
+{
+ llcache_object *object;
+
+ /* Assume after this we'll be all caught up. If any user of a handle
+ * defers then we'll invalidate all_caught_up and reschedule via
+ * llcache_users_not_caught_up()
+ */
+ llcache->all_caught_up = true;
+
+ /* Catch new users up with state of objects */
+ for (object = llcache->cached_objects; object != NULL;
+ object = object->next) {
+ llcache_object_notify_users(object);
+ }
+
+ for (object = llcache->uncached_objects; object != NULL;
+ object = object->next) {
+ llcache_object_notify_users(object);
+ }
+}
+
+/**
+ * Ask for ::llcache_catch_up_all_users to be scheduled ASAP to pump the
+ * user state machines.
+ */
+static void llcache_users_not_caught_up(void)
+{
+ if (llcache->all_caught_up) {
+ llcache->all_caught_up = false;
+ guit->misc->schedule(0, llcache_catch_up_all_users, NULL);
+ }
+}
+
+
/******************************************************************************
* Public API *
******************************************************************************/
@@ -3843,51 +3976,16 @@ void llcache_finalise(void)
llcache = NULL;
}
-/**
- * Catch up the cache users with state changes from fetchers.
- *
- * \param ignored We ignore this because all our state comes from llcache.
- */
-static void llcache_catch_up_all_users(void *ignored)
-{
- llcache_object *object;
-
- /* Assume after this we'll be all caught up. If any user of a handle
- * defers then we'll invalidate all_caught_up and reschedule via
- * llcache_users_not_caught_up()
- */
- llcache->all_caught_up = true;
-
- /* Catch new users up with state of objects */
- for (object = llcache->cached_objects; object != NULL;
- object = object->next) {
- llcache_object_notify_users(object);
- }
-
- for (object = llcache->uncached_objects; object != NULL;
- object = object->next) {
- llcache_object_notify_users(object);
- }
-}
-
-/**
- * Ask for ::llcache_catch_up_all_users to be scheduled ASAP to pump the
- * user state machines.
- */
-static void llcache_users_not_caught_up(void)
-{
- if (llcache->all_caught_up) {
- llcache->all_caught_up = false;
- guit->misc->schedule(0, llcache_catch_up_all_users, NULL);
- }
-}
/* Exported interface documented in content/llcache.h */
-nserror llcache_handle_retrieve(nsurl *url, uint32_t flags,
- nsurl *referer, const llcache_post_data *post,
- llcache_handle_callback cb, void *pw,
- llcache_handle **result)
+nserror
+llcache_handle_retrieve(nsurl *url,
+ uint32_t flags,
+ nsurl *referer,
+ const llcache_post_data *post,
+ llcache_handle_callback cb, void *pw,
+ llcache_handle **result)
{
nserror error;
llcache_object_user *user;
-----------------------------------------------------------------------
Summary of changes:
content/fetch.c | 50 +------------
content/fetch.h | 5 --
content/fetchers/curl.c | 1 -
content/hlcache.c | 14 ++--
content/llcache.c | 186 ++++++++++++++++++++++++++++++++++++-----------
5 files changed, 152 insertions(+), 104 deletions(-)
diff --git a/content/fetch.c b/content/fetch.c
index 533f75e..1fcc3f9 100644
--- a/content/fetch.c
+++ b/content/fetch.c
@@ -90,7 +90,6 @@ struct fetch {
fetch_callback callback;/**< Callback function. */
nsurl *url; /**< URL. */
nsurl *referer; /**< Referer URL. */
- bool send_referer; /**< Valid to send the referer */
bool verifiable; /**< Transaction is verifiable */
void *p; /**< Private data for callback. */
lwc_string *host; /**< Host part of URL, interned */
@@ -461,7 +460,6 @@ fetch_start(nsurl *url,
{
struct fetch *fetch;
lwc_string *scheme;
- bool match;
fetch = calloc(1, sizeof (*fetch));
if (fetch == NULL) {
@@ -474,8 +472,8 @@ fetch_start(nsurl *url,
/* try and obtain a fetcher for this scheme */
fetch->fetcherd = get_fetcher_for_scheme(scheme);
+ lwc_string_unref(scheme);
if (fetch->fetcherd == -1) {
- lwc_string_unref(scheme);
free(fetch);
return NSERROR_NO_FETCH_HANDLER;
}
@@ -490,48 +488,9 @@ fetch_start(nsurl *url,
fetch->host = nsurl_get_component(url, NSURL_HOST);
if (referer != NULL) {
- lwc_string *ref_scheme;
fetch->referer = nsurl_ref(referer);
-
- ref_scheme = nsurl_get_component(referer, NSURL_SCHEME);
- /* Not a problem if referer has no scheme */
-
- /* Determine whether to send the Referer header */
- if (nsoption_bool(send_referer) && ref_scheme != NULL) {
- /* User permits us to send the header
- * Only send it if:
- * 1) The fetch and referer schemes match
- * or 2) The fetch is https and the referer is http
- *
- * This ensures that referer information is only sent
- * across schemes in the special case of an https
- * request from a page served over http. The inverse
- * (https -> http) should not send the referer (15.1.3)
- */
- bool match1;
- bool match2;
- if (lwc_string_isequal(scheme, ref_scheme,
- &match) != lwc_error_ok) {
- match = false;
- }
- if (lwc_string_isequal(scheme, corestring_lwc_https,
- &match1) != lwc_error_ok) {
- match1 = false;
- }
- if (lwc_string_isequal(ref_scheme, corestring_lwc_http,
- &match2) != lwc_error_ok) {
- match2= false;
- }
- if (match == true || (match1 == true && match2 == true))
- fetch->send_referer = true;
- }
- if (ref_scheme != NULL)
- lwc_string_unref(ref_scheme);
}
- /* these aren't needed past here */
- lwc_string_unref(scheme);
-
/* try and set up the fetch */
fetch->fetcher_handle = fetchers[fetch->fetcherd].ops.setup(fetch, url,
only_2xx, downgrade_tls,
@@ -839,13 +798,6 @@ void fetch_set_http_code(struct fetch *fetch, long http_code)
fetch->http_code = http_code;
}
-/* exported interface documented in content/fetch.h */
-const char *fetch_get_referer_to_send(struct fetch *fetch)
-{
- if (fetch->send_referer)
- return nsurl_access(fetch->referer);
- return NULL;
-}
/* exported interface documented in content/fetch.h */
void fetch_set_cookie(struct fetch *fetch, const char *data)
diff --git a/content/fetch.h b/content/fetch.h
index fdb3bfb..843fec9 100644
--- a/content/fetch.h
+++ b/content/fetch.h
@@ -230,11 +230,6 @@ void fetch_free(struct fetch *f);
void fetch_set_http_code(struct fetch *fetch, long http_code);
/**
- * get the referer from the fetch
- */
-const char *fetch_get_referer_to_send(struct fetch *fetch);
-
-/**
* set cookie data on a fetch
*/
void fetch_set_cookie(struct fetch *fetch, const char *data);
diff --git a/content/fetchers/curl.c b/content/fetchers/curl.c
index f9cafae..d36f44c 100644
--- a/content/fetchers/curl.c
+++ b/content/fetchers/curl.c
@@ -889,7 +889,6 @@ static CURLcode fetch_curl_set_options(struct curl_fetch_info *f)
SETOPT(CURLOPT_WRITEDATA, f);
SETOPT(CURLOPT_WRITEHEADER, f);
SETOPT(CURLOPT_PROGRESSDATA, f);
- SETOPT(CURLOPT_REFERER, fetch_get_referer_to_send(f->fetch_handle));
SETOPT(CURLOPT_HTTPHEADER, f->headers);
if (f->post_urlenc) {
SETOPT(CURLOPT_HTTPPOST, NULL);
diff --git a/content/hlcache.c b/content/hlcache.c
index 2e15edd..d860015 100644
--- a/content/hlcache.c
+++ b/content/hlcache.c
@@ -673,11 +673,15 @@ void hlcache_finalise(void)
}
/* See hlcache.h for documentation */
-nserror hlcache_handle_retrieve(nsurl *url, uint32_t flags,
- nsurl *referer, llcache_post_data *post,
- hlcache_handle_callback cb, void *pw,
- hlcache_child_context *child,
- content_type accepted_types, hlcache_handle **result)
+nserror
+hlcache_handle_retrieve(nsurl *url,
+ uint32_t flags,
+ nsurl *referer,
+ llcache_post_data *post,
+ hlcache_handle_callback cb, void *pw,
+ hlcache_child_context *child,
+ content_type accepted_types,
+ hlcache_handle **result)
{
hlcache_retrieval_ctx *ctx;
nserror error;
diff --git a/content/llcache.c b/content/llcache.c
index c1ddea5..81e0838 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -47,6 +47,7 @@
#include "utils/utils.h"
#include "utils/time.h"
#include "utils/http.h"
+#include "utils/nsoption.h"
#include "netsurf/misc.h"
#include "desktop/gui_internal.h"
@@ -807,6 +808,87 @@ static nserror llcache_fetch_process_header(llcache_object *object,
}
/**
+ * construct a Referer header appropriate for the request
+ *
+ * \param url The url being navigated to
+ * \param referer The referring url
+ * \param header_out A pointer to receive the header. The buffer must
+ * be freed by the caller.
+ * \return NSERROR_OK and \a header_out updated on success else error code
+ */
+static nserror get_referer_header(nsurl *url, nsurl *referer, char **header_out)
+{
+ nserror res = NSERROR_INVALID;
+ lwc_string *ref_scheme;
+ lwc_string *scheme;
+ bool match;
+ bool match1;
+ bool match2;
+ char *header;
+
+ /* Determine whether to send the Referer header */
+ if (!nsoption_bool(send_referer)) {
+ return NSERROR_INVALID;
+ }
+
+ scheme = nsurl_get_component(url, NSURL_SCHEME);
+ if (scheme == NULL) {
+ return NSERROR_BAD_URL;
+ }
+
+ ref_scheme = nsurl_get_component(referer, NSURL_SCHEME);
+ if (ref_scheme == NULL) {
+ /* referer has no scheme so no header */
+ lwc_string_unref(scheme);
+ return NSERROR_INVALID;
+ }
+
+ /* User permits us to send the header
+ * Only send it if:
+ * 1) The fetch and referer schemes match
+ * or 2) The fetch is https and the referer is http
+ *
+ * This ensures that referer information is only sent
+ * across schemes in the special case of an https
+ * request from a page served over http. The inverse
+ * (https -> http) should not send the referer (15.1.3)
+ */
+ if (lwc_string_isequal(scheme, ref_scheme,
+ &match) != lwc_error_ok) {
+ match = false;
+ }
+ if (lwc_string_isequal(scheme, corestring_lwc_https,
+ &match1) != lwc_error_ok) {
+ match1 = false;
+ }
+ if (lwc_string_isequal(ref_scheme, corestring_lwc_http,
+ &match2) != lwc_error_ok) {
+ match2 = false;
+ }
+ if (match == true || (match1 == true && match2 == true)) {
+ const size_t len = SLEN("Referer: ") +
+ nsurl_length(referer) + 1;
+
+ header = malloc(len);
+ if (header == NULL) {
+ res = NSERROR_NOMEM;
+ } else {
+ snprintf(header, len, "Referer: %s",
+ nsurl_access(referer));
+
+ *header_out = header;
+ res = NSERROR_OK;
+ }
+ }
+
+
+ lwc_string_unref(scheme);
+ lwc_string_unref(ref_scheme);
+
+ return res;
+}
+
+/**
* (Re)fetch an object
*
* Sets up headers and attempts to start an actual fetch from the
@@ -834,12 +916,13 @@ static nserror llcache_object_refetch(llcache_object *object)
}
}
- /* Generate cache-control headers */
- headers = malloc(3 * sizeof(char *));
+ /* Generate headers */
+ headers = malloc(4 * sizeof(char *));
if (headers == NULL) {
return NSERROR_NOMEM;
}
+ /* cache-control header for etag */
if (object->cache.etag != NULL) {
const size_t len = SLEN("If-None-Match: ") +
strlen(object->cache.etag) + 1;
@@ -856,6 +939,7 @@ static nserror llcache_object_refetch(llcache_object *object)
header_idx++;
}
+ /* cache-control header for modification time */
if (object->cache.last_modified != 0) {
/* Maximum length of an RFC 1123 date is 29 bytes */
const size_t len = SLEN("If-Modified-Since: ") + 29 + 1;
@@ -873,6 +957,15 @@ static nserror llcache_object_refetch(llcache_object *object)
header_idx++;
}
+
+ /* Referer header */
+ if (object->fetch.referer != NULL) {
+ if (get_referer_header(object->url,
+ object->fetch.referer,
+ &headers[header_idx]) == NSERROR_OK) {
+ header_idx++;
+ }
+ }
headers[header_idx] = NULL;
/* Reset cache control data */
@@ -3571,6 +3664,46 @@ total_object_size(llcache_object *object)
return tot;
}
+/**
+ * Catch up the cache users with state changes from fetchers.
+ *
+ * \param ignored We ignore this because all our state comes from llcache.
+ */
+static void llcache_catch_up_all_users(void *ignored)
+{
+ llcache_object *object;
+
+ /* Assume after this we'll be all caught up. If any user of a handle
+ * defers then we'll invalidate all_caught_up and reschedule via
+ * llcache_users_not_caught_up()
+ */
+ llcache->all_caught_up = true;
+
+ /* Catch new users up with state of objects */
+ for (object = llcache->cached_objects; object != NULL;
+ object = object->next) {
+ llcache_object_notify_users(object);
+ }
+
+ for (object = llcache->uncached_objects; object != NULL;
+ object = object->next) {
+ llcache_object_notify_users(object);
+ }
+}
+
+/**
+ * Ask for ::llcache_catch_up_all_users to be scheduled ASAP to pump the
+ * user state machines.
+ */
+static void llcache_users_not_caught_up(void)
+{
+ if (llcache->all_caught_up) {
+ llcache->all_caught_up = false;
+ guit->misc->schedule(0, llcache_catch_up_all_users, NULL);
+ }
+}
+
+
/******************************************************************************
* Public API *
******************************************************************************/
@@ -3843,51 +3976,16 @@ void llcache_finalise(void)
llcache = NULL;
}
-/**
- * Catch up the cache users with state changes from fetchers.
- *
- * \param ignored We ignore this because all our state comes from llcache.
- */
-static void llcache_catch_up_all_users(void *ignored)
-{
- llcache_object *object;
-
- /* Assume after this we'll be all caught up. If any user of a handle
- * defers then we'll invalidate all_caught_up and reschedule via
- * llcache_users_not_caught_up()
- */
- llcache->all_caught_up = true;
-
- /* Catch new users up with state of objects */
- for (object = llcache->cached_objects; object != NULL;
- object = object->next) {
- llcache_object_notify_users(object);
- }
-
- for (object = llcache->uncached_objects; object != NULL;
- object = object->next) {
- llcache_object_notify_users(object);
- }
-}
-
-/**
- * Ask for ::llcache_catch_up_all_users to be scheduled ASAP to pump the
- * user state machines.
- */
-static void llcache_users_not_caught_up(void)
-{
- if (llcache->all_caught_up) {
- llcache->all_caught_up = false;
- guit->misc->schedule(0, llcache_catch_up_all_users, NULL);
- }
-}
/* Exported interface documented in content/llcache.h */
-nserror llcache_handle_retrieve(nsurl *url, uint32_t flags,
- nsurl *referer, const llcache_post_data *post,
- llcache_handle_callback cb, void *pw,
- llcache_handle **result)
+nserror
+llcache_handle_retrieve(nsurl *url,
+ uint32_t flags,
+ nsurl *referer,
+ const llcache_post_data *post,
+ llcache_handle_callback cb, void *pw,
+ llcache_handle **result)
{
nserror error;
llcache_object_user *user;
--
NetSurf Browser
2 years, 6 months
netsurf: branch master updated. release/3.10-127-g537f131
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/537f131ee3617614cba46...
...commit http://git.netsurf-browser.org/netsurf.git/commit/537f131ee3617614cba46da...
...tree http://git.netsurf-browser.org/netsurf.git/tree/537f131ee3617614cba46dae2...
The branch, master has been updated
via 537f131ee3617614cba46dae2d893d209c0a95e3 (commit)
from 847d5680613cb578ba4a548960480363a3230174 (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=537f131ee3617614cba...
commit 537f131ee3617614cba46dae2d893d209c0a95e3
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
extend teh implementing a new frontend document
diff --git a/docs/implementing-new-frontend.md b/docs/implementing-new-frontend.md
index 1b4e438..4bda47a 100644
--- a/docs/implementing-new-frontend.md
+++ b/docs/implementing-new-frontend.md
@@ -184,7 +184,7 @@ operations:
Rather than attempt to describe every aspect of an implementation we
will rather work from an actual minimal example for the FLTK toolkit.
-This is availble as a single commit (`git show 04900e82e65f8669675538a66a01b56a3e473cb2`) in the NetSurf source repository. Alternatively it can be [viewed in a web browser](https://git.netsurf-browser.org/netsurf.git/commit/?h=vince/fltk....
+This is availble as a single commit (`git show 28ecbf82ed3024f51be4c87928fd91bacfc15cbc`) in the NetSurf source repository. Alternatively it can be [viewed in a web browser](https://git.netsurf-browser.org/netsurf.git/commit/?h=vince/fltk....
This represents the absolute minimum implementation to get a browser
window on screen (and be able to click visible links). It is
@@ -193,28 +193,28 @@ equivalent implementation in other languages should be obvious.
## Building
-The [frontends/Makefile.hts](https://git.netsurf-browser.org/netsurf.git/diff/...
+The [frontends/Makefile.hts](https://git.netsurf-browser.org/netsurf.git/diff/...
had the fltk target added to the VLDTARGET variable. This allows
NetSurf to be built for this frontend with `make TARGET=fltk`
As previously described the three GNU Make files are added:
-[Makefile](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk/Makefile?h=vince/fltk&id=04900e82e65f8669675538a66a01b56a3e473cb2)
+[Makefile](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk/Makefile?h=vince/fltk&id=28ecbf82ed3024f51be4c87928fd91bacfc15cbc)
this shows how the flags are extended to add the fltk headers and
library. Additionaly the list of sources are built here, as teh
comment suggests it is important the SOURCES variable is not expanded
here so the S_FRONTEND variable is used to allow expansion at teh
correct time in the build process.
-[Makefile.defaults](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk/Makefile.defaults?h=vince/fltk&id=04900e82e65f8669675538a66a01b56a3e473cb2)
+[Makefile.defaults](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk/Makefile.defaults?h=vince/fltk&id=28ecbf82ed3024f51be4c87928fd91bacfc15cbc)
has the default setting to control the build parameters and file locations. These can be overriden by the `Makefile.config` at compile time.
-[Makefile.tools](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk/Makefile.tools?h=vince/fltk&id=04900e82e65f8669675538a66a01b56a3e473cb2)
+[Makefile.tools](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk/Makefile.tools?h=vince/fltk&id=28ecbf82ed3024f51be4c87928fd91bacfc15cbc)
allows the configuration of additional tools necessary to build for the target as a minimum pkg-config is usually required to find libraries.
## Program entry
-In our example program entry is the classical `main()` in the [main.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk... module.
+In our example program entry is the classical `main()` in the [main.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk... module.
This implements the six stage process outlined previously.
@@ -256,7 +256,7 @@ example here is a good start.
### Toolkit run loop
-The function `nsfltk_run()` runs the toolkit event loop. In this case it is using the generic scheduleing in the [misc.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk... module to ensure callbacks get made at the apropriate time.
+The function `nsfltk_run()` runs the toolkit event loop. In this case it is using the generic scheduleing in the [misc.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk... module to ensure callbacks get made at the apropriate time.
There is a `nsfltk_done` boolean global checked here so when all the
browser windows are closed the program will exit.
@@ -284,7 +284,7 @@ flushed.
## The window operation table
-Amongst all the boilerplate of the default implementation the only novel code is in the window operation table in the [window.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fl... module.
+Amongst all the boilerplate of the default implementation the only novel code is in the window operation table in the [window.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fl... module.
### `nsfltk_window_create`
@@ -333,13 +333,74 @@ This obtains the fltk widget width and height and returns them.
When the `NS_Widget::draw` method was discussed it was noted that a
plotting context is built containing an operation table. That table is
-implemented in [plotters.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/...
+implemented in [plotters.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/...
The implementation here is as minimal as can be, only line, rectangle
and text have any implementation at all and even that simply sets a
colour and performs the appropriate fltk draw function (`fl_line`,
`fl_rect` and `fl_draw` respectively)
+# Worked Example next steps
+
+The previous section outlined the absolute minimum
+implementation. Here we can exmaine some next steps taken to extend
+the frontend.
+
+## Improving the user interface
+
+The example discussion is based on a commit (`git show bc546388ce428be5cfa37cecb174d549c7b30320`) in the NetSurf source repository. Alternatively it can be [viewed in a web browser](https://git.netsurf-browser.org/netsurf.git/commit/?h=vince/fltk....
+
+This changes a single module `window.cpp` where the `NS_Window`,
+`NS_Widget` and `NS_URLBar` classes are used to create a basic
+browsing interface.
+
+The static window operation functions are moved inside the `NS_Window`
+class and the `gui_window` structure is used to obtain an instance
+allowing normal methods to be called to implement functionality. This
+is purely to make the C++ code more idiomatic and obviously would be
+handled differently in other languages.
+
+The `NS_Window` constructor builds additional widgets to just the
+browser drawing widget. It creates:
+ - a URL bar widget containing some navigation buttons and a widget to show the current url
+ - a vertical scrollbar
+ - a horizontal scrollbar
+ - a status text widget
+
+The scrollbar widgets fltk callbacks (called when user interacts with
+the scrollbar) call a method on the `NS_Widget` allowing it to track
+the current scroll offsets which are subsequently used in the drawing
+and user input handling methods.
+
+## Improving rendering
+
+Up to this point the rendering has been minimal and the text in a
+single face and size with incorrect width measurement. There was no
+proper handling of plotting styles and colours.
+
+## Implementing bitmap rendering
+
+There was no bitmap rendering so no pretty pictures.
+
+## Implementing the user messages API
+
+This immediately allows the browser to use the existing language
+translations for many internal strings.
+
+## Implementing a user settings dialog
+
+Implementing a way for the user to change configuration options
+without having to edit a configuration file greatly improves the
+perceived functionality.
+
+## Implementing corewindow
+
+The [core window interface](docs/core-window-interface.md) allows a
+frontend to use inbuilt rendering for several interfaces gaining a
+great deal of functionality for very litte code. This one interface
+set gives a cookie viewer,a local and global history viewer and a
+hotlist(bookmarks) viewer.
+
# Conclusion
Hopefully this breif overview and worked example should give the
-----------------------------------------------------------------------
Summary of changes:
docs/implementing-new-frontend.md | 79 ++++++++++++++++++++++++++++++++-----
1 file changed, 70 insertions(+), 9 deletions(-)
diff --git a/docs/implementing-new-frontend.md b/docs/implementing-new-frontend.md
index 1b4e438..4bda47a 100644
--- a/docs/implementing-new-frontend.md
+++ b/docs/implementing-new-frontend.md
@@ -184,7 +184,7 @@ operations:
Rather than attempt to describe every aspect of an implementation we
will rather work from an actual minimal example for the FLTK toolkit.
-This is availble as a single commit (`git show 04900e82e65f8669675538a66a01b56a3e473cb2`) in the NetSurf source repository. Alternatively it can be [viewed in a web browser](https://git.netsurf-browser.org/netsurf.git/commit/?h=vince/fltk....
+This is availble as a single commit (`git show 28ecbf82ed3024f51be4c87928fd91bacfc15cbc`) in the NetSurf source repository. Alternatively it can be [viewed in a web browser](https://git.netsurf-browser.org/netsurf.git/commit/?h=vince/fltk....
This represents the absolute minimum implementation to get a browser
window on screen (and be able to click visible links). It is
@@ -193,28 +193,28 @@ equivalent implementation in other languages should be obvious.
## Building
-The [frontends/Makefile.hts](https://git.netsurf-browser.org/netsurf.git/diff/...
+The [frontends/Makefile.hts](https://git.netsurf-browser.org/netsurf.git/diff/...
had the fltk target added to the VLDTARGET variable. This allows
NetSurf to be built for this frontend with `make TARGET=fltk`
As previously described the three GNU Make files are added:
-[Makefile](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk/Makefile?h=vince/fltk&id=04900e82e65f8669675538a66a01b56a3e473cb2)
+[Makefile](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk/Makefile?h=vince/fltk&id=28ecbf82ed3024f51be4c87928fd91bacfc15cbc)
this shows how the flags are extended to add the fltk headers and
library. Additionaly the list of sources are built here, as teh
comment suggests it is important the SOURCES variable is not expanded
here so the S_FRONTEND variable is used to allow expansion at teh
correct time in the build process.
-[Makefile.defaults](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk/Makefile.defaults?h=vince/fltk&id=04900e82e65f8669675538a66a01b56a3e473cb2)
+[Makefile.defaults](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk/Makefile.defaults?h=vince/fltk&id=28ecbf82ed3024f51be4c87928fd91bacfc15cbc)
has the default setting to control the build parameters and file locations. These can be overriden by the `Makefile.config` at compile time.
-[Makefile.tools](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk/Makefile.tools?h=vince/fltk&id=04900e82e65f8669675538a66a01b56a3e473cb2)
+[Makefile.tools](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk/Makefile.tools?h=vince/fltk&id=28ecbf82ed3024f51be4c87928fd91bacfc15cbc)
allows the configuration of additional tools necessary to build for the target as a minimum pkg-config is usually required to find libraries.
## Program entry
-In our example program entry is the classical `main()` in the [main.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk... module.
+In our example program entry is the classical `main()` in the [main.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk... module.
This implements the six stage process outlined previously.
@@ -256,7 +256,7 @@ example here is a good start.
### Toolkit run loop
-The function `nsfltk_run()` runs the toolkit event loop. In this case it is using the generic scheduleing in the [misc.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk... module to ensure callbacks get made at the apropriate time.
+The function `nsfltk_run()` runs the toolkit event loop. In this case it is using the generic scheduleing in the [misc.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk... module to ensure callbacks get made at the apropriate time.
There is a `nsfltk_done` boolean global checked here so when all the
browser windows are closed the program will exit.
@@ -284,7 +284,7 @@ flushed.
## The window operation table
-Amongst all the boilerplate of the default implementation the only novel code is in the window operation table in the [window.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fl... module.
+Amongst all the boilerplate of the default implementation the only novel code is in the window operation table in the [window.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fl... module.
### `nsfltk_window_create`
@@ -333,13 +333,74 @@ This obtains the fltk widget width and height and returns them.
When the `NS_Widget::draw` method was discussed it was noted that a
plotting context is built containing an operation table. That table is
-implemented in [plotters.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/...
+implemented in [plotters.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/...
The implementation here is as minimal as can be, only line, rectangle
and text have any implementation at all and even that simply sets a
colour and performs the appropriate fltk draw function (`fl_line`,
`fl_rect` and `fl_draw` respectively)
+# Worked Example next steps
+
+The previous section outlined the absolute minimum
+implementation. Here we can exmaine some next steps taken to extend
+the frontend.
+
+## Improving the user interface
+
+The example discussion is based on a commit (`git show bc546388ce428be5cfa37cecb174d549c7b30320`) in the NetSurf source repository. Alternatively it can be [viewed in a web browser](https://git.netsurf-browser.org/netsurf.git/commit/?h=vince/fltk....
+
+This changes a single module `window.cpp` where the `NS_Window`,
+`NS_Widget` and `NS_URLBar` classes are used to create a basic
+browsing interface.
+
+The static window operation functions are moved inside the `NS_Window`
+class and the `gui_window` structure is used to obtain an instance
+allowing normal methods to be called to implement functionality. This
+is purely to make the C++ code more idiomatic and obviously would be
+handled differently in other languages.
+
+The `NS_Window` constructor builds additional widgets to just the
+browser drawing widget. It creates:
+ - a URL bar widget containing some navigation buttons and a widget to show the current url
+ - a vertical scrollbar
+ - a horizontal scrollbar
+ - a status text widget
+
+The scrollbar widgets fltk callbacks (called when user interacts with
+the scrollbar) call a method on the `NS_Widget` allowing it to track
+the current scroll offsets which are subsequently used in the drawing
+and user input handling methods.
+
+## Improving rendering
+
+Up to this point the rendering has been minimal and the text in a
+single face and size with incorrect width measurement. There was no
+proper handling of plotting styles and colours.
+
+## Implementing bitmap rendering
+
+There was no bitmap rendering so no pretty pictures.
+
+## Implementing the user messages API
+
+This immediately allows the browser to use the existing language
+translations for many internal strings.
+
+## Implementing a user settings dialog
+
+Implementing a way for the user to change configuration options
+without having to edit a configuration file greatly improves the
+perceived functionality.
+
+## Implementing corewindow
+
+The [core window interface](docs/core-window-interface.md) allows a
+frontend to use inbuilt rendering for several interfaces gaining a
+great deal of functionality for very litte code. This one interface
+set gives a cookie viewer,a local and global history viewer and a
+hotlist(bookmarks) viewer.
+
# Conclusion
Hopefully this breif overview and worked example should give the
--
NetSurf Browser
2 years, 6 months
netsurf: branch vince/fltk updated. release/3.10-128-gbc54638
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/bc546388ce428be5cfa37...
...commit http://git.netsurf-browser.org/netsurf.git/commit/bc546388ce428be5cfa37ce...
...tree http://git.netsurf-browser.org/netsurf.git/tree/bc546388ce428be5cfa37cecb...
The branch, vince/fltk has been updated
discards 04900e82e65f8669675538a66a01b56a3e473cb2 (commit)
via bc546388ce428be5cfa37cecb174d549c7b30320 (commit)
via 28ecbf82ed3024f51be4c87928fd91bacfc15cbc (commit)
via 847d5680613cb578ba4a548960480363a3230174 (commit)
via 5749ace60f9359b6bc31d7f8c071d87d270733da (commit)
via 6faa70893b70fc43d6f398f2e43719c763c2d193 (commit)
via a11ad57bf64ae4e701e049ced1233cc4c7b22054 (commit)
via 9a7e41d3ea966387eff8abd86198812244cd47bc (commit)
This update added new revisions after undoing existing revisions. That is
to say, the old revision is not a strict subset of the new revision. This
situation occurs when you --force push a change and generate a repository
containing something like this:
* -- * -- B -- O -- O -- O (04900e82e65f8669675538a66a01b56a3e473cb2)
\
N -- N -- N (bc546388ce428be5cfa37cecb174d549c7b30320)
When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.
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=bc546388ce428be5cfa...
commit bc546388ce428be5cfa37cecb174d549c7b30320
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
greatly improve fltk browser user interface
diff --git a/frontends/fltk/window.cpp b/frontends/fltk/window.cpp
index 19aa265..fffc380 100644
--- a/frontends/fltk/window.cpp
+++ b/frontends/fltk/window.cpp
@@ -24,11 +24,17 @@
#include <stddef.h>
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Scrollbar.H>
#include <FL/fl_draw.H>
+#include <Fl/Fl_Output.H>
+#include <Fl/Fl_Pack.H>
+#include <Fl/Fl_Button.H>
extern "C" {
#include "utils/errors.h"
+#include "utils/nsoption.h"
+#include "utils/nsurl.h"
#include "netsurf/types.h"
#include "netsurf/mouse.h"
#include "netsurf/window.h"
@@ -36,6 +42,7 @@ extern "C" {
#include "netsurf/content.h"
#include "netsurf/browser_window.h"
#include "netsurf/mouse.h"
+#include "desktop/browser_history.h"
}
@@ -44,10 +51,16 @@ extern "C" {
extern bool nsfltk_done;
+struct gui_window {
+ class NS_Window *window;
+};
+
class NS_Widget : public Fl_Widget
{
private:
- struct browser_window *mbw;
+ struct browser_window *m_bw;
+ int m_xoffset;
+ int m_yoffset;
protected:
void draw();
@@ -55,38 +68,19 @@ protected:
public:
NS_Widget(int X,int Y,int W,int H, struct browser_window *bw)
- : Fl_Widget(X,Y,W,H), mbw(bw) {}
-};
-
-
-class NS_Window : public Fl_Double_Window
-{
-private:
- struct browser_window *mbw;
- NS_Widget *mnswidget;
-
- void close_callback(Fl_Widget *w);
- static void static_close_callback(Fl_Widget *w, void *f) { ((NS_Window *)f)->close_callback(w); }
+ : Fl_Widget(X,Y,W,H), m_bw(bw), m_xoffset(0), m_yoffset(0) {}
-public:
- NS_Window(int W, int H, struct browser_window *bw)
- : Fl_Double_Window(W,H), mbw(bw) {
- this->callback(static_close_callback, (void *)this);
- mnswidget = new NS_Widget(0, 0, W, H, bw);
- this->end();
- }
- ~NS_Window() { nsfltk_done=true; }
+ bool get_scroll(int *sx, int *sy);
+ nserror get_dimensions(int *width, int *height);
- NS_Widget *get_nswidget() { return mnswidget; }
+ nserror invalidate(const struct rect *rect);
+ void vscroll_callback(Fl_Scrollbar *w);
+ void hscroll_callback(Fl_Scrollbar *w);
};
-struct gui_window {
- struct browser_window *bw;
- NS_Window *window;
-};
/**
- * method to handle events on the netsurf browsing widget
+ * handle events on the netsurf browsing widget
*/
int NS_Widget::handle(int event)
{
@@ -99,10 +93,10 @@ int NS_Widget::handle(int event)
if (button == FL_LEFT_MOUSE) {
state |= BROWSER_MOUSE_PRESS_1;
}
- browser_window_mouse_click(mbw,
+ browser_window_mouse_click(m_bw,
(browser_mouse_state)state,
- Fl::event_x() - x(),
- Fl::event_y() - y());
+ Fl::event_x() - x() + m_xoffset,
+ Fl::event_y() - y() + m_yoffset);
return 1;
case FL_RELEASE:
@@ -111,10 +105,10 @@ int NS_Widget::handle(int event)
state |= BROWSER_MOUSE_CLICK_1;
}
- browser_window_mouse_click(mbw,
+ browser_window_mouse_click(m_bw,
(browser_mouse_state)state,
- Fl::event_x() - x(),
- Fl::event_y() - y());
+ Fl::event_x() - x() + m_xoffset,
+ Fl::event_y() - y() + m_yoffset);
return 1;
default:
@@ -124,7 +118,7 @@ int NS_Widget::handle(int event)
/**
- * method to redraw the netsurf browsing widget
+ * redraw the netsurf browsing widget
*/
void NS_Widget::draw()
{
@@ -140,103 +134,352 @@ void NS_Widget::draw()
.priv = NULL,
};
- browser_window_redraw(mbw, x(), y(), &clip, &ctx);
+ browser_window_redraw(m_bw,
+ x() - m_xoffset,
+ y() - m_yoffset,
+ &clip,
+ &ctx);
}
+
/**
- * callback when fltk window is closed
+ * vertical scrollbar position has been changed
*/
-void NS_Window::close_callback(Fl_Widget *w)
+void NS_Widget::vscroll_callback(Fl_Scrollbar *sb)
{
- browser_window_destroy(mbw);
+ m_yoffset = sb->value();
+ damage(FL_DAMAGE_SCROLL);
}
+
/**
- * Create and open a gui window for a browsing context.
- *
- * The implementing front end must create a context suitable
- * for it to display a window referred to as the "gui window".
- *
- * The frontend will be expected to request the core redraw
- * areas of the gui window which have become invalidated
- * either from toolkit expose events or as a result of a
- * invalidate() call.
- *
- * Most core operations used by the frontend concerning browser
- * windows require passing the browser window context therefor
- * the gui window must include a reference to the browser
- * window passed here.
- *
- * If GW_CREATE_CLONE flag is set existing is non-NULL.
- *
- * \param bw The core browsing context associated with the gui window
- * \param existing An existing gui_window, may be NULL.
- * \param flags flags to control the gui window creation.
- * \return gui window, or NULL on error.
+ * horizontal scrollbar position has been changed
*/
-static struct gui_window *
-nsfltk_window_create(struct browser_window *bw,
- struct gui_window *existing,
- gui_window_create_flags flags)
+void NS_Widget::hscroll_callback(Fl_Scrollbar *sb)
{
- struct gui_window *gw;
- gw = (struct gui_window *)calloc(1, sizeof(struct gui_window));
-
- gw->window = new NS_Window(800,600, bw);
+ m_xoffset = sb->value();
+ damage(FL_DAMAGE_SCROLL);
+}
- gw->window->show();
+/**
+ * get the current scroll offsets
+ */
+bool NS_Widget::get_scroll(int *sx, int *sy)
+{
+ *sx = m_xoffset;
+ *sy = m_yoffset;
- return gw;
+ return true;
}
+
/**
- * Destroy previously created gui window
- *
- * \param gw The gui window to destroy.
+ * get the viewable dimensions of browsing context
*/
-static void nsfltk_window_destroy(struct gui_window *gw)
+nserror NS_Widget::get_dimensions(int *width, int *height)
{
- Fl::delete_widget(gw->window);
- free(gw);
+ *width = w();
+ *height = h();
+
+ return NSERROR_OK;
}
/**
- * Invalidate an area of a window.
- *
- * The specified area of the window should now be considered
- * out of date. If the area is NULL the entire window must be
- * invalidated. It is expected that the windowing system will
- * then subsequently cause redraw/expose operations as
- * necessary.
- *
- * \note the frontend should not attempt to actually start the
- * redraw operations as a result of this callback because the
- * core redraw functions may already be threaded.
- *
- * \param gw The gui window to invalidate.
- * \param rect area to redraw or NULL for the entire window area
- * \return NSERROR_OK on success or appropriate error code
+ * mark an area of the browsing context as invalid
*/
-static nserror
-nsfltk_window_invalidate(struct gui_window *gw, const struct rect *rect)
+nserror NS_Widget::invalidate(const struct rect *rect)
{
- NS_Widget *nswidget;
- nswidget = gw->window->get_nswidget();
-
if (rect == NULL) {
- nswidget->damage(FL_DAMAGE_ALL);
+ damage(FL_DAMAGE_ALL);
+ } else {
+ damage(FL_DAMAGE_ALL,
+ rect->x0,
+ rect->y0,
+ rect->x1 - rect->x0,
+ rect->y1 - rect->y0);
+ }
+ return NSERROR_OK;
+
+}
+
+/**
+ * widget representing url bar
+ */
+class NS_URLBar : public Fl_Pack
+{
+private:
+ struct browser_window *m_bw;
+ Fl_Button *m_back_button;
+ Fl_Button *m_forward_button;
+ Fl_Input *m_input;
+
+ void back_callback(Fl_Button *button);
+ void forward_callback(Fl_Button *button);
+public:
+ NS_URLBar(int X,int Y,int W,int H, struct browser_window *bw);
+ nserror set_url(struct nsurl *url);
+
+ /* static wrapper for fltk callbacks */
+ static void static_back_callback(Fl_Widget *w, void *f);
+ static void static_forward_callback(Fl_Widget *w, void *f);
+
+};
+
+NS_URLBar::NS_URLBar(int X,int Y,int W,int H, struct browser_window *bw)
+ : Fl_Pack(X,Y,W,H), m_bw(bw)
+{
+ type(Fl_Pack::HORIZONTAL);
+ spacing(4);
+
+ m_back_button = new Fl_Button(0,0,H,H, "B");
+ m_back_button->callback(static_back_callback, (void *)this);
+
+ m_forward_button = new Fl_Button(0,0,H,H, "F");
+ m_forward_button->callback(static_forward_callback, (void *)this);
+
+ m_input = new Fl_Input(0,0,W,H);
+
+ end();
+
+ resizable(m_input);
+}
+
+nserror NS_URLBar::set_url(struct nsurl *url)
+{
+ size_t idn_url_l;
+ char *idn_url_s = NULL;
+ if (nsurl_get_utf8(url, &idn_url_s, &idn_url_l) == NSERROR_OK) {
+ m_input->value(idn_url_s, idn_url_l-1);
+ free(idn_url_s);
} else {
- nswidget->damage(FL_DAMAGE_ALL,
- rect->x0,
- rect->y0,
- rect->x1 - rect->x0,
- rect->y1 - rect->y0);
+ m_input->value(nsurl_access(url));
}
return NSERROR_OK;
}
+void NS_URLBar::back_callback(Fl_Button *button)
+{
+ browser_window_history_back(m_bw, false);
+}
+
+void NS_URLBar::forward_callback(Fl_Button *button)
+{
+ browser_window_history_forward(m_bw, false);
+}
+
+
+void NS_URLBar::static_back_callback(Fl_Widget *w, void *f)
+{
+ ((NS_URLBar *)f)->back_callback((Fl_Button *)w);
+}
+
+void NS_URLBar::static_forward_callback(Fl_Widget *w, void *f)
+{
+ ((NS_URLBar *)f)->forward_callback((Fl_Button *)w);
+}
+
+
+/**
+ * Class for netsurf window
+ */
+class NS_Window : public Fl_Double_Window
+{
+private:
+ struct browser_window *m_bw;
+
+ NS_URLBar *m_nsurlbar;
+ NS_Widget *m_nswidget;
+ Fl_Scrollbar *m_vscrollbar;
+ Fl_Scrollbar *m_hscrollbar;
+ Fl_Output *m_status;
+
+ nserror set_scroll(const struct rect *rect);
+ void set_status(const char *text);
+ void set_title(const char *title);
+ nserror set_extent(int w, int h);
+
+ void close_callback(Fl_Widget *w);
+
+ /* static wrapper for fltk callbacks */
+ static void static_close_callback(Fl_Widget *w, void *f);
+ static void static_hscroll_callback(Fl_Widget *w, void *f);
+ static void static_vscroll_callback(Fl_Widget *w, void *f);
+
+public:
+ NS_Window(int W, int H, struct browser_window *bw);
+ ~NS_Window() { nsfltk_done=true; }
+
+ /* static wrappers to be able to call instance methods */
+ static nserror static_set_scroll(struct gui_window *gw, const struct rect *rect);
+ static void static_set_status(struct gui_window *gw, const char *text);
+ static void static_set_title(struct gui_window *gw, const char *title);
+
+ static bool static_get_scroll(struct gui_window *gw, int *sx, int *sy);
+ static nserror static_set_url(struct gui_window *gw, struct nsurl *url);
+
+ static nserror static_event(struct gui_window *gw, enum gui_window_event event);
+ static nserror static_invalidate(struct gui_window *gw, const struct rect *rect);
+ static nserror static_get_dimensions(struct gui_window *gw, int *width, int *height);
+ static struct gui_window *static_create(struct browser_window *bw, struct gui_window *existing, gui_window_create_flags flags);
+ static void static_destroy(struct gui_window *gw);
+};
+
+
+/**
+ * netsurf window class constructor
+ */
+NS_Window::NS_Window(int W, int H, struct browser_window *bw)
+ : Fl_Double_Window(W,H), m_bw(bw)
+{
+ int scrlsize = Fl::scrollbar_size();
+ int splitx = (nsoption_int(toolbar_status_size) * W) / 10000;
+ int urlbarh = scrlsize * 2;
+
+ callback(static_close_callback, (void *)this);
+
+ // url bar
+ m_nsurlbar = new NS_URLBar(0, 0, W, urlbarh, bw);
+
+ // browser drawing canvas widget
+ m_nswidget = new NS_Widget(0,
+ m_nsurlbar->h(),
+ W - scrlsize,
+ H - scrlsize - urlbarh,
+ bw);
+
+ // vertical scrollbar
+ m_vscrollbar = new Fl_Scrollbar(m_nswidget->w(),
+ m_nsurlbar->h(),
+ scrlsize,
+ m_nswidget->h());
+ m_vscrollbar->callback(static_vscroll_callback, (void *)m_nswidget);
+ m_vscrollbar->value(0, m_nswidget->h(), 0, m_nswidget->h());
+
+ // horizontal scrollbar
+ m_hscrollbar = new Fl_Scrollbar(splitx,
+ m_nswidget->y() + m_nswidget->h(),
+ m_nswidget->w() - splitx,
+ scrlsize);
+ m_hscrollbar->type(FL_HORIZONTAL);
+ m_hscrollbar->callback(static_hscroll_callback, (void *)m_nswidget);
+ m_hscrollbar->value(0, m_nswidget->w(), 0, m_nswidget->w());
+
+ // status text
+ m_status = new Fl_Output(0, m_hscrollbar->y(), splitx, scrlsize);
+ end();
+
+ resizable(m_nswidget);
+}
+
+
+/**
+ * fltk window has been closed
+ */
+void NS_Window::close_callback(Fl_Widget *w)
+{
+ browser_window_destroy(m_bw);
+}
+
+
+
+
+/**
+ * set the status text
+ */
+void NS_Window::set_status(const char *text)
+{
+ m_status->value(text);
+}
+
+
+/**
+ * set the window title text
+ */
+void NS_Window::set_title(const char *text)
+{
+ label(text);
+}
+
+
+/**
+ * set the current position of the scroll bars
+ */
+nserror NS_Window::set_scroll(const struct rect *rect)
+{
+ m_vscrollbar->value(rect->y0);
+ m_hscrollbar->value(rect->x0);
+
+ m_nswidget->vscroll_callback(m_vscrollbar);
+ m_nswidget->hscroll_callback(m_hscrollbar);
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * Set the extent of the underlying canvas
+ */
+nserror NS_Window::set_extent(int ew, int eh)
+{
+ m_hscrollbar->value(0, w(), 0, ew);
+ m_vscrollbar->value(0, h(), 0, eh);
+
+ return NSERROR_OK;
+}
+
+
+/* static methods */
+
+/**
+ * static window close fltk callback which calls the instance
+ */
+void NS_Window::static_close_callback(Fl_Widget *w, void *f)
+{
+ ((NS_Window *)f)->close_callback(w);
+}
+
+/**
+ * static vertical scrollbar fltk callback which calls the instance
+ */
+void NS_Window::static_vscroll_callback(Fl_Widget *w, void *f)
+{
+ ((NS_Widget *)f)->vscroll_callback((Fl_Scrollbar *)w);
+}
+
+/**
+ * static horizontal scrollbar fltk callback which calls the instance
+ */
+void NS_Window::static_hscroll_callback(Fl_Widget *w, void *f)
+{
+ ((NS_Widget *)f)->hscroll_callback((Fl_Scrollbar *)w);
+}
+
+
+/**
+ * Set the status bar message of a browser window.
+ *
+ * \param g gui_window to update
+ * \param text new status text
+ */
+void NS_Window::static_set_status(struct gui_window *gw, const char *text)
+{
+ ((NS_Window *)gw->window)->set_status(text);
+}
+
+
+/**
+ * Set the title of a window.
+ *
+ * \param gw The gui window to set title of.
+ * \param title new window title
+ */
+void NS_Window::static_set_title(struct gui_window *gw, const char *title)
+{
+ ((NS_Window *)gw->window)->set_title(title);
+}
+
/**
* Get the scroll position of a browser window.
@@ -246,17 +489,17 @@ nsfltk_window_invalidate(struct gui_window *gw, const struct rect *rect)
* \param sy receives y ordinate of point at top-left of window
* \return true iff successful
*/
-static bool nsfltk_window_get_scroll(struct gui_window *gw, int *sx, int *sy)
+bool NS_Window::static_get_scroll(struct gui_window *gw, int *sx, int *sy)
{
- return false;
+ return gw->window->m_nswidget->get_scroll(sx, sy);
}
/**
* Set the scroll position of a browser window.
*
- * scrolls the viewport to ensure the specified rectangle of
- * the content is shown.
+ * scrolls the viewport to ensure the specified rectangle of the
+ * content is shown.
* If the rectangle is of zero size i.e. x0 == x1 and y0 == y1
* the contents will be scrolled so the specified point in the
* content is at the top of the viewport.
@@ -268,10 +511,80 @@ static bool nsfltk_window_get_scroll(struct gui_window *gw, int *sx, int *sy)
* \param rect The rectangle to ensure is shown.
* \return NSERROR_OK on success or appropriate error code.
*/
-static nserror
-nsfltk_window_set_scroll(struct gui_window *gw, const struct rect *rect)
+nserror
+NS_Window::static_set_scroll(struct gui_window *gw, const struct rect *rect)
{
- return NSERROR_OK;
+ return gw->window->set_scroll(rect);
+}
+
+
+/**
+ * Set the navigation url.
+ *
+ * \param gw window to update.
+ * \param url The url to use as icon.
+ */
+nserror NS_Window::static_set_url(struct gui_window *gw, struct nsurl *url)
+{
+ return gw->window->m_nsurlbar->set_url(url);
+}
+
+
+/**
+ * Miscellaneous event occurred for a window
+ *
+ * This is used to inform the frontend of window events which
+ * require no additional parameters.
+ *
+ * \param gw The gui window the event occurred for
+ * \param event Which event has occurred.
+ * \return NSERROR_OK if the event was processed else error code.
+ */
+nserror
+NS_Window::static_event(struct gui_window *gw, enum gui_window_event event)
+{
+ nserror res;
+
+ switch (event) {
+ case GW_EVENT_UPDATE_EXTENT:
+ {
+ int w, h;
+
+ res = browser_window_get_extents(gw->window->m_bw, true, &w, &h);
+ if (res == NSERROR_OK) {
+ res = (gw->window)->set_extent(w, h);
+ }
+ break;
+ }
+ default:
+ res = NSERROR_OK;
+ break;
+ }
+ return res;
+}
+
+
+/**
+ * Invalidate an area of a window.
+ *
+ * The specified area of the window should now be considered
+ * out of date. If the area is NULL the entire window must be
+ * invalidated. It is expected that the windowing system will
+ * then subsequently cause redraw/expose operations as
+ * necessary.
+ *
+ * \note the frontend should not attempt to actually start the
+ * redraw operations as a result of this callback because the
+ * core redraw functions may already be threaded.
+ *
+ * \param gw The gui window to invalidate.
+ * \param rect area to redraw or NULL for the entire window area
+ * \return NSERROR_OK on success or appropriate error code
+ */
+nserror
+NS_Window::static_invalidate(struct gui_window *gw, const struct rect *rect)
+{
+ return gw->window->m_nswidget->invalidate(rect);
}
@@ -289,47 +602,80 @@ nsfltk_window_set_scroll(struct gui_window *gw, const struct rect *rect)
* \return NSERROR_OK on success and width and height updated
* else error code.
*/
-static nserror
-nsfltk_window_get_dimensions(struct gui_window *gw, int *width, int *height)
+nserror
+NS_Window::static_get_dimensions(struct gui_window *gw, int *width, int *height)
{
- NS_Widget *nswidget;
- nswidget = gw->window->get_nswidget();
-
- *width = nswidget->w();
- *height = nswidget->h();
-
- return NSERROR_OK;
+ return gw->window->m_nswidget->get_dimensions(width, height);
}
/**
- * Miscellaneous event occurred for a window
+ * Create and open a gui window for a browsing context.
*
- * This is used to inform the frontend of window events which
- * require no additional parameters.
+ * The implementing front end must create a context suitable
+ * for it to display a window referred to as the "gui window".
*
- * \param gw The gui window the event occurred for
- * \param event Which event has occurred.
- * \return NSERROR_OK if the event was processed else error code.
+ * The frontend will be expected to request the core redraw
+ * areas of the gui window which have become invalidated
+ * either from toolkit expose events or as a result of a
+ * invalidate() call.
+ *
+ * Most core operations used by the frontend concerning browser
+ * windows require passing the browser window context therefor
+ * the gui window must include a reference to the browser
+ * window passed here.
+ *
+ * If GW_CREATE_CLONE flag is set existing is non-NULL.
+ *
+ * \param bw The core browsing context associated with the gui window
+ * \param existing An existing gui_window, may be NULL.
+ * \param flags flags to control the gui window creation.
+ * \return gui window, or NULL on error.
*/
-static nserror
-nsfltk_window_event(struct gui_window *gw, enum gui_window_event event)
+struct gui_window *
+NS_Window::static_create(struct browser_window *bw,
+ struct gui_window *existing,
+ gui_window_create_flags flags)
{
- return NSERROR_OK;
+ struct gui_window *gw;
+ gw = (struct gui_window *)calloc(1, sizeof(struct gui_window));
+
+ if (gw != NULL) {
+ gw->window = new NS_Window(800,600, bw);
+
+ gw->window->show();
+ }
+
+ return gw;
}
+/**
+ * Destroy previously created gui window
+ *
+ * \param gw The gui window to destroy.
+ */
+void NS_Window::static_destroy(struct gui_window *gw)
+{
+ Fl::delete_widget(gw->window);
+ free(gw);
+}
+
+
+/**
+ * window operations table for fltk frontend
+ */
static struct gui_window_table window_table = {
- .create = nsfltk_window_create,
- .destroy = nsfltk_window_destroy,
- .invalidate = nsfltk_window_invalidate,
- .get_scroll = nsfltk_window_get_scroll,
- .set_scroll = nsfltk_window_set_scroll,
- .get_dimensions = nsfltk_window_get_dimensions,
- .event = nsfltk_window_event,
- .set_title = NULL,
- .set_url = NULL,
+ .create = NS_Window::static_create,
+ .destroy = NS_Window::static_destroy,
+ .invalidate = NS_Window::static_invalidate,
+ .get_scroll = NS_Window::static_get_scroll,
+ .set_scroll = NS_Window::static_set_scroll,
+ .get_dimensions = NS_Window::static_get_dimensions,
+ .event = NS_Window::static_event,
+ .set_title = NS_Window::static_set_title,
+ .set_url = NS_Window::static_set_url,
.set_icon = NULL,
- .set_status = NULL,
+ .set_status = NS_Window::static_set_status,
.set_pointer = NULL,
.place_caret = NULL,
.drag_start = NULL,
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=28ecbf82ed3024f51be...
commit 28ecbf82ed3024f51be4c87928fd91bacfc15cbc
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
Initial minimal FLTK toolkit implementation
diff --git a/frontends/Makefile.hts b/frontends/Makefile.hts
index b5af240..a78e34c 100644
--- a/frontends/Makefile.hts
+++ b/frontends/Makefile.hts
@@ -114,7 +114,7 @@ else
endif
# valid values for the TARGET
-VLDTARGET := amiga atari beos framebuffer gtk monkey riscos windows
+VLDTARGET := amiga atari beos fltk framebuffer gtk monkey riscos windows
# Check for valid TARGET
ifeq ($(filter $(VLDTARGET),$(TARGET)),)
diff --git a/frontends/fltk/Makefile b/frontends/fltk/Makefile
new file mode 100644
index 0000000..1cfb278
--- /dev/null
+++ b/frontends/fltk/Makefile
@@ -0,0 +1,35 @@
+#
+# Makefile for NetSurf ftlk target
+#
+# This file is part of NetSurf
+#
+# ----------------------------------------------------------------------------
+# FLTK flag setup (using pkg-config)
+# ----------------------------------------------------------------------------
+
+CXXFLAGS += -DFLTK_RESPATH=\"$(NETSURF_FLTK_RES_PATH)\"
+
+# fltk does not ship a pkg-config file, instead it has its own program
+
+FLTKCONFIG = fltk-config
+CXXFLAGS += $(shell $(FLTKCONFIG) --cxxflags)
+LDFLAGS += -lstdc++ $(shell $(FLTKCONFIG) --ldstaticflags)
+
+# ---------------------------------------------------------------------------
+# Target setup
+# ---------------------------------------------------------------------------
+
+# The binary target.
+EXETARGET := nsfltk
+
+# ----------------------------------------------------------------------------
+# Source file setup
+# ----------------------------------------------------------------------------
+
+# S_FRONTEND are sources purely for the FLTK frontend
+S_FRONTEND := main.cpp misc.cpp window.cpp fetch.cpp bitmap.cpp layout.cpp plotters.cpp resources.cpp
+
+# This is the final source build list
+# Note this is deliberately *not* expanded here as common and image
+# are not yet available
+SOURCES = $(S_COMMON) $(S_IMAGE) $(S_BROWSER) $(S_RESOURCE) $(S_FRONTEND)
diff --git a/frontends/fltk/Makefile.defaults b/frontends/fltk/Makefile.defaults
new file mode 100644
index 0000000..ad70fb0
--- /dev/null
+++ b/frontends/fltk/Makefile.defaults
@@ -0,0 +1,28 @@
+# ----------------------------------------------------------------------------
+# FLTK-specific options
+# ----------------------------------------------------------------------------
+
+# Where to search for NetSurf's resources after looking in ~/.netsurf and
+# $NETSURFRES. It must have a trailing /
+NETSURF_FLTK_RES_PATH := $(PREFIX)/share/netsurf/:./frontends/fltk/res/
+
+# Where to install the netsurf binary
+NETSURF_FLTK_BIN := $(PREFIX)/bin/
+
+# Enable NetSurf's use of librsvg in conjunction with Cairo to display SVGs
+# Valid options: YES, NO, AUTO
+NETSURF_USE_RSVG := NO
+
+# Enable NetSurf's use of libsvgtiny for displaying SVGs
+# Valid options: YES, NO, AUTO
+NETSURF_USE_NSSVG := NO
+
+# Enable NetSurf's use of librosprite for displaying RISC OS Sprites
+# Valid options: YES, NO, AUTO
+NETSURF_USE_ROSPRITE := NO
+
+# Enable building the source object cache filesystem based backing store.
+NETSURF_FS_BACKING_STORE := NO
+
+# Optimisation levels
+CFLAGS += -O2
diff --git a/frontends/fltk/Makefile.tools b/frontends/fltk/Makefile.tools
new file mode 100644
index 0000000..460a957
--- /dev/null
+++ b/frontends/fltk/Makefile.tools
@@ -0,0 +1,8 @@
+# -*- mode: makefile-gmake -*-
+##
+## tool setup for the fltk target
+##
+
+# use native package config
+PKG_CONFIG := pkg-config
+
diff --git a/frontends/fltk/bitmap.cpp b/frontends/fltk/bitmap.cpp
new file mode 100644
index 0000000..bc41822
--- /dev/null
+++ b/frontends/fltk/bitmap.cpp
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2021 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
+ * Implementation of netsurf bitmap for fltk.
+ */
+
+#include <stddef.h>
+
+extern "C" {
+
+#include "utils/errors.h"
+#include "netsurf/bitmap.h"
+
+}
+
+#include "fltk/bitmap.h"
+
+/**
+ * Create a new bitmap.
+ *
+ * \param width width of image in pixels
+ * \param height width of image in pixels
+ * \param state The state to create the bitmap in.
+ * \return A bitmap structure or NULL on error.
+ */
+static void *nsfltk_bitmap_create(int width, int height, unsigned int state)
+{
+ return NULL;
+}
+
+/**
+ * Destroy a bitmap.
+ *
+ * \param bitmap The bitmap to destroy.
+ */
+static void nsfltk_bitmap_destroy(void *bitmap)
+{
+}
+
+/**
+ * Set the opacity of a bitmap.
+ *
+ * \param bitmap The bitmap to set opacity on.
+ * \param opaque The bitmap opacity to set.
+ */
+static void nsfltk_bitmap_set_opaque(void *bitmap, bool opaque)
+{
+}
+
+/**
+ * Get the opacity of a bitmap.
+ *
+ * \param bitmap The bitmap to examine.
+ * \return The bitmap opacity.
+ */
+static bool nsfltk_bitmap_get_opaque(void *bitmap)
+{
+ return false;
+}
+
+/**
+ * Test if a bitmap is opaque.
+ *
+ * \param bitmap The bitmap to examine.
+ * \return The bitmap opacity.
+ */
+static bool nsfltk_bitmap_test_opaque(void *bitmap)
+{
+ return false;
+}
+
+/**
+ * Get the image buffer from a bitmap
+ *
+ * \param bitmap The bitmap to get the buffer from.
+ * \return The image buffer or NULL if there is none.
+ */
+static unsigned char *nsfltk_bitmap_get_buffer(void *bitmap)
+{
+ return NULL;
+}
+
+/**
+ * Get the number of bytes per row of the image
+ *
+ * \param bitmap The bitmap
+ * \return The number of bytes for a row of the bitmap.
+ */
+static size_t nsfltk_bitmap_get_rowstride(void *bitmap)
+{
+ return 0;
+}
+
+/**
+ * Get the bitmap width
+ *
+ * \param bitmap The bitmap
+ * \return The bitmap width in pixels.
+ */
+static int nsfltk_bitmap_get_width(void *bitmap)
+{
+ return 0;
+}
+
+/**
+ * Get the bitmap height
+ *
+ * \param bitmap The bitmap
+ * \return The bitmap height in pixels.
+ */
+static int nsfltk_bitmap_get_height(void *bitmap)
+{
+ return 0;
+}
+
+/**
+ * Get the *bytes* per pixel.
+ *
+ * \param bitmap The bitmap
+ */
+static size_t nsfltk_bitmap_get_bpp(void *bitmap)
+{
+ return 4;
+}
+
+/**
+ * Save a bitmap to disc.
+ *
+ * \param bitmap The bitmap to save
+ * \param path The path to save the bitmap to.
+ * \param flags Flags affecting the save.
+ */
+static bool nsfltk_bitmap_save(void *bitmap, const char *path, unsigned flags)
+{
+ return false;
+}
+
+/**
+ * Marks a bitmap as modified.
+ *
+ * \param bitmap The bitmap set as modified.
+ */
+static void nsfltk_bitmap_modified(void *bitmap)
+{
+}
+
+/**
+ * Render content into a bitmap.
+ *
+ * \param bitmap The bitmap to render into.
+ * \param content The content to render.
+ */
+static nserror
+nsfltk_bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content)
+{
+ return NSERROR_OK;
+}
+
+
+static struct gui_bitmap_table bitmap_table = {
+ .create = nsfltk_bitmap_create,
+ .destroy = nsfltk_bitmap_destroy,
+ .set_opaque = nsfltk_bitmap_set_opaque,
+ .get_opaque = nsfltk_bitmap_get_opaque,
+ .test_opaque = nsfltk_bitmap_test_opaque,
+ .get_buffer = nsfltk_bitmap_get_buffer,
+ .get_rowstride = nsfltk_bitmap_get_rowstride,
+ .get_width = nsfltk_bitmap_get_width,
+ .get_height = nsfltk_bitmap_get_height,
+ .get_bpp = nsfltk_bitmap_get_bpp,
+ .save = nsfltk_bitmap_save,
+ .modified = nsfltk_bitmap_modified,
+ .render = nsfltk_bitmap_render,
+};
+
+struct gui_bitmap_table *nsfltk_bitmap_table = &bitmap_table;
diff --git a/frontends/fltk/bitmap.h b/frontends/fltk/bitmap.h
new file mode 100644
index 0000000..e0f01a6
--- /dev/null
+++ b/frontends/fltk/bitmap.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2021 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/>.
+ */
+
+#ifndef NETSURF_FLTK_BITMAP_H
+#define NETSURF_FLTK_BITMAP_H 1
+
+/**
+ * fltk bitmap operations table
+ */
+extern struct gui_bitmap_table *nsfltk_bitmap_table;
+
+#endif
diff --git a/frontends/fltk/fetch.cpp b/frontends/fltk/fetch.cpp
new file mode 100644
index 0000000..39c15a6
--- /dev/null
+++ b/frontends/fltk/fetch.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2021 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
+ * Implementation of netsurf fetch for fltk.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <limits.h>
+
+extern "C" {
+
+#include "utils/errors.h"
+#include "utils/log.h"
+#include "utils/filepath.h"
+#include "utils/file.h"
+#include "netsurf/fetch.h"
+
+}
+
+#include "fltk/fetch.h"
+#include "fltk/resources.h"
+
+/**
+ * Determine the MIME type of a local file.
+ *
+ * @note used in file fetcher
+ *
+ * \param unix_path Unix style path to file on disk
+ * \return Pointer to MIME type string (should not be freed) -
+ * invalidated on next call to fetch_filetype.
+ */
+static const char *nsfltk_fetch_filetype(const char *unix_path)
+{
+ int l;
+ char * res = (char*)"text/html";
+ l = strlen(unix_path);
+ NSLOG(netsurf, INFO, "unix path: %s", unix_path);
+
+
+ if (2 < l && strcasecmp(unix_path + l - 3, "f79") == 0)
+ res = (char*)"text/css";
+ else if (2 < l && strcasecmp(unix_path + l - 3, "css") == 0)
+ res = (char*)"text/css";
+ else if (2 < l && strcasecmp(unix_path + l - 3, "jpg") == 0)
+ res = (char*)"image/jpeg";
+ else if (3 < l && strcasecmp(unix_path + l - 4, "jpeg") == 0)
+ res = (char*)"image/jpeg";
+ else if (2 < l && strcasecmp(unix_path + l - 3, "gif") == 0)
+ res = (char*)"image/gif";
+ else if (2 < l && strcasecmp(unix_path + l - 3, "png") == 0)
+ res = (char*)"image/png";
+ else if (2 < l && strcasecmp(unix_path + l - 3, "jng") == 0)
+ res = (char*)"image/jng";
+ else if (2 < l && strcasecmp(unix_path + l - 3, "svg") == 0)
+ res = (char*)"image/svg";
+ else if (2 < l && strcasecmp(unix_path + l - 3, "txt") == 0)
+ res = (char*)"text/plain";
+
+ NSLOG(netsurf, INFO, "mime type: %s", res);
+ return res;
+}
+
+/**
+ * Translate resource path to full url.
+ *
+ * @note Only used in resource protocol fetcher
+ *
+ * Transforms a resource protocol path into a full URL. The returned URL
+ * is used as the target for a redirect. The caller takes ownership of
+ * the returned nsurl including unrefing it when finished with it.
+ *
+ * \param path The path of the resource to locate.
+ * \return A netsurf url object containing the full URL of the resource path
+ * or NULL if a suitable resource URL can not be generated.
+ */
+static nsurl *nsfltk_get_resource_url(const char *path)
+{
+ char buf[PATH_MAX];
+ nsurl *url = NULL;
+
+ netsurf_path_to_nsurl(filepath_sfind(respaths, buf, path), &url);
+
+ return url;
+}
+
+static struct gui_fetch_table fetch_table = {
+ .filetype = nsfltk_fetch_filetype,
+
+ .get_resource_url = nsfltk_get_resource_url,
+ .get_resource_data = NULL,
+ .release_resource_data = NULL,
+ .mimetype = NULL,
+};
+
+struct gui_fetch_table *nsfltk_fetch_table = &fetch_table;
diff --git a/frontends/fltk/fetch.h b/frontends/fltk/fetch.h
new file mode 100644
index 0000000..6f9913e
--- /dev/null
+++ b/frontends/fltk/fetch.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2021 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/>.
+ */
+
+#ifndef NETSURF_FLTK_FETCH_H
+#define NETSURF_FLTK_FETCH_H 1
+
+/**
+ * fltk fetch operations table
+ */
+extern struct gui_fetch_table *nsfltk_fetch_table;
+
+#endif
diff --git a/frontends/fltk/layout.cpp b/frontends/fltk/layout.cpp
new file mode 100644
index 0000000..4504430
--- /dev/null
+++ b/frontends/fltk/layout.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2021 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
+ * Implementation of netsurf layout operations for fltk.
+ */
+
+#include <stddef.h>
+
+extern "C" {
+
+#include "utils/errors.h"
+#include "utils/utf8.h"
+#include "netsurf/layout.h"
+#include "netsurf/plot_style.h"
+
+}
+
+#include "fltk/layout.h"
+
+/**
+ * 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
+nsfltk_layout_width(const struct plot_font_style *fstyle,
+ const char *string,
+ size_t length,
+ int *width)
+{
+ *width = (fstyle->size * utf8_bounded_length(string, length)) / PLOT_STYLE_SCALE;
+ return NSERROR_OK;
+}
+
+
+/**
+ * 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
+nsfltk_layout_position(const struct plot_font_style *fstyle,
+ const char *string,
+ size_t length,
+ int x,
+ size_t *char_offset,
+ int *actual_x)
+{
+ *char_offset = x / (fstyle->size / PLOT_STYLE_SCALE);
+ if (*char_offset > length)
+ *char_offset = length;
+ *actual_x = *char_offset * (fstyle->size / PLOT_STYLE_SCALE);
+ return NSERROR_OK;
+}
+
+
+/**
+ * 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
+nsfltk_layout_split(const struct plot_font_style *fstyle,
+ const char *string,
+ size_t length,
+ int x,
+ size_t *char_offset,
+ int *actual_x)
+{
+ int c_off = *char_offset = x / (fstyle->size / PLOT_STYLE_SCALE);
+ if (*char_offset > length) {
+ *char_offset = length;
+ } else {
+ while (*char_offset > 0) {
+ if (string[*char_offset] == ' ')
+ break;
+ (*char_offset)--;
+ }
+ if (*char_offset == 0) {
+ *char_offset = c_off;
+ while (*char_offset < length && string[*char_offset] != ' ') {
+ (*char_offset)++;
+ }
+ }
+ }
+ *actual_x = *char_offset * (fstyle->size / PLOT_STYLE_SCALE);
+ return NSERROR_OK;
+}
+
+static struct gui_layout_table layout_table = {
+ .width = nsfltk_layout_width,
+ .position = nsfltk_layout_position,
+ .split = nsfltk_layout_split,
+};
+
+struct gui_layout_table *nsfltk_layout_table = &layout_table;
diff --git a/frontends/fltk/layout.h b/frontends/fltk/layout.h
new file mode 100644
index 0000000..5e19cc0
--- /dev/null
+++ b/frontends/fltk/layout.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2021 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/>.
+ */
+
+#ifndef NETSURF_FLTK_LAYOUT_H
+#define NETSURF_FLTK_LAYOUT_H 1
+
+/**
+ * fltk layout operations table
+ */
+extern struct gui_layout_table *nsfltk_layout_table;
+
+#endif
diff --git a/frontends/fltk/main.cpp b/frontends/fltk/main.cpp
new file mode 100644
index 0000000..ab0e1bc
--- /dev/null
+++ b/frontends/fltk/main.cpp
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2021 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/>.
+ */
+
+#include <assert.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <FL/Fl.H>
+
+extern "C" {
+
+#include "utils/utils.h"
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "utils/nsoption.h"
+#include "utils/nsurl.h"
+
+#include "netsurf/netsurf.h"
+#include "netsurf/content.h"
+#include "netsurf/browser_window.h"
+
+}
+
+#include "fltk/misc.h"
+#include "fltk/window.h"
+#include "fltk/fetch.h"
+#include "fltk/bitmap.h"
+#include "fltk/layout.h"
+#include "fltk/resources.h"
+
+bool nsfltk_done = false;
+
+/**
+ * Set option defaults for fltk frontend
+ *
+ * @param defaults The option table to update.
+ * @return error status.
+ */
+static nserror set_option_defaults(struct nsoption_s *defaults)
+{
+ return NSERROR_OK;
+}
+
+
+/**
+ * Ensures output logging stream is correctly configured
+ */
+static bool nslog_stream_configure(FILE *fptr)
+{
+ /* set log stream to be non-buffering */
+ setbuf(fptr, NULL);
+
+ return true;
+}
+
+
+/**
+ * fltk frontend specific initialisation
+ */
+static nserror nsfltk_init(int *pargc, char** argv)
+{
+ nserror res;
+
+ /* Prep the resource search paths */
+ res = nsfltk_init_resource_path("${HOME}/.netsurf/:${NETSURFRES}:" FLTK_RESPATH);
+ if (res != NSERROR_OK) {
+ fprintf(stderr, "Resources failed to initialise (%s)\n",
+ messages_get_errorcode(res));
+ return res;
+ }
+
+ /* Initialise logging. Not fatal if it fails but not much we
+ * can do about it either.
+ */
+ nslog_init(nslog_stream_configure, pargc, argv);
+
+ /* override loaded options with those from commandline */
+ nsoption_commandline(pargc, argv, nsoptions);
+
+ /* Initialise user options */
+ res = nsoption_init(set_option_defaults, &nsoptions, &nsoptions_default);
+ if (res != NSERROR_OK) {
+ fprintf(stderr, "Options failed to initialise (%s)\n",
+ messages_get_errorcode(res));
+ return res;
+ }
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * Start fltk browser.
+ *
+ * performs fltk specific startup including opening initial window if necessary
+ *
+ * \param argc The number of arguments on the command line
+ * \param argv A string vector of command line arguments.
+ */
+static nserror nsfltk_start(int argc, char** argv)
+{
+ char *addr = NULL;
+ nsurl *url;
+ nserror res;
+
+ /* If there is a url specified on the command line use it */
+ if (argc > 1) {
+ struct stat fs;
+ if (stat(argv[1], &fs) == 0) {
+ size_t addrlen;
+ char *rp = realpath(argv[1], NULL);
+ assert(rp != NULL);
+
+ /* calculate file url length including terminator */
+ addrlen = SLEN("file://") + strlen(rp) + 1;
+ addr = (char *)malloc(addrlen);
+ assert(addr != NULL);
+ snprintf(addr, addrlen, "file://%s", rp);
+ free(rp);
+ } else {
+ addr = strdup(argv[1]);
+ }
+ }
+ if (addr != NULL) {
+ /* managed to set up based on local launch */
+ } else if (nsoption_charp(homepage_url) != NULL) {
+ addr = strdup(nsoption_charp(homepage_url));
+ } else {
+ addr = strdup(NETSURF_HOMEPAGE);
+ }
+
+ /* create an initial browser window */
+ res = nsurl_create(addr, &url);
+ if (res == NSERROR_OK) {
+ res = browser_window_create(BW_CREATE_HISTORY,
+ url,
+ NULL,
+ NULL,
+ NULL);
+ nsurl_unref(url);
+ }
+
+ free(addr);
+
+ return res;
+}
+
+/**
+ * Run the fltk event loop.
+ *
+ */
+static void nsfltk_run(void)
+{
+ int schedtm;
+ do {
+ /* run scheduled callbacks and get the next event delta in ms */
+ schedtm = nsfltk_schedule_run();
+ Fl::wait(((double)schedtm/1000));
+ } while(nsfltk_done != true);
+}
+
+static nserror nsfltk_finalise(void)
+{
+ /* common finalisation */
+ netsurf_exit();
+
+ /* finalise options */
+ nsoption_finalise(nsoptions, nsoptions_default);
+
+ /* finalise logging */
+ nslog_finalise();
+
+ return NSERROR_OK;
+}
+
+/**
+ * Main entry point from OS.
+ */
+int main(int argc, char** argv)
+{
+ nserror res;
+ struct netsurf_table nsfltk_table = {
+ .misc = nsfltk_misc_table,
+ .window = nsfltk_window_table,
+ .download = NULL, /* no download functionality */
+ .clipboard = NULL, /* no clipboard functionality */
+ .fetch = nsfltk_fetch_table,
+ .file = NULL, /* use the posix default file operations */
+ .utf8 = NULL, /* use default utf-8 processing */
+ .search = NULL, /* use the default text search */
+ .search_web = NULL, /* use default web search */
+ .llcache = NULL, /* use default low level cache storage */
+ .bitmap = nsfltk_bitmap_table,
+ .layout = nsfltk_layout_table,
+ };
+
+ /* register operation tables */
+ res = netsurf_register(&nsfltk_table);
+ if (res != NSERROR_OK) {
+ fprintf(stderr,
+ "NetSurf operation table failed registration (%s)\n",
+ messages_get_errorcode(res));
+ return 1;
+ }
+
+ /* fltk specific initialisation */
+ res = nsfltk_init(&argc, argv);
+ if (res != NSERROR_OK) {
+ fprintf(stderr, "NetSurf fltk initialisation failed (%s)\n",
+ messages_get_errorcode(res));
+ return 2;
+ }
+
+ /* netsurf initialisation */
+ res = netsurf_init(NULL);
+ if (res != NSERROR_OK) {
+ fprintf(stderr, "NetSurf core failed to initialise (%s)\n",
+ messages_get_errorcode(res));
+ return 3;
+ }
+
+ /* fltk specific startup */
+ res = nsfltk_start(argc, argv);
+ if (res != NSERROR_OK) {
+ fprintf(stderr, "NetSurf fltk startup failed (%s)\n",
+ messages_get_errorcode(res));
+ nsfltk_finalise();
+ return 4;
+ }
+
+ /* startup suceeded so main run loop */
+ nsfltk_run();
+
+ /* finalise everything */
+ nsfltk_finalise();
+
+ return 0;
+
+}
diff --git a/frontends/fltk/misc.cpp b/frontends/fltk/misc.cpp
new file mode 100644
index 0000000..b86affd
--- /dev/null
+++ b/frontends/fltk/misc.cpp
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2021 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
+ * Implementation of netsurf miscelaneous operations for fltk.
+ */
+
+#include <stddef.h>
+#include <time.h>
+#include <stdlib.h>
+
+extern "C" {
+
+#include "utils/errors.h"
+#include "utils/sys_time.h"
+#include "utils/log.h"
+#include "netsurf/misc.h"
+
+}
+
+#include "fltk/misc.h"
+
+/* linked list of scheduled callbacks */
+static struct nscallback *schedule_list = NULL;
+
+/**
+ * scheduled callback.
+ */
+struct nscallback
+{
+ struct nscallback *next;
+ struct timeval tv;
+ void (*callback)(void *p);
+ void *p;
+};
+
+/* exported function documented in fltk/misc.h */
+int nsfltk_schedule_run(void)
+{
+ struct timeval tv;
+ struct timeval nexttime;
+ struct timeval rettime;
+ struct nscallback *cur_nscb;
+ struct nscallback *prev_nscb;
+ struct nscallback *unlnk_nscb;
+
+ if (schedule_list == NULL)
+ return -1;
+
+ /* reset enumeration to the start of the list */
+ cur_nscb = schedule_list;
+ prev_nscb = NULL;
+ nexttime = cur_nscb->tv;
+
+ gettimeofday(&tv, NULL);
+
+ while (cur_nscb != NULL) {
+ if (timercmp(&tv, &cur_nscb->tv, >)) {
+ /* scheduled time */
+
+ /* remove callback */
+ unlnk_nscb = cur_nscb;
+
+ if (prev_nscb == NULL) {
+ schedule_list = unlnk_nscb->next;
+ } else {
+ prev_nscb->next = unlnk_nscb->next;
+ }
+
+ unlnk_nscb->callback(unlnk_nscb->p);
+
+ free(unlnk_nscb);
+
+ /* need to deal with callback modifying the list. */
+ if (schedule_list == NULL)
+ return -1; /* no more callbacks scheduled */
+
+ /* reset enumeration to the start of the list */
+ cur_nscb = schedule_list;
+ prev_nscb = NULL;
+ nexttime = cur_nscb->tv;
+ } else {
+ /* if the time to the event is sooner than the
+ * currently recorded soonest event record it
+ */
+ if (timercmp(&nexttime, &cur_nscb->tv, >)) {
+ nexttime = cur_nscb->tv;
+ }
+ /* move to next element */
+ prev_nscb = cur_nscb;
+ cur_nscb = prev_nscb->next;
+ }
+ }
+
+ /* make rettime relative to now */
+ timersub(&nexttime, &tv, &rettime);
+
+ NSLOG(schedule, DEBUG, "returning time to next event as %ldms",
+ (long)((rettime.tv_sec * 1000) + (rettime.tv_usec / 1000)));
+
+ /* return next event time in milliseconds (24days max wait) */
+ return (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000);
+}
+
+/**
+ * Unschedule a callback.
+ *
+ * \param callback callback function
+ * \param p user parameter, passed to callback function
+ * \return NSERROR_OK if callback found and removed else NSERROR_NOT_FOUND
+ *
+ * All scheduled callbacks matching both callback and p are removed.
+ */
+static nserror schedule_remove(void (*callback)(void *p), void *p)
+{
+ struct nscallback *cur_nscb;
+ struct nscallback *prev_nscb;
+ struct nscallback *unlnk_nscb;
+ bool removed = false;
+
+ /* check there is something on the list to remove */
+ if (schedule_list == NULL) {
+ return NSERROR_NOT_FOUND;
+ }
+
+ NSLOG(schedule, DEBUG, "removing %p, %p", callback, p);
+
+ cur_nscb = schedule_list;
+ prev_nscb = NULL;
+
+ while (cur_nscb != NULL) {
+ if ((cur_nscb->callback == callback) &&
+ (cur_nscb->p == p)) {
+ /* item to remove */
+
+ NSLOG(schedule, DEBUG, "callback entry %p removing %p(%p)",
+ cur_nscb, cur_nscb->callback, cur_nscb->p);
+
+ /* remove callback */
+ unlnk_nscb = cur_nscb;
+ cur_nscb = unlnk_nscb->next;
+
+ if (prev_nscb == NULL) {
+ schedule_list = cur_nscb;
+ } else {
+ prev_nscb->next = cur_nscb;
+ }
+ free (unlnk_nscb);
+ removed = true;
+ } else {
+ /* move to next element */
+ prev_nscb = cur_nscb;
+ cur_nscb = prev_nscb->next;
+ }
+ }
+
+ if (removed == false) {
+ return NSERROR_NOT_FOUND;
+ }
+ return NSERROR_OK;
+}
+
+
+/**
+ * Schedule a callback.
+ *
+ * \param tival interval before the callback should be made in ms or
+ * negative value to remove any existing callback.
+ * \param callback callback function
+ * \param p user parameter passed to callback function
+ * \return NSERROR_OK on sucess or appropriate error on faliure
+ *
+ * The callback function will be called as soon as possible
+ * after the timeout has elapsed.
+ *
+ * Additional calls with the same callback and user parameter will
+ * reset the callback time to the newly specified value.
+ *
+ */
+static nserror nsfltk_schedule(int tival, void (*callback)(void *p), void *p)
+{
+ struct nscallback *nscb;
+ struct timeval tv;
+ nserror ret;
+
+ /* ensure uniqueness of the callback and context */
+ ret = schedule_remove(callback, p);
+ if (tival < 0) {
+ return ret;
+ }
+
+ NSLOG(schedule, DEBUG, "Adding %p(%p) in %d", callback, p, tival);
+
+ tv.tv_sec = tival / 1000; /* miliseconds to seconds */
+ tv.tv_usec = (tival % 1000) * 1000; /* remainder to microseconds */
+
+ nscb = (struct nscallback*)calloc(1, sizeof(struct nscallback));
+
+ gettimeofday(&nscb->tv, NULL);
+ timeradd(&nscb->tv, &tv, &nscb->tv);
+
+ nscb->callback = callback;
+ nscb->p = p;
+
+ /* add to list front */
+ nscb->next = schedule_list;
+ schedule_list = nscb;
+
+ return NSERROR_OK;
+}
+
+static struct gui_misc_table misc_table = {
+ .schedule = nsfltk_schedule,
+ .quit = NULL,
+ .launch_url = NULL,
+ .login = NULL,
+ .pdf_password = NULL,
+ .present_cookies = NULL,
+};
+
+struct gui_misc_table *nsfltk_misc_table = &misc_table;
diff --git a/frontends/fltk/misc.h b/frontends/fltk/misc.h
new file mode 100644
index 0000000..e088043
--- /dev/null
+++ b/frontends/fltk/misc.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021 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/>.
+ */
+
+#ifndef NETSURF_FLTK_MISC_H
+#define NETSURF_FLTK_MISC_H 1
+
+/**
+ * fltk miscellaneous (scheduling) operations table
+ */
+extern struct gui_misc_table *nsfltk_misc_table;
+
+/**
+ * run and pending scheduling callbacks
+ *
+ * \return number of miliseconds before next scheduled event
+ */
+int nsfltk_schedule_run(void);
+
+#endif
diff --git a/frontends/fltk/plotters.cpp b/frontends/fltk/plotters.cpp
new file mode 100644
index 0000000..65268f1
--- /dev/null
+++ b/frontends/fltk/plotters.cpp
@@ -0,0 +1,300 @@
+/*
+ * Copyright 2021 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
+ * Implementation of plotters for fltk.
+ */
+
+#include <stddef.h>
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+
+extern "C" {
+
+#include "utils/errors.h"
+#include "netsurf/types.h"
+#include "netsurf/mouse.h"
+#include "netsurf/window.h"
+#include "netsurf/plotters.h"
+
+}
+
+#include "fltk/window.h"
+#include "fltk/plotters.h"
+
+
+static inline void nsfltk_set_colour(colour c)
+{
+ fl_color(fl_rgb_color((c & 0xff),
+ ((c & 0xff00) >> 8),
+ ((c & 0xff0000) >> 16)));
+}
+
+
+/**
+ * \brief Sets a clip rectangle for subsequent plot operations.
+ *
+ * \param ctx The current redraw context.
+ * \param clip The rectangle to limit all subsequent plot
+ * operations within.
+ * \return NSERROR_OK on success else error code.
+ */
+static nserror
+nsfltk_plot_clip(const struct redraw_context *ctx, const struct rect *clip)
+{
+ return NSERROR_OK;
+}
+
+
+/**
+ * Plots an arc
+ *
+ * plot an arc segment around (x,y), anticlockwise from angle1
+ * to angle2. Angles are measured anticlockwise from
+ * horizontal, in degrees.
+ *
+ * \param ctx The current redraw context.
+ * \param style Style controlling the arc plot.
+ * \param x The x coordinate of the arc.
+ * \param y The y coordinate of the arc.
+ * \param radius The radius of the arc.
+ * \param angle1 The start angle of the arc.
+ * \param angle2 The finish angle of the arc.
+ * \return NSERROR_OK on success else error code.
+ */
+static nserror
+nsfltk_plot_arc(const struct redraw_context *ctx,
+ const plot_style_t *style,
+ int x, int y, int radius, int angle1, int angle2)
+{
+ return NSERROR_OK;
+}
+
+
+/**
+ * Plots a circle
+ *
+ * Plot a circle centered on (x,y), which is optionally filled.
+ *
+ * \param ctx The current redraw context.
+ * \param style Style controlling the circle plot.
+ * \param x x coordinate of circle centre.
+ * \param y y coordinate of circle centre.
+ * \param radius circle radius.
+ * \return NSERROR_OK on success else error code.
+ */
+static nserror
+nsfltk_plot_disc(const struct redraw_context *ctx,
+ const plot_style_t *style,
+ int x, int y, int radius)
+{
+ return NSERROR_OK;
+}
+
+
+/**
+ * Plots a line
+ *
+ * plot a line from (x0,y0) to (x1,y1). Coordinates are at
+ * centre of line width/thickness.
+ *
+ * \param ctx The current redraw context.
+ * \param style Style controlling the line plot.
+ * \param line A rectangle defining the line to be drawn
+ * \return NSERROR_OK on success else error code.
+ */
+static nserror
+nsfltk_plot_line(const struct redraw_context *ctx,
+ const plot_style_t *style,
+ const struct rect *line)
+{
+ if (style->stroke_type != PLOT_OP_TYPE_NONE) {
+ nsfltk_set_colour(style->stroke_colour);
+ fl_line(line->x0, line->y0, line->x1, line->y1);
+ }
+ return NSERROR_OK;
+}
+
+
+/**
+ * Plots a rectangle.
+ *
+ * The rectangle can be filled an outline or both controlled
+ * by the plot style The line can be solid, dotted or
+ * dashed. Top left corner at (x0,y0) and rectangle has given
+ * width and height.
+ *
+ * \param ctx The current redraw context.
+ * \param style Style controlling the rectangle plot.
+ * \param rect A rectangle defining the line to be drawn
+ * \return NSERROR_OK on success else error code.
+ */
+static nserror
+nsfltk_plot_rectangle(const struct redraw_context *ctx,
+ const plot_style_t *style,
+ const struct rect *rect)
+{
+ if (style->fill_type != PLOT_OP_TYPE_NONE) {
+ nsfltk_set_colour(style->fill_colour);
+ fl_rectf(rect->x0,
+ rect->y0,
+ rect->x1 - rect->x0,
+ rect->y1 - rect->y0);
+ }
+
+ if (style->stroke_type != PLOT_OP_TYPE_NONE) {
+ nsfltk_set_colour(style->stroke_colour);
+ fl_rect(rect->x0,
+ rect->y0,
+ rect->x1 - rect->x0,
+ rect->y1 - rect->y0);
+ }
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * Plot a polygon
+ *
+ * Plots a filled polygon with straight lines between
+ * points. The lines around the edge of the ploygon are not
+ * plotted. The polygon is filled with the non-zero winding
+ * rule.
+ *
+ * \param ctx The current redraw context.
+ * \param style Style controlling the polygon plot.
+ * \param p verticies of polygon
+ * \param n number of verticies.
+ * \return NSERROR_OK on success else error code.
+ */
+static nserror
+nsfltk_plot_polygon(const struct redraw_context *ctx,
+ const plot_style_t *style,
+ const int *p,
+ unsigned int n)
+{
+ return NSERROR_OK;
+}
+
+
+/**
+ * Plots a path.
+ *
+ * Path plot consisting of cubic Bezier curves. Line and fill colour is
+ * controlled by the plot style.
+ *
+ * \param ctx The current redraw context.
+ * \param pstyle Style controlling the path plot.
+ * \param p elements of path
+ * \param n nunber of elements on path
+ * \param transform A transform to apply to the path.
+ * \return NSERROR_OK on success else error code.
+ */
+static nserror
+nsfltk_plot_path(const struct redraw_context *ctx,
+ const plot_style_t *pstyle,
+ const float *p,
+ unsigned int n,
+ const float transform[6])
+{
+ return NSERROR_OK;
+}
+
+
+/**
+ * Plot a bitmap
+ *
+ * Tiled plot of a bitmap image. (x,y) gives the top left
+ * coordinate of an explicitly placed tile. From this tile the
+ * image can repeat in all four directions -- up, down, left
+ * and right -- to the extents given by the current clip
+ * rectangle.
+ *
+ * The bitmap_flags say whether to tile in the x and y
+ * directions. If not tiling in x or y directions, the single
+ * image is plotted. The width and height give the dimensions
+ * the image is to be scaled to.
+ *
+ * \param ctx The current redraw context.
+ * \param bitmap The bitmap to plot
+ * \param x The x coordinate to plot the bitmap
+ * \param y The y coordiante to plot the bitmap
+ * \param width The width of area to plot the bitmap into
+ * \param height The height of area to plot the bitmap into
+ * \param bg the background colour to alpha blend into
+ * \param flags the flags controlling the type of plot operation
+ * \return NSERROR_OK on success else error code.
+ */
+static nserror
+nsfltk_plot_bitmap(const struct redraw_context *ctx,
+ struct bitmap *bitmap,
+ int x, int y,
+ int width,
+ int height,
+ colour bg,
+ bitmap_flags_t flags)
+{
+ return NSERROR_OK;
+}
+
+
+/**
+ * Text plotting.
+ *
+ * \param ctx The current redraw context.
+ * \param fstyle plot style for this text
+ * \param x x coordinate
+ * \param y y coordinate
+ * \param text UTF-8 string to plot
+ * \param length length of string, in bytes
+ * \return NSERROR_OK on success else error code.
+ */
+static nserror
+nsfltk_plot_text(const struct redraw_context *ctx,
+ const struct plot_font_style *fstyle,
+ int x,
+ int y,
+ const char *text,
+ size_t length)
+{
+ nsfltk_set_colour(fstyle->foreground);
+ fl_draw(text,length,x,y);
+ return NSERROR_OK;
+}
+
+
+/**
+ * FLTK plotter table
+ */
+const struct plotter_table nsfltk_plotters = {
+ .clip = nsfltk_plot_clip,
+ .arc = nsfltk_plot_arc,
+ .disc = nsfltk_plot_disc,
+ .line = nsfltk_plot_line,
+ .rectangle = nsfltk_plot_rectangle,
+ .polygon = nsfltk_plot_polygon,
+ .path = nsfltk_plot_path,
+ .bitmap = nsfltk_plot_bitmap,
+ .text = nsfltk_plot_text,
+ .group_start = NULL,
+ .group_end = NULL,
+ .flush = NULL,
+ .option_knockout = true
+};
diff --git a/frontends/fltk/plotters.h b/frontends/fltk/plotters.h
new file mode 100644
index 0000000..f0c8df9
--- /dev/null
+++ b/frontends/fltk/plotters.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2021 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
+ * Target independent plotting FLGTK+ interface.
+ */
+
+#ifndef NETSURF_FLTK_PLOTTERS_H
+#define NETSURF_FLTK_PLOTTERS_H 1
+
+struct plotter_table;
+
+extern const struct plotter_table nsfltk_plotters;
+
+#endif /* NETSURF_FLTK_PLOTTERS_H */
+
diff --git a/frontends/fltk/res/adblock.css b/frontends/fltk/res/adblock.css
new file mode 120000
index 0000000..0d12aaa
--- /dev/null
+++ b/frontends/fltk/res/adblock.css
@@ -0,0 +1 @@
+../../../resources/adblock.css
\ No newline at end of file
diff --git a/frontends/fltk/res/default.css b/frontends/fltk/res/default.css
new file mode 120000
index 0000000..fa3ae6c
--- /dev/null
+++ b/frontends/fltk/res/default.css
@@ -0,0 +1 @@
+../../../resources/default.css
\ No newline at end of file
diff --git a/frontends/fltk/res/en/credits.html b/frontends/fltk/res/en/credits.html
new file mode 120000
index 0000000..f73ecd4
--- /dev/null
+++ b/frontends/fltk/res/en/credits.html
@@ -0,0 +1 @@
+../../../../resources/en/credits.html
\ No newline at end of file
diff --git a/frontends/fltk/res/en/licence.html b/frontends/fltk/res/en/licence.html
new file mode 120000
index 0000000..0c3b430
--- /dev/null
+++ b/frontends/fltk/res/en/licence.html
@@ -0,0 +1 @@
+../../../../resources/en/licence.html
\ No newline at end of file
diff --git a/frontends/fltk/res/en/welcome.html b/frontends/fltk/res/en/welcome.html
new file mode 120000
index 0000000..543f31d
--- /dev/null
+++ b/frontends/fltk/res/en/welcome.html
@@ -0,0 +1 @@
+../../../../resources/en/welcome.html
\ No newline at end of file
diff --git a/frontends/fltk/res/internal.css b/frontends/fltk/res/internal.css
new file mode 120000
index 0000000..5583a98
--- /dev/null
+++ b/frontends/fltk/res/internal.css
@@ -0,0 +1 @@
+../../../resources/internal.css
\ No newline at end of file
diff --git a/frontends/fltk/res/netsurf.png b/frontends/fltk/res/netsurf.png
new file mode 120000
index 0000000..d0ab72a
--- /dev/null
+++ b/frontends/fltk/res/netsurf.png
@@ -0,0 +1 @@
+../../../resources/netsurf.png
\ No newline at end of file
diff --git a/frontends/fltk/res/quirks.css b/frontends/fltk/res/quirks.css
new file mode 120000
index 0000000..1e752cb
--- /dev/null
+++ b/frontends/fltk/res/quirks.css
@@ -0,0 +1 @@
+../../../resources/quirks.css
\ No newline at end of file
diff --git a/frontends/fltk/resources.cpp b/frontends/fltk/resources.cpp
new file mode 100644
index 0000000..78925eb
--- /dev/null
+++ b/frontends/fltk/resources.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2021 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/>.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+extern "C" {
+
+#include "utils/errors.h"
+#include "utils/filepath.h"
+
+}
+
+#include "fltk/resources.h"
+
+/** resource search path vector */
+char **respaths;
+
+/** maximum number of languages in language vector */
+#define LANGV_SIZE 32
+/** maximum length of all strings in language vector */
+#define LANGS_SIZE 4096
+
+/**
+ * obtain language from environment
+ *
+ * start with GNU extension LANGUAGE environment variable and then try
+ * POSIX variables LC_ALL, LC_MESSAGES and LANG
+ *
+ */
+static const char *get_language(void)
+{
+ const char *lang;
+
+ lang = getenv("LANGUAGE");
+ if ((lang != NULL) && (lang[0] != '\0')) {
+ return lang;
+ }
+
+ lang = getenv("LC_ALL");
+ if ((lang != NULL) && (lang[0] != '\0')) {
+ return lang;
+ }
+
+ lang = getenv("LC_MESSAGES");
+ if ((lang != NULL) && (lang[0] != '\0')) {
+ return lang;
+ }
+
+ lang = getenv("LANG");
+ if ((lang != NULL) && (lang[0] != '\0')) {
+ return lang;
+ }
+
+ return NULL;
+}
+
+
+/** provide a string vector of languages in preference order
+ *
+ * environment variables are processed to aquire a colon separated
+ * list of languages which are converted into a string vector. The
+ * vector will always have the C language as its last entry.
+ *
+ * This implementation creates an internal static representation of
+ * the vector when first called and returns that for all subsequent
+ * calls. i.e. changing the environment does not change the returned
+ * vector on repeated calls.
+ *
+ * If the environment variables have more than LANGV_SIZE languages or
+ * LANGS_SIZE bytes of data the results list will be curtailed.
+ */
+static const char * const *get_languagev(void)
+{
+ static const char *langv[LANGV_SIZE];
+ int langidx = 0; /* index of next entry in vector */
+ static char langs[LANGS_SIZE];
+ char *curp; /* next language parameter in langs string */
+ const char *lange; /* language from environment variable */
+ int lang_len;
+ char *cln; /* colon in lange */
+
+ /* return cached vector */
+ if (langv[0] != NULL) {
+ return &langv[0];
+ }
+
+ curp = &langs[0];
+
+ lange = get_language();
+
+ if (lange != NULL) {
+ lang_len = strlen(lange) + 1;
+ if (lang_len < (LANGS_SIZE - 2)) {
+ memcpy(curp, lange, lang_len);
+ while ((curp[0] != 0) &&
+ (langidx < (LANGV_SIZE - 2))) {
+ /* avoid using strchrnul as it is not portable */
+ cln = strchr(curp, ':');
+ if (cln == NULL) {
+ langv[langidx++] = curp;
+ curp += lang_len;
+ break;
+ } else {
+ if ((cln - curp) > 1) {
+ /* only place non empty entries in vector */
+ langv[langidx++] = curp;
+ }
+ *cln++ = 0; /* null terminate */
+ lang_len -= (cln - curp);
+ curp = cln;
+ }
+ }
+ }
+ }
+
+ /* ensure C language is present */
+ langv[langidx++] = curp;
+ *curp++ = 'C';
+ *curp++ = 0;
+ langv[langidx] = NULL;
+
+ return &langv[0];
+}
+
+
+/* exported interface documented in fltk/resources.h */
+nserror nsfltk_init_resource_path(const char *resource_path)
+{
+ const char * const *langv;
+ char **pathv; /* resource path string vector */
+
+ pathv = filepath_path_to_strvec(resource_path);
+
+ langv = get_languagev();
+
+ respaths = filepath_generate(pathv, langv);
+
+ filepath_free_strvec(pathv);
+
+ return NSERROR_OK;
+}
diff --git a/frontends/fltk/resources.h b/frontends/fltk/resources.h
new file mode 100644
index 0000000..849179b
--- /dev/null
+++ b/frontends/fltk/resources.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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/>.
+ */
+
+#ifndef NETSURF_FLTK_RESOURCES_H
+#define NETSURF_FLTK_RESOURCES_H 1
+
+/**
+ * resource search path vector
+ */
+extern char **respaths;
+
+/**
+ * Create an array of valid paths to search for resources.
+ *
+ * The idea is that all the complex path computation to find resources
+ * is performed here, once, rather than every time a resource is
+ * searched for.
+ *
+ * \param resource_path A shell style colon separated path list
+
+ * \return NSERROR_OK on success and the respaths set to a string
+ * vector of valid paths where resources can be found or appropriate
+ * error code on faliure.
+ */
+nserror nsfltk_init_resource_path(const char *resource_path);
+
+#endif
diff --git a/frontends/fltk/window.cpp b/frontends/fltk/window.cpp
new file mode 100644
index 0000000..19aa265
--- /dev/null
+++ b/frontends/fltk/window.cpp
@@ -0,0 +1,344 @@
+/*
+ * Copyright 2021 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
+ * Implementation of netsurf window (widget) for fltk.
+ */
+
+#include <stddef.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Double_Window.H>
+#include <FL/fl_draw.H>
+
+extern "C" {
+
+#include "utils/errors.h"
+#include "netsurf/types.h"
+#include "netsurf/mouse.h"
+#include "netsurf/window.h"
+#include "netsurf/plotters.h"
+#include "netsurf/content.h"
+#include "netsurf/browser_window.h"
+#include "netsurf/mouse.h"
+
+}
+
+#include "fltk/window.h"
+#include "fltk/plotters.h"
+
+extern bool nsfltk_done;
+
+class NS_Widget : public Fl_Widget
+{
+private:
+ struct browser_window *mbw;
+
+protected:
+ void draw();
+ int handle(int event);
+
+public:
+ NS_Widget(int X,int Y,int W,int H, struct browser_window *bw)
+ : Fl_Widget(X,Y,W,H), mbw(bw) {}
+};
+
+
+class NS_Window : public Fl_Double_Window
+{
+private:
+ struct browser_window *mbw;
+ NS_Widget *mnswidget;
+
+ void close_callback(Fl_Widget *w);
+ static void static_close_callback(Fl_Widget *w, void *f) { ((NS_Window *)f)->close_callback(w); }
+
+public:
+ NS_Window(int W, int H, struct browser_window *bw)
+ : Fl_Double_Window(W,H), mbw(bw) {
+ this->callback(static_close_callback, (void *)this);
+ mnswidget = new NS_Widget(0, 0, W, H, bw);
+ this->end();
+ }
+ ~NS_Window() { nsfltk_done=true; }
+
+ NS_Widget *get_nswidget() { return mnswidget; }
+};
+
+struct gui_window {
+ struct browser_window *bw;
+ NS_Window *window;
+};
+
+/**
+ * method to handle events on the netsurf browsing widget
+ */
+int NS_Widget::handle(int event)
+{
+ int state = BROWSER_MOUSE_HOVER;
+ int button;
+
+ switch (event) {
+ case FL_PUSH:
+ button = Fl::event_button();
+ if (button == FL_LEFT_MOUSE) {
+ state |= BROWSER_MOUSE_PRESS_1;
+ }
+ browser_window_mouse_click(mbw,
+ (browser_mouse_state)state,
+ Fl::event_x() - x(),
+ Fl::event_y() - y());
+ return 1;
+
+ case FL_RELEASE:
+ button = Fl::event_button();
+ if (button == FL_LEFT_MOUSE) {
+ state |= BROWSER_MOUSE_CLICK_1;
+
+ }
+ browser_window_mouse_click(mbw,
+ (browser_mouse_state)state,
+ Fl::event_x() - x(),
+ Fl::event_y() - y());
+
+ return 1;
+ default:
+ return Fl_Widget::handle(event);
+ }
+}
+
+
+/**
+ * method to redraw the netsurf browsing widget
+ */
+void NS_Widget::draw()
+{
+ struct rect clip;
+ fl_clip_box(x(), y(), w(), h(), clip.x0, clip.y0, clip.x1, clip.y1);
+ /* clip box generates width/height so convert to absolute */
+ clip.x1 += clip.x0;
+ clip.y1 += clip.y0;
+ struct redraw_context ctx = {
+ .interactive = true,
+ .background_images = true,
+ .plot = &nsfltk_plotters,
+ .priv = NULL,
+ };
+
+ browser_window_redraw(mbw, x(), y(), &clip, &ctx);
+
+}
+
+/**
+ * callback when fltk window is closed
+ */
+void NS_Window::close_callback(Fl_Widget *w)
+{
+ browser_window_destroy(mbw);
+}
+
+/**
+ * Create and open a gui window for a browsing context.
+ *
+ * The implementing front end must create a context suitable
+ * for it to display a window referred to as the "gui window".
+ *
+ * The frontend will be expected to request the core redraw
+ * areas of the gui window which have become invalidated
+ * either from toolkit expose events or as a result of a
+ * invalidate() call.
+ *
+ * Most core operations used by the frontend concerning browser
+ * windows require passing the browser window context therefor
+ * the gui window must include a reference to the browser
+ * window passed here.
+ *
+ * If GW_CREATE_CLONE flag is set existing is non-NULL.
+ *
+ * \param bw The core browsing context associated with the gui window
+ * \param existing An existing gui_window, may be NULL.
+ * \param flags flags to control the gui window creation.
+ * \return gui window, or NULL on error.
+ */
+static struct gui_window *
+nsfltk_window_create(struct browser_window *bw,
+ struct gui_window *existing,
+ gui_window_create_flags flags)
+{
+ struct gui_window *gw;
+ gw = (struct gui_window *)calloc(1, sizeof(struct gui_window));
+
+ gw->window = new NS_Window(800,600, bw);
+
+ gw->window->show();
+
+ return gw;
+}
+
+/**
+ * Destroy previously created gui window
+ *
+ * \param gw The gui window to destroy.
+ */
+static void nsfltk_window_destroy(struct gui_window *gw)
+{
+ Fl::delete_widget(gw->window);
+ free(gw);
+}
+
+
+/**
+ * Invalidate an area of a window.
+ *
+ * The specified area of the window should now be considered
+ * out of date. If the area is NULL the entire window must be
+ * invalidated. It is expected that the windowing system will
+ * then subsequently cause redraw/expose operations as
+ * necessary.
+ *
+ * \note the frontend should not attempt to actually start the
+ * redraw operations as a result of this callback because the
+ * core redraw functions may already be threaded.
+ *
+ * \param gw The gui window to invalidate.
+ * \param rect area to redraw or NULL for the entire window area
+ * \return NSERROR_OK on success or appropriate error code
+ */
+static nserror
+nsfltk_window_invalidate(struct gui_window *gw, const struct rect *rect)
+{
+ NS_Widget *nswidget;
+ nswidget = gw->window->get_nswidget();
+
+ if (rect == NULL) {
+ nswidget->damage(FL_DAMAGE_ALL);
+ } else {
+ nswidget->damage(FL_DAMAGE_ALL,
+ rect->x0,
+ rect->y0,
+ rect->x1 - rect->x0,
+ rect->y1 - rect->y0);
+ }
+ return NSERROR_OK;
+}
+
+
+/**
+ * Get the scroll position of a browser window.
+ *
+ * \param gw The gui window to obtain the scroll position from.
+ * \param sx receives x ordinate of point at top-left of window
+ * \param sy receives y ordinate of point at top-left of window
+ * \return true iff successful
+ */
+static bool nsfltk_window_get_scroll(struct gui_window *gw, int *sx, int *sy)
+{
+ return false;
+}
+
+
+/**
+ * Set the scroll position of a browser window.
+ *
+ * scrolls the viewport to ensure the specified rectangle of
+ * the content is shown.
+ * If the rectangle is of zero size i.e. x0 == x1 and y0 == y1
+ * the contents will be scrolled so the specified point in the
+ * content is at the top of the viewport.
+ * If the size of the rectangle is non zero the frontend may
+ * add padding or centre the defined area or it may simply
+ * align as in the zero size rectangle
+ *
+ * \param gw The gui window to scroll.
+ * \param rect The rectangle to ensure is shown.
+ * \return NSERROR_OK on success or appropriate error code.
+ */
+static nserror
+nsfltk_window_set_scroll(struct gui_window *gw, const struct rect *rect)
+{
+ return NSERROR_OK;
+}
+
+
+/**
+ * Find the current dimensions of a browser window's content area.
+ *
+ * This is used to determine the actual available drawing size
+ * in pixels. This allows contents that can be dynamically
+ * reformatted, such as HTML, to better use the available
+ * space.
+ *
+ * \param gw The gui window to measure content area of.
+ * \param width receives width of window
+ * \param height receives height of window
+ * \return NSERROR_OK on success and width and height updated
+ * else error code.
+ */
+static nserror
+nsfltk_window_get_dimensions(struct gui_window *gw, int *width, int *height)
+{
+ NS_Widget *nswidget;
+ nswidget = gw->window->get_nswidget();
+
+ *width = nswidget->w();
+ *height = nswidget->h();
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * Miscellaneous event occurred for a window
+ *
+ * This is used to inform the frontend of window events which
+ * require no additional parameters.
+ *
+ * \param gw The gui window the event occurred for
+ * \param event Which event has occurred.
+ * \return NSERROR_OK if the event was processed else error code.
+ */
+static nserror
+nsfltk_window_event(struct gui_window *gw, enum gui_window_event event)
+{
+ return NSERROR_OK;
+}
+
+static struct gui_window_table window_table = {
+ .create = nsfltk_window_create,
+ .destroy = nsfltk_window_destroy,
+ .invalidate = nsfltk_window_invalidate,
+ .get_scroll = nsfltk_window_get_scroll,
+ .set_scroll = nsfltk_window_set_scroll,
+ .get_dimensions = nsfltk_window_get_dimensions,
+ .event = nsfltk_window_event,
+ .set_title = NULL,
+ .set_url = NULL,
+ .set_icon = NULL,
+ .set_status = NULL,
+ .set_pointer = NULL,
+ .place_caret = NULL,
+ .drag_start = NULL,
+ .save_link = NULL,
+ .create_form_select_menu = NULL,
+ .file_gadget_open = NULL,
+ .drag_save_object = NULL,
+ .drag_save_selection = NULL,
+ .console_log = NULL,
+};
+
+struct gui_window_table *nsfltk_window_table = &window_table;
diff --git a/frontends/fltk/window.h b/frontends/fltk/window.h
new file mode 100644
index 0000000..c339418
--- /dev/null
+++ b/frontends/fltk/window.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2021 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/>.
+ */
+
+#ifndef NETSURF_FLTK_WINDOW_H
+#define NETSURF_FLTK_WINDOW_H 1
+
+/**
+ * fltk window (browser widget) operations table
+ */
+extern struct gui_window_table *nsfltk_window_table;
+
+#endif
-----------------------------------------------------------------------
Summary of changes:
Makefile.macros | 2 +-
desktop/browser_history.c | 11 +-
desktop/browser_history.h | 11 -
desktop/local_history.c | 1 +
.../textplain.h => desktop/local_history_private.h | 23 +-
docs/development.md | 6 +
docs/implementing-new-frontend.md | 352 +++++++++++
frontends/fltk/main.cpp | 3 -
frontends/fltk/window.cpp | 618 +++++++++++++++-----
9 files changed, 858 insertions(+), 169 deletions(-)
copy content/handlers/text/textplain.h => desktop/local_history_private.h (57%)
create mode 100644 docs/implementing-new-frontend.md
diff --git a/Makefile.macros b/Makefile.macros
index d8468b4..9421acf 100644
--- a/Makefile.macros
+++ b/Makefile.macros
@@ -207,7 +207,7 @@ $$(OBJROOT)/$(2): $(1) $$(OBJROOT)/created $$(DEPROOT)/created
$$(Q)$$(RM) $$(DEPROOT)/$(3)
$$(Q)$$(RM) $$(OBJROOT)/$(2)
$$(Q)$$(CC) $$(COMMON_WARNFLAGS) $$(CWARNFLAGS) $$(IFLAGS) $$(CFLAGS) $(CFLAGS_ENV) \
- -MMD -MT '$$(DEPROOT)/$(3) $$(OBJROOT)/$(2)' \
+ -MMD -MP -MT '$$(DEPROOT)/$(3) $$(OBJROOT)/$(2)' \
-MF $$(DEPROOT)/$(3) -o $$(OBJROOT)/$(2) -c $(1)
endef
diff --git a/desktop/browser_history.c b/desktop/browser_history.c
index 5b44670..2fbc80f 100644
--- a/desktop/browser_history.c
+++ b/desktop/browser_history.c
@@ -41,6 +41,7 @@
#include "desktop/gui_internal.h"
#include "desktop/browser_private.h"
+#include "desktop/local_history_private.h"
#include "desktop/browser_history.h"
/**
@@ -434,9 +435,7 @@ nserror browser_window_history_update(struct browser_window *bw,
history = bw->history;
- if (!history ||
- !history->current ||
- !history->current->page.bitmap) {
+ if ((history == NULL) || (history->current == NULL)) {
return NSERROR_INVALID;
}
@@ -455,7 +454,7 @@ nserror browser_window_history_update(struct browser_window *bw,
guit->bitmap->render(history->current->page.bitmap, content);
}
- if (bw->window != NULL &&
+ if ((bw->window != NULL) &&
guit->window->get_scroll(bw->window, &sx, &sy)) {
int content_height = content_get_height(content);
int content_width = content_get_width(content);
@@ -489,9 +488,7 @@ browser_window_history_get_scroll(struct browser_window *bw,
history = bw->history;
- if (!history ||
- !history->current ||
- !history->current->page.bitmap) {
+ if ((history== NULL) || (history->current == NULL)) {
return NSERROR_INVALID;
}
diff --git a/desktop/browser_history.h b/desktop/browser_history.h
index 06041eb..9b6f1fd 100644
--- a/desktop/browser_history.h
+++ b/desktop/browser_history.h
@@ -35,17 +35,6 @@
#include "utils/errors.h"
-#include "content/handlers/css/utils.h"
-
-#define LOCAL_HISTORY_WIDTH \
- (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(116))))
-#define LOCAL_HISTORY_HEIGHT \
- (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(100))))
-#define LOCAL_HISTORY_RIGHT_MARGIN \
- (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(50))))
-#define LOCAL_HISTORY_BOTTOM_MARGIN \
- (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(30))))
-
struct browser_window;
struct history_entry;
struct bitmap;
diff --git a/desktop/local_history.c b/desktop/local_history.c
index 412e893..5227c97 100644
--- a/desktop/local_history.c
+++ b/desktop/local_history.c
@@ -41,6 +41,7 @@
#include "desktop/system_colour.h"
#include "desktop/browser_private.h"
#include "desktop/browser_history.h"
+#include "desktop/local_history_private.h"
#include "desktop/local_history.h"
/**
diff --git a/content/handlers/text/textplain.h b/desktop/local_history_private.h
similarity index 57%
copy from content/handlers/text/textplain.h
copy to desktop/local_history_private.h
index 6cc2716..0b74562 100644
--- a/content/handlers/text/textplain.h
+++ b/desktop/local_history_private.h
@@ -1,6 +1,5 @@
/*
* Copyright 2006 James Bursa <bursa(a)users.sourceforge.net>
- * Copyright 2006 Adrian Lees <adrianl(a)users.sourceforge.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -19,19 +18,21 @@
/**
* \file
- *
- * Interface to content handler for plain text.
+ * Interface to browser history private operations
*/
-#ifndef NETSURF_HTML_TEXTPLAIN_H
-#define NETSURF_HTML_TEXTPLAIN_H
+#ifndef NETSURF_DESKTOP_BROWSER_HISTORY_PRIVATE_H
+#define NETSURF_DESKTOP_BROWSER_HISTORY_PRIVATE_H
-/**
- * Initialise the text content handler
- *
- * \return NSERROR_OK on success else appropriate error code.
- */
-nserror textplain_init(void);
+#include "content/handlers/css/utils.h"
+#define LOCAL_HISTORY_WIDTH \
+ (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(116))))
+#define LOCAL_HISTORY_HEIGHT \
+ (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(100))))
+#define LOCAL_HISTORY_RIGHT_MARGIN \
+ (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(50))))
+#define LOCAL_HISTORY_BOTTOM_MARGIN \
+ (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(30))))
#endif
diff --git a/docs/development.md b/docs/development.md
index 5a8d1aa..3f08b54 100644
--- a/docs/development.md
+++ b/docs/development.md
@@ -69,6 +69,12 @@ NetSurf [integration tests](docs/integration-testing.md) use the
monkey frontend to operate the browser as a whole. These tests open
windows, navigate to websites and render contents as a user might.
+# New frontend development
+
+[Implementing a new frotend](docs/implementing-new-frontend.md) for a
+toolkit can be challenging and this guide provides an overview and
+worked example.
+
# Documented API
The NetSurf code makes use of Doxygen for code documentation.
diff --git a/docs/implementing-new-frontend.md b/docs/implementing-new-frontend.md
new file mode 100644
index 0000000..1b4e438
--- /dev/null
+++ b/docs/implementing-new-frontend.md
@@ -0,0 +1,352 @@
+Implementing a new frontend
+===========================
+
+[TOC]
+
+# Introduction
+
+NetSurf is divided into a series of frontends which provide a user
+interface around common core functionality.
+
+Each frontend is a distinct implementation for a specific GUI toolkit.
+
+The existing frontends are covered in the [user
+interface](docs/user-interface.md) documentation.
+
+Note implementing a new frontend implies using a toolkit distinct from
+one of those already implemented and is distinct from porting NetSurf
+to a new operating system platform.
+
+It is recommend, in the strongest terms, that if the prospective
+developer is porting to both a new platform and toolkit that they
+*start* by getting the [monkey](docs/using-monkey.md) frontend
+building and passing at least the basic integration tests on their
+platform.
+
+Experience has shown that attempting to port to a platform and
+implement a toolkit at the same time generally results in failure to
+achieve either goal.
+
+NetSurf is built using GNU make and frontends are expected to
+integrate with this buildsystem.
+
+Implementation languages have historically been limited to C, C++ and
+objective C. However any language that can call C functions and
+*importantly* be called back from C code ought to be usable. For
+example there have been experiments with JAVA using JNI but no current
+frontend is implemented using it.
+
+# Implementation complexity
+
+An absolutely minimal "proof of concept" frontend implementation (like
+the FLTK frontend that will be used as an example) is around 1,000
+lines of C code. Basic functionality like the windows frontend is
+around 7,000 lines. A complete fully functional frontend such as the
+one for GTK is closer to 15,000 lines.
+
+It should be noted the majority of the minimal implementation can
+simply be copied and the names changed as appropriate from an existing
+example. The actual amount of new code that needs to be provided is
+very small.
+
+NetSurf provides a great deal of generic functionality for things like
+cookie, bookmark, history windows which require only minimal frontend
+support with the [core window API](docs/core-window-interface.md).
+
+A frontend developer is free to implement any and all of this generic
+functionality thelselves in a manner more integrated into a toolkit.
+
+# Implementation
+
+A frontend is generally named for the toolkit it is implementing (i.e
+gtk for the GTK+ toolkit). It is advisable to be as specific as
+possible e.g. the frontend for the windows operating system should
+have been named win32 allowing for an impementation using a differnt
+toolkit (e.g mfc)
+
+All the files needed for the frontend are contained in a single
+sub-directory in the NetSurf source tree e.g. `frontends/fltk`
+
+The only file outside this directory that much be changed is the
+`frontends/Makefile.hts` where a new entry must be added to the valid
+targets list.
+
+## Build system
+
+A frontend must provide three GNU Makefile fragments (these will be
+included from the core Makefile):
+
+ - `Makefile` - This is used to extend CFLAGS, CXXFLAGS and LDFLAGS variables as required. The executable target is set with EXETARGET and the browser source files are listed in the SOURCES variable
+ - `Makefile.defaults` - allows setting frontend specific makefile variables and overriding of the default core build variables.
+ - `Makefile.tools` - allows setting up frontend specific build tooling (as a minimum a tool for the package configuration in PKG_CONFIG)
+
+Source code modules can be named as the devloper desires within the
+frontend directory and should be added to the SOURCES variable as
+desired.
+
+## Program entry
+
+Generally the entry point from the OS is the `main()` function and
+several frontends have a `main.cpp` where some have used `gui.c`.
+
+The usual shape for the `main()` function is a six step process:
+ 1. The frontends operation tables are registered with NetSurf
+ 2. The toolkit specific initialisation is performed (which may involve calling NetSurf provided utility functions for support operations like logging, message translations etc.)
+ 3. Initialise the NetSurf core. After this point all browser functionality is available and registered operations can be called.
+ 4. Perform toolkiit setup, usually opening the initial browsing window (perhaps according to user preferences)
+ 5. Run the toolkits main loop while ensuring the Netsurf scheduled operations are also run at teh apropriate time.
+ 6. Finalisation on completion.
+
+## NetSurf operations tables
+
+The frontend will generally call netsurf interfaces to get a desired
+behaviour e.g. `browser_window_create()` to create a new browsing
+context (the `browser_window_` prefix is historical and does not
+necessarily create a window e.g. on gtk it is more likely to open a
+tab in an existing window). To achive the desired operation some
+operations need to be performed by the frontend under control of
+NetSurf, these operations are listed in tables.
+
+The operation tables should be registered with the NetSurf core as one
+of the first operations of the frontend code. The functions in these
+tables (and the tables themselves) must remain valid until
+`netsurf_exit()` is called.
+
+There are (currently) twelve sets of operation tables held in separate
+structures. Only five of these are mandantory (misc, window, fetch,
+bitmap and layout).
+
+In this context mandantory means the tables must be non NULL and do
+not have a suitable default. Each of the mandantory sets contain
+function pointers to implement operations.
+
+### misc operation table
+
+The only mandantory operation in this table is schedule.
+
+When schedule is called the frontend must arrange for the passed
+callback to be called with the context parameter after a number of
+miliseconds.
+
+This callback is typicaly driven through the toolkits event loop and
+it is important such callbacks are not attempted from an operation.
+
+### window operation table
+
+The window operations (poorly named as already mentioned) are where
+the frontend is called to actually manipulate widgets in the
+toolkit. This is mediated through a `gui_window` context pointer which
+is typed as a structure.
+
+This context pointer is passed to all window operations and is
+generally assumed to contain at least a reference to the underlying
+`browser_window` which is provided in the initial create operation to
+allow subsequent use of various core functionality.
+
+The mandantory window operations are:
+ - create - create a new browsing context widget in the frontend toolkit
+ - destroy - destoy a previously created `gui_window`
+ - invalidate - mark an area of the browsing context viewport as requiring redraw (note no redraw should be attempted from here)
+ - get_scroll - get the scroll offsets from the toolkit drawing widget
+ - set_scroll - set the scroll offsets on the toolkit drawing widget
+ - get_dimensions - get the dimensions of the toolkit drawing widget
+ - event - deal with various window events from netsurf which have no additional parameters
+
+
+### fetch operation table
+
+The fetch operations allow the built in scheme fetchers (file, about, resource) to obtain additional information necessary to complete their operation.
+
+The two mandantory operations are:
+ - `filetype` - allows the file scheme to obtain a mime type from a file path e.g. `a.file.name.png` would result in `image/png`
+ - `get_resource_url` - maps resource scheme paths to URL e.g. `resource:default.css` to `file:///usr/share/netsurf/default.css`
+
+### bitmap operation table
+
+The bitmap table and all of its operations are mandantory only because
+the empty defaults have not been included as it is assumed a browser
+will want to display images.
+
+All operations may be provided by stubs that return the failure codes
+until full implementations are made.
+
+### layout operation table
+
+The layout table is used to layout text. All operations are given
+strings to manipulate encoded in UTF-8. There are three mandantory
+operations:
+ - `width` - Calculate the width of a string.
+ - `position` - Find the position in a string where an x coordinate falls.
+ - `split` - Find where to split a string to make it fit a width.
+
+# Worked Example
+
+Rather than attempt to describe every aspect of an implementation we
+will rather work from an actual minimal example for the FLTK toolkit.
+
+This is availble as a single commit (`git show 04900e82e65f8669675538a66a01b56a3e473cb2`) in the NetSurf source repository. Alternatively it can be [viewed in a web browser](https://git.netsurf-browser.org/netsurf.git/commit/?h=vince/fltk....
+
+This represents the absolute minimum implementation to get a browser
+window on screen (and be able to click visible links). It is
+implemented in C++ as that is the FLTK implementation language but an
+equivalent implementation in other languages should be obvious.
+
+## Building
+
+The [frontends/Makefile.hts](https://git.netsurf-browser.org/netsurf.git/diff/...
+had the fltk target added to the VLDTARGET variable. This allows
+NetSurf to be built for this frontend with `make TARGET=fltk`
+
+As previously described the three GNU Make files are added:
+
+[Makefile](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk/Makefile?h=vince/fltk&id=04900e82e65f8669675538a66a01b56a3e473cb2)
+this shows how the flags are extended to add the fltk headers and
+library. Additionaly the list of sources are built here, as teh
+comment suggests it is important the SOURCES variable is not expanded
+here so the S_FRONTEND variable is used to allow expansion at teh
+correct time in the build process.
+
+[Makefile.defaults](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk/Makefile.defaults?h=vince/fltk&id=04900e82e65f8669675538a66a01b56a3e473cb2)
+has the default setting to control the build parameters and file locations. These can be overriden by the `Makefile.config` at compile time.
+
+[Makefile.tools](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk/Makefile.tools?h=vince/fltk&id=04900e82e65f8669675538a66a01b56a3e473cb2)
+allows the configuration of additional tools necessary to build for the target as a minimum pkg-config is usually required to find libraries.
+
+## Program entry
+
+In our example program entry is the classical `main()` in the [main.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk... module.
+
+This implements the six stage process outlined previously.
+
+### Operations table registration
+
+The `netsurf_table` structure is initialised and passed to
+`netsurf_register()`. It should be noted that the approach taken here
+and in most frontends is to have a source module for each operation
+table. The header for each module exposes just the pointer to the
+indivial operation set, this allows for all the operation functions to
+be static to their module and hence helps reduce global symbol usage.
+
+### Frontend specific initialisation
+
+Her it is implemented in `nsfltk_init()` this function performs all
+the operations specific to the frontend which must be initialised
+before netsurf itself. In some toolkits this would require calling the
+toolkit initialisation (e.g. `gtk_init()`).
+
+It is nessesary to initialise netsurf logging and user options at this
+point. A more fully featured implementation would also initialise the
+message translation system here.
+
+### Netsurf initialisation
+
+This is simply the call to `netsurf_init()` from this point the
+browser is fully operational and operations can and will be called.
+
+### Frontend specific startup
+
+Although the browser is running it has not yet been told to open a
+window or navigate to a page. Here `nsfltk_start()` examines the
+command line and environment to determine the initial page to navigate
+to and calls `browser_window_create()` with the url, this will cause
+the browser to open a new browsing context and start the navigation.
+
+A frontend may choose to implement more complex logic here but the
+example here is a good start.
+
+### Toolkit run loop
+
+The function `nsfltk_run()` runs the toolkit event loop. In this case it is using the generic scheduleing in the [misc.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk... module to ensure callbacks get made at the apropriate time.
+
+There is a `nsfltk_done` boolean global checked here so when all the
+browser windows are closed the program will exit.
+
+A more fully featured port might use the toolkits scheduling rather
+than open coding a solution with a linked list as is done
+here.
+
+A futher optimisation would be to obtain the set of file descriptors
+being used (with `fetch_fdset()`) for active fetches allowing for
+activity based fetch progress instead of the fallback polling method.
+
+### finalisation
+
+This simply finalises the browser stopping all activity and cleaning
+up any resource usage. After the call to `netsurf_exit()` no more
+operation calls will be made and all caches used by the core will be
+flushed.
+
+If user option chnages are to be made persistant `nsoption_finalise()`
+should be called.
+
+The finalisation of logging will ensure that any output buffers are
+flushed.
+
+## The window operation table
+
+Amongst all the boilerplate of the default implementation the only novel code is in the window operation table in the [window.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fl... module.
+
+### `nsfltk_window_create`
+
+The create operation instansiates a new `NS_Window` object and
+references it in the gui_window structure which it returns to the
+caller. Technically we could simply return the `NS_Window` object as
+the gui_window pointer but this implementation is avoiding the cast.
+
+Secondly `Fl_Double_Window` is subclassed as `NS_Widget`. The sublass
+allows the close callback to be accessed so the global `nsfltk_done`
+boolean can be set during the destructor method.
+
+The NS_Window creates an instance of `NS_Widget` in its constructor, a
+more extensive implementation would add other window furniture here
+(scroll bars, url bar, navigation elements, etc.)
+
+The implementation subclasses `Fl_Widget` implementing the draw
+method to render the browsing context and the handle method to handle
+mouse events to allow teh user to click.
+
+The `NS_Widget::handle()` method simply translates the mouse press
+event from widget coordinates to netsurf canvas cooridinates and maps
+teh mouse button state. The core is informed of these events using
+`browser_window_mouse_click()`
+
+The `NS_Widget::draw` method similarly translates the fltk toolkits
+clip rectangle, builds a plotting context and calls
+`browser_window_redraw()` which will use the plotting operations in
+the plotting context to render the browsing context within the area
+specified. One thing to note here is the translation between the
+coordinates of the render area and the internal page canvas given as
+the second and third parameters to the draw call. When scrolling is
+required this is achived by altering these offsets.
+
+
+### `nsfltk_window_invalidate()`
+
+This simply calls the damage method on the `Fl_Widget` class with the
+appropriate coordinate translation.
+
+### `nsfltk_window_get_dimensions()`
+
+This obtains the fltk widget width and height and returns them.
+
+## The plotting interface
+
+When the `NS_Widget::draw` method was discussed it was noted that a
+plotting context is built containing an operation table. That table is
+implemented in [plotters.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/...
+
+The implementation here is as minimal as can be, only line, rectangle
+and text have any implementation at all and even that simply sets a
+colour and performs the appropriate fltk draw function (`fl_line`,
+`fl_rect` and `fl_draw` respectively)
+
+# Conclusion
+
+Hopefully this breif overview and worked example should give the
+prospectinve frontend developer enough information to understand how
+to get started implementing a new frontend toolkit for NetSurf.
+
+As can be seen there is actualy very little novel code necessary to
+get started though I should mention that the move from "minimal" to
+"full" implementation is a large undertaking and it would be wise to
+talk with the NetSurf developers if undertaking such work.
diff --git a/frontends/fltk/main.cpp b/frontends/fltk/main.cpp
index 935bd2a..ab0e1bc 100644
--- a/frontends/fltk/main.cpp
+++ b/frontends/fltk/main.cpp
@@ -169,9 +169,6 @@ static void nsfltk_run(void)
do {
/* run scheduled callbacks and get the next event delta in ms */
schedtm = nsfltk_schedule_run();
- if (schedtm > 0) {
- NSLOG(netsurf, INFO, "scheduling for %d", schedtm);
- }
Fl::wait(((double)schedtm/1000));
} while(nsfltk_done != true);
}
diff --git a/frontends/fltk/window.cpp b/frontends/fltk/window.cpp
index 19aa265..fffc380 100644
--- a/frontends/fltk/window.cpp
+++ b/frontends/fltk/window.cpp
@@ -24,11 +24,17 @@
#include <stddef.h>
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Scrollbar.H>
#include <FL/fl_draw.H>
+#include <Fl/Fl_Output.H>
+#include <Fl/Fl_Pack.H>
+#include <Fl/Fl_Button.H>
extern "C" {
#include "utils/errors.h"
+#include "utils/nsoption.h"
+#include "utils/nsurl.h"
#include "netsurf/types.h"
#include "netsurf/mouse.h"
#include "netsurf/window.h"
@@ -36,6 +42,7 @@ extern "C" {
#include "netsurf/content.h"
#include "netsurf/browser_window.h"
#include "netsurf/mouse.h"
+#include "desktop/browser_history.h"
}
@@ -44,10 +51,16 @@ extern "C" {
extern bool nsfltk_done;
+struct gui_window {
+ class NS_Window *window;
+};
+
class NS_Widget : public Fl_Widget
{
private:
- struct browser_window *mbw;
+ struct browser_window *m_bw;
+ int m_xoffset;
+ int m_yoffset;
protected:
void draw();
@@ -55,38 +68,19 @@ protected:
public:
NS_Widget(int X,int Y,int W,int H, struct browser_window *bw)
- : Fl_Widget(X,Y,W,H), mbw(bw) {}
-};
-
-
-class NS_Window : public Fl_Double_Window
-{
-private:
- struct browser_window *mbw;
- NS_Widget *mnswidget;
-
- void close_callback(Fl_Widget *w);
- static void static_close_callback(Fl_Widget *w, void *f) { ((NS_Window *)f)->close_callback(w); }
+ : Fl_Widget(X,Y,W,H), m_bw(bw), m_xoffset(0), m_yoffset(0) {}
-public:
- NS_Window(int W, int H, struct browser_window *bw)
- : Fl_Double_Window(W,H), mbw(bw) {
- this->callback(static_close_callback, (void *)this);
- mnswidget = new NS_Widget(0, 0, W, H, bw);
- this->end();
- }
- ~NS_Window() { nsfltk_done=true; }
+ bool get_scroll(int *sx, int *sy);
+ nserror get_dimensions(int *width, int *height);
- NS_Widget *get_nswidget() { return mnswidget; }
+ nserror invalidate(const struct rect *rect);
+ void vscroll_callback(Fl_Scrollbar *w);
+ void hscroll_callback(Fl_Scrollbar *w);
};
-struct gui_window {
- struct browser_window *bw;
- NS_Window *window;
-};
/**
- * method to handle events on the netsurf browsing widget
+ * handle events on the netsurf browsing widget
*/
int NS_Widget::handle(int event)
{
@@ -99,10 +93,10 @@ int NS_Widget::handle(int event)
if (button == FL_LEFT_MOUSE) {
state |= BROWSER_MOUSE_PRESS_1;
}
- browser_window_mouse_click(mbw,
+ browser_window_mouse_click(m_bw,
(browser_mouse_state)state,
- Fl::event_x() - x(),
- Fl::event_y() - y());
+ Fl::event_x() - x() + m_xoffset,
+ Fl::event_y() - y() + m_yoffset);
return 1;
case FL_RELEASE:
@@ -111,10 +105,10 @@ int NS_Widget::handle(int event)
state |= BROWSER_MOUSE_CLICK_1;
}
- browser_window_mouse_click(mbw,
+ browser_window_mouse_click(m_bw,
(browser_mouse_state)state,
- Fl::event_x() - x(),
- Fl::event_y() - y());
+ Fl::event_x() - x() + m_xoffset,
+ Fl::event_y() - y() + m_yoffset);
return 1;
default:
@@ -124,7 +118,7 @@ int NS_Widget::handle(int event)
/**
- * method to redraw the netsurf browsing widget
+ * redraw the netsurf browsing widget
*/
void NS_Widget::draw()
{
@@ -140,103 +134,352 @@ void NS_Widget::draw()
.priv = NULL,
};
- browser_window_redraw(mbw, x(), y(), &clip, &ctx);
+ browser_window_redraw(m_bw,
+ x() - m_xoffset,
+ y() - m_yoffset,
+ &clip,
+ &ctx);
}
+
/**
- * callback when fltk window is closed
+ * vertical scrollbar position has been changed
*/
-void NS_Window::close_callback(Fl_Widget *w)
+void NS_Widget::vscroll_callback(Fl_Scrollbar *sb)
{
- browser_window_destroy(mbw);
+ m_yoffset = sb->value();
+ damage(FL_DAMAGE_SCROLL);
}
+
/**
- * Create and open a gui window for a browsing context.
- *
- * The implementing front end must create a context suitable
- * for it to display a window referred to as the "gui window".
- *
- * The frontend will be expected to request the core redraw
- * areas of the gui window which have become invalidated
- * either from toolkit expose events or as a result of a
- * invalidate() call.
- *
- * Most core operations used by the frontend concerning browser
- * windows require passing the browser window context therefor
- * the gui window must include a reference to the browser
- * window passed here.
- *
- * If GW_CREATE_CLONE flag is set existing is non-NULL.
- *
- * \param bw The core browsing context associated with the gui window
- * \param existing An existing gui_window, may be NULL.
- * \param flags flags to control the gui window creation.
- * \return gui window, or NULL on error.
+ * horizontal scrollbar position has been changed
*/
-static struct gui_window *
-nsfltk_window_create(struct browser_window *bw,
- struct gui_window *existing,
- gui_window_create_flags flags)
+void NS_Widget::hscroll_callback(Fl_Scrollbar *sb)
{
- struct gui_window *gw;
- gw = (struct gui_window *)calloc(1, sizeof(struct gui_window));
-
- gw->window = new NS_Window(800,600, bw);
+ m_xoffset = sb->value();
+ damage(FL_DAMAGE_SCROLL);
+}
- gw->window->show();
+/**
+ * get the current scroll offsets
+ */
+bool NS_Widget::get_scroll(int *sx, int *sy)
+{
+ *sx = m_xoffset;
+ *sy = m_yoffset;
- return gw;
+ return true;
}
+
/**
- * Destroy previously created gui window
- *
- * \param gw The gui window to destroy.
+ * get the viewable dimensions of browsing context
*/
-static void nsfltk_window_destroy(struct gui_window *gw)
+nserror NS_Widget::get_dimensions(int *width, int *height)
{
- Fl::delete_widget(gw->window);
- free(gw);
+ *width = w();
+ *height = h();
+
+ return NSERROR_OK;
}
/**
- * Invalidate an area of a window.
- *
- * The specified area of the window should now be considered
- * out of date. If the area is NULL the entire window must be
- * invalidated. It is expected that the windowing system will
- * then subsequently cause redraw/expose operations as
- * necessary.
- *
- * \note the frontend should not attempt to actually start the
- * redraw operations as a result of this callback because the
- * core redraw functions may already be threaded.
- *
- * \param gw The gui window to invalidate.
- * \param rect area to redraw or NULL for the entire window area
- * \return NSERROR_OK on success or appropriate error code
+ * mark an area of the browsing context as invalid
*/
-static nserror
-nsfltk_window_invalidate(struct gui_window *gw, const struct rect *rect)
+nserror NS_Widget::invalidate(const struct rect *rect)
{
- NS_Widget *nswidget;
- nswidget = gw->window->get_nswidget();
-
if (rect == NULL) {
- nswidget->damage(FL_DAMAGE_ALL);
+ damage(FL_DAMAGE_ALL);
+ } else {
+ damage(FL_DAMAGE_ALL,
+ rect->x0,
+ rect->y0,
+ rect->x1 - rect->x0,
+ rect->y1 - rect->y0);
+ }
+ return NSERROR_OK;
+
+}
+
+/**
+ * widget representing url bar
+ */
+class NS_URLBar : public Fl_Pack
+{
+private:
+ struct browser_window *m_bw;
+ Fl_Button *m_back_button;
+ Fl_Button *m_forward_button;
+ Fl_Input *m_input;
+
+ void back_callback(Fl_Button *button);
+ void forward_callback(Fl_Button *button);
+public:
+ NS_URLBar(int X,int Y,int W,int H, struct browser_window *bw);
+ nserror set_url(struct nsurl *url);
+
+ /* static wrapper for fltk callbacks */
+ static void static_back_callback(Fl_Widget *w, void *f);
+ static void static_forward_callback(Fl_Widget *w, void *f);
+
+};
+
+NS_URLBar::NS_URLBar(int X,int Y,int W,int H, struct browser_window *bw)
+ : Fl_Pack(X,Y,W,H), m_bw(bw)
+{
+ type(Fl_Pack::HORIZONTAL);
+ spacing(4);
+
+ m_back_button = new Fl_Button(0,0,H,H, "B");
+ m_back_button->callback(static_back_callback, (void *)this);
+
+ m_forward_button = new Fl_Button(0,0,H,H, "F");
+ m_forward_button->callback(static_forward_callback, (void *)this);
+
+ m_input = new Fl_Input(0,0,W,H);
+
+ end();
+
+ resizable(m_input);
+}
+
+nserror NS_URLBar::set_url(struct nsurl *url)
+{
+ size_t idn_url_l;
+ char *idn_url_s = NULL;
+ if (nsurl_get_utf8(url, &idn_url_s, &idn_url_l) == NSERROR_OK) {
+ m_input->value(idn_url_s, idn_url_l-1);
+ free(idn_url_s);
} else {
- nswidget->damage(FL_DAMAGE_ALL,
- rect->x0,
- rect->y0,
- rect->x1 - rect->x0,
- rect->y1 - rect->y0);
+ m_input->value(nsurl_access(url));
}
return NSERROR_OK;
}
+void NS_URLBar::back_callback(Fl_Button *button)
+{
+ browser_window_history_back(m_bw, false);
+}
+
+void NS_URLBar::forward_callback(Fl_Button *button)
+{
+ browser_window_history_forward(m_bw, false);
+}
+
+
+void NS_URLBar::static_back_callback(Fl_Widget *w, void *f)
+{
+ ((NS_URLBar *)f)->back_callback((Fl_Button *)w);
+}
+
+void NS_URLBar::static_forward_callback(Fl_Widget *w, void *f)
+{
+ ((NS_URLBar *)f)->forward_callback((Fl_Button *)w);
+}
+
+
+/**
+ * Class for netsurf window
+ */
+class NS_Window : public Fl_Double_Window
+{
+private:
+ struct browser_window *m_bw;
+
+ NS_URLBar *m_nsurlbar;
+ NS_Widget *m_nswidget;
+ Fl_Scrollbar *m_vscrollbar;
+ Fl_Scrollbar *m_hscrollbar;
+ Fl_Output *m_status;
+
+ nserror set_scroll(const struct rect *rect);
+ void set_status(const char *text);
+ void set_title(const char *title);
+ nserror set_extent(int w, int h);
+
+ void close_callback(Fl_Widget *w);
+
+ /* static wrapper for fltk callbacks */
+ static void static_close_callback(Fl_Widget *w, void *f);
+ static void static_hscroll_callback(Fl_Widget *w, void *f);
+ static void static_vscroll_callback(Fl_Widget *w, void *f);
+
+public:
+ NS_Window(int W, int H, struct browser_window *bw);
+ ~NS_Window() { nsfltk_done=true; }
+
+ /* static wrappers to be able to call instance methods */
+ static nserror static_set_scroll(struct gui_window *gw, const struct rect *rect);
+ static void static_set_status(struct gui_window *gw, const char *text);
+ static void static_set_title(struct gui_window *gw, const char *title);
+
+ static bool static_get_scroll(struct gui_window *gw, int *sx, int *sy);
+ static nserror static_set_url(struct gui_window *gw, struct nsurl *url);
+
+ static nserror static_event(struct gui_window *gw, enum gui_window_event event);
+ static nserror static_invalidate(struct gui_window *gw, const struct rect *rect);
+ static nserror static_get_dimensions(struct gui_window *gw, int *width, int *height);
+ static struct gui_window *static_create(struct browser_window *bw, struct gui_window *existing, gui_window_create_flags flags);
+ static void static_destroy(struct gui_window *gw);
+};
+
+
+/**
+ * netsurf window class constructor
+ */
+NS_Window::NS_Window(int W, int H, struct browser_window *bw)
+ : Fl_Double_Window(W,H), m_bw(bw)
+{
+ int scrlsize = Fl::scrollbar_size();
+ int splitx = (nsoption_int(toolbar_status_size) * W) / 10000;
+ int urlbarh = scrlsize * 2;
+
+ callback(static_close_callback, (void *)this);
+
+ // url bar
+ m_nsurlbar = new NS_URLBar(0, 0, W, urlbarh, bw);
+
+ // browser drawing canvas widget
+ m_nswidget = new NS_Widget(0,
+ m_nsurlbar->h(),
+ W - scrlsize,
+ H - scrlsize - urlbarh,
+ bw);
+
+ // vertical scrollbar
+ m_vscrollbar = new Fl_Scrollbar(m_nswidget->w(),
+ m_nsurlbar->h(),
+ scrlsize,
+ m_nswidget->h());
+ m_vscrollbar->callback(static_vscroll_callback, (void *)m_nswidget);
+ m_vscrollbar->value(0, m_nswidget->h(), 0, m_nswidget->h());
+
+ // horizontal scrollbar
+ m_hscrollbar = new Fl_Scrollbar(splitx,
+ m_nswidget->y() + m_nswidget->h(),
+ m_nswidget->w() - splitx,
+ scrlsize);
+ m_hscrollbar->type(FL_HORIZONTAL);
+ m_hscrollbar->callback(static_hscroll_callback, (void *)m_nswidget);
+ m_hscrollbar->value(0, m_nswidget->w(), 0, m_nswidget->w());
+
+ // status text
+ m_status = new Fl_Output(0, m_hscrollbar->y(), splitx, scrlsize);
+ end();
+
+ resizable(m_nswidget);
+}
+
+
+/**
+ * fltk window has been closed
+ */
+void NS_Window::close_callback(Fl_Widget *w)
+{
+ browser_window_destroy(m_bw);
+}
+
+
+
+
+/**
+ * set the status text
+ */
+void NS_Window::set_status(const char *text)
+{
+ m_status->value(text);
+}
+
+
+/**
+ * set the window title text
+ */
+void NS_Window::set_title(const char *text)
+{
+ label(text);
+}
+
+
+/**
+ * set the current position of the scroll bars
+ */
+nserror NS_Window::set_scroll(const struct rect *rect)
+{
+ m_vscrollbar->value(rect->y0);
+ m_hscrollbar->value(rect->x0);
+
+ m_nswidget->vscroll_callback(m_vscrollbar);
+ m_nswidget->hscroll_callback(m_hscrollbar);
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * Set the extent of the underlying canvas
+ */
+nserror NS_Window::set_extent(int ew, int eh)
+{
+ m_hscrollbar->value(0, w(), 0, ew);
+ m_vscrollbar->value(0, h(), 0, eh);
+
+ return NSERROR_OK;
+}
+
+
+/* static methods */
+
+/**
+ * static window close fltk callback which calls the instance
+ */
+void NS_Window::static_close_callback(Fl_Widget *w, void *f)
+{
+ ((NS_Window *)f)->close_callback(w);
+}
+
+/**
+ * static vertical scrollbar fltk callback which calls the instance
+ */
+void NS_Window::static_vscroll_callback(Fl_Widget *w, void *f)
+{
+ ((NS_Widget *)f)->vscroll_callback((Fl_Scrollbar *)w);
+}
+
+/**
+ * static horizontal scrollbar fltk callback which calls the instance
+ */
+void NS_Window::static_hscroll_callback(Fl_Widget *w, void *f)
+{
+ ((NS_Widget *)f)->hscroll_callback((Fl_Scrollbar *)w);
+}
+
+
+/**
+ * Set the status bar message of a browser window.
+ *
+ * \param g gui_window to update
+ * \param text new status text
+ */
+void NS_Window::static_set_status(struct gui_window *gw, const char *text)
+{
+ ((NS_Window *)gw->window)->set_status(text);
+}
+
+
+/**
+ * Set the title of a window.
+ *
+ * \param gw The gui window to set title of.
+ * \param title new window title
+ */
+void NS_Window::static_set_title(struct gui_window *gw, const char *title)
+{
+ ((NS_Window *)gw->window)->set_title(title);
+}
+
/**
* Get the scroll position of a browser window.
@@ -246,17 +489,17 @@ nsfltk_window_invalidate(struct gui_window *gw, const struct rect *rect)
* \param sy receives y ordinate of point at top-left of window
* \return true iff successful
*/
-static bool nsfltk_window_get_scroll(struct gui_window *gw, int *sx, int *sy)
+bool NS_Window::static_get_scroll(struct gui_window *gw, int *sx, int *sy)
{
- return false;
+ return gw->window->m_nswidget->get_scroll(sx, sy);
}
/**
* Set the scroll position of a browser window.
*
- * scrolls the viewport to ensure the specified rectangle of
- * the content is shown.
+ * scrolls the viewport to ensure the specified rectangle of the
+ * content is shown.
* If the rectangle is of zero size i.e. x0 == x1 and y0 == y1
* the contents will be scrolled so the specified point in the
* content is at the top of the viewport.
@@ -268,10 +511,80 @@ static bool nsfltk_window_get_scroll(struct gui_window *gw, int *sx, int *sy)
* \param rect The rectangle to ensure is shown.
* \return NSERROR_OK on success or appropriate error code.
*/
-static nserror
-nsfltk_window_set_scroll(struct gui_window *gw, const struct rect *rect)
+nserror
+NS_Window::static_set_scroll(struct gui_window *gw, const struct rect *rect)
{
- return NSERROR_OK;
+ return gw->window->set_scroll(rect);
+}
+
+
+/**
+ * Set the navigation url.
+ *
+ * \param gw window to update.
+ * \param url The url to use as icon.
+ */
+nserror NS_Window::static_set_url(struct gui_window *gw, struct nsurl *url)
+{
+ return gw->window->m_nsurlbar->set_url(url);
+}
+
+
+/**
+ * Miscellaneous event occurred for a window
+ *
+ * This is used to inform the frontend of window events which
+ * require no additional parameters.
+ *
+ * \param gw The gui window the event occurred for
+ * \param event Which event has occurred.
+ * \return NSERROR_OK if the event was processed else error code.
+ */
+nserror
+NS_Window::static_event(struct gui_window *gw, enum gui_window_event event)
+{
+ nserror res;
+
+ switch (event) {
+ case GW_EVENT_UPDATE_EXTENT:
+ {
+ int w, h;
+
+ res = browser_window_get_extents(gw->window->m_bw, true, &w, &h);
+ if (res == NSERROR_OK) {
+ res = (gw->window)->set_extent(w, h);
+ }
+ break;
+ }
+ default:
+ res = NSERROR_OK;
+ break;
+ }
+ return res;
+}
+
+
+/**
+ * Invalidate an area of a window.
+ *
+ * The specified area of the window should now be considered
+ * out of date. If the area is NULL the entire window must be
+ * invalidated. It is expected that the windowing system will
+ * then subsequently cause redraw/expose operations as
+ * necessary.
+ *
+ * \note the frontend should not attempt to actually start the
+ * redraw operations as a result of this callback because the
+ * core redraw functions may already be threaded.
+ *
+ * \param gw The gui window to invalidate.
+ * \param rect area to redraw or NULL for the entire window area
+ * \return NSERROR_OK on success or appropriate error code
+ */
+nserror
+NS_Window::static_invalidate(struct gui_window *gw, const struct rect *rect)
+{
+ return gw->window->m_nswidget->invalidate(rect);
}
@@ -289,47 +602,80 @@ nsfltk_window_set_scroll(struct gui_window *gw, const struct rect *rect)
* \return NSERROR_OK on success and width and height updated
* else error code.
*/
-static nserror
-nsfltk_window_get_dimensions(struct gui_window *gw, int *width, int *height)
+nserror
+NS_Window::static_get_dimensions(struct gui_window *gw, int *width, int *height)
{
- NS_Widget *nswidget;
- nswidget = gw->window->get_nswidget();
-
- *width = nswidget->w();
- *height = nswidget->h();
-
- return NSERROR_OK;
+ return gw->window->m_nswidget->get_dimensions(width, height);
}
/**
- * Miscellaneous event occurred for a window
+ * Create and open a gui window for a browsing context.
*
- * This is used to inform the frontend of window events which
- * require no additional parameters.
+ * The implementing front end must create a context suitable
+ * for it to display a window referred to as the "gui window".
*
- * \param gw The gui window the event occurred for
- * \param event Which event has occurred.
- * \return NSERROR_OK if the event was processed else error code.
+ * The frontend will be expected to request the core redraw
+ * areas of the gui window which have become invalidated
+ * either from toolkit expose events or as a result of a
+ * invalidate() call.
+ *
+ * Most core operations used by the frontend concerning browser
+ * windows require passing the browser window context therefor
+ * the gui window must include a reference to the browser
+ * window passed here.
+ *
+ * If GW_CREATE_CLONE flag is set existing is non-NULL.
+ *
+ * \param bw The core browsing context associated with the gui window
+ * \param existing An existing gui_window, may be NULL.
+ * \param flags flags to control the gui window creation.
+ * \return gui window, or NULL on error.
*/
-static nserror
-nsfltk_window_event(struct gui_window *gw, enum gui_window_event event)
+struct gui_window *
+NS_Window::static_create(struct browser_window *bw,
+ struct gui_window *existing,
+ gui_window_create_flags flags)
{
- return NSERROR_OK;
+ struct gui_window *gw;
+ gw = (struct gui_window *)calloc(1, sizeof(struct gui_window));
+
+ if (gw != NULL) {
+ gw->window = new NS_Window(800,600, bw);
+
+ gw->window->show();
+ }
+
+ return gw;
}
+/**
+ * Destroy previously created gui window
+ *
+ * \param gw The gui window to destroy.
+ */
+void NS_Window::static_destroy(struct gui_window *gw)
+{
+ Fl::delete_widget(gw->window);
+ free(gw);
+}
+
+
+/**
+ * window operations table for fltk frontend
+ */
static struct gui_window_table window_table = {
- .create = nsfltk_window_create,
- .destroy = nsfltk_window_destroy,
- .invalidate = nsfltk_window_invalidate,
- .get_scroll = nsfltk_window_get_scroll,
- .set_scroll = nsfltk_window_set_scroll,
- .get_dimensions = nsfltk_window_get_dimensions,
- .event = nsfltk_window_event,
- .set_title = NULL,
- .set_url = NULL,
+ .create = NS_Window::static_create,
+ .destroy = NS_Window::static_destroy,
+ .invalidate = NS_Window::static_invalidate,
+ .get_scroll = NS_Window::static_get_scroll,
+ .set_scroll = NS_Window::static_set_scroll,
+ .get_dimensions = NS_Window::static_get_dimensions,
+ .event = NS_Window::static_event,
+ .set_title = NS_Window::static_set_title,
+ .set_url = NS_Window::static_set_url,
.set_icon = NULL,
- .set_status = NULL,
+ .set_status = NS_Window::static_set_status,
.set_pointer = NULL,
.place_caret = NULL,
.drag_start = NULL,
--
NetSurf Browser
2 years, 6 months
netsurf: branch master updated. release/3.10-126-g847d568
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/847d5680613cb578ba4a5...
...commit http://git.netsurf-browser.org/netsurf.git/commit/847d5680613cb578ba4a548...
...tree http://git.netsurf-browser.org/netsurf.git/tree/847d5680613cb578ba4a54896...
The branch, master has been updated
via 847d5680613cb578ba4a548960480363a3230174 (commit)
via 5749ace60f9359b6bc31d7f8c071d87d270733da (commit)
from 6faa70893b70fc43d6f398f2e43719c763c2d193 (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=847d5680613cb578ba4...
commit 847d5680613cb578ba4a548960480363a3230174
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
fix missing bitmap from preventing history and scroll updates
diff --git a/desktop/browser_history.c b/desktop/browser_history.c
index 39072ff..2fbc80f 100644
--- a/desktop/browser_history.c
+++ b/desktop/browser_history.c
@@ -435,9 +435,7 @@ nserror browser_window_history_update(struct browser_window *bw,
history = bw->history;
- if (!history ||
- !history->current ||
- !history->current->page.bitmap) {
+ if ((history == NULL) || (history->current == NULL)) {
return NSERROR_INVALID;
}
@@ -456,7 +454,7 @@ nserror browser_window_history_update(struct browser_window *bw,
guit->bitmap->render(history->current->page.bitmap, content);
}
- if (bw->window != NULL &&
+ if ((bw->window != NULL) &&
guit->window->get_scroll(bw->window, &sx, &sy)) {
int content_height = content_get_height(content);
int content_width = content_get_width(content);
@@ -490,9 +488,7 @@ browser_window_history_get_scroll(struct browser_window *bw,
history = bw->history;
- if (!history ||
- !history->current ||
- !history->current->page.bitmap) {
+ if ((history== NULL) || (history->current == NULL)) {
return NSERROR_INVALID;
}
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=5749ace60f9359b6bc3...
commit 5749ace60f9359b6bc31d7f8c071d87d270733da
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
split out internal local history macros from public interface header
diff --git a/desktop/browser_history.c b/desktop/browser_history.c
index 5b44670..39072ff 100644
--- a/desktop/browser_history.c
+++ b/desktop/browser_history.c
@@ -41,6 +41,7 @@
#include "desktop/gui_internal.h"
#include "desktop/browser_private.h"
+#include "desktop/local_history_private.h"
#include "desktop/browser_history.h"
/**
diff --git a/desktop/browser_history.h b/desktop/browser_history.h
index 06041eb..9b6f1fd 100644
--- a/desktop/browser_history.h
+++ b/desktop/browser_history.h
@@ -35,17 +35,6 @@
#include "utils/errors.h"
-#include "content/handlers/css/utils.h"
-
-#define LOCAL_HISTORY_WIDTH \
- (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(116))))
-#define LOCAL_HISTORY_HEIGHT \
- (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(100))))
-#define LOCAL_HISTORY_RIGHT_MARGIN \
- (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(50))))
-#define LOCAL_HISTORY_BOTTOM_MARGIN \
- (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(30))))
-
struct browser_window;
struct history_entry;
struct bitmap;
diff --git a/desktop/local_history.c b/desktop/local_history.c
index 412e893..5227c97 100644
--- a/desktop/local_history.c
+++ b/desktop/local_history.c
@@ -41,6 +41,7 @@
#include "desktop/system_colour.h"
#include "desktop/browser_private.h"
#include "desktop/browser_history.h"
+#include "desktop/local_history_private.h"
#include "desktop/local_history.h"
/**
diff --git a/desktop/local_history_private.h b/desktop/local_history_private.h
new file mode 100644
index 0000000..0b74562
--- /dev/null
+++ b/desktop/local_history_private.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2006 James Bursa <bursa(a)users.sourceforge.net>
+ *
+ * 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
+ * Interface to browser history private operations
+ */
+
+#ifndef NETSURF_DESKTOP_BROWSER_HISTORY_PRIVATE_H
+#define NETSURF_DESKTOP_BROWSER_HISTORY_PRIVATE_H
+
+#include "content/handlers/css/utils.h"
+
+#define LOCAL_HISTORY_WIDTH \
+ (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(116))))
+#define LOCAL_HISTORY_HEIGHT \
+ (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(100))))
+#define LOCAL_HISTORY_RIGHT_MARGIN \
+ (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(50))))
+#define LOCAL_HISTORY_BOTTOM_MARGIN \
+ (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(30))))
+
+#endif
-----------------------------------------------------------------------
Summary of changes:
desktop/browser_history.c | 11 ++++------
desktop/browser_history.h | 11 ----------
desktop/local_history.c | 1 +
.../textplain.h => desktop/local_history_private.h | 23 ++++++++++----------
4 files changed, 17 insertions(+), 29 deletions(-)
copy content/handlers/text/textplain.h => desktop/local_history_private.h (57%)
diff --git a/desktop/browser_history.c b/desktop/browser_history.c
index 5b44670..2fbc80f 100644
--- a/desktop/browser_history.c
+++ b/desktop/browser_history.c
@@ -41,6 +41,7 @@
#include "desktop/gui_internal.h"
#include "desktop/browser_private.h"
+#include "desktop/local_history_private.h"
#include "desktop/browser_history.h"
/**
@@ -434,9 +435,7 @@ nserror browser_window_history_update(struct browser_window *bw,
history = bw->history;
- if (!history ||
- !history->current ||
- !history->current->page.bitmap) {
+ if ((history == NULL) || (history->current == NULL)) {
return NSERROR_INVALID;
}
@@ -455,7 +454,7 @@ nserror browser_window_history_update(struct browser_window *bw,
guit->bitmap->render(history->current->page.bitmap, content);
}
- if (bw->window != NULL &&
+ if ((bw->window != NULL) &&
guit->window->get_scroll(bw->window, &sx, &sy)) {
int content_height = content_get_height(content);
int content_width = content_get_width(content);
@@ -489,9 +488,7 @@ browser_window_history_get_scroll(struct browser_window *bw,
history = bw->history;
- if (!history ||
- !history->current ||
- !history->current->page.bitmap) {
+ if ((history== NULL) || (history->current == NULL)) {
return NSERROR_INVALID;
}
diff --git a/desktop/browser_history.h b/desktop/browser_history.h
index 06041eb..9b6f1fd 100644
--- a/desktop/browser_history.h
+++ b/desktop/browser_history.h
@@ -35,17 +35,6 @@
#include "utils/errors.h"
-#include "content/handlers/css/utils.h"
-
-#define LOCAL_HISTORY_WIDTH \
- (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(116))))
-#define LOCAL_HISTORY_HEIGHT \
- (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(100))))
-#define LOCAL_HISTORY_RIGHT_MARGIN \
- (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(50))))
-#define LOCAL_HISTORY_BOTTOM_MARGIN \
- (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(30))))
-
struct browser_window;
struct history_entry;
struct bitmap;
diff --git a/desktop/local_history.c b/desktop/local_history.c
index 412e893..5227c97 100644
--- a/desktop/local_history.c
+++ b/desktop/local_history.c
@@ -41,6 +41,7 @@
#include "desktop/system_colour.h"
#include "desktop/browser_private.h"
#include "desktop/browser_history.h"
+#include "desktop/local_history_private.h"
#include "desktop/local_history.h"
/**
diff --git a/content/handlers/text/textplain.h b/desktop/local_history_private.h
similarity index 57%
copy from content/handlers/text/textplain.h
copy to desktop/local_history_private.h
index 6cc2716..0b74562 100644
--- a/content/handlers/text/textplain.h
+++ b/desktop/local_history_private.h
@@ -1,6 +1,5 @@
/*
* Copyright 2006 James Bursa <bursa(a)users.sourceforge.net>
- * Copyright 2006 Adrian Lees <adrianl(a)users.sourceforge.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -19,19 +18,21 @@
/**
* \file
- *
- * Interface to content handler for plain text.
+ * Interface to browser history private operations
*/
-#ifndef NETSURF_HTML_TEXTPLAIN_H
-#define NETSURF_HTML_TEXTPLAIN_H
+#ifndef NETSURF_DESKTOP_BROWSER_HISTORY_PRIVATE_H
+#define NETSURF_DESKTOP_BROWSER_HISTORY_PRIVATE_H
-/**
- * Initialise the text content handler
- *
- * \return NSERROR_OK on success else appropriate error code.
- */
-nserror textplain_init(void);
+#include "content/handlers/css/utils.h"
+#define LOCAL_HISTORY_WIDTH \
+ (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(116))))
+#define LOCAL_HISTORY_HEIGHT \
+ (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(100))))
+#define LOCAL_HISTORY_RIGHT_MARGIN \
+ (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(50))))
+#define LOCAL_HISTORY_BOTTOM_MARGIN \
+ (FIXTOINT(nscss_pixels_css_to_physical(INTTOFIX(30))))
#endif
--
NetSurf Browser
2 years, 6 months
libcss: branch tlsa/units updated. release/0.9.1-20-g0c5718f
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/libcss.git/shortlog/0c5718ff8b5e94c8dcc175...
...commit http://git.netsurf-browser.org/libcss.git/commit/0c5718ff8b5e94c8dcc175a1...
...tree http://git.netsurf-browser.org/libcss.git/tree/0c5718ff8b5e94c8dcc175a112...
The branch, tlsa/units has been updated
discards b26554d3808c5c2736d611d4fb8eff28dc765b72 (commit)
via 0c5718ff8b5e94c8dcc175a1126eec8f3b598161 (commit)
via 9db93fe7a99c757c5065d2a6c9738cffa269378e (commit)
via 443bd7f401a74a0adc32bac0ecb87a2b77f9cfeb (commit)
via 0504194e51a35a88ceba06288a6a2d8243b27516 (commit)
This update added new revisions after undoing existing revisions. That is
to say, the old revision is not a strict subset of the new revision. This
situation occurs when you --force push a change and generate a repository
containing something like this:
* -- * -- B -- O -- O -- O (b26554d3808c5c2736d611d4fb8eff28dc765b72)
\
N -- N -- N (0c5718ff8b5e94c8dcc175a1126eec8f3b598161)
When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.
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/libcss.git/commit/?id=0c5718ff8b5e94c8dcc1...
commit 0c5718ff8b5e94c8dcc175a1126eec8f3b598161
Author: Michael Drake <Michael Drake tlsa(a)netsurf-browser.org>
Commit: Michael Drake <Michael Drake tlsa(a)netsurf-browser.org>
Selection: Remove client callback for unit conversion.
Now clients provide a unit conversion context and libcss provides
code to perform unit conversion.
This reduces the amount of common code that clients have to write.
diff --git a/Makefile b/Makefile
index 0835c8f..86d6641 100644
--- a/Makefile
+++ b/Makefile
@@ -65,5 +65,6 @@ INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):include/libcss/properties.h
INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):include/libcss/select.h
INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):include/libcss/stylesheet.h
INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):include/libcss/types.h
+INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):include/libcss/unit.h
INSTALL_ITEMS := $(INSTALL_ITEMS) /$(LIBDIR)/pkgconfig:lib$(COMPONENT).pc.in
INSTALL_ITEMS := $(INSTALL_ITEMS) /$(LIBDIR):$(OUTPUT)
diff --git a/examples/example1.c b/examples/example1.c
index c36a94d..6135793 100644
--- a/examples/example1.c
+++ b/examples/example1.c
@@ -98,13 +98,22 @@ static css_error node_presentational_hint(void *pw, void *node,
uint32_t *nhints, css_hint **hints);
static css_error ua_default_for_property(void *pw, uint32_t property,
css_hint *hint);
-static css_error compute_font_size(void *pw, const css_hint *parent,
- css_hint *size);
static css_error set_libcss_node_data(void *pw, void *n,
void *libcss_node_data);
static css_error get_libcss_node_data(void *pw, void *n,
void **libcss_node_data);
+static css_unit_len_ctx uint_len_ctx = {
+ .viewport_width = 800 * (1 << CSS_RADIX_POINT),
+ .viewport_height = 600 * (1 << CSS_RADIX_POINT),
+ .font_size_default = 16 * (1 << CSS_RADIX_POINT),
+ .font_size_minimum = 6 * (1 << CSS_RADIX_POINT),
+ .device_dpi = 96 * (1 << CSS_RADIX_POINT),
+ .root_style = NULL, /* We don't have a root node yet. */
+ .pw = NULL, /* We're not implementing measure callback */
+ .measure = NULL, /* We're not implementing measure callback */
+};
+
/* Table of function pointers for the LibCSS Select API. */
static css_select_handler select_handler = {
CSS_SELECT_HANDLER_VERSION_1,
@@ -143,9 +152,8 @@ static css_select_handler select_handler = {
node_is_lang,
node_presentational_hint,
ua_default_for_property,
- compute_font_size,
set_libcss_node_data,
- get_libcss_node_data
+ get_libcss_node_data,
};
@@ -237,6 +245,7 @@ int main(int argc, char **argv)
lwc_intern_string(element, strlen(element), &element_name);
code = css_select_style(select_ctx, element_name,
+ &uint_len_ctx,
&media, NULL,
&select_handler, 0,
&style);
@@ -662,68 +671,6 @@ css_error ua_default_for_property(void *pw, uint32_t property, css_hint *hint)
return CSS_OK;
}
-css_error compute_font_size(void *pw, const css_hint *parent, css_hint *size)
-{
- static css_hint_length sizes[] = {
- { FLTTOFIX(6.75), CSS_UNIT_PT },
- { FLTTOFIX(7.50), CSS_UNIT_PT },
- { FLTTOFIX(9.75), CSS_UNIT_PT },
- { FLTTOFIX(12.0), CSS_UNIT_PT },
- { FLTTOFIX(13.5), CSS_UNIT_PT },
- { FLTTOFIX(18.0), CSS_UNIT_PT },
- { FLTTOFIX(24.0), CSS_UNIT_PT }
- };
- const css_hint_length *parent_size;
-
- UNUSED(pw);
-
- /* Grab parent size, defaulting to medium if none */
- if (parent == NULL) {
- parent_size = &sizes[CSS_FONT_SIZE_MEDIUM - 1];
- } else {
- assert(parent->status == CSS_FONT_SIZE_DIMENSION);
- assert(parent->data.length.unit != CSS_UNIT_EM);
- assert(parent->data.length.unit != CSS_UNIT_EX);
- parent_size = &parent->data.length;
- }
-
- assert(size->status != CSS_FONT_SIZE_INHERIT);
-
- if (size->status < CSS_FONT_SIZE_LARGER) {
- /* Keyword -- simple */
- size->data.length = sizes[size->status - 1];
- } else if (size->status == CSS_FONT_SIZE_LARGER) {
- /** \todo Step within table, if appropriate */
- size->data.length.value =
- FMUL(parent_size->value, FLTTOFIX(1.2));
- size->data.length.unit = parent_size->unit;
- } else if (size->status == CSS_FONT_SIZE_SMALLER) {
- /** \todo Step within table, if appropriate */
- size->data.length.value =
- FMUL(parent_size->value, FLTTOFIX(1.2));
- size->data.length.unit = parent_size->unit;
- } else if (size->data.length.unit == CSS_UNIT_EM ||
- size->data.length.unit == CSS_UNIT_EX) {
- size->data.length.value =
- FMUL(size->data.length.value, parent_size->value);
-
- if (size->data.length.unit == CSS_UNIT_EX) {
- size->data.length.value = FMUL(size->data.length.value,
- FLTTOFIX(0.6));
- }
-
- size->data.length.unit = parent_size->unit;
- } else if (size->data.length.unit == CSS_UNIT_PCT) {
- size->data.length.value = FDIV(FMUL(size->data.length.value,
- parent_size->value), FLTTOFIX(100));
- size->data.length.unit = parent_size->unit;
- }
-
- size->status = CSS_FONT_SIZE_DIMENSION;
-
- return CSS_OK;
-}
-
static css_error set_libcss_node_data(void *pw, void *n,
void *libcss_node_data)
{
diff --git a/include/libcss/computed.h b/include/libcss/computed.h
index f4b3e21..1587d78 100644
--- a/include/libcss/computed.h
+++ b/include/libcss/computed.h
@@ -19,6 +19,7 @@ extern "C"
#include <libcss/functypes.h>
#include <libcss/properties.h>
#include <libcss/types.h>
+#include <libcss/unit.h>
struct css_hint;
struct css_select_handler;
@@ -81,10 +82,7 @@ css_error css_computed_style_destroy(css_computed_style *style);
css_error css_computed_style_compose(
const css_computed_style *restrict parent,
const css_computed_style *restrict child,
- css_error (*compute_font_size)(void *pw,
- const struct css_hint *parent,
- struct css_hint *size),
- void *pw,
+ const css_unit_len_ctx *unit_len_ctx,
css_computed_style **restrict result);
/******************************************************************************
diff --git a/include/libcss/select.h b/include/libcss/select.h
index ca57456..bfaf531 100644
--- a/include/libcss/select.h
+++ b/include/libcss/select.h
@@ -18,6 +18,7 @@ extern "C"
#include <libcss/hint.h>
#include <libcss/types.h>
#include <libcss/computed.h>
+#include <libcss/unit.h>
typedef enum css_pseudo_element {
CSS_PSEUDO_ELEMENT_NONE = 0,
@@ -123,9 +124,6 @@ typedef struct css_select_handler {
css_error (*ua_default_for_property)(void *pw, uint32_t property,
css_hint *hint);
- css_error (*compute_font_size)(void *pw, const css_hint *parent,
- css_hint *size);
-
/**
* Set libcss_node_data on a DOM node.
*
@@ -221,6 +219,7 @@ css_error css_select_default_style(css_select_ctx *ctx,
css_select_handler *handler, void *pw,
css_computed_style **style);
css_error css_select_style(css_select_ctx *ctx, void *node,
+ const css_unit_len_ctx *unit_len_ctx,
const css_media *media, const css_stylesheet *inline_style,
css_select_handler *handler, void *pw,
css_select_results **result);
diff --git a/include/libcss/unit.h b/include/libcss/unit.h
new file mode 100644
index 0000000..a847077
--- /dev/null
+++ b/include/libcss/unit.h
@@ -0,0 +1,156 @@
+/*
+ * This file is part of LibCSS.
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2008 John-Mark Bell <jmb(a)netsurf-browser.org>
+ */
+
+#ifndef libcss_unit_h_
+#define libcss_unit_h_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libcss/types.h>
+
+/**
+ * Client callback for font measuring.
+ *
+ * \param[in] pw Client data.
+ * \param[in] style Style to measure font for, or NULL.
+ * \param[in] unit Either CSS_UNIT_EX, or CSS_UNIT_CH.
+ * \return length in CSS pixels.
+ */
+typedef css_fixed (*css_unit_len_measure)(
+ void *pw,
+ const css_computed_style *style,
+ const css_unit unit);
+
+/**
+ * LibCSS unit conversion context.
+ *
+ * The client callback is optional. It is used for measuring "ch"
+ * (glyph '0' advance) and "ex" (height of the letter 'x') units.
+ * If a NULL pointer is given, LibCSS will use a fixed scaling of
+ * the "em" unit.
+ */
+typedef struct css_unit_len_ctx {
+ /**
+ * Viewport width in CSS pixels.
+ * Used if unit is vh, vw, vi, vb, vmin, or vmax.
+ */
+ css_fixed viewport_width;
+ /**
+ * Viewport height in CSS pixels.
+ * Used if unit is vh, vw, vi, vb, vmin, or vmax.
+ */
+ css_fixed viewport_height;
+ /**
+ * Client default font size in CSS pixels.
+ */
+ css_fixed font_size_default;
+ /**
+ * Client minimum font size in CSS pixels. May be zero.
+ */
+ css_fixed font_size_minimum;
+ /**
+ * DPI of the device the style is selected for.
+ */
+ css_fixed device_dpi;
+ /**
+ * Computed style for the document root element, needed for rem units.
+ * May be NULL, in which case font_size_default is used instead, as
+ * would be the case if rem unit is used on the root element.
+ */
+ const css_computed_style *root_style;
+ /**
+ * Optional client private word for measure callback.
+ */
+ void *pw;
+ /**
+ * Optional client callback for font measuring.
+ */
+ const css_unit_len_measure measure;
+} css_unit_len_ctx;
+
+/**
+ * Convert css pixels to physical pixels.
+ *
+ * \param[in] css_pixels Length in css pixels.
+ * \param[in] device_dpi Device dots per inch.
+ * \return Length in device pixels.
+ */
+static inline css_fixed css_unit_css2device_px(
+ const css_fixed css_pixels,
+ const css_fixed device_dpi)
+{
+ return FDIV(FMUL(css_pixels, device_dpi), F_96);
+}
+
+/**
+ * Convert device pixels to css pixels.
+ *
+ * \param[in] device_pixels Length in physical pixels.
+ * \param[in] device_dpi Device dots per inch.
+ * \return Length in css pixels.
+ */
+static inline css_fixed css_unit_device2css_px(
+ const css_fixed device_pixels,
+ const css_fixed device_dpi)
+{
+ return FDIV(FMUL(device_pixels, F_96), device_dpi);
+}
+
+/**
+ * Convert a length to points (pt).
+ *
+ * \param[in] style Style to perform conversion for or NULL.
+ * \param[in] ctx Length unit conversion context.
+ * \param[in] length Length to convert.
+ * \param[in] unit Current unit of length.
+ * \return A length in points.
+ */
+css_fixed css_unit_font_size_len2pt(
+ const css_computed_style *style,
+ const css_unit_len_ctx *ctx,
+ const css_fixed length,
+ const css_unit unit);
+
+/**
+ * Convert a length to CSS pixels.
+ *
+ * \param[in] style Style to perform conversion for or NULL.
+ * \param[in] ctx Length unit conversion context.
+ * \param[in] length Length to convert.
+ * \param[in] unit Current unit of length.
+ * \return A length in CSS pixels.
+ */
+css_fixed css_unit_len2css_px(
+ const css_computed_style *style,
+ const css_unit_len_ctx *ctx,
+ const css_fixed length,
+ const css_unit unit);
+
+/**
+ * Convert a length to device pixels.
+ *
+ * \param[in] style Style to perform conversion for or NULL.
+ * \param[in] ctx Length unit conversion context.
+ * \param[in] length Length to convert.
+ * \param[in] unit Current unit of length.
+ * \return A length in device pixels.
+ */
+css_fixed css_unit_len2device_px(
+ const css_computed_style *style,
+ const css_unit_len_ctx *ctx,
+ const css_fixed length,
+ const css_unit unit);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/select/computed.c b/src/select/computed.c
index a1b345b..d075af9 100644
--- a/src/select/computed.c
+++ b/src/select/computed.c
@@ -12,6 +12,7 @@
#include "select/dispatch.h"
#include "select/propget.h"
#include "select/propset.h"
+#include "select/unit.h"
#include "utils/utils.h"
static css_error compute_absolute_color(css_computed_style *style,
@@ -247,9 +248,7 @@ css_error css__computed_style_initialise(css_computed_style *style,
css_error css_computed_style_compose(
const css_computed_style *restrict parent,
const css_computed_style *restrict child,
- css_error (*compute_font_size)(void *pw,
- const css_hint *parent, css_hint *size),
- void *pw,
+ const css_unit_len_ctx *unit_len_ctx,
css_computed_style **restrict result)
{
css_computed_style *composed;
@@ -275,8 +274,7 @@ css_error css_computed_style_compose(
}
/* Finally, compute absolute values for everything */
- error = css__compute_absolute_values(parent, composed,
- compute_font_size, pw);
+ error = css__compute_absolute_values(parent, composed, unit_len_ctx);
if (error != CSS_OK) {
return error;
}
@@ -1087,31 +1085,36 @@ uint8_t css_computed_order(const css_computed_style *style,
*
* \param parent Parent style, or NULL for tree root
* \param style Computed style to process
- * \param compute_font_size Callback to calculate an absolute font-size
- * \param pw Private word for callback
+ * \param unit_len_ctx Client length conversion context.
* \return CSS_OK on success.
*/
css_error css__compute_absolute_values(const css_computed_style *parent,
css_computed_style *style,
- css_error (*compute_font_size)(void *pw,
- const css_hint *parent, css_hint *size),
- void *pw)
+ const css_unit_len_ctx *unit_len_ctx)
{
+ css_hint_length *ref_length = NULL;
css_hint psize, size, ex_size;
css_error error;
- /* Ensure font-size is absolute */
+ /* Get reference font-size for relative sizes. */
if (parent != NULL) {
psize.status = get_font_size(parent,
&psize.data.length.value,
&psize.data.length.unit);
+ if (psize.status != CSS_FONT_SIZE_DIMENSION) {
+ return CSS_BADPARM;
+ }
+ ref_length = &psize.data.length;
}
size.status = get_font_size(style,
&size.data.length.value,
&size.data.length.unit);
- error = compute_font_size(pw, parent != NULL ? &psize : NULL, &size);
+ error = css_unit_compute_absolute_font_size(ref_length,
+ unit_len_ctx->root_style,
+ unit_len_ctx->font_size_default,
+ &size);
if (error != CSS_OK)
return error;
@@ -1125,7 +1128,12 @@ css_error css__compute_absolute_values(const css_computed_style *parent,
ex_size.status = CSS_FONT_SIZE_DIMENSION;
ex_size.data.length.value = INTTOFIX(1);
ex_size.data.length.unit = CSS_UNIT_EX;
- error = compute_font_size(pw, &size, &ex_size);
+
+ error = css_unit_compute_absolute_font_size(
+ &size.data.length,
+ unit_len_ctx->root_style,
+ unit_len_ctx->font_size_default,
+ &ex_size);
if (error != CSS_OK)
return error;
diff --git a/src/select/computed.h b/src/select/computed.h
index c926cec..8b33405 100644
--- a/src/select/computed.h
+++ b/src/select/computed.h
@@ -10,6 +10,8 @@
#include <libcss/computed.h>
#include <libcss/hint.h>
+#include <libcss/unit.h>
+
#include "autogenerated_computed.h"
/**
@@ -35,8 +37,6 @@ css_error css__computed_style_initialise(css_computed_style *style,
css_error css__compute_absolute_values(const css_computed_style *parent,
css_computed_style *style,
- css_error (*compute_font_size)(void *pw,
- const css_hint *parent, css_hint *size),
- void *pw);
+ const css_unit_len_ctx *unit_len_ctx);
#endif
diff --git a/src/select/select.c b/src/select/select.c
index f6efbfe..03a45fe 100644
--- a/src/select/select.c
+++ b/src/select/select.c
@@ -23,6 +23,7 @@
#include "select/propset.h"
#include "select/font_face.h"
#include "select/select.h"
+#include "select/unit.h"
#include "utils/parserutilserror.h"
#include "utils/utils.h"
@@ -1164,6 +1165,7 @@ failed:
*
* \param ctx Selection context to use
* \param node Node to select style for
+ * \param unit_len_ctx Context for length unit conversions.
* \param media Currently active media specification
* \param inline_style Corresponding inline style for node, or NULL
* \param handler Dispatch table of handler functions
@@ -1181,6 +1183,7 @@ failed:
* update the fully computed style for a node when layout changes.
*/
css_error css_select_style(css_select_ctx *ctx, void *node,
+ const css_unit_len_ctx *unit_len_ctx,
const css_media *media, const css_stylesheet *inline_style,
css_select_handler *handler, void *pw,
css_select_results **result)
@@ -1353,7 +1356,7 @@ css_error css_select_style(css_select_ctx *ctx, void *node,
/* Only compute absolute values for the base element */
error = css__compute_absolute_values(NULL,
state.results->styles[CSS_PSEUDO_ELEMENT_NONE],
- handler->compute_font_size, pw);
+ unit_len_ctx);
if (error != CSS_OK)
goto cleanup;
}
diff --git a/src/select/unit.c b/src/select/unit.c
index f9ecf83..a279ec7 100644
--- a/src/select/unit.c
+++ b/src/select/unit.c
@@ -115,14 +115,15 @@ static inline css_fixed css_unit__absolute_len2pt(
}
}
-/* Exported function, documented in unit.h. */
+/* Exported function, documented in libcss/unit.h. */
css_fixed css_unit_font_size_len2pt(
+ const css_computed_style *style,
const css_unit_len_ctx *ctx,
const css_fixed length,
const css_unit unit)
{
return css_unit__absolute_len2pt(
- ctx->ref_style,
+ style,
ctx->viewport_height,
ctx->viewport_width,
length,
@@ -303,15 +304,16 @@ css_fixed css_unit_len2px_mq(
return FMUL(length, TRUNCATEFIX(px_per_unit));
}
-/* Exported function, documented in unit.h. */
+/* Exported function, documented in libcss/unit.h. */
css_fixed css_unit_len2css_px(
+ const css_computed_style *style,
const css_unit_len_ctx *ctx,
const css_fixed length,
const css_unit unit)
{
css_fixed px_per_unit = css_unit__px_per_unit(
ctx->measure,
- ctx->ref_style,
+ style,
ctx->root_style,
ctx->font_size_default,
ctx->font_size_minimum,
@@ -328,15 +330,16 @@ css_fixed css_unit_len2css_px(
return FMUL(length, TRUNCATEFIX(px_per_unit));
}
-/* Exported function, documented in unit.h. */
+/* Exported function, documented in libcss/unit.h. */
css_fixed css_unit_len2device_px(
+ const css_computed_style *style,
const css_unit_len_ctx *ctx,
const css_fixed length,
const css_unit unit)
{
css_fixed px_per_unit = css_unit__px_per_unit(
ctx->measure,
- ctx->ref_style,
+ style,
ctx->root_style,
ctx->font_size_default,
ctx->font_size_minimum,
@@ -361,18 +364,18 @@ css_fixed css_unit_len2device_px(
* The computed style will have font-size with an absolute unit.
* If no computed style is given, the client default font-size will be returned.
*
- * \param[in] ctx Length unit conversion context.
- * \param[in] style The style to get the font-size for, or NULL.
+ * \param[in] style Reference style. (Element or parent, or NULL).
+ * \param[in] font_size_default Client default font size in CSS pixels.
* \return The font size in absolute units.
*/
static inline css_hint_length css_unit__get_font_size(
- const css_unit_len_ctx *ctx,
- const css_computed_style *style)
+ const css_computed_style *style,
+ css_fixed font_size_default)
{
css_hint_length size;
if (style == NULL) {
- size.value = ctx->font_size_default;
+ size.value = font_size_default;
size.unit = CSS_UNIT_PX;
} else {
enum css_font_size_e status = get_font_size(
@@ -391,10 +394,24 @@ static inline css_hint_length css_unit__get_font_size(
/* Exported function, documented in unit.h. */
css_error css_unit_compute_absolute_font_size(
- const css_unit_len_ctx *ctx,
+ const css_hint_length *ref_length,
+ const css_computed_style *root_style,
+ css_fixed font_size_default,
css_hint *size)
{
- css_hint_length ref_len;
+ css_hint_length ref_len = {
+ .value = font_size_default,
+ .unit = CSS_UNIT_PX,
+ };
+
+ if (ref_length != NULL) {
+ /* Must be absolute. */
+ assert(ref_length->unit != CSS_UNIT_EM);
+ assert(ref_length->unit != CSS_UNIT_EX);
+ assert(ref_length->unit != CSS_UNIT_PCT);
+
+ ref_len = *ref_length;
+ }
assert(size->status != CSS_FONT_SIZE_INHERIT);
@@ -420,20 +437,18 @@ css_error css_unit_compute_absolute_font_size(
assert(CSS_FONT_SIZE_XX_SMALL == 1);
size->data.length.value = FMUL(factors[size->status - 1],
- ctx->font_size_default);
+ font_size_default);
size->data.length.unit = CSS_UNIT_PX;
size->status = CSS_FONT_SIZE_DIMENSION;
break;
}
case CSS_FONT_SIZE_LARGER:
- ref_len = css_unit__get_font_size(ctx, ctx->ref_style);
size->data.length.value = FMUL(ref_len.value, FLTTOFIX(1.2));
size->data.length.unit = ref_len.unit;
size->status = CSS_FONT_SIZE_DIMENSION;
break;
case CSS_FONT_SIZE_SMALLER:
- ref_len = css_unit__get_font_size(ctx, ctx->ref_style);
size->data.length.value = FDIV(ref_len.value, FLTTOFIX(1.2));
size->data.length.unit = ref_len.unit;
size->status = CSS_FONT_SIZE_DIMENSION;
@@ -443,9 +458,8 @@ css_error css_unit_compute_absolute_font_size(
/* Convert any relative units to absolute. */
switch (size->data.length.unit) {
case CSS_UNIT_PCT:
- ref_len = css_unit__get_font_size(ctx, ctx->ref_style);
- size->data.length.value = FDIV(
- FMUL(size->data.length.value,
+ size->data.length.value = FDIV(FMUL(
+ size->data.length.value,
ref_len.value), INTTOFIX(100));
size->data.length.unit = ref_len.unit;
break;
@@ -454,11 +468,8 @@ css_error css_unit_compute_absolute_font_size(
case CSS_UNIT_EX: /* Fall-through */
case CSS_UNIT_CH:
/* Parent relative units. */
- ref_len = css_unit__get_font_size(ctx, ctx->ref_style);
-
- size->data.length.unit = ref_len.unit;
- size->data.length.value = FMUL(size->data.length.value,
- ref_len.value);
+ size->data.length.value = FMUL(
+ size->data.length.value, ref_len.value);
switch (size->data.length.unit) {
case CSS_UNIT_EX:
@@ -476,15 +487,17 @@ css_error css_unit_compute_absolute_font_size(
default:
break;
}
+ size->data.length.unit = ref_len.unit;
break;
case CSS_UNIT_REM:
/* Root element relative units. */
- ref_len = css_unit__get_font_size(ctx, ctx->root_style);
+ ref_len = css_unit__get_font_size(root_style,
+ font_size_default);
size->data.length.unit = ref_len.unit;
- size->data.length.value = FMUL(size->data.length.value,
- ref_len.value);
+ size->data.length.value = FMUL(
+ size->data.length.value, ref_len.value);
break;
default:
diff --git a/src/select/unit.h b/src/select/unit.h
index 738c181..e4d21da 100644
--- a/src/select/unit.h
+++ b/src/select/unit.h
@@ -9,138 +9,7 @@
#ifndef css_select_unit_h_
#define css_select_unit_h_
-/**
- * Client callback for font measuring.
- *
- * \param[in] pw Client data.
- * \param[in] style Style to measure font for, or NULL.
- * \param[in] unit Either CSS_UNIT_EX, or CSS_UNIT_CH.
- * \return length in CSS pixels.
- */
-typedef css_fixed (*css_unit_len_measure)(
- void *pw,
- const css_computed_style *style,
- const css_unit unit);
-
-/**
- * LibCSS unit conversion context.
- *
- * The client callback is optional. It is used for measuring "ch"
- * (glyph '0' advance) and "ex" (height of the letter 'x') units.
- * If a NULL pointer is given, LibCSS will use a fixed scaling of
- * the "em" unit.
- */
-typedef struct css_unit_len_ctx {
- /**
- * Viewport width in CSS pixels.
- * Used if unit is vh, vw, vi, vb, vmin, or vmax.
- */
- css_fixed viewport_width;
- /**
- * Viewport height in CSS pixels.
- * Used if unit is vh, vw, vi, vb, vmin, or vmax.
- */
- css_fixed viewport_height;
- /**
- * Client default font size in CSS pixels.
- */
- css_fixed font_size_default;
- /**
- * Client minimum font size in CSS pixels. May be zero.
- */
- css_fixed font_size_minimum;
- /**
- * DPI of the device the style is selected for.
- */
- css_fixed device_dpi;
- /**
- * Reference style. Most of the time, this is the element's style.
- * When converting a length for a typographical property, such as
- * font-size, then this should be the parent node. If the node has
- * no parent then this may be NULL.
- */
- const css_computed_style *ref_style;
- /**
- * Computed style for the document root element.
- * May be NULL if unit is not rem.
- */
- const css_computed_style *root_style;
- /**
- * Client private word for measure callback.
- */
- void *pw;
- /**
- * Client callback for font measuring.
- */
- const css_unit_len_measure measure;
-} css_unit_len_ctx;
-
-/**
- * Convert css pixels to physical pixels.
- *
- * \param[in] css_pixels Length in css pixels.
- * \param[in] device_dpi Device dots per inch.
- * \return Length in device pixels.
- */
-static inline css_fixed css_unit_css2device_px(
- const css_fixed css_pixels,
- const css_fixed device_dpi)
-{
- return FDIV(FMUL(css_pixels, device_dpi), F_96);
-}
-
-/**
- * Convert device pixels to css pixels.
- *
- * \param[in] device_pixels Length in physical pixels.
- * \param[in] device_dpi Device dots per inch.
- * \return Length in css pixels.
- */
-static inline css_fixed css_unit_device2css_px(
- const css_fixed device_pixels,
- const css_fixed device_dpi)
-{
- return FDIV(FMUL(device_pixels, F_96), device_dpi);
-}
-
-/**
- * Convert a length to points (pt).
- *
- * \param[in] ctx Length unit conversion context.
- * \param[in] length Length to convert.
- * \param[in] unit Current unit of length.
- * \return A length in points.
- */
-css_fixed css_unit_font_size_len2pt(
- const css_unit_len_ctx *ctx,
- const css_fixed length,
- const css_unit unit);
-
-/**
- * Convert a length to CSS pixels.
- *
- * \param[in] ctx Length unit conversion context.
- * \param[in] length Length to convert.
- * \param[in] unit Current unit of length.
- * \return A length in CSS pixels.
- */
-css_fixed css_unit_len2css_px(
- const css_unit_len_ctx *ctx,
- const css_fixed length,
- const css_unit unit);
-
-/**
- * Convert a length to device pixels.
- *
- * \param[in] ctx Length unit conversion context.
- * \param[in] length Length to convert.
- * \param[in] unit Current unit of length.
- * \return A length in device pixels.
- */
-css_fixed css_unit_len2device_px(
- const css_unit_len_ctx *ctx,
- const css_fixed length,
- const css_unit unit);
+#include <libcss/unit.h>
/**
* Convert a length to CSS pixels for a media query context.
@@ -158,12 +27,16 @@ css_fixed css_unit_len2px_mq(
/**
* Convert relative font size units to absolute units.
*
- * \param[in] ctx Length unit conversion context.
- * \param[in,out] size The length to convert.
+ * \param[in] ref_length Reference font-size length or NULL.
+ * \param[in] root_style Root element style or NULL.
+ * \param[in] font_size_default Client default font size in CSS pixels.
+ * \param[in,out] size The length to convert.
* \return CSS_OK on success, or appropriate error otherwise.
*/
css_error css_unit_compute_absolute_font_size(
- const css_unit_len_ctx *ctx,
+ const css_hint_length *ref_length,
+ const css_computed_style *root_style,
+ css_fixed font_size_default,
css_hint *size);
#endif
diff --git a/test/data/select/tests1.dat b/test/data/select/tests1.dat
index ccce94d..919ca88 100644
--- a/test/data/select/tests1.dat
+++ b/test/data/select/tests1.dat
@@ -59,7 +59,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -173,7 +173,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -291,7 +291,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -410,7 +410,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -529,7 +529,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -648,7 +648,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -757,7 +757,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -867,7 +867,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -977,7 +977,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -1086,7 +1086,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -1200,7 +1200,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -1314,7 +1314,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -1429,7 +1429,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -1547,7 +1547,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -1664,7 +1664,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -1787,7 +1787,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -1910,7 +1910,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -2033,7 +2033,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -2160,7 +2160,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -2286,7 +2286,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -2410,7 +2410,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -2533,7 +2533,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -2656,7 +2656,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -2779,7 +2779,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -2902,7 +2902,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -3025,7 +3025,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -3148,7 +3148,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -3271,7 +3271,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -3394,7 +3394,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -3517,7 +3517,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -3640,7 +3640,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 10.600pt
+font-size: 13.342px
font-style: normal
font-variant: normal
font-weight: normal
@@ -3763,7 +3763,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 14.391pt
+font-size: 19.187px
font-style: normal
font-variant: normal
font-weight: normal
@@ -3886,7 +3886,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 24pt
+font-size: 32px
font-style: normal
font-variant: normal
font-weight: normal
@@ -4009,7 +4009,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 18pt
+font-size: 24px
font-style: normal
font-variant: normal
font-weight: normal
@@ -4132,7 +4132,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 13.500pt
+font-size: 18px
font-style: normal
font-variant: normal
font-weight: normal
@@ -4255,7 +4255,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -4378,7 +4378,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 9.750pt
+font-size: 13px
font-style: normal
font-variant: normal
font-weight: normal
@@ -4501,7 +4501,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 7.500pt
+font-size: 10px
font-style: normal
font-variant: normal
font-weight: normal
@@ -4624,7 +4624,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 6.750pt
+font-size: 9px
font-style: normal
font-variant: normal
font-weight: normal
@@ -4870,7 +4870,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -4986,7 +4986,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -5102,7 +5102,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -5218,7 +5218,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -5331,7 +5331,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -5445,7 +5445,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -5559,7 +5559,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -5673,7 +5673,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -5783,7 +5783,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -5894,7 +5894,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -6004,7 +6004,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -6114,7 +6114,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -6224,7 +6224,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -6334,7 +6334,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -6444,7 +6444,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -6556,7 +6556,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -6666,7 +6666,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -6776,7 +6776,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -6887,7 +6887,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -6997,7 +6997,7 @@ flex-shrink: 3.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -7107,7 +7107,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -7217,7 +7217,7 @@ flex-shrink: 0.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -7327,7 +7327,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -7437,7 +7437,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -7547,7 +7547,7 @@ flex-shrink: 0.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -7657,7 +7657,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -7766,7 +7766,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -7875,7 +7875,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -7984,7 +7984,7 @@ flex-shrink: 30.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -8095,7 +8095,7 @@ flex-shrink: 3.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -8206,7 +8206,7 @@ flex-shrink: 3.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -8315,7 +8315,7 @@ flex-shrink: 0.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -8426,7 +8426,7 @@ flex-shrink: 0.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -8537,7 +8537,7 @@ flex-shrink: 3.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -8648,7 +8648,7 @@ flex-shrink: 3.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -8757,7 +8757,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -8866,7 +8866,7 @@ flex-shrink: 1.000
flex-wrap: wrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -8975,7 +8975,7 @@ flex-shrink: 1.000
flex-wrap: wrap-reverse
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -9084,7 +9084,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -9193,7 +9193,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -9302,7 +9302,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -9411,7 +9411,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -9520,7 +9520,7 @@ flex-shrink: 1.000
flex-wrap: wrap-reverse
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -9631,7 +9631,7 @@ flex-shrink: 1.000
flex-wrap: wrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -9742,7 +9742,7 @@ flex-shrink: 1.000
flex-wrap: wrap-reverse
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -9851,7 +9851,7 @@ flex-shrink: 0.899
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -9960,7 +9960,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -10069,7 +10069,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -10178,7 +10178,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -10287,7 +10287,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -10396,7 +10396,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -10505,7 +10505,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -10616,7 +10616,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -10727,7 +10727,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -10836,7 +10836,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -10945,7 +10945,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -11054,7 +11054,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -11165,7 +11165,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -11274,7 +11274,7 @@ flex-shrink: 3.780
flex-wrap: wrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -11385,7 +11385,7 @@ flex-shrink: 3.780
flex-wrap: wrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -11494,7 +11494,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -11603,7 +11603,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -11712,7 +11712,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -11821,7 +11821,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -11930,7 +11930,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -12039,7 +12039,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -12148,7 +12148,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -12257,7 +12257,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -12366,7 +12366,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -12475,7 +12475,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -12584,7 +12584,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -12693,7 +12693,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -12802,7 +12802,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -12911,7 +12911,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -13020,7 +13020,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -13129,7 +13129,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -13238,7 +13238,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -13347,7 +13347,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -13456,7 +13456,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -13565,7 +13565,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -13674,7 +13674,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -13783,7 +13783,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -13892,7 +13892,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -14020,7 +14020,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
diff --git a/test/select.c b/test/select.c
index 664994e..8226a8b 100644
--- a/test/select.c
+++ b/test/select.c
@@ -159,13 +159,15 @@ static css_error node_presentational_hint(void *pw, void *node,
uint32_t *nhints, css_hint **hints);
static css_error ua_default_for_property(void *pw, uint32_t property,
css_hint *hints);
-static css_error compute_font_size(void *pw, const css_hint *parent,
- css_hint *size);
static css_error set_libcss_node_data(void *pw, void *n,
void *libcss_node_data);
static css_error get_libcss_node_data(void *pw, void *n,
void **libcss_node_data);
+static css_unit_len_ctx unit_len_ctx = {
+ .font_size_default = 16 * (1 << CSS_RADIX_POINT),
+};
+
static css_select_handler select_handler = {
CSS_SELECT_HANDLER_VERSION_1,
@@ -203,9 +205,9 @@ static css_select_handler select_handler = {
node_is_lang,
node_presentational_hint,
ua_default_for_property,
- compute_font_size,
+
set_libcss_node_data,
- get_libcss_node_data
+ get_libcss_node_data,
};
static css_error resolve_url(void *pw,
@@ -765,7 +767,12 @@ static void run_test_select_tree(css_select_ctx *select,
css_select_results *sr;
struct node *n = NULL;
- assert(css_select_style(select, node, &ctx->media, NULL,
+ if (node->parent == NULL) {
+ unit_len_ctx.root_style = NULL;
+ }
+
+
+ assert(css_select_style(select, node, &unit_len_ctx, &ctx->media, NULL,
&select_handler, ctx, &sr) == CSS_OK);
if (node->parent != NULL) {
@@ -773,7 +780,7 @@ static void run_test_select_tree(css_select_ctx *select,
assert(css_computed_style_compose(
node->parent->sr->styles[ctx->pseudo_element],
sr->styles[ctx->pseudo_element],
- compute_font_size, NULL,
+ &unit_len_ctx,
&composed) == CSS_OK);
css_computed_style_destroy(sr->styles[ctx->pseudo_element]);
sr->styles[ctx->pseudo_element] = composed;
@@ -786,6 +793,10 @@ static void run_test_select_tree(css_select_ctx *select,
buf, buflen);
}
+ if (node->parent == NULL) {
+ unit_len_ctx.root_style = node->sr->styles[ctx->pseudo_element];
+ }
+
for (n = node->children; n != NULL; n = n->next) {
run_test_select_tree(select, n, ctx, buf, buflen);
}
@@ -1606,68 +1617,6 @@ css_error ua_default_for_property(void *pw, uint32_t property, css_hint *hint)
return CSS_OK;
}
-css_error compute_font_size(void *pw, const css_hint *parent, css_hint *size)
-{
- static css_hint_length sizes[] = {
- { FLTTOFIX(6.75), CSS_UNIT_PT },
- { FLTTOFIX(7.50), CSS_UNIT_PT },
- { FLTTOFIX(9.75), CSS_UNIT_PT },
- { FLTTOFIX(12.0), CSS_UNIT_PT },
- { FLTTOFIX(13.5), CSS_UNIT_PT },
- { FLTTOFIX(18.0), CSS_UNIT_PT },
- { FLTTOFIX(24.0), CSS_UNIT_PT }
- };
- const css_hint_length *parent_size;
-
- UNUSED(pw);
-
- /* Grab parent size, defaulting to medium if none */
- if (parent == NULL) {
- parent_size = &sizes[CSS_FONT_SIZE_MEDIUM - 1];
- } else {
- assert(parent->status == CSS_FONT_SIZE_DIMENSION);
- assert(parent->data.length.unit != CSS_UNIT_EM);
- assert(parent->data.length.unit != CSS_UNIT_EX);
- parent_size = &parent->data.length;
- }
-
- assert(size->status != CSS_FONT_SIZE_INHERIT);
-
- if (size->status < CSS_FONT_SIZE_LARGER) {
- /* Keyword -- simple */
- size->data.length = sizes[size->status - 1];
- } else if (size->status == CSS_FONT_SIZE_LARGER) {
- /** \todo Step within table, if appropriate */
- size->data.length.value =
- FMUL(parent_size->value, FLTTOFIX(1.2));
- size->data.length.unit = parent_size->unit;
- } else if (size->status == CSS_FONT_SIZE_SMALLER) {
- /** \todo Step within table, if appropriate */
- size->data.length.value =
- FDIV(parent_size->value, FLTTOFIX(1.2));
- size->data.length.unit = parent_size->unit;
- } else if (size->data.length.unit == CSS_UNIT_EM ||
- size->data.length.unit == CSS_UNIT_EX) {
- size->data.length.value =
- FMUL(size->data.length.value, parent_size->value);
-
- if (size->data.length.unit == CSS_UNIT_EX) {
- size->data.length.value = FMUL(size->data.length.value,
- FLTTOFIX(0.6));
- }
-
- size->data.length.unit = parent_size->unit;
- } else if (size->data.length.unit == CSS_UNIT_PCT) {
- size->data.length.value = FDIV(FMUL(size->data.length.value,
- parent_size->value), FLTTOFIX(100));
- size->data.length.unit = parent_size->unit;
- }
-
- size->status = CSS_FONT_SIZE_DIMENSION;
-
- return CSS_OK;
-}
-
static css_error set_libcss_node_data(void *pw, void *n,
void *libcss_node_data)
{
commitdiff http://git.netsurf-browser.org/libcss.git/commit/?id=9db93fe7a99c757c5065...
commit 9db93fe7a99c757c5065d2a6c9738cffa269378e
Author: Michael Drake <Michael Drake tlsa(a)netsurf-browser.org>
Commit: Michael Drake <Michael Drake tlsa(a)netsurf-browser.org>
Units: Add support for length unit conversion to libcss.
Currently only used for unit conversion.
diff --git a/src/select/Makefile b/src/select/Makefile
index 8b47673..f5ddb18 100644
--- a/src/select/Makefile
+++ b/src/select/Makefile
@@ -2,6 +2,6 @@
select_generator:
python3 src/select/select_generator.py
-DIR_SOURCES := arena.c computed.c dispatch.c hash.c select.c font_face.c format_list_style.c
+DIR_SOURCES := arena.c computed.c dispatch.c hash.c select.c font_face.c format_list_style.c unit.c
include $(NSBUILD)/Makefile.subdir
diff --git a/src/select/hash.c b/src/select/hash.c
index 4b11702..4dedec9 100644
--- a/src/select/hash.c
+++ b/src/select/hash.c
@@ -8,6 +8,8 @@
#include <stdio.h>
#include <string.h>
+#include <libcss/hint.h>
+
#include "stylesheet.h"
#include "select/hash.h"
#include "select/mq.h"
diff --git a/src/select/mq.h b/src/select/mq.h
index 6f98387..080a6ba 100644
--- a/src/select/mq.h
+++ b/src/select/mq.h
@@ -10,96 +10,7 @@
#define css_select_mq_h_
#include "select/helpers.h"
-
-static inline css_fixed css_len2px(
- css_fixed length,
- css_unit unit,
- const css_media *media)
-{
- css_fixed px_per_unit;
-
- switch (unit) {
- case CSS_UNIT_VI:
- /* TODO: Assumes writing mode. */
- unit = CSS_UNIT_VW;
- break;
- case CSS_UNIT_VB:
- /* TODO: Assumes writing mode. */
- unit = CSS_UNIT_VH;
- break;
- case CSS_UNIT_VMIN:
- unit = (media->height < media->width) ?
- CSS_UNIT_VH : CSS_UNIT_VW;
- break;
- case CSS_UNIT_VMAX:
- unit = (media->width > media->height) ?
- CSS_UNIT_VH : CSS_UNIT_VW;
- break;
- default:
- break;
- }
-
- switch (unit) {
- case CSS_UNIT_EM:
- case CSS_UNIT_EX:
- case CSS_UNIT_CH:
- {
- px_per_unit = FDIV(FMUL(media->client_font_size, F_96), F_72);
-
- /* TODO: Handling these as fixed ratios of CSS_UNIT_EM. */
- switch (unit) {
- case CSS_UNIT_EX:
- px_per_unit = FMUL(px_per_unit, FLTTOFIX(0.6));
- break;
- case CSS_UNIT_CH:
- px_per_unit = FMUL(px_per_unit, FLTTOFIX(0.4));
- break;
- default:
- break;
- }
- }
- break;
- case CSS_UNIT_PX:
- return length;
- case CSS_UNIT_IN:
- px_per_unit = F_96;
- break;
- case CSS_UNIT_CM:
- px_per_unit = FDIV(F_96, FLTTOFIX(2.54));
- break;
- case CSS_UNIT_MM:
- px_per_unit = FDIV(F_96, FLTTOFIX(25.4));
- break;
- case CSS_UNIT_Q:
- px_per_unit = FDIV(F_96, FLTTOFIX(101.6));
- break;
- case CSS_UNIT_PT:
- px_per_unit = FDIV(F_96, F_72);
- break;
- case CSS_UNIT_PC:
- px_per_unit = FDIV(F_96, INTTOFIX(6));
- break;
- case CSS_UNIT_REM:
- px_per_unit = FDIV(FMUL(media->client_font_size, F_96), F_72);
- break;
- case CSS_UNIT_VH:
- px_per_unit = FDIV(media->height, F_100);
- break;
- case CSS_UNIT_VW:
- px_per_unit = FDIV(media->width, F_100);
- break;
- default:
- px_per_unit = 0;
- break;
- }
-
- /* Ensure we round px_per_unit to the nearest whole number of pixels:
- * the use of FIXTOINT() below will truncate. */
- px_per_unit += F_0_5;
-
- /* Calculate total number of pixels */
- return FMUL(length, TRUNCATEFIX(px_per_unit));
-}
+#include "select/unit.h"
static inline bool mq_match_feature_range_length_op1(
css_mq_feature_op op,
@@ -114,9 +25,9 @@ static inline bool mq_match_feature_range_length_op1(
}
if (value->data.dim.unit != UNIT_PX) {
- v = css_len2px(value->data.dim.len,
- css__to_css_unit(value->data.dim.unit),
- media);
+ v = css_unit_len2px_mq(media,
+ value->data.dim.len,
+ css__to_css_unit(value->data.dim.unit));
} else {
v = value->data.dim.len;
}
@@ -149,9 +60,9 @@ static inline bool mq_match_feature_range_length_op2(
}
if (value->data.dim.unit != UNIT_PX) {
- v = css_len2px(value->data.dim.len,
- css__to_css_unit(value->data.dim.unit),
- media);
+ v = css_unit_len2px_mq(media,
+ value->data.dim.len,
+ css__to_css_unit(value->data.dim.unit));
} else {
v = value->data.dim.len;
}
diff --git a/src/select/unit.c b/src/select/unit.c
new file mode 100644
index 0000000..f9ecf83
--- /dev/null
+++ b/src/select/unit.c
@@ -0,0 +1,498 @@
+/*
+ * This file is part of LibCSS
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ * Copyright 2021 Michael Drake <tlsa(a)netsurf-browser.org>
+ */
+
+#include <libcss/stylesheet.h>
+
+#include "utils/utils.h"
+
+#include "propget.h"
+#include "unit.h"
+
+/**
+ * Map viewport-relative length units to either vh or vw.
+ *
+ * Non-viewport-relative units are unchanged.
+ *
+ * \param[in] style Reference style.
+ * \param[in] viewport_height Viewport height in px.
+ * \param[in] viewport_width Viewport width in px.
+ * \param[in] unit Unit to map.
+ * \return the mapped unit.
+ */
+static inline css_unit css_unit__map_viewport_units(
+ const css_computed_style *style,
+ const css_fixed viewport_height,
+ const css_fixed viewport_width,
+ const css_unit unit)
+{
+ switch (unit) {
+ case CSS_UNIT_VI:
+ return (style != NULL && get_writing_mode(style) !=
+ CSS_WRITING_MODE_HORIZONTAL_TB) ?
+ CSS_UNIT_VH : CSS_UNIT_VW;
+
+ case CSS_UNIT_VB:
+ return (style != NULL && get_writing_mode(style) !=
+ CSS_WRITING_MODE_HORIZONTAL_TB) ?
+ CSS_UNIT_VW : CSS_UNIT_VH;
+
+ case CSS_UNIT_VMIN:
+ return (viewport_height < viewport_width) ?
+ CSS_UNIT_VH : CSS_UNIT_VW;
+
+ case CSS_UNIT_VMAX:
+ return (viewport_height > viewport_width) ?
+ CSS_UNIT_VH : CSS_UNIT_VW;
+
+ default:
+ return unit;
+ }
+}
+
+/**
+ * Convert an absolute length to points (pt).
+ *
+ * \param[in] style Style to get font-size from, or NULL.
+ * \param[in] viewport_height Client viewport height.
+ * \param[in] viewport_width Client viewport width.
+ * \param[in] length Length to convert.
+ * \param[in] unit Current unit of length.
+ * \return length in points (pt).
+ */
+static inline css_fixed css_unit__absolute_len2pt(
+ const css_computed_style *style,
+ const css_fixed viewport_height,
+ const css_fixed viewport_width,
+ const css_fixed length,
+ const css_unit unit)
+{
+ /* Length must not be relative */
+ assert(unit != CSS_UNIT_EM &&
+ unit != CSS_UNIT_EX &&
+ unit != CSS_UNIT_CH &&
+ unit != CSS_UNIT_REM);
+
+ switch (css_unit__map_viewport_units(style,
+ viewport_height,
+ viewport_width,
+ unit)) {
+ case CSS_UNIT_PX:
+ return FDIV(FMUL(length, F_72), F_96);
+
+ case CSS_UNIT_IN:
+ return FMUL(length, F_72);
+
+ case CSS_UNIT_CM:
+ return FMUL(length, FDIV(F_72, FLTTOFIX(2.54)));
+
+ case CSS_UNIT_MM:
+ return FMUL(length, FDIV(F_72, FLTTOFIX(25.4)));
+
+ case CSS_UNIT_Q:
+ return FMUL(length, FDIV(F_72, FLTTOFIX(101.6)));
+
+ case CSS_UNIT_PT:
+ return length;
+
+ case CSS_UNIT_PC:
+ return FMUL(length, INTTOFIX(12));
+
+ case CSS_UNIT_VH:
+ return FDIV(FMUL(FDIV(FMUL(length, viewport_height), F_100),
+ F_72), F_96);
+
+ case CSS_UNIT_VW:
+ return FDIV(FMUL(FDIV(FMUL(length, viewport_width), F_100),
+ F_72), F_96);
+
+ default:
+ return 0;
+ }
+}
+
+/* Exported function, documented in unit.h. */
+css_fixed css_unit_font_size_len2pt(
+ const css_unit_len_ctx *ctx,
+ const css_fixed length,
+ const css_unit unit)
+{
+ return css_unit__absolute_len2pt(
+ ctx->ref_style,
+ ctx->viewport_height,
+ ctx->viewport_width,
+ length,
+ unit);
+}
+
+/**
+ * Get font size from a style in CSS pixels.
+ *
+ * The style should have font size in absolute units.
+ *
+ * \param[in] style Style to get font-size from, or NULL.
+ * \param[in] font_size_default Client font size for NULL style.
+ * \param[in] font_size_minimum Client minimum font size clamp.
+ * \param[in] viewport_height Client viewport height.
+ * \param[in] viewport_width Client viewport width.
+ * \return font-size in CSS pixels.
+ */
+static inline css_fixed css_unit__font_size_px(
+ const css_computed_style *style,
+ const css_fixed font_size_default,
+ const css_fixed font_size_minimum,
+ const css_fixed viewport_height,
+ const css_fixed viewport_width)
+{
+ css_fixed font_length = 0;
+ css_unit font_unit = CSS_UNIT_PT;
+
+ if (style == NULL) {
+ return font_size_default;
+ }
+
+ get_font_size(style, &font_length, &font_unit);
+
+ if (font_unit != CSS_UNIT_PX) {
+ font_length = css_unit__absolute_len2pt(style,
+ viewport_height,
+ viewport_width,
+ font_length,
+ font_unit);
+
+ /* Convert from pt to CSS pixels.*/
+ font_length = FDIV(FMUL(font_length, F_96), F_72);
+ }
+
+ /* Clamp to configured minimum */
+ if (font_length < font_size_minimum) {
+ font_length = font_size_minimum;
+ }
+
+ return font_length;
+}
+
+/**
+ * Get the number of CSS pixels for a given unit.
+ *
+ * \param[in] measure Client callback for font measuring.
+ * \param[in] ref_style Reference style. (Element or parent, or NULL).
+ * \param[in] root_style Root element style or NULL.
+ * \param[in] font_size_default Client default font size in CSS pixels.
+ * \param[in] font_size_minimum Client minimum font size in CSS pixels.
+ * \param[in] viewport_height Viewport height in CSS pixels.
+ * \param[in] viewport_width Viewport width in CSS pixels.
+ * \param[in] unit The unit to convert from.
+ * \param[in] pw Client private word for measure callback.
+ * \return Number of CSS pixels equivalent to the given unit.
+ */
+static inline css_fixed css_unit__px_per_unit(
+ const css_unit_len_measure measure,
+ const css_computed_style *ref_style,
+ const css_computed_style *root_style,
+ const css_fixed font_size_default,
+ const css_fixed font_size_minimum,
+ const css_fixed viewport_height,
+ const css_fixed viewport_width,
+ const css_unit unit,
+ void *pw)
+{
+ switch (css_unit__map_viewport_units(
+ ref_style,
+ viewport_height,
+ viewport_width,
+ unit)) {
+ case CSS_UNIT_EM:
+ return css_unit__font_size_px(
+ ref_style,
+ font_size_default,
+ font_size_minimum,
+ viewport_height,
+ viewport_width);
+
+ case CSS_UNIT_EX:
+ if (measure != NULL) {
+ return measure(pw, ref_style, CSS_UNIT_EX);
+ }
+ return FMUL(css_unit__font_size_px(
+ ref_style,
+ font_size_default,
+ font_size_minimum,
+ viewport_height,
+ viewport_width), FLTTOFIX(0.6));
+
+ case CSS_UNIT_CH:
+ if (measure != NULL) {
+ return measure(pw, ref_style, CSS_UNIT_CH);
+ }
+ return FMUL(css_unit__font_size_px(
+ ref_style,
+ font_size_default,
+ font_size_minimum,
+ viewport_height,
+ viewport_width), FLTTOFIX(0.4));
+
+ case CSS_UNIT_PX:
+ return F_1;
+
+ case CSS_UNIT_IN:
+ return F_96;
+
+ case CSS_UNIT_CM:
+ return FDIV(F_96, FLTTOFIX(2.54));
+
+ case CSS_UNIT_MM:
+ return FDIV(F_96, FLTTOFIX(25.4));
+
+ case CSS_UNIT_Q:
+ return FDIV(F_96, FLTTOFIX(101.6));
+
+ case CSS_UNIT_PT:
+ return FDIV(F_96, F_72);
+
+ case CSS_UNIT_PC:
+ return FDIV(F_96, INTTOFIX(6));
+
+ case CSS_UNIT_REM:
+ return css_unit__font_size_px(
+ root_style,
+ font_size_default,
+ font_size_minimum,
+ viewport_height,
+ viewport_width);
+
+ case CSS_UNIT_VH:
+ return FDIV(viewport_width, F_100);
+
+ case CSS_UNIT_VW:
+ return FDIV(viewport_height, F_100);
+
+ default:
+ return 0;
+ }
+}
+
+/* Exported function, documented in unit.h. */
+css_fixed css_unit_len2px_mq(
+ const css_media *media,
+ const css_fixed length,
+ const css_unit unit)
+{
+ /* In the media query context there is no reference or root element
+ * style, so these are hardcoded to NULL. */
+ css_fixed px_per_unit = css_unit__px_per_unit(
+ NULL,
+ NULL,
+ NULL,
+ media->client_font_size,
+ INTTOFIX(0),
+ media->height,
+ media->width,
+ unit,
+ NULL);
+
+ /* Ensure we round px_per_unit to the nearest whole number of pixels:
+ * the use of FIXTOINT() below will truncate. */
+ px_per_unit += F_0_5;
+
+ /* Calculate total number of pixels */
+ return FMUL(length, TRUNCATEFIX(px_per_unit));
+}
+
+/* Exported function, documented in unit.h. */
+css_fixed css_unit_len2css_px(
+ const css_unit_len_ctx *ctx,
+ const css_fixed length,
+ const css_unit unit)
+{
+ css_fixed px_per_unit = css_unit__px_per_unit(
+ ctx->measure,
+ ctx->ref_style,
+ ctx->root_style,
+ ctx->font_size_default,
+ ctx->font_size_minimum,
+ ctx->viewport_height,
+ ctx->viewport_width,
+ unit,
+ ctx->pw);
+
+ /* Ensure we round px_per_unit to the nearest whole number of pixels:
+ * the use of FIXTOINT() below will truncate. */
+ px_per_unit += F_0_5;
+
+ /* Calculate total number of pixels */
+ return FMUL(length, TRUNCATEFIX(px_per_unit));
+}
+
+/* Exported function, documented in unit.h. */
+css_fixed css_unit_len2device_px(
+ const css_unit_len_ctx *ctx,
+ const css_fixed length,
+ const css_unit unit)
+{
+ css_fixed px_per_unit = css_unit__px_per_unit(
+ ctx->measure,
+ ctx->ref_style,
+ ctx->root_style,
+ ctx->font_size_default,
+ ctx->font_size_minimum,
+ ctx->viewport_height,
+ ctx->viewport_width,
+ unit,
+ ctx->pw);
+
+ px_per_unit = css_unit_css2device_px(px_per_unit, ctx->device_dpi);
+
+ /* Ensure we round px_per_unit to the nearest whole number of pixels:
+ * the use of FIXTOINT() below will truncate. */
+ px_per_unit += F_0_5;
+
+ /* Calculate total number of pixels */
+ return FMUL(length, TRUNCATEFIX(px_per_unit));
+}
+
+/**
+ * Get font size from a computed style.
+ *
+ * The computed style will have font-size with an absolute unit.
+ * If no computed style is given, the client default font-size will be returned.
+ *
+ * \param[in] ctx Length unit conversion context.
+ * \param[in] style The style to get the font-size for, or NULL.
+ * \return The font size in absolute units.
+ */
+static inline css_hint_length css_unit__get_font_size(
+ const css_unit_len_ctx *ctx,
+ const css_computed_style *style)
+{
+ css_hint_length size;
+
+ if (style == NULL) {
+ size.value = ctx->font_size_default;
+ size.unit = CSS_UNIT_PX;
+ } else {
+ enum css_font_size_e status = get_font_size(
+ style, &size.value, &size.unit);
+
+ UNUSED(status);
+
+ assert(status == CSS_FONT_SIZE_DIMENSION);
+ assert(size.unit != CSS_UNIT_EM);
+ assert(size.unit != CSS_UNIT_EX);
+ assert(size.unit != CSS_UNIT_PCT);
+ }
+
+ return size;
+}
+
+/* Exported function, documented in unit.h. */
+css_error css_unit_compute_absolute_font_size(
+ const css_unit_len_ctx *ctx,
+ css_hint *size)
+{
+ css_hint_length ref_len;
+
+ assert(size->status != CSS_FONT_SIZE_INHERIT);
+
+ switch (size->status) {
+ case CSS_FONT_SIZE_XX_SMALL: /* Fall-through. */
+ case CSS_FONT_SIZE_X_SMALL: /* Fall-through. */
+ case CSS_FONT_SIZE_SMALL: /* Fall-through. */
+ case CSS_FONT_SIZE_MEDIUM: /* Fall-through. */
+ case CSS_FONT_SIZE_LARGE: /* Fall-through. */
+ case CSS_FONT_SIZE_X_LARGE: /* Fall-through. */
+ case CSS_FONT_SIZE_XX_LARGE:
+ {
+ static const css_fixed factors[CSS_FONT_SIZE_XX_LARGE] = {
+ [CSS_FONT_SIZE_XX_SMALL - 1] = FLTTOFIX(0.5625),
+ [CSS_FONT_SIZE_X_SMALL - 1] = FLTTOFIX(0.6250),
+ [CSS_FONT_SIZE_SMALL - 1] = FLTTOFIX(0.8125),
+ [CSS_FONT_SIZE_MEDIUM - 1] = FLTTOFIX(1.0000),
+ [CSS_FONT_SIZE_LARGE - 1] = FLTTOFIX(1.1250),
+ [CSS_FONT_SIZE_X_LARGE - 1] = FLTTOFIX(1.5000),
+ [CSS_FONT_SIZE_XX_LARGE - 1] = FLTTOFIX(2.0000),
+ };
+ assert(CSS_FONT_SIZE_INHERIT == 0);
+ assert(CSS_FONT_SIZE_XX_SMALL == 1);
+
+ size->data.length.value = FMUL(factors[size->status - 1],
+ ctx->font_size_default);
+ size->data.length.unit = CSS_UNIT_PX;
+ size->status = CSS_FONT_SIZE_DIMENSION;
+ break;
+ }
+ case CSS_FONT_SIZE_LARGER:
+ ref_len = css_unit__get_font_size(ctx, ctx->ref_style);
+ size->data.length.value = FMUL(ref_len.value, FLTTOFIX(1.2));
+ size->data.length.unit = ref_len.unit;
+ size->status = CSS_FONT_SIZE_DIMENSION;
+ break;
+
+ case CSS_FONT_SIZE_SMALLER:
+ ref_len = css_unit__get_font_size(ctx, ctx->ref_style);
+ size->data.length.value = FDIV(ref_len.value, FLTTOFIX(1.2));
+ size->data.length.unit = ref_len.unit;
+ size->status = CSS_FONT_SIZE_DIMENSION;
+ break;
+
+ case CSS_FONT_SIZE_DIMENSION:
+ /* Convert any relative units to absolute. */
+ switch (size->data.length.unit) {
+ case CSS_UNIT_PCT:
+ ref_len = css_unit__get_font_size(ctx, ctx->ref_style);
+ size->data.length.value = FDIV(
+ FMUL(size->data.length.value,
+ ref_len.value), INTTOFIX(100));
+ size->data.length.unit = ref_len.unit;
+ break;
+
+ case CSS_UNIT_EM: /* Fall-through */
+ case CSS_UNIT_EX: /* Fall-through */
+ case CSS_UNIT_CH:
+ /* Parent relative units. */
+ ref_len = css_unit__get_font_size(ctx, ctx->ref_style);
+
+ size->data.length.unit = ref_len.unit;
+ size->data.length.value = FMUL(size->data.length.value,
+ ref_len.value);
+
+ switch (size->data.length.unit) {
+ case CSS_UNIT_EX:
+ size->data.length.value = FMUL(
+ size->data.length.value,
+ FLTTOFIX(0.6));
+ break;
+
+ case CSS_UNIT_CH:
+ size->data.length.value = FMUL(
+ size->data.length.value,
+ FLTTOFIX(0.4));
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case CSS_UNIT_REM:
+ /* Root element relative units. */
+ ref_len = css_unit__get_font_size(ctx, ctx->root_style);
+
+ size->data.length.unit = ref_len.unit;
+ size->data.length.value = FMUL(size->data.length.value,
+ ref_len.value);
+ break;
+
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+
+ return CSS_OK;
+}
diff --git a/src/select/unit.h b/src/select/unit.h
new file mode 100644
index 0000000..738c181
--- /dev/null
+++ b/src/select/unit.h
@@ -0,0 +1,169 @@
+/*
+ * This file is part of LibCSS
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ * Copyright 2021 Michael Drake <tlsa(a)netsurf-browser.org>
+ */
+
+#ifndef css_select_unit_h_
+#define css_select_unit_h_
+
+/**
+ * Client callback for font measuring.
+ *
+ * \param[in] pw Client data.
+ * \param[in] style Style to measure font for, or NULL.
+ * \param[in] unit Either CSS_UNIT_EX, or CSS_UNIT_CH.
+ * \return length in CSS pixels.
+ */
+typedef css_fixed (*css_unit_len_measure)(
+ void *pw,
+ const css_computed_style *style,
+ const css_unit unit);
+
+/**
+ * LibCSS unit conversion context.
+ *
+ * The client callback is optional. It is used for measuring "ch"
+ * (glyph '0' advance) and "ex" (height of the letter 'x') units.
+ * If a NULL pointer is given, LibCSS will use a fixed scaling of
+ * the "em" unit.
+ */
+typedef struct css_unit_len_ctx {
+ /**
+ * Viewport width in CSS pixels.
+ * Used if unit is vh, vw, vi, vb, vmin, or vmax.
+ */
+ css_fixed viewport_width;
+ /**
+ * Viewport height in CSS pixels.
+ * Used if unit is vh, vw, vi, vb, vmin, or vmax.
+ */
+ css_fixed viewport_height;
+ /**
+ * Client default font size in CSS pixels.
+ */
+ css_fixed font_size_default;
+ /**
+ * Client minimum font size in CSS pixels. May be zero.
+ */
+ css_fixed font_size_minimum;
+ /**
+ * DPI of the device the style is selected for.
+ */
+ css_fixed device_dpi;
+ /**
+ * Reference style. Most of the time, this is the element's style.
+ * When converting a length for a typographical property, such as
+ * font-size, then this should be the parent node. If the node has
+ * no parent then this may be NULL.
+ */
+ const css_computed_style *ref_style;
+ /**
+ * Computed style for the document root element.
+ * May be NULL if unit is not rem.
+ */
+ const css_computed_style *root_style;
+ /**
+ * Client private word for measure callback.
+ */
+ void *pw;
+ /**
+ * Client callback for font measuring.
+ */
+ const css_unit_len_measure measure;
+} css_unit_len_ctx;
+
+/**
+ * Convert css pixels to physical pixels.
+ *
+ * \param[in] css_pixels Length in css pixels.
+ * \param[in] device_dpi Device dots per inch.
+ * \return Length in device pixels.
+ */
+static inline css_fixed css_unit_css2device_px(
+ const css_fixed css_pixels,
+ const css_fixed device_dpi)
+{
+ return FDIV(FMUL(css_pixels, device_dpi), F_96);
+}
+
+/**
+ * Convert device pixels to css pixels.
+ *
+ * \param[in] device_pixels Length in physical pixels.
+ * \param[in] device_dpi Device dots per inch.
+ * \return Length in css pixels.
+ */
+static inline css_fixed css_unit_device2css_px(
+ const css_fixed device_pixels,
+ const css_fixed device_dpi)
+{
+ return FDIV(FMUL(device_pixels, F_96), device_dpi);
+}
+
+/**
+ * Convert a length to points (pt).
+ *
+ * \param[in] ctx Length unit conversion context.
+ * \param[in] length Length to convert.
+ * \param[in] unit Current unit of length.
+ * \return A length in points.
+ */
+css_fixed css_unit_font_size_len2pt(
+ const css_unit_len_ctx *ctx,
+ const css_fixed length,
+ const css_unit unit);
+
+/**
+ * Convert a length to CSS pixels.
+ *
+ * \param[in] ctx Length unit conversion context.
+ * \param[in] length Length to convert.
+ * \param[in] unit Current unit of length.
+ * \return A length in CSS pixels.
+ */
+css_fixed css_unit_len2css_px(
+ const css_unit_len_ctx *ctx,
+ const css_fixed length,
+ const css_unit unit);
+
+/**
+ * Convert a length to device pixels.
+ *
+ * \param[in] ctx Length unit conversion context.
+ * \param[in] length Length to convert.
+ * \param[in] unit Current unit of length.
+ * \return A length in device pixels.
+ */
+css_fixed css_unit_len2device_px(
+ const css_unit_len_ctx *ctx,
+ const css_fixed length,
+ const css_unit unit);
+
+/**
+ * Convert a length to CSS pixels for a media query context.
+ *
+ * \param[in] media Client media specification.
+ * \param[in] length Length to convert.
+ * \param[in] unit Current unit of length.
+ * \return A length in CSS pixels.
+ */
+css_fixed css_unit_len2px_mq(
+ const css_media *media,
+ const css_fixed length,
+ const css_unit unit);
+
+/**
+ * Convert relative font size units to absolute units.
+ *
+ * \param[in] ctx Length unit conversion context.
+ * \param[in,out] size The length to convert.
+ * \return CSS_OK on success, or appropriate error otherwise.
+ */
+css_error css_unit_compute_absolute_font_size(
+ const css_unit_len_ctx *ctx,
+ css_hint *size);
+
+#endif
commitdiff http://git.netsurf-browser.org/libcss.git/commit/?id=443bd7f401a74a0adc32...
commit 443bd7f401a74a0adc32bac0ecb87a2b77f9cfeb
Author: Michael Drake <Michael Drake tlsa(a)netsurf-browser.org>
Commit: Michael Drake <Michael Drake tlsa(a)netsurf-browser.org>
Units: Remove units that nobody supports.
diff --git a/docs/Bytecode b/docs/Bytecode
index d691923..4914e65 100644
--- a/docs/Bytecode
+++ b/docs/Bytecode
@@ -44,19 +44,16 @@ Length is a 32bit numeric value (as described above) and unit is as follows:
00000101 => mm
00000110 => pt
00000111 => pc
- 00001000 => cap
- 00001001 => ch
- 00001010 => ic
- 00001011 => rem
- 00001100 => lh
- 00001101 => rlh
- 00001110 => vh
- 00001111 => vw
- 00010000 => vi
- 00010001 => vb
- 00010010 => vmin
- 00010011 => vmax
- 00010100 => q
+ 00001000 => ch
+ 00001001 => rem
+ 00001010 => lh
+ 00001011 => vh
+ 00001100 => vw
+ 00001101 => vi
+ 00001110 => vb
+ 00001111 => vmin
+ 00010000 => vmax
+ 00010001 => q
bit 9 set => percentage unit
bits 9-31: MBZ
diff --git a/include/libcss/types.h b/include/libcss/types.h
index d8ac494..1186c6f 100644
--- a/include/libcss/types.h
+++ b/include/libcss/types.h
@@ -88,19 +88,16 @@ typedef enum css_unit {
CSS_UNIT_MM = 0x05,
CSS_UNIT_PT = 0x06,
CSS_UNIT_PC = 0x07,
- CSS_UNIT_CAP = 0x08,
- CSS_UNIT_CH = 0x09,
- CSS_UNIT_IC = 0x0a,
- CSS_UNIT_REM = 0x0b,
- CSS_UNIT_LH = 0x0c,
- CSS_UNIT_RLH = 0x0d,
- CSS_UNIT_VH = 0x0e,
- CSS_UNIT_VW = 0x0f,
- CSS_UNIT_VI = 0x10,
- CSS_UNIT_VB = 0x11,
- CSS_UNIT_VMIN = 0x12,
- CSS_UNIT_VMAX = 0x13,
- CSS_UNIT_Q = 0x14,
+ CSS_UNIT_CH = 0x08,
+ CSS_UNIT_REM = 0x09,
+ CSS_UNIT_LH = 0x0a,
+ CSS_UNIT_VH = 0x0b,
+ CSS_UNIT_VW = 0x0c,
+ CSS_UNIT_VI = 0x0d,
+ CSS_UNIT_VB = 0x0e,
+ CSS_UNIT_VMIN = 0x0f,
+ CSS_UNIT_VMAX = 0x10,
+ CSS_UNIT_Q = 0x11,
CSS_UNIT_PCT = 0x15, /* Percentage */
@@ -116,7 +113,7 @@ typedef enum css_unit {
} css_unit;
/**
- * Media orienations
+ * Media orientations
*/
typedef enum css_media_orientation {
CSS_MEDIA_ORIENTATION_PORTRAIT = 0,
diff --git a/src/bytecode/bytecode.h b/src/bytecode/bytecode.h
index 7518281..7f5ea9d 100644
--- a/src/bytecode/bytecode.h
+++ b/src/bytecode/bytecode.h
@@ -34,19 +34,16 @@ typedef enum unit {
UNIT_MM = (1u << 8) + 5,
UNIT_PT = (1u << 8) + 6,
UNIT_PC = (1u << 8) + 7,
- UNIT_CAP = (1u << 8) + 8,
- UNIT_CH = (1u << 8) + 9,
- UNIT_IC = (1u << 8) + 10,
- UNIT_REM = (1u << 8) + 11,
- UNIT_LH = (1u << 8) + 12,
- UNIT_RLH = (1u << 8) + 13,
- UNIT_VH = (1u << 8) + 14,
- UNIT_VW = (1u << 8) + 15,
- UNIT_VI = (1u << 8) + 16,
- UNIT_VB = (1u << 8) + 17,
- UNIT_VMIN = (1u << 8) + 18,
- UNIT_VMAX = (1u << 8) + 19,
- UNIT_Q = (1u << 8) + 20,
+ UNIT_CH = (1u << 8) + 8,
+ UNIT_REM = (1u << 8) + 9,
+ UNIT_LH = (1u << 8) + 10,
+ UNIT_VH = (1u << 8) + 11,
+ UNIT_VW = (1u << 8) + 12,
+ UNIT_VI = (1u << 8) + 13,
+ UNIT_VB = (1u << 8) + 14,
+ UNIT_VMIN = (1u << 8) + 15,
+ UNIT_VMAX = (1u << 8) + 16,
+ UNIT_Q = (1u << 8) + 17,
UNIT_PCT = (1 << 9),
diff --git a/src/parse/properties/utils.c b/src/parse/properties/utils.c
index 707a22b..1e184f8 100644
--- a/src/parse/properties/utils.c
+++ b/src/parse/properties/utils.c
@@ -1032,12 +1032,8 @@ css_error css__parse_unit_keyword(const char *ptr, size_t len, uint32_t *unit)
*unit = UNIT_DEG;
else if (strncasecmp(ptr, "rad", 3) == 0)
*unit = UNIT_RAD;
- else if (strncasecmp(ptr, "cap", 3) == 0)
- *unit = UNIT_CAP;
else if (strncasecmp(ptr, "rem", 3) == 0)
*unit = UNIT_REM;
- else if (strncasecmp(ptr, "rlh", 3) == 0)
- *unit = UNIT_RLH;
else if (strncasecmp(ptr, "dpi", 3) == 0)
*unit = UNIT_DPI;
else
@@ -1065,8 +1061,6 @@ css_error css__parse_unit_keyword(const char *ptr, size_t len, uint32_t *unit)
*unit = UNIT_PC;
else if (strncasecmp(ptr, "ch", 2) == 0)
*unit = UNIT_CH;
- else if (strncasecmp(ptr, "ic", 2) == 0)
- *unit = UNIT_IC;
else if (strncasecmp(ptr, "lh", 2) == 0)
*unit = UNIT_LH;
else if (strncasecmp(ptr, "vh", 2) == 0)
diff --git a/src/select/helpers.h b/src/select/helpers.h
index ba2e3be..19ff7de 100644
--- a/src/select/helpers.h
+++ b/src/select/helpers.h
@@ -22,12 +22,9 @@ static inline css_unit css__to_css_unit(uint32_t u)
case UNIT_MM: return CSS_UNIT_MM;
case UNIT_PT: return CSS_UNIT_PT;
case UNIT_PC: return CSS_UNIT_PC;
- case UNIT_CAP: return CSS_UNIT_CAP;
case UNIT_CH: return CSS_UNIT_CH;
- case UNIT_IC: return CSS_UNIT_IC;
case UNIT_REM: return CSS_UNIT_REM;
case UNIT_LH: return CSS_UNIT_LH;
- case UNIT_RLH: return CSS_UNIT_RLH;
case UNIT_VH: return CSS_UNIT_VH;
case UNIT_VW: return CSS_UNIT_VW;
case UNIT_VI: return CSS_UNIT_VI;
diff --git a/src/select/mq.h b/src/select/mq.h
index 79303e9..6f98387 100644
--- a/src/select/mq.h
+++ b/src/select/mq.h
@@ -42,9 +42,7 @@ static inline css_fixed css_len2px(
switch (unit) {
case CSS_UNIT_EM:
case CSS_UNIT_EX:
- case CSS_UNIT_CAP:
case CSS_UNIT_CH:
- case CSS_UNIT_IC:
{
px_per_unit = FDIV(FMUL(media->client_font_size, F_96), F_72);
@@ -53,15 +51,9 @@ static inline css_fixed css_len2px(
case CSS_UNIT_EX:
px_per_unit = FMUL(px_per_unit, FLTTOFIX(0.6));
break;
- case CSS_UNIT_CAP:
- px_per_unit = FMUL(px_per_unit, FLTTOFIX(0.9));
- break;
case CSS_UNIT_CH:
px_per_unit = FMUL(px_per_unit, FLTTOFIX(0.4));
break;
- case CSS_UNIT_IC:
- px_per_unit = FMUL(px_per_unit, FLTTOFIX(1.1));
- break;
default:
break;
}
@@ -90,9 +82,6 @@ static inline css_fixed css_len2px(
case CSS_UNIT_REM:
px_per_unit = FDIV(FMUL(media->client_font_size, F_96), F_72);
break;
- case CSS_UNIT_RLH:
- px_per_unit = media->client_line_height;
- break;
case CSS_UNIT_VH:
px_per_unit = FDIV(media->height, F_100);
break;
diff --git a/test/data/parse2/units.dat b/test/data/parse2/units.dat
index 1052dc5..800df75 100644
--- a/test/data/parse2/units.dat
+++ b/test/data/parse2/units.dat
@@ -70,14 +70,6 @@
#reset
#data
-* { width: 10cap; }
-#errors
-#expected
-| *
-| width: 10cap
-#reset
-
-#data
* { width: 10ch; }
#errors
#expected
@@ -86,14 +78,6 @@
#reset
#data
-* { width: 10ic; }
-#errors
-#expected
-| *
-| width: 10ic
-#reset
-
-#data
* { width: 10rem; }
#errors
#expected
@@ -110,14 +94,6 @@
#reset
#data
-* { width: 10rlh; }
-#errors
-#expected
-| *
-| width: 10rlh
-#reset
-
-#data
* { width: 10vh; }
#errors
#expected
diff --git a/test/data/select/tests1.dat b/test/data/select/tests1.dat
index 33ba589..ccce94d 100644
--- a/test/data/select/tests1.dat
+++ b/test/data/select/tests1.dat
@@ -12419,7 +12419,7 @@ z-index: auto
#tree
| div*
#ua
-div { width: 10cap; }
+div { width: 10em; }
#errors
#expected
align-content: stretch
@@ -12519,7 +12519,7 @@ unicode-bidi: normal
vertical-align: baseline
visibility: visible
white-space: normal
-width: 10cap
+width: 10em
word-spacing: normal
writing-mode: horizontal-tb
z-index: auto
@@ -12637,7 +12637,7 @@ z-index: auto
#tree
| div*
#ua
-div { width: 10ic; }
+div { width: 10ch; }
#errors
#expected
align-content: stretch
@@ -12737,7 +12737,7 @@ unicode-bidi: normal
vertical-align: baseline
visibility: visible
white-space: normal
-width: 10ic
+width: 10ch
word-spacing: normal
writing-mode: horizontal-tb
z-index: auto
@@ -12964,7 +12964,7 @@ z-index: auto
#tree
| div*
#ua
-div { width: 10rlh; }
+div { width: 10rem; }
#errors
#expected
align-content: stretch
@@ -13064,7 +13064,7 @@ unicode-bidi: normal
vertical-align: baseline
visibility: visible
white-space: normal
-width: 10rlh
+width: 10rem
word-spacing: normal
writing-mode: horizontal-tb
z-index: auto
diff --git a/test/dump.h b/test/dump.h
index d67bb2a..79819e0 100644
--- a/test/dump.h
+++ b/test/dump.h
@@ -584,24 +584,15 @@ static void dump_unit(css_fixed val, uint32_t unit, char **ptr)
case UNIT_PC:
*ptr += sprintf(*ptr, "pc");
break;
- case UNIT_CAP:
- *ptr += sprintf(*ptr, "cap");
- break;
case UNIT_CH:
*ptr += sprintf(*ptr, "ch");
break;
- case UNIT_IC:
- *ptr += sprintf(*ptr, "ic");
- break;
case UNIT_REM:
*ptr += sprintf(*ptr, "rem");
break;
case UNIT_LH:
*ptr += sprintf(*ptr, "lh");
break;
- case UNIT_RLH:
- *ptr += sprintf(*ptr, "rlh");
- break;
case UNIT_VH:
*ptr += sprintf(*ptr, "vh");
break;
diff --git a/test/dump_computed.h b/test/dump_computed.h
index b0c8bda..8ac6424 100644
--- a/test/dump_computed.h
+++ b/test/dump_computed.h
@@ -105,24 +105,15 @@ static size_t dump_css_unit(css_fixed val, css_unit unit, char *ptr, size_t len)
case CSS_UNIT_PC:
ret += snprintf(ptr + ret, len - ret, "pc");
break;
- case CSS_UNIT_CAP:
- ret += snprintf(ptr + ret, len - ret, "cap");
- break;
case CSS_UNIT_CH:
ret += snprintf(ptr + ret, len - ret, "ch");
break;
- case CSS_UNIT_IC:
- ret += snprintf(ptr + ret, len - ret, "ic");
- break;
case CSS_UNIT_REM:
ret += snprintf(ptr + ret, len - ret, "rem");
break;
case CSS_UNIT_LH:
ret += snprintf(ptr + ret, len - ret, "lh");
break;
- case CSS_UNIT_RLH:
- ret += snprintf(ptr + ret, len - ret, "rlh");
- break;
case CSS_UNIT_VH:
ret += snprintf(ptr + ret, len - ret, "vh");
break;
-----------------------------------------------------------------------
Summary of changes:
Makefile | 1 +
docs/Bytecode | 23 ++-
examples/example1.c | 79 ++--------
include/libcss/computed.h | 6 +-
include/libcss/properties.h | 7 +-
include/libcss/select.h | 5 +-
include/libcss/types.h | 25 ++-
{src/select => include/libcss}/unit.h | 84 +++++-----
src/bytecode/bytecode.h | 23 ++-
src/bytecode/opcodes.h | 7 +-
src/parse/properties/utils.c | 15 +-
src/parse/propstrings.c | 5 +
src/parse/propstrings.h | 3 +-
src/select/computed.c | 34 ++--
src/select/computed.h | 6 +-
src/select/format_list_style.c | 115 +++++++++++++-
src/select/helpers.h | 3 -
src/select/properties/list_style_type.c | 15 ++
src/select/select.c | 5 +-
src/select/unit.c | 115 ++++++++++----
src/select/unit.h | 120 +-------------
test/data/parse2/units.dat | 24 ---
test/data/select/tests1.dat | 258 +++++++++++++++----------------
test/dump.h | 9 --
test/dump_computed.h | 9 --
test/select.c | 85 ++--------
26 files changed, 516 insertions(+), 565 deletions(-)
copy {src/select => include/libcss}/unit.h (65%)
diff --git a/Makefile b/Makefile
index 0835c8f..86d6641 100644
--- a/Makefile
+++ b/Makefile
@@ -65,5 +65,6 @@ INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):include/libcss/properties.h
INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):include/libcss/select.h
INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):include/libcss/stylesheet.h
INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):include/libcss/types.h
+INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):include/libcss/unit.h
INSTALL_ITEMS := $(INSTALL_ITEMS) /$(LIBDIR)/pkgconfig:lib$(COMPONENT).pc.in
INSTALL_ITEMS := $(INSTALL_ITEMS) /$(LIBDIR):$(OUTPUT)
diff --git a/docs/Bytecode b/docs/Bytecode
index d691923..4914e65 100644
--- a/docs/Bytecode
+++ b/docs/Bytecode
@@ -44,19 +44,16 @@ Length is a 32bit numeric value (as described above) and unit is as follows:
00000101 => mm
00000110 => pt
00000111 => pc
- 00001000 => cap
- 00001001 => ch
- 00001010 => ic
- 00001011 => rem
- 00001100 => lh
- 00001101 => rlh
- 00001110 => vh
- 00001111 => vw
- 00010000 => vi
- 00010001 => vb
- 00010010 => vmin
- 00010011 => vmax
- 00010100 => q
+ 00001000 => ch
+ 00001001 => rem
+ 00001010 => lh
+ 00001011 => vh
+ 00001100 => vw
+ 00001101 => vi
+ 00001110 => vb
+ 00001111 => vmin
+ 00010000 => vmax
+ 00010001 => q
bit 9 set => percentage unit
bits 9-31: MBZ
diff --git a/examples/example1.c b/examples/example1.c
index c36a94d..6135793 100644
--- a/examples/example1.c
+++ b/examples/example1.c
@@ -98,13 +98,22 @@ static css_error node_presentational_hint(void *pw, void *node,
uint32_t *nhints, css_hint **hints);
static css_error ua_default_for_property(void *pw, uint32_t property,
css_hint *hint);
-static css_error compute_font_size(void *pw, const css_hint *parent,
- css_hint *size);
static css_error set_libcss_node_data(void *pw, void *n,
void *libcss_node_data);
static css_error get_libcss_node_data(void *pw, void *n,
void **libcss_node_data);
+static css_unit_len_ctx uint_len_ctx = {
+ .viewport_width = 800 * (1 << CSS_RADIX_POINT),
+ .viewport_height = 600 * (1 << CSS_RADIX_POINT),
+ .font_size_default = 16 * (1 << CSS_RADIX_POINT),
+ .font_size_minimum = 6 * (1 << CSS_RADIX_POINT),
+ .device_dpi = 96 * (1 << CSS_RADIX_POINT),
+ .root_style = NULL, /* We don't have a root node yet. */
+ .pw = NULL, /* We're not implementing measure callback */
+ .measure = NULL, /* We're not implementing measure callback */
+};
+
/* Table of function pointers for the LibCSS Select API. */
static css_select_handler select_handler = {
CSS_SELECT_HANDLER_VERSION_1,
@@ -143,9 +152,8 @@ static css_select_handler select_handler = {
node_is_lang,
node_presentational_hint,
ua_default_for_property,
- compute_font_size,
set_libcss_node_data,
- get_libcss_node_data
+ get_libcss_node_data,
};
@@ -237,6 +245,7 @@ int main(int argc, char **argv)
lwc_intern_string(element, strlen(element), &element_name);
code = css_select_style(select_ctx, element_name,
+ &uint_len_ctx,
&media, NULL,
&select_handler, 0,
&style);
@@ -662,68 +671,6 @@ css_error ua_default_for_property(void *pw, uint32_t property, css_hint *hint)
return CSS_OK;
}
-css_error compute_font_size(void *pw, const css_hint *parent, css_hint *size)
-{
- static css_hint_length sizes[] = {
- { FLTTOFIX(6.75), CSS_UNIT_PT },
- { FLTTOFIX(7.50), CSS_UNIT_PT },
- { FLTTOFIX(9.75), CSS_UNIT_PT },
- { FLTTOFIX(12.0), CSS_UNIT_PT },
- { FLTTOFIX(13.5), CSS_UNIT_PT },
- { FLTTOFIX(18.0), CSS_UNIT_PT },
- { FLTTOFIX(24.0), CSS_UNIT_PT }
- };
- const css_hint_length *parent_size;
-
- UNUSED(pw);
-
- /* Grab parent size, defaulting to medium if none */
- if (parent == NULL) {
- parent_size = &sizes[CSS_FONT_SIZE_MEDIUM - 1];
- } else {
- assert(parent->status == CSS_FONT_SIZE_DIMENSION);
- assert(parent->data.length.unit != CSS_UNIT_EM);
- assert(parent->data.length.unit != CSS_UNIT_EX);
- parent_size = &parent->data.length;
- }
-
- assert(size->status != CSS_FONT_SIZE_INHERIT);
-
- if (size->status < CSS_FONT_SIZE_LARGER) {
- /* Keyword -- simple */
- size->data.length = sizes[size->status - 1];
- } else if (size->status == CSS_FONT_SIZE_LARGER) {
- /** \todo Step within table, if appropriate */
- size->data.length.value =
- FMUL(parent_size->value, FLTTOFIX(1.2));
- size->data.length.unit = parent_size->unit;
- } else if (size->status == CSS_FONT_SIZE_SMALLER) {
- /** \todo Step within table, if appropriate */
- size->data.length.value =
- FMUL(parent_size->value, FLTTOFIX(1.2));
- size->data.length.unit = parent_size->unit;
- } else if (size->data.length.unit == CSS_UNIT_EM ||
- size->data.length.unit == CSS_UNIT_EX) {
- size->data.length.value =
- FMUL(size->data.length.value, parent_size->value);
-
- if (size->data.length.unit == CSS_UNIT_EX) {
- size->data.length.value = FMUL(size->data.length.value,
- FLTTOFIX(0.6));
- }
-
- size->data.length.unit = parent_size->unit;
- } else if (size->data.length.unit == CSS_UNIT_PCT) {
- size->data.length.value = FDIV(FMUL(size->data.length.value,
- parent_size->value), FLTTOFIX(100));
- size->data.length.unit = parent_size->unit;
- }
-
- size->status = CSS_FONT_SIZE_DIMENSION;
-
- return CSS_OK;
-}
-
static css_error set_libcss_node_data(void *pw, void *n,
void *libcss_node_data)
{
diff --git a/include/libcss/computed.h b/include/libcss/computed.h
index f4b3e21..1587d78 100644
--- a/include/libcss/computed.h
+++ b/include/libcss/computed.h
@@ -19,6 +19,7 @@ extern "C"
#include <libcss/functypes.h>
#include <libcss/properties.h>
#include <libcss/types.h>
+#include <libcss/unit.h>
struct css_hint;
struct css_select_handler;
@@ -81,10 +82,7 @@ css_error css_computed_style_destroy(css_computed_style *style);
css_error css_computed_style_compose(
const css_computed_style *restrict parent,
const css_computed_style *restrict child,
- css_error (*compute_font_size)(void *pw,
- const struct css_hint *parent,
- struct css_hint *size),
- void *pw,
+ const css_unit_len_ctx *unit_len_ctx,
css_computed_style **restrict result);
/******************************************************************************
diff --git a/include/libcss/properties.h b/include/libcss/properties.h
index a5569d0..ae00551 100644
--- a/include/libcss/properties.h
+++ b/include/libcss/properties.h
@@ -638,7 +638,12 @@ enum css_list_style_type_e {
CSS_LIST_STYLE_TYPE_HIAGANA = 0x2c,
CSS_LIST_STYLE_TYPE_HIAGANA_IROHA = 0x2d,
CSS_LIST_STYLE_TYPE_KATAKANA = 0x2e,
- CSS_LIST_STYLE_TYPE_KATAKANA_IROHA = 0x2f
+ CSS_LIST_STYLE_TYPE_KATAKANA_IROHA = 0x2f,
+ CSS_LIST_STYLE_TYPE_JAPANESE_INFORMAL = 0x30,
+ CSS_LIST_STYLE_TYPE_JAPANESE_FORMAL = 0x31,
+ CSS_LIST_STYLE_TYPE_KOREAN_HANGUL_FORMAL = 0x32,
+ CSS_LIST_STYLE_TYPE_KOREAN_HANJA_INFORMAL = 0x33,
+ CSS_LIST_STYLE_TYPE_KOREAN_HANJA_FORMAL = 0x34
};
enum css_margin_e {
diff --git a/include/libcss/select.h b/include/libcss/select.h
index ca57456..bfaf531 100644
--- a/include/libcss/select.h
+++ b/include/libcss/select.h
@@ -18,6 +18,7 @@ extern "C"
#include <libcss/hint.h>
#include <libcss/types.h>
#include <libcss/computed.h>
+#include <libcss/unit.h>
typedef enum css_pseudo_element {
CSS_PSEUDO_ELEMENT_NONE = 0,
@@ -123,9 +124,6 @@ typedef struct css_select_handler {
css_error (*ua_default_for_property)(void *pw, uint32_t property,
css_hint *hint);
- css_error (*compute_font_size)(void *pw, const css_hint *parent,
- css_hint *size);
-
/**
* Set libcss_node_data on a DOM node.
*
@@ -221,6 +219,7 @@ css_error css_select_default_style(css_select_ctx *ctx,
css_select_handler *handler, void *pw,
css_computed_style **style);
css_error css_select_style(css_select_ctx *ctx, void *node,
+ const css_unit_len_ctx *unit_len_ctx,
const css_media *media, const css_stylesheet *inline_style,
css_select_handler *handler, void *pw,
css_select_results **result);
diff --git a/include/libcss/types.h b/include/libcss/types.h
index d8ac494..1186c6f 100644
--- a/include/libcss/types.h
+++ b/include/libcss/types.h
@@ -88,19 +88,16 @@ typedef enum css_unit {
CSS_UNIT_MM = 0x05,
CSS_UNIT_PT = 0x06,
CSS_UNIT_PC = 0x07,
- CSS_UNIT_CAP = 0x08,
- CSS_UNIT_CH = 0x09,
- CSS_UNIT_IC = 0x0a,
- CSS_UNIT_REM = 0x0b,
- CSS_UNIT_LH = 0x0c,
- CSS_UNIT_RLH = 0x0d,
- CSS_UNIT_VH = 0x0e,
- CSS_UNIT_VW = 0x0f,
- CSS_UNIT_VI = 0x10,
- CSS_UNIT_VB = 0x11,
- CSS_UNIT_VMIN = 0x12,
- CSS_UNIT_VMAX = 0x13,
- CSS_UNIT_Q = 0x14,
+ CSS_UNIT_CH = 0x08,
+ CSS_UNIT_REM = 0x09,
+ CSS_UNIT_LH = 0x0a,
+ CSS_UNIT_VH = 0x0b,
+ CSS_UNIT_VW = 0x0c,
+ CSS_UNIT_VI = 0x0d,
+ CSS_UNIT_VB = 0x0e,
+ CSS_UNIT_VMIN = 0x0f,
+ CSS_UNIT_VMAX = 0x10,
+ CSS_UNIT_Q = 0x11,
CSS_UNIT_PCT = 0x15, /* Percentage */
@@ -116,7 +113,7 @@ typedef enum css_unit {
} css_unit;
/**
- * Media orienations
+ * Media orientations
*/
typedef enum css_media_orientation {
CSS_MEDIA_ORIENTATION_PORTRAIT = 0,
diff --git a/src/select/unit.h b/include/libcss/unit.h
similarity index 65%
copy from src/select/unit.h
copy to include/libcss/unit.h
index 7ed6458..a847077 100644
--- a/src/select/unit.h
+++ b/include/libcss/unit.h
@@ -1,13 +1,19 @@
/*
- * This file is part of LibCSS
+ * This file is part of LibCSS.
* Licensed under the MIT License,
* http://www.opensource.org/licenses/mit-license.php
- *
- * Copyright 2021 Michael Drake <tlsa(a)netsurf-browser.org>
+ * Copyright 2008 John-Mark Bell <jmb(a)netsurf-browser.org>
*/
-#ifndef css_select_unit_h_
-#define css_select_unit_h_
+#ifndef libcss_unit_h_
+#define libcss_unit_h_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <libcss/types.h>
/**
* Client callback for font measuring.
@@ -54,23 +60,17 @@ typedef struct css_unit_len_ctx {
*/
css_fixed device_dpi;
/**
- * Reference style. Most of the time, this is the element's style.
- * When converting a length for a typographical property, such as
- * font-size, then this should be the parent node. If the node has
- * no parent then this may be NULL.
- */
- const css_computed_style *ref_style;
- /**
- * Computed style for the document root element.
- * May be NULL if unit is not rem.
+ * Computed style for the document root element, needed for rem units.
+ * May be NULL, in which case font_size_default is used instead, as
+ * would be the case if rem unit is used on the root element.
*/
const css_computed_style *root_style;
/**
- * Client private word for measure callback.
+ * Optional client private word for measure callback.
*/
void *pw;
/**
- * Client callback for font measuring.
+ * Optional client callback for font measuring.
*/
const css_unit_len_measure measure;
} css_unit_len_ctx;
@@ -103,44 +103,54 @@ static inline css_fixed css_unit_device2css_px(
return FDIV(FMUL(device_pixels, F_96), device_dpi);
}
+/**
+ * Convert a length to points (pt).
+ *
+ * \param[in] style Style to perform conversion for or NULL.
+ * \param[in] ctx Length unit conversion context.
+ * \param[in] length Length to convert.
+ * \param[in] unit Current unit of length.
+ * \return A length in points.
+ */
css_fixed css_unit_font_size_len2pt(
- const css_unit_len_ctx *ctx,
- const css_fixed length,
- const css_unit unit);
-
-
-css_fixed css_unit_len2css_px(
- const css_unit_len_ctx *ctx,
- const css_fixed length,
- const css_unit unit);
-
-css_fixed css_unit_len2device_px(
+ const css_computed_style *style,
const css_unit_len_ctx *ctx,
const css_fixed length,
const css_unit unit);
/**
- * Convert a length to CSS pixels for a media query context.
+ * Convert a length to CSS pixels.
*
- * \param[in] media Client media specification.
+ * \param[in] style Style to perform conversion for or NULL.
+ * \param[in] ctx Length unit conversion context.
* \param[in] length Length to convert.
* \param[in] unit Current unit of length.
* \return A length in CSS pixels.
*/
-css_fixed css_unit_len2px_mq(
- const css_media *media,
+css_fixed css_unit_len2css_px(
+ const css_computed_style *style,
+ const css_unit_len_ctx *ctx,
const css_fixed length,
const css_unit unit);
/**
- * Convert relative font size units to absolute units.
+ * Convert a length to device pixels.
*
- * \param[in] ctx Length unit conversion context.
- * \param[in,out] size The length to convert.
- * \return CSS_OK on success, or appropriate error otherwise.
+ * \param[in] style Style to perform conversion for or NULL.
+ * \param[in] ctx Length unit conversion context.
+ * \param[in] length Length to convert.
+ * \param[in] unit Current unit of length.
+ * \return A length in device pixels.
*/
-css_error css_unit_compute_absolute_font_size(
+css_fixed css_unit_len2device_px(
+ const css_computed_style *style,
const css_unit_len_ctx *ctx,
- css_hint *size);
+ const css_fixed length,
+ const css_unit unit);
+
+#ifdef __cplusplus
+}
+#endif
#endif
+
diff --git a/src/bytecode/bytecode.h b/src/bytecode/bytecode.h
index 7518281..7f5ea9d 100644
--- a/src/bytecode/bytecode.h
+++ b/src/bytecode/bytecode.h
@@ -34,19 +34,16 @@ typedef enum unit {
UNIT_MM = (1u << 8) + 5,
UNIT_PT = (1u << 8) + 6,
UNIT_PC = (1u << 8) + 7,
- UNIT_CAP = (1u << 8) + 8,
- UNIT_CH = (1u << 8) + 9,
- UNIT_IC = (1u << 8) + 10,
- UNIT_REM = (1u << 8) + 11,
- UNIT_LH = (1u << 8) + 12,
- UNIT_RLH = (1u << 8) + 13,
- UNIT_VH = (1u << 8) + 14,
- UNIT_VW = (1u << 8) + 15,
- UNIT_VI = (1u << 8) + 16,
- UNIT_VB = (1u << 8) + 17,
- UNIT_VMIN = (1u << 8) + 18,
- UNIT_VMAX = (1u << 8) + 19,
- UNIT_Q = (1u << 8) + 20,
+ UNIT_CH = (1u << 8) + 8,
+ UNIT_REM = (1u << 8) + 9,
+ UNIT_LH = (1u << 8) + 10,
+ UNIT_VH = (1u << 8) + 11,
+ UNIT_VW = (1u << 8) + 12,
+ UNIT_VI = (1u << 8) + 13,
+ UNIT_VB = (1u << 8) + 14,
+ UNIT_VMIN = (1u << 8) + 15,
+ UNIT_VMAX = (1u << 8) + 16,
+ UNIT_Q = (1u << 8) + 17,
UNIT_PCT = (1 << 9),
diff --git a/src/bytecode/opcodes.h b/src/bytecode/opcodes.h
index 1e561e5..01ea25a 100644
--- a/src/bytecode/opcodes.h
+++ b/src/bytecode/opcodes.h
@@ -523,7 +523,12 @@ enum op_list_style_type {
LIST_STYLE_TYPE_HIAGANA = 0x002b,
LIST_STYLE_TYPE_HIAGANA_IROHA = 0x002c,
LIST_STYLE_TYPE_KATAKANA = 0x002d,
- LIST_STYLE_TYPE_KATAKANA_IROHA = 0x002e
+ LIST_STYLE_TYPE_KATAKANA_IROHA = 0x002e,
+ LIST_STYLE_TYPE_JAPANESE_INFORMAL = 0x002f,
+ LIST_STYLE_TYPE_JAPANESE_FORMAL = 0x0030,
+ LIST_STYLE_TYPE_KOREAN_HANGUL_FORMAL = 0x0031,
+ LIST_STYLE_TYPE_KOREAN_HANJA_INFORMAL = 0x0032,
+ LIST_STYLE_TYPE_KOREAN_HANJA_FORMAL = 0x0033
};
enum op_margin {
diff --git a/src/parse/properties/utils.c b/src/parse/properties/utils.c
index c82c88f..1e184f8 100644
--- a/src/parse/properties/utils.c
+++ b/src/parse/properties/utils.c
@@ -34,7 +34,7 @@ css_error css__parse_list_style_type_value(css_language *c, const css_token *ide
* upper-latin, armenian, georgian, lower-alpha, upper-alpha,
* none)
*/
- #define MAP_ENTRIES 47
+ #define MAP_ENTRIES 52
bool match;
int midx;
const struct {
@@ -87,7 +87,12 @@ css_error css__parse_list_style_type_value(css_language *c, const css_token *ide
{ HIAGANA, LIST_STYLE_TYPE_HIAGANA },
{ HIAGANA_IROHA, LIST_STYLE_TYPE_HIAGANA_IROHA },
{ KATAKANA, LIST_STYLE_TYPE_KATAKANA },
- { KATAKANA_IROHA, LIST_STYLE_TYPE_KATAKANA_IROHA }
+ { KATAKANA_IROHA, LIST_STYLE_TYPE_KATAKANA_IROHA },
+ { JAPANESE_INFORMAL, LIST_STYLE_TYPE_JAPANESE_INFORMAL },
+ { JAPANESE_FORMAL, LIST_STYLE_TYPE_JAPANESE_FORMAL },
+ { KOREAN_HANGUL_FORMAL, LIST_STYLE_TYPE_KOREAN_HANGUL_FORMAL },
+ { KOREAN_HANJA_INFORMAL, LIST_STYLE_TYPE_KOREAN_HANJA_INFORMAL },
+ { KOREAN_HANJA_FORMAL, LIST_STYLE_TYPE_KOREAN_HANJA_FORMAL }
};
for (midx = 0; midx < MAP_ENTRIES; midx++) {
@@ -1027,12 +1032,8 @@ css_error css__parse_unit_keyword(const char *ptr, size_t len, uint32_t *unit)
*unit = UNIT_DEG;
else if (strncasecmp(ptr, "rad", 3) == 0)
*unit = UNIT_RAD;
- else if (strncasecmp(ptr, "cap", 3) == 0)
- *unit = UNIT_CAP;
else if (strncasecmp(ptr, "rem", 3) == 0)
*unit = UNIT_REM;
- else if (strncasecmp(ptr, "rlh", 3) == 0)
- *unit = UNIT_RLH;
else if (strncasecmp(ptr, "dpi", 3) == 0)
*unit = UNIT_DPI;
else
@@ -1060,8 +1061,6 @@ css_error css__parse_unit_keyword(const char *ptr, size_t len, uint32_t *unit)
*unit = UNIT_PC;
else if (strncasecmp(ptr, "ch", 2) == 0)
*unit = UNIT_CH;
- else if (strncasecmp(ptr, "ic", 2) == 0)
- *unit = UNIT_IC;
else if (strncasecmp(ptr, "lh", 2) == 0)
*unit = UNIT_LH;
else if (strncasecmp(ptr, "vh", 2) == 0)
diff --git a/src/parse/propstrings.c b/src/parse/propstrings.c
index a2d9175..7d723e1 100644
--- a/src/parse/propstrings.c
+++ b/src/parse/propstrings.c
@@ -345,6 +345,11 @@ const stringmap_entry stringmap[LAST_KNOWN] = {
SMAP("hiragana-iroha"),
SMAP("katakana"),
SMAP("katakana-iroha"),
+ SMAP("japanese-informal"),
+ SMAP("japanese-formal"),
+ SMAP("korean-hangul-formal"),
+ SMAP("korean-hanja-informal"),
+ SMAP("korean-hanja-formal"),
SMAP("invert"),
SMAP("visible"),
SMAP("always"),
diff --git a/src/parse/propstrings.h b/src/parse/propstrings.h
index f011231..fd24a47 100644
--- a/src/parse/propstrings.h
+++ b/src/parse/propstrings.h
@@ -88,7 +88,8 @@ enum {
DEVANAGARI, GUJARATI, GURMUKHI, HEBREW, KANNADA, LAO, MALAYALAM,
MONGOLIAN, MYANMAR, ORIYA, PERSIAN, TAMIL, TELUGU, THAI, TIBETAN,
CJK_EARTHLY_BRANCH, CJK_HEAVENLY_STEM, HIAGANA, HIAGANA_IROHA,
- KATAKANA, KATAKANA_IROHA,
+ KATAKANA, KATAKANA_IROHA, JAPANESE_INFORMAL, JAPANESE_FORMAL,
+ KOREAN_HANGUL_FORMAL, KOREAN_HANJA_INFORMAL, KOREAN_HANJA_FORMAL,
INVERT, VISIBLE, ALWAYS, AVOID, X_LOW, LOW, HIGH, X_HIGH, LIBCSS_STATIC,
RELATIVE, ABSOLUTE, ONCE, DIGITS, CONTINUOUS, CODE, SPELL_OUT, X_SLOW,
SLOW, FAST, X_FAST, FASTER, SLOWER, CENTER, JUSTIFY, CAPITALIZE,
diff --git a/src/select/computed.c b/src/select/computed.c
index a1b345b..d075af9 100644
--- a/src/select/computed.c
+++ b/src/select/computed.c
@@ -12,6 +12,7 @@
#include "select/dispatch.h"
#include "select/propget.h"
#include "select/propset.h"
+#include "select/unit.h"
#include "utils/utils.h"
static css_error compute_absolute_color(css_computed_style *style,
@@ -247,9 +248,7 @@ css_error css__computed_style_initialise(css_computed_style *style,
css_error css_computed_style_compose(
const css_computed_style *restrict parent,
const css_computed_style *restrict child,
- css_error (*compute_font_size)(void *pw,
- const css_hint *parent, css_hint *size),
- void *pw,
+ const css_unit_len_ctx *unit_len_ctx,
css_computed_style **restrict result)
{
css_computed_style *composed;
@@ -275,8 +274,7 @@ css_error css_computed_style_compose(
}
/* Finally, compute absolute values for everything */
- error = css__compute_absolute_values(parent, composed,
- compute_font_size, pw);
+ error = css__compute_absolute_values(parent, composed, unit_len_ctx);
if (error != CSS_OK) {
return error;
}
@@ -1087,31 +1085,36 @@ uint8_t css_computed_order(const css_computed_style *style,
*
* \param parent Parent style, or NULL for tree root
* \param style Computed style to process
- * \param compute_font_size Callback to calculate an absolute font-size
- * \param pw Private word for callback
+ * \param unit_len_ctx Client length conversion context.
* \return CSS_OK on success.
*/
css_error css__compute_absolute_values(const css_computed_style *parent,
css_computed_style *style,
- css_error (*compute_font_size)(void *pw,
- const css_hint *parent, css_hint *size),
- void *pw)
+ const css_unit_len_ctx *unit_len_ctx)
{
+ css_hint_length *ref_length = NULL;
css_hint psize, size, ex_size;
css_error error;
- /* Ensure font-size is absolute */
+ /* Get reference font-size for relative sizes. */
if (parent != NULL) {
psize.status = get_font_size(parent,
&psize.data.length.value,
&psize.data.length.unit);
+ if (psize.status != CSS_FONT_SIZE_DIMENSION) {
+ return CSS_BADPARM;
+ }
+ ref_length = &psize.data.length;
}
size.status = get_font_size(style,
&size.data.length.value,
&size.data.length.unit);
- error = compute_font_size(pw, parent != NULL ? &psize : NULL, &size);
+ error = css_unit_compute_absolute_font_size(ref_length,
+ unit_len_ctx->root_style,
+ unit_len_ctx->font_size_default,
+ &size);
if (error != CSS_OK)
return error;
@@ -1125,7 +1128,12 @@ css_error css__compute_absolute_values(const css_computed_style *parent,
ex_size.status = CSS_FONT_SIZE_DIMENSION;
ex_size.data.length.value = INTTOFIX(1);
ex_size.data.length.unit = CSS_UNIT_EX;
- error = compute_font_size(pw, &size, &ex_size);
+
+ error = css_unit_compute_absolute_font_size(
+ &size.data.length,
+ unit_len_ctx->root_style,
+ unit_len_ctx->font_size_default,
+ &ex_size);
if (error != CSS_OK)
return error;
diff --git a/src/select/computed.h b/src/select/computed.h
index c926cec..8b33405 100644
--- a/src/select/computed.h
+++ b/src/select/computed.h
@@ -10,6 +10,8 @@
#include <libcss/computed.h>
#include <libcss/hint.h>
+#include <libcss/unit.h>
+
#include "autogenerated_computed.h"
/**
@@ -35,8 +37,6 @@ css_error css__computed_style_initialise(css_computed_style *style,
css_error css__compute_absolute_values(const css_computed_style *parent,
css_computed_style *style,
- css_error (*compute_font_size)(void *pw,
- const css_hint *parent, css_hint *size),
- void *pw);
+ const css_unit_len_ctx *unit_len_ctx);
#endif
diff --git a/src/select/format_list_style.c b/src/select/format_list_style.c
index 9cc5de7..0e3a39e 100644
--- a/src/select/format_list_style.c
+++ b/src/select/format_list_style.c
@@ -8,7 +8,7 @@
#include "select/propget.h"
#include "utils/utils.h"
-#define SYMBOL_SIZE 5
+#define SYMBOL_SIZE 8
typedef char symbol_t[SYMBOL_SIZE];
/**
@@ -330,6 +330,9 @@ calc_additive_system(int value,
/* iterate over the available weights */
for (widx = 0; widx < cstyle->items; widx++) {
+ if (cstyle->weights[widx] == 0) {
+ break;
+ }
times = value / cstyle->weights[widx];
if (times > 0) {
for (idx = 0;idx < times;idx++) {
@@ -975,6 +978,106 @@ static struct list_counter_style lcs_katakana_iroha = {
.suffix = "���",
};
+/**
+ * weights suitable for the five complex addative styles
+ */
+static const int complex_counter_weights[] = {
+ 9000, 8000, 7000, 6000, 5000, 4000, 3000, 2000, 1000,
+ 900, 800, 700, 600, 500, 400, 300, 200, 100,
+ 90, 80, 70, 60, 50, 40, 30, 20, 10,
+ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
+};
+static const symbol_t japanese_informal_symbols[] = {
+ "������", "������", "������", "������", "������", "������", "������", "������", "���",
+ "������", "������", "������", "������", "������", "������", "������", "������", "���",
+ "������", "������", "������", "������", "������", "������", "������", "������", "���",
+ "���", "���", "���", "���", "���", "���", "���", "���", "���", "���",
+};
+static const struct list_counter_style lcs_japanese_informal = {
+ .name = "japanese-informal",
+ .system = calc_additive_system,
+ .fallback = &lcs_cjk_decimal,
+ .symbols = japanese_informal_symbols,
+ .weights = complex_counter_weights,
+ .items = (sizeof(japanese_informal_symbols) / SYMBOL_SIZE),
+ .range = { .start = -9999, .end = 9999 },
+ .negative = { .pre = "������������" },
+ .suffix = "\xE3\x80\x81",
+};
+
+static const symbol_t japanese_formal_symbols[] = {
+ "������", "������", "������", "������", "������", "������", "������", "������", "������",
+ "������", "������", "������", "������", "������", "������", "������", "������", "������",
+ "������", "������", "������", "������", "������", "������", "������", "������", "������",
+ "���", "���", "���", "���", "���", "���", "���", "���", "���", "���",
+};
+static const struct list_counter_style lcs_japanese_formal = {
+ .name = "japanese-formal",
+ .system = calc_additive_system,
+ .fallback = &lcs_cjk_decimal,
+ .symbols = japanese_formal_symbols,
+ .weights = complex_counter_weights,
+ .items = (sizeof(japanese_formal_symbols) / SYMBOL_SIZE),
+ .range = { .start = -9999, .end = 9999 },
+ .negative = { .pre = "������������" },
+ .suffix = "\xE3\x80\x81",
+};
+
+static const symbol_t korean_hangul_formal_symbols[] = {
+ "������", "������", "������", "������", "������", "������", "������", "������", "������",
+ "������", "������", "������", "������", "������", "������", "������", "������", "������",
+ "������", "������", "������", "������", "������", "������", "������", "������", "������",
+ "���", "���", "���", "���", "���", "���", "���", "���", "���", "���"
+};
+static const struct list_counter_style lcs_korean_hangul_formal = {
+ .name = "korean-hangul-formal",
+ .system = calc_additive_system,
+ .fallback = &lcs_cjk_decimal,
+ .symbols = korean_hangul_formal_symbols,
+ .weights = complex_counter_weights,
+ .items = (sizeof(korean_hangul_formal_symbols) / SYMBOL_SIZE),
+ .range = { .start = -9999, .end = 9999 },
+ .negative = { .pre = "\xEB\xA7\x88\xEC\x9D\xB4\xEB\x84\x88\xEC\x8A\xA4 " },
+ .suffix = ", ",
+};
+
+static const symbol_t korean_hanja_informal_symbols[] = {
+ "������", "������", "������", "������", "������", "������", "������", "������", "���",
+ "������", "������", "������", "������", "������", "������", "������", "������", "���",
+ "������", "������", "������", "������", "������", "������", "������", "������", "���",
+ "���", "���", "���", "���", "���", "���", "���", "���", "���", "���"
+};
+static const struct list_counter_style lcs_korean_hanja_informal = {
+ .name = "korean-hanja-informal",
+ .system = calc_additive_system,
+ .fallback = &lcs_cjk_decimal,
+ .symbols = korean_hanja_informal_symbols,
+ .weights = complex_counter_weights,
+ .items = (sizeof(korean_hanja_informal_symbols) / SYMBOL_SIZE),
+ .range = { .start = -9999, .end = 9999 },
+ .negative = { .pre = "\xEB\xA7\x88\xEC\x9D\xB4\xEB\x84\x88\xEC\x8A\xA4 " },
+ .suffix = ", ",
+};
+
+static const symbol_t korean_hanja_formal_symbols[] = {
+ "������", "������", "������", "������", "������", "������", "������", "������", "������",
+ "������", "������", "������", "������", "������", "������", "������", "������", "������",
+ "������", "������", "������", "������", "������", "������", "������", "������", "������",
+ "���", "���", "���", "���", "���", "���", "���", "���", "���", "���"
+};
+static const struct list_counter_style lcs_korean_hanja_formal = {
+ .name = "korean-hanja-formal",
+ .system = calc_additive_system,
+ .fallback = &lcs_cjk_decimal,
+ .symbols = korean_hanja_formal_symbols,
+ .weights = complex_counter_weights,
+ .items = (sizeof(korean_hanja_formal_symbols) / SYMBOL_SIZE),
+ .range = { .start = -9999, .end = 9999 },
+ .negative = { .pre = "\xEB\xA7\x88\xEC\x9D\xB4\xEB\x84\x88\xEC\x8A\xA4 " },
+ .suffix = ", ",
+};
+
+
static const struct list_counter_style *
counter_style_from_computed_style(const css_computed_style *style)
@@ -1070,6 +1173,16 @@ counter_style_from_computed_style(const css_computed_style *style)
return &lcs_katakana;
case CSS_LIST_STYLE_TYPE_KATAKANA_IROHA:
return &lcs_katakana_iroha;
+ case CSS_LIST_STYLE_TYPE_JAPANESE_INFORMAL:
+ return &lcs_japanese_informal;
+ case CSS_LIST_STYLE_TYPE_JAPANESE_FORMAL:
+ return &lcs_japanese_formal;
+ case CSS_LIST_STYLE_TYPE_KOREAN_HANGUL_FORMAL:
+ return &lcs_korean_hangul_formal;
+ case CSS_LIST_STYLE_TYPE_KOREAN_HANJA_INFORMAL:
+ return &lcs_korean_hanja_informal;
+ case CSS_LIST_STYLE_TYPE_KOREAN_HANJA_FORMAL:
+ return &lcs_korean_hanja_formal;
}
return NULL;
}
diff --git a/src/select/helpers.h b/src/select/helpers.h
index ba2e3be..19ff7de 100644
--- a/src/select/helpers.h
+++ b/src/select/helpers.h
@@ -22,12 +22,9 @@ static inline css_unit css__to_css_unit(uint32_t u)
case UNIT_MM: return CSS_UNIT_MM;
case UNIT_PT: return CSS_UNIT_PT;
case UNIT_PC: return CSS_UNIT_PC;
- case UNIT_CAP: return CSS_UNIT_CAP;
case UNIT_CH: return CSS_UNIT_CH;
- case UNIT_IC: return CSS_UNIT_IC;
case UNIT_REM: return CSS_UNIT_REM;
case UNIT_LH: return CSS_UNIT_LH;
- case UNIT_RLH: return CSS_UNIT_RLH;
case UNIT_VH: return CSS_UNIT_VH;
case UNIT_VW: return CSS_UNIT_VW;
case UNIT_VI: return CSS_UNIT_VI;
diff --git a/src/select/properties/list_style_type.c b/src/select/properties/list_style_type.c
index 7560c3b..e32d1b1 100644
--- a/src/select/properties/list_style_type.c
+++ b/src/select/properties/list_style_type.c
@@ -164,6 +164,21 @@ css_error css__cascade_list_style_type(uint32_t opv, css_style *style,
case LIST_STYLE_TYPE_KATAKANA_IROHA:
value = CSS_LIST_STYLE_TYPE_KATAKANA_IROHA;
break;
+ case LIST_STYLE_TYPE_JAPANESE_INFORMAL:
+ value = CSS_LIST_STYLE_TYPE_JAPANESE_INFORMAL;
+ break;
+ case LIST_STYLE_TYPE_JAPANESE_FORMAL:
+ value = CSS_LIST_STYLE_TYPE_JAPANESE_FORMAL;
+ break;
+ case LIST_STYLE_TYPE_KOREAN_HANGUL_FORMAL:
+ value = CSS_LIST_STYLE_TYPE_KOREAN_HANGUL_FORMAL;
+ break;
+ case LIST_STYLE_TYPE_KOREAN_HANJA_INFORMAL:
+ value = CSS_LIST_STYLE_TYPE_KOREAN_HANJA_INFORMAL;
+ break;
+ case LIST_STYLE_TYPE_KOREAN_HANJA_FORMAL:
+ value = CSS_LIST_STYLE_TYPE_KOREAN_HANJA_FORMAL;
+ break;
}
}
diff --git a/src/select/select.c b/src/select/select.c
index f6efbfe..03a45fe 100644
--- a/src/select/select.c
+++ b/src/select/select.c
@@ -23,6 +23,7 @@
#include "select/propset.h"
#include "select/font_face.h"
#include "select/select.h"
+#include "select/unit.h"
#include "utils/parserutilserror.h"
#include "utils/utils.h"
@@ -1164,6 +1165,7 @@ failed:
*
* \param ctx Selection context to use
* \param node Node to select style for
+ * \param unit_len_ctx Context for length unit conversions.
* \param media Currently active media specification
* \param inline_style Corresponding inline style for node, or NULL
* \param handler Dispatch table of handler functions
@@ -1181,6 +1183,7 @@ failed:
* update the fully computed style for a node when layout changes.
*/
css_error css_select_style(css_select_ctx *ctx, void *node,
+ const css_unit_len_ctx *unit_len_ctx,
const css_media *media, const css_stylesheet *inline_style,
css_select_handler *handler, void *pw,
css_select_results **result)
@@ -1353,7 +1356,7 @@ css_error css_select_style(css_select_ctx *ctx, void *node,
/* Only compute absolute values for the base element */
error = css__compute_absolute_values(NULL,
state.results->styles[CSS_PSEUDO_ELEMENT_NONE],
- handler->compute_font_size, pw);
+ unit_len_ctx);
if (error != CSS_OK)
goto cleanup;
}
diff --git a/src/select/unit.c b/src/select/unit.c
index e01c59e..a279ec7 100644
--- a/src/select/unit.c
+++ b/src/select/unit.c
@@ -54,7 +54,17 @@ static inline css_unit css_unit__map_viewport_units(
}
}
-static inline css_fixed css_unit__len2pt(
+/**
+ * Convert an absolute length to points (pt).
+ *
+ * \param[in] style Style to get font-size from, or NULL.
+ * \param[in] viewport_height Client viewport height.
+ * \param[in] viewport_width Client viewport width.
+ * \param[in] length Length to convert.
+ * \param[in] unit Current unit of length.
+ * \return length in points (pt).
+ */
+static inline css_fixed css_unit__absolute_len2pt(
const css_computed_style *style,
const css_fixed viewport_height,
const css_fixed viewport_width,
@@ -105,19 +115,33 @@ static inline css_fixed css_unit__len2pt(
}
}
+/* Exported function, documented in libcss/unit.h. */
css_fixed css_unit_font_size_len2pt(
+ const css_computed_style *style,
const css_unit_len_ctx *ctx,
const css_fixed length,
const css_unit unit)
{
- return css_unit__len2pt(
- ctx->ref_style,
+ return css_unit__absolute_len2pt(
+ style,
ctx->viewport_height,
ctx->viewport_width,
length,
unit);
}
+/**
+ * Get font size from a style in CSS pixels.
+ *
+ * The style should have font size in absolute units.
+ *
+ * \param[in] style Style to get font-size from, or NULL.
+ * \param[in] font_size_default Client font size for NULL style.
+ * \param[in] font_size_minimum Client minimum font size clamp.
+ * \param[in] viewport_height Client viewport height.
+ * \param[in] viewport_width Client viewport width.
+ * \return font-size in CSS pixels.
+ */
static inline css_fixed css_unit__font_size_px(
const css_computed_style *style,
const css_fixed font_size_default,
@@ -134,14 +158,16 @@ static inline css_fixed css_unit__font_size_px(
get_font_size(style, &font_length, &font_unit);
- font_length = css_unit__len2pt(style,
- viewport_height,
- viewport_width,
- font_length,
- font_unit);
+ if (font_unit != CSS_UNIT_PX) {
+ font_length = css_unit__absolute_len2pt(style,
+ viewport_height,
+ viewport_width,
+ font_length,
+ font_unit);
- /* Convert from pt to CSS pixels.*/
- font_length = FDIV(FMUL(font_length, F_96), F_72);
+ /* Convert from pt to CSS pixels.*/
+ font_length = FDIV(FMUL(font_length, F_96), F_72);
+ }
/* Clamp to configured minimum */
if (font_length < font_size_minimum) {
@@ -158,7 +184,7 @@ static inline css_fixed css_unit__font_size_px(
* \param[in] ref_style Reference style. (Element or parent, or NULL).
* \param[in] root_style Root element style or NULL.
* \param[in] font_size_default Client default font size in CSS pixels.
- * \param[in] font_size_minimum Client minimum font size in CSS pixels. May be zero.
+ * \param[in] font_size_minimum Client minimum font size in CSS pixels.
* \param[in] viewport_height Viewport height in CSS pixels.
* \param[in] viewport_width Viewport width in CSS pixels.
* \param[in] unit The unit to convert from.
@@ -251,6 +277,7 @@ static inline css_fixed css_unit__px_per_unit(
}
}
+/* Exported function, documented in unit.h. */
css_fixed css_unit_len2px_mq(
const css_media *media,
const css_fixed length,
@@ -277,14 +304,16 @@ css_fixed css_unit_len2px_mq(
return FMUL(length, TRUNCATEFIX(px_per_unit));
}
+/* Exported function, documented in libcss/unit.h. */
css_fixed css_unit_len2css_px(
+ const css_computed_style *style,
const css_unit_len_ctx *ctx,
const css_fixed length,
const css_unit unit)
{
css_fixed px_per_unit = css_unit__px_per_unit(
ctx->measure,
- ctx->ref_style,
+ style,
ctx->root_style,
ctx->font_size_default,
ctx->font_size_minimum,
@@ -301,14 +330,16 @@ css_fixed css_unit_len2css_px(
return FMUL(length, TRUNCATEFIX(px_per_unit));
}
+/* Exported function, documented in libcss/unit.h. */
css_fixed css_unit_len2device_px(
+ const css_computed_style *style,
const css_unit_len_ctx *ctx,
const css_fixed length,
const css_unit unit)
{
css_fixed px_per_unit = css_unit__px_per_unit(
ctx->measure,
- ctx->ref_style,
+ style,
ctx->root_style,
ctx->font_size_default,
ctx->font_size_minimum,
@@ -327,14 +358,24 @@ css_fixed css_unit_len2device_px(
return FMUL(length, TRUNCATEFIX(px_per_unit));
}
+/**
+ * Get font size from a computed style.
+ *
+ * The computed style will have font-size with an absolute unit.
+ * If no computed style is given, the client default font-size will be returned.
+ *
+ * \param[in] style Reference style. (Element or parent, or NULL).
+ * \param[in] font_size_default Client default font size in CSS pixels.
+ * \return The font size in absolute units.
+ */
static inline css_hint_length css_unit__get_font_size(
- const css_unit_len_ctx *ctx,
- const css_computed_style *style)
+ const css_computed_style *style,
+ css_fixed font_size_default)
{
css_hint_length size;
if (style == NULL) {
- size.value = ctx->font_size_default;
+ size.value = font_size_default;
size.unit = CSS_UNIT_PX;
} else {
enum css_font_size_e status = get_font_size(
@@ -353,10 +394,24 @@ static inline css_hint_length css_unit__get_font_size(
/* Exported function, documented in unit.h. */
css_error css_unit_compute_absolute_font_size(
- const css_unit_len_ctx *ctx,
+ const css_hint_length *ref_length,
+ const css_computed_style *root_style,
+ css_fixed font_size_default,
css_hint *size)
{
- css_hint_length ref_len;
+ css_hint_length ref_len = {
+ .value = font_size_default,
+ .unit = CSS_UNIT_PX,
+ };
+
+ if (ref_length != NULL) {
+ /* Must be absolute. */
+ assert(ref_length->unit != CSS_UNIT_EM);
+ assert(ref_length->unit != CSS_UNIT_EX);
+ assert(ref_length->unit != CSS_UNIT_PCT);
+
+ ref_len = *ref_length;
+ }
assert(size->status != CSS_FONT_SIZE_INHERIT);
@@ -382,20 +437,18 @@ css_error css_unit_compute_absolute_font_size(
assert(CSS_FONT_SIZE_XX_SMALL == 1);
size->data.length.value = FMUL(factors[size->status - 1],
- ctx->font_size_default);
+ font_size_default);
size->data.length.unit = CSS_UNIT_PX;
size->status = CSS_FONT_SIZE_DIMENSION;
break;
}
case CSS_FONT_SIZE_LARGER:
- ref_len = css_unit__get_font_size(ctx, ctx->ref_style);
size->data.length.value = FMUL(ref_len.value, FLTTOFIX(1.2));
size->data.length.unit = ref_len.unit;
size->status = CSS_FONT_SIZE_DIMENSION;
break;
case CSS_FONT_SIZE_SMALLER:
- ref_len = css_unit__get_font_size(ctx, ctx->ref_style);
size->data.length.value = FDIV(ref_len.value, FLTTOFIX(1.2));
size->data.length.unit = ref_len.unit;
size->status = CSS_FONT_SIZE_DIMENSION;
@@ -405,9 +458,8 @@ css_error css_unit_compute_absolute_font_size(
/* Convert any relative units to absolute. */
switch (size->data.length.unit) {
case CSS_UNIT_PCT:
- ref_len = css_unit__get_font_size(ctx, ctx->ref_style);
- size->data.length.value = FDIV(
- FMUL(size->data.length.value,
+ size->data.length.value = FDIV(FMUL(
+ size->data.length.value,
ref_len.value), INTTOFIX(100));
size->data.length.unit = ref_len.unit;
break;
@@ -416,11 +468,8 @@ css_error css_unit_compute_absolute_font_size(
case CSS_UNIT_EX: /* Fall-through */
case CSS_UNIT_CH:
/* Parent relative units. */
- ref_len = css_unit__get_font_size(ctx, ctx->ref_style);
-
- size->data.length.unit = ref_len.unit;
- size->data.length.value = FMUL(size->data.length.value,
- ref_len.value);
+ size->data.length.value = FMUL(
+ size->data.length.value, ref_len.value);
switch (size->data.length.unit) {
case CSS_UNIT_EX:
@@ -438,15 +487,17 @@ css_error css_unit_compute_absolute_font_size(
default:
break;
}
+ size->data.length.unit = ref_len.unit;
break;
case CSS_UNIT_REM:
/* Root element relative units. */
- ref_len = css_unit__get_font_size(ctx, ctx->root_style);
+ ref_len = css_unit__get_font_size(root_style,
+ font_size_default);
size->data.length.unit = ref_len.unit;
- size->data.length.value = FMUL(size->data.length.value,
- ref_len.value);
+ size->data.length.value = FMUL(
+ size->data.length.value, ref_len.value);
break;
default:
diff --git a/src/select/unit.h b/src/select/unit.h
index 7ed6458..e4d21da 100644
--- a/src/select/unit.h
+++ b/src/select/unit.h
@@ -9,115 +9,7 @@
#ifndef css_select_unit_h_
#define css_select_unit_h_
-/**
- * Client callback for font measuring.
- *
- * \param[in] pw Client data.
- * \param[in] style Style to measure font for, or NULL.
- * \param[in] unit Either CSS_UNIT_EX, or CSS_UNIT_CH.
- * \return length in CSS pixels.
- */
-typedef css_fixed (*css_unit_len_measure)(
- void *pw,
- const css_computed_style *style,
- const css_unit unit);
-
-/**
- * LibCSS unit conversion context.
- *
- * The client callback is optional. It is used for measuring "ch"
- * (glyph '0' advance) and "ex" (height of the letter 'x') units.
- * If a NULL pointer is given, LibCSS will use a fixed scaling of
- * the "em" unit.
- */
-typedef struct css_unit_len_ctx {
- /**
- * Viewport width in CSS pixels.
- * Used if unit is vh, vw, vi, vb, vmin, or vmax.
- */
- css_fixed viewport_width;
- /**
- * Viewport height in CSS pixels.
- * Used if unit is vh, vw, vi, vb, vmin, or vmax.
- */
- css_fixed viewport_height;
- /**
- * Client default font size in CSS pixels.
- */
- css_fixed font_size_default;
- /**
- * Client minimum font size in CSS pixels. May be zero.
- */
- css_fixed font_size_minimum;
- /**
- * DPI of the device the style is selected for.
- */
- css_fixed device_dpi;
- /**
- * Reference style. Most of the time, this is the element's style.
- * When converting a length for a typographical property, such as
- * font-size, then this should be the parent node. If the node has
- * no parent then this may be NULL.
- */
- const css_computed_style *ref_style;
- /**
- * Computed style for the document root element.
- * May be NULL if unit is not rem.
- */
- const css_computed_style *root_style;
- /**
- * Client private word for measure callback.
- */
- void *pw;
- /**
- * Client callback for font measuring.
- */
- const css_unit_len_measure measure;
-} css_unit_len_ctx;
-
-/**
- * Convert css pixels to physical pixels.
- *
- * \param[in] css_pixels Length in css pixels.
- * \param[in] device_dpi Device dots per inch.
- * \return Length in device pixels.
- */
-static inline css_fixed css_unit_css2device_px(
- const css_fixed css_pixels,
- const css_fixed device_dpi)
-{
- return FDIV(FMUL(css_pixels, device_dpi), F_96);
-}
-
-/**
- * Convert device pixels to css pixels.
- *
- * \param[in] device_pixels Length in physical pixels.
- * \param[in] device_dpi Device dots per inch.
- * \return Length in css pixels.
- */
-static inline css_fixed css_unit_device2css_px(
- const css_fixed device_pixels,
- const css_fixed device_dpi)
-{
- return FDIV(FMUL(device_pixels, F_96), device_dpi);
-}
-
-css_fixed css_unit_font_size_len2pt(
- const css_unit_len_ctx *ctx,
- const css_fixed length,
- const css_unit unit);
-
-
-css_fixed css_unit_len2css_px(
- const css_unit_len_ctx *ctx,
- const css_fixed length,
- const css_unit unit);
-
-css_fixed css_unit_len2device_px(
- const css_unit_len_ctx *ctx,
- const css_fixed length,
- const css_unit unit);
+#include <libcss/unit.h>
/**
* Convert a length to CSS pixels for a media query context.
@@ -135,12 +27,16 @@ css_fixed css_unit_len2px_mq(
/**
* Convert relative font size units to absolute units.
*
- * \param[in] ctx Length unit conversion context.
- * \param[in,out] size The length to convert.
+ * \param[in] ref_length Reference font-size length or NULL.
+ * \param[in] root_style Root element style or NULL.
+ * \param[in] font_size_default Client default font size in CSS pixels.
+ * \param[in,out] size The length to convert.
* \return CSS_OK on success, or appropriate error otherwise.
*/
css_error css_unit_compute_absolute_font_size(
- const css_unit_len_ctx *ctx,
+ const css_hint_length *ref_length,
+ const css_computed_style *root_style,
+ css_fixed font_size_default,
css_hint *size);
#endif
diff --git a/test/data/parse2/units.dat b/test/data/parse2/units.dat
index 1052dc5..800df75 100644
--- a/test/data/parse2/units.dat
+++ b/test/data/parse2/units.dat
@@ -70,14 +70,6 @@
#reset
#data
-* { width: 10cap; }
-#errors
-#expected
-| *
-| width: 10cap
-#reset
-
-#data
* { width: 10ch; }
#errors
#expected
@@ -86,14 +78,6 @@
#reset
#data
-* { width: 10ic; }
-#errors
-#expected
-| *
-| width: 10ic
-#reset
-
-#data
* { width: 10rem; }
#errors
#expected
@@ -110,14 +94,6 @@
#reset
#data
-* { width: 10rlh; }
-#errors
-#expected
-| *
-| width: 10rlh
-#reset
-
-#data
* { width: 10vh; }
#errors
#expected
diff --git a/test/data/select/tests1.dat b/test/data/select/tests1.dat
index 33ba589..919ca88 100644
--- a/test/data/select/tests1.dat
+++ b/test/data/select/tests1.dat
@@ -59,7 +59,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -173,7 +173,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -291,7 +291,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -410,7 +410,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -529,7 +529,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -648,7 +648,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -757,7 +757,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -867,7 +867,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -977,7 +977,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -1086,7 +1086,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -1200,7 +1200,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -1314,7 +1314,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -1429,7 +1429,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -1547,7 +1547,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -1664,7 +1664,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -1787,7 +1787,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -1910,7 +1910,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -2033,7 +2033,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -2160,7 +2160,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -2286,7 +2286,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -2410,7 +2410,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -2533,7 +2533,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -2656,7 +2656,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -2779,7 +2779,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -2902,7 +2902,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -3025,7 +3025,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -3148,7 +3148,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -3271,7 +3271,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -3394,7 +3394,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -3517,7 +3517,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -3640,7 +3640,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 10.600pt
+font-size: 13.342px
font-style: normal
font-variant: normal
font-weight: normal
@@ -3763,7 +3763,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 14.391pt
+font-size: 19.187px
font-style: normal
font-variant: normal
font-weight: normal
@@ -3886,7 +3886,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 24pt
+font-size: 32px
font-style: normal
font-variant: normal
font-weight: normal
@@ -4009,7 +4009,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 18pt
+font-size: 24px
font-style: normal
font-variant: normal
font-weight: normal
@@ -4132,7 +4132,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 13.500pt
+font-size: 18px
font-style: normal
font-variant: normal
font-weight: normal
@@ -4255,7 +4255,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -4378,7 +4378,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 9.750pt
+font-size: 13px
font-style: normal
font-variant: normal
font-weight: normal
@@ -4501,7 +4501,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 7.500pt
+font-size: 10px
font-style: normal
font-variant: normal
font-weight: normal
@@ -4624,7 +4624,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 6.750pt
+font-size: 9px
font-style: normal
font-variant: normal
font-weight: normal
@@ -4870,7 +4870,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -4986,7 +4986,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -5102,7 +5102,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -5218,7 +5218,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -5331,7 +5331,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -5445,7 +5445,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -5559,7 +5559,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -5673,7 +5673,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -5783,7 +5783,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -5894,7 +5894,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -6004,7 +6004,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -6114,7 +6114,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -6224,7 +6224,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -6334,7 +6334,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -6444,7 +6444,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -6556,7 +6556,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -6666,7 +6666,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -6776,7 +6776,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -6887,7 +6887,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -6997,7 +6997,7 @@ flex-shrink: 3.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -7107,7 +7107,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -7217,7 +7217,7 @@ flex-shrink: 0.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -7327,7 +7327,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -7437,7 +7437,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -7547,7 +7547,7 @@ flex-shrink: 0.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -7657,7 +7657,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -7766,7 +7766,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -7875,7 +7875,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -7984,7 +7984,7 @@ flex-shrink: 30.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -8095,7 +8095,7 @@ flex-shrink: 3.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -8206,7 +8206,7 @@ flex-shrink: 3.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -8315,7 +8315,7 @@ flex-shrink: 0.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -8426,7 +8426,7 @@ flex-shrink: 0.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -8537,7 +8537,7 @@ flex-shrink: 3.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -8648,7 +8648,7 @@ flex-shrink: 3.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -8757,7 +8757,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -8866,7 +8866,7 @@ flex-shrink: 1.000
flex-wrap: wrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -8975,7 +8975,7 @@ flex-shrink: 1.000
flex-wrap: wrap-reverse
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -9084,7 +9084,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -9193,7 +9193,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -9302,7 +9302,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -9411,7 +9411,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -9520,7 +9520,7 @@ flex-shrink: 1.000
flex-wrap: wrap-reverse
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -9631,7 +9631,7 @@ flex-shrink: 1.000
flex-wrap: wrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -9742,7 +9742,7 @@ flex-shrink: 1.000
flex-wrap: wrap-reverse
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -9851,7 +9851,7 @@ flex-shrink: 0.899
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -9960,7 +9960,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -10069,7 +10069,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -10178,7 +10178,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -10287,7 +10287,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -10396,7 +10396,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -10505,7 +10505,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -10616,7 +10616,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -10727,7 +10727,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -10836,7 +10836,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -10945,7 +10945,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -11054,7 +11054,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -11165,7 +11165,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -11274,7 +11274,7 @@ flex-shrink: 3.780
flex-wrap: wrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -11385,7 +11385,7 @@ flex-shrink: 3.780
flex-wrap: wrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -11494,7 +11494,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -11603,7 +11603,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -11712,7 +11712,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -11821,7 +11821,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -11930,7 +11930,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -12039,7 +12039,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -12148,7 +12148,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -12257,7 +12257,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -12366,7 +12366,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -12419,7 +12419,7 @@ z-index: auto
#tree
| div*
#ua
-div { width: 10cap; }
+div { width: 10em; }
#errors
#expected
align-content: stretch
@@ -12475,7 +12475,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -12519,7 +12519,7 @@ unicode-bidi: normal
vertical-align: baseline
visibility: visible
white-space: normal
-width: 10cap
+width: 10em
word-spacing: normal
writing-mode: horizontal-tb
z-index: auto
@@ -12584,7 +12584,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -12637,7 +12637,7 @@ z-index: auto
#tree
| div*
#ua
-div { width: 10ic; }
+div { width: 10ch; }
#errors
#expected
align-content: stretch
@@ -12693,7 +12693,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -12737,7 +12737,7 @@ unicode-bidi: normal
vertical-align: baseline
visibility: visible
white-space: normal
-width: 10ic
+width: 10ch
word-spacing: normal
writing-mode: horizontal-tb
z-index: auto
@@ -12802,7 +12802,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -12911,7 +12911,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -12964,7 +12964,7 @@ z-index: auto
#tree
| div*
#ua
-div { width: 10rlh; }
+div { width: 10rem; }
#errors
#expected
align-content: stretch
@@ -13020,7 +13020,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -13064,7 +13064,7 @@ unicode-bidi: normal
vertical-align: baseline
visibility: visible
white-space: normal
-width: 10rlh
+width: 10rem
word-spacing: normal
writing-mode: horizontal-tb
z-index: auto
@@ -13129,7 +13129,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -13238,7 +13238,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -13347,7 +13347,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -13456,7 +13456,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -13565,7 +13565,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -13674,7 +13674,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -13783,7 +13783,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -13892,7 +13892,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
@@ -14020,7 +14020,7 @@ flex-shrink: 1.000
flex-wrap: nowrap
float: none
font-family: sans-serif
-font-size: 12pt
+font-size: 16px
font-style: normal
font-variant: normal
font-weight: normal
diff --git a/test/dump.h b/test/dump.h
index d67bb2a..79819e0 100644
--- a/test/dump.h
+++ b/test/dump.h
@@ -584,24 +584,15 @@ static void dump_unit(css_fixed val, uint32_t unit, char **ptr)
case UNIT_PC:
*ptr += sprintf(*ptr, "pc");
break;
- case UNIT_CAP:
- *ptr += sprintf(*ptr, "cap");
- break;
case UNIT_CH:
*ptr += sprintf(*ptr, "ch");
break;
- case UNIT_IC:
- *ptr += sprintf(*ptr, "ic");
- break;
case UNIT_REM:
*ptr += sprintf(*ptr, "rem");
break;
case UNIT_LH:
*ptr += sprintf(*ptr, "lh");
break;
- case UNIT_RLH:
- *ptr += sprintf(*ptr, "rlh");
- break;
case UNIT_VH:
*ptr += sprintf(*ptr, "vh");
break;
diff --git a/test/dump_computed.h b/test/dump_computed.h
index b0c8bda..8ac6424 100644
--- a/test/dump_computed.h
+++ b/test/dump_computed.h
@@ -105,24 +105,15 @@ static size_t dump_css_unit(css_fixed val, css_unit unit, char *ptr, size_t len)
case CSS_UNIT_PC:
ret += snprintf(ptr + ret, len - ret, "pc");
break;
- case CSS_UNIT_CAP:
- ret += snprintf(ptr + ret, len - ret, "cap");
- break;
case CSS_UNIT_CH:
ret += snprintf(ptr + ret, len - ret, "ch");
break;
- case CSS_UNIT_IC:
- ret += snprintf(ptr + ret, len - ret, "ic");
- break;
case CSS_UNIT_REM:
ret += snprintf(ptr + ret, len - ret, "rem");
break;
case CSS_UNIT_LH:
ret += snprintf(ptr + ret, len - ret, "lh");
break;
- case CSS_UNIT_RLH:
- ret += snprintf(ptr + ret, len - ret, "rlh");
- break;
case CSS_UNIT_VH:
ret += snprintf(ptr + ret, len - ret, "vh");
break;
diff --git a/test/select.c b/test/select.c
index 664994e..8226a8b 100644
--- a/test/select.c
+++ b/test/select.c
@@ -159,13 +159,15 @@ static css_error node_presentational_hint(void *pw, void *node,
uint32_t *nhints, css_hint **hints);
static css_error ua_default_for_property(void *pw, uint32_t property,
css_hint *hints);
-static css_error compute_font_size(void *pw, const css_hint *parent,
- css_hint *size);
static css_error set_libcss_node_data(void *pw, void *n,
void *libcss_node_data);
static css_error get_libcss_node_data(void *pw, void *n,
void **libcss_node_data);
+static css_unit_len_ctx unit_len_ctx = {
+ .font_size_default = 16 * (1 << CSS_RADIX_POINT),
+};
+
static css_select_handler select_handler = {
CSS_SELECT_HANDLER_VERSION_1,
@@ -203,9 +205,9 @@ static css_select_handler select_handler = {
node_is_lang,
node_presentational_hint,
ua_default_for_property,
- compute_font_size,
+
set_libcss_node_data,
- get_libcss_node_data
+ get_libcss_node_data,
};
static css_error resolve_url(void *pw,
@@ -765,7 +767,12 @@ static void run_test_select_tree(css_select_ctx *select,
css_select_results *sr;
struct node *n = NULL;
- assert(css_select_style(select, node, &ctx->media, NULL,
+ if (node->parent == NULL) {
+ unit_len_ctx.root_style = NULL;
+ }
+
+
+ assert(css_select_style(select, node, &unit_len_ctx, &ctx->media, NULL,
&select_handler, ctx, &sr) == CSS_OK);
if (node->parent != NULL) {
@@ -773,7 +780,7 @@ static void run_test_select_tree(css_select_ctx *select,
assert(css_computed_style_compose(
node->parent->sr->styles[ctx->pseudo_element],
sr->styles[ctx->pseudo_element],
- compute_font_size, NULL,
+ &unit_len_ctx,
&composed) == CSS_OK);
css_computed_style_destroy(sr->styles[ctx->pseudo_element]);
sr->styles[ctx->pseudo_element] = composed;
@@ -786,6 +793,10 @@ static void run_test_select_tree(css_select_ctx *select,
buf, buflen);
}
+ if (node->parent == NULL) {
+ unit_len_ctx.root_style = node->sr->styles[ctx->pseudo_element];
+ }
+
for (n = node->children; n != NULL; n = n->next) {
run_test_select_tree(select, n, ctx, buf, buflen);
}
@@ -1606,68 +1617,6 @@ css_error ua_default_for_property(void *pw, uint32_t property, css_hint *hint)
return CSS_OK;
}
-css_error compute_font_size(void *pw, const css_hint *parent, css_hint *size)
-{
- static css_hint_length sizes[] = {
- { FLTTOFIX(6.75), CSS_UNIT_PT },
- { FLTTOFIX(7.50), CSS_UNIT_PT },
- { FLTTOFIX(9.75), CSS_UNIT_PT },
- { FLTTOFIX(12.0), CSS_UNIT_PT },
- { FLTTOFIX(13.5), CSS_UNIT_PT },
- { FLTTOFIX(18.0), CSS_UNIT_PT },
- { FLTTOFIX(24.0), CSS_UNIT_PT }
- };
- const css_hint_length *parent_size;
-
- UNUSED(pw);
-
- /* Grab parent size, defaulting to medium if none */
- if (parent == NULL) {
- parent_size = &sizes[CSS_FONT_SIZE_MEDIUM - 1];
- } else {
- assert(parent->status == CSS_FONT_SIZE_DIMENSION);
- assert(parent->data.length.unit != CSS_UNIT_EM);
- assert(parent->data.length.unit != CSS_UNIT_EX);
- parent_size = &parent->data.length;
- }
-
- assert(size->status != CSS_FONT_SIZE_INHERIT);
-
- if (size->status < CSS_FONT_SIZE_LARGER) {
- /* Keyword -- simple */
- size->data.length = sizes[size->status - 1];
- } else if (size->status == CSS_FONT_SIZE_LARGER) {
- /** \todo Step within table, if appropriate */
- size->data.length.value =
- FMUL(parent_size->value, FLTTOFIX(1.2));
- size->data.length.unit = parent_size->unit;
- } else if (size->status == CSS_FONT_SIZE_SMALLER) {
- /** \todo Step within table, if appropriate */
- size->data.length.value =
- FDIV(parent_size->value, FLTTOFIX(1.2));
- size->data.length.unit = parent_size->unit;
- } else if (size->data.length.unit == CSS_UNIT_EM ||
- size->data.length.unit == CSS_UNIT_EX) {
- size->data.length.value =
- FMUL(size->data.length.value, parent_size->value);
-
- if (size->data.length.unit == CSS_UNIT_EX) {
- size->data.length.value = FMUL(size->data.length.value,
- FLTTOFIX(0.6));
- }
-
- size->data.length.unit = parent_size->unit;
- } else if (size->data.length.unit == CSS_UNIT_PCT) {
- size->data.length.value = FDIV(FMUL(size->data.length.value,
- parent_size->value), FLTTOFIX(100));
- size->data.length.unit = parent_size->unit;
- }
-
- size->status = CSS_FONT_SIZE_DIMENSION;
-
- return CSS_OK;
-}
-
static css_error set_libcss_node_data(void *pw, void *n,
void *libcss_node_data)
{
--
Cascading Style Sheets library
2 years, 6 months
netsurf: branch master updated. release/3.10-124-g6faa708
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/6faa70893b70fc43d6f39...
...commit http://git.netsurf-browser.org/netsurf.git/commit/6faa70893b70fc43d6f398f...
...tree http://git.netsurf-browser.org/netsurf.git/tree/6faa70893b70fc43d6f398f2e...
The branch, master has been updated
via 6faa70893b70fc43d6f398f2e43719c763c2d193 (commit)
from a11ad57bf64ae4e701e049ced1233cc4c7b22054 (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=6faa70893b70fc43d6f...
commit 6faa70893b70fc43d6f398f2e43719c763c2d193
Author: Michael Drake <michael.drake(a)codethink.co.uk>
Commit: Michael Drake <michael.drake(a)codethink.co.uk>
Buildsystem: Avoid errors when headers are removed.
diff --git a/Makefile.macros b/Makefile.macros
index d8468b4..9421acf 100644
--- a/Makefile.macros
+++ b/Makefile.macros
@@ -207,7 +207,7 @@ $$(OBJROOT)/$(2): $(1) $$(OBJROOT)/created $$(DEPROOT)/created
$$(Q)$$(RM) $$(DEPROOT)/$(3)
$$(Q)$$(RM) $$(OBJROOT)/$(2)
$$(Q)$$(CC) $$(COMMON_WARNFLAGS) $$(CWARNFLAGS) $$(IFLAGS) $$(CFLAGS) $(CFLAGS_ENV) \
- -MMD -MT '$$(DEPROOT)/$(3) $$(OBJROOT)/$(2)' \
+ -MMD -MP -MT '$$(DEPROOT)/$(3) $$(OBJROOT)/$(2)' \
-MF $$(DEPROOT)/$(3) -o $$(OBJROOT)/$(2) -c $(1)
endef
-----------------------------------------------------------------------
Summary of changes:
Makefile.macros | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile.macros b/Makefile.macros
index d8468b4..9421acf 100644
--- a/Makefile.macros
+++ b/Makefile.macros
@@ -207,7 +207,7 @@ $$(OBJROOT)/$(2): $(1) $$(OBJROOT)/created $$(DEPROOT)/created
$$(Q)$$(RM) $$(DEPROOT)/$(3)
$$(Q)$$(RM) $$(OBJROOT)/$(2)
$$(Q)$$(CC) $$(COMMON_WARNFLAGS) $$(CWARNFLAGS) $$(IFLAGS) $$(CFLAGS) $(CFLAGS_ENV) \
- -MMD -MT '$$(DEPROOT)/$(3) $$(OBJROOT)/$(2)' \
+ -MMD -MP -MT '$$(DEPROOT)/$(3) $$(OBJROOT)/$(2)' \
-MF $$(DEPROOT)/$(3) -o $$(OBJROOT)/$(2) -c $(1)
endef
--
NetSurf Browser
2 years, 6 months
libnsgif: branch master updated. release/0.2.1-3-g3665353
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/libnsgif.git/shortlog/3665353c4da1dfb7b4a1...
...commit http://git.netsurf-browser.org/libnsgif.git/commit/3665353c4da1dfb7b4a1d9...
...tree http://git.netsurf-browser.org/libnsgif.git/tree/3665353c4da1dfb7b4a1d9fa...
The branch, master has been updated
via 3665353c4da1dfb7b4a1d9fa412f0dec2cb673d2 (commit)
from e5802bc82dd3b85eec48437c44a299457f6b3b3c (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/libnsgif.git/commit/?id=3665353c4da1dfb7b4...
commit 3665353c4da1dfb7b4a1d9fa412f0dec2cb673d2
Author: John Cupitt <jcupitt(a)gmail.com>
Commit: Michael Drake <michael.drake(a)codethink.co.uk>
fix libnsgif restore/record ordering
diff --git a/src/libnsgif.c b/src/libnsgif.c
index 479d161..49e790a 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -680,11 +680,6 @@ gif_internal_decode_frame(gif_animation *gif,
return GIF_OK;
}
- if (gif->frames[frame].disposal_method == GIF_FRAME_RESTORE) {
- /* Store the previous frame for later restoration */
- gif__record_previous_frame(gif);
- }
-
/* Get the start of our frame data and the end of the GIF data */
gif_data = gif->gif_data + gif->frames[frame].frame_pointer;
gif_end = gif->gif_data + gif->buffer_size;
@@ -873,6 +868,12 @@ gif_internal_decode_frame(gif_animation *gif,
gif->width * gif->height * sizeof(int));
}
}
+
+ if (gif->frames[frame].disposal_method == GIF_FRAME_RESTORE) {
+ /* Store the previous frame for later restoration */
+ gif__record_previous_frame(gif);
+ }
+
gif->decoded_frame = frame;
gif->buffer_position = (gif_data - gif->gif_data) + 1;
-----------------------------------------------------------------------
Summary of changes:
src/libnsgif.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/src/libnsgif.c b/src/libnsgif.c
index 479d161..49e790a 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -680,11 +680,6 @@ gif_internal_decode_frame(gif_animation *gif,
return GIF_OK;
}
- if (gif->frames[frame].disposal_method == GIF_FRAME_RESTORE) {
- /* Store the previous frame for later restoration */
- gif__record_previous_frame(gif);
- }
-
/* Get the start of our frame data and the end of the GIF data */
gif_data = gif->gif_data + gif->frames[frame].frame_pointer;
gif_end = gif->gif_data + gif->buffer_size;
@@ -873,6 +868,12 @@ gif_internal_decode_frame(gif_animation *gif,
gif->width * gif->height * sizeof(int));
}
}
+
+ if (gif->frames[frame].disposal_method == GIF_FRAME_RESTORE) {
+ /* Store the previous frame for later restoration */
+ gif__record_previous_frame(gif);
+ }
+
gif->decoded_frame = frame;
gif->buffer_position = (gif_data - gif->gif_data) + 1;
--
NetSurf GIF Decoder
2 years, 6 months
netsurf: branch master updated. release/3.10-123-ga11ad57
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/a11ad57bf64ae4e701e04...
...commit http://git.netsurf-browser.org/netsurf.git/commit/a11ad57bf64ae4e701e049c...
...tree http://git.netsurf-browser.org/netsurf.git/tree/a11ad57bf64ae4e701e049ced...
The branch, master has been updated
via a11ad57bf64ae4e701e049ced1233cc4c7b22054 (commit)
from 9a7e41d3ea966387eff8abd86198812244cd47bc (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=a11ad57bf64ae4e701e...
commit a11ad57bf64ae4e701e049ced1233cc4c7b22054
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
fix headings to be in doxygen prefered format
diff --git a/docs/implementing-new-frontend.md b/docs/implementing-new-frontend.md
index 03e6180..1b4e438 100644
--- a/docs/implementing-new-frontend.md
+++ b/docs/implementing-new-frontend.md
@@ -1,8 +1,9 @@
-# Implementing a new frontend
+Implementing a new frontend
+===========================
[TOC]
-## Introduction
+# Introduction
NetSurf is divided into a series of frontends which provide a user
interface around common core functionality.
@@ -35,7 +36,7 @@ objective C. However any language that can call C functions and
example there have been experiments with JAVA using JNI but no current
frontend is implemented using it.
-## Implementation complexity
+# Implementation complexity
An absolutely minimal "proof of concept" frontend implementation (like
the FLTK frontend that will be used as an example) is around 1,000
@@ -55,7 +56,7 @@ support with the [core window API](docs/core-window-interface.md).
A frontend developer is free to implement any and all of this generic
functionality thelselves in a manner more integrated into a toolkit.
-## Implementation
+# Implementation
A frontend is generally named for the toolkit it is implementing (i.e
gtk for the GTK+ toolkit). It is advisable to be as specific as
@@ -70,7 +71,7 @@ The only file outside this directory that much be changed is the
`frontends/Makefile.hts` where a new entry must be added to the valid
targets list.
-### Build system
+## Build system
A frontend must provide three GNU Makefile fragments (these will be
included from the core Makefile):
@@ -83,7 +84,7 @@ Source code modules can be named as the devloper desires within the
frontend directory and should be added to the SOURCES variable as
desired.
-### Program entry
+## Program entry
Generally the entry point from the OS is the `main()` function and
several frontends have a `main.cpp` where some have used `gui.c`.
@@ -96,7 +97,7 @@ The usual shape for the `main()` function is a six step process:
5. Run the toolkits main loop while ensuring the Netsurf scheduled operations are also run at teh apropriate time.
6. Finalisation on completion.
-### NetSurf operations tables
+## NetSurf operations tables
The frontend will generally call netsurf interfaces to get a desired
behaviour e.g. `browser_window_create()` to create a new browsing
@@ -119,7 +120,7 @@ In this context mandantory means the tables must be non NULL and do
not have a suitable default. Each of the mandantory sets contain
function pointers to implement operations.
-#### misc operation table
+### misc operation table
The only mandantory operation in this table is schedule.
@@ -130,7 +131,7 @@ miliseconds.
This callback is typicaly driven through the toolkits event loop and
it is important such callbacks are not attempted from an operation.
-#### window operation table
+### window operation table
The window operations (poorly named as already mentioned) are where
the frontend is called to actually manipulate widgets in the
@@ -152,7 +153,7 @@ The mandantory window operations are:
- event - deal with various window events from netsurf which have no additional parameters
-#### fetch operation table
+### fetch operation table
The fetch operations allow the built in scheme fetchers (file, about, resource) to obtain additional information necessary to complete their operation.
@@ -160,7 +161,7 @@ The two mandantory operations are:
- `filetype` - allows the file scheme to obtain a mime type from a file path e.g. `a.file.name.png` would result in `image/png`
- `get_resource_url` - maps resource scheme paths to URL e.g. `resource:default.css` to `file:///usr/share/netsurf/default.css`
-#### bitmap operation table
+### bitmap operation table
The bitmap table and all of its operations are mandantory only because
the empty defaults have not been included as it is assumed a browser
@@ -169,7 +170,7 @@ will want to display images.
All operations may be provided by stubs that return the failure codes
until full implementations are made.
-#### layout operation table
+### layout operation table
The layout table is used to layout text. All operations are given
strings to manipulate encoded in UTF-8. There are three mandantory
@@ -178,7 +179,7 @@ operations:
- `position` - Find the position in a string where an x coordinate falls.
- `split` - Find where to split a string to make it fit a width.
-## Worked Example
+# Worked Example
Rather than attempt to describe every aspect of an implementation we
will rather work from an actual minimal example for the FLTK toolkit.
@@ -190,7 +191,7 @@ window on screen (and be able to click visible links). It is
implemented in C++ as that is the FLTK implementation language but an
equivalent implementation in other languages should be obvious.
-### Building
+## Building
The [frontends/Makefile.hts](https://git.netsurf-browser.org/netsurf.git/diff/...
had the fltk target added to the VLDTARGET variable. This allows
@@ -205,20 +206,19 @@ comment suggests it is important the SOURCES variable is not expanded
here so the S_FRONTEND variable is used to allow expansion at teh
correct time in the build process.
-
[Makefile.defaults](https://git.netsurf-browser.org/netsurf.git/diff/front...
has the default setting to control the build parameters and file locations. These can be overriden by the `Makefile.config` at compile time.
[Makefile.tools](https://git.netsurf-browser.org/netsurf.git/diff/frontend...
allows the configuration of additional tools necessary to build for the target as a minimum pkg-config is usually required to find libraries.
-### Program entry
+## Program entry
In our example program entry is the classical `main()` in the [main.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk... module.
This implements the six stage process outlined previously.
-#### Operations table registration
+### Operations table registration
The `netsurf_table` structure is initialised and passed to
`netsurf_register()`. It should be noted that the approach taken here
@@ -227,7 +227,7 @@ table. The header for each module exposes just the pointer to the
indivial operation set, this allows for all the operation functions to
be static to their module and hence helps reduce global symbol usage.
-#### Frontend specific initialisation
+### Frontend specific initialisation
Her it is implemented in `nsfltk_init()` this function performs all
the operations specific to the frontend which must be initialised
@@ -238,12 +238,12 @@ It is nessesary to initialise netsurf logging and user options at this
point. A more fully featured implementation would also initialise the
message translation system here.
-#### Netsurf initialisation
+### Netsurf initialisation
This is simply the call to `netsurf_init()` from this point the
browser is fully operational and operations can and will be called.
-#### Frontend specific startup
+### Frontend specific startup
Although the browser is running it has not yet been told to open a
window or navigate to a page. Here `nsfltk_start()` examines the
@@ -254,7 +254,7 @@ the browser to open a new browsing context and start the navigation.
A frontend may choose to implement more complex logic here but the
example here is a good start.
-#### Toolkit run loop
+### Toolkit run loop
The function `nsfltk_run()` runs the toolkit event loop. In this case it is using the generic scheduleing in the [misc.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk... module to ensure callbacks get made at the apropriate time.
@@ -269,7 +269,7 @@ A futher optimisation would be to obtain the set of file descriptors
being used (with `fetch_fdset()`) for active fetches allowing for
activity based fetch progress instead of the fallback polling method.
-#### finalisation
+### finalisation
This simply finalises the browser stopping all activity and cleaning
up any resource usage. After the call to `netsurf_exit()` no more
@@ -282,11 +282,11 @@ should be called.
The finalisation of logging will ensure that any output buffers are
flushed.
-### The window operation table
+## The window operation table
Amongst all the boilerplate of the default implementation the only novel code is in the window operation table in the [window.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fl... module.
-#### `nsfltk_window_create`
+### `nsfltk_window_create`
The create operation instansiates a new `NS_Window` object and
references it in the gui_window structure which it returns to the
@@ -320,16 +320,16 @@ the second and third parameters to the draw call. When scrolling is
required this is achived by altering these offsets.
-#### `nsfltk_window_invalidate()`
+### `nsfltk_window_invalidate()`
This simply calls the damage method on the `Fl_Widget` class with the
appropriate coordinate translation.
-#### `nsfltk_window_get_dimensions()`
+### `nsfltk_window_get_dimensions()`
This obtains the fltk widget width and height and returns them.
-### The plotting interface
+## The plotting interface
When the `NS_Widget::draw` method was discussed it was noted that a
plotting context is built containing an operation table. That table is
@@ -340,7 +340,7 @@ and text have any implementation at all and even that simply sets a
colour and performs the appropriate fltk draw function (`fl_line`,
`fl_rect` and `fl_draw` respectively)
-## Conclusion
+# Conclusion
Hopefully this breif overview and worked example should give the
prospectinve frontend developer enough information to understand how
-----------------------------------------------------------------------
Summary of changes:
docs/implementing-new-frontend.md | 56 ++++++++++++++++++-------------------
1 file changed, 28 insertions(+), 28 deletions(-)
diff --git a/docs/implementing-new-frontend.md b/docs/implementing-new-frontend.md
index 03e6180..1b4e438 100644
--- a/docs/implementing-new-frontend.md
+++ b/docs/implementing-new-frontend.md
@@ -1,8 +1,9 @@
-# Implementing a new frontend
+Implementing a new frontend
+===========================
[TOC]
-## Introduction
+# Introduction
NetSurf is divided into a series of frontends which provide a user
interface around common core functionality.
@@ -35,7 +36,7 @@ objective C. However any language that can call C functions and
example there have been experiments with JAVA using JNI but no current
frontend is implemented using it.
-## Implementation complexity
+# Implementation complexity
An absolutely minimal "proof of concept" frontend implementation (like
the FLTK frontend that will be used as an example) is around 1,000
@@ -55,7 +56,7 @@ support with the [core window API](docs/core-window-interface.md).
A frontend developer is free to implement any and all of this generic
functionality thelselves in a manner more integrated into a toolkit.
-## Implementation
+# Implementation
A frontend is generally named for the toolkit it is implementing (i.e
gtk for the GTK+ toolkit). It is advisable to be as specific as
@@ -70,7 +71,7 @@ The only file outside this directory that much be changed is the
`frontends/Makefile.hts` where a new entry must be added to the valid
targets list.
-### Build system
+## Build system
A frontend must provide three GNU Makefile fragments (these will be
included from the core Makefile):
@@ -83,7 +84,7 @@ Source code modules can be named as the devloper desires within the
frontend directory and should be added to the SOURCES variable as
desired.
-### Program entry
+## Program entry
Generally the entry point from the OS is the `main()` function and
several frontends have a `main.cpp` where some have used `gui.c`.
@@ -96,7 +97,7 @@ The usual shape for the `main()` function is a six step process:
5. Run the toolkits main loop while ensuring the Netsurf scheduled operations are also run at teh apropriate time.
6. Finalisation on completion.
-### NetSurf operations tables
+## NetSurf operations tables
The frontend will generally call netsurf interfaces to get a desired
behaviour e.g. `browser_window_create()` to create a new browsing
@@ -119,7 +120,7 @@ In this context mandantory means the tables must be non NULL and do
not have a suitable default. Each of the mandantory sets contain
function pointers to implement operations.
-#### misc operation table
+### misc operation table
The only mandantory operation in this table is schedule.
@@ -130,7 +131,7 @@ miliseconds.
This callback is typicaly driven through the toolkits event loop and
it is important such callbacks are not attempted from an operation.
-#### window operation table
+### window operation table
The window operations (poorly named as already mentioned) are where
the frontend is called to actually manipulate widgets in the
@@ -152,7 +153,7 @@ The mandantory window operations are:
- event - deal with various window events from netsurf which have no additional parameters
-#### fetch operation table
+### fetch operation table
The fetch operations allow the built in scheme fetchers (file, about, resource) to obtain additional information necessary to complete their operation.
@@ -160,7 +161,7 @@ The two mandantory operations are:
- `filetype` - allows the file scheme to obtain a mime type from a file path e.g. `a.file.name.png` would result in `image/png`
- `get_resource_url` - maps resource scheme paths to URL e.g. `resource:default.css` to `file:///usr/share/netsurf/default.css`
-#### bitmap operation table
+### bitmap operation table
The bitmap table and all of its operations are mandantory only because
the empty defaults have not been included as it is assumed a browser
@@ -169,7 +170,7 @@ will want to display images.
All operations may be provided by stubs that return the failure codes
until full implementations are made.
-#### layout operation table
+### layout operation table
The layout table is used to layout text. All operations are given
strings to manipulate encoded in UTF-8. There are three mandantory
@@ -178,7 +179,7 @@ operations:
- `position` - Find the position in a string where an x coordinate falls.
- `split` - Find where to split a string to make it fit a width.
-## Worked Example
+# Worked Example
Rather than attempt to describe every aspect of an implementation we
will rather work from an actual minimal example for the FLTK toolkit.
@@ -190,7 +191,7 @@ window on screen (and be able to click visible links). It is
implemented in C++ as that is the FLTK implementation language but an
equivalent implementation in other languages should be obvious.
-### Building
+## Building
The [frontends/Makefile.hts](https://git.netsurf-browser.org/netsurf.git/diff/...
had the fltk target added to the VLDTARGET variable. This allows
@@ -205,20 +206,19 @@ comment suggests it is important the SOURCES variable is not expanded
here so the S_FRONTEND variable is used to allow expansion at teh
correct time in the build process.
-
[Makefile.defaults](https://git.netsurf-browser.org/netsurf.git/diff/front...
has the default setting to control the build parameters and file locations. These can be overriden by the `Makefile.config` at compile time.
[Makefile.tools](https://git.netsurf-browser.org/netsurf.git/diff/frontend...
allows the configuration of additional tools necessary to build for the target as a minimum pkg-config is usually required to find libraries.
-### Program entry
+## Program entry
In our example program entry is the classical `main()` in the [main.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk... module.
This implements the six stage process outlined previously.
-#### Operations table registration
+### Operations table registration
The `netsurf_table` structure is initialised and passed to
`netsurf_register()`. It should be noted that the approach taken here
@@ -227,7 +227,7 @@ table. The header for each module exposes just the pointer to the
indivial operation set, this allows for all the operation functions to
be static to their module and hence helps reduce global symbol usage.
-#### Frontend specific initialisation
+### Frontend specific initialisation
Her it is implemented in `nsfltk_init()` this function performs all
the operations specific to the frontend which must be initialised
@@ -238,12 +238,12 @@ It is nessesary to initialise netsurf logging and user options at this
point. A more fully featured implementation would also initialise the
message translation system here.
-#### Netsurf initialisation
+### Netsurf initialisation
This is simply the call to `netsurf_init()` from this point the
browser is fully operational and operations can and will be called.
-#### Frontend specific startup
+### Frontend specific startup
Although the browser is running it has not yet been told to open a
window or navigate to a page. Here `nsfltk_start()` examines the
@@ -254,7 +254,7 @@ the browser to open a new browsing context and start the navigation.
A frontend may choose to implement more complex logic here but the
example here is a good start.
-#### Toolkit run loop
+### Toolkit run loop
The function `nsfltk_run()` runs the toolkit event loop. In this case it is using the generic scheduleing in the [misc.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk... module to ensure callbacks get made at the apropriate time.
@@ -269,7 +269,7 @@ A futher optimisation would be to obtain the set of file descriptors
being used (with `fetch_fdset()`) for active fetches allowing for
activity based fetch progress instead of the fallback polling method.
-#### finalisation
+### finalisation
This simply finalises the browser stopping all activity and cleaning
up any resource usage. After the call to `netsurf_exit()` no more
@@ -282,11 +282,11 @@ should be called.
The finalisation of logging will ensure that any output buffers are
flushed.
-### The window operation table
+## The window operation table
Amongst all the boilerplate of the default implementation the only novel code is in the window operation table in the [window.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fl... module.
-#### `nsfltk_window_create`
+### `nsfltk_window_create`
The create operation instansiates a new `NS_Window` object and
references it in the gui_window structure which it returns to the
@@ -320,16 +320,16 @@ the second and third parameters to the draw call. When scrolling is
required this is achived by altering these offsets.
-#### `nsfltk_window_invalidate()`
+### `nsfltk_window_invalidate()`
This simply calls the damage method on the `Fl_Widget` class with the
appropriate coordinate translation.
-#### `nsfltk_window_get_dimensions()`
+### `nsfltk_window_get_dimensions()`
This obtains the fltk widget width and height and returns them.
-### The plotting interface
+## The plotting interface
When the `NS_Widget::draw` method was discussed it was noted that a
plotting context is built containing an operation table. That table is
@@ -340,7 +340,7 @@ and text have any implementation at all and even that simply sets a
colour and performs the appropriate fltk draw function (`fl_line`,
`fl_rect` and `fl_draw` respectively)
-## Conclusion
+# Conclusion
Hopefully this breif overview and worked example should give the
prospectinve frontend developer enough information to understand how
--
NetSurf Browser
2 years, 6 months
netsurf: branch master updated. release/3.10-122-g9a7e41d
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/9a7e41d3ea966387eff8a...
...commit http://git.netsurf-browser.org/netsurf.git/commit/9a7e41d3ea966387eff8abd...
...tree http://git.netsurf-browser.org/netsurf.git/tree/9a7e41d3ea966387eff8abd86...
The branch, master has been updated
via 9a7e41d3ea966387eff8abd86198812244cd47bc (commit)
from 5e31f045a03753e2d65c3d65ef27d10919648eff (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=9a7e41d3ea966387eff...
commit 9a7e41d3ea966387eff8abd86198812244cd47bc
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
add document outlining new frontend development
diff --git a/docs/development.md b/docs/development.md
index 5a8d1aa..3f08b54 100644
--- a/docs/development.md
+++ b/docs/development.md
@@ -69,6 +69,12 @@ NetSurf [integration tests](docs/integration-testing.md) use the
monkey frontend to operate the browser as a whole. These tests open
windows, navigate to websites and render contents as a user might.
+# New frontend development
+
+[Implementing a new frotend](docs/implementing-new-frontend.md) for a
+toolkit can be challenging and this guide provides an overview and
+worked example.
+
# Documented API
The NetSurf code makes use of Doxygen for code documentation.
diff --git a/docs/implementing-new-frontend.md b/docs/implementing-new-frontend.md
new file mode 100644
index 0000000..03e6180
--- /dev/null
+++ b/docs/implementing-new-frontend.md
@@ -0,0 +1,352 @@
+# Implementing a new frontend
+
+[TOC]
+
+## Introduction
+
+NetSurf is divided into a series of frontends which provide a user
+interface around common core functionality.
+
+Each frontend is a distinct implementation for a specific GUI toolkit.
+
+The existing frontends are covered in the [user
+interface](docs/user-interface.md) documentation.
+
+Note implementing a new frontend implies using a toolkit distinct from
+one of those already implemented and is distinct from porting NetSurf
+to a new operating system platform.
+
+It is recommend, in the strongest terms, that if the prospective
+developer is porting to both a new platform and toolkit that they
+*start* by getting the [monkey](docs/using-monkey.md) frontend
+building and passing at least the basic integration tests on their
+platform.
+
+Experience has shown that attempting to port to a platform and
+implement a toolkit at the same time generally results in failure to
+achieve either goal.
+
+NetSurf is built using GNU make and frontends are expected to
+integrate with this buildsystem.
+
+Implementation languages have historically been limited to C, C++ and
+objective C. However any language that can call C functions and
+*importantly* be called back from C code ought to be usable. For
+example there have been experiments with JAVA using JNI but no current
+frontend is implemented using it.
+
+## Implementation complexity
+
+An absolutely minimal "proof of concept" frontend implementation (like
+the FLTK frontend that will be used as an example) is around 1,000
+lines of C code. Basic functionality like the windows frontend is
+around 7,000 lines. A complete fully functional frontend such as the
+one for GTK is closer to 15,000 lines.
+
+It should be noted the majority of the minimal implementation can
+simply be copied and the names changed as appropriate from an existing
+example. The actual amount of new code that needs to be provided is
+very small.
+
+NetSurf provides a great deal of generic functionality for things like
+cookie, bookmark, history windows which require only minimal frontend
+support with the [core window API](docs/core-window-interface.md).
+
+A frontend developer is free to implement any and all of this generic
+functionality thelselves in a manner more integrated into a toolkit.
+
+## Implementation
+
+A frontend is generally named for the toolkit it is implementing (i.e
+gtk for the GTK+ toolkit). It is advisable to be as specific as
+possible e.g. the frontend for the windows operating system should
+have been named win32 allowing for an impementation using a differnt
+toolkit (e.g mfc)
+
+All the files needed for the frontend are contained in a single
+sub-directory in the NetSurf source tree e.g. `frontends/fltk`
+
+The only file outside this directory that much be changed is the
+`frontends/Makefile.hts` where a new entry must be added to the valid
+targets list.
+
+### Build system
+
+A frontend must provide three GNU Makefile fragments (these will be
+included from the core Makefile):
+
+ - `Makefile` - This is used to extend CFLAGS, CXXFLAGS and LDFLAGS variables as required. The executable target is set with EXETARGET and the browser source files are listed in the SOURCES variable
+ - `Makefile.defaults` - allows setting frontend specific makefile variables and overriding of the default core build variables.
+ - `Makefile.tools` - allows setting up frontend specific build tooling (as a minimum a tool for the package configuration in PKG_CONFIG)
+
+Source code modules can be named as the devloper desires within the
+frontend directory and should be added to the SOURCES variable as
+desired.
+
+### Program entry
+
+Generally the entry point from the OS is the `main()` function and
+several frontends have a `main.cpp` where some have used `gui.c`.
+
+The usual shape for the `main()` function is a six step process:
+ 1. The frontends operation tables are registered with NetSurf
+ 2. The toolkit specific initialisation is performed (which may involve calling NetSurf provided utility functions for support operations like logging, message translations etc.)
+ 3. Initialise the NetSurf core. After this point all browser functionality is available and registered operations can be called.
+ 4. Perform toolkiit setup, usually opening the initial browsing window (perhaps according to user preferences)
+ 5. Run the toolkits main loop while ensuring the Netsurf scheduled operations are also run at teh apropriate time.
+ 6. Finalisation on completion.
+
+### NetSurf operations tables
+
+The frontend will generally call netsurf interfaces to get a desired
+behaviour e.g. `browser_window_create()` to create a new browsing
+context (the `browser_window_` prefix is historical and does not
+necessarily create a window e.g. on gtk it is more likely to open a
+tab in an existing window). To achive the desired operation some
+operations need to be performed by the frontend under control of
+NetSurf, these operations are listed in tables.
+
+The operation tables should be registered with the NetSurf core as one
+of the first operations of the frontend code. The functions in these
+tables (and the tables themselves) must remain valid until
+`netsurf_exit()` is called.
+
+There are (currently) twelve sets of operation tables held in separate
+structures. Only five of these are mandantory (misc, window, fetch,
+bitmap and layout).
+
+In this context mandantory means the tables must be non NULL and do
+not have a suitable default. Each of the mandantory sets contain
+function pointers to implement operations.
+
+#### misc operation table
+
+The only mandantory operation in this table is schedule.
+
+When schedule is called the frontend must arrange for the passed
+callback to be called with the context parameter after a number of
+miliseconds.
+
+This callback is typicaly driven through the toolkits event loop and
+it is important such callbacks are not attempted from an operation.
+
+#### window operation table
+
+The window operations (poorly named as already mentioned) are where
+the frontend is called to actually manipulate widgets in the
+toolkit. This is mediated through a `gui_window` context pointer which
+is typed as a structure.
+
+This context pointer is passed to all window operations and is
+generally assumed to contain at least a reference to the underlying
+`browser_window` which is provided in the initial create operation to
+allow subsequent use of various core functionality.
+
+The mandantory window operations are:
+ - create - create a new browsing context widget in the frontend toolkit
+ - destroy - destoy a previously created `gui_window`
+ - invalidate - mark an area of the browsing context viewport as requiring redraw (note no redraw should be attempted from here)
+ - get_scroll - get the scroll offsets from the toolkit drawing widget
+ - set_scroll - set the scroll offsets on the toolkit drawing widget
+ - get_dimensions - get the dimensions of the toolkit drawing widget
+ - event - deal with various window events from netsurf which have no additional parameters
+
+
+#### fetch operation table
+
+The fetch operations allow the built in scheme fetchers (file, about, resource) to obtain additional information necessary to complete their operation.
+
+The two mandantory operations are:
+ - `filetype` - allows the file scheme to obtain a mime type from a file path e.g. `a.file.name.png` would result in `image/png`
+ - `get_resource_url` - maps resource scheme paths to URL e.g. `resource:default.css` to `file:///usr/share/netsurf/default.css`
+
+#### bitmap operation table
+
+The bitmap table and all of its operations are mandantory only because
+the empty defaults have not been included as it is assumed a browser
+will want to display images.
+
+All operations may be provided by stubs that return the failure codes
+until full implementations are made.
+
+#### layout operation table
+
+The layout table is used to layout text. All operations are given
+strings to manipulate encoded in UTF-8. There are three mandantory
+operations:
+ - `width` - Calculate the width of a string.
+ - `position` - Find the position in a string where an x coordinate falls.
+ - `split` - Find where to split a string to make it fit a width.
+
+## Worked Example
+
+Rather than attempt to describe every aspect of an implementation we
+will rather work from an actual minimal example for the FLTK toolkit.
+
+This is availble as a single commit (`git show 04900e82e65f8669675538a66a01b56a3e473cb2`) in the NetSurf source repository. Alternatively it can be [viewed in a web browser](https://git.netsurf-browser.org/netsurf.git/commit/?h=vince/fltk....
+
+This represents the absolute minimum implementation to get a browser
+window on screen (and be able to click visible links). It is
+implemented in C++ as that is the FLTK implementation language but an
+equivalent implementation in other languages should be obvious.
+
+### Building
+
+The [frontends/Makefile.hts](https://git.netsurf-browser.org/netsurf.git/diff/...
+had the fltk target added to the VLDTARGET variable. This allows
+NetSurf to be built for this frontend with `make TARGET=fltk`
+
+As previously described the three GNU Make files are added:
+
+[Makefile](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk/Makefile?h=vince/fltk&id=04900e82e65f8669675538a66a01b56a3e473cb2)
+this shows how the flags are extended to add the fltk headers and
+library. Additionaly the list of sources are built here, as teh
+comment suggests it is important the SOURCES variable is not expanded
+here so the S_FRONTEND variable is used to allow expansion at teh
+correct time in the build process.
+
+
+[Makefile.defaults](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk/Makefile.defaults?h=vince/fltk&id=04900e82e65f8669675538a66a01b56a3e473cb2)
+has the default setting to control the build parameters and file locations. These can be overriden by the `Makefile.config` at compile time.
+
+[Makefile.tools](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk/Makefile.tools?h=vince/fltk&id=04900e82e65f8669675538a66a01b56a3e473cb2)
+allows the configuration of additional tools necessary to build for the target as a minimum pkg-config is usually required to find libraries.
+
+### Program entry
+
+In our example program entry is the classical `main()` in the [main.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk... module.
+
+This implements the six stage process outlined previously.
+
+#### Operations table registration
+
+The `netsurf_table` structure is initialised and passed to
+`netsurf_register()`. It should be noted that the approach taken here
+and in most frontends is to have a source module for each operation
+table. The header for each module exposes just the pointer to the
+indivial operation set, this allows for all the operation functions to
+be static to their module and hence helps reduce global symbol usage.
+
+#### Frontend specific initialisation
+
+Her it is implemented in `nsfltk_init()` this function performs all
+the operations specific to the frontend which must be initialised
+before netsurf itself. In some toolkits this would require calling the
+toolkit initialisation (e.g. `gtk_init()`).
+
+It is nessesary to initialise netsurf logging and user options at this
+point. A more fully featured implementation would also initialise the
+message translation system here.
+
+#### Netsurf initialisation
+
+This is simply the call to `netsurf_init()` from this point the
+browser is fully operational and operations can and will be called.
+
+#### Frontend specific startup
+
+Although the browser is running it has not yet been told to open a
+window or navigate to a page. Here `nsfltk_start()` examines the
+command line and environment to determine the initial page to navigate
+to and calls `browser_window_create()` with the url, this will cause
+the browser to open a new browsing context and start the navigation.
+
+A frontend may choose to implement more complex logic here but the
+example here is a good start.
+
+#### Toolkit run loop
+
+The function `nsfltk_run()` runs the toolkit event loop. In this case it is using the generic scheduleing in the [misc.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk... module to ensure callbacks get made at the apropriate time.
+
+There is a `nsfltk_done` boolean global checked here so when all the
+browser windows are closed the program will exit.
+
+A more fully featured port might use the toolkits scheduling rather
+than open coding a solution with a linked list as is done
+here.
+
+A futher optimisation would be to obtain the set of file descriptors
+being used (with `fetch_fdset()`) for active fetches allowing for
+activity based fetch progress instead of the fallback polling method.
+
+#### finalisation
+
+This simply finalises the browser stopping all activity and cleaning
+up any resource usage. After the call to `netsurf_exit()` no more
+operation calls will be made and all caches used by the core will be
+flushed.
+
+If user option chnages are to be made persistant `nsoption_finalise()`
+should be called.
+
+The finalisation of logging will ensure that any output buffers are
+flushed.
+
+### The window operation table
+
+Amongst all the boilerplate of the default implementation the only novel code is in the window operation table in the [window.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fl... module.
+
+#### `nsfltk_window_create`
+
+The create operation instansiates a new `NS_Window` object and
+references it in the gui_window structure which it returns to the
+caller. Technically we could simply return the `NS_Window` object as
+the gui_window pointer but this implementation is avoiding the cast.
+
+Secondly `Fl_Double_Window` is subclassed as `NS_Widget`. The sublass
+allows the close callback to be accessed so the global `nsfltk_done`
+boolean can be set during the destructor method.
+
+The NS_Window creates an instance of `NS_Widget` in its constructor, a
+more extensive implementation would add other window furniture here
+(scroll bars, url bar, navigation elements, etc.)
+
+The implementation subclasses `Fl_Widget` implementing the draw
+method to render the browsing context and the handle method to handle
+mouse events to allow teh user to click.
+
+The `NS_Widget::handle()` method simply translates the mouse press
+event from widget coordinates to netsurf canvas cooridinates and maps
+teh mouse button state. The core is informed of these events using
+`browser_window_mouse_click()`
+
+The `NS_Widget::draw` method similarly translates the fltk toolkits
+clip rectangle, builds a plotting context and calls
+`browser_window_redraw()` which will use the plotting operations in
+the plotting context to render the browsing context within the area
+specified. One thing to note here is the translation between the
+coordinates of the render area and the internal page canvas given as
+the second and third parameters to the draw call. When scrolling is
+required this is achived by altering these offsets.
+
+
+#### `nsfltk_window_invalidate()`
+
+This simply calls the damage method on the `Fl_Widget` class with the
+appropriate coordinate translation.
+
+#### `nsfltk_window_get_dimensions()`
+
+This obtains the fltk widget width and height and returns them.
+
+### The plotting interface
+
+When the `NS_Widget::draw` method was discussed it was noted that a
+plotting context is built containing an operation table. That table is
+implemented in [plotters.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/...
+
+The implementation here is as minimal as can be, only line, rectangle
+and text have any implementation at all and even that simply sets a
+colour and performs the appropriate fltk draw function (`fl_line`,
+`fl_rect` and `fl_draw` respectively)
+
+## Conclusion
+
+Hopefully this breif overview and worked example should give the
+prospectinve frontend developer enough information to understand how
+to get started implementing a new frontend toolkit for NetSurf.
+
+As can be seen there is actualy very little novel code necessary to
+get started though I should mention that the move from "minimal" to
+"full" implementation is a large undertaking and it would be wise to
+talk with the NetSurf developers if undertaking such work.
-----------------------------------------------------------------------
Summary of changes:
docs/development.md | 6 +
docs/implementing-new-frontend.md | 352 +++++++++++++++++++++++++++++++++++++
2 files changed, 358 insertions(+)
create mode 100644 docs/implementing-new-frontend.md
diff --git a/docs/development.md b/docs/development.md
index 5a8d1aa..3f08b54 100644
--- a/docs/development.md
+++ b/docs/development.md
@@ -69,6 +69,12 @@ NetSurf [integration tests](docs/integration-testing.md) use the
monkey frontend to operate the browser as a whole. These tests open
windows, navigate to websites and render contents as a user might.
+# New frontend development
+
+[Implementing a new frotend](docs/implementing-new-frontend.md) for a
+toolkit can be challenging and this guide provides an overview and
+worked example.
+
# Documented API
The NetSurf code makes use of Doxygen for code documentation.
diff --git a/docs/implementing-new-frontend.md b/docs/implementing-new-frontend.md
new file mode 100644
index 0000000..03e6180
--- /dev/null
+++ b/docs/implementing-new-frontend.md
@@ -0,0 +1,352 @@
+# Implementing a new frontend
+
+[TOC]
+
+## Introduction
+
+NetSurf is divided into a series of frontends which provide a user
+interface around common core functionality.
+
+Each frontend is a distinct implementation for a specific GUI toolkit.
+
+The existing frontends are covered in the [user
+interface](docs/user-interface.md) documentation.
+
+Note implementing a new frontend implies using a toolkit distinct from
+one of those already implemented and is distinct from porting NetSurf
+to a new operating system platform.
+
+It is recommend, in the strongest terms, that if the prospective
+developer is porting to both a new platform and toolkit that they
+*start* by getting the [monkey](docs/using-monkey.md) frontend
+building and passing at least the basic integration tests on their
+platform.
+
+Experience has shown that attempting to port to a platform and
+implement a toolkit at the same time generally results in failure to
+achieve either goal.
+
+NetSurf is built using GNU make and frontends are expected to
+integrate with this buildsystem.
+
+Implementation languages have historically been limited to C, C++ and
+objective C. However any language that can call C functions and
+*importantly* be called back from C code ought to be usable. For
+example there have been experiments with JAVA using JNI but no current
+frontend is implemented using it.
+
+## Implementation complexity
+
+An absolutely minimal "proof of concept" frontend implementation (like
+the FLTK frontend that will be used as an example) is around 1,000
+lines of C code. Basic functionality like the windows frontend is
+around 7,000 lines. A complete fully functional frontend such as the
+one for GTK is closer to 15,000 lines.
+
+It should be noted the majority of the minimal implementation can
+simply be copied and the names changed as appropriate from an existing
+example. The actual amount of new code that needs to be provided is
+very small.
+
+NetSurf provides a great deal of generic functionality for things like
+cookie, bookmark, history windows which require only minimal frontend
+support with the [core window API](docs/core-window-interface.md).
+
+A frontend developer is free to implement any and all of this generic
+functionality thelselves in a manner more integrated into a toolkit.
+
+## Implementation
+
+A frontend is generally named for the toolkit it is implementing (i.e
+gtk for the GTK+ toolkit). It is advisable to be as specific as
+possible e.g. the frontend for the windows operating system should
+have been named win32 allowing for an impementation using a differnt
+toolkit (e.g mfc)
+
+All the files needed for the frontend are contained in a single
+sub-directory in the NetSurf source tree e.g. `frontends/fltk`
+
+The only file outside this directory that much be changed is the
+`frontends/Makefile.hts` where a new entry must be added to the valid
+targets list.
+
+### Build system
+
+A frontend must provide three GNU Makefile fragments (these will be
+included from the core Makefile):
+
+ - `Makefile` - This is used to extend CFLAGS, CXXFLAGS and LDFLAGS variables as required. The executable target is set with EXETARGET and the browser source files are listed in the SOURCES variable
+ - `Makefile.defaults` - allows setting frontend specific makefile variables and overriding of the default core build variables.
+ - `Makefile.tools` - allows setting up frontend specific build tooling (as a minimum a tool for the package configuration in PKG_CONFIG)
+
+Source code modules can be named as the devloper desires within the
+frontend directory and should be added to the SOURCES variable as
+desired.
+
+### Program entry
+
+Generally the entry point from the OS is the `main()` function and
+several frontends have a `main.cpp` where some have used `gui.c`.
+
+The usual shape for the `main()` function is a six step process:
+ 1. The frontends operation tables are registered with NetSurf
+ 2. The toolkit specific initialisation is performed (which may involve calling NetSurf provided utility functions for support operations like logging, message translations etc.)
+ 3. Initialise the NetSurf core. After this point all browser functionality is available and registered operations can be called.
+ 4. Perform toolkiit setup, usually opening the initial browsing window (perhaps according to user preferences)
+ 5. Run the toolkits main loop while ensuring the Netsurf scheduled operations are also run at teh apropriate time.
+ 6. Finalisation on completion.
+
+### NetSurf operations tables
+
+The frontend will generally call netsurf interfaces to get a desired
+behaviour e.g. `browser_window_create()` to create a new browsing
+context (the `browser_window_` prefix is historical and does not
+necessarily create a window e.g. on gtk it is more likely to open a
+tab in an existing window). To achive the desired operation some
+operations need to be performed by the frontend under control of
+NetSurf, these operations are listed in tables.
+
+The operation tables should be registered with the NetSurf core as one
+of the first operations of the frontend code. The functions in these
+tables (and the tables themselves) must remain valid until
+`netsurf_exit()` is called.
+
+There are (currently) twelve sets of operation tables held in separate
+structures. Only five of these are mandantory (misc, window, fetch,
+bitmap and layout).
+
+In this context mandantory means the tables must be non NULL and do
+not have a suitable default. Each of the mandantory sets contain
+function pointers to implement operations.
+
+#### misc operation table
+
+The only mandantory operation in this table is schedule.
+
+When schedule is called the frontend must arrange for the passed
+callback to be called with the context parameter after a number of
+miliseconds.
+
+This callback is typicaly driven through the toolkits event loop and
+it is important such callbacks are not attempted from an operation.
+
+#### window operation table
+
+The window operations (poorly named as already mentioned) are where
+the frontend is called to actually manipulate widgets in the
+toolkit. This is mediated through a `gui_window` context pointer which
+is typed as a structure.
+
+This context pointer is passed to all window operations and is
+generally assumed to contain at least a reference to the underlying
+`browser_window` which is provided in the initial create operation to
+allow subsequent use of various core functionality.
+
+The mandantory window operations are:
+ - create - create a new browsing context widget in the frontend toolkit
+ - destroy - destoy a previously created `gui_window`
+ - invalidate - mark an area of the browsing context viewport as requiring redraw (note no redraw should be attempted from here)
+ - get_scroll - get the scroll offsets from the toolkit drawing widget
+ - set_scroll - set the scroll offsets on the toolkit drawing widget
+ - get_dimensions - get the dimensions of the toolkit drawing widget
+ - event - deal with various window events from netsurf which have no additional parameters
+
+
+#### fetch operation table
+
+The fetch operations allow the built in scheme fetchers (file, about, resource) to obtain additional information necessary to complete their operation.
+
+The two mandantory operations are:
+ - `filetype` - allows the file scheme to obtain a mime type from a file path e.g. `a.file.name.png` would result in `image/png`
+ - `get_resource_url` - maps resource scheme paths to URL e.g. `resource:default.css` to `file:///usr/share/netsurf/default.css`
+
+#### bitmap operation table
+
+The bitmap table and all of its operations are mandantory only because
+the empty defaults have not been included as it is assumed a browser
+will want to display images.
+
+All operations may be provided by stubs that return the failure codes
+until full implementations are made.
+
+#### layout operation table
+
+The layout table is used to layout text. All operations are given
+strings to manipulate encoded in UTF-8. There are three mandantory
+operations:
+ - `width` - Calculate the width of a string.
+ - `position` - Find the position in a string where an x coordinate falls.
+ - `split` - Find where to split a string to make it fit a width.
+
+## Worked Example
+
+Rather than attempt to describe every aspect of an implementation we
+will rather work from an actual minimal example for the FLTK toolkit.
+
+This is availble as a single commit (`git show 04900e82e65f8669675538a66a01b56a3e473cb2`) in the NetSurf source repository. Alternatively it can be [viewed in a web browser](https://git.netsurf-browser.org/netsurf.git/commit/?h=vince/fltk....
+
+This represents the absolute minimum implementation to get a browser
+window on screen (and be able to click visible links). It is
+implemented in C++ as that is the FLTK implementation language but an
+equivalent implementation in other languages should be obvious.
+
+### Building
+
+The [frontends/Makefile.hts](https://git.netsurf-browser.org/netsurf.git/diff/...
+had the fltk target added to the VLDTARGET variable. This allows
+NetSurf to be built for this frontend with `make TARGET=fltk`
+
+As previously described the three GNU Make files are added:
+
+[Makefile](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk/Makefile?h=vince/fltk&id=04900e82e65f8669675538a66a01b56a3e473cb2)
+this shows how the flags are extended to add the fltk headers and
+library. Additionaly the list of sources are built here, as teh
+comment suggests it is important the SOURCES variable is not expanded
+here so the S_FRONTEND variable is used to allow expansion at teh
+correct time in the build process.
+
+
+[Makefile.defaults](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk/Makefile.defaults?h=vince/fltk&id=04900e82e65f8669675538a66a01b56a3e473cb2)
+has the default setting to control the build parameters and file locations. These can be overriden by the `Makefile.config` at compile time.
+
+[Makefile.tools](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk/Makefile.tools?h=vince/fltk&id=04900e82e65f8669675538a66a01b56a3e473cb2)
+allows the configuration of additional tools necessary to build for the target as a minimum pkg-config is usually required to find libraries.
+
+### Program entry
+
+In our example program entry is the classical `main()` in the [main.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk... module.
+
+This implements the six stage process outlined previously.
+
+#### Operations table registration
+
+The `netsurf_table` structure is initialised and passed to
+`netsurf_register()`. It should be noted that the approach taken here
+and in most frontends is to have a source module for each operation
+table. The header for each module exposes just the pointer to the
+indivial operation set, this allows for all the operation functions to
+be static to their module and hence helps reduce global symbol usage.
+
+#### Frontend specific initialisation
+
+Her it is implemented in `nsfltk_init()` this function performs all
+the operations specific to the frontend which must be initialised
+before netsurf itself. In some toolkits this would require calling the
+toolkit initialisation (e.g. `gtk_init()`).
+
+It is nessesary to initialise netsurf logging and user options at this
+point. A more fully featured implementation would also initialise the
+message translation system here.
+
+#### Netsurf initialisation
+
+This is simply the call to `netsurf_init()` from this point the
+browser is fully operational and operations can and will be called.
+
+#### Frontend specific startup
+
+Although the browser is running it has not yet been told to open a
+window or navigate to a page. Here `nsfltk_start()` examines the
+command line and environment to determine the initial page to navigate
+to and calls `browser_window_create()` with the url, this will cause
+the browser to open a new browsing context and start the navigation.
+
+A frontend may choose to implement more complex logic here but the
+example here is a good start.
+
+#### Toolkit run loop
+
+The function `nsfltk_run()` runs the toolkit event loop. In this case it is using the generic scheduleing in the [misc.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fltk... module to ensure callbacks get made at the apropriate time.
+
+There is a `nsfltk_done` boolean global checked here so when all the
+browser windows are closed the program will exit.
+
+A more fully featured port might use the toolkits scheduling rather
+than open coding a solution with a linked list as is done
+here.
+
+A futher optimisation would be to obtain the set of file descriptors
+being used (with `fetch_fdset()`) for active fetches allowing for
+activity based fetch progress instead of the fallback polling method.
+
+#### finalisation
+
+This simply finalises the browser stopping all activity and cleaning
+up any resource usage. After the call to `netsurf_exit()` no more
+operation calls will be made and all caches used by the core will be
+flushed.
+
+If user option chnages are to be made persistant `nsoption_finalise()`
+should be called.
+
+The finalisation of logging will ensure that any output buffers are
+flushed.
+
+### The window operation table
+
+Amongst all the boilerplate of the default implementation the only novel code is in the window operation table in the [window.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/fl... module.
+
+#### `nsfltk_window_create`
+
+The create operation instansiates a new `NS_Window` object and
+references it in the gui_window structure which it returns to the
+caller. Technically we could simply return the `NS_Window` object as
+the gui_window pointer but this implementation is avoiding the cast.
+
+Secondly `Fl_Double_Window` is subclassed as `NS_Widget`. The sublass
+allows the close callback to be accessed so the global `nsfltk_done`
+boolean can be set during the destructor method.
+
+The NS_Window creates an instance of `NS_Widget` in its constructor, a
+more extensive implementation would add other window furniture here
+(scroll bars, url bar, navigation elements, etc.)
+
+The implementation subclasses `Fl_Widget` implementing the draw
+method to render the browsing context and the handle method to handle
+mouse events to allow teh user to click.
+
+The `NS_Widget::handle()` method simply translates the mouse press
+event from widget coordinates to netsurf canvas cooridinates and maps
+teh mouse button state. The core is informed of these events using
+`browser_window_mouse_click()`
+
+The `NS_Widget::draw` method similarly translates the fltk toolkits
+clip rectangle, builds a plotting context and calls
+`browser_window_redraw()` which will use the plotting operations in
+the plotting context to render the browsing context within the area
+specified. One thing to note here is the translation between the
+coordinates of the render area and the internal page canvas given as
+the second and third parameters to the draw call. When scrolling is
+required this is achived by altering these offsets.
+
+
+#### `nsfltk_window_invalidate()`
+
+This simply calls the damage method on the `Fl_Widget` class with the
+appropriate coordinate translation.
+
+#### `nsfltk_window_get_dimensions()`
+
+This obtains the fltk widget width and height and returns them.
+
+### The plotting interface
+
+When the `NS_Widget::draw` method was discussed it was noted that a
+plotting context is built containing an operation table. That table is
+implemented in [plotters.cpp](https://git.netsurf-browser.org/netsurf.git/diff/frontends/...
+
+The implementation here is as minimal as can be, only line, rectangle
+and text have any implementation at all and even that simply sets a
+colour and performs the appropriate fltk draw function (`fl_line`,
+`fl_rect` and `fl_draw` respectively)
+
+## Conclusion
+
+Hopefully this breif overview and worked example should give the
+prospectinve frontend developer enough information to understand how
+to get started implementing a new frontend toolkit for NetSurf.
+
+As can be seen there is actualy very little novel code necessary to
+get started though I should mention that the move from "minimal" to
+"full" implementation is a large undertaking and it would be wise to
+talk with the NetSurf developers if undertaking such work.
--
NetSurf Browser
2 years, 6 months