From 25e85e1b809ec58ecac0f2e8fe48f74836f8e131 Mon Sep 17 00:00:00 2001 From: Pixel Date: Tue, 15 Jun 2010 00:18:43 -0700 Subject: Upgrading to CD 5.3 --- cd/src/drv/cdcgm.c | 2 + cd/src/drv/cddxf.c | 1 + cd/src/drv/cdirgb.c | 200 +++++++++++++++++++++---------------------------- cd/src/drv/cdmf.c | 26 +++---- cd/src/drv/cdpdf.c | 90 ++++++++++++++++++++-- cd/src/drv/cdpicture.c | 10 +++ cd/src/drv/cdps.c | 2 + 7 files changed, 197 insertions(+), 134 deletions(-) (limited to 'cd/src/drv') diff --git a/cd/src/drv/cdcgm.c b/cd/src/drv/cdcgm.c index 3049818..ab47c1e 100755 --- a/cd/src/drv/cdcgm.c +++ b/cd/src/drv/cdcgm.c @@ -183,6 +183,8 @@ static void cddeactivate(cdCtxCanvas *ctxcanvas) static void cdflush(cdCtxCanvas *ctxcanvas) { long pt; + + fflush(ctxcanvas->cgm->file); pt = ftell ( ctxcanvas->cgm->file ); fseek ( ctxcanvas->cgm->file, ctxcanvas->point, SEEK_SET ); diff --git a/cd/src/drv/cddxf.c b/cd/src/drv/cddxf.c index b4dc875..db05978 100755 --- a/cd/src/drv/cddxf.c +++ b/cd/src/drv/cddxf.c @@ -314,6 +314,7 @@ static void cdkillcanvas(cdCtxCanvas *ctxcanvas) static void cdflush (cdCtxCanvas *ctxcanvas) { + fflush (ctxcanvas->file); /* flush file */ ctxcanvas->layer++; } diff --git a/cd/src/drv/cdirgb.c b/cd/src/drv/cdirgb.c index 7e4720c..433a684 100755 --- a/cd/src/drv/cdirgb.c +++ b/cd/src/drv/cdirgb.c @@ -55,13 +55,35 @@ struct _cdCtxCanvas #define _sNormX(_ctxcanvas, _x) (_x < 0? 0: _x < _ctxcanvas->canvas->w? _x: _ctxcanvas->canvas->w-1) #define _sNormY(_ctxcanvas, _y) (_y < 0? 0: _y < _ctxcanvas->canvas->h? _y: _ctxcanvas->canvas->h-1) -#define RGB_COMPOSE(_SRC, _SRC_ALPHA, _DST, _TMP_MULTI, _TMP_ALPHA) (unsigned char)(((_SRC_ALPHA)*(_SRC) + (_TMP_MULTI)*(_DST)) / (_TMP_ALPHA)) +#define RGB_COMPOSE_OVER(_SRC, _SRC_ALPHA, _DST, _TMP_MULTI, _TMP_ALPHA) (unsigned char)(((_SRC_ALPHA)*(_SRC) + (_TMP_MULTI)*(_DST)) / (_TMP_ALPHA)) + +#define RGBA_WRITE_MODE(_write_mode, _pdst_red, _pdst_green, _pdst_blue, _tmp_red, _tmp_green, _tmp_blue) \ +{ \ + switch (_write_mode) \ + { \ + case CD_REPLACE: \ + *_pdst_red = _tmp_red; \ + *_pdst_green = _tmp_green; \ + *_pdst_blue = _tmp_blue; \ + break; \ + case CD_XOR: \ + *_pdst_red ^= _tmp_red; \ + *_pdst_green ^= _tmp_green; \ + *_pdst_blue ^= _tmp_blue; \ + break; \ + case CD_NOT_XOR: \ + *_pdst_red = (unsigned char)~(_tmp_red ^ *_pdst_red); \ + *_pdst_green = (unsigned char)~(_tmp_green ^ *_pdst_green); \ + *_pdst_blue = (unsigned char)~(_tmp_blue ^ *_pdst_blue); \ + break; \ + } \ +} #define RGBA_COLOR_COMBINE(_ctxcanvas, _pdst_red, _pdst_green, _pdst_blue, _pdst_alpha, _src_red, _src_green, _src_blue, _src_alpha) \ { \ - unsigned char _tmp_red = 0, _tmp_green = 0, _tmp_blue = 0; \ + unsigned char _tmp_red = 0, _tmp_green = 0, _tmp_blue = 0; \ \ - if (_pdst_alpha) /* (_pdst_alpha != NULL) */ \ + if (_pdst_alpha) /* destiny has alpha */ \ { \ if (_src_alpha != 255) /* some transparency */ \ { \ @@ -73,6 +95,8 @@ struct _cdCtxCanvas _tmp_green = _src_green; \ _tmp_blue = _src_blue; \ *_pdst_alpha = _src_alpha; \ + RGBA_WRITE_MODE(CD_REPLACE, _pdst_red, _pdst_green, _pdst_blue, \ + _tmp_red, _tmp_green, _tmp_blue); \ } \ else if (*_pdst_alpha == 255) /* destiny opaque */ \ { \ @@ -80,16 +104,25 @@ struct _cdCtxCanvas _tmp_green = CD_ALPHA_BLEND(_src_green, *_pdst_green, _src_alpha); \ _tmp_blue = CD_ALPHA_BLEND(_src_blue, *_pdst_blue, _src_alpha); \ /* *_pdst_alpha is not changed */ \ + RGBA_WRITE_MODE(CD_REPLACE, _pdst_red, _pdst_green, _pdst_blue, \ + _tmp_red, _tmp_green, _tmp_blue); \ } \ else /* (0<*_pdst_alpha<255 && 0<_src_alpha<255) destiny and source are semi-transparent */ \ { \ - /* Closed Compositing Formulas for SRC over DST, Colors Not Premultiplied by Alpha: */ \ + /* Closed Compositing SRC over DST (see smith95a.pdf) */ \ + /* Colors NOT Premultiplied by Alpha */ \ + /* DST = SRC * SRC_ALPHA + DST * DST_ALPHA * (1 - SRC_ALPHA) */ \ + /* DST_ALPHA = SRC_ALPHA + DST_ALPHA * (1 - SRC_ALPHA) */ \ + /* DST /= DST_ALPHA */ \ int _tmp_multi = *_pdst_alpha * (255 - _src_alpha); \ - int _tmp_alpha = _src_alpha + _tmp_multi; \ - _tmp_red = RGB_COMPOSE(_src_red, _src_alpha, *_pdst_red, _tmp_multi, _tmp_alpha); \ - _tmp_green = RGB_COMPOSE(_src_green, _src_alpha, *_pdst_green, _tmp_multi, _tmp_alpha); \ - _tmp_blue = RGB_COMPOSE(_src_blue, _src_alpha, *_pdst_blue, _tmp_multi, _tmp_alpha); \ + int _tmp_src_alpha = _src_alpha*255; \ + int _tmp_alpha = _tmp_src_alpha + _tmp_multi; \ + _tmp_red = RGB_COMPOSE_OVER(_src_red, _tmp_src_alpha, *_pdst_red, _tmp_multi, _tmp_alpha); \ + _tmp_green = RGB_COMPOSE_OVER(_src_green, _tmp_src_alpha, *_pdst_green, _tmp_multi, _tmp_alpha); \ + _tmp_blue = RGB_COMPOSE_OVER(_src_blue, _tmp_src_alpha, *_pdst_blue, _tmp_multi, _tmp_alpha); \ *_pdst_alpha = (unsigned char)(_tmp_alpha / 255); \ + RGBA_WRITE_MODE(CD_REPLACE, _pdst_red, _pdst_green, _pdst_blue, \ + _tmp_red, _tmp_green, _tmp_blue); \ } \ } \ else /* (_src_alpha == 0) source full transparent */ \ @@ -97,6 +130,8 @@ struct _cdCtxCanvas _tmp_red = *_pdst_red; \ _tmp_green = *_pdst_green; \ _tmp_blue = *_pdst_blue; \ + RGBA_WRITE_MODE(CD_REPLACE, _pdst_red, _pdst_green, _pdst_blue, \ + _tmp_red, _tmp_green, _tmp_blue); \ /* *_pdst_alpha is not changed */ \ } \ } \ @@ -106,9 +141,11 @@ struct _cdCtxCanvas _tmp_green = _src_green; \ _tmp_blue = _src_blue; \ *_pdst_alpha = (unsigned char)255; /* set destiny as opaque */ \ + RGBA_WRITE_MODE(_ctxcanvas->canvas->write_mode, _pdst_red, _pdst_green, _pdst_blue, \ + _tmp_red, _tmp_green, _tmp_blue); \ } \ } \ - else /* (_pdst_alpha == NULL) */ \ + else /* destiny does NOT have alpha */ \ { \ if (_src_alpha != 255) /* source has some transparency */ \ { \ @@ -117,12 +154,16 @@ struct _cdCtxCanvas _tmp_red = CD_ALPHA_BLEND(_src_red, *_pdst_red, _src_alpha); \ _tmp_green = CD_ALPHA_BLEND(_src_green, *_pdst_green, _src_alpha); \ _tmp_blue = CD_ALPHA_BLEND(_src_blue, *_pdst_blue, _src_alpha); \ + RGBA_WRITE_MODE(CD_REPLACE, _pdst_red, _pdst_green, _pdst_blue, \ + _tmp_red, _tmp_green, _tmp_blue); \ } \ else /* (_src_alpha == 0) source full transparent */ \ { \ _tmp_red = *_pdst_red; \ _tmp_green = *_pdst_green; \ _tmp_blue = *_pdst_blue; \ + RGBA_WRITE_MODE(CD_REPLACE, _pdst_red, _pdst_green, _pdst_blue, \ + _tmp_red, _tmp_green, _tmp_blue); \ } \ } \ else /* (_src_alpha == 255) source has no alpha = opaque */ \ @@ -130,26 +171,9 @@ struct _cdCtxCanvas _tmp_red = _src_red; \ _tmp_green = _src_green; \ _tmp_blue = _src_blue; \ + RGBA_WRITE_MODE(_ctxcanvas->canvas->write_mode, _pdst_red, _pdst_green, _pdst_blue, \ + _tmp_red, _tmp_green, _tmp_blue); \ } \ - } \ - \ - switch (_ctxcanvas->canvas->write_mode) \ - { \ - case CD_REPLACE: \ - *_pdst_red = _tmp_red; \ - *_pdst_green = _tmp_green; \ - *_pdst_blue = _tmp_blue; \ - break; \ - case CD_XOR: \ - *_pdst_red ^= _tmp_red; \ - *_pdst_green ^= _tmp_green; \ - *_pdst_blue ^= _tmp_blue; \ - break; \ - case CD_NOT_XOR: \ - *_pdst_red = (unsigned char)~(_tmp_red ^ *_pdst_red); \ - *_pdst_green = (unsigned char)~(_tmp_green ^ *_pdst_green); \ - *_pdst_blue = (unsigned char)~(_tmp_blue ^ *_pdst_blue); \ - break; \ } \ } @@ -405,7 +429,7 @@ static void cdclear(cdCtxCanvas* ctxcanvas) memset(ctxcanvas->red, cdRed(ctxcanvas->canvas->background), size); memset(ctxcanvas->green, cdGreen(ctxcanvas->canvas->background), size); memset(ctxcanvas->blue, cdBlue(ctxcanvas->canvas->background), size); - if (ctxcanvas->alpha) memset(ctxcanvas->alpha, cdAlpha(ctxcanvas->canvas->background), size); + if (ctxcanvas->alpha) memset(ctxcanvas->alpha, cdAlpha(ctxcanvas->canvas->background), size); /* here is the normal alpha coding */ } static void irgPostProcessIntersect(unsigned char* clip, int size) @@ -465,15 +489,16 @@ static int compare_int(const int* xx1, const int* xx2) static void irgbClipPoly(cdCtxCanvas* ctxcanvas, unsigned char* clip_region, cdPoint* poly, int n, int combine_mode) { + /***********IMPORTANT: the reference for this function is simPolyFill in "sim_linepolyfill.c", + if a change is made here, must be reflected there, and vice-versa */ cdCanvas* canvas = ctxcanvas->canvas; unsigned char* clip_line; - simLineSegment *seg_i; cdPoint* t_poly = NULL; - int y_max, y_min, i, y, i1, fill_mode, num_lines, - inter_count, width, height; + int y_max, y_min, i, y, fill_mode, num_lines, + xx_count, width, height, *xx, *hh, max_hh, n_seg; - int *xx = (int*)malloc((n+1)*sizeof(int)); - simLineSegment *segment = (simLineSegment *)malloc(n*sizeof(simLineSegment)); + /* alloc maximum number of segments */ + simLineSegment *segments = (simLineSegment *)malloc(n*sizeof(simLineSegment)); if (canvas->use_matrix) { @@ -489,112 +514,55 @@ static void irgbClipPoly(cdCtxCanvas* ctxcanvas, unsigned char* clip_region, cdP height = canvas->h; fill_mode = canvas->fill_mode; - y_max = poly[0].y; - y_min = poly[0].y; - for(i = 0; i < n; i++) + simPolyMakeSegments(segments, &n_seg, poly, n, &max_hh, &y_max, &y_min); + + if (y_min > height-1 || y_max < 0) { - i1 = (i+1)%n; /* next point(i+1), next of last(n-1) is first(0) */ - simAddSegment(segment+i, poly[i].x, poly[i].y, poly[i1].x, poly[i1].y, &y_max, &y_min); + free(segments); + return; } if (y_min < 0) y_min = 0; + /* number of horizontal lines */ if (y_max > height-1) num_lines = height-y_min; else num_lines = y_max-y_min+1; + /* buffer to store the current horizontal intervals during the fill of an horizontal line */ + xx = (int*)malloc((n+1)*sizeof(int)); /* allocated to the maximum number of possible intervals in one line */ + hh = (int*)malloc((2*max_hh)*sizeof(int)); + /* for all horizontal lines between y_max and y_min */ for(y = y_max; y >= y_min; y--) { - inter_count = 0; - - /* for all segments, calculates the intervals to be filled. */ - for(i = 0; i < n; i++) - { - seg_i = segment + i; - - /* if the minimum Y coordinate of the segment is greater than the current y, then ignore the segment. */ - /* if it is an horizontal line, then ignore the segment. */ - if (seg_i->y1 > y || - seg_i->y1 == seg_i->y2) - continue; - - if (y == seg_i->y1) /* intersection at the start point (x1,y1) */ - { - int i_next = (i==n-1)? 0: i+1; - int i_prev = (i==0)? n-1: i-1; - simLineSegment *seg_i_next = segment + i_next; - simLineSegment *seg_i_prev = segment + i_prev; - - /* always save at least one intersection point for (y1) */ - - xx[inter_count++] = seg_i->x1; /* save the intersection point */ - - /* check for missing bottom-corner points (|_|), must duplicate the intersection */ - if ((seg_i_next->y1 == y && seg_i_next->y2 == seg_i_next->y1) || /* next is an horizontal line */ - (seg_i_prev->y1 == y && seg_i_prev->y2 == seg_i_prev->y1)) /* previous is an horizontal line */ - { - xx[inter_count++] = seg_i->x1; /* save the intersection point */ - } - } - else if ((y > seg_i->y1) && (y < seg_i->y2)) /* intersection inside the segment, do not include y2 */ - { - xx[inter_count++] = simSegmentInc(seg_i, canvas, y); /* save the intersection point */ - } - else if (y == seg_i->y2) /* intersection at the end point (x2,y2) */ - { - int i_next = (i==n-1)? 0: i+1; - int i_prev = (i==0)? n-1: i-1; - simLineSegment *seg_i_next = segment + i_next; - simLineSegment *seg_i_prev = segment + i_prev; - - /* only save the intersection point for (y2) if not handled by (y1) of another segment */ - - /* check for missing top-corner points (^) or (|ŻŻ|) */ - if ((seg_i_next->y2 == y && seg_i_next->y2 == seg_i_next->y1) || /* next is an horizontal line */ - (seg_i_prev->y2 == y && seg_i_prev->y2 == seg_i_prev->y1) || /* previous is an horizontal line */ - (seg_i_next->y2 == y && seg_i_next->x2 == seg_i->x2 && seg_i_next->x1 != seg_i->x1) || - (seg_i_prev->y2 == y && seg_i_prev->x2 == seg_i->x2 && seg_i_prev->x1 != seg_i->x1)) - { - xx[inter_count++] = seg_i->x2; /* save the intersection point */ - } - } - } - - /* if outside the canvas, ignore the intervals and */ - /* continue since the segments where updated. */ - if (y > height-1 || inter_count == 0) + xx_count = simPolyFindHorizontalIntervals(segments, n_seg, xx, hh, y, height); + if (xx_count < 2) continue; - - /* sort the intervals */ - qsort(xx, inter_count, sizeof(int), (int (*)(const void*,const void*))compare_int); clip_line = clip_region + y*width; /* for all intervals, fill the interval */ - for(i = 0; i < inter_count; i += 2) + for(i = 0; i < xx_count; i += 2) /* process only pairs */ { - if (fill_mode == CD_EVENODD) - { - /* since it fills only pairs of intervals, */ - /* it is the EVENODD fill rule. */ - irgbClipFillLine(clip_line, combine_mode, xx[i], xx[i+1], width); - } - else + /* fills only pairs of intervals, */ + irgbClipFillLine(clip_line, combine_mode, xx[i], xx[i+1], width); + + if ((fill_mode == CD_WINDING) && /* NOT EVENODD */ + ((i+2 < xx_count) && (xx[i+1] < xx[i+2])) && /* avoid point intervals */ + simIsPointInPolyWind(poly, n, (xx[i+1]+xx[i+2])/2, y)) /* the next interval is inside the polygon */ { - irgbClipFillLine(clip_line, combine_mode, xx[i], xx[i+1], width); - if ((i+2 < inter_count) && (xx[i+1] < xx[i+2])) /* avoid point intervals */ - if (simIsPointInPolyWind(poly, n, (xx[i+1]+xx[i+2])/2, y)) /* if the next interval is inside the polygon then fill it */ - irgbClipFillLine(clip_line, combine_mode, xx[i+1], xx[i+2], width); + irgbClipFillLine(clip_line, combine_mode, xx[i+1], xx[i+2], width); } } } if (t_poly) free(t_poly); free(xx); - free(segment); + free(hh); + free(segments); if (combine_mode == CD_INTERSECT) irgPostProcessIntersect(ctxcanvas->clip_region, ctxcanvas->canvas->w * ctxcanvas->canvas->h); @@ -1440,8 +1408,8 @@ static cdCtxImage* cdcreateimage(cdCtxCanvas* ctxcanvas, int w, int h) if (ctxcanvas->alpha) ctximage->alpha = ctximage->red + 3*size; - memset(ctximage->red, 0xFF, 3*size); - if (ctximage->alpha) memset(ctximage->alpha, 0, size); /* transparent */ + memset(ctximage->red, 0xFF, 3*size); /* white */ + if (ctximage->alpha) memset(ctximage->alpha, 0, size); /* transparent, this is the normal alpha coding */ return ctximage; } @@ -1842,7 +1810,7 @@ static void cdcreatecanvas(cdCanvas* canvas, void *data) ctxcanvas->alpha = ctxcanvas->red + 3*size; memset(ctxcanvas->red, 0xFF, 3*size); /* white */ - if (ctxcanvas->alpha) memset(ctxcanvas->alpha, 0, size); /* transparent */ + if (ctxcanvas->alpha) memset(ctxcanvas->alpha, 0, size); /* transparent, this is the normal alpha coding */ } ctxcanvas->clip = (unsigned char*)malloc(w*h); diff --git a/cd/src/drv/cdmf.c b/cd/src/drv/cdmf.c index d44bb5e..727fcac 100755 --- a/cd/src/drv/cdmf.c +++ b/cd/src/drv/cdmf.c @@ -354,7 +354,7 @@ static void cdpattern(cdCtxCanvas *ctxcanvas, int w, int h, const long int *patt { cdDecodeColor(*pattern++, &r, &g, &b); fprintf(ctxcanvas->file, "%d %d %d ", (int)r, (int)g, (int)b); - if (c % w == 0) + if ((c + 1) % w == 0) fprintf(ctxcanvas->file, "\n"); } } @@ -767,15 +767,15 @@ static int cdplay(cdCanvas* canvas, int xmin, int xmax, int ymin, int ymax, void wdCanvasChord(canvas, dparam1, dparam2, dparam3, dparam4, dparam5, dparam6); break; case CDMF_TEXT: - fscanf(file, "%d %d %[^\n]", &iparam1, &iparam2, TextBuffer); + fscanf(file, "%d %d %[^\n\r]", &iparam1, &iparam2, TextBuffer); cdCanvasText(canvas, sScaleX(iparam1), sScaleY(iparam2), TextBuffer); break; case CDMF_FTEXT: - fscanf(file, "%lg %lg %[^\n]", &dparam1, &dparam2, TextBuffer); + fscanf(file, "%lg %lg %[^\n\r]", &dparam1, &dparam2, TextBuffer); cdfCanvasText(canvas, sfScaleX(dparam1), sfScaleY(dparam2), TextBuffer); break; case CDMF_WTEXT: - fscanf(file, "%lg %lg %[^\n]", &dparam1, &dparam2, TextBuffer); + fscanf(file, "%lg %lg %[^\n\r]", &dparam1, &dparam2, TextBuffer); wdCanvasText(canvas, dparam1, dparam2, TextBuffer); break; case CDMF_BEGIN: @@ -891,7 +891,7 @@ static int cdplay(cdCanvas* canvas, int xmin, int xmax, int ymin, int ymax, void cdCanvasFont(canvas, font_family[iparam1], iparam2, iparam3); break; case CDMF_FONT: - fscanf(file, "%d %d %[^\n]", &iparam2, &iparam3, TextBuffer); + fscanf(file, "%d %d %[^\n\r]", &iparam2, &iparam3, TextBuffer); if (iparam3 < 0) { iparam3 = -sScaleH(abs(iparam3)); @@ -905,7 +905,7 @@ static int cdplay(cdCanvas* canvas, int xmin, int xmax, int ymin, int ymax, void cdCanvasFont(canvas, TextBuffer, iparam2, iparam3); break; case CDMF_NATIVEFONT: - fscanf(file, "%[^\n]", TextBuffer); + fscanf(file, "%[^\n\r]", TextBuffer); cdCanvasNativeFont(canvas, TextBuffer); break; case CDMF_TEXTALIGNMENT: @@ -1013,19 +1013,19 @@ static int cdplay(cdCanvas* canvas, int xmin, int xmax, int ymin, int ymax, void 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); + fscanf(file, "%lg %lg %[^\n\r]", &dparam1, &dparam2, TextBuffer); wdCanvasVectorText(canvas, dparam1, dparam2, TextBuffer); break; case CDMF_WMULTILINEVECTORTEXT: - fscanf(file, "%lg %lg %[^\n]", &dparam1, &dparam2, TextBuffer); + fscanf(file, "%lg %lg %[^\n\r]", &dparam1, &dparam2, TextBuffer); wdCanvasVectorText(canvas, dparam1, dparam2, TextBuffer); break; case CDMF_VECTORTEXT: - fscanf(file, "%d %d %[^\n]", &iparam1, &iparam2, TextBuffer); + fscanf(file, "%d %d %[^\n\r]", &iparam1, &iparam2, TextBuffer); cdCanvasVectorText(canvas, iparam1, iparam2, TextBuffer); break; case CDMF_MULTILINEVECTORTEXT: - fscanf(file, "%d %d %[^\n]", &iparam1, &iparam2, TextBuffer); + fscanf(file, "%d %d %[^\n\r]", &iparam1, &iparam2, TextBuffer); cdCanvasVectorText(canvas, iparam1, iparam2, TextBuffer); break; case CDMF_WVECTORCHARSIZE: @@ -1033,7 +1033,7 @@ static int cdplay(cdCanvas* canvas, int xmin, int xmax, int ymin, int ymax, void wdCanvasVectorCharSize(canvas, dparam1); break; case CDMF_WVECTORTEXTSIZE: - fscanf(file, "%lg %lg %[^\n]", &dparam1, &dparam2, TextBuffer); + fscanf(file, "%lg %lg %[^\n\r]", &dparam1, &dparam2, TextBuffer); wdCanvasVectorTextSize(canvas, dparam1, dparam2, TextBuffer); break; case CDMF_WVECTORTEXTDIRECTION: @@ -1045,7 +1045,7 @@ static int cdplay(cdCanvas* canvas, int xmin, int xmax, int ymin, int ymax, void cdCanvasVectorCharSize(canvas, iparam1); break; case CDMF_VECTORTEXTSIZE: - fscanf(file, "%d %d %[^\n]", &iparam1, &iparam2, TextBuffer); + fscanf(file, "%d %d %[^\n\r]", &iparam1, &iparam2, TextBuffer); cdCanvasVectorTextSize(canvas, iparam1, iparam2, TextBuffer); break; case CDMF_VECTORTEXTDIRECTION: @@ -1053,7 +1053,7 @@ static int cdplay(cdCanvas* canvas, int xmin, int xmax, int ymin, int ymax, void cdCanvasVectorTextDirection(canvas, iparam1, iparam2, iparam3, iparam4); break; case CDMF_VECTORFONT: - fscanf(file, "%[^\n]", TextBuffer); + fscanf(file, "%[^\n\r]", TextBuffer); cdCanvasVectorFont(canvas, TextBuffer); break; case CDMF_VECTORTEXTTRANSFORM: diff --git a/cd/src/drv/cdpdf.c b/cd/src/drv/cdpdf.c index 79ce28f..a5d91d4 100755 --- a/cd/src/drv/cdpdf.c +++ b/cd/src/drv/cdpdf.c @@ -1278,6 +1278,71 @@ static cdAttribute pattern_attrib = NULL }; +static void set_subject_attrib(cdCtxCanvas *ctxcanvas, char* data) +{ + if (data) + PDF_set_info(ctxcanvas->pdf, "Subject", data); +} + +static cdAttribute subject_attrib = +{ + "SUBJECT", + set_subject_attrib, + NULL +}; + +static void set_title_attrib(cdCtxCanvas *ctxcanvas, char* data) +{ + if (data) + PDF_set_info(ctxcanvas->pdf, "Title", data); +} + +static cdAttribute title_attrib = +{ + "TITLE", + set_title_attrib, + NULL +}; + +static void set_creator_attrib(cdCtxCanvas *ctxcanvas, char* data) +{ + if (data) + PDF_set_info(ctxcanvas->pdf, "Creator", data); +} + +static cdAttribute creator_attrib = +{ + "CREATOR", + set_creator_attrib, + NULL +}; + +static void set_author_attrib(cdCtxCanvas *ctxcanvas, char* data) +{ + if (data) + PDF_set_info(ctxcanvas->pdf, "Author", data); +} + +static cdAttribute author_attrib = +{ + "AUTHOR", + set_author_attrib, + NULL +}; + +static void set_keywords_attrib(cdCtxCanvas *ctxcanvas, char* data) +{ + if (data) + PDF_set_info(ctxcanvas->pdf, "Keywords", data); +} + +static cdAttribute keywords_attrib = +{ + "KEYWORDS", + set_keywords_attrib, + NULL +}; + static void set_opacity_attrib(cdCtxCanvas *ctxcanvas, char* data) { int state; @@ -1331,6 +1396,19 @@ static cdAttribute pdf_attrib = get_pdf_attrib }; +static char* get_version_attrib(cdCtxCanvas* ctxcanvas) +{ + (void)ctxcanvas; + return (char*)PDF_get_parameter(ctxcanvas->pdf, "version", 0); +} + +static cdAttribute version_attrib = +{ + "PDFLIBVERSION", + NULL, + get_version_attrib +}; + static void cdcreatecanvas(cdCanvas* canvas, void *data) { char *line = (char *)data; @@ -1367,6 +1445,12 @@ static void cdcreatecanvas(cdCanvas* canvas, void *data) cdRegisterAttribute(canvas, &opacity_attrib); cdRegisterAttribute(canvas, &pattern_attrib); cdRegisterAttribute(canvas, &pdf_attrib); + cdRegisterAttribute(canvas, &subject_attrib); + cdRegisterAttribute(canvas, &title_attrib); + cdRegisterAttribute(canvas, &creator_attrib); + cdRegisterAttribute(canvas, &author_attrib); + cdRegisterAttribute(canvas, &keywords_attrib); + cdRegisterAttribute(canvas, &version_attrib); setpdfdefaultvalues(ctxcanvas); @@ -1473,7 +1557,7 @@ static cdContext cdPDFContext = CD_CAP_ALL & ~(CD_CAP_CLEAR | CD_CAP_PLAY | CD_CAP_PALETTE | CD_CAP_REGION | CD_CAP_IMAGESRV | CD_CAP_TEXTSIZE | CD_CAP_BACKGROUND | CD_CAP_BACKOPACITY | CD_CAP_WRITEMODE | - CD_CAP_IMAGERGBA | CD_CAP_GETIMAGERGB), + CD_CAP_GETIMAGERGB), 0, cdcreatecanvas, cdinittable, @@ -1485,7 +1569,3 @@ cdContext* cdContextPDF(void) { return &cdPDFContext; } - -/* -p.set_info("Creator", "PDFlib Cookbook") -*/ diff --git a/cd/src/drv/cdpicture.c b/cd/src/drv/cdpicture.c index ff4f532..a5533b2 100755 --- a/cd/src/drv/cdpicture.c +++ b/cd/src/drv/cdpicture.c @@ -360,6 +360,15 @@ void primUpdateAttrib_Text(tPrimNode *prim, cdCanvas *canvas) cdCanvasFont(canvas, prim->attrib.text.font_type_face, prim->attrib.text.font_style, prim->attrib.text.font_size); } +static int cdfont(cdCtxCanvas *ctxcanvas, const char *type_face, int style, int size) +{ + (void)ctxcanvas; + (void)type_face; + (void)style; + (void)size; + return 1; +} + static void cdclear(cdCtxCanvas *ctxcanvas) { tPrimNode *prim; @@ -1092,6 +1101,7 @@ static void cdcreatecanvas(cdCanvas *canvas, void *data) static void cdinittable(cdCanvas* canvas) { + canvas->cxFont = cdfont; canvas->cxClear = cdclear; canvas->cxPixel = cdpixel; canvas->cxLine = cdline; diff --git a/cd/src/drv/cdps.c b/cd/src/drv/cdps.c index d5d62fe..ef77c4d 100755 --- a/cd/src/drv/cdps.c +++ b/cd/src/drv/cdps.c @@ -466,6 +466,8 @@ static void cdflush(cdCtxCanvas *ctxcanvas) { if (ctxcanvas->debug) fprintf(ctxcanvas->file, "\n%%cdFlush Begin\n"); + fflush(ctxcanvas->file); + if (!ctxcanvas->eps) { fprintf(ctxcanvas->file, "gsave\n"); -- cgit v1.2.3