diff options
-rw-r--r-- | Makefile | 19 | ||||
-rw-r--r-- | include/pencil.h | 2 | ||||
-rw-r--r-- | src/pencil_save.c | 71 | ||||
-rw-r--r-- | test/pencil_test.c | 132 |
4 files changed, 168 insertions, 56 deletions
@@ -1,6 +1,6 @@ # Component settings COMPONENT := pencil -COMPONENT_VERSION := 0.0.3 +COMPONENT_VERSION := 0.0.5 # Default to a static library COMPONENT_TYPE ?= lib-static @@ -29,14 +29,6 @@ else CFLAGS := $(CFLAGS) -Dinline="__inline__" endif -# OSLib -ifneq ($(findstring clean,$(MAKECMDGOALS)),clean) - ifeq ($(BUILD),arm-unknown-riscos) - CFLAGS := $(CFLAGS) -I$(PREFIX)/include - LDFLAGS := $(LDFLAGS) -lOSLib32 - endif -endif - # RUfl ifneq ($(findstring clean,$(MAKECMDGOALS)),clean) ifneq ($(PKGCONFIG),) @@ -48,6 +40,15 @@ ifneq ($(findstring clean,$(MAKECMDGOALS)),clean) endif endif +# OSLib +ifneq ($(findstring clean,$(MAKECMDGOALS)),clean) + ifeq ($(findstring -riscos,$(HOST)),-riscos) + CFLAGS := $(CFLAGS) -I$(PREFIX)/include + LDFLAGS := $(LDFLAGS) -lOSLib32 + TESTLDFLAGS := $(TESTLDFLAGS) -static + endif +endif + include $(NSBUILD)/Makefile.top # Extra installation rules diff --git a/include/pencil.h b/include/pencil.h index 9205d5a..d4f1ac3 100644 --- a/include/pencil.h +++ b/include/pencil.h @@ -17,7 +17,7 @@ struct pencil_diagram; typedef enum { - pencil_OK, + pencil_OK = rufl_OK, pencil_OUT_OF_MEMORY = rufl_OUT_OF_MEMORY, pencil_FONT_MANAGER_ERROR = rufl_FONT_MANAGER_ERROR, pencil_FONT_NOT_FOUND = rufl_FONT_NOT_FOUND, diff --git a/src/pencil_save.c b/src/pencil_save.c index f5c23fb..426423a 100644 --- a/src/pencil_save.c +++ b/src/pencil_save.c @@ -46,13 +46,13 @@ static void pencil_save_pass1(struct pencil_save_context *context, struct pencil_item *item, unsigned int depth); static void pencil_save_pass1_text_callback(void *c, const char *font_name, unsigned int font_size, - const char *s8, unsigned short *s16, unsigned int n, + const uint8_t *s8, const uint32_t *s32, unsigned int n, int x, int y); static void pencil_save_pass2(struct pencil_save_context *context, struct pencil_item *item, unsigned int depth); static void pencil_save_pass2_text_callback(void *c, const char *font_name, unsigned int font_size, - const char *s8, unsigned short *s16, unsigned int n, + const uint8_t *s8, const uint32_t *s32, unsigned int n, int x, int y); @@ -107,8 +107,9 @@ pencil_code pencil_save_drawfile(struct pencil_diagram *diagram, header->tag[3] = 'w'; header->major_version = 201; header->minor_version = 0; - strncpy(header->source, source, 12); - for (i = strlen(source); i < 12; i++) + i = strlen(source); + memcpy(header->source, source, (i < 12) ? i : 12); + for (; i < 12; i++) header->source[i] = ' '; header->bbox = context.bbox; b = (char *) buffer + sizeof(drawfile_diagram_base); @@ -192,7 +193,7 @@ void pencil_save_pass1(struct pencil_save_context *context, break; case pencil_TEXT: { - int bbox[4]; + os_box bbox; int width; code = rufl_paint_callback(item->font_family, item->font_style, @@ -200,14 +201,14 @@ void pencil_save_pass1(struct pencil_save_context *context, item->x, item->y, pencil_save_pass1_text_callback, context); if (code != rufl_OK) - context->code = code; + context->code = (pencil_code) code; if (context->code != pencil_OK) return; code = rufl_font_bbox(item->font_family, item->font_style, - item->font_size, bbox); + item->font_size, &bbox); if (code != rufl_OK) - context->code = code; + context->code = (pencil_code) code; if (context->code != pencil_OK) return; @@ -215,14 +216,14 @@ void pencil_save_pass1(struct pencil_save_context *context, item->font_size, item->text, strlen(item->text), &width); if (code != rufl_OK) - context->code = code; + context->code = (pencil_code) code; if (context->code != pencil_OK) return; item->bbox.x0 = item->x * 256; item->bbox.y0 = item->y * 256; item->bbox.x1 = (item->x + width) * 256; - item->bbox.y1 = (item->y + (bbox[3] - bbox[1])) * 256; + item->bbox.y1 = (item->y + (bbox.y1 - bbox.y0)) * 256; } break; case pencil_PATH: @@ -290,7 +291,7 @@ void pencil_save_pass1(struct pencil_save_context *context, void pencil_save_pass1_text_callback(void *c, const char *font_name, unsigned int font_size, - const char *s8, unsigned short *s16, unsigned int n, + const uint8_t *s8, const uint32_t *s32, unsigned int n, int x, int y) { struct pencil_save_context *context = c; @@ -301,7 +302,7 @@ void pencil_save_pass1_text_callback(void *c, (void) x; /* unused */ (void) y; /* unused */ - assert(s8 || s16); + assert(s8 || s32); /* check if the font name is new */ for (i = 0; i != context->font_count && @@ -331,12 +332,14 @@ void pencil_save_pass1_text_callback(void *c, } else { unsigned int utf8_length = 0; for (i = 0; i != n; i++) { - if (s16[i] < 0x80) + if (s32[i] < 0x80) utf8_length += 1; - else if (s16[i] < 0x800) + else if (s32[i] < 0x800) utf8_length += 2; - else + else if (s32[i] < 0x10000) utf8_length += 3; + else + utf8_length += 4; } context->size += 24 + 56 + ((utf8_length + 4) & ~3); } @@ -367,8 +370,10 @@ void pencil_save_pass2(struct pencil_save_context *context, group = true; object->type = drawfile_TYPE_GROUP; object->size = 36; - strncpy(object->data.group.name, item->group_name, 12); - for (i = strlen(item->group_name); i < 12; i++) + i = strlen(item->group_name); + memcpy(object->data.group.name, item->group_name, + (i < 12) ? i : 12); + for (; i < 12; i++) object->data.group.name[i] = ' '; object->data.group.bbox.x0 = item->bbox.x0; object->data.group.bbox.y0 = item->bbox.y0; @@ -383,7 +388,7 @@ void pencil_save_pass2(struct pencil_save_context *context, item->x, item->y, pencil_save_pass2_text_callback, context); if (code != rufl_OK) - context->code = code; + context->code = (pencil_code) code; if (context->code != pencil_OK) return; break; @@ -470,14 +475,14 @@ void pencil_save_pass2(struct pencil_save_context *context, void pencil_save_pass2_text_callback(void *c, const char *font_name, unsigned int font_size, - const char *s8, unsigned short *s16, unsigned int n, + const uint8_t *s8, const uint32_t *s32, unsigned int n, int x, int y) { struct pencil_save_context *context = c; drawfile_object *object = (drawfile_object *) context->b; unsigned int i; - assert(s8 || s16); + assert(s8 || s32); /* find font index */ for (i = 0; i != context->font_count && @@ -506,24 +511,30 @@ void pencil_save_pass2_text_callback(void *c, object->data.trfm_text.base.y = y * 256; if (s8) { - strncpy(object->data.trfm_text.text, s8, n); + strncpy(object->data.trfm_text.text, (const char *) s8, n); object->size = 24 + 56 + ((n + 4) & ~3); } else { char *z = object->data.trfm_text.text; unsigned int utf8_length = 0; for (i = 0; i != n; i++) { - if (s16[i] < 0x80) { - *z++ = s16[i]; + if (s32[i] < 0x80) { + *z++ = s32[i]; utf8_length += 1; - } else if (s16[i] < 0x800) { - *z++ = 0xc0 | ((s16[i] >> 6) & 0x1f); - *z++ = 0x80 | (s16[i] & 0x3f); + } else if (s32[i] < 0x800) { + *z++ = 0xc0 | ((s32[i] >> 6) & 0x1f); + *z++ = 0x80 | (s32[i] & 0x3f); utf8_length += 2; - } else { - *z++ = 0xe0 | (s16[i] >> 12); - *z++ = 0x80 | ((s16[i] >> 6) & 0x3f); - *z++ = 0x80 | (s16[i] & 0x3f); + } else if (s32[i] < 0x10000) { + *z++ = 0xe0 | (s32[i] >> 12); + *z++ = 0x80 | ((s32[i] >> 6) & 0x3f); + *z++ = 0x80 | (s32[i] & 0x3f); utf8_length += 3; + } else { + *z++ = 0xf0 | (s32[i] >> 18); + *z++ = 0x80 | ((s32[i] >> 12) & 0x3f); + *z++ = 0x80 | ((s32[i] >> 6) & 0x3f); + *z++ = 0x80 | (s32[i] & 0x3f); + utf8_length += 4; } } object->size = 24 + 56 + ((utf8_length + 4) & ~3); diff --git a/test/pencil_test.c b/test/pencil_test.c index 04522ee..3113f1a 100644 --- a/test/pencil_test.c +++ b/test/pencil_test.c @@ -9,6 +9,7 @@ #include <stdio.h> #include <oslib/osfile.h> #include <oslib/osspriteop.h> +#include <oslib/squash.h> #include <rufl.h> #include "pencil.h" @@ -46,12 +47,13 @@ void test_pencil(void) pencil_code code; int path[] = {2, 100, 40, 8, 100, 400, 8, 300, 300, 0}; char utf8_test[] = "Hello, world! ὕαλον " - "Uherské Hradiště. 𐀀"; + "Uherské Hradiště. 𐀀\xf0\xa0\x80\xa1"; char *drawfile_buffer; size_t drawfile_size; os_error *error; fileswitch_object_type obj_type; int size; + bits load; osspriteop_area *area; diagram = pencil_create(); @@ -94,7 +96,7 @@ void test_pencil(void) return; } - error = xosfile_read_no_path(SPRITE, &obj_type, 0, 0, &size, 0); + error = xosfile_read_no_path(SPRITE, &obj_type, &load, 0, &size, 0); if (error) { printf("xosfile_read_no_path failed: 0x%x: %s\n", error->errnum, error->errmess); @@ -104,23 +106,121 @@ void test_pencil(void) printf("File " SPRITE " does not exist\n"); return; } - - area = malloc(size + 4); - if (!area) { - printf("Out of memory\n"); + if ((load & 0xfff00000) != 0xfff00000 || + ((load & 0xfff00) != 0xff900 && + (load & 0xfff00) != 0xfca00)) { + printf("File " SPRITE " is not a sprite file\n"); return; } - area->size = size + 4; - area->sprite_count = 0; - area->first = 0; - area->used = 16; - error = xosspriteop_load_sprite_file(osspriteop_USER_AREA, - area, SPRITE); - if (error) { - printf("xosspriteop_load_sprite_file failed: 0x%x: %s\n", - error->errnum, error->errmess); - return; + if ((load & 0xfff00) == 0xfca00) { + /* File is squashed */ + squash_output_status status; + struct squash_file_base sf; + char *buf, *ws; + int wslen; + FILE *fp; + + fp = fopen(SPRITE, "r"); + if (!fp) { + printf("Failed opening " SPRITE "\n"); + return; + } + if (fread(&sf, 1, sizeof(sf), fp) != sizeof(sf)) { + printf("Failed loading squash header\n"); + fclose(fp); + return; + } + if ((sf.load_addr & 0xffffff00) != 0xfffff900) { + printf("File " SPRITE " is not a sprite file\n"); + fclose(fp); + return; + } + + buf = malloc(size - sizeof(sf)); + if (!buf) { + printf("Out of memory\n"); + fclose(fp); + return; + } + if (fread(buf, 1, size - sizeof(sf), fp) != size - sizeof(sf)) { + printf("Failed reading squashed data\n"); + free(buf); + fclose(fp); + return; + } + + error = xsquash_decompress_return_sizes(size - sizeof(sf), + &wslen, NULL); + if (error) { + printf("xsquash_decompress_return_sizes failed: 0x%x: %s\n", + error->errnum, error->errmess); + free(buf); + fclose(fp); + return; + } + + ws = malloc(wslen); + if (!ws) { + printf("Out of memory\n"); + free(buf); + fclose(fp); + return; + } + + area = malloc(sf.size + 4); + if (!area) { + printf("Out of memory\n"); + free(ws); + free(buf); + fclose(fp); + return; + } + area->size = sf.size + 4; + + error = xsquash_decompress(squash_INPUT_ALL_PRESENT, ws, + (byte *) buf, size - sizeof(sf), + (byte *) &area->sprite_count, sf.size, + &status, NULL, NULL, NULL, NULL); + if (error) { + printf("xsquash_decompress failed: 0x%x: %s\n", + error->errnum, error->errmess); + free(area); + free(ws); + free(buf); + fclose(fp); + return; + } + if (status != 0) { + printf("xsquash_decompress did not complete: %x\n", status); + free(area); + free(ws); + free(buf); + fclose(fp); + return; + } + + free(ws); + free(buf); + fclose(fp); + } else { + area = malloc(size + 4); + if (!area) { + printf("Out of memory\n"); + return; + } + area->size = size + 4; + area->sprite_count = 0; + area->first = 0; + area->used = 16; + + error = xosspriteop_load_sprite_file(osspriteop_USER_AREA, + area, SPRITE); + if (error) { + printf("xosspriteop_load_sprite_file failed: 0x%x: %s\n", + error->errnum, error->errmess); + return; + } } code = pencil_sprite(diagram, 400, 200, 200, 100, |