summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile19
-rw-r--r--include/pencil.h2
-rw-r--r--src/pencil_save.c71
-rw-r--r--test/pencil_test.c132
4 files changed, 168 insertions, 56 deletions
diff --git a/Makefile b/Makefile
index 81dd4c0..290d952 100644
--- a/Makefile
+++ b/Makefile
@@ -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,