From e5afa03605e4e8eda39ecbf589796d1c51b8452a Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 2 Aug 2004 17:04:00 +0000 Subject: Fix to explicitly refer to GNU Lesser Public License 2.1 rather than the Library Public License version 2 or 'any later version' --- ChangeLog | 2 ++ src/cairo-color.c | 12 +++++------- src/cairo-features.h.in | 12 +++++------- src/cairo-fixed.c | 12 +++++------- src/cairo-font.c | 12 +++++------- src/cairo-gstate.c | 12 +++++------- src/cairo-hull.c | 12 +++++------- src/cairo-image-surface.c | 12 +++++------- src/cairo-matrix.c | 12 +++++------- src/cairo-path-bounds.c | 12 +++++------- src/cairo-path-fill.c | 12 +++++------- src/cairo-path-stroke.c | 12 +++++------- src/cairo-path.c | 12 +++++------- src/cairo-pen.c | 12 +++++------- src/cairo-polygon.c | 12 +++++------- src/cairo-ps-surface.c | 12 +++++------- src/cairo-slope.c | 12 +++++------- src/cairo-spline.c | 12 +++++------- src/cairo-surface.c | 12 +++++------- src/cairo-xcb-surface.c | 12 +++++------- src/cairo-xlib-surface.c | 12 +++++------- src/cairo.c | 12 +++++------- src/cairo.h | 12 +++++------- src/cairo_color.c | 12 +++++------- src/cairo_fixed.c | 12 +++++------- src/cairo_font.c | 12 +++++------- src/cairo_gstate.c | 12 +++++------- src/cairo_hull.c | 12 +++++------- src/cairo_image_surface.c | 12 +++++------- src/cairo_matrix.c | 12 +++++------- src/cairo_path.c | 12 +++++------- src/cairo_path_bounds.c | 12 +++++------- src/cairo_path_fill.c | 12 +++++------- src/cairo_path_stroke.c | 12 +++++------- src/cairo_pen.c | 12 +++++------- src/cairo_polygon.c | 12 +++++------- src/cairo_ps_surface.c | 12 +++++------- src/cairo_slope.c | 12 +++++------- src/cairo_spline.c | 12 +++++------- src/cairo_surface.c | 12 +++++------- src/cairo_xcb_surface.c | 12 +++++------- src/cairo_xlib_surface.c | 12 +++++------- src/cairoint.h | 12 +++++------- 43 files changed, 212 insertions(+), 294 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7bd1c15b6..07beab92b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24,6 +24,8 @@ * src/cairo_xcb_surface.c: * src/cairo_xlib_surface.c: * src/cairoint.h: Change from MIT license to LGPL. + Fix to explicitly refer to GNU Lesser Public License 2.1 rather + than the Library Public License version 2 or "any later version" * src/cairo_pattern.c: * src/cairo_gl_surface.c: Fix copyright attributions mistakenly diff --git a/src/cairo-color.c b/src/cairo-color.c index 837a9a523..a744aaf46 100644 --- a/src/cairo-color.c +++ b/src/cairo-color.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo-features.h.in b/src/cairo-features.h.in index 21d167499..01557abea 100644 --- a/src/cairo-features.h.in +++ b/src/cairo-features.h.in @@ -3,19 +3,17 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo-fixed.c b/src/cairo-fixed.c index 7dd1a07e3..a9186ff48 100644 --- a/src/cairo-fixed.c +++ b/src/cairo-fixed.c @@ -3,19 +3,17 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo-font.c b/src/cairo-font.c index af397172f..da73cc7fe 100644 --- a/src/cairo-font.c +++ b/src/cairo-font.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 563f84b4f..5854cc4f0 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo-hull.c b/src/cairo-hull.c index 93115e6a5..2bc8fd4eb 100644 --- a/src/cairo-hull.c +++ b/src/cairo-hull.c @@ -3,19 +3,17 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index c8e05804a..84de8d97d 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -3,19 +3,17 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c index 82b042f35..76567bcd4 100644 --- a/src/cairo-matrix.c +++ b/src/cairo-matrix.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo-path-bounds.c b/src/cairo-path-bounds.c index 5795c5b1f..09351219e 100644 --- a/src/cairo-path-bounds.c +++ b/src/cairo-path-bounds.c @@ -3,19 +3,17 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo-path-fill.c b/src/cairo-path-fill.c index fdb67bc4f..f130951cd 100644 --- a/src/cairo-path-fill.c +++ b/src/cairo-path-fill.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c index bb704f156..8baf01b88 100644 --- a/src/cairo-path-stroke.c +++ b/src/cairo-path-stroke.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo-path.c b/src/cairo-path.c index 31d9f250b..3d41ab7f9 100644 --- a/src/cairo-path.c +++ b/src/cairo-path.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo-pen.c b/src/cairo-pen.c index c91e97d60..2df58d271 100644 --- a/src/cairo-pen.c +++ b/src/cairo-pen.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo-polygon.c b/src/cairo-polygon.c index ad0344064..2f1681c90 100644 --- a/src/cairo-polygon.c +++ b/src/cairo-polygon.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c index cf7e0a798..264867d95 100644 --- a/src/cairo-ps-surface.c +++ b/src/cairo-ps-surface.c @@ -3,19 +3,17 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo-slope.c b/src/cairo-slope.c index 885ba4c9f..a79d7787e 100644 --- a/src/cairo-slope.c +++ b/src/cairo-slope.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo-spline.c b/src/cairo-spline.c index 68bb75eb4..56bb5b885 100644 --- a/src/cairo-spline.c +++ b/src/cairo-spline.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo-surface.c b/src/cairo-surface.c index b17368a5e..422bad633 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c index f992bf5f5..a59d5308d 100644 --- a/src/cairo-xcb-surface.c +++ b/src/cairo-xcb-surface.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index 2036f8e46..46afd2d15 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo.c b/src/cairo.c index 7c469854d..708901de1 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo.h b/src/cairo.h index 40848396d..f034ba845 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo_color.c b/src/cairo_color.c index 837a9a523..a744aaf46 100644 --- a/src/cairo_color.c +++ b/src/cairo_color.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo_fixed.c b/src/cairo_fixed.c index 7dd1a07e3..a9186ff48 100644 --- a/src/cairo_fixed.c +++ b/src/cairo_fixed.c @@ -3,19 +3,17 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo_font.c b/src/cairo_font.c index af397172f..da73cc7fe 100644 --- a/src/cairo_font.c +++ b/src/cairo_font.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo_gstate.c b/src/cairo_gstate.c index 563f84b4f..5854cc4f0 100644 --- a/src/cairo_gstate.c +++ b/src/cairo_gstate.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo_hull.c b/src/cairo_hull.c index 93115e6a5..2bc8fd4eb 100644 --- a/src/cairo_hull.c +++ b/src/cairo_hull.c @@ -3,19 +3,17 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo_image_surface.c b/src/cairo_image_surface.c index c8e05804a..84de8d97d 100644 --- a/src/cairo_image_surface.c +++ b/src/cairo_image_surface.c @@ -3,19 +3,17 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo_matrix.c b/src/cairo_matrix.c index 82b042f35..76567bcd4 100644 --- a/src/cairo_matrix.c +++ b/src/cairo_matrix.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo_path.c b/src/cairo_path.c index 31d9f250b..3d41ab7f9 100644 --- a/src/cairo_path.c +++ b/src/cairo_path.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo_path_bounds.c b/src/cairo_path_bounds.c index 5795c5b1f..09351219e 100644 --- a/src/cairo_path_bounds.c +++ b/src/cairo_path_bounds.c @@ -3,19 +3,17 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo_path_fill.c b/src/cairo_path_fill.c index fdb67bc4f..f130951cd 100644 --- a/src/cairo_path_fill.c +++ b/src/cairo_path_fill.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo_path_stroke.c b/src/cairo_path_stroke.c index bb704f156..8baf01b88 100644 --- a/src/cairo_path_stroke.c +++ b/src/cairo_path_stroke.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo_pen.c b/src/cairo_pen.c index c91e97d60..2df58d271 100644 --- a/src/cairo_pen.c +++ b/src/cairo_pen.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo_polygon.c b/src/cairo_polygon.c index ad0344064..2f1681c90 100644 --- a/src/cairo_polygon.c +++ b/src/cairo_polygon.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo_ps_surface.c b/src/cairo_ps_surface.c index cf7e0a798..264867d95 100644 --- a/src/cairo_ps_surface.c +++ b/src/cairo_ps_surface.c @@ -3,19 +3,17 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo_slope.c b/src/cairo_slope.c index 885ba4c9f..a79d7787e 100644 --- a/src/cairo_slope.c +++ b/src/cairo_slope.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo_spline.c b/src/cairo_spline.c index 68bb75eb4..56bb5b885 100644 --- a/src/cairo_spline.c +++ b/src/cairo_spline.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo_surface.c b/src/cairo_surface.c index b17368a5e..422bad633 100644 --- a/src/cairo_surface.c +++ b/src/cairo_surface.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo_xcb_surface.c b/src/cairo_xcb_surface.c index f992bf5f5..a59d5308d 100644 --- a/src/cairo_xcb_surface.c +++ b/src/cairo_xcb_surface.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairo_xlib_surface.c b/src/cairo_xlib_surface.c index 2036f8e46..46afd2d15 100644 --- a/src/cairo_xlib_surface.c +++ b/src/cairo_xlib_surface.c @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ diff --git a/src/cairoint.h b/src/cairoint.h index 2b151dfef..c8c10a65f 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -3,19 +3,17 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Author: Carl D. Worth */ -- cgit v1.2.1 From 62e4b869cd17c2fd5103d9e61656a4451624f6b9 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 3 Aug 2004 11:49:20 +0000 Subject: Temporarily disable rectangle-based clipping optimization as it's not working (see cairo_snippets/xxx_clip_rectangle for a test case). --- ChangeLog | 6 ++++++ src/cairo-gstate.c | 9 +++++++++ src/cairo_gstate.c | 9 +++++++++ 3 files changed, 24 insertions(+) diff --git a/ChangeLog b/ChangeLog index 07beab92b..e1499c714 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2004-08-03 Carl Worth + + * src/cairo_gstate.c (extract_transformed_rectangle): Temporarily + disable rectangle-based clipping optimization as it's not working + (see cairo_snippets/xxx_clip_rectangle for a test case). + 2004-08-02 Carl Worth * COPYING: diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 5854cc4f0..aeebcb49c 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -1659,6 +1659,15 @@ extract_transformed_rectangle(cairo_matrix_t *mat, double a, b, c, d, tx, ty; cairo_status_t st; + /* XXX: Something in the rectangle-based clipping support is + * broken. See cairo_snippets/xxx_clip_rectangle which + * demonstrates no clipping at all. + * + * For now, I'm am disabling this optimization completely until it + * can be fixed. + */ + return 0; + st = cairo_matrix_get_affine (mat, &a, &b, &c, &d, &tx, &ty); if (!(st == CAIRO_STATUS_SUCCESS && b == 0. && c == 0.)) return 0; diff --git a/src/cairo_gstate.c b/src/cairo_gstate.c index 5854cc4f0..aeebcb49c 100644 --- a/src/cairo_gstate.c +++ b/src/cairo_gstate.c @@ -1659,6 +1659,15 @@ extract_transformed_rectangle(cairo_matrix_t *mat, double a, b, c, d, tx, ty; cairo_status_t st; + /* XXX: Something in the rectangle-based clipping support is + * broken. See cairo_snippets/xxx_clip_rectangle which + * demonstrates no clipping at all. + * + * For now, I'm am disabling this optimization completely until it + * can be fixed. + */ + return 0; + st = cairo_matrix_get_affine (mat, &a, &b, &c, &d, &tx, &ty); if (!(st == CAIRO_STATUS_SUCCESS && b == 0. && c == 0.)) return 0; -- cgit v1.2.1 From adabb18408157299940413a80a6c943de96296d5 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Sat, 14 Aug 2004 06:35:30 +0000 Subject: Explicitly set LANG=C to fix the awk string->number conversion for user with locales that don't match ASCII digit conventions. --- ChangeLog | 6 ++++++ autogen.sh | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e1499c714..2e98fe3d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2004-08-14 Carl Worth + + * autogen.sh (LANG): Explicitly set LANG=C to fix the awk + string->number conversion for user with locales that don't match + ASCII digit conventions. + 2004-08-03 Carl Worth * src/cairo_gstate.c (extract_transformed_rectangle): Temporarily diff --git a/autogen.sh b/autogen.sh index 4de364a16..d365a92b1 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,6 +1,5 @@ #!/bin/sh # Run this to generate all the initial makefiles, etc. - set -e PACKAGE=cairo @@ -20,6 +19,8 @@ aclocal_min_vers=$automake_min_vers autoconf_min_vers=2.54 libtoolize_min_vers=1.4 +# The awk-based string->number conversion we use needs a C locale to work as expected. +LANG=C ARGV0=$0 -- cgit v1.2.1 From 31d0ddbf2a6acecea8ffede9f3f3942dcbc9c035 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Sat, 14 Aug 2004 07:21:52 +0000 Subject: Make a copy of the region since pixman is currently taking ownership of it (ugh). Thanks to Vladimir Vukicevic and Peter Dennis Bartok . --- AUTHORS | 2 ++ ChangeLog | 6 ++++++ src/cairo-image-surface.c | 15 ++++++++++++++- src/cairo_image_surface.c | 15 ++++++++++++++- 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/AUTHORS b/AUTHORS index b86eac31f..3be11047e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,4 +1,5 @@ Olivier Andrieu PNG backend +Peter Dennis Bartok Bug fix for clipping Dave Beckett Track rename of libpixman, build fixes Andrew Chant Adding const where needed John Ellson First font/glyph extents functions @@ -13,6 +14,7 @@ David Reveman New pattern API, OpenGL backend Jamey Sharp Surface/font backend virtualization, XCB backend Bill Spitzak Build fix to find Xrender.h without xrender.pc Sasha Vasko Build fix to compile without xlib backend +Vladimir Vukicevic Bug fix for clipping Carl Worth Original library, support for paths, images Richard D. Worth Build fixes for cygwin diff --git a/ChangeLog b/ChangeLog index 2e98fe3d8..7ffc1dae2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2004-08-14 Carl Worth + * src/cairo_image_surface.c + (_cairo_image_surface_set_clip_region): Make a copy of the region + since pixman is currently taking ownership of it (ugh). Thanks to + Vladimir Vukicevic and Peter Dennis Bartok + . + * autogen.sh (LANG): Explicitly set LANG=C to fix the awk string->number conversion for user with locales that don't match ASCII digit conventions. diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index 84de8d97d..ec223945a 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -455,7 +455,20 @@ cairo_int_status_t _cairo_image_surface_set_clip_region (cairo_image_surface_t *surface, pixman_region16_t *region) { - pixman_image_set_clip_region (surface->pixman_image, region); + if (region) { + pixman_region16_t *rcopy; + + rcopy = pixman_region_create(); + /* pixman_image_set_clip_region expects to take ownership of the + * passed-in region, so we create a copy to give it. */ + /* XXX: I think that's probably a bug in pixman. But its + * memory management issues need auditing anyway, so a + * workaround like this is fine for now. */ + pixman_region_copy (rcopy, region); + pixman_image_set_clip_region (surface->pixman_image, rcopy); + } else { + pixman_image_set_clip_region (surface->pixman_image, region); + } return CAIRO_STATUS_SUCCESS; } diff --git a/src/cairo_image_surface.c b/src/cairo_image_surface.c index 84de8d97d..ec223945a 100644 --- a/src/cairo_image_surface.c +++ b/src/cairo_image_surface.c @@ -455,7 +455,20 @@ cairo_int_status_t _cairo_image_surface_set_clip_region (cairo_image_surface_t *surface, pixman_region16_t *region) { - pixman_image_set_clip_region (surface->pixman_image, region); + if (region) { + pixman_region16_t *rcopy; + + rcopy = pixman_region_create(); + /* pixman_image_set_clip_region expects to take ownership of the + * passed-in region, so we create a copy to give it. */ + /* XXX: I think that's probably a bug in pixman. But its + * memory management issues need auditing anyway, so a + * workaround like this is fine for now. */ + pixman_region_copy (rcopy, region); + pixman_image_set_clip_region (surface->pixman_image, rcopy); + } else { + pixman_image_set_clip_region (surface->pixman_image, region); + } return CAIRO_STATUS_SUCCESS; } -- cgit v1.2.1 From 0f3ce6a24010b9d1416f218c447b5c68a0df85ea Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Sat, 4 Sep 2004 06:38:34 +0000 Subject: Add the MPL as a new license option, in addition to the LGPL. --- COPYING | 519 ++-------------------------------------------- COPYING-LGPL-2.1 | 510 +++++++++++++++++++++++++++++++++++++++++++++ COPYING-MPL-1.1 | 470 +++++++++++++++++++++++++++++++++++++++++ ChangeLog | 8 + src/cairo-color.c | 37 +++- src/cairo-features.h.in | 41 ++-- src/cairo-fixed.c | 41 ++-- src/cairo-font.c | 37 +++- src/cairo-gstate.c | 37 +++- src/cairo-hull.c | 37 +++- src/cairo-image-surface.c | 37 +++- src/cairo-matrix.c | 37 +++- src/cairo-path-bounds.c | 37 +++- src/cairo-path-fill.c | 37 +++- src/cairo-path-stroke.c | 37 +++- src/cairo-path.c | 37 +++- src/cairo-pen.c | 37 +++- src/cairo-polygon.c | 37 +++- src/cairo-ps-surface.c | 37 +++- src/cairo-slope.c | 37 +++- src/cairo-spline.c | 37 +++- src/cairo-surface.c | 37 +++- src/cairo-xcb-surface.c | 37 +++- src/cairo-xlib-surface.c | 37 +++- src/cairo.c | 38 +++- src/cairo.h | 37 +++- src/cairo_color.c | 37 +++- src/cairo_fixed.c | 41 ++-- src/cairo_font.c | 37 +++- src/cairo_gstate.c | 37 +++- src/cairo_hull.c | 37 +++- src/cairo_image_surface.c | 37 +++- src/cairo_matrix.c | 37 +++- src/cairo_path.c | 37 +++- src/cairo_path_bounds.c | 37 +++- src/cairo_path_fill.c | 37 +++- src/cairo_path_stroke.c | 37 +++- src/cairo_pen.c | 37 +++- src/cairo_polygon.c | 37 +++- src/cairo_ps_surface.c | 37 +++- src/cairo_slope.c | 37 +++- src/cairo_spline.c | 37 +++- src/cairo_surface.c | 37 +++- src/cairo_xcb_surface.c | 37 +++- src/cairo_xlib_surface.c | 37 +++- src/cairoint.h | 37 +++- 46 files changed, 2142 insertions(+), 932 deletions(-) create mode 100644 COPYING-LGPL-2.1 create mode 100644 COPYING-MPL-1.1 diff --git a/COPYING b/COPYING index b124cf581..66cf5f2b3 100644 --- a/COPYING +++ b/COPYING @@ -1,510 +1,17 @@ +Cairo is free software. - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 +Every source file in the implementation of cairo is available to be +redistributed and/or modified under the terms of either the GNU Lesser +General Public License (LPGL) version 2.1 or the Mozilla Public +License (MPL) version 1.1. Some files are available under more +liberal terms, but we believe that in all cases, each file may be used +under either the LGPL or the MPL. - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations -below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it -becomes a de-facto standard. To achieve this, non-free programs must -be allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control -compilation and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at least - three years, to give the same user the materials specified in - Subsection 6a, above, for a charge no more than the cost of - performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply, and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License -may add an explicit geographical distribution limitation excluding those -countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms -of the ordinary General Public License). - - To apply these terms, attach the following notices to the library. -It is safest to attach them to the start of each source file to most -effectively convey the exclusion of warranty; and each file should -have at least the "copyright" line and a pointer to where the full -notice is found. - - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or -your school, if any, to sign a "copyright disclaimer" for the library, -if necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James - Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! +See the following files in this directory for the precise terms and +conditions of either license: + COPYING-LGPL-2.1 + COPYING-MPL-1.1 +Please see each file in the implementation for Copyright and licensing +information. diff --git a/COPYING-LGPL-2.1 b/COPYING-LGPL-2.1 new file mode 100644 index 000000000..b124cf581 --- /dev/null +++ b/COPYING-LGPL-2.1 @@ -0,0 +1,510 @@ + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations +below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes a de-facto standard. To achieve this, non-free programs must +be allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at least + three years, to give the same user the materials specified in + Subsection 6a, above, for a charge no more than the cost of + performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply, and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License +may add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should +have at least the "copyright" line and a pointer to where the full +notice is found. + + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the library, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James + Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/COPYING-MPL-1.1 b/COPYING-MPL-1.1 new file mode 100644 index 000000000..7714141d1 --- /dev/null +++ b/COPYING-MPL-1.1 @@ -0,0 +1,470 @@ + MOZILLA PUBLIC LICENSE + Version 1.1 + + --------------- + +1. Definitions. + + 1.0.1. "Commercial Use" means distribution or otherwise making the + Covered Code available to a third party. + + 1.1. "Contributor" means each entity that creates or contributes to + the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Code, prior Modifications used by a Contributor, and the Modifications + made by that particular Contributor. + + 1.3. "Covered Code" means the Original Code or Modifications or the + combination of the Original Code and Modifications, in each case + including portions thereof. + + 1.4. "Electronic Distribution Mechanism" means a mechanism generally + accepted in the software development community for the electronic + transfer of data. + + 1.5. "Executable" means Covered Code in any form other than Source + Code. + + 1.6. "Initial Developer" means the individual or entity identified + as the Initial Developer in the Source Code notice required by Exhibit + A. + + 1.7. "Larger Work" means a work which combines Covered Code or + portions thereof with code not governed by the terms of this License. + + 1.8. "License" means this document. + + 1.8.1. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means any addition to or deletion from the + substance or structure of either the Original Code or any previous + Modifications. When Covered Code is released as a series of files, a + Modification is: + A. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. + + B. Any new file that contains any part of the Original Code or + previous Modifications. + + 1.10. "Original Code" means Source Code of computer software code + which is described in the Source Code notice required by Exhibit A as + Original Code, and which, at the time of its release under this + License is not already Covered Code governed by this License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.11. "Source Code" means the preferred form of the Covered Code for + making modifications to it, including all modules it contains, plus + any associated interface definition files, scripts used to control + compilation and installation of an Executable, or source code + differential comparisons against either the Original Code or another + well known, available Covered Code of the Contributor's choice. The + Source Code can be in a compressed or archival form, provided the + appropriate decompression or de-archiving software is widely available + for no charge. + + 1.12. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, this + License or a future version of this License issued under Section 6.1. + For legal entities, "You" includes any entity which controls, is + controlled by, or is under common control with You. For purposes of + this definition, "control" means (a) the power, direct or indirect, + to cause the direction or management of such entity, whether by + contract or otherwise, or (b) ownership of more than fifty percent + (50%) of the outstanding shares or beneficial ownership of such + entity. + +2. Source Code License. + + 2.1. The Initial Developer Grant. + The Initial Developer hereby grants You a world-wide, royalty-free, + non-exclusive license, subject to third party intellectual property + claims: + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Code (or portions thereof) with or without Modifications, and/or + as part of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or + selling of Original Code, to make, have made, use, practice, + sell, and offer for sale, and/or otherwise dispose of the + Original Code (or portions thereof). + + (c) the licenses granted in this Section 2.1(a) and (b) are + effective on the date Initial Developer first distributes + Original Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: 1) for code that You delete from the Original Code; 2) + separate from the Original Code; or 3) for infringements caused + by: i) the modification of the Original Code or ii) the + combination of the Original Code with other software or devices. + + 2.2. Contributor Grant. + Subject to third party intellectual property claims, each Contributor + hereby grants You a world-wide, royalty-free, non-exclusive license + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor, to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof) either on an + unmodified basis, with other Modifications, as Covered Code + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either alone + and/or in combination with its Contributor Version (or portions + of such combination), to make, use, sell, offer for sale, have + made, and/or otherwise dispose of: 1) Modifications made by that + Contributor (or portions thereof); and 2) the combination of + Modifications made by that Contributor with its Contributor + Version (or portions of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use of + the Covered Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: 1) for any code that Contributor has deleted from the + Contributor Version; 2) separate from the Contributor Version; + 3) for infringements caused by: i) third party modifications of + Contributor Version or ii) the combination of Modifications made + by that Contributor with other software (except as part of the + Contributor Version) or other devices; or 4) under Patent Claims + infringed by Covered Code in the absence of Modifications made by + that Contributor. + +3. Distribution Obligations. + + 3.1. Application of License. + The Modifications which You create or to which You contribute are + governed by the terms of this License, including without limitation + Section 2.2. The Source Code version of Covered Code may be + distributed only under the terms of this License or a future version + of this License released under Section 6.1, and You must include a + copy of this License with every copy of the Source Code You + distribute. You may not offer or impose any terms on any Source Code + version that alters or restricts the applicable version of this + License or the recipients' rights hereunder. However, You may include + an additional document offering the additional rights described in + Section 3.5. + + 3.2. Availability of Source Code. + Any Modification which You create or to which You contribute must be + made available in Source Code form under the terms of this License + either on the same media as an Executable version or via an accepted + Electronic Distribution Mechanism to anyone to whom you made an + Executable version available; and if made available via Electronic + Distribution Mechanism, must remain available for at least twelve (12) + months after the date it initially became available, or at least six + (6) months after a subsequent version of that particular Modification + has been made available to such recipients. You are responsible for + ensuring that the Source Code version remains available even if the + Electronic Distribution Mechanism is maintained by a third party. + + 3.3. Description of Modifications. + You must cause all Covered Code to which You contribute to contain a + file documenting the changes You made to create that Covered Code and + the date of any change. You must include a prominent statement that + the Modification is derived, directly or indirectly, from Original + Code provided by the Initial Developer and including the name of the + Initial Developer in (a) the Source Code, and (b) in any notice in an + Executable version or related documentation in which You describe the + origin or ownership of the Covered Code. + + 3.4. Intellectual Property Matters + (a) Third Party Claims. + If Contributor has knowledge that a license under a third party's + intellectual property rights is required to exercise the rights + granted by such Contributor under Sections 2.1 or 2.2, + Contributor must include a text file with the Source Code + distribution titled "LEGAL" which describes the claim and the + party making the claim in sufficient detail that a recipient will + know whom to contact. If Contributor obtains such knowledge after + the Modification is made available as described in Section 3.2, + Contributor shall promptly modify the LEGAL file in all copies + Contributor makes available thereafter and shall take other steps + (such as notifying appropriate mailing lists or newsgroups) + reasonably calculated to inform those who received the Covered + Code that new knowledge has been obtained. + + (b) Contributor APIs. + If Contributor's Modifications include an application programming + interface and Contributor has knowledge of patent licenses which + are reasonably necessary to implement that API, Contributor must + also include this information in the LEGAL file. + + (c) Representations. + Contributor represents that, except as disclosed pursuant to + Section 3.4(a) above, Contributor believes that Contributor's + Modifications are Contributor's original creation(s) and/or + Contributor has sufficient rights to grant the rights conveyed by + this License. + + 3.5. Required Notices. + You must duplicate the notice in Exhibit A in each file of the Source + Code. If it is not possible to put such notice in a particular Source + Code file due to its structure, then You must include such notice in a + location (such as a relevant directory) where a user would be likely + to look for such a notice. If You created one or more Modification(s) + You may add your name as a Contributor to the notice described in + Exhibit A. You must also duplicate this License in any documentation + for the Source Code where You describe recipients' rights or ownership + rights relating to Covered Code. You may choose to offer, and to + charge a fee for, warranty, support, indemnity or liability + obligations to one or more recipients of Covered Code. However, You + may do so only on Your own behalf, and not on behalf of the Initial + Developer or any Contributor. You must make it absolutely clear than + any such warranty, support, indemnity or liability obligation is + offered by You alone, and You hereby agree to indemnify the Initial + Developer and every Contributor for any liability incurred by the + Initial Developer or such Contributor as a result of warranty, + support, indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. + You may distribute Covered Code in Executable form only if the + requirements of Section 3.1-3.5 have been met for that Covered Code, + and if You include a notice stating that the Source Code version of + the Covered Code is available under the terms of this License, + including a description of how and where You have fulfilled the + obligations of Section 3.2. The notice must be conspicuously included + in any notice in an Executable version, related documentation or + collateral in which You describe recipients' rights relating to the + Covered Code. You may distribute the Executable version of Covered + Code or ownership rights under a license of Your choice, which may + contain terms different from this License, provided that You are in + compliance with the terms of this License and that the license for the + Executable version does not attempt to limit or alter the recipient's + rights in the Source Code version from the rights set forth in this + License. If You distribute the Executable version under a different + license You must make it absolutely clear that any terms which differ + from this License are offered by You alone, not by the Initial + Developer or any Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred by + the Initial Developer or such Contributor as a result of any such + terms You offer. + + 3.7. Larger Works. + You may create a Larger Work by combining Covered Code with other code + not governed by the terms of this License and distribute the Larger + Work as a single product. In such a case, You must make sure the + requirements of this License are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. + + If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Code due to + statute, judicial order, or regulation then You must: (a) comply with + the terms of this License to the maximum extent possible; and (b) + describe the limitations and the code they affect. Such description + must be included in the LEGAL file described in Section 3.4 and must + be included with all distributions of the Source Code. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Application of this License. + + This License applies to code to which the Initial Developer has + attached the notice in Exhibit A and to related Covered Code. + +6. Versions of the License. + + 6.1. New Versions. + Netscape Communications Corporation ("Netscape") may publish revised + and/or new versions of the License from time to time. Each version + will be given a distinguishing version number. + + 6.2. Effect of New Versions. + Once Covered Code has been published under a particular version of the + License, You may always continue to use it under the terms of that + version. You may also choose to use such Covered Code under the terms + of any subsequent version of the License published by Netscape. No one + other than Netscape has the right to modify the terms applicable to + Covered Code created under this License. + + 6.3. Derivative Works. + If You create or use a modified version of this License (which you may + only do in order to apply it to code which is not already Covered Code + governed by this License), You must (a) rename Your license so that + the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", + "MPL", "NPL" or any confusingly similar phrase do not appear in your + license (except to note that your license differs from this License) + and (b) otherwise make it clear that Your version of the license + contains terms which differ from the Mozilla Public License and + Netscape Public License. (Filling in the name of the Initial + Developer, Original Code or Contributor in the notice described in + Exhibit A shall not of themselves be deemed to be modifications of + this License.) + +7. DISCLAIMER OF WARRANTY. + + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF + DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE + IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, + YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE + COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER + OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +8. TERMINATION. + + 8.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to cure + such breach within 30 days of becoming aware of the breach. All + sublicenses to the Covered Code which are properly granted shall + survive any termination of this License. Provisions which, by their + nature, must remain in effect beyond the termination of this License + shall survive. + + 8.2. If You initiate litigation by asserting a patent infringement + claim (excluding declatory judgment actions) against Initial Developer + or a Contributor (the Initial Developer or Contributor against whom + You file such action is referred to as "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License + shall, upon 60 days notice from Participant terminate prospectively, + unless if within 60 days after receipt of notice You either: (i) + agree in writing to pay Participant a mutually agreeable reasonable + royalty for Your past and future use of Modifications made by such + Participant, or (ii) withdraw Your litigation claim with respect to + the Contributor Version against such Participant. If within 60 days + of notice, a reasonable royalty and payment arrangement are not + mutually agreed upon in writing by the parties or the litigation claim + is not withdrawn, the rights granted by Participant to You under + Sections 2.1 and/or 2.2 automatically terminate at the expiration of + the 60 day notice period specified above. + + (b) any software, hardware, or device, other than such Participant's + Contributor Version, directly or indirectly infringes any patent, then + any rights granted to You by such Participant under Sections 2.1(b) + and 2.2(b) are revoked effective as of the date You first made, used, + sold, distributed, or had made, Modifications made by that + Participant. + + 8.3. If You assert a patent infringement claim against Participant + alleging that such Participant's Contributor Version directly or + indirectly infringes any patent where such claim is resolved (such as + by license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 above, + all end user license agreements (excluding distributors and resellers) + which have been validly granted by You or any distributor hereunder + prior to termination shall survive termination. + +9. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL + DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, + OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR + ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY + CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, + WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY + RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW + PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO + THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10. U.S. GOVERNMENT END USERS. + + The Covered Code is a "commercial item," as that term is defined in + 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" and "commercial computer software documentation," as such + terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 + C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), + all U.S. Government End Users acquire Covered Code with only those + rights set forth herein. + +11. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + California law provisions (except to the extent applicable law, if + any, provides otherwise), excluding its conflict-of-law provisions. + With respect to disputes in which at least one party is a citizen of, + or an entity chartered or registered to do business in the United + States of America, any litigation relating to this License shall be + subject to the jurisdiction of the Federal Courts of the Northern + District of California, with venue lying in Santa Clara County, + California, with the losing party responsible for costs, including + without limitation, court costs and reasonable attorneys' fees and + expenses. The application of the United Nations Convention on + Contracts for the International Sale of Goods is expressly excluded. + Any law or regulation which provides that the language of a contract + shall be construed against the drafter shall not apply to this + License. + +12. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +13. MULTIPLE-LICENSED CODE. + + Initial Developer may designate portions of the Covered Code as + "Multiple-Licensed". "Multiple-Licensed" means that the Initial + Developer permits you to utilize portions of the Covered Code under + Your choice of the NPL or the alternative licenses, if any, specified + by the Initial Developer in the file described in Exhibit A. + +EXHIBIT A -Mozilla Public License. + + ``The contents of this file are subject to the Mozilla Public License + Version 1.1 (the "License"); you may not use this file except in + compliance with the License. You may obtain a copy of the License at + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + License for the specific language governing rights and limitations + under the License. + + The Original Code is ______________________________________. + + The Initial Developer of the Original Code is ________________________. + Portions created by ______________________ are Copyright (C) ______ + _______________________. All Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the terms + of the _____ license (the "[___] License"), in which case the + provisions of [______] License are applicable instead of those + above. If you wish to allow use of your version of this file only + under the terms of the [____] License and not to allow others to use + your version of this file under the MPL, indicate your decision by + deleting the provisions above and replace them with the notice and + other provisions required by the [___] License. If you do not delete + the provisions above, a recipient may use your version of this file + under either the MPL or the [___] License." + + [NOTE: The text of this Exhibit A may differ slightly from the text of + the notices in the Source Code files of the Original Code. You should + use the text of this Exhibit A rather than the text found in the + Original Code Source Code for Your Modifications.] + diff --git a/ChangeLog b/ChangeLog index 7ffc1dae2..12ae7d137 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2004-09-04 Carl Worth + + * COPYING: + * COPYING-MPL-1.1: + + * COPYING-LGPL-2.1: Add the MPL as a new license option, in + addition to the LGPL. + 2004-08-14 Carl Worth * src/cairo_image_surface.c diff --git a/src/cairo-color.c b/src/cairo-color.c index a744aaf46..7dc733118 100644 --- a/src/cairo-color.c +++ b/src/cairo-color.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo-features.h.in b/src/cairo-features.h.in index 01557abea..b26ad0482 100644 --- a/src/cairo-features.h.in +++ b/src/cairo-features.h.in @@ -3,18 +3,35 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl Worth */ #ifndef _CAIRO_CONFIG_H_ diff --git a/src/cairo-fixed.c b/src/cairo-fixed.c index a9186ff48..9bafce360 100644 --- a/src/cairo-fixed.c +++ b/src/cairo-fixed.c @@ -3,18 +3,35 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo-font.c b/src/cairo-font.c index da73cc7fe..1b356698e 100644 --- a/src/cairo-font.c +++ b/src/cairo-font.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index aeebcb49c..c89d63769 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include diff --git a/src/cairo-hull.c b/src/cairo-hull.c index 2bc8fd4eb..be464f369 100644 --- a/src/cairo-hull.c +++ b/src/cairo-hull.c @@ -3,18 +3,35 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index ec223945a..e2ee69c57 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -3,18 +3,35 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c index 76567bcd4..540470e65 100644 --- a/src/cairo-matrix.c +++ b/src/cairo-matrix.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include diff --git a/src/cairo-path-bounds.c b/src/cairo-path-bounds.c index 09351219e..5f59cb5fc 100644 --- a/src/cairo-path-bounds.c +++ b/src/cairo-path-bounds.c @@ -3,18 +3,35 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo-path-fill.c b/src/cairo-path-fill.c index f130951cd..ca5e098ca 100644 --- a/src/cairo-path-fill.c +++ b/src/cairo-path-fill.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c index 8baf01b88..477cf99e0 100644 --- a/src/cairo-path-stroke.c +++ b/src/cairo-path-stroke.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo-path.c b/src/cairo-path.c index 3d41ab7f9..21715bf35 100644 --- a/src/cairo-path.c +++ b/src/cairo-path.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include diff --git a/src/cairo-pen.c b/src/cairo-pen.c index 2df58d271..a6ebc5e04 100644 --- a/src/cairo-pen.c +++ b/src/cairo-pen.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo-polygon.c b/src/cairo-polygon.c index 2f1681c90..8fc1f3097 100644 --- a/src/cairo-polygon.c +++ b/src/cairo-polygon.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c index 264867d95..4296d0d49 100644 --- a/src/cairo-ps-surface.c +++ b/src/cairo-ps-surface.c @@ -3,18 +3,35 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo-slope.c b/src/cairo-slope.c index a79d7787e..484cd86fd 100644 --- a/src/cairo-slope.c +++ b/src/cairo-slope.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo-spline.c b/src/cairo-spline.c index 56bb5b885..f3c21726d 100644 --- a/src/cairo-spline.c +++ b/src/cairo-spline.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 422bad633..e5cf7aa9d 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c index a59d5308d..8389c96d5 100644 --- a/src/cairo-xcb-surface.c +++ b/src/cairo-xcb-surface.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index 46afd2d15..8513ae4ef 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo.c b/src/cairo.c index 708901de1..bd3ea90f8 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -3,20 +3,38 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ + #include "cairoint.h" #define CAIRO_TOLERANCE_MINIMUM 0.0002 /* We're limited by 16 bits of sub-pixel precision */ diff --git a/src/cairo.h b/src/cairo.h index f034ba845..328b53cd6 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #ifndef _CAIRO_H_ diff --git a/src/cairo_color.c b/src/cairo_color.c index a744aaf46..7dc733118 100644 --- a/src/cairo_color.c +++ b/src/cairo_color.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo_fixed.c b/src/cairo_fixed.c index a9186ff48..9bafce360 100644 --- a/src/cairo_fixed.c +++ b/src/cairo_fixed.c @@ -3,18 +3,35 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo_font.c b/src/cairo_font.c index da73cc7fe..1b356698e 100644 --- a/src/cairo_font.c +++ b/src/cairo_font.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo_gstate.c b/src/cairo_gstate.c index aeebcb49c..c89d63769 100644 --- a/src/cairo_gstate.c +++ b/src/cairo_gstate.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include diff --git a/src/cairo_hull.c b/src/cairo_hull.c index 2bc8fd4eb..be464f369 100644 --- a/src/cairo_hull.c +++ b/src/cairo_hull.c @@ -3,18 +3,35 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo_image_surface.c b/src/cairo_image_surface.c index ec223945a..e2ee69c57 100644 --- a/src/cairo_image_surface.c +++ b/src/cairo_image_surface.c @@ -3,18 +3,35 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo_matrix.c b/src/cairo_matrix.c index 76567bcd4..540470e65 100644 --- a/src/cairo_matrix.c +++ b/src/cairo_matrix.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include diff --git a/src/cairo_path.c b/src/cairo_path.c index 3d41ab7f9..21715bf35 100644 --- a/src/cairo_path.c +++ b/src/cairo_path.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include diff --git a/src/cairo_path_bounds.c b/src/cairo_path_bounds.c index 09351219e..5f59cb5fc 100644 --- a/src/cairo_path_bounds.c +++ b/src/cairo_path_bounds.c @@ -3,18 +3,35 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo_path_fill.c b/src/cairo_path_fill.c index f130951cd..ca5e098ca 100644 --- a/src/cairo_path_fill.c +++ b/src/cairo_path_fill.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo_path_stroke.c b/src/cairo_path_stroke.c index 8baf01b88..477cf99e0 100644 --- a/src/cairo_path_stroke.c +++ b/src/cairo_path_stroke.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo_pen.c b/src/cairo_pen.c index 2df58d271..a6ebc5e04 100644 --- a/src/cairo_pen.c +++ b/src/cairo_pen.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo_polygon.c b/src/cairo_polygon.c index 2f1681c90..8fc1f3097 100644 --- a/src/cairo_polygon.c +++ b/src/cairo_polygon.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include diff --git a/src/cairo_ps_surface.c b/src/cairo_ps_surface.c index 264867d95..4296d0d49 100644 --- a/src/cairo_ps_surface.c +++ b/src/cairo_ps_surface.c @@ -3,18 +3,35 @@ * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo_slope.c b/src/cairo_slope.c index a79d7787e..484cd86fd 100644 --- a/src/cairo_slope.c +++ b/src/cairo_slope.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo_spline.c b/src/cairo_spline.c index 56bb5b885..f3c21726d 100644 --- a/src/cairo_spline.c +++ b/src/cairo_spline.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo_surface.c b/src/cairo_surface.c index 422bad633..e5cf7aa9d 100644 --- a/src/cairo_surface.c +++ b/src/cairo_surface.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include diff --git a/src/cairo_xcb_surface.c b/src/cairo_xcb_surface.c index a59d5308d..8389c96d5 100644 --- a/src/cairo_xcb_surface.c +++ b/src/cairo_xcb_surface.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairo_xlib_surface.c b/src/cairo_xlib_surface.c index 46afd2d15..8513ae4ef 100644 --- a/src/cairo_xlib_surface.c +++ b/src/cairo_xlib_surface.c @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ #include "cairoint.h" diff --git a/src/cairoint.h b/src/cairoint.h index c8c10a65f..6242a3fc5 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -3,18 +3,35 @@ * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * Author: Carl D. Worth + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth */ /* -- cgit v1.2.1 From 211cf9a2ce2f15402062ebc87f82a2b45b0cfde2 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Sat, 4 Sep 2004 07:29:16 +0000 Subject: Add the MPL as a new license option, in addition to the LGPL. --- ChangeLog | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 12ae7d137..27e435a51 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,9 +2,31 @@ * COPYING: * COPYING-MPL-1.1: - - * COPYING-LGPL-2.1: Add the MPL as a new license option, in - addition to the LGPL. + * COPYING-LGPL-2.1: + * src/cairo-features.h.in: + * src/cairo.c: + * src/cairo.h: + * src/cairo_color.c: + * src/cairo_fixed.c: + * src/cairo_font.c: + * src/cairo_gstate.c: + * src/cairo_hull.c: + * src/cairo_image_surface.c: + * src/cairo_matrix.c: + * src/cairo_path.c: + * src/cairo_path_bounds.c: + * src/cairo_path_fill.c: + * src/cairo_path_stroke.c: + * src/cairo_pen.c: + * src/cairo_polygon.c: + * src/cairo_ps_surface.c: + * src/cairo_slope.c: + * src/cairo_spline.c: + * src/cairo_surface.c: + * src/cairo_xcb_surface.c: + * src/cairo_xlib_surface.c: + * src/cairoint.h: Add the MPL as a new license option, in addition + to the LGPL. 2004-08-14 Carl Worth -- cgit v1.2.1 From 27d2de8c2d0ebdabf80321bf59d7e680093b4e33 Mon Sep 17 00:00:00 2001 From: David Reveman Date: Sat, 11 Sep 2004 04:23:17 +0000 Subject: Replaced the gl backend with the new glitz backend --- ChangeLog | 18 + cairo.pc.in | 2 +- configure.in | 36 +- src/Makefile.am | 10 +- src/cairo-features.h.in | 2 +- src/cairo-glitz-surface.c | 907 +++++++++++++++++++++++++++++++++++++++++++ src/cairo.h | 14 +- src/cairo_gl_surface.c | 967 ---------------------------------------------- src/cairo_glitz_surface.c | 907 +++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 1864 insertions(+), 999 deletions(-) create mode 100644 src/cairo-glitz-surface.c delete mode 100644 src/cairo_gl_surface.c create mode 100644 src/cairo_glitz_surface.c diff --git a/ChangeLog b/ChangeLog index 27e435a51..e09f60604 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2004-09-11 David Reveman + + * src/cairo.h: CAIRO_HAS_GL_SURFACE -> CAIRO_HAS_GLITZ_SURFACE. + cairo_set_target_gl -> cairo_set_target_glitz. + cairo_gl_surface_create -> cairo_glitz_surface_create. + + * src/cairo-features.h.in: GL_SURFACE_FEATURE -> GLITZ_SURFACE_FEATURE. + + * src/Makefile.am: CAIRO_HAS_GL_SURFACE -> CAIRO_HAS_GLITZ_SURFACE, + libcairo_gl_sources -> libcairo_glitz_sources, cairo_gl_surface.c -> + cairo_glitz_surface.c, GL_CFLAGS -> GLITZ_CFLAGS and + GL_LIBS -> GLITZ_LIBS. + + * cairo.pc.in (Requires): GL_REQUIRES -> GLITZ_REQUIRES. + + * configure.in: Replaced the gl backend with the new glitz backend. + Cairo now requires version 0.2.1 of glitz. + 2004-09-04 Carl Worth * COPYING: diff --git a/cairo.pc.in b/cairo.pc.in index c67dc05cb..b2859b24b 100644 --- a/cairo.pc.in +++ b/cairo.pc.in @@ -7,7 +7,7 @@ Name: cairo Description: Multi-platform 2D graphics library Version: @VERSION@ -Requires: fontconfig libpixman @XRENDER_REQUIRES@ @PNG_REQUIRES@ @GL_REQUIRES@ +Requires: fontconfig libpixman @XRENDER_REQUIRES@ @PNG_REQUIRES@ @GLITZ_REQUIRES@ Libs: -L${libdir} -lcairo -lm @XRENDER_LIBS@ @PS_LIBS@ @FREETYPE_LIBS@ Cflags: -I${includedir} @FREETYPE_CFLAGS@ diff --git a/configure.in b/configure.in index 5ab37391a..a682d47ec 100644 --- a/configure.in +++ b/configure.in @@ -136,28 +136,28 @@ AC_SUBST(PNG_REQUIRES) dnl =========================================================================== -AC_ARG_ENABLE(gl, - [ --disable-gl Disable cairo's OpenGL backend], - [use_gl=$enableval], [use_gl=yes]) - -if test "x$use_gl" = "xyes"; then - PKG_CHECK_MODULES(GL, glitz >= 0.1.5, [ - GL_REQUIRES=glitz - use_gl=yes], [use_gl="no (requires glitz http://freedesktop.org/software/glitz)"]) +AC_ARG_ENABLE(glitz, + [ --disable-glitz Disable cairo's glitz backend], + [use_glitz=$enableval], [use_glitz=yes]) + +if test "x$use_glitz" = "xyes"; then + PKG_CHECK_MODULES(GLITZ, glitz >= 0.2.1, [ + GLITZ_REQUIRES=glitz + use_glitz=yes], [use_glitz="no (requires glitz http://freedesktop.org/software/glitz)"]) fi -if test "x$use_gl" != "xyes"; then - GL_SURFACE_FEATURE=CAIRO_HAS_NO_GL_SURFACE - AM_CONDITIONAL(CAIRO_HAS_GL_SURFACE, false) +if test "x$use_glitz" != "xyes"; then + GLITZ_SURFACE_FEATURE=CAIRO_HAS_NO_GLITZ_SURFACE + AM_CONDITIONAL(CAIRO_HAS_GLITZ_SURFACE, false) else - GL_SURFACE_FEATURE=CAIRO_HAS_GL_SURFACE - AM_CONDITIONAL(CAIRO_HAS_GL_SURFACE, true) + GLITZ_SURFACE_FEATURE=CAIRO_HAS_GLITZ_SURFACE + AM_CONDITIONAL(CAIRO_HAS_GLITZ_SURFACE, true) fi -AC_SUBST(GL_LIBS) -AC_SUBST(GL_CFLAGS) -AC_SUBST(GL_SURFACE_FEATURE) -AC_SUBST(GL_REQUIRES) +AC_SUBST(GLITZ_LIBS) +AC_SUBST(GLITZ_CFLAGS) +AC_SUBST(GLITZ_SURFACE_FEATURE) +AC_SUBST(GLITZ_REQUIRES) dnl =========================================================================== @@ -258,6 +258,6 @@ echo " Xlib: $use_xlib" echo " XCB: $use_xcb" echo " PostScript: $use_ps" echo " PNG: $use_png" -echo " OpenGL: $use_gl" +echo " glitz: $use_glitz" echo "" diff --git a/src/Makefile.am b/src/Makefile.am index 38a30adef..5dfa079e5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,8 +17,8 @@ if CAIRO_HAS_XCB_SURFACE libcairo_xcb_sources = cairo_xcb_surface.c endif -if CAIRO_HAS_GL_SURFACE -libcairo_gl_sources = cairo_gl_surface.c +if CAIRO_HAS_GLITZ_SURFACE +libcairo_glitz_sources = cairo_glitz_surface.c endif # These names match automake style variable definition conventions so @@ -56,11 +56,11 @@ libcairo_la_SOURCES = \ $(libcairo_png_sources) \ $(libcairo_xlib_sources)\ $(libcairo_xcb_sources) \ - $(libcairo_gl_sources) \ + $(libcairo_glitz_sources)\ cairoint.h libcairo_la_LDFLAGS = -version-info @VERSION_INFO@ -no-undefined -INCLUDES = -I$(srcdir) $(WARN_CFLAGS) $(CAIRO_CFLAGS) $(FONTCONFIG_CFLAGS) $(XRENDER_CFLAGS) $(XCB_CFLAGS) $(PNG_CFLAGS) $(GL_CFLAGS) +INCLUDES = -I$(srcdir) $(WARN_CFLAGS) $(CAIRO_CFLAGS) $(FONTCONFIG_CFLAGS) $(XRENDER_CFLAGS) $(XCB_CFLAGS) $(PNG_CFLAGS) $(GLITZ_CFLAGS) -libcairo_la_LIBADD = $(CAIRO_LIBS) $(FONTCONFIG_LIBS) $(XRENDER_LIBS) $(XCB_LIBS) $(PS_LIBS) $(PNG_LIBS) $(GL_LIBS) -lm +libcairo_la_LIBADD = $(CAIRO_LIBS) $(FONTCONFIG_LIBS) $(XRENDER_LIBS) $(XCB_LIBS) $(PS_LIBS) $(PNG_LIBS) $(GLITZ_LIBS) -lm diff --git a/src/cairo-features.h.in b/src/cairo-features.h.in index b26ad0482..632ad8d72 100644 --- a/src/cairo-features.h.in +++ b/src/cairo-features.h.in @@ -45,7 +45,7 @@ #define @XCB_SURFACE_FEATURE@ -#define @GL_SURFACE_FEATURE@ +#define @GLITZ_SURFACE_FEATURE@ #define @SANITY_CHECKING_FEATURE@ diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c new file mode 100644 index 000000000..83269dc12 --- /dev/null +++ b/src/cairo-glitz-surface.c @@ -0,0 +1,907 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2004 David Reveman + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of David + * Reveman not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. David Reveman makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: David Reveman + */ + +#include "cairoint.h" + +#define GLITZ_FIXED_TO_FLOAT(f) \ + (((glitz_float_t) (f)) / 65536) + +#define GLITZ_FIXED_LINE_X_TO_FLOAT(line, v) \ + (((glitz_float_t) \ + ((line).p1.x + (cairo_fixed_16_16_t) \ + (((cairo_fixed_32_32_t) ((v) - (line).p1.y) * \ + ((line).p2.x - (line).p1.x)) / \ + ((line).p2.y - (line).p1.y)))) / 65536) + +#define GLITZ_FIXED_LINE_X_CEIL_TO_FLOAT(line, v) \ + (((glitz_float_t) \ + ((line).p1.x + (cairo_fixed_16_16_t) \ + (((((line).p2.y - (line).p1.y) - 1) + \ + ((cairo_fixed_32_32_t) ((v) - (line).p1.y) * \ + ((line).p2.x - (line).p1.x))) / \ + ((line).p2.y - (line).p1.y)))) / 65536) + +void +cairo_set_target_glitz (cairo_t *cr, glitz_surface_t *surface) +{ + cairo_surface_t *crsurface; + + if (cr->status && cr->status != CAIRO_STATUS_NO_TARGET_SURFACE) + return; + + glitz_surface_reference (surface); + + crsurface = cairo_glitz_surface_create (surface); + if (crsurface == NULL) { + cr->status = CAIRO_STATUS_NO_MEMORY; + return; + } + + cairo_set_target_surface (cr, crsurface); + + cairo_surface_destroy (crsurface); +} + +typedef struct cairo_glitz_surface { + cairo_surface_t base; + + unsigned long features; + glitz_surface_t *surface; + glitz_format_t *format; + + cairo_pattern_t pattern; + cairo_box_t pattern_box; +} cairo_glitz_surface_t; + +static void +_cairo_glitz_surface_destroy (void *abstract_surface) +{ + cairo_glitz_surface_t *surface = abstract_surface; + + glitz_surface_destroy (surface->surface); + + _cairo_pattern_fini (&surface->pattern); + + free (surface); +} + +static double +_cairo_glitz_surface_pixels_per_inch (void *abstract_surface) +{ + return 96.0; +} + +static cairo_image_surface_t * +_cairo_glitz_surface_get_image (void *abstract_surface) +{ + cairo_glitz_surface_t *surface = abstract_surface; + cairo_image_surface_t *image; + char *pixels; + int width, height, rowstride, size; + cairo_format_masks_t format; + glitz_buffer_t *buffer; + glitz_pixel_format_t pf; + + if (surface->pattern.type != CAIRO_PATTERN_SURFACE) { + cairo_box_t box; + + box.p1.x = box.p1.y = 0; + box.p2.x = surface->pattern_box.p2.x; + box.p2.y = surface->pattern_box.p2.y; + + return _cairo_pattern_get_image (&surface->pattern, &box); + } + + + width = glitz_surface_get_width (surface->surface); + height = glitz_surface_get_height (surface->surface); + + if (surface->format->red_size > 0) { + format.bpp = 32; + + if (surface->format->alpha_size > 0) + format.alpha_mask = 0xff000000; + else + format.alpha_mask = 0x0; + + format.red_mask = 0xff0000; + format.green_mask = 0xff00; + format.blue_mask = 0xff; + } else { + format.bpp = 8; + format.blue_mask = format.green_mask = format.red_mask = 0x0; + format.alpha_mask = 0xff; + } + + rowstride = (((width * format.bpp) / 8) + 3) & -4; + + pf.masks.bpp = format.bpp; + pf.masks.alpha_mask = format.alpha_mask; + pf.masks.red_mask = format.red_mask; + pf.masks.green_mask = format.green_mask; + pf.masks.blue_mask = format.blue_mask; + pf.xoffset = 0; + pf.skip_lines = 0; + pf.bytes_per_line = rowstride; + pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; + size = height * rowstride; + + pixels = malloc (size); + if (!pixels) + return NULL; + + buffer = glitz_pixel_buffer_create (surface->surface, NULL, size, + GLITZ_BUFFER_HINT_DYNAMIC_READ); + if (!buffer) { + free (pixels); + return NULL; + } + + glitz_get_pixels (surface->surface, + 0, 0, + width, height, + &pf, + buffer); + + glitz_buffer_get_data (buffer, 0, size, pixels); + + glitz_buffer_destroy (buffer); + + image = (cairo_image_surface_t *) + _cairo_image_surface_create_with_masks (pixels, + &format, + width, height, + rowstride); + + _cairo_image_surface_assume_ownership_of_data (image); + + _cairo_image_surface_set_repeat (image, surface->base.repeat); + _cairo_image_surface_set_matrix (image, &(surface->base.matrix)); + + return image; +} + +static cairo_status_t +_cairo_glitz_surface_set_image (void *abstract_surface, + cairo_image_surface_t *image) +{ + cairo_glitz_surface_t *surface = abstract_surface; + glitz_buffer_t *buffer; + glitz_pixel_format_t pf; + + if (image->depth > 8) { + pf.masks.bpp = 32; + + if (surface->format->alpha_size) + pf.masks.alpha_mask = 0xff000000; + else + pf.masks.alpha_mask = 0x0; + + pf.masks.red_mask = 0xff0000; + pf.masks.green_mask = 0xff00; + pf.masks.blue_mask = 0xff; + } else { + pf.masks.bpp = 8; + pf.masks.alpha_mask = 0xff; + pf.masks.red_mask = pf.masks.green_mask = pf.masks.blue_mask = 0x0; + } + + pf.xoffset = 0; + pf.skip_lines = 0; + pf.bytes_per_line = (((image->width * pf.masks.bpp) / 8) + 3) & -4; + pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; + + buffer = glitz_pixel_buffer_create (surface->surface, + image->data, + pf.bytes_per_line * image->height, + GLITZ_BUFFER_HINT_STREAM_DRAW); + if (!buffer) + return CAIRO_STATUS_NO_MEMORY; + + glitz_set_pixels (surface->surface, + 0, 0, + image->width, image->height, + &pf, + buffer); + + glitz_buffer_destroy (buffer); + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_cairo_glitz_surface_set_matrix (void *abstract_surface, + cairo_matrix_t *matrix) +{ + cairo_glitz_surface_t *surface = abstract_surface; + glitz_transform_t transform; + + transform.matrix[0][0] = _cairo_fixed_from_double (matrix->m[0][0]); + transform.matrix[0][1] = _cairo_fixed_from_double (matrix->m[1][0]); + transform.matrix[0][2] = _cairo_fixed_from_double (matrix->m[2][0]); + + transform.matrix[1][0] = _cairo_fixed_from_double (matrix->m[0][1]); + transform.matrix[1][1] = _cairo_fixed_from_double (matrix->m[1][1]); + transform.matrix[1][2] = _cairo_fixed_from_double (matrix->m[2][1]); + + transform.matrix[2][0] = 0; + transform.matrix[2][1] = 0; + transform.matrix[2][2] = 1 << 16; + + glitz_surface_set_transform (surface->surface, &transform); + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_cairo_glitz_surface_set_filter (void *abstract_surface, cairo_filter_t filter) +{ + cairo_glitz_surface_t *surface = abstract_surface; + glitz_filter_t glitz_filter; + + switch (filter) { + case CAIRO_FILTER_FAST: + case CAIRO_FILTER_NEAREST: + glitz_filter = GLITZ_FILTER_NEAREST; + break; + case CAIRO_FILTER_GOOD: + case CAIRO_FILTER_BEST: + case CAIRO_FILTER_BILINEAR: + default: + glitz_filter = GLITZ_FILTER_BILINEAR; + break; + } + + glitz_surface_set_filter (surface->surface, glitz_filter, NULL, 0); + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_cairo_glitz_surface_set_repeat (void *abstract_surface, int repeat) +{ + cairo_glitz_surface_t *surface = abstract_surface; + + glitz_surface_set_fill (surface->surface, + (repeat)? GLITZ_FILL_REPEAT: + GLITZ_FILL_TRANSPARENT); + + return CAIRO_STATUS_SUCCESS; +} + +static glitz_operator_t +_glitz_operator (cairo_operator_t op) +{ + switch (op) { + case CAIRO_OPERATOR_CLEAR: + return GLITZ_OPERATOR_CLEAR; + case CAIRO_OPERATOR_SRC: + return GLITZ_OPERATOR_SRC; + case CAIRO_OPERATOR_DST: + return GLITZ_OPERATOR_DST; + case CAIRO_OPERATOR_OVER_REVERSE: + return GLITZ_OPERATOR_OVER_REVERSE; + case CAIRO_OPERATOR_IN: + return GLITZ_OPERATOR_IN; + case CAIRO_OPERATOR_IN_REVERSE: + return GLITZ_OPERATOR_IN_REVERSE; + case CAIRO_OPERATOR_OUT: + return GLITZ_OPERATOR_OUT; + case CAIRO_OPERATOR_OUT_REVERSE: + return GLITZ_OPERATOR_OUT_REVERSE; + case CAIRO_OPERATOR_ATOP: + return GLITZ_OPERATOR_ATOP; + case CAIRO_OPERATOR_ATOP_REVERSE: + return GLITZ_OPERATOR_ATOP_REVERSE; + case CAIRO_OPERATOR_XOR: + return GLITZ_OPERATOR_XOR; + case CAIRO_OPERATOR_ADD: + return GLITZ_OPERATOR_ADD; + case CAIRO_OPERATOR_SATURATE: + return GLITZ_OPERATOR_SATURATE; + case CAIRO_OPERATOR_OVER: + default: + return GLITZ_OPERATOR_OVER; + } +} + +static glitz_format_name_t +_glitz_format (cairo_format_t format) +{ + switch (format) { + case CAIRO_FORMAT_A1: + return GLITZ_STANDARD_A1; + case CAIRO_FORMAT_A8: + return GLITZ_STANDARD_A8; + case CAIRO_FORMAT_RGB24: + return GLITZ_STANDARD_RGB24; + case CAIRO_FORMAT_ARGB32: + default: + return GLITZ_STANDARD_ARGB32; + } +} + +static glitz_surface_t * +_glitz_surface_create_solid (glitz_surface_t *other, + glitz_format_name_t format_name, + glitz_color_t *color) +{ + glitz_surface_t *surface; + glitz_format_t *format; + + format = glitz_surface_find_similar_standard_format (other, format_name); + if (format == NULL) + return NULL; + + surface = glitz_surface_create_similar (other, format, 1, 1); + if (surface == NULL) + return NULL; + + glitz_set_rectangle (surface, color, 0, 0, 1, 1); + + glitz_surface_set_fill (surface, GLITZ_FILL_REPEAT); + + return surface; +} + +static cairo_surface_t * +_cairo_glitz_surface_create_similar (void *abstract_src, + cairo_format_t format, + int drawable, + int width, + int height) +{ + cairo_glitz_surface_t *src = abstract_src; + glitz_surface_t *surface; + cairo_surface_t *crsurface; + glitz_format_t *glitz_format; + + glitz_format = + glitz_surface_find_similar_standard_format (src->surface, + _glitz_format (format)); + if (glitz_format == NULL) + return NULL; + + surface = glitz_surface_create_similar (src->surface, glitz_format, + width, height); + if (surface == NULL) + return NULL; + + crsurface = cairo_glitz_surface_create (surface); + if (crsurface == NULL) + glitz_surface_destroy (surface); + + return crsurface; +} + +static cairo_glitz_surface_t * +_cairo_glitz_surface_clone_similar (cairo_glitz_surface_t *templ, + cairo_surface_t *src, + cairo_format_t format) +{ + cairo_glitz_surface_t *clone; + cairo_image_surface_t *src_image; + + src_image = _cairo_surface_get_image (src); + + clone = (cairo_glitz_surface_t *) + _cairo_glitz_surface_create_similar (templ, format, 0, + src_image->width, + src_image->height); + if (clone == NULL) + return NULL; + + _cairo_glitz_surface_set_filter (clone, cairo_surface_get_filter (src)); + + _cairo_glitz_surface_set_image (clone, src_image); + + _cairo_glitz_surface_set_matrix (clone, &(src_image->base.matrix)); + + cairo_surface_destroy (&src_image->base); + + return clone; +} + +static cairo_int_status_t +_glitz_composite (glitz_operator_t op, + glitz_surface_t *src, + glitz_surface_t *mask, + glitz_surface_t *dst, + int src_x, + int src_y, + int mask_x, + int mask_y, + int dst_x, + int dst_y, + int width, + int height, + glitz_buffer_t *geometry, + glitz_geometry_format_t *format) +{ + if (glitz_surface_get_status (dst)) + return CAIRO_STATUS_NO_TARGET_SURFACE; + + glitz_set_geometry (dst, + 0, 0, + format, geometry); + + glitz_composite (op, + src, + mask, + dst, + src_x, src_y, + mask_x, mask_y, + dst_x, dst_y, + width, height); + + glitz_set_geometry (dst, 0, 0, NULL, NULL); + + if (glitz_surface_get_status (dst) == GLITZ_STATUS_NOT_SUPPORTED) + return CAIRO_INT_STATUS_UNSUPPORTED; + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_int_status_t +_cairo_glitz_surface_composite (cairo_operator_t op, + cairo_surface_t *generic_src, + cairo_surface_t *generic_mask, + void *abstract_dst, + int src_x, + int src_y, + int mask_x, + int mask_y, + int dst_x, + int dst_y, + unsigned int width, + unsigned int height) +{ + cairo_glitz_surface_t *dst = abstract_dst; + cairo_glitz_surface_t *src = (cairo_glitz_surface_t *) generic_src; + cairo_glitz_surface_t *mask = (cairo_glitz_surface_t *) generic_mask; + cairo_glitz_surface_t *src_clone = NULL; + cairo_glitz_surface_t *mask_clone = NULL; + cairo_int_status_t status; + + if (generic_src->backend != dst->base.backend) { + src_clone = _cairo_glitz_surface_clone_similar (dst, generic_src, + CAIRO_FORMAT_ARGB32); + if (!src_clone) + return CAIRO_INT_STATUS_UNSUPPORTED; + + src = src_clone; + } + + if (generic_mask && (generic_mask->backend != dst->base.backend)) { + mask_clone = _cairo_glitz_surface_clone_similar (dst, generic_mask, + CAIRO_FORMAT_ARGB32); + if (!mask_clone) + return CAIRO_INT_STATUS_UNSUPPORTED; + + mask = mask_clone; + } + + status = _glitz_composite (_glitz_operator (op), + src->surface, + (mask)? mask->surface: NULL, + dst->surface, + src_x, src_y, + mask_x, mask_y, + dst_x, dst_y, + width, height, + NULL, NULL); + + if (src_clone) + cairo_surface_destroy (&src_clone->base); + + if (mask_clone) + cairo_surface_destroy (&mask_clone->base); + + return status; +} + +static cairo_int_status_t +_cairo_glitz_surface_fill_rectangles (void *abstract_dst, + cairo_operator_t op, + const cairo_color_t *color, + cairo_rectangle_t *rects, + int n_rects) +{ + cairo_glitz_surface_t *dst = abstract_dst; + glitz_color_t glitz_color; + + glitz_color.red = color->red_short; + glitz_color.green = color->green_short; + glitz_color.blue = color->blue_short; + glitz_color.alpha = color->alpha_short; + + if (op != CAIRO_OPERATOR_SRC) { + glitz_surface_t *solid; + glitz_float_t *data; + glitz_buffer_t *buffer; + glitz_geometry_format_t gf; + cairo_int_status_t status; + int width = 0; + int height = 0; + + gf.mode = GLITZ_GEOMETRY_MODE_DIRECT; + gf.edge_hint = GLITZ_GEOMETRY_EDGE_HINT_SHARP; + gf.primitive = GLITZ_GEOMETRY_PRIMITIVE_QUADS; + gf.type = GLITZ_DATA_TYPE_FLOAT; + gf.first = 0; + gf.count = n_rects * 4; + + buffer = + glitz_geometry_buffer_create (dst->surface, NULL, + n_rects * 8 * sizeof (glitz_float_t), + GLITZ_BUFFER_HINT_STREAM_DRAW); + if (buffer == NULL) + return CAIRO_STATUS_NO_MEMORY; + + data = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); + for (; n_rects; rects++, n_rects--) { + *data++ = (glitz_float_t) rects->x; + *data++ = (glitz_float_t) rects->y; + *data++ = (glitz_float_t) (rects->x + rects->width); + *data++ = (glitz_float_t) rects->y; + *data++ = (glitz_float_t) (rects->x + rects->width); + *data++ = (glitz_float_t) (rects->y + rects->height); + *data++ = (glitz_float_t) rects->x; + *data++ = (glitz_float_t) (rects->y + rects->height); + + if ((rects->x + rects->width) > width) + width = rects->x + rects->width; + + if ((rects->y + rects->height) > height) + height = rects->y + rects->height; + } + glitz_buffer_unmap (buffer); + + solid = _glitz_surface_create_solid (dst->surface, + GLITZ_STANDARD_ARGB32, + &glitz_color); + if (solid == NULL) + return CAIRO_STATUS_NO_MEMORY; + + status = _glitz_composite (_glitz_operator (op), + solid, + NULL, + dst->surface, + 0, 0, + 0, 0, + 0, 0, + width, height, + buffer, &gf); + + glitz_surface_destroy (solid); + glitz_buffer_destroy (buffer); + + return status; + } else + glitz_set_rectangles (dst->surface, &glitz_color, + (glitz_rectangle_t *) rects, n_rects); + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_int_status_t +_cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, + cairo_surface_t *generic_src, + void *abstract_dst, + int x_src, + int y_src, + cairo_trapezoid_t *traps, + int n_traps) +{ + cairo_glitz_surface_t *dst = abstract_dst; + cairo_glitz_surface_t *src = (cairo_glitz_surface_t *) generic_src; + glitz_surface_t *mask = NULL; + glitz_float_t *data; + glitz_buffer_t *buffer; + glitz_geometry_format_t gf; + cairo_int_status_t status; + int x_dst, y_dst, x_rel, y_rel, width, height; + + if (generic_src->backend != dst->base.backend) + return CAIRO_INT_STATUS_UNSUPPORTED; + + gf.mode = GLITZ_GEOMETRY_MODE_DIRECT; + gf.edge_hint = GLITZ_GEOMETRY_EDGE_HINT_GOOD_SMOOTH; + gf.primitive = GLITZ_GEOMETRY_PRIMITIVE_QUADS; + gf.type = GLITZ_DATA_TYPE_FLOAT; + gf.first = 0; + gf.count = n_traps * 4; + + buffer = + glitz_geometry_buffer_create (dst->surface, NULL, + n_traps * 8 * sizeof (glitz_float_t), + GLITZ_BUFFER_HINT_STREAM_DRAW); + if (buffer == NULL) + return CAIRO_STATUS_NO_MEMORY; + + x_dst = traps[0].left.p1.x >> 16; + y_dst = traps[0].left.p1.y >> 16; + + data = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); + for (; n_traps; traps++, n_traps--) { + glitz_float_t top, bottom; + + top = GLITZ_FIXED_TO_FLOAT (traps->top); + bottom = GLITZ_FIXED_TO_FLOAT (traps->bottom); + + *data++ = GLITZ_FIXED_LINE_X_TO_FLOAT (traps->left, traps->top); + *data++ = top; + *data++ = GLITZ_FIXED_LINE_X_CEIL_TO_FLOAT (traps->right, traps->top); + *data++ = top; + *data++ = + GLITZ_FIXED_LINE_X_CEIL_TO_FLOAT (traps->right, traps->bottom); + *data++ = bottom; + *data++ = GLITZ_FIXED_LINE_X_TO_FLOAT (traps->left, traps->bottom); + *data++ = bottom; + } + glitz_buffer_unmap (buffer); + + if ((src->pattern.type == CAIRO_PATTERN_SURFACE) && + (src->pattern.color.alpha != 1.0)) { + glitz_color_t color; + + color.red = color.green = color.blue = 0; + color.alpha = src->pattern.color.alpha_short; + + mask = _glitz_surface_create_solid (dst->surface, + GLITZ_STANDARD_A8, + &color); + } + + x_rel = (src->pattern_box.p1.x >> 16) + x_src - x_dst; + y_rel = (src->pattern_box.p1.y >> 16) + y_src - y_dst; + + x_dst = src->pattern_box.p1.x >> 16; + y_dst = src->pattern_box.p1.y >> 16; + + width = ((src->pattern_box.p2.x + 65535) >> 16) - + (src->pattern_box.p1.x >> 16); + height = ((src->pattern_box.p2.y + 65535) >> 16) - + (src->pattern_box.p1.y >> 16); + + status = _glitz_composite (_glitz_operator (op), + src->surface, + mask, + dst->surface, + x_rel, y_rel, + 0, 0, + x_dst, y_dst, + width, height, + buffer, &gf); + + if (mask) + glitz_surface_destroy (mask); + + glitz_buffer_destroy (buffer); + + return status; +} + +static cairo_int_status_t +_cairo_glitz_surface_copy_page (void *abstract_surface) +{ + return CAIRO_INT_STATUS_UNSUPPORTED; +} + +static cairo_int_status_t +_cairo_glitz_surface_show_page (void *abstract_surface) +{ + return CAIRO_INT_STATUS_UNSUPPORTED; +} + +static cairo_int_status_t +_cairo_glitz_surface_create_pattern (void *abstract_dst, + cairo_pattern_t *pattern, + cairo_box_t *box) +{ + cairo_glitz_surface_t *dst = abstract_dst; + cairo_surface_t *generic_src = NULL; + cairo_image_surface_t *image = NULL; + cairo_glitz_surface_t *src; + + switch (pattern->type) { + case CAIRO_PATTERN_SOLID: + generic_src = + _cairo_surface_create_similar_solid (&dst->base, + CAIRO_FORMAT_ARGB32, + 1, 1, + &pattern->color); + if (generic_src) + cairo_surface_set_repeat (generic_src, 1); + break; + case CAIRO_PATTERN_RADIAL: + /* glitz doesn't support inner and outer circle with different + center points. */ + if (pattern->u.radial.center0.x != pattern->u.radial.center1.x || + pattern->u.radial.center0.y != pattern->u.radial.center1.y) + break; + /* fall-through */ + case CAIRO_PATTERN_LINEAR: { + glitz_fixed16_16_t *params; + int i, n_params; + + if (!(dst->features & GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK)) + break; + + if (pattern->filter != CAIRO_FILTER_BILINEAR) + break; + + n_params = pattern->n_stops * 3 + 4; + + params = malloc (sizeof (glitz_fixed16_16_t) * n_params); + if (params == NULL) + return CAIRO_STATUS_NO_MEMORY; + + generic_src = + _cairo_glitz_surface_create_similar (abstract_dst, + CAIRO_FORMAT_ARGB32, 0, + pattern->n_stops, 1); + if (generic_src == NULL) { + free (params); + return CAIRO_STATUS_NO_MEMORY; + } + + src = (cairo_glitz_surface_t *) generic_src; + + for (i = 0; i < pattern->n_stops; i++) { + glitz_color_t color; + + color.red = pattern->stops[i].color_char[0] * 256; + color.green = pattern->stops[i].color_char[1] * 256; + color.blue = pattern->stops[i].color_char[2] * 256; + color.alpha = pattern->stops[i].color_char[3] * 256; + + glitz_set_rectangle (src->surface, &color, i, 0, 1, 1); + + params[4 + 3 * i] = pattern->stops[i].offset; + params[5 + 3 * i] = 0x8000 | (i << 16); + params[6 + 3 * i] = 0x8000; + } + + if (pattern->type == CAIRO_PATTERN_LINEAR) { + params[0] = _cairo_fixed_from_double (pattern->u.linear.point0.x); + params[1] = _cairo_fixed_from_double (pattern->u.linear.point0.y); + params[2] = _cairo_fixed_from_double (pattern->u.linear.point1.x); + params[3] = _cairo_fixed_from_double (pattern->u.linear.point1.y); + + glitz_surface_set_filter (src->surface, + GLITZ_FILTER_LINEAR_GRADIENT, + params, n_params); + } else { + params[0] = _cairo_fixed_from_double (pattern->u.radial.center0.x); + params[1] = _cairo_fixed_from_double (pattern->u.radial.center0.y); + params[2] = _cairo_fixed_from_double (pattern->u.radial.radius0); + params[3] = _cairo_fixed_from_double (pattern->u.radial.radius1); + + glitz_surface_set_filter (src->surface, + GLITZ_FILTER_RADIAL_GRADIENT, + params, n_params); + } + + switch (pattern->extend) { + case CAIRO_EXTEND_REPEAT: + glitz_surface_set_fill (src->surface, GLITZ_FILL_REPEAT); + break; + case CAIRO_EXTEND_REFLECT: + glitz_surface_set_fill (src->surface, GLITZ_FILL_REFLECT); + break; + case CAIRO_EXTEND_NONE: + default: + glitz_surface_set_fill (src->surface, GLITZ_FILL_NEAREST); + break; + } + + cairo_surface_set_matrix (&src->base, &pattern->matrix); + + free (params); + } break; + case CAIRO_PATTERN_SURFACE: + generic_src = pattern->u.surface.surface; + cairo_surface_reference (generic_src); + break; + } + + if (generic_src == NULL) { + image = _cairo_pattern_get_image (pattern, box); + if (image == NULL) + return CAIRO_STATUS_NO_MEMORY; + + generic_src = &image->base; + } + + if (generic_src->backend != dst->base.backend) { + src = _cairo_glitz_surface_clone_similar (dst, generic_src, + CAIRO_FORMAT_ARGB32); + if (src == NULL) + return CAIRO_STATUS_NO_MEMORY; + } else + src = (cairo_glitz_surface_t *) generic_src; + + if (image) + cairo_surface_destroy (&image->base); + + _cairo_pattern_init_copy (&src->pattern, pattern); + src->pattern_box = *box; + + pattern->source = &src->base; + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_int_status_t +_cairo_glitz_surface_set_clip_region (void *abstract_surface, + pixman_region16_t *region) +{ + return CAIRO_INT_STATUS_UNSUPPORTED; +} + +static const struct cairo_surface_backend cairo_glitz_surface_backend = { + _cairo_glitz_surface_create_similar, + _cairo_glitz_surface_destroy, + _cairo_glitz_surface_pixels_per_inch, + _cairo_glitz_surface_get_image, + _cairo_glitz_surface_set_image, + _cairo_glitz_surface_set_matrix, + _cairo_glitz_surface_set_filter, + _cairo_glitz_surface_set_repeat, + _cairo_glitz_surface_composite, + _cairo_glitz_surface_fill_rectangles, + _cairo_glitz_surface_composite_trapezoids, + _cairo_glitz_surface_copy_page, + _cairo_glitz_surface_show_page, + _cairo_glitz_surface_set_clip_region, + _cairo_glitz_surface_create_pattern +}; + +cairo_surface_t * +cairo_glitz_surface_create (glitz_surface_t *surface) +{ + cairo_glitz_surface_t *crsurface; + + if (!surface) + return NULL; + + crsurface = malloc (sizeof (cairo_glitz_surface_t)); + if (crsurface == NULL) + return NULL; + + _cairo_surface_init (&crsurface->base, &cairo_glitz_surface_backend); + + crsurface->surface = surface; + crsurface->features = glitz_surface_get_features (surface); + crsurface->format = glitz_surface_get_format (surface); + + _cairo_pattern_init (&crsurface->pattern); + crsurface->pattern.type = CAIRO_PATTERN_SURFACE; + crsurface->pattern.u.surface.surface = NULL; + + return (cairo_surface_t *) crsurface; +} diff --git a/src/cairo.h b/src/cairo.h index 328b53cd6..44b631633 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -150,14 +150,14 @@ cairo_set_target_xcb (cairo_t *cr, cairo_format_t format); #endif /* CAIRO_HAS_XCB_SURFACE */ -#ifdef CAIRO_HAS_GL_SURFACE +#ifdef CAIRO_HAS_GLITZ_SURFACE #include void -cairo_set_target_gl (cairo_t *cr, - glitz_surface_t *surface); -#endif /* CAIRO_HAS_GL_SURFACE */ +cairo_set_target_glitz (cairo_t *cr, + glitz_surface_t *surface); +#endif /* CAIRO_HAS_GLITZ_SURFACE */ typedef enum cairo_operator { CAIRO_OPERATOR_CLEAR, @@ -784,12 +784,12 @@ cairo_xlib_surface_set_size (cairo_surface_t *surface, int width, int height); #endif /* CAIRO_HAS_XLIB_SURFACE */ -#ifdef CAIRO_HAS_GL_SURFACE +#ifdef CAIRO_HAS_GLITZ_SURFACE cairo_surface_t * -cairo_gl_surface_create (glitz_surface_t *surface); +cairo_glitz_surface_create (glitz_surface_t *surface); -#endif /* CAIRO_HAS_GL_SURFACE */ +#endif /* CAIRO_HAS_GLITZ_SURFACE */ /* Matrix functions */ diff --git a/src/cairo_gl_surface.c b/src/cairo_gl_surface.c deleted file mode 100644 index b56fc5fc3..000000000 --- a/src/cairo_gl_surface.c +++ /dev/null @@ -1,967 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2004 David Reveman - * - * Permission to use, copy, modify, distribute, and sell this software - * and its documentation for any purpose is hereby granted without - * fee, provided that the above copyright notice appear in all copies - * and that both that copyright notice and this permission notice - * appear in supporting documentation, and that the name of David - * Reveman not be used in advertising or publicity pertaining to - * distribution of the software without specific, written prior - * permission. David Reveman makes no representations about the - * suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, - * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR - * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Author: David Reveman - */ - -#include "cairoint.h" - -static cairo_surface_t * -_cairo_gl_surface_create (glitz_surface_t *surface, - int owns_surface); - -void -cairo_set_target_gl (cairo_t *cr, glitz_surface_t *surface) -{ - cairo_surface_t *crsurface; - - if (cr->status && cr->status != CAIRO_STATUS_NO_TARGET_SURFACE) - return; - - if (glitz_surface_get_hints (surface) & GLITZ_HINT_PROGRAMMATIC_MASK) { - cr->status = CAIRO_STATUS_NO_TARGET_SURFACE; - return; - } - - crsurface = _cairo_gl_surface_create (surface, 0); - if (crsurface == NULL) { - cr->status = CAIRO_STATUS_NO_MEMORY; - return; - } - - cairo_set_target_surface (cr, crsurface); - - cairo_surface_destroy (crsurface); -} - -typedef struct cairo_gl_surface cairo_gl_surface_t; - -struct cairo_gl_surface { - cairo_surface_t base; - - glitz_format_t *format; - long int features; - long int hints; - int owns_surface; - unsigned short opacity; - - cairo_pattern_t pattern; - cairo_box_t pattern_box; - - glitz_surface_t *surface; -}; - -#define CAIRO_GL_MULTITEXTURE_SUPPORT(surface) \ - (surface->features & GLITZ_FEATURE_ARB_MULTITEXTURE_MASK) - -#define CAIRO_GL_OFFSCREEN_SUPPORT(surface) \ - (surface->features & GLITZ_FEATURE_OFFSCREEN_DRAWING_MASK) - -#define CAIRO_GL_CONVOLUTION_SUPPORT(surface) \ - (surface->features & GLITZ_FEATURE_CONVOLUTION_FILTER_MASK) - -#define CAIRO_GL_FRAGMENT_PROGRAM_SUPPORT(surface) \ - (surface->features & GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK) - -#define CAIRO_GL_TEXTURE_NPOT_SUPPORT(surface) \ - (surface->features & GLITZ_FEATURE_TEXTURE_NPOT_MASK) - -#define CAIRO_GL_TEXTURE_MIRRORED_REPEAT_SUPPORT(surface) \ - (surface->features & GLITZ_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK) - -#define CAIRO_GL_COMPOSITE_TRAPEZOIDS_SUPPORT(surface) \ - (surface->format->stencil_size >= \ - ((surface->hints & GLITZ_HINT_CLIPPING_MASK)? 2: 1)) - -#define CAIRO_GL_SURFACE_IS_DRAWABLE(surface) \ - ((surface->hints & GLITZ_HINT_OFFSCREEN_MASK)? \ - surface->format->draw.offscreen: surface->format->draw.onscreen) - -#define CAIRO_GL_SURFACE_IS_SOLID(surface) \ - ((surface->hints & GLITZ_HINT_PROGRAMMATIC_MASK) && \ - (surface->pattern.type == CAIRO_PATTERN_SOLID)) - -#define CAIRO_GL_SURFACE_MULTISAMPLE(surface) \ - (surface->hints & GLITZ_HINT_MULTISAMPLE_MASK) - -static void -_cairo_gl_surface_destroy (void *abstract_surface) -{ - cairo_gl_surface_t *surface = abstract_surface; - - if (surface->owns_surface && surface->surface) - glitz_surface_destroy (surface->surface); - - _cairo_pattern_fini (&surface->pattern); - - free (surface); -} - -static double -_cairo_gl_surface_pixels_per_inch (void *abstract_surface) -{ - return 96.0; -} - -static cairo_image_surface_t * -_cairo_gl_surface_get_image (void *abstract_surface) -{ - cairo_gl_surface_t *surface = abstract_surface; - cairo_image_surface_t *image; - char *pixels; - int width, height; - int rowstride; - cairo_format_masks_t format; - glitz_pixel_buffer_t *buffer; - glitz_pixel_format_t pf; - - if (surface->hints & GLITZ_HINT_PROGRAMMATIC_MASK) - return _cairo_pattern_get_image (&surface->pattern, - &surface->pattern_box); - - width = glitz_surface_get_width (surface->surface); - height = glitz_surface_get_height (surface->surface); - - if (surface->format->red_size > 0) { - format.bpp = 32; - - if (surface->format->alpha_size > 0) - format.alpha_mask = 0xff000000; - else - format.alpha_mask = 0x0; - - format.red_mask = 0xff0000; - format.green_mask = 0xff00; - format.blue_mask = 0xff; - } else { - format.bpp = 8; - format.blue_mask = format.green_mask = format.red_mask = 0x0; - format.alpha_mask = 0xff; - } - - rowstride = (((width * format.bpp) / 8) + 3) & -4; - - pf.masks.bpp = format.bpp; - pf.masks.alpha_mask = format.alpha_mask; - pf.masks.red_mask = format.red_mask; - pf.masks.green_mask = format.green_mask; - pf.masks.blue_mask = format.blue_mask; - pf.xoffset = 0; - pf.skip_lines = 0; - pf.bytes_per_line = rowstride; - pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; - - pixels = (char *) malloc (height * rowstride); - if (!pixels) - return NULL; - - buffer = glitz_pixel_buffer_create_for_data (pixels, &pf); - if (!buffer) { - free (pixels); - return NULL; - } - - glitz_get_pixels (surface->surface, - 0, 0, - width, height, - buffer); - - glitz_pixel_buffer_destroy (buffer); - - image = (cairo_image_surface_t *) - _cairo_image_surface_create_with_masks (pixels, - &format, - width, height, rowstride); - - _cairo_image_surface_assume_ownership_of_data (image); - - _cairo_image_surface_set_repeat (image, surface->base.repeat); - _cairo_image_surface_set_matrix (image, &(surface->base.matrix)); - - return image; -} - -static cairo_status_t -_cairo_gl_surface_set_image (void *abstract_surface, - cairo_image_surface_t *image) -{ - cairo_gl_surface_t *surface = abstract_surface; - glitz_pixel_buffer_t *buffer; - glitz_pixel_format_t pf; - - if (image->depth > 8) { - pf.masks.bpp = 32; - - if (surface->format->alpha_size) - pf.masks.alpha_mask = 0xff000000; - else - pf.masks.alpha_mask = 0x0; - - pf.masks.red_mask = 0xff0000; - pf.masks.green_mask = 0xff00; - pf.masks.blue_mask = 0xff; - } else { - pf.masks.bpp = 8; - pf.masks.alpha_mask = 0xff; - pf.masks.red_mask = pf.masks.green_mask = pf.masks.blue_mask = 0x0; - } - - pf.xoffset = 0; - pf.skip_lines = 0; - pf.bytes_per_line = (((image->width * pf.masks.bpp) / 8) + 3) & -4; - pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; - - buffer = glitz_pixel_buffer_create_for_data (image->data, &pf); - if (!buffer) - return CAIRO_STATUS_NO_MEMORY; - - glitz_put_pixels (surface->surface, - 0, 0, - image->width, image->height, - buffer); - - glitz_pixel_buffer_destroy (buffer); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_gl_surface_set_matrix (void *abstract_surface, cairo_matrix_t *matrix) -{ - cairo_gl_surface_t *surface = abstract_surface; - glitz_transform_t transform; - - if (!surface->surface) - return CAIRO_STATUS_SUCCESS; - - transform.matrix[0][0] = _cairo_fixed_from_double (matrix->m[0][0]); - transform.matrix[0][1] = _cairo_fixed_from_double (matrix->m[1][0]); - transform.matrix[0][2] = _cairo_fixed_from_double (matrix->m[2][0]); - - transform.matrix[1][0] = _cairo_fixed_from_double (matrix->m[0][1]); - transform.matrix[1][1] = _cairo_fixed_from_double (matrix->m[1][1]); - transform.matrix[1][2] = _cairo_fixed_from_double (matrix->m[2][1]); - - transform.matrix[2][0] = 0; - transform.matrix[2][1] = 0; - transform.matrix[2][2] = _cairo_fixed_from_double (1); - - glitz_surface_set_transform (surface->surface, &transform); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_gl_surface_set_filter (void *abstract_surface, cairo_filter_t filter) -{ - cairo_gl_surface_t *surface = abstract_surface; - glitz_filter_t gl_filter; - - if (!surface->surface) - return CAIRO_STATUS_SUCCESS; - - switch (filter) { - case CAIRO_FILTER_FAST: - gl_filter = GLITZ_FILTER_FAST; - break; - case CAIRO_FILTER_GOOD: - gl_filter = GLITZ_FILTER_GOOD; - break; - case CAIRO_FILTER_BEST: - gl_filter = GLITZ_FILTER_BEST; - break; - case CAIRO_FILTER_NEAREST: - gl_filter = GLITZ_FILTER_NEAREST; - break; - case CAIRO_FILTER_BILINEAR: - gl_filter = GLITZ_FILTER_BILINEAR; - break; - default: - gl_filter = GLITZ_FILTER_BEST; - } - - glitz_surface_set_filter (surface->surface, gl_filter); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_gl_surface_set_repeat (void *abstract_surface, int repeat) -{ - cairo_gl_surface_t *surface = abstract_surface; - - if (!surface->surface) - return CAIRO_STATUS_SUCCESS; - - glitz_surface_set_repeat (surface->surface, repeat); - - return CAIRO_STATUS_SUCCESS; -} - -static glitz_operator_t -_glitz_operator (cairo_operator_t operator) -{ - switch (operator) { - case CAIRO_OPERATOR_CLEAR: - return GLITZ_OPERATOR_CLEAR; - case CAIRO_OPERATOR_SRC: - return GLITZ_OPERATOR_SRC; - case CAIRO_OPERATOR_DST: - return GLITZ_OPERATOR_DST; - case CAIRO_OPERATOR_OVER: - return GLITZ_OPERATOR_OVER; - case CAIRO_OPERATOR_OVER_REVERSE: - return GLITZ_OPERATOR_OVER_REVERSE; - case CAIRO_OPERATOR_IN: - return GLITZ_OPERATOR_IN; - case CAIRO_OPERATOR_IN_REVERSE: - return GLITZ_OPERATOR_IN_REVERSE; - case CAIRO_OPERATOR_OUT: - return GLITZ_OPERATOR_OUT; - case CAIRO_OPERATOR_OUT_REVERSE: - return GLITZ_OPERATOR_OUT_REVERSE; - case CAIRO_OPERATOR_ATOP: - return GLITZ_OPERATOR_ATOP; - case CAIRO_OPERATOR_ATOP_REVERSE: - return GLITZ_OPERATOR_ATOP_REVERSE; - case CAIRO_OPERATOR_XOR: - return GLITZ_OPERATOR_XOR; - case CAIRO_OPERATOR_ADD: - return GLITZ_OPERATOR_ADD; - case CAIRO_OPERATOR_SATURATE: - return GLITZ_OPERATOR_SATURATE; - default: - return GLITZ_OPERATOR_OVER; - } -} - -static glitz_format_name_t -_glitz_format (cairo_format_t format) -{ - switch (format) { - case CAIRO_FORMAT_A1: - return GLITZ_STANDARD_A1; - break; - case CAIRO_FORMAT_A8: - return GLITZ_STANDARD_A8; - break; - case CAIRO_FORMAT_RGB24: - return GLITZ_STANDARD_RGB24; - break; - case CAIRO_FORMAT_ARGB32: - default: - return GLITZ_STANDARD_ARGB32; - break; - } -} - -static cairo_surface_t * -_cairo_gl_surface_create_similar (void *abstract_src, - cairo_format_t format, - int drawable, - int width, - int height) -{ - cairo_gl_surface_t *src = abstract_src; - glitz_surface_t *surface; - cairo_surface_t *crsurface; - glitz_format_t *glitz_format; - unsigned long option_mask; - glitz_format_name_t format_name = _glitz_format (format); - - option_mask = GLITZ_FORMAT_OPTION_OFFSCREEN_MASK; - - if (drawable) - option_mask |= GLITZ_FORMAT_OPTION_READDRAW_MASK; - else - option_mask |= GLITZ_FORMAT_OPTION_READONLY_MASK; - - if (src->format->multisample.samples < 2) - option_mask |= GLITZ_FORMAT_OPTION_NO_MULTISAMPLE_MASK; - - glitz_format = - glitz_surface_find_similar_standard_format (src->surface, option_mask, - format_name); - if (glitz_format == NULL) { - option_mask &= ~GLITZ_FORMAT_OPTION_READDRAW_MASK; - glitz_format = - glitz_surface_find_similar_standard_format (src->surface, - option_mask, - format_name); - } - - if (glitz_format == NULL) - return NULL; - - surface = glitz_surface_create_similar (src->surface, glitz_format, - width, height); - if (surface == NULL) - return NULL; - - crsurface = _cairo_gl_surface_create (surface, 1); - if (crsurface == NULL) - glitz_surface_destroy (surface); - - return crsurface; -} - -static cairo_gl_surface_t * -_cairo_gl_surface_clone_similar (cairo_surface_t *src, - cairo_gl_surface_t *template, - cairo_format_t format) -{ - cairo_gl_surface_t *clone; - cairo_image_surface_t *src_image; - - src_image = _cairo_surface_get_image (src); - - clone = (cairo_gl_surface_t *) - _cairo_gl_surface_create_similar (template, format, 0, - src_image->width, - src_image->height); - if (clone == NULL) - return NULL; - - _cairo_gl_surface_set_filter (clone, cairo_surface_get_filter (src)); - - _cairo_gl_surface_set_image (clone, src_image); - - _cairo_gl_surface_set_matrix (clone, &(src_image->base.matrix)); - - cairo_surface_destroy (&src_image->base); - - return clone; -} - -static cairo_int_status_t -_cairo_gl_surface_composite (cairo_operator_t operator, - cairo_surface_t *generic_src, - cairo_surface_t *generic_mask, - void *abstract_dst, - int src_x, - int src_y, - int mask_x, - int mask_y, - int dst_x, - int dst_y, - unsigned int width, - unsigned int height) -{ - cairo_gl_surface_t *dst = abstract_dst; - cairo_gl_surface_t *src = (cairo_gl_surface_t *) generic_src; - cairo_gl_surface_t *mask = (cairo_gl_surface_t *) generic_mask; - cairo_gl_surface_t *src_clone = NULL; - cairo_gl_surface_t *mask_clone = NULL; - - /* Make sure that target surface is OK. */ - if (glitz_surface_get_status (dst->surface)) - return CAIRO_STATUS_NO_TARGET_SURFACE; - - /* Make sure target surface is drawable */ - if (!CAIRO_GL_SURFACE_IS_DRAWABLE (dst)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* We need multi-texturing or offscreen drawing when compositing with - non-solid mask. */ - if (mask && - (!CAIRO_GL_SURFACE_IS_SOLID (mask)) && - (!CAIRO_GL_MULTITEXTURE_SUPPORT (dst)) && - (!CAIRO_GL_OFFSCREEN_SUPPORT (dst))) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (generic_src->backend != dst->base.backend) { - src_clone = _cairo_gl_surface_clone_similar (generic_src, dst, - CAIRO_FORMAT_ARGB32); - if (!src_clone) - return CAIRO_INT_STATUS_UNSUPPORTED; - src = src_clone; - } - if (generic_mask && (generic_mask->backend != dst->base.backend)) { - mask_clone = _cairo_gl_surface_clone_similar (generic_mask, dst, - CAIRO_FORMAT_A8); - if (!mask_clone) - return CAIRO_INT_STATUS_UNSUPPORTED; - mask = mask_clone; - } - - glitz_composite (_glitz_operator (operator), - src->surface, - mask ? mask->surface : 0, - dst->surface, - src_x, src_y, - mask_x, mask_y, - dst_x, dst_y, - width, height); - - if (src_clone) - cairo_surface_destroy (&src_clone->base); - if (mask_clone) - cairo_surface_destroy (&mask_clone->base); - - if (glitz_surface_get_status (dst->surface) == GLITZ_STATUS_NOT_SUPPORTED) - return CAIRO_INT_STATUS_UNSUPPORTED; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_gl_surface_fill_rectangles (void *abstract_surface, - cairo_operator_t operator, - const cairo_color_t *color, - cairo_rectangle_t *rects, - int num_rects) -{ - cairo_gl_surface_t *surface = abstract_surface; - glitz_color_t glitz_color; - - /* Make sure that target surface is OK. */ - if (glitz_surface_get_status (surface->surface)) - return CAIRO_STATUS_NO_TARGET_SURFACE; - - /* Make sure target surface is drawable */ - if (!CAIRO_GL_SURFACE_IS_DRAWABLE (surface)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - glitz_color.red = color->red_short; - glitz_color.green = color->green_short; - glitz_color.blue = color->blue_short; - glitz_color.alpha = color->alpha_short; - - glitz_fill_rectangles (_glitz_operator (operator), - surface->surface, - &glitz_color, (glitz_rectangle_t *) rects, - num_rects); - - return CAIRO_STATUS_SUCCESS; -} - -/* This function will produce incorrect drawing if alpha is not 1.0. */ -static cairo_int_status_t -_cairo_gl_surface_fill_trapezoids (cairo_gl_surface_t *surface, - cairo_operator_t operator, - const cairo_color_t *color, - cairo_trapezoid_t *traps, - int num_traps) -{ - glitz_color_t glitz_color; - - glitz_color.red = color->red_short; - glitz_color.green = color->green_short; - glitz_color.blue = color->blue_short; - glitz_color.alpha = color->alpha_short; - - glitz_fill_trapezoids (_glitz_operator (operator), - surface->surface, - &glitz_color, - (glitz_trapezoid_t *) traps, num_traps); - - return CAIRO_STATUS_SUCCESS; -} - -static int -_cairo_gl_extract_rectangle (cairo_trapezoid_t *trap, - cairo_rectangle_t *rect) -{ - if (trap->left.p1.x == trap->left.p2.x && - trap->right.p1.x == trap->right.p2.x && - trap->left.p1.y == trap->right.p1.y && - trap->left.p2.y == trap->right.p2.y && - _cairo_fixed_is_integer (trap->left.p1.x) && - _cairo_fixed_is_integer (trap->left.p1.y) && - _cairo_fixed_is_integer (trap->left.p2.x) && - _cairo_fixed_is_integer (trap->left.p2.y) && - _cairo_fixed_is_integer (trap->right.p1.x) && - _cairo_fixed_is_integer (trap->right.p1.y) && - _cairo_fixed_is_integer (trap->right.p2.x) && - _cairo_fixed_is_integer (trap->right.p2.y)) { - - rect->x = _cairo_fixed_integer_part (trap->left.p1.x); - rect->y = _cairo_fixed_integer_part (trap->left.p1.y); - rect->width = _cairo_fixed_integer_part (trap->right.p1.x) - rect->x; - rect->height = _cairo_fixed_integer_part (trap->left.p2.y) - rect->y; - - return 1; - } - - return 0; -} - -static cairo_int_status_t -_cairo_gl_surface_composite_trapezoids (cairo_operator_t operator, - cairo_surface_t *generic_src, - void *abstract_dst, - int x_src, - int y_src, - cairo_trapezoid_t *traps, - int num_traps) -{ - cairo_gl_surface_t *dst = abstract_dst; - cairo_gl_surface_t *src = (cairo_gl_surface_t *) generic_src; - cairo_gl_surface_t *src_clone = NULL; - - /* Make sure that target surface is OK. */ - if (glitz_surface_get_status (dst->surface)) - return CAIRO_STATUS_NO_TARGET_SURFACE; - - /* Make sure target surface is drawable */ - if (!CAIRO_GL_SURFACE_IS_DRAWABLE (dst)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Need to get current hints as clipping may have changed. */ - dst->hints = glitz_surface_get_hints (dst->surface); - - /* Solid source? */ - if ((generic_src->backend == dst->base.backend) && - (src->pattern.type == CAIRO_PATTERN_SOLID)) { - cairo_rectangle_t rect; - - /* Check to see if we can represent these traps as a rectangle. */ - if (num_traps == 1 && _cairo_gl_extract_rectangle (traps, &rect)) - return _cairo_gl_surface_fill_rectangles (dst, operator, - &src->pattern.color, - &rect, 1); - - /* If we're not using software multi-sampling, then we can use - fill trapezoids if only one trapezoid should be drawn or if - solid color alpha is 1.0. */ - if ((!CAIRO_GL_SURFACE_MULTISAMPLE (dst)) && - (num_traps == 1 || src->pattern.color.alpha == 1.0)) - return _cairo_gl_surface_fill_trapezoids (dst, operator, - &src->pattern.color, - traps, num_traps); - } - - if (generic_src->backend != dst->base.backend) { - src_clone = _cairo_gl_surface_clone_similar (generic_src, dst, - CAIRO_FORMAT_ARGB32); - if (!src_clone) - return CAIRO_INT_STATUS_UNSUPPORTED; - src = src_clone; - } - - glitz_surface_set_polyopacity (dst->surface, src->opacity); - - glitz_composite_trapezoids (_glitz_operator (operator), - src->surface, dst->surface, - x_src, y_src, (glitz_trapezoid_t *) traps, - num_traps); - - glitz_surface_set_polyopacity (dst->surface, 0xffff); - - if (src_clone) - cairo_surface_destroy (&src_clone->base); - - if (glitz_surface_get_status (dst->surface) == GLITZ_STATUS_NOT_SUPPORTED) - return CAIRO_INT_STATUS_UNSUPPORTED; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_gl_surface_copy_page (void *abstract_surface) -{ - return CAIRO_INT_STATUS_UNSUPPORTED; -} - -static cairo_int_status_t -_cairo_gl_surface_show_page (void *abstract_surface) -{ - return CAIRO_INT_STATUS_UNSUPPORTED; -} - -static void -_cairo_gl_create_color_range (cairo_pattern_t *pattern, - unsigned char *data, - unsigned int size) -{ - unsigned int i, bytes = size * 4; - cairo_shader_op_t op; - - _cairo_pattern_shader_init (pattern, &op); - - for (i = 0; i < bytes; i += 4) - _cairo_pattern_calc_color_at_pixel (&op, - ((double) i / bytes) * 65536, - (int *) &data[i]); -} - -static cairo_int_status_t -_cairo_gl_surface_create_pattern (void *abstract_surface, - cairo_pattern_t *pattern, - cairo_box_t *box) -{ - cairo_gl_surface_t *surface = abstract_surface; - glitz_surface_t *source = NULL; - cairo_gl_surface_t *src; - - switch (pattern->type) { - case CAIRO_PATTERN_SOLID: { - glitz_color_t color; - - color.red = pattern->color.red_short; - color.green = pattern->color.green_short; - color.blue = pattern->color.blue_short; - color.alpha = pattern->color.alpha_short; - - source = glitz_surface_create_solid (&color); - } break; - case CAIRO_PATTERN_RADIAL: - /* glitz doesn't support inner circle yet. */ - if (pattern->u.radial.center0.x != pattern->u.radial.center1.x || - pattern->u.radial.center0.y != pattern->u.radial.center1.y) - return CAIRO_INT_STATUS_UNSUPPORTED; - /* fall-through */ - case CAIRO_PATTERN_LINEAR: { - int color_range_size; - glitz_color_range_t *color_range; - int width = ((box->p2.x + 65535) >> 16) - (box->p1.x >> 16); - int height = ((box->p2.y + 65535) >> 16) - (box->p1.y >> 16); - - if (!CAIRO_GL_FRAGMENT_PROGRAM_SUPPORT (surface)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* reflect could be emulated for hardware that doesn't support mirrored - repeat of textures, but I don't know of any card that support - fragment programs but not mirrored repeat, so what's the use. */ - if (pattern->extend == CAIRO_EXTEND_REFLECT && - (!CAIRO_GL_TEXTURE_MIRRORED_REPEAT_SUPPORT (surface))) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* TODO: how do we figure out the color range resolution? transforming - the gradient vector with the inverse of the pattern matrix should - give us a good hint. */ - color_range_size = 512; - - /* destination surface size less than color range size, an image - gradient is probably more efficient. */ - if ((width * height) <= color_range_size) - return CAIRO_INT_STATUS_UNSUPPORTED; - - color_range = glitz_color_range_create (surface->surface, - color_range_size); - if (!color_range) - return CAIRO_STATUS_NO_MEMORY; - - _cairo_gl_create_color_range (pattern, - glitz_color_range_get_data (color_range), - color_range_size); - - glitz_color_range_put_back_data (color_range); - - switch (pattern->extend) { - case CAIRO_EXTEND_REPEAT: - glitz_color_range_set_extend (color_range, GLITZ_EXTEND_REPEAT); - break; - case CAIRO_EXTEND_REFLECT: - glitz_color_range_set_extend (color_range, GLITZ_EXTEND_REFLECT); - break; - case CAIRO_EXTEND_NONE: - glitz_color_range_set_extend (color_range, GLITZ_EXTEND_PAD); - break; - } - - glitz_color_range_set_filter (color_range, GLITZ_FILTER_BILINEAR); - - if (pattern->type == CAIRO_PATTERN_LINEAR) { - glitz_point_fixed_t start; - glitz_point_fixed_t stop; - - start.x = _cairo_fixed_from_double (pattern->u.linear.point0.x); - start.y = _cairo_fixed_from_double (pattern->u.linear.point0.y); - stop.x = _cairo_fixed_from_double (pattern->u.linear.point1.x); - stop.y = _cairo_fixed_from_double (pattern->u.linear.point1.y); - - source = glitz_surface_create_linear (&start, &stop, color_range); - } else { - glitz_point_fixed_t center; - - center.x = _cairo_fixed_from_double (pattern->u.radial.center1.x); - center.y = _cairo_fixed_from_double (pattern->u.radial.center1.y); - - source = glitz_surface_create_radial - (¢er, - _cairo_fixed_from_double (pattern->u.radial.radius0), - _cairo_fixed_from_double (pattern->u.radial.radius1), - color_range); - } - - glitz_color_range_destroy (color_range); - } break; - case CAIRO_PATTERN_SURFACE: - if (CAIRO_GL_COMPOSITE_TRAPEZOIDS_SUPPORT (surface)) { - cairo_gl_surface_t *src_clone = NULL; - cairo_surface_t *generic_src = pattern->u.surface.surface; - - src = (cairo_gl_surface_t *) generic_src; - if (generic_src->backend != surface->base.backend) { - src_clone = - _cairo_gl_surface_clone_similar (generic_src, surface, - CAIRO_FORMAT_ARGB32); - if (!src_clone) - return CAIRO_INT_STATUS_UNSUPPORTED; - } else { - src_clone = (cairo_gl_surface_t *) - _cairo_gl_surface_create (src->surface, 0); - if (!src_clone) - return CAIRO_STATUS_NO_MEMORY; - - cairo_surface_set_filter - (&src_clone->base, cairo_surface_get_filter (generic_src)); - - cairo_surface_set_matrix (&src_clone->base, - &generic_src->matrix); - } - - cairo_surface_set_repeat (&src_clone->base, generic_src->repeat); - - src_clone->opacity = (unsigned short) - (pattern->color.alpha * 0xffff); - - pattern->source = &src_clone->base; - - return CAIRO_STATUS_SUCCESS; - } - return CAIRO_INT_STATUS_UNSUPPORTED; - break; - } - - if (!source) - return CAIRO_STATUS_NO_MEMORY; - - src = (cairo_gl_surface_t *) _cairo_gl_surface_create (source, 1); - if (!src) { - glitz_surface_destroy (source); - - return CAIRO_STATUS_NO_MEMORY; - } - - if (pattern->type == CAIRO_PATTERN_LINEAR || - pattern->type == CAIRO_PATTERN_RADIAL) - cairo_surface_set_matrix (&src->base, &pattern->matrix); - - _cairo_pattern_init_copy (&src->pattern, pattern); - src->pattern_box = *box; - - pattern->source = &src->base; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_gl_surface_set_clip_region (void *abstract_surface, - pixman_region16_t *region) -{ - cairo_gl_surface_t *surface = abstract_surface; - glitz_rectangle_t *clip_rects; - pixman_box16_t *box; - int n, i; - - if (region == NULL) { - glitz_rectangle_t rect; - - rect.x = 0; - rect.y = 0; - rect.width = glitz_surface_get_width (surface->surface); - rect.height = glitz_surface_get_height (surface->surface); - - glitz_surface_clip_rectangles (surface->surface, - GLITZ_CLIP_OPERATOR_SET, &rect, 1); - } - - if (surface->format->stencil_size < 1) - return CAIRO_INT_STATUS_UNSUPPORTED; - - n = pixman_region_num_rects (region); - if (n == 0) - return CAIRO_STATUS_SUCCESS; - - box = pixman_region_rects (region); - - clip_rects = malloc (n * sizeof (glitz_rectangle_t)); - if (!clip_rects) - return CAIRO_STATUS_NO_MEMORY; - - for (i = 0; i < n; n++, box++) { - clip_rects[i].x = box->x1; - clip_rects[i].y = box->y1; - clip_rects[i].width = (unsigned short) (box->x2 - box->x1); - clip_rects[i].height = (unsigned short) (box->y2 - box->y1); - } - - glitz_surface_clip_rectangles (surface->surface, - GLITZ_CLIP_OPERATOR_SET, clip_rects, n); - - free (clip_rects); - - return CAIRO_STATUS_SUCCESS; -} - -static const struct cairo_surface_backend cairo_gl_surface_backend = { - _cairo_gl_surface_create_similar, - _cairo_gl_surface_destroy, - _cairo_gl_surface_pixels_per_inch, - _cairo_gl_surface_get_image, - _cairo_gl_surface_set_image, - _cairo_gl_surface_set_matrix, - _cairo_gl_surface_set_filter, - _cairo_gl_surface_set_repeat, - _cairo_gl_surface_composite, - _cairo_gl_surface_fill_rectangles, - _cairo_gl_surface_composite_trapezoids, - _cairo_gl_surface_copy_page, - _cairo_gl_surface_show_page, - _cairo_gl_surface_set_clip_region, - _cairo_gl_surface_create_pattern -}; - -static cairo_surface_t * -_cairo_gl_surface_create (glitz_surface_t *surface, int owns_surface) -{ - cairo_gl_surface_t *crsurface; - - if (!surface) - return NULL; - - crsurface = malloc (sizeof (cairo_gl_surface_t)); - if (crsurface == NULL) - return NULL; - - _cairo_surface_init (&crsurface->base, &cairo_gl_surface_backend); - _cairo_pattern_init (&crsurface->pattern); - crsurface->pattern.type = CAIRO_PATTERN_SURFACE; - crsurface->pattern.u.surface.surface = NULL; - crsurface->format = glitz_surface_get_format (surface); - crsurface->surface = surface; - crsurface->features = glitz_surface_get_features (surface); - crsurface->hints = glitz_surface_get_hints (surface); - crsurface->owns_surface = owns_surface; - crsurface->opacity = 0xffff; - - return (cairo_surface_t *) crsurface; -} - -cairo_surface_t * -cairo_gl_surface_create (glitz_surface_t *surface) -{ - return _cairo_gl_surface_create (surface, 0); -} diff --git a/src/cairo_glitz_surface.c b/src/cairo_glitz_surface.c new file mode 100644 index 000000000..83269dc12 --- /dev/null +++ b/src/cairo_glitz_surface.c @@ -0,0 +1,907 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2004 David Reveman + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of David + * Reveman not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. David Reveman makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: David Reveman + */ + +#include "cairoint.h" + +#define GLITZ_FIXED_TO_FLOAT(f) \ + (((glitz_float_t) (f)) / 65536) + +#define GLITZ_FIXED_LINE_X_TO_FLOAT(line, v) \ + (((glitz_float_t) \ + ((line).p1.x + (cairo_fixed_16_16_t) \ + (((cairo_fixed_32_32_t) ((v) - (line).p1.y) * \ + ((line).p2.x - (line).p1.x)) / \ + ((line).p2.y - (line).p1.y)))) / 65536) + +#define GLITZ_FIXED_LINE_X_CEIL_TO_FLOAT(line, v) \ + (((glitz_float_t) \ + ((line).p1.x + (cairo_fixed_16_16_t) \ + (((((line).p2.y - (line).p1.y) - 1) + \ + ((cairo_fixed_32_32_t) ((v) - (line).p1.y) * \ + ((line).p2.x - (line).p1.x))) / \ + ((line).p2.y - (line).p1.y)))) / 65536) + +void +cairo_set_target_glitz (cairo_t *cr, glitz_surface_t *surface) +{ + cairo_surface_t *crsurface; + + if (cr->status && cr->status != CAIRO_STATUS_NO_TARGET_SURFACE) + return; + + glitz_surface_reference (surface); + + crsurface = cairo_glitz_surface_create (surface); + if (crsurface == NULL) { + cr->status = CAIRO_STATUS_NO_MEMORY; + return; + } + + cairo_set_target_surface (cr, crsurface); + + cairo_surface_destroy (crsurface); +} + +typedef struct cairo_glitz_surface { + cairo_surface_t base; + + unsigned long features; + glitz_surface_t *surface; + glitz_format_t *format; + + cairo_pattern_t pattern; + cairo_box_t pattern_box; +} cairo_glitz_surface_t; + +static void +_cairo_glitz_surface_destroy (void *abstract_surface) +{ + cairo_glitz_surface_t *surface = abstract_surface; + + glitz_surface_destroy (surface->surface); + + _cairo_pattern_fini (&surface->pattern); + + free (surface); +} + +static double +_cairo_glitz_surface_pixels_per_inch (void *abstract_surface) +{ + return 96.0; +} + +static cairo_image_surface_t * +_cairo_glitz_surface_get_image (void *abstract_surface) +{ + cairo_glitz_surface_t *surface = abstract_surface; + cairo_image_surface_t *image; + char *pixels; + int width, height, rowstride, size; + cairo_format_masks_t format; + glitz_buffer_t *buffer; + glitz_pixel_format_t pf; + + if (surface->pattern.type != CAIRO_PATTERN_SURFACE) { + cairo_box_t box; + + box.p1.x = box.p1.y = 0; + box.p2.x = surface->pattern_box.p2.x; + box.p2.y = surface->pattern_box.p2.y; + + return _cairo_pattern_get_image (&surface->pattern, &box); + } + + + width = glitz_surface_get_width (surface->surface); + height = glitz_surface_get_height (surface->surface); + + if (surface->format->red_size > 0) { + format.bpp = 32; + + if (surface->format->alpha_size > 0) + format.alpha_mask = 0xff000000; + else + format.alpha_mask = 0x0; + + format.red_mask = 0xff0000; + format.green_mask = 0xff00; + format.blue_mask = 0xff; + } else { + format.bpp = 8; + format.blue_mask = format.green_mask = format.red_mask = 0x0; + format.alpha_mask = 0xff; + } + + rowstride = (((width * format.bpp) / 8) + 3) & -4; + + pf.masks.bpp = format.bpp; + pf.masks.alpha_mask = format.alpha_mask; + pf.masks.red_mask = format.red_mask; + pf.masks.green_mask = format.green_mask; + pf.masks.blue_mask = format.blue_mask; + pf.xoffset = 0; + pf.skip_lines = 0; + pf.bytes_per_line = rowstride; + pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; + size = height * rowstride; + + pixels = malloc (size); + if (!pixels) + return NULL; + + buffer = glitz_pixel_buffer_create (surface->surface, NULL, size, + GLITZ_BUFFER_HINT_DYNAMIC_READ); + if (!buffer) { + free (pixels); + return NULL; + } + + glitz_get_pixels (surface->surface, + 0, 0, + width, height, + &pf, + buffer); + + glitz_buffer_get_data (buffer, 0, size, pixels); + + glitz_buffer_destroy (buffer); + + image = (cairo_image_surface_t *) + _cairo_image_surface_create_with_masks (pixels, + &format, + width, height, + rowstride); + + _cairo_image_surface_assume_ownership_of_data (image); + + _cairo_image_surface_set_repeat (image, surface->base.repeat); + _cairo_image_surface_set_matrix (image, &(surface->base.matrix)); + + return image; +} + +static cairo_status_t +_cairo_glitz_surface_set_image (void *abstract_surface, + cairo_image_surface_t *image) +{ + cairo_glitz_surface_t *surface = abstract_surface; + glitz_buffer_t *buffer; + glitz_pixel_format_t pf; + + if (image->depth > 8) { + pf.masks.bpp = 32; + + if (surface->format->alpha_size) + pf.masks.alpha_mask = 0xff000000; + else + pf.masks.alpha_mask = 0x0; + + pf.masks.red_mask = 0xff0000; + pf.masks.green_mask = 0xff00; + pf.masks.blue_mask = 0xff; + } else { + pf.masks.bpp = 8; + pf.masks.alpha_mask = 0xff; + pf.masks.red_mask = pf.masks.green_mask = pf.masks.blue_mask = 0x0; + } + + pf.xoffset = 0; + pf.skip_lines = 0; + pf.bytes_per_line = (((image->width * pf.masks.bpp) / 8) + 3) & -4; + pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; + + buffer = glitz_pixel_buffer_create (surface->surface, + image->data, + pf.bytes_per_line * image->height, + GLITZ_BUFFER_HINT_STREAM_DRAW); + if (!buffer) + return CAIRO_STATUS_NO_MEMORY; + + glitz_set_pixels (surface->surface, + 0, 0, + image->width, image->height, + &pf, + buffer); + + glitz_buffer_destroy (buffer); + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_cairo_glitz_surface_set_matrix (void *abstract_surface, + cairo_matrix_t *matrix) +{ + cairo_glitz_surface_t *surface = abstract_surface; + glitz_transform_t transform; + + transform.matrix[0][0] = _cairo_fixed_from_double (matrix->m[0][0]); + transform.matrix[0][1] = _cairo_fixed_from_double (matrix->m[1][0]); + transform.matrix[0][2] = _cairo_fixed_from_double (matrix->m[2][0]); + + transform.matrix[1][0] = _cairo_fixed_from_double (matrix->m[0][1]); + transform.matrix[1][1] = _cairo_fixed_from_double (matrix->m[1][1]); + transform.matrix[1][2] = _cairo_fixed_from_double (matrix->m[2][1]); + + transform.matrix[2][0] = 0; + transform.matrix[2][1] = 0; + transform.matrix[2][2] = 1 << 16; + + glitz_surface_set_transform (surface->surface, &transform); + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_cairo_glitz_surface_set_filter (void *abstract_surface, cairo_filter_t filter) +{ + cairo_glitz_surface_t *surface = abstract_surface; + glitz_filter_t glitz_filter; + + switch (filter) { + case CAIRO_FILTER_FAST: + case CAIRO_FILTER_NEAREST: + glitz_filter = GLITZ_FILTER_NEAREST; + break; + case CAIRO_FILTER_GOOD: + case CAIRO_FILTER_BEST: + case CAIRO_FILTER_BILINEAR: + default: + glitz_filter = GLITZ_FILTER_BILINEAR; + break; + } + + glitz_surface_set_filter (surface->surface, glitz_filter, NULL, 0); + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_cairo_glitz_surface_set_repeat (void *abstract_surface, int repeat) +{ + cairo_glitz_surface_t *surface = abstract_surface; + + glitz_surface_set_fill (surface->surface, + (repeat)? GLITZ_FILL_REPEAT: + GLITZ_FILL_TRANSPARENT); + + return CAIRO_STATUS_SUCCESS; +} + +static glitz_operator_t +_glitz_operator (cairo_operator_t op) +{ + switch (op) { + case CAIRO_OPERATOR_CLEAR: + return GLITZ_OPERATOR_CLEAR; + case CAIRO_OPERATOR_SRC: + return GLITZ_OPERATOR_SRC; + case CAIRO_OPERATOR_DST: + return GLITZ_OPERATOR_DST; + case CAIRO_OPERATOR_OVER_REVERSE: + return GLITZ_OPERATOR_OVER_REVERSE; + case CAIRO_OPERATOR_IN: + return GLITZ_OPERATOR_IN; + case CAIRO_OPERATOR_IN_REVERSE: + return GLITZ_OPERATOR_IN_REVERSE; + case CAIRO_OPERATOR_OUT: + return GLITZ_OPERATOR_OUT; + case CAIRO_OPERATOR_OUT_REVERSE: + return GLITZ_OPERATOR_OUT_REVERSE; + case CAIRO_OPERATOR_ATOP: + return GLITZ_OPERATOR_ATOP; + case CAIRO_OPERATOR_ATOP_REVERSE: + return GLITZ_OPERATOR_ATOP_REVERSE; + case CAIRO_OPERATOR_XOR: + return GLITZ_OPERATOR_XOR; + case CAIRO_OPERATOR_ADD: + return GLITZ_OPERATOR_ADD; + case CAIRO_OPERATOR_SATURATE: + return GLITZ_OPERATOR_SATURATE; + case CAIRO_OPERATOR_OVER: + default: + return GLITZ_OPERATOR_OVER; + } +} + +static glitz_format_name_t +_glitz_format (cairo_format_t format) +{ + switch (format) { + case CAIRO_FORMAT_A1: + return GLITZ_STANDARD_A1; + case CAIRO_FORMAT_A8: + return GLITZ_STANDARD_A8; + case CAIRO_FORMAT_RGB24: + return GLITZ_STANDARD_RGB24; + case CAIRO_FORMAT_ARGB32: + default: + return GLITZ_STANDARD_ARGB32; + } +} + +static glitz_surface_t * +_glitz_surface_create_solid (glitz_surface_t *other, + glitz_format_name_t format_name, + glitz_color_t *color) +{ + glitz_surface_t *surface; + glitz_format_t *format; + + format = glitz_surface_find_similar_standard_format (other, format_name); + if (format == NULL) + return NULL; + + surface = glitz_surface_create_similar (other, format, 1, 1); + if (surface == NULL) + return NULL; + + glitz_set_rectangle (surface, color, 0, 0, 1, 1); + + glitz_surface_set_fill (surface, GLITZ_FILL_REPEAT); + + return surface; +} + +static cairo_surface_t * +_cairo_glitz_surface_create_similar (void *abstract_src, + cairo_format_t format, + int drawable, + int width, + int height) +{ + cairo_glitz_surface_t *src = abstract_src; + glitz_surface_t *surface; + cairo_surface_t *crsurface; + glitz_format_t *glitz_format; + + glitz_format = + glitz_surface_find_similar_standard_format (src->surface, + _glitz_format (format)); + if (glitz_format == NULL) + return NULL; + + surface = glitz_surface_create_similar (src->surface, glitz_format, + width, height); + if (surface == NULL) + return NULL; + + crsurface = cairo_glitz_surface_create (surface); + if (crsurface == NULL) + glitz_surface_destroy (surface); + + return crsurface; +} + +static cairo_glitz_surface_t * +_cairo_glitz_surface_clone_similar (cairo_glitz_surface_t *templ, + cairo_surface_t *src, + cairo_format_t format) +{ + cairo_glitz_surface_t *clone; + cairo_image_surface_t *src_image; + + src_image = _cairo_surface_get_image (src); + + clone = (cairo_glitz_surface_t *) + _cairo_glitz_surface_create_similar (templ, format, 0, + src_image->width, + src_image->height); + if (clone == NULL) + return NULL; + + _cairo_glitz_surface_set_filter (clone, cairo_surface_get_filter (src)); + + _cairo_glitz_surface_set_image (clone, src_image); + + _cairo_glitz_surface_set_matrix (clone, &(src_image->base.matrix)); + + cairo_surface_destroy (&src_image->base); + + return clone; +} + +static cairo_int_status_t +_glitz_composite (glitz_operator_t op, + glitz_surface_t *src, + glitz_surface_t *mask, + glitz_surface_t *dst, + int src_x, + int src_y, + int mask_x, + int mask_y, + int dst_x, + int dst_y, + int width, + int height, + glitz_buffer_t *geometry, + glitz_geometry_format_t *format) +{ + if (glitz_surface_get_status (dst)) + return CAIRO_STATUS_NO_TARGET_SURFACE; + + glitz_set_geometry (dst, + 0, 0, + format, geometry); + + glitz_composite (op, + src, + mask, + dst, + src_x, src_y, + mask_x, mask_y, + dst_x, dst_y, + width, height); + + glitz_set_geometry (dst, 0, 0, NULL, NULL); + + if (glitz_surface_get_status (dst) == GLITZ_STATUS_NOT_SUPPORTED) + return CAIRO_INT_STATUS_UNSUPPORTED; + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_int_status_t +_cairo_glitz_surface_composite (cairo_operator_t op, + cairo_surface_t *generic_src, + cairo_surface_t *generic_mask, + void *abstract_dst, + int src_x, + int src_y, + int mask_x, + int mask_y, + int dst_x, + int dst_y, + unsigned int width, + unsigned int height) +{ + cairo_glitz_surface_t *dst = abstract_dst; + cairo_glitz_surface_t *src = (cairo_glitz_surface_t *) generic_src; + cairo_glitz_surface_t *mask = (cairo_glitz_surface_t *) generic_mask; + cairo_glitz_surface_t *src_clone = NULL; + cairo_glitz_surface_t *mask_clone = NULL; + cairo_int_status_t status; + + if (generic_src->backend != dst->base.backend) { + src_clone = _cairo_glitz_surface_clone_similar (dst, generic_src, + CAIRO_FORMAT_ARGB32); + if (!src_clone) + return CAIRO_INT_STATUS_UNSUPPORTED; + + src = src_clone; + } + + if (generic_mask && (generic_mask->backend != dst->base.backend)) { + mask_clone = _cairo_glitz_surface_clone_similar (dst, generic_mask, + CAIRO_FORMAT_ARGB32); + if (!mask_clone) + return CAIRO_INT_STATUS_UNSUPPORTED; + + mask = mask_clone; + } + + status = _glitz_composite (_glitz_operator (op), + src->surface, + (mask)? mask->surface: NULL, + dst->surface, + src_x, src_y, + mask_x, mask_y, + dst_x, dst_y, + width, height, + NULL, NULL); + + if (src_clone) + cairo_surface_destroy (&src_clone->base); + + if (mask_clone) + cairo_surface_destroy (&mask_clone->base); + + return status; +} + +static cairo_int_status_t +_cairo_glitz_surface_fill_rectangles (void *abstract_dst, + cairo_operator_t op, + const cairo_color_t *color, + cairo_rectangle_t *rects, + int n_rects) +{ + cairo_glitz_surface_t *dst = abstract_dst; + glitz_color_t glitz_color; + + glitz_color.red = color->red_short; + glitz_color.green = color->green_short; + glitz_color.blue = color->blue_short; + glitz_color.alpha = color->alpha_short; + + if (op != CAIRO_OPERATOR_SRC) { + glitz_surface_t *solid; + glitz_float_t *data; + glitz_buffer_t *buffer; + glitz_geometry_format_t gf; + cairo_int_status_t status; + int width = 0; + int height = 0; + + gf.mode = GLITZ_GEOMETRY_MODE_DIRECT; + gf.edge_hint = GLITZ_GEOMETRY_EDGE_HINT_SHARP; + gf.primitive = GLITZ_GEOMETRY_PRIMITIVE_QUADS; + gf.type = GLITZ_DATA_TYPE_FLOAT; + gf.first = 0; + gf.count = n_rects * 4; + + buffer = + glitz_geometry_buffer_create (dst->surface, NULL, + n_rects * 8 * sizeof (glitz_float_t), + GLITZ_BUFFER_HINT_STREAM_DRAW); + if (buffer == NULL) + return CAIRO_STATUS_NO_MEMORY; + + data = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); + for (; n_rects; rects++, n_rects--) { + *data++ = (glitz_float_t) rects->x; + *data++ = (glitz_float_t) rects->y; + *data++ = (glitz_float_t) (rects->x + rects->width); + *data++ = (glitz_float_t) rects->y; + *data++ = (glitz_float_t) (rects->x + rects->width); + *data++ = (glitz_float_t) (rects->y + rects->height); + *data++ = (glitz_float_t) rects->x; + *data++ = (glitz_float_t) (rects->y + rects->height); + + if ((rects->x + rects->width) > width) + width = rects->x + rects->width; + + if ((rects->y + rects->height) > height) + height = rects->y + rects->height; + } + glitz_buffer_unmap (buffer); + + solid = _glitz_surface_create_solid (dst->surface, + GLITZ_STANDARD_ARGB32, + &glitz_color); + if (solid == NULL) + return CAIRO_STATUS_NO_MEMORY; + + status = _glitz_composite (_glitz_operator (op), + solid, + NULL, + dst->surface, + 0, 0, + 0, 0, + 0, 0, + width, height, + buffer, &gf); + + glitz_surface_destroy (solid); + glitz_buffer_destroy (buffer); + + return status; + } else + glitz_set_rectangles (dst->surface, &glitz_color, + (glitz_rectangle_t *) rects, n_rects); + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_int_status_t +_cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, + cairo_surface_t *generic_src, + void *abstract_dst, + int x_src, + int y_src, + cairo_trapezoid_t *traps, + int n_traps) +{ + cairo_glitz_surface_t *dst = abstract_dst; + cairo_glitz_surface_t *src = (cairo_glitz_surface_t *) generic_src; + glitz_surface_t *mask = NULL; + glitz_float_t *data; + glitz_buffer_t *buffer; + glitz_geometry_format_t gf; + cairo_int_status_t status; + int x_dst, y_dst, x_rel, y_rel, width, height; + + if (generic_src->backend != dst->base.backend) + return CAIRO_INT_STATUS_UNSUPPORTED; + + gf.mode = GLITZ_GEOMETRY_MODE_DIRECT; + gf.edge_hint = GLITZ_GEOMETRY_EDGE_HINT_GOOD_SMOOTH; + gf.primitive = GLITZ_GEOMETRY_PRIMITIVE_QUADS; + gf.type = GLITZ_DATA_TYPE_FLOAT; + gf.first = 0; + gf.count = n_traps * 4; + + buffer = + glitz_geometry_buffer_create (dst->surface, NULL, + n_traps * 8 * sizeof (glitz_float_t), + GLITZ_BUFFER_HINT_STREAM_DRAW); + if (buffer == NULL) + return CAIRO_STATUS_NO_MEMORY; + + x_dst = traps[0].left.p1.x >> 16; + y_dst = traps[0].left.p1.y >> 16; + + data = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); + for (; n_traps; traps++, n_traps--) { + glitz_float_t top, bottom; + + top = GLITZ_FIXED_TO_FLOAT (traps->top); + bottom = GLITZ_FIXED_TO_FLOAT (traps->bottom); + + *data++ = GLITZ_FIXED_LINE_X_TO_FLOAT (traps->left, traps->top); + *data++ = top; + *data++ = GLITZ_FIXED_LINE_X_CEIL_TO_FLOAT (traps->right, traps->top); + *data++ = top; + *data++ = + GLITZ_FIXED_LINE_X_CEIL_TO_FLOAT (traps->right, traps->bottom); + *data++ = bottom; + *data++ = GLITZ_FIXED_LINE_X_TO_FLOAT (traps->left, traps->bottom); + *data++ = bottom; + } + glitz_buffer_unmap (buffer); + + if ((src->pattern.type == CAIRO_PATTERN_SURFACE) && + (src->pattern.color.alpha != 1.0)) { + glitz_color_t color; + + color.red = color.green = color.blue = 0; + color.alpha = src->pattern.color.alpha_short; + + mask = _glitz_surface_create_solid (dst->surface, + GLITZ_STANDARD_A8, + &color); + } + + x_rel = (src->pattern_box.p1.x >> 16) + x_src - x_dst; + y_rel = (src->pattern_box.p1.y >> 16) + y_src - y_dst; + + x_dst = src->pattern_box.p1.x >> 16; + y_dst = src->pattern_box.p1.y >> 16; + + width = ((src->pattern_box.p2.x + 65535) >> 16) - + (src->pattern_box.p1.x >> 16); + height = ((src->pattern_box.p2.y + 65535) >> 16) - + (src->pattern_box.p1.y >> 16); + + status = _glitz_composite (_glitz_operator (op), + src->surface, + mask, + dst->surface, + x_rel, y_rel, + 0, 0, + x_dst, y_dst, + width, height, + buffer, &gf); + + if (mask) + glitz_surface_destroy (mask); + + glitz_buffer_destroy (buffer); + + return status; +} + +static cairo_int_status_t +_cairo_glitz_surface_copy_page (void *abstract_surface) +{ + return CAIRO_INT_STATUS_UNSUPPORTED; +} + +static cairo_int_status_t +_cairo_glitz_surface_show_page (void *abstract_surface) +{ + return CAIRO_INT_STATUS_UNSUPPORTED; +} + +static cairo_int_status_t +_cairo_glitz_surface_create_pattern (void *abstract_dst, + cairo_pattern_t *pattern, + cairo_box_t *box) +{ + cairo_glitz_surface_t *dst = abstract_dst; + cairo_surface_t *generic_src = NULL; + cairo_image_surface_t *image = NULL; + cairo_glitz_surface_t *src; + + switch (pattern->type) { + case CAIRO_PATTERN_SOLID: + generic_src = + _cairo_surface_create_similar_solid (&dst->base, + CAIRO_FORMAT_ARGB32, + 1, 1, + &pattern->color); + if (generic_src) + cairo_surface_set_repeat (generic_src, 1); + break; + case CAIRO_PATTERN_RADIAL: + /* glitz doesn't support inner and outer circle with different + center points. */ + if (pattern->u.radial.center0.x != pattern->u.radial.center1.x || + pattern->u.radial.center0.y != pattern->u.radial.center1.y) + break; + /* fall-through */ + case CAIRO_PATTERN_LINEAR: { + glitz_fixed16_16_t *params; + int i, n_params; + + if (!(dst->features & GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK)) + break; + + if (pattern->filter != CAIRO_FILTER_BILINEAR) + break; + + n_params = pattern->n_stops * 3 + 4; + + params = malloc (sizeof (glitz_fixed16_16_t) * n_params); + if (params == NULL) + return CAIRO_STATUS_NO_MEMORY; + + generic_src = + _cairo_glitz_surface_create_similar (abstract_dst, + CAIRO_FORMAT_ARGB32, 0, + pattern->n_stops, 1); + if (generic_src == NULL) { + free (params); + return CAIRO_STATUS_NO_MEMORY; + } + + src = (cairo_glitz_surface_t *) generic_src; + + for (i = 0; i < pattern->n_stops; i++) { + glitz_color_t color; + + color.red = pattern->stops[i].color_char[0] * 256; + color.green = pattern->stops[i].color_char[1] * 256; + color.blue = pattern->stops[i].color_char[2] * 256; + color.alpha = pattern->stops[i].color_char[3] * 256; + + glitz_set_rectangle (src->surface, &color, i, 0, 1, 1); + + params[4 + 3 * i] = pattern->stops[i].offset; + params[5 + 3 * i] = 0x8000 | (i << 16); + params[6 + 3 * i] = 0x8000; + } + + if (pattern->type == CAIRO_PATTERN_LINEAR) { + params[0] = _cairo_fixed_from_double (pattern->u.linear.point0.x); + params[1] = _cairo_fixed_from_double (pattern->u.linear.point0.y); + params[2] = _cairo_fixed_from_double (pattern->u.linear.point1.x); + params[3] = _cairo_fixed_from_double (pattern->u.linear.point1.y); + + glitz_surface_set_filter (src->surface, + GLITZ_FILTER_LINEAR_GRADIENT, + params, n_params); + } else { + params[0] = _cairo_fixed_from_double (pattern->u.radial.center0.x); + params[1] = _cairo_fixed_from_double (pattern->u.radial.center0.y); + params[2] = _cairo_fixed_from_double (pattern->u.radial.radius0); + params[3] = _cairo_fixed_from_double (pattern->u.radial.radius1); + + glitz_surface_set_filter (src->surface, + GLITZ_FILTER_RADIAL_GRADIENT, + params, n_params); + } + + switch (pattern->extend) { + case CAIRO_EXTEND_REPEAT: + glitz_surface_set_fill (src->surface, GLITZ_FILL_REPEAT); + break; + case CAIRO_EXTEND_REFLECT: + glitz_surface_set_fill (src->surface, GLITZ_FILL_REFLECT); + break; + case CAIRO_EXTEND_NONE: + default: + glitz_surface_set_fill (src->surface, GLITZ_FILL_NEAREST); + break; + } + + cairo_surface_set_matrix (&src->base, &pattern->matrix); + + free (params); + } break; + case CAIRO_PATTERN_SURFACE: + generic_src = pattern->u.surface.surface; + cairo_surface_reference (generic_src); + break; + } + + if (generic_src == NULL) { + image = _cairo_pattern_get_image (pattern, box); + if (image == NULL) + return CAIRO_STATUS_NO_MEMORY; + + generic_src = &image->base; + } + + if (generic_src->backend != dst->base.backend) { + src = _cairo_glitz_surface_clone_similar (dst, generic_src, + CAIRO_FORMAT_ARGB32); + if (src == NULL) + return CAIRO_STATUS_NO_MEMORY; + } else + src = (cairo_glitz_surface_t *) generic_src; + + if (image) + cairo_surface_destroy (&image->base); + + _cairo_pattern_init_copy (&src->pattern, pattern); + src->pattern_box = *box; + + pattern->source = &src->base; + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_int_status_t +_cairo_glitz_surface_set_clip_region (void *abstract_surface, + pixman_region16_t *region) +{ + return CAIRO_INT_STATUS_UNSUPPORTED; +} + +static const struct cairo_surface_backend cairo_glitz_surface_backend = { + _cairo_glitz_surface_create_similar, + _cairo_glitz_surface_destroy, + _cairo_glitz_surface_pixels_per_inch, + _cairo_glitz_surface_get_image, + _cairo_glitz_surface_set_image, + _cairo_glitz_surface_set_matrix, + _cairo_glitz_surface_set_filter, + _cairo_glitz_surface_set_repeat, + _cairo_glitz_surface_composite, + _cairo_glitz_surface_fill_rectangles, + _cairo_glitz_surface_composite_trapezoids, + _cairo_glitz_surface_copy_page, + _cairo_glitz_surface_show_page, + _cairo_glitz_surface_set_clip_region, + _cairo_glitz_surface_create_pattern +}; + +cairo_surface_t * +cairo_glitz_surface_create (glitz_surface_t *surface) +{ + cairo_glitz_surface_t *crsurface; + + if (!surface) + return NULL; + + crsurface = malloc (sizeof (cairo_glitz_surface_t)); + if (crsurface == NULL) + return NULL; + + _cairo_surface_init (&crsurface->base, &cairo_glitz_surface_backend); + + crsurface->surface = surface; + crsurface->features = glitz_surface_get_features (surface); + crsurface->format = glitz_surface_get_format (surface); + + _cairo_pattern_init (&crsurface->pattern); + crsurface->pattern.type = CAIRO_PATTERN_SURFACE; + crsurface->pattern.u.surface.surface = NULL; + + return (cairo_surface_t *) crsurface; +} -- cgit v1.2.1 From 786904f1aa0dc24f9c206387312eec81e42784d8 Mon Sep 17 00:00:00 2001 From: David Reveman Date: Sat, 11 Sep 2004 07:59:27 +0000 Subject: Tracking color stop coordinate changes to glitz's gradient filters --- ChangeLog | 5 +++++ configure.in | 2 +- src/cairo-glitz-surface.c | 4 ++-- src/cairo_glitz_surface.c | 4 ++-- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index e09f60604..0c08d2df8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2004-09-11 David Reveman + * configure.in: Require version 0.2.2 of glitz. + + * src/cairo_glitz_surface.c (_cairo_glitz_surface_create_pattern): + 0.5 should no longer be added to gradient stop coordinates. + * src/cairo.h: CAIRO_HAS_GL_SURFACE -> CAIRO_HAS_GLITZ_SURFACE. cairo_set_target_gl -> cairo_set_target_glitz. cairo_gl_surface_create -> cairo_glitz_surface_create. diff --git a/configure.in b/configure.in index a682d47ec..49a43a84a 100644 --- a/configure.in +++ b/configure.in @@ -141,7 +141,7 @@ AC_ARG_ENABLE(glitz, [use_glitz=$enableval], [use_glitz=yes]) if test "x$use_glitz" = "xyes"; then - PKG_CHECK_MODULES(GLITZ, glitz >= 0.2.1, [ + PKG_CHECK_MODULES(GLITZ, glitz >= 0.2.2, [ GLITZ_REQUIRES=glitz use_glitz=yes], [use_glitz="no (requires glitz http://freedesktop.org/software/glitz)"]) fi diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c index 83269dc12..9ea25190f 100644 --- a/src/cairo-glitz-surface.c +++ b/src/cairo-glitz-surface.c @@ -782,8 +782,8 @@ _cairo_glitz_surface_create_pattern (void *abstract_dst, glitz_set_rectangle (src->surface, &color, i, 0, 1, 1); params[4 + 3 * i] = pattern->stops[i].offset; - params[5 + 3 * i] = 0x8000 | (i << 16); - params[6 + 3 * i] = 0x8000; + params[5 + 3 * i] = i << 16; + params[6 + 3 * i] = 0; } if (pattern->type == CAIRO_PATTERN_LINEAR) { diff --git a/src/cairo_glitz_surface.c b/src/cairo_glitz_surface.c index 83269dc12..9ea25190f 100644 --- a/src/cairo_glitz_surface.c +++ b/src/cairo_glitz_surface.c @@ -782,8 +782,8 @@ _cairo_glitz_surface_create_pattern (void *abstract_dst, glitz_set_rectangle (src->surface, &color, i, 0, 1, 1); params[4 + 3 * i] = pattern->stops[i].offset; - params[5 + 3 * i] = 0x8000 | (i << 16); - params[6 + 3 * i] = 0x8000; + params[5 + 3 * i] = i << 16; + params[6 + 3 * i] = 0; } if (pattern->type == CAIRO_PATTERN_LINEAR) { -- cgit v1.2.1 From 7abd103d2eb0fb7099527f16634c80df247c7a65 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Sat, 11 Sep 2004 13:29:59 +0000 Subject: Require automake 1.6 rather than 1.7 since it seems to work just fine. --- ChangeLog | 5 +++++ autogen.sh | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0c08d2df8..2dab2c022 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2004-09-11 Carl Worth + + * autogen.sh: Require automake 1.6 rather than 1.7 since it seems + to work just fine. + 2004-09-11 David Reveman * configure.in: Require version 0.2.2 of glitz. diff --git a/autogen.sh b/autogen.sh index d365a92b1..a952f4c53 100755 --- a/autogen.sh +++ b/autogen.sh @@ -14,7 +14,8 @@ AUTOCONF=${AUTOCONF-autoconf} # automake 1.8 requires autoconf 2.58 # automake 1.7 requires autoconf 2.54 -automake_min_vers=1.7 +# I don't know what automake 1.6 wants, but this seems to work... +automake_min_vers=1.6 aclocal_min_vers=$automake_min_vers autoconf_min_vers=2.54 libtoolize_min_vers=1.4 -- cgit v1.2.1 From 4af8faee061b3b90e71badf36040daa0b8edb7d1 Mon Sep 17 00:00:00 2001 From: David Reveman Date: Sat, 11 Sep 2004 19:05:46 +0000 Subject: Pickup repeat setting when cloning surface --- ChangeLog | 5 +++++ src/cairo-glitz-surface.c | 2 ++ src/cairo_glitz_surface.c | 2 ++ 3 files changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index 2dab2c022..8c8a43a01 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2004-09-12 David Reveman + + * src/cairo_glitz_surface.c (_cairo_glitz_surface_create_pattern): + Pickup repeat setting when cloning surface. + 2004-09-11 Carl Worth * autogen.sh: Require automake 1.6 rather than 1.7 since it seems diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c index 9ea25190f..14dc0d0cb 100644 --- a/src/cairo-glitz-surface.c +++ b/src/cairo-glitz-surface.c @@ -842,6 +842,8 @@ _cairo_glitz_surface_create_pattern (void *abstract_dst, CAIRO_FORMAT_ARGB32); if (src == NULL) return CAIRO_STATUS_NO_MEMORY; + + cairo_surface_set_repeat (src, generic_src->repeat); } else src = (cairo_glitz_surface_t *) generic_src; diff --git a/src/cairo_glitz_surface.c b/src/cairo_glitz_surface.c index 9ea25190f..14dc0d0cb 100644 --- a/src/cairo_glitz_surface.c +++ b/src/cairo_glitz_surface.c @@ -842,6 +842,8 @@ _cairo_glitz_surface_create_pattern (void *abstract_dst, CAIRO_FORMAT_ARGB32); if (src == NULL) return CAIRO_STATUS_NO_MEMORY; + + cairo_surface_set_repeat (src, generic_src->repeat); } else src = (cairo_glitz_surface_t *) generic_src; -- cgit v1.2.1 From c5786fd0fe0f0b69f3896e77705282c211ba7a77 Mon Sep 17 00:00:00 2001 From: David Reveman Date: Sat, 11 Sep 2004 19:27:59 +0000 Subject: Added support for both transform and repeat --- pixman/AUTHORS | 1 + pixman/ChangeLog | 7 +++++++ pixman/src/ic.c | 8 ++++++++ pixman/src/iccompose.c | 46 ++++++++++++++++++++++++++++++++++++++++++---- pixman/src/icimage.h | 3 +++ 5 files changed, 61 insertions(+), 4 deletions(-) diff --git a/pixman/AUTHORS b/pixman/AUTHORS index 034f854b7..d18a04119 100644 --- a/pixman/AUTHORS +++ b/pixman/AUTHORS @@ -4,6 +4,7 @@ Dave Beckett Combined libpixregion, libic, and slim Jakub Bogusz Fixes for 64-bit machines. Anders Carlsson Build fixes. New accessor functions. Richard Henderson "slim" macros for better shared libraries +Owen Taylor Support for both transform and repeat Keith Packard The original implementation of the compositing code. Vladimir Vukicevic Bug fix. Bryan Worth Cleanups to not depend on X header files. diff --git a/pixman/ChangeLog b/pixman/ChangeLog index 798ed09da..34d3f90ce 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -1,3 +1,10 @@ +2004-09-12 David Reveman + + * src/ic.c (pixman_composite): + * src/iccompose.c (IcFetch_transform, IcFetcha_transform): + * src/icimage.h: Added support for both transform and repeat + (thanks to Owen Taylor ). + 2004-05-06 Carl Worth * src/icimage.c (pixman_image_set_clip_region): Leave diff --git a/pixman/src/ic.c b/pixman/src/ic.c index 13ec65385..44e7120f2 100644 --- a/pixman/src/ic.c +++ b/pixman/src/ic.c @@ -1078,6 +1078,14 @@ pixman_composite (pixman_operator_t op, func = pixman_compositeGeneral; break; } + /* if we are transforming, we handle repeats in + * IcFetch[a]_transform + */ + if (iSrc->transform) + srcRepeat = 0; + if (iMask && iMask->transform) + maskRepeat = 0; + n = pixman_region_num_rects (region); pbox = pixman_region_rects (region); while (n--) diff --git a/pixman/src/iccompose.c b/pixman/src/iccompose.c index 0f2413531..5dd074cc8 100644 --- a/pixman/src/iccompose.c +++ b/pixman/src/iccompose.c @@ -2239,6 +2239,8 @@ IcStore_external (pixman_compositeOperand *op, uint32_t value) (*op[2].store) (&op[2], value & 0xff000000); } +#define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (a) % (b) == 0 ? 0: (b) + (a) % (b)) + static uint32_t IcFetch_transform (pixman_compositeOperand *op) { @@ -2260,6 +2262,11 @@ IcFetch_transform (pixman_compositeOperand *op) case PIXMAN_FILTER_NEAREST: y = xFixedToInt (v.vector[1]) + op->u.transform.top_y; x = xFixedToInt (v.vector[0]) + op->u.transform.left_x; + if (op->u.transform.repeat) + { + y = mod (y, op->u.transform.height); + x = mod (x, op->u.transform.width); + } if (pixman_region_contains_point (op->clip, x, y, &box)) { (*op[1].set) (&op[1], x, y); @@ -2282,13 +2289,24 @@ IcFetch_transform (pixman_compositeOperand *op) for (y = miny; y <= maxy; y++) { uint32_t lrtot = 0, lgtot = 0, lbtot = 0, latot = 0; + int tx, ty; + + if (op->u.transform.repeat) + ty = mod (y, op->u.transform.height); + else + ty = y; xerr = xFixed1 - xFixedFrac (v.vector[0]); for (x = minx; x <= maxx; x++) { - if (pixman_region_contains_point (op->clip, x, y, &box)) + if (op->u.transform.repeat) + tx = mod (x, op->u.transform.width); + else + tx = x; + + if (pixman_region_contains_point (op->clip, tx, ty, &box)) { - (*op[1].set) (&op[1], x, y); + (*op[1].set) (&op[1], tx, ty); bits = (*op[1].fetch) (&op[1]); { Splita(bits); @@ -2343,6 +2361,11 @@ IcFetcha_transform (pixman_compositeOperand *op) case PIXMAN_FILTER_NEAREST: y = xFixedToInt (v.vector[1]) + op->u.transform.left_x; x = xFixedToInt (v.vector[0]) + op->u.transform.top_y; + if (op->u.transform.repeat) + { + y = mod (y, op->u.transform.height); + x = mod (x, op->u.transform.width); + } if (pixman_region_contains_point (op->clip, x, y, &box)) { (*op[1].set) (&op[1], x, y); @@ -2366,12 +2389,24 @@ IcFetcha_transform (pixman_compositeOperand *op) for (y = miny; y <= maxy; y++) { uint32_t lrtot = 0, lgtot = 0, lbtot = 0, latot = 0; + int tx, ty; + + if (op->u.transform.repeat) + ty = mod (y, op->u.transform.height); + else + ty = y; + xerr = xFixed1 - xFixedFrac (v.vector[0]); for (x = minx; x <= maxx; x++) { - if (pixman_region_contains_point (op->clip, x, y, &box)) + if (op->u.transform.repeat) + tx = mod (x, op->u.transform.width); + else + tx = x; + + if (pixman_region_contains_point (op->clip, tx, ty, &box)) { - (*op[1].set) (&op[1], x, y); + (*op[1].set) (&op[1], tx, ty); bits = (*op[1].fetcha) (&op[1]); { Splita(bits); @@ -2535,6 +2570,9 @@ IcBuildCompositeOperand (pixman_image_t *image, op->u.transform.y = y - op->u.transform.top_y; op->u.transform.transform = image->transform; op->u.transform.filter = image->filter; + op->u.transform.repeat = image->repeat; + op->u.transform.width = image->pixels->width; + op->u.transform.height = image->pixels->height; op->fetch = IcFetch_transform; op->fetcha = IcFetcha_transform; diff --git a/pixman/src/icimage.h b/pixman/src/icimage.h index 0c37666ef..79fcae169 100644 --- a/pixman/src/icimage.h +++ b/pixman/src/icimage.h @@ -272,6 +272,9 @@ struct _pixman_compositeOperand { int y; pixman_transform_t *transform; pixman_filter_t filter; + int repeat; + int width; + int height; } transform; } u; pixman_compositeFetch fetch; -- cgit v1.2.1 From 81d66588587e506781a91e7378b39f728202b317 Mon Sep 17 00:00:00 2001 From: David Reveman Date: Sat, 11 Sep 2004 19:33:23 +0000 Subject: Byte-order fix --- pixman/ChangeLog | 5 +++++ pixman/configure.in | 2 ++ pixman/src/icint.h | 13 +++++++++++++ 3 files changed, 20 insertions(+) diff --git a/pixman/ChangeLog b/pixman/ChangeLog index 34d3f90ce..1c4894292 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -1,5 +1,10 @@ 2004-09-12 David Reveman + * src/icint.h: Include "../config.h". + Define IMAGE_BYTE_ORDER and BITMAP_BIT_ORDER correctly. + + * configure.in: Added AC_C_BIGENDIAN. + * src/ic.c (pixman_composite): * src/iccompose.c (IcFetch_transform, IcFetcha_transform): * src/icimage.h: Added support for both transform and repeat diff --git a/pixman/configure.in b/pixman/configure.in index ad312da44..4a4c17a73 100644 --- a/pixman/configure.in +++ b/pixman/configure.in @@ -35,6 +35,8 @@ AM_MAINTAINER_MODE AC_PROG_CC AM_PROG_LIBTOOL +AC_C_BIGENDIAN + dnl =========================================================================== AC_OUTPUT([ diff --git a/pixman/src/icint.h b/pixman/src/icint.h index 1f8a41629..1cc8883b3 100644 --- a/pixman/src/icint.h +++ b/pixman/src/icint.h @@ -23,6 +23,10 @@ #ifndef _ICINT_H_ #define _ICINT_H_ +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif + #include "pixman.h" #include @@ -61,7 +65,16 @@ typedef unsigned int Mask; #define LOG2_BYTES_PER_SCANLINE_PAD 2 #endif +#define LSBFirst 0 +#define MSBFirst 1 +#ifdef WORDS_BIGENDIAN +# define IMAGE_BYTE_ORDER MSBFirst +# define BITMAP_BIT_ORDER MSBFirst +#else +# define IMAGE_BYTE_ORDER LSBFirst +# define BITMAP_BIT_ORDER LSBFirst +#endif #define MAXSHORT SHRT_MAX -- cgit v1.2.1 From 1ba0de94fb774d1f3f8e082004adadfe897e285e Mon Sep 17 00:00:00 2001 From: David Reveman Date: Sat, 11 Sep 2004 19:42:40 +0000 Subject: Fixed clipping --- pixman/ChangeLog | 4 ++++ pixman/src/icimage.c | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/pixman/ChangeLog b/pixman/ChangeLog index 1c4894292..f15e54de7 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -1,5 +1,9 @@ 2004-09-12 David Reveman + * src/icimage.c (pixman_image_set_clip_region): Make a copy of + the client owned region. + (IcComputeCompositeRegion): Intersect possible client region. + * src/icint.h: Include "../config.h". Define IMAGE_BYTE_ORDER and BITMAP_BIT_ORDER correctly. diff --git a/pixman/src/icimage.c b/pixman/src/icimage.c index e1f827785..78b875a4c 100644 --- a/pixman/src/icimage.c +++ b/pixman/src/icimage.c @@ -264,7 +264,8 @@ pixman_image_set_clip_region (pixman_image_t *image, { pixman_image_destroyClip (image); if (region) { - image->clientClip = region; + image->clientClip = pixman_region_create (); + pixman_region_copy (image->clientClip, region); image->clientClipType = CT_REGION; } image->stateChanges |= CPClipMask; @@ -613,6 +614,13 @@ IcComputeCompositeRegion (pixman_region16_t *region, return 0; } } + if (iDst->clientClipType != CT_NONE) { + if (!IcClipImageReg (region, iDst->clientClip, 0, 0)) + { + pixman_region_destroy (region); + return 0; + } + } return 1; } -- cgit v1.2.1 From d0e30df8cb32550e2075efc2d1fa342fa6d8ca8b Mon Sep 17 00:00:00 2001 From: David Reveman Date: Sat, 11 Sep 2004 19:55:24 +0000 Subject: Added function for setting component alpha --- pixman/AUTHORS | 1 + pixman/ChangeLog | 6 ++++++ pixman/src/icimage.c | 9 +++++++++ pixman/src/icint.h | 1 + pixman/src/pixman.h | 6 +++++- 5 files changed, 22 insertions(+), 1 deletion(-) diff --git a/pixman/AUTHORS b/pixman/AUTHORS index d18a04119..25e3b641a 100644 --- a/pixman/AUTHORS +++ b/pixman/AUTHORS @@ -6,6 +6,7 @@ Anders Carlsson Build fixes. New accessor functions. Richard Henderson "slim" macros for better shared libraries Owen Taylor Support for both transform and repeat Keith Packard The original implementation of the compositing code. +David Reveman Byte-order and clipping fixes. Vladimir Vukicevic Bug fix. Bryan Worth Cleanups to not depend on X header files. Carl Worth General maintenance. Original port from X server code. diff --git a/pixman/ChangeLog b/pixman/ChangeLog index f15e54de7..bbb2715a6 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -1,8 +1,14 @@ 2004-09-12 David Reveman + * src/icint.h: slim_hidden_proto pixman_image_set_component_alpha. + + * src/pixman.h: Added pixman_image_set_component_alpha, making it + possible to use component alpha. + * src/icimage.c (pixman_image_set_clip_region): Make a copy of the client owned region. (IcComputeCompositeRegion): Intersect possible client region. + Added pixman_image_set_component_alpha. * src/icint.h: Include "../config.h". Define IMAGE_BYTE_ORDER and BITMAP_BIT_ORDER correctly. diff --git a/pixman/src/icimage.c b/pixman/src/icimage.c index 78b875a4c..3055b6e88 100644 --- a/pixman/src/icimage.c +++ b/pixman/src/icimage.c @@ -144,6 +144,15 @@ pixman_image_init (pixman_image_t *image) image->owns_pixels = 0; } +void +pixman_image_set_component_alpha (pixman_image_t *image, + int component_alpha) +{ + if (image) + image->componentAlpha = component_alpha; +} +slim_hidden_def(pixman_image_set_component_alpha); + int pixman_image_set_transform (pixman_image_t *image, pixman_transform_t *transform) diff --git a/pixman/src/icint.h b/pixman/src/icint.h index 1cc8883b3..b200e9e05 100644 --- a/pixman/src/icint.h +++ b/pixman/src/icint.h @@ -819,6 +819,7 @@ slim_hidden_proto(pixman_color_to_pixel) slim_hidden_proto(pixman_format_init) slim_hidden_proto(pixman_image_destroy) slim_hidden_proto(pixman_fill_rectangles) +slim_hidden_proto(pixman_image_set_component_alpha) slim_hidden_proto(pixman_image_set_repeat) slim_hidden_proto(pixman_composite) diff --git a/pixman/src/pixman.h b/pixman/src/pixman.h index 46a9a7754..4420f10df 100644 --- a/pixman/src/pixman.h +++ b/pixman/src/pixman.h @@ -54,7 +54,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************/ -/* $Id: pixman.h,v 1.13 2004-04-16 15:32:53 cworth Exp $ */ +/* $Id: pixman.h,v 1.14 2004-09-12 02:55:24 davidr Exp $ */ /* libic.h */ @@ -323,6 +323,10 @@ typedef enum { PIXMAN_FILTER_BILINEAR } pixman_filter_t; +void +pixman_image_set_component_alpha (pixman_image_t *image, + int component_alpha); + int pixman_image_set_transform (pixman_image_t *image, pixman_transform_t *transform); -- cgit v1.2.1 From 93c27d48a3783dbf318392170edfec78af42fd4f Mon Sep 17 00:00:00 2001 From: David Reveman Date: Sun, 12 Sep 2004 05:09:32 +0000 Subject: cairo_surface_t pointer to cairo_surface_set_repeat --- ChangeLog | 3 +++ src/cairo-glitz-surface.c | 2 +- src/cairo_glitz_surface.c | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8c8a43a01..b4e220004 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,9 @@ * src/cairo_glitz_surface.c (_cairo_glitz_surface_create_pattern): Pickup repeat setting when cloning surface. + (_cairo_glitz_surface_create_pattern): cairo_surface_set_repeat + likes to get a cairo_surface_t pointer not a cairo_glitz_surface_t + pointer. 2004-09-11 Carl Worth diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c index 14dc0d0cb..56d19fce2 100644 --- a/src/cairo-glitz-surface.c +++ b/src/cairo-glitz-surface.c @@ -843,7 +843,7 @@ _cairo_glitz_surface_create_pattern (void *abstract_dst, if (src == NULL) return CAIRO_STATUS_NO_MEMORY; - cairo_surface_set_repeat (src, generic_src->repeat); + cairo_surface_set_repeat (&src->base, generic_src->repeat); } else src = (cairo_glitz_surface_t *) generic_src; diff --git a/src/cairo_glitz_surface.c b/src/cairo_glitz_surface.c index 14dc0d0cb..56d19fce2 100644 --- a/src/cairo_glitz_surface.c +++ b/src/cairo_glitz_surface.c @@ -843,7 +843,7 @@ _cairo_glitz_surface_create_pattern (void *abstract_dst, if (src == NULL) return CAIRO_STATUS_NO_MEMORY; - cairo_surface_set_repeat (src, generic_src->repeat); + cairo_surface_set_repeat (&src->base, generic_src->repeat); } else src = (cairo_glitz_surface_t *) generic_src; -- cgit v1.2.1 From 3a1931baba4c453226a2d0c307352569c6b2bfab Mon Sep 17 00:00:00 2001 From: David Reveman Date: Sun, 12 Sep 2004 06:06:50 +0000 Subject: Added pixman_format_get_masks and fixed a few format issues --- pixman/AUTHORS | 2 +- pixman/ChangeLog | 9 +++++++++ pixman/src/icformat.c | 35 ++++++++++++++++++++++++++++++++++- pixman/src/icimage.c | 6 ++++++ pixman/src/pixman.h | 10 +++++++++- 5 files changed, 59 insertions(+), 3 deletions(-) diff --git a/pixman/AUTHORS b/pixman/AUTHORS index 25e3b641a..d858e59ba 100644 --- a/pixman/AUTHORS +++ b/pixman/AUTHORS @@ -6,7 +6,7 @@ Anders Carlsson Build fixes. New accessor functions. Richard Henderson "slim" macros for better shared libraries Owen Taylor Support for both transform and repeat Keith Packard The original implementation of the compositing code. -David Reveman Byte-order and clipping fixes. +David Reveman Byte-order, clipping and format fixes. Vladimir Vukicevic Bug fix. Bryan Worth Cleanups to not depend on X header files. Carl Worth General maintenance. Original port from X server code. diff --git a/pixman/ChangeLog b/pixman/ChangeLog index bbb2715a6..e9161905c 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -1,5 +1,14 @@ 2004-09-12 David Reveman + * src/icformat.c (pixman_format_init): pixman_format_init expects + that all variables not touched are zero. We need to add a memset + here to make that true. + Added pixman_format_get_masks, which allow clients to get the + masks from a format. + + * src/icimage.c: Added the implementation of pixman_image_get_format, + which was missing. + * src/icint.h: slim_hidden_proto pixman_image_set_component_alpha. * src/pixman.h: Added pixman_image_set_component_alpha, making it diff --git a/pixman/src/icformat.c b/pixman/src/icformat.c index 870fc0faa..c8a313e56 100644 --- a/pixman/src/icformat.c +++ b/pixman/src/icformat.c @@ -93,6 +93,8 @@ pixman_format_create_masks (int bpp, void pixman_format_init (pixman_format_t *format, int format_code) { + memset (format, 0, sizeof (pixman_format_t)); + /* XXX: What do we want to lodge in here? format->id = FakeClientID (0); */ @@ -142,7 +144,7 @@ pixman_format_init (pixman_format_t *format, int format_code) format->alpha = 0; format->alphaMask = Mask(PICT_FORMAT_A(format_code)); - + /* remaining fields already set to zero */ break; } @@ -154,3 +156,34 @@ pixman_format_destroy (pixman_format_t *format) { free (format); } + +void +pixman_format_get_masks (pixman_format_t *format, + int *bpp, + int *alpha_mask, + int *red_mask, + int *green_mask, + int *blue_mask) +{ + *bpp = PICT_FORMAT_BPP (format->format_code); + + if (format->alphaMask) + *alpha_mask = format->alphaMask << format->alpha; + else + *alpha_mask = 0; + + if (format->redMask) + *red_mask = format->redMask << format->red; + else + *red_mask = 0; + + if (format->greenMask) + *green_mask = format->greenMask << format->green; + else + *green_mask = 0; + + if (format->blueMask) + *blue_mask = format->blueMask << format->blue; + else + *blue_mask = 0; +} diff --git a/pixman/src/icimage.c b/pixman/src/icimage.c index 3055b6e88..6f4958f46 100644 --- a/pixman/src/icimage.c +++ b/pixman/src/icimage.c @@ -228,6 +228,12 @@ pixman_image_get_stride (pixman_image_t *image) return image->pixels->stride; } +pixman_format_t * +pixman_image_get_format (pixman_image_t *image) +{ + return &image->image_format; +} + pixman_bits_t * pixman_image_get_data (pixman_image_t *image) { diff --git a/pixman/src/pixman.h b/pixman/src/pixman.h index 4420f10df..530b98065 100644 --- a/pixman/src/pixman.h +++ b/pixman/src/pixman.h @@ -54,7 +54,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************/ -/* $Id: pixman.h,v 1.14 2004-09-12 02:55:24 davidr Exp $ */ +/* $Id: pixman.h,v 1.15 2004-09-12 13:06:50 davidr Exp $ */ /* libic.h */ @@ -239,6 +239,14 @@ pixman_format_create_masks (int bpp, void pixman_format_destroy (pixman_format_t *format); +void +pixman_format_get_masks (pixman_format_t *format, + int *bpp, + int *alpha_mask, + int *red_mask, + int *green_mask, + int *blue_mask); + /* icimage.c */ typedef struct pixman_image pixman_image_t; -- cgit v1.2.1 From 3deeb1d1784cced73d94e8274e5c1650189b85d4 Mon Sep 17 00:00:00 2001 From: David Reveman Date: Sun, 12 Sep 2004 15:34:00 +0000 Subject: Get pixel masks from pixman image format --- ChangeLog | 2 ++ src/cairo-glitz-surface.c | 27 +++++++++++---------------- src/cairo_glitz_surface.c | 27 +++++++++++---------------- 3 files changed, 24 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index b4e220004..c324a9b2f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,8 @@ (_cairo_glitz_surface_create_pattern): cairo_surface_set_repeat likes to get a cairo_surface_t pointer not a cairo_glitz_surface_t pointer. + (_cairo_glitz_surface_set_image): Get pixel masks from pixman image + format. 2004-09-11 Carl Worth diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c index 56d19fce2..a59e8d4ef 100644 --- a/src/cairo-glitz-surface.c +++ b/src/cairo-glitz-surface.c @@ -191,24 +191,19 @@ _cairo_glitz_surface_set_image (void *abstract_surface, cairo_glitz_surface_t *surface = abstract_surface; glitz_buffer_t *buffer; glitz_pixel_format_t pf; + pixman_format_t *format; + int am, rm, gm, bm; + + format = pixman_image_get_format (image->pixman_image); + if (format == NULL) + return CAIRO_STATUS_NO_MEMORY; - if (image->depth > 8) { - pf.masks.bpp = 32; - - if (surface->format->alpha_size) - pf.masks.alpha_mask = 0xff000000; - else - pf.masks.alpha_mask = 0x0; - - pf.masks.red_mask = 0xff0000; - pf.masks.green_mask = 0xff00; - pf.masks.blue_mask = 0xff; - } else { - pf.masks.bpp = 8; - pf.masks.alpha_mask = 0xff; - pf.masks.red_mask = pf.masks.green_mask = pf.masks.blue_mask = 0x0; - } + pixman_format_get_masks (format, &pf.masks.bpp, &am, &rm, &gm, &bm); + pf.masks.alpha_mask = am; + pf.masks.red_mask = rm; + pf.masks.green_mask = gm; + pf.masks.blue_mask = bm; pf.xoffset = 0; pf.skip_lines = 0; pf.bytes_per_line = (((image->width * pf.masks.bpp) / 8) + 3) & -4; diff --git a/src/cairo_glitz_surface.c b/src/cairo_glitz_surface.c index 56d19fce2..a59e8d4ef 100644 --- a/src/cairo_glitz_surface.c +++ b/src/cairo_glitz_surface.c @@ -191,24 +191,19 @@ _cairo_glitz_surface_set_image (void *abstract_surface, cairo_glitz_surface_t *surface = abstract_surface; glitz_buffer_t *buffer; glitz_pixel_format_t pf; + pixman_format_t *format; + int am, rm, gm, bm; + + format = pixman_image_get_format (image->pixman_image); + if (format == NULL) + return CAIRO_STATUS_NO_MEMORY; - if (image->depth > 8) { - pf.masks.bpp = 32; - - if (surface->format->alpha_size) - pf.masks.alpha_mask = 0xff000000; - else - pf.masks.alpha_mask = 0x0; - - pf.masks.red_mask = 0xff0000; - pf.masks.green_mask = 0xff00; - pf.masks.blue_mask = 0xff; - } else { - pf.masks.bpp = 8; - pf.masks.alpha_mask = 0xff; - pf.masks.red_mask = pf.masks.green_mask = pf.masks.blue_mask = 0x0; - } + pixman_format_get_masks (format, &pf.masks.bpp, &am, &rm, &gm, &bm); + pf.masks.alpha_mask = am; + pf.masks.red_mask = rm; + pf.masks.green_mask = gm; + pf.masks.blue_mask = bm; pf.xoffset = 0; pf.skip_lines = 0; pf.bytes_per_line = (((image->width * pf.masks.bpp) / 8) + 3) & -4; -- cgit v1.2.1 From c150ea0855428f56cc12d83f4bdafec7f1ce6ce8 Mon Sep 17 00:00:00 2001 From: David Reveman Date: Wed, 15 Sep 2004 09:55:40 +0000 Subject: Improved format handling, pixel transfers and gradients --- ChangeLog | 8 +++++ src/cairo-glitz-surface.c | 74 ++++++++++++++++++++++++++++++----------------- src/cairo_glitz_surface.c | 74 ++++++++++++++++++++++++++++++----------------- 3 files changed, 104 insertions(+), 52 deletions(-) diff --git a/ChangeLog b/ChangeLog index c324a9b2f..9b1659154 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2004-09-15 David Reveman + + * src/cairo_glitz_surface.c (_cairo_glitz_surface_set_image): Do + the scanline order conversion in cairo. + (_cairo_glitz_surface_create_pattern): Pre-multiply gradient colors. + (_cairo_glitz_surface_create_similar): Find similar formats + correctly. + 2004-09-12 David Reveman * src/cairo_glitz_surface.c (_cairo_glitz_surface_create_pattern): diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c index a59e8d4ef..bfc20065e 100644 --- a/src/cairo-glitz-surface.c +++ b/src/cairo-glitz-surface.c @@ -192,7 +192,8 @@ _cairo_glitz_surface_set_image (void *abstract_surface, glitz_buffer_t *buffer; glitz_pixel_format_t pf; pixman_format_t *format; - int am, rm, gm, bm; + int am, rm, gm, bm, y; + unsigned char *data; format = pixman_image_get_format (image->pixman_image); if (format == NULL) @@ -207,15 +208,24 @@ _cairo_glitz_surface_set_image (void *abstract_surface, pf.xoffset = 0; pf.skip_lines = 0; pf.bytes_per_line = (((image->width * pf.masks.bpp) / 8) + 3) & -4; - pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; + pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP; buffer = glitz_pixel_buffer_create (surface->surface, - image->data, + NULL, pf.bytes_per_line * image->height, GLITZ_BUFFER_HINT_STREAM_DRAW); if (!buffer) return CAIRO_STATUS_NO_MEMORY; + data = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); + + for (y = 0; y < image->height; y++) + memcpy (&data[pf.bytes_per_line * (image->height - 1 - y)], + &image->data[pf.bytes_per_line * y], + pf.bytes_per_line); + + glitz_buffer_unmap (buffer); + glitz_set_pixels (surface->surface, 0, 0, image->width, image->height, @@ -323,22 +333,6 @@ _glitz_operator (cairo_operator_t op) } } -static glitz_format_name_t -_glitz_format (cairo_format_t format) -{ - switch (format) { - case CAIRO_FORMAT_A1: - return GLITZ_STANDARD_A1; - case CAIRO_FORMAT_A8: - return GLITZ_STANDARD_A8; - case CAIRO_FORMAT_RGB24: - return GLITZ_STANDARD_RGB24; - case CAIRO_FORMAT_ARGB32: - default: - return GLITZ_STANDARD_ARGB32; - } -} - static glitz_surface_t * _glitz_surface_create_solid (glitz_surface_t *other, glitz_format_name_t format_name, @@ -373,10 +367,37 @@ _cairo_glitz_surface_create_similar (void *abstract_src, glitz_surface_t *surface; cairo_surface_t *crsurface; glitz_format_t *glitz_format; - + glitz_format_t templ; + unsigned long mask; + + mask = GLITZ_FORMAT_DRAW_OFFSCREEN_MASK; + if (drawable) { + templ.draw.offscreen = 1; + templ.multisample.samples = src->format->multisample.samples; + mask |= GLITZ_FORMAT_MULTISAMPLE_SAMPLES_MASK; + } else + templ.draw.offscreen = 0; + + switch (format) { + case CAIRO_FORMAT_A1: + case CAIRO_FORMAT_A8: + templ.alpha_size = 8; + mask |= GLITZ_FORMAT_ALPHA_SIZE_MASK; + break; + case CAIRO_FORMAT_RGB24: + templ.red_size = 8; + mask |= GLITZ_FORMAT_RED_SIZE_MASK; + break; + case CAIRO_FORMAT_ARGB32: + default: + templ.alpha_size = templ.red_size = 8; + mask |= GLITZ_FORMAT_ALPHA_SIZE_MASK; + mask |= GLITZ_FORMAT_RED_SIZE_MASK; + break; + } + glitz_format = - glitz_surface_find_similar_standard_format (src->surface, - _glitz_format (format)); + glitz_surface_find_similar_format (src->surface, mask, &templ, 0); if (glitz_format == NULL) return NULL; @@ -769,10 +790,11 @@ _cairo_glitz_surface_create_pattern (void *abstract_dst, for (i = 0; i < pattern->n_stops; i++) { glitz_color_t color; - color.red = pattern->stops[i].color_char[0] * 256; - color.green = pattern->stops[i].color_char[1] * 256; - color.blue = pattern->stops[i].color_char[2] * 256; - color.alpha = pattern->stops[i].color_char[3] * 256; + color.alpha = pattern->stops[i].color_char[3]; + color.red = pattern->stops[i].color_char[0] * color.alpha; + color.green = pattern->stops[i].color_char[1] * color.alpha; + color.blue = pattern->stops[i].color_char[2] * color.alpha; + color.alpha *= 256; glitz_set_rectangle (src->surface, &color, i, 0, 1, 1); diff --git a/src/cairo_glitz_surface.c b/src/cairo_glitz_surface.c index a59e8d4ef..bfc20065e 100644 --- a/src/cairo_glitz_surface.c +++ b/src/cairo_glitz_surface.c @@ -192,7 +192,8 @@ _cairo_glitz_surface_set_image (void *abstract_surface, glitz_buffer_t *buffer; glitz_pixel_format_t pf; pixman_format_t *format; - int am, rm, gm, bm; + int am, rm, gm, bm, y; + unsigned char *data; format = pixman_image_get_format (image->pixman_image); if (format == NULL) @@ -207,15 +208,24 @@ _cairo_glitz_surface_set_image (void *abstract_surface, pf.xoffset = 0; pf.skip_lines = 0; pf.bytes_per_line = (((image->width * pf.masks.bpp) / 8) + 3) & -4; - pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; + pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP; buffer = glitz_pixel_buffer_create (surface->surface, - image->data, + NULL, pf.bytes_per_line * image->height, GLITZ_BUFFER_HINT_STREAM_DRAW); if (!buffer) return CAIRO_STATUS_NO_MEMORY; + data = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); + + for (y = 0; y < image->height; y++) + memcpy (&data[pf.bytes_per_line * (image->height - 1 - y)], + &image->data[pf.bytes_per_line * y], + pf.bytes_per_line); + + glitz_buffer_unmap (buffer); + glitz_set_pixels (surface->surface, 0, 0, image->width, image->height, @@ -323,22 +333,6 @@ _glitz_operator (cairo_operator_t op) } } -static glitz_format_name_t -_glitz_format (cairo_format_t format) -{ - switch (format) { - case CAIRO_FORMAT_A1: - return GLITZ_STANDARD_A1; - case CAIRO_FORMAT_A8: - return GLITZ_STANDARD_A8; - case CAIRO_FORMAT_RGB24: - return GLITZ_STANDARD_RGB24; - case CAIRO_FORMAT_ARGB32: - default: - return GLITZ_STANDARD_ARGB32; - } -} - static glitz_surface_t * _glitz_surface_create_solid (glitz_surface_t *other, glitz_format_name_t format_name, @@ -373,10 +367,37 @@ _cairo_glitz_surface_create_similar (void *abstract_src, glitz_surface_t *surface; cairo_surface_t *crsurface; glitz_format_t *glitz_format; - + glitz_format_t templ; + unsigned long mask; + + mask = GLITZ_FORMAT_DRAW_OFFSCREEN_MASK; + if (drawable) { + templ.draw.offscreen = 1; + templ.multisample.samples = src->format->multisample.samples; + mask |= GLITZ_FORMAT_MULTISAMPLE_SAMPLES_MASK; + } else + templ.draw.offscreen = 0; + + switch (format) { + case CAIRO_FORMAT_A1: + case CAIRO_FORMAT_A8: + templ.alpha_size = 8; + mask |= GLITZ_FORMAT_ALPHA_SIZE_MASK; + break; + case CAIRO_FORMAT_RGB24: + templ.red_size = 8; + mask |= GLITZ_FORMAT_RED_SIZE_MASK; + break; + case CAIRO_FORMAT_ARGB32: + default: + templ.alpha_size = templ.red_size = 8; + mask |= GLITZ_FORMAT_ALPHA_SIZE_MASK; + mask |= GLITZ_FORMAT_RED_SIZE_MASK; + break; + } + glitz_format = - glitz_surface_find_similar_standard_format (src->surface, - _glitz_format (format)); + glitz_surface_find_similar_format (src->surface, mask, &templ, 0); if (glitz_format == NULL) return NULL; @@ -769,10 +790,11 @@ _cairo_glitz_surface_create_pattern (void *abstract_dst, for (i = 0; i < pattern->n_stops; i++) { glitz_color_t color; - color.red = pattern->stops[i].color_char[0] * 256; - color.green = pattern->stops[i].color_char[1] * 256; - color.blue = pattern->stops[i].color_char[2] * 256; - color.alpha = pattern->stops[i].color_char[3] * 256; + color.alpha = pattern->stops[i].color_char[3]; + color.red = pattern->stops[i].color_char[0] * color.alpha; + color.green = pattern->stops[i].color_char[1] * color.alpha; + color.blue = pattern->stops[i].color_char[2] * color.alpha; + color.alpha *= 256; glitz_set_rectangle (src->surface, &color, i, 0, 1, 1); -- cgit v1.2.1 From 96dfd5db6488f4b649c429471da14362c7697503 Mon Sep 17 00:00:00 2001 From: David Reveman Date: Sun, 19 Sep 2004 22:11:04 +0000 Subject: Important fixes to glitz format handling --- ChangeLog | 11 +++++++++++ src/cairo-glitz-surface.c | 29 ++++++++++++++++++++--------- src/cairo_glitz_surface.c | 29 ++++++++++++++++++++--------- 3 files changed, 51 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9b1659154..b8cbad741 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2004-09-20 David Reveman + + * src/cairo_glitz_surface.c (_cairo_glitz_surface_create_similar): + Make sure that only offscreen formats are picked. + (_cairo_glitz_surface_create_similar): Only try to find offscreen + multi-sample format if offscreen multi-sampling is supported. + (_cairo_glitz_surface_create_similar): If we can't find a drawable + format try to pick a non-drawable format. + (_cairo_glitz_surface_composite): Mask clone should be in + CAIRO_FORMAT_A8 format. + 2004-09-15 David Reveman * src/cairo_glitz_surface.c (_cairo_glitz_surface_set_image): Do diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c index bfc20065e..2fcf6837d 100644 --- a/src/cairo-glitz-surface.c +++ b/src/cairo-glitz-surface.c @@ -369,15 +369,21 @@ _cairo_glitz_surface_create_similar (void *abstract_src, glitz_format_t *glitz_format; glitz_format_t templ; unsigned long mask; - - mask = GLITZ_FORMAT_DRAW_OFFSCREEN_MASK; + + templ.read.offscreen = 1; + mask = GLITZ_FORMAT_READ_OFFSCREEN_MASK; + if (drawable) { templ.draw.offscreen = 1; - templ.multisample.samples = src->format->multisample.samples; - mask |= GLITZ_FORMAT_MULTISAMPLE_SAMPLES_MASK; + if (src->features & GLITZ_FEATURE_OFFSCREEN_MULTISAMPLE_MASK) { + templ.multisample.samples = src->format->multisample.samples; + mask |= GLITZ_FORMAT_MULTISAMPLE_SAMPLES_MASK; + } } else templ.draw.offscreen = 0; + mask |= GLITZ_FORMAT_DRAW_OFFSCREEN_MASK; + switch (format) { case CAIRO_FORMAT_A1: case CAIRO_FORMAT_A8: @@ -398,9 +404,14 @@ _cairo_glitz_surface_create_similar (void *abstract_src, glitz_format = glitz_surface_find_similar_format (src->surface, mask, &templ, 0); - if (glitz_format == NULL) - return NULL; - + if (glitz_format == NULL) { + mask &= ~GLITZ_FORMAT_DRAW_OFFSCREEN_MASK; + glitz_format = + glitz_surface_find_similar_format (src->surface, mask, &templ, 0); + if (glitz_format == NULL) + return NULL; + } + surface = glitz_surface_create_similar (src->surface, glitz_format, width, height); if (surface == NULL) @@ -513,7 +524,7 @@ _cairo_glitz_surface_composite (cairo_operator_t op, if (generic_mask && (generic_mask->backend != dst->base.backend)) { mask_clone = _cairo_glitz_surface_clone_similar (dst, generic_mask, - CAIRO_FORMAT_ARGB32); + CAIRO_FORMAT_A8); if (!mask_clone) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -746,7 +757,7 @@ _cairo_glitz_surface_create_pattern (void *abstract_dst, switch (pattern->type) { case CAIRO_PATTERN_SOLID: generic_src = - _cairo_surface_create_similar_solid (&dst->base, + _cairo_surface_create_similar_solid (abstract_dst, CAIRO_FORMAT_ARGB32, 1, 1, &pattern->color); diff --git a/src/cairo_glitz_surface.c b/src/cairo_glitz_surface.c index bfc20065e..2fcf6837d 100644 --- a/src/cairo_glitz_surface.c +++ b/src/cairo_glitz_surface.c @@ -369,15 +369,21 @@ _cairo_glitz_surface_create_similar (void *abstract_src, glitz_format_t *glitz_format; glitz_format_t templ; unsigned long mask; - - mask = GLITZ_FORMAT_DRAW_OFFSCREEN_MASK; + + templ.read.offscreen = 1; + mask = GLITZ_FORMAT_READ_OFFSCREEN_MASK; + if (drawable) { templ.draw.offscreen = 1; - templ.multisample.samples = src->format->multisample.samples; - mask |= GLITZ_FORMAT_MULTISAMPLE_SAMPLES_MASK; + if (src->features & GLITZ_FEATURE_OFFSCREEN_MULTISAMPLE_MASK) { + templ.multisample.samples = src->format->multisample.samples; + mask |= GLITZ_FORMAT_MULTISAMPLE_SAMPLES_MASK; + } } else templ.draw.offscreen = 0; + mask |= GLITZ_FORMAT_DRAW_OFFSCREEN_MASK; + switch (format) { case CAIRO_FORMAT_A1: case CAIRO_FORMAT_A8: @@ -398,9 +404,14 @@ _cairo_glitz_surface_create_similar (void *abstract_src, glitz_format = glitz_surface_find_similar_format (src->surface, mask, &templ, 0); - if (glitz_format == NULL) - return NULL; - + if (glitz_format == NULL) { + mask &= ~GLITZ_FORMAT_DRAW_OFFSCREEN_MASK; + glitz_format = + glitz_surface_find_similar_format (src->surface, mask, &templ, 0); + if (glitz_format == NULL) + return NULL; + } + surface = glitz_surface_create_similar (src->surface, glitz_format, width, height); if (surface == NULL) @@ -513,7 +524,7 @@ _cairo_glitz_surface_composite (cairo_operator_t op, if (generic_mask && (generic_mask->backend != dst->base.backend)) { mask_clone = _cairo_glitz_surface_clone_similar (dst, generic_mask, - CAIRO_FORMAT_ARGB32); + CAIRO_FORMAT_A8); if (!mask_clone) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -746,7 +757,7 @@ _cairo_glitz_surface_create_pattern (void *abstract_dst, switch (pattern->type) { case CAIRO_PATTERN_SOLID: generic_src = - _cairo_surface_create_similar_solid (&dst->base, + _cairo_surface_create_similar_solid (abstract_dst, CAIRO_FORMAT_ARGB32, 1, 1, &pattern->color); -- cgit v1.2.1 From 978e2dd0d613a6c043014b62df0c1ac7ae076581 Mon Sep 17 00:00:00 2001 From: Jamey Sharp Date: Thu, 30 Sep 2004 13:34:19 +0000 Subject: Update for minor XCB API change. --- ChangeLog | 5 +++++ src/cairo-xcb-surface.c | 2 +- src/cairo_xcb_surface.c | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index b8cbad741..865c64723 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2004-09-30 Jamey Sharp + + * src/cairo_xcb_surface.c: + Update for minor XCB API change. + 2004-09-20 David Reveman * src/cairo_glitz_surface.c (_cairo_glitz_surface_create_similar): diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c index 8389c96d5..36aa15731 100644 --- a/src/cairo-xcb-surface.c +++ b/src/cairo-xcb-surface.c @@ -485,7 +485,7 @@ _cairo_xcb_surface_set_filter (void *abstract_surface, cairo_filter_t filter) } XCBRenderSetPictureFilter(surface->dpy, surface->picture, - strlen(render_filter), 0, render_filter, NULL); + strlen(render_filter), render_filter, 0, NULL); return CAIRO_STATUS_SUCCESS; } diff --git a/src/cairo_xcb_surface.c b/src/cairo_xcb_surface.c index 8389c96d5..36aa15731 100644 --- a/src/cairo_xcb_surface.c +++ b/src/cairo_xcb_surface.c @@ -485,7 +485,7 @@ _cairo_xcb_surface_set_filter (void *abstract_surface, cairo_filter_t filter) } XCBRenderSetPictureFilter(surface->dpy, surface->picture, - strlen(render_filter), 0, render_filter, NULL); + strlen(render_filter), render_filter, 0, NULL); return CAIRO_STATUS_SUCCESS; } -- cgit v1.2.1 From 56ccb883761ff0781954705795f78b8e5a1591d4 Mon Sep 17 00:00:00 2001 From: David Reveman Date: Mon, 4 Oct 2004 04:55:46 +0000 Subject: Do not use VBOs and PBOs for immediate mode drawing --- ChangeLog | 7 +++ configure.in | 2 +- src/cairo-glitz-surface.c | 118 +++++++++++++++++++++------------------------- src/cairo_glitz_surface.c | 118 +++++++++++++++++++++------------------------- 4 files changed, 118 insertions(+), 127 deletions(-) diff --git a/ChangeLog b/ChangeLog index 865c64723..c832d5591 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2004-10-04 David Reveman + + * configure.in: Require version 0.2.3 of glitz. + + * src/cairo_glitz_surface.c: Do not use VBOs and PBOs for immediate + mode drawing. + 2004-09-30 Jamey Sharp * src/cairo_xcb_surface.c: diff --git a/configure.in b/configure.in index 49a43a84a..3415b12f4 100644 --- a/configure.in +++ b/configure.in @@ -141,7 +141,7 @@ AC_ARG_ENABLE(glitz, [use_glitz=$enableval], [use_glitz=yes]) if test "x$use_glitz" = "xyes"; then - PKG_CHECK_MODULES(GLITZ, glitz >= 0.2.2, [ + PKG_CHECK_MODULES(GLITZ, glitz >= 0.2.3, [ GLITZ_REQUIRES=glitz use_glitz=yes], [use_glitz="no (requires glitz http://freedesktop.org/software/glitz)"]) fi diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c index 2fcf6837d..8d18280be 100644 --- a/src/cairo-glitz-surface.c +++ b/src/cairo-glitz-surface.c @@ -100,7 +100,7 @@ _cairo_glitz_surface_get_image (void *abstract_surface) cairo_glitz_surface_t *surface = abstract_surface; cairo_image_surface_t *image; char *pixels; - int width, height, rowstride, size; + int width, height; cairo_format_masks_t format; glitz_buffer_t *buffer; glitz_pixel_format_t pf; @@ -136,8 +136,6 @@ _cairo_glitz_surface_get_image (void *abstract_surface) format.alpha_mask = 0xff; } - rowstride = (((width * format.bpp) / 8) + 3) & -4; - pf.masks.bpp = format.bpp; pf.masks.alpha_mask = format.alpha_mask; pf.masks.red_mask = format.red_mask; @@ -145,16 +143,14 @@ _cairo_glitz_surface_get_image (void *abstract_surface) pf.masks.blue_mask = format.blue_mask; pf.xoffset = 0; pf.skip_lines = 0; - pf.bytes_per_line = rowstride; + pf.bytes_per_line = (((width * format.bpp) / 8) + 3) & -4; pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; - size = height * rowstride; - pixels = malloc (size); + pixels = malloc (height * pf.bytes_per_line); if (!pixels) return NULL; - buffer = glitz_pixel_buffer_create (surface->surface, NULL, size, - GLITZ_BUFFER_HINT_DYNAMIC_READ); + buffer = glitz_buffer_create_for_data (pixels); if (!buffer) { free (pixels); return NULL; @@ -166,15 +162,13 @@ _cairo_glitz_surface_get_image (void *abstract_surface) &pf, buffer); - glitz_buffer_get_data (buffer, 0, size, pixels); - glitz_buffer_destroy (buffer); image = (cairo_image_surface_t *) _cairo_image_surface_create_with_masks (pixels, &format, width, height, - rowstride); + pf.bytes_per_line); _cairo_image_surface_assume_ownership_of_data (image); @@ -192,8 +186,7 @@ _cairo_glitz_surface_set_image (void *abstract_surface, glitz_buffer_t *buffer; glitz_pixel_format_t pf; pixman_format_t *format; - int am, rm, gm, bm, y; - unsigned char *data; + int am, rm, gm, bm; format = pixman_image_get_format (image->pixman_image); if (format == NULL) @@ -207,31 +200,19 @@ _cairo_glitz_surface_set_image (void *abstract_surface, pf.masks.blue_mask = bm; pf.xoffset = 0; pf.skip_lines = 0; - pf.bytes_per_line = (((image->width * pf.masks.bpp) / 8) + 3) & -4; - pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP; + pf.bytes_per_line = image->stride; + pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; - buffer = glitz_pixel_buffer_create (surface->surface, - NULL, - pf.bytes_per_line * image->height, - GLITZ_BUFFER_HINT_STREAM_DRAW); + buffer = glitz_buffer_create_for_data (image->data); if (!buffer) return CAIRO_STATUS_NO_MEMORY; - - data = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); - - for (y = 0; y < image->height; y++) - memcpy (&data[pf.bytes_per_line * (image->height - 1 - y)], - &image->data[pf.bytes_per_line * y], - pf.bytes_per_line); - - glitz_buffer_unmap (buffer); - + glitz_set_pixels (surface->surface, 0, 0, image->width, image->height, &pf, buffer); - + glitz_buffer_destroy (buffer); return CAIRO_STATUS_SUCCESS; @@ -567,12 +548,12 @@ _cairo_glitz_surface_fill_rectangles (void *abstract_dst, if (op != CAIRO_OPERATOR_SRC) { glitz_surface_t *solid; - glitz_float_t *data; + glitz_float_t *vertices; glitz_buffer_t *buffer; glitz_geometry_format_t gf; cairo_int_status_t status; - int width = 0; - int height = 0; + int width, height; + void *data; gf.mode = GLITZ_GEOMETRY_MODE_DIRECT; gf.edge_hint = GLITZ_GEOMETRY_EDGE_HINT_SHARP; @@ -581,23 +562,27 @@ _cairo_glitz_surface_fill_rectangles (void *abstract_dst, gf.first = 0; gf.count = n_rects * 4; - buffer = - glitz_geometry_buffer_create (dst->surface, NULL, - n_rects * 8 * sizeof (glitz_float_t), - GLITZ_BUFFER_HINT_STREAM_DRAW); - if (buffer == NULL) + data = malloc (n_rects * 8 * sizeof (glitz_float_t)); + if (!data) return CAIRO_STATUS_NO_MEMORY; - - data = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); + + buffer = glitz_buffer_create_for_data (data); + if (buffer == NULL) { + free (data); + return CAIRO_STATUS_NO_MEMORY; + } + + width = height = 0; + vertices = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); for (; n_rects; rects++, n_rects--) { - *data++ = (glitz_float_t) rects->x; - *data++ = (glitz_float_t) rects->y; - *data++ = (glitz_float_t) (rects->x + rects->width); - *data++ = (glitz_float_t) rects->y; - *data++ = (glitz_float_t) (rects->x + rects->width); - *data++ = (glitz_float_t) (rects->y + rects->height); - *data++ = (glitz_float_t) rects->x; - *data++ = (glitz_float_t) (rects->y + rects->height); + *vertices++ = (glitz_float_t) rects->x; + *vertices++ = (glitz_float_t) rects->y; + *vertices++ = (glitz_float_t) (rects->x + rects->width); + *vertices++ = (glitz_float_t) rects->y; + *vertices++ = (glitz_float_t) (rects->x + rects->width); + *vertices++ = (glitz_float_t) (rects->y + rects->height); + *vertices++ = (glitz_float_t) rects->x; + *vertices++ = (glitz_float_t) (rects->y + rects->height); if ((rects->x + rects->width) > width) width = rects->x + rects->width; @@ -625,6 +610,7 @@ _cairo_glitz_surface_fill_rectangles (void *abstract_dst, glitz_surface_destroy (solid); glitz_buffer_destroy (buffer); + free (data); return status; } else @@ -646,11 +632,12 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, cairo_glitz_surface_t *dst = abstract_dst; cairo_glitz_surface_t *src = (cairo_glitz_surface_t *) generic_src; glitz_surface_t *mask = NULL; - glitz_float_t *data; + glitz_float_t *vertices; glitz_buffer_t *buffer; glitz_geometry_format_t gf; cairo_int_status_t status; int x_dst, y_dst, x_rel, y_rel, width, height; + void *data; if (generic_src->backend != dst->base.backend) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -662,32 +649,36 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, gf.first = 0; gf.count = n_traps * 4; - buffer = - glitz_geometry_buffer_create (dst->surface, NULL, - n_traps * 8 * sizeof (glitz_float_t), - GLITZ_BUFFER_HINT_STREAM_DRAW); - if (buffer == NULL) + data = malloc (n_traps * 8 * sizeof (glitz_float_t)); + if (!data) return CAIRO_STATUS_NO_MEMORY; + buffer = glitz_buffer_create_for_data (data); + if (buffer == NULL) { + free (data); + return CAIRO_STATUS_NO_MEMORY; + } + x_dst = traps[0].left.p1.x >> 16; y_dst = traps[0].left.p1.y >> 16; - data = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); + vertices = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); for (; n_traps; traps++, n_traps--) { glitz_float_t top, bottom; top = GLITZ_FIXED_TO_FLOAT (traps->top); bottom = GLITZ_FIXED_TO_FLOAT (traps->bottom); - *data++ = GLITZ_FIXED_LINE_X_TO_FLOAT (traps->left, traps->top); - *data++ = top; - *data++ = GLITZ_FIXED_LINE_X_CEIL_TO_FLOAT (traps->right, traps->top); - *data++ = top; - *data++ = + *vertices++ = GLITZ_FIXED_LINE_X_TO_FLOAT (traps->left, traps->top); + *vertices++ = top; + *vertices++ = + GLITZ_FIXED_LINE_X_CEIL_TO_FLOAT (traps->right, traps->top); + *vertices++ = top; + *vertices++ = GLITZ_FIXED_LINE_X_CEIL_TO_FLOAT (traps->right, traps->bottom); - *data++ = bottom; - *data++ = GLITZ_FIXED_LINE_X_TO_FLOAT (traps->left, traps->bottom); - *data++ = bottom; + *vertices++ = bottom; + *vertices++ = GLITZ_FIXED_LINE_X_TO_FLOAT (traps->left, traps->bottom); + *vertices++ = bottom; } glitz_buffer_unmap (buffer); @@ -728,6 +719,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, glitz_surface_destroy (mask); glitz_buffer_destroy (buffer); + free (data); return status; } diff --git a/src/cairo_glitz_surface.c b/src/cairo_glitz_surface.c index 2fcf6837d..8d18280be 100644 --- a/src/cairo_glitz_surface.c +++ b/src/cairo_glitz_surface.c @@ -100,7 +100,7 @@ _cairo_glitz_surface_get_image (void *abstract_surface) cairo_glitz_surface_t *surface = abstract_surface; cairo_image_surface_t *image; char *pixels; - int width, height, rowstride, size; + int width, height; cairo_format_masks_t format; glitz_buffer_t *buffer; glitz_pixel_format_t pf; @@ -136,8 +136,6 @@ _cairo_glitz_surface_get_image (void *abstract_surface) format.alpha_mask = 0xff; } - rowstride = (((width * format.bpp) / 8) + 3) & -4; - pf.masks.bpp = format.bpp; pf.masks.alpha_mask = format.alpha_mask; pf.masks.red_mask = format.red_mask; @@ -145,16 +143,14 @@ _cairo_glitz_surface_get_image (void *abstract_surface) pf.masks.blue_mask = format.blue_mask; pf.xoffset = 0; pf.skip_lines = 0; - pf.bytes_per_line = rowstride; + pf.bytes_per_line = (((width * format.bpp) / 8) + 3) & -4; pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; - size = height * rowstride; - pixels = malloc (size); + pixels = malloc (height * pf.bytes_per_line); if (!pixels) return NULL; - buffer = glitz_pixel_buffer_create (surface->surface, NULL, size, - GLITZ_BUFFER_HINT_DYNAMIC_READ); + buffer = glitz_buffer_create_for_data (pixels); if (!buffer) { free (pixels); return NULL; @@ -166,15 +162,13 @@ _cairo_glitz_surface_get_image (void *abstract_surface) &pf, buffer); - glitz_buffer_get_data (buffer, 0, size, pixels); - glitz_buffer_destroy (buffer); image = (cairo_image_surface_t *) _cairo_image_surface_create_with_masks (pixels, &format, width, height, - rowstride); + pf.bytes_per_line); _cairo_image_surface_assume_ownership_of_data (image); @@ -192,8 +186,7 @@ _cairo_glitz_surface_set_image (void *abstract_surface, glitz_buffer_t *buffer; glitz_pixel_format_t pf; pixman_format_t *format; - int am, rm, gm, bm, y; - unsigned char *data; + int am, rm, gm, bm; format = pixman_image_get_format (image->pixman_image); if (format == NULL) @@ -207,31 +200,19 @@ _cairo_glitz_surface_set_image (void *abstract_surface, pf.masks.blue_mask = bm; pf.xoffset = 0; pf.skip_lines = 0; - pf.bytes_per_line = (((image->width * pf.masks.bpp) / 8) + 3) & -4; - pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP; + pf.bytes_per_line = image->stride; + pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; - buffer = glitz_pixel_buffer_create (surface->surface, - NULL, - pf.bytes_per_line * image->height, - GLITZ_BUFFER_HINT_STREAM_DRAW); + buffer = glitz_buffer_create_for_data (image->data); if (!buffer) return CAIRO_STATUS_NO_MEMORY; - - data = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); - - for (y = 0; y < image->height; y++) - memcpy (&data[pf.bytes_per_line * (image->height - 1 - y)], - &image->data[pf.bytes_per_line * y], - pf.bytes_per_line); - - glitz_buffer_unmap (buffer); - + glitz_set_pixels (surface->surface, 0, 0, image->width, image->height, &pf, buffer); - + glitz_buffer_destroy (buffer); return CAIRO_STATUS_SUCCESS; @@ -567,12 +548,12 @@ _cairo_glitz_surface_fill_rectangles (void *abstract_dst, if (op != CAIRO_OPERATOR_SRC) { glitz_surface_t *solid; - glitz_float_t *data; + glitz_float_t *vertices; glitz_buffer_t *buffer; glitz_geometry_format_t gf; cairo_int_status_t status; - int width = 0; - int height = 0; + int width, height; + void *data; gf.mode = GLITZ_GEOMETRY_MODE_DIRECT; gf.edge_hint = GLITZ_GEOMETRY_EDGE_HINT_SHARP; @@ -581,23 +562,27 @@ _cairo_glitz_surface_fill_rectangles (void *abstract_dst, gf.first = 0; gf.count = n_rects * 4; - buffer = - glitz_geometry_buffer_create (dst->surface, NULL, - n_rects * 8 * sizeof (glitz_float_t), - GLITZ_BUFFER_HINT_STREAM_DRAW); - if (buffer == NULL) + data = malloc (n_rects * 8 * sizeof (glitz_float_t)); + if (!data) return CAIRO_STATUS_NO_MEMORY; - - data = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); + + buffer = glitz_buffer_create_for_data (data); + if (buffer == NULL) { + free (data); + return CAIRO_STATUS_NO_MEMORY; + } + + width = height = 0; + vertices = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); for (; n_rects; rects++, n_rects--) { - *data++ = (glitz_float_t) rects->x; - *data++ = (glitz_float_t) rects->y; - *data++ = (glitz_float_t) (rects->x + rects->width); - *data++ = (glitz_float_t) rects->y; - *data++ = (glitz_float_t) (rects->x + rects->width); - *data++ = (glitz_float_t) (rects->y + rects->height); - *data++ = (glitz_float_t) rects->x; - *data++ = (glitz_float_t) (rects->y + rects->height); + *vertices++ = (glitz_float_t) rects->x; + *vertices++ = (glitz_float_t) rects->y; + *vertices++ = (glitz_float_t) (rects->x + rects->width); + *vertices++ = (glitz_float_t) rects->y; + *vertices++ = (glitz_float_t) (rects->x + rects->width); + *vertices++ = (glitz_float_t) (rects->y + rects->height); + *vertices++ = (glitz_float_t) rects->x; + *vertices++ = (glitz_float_t) (rects->y + rects->height); if ((rects->x + rects->width) > width) width = rects->x + rects->width; @@ -625,6 +610,7 @@ _cairo_glitz_surface_fill_rectangles (void *abstract_dst, glitz_surface_destroy (solid); glitz_buffer_destroy (buffer); + free (data); return status; } else @@ -646,11 +632,12 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, cairo_glitz_surface_t *dst = abstract_dst; cairo_glitz_surface_t *src = (cairo_glitz_surface_t *) generic_src; glitz_surface_t *mask = NULL; - glitz_float_t *data; + glitz_float_t *vertices; glitz_buffer_t *buffer; glitz_geometry_format_t gf; cairo_int_status_t status; int x_dst, y_dst, x_rel, y_rel, width, height; + void *data; if (generic_src->backend != dst->base.backend) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -662,32 +649,36 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, gf.first = 0; gf.count = n_traps * 4; - buffer = - glitz_geometry_buffer_create (dst->surface, NULL, - n_traps * 8 * sizeof (glitz_float_t), - GLITZ_BUFFER_HINT_STREAM_DRAW); - if (buffer == NULL) + data = malloc (n_traps * 8 * sizeof (glitz_float_t)); + if (!data) return CAIRO_STATUS_NO_MEMORY; + buffer = glitz_buffer_create_for_data (data); + if (buffer == NULL) { + free (data); + return CAIRO_STATUS_NO_MEMORY; + } + x_dst = traps[0].left.p1.x >> 16; y_dst = traps[0].left.p1.y >> 16; - data = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); + vertices = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); for (; n_traps; traps++, n_traps--) { glitz_float_t top, bottom; top = GLITZ_FIXED_TO_FLOAT (traps->top); bottom = GLITZ_FIXED_TO_FLOAT (traps->bottom); - *data++ = GLITZ_FIXED_LINE_X_TO_FLOAT (traps->left, traps->top); - *data++ = top; - *data++ = GLITZ_FIXED_LINE_X_CEIL_TO_FLOAT (traps->right, traps->top); - *data++ = top; - *data++ = + *vertices++ = GLITZ_FIXED_LINE_X_TO_FLOAT (traps->left, traps->top); + *vertices++ = top; + *vertices++ = + GLITZ_FIXED_LINE_X_CEIL_TO_FLOAT (traps->right, traps->top); + *vertices++ = top; + *vertices++ = GLITZ_FIXED_LINE_X_CEIL_TO_FLOAT (traps->right, traps->bottom); - *data++ = bottom; - *data++ = GLITZ_FIXED_LINE_X_TO_FLOAT (traps->left, traps->bottom); - *data++ = bottom; + *vertices++ = bottom; + *vertices++ = GLITZ_FIXED_LINE_X_TO_FLOAT (traps->left, traps->bottom); + *vertices++ = bottom; } glitz_buffer_unmap (buffer); @@ -728,6 +719,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, glitz_surface_destroy (mask); glitz_buffer_destroy (buffer); + free (data); return status; } -- cgit v1.2.1 From 30131aa4638f9bba6148114d3c60770592d6583b Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Fri, 8 Oct 2004 12:09:49 +0000 Subject: Add cairo_cache.c Rewrite using temporary glyph arrays New file. Remove old glyph cache code. (_cairo_font_scale) (_cairo_font_transform): Remove font-transforming code. (_cairo_font_text_extents) (_cairo_font_text_bbox) (_cairo_font_show_text) (_cairo_font_text_path): Remove text-API code. (_cairo_font_cache_key_t): New structure type. (_font_cache_hash) (_font_cache_keys_equal) (_font_cache_create_entry) (_font_cache_destroy_entry) (_font_cache_destroy_cache): New font cache code. (_global_font_cache) (_lock_global_font_cache) (_unlock_global_font_cache) (_get_global_font_cache): New global font cache. (_cairo_font_text_to_glyphs) (_cairo_glyph_cache_hash) (_cairo_glyph_cache_keys_equal) (_image_glyph_cache_create_entry) (_image_glyph_cache_destroy_entry) (_image_glyph_cache_destroy_cache): New glyph cache code. (_global_image_glyph_cache) (_cairo_lock_global_image_glyph_cache) (_cairo_unlock_global_image_glyph_cache) (_cairo_get_global_image_glyph_cache): New global glyph cache. (_cairo_font_cache_backend): New structure. (_cairo_image_cache_backend): Likewise. (_cairo_font_create): Reimplement in terms of font cache. (_cairo_font_init): Remove matrix and glyph cache related code. (_cairo_font_copy): Likewise. (_cairo_font_show_glyphs): Delegate to surface when possible. (_cairo_font_glyph_extents) (_cairo_font_glyph_bbox) (_cairo_font_glyph_path) (_cairo_font_font_extents) (_cairo_font_show_glyphs): Rename to as cairo_unscaled_font_XXX, and add scale parameter. New structure types. (_create_from_face) (_reference_font_val) (_destroy_font_val) (_create_from_library_and_pattern): New functions. (_ft_font_cache_hash) (_ft_font_cache_keys_equal) (_ft_font_cache_create_entry) (_ft_font_cache_destroy_entry) (_ft_font_cache_destroy_cache): New ft font cache code. (_global_ft_cache) (_lock_global_ft_cache) (_unlock_global_ft_cache) (_get_global_ft_cache): New global ft font cache. (_ft_font_cache_backend): New structure. (_cairo_ft_font_create): Rewrite to use cache. (_cairo_ft_font_destroy): Likewise. (_cairo_ft_font_copy): Remove. (_install_font_matrix): Rename as _install_font_scale. (_utf8_to_glyphs): Rename as _cairo_ft_font_text_to_glyphs. (_cairo_ft_font_text_to_glyphs): Use cache for metrics. (_cairo_ft_font_extents): Accept size, use scaled metrics. (_cairo_ft_font_glyph_extents) (_cairo_ft_font_glyph_bbox) (_cairo_ft_font_show_glyphs) (_cairo_ft_font_glyph_path): Modify to use size, cache. (_cairo_ft_font_text_extents) (_cairo_ft_font_text_bbox) (_cairo_ft_font_show_text) (_cairo_ft_font_text_path): Remove text-API code. (cairo_ft_font_create) (cairo_ft_font_create_for_ft_face) (cairo_ft_font_face) (cairo_ft_font_pattern): Rewrite using ft_font_val_t. Just reference font. (_cairo_gstate_fini): Finalize font matrix. (_cairo_gstate_default_matrix): Initialize font matrix. (_cairo_gstate_clip): Re-enable clipping rectangle. (_cairo_gstate_select_font) (_cairo_gstate_set_font): Set font matrix to identity. (_cairo_gstate_scale_font): Scale font matrix, not font. (_cairo_gstate_transform_font): Transform font matrix, not font. (_cairo_gstate_set_font_transform): Install as font matrix, not in font. (_build_font_scale): New helper function. (_cairo_gstate_text_to_glyphs): New function. (_cairo_gstate_current_font_extents) (_cairo_gstate_glyph_extents) (_cairo_gstate_show_glyphs) (_cairo_gstate_glyph_path): Rewrite using font matrix and size. (_cairo_gstate_text_path (_cairo_gstate_text_extents) (_cairo_gstate_show_text): Remove text-API code. Minor bug fix. (_cairo_xlib_surface_show_glyphs): New function. (_cairo_xlib_surface_backend): Add reference to new function. (glyphset_cache_t) (glyphset_cache_entry_t): New structure types. (_next_xlib_glyph): New helper function. (_xlib_glyphset_cache_create_value) (_xlib_glyphset_cache_destroy_cache) (_xlib_glyphset_cache_destroy_value) (_xlib_glyphset_cache_backend): New glyphset cache code. (_xlib_glyphset_caches) (_lock_xlib_glyphset_caches) (_unlock_xlib_glyphset_caches) (_get_glyphset_cache): New global glyphset cache. Add NULL entry for show_glyphs. Add NULL entry for show_glyphs. Add NULL entry for show_glyphs. Add NULL entry for show_glyphs. Add NULL entry for show_glyphs. New structure type. (cairo_cache_entry_base_t) (cairo_cache_arrangement_t) (cairo_cache_t): New structure types. (_cairo_cache_init) (_cairo_cache_reference) (_cairo_cache_destroy) (_cairo_cache_lookup) (_cairo_hash_string): New cache functions. (CAIRO_IMAGE_GLYPH_CACHE_MEMORY_DEFAULT) (CAIRO_XLIB_GLYPH_CACHE_MEMORY_DEFAULT) (CAIRO_FONT_CACHE_NUM_FONTS_DEFAULT) (CAIRO_FT_CACHE_NUM_FONTS_DEFAULT): New constants. (cairo_font_scale_t) (cairo_glyph_cache_key_t) (cairo_image_glyph_cache_entry_t): New structure types. (_cairo_lock_global_image_glyph_cache) (_cairo_unlock_global_image_glyph_cache) (_cairo_get_global_image_glyph_cache) (_cairo_glyph_cache_hash) (_cairo_glyph_cache_keys_equal): New functions for glyph caches. (cairo_font_backend_t): Remove text-API calls, add scale params, remove copy call. (cairo_surface_backend_t): Add show_glyphs entry. (cairo_glyph_surface_t) (cairo_glyph_surface_node_t): Remove old glyph cache structures. (cairo_unscaled_font_t): New structure type. (cairo_font): Remove glyph cache member, add pointer to unscaled. (cairo_gstate): Add font_matrix member, change to hold unscaled. (_cairo_gstate_set_font_transform) (_cairo_gstate_current_font_transform) (_cairo_gstate_text_to_glyphs): New functions. (_cairo_gstate_text_path (_cairo_gstate_text_extents) (_cairo_gstate_show_text) (_cairo_font_text_extents) (_cairo_font_text_bbox) (_cairo_font_show_text) (_cairo_font_text_path): Remove text-API code. (_cairo_font_glyph_extents) (_cairo_font_glyph_bbox) (_cairo_font_glyph_path) (_cairo_font_font_extents) (_cairo_font_show_glyphs): Add scale parameter. --- ChangeLog | 190 +++++++++ src/Makefile.am | 1 + src/cairo-cache.c | 454 ++++++++++++++++++++++ src/cairo-font.c | 659 ++++++++++++++++++------------- src/cairo-ft-font.c | 965 +++++++++++++++++++++++++++++----------------- src/cairo-glitz-surface.c | 3 +- src/cairo-gstate.c | 526 +++++++++++++------------ src/cairo-hash.c | 454 ++++++++++++++++++++++ src/cairo-image-surface.c | 3 +- src/cairo-ps-surface.c | 3 +- src/cairo-xcb-surface.c | 3 +- src/cairo-xlib-surface.c | 529 ++++++++++++++++++++++++- src/cairo.c | 53 ++- src/cairo_cache.c | 454 ++++++++++++++++++++++ src/cairo_font.c | 659 ++++++++++++++++++------------- src/cairo_ft_font.c | 965 +++++++++++++++++++++++++++++----------------- src/cairo_glitz_surface.c | 3 +- src/cairo_gstate.c | 526 +++++++++++++------------ src/cairo_image_surface.c | 3 +- src/cairo_png_surface.c | 3 +- src/cairo_ps_surface.c | 3 +- src/cairo_xcb_surface.c | 3 +- src/cairo_xlib_surface.c | 529 ++++++++++++++++++++++++- src/cairoint.h | 413 ++++++++++++-------- 24 files changed, 5485 insertions(+), 1919 deletions(-) create mode 100644 src/cairo-cache.c create mode 100644 src/cairo-hash.c create mode 100644 src/cairo_cache.c diff --git a/ChangeLog b/ChangeLog index c832d5591..6af45f52c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,193 @@ +2004-10-07 Graydon Hoare + + * src/Makefile.am (libcairo_la_SOURCES): Add cairo_cache.c + + * src/cairo.c + (cairo_text_extents) + (cairo_show_text) + (cairo_text_path): Rewrite using temporary glyph arrays + + * src/cairo_cache.c: New file. + + * src/cairo_font.c (_cairo_glyph_cache_create) + (_cairo_glyph_cache_destroy) + (_cairo_glyph_cache_reference) + (_cairo_glyph_cache_pop_last) + (_cairo_glyph_surface_init) + (_cairo_font_lookup_glyph): Remove old glyph cache code. + (_cairo_font_scale) + (_cairo_font_transform): Remove font-transforming code. + (_cairo_font_text_extents) + (_cairo_font_text_bbox) + (_cairo_font_show_text) + (_cairo_font_text_path): Remove text-API code. + (_cairo_font_cache_key_t): New structure type. + (_font_cache_hash) + (_font_cache_keys_equal) + (_font_cache_create_entry) + (_font_cache_destroy_entry) + (_font_cache_destroy_cache): New font cache code. + (_global_font_cache) + (_lock_global_font_cache) + (_unlock_global_font_cache) + (_get_global_font_cache): New global font cache. + (_cairo_font_text_to_glyphs) + (_cairo_glyph_cache_hash) + (_cairo_glyph_cache_keys_equal) + (_image_glyph_cache_create_entry) + (_image_glyph_cache_destroy_entry) + (_image_glyph_cache_destroy_cache): New glyph cache code. + (_global_image_glyph_cache) + (_cairo_lock_global_image_glyph_cache) + (_cairo_unlock_global_image_glyph_cache) + (_cairo_get_global_image_glyph_cache): New global glyph cache. + (_cairo_font_cache_backend): New structure. + (_cairo_image_cache_backend): Likewise. + (_cairo_font_create): Reimplement in terms of font cache. + (_cairo_font_init): Remove matrix and glyph cache related code. + (_cairo_font_copy): Likewise. + (_cairo_font_show_glyphs): Delegate to surface when possible. + (_cairo_font_glyph_extents) + (_cairo_font_glyph_bbox) + (_cairo_font_glyph_path) + (_cairo_font_font_extents) + (_cairo_font_show_glyphs): Rename to as cairo_unscaled_font_XXX, + and add scale parameter. + + * src/cairo_ft_font.c + (ft_cache_t) + (ft_font_val_t) + (cairo_ft_cache_key_t) + (cairo_ft_cache_entry_t): New structure types. + (_create_from_face) + (_reference_font_val) + (_destroy_font_val) + (_create_from_library_and_pattern): New functions. + (_ft_font_cache_hash) + (_ft_font_cache_keys_equal) + (_ft_font_cache_create_entry) + (_ft_font_cache_destroy_entry) + (_ft_font_cache_destroy_cache): New ft font cache code. + (_global_ft_cache) + (_lock_global_ft_cache) + (_unlock_global_ft_cache) + (_get_global_ft_cache): New global ft font cache. + (_ft_font_cache_backend): New structure. + (_cairo_ft_font_create): Rewrite to use cache. + (_cairo_ft_font_destroy): Likewise. + (_cairo_ft_font_copy): Remove. + (_install_font_matrix): Rename as _install_font_scale. + (_utf8_to_glyphs): Rename as _cairo_ft_font_text_to_glyphs. + (_cairo_ft_font_text_to_glyphs): Use cache for metrics. + (_cairo_ft_font_extents): Accept size, use scaled metrics. + (_cairo_ft_font_glyph_extents) + (_cairo_ft_font_glyph_bbox) + (_cairo_ft_font_show_glyphs) + (_cairo_ft_font_glyph_path): Modify to use size, cache. + (_cairo_ft_font_text_extents) + (_cairo_ft_font_text_bbox) + (_cairo_ft_font_show_text) + (_cairo_ft_font_text_path): Remove text-API code. + (cairo_ft_font_create) + (cairo_ft_font_create_for_ft_face) + (cairo_ft_font_face) + (cairo_ft_font_pattern): Rewrite using ft_font_val_t. + + * src/cairo_gstate.c (cairo_gstate_init_copy): Just reference font. + (_cairo_gstate_fini): Finalize font matrix. + (_cairo_gstate_default_matrix): Initialize font matrix. + (_cairo_gstate_clip): Re-enable clipping rectangle. + (_cairo_gstate_select_font) + (_cairo_gstate_set_font): Set font matrix to identity. + (_cairo_gstate_scale_font): Scale font matrix, not font. + (_cairo_gstate_transform_font): Transform font matrix, not font. + (_cairo_gstate_set_font_transform): Install as font matrix, not in font. + (_build_font_scale): New helper function. + (_cairo_gstate_text_to_glyphs): New function. + (_cairo_gstate_current_font_extents) + (_cairo_gstate_glyph_extents) + (_cairo_gstate_show_glyphs) + (_cairo_gstate_glyph_path): Rewrite using font matrix and size. + (_cairo_gstate_text_path + (_cairo_gstate_text_extents) + (_cairo_gstate_show_text): Remove text-API code. + + * src/cairo_xlib_surface.c + (_cairo_xlib_surface_set_clip_region): Minor bug fix. + (_cairo_xlib_surface_show_glyphs): New function. + (_cairo_xlib_surface_backend): Add reference to new function. + (glyphset_cache_t) + (glyphset_cache_entry_t): New structure types. + (_next_xlib_glyph): New helper function. + (_xlib_glyphset_cache_create_value) + (_xlib_glyphset_cache_destroy_cache) + (_xlib_glyphset_cache_destroy_value) + (_xlib_glyphset_cache_backend): New glyphset cache code. + (_xlib_glyphset_caches) + (_lock_xlib_glyphset_caches) + (_unlock_xlib_glyphset_caches) + (_get_glyphset_cache): New global glyphset cache. + + * src/cairo_glitz_surface.c (cairo_glitz_surface_backend): + Add NULL entry for show_glyphs. + + * src/cairo_image_surface.c (cairo_image_surface_backend): + Add NULL entry for show_glyphs. + + * src/cairo_ps_surface.c (cairo_ps_surface_backend): + Add NULL entry for show_glyphs. + + * src/cairo_png_surface.c (cairo_png_surface_backend): + Add NULL entry for show_glyphs. + + * src/cairo_xcb_surface.c (cairo_xcb_surface_backend): + Add NULL entry for show_glyphs. + + * src/cairoint.h (cairo_cache_backend_t): New structure type. + (cairo_cache_entry_base_t) + (cairo_cache_arrangement_t) + (cairo_cache_t): New structure types. + (_cairo_cache_init) + (_cairo_cache_reference) + (_cairo_cache_destroy) + (_cairo_cache_lookup) + (_cairo_hash_string): New cache functions. + (CAIRO_IMAGE_GLYPH_CACHE_MEMORY_DEFAULT) + (CAIRO_XLIB_GLYPH_CACHE_MEMORY_DEFAULT) + (CAIRO_FONT_CACHE_NUM_FONTS_DEFAULT) + (CAIRO_FT_CACHE_NUM_FONTS_DEFAULT): New constants. + (cairo_font_scale_t) + (cairo_glyph_cache_key_t) + (cairo_image_glyph_cache_entry_t): New structure types. + (_cairo_lock_global_image_glyph_cache) + (_cairo_unlock_global_image_glyph_cache) + (_cairo_get_global_image_glyph_cache) + (_cairo_glyph_cache_hash) + (_cairo_glyph_cache_keys_equal): New functions for glyph caches. + (cairo_font_backend_t): Remove text-API calls, add scale params, + remove copy call. + (cairo_surface_backend_t): Add show_glyphs entry. + (cairo_glyph_surface_t) + (cairo_glyph_surface_node_t): Remove old glyph cache structures. + (cairo_unscaled_font_t): New structure type. + (cairo_font): Remove glyph cache member, add pointer to unscaled. + (cairo_gstate): Add font_matrix member, change to hold unscaled. + (_cairo_gstate_set_font_transform) + (_cairo_gstate_current_font_transform) + (_cairo_gstate_text_to_glyphs): New functions. + (_cairo_gstate_text_path + (_cairo_gstate_text_extents) + (_cairo_gstate_show_text) + (_cairo_font_text_extents) + (_cairo_font_text_bbox) + (_cairo_font_show_text) + (_cairo_font_text_path): Remove text-API code. + (_cairo_font_glyph_extents) + (_cairo_font_glyph_bbox) + (_cairo_font_glyph_path) + (_cairo_font_font_extents) + (_cairo_font_show_glyphs): Add scale parameter. + 2004-10-04 David Reveman * configure.in: Require version 0.2.3 of glitz. diff --git a/src/Makefile.am b/src/Makefile.am index 5dfa079e5..8f5f639aa 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -31,6 +31,7 @@ XRENDER_LIBS=@XRENDER_LIBS@ libcairo_la_SOURCES = \ cairo.c \ cairo.h \ + cairo_cache.c \ cairo_color.c \ cairo_fixed.c \ cairo_font.c \ diff --git a/src/cairo-cache.c b/src/cairo-cache.c new file mode 100644 index 000000000..c5ce39935 --- /dev/null +++ b/src/cairo-cache.c @@ -0,0 +1,454 @@ +/* cairo - a vector graphics library with display and print output + * + * This file is Copyright © 2004 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is Red Hat, Inc. + * + * Contributor(s): + * Keith Packard + * Graydon Hoare + */ + +#include "cairoint.h" + +/* + * This structure, and accompanying table, is borrowed/modified from the + * file xserver/render/glyph.c in the freedesktop.org x server, with + * permission (and suggested modification of doubling sizes) by Keith + * Packard. + */ + +static cairo_cache_arrangement_t cache_arrangements [] = { + { 16, 43, 41 }, + { 32, 73, 71 }, + { 64, 151, 149 }, + { 128, 283, 281 }, + { 256, 571, 569 }, + { 512, 1153, 1151 }, + { 1024, 2269, 2267 }, + { 2048, 4519, 4517 }, + { 4096, 9013, 9011 }, + { 8192, 18043, 18041 }, + { 16384, 36109, 36107 }, + { 32768, 72091, 72089 }, + { 65536, 144409, 144407 }, + { 131072, 288361, 288359 }, + { 262144, 576883, 576881 }, + { 524288, 1153459, 1153457 }, + { 1048576, 2307163, 2307161 }, + { 2097152, 4613893, 4613891 }, + { 4194304, 9227641, 9227639 }, + { 8388608, 18455029, 18455027 }, + { 16777216, 36911011, 36911009 }, + { 33554432, 73819861, 73819859 }, + { 67108864, 147639589, 147639587 }, + { 134217728, 295279081, 295279079 }, + { 268435456, 590559793, 590559791 } +}; + +#define N_CACHE_SIZES (sizeof(cache_arrangements)/sizeof(cache_arrangements[0])) + +/* + * Entries 'e' are poiners, in one of 3 states: + * + * e == NULL: The entry has never had anything put in it + * e != DEAD_ENTRY: The entry has an active value in it currently + * e == DEAD_ENTRY: The entry *had* a value in it at some point, but the + * entry has been killed. Lookups requesting free space can + * reuse these entries; lookups requesting a precise match + * should neither return these entries nor stop searching when + * seeing these entries. + * + * We expect keys will not be destroyed frequently, so our table does not + * contain any explicit shrinking code nor any chain-coalescing code for + * entries randomly deleted by memory pressure (except during rehashing, of + * course). These assumptions are potentially bad, but they make the + * implementation straightforward. + * + * Revisit later if evidence appears that we're using excessive memory from + * a mostly-dead table. + * + * Generally you do not need to worry about freeing cache entries; the + * cache will expire entries randomly as it experiences memory pressure. + * There is currently no explicit entry-removing call, though one can be + * added easily. + * + * This table is open-addressed with double hashing. Each table size is a + * prime chosen to be a little more than double the high water mark for a + * given arrangement, so the tables should remain < 50% full. The table + * size makes for the "first" hash modulus; a second prime (2 less than the + * first prime) serves as the "second" hash modulus, which is co-prime and + * thus guarantees a complete permutation of table indices. + * + */ + +#define DEAD_ENTRY ((cairo_cache_entry_base_t *) 1) +#define NULL_ENTRY_P(cache, i) ((cache)->entries[i] == NULL) +#define DEAD_ENTRY_P(cache, i) ((cache)->entries[i] == DEAD_ENTRY) +#define LIVE_ENTRY_P(cache, i) \ + (!((NULL_ENTRY_P((cache),(i))) || (DEAD_ENTRY_P((cache),(i))))) + +#ifdef CAIRO_DO_SANITY_CHECKING +#include +static void +_cache_sane_state (cairo_cache_t *cache) +{ + assert (cache != NULL); + assert (cache->entries != NULL); + assert (cache->backend != NULL); + assert (cache->arrangement != NULL); + assert (cache->refcount > 0); + assert (cache->used_memory <= cache->max_memory); + assert (cache->live_entries <= cache->arrangement->size); +} +#else +#define _cache_sane_state(c) +#define assert(x) +#endif + +static void +_entry_destroy (cairo_cache_t *cache, unsigned long i) +{ + _cache_sane_state (cache); + + if (LIVE_ENTRY_P(cache, i)) + { + cairo_cache_entry_base_t *entry = cache->entries[i]; + assert(cache->live_entries > 0); + assert(cache->used_memory > entry->memory); + + cache->live_entries--; + cache->used_memory -= entry->memory; + cache->backend->destroy_entry (cache, entry); + cache->entries[i] = DEAD_ENTRY; + } +} + +static cairo_cache_entry_base_t ** +_cache_lookup (cairo_cache_t *cache, + void *key, + int (*predicate)(void*,void*,void*)) +{ + + cairo_cache_entry_base_t **probe; + unsigned long hash; + unsigned long table_size, i, idx, step; + + _cache_sane_state (cache); + assert (key != NULL); + + table_size = cache->arrangement->size; + hash = cache->backend->hash (cache, key); + idx = hash % table_size; + step = 0; + + for (i = 0; i < table_size; ++i) + { +#ifdef CAIRO_MEASURE_CACHE_PERFORMANCE + cache->probes++; +#endif + assert(idx < table_size); + probe = cache->entries + idx; + + /* + * There are two lookup modes: searching for a free slot and searching + * for an exact entry. + */ + + if (predicate != NULL) + { + /* We are looking up an exact entry. */ + if (*probe != NULL + && *probe != DEAD_ENTRY + && (*probe)->hashcode == hash + && predicate (cache, key, *probe)) + return probe; + } + else + { + /* We are just looking for a free slot. */ + if (*probe == NULL + || *probe == DEAD_ENTRY) + return probe; + } + + if (step == 0) { + step = hash % cache->arrangement->rehash; + if (step == 0) + step = 1; + } + + idx += step; + if (idx >= table_size) + idx -= table_size; + } + + /* + * The table should not have permitted you to get here if you were just + * looking for a free slot: there should have been room. + */ + assert(predicate != NULL); + return NULL; +} + +static cairo_cache_entry_base_t ** +_find_available_entry_for (cairo_cache_t *cache, + void *key) +{ + return _cache_lookup (cache, key, NULL); +} + +static cairo_cache_entry_base_t ** +_find_exact_live_entry_for (cairo_cache_t *cache, + void *key) +{ + return _cache_lookup (cache, key, cache->backend->keys_equal); +} + + +static cairo_cache_arrangement_t * +_find_cache_arrangement (unsigned long proposed_size) +{ + unsigned long idx; + + for (idx = 0; idx < N_CACHE_SIZES; ++idx) + if (cache_arrangements[idx].high_water_mark >= proposed_size) + return &cache_arrangements[idx]; + return NULL; +} + +static cairo_status_t +_resize_cache (cairo_cache_t *cache, unsigned long proposed_size) +{ + cairo_cache_t tmp; + cairo_cache_entry_base_t **e; + unsigned long new_size, i; + + tmp = *cache; + tmp.arrangement = _find_cache_arrangement (proposed_size); + assert(tmp.arrangement != NULL); + if (tmp.arrangement == cache->arrangement) + return CAIRO_STATUS_SUCCESS; + + new_size = tmp.arrangement->size; + tmp.entries = calloc (new_size, sizeof (cairo_cache_entry_base_t *)); + if (tmp.entries == NULL) + return CAIRO_STATUS_NO_MEMORY; + + for (i = 0; i < cache->arrangement->size; ++i) { + if (LIVE_ENTRY_P(cache, i)) { + e = _find_available_entry_for (&tmp, cache->entries[i]); + assert (e != NULL); + *e = cache->entries[i]; + } + } + free (cache->entries); + cache->entries = tmp.entries; + cache->arrangement = tmp.arrangement; + return CAIRO_STATUS_SUCCESS; +} + + +#ifdef CAIRO_MEASURE_CACHE_PERFORMANCE +static double +_load_factor (cairo_cache_t *cache) +{ + return ((double) cache->live_entries) + / ((double) cache->arrangement->size); +} +#endif + +static unsigned long +_random_live_entry (cairo_cache_t *cache) +{ + unsigned long idx; + assert(cache != NULL); + do { + idx = rand () % cache->arrangement->size; + } while (! LIVE_ENTRY_P(cache, idx)); + return idx; +} + + +/* public API follows */ + +cairo_status_t +_cairo_cache_init (cairo_cache_t *cache, + const cairo_cache_backend_t *backend, + unsigned long max_memory) +{ + assert(backend != NULL); + + if (cache != NULL){ + cache->arrangement = &cache_arrangements[0]; + cache->refcount = 1; + cache->max_memory = max_memory; + cache->used_memory = 0; + cache->live_entries = 0; + +#ifdef CAIRO_MEASURE_CACHE_PERFORMANCE + cache->hits = 0; + cache->misses = 0; + cache->probes = 0; +#endif + + cache->backend = backend; + cache->entries = calloc (sizeof(cairo_cache_entry_base_t *), + cache->arrangement->size); + if (cache->entries == NULL) + return CAIRO_STATUS_NO_MEMORY; + } + _cache_sane_state (cache); + return CAIRO_STATUS_SUCCESS; +} + +void +_cairo_cache_reference (cairo_cache_t *cache) +{ + _cache_sane_state (cache); + cache->refcount++; +} + +void +_cairo_cache_destroy (cairo_cache_t *cache) +{ + unsigned long i; + if (cache != NULL) { + + _cache_sane_state (cache); + + if (cache->refcount-- > 0) + return; + + for (i = 0; i < cache->arrangement->size; ++i) { + _entry_destroy (cache, i); + } + + free (cache->entries); + cache->entries = NULL; + cache->backend->destroy_cache (cache); + } +} + +cairo_status_t +_cairo_cache_lookup (cairo_cache_t *cache, + void *key, + void **entry_return) +{ + + unsigned long idx; + cairo_status_t status = CAIRO_STATUS_SUCCESS; + cairo_cache_entry_base_t **slot = NULL, *new_entry; + + _cache_sane_state (cache); + +#ifdef CAIRO_MEASURE_CACHE_PERFORMANCE + if ((cache->hits + cache->misses) % 0xffff == 0) + printf("cache %p stats: size %ld, live %ld, load %.2f\n" + " mem %ld/%ld, hit %ld, miss %ld\n" + " probe %ld, %.2f probe/access\n", + cache, + cache->arrangement->size, + cache->live_entries, + _load_factor (cache), + cache->used_memory, + cache->max_memory, + cache->hits, + cache->misses, + cache->probes, + ((double) cache->probes) + / ((double) (cache->hits + + cache->misses + 1))); +#endif + + /* See if we have an entry in the table already. */ + slot = _find_exact_live_entry_for (cache, key); + if (slot != NULL) { +#ifdef CAIRO_MEASURE_CACHE_PERFORMANCE + cache->hits++; +#endif + *entry_return = *slot; + return status; + } + +#ifdef CAIRO_MEASURE_CACHE_PERFORMANCE + cache->misses++; +#endif + + /* Build the new entry. */ + status = cache->backend->create_entry (cache, key, + entry_return); + if (status != CAIRO_STATUS_SUCCESS) + return status; + + new_entry = (cairo_cache_entry_base_t *) (*entry_return); + + /* Store the hash value in case the backend forgot. */ + new_entry->hashcode = cache->backend->hash (cache, key); + + /* Make some entries die if we're under memory pressure. */ + while (cache->live_entries > 0 && + ((cache->max_memory - cache->used_memory) < new_entry->memory)) { + idx = _random_live_entry (cache); + assert (idx < cache->arrangement->size); + _entry_destroy (cache, idx); + } + + assert(cache->max_memory >= (cache->used_memory + new_entry->memory)); + + /* Make room in the table for a new slot. */ + status = _resize_cache (cache, cache->live_entries + 1); + if (status != CAIRO_STATUS_SUCCESS) { + cache->backend->destroy_entry (cache, new_entry); + *entry_return = NULL; + return status; + } + + slot = _find_available_entry_for (cache, key); + assert(slot != NULL); + + /* Store entry in slot and increment statistics. */ + *slot = new_entry; + cache->live_entries++; + cache->used_memory += new_entry->memory; + + _cache_sane_state (cache); + + return status; +} + +unsigned long +_cairo_hash_string (const char *c) +{ + /* This is the djb2 hash. */ + unsigned long hash = 5381; + while (*c) + hash = ((hash << 5) + hash) + *c++; + return hash; +} + diff --git a/src/cairo-font.c b/src/cairo-font.c index 1b356698e..c90a02bd6 100644 --- a/src/cairo-font.c +++ b/src/cairo-font.c @@ -36,20 +36,60 @@ #include "cairoint.h" -static cairo_glyph_cache_t * -_cairo_glyph_cache_create (void); -static void -_cairo_glyph_cache_destroy (cairo_glyph_cache_t *glyph_cache); +/* First we implement a global font cache for named fonts. */ + +typedef struct { + cairo_cache_entry_base_t base; + const char *family; + cairo_font_slant_t slant; + cairo_font_weight_t weight; +} cairo_font_cache_key_t; + +typedef struct { + cairo_font_cache_key_t key; + cairo_unscaled_font_t *unscaled; +} cairo_font_cache_entry_t; + +static unsigned long +_font_cache_hash (void *cache, void *key) +{ + cairo_font_cache_key_t *in; + in = (cairo_font_cache_key_t *) key; + unsigned long hash; + + /* 1607 and 1451 are just a couple random primes. */ + hash = _cairo_hash_string (in->family); + hash += ((unsigned long) in->slant) * 1607; + hash += ((unsigned long) in->weight) * 1451; + return hash; +} -static void -_cairo_glyph_cache_reference (cairo_glyph_cache_t *glyph_cache); -cairo_font_t * -_cairo_font_create (const char *family, - cairo_font_slant_t slant, - cairo_font_weight_t weight) +static int +_font_cache_keys_equal (void *cache, + void *k1, + void *k2) { + cairo_font_cache_key_t *a, *b; + a = (cairo_font_cache_key_t *) k1; + b = (cairo_font_cache_key_t *) k2; + + return (strcmp (a->family, b->family) == 0) + && (a->weight == b->weight) + && (a->slant == b->slant); +} + + +static cairo_status_t +_font_cache_create_entry (void *cache, + void *key, + void **return_value) +{ + cairo_font_cache_key_t *k; + cairo_font_cache_entry_t *entry; + k = (cairo_font_cache_key_t *) key; + const struct cairo_font_backend *backend = CAIRO_FONT_BACKEND_DEFAULT; /* XXX: The current freetype backend may return NULL, (for example @@ -58,365 +98,428 @@ _cairo_font_create (const char *family, * like to build in some sort fo font here, (even a really lame, * ugly one if necessary). */ - return backend->create (family, slant, weight); + entry = malloc (sizeof (cairo_font_cache_entry_t)); + if (entry == NULL) + goto FAIL; + + entry->key.slant = k->slant; + entry->key.weight = k->weight; + entry->key.family = strdup(k->family); + if (entry->key.family == NULL) + goto FREE_ENTRY; + + entry->unscaled = backend->create (k->family, k->slant, k->weight); + if (entry->unscaled == NULL) + goto FREE_FAMILY; + + /* Not sure how to measure backend font mem; use a simple count for now.*/ + entry->key.base.memory = 1; + *return_value = entry; + return CAIRO_STATUS_SUCCESS; + + FREE_FAMILY: + free ((void *) entry->key.family); + + FREE_ENTRY: + free (entry); + + FAIL: + return CAIRO_STATUS_NO_MEMORY; } -cairo_status_t -_cairo_font_init (cairo_font_t *font, - const struct cairo_font_backend *backend) +static void +_font_cache_destroy_entry (void *cache, + void *entry) { - cairo_matrix_set_identity (&font->matrix); - font->refcount = 1; - font->backend = backend; - font->glyph_cache = _cairo_glyph_cache_create (); - if (font->glyph_cache == NULL) - return CAIRO_STATUS_NO_MEMORY; + cairo_font_cache_entry_t *e; - return CAIRO_STATUS_SUCCESS; + e = (cairo_font_cache_entry_t *) entry; + _cairo_unscaled_font_destroy (e->unscaled); + free ((void *) e->key.family); + free (e); } -cairo_font_t * -_cairo_font_copy (cairo_font_t *font) +static void +_font_cache_destroy_cache (void *cache) { - cairo_font_t *newfont = NULL; - char *tmp = NULL; + free (cache); +} - if (font == NULL || font->backend->copy == NULL) - return NULL; - - newfont = font->backend->copy (font); - if (newfont == NULL) { - free (tmp); - return NULL; - } +const struct cairo_cache_backend cairo_font_cache_backend = { + _font_cache_hash, + _font_cache_keys_equal, + _font_cache_create_entry, + _font_cache_destroy_entry, + _font_cache_destroy_cache +}; - newfont->refcount = 1; - cairo_matrix_copy(&newfont->matrix, &font->matrix); - newfont->backend = font->backend; - if (newfont->glyph_cache) - _cairo_glyph_cache_destroy (newfont->glyph_cache); - - newfont->glyph_cache = font->glyph_cache; - _cairo_glyph_cache_reference (font->glyph_cache); - - return newfont; +static void +_lock_global_font_cache (void) +{ + /* FIXME: implement locking. */ } -cairo_status_t -_cairo_font_scale (cairo_font_t *font, double scale) +static void +_unlock_global_font_cache (void) { - return cairo_matrix_scale (&font->matrix, scale, scale); + /* FIXME: implement locking. */ } -cairo_status_t -_cairo_font_transform (cairo_font_t *font, cairo_matrix_t *matrix) +static cairo_cache_t * +_global_font_cache = NULL; + +static cairo_cache_t * +_get_global_font_cache (void) { - return cairo_matrix_multiply (&font->matrix, matrix, &font->matrix); + if (_global_font_cache == NULL) { + _global_font_cache = malloc (sizeof (cairo_cache_t)); + + if (_global_font_cache == NULL) + goto FAIL; + + if (_cairo_cache_init (_global_font_cache, + &cairo_font_cache_backend, + CAIRO_FONT_CACHE_NUM_FONTS_DEFAULT)) + goto FAIL; + } + + return _global_font_cache; + + FAIL: + if (_global_font_cache) + free (_global_font_cache); + _global_font_cache = NULL; + return NULL; } -cairo_status_t -_cairo_font_text_extents (cairo_font_t *font, - const unsigned char *utf8, - cairo_text_extents_t *extents) +/* Now the internal "unscaled + scale" font API */ + +cairo_unscaled_font_t * +_cairo_unscaled_font_create (const char *family, + cairo_font_slant_t slant, + cairo_font_weight_t weight) { - return font->backend->text_extents(font, utf8, extents); + cairo_cache_t * cache; + cairo_font_cache_key_t key; + cairo_font_cache_entry_t *font; + cairo_status_t status; + + _lock_global_font_cache (); + cache = _get_global_font_cache (); + if (cache == NULL) { + _unlock_global_font_cache (); + return NULL; + } + + key.family = family; + key.slant = slant; + key.weight = weight; + + status = _cairo_cache_lookup (cache, &key, (void **) &font); + if (status) { + _unlock_global_font_cache (); + return NULL; + } + + _cairo_unscaled_font_reference (font->unscaled); + _unlock_global_font_cache (); + return font->unscaled; } -cairo_status_t -_cairo_font_glyph_extents (cairo_font_t *font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_text_extents_t *extents) +void +_cairo_font_init (cairo_font_t *scaled, + cairo_font_scale_t *scale, + cairo_unscaled_font_t *unscaled) { - return font->backend->glyph_extents(font, glyphs, num_glyphs, extents); + scaled->scale = *scale; + scaled->unscaled = unscaled; + scaled->refcount = 1; } cairo_status_t -_cairo_font_text_bbox (cairo_font_t *font, - cairo_surface_t *surface, - double x, - double y, - const unsigned char *utf8, - cairo_box_t *bbox) +_cairo_unscaled_font_init (cairo_unscaled_font_t *font, + const struct cairo_font_backend *backend) { - return font->backend->text_bbox (font, surface, x, y, utf8, bbox); + font->refcount = 1; + font->backend = backend; + return CAIRO_STATUS_SUCCESS; } + cairo_status_t -_cairo_font_glyph_bbox (cairo_font_t *font, - cairo_surface_t *surface, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_box_t *bbox) +_cairo_unscaled_font_text_to_glyphs (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + const unsigned char *utf8, + cairo_glyph_t **glyphs, + int *num_glyphs) { - return font->backend->glyph_bbox (font, surface, glyphs, num_glyphs, bbox); + return font->backend->text_to_glyphs (font, scale, utf8, glyphs, num_glyphs); } cairo_status_t -_cairo_font_show_text (cairo_font_t *font, - cairo_operator_t operator, - cairo_surface_t *source, - cairo_surface_t *surface, - int source_x, - int source_y, - double x, - double y, - const unsigned char *utf8) +_cairo_unscaled_font_glyph_extents (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_glyph_t *glyphs, + int num_glyphs, + cairo_text_extents_t *extents) { - return font->backend->show_text(font, operator, source, - surface, source_x, source_y, x, y, utf8); + return font->backend->glyph_extents(font, scale, glyphs, num_glyphs, extents); } + cairo_status_t -_cairo_font_show_glyphs (cairo_font_t *font, - cairo_operator_t operator, - cairo_surface_t *source, - cairo_surface_t *surface, - int source_x, - int source_y, - cairo_glyph_t *glyphs, - int num_glyphs) +_cairo_unscaled_font_glyph_bbox (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_glyph_t *glyphs, + int num_glyphs, + cairo_box_t *bbox) { - return font->backend->show_glyphs(font, operator, source, - surface, source_x, source_y, - glyphs, num_glyphs); + return font->backend->glyph_bbox (font, scale, glyphs, num_glyphs, bbox); } cairo_status_t -_cairo_font_text_path (cairo_font_t *font, - double x, - double y, - const unsigned char *utf8, - cairo_path_t *path) +_cairo_unscaled_font_show_glyphs (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_operator_t operator, + cairo_surface_t *source, + cairo_surface_t *surface, + int source_x, + int source_y, + cairo_glyph_t *glyphs, + int num_glyphs) { - return font->backend->text_path(font, x, y, utf8, path); + cairo_status_t status; + if (surface->backend->show_glyphs != NULL) { + status = surface->backend->show_glyphs (font, scale, operator, source, + surface, source_x, source_y, + glyphs, num_glyphs); + if (status == CAIRO_STATUS_SUCCESS) + return status; + } + + /* Surface display routine either does not exist or failed. */ + return font->backend->show_glyphs (font, scale, operator, source, + surface, source_x, source_y, + glyphs, num_glyphs); } cairo_status_t -_cairo_font_glyph_path (cairo_font_t *font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_path_t *path) +_cairo_unscaled_font_glyph_path (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_glyph_t *glyphs, + int num_glyphs, + cairo_path_t *path) { - return font->backend->glyph_path(font, glyphs, num_glyphs, path); + return font->backend->glyph_path (font, scale, glyphs, num_glyphs, path); } cairo_status_t -_cairo_font_font_extents (cairo_font_t *font, - cairo_font_extents_t *extents) +_cairo_unscaled_font_font_extents (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_font_extents_t *extents) { - return font->backend->font_extents(font, extents); + return font->backend->font_extents(font, scale, extents); } -static void -_cairo_glyph_cache_pop_last (cairo_glyph_cache_t *glyph_cache) +void +_cairo_unscaled_font_reference (cairo_unscaled_font_t *font) { - if (glyph_cache->last) { - cairo_glyph_surface_node_t *remove = glyph_cache->last; - - cairo_surface_destroy (remove->s.surface); - glyph_cache->last = remove->prev; - if (glyph_cache->last) - glyph_cache->last->next = NULL; + font->refcount++; +} - free (remove); - glyph_cache->n_nodes--; - } +void +_cairo_unscaled_font_destroy (cairo_unscaled_font_t *font) +{ + if (--(font->refcount) > 0) + return; + + if (font->backend) + font->backend->destroy (font); } -static cairo_glyph_cache_t * -_cairo_glyph_cache_create (void) -{ - cairo_glyph_cache_t *glyph_cache; - - glyph_cache = malloc (sizeof (cairo_glyph_cache_t)); - if (glyph_cache == NULL) - return NULL; - - glyph_cache->n_nodes = 0; - glyph_cache->first = NULL; - glyph_cache->last = NULL; - glyph_cache->cache_size = CAIRO_FONT_CACHE_SIZE_DEFAULT; - glyph_cache->ref_count = 1; - return glyph_cache; + +/* Public font API follows. */ + +void +cairo_font_reference (cairo_font_t *font) +{ + font->refcount++; } -static void -_cairo_glyph_cache_reference (cairo_glyph_cache_t *glyph_cache) +void +cairo_font_destroy (cairo_font_t *font) { - if (glyph_cache == NULL) + if (--(font->refcount) > 0) return; - glyph_cache->ref_count++; + if (font->unscaled) + _cairo_unscaled_font_destroy (font->unscaled); + + free (font); } -static void -_cairo_glyph_cache_destroy (cairo_glyph_cache_t *glyph_cache) +void +cairo_font_set_transform (cairo_font_t *font, + cairo_matrix_t *matrix) { - if (glyph_cache == NULL) - return; + double dummy; + cairo_matrix_get_affine (matrix, + &font->scale.matrix[0][0], + &font->scale.matrix[0][1], + &font->scale.matrix[1][0], + &font->scale.matrix[1][1], + &dummy, &dummy); +} - glyph_cache->ref_count--; - if (glyph_cache->ref_count) - return; +void +cairo_font_current_transform (cairo_font_t *font, + cairo_matrix_t *matrix) +{ + cairo_matrix_set_affine (matrix, + font->scale.matrix[0][0], + font->scale.matrix[0][1], + font->scale.matrix[1][0], + font->scale.matrix[1][1], + 0, 0); +} - while (glyph_cache->last) - _cairo_glyph_cache_pop_last (glyph_cache); - free (glyph_cache); +/* Now we implement functions to access a default global image & metrics + * cache. + */ + +unsigned long +_cairo_glyph_cache_hash (void *cache, void *key) +{ + cairo_glyph_cache_key_t *in; + in = (cairo_glyph_cache_key_t *) key; + return + ((unsigned long) in->unscaled) + ^ ((unsigned long) in->scale.matrix[0][0]) + ^ ((unsigned long) in->scale.matrix[0][1]) + ^ ((unsigned long) in->scale.matrix[1][0]) + ^ ((unsigned long) in->scale.matrix[1][1]) + ^ in->index; } -static void -_cairo_glyph_surface_init (cairo_font_t *font, - cairo_surface_t *surface, - const cairo_glyph_t *glyph, - cairo_glyph_surface_t *glyph_surface) +int +_cairo_glyph_cache_keys_equal (void *cache, + void *k1, + void *k2) { - cairo_surface_t *image; - - glyph_surface->surface = NULL; - glyph_surface->index = glyph->index; - glyph_surface->matrix[0][0] = font->matrix.m[0][0]; - glyph_surface->matrix[0][1] = font->matrix.m[0][1]; - glyph_surface->matrix[1][0] = font->matrix.m[1][0]; - glyph_surface->matrix[1][1] = font->matrix.m[1][1]; - - image = font->backend->create_glyph (font, glyph, &glyph_surface->size); - if (image == NULL) - return; - - if (surface->backend != image->backend) { - cairo_status_t status; - - glyph_surface->surface = - _cairo_surface_create_similar_scratch (surface, - CAIRO_FORMAT_A8, 0, - glyph_surface->size.width, - glyph_surface->size.height); - if (glyph_surface->surface == NULL) { - glyph_surface->surface = image; - return; - } - - status = _cairo_surface_set_image (glyph_surface->surface, - (cairo_image_surface_t *) image); - if (status) { - cairo_surface_destroy (glyph_surface->surface); - glyph_surface->surface = NULL; - } - cairo_surface_destroy (image); - } else - glyph_surface->surface = image; + cairo_glyph_cache_key_t *a, *b; + a = (cairo_glyph_cache_key_t *) k1; + b = (cairo_glyph_cache_key_t *) k2; + return (a->index == b->index) + && (a->unscaled == b->unscaled) + && (a->scale.matrix[0][0] == b->scale.matrix[0][0]) + && (a->scale.matrix[0][1] == b->scale.matrix[0][1]) + && (a->scale.matrix[1][0] == b->scale.matrix[1][0]) + && (a->scale.matrix[1][1] == b->scale.matrix[1][1]); } -cairo_surface_t * -_cairo_font_lookup_glyph (cairo_font_t *font, - cairo_surface_t *surface, - const cairo_glyph_t *glyph, - cairo_glyph_size_t *return_size) + +static cairo_status_t +_image_glyph_cache_create_entry (void *cache, + void *key, + void **return_value) { - cairo_glyph_surface_t glyph_surface; - cairo_glyph_cache_t *cache = font->glyph_cache; - cairo_glyph_surface_node_t *node; - - for (node = cache->first; node != NULL; node = node->next) { - cairo_glyph_surface_t *s = &node->s; - - if ((s->surface == NULL || s->surface->backend == surface->backend) && - s->index == glyph->index && - s->matrix[0][0] == font->matrix.m[0][0] && - s->matrix[0][1] == font->matrix.m[0][1] && - s->matrix[1][0] == font->matrix.m[1][0] && - s->matrix[1][1] == font->matrix.m[1][1]) { - - /* move node first in cache */ - if (node->prev) { - if (node->next == NULL) { - cache->last = node->prev; - node->prev->next = NULL; - } else { - node->prev->next = node->next; - node->next->prev = node->prev; - } - - node->prev = NULL; - node->next = cache->first; - cache->first = node; - if (node->next) - node->next->prev = node; - else - cache->last = node; - } - - cairo_surface_reference (s->surface); - *return_size = s->size; - - return s->surface; - } - } - - _cairo_glyph_surface_init (font, surface, glyph, &glyph_surface); + cairo_glyph_cache_key_t *k = (cairo_glyph_cache_key_t *) key; + cairo_image_glyph_cache_entry_t *im; + cairo_status_t status; - *return_size = glyph_surface.size; - - if (cache->cache_size > 0) { - if (cache->n_nodes == cache->cache_size) - _cairo_glyph_cache_pop_last (cache); - - node = malloc (sizeof (cairo_glyph_surface_node_t)); - if (node) { - cairo_surface_reference (glyph_surface.surface); - - /* insert node first in cache */ - node->s = glyph_surface; - node->prev = NULL; - node->next = cache->first; - cache->first = node; - if (node->next) - node->next->prev = node; - else - cache->last = node; - - cache->n_nodes++; - } + im = calloc (1, sizeof (cairo_image_glyph_cache_entry_t)); + if (im == NULL) + return CAIRO_STATUS_NO_MEMORY; + + im->key = *k; + status = im->key.unscaled->backend->create_glyph (im); + + if (status != CAIRO_STATUS_SUCCESS) { + free (im); + return status; } - - return glyph_surface.surface; + + _cairo_unscaled_font_reference (im->key.unscaled); + + im->key.base.memory = + sizeof (cairo_image_glyph_cache_entry_t) + + (im->image ? + sizeof (cairo_image_surface_t) + + 28 * sizeof (int) /* rough guess at size of pixman image structure */ + + (im->image->height * im->image->stride) : 0); + + *return_value = im; + + return CAIRO_STATUS_SUCCESS; } -/* public font interface follows */ -void -cairo_font_reference (cairo_font_t *font) +static void +_image_glyph_cache_destroy_entry (void *cache, + void *value) { - font->refcount++; + cairo_image_glyph_cache_entry_t *im; + + im = (cairo_image_glyph_cache_entry_t *) value; + _cairo_unscaled_font_destroy (im->key.unscaled); + cairo_surface_destroy (&(im->image->base)); + free (im); } -void -cairo_font_destroy (cairo_font_t *font) +static void +_image_glyph_cache_destroy_cache (void *cache) { - if (--(font->refcount) > 0) - return; + free (cache); +} - _cairo_glyph_cache_destroy (font->glyph_cache); +const cairo_cache_backend_t cairo_image_cache_backend = { + _cairo_glyph_cache_hash, + _cairo_glyph_cache_keys_equal, + _image_glyph_cache_create_entry, + _image_glyph_cache_destroy_entry, + _image_glyph_cache_destroy_cache +}; - if (font->backend->destroy) - font->backend->destroy (font); -} void -cairo_font_set_transform (cairo_font_t *font, - cairo_matrix_t *matrix) +_cairo_lock_global_image_glyph_cache() { - cairo_matrix_copy (&(font->matrix), matrix); + /* FIXME: implement locking. */ } void -cairo_font_current_transform (cairo_font_t *font, - cairo_matrix_t *matrix) +_cairo_unlock_global_image_glyph_cache() { - cairo_matrix_copy (matrix, &(font->matrix)); + /* FIXME: implement locking. */ +} + +static cairo_cache_t * +_global_image_glyph_cache = NULL; + +cairo_cache_t * +_cairo_get_global_image_glyph_cache () +{ + if (_global_image_glyph_cache == NULL) { + _global_image_glyph_cache = malloc (sizeof (cairo_cache_t)); + + if (_global_image_glyph_cache == NULL) + goto FAIL; + + if (_cairo_cache_init (_global_image_glyph_cache, + &cairo_image_cache_backend, + CAIRO_IMAGE_GLYPH_CACHE_MEMORY_DEFAULT)) + goto FAIL; + } + + return _global_image_glyph_cache; + + FAIL: + if (_global_image_glyph_cache) + free (_global_image_glyph_cache); + _global_image_glyph_cache = NULL; + return NULL; } diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 5b0a7f641..740613501 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -31,116 +31,294 @@ #include FT_OUTLINE_H #include FT_IMAGE_H -typedef struct { - cairo_font_t base; +#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0)) +#define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0) +#define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0)) +#define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0) - FT_Library ft_library; - int owns_ft_library; +/* + * First we make a private, sharable implementation object which can be + * stored both in a private cache and in public font objects (including + * those connected to fonts we don't own) + */ + +typedef struct { + int refcount; FT_Face face; int owns_face; - FcPattern *pattern; -} cairo_ft_font_t; +} ft_font_val_t; -#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0)) -#define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0) -#define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0)) -#define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0) +static ft_font_val_t * +_create_from_face (FT_Face face, int owns_face) +{ + ft_font_val_t *tmp = malloc (sizeof(ft_font_val_t)); + if (tmp) { + tmp->refcount = 1; + tmp->face = face; + tmp->owns_face = owns_face; + FT_Set_Char_Size (face, + DOUBLE_TO_26_6 (1.0), + DOUBLE_TO_26_6 (1.0), + 0, 0); + } + return tmp; +} -/* implement the platform-specific interface */ +static void +_reference_font_val (ft_font_val_t *f) +{ + f->refcount++; +} -cairo_font_t * -cairo_ft_font_create (FT_Library ft_library, FcPattern *pattern) +static void +_destroy_font_val (ft_font_val_t *f) { - cairo_ft_font_t *f = NULL; + if (--(f->refcount) > 0) + return; + + if (f->owns_face) + FT_Done_Face (f->face); + + free (f); +} + +static ft_font_val_t * +_create_from_library_and_pattern (FT_Library ft_library, FcPattern *pattern) +{ + ft_font_val_t *f = NULL; char *filename = NULL; - FT_Face face = NULL; int owns_face = 0; + FT_Face face = NULL; FcPattern *resolved = NULL; FcResult result = FcResultMatch; - + + if (pattern == NULL) + goto FAIL; + FcConfigSubstitute (0, pattern, FcMatchPattern); FcDefaultSubstitute (pattern); resolved = FcFontMatch (0, pattern, &result); + if (!resolved) + goto FAIL; + if (result != FcResultMatch) - { - if (resolved) - FcPatternDestroy (resolved); - return NULL; - } + goto FREE_RESOLVED; /* If the pattern has an FT_Face object, use that. */ if (FcPatternGetFTFace (resolved, FC_FT_FACE, 0, &face) != FcResultMatch || face == NULL) { - /* otherwise it had better have a filename */ - int open_res = 0; - owns_face = 1; result = FcPatternGetString (resolved, FC_FILE, 0, (FcChar8 **)(&filename)); if (result == FcResultMatch) - open_res = FT_New_Face (ft_library, filename, 0, &face); + if (FT_New_Face (ft_library, filename, 0, &face)) + goto FREE_RESOLVED; if (face == NULL) - return NULL; + goto FREE_RESOLVED; + + owns_face = 1; } - f = (cairo_ft_font_t *) cairo_ft_font_create_for_ft_face (face); - if (f != NULL) - f->pattern = FcPatternDuplicate (resolved); + f = _create_from_face (face, owns_face); + + FcPatternDestroy (resolved); + return f; + + FREE_RESOLVED: + if (resolved) + FcPatternDestroy (resolved); + + FAIL: + return NULL; +} - f->ft_library = ft_library; - f->owns_ft_library = 0; - f->owns_face = owns_face; +/* + * We then make the user-exposed structure out of one of these impls, such + * that it is reasonably cheap to copy and/or destroy. Unfortunately this + * duplicates a certain amount of the caching machinery in the font cache, + * but that's unavoidable as we also provide an FcPattern resolution API, + * which is not part of cairo's generic font finding system. + */ - FcPatternDestroy (resolved); - return (cairo_font_t *) f; +typedef struct { + cairo_unscaled_font_t base; + FcPattern *pattern; + ft_font_val_t *val; +} cairo_ft_font_t; + +/* + * We then make a key and entry type which are compatible with the generic + * cache system. This cache serves to share single ft_font_val_t instances + * between fonts (or between font lifecycles). + */ + +typedef struct { + cairo_cache_entry_base_t base; + FcPattern *pattern; +} cairo_ft_cache_key_t; + +typedef struct { + cairo_ft_cache_key_t key; + ft_font_val_t *val; +} cairo_ft_cache_entry_t; + +/* + * Then we create a cache which maps FcPattern keys to the refcounted + * ft_font_val_t values. + */ + +typedef struct { + cairo_cache_t base; + FT_Library lib; +} ft_cache_t; + + +static unsigned long +_ft_font_cache_hash (void *cache, void *key) +{ + cairo_ft_cache_key_t *in; + in = (cairo_ft_cache_key_t *) key; + return FcPatternHash (in->pattern); } -FT_Face -cairo_ft_font_face (cairo_font_t *abstract_font) +static int +_ft_font_cache_keys_equal (void *cache, + void *k1, + void *k2) { - cairo_ft_font_t *font = (cairo_ft_font_t *) abstract_font; + cairo_ft_cache_key_t *a; + cairo_ft_cache_key_t *b; + a = (cairo_ft_cache_key_t *) k1; + b = (cairo_ft_cache_key_t *) k2; + + return FcPatternEqual (a->pattern, b->pattern); +} - if (font == NULL) - return NULL; - return font->face; +static cairo_status_t +_ft_font_cache_create_entry (void *cache, + void *key, + void **return_entry) +{ + ft_cache_t *ftcache = (ft_cache_t *) cache; + cairo_ft_cache_key_t *k = (cairo_ft_cache_key_t *) key; + cairo_ft_cache_entry_t *entry; + + entry = malloc (sizeof (cairo_ft_cache_entry_t)); + if (entry == NULL) + return CAIRO_STATUS_NO_MEMORY; + + entry->key.pattern = FcPatternDuplicate (k->pattern); + if (!entry->key.pattern) { + free (entry); + return CAIRO_STATUS_NO_MEMORY; + } + + entry->val = _create_from_library_and_pattern (ftcache->lib, entry->key.pattern); + entry->key.base.memory = 1; + + *return_entry = entry; + + return CAIRO_STATUS_SUCCESS; } -FcPattern * -cairo_ft_font_pattern (cairo_font_t *abstract_font) +static void +_ft_font_cache_destroy_entry (void *cache, + void *entry) +{ + cairo_ft_cache_entry_t *e = (cairo_ft_cache_entry_t *) entry; + FcPatternDestroy (e->key.pattern); + _destroy_font_val (e->val); + free (e); +} + +static void +_ft_font_cache_destroy_cache (void *cache) { - cairo_ft_font_t *font = (cairo_ft_font_t *) abstract_font; + ft_cache_t *fc = (ft_cache_t *) cache; + FT_Done_FreeType (fc->lib); + free (fc); +} - if (font == NULL) - return NULL; +const struct cairo_cache_backend _ft_font_cache_backend = { + _ft_font_cache_hash, + _ft_font_cache_keys_equal, + _ft_font_cache_create_entry, + _ft_font_cache_destroy_entry, + _ft_font_cache_destroy_cache +}; - return font->pattern; + +static ft_cache_t *_global_ft_cache = NULL; + +static void +_lock_global_ft_cache (void) +{ + /* FIXME: Perform locking here. */ +} + +static void +_unlock_global_ft_cache (void) +{ + /* FIXME: Perform locking here. */ +} + +static cairo_cache_t * +_get_global_ft_cache (void) +{ + if (_global_ft_cache == NULL) + { + _global_ft_cache = malloc (sizeof(ft_cache_t)); + if (!_global_ft_cache) + goto FAIL; + + if (_cairo_cache_init (&_global_ft_cache->base, + &_ft_font_cache_backend, + CAIRO_FT_CACHE_NUM_FONTS_DEFAULT)) + goto FAIL; + + if (FT_Init_FreeType (&_global_ft_cache->lib)) + goto FAIL; + } + return &_global_ft_cache->base; + + FAIL: + if (_global_ft_cache) + free (_global_ft_cache); + _global_ft_cache = NULL; + return NULL; } /* implement the backend interface */ -static cairo_font_t * +const struct cairo_font_backend cairo_ft_font_backend; + +static cairo_unscaled_font_t * _cairo_ft_font_create (const char *family, cairo_font_slant_t slant, cairo_font_weight_t weight) { - cairo_ft_font_t *ft_font = NULL; - cairo_font_t *font = NULL; - FcPattern * pat = NULL; + cairo_status_t status; + cairo_ft_font_t *font = NULL; int fcslant; int fcweight; - FT_Library ft_library; - FT_Error error; + cairo_cache_t *cache; + cairo_ft_cache_entry_t *entry; + cairo_ft_cache_key_t key; - pat = FcPatternCreate (); - if (pat == NULL) - return NULL; + key.pattern = FcPatternCreate (); + if (key.pattern == NULL) + goto FAIL; + + font = malloc (sizeof (cairo_ft_font_t)); + if (font == NULL) + goto FREE_PATTERN; switch (weight) { @@ -167,52 +345,44 @@ _cairo_ft_font_create (const char *family, break; } - FcPatternAddString (pat, FC_FAMILY, family); - FcPatternAddInteger (pat, FC_SLANT, fcslant); - FcPatternAddInteger (pat, FC_WEIGHT, fcweight); + FcPatternAddString (key.pattern, FC_FAMILY, family); + FcPatternAddInteger (key.pattern, FC_SLANT, fcslant); + FcPatternAddInteger (key.pattern, FC_WEIGHT, fcweight); - error = FT_Init_FreeType (&ft_library); - if (error) { - FcPatternDestroy (pat); - return NULL; - } + if (_cairo_unscaled_font_init (&font->base, &cairo_ft_font_backend)) + goto FREE_PATTERN; - font = cairo_ft_font_create (ft_library, pat); - if (font == NULL) - return NULL; + _lock_global_ft_cache (); + cache = _get_global_ft_cache (); + if (cache == NULL) { + _unlock_global_ft_cache (); + goto FREE_PATTERN; + } - ft_font = (cairo_ft_font_t *) font; + status = _cairo_cache_lookup (cache, &key, (void **) &entry); + _unlock_global_ft_cache (); - ft_font->owns_ft_library = 1; + if (status) + goto FREE_PATTERN; - FT_Set_Char_Size (ft_font->face, - DOUBLE_TO_26_6 (1.0), - DOUBLE_TO_26_6 (1.0), - 0, 0); - - FcPatternDestroy (pat); - return font; -} + font->pattern = FcPatternDuplicate (entry->key.pattern); + if (font->pattern == NULL) + goto FREE_PATTERN; -static cairo_font_t * -_cairo_ft_font_copy (void *abstract_font) -{ - cairo_ft_font_t * font_new = NULL; - cairo_ft_font_t * font = abstract_font; - - if (font->base.backend != &cairo_ft_font_backend) - return NULL; + font->val = entry->val; + _reference_font_val (font->val); + + return &font->base; - font_new = (cairo_ft_font_t *) cairo_ft_font_create_for_ft_face (font->face); - if (font_new == NULL) - return NULL; + FREE_PATTERN: + FcPatternDestroy (key.pattern); - if (font_new != NULL && font->pattern != NULL) - font_new->pattern = FcPatternDuplicate (font->pattern); + FAIL: + return NULL; - return (cairo_font_t *) font_new; } + static void _cairo_ft_font_destroy (void *abstract_font) { @@ -220,15 +390,11 @@ _cairo_ft_font_destroy (void *abstract_font) if (font == NULL) return; - - if (font->face != NULL && font->owns_face) - FT_Done_Face (font->face); if (font->pattern != NULL) FcPatternDestroy (font->pattern); - if (font->ft_library && font->owns_ft_library) - FT_Done_FreeType (font->ft_library); + _destroy_font_val (font->val); free (font); } @@ -268,7 +434,7 @@ _utf8_to_ucs4 (char const *utf8, } static void -_install_font_matrix(cairo_matrix_t *matrix, FT_Face face) +_install_font_scale (cairo_font_scale_t *sc, FT_Face face) { cairo_matrix_t normalized; double scale_x, scale_y; @@ -276,16 +442,20 @@ _install_font_matrix(cairo_matrix_t *matrix, FT_Face face) FT_Matrix mat; /* The font matrix has x and y "scale" components which we extract and - * use as pixel scale values. These influence the way freetype chooses - * hints, as well as selecting different bitmaps in hand-rendered - * fonts. We also copy the normalized matrix to freetype's - * transformation. + * use as character scale values. These influence the way freetype + * chooses hints, as well as selecting different bitmaps in + * hand-rendered fonts. We also copy the normalized matrix to + * freetype's transformation. */ - _cairo_matrix_compute_scale_factors (matrix, &scale_x, &scale_y); - - cairo_matrix_copy (&normalized, matrix); + cairo_matrix_set_affine (&normalized, + sc->matrix[0][0], + sc->matrix[0][1], + sc->matrix[1][0], + sc->matrix[1][1], + 0, 0); + _cairo_matrix_compute_scale_factors (&normalized, &scale_x, &scale_y); cairo_matrix_scale (&normalized, 1.0 / scale_x, 1.0 / scale_y); cairo_matrix_get_affine (&normalized, &xx /* 00 */ , &yx /* 01 */, @@ -298,21 +468,28 @@ _install_font_matrix(cairo_matrix_t *matrix, FT_Face face) mat.yy = DOUBLE_TO_16_16(yy); FT_Set_Transform(face, &mat, NULL); - FT_Set_Char_Size(face, - DOUBLE_TO_26_6(scale_x), - DOUBLE_TO_26_6(scale_y), - 0, 0); + + FT_Set_Pixel_Sizes(face, + (FT_UInt) scale_x, + (FT_UInt) scale_y); } -static int -_utf8_to_glyphs (cairo_ft_font_t *font, - const unsigned char *utf8, - double x0, - double y0, - cairo_glyph_t **glyphs, - size_t *nglyphs) +static cairo_status_t +_cairo_ft_font_text_to_glyphs (void *abstract_font, + cairo_font_scale_t *sc, + const unsigned char *utf8, + cairo_glyph_t **glyphs, + int *nglyphs) { - FT_Face face = font->face; + cairo_ft_font_t *font = abstract_font; + FT_Face face = font->val->face; + cairo_glyph_cache_key_t key; + cairo_image_glyph_cache_entry_t *val; + cairo_cache_t *cache; + + key.unscaled = &font->base; + key.scale = *sc; + double x = 0., y = 0.; size_t i; FT_ULong *ucs4 = NULL; @@ -320,56 +497,70 @@ _utf8_to_glyphs (cairo_ft_font_t *font, _utf8_to_ucs4 (utf8, &ucs4, nglyphs); if (ucs4 == NULL) - return 0; + return CAIRO_STATUS_NO_MEMORY; *glyphs = (cairo_glyph_t *) malloc ((*nglyphs) * (sizeof (cairo_glyph_t))); if (*glyphs == NULL) { free (ucs4); - return 0; + return CAIRO_STATUS_NO_MEMORY; } - _install_font_matrix (&font->base.matrix, face); + _cairo_lock_global_image_glyph_cache (); + cache = _cairo_get_global_image_glyph_cache (); + if (cache == NULL) { + _cairo_unlock_global_image_glyph_cache (); + return CAIRO_STATUS_NO_MEMORY; + } for (i = 0; i < *nglyphs; i++) { (*glyphs)[i].index = FT_Get_Char_Index (face, ucs4[i]); - (*glyphs)[i].x = x0 + x; - (*glyphs)[i].y = y0 + y; - - FT_Load_Glyph (face, (*glyphs)[i].index, FT_LOAD_DEFAULT); + (*glyphs)[i].x = x; + (*glyphs)[i].y = y; - x += DOUBLE_FROM_26_6 (face->glyph->advance.x); - y -= DOUBLE_FROM_26_6 (face->glyph->advance.y); + val = NULL; + key.index = (*glyphs)[i].index; + + if (_cairo_cache_lookup (cache, &key, (void **) &val) + != CAIRO_STATUS_SUCCESS || val == NULL) + continue; + + x += val->extents.x_advance; + y -= val->extents.y_advance; } + _cairo_unlock_global_image_glyph_cache (); free (ucs4); - return 1; + return CAIRO_STATUS_SUCCESS; } + static cairo_status_t _cairo_ft_font_font_extents (void *abstract_font, + cairo_font_scale_t *sc, cairo_font_extents_t *extents) { cairo_ft_font_t *font = abstract_font; - FT_Face face = font->face; - double scale_x, scale_y; + FT_Face face = font->val->face; + FT_Size_Metrics *metrics = &face->size->metrics; - double upm = face->units_per_EM; + _install_font_scale (sc, face); - _cairo_matrix_compute_scale_factors (&font->base.matrix, &scale_x, &scale_y); + extents->ascent = DOUBLE_FROM_26_6(metrics->ascender); + extents->descent = DOUBLE_FROM_26_6(metrics->descender); + extents->height = DOUBLE_FROM_26_6(metrics->height); + extents->max_x_advance = DOUBLE_FROM_26_6(metrics->max_advance); - extents->ascent = face->ascender / upm * scale_y; - extents->descent = face->descender / upm * scale_y; - extents->height = face->height / upm * scale_y; - extents->max_x_advance = face->max_advance_width / upm * scale_x; - extents->max_y_advance = face->max_advance_height / upm * scale_y; + /* FIXME: this doesn't do vertical layout atm. */ + extents->max_y_advance = 0.0; return CAIRO_STATUS_SUCCESS; } static cairo_status_t _cairo_ft_font_glyph_extents (void *abstract_font, + cairo_font_scale_t *sc, cairo_glyph_t *glyphs, int num_glyphs, cairo_text_extents_t *extents) @@ -379,10 +570,10 @@ _cairo_ft_font_glyph_extents (void *abstract_font, cairo_point_double_t origin; cairo_point_double_t glyph_min, glyph_max; cairo_point_double_t total_min, total_max; - FT_Error error; - FT_Face face = font->face; - FT_GlyphSlot glyph = face->glyph; - FT_Glyph_Metrics *metrics = &glyph->metrics; + + cairo_image_glyph_cache_entry_t *img = NULL; + cairo_cache_t *cache; + cairo_glyph_cache_key_t key; if (num_glyphs == 0) { @@ -399,24 +590,33 @@ _cairo_ft_font_glyph_extents (void *abstract_font, origin.x = glyphs[0].x; origin.y = glyphs[0].y; - _install_font_matrix (&font->base.matrix, face); + _cairo_lock_global_image_glyph_cache (); + cache = _cairo_get_global_image_glyph_cache (); + if (cache == NULL) { + _cairo_unlock_global_image_glyph_cache (); + return CAIRO_STATUS_NO_MEMORY; + } + + key.unscaled = &font->base; + key.scale = *sc; for (i = 0; i < num_glyphs; i++) { - error = FT_Load_Glyph (face, glyphs[i].index, FT_LOAD_DEFAULT); - /* XXX: What to do in this error case? */ - if (error) + img = NULL; + key.index = glyphs[i].index; + if (_cairo_cache_lookup (cache, &key, (void **) &img) + != CAIRO_STATUS_SUCCESS || img == NULL) continue; - + /* XXX: Need to add code here to check the font's FcPattern for FC_VERTICAL_LAYOUT and if set get vertBearingX/Y instead. This will require that cairo_ft_font_create_for_ft_face accept an FcPattern. */ - glyph_min.x = glyphs[i].x + DOUBLE_FROM_26_6 (metrics->horiBearingX); - glyph_min.y = glyphs[i].y - DOUBLE_FROM_26_6 (metrics->horiBearingY); - glyph_max.x = glyph_min.x + DOUBLE_FROM_26_6 (metrics->width); - glyph_max.y = glyph_min.y + DOUBLE_FROM_26_6 (metrics->height); + glyph_min.x = glyphs[i].x + img->extents.x_bearing; + glyph_min.y = glyphs[i].y - img->extents.y_bearing; + glyph_max.x = glyph_min.x + img->extents.width; + glyph_max.y = glyph_min.y + img->extents.height; if (i==0) { total_min = glyph_min; @@ -433,12 +633,13 @@ _cairo_ft_font_glyph_extents (void *abstract_font, total_max.y = glyph_max.y; } } + _cairo_unlock_global_image_glyph_cache (); extents->x_bearing = total_min.x - origin.x; extents->y_bearing = total_min.y - origin.y; extents->width = total_max.x - total_min.x; extents->height = total_max.y - total_min.y; - extents->x_advance = glyphs[i-1].x + DOUBLE_FROM_26_6 (metrics->horiAdvance) - origin.x; + extents->x_advance = glyphs[i-1].x + (img == NULL ? 0 : img->extents.x_advance) - origin.x; extents->y_advance = glyphs[i-1].y + 0 - origin.y; return CAIRO_STATUS_SUCCESS; @@ -446,34 +647,16 @@ _cairo_ft_font_glyph_extents (void *abstract_font, static cairo_status_t -_cairo_ft_font_text_extents (void *abstract_font, - const unsigned char *utf8, - cairo_text_extents_t *extents) -{ - cairo_ft_font_t *font = abstract_font; - cairo_glyph_t *glyphs; - size_t nglyphs; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - - if (_utf8_to_glyphs (font, utf8, 0, 0, &glyphs, &nglyphs)) - { - status = _cairo_ft_font_glyph_extents (font, glyphs, nglyphs, - extents); - free (glyphs); - } - return status; -} - -static cairo_status_t -_cairo_ft_font_glyph_bbox (void *abstract_font, - cairo_surface_t *surface, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_box_t *bbox) +_cairo_ft_font_glyph_bbox (void *abstract_font, + cairo_font_scale_t *sc, + const cairo_glyph_t *glyphs, + int num_glyphs, + cairo_box_t *bbox) { + cairo_image_glyph_cache_entry_t *img; + cairo_cache_t *cache; + cairo_glyph_cache_key_t key; cairo_ft_font_t *font = abstract_font; - cairo_surface_t *mask = NULL; - cairo_glyph_size_t size; cairo_fixed_t x1, y1, x2, y2; int i; @@ -481,22 +664,33 @@ _cairo_ft_font_glyph_bbox (void *abstract_font, bbox->p1.x = bbox->p1.y = CAIRO_MAXSHORT << 16; bbox->p2.x = bbox->p2.y = CAIRO_MINSHORT << 16; - if (font == NULL - || surface == NULL - || glyphs == NULL) + _cairo_lock_global_image_glyph_cache (); + cache = _cairo_get_global_image_glyph_cache(); + + if (cache == NULL + || font == NULL + || glyphs == NULL) { + _cairo_unlock_global_image_glyph_cache (); return CAIRO_STATUS_NO_MEMORY; + } + + key.unscaled = &font->base; + key.scale = *sc; for (i = 0; i < num_glyphs; i++) { - mask = _cairo_font_lookup_glyph (&font->base, surface, - &glyphs[i], &size); - if (mask == NULL) + + img = NULL; + key.index = glyphs[i].index; + + if (_cairo_cache_lookup (cache, &key, (void **) &img) + != CAIRO_STATUS_SUCCESS || img == NULL) continue; - x1 = _cairo_fixed_from_double (glyphs[i].x + size.x); - y1 = _cairo_fixed_from_double (glyphs[i].y - size.y); - x2 = x1 + _cairo_fixed_from_double (size.width); - y2 = y1 + _cairo_fixed_from_double (size.height); + x1 = _cairo_fixed_from_double (glyphs[i].x + img->size.x); + y1 = _cairo_fixed_from_double (glyphs[i].y - img->size.y); + x2 = x1 + _cairo_fixed_from_double (img->size.width); + y2 = y1 + _cairo_fixed_from_double (img->size.height); if (x1 < bbox->p1.x) bbox->p1.x = x1; @@ -509,117 +703,82 @@ _cairo_ft_font_glyph_bbox (void *abstract_font, if (y2 > bbox->p2.y) bbox->p2.y = y2; - - if (mask) - cairo_surface_destroy (mask); } + _cairo_unlock_global_image_glyph_cache (); return CAIRO_STATUS_SUCCESS; } -static cairo_status_t -_cairo_ft_font_text_bbox (void *abstract_font, - cairo_surface_t *surface, - double x0, - double y0, - const unsigned char *utf8, - cairo_box_t *bbox) -{ - cairo_ft_font_t *font = abstract_font; - cairo_glyph_t *glyphs; - size_t num_glyphs; - - if (_utf8_to_glyphs (font, utf8, x0, y0, &glyphs, &num_glyphs)) - { - cairo_status_t res; - res = _cairo_ft_font_glyph_bbox (font, surface, - glyphs, num_glyphs, bbox); - free (glyphs); - return res; - } - else - return CAIRO_STATUS_NO_MEMORY; -} static cairo_status_t -_cairo_ft_font_show_glyphs (void *abstract_font, - cairo_operator_t operator, - cairo_surface_t *source, - cairo_surface_t *surface, - int source_x, - int source_y, - const cairo_glyph_t *glyphs, - int num_glyphs) +_cairo_ft_font_show_glyphs (void *abstract_font, + cairo_font_scale_t *sc, + cairo_operator_t operator, + cairo_surface_t *source, + cairo_surface_t *surface, + int source_x, + int source_y, + const cairo_glyph_t *glyphs, + int num_glyphs) { + cairo_image_glyph_cache_entry_t *img; + cairo_cache_t *cache; + cairo_glyph_cache_key_t key; cairo_ft_font_t *font = abstract_font; cairo_status_t status; - cairo_surface_t *mask = NULL; - cairo_glyph_size_t size; double x, y; int i; - if (font == NULL + _cairo_lock_global_image_glyph_cache (); + cache = _cairo_get_global_image_glyph_cache(); + + if (cache == NULL + || font == NULL || source == NULL || surface == NULL - || glyphs == NULL) + || glyphs == NULL) { + _cairo_unlock_global_image_glyph_cache (); return CAIRO_STATUS_NO_MEMORY; + } + + key.unscaled = &font->base; + key.scale = *sc; for (i = 0; i < num_glyphs; i++) { - mask = _cairo_font_lookup_glyph (&font->base, surface, - &glyphs[i], &size); - if (mask == NULL) + img = NULL; + key.index = glyphs[i].index; + + if (_cairo_cache_lookup (cache, &key, (void **) &img) + != CAIRO_STATUS_SUCCESS + || img == NULL + || img->image == NULL) continue; x = glyphs[i].x; y = glyphs[i].y; - status = _cairo_surface_composite (operator, source, mask, surface, - source_x + x + size.x, - source_y + y - size.y, + status = _cairo_surface_composite (operator, source, + &(img->image->base), + surface, + source_x + x + img->size.x, + source_y + y - img->size.y, 0, 0, - x + size.x, - y - size.y, - (double) size.width, - (double) size.height); - - cairo_surface_destroy (mask); + x + img->size.x, + y - img->size.y, + (double) img->size.width, + (double) img->size.height); - if (status) + if (status) { + _cairo_unlock_global_image_glyph_cache (); return status; + } } + _cairo_unlock_global_image_glyph_cache (); return CAIRO_STATUS_SUCCESS; } -static cairo_status_t -_cairo_ft_font_show_text (void *abstract_font, - cairo_operator_t operator, - cairo_surface_t *source, - cairo_surface_t *surface, - int source_x, - int source_y, - double x0, - double y0, - const unsigned char *utf8) -{ - cairo_ft_font_t *font = abstract_font; - cairo_glyph_t *glyphs; - size_t num_glyphs; - - if (_utf8_to_glyphs (font, utf8, x0, y0, &glyphs, &num_glyphs)) - { - cairo_status_t res; - res = _cairo_ft_font_show_glyphs (font, operator, - source, surface, - source_x, source_y, - glyphs, num_glyphs); - free (glyphs); - return res; - } - else - return CAIRO_STATUS_NO_MEMORY; -} static int _move_to (FT_Vector *to, void *closure) @@ -699,10 +858,11 @@ _cubic_to (FT_Vector *control1, FT_Vector *control2, FT_Vector *to, void *closur } static cairo_status_t -_cairo_ft_font_glyph_path (void *abstract_font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_path_t *path) +_cairo_ft_font_glyph_path (void *abstract_font, + cairo_font_scale_t *sc, + cairo_glyph_t *glyphs, + int num_glyphs, + cairo_path_t *path) { int i; cairo_ft_font_t *font = abstract_font; @@ -717,8 +877,9 @@ _cairo_ft_font_glyph_path (void *abstract_font, 0, /* delta */ }; - glyph = font->face->glyph; - _install_font_matrix (&font->base.matrix, font->face); + glyph = font->val->face->glyph; + + _install_font_scale (sc, font->val->face); for (i = 0; i < num_glyphs; i++) { @@ -727,7 +888,7 @@ _cairo_ft_font_glyph_path (void *abstract_font, 0, DOUBLE_TO_16_16 (-1.0), }; - error = FT_Load_Glyph (font->face, glyphs[i].index, FT_LOAD_DEFAULT); + error = FT_Load_Glyph (font->val->face, glyphs[i].index, FT_LOAD_DEFAULT); /* XXX: What to do in this error case? */ if (error) continue; @@ -747,130 +908,218 @@ _cairo_ft_font_glyph_path (void *abstract_font, return CAIRO_STATUS_SUCCESS; } -static cairo_status_t -_cairo_ft_font_text_path (void *abstract_font, - double x, - double y, - const unsigned char *utf8, - cairo_path_t *path) -{ - cairo_ft_font_t *font = abstract_font; - cairo_glyph_t *glyphs; - size_t nglyphs; - - if (_utf8_to_glyphs (font, utf8, x, y, &glyphs, &nglyphs)) - { - cairo_status_t res; - res = _cairo_ft_font_glyph_path (font, glyphs, nglyphs, path); - free (glyphs); - return res; - } - else - return CAIRO_STATUS_NO_MEMORY; -} - -cairo_font_t * -cairo_ft_font_create_for_ft_face (FT_Face face) -{ - cairo_ft_font_t *f = NULL; - - f = malloc (sizeof (cairo_ft_font_t)); - if (f == NULL) - return NULL; - memset (f, 0, sizeof (cairo_ft_font_t)); - - _cairo_font_init (&f->base, - &cairo_ft_font_backend); - - f->ft_library = NULL; - f->owns_ft_library = 0; - - f->face = face; - f->owns_face = 0; - return (cairo_font_t *) f; -} - -static cairo_surface_t * -_cairo_ft_font_create_glyph (void *abstract_font, - const cairo_glyph_t *glyph, - cairo_glyph_size_t *return_size) +static cairo_status_t +_cairo_ft_font_create_glyph(cairo_image_glyph_cache_entry_t *val) { - cairo_ft_font_t *font = abstract_font; - cairo_image_surface_t *image; + cairo_ft_font_t *font = (cairo_ft_font_t *)val->key.unscaled; FT_GlyphSlot glyphslot; unsigned int width, height, stride; FT_Outline *outline; FT_BBox cbox; FT_Bitmap bitmap; - - glyphslot = font->face->glyph; - _install_font_matrix (&font->base.matrix, font->face); + FT_Glyph_Metrics *metrics; - FT_Load_Glyph (font->face, glyph->index, FT_LOAD_DEFAULT); + glyphslot = font->val->face->glyph; + metrics = &glyphslot->metrics; - outline = &glyphslot->outline; + _install_font_scale (&val->key.scale, font->val->face); + + if (FT_Load_Glyph (font->val->face, val->key.index, FT_LOAD_DEFAULT) != 0) + return CAIRO_STATUS_NO_MEMORY; + + val->extents.x_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingX); + val->extents.y_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingY); + val->extents.width = DOUBLE_FROM_26_6 (metrics->width); + val->extents.height = DOUBLE_FROM_26_6 (metrics->height); + val->extents.x_advance = DOUBLE_FROM_26_6 (font->val->face->glyph->advance.x); + val->extents.y_advance = DOUBLE_FROM_26_6 (font->val->face->glyph->advance.y); + outline = &glyphslot->outline; + FT_Outline_Get_CBox (outline, &cbox); cbox.xMin &= -64; cbox.yMin &= -64; cbox.xMax = (cbox.xMax + 63) & -64; cbox.yMax = (cbox.yMax + 63) & -64; - + width = (unsigned int) ((cbox.xMax - cbox.xMin) >> 6); height = (unsigned int) ((cbox.yMax - cbox.yMin) >> 6); stride = (width + 3) & -4; - bitmap.pixel_mode = ft_pixel_mode_grays; - bitmap.num_grays = 256; - bitmap.width = width; - bitmap.rows = height; - bitmap.pitch = stride; - if (width * height == 0) - return NULL; - - bitmap.buffer = malloc (stride * height); - if (bitmap.buffer == NULL) - return NULL; - - memset (bitmap.buffer, 0x0, stride * height); + val->image = NULL; + else + { - FT_Outline_Translate (outline, -cbox.xMin, -cbox.yMin); - FT_Outline_Get_Bitmap (glyphslot->library, outline, &bitmap); - - image = (cairo_image_surface_t *) + bitmap.pixel_mode = ft_pixel_mode_grays; + bitmap.num_grays = 256; + bitmap.width = width; + bitmap.rows = height; + bitmap.pitch = stride; + bitmap.buffer = calloc (1, stride * height); + + if (bitmap.buffer == NULL) { + return CAIRO_STATUS_NO_MEMORY; + }; + + FT_Outline_Translate (outline, -cbox.xMin, -cbox.yMin); + + if (FT_Outline_Get_Bitmap (glyphslot->library, outline, &bitmap) != 0) { + free (bitmap.buffer); + return CAIRO_STATUS_NO_MEMORY; + } + + val->image = (cairo_image_surface_t *) cairo_image_surface_create_for_data ((char *) bitmap.buffer, CAIRO_FORMAT_A8, width, height, stride); - if (image == NULL) { - free (bitmap.buffer); - return NULL; + if (val->image == NULL) { + free (bitmap.buffer); + return CAIRO_STATUS_NO_MEMORY; + } + + _cairo_image_surface_assume_ownership_of_data (val->image); } - - _cairo_image_surface_assume_ownership_of_data (image); - - return_size->width = (unsigned short) width; - return_size->height = (unsigned short) height; - return_size->x = (short) (cbox.xMin >> 6); - return_size->y = (short) (cbox.yMax >> 6); - return &image->base; + val->size.width = (unsigned short) width; + val->size.height = (unsigned short) height; + val->size.x = (short) (cbox.xMin >> 6); + val->size.y = (short) (cbox.yMax >> 6); + + return CAIRO_STATUS_SUCCESS; } const struct cairo_font_backend cairo_ft_font_backend = { _cairo_ft_font_create, - _cairo_ft_font_copy, _cairo_ft_font_destroy, _cairo_ft_font_font_extents, - _cairo_ft_font_text_extents, + _cairo_ft_font_text_to_glyphs, _cairo_ft_font_glyph_extents, - _cairo_ft_font_text_bbox, _cairo_ft_font_glyph_bbox, - _cairo_ft_font_show_text, _cairo_ft_font_show_glyphs, - _cairo_ft_font_text_path, _cairo_ft_font_glyph_path, _cairo_ft_font_create_glyph }; + + +/* implement the platform-specific interface */ + +cairo_font_t * +cairo_ft_font_create (FT_Library ft_library, FcPattern *pattern) +{ + cairo_font_scale_t scale; + cairo_font_t *scaled; + cairo_ft_font_t *f = NULL; + ft_font_val_t *v = NULL; + FcPattern *dup; + + scale.matrix[0][0] = 1.; + scale.matrix[0][1] = 0.; + scale.matrix[1][0] = 0.; + scale.matrix[1][1] = 1.; + + scaled = malloc (sizeof (cairo_font_t)); + if (scaled == NULL) + goto FAIL; + + dup = FcPatternDuplicate(pattern); + if (dup == NULL) + goto FREE_SCALED; + + v = _create_from_library_and_pattern (ft_library, pattern); + if (v == NULL) + goto FREE_PATTERN; + + f = malloc (sizeof(cairo_ft_font_t)); + if (f == NULL) + goto FREE_VAL; + + if (_cairo_unscaled_font_init (&f->base, &cairo_ft_font_backend)) + goto FREE_VAL; + + f->pattern = dup; + f->val = v; + + _cairo_font_init (scaled, &scale, &f->base); + + return scaled; + + FREE_VAL: + _destroy_font_val (v); + + FREE_PATTERN: + FcPatternDestroy (dup); + + FREE_SCALED: + free (scaled); + + FAIL: + return NULL; +} + +cairo_font_t * +cairo_ft_font_create_for_ft_face (FT_Face face) +{ + cairo_font_scale_t scale; + cairo_font_t *scaled; + cairo_ft_font_t *f = NULL; + ft_font_val_t *v = NULL; + + scale.matrix[0][0] = 1.; + scale.matrix[0][1] = 0.; + scale.matrix[1][0] = 0.; + scale.matrix[1][1] = 1.; + + scaled = malloc (sizeof (cairo_font_t)); + if (scaled == NULL) + goto FAIL; + + v = _create_from_face (face, 0); + if (v == NULL) + goto FREE_SCALED; + + f = malloc (sizeof(cairo_ft_font_t)); + if (f == NULL) + goto FREE_VAL; + + _cairo_unscaled_font_init (&f->base, &cairo_ft_font_backend); + f->pattern = NULL; + f->val = v; + + _cairo_font_init (scaled, &scale, &f->base); + + return scaled; + + FREE_VAL: + _destroy_font_val (v); + + FREE_SCALED: + free (scaled); + + FAIL: + return NULL; +} + +FT_Face +cairo_ft_font_face (cairo_font_t *abstract_font) +{ + cairo_ft_font_t *font = (cairo_ft_font_t *) abstract_font->unscaled; + + if (font == NULL || font->val == NULL) + return NULL; + + return font->val->face; +} + +FcPattern * +cairo_ft_font_pattern (cairo_font_t *abstract_font) +{ + cairo_ft_font_t *font = (cairo_ft_font_t *) abstract_font->unscaled; + + if (font == NULL) + return NULL; + + return font->pattern; +} diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c index 8d18280be..d351108db 100644 --- a/src/cairo-glitz-surface.c +++ b/src/cairo-glitz-surface.c @@ -900,7 +900,8 @@ static const struct cairo_surface_backend cairo_glitz_surface_backend = { _cairo_glitz_surface_copy_page, _cairo_glitz_surface_show_page, _cairo_glitz_surface_set_clip_region, - _cairo_glitz_surface_create_pattern + _cairo_glitz_surface_create_pattern, + NULL /* show_glyphs */ }; cairo_surface_t * diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index c89d63769..fabb53efd 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -77,9 +77,9 @@ _cairo_gstate_init (cairo_gstate_t *gstate) gstate->num_dashes = 0; gstate->dash_offset = 0.0; - gstate->font = _cairo_font_create (CAIRO_FONT_FAMILY_DEFAULT, - CAIRO_FONT_SLANT_DEFAULT, - CAIRO_FONT_WEIGHT_DEFAULT); + gstate->font = _cairo_unscaled_font_create (CAIRO_FONT_FAMILY_DEFAULT, + CAIRO_FONT_SLANT_DEFAULT, + CAIRO_FONT_WEIGHT_DEFAULT); gstate->surface = NULL; @@ -119,11 +119,8 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other) } if (other->font) { - gstate->font = _cairo_font_copy (other->font); - if (!gstate->font) { - status = CAIRO_STATUS_NO_MEMORY; - goto CLEANUP_DASHES; - } + gstate->font = other->font; + _cairo_unscaled_font_reference (gstate->font); } if (other->clip.region) @@ -149,9 +146,10 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other) CLEANUP_PATH: _cairo_path_fini (&gstate->path); + CLEANUP_FONT: - cairo_font_destroy (gstate->font); - CLEANUP_DASHES: + _cairo_unscaled_font_destroy (gstate->font); + free (gstate->dash); gstate->dash = NULL; @@ -161,7 +159,7 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other) void _cairo_gstate_fini (cairo_gstate_t *gstate) { - cairo_font_destroy (gstate->font); + _cairo_unscaled_font_destroy (gstate->font); if (gstate->surface) cairo_surface_destroy (gstate->surface); @@ -177,6 +175,8 @@ _cairo_gstate_fini (cairo_gstate_t *gstate) cairo_pattern_destroy (gstate->pattern); + _cairo_matrix_fini (&gstate->font_matrix); + _cairo_matrix_fini (&gstate->ctm); _cairo_matrix_fini (&gstate->ctm_inverse); @@ -627,6 +627,8 @@ _cairo_gstate_default_matrix (cairo_gstate_t *gstate) if (scale == 0) scale = 1; + cairo_matrix_set_identity (&gstate->font_matrix); + cairo_matrix_set_identity (&gstate->ctm); cairo_matrix_scale (&gstate->ctm, scale, scale); cairo_matrix_copy (&gstate->ctm_inverse, &gstate->ctm); @@ -1676,15 +1678,6 @@ extract_transformed_rectangle(cairo_matrix_t *mat, double a, b, c, d, tx, ty; cairo_status_t st; - /* XXX: Something in the rectangle-based clipping support is - * broken. See cairo_snippets/xxx_clip_rectangle which - * demonstrates no clipping at all. - * - * For now, I'm am disabling this optimization completely until it - * can be fixed. - */ - return 0; - st = cairo_matrix_get_affine (mat, &a, &b, &c, &d, &tx, &ty); if (!(st == CAIRO_STATUS_SUCCESS && b == 0. && c == 0.)) return 0; @@ -1992,16 +1985,28 @@ _cairo_gstate_show_surface (cairo_gstate_t *gstate, return CAIRO_STATUS_SUCCESS; } + cairo_status_t _cairo_gstate_select_font (cairo_gstate_t *gstate, const char *family, cairo_font_slant_t slant, cairo_font_weight_t weight) { - if (gstate->font != NULL) - cairo_font_destroy (gstate->font); + cairo_unscaled_font_t *tmp; + + tmp = _cairo_unscaled_font_create (family, slant, weight); - gstate->font = _cairo_font_create (family, slant, weight); + if (tmp == NULL) + return CAIRO_STATUS_NO_MEMORY; + + if (gstate->font != tmp) + { + if (gstate->font != NULL) + _cairo_unscaled_font_destroy (gstate->font); + + cairo_matrix_set_identity (&gstate->font_matrix); + gstate->font = tmp; + } return CAIRO_STATUS_SUCCESS; } @@ -2010,212 +2015,294 @@ cairo_status_t _cairo_gstate_scale_font (cairo_gstate_t *gstate, double scale) { - return _cairo_font_scale (gstate->font, scale); + return cairo_matrix_scale (&gstate->font_matrix, scale, scale); } cairo_status_t _cairo_gstate_transform_font (cairo_gstate_t *gstate, cairo_matrix_t *matrix) { - return _cairo_font_transform (gstate->font, matrix); + cairo_matrix_t tmp; + double a, b, c, d, tx, ty; + cairo_matrix_get_affine (matrix, &a, &b, &c, &d, &tx, &ty); + cairo_matrix_set_affine (&tmp, a, b, c, d, 0, 0); + return cairo_matrix_multiply (&gstate->font_matrix, &gstate->font_matrix, &tmp); } + cairo_status_t _cairo_gstate_current_font (cairo_gstate_t *gstate, cairo_font_t **font) { - *font = gstate->font; + cairo_font_scale_t scale; + cairo_font_t *scaled; + double dummy; + + scaled = malloc (sizeof (cairo_font_t)); + if (scaled == NULL) + return CAIRO_STATUS_NO_MEMORY; + + cairo_matrix_get_affine (&gstate->font_matrix, + &scale.matrix[0][0], + &scale.matrix[0][1], + &scale.matrix[1][0], + &scale.matrix[1][1], + &dummy, &dummy); + + _cairo_font_init (scaled, &scale, gstate->font); + _cairo_unscaled_font_reference (gstate->font); + + *font = scaled; return CAIRO_STATUS_SUCCESS; } -cairo_status_t -_cairo_gstate_current_font_extents (cairo_gstate_t *gstate, - cairo_font_extents_t *extents) +void +_cairo_gstate_set_font_transform (cairo_gstate_t *gstate, + cairo_matrix_t *matrix) { - cairo_int_status_t status; - cairo_matrix_t saved_font_matrix; - - cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix); - cairo_matrix_multiply (&gstate->font->matrix, &gstate->ctm, &gstate->font->matrix); - - status = _cairo_font_font_extents (gstate->font, extents); - - cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix); + cairo_matrix_copy (&gstate->font_matrix, matrix); +} - return status; +void +_cairo_gstate_current_font_transform (cairo_gstate_t *gstate, + cairo_matrix_t *matrix) +{ + cairo_matrix_copy (matrix, &gstate->font_matrix); } +/* + * Like everything else in this file, fonts involve Too Many Coordinate Spaces; + * it is easy to get confused about what's going on. + * + * The user's view + * --------------- + * + * Users ask for things in user space. When cairo starts, a user space unit + * is about 1/96 inch, which is similar to (but importantly different from) + * the normal "point" units most users think in terms of. When a user + * selects a font, its scale is set to "one user unit". The user can then + * independently scale the user coordinate system *or* the font matrix, in + * order to adjust the rendered size of the font. + * + * If the user asks for a permanent reference to "a font", they are given a + * handle to a structure holding a scale matrix and an unscaled font. This + * effectively decouples the font from further changes to user space. Even + * if the user then "sets" the current cairo_t font to the handle they were + * passed, further changes to the cairo_t CTM will not affect externally + * held references to the font. + * + * + * The font's view + * --------------- + * + * Fonts are designed and stored (in say .ttf files) in "font space", which + * describes an "EM Square" (a design tile) and has some abstract number + * such as 1000, 1024, or 2048 units per "EM". This is basically an + * uninteresting space for us, but we need to remember that it exists. + * + * Font resources (from libraries or operating systems) render themselves + * to a particular device. Since they do not want to make most programmers + * worry about the font design space, the scaling API is simplified to + * involve just telling the font the required pixel size of the EM square + * (that is, in device space). + * + * + * Cairo's gstate view + * ------------------- + * + * In addition to the CTM and CTM inverse, we keep a matrix in the gstate + * called the "font matrix" which describes the user's most recent + * font-scaling or font-transforming request. This is kept in terms of an + * abstract scale factor, composed with the CTM and used to set the font's + * pixel size. So if the user asks to "scale the font by 12", the matrix + * is: + * + * [ 12.0, 0.0, 0.0, 12.0, 0.0, 0.0 ] + * + * It is an affine matrix, like all cairo matrices, but its tx and ty + * components are always set to zero; we don't permit "nudging" fonts + * around. + * + * In order to perform any action on a font, we must build an object + * called a cairo_font_scale_t; this contains the central 2x2 matrix + * resulting from "font matrix * CTM". + * + * We pass this to the font when making requests of it, which causes it to + * reply for a particular [user request, device] combination, under the CTM + * (to accomodate the "zoom in" == "bigger fonts" issue above). + * + * The other terms in our communication with the font are therefore in + * device space. When we ask it to perform text->glyph conversion, it will + * produce a glyph string in device space. Glyph vectors we pass to it for + * measuring or rendering should be in device space. The metrics which we + * get back from the font will be in device space. The contents of the + * global glyph image cache will be in device space. + * + * + * Cairo's public view + * ------------------- + * + * Since the values entering and leaving via public API calls are in user + * space, the gstate functions typically need to multiply argumens by the + * CTM (for user-input glyph vectors), and return values by the CTM inverse + * (for font responses such as metrics or glyph vectors). + * + */ -cairo_status_t -_cairo_gstate_set_font (cairo_gstate_t *gstate, - cairo_font_t *font) +static void +_build_font_scale (cairo_gstate_t *gstate, + cairo_font_scale_t *sc) { - if (gstate->font != NULL) - cairo_font_destroy (gstate->font); - gstate->font = font; - cairo_font_reference (gstate->font); - return CAIRO_STATUS_SUCCESS; + cairo_matrix_t tmp; + double dummy; + cairo_matrix_multiply (&tmp, &gstate->font_matrix, &gstate->ctm); + cairo_matrix_get_affine (&tmp, + &sc->matrix[0][0], + &sc->matrix[0][1], + &sc->matrix[1][0], + &sc->matrix[1][1], + &dummy, &dummy); } cairo_status_t -_cairo_gstate_text_extents (cairo_gstate_t *gstate, - const unsigned char *utf8, - cairo_text_extents_t *extents) +_cairo_gstate_current_font_extents (cairo_gstate_t *gstate, + cairo_font_extents_t *extents) { - cairo_matrix_t saved_font_matrix; - cairo_status_t status; - double scale_x, scale_y; - - cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix); - _cairo_matrix_compute_scale_factors (&gstate->ctm, &scale_x, &scale_y); - cairo_matrix_scale (&gstate->font->matrix, scale_x, scale_y); - - status = _cairo_font_text_extents (gstate->font, - utf8, extents); - - cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix); + cairo_int_status_t status; + cairo_font_scale_t sc; + double dummy = 0.0; - extents->x_bearing /= scale_x; - extents->y_bearing /= scale_y; - extents->width /= scale_x; - extents->height /= scale_y; - extents->x_advance /= scale_x; - extents->y_advance /= scale_y; + _build_font_scale (gstate, &sc); - return status; -} + status = _cairo_unscaled_font_font_extents (gstate->font, &sc, extents); -cairo_status_t -_cairo_gstate_glyph_extents (cairo_gstate_t *gstate, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_text_extents_t *extents) -{ - cairo_status_t status; - cairo_matrix_t saved_font_matrix; - double scale_x, scale_y; + /* The font responded in device space; convert to user space. */ - cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix); - _cairo_matrix_compute_scale_factors (&gstate->ctm, &scale_x, &scale_y); - cairo_matrix_scale (&gstate->font->matrix, scale_x, scale_y); + cairo_matrix_transform_distance (&gstate->ctm_inverse, + &dummy, + &extents->ascent); - status = _cairo_font_glyph_extents (gstate->font, - glyphs, num_glyphs, - extents); + cairo_matrix_transform_distance (&gstate->ctm_inverse, + &dummy, + &extents->descent); - cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix); + cairo_matrix_transform_distance (&gstate->ctm_inverse, + &dummy, + &extents->height); - extents->x_bearing /= scale_x; - extents->y_bearing /= scale_y; - extents->width /= scale_x; - extents->height /= scale_y; - extents->x_advance /= scale_x; - extents->y_advance /= scale_y; + cairo_matrix_transform_distance (&gstate->ctm_inverse, + &extents->max_x_advance, + &extents->max_y_advance); return status; } cairo_status_t -_cairo_gstate_show_text (cairo_gstate_t *gstate, - const unsigned char *utf8) +_cairo_gstate_text_to_glyphs (cairo_gstate_t *gstate, + const unsigned char *utf8, + cairo_glyph_t **glyphs, + int *nglyphs) { cairo_status_t status; - cairo_point_t point; - double x, y; - cairo_matrix_t saved_font_matrix; - cairo_pattern_t pattern; - cairo_box_t bbox; + cairo_font_scale_t sc; + + cairo_point_t point; + double dev_x, dev_y; + int i; + + _build_font_scale (gstate, &sc); status = _cairo_path_current_point (&gstate->path, &point); if (status == CAIRO_STATUS_NO_CURRENT_POINT) { - x = 0; - y = 0; - cairo_matrix_transform_point (&gstate->ctm, &x, &y); + dev_x = 0.0; + dev_y = 0.0; } else { - x = _cairo_fixed_to_double (point.x); - y = _cairo_fixed_to_double (point.y); + dev_x = _cairo_fixed_to_double (point.x); + dev_y = _cairo_fixed_to_double (point.y); } - - cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix); - cairo_matrix_multiply (&gstate->font->matrix, &gstate->ctm, &gstate->font->matrix); - _cairo_pattern_init_copy (&pattern, gstate->pattern); - - status = _cairo_font_text_bbox (gstate->font, gstate->surface, - x, y, utf8, &bbox); - if (status) - return status; - - status = _cairo_gstate_create_pattern (gstate, &pattern, &bbox); - if (status) + status = _cairo_unscaled_font_text_to_glyphs (gstate->font, + &sc, utf8, glyphs, nglyphs); + + if (status || !glyphs || !nglyphs || !(*glyphs) || !(nglyphs)) return status; - - if (gstate->clip.surface) - { - cairo_surface_t *intermediate; - cairo_color_t empty_color; - _cairo_color_init (&empty_color); - _cairo_color_set_alpha (&empty_color, .0); - intermediate = _cairo_surface_create_similar_solid (gstate->clip.surface, - CAIRO_FORMAT_A8, - gstate->clip.width, - gstate->clip.height, - &empty_color); + /* The font responded in device space, starting from (0,0); add any + current point offset in device space, and convert to user space. */ - status = _cairo_font_show_text (gstate->font, - CAIRO_OPERATOR_ADD, pattern.source, - intermediate, - gstate->clip.x - pattern.source_offset.x, - gstate->clip.y - pattern.source_offset.y, - x - gstate->clip.x, - y - gstate->clip.y, utf8); + for (i = 0; i < *nglyphs; ++i) { + (*glyphs)[i].x += dev_x; + (*glyphs)[i].y += dev_y; + cairo_matrix_transform_point (&gstate->ctm_inverse, + &((*glyphs)[i].x), + &((*glyphs)[i].y)); + } + + return CAIRO_STATUS_SUCCESS; +} - if (status) - goto BAIL; - - status = _cairo_surface_composite (CAIRO_OPERATOR_IN, - gstate->clip.surface, - NULL, - intermediate, - 0, 0, - 0, 0, - 0, 0, - gstate->clip.width, - gstate->clip.height); +cairo_status_t +_cairo_gstate_set_font (cairo_gstate_t *gstate, + cairo_font_t *font) +{ + if (gstate->font != NULL) + _cairo_unscaled_font_destroy (gstate->font); + gstate->font = font->unscaled; + _cairo_unscaled_font_reference (gstate->font); + cairo_matrix_set_affine (&gstate->font_matrix, + font->scale.matrix[0][0], + font->scale.matrix[0][1], + font->scale.matrix[1][0], + font->scale.matrix[1][1], + 0, 0); + return CAIRO_STATUS_SUCCESS; +} - if (status) - goto BAIL; +cairo_status_t +_cairo_gstate_glyph_extents (cairo_gstate_t *gstate, + cairo_glyph_t *glyphs, + int num_glyphs, + cairo_text_extents_t *extents) +{ + cairo_status_t status; + cairo_glyph_t *transformed_glyphs; + cairo_font_scale_t sc; + int i; - status = _cairo_surface_composite (gstate->operator, - pattern.source, - intermediate, - gstate->surface, - 0, 0, - 0, 0, - gstate->clip.x, - gstate->clip.y, - gstate->clip.width, - gstate->clip.height); + _build_font_scale (gstate, &sc); - BAIL: - cairo_surface_destroy (intermediate); - - } - else + transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t)); + if (transformed_glyphs == NULL) + return CAIRO_STATUS_NO_MEMORY; + + for (i = 0; i < num_glyphs; ++i) { - status = _cairo_font_show_text (gstate->font, - gstate->operator, pattern.source, - gstate->surface, - -pattern.source_offset.x, - -pattern.source_offset.y, - x, y, utf8); + transformed_glyphs[i] = glyphs[i]; + cairo_matrix_transform_point (&gstate->ctm, + &transformed_glyphs[i].x, + &transformed_glyphs[i].y); } - - cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix); - _cairo_pattern_fini (&pattern); + status = _cairo_unscaled_font_glyph_extents (gstate->font, &sc, + transformed_glyphs, num_glyphs, + extents); + + /* The font responded in device space; convert to user space. */ + + cairo_matrix_transform_distance (&gstate->ctm_inverse, + &extents->x_bearing, + &extents->y_bearing); + + cairo_matrix_transform_distance (&gstate->ctm_inverse, + &extents->width, + &extents->height); + + cairo_matrix_transform_distance (&gstate->ctm_inverse, + &extents->x_advance, + &extents->y_advance); + + free (transformed_glyphs); return status; } @@ -2226,12 +2313,14 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, int num_glyphs) { cairo_status_t status; - cairo_matrix_t saved_font_matrix; int i; cairo_glyph_t *transformed_glyphs = NULL; + cairo_font_scale_t sc; cairo_pattern_t pattern; cairo_box_t bbox; + _build_font_scale (gstate, &sc); + transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t)); if (transformed_glyphs == NULL) return CAIRO_STATUS_NO_MEMORY; @@ -2240,16 +2329,14 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, { transformed_glyphs[i] = glyphs[i]; cairo_matrix_transform_point (&gstate->ctm, - &(transformed_glyphs[i].x), - &(transformed_glyphs[i].y)); + &transformed_glyphs[i].x, + &transformed_glyphs[i].y); } - cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix); - cairo_matrix_multiply (&gstate->font->matrix, &gstate->ctm, &gstate->font->matrix); - _cairo_pattern_init_copy (&pattern, gstate->pattern); - status = _cairo_font_glyph_bbox (gstate->font, gstate->surface, - transformed_glyphs, num_glyphs, &bbox); + status = _cairo_unscaled_font_glyph_bbox (gstate->font, &sc, + transformed_glyphs, num_glyphs, + &bbox); if (status) return status; @@ -2277,12 +2364,13 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, transformed_glyphs[i].y -= gstate->clip.y; } - status = _cairo_font_show_glyphs (gstate->font, - CAIRO_OPERATOR_ADD, - pattern.source, intermediate, - gstate->clip.x - pattern.source_offset.x, - gstate->clip.y - pattern.source_offset.y, - transformed_glyphs, num_glyphs); + status = _cairo_unscaled_font_show_glyphs (gstate->font, + &sc, + CAIRO_OPERATOR_ADD, + pattern.source, intermediate, + gstate->clip.x - pattern.source_offset.x, + gstate->clip.y - pattern.source_offset.y, + transformed_glyphs, num_glyphs); if (status) goto BAIL; @@ -2317,16 +2405,15 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, } else { - status = _cairo_font_show_glyphs (gstate->font, - gstate->operator, pattern.source, - gstate->surface, - -pattern.source_offset.x, - -pattern.source_offset.y, - transformed_glyphs, num_glyphs); + status = _cairo_unscaled_font_show_glyphs (gstate->font, + &sc, + gstate->operator, pattern.source, + gstate->surface, + -pattern.source_offset.x, + -pattern.source_offset.y, + transformed_glyphs, num_glyphs); } - cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix); - _cairo_pattern_fini (&pattern); free (transformed_glyphs); @@ -2334,40 +2421,6 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, return status; } - -cairo_status_t -_cairo_gstate_text_path (cairo_gstate_t *gstate, - const unsigned char *utf8) -{ - cairo_status_t status; - cairo_matrix_t saved_font_matrix; - cairo_point_t point; - double x, y; - - status = _cairo_path_current_point (&gstate->path, &point); - if (status == CAIRO_STATUS_NO_CURRENT_POINT) { - x = 0; - y = 0; - cairo_matrix_transform_point (&gstate->ctm, &x, &y); - } else { - x = _cairo_fixed_to_double (point.x); - y = _cairo_fixed_to_double (point.y); - } - - cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix); - cairo_matrix_multiply (&gstate->font->matrix, &gstate->ctm, &gstate->font->matrix); - - status = _cairo_font_text_path (gstate->font, - x, y, - utf8, - &gstate->path); - - cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix); - - return status; -} - - cairo_status_t _cairo_gstate_glyph_path (cairo_gstate_t *gstate, cairo_glyph_t *glyphs, @@ -2376,7 +2429,9 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate, cairo_status_t status; int i; cairo_glyph_t *transformed_glyphs = NULL; - cairo_matrix_t saved_font_matrix; + cairo_font_scale_t sc; + + _build_font_scale (gstate, &sc); transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t)); if (transformed_glyphs == NULL) @@ -2390,14 +2445,9 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate, &(transformed_glyphs[i].y)); } - cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix); - cairo_matrix_multiply (&gstate->font->matrix, &gstate->ctm, &gstate->font->matrix); - - status = _cairo_font_glyph_path (gstate->font, - transformed_glyphs, num_glyphs, - &gstate->path); - - cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix); + status = _cairo_unscaled_font_glyph_path (gstate->font, &sc, + transformed_glyphs, num_glyphs, + &gstate->path); free (transformed_glyphs); return status; diff --git a/src/cairo-hash.c b/src/cairo-hash.c new file mode 100644 index 000000000..c5ce39935 --- /dev/null +++ b/src/cairo-hash.c @@ -0,0 +1,454 @@ +/* cairo - a vector graphics library with display and print output + * + * This file is Copyright © 2004 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is Red Hat, Inc. + * + * Contributor(s): + * Keith Packard + * Graydon Hoare + */ + +#include "cairoint.h" + +/* + * This structure, and accompanying table, is borrowed/modified from the + * file xserver/render/glyph.c in the freedesktop.org x server, with + * permission (and suggested modification of doubling sizes) by Keith + * Packard. + */ + +static cairo_cache_arrangement_t cache_arrangements [] = { + { 16, 43, 41 }, + { 32, 73, 71 }, + { 64, 151, 149 }, + { 128, 283, 281 }, + { 256, 571, 569 }, + { 512, 1153, 1151 }, + { 1024, 2269, 2267 }, + { 2048, 4519, 4517 }, + { 4096, 9013, 9011 }, + { 8192, 18043, 18041 }, + { 16384, 36109, 36107 }, + { 32768, 72091, 72089 }, + { 65536, 144409, 144407 }, + { 131072, 288361, 288359 }, + { 262144, 576883, 576881 }, + { 524288, 1153459, 1153457 }, + { 1048576, 2307163, 2307161 }, + { 2097152, 4613893, 4613891 }, + { 4194304, 9227641, 9227639 }, + { 8388608, 18455029, 18455027 }, + { 16777216, 36911011, 36911009 }, + { 33554432, 73819861, 73819859 }, + { 67108864, 147639589, 147639587 }, + { 134217728, 295279081, 295279079 }, + { 268435456, 590559793, 590559791 } +}; + +#define N_CACHE_SIZES (sizeof(cache_arrangements)/sizeof(cache_arrangements[0])) + +/* + * Entries 'e' are poiners, in one of 3 states: + * + * e == NULL: The entry has never had anything put in it + * e != DEAD_ENTRY: The entry has an active value in it currently + * e == DEAD_ENTRY: The entry *had* a value in it at some point, but the + * entry has been killed. Lookups requesting free space can + * reuse these entries; lookups requesting a precise match + * should neither return these entries nor stop searching when + * seeing these entries. + * + * We expect keys will not be destroyed frequently, so our table does not + * contain any explicit shrinking code nor any chain-coalescing code for + * entries randomly deleted by memory pressure (except during rehashing, of + * course). These assumptions are potentially bad, but they make the + * implementation straightforward. + * + * Revisit later if evidence appears that we're using excessive memory from + * a mostly-dead table. + * + * Generally you do not need to worry about freeing cache entries; the + * cache will expire entries randomly as it experiences memory pressure. + * There is currently no explicit entry-removing call, though one can be + * added easily. + * + * This table is open-addressed with double hashing. Each table size is a + * prime chosen to be a little more than double the high water mark for a + * given arrangement, so the tables should remain < 50% full. The table + * size makes for the "first" hash modulus; a second prime (2 less than the + * first prime) serves as the "second" hash modulus, which is co-prime and + * thus guarantees a complete permutation of table indices. + * + */ + +#define DEAD_ENTRY ((cairo_cache_entry_base_t *) 1) +#define NULL_ENTRY_P(cache, i) ((cache)->entries[i] == NULL) +#define DEAD_ENTRY_P(cache, i) ((cache)->entries[i] == DEAD_ENTRY) +#define LIVE_ENTRY_P(cache, i) \ + (!((NULL_ENTRY_P((cache),(i))) || (DEAD_ENTRY_P((cache),(i))))) + +#ifdef CAIRO_DO_SANITY_CHECKING +#include +static void +_cache_sane_state (cairo_cache_t *cache) +{ + assert (cache != NULL); + assert (cache->entries != NULL); + assert (cache->backend != NULL); + assert (cache->arrangement != NULL); + assert (cache->refcount > 0); + assert (cache->used_memory <= cache->max_memory); + assert (cache->live_entries <= cache->arrangement->size); +} +#else +#define _cache_sane_state(c) +#define assert(x) +#endif + +static void +_entry_destroy (cairo_cache_t *cache, unsigned long i) +{ + _cache_sane_state (cache); + + if (LIVE_ENTRY_P(cache, i)) + { + cairo_cache_entry_base_t *entry = cache->entries[i]; + assert(cache->live_entries > 0); + assert(cache->used_memory > entry->memory); + + cache->live_entries--; + cache->used_memory -= entry->memory; + cache->backend->destroy_entry (cache, entry); + cache->entries[i] = DEAD_ENTRY; + } +} + +static cairo_cache_entry_base_t ** +_cache_lookup (cairo_cache_t *cache, + void *key, + int (*predicate)(void*,void*,void*)) +{ + + cairo_cache_entry_base_t **probe; + unsigned long hash; + unsigned long table_size, i, idx, step; + + _cache_sane_state (cache); + assert (key != NULL); + + table_size = cache->arrangement->size; + hash = cache->backend->hash (cache, key); + idx = hash % table_size; + step = 0; + + for (i = 0; i < table_size; ++i) + { +#ifdef CAIRO_MEASURE_CACHE_PERFORMANCE + cache->probes++; +#endif + assert(idx < table_size); + probe = cache->entries + idx; + + /* + * There are two lookup modes: searching for a free slot and searching + * for an exact entry. + */ + + if (predicate != NULL) + { + /* We are looking up an exact entry. */ + if (*probe != NULL + && *probe != DEAD_ENTRY + && (*probe)->hashcode == hash + && predicate (cache, key, *probe)) + return probe; + } + else + { + /* We are just looking for a free slot. */ + if (*probe == NULL + || *probe == DEAD_ENTRY) + return probe; + } + + if (step == 0) { + step = hash % cache->arrangement->rehash; + if (step == 0) + step = 1; + } + + idx += step; + if (idx >= table_size) + idx -= table_size; + } + + /* + * The table should not have permitted you to get here if you were just + * looking for a free slot: there should have been room. + */ + assert(predicate != NULL); + return NULL; +} + +static cairo_cache_entry_base_t ** +_find_available_entry_for (cairo_cache_t *cache, + void *key) +{ + return _cache_lookup (cache, key, NULL); +} + +static cairo_cache_entry_base_t ** +_find_exact_live_entry_for (cairo_cache_t *cache, + void *key) +{ + return _cache_lookup (cache, key, cache->backend->keys_equal); +} + + +static cairo_cache_arrangement_t * +_find_cache_arrangement (unsigned long proposed_size) +{ + unsigned long idx; + + for (idx = 0; idx < N_CACHE_SIZES; ++idx) + if (cache_arrangements[idx].high_water_mark >= proposed_size) + return &cache_arrangements[idx]; + return NULL; +} + +static cairo_status_t +_resize_cache (cairo_cache_t *cache, unsigned long proposed_size) +{ + cairo_cache_t tmp; + cairo_cache_entry_base_t **e; + unsigned long new_size, i; + + tmp = *cache; + tmp.arrangement = _find_cache_arrangement (proposed_size); + assert(tmp.arrangement != NULL); + if (tmp.arrangement == cache->arrangement) + return CAIRO_STATUS_SUCCESS; + + new_size = tmp.arrangement->size; + tmp.entries = calloc (new_size, sizeof (cairo_cache_entry_base_t *)); + if (tmp.entries == NULL) + return CAIRO_STATUS_NO_MEMORY; + + for (i = 0; i < cache->arrangement->size; ++i) { + if (LIVE_ENTRY_P(cache, i)) { + e = _find_available_entry_for (&tmp, cache->entries[i]); + assert (e != NULL); + *e = cache->entries[i]; + } + } + free (cache->entries); + cache->entries = tmp.entries; + cache->arrangement = tmp.arrangement; + return CAIRO_STATUS_SUCCESS; +} + + +#ifdef CAIRO_MEASURE_CACHE_PERFORMANCE +static double +_load_factor (cairo_cache_t *cache) +{ + return ((double) cache->live_entries) + / ((double) cache->arrangement->size); +} +#endif + +static unsigned long +_random_live_entry (cairo_cache_t *cache) +{ + unsigned long idx; + assert(cache != NULL); + do { + idx = rand () % cache->arrangement->size; + } while (! LIVE_ENTRY_P(cache, idx)); + return idx; +} + + +/* public API follows */ + +cairo_status_t +_cairo_cache_init (cairo_cache_t *cache, + const cairo_cache_backend_t *backend, + unsigned long max_memory) +{ + assert(backend != NULL); + + if (cache != NULL){ + cache->arrangement = &cache_arrangements[0]; + cache->refcount = 1; + cache->max_memory = max_memory; + cache->used_memory = 0; + cache->live_entries = 0; + +#ifdef CAIRO_MEASURE_CACHE_PERFORMANCE + cache->hits = 0; + cache->misses = 0; + cache->probes = 0; +#endif + + cache->backend = backend; + cache->entries = calloc (sizeof(cairo_cache_entry_base_t *), + cache->arrangement->size); + if (cache->entries == NULL) + return CAIRO_STATUS_NO_MEMORY; + } + _cache_sane_state (cache); + return CAIRO_STATUS_SUCCESS; +} + +void +_cairo_cache_reference (cairo_cache_t *cache) +{ + _cache_sane_state (cache); + cache->refcount++; +} + +void +_cairo_cache_destroy (cairo_cache_t *cache) +{ + unsigned long i; + if (cache != NULL) { + + _cache_sane_state (cache); + + if (cache->refcount-- > 0) + return; + + for (i = 0; i < cache->arrangement->size; ++i) { + _entry_destroy (cache, i); + } + + free (cache->entries); + cache->entries = NULL; + cache->backend->destroy_cache (cache); + } +} + +cairo_status_t +_cairo_cache_lookup (cairo_cache_t *cache, + void *key, + void **entry_return) +{ + + unsigned long idx; + cairo_status_t status = CAIRO_STATUS_SUCCESS; + cairo_cache_entry_base_t **slot = NULL, *new_entry; + + _cache_sane_state (cache); + +#ifdef CAIRO_MEASURE_CACHE_PERFORMANCE + if ((cache->hits + cache->misses) % 0xffff == 0) + printf("cache %p stats: size %ld, live %ld, load %.2f\n" + " mem %ld/%ld, hit %ld, miss %ld\n" + " probe %ld, %.2f probe/access\n", + cache, + cache->arrangement->size, + cache->live_entries, + _load_factor (cache), + cache->used_memory, + cache->max_memory, + cache->hits, + cache->misses, + cache->probes, + ((double) cache->probes) + / ((double) (cache->hits + + cache->misses + 1))); +#endif + + /* See if we have an entry in the table already. */ + slot = _find_exact_live_entry_for (cache, key); + if (slot != NULL) { +#ifdef CAIRO_MEASURE_CACHE_PERFORMANCE + cache->hits++; +#endif + *entry_return = *slot; + return status; + } + +#ifdef CAIRO_MEASURE_CACHE_PERFORMANCE + cache->misses++; +#endif + + /* Build the new entry. */ + status = cache->backend->create_entry (cache, key, + entry_return); + if (status != CAIRO_STATUS_SUCCESS) + return status; + + new_entry = (cairo_cache_entry_base_t *) (*entry_return); + + /* Store the hash value in case the backend forgot. */ + new_entry->hashcode = cache->backend->hash (cache, key); + + /* Make some entries die if we're under memory pressure. */ + while (cache->live_entries > 0 && + ((cache->max_memory - cache->used_memory) < new_entry->memory)) { + idx = _random_live_entry (cache); + assert (idx < cache->arrangement->size); + _entry_destroy (cache, idx); + } + + assert(cache->max_memory >= (cache->used_memory + new_entry->memory)); + + /* Make room in the table for a new slot. */ + status = _resize_cache (cache, cache->live_entries + 1); + if (status != CAIRO_STATUS_SUCCESS) { + cache->backend->destroy_entry (cache, new_entry); + *entry_return = NULL; + return status; + } + + slot = _find_available_entry_for (cache, key); + assert(slot != NULL); + + /* Store entry in slot and increment statistics. */ + *slot = new_entry; + cache->live_entries++; + cache->used_memory += new_entry->memory; + + _cache_sane_state (cache); + + return status; +} + +unsigned long +_cairo_hash_string (const char *c) +{ + /* This is the djb2 hash. */ + unsigned long hash = 5381; + while (*c) + hash = ((hash << 5) + hash) + *c++; + return hash; +} + diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index e2ee69c57..9e6abb2a6 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -525,5 +525,6 @@ static const cairo_surface_backend_t cairo_image_surface_backend = { _cairo_image_surface_copy_page, _cairo_image_surface_show_page, _cairo_image_abstract_surface_set_clip_region, - _cairo_image_abstract_surface_create_pattern + _cairo_image_abstract_surface_create_pattern, + NULL /* show_glyphs */ }; diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c index 4296d0d49..9b3096b0f 100644 --- a/src/cairo-ps-surface.c +++ b/src/cairo-ps-surface.c @@ -436,5 +436,6 @@ static const cairo_surface_backend_t cairo_ps_surface_backend = { _cairo_ps_surface_copy_page, _cairo_ps_surface_show_page, _cairo_ps_surface_set_clip_region, - _cairo_ps_surface_create_pattern + _cairo_ps_surface_create_pattern, + NULL /* show_glyphs */ }; diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c index 36aa15731..bc37d2047 100644 --- a/src/cairo-xcb-surface.c +++ b/src/cairo-xcb-surface.c @@ -745,7 +745,8 @@ static const struct cairo_surface_backend cairo_xcb_surface_backend = { _cairo_xcb_surface_copy_page, _cairo_xcb_surface_show_page, _cairo_xcb_surface_set_clip_region, - _cairo_xcb_surface_create_pattern + _cairo_xcb_surface_create_pattern, + NULL /* show_glyphs */ }; static void diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index 8513ae4ef..fca7f33e4 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -631,6 +631,8 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, xr.height = surf->height; XUnionRectWithRegion (&xr, xregion, xregion); rects = malloc(sizeof(XRectangle)); + if (rects == NULL) + return CAIRO_STATUS_NO_MEMORY; rects[0] = xr; m = 1; @@ -641,6 +643,8 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, if (n == 0) return CAIRO_STATUS_SUCCESS; rects = malloc(sizeof(XRectangle) * n); + if (rects == NULL) + return CAIRO_STATUS_NO_MEMORY; box = pixman_region_rects (region); xregion = XCreateRegion(); @@ -661,7 +665,7 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, XSetClipRectangles(surf->dpy, surf->gc, 0, 0, rects, m, Unsorted); free(rects); if (surf->picture) - XRenderSetPictureClipRegion (surf->dpy, surf->picture, xregion); + XRenderSetPictureClipRegion (surf->dpy, surf->picture, xregion); XDestroyRegion(xregion); XSetGraphicsExposures(surf->dpy, surf->gc, gc_values.graphics_exposures); return CAIRO_STATUS_SUCCESS; @@ -675,6 +679,17 @@ _cairo_xlib_surface_create_pattern (void *abstract_surface, return CAIRO_INT_STATUS_UNSUPPORTED; } +static cairo_status_t +_cairo_xlib_surface_show_glyphs (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_operator_t operator, + cairo_surface_t *source, + cairo_surface_t *surface, + int source_x, + int source_y, + const cairo_glyph_t *glyphs, + int num_glyphs); + static const struct cairo_surface_backend cairo_xlib_surface_backend = { _cairo_xlib_surface_create_similar, _cairo_xlib_surface_destroy, @@ -690,7 +705,8 @@ static const struct cairo_surface_backend cairo_xlib_surface_backend = { _cairo_xlib_surface_copy_page, _cairo_xlib_surface_show_page, _cairo_xlib_surface_set_clip_region, - _cairo_xlib_surface_create_pattern + _cairo_xlib_surface_create_pattern, + _cairo_xlib_surface_show_glyphs }; cairo_surface_t * @@ -761,3 +777,512 @@ cairo_xlib_surface_create (Display *dpy, return (cairo_surface_t *) surface; } DEPRECATE (cairo_surface_create_for_drawable, cairo_xlib_surface_create); + + +/* RENDER glyphset cache code */ + +typedef struct glyphset_cache { + cairo_cache_t base; + struct glyphset_cache *next; + Display *display; + XRenderPictFormat *a8_pict_format; + GlyphSet glyphset; + Glyph counter; +} glyphset_cache_t; + +typedef struct { + cairo_glyph_cache_key_t key; + Glyph glyph; + XGlyphInfo info; +} glyphset_cache_entry_t; + +static Glyph +_next_xlib_glyph (glyphset_cache_t *cache) +{ + return ++(cache->counter); +} + + +static cairo_status_t +_xlib_glyphset_cache_create_entry (void *cache, + void *key, + void **return_entry) +{ + glyphset_cache_t *g = (glyphset_cache_t *) cache; + cairo_glyph_cache_key_t *k = (cairo_glyph_cache_key_t *)key; + glyphset_cache_entry_t *v; + + cairo_status_t status; + + cairo_cache_t *im_cache; + cairo_image_glyph_cache_entry_t *im; + + v = malloc (sizeof (glyphset_cache_entry_t)); + _cairo_lock_global_image_glyph_cache (); + im_cache = _cairo_get_global_image_glyph_cache (); + + if (g == NULL || v == NULL ||g == NULL || im_cache == NULL) { + _cairo_unlock_global_image_glyph_cache (); + return CAIRO_STATUS_NO_MEMORY; + } + + status = _cairo_cache_lookup (im_cache, key, (void **) (&im)); + if (status != CAIRO_STATUS_SUCCESS || im == NULL) { + _cairo_unlock_global_image_glyph_cache (); + return CAIRO_STATUS_NO_MEMORY; + } + + v->key = *k; + _cairo_unscaled_font_reference (v->key.unscaled); + + v->glyph = _next_xlib_glyph (g); + + v->info.width = im->image ? im->image->stride : im->size.width; + v->info.height = im->size.height; + v->info.x = - im->extents.x_bearing; + v->info.y = im->extents.y_bearing; + v->info.xOff = 0; + v->info.yOff = 0; + + XRenderAddGlyphs (g->display, g->glyphset, + &(v->glyph), &(v->info), 1, + im->image ? im->image->data : NULL, + im->image ? v->info.height * v->info.width : 0); + + v->key.base.memory = im->image ? im->image->width * im->image->stride : 0; + *return_entry = v; + _cairo_unlock_global_image_glyph_cache (); + return CAIRO_STATUS_SUCCESS; +} + +static void +_xlib_glyphset_cache_destroy_cache (void *cache) +{ + /* FIXME: will we ever release glyphset caches? */ +} + +static void +_xlib_glyphset_cache_destroy_entry (void *cache, void *entry) +{ + glyphset_cache_t *g; + glyphset_cache_entry_t *v; + + g = (glyphset_cache_t *) cache; + v = (glyphset_cache_entry_t *) entry; + + _cairo_unscaled_font_destroy (v->key.unscaled); + XRenderFreeGlyphs (g->display, g->glyphset, &(v->glyph), 1); + free (v); +} + +const cairo_cache_backend_t _xlib_glyphset_cache_backend = { + _cairo_glyph_cache_hash, + _cairo_glyph_cache_keys_equal, + _xlib_glyphset_cache_create_entry, + _xlib_glyphset_cache_destroy_entry, + _xlib_glyphset_cache_destroy_cache +}; + + +static glyphset_cache_t * +_xlib_glyphset_caches = NULL; + +static void +_lock_xlib_glyphset_caches (void) +{ + /* FIXME: implement locking */ +} + +static void +_unlock_xlib_glyphset_caches (void) +{ + /* FIXME: implement locking */ +} + +static glyphset_cache_t * +_get_glyphset_cache (Display *d) +{ + /* + * There should usually only be one, or a very small number, of + * displays. So we just do a linear scan. + */ + + glyphset_cache_t *g; + + for (g = _xlib_glyphset_caches; g != NULL; g = g->next) { + if (g->display == d) + return g; + } + + g = malloc (sizeof (glyphset_cache_t)); + if (g == NULL) + goto ERR; + + g->counter = 0; + g->display = d; + g->a8_pict_format = XRenderFindStandardFormat (d, PictStandardA8); + if (g->a8_pict_format == NULL) + goto ERR; + + if (_cairo_cache_init (&g->base, + &_xlib_glyphset_cache_backend, + CAIRO_XLIB_GLYPH_CACHE_MEMORY_DEFAULT)) + goto FREE_GLYPHSET_CACHE; + + g->glyphset = XRenderCreateGlyphSet (d, g->a8_pict_format); + g->next = _xlib_glyphset_caches; + _xlib_glyphset_caches = g; + return g; + + FREE_GLYPHSET_CACHE: + free (g); + + ERR: + return NULL; +} + +#define N_STACK_BUF 1024 + +static cairo_status_t +_cairo_xlib_surface_show_glyphs32 (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_operator_t operator, + glyphset_cache_t *g, + cairo_glyph_cache_key_t *key, + cairo_xlib_surface_t *src, + cairo_xlib_surface_t *self, + int source_x, + int source_y, + const cairo_glyph_t *glyphs, + glyphset_cache_entry_t **entries, + int num_glyphs) +{ + XGlyphElt32 *elts = NULL; + XGlyphElt32 stack_elts [N_STACK_BUF]; + + unsigned int *chars = NULL; + unsigned int stack_chars [N_STACK_BUF]; + + int i; + int lastX = 0, lastY = 0; + + /* Acquire arrays of suitable sizes. */ + if (num_glyphs < N_STACK_BUF) { + elts = stack_elts; + chars = stack_chars; + + } else { + elts = malloc (num_glyphs * sizeof (XGlyphElt32)); + if (elts == NULL) + goto FAIL; + + chars = malloc (num_glyphs * sizeof (unsigned int)); + if (chars == NULL) + goto FREE_ELTS; + + } + + for (i = 0; i < num_glyphs; ++i) { + chars[i] = entries[i]->glyph; + elts[i].chars = &(chars[i]); + elts[i].nchars = 1; + elts[i].glyphset = g->glyphset; + elts[i].xOff = glyphs[i].x - lastX; + elts[i].yOff = glyphs[i].y - lastY; + lastX = glyphs[i].x; + lastY = glyphs[i].y; + } + + XRenderCompositeText32 (self->dpy, + _render_operator (operator), + src->picture, + self->picture, + g->a8_pict_format, + source_x, source_y, + 0, 0, + elts, num_glyphs); + + if (num_glyphs >= N_STACK_BUF) { + free (chars); + free (elts); + } + + return CAIRO_STATUS_SUCCESS; + + FREE_ELTS: + if (num_glyphs >= N_STACK_BUF) + free (elts); + + FAIL: + return CAIRO_STATUS_NO_MEMORY; +} + + +static cairo_status_t +_cairo_xlib_surface_show_glyphs16 (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_operator_t operator, + glyphset_cache_t *g, + cairo_glyph_cache_key_t *key, + cairo_xlib_surface_t *src, + cairo_xlib_surface_t *self, + int source_x, + int source_y, + const cairo_glyph_t *glyphs, + glyphset_cache_entry_t **entries, + int num_glyphs) +{ + XGlyphElt16 *elts = NULL; + XGlyphElt16 stack_elts [N_STACK_BUF]; + + unsigned short *chars = NULL; + unsigned short stack_chars [N_STACK_BUF]; + + int i; + int lastX = 0, lastY = 0; + + /* Acquire arrays of suitable sizes. */ + if (num_glyphs < N_STACK_BUF) { + elts = stack_elts; + chars = stack_chars; + + } else { + elts = malloc (num_glyphs * sizeof (XGlyphElt16)); + if (elts == NULL) + goto FAIL; + + chars = malloc (num_glyphs * sizeof (unsigned short)); + if (chars == NULL) + goto FREE_ELTS; + + } + + for (i = 0; i < num_glyphs; ++i) { + chars[i] = entries[i]->glyph; + elts[i].chars = &(chars[i]); + elts[i].nchars = 1; + elts[i].glyphset = g->glyphset; + elts[i].xOff = glyphs[i].x - lastX; + elts[i].yOff = glyphs[i].y - lastY; + lastX = glyphs[i].x; + lastY = glyphs[i].y; + } + + XRenderCompositeText16 (self->dpy, + _render_operator (operator), + src->picture, + self->picture, + g->a8_pict_format, + source_x, source_y, + 0, 0, + elts, num_glyphs); + + if (num_glyphs >= N_STACK_BUF) { + free (chars); + free (elts); + } + + return CAIRO_STATUS_SUCCESS; + + FREE_ELTS: + if (num_glyphs >= N_STACK_BUF) + free (elts); + + FAIL: + return CAIRO_STATUS_NO_MEMORY; +} + +static cairo_status_t +_cairo_xlib_surface_show_glyphs8 (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_operator_t operator, + glyphset_cache_t *g, + cairo_glyph_cache_key_t *key, + cairo_xlib_surface_t *src, + cairo_xlib_surface_t *self, + int source_x, + int source_y, + const cairo_glyph_t *glyphs, + glyphset_cache_entry_t **entries, + int num_glyphs) +{ + XGlyphElt8 *elts = NULL; + XGlyphElt8 stack_elts [N_STACK_BUF]; + + char *chars = NULL; + char stack_chars [N_STACK_BUF]; + + int i; + int lastX = 0, lastY = 0; + + /* Acquire arrays of suitable sizes. */ + if (num_glyphs < N_STACK_BUF) { + elts = stack_elts; + chars = stack_chars; + + } else { + elts = malloc (num_glyphs * sizeof (XGlyphElt8)); + if (elts == NULL) + goto FAIL; + + chars = malloc (num_glyphs * sizeof (char)); + if (chars == NULL) + goto FREE_ELTS; + + } + + for (i = 0; i < num_glyphs; ++i) { + chars[i] = entries[i]->glyph; + elts[i].chars = &(chars[i]); + elts[i].nchars = 1; + elts[i].glyphset = g->glyphset; + elts[i].xOff = glyphs[i].x - lastX; + elts[i].yOff = glyphs[i].y - lastY; + lastX = glyphs[i].x; + lastY = glyphs[i].y; + } + + XRenderCompositeText8 (self->dpy, + _render_operator (operator), + src->picture, + self->picture, + g->a8_pict_format, + source_x, source_y, + 0, 0, + elts, num_glyphs); + + if (num_glyphs >= N_STACK_BUF) { + free (chars); + free (elts); + } + + return CAIRO_STATUS_SUCCESS; + + FREE_ELTS: + if (num_glyphs >= N_STACK_BUF) + free (elts); + + FAIL: + return CAIRO_STATUS_NO_MEMORY; +} + + +static cairo_status_t +_cairo_xlib_surface_show_glyphs (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_operator_t operator, + cairo_surface_t *source, + cairo_surface_t *surface, + int source_x, + int source_y, + const cairo_glyph_t *glyphs, + int num_glyphs) +{ + unsigned int elt_size; + cairo_xlib_surface_t *self = (cairo_xlib_surface_t *) surface; + cairo_image_surface_t *tmp = NULL; + cairo_xlib_surface_t *src = NULL; + glyphset_cache_t *g; + cairo_status_t status; + cairo_glyph_cache_key_t key; + glyphset_cache_entry_t **entries; + glyphset_cache_entry_t *stack_entries [N_STACK_BUF]; + int i; + + /* Acquire an entry array of suitable size. */ + if (num_glyphs < N_STACK_BUF) { + entries = stack_entries; + + } else { + entries = malloc (num_glyphs * sizeof (glyphset_cache_entry_t *)); + if (entries == NULL) + goto FAIL; + } + + /* prep the source surface. */ + if (source->backend == surface->backend) { + src = (cairo_xlib_surface_t *) source; + + } else { + tmp = _cairo_surface_get_image (source); + if (tmp == NULL) + goto FREE_ENTRIES; + + src = (cairo_xlib_surface_t *) + _cairo_surface_create_similar_scratch (surface, self->format, 1, + tmp->width, tmp->height); + + if (src == NULL) + goto FREE_TMP; + + if (_cairo_surface_set_image (&(src->base), tmp) != CAIRO_STATUS_SUCCESS) + goto FREE_SRC; + } + + _lock_xlib_glyphset_caches (); + g = _get_glyphset_cache (self->dpy); + if (g == NULL) + goto UNLOCK; + + /* Work out the index size to use. */ + elt_size = 8; + key.scale = *scale; + key.unscaled = font; + + for (i = 0; i < num_glyphs; ++i) { + key.index = glyphs[i].index; + status = _cairo_cache_lookup (&g->base, &key, (void **) (&entries[i])); + if (status != CAIRO_STATUS_SUCCESS || entries[i] == NULL) + goto UNLOCK; + + if (elt_size == 8 && entries[i]->glyph > 0xff) + elt_size = 16; + if (elt_size == 16 && entries[i]->glyph > 0xffff) { + elt_size = 32; + break; + } + } + + /* Call the appropriate sub-function. */ + + if (elt_size == 8) + status = _cairo_xlib_surface_show_glyphs8 (font, scale, operator, g, &key, src, self, + source_x, source_y, + glyphs, entries, num_glyphs); + else if (elt_size == 16) + status = _cairo_xlib_surface_show_glyphs16 (font, scale, operator, g, &key, src, self, + source_x, source_y, + glyphs, entries, num_glyphs); + else + status = _cairo_xlib_surface_show_glyphs32 (font, scale, operator, g, &key, src, self, + source_x, source_y, + glyphs, entries, num_glyphs); + + _unlock_xlib_glyphset_caches (); + + if (tmp != NULL) { + cairo_surface_destroy (&(src->base)); + cairo_surface_destroy (&(tmp->base)); + } + + if (num_glyphs >= N_STACK_BUF) + free (entries); + + return status; + + UNLOCK: + _unlock_xlib_glyphset_caches (); + + FREE_SRC: + cairo_surface_destroy (&(src->base)); + + FREE_TMP: + cairo_surface_destroy (&(tmp->base)); + + FREE_ENTRIES: + if (num_glyphs >= N_STACK_BUF) + free (entries); + + FAIL: + return CAIRO_STATUS_NO_MEMORY; +} diff --git a/src/cairo.c b/src/cairo.c index bd3ea90f8..8bd5f2012 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -900,12 +900,27 @@ cairo_text_extents (cairo_t *cr, const unsigned char *utf8, cairo_text_extents_t *extents) { + cairo_glyph_t *glyphs = NULL; + int nglyphs; + CAIRO_CHECK_SANITY (cr); if (cr->status) return; - - cr->status = _cairo_gstate_text_extents (cr->gstate, utf8, extents); + + cr->status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8, &glyphs, &nglyphs); + CAIRO_CHECK_SANITY (cr); + + if (cr->status) { + if (glyphs) + free (glyphs); + return; + } + + cr->status = _cairo_gstate_glyph_extents (cr->gstate, glyphs, nglyphs, extents); CAIRO_CHECK_SANITY (cr); + + if (glyphs) + free (glyphs); } void @@ -926,6 +941,9 @@ cairo_glyph_extents (cairo_t *cr, void cairo_show_text (cairo_t *cr, const unsigned char *utf8) { + cairo_glyph_t *glyphs = NULL; + int nglyphs; + CAIRO_CHECK_SANITY (cr); if (cr->status) return; @@ -933,8 +951,20 @@ cairo_show_text (cairo_t *cr, const unsigned char *utf8) if (utf8 == NULL) return; - cr->status = _cairo_gstate_show_text (cr->gstate, utf8); + cr->status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8, &glyphs, &nglyphs); CAIRO_CHECK_SANITY (cr); + + if (cr->status) { + if (glyphs) + free (glyphs); + return; + } + + cr->status = _cairo_gstate_show_glyphs (cr->gstate, glyphs, nglyphs); + CAIRO_CHECK_SANITY (cr); + + if (glyphs) + free (glyphs); } void @@ -951,12 +981,27 @@ cairo_show_glyphs (cairo_t *cr, cairo_glyph_t *glyphs, int num_glyphs) void cairo_text_path (cairo_t *cr, const unsigned char *utf8) { + cairo_glyph_t *glyphs = NULL; + int nglyphs; + CAIRO_CHECK_SANITY (cr); if (cr->status) return; - cr->status = _cairo_gstate_text_path (cr->gstate, utf8); + cr->status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8, &glyphs, &nglyphs); CAIRO_CHECK_SANITY (cr); + + if (cr->status) { + if (glyphs) + free (glyphs); + return; + } + + cr->status = _cairo_gstate_glyph_path (cr->gstate, glyphs, nglyphs); + CAIRO_CHECK_SANITY (cr); + + if (glyphs) + free (glyphs); } void diff --git a/src/cairo_cache.c b/src/cairo_cache.c new file mode 100644 index 000000000..c5ce39935 --- /dev/null +++ b/src/cairo_cache.c @@ -0,0 +1,454 @@ +/* cairo - a vector graphics library with display and print output + * + * This file is Copyright © 2004 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is Red Hat, Inc. + * + * Contributor(s): + * Keith Packard + * Graydon Hoare + */ + +#include "cairoint.h" + +/* + * This structure, and accompanying table, is borrowed/modified from the + * file xserver/render/glyph.c in the freedesktop.org x server, with + * permission (and suggested modification of doubling sizes) by Keith + * Packard. + */ + +static cairo_cache_arrangement_t cache_arrangements [] = { + { 16, 43, 41 }, + { 32, 73, 71 }, + { 64, 151, 149 }, + { 128, 283, 281 }, + { 256, 571, 569 }, + { 512, 1153, 1151 }, + { 1024, 2269, 2267 }, + { 2048, 4519, 4517 }, + { 4096, 9013, 9011 }, + { 8192, 18043, 18041 }, + { 16384, 36109, 36107 }, + { 32768, 72091, 72089 }, + { 65536, 144409, 144407 }, + { 131072, 288361, 288359 }, + { 262144, 576883, 576881 }, + { 524288, 1153459, 1153457 }, + { 1048576, 2307163, 2307161 }, + { 2097152, 4613893, 4613891 }, + { 4194304, 9227641, 9227639 }, + { 8388608, 18455029, 18455027 }, + { 16777216, 36911011, 36911009 }, + { 33554432, 73819861, 73819859 }, + { 67108864, 147639589, 147639587 }, + { 134217728, 295279081, 295279079 }, + { 268435456, 590559793, 590559791 } +}; + +#define N_CACHE_SIZES (sizeof(cache_arrangements)/sizeof(cache_arrangements[0])) + +/* + * Entries 'e' are poiners, in one of 3 states: + * + * e == NULL: The entry has never had anything put in it + * e != DEAD_ENTRY: The entry has an active value in it currently + * e == DEAD_ENTRY: The entry *had* a value in it at some point, but the + * entry has been killed. Lookups requesting free space can + * reuse these entries; lookups requesting a precise match + * should neither return these entries nor stop searching when + * seeing these entries. + * + * We expect keys will not be destroyed frequently, so our table does not + * contain any explicit shrinking code nor any chain-coalescing code for + * entries randomly deleted by memory pressure (except during rehashing, of + * course). These assumptions are potentially bad, but they make the + * implementation straightforward. + * + * Revisit later if evidence appears that we're using excessive memory from + * a mostly-dead table. + * + * Generally you do not need to worry about freeing cache entries; the + * cache will expire entries randomly as it experiences memory pressure. + * There is currently no explicit entry-removing call, though one can be + * added easily. + * + * This table is open-addressed with double hashing. Each table size is a + * prime chosen to be a little more than double the high water mark for a + * given arrangement, so the tables should remain < 50% full. The table + * size makes for the "first" hash modulus; a second prime (2 less than the + * first prime) serves as the "second" hash modulus, which is co-prime and + * thus guarantees a complete permutation of table indices. + * + */ + +#define DEAD_ENTRY ((cairo_cache_entry_base_t *) 1) +#define NULL_ENTRY_P(cache, i) ((cache)->entries[i] == NULL) +#define DEAD_ENTRY_P(cache, i) ((cache)->entries[i] == DEAD_ENTRY) +#define LIVE_ENTRY_P(cache, i) \ + (!((NULL_ENTRY_P((cache),(i))) || (DEAD_ENTRY_P((cache),(i))))) + +#ifdef CAIRO_DO_SANITY_CHECKING +#include +static void +_cache_sane_state (cairo_cache_t *cache) +{ + assert (cache != NULL); + assert (cache->entries != NULL); + assert (cache->backend != NULL); + assert (cache->arrangement != NULL); + assert (cache->refcount > 0); + assert (cache->used_memory <= cache->max_memory); + assert (cache->live_entries <= cache->arrangement->size); +} +#else +#define _cache_sane_state(c) +#define assert(x) +#endif + +static void +_entry_destroy (cairo_cache_t *cache, unsigned long i) +{ + _cache_sane_state (cache); + + if (LIVE_ENTRY_P(cache, i)) + { + cairo_cache_entry_base_t *entry = cache->entries[i]; + assert(cache->live_entries > 0); + assert(cache->used_memory > entry->memory); + + cache->live_entries--; + cache->used_memory -= entry->memory; + cache->backend->destroy_entry (cache, entry); + cache->entries[i] = DEAD_ENTRY; + } +} + +static cairo_cache_entry_base_t ** +_cache_lookup (cairo_cache_t *cache, + void *key, + int (*predicate)(void*,void*,void*)) +{ + + cairo_cache_entry_base_t **probe; + unsigned long hash; + unsigned long table_size, i, idx, step; + + _cache_sane_state (cache); + assert (key != NULL); + + table_size = cache->arrangement->size; + hash = cache->backend->hash (cache, key); + idx = hash % table_size; + step = 0; + + for (i = 0; i < table_size; ++i) + { +#ifdef CAIRO_MEASURE_CACHE_PERFORMANCE + cache->probes++; +#endif + assert(idx < table_size); + probe = cache->entries + idx; + + /* + * There are two lookup modes: searching for a free slot and searching + * for an exact entry. + */ + + if (predicate != NULL) + { + /* We are looking up an exact entry. */ + if (*probe != NULL + && *probe != DEAD_ENTRY + && (*probe)->hashcode == hash + && predicate (cache, key, *probe)) + return probe; + } + else + { + /* We are just looking for a free slot. */ + if (*probe == NULL + || *probe == DEAD_ENTRY) + return probe; + } + + if (step == 0) { + step = hash % cache->arrangement->rehash; + if (step == 0) + step = 1; + } + + idx += step; + if (idx >= table_size) + idx -= table_size; + } + + /* + * The table should not have permitted you to get here if you were just + * looking for a free slot: there should have been room. + */ + assert(predicate != NULL); + return NULL; +} + +static cairo_cache_entry_base_t ** +_find_available_entry_for (cairo_cache_t *cache, + void *key) +{ + return _cache_lookup (cache, key, NULL); +} + +static cairo_cache_entry_base_t ** +_find_exact_live_entry_for (cairo_cache_t *cache, + void *key) +{ + return _cache_lookup (cache, key, cache->backend->keys_equal); +} + + +static cairo_cache_arrangement_t * +_find_cache_arrangement (unsigned long proposed_size) +{ + unsigned long idx; + + for (idx = 0; idx < N_CACHE_SIZES; ++idx) + if (cache_arrangements[idx].high_water_mark >= proposed_size) + return &cache_arrangements[idx]; + return NULL; +} + +static cairo_status_t +_resize_cache (cairo_cache_t *cache, unsigned long proposed_size) +{ + cairo_cache_t tmp; + cairo_cache_entry_base_t **e; + unsigned long new_size, i; + + tmp = *cache; + tmp.arrangement = _find_cache_arrangement (proposed_size); + assert(tmp.arrangement != NULL); + if (tmp.arrangement == cache->arrangement) + return CAIRO_STATUS_SUCCESS; + + new_size = tmp.arrangement->size; + tmp.entries = calloc (new_size, sizeof (cairo_cache_entry_base_t *)); + if (tmp.entries == NULL) + return CAIRO_STATUS_NO_MEMORY; + + for (i = 0; i < cache->arrangement->size; ++i) { + if (LIVE_ENTRY_P(cache, i)) { + e = _find_available_entry_for (&tmp, cache->entries[i]); + assert (e != NULL); + *e = cache->entries[i]; + } + } + free (cache->entries); + cache->entries = tmp.entries; + cache->arrangement = tmp.arrangement; + return CAIRO_STATUS_SUCCESS; +} + + +#ifdef CAIRO_MEASURE_CACHE_PERFORMANCE +static double +_load_factor (cairo_cache_t *cache) +{ + return ((double) cache->live_entries) + / ((double) cache->arrangement->size); +} +#endif + +static unsigned long +_random_live_entry (cairo_cache_t *cache) +{ + unsigned long idx; + assert(cache != NULL); + do { + idx = rand () % cache->arrangement->size; + } while (! LIVE_ENTRY_P(cache, idx)); + return idx; +} + + +/* public API follows */ + +cairo_status_t +_cairo_cache_init (cairo_cache_t *cache, + const cairo_cache_backend_t *backend, + unsigned long max_memory) +{ + assert(backend != NULL); + + if (cache != NULL){ + cache->arrangement = &cache_arrangements[0]; + cache->refcount = 1; + cache->max_memory = max_memory; + cache->used_memory = 0; + cache->live_entries = 0; + +#ifdef CAIRO_MEASURE_CACHE_PERFORMANCE + cache->hits = 0; + cache->misses = 0; + cache->probes = 0; +#endif + + cache->backend = backend; + cache->entries = calloc (sizeof(cairo_cache_entry_base_t *), + cache->arrangement->size); + if (cache->entries == NULL) + return CAIRO_STATUS_NO_MEMORY; + } + _cache_sane_state (cache); + return CAIRO_STATUS_SUCCESS; +} + +void +_cairo_cache_reference (cairo_cache_t *cache) +{ + _cache_sane_state (cache); + cache->refcount++; +} + +void +_cairo_cache_destroy (cairo_cache_t *cache) +{ + unsigned long i; + if (cache != NULL) { + + _cache_sane_state (cache); + + if (cache->refcount-- > 0) + return; + + for (i = 0; i < cache->arrangement->size; ++i) { + _entry_destroy (cache, i); + } + + free (cache->entries); + cache->entries = NULL; + cache->backend->destroy_cache (cache); + } +} + +cairo_status_t +_cairo_cache_lookup (cairo_cache_t *cache, + void *key, + void **entry_return) +{ + + unsigned long idx; + cairo_status_t status = CAIRO_STATUS_SUCCESS; + cairo_cache_entry_base_t **slot = NULL, *new_entry; + + _cache_sane_state (cache); + +#ifdef CAIRO_MEASURE_CACHE_PERFORMANCE + if ((cache->hits + cache->misses) % 0xffff == 0) + printf("cache %p stats: size %ld, live %ld, load %.2f\n" + " mem %ld/%ld, hit %ld, miss %ld\n" + " probe %ld, %.2f probe/access\n", + cache, + cache->arrangement->size, + cache->live_entries, + _load_factor (cache), + cache->used_memory, + cache->max_memory, + cache->hits, + cache->misses, + cache->probes, + ((double) cache->probes) + / ((double) (cache->hits + + cache->misses + 1))); +#endif + + /* See if we have an entry in the table already. */ + slot = _find_exact_live_entry_for (cache, key); + if (slot != NULL) { +#ifdef CAIRO_MEASURE_CACHE_PERFORMANCE + cache->hits++; +#endif + *entry_return = *slot; + return status; + } + +#ifdef CAIRO_MEASURE_CACHE_PERFORMANCE + cache->misses++; +#endif + + /* Build the new entry. */ + status = cache->backend->create_entry (cache, key, + entry_return); + if (status != CAIRO_STATUS_SUCCESS) + return status; + + new_entry = (cairo_cache_entry_base_t *) (*entry_return); + + /* Store the hash value in case the backend forgot. */ + new_entry->hashcode = cache->backend->hash (cache, key); + + /* Make some entries die if we're under memory pressure. */ + while (cache->live_entries > 0 && + ((cache->max_memory - cache->used_memory) < new_entry->memory)) { + idx = _random_live_entry (cache); + assert (idx < cache->arrangement->size); + _entry_destroy (cache, idx); + } + + assert(cache->max_memory >= (cache->used_memory + new_entry->memory)); + + /* Make room in the table for a new slot. */ + status = _resize_cache (cache, cache->live_entries + 1); + if (status != CAIRO_STATUS_SUCCESS) { + cache->backend->destroy_entry (cache, new_entry); + *entry_return = NULL; + return status; + } + + slot = _find_available_entry_for (cache, key); + assert(slot != NULL); + + /* Store entry in slot and increment statistics. */ + *slot = new_entry; + cache->live_entries++; + cache->used_memory += new_entry->memory; + + _cache_sane_state (cache); + + return status; +} + +unsigned long +_cairo_hash_string (const char *c) +{ + /* This is the djb2 hash. */ + unsigned long hash = 5381; + while (*c) + hash = ((hash << 5) + hash) + *c++; + return hash; +} + diff --git a/src/cairo_font.c b/src/cairo_font.c index 1b356698e..c90a02bd6 100644 --- a/src/cairo_font.c +++ b/src/cairo_font.c @@ -36,20 +36,60 @@ #include "cairoint.h" -static cairo_glyph_cache_t * -_cairo_glyph_cache_create (void); -static void -_cairo_glyph_cache_destroy (cairo_glyph_cache_t *glyph_cache); +/* First we implement a global font cache for named fonts. */ + +typedef struct { + cairo_cache_entry_base_t base; + const char *family; + cairo_font_slant_t slant; + cairo_font_weight_t weight; +} cairo_font_cache_key_t; + +typedef struct { + cairo_font_cache_key_t key; + cairo_unscaled_font_t *unscaled; +} cairo_font_cache_entry_t; + +static unsigned long +_font_cache_hash (void *cache, void *key) +{ + cairo_font_cache_key_t *in; + in = (cairo_font_cache_key_t *) key; + unsigned long hash; + + /* 1607 and 1451 are just a couple random primes. */ + hash = _cairo_hash_string (in->family); + hash += ((unsigned long) in->slant) * 1607; + hash += ((unsigned long) in->weight) * 1451; + return hash; +} -static void -_cairo_glyph_cache_reference (cairo_glyph_cache_t *glyph_cache); -cairo_font_t * -_cairo_font_create (const char *family, - cairo_font_slant_t slant, - cairo_font_weight_t weight) +static int +_font_cache_keys_equal (void *cache, + void *k1, + void *k2) { + cairo_font_cache_key_t *a, *b; + a = (cairo_font_cache_key_t *) k1; + b = (cairo_font_cache_key_t *) k2; + + return (strcmp (a->family, b->family) == 0) + && (a->weight == b->weight) + && (a->slant == b->slant); +} + + +static cairo_status_t +_font_cache_create_entry (void *cache, + void *key, + void **return_value) +{ + cairo_font_cache_key_t *k; + cairo_font_cache_entry_t *entry; + k = (cairo_font_cache_key_t *) key; + const struct cairo_font_backend *backend = CAIRO_FONT_BACKEND_DEFAULT; /* XXX: The current freetype backend may return NULL, (for example @@ -58,365 +98,428 @@ _cairo_font_create (const char *family, * like to build in some sort fo font here, (even a really lame, * ugly one if necessary). */ - return backend->create (family, slant, weight); + entry = malloc (sizeof (cairo_font_cache_entry_t)); + if (entry == NULL) + goto FAIL; + + entry->key.slant = k->slant; + entry->key.weight = k->weight; + entry->key.family = strdup(k->family); + if (entry->key.family == NULL) + goto FREE_ENTRY; + + entry->unscaled = backend->create (k->family, k->slant, k->weight); + if (entry->unscaled == NULL) + goto FREE_FAMILY; + + /* Not sure how to measure backend font mem; use a simple count for now.*/ + entry->key.base.memory = 1; + *return_value = entry; + return CAIRO_STATUS_SUCCESS; + + FREE_FAMILY: + free ((void *) entry->key.family); + + FREE_ENTRY: + free (entry); + + FAIL: + return CAIRO_STATUS_NO_MEMORY; } -cairo_status_t -_cairo_font_init (cairo_font_t *font, - const struct cairo_font_backend *backend) +static void +_font_cache_destroy_entry (void *cache, + void *entry) { - cairo_matrix_set_identity (&font->matrix); - font->refcount = 1; - font->backend = backend; - font->glyph_cache = _cairo_glyph_cache_create (); - if (font->glyph_cache == NULL) - return CAIRO_STATUS_NO_MEMORY; + cairo_font_cache_entry_t *e; - return CAIRO_STATUS_SUCCESS; + e = (cairo_font_cache_entry_t *) entry; + _cairo_unscaled_font_destroy (e->unscaled); + free ((void *) e->key.family); + free (e); } -cairo_font_t * -_cairo_font_copy (cairo_font_t *font) +static void +_font_cache_destroy_cache (void *cache) { - cairo_font_t *newfont = NULL; - char *tmp = NULL; + free (cache); +} - if (font == NULL || font->backend->copy == NULL) - return NULL; - - newfont = font->backend->copy (font); - if (newfont == NULL) { - free (tmp); - return NULL; - } +const struct cairo_cache_backend cairo_font_cache_backend = { + _font_cache_hash, + _font_cache_keys_equal, + _font_cache_create_entry, + _font_cache_destroy_entry, + _font_cache_destroy_cache +}; - newfont->refcount = 1; - cairo_matrix_copy(&newfont->matrix, &font->matrix); - newfont->backend = font->backend; - if (newfont->glyph_cache) - _cairo_glyph_cache_destroy (newfont->glyph_cache); - - newfont->glyph_cache = font->glyph_cache; - _cairo_glyph_cache_reference (font->glyph_cache); - - return newfont; +static void +_lock_global_font_cache (void) +{ + /* FIXME: implement locking. */ } -cairo_status_t -_cairo_font_scale (cairo_font_t *font, double scale) +static void +_unlock_global_font_cache (void) { - return cairo_matrix_scale (&font->matrix, scale, scale); + /* FIXME: implement locking. */ } -cairo_status_t -_cairo_font_transform (cairo_font_t *font, cairo_matrix_t *matrix) +static cairo_cache_t * +_global_font_cache = NULL; + +static cairo_cache_t * +_get_global_font_cache (void) { - return cairo_matrix_multiply (&font->matrix, matrix, &font->matrix); + if (_global_font_cache == NULL) { + _global_font_cache = malloc (sizeof (cairo_cache_t)); + + if (_global_font_cache == NULL) + goto FAIL; + + if (_cairo_cache_init (_global_font_cache, + &cairo_font_cache_backend, + CAIRO_FONT_CACHE_NUM_FONTS_DEFAULT)) + goto FAIL; + } + + return _global_font_cache; + + FAIL: + if (_global_font_cache) + free (_global_font_cache); + _global_font_cache = NULL; + return NULL; } -cairo_status_t -_cairo_font_text_extents (cairo_font_t *font, - const unsigned char *utf8, - cairo_text_extents_t *extents) +/* Now the internal "unscaled + scale" font API */ + +cairo_unscaled_font_t * +_cairo_unscaled_font_create (const char *family, + cairo_font_slant_t slant, + cairo_font_weight_t weight) { - return font->backend->text_extents(font, utf8, extents); + cairo_cache_t * cache; + cairo_font_cache_key_t key; + cairo_font_cache_entry_t *font; + cairo_status_t status; + + _lock_global_font_cache (); + cache = _get_global_font_cache (); + if (cache == NULL) { + _unlock_global_font_cache (); + return NULL; + } + + key.family = family; + key.slant = slant; + key.weight = weight; + + status = _cairo_cache_lookup (cache, &key, (void **) &font); + if (status) { + _unlock_global_font_cache (); + return NULL; + } + + _cairo_unscaled_font_reference (font->unscaled); + _unlock_global_font_cache (); + return font->unscaled; } -cairo_status_t -_cairo_font_glyph_extents (cairo_font_t *font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_text_extents_t *extents) +void +_cairo_font_init (cairo_font_t *scaled, + cairo_font_scale_t *scale, + cairo_unscaled_font_t *unscaled) { - return font->backend->glyph_extents(font, glyphs, num_glyphs, extents); + scaled->scale = *scale; + scaled->unscaled = unscaled; + scaled->refcount = 1; } cairo_status_t -_cairo_font_text_bbox (cairo_font_t *font, - cairo_surface_t *surface, - double x, - double y, - const unsigned char *utf8, - cairo_box_t *bbox) +_cairo_unscaled_font_init (cairo_unscaled_font_t *font, + const struct cairo_font_backend *backend) { - return font->backend->text_bbox (font, surface, x, y, utf8, bbox); + font->refcount = 1; + font->backend = backend; + return CAIRO_STATUS_SUCCESS; } + cairo_status_t -_cairo_font_glyph_bbox (cairo_font_t *font, - cairo_surface_t *surface, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_box_t *bbox) +_cairo_unscaled_font_text_to_glyphs (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + const unsigned char *utf8, + cairo_glyph_t **glyphs, + int *num_glyphs) { - return font->backend->glyph_bbox (font, surface, glyphs, num_glyphs, bbox); + return font->backend->text_to_glyphs (font, scale, utf8, glyphs, num_glyphs); } cairo_status_t -_cairo_font_show_text (cairo_font_t *font, - cairo_operator_t operator, - cairo_surface_t *source, - cairo_surface_t *surface, - int source_x, - int source_y, - double x, - double y, - const unsigned char *utf8) +_cairo_unscaled_font_glyph_extents (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_glyph_t *glyphs, + int num_glyphs, + cairo_text_extents_t *extents) { - return font->backend->show_text(font, operator, source, - surface, source_x, source_y, x, y, utf8); + return font->backend->glyph_extents(font, scale, glyphs, num_glyphs, extents); } + cairo_status_t -_cairo_font_show_glyphs (cairo_font_t *font, - cairo_operator_t operator, - cairo_surface_t *source, - cairo_surface_t *surface, - int source_x, - int source_y, - cairo_glyph_t *glyphs, - int num_glyphs) +_cairo_unscaled_font_glyph_bbox (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_glyph_t *glyphs, + int num_glyphs, + cairo_box_t *bbox) { - return font->backend->show_glyphs(font, operator, source, - surface, source_x, source_y, - glyphs, num_glyphs); + return font->backend->glyph_bbox (font, scale, glyphs, num_glyphs, bbox); } cairo_status_t -_cairo_font_text_path (cairo_font_t *font, - double x, - double y, - const unsigned char *utf8, - cairo_path_t *path) +_cairo_unscaled_font_show_glyphs (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_operator_t operator, + cairo_surface_t *source, + cairo_surface_t *surface, + int source_x, + int source_y, + cairo_glyph_t *glyphs, + int num_glyphs) { - return font->backend->text_path(font, x, y, utf8, path); + cairo_status_t status; + if (surface->backend->show_glyphs != NULL) { + status = surface->backend->show_glyphs (font, scale, operator, source, + surface, source_x, source_y, + glyphs, num_glyphs); + if (status == CAIRO_STATUS_SUCCESS) + return status; + } + + /* Surface display routine either does not exist or failed. */ + return font->backend->show_glyphs (font, scale, operator, source, + surface, source_x, source_y, + glyphs, num_glyphs); } cairo_status_t -_cairo_font_glyph_path (cairo_font_t *font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_path_t *path) +_cairo_unscaled_font_glyph_path (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_glyph_t *glyphs, + int num_glyphs, + cairo_path_t *path) { - return font->backend->glyph_path(font, glyphs, num_glyphs, path); + return font->backend->glyph_path (font, scale, glyphs, num_glyphs, path); } cairo_status_t -_cairo_font_font_extents (cairo_font_t *font, - cairo_font_extents_t *extents) +_cairo_unscaled_font_font_extents (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_font_extents_t *extents) { - return font->backend->font_extents(font, extents); + return font->backend->font_extents(font, scale, extents); } -static void -_cairo_glyph_cache_pop_last (cairo_glyph_cache_t *glyph_cache) +void +_cairo_unscaled_font_reference (cairo_unscaled_font_t *font) { - if (glyph_cache->last) { - cairo_glyph_surface_node_t *remove = glyph_cache->last; - - cairo_surface_destroy (remove->s.surface); - glyph_cache->last = remove->prev; - if (glyph_cache->last) - glyph_cache->last->next = NULL; + font->refcount++; +} - free (remove); - glyph_cache->n_nodes--; - } +void +_cairo_unscaled_font_destroy (cairo_unscaled_font_t *font) +{ + if (--(font->refcount) > 0) + return; + + if (font->backend) + font->backend->destroy (font); } -static cairo_glyph_cache_t * -_cairo_glyph_cache_create (void) -{ - cairo_glyph_cache_t *glyph_cache; - - glyph_cache = malloc (sizeof (cairo_glyph_cache_t)); - if (glyph_cache == NULL) - return NULL; - - glyph_cache->n_nodes = 0; - glyph_cache->first = NULL; - glyph_cache->last = NULL; - glyph_cache->cache_size = CAIRO_FONT_CACHE_SIZE_DEFAULT; - glyph_cache->ref_count = 1; - return glyph_cache; + +/* Public font API follows. */ + +void +cairo_font_reference (cairo_font_t *font) +{ + font->refcount++; } -static void -_cairo_glyph_cache_reference (cairo_glyph_cache_t *glyph_cache) +void +cairo_font_destroy (cairo_font_t *font) { - if (glyph_cache == NULL) + if (--(font->refcount) > 0) return; - glyph_cache->ref_count++; + if (font->unscaled) + _cairo_unscaled_font_destroy (font->unscaled); + + free (font); } -static void -_cairo_glyph_cache_destroy (cairo_glyph_cache_t *glyph_cache) +void +cairo_font_set_transform (cairo_font_t *font, + cairo_matrix_t *matrix) { - if (glyph_cache == NULL) - return; + double dummy; + cairo_matrix_get_affine (matrix, + &font->scale.matrix[0][0], + &font->scale.matrix[0][1], + &font->scale.matrix[1][0], + &font->scale.matrix[1][1], + &dummy, &dummy); +} - glyph_cache->ref_count--; - if (glyph_cache->ref_count) - return; +void +cairo_font_current_transform (cairo_font_t *font, + cairo_matrix_t *matrix) +{ + cairo_matrix_set_affine (matrix, + font->scale.matrix[0][0], + font->scale.matrix[0][1], + font->scale.matrix[1][0], + font->scale.matrix[1][1], + 0, 0); +} - while (glyph_cache->last) - _cairo_glyph_cache_pop_last (glyph_cache); - free (glyph_cache); +/* Now we implement functions to access a default global image & metrics + * cache. + */ + +unsigned long +_cairo_glyph_cache_hash (void *cache, void *key) +{ + cairo_glyph_cache_key_t *in; + in = (cairo_glyph_cache_key_t *) key; + return + ((unsigned long) in->unscaled) + ^ ((unsigned long) in->scale.matrix[0][0]) + ^ ((unsigned long) in->scale.matrix[0][1]) + ^ ((unsigned long) in->scale.matrix[1][0]) + ^ ((unsigned long) in->scale.matrix[1][1]) + ^ in->index; } -static void -_cairo_glyph_surface_init (cairo_font_t *font, - cairo_surface_t *surface, - const cairo_glyph_t *glyph, - cairo_glyph_surface_t *glyph_surface) +int +_cairo_glyph_cache_keys_equal (void *cache, + void *k1, + void *k2) { - cairo_surface_t *image; - - glyph_surface->surface = NULL; - glyph_surface->index = glyph->index; - glyph_surface->matrix[0][0] = font->matrix.m[0][0]; - glyph_surface->matrix[0][1] = font->matrix.m[0][1]; - glyph_surface->matrix[1][0] = font->matrix.m[1][0]; - glyph_surface->matrix[1][1] = font->matrix.m[1][1]; - - image = font->backend->create_glyph (font, glyph, &glyph_surface->size); - if (image == NULL) - return; - - if (surface->backend != image->backend) { - cairo_status_t status; - - glyph_surface->surface = - _cairo_surface_create_similar_scratch (surface, - CAIRO_FORMAT_A8, 0, - glyph_surface->size.width, - glyph_surface->size.height); - if (glyph_surface->surface == NULL) { - glyph_surface->surface = image; - return; - } - - status = _cairo_surface_set_image (glyph_surface->surface, - (cairo_image_surface_t *) image); - if (status) { - cairo_surface_destroy (glyph_surface->surface); - glyph_surface->surface = NULL; - } - cairo_surface_destroy (image); - } else - glyph_surface->surface = image; + cairo_glyph_cache_key_t *a, *b; + a = (cairo_glyph_cache_key_t *) k1; + b = (cairo_glyph_cache_key_t *) k2; + return (a->index == b->index) + && (a->unscaled == b->unscaled) + && (a->scale.matrix[0][0] == b->scale.matrix[0][0]) + && (a->scale.matrix[0][1] == b->scale.matrix[0][1]) + && (a->scale.matrix[1][0] == b->scale.matrix[1][0]) + && (a->scale.matrix[1][1] == b->scale.matrix[1][1]); } -cairo_surface_t * -_cairo_font_lookup_glyph (cairo_font_t *font, - cairo_surface_t *surface, - const cairo_glyph_t *glyph, - cairo_glyph_size_t *return_size) + +static cairo_status_t +_image_glyph_cache_create_entry (void *cache, + void *key, + void **return_value) { - cairo_glyph_surface_t glyph_surface; - cairo_glyph_cache_t *cache = font->glyph_cache; - cairo_glyph_surface_node_t *node; - - for (node = cache->first; node != NULL; node = node->next) { - cairo_glyph_surface_t *s = &node->s; - - if ((s->surface == NULL || s->surface->backend == surface->backend) && - s->index == glyph->index && - s->matrix[0][0] == font->matrix.m[0][0] && - s->matrix[0][1] == font->matrix.m[0][1] && - s->matrix[1][0] == font->matrix.m[1][0] && - s->matrix[1][1] == font->matrix.m[1][1]) { - - /* move node first in cache */ - if (node->prev) { - if (node->next == NULL) { - cache->last = node->prev; - node->prev->next = NULL; - } else { - node->prev->next = node->next; - node->next->prev = node->prev; - } - - node->prev = NULL; - node->next = cache->first; - cache->first = node; - if (node->next) - node->next->prev = node; - else - cache->last = node; - } - - cairo_surface_reference (s->surface); - *return_size = s->size; - - return s->surface; - } - } - - _cairo_glyph_surface_init (font, surface, glyph, &glyph_surface); + cairo_glyph_cache_key_t *k = (cairo_glyph_cache_key_t *) key; + cairo_image_glyph_cache_entry_t *im; + cairo_status_t status; - *return_size = glyph_surface.size; - - if (cache->cache_size > 0) { - if (cache->n_nodes == cache->cache_size) - _cairo_glyph_cache_pop_last (cache); - - node = malloc (sizeof (cairo_glyph_surface_node_t)); - if (node) { - cairo_surface_reference (glyph_surface.surface); - - /* insert node first in cache */ - node->s = glyph_surface; - node->prev = NULL; - node->next = cache->first; - cache->first = node; - if (node->next) - node->next->prev = node; - else - cache->last = node; - - cache->n_nodes++; - } + im = calloc (1, sizeof (cairo_image_glyph_cache_entry_t)); + if (im == NULL) + return CAIRO_STATUS_NO_MEMORY; + + im->key = *k; + status = im->key.unscaled->backend->create_glyph (im); + + if (status != CAIRO_STATUS_SUCCESS) { + free (im); + return status; } - - return glyph_surface.surface; + + _cairo_unscaled_font_reference (im->key.unscaled); + + im->key.base.memory = + sizeof (cairo_image_glyph_cache_entry_t) + + (im->image ? + sizeof (cairo_image_surface_t) + + 28 * sizeof (int) /* rough guess at size of pixman image structure */ + + (im->image->height * im->image->stride) : 0); + + *return_value = im; + + return CAIRO_STATUS_SUCCESS; } -/* public font interface follows */ -void -cairo_font_reference (cairo_font_t *font) +static void +_image_glyph_cache_destroy_entry (void *cache, + void *value) { - font->refcount++; + cairo_image_glyph_cache_entry_t *im; + + im = (cairo_image_glyph_cache_entry_t *) value; + _cairo_unscaled_font_destroy (im->key.unscaled); + cairo_surface_destroy (&(im->image->base)); + free (im); } -void -cairo_font_destroy (cairo_font_t *font) +static void +_image_glyph_cache_destroy_cache (void *cache) { - if (--(font->refcount) > 0) - return; + free (cache); +} - _cairo_glyph_cache_destroy (font->glyph_cache); +const cairo_cache_backend_t cairo_image_cache_backend = { + _cairo_glyph_cache_hash, + _cairo_glyph_cache_keys_equal, + _image_glyph_cache_create_entry, + _image_glyph_cache_destroy_entry, + _image_glyph_cache_destroy_cache +}; - if (font->backend->destroy) - font->backend->destroy (font); -} void -cairo_font_set_transform (cairo_font_t *font, - cairo_matrix_t *matrix) +_cairo_lock_global_image_glyph_cache() { - cairo_matrix_copy (&(font->matrix), matrix); + /* FIXME: implement locking. */ } void -cairo_font_current_transform (cairo_font_t *font, - cairo_matrix_t *matrix) +_cairo_unlock_global_image_glyph_cache() { - cairo_matrix_copy (matrix, &(font->matrix)); + /* FIXME: implement locking. */ +} + +static cairo_cache_t * +_global_image_glyph_cache = NULL; + +cairo_cache_t * +_cairo_get_global_image_glyph_cache () +{ + if (_global_image_glyph_cache == NULL) { + _global_image_glyph_cache = malloc (sizeof (cairo_cache_t)); + + if (_global_image_glyph_cache == NULL) + goto FAIL; + + if (_cairo_cache_init (_global_image_glyph_cache, + &cairo_image_cache_backend, + CAIRO_IMAGE_GLYPH_CACHE_MEMORY_DEFAULT)) + goto FAIL; + } + + return _global_image_glyph_cache; + + FAIL: + if (_global_image_glyph_cache) + free (_global_image_glyph_cache); + _global_image_glyph_cache = NULL; + return NULL; } diff --git a/src/cairo_ft_font.c b/src/cairo_ft_font.c index 5b0a7f641..740613501 100644 --- a/src/cairo_ft_font.c +++ b/src/cairo_ft_font.c @@ -31,116 +31,294 @@ #include FT_OUTLINE_H #include FT_IMAGE_H -typedef struct { - cairo_font_t base; +#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0)) +#define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0) +#define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0)) +#define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0) - FT_Library ft_library; - int owns_ft_library; +/* + * First we make a private, sharable implementation object which can be + * stored both in a private cache and in public font objects (including + * those connected to fonts we don't own) + */ + +typedef struct { + int refcount; FT_Face face; int owns_face; - FcPattern *pattern; -} cairo_ft_font_t; +} ft_font_val_t; -#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0)) -#define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0) -#define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0)) -#define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0) +static ft_font_val_t * +_create_from_face (FT_Face face, int owns_face) +{ + ft_font_val_t *tmp = malloc (sizeof(ft_font_val_t)); + if (tmp) { + tmp->refcount = 1; + tmp->face = face; + tmp->owns_face = owns_face; + FT_Set_Char_Size (face, + DOUBLE_TO_26_6 (1.0), + DOUBLE_TO_26_6 (1.0), + 0, 0); + } + return tmp; +} -/* implement the platform-specific interface */ +static void +_reference_font_val (ft_font_val_t *f) +{ + f->refcount++; +} -cairo_font_t * -cairo_ft_font_create (FT_Library ft_library, FcPattern *pattern) +static void +_destroy_font_val (ft_font_val_t *f) { - cairo_ft_font_t *f = NULL; + if (--(f->refcount) > 0) + return; + + if (f->owns_face) + FT_Done_Face (f->face); + + free (f); +} + +static ft_font_val_t * +_create_from_library_and_pattern (FT_Library ft_library, FcPattern *pattern) +{ + ft_font_val_t *f = NULL; char *filename = NULL; - FT_Face face = NULL; int owns_face = 0; + FT_Face face = NULL; FcPattern *resolved = NULL; FcResult result = FcResultMatch; - + + if (pattern == NULL) + goto FAIL; + FcConfigSubstitute (0, pattern, FcMatchPattern); FcDefaultSubstitute (pattern); resolved = FcFontMatch (0, pattern, &result); + if (!resolved) + goto FAIL; + if (result != FcResultMatch) - { - if (resolved) - FcPatternDestroy (resolved); - return NULL; - } + goto FREE_RESOLVED; /* If the pattern has an FT_Face object, use that. */ if (FcPatternGetFTFace (resolved, FC_FT_FACE, 0, &face) != FcResultMatch || face == NULL) { - /* otherwise it had better have a filename */ - int open_res = 0; - owns_face = 1; result = FcPatternGetString (resolved, FC_FILE, 0, (FcChar8 **)(&filename)); if (result == FcResultMatch) - open_res = FT_New_Face (ft_library, filename, 0, &face); + if (FT_New_Face (ft_library, filename, 0, &face)) + goto FREE_RESOLVED; if (face == NULL) - return NULL; + goto FREE_RESOLVED; + + owns_face = 1; } - f = (cairo_ft_font_t *) cairo_ft_font_create_for_ft_face (face); - if (f != NULL) - f->pattern = FcPatternDuplicate (resolved); + f = _create_from_face (face, owns_face); + + FcPatternDestroy (resolved); + return f; + + FREE_RESOLVED: + if (resolved) + FcPatternDestroy (resolved); + + FAIL: + return NULL; +} - f->ft_library = ft_library; - f->owns_ft_library = 0; - f->owns_face = owns_face; +/* + * We then make the user-exposed structure out of one of these impls, such + * that it is reasonably cheap to copy and/or destroy. Unfortunately this + * duplicates a certain amount of the caching machinery in the font cache, + * but that's unavoidable as we also provide an FcPattern resolution API, + * which is not part of cairo's generic font finding system. + */ - FcPatternDestroy (resolved); - return (cairo_font_t *) f; +typedef struct { + cairo_unscaled_font_t base; + FcPattern *pattern; + ft_font_val_t *val; +} cairo_ft_font_t; + +/* + * We then make a key and entry type which are compatible with the generic + * cache system. This cache serves to share single ft_font_val_t instances + * between fonts (or between font lifecycles). + */ + +typedef struct { + cairo_cache_entry_base_t base; + FcPattern *pattern; +} cairo_ft_cache_key_t; + +typedef struct { + cairo_ft_cache_key_t key; + ft_font_val_t *val; +} cairo_ft_cache_entry_t; + +/* + * Then we create a cache which maps FcPattern keys to the refcounted + * ft_font_val_t values. + */ + +typedef struct { + cairo_cache_t base; + FT_Library lib; +} ft_cache_t; + + +static unsigned long +_ft_font_cache_hash (void *cache, void *key) +{ + cairo_ft_cache_key_t *in; + in = (cairo_ft_cache_key_t *) key; + return FcPatternHash (in->pattern); } -FT_Face -cairo_ft_font_face (cairo_font_t *abstract_font) +static int +_ft_font_cache_keys_equal (void *cache, + void *k1, + void *k2) { - cairo_ft_font_t *font = (cairo_ft_font_t *) abstract_font; + cairo_ft_cache_key_t *a; + cairo_ft_cache_key_t *b; + a = (cairo_ft_cache_key_t *) k1; + b = (cairo_ft_cache_key_t *) k2; + + return FcPatternEqual (a->pattern, b->pattern); +} - if (font == NULL) - return NULL; - return font->face; +static cairo_status_t +_ft_font_cache_create_entry (void *cache, + void *key, + void **return_entry) +{ + ft_cache_t *ftcache = (ft_cache_t *) cache; + cairo_ft_cache_key_t *k = (cairo_ft_cache_key_t *) key; + cairo_ft_cache_entry_t *entry; + + entry = malloc (sizeof (cairo_ft_cache_entry_t)); + if (entry == NULL) + return CAIRO_STATUS_NO_MEMORY; + + entry->key.pattern = FcPatternDuplicate (k->pattern); + if (!entry->key.pattern) { + free (entry); + return CAIRO_STATUS_NO_MEMORY; + } + + entry->val = _create_from_library_and_pattern (ftcache->lib, entry->key.pattern); + entry->key.base.memory = 1; + + *return_entry = entry; + + return CAIRO_STATUS_SUCCESS; } -FcPattern * -cairo_ft_font_pattern (cairo_font_t *abstract_font) +static void +_ft_font_cache_destroy_entry (void *cache, + void *entry) +{ + cairo_ft_cache_entry_t *e = (cairo_ft_cache_entry_t *) entry; + FcPatternDestroy (e->key.pattern); + _destroy_font_val (e->val); + free (e); +} + +static void +_ft_font_cache_destroy_cache (void *cache) { - cairo_ft_font_t *font = (cairo_ft_font_t *) abstract_font; + ft_cache_t *fc = (ft_cache_t *) cache; + FT_Done_FreeType (fc->lib); + free (fc); +} - if (font == NULL) - return NULL; +const struct cairo_cache_backend _ft_font_cache_backend = { + _ft_font_cache_hash, + _ft_font_cache_keys_equal, + _ft_font_cache_create_entry, + _ft_font_cache_destroy_entry, + _ft_font_cache_destroy_cache +}; - return font->pattern; + +static ft_cache_t *_global_ft_cache = NULL; + +static void +_lock_global_ft_cache (void) +{ + /* FIXME: Perform locking here. */ +} + +static void +_unlock_global_ft_cache (void) +{ + /* FIXME: Perform locking here. */ +} + +static cairo_cache_t * +_get_global_ft_cache (void) +{ + if (_global_ft_cache == NULL) + { + _global_ft_cache = malloc (sizeof(ft_cache_t)); + if (!_global_ft_cache) + goto FAIL; + + if (_cairo_cache_init (&_global_ft_cache->base, + &_ft_font_cache_backend, + CAIRO_FT_CACHE_NUM_FONTS_DEFAULT)) + goto FAIL; + + if (FT_Init_FreeType (&_global_ft_cache->lib)) + goto FAIL; + } + return &_global_ft_cache->base; + + FAIL: + if (_global_ft_cache) + free (_global_ft_cache); + _global_ft_cache = NULL; + return NULL; } /* implement the backend interface */ -static cairo_font_t * +const struct cairo_font_backend cairo_ft_font_backend; + +static cairo_unscaled_font_t * _cairo_ft_font_create (const char *family, cairo_font_slant_t slant, cairo_font_weight_t weight) { - cairo_ft_font_t *ft_font = NULL; - cairo_font_t *font = NULL; - FcPattern * pat = NULL; + cairo_status_t status; + cairo_ft_font_t *font = NULL; int fcslant; int fcweight; - FT_Library ft_library; - FT_Error error; + cairo_cache_t *cache; + cairo_ft_cache_entry_t *entry; + cairo_ft_cache_key_t key; - pat = FcPatternCreate (); - if (pat == NULL) - return NULL; + key.pattern = FcPatternCreate (); + if (key.pattern == NULL) + goto FAIL; + + font = malloc (sizeof (cairo_ft_font_t)); + if (font == NULL) + goto FREE_PATTERN; switch (weight) { @@ -167,52 +345,44 @@ _cairo_ft_font_create (const char *family, break; } - FcPatternAddString (pat, FC_FAMILY, family); - FcPatternAddInteger (pat, FC_SLANT, fcslant); - FcPatternAddInteger (pat, FC_WEIGHT, fcweight); + FcPatternAddString (key.pattern, FC_FAMILY, family); + FcPatternAddInteger (key.pattern, FC_SLANT, fcslant); + FcPatternAddInteger (key.pattern, FC_WEIGHT, fcweight); - error = FT_Init_FreeType (&ft_library); - if (error) { - FcPatternDestroy (pat); - return NULL; - } + if (_cairo_unscaled_font_init (&font->base, &cairo_ft_font_backend)) + goto FREE_PATTERN; - font = cairo_ft_font_create (ft_library, pat); - if (font == NULL) - return NULL; + _lock_global_ft_cache (); + cache = _get_global_ft_cache (); + if (cache == NULL) { + _unlock_global_ft_cache (); + goto FREE_PATTERN; + } - ft_font = (cairo_ft_font_t *) font; + status = _cairo_cache_lookup (cache, &key, (void **) &entry); + _unlock_global_ft_cache (); - ft_font->owns_ft_library = 1; + if (status) + goto FREE_PATTERN; - FT_Set_Char_Size (ft_font->face, - DOUBLE_TO_26_6 (1.0), - DOUBLE_TO_26_6 (1.0), - 0, 0); - - FcPatternDestroy (pat); - return font; -} + font->pattern = FcPatternDuplicate (entry->key.pattern); + if (font->pattern == NULL) + goto FREE_PATTERN; -static cairo_font_t * -_cairo_ft_font_copy (void *abstract_font) -{ - cairo_ft_font_t * font_new = NULL; - cairo_ft_font_t * font = abstract_font; - - if (font->base.backend != &cairo_ft_font_backend) - return NULL; + font->val = entry->val; + _reference_font_val (font->val); + + return &font->base; - font_new = (cairo_ft_font_t *) cairo_ft_font_create_for_ft_face (font->face); - if (font_new == NULL) - return NULL; + FREE_PATTERN: + FcPatternDestroy (key.pattern); - if (font_new != NULL && font->pattern != NULL) - font_new->pattern = FcPatternDuplicate (font->pattern); + FAIL: + return NULL; - return (cairo_font_t *) font_new; } + static void _cairo_ft_font_destroy (void *abstract_font) { @@ -220,15 +390,11 @@ _cairo_ft_font_destroy (void *abstract_font) if (font == NULL) return; - - if (font->face != NULL && font->owns_face) - FT_Done_Face (font->face); if (font->pattern != NULL) FcPatternDestroy (font->pattern); - if (font->ft_library && font->owns_ft_library) - FT_Done_FreeType (font->ft_library); + _destroy_font_val (font->val); free (font); } @@ -268,7 +434,7 @@ _utf8_to_ucs4 (char const *utf8, } static void -_install_font_matrix(cairo_matrix_t *matrix, FT_Face face) +_install_font_scale (cairo_font_scale_t *sc, FT_Face face) { cairo_matrix_t normalized; double scale_x, scale_y; @@ -276,16 +442,20 @@ _install_font_matrix(cairo_matrix_t *matrix, FT_Face face) FT_Matrix mat; /* The font matrix has x and y "scale" components which we extract and - * use as pixel scale values. These influence the way freetype chooses - * hints, as well as selecting different bitmaps in hand-rendered - * fonts. We also copy the normalized matrix to freetype's - * transformation. + * use as character scale values. These influence the way freetype + * chooses hints, as well as selecting different bitmaps in + * hand-rendered fonts. We also copy the normalized matrix to + * freetype's transformation. */ - _cairo_matrix_compute_scale_factors (matrix, &scale_x, &scale_y); - - cairo_matrix_copy (&normalized, matrix); + cairo_matrix_set_affine (&normalized, + sc->matrix[0][0], + sc->matrix[0][1], + sc->matrix[1][0], + sc->matrix[1][1], + 0, 0); + _cairo_matrix_compute_scale_factors (&normalized, &scale_x, &scale_y); cairo_matrix_scale (&normalized, 1.0 / scale_x, 1.0 / scale_y); cairo_matrix_get_affine (&normalized, &xx /* 00 */ , &yx /* 01 */, @@ -298,21 +468,28 @@ _install_font_matrix(cairo_matrix_t *matrix, FT_Face face) mat.yy = DOUBLE_TO_16_16(yy); FT_Set_Transform(face, &mat, NULL); - FT_Set_Char_Size(face, - DOUBLE_TO_26_6(scale_x), - DOUBLE_TO_26_6(scale_y), - 0, 0); + + FT_Set_Pixel_Sizes(face, + (FT_UInt) scale_x, + (FT_UInt) scale_y); } -static int -_utf8_to_glyphs (cairo_ft_font_t *font, - const unsigned char *utf8, - double x0, - double y0, - cairo_glyph_t **glyphs, - size_t *nglyphs) +static cairo_status_t +_cairo_ft_font_text_to_glyphs (void *abstract_font, + cairo_font_scale_t *sc, + const unsigned char *utf8, + cairo_glyph_t **glyphs, + int *nglyphs) { - FT_Face face = font->face; + cairo_ft_font_t *font = abstract_font; + FT_Face face = font->val->face; + cairo_glyph_cache_key_t key; + cairo_image_glyph_cache_entry_t *val; + cairo_cache_t *cache; + + key.unscaled = &font->base; + key.scale = *sc; + double x = 0., y = 0.; size_t i; FT_ULong *ucs4 = NULL; @@ -320,56 +497,70 @@ _utf8_to_glyphs (cairo_ft_font_t *font, _utf8_to_ucs4 (utf8, &ucs4, nglyphs); if (ucs4 == NULL) - return 0; + return CAIRO_STATUS_NO_MEMORY; *glyphs = (cairo_glyph_t *) malloc ((*nglyphs) * (sizeof (cairo_glyph_t))); if (*glyphs == NULL) { free (ucs4); - return 0; + return CAIRO_STATUS_NO_MEMORY; } - _install_font_matrix (&font->base.matrix, face); + _cairo_lock_global_image_glyph_cache (); + cache = _cairo_get_global_image_glyph_cache (); + if (cache == NULL) { + _cairo_unlock_global_image_glyph_cache (); + return CAIRO_STATUS_NO_MEMORY; + } for (i = 0; i < *nglyphs; i++) { (*glyphs)[i].index = FT_Get_Char_Index (face, ucs4[i]); - (*glyphs)[i].x = x0 + x; - (*glyphs)[i].y = y0 + y; - - FT_Load_Glyph (face, (*glyphs)[i].index, FT_LOAD_DEFAULT); + (*glyphs)[i].x = x; + (*glyphs)[i].y = y; - x += DOUBLE_FROM_26_6 (face->glyph->advance.x); - y -= DOUBLE_FROM_26_6 (face->glyph->advance.y); + val = NULL; + key.index = (*glyphs)[i].index; + + if (_cairo_cache_lookup (cache, &key, (void **) &val) + != CAIRO_STATUS_SUCCESS || val == NULL) + continue; + + x += val->extents.x_advance; + y -= val->extents.y_advance; } + _cairo_unlock_global_image_glyph_cache (); free (ucs4); - return 1; + return CAIRO_STATUS_SUCCESS; } + static cairo_status_t _cairo_ft_font_font_extents (void *abstract_font, + cairo_font_scale_t *sc, cairo_font_extents_t *extents) { cairo_ft_font_t *font = abstract_font; - FT_Face face = font->face; - double scale_x, scale_y; + FT_Face face = font->val->face; + FT_Size_Metrics *metrics = &face->size->metrics; - double upm = face->units_per_EM; + _install_font_scale (sc, face); - _cairo_matrix_compute_scale_factors (&font->base.matrix, &scale_x, &scale_y); + extents->ascent = DOUBLE_FROM_26_6(metrics->ascender); + extents->descent = DOUBLE_FROM_26_6(metrics->descender); + extents->height = DOUBLE_FROM_26_6(metrics->height); + extents->max_x_advance = DOUBLE_FROM_26_6(metrics->max_advance); - extents->ascent = face->ascender / upm * scale_y; - extents->descent = face->descender / upm * scale_y; - extents->height = face->height / upm * scale_y; - extents->max_x_advance = face->max_advance_width / upm * scale_x; - extents->max_y_advance = face->max_advance_height / upm * scale_y; + /* FIXME: this doesn't do vertical layout atm. */ + extents->max_y_advance = 0.0; return CAIRO_STATUS_SUCCESS; } static cairo_status_t _cairo_ft_font_glyph_extents (void *abstract_font, + cairo_font_scale_t *sc, cairo_glyph_t *glyphs, int num_glyphs, cairo_text_extents_t *extents) @@ -379,10 +570,10 @@ _cairo_ft_font_glyph_extents (void *abstract_font, cairo_point_double_t origin; cairo_point_double_t glyph_min, glyph_max; cairo_point_double_t total_min, total_max; - FT_Error error; - FT_Face face = font->face; - FT_GlyphSlot glyph = face->glyph; - FT_Glyph_Metrics *metrics = &glyph->metrics; + + cairo_image_glyph_cache_entry_t *img = NULL; + cairo_cache_t *cache; + cairo_glyph_cache_key_t key; if (num_glyphs == 0) { @@ -399,24 +590,33 @@ _cairo_ft_font_glyph_extents (void *abstract_font, origin.x = glyphs[0].x; origin.y = glyphs[0].y; - _install_font_matrix (&font->base.matrix, face); + _cairo_lock_global_image_glyph_cache (); + cache = _cairo_get_global_image_glyph_cache (); + if (cache == NULL) { + _cairo_unlock_global_image_glyph_cache (); + return CAIRO_STATUS_NO_MEMORY; + } + + key.unscaled = &font->base; + key.scale = *sc; for (i = 0; i < num_glyphs; i++) { - error = FT_Load_Glyph (face, glyphs[i].index, FT_LOAD_DEFAULT); - /* XXX: What to do in this error case? */ - if (error) + img = NULL; + key.index = glyphs[i].index; + if (_cairo_cache_lookup (cache, &key, (void **) &img) + != CAIRO_STATUS_SUCCESS || img == NULL) continue; - + /* XXX: Need to add code here to check the font's FcPattern for FC_VERTICAL_LAYOUT and if set get vertBearingX/Y instead. This will require that cairo_ft_font_create_for_ft_face accept an FcPattern. */ - glyph_min.x = glyphs[i].x + DOUBLE_FROM_26_6 (metrics->horiBearingX); - glyph_min.y = glyphs[i].y - DOUBLE_FROM_26_6 (metrics->horiBearingY); - glyph_max.x = glyph_min.x + DOUBLE_FROM_26_6 (metrics->width); - glyph_max.y = glyph_min.y + DOUBLE_FROM_26_6 (metrics->height); + glyph_min.x = glyphs[i].x + img->extents.x_bearing; + glyph_min.y = glyphs[i].y - img->extents.y_bearing; + glyph_max.x = glyph_min.x + img->extents.width; + glyph_max.y = glyph_min.y + img->extents.height; if (i==0) { total_min = glyph_min; @@ -433,12 +633,13 @@ _cairo_ft_font_glyph_extents (void *abstract_font, total_max.y = glyph_max.y; } } + _cairo_unlock_global_image_glyph_cache (); extents->x_bearing = total_min.x - origin.x; extents->y_bearing = total_min.y - origin.y; extents->width = total_max.x - total_min.x; extents->height = total_max.y - total_min.y; - extents->x_advance = glyphs[i-1].x + DOUBLE_FROM_26_6 (metrics->horiAdvance) - origin.x; + extents->x_advance = glyphs[i-1].x + (img == NULL ? 0 : img->extents.x_advance) - origin.x; extents->y_advance = glyphs[i-1].y + 0 - origin.y; return CAIRO_STATUS_SUCCESS; @@ -446,34 +647,16 @@ _cairo_ft_font_glyph_extents (void *abstract_font, static cairo_status_t -_cairo_ft_font_text_extents (void *abstract_font, - const unsigned char *utf8, - cairo_text_extents_t *extents) -{ - cairo_ft_font_t *font = abstract_font; - cairo_glyph_t *glyphs; - size_t nglyphs; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - - if (_utf8_to_glyphs (font, utf8, 0, 0, &glyphs, &nglyphs)) - { - status = _cairo_ft_font_glyph_extents (font, glyphs, nglyphs, - extents); - free (glyphs); - } - return status; -} - -static cairo_status_t -_cairo_ft_font_glyph_bbox (void *abstract_font, - cairo_surface_t *surface, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_box_t *bbox) +_cairo_ft_font_glyph_bbox (void *abstract_font, + cairo_font_scale_t *sc, + const cairo_glyph_t *glyphs, + int num_glyphs, + cairo_box_t *bbox) { + cairo_image_glyph_cache_entry_t *img; + cairo_cache_t *cache; + cairo_glyph_cache_key_t key; cairo_ft_font_t *font = abstract_font; - cairo_surface_t *mask = NULL; - cairo_glyph_size_t size; cairo_fixed_t x1, y1, x2, y2; int i; @@ -481,22 +664,33 @@ _cairo_ft_font_glyph_bbox (void *abstract_font, bbox->p1.x = bbox->p1.y = CAIRO_MAXSHORT << 16; bbox->p2.x = bbox->p2.y = CAIRO_MINSHORT << 16; - if (font == NULL - || surface == NULL - || glyphs == NULL) + _cairo_lock_global_image_glyph_cache (); + cache = _cairo_get_global_image_glyph_cache(); + + if (cache == NULL + || font == NULL + || glyphs == NULL) { + _cairo_unlock_global_image_glyph_cache (); return CAIRO_STATUS_NO_MEMORY; + } + + key.unscaled = &font->base; + key.scale = *sc; for (i = 0; i < num_glyphs; i++) { - mask = _cairo_font_lookup_glyph (&font->base, surface, - &glyphs[i], &size); - if (mask == NULL) + + img = NULL; + key.index = glyphs[i].index; + + if (_cairo_cache_lookup (cache, &key, (void **) &img) + != CAIRO_STATUS_SUCCESS || img == NULL) continue; - x1 = _cairo_fixed_from_double (glyphs[i].x + size.x); - y1 = _cairo_fixed_from_double (glyphs[i].y - size.y); - x2 = x1 + _cairo_fixed_from_double (size.width); - y2 = y1 + _cairo_fixed_from_double (size.height); + x1 = _cairo_fixed_from_double (glyphs[i].x + img->size.x); + y1 = _cairo_fixed_from_double (glyphs[i].y - img->size.y); + x2 = x1 + _cairo_fixed_from_double (img->size.width); + y2 = y1 + _cairo_fixed_from_double (img->size.height); if (x1 < bbox->p1.x) bbox->p1.x = x1; @@ -509,117 +703,82 @@ _cairo_ft_font_glyph_bbox (void *abstract_font, if (y2 > bbox->p2.y) bbox->p2.y = y2; - - if (mask) - cairo_surface_destroy (mask); } + _cairo_unlock_global_image_glyph_cache (); return CAIRO_STATUS_SUCCESS; } -static cairo_status_t -_cairo_ft_font_text_bbox (void *abstract_font, - cairo_surface_t *surface, - double x0, - double y0, - const unsigned char *utf8, - cairo_box_t *bbox) -{ - cairo_ft_font_t *font = abstract_font; - cairo_glyph_t *glyphs; - size_t num_glyphs; - - if (_utf8_to_glyphs (font, utf8, x0, y0, &glyphs, &num_glyphs)) - { - cairo_status_t res; - res = _cairo_ft_font_glyph_bbox (font, surface, - glyphs, num_glyphs, bbox); - free (glyphs); - return res; - } - else - return CAIRO_STATUS_NO_MEMORY; -} static cairo_status_t -_cairo_ft_font_show_glyphs (void *abstract_font, - cairo_operator_t operator, - cairo_surface_t *source, - cairo_surface_t *surface, - int source_x, - int source_y, - const cairo_glyph_t *glyphs, - int num_glyphs) +_cairo_ft_font_show_glyphs (void *abstract_font, + cairo_font_scale_t *sc, + cairo_operator_t operator, + cairo_surface_t *source, + cairo_surface_t *surface, + int source_x, + int source_y, + const cairo_glyph_t *glyphs, + int num_glyphs) { + cairo_image_glyph_cache_entry_t *img; + cairo_cache_t *cache; + cairo_glyph_cache_key_t key; cairo_ft_font_t *font = abstract_font; cairo_status_t status; - cairo_surface_t *mask = NULL; - cairo_glyph_size_t size; double x, y; int i; - if (font == NULL + _cairo_lock_global_image_glyph_cache (); + cache = _cairo_get_global_image_glyph_cache(); + + if (cache == NULL + || font == NULL || source == NULL || surface == NULL - || glyphs == NULL) + || glyphs == NULL) { + _cairo_unlock_global_image_glyph_cache (); return CAIRO_STATUS_NO_MEMORY; + } + + key.unscaled = &font->base; + key.scale = *sc; for (i = 0; i < num_glyphs; i++) { - mask = _cairo_font_lookup_glyph (&font->base, surface, - &glyphs[i], &size); - if (mask == NULL) + img = NULL; + key.index = glyphs[i].index; + + if (_cairo_cache_lookup (cache, &key, (void **) &img) + != CAIRO_STATUS_SUCCESS + || img == NULL + || img->image == NULL) continue; x = glyphs[i].x; y = glyphs[i].y; - status = _cairo_surface_composite (operator, source, mask, surface, - source_x + x + size.x, - source_y + y - size.y, + status = _cairo_surface_composite (operator, source, + &(img->image->base), + surface, + source_x + x + img->size.x, + source_y + y - img->size.y, 0, 0, - x + size.x, - y - size.y, - (double) size.width, - (double) size.height); - - cairo_surface_destroy (mask); + x + img->size.x, + y - img->size.y, + (double) img->size.width, + (double) img->size.height); - if (status) + if (status) { + _cairo_unlock_global_image_glyph_cache (); return status; + } } + _cairo_unlock_global_image_glyph_cache (); return CAIRO_STATUS_SUCCESS; } -static cairo_status_t -_cairo_ft_font_show_text (void *abstract_font, - cairo_operator_t operator, - cairo_surface_t *source, - cairo_surface_t *surface, - int source_x, - int source_y, - double x0, - double y0, - const unsigned char *utf8) -{ - cairo_ft_font_t *font = abstract_font; - cairo_glyph_t *glyphs; - size_t num_glyphs; - - if (_utf8_to_glyphs (font, utf8, x0, y0, &glyphs, &num_glyphs)) - { - cairo_status_t res; - res = _cairo_ft_font_show_glyphs (font, operator, - source, surface, - source_x, source_y, - glyphs, num_glyphs); - free (glyphs); - return res; - } - else - return CAIRO_STATUS_NO_MEMORY; -} static int _move_to (FT_Vector *to, void *closure) @@ -699,10 +858,11 @@ _cubic_to (FT_Vector *control1, FT_Vector *control2, FT_Vector *to, void *closur } static cairo_status_t -_cairo_ft_font_glyph_path (void *abstract_font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_path_t *path) +_cairo_ft_font_glyph_path (void *abstract_font, + cairo_font_scale_t *sc, + cairo_glyph_t *glyphs, + int num_glyphs, + cairo_path_t *path) { int i; cairo_ft_font_t *font = abstract_font; @@ -717,8 +877,9 @@ _cairo_ft_font_glyph_path (void *abstract_font, 0, /* delta */ }; - glyph = font->face->glyph; - _install_font_matrix (&font->base.matrix, font->face); + glyph = font->val->face->glyph; + + _install_font_scale (sc, font->val->face); for (i = 0; i < num_glyphs; i++) { @@ -727,7 +888,7 @@ _cairo_ft_font_glyph_path (void *abstract_font, 0, DOUBLE_TO_16_16 (-1.0), }; - error = FT_Load_Glyph (font->face, glyphs[i].index, FT_LOAD_DEFAULT); + error = FT_Load_Glyph (font->val->face, glyphs[i].index, FT_LOAD_DEFAULT); /* XXX: What to do in this error case? */ if (error) continue; @@ -747,130 +908,218 @@ _cairo_ft_font_glyph_path (void *abstract_font, return CAIRO_STATUS_SUCCESS; } -static cairo_status_t -_cairo_ft_font_text_path (void *abstract_font, - double x, - double y, - const unsigned char *utf8, - cairo_path_t *path) -{ - cairo_ft_font_t *font = abstract_font; - cairo_glyph_t *glyphs; - size_t nglyphs; - - if (_utf8_to_glyphs (font, utf8, x, y, &glyphs, &nglyphs)) - { - cairo_status_t res; - res = _cairo_ft_font_glyph_path (font, glyphs, nglyphs, path); - free (glyphs); - return res; - } - else - return CAIRO_STATUS_NO_MEMORY; -} - -cairo_font_t * -cairo_ft_font_create_for_ft_face (FT_Face face) -{ - cairo_ft_font_t *f = NULL; - - f = malloc (sizeof (cairo_ft_font_t)); - if (f == NULL) - return NULL; - memset (f, 0, sizeof (cairo_ft_font_t)); - - _cairo_font_init (&f->base, - &cairo_ft_font_backend); - - f->ft_library = NULL; - f->owns_ft_library = 0; - - f->face = face; - f->owns_face = 0; - return (cairo_font_t *) f; -} - -static cairo_surface_t * -_cairo_ft_font_create_glyph (void *abstract_font, - const cairo_glyph_t *glyph, - cairo_glyph_size_t *return_size) +static cairo_status_t +_cairo_ft_font_create_glyph(cairo_image_glyph_cache_entry_t *val) { - cairo_ft_font_t *font = abstract_font; - cairo_image_surface_t *image; + cairo_ft_font_t *font = (cairo_ft_font_t *)val->key.unscaled; FT_GlyphSlot glyphslot; unsigned int width, height, stride; FT_Outline *outline; FT_BBox cbox; FT_Bitmap bitmap; - - glyphslot = font->face->glyph; - _install_font_matrix (&font->base.matrix, font->face); + FT_Glyph_Metrics *metrics; - FT_Load_Glyph (font->face, glyph->index, FT_LOAD_DEFAULT); + glyphslot = font->val->face->glyph; + metrics = &glyphslot->metrics; - outline = &glyphslot->outline; + _install_font_scale (&val->key.scale, font->val->face); + + if (FT_Load_Glyph (font->val->face, val->key.index, FT_LOAD_DEFAULT) != 0) + return CAIRO_STATUS_NO_MEMORY; + + val->extents.x_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingX); + val->extents.y_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingY); + val->extents.width = DOUBLE_FROM_26_6 (metrics->width); + val->extents.height = DOUBLE_FROM_26_6 (metrics->height); + val->extents.x_advance = DOUBLE_FROM_26_6 (font->val->face->glyph->advance.x); + val->extents.y_advance = DOUBLE_FROM_26_6 (font->val->face->glyph->advance.y); + outline = &glyphslot->outline; + FT_Outline_Get_CBox (outline, &cbox); cbox.xMin &= -64; cbox.yMin &= -64; cbox.xMax = (cbox.xMax + 63) & -64; cbox.yMax = (cbox.yMax + 63) & -64; - + width = (unsigned int) ((cbox.xMax - cbox.xMin) >> 6); height = (unsigned int) ((cbox.yMax - cbox.yMin) >> 6); stride = (width + 3) & -4; - bitmap.pixel_mode = ft_pixel_mode_grays; - bitmap.num_grays = 256; - bitmap.width = width; - bitmap.rows = height; - bitmap.pitch = stride; - if (width * height == 0) - return NULL; - - bitmap.buffer = malloc (stride * height); - if (bitmap.buffer == NULL) - return NULL; - - memset (bitmap.buffer, 0x0, stride * height); + val->image = NULL; + else + { - FT_Outline_Translate (outline, -cbox.xMin, -cbox.yMin); - FT_Outline_Get_Bitmap (glyphslot->library, outline, &bitmap); - - image = (cairo_image_surface_t *) + bitmap.pixel_mode = ft_pixel_mode_grays; + bitmap.num_grays = 256; + bitmap.width = width; + bitmap.rows = height; + bitmap.pitch = stride; + bitmap.buffer = calloc (1, stride * height); + + if (bitmap.buffer == NULL) { + return CAIRO_STATUS_NO_MEMORY; + }; + + FT_Outline_Translate (outline, -cbox.xMin, -cbox.yMin); + + if (FT_Outline_Get_Bitmap (glyphslot->library, outline, &bitmap) != 0) { + free (bitmap.buffer); + return CAIRO_STATUS_NO_MEMORY; + } + + val->image = (cairo_image_surface_t *) cairo_image_surface_create_for_data ((char *) bitmap.buffer, CAIRO_FORMAT_A8, width, height, stride); - if (image == NULL) { - free (bitmap.buffer); - return NULL; + if (val->image == NULL) { + free (bitmap.buffer); + return CAIRO_STATUS_NO_MEMORY; + } + + _cairo_image_surface_assume_ownership_of_data (val->image); } - - _cairo_image_surface_assume_ownership_of_data (image); - - return_size->width = (unsigned short) width; - return_size->height = (unsigned short) height; - return_size->x = (short) (cbox.xMin >> 6); - return_size->y = (short) (cbox.yMax >> 6); - return &image->base; + val->size.width = (unsigned short) width; + val->size.height = (unsigned short) height; + val->size.x = (short) (cbox.xMin >> 6); + val->size.y = (short) (cbox.yMax >> 6); + + return CAIRO_STATUS_SUCCESS; } const struct cairo_font_backend cairo_ft_font_backend = { _cairo_ft_font_create, - _cairo_ft_font_copy, _cairo_ft_font_destroy, _cairo_ft_font_font_extents, - _cairo_ft_font_text_extents, + _cairo_ft_font_text_to_glyphs, _cairo_ft_font_glyph_extents, - _cairo_ft_font_text_bbox, _cairo_ft_font_glyph_bbox, - _cairo_ft_font_show_text, _cairo_ft_font_show_glyphs, - _cairo_ft_font_text_path, _cairo_ft_font_glyph_path, _cairo_ft_font_create_glyph }; + + +/* implement the platform-specific interface */ + +cairo_font_t * +cairo_ft_font_create (FT_Library ft_library, FcPattern *pattern) +{ + cairo_font_scale_t scale; + cairo_font_t *scaled; + cairo_ft_font_t *f = NULL; + ft_font_val_t *v = NULL; + FcPattern *dup; + + scale.matrix[0][0] = 1.; + scale.matrix[0][1] = 0.; + scale.matrix[1][0] = 0.; + scale.matrix[1][1] = 1.; + + scaled = malloc (sizeof (cairo_font_t)); + if (scaled == NULL) + goto FAIL; + + dup = FcPatternDuplicate(pattern); + if (dup == NULL) + goto FREE_SCALED; + + v = _create_from_library_and_pattern (ft_library, pattern); + if (v == NULL) + goto FREE_PATTERN; + + f = malloc (sizeof(cairo_ft_font_t)); + if (f == NULL) + goto FREE_VAL; + + if (_cairo_unscaled_font_init (&f->base, &cairo_ft_font_backend)) + goto FREE_VAL; + + f->pattern = dup; + f->val = v; + + _cairo_font_init (scaled, &scale, &f->base); + + return scaled; + + FREE_VAL: + _destroy_font_val (v); + + FREE_PATTERN: + FcPatternDestroy (dup); + + FREE_SCALED: + free (scaled); + + FAIL: + return NULL; +} + +cairo_font_t * +cairo_ft_font_create_for_ft_face (FT_Face face) +{ + cairo_font_scale_t scale; + cairo_font_t *scaled; + cairo_ft_font_t *f = NULL; + ft_font_val_t *v = NULL; + + scale.matrix[0][0] = 1.; + scale.matrix[0][1] = 0.; + scale.matrix[1][0] = 0.; + scale.matrix[1][1] = 1.; + + scaled = malloc (sizeof (cairo_font_t)); + if (scaled == NULL) + goto FAIL; + + v = _create_from_face (face, 0); + if (v == NULL) + goto FREE_SCALED; + + f = malloc (sizeof(cairo_ft_font_t)); + if (f == NULL) + goto FREE_VAL; + + _cairo_unscaled_font_init (&f->base, &cairo_ft_font_backend); + f->pattern = NULL; + f->val = v; + + _cairo_font_init (scaled, &scale, &f->base); + + return scaled; + + FREE_VAL: + _destroy_font_val (v); + + FREE_SCALED: + free (scaled); + + FAIL: + return NULL; +} + +FT_Face +cairo_ft_font_face (cairo_font_t *abstract_font) +{ + cairo_ft_font_t *font = (cairo_ft_font_t *) abstract_font->unscaled; + + if (font == NULL || font->val == NULL) + return NULL; + + return font->val->face; +} + +FcPattern * +cairo_ft_font_pattern (cairo_font_t *abstract_font) +{ + cairo_ft_font_t *font = (cairo_ft_font_t *) abstract_font->unscaled; + + if (font == NULL) + return NULL; + + return font->pattern; +} diff --git a/src/cairo_glitz_surface.c b/src/cairo_glitz_surface.c index 8d18280be..d351108db 100644 --- a/src/cairo_glitz_surface.c +++ b/src/cairo_glitz_surface.c @@ -900,7 +900,8 @@ static const struct cairo_surface_backend cairo_glitz_surface_backend = { _cairo_glitz_surface_copy_page, _cairo_glitz_surface_show_page, _cairo_glitz_surface_set_clip_region, - _cairo_glitz_surface_create_pattern + _cairo_glitz_surface_create_pattern, + NULL /* show_glyphs */ }; cairo_surface_t * diff --git a/src/cairo_gstate.c b/src/cairo_gstate.c index c89d63769..fabb53efd 100644 --- a/src/cairo_gstate.c +++ b/src/cairo_gstate.c @@ -77,9 +77,9 @@ _cairo_gstate_init (cairo_gstate_t *gstate) gstate->num_dashes = 0; gstate->dash_offset = 0.0; - gstate->font = _cairo_font_create (CAIRO_FONT_FAMILY_DEFAULT, - CAIRO_FONT_SLANT_DEFAULT, - CAIRO_FONT_WEIGHT_DEFAULT); + gstate->font = _cairo_unscaled_font_create (CAIRO_FONT_FAMILY_DEFAULT, + CAIRO_FONT_SLANT_DEFAULT, + CAIRO_FONT_WEIGHT_DEFAULT); gstate->surface = NULL; @@ -119,11 +119,8 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other) } if (other->font) { - gstate->font = _cairo_font_copy (other->font); - if (!gstate->font) { - status = CAIRO_STATUS_NO_MEMORY; - goto CLEANUP_DASHES; - } + gstate->font = other->font; + _cairo_unscaled_font_reference (gstate->font); } if (other->clip.region) @@ -149,9 +146,10 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other) CLEANUP_PATH: _cairo_path_fini (&gstate->path); + CLEANUP_FONT: - cairo_font_destroy (gstate->font); - CLEANUP_DASHES: + _cairo_unscaled_font_destroy (gstate->font); + free (gstate->dash); gstate->dash = NULL; @@ -161,7 +159,7 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other) void _cairo_gstate_fini (cairo_gstate_t *gstate) { - cairo_font_destroy (gstate->font); + _cairo_unscaled_font_destroy (gstate->font); if (gstate->surface) cairo_surface_destroy (gstate->surface); @@ -177,6 +175,8 @@ _cairo_gstate_fini (cairo_gstate_t *gstate) cairo_pattern_destroy (gstate->pattern); + _cairo_matrix_fini (&gstate->font_matrix); + _cairo_matrix_fini (&gstate->ctm); _cairo_matrix_fini (&gstate->ctm_inverse); @@ -627,6 +627,8 @@ _cairo_gstate_default_matrix (cairo_gstate_t *gstate) if (scale == 0) scale = 1; + cairo_matrix_set_identity (&gstate->font_matrix); + cairo_matrix_set_identity (&gstate->ctm); cairo_matrix_scale (&gstate->ctm, scale, scale); cairo_matrix_copy (&gstate->ctm_inverse, &gstate->ctm); @@ -1676,15 +1678,6 @@ extract_transformed_rectangle(cairo_matrix_t *mat, double a, b, c, d, tx, ty; cairo_status_t st; - /* XXX: Something in the rectangle-based clipping support is - * broken. See cairo_snippets/xxx_clip_rectangle which - * demonstrates no clipping at all. - * - * For now, I'm am disabling this optimization completely until it - * can be fixed. - */ - return 0; - st = cairo_matrix_get_affine (mat, &a, &b, &c, &d, &tx, &ty); if (!(st == CAIRO_STATUS_SUCCESS && b == 0. && c == 0.)) return 0; @@ -1992,16 +1985,28 @@ _cairo_gstate_show_surface (cairo_gstate_t *gstate, return CAIRO_STATUS_SUCCESS; } + cairo_status_t _cairo_gstate_select_font (cairo_gstate_t *gstate, const char *family, cairo_font_slant_t slant, cairo_font_weight_t weight) { - if (gstate->font != NULL) - cairo_font_destroy (gstate->font); + cairo_unscaled_font_t *tmp; + + tmp = _cairo_unscaled_font_create (family, slant, weight); - gstate->font = _cairo_font_create (family, slant, weight); + if (tmp == NULL) + return CAIRO_STATUS_NO_MEMORY; + + if (gstate->font != tmp) + { + if (gstate->font != NULL) + _cairo_unscaled_font_destroy (gstate->font); + + cairo_matrix_set_identity (&gstate->font_matrix); + gstate->font = tmp; + } return CAIRO_STATUS_SUCCESS; } @@ -2010,212 +2015,294 @@ cairo_status_t _cairo_gstate_scale_font (cairo_gstate_t *gstate, double scale) { - return _cairo_font_scale (gstate->font, scale); + return cairo_matrix_scale (&gstate->font_matrix, scale, scale); } cairo_status_t _cairo_gstate_transform_font (cairo_gstate_t *gstate, cairo_matrix_t *matrix) { - return _cairo_font_transform (gstate->font, matrix); + cairo_matrix_t tmp; + double a, b, c, d, tx, ty; + cairo_matrix_get_affine (matrix, &a, &b, &c, &d, &tx, &ty); + cairo_matrix_set_affine (&tmp, a, b, c, d, 0, 0); + return cairo_matrix_multiply (&gstate->font_matrix, &gstate->font_matrix, &tmp); } + cairo_status_t _cairo_gstate_current_font (cairo_gstate_t *gstate, cairo_font_t **font) { - *font = gstate->font; + cairo_font_scale_t scale; + cairo_font_t *scaled; + double dummy; + + scaled = malloc (sizeof (cairo_font_t)); + if (scaled == NULL) + return CAIRO_STATUS_NO_MEMORY; + + cairo_matrix_get_affine (&gstate->font_matrix, + &scale.matrix[0][0], + &scale.matrix[0][1], + &scale.matrix[1][0], + &scale.matrix[1][1], + &dummy, &dummy); + + _cairo_font_init (scaled, &scale, gstate->font); + _cairo_unscaled_font_reference (gstate->font); + + *font = scaled; return CAIRO_STATUS_SUCCESS; } -cairo_status_t -_cairo_gstate_current_font_extents (cairo_gstate_t *gstate, - cairo_font_extents_t *extents) +void +_cairo_gstate_set_font_transform (cairo_gstate_t *gstate, + cairo_matrix_t *matrix) { - cairo_int_status_t status; - cairo_matrix_t saved_font_matrix; - - cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix); - cairo_matrix_multiply (&gstate->font->matrix, &gstate->ctm, &gstate->font->matrix); - - status = _cairo_font_font_extents (gstate->font, extents); - - cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix); + cairo_matrix_copy (&gstate->font_matrix, matrix); +} - return status; +void +_cairo_gstate_current_font_transform (cairo_gstate_t *gstate, + cairo_matrix_t *matrix) +{ + cairo_matrix_copy (matrix, &gstate->font_matrix); } +/* + * Like everything else in this file, fonts involve Too Many Coordinate Spaces; + * it is easy to get confused about what's going on. + * + * The user's view + * --------------- + * + * Users ask for things in user space. When cairo starts, a user space unit + * is about 1/96 inch, which is similar to (but importantly different from) + * the normal "point" units most users think in terms of. When a user + * selects a font, its scale is set to "one user unit". The user can then + * independently scale the user coordinate system *or* the font matrix, in + * order to adjust the rendered size of the font. + * + * If the user asks for a permanent reference to "a font", they are given a + * handle to a structure holding a scale matrix and an unscaled font. This + * effectively decouples the font from further changes to user space. Even + * if the user then "sets" the current cairo_t font to the handle they were + * passed, further changes to the cairo_t CTM will not affect externally + * held references to the font. + * + * + * The font's view + * --------------- + * + * Fonts are designed and stored (in say .ttf files) in "font space", which + * describes an "EM Square" (a design tile) and has some abstract number + * such as 1000, 1024, or 2048 units per "EM". This is basically an + * uninteresting space for us, but we need to remember that it exists. + * + * Font resources (from libraries or operating systems) render themselves + * to a particular device. Since they do not want to make most programmers + * worry about the font design space, the scaling API is simplified to + * involve just telling the font the required pixel size of the EM square + * (that is, in device space). + * + * + * Cairo's gstate view + * ------------------- + * + * In addition to the CTM and CTM inverse, we keep a matrix in the gstate + * called the "font matrix" which describes the user's most recent + * font-scaling or font-transforming request. This is kept in terms of an + * abstract scale factor, composed with the CTM and used to set the font's + * pixel size. So if the user asks to "scale the font by 12", the matrix + * is: + * + * [ 12.0, 0.0, 0.0, 12.0, 0.0, 0.0 ] + * + * It is an affine matrix, like all cairo matrices, but its tx and ty + * components are always set to zero; we don't permit "nudging" fonts + * around. + * + * In order to perform any action on a font, we must build an object + * called a cairo_font_scale_t; this contains the central 2x2 matrix + * resulting from "font matrix * CTM". + * + * We pass this to the font when making requests of it, which causes it to + * reply for a particular [user request, device] combination, under the CTM + * (to accomodate the "zoom in" == "bigger fonts" issue above). + * + * The other terms in our communication with the font are therefore in + * device space. When we ask it to perform text->glyph conversion, it will + * produce a glyph string in device space. Glyph vectors we pass to it for + * measuring or rendering should be in device space. The metrics which we + * get back from the font will be in device space. The contents of the + * global glyph image cache will be in device space. + * + * + * Cairo's public view + * ------------------- + * + * Since the values entering and leaving via public API calls are in user + * space, the gstate functions typically need to multiply argumens by the + * CTM (for user-input glyph vectors), and return values by the CTM inverse + * (for font responses such as metrics or glyph vectors). + * + */ -cairo_status_t -_cairo_gstate_set_font (cairo_gstate_t *gstate, - cairo_font_t *font) +static void +_build_font_scale (cairo_gstate_t *gstate, + cairo_font_scale_t *sc) { - if (gstate->font != NULL) - cairo_font_destroy (gstate->font); - gstate->font = font; - cairo_font_reference (gstate->font); - return CAIRO_STATUS_SUCCESS; + cairo_matrix_t tmp; + double dummy; + cairo_matrix_multiply (&tmp, &gstate->font_matrix, &gstate->ctm); + cairo_matrix_get_affine (&tmp, + &sc->matrix[0][0], + &sc->matrix[0][1], + &sc->matrix[1][0], + &sc->matrix[1][1], + &dummy, &dummy); } cairo_status_t -_cairo_gstate_text_extents (cairo_gstate_t *gstate, - const unsigned char *utf8, - cairo_text_extents_t *extents) +_cairo_gstate_current_font_extents (cairo_gstate_t *gstate, + cairo_font_extents_t *extents) { - cairo_matrix_t saved_font_matrix; - cairo_status_t status; - double scale_x, scale_y; - - cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix); - _cairo_matrix_compute_scale_factors (&gstate->ctm, &scale_x, &scale_y); - cairo_matrix_scale (&gstate->font->matrix, scale_x, scale_y); - - status = _cairo_font_text_extents (gstate->font, - utf8, extents); - - cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix); + cairo_int_status_t status; + cairo_font_scale_t sc; + double dummy = 0.0; - extents->x_bearing /= scale_x; - extents->y_bearing /= scale_y; - extents->width /= scale_x; - extents->height /= scale_y; - extents->x_advance /= scale_x; - extents->y_advance /= scale_y; + _build_font_scale (gstate, &sc); - return status; -} + status = _cairo_unscaled_font_font_extents (gstate->font, &sc, extents); -cairo_status_t -_cairo_gstate_glyph_extents (cairo_gstate_t *gstate, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_text_extents_t *extents) -{ - cairo_status_t status; - cairo_matrix_t saved_font_matrix; - double scale_x, scale_y; + /* The font responded in device space; convert to user space. */ - cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix); - _cairo_matrix_compute_scale_factors (&gstate->ctm, &scale_x, &scale_y); - cairo_matrix_scale (&gstate->font->matrix, scale_x, scale_y); + cairo_matrix_transform_distance (&gstate->ctm_inverse, + &dummy, + &extents->ascent); - status = _cairo_font_glyph_extents (gstate->font, - glyphs, num_glyphs, - extents); + cairo_matrix_transform_distance (&gstate->ctm_inverse, + &dummy, + &extents->descent); - cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix); + cairo_matrix_transform_distance (&gstate->ctm_inverse, + &dummy, + &extents->height); - extents->x_bearing /= scale_x; - extents->y_bearing /= scale_y; - extents->width /= scale_x; - extents->height /= scale_y; - extents->x_advance /= scale_x; - extents->y_advance /= scale_y; + cairo_matrix_transform_distance (&gstate->ctm_inverse, + &extents->max_x_advance, + &extents->max_y_advance); return status; } cairo_status_t -_cairo_gstate_show_text (cairo_gstate_t *gstate, - const unsigned char *utf8) +_cairo_gstate_text_to_glyphs (cairo_gstate_t *gstate, + const unsigned char *utf8, + cairo_glyph_t **glyphs, + int *nglyphs) { cairo_status_t status; - cairo_point_t point; - double x, y; - cairo_matrix_t saved_font_matrix; - cairo_pattern_t pattern; - cairo_box_t bbox; + cairo_font_scale_t sc; + + cairo_point_t point; + double dev_x, dev_y; + int i; + + _build_font_scale (gstate, &sc); status = _cairo_path_current_point (&gstate->path, &point); if (status == CAIRO_STATUS_NO_CURRENT_POINT) { - x = 0; - y = 0; - cairo_matrix_transform_point (&gstate->ctm, &x, &y); + dev_x = 0.0; + dev_y = 0.0; } else { - x = _cairo_fixed_to_double (point.x); - y = _cairo_fixed_to_double (point.y); + dev_x = _cairo_fixed_to_double (point.x); + dev_y = _cairo_fixed_to_double (point.y); } - - cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix); - cairo_matrix_multiply (&gstate->font->matrix, &gstate->ctm, &gstate->font->matrix); - _cairo_pattern_init_copy (&pattern, gstate->pattern); - - status = _cairo_font_text_bbox (gstate->font, gstate->surface, - x, y, utf8, &bbox); - if (status) - return status; - - status = _cairo_gstate_create_pattern (gstate, &pattern, &bbox); - if (status) + status = _cairo_unscaled_font_text_to_glyphs (gstate->font, + &sc, utf8, glyphs, nglyphs); + + if (status || !glyphs || !nglyphs || !(*glyphs) || !(nglyphs)) return status; - - if (gstate->clip.surface) - { - cairo_surface_t *intermediate; - cairo_color_t empty_color; - _cairo_color_init (&empty_color); - _cairo_color_set_alpha (&empty_color, .0); - intermediate = _cairo_surface_create_similar_solid (gstate->clip.surface, - CAIRO_FORMAT_A8, - gstate->clip.width, - gstate->clip.height, - &empty_color); + /* The font responded in device space, starting from (0,0); add any + current point offset in device space, and convert to user space. */ - status = _cairo_font_show_text (gstate->font, - CAIRO_OPERATOR_ADD, pattern.source, - intermediate, - gstate->clip.x - pattern.source_offset.x, - gstate->clip.y - pattern.source_offset.y, - x - gstate->clip.x, - y - gstate->clip.y, utf8); + for (i = 0; i < *nglyphs; ++i) { + (*glyphs)[i].x += dev_x; + (*glyphs)[i].y += dev_y; + cairo_matrix_transform_point (&gstate->ctm_inverse, + &((*glyphs)[i].x), + &((*glyphs)[i].y)); + } + + return CAIRO_STATUS_SUCCESS; +} - if (status) - goto BAIL; - - status = _cairo_surface_composite (CAIRO_OPERATOR_IN, - gstate->clip.surface, - NULL, - intermediate, - 0, 0, - 0, 0, - 0, 0, - gstate->clip.width, - gstate->clip.height); +cairo_status_t +_cairo_gstate_set_font (cairo_gstate_t *gstate, + cairo_font_t *font) +{ + if (gstate->font != NULL) + _cairo_unscaled_font_destroy (gstate->font); + gstate->font = font->unscaled; + _cairo_unscaled_font_reference (gstate->font); + cairo_matrix_set_affine (&gstate->font_matrix, + font->scale.matrix[0][0], + font->scale.matrix[0][1], + font->scale.matrix[1][0], + font->scale.matrix[1][1], + 0, 0); + return CAIRO_STATUS_SUCCESS; +} - if (status) - goto BAIL; +cairo_status_t +_cairo_gstate_glyph_extents (cairo_gstate_t *gstate, + cairo_glyph_t *glyphs, + int num_glyphs, + cairo_text_extents_t *extents) +{ + cairo_status_t status; + cairo_glyph_t *transformed_glyphs; + cairo_font_scale_t sc; + int i; - status = _cairo_surface_composite (gstate->operator, - pattern.source, - intermediate, - gstate->surface, - 0, 0, - 0, 0, - gstate->clip.x, - gstate->clip.y, - gstate->clip.width, - gstate->clip.height); + _build_font_scale (gstate, &sc); - BAIL: - cairo_surface_destroy (intermediate); - - } - else + transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t)); + if (transformed_glyphs == NULL) + return CAIRO_STATUS_NO_MEMORY; + + for (i = 0; i < num_glyphs; ++i) { - status = _cairo_font_show_text (gstate->font, - gstate->operator, pattern.source, - gstate->surface, - -pattern.source_offset.x, - -pattern.source_offset.y, - x, y, utf8); + transformed_glyphs[i] = glyphs[i]; + cairo_matrix_transform_point (&gstate->ctm, + &transformed_glyphs[i].x, + &transformed_glyphs[i].y); } - - cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix); - _cairo_pattern_fini (&pattern); + status = _cairo_unscaled_font_glyph_extents (gstate->font, &sc, + transformed_glyphs, num_glyphs, + extents); + + /* The font responded in device space; convert to user space. */ + + cairo_matrix_transform_distance (&gstate->ctm_inverse, + &extents->x_bearing, + &extents->y_bearing); + + cairo_matrix_transform_distance (&gstate->ctm_inverse, + &extents->width, + &extents->height); + + cairo_matrix_transform_distance (&gstate->ctm_inverse, + &extents->x_advance, + &extents->y_advance); + + free (transformed_glyphs); return status; } @@ -2226,12 +2313,14 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, int num_glyphs) { cairo_status_t status; - cairo_matrix_t saved_font_matrix; int i; cairo_glyph_t *transformed_glyphs = NULL; + cairo_font_scale_t sc; cairo_pattern_t pattern; cairo_box_t bbox; + _build_font_scale (gstate, &sc); + transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t)); if (transformed_glyphs == NULL) return CAIRO_STATUS_NO_MEMORY; @@ -2240,16 +2329,14 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, { transformed_glyphs[i] = glyphs[i]; cairo_matrix_transform_point (&gstate->ctm, - &(transformed_glyphs[i].x), - &(transformed_glyphs[i].y)); + &transformed_glyphs[i].x, + &transformed_glyphs[i].y); } - cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix); - cairo_matrix_multiply (&gstate->font->matrix, &gstate->ctm, &gstate->font->matrix); - _cairo_pattern_init_copy (&pattern, gstate->pattern); - status = _cairo_font_glyph_bbox (gstate->font, gstate->surface, - transformed_glyphs, num_glyphs, &bbox); + status = _cairo_unscaled_font_glyph_bbox (gstate->font, &sc, + transformed_glyphs, num_glyphs, + &bbox); if (status) return status; @@ -2277,12 +2364,13 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, transformed_glyphs[i].y -= gstate->clip.y; } - status = _cairo_font_show_glyphs (gstate->font, - CAIRO_OPERATOR_ADD, - pattern.source, intermediate, - gstate->clip.x - pattern.source_offset.x, - gstate->clip.y - pattern.source_offset.y, - transformed_glyphs, num_glyphs); + status = _cairo_unscaled_font_show_glyphs (gstate->font, + &sc, + CAIRO_OPERATOR_ADD, + pattern.source, intermediate, + gstate->clip.x - pattern.source_offset.x, + gstate->clip.y - pattern.source_offset.y, + transformed_glyphs, num_glyphs); if (status) goto BAIL; @@ -2317,16 +2405,15 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, } else { - status = _cairo_font_show_glyphs (gstate->font, - gstate->operator, pattern.source, - gstate->surface, - -pattern.source_offset.x, - -pattern.source_offset.y, - transformed_glyphs, num_glyphs); + status = _cairo_unscaled_font_show_glyphs (gstate->font, + &sc, + gstate->operator, pattern.source, + gstate->surface, + -pattern.source_offset.x, + -pattern.source_offset.y, + transformed_glyphs, num_glyphs); } - cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix); - _cairo_pattern_fini (&pattern); free (transformed_glyphs); @@ -2334,40 +2421,6 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, return status; } - -cairo_status_t -_cairo_gstate_text_path (cairo_gstate_t *gstate, - const unsigned char *utf8) -{ - cairo_status_t status; - cairo_matrix_t saved_font_matrix; - cairo_point_t point; - double x, y; - - status = _cairo_path_current_point (&gstate->path, &point); - if (status == CAIRO_STATUS_NO_CURRENT_POINT) { - x = 0; - y = 0; - cairo_matrix_transform_point (&gstate->ctm, &x, &y); - } else { - x = _cairo_fixed_to_double (point.x); - y = _cairo_fixed_to_double (point.y); - } - - cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix); - cairo_matrix_multiply (&gstate->font->matrix, &gstate->ctm, &gstate->font->matrix); - - status = _cairo_font_text_path (gstate->font, - x, y, - utf8, - &gstate->path); - - cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix); - - return status; -} - - cairo_status_t _cairo_gstate_glyph_path (cairo_gstate_t *gstate, cairo_glyph_t *glyphs, @@ -2376,7 +2429,9 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate, cairo_status_t status; int i; cairo_glyph_t *transformed_glyphs = NULL; - cairo_matrix_t saved_font_matrix; + cairo_font_scale_t sc; + + _build_font_scale (gstate, &sc); transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t)); if (transformed_glyphs == NULL) @@ -2390,14 +2445,9 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate, &(transformed_glyphs[i].y)); } - cairo_matrix_copy (&saved_font_matrix, &gstate->font->matrix); - cairo_matrix_multiply (&gstate->font->matrix, &gstate->ctm, &gstate->font->matrix); - - status = _cairo_font_glyph_path (gstate->font, - transformed_glyphs, num_glyphs, - &gstate->path); - - cairo_matrix_copy (&gstate->font->matrix, &saved_font_matrix); + status = _cairo_unscaled_font_glyph_path (gstate->font, &sc, + transformed_glyphs, num_glyphs, + &gstate->path); free (transformed_glyphs); return status; diff --git a/src/cairo_image_surface.c b/src/cairo_image_surface.c index e2ee69c57..9e6abb2a6 100644 --- a/src/cairo_image_surface.c +++ b/src/cairo_image_surface.c @@ -525,5 +525,6 @@ static const cairo_surface_backend_t cairo_image_surface_backend = { _cairo_image_surface_copy_page, _cairo_image_surface_show_page, _cairo_image_abstract_surface_set_clip_region, - _cairo_image_abstract_surface_create_pattern + _cairo_image_abstract_surface_create_pattern, + NULL /* show_glyphs */ }; diff --git a/src/cairo_png_surface.c b/src/cairo_png_surface.c index 1d1fa63e0..cfd68c878 100644 --- a/src/cairo_png_surface.c +++ b/src/cairo_png_surface.c @@ -382,5 +382,6 @@ static const cairo_surface_backend_t cairo_png_surface_backend = { _cairo_png_surface_copy_page, _cairo_png_surface_show_page, _cairo_png_surface_set_clip_region, - _cairo_png_surface_create_pattern + _cairo_png_surface_create_pattern, + NULL /* show_glyphs */ }; diff --git a/src/cairo_ps_surface.c b/src/cairo_ps_surface.c index 4296d0d49..9b3096b0f 100644 --- a/src/cairo_ps_surface.c +++ b/src/cairo_ps_surface.c @@ -436,5 +436,6 @@ static const cairo_surface_backend_t cairo_ps_surface_backend = { _cairo_ps_surface_copy_page, _cairo_ps_surface_show_page, _cairo_ps_surface_set_clip_region, - _cairo_ps_surface_create_pattern + _cairo_ps_surface_create_pattern, + NULL /* show_glyphs */ }; diff --git a/src/cairo_xcb_surface.c b/src/cairo_xcb_surface.c index 36aa15731..bc37d2047 100644 --- a/src/cairo_xcb_surface.c +++ b/src/cairo_xcb_surface.c @@ -745,7 +745,8 @@ static const struct cairo_surface_backend cairo_xcb_surface_backend = { _cairo_xcb_surface_copy_page, _cairo_xcb_surface_show_page, _cairo_xcb_surface_set_clip_region, - _cairo_xcb_surface_create_pattern + _cairo_xcb_surface_create_pattern, + NULL /* show_glyphs */ }; static void diff --git a/src/cairo_xlib_surface.c b/src/cairo_xlib_surface.c index 8513ae4ef..fca7f33e4 100644 --- a/src/cairo_xlib_surface.c +++ b/src/cairo_xlib_surface.c @@ -631,6 +631,8 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, xr.height = surf->height; XUnionRectWithRegion (&xr, xregion, xregion); rects = malloc(sizeof(XRectangle)); + if (rects == NULL) + return CAIRO_STATUS_NO_MEMORY; rects[0] = xr; m = 1; @@ -641,6 +643,8 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, if (n == 0) return CAIRO_STATUS_SUCCESS; rects = malloc(sizeof(XRectangle) * n); + if (rects == NULL) + return CAIRO_STATUS_NO_MEMORY; box = pixman_region_rects (region); xregion = XCreateRegion(); @@ -661,7 +665,7 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, XSetClipRectangles(surf->dpy, surf->gc, 0, 0, rects, m, Unsorted); free(rects); if (surf->picture) - XRenderSetPictureClipRegion (surf->dpy, surf->picture, xregion); + XRenderSetPictureClipRegion (surf->dpy, surf->picture, xregion); XDestroyRegion(xregion); XSetGraphicsExposures(surf->dpy, surf->gc, gc_values.graphics_exposures); return CAIRO_STATUS_SUCCESS; @@ -675,6 +679,17 @@ _cairo_xlib_surface_create_pattern (void *abstract_surface, return CAIRO_INT_STATUS_UNSUPPORTED; } +static cairo_status_t +_cairo_xlib_surface_show_glyphs (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_operator_t operator, + cairo_surface_t *source, + cairo_surface_t *surface, + int source_x, + int source_y, + const cairo_glyph_t *glyphs, + int num_glyphs); + static const struct cairo_surface_backend cairo_xlib_surface_backend = { _cairo_xlib_surface_create_similar, _cairo_xlib_surface_destroy, @@ -690,7 +705,8 @@ static const struct cairo_surface_backend cairo_xlib_surface_backend = { _cairo_xlib_surface_copy_page, _cairo_xlib_surface_show_page, _cairo_xlib_surface_set_clip_region, - _cairo_xlib_surface_create_pattern + _cairo_xlib_surface_create_pattern, + _cairo_xlib_surface_show_glyphs }; cairo_surface_t * @@ -761,3 +777,512 @@ cairo_xlib_surface_create (Display *dpy, return (cairo_surface_t *) surface; } DEPRECATE (cairo_surface_create_for_drawable, cairo_xlib_surface_create); + + +/* RENDER glyphset cache code */ + +typedef struct glyphset_cache { + cairo_cache_t base; + struct glyphset_cache *next; + Display *display; + XRenderPictFormat *a8_pict_format; + GlyphSet glyphset; + Glyph counter; +} glyphset_cache_t; + +typedef struct { + cairo_glyph_cache_key_t key; + Glyph glyph; + XGlyphInfo info; +} glyphset_cache_entry_t; + +static Glyph +_next_xlib_glyph (glyphset_cache_t *cache) +{ + return ++(cache->counter); +} + + +static cairo_status_t +_xlib_glyphset_cache_create_entry (void *cache, + void *key, + void **return_entry) +{ + glyphset_cache_t *g = (glyphset_cache_t *) cache; + cairo_glyph_cache_key_t *k = (cairo_glyph_cache_key_t *)key; + glyphset_cache_entry_t *v; + + cairo_status_t status; + + cairo_cache_t *im_cache; + cairo_image_glyph_cache_entry_t *im; + + v = malloc (sizeof (glyphset_cache_entry_t)); + _cairo_lock_global_image_glyph_cache (); + im_cache = _cairo_get_global_image_glyph_cache (); + + if (g == NULL || v == NULL ||g == NULL || im_cache == NULL) { + _cairo_unlock_global_image_glyph_cache (); + return CAIRO_STATUS_NO_MEMORY; + } + + status = _cairo_cache_lookup (im_cache, key, (void **) (&im)); + if (status != CAIRO_STATUS_SUCCESS || im == NULL) { + _cairo_unlock_global_image_glyph_cache (); + return CAIRO_STATUS_NO_MEMORY; + } + + v->key = *k; + _cairo_unscaled_font_reference (v->key.unscaled); + + v->glyph = _next_xlib_glyph (g); + + v->info.width = im->image ? im->image->stride : im->size.width; + v->info.height = im->size.height; + v->info.x = - im->extents.x_bearing; + v->info.y = im->extents.y_bearing; + v->info.xOff = 0; + v->info.yOff = 0; + + XRenderAddGlyphs (g->display, g->glyphset, + &(v->glyph), &(v->info), 1, + im->image ? im->image->data : NULL, + im->image ? v->info.height * v->info.width : 0); + + v->key.base.memory = im->image ? im->image->width * im->image->stride : 0; + *return_entry = v; + _cairo_unlock_global_image_glyph_cache (); + return CAIRO_STATUS_SUCCESS; +} + +static void +_xlib_glyphset_cache_destroy_cache (void *cache) +{ + /* FIXME: will we ever release glyphset caches? */ +} + +static void +_xlib_glyphset_cache_destroy_entry (void *cache, void *entry) +{ + glyphset_cache_t *g; + glyphset_cache_entry_t *v; + + g = (glyphset_cache_t *) cache; + v = (glyphset_cache_entry_t *) entry; + + _cairo_unscaled_font_destroy (v->key.unscaled); + XRenderFreeGlyphs (g->display, g->glyphset, &(v->glyph), 1); + free (v); +} + +const cairo_cache_backend_t _xlib_glyphset_cache_backend = { + _cairo_glyph_cache_hash, + _cairo_glyph_cache_keys_equal, + _xlib_glyphset_cache_create_entry, + _xlib_glyphset_cache_destroy_entry, + _xlib_glyphset_cache_destroy_cache +}; + + +static glyphset_cache_t * +_xlib_glyphset_caches = NULL; + +static void +_lock_xlib_glyphset_caches (void) +{ + /* FIXME: implement locking */ +} + +static void +_unlock_xlib_glyphset_caches (void) +{ + /* FIXME: implement locking */ +} + +static glyphset_cache_t * +_get_glyphset_cache (Display *d) +{ + /* + * There should usually only be one, or a very small number, of + * displays. So we just do a linear scan. + */ + + glyphset_cache_t *g; + + for (g = _xlib_glyphset_caches; g != NULL; g = g->next) { + if (g->display == d) + return g; + } + + g = malloc (sizeof (glyphset_cache_t)); + if (g == NULL) + goto ERR; + + g->counter = 0; + g->display = d; + g->a8_pict_format = XRenderFindStandardFormat (d, PictStandardA8); + if (g->a8_pict_format == NULL) + goto ERR; + + if (_cairo_cache_init (&g->base, + &_xlib_glyphset_cache_backend, + CAIRO_XLIB_GLYPH_CACHE_MEMORY_DEFAULT)) + goto FREE_GLYPHSET_CACHE; + + g->glyphset = XRenderCreateGlyphSet (d, g->a8_pict_format); + g->next = _xlib_glyphset_caches; + _xlib_glyphset_caches = g; + return g; + + FREE_GLYPHSET_CACHE: + free (g); + + ERR: + return NULL; +} + +#define N_STACK_BUF 1024 + +static cairo_status_t +_cairo_xlib_surface_show_glyphs32 (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_operator_t operator, + glyphset_cache_t *g, + cairo_glyph_cache_key_t *key, + cairo_xlib_surface_t *src, + cairo_xlib_surface_t *self, + int source_x, + int source_y, + const cairo_glyph_t *glyphs, + glyphset_cache_entry_t **entries, + int num_glyphs) +{ + XGlyphElt32 *elts = NULL; + XGlyphElt32 stack_elts [N_STACK_BUF]; + + unsigned int *chars = NULL; + unsigned int stack_chars [N_STACK_BUF]; + + int i; + int lastX = 0, lastY = 0; + + /* Acquire arrays of suitable sizes. */ + if (num_glyphs < N_STACK_BUF) { + elts = stack_elts; + chars = stack_chars; + + } else { + elts = malloc (num_glyphs * sizeof (XGlyphElt32)); + if (elts == NULL) + goto FAIL; + + chars = malloc (num_glyphs * sizeof (unsigned int)); + if (chars == NULL) + goto FREE_ELTS; + + } + + for (i = 0; i < num_glyphs; ++i) { + chars[i] = entries[i]->glyph; + elts[i].chars = &(chars[i]); + elts[i].nchars = 1; + elts[i].glyphset = g->glyphset; + elts[i].xOff = glyphs[i].x - lastX; + elts[i].yOff = glyphs[i].y - lastY; + lastX = glyphs[i].x; + lastY = glyphs[i].y; + } + + XRenderCompositeText32 (self->dpy, + _render_operator (operator), + src->picture, + self->picture, + g->a8_pict_format, + source_x, source_y, + 0, 0, + elts, num_glyphs); + + if (num_glyphs >= N_STACK_BUF) { + free (chars); + free (elts); + } + + return CAIRO_STATUS_SUCCESS; + + FREE_ELTS: + if (num_glyphs >= N_STACK_BUF) + free (elts); + + FAIL: + return CAIRO_STATUS_NO_MEMORY; +} + + +static cairo_status_t +_cairo_xlib_surface_show_glyphs16 (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_operator_t operator, + glyphset_cache_t *g, + cairo_glyph_cache_key_t *key, + cairo_xlib_surface_t *src, + cairo_xlib_surface_t *self, + int source_x, + int source_y, + const cairo_glyph_t *glyphs, + glyphset_cache_entry_t **entries, + int num_glyphs) +{ + XGlyphElt16 *elts = NULL; + XGlyphElt16 stack_elts [N_STACK_BUF]; + + unsigned short *chars = NULL; + unsigned short stack_chars [N_STACK_BUF]; + + int i; + int lastX = 0, lastY = 0; + + /* Acquire arrays of suitable sizes. */ + if (num_glyphs < N_STACK_BUF) { + elts = stack_elts; + chars = stack_chars; + + } else { + elts = malloc (num_glyphs * sizeof (XGlyphElt16)); + if (elts == NULL) + goto FAIL; + + chars = malloc (num_glyphs * sizeof (unsigned short)); + if (chars == NULL) + goto FREE_ELTS; + + } + + for (i = 0; i < num_glyphs; ++i) { + chars[i] = entries[i]->glyph; + elts[i].chars = &(chars[i]); + elts[i].nchars = 1; + elts[i].glyphset = g->glyphset; + elts[i].xOff = glyphs[i].x - lastX; + elts[i].yOff = glyphs[i].y - lastY; + lastX = glyphs[i].x; + lastY = glyphs[i].y; + } + + XRenderCompositeText16 (self->dpy, + _render_operator (operator), + src->picture, + self->picture, + g->a8_pict_format, + source_x, source_y, + 0, 0, + elts, num_glyphs); + + if (num_glyphs >= N_STACK_BUF) { + free (chars); + free (elts); + } + + return CAIRO_STATUS_SUCCESS; + + FREE_ELTS: + if (num_glyphs >= N_STACK_BUF) + free (elts); + + FAIL: + return CAIRO_STATUS_NO_MEMORY; +} + +static cairo_status_t +_cairo_xlib_surface_show_glyphs8 (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_operator_t operator, + glyphset_cache_t *g, + cairo_glyph_cache_key_t *key, + cairo_xlib_surface_t *src, + cairo_xlib_surface_t *self, + int source_x, + int source_y, + const cairo_glyph_t *glyphs, + glyphset_cache_entry_t **entries, + int num_glyphs) +{ + XGlyphElt8 *elts = NULL; + XGlyphElt8 stack_elts [N_STACK_BUF]; + + char *chars = NULL; + char stack_chars [N_STACK_BUF]; + + int i; + int lastX = 0, lastY = 0; + + /* Acquire arrays of suitable sizes. */ + if (num_glyphs < N_STACK_BUF) { + elts = stack_elts; + chars = stack_chars; + + } else { + elts = malloc (num_glyphs * sizeof (XGlyphElt8)); + if (elts == NULL) + goto FAIL; + + chars = malloc (num_glyphs * sizeof (char)); + if (chars == NULL) + goto FREE_ELTS; + + } + + for (i = 0; i < num_glyphs; ++i) { + chars[i] = entries[i]->glyph; + elts[i].chars = &(chars[i]); + elts[i].nchars = 1; + elts[i].glyphset = g->glyphset; + elts[i].xOff = glyphs[i].x - lastX; + elts[i].yOff = glyphs[i].y - lastY; + lastX = glyphs[i].x; + lastY = glyphs[i].y; + } + + XRenderCompositeText8 (self->dpy, + _render_operator (operator), + src->picture, + self->picture, + g->a8_pict_format, + source_x, source_y, + 0, 0, + elts, num_glyphs); + + if (num_glyphs >= N_STACK_BUF) { + free (chars); + free (elts); + } + + return CAIRO_STATUS_SUCCESS; + + FREE_ELTS: + if (num_glyphs >= N_STACK_BUF) + free (elts); + + FAIL: + return CAIRO_STATUS_NO_MEMORY; +} + + +static cairo_status_t +_cairo_xlib_surface_show_glyphs (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_operator_t operator, + cairo_surface_t *source, + cairo_surface_t *surface, + int source_x, + int source_y, + const cairo_glyph_t *glyphs, + int num_glyphs) +{ + unsigned int elt_size; + cairo_xlib_surface_t *self = (cairo_xlib_surface_t *) surface; + cairo_image_surface_t *tmp = NULL; + cairo_xlib_surface_t *src = NULL; + glyphset_cache_t *g; + cairo_status_t status; + cairo_glyph_cache_key_t key; + glyphset_cache_entry_t **entries; + glyphset_cache_entry_t *stack_entries [N_STACK_BUF]; + int i; + + /* Acquire an entry array of suitable size. */ + if (num_glyphs < N_STACK_BUF) { + entries = stack_entries; + + } else { + entries = malloc (num_glyphs * sizeof (glyphset_cache_entry_t *)); + if (entries == NULL) + goto FAIL; + } + + /* prep the source surface. */ + if (source->backend == surface->backend) { + src = (cairo_xlib_surface_t *) source; + + } else { + tmp = _cairo_surface_get_image (source); + if (tmp == NULL) + goto FREE_ENTRIES; + + src = (cairo_xlib_surface_t *) + _cairo_surface_create_similar_scratch (surface, self->format, 1, + tmp->width, tmp->height); + + if (src == NULL) + goto FREE_TMP; + + if (_cairo_surface_set_image (&(src->base), tmp) != CAIRO_STATUS_SUCCESS) + goto FREE_SRC; + } + + _lock_xlib_glyphset_caches (); + g = _get_glyphset_cache (self->dpy); + if (g == NULL) + goto UNLOCK; + + /* Work out the index size to use. */ + elt_size = 8; + key.scale = *scale; + key.unscaled = font; + + for (i = 0; i < num_glyphs; ++i) { + key.index = glyphs[i].index; + status = _cairo_cache_lookup (&g->base, &key, (void **) (&entries[i])); + if (status != CAIRO_STATUS_SUCCESS || entries[i] == NULL) + goto UNLOCK; + + if (elt_size == 8 && entries[i]->glyph > 0xff) + elt_size = 16; + if (elt_size == 16 && entries[i]->glyph > 0xffff) { + elt_size = 32; + break; + } + } + + /* Call the appropriate sub-function. */ + + if (elt_size == 8) + status = _cairo_xlib_surface_show_glyphs8 (font, scale, operator, g, &key, src, self, + source_x, source_y, + glyphs, entries, num_glyphs); + else if (elt_size == 16) + status = _cairo_xlib_surface_show_glyphs16 (font, scale, operator, g, &key, src, self, + source_x, source_y, + glyphs, entries, num_glyphs); + else + status = _cairo_xlib_surface_show_glyphs32 (font, scale, operator, g, &key, src, self, + source_x, source_y, + glyphs, entries, num_glyphs); + + _unlock_xlib_glyphset_caches (); + + if (tmp != NULL) { + cairo_surface_destroy (&(src->base)); + cairo_surface_destroy (&(tmp->base)); + } + + if (num_glyphs >= N_STACK_BUF) + free (entries); + + return status; + + UNLOCK: + _unlock_xlib_glyphset_caches (); + + FREE_SRC: + cairo_surface_destroy (&(src->base)); + + FREE_TMP: + cairo_surface_destroy (&(tmp->base)); + + FREE_ENTRIES: + if (num_glyphs >= N_STACK_BUF) + free (entries); + + FAIL: + return CAIRO_STATUS_NO_MEMORY; +} diff --git a/src/cairoint.h b/src/cairoint.h index 6242a3fc5..728a5d174 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -49,7 +49,6 @@ #include "config.h" #endif -#include #include #include #include @@ -253,52 +252,204 @@ typedef struct cairo_pen { } cairo_pen_t; typedef struct cairo_color cairo_color_t; +typedef struct cairo_image_surface cairo_image_surface_t; + +/* cairo_cache.c structures and functions */ + +typedef struct cairo_cache_backend { + + unsigned long (*hash) (void *cache, + void *key); + + int (*keys_equal) (void *cache, + void *k1, + void *k2); + + cairo_status_t (*create_entry) (void *cache, + void *key, + void **entry_return); + + void (*destroy_entry) (void *cache, + void *entry); + + void (*destroy_cache) (void *cache); + +} cairo_cache_backend_t; + + +/* + * The cairo_cache system makes the following assumptions about + * entries in its cache: + * + * - a pointer to an entry can be cast to a cairo_cache_entry_base_t. + * - a pointer to an entry can also be cast to the "key type". + * + * The practical effect of this is that your entries must be laid + * out this way: + * + * struct my_entry { + * cairo_cache_entry_base_t; + * my_key_value_1; + * my_key_value_2; + * ... + * my_value; + * }; + */ + +typedef struct { + unsigned long memory; + unsigned long hashcode; +} cairo_cache_entry_base_t; + +typedef struct { + unsigned long high_water_mark; + unsigned long size; + unsigned long rehash; +} cairo_cache_arrangement_t; + +#undef CAIRO_MEASURE_CACHE_PERFORMANCE + +typedef struct { + unsigned long refcount; + const cairo_cache_backend_t *backend; + cairo_cache_arrangement_t *arrangement; + cairo_cache_entry_base_t **entries; + + unsigned long max_memory; + unsigned long used_memory; + unsigned long live_entries; + +#ifdef CAIRO_MEASURE_CACHE_PERFORMANCE + unsigned long hits; + unsigned long misses; + unsigned long probes; +#endif +} cairo_cache_t; + +extern cairo_status_t __internal_linkage +_cairo_cache_init (cairo_cache_t *cache, + const cairo_cache_backend_t *backend, + unsigned long max_memory); + +extern void __internal_linkage +_cairo_cache_reference (cairo_cache_t *cache); + +extern void __internal_linkage +_cairo_cache_destroy (cairo_cache_t *cache); + +extern cairo_status_t __internal_linkage +_cairo_cache_lookup (cairo_cache_t *cache, + void *key, + void **entry_return); + +extern unsigned long __internal_linkage +_cairo_hash_string (const char *c); + +#define CAIRO_IMAGE_GLYPH_CACHE_MEMORY_DEFAULT 0x100000 +#define CAIRO_XLIB_GLYPH_CACHE_MEMORY_DEFAULT 0x100000 +#define CAIRO_FONT_CACHE_NUM_FONTS_DEFAULT 20 +#define CAIRO_FT_CACHE_NUM_FONTS_DEFAULT 20 + +typedef struct { + double matrix[2][2]; +} cairo_font_scale_t; + +struct cairo_font_backend; + +typedef struct { + int refcount; + const struct cairo_font_backend *backend; +} cairo_unscaled_font_t; + +/* + * A cairo_font contains a pointer to a cairo_sizeless_font_t and a scale + * matrix. These are the things the user holds references to. + */ + +struct cairo_font { + int refcount; + cairo_font_scale_t scale; + cairo_unscaled_font_t *unscaled; +}; + + +/* cairo_font.c is responsible for two global caches: + * + * - font entries: [[[base], name, weight, slant], cairo_unscaled_font_t ] + * - glyph entries: [[[base], cairo_font_t, index], image, size, extents ] + * + * Surfaces may build their own glyph caches if they have surface-specific + * glyph resources to maintain; those caches can feed off of the global + * caches if need be (eg. cairo_xlib_surface.c does this). + */ + +typedef struct { + cairo_cache_entry_base_t base; + cairo_unscaled_font_t *unscaled; + cairo_font_scale_t scale; + unsigned long index; +} cairo_glyph_cache_key_t; + +typedef struct { + cairo_glyph_cache_key_t key; + cairo_image_surface_t *image; + cairo_glyph_size_t size; + cairo_text_extents_t extents; +} cairo_image_glyph_cache_entry_t; + +extern void __internal_linkage +_cairo_lock_global_image_glyph_cache (void); + +extern void __internal_linkage +_cairo_unlock_global_image_glyph_cache (void); + +extern cairo_cache_t * __internal_linkage +_cairo_get_global_image_glyph_cache (void); + +/* Some glyph cache functions you can reuse. */ + +extern unsigned long __internal_linkage +_cairo_glyph_cache_hash (void *cache, void *key); + +extern int __internal_linkage +_cairo_glyph_cache_keys_equal (void *cache, + void *k1, + void *k2); + + +/* the font backend interface */ typedef struct cairo_font_backend { - cairo_font_t *(*create) (const char *family, + cairo_unscaled_font_t *(*create) (const char *family, cairo_font_slant_t slant, cairo_font_weight_t weight); - cairo_font_t *(*copy) (void *font); - void (*destroy) (void *font); cairo_status_t (*font_extents) (void *font, + cairo_font_scale_t *scale, cairo_font_extents_t *extents); - cairo_status_t (*text_extents) (void *font, + cairo_status_t (*text_to_glyphs) (void *font, + cairo_font_scale_t *scale, const unsigned char *utf8, - cairo_text_extents_t *extents); - + cairo_glyph_t **glyphs, + int *num_glyphs); + cairo_status_t (*glyph_extents) (void *font, + cairo_font_scale_t *scale, cairo_glyph_t *glyphs, int num_glyphs, cairo_text_extents_t *extents); - cairo_status_t (*text_bbox) (void *font, - cairo_surface_t *surface, - double x, - double y, - const unsigned char *utf8, - cairo_box_t *bbox); - cairo_status_t (*glyph_bbox) (void *font, - cairo_surface_t *surface, + cairo_font_scale_t *scale, const cairo_glyph_t *glyphs, int num_glyphs, cairo_box_t *bbox); - cairo_status_t (*show_text) (void *font, - cairo_operator_t operator, - cairo_surface_t *source, - cairo_surface_t *surface, - int source_x, - int source_y, - double x, - double y, - const unsigned char *utf8); - cairo_status_t (*show_glyphs) (void *font, + cairo_font_scale_t *scale, cairo_operator_t operator, cairo_surface_t *source, cairo_surface_t *surface, @@ -307,25 +458,19 @@ typedef struct cairo_font_backend { const cairo_glyph_t *glyphs, int num_glyphs); - cairo_status_t (*text_path) (void *font, - double x, - double y, - const unsigned char *utf8, - cairo_path_t *path); - cairo_status_t (*glyph_path) (void *font, + cairo_font_scale_t *scale, cairo_glyph_t *glyphs, int num_glyphs, cairo_path_t *path); - cairo_surface_t *(*create_glyph) (void *font, - const cairo_glyph_t *glyph, - cairo_glyph_size_t *return_size); + + cairo_status_t (*create_glyph) (cairo_image_glyph_cache_entry_t *entry); + } cairo_font_backend_t; /* concrete font backends */ extern const struct cairo_font_backend cairo_ft_font_backend; -typedef struct cairo_image_surface cairo_image_surface_t; typedef struct cairo_surface_backend { cairo_surface_t * @@ -410,6 +555,23 @@ typedef struct cairo_surface_backend { (*create_pattern) (void *surface, cairo_pattern_t *pattern, cairo_box_t *extents); + + /* + * This is an optional entry to let the surface manage its own glyph + * resources. If null, the font will be asked to render against this + * surface, using image surfaces as glyphs. + */ + cairo_status_t + (*show_glyphs) (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_operator_t operator, + cairo_surface_t *source, + cairo_surface_t *surface, + int source_x, + int source_y, + const cairo_glyph_t *glyphs, + int num_glyphs); + } cairo_surface_backend_t; struct cairo_matrix { @@ -547,40 +709,6 @@ typedef struct cairo_traps { /* XXX: Platform-specific. Other platforms may want a different default */ #define CAIRO_FONT_BACKEND_DEFAULT &cairo_ft_font_backend -#define CAIRO_FONT_CACHE_SIZE_DEFAULT 256 - -typedef struct { - unsigned long index; - double matrix[2][2]; - - unsigned int time; - - cairo_surface_t *surface; - cairo_glyph_size_t size; -} cairo_glyph_surface_t; - -typedef struct cairo_glyph_surface_node { - struct cairo_glyph_surface_node *next; - struct cairo_glyph_surface_node *prev; - - cairo_glyph_surface_t s; -} cairo_glyph_surface_node_t; - -typedef struct { - cairo_glyph_surface_node_t *first; - cairo_glyph_surface_node_t *last; - unsigned int n_nodes; - - unsigned int ref_count; - unsigned int cache_size; -} cairo_glyph_cache_t; - -struct cairo_font { - int refcount; - cairo_matrix_t matrix; - cairo_glyph_cache_t *glyph_cache; - const struct cairo_font_backend *backend; -}; #define CAIRO_GSTATE_OPERATOR_DEFAULT CAIRO_OPERATOR_OVER #define CAIRO_GSTATE_TOLERANCE_DEFAULT 0.1 @@ -618,7 +746,7 @@ typedef struct cairo_gstate { int num_dashes; double dash_offset; - cairo_font_t *font; + cairo_unscaled_font_t *font; cairo_surface_t *surface; @@ -628,6 +756,9 @@ typedef struct cairo_gstate { cairo_clip_rec_t clip; double pixels_per_inch; + + cairo_matrix_t font_matrix; + cairo_matrix_t ctm; cairo_matrix_t ctm_inverse; @@ -935,6 +1066,14 @@ extern cairo_status_t __internal_linkage _cairo_gstate_current_font (cairo_gstate_t *gstate, cairo_font_t **font); +extern void __internal_linkage +_cairo_gstate_set_font_transform (cairo_gstate_t *gstate, + cairo_matrix_t *matrix); + +extern void __internal_linkage +_cairo_gstate_current_font_transform (cairo_gstate_t *gstate, + cairo_matrix_t *matrix); + extern cairo_status_t __internal_linkage _cairo_gstate_current_font_extents (cairo_gstate_t *gstate, cairo_font_extents_t *extents); @@ -943,11 +1082,11 @@ extern cairo_status_t __internal_linkage _cairo_gstate_set_font (cairo_gstate_t *gstate, cairo_font_t *font); - extern cairo_status_t __internal_linkage -_cairo_gstate_text_extents (cairo_gstate_t *gstate, - const unsigned char *utf8, - cairo_text_extents_t *extents); +_cairo_gstate_text_to_glyphs (cairo_gstate_t *font, + const unsigned char *utf8, + cairo_glyph_t **glyphs, + int *num_glyphs); extern cairo_status_t __internal_linkage _cairo_gstate_glyph_extents (cairo_gstate_t *gstate, @@ -955,19 +1094,11 @@ _cairo_gstate_glyph_extents (cairo_gstate_t *gstate, int num_glyphs, cairo_text_extents_t *extents); -extern cairo_status_t __internal_linkage -_cairo_gstate_show_text (cairo_gstate_t *gstate, - const unsigned char *utf8); - extern cairo_status_t __internal_linkage _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, cairo_glyph_t *glyphs, int num_glyphs); -extern cairo_status_t __internal_linkage -_cairo_gstate_text_path (cairo_gstate_t *gstate, - const unsigned char *utf8); - extern cairo_status_t __internal_linkage _cairo_gstate_glyph_path (cairo_gstate_t *gstate, cairo_glyph_t *glyphs, @@ -992,95 +1123,69 @@ _cairo_color_set_alpha (cairo_color_t *color, double alpha); /* cairo_font.c */ -extern cairo_font_t * __internal_linkage -_cairo_font_create (const char *family, - cairo_font_slant_t slant, - cairo_font_weight_t weight); - -extern cairo_status_t __internal_linkage -_cairo_font_init (cairo_font_t *font, - const struct cairo_font_backend *backend); - -extern cairo_font_t * __internal_linkage -_cairo_font_copy (cairo_font_t *font); - -extern cairo_status_t __internal_linkage -_cairo_font_scale (cairo_font_t *font, double scale); +extern cairo_unscaled_font_t * __internal_linkage +_cairo_unscaled_font_create (const char *family, + cairo_font_slant_t slant, + cairo_font_weight_t weight); -extern cairo_status_t __internal_linkage -_cairo_font_transform (cairo_font_t *font, cairo_matrix_t *matrix); +extern void __internal_linkage +_cairo_font_init (cairo_font_t *scaled, + cairo_font_scale_t *scale, + cairo_unscaled_font_t *unscaled); extern cairo_status_t __internal_linkage -_cairo_font_font_extents (cairo_font_t *font, - cairo_font_extents_t *extents); +_cairo_unscaled_font_init (cairo_unscaled_font_t *font, + const struct cairo_font_backend *backend); -extern cairo_status_t __internal_linkage -_cairo_font_text_extents (cairo_font_t *font, - const unsigned char *utf8, - cairo_text_extents_t *extents); +extern void __internal_linkage +_cairo_unscaled_font_reference (cairo_unscaled_font_t *font); -extern cairo_status_t __internal_linkage -_cairo_font_glyph_extents (cairo_font_t *font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_text_extents_t *extents); +extern void __internal_linkage +_cairo_unscaled_font_destroy (cairo_unscaled_font_t *font); extern cairo_status_t __internal_linkage -_cairo_font_text_bbox (cairo_font_t *font, - cairo_surface_t *surface, - double x, - double y, - const unsigned char *utf8, - cairo_box_t *bbox); +_cairo_unscaled_font_font_extents (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_font_extents_t *extents); extern cairo_status_t __internal_linkage -_cairo_font_glyph_bbox (cairo_font_t *font, - cairo_surface_t *surface, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_box_t *bbox); +_cairo_unscaled_font_text_to_glyphs (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + const unsigned char *utf8, + cairo_glyph_t **glyphs, + int *num_glyphs); extern cairo_status_t __internal_linkage -_cairo_font_show_text (cairo_font_t *font, - cairo_operator_t operator, - cairo_surface_t *source, - cairo_surface_t *surface, - int source_x, - int source_y, - double x, - double y, - const unsigned char *utf8); - +_cairo_unscaled_font_glyph_extents (cairo_unscaled_font_t *font, + cairo_font_scale_t *scale, + cairo_glyph_t *glyphs, + int num_glyphs, + cairo_text_extents_t *extents); extern cairo_status_t __internal_linkage -_cairo_font_show_glyphs (cairo_font_t *font, - cairo_operator_t operator, - cairo_surface_t *source, - cairo_surface_t *surface, - int source_x, - int source_y, - cairo_glyph_t *glyphs, - int num_glyphs); - +_cairo_unscaled_font_glyph_bbox (cairo_unscaled_font_t *font, + cairo_font_scale_t *size, + cairo_glyph_t *glyphs, + int num_glyphs, + cairo_box_t *bbox); extern cairo_status_t __internal_linkage -_cairo_font_text_path (cairo_font_t *font, - double x, - double y, - const unsigned char *utf8, - cairo_path_t *path); +_cairo_unscaled_font_show_glyphs (cairo_unscaled_font_t *font, + cairo_font_scale_t *size, + cairo_operator_t operator, + cairo_surface_t *source, + cairo_surface_t *surface, + int source_x, + int source_y, + cairo_glyph_t *glyphs, + int num_glyphs); extern cairo_status_t __internal_linkage -_cairo_font_glyph_path (cairo_font_t *font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_path_t *path); - -extern cairo_surface_t *__internal_linkage -_cairo_font_lookup_glyph (cairo_font_t *font, - cairo_surface_t *surface, - const cairo_glyph_t *glyph, - cairo_glyph_size_t *return_size); +_cairo_unscaled_font_glyph_path (cairo_unscaled_font_t *font, + cairo_font_scale_t *size, + cairo_glyph_t *glyphs, + int num_glyphs, + cairo_path_t *path); /* cairo_hull.c */ extern cairo_status_t -- cgit v1.2.1 From cc890b9cf4d2a38e13ae48e16589c4fd02678f99 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 12 Oct 2004 12:29:29 +0000 Subject: Adapt function from Walter Brisken to compute pen ellipse major axis length and use that to compute the required number of pen vertices. reviewed by: Carl Worth --- ChangeLog | 9 ++ src/cairo-pen.c | 273 +++++++++++++++++++++++++++++++++++++++++++++++++++----- src/cairo_pen.c | 273 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 511 insertions(+), 44 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6af45f52c..01c15b577 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2004-10-12 Keith Packard + + reviewed by: Carl Worth + + * src/cairo_pen.c: (_cairo_pen_init), (_cairo_pen_vertices_needed): + Adapt function from Walter Brisken to compute pen ellipse major + axis length and use that to compute the required number of pen + vertices. + 2004-10-07 Graydon Hoare * src/Makefile.am (libcairo_la_SOURCES): Add cairo_cache.c diff --git a/src/cairo-pen.c b/src/cairo-pen.c index a6ebc5e04..1c63adec9 100644 --- a/src/cairo-pen.c +++ b/src/cairo-pen.c @@ -37,7 +37,7 @@ #include "cairoint.h" static int -_cairo_pen_vertices_needed (double radius, double tolerance, double expansion); +_cairo_pen_vertices_needed (double tolerance, double radius, cairo_matrix_t *matrix); static void _cairo_pen_compute_slopes (cairo_pen_t *pen); @@ -61,7 +61,7 @@ _cairo_pen_init (cairo_pen_t *pen, double radius, cairo_gstate_t *gstate) { int i; int reflect; - double det, expansion; + double det; if (pen->num_vertices) { /* XXX: It would be nice to notice that the pen is already properly constructed. @@ -76,24 +76,17 @@ _cairo_pen_init (cairo_pen_t *pen, double radius, cairo_gstate_t *gstate) pen->radius = radius; pen->tolerance = gstate->tolerance; - /* The determinant represents the area expansion factor of the - transform. In the worst case, this is entirely in one - dimension, which is what we assume here. */ - _cairo_matrix_compute_determinant (&gstate->ctm, &det); if (det >= 0) { reflect = 0; - expansion = det; } else { reflect = 1; - expansion = -det; } - - pen->num_vertices = _cairo_pen_vertices_needed (radius, gstate->tolerance, expansion); - /* number of vertices must be even */ - if (pen->num_vertices % 2) - pen->num_vertices++; + pen->num_vertices = _cairo_pen_vertices_needed (gstate->tolerance, + radius, + &gstate->ctm); + pen->vertices = malloc (pen->num_vertices * sizeof (cairo_pen_vertex_t)); if (pen->vertices == NULL) { return CAIRO_STATUS_NO_MEMORY; @@ -171,17 +164,253 @@ _cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points) return CAIRO_STATUS_SUCCESS; } +/* +The circular pen in user space is transformed into an ellipse in +device space. + +We construct the pen by computing points along the circumference +using equally spaced angles. + +We show below that this approximation to the ellipse has +maximum error at the major axis of the ellipse. +So, we need to compute the length of the major axis and then +use that to compute the number of sides needed in our pen. + +Thanks to Walter Brisken for this +derivation: + +1. First some notation: + +All capital letters represent vectors in two dimensions. A prime ' +represents a transformed coordinate. Matrices are written in underlined +form, ie _R_. Lowercase letters represent scalar real values. + +The letter t is used to represent the greek letter theta. + +2. The question has been posed: What is the maximum expansion factor +achieved by the linear transformation + +X' = _R_ X + +where _R_ is a real-valued 2x2 matrix with entries: + +_R_ = [a b] + [c d] . + +In other words, what is the maximum radius, MAX[ |X'| ], reached for any +X on the unit circle ( |X| = 1 ) ? + + +3. Some useful formulae + +(A) through (C) below are standard double-angle formulae. (D) is a lesser +known result and is derived below: + +(A) sin^2(t) = (1 - cos(2*t))/2 +(B) cos^2(t) = (1 + cos(2*t))/2 +(C) sin(t)*cos(t) = sin(2*t)/2 +(D) MAX[a*cos(t) + b*sin(t)] = sqrt(a^2 + b^2) + +Proof of (D): + +find the maximum of the function by setting the derivative to zero: + + -a*sin(t)+b*cos(t) = 0 + +From this it follows that + + tan(t) = b/a + +and hence + + sin(t) = b/sqrt(a^2 + b^2) + +and + + cos(t) = a/sqrt(a^2 + b^2) + +Thus the maximum value is + + MAX[a*cos(t) + b*sin(t)] = (a*a + b*b)/sqrt(a^2 + b^2) + = sqrt(a^2 + b^2) + + +4. Derivation of maximum expansion + +To find MAX[ |X'| ] we search brute force method using calculus. The unit +circle on which X is constrained is to be parameterized by t: + + X(t) = (cos(t), sin(t)) + +Thus + + X'(t) = (a*cos(t) + b*sin(t), c*cos(t) + d*sin(t)) . + +Define + + r(t) = |X'(t)| + +Thus + + r^2(t) = (a*cos(t) + b*sin(t))^2 + (c*cos(t) + d*sin(t))^2 + = (a^2 + c^2)*cos(t) + (b^2 + d^2)*sin(t) + + 2*(a*b + c*d)*cos(t)*sin(t) + +Now apply the double angle formulae (A) to (C) from above: + + r^2(t) = (a^2 + b^2 + c^2 + d^2)/2 + + (a^2 - b^2 + c^2 - d^2)*cos(2*t)/2 + + (a*b + c*d)*sin(2*t) + = f + g*cos(u) + h*sin(u) + +Where + + f = (a^2 + b^2 + c^2 + d^2)/2 + g = (a^2 - b^2 + c^2 - d^2)/2 + h = (a*b + c*d) + u = 2*t + +It is clear that MAX[ |X'| ] = sqrt(MAX[ r^2 ]). Here we determine MAX[ r^2 ] +using (D) from above: + + MAX[ r^2 ] = f + sqrt(g^2 + h^2) + +And finally + + MAX[ |X'| ] = sqrt( f + sqrt(g^2 + h^2) ) + +Which is the solution to this problem. + + +Walter Brisken +2004/10/08 + +(Note that the minor axis length is at the minimum of the above solution, +which is just sqrt (f - sqrt (g^2 + h^2)) given the symmetry of (D)). + +Now to compute how many sides to use for the pen formed by +a regular polygon. + +Set + + M = major axis length (computed by above formula) + m = minor axis length (computed by above formula) + +Align 'M' along the X axis and 'm' along the Y axis and draw +an ellipse parameterized by angle 't': + + x = M cos t y = m sin t + +Perturb t by ± d and compute two new points (x+,y+), (x-,y-). +The distance from the average of these two points to (x,y) represents +the maximum error in approximating the ellipse with a polygon formed +from vertices 2∆ radians apart. + + x+ = M cos (t+∆) y+ = m sin (t+∆) + x- = M cos (t-∆) y- = m sin (t-∆) + +Now compute the approximation error, E: + + Ex = (x - (x+ + x-) / 2) + Ex = (M cos(t) - (Mcos(t+∆) + Mcos(t-∆))/2) + = M (cos(t) - (cos(t)cos(∆) + sin(t)sin(∆) + + cos(t)cos(∆) - sin(t)sin(∆))/2) + = M(cos(t) - cos(t)cos(∆)) + = M cos(t) (1 - cos(∆)) + + Ey = y - (y+ - y-) / 2 + = m sin (t) - (m sin(t+∆) + m sin(t-∆)) / 2 + = m (sin(t) - (sin(t)cos(∆) + cos(t)sin(∆) + + sin(t)cos(∆) - cos(t)sin(∆))/2) + = m (sin(t) - sin(t)cos(∆)) + = m sin(t) (1 - cos(∆)) + + E² = Ex² + Ey² + = (M cos(t) (1 - cos (∆)))² + (m sin(t) (1-cos(∆)))² + = (1 - cos(∆))² (M² cos²(t) + m² sin²(t)) + = (1 - cos(∆))² ((m² + M² - m²) cos² (t) + m² sin²(t)) + = (1 - cos(∆))² (M² - m²) cos² (t) + (1 - cos(∆))² m² + +Find the extremum by differentiation wrt t and setting that to zero + +∂(E²)/∂(t) = (1-cos(d))² (M² - m²) (-2 cos(t) sin(t)) + + 0 = 2 cos (t) sin (t) + 0 = sin (2t) + t = nÏ€ + +Which is to say that the maximum and minimum errors occur on the +axes of the ellipse at 0 and Ï€ radians: + + E²(0) = (1-cos(∆))² (M² - m²) + (1-cos(∆))² m² + = (1-cos(∆))² M² + E²(Ï€) = (1-cos(∆))² m² + +maximum error = M (1-cos(∆)) +minimum error = m (1-cos(∆)) + +We must make maximum error ≤ tolerance, so compute the ∆ needed: + + tolerance = M (1-cos(∆)) + tolerance / M = 1 - cos (∆) + cos(∆) = 1 - tolerance/M + ∆ = acos (1 - tolerance / M); + +Remembering that ∆ is half of our angle between vertices, +the number of vertices is then + +vertices = ceil(2Ï€/2∆). + = ceil(Ï€/∆). + +Note that this also equation works for M == m (a circle) as it +doesn't matter where on the circle the error is computed. + +*/ + static int -_cairo_pen_vertices_needed (double radius, double tolerance, double expansion) +_cairo_pen_vertices_needed (double tolerance, + double radius, + cairo_matrix_t *matrix) { - double theta; + double a = matrix->m[0][0], c = matrix->m[0][1]; + double b = matrix->m[1][0], d = matrix->m[1][1]; - if (tolerance > expansion*radius) { - return 4; - } + double i = a*a + c*c; + double j = b*b + d*d; + + double f = 0.5 * (i + j); + double g = 0.5 * (i - j); + double h = a*b + c*d; + + /* + * compute major and minor axes lengths for + * a pen with the specified radius + */ + + double major_axis = radius * sqrt (f + sqrt (g*g+h*h)); - theta = acos (1 - tolerance/(expansion * radius)); - return ceil (M_PI / theta); + /* + * we don't need the minor axis length, which is + * double min = radius * sqrt (f - sqrt (g*g+h*h)); + */ + + /* + * compute number of vertices needed + */ + int num_vertices; + + /* Where tolerance / M is > 1, we use 4 points */ + if (tolerance >= major_axis) { + num_vertices = 4; + } else { + double delta = acos (1 - tolerance / major_axis); + num_vertices = ceil (M_PI / delta); + + /* number of vertices must be even */ + if (num_vertices % 2) + num_vertices++; + } + return num_vertices; } static void @@ -201,8 +430,8 @@ _cairo_pen_compute_slopes (cairo_pen_t *pen) _cairo_slope_init (&v->slope_ccw, &v->point, &next->point); } } - -/* Find active pen vertex for clockwise edge of stroke at the given slope. +/* + * Find active pen vertex for clockwise edge of stroke at the given slope. * * NOTE: The behavior of this function is sensitive to the sense of * the inequality within _cairo_slope_clockwise/_cairo_slope_counter_clockwise. diff --git a/src/cairo_pen.c b/src/cairo_pen.c index a6ebc5e04..1c63adec9 100644 --- a/src/cairo_pen.c +++ b/src/cairo_pen.c @@ -37,7 +37,7 @@ #include "cairoint.h" static int -_cairo_pen_vertices_needed (double radius, double tolerance, double expansion); +_cairo_pen_vertices_needed (double tolerance, double radius, cairo_matrix_t *matrix); static void _cairo_pen_compute_slopes (cairo_pen_t *pen); @@ -61,7 +61,7 @@ _cairo_pen_init (cairo_pen_t *pen, double radius, cairo_gstate_t *gstate) { int i; int reflect; - double det, expansion; + double det; if (pen->num_vertices) { /* XXX: It would be nice to notice that the pen is already properly constructed. @@ -76,24 +76,17 @@ _cairo_pen_init (cairo_pen_t *pen, double radius, cairo_gstate_t *gstate) pen->radius = radius; pen->tolerance = gstate->tolerance; - /* The determinant represents the area expansion factor of the - transform. In the worst case, this is entirely in one - dimension, which is what we assume here. */ - _cairo_matrix_compute_determinant (&gstate->ctm, &det); if (det >= 0) { reflect = 0; - expansion = det; } else { reflect = 1; - expansion = -det; } - - pen->num_vertices = _cairo_pen_vertices_needed (radius, gstate->tolerance, expansion); - /* number of vertices must be even */ - if (pen->num_vertices % 2) - pen->num_vertices++; + pen->num_vertices = _cairo_pen_vertices_needed (gstate->tolerance, + radius, + &gstate->ctm); + pen->vertices = malloc (pen->num_vertices * sizeof (cairo_pen_vertex_t)); if (pen->vertices == NULL) { return CAIRO_STATUS_NO_MEMORY; @@ -171,17 +164,253 @@ _cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points) return CAIRO_STATUS_SUCCESS; } +/* +The circular pen in user space is transformed into an ellipse in +device space. + +We construct the pen by computing points along the circumference +using equally spaced angles. + +We show below that this approximation to the ellipse has +maximum error at the major axis of the ellipse. +So, we need to compute the length of the major axis and then +use that to compute the number of sides needed in our pen. + +Thanks to Walter Brisken for this +derivation: + +1. First some notation: + +All capital letters represent vectors in two dimensions. A prime ' +represents a transformed coordinate. Matrices are written in underlined +form, ie _R_. Lowercase letters represent scalar real values. + +The letter t is used to represent the greek letter theta. + +2. The question has been posed: What is the maximum expansion factor +achieved by the linear transformation + +X' = _R_ X + +where _R_ is a real-valued 2x2 matrix with entries: + +_R_ = [a b] + [c d] . + +In other words, what is the maximum radius, MAX[ |X'| ], reached for any +X on the unit circle ( |X| = 1 ) ? + + +3. Some useful formulae + +(A) through (C) below are standard double-angle formulae. (D) is a lesser +known result and is derived below: + +(A) sin^2(t) = (1 - cos(2*t))/2 +(B) cos^2(t) = (1 + cos(2*t))/2 +(C) sin(t)*cos(t) = sin(2*t)/2 +(D) MAX[a*cos(t) + b*sin(t)] = sqrt(a^2 + b^2) + +Proof of (D): + +find the maximum of the function by setting the derivative to zero: + + -a*sin(t)+b*cos(t) = 0 + +From this it follows that + + tan(t) = b/a + +and hence + + sin(t) = b/sqrt(a^2 + b^2) + +and + + cos(t) = a/sqrt(a^2 + b^2) + +Thus the maximum value is + + MAX[a*cos(t) + b*sin(t)] = (a*a + b*b)/sqrt(a^2 + b^2) + = sqrt(a^2 + b^2) + + +4. Derivation of maximum expansion + +To find MAX[ |X'| ] we search brute force method using calculus. The unit +circle on which X is constrained is to be parameterized by t: + + X(t) = (cos(t), sin(t)) + +Thus + + X'(t) = (a*cos(t) + b*sin(t), c*cos(t) + d*sin(t)) . + +Define + + r(t) = |X'(t)| + +Thus + + r^2(t) = (a*cos(t) + b*sin(t))^2 + (c*cos(t) + d*sin(t))^2 + = (a^2 + c^2)*cos(t) + (b^2 + d^2)*sin(t) + + 2*(a*b + c*d)*cos(t)*sin(t) + +Now apply the double angle formulae (A) to (C) from above: + + r^2(t) = (a^2 + b^2 + c^2 + d^2)/2 + + (a^2 - b^2 + c^2 - d^2)*cos(2*t)/2 + + (a*b + c*d)*sin(2*t) + = f + g*cos(u) + h*sin(u) + +Where + + f = (a^2 + b^2 + c^2 + d^2)/2 + g = (a^2 - b^2 + c^2 - d^2)/2 + h = (a*b + c*d) + u = 2*t + +It is clear that MAX[ |X'| ] = sqrt(MAX[ r^2 ]). Here we determine MAX[ r^2 ] +using (D) from above: + + MAX[ r^2 ] = f + sqrt(g^2 + h^2) + +And finally + + MAX[ |X'| ] = sqrt( f + sqrt(g^2 + h^2) ) + +Which is the solution to this problem. + + +Walter Brisken +2004/10/08 + +(Note that the minor axis length is at the minimum of the above solution, +which is just sqrt (f - sqrt (g^2 + h^2)) given the symmetry of (D)). + +Now to compute how many sides to use for the pen formed by +a regular polygon. + +Set + + M = major axis length (computed by above formula) + m = minor axis length (computed by above formula) + +Align 'M' along the X axis and 'm' along the Y axis and draw +an ellipse parameterized by angle 't': + + x = M cos t y = m sin t + +Perturb t by ± d and compute two new points (x+,y+), (x-,y-). +The distance from the average of these two points to (x,y) represents +the maximum error in approximating the ellipse with a polygon formed +from vertices 2∆ radians apart. + + x+ = M cos (t+∆) y+ = m sin (t+∆) + x- = M cos (t-∆) y- = m sin (t-∆) + +Now compute the approximation error, E: + + Ex = (x - (x+ + x-) / 2) + Ex = (M cos(t) - (Mcos(t+∆) + Mcos(t-∆))/2) + = M (cos(t) - (cos(t)cos(∆) + sin(t)sin(∆) + + cos(t)cos(∆) - sin(t)sin(∆))/2) + = M(cos(t) - cos(t)cos(∆)) + = M cos(t) (1 - cos(∆)) + + Ey = y - (y+ - y-) / 2 + = m sin (t) - (m sin(t+∆) + m sin(t-∆)) / 2 + = m (sin(t) - (sin(t)cos(∆) + cos(t)sin(∆) + + sin(t)cos(∆) - cos(t)sin(∆))/2) + = m (sin(t) - sin(t)cos(∆)) + = m sin(t) (1 - cos(∆)) + + E² = Ex² + Ey² + = (M cos(t) (1 - cos (∆)))² + (m sin(t) (1-cos(∆)))² + = (1 - cos(∆))² (M² cos²(t) + m² sin²(t)) + = (1 - cos(∆))² ((m² + M² - m²) cos² (t) + m² sin²(t)) + = (1 - cos(∆))² (M² - m²) cos² (t) + (1 - cos(∆))² m² + +Find the extremum by differentiation wrt t and setting that to zero + +∂(E²)/∂(t) = (1-cos(d))² (M² - m²) (-2 cos(t) sin(t)) + + 0 = 2 cos (t) sin (t) + 0 = sin (2t) + t = nÏ€ + +Which is to say that the maximum and minimum errors occur on the +axes of the ellipse at 0 and Ï€ radians: + + E²(0) = (1-cos(∆))² (M² - m²) + (1-cos(∆))² m² + = (1-cos(∆))² M² + E²(Ï€) = (1-cos(∆))² m² + +maximum error = M (1-cos(∆)) +minimum error = m (1-cos(∆)) + +We must make maximum error ≤ tolerance, so compute the ∆ needed: + + tolerance = M (1-cos(∆)) + tolerance / M = 1 - cos (∆) + cos(∆) = 1 - tolerance/M + ∆ = acos (1 - tolerance / M); + +Remembering that ∆ is half of our angle between vertices, +the number of vertices is then + +vertices = ceil(2Ï€/2∆). + = ceil(Ï€/∆). + +Note that this also equation works for M == m (a circle) as it +doesn't matter where on the circle the error is computed. + +*/ + static int -_cairo_pen_vertices_needed (double radius, double tolerance, double expansion) +_cairo_pen_vertices_needed (double tolerance, + double radius, + cairo_matrix_t *matrix) { - double theta; + double a = matrix->m[0][0], c = matrix->m[0][1]; + double b = matrix->m[1][0], d = matrix->m[1][1]; - if (tolerance > expansion*radius) { - return 4; - } + double i = a*a + c*c; + double j = b*b + d*d; + + double f = 0.5 * (i + j); + double g = 0.5 * (i - j); + double h = a*b + c*d; + + /* + * compute major and minor axes lengths for + * a pen with the specified radius + */ + + double major_axis = radius * sqrt (f + sqrt (g*g+h*h)); - theta = acos (1 - tolerance/(expansion * radius)); - return ceil (M_PI / theta); + /* + * we don't need the minor axis length, which is + * double min = radius * sqrt (f - sqrt (g*g+h*h)); + */ + + /* + * compute number of vertices needed + */ + int num_vertices; + + /* Where tolerance / M is > 1, we use 4 points */ + if (tolerance >= major_axis) { + num_vertices = 4; + } else { + double delta = acos (1 - tolerance / major_axis); + num_vertices = ceil (M_PI / delta); + + /* number of vertices must be even */ + if (num_vertices % 2) + num_vertices++; + } + return num_vertices; } static void @@ -201,8 +430,8 @@ _cairo_pen_compute_slopes (cairo_pen_t *pen) _cairo_slope_init (&v->slope_ccw, &v->point, &next->point); } } - -/* Find active pen vertex for clockwise edge of stroke at the given slope. +/* + * Find active pen vertex for clockwise edge of stroke at the given slope. * * NOTE: The behavior of this function is sensitive to the sense of * the inequality within _cairo_slope_clockwise/_cairo_slope_counter_clockwise. -- cgit v1.2.1 From 047ce336000d595bcc123bb3647c44d239e1b89a Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 12 Oct 2004 14:09:37 +0000 Subject: Fix a few typos in pen vertex math description. --- ChangeLog | 4 ++++ src/cairo-pen.c | 6 +++--- src/cairo_pen.c | 6 +++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 01c15b577..f9134ce41 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2004-10-12 Carl Worth + + * src/cairo_pen.c: Fix a few typos in pen vertex math description. + 2004-10-12 Keith Packard reviewed by: Carl Worth diff --git a/src/cairo-pen.c b/src/cairo-pen.c index 1c63adec9..3e58dd7fc 100644 --- a/src/cairo-pen.c +++ b/src/cairo-pen.c @@ -231,7 +231,7 @@ and Thus the maximum value is - MAX[a*cos(t) + b*sin(t)] = (a*a + b*b)/sqrt(a^2 + b^2) + MAX[a*cos(t) + b*sin(t)] = (a^2 + b^2)/sqrt(a^2 + b^2) = sqrt(a^2 + b^2) @@ -253,7 +253,7 @@ Define Thus r^2(t) = (a*cos(t) + b*sin(t))^2 + (c*cos(t) + d*sin(t))^2 - = (a^2 + c^2)*cos(t) + (b^2 + d^2)*sin(t) + = (a^2 + c^2)*cos^2(t) + (b^2 + d^2)*sin^2(t) + 2*(a*b + c*d)*cos(t)*sin(t) Now apply the double angle formulae (A) to (C) from above: @@ -333,7 +333,7 @@ Now compute the approximation error, E: Find the extremum by differentiation wrt t and setting that to zero -∂(E²)/∂(t) = (1-cos(d))² (M² - m²) (-2 cos(t) sin(t)) +∂(E²)/∂(t) = (1-cos(∆))² (M² - m²) (-2 cos(t) sin(t)) 0 = 2 cos (t) sin (t) 0 = sin (2t) diff --git a/src/cairo_pen.c b/src/cairo_pen.c index 1c63adec9..3e58dd7fc 100644 --- a/src/cairo_pen.c +++ b/src/cairo_pen.c @@ -231,7 +231,7 @@ and Thus the maximum value is - MAX[a*cos(t) + b*sin(t)] = (a*a + b*b)/sqrt(a^2 + b^2) + MAX[a*cos(t) + b*sin(t)] = (a^2 + b^2)/sqrt(a^2 + b^2) = sqrt(a^2 + b^2) @@ -253,7 +253,7 @@ Define Thus r^2(t) = (a*cos(t) + b*sin(t))^2 + (c*cos(t) + d*sin(t))^2 - = (a^2 + c^2)*cos(t) + (b^2 + d^2)*sin(t) + = (a^2 + c^2)*cos^2(t) + (b^2 + d^2)*sin^2(t) + 2*(a*b + c*d)*cos(t)*sin(t) Now apply the double angle formulae (A) to (C) from above: @@ -333,7 +333,7 @@ Now compute the approximation error, E: Find the extremum by differentiation wrt t and setting that to zero -∂(E²)/∂(t) = (1-cos(d))² (M² - m²) (-2 cos(t) sin(t)) +∂(E²)/∂(t) = (1-cos(∆))² (M² - m²) (-2 cos(t) sin(t)) 0 = 2 cos (t) sin (t) 0 = sin (2t) -- cgit v1.2.1 From f9b0020850ac62f37989e6828a69ddaa421d722b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 12 Oct 2004 14:17:23 +0000 Subject: Compute extents of cairo_traps_t on the fly using approximate method which is correct given the way cairo generates trapezoids. Avoid zero-dimensioned pixmaps --- ChangeLog | 11 +++++ src/cairo-traps.c | 105 +++++++++++++++++++++++++---------------------- src/cairo-xlib-surface.c | 2 +- src/cairo_traps.c | 105 +++++++++++++++++++++++++---------------------- src/cairo_xlib_surface.c | 2 +- src/cairoint.h | 1 + 6 files changed, 126 insertions(+), 100 deletions(-) diff --git a/ChangeLog b/ChangeLog index f9134ce41..186deb2b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2004-10-12 Keith Packard + + * src/cairo_traps.c: (_cairo_traps_init), (_cairo_traps_add_trap), + (_cairo_traps_extents): + * src/cairoint.h: + Compute extents of cairo_traps_t on the fly using approximate + method which is correct given the way cairo generates trapezoids. + + * src/cairo_xlib_surface.c: (_cairo_xlib_surface_create_similar): + Avoid zero-dimensioned pixmaps + 2004-10-12 Carl Worth * src/cairo_pen.c: Fix a few typos in pen vertex math description. diff --git a/src/cairo-traps.c b/src/cairo-traps.c index 000e05f4f..1dc6e3df2 100644 --- a/src/cairo-traps.c +++ b/src/cairo-traps.c @@ -1,23 +1,36 @@ /* * Copyright © 2002 Keith Packard * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is Keith Packard + * + * Contributor(s): + * Keith R. Packard + * Carl D. Worth * * 2002-07-15: Converted from XRenderCompositeDoublePoly to cairo_trap. Carl D. Worth */ @@ -62,6 +75,8 @@ _cairo_traps_init (cairo_traps_t *traps) traps->traps_size = 0; traps->traps = NULL; + traps->extents.p1.x = traps->extents.p1.y = CAIRO_MAXSHORT << 16; + traps->extents.p2.x = traps->extents.p2.y = CAIRO_MINSHORT << 16; } void @@ -87,7 +102,8 @@ _cairo_traps_add_trap (cairo_traps_t *traps, cairo_fixed_t top, cairo_fixed_t bo } if (traps->num_traps >= traps->traps_size) { - status = _cairo_traps_grow_by (traps, CAIRO_TRAPS_GROWTH_INC); + int inc = traps->traps_size ? traps->traps_size : 32; + status = _cairo_traps_grow_by (traps, inc); if (status) return status; } @@ -98,6 +114,28 @@ _cairo_traps_add_trap (cairo_traps_t *traps, cairo_fixed_t top, cairo_fixed_t bo trap->left = *left; trap->right = *right; + if (top < traps->extents.p1.y) + traps->extents.p1.y = top; + if (bottom > traps->extents.p2.y) + traps->extents.p2.y = bottom; + /* + * This isn't generally accurate, but it is close enough for + * this purpose. Assuming that the left and right segments always + * contain the trapezoid vertical extents, these compares will + * yield a containing box. Assuming that the points all come from + * the same figure which will eventually be completely drawn, then + * the compares will yield the correct overall extents + */ + if (left->p1.x < traps->extents.p1.x) + traps->extents.p1.x = left->p1.x; + if (left->p2.x < traps->extents.p1.x) + traps->extents.p1.x = left->p2.x; + + if (right->p1.x > traps->extents.p2.x) + traps->extents.p2.x = right->p1.x; + if (right->p2.x > traps->extents.p2.x) + traps->extents.p2.x = right->p2.x; + traps->num_traps++; return CAIRO_STATUS_SUCCESS; @@ -673,39 +711,8 @@ _cairo_traps_contain (cairo_traps_t *traps, double x, double y) return 0; } -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - -static void -_cairo_trap_extents (cairo_trapezoid_t *t, cairo_box_t *extents) -{ - cairo_fixed_t x; - - if (t->top < extents->p1.y) - extents->p1.y = t->top; - - if (t->bottom > extents->p2.y) - extents->p2.y = t->bottom; - - x = MIN (_compute_x (&t->left, t->top), - _compute_x (&t->left, t->bottom)); - if (x < extents->p1.x) - extents->p1.x = x; - - x = MAX (_compute_x (&t->right, t->top), - _compute_x (&t->right, t->bottom)); - if (x > extents->p2.x) - extents->p2.x = x; -} - void _cairo_traps_extents (cairo_traps_t *traps, cairo_box_t *extents) { - int i; - - extents->p1.x = extents->p1.y = CAIRO_MAXSHORT << 16; - extents->p2.x = extents->p2.y = CAIRO_MINSHORT << 16; - - for (i = 0; i < traps->num_traps; i++) - _cairo_trap_extents (&traps->traps[i], extents); + *extents = traps->extents; } diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index fca7f33e4..43491a904 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -145,7 +145,7 @@ _cairo_xlib_surface_create_similar (void *abstract_src, scr = DefaultScreen (dpy); pix = XCreatePixmap (dpy, DefaultRootWindow (dpy), - width, height, + width <= 0 ? 1 : width, height <= 0 ? 1 : height, _CAIRO_FORMAT_DEPTH (format)); surface = (cairo_xlib_surface_t *) diff --git a/src/cairo_traps.c b/src/cairo_traps.c index 000e05f4f..1dc6e3df2 100644 --- a/src/cairo_traps.c +++ b/src/cairo_traps.c @@ -1,23 +1,36 @@ /* * Copyright © 2002 Keith Packard * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is Keith Packard + * + * Contributor(s): + * Keith R. Packard + * Carl D. Worth * * 2002-07-15: Converted from XRenderCompositeDoublePoly to cairo_trap. Carl D. Worth */ @@ -62,6 +75,8 @@ _cairo_traps_init (cairo_traps_t *traps) traps->traps_size = 0; traps->traps = NULL; + traps->extents.p1.x = traps->extents.p1.y = CAIRO_MAXSHORT << 16; + traps->extents.p2.x = traps->extents.p2.y = CAIRO_MINSHORT << 16; } void @@ -87,7 +102,8 @@ _cairo_traps_add_trap (cairo_traps_t *traps, cairo_fixed_t top, cairo_fixed_t bo } if (traps->num_traps >= traps->traps_size) { - status = _cairo_traps_grow_by (traps, CAIRO_TRAPS_GROWTH_INC); + int inc = traps->traps_size ? traps->traps_size : 32; + status = _cairo_traps_grow_by (traps, inc); if (status) return status; } @@ -98,6 +114,28 @@ _cairo_traps_add_trap (cairo_traps_t *traps, cairo_fixed_t top, cairo_fixed_t bo trap->left = *left; trap->right = *right; + if (top < traps->extents.p1.y) + traps->extents.p1.y = top; + if (bottom > traps->extents.p2.y) + traps->extents.p2.y = bottom; + /* + * This isn't generally accurate, but it is close enough for + * this purpose. Assuming that the left and right segments always + * contain the trapezoid vertical extents, these compares will + * yield a containing box. Assuming that the points all come from + * the same figure which will eventually be completely drawn, then + * the compares will yield the correct overall extents + */ + if (left->p1.x < traps->extents.p1.x) + traps->extents.p1.x = left->p1.x; + if (left->p2.x < traps->extents.p1.x) + traps->extents.p1.x = left->p2.x; + + if (right->p1.x > traps->extents.p2.x) + traps->extents.p2.x = right->p1.x; + if (right->p2.x > traps->extents.p2.x) + traps->extents.p2.x = right->p2.x; + traps->num_traps++; return CAIRO_STATUS_SUCCESS; @@ -673,39 +711,8 @@ _cairo_traps_contain (cairo_traps_t *traps, double x, double y) return 0; } -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - -static void -_cairo_trap_extents (cairo_trapezoid_t *t, cairo_box_t *extents) -{ - cairo_fixed_t x; - - if (t->top < extents->p1.y) - extents->p1.y = t->top; - - if (t->bottom > extents->p2.y) - extents->p2.y = t->bottom; - - x = MIN (_compute_x (&t->left, t->top), - _compute_x (&t->left, t->bottom)); - if (x < extents->p1.x) - extents->p1.x = x; - - x = MAX (_compute_x (&t->right, t->top), - _compute_x (&t->right, t->bottom)); - if (x > extents->p2.x) - extents->p2.x = x; -} - void _cairo_traps_extents (cairo_traps_t *traps, cairo_box_t *extents) { - int i; - - extents->p1.x = extents->p1.y = CAIRO_MAXSHORT << 16; - extents->p2.x = extents->p2.y = CAIRO_MINSHORT << 16; - - for (i = 0; i < traps->num_traps; i++) - _cairo_trap_extents (&traps->traps[i], extents); + *extents = traps->extents; } diff --git a/src/cairo_xlib_surface.c b/src/cairo_xlib_surface.c index fca7f33e4..43491a904 100644 --- a/src/cairo_xlib_surface.c +++ b/src/cairo_xlib_surface.c @@ -145,7 +145,7 @@ _cairo_xlib_surface_create_similar (void *abstract_src, scr = DefaultScreen (dpy); pix = XCreatePixmap (dpy, DefaultRootWindow (dpy), - width, height, + width <= 0 ? 1 : width, height <= 0 ? 1 : height, _CAIRO_FORMAT_DEPTH (format)); surface = (cairo_xlib_surface_t *) diff --git a/src/cairoint.h b/src/cairoint.h index 728a5d174..ffaecf9d3 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -700,6 +700,7 @@ typedef struct cairo_traps { cairo_trapezoid_t *traps; int num_traps; int traps_size; + cairo_box_t extents; } cairo_traps_t; #define CAIRO_FONT_FAMILY_DEFAULT "serif" -- cgit v1.2.1 From d8b24a4ee035071db8b65c1fcc37ef467b70e2c7 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 13 Oct 2004 08:18:38 +0000 Subject: automake 1.4 seems to be sufficient. Don't require 1.6. --- ChangeLog | 5 +++++ autogen.sh | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 186deb2b8..efb4888df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2004-10-13 Carl Worth + + * autogen.sh: automake 1.4 seems to be sufficient. Don't require + 1.6. + 2004-10-12 Keith Packard * src/cairo_traps.c: (_cairo_traps_init), (_cairo_traps_add_trap), diff --git a/autogen.sh b/autogen.sh index a952f4c53..dbe36ddf6 100755 --- a/autogen.sh +++ b/autogen.sh @@ -14,8 +14,8 @@ AUTOCONF=${AUTOCONF-autoconf} # automake 1.8 requires autoconf 2.58 # automake 1.7 requires autoconf 2.54 -# I don't know what automake 1.6 wants, but this seems to work... -automake_min_vers=1.6 +# I don't know what automake 1.4 wants, but the following seems to work... +automake_min_vers=1.4 aclocal_min_vers=$automake_min_vers autoconf_min_vers=2.54 libtoolize_min_vers=1.4 -- cgit v1.2.1 From 06788edb0af0b1c15823022747c58e5d595d9960 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 13 Oct 2004 11:01:42 +0000 Subject: Add notes for snapshot 0.1.2 Increment version to 0.1.2 --- pixman/ChangeLog | 6 ++++++ pixman/NEWS | 24 ++++++++++++++++++++++++ pixman/configure.in | 3 +-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/pixman/ChangeLog b/pixman/ChangeLog index e9161905c..402e47afa 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -1,3 +1,9 @@ +2004-10-13 Carl Worth + + * NEWS: Add notes for snapshot 0.1.2 + + * configure.in: Increment version to 0.1.2 + 2004-09-12 David Reveman * src/icformat.c (pixman_format_init): pixman_format_init expects diff --git a/pixman/NEWS b/pixman/NEWS index 55f8c0876..9e6b99c5d 100644 --- a/pixman/NEWS +++ b/pixman/NEWS @@ -1,3 +1,27 @@ +Snapshot 0.1.2 (2004-10-13 Carl Worth ) +========================================================== +New functionality +----------------- +Added three new functions: + + pixman_image_set_component_alpha + pixman_format_get_masks + pixman_image_get_format + +The first enables component-alpha compositing which can be used for +optimizing sub-pixel rendering of text and other geometry. This is +useful when the geometrical relationship of the sub-pixel components +of the display device are known, (eg. with flat-panel monitors rather +than CRTs). + +The other two functions are simple query functions that were missing. + +Bug fixes +--------- +Enabling transform and repeat together now works. +Endian-ness fixes. +Memory mismanagement fixes. + Snapshot 0.1.1 (2004-04-16 Carl Worth ) ============================================================ Build fixes for cygwin diff --git a/pixman/configure.in b/pixman/configure.in index 4a4c17a73..3248d3c0b 100644 --- a/pixman/configure.in +++ b/pixman/configure.in @@ -5,8 +5,7 @@ AC_INIT(src/pixman.h) dnl =========================================================================== # Package version number, (as distinct from shared library version) -# This must be manually synchronized with the version in src/pixman.h -LIBPIXMAN_VERSION=0.1.1 +LIBPIXMAN_VERSION=0.1.2 # libtool shared library version -- cgit v1.2.1 From ce5f903ea84c398f0766fefdafc4f0866fc2c429 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 13 Oct 2004 11:13:51 +0000 Subject: Fix email address in ChangeLog --- pixman/ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pixman/ChangeLog b/pixman/ChangeLog index 402e47afa..bf6165c8e 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -1,4 +1,4 @@ -2004-10-13 Carl Worth +2004-10-13 Carl Worth * NEWS: Add notes for snapshot 0.1.2 -- cgit v1.2.1 From fe2b2c0abf64ad67f9f128c29d2ecd24d8fbac2a Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 21 Oct 2004 08:31:21 +0000 Subject: Makefile.am --- ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index efb4888df..e5c1b9c6e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2004-10-21 Carl Worth + + * Makefile.am (EXTRA_DIST): Add COPYING-LGPL-2.1 and + COPYING-MPL-1.1 to the distribution. + 2004-10-13 Carl Worth * autogen.sh: automake 1.4 seems to be sufficient. Don't require -- cgit v1.2.1 From 07677744429a5664af30dcbae5bd67d26ba64401 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 21 Oct 2004 08:51:52 +0000 Subject: Add COPYING-LGPL-2.1 and COPYING-MPL-1.1 to the distribution. --- Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile.am b/Makefile.am index 297ec9de8..aed2d88af 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,6 +2,8 @@ SUBDIRS = src EXTRA_DIST = \ COPYING \ + COPYING-LGPL-2.1 \ + COPYING-MPL-1.1 \ cairo.pc.in pkgconfigdir = $(libdir)/pkgconfig -- cgit v1.2.1 From de115d07c35ec59e65d27bbfeced9af5a9df43c0 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 21 Oct 2004 08:55:46 +0000 Subject: Add items on custom caps and getting access to hidden image data --- ChangeLog | 3 +++ TODO | 13 +++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index e5c1b9c6e..ecd228933 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2004-10-21 Carl Worth + * TODO: Add items on custom caps and getting access to hidden + image data + * Makefile.am (EXTRA_DIST): Add COPYING-LGPL-2.1 and COPYING-MPL-1.1 to the distribution. diff --git a/TODO b/TODO index d06fee883..2f594ec5b 100644 --- a/TODO +++ b/TODO @@ -58,10 +58,19 @@ functions: cairo_mark_dirty * Re-implement the trapezoid rasterization algorithm according to the -new "specification". + new "specification". * Stroking closed, degenerate paths should still draw caps. Round -caps are easy; square should probably draw an axis aligned square. + caps are easy; square should probably draw an axis-aligned square. + +* It would be nice if the user had a mechanism to reliably draw custom + caps. One approach here would be to provide the coordinates of the + butt cap faces so that the user can append seamless caps to the + current path. We may also need to provide the coordinates of the + faces of every dash as well. + +* We need a way to get at the image data after something + like cairo_surface_create_similar with the image backend. * Verification, profiling, optimization. -- cgit v1.2.1 From 215d5c5a46b7523faa31d2f1d087123a7fd54f32 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 21 Oct 2004 18:26:25 +0000 Subject: Fix comparison so that it results in a stable sort. This should fix some rendering bugs due to broken pens. --- ChangeLog | 4 ++++ src/cairo-hull.c | 7 +++++-- src/cairo_hull.c | 7 +++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index ecd228933..274b6ef23 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2004-10-21 Carl Worth + * src/cairo_hull.c (_cairo_hull_vertex_compare): Fix comparison so + that it results in a stable sort. This should fix some rendering + bugs due to broken pens. + * TODO: Add items on custom caps and getting access to hidden image data diff --git a/src/cairo-hull.c b/src/cairo-hull.c index be464f369..37825b952 100644 --- a/src/cairo-hull.c +++ b/src/cairo-hull.c @@ -97,10 +97,13 @@ _cairo_hull_vertex_compare (const void *av, const void *bv) (cairo_fixed_48_16_t) a->slope.dy * a->slope.dy); b_dist = ((cairo_fixed_48_16_t) b->slope.dx * b->slope.dx + (cairo_fixed_48_16_t) b->slope.dy * b->slope.dy); - if (a_dist < b_dist) + if (a_dist < b_dist) { a->discard = 1; - else + ret = -1; + } else { b->discard = 1; + ret = 1; + } } return ret; diff --git a/src/cairo_hull.c b/src/cairo_hull.c index be464f369..37825b952 100644 --- a/src/cairo_hull.c +++ b/src/cairo_hull.c @@ -97,10 +97,13 @@ _cairo_hull_vertex_compare (const void *av, const void *bv) (cairo_fixed_48_16_t) a->slope.dy * a->slope.dy); b_dist = ((cairo_fixed_48_16_t) b->slope.dx * b->slope.dx + (cairo_fixed_48_16_t) b->slope.dy * b->slope.dy); - if (a_dist < b_dist) + if (a_dist < b_dist) { a->discard = 1; - else + ret = -1; + } else { b->discard = 1; + ret = 1; + } } return ret; -- cgit v1.2.1 From bf8374dba260c80ae8ee33c1eb5bddf39ae649f4 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 21 Oct 2004 18:40:50 +0000 Subject: Convert all files to utf-8. Add copyright information to cairo_png_surface.c. --- ChangeLog | 31 +++++++++++++++++++++++++++++++ src/cairo-cache.c | 2 +- src/cairo-color.c | 2 +- src/cairo-fixed.c | 2 +- src/cairo-font.c | 2 +- src/cairo-ft-font.c | 2 +- src/cairo-glitz-surface.c | 2 +- src/cairo-gstate.c | 2 +- src/cairo-hash.c | 2 +- src/cairo-hull.c | 2 +- src/cairo-image-surface.c | 2 +- src/cairo-matrix.c | 2 +- src/cairo-path-bounds.c | 2 +- src/cairo-path-fill.c | 2 +- src/cairo-path-stroke.c | 2 +- src/cairo-path.c | 2 +- src/cairo-pattern.c | 2 +- src/cairo-pen.c | 2 +- src/cairo-polygon.c | 2 +- src/cairo-ps-surface.c | 2 +- src/cairo-slope.c | 2 +- src/cairo-spline.c | 2 +- src/cairo-surface.c | 2 +- src/cairo-traps.c | 2 +- src/cairo-xcb-surface.c | 2 +- src/cairo-xlib-surface.c | 2 +- src/cairo.c | 2 +- src/cairo.h | 2 +- src/cairo_cache.c | 2 +- src/cairo_color.c | 2 +- src/cairo_fixed.c | 2 +- src/cairo_font.c | 2 +- src/cairo_ft_font.c | 2 +- src/cairo_glitz_surface.c | 2 +- src/cairo_gstate.c | 2 +- src/cairo_hull.c | 2 +- src/cairo_image_surface.c | 2 +- src/cairo_matrix.c | 2 +- src/cairo_path.c | 2 +- src/cairo_path_bounds.c | 2 +- src/cairo_path_fill.c | 2 +- src/cairo_path_stroke.c | 2 +- src/cairo_pattern.c | 2 +- src/cairo_pen.c | 2 +- src/cairo_png_surface.c | 37 +++++++++++++++++++++++++++++++++++++ src/cairo_polygon.c | 2 +- src/cairo_ps_surface.c | 2 +- src/cairo_slope.c | 2 +- src/cairo_spline.c | 2 +- src/cairo_surface.c | 2 +- src/cairo_traps.c | 2 +- src/cairo_xcb_surface.c | 2 +- src/cairo_xlib_surface.c | 2 +- src/cairoint.h | 2 +- 54 files changed, 120 insertions(+), 52 deletions(-) diff --git a/ChangeLog b/ChangeLog index 274b6ef23..a22b8f3f8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,36 @@ 2004-10-21 Carl Worth + * src/cairo_png_surface.c: + * src/cairo.c: + * src/cairo.h: + * src/cairo_cache.c: + * src/cairo_color.c: + * src/cairo_fixed.c: + * src/cairo_font.c: + * src/cairo_ft_font.c: + * src/cairo_glitz_surface.c: + * src/cairo_gstate.c: + * src/cairo_hull.c: + * src/cairo_image_surface.c: + * src/cairo_matrix.c: + * src/cairo_path.c: + * src/cairo_path_bounds.c: + * src/cairo_path_fill.c: + * src/cairo_path_stroke.c: + * src/cairo_pattern.c: + * src/cairo_pen.c: + * src/cairo_png_surface.c: + * src/cairo_polygon.c: + * src/cairo_ps_surface.c: + * src/cairo_slope.c: + * src/cairo_spline.c: + * src/cairo_surface.c: + * src/cairo_traps.c: + * src/cairo_xcb_surface.c: + * src/cairo_xlib_surface.c: + * src/cairoint.h: Convert all files to utf-8. Add copyright + information to cairo_png_surface.c. + * src/cairo_hull.c (_cairo_hull_vertex_compare): Fix comparison so that it results in a stable sort. This should fix some rendering bugs due to broken pens. diff --git a/src/cairo-cache.c b/src/cairo-cache.c index c5ce39935..a33d69a04 100644 --- a/src/cairo-cache.c +++ b/src/cairo-cache.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * This file is Copyright © 2004 Red Hat, Inc. + * This file is Copyright © 2004 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo-color.c b/src/cairo-color.c index 7dc733118..2fe793ac8 100644 --- a/src/cairo-color.c +++ b/src/cairo-color.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo-fixed.c b/src/cairo-fixed.c index 9bafce360..32368d7fc 100644 --- a/src/cairo-fixed.c +++ b/src/cairo-fixed.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2003 University of Southern California + * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo-font.c b/src/cairo-font.c index c90a02bd6..5ad9f0417 100644 --- a/src/cairo-font.c +++ b/src/cairo-font.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 740613501..f757db09c 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -1,5 +1,5 @@ /* - * Copyright © 2003 Red Hat Inc. + * Copyright © 2003 Red Hat Inc. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c index d351108db..21e889204 100644 --- a/src/cairo-glitz-surface.c +++ b/src/cairo-glitz-surface.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2004 David Reveman + * Copyright © 2004 David Reveman * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index fabb53efd..9f9de69e1 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo-hash.c b/src/cairo-hash.c index c5ce39935..a33d69a04 100644 --- a/src/cairo-hash.c +++ b/src/cairo-hash.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * This file is Copyright © 2004 Red Hat, Inc. + * This file is Copyright © 2004 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo-hull.c b/src/cairo-hull.c index 37825b952..99b16d1ae 100644 --- a/src/cairo-hull.c +++ b/src/cairo-hull.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2003 University of Southern California + * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index 9e6abb2a6..cbdc018a1 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2003 University of Southern California + * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c index 540470e65..7fc2694f3 100644 --- a/src/cairo-matrix.c +++ b/src/cairo-matrix.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo-path-bounds.c b/src/cairo-path-bounds.c index 5f59cb5fc..cfcdd97ee 100644 --- a/src/cairo-path-bounds.c +++ b/src/cairo-path-bounds.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2003 University of Southern California + * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo-path-fill.c b/src/cairo-path-fill.c index ca5e098ca..6c6ebd976 100644 --- a/src/cairo-path-fill.c +++ b/src/cairo-path-fill.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c index 477cf99e0..ad0220370 100644 --- a/src/cairo-path-stroke.c +++ b/src/cairo-path-stroke.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo-path.c b/src/cairo-path.c index 21715bf35..36c25d637 100644 --- a/src/cairo-path.c +++ b/src/cairo-path.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c index e10013729..6cb981458 100644 --- a/src/cairo-pattern.c +++ b/src/cairo-pattern.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2004 David Reveman + * Copyright © 2004 David Reveman * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without diff --git a/src/cairo-pen.c b/src/cairo-pen.c index 3e58dd7fc..f365091dc 100644 --- a/src/cairo-pen.c +++ b/src/cairo-pen.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo-polygon.c b/src/cairo-polygon.c index 8fc1f3097..8fa32f9f6 100644 --- a/src/cairo-polygon.c +++ b/src/cairo-polygon.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c index 9b3096b0f..bfdfada38 100644 --- a/src/cairo-ps-surface.c +++ b/src/cairo-ps-surface.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2003 University of Southern California + * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo-slope.c b/src/cairo-slope.c index 484cd86fd..1a1497988 100644 --- a/src/cairo-slope.c +++ b/src/cairo-slope.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo-spline.c b/src/cairo-spline.c index f3c21726d..bed351ef4 100644 --- a/src/cairo-spline.c +++ b/src/cairo-spline.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo-surface.c b/src/cairo-surface.c index e5cf7aa9d..a457d2062 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo-traps.c b/src/cairo-traps.c index 1dc6e3df2..8f8d035c1 100644 --- a/src/cairo-traps.c +++ b/src/cairo-traps.c @@ -1,5 +1,5 @@ /* - * Copyright © 2002 Keith Packard + * Copyright © 2002 Keith Packard * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c index bc37d2047..21760d764 100644 --- a/src/cairo-xcb-surface.c +++ b/src/cairo-xcb-surface.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index 43491a904..dda7995bd 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo.c b/src/cairo.c index 8bd5f2012..7e6f1d7b4 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo.h b/src/cairo.h index 44b631633..25dfd4d6b 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo_cache.c b/src/cairo_cache.c index c5ce39935..a33d69a04 100644 --- a/src/cairo_cache.c +++ b/src/cairo_cache.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * This file is Copyright © 2004 Red Hat, Inc. + * This file is Copyright © 2004 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo_color.c b/src/cairo_color.c index 7dc733118..2fe793ac8 100644 --- a/src/cairo_color.c +++ b/src/cairo_color.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo_fixed.c b/src/cairo_fixed.c index 9bafce360..32368d7fc 100644 --- a/src/cairo_fixed.c +++ b/src/cairo_fixed.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2003 University of Southern California + * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo_font.c b/src/cairo_font.c index c90a02bd6..5ad9f0417 100644 --- a/src/cairo_font.c +++ b/src/cairo_font.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo_ft_font.c b/src/cairo_ft_font.c index 740613501..f757db09c 100644 --- a/src/cairo_ft_font.c +++ b/src/cairo_ft_font.c @@ -1,5 +1,5 @@ /* - * Copyright © 2003 Red Hat Inc. + * Copyright © 2003 Red Hat Inc. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, diff --git a/src/cairo_glitz_surface.c b/src/cairo_glitz_surface.c index d351108db..21e889204 100644 --- a/src/cairo_glitz_surface.c +++ b/src/cairo_glitz_surface.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2004 David Reveman + * Copyright © 2004 David Reveman * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without diff --git a/src/cairo_gstate.c b/src/cairo_gstate.c index fabb53efd..9f9de69e1 100644 --- a/src/cairo_gstate.c +++ b/src/cairo_gstate.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo_hull.c b/src/cairo_hull.c index 37825b952..99b16d1ae 100644 --- a/src/cairo_hull.c +++ b/src/cairo_hull.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2003 University of Southern California + * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo_image_surface.c b/src/cairo_image_surface.c index 9e6abb2a6..cbdc018a1 100644 --- a/src/cairo_image_surface.c +++ b/src/cairo_image_surface.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2003 University of Southern California + * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo_matrix.c b/src/cairo_matrix.c index 540470e65..7fc2694f3 100644 --- a/src/cairo_matrix.c +++ b/src/cairo_matrix.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo_path.c b/src/cairo_path.c index 21715bf35..36c25d637 100644 --- a/src/cairo_path.c +++ b/src/cairo_path.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo_path_bounds.c b/src/cairo_path_bounds.c index 5f59cb5fc..cfcdd97ee 100644 --- a/src/cairo_path_bounds.c +++ b/src/cairo_path_bounds.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2003 University of Southern California + * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo_path_fill.c b/src/cairo_path_fill.c index ca5e098ca..6c6ebd976 100644 --- a/src/cairo_path_fill.c +++ b/src/cairo_path_fill.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo_path_stroke.c b/src/cairo_path_stroke.c index 477cf99e0..ad0220370 100644 --- a/src/cairo_path_stroke.c +++ b/src/cairo_path_stroke.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo_pattern.c b/src/cairo_pattern.c index e10013729..6cb981458 100644 --- a/src/cairo_pattern.c +++ b/src/cairo_pattern.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2004 David Reveman + * Copyright © 2004 David Reveman * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without diff --git a/src/cairo_pen.c b/src/cairo_pen.c index 3e58dd7fc..f365091dc 100644 --- a/src/cairo_pen.c +++ b/src/cairo_pen.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo_png_surface.c b/src/cairo_png_surface.c index cfd68c878..4c689d599 100644 --- a/src/cairo_png_surface.c +++ b/src/cairo_png_surface.c @@ -1,3 +1,40 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2004 University of Southern California + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Olivier Andrieu + * Carl D. Worth + */ + #include #include "cairoint.h" diff --git a/src/cairo_polygon.c b/src/cairo_polygon.c index 8fc1f3097..8fa32f9f6 100644 --- a/src/cairo_polygon.c +++ b/src/cairo_polygon.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo_ps_surface.c b/src/cairo_ps_surface.c index 9b3096b0f..bfdfada38 100644 --- a/src/cairo_ps_surface.c +++ b/src/cairo_ps_surface.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2003 University of Southern California + * Copyright © 2003 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo_slope.c b/src/cairo_slope.c index 484cd86fd..1a1497988 100644 --- a/src/cairo_slope.c +++ b/src/cairo_slope.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo_spline.c b/src/cairo_spline.c index f3c21726d..bed351ef4 100644 --- a/src/cairo_spline.c +++ b/src/cairo_spline.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo_surface.c b/src/cairo_surface.c index e5cf7aa9d..a457d2062 100644 --- a/src/cairo_surface.c +++ b/src/cairo_surface.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo_traps.c b/src/cairo_traps.c index 1dc6e3df2..8f8d035c1 100644 --- a/src/cairo_traps.c +++ b/src/cairo_traps.c @@ -1,5 +1,5 @@ /* - * Copyright © 2002 Keith Packard + * Copyright © 2002 Keith Packard * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo_xcb_surface.c b/src/cairo_xcb_surface.c index bc37d2047..21760d764 100644 --- a/src/cairo_xcb_surface.c +++ b/src/cairo_xcb_surface.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairo_xlib_surface.c b/src/cairo_xlib_surface.c index 43491a904..dda7995bd 100644 --- a/src/cairo_xlib_surface.c +++ b/src/cairo_xlib_surface.c @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public diff --git a/src/cairoint.h b/src/cairoint.h index ffaecf9d3..be0e54e78 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -1,6 +1,6 @@ /* cairo - a vector graphics library with display and print output * - * Copyright © 2002 University of Southern California + * Copyright © 2002 University of Southern California * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public -- cgit v1.2.1 From f8e632ab1e0673cecd2ea68b3c0e6747b74d7cd6 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 26 Oct 2004 14:38:43 +0000 Subject: Add initial regression test suite. Don't AC_SUBST a dozen different FOO_CFLAGS and FOO_LIBS. Instead, incrementally build up just CAIRO_CFLAGS and CAIRO_LIBS. Don't list flags that should get picked up via dependency information through Requires. Add description of move_to_show_surface. --- BUGS | 11 +++ ChangeLog | 27 ++++++ Makefile.am | 2 +- cairo.pc.in | 2 +- configure.in | 41 +++++--- src/Makefile.am | 4 +- test/.cvsignore | 10 ++ test/Makefile.am | 29 ++++++ test/README | 55 +++++++++++ test/cairo-test.c | 191 ++++++++++++++++++++++++++++++++++++++ test/cairo-test.h | 50 ++++++++++ test/cairo_test.c | 191 ++++++++++++++++++++++++++++++++++++++ test/cairo_test.h | 50 ++++++++++ test/line-width-ref.png | Bin 0 -> 167 bytes test/line-width.c | 63 +++++++++++++ test/line_width-ref.png | Bin 0 -> 167 bytes test/line_width.c | 63 +++++++++++++ test/move-to-show-surface-ref.png | Bin 0 -> 100 bytes test/move-to-show-surface.c | 69 ++++++++++++++ test/move_to_show_surface-ref.png | Bin 0 -> 100 bytes test/move_to_show_surface.c | 69 ++++++++++++++ test/read-png.c | 166 +++++++++++++++++++++++++++++++++ test/read-png.h | 45 +++++++++ test/read_png.c | 166 +++++++++++++++++++++++++++++++++ test/read_png.h | 45 +++++++++ test/write-png.c | 102 ++++++++++++++++++++ test/write-png.h | 35 +++++++ test/write_png.c | 102 ++++++++++++++++++++ test/write_png.h | 35 +++++++ test/xmalloc.c | 58 ++++++++++++ test/xmalloc.h | 35 +++++++ 31 files changed, 1698 insertions(+), 18 deletions(-) create mode 100644 test/.cvsignore create mode 100644 test/Makefile.am create mode 100644 test/README create mode 100644 test/cairo-test.c create mode 100644 test/cairo-test.h create mode 100644 test/cairo_test.c create mode 100644 test/cairo_test.h create mode 100644 test/line-width-ref.png create mode 100644 test/line-width.c create mode 100644 test/line_width-ref.png create mode 100644 test/line_width.c create mode 100644 test/move-to-show-surface-ref.png create mode 100644 test/move-to-show-surface.c create mode 100644 test/move_to_show_surface-ref.png create mode 100644 test/move_to_show_surface.c create mode 100644 test/read-png.c create mode 100644 test/read-png.h create mode 100644 test/read_png.c create mode 100644 test/read_png.h create mode 100644 test/write-png.c create mode 100644 test/write-png.h create mode 100644 test/write_png.c create mode 100644 test/write_png.h create mode 100644 test/xmalloc.c create mode 100644 test/xmalloc.h diff --git a/BUGS b/BUGS index 8d24b3d74..31690e6cc 100644 --- a/BUGS +++ b/BUGS @@ -81,3 +81,14 @@ libpixman, (nor in glitz?). -- font-size="0" in an SVG file does very bad things. + +-- + +move_to_show_surface (see cairo/test): + + * 2004-10-25 Carl Worth + * + * It looks like cairo_show_surface has no effect if it follows a + * call to cairo_move_to to any coordinate other than 0,0. A little + * bit of poking around suggests this isn't a regression, (at least + * not since the last pixman snapshot). diff --git a/ChangeLog b/ChangeLog index a22b8f3f8..0e15f0100 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +2004-10-26 Carl Worth + + * test/.cvsignore: + * test/Makefile.am: + * test/README: + * test/cairo_test.c: + * test/cairo_test.h: + * test/line_width-ref.png: + * test/line_width.c: + * test/move_to_show_surface-ref.png: + * test/move_to_show_surface.c: + * test/read_png.c: + * test/read_png.h: + * test/write_png.c: + * test/write_png.h: + * test/xmalloc.c: + * test/xmalloc.h: Add initial regression test suite. + + * configure.in: Don't AC_SUBST a dozen different FOO_CFLAGS and + FOO_LIBS. Instead, incrementally build up just CAIRO_CFLAGS and + CAIRO_LIBS. + + * cairo.pc.in (Libs): Don't list flags that should get picked up + via dependency information through Requires. + + * BUGS (font-size): Add description of move_to_show_surface. + 2004-10-21 Carl Worth * src/cairo_png_surface.c: diff --git a/Makefile.am b/Makefile.am index aed2d88af..624ec1334 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = src +SUBDIRS = src test EXTRA_DIST = \ COPYING \ diff --git a/cairo.pc.in b/cairo.pc.in index b2859b24b..339d576b2 100644 --- a/cairo.pc.in +++ b/cairo.pc.in @@ -8,6 +8,6 @@ Description: Multi-platform 2D graphics library Version: @VERSION@ Requires: fontconfig libpixman @XRENDER_REQUIRES@ @PNG_REQUIRES@ @GLITZ_REQUIRES@ -Libs: -L${libdir} -lcairo -lm @XRENDER_LIBS@ @PS_LIBS@ @FREETYPE_LIBS@ +Libs: -L${libdir} -lcairo -lm Cflags: -I${includedir} @FREETYPE_CFLAGS@ diff --git a/configure.in b/configure.in index 3415b12f4..ebe259a19 100644 --- a/configure.in +++ b/configure.in @@ -60,9 +60,10 @@ else AM_CONDITIONAL(CAIRO_HAS_XLIB_SURFACE, true) fi +CAIRO_CFLAGS="$CAIRO_CFLAGS $XRENDER_CFLAGS" +CAIRO_LIBS="$CAIRO_LIBS $XRENDER_LIBS" + AC_SUBST(XLIB_SURFACE_FEATURE) -AC_SUBST(XRENDER_CFLAGS) -AC_SUBST(XRENDER_LIBS) AC_SUBST(XRENDER_REQUIRES) dnl =========================================================================== @@ -84,9 +85,10 @@ else AM_CONDITIONAL(CAIRO_HAS_XCB_SURFACE, true) fi +CAIRO_CFLAGS="$CAIRO_CFLAGS $XCB_CFLAGS" +CAIRO_LIBS="$CAIRO_LIBS $XCB_LIBS" + AC_SUBST(XCB_SURFACE_FEATURE) -AC_SUBST(XCB_CFLAGS) -AC_SUBST(XCB_LIBS) dnl =========================================================================== @@ -103,6 +105,8 @@ else AM_CONDITIONAL(CAIRO_HAS_PS_SURFACE, true) fi +CAIRO_LIBS="$CAIRO_LIBS $PS_LIBS" + AC_SUBST(PS_SURFACE_FEATURE) AC_SUBST(PS_LIBS) @@ -129,9 +133,10 @@ else AM_CONDITIONAL(CAIRO_HAS_PNG_SURFACE, true) fi +CAIRO_CFLAGS="$CAIRO_CFLAGS $PNG_CFLAGS" +CAIRO_LIBS="$CAIRO_LIBS $PNG_LIBS" + AC_SUBST(PNG_SURFACE_FEATURE) -AC_SUBST(PNG_CFLAGS) -AC_SUBST(PNG_LIBS) AC_SUBST(PNG_REQUIRES) dnl =========================================================================== @@ -154,8 +159,9 @@ else AM_CONDITIONAL(CAIRO_HAS_GLITZ_SURFACE, true) fi -AC_SUBST(GLITZ_LIBS) -AC_SUBST(GLITZ_CFLAGS) +CAIRO_CFLAGS="$CAIRO_CFLAGS $GLITZ_CFLAGS" +CAIRO_LIBS="$CAIRO_LIBS $GLITZ_LIBS" + AC_SUBST(GLITZ_SURFACE_FEATURE) AC_SUBST(GLITZ_REQUIRES) @@ -176,7 +182,12 @@ AC_SUBST(SANITY_CHECKING_FEATURE) dnl =========================================================================== PKG_CHECK_MODULES(FONTCONFIG, fontconfig) -PKG_CHECK_MODULES(CAIRO, libpixman >= 0.1.1) +CAIRO_CFLAGS="$CAIRO_CFLAGS $FONTCONFIG_CFLAGS" +CAIRO_LIBS="$CAIRO_LIBS $FONTCONFIG_LIBS" + +PKG_CHECK_MODULES(PIXMAN, libpixman >= 0.1.1) +CAIRO_CFLAGS="$CAIRO_CFLAGS $PIXMAN_CFLAGS" +CAIRO_LIBS="$CAIRO_LIBS $PIXMAN_LIBS" # Test for freetype2 separate from pkg-config since at least up to # 2003-06-07, there was no freetype2.pc in the release. @@ -218,13 +229,9 @@ FREETYPE_LIBS=`$FREETYPE_CONFIG --libs` AC_SUBST(FREETYPE_CFLAGS) AC_SUBST(FREETYPE_LIBS) - CAIRO_CFLAGS="$CAIRO_CFLAGS $FREETYPE_CFLAGS" CAIRO_LIBS="$CAIRO_LIBS $FREETYPE_LIBS" -AC_SUBST(CAIRO_CFLAGS) -AC_SUBST(CAIRO_LIBS) - dnl =========================================================================== dnl Checks for precise integer types @@ -239,7 +246,12 @@ if test "x$GCC" = "xyes"; then -Wmissing-prototypes -Wmissing-declarations \ -Wnested-externs -fno-strict-aliasing" fi -AC_SUBST(WARN_CFLAGS) + +CAIRO_CFLAGS="$CAIRO_CFLAGS $WARN_CFLAGS" +CAIRO_LIBS = "$CAIRO_LIBS -lm" + +AC_SUBST(CAIRO_CFLAGS) +AC_SUBST(CAIRO_LIBS) dnl =========================================================================== @@ -248,6 +260,7 @@ cairo.pc Makefile src/Makefile src/cairo-features.h +test/Makefile ]) dnl =========================================================================== diff --git a/src/Makefile.am b/src/Makefile.am index 8f5f639aa..8343cb1ce 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -62,6 +62,6 @@ libcairo_la_SOURCES = \ libcairo_la_LDFLAGS = -version-info @VERSION_INFO@ -no-undefined -INCLUDES = -I$(srcdir) $(WARN_CFLAGS) $(CAIRO_CFLAGS) $(FONTCONFIG_CFLAGS) $(XRENDER_CFLAGS) $(XCB_CFLAGS) $(PNG_CFLAGS) $(GLITZ_CFLAGS) +INCLUDES = -I$(srcdir) $(CAIRO_CFLAGS) -libcairo_la_LIBADD = $(CAIRO_LIBS) $(FONTCONFIG_LIBS) $(XRENDER_LIBS) $(XCB_LIBS) $(PS_LIBS) $(PNG_LIBS) $(GLITZ_LIBS) -lm +libcairo_la_LIBADD = $(CAIRO_LIBS) -lm diff --git a/test/.cvsignore b/test/.cvsignore new file mode 100644 index 000000000..1937368c3 --- /dev/null +++ b/test/.cvsignore @@ -0,0 +1,10 @@ +.deps +.libs +Makefile +Makefile.in +line_width +move_to_show_surface +*-out.png +*-diff.png + + diff --git a/test/Makefile.am b/test/Makefile.am new file mode 100644 index 000000000..132d4037e --- /dev/null +++ b/test/Makefile.am @@ -0,0 +1,29 @@ +TESTS = \ +line_width \ +move_to_show_surface + +# Known bugs (not regressions). We do need to fix these before the +# next release, but they are expected to fail for now, so they don't +# need to hold up any new code commit. +# +# When new bugs are found in committed code they can be listed +# here. New failures due to local, uncommitted code changes are +# regression bugs that should not be listed here. Instead they should +# be fixed before the code is committed. +XFAIL_TESTS = \ +move_to_show_surface + +check_PROGRAMS = $(TESTS) + +INCLUDES = -I$(srcdir) $(CAIRO_CFLAGS) -I$(srcdir)/../src + +AM_LDFLAGS = $(CAIRO_LIBS) -L../src -lcairo + +cairo_test_lib = cairo_test.c read_png.c write_png.c xmalloc.c + +line_width_SOURCES = line_width.c $(cairo_test_lib) +move_to_show_surface_SOURCES = move_to_show_surface.c $(cairo_test_lib) + + + + diff --git a/test/README b/test/README new file mode 100644 index 000000000..3e7acf5c2 --- /dev/null +++ b/test/README @@ -0,0 +1,55 @@ +Regression test suite for cairo. + +Using this test should be as simple as running: + + make check + +assuming that the cairo distribution in the directory above has been +configured and built. The test suite here goes through some effort to +run against the locally compiled library rather than any installed +version. + +The test suite needs to be run before any code is committed and before +any release. Here are the rules governing the use of the suite: + +Before committing +----------------- + +All tests should return a result of PASS or XFAIL. The XFAIL results +indicate known bugs. The final message should be one of the following: + + All XX tests behaved as expected (YY expected failures) + All XX tests passed + +If any tests have a status of FAIL, then the new code has caused a +regression error which should be fixed before the code is committed. + +When a new bug is found +----------------------- +A new test case should be added by imitating the style of an existing +test. This means adding the following files: + + new_bug.c + new_bug-ref.png + +Where new_bug.c is a minimal program to demonstrate the bug, following +the style of existing tests. The new_bug-ref.png image should contain +the desired result of new_bug.c if the bug were fixed. + +Makefile.am should be edited, adding new_bug.c to both the TESTS and +XFAIL_TESTS lists. + +When a bug is fixed +------------------- +The fix shold be verified by running the test suite which should +result in an "unexpected pass" for the test of interest. Rejoice as +appropriate, then remove the relevant file name from the XFAIL_TESTS +variable in Makefile.am. + +Before releasing +---------------- +All tests should return a result of PASS meaning all known bugs are +fixed, resulting in the happy message: + + All XX tests passed + diff --git a/test/cairo-test.c b/test/cairo-test.c new file mode 100644 index 000000000..0c2d09f3a --- /dev/null +++ b/test/cairo-test.c @@ -0,0 +1,191 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Red Hat, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Red Hat, Inc. makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Carl D. Worth + */ + +#include +#include + +#include "cairo_test.h" + +#include "read_png.h" +#include "write_png.h" +#include "xmalloc.h" + +#define CAIRO_TEST_PNG_SUFFIX "-out.png" +#define CAIRO_TEST_REF_SUFFIX "-ref.png" +#define CAIRO_TEST_DIFF_SUFFIX "-diff.png" + +static char * +xstrcat_alloc (const char *s1, const char *s2) +{ + char *ret; + + ret = xmalloc (strlen (s1) + strlen (s2) + 1); + strcpy (ret, s1); + strcat (ret, s2); + + return ret; +} + +/* Image comparison code courttesy of Richard Worth. + * Returns number of pixels changed. + * Also fills out a "diff" image intended to visually show where the + * images differ. + */ +static int +image_diff (char *buf_a, char *buf_b, char *buf_diff, + int width, int height, int stride) +{ + int x, y; + int total_pixels_changed = 0; + unsigned char *row_a, *row_b, *row; + + for (y = 0; y < height; y++) + { + row_a = buf_a + y * stride; + row_b = buf_b + y * stride; + row = buf_diff + y * stride; + for (x = 0; x < width; x++) + { + int channel; + unsigned char value_a, value_b; + int pixel_changed = 0; + for (channel = 0; channel < 4; channel++) + { + double diff; + value_a = row_a[x * 4 + channel]; + value_b = row_b[x * 4 + channel]; + if (value_a != value_b) + pixel_changed = 1; + diff = value_a - value_b; + row[x * 4 + channel] = 128 + diff / 3.0; + } + if (pixel_changed) { + total_pixels_changed++; + } else { + row[x*4+0] = 0; + row[x*4+1] = 0; + row[x*4+2] = 0; + } + row[x * 4 + 3] = 0xff; /* Set ALPHA to 100% (opaque) */ + } + } + + return total_pixels_changed; +} + +cairo_test_status_t +cairo_test (cairo_test_t *test, cairo_test_draw_function_t draw) +{ + cairo_t *cr; + int stride; + unsigned char *png_buf, *ref_buf, *diff_buf; + char *png_name, *ref_name, *diff_name; + int pixels_changed; + int ref_width, ref_height, ref_stride; + read_png_status_t png_status; + cairo_test_status_t ret; + + /* The cairo part of the test is the easiest part */ + cr = cairo_create (); + + stride = 4 * test->width; + + png_buf = xcalloc (stride * test->height, 1); + diff_buf = xcalloc (stride * test->height, 1); + + cairo_set_target_image (cr, png_buf, CAIRO_FORMAT_ARGB32, + test->width, test->height, stride); + + (draw) (cr, test->width, test->height); + + cairo_destroy (cr); + + /* Then we've got a bunch of string manipulation and file I/O for the check */ + + png_name = xstrcat_alloc (test->name, CAIRO_TEST_PNG_SUFFIX); + ref_name = xstrcat_alloc (test->name, CAIRO_TEST_REF_SUFFIX); + diff_name = xstrcat_alloc (test->name, CAIRO_TEST_DIFF_SUFFIX); + + write_png_argb32 (png_buf, png_name, test->width, test->height, stride); + + ref_buf = NULL; + png_status = (read_png_argb32 (ref_name, &ref_buf, &ref_width, &ref_height, &ref_stride)); + if (png_status) { + switch (png_status) + { + case READ_PNG_FILE_NOT_FOUND: + fprintf (stderr, " Error: No reference image found: %s\n", ref_name); + break; + case READ_PNG_FILE_NOT_PNG: + fprintf (stderr, " Error: %s is not a png image\n", ref_name); + break; + default: + fprintf (stderr, " Error: Failed to read %s\n", ref_name); + } + + ret = CAIRO_TEST_FAILURE; + goto BAIL; + } + + if (test->width != ref_width || test->height != ref_height) { + fprintf (stderr, + " Error: Image size mismatch: (%dx%d) vs. (%dx%d)\n" + " for %s vs %s\n", + test->width, test->height, + ref_width, ref_height, + png_name, ref_name); + ret = CAIRO_TEST_FAILURE; + goto BAIL; + } + + pixels_changed = image_diff (png_buf, ref_buf, diff_buf, + test->width, test->height, stride); + if (pixels_changed) { + fprintf (stderr, " Error: %d pixels differ from reference image %s\n", + pixels_changed, ref_name); + write_png_argb32 (diff_buf, diff_name, test->width, test->height, stride); + ret = CAIRO_TEST_FAILURE; + goto BAIL; + } else { + if (unlink (diff_name) < 0 && errno != ENOENT) { + fprintf (stderr, " Error: Cannot remove %s: %s\n", + diff_name, strerror (errno)); + ret = CAIRO_TEST_FAILURE; + goto BAIL; + } + } + + ret = CAIRO_TEST_SUCCESS; + +BAIL: + free (png_buf); + free (ref_buf); + free (diff_buf); + free (png_name); + free (ref_name); + free (diff_name); + + return ret; +} diff --git a/test/cairo-test.h b/test/cairo-test.h new file mode 100644 index 000000000..7062f029d --- /dev/null +++ b/test/cairo-test.h @@ -0,0 +1,50 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Red Hat, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Red Hat, Inc. makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Carl D. Worth + */ + +#ifndef _CAIRO_TEST_H_ +#define _CAIRO_TEST_H_ + +#include + +typedef enum cairo_test_status { + CAIRO_TEST_SUCCESS = 0, + CAIRO_TEST_FAILURE +} cairo_test_status_t; + +typedef struct cairo_test { + char *name; + char *description; + int width; + int height; +} cairo_test_t; + +typedef void (*cairo_test_draw_function_t) (cairo_t *cr, int width, int height); + +/* cairo_test.c */ +cairo_test_status_t +cairo_test (cairo_test_t *test, cairo_test_draw_function_t draw); + +#endif + diff --git a/test/cairo_test.c b/test/cairo_test.c new file mode 100644 index 000000000..0c2d09f3a --- /dev/null +++ b/test/cairo_test.c @@ -0,0 +1,191 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Red Hat, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Red Hat, Inc. makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Carl D. Worth + */ + +#include +#include + +#include "cairo_test.h" + +#include "read_png.h" +#include "write_png.h" +#include "xmalloc.h" + +#define CAIRO_TEST_PNG_SUFFIX "-out.png" +#define CAIRO_TEST_REF_SUFFIX "-ref.png" +#define CAIRO_TEST_DIFF_SUFFIX "-diff.png" + +static char * +xstrcat_alloc (const char *s1, const char *s2) +{ + char *ret; + + ret = xmalloc (strlen (s1) + strlen (s2) + 1); + strcpy (ret, s1); + strcat (ret, s2); + + return ret; +} + +/* Image comparison code courttesy of Richard Worth. + * Returns number of pixels changed. + * Also fills out a "diff" image intended to visually show where the + * images differ. + */ +static int +image_diff (char *buf_a, char *buf_b, char *buf_diff, + int width, int height, int stride) +{ + int x, y; + int total_pixels_changed = 0; + unsigned char *row_a, *row_b, *row; + + for (y = 0; y < height; y++) + { + row_a = buf_a + y * stride; + row_b = buf_b + y * stride; + row = buf_diff + y * stride; + for (x = 0; x < width; x++) + { + int channel; + unsigned char value_a, value_b; + int pixel_changed = 0; + for (channel = 0; channel < 4; channel++) + { + double diff; + value_a = row_a[x * 4 + channel]; + value_b = row_b[x * 4 + channel]; + if (value_a != value_b) + pixel_changed = 1; + diff = value_a - value_b; + row[x * 4 + channel] = 128 + diff / 3.0; + } + if (pixel_changed) { + total_pixels_changed++; + } else { + row[x*4+0] = 0; + row[x*4+1] = 0; + row[x*4+2] = 0; + } + row[x * 4 + 3] = 0xff; /* Set ALPHA to 100% (opaque) */ + } + } + + return total_pixels_changed; +} + +cairo_test_status_t +cairo_test (cairo_test_t *test, cairo_test_draw_function_t draw) +{ + cairo_t *cr; + int stride; + unsigned char *png_buf, *ref_buf, *diff_buf; + char *png_name, *ref_name, *diff_name; + int pixels_changed; + int ref_width, ref_height, ref_stride; + read_png_status_t png_status; + cairo_test_status_t ret; + + /* The cairo part of the test is the easiest part */ + cr = cairo_create (); + + stride = 4 * test->width; + + png_buf = xcalloc (stride * test->height, 1); + diff_buf = xcalloc (stride * test->height, 1); + + cairo_set_target_image (cr, png_buf, CAIRO_FORMAT_ARGB32, + test->width, test->height, stride); + + (draw) (cr, test->width, test->height); + + cairo_destroy (cr); + + /* Then we've got a bunch of string manipulation and file I/O for the check */ + + png_name = xstrcat_alloc (test->name, CAIRO_TEST_PNG_SUFFIX); + ref_name = xstrcat_alloc (test->name, CAIRO_TEST_REF_SUFFIX); + diff_name = xstrcat_alloc (test->name, CAIRO_TEST_DIFF_SUFFIX); + + write_png_argb32 (png_buf, png_name, test->width, test->height, stride); + + ref_buf = NULL; + png_status = (read_png_argb32 (ref_name, &ref_buf, &ref_width, &ref_height, &ref_stride)); + if (png_status) { + switch (png_status) + { + case READ_PNG_FILE_NOT_FOUND: + fprintf (stderr, " Error: No reference image found: %s\n", ref_name); + break; + case READ_PNG_FILE_NOT_PNG: + fprintf (stderr, " Error: %s is not a png image\n", ref_name); + break; + default: + fprintf (stderr, " Error: Failed to read %s\n", ref_name); + } + + ret = CAIRO_TEST_FAILURE; + goto BAIL; + } + + if (test->width != ref_width || test->height != ref_height) { + fprintf (stderr, + " Error: Image size mismatch: (%dx%d) vs. (%dx%d)\n" + " for %s vs %s\n", + test->width, test->height, + ref_width, ref_height, + png_name, ref_name); + ret = CAIRO_TEST_FAILURE; + goto BAIL; + } + + pixels_changed = image_diff (png_buf, ref_buf, diff_buf, + test->width, test->height, stride); + if (pixels_changed) { + fprintf (stderr, " Error: %d pixels differ from reference image %s\n", + pixels_changed, ref_name); + write_png_argb32 (diff_buf, diff_name, test->width, test->height, stride); + ret = CAIRO_TEST_FAILURE; + goto BAIL; + } else { + if (unlink (diff_name) < 0 && errno != ENOENT) { + fprintf (stderr, " Error: Cannot remove %s: %s\n", + diff_name, strerror (errno)); + ret = CAIRO_TEST_FAILURE; + goto BAIL; + } + } + + ret = CAIRO_TEST_SUCCESS; + +BAIL: + free (png_buf); + free (ref_buf); + free (diff_buf); + free (png_name); + free (ref_name); + free (diff_name); + + return ret; +} diff --git a/test/cairo_test.h b/test/cairo_test.h new file mode 100644 index 000000000..7062f029d --- /dev/null +++ b/test/cairo_test.h @@ -0,0 +1,50 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Red Hat, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Red Hat, Inc. makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Carl D. Worth + */ + +#ifndef _CAIRO_TEST_H_ +#define _CAIRO_TEST_H_ + +#include + +typedef enum cairo_test_status { + CAIRO_TEST_SUCCESS = 0, + CAIRO_TEST_FAILURE +} cairo_test_status_t; + +typedef struct cairo_test { + char *name; + char *description; + int width; + int height; +} cairo_test_t; + +typedef void (*cairo_test_draw_function_t) (cairo_t *cr, int width, int height); + +/* cairo_test.c */ +cairo_test_status_t +cairo_test (cairo_test_t *test, cairo_test_draw_function_t draw); + +#endif + diff --git a/test/line-width-ref.png b/test/line-width-ref.png new file mode 100644 index 000000000..1490b1b42 Binary files /dev/null and b/test/line-width-ref.png differ diff --git a/test/line-width.c b/test/line-width.c new file mode 100644 index 000000000..9c3ed89b9 --- /dev/null +++ b/test/line-width.c @@ -0,0 +1,63 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Red Hat, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Red Hat, Inc. makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Carl D. Worth + */ + +#include "cairo_test.h" + +#define LINES 5 +#define LINE_LENGTH 10 +#define IMAGE_WIDTH 2 * LINE_LENGTH + 6 +#define IMAGE_HEIGHT ((LINES+4)*LINES)/2 + 2 + +cairo_test_t test = { + "line_width", + "Tests cairo_set_line_width", + IMAGE_WIDTH, IMAGE_HEIGHT +}; + +static void +draw (cairo_t *cr, int width, int height) +{ + int i; + + cairo_set_rgb_color (cr, 0, 0, 0); + cairo_translate (cr, 2, 2); + + for (i=0; i < LINES; i++) { + cairo_set_line_width (cr, i+1); + cairo_move_to (cr, 0, 0); + cairo_rel_line_to (cr, LINE_LENGTH, 0); + cairo_stroke (cr); + cairo_move_to (cr, LINE_LENGTH + 2, 0.5); + cairo_rel_line_to (cr, LINE_LENGTH, 0); + cairo_stroke (cr); + cairo_translate (cr, 0, i+3); + } +} + +int +main (void) +{ + return cairo_test (&test, draw); +} diff --git a/test/line_width-ref.png b/test/line_width-ref.png new file mode 100644 index 000000000..1490b1b42 Binary files /dev/null and b/test/line_width-ref.png differ diff --git a/test/line_width.c b/test/line_width.c new file mode 100644 index 000000000..9c3ed89b9 --- /dev/null +++ b/test/line_width.c @@ -0,0 +1,63 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Red Hat, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Red Hat, Inc. makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Carl D. Worth + */ + +#include "cairo_test.h" + +#define LINES 5 +#define LINE_LENGTH 10 +#define IMAGE_WIDTH 2 * LINE_LENGTH + 6 +#define IMAGE_HEIGHT ((LINES+4)*LINES)/2 + 2 + +cairo_test_t test = { + "line_width", + "Tests cairo_set_line_width", + IMAGE_WIDTH, IMAGE_HEIGHT +}; + +static void +draw (cairo_t *cr, int width, int height) +{ + int i; + + cairo_set_rgb_color (cr, 0, 0, 0); + cairo_translate (cr, 2, 2); + + for (i=0; i < LINES; i++) { + cairo_set_line_width (cr, i+1); + cairo_move_to (cr, 0, 0); + cairo_rel_line_to (cr, LINE_LENGTH, 0); + cairo_stroke (cr); + cairo_move_to (cr, LINE_LENGTH + 2, 0.5); + cairo_rel_line_to (cr, LINE_LENGTH, 0); + cairo_stroke (cr); + cairo_translate (cr, 0, i+3); + } +} + +int +main (void) +{ + return cairo_test (&test, draw); +} diff --git a/test/move-to-show-surface-ref.png b/test/move-to-show-surface-ref.png new file mode 100644 index 000000000..765adc4a4 Binary files /dev/null and b/test/move-to-show-surface-ref.png differ diff --git a/test/move-to-show-surface.c b/test/move-to-show-surface.c new file mode 100644 index 000000000..6dcda2103 --- /dev/null +++ b/test/move-to-show-surface.c @@ -0,0 +1,69 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Red Hat, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Red Hat, Inc. makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Carl D. Worth + */ + +/* Bug history + * + * 2004-10-25 Carl Worth + * + * It looks like cairo_show_surface has no effect if it follows a + * call to cairo_move_to to any coordinate other than 0,0. A little + * bit of poking around suggests this isn't a regression, (at least + * not since the last pixman snapshot). + * + */ + + +#include "cairo_test.h" + +cairo_test_t test = { + "move_to_show_surface", + "Tests calls to cairo_show_surface after cairo_move_to", + 2, 2 +}; + +static void +draw (cairo_t *cr, int width, int height) +{ + cairo_surface_t *surface; + uint32_t colors[4] = { + 0xffffffff, 0xffff0000, + 0xff00ff00, 0xff0000ff + }; + int i; + + for (i=0; i < 4; i++) { + surface = cairo_surface_create_for_image ((char *) &colors[i], + CAIRO_FORMAT_ARGB32, 1, 1, 4); + cairo_move_to (cr, i % 2, i / 2); + cairo_show_surface (cr, surface, 1, 1); + cairo_surface_destroy (surface); + } +} + +int +main (void) +{ + return cairo_test (&test, draw); +} diff --git a/test/move_to_show_surface-ref.png b/test/move_to_show_surface-ref.png new file mode 100644 index 000000000..765adc4a4 Binary files /dev/null and b/test/move_to_show_surface-ref.png differ diff --git a/test/move_to_show_surface.c b/test/move_to_show_surface.c new file mode 100644 index 000000000..6dcda2103 --- /dev/null +++ b/test/move_to_show_surface.c @@ -0,0 +1,69 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Red Hat, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Red Hat, Inc. makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Carl D. Worth + */ + +/* Bug history + * + * 2004-10-25 Carl Worth + * + * It looks like cairo_show_surface has no effect if it follows a + * call to cairo_move_to to any coordinate other than 0,0. A little + * bit of poking around suggests this isn't a regression, (at least + * not since the last pixman snapshot). + * + */ + + +#include "cairo_test.h" + +cairo_test_t test = { + "move_to_show_surface", + "Tests calls to cairo_show_surface after cairo_move_to", + 2, 2 +}; + +static void +draw (cairo_t *cr, int width, int height) +{ + cairo_surface_t *surface; + uint32_t colors[4] = { + 0xffffffff, 0xffff0000, + 0xff00ff00, 0xff0000ff + }; + int i; + + for (i=0; i < 4; i++) { + surface = cairo_surface_create_for_image ((char *) &colors[i], + CAIRO_FORMAT_ARGB32, 1, 1, 4); + cairo_move_to (cr, i % 2, i / 2); + cairo_show_surface (cr, surface, 1, 1); + cairo_surface_destroy (surface); + } +} + +int +main (void) +{ + return cairo_test (&test, draw); +} diff --git a/test/read-png.c b/test/read-png.c new file mode 100644 index 000000000..23f91e831 --- /dev/null +++ b/test/read-png.c @@ -0,0 +1,166 @@ +/* + * Copyright © 2003 USC, Information Sciences Institute + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * University of Southern California not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. The University of Southern + * California makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF + * SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Carl D. Worth + */ + +#include +#include +#include + +#include "read_png.h" +#include "xmalloc.h" + +static void +premultiply_data (png_structp png, + png_row_infop row_info, + png_bytep data) +{ + int i; + + for (i = 0; i < row_info->rowbytes; i += 4) { + unsigned char *base = &data[i]; + unsigned char blue = base[0]; + unsigned char green = base[1]; + unsigned char red = base[2]; + unsigned char alpha = base[3]; + unsigned long p; + + red = (unsigned) red * (unsigned) alpha / 255; + green = (unsigned) green * (unsigned) alpha / 255; + blue = (unsigned) blue * (unsigned) alpha / 255; + p = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0); + memcpy (base, &p, sizeof (unsigned long)); + } +} + +read_png_status_t +read_png_argb32 (const char *filename, + unsigned char **data, + unsigned int *width, + unsigned int *height, + unsigned int *stride) +{ + int i; + FILE *file; + static const int PNG_SIG_SIZE = 8; + unsigned char png_sig[PNG_SIG_SIZE]; + int sig_bytes; + png_struct *png; + png_info *info; + png_uint_32 png_width, png_height; + int depth, color_type, interlace; + unsigned int pixel_size; + png_byte **row_pointers; + + file = fopen (filename, "rb"); + if (file == NULL) { + return READ_PNG_FILE_NOT_FOUND; + } + + sig_bytes = fread (png_sig, 1, PNG_SIG_SIZE, file); + if (png_check_sig (png_sig, sig_bytes) == 0) { + fclose (file); + return READ_PNG_FILE_NOT_PNG; + } + + /* XXX: Perhaps we'll want some other error handlers? */ + png = png_create_read_struct (PNG_LIBPNG_VER_STRING, + NULL, + NULL, + NULL); + if (png == NULL) { + fclose (file); + return READ_PNG_NO_MEMORY; + } + + info = png_create_info_struct (png); + if (info == NULL) { + fclose (file); + png_destroy_read_struct (&png, NULL, NULL); + return READ_PNG_NO_MEMORY; + } + + png_init_io (png, file); + png_set_sig_bytes (png, sig_bytes); + + png_read_info (png, info); + + png_get_IHDR (png, info, + &png_width, &png_height, &depth, + &color_type, &interlace, NULL, NULL); + *width = png_width; + *height = png_height; + *stride = 4 * png_width; + + + /* convert palette/gray image to rgb */ + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb (png); + + /* expand gray bit depth if needed */ + if (color_type == PNG_COLOR_TYPE_GRAY && depth < 8) + png_set_gray_1_2_4_to_8 (png); + /* transform transparency to alpha */ + if (png_get_valid(png, info, PNG_INFO_tRNS)) + png_set_tRNS_to_alpha (png); + + if (depth == 16) + png_set_strip_16 (png); + + if (depth < 8) + png_set_packing (png); + + /* convert grayscale to RGB */ + if (color_type == PNG_COLOR_TYPE_GRAY + || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb (png); + + if (interlace != PNG_INTERLACE_NONE) + png_set_interlace_handling (png); + + png_set_bgr (png); + png_set_filler (png, 0xff, PNG_FILLER_AFTER); + + png_set_read_user_transform_fn (png, premultiply_data); + + png_read_update_info (png, info); + + pixel_size = 4; + *data = xmalloc (png_width * png_height * pixel_size); + + row_pointers = malloc (png_height * sizeof(char *)); + for (i=0; i < png_height; i++) + row_pointers[i] = (png_byte *) (*data + i * png_width * pixel_size); + + png_read_image (png, row_pointers); + png_read_end (png, info); + + free (row_pointers); + fclose (file); + + png_destroy_read_struct (&png, &info, NULL); + + return READ_PNG_SUCCESS; +} diff --git a/test/read-png.h b/test/read-png.h new file mode 100644 index 000000000..9c9ba433d --- /dev/null +++ b/test/read-png.h @@ -0,0 +1,45 @@ +/* + * Copyright © 2003 USC, Information Sciences Institute + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * University of Southern California not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. The University of Southern + * California makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF + * SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Carl D. Worth + */ + +#ifndef READ_PNG_H +#define READ_PNG_H + +typedef enum { + READ_PNG_SUCCESS = 0, + READ_PNG_FILE_NOT_FOUND, + READ_PNG_FILE_NOT_PNG, + READ_PNG_NO_MEMORY +} read_png_status_t; + +read_png_status_t +read_png_argb32 (const char *filename, + unsigned char **data, + unsigned int *width, + unsigned int *height, + unsigned int *stride); + +#endif diff --git a/test/read_png.c b/test/read_png.c new file mode 100644 index 000000000..23f91e831 --- /dev/null +++ b/test/read_png.c @@ -0,0 +1,166 @@ +/* + * Copyright © 2003 USC, Information Sciences Institute + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * University of Southern California not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. The University of Southern + * California makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF + * SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Carl D. Worth + */ + +#include +#include +#include + +#include "read_png.h" +#include "xmalloc.h" + +static void +premultiply_data (png_structp png, + png_row_infop row_info, + png_bytep data) +{ + int i; + + for (i = 0; i < row_info->rowbytes; i += 4) { + unsigned char *base = &data[i]; + unsigned char blue = base[0]; + unsigned char green = base[1]; + unsigned char red = base[2]; + unsigned char alpha = base[3]; + unsigned long p; + + red = (unsigned) red * (unsigned) alpha / 255; + green = (unsigned) green * (unsigned) alpha / 255; + blue = (unsigned) blue * (unsigned) alpha / 255; + p = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0); + memcpy (base, &p, sizeof (unsigned long)); + } +} + +read_png_status_t +read_png_argb32 (const char *filename, + unsigned char **data, + unsigned int *width, + unsigned int *height, + unsigned int *stride) +{ + int i; + FILE *file; + static const int PNG_SIG_SIZE = 8; + unsigned char png_sig[PNG_SIG_SIZE]; + int sig_bytes; + png_struct *png; + png_info *info; + png_uint_32 png_width, png_height; + int depth, color_type, interlace; + unsigned int pixel_size; + png_byte **row_pointers; + + file = fopen (filename, "rb"); + if (file == NULL) { + return READ_PNG_FILE_NOT_FOUND; + } + + sig_bytes = fread (png_sig, 1, PNG_SIG_SIZE, file); + if (png_check_sig (png_sig, sig_bytes) == 0) { + fclose (file); + return READ_PNG_FILE_NOT_PNG; + } + + /* XXX: Perhaps we'll want some other error handlers? */ + png = png_create_read_struct (PNG_LIBPNG_VER_STRING, + NULL, + NULL, + NULL); + if (png == NULL) { + fclose (file); + return READ_PNG_NO_MEMORY; + } + + info = png_create_info_struct (png); + if (info == NULL) { + fclose (file); + png_destroy_read_struct (&png, NULL, NULL); + return READ_PNG_NO_MEMORY; + } + + png_init_io (png, file); + png_set_sig_bytes (png, sig_bytes); + + png_read_info (png, info); + + png_get_IHDR (png, info, + &png_width, &png_height, &depth, + &color_type, &interlace, NULL, NULL); + *width = png_width; + *height = png_height; + *stride = 4 * png_width; + + + /* convert palette/gray image to rgb */ + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb (png); + + /* expand gray bit depth if needed */ + if (color_type == PNG_COLOR_TYPE_GRAY && depth < 8) + png_set_gray_1_2_4_to_8 (png); + /* transform transparency to alpha */ + if (png_get_valid(png, info, PNG_INFO_tRNS)) + png_set_tRNS_to_alpha (png); + + if (depth == 16) + png_set_strip_16 (png); + + if (depth < 8) + png_set_packing (png); + + /* convert grayscale to RGB */ + if (color_type == PNG_COLOR_TYPE_GRAY + || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb (png); + + if (interlace != PNG_INTERLACE_NONE) + png_set_interlace_handling (png); + + png_set_bgr (png); + png_set_filler (png, 0xff, PNG_FILLER_AFTER); + + png_set_read_user_transform_fn (png, premultiply_data); + + png_read_update_info (png, info); + + pixel_size = 4; + *data = xmalloc (png_width * png_height * pixel_size); + + row_pointers = malloc (png_height * sizeof(char *)); + for (i=0; i < png_height; i++) + row_pointers[i] = (png_byte *) (*data + i * png_width * pixel_size); + + png_read_image (png, row_pointers); + png_read_end (png, info); + + free (row_pointers); + fclose (file); + + png_destroy_read_struct (&png, &info, NULL); + + return READ_PNG_SUCCESS; +} diff --git a/test/read_png.h b/test/read_png.h new file mode 100644 index 000000000..9c9ba433d --- /dev/null +++ b/test/read_png.h @@ -0,0 +1,45 @@ +/* + * Copyright © 2003 USC, Information Sciences Institute + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * University of Southern California not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. The University of Southern + * California makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF + * SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Carl D. Worth + */ + +#ifndef READ_PNG_H +#define READ_PNG_H + +typedef enum { + READ_PNG_SUCCESS = 0, + READ_PNG_FILE_NOT_FOUND, + READ_PNG_FILE_NOT_PNG, + READ_PNG_NO_MEMORY +} read_png_status_t; + +read_png_status_t +read_png_argb32 (const char *filename, + unsigned char **data, + unsigned int *width, + unsigned int *height, + unsigned int *stride); + +#endif diff --git a/test/write-png.c b/test/write-png.c new file mode 100644 index 000000000..2ea29d062 --- /dev/null +++ b/test/write-png.c @@ -0,0 +1,102 @@ +/* + * Copyright © 2003 USC, Information Sciences Institute + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * University of Southern California not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. The University of Southern + * California makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF + * SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Carl D. Worth + */ + +#include +#include +#include + +#include "write_png.h" + +static void +unpremultiply_data (png_structp png, png_row_infop row_info, png_bytep data) +{ + int i; + + for (i = 0; i < row_info->rowbytes; i += 4) { + unsigned char *b = &data[i]; + unsigned int pixel; + unsigned char alpha; + + memcpy (&pixel, b, sizeof (unsigned int)); + alpha = (pixel & 0xff000000) >> 24; + if (alpha == 0) { + b[0] = b[1] = b[2] = b[3] = 0; + } else { + b[0] = (((pixel & 0x0000ff) >> 0) * 255) / alpha; + b[1] = (((pixel & 0x00ff00) >> 8) * 255) / alpha; + b[2] = (((pixel & 0xff0000) >> 16) * 255) / alpha; + b[3] = alpha; + } + } +} + +void +write_png_argb32 (char *buffer, char *filename, + int width, int height, int stride) +{ + FILE *f; + int i; + png_struct *png; + png_info *info; + png_byte **rows; + png_color_16 white; + + f = fopen (filename, "w"); + rows = malloc (height * sizeof(png_byte*)); + + for (i = 0; i < height; i++) { + rows[i] = buffer + i * stride; + } + + png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + info = png_create_info_struct (png); + + png_init_io (png, f); + png_set_IHDR (png, info, + width, height, 8, + PNG_COLOR_TYPE_RGB_ALPHA, + PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + + white.red = 0xff; + white.blue = 0xff; + white.green = 0xff; + png_set_bKGD (png, info, &white); + + png_set_write_user_transform_fn (png, unpremultiply_data); + png_set_bgr (png); + + png_write_info (png, info); + png_write_image (png, rows); + png_write_end (png, info); + + png_destroy_write_struct (&png, &info); + + free (rows); + fclose (f); +} diff --git a/test/write-png.h b/test/write-png.h new file mode 100644 index 000000000..a71ca6a32 --- /dev/null +++ b/test/write-png.h @@ -0,0 +1,35 @@ +/* + * Copyright © 2003 USC, Information Sciences Institute + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * University of Southern California not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. The University of Southern + * California makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF + * SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Carl D. Worth + */ + +#ifndef WRITE_PNG_H +#define WRITE_PNG_H + +void +write_png_argb32 (char *buffer, char *filename, + int width, int height, int stride); + +#endif diff --git a/test/write_png.c b/test/write_png.c new file mode 100644 index 000000000..2ea29d062 --- /dev/null +++ b/test/write_png.c @@ -0,0 +1,102 @@ +/* + * Copyright © 2003 USC, Information Sciences Institute + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * University of Southern California not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. The University of Southern + * California makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF + * SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Carl D. Worth + */ + +#include +#include +#include + +#include "write_png.h" + +static void +unpremultiply_data (png_structp png, png_row_infop row_info, png_bytep data) +{ + int i; + + for (i = 0; i < row_info->rowbytes; i += 4) { + unsigned char *b = &data[i]; + unsigned int pixel; + unsigned char alpha; + + memcpy (&pixel, b, sizeof (unsigned int)); + alpha = (pixel & 0xff000000) >> 24; + if (alpha == 0) { + b[0] = b[1] = b[2] = b[3] = 0; + } else { + b[0] = (((pixel & 0x0000ff) >> 0) * 255) / alpha; + b[1] = (((pixel & 0x00ff00) >> 8) * 255) / alpha; + b[2] = (((pixel & 0xff0000) >> 16) * 255) / alpha; + b[3] = alpha; + } + } +} + +void +write_png_argb32 (char *buffer, char *filename, + int width, int height, int stride) +{ + FILE *f; + int i; + png_struct *png; + png_info *info; + png_byte **rows; + png_color_16 white; + + f = fopen (filename, "w"); + rows = malloc (height * sizeof(png_byte*)); + + for (i = 0; i < height; i++) { + rows[i] = buffer + i * stride; + } + + png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + info = png_create_info_struct (png); + + png_init_io (png, f); + png_set_IHDR (png, info, + width, height, 8, + PNG_COLOR_TYPE_RGB_ALPHA, + PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + + white.red = 0xff; + white.blue = 0xff; + white.green = 0xff; + png_set_bKGD (png, info, &white); + + png_set_write_user_transform_fn (png, unpremultiply_data); + png_set_bgr (png); + + png_write_info (png, info); + png_write_image (png, rows); + png_write_end (png, info); + + png_destroy_write_struct (&png, &info); + + free (rows); + fclose (f); +} diff --git a/test/write_png.h b/test/write_png.h new file mode 100644 index 000000000..a71ca6a32 --- /dev/null +++ b/test/write_png.h @@ -0,0 +1,35 @@ +/* + * Copyright © 2003 USC, Information Sciences Institute + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * University of Southern California not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. The University of Southern + * California makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF + * SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Carl D. Worth + */ + +#ifndef WRITE_PNG_H +#define WRITE_PNG_H + +void +write_png_argb32 (char *buffer, char *filename, + int width, int height, int stride); + +#endif diff --git a/test/xmalloc.c b/test/xmalloc.c new file mode 100644 index 000000000..04ed38afa --- /dev/null +++ b/test/xmalloc.c @@ -0,0 +1,58 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Red Hat, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Red Hat, Inc. makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Carl D. Worth + */ + +#include +#include + +#include "xmalloc.h" + +void * +xmalloc (size_t size) +{ + void *buf; + + buf = malloc (size); + if (!buf) { + fprintf (stderr, "Error: Out of memory. Exiting.\n"); + exit (1); + } + + return buf; +} + +void * +xcalloc (size_t nmemb, size_t size) +{ + void *buf; + + buf = calloc (nmemb, size); + if (!buf) { + fprintf (stderr, "Error: Out of memory. Exiting\n"); + exit (1); + } + + return buf; +} + diff --git a/test/xmalloc.h b/test/xmalloc.h new file mode 100644 index 000000000..a4ba24b67 --- /dev/null +++ b/test/xmalloc.h @@ -0,0 +1,35 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Red Hat, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Red Hat, Inc. makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Carl D. Worth + */ + +#ifndef _XMALLOC_H_ +#define _XMALLOC_H_ + +void * +xmalloc (size_t size); + +void * +xcalloc (size_t nmemb, size_t size); + +#endif -- cgit v1.2.1 From 211b19b47575741a70901c10fe0e2d9aec8aa37b Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 26 Oct 2004 16:31:31 +0000 Subject: Add paragraph on new features. --- ChangeLog | 2 ++ test/README | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0e15f0100..212d8487e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2004-10-26 Carl Worth + * test/README: Add paragraph on new features. + * test/.cvsignore: * test/Makefile.am: * test/README: diff --git a/test/README b/test/README index 3e7acf5c2..edff360b6 100644 --- a/test/README +++ b/test/README @@ -39,9 +39,18 @@ the desired result of new_bug.c if the bug were fixed. Makefile.am should be edited, adding new_bug.c to both the TESTS and XFAIL_TESTS lists. +When a new feature is added +--------------------------- +It's important for the regression suite to keep pace with development +of the library. So a new test should be added for each new +feature. The work involved is similar the work described above for new +bugs. The only distinction is that the test is expected to pass so it +should not be added to the XFAIL_TESTS list. + + When a bug is fixed ------------------- -The fix shold be verified by running the test suite which should +The fix should be verified by running the test suite which should result in an "unexpected pass" for the test of interest. Rejoice as appropriate, then remove the relevant file name from the XFAIL_TESTS variable in Makefile.am. -- cgit v1.2.1 From 240276d7920d1c03e32e9a90f826f891f3cd3fcf Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 26 Oct 2004 16:59:22 +0000 Subject: Shell doesn't like whitespace around assignment operator. --- ChangeLog | 3 +++ configure.in | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 212d8487e..776b2958e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2004-10-26 Carl Worth + * configure.in: Shell doesn't like whitespace around assignment + operator. + * test/README: Add paragraph on new features. * test/.cvsignore: diff --git a/configure.in b/configure.in index ebe259a19..c4e57e6b5 100644 --- a/configure.in +++ b/configure.in @@ -248,7 +248,7 @@ if test "x$GCC" = "xyes"; then fi CAIRO_CFLAGS="$CAIRO_CFLAGS $WARN_CFLAGS" -CAIRO_LIBS = "$CAIRO_LIBS -lm" +CAIRO_LIBS="$CAIRO_LIBS -lm" AC_SUBST(CAIRO_CFLAGS) AC_SUBST(CAIRO_LIBS) -- cgit v1.2.1 From 083de7201755e1b4b322cf2308607f8f3c60a9d8 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 26 Oct 2004 18:19:55 +0000 Subject: Find reference images in so that make distcheck will work. Add header files so that make distcheck is happy. (INCLUDES): Add -D_GNU_SOURCE for asprintf. Someone motivated may want to find a more portable approach. (EXTRA_DIST): Add reference images for the sake of make distcheck. --- ChangeLog | 9 +++++++++ test/Makefile.am | 26 +++++++++++++++++++++----- test/cairo-test.c | 29 ++++++++++++++++++----------- test/cairo_test.c | 29 ++++++++++++++++++----------- 4 files changed, 66 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index 776b2958e..787f19bbf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ 2004-10-26 Carl Worth + * test/cairo_test.c (cairo_test): Find reference images in + ${srcdir} so that make distcheck will work. + + * test/Makefile.am (cairo_test_lib): Add header files so that make + distcheck is happy. + (INCLUDES): Add -D_GNU_SOURCE for asprintf. Someone motivated may + want to find a more portable approach. + (EXTRA_DIST): Add reference images for the sake of make distcheck. + * configure.in: Shell doesn't like whitespace around assignment operator. diff --git a/test/Makefile.am b/test/Makefile.am index 132d4037e..b0729cc71 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -13,17 +13,33 @@ move_to_show_surface XFAIL_TESTS = \ move_to_show_surface +# Ugh, don't like having to repeat this list so much. Can I use a +# wildcard here? +EXTRA_DIST = \ +line_width-ref.png \ +move_to_show_surface-ref.png + check_PROGRAMS = $(TESTS) -INCLUDES = -I$(srcdir) $(CAIRO_CFLAGS) -I$(srcdir)/../src +# We're using _GNU_SOURCE to get the prototype for asprintf. This may +# not be the most portable approach, but it is pragmatic and I'm +# willing to do something cleaner as soon as it causes someone a +# problem. +INCLUDES = -D_GNU_SOURCE -I$(srcdir) $(CAIRO_CFLAGS) -I$(srcdir)/../src AM_LDFLAGS = $(CAIRO_LIBS) -L../src -lcairo -cairo_test_lib = cairo_test.c read_png.c write_png.c xmalloc.c +cairo_test_lib =\ +cairo_test.c \ +cairo_test.h \ +read_png.c \ +read_png.h \ +write_png.c \ +write_png.h \ +xmalloc.c \ +xmalloc.h line_width_SOURCES = line_width.c $(cairo_test_lib) move_to_show_surface_SOURCES = move_to_show_surface.c $(cairo_test_lib) - - - +CLEANFILES = *-out.png *-diff.png diff --git a/test/cairo-test.c b/test/cairo-test.c index 0c2d09f3a..75327c892 100644 --- a/test/cairo-test.c +++ b/test/cairo-test.c @@ -36,16 +36,20 @@ #define CAIRO_TEST_REF_SUFFIX "-ref.png" #define CAIRO_TEST_DIFF_SUFFIX "-diff.png" -static char * -xstrcat_alloc (const char *s1, const char *s2) +static void +xasprintf (char **strp, const char *fmt, ...) { - char *ret; + va_list va; + int ret; - ret = xmalloc (strlen (s1) + strlen (s2) + 1); - strcpy (ret, s1); - strcat (ret, s2); + va_start (va, fmt); + ret = vasprintf (strp, fmt, va); + va_end (va); - return ret; + if (ret < 0) { + fprintf (stderr, "Out of memory\n"); + exit (1); + } } /* Image comparison code courttesy of Richard Worth. @@ -102,6 +106,7 @@ cairo_test (cairo_test_t *test, cairo_test_draw_function_t draw) int stride; unsigned char *png_buf, *ref_buf, *diff_buf; char *png_name, *ref_name, *diff_name; + char *srcdir; int pixels_changed; int ref_width, ref_height, ref_stride; read_png_status_t png_status; @@ -123,10 +128,12 @@ cairo_test (cairo_test_t *test, cairo_test_draw_function_t draw) cairo_destroy (cr); /* Then we've got a bunch of string manipulation and file I/O for the check */ - - png_name = xstrcat_alloc (test->name, CAIRO_TEST_PNG_SUFFIX); - ref_name = xstrcat_alloc (test->name, CAIRO_TEST_REF_SUFFIX); - diff_name = xstrcat_alloc (test->name, CAIRO_TEST_DIFF_SUFFIX); + srcdir = getenv ("srcdir"); + if (!srcdir) + srcdir = ""; + xasprintf (&png_name, "%s%s", test->name, CAIRO_TEST_PNG_SUFFIX); + xasprintf (&ref_name, "%s/%s%s", srcdir, test->name, CAIRO_TEST_REF_SUFFIX); + xasprintf (&diff_name, "%s%s", test->name, CAIRO_TEST_DIFF_SUFFIX); write_png_argb32 (png_buf, png_name, test->width, test->height, stride); diff --git a/test/cairo_test.c b/test/cairo_test.c index 0c2d09f3a..75327c892 100644 --- a/test/cairo_test.c +++ b/test/cairo_test.c @@ -36,16 +36,20 @@ #define CAIRO_TEST_REF_SUFFIX "-ref.png" #define CAIRO_TEST_DIFF_SUFFIX "-diff.png" -static char * -xstrcat_alloc (const char *s1, const char *s2) +static void +xasprintf (char **strp, const char *fmt, ...) { - char *ret; + va_list va; + int ret; - ret = xmalloc (strlen (s1) + strlen (s2) + 1); - strcpy (ret, s1); - strcat (ret, s2); + va_start (va, fmt); + ret = vasprintf (strp, fmt, va); + va_end (va); - return ret; + if (ret < 0) { + fprintf (stderr, "Out of memory\n"); + exit (1); + } } /* Image comparison code courttesy of Richard Worth. @@ -102,6 +106,7 @@ cairo_test (cairo_test_t *test, cairo_test_draw_function_t draw) int stride; unsigned char *png_buf, *ref_buf, *diff_buf; char *png_name, *ref_name, *diff_name; + char *srcdir; int pixels_changed; int ref_width, ref_height, ref_stride; read_png_status_t png_status; @@ -123,10 +128,12 @@ cairo_test (cairo_test_t *test, cairo_test_draw_function_t draw) cairo_destroy (cr); /* Then we've got a bunch of string manipulation and file I/O for the check */ - - png_name = xstrcat_alloc (test->name, CAIRO_TEST_PNG_SUFFIX); - ref_name = xstrcat_alloc (test->name, CAIRO_TEST_REF_SUFFIX); - diff_name = xstrcat_alloc (test->name, CAIRO_TEST_DIFF_SUFFIX); + srcdir = getenv ("srcdir"); + if (!srcdir) + srcdir = ""; + xasprintf (&png_name, "%s%s", test->name, CAIRO_TEST_PNG_SUFFIX); + xasprintf (&ref_name, "%s/%s%s", srcdir, test->name, CAIRO_TEST_REF_SUFFIX); + xasprintf (&diff_name, "%s%s", test->name, CAIRO_TEST_DIFF_SUFFIX); write_png_argb32 (png_buf, png_name, test->width, test->height, stride); -- cgit v1.2.1 From 19d3fc2399a05a3802b1cb2ced55139fa85a68b8 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 27 Oct 2004 07:26:36 +0000 Subject: Switch from two different buggy mod macros to a new MOD macro which should work in C89 or C99. --- pixman/ChangeLog | 5 +++++ pixman/NEWS | 7 ++++--- pixman/src/ic.c | 10 ++++------ pixman/src/iccompose.c | 18 ++++++++---------- pixman/src/icint.h | 10 +++++++++- 5 files changed, 30 insertions(+), 20 deletions(-) diff --git a/pixman/ChangeLog b/pixman/ChangeLog index bf6165c8e..259ddd5ba 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -4,6 +4,11 @@ * configure.in: Increment version to 0.1.2 + * src/icint.h (MOD): + * src/iccompose.c (IcFetch_transform): + * src/ic.c (pixman_composite): Switch from two different buggy mod + macros to a new MOD macro which should work in C89 or C99. + 2004-09-12 David Reveman * src/icformat.c (pixman_format_init): pixman_format_init expects diff --git a/pixman/NEWS b/pixman/NEWS index 9e6b99c5d..8a392e19e 100644 --- a/pixman/NEWS +++ b/pixman/NEWS @@ -18,9 +18,10 @@ The other two functions are simple query functions that were missing. Bug fixes --------- -Enabling transform and repeat together now works. -Endian-ness fixes. -Memory mismanagement fixes. +Enabling both transform and repeat simultaneously now works. +Some byte-order fixes. +Clipping fixes: pixman now takes a copy of the client clipping region + client clipping is now actually used, it wasn't earlier. Snapshot 0.1.1 (2004-04-16 Carl Worth ) ============================================================ diff --git a/pixman/src/ic.c b/pixman/src/ic.c index 44e7120f2..b8b445c9e 100644 --- a/pixman/src/ic.c +++ b/pixman/src/ic.c @@ -857,8 +857,6 @@ pixman_compositeSolidMask_nx1xn (pixman_operator_t op, 0x0); } -# define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b)) - void pixman_composite (pixman_operator_t op, pixman_image_t *iSrc, @@ -1103,13 +1101,13 @@ pixman_composite (pixman_operator_t op, x_dst = pbox->x1; if (maskRepeat) { - y_msk = mod (y_msk, iMask->pixels->height); + y_msk = MOD (y_msk, iMask->pixels->height); if (h_this > iMask->pixels->height - y_msk) h_this = iMask->pixels->height - y_msk; } if (srcRepeat) { - y_src = mod (y_src, iSrc->pixels->height); + y_src = MOD (y_src, iSrc->pixels->height); if (h_this > iSrc->pixels->height - y_src) h_this = iSrc->pixels->height - y_src; } @@ -1118,13 +1116,13 @@ pixman_composite (pixman_operator_t op, w_this = w; if (maskRepeat) { - x_msk = mod (x_msk, iMask->pixels->width); + x_msk = MOD (x_msk, iMask->pixels->width); if (w_this > iMask->pixels->width - x_msk) w_this = iMask->pixels->width - x_msk; } if (srcRepeat) { - x_src = mod (x_src, iSrc->pixels->width); + x_src = MOD (x_src, iSrc->pixels->width); if (w_this > iSrc->pixels->width - x_src) w_this = iSrc->pixels->width - x_src; } diff --git a/pixman/src/iccompose.c b/pixman/src/iccompose.c index 5dd074cc8..a8ae1e864 100644 --- a/pixman/src/iccompose.c +++ b/pixman/src/iccompose.c @@ -2239,8 +2239,6 @@ IcStore_external (pixman_compositeOperand *op, uint32_t value) (*op[2].store) (&op[2], value & 0xff000000); } -#define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (a) % (b) == 0 ? 0: (b) + (a) % (b)) - static uint32_t IcFetch_transform (pixman_compositeOperand *op) { @@ -2264,8 +2262,8 @@ IcFetch_transform (pixman_compositeOperand *op) x = xFixedToInt (v.vector[0]) + op->u.transform.left_x; if (op->u.transform.repeat) { - y = mod (y, op->u.transform.height); - x = mod (x, op->u.transform.width); + y = MOD (y, op->u.transform.height); + x = MOD (x, op->u.transform.width); } if (pixman_region_contains_point (op->clip, x, y, &box)) { @@ -2292,7 +2290,7 @@ IcFetch_transform (pixman_compositeOperand *op) int tx, ty; if (op->u.transform.repeat) - ty = mod (y, op->u.transform.height); + ty = MOD (y, op->u.transform.height); else ty = y; @@ -2300,7 +2298,7 @@ IcFetch_transform (pixman_compositeOperand *op) for (x = minx; x <= maxx; x++) { if (op->u.transform.repeat) - tx = mod (x, op->u.transform.width); + tx = MOD (x, op->u.transform.width); else tx = x; @@ -2363,8 +2361,8 @@ IcFetcha_transform (pixman_compositeOperand *op) x = xFixedToInt (v.vector[0]) + op->u.transform.top_y; if (op->u.transform.repeat) { - y = mod (y, op->u.transform.height); - x = mod (x, op->u.transform.width); + y = MOD (y, op->u.transform.height); + x = MOD (x, op->u.transform.width); } if (pixman_region_contains_point (op->clip, x, y, &box)) { @@ -2392,7 +2390,7 @@ IcFetcha_transform (pixman_compositeOperand *op) int tx, ty; if (op->u.transform.repeat) - ty = mod (y, op->u.transform.height); + ty = MOD (y, op->u.transform.height); else ty = y; @@ -2400,7 +2398,7 @@ IcFetcha_transform (pixman_compositeOperand *op) for (x = minx; x <= maxx; x++) { if (op->u.transform.repeat) - tx = mod (x, op->u.transform.width); + tx = MOD (x, op->u.transform.width); else tx = x; diff --git a/pixman/src/icint.h b/pixman/src/icint.h index b200e9e05..0f8ce1c12 100644 --- a/pixman/src/icint.h +++ b/pixman/src/icint.h @@ -37,9 +37,17 @@ #include "slim_internal.h" +/* C89 has implementation-defined behavior for % with negative operands. + C99 has well-defined behavior which is that / with integers rounds toward zero + and a%b is defined so that (a/b)*b + a%b == a. + The C99 version gives negative remainders rather than the modulus + in [0 .. b-1] that we want. This macro avoids using % with negative + operands to avoid both problems. - + a and b are integers. b > 0. +*/ +#define MOD(a, b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-(a) - 1) % (b) - 1) typedef struct _IcPoint { int16_t x,y ; -- cgit v1.2.1 From ed1ad714174abd3354d2dc3991b596d83f6330bf Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 27 Oct 2004 09:37:34 +0000 Subject: Update date since 0.1.2 release didn't get pushed out until today. Update release instructions to include new release-publish target. Add release-check and release-publish targets to simplify the release process. --- pixman/.cvsignore | 2 +- pixman/ChangeLog | 11 +++++++++++ pixman/Makefile.am | 42 ++++++++++++++++++++++++++++++++++++++++ pixman/NEWS | 2 +- pixman/RELEASING | 57 ++++++++++++++++++++++-------------------------------- pixman/TODO | 10 ++++++++++ 6 files changed, 88 insertions(+), 36 deletions(-) create mode 100644 pixman/TODO diff --git a/pixman/.cvsignore b/pixman/.cvsignore index 92be14143..a3d5a36ac 100644 --- a/pixman/.cvsignore +++ b/pixman/.cvsignore @@ -13,7 +13,7 @@ configure libpixman.pc libtool ltmain.sh +releases stamp-h stamp-h.in stamp-h1 - diff --git a/pixman/ChangeLog b/pixman/ChangeLog index 259ddd5ba..f4459855b 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -1,3 +1,14 @@ +2004-10-27 Carl Worth + + * NEWS: Update date since 0.1.2 release didn't get pushed out + until today. + + * RELEASING: Update release instructions to include new + release-publish target. + + * Makefile.am (release-publish): Add release-check and + release-publish targets to simplify the release process. + 2004-10-13 Carl Worth * NEWS: Add notes for snapshot 0.1.2 diff --git a/pixman/Makefile.am b/pixman/Makefile.am index 3d70323a2..eea99b0a6 100644 --- a/pixman/Makefile.am +++ b/pixman/Makefile.am @@ -9,3 +9,45 @@ EXTRA_DIST = \ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libpixman.pc + +tar_file = $(PACKAGE)-$(VERSION).tar.gz +md5_file = $(tar_file).md5 + +# Some custom targets to make it easier to release things. +# Use either: +# make release-check +# or make release-publish + +RELEASE_UPLOAD_DIR = cairographics.org:/home/www/cairo/snapshots +RELEASE_URL_BASE = http://cairographics.org/snapshots +RELEASE_ANNOUNCE_LIST = cairo-announce@cairographics.org + +$(md5_file): $(tar_file) + md5sum $^ > $@ + +release-remove-old: + rm -f $(tar_file) $(md5_file) + +release-check: release-remove-old distcheck $(md5_file) + +release-publish: release-check + mkdir -p releases + scp $(tar_file) $(md5_file) $(RELEASE_UPLOAD_DIR) + mv $(tar_file) $(md5_file) releases + @echo "" + @echo "Please send an announcement to $(RELEASE_ANNOUNCE_LIST)" + @echo "including the following:" + @echo "" + @echo "Subject: $(PACKAGE) snapshot $(VERSION) now available" + @echo "" + @echo "A new $(PACKAGE) snapshot $(VERSION) is now available from:" + @echo "" + @echo " $(RELEASE_URL_BASE)/$(tar_file)" + @echo " $(RELEASE_URL_BASE)/$(md5_file)" + @echo -n " " + @cat releases/$(md5_file) + @echo "" + @echo "Also, please include the new entries from the NEWS file." + + + diff --git a/pixman/NEWS b/pixman/NEWS index 8a392e19e..7d3544ce7 100644 --- a/pixman/NEWS +++ b/pixman/NEWS @@ -1,4 +1,4 @@ -Snapshot 0.1.2 (2004-10-13 Carl Worth ) +Snapshot 0.1.2 (2004-10-27 Carl Worth ) ========================================================== New functionality ----------------- diff --git a/pixman/RELEASING b/pixman/RELEASING index 88077f306..cb9d41605 100644 --- a/pixman/RELEASING +++ b/pixman/RELEASING @@ -2,16 +2,13 @@ So far, libpixman hasn't reached an initial release. But we can still form good habits now by practicing the release process with the current snapshots. -10 easy steps to creating a new libpixman snapshot -================================================== +A new snapshot is needed whenever significant new features or bug +fixes are committed. Here are the steps to follow: -1) Commit code with a significant new feature or backwards - incompatibility. +1) Ensure that there are no local, uncommitted modifications. The best + thing to do here may be to begin with a fresh checkout from CVS: - Either of these events triggers the need for a new snapshot. - Users of libpixman snapshots need to be able to specify snapshot - version numbers in order to get access to a specific set of - features. + cvs -d cairographics.org:/cvs/cairo co libpixman 2) Verify that the code passes "make distcheck" @@ -34,10 +31,14 @@ snapshots. 4) Increment LIBPIXMAN_VERSION in configure.in Right now, in its pre-release form, we are incrementing - LIBPIXMAN_VERSION for each snapshot but we are not changing the - libtool shared library version information. Until now, we've - only incremented the sub-minor version. We'll invent rules for - incrementing major and minor numbers when the time is right. + LIBPIXMAN_VERSION for each snapshot but we are not changing + the libtool shared library version information. Increment the + subminor version for bug fixes and backwards-compatible + additions to the API. Increment the minor number (and reset + the subminor) for backward-incompatible changes to the API + (including removals). Leave the major number at 0 until we are + ready for the first 1.0 release, (at which point these rules + will change). 5) Commit the changes to NEWS and configure.in @@ -45,27 +46,15 @@ snapshots. other commit. It's especially important to mention the new version number in the ChangeLog. -6) Run "make distcheck" to generate the final tar file with the - correct version number. +6) Run "make release-publish" which will perform the following steps + for you: -7) Copy the resulting tar file to the cairo snapshots distribution - directory: + * Verify that make distcheck completes successfully + * Generate the final tar file with the correct version number + * Generate an md5sum file + * scp both files to cairographics.org:/home/www/cairo/snapshots + * Place local copies of both files in the releases directory + * Provide some text for the release announcement - scp libpixman-X.Y.Z-tar.gz cairographics.org:/home/www/cairo/snapshots - -8) Tag the entire source tree with a tag of the form SNAPSHOT_X_Y_Z: - - cvs tag SNAPSHOT_X_Y_Z - -9) Send a message to cairo-announce@cairographics.org to announce the - new snapshot. - - The message should provide the URL for the snapshot: - - http://cairographics.org/snapshots/cairo-X.Y.Z.tar.gz - - and should also include the relevant section from the NEWS - file. - -10) Sit back and relax in confidence, or alternately, brace yourself - for a flood of new bug reports. +7) Send a message to cairo-announce@cairographics.org to announce the + new snapshot using the text provided by the previous step. diff --git a/pixman/TODO b/pixman/TODO new file mode 100644 index 000000000..5560d8de4 --- /dev/null +++ b/pixman/TODO @@ -0,0 +1,10 @@ +Need to finish up libpixman to the point where there X server can use +it in place of its original copy of all this code (eg. in fb). This +means merging features that have happened in either tree since the +birth of libpixman. Off-hand I can think of the following things that +have happened: + + * libpixman has fix for transform + repeat + * X server has some (MMX? SSE?) optimized compositing code + +But see the logs for more details. -- cgit v1.2.1 From 944b1721e1910bc4d8caa97ae946b769f9ad2d8a Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 27 Oct 2004 09:43:22 +0000 Subject: Suggest "cvs -q update -Ad" as an alternative to checkout. --- pixman/ChangeLog | 1 + pixman/RELEASING | 3 +++ 2 files changed, 4 insertions(+) diff --git a/pixman/ChangeLog b/pixman/ChangeLog index f4459855b..59a6e49da 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -5,6 +5,7 @@ * RELEASING: Update release instructions to include new release-publish target. + Suggest "cvs -q update -Ad" as an alternative to checkout. * Makefile.am (release-publish): Add release-check and release-publish targets to simplify the release process. diff --git a/pixman/RELEASING b/pixman/RELEASING index cb9d41605..a45ad48ca 100644 --- a/pixman/RELEASING +++ b/pixman/RELEASING @@ -10,6 +10,9 @@ fixes are committed. Here are the steps to follow: cvs -d cairographics.org:/cvs/cairo co libpixman + But it's probably good enough if "cvs -q update -Ad" generates no + output. + 2) Verify that the code passes "make distcheck" Running "make distcheck" should result in no warnings or -- cgit v1.2.1 From 667fa8fc15044f1d488aa98a74c29206b921d57e Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 27 Oct 2004 10:48:58 +0000 Subject: Add new test for cairo_set_fill_rule. Also demonstrate some of the current tessellation bugs with the version of the code that is in CVS. --- ChangeLog | 6 ++++ test/.cvsignore | 1 + test/Makefile.am | 26 +++++++++----- test/fill-rule-ref.png | Bin 0 -> 408 bytes test/fill-rule.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++ test/fill_rule-ref.png | Bin 0 -> 408 bytes test/fill_rule.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 204 insertions(+), 9 deletions(-) create mode 100644 test/fill-rule-ref.png create mode 100644 test/fill-rule.c create mode 100644 test/fill_rule-ref.png create mode 100644 test/fill_rule.c diff --git a/ChangeLog b/ChangeLog index 787f19bbf..9db2d9dd6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2004-10-27 Carl Worth + + * test/fill_rule.c: Add new test for cairo_set_fill_rule. Also + demonstrate some of the current tessellation bugs with the version + of the code that is in CVS. + 2004-10-26 Carl Worth * test/cairo_test.c (cairo_test): Find reference images in diff --git a/test/.cvsignore b/test/.cvsignore index 1937368c3..3b5304218 100644 --- a/test/.cvsignore +++ b/test/.cvsignore @@ -2,6 +2,7 @@ .libs Makefile Makefile.in +fill_rule line_width move_to_show_surface *-out.png diff --git a/test/Makefile.am b/test/Makefile.am index b0729cc71..13216d72d 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,10 +1,20 @@ +# All new test cases go here TESTS = \ +fill_rule \ line_width \ move_to_show_surface -# Known bugs (not regressions). We do need to fix these before the -# next release, but they are expected to fail for now, so they don't -# need to hold up any new code commit. +# And all new test go here too. I really don't like having to repeat +# this list. Anyone know a good way to avoid it? Can I use a wildcard +# here? +EXTRA_DIST = \ +fill_rule-ref.png \ +line_width-ref.png \ +move_to_show_surface-ref.png + +# This list is only for known bugs (not regressions). We do need to +# fix these before the next release, but they are expected to fail for +# now, so they don't need to hold up any new code commit. # # When new bugs are found in committed code they can be listed # here. New failures due to local, uncommitted code changes are @@ -13,12 +23,6 @@ move_to_show_surface XFAIL_TESTS = \ move_to_show_surface -# Ugh, don't like having to repeat this list so much. Can I use a -# wildcard here? -EXTRA_DIST = \ -line_width-ref.png \ -move_to_show_surface-ref.png - check_PROGRAMS = $(TESTS) # We're using _GNU_SOURCE to get the prototype for asprintf. This may @@ -39,6 +43,10 @@ write_png.h \ xmalloc.c \ xmalloc.h +# ARGH! I have to repeat the list of tests a third time. Maybe it's +# time to break down and auto-generate the Makefile.am or something +# from autogen.sh. My, but this is painful... +fill_rule_SOURCES = fill_rule.c $(cairo_test_lib) line_width_SOURCES = line_width.c $(cairo_test_lib) move_to_show_surface_SOURCES = move_to_show_surface.c $(cairo_test_lib) diff --git a/test/fill-rule-ref.png b/test/fill-rule-ref.png new file mode 100644 index 000000000..25442c049 Binary files /dev/null and b/test/fill-rule-ref.png differ diff --git a/test/fill-rule.c b/test/fill-rule.c new file mode 100644 index 000000000..40ab9a123 --- /dev/null +++ b/test/fill-rule.c @@ -0,0 +1,90 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Red Hat, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Red Hat, Inc. makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Carl D. Worth + */ + +/* Bug history + * + * 2004-10-27 Carl Worth + * + * There's currently a regression bug in the tessellation code. This + * causes each of these simple star shapes to be filled incorrectly. + * + * It looks like right now we can get this test to pass by doing: + * + * cvs update -r 1.16 src/cairo_traps.c + * + * But we don't want to revert that change permanently since it + * really does correct some bugs. It must be that the old version of + * the code is masking some other bugs in the tessellation code. My + * current plan is to back this revision up for the next snapshot, + * but not to list the test as an expected failure since I'm + * planning on doing the new tessellator which should fix this + * problem. + * + */ + +#include "cairo_test.h" + +#define STAR_SIZE 20 + +cairo_test_t test = { + "fill_rule", + "Tests cairo_set_full_rule with a star shape", + STAR_SIZE * 2 + 3, STAR_SIZE +2 +}; + + +/* Not a perfect star, but one that does show the tessellation bug. */ +static void +star_path (cairo_t *cr) +{ + cairo_move_to (cr, 10, 0); + cairo_rel_line_to (cr, 6, 20); + cairo_rel_line_to (cr, -16, -12); + cairo_rel_line_to (cr, 20, 0); + cairo_rel_line_to (cr, -16, 12); +} + +/* Fill the same path twice, once with each fill rule */ +static void +draw (cairo_t *cr, int width, int height) +{ + cairo_set_rgb_color (cr, 1, 0, 0); + + cairo_translate (cr, 1, 1); + star_path (cr); + cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING); + cairo_fill (cr); + + cairo_translate (cr, STAR_SIZE + 1, 0); + star_path (cr); + cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); + cairo_fill (cr); +} + +int +main (void) +{ + return cairo_test (&test, draw); +} diff --git a/test/fill_rule-ref.png b/test/fill_rule-ref.png new file mode 100644 index 000000000..25442c049 Binary files /dev/null and b/test/fill_rule-ref.png differ diff --git a/test/fill_rule.c b/test/fill_rule.c new file mode 100644 index 000000000..40ab9a123 --- /dev/null +++ b/test/fill_rule.c @@ -0,0 +1,90 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Red Hat, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Red Hat, Inc. makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Carl D. Worth + */ + +/* Bug history + * + * 2004-10-27 Carl Worth + * + * There's currently a regression bug in the tessellation code. This + * causes each of these simple star shapes to be filled incorrectly. + * + * It looks like right now we can get this test to pass by doing: + * + * cvs update -r 1.16 src/cairo_traps.c + * + * But we don't want to revert that change permanently since it + * really does correct some bugs. It must be that the old version of + * the code is masking some other bugs in the tessellation code. My + * current plan is to back this revision up for the next snapshot, + * but not to list the test as an expected failure since I'm + * planning on doing the new tessellator which should fix this + * problem. + * + */ + +#include "cairo_test.h" + +#define STAR_SIZE 20 + +cairo_test_t test = { + "fill_rule", + "Tests cairo_set_full_rule with a star shape", + STAR_SIZE * 2 + 3, STAR_SIZE +2 +}; + + +/* Not a perfect star, but one that does show the tessellation bug. */ +static void +star_path (cairo_t *cr) +{ + cairo_move_to (cr, 10, 0); + cairo_rel_line_to (cr, 6, 20); + cairo_rel_line_to (cr, -16, -12); + cairo_rel_line_to (cr, 20, 0); + cairo_rel_line_to (cr, -16, 12); +} + +/* Fill the same path twice, once with each fill rule */ +static void +draw (cairo_t *cr, int width, int height) +{ + cairo_set_rgb_color (cr, 1, 0, 0); + + cairo_translate (cr, 1, 1); + star_path (cr); + cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING); + cairo_fill (cr); + + cairo_translate (cr, STAR_SIZE + 1, 0); + star_path (cr); + cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); + cairo_fill (cr); +} + +int +main (void) +{ + return cairo_test (&test, draw); +} -- cgit v1.2.1 From 1839d679b1a9b60b9c153183df8380061fdd7e64 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 27 Oct 2004 10:53:44 +0000 Subject: Put the tag command back which was accidentally removed from the instructions. --- pixman/ChangeLog | 3 +++ pixman/RELEASING | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/pixman/ChangeLog b/pixman/ChangeLog index 59a6e49da..94cbf2016 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -1,5 +1,8 @@ 2004-10-27 Carl Worth + * RELEASING: Put the tag command back which was accidentally + removed from the instructions. + * NEWS: Update date since 0.1.2 release didn't get pushed out until today. diff --git a/pixman/RELEASING b/pixman/RELEASING index a45ad48ca..22667b3ac 100644 --- a/pixman/RELEASING +++ b/pixman/RELEASING @@ -59,5 +59,9 @@ fixes are committed. Here are the steps to follow: * Place local copies of both files in the releases directory * Provide some text for the release announcement -7) Send a message to cairo-announce@cairographics.org to announce the +7) Tag the entire source tree with a tag of the form SNAPSHOT_X_Y_Z: + + cvs tag SNAPSHOT_X_Y_Z + +8) Send a message to cairo-announce@cairographics.org to announce the new snapshot using the text provided by the previous step. -- cgit v1.2.1 From 39d57762a65f8b16e27c56435217cc96e8c68a23 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 27 Oct 2004 11:42:45 +0000 Subject: Fix to always link tests against locally built library, not installed version. --- ChangeLog | 3 +++ test/Makefile.am | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9db2d9dd6..4c3cd6896 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2004-10-27 Carl Worth + * test/Makefile.am (AM_LDFLAGS): Fix to always link tests against + locally built library, not installed version. + * test/fill_rule.c: Add new test for cairo_set_fill_rule. Also demonstrate some of the current tessellation bugs with the version of the code that is in CVS. diff --git a/test/Makefile.am b/test/Makefile.am index 13216d72d..2f80f9f89 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -31,7 +31,7 @@ check_PROGRAMS = $(TESTS) # problem. INCLUDES = -D_GNU_SOURCE -I$(srcdir) $(CAIRO_CFLAGS) -I$(srcdir)/../src -AM_LDFLAGS = $(CAIRO_LIBS) -L../src -lcairo +AM_LDFLAGS = $(CAIRO_LIBS) ../src/libcairo.la cairo_test_lib =\ cairo_test.c \ -- cgit v1.2.1 From 377983fdf320cf98061fed9cec1870712855871a Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 27 Oct 2004 11:59:56 +0000 Subject: Update release instructions for new release-publish target. Add release-check and release-publish targets copied from libpixman. --- ChangeLog | 6 ++++++ Makefile.am | 40 ++++++++++++++++++++++++++++++++++ RELEASING | 71 +++++++++++++++++++++++++++++-------------------------------- 3 files changed, 80 insertions(+), 37 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4c3cd6896..781f09a34 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2004-10-27 Carl Worth + * RELEASING: Update release instructions for new release-publish + target. + + * Makefile.am: Add release-check and release-publish targets + copied from libpixman. + * test/Makefile.am (AM_LDFLAGS): Fix to always link tests against locally built library, not installed version. diff --git a/Makefile.am b/Makefile.am index 624ec1334..6dfc4ab3d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -8,3 +8,43 @@ EXTRA_DIST = \ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = cairo.pc + +# Some custom targets to make it easier to release things. +# Use either: +# make release-check +# or make release-publish + +RELEASE_UPLOAD_DIR = cairographics.org:/home/www/cairo/snapshots +RELEASE_URL_BASE = http://cairographics.org/snapshots +RELEASE_ANNOUNCE_LIST = cairo-announce@cairographics.org + +tar_file = $(PACKAGE)-$(VERSION).tar.gz +md5_file = $(tar_file).md5 + +$(md5_file): $(tar_file) + md5sum $^ > $@ + +release-remove-old: + rm -f $(tar_file) $(md5_file) + +release-check: release-remove-old distcheck $(md5_file) + +release-publish: release-check + mkdir -p releases + scp $(tar_file) $(md5_file) $(RELEASE_UPLOAD_DIR) + mv $(tar_file) $(md5_file) releases + @echo "" + @echo "Please send an announcement to $(RELEASE_ANNOUNCE_LIST)" + @echo "including the following:" + @echo "" + @echo "Subject: $(PACKAGE) snapshot $(VERSION) now available" + @echo "" + @echo "A new $(PACKAGE) snapshot $(VERSION) is now available from:" + @echo "" + @echo " $(RELEASE_URL_BASE)/$(tar_file)" + @echo " $(RELEASE_URL_BASE)/$(md5_file)" + @echo -n " " + @cat releases/$(md5_file) + @echo "" + @echo "Also, please include the new entries from the NEWS file." + diff --git a/RELEASING b/RELEASING index 64ebb43fa..5a7ee9d87 100644 --- a/RELEASING +++ b/RELEASING @@ -2,38 +2,30 @@ So far, cairo hasn't reached an initial release. But we can still form good habits now by practicing the release process with the current snapshots. -10 easy steps to creating a new cairo snapshot -============================================== +A new snapshot is needed whenever significant new features or bug +fixes are committed. Here are the steps to follow: -1) Commit code with a significant new feature or backwards - incompatibility. +1) Ensure that there are no local, uncommitted modifications. The best + thing to do here may be to begin with a fresh checkout from CVS: - Either of these events triggers the need for a new snapshot. - Users of cairo snapshots need to be able to specify snapshot - version numbers in order to get access to a specific set of - features. + cvs -d cairographics.org:/cvs/cairo co cairo -2) Increment CAIRO_VERSION in configure.in + But it's probably good enough if "cvs -q update -Ad" generates no + output. - Right now, in its pre-release form, we are incrementing - CAIRO_VERSION for each snapshot but we are not changing the - libtool shared library version information. Until now, we've - only incremented the sub-minor version. We'll invent rules for - incrementing major and minor numbers when the time is right. - -3) Verify that the code passes "make distcheck" +2) Verify that the code passes "make distcheck" Running "make distcheck" should result in no warnings or errors and end with a message of the form: - ============================================= + ================================================ cairo-X.Y.Z.tar.gz is ready for distribution - ============================================= + ================================================ (But the tar file isn't actually ready yet, as we still have some more steps to follow). -4) Fill out an entry in the NEWS file +3) Fill out an entry in the NEWS file Sift through the information in ChangeLog since the last snapshot. Summarize major changes briefly in a style similar @@ -41,33 +33,38 @@ snapshots. incompatible changes in the API. These should be easy to find by looking for cairo.h in the ChangeLog. +4) Increment CAIRO_VERSION in configure.in + + Right now, in its pre-release form, we are incrementing + CAIRO_VERSION for each snapshot but we are not changing + the libtool shared library version information. Increment the + subminor version for bug fixes and backwards-compatible + additions to the API. Increment the minor number (and reset + the subminor) for backward-incompatible changes to the API + (including removals). Leave the major number at 0 until we are + ready for the first 1.0 release, (at which point these rules + will change). + 5) Commit the changes to NEWS and configure.in Don't forget to fill out the ChangeLog just like with any other commit. It's especially important to mention the new version number in the ChangeLog. -6) Run "make distcheck" to generate the final tar file including the - changes to NEWS and ChangeLog. +6) Run "make release-publish" which will perform the following steps + for you: -7) Copy the resulting tar file to the cairo snapshots distribution - directory: + * Verify that make distcheck completes successfully + * Generate the final tar file with the correct version number + * Generate an md5sum file + * scp both files to cairographics.org:/home/www/cairo/snapshots + * Place local copies of both files in the releases directory + * Provide some text for the release announcement - scp cairo-X.Y.Z-tar.gz cairographics.org:/home/www/cairo/snapshots - -8) Tag the entire source tree with a tag of the form SNAPSHOT_X_Y_Z: +7) Tag the entire source tree with a tag of the form SNAPSHOT_X_Y_Z: cvs tag SNAPSHOT_X_Y_Z -9) Send a message to cairo-announce@cairographics.org to announce the - new snapshot. - - The message should provide the URL for the snapshot: - - http://cairographics.org/snapshots/cairo-X.Y.Z.tar.gz - - and should also include the relevant section from the NEWS - file. +8) Send a message to cairo-announce@cairographics.org to announce the + new snapshot using the text provided by the previous step. -10) Sit back and relax in confidence, or alternately, brace yourself - for a flood of new bug reports. -- cgit v1.2.1 From d18aad05f33b903ec2ce2d5b5159ea1193af819c Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 27 Oct 2004 13:13:39 +0000 Subject: Increment CAIRO_VERSION to 0.2.0. Add notes for snapshot 0.2.0. --- .cvsignore | 1 + ChangeLog | 4 +++ NEWS | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----- RELEASING | 6 ++++- configure.in | 2 +- 5 files changed, 84 insertions(+), 8 deletions(-) diff --git a/.cvsignore b/.cvsignore index e7a9cd8c0..fab894e3f 100644 --- a/.cvsignore +++ b/.cvsignore @@ -13,6 +13,7 @@ config.sub configure libtool ltmain.sh +releases stamp-h stamp-h1 stamp-h.in diff --git a/ChangeLog b/ChangeLog index 781f09a34..651945590 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2004-10-27 Carl Worth + * configure.in: Increment CAIRO_VERSION to 0.2.0. + + * NEWS: Add notes for snapshot 0.2.0. + * RELEASING: Update release instructions for new release-publish target. diff --git a/NEWS b/NEWS index 116c8dfcf..765218573 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,75 @@ -Glyph caching -------------- -Internal caching of glyphs provides a major improvement to -text rendering performance, especially for Xlib and OpenGL -backends. +Snapshot 0.2.0 (2004-10-27 Carl Worth ) +=========================================================== +New license: LGPL/MPL +--------------------- +The most significant news with this release is that the license of +cairo has changed. It is now dual-licensed under the LGPL and the +MPL. For details see the COPYING file as well as COPYING-LGPL-2.1 and +COPYING-MPL-1.1. + +I express my thanks to everyone involved in the license change process +for their patience and support! + +New font and glyph internals +---------------------------- +Graydon Hoare has put a tremendous amount of work into new internals +for handling fonts and glyphs, including caches where appropriate. +This work has no impact on the user-level API, but should result in +great performance improvements for applications using text. + +New test suite +-------------- +This snapshot of cairo includes a (small) test suite in +cairo/test. The tests can be run with "make check". The test suite was +designed to make it very easy to add new tests, and we hope to see +many contributions here. As you find bugs, please try adding a minimal +test case to the suite, and submit it with the bug report to the +cairo@cairographics.org mailing list. This will make it much easier +for us to track progress in fixing bugs. + +New name for glitz backend +-------------------------- +The gl backend has now been renamed to the glitz backend. This means +that the following names have changed: + + CAIRO_HAS_GL_SURFACE -> CAIRO_HAS_GLITZ_SURFACE + cairo_set_target_gl -> cairo_set_target_glitz + cairo_gl_surface_create -> cairo_glitz_surface_create + +This change obviously breaks backwards compatibility for applications +using the old gl backend. + +Up-to-date with latest glitz snapshots +-------------------------------------- +This snapshot of cairo is now up to date with the latest glitz +snapshot, (currently 0.2.3). We know that the latest cairo and glitz +snapshots have been incompatible for a very long time. We've finally +fixed that now and we're determined to not let that happen again. + +Miscellaneous changes +--------------------- +Changed CAIRO_FILTER_DEFAULT to CAIRO_FILTER_BEST to make gradients +easier. + +Track XCB API change regarding iterators. + +Various bug fixes +----------------- +Fix calculation of required number of vertices for pen. + +Fix to avoid zero-dimensioned pixmaps. + +Fix broken sort of pen vertices. + +Fix bug when cairo_show_text called with a NULL string. + +Fix clipping bugs. + +Fix bug in computing image length with XCB. + +Fix infinite loop bug in cairo_arc. + +Fix memory management interactions with libpixman. Snapshot 0.1.23 (2004-05-11 Carl Worth ) ======================================================== @@ -170,7 +237,7 @@ the heavy lifting with this renaming effort. Conditional compilation of backends ----------------------------------- -Cairo now allows optional beckends to be disabled at compile time. The +Cairo now allows optional backends to be disabled at compile time. The following options may now be passed to the configure script: --disable-xlib diff --git a/RELEASING b/RELEASING index 5a7ee9d87..8cc5f021b 100644 --- a/RELEASING +++ b/RELEASING @@ -31,7 +31,11 @@ fixes are committed. Here are the steps to follow: snapshot. Summarize major changes briefly in a style similar to other entries in NEWS. Take special care to note any incompatible changes in the API. These should be easy to find - by looking for cairo.h in the ChangeLog. + by looking for cairo.h in the ChangeLog. Additionally, the + output following command should be examined using the previous + snapshot tag: + + cvs diff -r SNAPSHOT_X_Y_Z src/cairo.h 4) Increment CAIRO_VERSION in configure.in diff --git a/configure.in b/configure.in index c4e57e6b5..b17c91006 100644 --- a/configure.in +++ b/configure.in @@ -3,7 +3,7 @@ AC_INIT(src/cairo.h) dnl =========================================================================== # Package version number, (as distinct from shared library version) -CAIRO_VERSION=0.1.23 +CAIRO_VERSION=0.2.0 # libtool shared library version -- cgit v1.2.1 From 327dc6f2ae304aa0536123bf8224a53290f72c29 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 27 Oct 2004 13:19:39 +0000 Subject: Add note on reverted tessellation regression bugs. --- ChangeLog | 1 + NEWS | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index 651945590..db326ebe8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,7 @@ * configure.in: Increment CAIRO_VERSION to 0.2.0. * NEWS: Add notes for snapshot 0.2.0. + Add note on reverted tessellation regression bugs. * RELEASING: Update release instructions for new release-publish target. diff --git a/NEWS b/NEWS index 765218573..8465aaa3f 100644 --- a/NEWS +++ b/NEWS @@ -46,6 +46,14 @@ snapshot, (currently 0.2.3). We know that the latest cairo and glitz snapshots have been incompatible for a very long time. We've finally fixed that now and we're determined to not let that happen again. +Revert some tessellation regression bugs +---------------------------------------- +People that have been seeing some tessellation bugs, (eg. leaked +fills), in the CVS version of cairo may have better luck with this +release. A change since the last snapshot was identified to trigger +some of these bugs and was reverted before making the snapshot. The +behavior should be the same as the previous (0.1.23) snapshot. + Miscellaneous changes --------------------- Changed CAIRO_FILTER_DEFAULT to CAIRO_FILTER_BEST to make gradients -- cgit v1.2.1