summaryrefslogtreecommitdiff
path: root/rufl_init.c
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2010-01-06 16:32:59 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2010-01-06 16:32:59 +0000
commitf3a77d3c00c095a53f37aa7efb39d56168799596 (patch)
tree0bd2269afe0edd5018c5d231c95a5011002c83cf /rufl_init.c
parent628079a91ca6d86a7915906d266e6fe5593bb846 (diff)
downloadlibrufl-f3a77d3c00c095a53f37aa7efb39d56168799596.tar.gz
librufl-f3a77d3c00c095a53f37aa7efb39d56168799596.tar.bz2
Port to core buildsystem.
The python module (and associated make runes) need some love (as does non-GCC building with the core buildsystem in general) svn path=/trunk/rufl/; revision=9792
Diffstat (limited to 'rufl_init.c')
-rw-r--r--rufl_init.c1678
1 files changed, 0 insertions, 1678 deletions
diff --git a/rufl_init.c b/rufl_init.c
deleted file mode 100644
index 533955a..0000000
--- a/rufl_init.c
+++ /dev/null
@@ -1,1678 +0,0 @@
-/*
- * This file is part of RUfl
- * Licensed under the MIT License,
- * http://www.opensource.org/licenses/mit-license
- * Copyright 2006 James Bursa <james@semichrome.net>
- */
-
-#define _GNU_SOURCE /* for strndup */
-#include <assert.h>
-#include <errno.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <search.h>
-#include <oslib/font.h>
-#include <oslib/hourglass.h>
-#include <oslib/os.h>
-#include <oslib/osfscontrol.h>
-#include <oslib/taskwindow.h>
-#include <oslib/wimp.h>
-#include <oslib/wimpreadsysinfo.h>
-#include "rufl_internal.h"
-
-
-struct rufl_font_list_entry *rufl_font_list = 0;
-size_t rufl_font_list_entries = 0;
-const char **rufl_family_list = 0;
-unsigned int rufl_family_list_entries = 0;
-struct rufl_family_map_entry *rufl_family_map = 0;
-os_error *rufl_fm_error = 0;
-void *rufl_family_menu = 0;
-unsigned short *rufl_substitution_table = 0;
-struct rufl_cache_entry rufl_cache[rufl_CACHE_SIZE];
-int rufl_cache_time = 0;
-bool rufl_old_font_manager = false;
-wimp_w rufl_status_w = 0;
-char rufl_status_buffer[80];
-
-/** An entry in rufl_weight_table. */
-struct rufl_weight_table_entry {
- const char *name;
- unsigned int weight;
-};
-
-/** Map from font name part to font weight. Must be case-insensitive sorted by
- * name. */
-const struct rufl_weight_table_entry rufl_weight_table[] = {
- { "Black", 9 },
- { "Bold", 7 },
- { "Book", 3 },
- { "Demi", 6 },
- { "DemiBold", 6 },
- { "Extra", 8 },
- { "ExtraBlack", 9 },
- { "ExtraBold", 8 },
- { "ExtraLight", 1 },
- { "Heavy", 8 },
- { "Light", 2 },
- { "Medium", 5 },
- { "Regular", 4 },
- { "Semi", 6 },
- { "SemiBold", 6 },
- { "SemiLight", 3 },
- { "UltraBlack", 9 },
- { "UltraBold", 9 },
-};
-
-
-static rufl_code rufl_init_font_list(void);
-static rufl_code rufl_init_add_font(const char *identifier,
- const char *local_name);
-static int rufl_weight_table_cmp(const void *keyval, const void *datum);
-static rufl_code rufl_init_scan_font(unsigned int font);
-static rufl_code rufl_init_scan_font_no_enumerate(unsigned int font);
-static bool rufl_is_space(unsigned int u);
-static rufl_code rufl_init_scan_font_old(unsigned int font_index);
-static rufl_code rufl_init_scan_font_in_encoding(const char *font_name,
- const char *encoding, struct rufl_character_set *charset,
- struct rufl_unicode_map *umap, unsigned int *last);
-static rufl_code rufl_init_read_encoding(font_f font,
- struct rufl_unicode_map *umap);
-static int rufl_glyph_map_cmp(const void *keyval, const void *datum);
-static int rufl_unicode_map_cmp(const void *z1, const void *z2);
-static rufl_code rufl_init_substitution_table(void);
-static rufl_code rufl_save_cache(void);
-static rufl_code rufl_load_cache(void);
-static int rufl_font_list_cmp(const void *keyval, const void *datum);
-static rufl_code rufl_init_family_menu(void);
-static void rufl_init_status_open(void);
-static void rufl_init_status(const char *status, float progress);
-static void rufl_init_status_close(void);
-
-
-/**
- * Initialise RUfl.
- *
- * All available fonts are scanned. May take some time.
- */
-
-rufl_code rufl_init(void)
-{
- bool rufl_broken_font_enumerate_characters = false;
- unsigned int changes = 0;
- unsigned int i;
- int fm_version;
- rufl_code code;
- font_f font;
- os_colour old_sand, old_glass;
-
- if (rufl_font_list_entries)
- /* already initialized */
- return rufl_OK;
-
- xhourglass_on();
-
- rufl_init_status_open();
-
- /* determine if the font manager supports Unicode */
- rufl_fm_error = xfont_find_font("Homerton.Medium\\EUTF8", 160, 160,
- 0, 0, &font, 0, 0);
- if (rufl_fm_error) {
- if (rufl_fm_error->errnum == error_FONT_ENCODING_NOT_FOUND) {
- rufl_old_font_manager = true;
- } else {
- LOG("xfont_find_font: 0x%x: %s",
- rufl_fm_error->errnum,
- rufl_fm_error->errmess);
- rufl_quit();
- xhourglass_off();
- return rufl_FONT_MANAGER_ERROR;
- }
- } else {
- /* New font manager; see if character enumeration works */
- int next;
-
- rufl_fm_error = xfont_enumerate_characters(font, 0,
- &next, NULL);
- /* Broken if SWI fails or it doesn't return 0x20 as the first
- * character to process. Font Managers earlier than 3.64 have
- * a bug that means they do not return the first available
- * range of characters in a font. We detect this by asking
- * for the first character in Homerton.Medium, which we know
- * is 0x20 (i.e. space). If the value returned is not this,
- * then we assume the font manager is broken and fall back to
- * the old code which is significantly slower.
- */
- if (rufl_fm_error || next != 0x20)
- rufl_broken_font_enumerate_characters = true;
-
- xfont_lose_font(font);
- }
- LOG("%s font manager", rufl_old_font_manager ? "old" : "new");
-
- /* test if the font manager supports background blending */
- rufl_fm_error = xfont_cache_addr(&fm_version, 0, 0);
- if (rufl_fm_error)
- return rufl_FONT_MANAGER_ERROR;
- if (fm_version >= 335)
- rufl_can_background_blend = true;
-
- code = rufl_init_font_list();
- if (code != rufl_OK) {
- rufl_quit();
- xhourglass_off();
- return code;
- }
- LOG("%zu faces, %u families", rufl_font_list_entries,
- rufl_family_list_entries);
-
- code = rufl_load_cache();
- if (code != rufl_OK) {
- LOG("rufl_load_cache: 0x%x", code);
- rufl_quit();
- xhourglass_off();
- return code;
- }
-
- xhourglass_leds(1, 0, 0);
- for (i = 0; i != rufl_font_list_entries; i++) {
- if (rufl_font_list[i].charset) {
- /* character set loaded from cache */
- continue;
- }
- LOG("scanning %u \"%s\"", i, rufl_font_list[i].identifier);
- xhourglass_percentage(100 * i / rufl_font_list_entries);
- rufl_init_status(rufl_font_list[i].identifier,
- (float) i / rufl_font_list_entries);
- if (rufl_old_font_manager)
- code = rufl_init_scan_font_old(i);
- else if (rufl_broken_font_enumerate_characters)
- code = rufl_init_scan_font_no_enumerate(i);
- else
- code = rufl_init_scan_font(i);
- if (code != rufl_OK) {
- LOG("rufl_init_scan_font: 0x%x", code);
- rufl_quit();
- xhourglass_off();
- return code;
- }
- changes++;
- }
-
- xhourglass_leds(2, 0, 0);
- xhourglass_colours(0x0000ff, 0x00ffff, &old_sand, &old_glass);
- code = rufl_init_substitution_table();
- if (code != rufl_OK) {
- LOG("rufl_init_substitution_table: 0x%x", code);
- rufl_quit();
- xhourglass_off();
- return code;
- }
- xhourglass_colours(old_sand, old_glass, 0, 0);
-
- if (changes) {
- LOG("%u new charsets", changes);
- xhourglass_leds(3, 0, 0);
- code = rufl_save_cache();
- if (code != rufl_OK) {
- LOG("rufl_save_cache: 0x%x", code);
- rufl_quit();
- xhourglass_off();
- return code;
- }
- }
-
- for (i = 0; i != rufl_CACHE_SIZE; i++)
- rufl_cache[i].font = rufl_CACHE_NONE;
-
- code = rufl_init_family_menu();
- if (code != rufl_OK) {
- LOG("rufl_init_substitution_table: 0x%x", code);
- rufl_quit();
- xhourglass_off();
- return code;
- }
-
- rufl_init_status_close();
-
- xhourglass_off();
-
- return rufl_OK;
-}
-
-
-/**
- * Build list of font in rufl_font_list and list of font families
- * in rufl_family_list.
- */
-
-rufl_code rufl_init_font_list(void)
-{
- rufl_code code;
- font_list_context context = 0;
- char identifier[80], local_name[80];
-
- while (context != -1) {
- /* read identifier */
- rufl_fm_error = xfont_list_fonts((byte *)identifier,
- font_RETURN_FONT_NAME |
- font_RETURN_LOCAL_FONT_NAME |
- context,
- sizeof identifier,
- (byte *)local_name, sizeof local_name, 0,
- &context, 0, 0);
- if (rufl_fm_error) {
- LOG("xfont_list_fonts: 0x%x: %s",
- rufl_fm_error->errnum,
- rufl_fm_error->errmess);
- return rufl_FONT_MANAGER_ERROR;
- }
- if (context == -1)
- break;
-
- code = rufl_init_add_font(identifier, local_name);
- if (code != rufl_OK)
- return code;
- }
-
- return rufl_OK;
-}
-
-
-rufl_code rufl_init_add_font(const char *identifier, const char *local_name)
-{
- int size;
- struct rufl_font_list_entry *font_list;
- char *dot;
- const char **family_list;
- const char *family, *part;
- unsigned int weight = 0;
- unsigned int slant = 0;
- bool special = false;
- struct rufl_family_map_entry *family_map;
- unsigned int i;
- struct rufl_weight_table_entry *entry;
-
- /* Check that:
- * a) it's not a RiScript generated font
- * b) it's not a TeX font */
-
- /* Read required buffer size */
- rufl_fm_error = xosfscontrol_canonicalise_path(identifier, 0,
- "Font$Path", 0, 0, &size);
- if (rufl_fm_error) {
- LOG("xosfscontrol_canonicalise_path(\"%s\", ...): 0x%x: %s",
- identifier,
- rufl_fm_error->errnum,
- rufl_fm_error->errmess);
- return rufl_OK;
- }
- /* size is -(space required - 1) so negate and add 1 */
- size = -size + 1;
-
- /* Create buffer and canonicalise path */
- char fullpath[size];
- rufl_fm_error = xosfscontrol_canonicalise_path(identifier,
- fullpath, "Font$Path", 0, size, 0);
- if (rufl_fm_error) {
- LOG("xosfscontrol_canonicalise_path(\"%s\", ...): 0x%x: %s",
- identifier,
- rufl_fm_error->errnum,
- rufl_fm_error->errmess);
- return rufl_OK;
- }
-
- /* LOG("%s", fullpath); */
-
- if (strstr(fullpath, "RiScript") || strstr(fullpath, "!TeXFonts"))
- /* Ignore this font */
- return rufl_OK;
-
- /* add identifier to rufl_font_list */
- font_list = realloc(rufl_font_list, sizeof rufl_font_list[0] *
- (rufl_font_list_entries + 1));
- if (!font_list)
- return rufl_OUT_OF_MEMORY;
- rufl_font_list = font_list;
- rufl_font_list[rufl_font_list_entries].identifier = strdup(identifier);
- if (!rufl_font_list[rufl_font_list_entries].identifier)
- return rufl_OUT_OF_MEMORY;
- rufl_font_list[rufl_font_list_entries].charset = 0;
- rufl_font_list[rufl_font_list_entries].umap = 0;
- rufl_font_list_entries++;
-
- /* determine family, weight, and slant */
- dot = strchr(local_name, '.');
- family = local_name;
- if (dot)
- *dot = 0;
- while (dot) {
- part = dot + 1;
- dot = strchr(part, '.');
- if (dot)
- *dot = 0;
- if (strcasecmp(part, "Italic") == 0 ||
- strcasecmp(part, "Oblique") == 0) {
- slant = 1;
- continue;
- }
- entry = bsearch(part, rufl_weight_table,
- sizeof rufl_weight_table /
- sizeof rufl_weight_table[0],
- sizeof rufl_weight_table[0],
- rufl_weight_table_cmp);
- if (entry)
- weight = entry->weight;
- else
- special = true; /* unknown weight or style */
- }
- if (!weight)
- weight = 4;
- weight--;
-
- if (rufl_family_list_entries == 0 || strcasecmp(family,
- rufl_family_list[rufl_family_list_entries - 1]) != 0) {
- /* new family */
- family_list = realloc(rufl_family_list,
- sizeof rufl_family_list[0] *
- (rufl_family_list_entries + 1));
- if (!family_list)
- return rufl_OUT_OF_MEMORY;
- rufl_family_list = family_list;
-
- family_map = realloc(rufl_family_map,
- sizeof rufl_family_map[0] *
- (rufl_family_list_entries + 1));
- if (!family_map)
- return rufl_OUT_OF_MEMORY;
- rufl_family_map = family_map;
-
- family = strdup(family);
- if (!family)
- return rufl_OUT_OF_MEMORY;
-
- rufl_family_list[rufl_family_list_entries] = family;
- for (i = 0; i != 9; i++)
- rufl_family_map[rufl_family_list_entries].font[i][0] =
- rufl_family_map[rufl_family_list_entries].font[i][1] =
- NO_FONT;
- rufl_family_list_entries++;
- }
-
- struct rufl_family_map_entry *e =
- &rufl_family_map[rufl_family_list_entries - 1];
- /* prefer fonts with no unknown weight or style in their name, so that,
- * for example, Alps.Light takes priority over Alps.Cond.Light */
- if (e->font[weight][slant] == NO_FONT || !special)
- e->font[weight][slant] = rufl_font_list_entries - 1;
-
- rufl_font_list[rufl_font_list_entries - 1].family =
- rufl_family_list_entries - 1;
- rufl_font_list[rufl_font_list_entries - 1].weight = weight;
- rufl_font_list[rufl_font_list_entries - 1].slant = slant;
-
- return rufl_OK;
-}
-
-
-int rufl_weight_table_cmp(const void *keyval, const void *datum)
-{
- const char *key = keyval;
- const struct rufl_weight_table_entry *entry = datum;
- return strcasecmp(key, entry->name);
-}
-
-/**
- * Scan a font for available characters.
- */
-
-rufl_code rufl_init_scan_font(unsigned int font_index)
-{
- char font_name[80];
- int x_out, y_out;
- unsigned int byte, bit;
- unsigned int last_used = 0;
- unsigned int string[2] = { 0, 0 };
- unsigned int u, next;
- struct rufl_character_set *charset;
- struct rufl_character_set *charset2;
- font_f font;
- font_scan_block block = { { 0, 0 }, { 0, 0 }, -1, { 0, 0, 0, 0 } };
-
- /*LOG("font %u \"%s\"", font_index,
- rufl_font_list[font_index].identifier);*/
-
- charset = calloc(1, sizeof *charset);
- if (!charset)
- return rufl_OUT_OF_MEMORY;
- for (u = 0; u != 256; u++)
- charset->index[u] = BLOCK_EMPTY;
-
- snprintf(font_name, sizeof font_name, "%s\\EUTF8",
- rufl_font_list[font_index].identifier);
-
- rufl_fm_error = xfont_find_font(font_name, 160, 160, 0, 0, &font, 0, 0);
- if (rufl_fm_error) {
- LOG("xfont_find_font(\"%s\"): 0x%x: %s", font_name,
- rufl_fm_error->errnum, rufl_fm_error->errmess);
- free(charset);
- return rufl_OK;
- }
-
- /* Scan through mapped characters */
- for (u = 0; u != (unsigned int) -1; u = next) {
- unsigned int internal;
-
- rufl_fm_error = xfont_enumerate_characters(font, u,
- (int *) &next, (int *) &internal);
- if (rufl_fm_error) {
- LOG("xfont_enumerate_characters: 0x%x: %s",
- rufl_fm_error->errnum,
- rufl_fm_error->errmess);
- xfont_lose_font(font);
- free(charset);
- return rufl_OK;
- }
-
- /* Skip DELETE and C0/C1 controls */
- if (u < 0x0020 || (0x007f <= u && u <= 0x009f))
- continue;
-
- /* Skip astral characters */
- if (u > 0xffff)
- continue;
-
- /* Skip unmapped characters */
- if (internal == (unsigned int) -1)
- continue;
-
- if (u % 0x200 == 0)
- rufl_init_status(0, 0);
-
- /* Character is mapped, let's see if it's really there */
- string[0] = u;
- rufl_fm_error = xfont_scan_string(font, (char *) string,
- font_RETURN_BBOX | font_GIVEN32_BIT |
- font_GIVEN_FONT | font_GIVEN_LENGTH |
- font_GIVEN_BLOCK,
- 0x7fffffff, 0x7fffffff,
- &block, 0, 4,
- 0, &x_out, &y_out, 0);
- if (rufl_fm_error)
- break;
-
- if (block.bbox.x0 == 0x20000000) {
- /* absent (no definition) */
- } else if (x_out == 0 && y_out == 0 &&
- block.bbox.x0 == 0 && block.bbox.y0 == 0 &&
- block.bbox.x1 == 0 && block.bbox.y1 == 0) {
- /* absent (empty) */
- } else if (block.bbox.x0 == 0 && block.bbox.y0 == 0 &&
- block.bbox.x1 == 0 && block.bbox.y1 == 0 &&
- !rufl_is_space(u)) {
- /* absent (space but not a space character - some
- * fonts do this) */
- } else {
- /* present */
- if (charset->index[u >> 8] == BLOCK_EMPTY) {
- charset->index[u >> 8] = last_used;
- last_used++;
- if (last_used == 254)
- /* too many characters */
- break;
- }
-
- byte = (u >> 3) & 31;
- bit = u & 7;
- charset->block[charset->index[u >> 8]][byte] |=
- 1 << bit;
- }
- }
-
- xfont_lose_font(font);
-
- if (rufl_fm_error) {
- free(charset);
- LOG("xfont_scan_string: 0x%x: %s",
- rufl_fm_error->errnum, rufl_fm_error->errmess);
- return rufl_FONT_MANAGER_ERROR;
- }
-
- /* Determine which blocks are full, and mark them as such */
- for (u = 0; u != 256; u++) {
- if (charset->index[u] == BLOCK_EMPTY)
- continue;
-
- bit = 0xff;
-
- for (byte = 0; byte != 32; byte++)
- bit &= charset->block[u][byte];
-
- if (bit == 0xff) {
- /* Block is full */
- charset->index[u] = BLOCK_FULL;
-
- for (byte = 0; byte != 32; byte++)
- charset->block[u][byte] = 0;
- }
- }
-
- /* shrink-wrap */
- charset->size = offsetof(struct rufl_character_set, block) +
- 32 * last_used;
- charset2 = realloc(charset, charset->size);
- if (!charset2) {
- free(charset);
- return rufl_OUT_OF_MEMORY;
- }
-
- rufl_font_list[font_index].charset = charset;
-
- return rufl_OK;
-}
-
-/**
- * Scan a font for available characters (version without character enumeration)
- */
-
-rufl_code rufl_init_scan_font_no_enumerate(unsigned int font_index)
-{
- char font_name[80];
- int x_out, y_out;
- unsigned int byte, bit;
- unsigned int block_count = 0;
- unsigned int last_used = 0;
- unsigned int string[2] = { 0, 0 };
- unsigned int u;
- struct rufl_character_set *charset;
- struct rufl_character_set *charset2;
- font_f font;
- font_scan_block block = { { 0, 0 }, { 0, 0 }, -1, { 0, 0, 0, 0 } };
-
- /*LOG("font %u \"%s\"", font_index,
- rufl_font_list[font_index].identifier);*/
-
- charset = calloc(1, sizeof *charset);
- if (!charset)
- return rufl_OUT_OF_MEMORY;
-
- snprintf(font_name, sizeof font_name, "%s\\EUTF8",
- rufl_font_list[font_index].identifier);
-
- rufl_fm_error = xfont_find_font(font_name, 160, 160, 0, 0, &font, 0, 0);
- if (rufl_fm_error) {
- LOG("xfont_find_font(\"%s\"): 0x%x: %s", font_name,
- rufl_fm_error->errnum, rufl_fm_error->errmess);
- free(charset);
- return rufl_OK;
- }
-
- /* scan through all characters */
- for (u = 0x0020; u != 0x10000; u++) {
- if (u == 0x007f) {
- /* skip DELETE and C1 controls */
- u = 0x009f;
- continue;
- }
-
- if (u % 0x200 == 0)
- rufl_init_status(0, 0);
-
- string[0] = u;
- rufl_fm_error = xfont_scan_string(font, (char *) string,
- font_RETURN_BBOX | font_GIVEN32_BIT |
- font_GIVEN_FONT | font_GIVEN_LENGTH |
- font_GIVEN_BLOCK,
- 0x7fffffff, 0x7fffffff,
- &block, 0, 4,
- 0, &x_out, &y_out, 0);
- if (rufl_fm_error)
- break;
-
- if (block.bbox.x0 == 0x20000000) {
- /* absent (no definition) */
- } else if (x_out == 0 && y_out == 0 &&
- block.bbox.x0 == 0 && block.bbox.y0 == 0 &&
- block.bbox.x1 == 0 && block.bbox.y1 == 0) {
- /* absent (empty) */
- } else if (block.bbox.x0 == 0 && block.bbox.y0 == 0 &&
- block.bbox.x1 == 0 && block.bbox.y1 == 0 &&
- !rufl_is_space(u)) {
- /* absent (space but not a space character - some
- * fonts do this) */
- } else {
- /* present */
- byte = (u >> 3) & 31;
- bit = u & 7;
- charset->block[last_used][byte] |= 1 << bit;
-
- block_count++;
- }
-
- if ((u + 1) % 256 == 0) {
- /* end of block */
- if (block_count == 0)
- charset->index[u >> 8] = BLOCK_EMPTY;
- else if (block_count == 256) {
- charset->index[u >> 8] = BLOCK_FULL;
- for (byte = 0; byte != 32; byte++)
- charset->block[last_used][byte] = 0;
- } else {
- charset->index[u >> 8] = last_used;
- last_used++;
- if (last_used == 254)
- /* too many characters */
- break;
- }
- block_count = 0;
- }
- }
-
- xfont_lose_font(font);
-
- if (rufl_fm_error) {
- free(charset);
- LOG("xfont_scan_string: 0x%x: %s",
- rufl_fm_error->errnum, rufl_fm_error->errmess);
- return rufl_FONT_MANAGER_ERROR;
- }
-
- /* shrink-wrap */
- charset->size = offsetof(struct rufl_character_set, block) +
- 32 * last_used;
- charset2 = realloc(charset, charset->size);
- if (!charset2) {
- free(charset);
- return rufl_OUT_OF_MEMORY;
- }
-
- rufl_font_list[font_index].charset = charset;
-
- return rufl_OK;
-}
-
-/**
- * A character is one of the Unicode space characters.
- */
-
-bool rufl_is_space(unsigned int u)
-{
- return u == 0x0020 || u == 0x00a0 ||
- (0x2000 <= u && u <= 0x200b) ||
- u == 0x202f || u == 0x3000;
-}
-
-
-/**
- * Scan a font for available characters (old font manager version).
- */
-
-rufl_code rufl_init_scan_font_old(unsigned int font_index)
-{
- const char *font_name = rufl_font_list[font_index].identifier;
- struct rufl_character_set *charset;
- struct rufl_character_set *charset2;
- struct rufl_unicode_map *umap = NULL;
- unsigned int num_umaps = 0;
- unsigned int i;
- unsigned int last_used = 0;
- rufl_code code;
- font_list_context context = 0;
- char encoding[80];
-
- /*LOG("font %u \"%s\"", font_index, font_name);*/
-
- charset = calloc(1, sizeof *charset);
- if (!charset)
- return rufl_OUT_OF_MEMORY;
- for (i = 0; i != 256; i++)
- charset->index[i] = BLOCK_EMPTY;
-
- /* Firstly, search through available encodings (Symbol fonts fail) */
- while (context != -1) {
- struct rufl_unicode_map *temp;
-
- rufl_fm_error = xfont_list_fonts((byte *) encoding,
- font_RETURN_FONT_NAME |
- 0x400000 /* Return encoding name, instead */ |
- context,
- sizeof(encoding), NULL, 0, NULL,
- &context, NULL, NULL);
- if (rufl_fm_error) {
- LOG("xfont_list_fonts: 0x%x: %s",
- rufl_fm_error->errnum,
- rufl_fm_error->errmess);
- free(charset);
- for (i = 0; i < num_umaps; i++)
- free((umap + i)->encoding);
- free(umap);
- return rufl_FONT_MANAGER_ERROR;
- }
- if (context == -1)
- break;
-
- temp = realloc(umap, (num_umaps + 1) * sizeof *umap);
- if (!temp) {
- free(charset);
- for (i = 0; i < num_umaps; i++)
- free((umap + i)->encoding);
- free(umap);
- return rufl_OUT_OF_MEMORY;
- }
-
- memset(temp + num_umaps, 0, sizeof *umap);
-
- umap = temp;
- num_umaps++;
-
- 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)) {
- 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--;
- } else {
- /* If this mapping is identical to an existing one,
- * then we can discard it */
- for (i = 0; i != num_umaps - 1; i++) {
- const struct rufl_unicode_map *a = (umap + i);
- const struct rufl_unicode_map *b =
- (umap + num_umaps - 1);
-
- if (a->entries == b->entries &&
- memcmp(a->map, b->map,
- sizeof a->map) == 0) {
- /* Found identical map; discard */
- num_umaps--;
- break;
- }
- }
- }
- }
-
- if (num_umaps == 0) {
- /* This is a symbol font and can only be used
- * without an encoding */
- struct rufl_unicode_map *temp;
-
- temp = realloc(umap, (num_umaps + 1) * sizeof *umap);
- if (!temp) {
- free(charset);
- free(umap);
- return rufl_OUT_OF_MEMORY;
- }
-
- memset(temp + num_umaps, 0, sizeof *umap);
-
- umap = temp;
- num_umaps++;
-
- 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)) {
- free(charset);
- for (i = 0; i < num_umaps; i++)
- free((umap + i)->encoding);
- free(umap);
- return code;
- }
-
- num_umaps--;
- }
- }
-
- /* shrink-wrap */
- charset->size = offsetof(struct rufl_character_set, block) +
- 32 * last_used;
- charset2 = realloc(charset, charset->size);
- if (!charset2) {
- for (i = 0; i < num_umaps; i++)
- free((umap + i)->encoding);
- free(umap);
- free(charset);
- return rufl_OUT_OF_MEMORY;
- }
-
- rufl_font_list[font_index].charset = charset;
- rufl_font_list[font_index].umap = umap;
- rufl_font_list[font_index].num_umaps = num_umaps;
-
- return rufl_OK;
-}
-
-/**
- * Helper function for rufl_init_scan_font_old.
- * Scans the given font using the given font encoding (or none, if NULL)
- */
-
-rufl_code rufl_init_scan_font_in_encoding(const char *font_name,
- const char *encoding, struct rufl_character_set *charset,
- struct rufl_unicode_map *umap, unsigned int *last)
-{
- char string[2] = { 0, 0 };
- int x_out, y_out;
- unsigned int byte, bit;
- unsigned int i;
- unsigned int last_used = *last;
- unsigned int u;
- rufl_code code;
- font_f font;
- font_scan_block block = { { 0, 0 }, { 0, 0 }, -1, { 0, 0, 0, 0 } };
- char buf[80];
-
- if (encoding)
- snprintf(buf, sizeof buf, "%s\\E%s", font_name, encoding);
- else
- snprintf(buf, sizeof buf, "%s", 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);
- return rufl_FONT_MANAGER_ERROR;
- }
-
- code = rufl_init_read_encoding(font, umap);
- if (code != rufl_OK) {
- xfont_lose_font(font);
- return code;
- }
-
- for (i = 0; i != umap->entries; i++) {
- u = umap->map[i].u;
- string[0] = umap->map[i].c;
- rufl_fm_error = xfont_scan_string(font, (char *) string,
- font_RETURN_BBOX | font_GIVEN_FONT |
- font_GIVEN_LENGTH | font_GIVEN_BLOCK,
- 0x7fffffff, 0x7fffffff,
- &block, 0, 1,
- 0, &x_out, &y_out, 0);
- if (rufl_fm_error)
- break;
-
- if (block.bbox.x0 == 0x20000000) {
- /* absent (no definition) */
- } else if (x_out == 0 && y_out == 0 &&
- block.bbox.x0 == 0 && block.bbox.y0 == 0 &&
- block.bbox.x1 == 0 && block.bbox.y1 == 0) {
- /* absent (empty) */
- } else if (block.bbox.x0 == 0 && block.bbox.y0 == 0 &&
- block.bbox.x1 == 0 && block.bbox.y1 == 0 &&
- !rufl_is_space(u)) {
- /* absent (space but not a space character - some
- * fonts do this) */
- } else {
- /* present */
- if (charset->index[u >> 8] == BLOCK_EMPTY) {
- charset->index[u >> 8] = last_used;
- last_used++;
- if (last_used == 254)
- /* too many characters */
- break;
- }
-
- byte = (u >> 3) & 31;
- bit = u & 7;
- charset->block[charset->index[u >> 8]][byte] |=
- 1 << bit;
- }
- }
-
- xfont_lose_font(font);
-
- if (rufl_fm_error) {
- LOG("xfont_scan_string: 0x%x: %s",
- rufl_fm_error->errnum, rufl_fm_error->errmess);
- return rufl_FONT_MANAGER_ERROR;
- }
-
- if (encoding) {
- umap->encoding = strdup(encoding);
- if (!umap->encoding)
- return rufl_OUT_OF_MEMORY;
- }
-
- *last = last_used;
-
- return rufl_OK;
-}
-
-
-/**
- * Parse an encoding file and fill in a rufl_unicode_map.
- */
-
-rufl_code rufl_init_read_encoding(font_f font,
- struct rufl_unicode_map *umap)
-{
- unsigned int u = 0;
- unsigned int i = 0;
- int c;
- int n;
- char filename[200];
- char s[200];
- struct rufl_glyph_map_entry *entry;
- FILE *fp;
-
- rufl_fm_error = xfont_read_encoding_filename(font, filename,
- sizeof filename, 0);
- if (rufl_fm_error) {
- LOG("xfont_read_encoding_filename: 0x%x: %s",
- rufl_fm_error->errnum, rufl_fm_error->errmess);
- return rufl_FONT_MANAGER_ERROR;
- }
-
- fp = fopen(filename, "r");
- if (!fp)
- /* many "symbol" fonts have no encoding file: assume Latin 1 */
- fp = fopen("Resources:$.Fonts.Encodings.Latin1", "r");
- if (!fp)
- return rufl_IO_ERROR;
-
- while (!feof(fp) && u != 256) {
- c = fgetc(fp);
- if (c == '%') {
- /* comment line */
- fgets(s, sizeof s, fp);
- } else if (c == '/') {
- /* character definition */
- if (i++ < 32)
- continue;
- n = fscanf(fp, "%100s", s);
- if (n != 1)
- break;
- entry = bsearch(s, rufl_glyph_map,
- rufl_glyph_map_size,
- sizeof rufl_glyph_map[0],
- rufl_glyph_map_cmp);
- if (entry) {
- /* may be more than one unicode for the glyph
- * sentinels stop overshooting array */
- while (strcmp(s, (entry - 1)->glyph_name) == 0)
- entry--;
- for (; strcmp(s, entry->glyph_name) == 0;
- entry++) {
- umap->map[u].u = entry->u;
- umap->map[u].c = i - 1;
- u++;
- if (u == 256)
- break;
- }
- }
- }
- }
-
- if (fclose(fp) == EOF)
- return rufl_IO_ERROR;
-
- /* sort by unicode */
- qsort(umap->map, u, sizeof umap->map[0], rufl_unicode_map_cmp);
- umap->entries = u;
-
- return rufl_OK;
-}
-
-
-int rufl_glyph_map_cmp(const void *keyval, const void *datum)
-{
- const char *key = keyval;
- const struct rufl_glyph_map_entry *entry = datum;
- return strcmp(key, entry->glyph_name);
-}
-
-
-int rufl_unicode_map_cmp(const void *z1, const void *z2)
-{
- const struct rufl_unicode_map_entry *entry1 = z1;
- const struct rufl_unicode_map_entry *entry2 = z2;
- if (entry1->u < entry2->u)
- return -1;
- else if (entry2->u < entry1->u)
- return 1;
- return 0;
-}
-
-
-/**
- * Construct the font substitution table.
- */
-
-rufl_code rufl_init_substitution_table(void)
-{
- unsigned char z;
- unsigned int i;
- unsigned int block, byte, bit;
- unsigned int u;
- unsigned int index;
- const struct rufl_character_set *charset;
-
- rufl_substitution_table = malloc(65536 *
- sizeof rufl_substitution_table[0]);
- if (!rufl_substitution_table) {
- LOG("malloc(%zu) failed", 65536 *
- sizeof rufl_substitution_table[0]);
- return rufl_OUT_OF_MEMORY;
- }
-
- for (u = 0; u != 0x10000; u++)
- rufl_substitution_table[u] = NOT_AVAILABLE;
-
- for (i = 0; i != rufl_font_list_entries; i++) {
- charset = rufl_font_list[i].charset;
- if (!charset)
- continue;
- for (block = 0; block != 256; block++) {
- if (charset->index[block] == BLOCK_EMPTY)
- continue;
- if (charset->index[block] == BLOCK_FULL) {
- for (u = block << 8; u != (block << 8) + 256;
- u++) {
- if (rufl_substitution_table[u] ==
- NOT_AVAILABLE)
- rufl_substitution_table[u] = i;
- }
- continue;
- }
- index = charset->index[block];
- for (byte = 0; byte != 32; byte++) {
- z = charset->block[index][byte];
- if (z == 0)
- continue;
- u = (block << 8) | (byte << 3);
- for (bit = 0; bit != 8; bit++, u++) {
- if (rufl_substitution_table[u] ==
- NOT_AVAILABLE &&
- z & (1 << bit))
- rufl_substitution_table[u] = i;
- }
- }
- }
- }
-
- return rufl_OK;
-}
-
-
-/**
- * Save character sets to cache.
- */
-
-rufl_code rufl_save_cache(void)
-{
- unsigned int i;
- const unsigned int version = rufl_CACHE_VERSION;
- size_t len;
- FILE *fp;
-
- fp = fopen(rufl_CACHE, "wb");
- if (!fp) {
- LOG("fopen: 0x%x: %s", errno, strerror(errno));
- return rufl_OK;
- }
-
- /* cache format version */
- if (fwrite(&version, sizeof version, 1, fp) != 1) {
- LOG("fwrite: 0x%x: %s", errno, strerror(errno));
- fclose(fp);
- return rufl_OK;
- }
-
- /* font manager type flag */
- if (fwrite(&rufl_old_font_manager, sizeof rufl_old_font_manager, 1,
- fp) != 1) {
- LOG("fwrite: 0x%x: %s", errno, strerror(errno));
- fclose(fp);
- return rufl_OK;
- }
-
- for (i = 0; i != rufl_font_list_entries; i++) {
- if (!rufl_font_list[i].charset)
- continue;
-
- /* length of font identifier */
- len = strlen(rufl_font_list[i].identifier);
- if (fwrite(&len, sizeof len, 1, fp) != 1) {
- LOG("fwrite: 0x%x: %s", errno, strerror(errno));
- fclose(fp);
- return rufl_OK;
- }
-
- /* font identifier */
- if (fwrite(rufl_font_list[i].identifier, len, 1, fp) != 1) {
- LOG("fwrite: 0x%x: %s", errno, strerror(errno));
- fclose(fp);
- return rufl_OK;
- }
-
- /* character set */
- if (fwrite(rufl_font_list[i].charset,
- rufl_font_list[i].charset->size, 1, fp) != 1) {
- LOG("fwrite: 0x%x: %s", errno, strerror(errno));
- fclose(fp);
- return rufl_OK;
- }
-
- /* unicode map */
- if (rufl_old_font_manager) {
- unsigned int j;
-
- if (fwrite(&rufl_font_list[i].num_umaps,
- sizeof rufl_font_list[i].num_umaps, 1,
- fp) != 1) {
- LOG("fwrite: 0x%x: %s", errno, strerror(errno));
- fclose(fp);
- return rufl_OK;
- }
-
- for (j = 0; j < rufl_font_list[i].num_umaps; j++) {
- const struct rufl_unicode_map *umap =
- rufl_font_list[i].umap + j;
-
- len = umap->encoding ?
- strlen(umap->encoding) : 0;
-
- if (fwrite(&len, sizeof len, 1, fp) != 1) {
- LOG("fwrite: 0x%x: %s",
- errno, strerror(errno));
- fclose(fp);
- return rufl_OK;
- }
-
- if (umap->encoding) {
- if (fwrite(umap->encoding, len, 1,
- fp) != 1) {
- LOG("fwrite: 0x%x: %s",
- errno, strerror(errno));
- fclose(fp);
- return rufl_OK;
- }
- }
-
- if (fwrite(&umap->entries, sizeof umap->entries,
- 1, fp) != 1) {
- LOG("fwrite: 0x%x: %s",
- errno, strerror(errno));
- fclose(fp);
- return rufl_OK;
- }
-
- if (fwrite(umap->map, umap->entries *
- sizeof(struct rufl_unicode_map_entry),
- 1, fp) != 1) {
- LOG("fwrite: 0x%x: %s",
- errno, strerror(errno));
- fclose(fp);
- return rufl_OK;
- }
- }
- }
- }
-
- if (fclose(fp) == EOF) {
- LOG("fclose: 0x%x: %s", errno, strerror(errno));
- return rufl_OK;
- }
-
- LOG("%u charsets saved", i);
-
- return rufl_OK;
-}
-
-
-/**
- * Load character sets from cache.
- */
-
-rufl_code rufl_load_cache(void)
-{
- unsigned int version;
- unsigned int i = 0;
- bool old_font_manager;
- char *identifier;
- size_t len, size;
- FILE *fp;
- struct rufl_font_list_entry *entry;
- struct rufl_character_set *charset;
- struct rufl_unicode_map *umap = NULL;
- unsigned int num_umaps = 0;
-
- fp = fopen(rufl_CACHE, "rb");
- if (!fp) {
- LOG("fopen: 0x%x: %s", errno, strerror(errno));
- return rufl_OK;
- }
-
- /* cache format version */
- if (fread(&version, sizeof version, 1, fp) != 1) {
- if (feof(fp))
- LOG("fread: %s", "unexpected eof");
- else
- LOG("fread: 0x%x: %s", errno, strerror(errno));
- fclose(fp);
- return rufl_OK;
- }
- if (version != rufl_CACHE_VERSION) {
- /* incompatible cache format */
- LOG("cache version %u (now %u)", version, rufl_CACHE_VERSION);
- fclose(fp);
- return rufl_OK;
- }
-
- /* font manager type flag */
- if (fread(&old_font_manager, sizeof old_font_manager, 1, fp) != 1) {
- if (feof(fp))
- LOG("fread: %s", "unexpected eof");
- else
- LOG("fread: 0x%x: %s", errno, strerror(errno));
- fclose(fp);
- return rufl_OK;
- }
- if (old_font_manager != rufl_old_font_manager) {
- /* font manager type has changed */
- LOG("font manager %u (now %u)", old_font_manager,
- rufl_old_font_manager);
- fclose(fp);
- return rufl_OK;
- }
-
- while (!feof(fp)) {
- /* length of font identifier */
- if (fread(&len, sizeof len, 1, fp) != 1) {
- /* eof at this point simply means that the whole cache
- * file has been loaded */
- if (!feof(fp))
- LOG("fread: 0x%x: %s", errno, strerror(errno));
- break;
- }
-
- identifier = malloc(len + 1);
- if (!identifier) {
- LOG("malloc(%zu) failed", len + 1);
- fclose(fp);
- return rufl_OUT_OF_MEMORY;
- }
-
- /* font identifier */
- if (fread(identifier, len, 1, fp) != 1) {
- if (feof(fp))
- LOG("fread: %s", "unexpected eof");
- else
- LOG("fread: 0x%x: %s", errno, strerror(errno));
- free(identifier);
- break;
- }
- identifier[len] = 0;
-
- /* character set */
- if (fread(&size, sizeof size, 1, fp) != 1) {
- if (feof(fp))
- LOG("fread: %s", "unexpected eof");
- else
- LOG("fread: 0x%x: %s", errno, strerror(errno));
- free(identifier);
- break;
- }
-
- charset = malloc(size);
- if (!charset) {
- LOG("malloc(%zu) failed", size);
- free(identifier);
- fclose(fp);
- return rufl_OUT_OF_MEMORY;
- }
-
- charset->size = size;
- if (fread(charset->index, size - sizeof size, 1, fp) != 1) {
- if (feof(fp))
- LOG("fread: %s", "unexpected eof");
- else
- LOG("fread: 0x%x: %s", errno, strerror(errno));
- free(charset);
- free(identifier);
- break;
- }
-
- /* unicode map */
- if (rufl_old_font_manager) {
- rufl_code code = rufl_OK;
- unsigned int entry;
-
- /* Number of maps */
- if (fread(&num_umaps, sizeof num_umaps, 1, fp) != 1) {
- if (feof(fp))
- LOG("fread: %s", "unexpected eof");
- else
- LOG("fread: 0x%x: %s", errno,
- strerror(errno));
- free(charset);
- free(identifier);
- break;
- }
-
- umap = calloc(num_umaps, sizeof *umap);
- if (!umap) {
- LOG("malloc(%zu) failed", sizeof *umap);
- free(charset);
- free(identifier);
- fclose(fp);
- return rufl_OUT_OF_MEMORY;
- }
-
- /* Load them */
- for (entry = 0; entry < num_umaps; entry++) {
- struct rufl_unicode_map *map = umap + entry;
-
- if (fread(&len, sizeof(len), 1, fp) != 1) {
- if (feof(fp))
- LOG("fread: %s",
- "unexpected eof");
- else
- LOG("fread: 0x%x: %s", errno,
- strerror(errno));
- break;
- }
-
- if (len > 0) {
- map->encoding = malloc(len + 1);
- if (!map->encoding) {
- LOG("malloc(%zu) failed",
- len + 1);
- code = rufl_OUT_OF_MEMORY;
- break;
- }
-
- if (fread(map->encoding, len, 1,
- fp) != 1) {
- if (feof(fp))
- LOG("fread: %s",
- "unexpected eof");
- else
- LOG("fread: 0x%x: %s",
- errno,
- strerror(errno));
- break;
- }
- map->encoding[len] = 0;
- }
-
- if (fread(&map->entries, sizeof(map->entries),
- 1, fp) != 1) {
- if (feof(fp))
- LOG("fread: %s",
- "unexpected eof");
- else
- LOG("fread: 0x%x: %s", errno,
- strerror(errno));
- break;
- }
-
- if (fread(map->map, map->entries *
- sizeof(struct rufl_unicode_map_entry),
- 1, fp) != 1) {
- if (feof(fp))
- LOG("fread: %s",
- "unexpected eof");
- else
- LOG("fread: 0x%x: %s", errno,
- strerror(errno));
- break;
- }
- }
-
- /* Clean up if loading failed */
- if (entry != num_umaps) {
- for (num_umaps = 0; num_umaps <= entry;
- num_umaps++) {
- struct rufl_unicode_map *map =
- umap + num_umaps;
-
- free(map->encoding);
- }
- free(umap);
- free(charset);
- free(identifier);
-
- if (code != rufl_OK)
- return code;
-
- break;
- }
- }
-
- /* put in rufl_font_list */
- entry = lfind(identifier, rufl_font_list,
- &rufl_font_list_entries,
- sizeof rufl_font_list[0], rufl_font_list_cmp);
- if (entry) {
- entry->charset = charset;
- entry->umap = umap;
- entry->num_umaps = num_umaps;
- i++;
- } else {
- LOG("\"%s\" not in font list", identifier);
- while (num_umaps > 0) {
- struct rufl_unicode_map *map =
- umap + num_umaps - 1;
-
- free(map->encoding);
-
- num_umaps--;
- }
- free(umap);
- free(charset);
- }
-
- free(identifier);
- }
- fclose(fp);
-
- LOG("%u charsets loaded", i);
-
- return rufl_OK;
-}
-
-
-int rufl_font_list_cmp(const void *keyval, const void *datum)
-{
- const char *key = keyval;
- const struct rufl_font_list_entry *entry = datum;
- return strcasecmp(key, entry->identifier);
-}
-
-
-/**
- * Create a menu of font families.
- */
-
-rufl_code rufl_init_family_menu(void)
-{
- wimp_menu *menu;
- unsigned int i;
-
- menu = malloc(wimp_SIZEOF_MENU(rufl_family_list_entries));
- if (!menu)
- return rufl_OUT_OF_MEMORY;
- menu->title_data.indirected_text.text = (char *) "Fonts";
- menu->title_fg = wimp_COLOUR_BLACK;
- menu->title_bg = wimp_COLOUR_LIGHT_GREY;
- menu->work_fg = wimp_COLOUR_BLACK;
- menu->work_bg = wimp_COLOUR_WHITE;
- menu->width = 200;
- menu->height = wimp_MENU_ITEM_HEIGHT;
- menu->gap = wimp_MENU_ITEM_GAP;
- for (i = 0; i != rufl_family_list_entries; i++) {
- menu->entries[i].menu_flags = 0;
- menu->entries[i].sub_menu = wimp_NO_SUB_MENU;
- menu->entries[i].icon_flags = wimp_ICON_TEXT |
- wimp_ICON_INDIRECTED |
- (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) |
- (wimp_COLOUR_WHITE << wimp_ICON_BG_COLOUR_SHIFT);
- menu->entries[i].data.indirected_text.text =
- (char *) rufl_family_list[i];
- menu->entries[i].data.indirected_text.validation = (char *) -1;
- menu->entries[i].data.indirected_text.size =
- strlen(rufl_family_list[i]);
- }
- menu->entries[0].menu_flags = wimp_MENU_TITLE_INDIRECTED;
- menu->entries[i - 1].menu_flags |= wimp_MENU_LAST;
-
- rufl_family_menu = menu;
-
- return rufl_OK;
-}
-
-
-/**
- * Create and open the init status window.
- */
-
-void rufl_init_status_open(void)
-{
- int xeig_factor, yeig_factor, xwind_limit, ywind_limit, width, height;
- wimp_t task;
- osbool window_task;
- wimp_WINDOW(4) window = { { 0, 0, 0, 0 }, 0, 0, wimp_TOP,
- wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_NEW_FORMAT,
- wimp_COLOUR_BLACK, wimp_COLOUR_LIGHT_GREY,
- wimp_COLOUR_BLACK, wimp_COLOUR_VERY_LIGHT_GREY,
- wimp_COLOUR_DARK_GREY, wimp_COLOUR_LIGHT_GREY,
- wimp_COLOUR_CREAM, 0,
- { 0, -128, 800, 0 }, 0, 0, 0, 0, 0, { "" }, 4,
- { { { 12, -56, 788, -12 }, wimp_ICON_TEXT |
- wimp_ICON_HCENTRED | wimp_ICON_VCENTRED |
- wimp_ICON_INDIRECTED |
- wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT |
- wimp_COLOUR_VERY_LIGHT_GREY <<wimp_ICON_BG_COLOUR_SHIFT,
- { "" } },
- { { 12, -116, 788, -64 }, wimp_ICON_TEXT |
- wimp_ICON_FILLED | wimp_ICON_BORDER |
- wimp_ICON_INDIRECTED |
- wimp_COLOUR_VERY_LIGHT_GREY <<wimp_ICON_BG_COLOUR_SHIFT,
- { "" } },
- { { 16, -112, 16, -68 }, wimp_ICON_FILLED |
- wimp_COLOUR_ORANGE << wimp_ICON_BG_COLOUR_SHIFT,
- { "" } },
- { { 16, -112, 784, -68 }, wimp_ICON_TEXT |
- wimp_ICON_HCENTRED | wimp_ICON_VCENTRED |
- wimp_ICON_INDIRECTED |
- wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT |
- wimp_COLOUR_MID_LIGHT_GREY << wimp_ICON_BG_COLOUR_SHIFT,
- { "" } } },
- };
- wimp_window_state state;
- os_error *error;
-
- window.icons[0].data.indirected_text.text =
- (char *) "Scanning fonts - please wait";
- window.icons[0].data.indirected_text.validation = (char *) "";
- window.icons[1].data.indirected_text.text = (char *) "";
- window.icons[1].data.indirected_text.validation = (char *) "r2";
- window.icons[3].data.indirected_text.text = rufl_status_buffer;
- window.icons[3].data.indirected_text.validation = (char *) "";
-
- xos_read_mode_variable(os_CURRENT_MODE, os_MODEVAR_XEIG_FACTOR,
- &xeig_factor, 0);
- xos_read_mode_variable(os_CURRENT_MODE, os_MODEVAR_YEIG_FACTOR,
- &yeig_factor, 0);
- xos_read_mode_variable(os_CURRENT_MODE, os_MODEVAR_XWIND_LIMIT,
- &xwind_limit, 0);
- xos_read_mode_variable(os_CURRENT_MODE, os_MODEVAR_YWIND_LIMIT,
- &ywind_limit, 0);
- width = (xwind_limit + 1) << xeig_factor;
- height = (ywind_limit + 1) << yeig_factor;
-
- window.visible.x0 = width / 2 - 400;
- window.visible.y0 = height / 2 - 64;
- window.visible.x1 = window.visible.x0 + 800;
- window.visible.y1 = window.visible.y0 + 128;
-
- error = xwimpreadsysinfo_task(&task, 0);
- if (error) {
- LOG("xwimpreadsysinfo_task: 0x%x: %s",
- error->errnum, error->errmess);
- return;
- }
- if (!task)
- return; /* not a Wimp task */
-
- error = xtaskwindowtaskinfo_window_task(&window_task);
- if (error) {
- LOG("xtaskwindowtaskinfo_window_task: 0x%x: %s",
- error->errnum, error->errmess);
- return;
- }
- if (window_task)
- return; /* in a TaskWindow */
-
- xwimp_create_window((const wimp_window *) &window, &rufl_status_w);
- state.w = rufl_status_w;
- xwimp_get_window_state(&state);
- xwimp_open_window((wimp_open *) (void *) &state);
-}
-
-
-/**
- * Update the status window and multitask.
- */
-
-void rufl_init_status(const char *status, float progress)
-{
- wimp_block block;
- static os_t last_t = 0;
- os_t t;
-
- if (!rufl_status_w)
- return;
-
- if (status) {
- strncpy(rufl_status_buffer, status, sizeof rufl_status_buffer);
- rufl_status_buffer[sizeof rufl_status_buffer - 1] = 0;
- xwimp_set_icon_state(rufl_status_w, 3, 0, 0);
- }
- if (progress)
- xwimp_resize_icon(rufl_status_w, 2, 16, -112,
- 16 + 768 * progress, -68);
- xos_read_monotonic_time(&t);
- if (last_t == t)
- return;
- xwimp_poll(wimp_QUEUE_REDRAW | wimp_MASK_LEAVING | wimp_MASK_ENTERING |
- wimp_MASK_LOSE | wimp_MASK_GAIN | wimp_MASK_MESSAGE |
- wimp_MASK_RECORDED | wimp_MASK_ACKNOWLEDGE,
- &block, 0, 0);
- last_t = t;
-}
-
-
-/**
- * Close and delete the status window.
- */
-
-void rufl_init_status_close(void)
-{
- if (!rufl_status_w)
- return;
-
- xwimp_delete_window(rufl_status_w);
- rufl_status_w = 0;
-}