<?php
define('FPDF_FONTPATH', dirname(__FILE__) . DIRECTORY_SEPARATOR . 'font' . DIRECTORY_SEPARATOR);
require(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'fpdf.php');
$Big5_widths = array(' ' => 250, '!' => 250, '"' => 408, '#' => 668, '$' => 490, '%' => 875, '&' => 698, '\'' => 250,
	'(' => 240, ')' => 240, '*' => 417, '+' => 667, ',' => 250, '-' => 313, '.' => 250, '/' => 520, '0' => 500, '1' => 500,
	'2' => 500, '3' => 500, '4' => 500, '5' => 500, '6' => 500, '7' => 500, '8' => 500, '9' => 500, ':' => 250, ';' => 250,
	'<' => 667, '=' => 667, '>' => 667, '?' => 396, '@' => 921, 'A' => 677, 'B' => 615, 'C' => 719, 'D' => 760, 'E' => 625,
	'F' => 552, 'G' => 771, 'H' => 802, 'I' => 354, 'J' => 354, 'K' => 781, 'L' => 604, 'M' => 927, 'N' => 750, 'O' => 823,
	'P' => 563, 'Q' => 823, 'R' => 729, 'S' => 542, 'T' => 698, 'U' => 771, 'V' => 729, 'W' => 948, 'X' => 771, 'Y' => 677,
	'Z' => 635, '[' => 344, '' => 520, ']' => 344, '^' => 469, '_' => 500, '`' => 250, 'a' => 469, 'b' => 521, 'c' => 427,
	'd' => 521, 'e' => 438, 'f' => 271, 'g' => 469, 'h' => 531, 'i' => 250, 'j' => 250, 'k' => 458, 'l' => 240, 'm' => 802,
	'n' => 531, 'o' => 500, 'p' => 521, 'q' => 521, 'r' => 365, 's' => 333, 't' => 292, 'u' => 521, 'v' => 458, 'w' => 677,
	'x' => 479, 'y' => 458, 'z' => 427, '{' => 480, '|' => 496, '}' => 480, '~' => 667);
$GB_widths = array(' ' => 207, '!' => 270, '"' => 342, '#' => 467, '$' => 462, '%' => 797, '&' => 710, '\'' => 239,
	'(' => 374, ')' => 374, '*' => 423, '+' => 605, ',' => 238, '-' => 375, '.' => 238, '/' => 334, '0' => 462, '1' => 462,
	'2' => 462, '3' => 462, '4' => 462, '5' => 462, '6' => 462, '7' => 462, '8' => 462, '9' => 462, ':' => 238, ';' => 238,
	'<' => 605, '=' => 605, '>' => 605, '?' => 344, '@' => 748, 'A' => 684, 'B' => 560, 'C' => 695, 'D' => 739, 'E' => 563,
	'F' => 511, 'G' => 729, 'H' => 793, 'I' => 318, 'J' => 312, 'K' => 666, 'L' => 526, 'M' => 896, 'N' => 758, 'O' => 772,
	'P' => 544, 'Q' => 772, 'R' => 628, 'S' => 465, 'T' => 607, 'U' => 753, 'V' => 711, 'W' => 972, 'X' => 647, 'Y' => 620,
	'Z' => 607, '[' => 374, '' => 333, ']' => 374, '^' => 606, '_' => 500, '`' => 239, 'a' => 417, 'b' => 503, 'c' => 427,
	'd' => 529, 'e' => 415, 'f' => 264, 'g' => 444, 'h' => 518, 'i' => 241, 'j' => 230, 'k' => 495, 'l' => 228, 'm' => 793,
	'n' => 527, 'o' => 524, 'p' => 524, 'q' => 504, 'r' => 338, 's' => 336, 't' => 277, 'u' => 517, 'v' => 450, 'w' => 652,
	'x' => 466, 'y' => 452, 'z' => 407, '{' => 370, '|' => 258, '}' => 370, '~' => 605);
class PDF_Chinese extends FPDF {
	function AddCIDFont($family, $style, $name, $cw, $CMap, $registry) {
		$i = count($this->fonts) + 1;
		$fontkey = strtolower($family) . strtoupper($style);
		$this->fonts[$fontkey] = array('i' => $i, 'type' => 'Type0', 'name' => $name, 'up' => -120, 'ut' => 40, 'cw' => $cw, 'CMap' => $CMap, 'registry' => $registry);
	} 
	function AddBig5Font($family = 'Big5') {
		$cw = $GLOBALS['Big5_widths'];
		$name = 'MSungStd-Light-Acro';
		$CMap = 'ETenms-B5-H';
		$registry = array('ordering' => 'CNS1', 'supplement' => 0);
		$this->AddCIDFont($family, '', $name, $cw, $CMap, $registry);
		$this->AddCIDFont($family, 'B', $name . ',Bold', $cw, $CMap, $registry);
		$this->AddCIDFont($family, 'I', $name . ',Italic', $cw, $CMap, $registry);
		$this->AddCIDFont($family, 'BI', $name . ',BoldItalic', $cw, $CMap, $registry);
	} 
	function AddGBFont($family = 'GB') {
		$cw = $GLOBALS['GB_widths'];
		$name = 'STSongStd-Light-Acro';
		$CMap = 'GBKp-EUC-H';
		$registry = array('ordering' => 'GB1', 'supplement' => 2);
		$this->AddCIDFont($family, '', $name, $cw, $CMap, $registry);
		$this->AddCIDFont($family, 'B', $name . ',Bold', $cw, $CMap, $registry);
		$this->AddCIDFont($family, 'I', $name . ',Italic', $cw, $CMap, $registry);
		$this->AddCIDFont($family, 'BI', $name . ',BoldItalic', $cw, $CMap, $registry);
	} 
	function GetStringWidth($s) {
		if ($this->CurrentFont['type'] == 'Type0')
			return $this->GetMBStringWidth($s);
		else
			return parent :: GetStringWidth($s);
	} 

	function GetMBStringWidth($s) {
		// Multi-byte version of GetStringWidth()
		$l = 0;
		$cw = &$this->CurrentFont['cw'];
		$nb = strlen($s);
		$i = 0;
		while ($i < $nb) {
			$c = $s[$i];
			if (ord($c) < 128) {
				$l += $cw[$c];
				$i++;
			} else {
				$l += 1000;
				$i += 2;
			} 
		} 
		return $l * $this->FontSize / 1000;
	} 
	function MultiCell($w, $h, $txt, $border = 0, $align = 'L', $fill = 0) {
		if ($this->CurrentFont['type'] == 'Type0')
			$this->MBMultiCell($w, $h, $txt, $border, $align, $fill);
		else
			parent :: MultiCell($w, $h, $txt, $border, $align, $fill);
	} 
	function MBMultiCell($w, $h, $txt, $border = 0, $align = 'L', $fill = 0) {
		// Multi-byte version of MultiCell()
		$cw = &$this->CurrentFont['cw'];
		if ($w == 0)
			$w = $this->w - $this->rMargin - $this->x;
		$wmax = ($w-2 * $this->cMargin) * 1000 / $this->FontSize;
		$s = str_replace("\r", '', $txt);
		$nb = strlen($s);
		if ($nb > 0 and $s[$nb-1] == "\n")
			$nb--;
		$b = 0;
		if ($border) {
			if ($border == 1) {
				$border = 'LTRB';
				$b = 'LRT';
				$b2 = 'LR';
			} else {
				$b2 = '';
				if (is_int(strpos($border, 'L')))
					$b2 .= 'L';
				if (is_int(strpos($border, 'R')))
					$b2 .= 'R';
				$b = is_int(strpos($border, 'T')) ? $b2 . 'T' : $b2;
			} 
		} 
		$sep = -1;
		$i = 0;
		$j = 0;
		$l = 0;
		$ns = 0;
		$nl = 1;
		while ($i < $nb) {
			// Get next character
			$c = $s[$i];
			// Check if ASCII or MB
			$ascii = (ord($c) < 128);
			if ($c == "\n") {
				// Explicit line break
				if ($this->ws > 0) {
					$this->ws = 0;
					$this->_out('0 Tw');
				} 
				$this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill);
				$i++;
				$sep = -1;
				$j = $i;
				$l = 0;
				$ns = 0;
				$nl++;
				if ($border and $nl == 2)
					$b = $b2;
				continue;
			} 
			if (!$ascii) {
				$sep = $i;
				$ls = $l;
			} elseif ($c == ' ') {
				$sep = $i;
				$ls = $l;
				$ns++;
			} 
			$l += $ascii ? $cw[$c] : 1000;
			if ($l > $wmax) {
				// Automatic line break
				if ($sep == -1 or $i == $j) {
					if ($i == $j)
						$i += $ascii ? 1 : 2;
					if ($this->ws > 0) {
						$this->ws = 0;
						$this->_out('0 Tw');
					} 
					$this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill);
				} else {
					if ($align == 'J') {
						if ($s[$sep] == ' ')
							$ns--;
						if ($s[$i-1] == ' ') {
							$ns--;
							$ls -= $cw[' '];
						} 
						$this->ws = ($ns > 0) ? ($wmax - $ls) / 1000 * $this->FontSize / $ns : 0;
						$this->_out(sprintf('%.3f Tw', $this->ws * $this->k));
					} 
					$this->Cell($w, $h, substr($s, $j, $sep - $j), $b, 2, $align, $fill);
					$i = ($s[$sep] == ' ') ? $sep + 1 : $sep;
				} 
				$sep = -1;
				$j = $i;
				$l = 0;
				$ns = 0;
				$nl++;
				if ($border and $nl == 2)
					$b = $b2;
			} else
				$i += $ascii ? 1 : 2;
		} 
		// Last chunk
		if ($this->ws > 0) {
			$this->ws = 0;
			$this->_out('0 Tw');
		} 
		if ($border and is_int(strpos($border, 'B')))
			$b .= 'B';
		$this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill);
		$this->x = $this->lMargin;
	} 
	function Write($h, $txt, $link = '') {
		if ($this->CurrentFont['type'] == 'Type0')
			$this->MBWrite($h, $txt, $link);
		else
			parent::Write($h, $txt, $link);
	} 
	function MBWrite($h, $txt, $link) {
		// Multi-byte version of Write()
		$cw = &$this->CurrentFont['cw'];
		$w = $this->w - $this->rMargin - $this->x;
		$wmax = ($w-2 * $this->cMargin) * 1000 / $this->FontSize;
		$s = str_replace("\r", '', $txt);
		$nb = strlen($s);
		$sep = -1;
		$i = 0;
		$j = 0;
		$l = 0;
		$nl = 1;
		while ($i < $nb) {
			// Get next character
			$c = $s[$i];
			// Check if ASCII or MB
			$ascii = (ord($c) < 128);
			if ($c == "\n") {
				// Explicit line break
				$this->Cell($w, $h, substr($s, $j, $i - $j), 0, 2, '', 0, $link);
				$i++;
				$sep = -1;
				$j = $i;
				$l = 0;
				if ($nl == 1) {
					$this->x = $this->lMargin;
					$w = $this->w - $this->rMargin - $this->x;
					$wmax = ($w-2 * $this->cMargin) * 1000 / $this->FontSize;
				} 
				$nl++;
				continue;
			} 
			if (!$ascii or $c == ' ')
				$sep = $i;
			$l += $ascii ? $cw[$c] : 1000;
			if ($l > $wmax) {
				// Automatic line break
				if ($sep == -1 or $i == $j) {
					if ($this->x > $this->lMargin) {
						// Move to next line
						$this->x = $this->lMargin;
						$this->y += $h;
						$w = $this->w - $this->rMargin - $this->x;
						$wmax = ($w-2 * $this->cMargin) * 1000 / $this->FontSize;
						$i++;
						$nl++;
						continue;
					} 
					if ($i == $j)
						$i += $ascii ? 1 : 2;
					$this->Cell($w, $h, substr($s, $j, $i - $j), 0, 2, '', 0, $link);
				} else {
					$this->Cell($w, $h, substr($s, $j, $sep - $j), 0, 2, '', 0, $link);
					$i = ($s[$sep] == ' ') ? $sep + 1 : $sep;
				} 
				$sep = -1;
				$j = $i;
				$l = 0;
				if ($nl == 1) {
					$this->x = $this->lMargin;
					$w = $this->w - $this->rMargin - $this->x;
					$wmax = ($w-2 * $this->cMargin) * 1000 / $this->FontSize;
				} 
				$nl++;
			} else
				$i += $ascii ? 1 : 2;
		} 
		// Last chunk
		if ($i != $j)
			$this->Cell($l / 1000 * $this->FontSize, $h, substr($s, $j, $i - $j), 0, 0, '', 0, $link);
	} 
	function _putfonts() {
		$nf = $this->n;
		foreach($this->diffs as $diff) {
			// Encodings
			$this->_newobj();
			$this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [' . $diff . ']>>');
			$this->_out('endobj');
		} 
		$mqr = get_magic_quotes_runtime();
		set_magic_quotes_runtime(0);
		foreach($this->FontFiles as $file => $info) {
			// Font file embedding
			$this->_newobj();
			$this->FontFiles[$file]['n'] = $this->n;
			if (defined('FPDF_FONTPATH'))
				$file = FPDF_FONTPATH . $file;
			$size = filesize($file);
			if (!$size)
				$this->Error('Font file not found');
			$this->_out('<</Length ' . $size);
			if (substr($file, -2) == '.z')
				$this->_out('/Filter /FlateDecode');
			$this->_out('/Length1 ' . $info['length1']);
			if (isset($info['length2']))
				$this->_out('/Length2 ' . $info['length2'] . ' /Length3 0');
			$this->_out('>>');
			$f = fopen($file, 'rb');
			$this->_putstream(fread($f, $size));
			fclose($f);
			$this->_out('endobj');
		} 
		set_magic_quotes_runtime($mqr);
		foreach($this->fonts as $k => $font) {
			// Font objects
			$this->_newobj();
			$this->fonts[$k]['n'] = $this->n;
			$this->_out('<</Type /Font');
			if ($font['type'] == 'Type0')
				$this->_putType0($font);
			else {
				$name = $font['name'];
				$this->_out('/BaseFont /' . $name);
				if ($font['type'] == 'core') {
					// Standard font
					$this->_out('/Subtype /Type1');
					if ($name != 'Symbol' and $name != 'ZapfDingbats')
						$this->_out('/Encoding /WinAnsiEncoding');
				} else {
					// Additional font
					$this->_out('/Subtype /' . $font['type']);
					$this->_out('/FirstChar 32');
					$this->_out('/LastChar 255');
					$this->_out('/Widths ' . ($this->n + 1) . ' 0 R');
					$this->_out('/FontDescriptor ' . ($this->n + 2) . ' 0 R');
					if ($font['enc']) {
						if (isset($font['diff']))
							$this->_out('/Encoding ' . ($nf + $font['diff']) . ' 0 R');
						else
							$this->_out('/Encoding /WinAnsiEncoding');
					} 
				} 
				$this->_out('>>');
				$this->_out('endobj');
				if ($font['type'] != 'core') {
					// Widths
					$this->_newobj();
					$cw = &$font['cw'];
					$s = '[';
					for($i = 32;$i <= 255;$i++)
					$s .= $cw[chr($i)] . ' ';
					$this->_out($s . ']');
					$this->_out('endobj');
					// Descriptor
					$this->_newobj();
					$s = '<</Type /FontDescriptor /FontName /' . $name;
					foreach($font['desc'] as $k => $v)
					$s .= ' /' . $k . ' ' . $v;
					$file = $font['file'];
					if ($file)
						$s .= ' /FontFile' . ($font['type'] == 'Type1' ? '' : '2') . ' ' . $this->FontFiles[$file]['n'] . ' 0 R';
					$this->_out($s . '>>');
					$this->_out('endobj');
				} 
			} 
		} 
	} 
	function _putType0($font) {
		// Type0
		$this->_out('/Subtype /Type0');
		$this->_out('/BaseFont /' . $font['name'] . '-' . $font['CMap']);
		$this->_out('/Encoding /' . $font['CMap']);
		$this->_out('/DescendantFonts [' . ($this->n + 1) . ' 0 R]');
		$this->_out('>>');
		$this->_out('endobj');
		// CIDFont
		$this->_newobj();
		$this->_out('<</Type /Font');
		$this->_out('/Subtype /CIDFontType0');
		$this->_out('/BaseFont /' . $font['name']);
		$this->_out('/CIDSystemInfo <</Registry (Adobe) /Ordering (' . $font['registry']['ordering'] . ') /Supplement ' . $font['registry']['supplement'] . '>>');
		$this->_out('/FontDescriptor ' . ($this->n + 1) . ' 0 R');
		$W = '/W [1 [';
		foreach($font['cw'] as $w)
		$W .= $w . ' ';
		$this->_out($W . ']]');
		$this->_out('>>');
		$this->_out('endobj');
		// Font descriptor
		$this->_newobj();
		$this->_out('<</Type /FontDescriptor');
		$this->_out('/FontName /' . $font['name']);
		$this->_out('/Flags 6');
		$this->_out('/FontBBox [0 0 1000 1000]');
		$this->_out('/ItalicAngle 0');
		$this->_out('/Ascent 1000');
		$this->_out('/Descent 0');
		$this->_out('/CapHeight 1000');
		$this->_out('/StemV 10');
		$this->_out('>>');
		$this->_out('endobj');
	} 
} 
?>