diff mupdf-source/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mupdf-source/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh	Mon Sep 15 11:43:07 2025 +0200
@@ -0,0 +1,244 @@
+/*
+ * Copyright © 2017  Google, Inc.
+ *
+ *  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.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_VAR_AVAR_TABLE_HH
+#define HB_OT_VAR_AVAR_TABLE_HH
+
+#include "hb-open-type.hh"
+#include "hb-ot-var-common.hh"
+
+
+/*
+ * avar -- Axis Variations
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/avar
+ */
+
+#define HB_OT_TAG_avar HB_TAG('a','v','a','r')
+
+
+namespace OT {
+
+
+/* "Spec": https://github.com/be-fonts/boring-expansion-spec/issues/14 */
+struct avarV2Tail
+{
+  friend struct avar;
+
+  bool sanitize (hb_sanitize_context_t *c,
+		 const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (varIdxMap.sanitize (c, base) &&
+		  varStore.sanitize (c, base));
+  }
+
+  protected:
+  Offset32To<DeltaSetIndexMap>	varIdxMap;	/* Offset from the beginning of 'avar' table. */
+  Offset32To<VariationStore>	varStore;	/* Offset from the beginning of 'avar' table. */
+
+  public:
+  DEFINE_SIZE_STATIC (8);
+};
+
+
+struct AxisValueMap
+{
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  public:
+  F2DOT14	coords[2];
+//   F2DOT14	fromCoord;	/* A normalized coordinate value obtained using
+//				 * default normalization. */
+//   F2DOT14	toCoord;	/* The modified, normalized coordinate value. */
+
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+struct SegmentMaps : Array16Of<AxisValueMap>
+{
+  int map (int value, unsigned int from_offset = 0, unsigned int to_offset = 1) const
+  {
+#define fromCoord coords[from_offset]
+#define toCoord coords[to_offset]
+    /* The following special-cases are not part of OpenType, which requires
+     * that at least -1, 0, and +1 must be mapped. But we include these as
+     * part of a better error recovery scheme. */
+    if (len < 2)
+    {
+      if (!len)
+	return value;
+      else /* len == 1*/
+	return value - arrayZ[0].fromCoord + arrayZ[0].toCoord;
+    }
+
+    if (value <= arrayZ[0].fromCoord)
+      return value - arrayZ[0].fromCoord + arrayZ[0].toCoord;
+
+    unsigned int i;
+    unsigned int count = len - 1;
+    for (i = 1; i < count && value > arrayZ[i].fromCoord; i++)
+      ;
+
+    if (value >= arrayZ[i].fromCoord)
+      return value - arrayZ[i].fromCoord + arrayZ[i].toCoord;
+
+    if (unlikely (arrayZ[i-1].fromCoord == arrayZ[i].fromCoord))
+      return arrayZ[i-1].toCoord;
+
+    int denom = arrayZ[i].fromCoord - arrayZ[i-1].fromCoord;
+    return roundf (arrayZ[i-1].toCoord + ((float) (arrayZ[i].toCoord - arrayZ[i-1].toCoord) *
+					  (value - arrayZ[i-1].fromCoord)) / denom);
+#undef toCoord
+#undef fromCoord
+  }
+
+  int unmap (int value) const { return map (value, 1, 0); }
+
+  public:
+  DEFINE_SIZE_ARRAY (2, *this);
+};
+
+struct avar
+{
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_avar;
+
+  bool has_data () const { return version.to_int (); }
+
+  const SegmentMaps* get_segment_maps () const
+  { return &firstAxisSegmentMaps; }
+
+  unsigned get_axis_count () const
+  { return axisCount; }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (!(version.sanitize (c) &&
+	  (version.major == 1
+#ifndef HB_NO_AVAR2
+	   || version.major == 2
+#endif
+	   ) &&
+	  c->check_struct (this)))
+      return_trace (false);
+
+    const SegmentMaps *map = &firstAxisSegmentMaps;
+    unsigned int count = axisCount;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      if (unlikely (!map->sanitize (c)))
+	return_trace (false);
+      map = &StructAfter<SegmentMaps> (*map);
+    }
+
+#ifndef HB_NO_AVAR2
+    if (version.major < 2)
+      return_trace (true);
+
+    const auto &v2 = * (const avarV2Tail *) map;
+    if (unlikely (!v2.sanitize (c, this)))
+      return_trace (false);
+#endif
+
+    return_trace (true);
+  }
+
+  void map_coords (int *coords, unsigned int coords_length) const
+  {
+    unsigned int count = hb_min (coords_length, axisCount);
+
+    const SegmentMaps *map = &firstAxisSegmentMaps;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      coords[i] = map->map (coords[i]);
+      map = &StructAfter<SegmentMaps> (*map);
+    }
+
+#ifndef HB_NO_AVAR2
+    if (version.major < 2)
+      return;
+
+    for (; count < axisCount; count++)
+      map = &StructAfter<SegmentMaps> (*map);
+
+    const auto &v2 = * (const avarV2Tail *) map;
+
+    const auto &varidx_map = this+v2.varIdxMap;
+    const auto &var_store = this+v2.varStore;
+    auto *var_store_cache = var_store.create_cache ();
+
+    hb_vector_t<int> out;
+    out.alloc (coords_length);
+    for (unsigned i = 0; i < coords_length; i++)
+    {
+      int v = coords[i];
+      uint32_t varidx = varidx_map.map (i);
+      float delta = var_store.get_delta (varidx, coords, coords_length, var_store_cache);
+      v += roundf (delta);
+      v = hb_clamp (v, -(1<<14), +(1<<14));
+      out.push (v);
+    }
+    for (unsigned i = 0; i < coords_length; i++)
+      coords[i] = out[i];
+
+    OT::VariationStore::destroy_cache (var_store_cache);
+#endif
+  }
+
+  void unmap_coords (int *coords, unsigned int coords_length) const
+  {
+    unsigned int count = hb_min (coords_length, axisCount);
+
+    const SegmentMaps *map = &firstAxisSegmentMaps;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      coords[i] = map->unmap (coords[i]);
+      map = &StructAfter<SegmentMaps> (*map);
+    }
+  }
+
+  protected:
+  FixedVersion<>version;	/* Version of the avar table
+				 * initially set to 0x00010000u */
+  HBUINT16	reserved;	/* This field is permanently reserved. Set to 0. */
+  HBUINT16	axisCount;	/* The number of variation axes in the font. This
+				 * must be the same number as axisCount in the
+				 * 'fvar' table. */
+  SegmentMaps	firstAxisSegmentMaps;
+
+  public:
+  DEFINE_SIZE_MIN (8);
+};
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_VAR_AVAR_TABLE_HH */