diff options
Diffstat (limited to 'src/drv/cdmf.c')
-rw-r--r-- | src/drv/cdmf.c | 1188 |
1 files changed, 1188 insertions, 0 deletions
diff --git a/src/drv/cdmf.c b/src/drv/cdmf.c new file mode 100644 index 0000000..6c2e711 --- /dev/null +++ b/src/drv/cdmf.c @@ -0,0 +1,1188 @@ +/** \file + * \brief CD Metafile driver + * + * See Copyright Notice in cd.h + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> + +#include "cd.h" +#include "wd.h" +#include "cd_private.h" +#include "cdmf.h" +#include "cdmf_private.h" + + +/* codes for the primitives and attributes in the metafile + Can NOT be changed, only added for backward compatibility. +*/ +enum +{ + CDMF_FLUSH, /* 0 */ + CDMF_CLEAR, /* 1 */ + CDMF_CLIP, /* 2 */ + CDMF_CLIPAREA, /* 3 */ + CDMF_LINE, /* 4 */ + CDMF_BOX, /* 5 */ + CDMF_ARC, /* 6 */ + CDMF_SECTOR, /* 7 */ + CDMF_TEXT, /* 8 */ + CDMF_BEGIN, /* 9 */ + CDMF_VERTEX, /* 10 */ + CDMF_END, /* 11 */ + CDMF_MARK, /* 12 */ + CDMF_BACKOPACITY, /* 13 */ + CDMF_WRITEMODE, /* 14 */ + CDMF_LINESTYLE, /* 15 */ + CDMF_LINEWIDTH, /* 16 */ + CDMF_INTERIORSTYLE, /* 17 */ + CDMF_HATCH, /* 18 */ + CDMF_STIPPLE, /* 19 */ + CDMF_PATTERN, /* 20 */ + CDMF_OLDFONT, /* 21 */ + CDMF_NATIVEFONT, /* 22 */ + CDMF_TEXTALIGNMENT, /* 23 */ + CDMF_MARKTYPE, /* 24 */ + CDMF_MARKSIZE, /* 25 */ + CDMF_PALETTE, /* 26 */ + CDMF_BACKGROUND, /* 27 */ + CDMF_FOREGROUND, /* 28 */ + CDMF_PUTIMAGERGB, /* 29 */ + CDMF_PUTIMAGEMAP, /* 30 */ + CDMF_PIXEL, /* 31 */ + CDMF_SCROLLAREA, /* 32 */ + CDMF_TEXTORIENTATION, /* 33 */ + CDMF_RECT, /* 34 */ + CDMF_PUTIMAGERGBA, /* 35 */ + CDMF_WLINE, /* 36 */ + CDMF_WRECT, /* 37 */ + CDMF_WBOX, /* 38 */ + CDMF_WARC, /* 39 */ + CDMF_WSECTOR, /* 40 */ + CDMF_WTEXT, /* 41 */ + CDMF_WVERTEX, /* 42 */ + CDMF_WMARK, /* 43 */ + CDMF_VECTORTEXT, /* 44 */ + CDMF_MULTILINEVECTORTEXT, /* 45 */ + CDMF_WVECTORTEXT, /* 46 */ + CDMF_WMULTILINEVECTORTEXT, /* 47 */ + CDMF_WINDOW, /* 48 */ + CDMF_WCLIPAREA, /* 49 */ + CDMF_VECTORFONT, /* 50 */ + CDMF_VECTORTEXTDIRECTION, /* 51 */ + CDMF_VECTORTEXTTRANSFORM, /* 52 */ + CDMF_VECTORTEXTSIZE, /* 53 */ + CDMF_VECTORCHARSIZE, /* 54 */ + CDMF_WVECTORTEXTDIRECTION, /* 55 */ + CDMF_WVECTORTEXTSIZE, /* 56 */ + CDMF_WVECTORCHARSIZE, /* 57 */ + CDMF_FILLMODE, /* 58 */ + CDMF_LINESTYLEDASHES, /* 59 */ + CDMF_LINECAP, /* 60 */ + CDMF_LINEJOIN, /* 61 */ + CDMF_CHORD, /* 62 */ + CDMF_WCHORD, /* 63 */ + CDMF_FLINE, /* 64 */ + CDMF_FRECT, /* 65 */ + CDMF_FBOX, /* 66 */ + CDMF_FARC, /* 67 */ + CDMF_FSECTOR, /* 68 */ + CDMF_FTEXT, /* 69 */ + CDMF_FVERTEX, /* 70 */ + CDMF_MATRIX, /* 71 */ + CDMF_FCHORD, /* 72 */ + CDMF_FCLIPAREA, /* 73 */ + CDMF_FONT, /* 74 */ + CDMF_RESETMATRIX /* 75 */ +}; + +struct _cdCtxCanvas +{ + /* public */ + cdCanvas* canvas; + char* filename; + void* data; /* used by other drivers */ + + /* private */ + int last_line_style; + int last_fill_mode; + FILE* file; +}; + +void cdkillcanvasMF(cdCanvasMF *mfcanvas) +{ + cdCtxCanvas *ctxcanvas = (cdCtxCanvas*)mfcanvas; + free(ctxcanvas->filename); + fclose(ctxcanvas->file); + memset(ctxcanvas, 0, sizeof(cdCtxCanvas)); + free(ctxcanvas); +} + +static void cdflush(cdCtxCanvas *ctxcanvas) +{ + fflush(ctxcanvas->file); + fprintf(ctxcanvas->file, "%d\n", CDMF_FLUSH); +} + +static void cdclear(cdCtxCanvas *ctxcanvas) +{ + fprintf(ctxcanvas->file, "%d\n", CDMF_CLEAR); +} + +static int cdclip(cdCtxCanvas *ctxcanvas, int mode) +{ + fprintf(ctxcanvas->file, "%d %d\n", CDMF_CLIP, mode); + return mode; +} + +static void cdcliparea(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax) +{ + fprintf(ctxcanvas->file, "%d %d %d %d %d\n", CDMF_CLIPAREA, xmin, xmax, ymin, ymax); +} + +static void cdfcliparea(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax) +{ + fprintf(ctxcanvas->file, "%d %g %g %g %g\n", CDMF_FCLIPAREA, xmin, xmax, ymin, ymax); +} + +static void cdtransform(cdCtxCanvas *ctxcanvas, const double* matrix) +{ + if (matrix) + fprintf(ctxcanvas->file, "%d %g %g %g %g %g %g\n", CDMF_MATRIX, matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); + else + fprintf(ctxcanvas->file, "%d\n", CDMF_RESETMATRIX); +} + +static void cdline(cdCtxCanvas *ctxcanvas, int x1, int y1, int x2, int y2) +{ + fprintf(ctxcanvas->file, "%d %d %d %d %d\n", CDMF_LINE, x1, y1, x2, y2); +} + +static void cdfline(cdCtxCanvas *ctxcanvas, double x1, double y1, double x2, double y2) +{ + fprintf(ctxcanvas->file, "%d %g %g %g %g\n", CDMF_FLINE, x1, y1, x2, y2); +} + +static void cdrect(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax) +{ + fprintf(ctxcanvas->file, "%d %d %d %d %d\n", CDMF_RECT, xmin, xmax, ymin, ymax); +} + +static void cdfrect(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax) +{ + fprintf(ctxcanvas->file, "%d %g %g %g %g\n", CDMF_FRECT, xmin, xmax, ymin, ymax); +} + +static void cdbox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax) +{ + fprintf(ctxcanvas->file, "%d %d %d %d %d\n", CDMF_BOX, xmin, xmax, ymin, ymax); +} + +static void cdfbox(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax) +{ + fprintf(ctxcanvas->file, "%d %g %g %g %g\n", CDMF_FBOX, xmin, xmax, ymin, ymax); +} + +static void cdarc(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2) +{ + fprintf(ctxcanvas->file, "%d %d %d %d %d %g %g\n", CDMF_ARC, xc, yc, w, h, a1, a2); +} + +static void cdfarc(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2) +{ + fprintf(ctxcanvas->file, "%d %g %g %g %g %g %g\n", CDMF_FARC, xc, yc, w, h, a1, a2); +} + +static void cdsector(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2) +{ + fprintf(ctxcanvas->file, "%d %d %d %d %d %g %g\n", CDMF_SECTOR, xc, yc, w, h, a1, a2); +} + +static void cdfsector(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2) +{ + fprintf(ctxcanvas->file, "%d %g %g %g %g %g %g\n", CDMF_FSECTOR, xc, yc, w, h, a1, a2); +} + +static void cdchord(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2) +{ + fprintf(ctxcanvas->file, "%d %d %d %d %d %g %g\n", CDMF_CHORD, xc, yc, w, h, a1, a2); +} + +static void cdfchord(cdCtxCanvas *ctxcanvas, double xc, double yc, double w, double h, double a1, double a2) +{ + fprintf(ctxcanvas->file, "%d %g %g %g %g %g %g\n", CDMF_FCHORD, xc, yc, w, h, a1, a2); +} + +static void cdtext(cdCtxCanvas *ctxcanvas, int x, int y, const char *text) +{ + fprintf(ctxcanvas->file, "%d %d %d %s\n", CDMF_TEXT, x, y, text); +} + +static void cdftext(cdCtxCanvas *ctxcanvas, double x, double y, const char *text) +{ + fprintf(ctxcanvas->file, "%d %g %g %s\n", CDMF_FTEXT, x, y, text); +} + +static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n) +{ + int i; + + if (mode == CD_FILL && ctxcanvas->canvas->fill_mode != ctxcanvas->last_fill_mode) + { + fprintf(ctxcanvas->file, "%d %d\n", CDMF_FILLMODE, ctxcanvas->canvas->fill_mode); + ctxcanvas->last_fill_mode = ctxcanvas->canvas->fill_mode; + } + + fprintf(ctxcanvas->file, "%d %d\n", CDMF_BEGIN, mode); + + for(i = 0; i<n; i++) + fprintf(ctxcanvas->file, "%d %d %d\n", CDMF_VERTEX, poly[i].x, poly[i].y); + + fprintf(ctxcanvas->file, "%d\n", CDMF_END); +} + +static void cdfpoly(cdCtxCanvas *ctxcanvas, int mode, cdfPoint* poly, int n) +{ + int i; + + if (mode == CD_FILL && ctxcanvas->canvas->fill_mode != ctxcanvas->last_fill_mode) + { + fprintf(ctxcanvas->file, "%d %d\n", CDMF_FILLMODE, ctxcanvas->canvas->fill_mode); + ctxcanvas->last_fill_mode = ctxcanvas->canvas->fill_mode; + } + + fprintf(ctxcanvas->file, "%d %d\n", CDMF_BEGIN, mode); + + for(i = 0; i<n; i++) + fprintf(ctxcanvas->file, "%d %g %g\n", CDMF_FVERTEX, poly[i].x, poly[i].y); + + fprintf(ctxcanvas->file, "%d\n", CDMF_END); +} + +static int cdbackopacity(cdCtxCanvas *ctxcanvas, int opacity) +{ + fprintf(ctxcanvas->file, "%d %d\n", CDMF_BACKOPACITY, opacity); + return opacity; +} + +static int cdwritemode(cdCtxCanvas *ctxcanvas, int mode) +{ + fprintf(ctxcanvas->file, "%d %d\n", CDMF_WRITEMODE, mode); + return mode; +} + +static int cdlinestyle(cdCtxCanvas *ctxcanvas, int style) +{ + if (style == CD_CUSTOM && ctxcanvas->canvas->line_style != ctxcanvas->last_line_style) + { + int i; + fprintf(ctxcanvas->file, "%d %d", CDMF_LINESTYLEDASHES, ctxcanvas->canvas->line_dashes_count); + for (i = 0; i < ctxcanvas->canvas->line_dashes_count; i++) + fprintf(ctxcanvas->file, " %d", ctxcanvas->canvas->line_dashes[i]); + fprintf(ctxcanvas->file, "\n"); + ctxcanvas->last_line_style = ctxcanvas->canvas->line_style; + } + + fprintf(ctxcanvas->file, "%d %d\n", CDMF_LINESTYLE, style); + return style; +} + +static int cdlinewidth(cdCtxCanvas *ctxcanvas, int width) +{ + fprintf(ctxcanvas->file, "%d %d\n", CDMF_LINEWIDTH, width); + return width; +} + +static int cdlinecap(cdCtxCanvas *ctxcanvas, int cap) +{ + fprintf(ctxcanvas->file, "%d %d\n", CDMF_LINECAP, cap); + return cap; +} + +static int cdlinejoin(cdCtxCanvas *ctxcanvas, int join) +{ + fprintf(ctxcanvas->file, "%d %d\n", CDMF_LINEJOIN, join); + return join; +} + +static int cdinteriorstyle(cdCtxCanvas *ctxcanvas, int style) +{ + fprintf(ctxcanvas->file, "%d %d\n", CDMF_INTERIORSTYLE, style); + return style; +} + +static int cdhatch(cdCtxCanvas *ctxcanvas, int style) +{ + fprintf(ctxcanvas->file, "%d %d\n", CDMF_HATCH, style); + return style; +} + +static void cdstipple(cdCtxCanvas *ctxcanvas, int w, int h, const unsigned char *stipple) +{ + int c, t; + + fprintf(ctxcanvas->file, "%d %d %d\n", CDMF_STIPPLE, w, h); + + t = w * h; + + for (c = 0; c < t; c++) + { + fprintf(ctxcanvas->file, "%d ", (int)*stipple++); + if ((c + 1) % w == 0) + fprintf(ctxcanvas->file, "\n"); + } +} + +static void cdpattern(cdCtxCanvas *ctxcanvas, int w, int h, const long int *pattern) +{ + int c, t; + unsigned char r, g, b; + + fprintf(ctxcanvas->file, "%d %d %d\n", CDMF_PATTERN, w, h); + + t = w * h; + + /* stores the pattern with separeted RGB values */ + for (c = 0; c < t; c++) + { + cdDecodeColor(*pattern++, &r, &g, &b); + fprintf(ctxcanvas->file, "%d %d %d ", (int)r, (int)g, (int)b); + if (c % w == 0) + fprintf(ctxcanvas->file, "\n"); + } +} + +static int cdfont(cdCtxCanvas *ctxcanvas, const char* type_face, int style, int size) +{ + fprintf(ctxcanvas->file, "%d %d %d %s\n", CDMF_FONT, style, size, type_face); + return 1; +} + +static int cdnativefont(cdCtxCanvas *ctxcanvas, const char* font) +{ + fprintf(ctxcanvas->file, "%d %s\n", CDMF_NATIVEFONT, font); + return 1; +} + +static int cdtextalignment(cdCtxCanvas *ctxcanvas, int alignment) +{ + fprintf(ctxcanvas->file, "%d %d\n", CDMF_TEXTALIGNMENT, alignment); + return alignment; +} + +static double cdtextorientation(cdCtxCanvas *ctxcanvas, double angle) +{ + fprintf(ctxcanvas->file, "%d %g\n", CDMF_TEXTORIENTATION, angle); + return angle; +} + +static void cdpalette(cdCtxCanvas *ctxcanvas, int n, const long int *palette, int mode) +{ + int c; + unsigned char r, g, b; + + fprintf(ctxcanvas->file, "%d %d %d\n", CDMF_PALETTE, n, mode); + + for (c = 0; c < n; c++) + { + cdDecodeColor(*palette++, &r, &g, &b); + fprintf(ctxcanvas->file, "%d %d %d\n", (int)r, (int)g, (int)b); + } +} + +static long cdbackground(cdCtxCanvas *ctxcanvas, long int color) +{ + unsigned char r, g, b; + cdDecodeColor(color, &r, &g, &b); + fprintf(ctxcanvas->file, "%d %d %d %d\n", CDMF_BACKGROUND, (int)r, (int)g, (int)b); + return color; +} + +static long cdforeground(cdCtxCanvas *ctxcanvas, long int color) +{ + unsigned char r, g, b; + cdDecodeColor(color, &r, &g, &b); + fprintf(ctxcanvas->file, "%d %d %d %d\n", CDMF_FOREGROUND, (int)r, (int)g, (int)b); + return color; +} + +static void cdputimagerectrgb(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsigned char *r, const unsigned char *g, const unsigned char *b, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax) +{ + int c, l, offset; + + fprintf(ctxcanvas->file, "%d %d %d %d %d %d %d\n", CDMF_PUTIMAGERGB, iw, ih, x, y, w, h); + + offset = ymin*iw + xmin; + r += offset; + g += offset; + b += offset; + + offset = iw - (xmax-xmin+1); + + for (l = ymin; l <= ymax; l++) + { + for (c = xmin; c <= xmax; c++) + { + fprintf(ctxcanvas->file, "%d %d %d ", (int)*r++, (int)*g++, (int)*b++); + } + + r += offset; + g += offset; + b += offset; + + fprintf(ctxcanvas->file, "\n"); + } +} + +static void cdputimagerectrgba(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsigned char *r, const unsigned char *g, const unsigned char *b, const unsigned char *a, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax) +{ + int c, l, offset; + + fprintf(ctxcanvas->file, "%d %d %d %d %d %d %d\n", CDMF_PUTIMAGERGBA, iw, ih, x, y, w, h); + + offset = ymin*iw + xmin; + r += offset; + g += offset; + b += offset; + a += offset; + + offset = iw - (xmax-xmin+1); + + for (l = ymin; l <= ymax; l++) + { + for (c = xmin; c <= xmax; c++) + { + fprintf(ctxcanvas->file, "%d %d %d %d ", (int)*r++, (int)*g++, (int)*b++, (int)*a++); + } + + r += offset; + g += offset; + b += offset; + a += offset; + + fprintf(ctxcanvas->file, "\n"); + } +} + +static void cdputimagerectmap(cdCtxCanvas *ctxcanvas, int iw, int ih, const unsigned char *index, const long int *colors, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax) +{ + int c, l, n = 0, offset; + unsigned char r, g, b; + + fprintf(ctxcanvas->file, "%d %d %d %d %d %d %d\n", CDMF_PUTIMAGEMAP, iw, ih, x, y, w, h); + + index += ymin*iw + xmin; + offset = iw - (xmax-xmin+1); + + for (l = ymin; l <= ymax; l++) + { + for (c = xmin; c <= xmax; c++) + { + if (*index > n) + n = *index; + + fprintf(ctxcanvas->file, "%d ", (int)*index++); + } + + index += offset; + + fprintf(ctxcanvas->file, "\n"); + } + + n++; + + for (c = 0; c < n; c++) + { + cdDecodeColor(*colors++, &r, &g, &b); + fprintf(ctxcanvas->file, "%d %d %d\n", (int)r, (int)g, (int)b); + } +} + +static void cdpixel(cdCtxCanvas *ctxcanvas, int x, int y, long int color) +{ + unsigned char r, g, b; + cdDecodeColor(color, &r, &g, &b); + fprintf(ctxcanvas->file, "%d %d %d %d %d %d\n", CDMF_PIXEL, x, y, (int)r, (int)g, (int)b); +} + +static void cdscrollarea(cdCtxCanvas *ctxcanvas, int xmin,int xmax, int ymin,int ymax, int dx,int dy) +{ + fprintf(ctxcanvas->file, "%d %d %d %d %d %d %d\n", CDMF_SCROLLAREA, xmin, xmax, ymin, ymax, dx, dy); +} + + +/**********/ +/* cdPlay */ +/**********/ + + +static double factorX = 1; +static double factorY = 1; +static int offsetX = 0; +static int offsetY = 0; +static double factorS = 1; + +static int sScaleX(int x) +{ + return cdRound(x * factorX + offsetX); +} + +static int sScaleY(int y) +{ + return cdRound(y * factorY + offsetY); +} + +static double sfScaleX(double x) +{ + return x * factorX + offsetX; +} + +static double sfScaleY(double y) +{ + return y * factorY + offsetY; +} + +static int sScaleW(int w) +{ + w = (int)(w * factorX + 0.5); /* always positive */ + return w == 0? 1: w; +} + +static double sfScaleH(double h) +{ + h = h * factorY; + return h == 0? 1: h; +} + +static double sfScaleW(double w) +{ + w = w * factorX; /* always positive */ + return w == 0? 1: w; +} + +static int sScaleH(int h) +{ + h = (int)(h * factorY + 0.5); + return h == 0? 1: h; +} + +static int sScaleS(int s) +{ + s = (int)(s * factorS + 0.5); + return s == 0? 1: s; +} + +typedef int(*_cdsizecb)(cdCanvas* canvas, int w, int h, double w_mm, double h_mm); +static _cdsizecb cdsizecb = NULL; + +static int cdregistercallback(int cb, cdCallback func) +{ + switch (cb) + { + case CD_SIZECB: + cdsizecb = (_cdsizecb)func; + return CD_OK; + } + + return CD_ERROR; +} + +static int cdplay(cdCanvas* canvas, int xmin, int xmax, int ymin, int ymax, void *data) +{ + char* filename = (char*)data; + FILE* file; + char TextBuffer[512]; + int iparam1, iparam2, iparam3, iparam4, iparam5, iparam6, iparam7, iparam8, iparam9, iparam10; + int c, t, n, w, h, func; + double dparam1, dparam2, dparam3, dparam4, dparam5, dparam6; + unsigned char* stipple, * _stipple, *red, *green, *blue, *_red, *_green, *_blue, *index, *_index, *_alpha, *alpha; + long int *pattern, *palette, *_pattern, *_palette, *colors, *_colors; + int* dashes; + double matrix[6]; + const char * font_family[] = + { + "System", /* CD_SYSTEM */ + "Courier", /* CD_COURIER */ + "Times", /* CD_TIMES_ROMAN */ + "Helvetica" /* CD_HELVETICA */ + }; + + file = fopen(filename, "r"); + if (!file) + return CD_ERROR; + + func = -1; + w = 0; + h = 0; + + factorX = 1; + factorY = 1; + offsetX = 0; + offsetY = 0; + factorS = 1; + + fscanf(file, "%s %d %d", TextBuffer, &w, &h); + + if (strcmp(TextBuffer, "CDMF") != 0) + { + fclose(file); + return CD_ERROR; + } + + if (w>1 && h>1 && xmax!=0 && ymax!=0) + { + offsetX = xmin; + offsetY = ymin; + factorX = ((double)(xmax-xmin)) / (w-1); + factorY = ((double)(ymax-ymin)) / (h-1); + + if (factorX < factorY) + factorS = factorX; + else + factorS = factorY; + } + + if (cdsizecb) + { + int err; + err = cdsizecb(canvas, w, h, w, h); + if (err) + return CD_ERROR; + } + + while (!feof(file)) + { + fscanf(file, "%d", &func); + if (feof(file)) + break; + + switch (func) + { + case CDMF_FLUSH: + cdCanvasFlush(canvas); + break; + case CDMF_CLEAR: + cdCanvasClear(canvas); + break; + case CDMF_CLIP: + fscanf(file, "%d", &iparam1); + cdCanvasClip(canvas, iparam1); + break; + case CDMF_CLIPAREA: + fscanf(file, "%d %d %d %d", &iparam1, &iparam2, &iparam3, &iparam4); + cdCanvasClipArea(canvas, sScaleX(iparam1), sScaleX(iparam2), sScaleY(iparam3), sScaleY(iparam4)); + break; + case CDMF_FCLIPAREA: + fscanf(file, "%lg %lg %lg %lg", &dparam1, &dparam2, &dparam3, &dparam4); + cdfCanvasClipArea(canvas, sfScaleX(dparam1), sfScaleX(dparam2), sfScaleY(dparam3), sfScaleY(dparam4)); + break; + case CDMF_MATRIX: + fscanf(file, "%lg %lg %lg %lg %lg %lg", &matrix[0], &matrix[1], &matrix[2], &matrix[3], &matrix[4], &matrix[5]); + cdCanvasTransform(canvas, matrix); + break; + case CDMF_RESETMATRIX: + cdCanvasTransform(canvas, NULL); + break; + case CDMF_WCLIPAREA: + fscanf(file, "%lg %lg %lg %lg", &dparam1, &dparam2, &dparam3, &dparam4); + wdCanvasClipArea(canvas, dparam1, dparam2, dparam3, dparam4); + break; + case CDMF_LINE: + fscanf(file, "%d %d %d %d", &iparam1, &iparam2, &iparam3, &iparam4); + cdCanvasLine(canvas, sScaleX(iparam1), sScaleY(iparam2), sScaleX(iparam3), sScaleY(iparam4)); + break; + case CDMF_FLINE: + fscanf(file, "%lg %lg %lg %lg", &dparam1, &dparam2, &dparam3, &dparam4); + cdfCanvasLine(canvas, sfScaleX(dparam1), sfScaleY(dparam2), sfScaleX(dparam3), sfScaleY(dparam4)); + break; + case CDMF_WLINE: + fscanf(file, "%lg %lg %lg %lg", &dparam1, &dparam2, &dparam3, &dparam4); + wdCanvasLine(canvas, dparam1, dparam2, dparam3, dparam4); + break; + case CDMF_RECT: + fscanf(file, "%d %d %d %d", &iparam1, &iparam2, &iparam3, &iparam4); + cdCanvasRect(canvas, sScaleX(iparam1), sScaleX(iparam2), sScaleY(iparam3), sScaleY(iparam4)); + break; + case CDMF_FRECT: + fscanf(file, "%lg %lg %lg %lg", &dparam1, &dparam2, &dparam3, &dparam4); + cdfCanvasRect(canvas, sfScaleX(dparam1), sfScaleX(dparam2), sfScaleY(dparam3), sfScaleY(dparam4)); + break; + case CDMF_WRECT: + fscanf(file, "%lg %lg %lg %lg", &dparam1, &dparam2, &dparam3, &dparam4); + wdCanvasRect(canvas, dparam1, dparam2, dparam3, dparam4); + break; + case CDMF_BOX: + fscanf(file, "%d %d %d %d", &iparam1, &iparam2, &iparam3, &iparam4); + cdCanvasBox(canvas, sScaleX(iparam1), sScaleX(iparam2), sScaleY(iparam3), sScaleY(iparam4)); + break; + case CDMF_WBOX: + fscanf(file, "%lg %lg %lg %lg", &dparam1, &dparam2, &dparam3, &dparam4); + wdCanvasBox(canvas, dparam1, dparam2, dparam3, dparam4); + break; + case CDMF_FBOX: + fscanf(file, "%lg %lg %lg %lg", &dparam1, &dparam2, &dparam3, &dparam4); + cdfCanvasBox(canvas, sfScaleX(dparam1), sfScaleX(dparam2), sfScaleY(dparam3), sfScaleY(dparam4)); + break; + case CDMF_ARC: + fscanf(file, "%d %d %d %d %lg %lg", &iparam1, &iparam2, &iparam3, &iparam4, &dparam1, &dparam2); + cdCanvasArc(canvas, sScaleX(iparam1), sScaleY(iparam2), sScaleW(iparam3), sScaleH(iparam4), dparam1, dparam2); + break; + case CDMF_FARC: + fscanf(file, "%lg %lg %lg %lg %lg %lg", &dparam1, &dparam2, &dparam3, &dparam4, &dparam5, &dparam6); + cdfCanvasArc(canvas, sfScaleX(dparam1), sfScaleY(dparam2), sfScaleW(dparam3), sfScaleH(dparam4), dparam5, dparam6); + break; + case CDMF_WARC: + fscanf(file, "%lg %lg %lg %lg %lg %lg", &dparam1, &dparam2, &dparam3, &dparam4, &dparam5, &dparam6); + wdCanvasArc(canvas, dparam1, dparam2, dparam3, dparam4, dparam5, dparam6); + break; + case CDMF_SECTOR: + fscanf(file, "%d %d %d %d %lg %lg", &iparam1, &iparam2, &iparam3, &iparam4, &dparam1, &dparam2); + cdCanvasSector(canvas, sScaleX(iparam1), sScaleY(iparam2), sScaleW(iparam3), sScaleH(iparam4), dparam1, dparam2); + break; + case CDMF_FSECTOR: + fscanf(file, "%lg %lg %lg %lg %lg %lg", &dparam1, &dparam2, &dparam3, &dparam4, &dparam5, &dparam6); + cdfCanvasSector(canvas, sfScaleX(dparam1), sfScaleY(dparam2), sfScaleW(dparam3), sfScaleH(dparam4), dparam5, dparam6); + break; + case CDMF_WSECTOR: + fscanf(file, "%lg %lg %lg %lg %lg %lg", &dparam1, &dparam2, &dparam3, &dparam4, &dparam5, &dparam6); + wdCanvasSector(canvas, dparam1, dparam2, dparam3, dparam4, dparam5, dparam6); + break; + case CDMF_CHORD: + fscanf(file, "%d %d %d %d %lg %lg", &iparam1, &iparam2, &iparam3, &iparam4, &dparam1, &dparam2); + cdCanvasChord(canvas, sScaleX(iparam1), sScaleY(iparam2), sScaleW(iparam3), sScaleH(iparam4), dparam1, dparam2); + break; + case CDMF_FCHORD: + fscanf(file, "%lg %lg %lg %lg %lg %lg", &dparam1, &dparam2, &dparam3, &dparam4, &dparam5, &dparam6); + cdfCanvasChord(canvas, sfScaleX(dparam1), sfScaleY(dparam2), sfScaleW(dparam3), sfScaleH(dparam4), dparam5, dparam6); + break; + case CDMF_WCHORD: + fscanf(file, "%lg %lg %lg %lg %lg %lg", &dparam1, &dparam2, &dparam3, &dparam4, &dparam5, &dparam6); + wdCanvasChord(canvas, dparam1, dparam2, dparam3, dparam4, dparam5, dparam6); + break; + case CDMF_TEXT: + fscanf(file, "%d %d %[^\n]", &iparam1, &iparam2, TextBuffer); + cdCanvasText(canvas, sScaleX(iparam1), sScaleY(iparam2), TextBuffer); + break; + case CDMF_FTEXT: + fscanf(file, "%lg %lg %[^\n]", &dparam1, &dparam2, TextBuffer); + cdfCanvasText(canvas, sfScaleX(dparam1), sfScaleY(dparam2), TextBuffer); + break; + case CDMF_WTEXT: + fscanf(file, "%lg %lg %[^\n]", &dparam1, &dparam2, TextBuffer); + wdCanvasText(canvas, dparam1, dparam2, TextBuffer); + break; + case CDMF_BEGIN: + fscanf(file, "%d", &iparam1); + cdCanvasBegin(canvas, iparam1); + break; + case CDMF_VERTEX: + fscanf(file, "%d %d", &iparam1, &iparam2); + cdCanvasVertex(canvas, sScaleX(iparam1), sScaleY(iparam2)); + break; + case CDMF_FVERTEX: + fscanf(file, "%lg %lg", &dparam1, &dparam2); + cdfCanvasVertex(canvas, sfScaleX(dparam1), sfScaleY(dparam2)); + break; + case CDMF_WVERTEX: + fscanf(file, "%lg %lg", &dparam1, &dparam2); + wdCanvasVertex(canvas, dparam1, dparam2); + break; + case CDMF_END: + cdCanvasEnd(canvas); + break; + case CDMF_MARK: + fscanf(file, "%d %d", &iparam1, &iparam2); + cdCanvasMark(canvas, sScaleX(iparam1), sScaleY(iparam2)); + break; + case CDMF_WMARK: + fscanf(file, "%lg %lg", &dparam1, &dparam2); + wdCanvasMark(canvas, dparam1, dparam2); + break; + case CDMF_BACKOPACITY: + fscanf(file, "%d", &iparam1); + cdCanvasBackOpacity(canvas, iparam1); + break; + case CDMF_WRITEMODE: + fscanf(file, "%d", &iparam1); + cdCanvasWriteMode(canvas, iparam1); + break; + case CDMF_LINESTYLE: + fscanf(file, "%d", &iparam1); + cdCanvasLineStyle(canvas, iparam1); + break; + case CDMF_LINEWIDTH: + fscanf(file, "%d", &iparam1); + cdCanvasLineWidth(canvas, sScaleS(iparam1)); + break; + case CDMF_LINECAP: + fscanf(file, "%d", &iparam1); + cdCanvasLineCap(canvas, iparam1); + break; + case CDMF_LINEJOIN: + fscanf(file, "%d", &iparam1); + cdCanvasLineJoin(canvas, iparam1); + break; + case CDMF_LINESTYLEDASHES: + fscanf(file, "%d", &iparam1); + dashes = (int*)malloc(iparam1*sizeof(int)); + for (c = 0; c < iparam1; c++) + fscanf(file, "%d", &dashes[c]); + cdCanvasLineStyleDashes(canvas, dashes, iparam1); + free(dashes); + break; + case CDMF_FILLMODE: + fscanf(file, "%d", &iparam1); + cdCanvasFillMode(canvas, iparam1); + break; + case CDMF_INTERIORSTYLE: + fscanf(file, "%d", &iparam1); + cdCanvasInteriorStyle(canvas, iparam1); + break; + case CDMF_HATCH: + fscanf(file, "%d", &iparam1); + cdCanvasHatch(canvas, iparam1); + break; + case CDMF_STIPPLE: + fscanf(file, "%d %d", &iparam1, &iparam2); + t = iparam1 * iparam2; + stipple = (unsigned char*)malloc(t); + _stipple = stipple; + for (c = 0; c < t; c++) + { + fscanf(file, "%d", &iparam3); + *_stipple++ = (unsigned char)iparam3; + } + cdCanvasStipple(canvas, iparam1, iparam2, stipple); + free(stipple); + break; + case CDMF_PATTERN: + fscanf(file, "%d %d", &iparam1, &iparam2); + t = iparam1 * iparam2; + pattern = (long int*)malloc(t * sizeof(long)); + _pattern = pattern; + for (c = 0; c < t; c++) + { + fscanf(file, "%d %d %d", &iparam3, &iparam4, &iparam5); + *_pattern++ = cdEncodeColor((unsigned char)iparam3, (unsigned char)iparam4, (unsigned char)iparam5); + } + cdCanvasPattern(canvas, iparam1, iparam2, pattern); + free(pattern); + break; + case CDMF_OLDFONT: + fscanf(file, "%d %d %d", &iparam1, &iparam2, &iparam3); + if (iparam1 < 0 || iparam1 > 3) break; + if (iparam3 < 0) + { + iparam3 = -sScaleH(abs(iparam3)); + if (iparam3 > -5) iparam3 = -5; + } + else + { + iparam3 = sScaleH(abs(iparam3)); + if (iparam3 < 5) iparam3 = 5; + } + cdCanvasFont(canvas, font_family[iparam1], iparam2, iparam3); + break; + case CDMF_FONT: + fscanf(file, "%d %d %[^\n]", &iparam2, &iparam3, TextBuffer); + if (iparam3 < 0) + { + iparam3 = -sScaleH(abs(iparam3)); + if (iparam3 > -5) iparam3 = -5; + } + else + { + iparam3 = sScaleH(abs(iparam3)); + if (iparam3 < 5) iparam3 = 5; + } + cdCanvasFont(canvas, TextBuffer, iparam2, iparam3); + break; + case CDMF_NATIVEFONT: + fscanf(file, "%[^\n]", TextBuffer); + cdCanvasNativeFont(canvas, TextBuffer); + break; + case CDMF_TEXTALIGNMENT: + fscanf(file, "%d", &iparam1); + cdCanvasTextAlignment(canvas, iparam1); + break; + case CDMF_TEXTORIENTATION: + fscanf(file, "%lg", &dparam1); + cdCanvasTextOrientation(canvas, dparam1); + break; + case CDMF_MARKTYPE: + fscanf(file, "%d", &iparam1); + cdCanvasMarkType(canvas, iparam1); + break; + case CDMF_MARKSIZE: + fscanf(file, "%d", &iparam1); + cdCanvasMarkSize(canvas, sScaleS(iparam1)); + break; + case CDMF_PALETTE: + fscanf(file, "%d %d", &iparam1, &iparam2); + _palette = palette = (long int*)malloc(iparam1); + for (c = 0; c < iparam1; c++) + { + fscanf(file, "%d %d %d", &iparam3, &iparam4, &iparam5); + *_palette++ = cdEncodeColor((unsigned char)iparam3, (unsigned char)iparam4, (unsigned char)iparam5); + } + cdCanvasPalette(canvas, iparam1, palette, iparam2); + free(palette); + break; + case CDMF_BACKGROUND: + fscanf(file, "%d %d %d", &iparam1, &iparam2, &iparam3); + cdCanvasSetBackground(canvas, cdEncodeColor((unsigned char)iparam1, (unsigned char)iparam2, (unsigned char)iparam3)); + break; + case CDMF_FOREGROUND: + fscanf(file, "%d %d %d", &iparam1, &iparam2, &iparam3); + cdCanvasSetForeground(canvas, cdEncodeColor((unsigned char)iparam1, (unsigned char)iparam2, (unsigned char)iparam3)); + break; + case CDMF_PUTIMAGERGB: + fscanf(file, "%d %d %d %d %d %d", &iparam1, &iparam2, &iparam3, &iparam4, &iparam5, &iparam6); + t = iparam1 * iparam2; + _red = red = (unsigned char*) malloc(t); + _green = green = (unsigned char*) malloc(t); + _blue = blue = (unsigned char*) malloc(t); + for (c = 0; c < t; c++) + { + fscanf(file, "%d %d %d", &iparam7, &iparam8, &iparam9); + *_red++ = (unsigned char)iparam7; + *_green++ = (unsigned char)iparam8; + *_blue++ = (unsigned char)iparam9; + } + cdCanvasPutImageRectRGB(canvas, iparam1, iparam2, red, green, blue, sScaleX(iparam3), sScaleY(iparam4), sScaleW(iparam5), sScaleH(iparam6), 0, 0, 0, 0); + free(red); + free(green); + free(blue); + break; + case CDMF_PUTIMAGERGBA: + fscanf(file, "%d %d %d %d %d %d", &iparam1, &iparam2, &iparam3, &iparam4, &iparam5, &iparam6); + t = iparam1 * iparam2; + _red = red = (unsigned char*) malloc(t); + _green = green = (unsigned char*) malloc(t); + _blue = blue = (unsigned char*) malloc(t); + _alpha = alpha = (unsigned char*) malloc(t); + for (c = 0; c < t; c++) + { + fscanf(file, "%d %d %d %d", &iparam7, &iparam8, &iparam9, &iparam10); + *_red++ = (unsigned char)iparam7; + *_green++ = (unsigned char)iparam8; + *_blue++ = (unsigned char)iparam9; + *_alpha++ = (unsigned char)iparam10; + } + cdCanvasPutImageRectRGBA(canvas, iparam1, iparam2, red, green, blue, alpha, sScaleX(iparam3), sScaleY(iparam4), sScaleW(iparam5), sScaleH(iparam6), 0, 0, 0, 0); + free(red); + free(green); + free(blue); + free(alpha); + break; + case CDMF_PUTIMAGEMAP: + fscanf(file, "%d %d %d %d %d %d", &iparam1, &iparam2, &iparam3, &iparam4, &iparam5, &iparam6); + t = iparam1 * iparam2; + n = 0; + _index = index = (unsigned char*) malloc(t); + for (c = 0; c < t; c++) + { + fscanf(file, "%d", &iparam7); + *_index++ = (unsigned char)iparam7; + if (iparam7 > n) + n = iparam7; + } + _colors = colors = (long int*)malloc(n); + for (c = 0; c < n; c++) + { + fscanf(file, "%d %d %d", &iparam7, &iparam8, &iparam9); + *_colors++ = cdEncodeColor((unsigned char)iparam7, (unsigned char)iparam8, (unsigned char)iparam9); + } + cdCanvasPutImageRectMap(canvas, iparam1, iparam2, index, colors, sScaleX(iparam3), sScaleY(iparam4), sScaleW(iparam5), sScaleH(iparam6), 0, 0, 0, 0); + free(index); + free(colors); + break; + case CDMF_PIXEL: + fscanf(file, "%d %d %d %d %d", &iparam1, &iparam2, &iparam3, &iparam4, &iparam5); + cdCanvasPixel(canvas, sScaleX(iparam1), sScaleY(iparam2), cdEncodeColor((unsigned char)iparam3, (unsigned char)iparam4, (unsigned char)iparam5)); + break; + case CDMF_SCROLLAREA: + fscanf(file, "%d %d %d %d %d %d", &iparam1, &iparam2, &iparam3, &iparam4, &iparam5, &iparam6); + cdCanvasScrollArea(canvas, sScaleX(iparam1), sScaleX(iparam2), sScaleY(iparam3), sScaleY(iparam4), sScaleX(iparam5), sScaleY(iparam6)); + break; + case CDMF_WVECTORTEXT: + fscanf(file, "%lg %lg %[^\n]", &dparam1, &dparam2, TextBuffer); + wdCanvasVectorText(canvas, dparam1, dparam2, TextBuffer); + break; + case CDMF_WMULTILINEVECTORTEXT: + fscanf(file, "%lg %lg %[^\n]", &dparam1, &dparam2, TextBuffer); + wdCanvasVectorText(canvas, dparam1, dparam2, TextBuffer); + break; + case CDMF_VECTORTEXT: + fscanf(file, "%d %d %[^\n]", &iparam1, &iparam2, TextBuffer); + cdCanvasVectorText(canvas, iparam1, iparam2, TextBuffer); + break; + case CDMF_MULTILINEVECTORTEXT: + fscanf(file, "%d %d %[^\n]", &iparam1, &iparam2, TextBuffer); + cdCanvasVectorText(canvas, iparam1, iparam2, TextBuffer); + break; + case CDMF_WVECTORCHARSIZE: + fscanf(file, "%lg", &dparam1); + wdCanvasVectorCharSize(canvas, dparam1); + break; + case CDMF_WVECTORTEXTSIZE: + fscanf(file, "%lg %lg %[^\n]", &dparam1, &dparam2, TextBuffer); + wdCanvasVectorTextSize(canvas, dparam1, dparam2, TextBuffer); + break; + case CDMF_WVECTORTEXTDIRECTION: + fscanf(file, "%lg %lg %lg %lg", &dparam1, &dparam2, &dparam3, &dparam4); + wdCanvasVectorTextDirection(canvas, dparam1, dparam2, dparam3, dparam4); + break; + case CDMF_VECTORCHARSIZE: + fscanf(file, "%d", &iparam1); + cdCanvasVectorCharSize(canvas, iparam1); + break; + case CDMF_VECTORTEXTSIZE: + fscanf(file, "%d %d %[^\n]", &iparam1, &iparam2, TextBuffer); + cdCanvasVectorTextSize(canvas, iparam1, iparam2, TextBuffer); + break; + case CDMF_VECTORTEXTDIRECTION: + fscanf(file, "%d %d %d %d", &iparam1, &iparam2, &iparam3, &iparam4); + cdCanvasVectorTextDirection(canvas, iparam1, iparam2, iparam3, iparam4); + break; + case CDMF_VECTORFONT: + fscanf(file, "%[^\n]", TextBuffer); + cdCanvasVectorFont(canvas, TextBuffer); + break; + case CDMF_VECTORTEXTTRANSFORM: + fscanf(file, "%lg %lg %lg %lg %lg %lg", &matrix[0], &matrix[1], &matrix[2], &matrix[3], &matrix[4], &matrix[5]); + cdCanvasVectorTextTransform(canvas, matrix); + break; + case CDMF_WINDOW: + fscanf(file, "%lg %lg %lg %lg", &dparam1, &dparam2, &dparam3, &dparam4); + wdCanvasWindow(canvas, dparam1, dparam2, dparam3, dparam4); + break; + default: + fclose(file); + return CD_ERROR; + } + } + + fclose(file); + + return CD_OK; +} + +/*******************/ +/* Canvas Creation */ +/*******************/ + +void cdcreatecanvasMF(cdCanvas *canvas, void *data) +{ + char filename[10240] = ""; + char* strdata = (char*)data; + double w_mm = INT_MAX*3.78, h_mm = INT_MAX*3.78, res = 3.78; + cdCtxCanvas* ctxcanvas; + int size; + + strdata += cdGetFileName(strdata, filename); + if (filename[0] == 0) + return; + + sscanf(strdata, "%lgx%lg %lg", &w_mm, &h_mm, &res); + + ctxcanvas = (cdCtxCanvas *)malloc(sizeof(cdCtxCanvas)); + memset(ctxcanvas, 0, sizeof(cdCtxCanvas)); + + ctxcanvas->file = fopen(filename, "w"); + if (!ctxcanvas->file) + { + free(ctxcanvas); + return; + } + + size = strlen(filename); + ctxcanvas->filename = malloc(size+1); + memcpy(ctxcanvas->filename, filename, size+1); + + ctxcanvas->canvas = canvas; + + /* update canvas context */ + canvas->w = (int)(w_mm * res); + canvas->h = (int)(h_mm * res); + canvas->w_mm = w_mm; + canvas->h_mm = h_mm; + canvas->bpp = 24; + canvas->xres = res; + canvas->yres = res; + canvas->ctxcanvas = ctxcanvas; + + ctxcanvas->last_line_style = -1; + ctxcanvas->last_fill_mode = -1; + + fprintf(ctxcanvas->file, "CDMF %d %d\n", canvas->w, canvas->h); +} + +void cdinittableMF(cdCanvas* canvas) +{ + canvas->cxFlush = cdflush; + canvas->cxClear = cdclear; + canvas->cxPixel = cdpixel; + canvas->cxLine = cdline; + canvas->cxPoly = cdpoly; + canvas->cxRect = cdrect; + canvas->cxBox = cdbox; + canvas->cxArc = cdarc; + canvas->cxSector = cdsector; + canvas->cxChord = cdchord; + canvas->cxText = cdtext; + canvas->cxPutImageRectRGB = cdputimagerectrgb; + canvas->cxPutImageRectRGBA = cdputimagerectrgba; + canvas->cxPutImageRectMap = cdputimagerectmap; + canvas->cxScrollArea = cdscrollarea; + canvas->cxFLine = cdfline; + canvas->cxFPoly = cdfpoly; + canvas->cxFRect = cdfrect; + canvas->cxFBox = cdfbox; + canvas->cxFArc = cdfarc; + canvas->cxFSector = cdfsector; + canvas->cxFChord = cdfchord; + canvas->cxFText = cdftext; + canvas->cxClip = cdclip; + canvas->cxClipArea = cdcliparea; + canvas->cxBackOpacity = cdbackopacity; + canvas->cxWriteMode = cdwritemode; + canvas->cxLineStyle = cdlinestyle; + canvas->cxLineWidth = cdlinewidth; + canvas->cxLineCap = cdlinecap; + canvas->cxLineJoin = cdlinejoin; + canvas->cxInteriorStyle = cdinteriorstyle; + canvas->cxHatch = cdhatch; + canvas->cxStipple = cdstipple; + canvas->cxPattern = cdpattern; + canvas->cxFont = cdfont; + canvas->cxNativeFont = cdnativefont; + canvas->cxTextAlignment = cdtextalignment; + canvas->cxTextOrientation = cdtextorientation; + canvas->cxPalette = cdpalette; + canvas->cxBackground = cdbackground; + canvas->cxForeground = cdforeground; + canvas->cxFClipArea = cdfcliparea; + canvas->cxTransform = cdtransform; + + canvas->cxKillCanvas = (void (*)(cdCtxCanvas*))cdkillcanvasMF; +} + +static cdContext cdMetafileContext = +{ + CD_CAP_ALL & ~(CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV | + CD_CAP_REGION | CD_CAP_FONTDIM | CD_CAP_TEXTSIZE), + 0, + cdcreatecanvasMF, + cdinittableMF, + cdplay, + cdregistercallback, +}; + +cdContext* cdContextMetafile(void) +{ + return &cdMetafileContext; +} |