Back to index

lightning-sunbird  0.9+nobinonly
cairo-path-bounds.c
Go to the documentation of this file.
00001 /* cairo - a vector graphics library with display and print output
00002  *
00003  * Copyright © 2003 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_path_bounder {
00040     int has_point;
00041 
00042     cairo_fixed_t min_x;
00043     cairo_fixed_t min_y;
00044     cairo_fixed_t max_x;
00045     cairo_fixed_t max_y;
00046 } cairo_path_bounder_t;
00047 
00048 static void
00049 _cairo_path_bounder_init (cairo_path_bounder_t *bounder);
00050 
00051 static void
00052 _cairo_path_bounder_fini (cairo_path_bounder_t *bounder);
00053 
00054 static cairo_status_t
00055 _cairo_path_bounder_add_point (cairo_path_bounder_t *bounder, cairo_point_t *point);
00056 
00057 static cairo_status_t
00058 _cairo_path_bounder_move_to (void *closure, cairo_point_t *point);
00059 
00060 static cairo_status_t
00061 _cairo_path_bounder_line_to (void *closure, cairo_point_t *point);
00062 
00063 static cairo_status_t
00064 _cairo_path_bounder_curve_to (void *closure,
00065                            cairo_point_t *b,
00066                            cairo_point_t *c,
00067                            cairo_point_t *d);
00068 
00069 static cairo_status_t
00070 _cairo_path_bounder_close_path (void *closure);
00071 
00072 static void
00073 _cairo_path_bounder_init (cairo_path_bounder_t *bounder)
00074 {
00075     bounder->has_point = 0;
00076 }
00077 
00078 static void
00079 _cairo_path_bounder_fini (cairo_path_bounder_t *bounder)
00080 {
00081     bounder->has_point = 0;
00082 }
00083 
00084 static cairo_status_t
00085 _cairo_path_bounder_add_point (cairo_path_bounder_t *bounder, cairo_point_t *point)
00086 {
00087     if (bounder->has_point) {
00088        if (point->x < bounder->min_x)
00089            bounder->min_x = point->x;
00090        
00091        if (point->y < bounder->min_y)
00092            bounder->min_y = point->y;
00093        
00094        if (point->x > bounder->max_x)
00095            bounder->max_x = point->x;
00096        
00097        if (point->y > bounder->max_y)
00098            bounder->max_y = point->y;
00099     } else {
00100        bounder->min_x = point->x;
00101        bounder->min_y = point->y;
00102        bounder->max_x = point->x;
00103        bounder->max_y = point->y;
00104 
00105        bounder->has_point = 1;
00106     }
00107        
00108     return CAIRO_STATUS_SUCCESS;
00109 }
00110 
00111 static cairo_status_t
00112 _cairo_path_bounder_move_to (void *closure, cairo_point_t *point)
00113 {
00114     cairo_path_bounder_t *bounder = closure;
00115 
00116     _cairo_path_bounder_add_point (bounder, point);
00117 
00118     return CAIRO_STATUS_SUCCESS;
00119 }
00120 
00121 static cairo_status_t
00122 _cairo_path_bounder_line_to (void *closure, cairo_point_t *point)
00123 {
00124     cairo_path_bounder_t *bounder = closure;
00125 
00126     _cairo_path_bounder_add_point (bounder, point);
00127 
00128     return CAIRO_STATUS_SUCCESS;
00129 }
00130 
00131 static cairo_status_t
00132 _cairo_path_bounder_curve_to (void *closure,
00133                            cairo_point_t *b,
00134                            cairo_point_t *c,
00135                            cairo_point_t *d)
00136 {
00137     cairo_path_bounder_t *bounder = closure;
00138 
00139     _cairo_path_bounder_add_point (bounder, b);
00140     _cairo_path_bounder_add_point (bounder, c);
00141     _cairo_path_bounder_add_point (bounder, d);
00142 
00143     return CAIRO_STATUS_SUCCESS;
00144 }
00145 
00146 static cairo_status_t
00147 _cairo_path_bounder_close_path (void *closure)
00148 {
00149     return CAIRO_STATUS_SUCCESS;
00150 }
00151 
00152 /* XXX: Perhaps this should compute a PixRegion rather than 4 doubles */
00153 cairo_status_t
00154 _cairo_path_fixed_bounds (cairo_path_fixed_t *path,
00155                        double *x1, double *y1,
00156                        double *x2, double *y2)
00157 {
00158     cairo_status_t status;
00159 
00160     cairo_path_bounder_t bounder;
00161 
00162     _cairo_path_bounder_init (&bounder);
00163 
00164     status = _cairo_path_fixed_interpret (path, CAIRO_DIRECTION_FORWARD,
00165                                      _cairo_path_bounder_move_to,
00166                                      _cairo_path_bounder_line_to,
00167                                      _cairo_path_bounder_curve_to,
00168                                      _cairo_path_bounder_close_path,
00169                                      &bounder);
00170     if (status) {
00171        *x1 = *y1 = *x2 = *y2 = 0.0;
00172        _cairo_path_bounder_fini (&bounder);
00173        return status;
00174     }
00175 
00176     *x1 = _cairo_fixed_to_double (bounder.min_x);
00177     *y1 = _cairo_fixed_to_double (bounder.min_y);
00178     *x2 = _cairo_fixed_to_double (bounder.max_x);
00179     *y2 = _cairo_fixed_to_double (bounder.max_y);
00180 
00181     _cairo_path_bounder_fini (&bounder);
00182 
00183     return CAIRO_STATUS_SUCCESS;
00184 }