Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / vendor / phenx / php-font-lib / src / FontLib / BinaryStream.php
diff --git a/vendor/phenx/php-font-lib/src/FontLib/BinaryStream.php b/vendor/phenx/php-font-lib/src/FontLib/BinaryStream.php
new file mode 100644 (file)
index 0000000..ab10454
--- /dev/null
@@ -0,0 +1,444 @@
+<?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
+ */
+
+namespace FontLib;
+
+/**
+ * Generic font file binary stream.
+ *
+ * @package php-font-lib
+ */
+class BinaryStream {
+  /**
+   * @var resource The file pointer
+   */
+  protected $f;
+
+  const uint8        = 1;
+  const  int8        = 2;
+  const uint16       = 3;
+  const  int16       = 4;
+  const uint32       = 5;
+  const  int32       = 6;
+  const shortFrac    = 7;
+  const Fixed        = 8;
+  const  FWord       = 9;
+  const uFWord       = 10;
+  const F2Dot14      = 11;
+  const longDateTime = 12;
+  const char         = 13;
+
+  const modeRead      = "rb";
+  const modeWrite     = "wb";
+  const modeReadWrite = "rb+";
+
+  static function backtrace() {
+    var_dump(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS));
+  }
+
+  /**
+   * Open a font file in read mode
+   *
+   * @param string $filename The file name of the font to open
+   *
+   * @return bool
+   */
+  public function load($filename) {
+    return $this->open($filename, self::modeRead);
+  }
+
+  /**
+   * Open a font file in a chosen mode
+   *
+   * @param string $filename The file name of the font to open
+   * @param string $mode     The opening mode
+   *
+   * @throws \Exception
+   * @return bool
+   */
+  public function open($filename, $mode = self::modeRead) {
+    if (!in_array($mode, array(self::modeRead, self::modeWrite, self::modeReadWrite))) {
+      throw new \Exception("Unkown file open mode");
+    }
+
+    $this->f = fopen($filename, $mode);
+
+    return $this->f != false;
+  }
+
+  /**
+   * Close the internal file pointer
+   */
+  public function close() {
+    return fclose($this->f) != false;
+  }
+
+  /**
+   * Change the internal file pointer
+   *
+   * @param resource $fp
+   *
+   * @throws \Exception
+   */
+  public function setFile($fp) {
+    if (!is_resource($fp)) {
+      throw new \Exception('$fp is not a valid resource');
+    }
+
+    $this->f = $fp;
+  }
+
+  /**
+   * Create a temporary file in write mode
+   *
+   * @param bool $allow_memory Allow in-memory files
+   *
+   * @return resource the temporary file pointer resource
+   */
+  public static function getTempFile($allow_memory = true) {
+    $f = null;
+
+    if ($allow_memory) {
+      $f = fopen("php://temp", "rb+");
+    }
+    else {
+      $f = fopen(tempnam(sys_get_temp_dir(), "fnt"), "rb+");
+    }
+
+    return $f;
+  }
+
+  /**
+   * Move the internal file pinter to $offset bytes
+   *
+   * @param int $offset
+   *
+   * @return bool True if the $offset position exists in the file
+   */
+  public function seek($offset) {
+    return fseek($this->f, $offset, SEEK_SET) == 0;
+  }
+
+  /**
+   * Gives the current position in the file
+   *
+   * @return int The current position
+   */
+  public function pos() {
+    return ftell($this->f);
+  }
+
+  public function skip($n) {
+    fseek($this->f, $n, SEEK_CUR);
+  }
+
+  public function read($n) {
+    if ($n < 1) {
+      return "";
+    }
+
+    return fread($this->f, $n);
+  }
+
+  public function write($data, $length = null) {
+    if ($data === null || $data === "" || $data === false) {
+      return 0;
+    }
+
+    return fwrite($this->f, $data, $length);
+  }
+
+  public function readUInt8() {
+    return ord($this->read(1));
+  }
+
+  public function readUInt8Many($count) {
+    return array_values(unpack("C*", $this->read($count)));
+  }
+
+  public function writeUInt8($data) {
+    return $this->write(chr($data), 1);
+  }
+
+  public function readInt8() {
+    $v = $this->readUInt8();
+
+    if ($v >= 0x80) {
+      $v -= 0x100;
+    }
+
+    return $v;
+  }
+
+  public function readInt8Many($count) {
+    return array_values(unpack("c*", $this->read($count)));
+  }
+
+  public function writeInt8($data) {
+    if ($data < 0) {
+      $data += 0x100;
+    }
+
+    return $this->writeUInt8($data);
+  }
+
+  public function readUInt16() {
+    $a = unpack("nn", $this->read(2));
+
+    return $a["n"];
+  }
+
+  public function readUInt16Many($count) {
+    return array_values(unpack("n*", $this->read($count * 2)));
+  }
+
+  public function readUFWord() {
+    return $this->readUInt16();
+  }
+
+  public function writeUInt16($data) {
+    return $this->write(pack("n", $data), 2);
+  }
+
+  public function writeUFWord($data) {
+    return $this->writeUInt16($data);
+  }
+
+  public function readInt16() {
+    $a = unpack("nn", $this->read(2));
+    $v = $a["n"];
+
+    if ($v >= 0x8000) {
+      $v -= 0x10000;
+    }
+
+    return $v;
+  }
+
+  public function readInt16Many($count) {
+    $vals = array_values(unpack("n*", $this->read($count * 2)));
+    foreach ($vals as &$v) {
+      if ($v >= 0x8000) {
+        $v -= 0x10000;
+      }
+    }
+
+    return $vals;
+  }
+
+  public function readFWord() {
+    return $this->readInt16();
+  }
+
+  public function writeInt16($data) {
+    if ($data < 0) {
+      $data += 0x10000;
+    }
+
+    return $this->writeUInt16($data);
+  }
+
+  public function writeFWord($data) {
+    return $this->writeInt16($data);
+  }
+
+  public function readUInt32() {
+    $a = unpack("NN", $this->read(4));
+
+    return $a["N"];
+  }
+
+  public function writeUInt32($data) {
+    return $this->write(pack("N", $data), 4);
+  }
+
+  public function readFixed() {
+    $d  = $this->readInt16();
+    $d2 = $this->readUInt16();
+
+    return round($d + $d2 / 0x10000, 4);
+  }
+
+  public function writeFixed($data) {
+    $left  = floor($data);
+    $right = ($data - $left) * 0x10000;
+
+    return $this->writeInt16($left) + $this->writeUInt16($right);
+  }
+
+  public function readLongDateTime() {
+    $this->readUInt32(); // ignored
+    $date = $this->readUInt32() - 2082844800;
+    
+    # PHP_INT_MIN isn't defined in PHP < 7.0
+    $php_int_min = defined("PHP_INT_MIN") ? PHP_INT_MIN : ~PHP_INT_MAX;
+
+    if (is_string($date) || $date > PHP_INT_MAX || $date < $php_int_min) {
+      $date = 0;
+    }
+
+    return strftime("%Y-%m-%d %H:%M:%S", $date);
+  }
+
+  public function writeLongDateTime($data) {
+    $date = strtotime($data);
+    $date += 2082844800;
+
+    return $this->writeUInt32(0) + $this->writeUInt32($date);
+  }
+
+  public function unpack($def) {
+    $d = array();
+    foreach ($def as $name => $type) {
+      $d[$name] = $this->r($type);
+    }
+
+    return $d;
+  }
+
+  public function pack($def, $data) {
+    $bytes = 0;
+    foreach ($def as $name => $type) {
+      $bytes += $this->w($type, $data[$name]);
+    }
+
+    return $bytes;
+  }
+
+  /**
+   * Read a data of type $type in the file from the current position
+   *
+   * @param mixed $type The data type to read
+   *
+   * @return mixed The data that was read
+   */
+  public function r($type) {
+    switch ($type) {
+      case self::uint8:
+        return $this->readUInt8();
+      case self::int8:
+        return $this->readInt8();
+      case self::uint16:
+        return $this->readUInt16();
+      case self::int16:
+        return $this->readInt16();
+      case self::uint32:
+        return $this->readUInt32();
+      case self::int32:
+        return $this->readUInt32();
+      case self::shortFrac:
+        return $this->readFixed();
+      case self::Fixed:
+        return $this->readFixed();
+      case self::FWord:
+        return $this->readInt16();
+      case self::uFWord:
+        return $this->readUInt16();
+      case self::F2Dot14:
+        return $this->readInt16();
+      case self::longDateTime:
+        return $this->readLongDateTime();
+      case self::char:
+        return $this->read(1);
+      default:
+        if (is_array($type)) {
+          if ($type[0] == self::char) {
+            return $this->read($type[1]);
+          }
+          if ($type[0] == self::uint16) {
+            return $this->readUInt16Many($type[1]);
+          }
+          if ($type[0] == self::int16) {
+            return $this->readInt16Many($type[1]);
+          }
+          if ($type[0] == self::uint8) {
+            return $this->readUInt8Many($type[1]);
+          }
+          if ($type[0] == self::int8) {
+            return $this->readInt8Many($type[1]);
+          }
+
+          $ret = array();
+          for ($i = 0; $i < $type[1]; $i++) {
+            $ret[] = $this->r($type[0]);
+          }
+
+          return $ret;
+        }
+
+        return null;
+    }
+  }
+
+  /**
+   * Write $data of type $type in the file from the current position
+   *
+   * @param mixed $type The data type to write
+   * @param mixed $data The data to write
+   *
+   * @return int The number of bytes read
+   */
+  public function w($type, $data) {
+    switch ($type) {
+      case self::uint8:
+        return $this->writeUInt8($data);
+      case self::int8:
+        return $this->writeInt8($data);
+      case self::uint16:
+        return $this->writeUInt16($data);
+      case self::int16:
+        return $this->writeInt16($data);
+      case self::uint32:
+        return $this->writeUInt32($data);
+      case self::int32:
+        return $this->writeUInt32($data);
+      case self::shortFrac:
+        return $this->writeFixed($data);
+      case self::Fixed:
+        return $this->writeFixed($data);
+      case self::FWord:
+        return $this->writeInt16($data);
+      case self::uFWord:
+        return $this->writeUInt16($data);
+      case self::F2Dot14:
+        return $this->writeInt16($data);
+      case self::longDateTime:
+        return $this->writeLongDateTime($data);
+      case self::char:
+        return $this->write($data, 1);
+      default:
+        if (is_array($type)) {
+          if ($type[0] == self::char) {
+            return $this->write($data, $type[1]);
+          }
+
+          $ret = 0;
+          for ($i = 0; $i < $type[1]; $i++) {
+            if (isset($data[$i])) {
+              $ret += $this->w($type[0], $data[$i]);
+            }
+          }
+
+          return $ret;
+        }
+
+        return null;
+    }
+  }
+
+  /**
+   * Converts a Uint32 value to string
+   *
+   * @param int $uint32
+   *
+   * @return string The string
+   */
+  public function convertUInt32ToStr($uint32) {
+    return chr(($uint32 >> 24) & 0xFF) . chr(($uint32 >> 16) & 0xFF) . chr(($uint32 >> 8) & 0xFF) . chr($uint32 & 0xFF);
+  }
+}