LCOV - code coverage report
Current view: top level - gfx/harfbuzz/src - hb-shaper.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 7 32 21.9 %
Date: 2017-07-14 16:53:18 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright © 2012  Google, Inc.
       3             :  *
       4             :  *  This is part of HarfBuzz, a text shaping library.
       5             :  *
       6             :  * Permission is hereby granted, without written agreement and without
       7             :  * license or royalty fees, to use, copy, modify, and distribute this
       8             :  * software and its documentation for any purpose, provided that the
       9             :  * above copyright notice and the following two paragraphs appear in
      10             :  * all copies of this software.
      11             :  *
      12             :  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
      13             :  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
      14             :  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
      15             :  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
      16             :  * DAMAGE.
      17             :  *
      18             :  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
      19             :  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
      20             :  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
      21             :  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
      22             :  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
      23             :  *
      24             :  * Google Author(s): Behdad Esfahbod
      25             :  */
      26             : 
      27             : #include "hb-private.hh"
      28             : #include "hb-shaper-private.hh"
      29             : #include "hb-atomic-private.hh"
      30             : 
      31             : 
      32             : static const hb_shaper_pair_t all_shapers[] = {
      33             : #define HB_SHAPER_IMPLEMENT(name) {#name, _hb_##name##_shape},
      34             : #include "hb-shaper-list.hh"
      35             : #undef HB_SHAPER_IMPLEMENT
      36             : };
      37             : 
      38             : 
      39             : /* Thread-safe, lock-free, shapers */
      40             : 
      41             : static const hb_shaper_pair_t *static_shapers;
      42             : 
      43             : #ifdef HB_USE_ATEXIT
      44             : static
      45             : void free_static_shapers (void)
      46             : {
      47             :   if (unlikely (static_shapers != all_shapers))
      48             :     free ((void *) static_shapers);
      49             : }
      50             : #endif
      51             : 
      52             : const hb_shaper_pair_t *
      53           2 : _hb_shapers_get (void)
      54             : {
      55             : retry:
      56           2 :   hb_shaper_pair_t *shapers = (hb_shaper_pair_t *) hb_atomic_ptr_get (&static_shapers);
      57             : 
      58           2 :   if (unlikely (!shapers))
      59             :   {
      60           2 :     char *env = getenv ("HB_SHAPER_LIST");
      61           2 :     if (!env || !*env) {
      62           2 :       (void) hb_atomic_ptr_cmpexch (&static_shapers, NULL, &all_shapers[0]);
      63           2 :       return (const hb_shaper_pair_t *) all_shapers;
      64             :     }
      65             : 
      66             :     /* Not found; allocate one. */
      67           0 :     shapers = (hb_shaper_pair_t *) calloc (1, sizeof (all_shapers));
      68           0 :     if (unlikely (!shapers)) {
      69           0 :       (void) hb_atomic_ptr_cmpexch (&static_shapers, NULL, &all_shapers[0]);
      70           0 :       return (const hb_shaper_pair_t *) all_shapers;
      71             :     }
      72             : 
      73           0 :     memcpy (shapers, all_shapers, sizeof (all_shapers));
      74             : 
      75             :      /* Reorder shaper list to prefer requested shapers. */
      76           0 :     unsigned int i = 0;
      77           0 :     char *end, *p = env;
      78             :     for (;;) {
      79           0 :       end = strchr (p, ',');
      80           0 :       if (!end)
      81           0 :         end = p + strlen (p);
      82             : 
      83           0 :       for (unsigned int j = i; j < ARRAY_LENGTH (all_shapers); j++)
      84           0 :         if (end - p == (int) strlen (shapers[j].name) &&
      85           0 :             0 == strncmp (shapers[j].name, p, end - p))
      86             :         {
      87             :           /* Reorder this shaper to position i */
      88           0 :          struct hb_shaper_pair_t t = shapers[j];
      89           0 :          memmove (&shapers[i + 1], &shapers[i], sizeof (shapers[i]) * (j - i));
      90           0 :          shapers[i] = t;
      91           0 :          i++;
      92             :         }
      93             : 
      94           0 :       if (!*end)
      95           0 :         break;
      96             :       else
      97           0 :         p = end + 1;
      98           0 :     }
      99             : 
     100           0 :     if (!hb_atomic_ptr_cmpexch (&static_shapers, NULL, shapers)) {
     101           0 :       free (shapers);
     102           0 :       goto retry;
     103             :     }
     104             : 
     105             : #ifdef HB_USE_ATEXIT
     106             :     atexit (free_static_shapers); /* First person registers atexit() callback. */
     107             : #endif
     108             :   }
     109             : 
     110           0 :   return shapers;
     111             : }

Generated by: LCOV version 1.13