diff options
author | scuri <scuri> | 2009-06-23 03:18:33 +0000 |
---|---|---|
committer | scuri <scuri> | 2009-06-23 03:18:33 +0000 |
commit | 0610dd4f3064220a2e8fb1d8dc120044eb6c64a8 (patch) | |
tree | a5d0d3b6c79e967cd4e80c7668b906e8b422f902 /src | |
parent | 09be96e0606d05b056f82b5f9254208a2d0e4c88 (diff) |
*** empty log message ***
Diffstat (limited to 'src')
-rw-r--r-- | src/cd.c | 10 | ||||
-rw-r--r-- | src/cd.def | 4 | ||||
-rw-r--r-- | src/cd_active.c | 1 | ||||
-rw-r--r-- | src/cd_text.c | 184 | ||||
-rw-r--r-- | src/cd_util.c | 50 | ||||
-rw-r--r-- | src/cd_vectortext.c | 901 | ||||
-rw-r--r-- | src/drv/cdcgm.c | 4 | ||||
-rw-r--r-- | src/drv/cdpicture.c | 8 | ||||
-rw-r--r-- | src/intcgm/bparse.c | 6 | ||||
-rw-r--r-- | src/intcgm/intcgm2.c | 6 | ||||
-rw-r--r-- | src/intcgm/tparse.c | 2 | ||||
-rw-r--r-- | src/lua5/cdlua5_canvas.c | 118 | ||||
-rw-r--r-- | src/pdflib/pdflib/p_type3.c | 4 | ||||
-rw-r--r-- | src/sim/cdfontex.c | 20 | ||||
-rw-r--r-- | src/sim/sim_text.c | 4 | ||||
-rw-r--r-- | src/win32/cdwin.c | 8 | ||||
-rw-r--r-- | src/win32/cdwwmf.c | 2 | ||||
-rw-r--r-- | src/x11/xvertex.c | 52 |
18 files changed, 1011 insertions, 373 deletions
@@ -18,8 +18,8 @@ #include "cdirgb.h" /* This appears only here to avoid changing the cd.h header fo bug fixes */ -#define CD_VERSION_FIX "" -#define CD_VERSION_FIX_NUMBER 0 +#define CD_VERSION_FIX ".1" +#define CD_VERSION_FIX_NUMBER 1 const char cd_ident[] = "$CD: " CD_VERSION CD_VERSION_FIX " " CD_COPYRIGHT " $\n" @@ -46,7 +46,6 @@ int cdVersionNumber(void) static void cd_setdefaultfunc(cdCanvas* canvas) { - /* default simulation functions */ canvas->cxGetTextSize = cdgettextsizeEX; canvas->cxGetFontDim = cdgetfontdimEX; canvas->cxRect = cdrectSIM; @@ -161,7 +160,7 @@ cdCanvas *cdCreateCanvas(cdContext* context, void *data_str) return NULL; } - /* functions that can do nothing, must be before InitTable */ + /* default simulation functions */ cd_setdefaultfunc(canvas); /* initialize canvas table */ @@ -257,7 +256,10 @@ int cdCanvasSimulate(cdCanvas* canvas, int mode) if (mode == CD_QUERY || cdCanvasGetContext(canvas) == CD_IMAGERGB) return sim_mode; + /* default simulation functions */ cd_setdefaultfunc(canvas); + + /* initialize canvas table */ context->cxInitTable(canvas); canvas->sim_mode = mode; @@ -232,6 +232,7 @@ EXPORTS wdCanvasGetTextBox wdCanvasGetTextSize wdCanvasGetVectorTextBounds + wdCanvasGetVectorTextBox wdCanvasGetVectorTextSize wdCanvasGetViewport wdCanvasGetWindow @@ -289,6 +290,8 @@ EXPORTS cdCanvasPlay cdCanvasRegionCombineMode cdCanvasVectorCharSize + cdCanvasVectorFontSize + cdCanvasGetVectorFontSize cdCanvasWriteMode cdCanvasUpdateYAxis cdCanvasInvertYAxis @@ -324,6 +327,7 @@ EXPORTS cdCanvasGetTextBox cdCanvasGetTextSize cdCanvasGetVectorTextBounds + cdCanvasGetVectorTextBox cdCanvasGetVectorTextSize cdCanvasLine cdCanvasLineStyleDashes diff --git a/src/cd_active.c b/src/cd_active.c index 0ae489a..f8229bd 100644 --- a/src/cd_active.c +++ b/src/cd_active.c @@ -1004,4 +1004,3 @@ void wdGetVectorTextBounds(const char* s, double x, double y, double *rect) if (!active_canvas) return; wdCanvasGetVectorTextBounds(active_canvas, s, x, y, rect); } - diff --git a/src/cd_text.c b/src/cd_text.c index a06f9b1..8a5ff81 100644 --- a/src/cd_text.c +++ b/src/cd_text.c @@ -11,13 +11,14 @@ #include <memory.h> #include <math.h> - #include "cd.h" #include "cd_private.h" void cdCanvasText(cdCanvas* canvas, int x, int y, const char *s) { + int num_line; + assert(canvas); assert(s); if (!_cdCheckCanvas(canvas)) return; @@ -34,11 +35,83 @@ void cdCanvasText(cdCanvas* canvas, int x, int y, const char *s) if (canvas->invert_yaxis) y = _cdInvertYAxis(canvas, y); - canvas->cxText(canvas->ctxcanvas, x, y, s); + num_line = cdStrLineCount(s); + if (num_line == 1) + canvas->cxText(canvas->ctxcanvas, x, y, s); + else + { + int i, line_height; + char *p, *q, *new_s; + double cos_theta = 0, sin_theta = 0; + + new_s = cdStrDup(s); + p = new_s; + + canvas->cxGetFontDim(canvas->ctxcanvas, NULL, &line_height, NULL, NULL); + + if (canvas->text_orientation) + { + int align = canvas->text_alignment; + cos_theta = cos(canvas->text_orientation*CD_DEG2RAD); + sin_theta = sin(canvas->text_orientation*CD_DEG2RAD); + + /* position vertically at the first line */ + if (align == CD_NORTH || align == CD_NORTH_EAST || align == CD_NORTH_WEST || /* it is relative to the full text */ + align == CD_BASE_LEFT || align == CD_BASE_CENTER || align == CD_BASE_RIGHT) /* it is relative to the first line already */ + { + /* Already at position */ + } + else if (align == CD_SOUTH || align == CD_SOUTH_EAST || align == CD_SOUTH_WEST) /* it is relative to the full text */ + { + cdMovePoint(&x, &y, 0, (num_line-1)*line_height, sin_theta, cos_theta); + } + else /* CD_CENTER || CD_EAST || CD_WEST */ /* it is relative to the full text */ + cdMovePoint(&x, &y, 0, (num_line-1)*line_height/2.0, sin_theta, cos_theta); + } + else + { + int align = canvas->text_alignment; + + /* position vertically at the first line */ + if (align == CD_NORTH || align == CD_NORTH_EAST || align == CD_NORTH_WEST || /* it is relative to the full text */ + align == CD_BASE_LEFT || align == CD_BASE_CENTER || align == CD_BASE_RIGHT) /* it is relative to the first line already */ + { + /* Already at position */ + } + else if (align == CD_SOUTH || align == CD_SOUTH_EAST || align == CD_SOUTH_WEST) /* it is relative to the full text */ + { + y += (num_line-1)*line_height; + } + else /* CD_CENTER || CD_EAST || CD_WEST */ /* it is relative to the full text */ + y += ((num_line-1)*line_height)/2; + } + + for(i = 0; i < num_line; i++) + { + q = strchr(p, '\n'); + if (q) *q = 0; /* Cut the string to contain only one line */ + + /* Draw the line */ + canvas->cxText(canvas->ctxcanvas, x, y, p); + + /* Advance the string */ + if (q) p = q + 1; + + /* Advance a line */ + if (canvas->text_orientation) + cdMovePoint(&x, &y, 0, -line_height, sin_theta, cos_theta); + else + y -= line_height; + } + + free(new_s); + } } void cdfCanvasText(cdCanvas* canvas, double x, double y, const char *s) { + int num_line; + assert(canvas); assert(s); if (!_cdCheckCanvas(canvas)) return; @@ -55,10 +128,68 @@ void cdfCanvasText(cdCanvas* canvas, double x, double y, const char *s) if (canvas->invert_yaxis) y = _cdInvertYAxis(canvas, y); - if (canvas->cxFText) - canvas->cxFText(canvas->ctxcanvas, x, y, s); + num_line = cdStrLineCount(s); + if (num_line == 1) + { + if (canvas->cxFText) + canvas->cxFText(canvas->ctxcanvas, x, y, s); + else + canvas->cxText(canvas->ctxcanvas, _cdRound(x), _cdRound(y), s); + } else - canvas->cxText(canvas->ctxcanvas, _cdRound(x), _cdRound(y), s); + { + int i, line_height; + char *p, *q, *new_s; + double cos_theta = 0, sin_theta = 0; + + new_s = cdStrDup(s); + p = new_s; + + canvas->cxGetFontDim(canvas->ctxcanvas, NULL, &line_height, NULL, NULL); + + if (canvas->text_orientation) + { + int align = canvas->text_alignment; + cos_theta = cos(canvas->text_orientation*CD_DEG2RAD); + sin_theta = sin(canvas->text_orientation*CD_DEG2RAD); + + /* position vertically at the first line */ + if (align == CD_NORTH || align == CD_NORTH_EAST || align == CD_NORTH_WEST || /* it is relative to the full text */ + align == CD_BASE_LEFT || align == CD_BASE_CENTER || align == CD_BASE_RIGHT) /* it is relative to the first line already */ + { + /* Already at position */ + } + else if (align == CD_SOUTH || align == CD_SOUTH_EAST || align == CD_SOUTH_WEST) /* it is relative to the full text */ + { + cdfMovePoint(&x, &y, 0, (num_line-1)*line_height, sin_theta, cos_theta); + } + else /* CD_CENTER || CD_EAST || CD_WEST */ /* it is relative to the full text */ + cdfMovePoint(&x, &y, 0, (num_line-1)*line_height/2.0, sin_theta, cos_theta); + } + + for(i = 0; i < num_line; i++) + { + q = strchr(p, '\n'); + if (q) *q = 0; /* Cut the string to contain only one line */ + + /* Draw the line */ + if (canvas->cxFText) + canvas->cxFText(canvas->ctxcanvas, x, y, p); + else + canvas->cxText(canvas->ctxcanvas, _cdRound(x), _cdRound(y), p); + + /* Advance the string */ + if (q) p = q + 1; + + /* Advance a line */ + if (canvas->text_orientation) + cdfMovePoint(&x, &y, 0, -line_height, sin_theta, cos_theta); + else + y -= line_height; + } + + free(new_s); + } } int cdGetFontSizePixels(cdCanvas* canvas, int size) @@ -96,6 +227,7 @@ int cdCanvasFont(cdCanvas* canvas, const char* type_face, int style, int size) assert(canvas); assert(style>=-1 && style<=CD_STRIKEOUT); if (!_cdCheckCanvas(canvas)) return CD_ERROR; + if (!type_face || type_face[0]==0) type_face = canvas->font_type_face; if (style==-1) @@ -235,10 +367,43 @@ void cdCanvasGetFontDim(cdCanvas* canvas, int *max_width, int *height, int *asce void cdCanvasGetTextSize(cdCanvas* canvas, const char *s, int *width, int *height) { + int num_line; + assert(canvas); assert(s); if (!_cdCheckCanvas(canvas)) return; - canvas->cxGetTextSize(canvas->ctxcanvas, s, width, height); + + num_line = cdStrLineCount(s); + if (num_line == 1) + canvas->cxGetTextSize(canvas->ctxcanvas, s, width, height); + else + { + int i, line_height, max_w = 0, w; + char *p, *q, *new_s; + + new_s = cdStrDup(s); + p = new_s; + + canvas->cxGetFontDim(canvas->ctxcanvas, NULL, &line_height, NULL, NULL); + + for(i = 0; i < num_line; i++) + { + q = strchr(p, '\n'); + if (q) *q = 0; /* Cut the string to contain only one line */ + + /* Calculate line width */ + canvas->cxGetTextSize(canvas->ctxcanvas, p, &w, NULL); + if (w > max_w) max_w = w; + + /* Advance the string */ + if (q) p = q + 1; + } + + if (width) *width = max_w; + if (height) *height = num_line*line_height; + + free(new_s); + } } void cdTextTranslatePoint(cdCanvas* canvas, int x, int y, int w, int h, int baseline, int *rx, int *ry) @@ -306,6 +471,13 @@ void cdCanvasGetTextBounds(cdCanvas* canvas, int x, int y, const char *s, int *r int w, h, ascent, height, baseline; int xmin, xmax, ymin, ymax; int old_invert_yaxis = canvas->invert_yaxis; + + assert(canvas); + assert(s); + if (!_cdCheckCanvas(canvas)) return; + + if (s[0] == 0) + return; cdCanvasGetTextSize(canvas, s, &w, &h); cdCanvasGetFontDim(canvas, NULL, &height, &ascent, NULL); diff --git a/src/cd_util.c b/src/cd_util.c index 033fac6..dadb6f4 100644 --- a/src/cd_util.c +++ b/src/cd_util.c @@ -223,6 +223,21 @@ int cdfCheckBoxSize(double *xmin, double *xmax, double *ymin, double *ymax) return 1; } +void cdMovePoint(int *x, int *y, double dx, double dy, double sin_theta, double cos_theta) +{ + double t; + t = cos_theta*dx - sin_theta*dy; + *x += _cdRound(t); + t = sin_theta*dx + cos_theta*dy; + *y += _cdRound(t); +} + +void cdfMovePoint(double *x, double *y, double dx, double dy, double sin_theta, double cos_theta) +{ + *x += cos_theta*dx - sin_theta*dy; + *y += sin_theta*dx + cos_theta*dy; +} + void cdRotatePoint(cdCanvas* canvas, int x, int y, int cx, int cy, int *rx, int *ry, double sin_theta, double cos_theta) { double t; @@ -283,3 +298,38 @@ int cdStrEqualNoCase(const char* str1, const char* str2) return 0; } +/* Copied from IUP3, simply ignore line breaks other than '\n' for CD */ + +int cdStrLineCount(const char* str) +{ + int num_lin = 1; + + if (!str) + return num_lin; + + while(*str != 0) + { + while(*str!=0 && *str!='\n') + str++; + + if (*str=='\n') /* UNIX line end */ + { + num_lin++; + str++; + } + } + + return num_lin; +} + +char* cdStrDup(const char *str) +{ + if (str) + { + int size = strlen(str)+1; + char *newstr = malloc(size); + if (newstr) memcpy(newstr, str, size); + return newstr; + } + return NULL; +} diff --git a/src/cd_vectortext.c b/src/cd_vectortext.c index 9886a3b..0be62af 100644 --- a/src/cd_vectortext.c +++ b/src/cd_vectortext.c @@ -8,6 +8,7 @@ #include <stdio.h> #include <string.h> #include <math.h> +#include <assert.h> #include "cd.h" #include "wd.h" @@ -30,17 +31,18 @@ typedef struct cdCaracter struct _cdVectorFont { + /* font data */ char name[256]; /* font name */ - char file_name[10240]; /* font file name */ + char file_name[10240]; /* font file name */ cdCaracter *chars; /* array of characters */ - int top, /* from baseline to top */ - cap, /* from baseline to cap (top of chars) */ - half, /* half between top and bottom UNUSED */ + cap, /* from baseline to cap (UNUSED) */ + half, /* half between top and bottom (UNUSED) */ bottom; /* from baseline to bottom (negative) */ - double point_size_x, point_size_y; /* internal char size proportional to "top" */ + + /* attributes (independ from font) */ + double size_x, size_y; /* internal font size */ double current_cos, current_sin; /* text direction */ - int space, line_space; /* space between chars and vf_lines */ /* general transformation matrix */ int text_transf; @@ -4206,12 +4208,6 @@ static void vf_setdefaultfont(cdVectorFont *vector_font) vector_font->cap = vf_default_cap; vector_font->half = vf_default_half; vector_font->bottom = vf_default_bottom; - vector_font->point_size_x = 1.0; - vector_font->point_size_y = 1.0; - vector_font->current_cos = 1.0; - vector_font->current_sin = 0.0; - vector_font->space = 1; - vector_font->line_space = 1; } static int vf_readfontfile(FILE *file, cdVectorFont *vector_font) @@ -4293,7 +4289,7 @@ static int vf_readfontstring(const char* file, cdVectorFont *vector_font) sprintf(vector_font->name, "Unknown"); } - /* skip 2 blank vf_lines */ + /* skip 2 blank lines */ file = strstr(file, "\n")+1; /* goto next line */ file = strstr(file, "\n")+1; /* goto next line */ @@ -4335,27 +4331,28 @@ static int vf_readfontstring(const char* file, cdVectorFont *vector_font) return 1; } -static int vf_primlen(cdVectorFont *vector_font, const char* s) +static int vf_textwidth(cdVectorFont *vector_font, const char* s) { - int len = 0; + int width = 0; while (*s) - len += vector_font->chars[(unsigned char)(*(s++))].right + vector_font->space; - return len; + width += vector_font->chars[(unsigned char)(*(s++))].right; + if (width==0) width = 1; + return width; } -static void vf_move_dir(cdVectorFont *vector_font, int *px, int *py, double dx, double dy) +static void vf_move_dir(cdVectorFont *vector_font, int *x, int *y, double dx, double dy) { - *px += cdRound(vector_font->current_cos*dx - vector_font->current_sin*dy); - *py += cdRound(vector_font->current_sin*dx + vector_font->current_cos*dy); + *x += cdRound(vector_font->current_cos*dx - vector_font->current_sin*dy); + *y += cdRound(vector_font->current_sin*dx + vector_font->current_cos*dy); } -static void vf_wmove_dir(cdVectorFont *vector_font, double *px, double *py, double dx, double dy) +static void vf_wmove_dir(cdVectorFont *vector_font, double *x, double *y, double dx, double dy) { - *px += vector_font->current_cos*dx - vector_font->current_sin*dy; - *py += vector_font->current_sin*dx + vector_font->current_cos*dy; + *x += vector_font->current_cos*dx - vector_font->current_sin*dy; + *y += vector_font->current_sin*dx + vector_font->current_cos*dy; } -static void vf_writechar(cdVectorFont *vector_font, char c, int *px, int *py) +static void vf_draw_char(cdVectorFont *vector_font, char c, int *x, int *y) { unsigned char ac = vf_ansi2ascii[(unsigned char)c]; cdOperation *current = vector_font->chars[ac].op; @@ -4363,8 +4360,8 @@ static void vf_writechar(cdVectorFont *vector_font, char c, int *px, int *py) for(m = 0; m < op; m++) { - int ponto_x = *px; - int ponto_y = *py; + int px = *x; + int py = *y; if (current->operation == 'm') { @@ -4372,23 +4369,23 @@ static void vf_writechar(cdVectorFont *vector_font, char c, int *px, int *py) cdCanvasBegin(vector_font->canvas, CD_OPEN_LINES); } - vf_move_dir(vector_font, &ponto_x, &ponto_y, current->x*vector_font->point_size_x, current->y*vector_font->point_size_y); + vf_move_dir(vector_font, &px, &py, current->x*vector_font->size_x, current->y*vector_font->size_y); if (vector_font->text_transf) { - double aux = ponto_x*vector_font->text_matrix[3] + ponto_y*vector_font->text_matrix[4] + vector_font->text_matrix[5]; - ponto_y = cdRound(ponto_x*vector_font->text_matrix[0] + ponto_y*vector_font->text_matrix[1] + vector_font->text_matrix[2]); - ponto_x = _cdRound(aux); + double aux = px*vector_font->text_matrix[3] + py*vector_font->text_matrix[4] + vector_font->text_matrix[5]; + py = cdRound(px*vector_font->text_matrix[0] + py*vector_font->text_matrix[1] + vector_font->text_matrix[2]); + px = _cdRound(aux); } - cdCanvasVertex(vector_font->canvas, ponto_x, ponto_y); + cdCanvasVertex(vector_font->canvas, px, py); current++; } if (m) cdCanvasEnd(vector_font->canvas); } -static void vf_wwritechar(cdVectorFont *vector_font, char c, double *px, double *py) +static void vf_wdraw_char(cdVectorFont *vector_font, char c, double *x, double *y) { unsigned char ac = vf_ansi2ascii[(unsigned char)c]; cdOperation *current = vector_font->chars[ac].op; @@ -4396,8 +4393,8 @@ static void vf_wwritechar(cdVectorFont *vector_font, char c, double *px, double for(m = 0; m < op; m++) { - double ponto_x = *px; - double ponto_y = *py; + double px = *x; + double py = *y; if (current->operation == 'm') { @@ -4405,146 +4402,214 @@ static void vf_wwritechar(cdVectorFont *vector_font, char c, double *px, double cdCanvasBegin(vector_font->canvas, CD_OPEN_LINES); } - vf_wmove_dir(vector_font, &ponto_x, &ponto_y, current->x*vector_font->point_size_x, current->y*vector_font->point_size_y); + vf_wmove_dir(vector_font, &px, &py, current->x*vector_font->size_x, current->y*vector_font->size_y); if (vector_font->text_transf) { - double aux = ponto_x*vector_font->text_matrix[3] + ponto_y*vector_font->text_matrix[4] + vector_font->text_matrix[5]; - ponto_y = ponto_x*vector_font->text_matrix[0] + ponto_y*vector_font->text_matrix[1] + vector_font->text_matrix[2]; - ponto_x = aux; + double aux = px*vector_font->text_matrix[3] + py*vector_font->text_matrix[4] + vector_font->text_matrix[5]; + py = px*vector_font->text_matrix[0] + py*vector_font->text_matrix[1] + vector_font->text_matrix[2]; + px = aux; } - wdCanvasVertex(vector_font->canvas, ponto_x, ponto_y); + wdCanvasVertex(vector_font->canvas, px, py); current++; } if (m) cdCanvasEnd(vector_font->canvas); } -static int vf_lines(char * s) +static void vf_move_to_base(cdVectorFont *vector_font, int *x, int *y, int width) { - int n = 1; - while (*s != 0) + /* move point to baseline/left according to alignment */ + int align = vector_font->canvas->text_alignment; + + if (align == CD_NORTH || align == CD_NORTH_EAST || align == CD_NORTH_WEST) { - if (*s == '\n') - { - n++; - *s = 0; - } - s++; + vf_move_dir(vector_font, x, y, 0, -vector_font->top*vector_font->size_y); } - return n; -} - -static void vf_basic_write(cdVectorFont *vector_font, const char* s, int px, int py) -{ - while (*s) + else if (align == CD_SOUTH || align == CD_SOUTH_EAST || align == CD_SOUTH_WEST) { - vf_writechar(vector_font, *s, &px, &py); - vf_move_dir(vector_font, &px, &py, (vector_font->chars[(unsigned char)*s].right + vector_font->space)*vector_font->point_size_x, 0); - s++; + vf_move_dir(vector_font, x, y, 0, -vector_font->bottom*vector_font->size_y); /* bottom is < 0 */ } -} + else if (align == CD_BASE_CENTER || align == CD_BASE_LEFT || align == CD_BASE_RIGHT) + { + /* y = y; */ + } + else /* CD_CENTER || CD_EAST || CD_WEST */ + vf_move_dir(vector_font, x, y, 0, -((double)(vector_font->top+vector_font->bottom)/2.0)*vector_font->size_y); -static void vf_wbasic_write(cdVectorFont *vector_font, const char* s, double px, double py) -{ - while (*s) + if (align == CD_EAST || align == CD_NORTH_EAST || align == CD_SOUTH_EAST || align == CD_BASE_RIGHT) { - vf_wwritechar(vector_font, *s, &px, &py); - vf_wmove_dir(vector_font, &px, &py, (vector_font->chars[(unsigned char)*s].right + vector_font->space)*vector_font->point_size_x, 0); - s++; + vf_move_dir(vector_font, x, y, -width*vector_font->size_x, 0); + } + else if (align == CD_WEST || align == CD_NORTH_WEST || align == CD_SOUTH_WEST || align == CD_BASE_LEFT) + { + /* x = x; */ + } + else /* CD_CENTER || CD_NORTH || CD_SOUTH */ + { + vf_move_dir(vector_font, x, y, -(width*vector_font->size_x)/2.0, 0); } } -static void vf_calc_pos(cdVectorFont *vector_font, int *px, int *py, int prim_len) +static void vf_wmove_to_base(cdVectorFont *vector_font, double *x, double *y, int width) { - int align = cdCanvasTextAlignment(vector_font->canvas, CD_QUERY); + /* move point to baseline/left according to alignment */ + int align = vector_font->canvas->text_alignment; if (align == CD_NORTH || align == CD_NORTH_EAST || align == CD_NORTH_WEST) { - vf_move_dir(vector_font, px, py, 0, -vector_font->top*vector_font->point_size_y); + vf_wmove_dir(vector_font, x, y, 0, -vector_font->top*vector_font->size_y); } else if (align == CD_SOUTH || align == CD_SOUTH_EAST || align == CD_SOUTH_WEST) { - vf_move_dir(vector_font, px, py, 0, -vector_font->bottom*vector_font->point_size_y); /* bottom is < 0 */ + vf_wmove_dir(vector_font, x, y, 0, -vector_font->bottom*vector_font->size_y); /* bottom is < 0 */ } else if (align == CD_BASE_CENTER || align == CD_BASE_LEFT || align == CD_BASE_RIGHT) { - /* py = py; */ + /* y = y; */ } - else /* center em y */ - vf_move_dir(vector_font, px, py, 0, -(double)(vector_font->cap+vector_font->bottom)/2*vector_font->point_size_y); + else /* CD_CENTER || CD_EAST || CD_WEST */ + vf_wmove_dir(vector_font, x, y, 0, -((double)(vector_font->top+vector_font->bottom)/2.0)*vector_font->size_y); if (align == CD_EAST || align == CD_NORTH_EAST || align == CD_SOUTH_EAST || align == CD_BASE_RIGHT) { - vf_move_dir(vector_font, px, py, -prim_len*vector_font->point_size_x, 0); + vf_wmove_dir(vector_font, x, y, -width*vector_font->size_x, 0); } else if (align == CD_WEST || align == CD_NORTH_WEST || align == CD_SOUTH_WEST || align == CD_BASE_LEFT) { - ; /* px = px; */ + /* x = x; */ + } + else /* CD_CENTER || CD_NORTH || CD_SOUTH */ + { + vf_wmove_dir(vector_font, x, y, -(width*vector_font->size_x)/2.0, 0); } - else /* center em x */ - vf_move_dir(vector_font, px, py, -(prim_len*vector_font->point_size_x)/2, 0); } -static void vf_wcalc_pos(cdVectorFont *vector_font, double *px, double *py, int prim_len) +static void vf_draw_text(cdVectorFont* vector_font, int x, int y, const char* s, int width) { - int align = cdCanvasTextAlignment(vector_font->canvas, CD_QUERY); + vf_move_to_base(vector_font, &x, &y, width); - if (align == CD_NORTH || align == CD_NORTH_EAST || align == CD_NORTH_WEST) - { - vf_wmove_dir(vector_font, px, py, 0, -vector_font->top*vector_font->point_size_y); - } - else if (align == CD_SOUTH || align == CD_SOUTH_EAST || align == CD_SOUTH_WEST) + while (*s) { - vf_wmove_dir(vector_font, px, py, 0, -vector_font->bottom*vector_font->point_size_y); /* bottom is < 0 */ + vf_draw_char(vector_font, *s, &x, &y); + vf_move_dir(vector_font, &x, &y, (vector_font->chars[(unsigned char)*s].right)*vector_font->size_x, 0); + s++; } - else if (align == CD_BASE_CENTER || align == CD_BASE_LEFT || align == CD_BASE_RIGHT) +} + +static void vf_wdraw_text(cdVectorFont* vector_font, double x, double y, const char* s, int width) +{ + vf_wmove_to_base(vector_font, &x, &y, width); + + while (*s) { - /* py = py; */ + vf_wdraw_char(vector_font, *s, &x, &y); + vf_wmove_dir(vector_font, &x, &y, (vector_font->chars[(unsigned char)*s].right)*vector_font->size_x, 0); + s++; } - else /* center em y */ - vf_wmove_dir(vector_font, px, py, 0, -(double)(vector_font->cap+vector_font->bottom)/2*vector_font->point_size_y); +} - if (align == CD_EAST || align == CD_NORTH_EAST || align == CD_SOUTH_EAST || align == CD_BASE_RIGHT) +static void vf_calc_point(cdVectorFont *vector_font, int start_x, int start_y, int *x, int *y, int dx, int dy) +{ + *x = start_x; + *y = start_y; + + vf_move_dir(vector_font, x, y, dx, dy); + + if (vector_font->text_transf) { - vf_wmove_dir(vector_font, px, py, -prim_len*vector_font->point_size_x, 0); + double aux = *x * vector_font->text_matrix[3] + *y * vector_font->text_matrix[4] + vector_font->text_matrix[5]; + *y = cdRound(*x * vector_font->text_matrix[0] + *y * vector_font->text_matrix[1] + vector_font->text_matrix[2]); + *x = _cdRound(aux); } - else if (align == CD_WEST || align == CD_NORTH_WEST || align == CD_SOUTH_WEST || align == CD_BASE_LEFT) +} + +static void vf_wcalc_point(cdVectorFont *vector_font, double start_x, double start_y, double *x, double *y, double dx, double dy) +{ + *x = start_x; + *y = start_y; + + vf_wmove_dir(vector_font, x, y, dx, dy); + + if (vector_font->text_transf) { - ; /* px = px; */ + double aux = *x * vector_font->text_matrix[3] + *y * vector_font->text_matrix[4] + vector_font->text_matrix[5]; + *y = *x * vector_font->text_matrix[0] + *y * vector_font->text_matrix[1] + vector_font->text_matrix[2]; + *x = aux; } - else /* center em x */ - vf_wmove_dir(vector_font, px, py, -(prim_len*vector_font->point_size_x)/2, 0); } -static void vf_calc_point(cdVectorFont *vector_font, int startx, int starty, int *px, int *py, int dx, int dy) +static int vf_gettextmaxwidth(cdVectorFont* vector_font, const char* s, int num_lin) { - *px = startx; - *py = starty; - vf_move_dir(vector_font, px, py, dx, dy); + int i, max_w = 0, w; + char *p, *q, *new_s; - if (vector_font->text_transf) + new_s = cdStrDup(s); + p = new_s; + + for(i = 0; i < num_lin; i++) { - double aux = *px * vector_font->text_matrix[3] + *py * vector_font->text_matrix[4] + vector_font->text_matrix[5]; - *py = cdRound(*px * vector_font->text_matrix[0] + *py * vector_font->text_matrix[1] + vector_font->text_matrix[2]); - *px = _cdRound(aux); + q = strchr(p, '\n'); + if (q) *q = 0; /* Cut the string to contain only one line */ + + /* Calculate line width */ + w = vf_textwidth(vector_font, p); + if (w > max_w) max_w = w; + + /* Advance the string */ + if (q) p = q + 1; } + + free(new_s); + return max_w; } -static void vf_wcalc_point(cdVectorFont *vector_font, double startx, double starty, double *px, double *py, double dx, double dy) +static void vf_gettextsize(cdVectorFont* vector_font, const char* s, int *width, int *height) { - *px = startx; - *py = starty; + int num_lin = cdStrLineCount(s); + if (num_lin == 1) + { + *width = vf_textwidth(vector_font, s); + *height = vector_font->top - vector_font->bottom; + } + else + { + *width = vf_gettextmaxwidth(vector_font, s, num_lin); + *height = num_lin*(vector_font->top - vector_font->bottom); + } +} - vf_wmove_dir(vector_font, px, py, dx, dy); +static void vf_move_to_first(cdVectorFont* vector_font, int align, int *x, int *y, int num_lin, double line_height) +{ + /* position vertically at the first line */ + if (align == CD_NORTH || align == CD_NORTH_EAST || align == CD_NORTH_WEST || /* it is relative to the full text */ + align == CD_BASE_LEFT || align == CD_BASE_CENTER || align == CD_BASE_RIGHT) /* it is relative to the first line already */ + { + /* Already at position */ + } + else if (align == CD_SOUTH || align == CD_SOUTH_EAST || align == CD_SOUTH_WEST) /* it is relative to the full text */ + { + vf_move_dir(vector_font, x, y, 0, (num_lin-1)*line_height); + } + else /* CD_CENTER || CD_EAST || CD_WEST */ /* it is relative to the full text */ + vf_move_dir(vector_font, x, y, 0, (num_lin-1)*line_height/2.0); +} - if (vector_font->text_transf) +static void vf_wmove_to_first(cdVectorFont* vector_font, int align, double *x, double *y, int num_lin, double line_height) +{ + /* position vertically at the first line */ + if (align == CD_NORTH || align == CD_NORTH_EAST || align == CD_NORTH_WEST || /* it is relative to the full text */ + align == CD_BASE_LEFT || align == CD_BASE_CENTER || align == CD_BASE_RIGHT) /* it is relative to the first line already */ + { + /* Already at position */ + } + else if (align == CD_SOUTH || align == CD_SOUTH_EAST || align == CD_SOUTH_WEST) /* it is relative to the full text */ { - double aux = *px * vector_font->text_matrix[3] + *py * vector_font->text_matrix[4] + vector_font->text_matrix[5]; - *py = *px * vector_font->text_matrix[0] + *py * vector_font->text_matrix[1] + vector_font->text_matrix[2]; - *px = aux; + vf_wmove_dir(vector_font, x, y, 0, (num_lin-1)*line_height); } + else /* CD_CENTER || CD_EAST || CD_WEST */ /* it is relative to the full text */ + vf_wmove_dir(vector_font, x, y, 0, (num_lin-1)*line_height/2.0); } static char *cd_getCDDIR(void) @@ -4562,49 +4627,113 @@ static char *cd_getCDDIR(void) cdVectorFont* cdCreateVectorFont(cdCanvas* canvas) { - cdVectorFont* vector_font = calloc(1, sizeof(cdVectorFont)); + cdVectorFont* vector_font; + + assert(canvas); + if (!_cdCheckCanvas(canvas)) return NULL; + + vector_font = calloc(1, sizeof(cdVectorFont)); + vector_font->canvas = canvas; + vf_setdefaultfont(vector_font); + + vector_font->size_x = 1.0; + vector_font->size_y = 1.0; + + vector_font->current_cos = 1.0; + vector_font->current_sin = 0.0; + + vector_font->text_transf = 0; + return vector_font; } void cdKillVectorFont(cdVectorFont* vector_font) { + assert(vector_font); + if (!vector_font) return; + if (vector_font->chars && vector_font->chars != vf_default_chars) vf_releasefontchars(vector_font); /* not the default font */ free(vector_font); } -void cdCanvasVectorTextDirection(cdCanvas* canvas, int x1, int y1, int x2, int y2) +char *cdCanvasVectorFont(cdCanvas* canvas, const char *file) { - int dx=x2-x1; - int dy=y2-y1; - double len = sqrt(dx*dx +dy*dy); - cdVectorFont* vector_font = canvas->vector_font; - vector_font->current_sin = dy/len; - vector_font->current_cos = dx/len; -} + cdVectorFont* vector_font; -int cdCanvasVectorCharSize(cdCanvas* canvas, int size) -{ - cdVectorFont* vector_font = canvas->vector_font; - int old_size = cdRound(vector_font->point_size_y*vector_font->top); - if (size == CD_QUERY) - return old_size; + assert(canvas); + assert(file); + if (!_cdCheckCanvas(canvas)) return NULL; - vector_font->point_size_y = size/(double)vector_font->top; - vector_font->point_size_x = size/(double)vector_font->top; + if (file[0] == 0) + return NULL; - return old_size; + vector_font = canvas->vector_font; + if (!file) + { + vf_setdefaultfont(vector_font); + vector_font->file_name[0] = 0; + } + else + { + FILE *font = NULL; + int read_ok; + + /* se arquivo foi o mesmo que o arq. corrente, entao retorna */ + if (strcmp (file, vector_font->file_name) == 0) + return vector_font->name; + + /* abre arq. no dir. corrente */ + font = fopen(file, "r"); + + /* se nao conseguiu, abre arq. no dir. do cd, */ + if (!font && (strlen(file) < 10240 - strlen(cd_getCDDIR()))) + { + char filename[10240]; + sprintf(filename, "%s/%s", cd_getCDDIR(), file); + font = fopen(filename, "r"); + } + + if (font) + read_ok = vf_readfontfile(font, vector_font); + else + read_ok = vf_readfontstring(file, vector_font); + + if (!read_ok) + { + if (font) fclose(font); + vf_setdefaultfont(vector_font); + vector_font->file_name[0] = 0; + return NULL; + } + + /* guarda nome do arquivo que esta' carregado */ + if (font) + { + strcpy(vector_font->file_name, file); + fclose(font); + } + else + strcpy(vector_font->file_name, vector_font->name); + } + + return vector_font->name; } double* cdCanvasVectorTextTransform(cdCanvas* canvas, const double* matrix) { - cdVectorFont* vector_font = canvas->vector_font; + cdVectorFont* vector_font; int i; static double old_matrix[6]; + assert(canvas); + assert(matrix); + if (!_cdCheckCanvas(canvas)) return NULL; + + vector_font = canvas->vector_font; if (vector_font->text_transf) { for (i=0; i<6; i++) @@ -4629,131 +4758,250 @@ double* cdCanvasVectorTextTransform(cdCanvas* canvas, const double* matrix) return old_matrix; } -void cdCanvasGetVectorTextSize(cdCanvas* canvas, const char *s, int *px, int *py) +/******************************************************/ +/* vector text em Raster */ +/******************************************************/ + +void cdCanvasVectorTextDirection(cdCanvas* canvas, int x1, int y1, int x2, int y2) +{ + cdVectorFont* vector_font; + int dx, dy; + double len; + + assert(canvas); + if (!_cdCheckCanvas(canvas)) return; + + vector_font = canvas->vector_font; + + dx=x2-x1; + dy=y2-y1; + len = sqrt(dx*dx +dy*dy); + if (len == 0) len = 1; + vector_font->current_sin = dy/len; + vector_font->current_cos = dx/len; +} + +void cdCanvasVectorFontSize(cdCanvas* canvas, double size_x, double size_y) { - cdVectorFont* vector_font = canvas->vector_font; - if (px) *px = cdRound(vf_primlen(vector_font, s)*vector_font->point_size_x); - if (py) *py = cdRound(vector_font->top*vector_font->point_size_y); + cdVectorFont* vector_font; + + assert(canvas); + if (!_cdCheckCanvas(canvas)) return; + + vector_font = canvas->vector_font; + + vector_font->size_x = size_x; + vector_font->size_y = size_y; } -void cdCanvasGetVectorTextBounds(cdCanvas* canvas, const char *s, int px, int py, int *rect) +void cdCanvasGetVectorFontSize(cdCanvas* canvas, double *size_x, double *size_y) { - cdVectorFont* vector_font = canvas->vector_font; - int prim_len = vf_primlen(vector_font, s); - int sx = cdRound(prim_len*vector_font->point_size_x); - int sy = cdRound(vector_font->top*vector_font->point_size_y); + cdVectorFont* vector_font; - vf_calc_pos(vector_font, &px, &py, prim_len); + assert(canvas); + if (!_cdCheckCanvas(canvas)) return; - vf_move_dir(vector_font, &px, &py, 0, vector_font->bottom*vector_font->point_size_y); + vector_font = canvas->vector_font; - vf_calc_point(vector_font, px, py, &rect[0], &rect[1], 0, 0); - vf_calc_point(vector_font, px, py, &rect[2], &rect[3], sx, 0); - vf_calc_point(vector_font, px, py, &rect[4], &rect[5], sx, sy); - vf_calc_point(vector_font, px, py, &rect[6], &rect[7], 0, sy); + if (size_x) *size_x = vector_font->size_x; + if (size_y) *size_y = vector_font->size_y; } -void cdCanvasVectorTextSize(cdCanvas* canvas, int size_x, int size_y, const char* s) +int cdCanvasVectorCharSize(cdCanvas* canvas, int size) { - cdVectorFont* vector_font = canvas->vector_font; - vector_font->point_size_x = size_x/(double)vf_primlen(vector_font, s); - vector_font->point_size_y = size_y/(double)vector_font->top; + cdVectorFont* vector_font; + int old_size; + + assert(canvas); + if (!_cdCheckCanvas(canvas)) return 0; + + vector_font = canvas->vector_font; + old_size = cdRound(vector_font->size_y*vector_font->top); + if (size == CD_QUERY) + return old_size; + + vector_font->size_y = size/(double)vector_font->top; + vector_font->size_x = vector_font->size_y; + + return old_size; } -void cdCanvasVectorText(cdCanvas* canvas, int px, int py, const char* s) +void cdCanvasVectorTextSize(cdCanvas* canvas, int s_width, int s_height, const char* s) { - cdVectorFont* vector_font = canvas->vector_font; - int prim_len = vf_primlen(vector_font, s); - vf_calc_pos(vector_font, &px, &py, prim_len); - vf_basic_write(vector_font, s, px, py); + int width, height; + cdVectorFont* vector_font; + + assert(canvas); + assert(s); + if (!_cdCheckCanvas(canvas)) return; + + if (s[0] == 0) + return; + + vector_font = canvas->vector_font; + vf_gettextsize(vector_font, s, &width, &height); + + vector_font->size_x = (double)s_width/(double)width; + vector_font->size_y = (double)s_height/(double)height; } -void cdCanvasMultiLineVectorText(cdCanvas* canvas, int px, int py, const char* s) +void cdCanvasGetVectorTextSize(cdCanvas* canvas, const char *s, int *x, int *y) { - cdVectorFont* vector_font = canvas->vector_font; - double line_height = (vector_font->top - vector_font->bottom + vector_font->line_space) * vector_font->point_size_y; - char buff[MULTILINE_MAXLEN]; - char *str = buff; - int n; + int width, height; + cdVectorFont* vector_font; - int align = cdCanvasTextAlignment(vector_font->canvas, CD_QUERY); /* procura o alinhamento do CD */ + assert(canvas); + assert(s); + if (!_cdCheckCanvas(canvas)) return; - if (strlen(s) >= MULTILINE_MAXLEN) + if (s[0] == 0) return; - strcpy(str, s); - n = vf_lines(str); - if (align == CD_NORTH || align == CD_NORTH_EAST || align == CD_NORTH_WEST) - { - ; /* Already at position */ - } - else if (align == CD_SOUTH || align == CD_SOUTH_EAST || align == CD_SOUTH_WEST) - { - vf_move_dir(vector_font, &px, &py, 0, (n-1)*line_height); - } - else - vf_move_dir(vector_font, &px, &py, 0, ((double)(n-1)/2)*line_height); + vector_font = canvas->vector_font; + + vf_gettextsize(vector_font, s, &width, &height); + + if (x) *x = cdRound(width*vector_font->size_x); + if (y) *y = cdRound(height*vector_font->size_y); +} + +void cdCanvasGetVectorTextBounds(cdCanvas* canvas, const char *s, int x, int y, int *rect) +{ + cdVectorFont* vector_font; + int sx, sy; + int width, height, num_lin; + double line_height; + + assert(canvas); + assert(s); + if (!_cdCheckCanvas(canvas)) return; + + if (s[0] == 0) + return; + + vector_font = canvas->vector_font; - while (n--) + vf_gettextsize(vector_font, s, &width, &height); + num_lin = height/(vector_font->top - vector_font->bottom); + + sx = cdRound(width*vector_font->size_x); + sy = cdRound(height*vector_font->size_y); + + line_height = (vector_font->top - vector_font->bottom) * vector_font->size_y; + + if (num_lin > 1) { - cdCanvasVectorText(canvas, px, py, str); - str += strlen(str)+1; - vf_move_dir(vector_font, &px, &py, 0, -line_height); + /* position vertically at the first line */ + int align = canvas->text_alignment; + vf_move_to_first(vector_font, align, &x, &y, num_lin, line_height); } + + /* move to bottom/left corner */ + vf_move_to_base(vector_font, &x, &y, width); + vf_move_dir(vector_font, &x, &y, 0, vector_font->bottom*vector_font->size_y); /* from base/left to bottom/left of the first line */ + if (num_lin > 1) + vf_move_dir(vector_font, &x, &y, 0, -(height*vector_font->size_y - line_height)); /* from bottom/left to the bottom of the last line */ + + vf_calc_point(vector_font, x, y, &rect[0], &rect[1], 0, 0); + vf_calc_point(vector_font, x, y, &rect[2], &rect[3], sx, 0); + vf_calc_point(vector_font, x, y, &rect[4], &rect[5], sx, sy); + vf_calc_point(vector_font, x, y, &rect[6], &rect[7], 0, sy); } -char *cdCanvasVectorFont(cdCanvas* canvas, const char *file) +void cdCanvasGetVectorTextBox(cdCanvas* canvas, int x, int y, const char *s, int *xmin, int *xmax, int *ymin, int *ymax) { - cdVectorFont* vector_font = canvas->vector_font; - if (!file) + int rect[8]; + int _xmin, _xmax, _ymin, _ymax; + + cdCanvasGetVectorTextBounds(canvas, s, x, y, rect); + + _xmin = rect[0]; + _ymin = rect[1]; + _xmax = rect[0]; + _ymax = rect[1]; + + if(rect[2] < _xmin) _xmin = rect[2]; + if(rect[4] < _xmin) _xmin = rect[4]; + if(rect[6] < _xmin) _xmin = rect[6]; + + if(rect[3] < _ymin) _ymin = rect[3]; + if(rect[5] < _ymin) _ymin = rect[5]; + if(rect[7] < _ymin) _ymin = rect[7]; + + if(rect[2] > _xmax) _xmax = rect[2]; + if(rect[4] > _xmax) _xmax = rect[4]; + if(rect[6] > _xmax) _xmax = rect[6]; + + if(rect[3] > _ymax) _ymax = rect[3]; + if(rect[5] > _ymax) _ymax = rect[5]; + if(rect[7] > _ymax) _ymax = rect[7]; + + if (xmin) *xmin = _xmin; + if (xmax) *xmax = _xmax; + if (ymin) *ymin = _ymin; + if (ymax) *ymax = _ymax; +} + +void cdCanvasVectorText(cdCanvas* canvas, int x, int y, const char* s) +{ + cdVectorFont* vector_font; + int num_lin, align, width = 0; + + assert(canvas); + assert(s); + if (!_cdCheckCanvas(canvas)) return; + + if (s[0] == 0) + return; + + vector_font = canvas->vector_font; + align = canvas->text_alignment; + + num_lin = cdStrLineCount(s); + if (num_lin == 1) { - vf_setdefaultfont(vector_font); - vector_font->file_name[0] = 0; + if (align != CD_WEST && align != CD_NORTH_WEST && align != CD_SOUTH_WEST && align != CD_BASE_LEFT) + width = vf_textwidth(vector_font, s); /* only necessary for some alignments */ + + vf_draw_text(vector_font, x, y, s, width); } else { - FILE *font = NULL; - int read_ok; + char *p, *q, *new_s; + double line_height = (vector_font->top - vector_font->bottom) * vector_font->size_y; + int i; - /* se arquivo foi o mesmo que o arq. corrente, entao retorna */ - if (strcmp (file, vector_font->file_name) == 0) - return vector_font->name; + if (align != CD_WEST && align != CD_NORTH_WEST && align != CD_SOUTH_WEST && align != CD_BASE_LEFT) + width = vf_gettextmaxwidth(vector_font, s, num_lin); /* only necessary for some alignments */ - /* abre arq. no dir. corrente */ - font = fopen(file, "r"); + /* position vertically at the first line */ + vf_move_to_first(vector_font, align, &x, &y, num_lin, line_height); - /* se nao conseguiu, abre arq. no dir. do cd, */ - if (!font && (strlen(file) < 10240 - strlen(cd_getCDDIR()))) + new_s = cdStrDup(s); + p = new_s; + + for(i = 0; i < num_lin; i++) { - char filename[10240]; - sprintf(filename, "%s/%s", cd_getCDDIR(), file); - font = fopen(filename, "r"); - } + q = strchr(p, '\n'); + if (q) *q = 0; /* Cut the string to contain only one line */ - if (font) - read_ok = vf_readfontfile(font, vector_font); - else - read_ok = vf_readfontstring(file, vector_font); + /* Draw the line */ + vf_draw_text(vector_font, x, y, p, width); - if (!read_ok) - { - if (font) fclose(font); - vf_setdefaultfont(vector_font); - vector_font->file_name[0] = 0; - return NULL; - } + /* Advance the string */ + if (q) p = q + 1; - /* guarda nome do arquivo que esta' carregado */ - if (font) - { - strcpy(vector_font->file_name, file); - fclose(font); + /* Advance a line */ + vf_move_dir(vector_font, &x, &y, 0, -line_height); } - else - strcpy(vector_font->file_name, vector_font->name); + + free(new_s); } +} - return vector_font->name; +void cdCanvasMultiLineVectorText(cdCanvas* canvas, int x, int y, const char* s) +{ + cdCanvasVectorText(canvas, x, y, s); } /******************************************************/ @@ -4762,92 +5010,215 @@ char *cdCanvasVectorFont(cdCanvas* canvas, const char *file) void wdCanvasVectorTextDirection(cdCanvas* canvas, double x1, double y1, double x2, double y2) { - cdVectorFont* vector_font = canvas->vector_font; - double dx=x2-x1; - double dy=y2-y1; - double len = sqrt(dx*dx +dy*dy); + cdVectorFont* vector_font; + double dx, dy, len; + + assert(canvas); + if (!_cdCheckCanvas(canvas)) return; + + vector_font = canvas->vector_font; + + dx=x2-x1; + dy=y2-y1; + len = sqrt(dx*dx +dy*dy); + if (len == 0) len = 1; vector_font->current_sin = dy/len; vector_font->current_cos = dx/len; } double wdCanvasVectorCharSize(cdCanvas* canvas, double size) { - cdVectorFont* vector_font = canvas->vector_font; - double old_size = vector_font->point_size_y*vector_font->top; + cdVectorFont* vector_font; + double old_size; + + assert(canvas); + if (!_cdCheckCanvas(canvas)) return 0; + + vector_font = canvas->vector_font; + old_size = vector_font->size_y*vector_font->top; if (size == CD_QUERY) return old_size; - vector_font->point_size_y = size/(double)vector_font->top; - vector_font->point_size_x = size/(double)vector_font->top; + vector_font->size_y = size/(double)vector_font->top; + vector_font->size_x = vector_font->size_y; return old_size; } -void wdCanvasVectorTextSize(cdCanvas* canvas, double size_x, double size_y, const char* s) +void wdCanvasVectorTextSize(cdCanvas* canvas, double s_width, double s_height, const char* s) { - cdVectorFont* vector_font = canvas->vector_font; - vector_font->point_size_x = size_x/(double)vf_primlen(vector_font, s); - vector_font->point_size_y = size_y/(double)vector_font->top; + int width, height; + cdVectorFont* vector_font; + + assert(canvas); + assert(s); + if (!_cdCheckCanvas(canvas)) return; + + if (s[0] == 0) + return; + + vector_font = canvas->vector_font; + vf_gettextsize(vector_font, s, &width, &height); + + vector_font->size_x = s_width/(double)width; + vector_font->size_y = s_height/(double)height; } -void wdCanvasGetVectorTextSize(cdCanvas* canvas, const char *s, double *px, double *py) +void wdCanvasGetVectorTextSize(cdCanvas* canvas, const char *s, double *x, double *y) { - cdVectorFont* vector_font = canvas->vector_font; - if (px) *px = vf_primlen(vector_font, s)*vector_font->point_size_x; - if (py) *py = vector_font->top*vector_font->point_size_y; + int width, height; + cdVectorFont* vector_font; + + assert(canvas); + assert(s); + if (!_cdCheckCanvas(canvas)) return; + + if (s[0] == 0) + return; + + vector_font = canvas->vector_font; + + vf_gettextsize(vector_font, s, &width, &height); + + if (x) *x = width*vector_font->size_x; + if (y) *y = height*vector_font->size_y; } -void wdCanvasGetVectorTextBounds(cdCanvas* canvas, const char *s, double px, double py, double *rect) +void wdCanvasGetVectorTextBounds(cdCanvas* canvas, const char *s, double x, double y, double *rect) { - cdVectorFont* vector_font = canvas->vector_font; - int prim_len = vf_primlen(vector_font, s); - double sx = prim_len*vector_font->point_size_x; - double sy = vector_font->top*vector_font->point_size_y; + cdVectorFont* vector_font; + double sx, sy, line_height; + int width, height, num_lin; + + assert(canvas); + assert(s); + if (!_cdCheckCanvas(canvas)) return; + + if (s[0] == 0) + return; + + vector_font = canvas->vector_font; - vf_wcalc_pos(vector_font, &px, &py, prim_len); + vf_gettextsize(vector_font, s, &width, &height); + num_lin = height/(vector_font->top - vector_font->bottom); + + sx = width*vector_font->size_x; + sy = height*vector_font->size_y; + + line_height = (vector_font->top - vector_font->bottom) * vector_font->size_y; + + if (num_lin > 1) + { + /* position vertically at the first line */ + int align = canvas->text_alignment; + vf_wmove_to_first(vector_font, align, &x, &y, num_lin, line_height); + } - vf_wmove_dir(vector_font, &px, &py, 0, vector_font->bottom*vector_font->point_size_y); + /* move to bottom/left corner */ + vf_wmove_to_base(vector_font, &x, &y, width); + vf_wmove_dir(vector_font, &x, &y, 0, vector_font->bottom*vector_font->size_y); /* from base/left to bottom/left of the first line */ + if (num_lin > 1) + vf_wmove_dir(vector_font, &x, &y, 0, -(height*vector_font->size_y - line_height)); /* from bottom/left to the bottom of the last line */ - vf_wcalc_point(vector_font, px, py, &rect[0], &rect[1], 0, 0); - vf_wcalc_point(vector_font, px, py, &rect[2], &rect[3], sx, 0); - vf_wcalc_point(vector_font, px, py, &rect[4], &rect[5], sx, sy); - vf_wcalc_point(vector_font, px, py, &rect[6], &rect[7], 0, sy); + vf_wcalc_point(vector_font, x, y, &rect[0], &rect[1], 0, 0); + vf_wcalc_point(vector_font, x, y, &rect[2], &rect[3], sx, 0); + vf_wcalc_point(vector_font, x, y, &rect[4], &rect[5], sx, sy); + vf_wcalc_point(vector_font, x, y, &rect[6], &rect[7], 0, sy); } -void wdCanvasVectorText(cdCanvas* canvas, double px, double py, const char* s) +void wdCanvasGetVectorTextBox(cdCanvas* canvas, double x, double y, const char *s, double *xmin, double *xmax, double *ymin, double *ymax) { - cdVectorFont* vector_font = canvas->vector_font; - int prim_len = vf_primlen(vector_font, s); - vf_wcalc_pos(vector_font, &px, &py, prim_len); - vf_wbasic_write(vector_font, s, px, py); + double rect[8]; + double _xmin, _xmax, _ymin, _ymax; + + wdCanvasGetVectorTextBounds(canvas, s, x, y, rect); + + _xmin = rect[0]; + _ymin = rect[1]; + _xmax = rect[0]; + _ymax = rect[1]; + + if(rect[2] < _xmin) _xmin = rect[2]; + if(rect[4] < _xmin) _xmin = rect[4]; + if(rect[6] < _xmin) _xmin = rect[6]; + + if(rect[3] < _ymin) _ymin = rect[3]; + if(rect[5] < _ymin) _ymin = rect[5]; + if(rect[7] < _ymin) _ymin = rect[7]; + + if(rect[2] > _xmax) _xmax = rect[2]; + if(rect[4] > _xmax) _xmax = rect[4]; + if(rect[6] > _xmax) _xmax = rect[6]; + + if(rect[3] > _ymax) _ymax = rect[3]; + if(rect[5] > _ymax) _ymax = rect[5]; + if(rect[7] > _ymax) _ymax = rect[7]; + + if (xmin) *xmin = _xmin; + if (xmax) *xmax = _xmax; + if (ymin) *ymin = _ymin; + if (ymax) *ymax = _ymax; } -void wdCanvasMultiLineVectorText(cdCanvas* canvas, double px, double py, const char* s) +void wdCanvasVectorText(cdCanvas* canvas, double x, double y, const char* s) { - cdVectorFont* vector_font = canvas->vector_font; - double line_height = (vector_font->top - vector_font->bottom + vector_font->line_space)*vector_font->point_size_y; - char buff[MULTILINE_MAXLEN]; - char *str = buff; - int n; + cdVectorFont* vector_font; + int num_lin, align, width = 0; - int align = cdCanvasTextAlignment(vector_font->canvas, CD_QUERY); /* procura o alinhamento do CD */ + assert(canvas); + assert(s); + if (!_cdCheckCanvas(canvas)) return; - if (strlen(s) >= MULTILINE_MAXLEN) + if (s[0] == 0) return; - strcpy(str, s); - n = vf_lines(str); - if (align == CD_NORTH || align == CD_NORTH_EAST || align == CD_NORTH_WEST) - ; /* Already at position */ - else if (align == CD_SOUTH || align == CD_SOUTH_EAST || align == CD_SOUTH_WEST) - vf_wmove_dir(vector_font, &px, &py, 0, (n-1)*line_height); - else - vf_wmove_dir(vector_font, &px, &py, 0, ((double)(n-1)/2)*line_height); + vector_font = canvas->vector_font; + align = canvas->text_alignment; - while (n--) + num_lin = cdStrLineCount(s); + if (num_lin == 1) { - wdCanvasVectorText(canvas, px, py, str); - str += strlen(str)+1; - vf_wmove_dir(vector_font, &px, &py, 0, -line_height); + if (align != CD_WEST && align != CD_NORTH_WEST && align != CD_SOUTH_WEST && align != CD_BASE_LEFT) + width = vf_textwidth(vector_font, s); /* only necessary for some alignments */ + + vf_wdraw_text(vector_font, x, y, s, width); + } + else + { + char *p, *q, *new_s; + double line_height = (vector_font->top - vector_font->bottom) * vector_font->size_y; + int i; + + if (align != CD_WEST && align != CD_NORTH_WEST && align != CD_SOUTH_WEST && align != CD_BASE_LEFT) + width = vf_gettextmaxwidth(vector_font, s, num_lin); /* only necessary for some alignments */ + + /* position vertically at the first line */ + vf_wmove_to_first(vector_font, align, &x, &y, num_lin, line_height); + + new_s = cdStrDup(s); + p = new_s; + + for(i = 0; i < num_lin; i++) + { + q = strchr(p, '\n'); + if (q) *q = 0; /* Cut the string to contain only one line */ + + /* Draw the line */ + vf_wdraw_text(vector_font, x, y, p, width); + + /* Advance the string */ + if (q) p = q + 1; + + /* Advance a line */ + vf_wmove_dir(vector_font, &x, &y, 0, -line_height); + } + + free(new_s); } } + +void wdCanvasMultiLineVectorText(cdCanvas* canvas, double x, double y, const char* s) +{ + wdCanvasVectorText(canvas, x, y, s); +} + diff --git a/src/drv/cdcgm.c b/src/drv/cdcgm.c index 4ba0065..2791c24 100644 --- a/src/drv/cdcgm.c +++ b/src/drv/cdcgm.c @@ -519,7 +519,7 @@ static void cdtext(cdCtxCanvas *ctxcanvas, int x, int y, const char *s) cgm_text( ctxcanvas->cgm, 1 /* final */ , (double)x, (double)y, s ); - cdCanvasGetTextSize(ctxcanvas->canvas, s, &width, &height); + cdgettextsizeEX(ctxcanvas, s, &width, &height); settextbbox (ctxcanvas, (double) x, (double) y, width, height ); } @@ -530,7 +530,7 @@ static void cdftext(cdCtxCanvas *ctxcanvas, double x, double y, const char *s) cgm_text( ctxcanvas->cgm, 1 /* final */ , x, y, s ); - cdCanvasGetTextSize(ctxcanvas->canvas, s, &width, &height); + cdgettextsizeEX(ctxcanvas, s, &width, &height); settextbbox (ctxcanvas, x, y, width, height ); } diff --git a/src/drv/cdpicture.c b/src/drv/cdpicture.c index 9bc5104..3f5598e 100644 --- a/src/drv/cdpicture.c +++ b/src/drv/cdpicture.c @@ -307,12 +307,12 @@ static void primAddAttrib_Text(tPrimNode *prim, cdCanvas *canvas) if (canvas->native_font[0]) { - prim->attrib_buffer = strdup(canvas->native_font); + prim->attrib_buffer = cdStrDup(canvas->native_font); prim->attrib.text.native_font = prim->attrib_buffer; } else { - prim->attrib_buffer = strdup(canvas->font_type_face); + prim->attrib_buffer = cdStrDup(canvas->font_type_face); prim->attrib.text.font_type_face = prim->attrib_buffer; } } @@ -576,7 +576,7 @@ static void cdtext(cdCtxCanvas *ctxcanvas, int x, int y, const char *text) primAddAttrib_Text(prim, ctxcanvas->canvas); prim->param.text.x = x; prim->param.text.y = y; - prim->param.text.s = strdup(text); + prim->param.text.s = cdStrDup(text); prim->param_buffer = prim->param.text.s; picAddPrim(ctxcanvas, prim); cdCanvasGetTextBox(ctxcanvas->canvas, x, y, text, &xmin, &xmax, &ymin, &ymax); @@ -591,7 +591,7 @@ static void cdftext(cdCtxCanvas *ctxcanvas, double x, double y, const char *text primAddAttrib_Text(prim, ctxcanvas->canvas); prim->param.textf.x = x; prim->param.textf.y = y; - prim->param.textf.s = strdup(text); + prim->param.textf.s = cdStrDup(text); prim->param_buffer = prim->param.textf.s; picAddPrim(ctxcanvas, prim); cdCanvasGetTextBox(ctxcanvas->canvas, _cdRound(x), _cdRound(y), text, &xmin, &xmax, &ymin, &ymax); diff --git a/src/intcgm/bparse.c b/src/intcgm/bparse.c index ad08179..c0ffada 100644 --- a/src/intcgm/bparse.c +++ b/src/intcgm/bparse.c @@ -179,7 +179,7 @@ int cgmb_intpre ( void ) int cgmb_realpr ( void ) { - short mode, i1; + short mode = 0, i1; long i2, i3; if ( cgmb_e ( &i1 ) ) return 1; @@ -543,7 +543,7 @@ int cgmb_vdcipr ( void ) int cgmb_vdcrpr ( void ) { short i1; - long mode, i2, i3; + long mode = 0, i2, i3; if ( cgmb_e ( &i1 ) ) return 1; if ( cgmb_i ( &i2 ) ) return 1; @@ -1320,7 +1320,7 @@ int cgmb_txftin ( void ) font = (char *) cgm_GetList ( intcgm_text_att.font_list, intcgm_text_att.font_index ); - if ( font==NULL ) font = (char*)strdup ( "SYSTEM" ); + if ( font==NULL ) font = "SYSTEM"; intcgm_text_att.font = 0; for ( i=0; font_array[i]!=NULL; i++ ) diff --git a/src/intcgm/intcgm2.c b/src/intcgm/intcgm2.c index f16c916..b6be7ee 100644 --- a/src/intcgm/intcgm2.c +++ b/src/intcgm/intcgm2.c @@ -1171,7 +1171,7 @@ int cgmb_r ( double *d ) int cgmb_s ( char **str ) { - register unsigned i; + register unsigned i = 0; unsigned char l; unsigned short l1; unsigned short cont; @@ -1206,9 +1206,7 @@ int cgmb_s ( char **str ) } s[i] = '\0'; - *str = (char*)strdup ( s ); - - free ( s ); + *str = s; return 0; } diff --git a/src/intcgm/tparse.c b/src/intcgm/tparse.c index 0402ce6..9bc47b3 100644 --- a/src/intcgm/tparse.c +++ b/src/intcgm/tparse.c @@ -1021,7 +1021,7 @@ int cgmt_txftin ( void ) /* text font index */ font = (char *) cgm_GetList ( intcgm_text_att.font_list, intcgm_text_att.font_index ); - if ( font==NULL ) font = (char*)strdup ( "SYSTEM" ); + if ( font==NULL ) font = "SYSTEM"; intcgm_text_att.font = 0; for ( i=0; font_array[i]!=NULL; i++ ) diff --git a/src/lua5/cdlua5_canvas.c b/src/lua5/cdlua5_canvas.c index 4d38cbf..d04f76f 100644 --- a/src/lua5/cdlua5_canvas.c +++ b/src/lua5/cdlua5_canvas.c @@ -1340,9 +1340,9 @@ static int cdlua5_textorientation(lua_State *L) } /***************************************************************************\ -* cd.FontDim() -> (max_width, max_height, ascent, descent: number) * +* cd.GetFontDim() -> (max_width, max_height, ascent, descent: number) * \***************************************************************************/ -static int cdlua5_fontdim(lua_State *L) +static int cdlua5_getfontdim(lua_State *L) { int max_width; int height; @@ -1358,9 +1358,9 @@ static int cdlua5_fontdim(lua_State *L) } /***************************************************************************\ -* cd.wFontDim() -> (max_width, max_height, ascent, descent: number) * +* cd.wGetFontDim() -> (max_width, max_height, ascent, descent: number) * \***************************************************************************/ -static int wdlua5_fontdim(lua_State *L) +static int wdlua5_getfontdim(lua_State *L) { double max_width; double height; @@ -1376,9 +1376,9 @@ static int wdlua5_fontdim(lua_State *L) } /***************************************************************************\ -* cd.TextSize(text: string) -> (width, heigth: number) * +* cd.GetTextSize(text: string) -> (width, heigth: number) * \***************************************************************************/ -static int cdlua5_textsize(lua_State *L) +static int cdlua5_gettextsize(lua_State *L) { int width; int height; @@ -1389,9 +1389,9 @@ static int cdlua5_textsize(lua_State *L) } /***************************************************************************\ -* cd.wTextSize(text: string) -> (width, heigth: number) * +* cd.wGetTextSize(text: string) -> (width, heigth: number) * \***************************************************************************/ -static int wdlua5_textsize(lua_State *L) +static int wdlua5_gettextsize(lua_State *L) { double width; double height; @@ -1402,9 +1402,9 @@ static int wdlua5_textsize(lua_State *L) } /****************************************************************************\ -* cd.TextBox(x, y: number, text: string) -> (xmin, xmax, ymin, ymax: number) * +* cd.GetTextBox(x, y: number, text: string) -> (xmin, xmax, ymin, ymax: number) * \****************************************************************************/ -static int cdlua5_textbox(lua_State *L) +static int cdlua5_gettextbox(lua_State *L) { int xmin, xmax, ymin, ymax; int x = luaL_checkint(L, 2); @@ -1420,9 +1420,9 @@ static int cdlua5_textbox(lua_State *L) } /*****************************************************************************\ -* cd.wTextBox(x, y: number, text: string) -> (xmin, xmax, ymin, ymax: number) * +* cd.wGetTextBox(x, y: number, text: string) -> (xmin, xmax, ymin, ymax: number) * \*****************************************************************************/ -static int wdlua5_textbox(lua_State *L) +static int wdlua5_gettextbox(lua_State *L) { double xmin, xmax, ymin, ymax; double x = luaL_checknumber(L, 2); @@ -1438,9 +1438,9 @@ static int wdlua5_textbox(lua_State *L) } /***************************************************************************************************************\ -* cd.TextBounds(x, y: number, text: string) -> (rect0, rect1, rect2, rect3, rect4, rect5, rect6, rect7: number) * +* cd.GetTextBounds(x, y: number, text: string) -> (rect0, rect1, rect2, rect3, rect4, rect5, rect6, rect7: number) * \***************************************************************************************************************/ -static int cdlua5_textbounds(lua_State *L) +static int cdlua5_gettextbounds(lua_State *L) { int rect[8]; int x = luaL_checkint(L, 2); @@ -1460,9 +1460,9 @@ static int cdlua5_textbounds(lua_State *L) } /****************************************************************************************************************\ -* cd.wTextBounds(x, y: number, text: string) -> (rect0, rect1, rect2, rect3, rect4, rect5, rect6, rect7: number) * +* cd.wGetTextBounds(x, y: number, text: string) -> (rect0, rect1, rect2, rect3, rect4, rect5, rect6, rect7: number) * \****************************************************************************************************************/ -static int wdlua5_textbounds(lua_State *L) +static int wdlua5_gettextbounds(lua_State *L) { double rect[8]; double x = luaL_checknumber(L, 2); @@ -1587,6 +1587,28 @@ static int cdlua5_vectortexttransform(lua_State *L) } /***************************************************************************\ +* cd.VectorFontSize(w, h: number, text: string) * +\***************************************************************************/ +static int cdlua5_vectorfontsize(lua_State *L) +{ + cdCanvasVectorFontSize(cdlua_checkcanvas(L, 1), luaL_checknumber(L, 2), luaL_checknumber(L, 3)); + return 0; +} + +/***************************************************************************\ +* cd.GetVectorFontSize(text: string) -> (w, h: number) * +\***************************************************************************/ +static int cdlua5_getvectorfontsize(lua_State *L) +{ + double width; + double height; + cdCanvasGetVectorFontSize(cdlua_checkcanvas(L, 1), &width, &height); + lua_pushnumber(L, width); + lua_pushnumber(L, height); + return 2; +} + +/***************************************************************************\ * cd.VectorTextSize(w, h: number, text: string) * \***************************************************************************/ static int cdlua5_vectortextsize(lua_State *L) @@ -1662,7 +1684,7 @@ static int wdlua5_getvectortextsize(lua_State *L) /***************************************************************************\ * cd.GetVectorTextBounds(s: string, px,py: number) -> (rect: table) * \***************************************************************************/ -static int cdlua5_vectortextbounds(lua_State *L) +static int cdlua5_getvectortextbounds(lua_State *L) { const char* s = luaL_checkstring(L, 2); int x = luaL_checkint(L, 3); @@ -1682,7 +1704,7 @@ static int cdlua5_vectortextbounds(lua_State *L) /***************************************************************************\ * cd.wGetVectorTextBounds(s: string, px,py: number) -> (rect: table) * \***************************************************************************/ -static int wdlua5_vectortextbounds(lua_State *L) +static int wdlua5_getvectortextbounds(lua_State *L) { const char* s = luaL_checkstring(L, 2); double x = luaL_checknumber(L, 3); @@ -1700,6 +1722,42 @@ static int wdlua5_vectortextbounds(lua_State *L) return 1; } +/****************************************************************************\ +* cd.GetVectorTextBox(x, y: number, text: string) -> (xmin, xmax, ymin, ymax: number) * +\****************************************************************************/ +static int cdlua5_getvectortextbox(lua_State *L) +{ + int xmin, xmax, ymin, ymax; + int x = luaL_checkint(L, 2); + int y = luaL_checkint(L, 3); + const char* s = luaL_checkstring(L, 4); + + cdCanvasGetVectorTextBox(cdlua_checkcanvas(L, 1), x, y, s, &xmin, &xmax, &ymin, &ymax); + lua_pushnumber(L, xmin); + lua_pushnumber(L, xmax); + lua_pushnumber(L, ymin); + lua_pushnumber(L, ymax); + return 4; +} + +/*****************************************************************************\ +* cd.wGetVectorTextBox(x, y: number, text: string) -> (xmin, xmax, ymin, ymax: number) * +\*****************************************************************************/ +static int wdlua5_getvectortextbox(lua_State *L) +{ + double xmin, xmax, ymin, ymax; + double x = luaL_checknumber(L, 2); + double y = luaL_checknumber(L, 3); + const char* s = luaL_checkstring(L, 4); + + wdCanvasGetVectorTextBox(cdlua_checkcanvas(L, 1), x, y, s, &xmin, &xmax, &ymin, &ymax); + lua_pushnumber(L, xmin); + lua_pushnumber(L, xmax); + lua_pushnumber(L, ymin); + lua_pushnumber(L, ymax); + return 4; +} + /***************************************************************************\ @@ -2249,14 +2307,14 @@ static const struct luaL_reg cdlib_canvas_meta[] = { {"NativeFont" , cdlua5_nativefont}, {"TextAlignment" , cdlua5_textalignment}, {"TextOrientation" , cdlua5_textorientation}, - {"GetFontDim" , cdlua5_fontdim}, - {"wGetFontDim" , wdlua5_fontdim}, - {"GetTextSize" , cdlua5_textsize}, - {"wGetTextSize" , wdlua5_textsize}, - {"GetTextBox" , cdlua5_textbox}, - {"wGetTextBox" , wdlua5_textbox}, - {"GetTextBounds" , cdlua5_textbounds}, - {"wGetTextBounds" , wdlua5_textbounds}, + {"GetFontDim" , cdlua5_getfontdim}, + {"wGetFontDim" , wdlua5_getfontdim}, + {"GetTextSize" , cdlua5_gettextsize}, + {"wGetTextSize" , wdlua5_gettextsize}, + {"GetTextBox" , cdlua5_gettextbox}, + {"wGetTextBox" , wdlua5_gettextbox}, + {"GetTextBounds" , cdlua5_gettextbounds}, + {"wGetTextBounds" , wdlua5_gettextbounds}, /* Vector Text */ {"VectorText" , cdlua5_vectortext}, @@ -2266,6 +2324,8 @@ static const struct luaL_reg cdlib_canvas_meta[] = { {"VectorTextDirection" , cdlua5_vectortextdirection}, {"wVectorTextDirection" , wdlua5_vectortextdirection}, {"VectorTextTransform" , cdlua5_vectortexttransform}, + {"VectorFontSize" , cdlua5_vectorfontsize}, + {"GetVectorFontSize" , cdlua5_getvectorfontsize}, {"VectorTextSize" , cdlua5_vectortextsize}, {"wVectorTextSize" , wdlua5_vectortextsize}, {"VectorCharSize" , cdlua5_vectorcharsize}, @@ -2273,8 +2333,10 @@ static const struct luaL_reg cdlib_canvas_meta[] = { {"VectorFont" , cdlua5_vectorfont}, {"GetVectorTextSize" , cdlua5_getvectortextsize}, {"wGetVectorTextSize" , wdlua5_getvectortextsize}, - {"VectorTextBounds" , cdlua5_vectortextbounds}, - {"wVectorTextBounds" , wdlua5_vectortextbounds}, + {"GetVectorTextBounds" , cdlua5_getvectortextbounds}, + {"wGetVectorTextBounds" , wdlua5_getvectortextbounds}, + {"GetVectorTextBox" , cdlua5_getvectortextbox}, + {"wGetVectorTextBox" , wdlua5_getvectortextbox}, /* Client Images */ {"GetImageRGB" , cdlua5_getimagergb}, diff --git a/src/pdflib/pdflib/p_type3.c b/src/pdflib/pdflib/p_type3.c index 411bd0d..c177443 100644 --- a/src/pdflib/pdflib/p_type3.c +++ b/src/pdflib/pdflib/p_type3.c @@ -10,7 +10,7 @@ | | *---------------------------------------------------------------------------*/ -/* $Id: p_type3.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ +/* $Id: p_type3.c,v 1.2 2009/06/23 03:18:34 scuri Exp $ * * Routines for Type 3 (user-defined) fonts * @@ -633,7 +633,7 @@ pdf__begin_glyph( /* see comment in p_font.c for explanation */ glyph->width = 1000 * wx * font->ft.matrix.a; - /* if the strdup above fails, cleanup won't touch this slot. */ + /* if the pdc_strdup above fails, cleanup won't touch this slot. */ t3font->next_glyph++; } glyph->pass = t3font->pass; diff --git a/src/sim/cdfontex.c b/src/sim/cdfontex.c index 699b06f..b0617a9 100644 --- a/src/sim/cdfontex.c +++ b/src/sim/cdfontex.c @@ -630,28 +630,16 @@ static void cdGetFontDimEx(int *max_width, int *line_height, int *ascent, int *d static void cdGetTextSizeEx(const char *s, int *width, int *height) { - int i = 0, numlin = 1, max_line_width = 0, line_width = 0; + int i = 0, w = 0; while (s[i] != '\0') { - if (s[i] == '\n') - { - numlin++; - line_width = 0; - } - else - { - line_width += font.CharWidth(s[i]); - } - - if (line_width > max_line_width) - max_line_width = line_width; - + w += font.CharWidth(s[i]); i++; } - if (height) *height = numlin * font.line_height; - if (width) *width = max_line_width; + if (height) *height = font.line_height; + if (width) *width = w; } void cdgetfontdimEX(cdCtxCanvas* ctxcanvas, int *max_width, int *height, int *ascent, int *descent) diff --git a/src/sim/sim_text.c b/src/sim/sim_text.c index 7172e16..86821ce 100644 --- a/src/sim/sim_text.c +++ b/src/sim/sim_text.c @@ -305,8 +305,8 @@ void simGetPenPos(cdCanvas* canvas, int x, int y, const char* s, FT_Matrix *matr int old_invert_yaxis = canvas->invert_yaxis; int w, h, ascent, height, baseline; - cdCanvasGetTextSize(canvas, s, &w, &h); - cdCanvasGetFontDim(canvas, NULL, &height, &ascent, NULL); + cdgettextsizeSIM(canvas->ctxcanvas, s, &w, &h); + cdgetfontdimSIM(canvas->ctxcanvas, NULL, &height, &ascent, NULL); baseline = height - ascent; /* in this case we are always upwards */ diff --git a/src/win32/cdwin.c b/src/win32/cdwin.c index 3a71746..ab8d63e 100644 --- a/src/win32/cdwin.c +++ b/src/win32/cdwin.c @@ -25,6 +25,8 @@ typedef BOOL (CALLBACK* AlphaBlendFunc)( HDC hdcDest, BLENDFUNCTION ftn); static AlphaBlendFunc cdwAlphaBlend = NULL; +static void cdgettextsize (cdCtxCanvas* ctxcanvas, const char *s, int *width, int *height); + /* %F Libera memoria e handles alocados pelo driver Windows. */ @@ -967,7 +969,7 @@ static void sTextOutBlt(cdCtxCanvas* ctxcanvas, int px, int py, const char* s, i double cos_teta = cos(teta); double sin_teta = sin(teta); - cdCanvasGetTextSize(ctxcanvas->canvas, s, &w, &h); + cdgettextsize(ctxcanvas, s, &w, &h); wt = w; ht = h; @@ -1163,7 +1165,7 @@ static void cdwCanvasGetTextHeight(cdCanvas* canvas, int x, int y, const char *s int w, h, ascent, height, baseline; int xmin, xmax, ymin, ymax; - cdCanvasGetTextSize(canvas, s, &w, &h); + cdgettextsize(canvas->ctxcanvas, s, &w, &h); cdCanvasGetFontDim(canvas, NULL, &height, &ascent, NULL); baseline = height - ascent; @@ -1247,7 +1249,7 @@ static void cdtext(cdCtxCanvas* ctxcanvas, int x, int y, const char *s) { /* compensa deficiencia do alinhamento no windows */ int off; - cdCanvasGetTextSize(ctxcanvas->canvas, s, NULL, &h); + cdgettextsize(ctxcanvas, s, NULL, &h); off = h/2 - ctxcanvas->font.descent; if (ctxcanvas->canvas->text_orientation != 0) diff --git a/src/win32/cdwwmf.c b/src/win32/cdwwmf.c index 6b47aa5..0571c9f 100644 --- a/src/win32/cdwwmf.c +++ b/src/win32/cdwwmf.c @@ -76,7 +76,7 @@ static void cdcreatecanvas(cdCanvas* canvas, void* data) ctxcanvas->clip_pnt[3].y = ctxcanvas->clip_pnt[2].y = canvas->h - 1; /* Inicializacao de variaveis particulares para o WMF */ - ctxcanvas->filename = strdup(filename); + ctxcanvas->filename = cdStrDup(filename); } static void cdinittable(cdCanvas* canvas) diff --git a/src/x11/xvertex.c b/src/x11/xvertex.c index 87a05e9..d58af13 100644 --- a/src/x11/xvertex.c +++ b/src/x11/xvertex.c @@ -48,16 +48,19 @@ /* Debugging macros */ #ifdef DEBUG -static int debug=1; +#define DEBUG_PRINT1(a) printf (a) +#define DEBUG_PRINT2(a, b) printf (a, b) +#define DEBUG_PRINT3(a, b, c) printf (a, b, c) +#define DEBUG_PRINT4(a, b, c, d) printf (a, b, c, d) +#define DEBUG_PRINT5(a, b, c, d, e) printf (a, b, c, d, e) #else -static int debug=0; +#define DEBUG_PRINT1(a) (a) +#define DEBUG_PRINT2(a, b) (a, b) +#define DEBUG_PRINT3(a, b, c) (a, b, c) +#define DEBUG_PRINT4(a, b, c, d) (a, b, c, d) +#define DEBUG_PRINT5(a, b, c, d, e) (a, b, c, d, e) #endif /*DEBUG*/ -#define DEBUG_PRINT1(a) if (debug) printf (a) -#define DEBUG_PRINT2(a, b) if (debug) printf (a, b) -#define DEBUG_PRINT3(a, b, c) if (debug) printf (a, b, c) -#define DEBUG_PRINT4(a, b, c, d) if (debug) printf (a, b, c, d) -#define DEBUG_PRINT5(a, b, c, d, e) if (debug) printf (a, b, c, d, e) /* ---------------------------------------------------------------------- */ @@ -126,29 +129,26 @@ static void XRotFreeTextItem(Display *dpy, RotatedTextItem *item); /* ---------------------------------------------------------------------- */ - /**************************************************************************/ -/* Routine to mimic `strdup()' (some machines don't have it) */ +/* Routine to mimic `my_strdup()' (some machines don't have it) */ /**************************************************************************/ static char *my_strdup(const char *str) { char *s; + int len; if(str==NULL) return NULL; - s=(char *)malloc((unsigned)(strlen(str)+1)); + len = (int)strlen(str); + s=(char *)malloc((unsigned)(len+1)); if(s!=NULL) - strcpy(s, str); + memcpy(s, str, len+1); return s; } - -/* ---------------------------------------------------------------------- */ - - /**************************************************************************/ /* Routine to replace `strtok' : this one returns a zero length string if */ /* it encounters two consecutive delimiters */ @@ -285,9 +285,9 @@ static int XRotDrawHorizontalString(Display *dpy, XFontStruct *font, Drawable dr str3=my_strtok(str1, str2); /* loop through each section in the string */ - do { - XTextExtents(font, str3, strlen(str3), &dir, &asc, &desc, - &overall); + do + { + XTextExtents(font, str3, strlen(str3), &dir, &asc, &desc, &overall); /* where to draw section in x ? */ if(align==XR_TLEFT || align==XR_MLEFT || align==XR_BLEFT || align==XR_LEFT) @@ -307,8 +307,7 @@ static int XRotDrawHorizontalString(Display *dpy, XFontStruct *font, Drawable dr yp+=height; str3=my_strtok((char *)NULL, str2); - } - while(str3!=NULL); + } while(str3!=NULL); free(str1); XFreeGC(dpy, my_gc); @@ -525,8 +524,7 @@ static RotatedTextItem *XRotCreateTextItem(Display *dpy, XFontStruct *font, doub str3=my_strtok(str1, str2); - XTextExtents(font, str3, strlen(str3), &dir, &asc, &desc, - &overall); + XTextExtents(font, str3, strlen(str3), &dir, &asc, &desc, &overall); item->max_width=overall.rbearing; @@ -1118,8 +1116,7 @@ XPoint *XRotTextExtents(Display* dpy, XFontStruct* font, double angle, int x, in str3=my_strtok(str1, str2); - XTextExtents(font, str3, strlen(str3), &dir, &asc, &desc, - &overall); + XTextExtents(font, str3, strlen(str3), &dir, &asc, &desc, &overall); max_width=overall.rbearing; @@ -1222,13 +1219,6 @@ int XRotDrawString(Display* dpy, XFontStruct* font, double angle, Drawable drawa RotatedTextItem *item; Pixmap bitmap_to_paint; - /* return early for NULL/empty strings */ - if(text==NULL) - return 0; - - if(strlen(text)==0) - return 0; - /* manipulate angle to 0<=angle<360 degrees */ while(angle<0) angle+=360; |