Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  psconv.c                                                               */
  4. /*                                                                         */
  5. /*    Some convenience conversions (body).                                 */
  6. /*                                                                         */
  7. /*  Copyright 2006, 2008, 2009, 2012-2013 by                               */
  8. /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  9. /*                                                                         */
  10. /*  This file is part of the FreeType project, and may only be used,       */
  11. /*  modified, and distributed under the terms of the FreeType project      */
  12. /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  13. /*  this file you indicate that you have read the license and              */
  14. /*  understand and accept it fully.                                        */
  15. /*                                                                         */
  16. /***************************************************************************/
  17.  
  18.  
  19. #include <ft2build.h>
  20. #include FT_INTERNAL_POSTSCRIPT_AUX_H
  21. #include FT_INTERNAL_DEBUG_H
  22.  
  23. #include "psconv.h"
  24. #include "psauxerr.h"
  25.  
  26.  
  27.   /*************************************************************************/
  28.   /*                                                                       */
  29.   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  30.   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  31.   /* messages during execution.                                            */
  32.   /*                                                                       */
  33. #undef  FT_COMPONENT
  34. #define FT_COMPONENT  trace_psconv
  35.  
  36.  
  37.   /* The following array is used by various functions to quickly convert */
  38.   /* digits (both decimal and non-decimal) into numbers.                 */
  39.  
  40. #if 'A' == 65
  41.   /* ASCII */
  42.  
  43.   static const FT_Char  ft_char_table[128] =
  44.   {
  45.     /* 0x00 */
  46.     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  47.     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  48.     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  49.      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,
  50.     -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  51.     25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
  52.     -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  53.     25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
  54.   };
  55.  
  56.   /* no character >= 0x80 can represent a valid number */
  57. #define OP  >=
  58.  
  59. #endif /* 'A' == 65 */
  60.  
  61. #if 'A' == 193
  62.   /* EBCDIC */
  63.  
  64.   static const FT_Char  ft_char_table[128] =
  65.   {
  66.     /* 0x80 */
  67.     -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1,
  68.     -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1,
  69.     -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
  70.     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  71.     -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1,
  72.     -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1,
  73.     -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
  74.      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,
  75.   };
  76.  
  77.   /* no character < 0x80 can represent a valid number */
  78. #define OP  <
  79.  
  80. #endif /* 'A' == 193 */
  81.  
  82.  
  83.   FT_LOCAL_DEF( FT_Long )
  84.   PS_Conv_Strtol( FT_Byte**  cursor,
  85.                   FT_Byte*   limit,
  86.                   FT_Long    base )
  87.   {
  88.     FT_Byte*  p = *cursor;
  89.  
  90.     FT_Long   num           = 0;
  91.     FT_Bool   sign          = 0;
  92.     FT_Bool   have_overflow = 0;
  93.  
  94.     FT_Long   num_limit;
  95.     FT_Char   c_limit;
  96.  
  97.  
  98.     if ( p >= limit )
  99.       goto Bad;
  100.  
  101.     if ( base < 2 || base > 36 )
  102.     {
  103.       FT_TRACE4(( "!!!INVALID BASE:!!!" ));
  104.       return 0;
  105.     }
  106.  
  107.     if ( *p == '-' || *p == '+' )
  108.     {
  109.       sign = FT_BOOL( *p == '-' );
  110.  
  111.       p++;
  112.       if ( p == limit )
  113.         goto Bad;
  114.     }
  115.  
  116.     num_limit = 0x7FFFFFFFL / base;
  117.     c_limit   = (FT_Char)( 0x7FFFFFFFL % base );
  118.  
  119.     for ( ; p < limit; p++ )
  120.     {
  121.       FT_Char  c;
  122.  
  123.  
  124.       if ( IS_PS_SPACE( *p ) || *p OP 0x80 )
  125.         break;
  126.  
  127.       c = ft_char_table[*p & 0x7f];
  128.  
  129.       if ( c < 0 || c >= base )
  130.         break;
  131.  
  132.       if ( num > num_limit || ( num == num_limit && c > c_limit ) )
  133.         have_overflow = 1;
  134.       else
  135.         num = num * base + c;
  136.     }
  137.  
  138.     *cursor = p;
  139.  
  140.     if ( have_overflow )
  141.     {
  142.       num = 0x7FFFFFFFL;
  143.       FT_TRACE4(( "!!!OVERFLOW:!!!" ));
  144.     }
  145.  
  146.     if ( sign )
  147.       num = -num;
  148.  
  149.     return num;
  150.  
  151.   Bad:
  152.     FT_TRACE4(( "!!!END OF DATA:!!!" ));
  153.     return 0;
  154.   }
  155.  
  156.  
  157.   FT_LOCAL_DEF( FT_Long )
  158.   PS_Conv_ToInt( FT_Byte**  cursor,
  159.                  FT_Byte*   limit )
  160.  
  161.   {
  162.     FT_Byte*  p = *cursor;
  163.     FT_Byte*  curp;
  164.  
  165.     FT_Long   num;
  166.  
  167.  
  168.     curp = p;
  169.     num  = PS_Conv_Strtol( &p, limit, 10 );
  170.  
  171.     if ( p == curp )
  172.       return 0;
  173.  
  174.     if ( p < limit && *p == '#' )
  175.     {
  176.       p++;
  177.  
  178.       curp = p;
  179.       num  = PS_Conv_Strtol( &p, limit, num );
  180.  
  181.       if ( p == curp )
  182.         return 0;
  183.     }
  184.  
  185.     *cursor = p;
  186.  
  187.     return num;
  188.   }
  189.  
  190.  
  191.   FT_LOCAL_DEF( FT_Fixed )
  192.   PS_Conv_ToFixed( FT_Byte**  cursor,
  193.                    FT_Byte*   limit,
  194.                    FT_Long    power_ten )
  195.   {
  196.     FT_Byte*  p = *cursor;
  197.     FT_Byte*  curp;
  198.  
  199.     FT_Fixed  integral = 0;
  200.     FT_Long   decimal  = 0;
  201.     FT_Long   divider  = 1;
  202.  
  203.     FT_Bool   sign           = 0;
  204.     FT_Bool   have_overflow  = 0;
  205.     FT_Bool   have_underflow = 0;
  206.  
  207.  
  208.     if ( p >= limit )
  209.       goto Bad;
  210.  
  211.     if ( *p == '-' || *p == '+' )
  212.     {
  213.       sign = FT_BOOL( *p == '-' );
  214.  
  215.       p++;
  216.       if ( p == limit )
  217.         goto Bad;
  218.     }
  219.  
  220.     /* read the integer part */
  221.     if ( *p != '.' )
  222.     {
  223.       curp     = p;
  224.       integral = PS_Conv_ToInt( &p, limit );
  225.  
  226.       if ( p == curp )
  227.         return 0;
  228.  
  229.       if ( integral > 0x7FFF )
  230.         have_overflow = 1;
  231.       else
  232.         integral = (FT_Fixed)( (FT_UInt32)integral << 16 );
  233.     }
  234.  
  235.     /* read the decimal part */
  236.     if ( p < limit && *p == '.' )
  237.     {
  238.       p++;
  239.  
  240.       for ( ; p < limit; p++ )
  241.       {
  242.         FT_Char  c;
  243.  
  244.  
  245.         if ( IS_PS_SPACE( *p ) || *p OP 0x80 )
  246.           break;
  247.  
  248.         c = ft_char_table[*p & 0x7f];
  249.  
  250.         if ( c < 0 || c >= 10 )
  251.           break;
  252.  
  253.         if ( decimal < 0xCCCCCCCL )
  254.         {
  255.           decimal = decimal * 10 + c;
  256.  
  257.           if ( !integral && power_ten > 0 )
  258.             power_ten--;
  259.           else
  260.             divider *= 10;
  261.         }
  262.       }
  263.     }
  264.  
  265.     /* read exponent, if any */
  266.     if ( p + 1 < limit && ( *p == 'e' || *p == 'E' ) )
  267.     {
  268.       FT_Long  exponent;
  269.  
  270.  
  271.       p++;
  272.  
  273.       curp     = p;
  274.       exponent = PS_Conv_ToInt( &p, limit );
  275.  
  276.       if ( curp == p )
  277.         return 0;
  278.  
  279.       /* arbitrarily limit exponent */
  280.       if ( exponent > 1000 )
  281.         have_overflow = 1;
  282.       else if ( exponent < -1000 )
  283.         have_underflow = 1;
  284.       else
  285.         power_ten += exponent;
  286.     }
  287.  
  288.     *cursor = p;
  289.  
  290.     if ( !integral && !decimal )
  291.       return 0;
  292.  
  293.     if ( have_overflow )
  294.       goto Overflow;
  295.     if ( have_underflow )
  296.       goto Underflow;
  297.  
  298.     while ( power_ten > 0 )
  299.     {
  300.       if ( integral >= 0xCCCCCCCL )
  301.         goto Overflow;
  302.       integral *= 10;
  303.  
  304.       if ( decimal >= 0xCCCCCCCL )
  305.       {
  306.         if ( divider == 1 )
  307.           goto Overflow;
  308.         divider /= 10;
  309.       }
  310.       else
  311.         decimal *= 10;
  312.  
  313.       power_ten--;
  314.     }
  315.  
  316.     while ( power_ten < 0 )
  317.     {
  318.       integral /= 10;
  319.       if ( divider < 0xCCCCCCCL )
  320.         divider *= 10;
  321.       else
  322.         decimal /= 10;
  323.  
  324.       if ( !integral && !decimal )
  325.         goto Underflow;
  326.  
  327.       power_ten++;
  328.     }
  329.  
  330.     if ( decimal )
  331.     {
  332.       decimal = FT_DivFix( decimal, divider );
  333.       /* it's not necessary to check this addition for overflow */
  334.       /* due to the structure of the real number representation */
  335.       integral += decimal;
  336.     }
  337.  
  338.   Exit:
  339.     if ( sign )
  340.       integral = -integral;
  341.  
  342.     return integral;
  343.  
  344.   Bad:
  345.     FT_TRACE4(( "!!!END OF DATA:!!!" ));
  346.     return 0;
  347.  
  348.   Overflow:
  349.     integral = 0x7FFFFFFFL;
  350.     FT_TRACE4(( "!!!OVERFLOW:!!!" ));
  351.     goto Exit;
  352.  
  353.   Underflow:
  354.     FT_TRACE4(( "!!!UNDERFLOW:!!!" ));
  355.     return 0;
  356.   }
  357.  
  358.  
  359. #if 0
  360.   FT_LOCAL_DEF( FT_UInt )
  361.   PS_Conv_StringDecode( FT_Byte**  cursor,
  362.                         FT_Byte*   limit,
  363.                         FT_Byte*   buffer,
  364.                         FT_Offset  n )
  365.   {
  366.     FT_Byte*  p;
  367.     FT_UInt   r = 0;
  368.  
  369.  
  370.     for ( p = *cursor; r < n && p < limit; p++ )
  371.     {
  372.       FT_Byte  b;
  373.  
  374.  
  375.       if ( *p != '\\' )
  376.       {
  377.         buffer[r++] = *p;
  378.  
  379.         continue;
  380.       }
  381.  
  382.       p++;
  383.  
  384.       switch ( *p )
  385.       {
  386.       case 'n':
  387.         b = '\n';
  388.         break;
  389.       case 'r':
  390.         b = '\r';
  391.         break;
  392.       case 't':
  393.         b = '\t';
  394.         break;
  395.       case 'b':
  396.         b = '\b';
  397.         break;
  398.       case 'f':
  399.         b = '\f';
  400.         break;
  401.       case '\r':
  402.         p++;
  403.         if ( *p != '\n' )
  404.         {
  405.           b = *p;
  406.  
  407.           break;
  408.         }
  409.         /* no break */
  410.       case '\n':
  411.         continue;
  412.         break;
  413.       default:
  414.         if ( IS_PS_DIGIT( *p ) )
  415.         {
  416.           b = *p - '0';
  417.  
  418.           p++;
  419.  
  420.           if ( IS_PS_DIGIT( *p ) )
  421.           {
  422.             b = b * 8 + *p - '0';
  423.  
  424.             p++;
  425.  
  426.             if ( IS_PS_DIGIT( *p ) )
  427.               b = b * 8 + *p - '0';
  428.             else
  429.             {
  430.               buffer[r++] = b;
  431.               b = *p;
  432.             }
  433.           }
  434.           else
  435.           {
  436.             buffer[r++] = b;
  437.             b = *p;
  438.           }
  439.         }
  440.         else
  441.           b = *p;
  442.         break;
  443.       }
  444.  
  445.       buffer[r++] = b;
  446.     }
  447.  
  448.     *cursor = p;
  449.  
  450.     return r;
  451.   }
  452. #endif /* 0 */
  453.  
  454.  
  455.   FT_LOCAL_DEF( FT_UInt )
  456.   PS_Conv_ASCIIHexDecode( FT_Byte**  cursor,
  457.                           FT_Byte*   limit,
  458.                           FT_Byte*   buffer,
  459.                           FT_Offset  n )
  460.   {
  461.     FT_Byte*  p;
  462.     FT_UInt   r   = 0;
  463.     FT_UInt   w   = 0;
  464.     FT_UInt   pad = 0x01;
  465.  
  466.  
  467.     n *= 2;
  468.  
  469. #if 1
  470.  
  471.     p = *cursor;
  472.  
  473.     if ( p >= limit )
  474.       return 0;
  475.  
  476.     if ( n > (FT_UInt)( limit - p ) )
  477.       n = (FT_UInt)( limit - p );
  478.  
  479.     /* we try to process two nibbles at a time to be as fast as possible */
  480.     for ( ; r < n; r++ )
  481.     {
  482.       FT_UInt  c = p[r];
  483.  
  484.  
  485.       if ( IS_PS_SPACE( c ) )
  486.         continue;
  487.  
  488.       if ( c OP 0x80 )
  489.         break;
  490.  
  491.       c = ft_char_table[c & 0x7F];
  492.       if ( (unsigned)c >= 16 )
  493.         break;
  494.  
  495.       pad = ( pad << 4 ) | c;
  496.       if ( pad & 0x100 )
  497.       {
  498.         buffer[w++] = (FT_Byte)pad;
  499.         pad         = 0x01;
  500.       }
  501.     }
  502.  
  503.     if ( pad != 0x01 )
  504.       buffer[w++] = (FT_Byte)( pad << 4 );
  505.  
  506.     *cursor = p + r;
  507.  
  508.     return w;
  509.  
  510. #else /* 0 */
  511.  
  512.     for ( r = 0; r < n; r++ )
  513.     {
  514.       FT_Char  c;
  515.  
  516.  
  517.       if ( IS_PS_SPACE( *p ) )
  518.         continue;
  519.  
  520.       if ( *p OP 0x80 )
  521.         break;
  522.  
  523.       c = ft_char_table[*p & 0x7f];
  524.  
  525.       if ( (unsigned)c >= 16 )
  526.         break;
  527.  
  528.       if ( r & 1 )
  529.       {
  530.         *buffer = (FT_Byte)(*buffer + c);
  531.         buffer++;
  532.       }
  533.       else
  534.         *buffer = (FT_Byte)(c << 4);
  535.  
  536.       r++;
  537.     }
  538.  
  539.     *cursor = p;
  540.  
  541.     return ( r + 1 ) / 2;
  542.  
  543. #endif /* 0 */
  544.  
  545.   }
  546.  
  547.  
  548.   FT_LOCAL_DEF( FT_UInt )
  549.   PS_Conv_EexecDecode( FT_Byte**   cursor,
  550.                        FT_Byte*    limit,
  551.                        FT_Byte*    buffer,
  552.                        FT_Offset   n,
  553.                        FT_UShort*  seed )
  554.   {
  555.     FT_Byte*  p;
  556.     FT_UInt   r;
  557.     FT_UInt   s = *seed;
  558.  
  559.  
  560. #if 1
  561.  
  562.     p = *cursor;
  563.  
  564.     if ( p >= limit )
  565.       return 0;
  566.  
  567.     if ( n > (FT_UInt)(limit - p) )
  568.       n = (FT_UInt)(limit - p);
  569.  
  570.     for ( r = 0; r < n; r++ )
  571.     {
  572.       FT_UInt  val = p[r];
  573.       FT_UInt  b   = ( val ^ ( s >> 8 ) );
  574.  
  575.  
  576.       s         = ( (val + s)*52845U + 22719 ) & 0xFFFFU;
  577.       buffer[r] = (FT_Byte) b;
  578.     }
  579.  
  580.     *cursor = p + n;
  581.     *seed   = (FT_UShort)s;
  582.  
  583. #else /* 0 */
  584.  
  585.     for ( r = 0, p = *cursor; r < n && p < limit; r++, p++ )
  586.     {
  587.       FT_Byte  b = (FT_Byte)( *p ^ ( s >> 8 ) );
  588.  
  589.  
  590.       s = (FT_UShort)( ( *p + s ) * 52845U + 22719 );
  591.       *buffer++ = b;
  592.     }
  593.     *cursor = p;
  594.     *seed   = s;
  595.  
  596. #endif /* 0 */
  597.  
  598.     return r;
  599.   }
  600.  
  601.  
  602. /* END */
  603.