Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  pfrsbit.c                                                              */
  4. /*                                                                         */
  5. /*    FreeType PFR bitmap loader (body).                                   */
  6. /*                                                                         */
  7. /*  Copyright 2002, 2003, 2006, 2009, 2010, 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 "pfrsbit.h"
  20. #include "pfrload.h"
  21. #include FT_INTERNAL_DEBUG_H
  22. #include FT_INTERNAL_STREAM_H
  23.  
  24. #include "pfrerror.h"
  25.  
  26. #undef  FT_COMPONENT
  27. #define FT_COMPONENT  trace_pfr
  28.  
  29.  
  30.   /*************************************************************************/
  31.   /*************************************************************************/
  32.   /*****                                                               *****/
  33.   /*****                      PFR BIT WRITER                           *****/
  34.   /*****                                                               *****/
  35.   /*************************************************************************/
  36.   /*************************************************************************/
  37.  
  38.   typedef struct  PFR_BitWriter_
  39.   {
  40.     FT_Byte*  line;      /* current line start                    */
  41.     FT_Int    pitch;     /* line size in bytes                    */
  42.     FT_Int    width;     /* width in pixels/bits                  */
  43.     FT_Int    rows;      /* number of remaining rows to scan      */
  44.     FT_Int    total;     /* total number of bits to draw          */
  45.  
  46.   } PFR_BitWriterRec, *PFR_BitWriter;
  47.  
  48.  
  49.   static void
  50.   pfr_bitwriter_init( PFR_BitWriter  writer,
  51.                       FT_Bitmap*     target,
  52.                       FT_Bool        decreasing )
  53.   {
  54.     writer->line   = target->buffer;
  55.     writer->pitch  = target->pitch;
  56.     writer->width  = target->width;
  57.     writer->rows   = target->rows;
  58.     writer->total  = writer->width * writer->rows;
  59.  
  60.     if ( !decreasing )
  61.     {
  62.       writer->line += writer->pitch * ( target->rows-1 );
  63.       writer->pitch = -writer->pitch;
  64.     }
  65.   }
  66.  
  67.  
  68.   static void
  69.   pfr_bitwriter_decode_bytes( PFR_BitWriter  writer,
  70.                               FT_Byte*       p,
  71.                               FT_Byte*       limit )
  72.   {
  73.     FT_Int    n, reload;
  74.     FT_Int    left = writer->width;
  75.     FT_Byte*  cur  = writer->line;
  76.     FT_UInt   mask = 0x80;
  77.     FT_UInt   val  = 0;
  78.     FT_UInt   c    = 0;
  79.  
  80.  
  81.     n = (FT_Int)( limit - p ) * 8;
  82.     if ( n > writer->total )
  83.       n = writer->total;
  84.  
  85.     reload = n & 7;
  86.  
  87.     for ( ; n > 0; n-- )
  88.     {
  89.       if ( ( n & 7 ) == reload )
  90.         val = *p++;
  91.  
  92.       if ( val & 0x80 )
  93.         c |= mask;
  94.  
  95.       val  <<= 1;
  96.       mask >>= 1;
  97.  
  98.       if ( --left <= 0 )
  99.       {
  100.         cur[0] = (FT_Byte)c;
  101.         left   = writer->width;
  102.         mask   = 0x80;
  103.  
  104.         writer->line += writer->pitch;
  105.         cur           = writer->line;
  106.         c             = 0;
  107.       }
  108.       else if ( mask == 0 )
  109.       {
  110.         cur[0] = (FT_Byte)c;
  111.         mask   = 0x80;
  112.         c      = 0;
  113.         cur ++;
  114.       }
  115.     }
  116.  
  117.     if ( mask != 0x80 )
  118.       cur[0] = (FT_Byte)c;
  119.   }
  120.  
  121.  
  122.   static void
  123.   pfr_bitwriter_decode_rle1( PFR_BitWriter  writer,
  124.                              FT_Byte*       p,
  125.                              FT_Byte*       limit )
  126.   {
  127.     FT_Int    n, phase, count, counts[2], reload;
  128.     FT_Int    left = writer->width;
  129.     FT_Byte*  cur  = writer->line;
  130.     FT_UInt   mask = 0x80;
  131.     FT_UInt   c    = 0;
  132.  
  133.  
  134.     n = writer->total;
  135.  
  136.     phase     = 1;
  137.     counts[0] = 0;
  138.     counts[1] = 0;
  139.     count     = 0;
  140.     reload    = 1;
  141.  
  142.     for ( ; n > 0; n-- )
  143.     {
  144.       if ( reload )
  145.       {
  146.         do
  147.         {
  148.           if ( phase )
  149.           {
  150.             FT_Int  v;
  151.  
  152.  
  153.             if ( p >= limit )
  154.               break;
  155.  
  156.             v         = *p++;
  157.             counts[0] = v >> 4;
  158.             counts[1] = v & 15;
  159.             phase     = 0;
  160.             count     = counts[0];
  161.           }
  162.           else
  163.           {
  164.             phase = 1;
  165.             count = counts[1];
  166.           }
  167.  
  168.         } while ( count == 0 );
  169.       }
  170.  
  171.       if ( phase )
  172.         c |= mask;
  173.  
  174.       mask >>= 1;
  175.  
  176.       if ( --left <= 0 )
  177.       {
  178.         cur[0] = (FT_Byte) c;
  179.         left   = writer->width;
  180.         mask   = 0x80;
  181.  
  182.         writer->line += writer->pitch;
  183.         cur           = writer->line;
  184.         c             = 0;
  185.       }
  186.       else if ( mask == 0 )
  187.       {
  188.         cur[0] = (FT_Byte)c;
  189.         mask   = 0x80;
  190.         c      = 0;
  191.         cur ++;
  192.       }
  193.  
  194.       reload = ( --count <= 0 );
  195.     }
  196.  
  197.     if ( mask != 0x80 )
  198.       cur[0] = (FT_Byte) c;
  199.   }
  200.  
  201.  
  202.   static void
  203.   pfr_bitwriter_decode_rle2( PFR_BitWriter  writer,
  204.                              FT_Byte*       p,
  205.                              FT_Byte*       limit )
  206.   {
  207.     FT_Int    n, phase, count, reload;
  208.     FT_Int    left = writer->width;
  209.     FT_Byte*  cur  = writer->line;
  210.     FT_UInt   mask = 0x80;
  211.     FT_UInt   c    = 0;
  212.  
  213.  
  214.     n = writer->total;
  215.  
  216.     phase  = 1;
  217.     count  = 0;
  218.     reload = 1;
  219.  
  220.     for ( ; n > 0; n-- )
  221.     {
  222.       if ( reload )
  223.       {
  224.         do
  225.         {
  226.           if ( p >= limit )
  227.             break;
  228.  
  229.           count = *p++;
  230.           phase = phase ^ 1;
  231.  
  232.         } while ( count == 0 );
  233.       }
  234.  
  235.       if ( phase )
  236.         c |= mask;
  237.  
  238.       mask >>= 1;
  239.  
  240.       if ( --left <= 0 )
  241.       {
  242.         cur[0] = (FT_Byte) c;
  243.         c      = 0;
  244.         mask   = 0x80;
  245.         left   = writer->width;
  246.  
  247.         writer->line += writer->pitch;
  248.         cur           = writer->line;
  249.       }
  250.       else if ( mask == 0 )
  251.       {
  252.         cur[0] = (FT_Byte)c;
  253.         c      = 0;
  254.         mask   = 0x80;
  255.         cur ++;
  256.       }
  257.  
  258.       reload = ( --count <= 0 );
  259.     }
  260.  
  261.     if ( mask != 0x80 )
  262.       cur[0] = (FT_Byte) c;
  263.   }
  264.  
  265.  
  266.   /*************************************************************************/
  267.   /*************************************************************************/
  268.   /*****                                                               *****/
  269.   /*****                  BITMAP DATA DECODING                         *****/
  270.   /*****                                                               *****/
  271.   /*************************************************************************/
  272.   /*************************************************************************/
  273.  
  274.   static void
  275.   pfr_lookup_bitmap_data( FT_Byte*   base,
  276.                           FT_Byte*   limit,
  277.                           FT_UInt    count,
  278.                           FT_UInt    flags,
  279.                           FT_UInt    char_code,
  280.                           FT_ULong*  found_offset,
  281.                           FT_ULong*  found_size )
  282.   {
  283.     FT_UInt   left, right, char_len;
  284.     FT_Bool   two = FT_BOOL( flags & 1 );
  285.     FT_Byte*  buff;
  286.  
  287.  
  288.     char_len = 4;
  289.     if ( two )       char_len += 1;
  290.     if ( flags & 2 ) char_len += 1;
  291.     if ( flags & 4 ) char_len += 1;
  292.  
  293.     left  = 0;
  294.     right = count;
  295.  
  296.     while ( left < right )
  297.     {
  298.       FT_UInt  middle, code;
  299.  
  300.  
  301.       middle = ( left + right ) >> 1;
  302.       buff   = base + middle * char_len;
  303.  
  304.       /* check that we are not outside of the table -- */
  305.       /* this is possible with broken fonts...         */
  306.       if ( buff + char_len > limit )
  307.         goto Fail;
  308.  
  309.       if ( two )
  310.         code = PFR_NEXT_USHORT( buff );
  311.       else
  312.         code = PFR_NEXT_BYTE( buff );
  313.  
  314.       if ( code == char_code )
  315.         goto Found_It;
  316.  
  317.       if ( code < char_code )
  318.         left = middle;
  319.       else
  320.         right = middle;
  321.     }
  322.  
  323.   Fail:
  324.     /* Not found */
  325.     *found_size   = 0;
  326.     *found_offset = 0;
  327.     return;
  328.  
  329.   Found_It:
  330.     if ( flags & 2 )
  331.       *found_size = PFR_NEXT_USHORT( buff );
  332.     else
  333.       *found_size = PFR_NEXT_BYTE( buff );
  334.  
  335.     if ( flags & 4 )
  336.       *found_offset = PFR_NEXT_ULONG( buff );
  337.     else
  338.       *found_offset = PFR_NEXT_USHORT( buff );
  339.   }
  340.  
  341.  
  342.   /* load bitmap metrics.  "*padvance" must be set to the default value */
  343.   /* before calling this function...                                    */
  344.   /*                                                                    */
  345.   static FT_Error
  346.   pfr_load_bitmap_metrics( FT_Byte**  pdata,
  347.                            FT_Byte*   limit,
  348.                            FT_Long    scaled_advance,
  349.                            FT_Long   *axpos,
  350.                            FT_Long   *aypos,
  351.                            FT_UInt   *axsize,
  352.                            FT_UInt   *aysize,
  353.                            FT_Long   *aadvance,
  354.                            FT_UInt   *aformat )
  355.   {
  356.     FT_Error  error = FT_Err_Ok;
  357.     FT_Byte   flags;
  358.     FT_Char   b;
  359.     FT_Byte*  p = *pdata;
  360.     FT_Long   xpos, ypos, advance;
  361.     FT_UInt   xsize, ysize;
  362.  
  363.  
  364.     PFR_CHECK( 1 );
  365.     flags = PFR_NEXT_BYTE( p );
  366.  
  367.     xpos    = 0;
  368.     ypos    = 0;
  369.     xsize   = 0;
  370.     ysize   = 0;
  371.     advance = 0;
  372.  
  373.     switch ( flags & 3 )
  374.     {
  375.     case 0:
  376.       PFR_CHECK( 1 );
  377.       b    = PFR_NEXT_INT8( p );
  378.       xpos = b >> 4;
  379.       ypos = ( (FT_Char)( b << 4 ) ) >> 4;
  380.       break;
  381.  
  382.     case 1:
  383.       PFR_CHECK( 2 );
  384.       xpos = PFR_NEXT_INT8( p );
  385.       ypos = PFR_NEXT_INT8( p );
  386.       break;
  387.  
  388.     case 2:
  389.       PFR_CHECK( 4 );
  390.       xpos = PFR_NEXT_SHORT( p );
  391.       ypos = PFR_NEXT_SHORT( p );
  392.       break;
  393.  
  394.     case 3:
  395.       PFR_CHECK( 6 );
  396.       xpos = PFR_NEXT_LONG( p );
  397.       ypos = PFR_NEXT_LONG( p );
  398.       break;
  399.  
  400.     default:
  401.       ;
  402.     }
  403.  
  404.     flags >>= 2;
  405.     switch ( flags & 3 )
  406.     {
  407.     case 0:
  408.       /* blank image */
  409.       xsize = 0;
  410.       ysize = 0;
  411.       break;
  412.  
  413.     case 1:
  414.       PFR_CHECK( 1 );
  415.       b     = PFR_NEXT_BYTE( p );
  416.       xsize = ( b >> 4 ) & 0xF;
  417.       ysize = b & 0xF;
  418.       break;
  419.  
  420.     case 2:
  421.       PFR_CHECK( 2 );
  422.       xsize = PFR_NEXT_BYTE( p );
  423.       ysize = PFR_NEXT_BYTE( p );
  424.       break;
  425.  
  426.     case 3:
  427.       PFR_CHECK( 4 );
  428.       xsize = PFR_NEXT_USHORT( p );
  429.       ysize = PFR_NEXT_USHORT( p );
  430.       break;
  431.  
  432.     default:
  433.       ;
  434.     }
  435.  
  436.     flags >>= 2;
  437.     switch ( flags & 3 )
  438.     {
  439.     case 0:
  440.       advance = scaled_advance;
  441.       break;
  442.  
  443.     case 1:
  444.       PFR_CHECK( 1 );
  445.       advance = PFR_NEXT_INT8( p ) << 8;
  446.       break;
  447.  
  448.     case 2:
  449.       PFR_CHECK( 2 );
  450.       advance = PFR_NEXT_SHORT( p );
  451.       break;
  452.  
  453.     case 3:
  454.       PFR_CHECK( 3 );
  455.       advance = PFR_NEXT_LONG( p );
  456.       break;
  457.  
  458.     default:
  459.       ;
  460.     }
  461.  
  462.     *axpos    = xpos;
  463.     *aypos    = ypos;
  464.     *axsize   = xsize;
  465.     *aysize   = ysize;
  466.     *aadvance = advance;
  467.     *aformat  = flags >> 2;
  468.     *pdata    = p;
  469.  
  470.   Exit:
  471.     return error;
  472.  
  473.   Too_Short:
  474.     error = FT_THROW( Invalid_Table );
  475.     FT_ERROR(( "pfr_load_bitmap_metrics: invalid glyph data\n" ));
  476.     goto Exit;
  477.   }
  478.  
  479.  
  480.   static FT_Error
  481.   pfr_load_bitmap_bits( FT_Byte*    p,
  482.                         FT_Byte*    limit,
  483.                         FT_UInt     format,
  484.                         FT_Bool     decreasing,
  485.                         FT_Bitmap*  target )
  486.   {
  487.     FT_Error          error = FT_Err_Ok;
  488.     PFR_BitWriterRec  writer;
  489.  
  490.  
  491.     if ( target->rows > 0 && target->width > 0 )
  492.     {
  493.       pfr_bitwriter_init( &writer, target, decreasing );
  494.  
  495.       switch ( format )
  496.       {
  497.       case 0: /* packed bits */
  498.         pfr_bitwriter_decode_bytes( &writer, p, limit );
  499.         break;
  500.  
  501.       case 1: /* RLE1 */
  502.         pfr_bitwriter_decode_rle1( &writer, p, limit );
  503.         break;
  504.  
  505.       case 2: /* RLE2 */
  506.         pfr_bitwriter_decode_rle2( &writer, p, limit );
  507.         break;
  508.  
  509.       default:
  510.         FT_ERROR(( "pfr_read_bitmap_data: invalid image type\n" ));
  511.         error = FT_THROW( Invalid_File_Format );
  512.       }
  513.     }
  514.  
  515.     return error;
  516.   }
  517.  
  518.  
  519.   /*************************************************************************/
  520.   /*************************************************************************/
  521.   /*****                                                               *****/
  522.   /*****                     BITMAP LOADING                            *****/
  523.   /*****                                                               *****/
  524.   /*************************************************************************/
  525.   /*************************************************************************/
  526.  
  527.   FT_LOCAL( FT_Error )
  528.   pfr_slot_load_bitmap( PFR_Slot  glyph,
  529.                         PFR_Size  size,
  530.                         FT_UInt   glyph_index )
  531.   {
  532.     FT_Error     error;
  533.     PFR_Face     face   = (PFR_Face) glyph->root.face;
  534.     FT_Stream    stream = face->root.stream;
  535.     PFR_PhyFont  phys   = &face->phy_font;
  536.     FT_ULong     gps_offset;
  537.     FT_ULong     gps_size;
  538.     PFR_Char     character;
  539.     PFR_Strike   strike;
  540.  
  541.  
  542.     character = &phys->chars[glyph_index];
  543.  
  544.     /* Look-up a bitmap strike corresponding to the current */
  545.     /* character dimensions                                 */
  546.     {
  547.       FT_UInt  n;
  548.  
  549.  
  550.       strike = phys->strikes;
  551.       for ( n = 0; n < phys->num_strikes; n++ )
  552.       {
  553.         if ( strike->x_ppm == (FT_UInt)size->root.metrics.x_ppem &&
  554.              strike->y_ppm == (FT_UInt)size->root.metrics.y_ppem )
  555.         {
  556.           goto Found_Strike;
  557.         }
  558.  
  559.         strike++;
  560.       }
  561.  
  562.       /* couldn't find it */
  563.       return FT_THROW( Invalid_Argument );
  564.     }
  565.  
  566.   Found_Strike:
  567.  
  568.     /* Now lookup the glyph's position within the file */
  569.     {
  570.       FT_UInt  char_len;
  571.  
  572.  
  573.       char_len = 4;
  574.       if ( strike->flags & 1 ) char_len += 1;
  575.       if ( strike->flags & 2 ) char_len += 1;
  576.       if ( strike->flags & 4 ) char_len += 1;
  577.  
  578.       /* Access data directly in the frame to speed lookups */
  579.       if ( FT_STREAM_SEEK( phys->bct_offset + strike->bct_offset ) ||
  580.            FT_FRAME_ENTER( char_len * strike->num_bitmaps )        )
  581.         goto Exit;
  582.  
  583.       pfr_lookup_bitmap_data( stream->cursor,
  584.                               stream->limit,
  585.                               strike->num_bitmaps,
  586.                               strike->flags,
  587.                               character->char_code,
  588.                               &gps_offset,
  589.                               &gps_size );
  590.  
  591.       FT_FRAME_EXIT();
  592.  
  593.       if ( gps_size == 0 )
  594.       {
  595.         /* Could not find a bitmap program string for this glyph */
  596.         error = FT_THROW( Invalid_Argument );
  597.         goto Exit;
  598.       }
  599.     }
  600.  
  601.     /* get the bitmap metrics */
  602.     {
  603.       FT_Long   xpos = 0, ypos = 0, advance = 0;
  604.       FT_UInt   xsize = 0, ysize = 0, format = 0;
  605.       FT_Byte*  p;
  606.  
  607.  
  608.       /* compute linear advance */
  609.       advance = character->advance;
  610.       if ( phys->metrics_resolution != phys->outline_resolution )
  611.         advance = FT_MulDiv( advance,
  612.                              phys->outline_resolution,
  613.                              phys->metrics_resolution );
  614.  
  615.       glyph->root.linearHoriAdvance = advance;
  616.  
  617.       /* compute default advance, i.e., scaled advance.  This can be */
  618.       /* overridden in the bitmap header of certain glyphs.          */
  619.       advance = FT_MulDiv( (FT_Fixed)size->root.metrics.x_ppem << 8,
  620.                            character->advance,
  621.                            phys->metrics_resolution );
  622.  
  623.       if ( FT_STREAM_SEEK( face->header.gps_section_offset + gps_offset ) ||
  624.            FT_FRAME_ENTER( gps_size )                                     )
  625.         goto Exit;
  626.  
  627.       p     = stream->cursor;
  628.       error = pfr_load_bitmap_metrics( &p, stream->limit,
  629.                                        advance,
  630.                                        &xpos, &ypos,
  631.                                        &xsize, &ysize,
  632.                                        &advance, &format );
  633.  
  634.       /*
  635.        * XXX: on 16bit system, we return an error for huge bitmap
  636.        *      which causes a size truncation, because truncated
  637.        *      size properties makes bitmap glyph broken.
  638.        */
  639.       if ( xpos > FT_INT_MAX || ( ypos + ysize ) > FT_INT_MAX )
  640.       {
  641.         FT_TRACE1(( "pfr_slot_load_bitmap:" ));
  642.         FT_TRACE1(( "huge bitmap glyph %dx%d over FT_GlyphSlot\n",
  643.                      xpos, ypos ));
  644.         error = FT_THROW( Invalid_Pixel_Size );
  645.       }
  646.  
  647.       if ( !error )
  648.       {
  649.         glyph->root.format = FT_GLYPH_FORMAT_BITMAP;
  650.  
  651.         /* Set up glyph bitmap and metrics */
  652.  
  653.         /* XXX: needs casts to fit FT_Bitmap.{width|rows|pitch} */
  654.         glyph->root.bitmap.width      = (FT_Int)xsize;
  655.         glyph->root.bitmap.rows       = (FT_Int)ysize;
  656.         glyph->root.bitmap.pitch      = (FT_Int)( xsize + 7 ) >> 3;
  657.         glyph->root.bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
  658.  
  659.         /* XXX: needs casts to fit FT_Glyph_Metrics.{width|height} */
  660.         glyph->root.metrics.width        = (FT_Pos)xsize << 6;
  661.         glyph->root.metrics.height       = (FT_Pos)ysize << 6;
  662.         glyph->root.metrics.horiBearingX = xpos << 6;
  663.         glyph->root.metrics.horiBearingY = ypos << 6;
  664.         glyph->root.metrics.horiAdvance  = FT_PIX_ROUND( ( advance >> 2 ) );
  665.         glyph->root.metrics.vertBearingX = - glyph->root.metrics.width >> 1;
  666.         glyph->root.metrics.vertBearingY = 0;
  667.         glyph->root.metrics.vertAdvance  = size->root.metrics.height;
  668.  
  669.         /* XXX: needs casts fit FT_GlyphSlotRec.bitmap_{left|top} */
  670.         glyph->root.bitmap_left = (FT_Int)xpos;
  671.         glyph->root.bitmap_top  = (FT_Int)(ypos + ysize);
  672.  
  673.         /* Allocate and read bitmap data */
  674.         {
  675.           FT_ULong  len = glyph->root.bitmap.pitch * ysize;
  676.  
  677.  
  678.           error = ft_glyphslot_alloc_bitmap( &glyph->root, len );
  679.           if ( !error )
  680.           {
  681.             error = pfr_load_bitmap_bits(
  682.                       p,
  683.                       stream->limit,
  684.                       format,
  685.                       FT_BOOL(face->header.color_flags & 2),
  686.                       &glyph->root.bitmap );
  687.           }
  688.         }
  689.       }
  690.  
  691.       FT_FRAME_EXIT();
  692.     }
  693.  
  694.   Exit:
  695.     return error;
  696.   }
  697.  
  698. /* END */
  699.