summaryrefslogtreecommitdiff
path: root/library/patchwork/utf8/class/Patchwork/Utf8/BestFit.php
diff options
context:
space:
mode:
Diffstat (limited to 'library/patchwork/utf8/class/Patchwork/Utf8/BestFit.php')
-rw-r--r--library/patchwork/utf8/class/Patchwork/Utf8/BestFit.php68
1 files changed, 68 insertions, 0 deletions
diff --git a/library/patchwork/utf8/class/Patchwork/Utf8/BestFit.php b/library/patchwork/utf8/class/Patchwork/Utf8/BestFit.php
new file mode 100644
index 0000000000..72b0d00dd3
--- /dev/null
+++ b/library/patchwork/utf8/class/Patchwork/Utf8/BestFit.php
@@ -0,0 +1,68 @@
+<?php // vi: set fenc=utf-8 ts=4 sw=4 et:
+/*
+ * Copyright (C) 2013 Nicolas Grekas - p@tchwork.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the (at your option):
+ * Apache License v2.0 (http://apache.org/licenses/LICENSE-2.0.txt), or
+ * GNU General Public License v2.0 (http://gnu.org/licenses/gpl-2.0.txt).
+ */
+
+namespace Patchwork\Utf8;
+
+/**
+ * UTF-8 to Code Page conversion using best fit mappings
+ * See http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/
+ */
+class BestFit
+{
+ static function fit($cp, $s, $placeholder = '?')
+ {
+ if (! $len = strlen($s)) return 0 === $len ? '' : false;
+
+ static $map = array();
+ static $ulen_mask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
+
+ $s .= '';
+ $cp = (string) (int) $cp;
+ $result = '9' === $cp[0] ? $s . $s : $s;
+
+ if ('932' === $cp && 2 === func_num_args()) $placeholder = "\x81\x45"; // Katakana Middle Dot in CP932
+
+ if (!isset($map[$cp]))
+ {
+ $i = static::getData('to.bestfit' . $cp);
+ if (false === $i) return false;
+ $map[$cp] = $i;
+ }
+
+ $i = $j = 0;
+ $cp = $map[$cp];
+
+ while ($i < $len)
+ {
+ if ($s[$i] < "\x80") $uchr = $s[$i++];
+ else
+ {
+ $ulen = $ulen_mask[$s[$i] & "\xF0"];
+ $uchr = substr($s, $i, $ulen);
+ $i += $ulen;
+ }
+
+ if (isset($cp[$uchr])) $uchr = $cp[$uchr];
+ else $uchr = $placeholder;
+
+ isset($uchr[0]) && $result[$j++] = $uchr[0];
+ isset($uchr[1]) && $result[$j++] = $uchr[1];
+ }
+
+ return substr($result, 0, $j);
+ }
+
+ protected static function getData($file)
+ {
+ $file = __DIR__ . '/data/' . $file . '.ser';
+ if (file_exists($file)) return unserialize(file_get_contents($file));
+ else return false;
+ }
+}