150 lines
4.0 KiB
PHP
150 lines
4.0 KiB
PHP
<?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
|
|
*/
|
|
|
|
require_once dirname(__FILE__) . "/Font_Glyph_Outline.php";
|
|
|
|
/**
|
|
* `glyf` font table.
|
|
*
|
|
* @package php-font-lib
|
|
* @property Font_Glyph_Outline[] $data
|
|
*/
|
|
class Font_Table_glyf extends Font_Table {
|
|
protected function _parse(){
|
|
$font = $this->getFont();
|
|
$offset = $font->pos();
|
|
|
|
$loca = $font->getData("loca");
|
|
$real_loca = array_slice($loca, 0, -1); // Not the last dummy loca entry
|
|
|
|
$data = array();
|
|
|
|
foreach($real_loca as $gid => $location) {
|
|
$_offset = $offset + $loca[$gid];
|
|
$_size = $loca[$gid+1] - $loca[$gid];
|
|
$data[$gid] = Font_Glyph_Outline::init($this, $_offset, $_size);
|
|
}
|
|
|
|
$this->data = $data;
|
|
}
|
|
|
|
public function getGlyphIDs($gids = array()){
|
|
$glyphIDs = array();
|
|
|
|
foreach ($gids as $_gid) {
|
|
$_glyph = $this->data[$_gid];
|
|
$glyphIDs = array_merge($glyphIDs, $_glyph->getGlyphIDs());
|
|
}
|
|
|
|
return array_unique(array_merge($gids, $glyphIDs));
|
|
}
|
|
|
|
public function toHTML(){
|
|
$max = 160;
|
|
$font = $this->getFont();
|
|
|
|
$head = $font->getData("head");
|
|
$head_json = json_encode($head);
|
|
|
|
$os2 = $font->getData("OS/2");
|
|
$os2_json = json_encode($os2);
|
|
|
|
$hmtx = $font->getData("hmtx");
|
|
$hmtx_json = json_encode($hmtx);
|
|
|
|
$names = $font->getData("post", "names");
|
|
$glyphIndexArray = array_flip($font->getUnicodeCharMap());
|
|
|
|
$width = (abs($head["xMin"]) + $head["xMax"]);
|
|
$height = (abs($head["yMin"]) + $head["yMax"]);
|
|
|
|
$ratio = 1;
|
|
if ($width > $max || $height > $max) {
|
|
$ratio = max($width, $height) / $max;
|
|
$width = round($width/$ratio);
|
|
$height = round($height/$ratio);
|
|
}
|
|
|
|
$n = 500;
|
|
|
|
$s = "<h3>"."Only the first $n simple glyphs are shown (".count($this->data)." total)
|
|
<div class='glyph-view simple'>Simple glyph</div>
|
|
<div class='glyph-view composite'>Composite glyph</div>
|
|
Zoom: <input type='range' value='100' max='400' onchange='Glyph.resize(this.value)' />
|
|
</h3>
|
|
<script>
|
|
Glyph.ratio = $ratio;
|
|
Glyph.head = $head_json;
|
|
Glyph.os2 = $os2_json;
|
|
Glyph.hmtx = $hmtx_json;
|
|
Glyph.width = $width;
|
|
Glyph.height = $height;
|
|
</script>";
|
|
|
|
foreach($this->data as $g => $glyph) {
|
|
if ($n-- <= 0) {
|
|
break;
|
|
}
|
|
|
|
$glyph->parseData();
|
|
|
|
$shape = array(
|
|
"SVGContours" => $glyph->getSVGContours(),
|
|
"xMin" => $glyph->xMin,
|
|
"yMin" => $glyph->yMin,
|
|
"xMax" => $glyph->xMax,
|
|
"yMax" => $glyph->yMax,
|
|
);
|
|
$shape_json = json_encode($shape);
|
|
|
|
$type = ($glyph instanceof Font_Glyph_Outline_Simple ? "simple" : "composite");
|
|
$char = isset($glyphIndexArray[$g]) ? $glyphIndexArray[$g] : 0;
|
|
$name = isset($names[$g]) ? $names[$g] : sprintf("uni%04x", $char);
|
|
$char = $char ? "&#{$glyphIndexArray[$g]};" : "";
|
|
|
|
$s .= "<div class='glyph-view $type' id='glyph-$g'>
|
|
<span class='glyph-id'>$g</span>
|
|
<span class='char'>$char</span>
|
|
<span class='char-name'>$name</span>
|
|
";
|
|
|
|
if ($type == "composite") {
|
|
foreach ($glyph->getGlyphIDs() as $_id) {
|
|
$s .= "<a href='#glyph-$_id' class='glyph-component-id'>$_id</a> ";
|
|
}
|
|
}
|
|
|
|
$s .= "<br />
|
|
<canvas width='$width' height='$height' id='glyph-canvas-$g'></canvas>
|
|
</div>
|
|
<script>Glyph.glyphs.push([$g,$shape_json]);</script>";
|
|
}
|
|
|
|
return $s;
|
|
}
|
|
|
|
|
|
protected function _encode() {
|
|
$font = $this->getFont();
|
|
$subset = $font->getSubset();
|
|
$data = $this->data;
|
|
|
|
$loca = array();
|
|
|
|
$length = 0;
|
|
foreach($subset as $gid) {
|
|
$loca[] = $length;
|
|
$length += $data[$gid]->encode();
|
|
}
|
|
|
|
$loca[] = $length; // dummy loca
|
|
$font->getTableObject("loca")->data = $loca;
|
|
|
|
return $length;
|
|
}
|
|
} |