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

📄 grblit.c

📁 Demo for Free type 2.2.1
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************/
/*                                                                          */
/*  The FreeType project -- a free and portable quality TrueType renderer.  */
/*                                                                          */
/*  Copyright 1996-1999, 2000, 2001, 2002 by                                */
/*  D. Turner, R.Wilhelm, and W. Lemberg                                    */
/*                                                                          */
/*  grblit.c: Support for blitting of bitmaps with various depth.           */
/*                                                                          */
/****************************************************************************/

#include "grblit.h"
#include "grobjs.h"

#define  GRAY8

  static
  int  compute_clips( grBlitter*  blit,
                      int         x_offset,
                      int         y_offset )
  {
    int  xmin, ymin, xmax, ymax, width, height, target_width;

    /* perform clipping and setup variables */
    width  = blit->source.width;
    height = blit->source.rows;

    switch ( blit->source.mode )
    {
    case gr_pixel_mode_mono:
      width = (width + 7) & -8;
      break;

    case gr_pixel_mode_pal4:
      width = (width + 1) & -2;
      break;

    case gr_pixel_mode_lcd:
    case gr_pixel_mode_lcd2:
      width /= 3;
      break;

    case gr_pixel_mode_lcdv:
    case gr_pixel_mode_lcdv2:
      height /= 3;
      break;

    default:
      ;
    }

    xmin = x_offset;
    ymin = y_offset;
    xmax = xmin + width-1;
    ymax = ymin + height-1;

    /* clip if necessary */
    if ( width == 0 || height == 0                ||
         xmax < 0   || xmin >= blit->target.width ||
         ymax < 0   || ymin >= blit->target.rows  )
      return 1;

    /* set up clipping and cursors */
    blit->yread = 0;
    if ( ymin < 0 )
    {
      blit->yread  -= ymin;
      height       += ymin;
      blit->ywrite  = 0;
    }
    else
      blit->ywrite  = ymin;

    if ( ymax >= blit->target.rows )
      height -= ymax - blit->target.rows + 1;

    blit->xread = 0;
    if ( xmin < 0 )
    {
      blit->xread  -= xmin;
      width        += xmin;
      blit->xwrite  = 0;
    }
    else
      blit->xwrite  = xmin;

    target_width = blit->target.width;

    switch ( blit->target.mode )
    {
    case gr_pixel_mode_mono:
      target_width = (target_width + 7) & -8;
      break;
    case gr_pixel_mode_pal4:
      target_width = (target_width + 1) & -2;
      break;

    default:
      ;
    }

    blit->right_clip = xmax - target_width + 1;
    if ( blit->right_clip > 0 )
      width -= blit->right_clip;
    else
      blit->right_clip = 0;

    blit->width  = width;
    blit->height = height;

    /* set read and write to the top-left corner of the read */
    /* and write areas before clipping.                      */

    blit->read  = blit->source.buffer;
    blit->write = blit->target.buffer;

    blit->read_line  = blit->source.pitch;
    blit->write_line = blit->target.pitch;

    if ( blit->read_line < 0 )
      blit->read -= (blit->source.rows-1) * blit->read_line;

    if ( blit->write_line < 0 )
      blit->write -= (blit->target.rows-1) * blit->write_line;

    /* now go to the start line. Note that we do not move the   */
    /* x position yet, as this is dependent on the pixel format */
    blit->read  += blit->yread * blit->read_line;
    blit->write += blit->ywrite * blit->write_line;

    return 0;
  }


/**************************************************************************/
/*                                                                        */
/* <Function> blit_mono_to_mono                                           */
/*                                                                        */
/**************************************************************************/

  static
  void  blit_mono_to_mono( grBlitter*  blit,
                           grColor     color )
  {
    int    shift, left_clip, x, y;
    byte*  read;
    byte*  write;

    (void)color;   /* unused argument */

    left_clip = ( blit->xread > 0 );
    shift     = ( blit->xwrite - blit->xread ) & 7;

    read  = blit->read  + (blit->xread >> 3);
    write = blit->write + (blit->xwrite >> 3);

    if ( shift == 0 )
    {
      y = blit->height;
      do
      {
        byte*  _read  = read;
        byte*  _write = write;

        x = blit->width;

        do
        {
          *_write++ |= *_read++;
          x -= 8;
        } while ( x > 0 );

        read  += blit->read_line;
        write += blit->write_line;
        y--;
      } while ( y > 0 );
    }
    else
    {
      int  first, last, count;


      first = blit->xwrite >> 3;
      last  = (blit->xwrite + blit->width-1) >> 3;

      count = last - first;

      if ( blit->right_clip )
        count++;

      y = blit->height;

      do
      {
        unsigned char*  _read  = read;
        unsigned char*  _write = write;
        unsigned int    old;
        int             shift2 = (8-shift);

        if ( left_clip )
          old = (*_read++) << shift2;
        else
          old = 0;

        x = count;
        while ( x > 0 )
        {
          unsigned char val;

          val = *_read++;
          *_write++ |= (unsigned char)( (val >> shift) | old );
          old = val << shift2;
          x--;
        }

        if ( !blit->right_clip )
          *_write |= (unsigned char)old;

        read  += blit->read_line;
        write += blit->write_line;
        y--;

      } while ( y > 0 );
    }
  }


/**************************************************************************/
/*                                                                        */
/* <Function> blit_mono_to_pal8                                           */
/*                                                                        */
/**************************************************************************/

  static
  void  blit_mono_to_pal8( grBlitter*  blit,
                           grColor     color )
  {
    int             x, y, shift;
    unsigned char*  read;
    unsigned char*  write;

    read  = blit->read  + (blit->xread >> 3);
    write = blit->write +  blit->xwrite;
    shift = blit->xread & 7;

    y = blit->height;
    do
    {
      unsigned char*  _read  = read;
      unsigned char*  _write = write;
      unsigned long    val    = (*_read++ | 0x100) << shift;

      x = blit->width;
      do
      {
        if (val & 0x10000)
          val = *_read++ | 0x100;

        if ( val & 0x80 )
          *_write = (unsigned char)color.value;

        val <<= 1;
        _write++;

      } while ( --x > 0 );

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


/**************************************************************************/
/*                                                                        */
/* <Function> blit_mono_to_pal4                                           */
/*                                                                        */
/**************************************************************************/

  static
  void  blit_mono_to_pal4( grBlitter*  blit,
                           grColor     color )
  {
    int             x, y, phase,shift;
    unsigned char*  read;
    unsigned char*  write;
    unsigned int    col;


    col   = color.value & 15;
    read  = blit->read  + (blit->xread >> 3);
    write = blit->write + (blit->xwrite >> 1);

    /* now begin blit */
    shift = blit->xread & 7;
    phase = blit->xwrite & 1;

    y = blit->height;
    do
    {
      unsigned char*  _read  = read;
      unsigned char*  _write = write;
      int             _phase = phase;
      unsigned long    val    = (*_read++ | 0x100) << shift;

      x = blit->width;
      do
      {
        if (val & 0x10000)
          val = *_read++ | 0x100;

        if ( val & 0x80 )
        {
          if ( _phase )
            *_write = (unsigned char)((*_write & 0xF0) | col);
          else
            *_write = (unsigned char)((*_write & 0x0F) | (col << 4));
        }

        val <<= 1;

        _write += _phase;
        _phase ^= 1;
        x--;
      } while ( x > 0 );

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


/**************************************************************************/
/*                                                                        */
/* <Function> blit_mono_to_rgb16                                          */
/*                                                                        */
/**************************************************************************/

  static
  void  blit_mono_to_rgb16( grBlitter*  blit,
                            grColor     color )
  {
    int              x, y,shift;
    unsigned char*   read;
    unsigned char*   write;

    read  = blit->read + (blit->xread >> 3);
    write = blit->write + blit->xwrite*2;
    shift = blit->xread & 7;

    y = blit->height;
    do
    {
      unsigned char*  _read  = read;
      unsigned char*  _write = write;
      unsigned long    val    = (*_read++ | 0x100) << shift;

      x = blit->width;
      do
      {
        if (val & 0x10000)
          val = *_read++ | 0x100;

        if ( val & 0x80 )
          *(short*)_write = (short)color.value;

        val   <<= 1;
        _write +=2;
        x--;
      } while ( x > 0 );

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


/**************************************************************************/
/*                                                                        */
/* <Function> blit_mono_to_rgb24                                          */
/*                                                                        */
/**************************************************************************/

  static
  void  blit_mono_to_rgb24( grBlitter*  blit,
                            grColor     color )
  {
    int             x, y, shift;
    unsigned char*  read;
    unsigned char*  write;

    read  = blit->read  + (blit->xread >> 3);
    write = blit->write + blit->xwrite*3;
    shift = blit->xread & 7;

    y = blit->height;
    do
    {
      unsigned char*  _read  = read;
      unsigned char*  _write = write;
      unsigned long    val   = (*_read++ | 0x100) << shift;

      x = blit->width;
      do
      {
        if (val & 0x10000)
          val = *_read++ | 0x100;

        if ( val & 0x80 )
        {
          _write[0] = color.chroma[0];
          _write[1] = color.chroma[1];
          _write[2] = color.chroma[2];
        }

        val   <<= 1;
        _write += 3;
        x--;
      } while ( x > 0 );

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


/**************************************************************************/
/*                                                                        */
/* <Function> blit_mono_to_rgb32                                          */
/*                                                                        */
/**************************************************************************/

  static
  void  blit_mono_to_rgb32( grBlitter*  blit,
                            grColor     color )
  {
    int             x, y,shift;
    unsigned char*  read;
    unsigned char*  write;

    read  = blit->read  + ( blit->xread >> 3 );
    write = blit->write + blit->xwrite*4;
    shift = blit->xread & 7;

    y = blit->height;
    do
    {
      unsigned char*  _read  = read;
      unsigned char*  _write = write;
      unsigned long   val    = ( *_read++ | 0x100L ) << shift;

      x = blit->width;
      do
      {
        if ( val & 0x10000 )
          val = *_read++ | 0x100L;

        if ( val & 0x80 )
        {
          /* this could be greatly optimized as                         */
          /*                                                            */
          /*   *(long*)_write = color.value                             */
          /*                                                            */
          /* but it wouldn't work on 64-bits systems... stupid C types! */
          _write[0] = color.chroma[0];
          _write[1] = color.chroma[1];
          _write[2] = color.chroma[2];
          _write[3] = color.chroma[3];
        }

        val   <<= 1;
        _write += 4;
        x--;

      } while ( x > 0 );

      read  += blit->read_line;
      write += blit->write_line;
      y--;

    } while ( y > 0 );
  }


  static
  const grBlitterFunc  gr_mono_blitters[gr_pixel_mode_max] =
  {
    0,
    blit_mono_to_mono,
    blit_mono_to_pal4,
    blit_mono_to_pal8,
    blit_mono_to_pal8,
    blit_mono_to_rgb16,
    blit_mono_to_rgb16,
    blit_mono_to_rgb24,
    blit_mono_to_rgb32
  };


  /*******************************************************************/
  /*                                                                 */
  /*                    Saturation tables                            */
  /*                                                                 */
  /*******************************************************************/

  typedef struct grSaturation_
  {
    int          count;
    const byte*  table;

  } grSaturation;


  static

⌨️ 快捷键说明

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