Font_Glyph_Outline_Simple

`glyf` font table.

Defined (1)

The class is defined in the following location(s).

/lib/dompdf/lib/php-font-lib/classes/Font_Glyph_Outline_Simple.php  
  1. class Font_Glyph_Outline_Simple extends Font_Glyph_Outline { 
  2. const ON_CURVE = 0x01; 
  3. const X_SHORT_VECTOR = 0x02; 
  4. const Y_SHORT_VECTOR = 0x04; 
  5. const REPEAT = 0x08; 
  6. const THIS_X_IS_SAME = 0x10; 
  7. const THIS_Y_IS_SAME = 0x20; 
  8.  
  9. public $instructions; 
  10. public $points; 
  11.  
  12. function parseData() { 
  13. parent::parseData(); 
  14.  
  15. if (!$this->size) { 
  16. return; 
  17.  
  18. $font = $this->getFont(); 
  19.  
  20. $noc = $this->numberOfContours; 
  21.  
  22. if ($noc == 0) { 
  23. return; 
  24.  
  25. $endPtsOfContours = $font->r(array(self::uint16, $noc)); 
  26.  
  27. $instructionLength = $font->readUInt16(); 
  28. $this->instructions = $font->r(array(self::uint8, $instructionLength)); 
  29.  
  30. $count = $endPtsOfContours[$noc-1] + 1; 
  31.  
  32. // Flags 
  33. $flags = array(); 
  34. for ($index = 0; $index < $count; $index++) { 
  35. $flags[$index] = $font->readUInt8(); 
  36.  
  37. if ($flags[$index] & self::REPEAT) { 
  38. $repeats = $font->readUInt8(); 
  39.  
  40. for ($i = 1; $i <= $repeats; $i++) { 
  41. $flags[$index+$i] = $flags[$index]; 
  42.  
  43. $index += $repeats; 
  44.  
  45. $points = array(); 
  46. foreach ($flags as $i => $flag) { 
  47. $points[$i]["onCurve"] = $flag & self::ON_CURVE; 
  48. $points[$i]["endOfContour"] = in_array($i, $endPtsOfContours); 
  49.  
  50. // X Coords 
  51. $x = 0; 
  52. for($i = 0; $i < $count; $i++) { 
  53. $flag = $flags[$i]; 
  54.  
  55. if ($flag & self::THIS_X_IS_SAME) { 
  56. if ($flag & self::X_SHORT_VECTOR) { 
  57. $x += $font->readUInt8(); 
  58. else { 
  59. if ($flag & self::X_SHORT_VECTOR) { 
  60. $x -= $font->readUInt8(); 
  61. else { 
  62. $x += $font->readInt16(); 
  63.  
  64. $points[$i]["x"] = $x; 
  65.  
  66. // Y Coords 
  67. $y = 0; 
  68. for($i = 0; $i < $count; $i++) { 
  69. $flag = $flags[$i]; 
  70.  
  71. if ($flag & self::THIS_Y_IS_SAME) { 
  72. if ($flag & self::Y_SHORT_VECTOR) { 
  73. $y += $font->readUInt8(); 
  74. else { 
  75. if ($flag & self::Y_SHORT_VECTOR) { 
  76. $y -= $font->readUInt8(); 
  77. else { 
  78. $y += $font->readInt16(); 
  79.  
  80. $points[$i]["y"] = $y; 
  81.  
  82. $this->points = $points; 
  83.  
  84. public function splitSVGPath($path) { 
  85. preg_match_all('/([a-z])|(-?\d+(?:\.\d+)?)/i', $path, $matches, PREG_PATTERN_ORDER); 
  86. return $matches[0]; 
  87.  
  88. public function makePoints($path) { 
  89. $path = $this->splitSVGPath($path); 
  90. $l = count($path); 
  91. $i = 0; 
  92.  
  93. $points = array(); 
  94.  
  95. while($i < $l) { 
  96. switch($path[$i]) { 
  97. // moveTo 
  98. case "M": 
  99. $points[] = array( 
  100. "onCurve" => true,  
  101. "x" => $path[++$i],  
  102. "y" => $path[++$i],  
  103. "endOfContour" => false,  
  104. ); 
  105. break; 
  106.  
  107. // lineTo 
  108. case "L": 
  109. $points[] = array( 
  110. "onCurve" => true,  
  111. "x" => $path[++$i],  
  112. "y" => $path[++$i],  
  113. "endOfContour" => false,  
  114. ); 
  115. break; 
  116.  
  117. // quadraticCurveTo 
  118. case "Q": 
  119. $points[] = array( 
  120. "onCurve" => false,  
  121. "x" => $path[++$i],  
  122. "y" => $path[++$i],  
  123. "endOfContour" => false,  
  124. ); 
  125. $points[] = array( 
  126. "onCurve" => true,  
  127. "x" => $path[++$i],  
  128. "y" => $path[++$i],  
  129. "endOfContour" => false,  
  130. ); 
  131. break; 
  132.  
  133. // closePath 
  134. /** @noinspection PhpMissingBreakStatementInspection */ 
  135. case "z": 
  136. $points[count($points)-1]["endOfContour"] = true; 
  137.  
  138. default: 
  139. $i++; 
  140. break; 
  141.  
  142. return $points; 
  143.  
  144. function encode() { 
  145. if (empty($this->points)) { 
  146. return parent::encode(); 
  147.  
  148. return $this->size = $this->encodePoints($this->points); 
  149.  
  150. public function encodePoints($points) { 
  151. $endPtsOfContours = array(); 
  152. $flags = array(); 
  153. $coords_x = array(); 
  154. $coords_y = array(); 
  155.  
  156. $last_x = 0; 
  157. $last_y = 0; 
  158. $xMin = $yMin = 0xFFFF; 
  159. $xMax = $yMax = -0xFFFF; 
  160. foreach($points as $i => $point) { 
  161. $flag = 0; 
  162. if ($point["onCurve"]) { 
  163. $flag |= self::ON_CURVE; 
  164.  
  165. if ($point["endOfContour"]) { 
  166. $endPtsOfContours[] = $i; 
  167.  
  168. // Simplified, we could do some optimizations 
  169. if ($point["x"] == $last_x) { 
  170. $flag |= self::THIS_X_IS_SAME; 
  171. else { 
  172. $x = intval($point["x"]); 
  173. $xMin = min($x, $xMin); 
  174. $xMax = max($x, $xMax); 
  175. $coords_x[] = $x-$last_x; // int16 
  176.  
  177. // Simplified, we could do some optimizations 
  178. if ($point["y"] == $last_y) { 
  179. $flag |= self::THIS_Y_IS_SAME; 
  180. else { 
  181. $y = intval($point["y"]); 
  182. $yMin = min($y, $yMin); 
  183. $yMax = max($y, $yMax); 
  184. $coords_y[] = $y-$last_y; // int16 
  185.  
  186. $flags[] = $flag; 
  187. $last_x = $point["x"]; 
  188. $last_y = $point["y"]; 
  189.  
  190. $font = $this->getFont(); 
  191.  
  192. $l = 0; 
  193. $l += $font->writeInt16(count($endPtsOfContours)); // endPtsOfContours 
  194. $l += $font->writeFWord(isset($this->xMin) ? $this->xMin : $xMin); // xMin 
  195. $l += $font->writeFWord(isset($this->yMin) ? $this->yMin : $yMin); // yMin 
  196. $l += $font->writeFWord(isset($this->xMax) ? $this->xMax : $xMax); // xMax 
  197. $l += $font->writeFWord(isset($this->yMax) ? $this->yMax : $yMax); // yMax 
  198.  
  199. // Simple glyf 
  200. $l += $font->w(array(self::uint16, count($endPtsOfContours)), $endPtsOfContours); // endPtsOfContours 
  201. $l += $font->writeUInt16(0); // instructionLength 
  202. $l += $font->w(array(self::uint8, count($flags)), $flags); // flags 
  203. $l += $font->w(array(self::int16, count($coords_x)), $coords_x); // xCoordinates 
  204. $l += $font->w(array(self::int16, count($coords_y)), $coords_y); // yCoordinates 
  205. return $l; 
  206. }  
  207.  
  208. public function getSVGContours($points = null) { 
  209. $path = ""; 
  210.  
  211. if (!$points) { 
  212. if (empty($this->points)) { 
  213. $this->parseData(); 
  214.  
  215. $points = $this->points; 
  216.  
  217. $length = count($points); 
  218. $firstIndex = 0; 
  219. $count = 0; 
  220.  
  221. for($i = 0; $i < $length; $i++) { 
  222. $count++; 
  223.  
  224. if ($points[$i]["endOfContour"]) { 
  225. $path .= $this->getSVGPath($points, $firstIndex, $count); 
  226. $firstIndex = $i + 1; 
  227. $count = 0; 
  228.  
  229. return $path; 
  230.  
  231. protected function getSVGPath($points, $startIndex, $count) { 
  232. $offset = 0; 
  233. $path = ""; 
  234.  
  235. while($offset < $count) { 
  236. $point = $points[ $startIndex + $offset %$count ]; 
  237. $point_p1 = $points[ $startIndex + ($offset+1)%$count ]; 
  238.  
  239. if($offset == 0) { 
  240. $path .= "M{$point['x']}, {$point['y']} "; 
  241.  
  242. if ($point["onCurve"]) { 
  243. if ($point_p1["onCurve"]) { 
  244. $path .= "L{$point_p1['x']}, {$point_p1['y']} "; 
  245. $offset++; 
  246. else { 
  247. $point_p2 = $points[ $startIndex + ($offset+2)%$count ]; 
  248.  
  249. if ($point_p2["onCurve"]) { 
  250. $path .= "Q{$point_p1['x']}, {$point_p1['y']}, {$point_p2['x']}, {$point_p2['y']} "; 
  251. }  
  252. else { 
  253. $path .= "Q{$point_p1['x']}, {$point_p1['y']}, ".$this->midValue($point_p1['x'], $point_p2['x']).", ".$this->midValue($point_p1['y'], $point_p2['y'])." "; 
  254. }  
  255.  
  256. $offset += 2; 
  257. else { 
  258. if ($point_p1["onCurve"]) { 
  259. $path .= "Q{$point['x']}, {$point['y']}, {$point_p1['x']}, {$point_p1['y']} "; 
  260. else { 
  261. $path .= "Q{$point['x']}, {$point['y']}, ".$this->midValue($point['x'], $point_p1['x']).", ".$this->midValue($point['y'], $point_p1['y'])." "; 
  262.  
  263. $offset++; 
  264.  
  265. $path .= "z "; 
  266.  
  267. return $path; 
  268.  
  269. function midValue($a, $b) { 
  270. return $a + ($b - $a)/2;