123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- <?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;
-
- /**
- * Composite glyph outline
- *
- * @package php-font-lib
- */
- class OutlineComposite extends Outline {
- const ARG_1_AND_2_ARE_WORDS = 0x0001;
- const ARGS_ARE_XY_VALUES = 0x0002;
- const ROUND_XY_TO_GRID = 0x0004;
- const WE_HAVE_A_SCALE = 0x0008;
- const MORE_COMPONENTS = 0x0020;
- const WE_HAVE_AN_X_AND_Y_SCALE = 0x0040;
- const WE_HAVE_A_TWO_BY_TWO = 0x0080;
- const WE_HAVE_INSTRUCTIONS = 0x0100;
- const USE_MY_METRICS = 0x0200;
- const OVERLAP_COMPOUND = 0x0400;
-
- /**
- * @var OutlineComponent[]
- */
- public $components = array();
-
- function getGlyphIDs() {
- if (empty($this->components)) {
- $this->parseData();
- }
-
- $glyphIDs = array();
- foreach ($this->components as $_component) {
- $glyphIDs[] = $_component->glyphIndex;
-
- $_glyph = $this->table->data[$_component->glyphIndex];
-
- if ($_glyph !== $this) {
- $glyphIDs = array_merge($glyphIDs, $_glyph->getGlyphIDs());
- }
- }
-
- return $glyphIDs;
- }
-
- /*function parse() {
- //$this->parseData();
- }*/
-
- function parseData() {
- parent::parseData();
-
- $font = $this->getFont();
-
- do {
- $flags = $font->readUInt16();
- $glyphIndex = $font->readUInt16();
-
- $a = 1.0;
- $b = 0.0;
- $c = 0.0;
- $d = 1.0;
- $e = 0.0;
- $f = 0.0;
-
- $point_compound = null;
- $point_component = null;
-
- $instructions = null;
-
- if ($flags & self::ARG_1_AND_2_ARE_WORDS) {
- if ($flags & self::ARGS_ARE_XY_VALUES) {
- $e = $font->readInt16();
- $f = $font->readInt16();
- }
- else {
- $point_compound = $font->readUInt16();
- $point_component = $font->readUInt16();
- }
- }
- else {
- if ($flags & self::ARGS_ARE_XY_VALUES) {
- $e = $font->readInt8();
- $f = $font->readInt8();
- }
- else {
- $point_compound = $font->readUInt8();
- $point_component = $font->readUInt8();
- }
- }
-
- if ($flags & self::WE_HAVE_A_SCALE) {
- $a = $d = $font->readInt16();
- }
- elseif ($flags & self::WE_HAVE_AN_X_AND_Y_SCALE) {
- $a = $font->readInt16();
- $d = $font->readInt16();
- }
- elseif ($flags & self::WE_HAVE_A_TWO_BY_TWO) {
- $a = $font->readInt16();
- $b = $font->readInt16();
- $c = $font->readInt16();
- $d = $font->readInt16();
- }
-
- //if ($flags & self::WE_HAVE_INSTRUCTIONS) {
- //
- //}
-
- $component = new OutlineComponent();
- $component->flags = $flags;
- $component->glyphIndex = $glyphIndex;
- $component->a = $a;
- $component->b = $b;
- $component->c = $c;
- $component->d = $d;
- $component->e = $e;
- $component->f = $f;
- $component->point_compound = $point_compound;
- $component->point_component = $point_component;
- $component->instructions = $instructions;
-
- $this->components[] = $component;
- } while ($flags & self::MORE_COMPONENTS);
- }
-
- function encode() {
- $font = $this->getFont();
-
- $gids = $font->getSubset();
-
- $size = $font->writeInt16(-1);
- $size += $font->writeFWord($this->xMin);
- $size += $font->writeFWord($this->yMin);
- $size += $font->writeFWord($this->xMax);
- $size += $font->writeFWord($this->yMax);
-
- foreach ($this->components as $_i => $_component) {
- $flags = 0;
- if ($_component->point_component === null && $_component->point_compound === null) {
- $flags |= self::ARGS_ARE_XY_VALUES;
-
- if (abs($_component->e) > 0x7F || abs($_component->f) > 0x7F) {
- $flags |= self::ARG_1_AND_2_ARE_WORDS;
- }
- }
- elseif ($_component->point_component > 0xFF || $_component->point_compound > 0xFF) {
- $flags |= self::ARG_1_AND_2_ARE_WORDS;
- }
-
- if ($_component->b == 0 && $_component->c == 0) {
- if ($_component->a == $_component->d) {
- if ($_component->a != 1.0) {
- $flags |= self::WE_HAVE_A_SCALE;
- }
- }
- else {
- $flags |= self::WE_HAVE_AN_X_AND_Y_SCALE;
- }
- }
- else {
- $flags |= self::WE_HAVE_A_TWO_BY_TWO;
- }
-
- if ($_i < count($this->components) - 1) {
- $flags |= self::MORE_COMPONENTS;
- }
-
- $size += $font->writeUInt16($flags);
-
- $new_gid = array_search($_component->glyphIndex, $gids);
- $size += $font->writeUInt16($new_gid);
-
- if ($flags & self::ARG_1_AND_2_ARE_WORDS) {
- if ($flags & self::ARGS_ARE_XY_VALUES) {
- $size += $font->writeInt16($_component->e);
- $size += $font->writeInt16($_component->f);
- }
- else {
- $size += $font->writeUInt16($_component->point_compound);
- $size += $font->writeUInt16($_component->point_component);
- }
- }
- else {
- if ($flags & self::ARGS_ARE_XY_VALUES) {
- $size += $font->writeInt8($_component->e);
- $size += $font->writeInt8($_component->f);
- }
- else {
- $size += $font->writeUInt8($_component->point_compound);
- $size += $font->writeUInt8($_component->point_component);
- }
- }
-
- if ($flags & self::WE_HAVE_A_SCALE) {
- $size += $font->writeInt16($_component->a);
- }
- elseif ($flags & self::WE_HAVE_AN_X_AND_Y_SCALE) {
- $size += $font->writeInt16($_component->a);
- $size += $font->writeInt16($_component->d);
- }
- elseif ($flags & self::WE_HAVE_A_TWO_BY_TWO) {
- $size += $font->writeInt16($_component->a);
- $size += $font->writeInt16($_component->b);
- $size += $font->writeInt16($_component->c);
- $size += $font->writeInt16($_component->d);
- }
- }
-
- return $size;
- }
-
- public function getSVGContours() {
- $contours = array();
-
- /** @var \FontLib\Table\Type\glyf $glyph_data */
- $glyph_data = $this->getFont()->getTableObject("glyf");
-
- /** @var Outline[] $glyphs */
- $glyphs = $glyph_data->data;
-
- foreach ($this->components as $component) {
- $_glyph = $glyphs[$component->glyphIndex];
-
- if ($_glyph !== $this) {
- $contours[] = array(
- "contours" => $_glyph->getSVGContours(),
- "transform" => $component->getMatrix(),
- );
- }
- }
-
- return $contours;
- }
- }
|