| /* |
| * Copyright © 2026 Behdad Esfahbod |
| * |
| * This is part of HarfBuzz, a text shaping library. |
| * |
| * Permission is hereby granted, without written agreement and without |
| * license or royalty fees, to use, copy, modify, and distribute this |
| * software and its documentation for any purpose, provided that the |
| * above copyright notice and the following two paragraphs appear in |
| * all copies of this software. |
| * |
| * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |
| * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES |
| * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN |
| * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
| * DAMAGE. |
| * |
| * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, |
| * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
| * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
| * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO |
| * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
| * |
| * Author(s): Behdad Esfahbod |
| */ |
| |
| #ifndef HB_NO_RASTER_SVG |
| |
| #include "hb.hh" |
| |
| #include "hb-raster-svg-defs.hh" |
| |
| #include <string.h> |
| |
| hb_svg_defs_t::~hb_svg_defs_t () |
| { |
| for (unsigned i = 0; i < owned_id_strings.length; i++) |
| hb_free (owned_id_strings.arrayZ[i]); |
| } |
| |
| bool |
| hb_svg_defs_t::add_id_mapping (hb_hashmap_t<hb_bytes_t, unsigned> *map, |
| hb_bytes_t id, |
| unsigned idx) |
| { |
| if (!id.length) |
| return false; |
| if (map->has (id)) |
| return true; |
| |
| unsigned n = (unsigned) id.length; |
| char *owned = (char *) hb_malloc (n + 1); |
| if (unlikely (!owned)) |
| return false; |
| hb_memcpy (owned, id.arrayZ, n); |
| owned[n] = '\0'; |
| if (unlikely (!owned_id_strings.push_or_fail (owned))) |
| { |
| hb_free (owned); |
| return false; |
| } |
| |
| hb_bytes_t owned_key = hb_bytes_t (owned, n); |
| if (unlikely (!map->set (owned_key, idx))) |
| return false; |
| return true; |
| } |
| |
| bool |
| hb_svg_defs_t::add_gradient (hb_bytes_t id, const hb_svg_gradient_t &grad) |
| { |
| unsigned idx = gradients.length; |
| gradients.push (grad); |
| if (unlikely (gradients.in_error ())) |
| return false; |
| |
| if (unlikely (!add_id_mapping (&gradient_by_id, id, idx))) |
| { |
| gradients.pop (); |
| return false; |
| } |
| return true; |
| } |
| |
| const hb_svg_gradient_t * |
| hb_svg_defs_t::find_gradient (hb_bytes_t id) const |
| { |
| if (!id.length) return nullptr; |
| unsigned *idx = nullptr; |
| if (gradient_by_id.has (id, &idx)) |
| return &gradients[*idx]; |
| return nullptr; |
| } |
| |
| bool |
| hb_svg_defs_t::add_clip_path (hb_bytes_t id, const hb_svg_clip_path_def_t &clip) |
| { |
| unsigned idx = clip_paths.length; |
| clip_paths.push (clip); |
| if (unlikely (clip_paths.in_error ())) |
| return false; |
| |
| if (unlikely (!add_id_mapping (&clip_path_by_id, id, idx))) |
| { |
| clip_paths.pop (); |
| return false; |
| } |
| return true; |
| } |
| |
| const hb_svg_clip_path_def_t * |
| hb_svg_defs_t::find_clip_path (hb_bytes_t id) const |
| { |
| if (!id.length) return nullptr; |
| unsigned *idx = nullptr; |
| if (clip_path_by_id.has (id, &idx)) |
| return &clip_paths[*idx]; |
| return nullptr; |
| } |
| |
| #endif /* !HB_NO_RASTER_SVG */ |