(root)/
freetype-2.13.2/
src/
raster/
ftrend1.c
       1  /****************************************************************************
       2   *
       3   * ftrend1.c
       4   *
       5   *   The FreeType glyph rasterizer interface (body).
       6   *
       7   * Copyright (C) 1996-2023 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 <freetype/internal/ftdebug.h>
      20  #include <freetype/internal/ftobjs.h>
      21  #include <freetype/ftoutln.h>
      22  #include "ftrend1.h"
      23  #include "ftraster.h"
      24  
      25  #include "rasterrs.h"
      26  
      27  
      28    /* initialize renderer -- init its raster */
      29    static FT_Error
      30    ft_raster1_init( FT_Module  module )   /* FT_Renderer */
      31    {
      32      FT_Renderer  render = (FT_Renderer)module;
      33  
      34  
      35      render->clazz->raster_class->raster_reset( render->raster, NULL, 0 );
      36  
      37      return FT_Err_Ok;
      38    }
      39  
      40  
      41    /* set render-specific mode */
      42    static FT_Error
      43    ft_raster1_set_mode( FT_Renderer  render,
      44                         FT_ULong     mode_tag,
      45                         FT_Pointer   data )
      46    {
      47      /* we simply pass it to the raster */
      48      return render->clazz->raster_class->raster_set_mode( render->raster,
      49                                                           mode_tag,
      50                                                           data );
      51    }
      52  
      53  
      54    /* transform a given glyph image */
      55    static FT_Error
      56    ft_raster1_transform( FT_Renderer       render,
      57                          FT_GlyphSlot      slot,
      58                          const FT_Matrix*  matrix,
      59                          const FT_Vector*  delta )
      60    {
      61      FT_Error error = FT_Err_Ok;
      62  
      63  
      64      if ( slot->format != render->glyph_format )
      65      {
      66        error = FT_THROW( Invalid_Argument );
      67        goto Exit;
      68      }
      69  
      70      if ( matrix )
      71        FT_Outline_Transform( &slot->outline, matrix );
      72  
      73      if ( delta )
      74        FT_Outline_Translate( &slot->outline, delta->x, delta->y );
      75  
      76    Exit:
      77      return error;
      78    }
      79  
      80  
      81    /* return the glyph's control box */
      82    static void
      83    ft_raster1_get_cbox( FT_Renderer   render,
      84                         FT_GlyphSlot  slot,
      85                         FT_BBox*      cbox )
      86    {
      87      FT_ZERO( cbox );
      88  
      89      if ( slot->format == render->glyph_format )
      90        FT_Outline_Get_CBox( &slot->outline, cbox );
      91    }
      92  
      93  
      94    /* convert a slot's glyph image into a bitmap */
      95    static FT_Error
      96    ft_raster1_render( FT_Renderer       render,
      97                       FT_GlyphSlot      slot,
      98                       FT_Render_Mode    mode,
      99                       const FT_Vector*  origin )
     100    {
     101      FT_Error     error   = FT_Err_Ok;
     102      FT_Outline*  outline = &slot->outline;
     103      FT_Bitmap*   bitmap  = &slot->bitmap;
     104      FT_Memory    memory  = render->root.memory;
     105      FT_Pos       x_shift = 0;
     106      FT_Pos       y_shift = 0;
     107  
     108      FT_Raster_Params  params;
     109  
     110  
     111      /* check glyph image format */
     112      if ( slot->format != render->glyph_format )
     113      {
     114        error = FT_THROW( Invalid_Argument );
     115        goto Exit;
     116      }
     117  
     118      /* check rendering mode */
     119      if ( mode != FT_RENDER_MODE_MONO )
     120      {
     121        /* raster1 is only capable of producing monochrome bitmaps */
     122        return FT_THROW( Cannot_Render_Glyph );
     123      }
     124  
     125      /* release old bitmap buffer */
     126      if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
     127      {
     128        FT_FREE( bitmap->buffer );
     129        slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
     130      }
     131  
     132      if ( ft_glyphslot_preset_bitmap( slot, mode, origin ) )
     133      {
     134        error = FT_THROW( Raster_Overflow );
     135        goto Exit;
     136      }
     137  
     138      /* allocate new one */
     139      if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) )
     140        goto Exit;
     141  
     142      slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
     143  
     144      x_shift = -slot->bitmap_left * 64;
     145      y_shift = ( (FT_Int)bitmap->rows - slot->bitmap_top ) * 64;
     146  
     147      if ( origin )
     148      {
     149        x_shift += origin->x;
     150        y_shift += origin->y;
     151      }
     152  
     153      /* translate outline to render it into the bitmap */
     154      if ( x_shift || y_shift )
     155        FT_Outline_Translate( outline, x_shift, y_shift );
     156  
     157      /* set up parameters */
     158      params.target = bitmap;
     159      params.source = outline;
     160      params.flags  = FT_RASTER_FLAG_DEFAULT;
     161  
     162      /* render outline into the bitmap */
     163      error = render->raster_render( render->raster, &params );
     164  
     165    Exit:
     166      if ( !error )
     167        /* everything is fine; the glyph is now officially a bitmap */
     168        slot->format = FT_GLYPH_FORMAT_BITMAP;
     169      else if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
     170      {
     171        FT_FREE( bitmap->buffer );
     172        slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
     173      }
     174  
     175      if ( x_shift || y_shift )
     176        FT_Outline_Translate( outline, -x_shift, -y_shift );
     177  
     178      return error;
     179    }
     180  
     181  
     182    FT_DEFINE_RENDERER(
     183      ft_raster1_renderer_class,
     184  
     185        FT_MODULE_RENDERER,
     186        sizeof ( FT_RendererRec ),
     187  
     188        "raster1",
     189        0x10000L,
     190        0x20000L,
     191  
     192        NULL,    /* module specific interface */
     193  
     194        ft_raster1_init,  /* FT_Module_Constructor module_init   */
     195        NULL,             /* FT_Module_Destructor  module_done   */
     196        NULL,             /* FT_Module_Requester   get_interface */
     197  
     198      FT_GLYPH_FORMAT_OUTLINE,
     199  
     200      ft_raster1_render,     /* FT_Renderer_RenderFunc    render_glyph    */
     201      ft_raster1_transform,  /* FT_Renderer_TransformFunc transform_glyph */
     202      ft_raster1_get_cbox,   /* FT_Renderer_GetCBoxFunc   get_glyph_cbox  */
     203      ft_raster1_set_mode,   /* FT_Renderer_SetModeFunc   set_mode        */
     204  
     205      &ft_standard_raster    /* FT_Raster_Funcs*          raster_class    */
     206    )
     207  
     208  
     209  /* END */