/home/andreas/src/svn/mapnik/include/mapnik/unicode.hpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * 
00003  * This file is part of Mapnik (c++ mapping toolkit)
00004  *
00005  * Copyright (C) 2006 Artem Pavlenko
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020  *
00021  *****************************************************************************/
00022 
00023 //$Id$
00024 #ifndef UNICODE_HPP
00025 #define UNICODE_HPP
00026 
00027 #include <string>
00028 #include <boost/utility.hpp>
00029 
00030 #ifdef USE_FRIBIDI
00031 #include <fribidi/fribidi.h>
00032 #endif
00033 
00034 #include <iconv.h>
00035 
00036 namespace mapnik {
00037     
00038 /*
00039 ** Use FRIBIDI to encode the string.
00040 ** The return value must be freed by the caller.
00041 */
00042 
00043 #ifdef USE_FRIBIDI
00044     inline wchar_t* bidi_string(const wchar_t *logical)
00045     {
00046         FriBidiCharType base = FRIBIDI_TYPE_ON;
00047         size_t len;
00048 
00049         len = wcslen(logical);
00050 
00051         FriBidiChar *visual;
00052 
00053         FriBidiStrIndex *ltov, *vtol;
00054         FriBidiLevel *levels;
00055         FriBidiStrIndex new_len;
00056         fribidi_boolean log2vis;
00057         
00058         visual = (FriBidiChar *) malloc (sizeof (FriBidiChar) * (len + 1));
00059         ltov = 0;
00060         vtol = 0;
00061         levels = 0;
00062 
00063         /* Create a bidi string. */
00064         log2vis = fribidi_log2vis ((FriBidiChar *)logical, len, &base,
00065                 /* output */
00066                 visual, ltov, vtol, levels);
00067 
00068         if (!log2vis) {
00069             return 0;
00070         }
00071 
00072         new_len = len;
00073 
00074         return (wchar_t *)visual;
00075     }
00076 #endif
00077 
00078 
00079     inline std::wstring to_unicode(std::string const& text)
00080     {
00081         std::wstring out;
00082         unsigned long code = 0;
00083         int expect = 0;
00084         std::string::const_iterator itr=text.begin();
00085         std::string::const_iterator end=text.end();
00086         while ( itr != end)
00087         {
00088             unsigned p = (*itr++) & 0xff;
00089             if ( p >= 0xc0)
00090             {
00091                 if ( p < 0xe0)      // U+0080 - U+07ff
00092                 {
00093                     expect = 1;
00094                     code = p & 0x1f;
00095                 }
00096                 else if ( p < 0xf0)  // U+0800 - U+ffff
00097                 {
00098                     expect = 2;
00099                     code = p & 0x0f;
00100                 }
00101                 else if ( p  < 0xf8) // U+1000 - U+10ffff
00102                 {
00103                     expect = 3;
00104                     code = p & 0x07;
00105                 }
00106                 continue;
00107             }
00108             else if (p >= 0x80)
00109             {
00110                 --expect;
00111                 if (expect >= 0)
00112                 {
00113                     code <<= 6;
00114                     code += p & 0x3f;
00115                 }
00116                 if (expect > 0)
00117                     continue;
00118                 expect = 0;
00119             }
00120             else 
00121             {
00122                 code = p;            // U+0000 - U+007f (ascii)
00123             }
00124             out.push_back(wchar_t(code));
00125         }
00126 #ifdef USE_FRIBIDI
00127         wchar_t *bidi_text = bidi_string(out.c_str());
00128         out = bidi_text;
00129         free(bidi_text);
00130 #endif
00131         
00132         return out;
00133     }
00134    
00135    inline std::wstring latin1_to_unicode(std::string const& text)
00136    {
00137       std::wstring out;
00138       std::string::const_iterator itr=text.begin();
00139       std::string::const_iterator end=text.end();
00140       while ( itr != end)
00141       {
00142          unsigned p = (*itr++) & 0xff;     
00143          out.push_back(wchar_t(p));
00144       }      
00145       return out;
00146    }
00147 
00148    inline std::string latin1_to_unicode2(std::string const& text)
00149    {
00150       std::string out;
00151       std::string::const_iterator itr=text.begin();
00152       std::string::const_iterator end=text.end();
00153       while ( itr != end)
00154       {
00155          out.push_back(0x00);
00156          out.push_back(*itr++);  
00157       }      
00158       return out;
00159    }
00160    
00161    class transcoder : private boost::noncopyable
00162    {
00163       public:
00164          explicit transcoder (std::string const& encoding)
00165          {
00166            //desc_ = iconv_open("UCS-2",encoding.c_str());
00167          }
00168          
00169          std::wstring transcode(std::string const& input) const
00170          {
00171            //return to_unicode(input);
00172            return to_unicode(input);
00173            /*
00174             std::string buf(input.size() * 2,0);
00175             size_t inleft = input.size();
00176             const char * in  = input.data();
00177             size_t outleft = buf.size();
00178             char * out = const_cast<char*>(buf.data());
00179             
00180             iconv(desc_,&in,&inleft,&out,&outleft);
00181             
00182             std::string::const_iterator itr = buf.begin();
00183             std::string::const_iterator end = buf.end();
00184             wchar_t wch = 0;
00185             bool state = false;
00186             std::wstring unicode;
00187             size_t num_char = buf.size() - outleft;
00188             for ( ; itr != end; ++itr)
00189             {
00190                if (!state)
00191                {
00192                   wch = (*itr & 0xff);
00193                   state = true;
00194                }
00195                else 
00196                {
00197                   wch |= *itr << 8 ;
00198                   unicode.push_back(wchar_t(wch));
00199                   state = false;
00200                }
00201                if (!num_char--) break;
00202             }
00203                      
00204 #ifdef USE_FRIBIDI
00205             if (unicode.length() > 0)
00206             {
00207                wchar_t *bidi_text = bidi_string(unicode.c_str());
00208                unicode = bidi_text;
00209                free(bidi_text);
00210             }
00211 #endif
00212             return unicode;
00213            */
00214          }
00215          
00216          ~transcoder()
00217          {
00218            //iconv_close(desc_);
00219          }
00220 
00221    private:
00222       iconv_t desc_;
00223    };
00224 }
00225 
00226 #endif // UNICODE_HPP

Generated on Thu Jul 19 17:59:27 2007 for Mapnik by  doxygen 1.4.7