Gitweb links:

...log 
http://git.netsurf-browser.org/librufl.git/shortlog/421bacf56744d00db7ccef93daa119ab8ea4ac55
...commit 
http://git.netsurf-browser.org/librufl.git/commit/421bacf56744d00db7ccef93daa119ab8ea4ac55
...tree 
http://git.netsurf-browser.org/librufl.git/tree/421bacf56744d00db7ccef93daa119ab8ea4ac55

The branch, jmb/ac has been updated
       via  421bacf56744d00db7ccef93daa119ab8ea4ac55 (commit)
       via  d59f17a6fb3d4f20a931ab45bf60ff910685b241 (commit)
       via  01da1538227f4d139c0665b730211c665c821625 (commit)
       via  b547911ad6cba76439eeb9cd03a6af3fe0dc6be3 (commit)
       via  5fd0f4c9161c5ab6163386598d04681f12858509 (commit)
       via  7455528fedc1d6a03ba693307c441ffddcc3c164 (commit)
       via  c69d7fee4ef1820296cb1c0db072e01cf6970ce1 (commit)
       via  158483bc75ac79cb2699d92e30f30aeefefe56ca (commit)
       via  5741043b16e81f9673fdef791aeb225e522c9a41 (commit)
       via  a53a1e176218aba04ec13d91bbfbd103608c4eb2 (commit)
       via  c945837b458fc9ff4d37568be74ddb1a685e6431 (commit)
      from  6dce21aa10a2d5f5a745a2f168d801d4baa7d4b2 (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/librufl.git/commit/?id=421bacf56744d00db7ccef93daa119ab8ea4ac55
commit 421bacf56744d00db7ccef93daa119ab8ea4ac55
Author: John-Mark Bell <j...@netsurf-browser.org>
Commit: John-Mark Bell <j...@netsurf-browser.org>

    Make dump of unicode maps optional
    
    Add a verbose flag to rufl_dump_state() and use it to control
    whether to dump the individual unicode maps generated when using
    a non-UCS Font Manager.
    
    Change rufl_test to not dump this state (ordinarily, anyway) as
    it is generally uninteresting and highly verbose.

diff --git a/include/rufl.h b/include/rufl.h
index 0164df8..15e889e 100644
--- a/include/rufl.h
+++ b/include/rufl.h
@@ -185,7 +185,7 @@ rufl_code rufl_font_bbox(const char *font_family, 
rufl_style font_style,
  * Dump the internal library state to stdout.
  */
 
-void rufl_dump_state(void);
+void rufl_dump_state(bool verbose);
 
 
 /**
diff --git a/src/rufl_dump_state.c b/src/rufl_dump_state.c
index 860d57e..f466333 100644
--- a/src/rufl_dump_state.c
+++ b/src/rufl_dump_state.c
@@ -18,7 +18,7 @@ static void rufl_dump_unicode_map(struct rufl_unicode_map 
*umap);
  * Dump the internal library state to stdout.
  */
 
-void rufl_dump_state(void)
+void rufl_dump_state(bool verbose)
 {
        unsigned int i, j;
 
@@ -32,7 +32,7 @@ void rufl_dump_state(void)
                } else {
                        printf("    (no charset table)\n");
                }
-               if (rufl_font_list[i].umap) {
+               if (verbose && rufl_font_list[i].umap) {
                        for (j = 0; j < rufl_font_list[i].num_umaps; j++) {
                                struct rufl_unicode_map *map =
                                                rufl_font_list[i].umap + j;
diff --git a/test/rufl_test.c b/test/rufl_test.c
index d939467..5b76f81 100644
--- a/test/rufl_test.c
+++ b/test/rufl_test.c
@@ -35,7 +35,7 @@ int main(void)
        int bbox[4];
 
        try(rufl_init(), "rufl_init");
-       rufl_dump_state();
+       rufl_dump_state(false);
        try(rufl_paint("NewHall", rufl_WEIGHT_400, 240,
                        utf8_test, sizeof utf8_test - 1,
                        1200, 1000, 0), "rufl_paint");


commitdiff 
http://git.netsurf-browser.org/librufl.git/commit/?id=d59f17a6fb3d4f20a931ab45bf60ff910685b241
commit d59f17a6fb3d4f20a931ab45bf60ff910685b241
Author: John-Mark Bell <j...@netsurf-browser.org>
Commit: John-Mark Bell <j...@netsurf-browser.org>

    Ignore UCS fonts if using a non-UCS Font Manager
    
    Attempting to use fonts constructed for the UCS Font Manager on
    older systems generally results in bad outcomes up to, and
    including, complete system freezes. As fixing the Font Manager
    on these systems is impractical, simply ignore these fonts
    completely when scanning for glyph coverage.

diff --git a/src/rufl_init.c b/src/rufl_init.c
index 79433c3..6cf0be6 100644
--- a/src/rufl_init.c
+++ b/src/rufl_init.c
@@ -1028,10 +1028,33 @@ rufl_code rufl_init_scan_font_in_encoding(const char 
*font_name,
        if (code != rufl_OK) {
                LOG("rufl_init_read_encoding(\"%s\", ...): 0x%x",
                                buf, code);
+               umap->encoding = NULL;
                xfont_lose_font(font);
                return code;
        }
 
+       /* Detect attempts to use UCS fonts with a non-UCS Font Manager.
+        * There is a bug in all known non-UCS Font Managers which is
+        * often triggered by scanning many fonts. The Font Manager will
+        * attempt to dereference a bogus pointer (at the start of
+        * getbbox_unscaled) and thus cause an abort in SVC mode.
+        * Fallout can be as (relatively) benign as the application
+        * crashing or escalate to an entire system freeze requiring
+        * a reset. As there are no "good" outcomes here, and we do
+        * not have a time machine to go back and fix long-ago released
+        * Font Managers, ensure we ignore UCS fonts here. */
+       if ((uint32_t) umap->encoding > 256) {
+               static os_error err = {
+                       error_FONT_TOO_MANY_CHUNKS, "Rejecting UCS font"};
+               LOG("%s", "Rejecting UCS font");
+               umap->encoding = NULL;
+               xfont_lose_font(font);
+               rufl_fm_error = &err;
+               return rufl_FONT_MANAGER_ERROR;
+       }
+       /* Eliminate all trace of our (ab)use of the encoding field */
+       umap->encoding = NULL;
+
        for (i = 0; i != umap->entries; i++) {
                u = umap->map[i].u;
                string[0] = umap->map[i].c;
@@ -1102,9 +1125,11 @@ static rufl_code rufl_init_umap_cb(void *pw, uint32_t 
glyph_idx, uint32_t ucs4)
                umap->map[umap->entries].u = ucs4;
                umap->map[umap->entries].c = glyph_idx;
                umap->entries++;
-               if (umap->entries == 256)
-                       result = rufl_IO_EOF;
        }
+       /* Stash the total number of encoding file entries so that
+        * rufl_init_scan_font_in_encoding can detect the presence of a
+        * UCS font on a non-UCS capable system. It will clean up for us. */
+       umap->encoding = (void *) (((uint32_t) umap->encoding) + 1);
 
        return result;
 }


commitdiff 
http://git.netsurf-browser.org/librufl.git/commit/?id=01da1538227f4d139c0665b730211c665c821625
commit 01da1538227f4d139c0665b730211c665c821625
Author: John-Mark Bell <j...@netsurf-browser.org>
Commit: John-Mark Bell <j...@netsurf-browser.org>

    Clean up logging in the non-UCS Font Manager path
    
    To obtain the full extent of a "language" font's glyph coverage
    we need to open and scan it in each of the available target
    encodings. All of the Latin1-6 + Welsh target encodings declare
    that they are based on the Base0 encoding and thus will cause the
    Font Manager to demand the existence of corresponding
    IntMetric0/Outlines0 font data files. A "language" font using a
    different base encoding (and corresponding target encodings
    based on it) would thus generate an error from the Font Manager.
    
    Additionally, without reinventing the Font Manager's own logic
    (and poking around the filesystem looking for IntMetrics and
    Encoding files), we don't know if a font is a "language" or a
    "symbol" font until we try to use it. Thus, we expect attempts to
    open "symbol" fonts with an explicit target encoding to generate
    an error from the Font Manager as well.
    
    As these are expected errors, there is no point logging them as
    it just produces a load of distracting noise.

diff --git a/src/rufl_init.c b/src/rufl_init.c
index 3a77588..79433c3 100644
--- a/src/rufl_init.c
+++ b/src/rufl_init.c
@@ -870,7 +870,20 @@ rufl_code rufl_init_scan_font_old(unsigned int font_index)
 
                code = rufl_init_scan_font_in_encoding(font_name, encoding,
                                charset, umap + (num_umaps - 1), &last_used);
-               if (code != rufl_OK) {
+               /* Not finding the font isn't fatal */
+               if (code == rufl_FONT_MANAGER_ERROR &&
+                               (rufl_fm_error->errnum ==
+                                       error_FONT_NOT_FOUND ||
+                               rufl_fm_error->errnum ==
+                                       error_FILE_NOT_FOUND ||
+                               rufl_fm_error->errnum ==
+                                       error_FONT_ENCODING_NOT_FOUND ||
+                               /* Neither is a too modern font */
+                               rufl_fm_error->errnum ==
+                                       error_FONT_TOO_MANY_CHUNKS)) {
+                       /* Ensure we reuse the currently allocated umap */
+                       num_umaps--;
+               } else if (code != rufl_OK) {
                        LOG("rufl_init_scan_font_in_encoding(\"%s\", \"%s\", "
                            "...): 0x%x (0x%x: %s)",
                                        font_name, encoding, code,
@@ -879,26 +892,11 @@ rufl_code rufl_init_scan_font_old(unsigned int font_index)
                                        code == rufl_FONT_MANAGER_ERROR ?
                                                rufl_fm_error->errmess : "");
 
-                       /* Not finding the font isn't fatal */
-                       if (code != rufl_FONT_MANAGER_ERROR ||
-                               (rufl_fm_error->errnum != 
-                                       error_FONT_NOT_FOUND &&
-                               rufl_fm_error->errnum !=
-                                       error_FILE_NOT_FOUND &&
-                               rufl_fm_error->errnum !=
-                                       error_FONT_ENCODING_NOT_FOUND &&
-                               /* Neither is a too modern font */
-                               rufl_fm_error->errnum !=
-                                       error_FONT_TOO_MANY_CHUNKS)) {
-                               free(charset);
-                               for (i = 0; i < num_umaps; i++)
-                                       free((umap + i)->encoding);
-                               free(umap);
-                               return code;
-                       }
-
-                       /* Ensure we reuse the currently allocated umap */
-                       num_umaps--;
+                       free(charset);
+                       for (i = 0; i < num_umaps; i++)
+                               free((umap + i)->encoding);
+                       free(umap);
+                       return code;
                } else {
                        /* If this mapping is identical to an existing one, 
                         * then we can discard it */
@@ -937,7 +935,20 @@ rufl_code rufl_init_scan_font_old(unsigned int font_index)
 
                code = rufl_init_scan_font_in_encoding(font_name, NULL,
                                charset, umap, &last_used);
-               if (code != rufl_OK) {
+               /* Not finding the font isn't fatal */
+               if (code == rufl_FONT_MANAGER_ERROR &&
+                               (rufl_fm_error->errnum ==
+                                       error_FONT_NOT_FOUND ||
+                               rufl_fm_error->errnum ==
+                                       error_FILE_NOT_FOUND ||
+                               rufl_fm_error->errnum ==
+                                       error_FONT_ENCODING_NOT_FOUND ||
+                               /* Neither is a too modern font */
+                               rufl_fm_error->errnum ==
+                                       error_FONT_TOO_MANY_CHUNKS)) {
+                       /* Ensure we reuse the currently allocated umap */
+                       num_umaps--;
+               } else if (code != rufl_OK) {
                        LOG("rufl_init_scan_font_in_encoding(\"%s\", NULL, "
                            "...): 0x%x (0x%x: %s)",
                                        font_name, code,
@@ -946,25 +957,11 @@ rufl_code rufl_init_scan_font_old(unsigned int font_index)
                                        code == rufl_FONT_MANAGER_ERROR ?
                                                rufl_fm_error->errmess : "");
 
-                       /* Not finding the font isn't fatal */
-                       if (code != rufl_FONT_MANAGER_ERROR ||
-                               (rufl_fm_error->errnum != 
-                                       error_FONT_NOT_FOUND &&
-                               rufl_fm_error->errnum !=
-                                       error_FILE_NOT_FOUND &&
-                               rufl_fm_error->errnum !=
-                                       error_FONT_ENCODING_NOT_FOUND &&
-                               /* Neither is a too modern font */
-                               rufl_fm_error->errnum !=
-                                       error_FONT_TOO_MANY_CHUNKS)) {
-                               free(charset);
-                               for (i = 0; i < num_umaps; i++)
-                                       free((umap + i)->encoding);
-                               free(umap);
-                               return code;
-                       }
-
-                       num_umaps--;
+                       free(charset);
+                       for (i = 0; i < num_umaps; i++)
+                               free((umap + i)->encoding);
+                       free(umap);
+                       return code;
                }
        }
 
@@ -1023,8 +1020,7 @@ rufl_code rufl_init_scan_font_in_encoding(const char 
*font_name,
 
        rufl_fm_error = xfont_find_font(buf, 160, 160, 0, 0, &font, 0, 0);
        if (rufl_fm_error) {
-               LOG("xfont_find_font(\"%s\"): 0x%x: %s", buf,
-                               rufl_fm_error->errnum, rufl_fm_error->errmess);
+               /* Leave it to our caller to log, if they wish */
                return rufl_FONT_MANAGER_ERROR;
        }
 


commitdiff 
http://git.netsurf-browser.org/librufl.git/commit/?id=b547911ad6cba76439eeb9cd03a6af3fe0dc6be3
commit b547911ad6cba76439eeb9cd03a6af3fe0dc6be3
Author: John-Mark Bell <j...@netsurf-browser.org>
Commit: John-Mark Bell <j...@netsurf-browser.org>

    Accept non-UCS Font Manager rejecting UCS fonts.
    
    If you attempt to use fonts supported by the UCS Font Manager with
    a non-UCS Font Manager, this will either work (in a limited way)
    or fail because the font data is incomprehensible to the non-UCS
    Font Manager. Cope with one particular instance of this.

diff --git a/src/rufl_init.c b/src/rufl_init.c
index 9beb992..3a77588 100644
--- a/src/rufl_init.c
+++ b/src/rufl_init.c
@@ -886,7 +886,10 @@ rufl_code rufl_init_scan_font_old(unsigned int font_index)
                                rufl_fm_error->errnum !=
                                        error_FILE_NOT_FOUND &&
                                rufl_fm_error->errnum !=
-                                       error_FONT_ENCODING_NOT_FOUND)) {
+                                       error_FONT_ENCODING_NOT_FOUND &&
+                               /* Neither is a too modern font */
+                               rufl_fm_error->errnum !=
+                                       error_FONT_TOO_MANY_CHUNKS)) {
                                free(charset);
                                for (i = 0; i < num_umaps; i++)
                                        free((umap + i)->encoding);
@@ -950,7 +953,10 @@ rufl_code rufl_init_scan_font_old(unsigned int font_index)
                                rufl_fm_error->errnum !=
                                        error_FILE_NOT_FOUND &&
                                rufl_fm_error->errnum !=
-                                       error_FONT_ENCODING_NOT_FOUND)) {
+                                       error_FONT_ENCODING_NOT_FOUND &&
+                               /* Neither is a too modern font */
+                               rufl_fm_error->errnum !=
+                                       error_FONT_TOO_MANY_CHUNKS)) {
                                free(charset);
                                for (i = 0; i < num_umaps; i++)
                                        free((umap + i)->encoding);


commitdiff 
http://git.netsurf-browser.org/librufl.git/commit/?id=5fd0f4c9161c5ab6163386598d04681f12858509
commit 5fd0f4c9161c5ab6163386598d04681f12858509
Author: John-Mark Bell <j...@netsurf-browser.org>
Commit: John-Mark Bell <j...@netsurf-browser.org>

    Fix font scanning on non-UCS Font Managers
    
    We want to update the umap itself not whatever happens to be on the
    stack in the vicinity of its address.

diff --git a/src/rufl_init.c b/src/rufl_init.c
index cf85980..9beb992 100644
--- a/src/rufl_init.c
+++ b/src/rufl_init.c
@@ -1118,7 +1118,7 @@ rufl_code rufl_init_populate_unicode_map(font_f f,
 
        umap->entries = 0;
 
-       result = rufl_init_read_encoding(f, rufl_init_umap_cb, &umap);
+       result = rufl_init_read_encoding(f, rufl_init_umap_cb, umap);
        if (result == rufl_OK) {
                /* sort by unicode */
                qsort(umap->map, umap->entries, sizeof umap->map[0],


commitdiff 
http://git.netsurf-browser.org/librufl.git/commit/?id=7455528fedc1d6a03ba693307c441ffddcc3c164
commit 7455528fedc1d6a03ba693307c441ffddcc3c164
Author: John-Mark Bell <j...@netsurf-browser.org>
Commit: John-Mark Bell <j...@netsurf-browser.org>

    Fix initialisation on UCS Font Manager 3.41-3.63
    
    We cannot use Font_ReadEncodingFile to find the path to a font's
    source encoding because that is not what the API returns (it
    returns the path to the encoding file corresponding to the target
    encoding used to open the font handle) and there is no public API
    for obtaining the path of the source encoding. Additionally, there
    is no reliable way to replicate the UCS Font Manager's mapping of
    undefined and duplicate glyph names into the private use space
    at U+E000-U+EFFF.
    
    Therefore, take a different approach to supporting these versions
    of the Font Manager: abuse Font_EnumerateCharacters by probing
    every codepoint in the range [0, first_returned) to force the
    Font Manager to reveal the information we want. Once we have
    reached the first_returned codepoint, we can happily fall through
    to the normal flow (which will make use of the sparse nature of
    the Unicode space).

diff --git a/src/rufl_init.c b/src/rufl_init.c
index 29ef415..cf85980 100644
--- a/src/rufl_init.c
+++ b/src/rufl_init.c
@@ -543,16 +543,56 @@ static rufl_code rufl_init_enumerate_characters(const 
char *font_name,
                        uint32_t glyph_idx, uint32_t ucs4),
                void *pw)
 {
-       unsigned int u, next;
-       rufl_code result;
+       unsigned int u = 0, next, internal;
+       rufl_code result = rufl_OK;
 
-       if (rufl_broken_font_enumerate_characters)
-               return rufl_init_read_encoding(font, callback, pw);
+       if (rufl_broken_font_enumerate_characters) {
+               /* We know that any codepoints in the first chunk will
+                * be missed because Font_EnumerateCharacters is broken
+                * on this version of the Font Manager. Find the first
+                * codepoint it will report. */
+               unsigned int first;
+               rufl_fm_error = xfont_enumerate_characters(font, 0,
+                               (int *) &first, (int *) &internal);
+               if (rufl_fm_error) {
+                       LOG("xfont_enumerate_characters(\"%s\", "
+                           "U+%x, ...): 0x%x: %s",
+                                       font_name, 0,
+                                       rufl_fm_error->errnum,
+                                       rufl_fm_error->errmess);
+                       return rufl_FONT_MANAGER_ERROR;
+               }
 
-       /* Scan through mapped characters */
-       for (u = 0; u != (unsigned int) -1; u = next) {
-               unsigned int internal;
+               /* Search the entire space up to the first codepoint it
+                * reported. */
+               for (u = 0; u != (unsigned int) -1 && u != first; u++) {
+                       rufl_fm_error = xfont_enumerate_characters(font, u,
+                                       (int *) &next, (int *) &internal);
+                       if (rufl_fm_error) {
+                               LOG("xfont_enumerate_characters(\"%s\", "
+                                   "U+%x, ...): 0x%x: %s",
+                                               font_name, u,
+                                               rufl_fm_error->errnum,
+                                               rufl_fm_error->errmess);
+                               result = rufl_FONT_MANAGER_ERROR;
+                               break;
+                       }
+
+                       /* Skip unmapped characters */
+                       if (internal == (unsigned int) -1)
+                               continue;
+
+                       /* Character is mapped, emit it */
+                       result = callback(pw, internal, u);
+                       if (result != rufl_OK)
+                               break;
+               }
 
+               /* Now fall through to the normal path */
+       }
+
+       /* Scan through mapped characters */
+       for (; u != (unsigned int) -1; u = next) {
                rufl_fm_error = xfont_enumerate_characters(font, u, 
                                (int *) &next, (int *) &internal);
                if (rufl_fm_error) {
@@ -561,6 +601,7 @@ static rufl_code rufl_init_enumerate_characters(const char 
*font_name,
                                        font_name, u,
                                        rufl_fm_error->errnum, 
                                        rufl_fm_error->errmess);
+                       result = rufl_FONT_MANAGER_ERROR;
                        break;
                }
 
@@ -1225,13 +1266,9 @@ rufl_code rufl_init_read_encoding(font_f font,
        }
 
        fp = fopen(filename, "r");
-       if (!fp) {
+       if (!fp && rufl_old_font_manager) {
                /* many "symbol" fonts have no encoding file */
-               const char *default_path =
-                       "Resources:$.Fonts.Encodings./Default";
-               if (rufl_old_font_manager)
-                       default_path = "Resources:$.Fonts.Encodings.Latin1";
-               fp = fopen(default_path, "r");
+               fp = fopen("Resources:$.Fonts.Encodings.Latin1", "r");
        }
        if (!fp)
                return rufl_IO_ERROR;


commitdiff 
http://git.netsurf-browser.org/librufl.git/commit/?id=c69d7fee4ef1820296cb1c0db072e01cf6970ce1
commit c69d7fee4ef1820296cb1c0db072e01cf6970ce1
Author: John-Mark Bell <j...@netsurf-browser.org>
Commit: John-Mark Bell <j...@netsurf-browser.org>

    Fix shrinkwrap moving blocks
    
    All blocks subsequent to a full one get moved up and all their
    indices need rewriting.

diff --git a/src/rufl_init.c b/src/rufl_init.c
index f49ceff..29ef415 100644
--- a/src/rufl_init.c
+++ b/src/rufl_init.c
@@ -472,31 +472,26 @@ static void rufl_init_shrinkwrap_plane(struct 
rufl_character_set *charset)
                for (byte = 0; byte != 32; byte++)
                        bit &= charset->block[block][byte];
 
-               if (bit == 0xff) {
-                       /* Block is full */
-
-                       /* Find a block whose index is after this one.
-                        * If such a block exists, move its data into
-                        * this block, as this block's bitmap is now free
-                       */
-                       for (byte = 0; byte != 256; byte++) {
-                               if (charset->index[byte] < BLOCK_EMPTY &&
-                                               charset->index[byte] > block) {
-                                       break;
-                               }
-                       }
-                       if (byte != 256) {
-                               memcpy(charset->block[block],
-                                               charset->block[
-                                                       charset->index[byte]],
-                                               32);
-                               charset->index[byte] = block;
-                       }
 
-                       /* Now mark this block as full */
-                       charset->index[u] = BLOCK_FULL;
-                       last_used--;
+               if (bit != 0xff)
+                       continue;
+
+               /* Block is full */
+
+               /* Move subsequent blocks up and rewrite their indices */
+               memmove(charset->block[block],
+                               charset->block[block+1],
+                               (254-(block+1)) * 32);
+               for (byte = 0; byte != 256; byte++) {
+                       if (charset->index[byte] < BLOCK_EMPTY &&
+                                       charset->index[byte] > block) {
+                               charset->index[byte]--;
+                       }
                }
+
+               /* Now mark this block as full */
+               charset->index[u] = BLOCK_FULL;
+               last_used--;
        }
 
        /* Fill in this plane's size now we know it */


commitdiff 
http://git.netsurf-browser.org/librufl.git/commit/?id=158483bc75ac79cb2699d92e30f30aeefefe56ca
commit 158483bc75ac79cb2699d92e30f30aeefefe56ca
Author: John-Mark Bell <j...@netsurf-browser.org>
Commit: John-Mark Bell <j...@netsurf-browser.org>

    Ensure dumping doesn't run off the end of a plane

diff --git a/src/rufl_dump_state.c b/src/rufl_dump_state.c
index 13a1564..860d57e 100644
--- a/src/rufl_dump_state.c
+++ b/src/rufl_dump_state.c
@@ -90,7 +90,7 @@ static void rufl_dump_character_set(const struct 
rufl_character_set *charset)
                                u++;
                        } else {
                                t = u;
-                               while (rufl_character_set_test(
+                               while (u != 0x10000 && rufl_character_set_test(
                                                        charset, plane + u))
                                        u++;
                                printf("%x-%x ", plane + t, plane + u - 1);


commitdiff 
http://git.netsurf-browser.org/librufl.git/commit/?id=5741043b16e81f9673fdef791aeb225e522c9a41
commit 5741043b16e81f9673fdef791aeb225e522c9a41
Author: John-Mark Bell <j...@netsurf-browser.org>
Commit: John-Mark Bell <j...@netsurf-browser.org>

    Fix bug in sparse encoding parser
    
    Spaces are valid characters in the sparse encoding so ensure we
    consume them correctly.

diff --git a/src/rufl_init.c b/src/rufl_init.c
index 5da9b50..f49ceff 100644
--- a/src/rufl_init.c
+++ b/src/rufl_init.c
@@ -1273,8 +1273,9 @@ rufl_code rufl_init_read_encoding(font_f font,
                                        (c >= 'a' && c <= 'z') ||
                                        (c >= 'A' && c <= 'Z') ||
                                        (c == '.') || (c == '_') ||
-                                       (c == ';')) {
-                               /* Printable: append */
+                                       (c == ';') ||
+                                       (c == ' ' && s[0] != '/')) {
+                               /* Printable (or space in new-style): append */
                                s[n++] = c;
                                if (n >= sizeof(s)) {
                                        /* Too long: garbage */


commitdiff 
http://git.netsurf-browser.org/librufl.git/commit/?id=a53a1e176218aba04ec13d91bbfbd103608c4eb2
commit a53a1e176218aba04ec13d91bbfbd103608c4eb2
Author: John-Mark Bell <j...@netsurf-browser.org>
Commit: John-Mark Bell <j...@netsurf-browser.org>

    Add MedBold and Thin weights

diff --git a/src/rufl_init.c b/src/rufl_init.c
index a6c895f..5da9b50 100644
--- a/src/rufl_init.c
+++ b/src/rufl_init.c
@@ -60,11 +60,13 @@ const struct rufl_weight_table_entry rufl_weight_table[] = {
        { "ExtraLight", 1 },
        { "Heavy", 8 },
        { "Light", 2 },
+       { "MedBold", 6 },
        { "Medium", 5 },
        { "Regular", 4 },
        { "Semi", 6 },
        { "SemiBold", 6 },
        { "SemiLight", 3 },
+       { "Thin", 1 },
        { "UltraBlack", 9 },
        { "UltraBold", 9 },
 };


commitdiff 
http://git.netsurf-browser.org/librufl.git/commit/?id=c945837b458fc9ff4d37568be74ddb1a685e6431
commit c945837b458fc9ff4d37568be74ddb1a685e6431
Author: John-Mark Bell <j...@netsurf-browser.org>
Commit: John-Mark Bell <j...@netsurf-browser.org>

    Clean up logging

diff --git a/src/rufl_init.c b/src/rufl_init.c
index 6ec21b7..a6c895f 100644
--- a/src/rufl_init.c
+++ b/src/rufl_init.c
@@ -512,14 +512,11 @@ static struct rufl_character_set 
*rufl_init_shrinkwrap_planes(
        /* Shrink-wrap each plane, accumulating total required size as we go */
        for (u = 0; u < 17; u++) {
                if (planes[u]) {
-                       LOG("shrink-wrapping plane %d", u);
                        rufl_init_shrinkwrap_plane(planes[u]);
                        size += PLANE_SIZE(planes[u]->metadata);
                }
        }
 
-       LOG("shrink-wrapped size: %u", size);
-
        charset = malloc(size);
        if (!charset)
                return NULL;
@@ -531,8 +528,6 @@ static struct rufl_character_set 
*rufl_init_shrinkwrap_planes(
                if (!planes[u-1])
                        continue;
 
-               LOG("merging plane %d", u);
-
                /* Set E bit if not the last plane */
                if (pos != size)
                        planes[u-1]->metadata |= (1u<<31);
@@ -1430,12 +1425,7 @@ rufl_code rufl_save_cache(void)
                }
 
                /* character set (all planes) */
-               LOG("writing character sets for %s",
-                               rufl_font_list[i].identifier);
                while (EXTENSION_FOLLOWS(charset->metadata)) {
-                       LOG("writing plane %d (%u)",
-                                       PLANE_ID(charset->metadata),
-                                       PLANE_SIZE(charset->metadata));
                        if (fwrite(charset, PLANE_SIZE(charset->metadata),
                                        1, fp) != 1) {
                                LOG("fwrite: 0x%x: %s", errno, strerror(errno));
@@ -1445,9 +1435,6 @@ rufl_code rufl_save_cache(void)
                        charset = (void *)(((uint8_t *)charset) +
                                        PLANE_SIZE(charset->metadata));
                }
-               LOG("writing plane %d (%u)",
-                               PLANE_ID(charset->metadata),
-                               PLANE_SIZE(charset->metadata));
                if (fwrite(charset, PLANE_SIZE(charset->metadata),
                                1, fp) != 1) {
                        LOG("fwrite: 0x%x: %s", errno, strerror(errno));
@@ -1606,7 +1593,6 @@ rufl_code rufl_load_cache(void)
                identifier[len] = 0;
 
                /* character set */
-               LOG("reading character sets for %s", identifier);
                do {
                        if (fread(&metadata, sizeof metadata, 1, fp) != 1) {
                                if (feof(fp))
@@ -1618,9 +1604,6 @@ rufl_code rufl_load_cache(void)
                                break;
                        }
 
-                       LOG("reading plane %d (%u)",
-                                       PLANE_ID(metadata),
-                                       PLANE_SIZE(metadata));
                        if (!charset) {
                                charset = cur_charset = malloc(
                                                PLANE_SIZE(metadata));


-----------------------------------------------------------------------

Summary of changes:
 include/rufl.h        |    2 +-
 src/rufl_dump_state.c |    6 +-
 src/rufl_init.c       |  233 +++++++++++++++++++++++++++++--------------------
 test/rufl_test.c      |    2 +-
 4 files changed, 144 insertions(+), 99 deletions(-)

diff --git a/include/rufl.h b/include/rufl.h
index 0164df8..15e889e 100644
--- a/include/rufl.h
+++ b/include/rufl.h
@@ -185,7 +185,7 @@ rufl_code rufl_font_bbox(const char *font_family, 
rufl_style font_style,
  * Dump the internal library state to stdout.
  */
 
-void rufl_dump_state(void);
+void rufl_dump_state(bool verbose);
 
 
 /**
diff --git a/src/rufl_dump_state.c b/src/rufl_dump_state.c
index 13a1564..f466333 100644
--- a/src/rufl_dump_state.c
+++ b/src/rufl_dump_state.c
@@ -18,7 +18,7 @@ static void rufl_dump_unicode_map(struct rufl_unicode_map 
*umap);
  * Dump the internal library state to stdout.
  */
 
-void rufl_dump_state(void)
+void rufl_dump_state(bool verbose)
 {
        unsigned int i, j;
 
@@ -32,7 +32,7 @@ void rufl_dump_state(void)
                } else {
                        printf("    (no charset table)\n");
                }
-               if (rufl_font_list[i].umap) {
+               if (verbose && rufl_font_list[i].umap) {
                        for (j = 0; j < rufl_font_list[i].num_umaps; j++) {
                                struct rufl_unicode_map *map =
                                                rufl_font_list[i].umap + j;
@@ -90,7 +90,7 @@ static void rufl_dump_character_set(const struct 
rufl_character_set *charset)
                                u++;
                        } else {
                                t = u;
-                               while (rufl_character_set_test(
+                               while (u != 0x10000 && rufl_character_set_test(
                                                        charset, plane + u))
                                        u++;
                                printf("%x-%x ", plane + t, plane + u - 1);
diff --git a/src/rufl_init.c b/src/rufl_init.c
index 6ec21b7..6cf0be6 100644
--- a/src/rufl_init.c
+++ b/src/rufl_init.c
@@ -60,11 +60,13 @@ const struct rufl_weight_table_entry rufl_weight_table[] = {
        { "ExtraLight", 1 },
        { "Heavy", 8 },
        { "Light", 2 },
+       { "MedBold", 6 },
        { "Medium", 5 },
        { "Regular", 4 },
        { "Semi", 6 },
        { "SemiBold", 6 },
        { "SemiLight", 3 },
+       { "Thin", 1 },
        { "UltraBlack", 9 },
        { "UltraBold", 9 },
 };
@@ -470,31 +472,26 @@ static void rufl_init_shrinkwrap_plane(struct 
rufl_character_set *charset)
                for (byte = 0; byte != 32; byte++)
                        bit &= charset->block[block][byte];
 
-               if (bit == 0xff) {
-                       /* Block is full */
 
-                       /* Find a block whose index is after this one.
-                        * If such a block exists, move its data into
-                        * this block, as this block's bitmap is now free
-                       */
-                       for (byte = 0; byte != 256; byte++) {
-                               if (charset->index[byte] < BLOCK_EMPTY &&
-                                               charset->index[byte] > block) {
-                                       break;
-                               }
-                       }
-                       if (byte != 256) {
-                               memcpy(charset->block[block],
-                                               charset->block[
-                                                       charset->index[byte]],
-                                               32);
-                               charset->index[byte] = block;
-                       }
+               if (bit != 0xff)
+                       continue;
 
-                       /* Now mark this block as full */
-                       charset->index[u] = BLOCK_FULL;
-                       last_used--;
+               /* Block is full */
+
+               /* Move subsequent blocks up and rewrite their indices */
+               memmove(charset->block[block],
+                               charset->block[block+1],
+                               (254-(block+1)) * 32);
+               for (byte = 0; byte != 256; byte++) {
+                       if (charset->index[byte] < BLOCK_EMPTY &&
+                                       charset->index[byte] > block) {
+                               charset->index[byte]--;
+                       }
                }
+
+               /* Now mark this block as full */
+               charset->index[u] = BLOCK_FULL;
+               last_used--;
        }
 
        /* Fill in this plane's size now we know it */
@@ -512,14 +509,11 @@ static struct rufl_character_set 
*rufl_init_shrinkwrap_planes(
        /* Shrink-wrap each plane, accumulating total required size as we go */
        for (u = 0; u < 17; u++) {
                if (planes[u]) {
-                       LOG("shrink-wrapping plane %d", u);
                        rufl_init_shrinkwrap_plane(planes[u]);
                        size += PLANE_SIZE(planes[u]->metadata);
                }
        }
 
-       LOG("shrink-wrapped size: %u", size);
-
        charset = malloc(size);
        if (!charset)
                return NULL;
@@ -531,8 +525,6 @@ static struct rufl_character_set 
*rufl_init_shrinkwrap_planes(
                if (!planes[u-1])
                        continue;
 
-               LOG("merging plane %d", u);
-
                /* Set E bit if not the last plane */
                if (pos != size)
                        planes[u-1]->metadata |= (1u<<31);
@@ -551,16 +543,56 @@ static rufl_code rufl_init_enumerate_characters(const 
char *font_name,
                        uint32_t glyph_idx, uint32_t ucs4),
                void *pw)
 {
-       unsigned int u, next;
-       rufl_code result;
+       unsigned int u = 0, next, internal;
+       rufl_code result = rufl_OK;
 
-       if (rufl_broken_font_enumerate_characters)
-               return rufl_init_read_encoding(font, callback, pw);
+       if (rufl_broken_font_enumerate_characters) {
+               /* We know that any codepoints in the first chunk will
+                * be missed because Font_EnumerateCharacters is broken
+                * on this version of the Font Manager. Find the first
+                * codepoint it will report. */
+               unsigned int first;
+               rufl_fm_error = xfont_enumerate_characters(font, 0,
+                               (int *) &first, (int *) &internal);
+               if (rufl_fm_error) {
+                       LOG("xfont_enumerate_characters(\"%s\", "
+                           "U+%x, ...): 0x%x: %s",
+                                       font_name, 0,
+                                       rufl_fm_error->errnum,
+                                       rufl_fm_error->errmess);
+                       return rufl_FONT_MANAGER_ERROR;
+               }
 
-       /* Scan through mapped characters */
-       for (u = 0; u != (unsigned int) -1; u = next) {
-               unsigned int internal;
+               /* Search the entire space up to the first codepoint it
+                * reported. */
+               for (u = 0; u != (unsigned int) -1 && u != first; u++) {
+                       rufl_fm_error = xfont_enumerate_characters(font, u,
+                                       (int *) &next, (int *) &internal);
+                       if (rufl_fm_error) {
+                               LOG("xfont_enumerate_characters(\"%s\", "
+                                   "U+%x, ...): 0x%x: %s",
+                                               font_name, u,
+                                               rufl_fm_error->errnum,
+                                               rufl_fm_error->errmess);
+                               result = rufl_FONT_MANAGER_ERROR;
+                               break;
+                       }
+
+                       /* Skip unmapped characters */
+                       if (internal == (unsigned int) -1)
+                               continue;
+
+                       /* Character is mapped, emit it */
+                       result = callback(pw, internal, u);
+                       if (result != rufl_OK)
+                               break;
+               }
+
+               /* Now fall through to the normal path */
+       }
 
+       /* Scan through mapped characters */
+       for (; u != (unsigned int) -1; u = next) {
                rufl_fm_error = xfont_enumerate_characters(font, u, 
                                (int *) &next, (int *) &internal);
                if (rufl_fm_error) {
@@ -569,6 +601,7 @@ static rufl_code rufl_init_enumerate_characters(const char 
*font_name,
                                        font_name, u,
                                        rufl_fm_error->errnum, 
                                        rufl_fm_error->errmess);
+                       result = rufl_FONT_MANAGER_ERROR;
                        break;
                }
 
@@ -837,7 +870,20 @@ rufl_code rufl_init_scan_font_old(unsigned int font_index)
 
                code = rufl_init_scan_font_in_encoding(font_name, encoding,
                                charset, umap + (num_umaps - 1), &last_used);
-               if (code != rufl_OK) {
+               /* Not finding the font isn't fatal */
+               if (code == rufl_FONT_MANAGER_ERROR &&
+                               (rufl_fm_error->errnum ==
+                                       error_FONT_NOT_FOUND ||
+                               rufl_fm_error->errnum ==
+                                       error_FILE_NOT_FOUND ||
+                               rufl_fm_error->errnum ==
+                                       error_FONT_ENCODING_NOT_FOUND ||
+                               /* Neither is a too modern font */
+                               rufl_fm_error->errnum ==
+                                       error_FONT_TOO_MANY_CHUNKS)) {
+                       /* Ensure we reuse the currently allocated umap */
+                       num_umaps--;
+               } else if (code != rufl_OK) {
                        LOG("rufl_init_scan_font_in_encoding(\"%s\", \"%s\", "
                            "...): 0x%x (0x%x: %s)",
                                        font_name, encoding, code,
@@ -846,23 +892,11 @@ rufl_code rufl_init_scan_font_old(unsigned int font_index)
                                        code == rufl_FONT_MANAGER_ERROR ?
                                                rufl_fm_error->errmess : "");
 
-                       /* Not finding the font isn't fatal */
-                       if (code != rufl_FONT_MANAGER_ERROR ||
-                               (rufl_fm_error->errnum != 
-                                       error_FONT_NOT_FOUND &&
-                               rufl_fm_error->errnum !=
-                                       error_FILE_NOT_FOUND &&
-                               rufl_fm_error->errnum !=
-                                       error_FONT_ENCODING_NOT_FOUND)) {
-                               free(charset);
-                               for (i = 0; i < num_umaps; i++)
-                                       free((umap + i)->encoding);
-                               free(umap);
-                               return code;
-                       }
-
-                       /* Ensure we reuse the currently allocated umap */
-                       num_umaps--;
+                       free(charset);
+                       for (i = 0; i < num_umaps; i++)
+                               free((umap + i)->encoding);
+                       free(umap);
+                       return code;
                } else {
                        /* If this mapping is identical to an existing one, 
                         * then we can discard it */
@@ -901,7 +935,20 @@ rufl_code rufl_init_scan_font_old(unsigned int font_index)
 
                code = rufl_init_scan_font_in_encoding(font_name, NULL,
                                charset, umap, &last_used);
-               if (code != rufl_OK) {
+               /* Not finding the font isn't fatal */
+               if (code == rufl_FONT_MANAGER_ERROR &&
+                               (rufl_fm_error->errnum ==
+                                       error_FONT_NOT_FOUND ||
+                               rufl_fm_error->errnum ==
+                                       error_FILE_NOT_FOUND ||
+                               rufl_fm_error->errnum ==
+                                       error_FONT_ENCODING_NOT_FOUND ||
+                               /* Neither is a too modern font */
+                               rufl_fm_error->errnum ==
+                                       error_FONT_TOO_MANY_CHUNKS)) {
+                       /* Ensure we reuse the currently allocated umap */
+                       num_umaps--;
+               } else if (code != rufl_OK) {
                        LOG("rufl_init_scan_font_in_encoding(\"%s\", NULL, "
                            "...): 0x%x (0x%x: %s)",
                                        font_name, code,
@@ -910,22 +957,11 @@ rufl_code rufl_init_scan_font_old(unsigned int font_index)
                                        code == rufl_FONT_MANAGER_ERROR ?
                                                rufl_fm_error->errmess : "");
 
-                       /* Not finding the font isn't fatal */
-                       if (code != rufl_FONT_MANAGER_ERROR ||
-                               (rufl_fm_error->errnum != 
-                                       error_FONT_NOT_FOUND &&
-                               rufl_fm_error->errnum !=
-                                       error_FILE_NOT_FOUND &&
-                               rufl_fm_error->errnum !=
-                                       error_FONT_ENCODING_NOT_FOUND)) {
-                               free(charset);
-                               for (i = 0; i < num_umaps; i++)
-                                       free((umap + i)->encoding);
-                               free(umap);
-                               return code;
-                       }
-
-                       num_umaps--;
+                       free(charset);
+                       for (i = 0; i < num_umaps; i++)
+                               free((umap + i)->encoding);
+                       free(umap);
+                       return code;
                }
        }
 
@@ -984,8 +1020,7 @@ rufl_code rufl_init_scan_font_in_encoding(const char 
*font_name,
 
        rufl_fm_error = xfont_find_font(buf, 160, 160, 0, 0, &font, 0, 0);
        if (rufl_fm_error) {
-               LOG("xfont_find_font(\"%s\"): 0x%x: %s", buf,
-                               rufl_fm_error->errnum, rufl_fm_error->errmess);
+               /* Leave it to our caller to log, if they wish */
                return rufl_FONT_MANAGER_ERROR;
        }
 
@@ -993,10 +1028,33 @@ rufl_code rufl_init_scan_font_in_encoding(const char 
*font_name,
        if (code != rufl_OK) {
                LOG("rufl_init_read_encoding(\"%s\", ...): 0x%x",
                                buf, code);
+               umap->encoding = NULL;
                xfont_lose_font(font);
                return code;
        }
 
+       /* Detect attempts to use UCS fonts with a non-UCS Font Manager.
+        * There is a bug in all known non-UCS Font Managers which is
+        * often triggered by scanning many fonts. The Font Manager will
+        * attempt to dereference a bogus pointer (at the start of
+        * getbbox_unscaled) and thus cause an abort in SVC mode.
+        * Fallout can be as (relatively) benign as the application
+        * crashing or escalate to an entire system freeze requiring
+        * a reset. As there are no "good" outcomes here, and we do
+        * not have a time machine to go back and fix long-ago released
+        * Font Managers, ensure we ignore UCS fonts here. */
+       if ((uint32_t) umap->encoding > 256) {
+               static os_error err = {
+                       error_FONT_TOO_MANY_CHUNKS, "Rejecting UCS font"};
+               LOG("%s", "Rejecting UCS font");
+               umap->encoding = NULL;
+               xfont_lose_font(font);
+               rufl_fm_error = &err;
+               return rufl_FONT_MANAGER_ERROR;
+       }
+       /* Eliminate all trace of our (ab)use of the encoding field */
+       umap->encoding = NULL;
+
        for (i = 0; i != umap->entries; i++) {
                u = umap->map[i].u;
                string[0] = umap->map[i].c;
@@ -1067,9 +1125,11 @@ static rufl_code rufl_init_umap_cb(void *pw, uint32_t 
glyph_idx, uint32_t ucs4)
                umap->map[umap->entries].u = ucs4;
                umap->map[umap->entries].c = glyph_idx;
                umap->entries++;
-               if (umap->entries == 256)
-                       result = rufl_IO_EOF;
        }
+       /* Stash the total number of encoding file entries so that
+        * rufl_init_scan_font_in_encoding can detect the presence of a
+        * UCS font on a non-UCS capable system. It will clean up for us. */
+       umap->encoding = (void *) (((uint32_t) umap->encoding) + 1);
 
        return result;
 }
@@ -1085,7 +1145,7 @@ rufl_code rufl_init_populate_unicode_map(font_f f,
 
        umap->entries = 0;
 
-       result = rufl_init_read_encoding(f, rufl_init_umap_cb, &umap);
+       result = rufl_init_read_encoding(f, rufl_init_umap_cb, umap);
        if (result == rufl_OK) {
                /* sort by unicode */
                qsort(umap->map, umap->entries, sizeof umap->map[0],
@@ -1233,13 +1293,9 @@ rufl_code rufl_init_read_encoding(font_f font,
        }
 
        fp = fopen(filename, "r");
-       if (!fp) {
+       if (!fp && rufl_old_font_manager) {
                /* many "symbol" fonts have no encoding file */
-               const char *default_path =
-                       "Resources:$.Fonts.Encodings./Default";
-               if (rufl_old_font_manager)
-                       default_path = "Resources:$.Fonts.Encodings.Latin1";
-               fp = fopen(default_path, "r");
+               fp = fopen("Resources:$.Fonts.Encodings.Latin1", "r");
        }
        if (!fp)
                return rufl_IO_ERROR;
@@ -1276,8 +1332,9 @@ rufl_code rufl_init_read_encoding(font_f font,
                                        (c >= 'a' && c <= 'z') ||
                                        (c >= 'A' && c <= 'Z') ||
                                        (c == '.') || (c == '_') ||
-                                       (c == ';')) {
-                               /* Printable: append */
+                                       (c == ';') ||
+                                       (c == ' ' && s[0] != '/')) {
+                               /* Printable (or space in new-style): append */
                                s[n++] = c;
                                if (n >= sizeof(s)) {
                                        /* Too long: garbage */
@@ -1430,12 +1487,7 @@ rufl_code rufl_save_cache(void)
                }
 
                /* character set (all planes) */
-               LOG("writing character sets for %s",
-                               rufl_font_list[i].identifier);
                while (EXTENSION_FOLLOWS(charset->metadata)) {
-                       LOG("writing plane %d (%u)",
-                                       PLANE_ID(charset->metadata),
-                                       PLANE_SIZE(charset->metadata));
                        if (fwrite(charset, PLANE_SIZE(charset->metadata),
                                        1, fp) != 1) {
                                LOG("fwrite: 0x%x: %s", errno, strerror(errno));
@@ -1445,9 +1497,6 @@ rufl_code rufl_save_cache(void)
                        charset = (void *)(((uint8_t *)charset) +
                                        PLANE_SIZE(charset->metadata));
                }
-               LOG("writing plane %d (%u)",
-                               PLANE_ID(charset->metadata),
-                               PLANE_SIZE(charset->metadata));
                if (fwrite(charset, PLANE_SIZE(charset->metadata),
                                1, fp) != 1) {
                        LOG("fwrite: 0x%x: %s", errno, strerror(errno));
@@ -1606,7 +1655,6 @@ rufl_code rufl_load_cache(void)
                identifier[len] = 0;
 
                /* character set */
-               LOG("reading character sets for %s", identifier);
                do {
                        if (fread(&metadata, sizeof metadata, 1, fp) != 1) {
                                if (feof(fp))
@@ -1618,9 +1666,6 @@ rufl_code rufl_load_cache(void)
                                break;
                        }
 
-                       LOG("reading plane %d (%u)",
-                                       PLANE_ID(metadata),
-                                       PLANE_SIZE(metadata));
                        if (!charset) {
                                charset = cur_charset = malloc(
                                                PLANE_SIZE(metadata));
diff --git a/test/rufl_test.c b/test/rufl_test.c
index d939467..5b76f81 100644
--- a/test/rufl_test.c
+++ b/test/rufl_test.c
@@ -35,7 +35,7 @@ int main(void)
        int bbox[4];
 
        try(rufl_init(), "rufl_init");
-       rufl_dump_state();
+       rufl_dump_state(false);
        try(rufl_paint("NewHall", rufl_WEIGHT_400, 240,
                        utf8_test, sizeof utf8_test - 1,
                        1200, 1000, 0), "rufl_paint");


-- 
RISC OS Unicode Font Library
_______________________________________________
netsurf-commits mailing list -- netsurf-commits@netsurf-browser.org
To unsubscribe send an email to netsurf-commits-le...@netsurf-browser.org

Reply via email to