Back to index

lightning-sunbird  0.9+nobinonly
cairo-path-fill.c
Go to the documentation of this file.
00001 /* cairo - a vector graphics library with display and print output
00002  *
00003  * Copyright © 2002 University of Southern California
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it either under the terms of the GNU Lesser General Public
00007  * License version 2.1 as published by the Free Software Foundation
00008  * (the "LGPL") or, at your option, under the terms of the Mozilla
00009  * Public License Version 1.1 (the "MPL"). If you do not alter this
00010  * notice, a recipient may use your version of this file under either
00011  * the MPL or the LGPL.
00012  *
00013  * You should have received a copy of the LGPL along with this library
00014  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
00015  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00016  * You should have received a copy of the MPL along with this library
00017  * in the file COPYING-MPL-1.1
00018  *
00019  * The contents of this file are subject to the Mozilla Public License
00020  * Version 1.1 (the "License"); you may not use this file except in
00021  * compliance with the License. You may obtain a copy of the License at
00022  * http://www.mozilla.org/MPL/
00023  *
00024  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
00025  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
00026  * the specific language governing rights and limitations.
00027  *
00028  * The Original Code is the cairo graphics library.
00029  *
00030  * The Initial Developer of the Original Code is University of Southern
00031  * California.
00032  *
00033  * Contributor(s):
00034  *     Carl D. Worth <cworth@cworth.org>
00035  */
00036 
00037 #include "cairoint.h"
00038 
00039 typedef struct cairo_filler {
00040     double tolerance;
00041     cairo_traps_t *traps;
00042 
00043     cairo_point_t current_point;
00044 
00045     cairo_polygon_t polygon;
00046 } cairo_filler_t;
00047 
00048 static void
00049 _cairo_filler_init (cairo_filler_t *filler, double tolerance, cairo_traps_t *traps);
00050 
00051 static void
00052 _cairo_filler_fini (cairo_filler_t *filler);
00053 
00054 static cairo_status_t
00055 _cairo_filler_move_to (void *closure, cairo_point_t *point);
00056 
00057 static cairo_status_t
00058 _cairo_filler_line_to (void *closure, cairo_point_t *point);
00059 
00060 static cairo_status_t
00061 _cairo_filler_curve_to (void *closure,
00062                      cairo_point_t *b,
00063                      cairo_point_t *c,
00064                      cairo_point_t *d);
00065 
00066 static cairo_status_t
00067 _cairo_filler_close_path (void *closure);
00068 
00069 static void
00070 _cairo_filler_init (cairo_filler_t *filler, double tolerance, cairo_traps_t *traps)
00071 {
00072     filler->tolerance = tolerance;
00073     filler->traps = traps;
00074 
00075     filler->current_point.x = 0;
00076     filler->current_point.y = 0;
00077 
00078     _cairo_polygon_init (&filler->polygon);
00079 }
00080 
00081 static void
00082 _cairo_filler_fini (cairo_filler_t *filler)
00083 {
00084     _cairo_polygon_fini (&filler->polygon);
00085 }
00086 
00087 static cairo_status_t
00088 _cairo_filler_move_to (void *closure, cairo_point_t *point)
00089 {
00090     cairo_status_t status;
00091     cairo_filler_t *filler = closure;
00092     cairo_polygon_t *polygon = &filler->polygon;
00093 
00094     status = _cairo_polygon_close (polygon);
00095     if (status)
00096        return status;
00097       
00098     status = _cairo_polygon_move_to (polygon, point);
00099     if (status)
00100        return status;
00101 
00102     filler->current_point = *point;
00103 
00104     return CAIRO_STATUS_SUCCESS;
00105 }
00106 
00107 static cairo_status_t
00108 _cairo_filler_line_to (void *closure, cairo_point_t *point)
00109 {
00110     cairo_status_t status;
00111     cairo_filler_t *filler = closure;
00112     cairo_polygon_t *polygon = &filler->polygon;
00113 
00114     status = _cairo_polygon_line_to (polygon, point);
00115     if (status)
00116        return status;
00117 
00118     filler->current_point = *point;
00119 
00120     return CAIRO_STATUS_SUCCESS;
00121 }
00122 
00123 static cairo_status_t
00124 _cairo_filler_curve_to (void *closure,
00125                      cairo_point_t *b,
00126                      cairo_point_t *c,
00127                      cairo_point_t *d)
00128 {
00129     int i;
00130     cairo_status_t status = CAIRO_STATUS_SUCCESS;
00131     cairo_filler_t *filler = closure;
00132     cairo_polygon_t *polygon = &filler->polygon;
00133     cairo_spline_t spline;
00134 
00135     status = _cairo_spline_init (&spline, &filler->current_point, b, c, d);
00136 
00137     if (status == CAIRO_INT_STATUS_DEGENERATE)
00138        return CAIRO_STATUS_SUCCESS;
00139 
00140     _cairo_spline_decompose (&spline, filler->tolerance);
00141     if (status)
00142        goto CLEANUP_SPLINE;
00143 
00144     for (i = 1; i < spline.num_points; i++) {
00145        status = _cairo_polygon_line_to (polygon, &spline.points[i]);
00146        if (status)
00147            break;
00148     }
00149 
00150   CLEANUP_SPLINE:
00151     _cairo_spline_fini (&spline);
00152 
00153     filler->current_point = *d;
00154 
00155     return status;
00156 }
00157 
00158 static cairo_status_t
00159 _cairo_filler_close_path (void *closure)
00160 {
00161     cairo_status_t status;
00162     cairo_filler_t *filler = closure;
00163     cairo_polygon_t *polygon = &filler->polygon;
00164 
00165     status = _cairo_polygon_close (polygon);
00166     if (status)
00167        return status;
00168 
00169     return CAIRO_STATUS_SUCCESS;
00170 }
00171 
00172 cairo_status_t
00173 _cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path,
00174                              cairo_fill_rule_t   fill_rule,
00175                              double              tolerance,
00176                              cairo_traps_t      *traps)
00177 {
00178     cairo_status_t status = CAIRO_STATUS_SUCCESS;
00179     cairo_filler_t filler;
00180 
00181     _cairo_filler_init (&filler, tolerance, traps);
00182 
00183     status = _cairo_path_fixed_interpret (path,
00184                                      CAIRO_DIRECTION_FORWARD,
00185                                      _cairo_filler_move_to,
00186                                      _cairo_filler_line_to,
00187                                      _cairo_filler_curve_to,
00188                                      _cairo_filler_close_path,
00189                                      &filler);
00190     if (status)
00191        goto BAIL;
00192 
00193     status = _cairo_polygon_close (&filler.polygon);
00194     if (status)
00195        goto BAIL;
00196 
00197     status = _cairo_traps_tessellate_polygon (filler.traps,
00198                                          &filler.polygon,
00199                                          fill_rule);
00200     if (status)
00201        goto BAIL;
00202 
00203 BAIL:
00204     _cairo_filler_fini (&filler);
00205 
00206     return status;
00207 }
00208