LCOV - code coverage report
Current view: top level - gfx/cairo/cairo/src - cairo-misc.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 172 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 15 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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           0 : _cairo_operator_bounded_by_either (cairo_operator_t op)
     446             : {
     447           0 :     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           0 :         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             : _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             :     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             :     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             :     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             :     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             :     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             :     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             :     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             :     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             :     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             :     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             :     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             :     output = (output & top) - (output & ~top);
     692             : 
     693             :     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           0 :     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           0 :     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           0 : _cairo_intern_string_reset_static_data (void)
     921             : {
     922           0 :     CAIRO_MUTEX_LOCK (_cairo_intern_string_mutex);
     923           0 :     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           0 :     CAIRO_MUTEX_UNLOCK (_cairo_intern_string_mutex);
     931           0 : }

Generated by: LCOV version 1.13