⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 grblit.c

📁 Ftee type Demo for Linux open source
💻 C
📖 第 1 页 / 共 4 页
字号:
    }
    while (y > 0);
  }
#endif /* GRAY8 */

  static void
  blit_lcd2_to_24( grBlitter*  blit,
                   grColor     color,
                   int         max )
  {
    int             y;
    unsigned char*  read;
    unsigned char*  write;

    read   = blit->read  + 3*blit->xread;
    write  = blit->write + 3*blit->xwrite;

    y = blit->height;
    do
    {
      unsigned char*  _read  = read;
      unsigned char*  _write = write;
      int             x      = blit->width;

      while (x > 0)
      {
        int    val0, val1, val2;

        val0 = _read[2];
        val1 = _read[1];
        val2 = _read[0];

        if ( val0 | val1 | val2 )
        {
          if ( val0 == val1 &&
               val0 == val2 &&
               val0 == max  )
          {
            _write[0] = color.chroma[0];
            _write[1] = color.chroma[1];
            _write[2] = color.chroma[2];
          }
          else
          {
            /* compose gray value */
            grColor pix;

            pix.chroma[0] = _write[0];
            pix.chroma[1] = _write[1];
            pix.chroma[2] = _write[2];

            compose_pixel_full( pix, color, val0, val1, val2, max );

            _write[0] = pix.chroma[0];
            _write[1] = pix.chroma[1];
            _write[2] = pix.chroma[2];
          }
        }
        _write += 3;
        _read  += 3;
        x--;
      }

      read  += blit->read_line;
      write += blit->write_line;
      y--;
    }
    while (y > 0);
  }


/**************************************************************************/
/*                                                                        */
/* <Function> blit_lcdv_to_24                                             */
/*                                                                        */
/**************************************************************************/

  static void
  blit_lcdv_to_24( grBlitter*  blit,
                   grColor     color,
                   int         max )
  {
    int             y;
    unsigned char*  read;
    unsigned char*  write;
    long            line;

    read   = blit->read  + blit->xread;
    write  = blit->write + 3*blit->xwrite;
    line   = blit->read_line;

    y = blit->height;
    do
    {
      unsigned char*  _read  = read;
      unsigned char*  _write = write;
      int             x      = blit->width;

      while (x > 0)
      {
        unsigned char    val0, val1, val2;

        val0 = _read[0*line];
        val1 = _read[1*line];
        val2 = _read[2*line];

        if ( val0 | val1 | val2 )
        {
          if ( val0 == val1 &&
               val0 == val2 &&
               val0 == max  )
          {
            _write[0] = color.chroma[0];
            _write[1] = color.chroma[1];
            _write[2] = color.chroma[2];
          }
          else
          {
            /* compose gray value */
            grColor pix;

            pix.chroma[0] = _write[0];
            pix.chroma[1] = _write[1];
            pix.chroma[2] = _write[2];

            compose_pixel_full( pix, color, val0, val1, val2, max );

            _write[0] = pix.chroma[0];
            _write[1] = pix.chroma[1];
            _write[2] = pix.chroma[2];
          }
        }
        _write += 3;
        _read  += 1;
        x--;
      }

      read  += 3*line;
      write += blit->write_line;
      y--;
    }
    while (y > 0);
  }


  static void
  blit_lcdv2_to_24( grBlitter*  blit,
                    grColor     color,
                    int         max )
  {
    int             y;
    unsigned char*  read;
    unsigned char*  write;
    long            line;

    read   = blit->read  + blit->xread;
    write  = blit->write + 3*blit->xwrite;
    line   = blit->read_line;

    y = blit->height;
    do
    {
      unsigned char*  _read  = read;
      unsigned char*  _write = write;
      int             x      = blit->width;

      while (x > 0)
      {
        unsigned char    val0, val1, val2;

        val0 = _read[2*line];
        val1 = _read[1*line];
        val2 = _read[0*line];

        if ( val0 | val1 | val2 )
        {
          if ( val0 == val1 &&
               val0 == val2 &&
               val0 == max  )
          {
            _write[0] = color.chroma[0];
            _write[1] = color.chroma[1];
            _write[2] = color.chroma[2];
          }
          else
          {
            /* compose gray value */
            grColor pix;

            pix.chroma[0] = _write[0];
            pix.chroma[1] = _write[1];
            pix.chroma[2] = _write[2];

            compose_pixel_full( pix, color, val0, val1, val2, max );

            _write[0] = pix.chroma[0];
            _write[1] = pix.chroma[1];
            _write[2] = pix.chroma[2];
          }
        }
        _write += 3;
        _read  += 1;
        x--;
      }

      read  += 3*line;
      write += blit->write_line;
      y--;
    }
    while (y > 0);
  }


 /**********************************************************************
  *
  * <Function>
  *    grBlitGlyphBitmap
  *
  * <Description>
  *    writes a given glyph bitmap to a target surface.
  *
  * <Input>
  *    surface :: handle to target surface
  *    x       :: position of left-most pixel of glyph image in surface
  *    y       :: position of top-most pixel of glyph image in surface
  *    bitmap  :: source glyph image
  *
  * <Return>
  *   Error code. 0 means success
  *
  **********************************************************************/

  typedef  void (*grColorGlyphBlitter)( grBlitter*  blit,
                                        grColor     color,
                                        int         max_gray );

  static
  const grColorGlyphBlitter  gr_color_blitters[gr_pixel_mode_max] =
  {
    0,
    0,
    0,
    0,
    0,
    blit_gray_to_555,
    blit_gray_to_565,
    blit_gray_to_24,
    blit_gray_to_32
  };

#ifdef GRAY8
  typedef  void (*grGray8GlyphBlitter)( grBlitter*  blit,
                                        grColor     color );

  static
  const grGray8GlyphBlitter  gr_gray8_blitters[gr_pixel_mode_max] =
  {
    0,
    0,
    0,
    0,
    0,
    blit_gray8_to_555,
    blit_gray8_to_565,
    blit_gray8_to_24,
    blit_gray8_to_32
  };
#endif


#include "gblblit.h"

  static double    gr_glyph_gamma = 1.2;

  void  grSetGlyphGamma( double  gamma )
  {
    gr_glyph_gamma = gamma;
  }


  int
  grBlitGlyphToBitmap( grBitmap*  target,
                       grBitmap*  glyph,
                       grPos      x,
                       grPos      y,
                       grColor    color )
  {
    grBlitter    blit;
    grPixelMode  mode;


    /* check arguments */
    if ( !target || !glyph )
    {
      grError = gr_err_bad_argument;
      return -1;
    }

   /* short cut to alpha blender for certain glyph types
    */
    {
      GBlenderSourceFormat  src_format;
      GBlenderTargetFormat  dst_format;
      int                   width, height;
      GBlenderBlitRec       gblit[1];
      GBlenderPixel         gcolor;
      static GBlenderRec    gblender[1];
      static double         gblender_gamma = -100.0;
      
      if ( glyph->grays != 256 )
        goto DefaultBlit;
      
      switch ( glyph->mode )
      {
      case gr_pixel_mode_gray:  src_format = GBLENDER_SOURCE_GRAY8; break;
      case gr_pixel_mode_lcd:   src_format = GBLENDER_SOURCE_HRGB;  break;
      case gr_pixel_mode_lcdv:  src_format = GBLENDER_SOURCE_VRGB;  break;
      case gr_pixel_mode_lcd2:  src_format = GBLENDER_SOURCE_HBGR;  break;
      case gr_pixel_mode_lcdv2: src_format = GBLENDER_SOURCE_VBGR;  break;
      
      default:
          goto DefaultBlit;
      }
      
      width  = glyph->width;
      height = glyph->rows;
      
      if ( glyph->mode == gr_pixel_mode_lcd  ||
           glyph->mode == gr_pixel_mode_lcd2 )
        width /= 3;
      
      if ( glyph->mode == gr_pixel_mode_lcdv  ||
           glyph->mode == gr_pixel_mode_lcdv2 )
        height /= 3;
      
      switch ( target->mode )
      {
      case gr_pixel_mode_rgb32: dst_format  = GBLENDER_TARGET_RGB32; break;
      case gr_pixel_mode_rgb24: dst_format  = GBLENDER_TARGET_RGB24; break;
      case gr_pixel_mode_rgb565: dst_format = GBLENDER_TARGET_RGB565; break;
      default:
          goto DefaultBlit;
      }
      
     /* initialize blender when needed, i.e. when gamma changes
      */
      if ( gblender_gamma != gr_glyph_gamma  )
      {
        gblender_gamma = gr_glyph_gamma;
        gblender_init( gblender, gblender_gamma );
      }

      if ( gblender_blit_init( gblit, gblender, 
                               x, y,
                               src_format,
                               glyph->buffer,
                               glyph->pitch,
                               width,
                               height,
                               dst_format,
                               target->buffer,
                               target->pitch,
                               target->width,
                               target->rows ) < 0 )
      {
        /* nothing to do */
        return 0;
      }
      
      gcolor = ((GBlenderPixel)color.chroma[0] << 16) |
               ((GBlenderPixel)color.chroma[1] << 8 ) |
               ((GBlenderPixel)color.chroma[2]      ) ;
               
      gblender_blit_run( gblit, gcolor );
      return 1;
    }

  DefaultBlit:
  
    /* set up blitter and compute clipping.  Return immediately if needed */
    blit.source = *glyph;
    blit.target = *target;
    mode        = target->mode;

    if ( compute_clips( &blit, x, y ) )
      return 0;

    switch ( glyph->mode )
    {
    case gr_pixel_mode_mono:     /* handle monochrome bitmap blitting */
      if ( mode <= gr_pixel_mode_none || mode >= gr_pixel_mode_max )
      {
        grError = gr_err_bad_source_depth;
        return -1;
      }

      gr_mono_blitters[mode]( &blit, color );
      break;

    case gr_pixel_mode_gray:
      if ( glyph->grays > 1 )
      {
        int          target_grays = target->grays;
        int          source_grays = glyph->grays;
        const byte*  saturation;


        if ( mode == gr_pixel_mode_gray && target_grays > 1 )
        {
          /* rendering into a gray target - use special composition */
          /* routines..                                             */
          if ( gr_last_saturation->count == target_grays )
            saturation = gr_last_saturation->table;
          else
          {
            saturation = grGetSaturation( target_grays );
            if ( !saturation )
              return -3;
          }

          if ( target_grays == source_grays )
            blit_gray_to_gray_simple( &blit, saturation );
          else
          {
            const byte*  conversion;


            if ( gr_last_conversion->target_grays == target_grays &&
                 gr_last_conversion->source_grays == source_grays )
              conversion = gr_last_conversion->table;
            else
            {
              conversion = grGetConversion( target_grays, source_grays );
              if ( !conversion )
                return -3;
            }

            blit_gray_to_gray( &blit, saturation, conversion );
          }
        }
        else
        {
          /* rendering into a color target */
          if ( mode <= gr_pixel_mode_gray ||
               mode >= gr_pixel_mode_max  )
          {
            grError = gr_err_bad_target_depth;
            return -1;
          }

#ifdef GRAY8
          if ( source_grays == 256 )
            gr_gray8_blitters[mode]( &blit, color );
          else
#endif /* GRAY8 */           
          gr_color_blitters[mode]( &blit, color, source_grays - 1 );
        }
      }
      break;

    case gr_pixel_mode_lcd:
      if ( mode == gr_pixel_mode_rgb24 )
      {
#ifdef GRAY8
        if ( glyph->grays == 256 )
          blit_lcd8_to_24( &blit, color );
        else
#endif
        if ( glyph->grays > 1 )
          blit_lcd_to_24( &blit, color, glyph->grays-1 );
      }
      break;
      

    case gr_pixel_mode_lcdv:
      if ( glyph->grays > 1 && mode == gr_pixel_mode_rgb24 )
      {
        blit_lcdv_to_24( &blit, color, glyph->grays-1 );
        break;
      }

    case gr_pixel_mode_lcd2:
      if ( mode == gr_pixel_mode_rgb24 )
      {
#ifdef GRAY8      
        if ( glyph->grays == 256 )
          blit_lcd28_to_24( &blit, color );
        else
#endif        
        if ( glyph->grays > 1 )
          blit_lcd2_to_24( &blit, color, glyph->grays-1 );
      }
      break;

    case gr_pixel_mode_lcdv2:
     if ( mode == gr_pixel_mode_rgb24 )
     {
       if ( glyph->grays > 1 )
         blit_lcdv2_to_24( &blit, color, glyph->grays-1 );
     }
     break;

    default:
      /* we don't support the blitting of bitmaps of the following  */
      /* types : pal4, pal8, rgb555, rgb565, rgb24, rgb32           */
      /*                                                            */
      grError = gr_err_bad_source_depth;
      return -2;
    }

    return 0;
  }


/* End */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -