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 (mb_strpos($this->_prevLink$chars[$i 2]!== false{
  272.                     $form++;
  273.                 }
  274.                 
  275.                 $output  .= '&#x'.$this->getGlyphs($prevChar.$crntChar$form).';';
  276.                 $nextChar $prevChar;
  277.                 continue;
  278.             }
  279.             
  280.             if ($prevChar && mb_strpos($this->_prevLink$prevChar!== false{
  281.                 $form++;
  282.             }
  283.             
  284.             if ($nextChar && mb_strpos($this->_nextLink$nextChar!== false{
  285.                 $form += 2;
  286.             }
  287.             
  288.             $output  .= '&#x' $this->getGlyphs($crntChar$form';';
  289.             $nextChar $crntChar;
  290.         }
  291.         
  292.         // from Arabic Presentation Forms-B, Range: FE70-FEFF, 
  293.         // file "UFE70.pdf" (in reversed order)
  294.         // into Arabic Presentation Forms-A, Range: FB50-FDFF, file "UFB50.pdf"
  295.         // Example: $output = str_replace('&#xFEA0;&#xFEDF;', '&#xFCC9;', $output);
  296.         // Lam Jeem
  297.  
  298.         $output $this->decodeEntities($output$exclude array('&'));
  299.         return $output;
  300.     }
  301.     
  302.     /**
  303.      * Regression analysis calculate roughly the max number of character fit in
  304.      * one A4 page line for a given font size.
  305.      *      
  306.      * @param integer $font Font size
  307.      *      
  308.      * @return integer Maximum number of characters per line
  309.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  310.      */
  311.     public function a4MaxChars($font)
  312.     {
  313.         $x 381.6 31.57 $font 1.182 pow($font20.02052 
  314.              pow($font30.0001342 pow($font4);
  315.         return floor($x 2);
  316.     }
  317.     
  318.     /**
  319.      * Calculate the lines number of given Arabic text and font size that will
  320.      * fit in A4 page size
  321.      *      
  322.      * @param string  $str  Arabic string you would like to split it into lines
  323.      * @param integer $font Font size
  324.      *                    
  325.      * @return integer Number of lines for a given Arabic string in A4 page size
  326.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  327.      */
  328.     public function a4Lines($str$font)
  329.     {
  330.         $str str_replace(array("\r\n""\n""\r")"\n"$str);
  331.         
  332.         $lines     0;
  333.         $chars     0;
  334.         $words     explode(' '$str);
  335.         $w_count   count($words);
  336.         $max_chars $this->a4MaxChars($font);
  337.         
  338.         for ($i 0$i $w_count$i++{
  339.             $w_len mb_strlen($words[$i]1;
  340.             
  341.             if ($chars $w_len $max_chars{
  342.                 if (mb_strpos($words[$i]"\n"!== false{
  343.                     $words_nl explode("\n"$words[$i]);
  344.                     
  345.                     $nl_num count($words_nl1;
  346.                     for ($j 1$j $nl_num$j++{
  347.                         $lines++;
  348.                     }
  349.                     
  350.                     $chars mb_strlen($words_nl[$nl_num]1;
  351.                 else {
  352.                     $chars += $w_len;
  353.                 }
  354.             else {
  355.                 $lines++;
  356.                 $chars $w_len;
  357.             }
  358.         }
  359.         $lines++;
  360.         
  361.         return $lines;
  362.     }
  363.     
  364.     /**
  365.      * Convert Arabic Windows-1256 charset string into glyph joining in UTF-8
  366.      * hexadecimals stream (take care of whole the document including English
  367.      * sections as well as numbers and arcs etc...)
  368.      *                    
  369.      * @param string  $str       Arabic string in Windows-1256 charset
  370.      * @param integer $max_chars Max number of chars you can fit in one line
  371.      * @param boolean $hindo     If true use Hindo digits else use Arabic digits
  372.      *                    
  373.      * @return string Arabic glyph joining in UTF-8 hexadecimals stream (take
  374.      *                 care of whole document including English sections as well
  375.      *                 as numbers and arcs etc...)
  376.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  377.      */
  378.     public function utf8Glyphs($str$max_chars 50$hindo true)
  379.     {
  380.         $str str_replace(array("\r\n""\n""\r")" \n "$str);
  381.         $str str_replace("\t""        "$str);
  382.         
  383.         $lines   array();
  384.         $words   explode(' '$str);
  385.         $w_count count($words);
  386.         $c_chars 0;
  387.         $c_words array();
  388.         
  389.         $english  array();
  390.         $en_index = -1;
  391.         $en_start false;
  392.         
  393.         for ($i 0$i $w_count$i++{
  394.             $pattern  '/^(\n?)';
  395.             $pattern .= '[a-z\d\\/\@\#\$\%\^\&\*\(\)\_\~\"\'\[\]\{\}\;\,\|\-\.\:]*';
  396.             $pattern .= '([\.\:\+\=\-\!،؟]?)$/i';
  397.             
  398.             if (preg_match($pattern$words[$i]$matches)) {
  399.                 if ($i == 0{
  400.                     $en_start true;
  401.                 }
  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.             elseif ($en_index != -1{
  414.                 $en_count count($english);
  415.                 
  416.                 for ($j 0$j $en_count$j++{
  417.                     $words[$en_index $j$english[$en_count $j];
  418.                 }
  419.                 
  420.                 $en_index = -1;
  421.                 $english  array();
  422.             }
  423.         }
  424.         
  425.         for ($i 0$i $w_count$i++{
  426.             $w_len mb_strlen($words[$i]1;
  427.             
  428.             if ($c_chars $w_len $max_chars{
  429.                 if (mb_strpos($words[$i]"\n"!== false{
  430.                     $words_nl explode("\n"$words[$i]);
  431.                     
  432.                     array_push($c_words$words_nl[0]);
  433.                     array_push($linesimplode(' '$c_words));
  434.                     
  435.                     $nl_num count($words_nl1;
  436.                     for ($j 1$j $nl_num$j++{
  437.                         array_push($lines$words_nl[$j]);
  438.                     }
  439.                     
  440.                     $c_words array($words_nl[$nl_num]);
  441.                     $c_chars mb_strlen($words_nl[$nl_num]1;
  442.                 else {
  443.                     array_push($c_words$words[$i]);
  444.                     $c_chars += $w_len;
  445.                 }
  446.             else {
  447.                 array_push($linesimplode(' '$c_words));
  448.                 $c_words array($words[$i]);
  449.                 $c_chars $w_len;
  450.             }
  451.         }
  452.         array_push($linesimplode(' '$c_words));
  453.         
  454.         $maxLine count($lines);
  455.         $output  '';
  456.         
  457.         for ($j $maxLine 1$j >= 0$j--{
  458.             $output .= $lines[$j"\n";
  459.         }
  460.         
  461.         $output rtrim($output);
  462.         
  463.         $output $this->preConvert($output);
  464.         if ($hindo{
  465.             $nums   array('0''1''2''3''4''5''6''7''8''9');
  466.             $arNums array('٠''١''٢''٣''٤''٥''٦''٧''٨''٩');
  467.             
  468.             foreach ($nums as $k => $v$p_nums[$k'/'.$v.'/ui';
  469.             $output preg_replace($p_nums$arNums$output);
  470.             
  471.             foreach ($arNums as $k => $v$p_arNums[$k'/([a-z-\d]+)'.$v.'/ui';
  472.             foreach ($nums as $k => $v$r_nums[$k'${1}'.$v;
  473.             $output preg_replace($p_arNums$r_nums$output);
  474.             
  475.             foreach ($arNums as $k => $v$p_arNums[$k'/'.$v.'([a-z-\d]+)/ui';
  476.             foreach ($nums as $k => $v$r_nums[$k$v.'${1}';
  477.             $output preg_replace($p_arNums$r_nums$output);
  478.         }
  479.  
  480.         return $output;
  481.     }
  482.     
  483.     /**
  484.      * Decode all HTML entities (including numerical ones) to regular UTF-8 bytes.
  485.      * Double-escaped entities will only be decoded once
  486.      * ("&amp;lt;" becomes "&lt;", not "<").
  487.      *                   
  488.      * @param string $text    The text to decode entities in.
  489.      * @param array  $exclude An array of characters which should not be decoded.
  490.      *                         For example, array('<', '&', '"'). This affects
  491.      *                         both named and numerical entities.
  492.      *                        
  493.      * @return string 
  494.      */
  495.     protected function decodeEntities($text$exclude array())
  496.     {
  497.         static $table;
  498.         
  499.         // We store named entities in a table for quick processing.
  500.         if (!isset($table)) {
  501.             // Get all named HTML entities.
  502.             $table array_flip(get_html_translation_table(HTML_ENTITIES));
  503.             
  504.             // PHP gives us ISO-8859-1 data, we need UTF-8.
  505.             $table array_map('utf8_encode'$table);
  506.             
  507.             // Add apostrophe (XML)
  508.             $table['&apos;'"'";
  509.         }
  510.         $newtable array_diff($table$exclude);
  511.         
  512.         // Use a regexp to select all entities in one pass, to avoid decoding 
  513.         // double-escaped entities twice.
  514.         //return preg_replace('/&(#x?)?([A-Za-z0-9]+);/e', 
  515.         //                    '$this->decodeEntities2("$1", "$2", "$0", $newtable, 
  516.         //                                             $exclude)', $text);
  517.  
  518.         $pieces explode('&'$text);
  519.         $text   array_shift($pieces);
  520.         foreach ($pieces as $piece{
  521.             if ($piece[0== '#'{
  522.                 if ($piece[1== 'x'{
  523.                     $one '#x';
  524.                 else {
  525.                     $one '#';
  526.                 }
  527.             else {
  528.                 $one '';
  529.             }
  530.             $end   mb_strpos($piece';');
  531.             $start mb_strlen($one);
  532.             
  533.             $two   mb_substr($piece$start$end $start);
  534.             $zero  '&'.$one.$two.';';
  535.             $text .= $this->decodeEntities2($one$two$zero$newtable$exclude).
  536.                      mb_substr($piece$end+1);
  537.         }
  538.         return $text;
  539.     }
  540.     
  541.     /**
  542.      * Helper function for decodeEntities
  543.      * 
  544.      * @param string $prefix    Prefix
  545.      * @param string $codepoint Codepoint
  546.      * @param string $original  Original
  547.      * @param array  &$table    Store named entities in a table
  548.      * @param array  &$exclude  An array of characters which should not be decoded
  549.      * 
  550.      * @return string 
  551.      */
  552.     protected function decodeEntities2($prefix$codepoint$original
  553.                                        &$table&$exclude)
  554.     {
  555.         // Named entity
  556.         if (!$prefix{
  557.             if (isset($table[$original])) {
  558.                 return $table[$original];
  559.             else {
  560.                 return $original;
  561.             }
  562.         }
  563.         
  564.         // Hexadecimal numerical entity
  565.         if ($prefix == '#x'{
  566.             $codepoint base_convert($codepoint1610);
  567.         }
  568.         
  569.         // Encode codepoint as UTF-8 bytes
  570.         if ($codepoint 0x80{
  571.             $str chr($codepoint);
  572.         elseif ($codepoint 0x800{
  573.             $str chr(0xC0 ($codepoint >> 6)) 
  574.                    chr(0x80 ($codepoint 0x3F));
  575.         elseif ($codepoint 0x10000{
  576.             $str chr(0xE0 ($codepoint >> 12)) 
  577.                    chr(0x80 (($codepoint >> 60x3F)) 
  578.                    chr(0x80 ($codepoint 0x3F));
  579.         elseif ($codepoint 0x200000{
  580.             $str chr(0xF0 ($codepoint >> 18)) 
  581.                    chr(0x80 (($codepoint >> 120x3F)) 
  582.                    chr(0x80 (($codepoint >> 60x3F)) 
  583.                    chr(0x80 ($codepoint 0x3F));
  584.         }
  585.         
  586.         // Check for excluded characters
  587.         if (in_array($str$exclude)) {
  588.             return $original;
  589.         else {
  590.             return $str;
  591.         }
  592.     }
  593. }

Documentation generated on Tue, 17 Jan 2012 09:18:15 +0200 by phpDocumentor 1.4.0