I18N_Arabic
[ class tree: I18N_Arabic ] [ index: I18N_Arabic ] [ all elements ]

Source for file Glyphs.php

Documentation is available at Glyphs.php

  1. <?php
  2. /**
  3.  * ----------------------------------------------------------------------
  4.  *  
  5.  * Copyright (c) 2006-2012 Khaled Al-Sham'aa.
  6.  *  
  7.  * http://www.ar-php.org
  8.  *  
  9.  * PHP Version 5
  10.  *  
  11.  * ----------------------------------------------------------------------
  12.  *  
  13.  * LICENSE
  14.  *
  15.  * This program is open source product; you can redistribute it and/or
  16.  * modify it under the terms of the GNU Lesser General Public License (LGPL)
  17.  * as published by the Free Software Foundation; either version 3
  18.  * of the License, or (at your option) any later version.
  19.  *  
  20.  * This program is distributed in the hope that it will be useful,
  21.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23.  * GNU Lesser General Public License for more details.
  24.  *  
  25.  * You should have received a copy of the GNU Lesser General Public License
  26.  * along with this program.  If not, see <http://www.gnu.org/licenses/lgpl.txt>.
  27.  *  
  28.  * ----------------------------------------------------------------------
  29.  *  
  30.  * Class Name: Arabic Glyphs is a simple class to render Arabic text
  31.  *  
  32.  * Filename:   Glyphs.php
  33.  *  
  34.  * Original    Author(s): Khaled Al-Sham'aa <khaled@ar-php.org>
  35.  *  
  36.  * Purpose:    This class takes Arabic text (encoded in Windows-1256 character
  37.  *             set) as input and performs Arabic glyph joining on it and outputs
  38.  *             a UTF-8 hexadecimals stream that is no longer logically arranged
  39.  *             but in a visual order which gives readable results when formatted
  40.  *             with a simple Unicode rendering just like GD and UFPDF libraries
  41.  *             that does not handle basic connecting glyphs of Arabic language
  42.  *             yet but simply outputs all stand alone glyphs in left-to-right
  43.  *             order.
  44.  *              
  45.  * ----------------------------------------------------------------------
  46.  *  
  47.  * Arabic Glyphs is class to render Arabic text
  48.  *
  49.  * PHP class to render Arabic text by performs Arabic glyph joining on it,
  50.  * then output a UTF-8 hexadecimals stream gives readable results on PHP
  51.  * libraries supports UTF-8.
  52.  *
  53.  * Example:
  54.  * <code>
  55.  *   include('./I18N/Arabic.php');
  56.  *   $obj = new I18N_Arabic('Glyphs');
  57.  *
  58.  *   $text = $obj->utf8Glyphs($text);
  59.  *      
  60.  *   imagettftext($im, 20, 0, 200, 100, $black, $font, $text);
  61.  * </code>
  62.  *
  63.  * @category  I18N
  64.  * @package   I18N_Arabic
  65.  * @author    Khaled Al-Sham'aa <khaled@ar-php.org>
  66.  * @copyright 2006-2012 Khaled Al-Sham'aa
  67.  *    
  68.  * @license   LGPL <http://www.gnu.org/licenses/lgpl.txt>
  69.  * @link      http://www.ar-php.org
  70.  */
  71.  
  72. // New in PHP V5.3: Namespaces
  73. // namespace I18N\Arabic;
  74. // 
  75. // $obj = new I18N\Arabic\Glyphs();
  76. // 
  77. // use I18N\Arabic;
  78. // $obj = new Arabic\Glyphs();
  79. //
  80. // use I18N\Arabic\Glyphs as Glyphs;
  81. // $obj = new Glyphs();
  82.  
  83. /**
  84.  * This PHP class render Arabic text by performs Arabic glyph joining on it
  85.  *  
  86.  * @category  I18N
  87.  * @package   I18N_Arabic
  88.  * @author    Khaled Al-Sham'aa <khaled@ar-php.org>
  89.  * @copyright 2006-2012 Khaled Al-Sham'aa
  90.  *    
  91.  * @license   LGPL <http://www.gnu.org/licenses/lgpl.txt>
  92.  * @link      http://www.ar-php.org
  93.  */ 
  94. {
  95.     private $_glyphs   null;
  96.     private $_hex      null;
  97.     private $_prevLink null;
  98.     private $_nextLink null;
  99.     private $_vowel    null;
  100.  
  101.     /**
  102.      * Loads initialize values
  103.      *
  104.      * @ignore
  105.      */         
  106.     public function __construct()
  107.     {
  108.         $this->_prevLink '،؟؛ـئبتثجحخسشصضطظعغفقكلمنهي';
  109.         $this->_nextLink 'ـآأؤإائبةتثجحخدذرزسشصضطظعغفقكلمنهوىي';
  110.         $this->_vowel    'ًٌٍَُِّْ';
  111.  
  112.         /*
  113.          $this->_glyphs['ً']  = array('FE70','FE71');
  114.          $this->_glyphs['ٌ']  = array('FE72','FE72');
  115.          $this->_glyphs['ٍ']  = array('FE74','FE74');
  116.          $this->_glyphs['َ']  = array('FE76','FE77');
  117.          $this->_glyphs['ُ']  = array('FE78','FE79');
  118.          $this->_glyphs['ِ']  = array('FE7A','FE7B');
  119.          $this->_glyphs['ّ']  = array('FE7C','FE7D');
  120.          $this->_glyphs['ْ']  = array('FE7E','FE7E');
  121.          */
  122.          
  123.         $this->_glyphs 'ًٌٍَُِّْ';
  124.         $this->_hex    '064B064B064B064B064C064C064C064C064D064D064D064D064E064E';
  125.         $this->_hex   .= '064E064E064F064F064F064F06500650065006500651065106510651';
  126.         $this->_hex   .= '0652065206520652';
  127.  
  128.         $this->_glyphs .= 'ءآأؤإئاب';
  129.         $this->_hex    .= 'FE80FE80FE80FE80FE81FE82FE81FE82FE83FE84FE83FE84FE85FE86';
  130.         $this->_hex    .= 'FE85FE86FE87FE88FE87FE88FE89FE8AFE8BFE8CFE8DFE8EFE8DFE8E';
  131.         $this->_hex    .= 'FE8FFE90FE91FE92';
  132.  
  133.         $this->_glyphs .= 'ةتثجحخدذ';
  134.         $this->_hex    .= 'FE93FE94FE93FE94FE95FE96FE97FE98FE99FE9AFE9BFE9CFE9DFE9E';
  135.         $this->_hex    .= 'FE9FFEA0FEA1FEA2FEA3FEA4FEA5FEA6FEA7FEA8FEA9FEAAFEA9FEAA';
  136.         $this->_hex    .= 'FEABFEACFEABFEAC';
  137.  
  138.         $this->_glyphs .= 'رزسشصضطظ';
  139.         $this->_hex    .= 'FEADFEAEFEADFEAEFEAFFEB0FEAFFEB0FEB1FEB2FEB3FEB4FEB5FEB6';
  140.         $this->_hex    .= 'FEB7FEB8FEB9FEBAFEBBFEBCFEBDFEBEFEBFFEC0FEC1FEC2FEC3FEC4';
  141.         $this->_hex    .= 'FEC5FEC6FEC7FEC8';
  142.  
  143.         $this->_glyphs .= 'عغفقكلمن';
  144.         $this->_hex    .= 'FEC9FECAFECBFECCFECDFECEFECFFED0FED1FED2FED3FED4FED5FED6';
  145.         $this->_hex    .= 'FED7FED8FED9FEDAFEDBFEDCFEDDFEDEFEDFFEE0FEE1FEE2FEE3FEE4';
  146.         $this->_hex    .= 'FEE5FEE6FEE7FEE8';
  147.  
  148.         $this->_glyphs .= 'هوىيـ،؟؛';
  149.         $this->_hex    .= 'FEE9FEEAFEEBFEECFEEDFEEEFEEDFEEEFEEFFEF0FEEFFEF0FEF1FEF2';
  150.         $this->_hex    .= 'FEF3FEF40640064006400640060C060C060C060C061F061F061F061F';
  151.         $this->_hex    .= '061B061B061B061B';
  152.  
  153.         // Support the extra 4 Persian letters (p), (ch), (zh) and (g)
  154.         // This needs value in getGlyphs function to be 52 instead of 48
  155.         // $this->_glyphs .= chr(129).chr(141).chr(142).chr(144);
  156.         // $this->_hex    .= 'FB56FB57FB58FB59FB7AFB7BFB7CFB7DFB8AFB8BFB8AFB8BFB92';
  157.         // $this->_hex    .= 'FB93FB94FB95';
  158.         //
  159.         // $this->_prevLink .= chr(129).chr(141).chr(142).chr(144);
  160.         // $this->_nextLink .= chr(129).chr(141).chr(142).chr(144);
  161.         //
  162.         // Example:     $text = 'نمونة قلم: لاگچ ژافپ';
  163.         // Email Yossi Beck <yosbeck@gmail.com> ask him to save that example
  164.         // string using ANSI encoding in Notepad
  165.  
  166.         $this->_glyphs .= 'لآلألإلا';
  167.         $this->_hex    .= 'FEF5FEF6FEF5FEF6FEF7FEF8FEF7FEF8FEF9FEFAFEF9FEFAFEFBFEFC';
  168.         $this->_hex    .= 'FEFBFEFC';
  169.     }
  170.     
  171.     /**
  172.      * Get glyphs
  173.      * 
  174.      * @param string  $char Char
  175.      * @param integer $type Type
  176.      * 
  177.      * @return string 
  178.      */                                  
  179.     protected function getGlyphs($char$type)
  180.     {
  181.  
  182.         $pos mb_strpos($this->_glyphs$char);
  183.         
  184.         if ($pos 48{
  185.             $pos ($pos-48)/48;
  186.         }
  187.         
  188.         $pos $pos*16 $type*4;
  189.         
  190.         return substr($this->_hex$pos4);
  191.     }
  192.     
  193.     /**
  194.      * Convert Arabic Windows-1256 charset string into glyph joining in UTF-8
  195.      * hexadecimals stream
  196.      *      
  197.      * @param string $str Arabic string in Windows-1256 charset
  198.      *      
  199.      * @return string Arabic glyph joining in UTF-8 hexadecimals stream
  200.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  201.      */
  202.     protected function preConvert($str)
  203.     {
  204.         $crntChar null;
  205.         $prevChar null;
  206.         $nextChar null;
  207.         $output   '';
  208.         
  209.         $_temp mb_strlen($str);
  210.  
  211.         for ($i 0$i $_temp$i++{
  212.             $chars[mb_substr($str$i1);
  213.         }
  214.  
  215.         $max count($chars);
  216.  
  217.         for ($i $max 1$i >= 0$i--{
  218.             $crntChar $chars[$i];
  219.             
  220.             if ($i 0{
  221.                 $prevChar $chars[$i 1];
  222.             }
  223.             
  224.             if ($prevChar && mb_strpos($this->_vowel$prevChar!== false{
  225.                 $prevChar $chars[$i 2];
  226.                 if ($prevChar && mb_strpos($this->_vowel$prevChar!== false{
  227.                     $prevChar $chars[$i 3];
  228.                 }
  229.             }
  230.             
  231.             $Reversed    false;
  232.             $flip_arr    ')]>}';
  233.             $ReversedChr '([<{';
  234.             
  235.             if ($crntChar && mb_strpos($flip_arr$crntChar!== false{
  236.                 $crntChar $ReversedChr[mb_strpos($flip_arr$crntChar)];
  237.                 $Reversed true;
  238.             else {
  239.                 $Reversed false;
  240.             }
  241.             
  242.             if ($crntChar && !$Reversed && 
  243.                 (mb_strpos($ReversedChr$crntChar!== false)) {
  244.                 $crntChar $flip_arr[mb_strpos($ReversedChr$crntChar)];
  245.             }
  246.             
  247.             if (ord($crntChar128{
  248.                 $output  .= $crntChar;
  249.                 $nextChar $crntChar;
  250.                 continue;
  251.             }
  252.             
  253.             if ($crntChar == 'ل' && isset($chars[$i 1]&& 
  254.                 (mb_strpos('آأإا'$chars[$i 1]!== false)) {
  255.                 continue;
  256.             }
  257.             
  258.             if ($crntChar && mb_strpos($this->_vowel$crntChar!== false{
  259.                 if ((mb_strpos($this->_nextLink$chars[$i 1]!== false&& 
  260.                     (mb_strpos($this->_prevLink$prevChar!== false)) {
  261.                     $output .= '&#x' $this->getGlyphs($crntChar1';';
  262.                 else {
  263.                     $output .= '&#x' $this->getGlyphs($crntChar0';';
  264.                 }
  265.                 continue;
  266.             }
  267.             
  268.             $form 0;
  269.             
  270.             //if ($prevChar == 'لا' && (mb_strpos('آأإا', $crntChar) !== false)) {
  271.             if ($prevChar == 'ل' && (mb_strpos('آأإا'$crntChar!== false)) {
  272.                 if (mb_strpos($this->_prevLink$chars[$i 2]!== false{
  273.                     $form++;
  274.                 }
  275.                 
  276.                 $output  .= '&#x'.$this->getGlyphs($prevChar.$crntChar$form).';';
  277.                 $nextChar $prevChar;
  278.                 continue;
  279.             }
  280.             
  281.             if ($prevChar && mb_strpos($this->_prevLink$prevChar!== false{
  282.                 $form++;
  283.             }
  284.             
  285.             if ($nextChar && mb_strpos($this->_nextLink$nextChar!== false{
  286.                 $form += 2;
  287.             }
  288.             
  289.             $output  .= '&#x' $this->getGlyphs($crntChar$form';';
  290.             $nextChar $crntChar;
  291.         }
  292.         
  293.         // from Arabic Presentation Forms-B, Range: FE70-FEFF, 
  294.         // file "UFE70.pdf" (in reversed order)
  295.         // into Arabic Presentation Forms-A, Range: FB50-FDFF, file "UFB50.pdf"
  296.         // Example: $output = str_replace('&#xFEA0;&#xFEDF;', '&#xFCC9;', $output);
  297.         // Lam Jeem
  298.  
  299.         $output $this->decodeEntities($output$exclude array('&'));
  300.         return $output;
  301.     }
  302.     
  303.     /**
  304.      * Regression analysis calculate roughly the max number of character fit in
  305.      * one A4 page line for a given font size.
  306.      *      
  307.      * @param integer $font Font size
  308.      *      
  309.      * @return integer Maximum number of characters per line
  310.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  311.      */
  312.     public function a4MaxChars($font)
  313.     {
  314.         $x 381.6 31.57 $font 1.182 pow($font20.02052 
  315.              pow($font30.0001342 pow($font4);
  316.         return floor($x 2);
  317.     }
  318.     
  319.     /**
  320.      * Calculate the lines number of given Arabic text and font size that will
  321.      * fit in A4 page size
  322.      *      
  323.      * @param string  $str  Arabic string you would like to split it into lines
  324.      * @param integer $font Font size
  325.      *                    
  326.      * @return integer Number of lines for a given Arabic string in A4 page size
  327.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  328.      */
  329.     public function a4Lines($str$font)
  330.     {
  331.         $str str_replace(array("\r\n""\n""\r")"\n"$str);
  332.         
  333.         $lines     0;
  334.         $chars     0;
  335.         $words     explode(' '$str);
  336.         $w_count   count($words);
  337.         $max_chars $this->a4MaxChars($font);
  338.         
  339.         for ($i 0$i $w_count$i++{
  340.             $w_len mb_strlen($words[$i]1;
  341.             
  342.             if ($chars $w_len $max_chars{
  343.                 if (mb_strpos($words[$i]"\n"!== false{
  344.                     $words_nl explode("\n"$words[$i]);
  345.                     
  346.                     $nl_num count($words_nl1;
  347.                     for ($j 1$j $nl_num$j++{
  348.                         $lines++;
  349.                     }
  350.                     
  351.                     $chars mb_strlen($words_nl[$nl_num]1;
  352.                 else {
  353.                     $chars += $w_len;
  354.                 }
  355.             else {
  356.                 $lines++;
  357.                 $chars $w_len;
  358.             }
  359.         }
  360.         $lines++;
  361.         
  362.         return $lines;
  363.     }
  364.     
  365.     /**
  366.      * Convert Arabic Windows-1256 charset string into glyph joining in UTF-8
  367.      * hexadecimals stream (take care of whole the document including English
  368.      * sections as well as numbers and arcs etc...)
  369.      *                    
  370.      * @param string  $str       Arabic string in Windows-1256 charset
  371.      * @param integer $max_chars Max number of chars you can fit in one line
  372.      * @param boolean $hindo     If true use Hindo digits else use Arabic digits
  373.      *                    
  374.      * @return string Arabic glyph joining in UTF-8 hexadecimals stream (take
  375.      *                 care of whole document including English sections as well
  376.      *                 as numbers and arcs etc...)
  377.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  378.      */
  379.     public function utf8Glyphs($str$max_chars 50$hindo true)
  380.     {
  381.         $str str_replace(array("\r\n""\n""\r")" \n "$str);
  382.         $str str_replace("\t""        "$str);
  383.         
  384.         $lines   array();
  385.         $words   explode(' '$str);
  386.         $w_count count($words);
  387.         $c_chars 0;
  388.         $c_words array();
  389.         
  390.         $english  array();
  391.         $en_index = -1;
  392.         
  393.         $en_words array();
  394.         $en_stack array();
  395.  
  396.         for ($i 0$i $w_count$i++{
  397.             $pattern  '/^(\n?)';
  398.             $pattern .= '[a-z\d\\/\@\#\$\%\^\&\*\(\)\_\~\"\'\[\]\{\}\;\,\|\-\.\:!]*';
  399.             $pattern .= '([\.\:\+\=\-\!،؟]?)$/i';
  400.             
  401.             if (preg_match($pattern$words[$i]$matches)) {
  402.                 if ($matches[1]{
  403.                     $words[$imb_substr($words[$i]1).$matches[1];
  404.                 }
  405.                 if ($matches[2]{
  406.                     $words[$i$matches[2].mb_substr($words[$i]0-1);
  407.                 }
  408.                 $words[$istrrev($words[$i]);
  409.                 array_push($english$words[$i]);
  410.                 if ($en_index == -1{
  411.                     $en_index $i;
  412.                 }
  413.                 $en_words[true;
  414.             elseif ($en_index != -1{
  415.                 $en_count count($english);
  416.                 
  417.                 for ($j 0$j $en_count$j++{
  418.                     $words[$en_index $j$english[$en_count $j];
  419.                 }
  420.                 
  421.                 $en_index = -1;
  422.                 $english  array();
  423.                 
  424.                 $en_words[false;
  425.             else {
  426.                 $en_words[false;
  427.             }
  428.         }
  429.  
  430.         if ($en_index != -1{
  431.             $en_count count($english);
  432.             
  433.             for ($j 0$j $en_count$j++{
  434.                 $words[$en_index $j$english[$en_count $j];
  435.             }
  436.         }
  437.  
  438.         // need more work to fix lines starts by English words
  439.         if ($en_start{
  440.             $last true;
  441.             $from 0;
  442.             
  443.             foreach ($en_words as $key => $value{
  444.                 if ($last !== $value{
  445.                     $to $key 1;
  446.                     array_push($en_stackarray($from$to));
  447.                     $from $key;
  448.                 }
  449.                 $last $value;
  450.             }
  451.             
  452.             array_push($en_stackarray($from$key));
  453.             
  454.             $new_words array();
  455.             
  456.             while (list($from$toarray_pop($en_stack)) {
  457.                 for ($i $from$i <= $to$i++{
  458.                     $new_words[$words[$i];
  459.                 }
  460.             }
  461.             
  462.             $words $new_words;
  463.         }
  464.  
  465.         for ($i 0$i $w_count$i++{
  466.             $w_len mb_strlen($words[$i]1;
  467.             
  468.             if ($c_chars $w_len $max_chars{
  469.                 if (mb_strpos($words[$i]"\n"!== false{
  470.                     $words_nl explode("\n"$words[$i]);
  471.                     
  472.                     array_push($c_words$words_nl[0]);
  473.                     array_push($linesimplode(' '$c_words));
  474.                     
  475.                     $nl_num count($words_nl1;
  476.                     for ($j 1$j $nl_num$j++{
  477.                         array_push($lines$words_nl[$j]);
  478.                     }
  479.                     
  480.                     $c_words array($words_nl[$nl_num]);
  481.                     $c_chars mb_strlen($words_nl[$nl_num]1;
  482.                 else {
  483.                     array_push($c_words$words[$i]);
  484.                     $c_chars += $w_len;
  485.                 }
  486.             else {
  487.                 array_push($linesimplode(' '$c_words));
  488.                 $c_words array($words[$i]);
  489.                 $c_chars $w_len;
  490.             }
  491.         }
  492.         array_push($linesimplode(' '$c_words));
  493.         
  494.         $maxLine count($lines);
  495.         $output  '';
  496.         
  497.         for ($j $maxLine 1$j >= 0$j--{
  498.             $output .= $lines[$j"\n";
  499.         }
  500.         
  501.         $output rtrim($output);
  502.         
  503.         $output $this->preConvert($output);
  504.         if ($hindo{
  505.             $nums   array('0''1''2''3''4''5''6''7''8''9');
  506.             $arNums array('٠''١''٢''٣''٤''٥''٦''٧''٨''٩');
  507.             
  508.             foreach ($nums as $k => $v$p_nums[$k'/'.$v.'/ui';
  509.             $output preg_replace($p_nums$arNums$output);
  510.             
  511.             foreach ($arNums as $k => $v$p_arNums[$k'/([a-z-\d]+)'.$v.'/ui';
  512.             foreach ($nums as $k => $v$r_nums[$k'${1}'.$v;
  513.             $output preg_replace($p_arNums$r_nums$output);
  514.             
  515.             foreach ($arNums as $k => $v$p_arNums[$k'/'.$v.'([a-z-\d]+)/ui';
  516.             foreach ($nums as $k => $v$r_nums[$k$v.'${1}';
  517.             $output preg_replace($p_arNums$r_nums$output);
  518.         }
  519.  
  520.         return $output;
  521.     }
  522.     
  523.     /**
  524.      * Decode all HTML entities (including numerical ones) to regular UTF-8 bytes.
  525.      * Double-escaped entities will only be decoded once
  526.      * ("&amp;lt;" becomes "&lt;", not "<").
  527.      *                   
  528.      * @param string $text    The text to decode entities in.
  529.      * @param array  $exclude An array of characters which should not be decoded.
  530.      *                         For example, array('<', '&', '"'). This affects
  531.      *                         both named and numerical entities.
  532.      *                        
  533.      * @return string 
  534.      */
  535.     protected function decodeEntities($text$exclude array())
  536.     {
  537.         static $table;
  538.         
  539.         // We store named entities in a table for quick processing.
  540.         if (!isset($table)) {
  541.             // Get all named HTML entities.
  542.             $table array_flip(get_html_translation_table(HTML_ENTITIES));
  543.             
  544.             // PHP gives us ISO-8859-1 data, we need UTF-8.
  545.             $table array_map('utf8_encode'$table);
  546.             
  547.             // Add apostrophe (XML)
  548.             $table['&apos;'"'";
  549.         }
  550.         $newtable array_diff($table$exclude);
  551.         
  552.         // Use a regexp to select all entities in one pass, to avoid decoding 
  553.         // double-escaped entities twice.
  554.         //return preg_replace('/&(#x?)?([A-Za-z0-9]+);/e', 
  555.         //                    '$this->decodeEntities2("$1", "$2", "$0", $newtable, 
  556.         //                                             $exclude)', $text);
  557.  
  558.         $pieces explode('&'$text);
  559.         $text   array_shift($pieces);
  560.         foreach ($pieces as $piece{
  561.             if ($piece[0== '#'{
  562.                 if ($piece[1== 'x'{
  563.                     $one '#x';
  564.                 else {
  565.                     $one '#';
  566.                 }
  567.             else {
  568.                 $one '';
  569.             }
  570.             $end   mb_strpos($piece';');
  571.             $start mb_strlen($one);
  572.             
  573.             $two   mb_substr($piece$start$end $start);
  574.             $zero  '&'.$one.$two.';';
  575.             $text .= $this->decodeEntities2($one$two$zero$newtable$exclude).
  576.                      mb_substr($piece$end+1);
  577.         }
  578.         return $text;
  579.     }
  580.     
  581.     /**
  582.      * Helper function for decodeEntities
  583.      * 
  584.      * @param string $prefix    Prefix
  585.      * @param string $codepoint Codepoint
  586.      * @param string $original  Original
  587.      * @param array  &$table    Store named entities in a table
  588.      * @param array  &$exclude  An array of characters which should not be decoded
  589.      * 
  590.      * @return string 
  591.      */
  592.     protected function decodeEntities2($prefix$codepoint$original
  593.                                        &$table&$exclude)
  594.     {
  595.         // Named entity
  596.         if (!$prefix{
  597.             if (isset($table[$original])) {
  598.                 return $table[$original];
  599.             else {
  600.                 return $original;
  601.             }
  602.         }
  603.         
  604.         // Hexadecimal numerical entity
  605.         if ($prefix == '#x'{
  606.             $codepoint base_convert($codepoint1610);
  607.         }
  608.         
  609.         // Encode codepoint as UTF-8 bytes
  610.         if ($codepoint 0x80{
  611.             $str chr($codepoint);
  612.         elseif ($codepoint 0x800{
  613.             $str chr(0xC0 ($codepoint >> 6)) 
  614.                    chr(0x80 ($codepoint 0x3F));
  615.         elseif ($codepoint 0x10000{
  616.             $str chr(0xE0 ($codepoint >> 12)) 
  617.                    chr(0x80 (($codepoint >> 60x3F)) 
  618.                    chr(0x80 ($codepoint 0x3F));
  619.         elseif ($codepoint 0x200000{
  620.             $str chr(0xF0 ($codepoint >> 18)) 
  621.                    chr(0x80 (($codepoint >> 120x3F)) 
  622.                    chr(0x80 (($codepoint >> 60x3F)) 
  623.                    chr(0x80 ($codepoint 0x3F));
  624.         }
  625.         
  626.         // Check for excluded characters
  627.         if (in_array($str$exclude)) {
  628.             return $original;
  629.         else {
  630.             return $str;
  631.         }
  632.     }
  633. }

Documentation generated on Wed, 29 Aug 2012 08:32:59 +0200 by phpDocumentor 1.4.0