From 2307ea0cd73b0506f032e7ea6656ae1aec19dab7 Mon Sep 17 00:00:00 2001 From: James Bursa Date: Thu, 24 Nov 2005 23:45:33 +0000 Subject: [project @ 2005-11-24 23:45:33 by bursa] Implement pencil_sprite(). Add a maximum grouping depth for DrawFiles. svn path=/import/pencil/; revision=2477 --- pencil.h | 3 +++ pencil_build.c | 26 ++++++++++++++++++++++++++ pencil_internal.h | 5 +++++ pencil_save.c | 45 +++++++++++++++++++++++++++++++++++---------- pencil_test.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 114 insertions(+), 10 deletions(-) diff --git a/pencil.h b/pencil.h index 315f282..9205d5a 100644 --- a/pencil.h +++ b/pencil.h @@ -65,6 +65,9 @@ pencil_code pencil_path(struct pencil_diagram *diagram, pencil_cap start_cap, pencil_cap end_cap, int cap_width, int cap_length, bool even_odd, pencil_pattern pattern); +pencil_code pencil_sprite(struct pencil_diagram *diagram, + int x, int y, int width, int height, + const char *sprite); pencil_code pencil_group_start(struct pencil_diagram *diagram, const char *name); diff --git a/pencil_build.c b/pencil_build.c index 7e90123..4b411e5 100644 --- a/pencil_build.c +++ b/pencil_build.c @@ -117,6 +117,28 @@ pencil_code pencil_path(struct pencil_diagram *diagram, } +pencil_code pencil_sprite(struct pencil_diagram *diagram, + int x, int y, int width, int height, + const char *sprite) +{ + struct pencil_item *item; + + item = pencil_new_item(pencil_SPRITE); + if (!item) + return pencil_OUT_OF_MEMORY; + + item->x = x; + item->y = y; + item->width = width; + item->height = height; + item->sprite = sprite; + + pencil_append_child(diagram->current_group, item); + + return pencil_OK; +} + + pencil_code pencil_group_start(struct pencil_diagram *diagram, const char *name) { @@ -235,6 +257,10 @@ void pencil_dump_item(struct pencil_item *item, unsigned int depth) printf("even-odd, "); printf("pattern %i", item->pattern); break; + case pencil_SPRITE: + printf("SPRITE (%i %i) (%i x %i)\n", item->x, item->y, + item->width, item->height); + break; default: printf("UNKNOWN"); } diff --git a/pencil_internal.h b/pencil_internal.h index 0081ccc..21579a6 100644 --- a/pencil_internal.h +++ b/pencil_internal.h @@ -24,6 +24,7 @@ typedef enum { pencil_GROUP, pencil_TEXT, pencil_PATH, + pencil_SPRITE, } pencil_item_type; struct pencil_item { @@ -35,6 +36,7 @@ struct pencil_item { char *group_name; int x, y; + const char *font_family; rufl_style font_style; unsigned int font_size; @@ -51,6 +53,9 @@ struct pencil_item { bool even_odd; pencil_pattern pattern; + int width, height; + const char *sprite; + struct pencil_item *parent; struct pencil_item *next; struct pencil_item *children; diff --git a/pencil_save.c b/pencil_save.c index 3d33950..cc40c74 100644 --- a/pencil_save.c +++ b/pencil_save.c @@ -20,9 +20,13 @@ #include #include #include +#include #include #include "pencil_internal.h" +/* Maximum grouping depth (too deep crashes Draw). */ +#define MAX_DEPTH 10 + struct pencil_save_context { pencil_code code; @@ -37,13 +41,13 @@ struct pencil_save_context { static void pencil_save_pass1(struct pencil_save_context *context, - struct pencil_item *item); + 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, int x, int y); static void pencil_save_pass2(struct pencil_save_context *context, - struct pencil_item *item); + 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, @@ -67,7 +71,7 @@ pencil_code pencil_save_drawfile(struct pencil_diagram *diagram, *drawfile_size = 0; /* pass 1 */ - pencil_save_pass1(&context, diagram->root); + pencil_save_pass1(&context, diagram->root, 0); if (context.code != pencil_OK) { for (i = 0; i != context.font_count; i++) free(context.font_list[i]); @@ -120,7 +124,7 @@ pencil_code pencil_save_drawfile(struct pencil_diagram *diagram, /* pass 2 */ context.buffer = buffer; context.b = b; - pencil_save_pass2(&context, diagram->root); + pencil_save_pass2(&context, diagram->root, 0); /* free font list */ for (i = 0; i != context.font_count; i++) @@ -141,7 +145,7 @@ pencil_code pencil_save_drawfile(struct pencil_diagram *diagram, void pencil_save_pass1(struct pencil_save_context *context, - struct pencil_item *item) + struct pencil_item *item, unsigned int depth) { rufl_code code; struct pencil_item *child; @@ -150,6 +154,8 @@ void pencil_save_pass1(struct pencil_save_context *context, switch (item->type) { case pencil_GROUP: + if (!item->children || MAX_DEPTH <= depth) + break; context->size += 36; break; case pencil_TEXT: @@ -167,12 +173,16 @@ void pencil_save_pass1(struct pencil_save_context *context, if (item->pattern != pencil_SOLID) context->size += 12; break; + case pencil_SPRITE: + context->size += 24 + ((const osspriteop_header *) + item->sprite)->size; + break; default: assert(0); } for (child = item->children; child; child = child->next) { - pencil_save_pass1(context, child); + pencil_save_pass1(context, child, depth + 1); if (context->code != pencil_OK) return; } @@ -235,9 +245,10 @@ void pencil_save_pass1_text_callback(void *c, void pencil_save_pass2(struct pencil_save_context *context, - struct pencil_item *item) + struct pencil_item *item, unsigned int depth) { drawfile_object *object = (drawfile_object *) context->b; + bool group = false; rufl_code code; int *path; unsigned int i; @@ -247,6 +258,9 @@ void pencil_save_pass2(struct pencil_save_context *context, switch (item->type) { case pencil_GROUP: + if (!item->children || MAX_DEPTH <= depth) + break; + group = true; object->type = drawfile_TYPE_GROUP; object->size = 36; strncpy(object->data.group.name, item->group_name, 12); @@ -319,19 +333,30 @@ void pencil_save_pass2(struct pencil_save_context *context, } context->b += object->size; break; + case pencil_SPRITE: + object->type = drawfile_TYPE_SPRITE; + object->size = 24 + ((const osspriteop_header *) + item->sprite)->size; + object->data.sprite.bbox.x0 = item->x * 256; + object->data.sprite.bbox.y0 = item->y * 256; + object->data.sprite.bbox.x1 = (item->x + item->width) * 256; + object->data.sprite.bbox.y1 = (item->y + item->height) * 256; + memcpy(&object->data.sprite.header, item->sprite, + object->size - 24); + context->b += object->size; + break; default: assert(0); } for (child = item->children; child; child = child->next) { - pencil_save_pass2(context, child); + pencil_save_pass2(context, child, depth + 1); if (context->code != pencil_OK) return; } - if (item->type == pencil_GROUP) { + if (group) object->size = context->b - (char *) object; - } } diff --git a/pencil_test.c b/pencil_test.c index b1c26d4..19af46b 100644 --- a/pencil_test.c +++ b/pencil_test.c @@ -8,10 +8,14 @@ #include #include #include +#include #include #include "pencil.h" +#define SPRITE "Resources:$.Resources.Desktop.Sprites" + + static void test_pencil(void); @@ -43,6 +47,9 @@ void test_pencil(void) char *drawfile_buffer; size_t drawfile_size; os_error *error; + fileswitch_object_type obj_type; + int size; + osspriteop_area *area; diagram = pencil_create(); if (!diagram) { @@ -84,6 +91,42 @@ void test_pencil(void) return; } + error = xosfile_read_no_path(SPRITE, &obj_type, 0, 0, &size, 0); + if (error) { + printf("xosfile_read_no_path failed: 0x%x: %s\n", + error->errnum, error->errmess); + return; + } + if (obj_type != fileswitch_IS_FILE) { + printf("File " SPRITE " does not exist\n"); + return; + } + + 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, + ((char *) area) + area->first); + if (code != pencil_OK) { + printf("pencil_sprite failed: %i\n", code); + return; + } + pencil_dump(diagram); code = pencil_save_drawfile(diagram, "Pencil-Test", @@ -101,4 +144,6 @@ void test_pencil(void) error->errnum, error->errmess); return; } + + pencil_free(diagram); } -- cgit v1.2.3