From dfce56be0d92c9859cb6ee5462dc7ce695311d8d Mon Sep 17 00:00:00 2001 From: James Bursa Date: Sun, 20 Nov 2005 20:04:28 +0000 Subject: [project @ 2005-11-20 20:04:28 by bursa] Initial revision svn path=/import/pencil/; revision=2475 --- makefile | 27 ++++ pencil.h | 86 ++++++++++++ pencil_build.c | 239 ++++++++++++++++++++++++++++++++ pencil_internal.h | 61 +++++++++ pencil_save.c | 400 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ pencil_test.c | 104 ++++++++++++++ 6 files changed, 917 insertions(+) create mode 100644 makefile create mode 100644 pencil.h create mode 100644 pencil_build.c create mode 100644 pencil_internal.h create mode 100644 pencil_save.c create mode 100644 pencil_test.c diff --git a/makefile b/makefile new file mode 100644 index 0000000..5160b9d --- /dev/null +++ b/makefile @@ -0,0 +1,27 @@ +# +# This file is part of Pencil +# Licensed under the MIT License, +# http://www.opensource.org/licenses/mit-license +# Copyright 2005 James Bursa +# + +SOURCE = pencil_build.c pencil_save.c + +CC = /home/riscos/cross/bin/gcc +CFLAGS = -std=c99 -O3 -W -Wall -Wundef -Wpointer-arith -Wcast-qual \ + -Wcast-align -Wwrite-strings -Wstrict-prototypes \ + -Wmissing-prototypes -Wmissing-declarations \ + -Wnested-externs -Winline -Wno-cast-align \ + -mpoke-function-name -I/home/riscos/env/include +LIBS = -L/home/riscos/env/lib -loslib -lrufl + +all: pencil.o pencil_test,ff8 + +pencil.o: $(SOURCE) pencil.h pencil_internal.h + $(CC) $(CFLAGS) -c -o $@ $(SOURCE) + +pencil_test,ff8: pencil_test.c pencil.o + $(CC) $(CFLAGS) $(LIBS) -o $@ $^ + +clean: + -rm pencil.o pencil_test,ff8 diff --git a/pencil.h b/pencil.h new file mode 100644 index 0000000..0b6e108 --- /dev/null +++ b/pencil.h @@ -0,0 +1,86 @@ +/* + * This file is part of Pencil + * Licensed under the MIT License, + * http://www.opensource.org/licenses/mit-license + * Copyright 2005 James Bursa + */ + +#ifndef PENCIL_H +#define PENCIL_H + +#include +#include +#include "rufl.h" + + +struct pencil_diagram; + + +typedef enum { + pencil_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, + pencil_IO_ERROR = rufl_IO_ERROR, + pencil_IO_EOF = rufl_IO_EOF, +} pencil_code; + +/** A colour as 0xRRGGBB. */ +typedef uint32_t pencil_colour; + +#define pencil_TRANSPARENT 0xffffffff + +typedef enum { + pencil_JOIN_MITRED, + pencil_JOIN_ROUND, + pencil_JOIN_BEVELLED, +} pencil_join; + +typedef enum { + pencil_CAP_BUTT, + pencil_CAP_ROUND, + pencil_CAP_SQUARE, + pencil_CAP_TRIANGLE, +} pencil_cap; + +typedef enum { + pencil_SOLID, + pencil_DOTTED, + pencil_DASHED, +} pencil_pattern; + + +struct pencil_diagram *pencil_create(void); + +pencil_code pencil_text(struct pencil_diagram *diagram, + int x, int y, + const char *font_family, rufl_style font_style, + unsigned int font_size, + const char *string, size_t length, + pencil_colour colour); +pencil_code pencil_path(struct pencil_diagram *diagram, + const int *path, unsigned int n, + pencil_colour fill_colour, pencil_colour outline_colour, + int thickness, pencil_join join, + pencil_cap start_cap, pencil_cap end_cap, + int cap_width, int cap_length, + bool even_odd, pencil_pattern pattern); + +pencil_code pencil_group_start(struct pencil_diagram *diagram, + const char *name); +pencil_code pencil_group_end(struct pencil_diagram *diagram); + +pencil_code pencil_clip_start(struct pencil_diagram *diagram, + int x0, int y0, int x1, int y1); +pencil_code pencil_clip_end(struct pencil_diagram *diagram); + +pencil_code pencil_save_drawfile(struct pencil_diagram *diagram, + const char *source, + char **drawfile_buffer, size_t *drawfile_size); + +void pencil_free(struct pencil_diagram *diagram); + +void pencil_dump(struct pencil_diagram *diagram); + + +#endif diff --git a/pencil_build.c b/pencil_build.c new file mode 100644 index 0000000..d550f95 --- /dev/null +++ b/pencil_build.c @@ -0,0 +1,239 @@ +/* + * This file is part of Pencil + * Licensed under the MIT License, + * http://www.opensource.org/licenses/mit-license + * Copyright 2005 James Bursa + */ + +#define _GNU_SOURCE /* for strndup */ +#include +#include +#include +#include +#include "pencil_internal.h" + + +static struct pencil_item *pencil_new_item(pencil_item_type type); +static void pencil_append_child(struct pencil_item *group, + struct pencil_item *child); +static void pencil_free_item(struct pencil_item *item); +static void pencil_dump_item(struct pencil_item *item, unsigned int depth); + + +struct pencil_diagram *pencil_create(void) +{ + struct pencil_diagram *diagram; + struct pencil_item *root_group; + + diagram = malloc(sizeof *diagram); + root_group = pencil_new_item(pencil_GROUP); + if (!diagram || !root_group) { + free(root_group); + free(diagram); + return 0; + } + + diagram->root = root_group; + diagram->current_group = root_group; + + return diagram; +} + + +pencil_code pencil_text(struct pencil_diagram *diagram, + int x, int y, + const char *font_family, rufl_style font_style, + unsigned int font_size, + const char *string, size_t length, + pencil_colour colour) +{ + struct pencil_item *item; + + item = pencil_new_item(pencil_TEXT); + if (!item) + return pencil_OUT_OF_MEMORY; + + item->x = x; + item->y = y; + item->fill_colour = colour; + item->font_family = font_family; + item->font_style = font_style; + item->font_size = font_size; + item->text = strndup(string, length); + if (!item->text) { + free(item); + return pencil_OUT_OF_MEMORY; + } + + pencil_append_child(diagram->current_group, item); + + return pencil_OK; +} + + +pencil_code pencil_path(struct pencil_diagram *diagram, + const int *path, unsigned int n, + pencil_colour fill_colour, pencil_colour outline_colour, + int thickness, pencil_join join, + pencil_cap start_cap, pencil_cap end_cap, + int cap_width, int cap_length, + bool even_odd, pencil_pattern pattern) + +{ + struct pencil_item *item; + + item = pencil_new_item(pencil_PATH); + if (!item) + return pencil_OUT_OF_MEMORY; + + item->fill_colour = fill_colour; + item->outline_colour = outline_colour; + item->path = malloc(sizeof path[0] * n); + if (!item->path) { + free(item); + return pencil_OUT_OF_MEMORY; + } + memcpy(item->path, path, sizeof path[0] * n); + item->path_size = n; + item->thickness = thickness; + item->join = join; + item->start_cap = start_cap; + item->end_cap = end_cap; + item->cap_width = cap_width; + item->cap_length = cap_length; + item->even_odd = even_odd; + item->pattern = pattern; + + pencil_append_child(diagram->current_group, item); + + return pencil_OK; +} + + +pencil_code pencil_group_start(struct pencil_diagram *diagram, + const char *name) +{ + struct pencil_item *item; + + item = pencil_new_item(pencil_GROUP); + if (!item) + return pencil_OUT_OF_MEMORY; + + item->group_name = strdup(name); + if (!item->group_name) { + free(item); + return pencil_OUT_OF_MEMORY; + } + + pencil_append_child(diagram->current_group, item); + + diagram->current_group = item; + + return pencil_OK; +} + + +pencil_code pencil_group_end(struct pencil_diagram *diagram) +{ + diagram->current_group = diagram->current_group->parent; + + return pencil_OK; +} + + +struct pencil_item *pencil_new_item(pencil_item_type type) +{ + struct pencil_item *item; + + item = malloc(sizeof *item); + if (!item) + return 0; + + item->type = type; + item->group_name = 0; + item->text = 0; + item->path = 0; + item->parent = item->next = item->children = item->last = 0; + + return item; +} + + +void pencil_append_child(struct pencil_item *group, + struct pencil_item *child) +{ + child->parent = group; + if (group->children) { + assert(group->last); + group->last->next = child; + } else { + group->children = child; + } + group->last = child; +} + + +void pencil_free(struct pencil_diagram *diagram) +{ + pencil_free_item(diagram->root); + free(diagram); +} + + +void pencil_free_item(struct pencil_item *item) +{ + for (struct pencil_item *child = item->children; child; + child = child->next) + pencil_free_item(child); + free(item->group_name); + free(item->text); + free(item->path); + free(item); +} + + +void pencil_dump(struct pencil_diagram *diagram) +{ + printf("diagram %p: current group %p\n", + diagram, diagram->current_group); + pencil_dump_item(diagram->root, 0); +} + + +void pencil_dump_item(struct pencil_item *item, unsigned int depth) +{ + for (unsigned int i = 0; i != depth; i++) + printf(" "); + + printf("%p ", item); + switch (item->type) { + case pencil_GROUP: + printf("GROUP"); + break; + case pencil_TEXT: + printf("TEXT (%i %i) font %s %i %i, text \"%s\"", + item->x, item->y, + item->font_family, item->font_style, + item->font_size, item->text); + break; + case pencil_PATH: + printf("PATH ("); + for (unsigned int i = 0; i != item->path_size; i++) + printf("%i ", item->path[i]); + printf(") thickness %i, join %i, caps %i %i %i %i, ", + item->thickness, item->join, + item->start_cap, item->end_cap, + item->cap_width, item->cap_length); + if (item->even_odd) + printf("even-odd, "); + printf("pattern %i", item->pattern); + break; + default: + printf("UNKNOWN"); + } + printf("\n"); + + for (struct pencil_item *child = item->children; child; + child = child->next) + pencil_dump_item(child, depth + 1); +} diff --git a/pencil_internal.h b/pencil_internal.h new file mode 100644 index 0000000..0081ccc --- /dev/null +++ b/pencil_internal.h @@ -0,0 +1,61 @@ +/* + * This file is part of Pencil + * Licensed under the MIT License, + * http://www.opensource.org/licenses/mit-license + * Copyright 2005 James Bursa + */ + +#ifndef PENCIL_INTERNAL_H +#define PENCIL_INTERNAL_H + +#include +#include "pencil.h" + + +struct pencil_item; + + +struct pencil_diagram { + struct pencil_item *root; + struct pencil_item *current_group; +}; + +typedef enum { + pencil_GROUP, + pencil_TEXT, + pencil_PATH, +} pencil_item_type; + +struct pencil_item { + pencil_item_type type; + + pencil_colour fill_colour; + pencil_colour outline_colour; + + char *group_name; + + int x, y; + const char *font_family; + rufl_style font_style; + unsigned int font_size; + char *text; + + int *path; + unsigned int path_size; + int thickness; + pencil_join join; + pencil_cap start_cap; + pencil_cap end_cap; + int cap_width; + int cap_length; + bool even_odd; + pencil_pattern pattern; + + struct pencil_item *parent; + struct pencil_item *next; + struct pencil_item *children; + struct pencil_item *last; +}; + + +#endif diff --git a/pencil_save.c b/pencil_save.c new file mode 100644 index 0000000..3d33950 --- /dev/null +++ b/pencil_save.c @@ -0,0 +1,400 @@ +/* + * This file is part of Pencil + * Licensed under the MIT License, + * http://www.opensource.org/licenses/mit-license + * Copyright 2005 James Bursa + */ + +/** \file + * Saving as a DrawFile (implementation). + * + * Two passes over the diagram tree are made. The first pass computes the size + * that will be required and enumerates the fonts. The second pass creates the + * DrawFile in a buffer. + */ + +#define _GNU_SOURCE /* for strndup */ +#include +#include +#include +#include +#include +#include +#include +#include "pencil_internal.h" + + +struct pencil_save_context { + pencil_code code; + struct pencil_diagram *diagram; + size_t size; + char **font_list; + unsigned int font_count; + struct pencil_item *item; + char *buffer; + char *b; +}; + + +static void pencil_save_pass1(struct pencil_save_context *context, + struct pencil_item *item); +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); +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, + int x, int y); + + +pencil_code pencil_save_drawfile(struct pencil_diagram *diagram, + const char *source, + char **drawfile_buffer, size_t *drawfile_size) +{ + struct pencil_save_context context = + { pencil_OK, diagram, 0, 0, 0, 0, 0, 0 }; + unsigned int i; + size_t size, font_table_size; + char *buffer; + drawfile_diagram *header; + drawfile_object *font_table; + char *b, *f; + + *drawfile_buffer = 0; + *drawfile_size = 0; + + /* pass 1 */ + pencil_save_pass1(&context, diagram->root); + if (context.code != pencil_OK) { + for (i = 0; i != context.font_count; i++) + free(context.font_list[i]); + free(context.font_list); + return context.code; + } + + /* find font table size */ + font_table_size = 8; + for (i = 0; i != context.font_count; i++) + font_table_size += 1 + strlen(context.font_list[i]) + 1; + font_table_size = (font_table_size + 3) & ~3; + + size = 40 + font_table_size + context.size; + + /* use calloc to prevent information leakage */ + buffer = calloc(size, 1); + if (!buffer) { + for (i = 0; i != context.font_count; i++) + free(context.font_list[i]); + free(context.font_list); + return pencil_OUT_OF_MEMORY; + } + + /* file headers */ + header = (drawfile_diagram *) buffer; + header->tag[0] = 'D'; + header->tag[1] = 'r'; + header->tag[2] = 'a'; + header->tag[3] = 'w'; + header->major_version = 201; + header->minor_version = 0; + strncpy(header->source, source, 12); + for (i = strlen(source); i < 12; i++) + header->source[i] = ' '; + b = buffer + 40; + + /* font table */ + font_table = (drawfile_object *) b; + font_table->type = drawfile_TYPE_FONT_TABLE; + font_table->size = font_table_size; + f = b + 8; + for (i = 0; i != context.font_count; i++) { + *f++ = i + 1; + strcpy(f, context.font_list[i]); + f += strlen(context.font_list[i]) + 1; + } + b += font_table_size; + + /* pass 2 */ + context.buffer = buffer; + context.b = b; + pencil_save_pass2(&context, diagram->root); + + /* free font list */ + for (i = 0; i != context.font_count; i++) + free(context.font_list[i]); + free(context.font_list); + + if (context.code != pencil_OK) { + free(buffer); + return context.code; + } + + assert(context.b == buffer + size); + + *drawfile_buffer = buffer; + *drawfile_size = size; + return pencil_OK; +} + + +void pencil_save_pass1(struct pencil_save_context *context, + struct pencil_item *item) +{ + rufl_code code; + struct pencil_item *child; + + assert(item); + + switch (item->type) { + case pencil_GROUP: + context->size += 36; + break; + case pencil_TEXT: + code = rufl_paint_callback(item->font_family, item->font_style, + item->font_size, item->text, strlen(item->text), + item->x, item->y, + pencil_save_pass1_text_callback, context); + if (code != rufl_OK) + context->code = code; + if (context->code != pencil_OK) + return; + break; + case pencil_PATH: + context->size += 24 + 16 + item->path_size * 4; + if (item->pattern != pencil_SOLID) + context->size += 12; + break; + default: + assert(0); + } + + for (child = item->children; child; child = child->next) { + pencil_save_pass1(context, child); + if (context->code != pencil_OK) + return; + } +} + + +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) +{ + struct pencil_save_context *context = c; + unsigned int i; + char **font_list; + + (void) font_size; /* unused */ + (void) x; /* unused */ + (void) y; /* unused */ + + assert(s8 || s16); + + /* check if the font name is new */ + for (i = 0; i != context->font_count && + strcmp(context->font_list[i], font_name) != 0; i++) + ; + if (i == context->font_count) { + /* add to list of fonts */ + font_list = realloc(context->font_list, + sizeof context->font_list[0] * + (context->font_count + 1)); + if (!font_list) { + context->code = pencil_OUT_OF_MEMORY; + return; + } + font_list[context->font_count] = strdup(font_name); + if (!font_list[context->font_count]) { + context->code = pencil_OUT_OF_MEMORY; + return; + } + context->font_list = font_list; + context->font_count++; + } + + /* compute size of transformed text object */ + if (s8) { + context->size += 24 + 56 + ((n + 4) & ~3); + } else { + unsigned int utf8_length = 0; + for (i = 0; i != n; i++) { + if (s16[i] < 0x80) + utf8_length += 1; + else if (s16[i] < 0x800) + utf8_length += 2; + else + utf8_length += 3; + } + context->size += 24 + 56 + ((utf8_length + 4) & ~3); + } +} + + +void pencil_save_pass2(struct pencil_save_context *context, + struct pencil_item *item) +{ + drawfile_object *object = (drawfile_object *) context->b; + rufl_code code; + int *path; + unsigned int i; + struct pencil_item *child; + + assert(item); + + switch (item->type) { + case pencil_GROUP: + 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++) + object->data.group.name[i] = ' '; + context->b += object->size; + break; + case pencil_TEXT: + context->item = item; + code = rufl_paint_callback(item->font_family, item->font_style, + item->font_size, item->text, strlen(item->text), + item->x, item->y, + pencil_save_pass2_text_callback, context); + if (code != rufl_OK) + context->code = code; + if (context->code != pencil_OK) + return; + break; + case pencil_PATH: + object->type = drawfile_TYPE_PATH; + object->size = 24 + 16 + item->path_size * 4; + object->data.path.bbox.x0 = 0; + object->data.path.bbox.y0 = 0; + object->data.path.bbox.x1 = 0; + object->data.path.bbox.y1 = 0; + object->data.path.fill = item->fill_colour; + object->data.path.outline = item->outline_colour; + object->data.path.width = item->thickness * 256; + object->data.path.style.flags = 0; + object->data.path.style.cap_width = item->cap_width; + object->data.path.style.cap_length = item->cap_length; + if (item->pattern != pencil_SOLID) { + object->size += 12; + object->data.path_with_pattern.pattern.start = 0; + object->data.path_with_pattern.pattern. + element_count = 1; + if (item->pattern != pencil_DOTTED) + object->data.path_with_pattern.pattern. + elements[0] = 512 * item->thickness; + else if (item->pattern != pencil_DASHED) + object->data.path_with_pattern.pattern. + elements[0] = 1536 * item->thickness; + } + path = (int *) (context->b + object->size - + item->path_size * 4); + for (i = 0; i != item->path_size; ) { + switch (item->path[i]) { + case 0: + case 5: + path[i] = item->path[i]; i++; + break; + case 2: + case 8: + path[i] = item->path[i]; i++; + path[i] = item->path[i] * 256; i++; + path[i] = item->path[i] * 256; i++; + break; + case 6: + path[i] = item->path[i]; i++; + path[i] = item->path[i] * 256; i++; + path[i] = item->path[i] * 256; i++; + path[i] = item->path[i] * 256; i++; + path[i] = item->path[i] * 256; i++; + path[i] = item->path[i] * 256; i++; + path[i] = item->path[i] * 256; i++; + break; + default: + assert(0); + } + } + context->b += object->size; + break; + default: + assert(0); + } + + for (child = item->children; child; child = child->next) { + pencil_save_pass2(context, child); + if (context->code != pencil_OK) + return; + } + + if (item->type == pencil_GROUP) { + object->size = context->b - (char *) object; + } +} + + +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, + int x, int y) +{ + struct pencil_save_context *context = c; + drawfile_object *object = (drawfile_object *) context->b; + unsigned int i; + + assert(s8 || s16); + + /* find font index */ + for (i = 0; i != context->font_count && + strcmp(context->font_list[i], font_name) != 0; i++) + ; + assert(i != context->font_count); + + object->type = drawfile_TYPE_TRFM_TEXT; + object->data.trfm_text.bbox.x0 = x * 256; + object->data.trfm_text.bbox.y0 = y * 256; + object->data.trfm_text.bbox.x1 = x * 256; + object->data.trfm_text.bbox.y1 = y * 256; + object->data.trfm_text.trfm.entries[0][0] = 0x10000; + object->data.trfm_text.trfm.entries[0][1] = 0; + object->data.trfm_text.trfm.entries[1][0] = 0; + object->data.trfm_text.trfm.entries[1][1] = 0x10000; + object->data.trfm_text.trfm.entries[2][0] = 0; + object->data.trfm_text.trfm.entries[2][1] = 0; + object->data.trfm_text.flags = drawfile_TEXT_KERN; + object->data.trfm_text.fill = context->item->fill_colour; + object->data.trfm_text.bg_hint = os_COLOUR_WHITE; + object->data.trfm_text.style.font_index = i + 1; + object->data.trfm_text.xsize = font_size * 40; + object->data.trfm_text.ysize = font_size * 40; + object->data.trfm_text.base.x = x * 256; + object->data.trfm_text.base.y = y * 256; + + if (s8) { + strncpy(object->data.trfm_text.text, 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]; + utf8_length += 1; + } else if (s16[i] < 0x800) { + *z++ = 0xc0 | ((s16[i] >> 6) & 0x1f); + *z++ = 0x80 | (s16[i] & 0x3f); + utf8_length += 2; + } else { + *z++ = 0xe0 | (s16[i] >> 12); + *z++ = 0x80 | ((s16[i] >> 6) & 0x3f); + *z++ = 0x80 | (s16[i] & 0x3f); + utf8_length += 3; + } + } + object->size = 24 + 56 + ((utf8_length + 4) & ~3); + } + + context->b += object->size; +} diff --git a/pencil_test.c b/pencil_test.c new file mode 100644 index 0000000..b1c26d4 --- /dev/null +++ b/pencil_test.c @@ -0,0 +1,104 @@ +/* + * This file is part of Pencil + * Licensed under the MIT License, + * http://www.opensource.org/licenses/mit-license + * Copyright 2005 James Bursa + */ + +#include +#include +#include +#include +#include "pencil.h" + + +static void test_pencil(void); + + +int main(int argc, char *argv[]) +{ + rufl_code code; + + code = rufl_init(); + if (code != rufl_OK) { + printf("rufl_init failed: %i\n", code); + return 1; + } + + test_pencil(); + + rufl_quit(); + + return 0; +} + + +void test_pencil(void) +{ + struct pencil_diagram *diagram; + pencil_code code; + int path[] = {2, 100, 40, 8, 100, 400, 8, 300, 300, 0}; + char utf8_test[] = "Hello, world! ὕαλον " + "Uherské Hradiště. 𐀀"; + char *drawfile_buffer; + size_t drawfile_size; + os_error *error; + + diagram = pencil_create(); + if (!diagram) { + printf("pencil_create failed\n"); + return; + } + + code = pencil_text(diagram, + 100, 40, + "Homerton", rufl_REGULAR, + 320, + "Hello, world!", 13, + 0x000000); + if (code != pencil_OK) { + printf("pencil_text failed: %i\n", code); + return; + } + + code = pencil_path(diagram, + path, sizeof path / sizeof path[0], + 0x00ff00, 0x0000ff, + 5, pencil_JOIN_ROUND, + pencil_CAP_BUTT, pencil_CAP_TRIANGLE, + 15, 20, + false, pencil_SOLID); + if (code != pencil_OK) { + printf("pencil_path failed: %i\n", code); + return; + } + + code = pencil_text(diagram, + 100, 400, + "NewHall", rufl_REGULAR, + 320, + utf8_test, sizeof utf8_test, + 0xff0000); + if (code != pencil_OK) { + printf("pencil_text failed: %i\n", code); + return; + } + + pencil_dump(diagram); + + code = pencil_save_drawfile(diagram, "Pencil-Test", + &drawfile_buffer, &drawfile_size); + if (code != pencil_OK) { + printf("pencil_save_drawfile failed: %i\n", code); + return; + } + assert(drawfile_buffer); + + error = xosfile_save_stamped("DrawFile", osfile_TYPE_DRAW, + drawfile_buffer, drawfile_buffer + drawfile_size); + if (error) { + printf("xosfile_save_stamped failed: 0x%x: %s\n", + error->errnum, error->errmess); + return; + } +} -- cgit v1.2.3