Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / vendor / phenx / php-font-lib / src / FontLib / Glyph / OutlineSimple.php
diff --git a/vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineSimple.php b/vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineSimple.php
new file mode 100644 (file)
index 0000000..3c023de
--- /dev/null
@@ -0,0 +1,335 @@
+<?php
+/**
+ * @package php-font-lib
+ * @link    https://github.com/PhenX/php-font-lib
+ * @author  Fabien Ménager <fabien.menager@gmail.com>
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
+ * @version $Id: Font_Table_glyf.php 46 2012-04-02 20:22:38Z fabien.menager $
+ */
+
+namespace FontLib\Glyph;
+
+/**
+ * `glyf` font table.
+ *
+ * @package php-font-lib
+ */
+class OutlineSimple extends Outline {
+  const ON_CURVE       = 0x01;
+  const X_SHORT_VECTOR = 0x02;
+  const Y_SHORT_VECTOR = 0x04;
+  const REPEAT         = 0x08;
+  const THIS_X_IS_SAME = 0x10;
+  const THIS_Y_IS_SAME = 0x20;
+
+  public $instructions;
+  public $points;
+
+  function parseData() {
+    parent::parseData();
+
+    if (!$this->size) {
+      return;
+    }
+
+    $font = $this->getFont();
+
+    $noc = $this->numberOfContours;
+
+    if ($noc == 0) {
+      return;
+    }
+
+    $endPtsOfContours = $font->r(array(self::uint16, $noc));
+
+    $instructionLength  = $font->readUInt16();
+    $this->instructions = $font->r(array(self::uint8, $instructionLength));
+
+    $count = $endPtsOfContours[$noc - 1] + 1;
+
+    // Flags
+    $flags = array();
+    for ($index = 0; $index < $count; $index++) {
+      $flags[$index] = $font->readUInt8();
+
+      if ($flags[$index] & self::REPEAT) {
+        $repeats = $font->readUInt8();
+
+        for ($i = 1; $i <= $repeats; $i++) {
+          $flags[$index + $i] = $flags[$index];
+        }
+
+        $index += $repeats;
+      }
+    }
+
+    $points = array();
+    foreach ($flags as $i => $flag) {
+      $points[$i]["onCurve"]      = $flag & self::ON_CURVE;
+      $points[$i]["endOfContour"] = in_array($i, $endPtsOfContours);
+    }
+
+    // X Coords
+    $x = 0;
+    for ($i = 0; $i < $count; $i++) {
+      $flag = $flags[$i];
+
+      if ($flag & self::THIS_X_IS_SAME) {
+        if ($flag & self::X_SHORT_VECTOR) {
+          $x += $font->readUInt8();
+        }
+      }
+      else {
+        if ($flag & self::X_SHORT_VECTOR) {
+          $x -= $font->readUInt8();
+        }
+        else {
+          $x += $font->readInt16();
+        }
+      }
+
+      $points[$i]["x"] = $x;
+    }
+
+    // Y Coords
+    $y = 0;
+    for ($i = 0; $i < $count; $i++) {
+      $flag = $flags[$i];
+
+      if ($flag & self::THIS_Y_IS_SAME) {
+        if ($flag & self::Y_SHORT_VECTOR) {
+          $y += $font->readUInt8();
+        }
+      }
+      else {
+        if ($flag & self::Y_SHORT_VECTOR) {
+          $y -= $font->readUInt8();
+        }
+        else {
+          $y += $font->readInt16();
+        }
+      }
+
+      $points[$i]["y"] = $y;
+    }
+
+    $this->points = $points;
+  }
+
+  public function splitSVGPath($path) {
+    preg_match_all('/([a-z])|(-?\d+(?:\.\d+)?)/i', $path, $matches, PREG_PATTERN_ORDER);
+
+    return $matches[0];
+  }
+
+  public function makePoints($path) {
+    $path = $this->splitSVGPath($path);
+    $l    = count($path);
+    $i    = 0;
+
+    $points = array();
+
+    while ($i < $l) {
+      switch ($path[$i]) {
+        // moveTo
+        case "M":
+          $points[] = array(
+            "onCurve"      => true,
+            "x"            => $path[++$i],
+            "y"            => $path[++$i],
+            "endOfContour" => false,
+          );
+          break;
+
+        // lineTo
+        case "L":
+          $points[] = array(
+            "onCurve"      => true,
+            "x"            => $path[++$i],
+            "y"            => $path[++$i],
+            "endOfContour" => false,
+          );
+          break;
+
+        // quadraticCurveTo
+        case "Q":
+          $points[] = array(
+            "onCurve"      => false,
+            "x"            => $path[++$i],
+            "y"            => $path[++$i],
+            "endOfContour" => false,
+          );
+          $points[] = array(
+            "onCurve"      => true,
+            "x"            => $path[++$i],
+            "y"            => $path[++$i],
+            "endOfContour" => false,
+          );
+          break;
+
+        // closePath
+        /** @noinspection PhpMissingBreakStatementInspection */
+        case "z":
+          $points[count($points) - 1]["endOfContour"] = true;
+
+        default:
+          $i++;
+          break;
+      }
+    }
+
+    return $points;
+  }
+
+  function encode() {
+    if (empty($this->points)) {
+      return parent::encode();
+    }
+
+    return $this->size = $this->encodePoints($this->points);
+  }
+
+  public function encodePoints($points) {
+    $endPtsOfContours = array();
+    $flags            = array();
+    $coords_x         = array();
+    $coords_y         = array();
+
+    $last_x = 0;
+    $last_y = 0;
+    $xMin   = $yMin = 0xFFFF;
+    $xMax   = $yMax = -0xFFFF;
+    foreach ($points as $i => $point) {
+      $flag = 0;
+      if ($point["onCurve"]) {
+        $flag |= self::ON_CURVE;
+      }
+
+      if ($point["endOfContour"]) {
+        $endPtsOfContours[] = $i;
+      }
+
+      // Simplified, we could do some optimizations
+      if ($point["x"] == $last_x) {
+        $flag |= self::THIS_X_IS_SAME;
+      }
+      else {
+        $x          = intval($point["x"]);
+        $xMin       = min($x, $xMin);
+        $xMax       = max($x, $xMax);
+        $coords_x[] = $x - $last_x; // int16
+      }
+
+      // Simplified, we could do some optimizations
+      if ($point["y"] == $last_y) {
+        $flag |= self::THIS_Y_IS_SAME;
+      }
+      else {
+        $y          = intval($point["y"]);
+        $yMin       = min($y, $yMin);
+        $yMax       = max($y, $yMax);
+        $coords_y[] = $y - $last_y; // int16
+      }
+
+      $flags[] = $flag;
+      $last_x  = $point["x"];
+      $last_y  = $point["y"];
+    }
+
+    $font = $this->getFont();
+
+    $l = 0;
+    $l += $font->writeInt16(count($endPtsOfContours)); // endPtsOfContours
+    $l += $font->writeFWord(isset($this->xMin) ? $this->xMin : $xMin); // xMin
+    $l += $font->writeFWord(isset($this->yMin) ? $this->yMin : $yMin); // yMin
+    $l += $font->writeFWord(isset($this->xMax) ? $this->xMax : $xMax); // xMax
+    $l += $font->writeFWord(isset($this->yMax) ? $this->yMax : $yMax); // yMax
+
+    // Simple glyf
+    $l += $font->w(array(self::uint16, count($endPtsOfContours)), $endPtsOfContours); // endPtsOfContours
+    $l += $font->writeUInt16(0); // instructionLength
+    $l += $font->w(array(self::uint8, count($flags)), $flags); // flags
+    $l += $font->w(array(self::int16, count($coords_x)), $coords_x); // xCoordinates
+    $l += $font->w(array(self::int16, count($coords_y)), $coords_y); // yCoordinates
+    return $l;
+  }
+
+  public function getSVGContours($points = null) {
+    $path = "";
+
+    if (!$points) {
+      if (empty($this->points)) {
+        $this->parseData();
+      }
+
+      $points = $this->points;
+    }
+
+    $length     = count($points);
+    $firstIndex = 0;
+    $count      = 0;
+
+    for ($i = 0; $i < $length; $i++) {
+      $count++;
+
+      if ($points[$i]["endOfContour"]) {
+        $path .= $this->getSVGPath($points, $firstIndex, $count);
+        $firstIndex = $i + 1;
+        $count      = 0;
+      }
+    }
+
+    return $path;
+  }
+
+  protected function getSVGPath($points, $startIndex, $count) {
+    $offset = 0;
+    $path   = "";
+
+    while ($offset < $count) {
+      $point    = $points[$startIndex + $offset % $count];
+      $point_p1 = $points[$startIndex + ($offset + 1) % $count];
+
+      if ($offset == 0) {
+        $path .= "M{$point['x']},{$point['y']} ";
+      }
+
+      if ($point["onCurve"]) {
+        if ($point_p1["onCurve"]) {
+          $path .= "L{$point_p1['x']},{$point_p1['y']} ";
+          $offset++;
+        }
+        else {
+          $point_p2 = $points[$startIndex + ($offset + 2) % $count];
+
+          if ($point_p2["onCurve"]) {
+            $path .= "Q{$point_p1['x']},{$point_p1['y']},{$point_p2['x']},{$point_p2['y']} ";
+          }
+          else {
+            $path .= "Q{$point_p1['x']},{$point_p1['y']}," . $this->midValue($point_p1['x'], $point_p2['x']) . "," . $this->midValue($point_p1['y'], $point_p2['y']) . " ";
+          }
+
+          $offset += 2;
+        }
+      }
+      else {
+        if ($point_p1["onCurve"]) {
+          $path .= "Q{$point['x']},{$point['y']},{$point_p1['x']},{$point_p1['y']} ";
+        }
+        else {
+          $path .= "Q{$point['x']},{$point['y']}," . $this->midValue($point['x'], $point_p1['x']) . "," . $this->midValue($point['y'], $point_p1['y']) . " ";
+        }
+
+        $offset++;
+      }
+    }
+
+    $path .= "z ";
+
+    return $path;
+  }
+
+  function midValue($a, $b) {
+    return $a + ($b - $a) / 2;
+  }
+}
\ No newline at end of file