Exemplo n.º 1
0
static void shDrawPaintMesh(VGContext *c, SHVector2 *min, SHVector2 *max,
                            VGPaintMode mode, GLenum texUnit)
{
  SHPaint *p;
  SHVector2 pmin, pmax;
  SHfloat K = 1.0f;
  
  /* Pick the right paint */
  if (mode == VG_FILL_PATH) {
    p = (c->fillPaint ? c->fillPaint : &c->defaultPaint);
  }else if (mode == VG_STROKE_PATH) {
    p = (c->strokePaint ? c->strokePaint : &c->defaultPaint);
    K = SH_CEIL(c->strokeMiterLimit * c->strokeLineWidth) + 1.0f;
  }
  
  /* We want to be sure to cover every pixel of this path so better
     take a pixel more than leave some out (multisampling is tricky). */
  SET2V(pmin, (*min)); SUB2(pmin, K,K);
  SET2V(pmax, (*max)); ADD2(pmax, K,K);

  /* Construct appropriate OpenGL primitives so as
     to fill the stencil mask with select paint */

  switch (p->type) {
  case VG_PAINT_TYPE_LINEAR_GRADIENT:
    shDrawLinearGradientMesh(p, min, max, mode, texUnit);
    break;

  case VG_PAINT_TYPE_RADIAL_GRADIENT:
    shDrawRadialGradientMesh(p, min, max, mode, texUnit);
    break;
    
  case VG_PAINT_TYPE_PATTERN:
    if (p->pattern != VG_INVALID_HANDLE) {
      shDrawPatternMesh(p, min, max, mode, texUnit);
      break;
    }/* else behave as a color paint */
  
  case VG_PAINT_TYPE_COLOR:
    glColor4fv((GLfloat*)&p->color);
    glBegin(GL_QUADS);
    glVertex2f(pmin.x, pmin.y);
    glVertex2f(pmax.x, pmin.y);
    glVertex2f(pmax.x, pmax.y);
    glVertex2f(pmin.x, pmax.y);
    glEnd();
    break;
  }
}
Exemplo n.º 2
0
int shDrawLinearGradientMesh(SHPaint *p, SHVector2 *min, SHVector2 *max,
                             VGPaintMode mode, GLenum texUnit)
{
  SHint i;
  SHfloat n;
  
  SHfloat x1 = p->linearGradient[0];
  SHfloat y1 = p->linearGradient[1];
  SHfloat x2 = p->linearGradient[2];
  SHfloat y2 = p->linearGradient[3];
  SHVector2 c, ux, uy;
  SHVector2 cc, uux, uuy;
  
  SHMatrix3x3 *m;
  SHMatrix3x3 mi;
  SHint invertible;
  SHVector2 corners[4];
  SHfloat minOffset = 0.0f;
  SHfloat maxOffset = 0.0f;
  SHfloat left = 0.0f;
  SHfloat right = 0.0f;
  SHVector2 l1,r1,l2,r2;

  /* Pick paint transform matrix */
  SH_GETCONTEXT(0);
  if (mode == VG_FILL_PATH)
    m = &context->fillTransform;
  else if (mode == VG_STROKE_PATH)
    m = &context->strokeTransform;
  
  /* Gradient center and unit vectors */
  SET2(c, x1, y1);
  SET2(ux, x2-x1, y2-y1);
  SET2(uy, -ux.y, ux.x);
  n = NORM2(ux);
  DIV2(ux, n);
  NORMALIZE2(uy);

  /* Apply paint-to-user transformation */
  ADD2V(ux, c); ADD2V(uy, c);
  TRANSFORM2TO(c, (*m), cc);
  TRANSFORM2TO(ux, (*m), uux);
  TRANSFORM2TO(uy, (*m), uuy);
  SUB2V(ux,c); SUB2V(uy,c);
  SUB2V(uux,cc); SUB2V(uuy,cc);
  
  /* Boundbox corners */
  SET2(corners[0], min->x, min->y);
  SET2(corners[1], max->x, min->y);
  SET2(corners[2], max->x, max->y);
  SET2(corners[3], min->x, max->y);
  
  /* Find inverse transformation (back to paint space) */
  invertible = shInvertMatrix(m, &mi);
  if (!invertible || n==0.0f) {
    
    /* Fill boundbox with color at offset 1 */
    SHColor *c = &p->stops.items[p->stops.size-1].color;
    glColor4fv((GLfloat*)c); glBegin(GL_QUADS);
    for (i=0; i<4; ++i) glVertex2fv((GLfloat*)&corners[i]);
    glEnd();
    return 1;
  }
  
  /*--------------------------------------------------------*/
  
  for (i=0; i<4; ++i) {
    
    /* Find min/max offset and perpendicular span */
    SHfloat o, s;
    TRANSFORM2(corners[i], mi);
    SUB2V(corners[i], c);
    o = DOT2(corners[i], ux) / n;
    s = DOT2(corners[i], uy);
    if (o < minOffset || i==0) minOffset = o;
    if (o > maxOffset || i==0) maxOffset = o;
    if (s < left || i==0) left = s;
    if (s > right || i==0) right = s;
  }
  
  /*---------------------------------------------------------*/
  
  /* Corners of boundbox in gradient system */
  SET2V(l1, cc); SET2V(r1, cc);
  SET2V(l2, cc); SET2V(r2, cc);
  OFFSET2V(l1, uuy, left);  OFFSET2V(l1, uux, minOffset * n);
  OFFSET2V(r1, uuy, right); OFFSET2V(r1, uux, minOffset * n);
  OFFSET2V(l2, uuy, left);  OFFSET2V(l2, uux, maxOffset * n);
  OFFSET2V(r2, uuy, right); OFFSET2V(r2, uux, maxOffset * n);
  
  /* Draw quad using color-ramp texture */
  glActiveTexture(texUnit);
  shSetGradientTexGLState(p);
  
  glEnable(GL_TEXTURE_1D);
  glBegin(GL_QUAD_STRIP);
  
  glMultiTexCoord1f(texUnit, minOffset);
  glVertex2fv((GLfloat*)&r1);
  glVertex2fv((GLfloat*)&l1);
  
  glMultiTexCoord1f(texUnit, maxOffset);
  glVertex2fv((GLfloat*)&r2);
  glVertex2fv((GLfloat*)&l2);
  
  glEnd();
  glDisable(GL_TEXTURE_1D);

  return 1;
}
Exemplo n.º 3
0
static void shDrawPaintMesh(VGContext *c, SHVector2 *min, SHVector2 *max,
                            VGPaintMode mode, GLenum texUnit)
{
  SHPaint *p;
  SHVector2 pmin, pmax;
  SHfloat K = 1.0f;
#ifdef ANDROIDVG
	SHColor *color;
	GLfloat v[6][2];
#endif
  
  /* Pick the right paint */
  if (mode == VG_FILL_PATH) {
    p = (c->fillPaint ? c->fillPaint : &c->defaultPaint);
  }else if (mode == VG_STROKE_PATH) {
    p = (c->strokePaint ? c->strokePaint : &c->defaultPaint);
    K = SH_CEIL(c->strokeMiterLimit * c->strokeLineWidth) + 1.0f;
  }
  
  /* We want to be sure to cover every pixel of this path so better
     take a pixel more than leave some out (multisampling is tricky). */
  SET2V(pmin, (*min)); SUB2(pmin, K,K);
  SET2V(pmax, (*max)); ADD2(pmax, K,K);

  /* Construct appropriate OpenGL primitives so as
     to fill the stencil mask with select paint */

  switch (p->type) {
  case VG_PAINT_TYPE_LINEAR_GRADIENT:
    shDrawLinearGradientMesh(p, min, max, mode, texUnit);
    break;

  case VG_PAINT_TYPE_RADIAL_GRADIENT:
    shDrawRadialGradientMesh(p, min, max, mode, texUnit);
    break;
    
  case VG_PAINT_TYPE_PATTERN:
    if (p->pattern != VG_INVALID_HANDLE) {
      shDrawPatternMesh(p, min, max, mode, texUnit);
      break;
    }/* else behave as a color paint */
  
  case VG_PAINT_TYPE_COLOR:
#ifdef ANDROIDVG
	v[0][0] = pmin.x; v[0][1] = pmin.y;
	v[1][0] = pmax.x; v[1][1] = pmin.y;
	v[2][0] = pmax.x; v[2][1] = pmax.y;
	v[3][0] = pmin.x; v[3][1] = pmin.y;
	v[4][0] = pmax.x; v[4][1] = pmax.y;
	v[5][0] = pmin.x; v[5][1] = pmax.y;
	color = &p->color;
	glColor4f(color->r, color->g, color->b, color->a);
	glEnableClientState(GL_VERTEX_ARRAY);
	glVertexPointer(2, GL_FLOAT, 0, v); 
	glDrawArrays(GL_TRIANGLES, 0, 6); 
	glDisableClientState(GL_VERTEX_ARRAY);
#else
	glColor4fv((GLfloat*)&p->color);
	glBegin(GL_QUADS);
	glVertex2f(pmin.x, pmin.y);
	glVertex2f(pmax.x, pmin.y);
	glVertex2f(pmax.x, pmax.y);
	glVertex2f(pmin.x, pmax.y);
	glEnd();
#endif
    break;
  }
}