diff options
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; | 
