summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Bursa <james@netsurf-browser.org>2005-11-24 23:45:33 +0000
committerJames Bursa <james@netsurf-browser.org>2005-11-24 23:45:33 +0000
commit2307ea0cd73b0506f032e7ea6656ae1aec19dab7 (patch)
tree446b8c752d5529cf4fdd1e4836e5d90f6d68b25a
parent6cad5b08da9bfe1a8bc0a2afc1a0c543eae558ed (diff)
downloadlibpencil-2307ea0cd73b0506f032e7ea6656ae1aec19dab7.tar.gz
libpencil-2307ea0cd73b0506f032e7ea6656ae1aec19dab7.tar.bz2
[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
-rw-r--r--pencil.h3
-rw-r--r--pencil_build.c26
-rw-r--r--pencil_internal.h5
-rw-r--r--pencil_save.c45
-rw-r--r--pencil_test.c45
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 <stdio.h>
#include <string.h>
#include <oslib/drawfile.h>
+#include <oslib/osspriteop.h>
#include <rufl.h>
#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 <assert.h>
#include <stdio.h>
#include <oslib/osfile.h>
+#include <oslib/osspriteop.h>
#include <rufl.h>
#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);
}