コード例 #1
0
ファイル: sim_primitives.c プロジェクト: Vulcanior/IUP
static int sBezierNumSegments(cdCanvas* canvas, cdPoint start, const cdPoint* p)
{
  int i, K, dx, dy, d,
    xmax = start.x, 
    ymax = start.y, 
    xmin = start.x, 
    ymin = start.y;

  for (i = 1; i < 4; i++)
  {
    if (p[i].x > xmax)
      xmax = p[i].x;
    if (p[i].y > ymax)
      ymax = p[i].y;
    if (p[i].x < xmin)
      xmin = p[i].x;
    if (p[i].y < ymin)
      ymin = p[i].y;
  }

  if (canvas->use_matrix)
  {
    cdMatrixTransformPoint(canvas->matrix, xmin, ymin, &xmin, &ymin);
    cdMatrixTransformPoint(canvas->matrix, xmax, ymax, &xmax, &ymax);
  }

  /* diagonal of the bounding box */
  dx = (xmax-xmin);
  dy = (ymax-ymin);
  d = (int)(sqrt(dx*dx + dy*dy));
  K = d / 8;
  if (K < 8) K = 8;
  return K;
}
コード例 #2
0
ファイル: cdgdk.c プロジェクト: LuaDist/cd
static void cdline(cdCtxCanvas *ctxcanvas, int x1, int y1, int x2, int y2)
{ 
  if (ctxcanvas->canvas->use_matrix)
  {
    cdMatrixTransformPoint(ctxcanvas->xmatrix, x1, y1, &x1, &y1);
    cdMatrixTransformPoint(ctxcanvas->xmatrix, x2, y2, &x2, &y2);
  }

  cdgdkCheckSolidStyle(ctxcanvas, 1);
  gdk_draw_line(ctxcanvas->wnd, ctxcanvas->gc, x1, y1, x2, y2);
  cdgdkCheckSolidStyle(ctxcanvas, 0);
}
コード例 #3
0
ファイル: cd_image.c プロジェクト: LuaDist/cd
void cdImageRGBCalcDstLimits(cdCanvas* canvas, int x, int y, int w, int h, int *xmin, int *xmax, int *ymin, int *ymax, int* rect)
{
  int t_xmin, t_xmax, t_ymin, t_ymax,
      t_x, t_y, t_w, t_h; 

  /* calculate the bounding box of the transformed rectangle */
  cdMatrixTransformPoint(canvas->matrix, x, y, &t_x, &t_y);
  if (rect) { rect[0] = t_x; rect[1] = t_y; }
  t_xmax = t_xmin = t_x; t_ymax = t_ymin = t_y;
  cdMatrixTransformPoint(canvas->matrix, x+w-1, y, &t_x, &t_y);
  if (rect) { rect[2] = t_x; rect[3] = t_y; }
  if (t_x > t_xmax) t_xmax = t_x;
  if (t_x < t_xmin) t_xmin = t_x;
  if (t_y > t_ymax) t_ymax = t_y;
  if (t_y < t_ymin) t_ymin = t_y;
  cdMatrixTransformPoint(canvas->matrix, x+w-1, y+h-1, &t_x, &t_y);
  if (rect) { rect[4] = t_x; rect[5] = t_y; }
  if (t_x > t_xmax) t_xmax = t_x;
  if (t_x < t_xmin) t_xmin = t_x;
  if (t_y > t_ymax) t_ymax = t_y;
  if (t_y < t_ymin) t_ymin = t_y;
  cdMatrixTransformPoint(canvas->matrix, x, y+h-1, &t_x, &t_y);
  if (rect) { rect[6] = t_x; rect[7] = t_y; }
  if (t_x > t_xmax) t_xmax = t_x;
  if (t_x < t_xmin) t_xmin = t_x;
  if (t_y > t_ymax) t_ymax = t_y;
  if (t_y < t_ymin) t_ymin = t_y;

  t_x = t_xmin;
  t_y = t_ymin;
  t_w = t_xmax-t_xmin+1;
  t_h = t_ymax-t_ymin+1;

  /* check if inside the canvas */
  if (t_x > (canvas->w-1) || t_y > (canvas->h-1) || 
      (t_x+t_w) < 0 || (t_y+t_h) < 0)
    return;

  /* fit to canvas area */
  if (t_x < 0) t_x = 0;
  if (t_y < 0) t_y = 0;
  if ((t_x+t_w) > (canvas->w-1)) t_w = (canvas->w-1)-t_x;
  if ((t_y+t_h) > (canvas->h-1)) t_h = (canvas->h-1)-t_y;

  /* define the destiny limits */
  *xmin = t_x;
  *ymin = t_y;
  *xmax = t_x+t_w-1;
  *ymax = t_y+t_h-1;
}
コード例 #4
0
ファイル: sim_primitives.c プロジェクト: Vulcanior/IUP
static int sCalcEllipseNumSegments(cdCanvas* canvas, int xc, int yc, int width, int height, double angle1, double angle2)
{
  int K, dx, dy, hd;
  int w2 = width/2;
  int h2 = height/2;
  int x1 = xc-w2, 
      y1 = yc-h2, 
      x2 = xc+w2, 
      y2 = yc+h2;

  if (canvas->use_matrix)
  {
    cdMatrixTransformPoint(canvas->matrix, x1, y1, &x1, &y1);
    cdMatrixTransformPoint(canvas->matrix, x2, y2, &x2, &y2);
  }

  /* first calculate the number of segments of equivalent poligonal for a full ellipse */

  dx = (x1-x2);
  dy = (y1-y2);
  hd = (int)(sqrt(dx*dx + dy*dy)/2);

  /*  Estimation Heuristic:
  use half diagonal to estimate the number of segments for 360 degrees.
  Use the difference of the half diagonal and its projection to calculate the minimum angle:
  cos(min_angle) = hd / (hd + 1)     or   min_angle = acos(hd / (hd + 1))
  The number of segments will be 360 / min_angle.
  */

  K = (int)((360.0*CD_DEG2RAD) / acos((double)hd / (hd + 1.0)) + 0.5); /* round up */

  /* multiple of 4 */
  K = ((K + 3)/4)*4;

  /* minimum number is 4 */
  if (K < 4) K = 4;


  /* finally, calculate the number of segments for the arc */
  K = cdRound((fabs(angle2-angle1)*K)/(360*CD_DEG2RAD));
  if (K < 1) K = 1;

  return K;
}
コード例 #5
0
ファイル: sim_primitives.c プロジェクト: gcfavorites/tastools
void cdlineSIM(cdCtxCanvas* ctxcanvas, int x1, int y1, int x2, int y2)
{
  cdCanvas* canvas = ((cdCtxCanvasBase*)ctxcanvas)->canvas;
  int old_use_matrix = canvas->use_matrix;

  if (canvas->use_matrix && !canvas->invert_yaxis)
  {
    cdMatrixTransformPoint(canvas->matrix, x1, y1, &x1, &y1);
    cdMatrixTransformPoint(canvas->matrix, x2, y2, &x2, &y2);
  }

  /* must disable transformation here, because line simulation use cxPixel */
  canvas->use_matrix = 0;

  if(canvas->line_width > 1)
    simLineThick(canvas, x1, y1, x2, y2);
  else 
    simLineThin(canvas, x1, y1, x2, y2);

  canvas->use_matrix = old_use_matrix;
}
コード例 #6
0
ファイル: cdgdk.c プロジェクト: LuaDist/cd
static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
{
  int i;

  if (mode != CD_BEZIER && mode != CD_PATH)
  {
    for (i = 0; i < n; i++)
    {
      if (ctxcanvas->canvas->use_matrix)
        cdMatrixTransformPoint(ctxcanvas->xmatrix, poly[i].x, poly[i].y, &(poly[i].x), &(poly[i].y));
    }
  }

  switch( mode )
  {
  case CD_FILL:
    if (ctxcanvas->canvas->new_region)
    {
      GdkRegion* rgn = gdk_region_polygon((GdkPoint*)poly, n, ctxcanvas->canvas->fill_mode == CD_EVENODD ? GDK_EVEN_ODD_RULE : GDK_WINDING_RULE);
      sCombineRegion(ctxcanvas, rgn);
    }
    else
      gdk_draw_polygon(ctxcanvas->wnd, ctxcanvas->gc, TRUE, (GdkPoint*)poly, n);
    break;

  case CD_CLOSED_LINES:
    cdgdkCheckSolidStyle(ctxcanvas, 1);
    gdk_draw_polygon(ctxcanvas->wnd, ctxcanvas->gc, FALSE, (GdkPoint*)poly, n);
    cdgdkCheckSolidStyle(ctxcanvas, 0);
    break;

  case CD_OPEN_LINES:
    cdgdkCheckSolidStyle(ctxcanvas, 1);
    gdk_draw_lines(ctxcanvas->wnd, ctxcanvas->gc, (GdkPoint*)poly, n);
    cdgdkCheckSolidStyle(ctxcanvas, 0);
    break;

  case CD_CLIP:
    ctxcanvas->clip_rgn = gdk_region_polygon((GdkPoint*)poly, n, ctxcanvas->canvas->fill_mode == CD_EVENODD ? GDK_EVEN_ODD_RULE : GDK_WINDING_RULE);     
    if (ctxcanvas->canvas->clip_mode == CD_CLIPPOLYGON)
      cdclip(ctxcanvas, CD_CLIPPOLYGON);
    break;

  case CD_BEZIER:
    cdSimPolyBezier(ctxcanvas->canvas, poly, n);
    break;

  case CD_PATH:
    cdSimPolyPath(ctxcanvas->canvas, poly, n);
    break;
  }
}
コード例 #7
0
ファイル: sim_primitives.c プロジェクト: gcfavorites/tastools
void cdpolySIM(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
{
  cdCanvas* canvas = ((cdCtxCanvasBase*)ctxcanvas)->canvas;
  int i, reset = 1;

  switch(mode) 
  {
  case CD_CLOSED_LINES:
    poly[n] = poly[0];
    n++;
    /* continue */
  case CD_OPEN_LINES:
    if (simLineStyleNoReset)  /* Bezier simulation use several poly */
    {
      reset = 0;
      simLineStyleNoReset = 1;
    }
    for (i = 0; i< n - 1; i++)
      canvas->cxLine(canvas->ctxcanvas, poly[i].x, poly[i].y, poly[i+1].x, poly[i+1].y);
    if (reset) simLineStyleNoReset = 0;
    break;
  case CD_BEZIER:
    simLineStyleNoReset = 1;
    cdSimPolyBezier(canvas, poly, n);
    simLineStyleNoReset = 0;
    break;
  case CD_FILL:
    {
      /* must set line attributes here, because fill simulation use cxLine */
      int oldwidth = cdCanvasLineWidth(canvas, 1);
      int oldstyle = cdCanvasLineStyle(canvas, CD_CONTINUOUS);
      int old_use_matrix = canvas->use_matrix;

      if (canvas->use_matrix && !canvas->invert_yaxis)
      {
        for(i = 0; i < n; i++)
          cdMatrixTransformPoint(canvas->matrix, poly[i].x, poly[i].y, &poly[i].x, &poly[i].y);
      }

      /* must disable transformation here, because line simulation use cxPixel */
      canvas->use_matrix = 0;

      simPolyFill(canvas->simulation, poly, n);

      canvas->use_matrix = old_use_matrix;
      cdCanvasLineStyle(canvas, oldstyle);
      cdCanvasLineWidth(canvas, oldwidth);
    }
    break;
  }
}
コード例 #8
0
ファイル: sim_primitives.c プロジェクト: gcfavorites/tastools
int simCalcEllipseNumSegments(cdCanvas* canvas, int xc, int yc, int width, int height)
{
  int n, dx, dy, hd;
  int w2 = width/2;
  int h2 = height/2;
  int x1 = xc-w2, 
      y1 = yc-h2, 
      x2 = xc+w2, 
      y2 = yc+h2;

  if (canvas->use_matrix)
  {
    cdMatrixTransformPoint(canvas->matrix, x1, y1, &x1, &y1);
    cdMatrixTransformPoint(canvas->matrix, x2, y2, &x2, &y2);
  }

  dx = (x1-x2);
  dy = (y1-y2);
  hd = (int)(sqrt(dx*dx + dy*dy)/2);

  /*  Estimation Heuristic:
  use half diagonal to estimate the number of segments for 360 degrees.
  Use the difference of the half diagonal and its projection to calculate the minimum angle:
  cos(min_angle) = hd / (hd + 1)     or   min_angle = acos(hd / (hd + 1))
  The number of segments will be 360 / min_angle.
  */

  n = (int)((360.0*CD_DEG2RAD) / acos((double)hd / (hd + 1.0)) + 0.5); /* round up */

  /* multiple of 4 */
  n = ((n + 3)/4)*4;

  /* minimum number is 4 */
  if (n < 4) n = 4;

  return n;
}
コード例 #9
0
ファイル: cdgdk.c プロジェクト: LuaDist/cd
static void cdpixel(cdCtxCanvas *ctxcanvas, int x, int y, long int color)
{
  if (ctxcanvas->canvas->foreground != color)
  {
    GdkColor clr = cdColorToGdk(color);
    gdk_gc_set_rgb_fg_color(ctxcanvas->gc, &clr);
  }

  if (ctxcanvas->canvas->use_matrix)
    cdMatrixTransformPoint(ctxcanvas->xmatrix, x, y, &x, &y);

  /* Draw pixel */
  gdk_draw_point(ctxcanvas->wnd, ctxcanvas->gc, x, y);

  if (ctxcanvas->canvas->foreground != color)
    gdk_gc_set_rgb_fg_color(ctxcanvas->gc, &ctxcanvas->fg);
}
コード例 #10
0
ファイル: sim_text.c プロジェクト: LuaDist/cd
void simGetPenPos(cdCanvas* canvas, int x, int y, const char* s, int len, FT_Matrix *matrix, FT_Vector *pen)
{
  int ox = x, oy = y;
  int old_invert_yaxis = canvas->invert_yaxis;
  int w, h, ascent, height, baseline;

  cdSimGetTextSizeFT(canvas->ctxcanvas, s, len, &w, &h);
  cdSimGetFontDimFT(canvas->ctxcanvas, NULL, &height, &ascent, NULL);
  baseline = height - ascent;

  /* in this case we are always upwards */

  /* move to bottom left */
  canvas->invert_yaxis = 0;
  cdTextTranslatePoint(canvas, x, y, w, h, baseline, &x, &y);
  canvas->invert_yaxis = old_invert_yaxis;

  /* move to the base line */
  y += baseline;

  /* set up matrix */
  matrix->xx = (FT_Fixed)0x10000L;
  matrix->xy = (FT_Fixed)0;
  matrix->yx = (FT_Fixed)0;
  matrix->yy = (FT_Fixed)0x10000L;

  if (canvas->text_orientation)
  {
    FT_Matrix text_matrix;
    double cos_theta = cos(canvas->text_orientation*CD_DEG2RAD);
    double sin_theta = sin(canvas->text_orientation*CD_DEG2RAD);

    /* manually rotate the initial point */
    canvas->invert_yaxis = 0;
    cdRotatePoint(canvas, x, y, ox, oy, &x, &y, sin_theta, cos_theta);
    canvas->invert_yaxis = old_invert_yaxis;

    text_matrix.xx = (FT_Fixed)( cos_theta*0x10000L);
    text_matrix.xy = (FT_Fixed)(-sin_theta*0x10000L);
    text_matrix.yx = (FT_Fixed)( sin_theta*0x10000L);
    text_matrix.yy = (FT_Fixed)( cos_theta*0x10000L);

    FT_Matrix_Multiply(&text_matrix, matrix);
  }

  if (canvas->use_matrix)
  {
    FT_Matrix trans_matrix;
    trans_matrix.xx = (FT_Fixed)(canvas->matrix[0]*0x10000L);
    trans_matrix.yx = (FT_Fixed)(canvas->matrix[1]*0x10000L);
    trans_matrix.xy = (FT_Fixed)(canvas->matrix[2]*0x10000L);
    trans_matrix.yy = (FT_Fixed)(canvas->matrix[3]*0x10000L);

    FT_Matrix_Multiply(&trans_matrix, matrix);

    /* manually transform the initial point */
    cdMatrixTransformPoint(canvas->matrix, x, y, &x, &y);
  }

  /* the pen position in 26.6 scale */
  pen->x = x * 64;
  pen->y = y * 64;

}
コード例 #11
0
ファイル: cdgdk.c プロジェクト: LuaDist/cd
static void cdtext(cdCtxCanvas *ctxcanvas, int x, int y, const char *s, int len)
{
  PangoFontMetrics* metrics;
  int w, h, desc, dir = -1;
  int ox = x, oy = y;

  pango_layout_set_text(ctxcanvas->fontlayout, sStrConvertToUTF8(ctxcanvas, s, len), -1);
  
	pango_layout_get_pixel_size(ctxcanvas->fontlayout, &w, &h);
  metrics = pango_context_get_metrics(ctxcanvas->fontcontext, ctxcanvas->fontdesc, pango_context_get_language(ctxcanvas->fontcontext));
  desc = (((pango_font_metrics_get_descent(metrics)) + PANGO_SCALE/2) / PANGO_SCALE);

  switch (ctxcanvas->canvas->text_alignment)
  {
    case CD_BASE_RIGHT:
    case CD_NORTH_EAST:
    case CD_EAST:
    case CD_SOUTH_EAST:
      x = x - w;
      break;
    case CD_BASE_CENTER:
    case CD_CENTER:
    case CD_NORTH:
    case CD_SOUTH:
      x = x - w/2;
      break;
    case CD_BASE_LEFT:
    case CD_NORTH_WEST:
    case CD_WEST:
    case CD_SOUTH_WEST:
      x = x;
      break;
  }

  if (ctxcanvas->canvas->invert_yaxis)
    dir = 1;

  switch (ctxcanvas->canvas->text_alignment)
  {
    case CD_BASE_LEFT:
    case CD_BASE_CENTER:
    case CD_BASE_RIGHT:
      y = y - (dir*h - desc);
      break;
    case CD_SOUTH_EAST:
    case CD_SOUTH_WEST:
    case CD_SOUTH:
      y = y - (dir*h);
      break;
    case CD_NORTH_EAST:
    case CD_NORTH:
    case CD_NORTH_WEST:
      y = y;
      break;
    case CD_CENTER:
    case CD_EAST:
    case CD_WEST:
      y = y - (dir*(h/2));
      break;
  }

  if(!ctxcanvas->canvas->use_matrix)
  {
    ctxcanvas->fontmatrix.xx = 1;     ctxcanvas->fontmatrix.xy = 0;
    ctxcanvas->fontmatrix.yx = 0;     ctxcanvas->fontmatrix.yy = 1;
    ctxcanvas->fontmatrix.x0 = 0;     ctxcanvas->fontmatrix.y0 = 0;
  }

  if (ctxcanvas->canvas->use_matrix || ctxcanvas->canvas->text_orientation)
  {
    PangoRectangle rect;
    double angle = ctxcanvas->canvas->text_orientation;

    if (ctxcanvas->canvas->text_orientation)
      pango_matrix_rotate(&ctxcanvas->fontmatrix, angle);

    pango_context_set_matrix (ctxcanvas->fontcontext, &ctxcanvas->fontmatrix);
    pango_layout_context_changed (ctxcanvas->fontlayout);

    pango_layout_get_pixel_extents(ctxcanvas->fontlayout, NULL, &rect);
#if PANGO_VERSION_CHECK(1,16,0)
    pango_matrix_transform_pixel_rectangle(&ctxcanvas->fontmatrix, &rect);
#endif

    if (ctxcanvas->canvas->text_orientation)
    {
      double cos_angle = cos(angle*CD_DEG2RAD);
      double sin_angle = sin(angle*CD_DEG2RAD);
      cdRotatePoint(ctxcanvas->canvas, x, y, ox, oy, &x, &y, sin_angle, cos_angle);
    }
    
    if (ctxcanvas->canvas->use_matrix)
      cdMatrixTransformPoint(ctxcanvas->xmatrix, x, y, &x, &y);

    /* Defines the new position (X,Y), considering the Pango rectangle transformed */
    x += (int)rect.x;
    y += (int)rect.y;
  }

  cdgdkCheckSolidStyle(ctxcanvas, 1);

  if (ctxcanvas->canvas->new_region)
  {
    GdkRegion *rgn;
    gint *idx;
    gint range;

    pango_layout_line_get_x_ranges(pango_layout_get_line(ctxcanvas->fontlayout, 0), 0, len, &idx, &range);

    /* TODO: this is only the bounding box of the layout, not the text itself,
             must transform the text into a polygon. */
    rgn = gdk_pango_layout_get_clip_region(ctxcanvas->fontlayout, x, y, idx, range);

    sCombineRegion(ctxcanvas, rgn);
  }
  else
    gdk_draw_layout(ctxcanvas->wnd, ctxcanvas->gc, x, y, ctxcanvas->fontlayout);

  pango_context_set_matrix(ctxcanvas->fontcontext, NULL);

  cdgdkCheckSolidStyle(ctxcanvas, 0);

  pango_font_metrics_unref(metrics); 
}