LCOV - app.info - gfx/cairo/cairo/src/cairo-misc.c

LCOV - code coverage report
| Current view: | directory - gfx/cairo/cairo/src - cairo-misc.c (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 182 | 6 | 3.3 %
| Date: | 2012-06-02 | Functions: | 20 | 2 | 10.0 %

           1                 : /* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
           2                 : /* cairo - a vector graphics library with display and print output
           3                 :  *
           4                 :  * Copyright © 2002 University of Southern California
           5                 :  * Copyright © 2005 Red Hat, Inc.
           6                 :  * Copyright © 2007 Adrian Johnson
           7                 :  *
           8                 :  * This library is free software; you can redistribute it and/or
           9                 :  * modify it either under the terms of the GNU Lesser General Public
          10                 :  * License version 2.1 as published by the Free Software Foundation
          11                 :  * (the "LGPL") or, at your option, under the terms of the Mozilla
          12                 :  * Public License Version 1.1 (the "MPL"). If you do not alter this
          13                 :  * notice, a recipient may use your version of this file under either
          14                 :  * the MPL or the LGPL.
          15                 :  *
          16                 :  * You should have received a copy of the LGPL along with this library
          17                 :  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
          18                 :  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
          19                 :  * You should have received a copy of the MPL along with this library
          20                 :  * in the file COPYING-MPL-1.1
          21                 :  *
          22                 :  * The contents of this file are subject to the Mozilla Public License
          23                 :  * Version 1.1 (the "License"); you may not use this file except in
          24                 :  * compliance with the License. You may obtain a copy of the License at
          25                 :  * http://www.mozilla.org/MPL/
          26                 :  *
          27                 :  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
          28                 :  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
          29                 :  * the specific language governing rights and limitations.
          30                 :  *
          31                 :  * The Original Code is the cairo graphics library.
          32                 :  *
          33                 :  * The Initial Developer of the Original Code is University of Southern
          34                 :  * California.
          35                 :  *
          36                 :  * Contributor(s):
          37                 :  *      Carl D. Worth <cworth@cworth.org>
          38                 :  *      Adrian Johnson <ajohnson@redneon.com>
          39                 :  */
          40                 :
          41                 : #include "cairoint.h"
          42                 : #include "cairo-error-private.h"
          43                 :
          44                 : COMPILE_TIME_ASSERT (CAIRO_STATUS_LAST_STATUS < CAIRO_INT_STATUS_UNSUPPORTED);
          45                 : COMPILE_TIME_ASSERT (CAIRO_INT_STATUS_LAST_STATUS <= 127);
          46                 :
          47                 : /**
          48                 :  * SECTION:cairo-status
          49                 :  * @Title: Error handling
          50                 :  * @Short_Description: Decoding cairo's status
          51                 :  * @See_Also: cairo_status(), cairo_surface_status(), cairo_pattern_status(),
          52                 :  *            cairo_font_face_status(), cairo_scaled_font_status(),
          53                 :  *            cairo_region_status()
          54                 :  *
          55                 :  * Cairo uses a single status type to represent all kinds of errors.  A status
          56                 :  * value of %CAIRO_STATUS_SUCCESS represents no error and has an integer value
          57                 :  * of zero.  All other status values represent an error.
          58                 :  *
          59                 :  * Cairo's error handling is designed to be easy to use and safe.  All major
          60                 :  * cairo objects <firstterm>retain</firstterm> an error status internally which
          61                 :  * can be queried anytime by the users using cairo*_status() calls.  In
          62                 :  * the mean time, it is safe to call all cairo functions normally even if the
          63                 :  * underlying object is in an error status.  This means that no error handling
          64                 :  * code is required before or after each individual cairo function call.
          65                 :  */
          66                 :
          67                 : /* Public stuff */
          68                 :
          69                 : /**
          70                 :  * cairo_status_to_string:
          71                 :  * @status: a cairo status
          72                 :  *
          73                 :  * Provides a human-readable description of a #cairo_status_t.
          74                 :  *
          75                 :  * Returns: a string representation of the status
          76                 :  */
          77                 : const char *
          78               0 : cairo_status_to_string (cairo_status_t status)
          79                 : {
          80               0 :     switch (status) {
          81                 :     case CAIRO_STATUS_SUCCESS:
          82               0 :         return "no error has occurred";
          83                 :     case CAIRO_STATUS_NO_MEMORY:
          84               0 :         return "out of memory";
          85                 :     case CAIRO_STATUS_INVALID_RESTORE:
          86               0 :         return "cairo_restore() without matching cairo_save()";
          87                 :     case CAIRO_STATUS_INVALID_POP_GROUP:
          88               0 :         return "no saved group to pop, i.e. cairo_pop_group() without matching cairo_push_group()";
          89                 :     case CAIRO_STATUS_NO_CURRENT_POINT:
          90               0 :         return "no current point defined";
          91                 :     case CAIRO_STATUS_INVALID_MATRIX:
          92               0 :         return "invalid matrix (not invertible)";
          93                 :     case CAIRO_STATUS_INVALID_STATUS:
          94               0 :         return "invalid value for an input cairo_status_t";
          95                 :     case CAIRO_STATUS_NULL_POINTER:
          96               0 :         return "NULL pointer";
          97                 :     case CAIRO_STATUS_INVALID_STRING:
          98               0 :         return "input string not valid UTF-8";
          99                 :     case CAIRO_STATUS_INVALID_PATH_DATA:
         100               0 :         return "input path data not valid";
         101                 :     case CAIRO_STATUS_READ_ERROR:
         102               0 :         return "error while reading from input stream";
         103                 :     case CAIRO_STATUS_WRITE_ERROR:
         104               0 :         return "error while writing to output stream";
         105                 :     case CAIRO_STATUS_SURFACE_FINISHED:
         106               0 :         return "the target surface has been finished";
         107                 :     case CAIRO_STATUS_SURFACE_TYPE_MISMATCH:
         108               0 :         return "the surface type is not appropriate for the operation";
         109                 :     case CAIRO_STATUS_PATTERN_TYPE_MISMATCH:
         110               0 :         return "the pattern type is not appropriate for the operation";
         111                 :     case CAIRO_STATUS_INVALID_CONTENT:
         112               0 :         return "invalid value for an input cairo_content_t";
         113                 :     case CAIRO_STATUS_INVALID_FORMAT:
         114               0 :         return "invalid value for an input cairo_format_t";
         115                 :     case CAIRO_STATUS_INVALID_VISUAL:
         116               0 :         return "invalid value for an input Visual*";
         117                 :     case CAIRO_STATUS_FILE_NOT_FOUND:
         118               0 :         return "file not found";
         119                 :     case CAIRO_STATUS_INVALID_DASH:
         120               0 :         return "invalid value for a dash setting";
         121                 :     case CAIRO_STATUS_INVALID_DSC_COMMENT:
         122               0 :         return "invalid value for a DSC comment";
         123                 :     case CAIRO_STATUS_INVALID_INDEX:
         124               0 :         return "invalid index passed to getter";
         125                 :     case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE:
         126               0 :         return "clip region not representable in desired format";
         127                 :     case CAIRO_STATUS_TEMP_FILE_ERROR:
         128               0 :         return "error creating or writing to a temporary file";
         129                 :     case CAIRO_STATUS_INVALID_STRIDE:
         130               0 :         return "invalid value for stride";
         131                 :     case CAIRO_STATUS_FONT_TYPE_MISMATCH:
         132               0 :         return "the font type is not appropriate for the operation";
         133                 :     case CAIRO_STATUS_USER_FONT_IMMUTABLE:
         134               0 :         return "the user-font is immutable";
         135                 :     case CAIRO_STATUS_USER_FONT_ERROR:
         136               0 :         return "error occurred in a user-font callback function";
         137                 :     case CAIRO_STATUS_NEGATIVE_COUNT:
         138               0 :         return "negative number used where it is not allowed";
         139                 :     case CAIRO_STATUS_INVALID_CLUSTERS:
         140               0 :         return "input clusters do not represent the accompanying text and glyph arrays";
         141                 :     case CAIRO_STATUS_INVALID_SLANT:
         142               0 :         return "invalid value for an input cairo_font_slant_t";
         143                 :     case CAIRO_STATUS_INVALID_WEIGHT:
         144               0 :         return "invalid value for an input cairo_font_weight_t";
         145                 :     case CAIRO_STATUS_INVALID_SIZE:
         146               0 :         return "invalid value (typically too big) for the size of the input (surface, pattern, etc.)";
         147                 :     case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED:
         148               0 :         return "user-font method not implemented";
         149                 :     case CAIRO_STATUS_DEVICE_TYPE_MISMATCH:
         150               0 :         return "the device type is not appropriate for the operation";
         151                 :     case CAIRO_STATUS_DEVICE_ERROR:
         152               0 :         return "an operation to the device caused an unspecified error";
         153                 :     default:
         154                 :     case CAIRO_STATUS_LAST_STATUS:
         155               0 :         return "<unknown error status>";
         156                 :     }
         157                 : }
         158                 :
         159                 :
         160                 : /**
         161                 :  * cairo_glyph_allocate:
         162                 :  * @num_glyphs: number of glyphs to allocate
         163                 :  *
         164                 :  * Allocates an array of #cairo_glyph_t's.
         165                 :  * This function is only useful in implementations of
         166                 :  * #cairo_user_scaled_font_text_to_glyphs_func_t where the user
         167                 :  * needs to allocate an array of glyphs that cairo will free.
         168                 :  * For all other uses, user can use their own allocation method
         169                 :  * for glyphs.
         170                 :  *
         171                 :  * This function returns %NULL if @num_glyphs is not positive,
         172                 :  * or if out of memory.  That means, the %NULL return value
         173                 :  * signals out-of-memory only if @num_glyphs was positive.
         174                 :  *
         175                 :  * Returns: the newly allocated array of glyphs that should be
         176                 :  *          freed using cairo_glyph_free()
         177                 :  *
         178                 :  * Since: 1.8
         179                 :  */
         180                 : cairo_glyph_t *
         181               0 : cairo_glyph_allocate (int num_glyphs)
         182                 : {
         183               0 :     if (num_glyphs <= 0)
         184               0 :         return NULL;
         185                 :
         186               0 :     return _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
         187                 : }
         188                 : slim_hidden_def (cairo_glyph_allocate);
         189                 :
         190                 : /**
         191                 :  * cairo_glyph_free:
         192                 :  * @glyphs: array of glyphs to free, or %NULL
         193                 :  *
         194                 :  * Frees an array of #cairo_glyph_t's allocated using cairo_glyph_allocate().
         195                 :  * This function is only useful to free glyph array returned
         196                 :  * by cairo_scaled_font_text_to_glyphs() where cairo returns
         197                 :  * an array of glyphs that the user will free.
         198                 :  * For all other uses, user can use their own allocation method
         199                 :  * for glyphs.
         200                 :  *
         201                 :  * Since: 1.8
         202                 :  */
         203                 : void
         204               0 : cairo_glyph_free (cairo_glyph_t *glyphs)
         205                 : {
         206               0 :     if (glyphs)
         207               0 :         free (glyphs);
         208               0 : }
         209                 : slim_hidden_def (cairo_glyph_free);
         210                 :
         211                 : /**
         212                 :  * cairo_text_cluster_allocate:
         213                 :  * @num_clusters: number of text_clusters to allocate
         214                 :  *
         215                 :  * Allocates an array of #cairo_text_cluster_t's.
         216                 :  * This function is only useful in implementations of
         217                 :  * #cairo_user_scaled_font_text_to_glyphs_func_t where the user
         218                 :  * needs to allocate an array of text clusters that cairo will free.
         219                 :  * For all other uses, user can use their own allocation method
         220                 :  * for text clusters.
         221                 :  *
         222                 :  * This function returns %NULL if @num_clusters is not positive,
         223                 :  * or if out of memory.  That means, the %NULL return value
         224                 :  * signals out-of-memory only if @num_clusters was positive.
         225                 :  *
         226                 :  * Returns: the newly allocated array of text clusters that should be
         227                 :  *          freed using cairo_text_cluster_free()
         228                 :  *
         229                 :  * Since: 1.8
         230                 :  */
         231                 : cairo_text_cluster_t *
         232               0 : cairo_text_cluster_allocate (int num_clusters)
         233                 : {
         234               0 :     if (num_clusters <= 0)
         235               0 :         return NULL;
         236                 :
         237               0 :     return _cairo_malloc_ab (num_clusters, sizeof (cairo_text_cluster_t));
         238                 : }
         239                 : slim_hidden_def (cairo_text_cluster_allocate);
         240                 :
         241                 : /**
         242                 :  * cairo_text_cluster_free:
         243                 :  * @clusters: array of text clusters to free, or %NULL
         244                 :  *
         245                 :  * Frees an array of #cairo_text_cluster's allocated using cairo_text_cluster_allocate().
         246                 :  * This function is only useful to free text cluster array returned
         247                 :  * by cairo_scaled_font_text_to_glyphs() where cairo returns
         248                 :  * an array of text clusters that the user will free.
         249                 :  * For all other uses, user can use their own allocation method
         250                 :  * for text clusters.
         251                 :  *
         252                 :  * Since: 1.8
         253                 :  */
         254                 : void
         255               0 : cairo_text_cluster_free (cairo_text_cluster_t *clusters)
         256                 : {
         257               0 :     if (clusters)
         258               0 :         free (clusters);
         259               0 : }
         260                 : slim_hidden_def (cairo_text_cluster_free);
         261                 :
         262                 :
         263                 : /* Private stuff */
         264                 :
         265                 : /**
         266                 :  * _cairo_validate_text_clusters:
         267                 :  * @utf8: UTF-8 text
         268                 :  * @utf8_len: length of @utf8 in bytes
         269                 :  * @glyphs: array of glyphs
         270                 :  * @num_glyphs: number of glyphs
         271                 :  * @clusters: array of cluster mapping information
         272                 :  * @num_clusters: number of clusters in the mapping
         273                 :  * @cluster_flags: cluster flags
         274                 :  *
         275                 :  * Check that clusters cover the entire glyphs and utf8 arrays,
         276                 :  * and that cluster boundaries are UTF-8 boundaries.
         277                 :  *
         278                 :  * Return value: %CAIRO_STATUS_SUCCESS upon success, or
         279                 :  *               %CAIRO_STATUS_INVALID_CLUSTERS on error.
         280                 :  *               The error is either invalid UTF-8 input,
         281                 :  *               or bad cluster mapping.
         282                 :  */
         283                 : cairo_status_t
         284               0 : _cairo_validate_text_clusters (const char                  *utf8,
         285                 :                                int                          utf8_len,
         286                 :                                const cairo_glyph_t         *glyphs,
         287                 :                                int                          num_glyphs,
         288                 :                                const cairo_text_cluster_t  *clusters,
         289                 :                                int                          num_clusters,
         290                 :                                cairo_text_cluster_flags_t   cluster_flags)
         291                 : {
         292                 :     cairo_status_t status;
         293               0 :     unsigned int n_bytes  = 0;
         294               0 :     unsigned int n_glyphs = 0;
         295                 :     int i;
         296                 :
         297               0 :     for (i = 0; i < num_clusters; i++) {
         298               0 :         int cluster_bytes  = clusters[i].num_bytes;
         299               0 :         int cluster_glyphs = clusters[i].num_glyphs;
         300                 :
         301               0 :         if (cluster_bytes < 0 || cluster_glyphs < 0)
         302                 :             goto BAD;
         303                 :
         304                 :         /* A cluster should cover at least one character or glyph.
         305                 :          * I can't see any use for a 0,0 cluster.
         306                 :          * I can't see an immediate use for a zero-text cluster
         307                 :          * right now either, but they don't harm.
         308                 :          * Zero-glyph clusters on the other hand are useful for
         309                 :          * things like U+200C ZERO WIDTH NON-JOINER */
         310               0 :         if (cluster_bytes == 0 && cluster_glyphs == 0)
         311               0 :             goto BAD;
         312                 :
         313                 :         /* Since n_bytes and n_glyphs are unsigned, but the rest of
         314                 :          * values involved are signed, we can detect overflow easily */
         315               0 :         if (n_bytes+cluster_bytes > (unsigned int)utf8_len || n_glyphs+cluster_glyphs > (unsigned int)num_glyphs)
         316                 :             goto BAD;
         317                 :
         318                 :         /* Make sure we've got valid UTF-8 for the cluster */
         319               0 :         status = _cairo_utf8_to_ucs4 (utf8+n_bytes, cluster_bytes, NULL, NULL);
         320               0 :         if (unlikely (status))
         321               0 :             return _cairo_error (CAIRO_STATUS_INVALID_CLUSTERS);
         322                 :
         323               0 :         n_bytes  += cluster_bytes ;
         324               0 :         n_glyphs += cluster_glyphs;
         325                 :     }
         326                 :
         327               0 :     if (n_bytes != (unsigned int) utf8_len || n_glyphs != (unsigned int) num_glyphs) {
         328                 :       BAD:
         329               0 :         return _cairo_error (CAIRO_STATUS_INVALID_CLUSTERS);
         330                 :     }
         331                 :
         332               0 :     return CAIRO_STATUS_SUCCESS;
         333                 : }
         334                 :
         335                 : /**
         336                 :  * _cairo_operator_bounded_by_mask:
         337                 :  * @op: a #cairo_operator_t
         338                 :  *
         339                 :  * A bounded operator is one where mask pixel
         340                 :  * of zero results in no effect on the destination image.
         341                 :  *
         342                 :  * Unbounded operators often require special handling; if you, for
         343                 :  * example, draw trapezoids with an unbounded operator, the effect
         344                 :  * extends past the bounding box of the trapezoids.
         345                 :  *
         346                 :  * Return value: %TRUE if the operator is bounded by the mask operand
         347                 :  **/
         348                 : cairo_bool_t
         349               0 : _cairo_operator_bounded_by_mask (cairo_operator_t op)
         350                 : {
         351               0 :     switch (op) {
         352                 :     case CAIRO_OPERATOR_CLEAR:
         353                 :     case CAIRO_OPERATOR_SOURCE:
         354                 :     case CAIRO_OPERATOR_OVER:
         355                 :     case CAIRO_OPERATOR_ATOP:
         356                 :     case CAIRO_OPERATOR_DEST:
         357                 :     case CAIRO_OPERATOR_DEST_OVER:
         358                 :     case CAIRO_OPERATOR_DEST_OUT:
         359                 :     case CAIRO_OPERATOR_XOR:
         360                 :     case CAIRO_OPERATOR_ADD:
         361                 :     case CAIRO_OPERATOR_SATURATE:
         362                 :     case CAIRO_OPERATOR_MULTIPLY:
         363                 :     case CAIRO_OPERATOR_SCREEN:
         364                 :     case CAIRO_OPERATOR_OVERLAY:
         365                 :     case CAIRO_OPERATOR_DARKEN:
         366                 :     case CAIRO_OPERATOR_LIGHTEN:
         367                 :     case CAIRO_OPERATOR_COLOR_DODGE:
         368                 :     case CAIRO_OPERATOR_COLOR_BURN:
         369                 :     case CAIRO_OPERATOR_HARD_LIGHT:
         370                 :     case CAIRO_OPERATOR_SOFT_LIGHT:
         371                 :     case CAIRO_OPERATOR_DIFFERENCE:
         372                 :     case CAIRO_OPERATOR_EXCLUSION:
         373                 :     case CAIRO_OPERATOR_HSL_HUE:
         374                 :     case CAIRO_OPERATOR_HSL_SATURATION:
         375                 :     case CAIRO_OPERATOR_HSL_COLOR:
         376                 :     case CAIRO_OPERATOR_HSL_LUMINOSITY:
         377               0 :         return TRUE;
         378                 :     case CAIRO_OPERATOR_OUT:
         379                 :     case CAIRO_OPERATOR_IN:
         380                 :     case CAIRO_OPERATOR_DEST_IN:
         381                 :     case CAIRO_OPERATOR_DEST_ATOP:
         382               0 :         return FALSE;
         383                 :     }
         384                 :
         385               0 :     ASSERT_NOT_REACHED;
         386               0 :     return FALSE;
         387                 : }
         388                 :
         389                 : /**
         390                 :  * _cairo_operator_bounded_by_source:
         391                 :  * @op: a #cairo_operator_t
         392                 :  *
         393                 :  * A bounded operator is one where source pixels of zero
         394                 :  * (in all four components, r, g, b and a) effect no change
         395                 :  * in the resulting destination image.
         396                 :  *
         397                 :  * Unbounded operators often require special handling; if you, for
         398                 :  * example, copy a surface with the SOURCE operator, the effect
         399                 :  * extends past the bounding box of the source surface.
         400                 :  *
         401                 :  * Return value: %TRUE if the operator is bounded by the source operand
         402                 :  **/
         403                 : cairo_bool_t
         404               0 : _cairo_operator_bounded_by_source (cairo_operator_t op)
         405                 : {
         406               0 :     switch (op) {
         407                 :     case CAIRO_OPERATOR_OVER:
         408                 :     case CAIRO_OPERATOR_ATOP:
         409                 :     case CAIRO_OPERATOR_DEST:
         410                 :     case CAIRO_OPERATOR_DEST_OVER:
         411                 :     case CAIRO_OPERATOR_DEST_OUT:
         412                 :     case CAIRO_OPERATOR_XOR:
         413                 :     case CAIRO_OPERATOR_ADD:
         414                 :     case CAIRO_OPERATOR_SATURATE:
         415                 :     case CAIRO_OPERATOR_MULTIPLY:
         416                 :     case CAIRO_OPERATOR_SCREEN:
         417                 :     case CAIRO_OPERATOR_OVERLAY:
         418                 :     case CAIRO_OPERATOR_DARKEN:
         419                 :     case CAIRO_OPERATOR_LIGHTEN:
         420                 :     case CAIRO_OPERATOR_COLOR_DODGE:
         421                 :     case CAIRO_OPERATOR_COLOR_BURN:
         422                 :     case CAIRO_OPERATOR_HARD_LIGHT:
         423                 :     case CAIRO_OPERATOR_SOFT_LIGHT:
         424                 :     case CAIRO_OPERATOR_DIFFERENCE:
         425                 :     case CAIRO_OPERATOR_EXCLUSION:
         426                 :     case CAIRO_OPERATOR_HSL_HUE:
         427                 :     case CAIRO_OPERATOR_HSL_SATURATION:
         428                 :     case CAIRO_OPERATOR_HSL_COLOR:
         429                 :     case CAIRO_OPERATOR_HSL_LUMINOSITY:
         430               0 :         return TRUE;
         431                 :     case CAIRO_OPERATOR_CLEAR:
         432                 :     case CAIRO_OPERATOR_SOURCE:
         433                 :     case CAIRO_OPERATOR_OUT:
         434                 :     case CAIRO_OPERATOR_IN:
         435                 :     case CAIRO_OPERATOR_DEST_IN:
         436                 :     case CAIRO_OPERATOR_DEST_ATOP:
         437               0 :         return FALSE;
         438                 :     }
         439                 :
         440               0 :     ASSERT_NOT_REACHED;
         441               0 :     return FALSE;
         442                 : }
         443                 :
         444                 : uint32_t
         445              64 : _cairo_operator_bounded_by_either (cairo_operator_t op)
         446                 : {
         447              64 :     switch (op) {
         448                 :     default:
         449               0 :         ASSERT_NOT_REACHED;
         450                 :     case CAIRO_OPERATOR_OVER:
         451                 :     case CAIRO_OPERATOR_ATOP:
         452                 :     case CAIRO_OPERATOR_DEST:
         453                 :     case CAIRO_OPERATOR_DEST_OVER:
         454                 :     case CAIRO_OPERATOR_DEST_OUT:
         455                 :     case CAIRO_OPERATOR_XOR:
         456                 :     case CAIRO_OPERATOR_ADD:
         457                 :     case CAIRO_OPERATOR_SATURATE:
         458                 :     case CAIRO_OPERATOR_MULTIPLY:
         459                 :     case CAIRO_OPERATOR_SCREEN:
         460                 :     case CAIRO_OPERATOR_OVERLAY:
         461                 :     case CAIRO_OPERATOR_DARKEN:
         462                 :     case CAIRO_OPERATOR_LIGHTEN:
         463                 :     case CAIRO_OPERATOR_COLOR_DODGE:
         464                 :     case CAIRO_OPERATOR_COLOR_BURN:
         465                 :     case CAIRO_OPERATOR_HARD_LIGHT:
         466                 :     case CAIRO_OPERATOR_SOFT_LIGHT:
         467                 :     case CAIRO_OPERATOR_DIFFERENCE:
         468                 :     case CAIRO_OPERATOR_EXCLUSION:
         469                 :     case CAIRO_OPERATOR_HSL_HUE:
         470                 :     case CAIRO_OPERATOR_HSL_SATURATION:
         471                 :     case CAIRO_OPERATOR_HSL_COLOR:
         472                 :     case CAIRO_OPERATOR_HSL_LUMINOSITY:
         473               0 :         return CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE;
         474                 :     case CAIRO_OPERATOR_CLEAR:
         475                 :     case CAIRO_OPERATOR_SOURCE:
         476              64 :         return CAIRO_OPERATOR_BOUND_BY_MASK;
         477                 :     case CAIRO_OPERATOR_OUT:
         478                 :     case CAIRO_OPERATOR_IN:
         479                 :     case CAIRO_OPERATOR_DEST_IN:
         480                 :     case CAIRO_OPERATOR_DEST_ATOP:
         481               0 :         return 0;
         482                 :     }
         483                 :
         484                 : }
         485                 :
         486                 : #if DISABLE_SOME_FLOATING_POINT || __STDC_VERSION__ < 199901L
         487                 : /* This function is identical to the C99 function lround(), except that it
         488                 :  * performs arithmetic rounding (floor(d + .5) instead of away-from-zero rounding) and
         489                 :  * has a valid input range of (INT_MIN, INT_MAX] instead of
         490                 :  * [INT_MIN, INT_MAX]. It is much faster on both x86 and FPU-less systems
         491                 :  * than other commonly used methods for rounding (lround, round, rint, lrint
         492                 :  * or float (d + 0.5)).
         493                 :  *
         494                 :  * The reason why this function is much faster on x86 than other
         495                 :  * methods is due to the fact that it avoids the fldcw instruction.
         496                 :  * This instruction incurs a large performance penalty on modern Intel
         497                 :  * processors due to how it prevents efficient instruction pipelining.
         498                 :  *
         499                 :  * The reason why this function is much faster on FPU-less systems is for
         500                 :  * an entirely different reason. All common rounding methods involve multiple
         501                 :  * floating-point operations. Each one of these operations has to be
         502                 :  * emulated in software, which adds up to be a large performance penalty.
         503                 :  * This function doesn't perform any floating-point calculations, and thus
         504                 :  * avoids this penalty.
         505                 :   */
         506                 : int
         507               0 : _cairo_lround (double d)
         508                 : {
         509                 :     uint32_t top, shift_amount, output;
         510                 :     union {
         511                 :         double d;
         512                 :         uint64_t ui64;
         513                 :         uint32_t ui32[2];
         514                 :     } u;
         515                 :
         516               0 :     u.d = d;
         517                 :
         518                 :     /* If the integer word order doesn't match the float word order, we swap
         519                 :      * the words of the input double. This is needed because we will be
         520                 :      * treating the whole double as a 64-bit unsigned integer. Notice that we
         521                 :      * use WORDS_BIGENDIAN to detect the integer word order, which isn't
         522                 :      * exactly correct because WORDS_BIGENDIAN refers to byte order, not word
         523                 :      * order. Thus, we are making the assumption that the byte order is the
         524                 :      * same as the integer word order which, on the modern machines that we
         525                 :      * care about, is OK.
         526                 :      */
         527                 : #if ( defined(FLOAT_WORDS_BIGENDIAN) && !defined(WORDS_BIGENDIAN)) || \
         528                 :     (!defined(FLOAT_WORDS_BIGENDIAN) &&  defined(WORDS_BIGENDIAN))
         529                 :     {
         530                 :         uint32_t temp = u.ui32[0];
         531                 :         u.ui32[0] = u.ui32[1];
         532                 :         u.ui32[1] = temp;
         533                 :     }
         534                 : #endif
         535                 :
         536                 : #ifdef WORDS_BIGENDIAN
         537                 :     #define MSW (0) /* Most Significant Word */
         538                 :     #define LSW (1) /* Least Significant Word */
         539                 : #else
         540                 :     #define MSW (1)
         541                 :     #define LSW (0)
         542                 : #endif
         543                 :
         544                 :     /* By shifting the most significant word of the input double to the
         545                 :      * right 20 places, we get the very "top" of the double where the exponent
         546                 :      * and sign bit lie.
         547                 :      */
         548               0 :     top = u.ui32[MSW] >> 20;
         549                 :
         550                 :     /* Here, we calculate how much we have to shift the mantissa to normalize
         551                 :      * it to an integer value. We extract the exponent "top" by masking out the
         552                 :      * sign bit, then we calculate the shift amount by subtracting the exponent
         553                 :      * from the bias. Notice that the correct bias for 64-bit doubles is
         554                 :      * actually 1075, but we use 1053 instead for two reasons:
         555                 :      *
         556                 :      *  1) To perform rounding later on, we will first need the target
         557                 :      *     value in a 31.1 fixed-point format. Thus, the bias needs to be one
         558                 :      *     less: (1075 - 1: 1074).
         559                 :      *
         560                 :      *  2) To avoid shifting the mantissa as a full 64-bit integer (which is
         561                 :      *     costly on certain architectures), we break the shift into two parts.
         562                 :      *     First, the upper and lower parts of the mantissa are shifted
         563                 :      *     individually by a constant amount that all valid inputs will require
         564                 :      *     at the very least. This amount is chosen to be 21, because this will
         565                 :      *     allow the two parts of the mantissa to later be combined into a
         566                 :      *     single 32-bit representation, on which the remainder of the shift
         567                 :      *     will be performed. Thus, we decrease the bias by an additional 21:
         568                 :      *     (1074 - 21: 1053).
         569                 :      */
         570               0 :     shift_amount = 1053 - (top & 0x7FF);
         571                 :
         572                 :     /* We are done with the exponent portion in "top", so here we shift it off
         573                 :      * the end.
         574                 :      */
         575               0 :     top >>= 11;
         576                 :
         577                 :     /* Before we perform any operations on the mantissa, we need to OR in
         578                 :      * the implicit 1 at the top (see the IEEE-754 spec). We needn't mask
         579                 :      * off the sign bit nor the exponent bits because these higher bits won't
         580                 :      * make a bit of difference in the rest of our calculations.
         581                 :      */
         582               0 :     u.ui32[MSW] |= 0x100000;
         583                 :
         584                 :     /* If the input double is negative, we have to decrease the mantissa
         585                 :      * by a hair. This is an important part of performing arithmetic rounding,
         586                 :      * as negative numbers must round towards positive infinity in the
         587                 :      * halfwase case of -x.5. Since "top" contains only the sign bit at this
         588                 :      * point, we can just decrease the mantissa by the value of "top".
         589                 :      */
         590               0 :     u.ui64 -= top;
         591                 :
         592                 :     /* By decrementing "top", we create a bitmask with a value of either
         593                 :      * 0x0 (if the input was negative) or 0xFFFFFFFF (if the input was positive
         594                 :      * and thus the unsigned subtraction underflowed) that we'll use later.
         595                 :      */
         596               0 :     top--;
         597                 :
         598                 :     /* Here, we shift the mantissa by the constant value as described above.
         599                 :      * We can emulate a 64-bit shift right by 21 through shifting the top 32
         600                 :      * bits left 11 places and ORing in the bottom 32 bits shifted 21 places
         601                 :      * to the right. Both parts of the mantissa are now packed into a single
         602                 :      * 32-bit integer. Although we severely truncate the lower part in the
         603                 :      * process, we still have enough significant bits to perform the conversion
         604                 :      * without error (for all valid inputs).
         605                 :      */
         606               0 :     output = (u.ui32[MSW] << 11) | (u.ui32[LSW] >> 21);
         607                 :
         608                 :     /* Next, we perform the shift that converts the X.Y fixed-point number
         609                 :      * currently found in "output" to the desired 31.1 fixed-point format
         610                 :      * needed for the following rounding step. It is important to consider
         611                 :      * all possible values for "shift_amount" at this point:
         612                 :      *
         613                 :      * - {shift_amount < 0} Since shift_amount is an unsigned integer, it
         614                 :      *   really can't have a value less than zero. But, if the shift_amount
         615                 :      *   calculation above caused underflow (which would happen with
         616                 :      *   input > INT_MAX or input <= INT_MIN) then shift_amount will now be
         617                 :      *   a very large number, and so this shift will result in complete
         618                 :      *   garbage. But that's OK, as the input was out of our range, so our
         619                 :      *   output is undefined.
         620                 :      *
         621                 :      * - {shift_amount > 31} If the magnitude of the input was very small
         622                 :      *   (i.e. |input| << 1.0), shift_amount will have a value greater than
         623                 :      *   31. Thus, this shift will also result in garbage. After performing
         624                 :      *   the shift, we will zero-out "output" if this is the case.
         625                 :      *
         626                 :      * - {0 <= shift_amount < 32} In this case, the shift will properly convert
         627                 :      *   the mantissa into a 31.1 fixed-point number.
         628                 :      */
         629               0 :     output >>= shift_amount;
         630                 :
         631                 :     /* This is where we perform rounding with the 31.1 fixed-point number.
         632                 :      * Since what we're after is arithmetic rounding, we simply add the single
         633                 :      * fractional bit into the integer part of "output", and just keep the
         634                 :      * integer part.
         635                 :      */
         636               0 :     output = (output >> 1) + (output & 1);
         637                 :
         638                 :     /* Here, we zero-out the result if the magnitude if the input was very small
         639                 :      * (as explained in the section above). Notice that all input out of the
         640                 :      * valid range is also caught by this condition, which means we produce 0
         641                 :      * for all invalid input, which is a nice side effect.
         642                 :      *
         643                 :      * The most straightforward way to do this would be:
         644                 :      *
         645                 :      *      if (shift_amount > 31)
         646                 :      *          output = 0;
         647                 :      *
         648                 :      * But we can use a little trick to avoid the potential branch. The
         649                 :      * expression (shift_amount > 31) will be either 1 or 0, which when
         650                 :      * decremented will be either 0x0 or 0xFFFFFFFF (unsigned underflow),
         651                 :      * which can be used to conditionally mask away all the bits in "output"
         652                 :      * (in the 0x0 case), effectively zeroing it out. Certain, compilers would
         653                 :      * have done this for us automatically.
         654                 :      */
         655               0 :     output &= ((shift_amount > 31) - 1);
         656                 :
         657                 :     /* If the input double was a negative number, then we have to negate our
         658                 :      * output. The most straightforward way to do this would be:
         659                 :      *
         660                 :      *      if (!top)
         661                 :      *          output = -output;
         662                 :      *
         663                 :      * as "top" at this point is either 0x0 (if the input was negative) or
         664                 :      * 0xFFFFFFFF (if the input was positive). But, we can use a trick to
         665                 :      * avoid the branch. Observe that the following snippet of code has the
         666                 :      * same effect as the reference snippet above:
         667                 :      *
         668                 :      *      if (!top)
         669                 :      *          output = 0 - output;
         670                 :      *      else
         671                 :      *          output = output - 0;
         672                 :      *
         673                 :      * Armed with the bitmask found in "top", we can condense the two statements
         674                 :      * into the following:
         675                 :      *
         676                 :      *      output = (output & top) - (output & ~top);
         677                 :      *
         678                 :      * where, in the case that the input double was negative, "top" will be 0,
         679                 :      * and the statement will be equivalent to:
         680                 :      *
         681                 :      *      output = (0) - (output);
         682                 :      *
         683                 :      * and if the input double was positive, "top" will be 0xFFFFFFFF, and the
         684                 :      * statement will be equivalent to:
         685                 :      *
         686                 :      *      output = (output) - (0);
         687                 :      *
         688                 :      * Which, as pointed out earlier, is equivalent to the original reference
         689                 :      * snippet.
         690                 :      */
         691               0 :     output = (output & top) - (output & ~top);
         692                 :
         693               0 :     return output;
         694                 : #undef MSW
         695                 : #undef LSW
         696                 : }
         697                 : #endif
         698                 :
         699                 : /* Convert a 32-bit IEEE single precision floating point number to a
         700                 :  * 'half' representation (s10.5)
         701                 :  */
         702                 : uint16_t
         703               0 : _cairo_half_from_float (float f)
         704                 : {
         705                 :     union {
         706                 :         uint32_t ui;
         707                 :         float f;
         708                 :     } u;
         709                 :     int s, e, m;
         710                 :
         711               0 :     u.f = f;
         712               0 :     s =  (u.ui >> 16) & 0x00008000;
         713               0 :     e = ((u.ui >> 23) & 0x000000ff) - (127 - 15);
         714               0 :     m =   u.ui        & 0x007fffff;
         715               0 :     if (e <= 0) {
         716               0 :         if (e < -10) {
         717                 :             /* underflow */
         718               0 :             return 0;
         719                 :         }
         720                 :
         721               0 :         m = (m | 0x00800000) >> (1 - e);
         722                 :
         723                 :         /* round to nearest, round 0.5 up. */
         724               0 :         if (m &  0x00001000)
         725               0 :             m += 0x00002000;
         726               0 :         return s | (m >> 13);
         727               0 :     } else if (e == 0xff - (127 - 15)) {
         728               0 :         if (m == 0) {
         729                 :             /* infinity */
         730               0 :             return s | 0x7c00;
         731                 :         } else {
         732                 :             /* nan */
         733               0 :             m >>= 13;
         734               0 :             return s | 0x7c00 | m | (m == 0);
         735                 :         }
         736                 :     } else {
         737                 :         /* round to nearest, round 0.5 up. */
         738               0 :         if (m &  0x00001000) {
         739               0 :             m += 0x00002000;
         740                 :
         741               0 :             if (m & 0x00800000) {
         742               0 :                 m =  0;
         743               0 :                 e += 1;
         744                 :             }
         745                 :         }
         746                 :
         747               0 :         if (e > 30) {
         748                 :             /* overflow -> infinity */
         749               0 :             return s | 0x7c00;
         750                 :         }
         751                 :
         752               0 :         return s | (e << 10) | (m >> 13);
         753                 :     }
         754                 : }
         755                 :
         756                 :
         757                 : #ifdef _WIN32
         758                 :
         759                 : #define WIN32_LEAN_AND_MEAN
         760                 : /* We require Windows 2000 features such as ETO_PDY */
         761                 : #if !defined(WINVER) || (WINVER < 0x0500)
         762                 : # define WINVER 0x0500
         763                 : #endif
         764                 : #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
         765                 : # define _WIN32_WINNT 0x0500
         766                 : #endif
         767                 :
         768                 : #include <windows.h>
         769                 : #include <io.h>
         770                 :
         771                 : #if !_WIN32_WCE
         772                 : /* tmpfile() replacement for Windows.
         773                 :  *
         774                 :  * On Windows tmpfile() creates the file in the root directory. This
         775                 :  * may fail due to unsufficient privileges. However, this isn't a
         776                 :  * problem on Windows CE so we don't use it there.
         777                 :  */
         778                 : FILE *
         779                 : _cairo_win32_tmpfile (void)
         780                 : {
         781                 :     DWORD path_len;
         782                 :     WCHAR path_name[MAX_PATH + 1];
         783                 :     WCHAR file_name[MAX_PATH + 1];
         784                 :     HANDLE handle;
         785                 :     int fd;
         786                 :     FILE *fp;
         787                 :
         788                 :     path_len = GetTempPathW (MAX_PATH, path_name);
         789                 :     if (path_len <= 0 || path_len >= MAX_PATH)
         790                 :         return NULL;
         791                 :
         792                 :     if (GetTempFileNameW (path_name, L"ps_", 0, file_name) == 0)
         793                 :         return NULL;
         794                 :
         795                 :     handle = CreateFileW (file_name,
         796                 :                          GENERIC_READ | GENERIC_WRITE,
         797                 :                          0,
         798                 :                          NULL,
         799                 :                          CREATE_ALWAYS,
         800                 :                          FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
         801                 :                          NULL);
         802                 :     if (handle == INVALID_HANDLE_VALUE) {
         803                 :         DeleteFileW (file_name);
         804                 :         return NULL;
         805                 :     }
         806                 :
         807                 :     fd = _open_osfhandle((intptr_t) handle, 0);
         808                 :     if (fd < 0) {
         809                 :         CloseHandle (handle);
         810                 :         return NULL;
         811                 :     }
         812                 :
         813                 :     fp = fdopen(fd, "w+b");
         814                 :     if (fp == NULL) {
         815                 :         _close(fd);
         816                 :         return NULL;
         817                 :     }
         818                 :
         819                 :     return fp;
         820                 : }
         821                 : #endif /* !_WIN32_WCE */
         822                 :
         823                 : #endif /* _WIN32 */
         824                 :
         825                 : typedef struct _cairo_intern_string {
         826                 :     cairo_hash_entry_t hash_entry;
         827                 :     int len;
         828                 :     char *string;
         829                 : } cairo_intern_string_t;
         830                 :
         831                 : static cairo_hash_table_t *_cairo_intern_string_ht;
         832                 :
         833                 : static unsigned long
         834               0 : _intern_string_hash (const char *str, int len)
         835                 : {
         836               0 :     const signed char *p = (const signed char *) str;
         837               0 :     unsigned int h = *p;
         838                 :
         839               0 :     for (p += 1; --len; p++)
         840               0 :         h = (h << 5) - h + *p;
         841                 :
         842               0 :     return h;
         843                 : }
         844                 :
         845                 : static cairo_bool_t
         846               0 : _intern_string_equal (const void *_a, const void *_b)
         847                 : {
         848               0 :     const cairo_intern_string_t *a = _a;
         849               0 :     const cairo_intern_string_t *b = _b;
         850                 :
         851               0 :     if (a->len != b->len)
         852               0 :         return FALSE;
         853                 :
         854               0 :     return memcmp (a->string, b->string, a->len) == 0;
         855                 : }
         856                 :
         857                 : cairo_status_t
         858               0 : _cairo_intern_string (const char **str_inout, int len)
         859                 : {
         860               0 :     char *str = (char *) *str_inout;
         861                 :     cairo_intern_string_t tmpl, *istring;
         862               0 :     cairo_status_t status = CAIRO_STATUS_SUCCESS;
         863                 :
         864                 :     if (CAIRO_INJECT_FAULT ())
         865                 :         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
         866                 :
         867               0 :     if (len < 0)
         868               0 :         len = strlen (str);
         869               0 :     tmpl.hash_entry.hash = _intern_string_hash (str, len);
         870               0 :     tmpl.len = len;
         871               0 :     tmpl.string = (char *) str;
         872                 :
         873                 :     CAIRO_MUTEX_LOCK (_cairo_intern_string_mutex);
         874               0 :     if (_cairo_intern_string_ht == NULL) {
         875               0 :         _cairo_intern_string_ht = _cairo_hash_table_create (_intern_string_equal);
         876               0 :         if (unlikely (_cairo_intern_string_ht == NULL)) {
         877               0 :             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
         878               0 :             goto BAIL;
         879                 :         }
         880                 :     }
         881                 :
         882               0 :     istring = _cairo_hash_table_lookup (_cairo_intern_string_ht,
         883                 :                                         &tmpl.hash_entry);
         884               0 :     if (istring == NULL) {
         885               0 :         istring = malloc (sizeof (cairo_intern_string_t) + len + 1);
         886               0 :         if (likely (istring != NULL)) {
         887               0 :             istring->hash_entry.hash = tmpl.hash_entry.hash;
         888               0 :             istring->len = tmpl.len;
         889               0 :             istring->string = (char *) (istring + 1);
         890               0 :             memcpy (istring->string, str, len);
         891               0 :             istring->string[len] = '\0';
         892                 :
         893               0 :             status = _cairo_hash_table_insert (_cairo_intern_string_ht,
         894                 :                                                &istring->hash_entry);
         895               0 :             if (unlikely (status)) {
         896               0 :                 free (istring);
         897               0 :                 goto BAIL;
         898                 :             }
         899                 :         } else {
         900               0 :             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
         901               0 :             goto BAIL;
         902                 :         }
         903                 :     }
         904                 :
         905               0 :     *str_inout = istring->string;
         906                 :
         907                 :   BAIL:
         908                 :     CAIRO_MUTEX_UNLOCK (_cairo_intern_string_mutex);
         909               0 :     return status;
         910                 : }
         911                 :
         912                 : static void
         913               0 : _intern_string_pluck (void *entry, void *closure)
         914                 : {
         915               0 :     _cairo_hash_table_remove (closure, entry);
         916               0 :     free (entry);
         917               0 : }
         918                 :
         919                 : void
         920               3 : _cairo_intern_string_reset_static_data (void)
         921                 : {
         922                 :     CAIRO_MUTEX_LOCK (_cairo_intern_string_mutex);
         923               3 :     if (_cairo_intern_string_ht != NULL) {
         924               0 :         _cairo_hash_table_foreach (_cairo_intern_string_ht,
         925                 :                                    _intern_string_pluck,
         926                 :                                    _cairo_intern_string_ht);
         927               0 :         _cairo_hash_table_destroy(_cairo_intern_string_ht);
         928               0 :         _cairo_intern_string_ht = NULL;
         929                 :     }
         930                 :     CAIRO_MUTEX_UNLOCK (_cairo_intern_string_mutex);
         931               3 : }

Generated by: LCOV version 1.7