diff options
author | Rob Kendrick <rjek@netsurf-browser.org> | 2009-05-08 12:07:22 +0000 |
---|---|---|
committer | Rob Kendrick <rjek@netsurf-browser.org> | 2009-05-08 12:07:22 +0000 |
commit | 2594050ffbc13156615d42b76baa38a0de06a322 (patch) | |
tree | 282096a9c51a664b5f8c884d03c546a275e98136 /src | |
parent | 36a451d571f6af0b220e7cc43c6eb278fce88135 (diff) | |
download | ttf2f-2594050ffbc13156615d42b76baa38a0de06a322.tar.gz ttf2f-2594050ffbc13156615d42b76baa38a0de06a322.tar.bz2 |
Add some error handling and reporting
svn path=/trunk/tools/ttf2f/; revision=7441
Diffstat (limited to 'src')
-rw-r--r-- | src/cli.c | 37 | ||||
-rw-r--r-- | src/encoding.c | 7 | ||||
-rw-r--r-- | src/encoding.h | 4 | ||||
-rw-r--r-- | src/intmetrics.c | 52 | ||||
-rw-r--r-- | src/intmetrics.h | 8 | ||||
-rw-r--r-- | src/outlines.c | 118 | ||||
-rw-r--r-- | src/outlines.h | 4 | ||||
-rw-r--r-- | src/utils.h | 7 |
8 files changed, 162 insertions, 75 deletions
@@ -25,6 +25,7 @@ void ttf2f_poll(int active) int main(int argc, char **argv) { int fail; + ttf2f_result err = TTF2F_RESULT_OK; int nglyphs; struct glyph *glist; struct font_metrics *metrics; @@ -85,11 +86,35 @@ int main(int argc, char **argv) mkdir(argv[2], 0755); - write_intmetrics(argv[2], argv[2], glist, nglyphs, metrics, progress); - - write_outlines(argv[2], argv[2], glist, nglyphs, metrics, progress); - - write_encoding(argv[2], argv[2], glist, nglyphs, 0, progress); + if ((err = write_intmetrics(argv[2], argv[2], glist, nglyphs, + metrics, progress)) != TTF2F_RESULT_OK) goto error_out; + + if ((err = write_outlines(argv[2], argv[2], glist, nglyphs, + metrics, progress)) != TTF2F_RESULT_OK) goto error_out; + + if ((err = write_encoding(argv[2], argv[2], glist, nglyphs, + 0, progress)) != TTF2F_RESULT_OK) goto error_out; + +error_out: + if (err != TTF2F_RESULT_OK) { + switch (err) { + case TTF2F_RESULT_NOMEM: + fprintf(stderr, "ERROR: failed to allocate memory\n"); + break; + case TTF2F_RESULT_OPEN: + fprintf(stderr, "ERROR: failed to open output file\n"); + break; + case TTF2F_RESULT_WRITE: + fprintf(stderr, "ERROR: failed to write to file\n"); + break; + + case TTF2F_RESULT_OK: + /* keeps gcc quiet, even though this will never occur. + * we avoid default: so we get a warning is we add more + */ + break; + } + } free(metrics); free(glist); @@ -99,6 +124,6 @@ int main(int argc, char **argv) ft_fini(); destroy_glyphs(); - return 0; + exit(err == TTF2F_RESULT_OK ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/encoding.c b/src/encoding.c index 61df3ed..2cba386 100644 --- a/src/encoding.c +++ b/src/encoding.c @@ -16,7 +16,7 @@ * \param type File format to use - 0 = full; 1 = sparse * \param callback Progress callback function */ -void write_encoding(const char *savein, const char *name, +ttf2f_result write_encoding(const char *savein, const char *name, struct glyph *glyph_list, int list_size, int type, void (*callback)(int progress)) { @@ -26,7 +26,8 @@ void write_encoding(const char *savein, const char *name, char out[1024]; snprintf(out, 1024, "%s" DIR_SEP "Encoding", savein); - output = fopen(out, "w+"); + if ((output = fopen(out, "w+")) == NULL) + return TTF2F_RESULT_OPEN; fprintf(output, "%% %sEncoding 1.00\n", name); fprintf(output, "%% Encoding file for font '%s'\n\n", name); @@ -67,5 +68,7 @@ void write_encoding(const char *savein, const char *name, } fclose(output); + + return TTF2F_RESULT_OK; } diff --git a/src/encoding.h b/src/encoding.h index 3a88cad..e99221e 100644 --- a/src/encoding.h +++ b/src/encoding.h @@ -1,9 +1,11 @@ #ifndef _TTF2F_ENCODING_H_ #define _TTF2F_ENCODING_H_ +#include "utils.h" + struct glyph; -void write_encoding(const char *savein, const char *name, +ttf2f_result write_encoding(const char *savein, const char *name, struct glyph *glyph_list, int list_size, int type, void (*callback)(int progress)); diff --git a/src/intmetrics.c b/src/intmetrics.c index 4e8e5f1..6040008 100644 --- a/src/intmetrics.c +++ b/src/intmetrics.c @@ -85,10 +85,9 @@ struct kern_pair_16 { * \param list_size Size of glyph list * \param metrics Global font metrics */ -void write_intmetrics(const char *savein, const char *name, - struct glyph *glyph_list, int list_size, - struct font_metrics *metrics, - void (*callback)(int progress)) +ttf2f_result write_intmetrics(const char *savein, + const char *name,struct glyph *glyph_list, int list_size, + struct font_metrics *metrics, void (*callback)(int progress)) { struct intmetrics_header header; int charmap_size = 0; @@ -102,10 +101,9 @@ void write_intmetrics(const char *savein, const char *name, /* allow for chunk 0 */ xwidthtab = calloc(33, sizeof(short)); - if (!xwidthtab) { - fprintf(stderr, "malloc failed\n"); - return; - } + if (xwidthtab == NULL) + return TTF2F_RESULT_NOMEM; + xwidthtab_size = 32; /* create xwidthtab - char code is now the index */ @@ -119,10 +117,8 @@ void write_intmetrics(const char *savein, const char *name, xwidthtab[i+32] = g->width; xwidthtab = realloc(xwidthtab, (xwidthtab_size+1) * sizeof(short)); - if (!xwidthtab) { - fprintf(stderr, "malloc failed\n"); - return; - } + if (xwidthtab == NULL) + return TTF2F_RESULT_NOMEM; } /* fill in header */ @@ -138,12 +134,23 @@ void write_intmetrics(const char *savein, const char *name, mapsize = charmap_size; snprintf(out, 1024, "%s" DIR_SEP "IntMetrics", savein); - output = fopen(out, "wb+"); - fwrite((void*)&header, sizeof(struct intmetrics_header), 1, output); - fputc(mapsize & 0xFF, output); - fputc((mapsize & 0xFF00) >> 8, output); - fwrite(character_map, sizeof(char), charmap_size, output); - fwrite(xwidthtab, sizeof(short), xwidthtab_size, output); + if ((output = fopen(out, "wb+")) == NULL) { + free(xwidthtab); + return TTF2F_RESULT_OPEN; + } + + if (fwrite((void*)&header, sizeof(struct intmetrics_header), + 1, output) != 1) goto error_write; + + if (fputc(mapsize & 0xFF, output) == EOF) goto error_write; + if (fputc((mapsize & 0xFF00) >> 8, output) == EOF) goto error_write; + + if (fwrite(character_map, sizeof(char), charmap_size, output) + != (size_t)charmap_size) goto error_write; + + if (fwrite(xwidthtab, sizeof(short), xwidthtab_size, output) + != xwidthtab_size) goto error_write; + fclose(output); #ifdef __riscos__ @@ -154,5 +161,14 @@ void write_intmetrics(const char *savein, const char *name, if (character_map) free(character_map); free(xwidthtab); + + return TTF2F_RESULT_OK; + +error_write: + free(character_map); + free(xwidthtab); + fclose(output); + + return TTF2F_RESULT_WRITE; } diff --git a/src/intmetrics.h b/src/intmetrics.h index 0aaf1be..5b8546d 100644 --- a/src/intmetrics.h +++ b/src/intmetrics.h @@ -1,12 +1,14 @@ #ifndef _TTF2F_INTMETRICS_H_ #define _TTF2F_INTMETRICS_H_ +#include "utils.h" + struct glyph; struct font_metrics; -void write_intmetrics(const char *savein, const char *name, - struct glyph *glyph_list, int list_size, - struct font_metrics *metrics, +ttf2f_result write_intmetrics(const char *savein, + const char *name, struct glyph *glyph_list, + int list_size, struct font_metrics *metrics, void (*callback)(int progress)); #endif diff --git a/src/outlines.c b/src/outlines.c index 2aef1bb..a3a1fcd 100644 --- a/src/outlines.c +++ b/src/outlines.c @@ -12,8 +12,8 @@ #include "outlines.h" #include "utils.h" -static unsigned int write_chunk(FILE* file, int chunk_no, - struct glyph *glyph_list, int list_size); +ttf2f_result write_chunk(FILE* file, int chunk_no, + struct glyph *glyph_list, int list_size, unsigned int *out_chunk_size); /** * Write the font outlines to file @@ -24,7 +24,7 @@ static unsigned int write_chunk(FILE* file, int chunk_no, * \param list_size Size of glyph list * \param metrics Global font metrics */ -void write_outlines(const char *savein, const char *name, +ttf2f_result write_outlines(const char *savein, const char *name, struct glyph *glyph_list, int list_size, struct font_metrics *metrics, void (*callback)(int progress)) @@ -61,22 +61,28 @@ void write_outlines(const char *savein, const char *name, header.chunk_data.reserved[4] = 0; snprintf(out, 1024, "%s" DIR_SEP "Outlines", savein); - output = fopen(out, "wb+"); + if ((output = fopen(out, "wb+") ) == NULL) + return TTF2F_RESULT_OPEN; + /* write file header */ - fwrite((void*)&header, sizeof(struct outlines_header), 1, output); + if (fwrite((void*)&header, sizeof(struct outlines_header), 1, output) + != 1) goto error_write; + /* write scaffold table */ - fputc(0x3, output); - fputc(0x0, output); - fputc(0x0, output); + if (fputc(0x3, output) == EOF) goto error_write; + if (fputc(0x0, output) == EOF) goto error_write; + if (fputc(0x0, output) == EOF) goto error_write; + /* table end */ - fprintf(output, "%s", name); - fputc(0x0, output); - fprintf(output, "Outlines"); - fputc(0x0, output); + if (fprintf(output, "%s", name) < 0) goto error_write; + if (fputc(0x0, output) == EOF) goto error_write; + if (fprintf(output, "Outlines") < 0) goto error_write; + if (fputc(0x0, output) == EOF) goto error_write; + /* word align */ i = table_end_len + 3 + sizeof(struct outlines_header); while (i++ < header.chunk_data.chunk_table_offset) - fputc(0x0, output); + if (fputc(0x0, output) == EOF) goto error_write; /* write chunk table */ chunk_table_entry = 1; @@ -85,30 +91,35 @@ void write_outlines(const char *savein, const char *name, /* initialise chunk table */ for (i = 0; i <= header.chunk_data.nchunks; i++) { - fwrite((void*)¤t_chunk_offset, sizeof(int), - 1, output); + if (fwrite((void*)¤t_chunk_offset, sizeof(int), + 1, output) != 1) goto error_write; } /* write copyright information to file */ - fputc(0x0, output); - fprintf(output, + if (fputc(0x0, output) == EOF) goto error_write; + if (fprintf(output, "\n\n\n%s is %s\nConverted to RISC OS by TTF2F\n\n\n", - metrics->name_full, metrics->name_copyright); - fputc(0x0, output); + metrics->name_full, metrics->name_copyright) < 0) goto error_write; + if (fputc(0x0, output) == EOF) goto error_write; current_chunk_offset += 42 + strlen(metrics->name_full) + strlen(metrics->name_copyright); while(current_chunk_offset % 4) { - fputc(0x0, output); + if (fputc(0x0, output) == EOF) goto error_write; current_chunk_offset++; } /* fill in offsets 0 and 1 */ fseek(output, header.chunk_data.chunk_table_offset, SEEK_SET); - fwrite((void*)¤t_chunk_offset, sizeof(int), 1, output); - fwrite((void*)¤t_chunk_offset, sizeof(int), 1, output); + if (fwrite((void*)¤t_chunk_offset, sizeof(int), 1, output) != 1) + goto error_write; + + if (fwrite((void*)¤t_chunk_offset, sizeof(int), 1, output) != 1) + goto error_write; for (; header.chunk_data.nchunks > 1; header.chunk_data.nchunks--) { + unsigned int chunk_size; + ttf2f_result err; callback((chunk_table_entry * 100) / ((list_size / 32) + 2)); ttf2f_poll(1); @@ -117,21 +128,27 @@ void write_outlines(const char *savein, const char *name, fseek(output, current_chunk_offset, SEEK_SET); /* write chunk */ - current_chunk_offset += write_chunk(output, - chunk_table_entry - 1, glyph_list, - list_size); + err = write_chunk(output, chunk_table_entry - 1, glyph_list, + list_size, &chunk_size); + + if (err != TTF2F_RESULT_OK) { + fclose(output); + return err; + } + + current_chunk_offset += chunk_size; /* align to word boundary */ while (current_chunk_offset % 4) { - fputc(0x0, output); + if (fputc(0x0, output) == EOF) goto error_write; current_chunk_offset++; } /* fill in next chunk table entry */ fseek(output, header.chunk_data.chunk_table_offset + (chunk_table_entry+1) * 4, SEEK_SET); - fwrite((void*)¤t_chunk_offset, sizeof(int), 1, - output); + if (fwrite((void*)¤t_chunk_offset, sizeof(int), 1, + output) != 1) goto error_write; chunk_table_entry++; } @@ -142,6 +159,11 @@ void write_outlines(const char *savein, const char *name, /* set type */ _swix(OS_File, _INR(0,2), 18, out, 0xFF6); #endif + return TTF2F_RESULT_OK; + +error_write: + fclose(output); + return TTF2F_RESULT_WRITE; } /** @@ -153,8 +175,8 @@ void write_outlines(const char *savein, const char *name, * \param list_size Size of glyph list * \return Size of this chunk, or 0 on failure */ -unsigned int write_chunk(FILE* file, int chunk_no, struct glyph *glyph_list, - int list_size) +ttf2f_result write_chunk(FILE* file, int chunk_no, struct glyph *glyph_list, + int list_size, unsigned int *out_chunk_size) { struct glyph *g; struct chunk *chunk; @@ -163,10 +185,12 @@ unsigned int write_chunk(FILE* file, int chunk_no, struct glyph *glyph_list, struct char_data *character; int i; + *out_chunk_size = 0; + /* create chunk */ chunk = calloc(1, sizeof(struct chunk)); - if (!chunk) - return 0; + if (chunk == NULL) + return TTF2F_RESULT_NOMEM; chunk->flags = 0x80000000; @@ -195,8 +219,9 @@ unsigned int write_chunk(FILE* file, int chunk_no, struct glyph *glyph_list, chunk = realloc((char*)chunk, chunk_size+sizeof(struct char_data)); - if (!chunk) - return 0; + if (chunk == NULL) + return TTF2F_RESULT_NOMEM; + character = (struct char_data*)(void*)((char*)chunk + chunk_size); chunk_size += sizeof(struct char_data); @@ -226,8 +251,8 @@ unsigned int write_chunk(FILE* file, int chunk_no, struct glyph *glyph_list, /* end of outline */ chunk = realloc((char*)chunk, chunk_size+1); - if (!chunk) - return 0; + if (chunk == NULL) + return TTF2F_RESULT_NOMEM; *((char*)chunk+chunk_size-1) = 0; chunk_size += 1; break; @@ -235,8 +260,8 @@ unsigned int write_chunk(FILE* file, int chunk_no, struct glyph *glyph_list, /* move to point */ chunk = realloc((char*)chunk, chunk_size+4); - if (!chunk) - return 0; + if (chunk == NULL) + return TTF2F_RESULT_NOMEM; /* id, no scaffold */ *((char*)chunk+chunk_size-1) = 1; /* x, y */ @@ -249,8 +274,8 @@ unsigned int write_chunk(FILE* file, int chunk_no, struct glyph *glyph_list, /* draw line to point */ chunk = realloc((char*)chunk, chunk_size+4); - if (!chunk) - return 0; + if (chunk == NULL) + return TTF2F_RESULT_NOMEM; /* id, no scaffold */ *((char*)chunk+chunk_size-1) = 2; /* x, y */ @@ -263,8 +288,8 @@ unsigned int write_chunk(FILE* file, int chunk_no, struct glyph *glyph_list, /* draw bezier curve to point */ chunk = realloc((char*)chunk, chunk_size+10); - if (!chunk) - return 0; + if (chunk == NULL) + return TTF2F_RESULT_NOMEM; /* id, no scaffold */ *((char*)chunk+chunk_size-1) = 3; /* x1, y1 */ @@ -292,10 +317,15 @@ unsigned int write_chunk(FILE* file, int chunk_no, struct glyph *glyph_list, } /* write chunk to file */ - fwrite((void*)chunk, chunk_size, 1, file); + if (fwrite((void*)chunk, chunk_size, 1, file) != 1) { + free(chunk); + return TTF2F_RESULT_WRITE; + } free(chunk); - return chunk_size; + *out_chunk_size = chunk_size; + + return TTF2F_RESULT_OK; } diff --git a/src/outlines.h b/src/outlines.h index 99a916b..51a6d1c 100644 --- a/src/outlines.h +++ b/src/outlines.h @@ -1,6 +1,8 @@ #ifndef _TTF2F_OUTLINES_H_ #define _TTF2F_OUTLINES_H_ +#include "utils.h" + struct chunk_data { int chunk_table_offset; int nchunks; @@ -50,7 +52,7 @@ struct char_data { struct glyph; struct font_metrics; -void write_outlines(const char *savein, const char *name, +ttf2f_result write_outlines(const char *savein, const char *name, struct glyph *glyph_list, int list_size, struct font_metrics *metrics, void (*callback)(int progress)); diff --git a/src/utils.h b/src/utils.h index de1d067..09d348e 100644 --- a/src/utils.h +++ b/src/utils.h @@ -11,6 +11,13 @@ #define DIR_SEP "/" #endif +typedef enum ttf2f_result { + TTF2F_RESULT_OK, + TTF2F_RESULT_NOMEM, + TTF2F_RESULT_OPEN, + TTF2F_RESULT_WRITE +} ttf2f_result; + void ttf2f_poll(int active); char *strndup(const char *s, size_t n); long convert_units(long raw, long ppem); |