< prev index next >
src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.c
Print this page
@@ -1,96 +1,96 @@
-/***************************************************************************/
-/* */
-/* ftgrays.c */
-/* */
-/* A new `perfect' anti-aliasing renderer (body). */
-/* */
-/* Copyright 2000-2018 by */
-/* David Turner, Robert Wilhelm, and Werner Lemberg. */
-/* */
-/* This file is part of the FreeType project, and may only be used, */
-/* modified, and distributed under the terms of the FreeType project */
-/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
-/* this file you indicate that you have read the license and */
-/* understand and accept it fully. */
-/* */
-/***************************************************************************/
+/****************************************************************************
+ *
+ * ftgrays.c
+ *
+ * A new `perfect' anti-aliasing renderer (body).
+ *
+ * Copyright (C) 2000-2019 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
- /*************************************************************************/
- /* */
- /* This file can be compiled without the rest of the FreeType engine, by */
- /* defining the STANDALONE_ macro when compiling it. You also need to */
- /* put the files `ftgrays.h' and `ftimage.h' into the current */
- /* compilation directory. Typically, you could do something like */
- /* */
- /* - copy `src/smooth/ftgrays.c' (this file) to your current directory */
- /* */
- /* - copy `include/freetype/ftimage.h' and `src/smooth/ftgrays.h' to the */
- /* same directory */
- /* */
- /* - compile `ftgrays' with the STANDALONE_ macro defined, as in */
- /* */
- /* cc -c -DSTANDALONE_ ftgrays.c */
- /* */
- /* The renderer can be initialized with a call to */
- /* `ft_gray_raster.raster_new'; an anti-aliased bitmap can be generated */
- /* with a call to `ft_gray_raster.raster_render'. */
- /* */
- /* See the comments and documentation in the file `ftimage.h' for more */
- /* details on how the raster works. */
- /* */
- /*************************************************************************/
+ /**************************************************************************
+ *
+ * This file can be compiled without the rest of the FreeType engine, by
+ * defining the STANDALONE_ macro when compiling it. You also need to
+ * put the files `ftgrays.h' and `ftimage.h' into the current
+ * compilation directory. Typically, you could do something like
+ *
+ * - copy `src/smooth/ftgrays.c' (this file) to your current directory
+ *
+ * - copy `include/freetype/ftimage.h' and `src/smooth/ftgrays.h' to the
+ * same directory
+ *
+ * - compile `ftgrays' with the STANDALONE_ macro defined, as in
+ *
+ * cc -c -DSTANDALONE_ ftgrays.c
+ *
+ * The renderer can be initialized with a call to
+ * `ft_gray_raster.raster_new'; an anti-aliased bitmap can be generated
+ * with a call to `ft_gray_raster.raster_render'.
+ *
+ * See the comments and documentation in the file `ftimage.h' for more
+ * details on how the raster works.
+ *
+ */
- /*************************************************************************/
- /* */
- /* This is a new anti-aliasing scan-converter for FreeType 2. The */
- /* algorithm used here is _very_ different from the one in the standard */
- /* `ftraster' module. Actually, `ftgrays' computes the _exact_ */
- /* coverage of the outline on each pixel cell. */
- /* */
- /* It is based on ideas that I initially found in Raph Levien's */
- /* excellent LibArt graphics library (see http://www.levien.com/libart */
- /* for more information, though the web pages do not tell anything */
- /* about the renderer; you'll have to dive into the source code to */
- /* understand how it works). */
- /* */
- /* Note, however, that this is a _very_ different implementation */
- /* compared to Raph's. Coverage information is stored in a very */
- /* different way, and I don't use sorted vector paths. Also, it doesn't */
- /* use floating point values. */
- /* */
- /* This renderer has the following advantages: */
- /* */
- /* - It doesn't need an intermediate bitmap. Instead, one can supply a */
- /* callback function that will be called by the renderer to draw gray */
- /* spans on any target surface. You can thus do direct composition on */
- /* any kind of bitmap, provided that you give the renderer the right */
- /* callback. */
- /* */
- /* - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on */
- /* each pixel cell. */
- /* */
- /* - It performs a single pass on the outline (the `standard' FT2 */
- /* renderer makes two passes). */
- /* */
- /* - It can easily be modified to render to _any_ number of gray levels */
- /* cheaply. */
- /* */
- /* - For small (< 20) pixel sizes, it is faster than the standard */
- /* renderer. */
- /* */
- /*************************************************************************/
+ /**************************************************************************
+ *
+ * This is a new anti-aliasing scan-converter for FreeType 2. The
+ * algorithm used here is _very_ different from the one in the standard
+ * `ftraster' module. Actually, `ftgrays' computes the _exact_
+ * coverage of the outline on each pixel cell.
+ *
+ * It is based on ideas that I initially found in Raph Levien's
+ * excellent LibArt graphics library (see https://www.levien.com/libart
+ * for more information, though the web pages do not tell anything
+ * about the renderer; you'll have to dive into the source code to
+ * understand how it works).
+ *
+ * Note, however, that this is a _very_ different implementation
+ * compared to Raph's. Coverage information is stored in a very
+ * different way, and I don't use sorted vector paths. Also, it doesn't
+ * use floating point values.
+ *
+ * This renderer has the following advantages:
+ *
+ * - It doesn't need an intermediate bitmap. Instead, one can supply a
+ * callback function that will be called by the renderer to draw gray
+ * spans on any target surface. You can thus do direct composition on
+ * any kind of bitmap, provided that you give the renderer the right
+ * callback.
+ *
+ * - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on
+ * each pixel cell.
+ *
+ * - It performs a single pass on the outline (the `standard' FT2
+ * renderer makes two passes).
+ *
+ * - It can easily be modified to render to _any_ number of gray levels
+ * cheaply.
+ *
+ * - For small (< 20) pixel sizes, it is faster than the standard
+ * renderer.
+ *
+ */
- /*************************************************************************/
- /* */
- /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
- /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
- /* messages during execution. */
- /* */
+ /**************************************************************************
+ *
+ * The macro FT_COMPONENT is used in trace mode. It is an implicit
+ * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
+ * messages during execution.
+ */
#undef FT_COMPONENT
-#define FT_COMPONENT trace_smooth
+#define FT_COMPONENT smooth
#ifdef STANDALONE_
@@ -220,14 +220,14 @@
#ifndef FT_ERROR
#define FT_ERROR( varformat ) FT_Message varformat
#endif
#define FT_THROW( e ) \
- ( FT_Throw( FT_ERR_CAT( ErrRaster, e ), \
+ ( FT_Throw( FT_ERR_CAT( ErrRaster_, e ), \
__LINE__, \
__FILE__ ) | \
- FT_ERR_CAT( ErrRaster, e ) )
+ FT_ERR_CAT( ErrRaster_, e ) )
#else /* !FT_DEBUG_LEVEL_TRACE */
#define FT_TRACE5( x ) do { } while ( 0 ) /* nothing */
#define FT_TRACE7( x ) do { } while ( 0 ) /* nothing */
@@ -277,12 +277,10 @@
#include FT_INTERNAL_CALC_H
#include FT_OUTLINE_H
#include "ftsmerrs.h"
-#include "ftspic.h"
-
#define Smooth_Err_Invalid_Mode Smooth_Err_Cannot_Render_Glyph
#define Smooth_Err_Memory_Overflow Smooth_Err_Out_Of_Memory
#define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory
@@ -393,14 +391,14 @@
#define FT_UDIV( a, b ) \
( ( (unsigned long)( a ) * (unsigned long)( b ## _r ) ) >> \
( sizeof( long ) * FT_CHAR_BIT - PIXEL_BITS ) )
- /*************************************************************************/
- /* */
- /* TYPE DEFINITIONS */
- /* */
+ /**************************************************************************
+ *
+ * TYPE DEFINITIONS
+ */
/* don't change the following types to FT_Int or FT_Pos, since we might */
/* need to define them to "float" or "double" when experimenting with */
/* new algorithms */
@@ -514,14 +512,14 @@
}
#endif /* FT_DEBUG_LEVEL_TRACE */
- /*************************************************************************/
- /* */
- /* Record the current cell in the table. */
- /* */
+ /**************************************************************************
+ *
+ * Record the current cell in the table.
+ */
static void
gray_record_cell( RAS_ARG )
{
PCell *pcell, cell;
TCoord x = ras.ex;
@@ -559,14 +557,14 @@
cell->area += ras.area;
cell->cover += ras.cover;
}
- /*************************************************************************/
- /* */
- /* Set the current cell to a new position. */
- /* */
+ /**************************************************************************
+ *
+ * Set the current cell to a new position.
+ */
static void
gray_set_cell( RAS_ARG_ TCoord ex,
TCoord ey )
{
/* Move the cell pointer to a new position. We set the `invalid' */
@@ -596,14 +594,14 @@
}
#ifndef FT_LONG64
- /*************************************************************************/
- /* */
- /* Render a scanline as one or more cells. */
- /* */
+ /**************************************************************************
+ *
+ * Render a scanline as one or more cells.
+ */
static void
gray_render_scanline( RAS_ARG_ TCoord ey,
TPos x1,
TCoord y1,
TPos x2,
@@ -694,14 +692,14 @@
ras.area += (TArea)( ( fx1 + fx2 ) * dy );
ras.cover += dy;
}
- /*************************************************************************/
- /* */
- /* Render a given line as a series of scanlines. */
- /* */
+ /**************************************************************************
+ *
+ * Render a given line as a series of scanlines.
+ */
static void
gray_render_line( RAS_ARG_ TPos to_x,
TPos to_y )
{
TCoord ey1, ey2, fy1, fy2, first, delta, mod;
@@ -835,14 +833,14 @@
ras.y = to_y;
}
#else
- /*************************************************************************/
- /* */
- /* Render a straight line across multiple cells in any direction. */
- /* */
+ /**************************************************************************
+ *
+ * Render a straight line across multiple cells in any direction.
+ */
static void
gray_render_line( RAS_ARG_ TPos to_x,
TPos to_y )
{
TPos dx, dy, fx1, fy1, fx2, fy2;
@@ -1328,44 +1326,47 @@
}
#ifdef STANDALONE_
- /*************************************************************************/
- /* */
- /* The following functions should only compile in stand-alone mode, */
- /* i.e., when building this component without the rest of FreeType. */
- /* */
- /*************************************************************************/
+ /**************************************************************************
+ *
+ * The following functions should only compile in stand-alone mode,
+ * i.e., when building this component without the rest of FreeType.
+ *
+ */
- /*************************************************************************/
- /* */
- /* <Function> */
- /* FT_Outline_Decompose */
- /* */
- /* <Description> */
- /* Walk over an outline's structure to decompose it into individual */
- /* segments and Bézier arcs. This function is also able to emit */
- /* `move to' and `close to' operations to indicate the start and end */
- /* of new contours in the outline. */
- /* */
- /* <Input> */
- /* outline :: A pointer to the source target. */
- /* */
- /* func_interface :: A table of `emitters', i.e., function pointers */
- /* called during decomposition to indicate path */
- /* operations. */
- /* */
- /* <InOut> */
- /* user :: A typeless pointer which is passed to each */
- /* emitter during the decomposition. It can be */
- /* used to store the state during the */
- /* decomposition. */
- /* */
- /* <Return> */
- /* Error code. 0 means success. */
- /* */
+ /**************************************************************************
+ *
+ * @Function:
+ * FT_Outline_Decompose
+ *
+ * @Description:
+ * Walk over an outline's structure to decompose it into individual
+ * segments and Bézier arcs. This function is also able to emit
+ * `move to' and `close to' operations to indicate the start and end
+ * of new contours in the outline.
+ *
+ * @Input:
+ * outline ::
+ * A pointer to the source target.
+ *
+ * func_interface ::
+ * A table of `emitters', i.e., function pointers
+ * called during decomposition to indicate path
+ * operations.
+ *
+ * @InOut:
+ * user ::
+ * A typeless pointer which is passed to each
+ * emitter during the decomposition. It can be
+ * used to store the state during the
+ * decomposition.
+ *
+ * @Return:
+ * Error code. 0 means success.
+ */
static int
FT_Outline_Decompose( const FT_Outline* outline,
const FT_Outline_Funcs* func_interface,
void* user )
{
@@ -1608,85 +1609,10 @@
Invalid_Outline:
return FT_THROW( Invalid_Outline );
}
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* FT_Outline_Get_CBox */
- /* */
- /* <Description> */
- /* Return an outline's `control box'. The control box encloses all */
- /* the outline's points, including Bézier control points. Though it */
- /* coincides with the exact bounding box for most glyphs, it can be */
- /* slightly larger in some situations (like when rotating an outline */
- /* that contains Bézier outside arcs). */
- /* */
- /* Computing the control box is very fast, while getting the bounding */
- /* box can take much more time as it needs to walk over all segments */
- /* and arcs in the outline. To get the latter, you can use the */
- /* `ftbbox' component, which is dedicated to this single task. */
- /* */
- /* <Input> */
- /* outline :: A pointer to the source outline descriptor. */
- /* */
- /* <Output> */
- /* acbox :: The outline's control box. */
- /* */
- /* <Note> */
- /* See @FT_Glyph_Get_CBox for a discussion of tricky fonts. */
- /* */
-
- static void
- FT_Outline_Get_CBox( const FT_Outline* outline,
- FT_BBox *acbox )
- {
- TPos xMin, yMin, xMax, yMax;
-
-
- if ( outline && acbox )
- {
- if ( outline->n_points == 0 )
- {
- xMin = 0;
- yMin = 0;
- xMax = 0;
- yMax = 0;
- }
- else
- {
- FT_Vector* vec = outline->points;
- FT_Vector* limit = vec + outline->n_points;
-
-
- xMin = xMax = vec->x;
- yMin = yMax = vec->y;
- vec++;
-
- for ( ; vec < limit; vec++ )
- {
- TPos x, y;
-
-
- x = vec->x;
- if ( x < xMin ) xMin = x;
- if ( x > xMax ) xMax = x;
-
- y = vec->y;
- if ( y < yMin ) yMin = y;
- if ( y > yMax ) yMax = y;
- }
- }
- acbox->xMin = xMin;
- acbox->xMax = xMax;
- acbox->yMin = yMin;
- acbox->yMax = yMax;
- }
- }
-
#endif /* STANDALONE_ */
FT_DEFINE_OUTLINE_FUNCS(
func_interface,
@@ -1700,23 +1626,24 @@
0 /* delta */
)
static int
- gray_convert_glyph_inner( RAS_ARG )
+ gray_convert_glyph_inner( RAS_ARG,
+ int continued )
{
-
volatile int error = 0;
-#ifdef FT_CONFIG_OPTION_PIC
- FT_Outline_Funcs func_interface;
- Init_Class_func_interface(&func_interface);
-#endif
if ( ft_setjmp( ras.jump_buffer ) == 0 )
{
+ if ( continued )
+ FT_Trace_Disable();
error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras );
+ if ( continued )
+ FT_Trace_Enable();
+
if ( !ras.invalid )
gray_record_cell( RAS_VAR );
FT_TRACE7(( "band [%d..%d]: %d cell%s\n",
ras.min_ey,
@@ -1739,20 +1666,20 @@
static int
gray_convert_glyph( RAS_ARG )
{
const TCoord yMin = ras.min_ey;
const TCoord yMax = ras.max_ey;
- const TCoord xMin = ras.min_ex;
- const TCoord xMax = ras.max_ex;
TCell buffer[FT_MAX_GRAY_POOL];
size_t height = (size_t)( yMax - yMin );
size_t n = FT_MAX_GRAY_POOL / 8;
TCoord y;
TCoord bands[32]; /* enough to accommodate bisections */
TCoord* band;
+ int continued = 0;
+
/* set up vertical bands */
if ( height > n )
{
/* two divisions rounded up */
@@ -1772,12 +1699,12 @@
ras.min_ey = y;
y += height;
ras.max_ey = FT_MIN( y, yMax );
band = bands;
- band[1] = xMin;
- band[0] = xMax;
+ band[1] = ras.min_ey;
+ band[0] = ras.max_ey;
do
{
TCoord width = band[0] - band[1];
int error;
@@ -1785,14 +1712,15 @@
FT_MEM_ZERO( ras.ycells, height * sizeof ( PCell ) );
ras.num_cells = 0;
ras.invalid = 1;
- ras.min_ex = band[1];
- ras.max_ex = band[0];
+ ras.min_ey = band[1];
+ ras.max_ey = band[0];
- error = gray_convert_glyph_inner( RAS_VAR );
+ error = gray_convert_glyph_inner( RAS_VAR, continued );
+ continued = 1;
if ( !error )
{
gray_sweep( RAS_VAR );
band--;
@@ -1825,11 +1753,11 @@
gray_raster_render( FT_Raster raster,
const FT_Raster_Params* params )
{
const FT_Outline* outline = (const FT_Outline*)params->source;
const FT_Bitmap* target_map = params->target;
- FT_BBox cbox, clip;
+ FT_BBox clip;
#ifndef FT_STATIC_RASTER
gray_TWorker worker[1];
#endif
@@ -1888,47 +1816,28 @@
ras.render_span = (FT_Raster_Span_Func)NULL;
ras.render_span_data = NULL;
}
- FT_Outline_Get_CBox( outline, &cbox );
-
- /* reject too large outline coordinates */
- if ( cbox.xMin < -0x1000000L || cbox.xMax > 0x1000000L ||
- cbox.yMin < -0x1000000L || cbox.yMax > 0x1000000L )
- return FT_THROW( Invalid_Outline );
-
- /* truncate the bounding box to integer pixels */
- cbox.xMin = cbox.xMin >> 6;
- cbox.yMin = cbox.yMin >> 6;
- cbox.xMax = ( cbox.xMax + 63 ) >> 6;
- cbox.yMax = ( cbox.yMax + 63 ) >> 6;
-
/* compute clipping box */
- if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
+ if ( params->flags & FT_RASTER_FLAG_DIRECT &&
+ params->flags & FT_RASTER_FLAG_CLIP )
+ clip = params->clip_box;
+ else
{
/* compute clip box from target pixmap */
clip.xMin = 0;
clip.yMin = 0;
clip.xMax = (FT_Pos)target_map->width;
clip.yMax = (FT_Pos)target_map->rows;
}
- else if ( params->flags & FT_RASTER_FLAG_CLIP )
- clip = params->clip_box;
- else
- {
- clip.xMin = -32768L;
- clip.yMin = -32768L;
- clip.xMax = 32767L;
- clip.yMax = 32767L;
- }
/* clip to target bitmap, exit if nothing to do */
- ras.min_ex = FT_MAX( cbox.xMin, clip.xMin );
- ras.min_ey = FT_MAX( cbox.yMin, clip.yMin );
- ras.max_ex = FT_MIN( cbox.xMax, clip.xMax );
- ras.max_ey = FT_MIN( cbox.yMax, clip.yMax );
+ ras.min_ex = clip.xMin;
+ ras.min_ey = clip.yMin;
+ ras.max_ex = clip.xMax;
+ ras.max_ey = clip.yMax;
if ( ras.max_ex <= ras.min_ex || ras.max_ey <= ras.min_ey )
return 0;
return gray_convert_glyph( RAS_VAR );
< prev index next >