示例#1
0
void image_draw(struct vg_image *img)
{
   struct vg_context *ctx = vg_current_context();
   VGfloat x1, y1;
   VGfloat x2, y2;
   VGfloat x3, y3;
   VGfloat x4, y4;
   struct matrix *matrix;

   x1 = 0;
   y1 = 0;
   x2 = img->width;
   y2 = 0;
   x3 = img->width;
   y3 = img->height;
   x4 = 0;
   y4 = img->height;

   matrix = &ctx->state.vg.image_user_to_surface_matrix;

   matrix_map_point(matrix, x1, y1, &x1, &y1);
   matrix_map_point(matrix, x2, y2, &x2, &y2);
   matrix_map_point(matrix, x3, y3, &x3, &y3);
   matrix_map_point(matrix, x4, y4, &x4, &y4);

   shader_set_drawing_image(ctx->shader, VG_TRUE);
   shader_set_paint(ctx->shader, ctx->state.vg.fill_paint);
   shader_set_image(ctx->shader, img);
   shader_bind(ctx->shader);

   renderer_texture_quad(ctx->renderer, image_texture(img),
                         img->x, img->y, img->x + img->width, img->y + img->height,
                         x1, y1, x2, y2, x3, y3, x4, y4);
}
示例#2
0
void vgPathTransformedBounds(VGPath path,
                             VGfloat * minX,
                             VGfloat * minY,
                             VGfloat * width,
                             VGfloat * height)
{
   struct vg_context *ctx = vg_current_context();
   struct path *p = 0;
   VGbitfield caps;

   if (path == VG_INVALID_HANDLE) {
      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
      return;
   }

   if (!minX || !minY || !width || !height) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }

   if (!is_aligned(minX) || !is_aligned(minY) ||
       !is_aligned(width) || !is_aligned(height)) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }

   p = (struct path*)path;

   caps = path_capabilities(p);
   if (!(caps & VG_PATH_CAPABILITY_PATH_TRANSFORMED_BOUNDS)) {
      vg_set_error(ctx, VG_PATH_CAPABILITY_ERROR);
      return;
   }

#if 0
   /* faster, but seems to have precision problems... */
   path_bounding_rect(p, minX, minY, width, height);
   if (*width > 0 && *height > 0) {
      VGfloat pts[] = {*minX,          *minY,
                       *minX + *width, *minY,
                       *minX + *width, *minY + *height,
                       *minX,          *minY + *height};
      struct matrix *matrix = &ctx->state.vg.path_user_to_surface_matrix;
      VGfloat maxX, maxY;
      matrix_map_point(matrix, pts[0], pts[1], pts + 0, pts + 1);
      matrix_map_point(matrix, pts[2], pts[3], pts + 2, pts + 3);
      matrix_map_point(matrix, pts[4], pts[5], pts + 4, pts + 5);
      matrix_map_point(matrix, pts[6], pts[7], pts + 6, pts + 7);
      *minX = MIN2(pts[0], MIN2(pts[2], MIN2(pts[4], pts[6])));
      *minY = MIN2(pts[1], MIN2(pts[3], MIN2(pts[5], pts[7])));
      maxX = MAX2(pts[0], MAX2(pts[2], MAX2(pts[4], pts[6])));
      maxY = MAX2(pts[1], MAX2(pts[3], MAX2(pts[5], pts[7])));
      *width  = maxX - *minX;
      *height = maxY - *minY;
   }
#else
   {
      struct path *dst = path_create(VG_PATH_DATATYPE_F, 1.0, 0,
                                     0, 0, VG_PATH_CAPABILITY_ALL);
      path_transform(dst, p);
      path_bounding_rect(dst, minX, minY, width, height);
      path_destroy(dst);
   }
#endif
}
示例#3
0
static void arc_to_beziers(struct arc *arc,
                           struct arc_cb cb,
                           struct matrix *matrix)
{
   int i;
   int n = 1;
   double d_eta, eta_b, cos_eta_b,
      sin_eta_b, a_cos_eta_b, b_sin_eta_b, a_sin_eta_b,
      b_cos_eta_b, x_b, y_b, x_b_dot, y_b_dot, lx, ly;
   double t, alpha;

   { /* always move to the start of the arc */
      VGfloat x = arc->x1;
      VGfloat y = arc->y1;
      matrix_map_point(matrix, x, y, &x, &y);
      cb.move(&cb, x, y);
   }

   if (!arc->is_valid) {
      VGfloat x = arc->x2;
      VGfloat y = arc->y2;
      matrix_map_point(matrix, x, y, &x, &y);
      cb.point(&cb, x, y);
      return;
   }

   /* find the number of Bézier curves needed */
   n = num_beziers_needed(arc);

   d_eta = (arc->eta2 - arc->eta1) / n;
   eta_b = arc->eta1;

   cos_eta_b  = cos(eta_b);
   sin_eta_b  = sin(eta_b);
   a_cos_eta_b = arc->a * cos_eta_b;
   b_sin_eta_b = arc->b * sin_eta_b;
   a_sin_eta_b = arc->a * sin_eta_b;
   b_cos_eta_b = arc->b * cos_eta_b;
   x_b       = arc->cx + a_cos_eta_b * arc->cos_theta -
               b_sin_eta_b * arc->sin_theta;
   y_b       = arc->cy + a_cos_eta_b * arc->sin_theta +
               b_sin_eta_b * arc->cos_theta;
   x_b_dot    = -a_sin_eta_b * arc->cos_theta -
                b_cos_eta_b * arc->sin_theta;
   y_b_dot    = -a_sin_eta_b * arc->sin_theta +
                b_cos_eta_b * arc->cos_theta;

   {
      VGfloat x = x_b, y = y_b;
      matrix_map_point(matrix, x, y, &x, &y);
      cb.point(&cb, x, y);
   }
   lx = x_b;
   ly = y_b;

   t     = tan(0.5 * d_eta);
   alpha = sin(d_eta) * (sqrt(4 + 3 * t * t) - 1) / 3;

   for (i = 0; i < n; ++i) {
      struct bezier bezier;
      double xA    = x_b;
      double yA    = y_b;
      double xADot = x_b_dot;
      double yADot = y_b_dot;

      eta_b    += d_eta;
      cos_eta_b  = cos(eta_b);
      sin_eta_b  = sin(eta_b);
      a_cos_eta_b = arc->a * cos_eta_b;
      b_sin_eta_b = arc->b * sin_eta_b;
      a_sin_eta_b = arc->a * sin_eta_b;
      b_cos_eta_b = arc->b * cos_eta_b;
      x_b       = arc->cx + a_cos_eta_b * arc->cos_theta -
                  b_sin_eta_b * arc->sin_theta;
      y_b       = arc->cy + a_cos_eta_b * arc->sin_theta +
                  b_sin_eta_b * arc->cos_theta;
      x_b_dot    = -a_sin_eta_b * arc->cos_theta -
                   b_cos_eta_b * arc->sin_theta;
      y_b_dot    = -a_sin_eta_b * arc->sin_theta +
                   b_cos_eta_b * arc->cos_theta;

      bezier_init(&bezier,
                  lx, ly,
                  (float) (xA + alpha * xADot), (float) (yA + alpha * yADot),
                  (float) (x_b - alpha * x_b_dot), (float) (y_b - alpha * y_b_dot),
                  (float) x_b,                   (float) y_b);
#if 0
      debug_printf("%d) Bezier (%f, %f), (%f, %f), (%f, %f), (%f, %f)\n",
                   i,
                   bezier.x1, bezier.y1,
                   bezier.x2, bezier.y2,
                   bezier.x3, bezier.y3,
                   bezier.x4, bezier.y4);
#endif
      bezier_transform(&bezier, matrix);
      cb.bezier(&cb, &bezier);
      lx = x_b;
      ly = y_b;
   }
}
示例#4
0
static VGboolean find_angles(struct arc *arc)
{
   double vec0[2], vec1[2];
   double lambda1, lambda2;
   double angle;
   struct matrix matrix;

   if (floatIsZero(arc->a) || floatIsZero(arc->b)) {
      return VG_FALSE;
   }
   /* map the points to an identity circle */
   matrix_load_identity(&matrix);
   matrix_scale(&matrix, 1.f, arc->a/arc->b);
   matrix_rotate(&matrix, -arc->theta);
   matrix_map_point(&matrix,
                    arc->x1, arc->y1,
                    &arc->x1, &arc->y1);
   matrix_map_point(&matrix,
                    arc->x2, arc->y2,
                    &arc->x2, &arc->y2);
   matrix_map_point(&matrix,
                    arc->cx, arc->cy,
                    &arc->cx, &arc->cy);

#if DEBUG_ARCS
   debug_printf("Matrix 3 [%f, %f, %f| %f, %f, %f| %f, %f, %f]\n",
                matrix.m[0], matrix.m[1], matrix.m[2],
                matrix.m[3], matrix.m[4], matrix.m[5],
                matrix.m[6], matrix.m[7], matrix.m[8]);
   debug_printf("Endpoints [%f, %f], [%f, %f]\n",
                arc->x1, arc->y1, arc->x2, arc->y2);
#endif

   vec0[0] = arc->x1 - arc->cx;
   vec0[1] = arc->y1 - arc->cy;
   vec1[0] = arc->x2 - arc->cx;
   vec1[1] = arc->y2 - arc->cy;

#if DEBUG_ARCS
   debug_printf("Vec is [%f, %f], [%f, %f], [%f, %f]\n",
                vec0[0], vec0[1], vec1[0], vec1[1], arc->cx, arc->cy);
#endif

   lambda1 = vector_orientation(vec0);

   if (isnan(lambda1))
      lambda1 = 0.f;

   if (arc->type == VG_SCWARC_TO ||
       arc->type == VG_SCCWARC_TO)
      angle = vector_angles(vec0, vec1);
   else if (arc->type == VG_LCWARC_TO ||
            arc->type == VG_LCCWARC_TO) {
      angle = 2*M_PI - vector_angles(vec0, vec1);
   } else
      abort();

   if (isnan(angle))
      angle = M_PI;


   if (arc->type == VG_SCWARC_TO ||
       arc->type == VG_LCWARC_TO)
      lambda2 = lambda1 - angle;
   else
      lambda2 = lambda1 + angle;

#if DEBUG_ARCS
   debug_printf("Angle is %f and (%f, %f)\n", angle, lambda1, lambda2);
#endif

#if 0
   arc->eta1 = atan2(sin(lambda1) / arc->b,
                     cos(lambda1) / arc->a);
   arc->eta2 = atan2(sin(lambda2) / arc->b,
                     cos(lambda2) / arc->a);

   /* make sure we have eta1 <= eta2 <= eta1 + 2 PI */
   arc->eta2 -= two_pi * floor((arc->eta2 - arc->eta1) / two_pi);

   /* the preceding correction fails if we have exactly et2 - eta1 = 2 PI
      it reduces the interval to zero length */
   if ((lambda2 - lambda1 > M_PI) && (arc->eta2 - arc->eta1 < M_PI)) {
      arc->eta2 += 2 * M_PI;
   }
#else
   arc->eta1 = lambda1;
   arc->eta2 = lambda2;
#endif

   return VG_TRUE;
}