summaryrefslogtreecommitdiff
path: root/frontends
diff options
context:
space:
mode:
Diffstat (limited to 'frontends')
-rw-r--r--frontends/framebuffer/Makefile28
-rw-r--r--frontends/framebuffer/convert_font.c1215
-rw-r--r--frontends/framebuffer/convert_image.c304
3 files changed, 3 insertions, 1544 deletions
diff --git a/frontends/framebuffer/Makefile b/frontends/framebuffer/Makefile
index f4a7494e2..7408f0cbc 100644
--- a/frontends/framebuffer/Makefile
+++ b/frontends/framebuffer/Makefile
@@ -122,27 +122,10 @@ FB_IMAGE_throbber6 := throbber/throbber6.png
FB_IMAGE_throbber7 := throbber/throbber7.png
FB_IMAGE_throbber8 := throbber/throbber8.png
-# local compiler flags
-ifeq ($(HOST),OpenBSD)
- BUILD_CFLAGS += $(shell $(PKG_CONFIG) --cflags libpng)
- BUILD_LDFLAGS += $(shell $(PKG_CONFIG) --libs libpng)
-else
- ifeq ($(HOST),FreeBSD)
- BUILD_CFLAGS += $(shell $(PKG_CONFIG) --cflags libpng)
- BUILD_LDFLAGS += $(shell $(PKG_CONFIG) --libs libpng)
- else
- BUILD_CFLAGS +=
- BUILD_LDFLAGS += -lpng
- endif
-endif
-
-# Host tool to convert image bitmaps to source code.
-#
-# convert_image dependd on fb_bitmap.h so that if we change that
+# make convert_image depend on fbtk.h so that if we change that
# header, we get new images built.
-$(TOOLROOT)/convert_image: $(TOOLROOT)/created $(FRONTEND_SOURCE_DIR)/convert_image.c $(FRONTEND_SOURCE_DIR)/fbtk.h
- $(VQ)echo "BUILD CC: $@"
- $(Q)$(BUILD_CC) $(BUILD_CFLAGS) -o $@ $(FRONTEND_SOURCE_DIR)/convert_image.c $(BUILD_LDFLAGS)
+$(TOOLROOT)/convert_image: $(FRONTEND_SOURCE_DIR)/fbtk.h
+
# 1: input file
# 2: output file
@@ -164,11 +147,6 @@ $(eval $(foreach V,$(filter FB_IMAGE_%,$(.VARIABLES)),$(call convert_image,$(FRO
# Internal fonts to generate
FB_FONT_internal_ns-sans := fonts/glyph_data
-# Internal font conversion
-$(TOOLROOT)/convert_font: $(TOOLROOT)/created $(FRONTEND_SOURCE_DIR)/convert_font.c
- $(VQ)echo "BUILD CC: $@"
- $(Q)$(BUILD_CC) -o $@ $(FRONTEND_SOURCE_DIR)/convert_font.c
-
# 1: input file
# 2: output source code file
# 3: output header file
diff --git a/frontends/framebuffer/convert_font.c b/frontends/framebuffer/convert_font.c
deleted file mode 100644
index 010af857a..000000000
--- a/frontends/framebuffer/convert_font.c
+++ /dev/null
@@ -1,1215 +0,0 @@
-/*
- * Copyright 2014 Michael Drake <tlsa@netsurf-browser.org>
- * Copyright 2014 Vincent Sanders <vince@netsurf-browser.org>
- *
- * This file is part of the convert_font tool used to convert font
- * glyph data into a compilable representation.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <unistd.h>
-#include <getopt.h>
-
-#define GLYPH_LEN 16
-#define BUCKETS 512
-#define CHUNK_SIZE (64 * 1024)
-#define HEADER_MAX 2000
-
-#define SECTION_SIZE (sizeof(uint16_t) * 256)
-
-const char *labels[4] = {
- " Regular",
- " Italic",
- " Bold",
- "Bold & Italic"
-};
-
-const char *var_lables[4] = {
- "fb_regular",
- "fb_italic",
- "fb_bold",
- "fb_bold_italic"
-};
-
-const char *short_labels[4] = {
- " ",
- " i",
- "b ",
- "bi"
-};
-
-enum font_style {
- REGULAR = 0,
- ITALIC = (1 << 0),
- BOLD = (1 << 1),
- ITALIC_BOLD = (1 << 2)
-};
-
-enum log_level {
- LOG_DEBUG,
- LOG_INFO,
- LOG_RESULT,
- LOG_WARNING,
- LOG_ERROR
-};
-
-enum log_level level;
-
-typedef struct glyph_entry {
- union {
- uint32_t u32[GLYPH_LEN / 4];
- uint8_t u8[GLYPH_LEN];
- } data;
- uint32_t index;
- struct glyph_entry *next;
-} glyph_entry;
-
-/** Scratch glyph for generated code points */
-uint8_t code_point[GLYPH_LEN];
-
-/** Hash table */
-glyph_entry *ht[BUCKETS];
-
-#define LOG(lev, fmt, ...) \
- if (lev >= level) \
- printf(fmt, ##__VA_ARGS__);
-
-/**
- * Get hash for glyph data
- * \param g Glyph data (GLYPH_LEN bytes)
- * \return glyph's hash
- */
-static inline uint32_t glyph_hash(const uint8_t *g)
-{
- uint32_t hash = 0x811c9dc5;
- unsigned int len = GLYPH_LEN;
-
- while (len > 0) {
- hash *= 0x01000193;
- hash ^= *g++;
- len--;
- }
-
- return hash;
-}
-
-
-/**
- * Check whether glyphs are identical (compares glyph data)
- *
- * \param g1 First glyph's data (GLYPH_LEN bytes)
- * \param g2 Second glyph's data (GLYPH_LEN bytes)
- * \return true iff both glyphs are identical, else false
- */
-static inline bool glyphs_match(const uint8_t *g1, const uint8_t *g2)
-{
- return (memcmp(g1, g2, GLYPH_LEN) == 0);
-}
-
-
-/**
- * Add a glyph to a hash chain (or free, and return pointer to existing glyph)
- *
- * Note that if new glyph already exists in chain, it is freed and a pointer to
- * the existing glyph is returned. If the glyph does not exist in the chain
- * it is added and its pointer is returned.
- *
- * \param head Head of hash chain
- * \param new New glyph to add (may be freed)
- * \return pointer to glyph in hash chain
- */
-static glyph_entry * glyph_add_to_chain(glyph_entry **head, glyph_entry *new)
-{
- glyph_entry *e = *head;
-
- if (*head == NULL) {
- new->next = NULL;
- *head = new;
- return new;
- }
-
- do {
- if (glyphs_match(new->data.u8, e->data.u8)) {
- free(new);
- return e;
- }
- if (e->next == NULL)
- break;
- e = e->next;
- } while (1);
-
- new->next = e->next;
- e->next = new;
- return new;
-}
-
-
-/**
- * Free a glyph entry chain
- *
- * \param head Head of hash chain
- */
-static void free_chain(glyph_entry *head)
-{
- glyph_entry *e = head;
-
- if (head == NULL)
- return;
-
- while (e != NULL) {
- head = e->next;
- free(e);
- e = head;
- };
-}
-
-
-/**
- * Add new glyph to hash table (or free, and return pointer to existing glyph)
- *
- * Note that if new glyph already exists in table, it is freed and a pointer to
- * the existing glyph is returned. If the glyph does not exist in the table
- * it is added and its pointer is returned.
- *
- * \param new New glyph to add (may be freed)
- * \return pointer to glyph in hash table
- */
-static glyph_entry * glyph_add_to_table(glyph_entry *new)
-{
- uint32_t hash = glyph_hash(new->data.u8);
-
- return glyph_add_to_chain(&ht[hash % BUCKETS], new);
-}
-
-
-/**
- * Free glyph table.
- */
-static void free_table(void)
-{
- int i;
-
- for (i = 0; i < BUCKETS; i++) {
- free_chain(ht[i]);
- }
-}
-
-struct parse_context {
- enum {
- START,
- IN_HEADER,
- BEFORE_ID,
- GLYPH_ID,
- BEFORE_GLYPH_DATA,
- IN_GLYPH_DATA
- } state; /**< Current parser state */
-
- union {
- struct {
- bool new_line;
- } in_header;
- struct {
- bool new_line;
- bool u;
- } before_id;
- struct {
- int c;
- } g_id;
- struct {
- bool new_line;
- bool prev_h;
- bool prev_s;
- int c;
- } before_gd;
- struct {
- int line;
- int pos;
- int styles;
- int line_styles;
- glyph_entry *e[4];
- } in_gd;
- } data; /**< The state specific data */
-
- int id; /**< Current ID */
-
- int codepoints; /**< Glyphs containing codepoints */
- int count[4]; /**< Count of glyphs in file */
-};
-
-struct font_data {
- char header[HEADER_MAX];
- int header_len;
-
- uint8_t section_table[4][256];
- uint8_t sec_count[4];
- uint16_t *sections[4];
-
- glyph_entry *e[0xffff];
- int glyphs;
-};
-
-bool generate_font_header(const char *path, struct font_data *data)
-{
- FILE *fp;
- int s;
-
- fp = fopen(path, "wb");
- if (fp == NULL) {
- LOG(LOG_ERROR, "Couldn't open header file \"%s\"\n", path);
- return false;
- }
-
- fprintf(fp, "/*\n");
- fwrite(data->header, 1, data->header_len, fp);
- fprintf(fp, " */\n\n");
- fprintf(fp, "/* Don't edit this file, it was generated from the "
- "plain text source data. */\n\n");
-
-
- for (s = 0; s < 4; s++) {
- fprintf(fp, "const uint8_t *%s_section_table;\n",
- var_lables[s]);
- fprintf(fp, "const uint16_t *%s_sections;\n",
- var_lables[s]);
-
- }
-
- fprintf(fp, "const uint8_t *font_glyph_data;\n");
-
- fprintf(fp, "\n\n");
-
- fclose(fp);
-
- return true;
-
-}
-
-bool generate_font_source(const char *path, struct font_data *data)
-{
- int s, i, y;
- int limit;
- FILE *fp;
-
- fp = fopen(path, "wb");
- if (fp == NULL) {
- LOG(LOG_ERROR, "Couldn't open output file \"%s\"\n", path);
- return false;
- }
-
- fprintf(fp, "/*\n");
- fwrite(data->header, 1, data->header_len, fp);
- fprintf(fp, " */\n\n");
- fprintf(fp, "/* Don't edit this file, it was generated from the "
- "plain text source data. */\n\n");
-
- fprintf(fp, "#include <stdint.h>\n");
- fprintf(fp, "\n");
-
- for (s = 0; s < 4; s++) {
-
- fprintf(fp, "static const uint8_t %s_section_table_c[256] = {\n",
- var_lables[s]);
-
- for (i = 0; i < 256; i++) {
- if (i == 255)
- fprintf(fp, "0x%.2X\n",
- data->section_table[s][i]);
- else if (i % 8 == 7)
- fprintf(fp, "0x%.2X,\n",
- data->section_table[s][i]);
- else if (i % 8 == 0)
- fprintf(fp, "\t0x%.2X, ",
- data->section_table[s][i]);
- else
- fprintf(fp, "0x%.2X, ",
- data->section_table[s][i]);
- }
-
- fprintf(fp, "};\nconst uint8_t *%s_section_table = &%s_section_table_c[0];\n\n",
- var_lables[s], var_lables[s]);
- fprintf(fp, "static const uint16_t %s_sections_c[%i] = {\n",
- var_lables[s], data->sec_count[s] * 256);
-
- limit = data->sec_count[s] * 256;
- for (i = 0; i < limit; i++) {
- uint16_t offset = data->sections[s][i];
- if (i == limit - 1)
- fprintf(fp, "0x%.4X\n", offset);
- else if (i % 4 == 3)
- fprintf(fp, "0x%.4X,\n", offset);
- else if (i % 4 == 0)
- fprintf(fp, "\t0x%.4X, ", offset);
- else
- fprintf(fp, "0x%.4X, ", offset);
- }
-
- fprintf(fp, "};\nconst uint16_t *%s_sections = &%s_sections_c[0];\n\n", var_lables[s], var_lables[s]);
- }
-
- fprintf(fp, "static const uint8_t font_glyph_data_c[%i] = {\n",
- (data->glyphs + 1) * 16);
-
- fprintf(fp, "\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n"
- "\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n");
-
- limit = data->glyphs;
- for (i = 0; i < limit; i++) {
- glyph_entry *e = data->e[i];
-
- for (y = 0; y < 16; y++) {
- if (i == limit - 1 && y == 15)
- fprintf(fp, "0x%.2X\n", e->data.u8[y]);
- else if (y % 8 == 7)
- fprintf(fp, "0x%.2X,\n", e->data.u8[y]);
- else if (y % 8 == 0)
- fprintf(fp, "\t0x%.2X, ", e->data.u8[y]);
- else
- fprintf(fp, "0x%.2X, ", e->data.u8[y]);
- }
- }
-
- fprintf(fp, "};\n");
- fprintf(fp, "const uint8_t *font_glyph_data = &font_glyph_data_c[0];\n\n");
-
- fclose(fp);
-
- return true;
-}
-
-static bool add_glyph_to_data(glyph_entry *add, int id, int style,
- struct font_data *d)
-{
- glyph_entry *e;
- int offset;
- int s;
-
- /* Find out if 'add' is unique, and get its unique table entry */
- e = glyph_add_to_table(add);
- if (e == add) {
- /* Unique glyph */
- d->e[d->glyphs++] = e;
- e->index = d->glyphs;
- if (d->glyphs >= 0xfffd) {
- LOG(LOG_ERROR, " Too many glyphs for internal data "
- "representation\n");
- return false;
- }
- } else {
- /* Duplicate glyph */
- LOG(LOG_DEBUG, " U+%.4X (%s) is duplicate\n",
- id, short_labels[style]);
- }
-
- /* Find glyph's section */
- s = id / 256;
-
- /* Allocate section if needed */
- if ((s == 0 && d->sections[style] == NULL) ||
- (s != 0 && d->section_table[style][s] == 0)) {
- size_t size = (d->sec_count[style] + 1) * SECTION_SIZE;
- uint16_t *temp = realloc(d->sections[style], size);
- if (temp == NULL) {
- LOG(LOG_ERROR, " Couldn't increase sections "
- "allocation\n");
- return false;
- }
- memset(temp + d->sec_count[style] * 256, 0,
- SECTION_SIZE);
- d->section_table[style][s] = d->sec_count[style];
- d->sections[style] = temp;
- d->sec_count[style]++;
- }
-
- offset = d->section_table[style][s] * 256 + (id & 0xff);
- d->sections[style][offset] = e->index;
-
- return true;
-}
-
-
-static bool check_glyph_data_valid(int pos, char c)
-{
- int offset = pos % 11;
-
- if (pos == 44) {
- if (c != '\n') {
- LOG(LOG_ERROR, " Invalid glyph data: "
- "expecting '\\n', got '%c' (%i)\n",
- c, c);
- return false;
- } else {
- return true;
- }
- } else if (pos < 3) {
- if (c != ' ') {
- LOG(LOG_ERROR, " Invalid glyph data: "
- "expecting ' ', got '%c' (%i)\n",
- c, c);
- return false;
- } else {
- return true;
- }
- } else if (offset == 0) {
- if (c != '\n' && c != ' ') {
- LOG(LOG_ERROR, " Invalid glyph data: "
- "expecting '\\n' or ' ', "
- "got '%c' (%i)\n",
- c, c);
- return false;
- } else {
- return true;
- }
- } else if (offset < 3) {
- if (c != ' ') {
- LOG(LOG_ERROR, " Invalid glyph data: "
- "expecting ' ', got '%c' (%i)\n",
- c, c);
- return false;
- } else {
- return true;
- }
- } else if (offset >= 3 && pos < 11) {
- if (c != '.' && c != '#') {
- LOG(LOG_ERROR, " Invalid glyph data: "
- "expecting '.' or '#', "
- "got '%c' (%i)\n",
- c, c);
- return false;
- } else {
- return true;
- }
- }
-
- /* offset must be >=3 */
- if (c != '.' && c != '#' && c != ' ') {
- LOG(LOG_ERROR, " Invalid glyph data: "
- "expecting '.', '#', or ' ', "
- "got '%c' (%i)\n",
- c, c);
- return false;
- }
-
- return true;
-}
-
-#define SEVEN_SET ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | \
- (1 << 4) | (1 << 5) | (1 << 6))
-
-#define THREE_SSS ((1 << 0) | (1 << 1) | (1 << 2))
-#define THREE_S_S ((1 << 0) | (1 << 2))
-#define THREE__SS ((1 << 0) | (1 << 1) )
-#define THREE_SS_ ( (1 << 1) | (1 << 2))
-#define THREE_S__ (1 << 2)
-#define THREE__S_ (1 << 1)
-#define THREE___S (1 << 0)
-
-uint8_t frag[16][5] = {
- { THREE_SSS,
- THREE_S_S,
- THREE_S_S,
- THREE_S_S,
- THREE_SSS },
-
- { THREE__S_,
- THREE_SS_,
- THREE__S_,
- THREE__S_,
- THREE_SSS },
-
- { THREE_SS_,
- THREE___S,
- THREE__S_,
- THREE_S__,
- THREE_SSS },
-
- { THREE_SS_,
- THREE___S,
- THREE_SS_,
- THREE___S,
- THREE_SS_ },
-
- { THREE_S_S,
- THREE_S_S,
- THREE_SSS,
- THREE___S,
- THREE___S },
-
- { THREE_SSS,
- THREE_S__,
- THREE_SSS,
- THREE___S,
- THREE_SSS },
-
- { THREE__SS,
- THREE_S__,
- THREE_SSS,
- THREE_S_S,
- THREE_SSS },
-
- { THREE_SSS,
- THREE___S,
- THREE__S_,
- THREE__S_,
- THREE__S_ },
-
- { THREE_SSS,
- THREE_S_S,
- THREE_SSS,
- THREE_S_S,
- THREE_SSS },
-
- { THREE_SSS,
- THREE_S_S,
- THREE_SSS,
- THREE___S,
- THREE___S },
-
- { THREE__S_,
- THREE_S_S,
- THREE_SSS,
- THREE_S_S,
- THREE_S_S },
-
- { THREE_SS_,
- THREE_S_S,
- THREE_SS_,
- THREE_S_S,
- THREE_SS_ },
-
- { THREE__S_,
- THREE_S_S,
- THREE_S__,
- THREE_S_S,
- THREE__S_ },
-
- { THREE_SS_,
- THREE_S_S,
- THREE_S_S,
- THREE_S_S,
- THREE_SS_ },
-
- { THREE_SSS,
- THREE_S__,
- THREE_SS_,
- THREE_S__,
- THREE_SSS },
-
- { THREE_SSS,
- THREE_S__,
- THREE_SS_,
- THREE_S__,
- THREE_S__ }
-};
-
-void build_codepoint(int id, bool italic, uint8_t *code_point)
-{
- int shift = 0;
- int l;
- int r;
-
- if (!italic)
- shift = 1;
-
- l = (id >> 12);
- r = 0xf & (id >> 8);
-
- code_point[ 0] = 0;
- code_point[ 1] = SEVEN_SET << shift;
- code_point[ 2] = 0;
-
- code_point[ 3] = (frag[l][0] << (4 + shift)) | (frag[r][0] << shift);
- code_point[ 4] = (frag[l][1] << (4 + shift)) | (frag[r][1] << shift);
- code_point[ 5] = (frag[l][2] << (4 + shift)) | (frag[r][2] << shift);
- code_point[ 6] = (frag[l][3] << (4 + shift)) | (frag[r][3] << shift);
- code_point[ 7] = (frag[l][4] << (4 + shift)) | (frag[r][4] << shift);
-
- code_point[ 8] = 0;
-
- shift = 1;
-
- l = 0xf & (id >> 4);
- r = 0xf & id ;
-
- code_point[ 9] = (frag[l][0] << (4 + shift)) | (frag[r][0] << shift);
- code_point[10] = (frag[l][1] << (4 + shift)) | (frag[r][1] << shift);
- code_point[11] = (frag[l][2] << (4 + shift)) | (frag[r][2] << shift);
- code_point[12] = (frag[l][3] << (4 + shift)) | (frag[r][3] << shift);
- code_point[13] = (frag[l][4] << (4 + shift)) | (frag[r][4] << shift);
-
- code_point[14] = 0;
- code_point[15] = SEVEN_SET << shift;
-}
-
-#undef SEVEN_SET
-#undef THREE_SSS
-#undef THREE_S_S
-#undef THREE__SS
-#undef THREE_SS_
-#undef THREE_S__
-#undef THREE__S_
-#undef THREE___S
-
-static bool glyph_is_codepoint(const glyph_entry *e, int id, int style)
-{
- bool italic = false;
-
- if (style == 1 || style == 3) {
- italic = true;
- }
-
- build_codepoint(id, italic, code_point);
-
- return glyphs_match(code_point, e->data.u8);
-}
-
-
-static bool parse_glyph_data(struct parse_context *ctx, char c,
- struct font_data *d)
-{
- int glyph = ctx->data.in_gd.pos / 11;
- int g_pos = ctx->data.in_gd.pos % 11 - 3;
- uint8_t *row;
- bool ok;
- int i;
-
- /* Check that character is valid */
- if (check_glyph_data_valid(ctx->data.in_gd.pos, c) == false) {
- LOG(LOG_ERROR, " Error in U+%.4X data: "
- "glyph line: %i, pos: %i\n",
- ctx->id,
- ctx->data.in_gd.line,
- ctx->data.in_gd.pos);
- goto error;
- }
-
- /* Allocate glyph data if needed */
- if (ctx->data.in_gd.line == 0 &&
- (c == '.' || c == '#')) {
- if (ctx->data.in_gd.e[glyph] == NULL) {
- ctx->data.in_gd.e[glyph] =
- calloc(sizeof(struct glyph_entry), 1);
- if (ctx->data.in_gd.e[glyph] == NULL) {
- LOG(LOG_ERROR, " Couldn't allocate memory for "
- "glyph entry\n");
- goto error;
- }
-
- ctx->data.in_gd.styles |= 1 << glyph;
- }
- }
-
- /* Build glyph data */
- if (c == '#') {
- row = &ctx->data.in_gd.e[glyph]->data.u8[ctx->data.in_gd.line];
- *row += 1 << (7 - g_pos);
-
- ctx->data.in_gd.line_styles |= 1 << glyph;
- } else if (c == '.') {
- ctx->data.in_gd.line_styles |= 1 << glyph;
- }
-
- /* Deal with current position */
- if (c == '\n') {
- if (ctx->data.in_gd.line == 0) {
- if (ctx->data.in_gd.e[0] == NULL) {
- LOG(LOG_ERROR, " Error in U+%.4X data: "
- "\"Regular\" glyph style must "
- "be present\n", ctx->id);
- goto error;
- }
- } else if (ctx->data.in_gd.styles !=
- ctx->data.in_gd.line_styles) {
- LOG(LOG_ERROR, " Error in U+%.4X data: "
- "glyph line: %i "
- "styles don't match first line\n",
- ctx->id,
- ctx->data.in_gd.line);
- goto error;
- }
-
- ctx->data.in_gd.pos = 0;
- ctx->data.in_gd.line++;
- ctx->data.in_gd.line_styles = 0;
- } else {
- ctx->data.in_gd.pos++;
- }
-
- /* If we've got all the glyph data, tidy up and advance state */
- if (ctx->data.in_gd.line == 16) {
- for (i = 0; i < 4; i++) {
- if (ctx->data.in_gd.e[i] != NULL) {
- ctx->count[i] += 1;
- if (glyph_is_codepoint(ctx->data.in_gd.e[i],
- ctx->id, i)) {
- LOG(LOG_DEBUG, " U+%.4X (%s) is "
- "codepoint\n",
- ctx->id,
- short_labels[i]);
- ctx->codepoints += 1;
- free(ctx->data.in_gd.e[i]);
- ctx->data.in_gd.e[i] = NULL;
- continue;
- }
-
- ok = add_glyph_to_data(ctx->data.in_gd.e[i],
- ctx->id, i, d);
- if (!ok) {
- goto error;
- }
- }
- }
-
- ctx->data.before_id.new_line = false;
- ctx->data.before_id.u = false;
- ctx->state = BEFORE_ID;
- }
-
- return true;
-
-error:
-
- for (i = 0; i < 4; i++) {
- free(ctx->data.in_gd.e[i]);
- }
-
- return false;
-}
-
-static void parse_init(struct parse_context *ctx)
-{
- memset(ctx, 0, sizeof(struct parse_context));
-}
-
-static bool get_hex_digit_value(char c, int *v)
-{
- if (c >= '0' && c <= '9')
- *v = (c - '0');
- else if (c >= 'A' && c <= 'F')
- *v = (10 + c - 'A');
- else {
- LOG(LOG_ERROR, "Invalid hex digit '%c' (%i)\n", c, c);
- return false;
- }
-
- return true;
-}
-
-static bool assemble_codepoint(const char* c, int n, int *id)
-{
- bool ok;
- int v;
-
- ok = get_hex_digit_value(*c, &v);
- if (!ok) {
- return false;
- }
-
- *id += v << (4 * (3 - n));
-
- return true;
-}
-
-static bool parse_chunk(struct parse_context *ctx, const char *buf, size_t len,
- struct font_data *d)
-{
- int i;
- bool ok;
- int count[4];
- const char *pos = buf;
- const char *end = buf + len;
-
- for (i = 0; i < 4; i++) {
- count[i] = ctx->count[i];
- }
-
- while (pos < end) {
- if (*pos == '\r') {
- LOG(LOG_ERROR, "Detected \'\\r\': Bad line ending\n");
- return false;
- }
-
- switch (ctx->state) {
- case START:
- if (*pos != '*') {
- LOG(LOG_ERROR, "First character must be '*'\n");
- printf("Got: %c (%i)\n", *pos, *pos);
- return false;
- }
- d->header_len = 0;
- ctx->data.in_header.new_line = true;
- ctx->state = IN_HEADER;
-
- /* Fall through */
- case IN_HEADER:
- if (ctx->data.in_header.new_line == true) {
- if (*pos != '*') {
- LOG(LOG_INFO, " Got header "
- "(%i bytes)\n",
- d->header_len);
- LOG(LOG_DEBUG, " Header:\n\n%.*s\n",
- d->header_len,
- d->header);
- ctx->data.before_id.new_line = false;
- ctx->data.before_id.u = false;
- ctx->state = BEFORE_ID;
- continue;
- } else if (*pos == '*') {
- d->header[d->header_len++] = ' ';
- }
- ctx->data.in_header.new_line = false;
-
- } else if (*pos == '\n') {
- ctx->data.in_header.new_line = true;
- }
-
- if (d->header_len == HEADER_MAX) {
- LOG(LOG_ERROR, " Header too long "
- "(>%i bytes)\n",
- d->header_len);
- return false;
- }
-
- d->header[d->header_len++] = *pos;
- break;
-
- case BEFORE_ID:
- if (*pos == '+' &&
- ctx->data.before_id.new_line == true &&
- ctx->data.before_id.u == true) {
- ctx->data.g_id.c = 0;
- ctx->id = 0;
- ctx->state = GLYPH_ID;
- break;
-
- } else if (*pos == 'U' &&
- ctx->data.before_id.new_line == true) {
- ctx->data.before_id.u = true;
-
- } else if (*pos == '\n') {
- ctx->data.before_id.new_line = true;
- ctx->data.before_id.u = false;
-
- } else {
- ctx->data.before_id.new_line = false;
- ctx->data.before_id.u = false;
- }
- break;
-
- case GLYPH_ID:
- ok = assemble_codepoint(pos, ctx->data.g_id.c++,
- &ctx->id);
- if (!ok) {
- LOG(LOG_ERROR, " Invalid glyph ID\n");
- return false;
- }
-
- if (ctx->data.g_id.c == 4) {
- ctx->data.before_gd.new_line = false;
- ctx->data.before_gd.prev_h = false;
- ctx->data.before_gd.prev_s = false;
- ctx->data.before_gd.c = 0;
- ctx->state = BEFORE_GLYPH_DATA;
- break;
- }
- break;
-
- case BEFORE_GLYPH_DATA:
- /* Skip until end of dashed line */
- if (*pos == '\n' && ctx->data.before_gd.c == 53) {
- ctx->state = IN_GLYPH_DATA;
- ctx->data.in_gd.e[0] = NULL;
- ctx->data.in_gd.e[1] = NULL;
- ctx->data.in_gd.e[2] = NULL;
- ctx->data.in_gd.e[3] = NULL;
- ctx->data.in_gd.line = 0;
- ctx->data.in_gd.pos = 0;
- ctx->data.in_gd.line_styles = 0;
- ctx->data.in_gd.styles = 0;
- break;
-
- } else if (*pos == '\n') {
- ctx->data.before_gd.new_line = true;
- ctx->data.before_gd.prev_h = false;
- ctx->data.before_gd.prev_s = false;
- ctx->data.before_gd.c = 0;
- } else if (*pos == '-' &&
- ctx->data.before_gd.new_line == true) {
- assert(ctx->data.before_gd.c == 0);
- ctx->data.before_gd.new_line = false;
- ctx->data.before_gd.c++;
- ctx->data.before_gd.prev_h = true;
- } else if (*pos == ' ' &&
- ctx->data.before_gd.prev_h == true) {
- assert(ctx->data.before_gd.prev_s == false);
- ctx->data.before_gd.c++;
- ctx->data.before_gd.prev_h = false;
- ctx->data.before_gd.prev_s = true;
- } else if (*pos == '-' &&
- ctx->data.before_gd.prev_s == true) {
- assert(ctx->data.before_gd.prev_h == false);
- ctx->data.before_gd.c++;
- ctx->data.before_gd.prev_h = true;
- ctx->data.before_gd.prev_s = false;
- } else {
- ctx->data.before_gd.new_line = false;
- ctx->data.before_gd.prev_h = false;
- ctx->data.before_gd.prev_s = false;
- ctx->data.before_gd.c = 0;
- }
- break;
-
- case IN_GLYPH_DATA:
- ok = parse_glyph_data(ctx, *pos, d);
- if (!ok) {
- return false;
- }
-
- break;
- }
-
- pos++;
- }
-
- for (i = 0; i < 4; i++) {
- LOG(LOG_DEBUG, " %s: %i gylphs\n", labels[i],
- ctx->count[i] - count[i]);
- }
-
- return true;
-}
-
-
-bool load_font(const char *path, struct font_data **data)
-{
- struct parse_context ctx;
- struct font_data *d;
- size_t file_len;
- size_t done;
- size_t len;
- int count;
- char *buf;
- FILE *fp;
- bool ok;
- int i;
-
- *data = NULL;
-
- fp = fopen(path, "rb");
- if (fp == NULL) {
- LOG(LOG_ERROR, "Couldn't open font data file\n");
- return false;
- }
-
- d = calloc(sizeof(struct font_data), 1);
- if (d == NULL) {
- LOG(LOG_ERROR, "Couldn't allocate memory for font data\n");
- fclose(fp);
- return false;
- }
-
- /* Find filesize */
- fseek(fp, 0L, SEEK_END);
- file_len = ftell(fp);
- if (file_len == -1) {
- LOG(LOG_ERROR, "Could not size input file\n");
- free(d);
- fclose(fp);
- return false;
- }
- fseek(fp, 0L, SEEK_SET);
- LOG(LOG_DEBUG, "Input size: %zu bytes\n", file_len);
-
- /* Allocate buffer for data chunks */
- buf = malloc(CHUNK_SIZE);
- if (buf == NULL) {
- LOG(LOG_ERROR, "Couldn't allocate memory for input buffer\n");
- free(d);
- fclose(fp);
- return false;
- }
-
- /* Initialise parser */
- parse_init(&ctx);
-
- LOG(LOG_DEBUG, "Using chunk size of %i bytes\n", CHUNK_SIZE);
-
- /* Parse the input file in chunks */
- for (done = 0; done < file_len; done += CHUNK_SIZE) {
- LOG(LOG_INFO, "Parsing input chunk %zu\n", done / CHUNK_SIZE);
-
- /* Read chunk */
- len = fread(buf, 1, CHUNK_SIZE, fp);
- if (file_len - done < CHUNK_SIZE &&
- len != file_len - done) {
- LOG(LOG_WARNING, "Last chunk has suspicious size\n");
- } else if (file_len - done >= CHUNK_SIZE &&
- len != CHUNK_SIZE) {
- LOG(LOG_ERROR, "Problem reading file\n");
- free(buf);
- free(d);
- fclose(fp);
- return false;
- }
-
- /* Parse chunk */
- ok = parse_chunk(&ctx, buf, len, d);
- if (!ok) {
- free(buf);
- free(d);
- fclose(fp);
- return false;
- }
- LOG(LOG_DEBUG, "Parsed %zu bytes\n", done + len);
- }
-
- fclose(fp);
-
- if (ctx.state != BEFORE_ID) {
- LOG(LOG_ERROR, "Unexpected end of file\n");
- free(buf);
- free(d);
- return false;
- }
-
- LOG(LOG_INFO, "Parsing complete:\n");
- count = 0;
- for (i = 0; i < 4; i++) {
- LOG(LOG_INFO, " %s: %i gylphs\n", labels[i], ctx.count[i]);
- count += ctx.count[i];
- }
-
- LOG(LOG_RESULT, " Total %i gylphs "
- "(of which %i unique, %i codepoints, %i duplicates)\n",
- count, d->glyphs, ctx.codepoints,
- count - d->glyphs - ctx.codepoints);
-
- free(buf);
-
- *data = d;
- return true;
-}
-
-static void log_usage(const char *argv0)
-{
- level = LOG_INFO;
- LOG(LOG_INFO,
- "Usage:\n"
- "\t%s [options] <in_file> <out_file>\n"
- "\n"
- "Options:\n"
- "\t--help -h Display this text\n"
- "\t--quiet -q Don't show warnings\n"
- "\t--verbose -v Verbose output\n"
- "\t--debug -d Full debug output\n",
- argv0);
-}
-
-int main(int argc, char** argv)
-{
- const char *in_path = NULL;
- const char *out_path = NULL;
- char *header_path = NULL;
- struct font_data *data;
- bool ok;
- int i;
- int opt;
-
- level = LOG_RESULT;
-
- /* Handle program arguments */
- struct option long_options[] = {
- { "help", no_argument, NULL, 'h' },
- { "quiet", no_argument, NULL, 'q' },
- { "verbose", no_argument, NULL, 'v' },
- { "debug", no_argument, NULL, 'd' },
- { "header", required_argument, NULL, 'H' },
- };
-
- while ((opt = getopt_long(argc, argv, "hqvdH:", long_options, NULL)) != -1) {
- switch (opt) {
- case 'q':
- level = LOG_WARNING;
- break;
-
- case 'v':
- level = LOG_INFO;
- break;
-
- case 'd':
- level = LOG_DEBUG;
- break;
-
- case 'H':
- header_path = strdup(optarg);
- break;
-
- case 'h':
- log_usage(argv[0]);
- free(header_path);
- return EXIT_SUCCESS;
-
- default:
- log_usage(argv[0]);
- free(header_path);
- return EXIT_FAILURE;
- }
- }
-
- if ((argc - optind) < 2) {
- log_usage(argv[0]);
- free(header_path);
- return EXIT_FAILURE;
- }
-
- in_path = argv[optind];
- out_path = argv[optind + 1];
-
- LOG(LOG_DEBUG, "Using input path: \"%s\"\n", in_path);
- LOG(LOG_DEBUG, "Using output path: \"%s\"\n", out_path);
-
- ok = load_font(in_path, &data);
- if (!ok) {
- free_table();
- free(header_path);
- return EXIT_FAILURE;
- }
-
- ok = generate_font_source(out_path, data);
- if (ok && (header_path != NULL)) {
- ok = generate_font_header(header_path, data);
- }
- free(header_path);
- free_table();
- for (i = 0; i < 4; i++) {
- free(data->sections[i]);
- }
- free(data);
- if (!ok) {
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
diff --git a/frontends/framebuffer/convert_image.c b/frontends/framebuffer/convert_image.c
deleted file mode 100644
index de772fc29..000000000
--- a/frontends/framebuffer/convert_image.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright 2009 Daniel Silverstone <dsilvers@netsurf-browser.org>
- *
- * This file is part of NetSurf, http://www.netsurf-browser.org/
- *
- * NetSurf is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * NetSurf is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdbool.h>
-#include <errno.h>
-#include <stdio.h>
-#include <png.h>
-#include <stdlib.h>
-#include <string.h>
-
-#if PNG_LIBPNG_VER < 10209
-#define png_set_expand_gray_1_2_4_to_8(png) png_set_gray_1_2_4_to_8(png)
-#endif
-
-static png_structp png;
-static png_infop info;
-static int interlace;
-static size_t rowbytes;
-static int raw_width, raw_height;
-static int rowstride;
-static unsigned char *bitmap_data;
-static bool is_cursor = true;
-static int raw_hot_x, raw_hot_y;
-
-#define WIDTH (is_cursor?raw_width-1:raw_width)
-#define HEIGHT (is_cursor?raw_height-1:raw_height)
-
-#define HOT_X (is_cursor?raw_hot_x-1:0)
-#define HOT_Y (is_cursor?raw_hot_y-1:0)
-
-#define REAL(v) (is_cursor?v+1:v)
-
-#define PPIX_AT(x,y) ((bitmap_data + (rowstride * y)) + (x * 4))
-
-#define R_OFF 2
-#define G_OFF 1
-#define B_OFF 0
-#define A_OFF 3
-
-#define R_AT(x,y) *(PPIX_AT(x,y) + R_OFF)
-#define G_AT(x,y) *(PPIX_AT(x,y) + G_OFF)
-#define B_AT(x,y) *(PPIX_AT(x,y) + B_OFF)
-#define A_AT(x,y) *(PPIX_AT(x,y) + A_OFF)
-
-
-static void
-usage(void)
-{
- fprintf(stderr, "usage: fb_convert_image input.png output.inc varname\n");
-}
-
-
-static void
-detect_hotspot(void)
-{
- int i;
- int greenpixels = 0;
-
- for (i = 0; i < raw_width; ++i) {
- if (A_AT(i, 0) == 255) {
- if (G_AT(i, 0) == 255) {
- greenpixels++;
- raw_hot_x = i;
- }
- if ((B_AT(i, 0) != 0) || (R_AT(i, 0) != 0)) {
- is_cursor = false;
- return;
- }
- } else if (A_AT(i, 0) != 0) {
- is_cursor = false;
- return;
- }
- }
- if (greenpixels != 1) {
- is_cursor = false;
- return;
- }
-
- for (i = 0; i < raw_height; ++i) {
- if (A_AT(0, i) == 255) {
- if (G_AT(0, i) == 255) {
- greenpixels++;
- raw_hot_y = i;
- }
- if ((B_AT(0, i) != 0) || (R_AT(0, i) != 0)) {
- is_cursor = false;
- return;
- }
- } else if (A_AT(0, i) != 0) {
- is_cursor = false;
- return;
- }
- }
- if (greenpixels != 2) {
- is_cursor = false;
- return;
- }
- printf(" Pointer detected. Adjusted hotspot at %d, %d (0-based)\n",
- raw_hot_x - 1, raw_hot_y - 1);
-}
-
-
-static void
-info_callback(png_structp png, png_infop info)
-{
- int bit_depth, color_type, interlace, intent;
- double gamma;
- png_uint_32 width, height;
-
- /* Read the PNG details */
- png_get_IHDR(png, info, &width, &height, &bit_depth,
- &color_type, &interlace, 0, 0);
-
- /* Set up our transformations */
- if (color_type == PNG_COLOR_TYPE_PALETTE)
- png_set_palette_to_rgb(png);
- if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
- png_set_expand_gray_1_2_4_to_8(png);
- if (png_get_valid(png, info, PNG_INFO_tRNS))
- png_set_tRNS_to_alpha(png);
- if (bit_depth == 16)
- png_set_strip_16(png);
- if (color_type == PNG_COLOR_TYPE_GRAY ||
- color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- png_set_gray_to_rgb(png);
- if (!(color_type & PNG_COLOR_MASK_ALPHA))
- png_set_filler(png, 0xff, PNG_FILLER_AFTER);
- /* gamma correction - we use 2.2 as our screen gamma
- * this appears to be correct (at least in respect to !Browse)
- * see http://www.w3.org/Graphics/PNG/all_seven.html for a test case
- */
- if (png_get_sRGB(png, info, &intent))
- png_set_gamma(png, 2.2, 0.45455);
- else {
- if (png_get_gAMA(png, info, &gamma))
- png_set_gamma(png, 2.2, gamma);
- else
- png_set_gamma(png, 2.2, 0.45455);
- }
-
-
- png_read_update_info(png, info);
-
- rowbytes = png_get_rowbytes(png, info);
- interlace = (interlace == PNG_INTERLACE_ADAM7);
- raw_width = width;
- raw_height = height;
-
- rowstride = raw_width * 4;
- bitmap_data = malloc(rowstride * raw_height);
-}
-
-static unsigned int interlace_start[8] = {0, 16, 0, 8, 0, 4, 0};
-static unsigned int interlace_step[8] = {28, 28, 12, 12, 4, 4, 0};
-static unsigned int interlace_row_start[8] = {0, 0, 4, 0, 2, 0, 1};
-static unsigned int interlace_row_step[8] = {8, 8, 8, 4, 4, 2, 2};
-
-static void
-row_callback(png_structp png, png_bytep new_row,
- png_uint_32 row_num, int pass)
-{
- unsigned long i, j;
- unsigned int start, step;
- unsigned char *row = bitmap_data + (rowstride * row_num);
-
- if (new_row == 0)
- return;
-
- if (interlace) {
- start = interlace_start[pass];
- step = interlace_step[pass];
- row_num = interlace_row_start[pass] +
- interlace_row_step[pass] * row_num;
-
- /* Copy the data to our current row taking interlacing
- * into consideration */
- row = bitmap_data + (rowstride * row_num);
- for (j = 0, i = start; i < rowbytes; i += step) {
- row[i++] = new_row[j++];
- row[i++] = new_row[j++];
- row[i++] = new_row[j++];
- row[i++] = new_row[j++];
- }
- } else {
- memcpy(row, new_row, rowbytes);
- }
-}
-
-static void
-end_callback(png_structp png, png_infop info)
-{
-}
-
-
-int
-main(int argc, char **argv)
-{
- FILE *f;
- unsigned char buffer[1024];
- int br;
- int x, y, c;
-
- if (argc != 4) {
- usage();
- return 1;
- }
-
- printf(" CONVERT: %s (%s)\n", argv[1], argv[3]);
-
- png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
- info = png_create_info_struct(png);
-
- png_set_progressive_read_fn(png, NULL, info_callback, row_callback, end_callback);
-
- f = fopen(argv[1], "rb");
- if (f == NULL) {
- printf(" Unable to open %s\n", argv[1]);
- return 1;
- }
-
- do {
- br = fread(buffer, 1, 1024, f);
- if (br > 0) {
- png_process_data(png, info, buffer, br);
- }
- } while (br > 0);
-
- if (br < 0) {
- printf("Error reading input: %s\n", strerror(errno));
- fclose(f);
- return 1;
- }
-
- fclose(f);
-
- detect_hotspot();
-
- f = fopen(argv[2], "w");
- if (f == NULL) {
- printf(" Unable to open %s\n", argv[2]);
- return 2;
- }
-
- fprintf(f, "/* This file is auto-generated from %s\n", argv[1]);
- fprintf(f, " *\n * Do not edit this file directly.\n */\n\n");
- fprintf(f, "#include <sys/types.h>\n\n");
- fprintf(f, "#include <stdint.h>\n\n");
- fprintf(f, "#include <stdbool.h>\n\n");
- fprintf(f, "#include <libnsfb.h>\n\n");
- fprintf(f, "#include \"netsurf/plot_style.h\"\n");
- fprintf(f, "#include \"framebuffer/gui.h\"\n");
- fprintf(f, "#include \"framebuffer/fbtk.h\"\n\n");
-
- fprintf(f, "static uint8_t %s_pixdata[] = {\n", argv[3]);
- for (y = 0; y < HEIGHT; ++y) {
- unsigned char *rowptr = bitmap_data + (rowstride * y);
- if (is_cursor) {
- /* If it's a cursor, skip one row and one column */
- rowptr += rowstride + 4;
- }
- fprintf(f, "\t");
- for (x = 0; x < WIDTH; ++x) {
- for (c = 0; c < 4; ++c) {
- unsigned char b = *rowptr++;
- fprintf(f, "0x%02x, ", b);
- }
- }
- fprintf(f, "\n");
- }
- fprintf(f, "};\n\n");
-
- fprintf(f, "struct fbtk_bitmap %s = {\n", argv[3]);
- fprintf(f, "\t.width\t\t= %d,\n", WIDTH);
- fprintf(f, "\t.height\t\t= %d,\n", HEIGHT);
- fprintf(f, "\t.hot_x\t\t= %d,\n", HOT_X);
- fprintf(f, "\t.hot_y\t\t= %d,\n", HOT_Y);
- fprintf(f, "\t.pixdata\t= %s_pixdata,\n", argv[3]);
-
- fprintf(f, "};\n\n");
- fclose(f);
-
- return 0;
-}
-
-/*
- * Local Variables:
- * c-basic-offset:8
- * End:
- */