Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlCore/Say.cpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
00029 /*                                                                                    */
00030 /**************************************************************************************/
00031 
00032 #include <vlCore/Say.hpp>
00033 #include <cmath>
00034 
00035 using namespace vl;
00036 
00037 SayArg::SayArg()
00038 {
00039   init();
00040 }
00041 
00042 SayArg::SayArg(void* d)
00043 {
00044   init();
00045   ulonglong = reinterpret_cast<unsigned long long>(d);
00046   type = ULONGLONG;
00047 }
00048 
00049 SayArg::SayArg(const std::string& d)
00050 {
00051   init();
00052   str = d.c_str();
00053   type = STRING;
00054 }
00055 
00056 SayArg::SayArg(const unsigned char* d)
00057 {
00058   init();
00059   if (d)
00060     str = (const char*)d;
00061   type = STRING;
00062 }
00063 
00064 SayArg::SayArg(const char* d)
00065 {
00066   init();
00067   if (d)
00068     str = d;
00069   type = STRING;
00070 }
00071 
00072 SayArg::SayArg(const String& d)
00073 {
00074   init();
00075   str = d;
00076   type = STRING;
00077 }
00078 
00079 SayArg::SayArg(double d)
00080 {
00081   init();
00082   float64 = d;
00083   type = FLOAT64;
00084 }
00085 
00086 SayArg::SayArg(float d)
00087 {
00088   init();
00089   float64 = d;
00090   type = FLOAT64;
00091 }
00092 
00093 SayArg::SayArg(unsigned char d)
00094 {
00095   init();
00096   ulonglong = d;
00097   type = ULONGLONG;
00098 }
00099 
00100 SayArg::SayArg(signed char d)
00101 {
00102   init();
00103   slonglong = d;
00104   type = SLONGLONG;
00105 }
00106 
00107 SayArg::SayArg(unsigned short d)
00108 {
00109   init();
00110   ulonglong = d;
00111   type = ULONGLONG;
00112 }
00113 
00114 SayArg::SayArg(signed short d)
00115 {
00116   init();
00117   slonglong = d;
00118   type = SLONGLONG;
00119 }
00120 
00121 SayArg::SayArg(unsigned int d)
00122 {
00123   init();
00124   ulonglong = d;
00125   type = ULONGLONG;
00126 }
00127 
00128 SayArg::SayArg(signed int d)
00129 {
00130   init();
00131   slonglong = d;
00132   type = SLONGLONG;
00133 }
00134 
00135 SayArg::SayArg(unsigned long d)
00136 {
00137   init();
00138   ulonglong = d;
00139   type = ULONGLONG;
00140 }
00141 
00142 SayArg::SayArg(signed long d)
00143 {
00144   init();
00145   slonglong = d;
00146   type = SLONGLONG;
00147 }
00148 
00149 SayArg::SayArg(unsigned long long d)
00150 {
00151   init();
00152   ulonglong = d;
00153   type = ULONGLONG;
00154 }
00155 
00156 SayArg::SayArg(signed long long d)
00157 {
00158   init();
00159   slonglong = d;
00160   type = SLONGLONG;
00161 }
00162 
00163 void SayArg::init()
00164 {
00165   type = NO_TYPE;
00166   float64 = 0;
00167   ulonglong = 0;
00168   slonglong = 0;
00169 }
00170 
00171 String Say::parse( const Say& pset ) const
00172 {
00173   String out;
00174   String fmt = pset.format_string;
00175 
00176   int param_idx = 0;
00177 
00178   int eur = -1;
00179   int base = -1;
00180   int field = -1;
00181   int decimals = -1;
00182   int align = -1; 
00183   int fill = -1;
00184   int plus = -1;
00185   
00186   int fmtstart = -1;
00187 
00188   // %H+014.5n
00189   bool fmtdata = false;
00190   for(int i=0; i<(int)fmt.length(); ++i)
00191   {
00192     int ch       = (i<(int)fmt.length())   ? (int)fmt[i+0] : -1;
00193     int next_ch  = (i<(int)fmt.length()-1) ? (int)fmt[i+1] : -1;
00194     int nnext_ch = (i<(int)fmt.length()-2) ? (int)fmt[i+2] : -1;
00195 
00196     if (!fmtdata)
00197     {
00198       if (ch == '%' && next_ch == '%')
00199       {
00200         out += '%';
00201         ++i;
00202       }
00203       else
00204       if (ch == '%')
00205       {
00206         if (param_idx < (int)pset.size())
00207         {
00208           fmtdata = true;
00209           fmtstart = i;
00210         }
00211         else
00212         {
00213           out += " !!!too few parameters: %";
00214         }
00215       }
00216       else
00217       if (ch >= 0)
00218       {
00219         out += (unsigned short)ch;
00220       }
00221     }
00222     else
00223     {
00224 
00225       if(eur == -1)
00226       {
00227         if (ch == '$')
00228         {
00229           eur = 1;
00230           continue;
00231         }
00232       }
00233 
00234       if (base == -1)
00235       {
00236         switch(ch)
00237         {
00238         case 'b': base = 2;  break;
00239         case 'o': base = 8;  break;
00240         case 'd': base = 10; break;
00241         case 'h': base = 16; break;
00242         }
00243         if (base != -1)
00244         {
00245           if (eur == -1)
00246             eur = 0;
00247           continue;
00248         }
00249       }
00250 
00251       if (plus == -1)
00252       {
00253         switch(ch)
00254         {
00255         case '+': plus = 1; break;
00256         }
00257         if (plus != -1)
00258         {
00259           if (base == -1)
00260             base = 10;
00261           if (eur == -1)
00262             eur = 0;
00263           continue;
00264         }
00265       }
00266 
00267       if (fill == -1)
00268       {
00269         switch(ch)
00270         {
00271         case '0': fill = '0'; break;
00272         case ' ': fill = ' '; break;
00273         }
00274         if (fill != -1)
00275         {
00276           if (base == -1)
00277             base = 10;
00278           if (plus == -1)
00279             plus = 0;
00280           if (eur == -1)
00281             eur = 0;
00282           continue;
00283         }
00284       }
00285 
00286       if (field == -1)
00287       {
00288         if (ch >= '0' && ch <= '9')
00289         {
00290           field = ch - '0';
00291           if (next_ch >= '0' && next_ch <= '9')
00292           {
00293             field = field*10 + next_ch - '0';
00294             ++i;
00295           }
00296         }
00297 
00298         if (field != -1)
00299         {
00300           if (base == -1)
00301             base = 10;
00302           if (plus == -1)
00303             plus = 0;
00304           if (fill == -1)
00305             fill = ' ';
00306           if (eur == -1)
00307             eur = 0;
00308           continue;
00309         }
00310       }
00311 
00312       if (decimals == -1)
00313       {
00314         if(ch == '.')
00315         {
00316           if (next_ch >= '0' && next_ch <= '9')
00317           {
00318             decimals = next_ch - '0';
00319             ++i;
00320             if (nnext_ch >= '0' && nnext_ch <= '9')
00321             {
00322               decimals = decimals*10 + nnext_ch - '0';
00323               ++i;
00324             }
00325           }
00326         }
00327 
00328         if (decimals != -1)
00329         {
00330           if (base == -1)
00331             base = 10;
00332           if (plus == -1)
00333             plus = 0;
00334           if (fill == -1)
00335             fill = ' ';
00336           if (field == -1)
00337             field = 0;
00338           if (eur == -1)
00339             eur = 0;
00340           continue;
00341         }
00342       }
00343 
00344       if (align == -1)
00345       {
00346         if(ch == '=')
00347           align = 0;
00348         if(ch == '<')
00349           align = 1;
00350         if(ch == '>')
00351           align = 2;
00352 
00353         if (align != -1)
00354         {
00355           if (base == -1)
00356             base = 10;
00357           if (plus == -1)
00358             plus = 0;
00359           if (fill == -1)
00360             fill = ' ';
00361           if (field == -1)
00362             field = 0;
00363           if (eur == -1)
00364             eur = 0;
00365           if (decimals == -1)
00366           {
00367             switch(pset[param_idx].type)
00368             {
00369             case SayArg::FLOAT64: decimals = 6; break;
00370             default: decimals = 0; break;
00371             }
00372           }
00373           continue;
00374         }
00375       }
00376 
00377       // generate formatted string
00378 
00379       // output parameter
00380       const SayArg& p = pset[param_idx];
00381 
00382       if (ch == 'c')
00383       {
00384         if (fmtstart != i-1)
00385           out += " !!! '%c' does not need arguments !!! ";
00386 
00387         switch(p.type)
00388         {
00389         case SayArg::FLOAT64: out += (char)p.float64; break;
00390         case SayArg::SLONGLONG: out += (char)p.slonglong; break;
00391         case SayArg::ULONGLONG: out += (char)p.ulonglong; break;
00392         default:
00393           out += " !!! wrong argument type for '%c' !!! ";
00394           break;
00395         }
00396 
00397       }
00398       else
00399       if (ch == 's')
00400       {
00401         if (fmtstart != i-1)
00402           out += " !!! '%s' does not need arguments !!! ";
00403 
00404         switch(p.type)
00405         {
00406         case SayArg::STRING: out += p.str; break;
00407         default:
00408           out += " !!! wrong argument type for '%s' !!! ";
00409           break;
00410         }
00411 
00412       }
00413       else
00414       if (ch == 'n' || ch == 'N' || ch == 'e' || ch == 'E')
00415       {
00416 
00417         if (param_idx<(int)pset.size())
00418         {
00419           if (decimals == -1)
00420           {
00421             switch(p.type)
00422             {
00423             case SayArg::FLOAT64: decimals = 6; break;
00424             default: decimals = 0; break;
00425             }
00426           }
00427 
00428           if (base == -1)
00429             base = 10;
00430           if (field == -1)
00431             field = 0;
00432           if (decimals == -1)
00433             decimals = 0;
00434           if (fill == -1)
00435             fill = ' ';
00436           if (plus == -1)
00437             plus = 0;
00438           if (align == -1)
00439             align = 2;
00440           if (eur == -1)
00441             eur = 0;
00442 
00443           switch(p.type)
00444           {
00445           case SayArg::FLOAT64:   out += format(p.float64, base, field, decimals, align, fill, plus, ch, eur); break;
00446           case SayArg::SLONGLONG: out += format(p.slonglong, base, field, decimals, align, fill, plus, ch, eur); break;
00447           case SayArg::ULONGLONG: out += format(p.ulonglong, base, field, decimals, align, fill, plus, ch, eur); break;
00448           default: 
00449             out += " !!! wrong argument type for '%n' !!! ";
00450             break;
00451           }
00452         }
00453         else
00454         {
00455           out += " !!!missing parameter!!! ";
00456           if (ch != -1)
00457             i--;
00458         }
00459       }
00460       else
00461       {
00462         out += " !!!format error: unexpected '";
00463         out += (char)ch;
00464         out += "' !!! ";
00465       }
00466 
00467       fmtdata = false;
00468       align = -1;
00469       base = -1;
00470       field = -1;
00471       decimals = -1;
00472       align = -1; 
00473       fill = -1;
00474       plus = -1;
00475       eur = -1;
00476 
00477       param_idx++;
00478     }
00479   }
00480 
00481   if (fmtdata)
00482   {
00483     out += " !!!truncated format!!! ";
00484     param_idx++;
00485   }
00486 
00487   if (param_idx < (int)pset.size())
00488     out += " !!!too many parameters!!! ";
00489 
00490   return out;
00491   // ... fare in modo che l'output venga generato anche quando non c'e' il carattere finale ...
00492 }
00493 
00494 String Say::euronotation(const String& str, int base) const
00495 {
00496   String tmp;
00497   int pos = (int)str.length();
00498   if ( str.contains('.') )
00499   {
00500     while(pos--)
00501     {
00502       if (str[pos] == '.')
00503       {
00504         tmp.insert(0, ',');
00505         break;
00506       }
00507       tmp.insert(0, str[pos]);
00508     }
00509     if (pos < 0)
00510       pos = (int)str.length();
00511   }
00512 
00513   int count = 0;
00514   int wait = 3;
00515   if (base == 2)
00516     wait = 4;
00517   if (base == 16)
00518     wait = 2;
00519   while(pos--)
00520   {
00521     if (count && count % wait == 0)
00522     {
00523       tmp.insert(0, '.');
00524     }
00525     tmp.insert(0, str[pos]);
00526     count ++;
00527   }
00528 
00529   return tmp;
00530 }
00531   
00532 String Say::format(unsigned long long n, int base, int field, int decimals, int align, int fill, int plus, int finalizer, int eur) const
00533 {
00534   if (field < 0)
00535     field = -field;
00536 
00537   if (field > 1024)
00538     field = 1024;
00539 
00540   if (decimals < 0)
00541     decimals = -decimals;
00542   if (decimals > 20)
00543     decimals = 20;
00544 
00545   if (align != 0 && align != 1 && align != 2)
00546     align = 0;
00547 
00548   if (base > 16)
00549     base = 16;
00550 
00551   if (base < 2)
00552     base = 2;
00553 
00554   String str;
00555 
00556   const char* hex = "0123456789abcdef";
00557 
00558   // UNSIGNED INT ALGORITHM
00559 
00560   int k = base;
00561   do
00562   {
00563     int x = (int)(n % base);
00564     int c = x/(k/base);
00565     str.insert(0, hex[c]);
00566     n = n  / base;
00567   }
00568   while(n);
00569 
00570   if (decimals)
00571   {
00572     str += '.';
00573     int i = decimals;
00574     while(i--)
00575       str += '0';
00576   }
00577 
00578   bool negative = false;
00579 
00580   return pipeline(str, base, field, decimals, finalizer, align, eur, fill, negative, plus); 
00581 }
00582 
00583 String Say::format(signed long long nn, int base, int field, int decimals, int align, int fill, int plus, int finalizer, int eur) const
00584 {
00585   if (field < 0)
00586     field = -field;
00587 
00588   if (field > 1024)
00589     field = 1024;
00590 
00591   if (decimals < 0)
00592     decimals = -decimals;
00593   if (decimals > 20)
00594     decimals = 20;
00595 
00596   if (align != 0 && align != 1 && align != 2)
00597     align = 0;
00598 
00599   if (base > 16)
00600     base = 16;
00601 
00602   if (base < 2)
00603     base = 2;
00604 
00605   String str;
00606 
00607   const char* hex = "0123456789abcdef";
00608 
00609   // SIGNED INT ALGORITHM
00610 
00611   bool negative = nn < 0;
00612   unsigned long long n;
00613 
00614   if (nn<0 && -nn<0) // overflow
00615     n = (unsigned long long)nn;
00616   else
00617   if (nn<0)
00618     n = - nn;
00619   else
00620     n = nn;
00621 
00622   //if (n < 0)
00623   // n = 0;
00624 
00625   int k = base;
00626   do
00627   {
00628     int x = (int)(n % base);
00629     int c = x/(k/base);
00630     str.insert(0, hex[c]);
00631     n = n  / base;
00632   }
00633   while(n);
00634   
00635   if (decimals)
00636   {
00637     str += '.';
00638     int i = decimals;
00639     while(i--)
00640       str += '0';
00641   }
00642 
00643   return pipeline(str, base, field, decimals, finalizer, align, eur, fill, negative, plus); 
00644 }
00645   
00646 String Say::format(double num, int base, int field, int decimals, int align, int fill, int plus, int finalizer, int eur) const
00647 {
00648   if (field < 0)
00649     field = -field;
00650   if (field > 1024)
00651     field = 1024;
00652 
00653   if (decimals < 0)
00654     decimals = -decimals;
00655   if (decimals > 20)
00656     decimals = 20;
00657 
00658   if (align != 0 && align != 1 && align != 2)
00659     align = 0;
00660 
00661   if (base > 16)
00662     base = 16;
00663 
00664   if (base < 2)
00665     base = 2;
00666 
00667   String str;
00668 
00669   const char* hex = "0123456789abcdef";
00670 
00671   double f = num;
00672 
00673   // INDEFINITE = - 127 192 0 0
00674   // -INFINITE  = - 127 128 0 0
00675   // +INFINITE  = + 127 128 0 0 
00676   float tmp = (float)f;
00677   unsigned char *nan= (unsigned char*)&tmp;
00678   const char* sign = nan[3] >= 128 ? "-" : "+";
00679   unsigned char exp = (nan[3] << 1) + (nan[2] >> 7);
00680   nan[2] &= 127;
00681   unsigned int frac = nan[0] + (nan[1] << 8) + (nan[2] << 16);
00682 
00683   bool negative = false;
00684   if (exp == 255 && frac == 0)
00685   {
00686     return String(sign) + "#INF";
00687   }
00688   else
00689   if (exp == 255 && frac != 0)
00690   {
00691     return "#NAN";
00692   }
00693   else
00694   {
00695     // ROUNDING FOR FRACTIONAL PART
00696 
00697     if (finalizer == 'n' || finalizer == 'N')
00698     {
00699       double fp = f - floor(f); 
00700       double eps = base/2;
00701       int dec = decimals;
00702       do
00703       {
00704         if ( !(dec--) )
00705           break;
00706 
00707         int c = (int)(fp * base);
00708         fp = fp * base - c;
00709 
00710         eps /= base;
00711 
00712         if (c<0 || c>15)
00713         {
00714           return "#ERR";
00715         }
00716 
00717         if (dec == 0) // round only if all the decimals are here
00718         {
00719           // program rounded fp
00720           f += eps/base;
00721           break;
00722         }
00723       }
00724       while(fp>0);
00725     }
00726       
00727     if (f < 0)
00728     {
00729       f = -f;
00730       negative = true;
00731     }
00732     double n = floor(f);
00733 
00734     // INTEGER PART
00735 
00736     int count = 0; 
00737     unsigned int base2 = base*base;
00738     unsigned int base3 = base*base*base;
00739     unsigned int base4 = base*base*base*base;
00740     unsigned int base5 = base*base*base*base*base;
00741     unsigned int base6 = base*base*base*base*base*base;
00742     unsigned int base7 = base*base*base*base*base*base*base; // maximum number in base 16
00743     while (floor(n))
00744     {
00745       if (n>=base7)
00746       {
00747         n /= base7;
00748         count+=7;
00749       }
00750       else
00751       if (n>=base6)
00752       {
00753         n /= base6;
00754         count+=6;
00755       }
00756       else
00757       if (n>=base5)
00758       {
00759         n /= base5;
00760         count+=5;
00761       }
00762       else
00763       if (n>=base4)
00764       {
00765         n /= base4;
00766         count+=4;
00767       }
00768       else
00769       if (n>=base3)
00770       {
00771         n /= base3;
00772         count+=3;
00773       }
00774       else
00775       if (n>=base2)
00776       {
00777         n /= base2;
00778         count+=2;
00779       }
00780       else
00781       {
00782         n = n / base;
00783         count++;
00784       }
00785     }
00786 
00787     // prevents rounding errors
00788     double eps = (base / 2.0) / base;
00789     for(int i=0; i<count; ++i)
00790     {
00791       eps /= base;
00792     }
00793     n+=eps;
00794 
00795     if (count)
00796     {
00797       do
00798       {
00799         int c = (int)(n * (double)base);
00800         n = n * (double)base - floor(n * (double)base);
00801         int next = (int)(n * base);
00802 
00803         if (c<0 || c>15 || next<0 || next>15)
00804         {
00805           return "#ERR";
00806         }
00807 
00808         str += hex[c];
00809       }
00810       while(--count);
00811     }
00812     else
00813       str += '0';
00814 
00815     str += '.';
00816 
00817     // FRACTIONAL PART
00818 
00819     double fp = f - floor(f);
00820     do
00821     {
00822       int c = (int)(fp * base);
00823       fp = fp * base - c;
00824 
00825       if (c<0 || c>15)
00826       {
00827         return "#ERR";
00828       }
00829 
00830       str += hex[c];
00831     }
00832     while(fp>0);
00833 
00834     // COMMON PIPELINE
00835 
00836     // (1) EXPONENTIAL SHIFT
00837     // (2) CLIP & FILL DECIMALS
00838     // (3) EXPONENTIAL DECORATIONS
00839     // (4) EURO NOTATION
00840     // (5) FIELD, ALIGN AND SIGN
00841     // (6) CASE TRANSFORM
00842 
00843     return pipeline(str, base, field, decimals, finalizer, align, eur, fill, negative, plus);
00844   }
00845 }
00846 
00847 String Say::pipeline(const String& in_str, int base, int field, int decimals, int finalizer, int align, int eur, int fill, int negative, int plus) const
00848 {
00849   String str = in_str;
00850   // EXPONENTIAL SHIFT
00851 
00852   int shift = 0;
00853   // exponential notation
00854   if (finalizer == 'e' || finalizer == 'E')
00855   {
00856     int ptpos = (int)str.length(); // point position
00857     int nzpos = -1; // non zero position
00858     for(int i=0; i<(int)str.length(); ++i)
00859     {
00860       if(str[i] != '0' && nzpos == -1 && str[i] != '.')
00861         nzpos = i;
00862       else
00863       if (str[i] == '.')
00864         ptpos = i;
00865     }
00866 
00867     if (nzpos == -1)
00868       shift = 0;
00869     else
00870       shift = ptpos - nzpos - ( (ptpos > nzpos) ? 1 : 0 );
00871 
00872     // remove the point
00873     str.remove( ptpos, 1 );
00874 
00875     // remove all the zeros on the left
00876     while( str.length() && str[0] == '0' )
00877       str.remove(0);
00878 
00879     // reinsert the point at the 2-nd position
00880     // with up to 2 zero if needed.
00881     if (str.length() == 1)
00882       str += '0';
00883     if (str.length() == 0)
00884       str = "00";
00885 
00886     str.insert(1, '.');
00887   }
00888 
00889   // CLIP AND FILL DECIMALS
00890 
00891   // position of the dot
00892   if ( !str.contains('.') )
00893     str += ".0";
00894   int pos = str.find('.');
00895   // number of decimals
00896   int decs = (int)str.length() - pos -1;
00897   // trim decimals
00898   if (decs > decimals)
00899   {
00900     // remove also the dot
00901     int dot = decimals == 0 ? 1 : 0;
00902     str.resize(str.length() - (decs - decimals + dot));
00903   }
00904   else
00905   {
00906     // add missing decimals
00907     int i = decimals - decs;
00908     while(i--)
00909       str += '0';
00910   }
00911 
00912   // EXPONENTIAL DECORATION
00913 
00914   if (finalizer == 'e' || finalizer == 'E')
00915   {
00916     str += 'e';
00917     str += format((signed long long)shift, base, 0, 0, 2, 0, 1, 0,0);
00918   }
00919   else
00920   // EURO NOTATION
00921 
00922   if (eur)
00923     str = euronotation(str, base);
00924 
00925   // FIELD, SIGN, ALIGN
00926 
00927   int right = (field - (int)str.length()) / 2;
00928   right = right < 0 ? 0 : right;
00929 
00930   int left =  (field - (int)str.length()) - right;
00931   left = left < 0 ? 0 : left;
00932 
00933   if (align == 1) // left
00934   {
00935     right += left;
00936     left = 0;
00937   }
00938   else
00939   if (align == 2) // right
00940   {
00941     left += right;
00942     right = 0;
00943   }
00944 
00945   // fill left
00946   str.insert(0, (wchar_t)fill, left);
00947 
00948   // fill right
00949   str.append(fill, right);
00950 
00951   if (negative)
00952   {
00953     if (left)
00954       str.remove(0);
00955     else
00956     if (right)
00957       str.resize(str.length()-1);
00958 
00959     str.insert(0, '-');
00960   }
00961   else
00962   if(plus)
00963   {
00964     if (left)
00965       str.remove(0);
00966     else
00967     if (right)
00968       str.resize(str.length()-1);
00969 
00970     str.insert(0, '+');
00971   }
00972 
00973   // CASE TRANSFORM
00974 
00975   if (finalizer == 'N' || finalizer == 'E')
00976   {
00977     for(int i=0; i<(int)str.length(); ++i)
00978       if (str[i] >= 'a' && str[i] <= 'z')
00979         str[i] = str[i] - 'a' + 'A';
00980   }
00981 
00982   return str;
00983 }
00984 

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:31.
Permission is granted to use this page to write and publish articles regarding Visualization Library.