2000-10-26 02:30:33 +02:00
|
|
|
/***************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* ftraster.c */
|
|
|
|
/* */
|
|
|
|
/* The FreeType glyph rasterizer (body). */
|
|
|
|
/* */
|
2013-03-14 10:27:35 +01:00
|
|
|
/* Copyright 1996-2003, 2005, 2007-2013 by */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* 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. */
|
|
|
|
/* */
|
|
|
|
/***************************************************************************/
|
|
|
|
|
* src/raster/ftmisc.h: New file. Only needed if ftraster.c is
compiled as stand-alone.
* src/raster/ftraster.c: Add comment how to compile as stand-alone.
s/FT_CONFIG_OPTION_STATIC_RASTER/FT_STATIC_RASTER/.
s/TT_STATIC_RASTER/FT_STATIC_RASTER/.
[_STANDALONE_]: Include ftimage.h and ftmisc.h.
(FT_TRACE1, FT_TRACE6, ft_memset, FT_MEM_ZERO): Define
conditionally.
(Render_Glyph, Render_Gray_Glyph): Return Raster_Err_None (or
Raster_Err_Unsupported).
(ft_black_new) [_STANDALONE_]: Fix type of `the_raster'.
(ft_black_init, ft_black_reset, ft_black_set_mode, ft_black_render):
Use `ras', not `raster'.
(ft_black_done): Use FT_UNUSED_RASTER.
(Horizontal_Sweep_Init, Horizontal_Sweep_Step,
Horizontal_Gray_Sweep_Span): Use FT_UNUSED_RASTER.
* docs/CHANGES: Updated.
2005-05-19 09:20:24 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* 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 `ftimage.h' and `ftmisc.h' into the $(incdir) */
|
|
|
|
/* directory. Typically, you should do something like */
|
|
|
|
/* */
|
|
|
|
/* - copy `src/raster/ftraster.c' (this file) to your current directory */
|
|
|
|
/* */
|
|
|
|
/* - copy `include/freetype/ftimage.h' and `src/raster/ftmisc.h' */
|
|
|
|
/* to your current directory */
|
|
|
|
/* */
|
|
|
|
/* - compile `ftraster' with the _STANDALONE_ macro defined, as in */
|
|
|
|
/* */
|
|
|
|
/* cc -c -D_STANDALONE_ ftraster.c */
|
|
|
|
/* */
|
|
|
|
/* The renderer can be initialized with a call to */
|
|
|
|
/* `ft_standard_raster.raster_new'; a bitmap can be generated */
|
|
|
|
/* with a call to `ft_standard_raster.raster_render'. */
|
|
|
|
/* */
|
|
|
|
/* See the comments and documentation in the file `ftimage.h' for more */
|
|
|
|
/* details on how the raster works. */
|
|
|
|
/* */
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* This is a rewrite of the FreeType 1.x scan-line converter */
|
|
|
|
/* */
|
|
|
|
/*************************************************************************/
|
|
|
|
|
* src/raster/ftmisc.h: New file. Only needed if ftraster.c is
compiled as stand-alone.
* src/raster/ftraster.c: Add comment how to compile as stand-alone.
s/FT_CONFIG_OPTION_STATIC_RASTER/FT_STATIC_RASTER/.
s/TT_STATIC_RASTER/FT_STATIC_RASTER/.
[_STANDALONE_]: Include ftimage.h and ftmisc.h.
(FT_TRACE1, FT_TRACE6, ft_memset, FT_MEM_ZERO): Define
conditionally.
(Render_Glyph, Render_Gray_Glyph): Return Raster_Err_None (or
Raster_Err_Unsupported).
(ft_black_new) [_STANDALONE_]: Fix type of `the_raster'.
(ft_black_init, ft_black_reset, ft_black_set_mode, ft_black_render):
Use `ras', not `raster'.
(ft_black_done): Use FT_UNUSED_RASTER.
(Horizontal_Sweep_Init, Horizontal_Sweep_Step,
Horizontal_Gray_Sweep_Span): Use FT_UNUSED_RASTER.
* docs/CHANGES: Updated.
2005-05-19 09:20:24 +02:00
|
|
|
#ifdef _STANDALONE_
|
|
|
|
|
2009-07-09 09:21:46 +02:00
|
|
|
#define FT_CONFIG_STANDARD_LIBRARY_H <stdlib.h>
|
|
|
|
|
2009-09-12 23:15:17 +02:00
|
|
|
#include <string.h> /* for memset */
|
2009-07-09 09:21:46 +02:00
|
|
|
|
* src/raster/ftmisc.h: New file. Only needed if ftraster.c is
compiled as stand-alone.
* src/raster/ftraster.c: Add comment how to compile as stand-alone.
s/FT_CONFIG_OPTION_STATIC_RASTER/FT_STATIC_RASTER/.
s/TT_STATIC_RASTER/FT_STATIC_RASTER/.
[_STANDALONE_]: Include ftimage.h and ftmisc.h.
(FT_TRACE1, FT_TRACE6, ft_memset, FT_MEM_ZERO): Define
conditionally.
(Render_Glyph, Render_Gray_Glyph): Return Raster_Err_None (or
Raster_Err_Unsupported).
(ft_black_new) [_STANDALONE_]: Fix type of `the_raster'.
(ft_black_init, ft_black_reset, ft_black_set_mode, ft_black_render):
Use `ras', not `raster'.
(ft_black_done): Use FT_UNUSED_RASTER.
(Horizontal_Sweep_Init, Horizontal_Sweep_Step,
Horizontal_Gray_Sweep_Span): Use FT_UNUSED_RASTER.
* docs/CHANGES: Updated.
2005-05-19 09:20:24 +02:00
|
|
|
#include "ftmisc.h"
|
|
|
|
#include "ftimage.h"
|
|
|
|
|
|
|
|
#else /* !_STANDALONE_ */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2000-12-08 03:42:29 +01:00
|
|
|
#include <ft2build.h>
|
2001-03-20 12:14:24 +01:00
|
|
|
#include "ftraster.h"
|
2012-06-06 13:24:04 +02:00
|
|
|
#include FT_INTERNAL_CALC_H /* for FT_MulDiv and FT_MulDiv_No_Round */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2009-07-09 09:21:46 +02:00
|
|
|
#include "rastpic.h"
|
|
|
|
|
* src/raster/ftmisc.h: New file. Only needed if ftraster.c is
compiled as stand-alone.
* src/raster/ftraster.c: Add comment how to compile as stand-alone.
s/FT_CONFIG_OPTION_STATIC_RASTER/FT_STATIC_RASTER/.
s/TT_STATIC_RASTER/FT_STATIC_RASTER/.
[_STANDALONE_]: Include ftimage.h and ftmisc.h.
(FT_TRACE1, FT_TRACE6, ft_memset, FT_MEM_ZERO): Define
conditionally.
(Render_Glyph, Render_Gray_Glyph): Return Raster_Err_None (or
Raster_Err_Unsupported).
(ft_black_new) [_STANDALONE_]: Fix type of `the_raster'.
(ft_black_init, ft_black_reset, ft_black_set_mode, ft_black_render):
Use `ras', not `raster'.
(ft_black_done): Use FT_UNUSED_RASTER.
(Horizontal_Sweep_Init, Horizontal_Sweep_Step,
Horizontal_Gray_Sweep_Span): Use FT_UNUSED_RASTER.
* docs/CHANGES: Updated.
2005-05-19 09:20:24 +02:00
|
|
|
#endif /* !_STANDALONE_ */
|
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* A simple technical note on how the raster works */
|
|
|
|
/* ----------------------------------------------- */
|
|
|
|
/* */
|
|
|
|
/* Converting an outline into a bitmap is achieved in several steps: */
|
|
|
|
/* */
|
|
|
|
/* 1 - Decomposing the outline into successive `profiles'. Each */
|
|
|
|
/* profile is simply an array of scanline intersections on a given */
|
|
|
|
/* dimension. A profile's main attributes are */
|
|
|
|
/* */
|
2009-06-18 15:48:21 +02:00
|
|
|
/* o its scanline position boundaries, i.e. `Ymin' and `Ymax' */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* o an array of intersection coordinates for each scanline */
|
2009-06-18 15:48:21 +02:00
|
|
|
/* between `Ymin' and `Ymax' */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* o a direction, indicating whether it was built going `up' or */
|
2009-06-18 15:48:21 +02:00
|
|
|
/* `down', as this is very important for filling rules */
|
|
|
|
/* */
|
|
|
|
/* o its drop-out mode */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* 2 - Sweeping the target map's scanlines in order to compute segment */
|
|
|
|
/* `spans' which are then filled. Additionally, this pass */
|
|
|
|
/* performs drop-out control. */
|
|
|
|
/* */
|
|
|
|
/* The outline data is parsed during step 1 only. The profiles are */
|
|
|
|
/* built from the bottom of the render pool, used as a stack. The */
|
|
|
|
/* following graphics shows the profile list under construction: */
|
|
|
|
/* */
|
2009-06-18 15:48:21 +02:00
|
|
|
/* __________________________________________________________ _ _ */
|
|
|
|
/* | | | | | */
|
|
|
|
/* | profile | coordinates for | profile | coordinates for |--> */
|
|
|
|
/* | 1 | profile 1 | 2 | profile 2 |--> */
|
|
|
|
/* |_________|_________________|_________|_________________|__ _ _ */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
2009-06-18 15:48:21 +02:00
|
|
|
/* ^ ^ */
|
|
|
|
/* | | */
|
|
|
|
/* start of render pool top */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* The top of the profile stack is kept in the `top' variable. */
|
|
|
|
/* */
|
|
|
|
/* As you can see, a profile record is pushed on top of the render */
|
|
|
|
/* pool, which is then followed by its coordinates/intersections. If */
|
|
|
|
/* a change of direction is detected in the outline, a new profile is */
|
|
|
|
/* generated until the end of the outline. */
|
|
|
|
/* */
|
|
|
|
/* Note that when all profiles have been generated, the function */
|
|
|
|
/* Finalize_Profile_Table() is used to record, for each profile, its */
|
|
|
|
/* bottom-most scanline as well as the scanline above its upmost */
|
|
|
|
/* boundary. These positions are called `y-turns' because they (sort */
|
|
|
|
/* of) correspond to local extrema. They are stored in a sorted list */
|
|
|
|
/* built from the top of the render pool as a downwards stack: */
|
|
|
|
/* */
|
|
|
|
/* _ _ _______________________________________ */
|
|
|
|
/* | | */
|
|
|
|
/* <--| sorted list of | */
|
|
|
|
/* <--| extrema scanlines | */
|
|
|
|
/* _ _ __________________|____________________| */
|
|
|
|
/* */
|
|
|
|
/* ^ ^ */
|
|
|
|
/* | | */
|
|
|
|
/* maxBuff sizeBuff = end of pool */
|
|
|
|
/* */
|
|
|
|
/* This list is later used during the sweep phase in order to */
|
|
|
|
/* optimize performance (see technical note on the sweep below). */
|
|
|
|
/* */
|
|
|
|
/* Of course, the raster detects whether the two stacks collide and */
|
2007-01-26 23:18:56 +01:00
|
|
|
/* handles the situation properly. */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/** **/
|
|
|
|
/** CONFIGURATION MACROS **/
|
|
|
|
/** **/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
/* define DEBUG_RASTER if you want to compile a debugging version */
|
2009-09-12 23:15:17 +02:00
|
|
|
/* #define DEBUG_RASTER */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2009-09-12 23:15:17 +02:00
|
|
|
/* define FT_RASTER_OPTION_ANTI_ALIASING if you want to support */
|
|
|
|
/* 5-levels anti-aliasing */
|
|
|
|
/* #define FT_RASTER_OPTION_ANTI_ALIASING */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
/* The size of the two-lines intermediate bitmap used */
|
|
|
|
/* for anti-aliasing, in bytes. */
|
|
|
|
#define RASTER_GRAY_LINES 2048
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/** **/
|
|
|
|
/** OTHER MACROS (do not change) **/
|
|
|
|
/** **/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* 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_raster
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _STANDALONE_
|
|
|
|
|
2013-03-14 10:27:35 +01:00
|
|
|
/* Auxiliary macros for token concatenation. */
|
|
|
|
#define FT_ERR_XCAT( x, y ) x ## y
|
|
|
|
#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y )
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
/* This macro is used to indicate that a function parameter is unused. */
|
|
|
|
/* Its purpose is simply to reduce compiler warnings. Note also that */
|
|
|
|
/* simply defining it as `(void)x' doesn't avoid warnings with certain */
|
|
|
|
/* ANSI compilers (e.g. LCC). */
|
|
|
|
#define FT_UNUSED( x ) (x) = (x)
|
|
|
|
|
|
|
|
/* Disable the tracing mechanism for simplicity -- developers can */
|
2013-03-14 10:27:35 +01:00
|
|
|
/* activate it easily by redefining these macros. */
|
2000-10-26 02:30:33 +02:00
|
|
|
#ifndef FT_ERROR
|
2009-01-12 21:11:14 +01:00
|
|
|
#define FT_ERROR( x ) do { } while ( 0 ) /* nothing */
|
2000-10-26 02:30:33 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef FT_TRACE
|
2009-01-12 21:11:14 +01:00
|
|
|
#define FT_TRACE( x ) do { } while ( 0 ) /* nothing */
|
|
|
|
#define FT_TRACE1( x ) do { } while ( 0 ) /* nothing */
|
|
|
|
#define FT_TRACE6( x ) do { } while ( 0 ) /* nothing */
|
2000-10-26 02:30:33 +02:00
|
|
|
#endif
|
|
|
|
|
2013-03-14 10:27:35 +01:00
|
|
|
#ifndef FT_THROW
|
|
|
|
#define FT_THROW( e ) FT_ERR_CAT( Raster_Err_, e )
|
|
|
|
#endif
|
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
#define Raster_Err_None 0
|
|
|
|
#define Raster_Err_Not_Ini -1
|
|
|
|
#define Raster_Err_Overflow -2
|
|
|
|
#define Raster_Err_Neg_Height -3
|
|
|
|
#define Raster_Err_Invalid -4
|
|
|
|
#define Raster_Err_Unsupported -5
|
|
|
|
|
2009-07-09 09:21:46 +02:00
|
|
|
#define ft_memset memset
|
|
|
|
|
|
|
|
#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, raster_new_, \
|
|
|
|
raster_reset_, raster_set_mode_, \
|
|
|
|
raster_render_, raster_done_ ) \
|
|
|
|
const FT_Raster_Funcs class_ = \
|
|
|
|
{ \
|
|
|
|
glyph_format_, \
|
|
|
|
raster_new_, \
|
|
|
|
raster_reset_, \
|
|
|
|
raster_set_mode_, \
|
|
|
|
raster_render_, \
|
|
|
|
raster_done_ \
|
|
|
|
};
|
2009-06-18 15:48:21 +02:00
|
|
|
|
|
|
|
#else /* !_STANDALONE_ */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
Complete redesign of error codes. Please check ftmoderr.h for more
details.
* include/freetype/internal/cfferrs.h,
include/freetype/internal/tterrors.h,
include/freetype/internal/t1errors.h: Removed. Replaced with files
local to the module. All extra error codes have been moved to
`fterrors.h'.
* src/sfnt/ttpost.h: Move error codes to `fterrors.h'.
* src/autohint/aherrors.h, src/cache/ftcerror.h, src/cff/cfferrs.h,
src/cid/ciderrs.h, src/pcf/pcferror.h, src/psaux/psauxerr.h,
src/psnames/psnamerr.h, src/raster/rasterrs.h, src/sfnt/sferrors.h,
src/smooth/ftsmerrs.h, src/truetype/tterrors.h,
src/type1/t1errors.h, src/winfonts/fnterrs.h: New files defining the
error names for the module it belongs to.
* include/freetype/ftmoderr.h: New file, defining the module error
offsets. Its structure is similar to `fterrors.h'.
* include/freetype/fterrors.h (FT_NOERRORDEF): New macro.
(FT_ERRORDEF): Redefined to use module error offsets.
All internal error codes are now public; unused error codes have
been removed, some are new.
* include/freetype/config/ftheader.h (FT_MODULE_ERRORS_H): New
macro.
* include/freetype/config/ftoption.h
(FT_CONFIG_OPTION_USE_MODULE_ERRORS): New macro.
All other source files have been updated to use the new error codes;
some already existing (internal) error codes local to a module have
been renamed to give them the same name as in the base module.
All make files have been updated to include the local error files.
* src/cid/cidtokens.h: Replaced with...
* src/cid/cidtoken.h: This file for 8+3 consistency.
* src/raster/ftraster.c: Use macros for header file names.
2001-06-06 19:30:41 +02:00
|
|
|
#include FT_INTERNAL_OBJECTS_H
|
2013-03-14 10:27:35 +01:00
|
|
|
#include FT_INTERNAL_DEBUG_H /* for FT_TRACE, FT_ERROR, and FT_THROW */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
Complete redesign of error codes. Please check ftmoderr.h for more
details.
* include/freetype/internal/cfferrs.h,
include/freetype/internal/tterrors.h,
include/freetype/internal/t1errors.h: Removed. Replaced with files
local to the module. All extra error codes have been moved to
`fterrors.h'.
* src/sfnt/ttpost.h: Move error codes to `fterrors.h'.
* src/autohint/aherrors.h, src/cache/ftcerror.h, src/cff/cfferrs.h,
src/cid/ciderrs.h, src/pcf/pcferror.h, src/psaux/psauxerr.h,
src/psnames/psnamerr.h, src/raster/rasterrs.h, src/sfnt/sferrors.h,
src/smooth/ftsmerrs.h, src/truetype/tterrors.h,
src/type1/t1errors.h, src/winfonts/fnterrs.h: New files defining the
error names for the module it belongs to.
* include/freetype/ftmoderr.h: New file, defining the module error
offsets. Its structure is similar to `fterrors.h'.
* include/freetype/fterrors.h (FT_NOERRORDEF): New macro.
(FT_ERRORDEF): Redefined to use module error offsets.
All internal error codes are now public; unused error codes have
been removed, some are new.
* include/freetype/config/ftheader.h (FT_MODULE_ERRORS_H): New
macro.
* include/freetype/config/ftoption.h
(FT_CONFIG_OPTION_USE_MODULE_ERRORS): New macro.
All other source files have been updated to use the new error codes;
some already existing (internal) error codes local to a module have
been renamed to give them the same name as in the base module.
All make files have been updated to include the local error files.
* src/cid/cidtokens.h: Replaced with...
* src/cid/cidtoken.h: This file for 8+3 consistency.
* src/raster/ftraster.c: Use macros for header file names.
2001-06-06 19:30:41 +02:00
|
|
|
#include "rasterrs.h"
|
|
|
|
|
2013-03-14 11:21:17 +01:00
|
|
|
#define Raster_Err_None FT_Err_Ok
|
Complete redesign of error codes. Please check ftmoderr.h for more
details.
* include/freetype/internal/cfferrs.h,
include/freetype/internal/tterrors.h,
include/freetype/internal/t1errors.h: Removed. Replaced with files
local to the module. All extra error codes have been moved to
`fterrors.h'.
* src/sfnt/ttpost.h: Move error codes to `fterrors.h'.
* src/autohint/aherrors.h, src/cache/ftcerror.h, src/cff/cfferrs.h,
src/cid/ciderrs.h, src/pcf/pcferror.h, src/psaux/psauxerr.h,
src/psnames/psnamerr.h, src/raster/rasterrs.h, src/sfnt/sferrors.h,
src/smooth/ftsmerrs.h, src/truetype/tterrors.h,
src/type1/t1errors.h, src/winfonts/fnterrs.h: New files defining the
error names for the module it belongs to.
* include/freetype/ftmoderr.h: New file, defining the module error
offsets. Its structure is similar to `fterrors.h'.
* include/freetype/fterrors.h (FT_NOERRORDEF): New macro.
(FT_ERRORDEF): Redefined to use module error offsets.
All internal error codes are now public; unused error codes have
been removed, some are new.
* include/freetype/config/ftheader.h (FT_MODULE_ERRORS_H): New
macro.
* include/freetype/config/ftoption.h
(FT_CONFIG_OPTION_USE_MODULE_ERRORS): New macro.
All other source files have been updated to use the new error codes;
some already existing (internal) error codes local to a module have
been renamed to give them the same name as in the base module.
All make files have been updated to include the local error files.
* src/cid/cidtokens.h: Replaced with...
* src/cid/cidtoken.h: This file for 8+3 consistency.
* src/raster/ftraster.c: Use macros for header file names.
2001-06-06 19:30:41 +02:00
|
|
|
#define Raster_Err_Not_Ini Raster_Err_Raster_Uninitialized
|
|
|
|
#define Raster_Err_Overflow Raster_Err_Raster_Overflow
|
|
|
|
#define Raster_Err_Neg_Height Raster_Err_Raster_Negative_Height
|
|
|
|
#define Raster_Err_Invalid Raster_Err_Invalid_Outline
|
|
|
|
#define Raster_Err_Unsupported Raster_Err_Cannot_Render_Glyph
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
#endif /* !_STANDALONE_ */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
2002-03-22 14:52:37 +01:00
|
|
|
#ifndef FT_MEM_SET
|
* README.UNX: updated the Unix-specific quick-compilation guide to
warn about the GNU Make requirement at compile time..
* include/freetype/config/ftstdlib.h,
include/freetype/config/ftconfig.h,
include/freetype/config/ftheader.h,
include/freetype/internal/ftmemory.h,
include/freetype/internal/ftobjs.h,
src/autohint/ahoptim.c,
src/base/ftdbgmem.c, src/base/ftdebug.c,
src/base/ftmac.c, src/base/ftobjs.c,
src/base/ftsystem.c,
src/cache/ftcimage.c, src/cache/ftcsbits.c,
src/cff/cffdriver.c, src/cff/cffload.c, src/cff/cffobjs.c,
src/cid/cidload.c, src/cid/cidparse.c, src/cid/cidriver.c,
src/pcf/pcfdriver.c, src/pcf/pcfread.c,
src/psaux/t1cmap.c, src/psaux/t1decode.c,
src/pshinter/pshalgo1.c, src/pshinter/pshalgo2.c,
src/pshinter/pshrec.c,
src/psnames/psmodule.c,
src/raster/ftraster.c,
src/sfnt/sfdriver.c, src/sfnt/ttload.c, src/sfnt/ttpost.c,
src/smooth/ftgrays.c,
src/type1/t1afm.c, src/type1/t1driver.c, src/type1/t1gload.c,
src/type1/t1load.c, src/type1/t1objs.c, src/type1/t1parse.c:
added the new configuration file "ftstdlib.h" used to define
aliases for all ISO C library functions used by the engine
(e.g. strlen, qsort, setjmp, etc...)
this eases the porting of FreeType 2 to exotic environments like
XFree86 modules/extensions..
also removed many #include <string.h>, #include <stdlib.h>, etc...
from the engine's sources where they're not needed..
2002-04-12 11:31:48 +02:00
|
|
|
#define FT_MEM_SET( d, s, c ) ft_memset( d, s, c )
|
2001-12-05 02:22:05 +01:00
|
|
|
#endif
|
|
|
|
|
* src/raster/ftmisc.h: New file. Only needed if ftraster.c is
compiled as stand-alone.
* src/raster/ftraster.c: Add comment how to compile as stand-alone.
s/FT_CONFIG_OPTION_STATIC_RASTER/FT_STATIC_RASTER/.
s/TT_STATIC_RASTER/FT_STATIC_RASTER/.
[_STANDALONE_]: Include ftimage.h and ftmisc.h.
(FT_TRACE1, FT_TRACE6, ft_memset, FT_MEM_ZERO): Define
conditionally.
(Render_Glyph, Render_Gray_Glyph): Return Raster_Err_None (or
Raster_Err_Unsupported).
(ft_black_new) [_STANDALONE_]: Fix type of `the_raster'.
(ft_black_init, ft_black_reset, ft_black_set_mode, ft_black_render):
Use `ras', not `raster'.
(ft_black_done): Use FT_UNUSED_RASTER.
(Horizontal_Sweep_Init, Horizontal_Sweep_Step,
Horizontal_Gray_Sweep_Span): Use FT_UNUSED_RASTER.
* docs/CHANGES: Updated.
2005-05-19 09:20:24 +02:00
|
|
|
#ifndef FT_MEM_ZERO
|
|
|
|
#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count )
|
|
|
|
#endif
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
/* FMulDiv means `Fast MulDiv'; it is used in case where `b' is */
|
|
|
|
/* typically a small value and the result of a*b is known to fit into */
|
|
|
|
/* 32 bits. */
|
|
|
|
#define FMulDiv( a, b, c ) ( (a) * (b) / (c) )
|
|
|
|
|
|
|
|
/* On the other hand, SMulDiv means `Slow MulDiv', and is used typically */
|
|
|
|
/* for clipping computations. It simply uses the FT_MulDiv() function */
|
|
|
|
/* defined in `ftcalc.h'. */
|
2012-06-06 13:24:04 +02:00
|
|
|
#define SMulDiv FT_MulDiv
|
|
|
|
#define SMulDiv_No_Round FT_MulDiv_No_Round
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
/* The rasterizer is a very general purpose component; please leave */
|
|
|
|
/* the following redefinitions there (you never know your target */
|
|
|
|
/* environment). */
|
|
|
|
|
|
|
|
#ifndef TRUE
|
|
|
|
#define TRUE 1
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef FALSE
|
|
|
|
#define FALSE 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef NULL
|
|
|
|
#define NULL (void*)0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef SUCCESS
|
|
|
|
#define SUCCESS 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef FAILURE
|
|
|
|
#define FAILURE 1
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#define MaxBezier 32 /* The maximum number of stacked Bezier curves. */
|
|
|
|
/* Setting this constant to more than 32 is a */
|
|
|
|
/* pure waste of space. */
|
|
|
|
|
|
|
|
#define Pixel_Bits 6 /* fractional bits of *input* coordinates */
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/** **/
|
|
|
|
/** SIMPLE TYPE DECLARATIONS **/
|
|
|
|
/** **/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
typedef int Int;
|
|
|
|
typedef unsigned int UInt;
|
|
|
|
typedef short Short;
|
|
|
|
typedef unsigned short UShort, *PUShort;
|
|
|
|
typedef long Long, *PLong;
|
2013-05-05 10:41:20 +02:00
|
|
|
typedef unsigned long ULong;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
typedef unsigned char Byte, *PByte;
|
|
|
|
typedef char Bool;
|
|
|
|
|
2004-06-12 15:21:20 +02:00
|
|
|
|
|
|
|
typedef union Alignment_
|
2004-06-09 22:18:35 +02:00
|
|
|
{
|
|
|
|
long l;
|
|
|
|
void* p;
|
|
|
|
void (*f)(void);
|
|
|
|
|
|
|
|
} Alignment, *PAlignment;
|
|
|
|
|
2004-06-12 15:21:20 +02:00
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
typedef struct TPoint_
|
|
|
|
{
|
|
|
|
Long x;
|
|
|
|
Long y;
|
|
|
|
|
|
|
|
} TPoint;
|
|
|
|
|
|
|
|
|
2009-06-16 15:14:21 +02:00
|
|
|
/* values for the `flags' bit field */
|
Fix B/W rasterization of subglyphs with different drop-out modes.
Normally, the SCANMODE instruction (if present) to set the drop-out
mode in a TrueType font is located in the `prep' table only and thus
valid for all glyphs. However, there are fonts like `pala.ttf'
which additionally contain this instruction in the hinting code of
some glyphs (but not all). As a result it can happen that a
composite glyph needs multiple drop-out modes for its subglyphs
since the rendering state gets reset for each subglyph.
FreeType collects the hinted outlines from all subglyphs, then it
sends the data to the rasterizer. It also sends the drop-out mode
-- after hinting has been applied -- and here is the error: It sends
the drop-out mode of the last subglyph only; drop-out modes of all
other subglyphs are lost.
This patch fixes the problem; it adds a second, alternative
mechanism to pass the drop-out mode: For each contour, the
rasterizer now checks the first `tags' array element. If bit 2 is
set, bits 5-7 contain the contour's drop-out mode, overriding the
global drop-out mode.
* include/freetype/ftimage.h (FT_CURVE_TAG_HAS_SCANMODE): New macro.
* src/truetype/ttgload.c (TT_Hint_Glyph): Store drop-out mode in
`tags[0]'.
* src/raster/ftraster.c (Flow_Up, Overshoot_Top, Overshoot_Bottom):
Use bits 3-5 instead of 0-2.
(New_Profile): Set the drop-out mode in the profile's `flags' field.
(Decompose_Curve): Check `tags[0]' and set `dropOutControl' if
necessary.
(Vertical_Sweep_Drop, Horizontal_Sweep_Drop,
Horizontal_Gray_Sweep_Drop, Draw_Sweep): Use the profile's drop-out
mode.
2009-06-18 15:42:52 +02:00
|
|
|
#define Flow_Up 0x8
|
|
|
|
#define Overshoot_Top 0x10
|
|
|
|
#define Overshoot_Bottom 0x20
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* States of each line, arc, and profile */
|
|
|
|
typedef enum TStates_
|
|
|
|
{
|
2002-04-30 16:26:49 +02:00
|
|
|
Unknown_State,
|
|
|
|
Ascending_State,
|
|
|
|
Descending_State,
|
|
|
|
Flat_State
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
} TStates;
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct TProfile_ TProfile;
|
|
|
|
typedef TProfile* PProfile;
|
|
|
|
|
|
|
|
struct TProfile_
|
|
|
|
{
|
2009-06-16 15:14:21 +02:00
|
|
|
FT_F26Dot6 X; /* current coordinate during sweep */
|
|
|
|
PProfile link; /* link to next profile (various purposes) */
|
|
|
|
PLong offset; /* start of profile's data in render pool */
|
Fix B/W rasterization of subglyphs with different drop-out modes.
Normally, the SCANMODE instruction (if present) to set the drop-out
mode in a TrueType font is located in the `prep' table only and thus
valid for all glyphs. However, there are fonts like `pala.ttf'
which additionally contain this instruction in the hinting code of
some glyphs (but not all). As a result it can happen that a
composite glyph needs multiple drop-out modes for its subglyphs
since the rendering state gets reset for each subglyph.
FreeType collects the hinted outlines from all subglyphs, then it
sends the data to the rasterizer. It also sends the drop-out mode
-- after hinting has been applied -- and here is the error: It sends
the drop-out mode of the last subglyph only; drop-out modes of all
other subglyphs are lost.
This patch fixes the problem; it adds a second, alternative
mechanism to pass the drop-out mode: For each contour, the
rasterizer now checks the first `tags' array element. If bit 2 is
set, bits 5-7 contain the contour's drop-out mode, overriding the
global drop-out mode.
* include/freetype/ftimage.h (FT_CURVE_TAG_HAS_SCANMODE): New macro.
* src/truetype/ttgload.c (TT_Hint_Glyph): Store drop-out mode in
`tags[0]'.
* src/raster/ftraster.c (Flow_Up, Overshoot_Top, Overshoot_Bottom):
Use bits 3-5 instead of 0-2.
(New_Profile): Set the drop-out mode in the profile's `flags' field.
(Decompose_Curve): Check `tags[0]' and set `dropOutControl' if
necessary.
(Vertical_Sweep_Drop, Horizontal_Sweep_Drop,
Horizontal_Gray_Sweep_Drop, Draw_Sweep): Use the profile's drop-out
mode.
2009-06-18 15:42:52 +02:00
|
|
|
unsigned flags; /* Bit 0-2: drop-out mode */
|
|
|
|
/* Bit 3: profile orientation (up/down) */
|
|
|
|
/* Bit 4: is top profile? */
|
|
|
|
/* Bit 5: is bottom profile? */
|
2009-06-16 15:14:21 +02:00
|
|
|
long height; /* profile's height in scanlines */
|
|
|
|
long start; /* profile's starting scanline */
|
|
|
|
|
|
|
|
unsigned countL; /* number of lines to step before this */
|
|
|
|
/* profile becomes drawable */
|
|
|
|
|
|
|
|
PProfile next; /* next profile in same contour, used */
|
|
|
|
/* during drop-out control */
|
2000-10-26 02:30:33 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef PProfile TProfileList;
|
|
|
|
typedef PProfile* PProfileList;
|
|
|
|
|
|
|
|
|
|
|
|
/* Simple record used to implement a stack of bands, required */
|
|
|
|
/* by the sub-banding mechanism */
|
2012-02-21 08:48:39 +01:00
|
|
|
typedef struct black_TBand_
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
Short y_min; /* band's minimum */
|
|
|
|
Short y_max; /* band's maximum */
|
|
|
|
|
2012-02-21 08:48:39 +01:00
|
|
|
} black_TBand;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
#define AlignProfileSize \
|
2004-06-12 15:21:20 +02:00
|
|
|
( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( long ) )
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
2012-02-22 07:01:35 +01:00
|
|
|
#undef RAS_ARG
|
|
|
|
#undef RAS_ARGS
|
|
|
|
#undef RAS_VAR
|
|
|
|
#undef RAS_VARS
|
|
|
|
|
* src/raster/ftmisc.h: New file. Only needed if ftraster.c is
compiled as stand-alone.
* src/raster/ftraster.c: Add comment how to compile as stand-alone.
s/FT_CONFIG_OPTION_STATIC_RASTER/FT_STATIC_RASTER/.
s/TT_STATIC_RASTER/FT_STATIC_RASTER/.
[_STANDALONE_]: Include ftimage.h and ftmisc.h.
(FT_TRACE1, FT_TRACE6, ft_memset, FT_MEM_ZERO): Define
conditionally.
(Render_Glyph, Render_Gray_Glyph): Return Raster_Err_None (or
Raster_Err_Unsupported).
(ft_black_new) [_STANDALONE_]: Fix type of `the_raster'.
(ft_black_init, ft_black_reset, ft_black_set_mode, ft_black_render):
Use `ras', not `raster'.
(ft_black_done): Use FT_UNUSED_RASTER.
(Horizontal_Sweep_Init, Horizontal_Sweep_Step,
Horizontal_Gray_Sweep_Span): Use FT_UNUSED_RASTER.
* docs/CHANGES: Updated.
2005-05-19 09:20:24 +02:00
|
|
|
#ifdef FT_STATIC_RASTER
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
#define RAS_ARGS /* void */
|
|
|
|
#define RAS_ARG /* void */
|
|
|
|
|
|
|
|
#define RAS_VARS /* void */
|
|
|
|
#define RAS_VAR /* void */
|
|
|
|
|
2009-01-12 21:11:14 +01:00
|
|
|
#define FT_UNUSED_RASTER do { } while ( 0 )
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
#else /* !FT_STATIC_RASTER */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
2012-02-21 09:21:19 +01:00
|
|
|
#define RAS_ARGS black_PWorker worker,
|
|
|
|
#define RAS_ARG black_PWorker worker
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2007-01-04 19:33:12 +01:00
|
|
|
#define RAS_VARS worker,
|
|
|
|
#define RAS_VAR worker
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2007-01-04 19:33:12 +01:00
|
|
|
#define FT_UNUSED_RASTER FT_UNUSED( worker )
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
#endif /* !FT_STATIC_RASTER */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
2012-02-21 09:21:19 +01:00
|
|
|
typedef struct black_TWorker_ black_TWorker, *black_PWorker;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* prototypes used for sweep function dispatch */
|
2001-06-28 01:25:46 +02:00
|
|
|
typedef void
|
|
|
|
Function_Sweep_Init( RAS_ARGS Short* min,
|
|
|
|
Short* max );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
typedef void
|
|
|
|
Function_Sweep_Span( RAS_ARGS Short y,
|
|
|
|
FT_F26Dot6 x1,
|
|
|
|
FT_F26Dot6 x2,
|
|
|
|
PProfile left,
|
|
|
|
PProfile right );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
typedef void
|
|
|
|
Function_Sweep_Step( RAS_ARG );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* NOTE: These operations are only valid on 2's complement processors */
|
2012-02-21 08:54:55 +01:00
|
|
|
#undef FLOOR
|
|
|
|
#undef CEILING
|
|
|
|
#undef TRUNC
|
|
|
|
#undef SCALED
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
#define FLOOR( x ) ( (x) & -ras.precision )
|
|
|
|
#define CEILING( x ) ( ( (x) + ras.precision - 1 ) & -ras.precision )
|
2013-05-05 10:41:20 +02:00
|
|
|
#define TRUNC( x ) ( (Long)(x) >> ras.precision_bits )
|
2000-10-26 02:30:33 +02:00
|
|
|
#define FRAC( x ) ( (x) & ( ras.precision - 1 ) )
|
2013-05-05 10:41:20 +02:00
|
|
|
#define SCALED( x ) ( ( (ULong)(x) << ras.scale_shift ) - ras.precision_half )
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2009-06-16 15:14:21 +02:00
|
|
|
#define IS_BOTTOM_OVERSHOOT( x ) ( CEILING( x ) - x >= ras.precision_half )
|
|
|
|
#define IS_TOP_OVERSHOOT( x ) ( x - FLOOR( x ) >= ras.precision_half )
|
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
/* The most used variables are positioned at the top of the structure. */
|
|
|
|
/* Thus, their offset can be coded with less opcodes, resulting in a */
|
|
|
|
/* smaller executable. */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2012-02-21 09:21:19 +01:00
|
|
|
struct black_TWorker_
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
2009-06-18 15:48:21 +02:00
|
|
|
Int precision_bits; /* precision related variables */
|
|
|
|
Int precision;
|
|
|
|
Int precision_half;
|
|
|
|
Int precision_shift;
|
|
|
|
Int precision_step;
|
|
|
|
Int precision_jitter;
|
|
|
|
|
|
|
|
Int scale_shift; /* == precision_shift for bitmaps */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* == precision_shift+1 for pixmaps */
|
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
PLong buff; /* The profiles buffer */
|
|
|
|
PLong sizeBuff; /* Render pool size */
|
|
|
|
PLong maxBuff; /* Profiles buffer size */
|
|
|
|
PLong top; /* Current cursor in buffer */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
FT_Error error;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
Int numTurns; /* number of Y-turns in outline */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
TPoint* arc; /* current Bezier arc pointer */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
UShort bWidth; /* target bitmap width */
|
|
|
|
PByte bTarget; /* target bitmap buffer */
|
|
|
|
PByte gTarget; /* target pixmap buffer */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
Long lastX, lastY;
|
|
|
|
Long minY, maxY;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
UShort num_Profs; /* current number of profiles */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
Bool fresh; /* signals a fresh new profile which */
|
2009-06-05 10:37:15 +02:00
|
|
|
/* `start' field must be completed */
|
2009-06-18 15:48:21 +02:00
|
|
|
Bool joint; /* signals that the last arc ended */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* exactly on a scanline. Allows */
|
|
|
|
/* removal of doublets */
|
2009-06-18 15:48:21 +02:00
|
|
|
PProfile cProfile; /* current profile */
|
|
|
|
PProfile fProfile; /* head of linked list of profiles */
|
|
|
|
PProfile gProfile; /* contour's first profile in case */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* of impact */
|
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
TStates state; /* rendering state */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
FT_Bitmap target; /* description of target bit/pixmap */
|
|
|
|
FT_Outline outline;
|
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
Long traceOfs; /* current offset in target bitmap */
|
|
|
|
Long traceG; /* current offset in target pixmap */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
Short traceIncr; /* sweep's increment in target bitmap */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
Short gray_min_x; /* current min x during gray rendering */
|
|
|
|
Short gray_max_x; /* current max x during gray rendering */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
/* dispatch variables */
|
|
|
|
|
|
|
|
Function_Sweep_Init* Proc_Sweep_Init;
|
|
|
|
Function_Sweep_Span* Proc_Sweep_Span;
|
|
|
|
Function_Sweep_Span* Proc_Sweep_Drop;
|
|
|
|
Function_Sweep_Step* Proc_Sweep_Step;
|
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
Byte dropOutControl; /* current drop_out control method */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
Bool second_pass; /* indicates whether a horizontal pass */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* should be performed to control */
|
|
|
|
/* drop-out accurately when calling */
|
|
|
|
/* Render_Glyph. Note that there is */
|
|
|
|
/* no horizontal pass during gray */
|
|
|
|
/* rendering. */
|
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2012-02-21 08:48:39 +01:00
|
|
|
black_TBand band_stack[16]; /* band stack used for sub-banding */
|
|
|
|
Int band_top; /* band stack top */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
#ifdef FT_RASTER_OPTION_ANTI_ALIASING
|
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
Byte* grays;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
Byte gray_lines[RASTER_GRAY_LINES];
|
2000-10-26 02:30:33 +02:00
|
|
|
/* Intermediate table used to render the */
|
|
|
|
/* graylevels pixmaps. */
|
|
|
|
/* gray_lines is a buffer holding two */
|
|
|
|
/* monochrome scanlines */
|
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
Short gray_width; /* width in bytes of one monochrome */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* intermediate scanline of gray_lines. */
|
|
|
|
/* Each gray pixel takes 2 bits long there */
|
|
|
|
|
|
|
|
/* The gray_lines must hold 2 lines, thus with size */
|
|
|
|
/* in bytes of at least `gray_width*2'. */
|
|
|
|
|
|
|
|
#endif /* FT_RASTER_ANTI_ALIASING */
|
|
|
|
|
2007-01-04 19:33:12 +01:00
|
|
|
};
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
2012-02-22 07:01:35 +01:00
|
|
|
typedef struct black_TRaster_
|
2007-01-04 19:33:12 +01:00
|
|
|
{
|
2012-02-21 09:21:19 +01:00
|
|
|
char* buffer;
|
|
|
|
long buffer_size;
|
|
|
|
void* memory;
|
|
|
|
black_PWorker worker;
|
|
|
|
Byte grays[5];
|
|
|
|
Short gray_width;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2012-02-22 07:01:35 +01:00
|
|
|
} black_TRaster, *black_PRaster;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
* src/raster/ftmisc.h: New file. Only needed if ftraster.c is
compiled as stand-alone.
* src/raster/ftraster.c: Add comment how to compile as stand-alone.
s/FT_CONFIG_OPTION_STATIC_RASTER/FT_STATIC_RASTER/.
s/TT_STATIC_RASTER/FT_STATIC_RASTER/.
[_STANDALONE_]: Include ftimage.h and ftmisc.h.
(FT_TRACE1, FT_TRACE6, ft_memset, FT_MEM_ZERO): Define
conditionally.
(Render_Glyph, Render_Gray_Glyph): Return Raster_Err_None (or
Raster_Err_Unsupported).
(ft_black_new) [_STANDALONE_]: Fix type of `the_raster'.
(ft_black_init, ft_black_reset, ft_black_set_mode, ft_black_render):
Use `ras', not `raster'.
(ft_black_done): Use FT_UNUSED_RASTER.
(Horizontal_Sweep_Init, Horizontal_Sweep_Step,
Horizontal_Gray_Sweep_Span): Use FT_UNUSED_RASTER.
* docs/CHANGES: Updated.
2005-05-19 09:20:24 +02:00
|
|
|
#ifdef FT_STATIC_RASTER
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2012-02-21 09:21:19 +01:00
|
|
|
static black_TWorker cur_ras;
|
2000-10-26 02:30:33 +02:00
|
|
|
#define ras cur_ras
|
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
#else /* !FT_STATIC_RASTER */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2007-01-04 19:33:12 +01:00
|
|
|
#define ras (*worker)
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2009-06-18 15:48:21 +02:00
|
|
|
#endif /* !FT_STATIC_RASTER */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
2007-07-28 07:40:40 +02:00
|
|
|
#ifdef FT_RASTER_OPTION_ANTI_ALIASING
|
|
|
|
|
2009-09-12 23:15:17 +02:00
|
|
|
/* A lookup table used to quickly count set bits in four gray 2x2 */
|
|
|
|
/* cells. The values of the table have been produced with the */
|
|
|
|
/* following code: */
|
|
|
|
/* */
|
|
|
|
/* for ( i = 0; i < 256; i++ ) */
|
|
|
|
/* { */
|
|
|
|
/* l = 0; */
|
|
|
|
/* j = i; */
|
|
|
|
/* */
|
|
|
|
/* for ( c = 0; c < 4; c++ ) */
|
|
|
|
/* { */
|
|
|
|
/* l <<= 4; */
|
|
|
|
/* */
|
|
|
|
/* if ( j & 0x80 ) l++; */
|
|
|
|
/* if ( j & 0x40 ) l++; */
|
|
|
|
/* */
|
|
|
|
/* j = ( j << 2 ) & 0xFF; */
|
|
|
|
/* } */
|
|
|
|
/* printf( "0x%04X", l ); */
|
|
|
|
/* } */
|
|
|
|
/* */
|
|
|
|
|
|
|
|
static const short count_table[256] =
|
2008-10-12 13:47:29 +02:00
|
|
|
{
|
2009-09-12 23:15:17 +02:00
|
|
|
0x0000, 0x0001, 0x0001, 0x0002, 0x0010, 0x0011, 0x0011, 0x0012,
|
|
|
|
0x0010, 0x0011, 0x0011, 0x0012, 0x0020, 0x0021, 0x0021, 0x0022,
|
|
|
|
0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112,
|
|
|
|
0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122,
|
|
|
|
0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112,
|
|
|
|
0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122,
|
|
|
|
0x0200, 0x0201, 0x0201, 0x0202, 0x0210, 0x0211, 0x0211, 0x0212,
|
|
|
|
0x0210, 0x0211, 0x0211, 0x0212, 0x0220, 0x0221, 0x0221, 0x0222,
|
|
|
|
0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012,
|
|
|
|
0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022,
|
|
|
|
0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
|
|
|
|
0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
|
|
|
|
0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
|
|
|
|
0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
|
|
|
|
0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212,
|
|
|
|
0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222,
|
|
|
|
0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012,
|
|
|
|
0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022,
|
|
|
|
0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
|
|
|
|
0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
|
|
|
|
0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
|
|
|
|
0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
|
|
|
|
0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212,
|
|
|
|
0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222,
|
|
|
|
0x2000, 0x2001, 0x2001, 0x2002, 0x2010, 0x2011, 0x2011, 0x2012,
|
|
|
|
0x2010, 0x2011, 0x2011, 0x2012, 0x2020, 0x2021, 0x2021, 0x2022,
|
|
|
|
0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112,
|
|
|
|
0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122,
|
|
|
|
0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112,
|
|
|
|
0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122,
|
|
|
|
0x2200, 0x2201, 0x2201, 0x2202, 0x2210, 0x2211, 0x2211, 0x2212,
|
|
|
|
0x2210, 0x2211, 0x2211, 0x2212, 0x2220, 0x2221, 0x2221, 0x2222
|
2009-06-03 08:53:47 +02:00
|
|
|
};
|
2007-01-04 19:50:12 +01:00
|
|
|
|
2007-07-28 07:40:40 +02:00
|
|
|
#endif /* FT_RASTER_OPTION_ANTI_ALIASING */
|
|
|
|
|
2007-01-04 19:50:12 +01:00
|
|
|
|
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/** **/
|
|
|
|
/** PROFILES COMPUTATION **/
|
|
|
|
/** **/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* Set_High_Precision */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
2008-10-12 13:47:29 +02:00
|
|
|
/* Set precision variables according to param flag. */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* <Input> */
|
2013-03-24 08:37:12 +01:00
|
|
|
/* High :: Set to True for high precision (typically for ppem < 24), */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* false otherwise. */
|
|
|
|
/* */
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
|
|
|
Set_High_Precision( RAS_ARGS Int High )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
2011-01-13 21:55:08 +01:00
|
|
|
/*
|
|
|
|
* `precision_step' is used in `Bezier_Up' to decide when to split a
|
|
|
|
* given y-monotonous Bezier arc that crosses a scanline before
|
|
|
|
* approximating it as a straight segment. The default value of 32 (for
|
|
|
|
* low accuracy) corresponds to
|
|
|
|
*
|
|
|
|
* 32 / 64 == 0.5 pixels ,
|
|
|
|
*
|
|
|
|
* while for the high accuracy case we have
|
|
|
|
*
|
|
|
|
* 256/ (1 << 12) = 0.0625 pixels .
|
|
|
|
*
|
|
|
|
* `precision_jitter' is an epsilon threshold used in
|
|
|
|
* `Vertical_Sweep_Span' to deal with small imperfections in the Bezier
|
|
|
|
* decomposition (after all, we are working with approximations only);
|
|
|
|
* it avoids switching on additional pixels which would cause artifacts
|
|
|
|
* otherwise.
|
|
|
|
*
|
|
|
|
* The value of `precision_jitter' has been determined heuristically.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
if ( High )
|
|
|
|
{
|
2009-06-11 17:32:31 +02:00
|
|
|
ras.precision_bits = 12;
|
|
|
|
ras.precision_step = 256;
|
2011-01-13 21:55:08 +01:00
|
|
|
ras.precision_jitter = 30;
|
2000-10-26 02:30:33 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ras.precision_bits = 6;
|
|
|
|
ras.precision_step = 32;
|
|
|
|
ras.precision_jitter = 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
FT_TRACE6(( "Set_High_Precision(%s)\n", High ? "true" : "false" ));
|
|
|
|
|
* src/sfnt/ttpost.c (load_post_names, tt_face_free_ps_names,
tt_face_get_ps_name): Replace switch statement with if clauses to
make it more portable.
* src/cff/cffobjs.c (cff_face_init): Ditto.
* include/freetype/ftmodule.h (FT_Module_Class): Use `FT_Long' for
`module_size'.
* include/freetype/ftrender.h (FT_Glyph_Class_): Use `FT_Long' for
`glyph_size'.
* src/base/ftobjs.c (FT_Render_Glyph): Change second parameter to
`FT_Render_Mode'.
(FT_Render_Glyph_Internal): Change third parameter to
`FT_Render_Mode'.
* src/base/ftglyph.c (FT_Glyph_To_Bitmap): Change second parameter
to `FT_Render_Mode'.
* src/raster/ftrend1.c (ft_raster1_render): Change third parameter
to `FT_Render_Mode'.
* src/smooth/ftsmooth.c (ft_smooth_render, ft_smooth_render_lcd,
ft_smooth_render_lcd_v): Ditto.
(ft_smooth_render_generic): Change third and fifth parameter to
`FT_Render_Mode'.
* include/freetype/freetype.h, include/freetype/internal/ftobjs.h,
include/freetype/ftglyph.h: Updated.
* src/cff/cffdrivr.c (Load_Glyph), src/pcf/pcfdriver.c
(PCF_Glyph_Load), src/pfr/pfrobjs.c (pfr_slot_load),
src/winfonts/winfnt.c (FNT_Load_Glyph), src/t42/t42objs.c
(T42_GlyphSlot_Load), src/bdf/bdfdrivr.c (BDF_Glyph_Load): Change
fourth parameter to `FT_Int32'.
* src/pfr/pfrobjs.c (pfr_face_init): Add two missing parameters
and declare them as unused.
* src/cid/cidparse.h (CID_Parser): Use FT_Long for `postscript_len'.
* src/psnames/psnames.h (PS_Unicode_Value_Func): Change return
value to FT_UInt32.
* src/psnames/psmodule.c (ps_unicode_value, ps_build_unicode_table):
Updated accordingly.
* src/cff/cffdrivr.c (Get_Kerning): Use FT_Long for `middle'.
(cff_get_glyph_name): Use cast for result of ft_strlen.
* src/cff/cffparse.c (cff_parse_real): User cast for assigning
`exp'.
* src/cff/cffload.c (cff_index_get_pointers): Use FT_ULong for
some local variables.
(cff_charset_load, cff_encoding_load): Use casts to FT_UInt for some
switch statements.
(cff_font_load): Use cast in call to CFF_Load_FD_Select.
* src/cff/cffobjs.c (cff_size_init): Use more casts.
(cff_face_init): Use FT_Int32 for `flags'.
* src/cff/cffgload.c (cff_operator_seac): Use cast for assigning
`adx' and `ady'.
(cff_decoder_parse_charstrings): Use FT_ULong for third parameter.
Use more casts.
* src/cff/cffcmap.c (cff_cmap_unicode_init): Use cast for `count'.
* src/cid/cidload.c (cid_read_subrs): Use FT_ULong for `len'.
* src/cid/cidgload.c (cid_load_glyph): Add missing cast for
`cid_get_offset'.
* src/psaux/t1decode.c (t1_decoder_parse_charstrings) <18>: Use
cast for `num_points'.
(t1_decoder_init): Use cast for assigning `decoder->num_glyphs'.
* src/base/ftdebug.c (ft_debug_init): Use FT_Int.
* include/freetype/internal/ftdriver.h (FT_Slot_LoadFunc): Use
`FT_Int32' for fourth parameter.
* src/base/ftobjs.c (open_face): Use cast for calling
clazz->init_face.
* src/raster/ftraster.c (Set_High_Precision): Use `1' instead of
`1L'.
(Finalize_Profile_Table, Line_Up, ft_black_init): Use casts.
* src/raster/ftrend1.c (ft_raster1_render): Ditto.
* src/sfnt/sfnt_dir_check: Compare `magic' with unsigned long
constant.
* builds/amiga/include/freetype/config/ftmodule.h: Updated.
2002-09-27 13:09:23 +02:00
|
|
|
ras.precision = 1 << ras.precision_bits;
|
2000-10-26 02:30:33 +02:00
|
|
|
ras.precision_half = ras.precision / 2;
|
|
|
|
ras.precision_shift = ras.precision_bits - Pixel_Bits;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* New_Profile */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
2008-10-12 13:47:29 +02:00
|
|
|
/* Create a new profile in the render pool. */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* <Input> */
|
2009-06-16 15:14:21 +02:00
|
|
|
/* aState :: The state/orientation of the new profile. */
|
|
|
|
/* */
|
|
|
|
/* overshoot :: Whether the profile's unrounded start position */
|
|
|
|
/* differs by at least a half pixel. */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* SUCCESS on success. FAILURE in case of overflow or of incoherent */
|
|
|
|
/* profile. */
|
|
|
|
/* */
|
2001-06-28 01:25:46 +02:00
|
|
|
static Bool
|
2009-06-16 15:14:21 +02:00
|
|
|
New_Profile( RAS_ARGS TStates aState,
|
|
|
|
Bool overshoot )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
if ( !ras.fProfile )
|
|
|
|
{
|
|
|
|
ras.cProfile = (PProfile)ras.top;
|
|
|
|
ras.fProfile = ras.cProfile;
|
|
|
|
ras.top += AlignProfileSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ras.top >= ras.maxBuff )
|
|
|
|
{
|
2013-03-14 10:27:35 +01:00
|
|
|
ras.error = FT_THROW( Overflow );
|
2000-10-26 02:30:33 +02:00
|
|
|
return FAILURE;
|
|
|
|
}
|
|
|
|
|
2009-06-16 15:14:21 +02:00
|
|
|
ras.cProfile->flags = 0;
|
|
|
|
ras.cProfile->start = 0;
|
|
|
|
ras.cProfile->height = 0;
|
|
|
|
ras.cProfile->offset = ras.top;
|
|
|
|
ras.cProfile->link = (PProfile)0;
|
|
|
|
ras.cProfile->next = (PProfile)0;
|
Fix B/W rasterization of subglyphs with different drop-out modes.
Normally, the SCANMODE instruction (if present) to set the drop-out
mode in a TrueType font is located in the `prep' table only and thus
valid for all glyphs. However, there are fonts like `pala.ttf'
which additionally contain this instruction in the hinting code of
some glyphs (but not all). As a result it can happen that a
composite glyph needs multiple drop-out modes for its subglyphs
since the rendering state gets reset for each subglyph.
FreeType collects the hinted outlines from all subglyphs, then it
sends the data to the rasterizer. It also sends the drop-out mode
-- after hinting has been applied -- and here is the error: It sends
the drop-out mode of the last subglyph only; drop-out modes of all
other subglyphs are lost.
This patch fixes the problem; it adds a second, alternative
mechanism to pass the drop-out mode: For each contour, the
rasterizer now checks the first `tags' array element. If bit 2 is
set, bits 5-7 contain the contour's drop-out mode, overriding the
global drop-out mode.
* include/freetype/ftimage.h (FT_CURVE_TAG_HAS_SCANMODE): New macro.
* src/truetype/ttgload.c (TT_Hint_Glyph): Store drop-out mode in
`tags[0]'.
* src/raster/ftraster.c (Flow_Up, Overshoot_Top, Overshoot_Bottom):
Use bits 3-5 instead of 0-2.
(New_Profile): Set the drop-out mode in the profile's `flags' field.
(Decompose_Curve): Check `tags[0]' and set `dropOutControl' if
necessary.
(Vertical_Sweep_Drop, Horizontal_Sweep_Drop,
Horizontal_Gray_Sweep_Drop, Draw_Sweep): Use the profile's drop-out
mode.
2009-06-18 15:42:52 +02:00
|
|
|
ras.cProfile->flags = ras.dropOutControl;
|
2009-06-16 15:14:21 +02:00
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
switch ( aState )
|
|
|
|
{
|
2002-04-30 16:26:49 +02:00
|
|
|
case Ascending_State:
|
2009-06-05 10:37:15 +02:00
|
|
|
ras.cProfile->flags |= Flow_Up;
|
2009-06-16 15:14:21 +02:00
|
|
|
if ( overshoot )
|
|
|
|
ras.cProfile->flags |= Overshoot_Bottom;
|
|
|
|
|
2010-10-24 17:14:13 +02:00
|
|
|
FT_TRACE6(( "New ascending profile = %p\n", ras.cProfile ));
|
2000-10-26 02:30:33 +02:00
|
|
|
break;
|
|
|
|
|
2002-04-30 16:26:49 +02:00
|
|
|
case Descending_State:
|
2009-06-16 15:14:21 +02:00
|
|
|
if ( overshoot )
|
|
|
|
ras.cProfile->flags |= Overshoot_Top;
|
2010-10-24 17:14:13 +02:00
|
|
|
FT_TRACE6(( "New descending profile = %p\n", ras.cProfile ));
|
2000-10-26 02:30:33 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2009-06-26 06:15:41 +02:00
|
|
|
FT_ERROR(( "New_Profile: invalid profile direction\n" ));
|
2013-03-14 10:27:35 +01:00
|
|
|
ras.error = FT_THROW( Invalid );
|
2000-10-26 02:30:33 +02:00
|
|
|
return FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !ras.gProfile )
|
|
|
|
ras.gProfile = ras.cProfile;
|
|
|
|
|
|
|
|
ras.state = aState;
|
|
|
|
ras.fresh = TRUE;
|
|
|
|
ras.joint = FALSE;
|
|
|
|
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* End_Profile */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
2008-10-12 13:47:29 +02:00
|
|
|
/* Finalize the current profile. */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
2009-06-16 15:14:21 +02:00
|
|
|
/* <Input> */
|
|
|
|
/* overshoot :: Whether the profile's unrounded end position differs */
|
|
|
|
/* by at least a half pixel. */
|
|
|
|
/* */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* <Return> */
|
|
|
|
/* SUCCESS on success. FAILURE in case of overflow or incoherency. */
|
|
|
|
/* */
|
2001-06-28 01:25:46 +02:00
|
|
|
static Bool
|
2009-06-16 15:14:21 +02:00
|
|
|
End_Profile( RAS_ARGS Bool overshoot )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
2013-06-04 10:30:48 +02:00
|
|
|
Long h;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
2001-03-10 18:07:42 +01:00
|
|
|
h = (Long)( ras.top - ras.cProfile->offset );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
if ( h < 0 )
|
|
|
|
{
|
2009-06-26 06:15:41 +02:00
|
|
|
FT_ERROR(( "End_Profile: negative height encountered\n" ));
|
2013-03-14 10:27:35 +01:00
|
|
|
ras.error = FT_THROW( Neg_Height );
|
2000-10-26 02:30:33 +02:00
|
|
|
return FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( h > 0 )
|
|
|
|
{
|
2013-06-04 10:30:48 +02:00
|
|
|
PProfile oldProfile;
|
|
|
|
|
|
|
|
|
2010-10-24 17:14:13 +02:00
|
|
|
FT_TRACE6(( "Ending profile %p, start = %ld, height = %ld\n",
|
|
|
|
ras.cProfile, ras.cProfile->start, h ));
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
ras.cProfile->height = h;
|
2009-06-16 15:14:21 +02:00
|
|
|
if ( overshoot )
|
|
|
|
{
|
|
|
|
if ( ras.cProfile->flags & Flow_Up )
|
|
|
|
ras.cProfile->flags |= Overshoot_Top;
|
|
|
|
else
|
|
|
|
ras.cProfile->flags |= Overshoot_Bottom;
|
|
|
|
}
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2009-06-16 15:14:21 +02:00
|
|
|
oldProfile = ras.cProfile;
|
|
|
|
ras.cProfile = (PProfile)ras.top;
|
|
|
|
|
|
|
|
ras.top += AlignProfileSize;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
ras.cProfile->height = 0;
|
|
|
|
ras.cProfile->offset = ras.top;
|
2009-06-16 15:14:21 +02:00
|
|
|
|
|
|
|
oldProfile->next = ras.cProfile;
|
2000-10-26 02:30:33 +02:00
|
|
|
ras.num_Profs++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ras.top >= ras.maxBuff )
|
|
|
|
{
|
|
|
|
FT_TRACE1(( "overflow in End_Profile\n" ));
|
2013-03-14 10:27:35 +01:00
|
|
|
ras.error = FT_THROW( Overflow );
|
2000-10-26 02:30:33 +02:00
|
|
|
return FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
ras.joint = FALSE;
|
|
|
|
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* Insert_Y_Turn */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
2008-10-12 13:47:29 +02:00
|
|
|
/* Insert a salient into the sorted list placed on top of the render */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* pool. */
|
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* New y scanline position. */
|
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* SUCCESS on success. FAILURE in case of overflow. */
|
|
|
|
/* */
|
2001-06-28 01:25:46 +02:00
|
|
|
static Bool
|
|
|
|
Insert_Y_Turn( RAS_ARGS Int y )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
2003-05-19 00:40:11 +02:00
|
|
|
PLong y_turns;
|
2013-06-04 10:30:48 +02:00
|
|
|
Int n;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
n = ras.numTurns - 1;
|
|
|
|
y_turns = ras.sizeBuff - ras.numTurns;
|
|
|
|
|
|
|
|
/* look for first y value that is <= */
|
|
|
|
while ( n >= 0 && y < y_turns[n] )
|
|
|
|
n--;
|
|
|
|
|
|
|
|
/* if it is <, simply insert it, ignore if == */
|
|
|
|
if ( n >= 0 && y > y_turns[n] )
|
|
|
|
while ( n >= 0 )
|
|
|
|
{
|
2013-06-04 10:30:48 +02:00
|
|
|
Int y2 = (Int)y_turns[n];
|
|
|
|
|
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
y_turns[n] = y;
|
|
|
|
y = y2;
|
|
|
|
n--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( n < 0 )
|
|
|
|
{
|
2003-05-19 00:40:11 +02:00
|
|
|
ras.maxBuff--;
|
2000-10-26 02:30:33 +02:00
|
|
|
if ( ras.maxBuff <= ras.top )
|
|
|
|
{
|
2013-03-14 10:27:35 +01:00
|
|
|
ras.error = FT_THROW( Overflow );
|
2000-10-26 02:30:33 +02:00
|
|
|
return FAILURE;
|
|
|
|
}
|
|
|
|
ras.numTurns++;
|
|
|
|
ras.sizeBuff[-ras.numTurns] = y;
|
|
|
|
}
|
|
|
|
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* Finalize_Profile_Table */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
2008-10-12 13:47:29 +02:00
|
|
|
/* Adjust all links in the profiles list. */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* SUCCESS on success. FAILURE in case of overflow. */
|
|
|
|
/* */
|
2001-06-28 01:25:46 +02:00
|
|
|
static Bool
|
|
|
|
Finalize_Profile_Table( RAS_ARG )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
UShort n;
|
|
|
|
PProfile p;
|
|
|
|
|
|
|
|
|
|
|
|
n = ras.num_Profs;
|
2009-03-12 09:07:49 +01:00
|
|
|
p = ras.fProfile;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2009-03-12 09:07:49 +01:00
|
|
|
if ( n > 1 && p )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
while ( n > 0 )
|
|
|
|
{
|
2013-06-04 10:30:48 +02:00
|
|
|
Int bottom, top;
|
|
|
|
|
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
if ( n > 1 )
|
|
|
|
p->link = (PProfile)( p->offset + p->height );
|
|
|
|
else
|
|
|
|
p->link = NULL;
|
|
|
|
|
2009-06-05 10:37:15 +02:00
|
|
|
if ( p->flags & Flow_Up )
|
|
|
|
{
|
|
|
|
bottom = (Int)p->start;
|
|
|
|
top = (Int)( p->start + p->height - 1 );
|
|
|
|
}
|
|
|
|
else
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
* src/sfnt/ttpost.c (load_post_names, tt_face_free_ps_names,
tt_face_get_ps_name): Replace switch statement with if clauses to
make it more portable.
* src/cff/cffobjs.c (cff_face_init): Ditto.
* include/freetype/ftmodule.h (FT_Module_Class): Use `FT_Long' for
`module_size'.
* include/freetype/ftrender.h (FT_Glyph_Class_): Use `FT_Long' for
`glyph_size'.
* src/base/ftobjs.c (FT_Render_Glyph): Change second parameter to
`FT_Render_Mode'.
(FT_Render_Glyph_Internal): Change third parameter to
`FT_Render_Mode'.
* src/base/ftglyph.c (FT_Glyph_To_Bitmap): Change second parameter
to `FT_Render_Mode'.
* src/raster/ftrend1.c (ft_raster1_render): Change third parameter
to `FT_Render_Mode'.
* src/smooth/ftsmooth.c (ft_smooth_render, ft_smooth_render_lcd,
ft_smooth_render_lcd_v): Ditto.
(ft_smooth_render_generic): Change third and fifth parameter to
`FT_Render_Mode'.
* include/freetype/freetype.h, include/freetype/internal/ftobjs.h,
include/freetype/ftglyph.h: Updated.
* src/cff/cffdrivr.c (Load_Glyph), src/pcf/pcfdriver.c
(PCF_Glyph_Load), src/pfr/pfrobjs.c (pfr_slot_load),
src/winfonts/winfnt.c (FNT_Load_Glyph), src/t42/t42objs.c
(T42_GlyphSlot_Load), src/bdf/bdfdrivr.c (BDF_Glyph_Load): Change
fourth parameter to `FT_Int32'.
* src/pfr/pfrobjs.c (pfr_face_init): Add two missing parameters
and declare them as unused.
* src/cid/cidparse.h (CID_Parser): Use FT_Long for `postscript_len'.
* src/psnames/psnames.h (PS_Unicode_Value_Func): Change return
value to FT_UInt32.
* src/psnames/psmodule.c (ps_unicode_value, ps_build_unicode_table):
Updated accordingly.
* src/cff/cffdrivr.c (Get_Kerning): Use FT_Long for `middle'.
(cff_get_glyph_name): Use cast for result of ft_strlen.
* src/cff/cffparse.c (cff_parse_real): User cast for assigning
`exp'.
* src/cff/cffload.c (cff_index_get_pointers): Use FT_ULong for
some local variables.
(cff_charset_load, cff_encoding_load): Use casts to FT_UInt for some
switch statements.
(cff_font_load): Use cast in call to CFF_Load_FD_Select.
* src/cff/cffobjs.c (cff_size_init): Use more casts.
(cff_face_init): Use FT_Int32 for `flags'.
* src/cff/cffgload.c (cff_operator_seac): Use cast for assigning
`adx' and `ady'.
(cff_decoder_parse_charstrings): Use FT_ULong for third parameter.
Use more casts.
* src/cff/cffcmap.c (cff_cmap_unicode_init): Use cast for `count'.
* src/cid/cidload.c (cid_read_subrs): Use FT_ULong for `len'.
* src/cid/cidgload.c (cid_load_glyph): Add missing cast for
`cid_get_offset'.
* src/psaux/t1decode.c (t1_decoder_parse_charstrings) <18>: Use
cast for `num_points'.
(t1_decoder_init): Use cast for assigning `decoder->num_glyphs'.
* src/base/ftdebug.c (ft_debug_init): Use FT_Int.
* include/freetype/internal/ftdriver.h (FT_Slot_LoadFunc): Use
`FT_Int32' for fourth parameter.
* src/base/ftobjs.c (open_face): Use cast for calling
clazz->init_face.
* src/raster/ftraster.c (Set_High_Precision): Use `1' instead of
`1L'.
(Finalize_Profile_Table, Line_Up, ft_black_init): Use casts.
* src/raster/ftrend1.c (ft_raster1_render): Ditto.
* src/sfnt/sfnt_dir_check: Compare `magic' with unsigned long
constant.
* builds/amiga/include/freetype/config/ftmodule.h: Updated.
2002-09-27 13:09:23 +02:00
|
|
|
bottom = (Int)( p->start - p->height + 1 );
|
|
|
|
top = (Int)p->start;
|
2000-10-26 02:30:33 +02:00
|
|
|
p->start = bottom;
|
|
|
|
p->offset += p->height - 1;
|
|
|
|
}
|
|
|
|
|
2009-06-05 10:37:15 +02:00
|
|
|
if ( Insert_Y_Turn( RAS_VARS bottom ) ||
|
|
|
|
Insert_Y_Turn( RAS_VARS top + 1 ) )
|
2000-10-26 02:30:33 +02:00
|
|
|
return FAILURE;
|
|
|
|
|
|
|
|
p = p->link;
|
|
|
|
n--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ras.fProfile = NULL;
|
|
|
|
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* Split_Conic */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
2008-10-12 13:47:29 +02:00
|
|
|
/* Subdivide one conic Bezier into two joint sub-arcs in the Bezier */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* stack. */
|
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* None (subdivided Bezier is taken from the top of the stack). */
|
|
|
|
/* */
|
|
|
|
/* <Note> */
|
|
|
|
/* This routine is the `beef' of this component. It is _the_ inner */
|
|
|
|
/* loop that should be optimized to hell to get the best performance. */
|
|
|
|
/* */
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
|
|
|
Split_Conic( TPoint* base )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
Long a, b;
|
|
|
|
|
|
|
|
|
|
|
|
base[4].x = base[2].x;
|
|
|
|
b = base[1].x;
|
|
|
|
a = base[3].x = ( base[2].x + b ) / 2;
|
|
|
|
b = base[1].x = ( base[0].x + b ) / 2;
|
|
|
|
base[2].x = ( a + b ) / 2;
|
|
|
|
|
|
|
|
base[4].y = base[2].y;
|
|
|
|
b = base[1].y;
|
|
|
|
a = base[3].y = ( base[2].y + b ) / 2;
|
|
|
|
b = base[1].y = ( base[0].y + b ) / 2;
|
|
|
|
base[2].y = ( a + b ) / 2;
|
|
|
|
|
|
|
|
/* hand optimized. gcc doesn't seem to be too good at common */
|
|
|
|
/* expression substitution and instruction scheduling ;-) */
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* Split_Cubic */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
2008-10-12 13:47:29 +02:00
|
|
|
/* Subdivide a third-order Bezier arc into two joint sub-arcs in the */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* Bezier stack. */
|
|
|
|
/* */
|
|
|
|
/* <Note> */
|
|
|
|
/* This routine is the `beef' of the component. It is one of _the_ */
|
|
|
|
/* inner loops that should be optimized like hell to get the best */
|
|
|
|
/* performance. */
|
|
|
|
/* */
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
|
|
|
Split_Cubic( TPoint* base )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
Long a, b, c, d;
|
|
|
|
|
|
|
|
|
|
|
|
base[6].x = base[3].x;
|
|
|
|
c = base[1].x;
|
|
|
|
d = base[2].x;
|
|
|
|
base[1].x = a = ( base[0].x + c + 1 ) >> 1;
|
|
|
|
base[5].x = b = ( base[3].x + d + 1 ) >> 1;
|
|
|
|
c = ( c + d + 1 ) >> 1;
|
|
|
|
base[2].x = a = ( a + c + 1 ) >> 1;
|
|
|
|
base[4].x = b = ( b + c + 1 ) >> 1;
|
|
|
|
base[3].x = ( a + b + 1 ) >> 1;
|
|
|
|
|
|
|
|
base[6].y = base[3].y;
|
|
|
|
c = base[1].y;
|
|
|
|
d = base[2].y;
|
|
|
|
base[1].y = a = ( base[0].y + c + 1 ) >> 1;
|
|
|
|
base[5].y = b = ( base[3].y + d + 1 ) >> 1;
|
|
|
|
c = ( c + d + 1 ) >> 1;
|
|
|
|
base[2].y = a = ( a + c + 1 ) >> 1;
|
|
|
|
base[4].y = b = ( b + c + 1 ) >> 1;
|
|
|
|
base[3].y = ( a + b + 1 ) >> 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* Line_Up */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
2008-10-12 13:47:29 +02:00
|
|
|
/* Compute the x-coordinates of an ascending line segment and store */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* them in the render pool. */
|
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* x1 :: The x-coordinate of the segment's start point. */
|
|
|
|
/* */
|
|
|
|
/* y1 :: The y-coordinate of the segment's start point. */
|
|
|
|
/* */
|
|
|
|
/* x2 :: The x-coordinate of the segment's end point. */
|
|
|
|
/* */
|
|
|
|
/* y2 :: The y-coordinate of the segment's end point. */
|
|
|
|
/* */
|
|
|
|
/* miny :: A lower vertical clipping bound value. */
|
|
|
|
/* */
|
|
|
|
/* maxy :: An upper vertical clipping bound value. */
|
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* SUCCESS on success, FAILURE on render pool overflow. */
|
|
|
|
/* */
|
2001-06-28 01:25:46 +02:00
|
|
|
static Bool
|
|
|
|
Line_Up( RAS_ARGS Long x1,
|
|
|
|
Long y1,
|
|
|
|
Long x2,
|
|
|
|
Long y2,
|
|
|
|
Long miny,
|
|
|
|
Long maxy )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
Long Dx, Dy;
|
|
|
|
Int e1, e2, f1, f2, size; /* XXX: is `Short' sufficient? */
|
|
|
|
Long Ix, Rx, Ax;
|
|
|
|
|
|
|
|
PLong top;
|
|
|
|
|
|
|
|
|
|
|
|
Dx = x2 - x1;
|
|
|
|
Dy = y2 - y1;
|
|
|
|
|
|
|
|
if ( Dy <= 0 || y2 < miny || y1 > maxy )
|
|
|
|
return SUCCESS;
|
|
|
|
|
|
|
|
if ( y1 < miny )
|
|
|
|
{
|
|
|
|
/* Take care: miny-y1 can be a very large value; we use */
|
|
|
|
/* a slow MulDiv function to avoid clipping bugs */
|
|
|
|
x1 += SMulDiv( Dx, miny - y1, Dy );
|
* include/freetype/internal/ftdriver.h,
include/freetype/internal/ftobjs.h,
include/freetype/internal/psaux.h, src/cid/cidgload.c,
src/psaux/psobjs.c, src/psaux/t1decode.c, src/psaux/psobjs.h,
src/pshinter/pshrec.c, src/pshinter/pshalgo.c,
src/psnames/psmodule.c, src/raster/ftraster.c, src/sfnt/sfobjs.c,
src/smooth/ftgrays.c, src/smooth/ftsmooth.c, src/truetype/ttobjs.c,
src/truetype/ttdriver.c, src/truetype/ttgload.c, src/type1/t1afm.c,
src/type1/t1gload.c, src/type1/t1gload.h, src/type1/t1load.c,
src/type1/t1objs.c, src/type42/t42parse.c, src/type42/t42parse.h:
Many casts and slight argument type changes to make it work with
a 16bit compiler.
2003-06-05 06:31:05 +02:00
|
|
|
e1 = (Int)TRUNC( miny );
|
2000-10-26 02:30:33 +02:00
|
|
|
f1 = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
* src/sfnt/ttpost.c (load_post_names, tt_face_free_ps_names,
tt_face_get_ps_name): Replace switch statement with if clauses to
make it more portable.
* src/cff/cffobjs.c (cff_face_init): Ditto.
* include/freetype/ftmodule.h (FT_Module_Class): Use `FT_Long' for
`module_size'.
* include/freetype/ftrender.h (FT_Glyph_Class_): Use `FT_Long' for
`glyph_size'.
* src/base/ftobjs.c (FT_Render_Glyph): Change second parameter to
`FT_Render_Mode'.
(FT_Render_Glyph_Internal): Change third parameter to
`FT_Render_Mode'.
* src/base/ftglyph.c (FT_Glyph_To_Bitmap): Change second parameter
to `FT_Render_Mode'.
* src/raster/ftrend1.c (ft_raster1_render): Change third parameter
to `FT_Render_Mode'.
* src/smooth/ftsmooth.c (ft_smooth_render, ft_smooth_render_lcd,
ft_smooth_render_lcd_v): Ditto.
(ft_smooth_render_generic): Change third and fifth parameter to
`FT_Render_Mode'.
* include/freetype/freetype.h, include/freetype/internal/ftobjs.h,
include/freetype/ftglyph.h: Updated.
* src/cff/cffdrivr.c (Load_Glyph), src/pcf/pcfdriver.c
(PCF_Glyph_Load), src/pfr/pfrobjs.c (pfr_slot_load),
src/winfonts/winfnt.c (FNT_Load_Glyph), src/t42/t42objs.c
(T42_GlyphSlot_Load), src/bdf/bdfdrivr.c (BDF_Glyph_Load): Change
fourth parameter to `FT_Int32'.
* src/pfr/pfrobjs.c (pfr_face_init): Add two missing parameters
and declare them as unused.
* src/cid/cidparse.h (CID_Parser): Use FT_Long for `postscript_len'.
* src/psnames/psnames.h (PS_Unicode_Value_Func): Change return
value to FT_UInt32.
* src/psnames/psmodule.c (ps_unicode_value, ps_build_unicode_table):
Updated accordingly.
* src/cff/cffdrivr.c (Get_Kerning): Use FT_Long for `middle'.
(cff_get_glyph_name): Use cast for result of ft_strlen.
* src/cff/cffparse.c (cff_parse_real): User cast for assigning
`exp'.
* src/cff/cffload.c (cff_index_get_pointers): Use FT_ULong for
some local variables.
(cff_charset_load, cff_encoding_load): Use casts to FT_UInt for some
switch statements.
(cff_font_load): Use cast in call to CFF_Load_FD_Select.
* src/cff/cffobjs.c (cff_size_init): Use more casts.
(cff_face_init): Use FT_Int32 for `flags'.
* src/cff/cffgload.c (cff_operator_seac): Use cast for assigning
`adx' and `ady'.
(cff_decoder_parse_charstrings): Use FT_ULong for third parameter.
Use more casts.
* src/cff/cffcmap.c (cff_cmap_unicode_init): Use cast for `count'.
* src/cid/cidload.c (cid_read_subrs): Use FT_ULong for `len'.
* src/cid/cidgload.c (cid_load_glyph): Add missing cast for
`cid_get_offset'.
* src/psaux/t1decode.c (t1_decoder_parse_charstrings) <18>: Use
cast for `num_points'.
(t1_decoder_init): Use cast for assigning `decoder->num_glyphs'.
* src/base/ftdebug.c (ft_debug_init): Use FT_Int.
* include/freetype/internal/ftdriver.h (FT_Slot_LoadFunc): Use
`FT_Int32' for fourth parameter.
* src/base/ftobjs.c (open_face): Use cast for calling
clazz->init_face.
* src/raster/ftraster.c (Set_High_Precision): Use `1' instead of
`1L'.
(Finalize_Profile_Table, Line_Up, ft_black_init): Use casts.
* src/raster/ftrend1.c (ft_raster1_render): Ditto.
* src/sfnt/sfnt_dir_check: Compare `magic' with unsigned long
constant.
* builds/amiga/include/freetype/config/ftmodule.h: Updated.
2002-09-27 13:09:23 +02:00
|
|
|
e1 = (Int)TRUNC( y1 );
|
|
|
|
f1 = (Int)FRAC( y1 );
|
2000-10-26 02:30:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( y2 > maxy )
|
|
|
|
{
|
|
|
|
/* x2 += FMulDiv( Dx, maxy - y2, Dy ); UNNECESSARY */
|
* src/sfnt/ttpost.c (load_post_names, tt_face_free_ps_names,
tt_face_get_ps_name): Replace switch statement with if clauses to
make it more portable.
* src/cff/cffobjs.c (cff_face_init): Ditto.
* include/freetype/ftmodule.h (FT_Module_Class): Use `FT_Long' for
`module_size'.
* include/freetype/ftrender.h (FT_Glyph_Class_): Use `FT_Long' for
`glyph_size'.
* src/base/ftobjs.c (FT_Render_Glyph): Change second parameter to
`FT_Render_Mode'.
(FT_Render_Glyph_Internal): Change third parameter to
`FT_Render_Mode'.
* src/base/ftglyph.c (FT_Glyph_To_Bitmap): Change second parameter
to `FT_Render_Mode'.
* src/raster/ftrend1.c (ft_raster1_render): Change third parameter
to `FT_Render_Mode'.
* src/smooth/ftsmooth.c (ft_smooth_render, ft_smooth_render_lcd,
ft_smooth_render_lcd_v): Ditto.
(ft_smooth_render_generic): Change third and fifth parameter to
`FT_Render_Mode'.
* include/freetype/freetype.h, include/freetype/internal/ftobjs.h,
include/freetype/ftglyph.h: Updated.
* src/cff/cffdrivr.c (Load_Glyph), src/pcf/pcfdriver.c
(PCF_Glyph_Load), src/pfr/pfrobjs.c (pfr_slot_load),
src/winfonts/winfnt.c (FNT_Load_Glyph), src/t42/t42objs.c
(T42_GlyphSlot_Load), src/bdf/bdfdrivr.c (BDF_Glyph_Load): Change
fourth parameter to `FT_Int32'.
* src/pfr/pfrobjs.c (pfr_face_init): Add two missing parameters
and declare them as unused.
* src/cid/cidparse.h (CID_Parser): Use FT_Long for `postscript_len'.
* src/psnames/psnames.h (PS_Unicode_Value_Func): Change return
value to FT_UInt32.
* src/psnames/psmodule.c (ps_unicode_value, ps_build_unicode_table):
Updated accordingly.
* src/cff/cffdrivr.c (Get_Kerning): Use FT_Long for `middle'.
(cff_get_glyph_name): Use cast for result of ft_strlen.
* src/cff/cffparse.c (cff_parse_real): User cast for assigning
`exp'.
* src/cff/cffload.c (cff_index_get_pointers): Use FT_ULong for
some local variables.
(cff_charset_load, cff_encoding_load): Use casts to FT_UInt for some
switch statements.
(cff_font_load): Use cast in call to CFF_Load_FD_Select.
* src/cff/cffobjs.c (cff_size_init): Use more casts.
(cff_face_init): Use FT_Int32 for `flags'.
* src/cff/cffgload.c (cff_operator_seac): Use cast for assigning
`adx' and `ady'.
(cff_decoder_parse_charstrings): Use FT_ULong for third parameter.
Use more casts.
* src/cff/cffcmap.c (cff_cmap_unicode_init): Use cast for `count'.
* src/cid/cidload.c (cid_read_subrs): Use FT_ULong for `len'.
* src/cid/cidgload.c (cid_load_glyph): Add missing cast for
`cid_get_offset'.
* src/psaux/t1decode.c (t1_decoder_parse_charstrings) <18>: Use
cast for `num_points'.
(t1_decoder_init): Use cast for assigning `decoder->num_glyphs'.
* src/base/ftdebug.c (ft_debug_init): Use FT_Int.
* include/freetype/internal/ftdriver.h (FT_Slot_LoadFunc): Use
`FT_Int32' for fourth parameter.
* src/base/ftobjs.c (open_face): Use cast for calling
clazz->init_face.
* src/raster/ftraster.c (Set_High_Precision): Use `1' instead of
`1L'.
(Finalize_Profile_Table, Line_Up, ft_black_init): Use casts.
* src/raster/ftrend1.c (ft_raster1_render): Ditto.
* src/sfnt/sfnt_dir_check: Compare `magic' with unsigned long
constant.
* builds/amiga/include/freetype/config/ftmodule.h: Updated.
2002-09-27 13:09:23 +02:00
|
|
|
e2 = (Int)TRUNC( maxy );
|
2000-10-26 02:30:33 +02:00
|
|
|
f2 = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
* src/sfnt/ttpost.c (load_post_names, tt_face_free_ps_names,
tt_face_get_ps_name): Replace switch statement with if clauses to
make it more portable.
* src/cff/cffobjs.c (cff_face_init): Ditto.
* include/freetype/ftmodule.h (FT_Module_Class): Use `FT_Long' for
`module_size'.
* include/freetype/ftrender.h (FT_Glyph_Class_): Use `FT_Long' for
`glyph_size'.
* src/base/ftobjs.c (FT_Render_Glyph): Change second parameter to
`FT_Render_Mode'.
(FT_Render_Glyph_Internal): Change third parameter to
`FT_Render_Mode'.
* src/base/ftglyph.c (FT_Glyph_To_Bitmap): Change second parameter
to `FT_Render_Mode'.
* src/raster/ftrend1.c (ft_raster1_render): Change third parameter
to `FT_Render_Mode'.
* src/smooth/ftsmooth.c (ft_smooth_render, ft_smooth_render_lcd,
ft_smooth_render_lcd_v): Ditto.
(ft_smooth_render_generic): Change third and fifth parameter to
`FT_Render_Mode'.
* include/freetype/freetype.h, include/freetype/internal/ftobjs.h,
include/freetype/ftglyph.h: Updated.
* src/cff/cffdrivr.c (Load_Glyph), src/pcf/pcfdriver.c
(PCF_Glyph_Load), src/pfr/pfrobjs.c (pfr_slot_load),
src/winfonts/winfnt.c (FNT_Load_Glyph), src/t42/t42objs.c
(T42_GlyphSlot_Load), src/bdf/bdfdrivr.c (BDF_Glyph_Load): Change
fourth parameter to `FT_Int32'.
* src/pfr/pfrobjs.c (pfr_face_init): Add two missing parameters
and declare them as unused.
* src/cid/cidparse.h (CID_Parser): Use FT_Long for `postscript_len'.
* src/psnames/psnames.h (PS_Unicode_Value_Func): Change return
value to FT_UInt32.
* src/psnames/psmodule.c (ps_unicode_value, ps_build_unicode_table):
Updated accordingly.
* src/cff/cffdrivr.c (Get_Kerning): Use FT_Long for `middle'.
(cff_get_glyph_name): Use cast for result of ft_strlen.
* src/cff/cffparse.c (cff_parse_real): User cast for assigning
`exp'.
* src/cff/cffload.c (cff_index_get_pointers): Use FT_ULong for
some local variables.
(cff_charset_load, cff_encoding_load): Use casts to FT_UInt for some
switch statements.
(cff_font_load): Use cast in call to CFF_Load_FD_Select.
* src/cff/cffobjs.c (cff_size_init): Use more casts.
(cff_face_init): Use FT_Int32 for `flags'.
* src/cff/cffgload.c (cff_operator_seac): Use cast for assigning
`adx' and `ady'.
(cff_decoder_parse_charstrings): Use FT_ULong for third parameter.
Use more casts.
* src/cff/cffcmap.c (cff_cmap_unicode_init): Use cast for `count'.
* src/cid/cidload.c (cid_read_subrs): Use FT_ULong for `len'.
* src/cid/cidgload.c (cid_load_glyph): Add missing cast for
`cid_get_offset'.
* src/psaux/t1decode.c (t1_decoder_parse_charstrings) <18>: Use
cast for `num_points'.
(t1_decoder_init): Use cast for assigning `decoder->num_glyphs'.
* src/base/ftdebug.c (ft_debug_init): Use FT_Int.
* include/freetype/internal/ftdriver.h (FT_Slot_LoadFunc): Use
`FT_Int32' for fourth parameter.
* src/base/ftobjs.c (open_face): Use cast for calling
clazz->init_face.
* src/raster/ftraster.c (Set_High_Precision): Use `1' instead of
`1L'.
(Finalize_Profile_Table, Line_Up, ft_black_init): Use casts.
* src/raster/ftrend1.c (ft_raster1_render): Ditto.
* src/sfnt/sfnt_dir_check: Compare `magic' with unsigned long
constant.
* builds/amiga/include/freetype/config/ftmodule.h: Updated.
2002-09-27 13:09:23 +02:00
|
|
|
e2 = (Int)TRUNC( y2 );
|
|
|
|
f2 = (Int)FRAC( y2 );
|
2000-10-26 02:30:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( f1 > 0 )
|
|
|
|
{
|
|
|
|
if ( e1 == e2 )
|
|
|
|
return SUCCESS;
|
|
|
|
else
|
|
|
|
{
|
2010-10-28 08:33:28 +02:00
|
|
|
x1 += SMulDiv( Dx, ras.precision - f1, Dy );
|
2000-10-26 02:30:33 +02:00
|
|
|
e1 += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if ( ras.joint )
|
|
|
|
{
|
|
|
|
ras.top--;
|
|
|
|
ras.joint = FALSE;
|
|
|
|
}
|
|
|
|
|
2001-06-19 10:28:24 +02:00
|
|
|
ras.joint = (char)( f2 == 0 );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
if ( ras.fresh )
|
|
|
|
{
|
|
|
|
ras.cProfile->start = e1;
|
|
|
|
ras.fresh = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
size = e2 - e1 + 1;
|
|
|
|
if ( ras.top + size >= ras.maxBuff )
|
|
|
|
{
|
2013-03-14 10:27:35 +01:00
|
|
|
ras.error = FT_THROW( Overflow );
|
2000-10-26 02:30:33 +02:00
|
|
|
return FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( Dx > 0 )
|
|
|
|
{
|
2012-06-06 13:24:04 +02:00
|
|
|
Ix = SMulDiv_No_Round( ras.precision, Dx, Dy );
|
2000-10-26 02:30:33 +02:00
|
|
|
Rx = ( ras.precision * Dx ) % Dy;
|
|
|
|
Dx = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-06-06 13:24:04 +02:00
|
|
|
Ix = -SMulDiv_No_Round( ras.precision, -Dx, Dy );
|
|
|
|
Rx = ( ras.precision * -Dx ) % Dy;
|
2000-10-26 02:30:33 +02:00
|
|
|
Dx = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ax = -Dy;
|
|
|
|
top = ras.top;
|
|
|
|
|
|
|
|
while ( size > 0 )
|
|
|
|
{
|
|
|
|
*top++ = x1;
|
|
|
|
|
|
|
|
x1 += Ix;
|
|
|
|
Ax += Rx;
|
|
|
|
if ( Ax >= 0 )
|
|
|
|
{
|
|
|
|
Ax -= Dy;
|
|
|
|
x1 += Dx;
|
|
|
|
}
|
|
|
|
size--;
|
|
|
|
}
|
|
|
|
|
|
|
|
ras.top = top;
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* Line_Down */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
2008-10-12 13:47:29 +02:00
|
|
|
/* Compute the x-coordinates of an descending line segment and store */
|
|
|
|
/* them in the render pool. */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* x1 :: The x-coordinate of the segment's start point. */
|
|
|
|
/* */
|
|
|
|
/* y1 :: The y-coordinate of the segment's start point. */
|
|
|
|
/* */
|
|
|
|
/* x2 :: The x-coordinate of the segment's end point. */
|
|
|
|
/* */
|
|
|
|
/* y2 :: The y-coordinate of the segment's end point. */
|
|
|
|
/* */
|
|
|
|
/* miny :: A lower vertical clipping bound value. */
|
|
|
|
/* */
|
|
|
|
/* maxy :: An upper vertical clipping bound value. */
|
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* SUCCESS on success, FAILURE on render pool overflow. */
|
|
|
|
/* */
|
2001-06-28 01:25:46 +02:00
|
|
|
static Bool
|
|
|
|
Line_Down( RAS_ARGS Long x1,
|
|
|
|
Long y1,
|
|
|
|
Long x2,
|
|
|
|
Long y2,
|
|
|
|
Long miny,
|
|
|
|
Long maxy )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
Bool result, fresh;
|
|
|
|
|
|
|
|
|
|
|
|
fresh = ras.fresh;
|
|
|
|
|
|
|
|
result = Line_Up( RAS_VARS x1, -y1, x2, -y2, -maxy, -miny );
|
|
|
|
|
|
|
|
if ( fresh && !ras.fresh )
|
|
|
|
ras.cProfile->start = -ras.cProfile->start;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* A function type describing the functions used to split Bezier arcs */
|
|
|
|
typedef void (*TSplitter)( TPoint* base );
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* Bezier_Up */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
2008-10-12 13:47:29 +02:00
|
|
|
/* Compute the x-coordinates of an ascending Bezier arc and store */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* them in the render pool. */
|
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* degree :: The degree of the Bezier arc (either 2 or 3). */
|
|
|
|
/* */
|
|
|
|
/* splitter :: The function to split Bezier arcs. */
|
|
|
|
/* */
|
|
|
|
/* miny :: A lower vertical clipping bound value. */
|
|
|
|
/* */
|
|
|
|
/* maxy :: An upper vertical clipping bound value. */
|
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* SUCCESS on success, FAILURE on render pool overflow. */
|
|
|
|
/* */
|
2001-06-28 01:25:46 +02:00
|
|
|
static Bool
|
|
|
|
Bezier_Up( RAS_ARGS Int degree,
|
|
|
|
TSplitter splitter,
|
|
|
|
Long miny,
|
|
|
|
Long maxy )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
Long y1, y2, e, e2, e0;
|
|
|
|
Short f1;
|
|
|
|
|
|
|
|
TPoint* arc;
|
|
|
|
TPoint* start_arc;
|
|
|
|
|
|
|
|
PLong top;
|
|
|
|
|
|
|
|
|
|
|
|
arc = ras.arc;
|
|
|
|
y1 = arc[degree].y;
|
|
|
|
y2 = arc[0].y;
|
|
|
|
top = ras.top;
|
|
|
|
|
|
|
|
if ( y2 < miny || y1 > maxy )
|
|
|
|
goto Fin;
|
|
|
|
|
|
|
|
e2 = FLOOR( y2 );
|
|
|
|
|
|
|
|
if ( e2 > maxy )
|
|
|
|
e2 = maxy;
|
|
|
|
|
|
|
|
e0 = miny;
|
|
|
|
|
|
|
|
if ( y1 < miny )
|
|
|
|
e = miny;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
e = CEILING( y1 );
|
2001-03-10 18:07:42 +01:00
|
|
|
f1 = (Short)( FRAC( y1 ) );
|
2000-10-26 02:30:33 +02:00
|
|
|
e0 = e;
|
|
|
|
|
|
|
|
if ( f1 == 0 )
|
|
|
|
{
|
|
|
|
if ( ras.joint )
|
|
|
|
{
|
|
|
|
top--;
|
|
|
|
ras.joint = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
*top++ = arc[degree].x;
|
|
|
|
|
|
|
|
e += ras.precision;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ras.fresh )
|
|
|
|
{
|
|
|
|
ras.cProfile->start = TRUNC( e0 );
|
|
|
|
ras.fresh = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( e2 < e )
|
|
|
|
goto Fin;
|
|
|
|
|
|
|
|
if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff )
|
|
|
|
{
|
|
|
|
ras.top = top;
|
2013-03-14 10:27:35 +01:00
|
|
|
ras.error = FT_THROW( Overflow );
|
2000-10-26 02:30:33 +02:00
|
|
|
return FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
start_arc = arc;
|
|
|
|
|
|
|
|
while ( arc >= start_arc && e <= e2 )
|
|
|
|
{
|
|
|
|
ras.joint = FALSE;
|
|
|
|
|
|
|
|
y2 = arc[0].y;
|
|
|
|
|
|
|
|
if ( y2 > e )
|
|
|
|
{
|
|
|
|
y1 = arc[degree].y;
|
|
|
|
if ( y2 - y1 >= ras.precision_step )
|
|
|
|
{
|
|
|
|
splitter( arc );
|
|
|
|
arc += degree;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-06-03 08:53:47 +02:00
|
|
|
*top++ = arc[degree].x + FMulDiv( arc[0].x - arc[degree].x,
|
2000-10-26 02:30:33 +02:00
|
|
|
e - y1, y2 - y1 );
|
|
|
|
arc -= degree;
|
|
|
|
e += ras.precision;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( y2 == e )
|
|
|
|
{
|
|
|
|
ras.joint = TRUE;
|
|
|
|
*top++ = arc[0].x;
|
|
|
|
|
|
|
|
e += ras.precision;
|
|
|
|
}
|
|
|
|
arc -= degree;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Fin:
|
|
|
|
ras.top = top;
|
|
|
|
ras.arc -= degree;
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* Bezier_Down */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
2008-10-12 13:47:29 +02:00
|
|
|
/* Compute the x-coordinates of an descending Bezier arc and store */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* them in the render pool. */
|
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* degree :: The degree of the Bezier arc (either 2 or 3). */
|
|
|
|
/* */
|
|
|
|
/* splitter :: The function to split Bezier arcs. */
|
|
|
|
/* */
|
|
|
|
/* miny :: A lower vertical clipping bound value. */
|
|
|
|
/* */
|
|
|
|
/* maxy :: An upper vertical clipping bound value. */
|
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* SUCCESS on success, FAILURE on render pool overflow. */
|
|
|
|
/* */
|
2001-06-28 01:25:46 +02:00
|
|
|
static Bool
|
|
|
|
Bezier_Down( RAS_ARGS Int degree,
|
|
|
|
TSplitter splitter,
|
|
|
|
Long miny,
|
|
|
|
Long maxy )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
TPoint* arc = ras.arc;
|
|
|
|
Bool result, fresh;
|
|
|
|
|
|
|
|
|
|
|
|
arc[0].y = -arc[0].y;
|
|
|
|
arc[1].y = -arc[1].y;
|
|
|
|
arc[2].y = -arc[2].y;
|
|
|
|
if ( degree > 2 )
|
|
|
|
arc[3].y = -arc[3].y;
|
|
|
|
|
|
|
|
fresh = ras.fresh;
|
|
|
|
|
|
|
|
result = Bezier_Up( RAS_VARS degree, splitter, -maxy, -miny );
|
|
|
|
|
|
|
|
if ( fresh && !ras.fresh )
|
|
|
|
ras.cProfile->start = -ras.cProfile->start;
|
|
|
|
|
|
|
|
arc[0].y = -arc[0].y;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* Line_To */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
2008-10-12 13:47:29 +02:00
|
|
|
/* Inject a new line segment and adjust the Profiles list. */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* x :: The x-coordinate of the segment's end point (its start point */
|
* builds/win32/visualc/freetype.vcproj: Updated.
Exclude debug info for `Release' versions to reduce library size.
* src/base/ftobjs.c (FT_Open_Face): Make it work as documented, this
is, ignore `aface' completely if face_index < 0. Reported by David
Osborn <spam@habitualhiatus.com>.
* include/freetype/ftimage.h (FT_Outline_MoveToFunc,
FT_Outline_LineTo_Func, FT_Outline_ConicToFunc,
FT_Outline_CubicToFunc), src/smooth/ftgrays.c (gray_render_conic,
gray_render_cubic, gray_move_to, gray_line_to, gray_conic_to,
gray_cubic_to, gray_render_span, gray_sweep): Decorate parameters
with `const' where appropriate.
2005-05-17 22:35:23 +02:00
|
|
|
/* is stored in `lastX'). */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* y :: The y-coordinate of the segment's end point (its start point */
|
* builds/win32/visualc/freetype.vcproj: Updated.
Exclude debug info for `Release' versions to reduce library size.
* src/base/ftobjs.c (FT_Open_Face): Make it work as documented, this
is, ignore `aface' completely if face_index < 0. Reported by David
Osborn <spam@habitualhiatus.com>.
* include/freetype/ftimage.h (FT_Outline_MoveToFunc,
FT_Outline_LineTo_Func, FT_Outline_ConicToFunc,
FT_Outline_CubicToFunc), src/smooth/ftgrays.c (gray_render_conic,
gray_render_cubic, gray_move_to, gray_line_to, gray_conic_to,
gray_cubic_to, gray_render_span, gray_sweep): Decorate parameters
with `const' where appropriate.
2005-05-17 22:35:23 +02:00
|
|
|
/* is stored in `lastY'). */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* SUCCESS on success, FAILURE on render pool overflow or incorrect */
|
|
|
|
/* profile. */
|
|
|
|
/* */
|
2001-06-28 01:25:46 +02:00
|
|
|
static Bool
|
|
|
|
Line_To( RAS_ARGS Long x,
|
|
|
|
Long y )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
/* First, detect a change of direction */
|
|
|
|
|
|
|
|
switch ( ras.state )
|
|
|
|
{
|
2002-04-30 16:26:49 +02:00
|
|
|
case Unknown_State:
|
2000-10-26 02:30:33 +02:00
|
|
|
if ( y > ras.lastY )
|
|
|
|
{
|
2009-06-16 15:14:21 +02:00
|
|
|
if ( New_Profile( RAS_VARS Ascending_State,
|
|
|
|
IS_BOTTOM_OVERSHOOT( ras.lastY ) ) )
|
2000-10-26 02:30:33 +02:00
|
|
|
return FAILURE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( y < ras.lastY )
|
2009-06-16 15:14:21 +02:00
|
|
|
if ( New_Profile( RAS_VARS Descending_State,
|
|
|
|
IS_TOP_OVERSHOOT( ras.lastY ) ) )
|
2000-10-26 02:30:33 +02:00
|
|
|
return FAILURE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2002-04-30 16:26:49 +02:00
|
|
|
case Ascending_State:
|
2000-10-26 02:30:33 +02:00
|
|
|
if ( y < ras.lastY )
|
|
|
|
{
|
2009-06-16 15:14:21 +02:00
|
|
|
if ( End_Profile( RAS_VARS IS_TOP_OVERSHOOT( ras.lastY ) ) ||
|
|
|
|
New_Profile( RAS_VARS Descending_State,
|
|
|
|
IS_TOP_OVERSHOOT( ras.lastY ) ) )
|
2000-10-26 02:30:33 +02:00
|
|
|
return FAILURE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2002-04-30 16:26:49 +02:00
|
|
|
case Descending_State:
|
2000-10-26 02:30:33 +02:00
|
|
|
if ( y > ras.lastY )
|
|
|
|
{
|
2009-06-16 15:14:21 +02:00
|
|
|
if ( End_Profile( RAS_VARS IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ||
|
|
|
|
New_Profile( RAS_VARS Ascending_State,
|
|
|
|
IS_BOTTOM_OVERSHOOT( ras.lastY ) ) )
|
2000-10-26 02:30:33 +02:00
|
|
|
return FAILURE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Then compute the lines */
|
|
|
|
|
|
|
|
switch ( ras.state )
|
|
|
|
{
|
2002-04-30 16:26:49 +02:00
|
|
|
case Ascending_State:
|
2000-10-26 02:30:33 +02:00
|
|
|
if ( Line_Up( RAS_VARS ras.lastX, ras.lastY,
|
2009-06-16 15:14:21 +02:00
|
|
|
x, y, ras.minY, ras.maxY ) )
|
2000-10-26 02:30:33 +02:00
|
|
|
return FAILURE;
|
|
|
|
break;
|
|
|
|
|
2002-04-30 16:26:49 +02:00
|
|
|
case Descending_State:
|
2000-10-26 02:30:33 +02:00
|
|
|
if ( Line_Down( RAS_VARS ras.lastX, ras.lastY,
|
2009-06-16 15:14:21 +02:00
|
|
|
x, y, ras.minY, ras.maxY ) )
|
2000-10-26 02:30:33 +02:00
|
|
|
return FAILURE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
ras.lastX = x;
|
|
|
|
ras.lastY = y;
|
|
|
|
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* Conic_To */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
2008-10-12 13:47:29 +02:00
|
|
|
/* Inject a new conic arc and adjust the profile list. */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* cx :: The x-coordinate of the arc's new control point. */
|
|
|
|
/* */
|
|
|
|
/* cy :: The y-coordinate of the arc's new control point. */
|
|
|
|
/* */
|
|
|
|
/* x :: The x-coordinate of the arc's end point (its start point is */
|
* builds/win32/visualc/freetype.vcproj: Updated.
Exclude debug info for `Release' versions to reduce library size.
* src/base/ftobjs.c (FT_Open_Face): Make it work as documented, this
is, ignore `aface' completely if face_index < 0. Reported by David
Osborn <spam@habitualhiatus.com>.
* include/freetype/ftimage.h (FT_Outline_MoveToFunc,
FT_Outline_LineTo_Func, FT_Outline_ConicToFunc,
FT_Outline_CubicToFunc), src/smooth/ftgrays.c (gray_render_conic,
gray_render_cubic, gray_move_to, gray_line_to, gray_conic_to,
gray_cubic_to, gray_render_span, gray_sweep): Decorate parameters
with `const' where appropriate.
2005-05-17 22:35:23 +02:00
|
|
|
/* stored in `lastX'). */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* y :: The y-coordinate of the arc's end point (its start point is */
|
* builds/win32/visualc/freetype.vcproj: Updated.
Exclude debug info for `Release' versions to reduce library size.
* src/base/ftobjs.c (FT_Open_Face): Make it work as documented, this
is, ignore `aface' completely if face_index < 0. Reported by David
Osborn <spam@habitualhiatus.com>.
* include/freetype/ftimage.h (FT_Outline_MoveToFunc,
FT_Outline_LineTo_Func, FT_Outline_ConicToFunc,
FT_Outline_CubicToFunc), src/smooth/ftgrays.c (gray_render_conic,
gray_render_cubic, gray_move_to, gray_line_to, gray_conic_to,
gray_cubic_to, gray_render_span, gray_sweep): Decorate parameters
with `const' where appropriate.
2005-05-17 22:35:23 +02:00
|
|
|
/* stored in `lastY'). */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* SUCCESS on success, FAILURE on render pool overflow or incorrect */
|
|
|
|
/* profile. */
|
|
|
|
/* */
|
2001-06-28 01:25:46 +02:00
|
|
|
static Bool
|
|
|
|
Conic_To( RAS_ARGS Long cx,
|
|
|
|
Long cy,
|
|
|
|
Long x,
|
|
|
|
Long y )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
Long y1, y2, y3, x3, ymin, ymax;
|
|
|
|
TStates state_bez;
|
|
|
|
|
|
|
|
|
|
|
|
ras.arc = ras.arcs;
|
|
|
|
ras.arc[2].x = ras.lastX;
|
|
|
|
ras.arc[2].y = ras.lastY;
|
2009-06-03 08:53:47 +02:00
|
|
|
ras.arc[1].x = cx;
|
|
|
|
ras.arc[1].y = cy;
|
|
|
|
ras.arc[0].x = x;
|
|
|
|
ras.arc[0].y = y;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
y1 = ras.arc[2].y;
|
|
|
|
y2 = ras.arc[1].y;
|
|
|
|
y3 = ras.arc[0].y;
|
|
|
|
x3 = ras.arc[0].x;
|
|
|
|
|
|
|
|
/* first, categorize the Bezier arc */
|
|
|
|
|
|
|
|
if ( y1 <= y3 )
|
|
|
|
{
|
|
|
|
ymin = y1;
|
|
|
|
ymax = y3;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ymin = y3;
|
|
|
|
ymax = y1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( y2 < ymin || y2 > ymax )
|
|
|
|
{
|
|
|
|
/* this arc has no given direction, split it! */
|
|
|
|
Split_Conic( ras.arc );
|
|
|
|
ras.arc += 2;
|
|
|
|
}
|
|
|
|
else if ( y1 == y3 )
|
|
|
|
{
|
|
|
|
/* this arc is flat, ignore it and pop it from the Bezier stack */
|
|
|
|
ras.arc -= 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* the arc is y-monotonous, either ascending or descending */
|
|
|
|
/* detect a change of direction */
|
2002-04-30 16:26:49 +02:00
|
|
|
state_bez = y1 < y3 ? Ascending_State : Descending_State;
|
2000-10-26 02:30:33 +02:00
|
|
|
if ( ras.state != state_bez )
|
|
|
|
{
|
2009-06-16 15:14:21 +02:00
|
|
|
Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 )
|
|
|
|
: IS_TOP_OVERSHOOT( y1 );
|
|
|
|
|
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
/* finalize current profile if any */
|
2009-06-03 08:53:47 +02:00
|
|
|
if ( ras.state != Unknown_State &&
|
2009-06-16 15:14:21 +02:00
|
|
|
End_Profile( RAS_VARS o ) )
|
2000-10-26 02:30:33 +02:00
|
|
|
goto Fail;
|
|
|
|
|
|
|
|
/* create a new profile */
|
2009-06-16 15:14:21 +02:00
|
|
|
if ( New_Profile( RAS_VARS state_bez, o ) )
|
2000-10-26 02:30:33 +02:00
|
|
|
goto Fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* now call the appropriate routine */
|
2002-04-30 16:26:49 +02:00
|
|
|
if ( state_bez == Ascending_State )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
if ( Bezier_Up( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) )
|
|
|
|
goto Fail;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if ( Bezier_Down( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) )
|
|
|
|
goto Fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
} while ( ras.arc >= ras.arcs );
|
|
|
|
|
|
|
|
ras.lastX = x3;
|
|
|
|
ras.lastY = y3;
|
|
|
|
|
|
|
|
return SUCCESS;
|
|
|
|
|
|
|
|
Fail:
|
|
|
|
return FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* Cubic_To */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
2008-10-12 13:47:29 +02:00
|
|
|
/* Inject a new cubic arc and adjust the profile list. */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* cx1 :: The x-coordinate of the arc's first new control point. */
|
|
|
|
/* */
|
|
|
|
/* cy1 :: The y-coordinate of the arc's first new control point. */
|
|
|
|
/* */
|
|
|
|
/* cx2 :: The x-coordinate of the arc's second new control point. */
|
|
|
|
/* */
|
|
|
|
/* cy2 :: The y-coordinate of the arc's second new control point. */
|
|
|
|
/* */
|
|
|
|
/* x :: The x-coordinate of the arc's end point (its start point is */
|
* builds/win32/visualc/freetype.vcproj: Updated.
Exclude debug info for `Release' versions to reduce library size.
* src/base/ftobjs.c (FT_Open_Face): Make it work as documented, this
is, ignore `aface' completely if face_index < 0. Reported by David
Osborn <spam@habitualhiatus.com>.
* include/freetype/ftimage.h (FT_Outline_MoveToFunc,
FT_Outline_LineTo_Func, FT_Outline_ConicToFunc,
FT_Outline_CubicToFunc), src/smooth/ftgrays.c (gray_render_conic,
gray_render_cubic, gray_move_to, gray_line_to, gray_conic_to,
gray_cubic_to, gray_render_span, gray_sweep): Decorate parameters
with `const' where appropriate.
2005-05-17 22:35:23 +02:00
|
|
|
/* stored in `lastX'). */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* y :: The y-coordinate of the arc's end point (its start point is */
|
* builds/win32/visualc/freetype.vcproj: Updated.
Exclude debug info for `Release' versions to reduce library size.
* src/base/ftobjs.c (FT_Open_Face): Make it work as documented, this
is, ignore `aface' completely if face_index < 0. Reported by David
Osborn <spam@habitualhiatus.com>.
* include/freetype/ftimage.h (FT_Outline_MoveToFunc,
FT_Outline_LineTo_Func, FT_Outline_ConicToFunc,
FT_Outline_CubicToFunc), src/smooth/ftgrays.c (gray_render_conic,
gray_render_cubic, gray_move_to, gray_line_to, gray_conic_to,
gray_cubic_to, gray_render_span, gray_sweep): Decorate parameters
with `const' where appropriate.
2005-05-17 22:35:23 +02:00
|
|
|
/* stored in `lastY'). */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* SUCCESS on success, FAILURE on render pool overflow or incorrect */
|
|
|
|
/* profile. */
|
|
|
|
/* */
|
2001-06-28 01:25:46 +02:00
|
|
|
static Bool
|
|
|
|
Cubic_To( RAS_ARGS Long cx1,
|
|
|
|
Long cy1,
|
|
|
|
Long cx2,
|
|
|
|
Long cy2,
|
|
|
|
Long x,
|
|
|
|
Long y )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
Long y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2;
|
|
|
|
TStates state_bez;
|
|
|
|
|
|
|
|
|
|
|
|
ras.arc = ras.arcs;
|
|
|
|
ras.arc[3].x = ras.lastX;
|
|
|
|
ras.arc[3].y = ras.lastY;
|
2009-06-03 08:53:47 +02:00
|
|
|
ras.arc[2].x = cx1;
|
|
|
|
ras.arc[2].y = cy1;
|
|
|
|
ras.arc[1].x = cx2;
|
|
|
|
ras.arc[1].y = cy2;
|
|
|
|
ras.arc[0].x = x;
|
|
|
|
ras.arc[0].y = y;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
y1 = ras.arc[3].y;
|
|
|
|
y2 = ras.arc[2].y;
|
|
|
|
y3 = ras.arc[1].y;
|
|
|
|
y4 = ras.arc[0].y;
|
|
|
|
x4 = ras.arc[0].x;
|
|
|
|
|
|
|
|
/* first, categorize the Bezier arc */
|
|
|
|
|
|
|
|
if ( y1 <= y4 )
|
|
|
|
{
|
|
|
|
ymin1 = y1;
|
|
|
|
ymax1 = y4;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ymin1 = y4;
|
|
|
|
ymax1 = y1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( y2 <= y3 )
|
|
|
|
{
|
|
|
|
ymin2 = y2;
|
|
|
|
ymax2 = y3;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ymin2 = y3;
|
|
|
|
ymax2 = y2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ymin2 < ymin1 || ymax2 > ymax1 )
|
|
|
|
{
|
|
|
|
/* this arc has no given direction, split it! */
|
|
|
|
Split_Cubic( ras.arc );
|
|
|
|
ras.arc += 3;
|
|
|
|
}
|
|
|
|
else if ( y1 == y4 )
|
|
|
|
{
|
|
|
|
/* this arc is flat, ignore it and pop it from the Bezier stack */
|
|
|
|
ras.arc -= 3;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-04-30 16:26:49 +02:00
|
|
|
state_bez = ( y1 <= y4 ) ? Ascending_State : Descending_State;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
/* detect a change of direction */
|
|
|
|
if ( ras.state != state_bez )
|
|
|
|
{
|
2009-06-16 15:14:21 +02:00
|
|
|
Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 )
|
|
|
|
: IS_TOP_OVERSHOOT( y1 );
|
|
|
|
|
|
|
|
|
|
|
|
/* finalize current profile if any */
|
2009-06-03 08:53:47 +02:00
|
|
|
if ( ras.state != Unknown_State &&
|
2009-06-16 15:14:21 +02:00
|
|
|
End_Profile( RAS_VARS o ) )
|
2000-10-26 02:30:33 +02:00
|
|
|
goto Fail;
|
|
|
|
|
2009-06-16 15:14:21 +02:00
|
|
|
if ( New_Profile( RAS_VARS state_bez, o ) )
|
2000-10-26 02:30:33 +02:00
|
|
|
goto Fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* compute intersections */
|
2002-04-30 16:26:49 +02:00
|
|
|
if ( state_bez == Ascending_State )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
if ( Bezier_Up( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) )
|
|
|
|
goto Fail;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if ( Bezier_Down( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) )
|
|
|
|
goto Fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
} while ( ras.arc >= ras.arcs );
|
|
|
|
|
|
|
|
ras.lastX = x4;
|
|
|
|
ras.lastY = y4;
|
|
|
|
|
|
|
|
return SUCCESS;
|
|
|
|
|
|
|
|
Fail:
|
|
|
|
return FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#undef SWAP_
|
|
|
|
#define SWAP_( x, y ) do \
|
|
|
|
{ \
|
|
|
|
Long swap = x; \
|
|
|
|
\
|
|
|
|
\
|
|
|
|
x = y; \
|
|
|
|
y = swap; \
|
|
|
|
} while ( 0 )
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* Decompose_Curve */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
2008-10-12 13:47:29 +02:00
|
|
|
/* Scan the outline arrays in order to emit individual segments and */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* Beziers by calling Line_To() and Bezier_To(). It handles all */
|
|
|
|
/* weird cases, like when the first point is off the curve, or when */
|
|
|
|
/* there are simply no `on' points in the contour! */
|
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* first :: The index of the first point in the contour. */
|
|
|
|
/* */
|
|
|
|
/* last :: The index of the last point in the contour. */
|
|
|
|
/* */
|
|
|
|
/* flipped :: If set, flip the direction of the curve. */
|
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* SUCCESS on success, FAILURE on error. */
|
|
|
|
/* */
|
2001-06-28 01:25:46 +02:00
|
|
|
static Bool
|
|
|
|
Decompose_Curve( RAS_ARGS UShort first,
|
|
|
|
UShort last,
|
|
|
|
int flipped )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
FT_Vector v_last;
|
|
|
|
FT_Vector v_control;
|
|
|
|
FT_Vector v_start;
|
|
|
|
|
|
|
|
FT_Vector* points;
|
|
|
|
FT_Vector* point;
|
|
|
|
FT_Vector* limit;
|
|
|
|
char* tags;
|
|
|
|
|
2001-06-19 10:28:24 +02:00
|
|
|
unsigned tag; /* current point's state */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
points = ras.outline.points;
|
|
|
|
limit = points + last;
|
|
|
|
|
|
|
|
v_start.x = SCALED( points[first].x );
|
|
|
|
v_start.y = SCALED( points[first].y );
|
|
|
|
v_last.x = SCALED( points[last].x );
|
|
|
|
v_last.y = SCALED( points[last].y );
|
|
|
|
|
|
|
|
if ( flipped )
|
|
|
|
{
|
|
|
|
SWAP_( v_start.x, v_start.y );
|
|
|
|
SWAP_( v_last.x, v_last.y );
|
|
|
|
}
|
|
|
|
|
|
|
|
v_control = v_start;
|
|
|
|
|
|
|
|
point = points + first;
|
2009-06-03 08:53:47 +02:00
|
|
|
tags = ras.outline.tags + first;
|
Fix B/W rasterization of subglyphs with different drop-out modes.
Normally, the SCANMODE instruction (if present) to set the drop-out
mode in a TrueType font is located in the `prep' table only and thus
valid for all glyphs. However, there are fonts like `pala.ttf'
which additionally contain this instruction in the hinting code of
some glyphs (but not all). As a result it can happen that a
composite glyph needs multiple drop-out modes for its subglyphs
since the rendering state gets reset for each subglyph.
FreeType collects the hinted outlines from all subglyphs, then it
sends the data to the rasterizer. It also sends the drop-out mode
-- after hinting has been applied -- and here is the error: It sends
the drop-out mode of the last subglyph only; drop-out modes of all
other subglyphs are lost.
This patch fixes the problem; it adds a second, alternative
mechanism to pass the drop-out mode: For each contour, the
rasterizer now checks the first `tags' array element. If bit 2 is
set, bits 5-7 contain the contour's drop-out mode, overriding the
global drop-out mode.
* include/freetype/ftimage.h (FT_CURVE_TAG_HAS_SCANMODE): New macro.
* src/truetype/ttgload.c (TT_Hint_Glyph): Store drop-out mode in
`tags[0]'.
* src/raster/ftraster.c (Flow_Up, Overshoot_Top, Overshoot_Bottom):
Use bits 3-5 instead of 0-2.
(New_Profile): Set the drop-out mode in the profile's `flags' field.
(Decompose_Curve): Check `tags[0]' and set `dropOutControl' if
necessary.
(Vertical_Sweep_Drop, Horizontal_Sweep_Drop,
Horizontal_Gray_Sweep_Drop, Draw_Sweep): Use the profile's drop-out
mode.
2009-06-18 15:42:52 +02:00
|
|
|
|
|
|
|
/* set scan mode if necessary */
|
|
|
|
if ( tags[0] & FT_CURVE_TAG_HAS_SCANMODE )
|
|
|
|
ras.dropOutControl = (Byte)tags[0] >> 5;
|
|
|
|
|
|
|
|
tag = FT_CURVE_TAG( tags[0] );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
/* A contour cannot start with a cubic control point! */
|
* massive re-formatting changes to many, many source files. I don't
want to list them all here. The operations performed were all logical
transformations of the sources:
- trying to convert all enums and constants to CAPITALIZED_STYLE, with
#define definitions like
#define my_old_constants MY_NEW_CONSTANT
- big, big update of the documentation comments
* include/freetype/freetype.h, src/base/ftobjs.c, src/smooth/ftsmooth.c,
include/freetype/ftimage.h: adding support for LCD-optimized rendering
though the new constants/enums:
FT_RENDER_MODE_LCD, FT_RENDER_MODE_LCD_V
FT_PIXEL_MODE_LCD, FT_PIXEL_MODE_LCD_V
this is still work in progress, don't expect everything to work correctly
though most of the features have been implemented.
* adding new FT_LOAD_XXX flags, used to specify both hinting and rendering
targets:
FT_LOAD_TARGET_NORMAL :: anti-aliased hinting & rendering
FT_LOAD_TARGET_MONO :: monochrome bitmaps
FT_LOAD_TARGET_LCD :: horizontal RGB/BGR decimated hinting & rendering
FT_LOAD_TARGET_LCD_V :: vertical RGB/BGR decimated hinting & rendering
note that FT_LOAD_TARGET_NORMAL is 0, which means that the default
behaviour of the font engine is _unchanged_.
2002-08-27 22:20:29 +02:00
|
|
|
if ( tag == FT_CURVE_TAG_CUBIC )
|
2000-10-26 02:30:33 +02:00
|
|
|
goto Invalid_Outline;
|
|
|
|
|
|
|
|
/* check first point to determine origin */
|
* massive re-formatting changes to many, many source files. I don't
want to list them all here. The operations performed were all logical
transformations of the sources:
- trying to convert all enums and constants to CAPITALIZED_STYLE, with
#define definitions like
#define my_old_constants MY_NEW_CONSTANT
- big, big update of the documentation comments
* include/freetype/freetype.h, src/base/ftobjs.c, src/smooth/ftsmooth.c,
include/freetype/ftimage.h: adding support for LCD-optimized rendering
though the new constants/enums:
FT_RENDER_MODE_LCD, FT_RENDER_MODE_LCD_V
FT_PIXEL_MODE_LCD, FT_PIXEL_MODE_LCD_V
this is still work in progress, don't expect everything to work correctly
though most of the features have been implemented.
* adding new FT_LOAD_XXX flags, used to specify both hinting and rendering
targets:
FT_LOAD_TARGET_NORMAL :: anti-aliased hinting & rendering
FT_LOAD_TARGET_MONO :: monochrome bitmaps
FT_LOAD_TARGET_LCD :: horizontal RGB/BGR decimated hinting & rendering
FT_LOAD_TARGET_LCD_V :: vertical RGB/BGR decimated hinting & rendering
note that FT_LOAD_TARGET_NORMAL is 0, which means that the default
behaviour of the font engine is _unchanged_.
2002-08-27 22:20:29 +02:00
|
|
|
if ( tag == FT_CURVE_TAG_CONIC )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
/* first point is conic control. Yes, this happens. */
|
* massive re-formatting changes to many, many source files. I don't
want to list them all here. The operations performed were all logical
transformations of the sources:
- trying to convert all enums and constants to CAPITALIZED_STYLE, with
#define definitions like
#define my_old_constants MY_NEW_CONSTANT
- big, big update of the documentation comments
* include/freetype/freetype.h, src/base/ftobjs.c, src/smooth/ftsmooth.c,
include/freetype/ftimage.h: adding support for LCD-optimized rendering
though the new constants/enums:
FT_RENDER_MODE_LCD, FT_RENDER_MODE_LCD_V
FT_PIXEL_MODE_LCD, FT_PIXEL_MODE_LCD_V
this is still work in progress, don't expect everything to work correctly
though most of the features have been implemented.
* adding new FT_LOAD_XXX flags, used to specify both hinting and rendering
targets:
FT_LOAD_TARGET_NORMAL :: anti-aliased hinting & rendering
FT_LOAD_TARGET_MONO :: monochrome bitmaps
FT_LOAD_TARGET_LCD :: horizontal RGB/BGR decimated hinting & rendering
FT_LOAD_TARGET_LCD_V :: vertical RGB/BGR decimated hinting & rendering
note that FT_LOAD_TARGET_NORMAL is 0, which means that the default
behaviour of the font engine is _unchanged_.
2002-08-27 22:20:29 +02:00
|
|
|
if ( FT_CURVE_TAG( ras.outline.tags[last] ) == FT_CURVE_TAG_ON )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
/* start at last point if it is on the curve */
|
|
|
|
v_start = v_last;
|
|
|
|
limit--;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* if both first and last points are conic, */
|
|
|
|
/* start at their middle and record its position */
|
|
|
|
/* for closure */
|
|
|
|
v_start.x = ( v_start.x + v_last.x ) / 2;
|
|
|
|
v_start.y = ( v_start.y + v_last.y ) / 2;
|
|
|
|
|
|
|
|
v_last = v_start;
|
|
|
|
}
|
|
|
|
point--;
|
|
|
|
tags--;
|
|
|
|
}
|
|
|
|
|
|
|
|
ras.lastX = v_start.x;
|
|
|
|
ras.lastY = v_start.y;
|
|
|
|
|
|
|
|
while ( point < limit )
|
|
|
|
{
|
|
|
|
point++;
|
|
|
|
tags++;
|
|
|
|
|
|
|
|
tag = FT_CURVE_TAG( tags[0] );
|
|
|
|
|
|
|
|
switch ( tag )
|
|
|
|
{
|
* massive re-formatting changes to many, many source files. I don't
want to list them all here. The operations performed were all logical
transformations of the sources:
- trying to convert all enums and constants to CAPITALIZED_STYLE, with
#define definitions like
#define my_old_constants MY_NEW_CONSTANT
- big, big update of the documentation comments
* include/freetype/freetype.h, src/base/ftobjs.c, src/smooth/ftsmooth.c,
include/freetype/ftimage.h: adding support for LCD-optimized rendering
though the new constants/enums:
FT_RENDER_MODE_LCD, FT_RENDER_MODE_LCD_V
FT_PIXEL_MODE_LCD, FT_PIXEL_MODE_LCD_V
this is still work in progress, don't expect everything to work correctly
though most of the features have been implemented.
* adding new FT_LOAD_XXX flags, used to specify both hinting and rendering
targets:
FT_LOAD_TARGET_NORMAL :: anti-aliased hinting & rendering
FT_LOAD_TARGET_MONO :: monochrome bitmaps
FT_LOAD_TARGET_LCD :: horizontal RGB/BGR decimated hinting & rendering
FT_LOAD_TARGET_LCD_V :: vertical RGB/BGR decimated hinting & rendering
note that FT_LOAD_TARGET_NORMAL is 0, which means that the default
behaviour of the font engine is _unchanged_.
2002-08-27 22:20:29 +02:00
|
|
|
case FT_CURVE_TAG_ON: /* emit a single line_to */
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
Long x, y;
|
|
|
|
|
|
|
|
|
|
|
|
x = SCALED( point->x );
|
|
|
|
y = SCALED( point->y );
|
|
|
|
if ( flipped )
|
|
|
|
SWAP_( x, y );
|
|
|
|
|
|
|
|
if ( Line_To( RAS_VARS x, y ) )
|
|
|
|
goto Fail;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
* massive re-formatting changes to many, many source files. I don't
want to list them all here. The operations performed were all logical
transformations of the sources:
- trying to convert all enums and constants to CAPITALIZED_STYLE, with
#define definitions like
#define my_old_constants MY_NEW_CONSTANT
- big, big update of the documentation comments
* include/freetype/freetype.h, src/base/ftobjs.c, src/smooth/ftsmooth.c,
include/freetype/ftimage.h: adding support for LCD-optimized rendering
though the new constants/enums:
FT_RENDER_MODE_LCD, FT_RENDER_MODE_LCD_V
FT_PIXEL_MODE_LCD, FT_PIXEL_MODE_LCD_V
this is still work in progress, don't expect everything to work correctly
though most of the features have been implemented.
* adding new FT_LOAD_XXX flags, used to specify both hinting and rendering
targets:
FT_LOAD_TARGET_NORMAL :: anti-aliased hinting & rendering
FT_LOAD_TARGET_MONO :: monochrome bitmaps
FT_LOAD_TARGET_LCD :: horizontal RGB/BGR decimated hinting & rendering
FT_LOAD_TARGET_LCD_V :: vertical RGB/BGR decimated hinting & rendering
note that FT_LOAD_TARGET_NORMAL is 0, which means that the default
behaviour of the font engine is _unchanged_.
2002-08-27 22:20:29 +02:00
|
|
|
case FT_CURVE_TAG_CONIC: /* consume conic arcs */
|
2000-10-26 02:30:33 +02:00
|
|
|
v_control.x = SCALED( point[0].x );
|
|
|
|
v_control.y = SCALED( point[0].y );
|
|
|
|
|
|
|
|
if ( flipped )
|
|
|
|
SWAP_( v_control.x, v_control.y );
|
|
|
|
|
|
|
|
Do_Conic:
|
|
|
|
if ( point < limit )
|
|
|
|
{
|
|
|
|
FT_Vector v_middle;
|
|
|
|
Long x, y;
|
|
|
|
|
|
|
|
|
|
|
|
point++;
|
|
|
|
tags++;
|
|
|
|
tag = FT_CURVE_TAG( tags[0] );
|
|
|
|
|
|
|
|
x = SCALED( point[0].x );
|
|
|
|
y = SCALED( point[0].y );
|
|
|
|
|
|
|
|
if ( flipped )
|
|
|
|
SWAP_( x, y );
|
|
|
|
|
* massive re-formatting changes to many, many source files. I don't
want to list them all here. The operations performed were all logical
transformations of the sources:
- trying to convert all enums and constants to CAPITALIZED_STYLE, with
#define definitions like
#define my_old_constants MY_NEW_CONSTANT
- big, big update of the documentation comments
* include/freetype/freetype.h, src/base/ftobjs.c, src/smooth/ftsmooth.c,
include/freetype/ftimage.h: adding support for LCD-optimized rendering
though the new constants/enums:
FT_RENDER_MODE_LCD, FT_RENDER_MODE_LCD_V
FT_PIXEL_MODE_LCD, FT_PIXEL_MODE_LCD_V
this is still work in progress, don't expect everything to work correctly
though most of the features have been implemented.
* adding new FT_LOAD_XXX flags, used to specify both hinting and rendering
targets:
FT_LOAD_TARGET_NORMAL :: anti-aliased hinting & rendering
FT_LOAD_TARGET_MONO :: monochrome bitmaps
FT_LOAD_TARGET_LCD :: horizontal RGB/BGR decimated hinting & rendering
FT_LOAD_TARGET_LCD_V :: vertical RGB/BGR decimated hinting & rendering
note that FT_LOAD_TARGET_NORMAL is 0, which means that the default
behaviour of the font engine is _unchanged_.
2002-08-27 22:20:29 +02:00
|
|
|
if ( tag == FT_CURVE_TAG_ON )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
if ( Conic_To( RAS_VARS v_control.x, v_control.y, x, y ) )
|
|
|
|
goto Fail;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
* massive re-formatting changes to many, many source files. I don't
want to list them all here. The operations performed were all logical
transformations of the sources:
- trying to convert all enums and constants to CAPITALIZED_STYLE, with
#define definitions like
#define my_old_constants MY_NEW_CONSTANT
- big, big update of the documentation comments
* include/freetype/freetype.h, src/base/ftobjs.c, src/smooth/ftsmooth.c,
include/freetype/ftimage.h: adding support for LCD-optimized rendering
though the new constants/enums:
FT_RENDER_MODE_LCD, FT_RENDER_MODE_LCD_V
FT_PIXEL_MODE_LCD, FT_PIXEL_MODE_LCD_V
this is still work in progress, don't expect everything to work correctly
though most of the features have been implemented.
* adding new FT_LOAD_XXX flags, used to specify both hinting and rendering
targets:
FT_LOAD_TARGET_NORMAL :: anti-aliased hinting & rendering
FT_LOAD_TARGET_MONO :: monochrome bitmaps
FT_LOAD_TARGET_LCD :: horizontal RGB/BGR decimated hinting & rendering
FT_LOAD_TARGET_LCD_V :: vertical RGB/BGR decimated hinting & rendering
note that FT_LOAD_TARGET_NORMAL is 0, which means that the default
behaviour of the font engine is _unchanged_.
2002-08-27 22:20:29 +02:00
|
|
|
if ( tag != FT_CURVE_TAG_CONIC )
|
2000-10-26 02:30:33 +02:00
|
|
|
goto Invalid_Outline;
|
|
|
|
|
|
|
|
v_middle.x = ( v_control.x + x ) / 2;
|
|
|
|
v_middle.y = ( v_control.y + y ) / 2;
|
|
|
|
|
|
|
|
if ( Conic_To( RAS_VARS v_control.x, v_control.y,
|
|
|
|
v_middle.x, v_middle.y ) )
|
|
|
|
goto Fail;
|
|
|
|
|
|
|
|
v_control.x = x;
|
|
|
|
v_control.y = y;
|
|
|
|
|
|
|
|
goto Do_Conic;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( Conic_To( RAS_VARS v_control.x, v_control.y,
|
|
|
|
v_start.x, v_start.y ) )
|
|
|
|
goto Fail;
|
|
|
|
|
|
|
|
goto Close;
|
|
|
|
|
* massive re-formatting changes to many, many source files. I don't
want to list them all here. The operations performed were all logical
transformations of the sources:
- trying to convert all enums and constants to CAPITALIZED_STYLE, with
#define definitions like
#define my_old_constants MY_NEW_CONSTANT
- big, big update of the documentation comments
* include/freetype/freetype.h, src/base/ftobjs.c, src/smooth/ftsmooth.c,
include/freetype/ftimage.h: adding support for LCD-optimized rendering
though the new constants/enums:
FT_RENDER_MODE_LCD, FT_RENDER_MODE_LCD_V
FT_PIXEL_MODE_LCD, FT_PIXEL_MODE_LCD_V
this is still work in progress, don't expect everything to work correctly
though most of the features have been implemented.
* adding new FT_LOAD_XXX flags, used to specify both hinting and rendering
targets:
FT_LOAD_TARGET_NORMAL :: anti-aliased hinting & rendering
FT_LOAD_TARGET_MONO :: monochrome bitmaps
FT_LOAD_TARGET_LCD :: horizontal RGB/BGR decimated hinting & rendering
FT_LOAD_TARGET_LCD_V :: vertical RGB/BGR decimated hinting & rendering
note that FT_LOAD_TARGET_NORMAL is 0, which means that the default
behaviour of the font engine is _unchanged_.
2002-08-27 22:20:29 +02:00
|
|
|
default: /* FT_CURVE_TAG_CUBIC */
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
Long x1, y1, x2, y2, x3, y3;
|
|
|
|
|
|
|
|
|
|
|
|
if ( point + 1 > limit ||
|
* massive re-formatting changes to many, many source files. I don't
want to list them all here. The operations performed were all logical
transformations of the sources:
- trying to convert all enums and constants to CAPITALIZED_STYLE, with
#define definitions like
#define my_old_constants MY_NEW_CONSTANT
- big, big update of the documentation comments
* include/freetype/freetype.h, src/base/ftobjs.c, src/smooth/ftsmooth.c,
include/freetype/ftimage.h: adding support for LCD-optimized rendering
though the new constants/enums:
FT_RENDER_MODE_LCD, FT_RENDER_MODE_LCD_V
FT_PIXEL_MODE_LCD, FT_PIXEL_MODE_LCD_V
this is still work in progress, don't expect everything to work correctly
though most of the features have been implemented.
* adding new FT_LOAD_XXX flags, used to specify both hinting and rendering
targets:
FT_LOAD_TARGET_NORMAL :: anti-aliased hinting & rendering
FT_LOAD_TARGET_MONO :: monochrome bitmaps
FT_LOAD_TARGET_LCD :: horizontal RGB/BGR decimated hinting & rendering
FT_LOAD_TARGET_LCD_V :: vertical RGB/BGR decimated hinting & rendering
note that FT_LOAD_TARGET_NORMAL is 0, which means that the default
behaviour of the font engine is _unchanged_.
2002-08-27 22:20:29 +02:00
|
|
|
FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC )
|
2000-10-26 02:30:33 +02:00
|
|
|
goto Invalid_Outline;
|
|
|
|
|
|
|
|
point += 2;
|
|
|
|
tags += 2;
|
|
|
|
|
|
|
|
x1 = SCALED( point[-2].x );
|
|
|
|
y1 = SCALED( point[-2].y );
|
|
|
|
x2 = SCALED( point[-1].x );
|
|
|
|
y2 = SCALED( point[-1].y );
|
|
|
|
|
|
|
|
if ( flipped )
|
|
|
|
{
|
|
|
|
SWAP_( x1, y1 );
|
|
|
|
SWAP_( x2, y2 );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( point <= limit )
|
|
|
|
{
|
2010-08-06 08:20:28 +02:00
|
|
|
x3 = SCALED( point[0].x );
|
|
|
|
y3 = SCALED( point[0].y );
|
|
|
|
|
|
|
|
if ( flipped )
|
|
|
|
SWAP_( x3, y3 );
|
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
if ( Cubic_To( RAS_VARS x1, y1, x2, y2, x3, y3 ) )
|
|
|
|
goto Fail;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( Cubic_To( RAS_VARS x1, y1, x2, y2, v_start.x, v_start.y ) )
|
|
|
|
goto Fail;
|
|
|
|
goto Close;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* close the contour with a line segment */
|
|
|
|
if ( Line_To( RAS_VARS v_start.x, v_start.y ) )
|
|
|
|
goto Fail;
|
|
|
|
|
|
|
|
Close:
|
|
|
|
return SUCCESS;
|
|
|
|
|
|
|
|
Invalid_Outline:
|
2013-03-14 10:27:35 +01:00
|
|
|
ras.error = FT_THROW( Invalid );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
Fail:
|
|
|
|
return FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* Convert_Glyph */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
2008-10-12 13:47:29 +02:00
|
|
|
/* Convert a glyph into a series of segments and arcs and make a */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* profiles list with them. */
|
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* flipped :: If set, flip the direction of curve. */
|
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* SUCCESS on success, FAILURE if any error was encountered during */
|
|
|
|
/* rendering. */
|
|
|
|
/* */
|
2001-06-28 01:25:46 +02:00
|
|
|
static Bool
|
|
|
|
Convert_Glyph( RAS_ARGS int flipped )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
2001-06-19 10:28:24 +02:00
|
|
|
int i;
|
|
|
|
unsigned start;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
ras.fProfile = NULL;
|
|
|
|
ras.joint = FALSE;
|
|
|
|
ras.fresh = FALSE;
|
|
|
|
|
|
|
|
ras.maxBuff = ras.sizeBuff - AlignProfileSize;
|
|
|
|
|
|
|
|
ras.numTurns = 0;
|
|
|
|
|
|
|
|
ras.cProfile = (PProfile)ras.top;
|
|
|
|
ras.cProfile->offset = ras.top;
|
|
|
|
ras.num_Profs = 0;
|
|
|
|
|
|
|
|
start = 0;
|
|
|
|
|
|
|
|
for ( i = 0; i < ras.outline.n_contours; i++ )
|
|
|
|
{
|
2013-06-04 10:30:48 +02:00
|
|
|
PProfile lastProfile;
|
|
|
|
Bool o;
|
2009-06-16 15:14:21 +02:00
|
|
|
|
|
|
|
|
2002-04-30 16:26:49 +02:00
|
|
|
ras.state = Unknown_State;
|
2000-10-26 02:30:33 +02:00
|
|
|
ras.gProfile = NULL;
|
|
|
|
|
2001-06-20 01:03:41 +02:00
|
|
|
if ( Decompose_Curve( RAS_VARS (unsigned short)start,
|
2009-06-16 15:14:21 +02:00
|
|
|
ras.outline.contours[i],
|
|
|
|
flipped ) )
|
2000-10-26 02:30:33 +02:00
|
|
|
return FAILURE;
|
|
|
|
|
|
|
|
start = ras.outline.contours[i] + 1;
|
|
|
|
|
2009-06-03 08:53:47 +02:00
|
|
|
/* we must now check whether the extreme arcs join or not */
|
2000-10-26 02:30:33 +02:00
|
|
|
if ( FRAC( ras.lastY ) == 0 &&
|
|
|
|
ras.lastY >= ras.minY &&
|
|
|
|
ras.lastY <= ras.maxY )
|
2009-06-16 15:14:21 +02:00
|
|
|
if ( ras.gProfile &&
|
|
|
|
( ras.gProfile->flags & Flow_Up ) ==
|
|
|
|
( ras.cProfile->flags & Flow_Up ) )
|
2000-10-26 02:30:33 +02:00
|
|
|
ras.top--;
|
|
|
|
/* Note that ras.gProfile can be nil if the contour was too small */
|
|
|
|
/* to be drawn. */
|
|
|
|
|
|
|
|
lastProfile = ras.cProfile;
|
2009-06-16 15:14:21 +02:00
|
|
|
if ( ras.cProfile->flags & Flow_Up )
|
|
|
|
o = IS_TOP_OVERSHOOT( ras.lastY );
|
|
|
|
else
|
|
|
|
o = IS_BOTTOM_OVERSHOOT( ras.lastY );
|
|
|
|
if ( End_Profile( RAS_VARS o ) )
|
2000-10-26 02:30:33 +02:00
|
|
|
return FAILURE;
|
|
|
|
|
|
|
|
/* close the `next profile in contour' linked list */
|
|
|
|
if ( ras.gProfile )
|
|
|
|
lastProfile->next = ras.gProfile;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( Finalize_Profile_Table( RAS_VAR ) )
|
|
|
|
return FAILURE;
|
|
|
|
|
2001-06-19 10:28:24 +02:00
|
|
|
return (Bool)( ras.top < ras.maxBuff ? SUCCESS : FAILURE );
|
2000-10-26 02:30:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/** **/
|
|
|
|
/** SCAN-LINE SWEEPS AND DRAWING **/
|
|
|
|
/** **/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Init_Linked */
|
|
|
|
/* */
|
|
|
|
/* Initializes an empty linked list. */
|
|
|
|
/* */
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
|
|
|
Init_Linked( TProfileList* l )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
*l = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* InsNew */
|
|
|
|
/* */
|
|
|
|
/* Inserts a new profile in a linked list. */
|
|
|
|
/* */
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
|
|
|
InsNew( PProfileList list,
|
|
|
|
PProfile profile )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
PProfile *old, current;
|
|
|
|
Long x;
|
|
|
|
|
|
|
|
|
|
|
|
old = list;
|
|
|
|
current = *old;
|
|
|
|
x = profile->X;
|
|
|
|
|
|
|
|
while ( current )
|
|
|
|
{
|
|
|
|
if ( x < current->X )
|
|
|
|
break;
|
|
|
|
old = ¤t->link;
|
|
|
|
current = *old;
|
|
|
|
}
|
|
|
|
|
|
|
|
profile->link = current;
|
|
|
|
*old = profile;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* DelOld */
|
|
|
|
/* */
|
|
|
|
/* Removes an old profile from a linked list. */
|
|
|
|
/* */
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
|
|
|
DelOld( PProfileList list,
|
|
|
|
PProfile profile )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
PProfile *old, current;
|
|
|
|
|
|
|
|
|
|
|
|
old = list;
|
|
|
|
current = *old;
|
|
|
|
|
|
|
|
while ( current )
|
|
|
|
{
|
|
|
|
if ( current == profile )
|
|
|
|
{
|
|
|
|
*old = current->link;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
old = ¤t->link;
|
|
|
|
current = *old;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* we should never get there, unless the profile was not part of */
|
|
|
|
/* the list. */
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Sort */
|
|
|
|
/* */
|
|
|
|
/* Sorts a trace list. In 95%, the list is already sorted. We need */
|
|
|
|
/* an algorithm which is fast in this case. Bubble sort is enough */
|
|
|
|
/* and simple. */
|
|
|
|
/* */
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
|
|
|
Sort( PProfileList list )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
PProfile *old, current, next;
|
|
|
|
|
|
|
|
|
|
|
|
/* First, set the new X coordinate of each profile */
|
2001-10-17 16:29:51 +02:00
|
|
|
current = *list;
|
|
|
|
while ( current )
|
|
|
|
{
|
|
|
|
current->X = *current->offset;
|
2009-06-05 10:37:15 +02:00
|
|
|
current->offset += current->flags & Flow_Up ? 1 : -1;
|
2001-10-17 16:29:51 +02:00
|
|
|
current->height--;
|
|
|
|
current = current->link;
|
|
|
|
}
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
/* Then sort them */
|
|
|
|
old = list;
|
|
|
|
current = *old;
|
|
|
|
|
|
|
|
if ( !current )
|
|
|
|
return;
|
|
|
|
|
|
|
|
next = current->link;
|
|
|
|
|
|
|
|
while ( next )
|
|
|
|
{
|
|
|
|
if ( current->X <= next->X )
|
|
|
|
{
|
|
|
|
old = ¤t->link;
|
|
|
|
current = *old;
|
|
|
|
|
|
|
|
if ( !current )
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*old = next;
|
|
|
|
current->link = next->link;
|
|
|
|
next->link = current;
|
|
|
|
|
|
|
|
old = list;
|
|
|
|
current = *old;
|
|
|
|
}
|
|
|
|
|
|
|
|
next = current->link;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Vertical Sweep Procedure Set */
|
|
|
|
/* */
|
|
|
|
/* These four routines are used during the vertical black/white sweep */
|
|
|
|
/* phase by the generic Draw_Sweep() function. */
|
|
|
|
/* */
|
|
|
|
/*************************************************************************/
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
|
|
|
Vertical_Sweep_Init( RAS_ARGS Short* min,
|
|
|
|
Short* max )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
Long pitch = ras.target.pitch;
|
|
|
|
|
|
|
|
FT_UNUSED( max );
|
|
|
|
|
|
|
|
|
|
|
|
ras.traceIncr = (Short)-pitch;
|
|
|
|
ras.traceOfs = -*min * pitch;
|
|
|
|
if ( pitch > 0 )
|
|
|
|
ras.traceOfs += ( ras.target.rows - 1 ) * pitch;
|
|
|
|
|
|
|
|
ras.gray_min_x = 0;
|
|
|
|
ras.gray_max_x = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
|
|
|
Vertical_Sweep_Span( RAS_ARGS Short y,
|
|
|
|
FT_F26Dot6 x1,
|
|
|
|
FT_F26Dot6 x2,
|
|
|
|
PProfile left,
|
|
|
|
PProfile right )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
Long e1, e2;
|
|
|
|
Byte* target;
|
|
|
|
|
|
|
|
FT_UNUSED( y );
|
|
|
|
FT_UNUSED( left );
|
|
|
|
FT_UNUSED( right );
|
|
|
|
|
|
|
|
|
|
|
|
/* Drop-out control */
|
|
|
|
|
|
|
|
e1 = TRUNC( CEILING( x1 ) );
|
|
|
|
|
|
|
|
if ( x2 - x1 - ras.precision <= ras.precision_jitter )
|
|
|
|
e2 = e1;
|
|
|
|
else
|
|
|
|
e2 = TRUNC( FLOOR( x2 ) );
|
|
|
|
|
|
|
|
if ( e2 >= 0 && e1 < ras.bWidth )
|
|
|
|
{
|
2013-06-04 10:30:48 +02:00
|
|
|
int c1, c2;
|
|
|
|
Byte f1, f2;
|
|
|
|
|
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
if ( e1 < 0 )
|
|
|
|
e1 = 0;
|
|
|
|
if ( e2 >= ras.bWidth )
|
|
|
|
e2 = ras.bWidth - 1;
|
|
|
|
|
|
|
|
c1 = (Short)( e1 >> 3 );
|
|
|
|
c2 = (Short)( e2 >> 3 );
|
|
|
|
|
2001-06-19 10:28:24 +02:00
|
|
|
f1 = (Byte) ( 0xFF >> ( e1 & 7 ) );
|
|
|
|
f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
if ( ras.gray_min_x > c1 )
|
|
|
|
ras.gray_min_x = (short)c1;
|
|
|
|
if ( ras.gray_max_x < c2 )
|
|
|
|
ras.gray_max_x = (short)c2;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
target = ras.bTarget + ras.traceOfs + c1;
|
|
|
|
c2 -= c1;
|
|
|
|
|
|
|
|
if ( c2 > 0 )
|
|
|
|
{
|
|
|
|
target[0] |= f1;
|
|
|
|
|
2002-04-14 02:54:32 +02:00
|
|
|
/* memset() is slower than the following code on many platforms. */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* This is due to the fact that, in the vast majority of cases, */
|
|
|
|
/* the span length in bytes is relatively small. */
|
|
|
|
c2--;
|
|
|
|
while ( c2 > 0 )
|
|
|
|
{
|
|
|
|
*(++target) = 0xFF;
|
|
|
|
c2--;
|
|
|
|
}
|
|
|
|
target[1] |= f2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
*target |= ( f1 & f2 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
|
|
|
Vertical_Sweep_Drop( RAS_ARGS Short y,
|
|
|
|
FT_F26Dot6 x1,
|
|
|
|
FT_F26Dot6 x2,
|
|
|
|
PProfile left,
|
|
|
|
PProfile right )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
2008-06-22 15:40:08 +02:00
|
|
|
Long e1, e2, pxl;
|
2000-10-26 02:30:33 +02:00
|
|
|
Short c1, f1;
|
|
|
|
|
|
|
|
|
|
|
|
/* Drop-out control */
|
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
/* e2 x2 x1 e1 */
|
|
|
|
/* */
|
|
|
|
/* ^ | */
|
|
|
|
/* | | */
|
|
|
|
/* +-------------+---------------------+------------+ */
|
|
|
|
/* | | */
|
|
|
|
/* | v */
|
|
|
|
/* */
|
|
|
|
/* pixel contour contour pixel */
|
|
|
|
/* center center */
|
|
|
|
|
|
|
|
/* drop-out mode scan conversion rules (as defined in OpenType) */
|
|
|
|
/* --------------------------------------------------------------- */
|
|
|
|
/* 0 1, 2, 3 */
|
|
|
|
/* 1 1, 2, 4 */
|
|
|
|
/* 2 1, 2 */
|
|
|
|
/* 3 same as mode 2 */
|
|
|
|
/* 4 1, 2, 5 */
|
|
|
|
/* 5 1, 2, 6 */
|
|
|
|
/* 6, 7 same as mode 2 */
|
|
|
|
|
|
|
|
e1 = CEILING( x1 );
|
|
|
|
e2 = FLOOR ( x2 );
|
|
|
|
pxl = e1;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
if ( e1 > e2 )
|
|
|
|
{
|
Fix B/W rasterization of subglyphs with different drop-out modes.
Normally, the SCANMODE instruction (if present) to set the drop-out
mode in a TrueType font is located in the `prep' table only and thus
valid for all glyphs. However, there are fonts like `pala.ttf'
which additionally contain this instruction in the hinting code of
some glyphs (but not all). As a result it can happen that a
composite glyph needs multiple drop-out modes for its subglyphs
since the rendering state gets reset for each subglyph.
FreeType collects the hinted outlines from all subglyphs, then it
sends the data to the rasterizer. It also sends the drop-out mode
-- after hinting has been applied -- and here is the error: It sends
the drop-out mode of the last subglyph only; drop-out modes of all
other subglyphs are lost.
This patch fixes the problem; it adds a second, alternative
mechanism to pass the drop-out mode: For each contour, the
rasterizer now checks the first `tags' array element. If bit 2 is
set, bits 5-7 contain the contour's drop-out mode, overriding the
global drop-out mode.
* include/freetype/ftimage.h (FT_CURVE_TAG_HAS_SCANMODE): New macro.
* src/truetype/ttgload.c (TT_Hint_Glyph): Store drop-out mode in
`tags[0]'.
* src/raster/ftraster.c (Flow_Up, Overshoot_Top, Overshoot_Bottom):
Use bits 3-5 instead of 0-2.
(New_Profile): Set the drop-out mode in the profile's `flags' field.
(Decompose_Curve): Check `tags[0]' and set `dropOutControl' if
necessary.
(Vertical_Sweep_Drop, Horizontal_Sweep_Drop,
Horizontal_Gray_Sweep_Drop, Draw_Sweep): Use the profile's drop-out
mode.
2009-06-18 15:42:52 +02:00
|
|
|
Int dropOutControl = left->flags & 7;
|
|
|
|
|
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
if ( e1 == e2 + ras.precision )
|
|
|
|
{
|
Fix B/W rasterization of subglyphs with different drop-out modes.
Normally, the SCANMODE instruction (if present) to set the drop-out
mode in a TrueType font is located in the `prep' table only and thus
valid for all glyphs. However, there are fonts like `pala.ttf'
which additionally contain this instruction in the hinting code of
some glyphs (but not all). As a result it can happen that a
composite glyph needs multiple drop-out modes for its subglyphs
since the rendering state gets reset for each subglyph.
FreeType collects the hinted outlines from all subglyphs, then it
sends the data to the rasterizer. It also sends the drop-out mode
-- after hinting has been applied -- and here is the error: It sends
the drop-out mode of the last subglyph only; drop-out modes of all
other subglyphs are lost.
This patch fixes the problem; it adds a second, alternative
mechanism to pass the drop-out mode: For each contour, the
rasterizer now checks the first `tags' array element. If bit 2 is
set, bits 5-7 contain the contour's drop-out mode, overriding the
global drop-out mode.
* include/freetype/ftimage.h (FT_CURVE_TAG_HAS_SCANMODE): New macro.
* src/truetype/ttgload.c (TT_Hint_Glyph): Store drop-out mode in
`tags[0]'.
* src/raster/ftraster.c (Flow_Up, Overshoot_Top, Overshoot_Bottom):
Use bits 3-5 instead of 0-2.
(New_Profile): Set the drop-out mode in the profile's `flags' field.
(Decompose_Curve): Check `tags[0]' and set `dropOutControl' if
necessary.
(Vertical_Sweep_Drop, Horizontal_Sweep_Drop,
Horizontal_Gray_Sweep_Drop, Draw_Sweep): Use the profile's drop-out
mode.
2009-06-18 15:42:52 +02:00
|
|
|
switch ( dropOutControl )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
2008-06-22 15:40:08 +02:00
|
|
|
case 0: /* simple drop-outs including stubs */
|
|
|
|
pxl = e2;
|
2000-10-26 02:30:33 +02:00
|
|
|
break;
|
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
case 4: /* smart drop-outs including stubs */
|
2009-06-07 08:29:30 +02:00
|
|
|
pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
|
2000-10-26 02:30:33 +02:00
|
|
|
break;
|
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
case 1: /* simple drop-outs excluding stubs */
|
|
|
|
case 5: /* smart drop-outs excluding stubs */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
/* Drop-out Control Rules #4 and #6 */
|
|
|
|
|
2009-06-16 15:14:21 +02:00
|
|
|
/* The specification neither provides an exact definition */
|
|
|
|
/* of a `stub' nor gives exact rules to exclude them. */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
2009-06-16 15:14:21 +02:00
|
|
|
/* Here the constraints we use to recognize a stub. */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* upper stub: */
|
|
|
|
/* */
|
|
|
|
/* - P_Left and P_Right are in the same contour */
|
|
|
|
/* - P_Right is the successor of P_Left in that contour */
|
|
|
|
/* - y is the top of P_Left and P_Right */
|
|
|
|
/* */
|
|
|
|
/* lower stub: */
|
|
|
|
/* */
|
|
|
|
/* - P_Left and P_Right are in the same contour */
|
|
|
|
/* - P_Left is the successor of P_Right in that contour */
|
|
|
|
/* - y is the bottom of P_Left */
|
|
|
|
/* */
|
2009-06-16 15:14:21 +02:00
|
|
|
/* We draw a stub if the following constraints are met. */
|
|
|
|
/* */
|
|
|
|
/* - for an upper or lower stub, there is top or bottom */
|
|
|
|
/* overshoot, respectively */
|
|
|
|
/* - the covered interval is greater or equal to a half */
|
|
|
|
/* pixel */
|
|
|
|
|
|
|
|
/* upper stub test */
|
|
|
|
if ( left->next == right &&
|
|
|
|
left->height <= 0 &&
|
|
|
|
!( left->flags & Overshoot_Top &&
|
|
|
|
x2 - x1 >= ras.precision_half ) )
|
|
|
|
return;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2009-06-16 15:14:21 +02:00
|
|
|
/* lower stub test */
|
|
|
|
if ( right->next == left &&
|
|
|
|
left->start == y &&
|
|
|
|
!( left->flags & Overshoot_Bottom &&
|
|
|
|
x2 - x1 >= ras.precision_half ) )
|
|
|
|
return;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
Fix B/W rasterization of subglyphs with different drop-out modes.
Normally, the SCANMODE instruction (if present) to set the drop-out
mode in a TrueType font is located in the `prep' table only and thus
valid for all glyphs. However, there are fonts like `pala.ttf'
which additionally contain this instruction in the hinting code of
some glyphs (but not all). As a result it can happen that a
composite glyph needs multiple drop-out modes for its subglyphs
since the rendering state gets reset for each subglyph.
FreeType collects the hinted outlines from all subglyphs, then it
sends the data to the rasterizer. It also sends the drop-out mode
-- after hinting has been applied -- and here is the error: It sends
the drop-out mode of the last subglyph only; drop-out modes of all
other subglyphs are lost.
This patch fixes the problem; it adds a second, alternative
mechanism to pass the drop-out mode: For each contour, the
rasterizer now checks the first `tags' array element. If bit 2 is
set, bits 5-7 contain the contour's drop-out mode, overriding the
global drop-out mode.
* include/freetype/ftimage.h (FT_CURVE_TAG_HAS_SCANMODE): New macro.
* src/truetype/ttgload.c (TT_Hint_Glyph): Store drop-out mode in
`tags[0]'.
* src/raster/ftraster.c (Flow_Up, Overshoot_Top, Overshoot_Bottom):
Use bits 3-5 instead of 0-2.
(New_Profile): Set the drop-out mode in the profile's `flags' field.
(Decompose_Curve): Check `tags[0]' and set `dropOutControl' if
necessary.
(Vertical_Sweep_Drop, Horizontal_Sweep_Drop,
Horizontal_Gray_Sweep_Drop, Draw_Sweep): Use the profile's drop-out
mode.
2009-06-18 15:42:52 +02:00
|
|
|
if ( dropOutControl == 1 )
|
2008-06-22 15:40:08 +02:00
|
|
|
pxl = e2;
|
|
|
|
else
|
2009-06-07 08:29:30 +02:00
|
|
|
pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
|
2008-06-22 15:40:08 +02:00
|
|
|
break;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
default: /* modes 2, 3, 6, 7 */
|
|
|
|
return; /* no drop-out control */
|
|
|
|
}
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2011-01-13 12:22:55 +01:00
|
|
|
/* undocumented but confirmed: If the drop-out would result in a */
|
2011-01-14 19:44:29 +01:00
|
|
|
/* pixel outside of the bounding box, use the pixel inside of the */
|
|
|
|
/* bounding box instead */
|
2011-01-13 12:22:55 +01:00
|
|
|
if ( pxl < 0 )
|
|
|
|
pxl = e1;
|
2011-01-14 19:44:29 +01:00
|
|
|
else if ( TRUNC( pxl ) >= ras.bWidth )
|
|
|
|
pxl = e2;
|
2011-01-13 12:22:55 +01:00
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
/* check that the other pixel isn't set */
|
|
|
|
e1 = pxl == e1 ? e2 : e1;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
e1 = TRUNC( e1 );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
c1 = (Short)( e1 >> 3 );
|
|
|
|
f1 = (Short)( e1 & 7 );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
if ( e1 >= 0 && e1 < ras.bWidth &&
|
|
|
|
ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) )
|
|
|
|
return;
|
2000-10-26 02:30:33 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
e1 = TRUNC( pxl );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
if ( e1 >= 0 && e1 < ras.bWidth )
|
|
|
|
{
|
|
|
|
c1 = (Short)( e1 >> 3 );
|
2001-03-10 18:07:42 +01:00
|
|
|
f1 = (Short)( e1 & 7 );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
if ( ras.gray_min_x > c1 )
|
|
|
|
ras.gray_min_x = c1;
|
|
|
|
if ( ras.gray_max_x < c1 )
|
|
|
|
ras.gray_max_x = c1;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
|
|
|
Vertical_Sweep_Step( RAS_ARG )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
ras.traceOfs += ras.traceIncr;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Horizontal Sweep Procedure Set */
|
|
|
|
/* */
|
|
|
|
/* These four routines are used during the horizontal black/white */
|
|
|
|
/* sweep phase by the generic Draw_Sweep() function. */
|
|
|
|
/* */
|
|
|
|
/***********************************************************************/
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
|
|
|
Horizontal_Sweep_Init( RAS_ARGS Short* min,
|
|
|
|
Short* max )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
/* nothing, really */
|
* src/raster/ftmisc.h: New file. Only needed if ftraster.c is
compiled as stand-alone.
* src/raster/ftraster.c: Add comment how to compile as stand-alone.
s/FT_CONFIG_OPTION_STATIC_RASTER/FT_STATIC_RASTER/.
s/TT_STATIC_RASTER/FT_STATIC_RASTER/.
[_STANDALONE_]: Include ftimage.h and ftmisc.h.
(FT_TRACE1, FT_TRACE6, ft_memset, FT_MEM_ZERO): Define
conditionally.
(Render_Glyph, Render_Gray_Glyph): Return Raster_Err_None (or
Raster_Err_Unsupported).
(ft_black_new) [_STANDALONE_]: Fix type of `the_raster'.
(ft_black_init, ft_black_reset, ft_black_set_mode, ft_black_render):
Use `ras', not `raster'.
(ft_black_done): Use FT_UNUSED_RASTER.
(Horizontal_Sweep_Init, Horizontal_Sweep_Step,
Horizontal_Gray_Sweep_Span): Use FT_UNUSED_RASTER.
* docs/CHANGES: Updated.
2005-05-19 09:20:24 +02:00
|
|
|
FT_UNUSED_RASTER;
|
2000-10-26 02:30:33 +02:00
|
|
|
FT_UNUSED( min );
|
|
|
|
FT_UNUSED( max );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
|
|
|
Horizontal_Sweep_Span( RAS_ARGS Short y,
|
|
|
|
FT_F26Dot6 x1,
|
|
|
|
FT_F26Dot6 x2,
|
|
|
|
PProfile left,
|
|
|
|
PProfile right )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
FT_UNUSED( left );
|
|
|
|
FT_UNUSED( right );
|
|
|
|
|
|
|
|
|
|
|
|
if ( x2 - x1 < ras.precision )
|
|
|
|
{
|
2013-06-04 10:30:48 +02:00
|
|
|
Long e1, e2;
|
|
|
|
Byte f1;
|
|
|
|
|
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
e1 = CEILING( x1 );
|
|
|
|
e2 = FLOOR ( x2 );
|
|
|
|
|
|
|
|
if ( e1 == e2 )
|
|
|
|
{
|
2013-06-04 10:30:48 +02:00
|
|
|
PByte bits;
|
|
|
|
|
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
bits = ras.bTarget + ( y >> 3 );
|
|
|
|
f1 = (Byte)( 0x80 >> ( y & 7 ) );
|
|
|
|
|
|
|
|
e1 = TRUNC( e1 );
|
|
|
|
|
|
|
|
if ( e1 >= 0 && e1 < ras.target.rows )
|
|
|
|
{
|
|
|
|
PByte p;
|
|
|
|
|
|
|
|
|
2010-08-06 08:20:28 +02:00
|
|
|
p = bits - e1 * ras.target.pitch;
|
2000-10-26 02:30:33 +02:00
|
|
|
if ( ras.target.pitch > 0 )
|
|
|
|
p += ( ras.target.rows - 1 ) * ras.target.pitch;
|
|
|
|
|
|
|
|
p[0] |= f1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
|
|
|
Horizontal_Sweep_Drop( RAS_ARGS Short y,
|
|
|
|
FT_F26Dot6 x1,
|
|
|
|
FT_F26Dot6 x2,
|
|
|
|
PProfile left,
|
|
|
|
PProfile right )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
2008-06-22 15:40:08 +02:00
|
|
|
Long e1, e2, pxl;
|
2000-10-26 02:30:33 +02:00
|
|
|
PByte bits;
|
|
|
|
Byte f1;
|
|
|
|
|
|
|
|
|
|
|
|
/* During the horizontal sweep, we only take care of drop-outs */
|
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
/* e1 + <-- pixel center */
|
|
|
|
/* | */
|
|
|
|
/* x1 ---+--> <-- contour */
|
|
|
|
/* | */
|
|
|
|
/* | */
|
|
|
|
/* x2 <--+--- <-- contour */
|
|
|
|
/* | */
|
|
|
|
/* | */
|
|
|
|
/* e2 + <-- pixel center */
|
|
|
|
|
|
|
|
e1 = CEILING( x1 );
|
|
|
|
e2 = FLOOR ( x2 );
|
|
|
|
pxl = e1;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
if ( e1 > e2 )
|
|
|
|
{
|
Fix B/W rasterization of subglyphs with different drop-out modes.
Normally, the SCANMODE instruction (if present) to set the drop-out
mode in a TrueType font is located in the `prep' table only and thus
valid for all glyphs. However, there are fonts like `pala.ttf'
which additionally contain this instruction in the hinting code of
some glyphs (but not all). As a result it can happen that a
composite glyph needs multiple drop-out modes for its subglyphs
since the rendering state gets reset for each subglyph.
FreeType collects the hinted outlines from all subglyphs, then it
sends the data to the rasterizer. It also sends the drop-out mode
-- after hinting has been applied -- and here is the error: It sends
the drop-out mode of the last subglyph only; drop-out modes of all
other subglyphs are lost.
This patch fixes the problem; it adds a second, alternative
mechanism to pass the drop-out mode: For each contour, the
rasterizer now checks the first `tags' array element. If bit 2 is
set, bits 5-7 contain the contour's drop-out mode, overriding the
global drop-out mode.
* include/freetype/ftimage.h (FT_CURVE_TAG_HAS_SCANMODE): New macro.
* src/truetype/ttgload.c (TT_Hint_Glyph): Store drop-out mode in
`tags[0]'.
* src/raster/ftraster.c (Flow_Up, Overshoot_Top, Overshoot_Bottom):
Use bits 3-5 instead of 0-2.
(New_Profile): Set the drop-out mode in the profile's `flags' field.
(Decompose_Curve): Check `tags[0]' and set `dropOutControl' if
necessary.
(Vertical_Sweep_Drop, Horizontal_Sweep_Drop,
Horizontal_Gray_Sweep_Drop, Draw_Sweep): Use the profile's drop-out
mode.
2009-06-18 15:42:52 +02:00
|
|
|
Int dropOutControl = left->flags & 7;
|
|
|
|
|
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
if ( e1 == e2 + ras.precision )
|
|
|
|
{
|
Fix B/W rasterization of subglyphs with different drop-out modes.
Normally, the SCANMODE instruction (if present) to set the drop-out
mode in a TrueType font is located in the `prep' table only and thus
valid for all glyphs. However, there are fonts like `pala.ttf'
which additionally contain this instruction in the hinting code of
some glyphs (but not all). As a result it can happen that a
composite glyph needs multiple drop-out modes for its subglyphs
since the rendering state gets reset for each subglyph.
FreeType collects the hinted outlines from all subglyphs, then it
sends the data to the rasterizer. It also sends the drop-out mode
-- after hinting has been applied -- and here is the error: It sends
the drop-out mode of the last subglyph only; drop-out modes of all
other subglyphs are lost.
This patch fixes the problem; it adds a second, alternative
mechanism to pass the drop-out mode: For each contour, the
rasterizer now checks the first `tags' array element. If bit 2 is
set, bits 5-7 contain the contour's drop-out mode, overriding the
global drop-out mode.
* include/freetype/ftimage.h (FT_CURVE_TAG_HAS_SCANMODE): New macro.
* src/truetype/ttgload.c (TT_Hint_Glyph): Store drop-out mode in
`tags[0]'.
* src/raster/ftraster.c (Flow_Up, Overshoot_Top, Overshoot_Bottom):
Use bits 3-5 instead of 0-2.
(New_Profile): Set the drop-out mode in the profile's `flags' field.
(Decompose_Curve): Check `tags[0]' and set `dropOutControl' if
necessary.
(Vertical_Sweep_Drop, Horizontal_Sweep_Drop,
Horizontal_Gray_Sweep_Drop, Draw_Sweep): Use the profile's drop-out
mode.
2009-06-18 15:42:52 +02:00
|
|
|
switch ( dropOutControl )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
2008-06-22 15:40:08 +02:00
|
|
|
case 0: /* simple drop-outs including stubs */
|
|
|
|
pxl = e2;
|
2000-10-26 02:30:33 +02:00
|
|
|
break;
|
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
case 4: /* smart drop-outs including stubs */
|
2009-06-07 08:29:30 +02:00
|
|
|
pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
|
2000-10-26 02:30:33 +02:00
|
|
|
break;
|
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
case 1: /* simple drop-outs excluding stubs */
|
|
|
|
case 5: /* smart drop-outs excluding stubs */
|
|
|
|
/* see Vertical_Sweep_Drop for details */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
/* rightmost stub test */
|
2009-06-16 15:14:21 +02:00
|
|
|
if ( left->next == right &&
|
|
|
|
left->height <= 0 &&
|
|
|
|
!( left->flags & Overshoot_Top &&
|
|
|
|
x2 - x1 >= ras.precision_half ) )
|
2000-10-26 02:30:33 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
/* leftmost stub test */
|
2009-06-16 15:14:21 +02:00
|
|
|
if ( right->next == left &&
|
|
|
|
left->start == y &&
|
|
|
|
!( left->flags & Overshoot_Bottom &&
|
|
|
|
x2 - x1 >= ras.precision_half ) )
|
2000-10-26 02:30:33 +02:00
|
|
|
return;
|
|
|
|
|
Fix B/W rasterization of subglyphs with different drop-out modes.
Normally, the SCANMODE instruction (if present) to set the drop-out
mode in a TrueType font is located in the `prep' table only and thus
valid for all glyphs. However, there are fonts like `pala.ttf'
which additionally contain this instruction in the hinting code of
some glyphs (but not all). As a result it can happen that a
composite glyph needs multiple drop-out modes for its subglyphs
since the rendering state gets reset for each subglyph.
FreeType collects the hinted outlines from all subglyphs, then it
sends the data to the rasterizer. It also sends the drop-out mode
-- after hinting has been applied -- and here is the error: It sends
the drop-out mode of the last subglyph only; drop-out modes of all
other subglyphs are lost.
This patch fixes the problem; it adds a second, alternative
mechanism to pass the drop-out mode: For each contour, the
rasterizer now checks the first `tags' array element. If bit 2 is
set, bits 5-7 contain the contour's drop-out mode, overriding the
global drop-out mode.
* include/freetype/ftimage.h (FT_CURVE_TAG_HAS_SCANMODE): New macro.
* src/truetype/ttgload.c (TT_Hint_Glyph): Store drop-out mode in
`tags[0]'.
* src/raster/ftraster.c (Flow_Up, Overshoot_Top, Overshoot_Bottom):
Use bits 3-5 instead of 0-2.
(New_Profile): Set the drop-out mode in the profile's `flags' field.
(Decompose_Curve): Check `tags[0]' and set `dropOutControl' if
necessary.
(Vertical_Sweep_Drop, Horizontal_Sweep_Drop,
Horizontal_Gray_Sweep_Drop, Draw_Sweep): Use the profile's drop-out
mode.
2009-06-18 15:42:52 +02:00
|
|
|
if ( dropOutControl == 1 )
|
2008-06-22 15:40:08 +02:00
|
|
|
pxl = e2;
|
|
|
|
else
|
2009-06-07 08:29:30 +02:00
|
|
|
pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
|
2008-06-22 15:40:08 +02:00
|
|
|
break;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
default: /* modes 2, 3, 6, 7 */
|
|
|
|
return; /* no drop-out control */
|
|
|
|
}
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2011-01-14 19:44:29 +01:00
|
|
|
/* undocumented but confirmed: If the drop-out would result in a */
|
|
|
|
/* pixel outside of the bounding box, use the pixel inside of the */
|
|
|
|
/* bounding box instead */
|
2011-01-13 12:22:55 +01:00
|
|
|
if ( pxl < 0 )
|
|
|
|
pxl = e1;
|
2011-01-14 19:44:29 +01:00
|
|
|
else if ( TRUNC( pxl ) >= ras.target.rows )
|
|
|
|
pxl = e2;
|
2011-01-13 12:22:55 +01:00
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
/* check that the other pixel isn't set */
|
|
|
|
e1 = pxl == e1 ? e2 : e1;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
e1 = TRUNC( e1 );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
bits = ras.bTarget + ( y >> 3 );
|
|
|
|
f1 = (Byte)( 0x80 >> ( y & 7 ) );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
bits -= e1 * ras.target.pitch;
|
|
|
|
if ( ras.target.pitch > 0 )
|
|
|
|
bits += ( ras.target.rows - 1 ) * ras.target.pitch;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
if ( e1 >= 0 &&
|
|
|
|
e1 < ras.target.rows &&
|
|
|
|
*bits & f1 )
|
|
|
|
return;
|
2000-10-26 02:30:33 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bits = ras.bTarget + ( y >> 3 );
|
|
|
|
f1 = (Byte)( 0x80 >> ( y & 7 ) );
|
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
e1 = TRUNC( pxl );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
if ( e1 >= 0 && e1 < ras.target.rows )
|
|
|
|
{
|
|
|
|
bits -= e1 * ras.target.pitch;
|
|
|
|
if ( ras.target.pitch > 0 )
|
|
|
|
bits += ( ras.target.rows - 1 ) * ras.target.pitch;
|
|
|
|
|
|
|
|
bits[0] |= f1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
|
|
|
Horizontal_Sweep_Step( RAS_ARG )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
/* Nothing, really */
|
* src/raster/ftmisc.h: New file. Only needed if ftraster.c is
compiled as stand-alone.
* src/raster/ftraster.c: Add comment how to compile as stand-alone.
s/FT_CONFIG_OPTION_STATIC_RASTER/FT_STATIC_RASTER/.
s/TT_STATIC_RASTER/FT_STATIC_RASTER/.
[_STANDALONE_]: Include ftimage.h and ftmisc.h.
(FT_TRACE1, FT_TRACE6, ft_memset, FT_MEM_ZERO): Define
conditionally.
(Render_Glyph, Render_Gray_Glyph): Return Raster_Err_None (or
Raster_Err_Unsupported).
(ft_black_new) [_STANDALONE_]: Fix type of `the_raster'.
(ft_black_init, ft_black_reset, ft_black_set_mode, ft_black_render):
Use `ras', not `raster'.
(ft_black_done): Use FT_UNUSED_RASTER.
(Horizontal_Sweep_Init, Horizontal_Sweep_Step,
Horizontal_Gray_Sweep_Span): Use FT_UNUSED_RASTER.
* docs/CHANGES: Updated.
2005-05-19 09:20:24 +02:00
|
|
|
FT_UNUSED_RASTER;
|
2000-10-26 02:30:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef FT_RASTER_OPTION_ANTI_ALIASING
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Vertical Gray Sweep Procedure Set */
|
|
|
|
/* */
|
|
|
|
/* These two routines are used during the vertical gray-levels sweep */
|
|
|
|
/* phase by the generic Draw_Sweep() function. */
|
|
|
|
/* */
|
|
|
|
/* NOTES */
|
|
|
|
/* */
|
|
|
|
/* - The target pixmap's width *must* be a multiple of 4. */
|
|
|
|
/* */
|
|
|
|
/* - You have to use the function Vertical_Sweep_Span() for the gray */
|
|
|
|
/* span call. */
|
|
|
|
/* */
|
|
|
|
/*************************************************************************/
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
|
|
|
Vertical_Gray_Sweep_Init( RAS_ARGS Short* min,
|
|
|
|
Short* max )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
Long pitch, byte_len;
|
|
|
|
|
|
|
|
|
|
|
|
*min = *min & -2;
|
|
|
|
*max = ( *max + 3 ) & -2;
|
|
|
|
|
|
|
|
ras.traceOfs = 0;
|
|
|
|
pitch = ras.target.pitch;
|
|
|
|
byte_len = -pitch;
|
|
|
|
ras.traceIncr = (Short)byte_len;
|
|
|
|
ras.traceG = ( *min / 2 ) * byte_len;
|
|
|
|
|
|
|
|
if ( pitch > 0 )
|
|
|
|
{
|
|
|
|
ras.traceG += ( ras.target.rows - 1 ) * pitch;
|
|
|
|
byte_len = -byte_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
ras.gray_min_x = (Short)byte_len;
|
|
|
|
ras.gray_max_x = -(Short)byte_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
|
|
|
Vertical_Gray_Sweep_Step( RAS_ARG )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
2009-09-12 23:15:17 +02:00
|
|
|
short* count = (short*)count_table;
|
|
|
|
Byte* grays;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
ras.traceOfs += ras.gray_width;
|
|
|
|
|
|
|
|
if ( ras.traceOfs > ras.gray_width )
|
|
|
|
{
|
2013-06-04 10:30:48 +02:00
|
|
|
PByte pix;
|
|
|
|
|
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
pix = ras.gTarget + ras.traceG + ras.gray_min_x * 4;
|
|
|
|
grays = ras.grays;
|
|
|
|
|
|
|
|
if ( ras.gray_max_x >= 0 )
|
|
|
|
{
|
2008-10-12 13:47:29 +02:00
|
|
|
Long last_pixel = ras.target.width - 1;
|
|
|
|
Int last_cell = last_pixel >> 2;
|
|
|
|
Int last_bit = last_pixel & 3;
|
|
|
|
Bool over = 0;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2013-06-04 10:30:48 +02:00
|
|
|
Int c1, c2;
|
|
|
|
PByte bit, bit2;
|
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
if ( ras.gray_max_x >= last_cell && last_bit != 3 )
|
|
|
|
{
|
|
|
|
ras.gray_max_x = last_cell - 1;
|
|
|
|
over = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ras.gray_min_x < 0 )
|
|
|
|
ras.gray_min_x = 0;
|
|
|
|
|
2008-10-12 13:47:29 +02:00
|
|
|
bit = ras.bTarget + ras.gray_min_x;
|
|
|
|
bit2 = bit + ras.gray_width;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
c1 = ras.gray_max_x - ras.gray_min_x;
|
|
|
|
|
|
|
|
while ( c1 >= 0 )
|
|
|
|
{
|
|
|
|
c2 = count[*bit] + count[*bit2];
|
|
|
|
|
|
|
|
if ( c2 )
|
|
|
|
{
|
|
|
|
pix[0] = grays[(c2 >> 12) & 0x000F];
|
|
|
|
pix[1] = grays[(c2 >> 8 ) & 0x000F];
|
|
|
|
pix[2] = grays[(c2 >> 4 ) & 0x000F];
|
|
|
|
pix[3] = grays[ c2 & 0x000F];
|
|
|
|
|
|
|
|
*bit = 0;
|
|
|
|
*bit2 = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bit++;
|
|
|
|
bit2++;
|
|
|
|
pix += 4;
|
|
|
|
c1--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( over )
|
|
|
|
{
|
|
|
|
c2 = count[*bit] + count[*bit2];
|
|
|
|
if ( c2 )
|
|
|
|
{
|
|
|
|
switch ( last_bit )
|
|
|
|
{
|
|
|
|
case 2:
|
|
|
|
pix[2] = grays[(c2 >> 4 ) & 0x000F];
|
|
|
|
case 1:
|
|
|
|
pix[1] = grays[(c2 >> 8 ) & 0x000F];
|
|
|
|
default:
|
|
|
|
pix[0] = grays[(c2 >> 12) & 0x000F];
|
|
|
|
}
|
|
|
|
|
|
|
|
*bit = 0;
|
|
|
|
*bit2 = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ras.traceOfs = 0;
|
|
|
|
ras.traceG += ras.traceIncr;
|
|
|
|
|
|
|
|
ras.gray_min_x = 32000;
|
|
|
|
ras.gray_max_x = -32000;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
|
|
|
Horizontal_Gray_Sweep_Span( RAS_ARGS Short y,
|
|
|
|
FT_F26Dot6 x1,
|
|
|
|
FT_F26Dot6 x2,
|
|
|
|
PProfile left,
|
|
|
|
PProfile right )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
/* nothing, really */
|
* src/raster/ftmisc.h: New file. Only needed if ftraster.c is
compiled as stand-alone.
* src/raster/ftraster.c: Add comment how to compile as stand-alone.
s/FT_CONFIG_OPTION_STATIC_RASTER/FT_STATIC_RASTER/.
s/TT_STATIC_RASTER/FT_STATIC_RASTER/.
[_STANDALONE_]: Include ftimage.h and ftmisc.h.
(FT_TRACE1, FT_TRACE6, ft_memset, FT_MEM_ZERO): Define
conditionally.
(Render_Glyph, Render_Gray_Glyph): Return Raster_Err_None (or
Raster_Err_Unsupported).
(ft_black_new) [_STANDALONE_]: Fix type of `the_raster'.
(ft_black_init, ft_black_reset, ft_black_set_mode, ft_black_render):
Use `ras', not `raster'.
(ft_black_done): Use FT_UNUSED_RASTER.
(Horizontal_Sweep_Init, Horizontal_Sweep_Step,
Horizontal_Gray_Sweep_Span): Use FT_UNUSED_RASTER.
* docs/CHANGES: Updated.
2005-05-19 09:20:24 +02:00
|
|
|
FT_UNUSED_RASTER;
|
2000-10-26 02:30:33 +02:00
|
|
|
FT_UNUSED( y );
|
|
|
|
FT_UNUSED( x1 );
|
|
|
|
FT_UNUSED( x2 );
|
|
|
|
FT_UNUSED( left );
|
|
|
|
FT_UNUSED( right );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
|
|
|
Horizontal_Gray_Sweep_Drop( RAS_ARGS Short y,
|
|
|
|
FT_F26Dot6 x1,
|
|
|
|
FT_F26Dot6 x2,
|
|
|
|
PProfile left,
|
|
|
|
PProfile right )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
Long e1, e2;
|
|
|
|
PByte pixel;
|
|
|
|
|
|
|
|
|
|
|
|
/* During the horizontal sweep, we only take care of drop-outs */
|
2008-06-22 15:40:08 +02:00
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
e1 = CEILING( x1 );
|
|
|
|
e2 = FLOOR ( x2 );
|
|
|
|
|
|
|
|
if ( e1 > e2 )
|
|
|
|
{
|
Fix B/W rasterization of subglyphs with different drop-out modes.
Normally, the SCANMODE instruction (if present) to set the drop-out
mode in a TrueType font is located in the `prep' table only and thus
valid for all glyphs. However, there are fonts like `pala.ttf'
which additionally contain this instruction in the hinting code of
some glyphs (but not all). As a result it can happen that a
composite glyph needs multiple drop-out modes for its subglyphs
since the rendering state gets reset for each subglyph.
FreeType collects the hinted outlines from all subglyphs, then it
sends the data to the rasterizer. It also sends the drop-out mode
-- after hinting has been applied -- and here is the error: It sends
the drop-out mode of the last subglyph only; drop-out modes of all
other subglyphs are lost.
This patch fixes the problem; it adds a second, alternative
mechanism to pass the drop-out mode: For each contour, the
rasterizer now checks the first `tags' array element. If bit 2 is
set, bits 5-7 contain the contour's drop-out mode, overriding the
global drop-out mode.
* include/freetype/ftimage.h (FT_CURVE_TAG_HAS_SCANMODE): New macro.
* src/truetype/ttgload.c (TT_Hint_Glyph): Store drop-out mode in
`tags[0]'.
* src/raster/ftraster.c (Flow_Up, Overshoot_Top, Overshoot_Bottom):
Use bits 3-5 instead of 0-2.
(New_Profile): Set the drop-out mode in the profile's `flags' field.
(Decompose_Curve): Check `tags[0]' and set `dropOutControl' if
necessary.
(Vertical_Sweep_Drop, Horizontal_Sweep_Drop,
Horizontal_Gray_Sweep_Drop, Draw_Sweep): Use the profile's drop-out
mode.
2009-06-18 15:42:52 +02:00
|
|
|
Int dropOutControl = left->flags & 7;
|
|
|
|
|
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
if ( e1 == e2 + ras.precision )
|
|
|
|
{
|
Fix B/W rasterization of subglyphs with different drop-out modes.
Normally, the SCANMODE instruction (if present) to set the drop-out
mode in a TrueType font is located in the `prep' table only and thus
valid for all glyphs. However, there are fonts like `pala.ttf'
which additionally contain this instruction in the hinting code of
some glyphs (but not all). As a result it can happen that a
composite glyph needs multiple drop-out modes for its subglyphs
since the rendering state gets reset for each subglyph.
FreeType collects the hinted outlines from all subglyphs, then it
sends the data to the rasterizer. It also sends the drop-out mode
-- after hinting has been applied -- and here is the error: It sends
the drop-out mode of the last subglyph only; drop-out modes of all
other subglyphs are lost.
This patch fixes the problem; it adds a second, alternative
mechanism to pass the drop-out mode: For each contour, the
rasterizer now checks the first `tags' array element. If bit 2 is
set, bits 5-7 contain the contour's drop-out mode, overriding the
global drop-out mode.
* include/freetype/ftimage.h (FT_CURVE_TAG_HAS_SCANMODE): New macro.
* src/truetype/ttgload.c (TT_Hint_Glyph): Store drop-out mode in
`tags[0]'.
* src/raster/ftraster.c (Flow_Up, Overshoot_Top, Overshoot_Bottom):
Use bits 3-5 instead of 0-2.
(New_Profile): Set the drop-out mode in the profile's `flags' field.
(Decompose_Curve): Check `tags[0]' and set `dropOutControl' if
necessary.
(Vertical_Sweep_Drop, Horizontal_Sweep_Drop,
Horizontal_Gray_Sweep_Drop, Draw_Sweep): Use the profile's drop-out
mode.
2009-06-18 15:42:52 +02:00
|
|
|
switch ( dropOutControl )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
2008-06-22 15:40:08 +02:00
|
|
|
case 0: /* simple drop-outs including stubs */
|
2000-10-26 02:30:33 +02:00
|
|
|
e1 = e2;
|
|
|
|
break;
|
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
case 4: /* smart drop-outs including stubs */
|
2009-06-07 08:29:30 +02:00
|
|
|
e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
|
2000-10-26 02:30:33 +02:00
|
|
|
break;
|
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
case 1: /* simple drop-outs excluding stubs */
|
|
|
|
case 5: /* smart drop-outs excluding stubs */
|
|
|
|
/* see Vertical_Sweep_Drop for details */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
/* rightmost stub test */
|
|
|
|
if ( left->next == right && left->height <= 0 )
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* leftmost stub test */
|
|
|
|
if ( right->next == left && left->start == y )
|
|
|
|
return;
|
|
|
|
|
Fix B/W rasterization of subglyphs with different drop-out modes.
Normally, the SCANMODE instruction (if present) to set the drop-out
mode in a TrueType font is located in the `prep' table only and thus
valid for all glyphs. However, there are fonts like `pala.ttf'
which additionally contain this instruction in the hinting code of
some glyphs (but not all). As a result it can happen that a
composite glyph needs multiple drop-out modes for its subglyphs
since the rendering state gets reset for each subglyph.
FreeType collects the hinted outlines from all subglyphs, then it
sends the data to the rasterizer. It also sends the drop-out mode
-- after hinting has been applied -- and here is the error: It sends
the drop-out mode of the last subglyph only; drop-out modes of all
other subglyphs are lost.
This patch fixes the problem; it adds a second, alternative
mechanism to pass the drop-out mode: For each contour, the
rasterizer now checks the first `tags' array element. If bit 2 is
set, bits 5-7 contain the contour's drop-out mode, overriding the
global drop-out mode.
* include/freetype/ftimage.h (FT_CURVE_TAG_HAS_SCANMODE): New macro.
* src/truetype/ttgload.c (TT_Hint_Glyph): Store drop-out mode in
`tags[0]'.
* src/raster/ftraster.c (Flow_Up, Overshoot_Top, Overshoot_Bottom):
Use bits 3-5 instead of 0-2.
(New_Profile): Set the drop-out mode in the profile's `flags' field.
(Decompose_Curve): Check `tags[0]' and set `dropOutControl' if
necessary.
(Vertical_Sweep_Drop, Horizontal_Sweep_Drop,
Horizontal_Gray_Sweep_Drop, Draw_Sweep): Use the profile's drop-out
mode.
2009-06-18 15:42:52 +02:00
|
|
|
if ( dropOutControl == 1 )
|
2000-10-26 02:30:33 +02:00
|
|
|
e1 = e2;
|
|
|
|
else
|
2009-06-07 08:29:30 +02:00
|
|
|
e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
break;
|
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
default: /* modes 2, 3, 6, 7 */
|
|
|
|
return; /* no drop-out control */
|
2000-10-26 02:30:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( e1 >= 0 )
|
|
|
|
{
|
2013-06-04 10:30:48 +02:00
|
|
|
Byte color;
|
|
|
|
|
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
if ( x2 - x1 >= ras.precision_half )
|
|
|
|
color = ras.grays[2];
|
|
|
|
else
|
|
|
|
color = ras.grays[1];
|
|
|
|
|
|
|
|
e1 = TRUNC( e1 ) / 2;
|
|
|
|
if ( e1 < ras.target.rows )
|
|
|
|
{
|
|
|
|
pixel = ras.gTarget - e1 * ras.target.pitch + y / 2;
|
|
|
|
if ( ras.target.pitch > 0 )
|
|
|
|
pixel += ( ras.target.rows - 1 ) * ras.target.pitch;
|
|
|
|
|
|
|
|
if ( pixel[0] == ras.grays[0] )
|
|
|
|
pixel[0] = color;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endif /* FT_RASTER_OPTION_ANTI_ALIASING */
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Generic Sweep Drawing routine */
|
|
|
|
/* */
|
|
|
|
/*************************************************************************/
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static Bool
|
|
|
|
Draw_Sweep( RAS_ARG )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
Short y, y_change, y_height;
|
|
|
|
|
|
|
|
PProfile P, Q, P_Left, P_Right;
|
|
|
|
|
|
|
|
Short min_Y, max_Y, top, bottom, dropouts;
|
|
|
|
|
|
|
|
Long x1, x2, xs, e1, e2;
|
|
|
|
|
2002-08-06 23:47:40 +02:00
|
|
|
TProfileList waiting;
|
2000-10-26 02:30:33 +02:00
|
|
|
TProfileList draw_left, draw_right;
|
|
|
|
|
|
|
|
|
2008-10-12 13:47:29 +02:00
|
|
|
/* initialize empty linked lists */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2002-08-06 23:47:40 +02:00
|
|
|
Init_Linked( &waiting );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
Init_Linked( &draw_left );
|
|
|
|
Init_Linked( &draw_right );
|
|
|
|
|
|
|
|
/* first, compute min and max Y */
|
|
|
|
|
|
|
|
P = ras.fProfile;
|
|
|
|
max_Y = (Short)TRUNC( ras.minY );
|
|
|
|
min_Y = (Short)TRUNC( ras.maxY );
|
|
|
|
|
|
|
|
while ( P )
|
|
|
|
{
|
|
|
|
Q = P->link;
|
|
|
|
|
|
|
|
bottom = (Short)P->start;
|
2001-03-10 18:07:42 +01:00
|
|
|
top = (Short)( P->start + P->height - 1 );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
if ( min_Y > bottom )
|
|
|
|
min_Y = bottom;
|
|
|
|
if ( max_Y < top )
|
|
|
|
max_Y = top;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
P->X = 0;
|
2002-08-06 23:47:40 +02:00
|
|
|
InsNew( &waiting, P );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
P = Q;
|
|
|
|
}
|
|
|
|
|
2008-10-12 13:47:29 +02:00
|
|
|
/* check the Y-turns */
|
2000-10-26 02:30:33 +02:00
|
|
|
if ( ras.numTurns == 0 )
|
|
|
|
{
|
2013-03-14 10:27:35 +01:00
|
|
|
ras.error = FT_THROW( Invalid );
|
2000-10-26 02:30:33 +02:00
|
|
|
return FAILURE;
|
|
|
|
}
|
|
|
|
|
2008-10-12 13:47:29 +02:00
|
|
|
/* now initialize the sweep */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
ras.Proc_Sweep_Init( RAS_VARS &min_Y, &max_Y );
|
|
|
|
|
2008-10-12 13:47:29 +02:00
|
|
|
/* then compute the distance of each profile from min_Y */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2002-08-06 23:47:40 +02:00
|
|
|
P = waiting;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
while ( P )
|
|
|
|
{
|
2001-03-10 18:07:42 +01:00
|
|
|
P->countL = (UShort)( P->start - min_Y );
|
2000-10-26 02:30:33 +02:00
|
|
|
P = P->link;
|
|
|
|
}
|
|
|
|
|
2008-10-12 13:47:29 +02:00
|
|
|
/* let's go */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
y = min_Y;
|
|
|
|
y_height = 0;
|
|
|
|
|
2009-06-03 08:53:47 +02:00
|
|
|
if ( ras.numTurns > 0 &&
|
2000-10-26 02:30:33 +02:00
|
|
|
ras.sizeBuff[-ras.numTurns] == min_Y )
|
|
|
|
ras.numTurns--;
|
|
|
|
|
|
|
|
while ( ras.numTurns > 0 )
|
|
|
|
{
|
2008-10-12 13:47:29 +02:00
|
|
|
/* check waiting list for new activations */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2002-08-06 23:47:40 +02:00
|
|
|
P = waiting;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
while ( P )
|
|
|
|
{
|
|
|
|
Q = P->link;
|
|
|
|
P->countL -= y_height;
|
|
|
|
if ( P->countL == 0 )
|
|
|
|
{
|
2002-08-06 23:47:40 +02:00
|
|
|
DelOld( &waiting, P );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2009-06-05 10:37:15 +02:00
|
|
|
if ( P->flags & Flow_Up )
|
2000-10-26 02:30:33 +02:00
|
|
|
InsNew( &draw_left, P );
|
2009-06-05 10:37:15 +02:00
|
|
|
else
|
2000-10-26 02:30:33 +02:00
|
|
|
InsNew( &draw_right, P );
|
|
|
|
}
|
|
|
|
|
|
|
|
P = Q;
|
|
|
|
}
|
|
|
|
|
2008-10-12 13:47:29 +02:00
|
|
|
/* sort the drawing lists */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
Sort( &draw_left );
|
|
|
|
Sort( &draw_right );
|
|
|
|
|
|
|
|
y_change = (Short)ras.sizeBuff[-ras.numTurns--];
|
2001-06-20 01:03:41 +02:00
|
|
|
y_height = (Short)( y_change - y );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
while ( y < y_change )
|
|
|
|
{
|
2008-10-12 13:47:29 +02:00
|
|
|
/* let's trace */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
dropouts = 0;
|
|
|
|
|
|
|
|
P_Left = draw_left;
|
|
|
|
P_Right = draw_right;
|
|
|
|
|
|
|
|
while ( P_Left )
|
|
|
|
{
|
|
|
|
x1 = P_Left ->X;
|
|
|
|
x2 = P_Right->X;
|
|
|
|
|
|
|
|
if ( x1 > x2 )
|
|
|
|
{
|
|
|
|
xs = x1;
|
|
|
|
x1 = x2;
|
|
|
|
x2 = xs;
|
|
|
|
}
|
|
|
|
|
2008-07-04 09:22:06 +02:00
|
|
|
e1 = FLOOR( x1 );
|
|
|
|
e2 = CEILING( x2 );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2008-07-04 09:22:06 +02:00
|
|
|
if ( x2 - x1 <= ras.precision &&
|
|
|
|
e1 != x1 && e2 != x2 )
|
|
|
|
{
|
2008-06-24 13:19:03 +02:00
|
|
|
if ( e1 > e2 || e2 == e1 + ras.precision )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
Fix B/W rasterization of subglyphs with different drop-out modes.
Normally, the SCANMODE instruction (if present) to set the drop-out
mode in a TrueType font is located in the `prep' table only and thus
valid for all glyphs. However, there are fonts like `pala.ttf'
which additionally contain this instruction in the hinting code of
some glyphs (but not all). As a result it can happen that a
composite glyph needs multiple drop-out modes for its subglyphs
since the rendering state gets reset for each subglyph.
FreeType collects the hinted outlines from all subglyphs, then it
sends the data to the rasterizer. It also sends the drop-out mode
-- after hinting has been applied -- and here is the error: It sends
the drop-out mode of the last subglyph only; drop-out modes of all
other subglyphs are lost.
This patch fixes the problem; it adds a second, alternative
mechanism to pass the drop-out mode: For each contour, the
rasterizer now checks the first `tags' array element. If bit 2 is
set, bits 5-7 contain the contour's drop-out mode, overriding the
global drop-out mode.
* include/freetype/ftimage.h (FT_CURVE_TAG_HAS_SCANMODE): New macro.
* src/truetype/ttgload.c (TT_Hint_Glyph): Store drop-out mode in
`tags[0]'.
* src/raster/ftraster.c (Flow_Up, Overshoot_Top, Overshoot_Bottom):
Use bits 3-5 instead of 0-2.
(New_Profile): Set the drop-out mode in the profile's `flags' field.
(Decompose_Curve): Check `tags[0]' and set `dropOutControl' if
necessary.
(Vertical_Sweep_Drop, Horizontal_Sweep_Drop,
Horizontal_Gray_Sweep_Drop, Draw_Sweep): Use the profile's drop-out
mode.
2009-06-18 15:42:52 +02:00
|
|
|
Int dropOutControl = P_Left->flags & 7;
|
|
|
|
|
|
|
|
|
|
|
|
if ( dropOutControl != 2 )
|
2008-06-24 13:19:03 +02:00
|
|
|
{
|
2008-10-12 13:47:29 +02:00
|
|
|
/* a drop-out was detected */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2008-06-24 13:19:03 +02:00
|
|
|
P_Left ->X = x1;
|
|
|
|
P_Right->X = x2;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2008-06-24 13:19:03 +02:00
|
|
|
/* mark profile for drop-out processing */
|
|
|
|
P_Left->countL = 1;
|
|
|
|
dropouts++;
|
|
|
|
}
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
goto Skip_To_Next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ras.Proc_Sweep_Span( RAS_VARS y, x1, x2, P_Left, P_Right );
|
|
|
|
|
|
|
|
Skip_To_Next:
|
|
|
|
|
|
|
|
P_Left = P_Left->link;
|
|
|
|
P_Right = P_Right->link;
|
|
|
|
}
|
|
|
|
|
2008-10-12 13:47:29 +02:00
|
|
|
/* handle drop-outs _after_ the span drawing -- */
|
|
|
|
/* drop-out processing has been moved out of the loop */
|
|
|
|
/* for performance tuning */
|
2000-10-26 02:30:33 +02:00
|
|
|
if ( dropouts > 0 )
|
|
|
|
goto Scan_DropOuts;
|
|
|
|
|
|
|
|
Next_Line:
|
|
|
|
|
|
|
|
ras.Proc_Sweep_Step( RAS_VAR );
|
|
|
|
|
|
|
|
y++;
|
|
|
|
|
|
|
|
if ( y < y_change )
|
|
|
|
{
|
|
|
|
Sort( &draw_left );
|
|
|
|
Sort( &draw_right );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-12 13:47:29 +02:00
|
|
|
/* now finalize the profiles that need it */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
P = draw_left;
|
|
|
|
while ( P )
|
|
|
|
{
|
|
|
|
Q = P->link;
|
|
|
|
if ( P->height == 0 )
|
|
|
|
DelOld( &draw_left, P );
|
|
|
|
P = Q;
|
|
|
|
}
|
|
|
|
|
|
|
|
P = draw_right;
|
|
|
|
while ( P )
|
|
|
|
{
|
|
|
|
Q = P->link;
|
|
|
|
if ( P->height == 0 )
|
|
|
|
DelOld( &draw_right, P );
|
|
|
|
P = Q;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-12 13:47:29 +02:00
|
|
|
/* for gray-scaling, flush the bitmap scanline cache */
|
2000-10-26 02:30:33 +02:00
|
|
|
while ( y <= max_Y )
|
|
|
|
{
|
|
|
|
ras.Proc_Sweep_Step( RAS_VAR );
|
|
|
|
y++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return SUCCESS;
|
|
|
|
|
|
|
|
Scan_DropOuts:
|
|
|
|
|
|
|
|
P_Left = draw_left;
|
|
|
|
P_Right = draw_right;
|
|
|
|
|
|
|
|
while ( P_Left )
|
|
|
|
{
|
|
|
|
if ( P_Left->countL )
|
|
|
|
{
|
|
|
|
P_Left->countL = 0;
|
|
|
|
#if 0
|
|
|
|
dropouts--; /* -- this is useful when debugging only */
|
|
|
|
#endif
|
|
|
|
ras.Proc_Sweep_Drop( RAS_VARS y,
|
|
|
|
P_Left->X,
|
|
|
|
P_Right->X,
|
|
|
|
P_Left,
|
|
|
|
P_Right );
|
|
|
|
}
|
|
|
|
|
|
|
|
P_Left = P_Left->link;
|
|
|
|
P_Right = P_Right->link;
|
|
|
|
}
|
|
|
|
|
|
|
|
goto Next_Line;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* Render_Single_Pass */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
2008-10-12 13:47:29 +02:00
|
|
|
/* Perform one sweep with sub-banding. */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* flipped :: If set, flip the direction of the outline. */
|
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* Renderer error code. */
|
|
|
|
/* */
|
2001-06-28 01:25:46 +02:00
|
|
|
static int
|
|
|
|
Render_Single_Pass( RAS_ARGS Bool flipped )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
Short i, j, k;
|
|
|
|
|
|
|
|
|
|
|
|
while ( ras.band_top >= 0 )
|
|
|
|
{
|
|
|
|
ras.maxY = (Long)ras.band_stack[ras.band_top].y_max * ras.precision;
|
|
|
|
ras.minY = (Long)ras.band_stack[ras.band_top].y_min * ras.precision;
|
|
|
|
|
|
|
|
ras.top = ras.buff;
|
|
|
|
|
|
|
|
ras.error = Raster_Err_None;
|
|
|
|
|
|
|
|
if ( Convert_Glyph( RAS_VARS flipped ) )
|
|
|
|
{
|
|
|
|
if ( ras.error != Raster_Err_Overflow )
|
|
|
|
return FAILURE;
|
|
|
|
|
|
|
|
ras.error = Raster_Err_None;
|
|
|
|
|
|
|
|
/* sub-banding */
|
|
|
|
|
|
|
|
#ifdef DEBUG_RASTER
|
|
|
|
ClearBand( RAS_VARS TRUNC( ras.minY ), TRUNC( ras.maxY ) );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
i = ras.band_stack[ras.band_top].y_min;
|
|
|
|
j = ras.band_stack[ras.band_top].y_max;
|
|
|
|
|
2001-06-20 01:03:41 +02:00
|
|
|
k = (Short)( ( i + j ) / 2 );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
if ( ras.band_top >= 7 || k < i )
|
|
|
|
{
|
|
|
|
ras.band_top = 0;
|
2013-03-14 10:27:35 +01:00
|
|
|
ras.error = FT_THROW( Invalid );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
return ras.error;
|
|
|
|
}
|
|
|
|
|
|
|
|
ras.band_stack[ras.band_top + 1].y_min = k;
|
|
|
|
ras.band_stack[ras.band_top + 1].y_max = j;
|
|
|
|
|
2001-06-20 01:03:41 +02:00
|
|
|
ras.band_stack[ras.band_top].y_max = (Short)( k - 1 );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
ras.band_top++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( ras.fProfile )
|
|
|
|
if ( Draw_Sweep( RAS_VAR ) )
|
|
|
|
return ras.error;
|
|
|
|
ras.band_top--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* Render_Glyph */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
2008-10-12 13:47:29 +02:00
|
|
|
/* Render a glyph in a bitmap. Sub-banding if needed. */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* FreeType error code. 0 means success. */
|
|
|
|
/* */
|
2002-03-01 03:26:22 +01:00
|
|
|
FT_LOCAL_DEF( FT_Error )
|
2001-06-28 01:25:46 +02:00
|
|
|
Render_Glyph( RAS_ARG )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
FT_Error error;
|
|
|
|
|
|
|
|
|
|
|
|
Set_High_Precision( RAS_VARS ras.outline.flags &
|
2009-06-16 15:14:21 +02:00
|
|
|
FT_OUTLINE_HIGH_PRECISION );
|
2008-06-22 15:40:08 +02:00
|
|
|
ras.scale_shift = ras.precision_shift;
|
|
|
|
|
|
|
|
if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS )
|
|
|
|
ras.dropOutControl = 2;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS )
|
|
|
|
ras.dropOutControl = 4;
|
|
|
|
else
|
|
|
|
ras.dropOutControl = 0;
|
|
|
|
|
|
|
|
if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) )
|
|
|
|
ras.dropOutControl += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ras.second_pass = (FT_Byte)( !( ras.outline.flags &
|
|
|
|
FT_OUTLINE_SINGLE_PASS ) );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
/* Vertical Sweep */
|
|
|
|
ras.Proc_Sweep_Init = Vertical_Sweep_Init;
|
|
|
|
ras.Proc_Sweep_Span = Vertical_Sweep_Span;
|
|
|
|
ras.Proc_Sweep_Drop = Vertical_Sweep_Drop;
|
|
|
|
ras.Proc_Sweep_Step = Vertical_Sweep_Step;
|
|
|
|
|
|
|
|
ras.band_top = 0;
|
|
|
|
ras.band_stack[0].y_min = 0;
|
2001-06-20 01:03:41 +02:00
|
|
|
ras.band_stack[0].y_max = (short)( ras.target.rows - 1 );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2001-06-19 10:28:24 +02:00
|
|
|
ras.bWidth = (unsigned short)ras.target.width;
|
2000-10-26 02:30:33 +02:00
|
|
|
ras.bTarget = (Byte*)ras.target.buffer;
|
|
|
|
|
|
|
|
if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 )
|
|
|
|
return error;
|
|
|
|
|
|
|
|
/* Horizontal Sweep */
|
2008-06-24 13:19:03 +02:00
|
|
|
if ( ras.second_pass && ras.dropOutControl != 2 )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
ras.Proc_Sweep_Init = Horizontal_Sweep_Init;
|
|
|
|
ras.Proc_Sweep_Span = Horizontal_Sweep_Span;
|
|
|
|
ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop;
|
|
|
|
ras.Proc_Sweep_Step = Horizontal_Sweep_Step;
|
|
|
|
|
|
|
|
ras.band_top = 0;
|
|
|
|
ras.band_stack[0].y_min = 0;
|
2001-06-20 01:03:41 +02:00
|
|
|
ras.band_stack[0].y_max = (short)( ras.target.width - 1 );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 )
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
* src/raster/ftmisc.h: New file. Only needed if ftraster.c is
compiled as stand-alone.
* src/raster/ftraster.c: Add comment how to compile as stand-alone.
s/FT_CONFIG_OPTION_STATIC_RASTER/FT_STATIC_RASTER/.
s/TT_STATIC_RASTER/FT_STATIC_RASTER/.
[_STANDALONE_]: Include ftimage.h and ftmisc.h.
(FT_TRACE1, FT_TRACE6, ft_memset, FT_MEM_ZERO): Define
conditionally.
(Render_Glyph, Render_Gray_Glyph): Return Raster_Err_None (or
Raster_Err_Unsupported).
(ft_black_new) [_STANDALONE_]: Fix type of `the_raster'.
(ft_black_init, ft_black_reset, ft_black_set_mode, ft_black_render):
Use `ras', not `raster'.
(ft_black_done): Use FT_UNUSED_RASTER.
(Horizontal_Sweep_Init, Horizontal_Sweep_Step,
Horizontal_Gray_Sweep_Span): Use FT_UNUSED_RASTER.
* docs/CHANGES: Updated.
2005-05-19 09:20:24 +02:00
|
|
|
return Raster_Err_None;
|
2000-10-26 02:30:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef FT_RASTER_OPTION_ANTI_ALIASING
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* Render_Gray_Glyph */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
2008-10-12 13:47:29 +02:00
|
|
|
/* Render a glyph with grayscaling. Sub-banding if needed. */
|
2000-10-26 02:30:33 +02:00
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* FreeType error code. 0 means success. */
|
|
|
|
/* */
|
2002-03-01 03:26:22 +01:00
|
|
|
FT_LOCAL_DEF( FT_Error )
|
2001-06-28 01:25:46 +02:00
|
|
|
Render_Gray_Glyph( RAS_ARG )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
Long pixel_width;
|
|
|
|
FT_Error error;
|
|
|
|
|
|
|
|
|
|
|
|
Set_High_Precision( RAS_VARS ras.outline.flags &
|
2009-06-16 15:14:21 +02:00
|
|
|
FT_OUTLINE_HIGH_PRECISION );
|
2008-06-22 15:40:08 +02:00
|
|
|
ras.scale_shift = ras.precision_shift + 1;
|
|
|
|
|
|
|
|
if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS )
|
|
|
|
ras.dropOutControl = 2;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS )
|
|
|
|
ras.dropOutControl = 4;
|
|
|
|
else
|
|
|
|
ras.dropOutControl = 0;
|
|
|
|
|
|
|
|
if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) )
|
|
|
|
ras.dropOutControl += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
/* Vertical Sweep */
|
|
|
|
|
|
|
|
ras.band_top = 0;
|
|
|
|
ras.band_stack[0].y_min = 0;
|
|
|
|
ras.band_stack[0].y_max = 2 * ras.target.rows - 1;
|
|
|
|
|
|
|
|
ras.bWidth = ras.gray_width;
|
|
|
|
pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 );
|
|
|
|
|
|
|
|
if ( ras.bWidth > pixel_width )
|
|
|
|
ras.bWidth = pixel_width;
|
|
|
|
|
|
|
|
ras.bWidth = ras.bWidth * 8;
|
|
|
|
ras.bTarget = (Byte*)ras.gray_lines;
|
|
|
|
ras.gTarget = (Byte*)ras.target.buffer;
|
|
|
|
|
|
|
|
ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init;
|
|
|
|
ras.Proc_Sweep_Span = Vertical_Sweep_Span;
|
|
|
|
ras.Proc_Sweep_Drop = Vertical_Sweep_Drop;
|
|
|
|
ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step;
|
|
|
|
|
|
|
|
error = Render_Single_Pass( RAS_VARS 0 );
|
|
|
|
if ( error )
|
|
|
|
return error;
|
|
|
|
|
|
|
|
/* Horizontal Sweep */
|
2008-06-24 13:19:03 +02:00
|
|
|
if ( ras.second_pass && ras.dropOutControl != 2 )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
ras.Proc_Sweep_Init = Horizontal_Sweep_Init;
|
|
|
|
ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span;
|
|
|
|
ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop;
|
|
|
|
ras.Proc_Sweep_Step = Horizontal_Sweep_Step;
|
|
|
|
|
|
|
|
ras.band_top = 0;
|
|
|
|
ras.band_stack[0].y_min = 0;
|
|
|
|
ras.band_stack[0].y_max = ras.target.width * 2 - 1;
|
|
|
|
|
|
|
|
error = Render_Single_Pass( RAS_VARS 1 );
|
|
|
|
if ( error )
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
* src/raster/ftmisc.h: New file. Only needed if ftraster.c is
compiled as stand-alone.
* src/raster/ftraster.c: Add comment how to compile as stand-alone.
s/FT_CONFIG_OPTION_STATIC_RASTER/FT_STATIC_RASTER/.
s/TT_STATIC_RASTER/FT_STATIC_RASTER/.
[_STANDALONE_]: Include ftimage.h and ftmisc.h.
(FT_TRACE1, FT_TRACE6, ft_memset, FT_MEM_ZERO): Define
conditionally.
(Render_Glyph, Render_Gray_Glyph): Return Raster_Err_None (or
Raster_Err_Unsupported).
(ft_black_new) [_STANDALONE_]: Fix type of `the_raster'.
(ft_black_init, ft_black_reset, ft_black_set_mode, ft_black_render):
Use `ras', not `raster'.
(ft_black_done): Use FT_UNUSED_RASTER.
(Horizontal_Sweep_Init, Horizontal_Sweep_Step,
Horizontal_Gray_Sweep_Span): Use FT_UNUSED_RASTER.
* docs/CHANGES: Updated.
2005-05-19 09:20:24 +02:00
|
|
|
return Raster_Err_None;
|
2000-10-26 02:30:33 +02:00
|
|
|
}
|
|
|
|
|
2002-03-01 03:26:22 +01:00
|
|
|
#else /* !FT_RASTER_OPTION_ANTI_ALIASING */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2002-03-01 03:26:22 +01:00
|
|
|
FT_LOCAL_DEF( FT_Error )
|
|
|
|
Render_Gray_Glyph( RAS_ARG )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
FT_UNUSED_RASTER;
|
|
|
|
|
2013-03-14 10:27:35 +01:00
|
|
|
return FT_THROW( Unsupported );
|
2000-10-26 02:30:33 +02:00
|
|
|
}
|
|
|
|
|
2002-03-01 03:26:22 +01:00
|
|
|
#endif /* !FT_RASTER_OPTION_ANTI_ALIASING */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
2012-02-22 07:01:35 +01:00
|
|
|
ft_black_init( black_PRaster raster )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
#ifdef FT_RASTER_OPTION_ANTI_ALIASING
|
2007-01-04 19:50:12 +01:00
|
|
|
FT_UInt n;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2007-01-05 10:03:31 +01:00
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
/* set default 5-levels gray palette */
|
|
|
|
for ( n = 0; n < 5; n++ )
|
|
|
|
raster->grays[n] = n * 255 / 4;
|
|
|
|
|
2007-01-04 19:33:12 +01:00
|
|
|
raster->gray_width = RASTER_GRAY_LINES / 2;
|
2008-01-12 08:46:09 +01:00
|
|
|
#else
|
|
|
|
FT_UNUSED( raster );
|
2000-10-26 02:30:33 +02:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/
|
|
|
|
/**** a static object. *****/
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _STANDALONE_
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static int
|
2008-10-12 13:47:29 +02:00
|
|
|
ft_black_new( void* memory,
|
2001-06-28 01:25:46 +02:00
|
|
|
FT_Raster *araster )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
2012-02-22 07:01:35 +01:00
|
|
|
static black_TRaster the_raster;
|
2010-08-29 11:02:24 +02:00
|
|
|
FT_UNUSED( memory );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
* src/raster/ftmisc.h: New file. Only needed if ftraster.c is
compiled as stand-alone.
* src/raster/ftraster.c: Add comment how to compile as stand-alone.
s/FT_CONFIG_OPTION_STATIC_RASTER/FT_STATIC_RASTER/.
s/TT_STATIC_RASTER/FT_STATIC_RASTER/.
[_STANDALONE_]: Include ftimage.h and ftmisc.h.
(FT_TRACE1, FT_TRACE6, ft_memset, FT_MEM_ZERO): Define
conditionally.
(Render_Glyph, Render_Gray_Glyph): Return Raster_Err_None (or
Raster_Err_Unsupported).
(ft_black_new) [_STANDALONE_]: Fix type of `the_raster'.
(ft_black_init, ft_black_reset, ft_black_set_mode, ft_black_render):
Use `ras', not `raster'.
(ft_black_done): Use FT_UNUSED_RASTER.
(Horizontal_Sweep_Init, Horizontal_Sweep_Step,
Horizontal_Gray_Sweep_Span): Use FT_UNUSED_RASTER.
* docs/CHANGES: Updated.
2005-05-19 09:20:24 +02:00
|
|
|
*araster = (FT_Raster)&the_raster;
|
2002-07-28 07:05:24 +02:00
|
|
|
FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) );
|
2000-10-26 02:30:33 +02:00
|
|
|
ft_black_init( &the_raster );
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
|
|
|
ft_black_done( FT_Raster raster )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
/* nothing */
|
* src/raster/ftmisc.h: New file. Only needed if ftraster.c is
compiled as stand-alone.
* src/raster/ftraster.c: Add comment how to compile as stand-alone.
s/FT_CONFIG_OPTION_STATIC_RASTER/FT_STATIC_RASTER/.
s/TT_STATIC_RASTER/FT_STATIC_RASTER/.
[_STANDALONE_]: Include ftimage.h and ftmisc.h.
(FT_TRACE1, FT_TRACE6, ft_memset, FT_MEM_ZERO): Define
conditionally.
(Render_Glyph, Render_Gray_Glyph): Return Raster_Err_None (or
Raster_Err_Unsupported).
(ft_black_new) [_STANDALONE_]: Fix type of `the_raster'.
(ft_black_init, ft_black_reset, ft_black_set_mode, ft_black_render):
Use `ras', not `raster'.
(ft_black_done): Use FT_UNUSED_RASTER.
(Horizontal_Sweep_Init, Horizontal_Sweep_Step,
Horizontal_Gray_Sweep_Span): Use FT_UNUSED_RASTER.
* docs/CHANGES: Updated.
2005-05-19 09:20:24 +02:00
|
|
|
FT_UNUSED( raster );
|
2000-10-26 02:30:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-07-12 21:13:22 +02:00
|
|
|
#else /* !_STANDALONE_ */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static int
|
2012-02-22 07:01:35 +01:00
|
|
|
ft_black_new( FT_Memory memory,
|
|
|
|
black_PRaster *araster )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
2012-02-22 07:01:35 +01:00
|
|
|
FT_Error error;
|
|
|
|
black_PRaster raster = NULL;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
*araster = 0;
|
2002-03-22 14:52:37 +01:00
|
|
|
if ( !FT_NEW( raster ) )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
raster->memory = memory;
|
|
|
|
ft_black_init( raster );
|
|
|
|
|
|
|
|
*araster = raster;
|
|
|
|
}
|
|
|
|
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
2012-02-22 07:01:35 +01:00
|
|
|
ft_black_done( black_PRaster raster )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
FT_Memory memory = (FT_Memory)raster->memory;
|
2012-02-22 07:01:35 +01:00
|
|
|
|
|
|
|
|
2002-03-22 14:52:37 +01:00
|
|
|
FT_FREE( raster );
|
2000-10-26 02:30:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-07-12 21:13:22 +02:00
|
|
|
#endif /* !_STANDALONE_ */
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
2012-02-22 07:01:35 +01:00
|
|
|
ft_black_reset( black_PRaster raster,
|
|
|
|
char* pool_base,
|
|
|
|
long pool_size )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
2007-01-04 19:33:12 +01:00
|
|
|
if ( raster )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
2012-02-21 09:21:19 +01:00
|
|
|
if ( pool_base && pool_size >= (long)sizeof ( black_TWorker ) + 2048 )
|
2007-01-04 19:33:12 +01:00
|
|
|
{
|
2012-02-21 09:21:19 +01:00
|
|
|
black_PWorker worker = (black_PWorker)pool_base;
|
2007-01-04 19:33:12 +01:00
|
|
|
|
2007-01-05 10:03:31 +01:00
|
|
|
|
2010-03-11 18:27:31 +01:00
|
|
|
raster->buffer = pool_base + ( ( sizeof ( *worker ) + 7 ) & ~7 );
|
|
|
|
raster->buffer_size = pool_base + pool_size - (char*)raster->buffer;
|
2007-01-04 19:33:12 +01:00
|
|
|
raster->worker = worker;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
raster->buffer = NULL;
|
|
|
|
raster->buffer_size = 0;
|
|
|
|
raster->worker = NULL;
|
|
|
|
}
|
2000-10-26 02:30:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
2012-02-22 07:01:35 +01:00
|
|
|
ft_black_set_mode( black_PRaster raster,
|
2008-10-12 13:47:29 +02:00
|
|
|
unsigned long mode,
|
|
|
|
const char* palette )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
|
|
|
#ifdef FT_RASTER_OPTION_ANTI_ALIASING
|
|
|
|
|
|
|
|
if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) )
|
|
|
|
{
|
|
|
|
/* set 5-levels gray palette */
|
2007-01-04 19:33:12 +01:00
|
|
|
raster->grays[0] = palette[0];
|
|
|
|
raster->grays[1] = palette[1];
|
|
|
|
raster->grays[2] = palette[2];
|
|
|
|
raster->grays[3] = palette[3];
|
|
|
|
raster->grays[4] = palette[4];
|
2000-10-26 02:30:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
FT_UNUSED( raster );
|
|
|
|
FT_UNUSED( mode );
|
|
|
|
FT_UNUSED( palette );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static int
|
2012-02-22 07:01:35 +01:00
|
|
|
ft_black_render( black_PRaster raster,
|
* include/freetype/ftimage.h (FT_Raster_RenderFunc),
include/freetype/ftrender.h (FT_Glyph_TransformFunc,
FT_Renderer_Render_Func, FT_Renderer_TransformFunc),
src/base/ftglyph.c (ft_outline_glyph_transform),
src/raster/ftrend1.c (ft_raster1_transform, ft_raster1_render),
src/smooth/ftgrays.c (FT_Outline_Decompose, gray_raster_render),
src/smooth/ftsmooth.c (ft_smooth_transform,
ft_smooth_render_generic, ft_smooth_render, ft_smooth_render_lcd,
ft_smooth_render_lcd_v): Decorate parameters with `const' where
appropriate.
* src/raster/ftraster.c (RASTER_RENDER_POOL): Removed. Obsolete.
(ft_black_render): Decorate parameters with `const' where
appropriate.
* src/sfnt/ttcmap.c (tt_cmap4_set_range): Fix typo (FT_PEEK_SHORT ->
FT_PEEK_USHORT) which caused crashes. Reported by Ismail Donmez
<ismail@kde.org.tr>.
2005-05-11 22:04:35 +02:00
|
|
|
const FT_Raster_Params* params )
|
2000-10-26 02:30:33 +02:00
|
|
|
{
|
2005-05-20 08:22:20 +02:00
|
|
|
const FT_Outline* outline = (const FT_Outline*)params->source;
|
|
|
|
const FT_Bitmap* target_map = params->target;
|
2012-02-22 07:01:35 +01:00
|
|
|
black_PWorker worker;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
2007-01-04 19:33:12 +01:00
|
|
|
if ( !raster || !raster->buffer || !raster->buffer_size )
|
2013-03-14 10:27:35 +01:00
|
|
|
return FT_THROW( Not_Ini );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2008-01-16 07:58:54 +01:00
|
|
|
if ( !outline )
|
2013-03-14 10:27:35 +01:00
|
|
|
return FT_THROW( Invalid );
|
2008-01-16 07:58:54 +01:00
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
/* return immediately if the outline is empty */
|
|
|
|
if ( outline->n_points == 0 || outline->n_contours <= 0 )
|
|
|
|
return Raster_Err_None;
|
|
|
|
|
2008-01-16 07:58:54 +01:00
|
|
|
if ( !outline->contours || !outline->points )
|
2013-03-14 10:27:35 +01:00
|
|
|
return FT_THROW( Invalid );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2008-05-25 14:19:34 +02:00
|
|
|
if ( outline->n_points !=
|
|
|
|
outline->contours[outline->n_contours - 1] + 1 )
|
2013-03-14 10:27:35 +01:00
|
|
|
return FT_THROW( Invalid );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2007-01-04 19:33:12 +01:00
|
|
|
worker = raster->worker;
|
|
|
|
|
2000-10-26 02:30:33 +02:00
|
|
|
/* this version of the raster does not support direct rendering, sorry */
|
* massive re-formatting changes to many, many source files. I don't
want to list them all here. The operations performed were all logical
transformations of the sources:
- trying to convert all enums and constants to CAPITALIZED_STYLE, with
#define definitions like
#define my_old_constants MY_NEW_CONSTANT
- big, big update of the documentation comments
* include/freetype/freetype.h, src/base/ftobjs.c, src/smooth/ftsmooth.c,
include/freetype/ftimage.h: adding support for LCD-optimized rendering
though the new constants/enums:
FT_RENDER_MODE_LCD, FT_RENDER_MODE_LCD_V
FT_PIXEL_MODE_LCD, FT_PIXEL_MODE_LCD_V
this is still work in progress, don't expect everything to work correctly
though most of the features have been implemented.
* adding new FT_LOAD_XXX flags, used to specify both hinting and rendering
targets:
FT_LOAD_TARGET_NORMAL :: anti-aliased hinting & rendering
FT_LOAD_TARGET_MONO :: monochrome bitmaps
FT_LOAD_TARGET_LCD :: horizontal RGB/BGR decimated hinting & rendering
FT_LOAD_TARGET_LCD_V :: vertical RGB/BGR decimated hinting & rendering
note that FT_LOAD_TARGET_NORMAL is 0, which means that the default
behaviour of the font engine is _unchanged_.
2002-08-27 22:20:29 +02:00
|
|
|
if ( params->flags & FT_RASTER_FLAG_DIRECT )
|
2013-03-14 10:27:35 +01:00
|
|
|
return FT_THROW( Unsupported );
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2008-05-25 14:19:34 +02:00
|
|
|
if ( !target_map )
|
2013-03-14 10:27:35 +01:00
|
|
|
return FT_THROW( Invalid );
|
2008-05-25 14:19:34 +02:00
|
|
|
|
|
|
|
/* nothing to do */
|
|
|
|
if ( !target_map->width || !target_map->rows )
|
|
|
|
return Raster_Err_None;
|
|
|
|
|
|
|
|
if ( !target_map->buffer )
|
2013-03-14 10:27:35 +01:00
|
|
|
return FT_THROW( Invalid );
|
2000-12-14 22:24:27 +01:00
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
ras.outline = *outline;
|
|
|
|
ras.target = *target_map;
|
2000-10-26 02:30:33 +02:00
|
|
|
|
2008-06-22 15:40:08 +02:00
|
|
|
worker->buff = (PLong) raster->buffer;
|
|
|
|
worker->sizeBuff = worker->buff +
|
|
|
|
raster->buffer_size / sizeof ( Long );
|
2007-01-04 19:33:12 +01:00
|
|
|
#ifdef FT_RASTER_OPTION_ANTI_ALIASING
|
2008-06-22 15:40:08 +02:00
|
|
|
worker->grays = raster->grays;
|
|
|
|
worker->gray_width = raster->gray_width;
|
2009-09-12 23:15:17 +02:00
|
|
|
|
|
|
|
FT_MEM_ZERO( worker->gray_lines, worker->gray_width * 2 );
|
2007-01-04 19:33:12 +01:00
|
|
|
#endif
|
|
|
|
|
2009-06-03 08:53:47 +02:00
|
|
|
return ( params->flags & FT_RASTER_FLAG_AA )
|
|
|
|
? Render_Gray_Glyph( RAS_VAR )
|
|
|
|
: Render_Glyph( RAS_VAR );
|
2000-10-26 02:30:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-07-09 09:21:46 +02:00
|
|
|
FT_DEFINE_RASTER_FUNCS( ft_standard_raster,
|
* massive re-formatting changes to many, many source files. I don't
want to list them all here. The operations performed were all logical
transformations of the sources:
- trying to convert all enums and constants to CAPITALIZED_STYLE, with
#define definitions like
#define my_old_constants MY_NEW_CONSTANT
- big, big update of the documentation comments
* include/freetype/freetype.h, src/base/ftobjs.c, src/smooth/ftsmooth.c,
include/freetype/ftimage.h: adding support for LCD-optimized rendering
though the new constants/enums:
FT_RENDER_MODE_LCD, FT_RENDER_MODE_LCD_V
FT_PIXEL_MODE_LCD, FT_PIXEL_MODE_LCD_V
this is still work in progress, don't expect everything to work correctly
though most of the features have been implemented.
* adding new FT_LOAD_XXX flags, used to specify both hinting and rendering
targets:
FT_LOAD_TARGET_NORMAL :: anti-aliased hinting & rendering
FT_LOAD_TARGET_MONO :: monochrome bitmaps
FT_LOAD_TARGET_LCD :: horizontal RGB/BGR decimated hinting & rendering
FT_LOAD_TARGET_LCD_V :: vertical RGB/BGR decimated hinting & rendering
note that FT_LOAD_TARGET_NORMAL is 0, which means that the default
behaviour of the font engine is _unchanged_.
2002-08-27 22:20:29 +02:00
|
|
|
FT_GLYPH_FORMAT_OUTLINE,
|
2000-10-26 02:30:33 +02:00
|
|
|
(FT_Raster_New_Func) ft_black_new,
|
|
|
|
(FT_Raster_Reset_Func) ft_black_reset,
|
|
|
|
(FT_Raster_Set_Mode_Func)ft_black_set_mode,
|
|
|
|
(FT_Raster_Render_Func) ft_black_render,
|
|
|
|
(FT_Raster_Done_Func) ft_black_done
|
2009-04-05 17:16:13 +02:00
|
|
|
)
|
2000-10-26 02:30:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* END */
|