/[crust]/crust/libs/GraphicsFoundation/GFContext.c
ViewVC logotype

Diff of /crust/libs/GraphicsFoundation/GFContext.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by jrydberg, Sun Aug 26 20:46:03 2001 UTC revision 1.2 by jrydberg, Wed Aug 29 01:02:38 2001 UTC
# Line 27  Line 27 
27  #include <libart/libart.h>  #include <libart/libart.h>
28  #include <libart/art_affine.h>  #include <libart/art_affine.h>
29  #include <libart/art_render.h>  #include <libart/art_render.h>
30    #include <libart/art_bpath.h>
31  #include <libart/art_render_svp.h>  #include <libart/art_render_svp.h>
32    
33  #include "GFContext.h"  #include "GFContext.h"
# Line 113  GFContextBeginPath (GFContextRef context Line 114  GFContextBeginPath (GFContextRef context
114  {  {
115    /* We just truncate the number of vectors.  */    /* We just truncate the number of vectors.  */
116    context->vpath_n = 0;    context->vpath_n = 0;
117      context->bpath_n = 0;
118  }  }
119    
120  /* Close current subpath.  */  /* Close current subpath.  */
# Line 177  GFContextSetAlpha (GFContextRef context, Line 179  GFContextSetAlpha (GFContextRef context,
179    context->gstate->alpha_value = value;    context->gstate->alpha_value = value;
180  }  }
181    
 /* Set fill color to VALUE.  Number of components in VALUE is  
    specified by current fill color space.  */  
 void  
 GFContextSetFillColor (GFContextRef context, float value[])  
 {  
   int i;  
   
   for (i = 0; i < context->gstate->fill_space->n_components; i++)  
     context->gstate->fill_color [i] = value [i];  
 }  
   
182  /* Set CONTEXT's fill color space to COLORSPACE.  */  /* Set CONTEXT's fill color space to COLORSPACE.  */
183  void  void
184  GFContextSetFillColorSpace (GFContextRef context,  GFContextSetFillColorSpace (GFContextRef context,
# Line 197  GFContextSetFillColorSpace (GFContextRef Line 188  GFContextSetFillColorSpace (GFContextRef
188    context->gstate->fill_space = colorspace;    context->gstate->fill_space = colorspace;
189  }  }
190    
   
 /* Set stoke color to VALUE.  Number of components in VALUE is  
    specified by current stroke color space.  */  
 void  
 GFContextSetStrokeColor (GFContextRef context, float value[])  
 {  
   int i;  
   
   for (i = 0; i < context->gstate->stroke_space->n_components; i++)  
     context->gstate->stroke_color [i] = value [i];  
 }  
   
191  /* Set CONTEXT's stroke color space to COLORSPACE.  */  /* Set CONTEXT's stroke color space to COLORSPACE.  */
192  void  void
193  GFContextSetStrokeColorSpace (GFContextRef context,  GFContextSetStrokeColorSpace (GFContextRef context,
# Line 225  void Line 204  void
204  GFContextSetRGBFillColor (GFContextRef context, float r, float  GFContextSetRGBFillColor (GFContextRef context, float r, float
205                            g, float b, float alpha)                            g, float b, float alpha)
206  {  {
207    float value_array [3] = { r, g, b };    float value_array [4] = { r, g, b, alpha };
208    
209    GFContextSetFillColorSpace (context, GFColorSpaceCreateDeviceRGB ());    GFContextSetFillColorSpace (context, GFColorSpaceCreateDeviceRGB ());
210    GFContextSetFillColor (context, value_array);    GFContextSetFillColor (context, value_array);
   GFContextSetAlpha (context, alpha);  
211  }  }
212    
213  /* Convenience function to set stroke color space to DeviceRGB  /* Convenience function to set stroke color space to DeviceRGB
# Line 238  void Line 216  void
216  GFContextSetRGBStrokeColor (GFContextRef context, float r, float  GFContextSetRGBStrokeColor (GFContextRef context, float r, float
217                              g, float b, float alpha)                              g, float b, float alpha)
218  {  {
219    float value_array [3] = { r, g, b };    float value_array [4] = { r, g, b, alpha };
220    
221    GFContextSetStrokeColorSpace (context, GFColorSpaceCreateDeviceRGB ());    GFContextSetStrokeColorSpace (context, GFColorSpaceCreateDeviceRGB ());
222    GFContextSetStrokeColor (context, value_array);    GFContextSetStrokeColor (context, value_array);
   GFContextSetAlpha (context, alpha);  
223  }  }
224    
225  /* Set line width in current graphic state to LINE_WIDTH.  */  /* Set line width in current graphic state to LINE_WIDTH.  */
# Line 272  GFContextSetLineJoin (GFContextRef conte Line 249  GFContextSetLineJoin (GFContextRef conte
249    gstate->line_join = line_join;    gstate->line_join = line_join;
250  }  }
251    
252    static void
253    path_arc_segment (GFContextRef context,
254                      double xc, double yc,
255                      double th0, double th1,
256                      double rx, double ry, double x_axis_rotation)
257    {
258      ArtBpath bez;
259      double sin_th, cos_th;
260      double a00, a01, a10, a11;
261      double x1, y1, x2, y2, x3, y3;
262      double t;
263      double th_half;
264    
265      sin_th = sin (x_axis_rotation);
266      cos_th = cos (x_axis_rotation);  
267    
268      /* inverse transform compared with rsvg_path_arc */
269      a00 = cos_th * rx;
270      a01 = -sin_th * ry;
271      a10 = sin_th * rx;
272      a11 = cos_th * ry;
273    
274      th_half = 0.5 * (th1 - th0);
275      t = (8.0 / 3.0) * sin (th_half * 0.5) * sin (th_half * 0.5) / sin (th_half);
276      x1 = xc + cos (th0) - t * sin (th0);
277      y1 = yc + sin (th0) + t * cos (th0);
278      x3 = xc + cos (th1);
279      y3 = yc + sin (th1);
280      x2 = x3 + t * sin (th1);
281      y2 = y3 - t * cos (th1);
282    
283      bez.code = ART_CURVETO;
284      bez.x1   = a00 * x1 + a01 * y1;
285      bez.y1   = a10 * x1 + a11 * y1;
286      bez.x2   = a00 * x2 + a01 * y2;
287      bez.y2   = a10 * x2 + a11 * y2;
288      bez.x3   = a00 * x3 + a01 * y3;
289      bez.y3   = a10 * x3 + a11 * y3;
290    
291      context->bpath [context->bpath_n++] = bez;
292    
293      art_vpath_add_point (&context->vpath, &context->vpath_n,
294                           &context->vpath_n_max, ART_CURVETO, bez.x3, bez.y3);  
295    }
296    
297    /* Draws an elliptical arc from the current point to (X, Y).
298       The size and orientation of the ellipse are defined by
299       two radii (RX, RY) and an X_AXIS_ROTATION, which indicates
300       how the ellipse as a whole is rotated relative to the current
301       coordinate system.  LARGE_ARC_FLAG and SWEEP_FLAG contribute
302       to the automatic calculations and help determine how the arc
303       is drawn.
304    
305       LARGE_ARC_FLAG: 0 for arc length <= 180, 1 for arc >= 180.
306       SWEEP_FLAG: 0 for "negative angle", 1 for "positive angle".  */
307    void
308    GFContextAddArcToPoint (GFContextRef context, float rx, float ry,
309                            float x_axis_rotation, int large_arc_flag,
310                            int sweep_flag, float x, float y)
311    {
312      double sin_th, cos_th;
313      double a00, a01, a10, a11, cpx, cpy;
314      double x0, y0, x1, y1, xc, yc;
315      double d, sfactor, sfactor_sq;
316      double th0, th1, th_arc;
317      int i, n_segs;
318    
319      sin_th = sin (x_axis_rotation);
320      cos_th = cos (x_axis_rotation);
321      a00 = cos_th / rx;
322      a01 = sin_th / rx;
323      a10 = -sin_th / ry;
324      a11 = cos_th / ry;
325    
326      cpx = context->vpath[context->vpath_n - 1].x;
327      cpy = context->vpath[context->vpath_n - 1].y;
328    
329      x0 = a00 * cpx + a01 * cpy;
330      y0 = a10 * cpx + a11 * cpy;
331      x1 = a00 * x + a01 * y;
332      y1 = a10 * x + a11 * y;
333    
334      /* (x0, y0) is current point in transformed coordinate space.
335         (x1, y1) is new point in transformed coordinate space.
336    
337         The arc fits a unit-radius circle in this space.  */
338      d = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0);
339      sfactor_sq = 1.0 / d - 0.25;
340      if (sfactor_sq < 0)
341        sfactor_sq = 0;
342      sfactor = sqrt (sfactor_sq);
343    
344      if (sweep_flag == large_arc_flag)
345        sfactor = -sfactor;
346    
347      xc = 0.5 * (x0 + x1) - sfactor * (y1 - y0);
348      yc = 0.5 * (y0 + y1) + sfactor * (x1 - x0);
349      /* (xc, yc) is center of the circle. */
350    
351      th0 = atan2 (y0 - yc, x0 - xc);
352      th1 = atan2 (y1 - yc, x1 - xc);
353    
354      th_arc = th1 - th0;
355      if (th_arc < 0 && sweep_flag)
356        th_arc += 2 * M_PI;
357      else if (th_arc > 0 && !sweep_flag)
358        th_arc -= 2 * M_PI;
359    
360      n_segs = ceil (fabs (th_arc / (M_PI * 0.5 + 0.001)));
361    
362      for (i = 0; i < n_segs; i++)
363        path_arc_segment (context, xc, yc,
364                          th0 + i * th_arc / n_segs,
365                          th0 + (i + 1) * th_arc / n_segs,
366                          rx, ry, x_axis_rotation);
367    }
368    
369    
370    
371  /* Add a bezier curve from current point to (X0, Y0).  (X1, Y1) and  /* Add a bezier curve from current point to (X0, Y0).  (X1, Y1) and
372     (X2, Y2) is the two control points.  */     (X2, Y2) is the two control points.  */
373  void  void
# Line 361  GFContextDrawPath (GFContextRef context, Line 457  GFContextDrawPath (GFContextRef context,
457            bez[0].x3   = cx;            bez[0].x3   = cx;
458            bez[0].y3   = cy;            bez[0].y3   = cy;
459            bez[1]      = context->bpath [bez_index++];            bez[1]      = context->bpath [bez_index++];
           bez[1].y1   = context->size.height - bez[1].y1;  
           bez[1].y2   = context->size.height - bez[1].y2;  
           bez[1].y3   = context->size.height - bez[1].y3;  
460            bez[2].code = ART_END;            bez[2].code = ART_END;
461    
462            bezpath = art_bez_path_to_vec (bez, 0.5);  /* ?? from state.  */            bezpath = art_bez_path_to_vec (bez, 0.5);  /* ?? from state.  */
# Line 378  GFContextDrawPath (GFContextRef context, Line 471  GFContextDrawPath (GFContextRef context,
471        else        else
472          {          {
473            art_vpath_add_point (&final, &final_n, &final_n_max,            art_vpath_add_point (&final, &final_n, &final_n_max,
474                                 vpath[i].code, vpath[i].x,                                 vpath[i].code, vpath[i].x, vpath[i].y);
                                context->size.height - vpath[i].y);  
475          }          }
476    
477        cx = final [final_n - 1].x;        cx = final [final_n - 1].x;
# Line 412  GFContextDrawPath (GFContextRef context, Line 504  GFContextDrawPath (GFContextRef context,
504        svp = art_svp_rewind_uncrossed (uncrossed, wind_rule);        svp = art_svp_rewind_uncrossed (uncrossed, wind_rule);
505        art_free (uncrossed);        art_free (uncrossed);
506    
507        rowstride = context->size.width * (context->n_components + 1)        rowstride = context->size.width * (context->n_components )
508          * context->n_bits_per_component / 8;          * context->n_bits_per_component / 8;
509                
510        alpha_info = alpha_info_to_libart_alpha_info (context->alpha_info);        alpha_info = alpha_info_to_libart_alpha_info (context->alpha_info);
# Line 421  GFContextDrawPath (GFContextRef context, Line 513  GFContextDrawPath (GFContextRef context,
513        render = art_render_new (x0, y0, x1 - x0, y1 - y0, context->dst_buffer,        render = art_render_new (x0, y0, x1 - x0, y1 - y0, context->dst_buffer,
514                                 rowstride, 3, 8, alpha_info, alpha_pos, NULL);                                 rowstride, 3, 8, alpha_info, alpha_pos, NULL);
515        art_render_svp (render, svp);        art_render_svp (render, svp);
516        (*gstate->stroke_space->render_fn) (gstate->fill_space,        paintserver_invoke (context, gstate->fill_space, render);
517                                            gstate->fill_color, render);        art_render_mask_solid (render, render->opacity * gstate->alpha_value);
       art_render_mask_solid (render, MAX_OPACITY (gstate->alpha_value));  
518        art_render_invoke (render);        art_render_invoke (render);
519          paintserver_free (context, gstate->fill_space);
520        art_free (svp);        art_free (svp);
521      }      }
522    
# Line 441  GFContextDrawPath (GFContextRef context, Line 533  GFContextDrawPath (GFContextRef context,
533        svp = art_svp_uncross (tmp_svp);        svp = art_svp_uncross (tmp_svp);
534        art_free (tmp_svp);        art_free (tmp_svp);
535    
536        rowstride = context->size.width * (context->n_components + 1)        rowstride = context->size.width * (context->n_components)
537          * context->n_bits_per_component / 8;          * context->n_bits_per_component / 8;
538                
539        alpha_info = alpha_info_to_libart_alpha_info (context->alpha_info);        alpha_info = alpha_info_to_libart_alpha_info (context->alpha_info);
# Line 450  GFContextDrawPath (GFContextRef context, Line 542  GFContextDrawPath (GFContextRef context,
542        render = art_render_new (x0, y0, x1 - x0, y1 - y0, context->dst_buffer,        render = art_render_new (x0, y0, x1 - x0, y1 - y0, context->dst_buffer,
543                                 rowstride, 3, 8, alpha_info, alpha_pos, NULL);                                 rowstride, 3, 8, alpha_info, alpha_pos, NULL);
544        art_render_svp (render, svp);        art_render_svp (render, svp);
545        (*gstate->stroke_space->render_fn) (gstate->stroke_space,        paintserver_invoke (context, gstate->stroke_space, render);
546                                            gstate->stroke_color, render);        art_render_mask_solid (render, render->opacity * gstate->alpha_value);
       art_render_mask_solid (render, MAX_OPACITY (gstate->alpha_value));  
547        art_render_invoke (render);        art_render_invoke (render);
548          paintserver_free (context, gstate->stroke_space);
549        art_free (svp);        art_free (svp);
550      }      }
551    art_free (transformed);    art_free (transformed);

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26