2000-06-28 01:18:39 +02:00
|
|
|
/***************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* ftgrays.c */
|
|
|
|
/* */
|
|
|
|
/* A new `perfect' anti-aliasing renderer (body). */
|
|
|
|
/* */
|
2016-01-13 11:54:10 +01:00
|
|
|
/* Copyright 2000-2016 by */
|
2000-06-28 01:18:39 +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. */
|
|
|
|
/* */
|
|
|
|
/***************************************************************************/
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
2002-04-01 16:25:28 +02:00
|
|
|
/* This file can be compiled without the rest of the FreeType engine, by */
|
2016-01-12 22:27:29 +01:00
|
|
|
/* defining the STANDALONE_ macro when compiling it. You also need to */
|
2002-04-01 16:25:28 +02:00
|
|
|
/* put the files `ftgrays.h' and `ftimage.h' into the current */
|
|
|
|
/* compilation directory. Typically, you could do something like */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* */
|
2002-09-16 08:15:31 +02:00
|
|
|
/* - copy `src/smooth/ftgrays.c' (this file) to your current directory */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* */
|
Another adjustment to header locations.
This change is a result of a discussion thread on freetype-devel
http://lists.nongnu.org/archive/html/freetype-devel/2015-06/msg00041.html
Re-introduce the `freetype2' subdirectory for all FreeType header
files after installation, and rename the `freetype2' subdirectory in
the git repository to `freetype'.
* include/freetype2: Renamed to...
* include/freetype: This.
* CMakeLists.txt (PUBLIC_HEADERS, PUBLIC_CONFIG_HEADERS,
PRIVATE_HEADERS): Updated.
Update creation of `ftconfig.h'.
Install generated `ftconfig.h'.
* Jamfile (HDRMACRO, RefDoc), autogen.sh: Updated.
* builds/amiga/include/config/ftconfig.h, builds/freetype.mk
(PUBLIC_DIR), builds/symbian/bld.inf, builds/toplevel.mk (work),
builds/unix/freetype2.in: Updated.
* builds/unix/freetype-config.in: Updated.
* builds/unix/configure.raw: Don't check for `rmdir'.
* builds/unix/unix-def.in (DELDIR): Use `rm -rf', which is portable
according to the autoconf info manual.
* builds/unix/install.mk (install, uninstall,
distclean_project_unix): Update and simplify.
* builds/wince/*, builds/windows/*: Updated.
* devel/ft2build.h, include/ft2build.h: Updated.
* include/freetype2/config/ftheader.h,
include/freetype2/internal/ftserv.h,
include/freetype2/internal/internal.h: Update all header file
macros.
* src/tools/chktrcmp.py (TRACE_DEF_FILES): Updated.
* docs/*: Updated.
2015-06-25 13:04:57 +02:00
|
|
|
/* - copy `include/freetype/ftimage.h' and `src/smooth/ftgrays.h' to the */
|
|
|
|
/* same directory */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* */
|
2016-01-12 22:27:29 +01:00
|
|
|
/* - compile `ftgrays' with the STANDALONE_ macro defined, as in */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* */
|
2016-01-12 22:27:29 +01:00
|
|
|
/* cc -c -DSTANDALONE_ ftgrays.c */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* */
|
2002-04-01 16:25:28 +02:00
|
|
|
/* The renderer can be initialized with a call to */
|
2002-10-24 23:37:02 +02:00
|
|
|
/* `ft_gray_raster.raster_new'; an anti-aliased bitmap can be generated */
|
|
|
|
/* with a call to `ft_gray_raster.raster_render'. */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* */
|
2002-04-01 16:25:28 +02:00
|
|
|
/* See the comments and documentation in the file `ftimage.h' for more */
|
|
|
|
/* details on how the raster works. */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* */
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
2002-04-01 16:25:28 +02:00
|
|
|
/* This is a new anti-aliasing scan-converter for FreeType 2. The */
|
|
|
|
/* algorithm used here is _very_ different from the one in the standard */
|
|
|
|
/* `ftraster' module. Actually, `ftgrays' computes the _exact_ */
|
|
|
|
/* coverage of the outline on each pixel cell. */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* */
|
2002-04-01 16:25:28 +02:00
|
|
|
/* It is based on ideas that I initially found in Raph Levien's */
|
|
|
|
/* excellent LibArt graphics library (see http://www.levien.com/libart */
|
|
|
|
/* for more information, though the web pages do not tell anything */
|
|
|
|
/* about the renderer; you'll have to dive into the source code to */
|
|
|
|
/* understand how it works). */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* */
|
2002-04-01 16:25:28 +02:00
|
|
|
/* Note, however, that this is a _very_ different implementation */
|
|
|
|
/* compared to Raph's. Coverage information is stored in a very */
|
|
|
|
/* different way, and I don't use sorted vector paths. Also, it doesn't */
|
|
|
|
/* use floating point values. */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* */
|
2002-04-01 16:25:28 +02:00
|
|
|
/* This renderer has the following advantages: */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* */
|
2002-04-01 16:25:28 +02:00
|
|
|
/* - It doesn't need an intermediate bitmap. Instead, one can supply a */
|
|
|
|
/* callback function that will be called by the renderer to draw gray */
|
|
|
|
/* spans on any target surface. You can thus do direct composition on */
|
|
|
|
/* any kind of bitmap, provided that you give the renderer the right */
|
|
|
|
/* callback. */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* */
|
2002-04-01 16:25:28 +02:00
|
|
|
/* - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on */
|
|
|
|
/* each pixel cell. */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* */
|
2002-04-01 16:25:28 +02:00
|
|
|
/* - It performs a single pass on the outline (the `standard' FT2 */
|
|
|
|
/* renderer makes two passes). */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* */
|
2002-04-01 16:25:28 +02:00
|
|
|
/* - It can easily be modified to render to _any_ number of gray levels */
|
|
|
|
/* cheaply. */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* */
|
2002-04-01 16:25:28 +02:00
|
|
|
/* - For small (< 20) pixel sizes, it is faster than the standard */
|
|
|
|
/* renderer. */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* */
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* 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
|
2002-02-21 12:48:48 +01:00
|
|
|
#define FT_COMPONENT trace_smooth
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
|
2016-01-12 22:27:29 +01:00
|
|
|
#ifdef STANDALONE_
|
2001-10-07 12:39:03 +02:00
|
|
|
|
* 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
|
|
|
|
2015-02-23 07:04:36 +01:00
|
|
|
/* The size in bytes of the render pool used by the scan-line converter */
|
|
|
|
/* to do all of its work. */
|
|
|
|
#define FT_RENDER_POOL_SIZE 16384L
|
|
|
|
|
|
|
|
|
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 )
|
|
|
|
|
2014-04-13 15:41:13 +02:00
|
|
|
#define FT_BEGIN_STMNT do {
|
|
|
|
#define FT_END_STMNT } while ( 0 )
|
|
|
|
|
2016-06-23 05:14:26 +02:00
|
|
|
#define FT_MIN( a, b ) ( (a) < (b) ? (a) : (b) )
|
|
|
|
#define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) )
|
2015-02-23 07:04:36 +01:00
|
|
|
#define FT_ABS( a ) ( (a) < 0 ? -(a) : (a) )
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Approximate sqrt(x*x+y*y) using the `alpha max plus beta min'
|
|
|
|
* algorithm. We use alpha = 1, beta = 3/8, giving us results with a
|
|
|
|
* largest error less than 7% compared to the exact value.
|
|
|
|
*/
|
|
|
|
#define FT_HYPOT( x, y ) \
|
|
|
|
( x = FT_ABS( x ), \
|
|
|
|
y = FT_ABS( y ), \
|
|
|
|
x > y ? x + ( 3 * y >> 3 ) \
|
|
|
|
: y + ( 3 * x >> 3 ) )
|
|
|
|
|
2013-03-14 10:27:35 +01:00
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
/* define this to dump debugging information */
|
|
|
|
/* #define FT_DEBUG_LEVEL_TRACE */
|
|
|
|
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
#ifdef FT_DEBUG_LEVEL_TRACE
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#endif
|
|
|
|
|
2010-07-03 15:31:38 +02:00
|
|
|
#include <stddef.h>
|
2008-09-20 13:50:47 +02:00
|
|
|
#include <string.h>
|
* 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
|
|
|
#include <setjmp.h>
|
|
|
|
#include <limits.h>
|
2015-10-07 04:39:54 +02:00
|
|
|
#define FT_CHAR_BIT CHAR_BIT
|
|
|
|
#define FT_UINT_MAX UINT_MAX
|
|
|
|
#define FT_INT_MAX INT_MAX
|
|
|
|
#define FT_ULONG_MAX ULONG_MAX
|
2000-07-09 21:15:30 +02:00
|
|
|
|
2002-09-16 08:15:31 +02:00
|
|
|
#define ft_memset memset
|
|
|
|
|
|
|
|
#define ft_setjmp setjmp
|
|
|
|
#define ft_longjmp longjmp
|
|
|
|
#define ft_jmp_buf jmp_buf
|
2002-06-11 01:03:35 +02:00
|
|
|
|
2010-07-03 15:31:38 +02:00
|
|
|
typedef ptrdiff_t FT_PtrDist;
|
|
|
|
|
2002-06-11 01:03:35 +02:00
|
|
|
|
2006-11-28 09:09:20 +01:00
|
|
|
#define ErrRaster_Invalid_Mode -2
|
|
|
|
#define ErrRaster_Invalid_Outline -1
|
|
|
|
#define ErrRaster_Invalid_Argument -3
|
|
|
|
#define ErrRaster_Memory_Overflow -4
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2002-09-16 08:15:31 +02:00
|
|
|
#define FT_BEGIN_HEADER
|
|
|
|
#define FT_END_HEADER
|
|
|
|
|
2000-06-28 01:18:39 +02:00
|
|
|
#include "ftimage.h"
|
|
|
|
#include "ftgrays.h"
|
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
|
2000-06-28 01:18:39 +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). */
|
2000-07-04 20:12:13 +02:00
|
|
|
#define FT_UNUSED( x ) (x) = (x)
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
|
|
|
|
/* we only use level 5 & 7 tracing messages; cf. ftdebug.h */
|
|
|
|
|
|
|
|
#ifdef FT_DEBUG_LEVEL_TRACE
|
|
|
|
|
|
|
|
void
|
|
|
|
FT_Message( const char* fmt,
|
|
|
|
... )
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
|
|
|
|
va_start( ap, fmt );
|
|
|
|
vfprintf( stderr, fmt, ap );
|
|
|
|
va_end( ap );
|
|
|
|
}
|
|
|
|
|
2013-03-14 10:27:35 +01:00
|
|
|
|
|
|
|
/* empty function useful for setting a breakpoint to catch errors */
|
|
|
|
int
|
|
|
|
FT_Throw( int error,
|
|
|
|
int line,
|
|
|
|
const char* file )
|
|
|
|
{
|
|
|
|
FT_UNUSED( error );
|
|
|
|
FT_UNUSED( line );
|
|
|
|
FT_UNUSED( file );
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
/* we don't handle tracing levels in stand-alone mode; */
|
|
|
|
#ifndef FT_TRACE5
|
|
|
|
#define FT_TRACE5( varformat ) FT_Message varformat
|
|
|
|
#endif
|
|
|
|
#ifndef FT_TRACE7
|
|
|
|
#define FT_TRACE7( varformat ) FT_Message varformat
|
|
|
|
#endif
|
2000-06-28 01:18:39 +02:00
|
|
|
#ifndef FT_ERROR
|
2008-09-20 13:50:47 +02:00
|
|
|
#define FT_ERROR( varformat ) FT_Message varformat
|
2000-06-28 01:18:39 +02:00
|
|
|
#endif
|
|
|
|
|
2013-03-14 10:27:35 +01:00
|
|
|
#define FT_THROW( e ) \
|
|
|
|
( FT_Throw( FT_ERR_CAT( ErrRaster, e ), \
|
|
|
|
__LINE__, \
|
|
|
|
__FILE__ ) | \
|
|
|
|
FT_ERR_CAT( ErrRaster, e ) )
|
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
#else /* !FT_DEBUG_LEVEL_TRACE */
|
|
|
|
|
2009-01-12 21:11:14 +01:00
|
|
|
#define FT_TRACE5( x ) do { } while ( 0 ) /* nothing */
|
|
|
|
#define FT_TRACE7( x ) do { } while ( 0 ) /* nothing */
|
|
|
|
#define FT_ERROR( x ) do { } while ( 0 ) /* nothing */
|
2013-03-14 10:27:35 +01:00
|
|
|
#define FT_THROW( e ) FT_ERR_CAT( ErrRaster_, e )
|
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
|
|
|
|
#endif /* !FT_DEBUG_LEVEL_TRACE */
|
|
|
|
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2009-04-26 16:32:10 +02:00
|
|
|
#define FT_DEFINE_OUTLINE_FUNCS( class_, \
|
|
|
|
move_to_, line_to_, \
|
|
|
|
conic_to_, cubic_to_, \
|
|
|
|
shift_, delta_ ) \
|
|
|
|
static const FT_Outline_Funcs class_ = \
|
|
|
|
{ \
|
|
|
|
move_to_, \
|
|
|
|
line_to_, \
|
|
|
|
conic_to_, \
|
|
|
|
cubic_to_, \
|
|
|
|
shift_, \
|
|
|
|
delta_ \
|
|
|
|
};
|
2010-09-20 09:29:23 +02:00
|
|
|
|
2009-04-26 16:32:10 +02:00
|
|
|
#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_ \
|
|
|
|
};
|
|
|
|
|
2013-03-14 10:27:35 +01:00
|
|
|
|
2016-01-12 22:27:29 +01:00
|
|
|
#else /* !STANDALONE_ */
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
|
2000-12-14 00:44:37 +01:00
|
|
|
#include <ft2build.h>
|
2001-03-20 12:14:24 +01:00
|
|
|
#include "ftgrays.h"
|
2000-12-14 00:44:37 +01:00
|
|
|
#include FT_INTERNAL_OBJECTS_H
|
|
|
|
#include FT_INTERNAL_DEBUG_H
|
|
|
|
#include FT_OUTLINE_H
|
2000-06-28 01:18:39 +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 "ftsmerrs.h"
|
|
|
|
|
2009-04-26 16:32:10 +02:00
|
|
|
#include "ftspic.h"
|
|
|
|
|
2013-03-14 10:27:35 +01:00
|
|
|
#define Smooth_Err_Invalid_Mode Smooth_Err_Cannot_Render_Glyph
|
|
|
|
#define Smooth_Err_Memory_Overflow Smooth_Err_Out_Of_Memory
|
2007-12-31 00:49:14 +01:00
|
|
|
#define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory
|
2013-03-14 10:27:35 +01:00
|
|
|
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2016-01-12 22:27:29 +01:00
|
|
|
#endif /* !STANDALONE_ */
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2013-03-14 10:27:35 +01: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 )
|
2002-09-16 08:15:31 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef FT_MEM_ZERO
|
|
|
|
#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count )
|
2001-10-24 09:32:55 +02:00
|
|
|
#endif
|
|
|
|
|
2000-06-28 01:18:39 +02:00
|
|
|
/* as usual, for the speed hungry :-) */
|
|
|
|
|
2012-02-22 07:01:35 +01:00
|
|
|
#undef RAS_ARG
|
|
|
|
#undef RAS_ARG_
|
|
|
|
#undef RAS_VAR
|
|
|
|
#undef RAS_VAR_
|
|
|
|
|
2000-06-28 01:18:39 +02:00
|
|
|
#ifndef FT_STATIC_RASTER
|
|
|
|
|
2012-02-21 09:21:19 +01:00
|
|
|
#define RAS_ARG gray_PWorker worker
|
|
|
|
#define RAS_ARG_ gray_PWorker worker,
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2007-01-04 19:00:14 +01:00
|
|
|
#define RAS_VAR worker
|
|
|
|
#define RAS_VAR_ worker,
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
#else /* FT_STATIC_RASTER */
|
|
|
|
|
2016-06-29 04:56:22 +02:00
|
|
|
#define RAS_ARG void
|
2000-06-28 01:18:39 +02:00
|
|
|
#define RAS_ARG_ /* empty */
|
|
|
|
#define RAS_VAR /* empty */
|
|
|
|
#define RAS_VAR_ /* empty */
|
|
|
|
|
|
|
|
#endif /* FT_STATIC_RASTER */
|
|
|
|
|
|
|
|
|
|
|
|
/* must be at least 6 bits! */
|
|
|
|
#define PIXEL_BITS 8
|
|
|
|
|
2012-02-21 08:54:55 +01:00
|
|
|
#undef FLOOR
|
|
|
|
#undef CEILING
|
|
|
|
#undef TRUNC
|
|
|
|
#undef SCALED
|
|
|
|
|
2016-07-02 05:27:41 +02:00
|
|
|
#define ONE_PIXEL ( 1 << PIXEL_BITS )
|
2007-06-17 07:31:23 +02:00
|
|
|
#define TRUNC( x ) ( (TCoord)( (x) >> PIXEL_BITS ) )
|
2016-03-07 05:01:50 +01:00
|
|
|
#define SUBPIXELS( x ) ( (TPos)(x) * ONE_PIXEL )
|
2000-06-28 01:18:39 +02:00
|
|
|
#define FLOOR( x ) ( (x) & -ONE_PIXEL )
|
|
|
|
#define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL )
|
|
|
|
#define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL )
|
|
|
|
|
|
|
|
#if PIXEL_BITS >= 6
|
2016-03-07 05:01:50 +01:00
|
|
|
#define UPSCALE( x ) ( (x) * ( ONE_PIXEL >> 6 ) )
|
2000-06-28 01:18:39 +02:00
|
|
|
#define DOWNSCALE( x ) ( (x) >> ( PIXEL_BITS - 6 ) )
|
|
|
|
#else
|
|
|
|
#define UPSCALE( x ) ( (x) >> ( 6 - PIXEL_BITS ) )
|
2016-03-07 05:01:50 +01:00
|
|
|
#define DOWNSCALE( x ) ( (x) * ( 64 >> PIXEL_BITS ) )
|
2000-06-28 01:18:39 +02:00
|
|
|
#endif
|
|
|
|
|
2006-09-05 21:24:34 +02:00
|
|
|
|
2013-07-16 15:25:24 +02:00
|
|
|
/* Compute `dividend / divisor' and return both its quotient and */
|
2013-07-16 13:36:07 +02:00
|
|
|
/* remainder, cast to a specific type. This macro also ensures that */
|
|
|
|
/* the remainder is always positive. */
|
|
|
|
#define FT_DIV_MOD( type, dividend, divisor, quotient, remainder ) \
|
|
|
|
FT_BEGIN_STMNT \
|
|
|
|
(quotient) = (type)( (dividend) / (divisor) ); \
|
|
|
|
(remainder) = (type)( (dividend) % (divisor) ); \
|
|
|
|
if ( (remainder) < 0 ) \
|
|
|
|
{ \
|
|
|
|
(quotient)--; \
|
|
|
|
(remainder) += (type)(divisor); \
|
|
|
|
} \
|
|
|
|
FT_END_STMNT
|
|
|
|
|
|
|
|
#ifdef __arm__
|
|
|
|
/* Work around a bug specific to GCC which make the compiler fail to */
|
|
|
|
/* optimize a division and modulo operation on the same parameters */
|
|
|
|
/* into a single call to `__aeabi_idivmod'. See */
|
|
|
|
/* */
|
|
|
|
/* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43721 */
|
|
|
|
#undef FT_DIV_MOD
|
|
|
|
#define FT_DIV_MOD( type, dividend, divisor, quotient, remainder ) \
|
|
|
|
FT_BEGIN_STMNT \
|
|
|
|
(quotient) = (type)( (dividend) / (divisor) ); \
|
|
|
|
(remainder) = (type)( (dividend) - (quotient) * (divisor) ); \
|
|
|
|
if ( (remainder) < 0 ) \
|
|
|
|
{ \
|
|
|
|
(quotient)--; \
|
|
|
|
(remainder) += (type)(divisor); \
|
|
|
|
} \
|
|
|
|
FT_END_STMNT
|
|
|
|
#endif /* __arm__ */
|
|
|
|
|
|
|
|
|
2015-10-07 04:39:54 +02:00
|
|
|
/* These macros speed up repetitive divisions by replacing them */
|
2016-05-06 05:41:03 +02:00
|
|
|
/* with multiplications and right shifts. */
|
2015-10-07 04:39:54 +02:00
|
|
|
#define FT_UDIVPREP( b ) \
|
|
|
|
long b ## _r = (long)( FT_ULONG_MAX >> PIXEL_BITS ) / ( b )
|
|
|
|
#define FT_UDIV( a, b ) \
|
|
|
|
( ( (unsigned long)( a ) * (unsigned long)( b ## _r ) ) >> \
|
|
|
|
( sizeof( long ) * FT_CHAR_BIT - PIXEL_BITS ) )
|
|
|
|
|
|
|
|
|
2000-06-28 01:18:39 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* TYPE DEFINITIONS */
|
|
|
|
/* */
|
2001-11-20 02:29:34 +01:00
|
|
|
|
Fixed a bug in `glnames.py' that prevented it from generating
correct glyph names tables. This resulted in the unavailability of
certain glyphs like `Cacute', `cacute' and `lslash' in Unicode
charmaps, even if these were present in the font (causing problems
for Polish users).
* src/tools/glnames.py (mac_standard_names): Fixed.
(t1_standard_strings): Some fixes and renamed to ...
(sid_standard_names): This.
(t1_expert_encoding): Fixed.
(the_adobe_glyph_list): Renamed to ...
(adobe_glyph_names): This.
(the_adobe_glyphs): Renamed to ...
(adobe_glyph_values): This.
(dump_mac_indices, dump_glyph_list, dump_unicode_values, main):
Updated.
* src/psnames/pstables.h: Regenerated.
* src/psnames/psmodule.c (PS_Unicode_Value): Fix offset.
Fix return value.
Use `sid_standard_table' and `ps_names_to_unicode' instead of
`t1_standard_glyphs' and `names_to_unicode'.
(PS_Macintosh_Name): Use `ps_glyph_names' instead of
`standard_glyph_names'.
(PS_Standard_Strings): Use `sid_standard_names' instead of
`t1_standard_glyphs'.
* doc/BUGS, doc/TODO: New documents.
* src/cache/ftlru.c (FT_Lru_Lookup_Node): Fixed a bug that prevented
correct LRU behaviour.
setjmp() and longjmp() are now used for rollback (i.e. when memory
pool overflow occurs).
Function names are now all uniformly prefixed with `gray_'.
* src/smooth/ftgrays.c: Include <setjmp.h>.
(ErrRaster_MemoryOverflow): New macro.
(TArea): New type to store area values in each cell (using `int' was
too small on 16-bit systems). <limits.h> is included to properly
get the needed data type.
(TCell, TRaster): Use it.
(TRaster): New element `jump_buffer'.
(gray_compute_cbox): Use `RAS_ARG' as the only parameter and get
`outline' from it.
(gray_record_cell): Use longjmp().
(gray_set_cell): Use gray_record_cell() for error handling.
(gray_render_line, gray_render_conic, gray_render_cubic): Simplify.
(gray_convert_glyph_inner): New function, using setjmp().
(gray_convert_glyph): Use it.
Provide a public API to manage multiple size objects for a given
FT_Face in the new header file `ftsizes.h'.
* include/freetype/ftsizes.h: New header file,
* include/freetype/internal/ftobjs.h: Use it.
Remove declarations of FT_New_Size and FT_Done_Size (moved to
ftsizes.h).
* include/freetype/config/ftheader.h (FT_SIZES_H): New macro.
* src/base/ftobjs.c (FT_Activate_Size): New function.
* src/cache/ftcmanag.c: Include ftsizes.h.
(ftc_manager_init_size, ftc_manager_flush_size): Use
FT_Activate_Size.
2001-10-10 21:56:42 +02:00
|
|
|
/* don't change the following types to FT_Int or FT_Pos, since we might */
|
|
|
|
/* need to define them to "float" or "double" when experimenting with */
|
|
|
|
/* new algorithms */
|
2001-10-07 12:39:03 +02:00
|
|
|
|
2002-04-30 16:26:49 +02:00
|
|
|
typedef long TPos; /* sub-pixel coordinate */
|
2016-07-05 05:46:53 +02:00
|
|
|
typedef int TCoord; /* integer scanline/pixel coordinate */
|
|
|
|
typedef int TArea; /* cell areas, coordinate products */
|
2001-10-07 12:39:03 +02:00
|
|
|
|
|
|
|
|
2006-09-05 21:24:34 +02:00
|
|
|
typedef struct TCell_* PCell;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2006-09-05 21:24:34 +02:00
|
|
|
typedef struct TCell_
|
|
|
|
{
|
2016-07-02 05:27:41 +02:00
|
|
|
TCoord x; /* same with gray_TWorker.ex */
|
2012-02-21 09:21:19 +01:00
|
|
|
TCoord cover; /* same with gray_TWorker.cover */
|
|
|
|
TArea area;
|
|
|
|
PCell next;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2006-09-05 21:24:34 +02:00
|
|
|
} TCell;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2016-08-30 05:15:35 +02:00
|
|
|
typedef struct TPixmap_
|
|
|
|
{
|
|
|
|
unsigned char* origin; /* pixmap origin at the bottom-left */
|
|
|
|
int pitch; /* pitch to go down one row */
|
|
|
|
|
|
|
|
} TPixmap;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2016-06-18 05:10:22 +02:00
|
|
|
/* maximum number of gray cells in the buffer */
|
|
|
|
#if FT_RENDER_POOL_SIZE > 2048
|
|
|
|
#define FT_MAX_GRAY_POOL ( FT_RENDER_POOL_SIZE / sizeof ( TCell ) )
|
2016-06-19 04:13:23 +02:00
|
|
|
#else
|
2016-06-18 05:10:22 +02:00
|
|
|
#define FT_MAX_GRAY_POOL ( 2048 / sizeof ( TCell ) )
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2013-06-14 18:33:39 +02:00
|
|
|
#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */
|
|
|
|
/* We disable the warning `structure was padded due to */
|
|
|
|
/* __declspec(align())' in order to compile cleanly with */
|
|
|
|
/* the maximum level of warnings. */
|
|
|
|
#pragma warning( push )
|
|
|
|
#pragma warning( disable : 4324 )
|
|
|
|
#endif /* _MSC_VER */
|
|
|
|
|
2012-02-21 09:21:19 +01:00
|
|
|
typedef struct gray_TWorker_
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2014-12-07 19:29:52 +01:00
|
|
|
ft_jmp_buf jump_buffer;
|
|
|
|
|
2006-09-05 14:17:38 +02:00
|
|
|
TCoord ex, ey;
|
2016-07-02 05:27:41 +02:00
|
|
|
TCoord min_ex, max_ex;
|
|
|
|
TCoord min_ey, max_ey;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2002-04-30 16:26:49 +02:00
|
|
|
TArea area;
|
2009-07-31 17:32:08 +02:00
|
|
|
TCoord cover;
|
2002-04-30 16:26:49 +02:00
|
|
|
int invalid;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2012-02-21 09:21:19 +01:00
|
|
|
PCell cells;
|
2009-07-31 17:32:08 +02:00
|
|
|
FT_PtrDist max_cells;
|
|
|
|
FT_PtrDist num_cells;
|
2006-09-05 14:17:38 +02:00
|
|
|
|
2002-04-30 16:26:49 +02:00
|
|
|
TPos x, y;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
FT_Outline outline;
|
2016-08-30 05:15:35 +02:00
|
|
|
TPixmap target;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
FT_Raster_Span_Func render_span;
|
|
|
|
void* render_span_data;
|
|
|
|
|
2006-09-01 21:05:24 +02:00
|
|
|
PCell* ycells;
|
2001-10-31 00:51:24 +01:00
|
|
|
|
2012-02-21 09:21:19 +01:00
|
|
|
} gray_TWorker, *gray_PWorker;
|
2007-01-04 19:00:14 +01:00
|
|
|
|
2013-06-14 18:33:39 +02:00
|
|
|
#if defined( _MSC_VER )
|
|
|
|
#pragma warning( pop )
|
|
|
|
#endif
|
|
|
|
|
2007-01-04 19:00:14 +01:00
|
|
|
|
2009-04-26 16:32:10 +02:00
|
|
|
#ifndef FT_STATIC_RASTER
|
|
|
|
#define ras (*worker)
|
|
|
|
#else
|
2012-02-21 09:21:19 +01:00
|
|
|
static gray_TWorker ras;
|
2009-04-26 16:32:10 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2012-02-22 07:01:35 +01:00
|
|
|
typedef struct gray_TRaster_
|
2007-01-04 19:00:14 +01:00
|
|
|
{
|
2012-02-21 09:21:19 +01:00
|
|
|
void* memory;
|
2007-01-04 19:00:14 +01:00
|
|
|
|
2012-02-22 07:01:35 +01:00
|
|
|
} gray_TRaster, *gray_PRaster;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
|
2016-06-09 05:19:41 +02:00
|
|
|
#ifdef FT_DEBUG_LEVEL_TRACE
|
|
|
|
|
|
|
|
/* to be called while in the debugger -- */
|
|
|
|
/* this function causes a compiler warning since it is unused otherwise */
|
|
|
|
static void
|
|
|
|
gray_dump_cells( RAS_ARG )
|
|
|
|
{
|
2016-09-07 05:59:33 +02:00
|
|
|
int y;
|
2016-06-09 05:19:41 +02:00
|
|
|
|
|
|
|
|
2016-09-07 05:59:33 +02:00
|
|
|
for ( y = ras.min_ey; y < ras.max_ey; y++ )
|
2016-06-09 05:19:41 +02:00
|
|
|
{
|
2016-09-07 05:59:33 +02:00
|
|
|
PCell cell = ras.ycells[y - ras.min_ey];
|
2016-06-09 05:19:41 +02:00
|
|
|
|
|
|
|
|
2016-09-07 05:59:33 +02:00
|
|
|
printf( "%3d:", y );
|
2016-06-09 05:19:41 +02:00
|
|
|
|
2016-09-07 05:59:33 +02:00
|
|
|
for ( ; cell != NULL; cell = cell->next )
|
2016-07-05 05:46:53 +02:00
|
|
|
printf( " (%3d, c:%4d, a:%6d)",
|
2016-06-09 05:19:41 +02:00
|
|
|
cell->x, cell->cover, cell->area );
|
|
|
|
printf( "\n" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* FT_DEBUG_LEVEL_TRACE */
|
|
|
|
|
2007-01-04 19:00:14 +01:00
|
|
|
|
2000-06-28 01:18:39 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Record the current cell in the table. */
|
|
|
|
/* */
|
2006-09-05 11:45:15 +02:00
|
|
|
static PCell
|
2006-09-05 14:17:38 +02:00
|
|
|
gray_find_cell( RAS_ARG )
|
2006-09-01 21:05:24 +02:00
|
|
|
{
|
2006-09-05 11:45:15 +02:00
|
|
|
PCell *pcell, cell;
|
2016-07-02 05:27:41 +02:00
|
|
|
TCoord x = ras.ex;
|
2006-09-01 21:05:24 +02:00
|
|
|
|
2007-06-17 07:31:23 +02:00
|
|
|
|
2016-09-07 05:59:33 +02:00
|
|
|
if ( x > ras.max_ex )
|
|
|
|
x = ras.max_ex;
|
2006-09-03 08:18:45 +02:00
|
|
|
|
2016-09-07 05:59:33 +02:00
|
|
|
pcell = &ras.ycells[ras.ey - ras.min_ey];
|
2006-09-01 21:05:24 +02:00
|
|
|
for (;;)
|
|
|
|
{
|
2006-09-05 11:45:15 +02:00
|
|
|
cell = *pcell;
|
|
|
|
if ( cell == NULL || cell->x > x )
|
2006-09-01 21:05:24 +02:00
|
|
|
break;
|
|
|
|
|
2006-09-05 11:45:15 +02:00
|
|
|
if ( cell->x == x )
|
|
|
|
goto Exit;
|
2006-09-01 21:05:24 +02:00
|
|
|
|
2006-09-05 11:45:15 +02:00
|
|
|
pcell = &cell->next;
|
|
|
|
}
|
2006-09-03 08:18:45 +02:00
|
|
|
|
2006-09-01 21:05:24 +02:00
|
|
|
if ( ras.num_cells >= ras.max_cells )
|
|
|
|
ft_longjmp( ras.jump_buffer, 1 );
|
|
|
|
|
|
|
|
cell = ras.cells + ras.num_cells++;
|
|
|
|
cell->x = x;
|
|
|
|
cell->area = 0;
|
|
|
|
cell->cover = 0;
|
|
|
|
|
2006-09-05 11:45:15 +02:00
|
|
|
cell->next = *pcell;
|
|
|
|
*pcell = cell;
|
|
|
|
|
|
|
|
Exit:
|
2006-09-01 21:05:24 +02:00
|
|
|
return cell;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-07 12:39:03 +02:00
|
|
|
static void
|
|
|
|
gray_record_cell( RAS_ARG )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2013-07-16 13:36:07 +02:00
|
|
|
if ( ras.area | ras.cover )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2006-09-05 21:24:34 +02:00
|
|
|
PCell cell = gray_find_cell( RAS_VAR );
|
|
|
|
|
2006-09-01 21:05:24 +02:00
|
|
|
|
|
|
|
cell->area += ras.area;
|
|
|
|
cell->cover += ras.cover;
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-03 08:18:45 +02:00
|
|
|
|
2000-06-28 01:18:39 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Set the current cell to a new position. */
|
|
|
|
/* */
|
2001-10-07 12:39:03 +02:00
|
|
|
static void
|
2002-04-30 16:26:49 +02:00
|
|
|
gray_set_cell( RAS_ARG_ TCoord ex,
|
|
|
|
TCoord ey )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
|
|
|
/* Move the cell pointer to a new position. We set the `invalid' */
|
|
|
|
/* flag to indicate that the cell isn't part of those we're interested */
|
|
|
|
/* in during the render phase. This means that: */
|
|
|
|
/* */
|
2000-07-02 02:27:53 +02:00
|
|
|
/* . the new vertical position must be within min_ey..max_ey-1. */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* . the new horizontal position must be strictly less than max_ex */
|
|
|
|
/* */
|
|
|
|
/* Note that if a cell is to the left of the clipping region, it is */
|
|
|
|
/* actually set to the (min_ex-1) horizontal position. */
|
|
|
|
|
2006-09-05 11:45:15 +02:00
|
|
|
/* All cells that are on the left of the clipping region go to the */
|
|
|
|
/* min_ex - 1 horizontal position. */
|
2007-06-17 07:31:23 +02:00
|
|
|
if ( ex > ras.max_ex )
|
2007-06-16 18:40:37 +02:00
|
|
|
ex = ras.max_ex;
|
|
|
|
|
2016-09-07 05:59:33 +02:00
|
|
|
if ( ex < ras.min_ex )
|
|
|
|
ex = ras.min_ex - 1;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2006-09-05 11:45:15 +02:00
|
|
|
/* are we moving to a different cell ? */
|
|
|
|
if ( ex != ras.ex || ey != ras.ey )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2006-09-05 11:45:15 +02:00
|
|
|
/* record the current one if it is valid */
|
|
|
|
if ( !ras.invalid )
|
|
|
|
gray_record_cell( RAS_VAR );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
ras.area = 0;
|
|
|
|
ras.cover = 0;
|
2013-07-16 13:36:07 +02:00
|
|
|
ras.ex = ex;
|
|
|
|
ras.ey = ey;
|
|
|
|
}
|
2013-07-16 15:25:24 +02:00
|
|
|
|
2016-09-07 05:59:33 +02:00
|
|
|
ras.invalid = ( ey >= ras.max_ey || ey < ras.min_ey ||
|
|
|
|
ex >= ras.max_ex );
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-06-09 05:31:28 +02:00
|
|
|
#ifndef FT_LONG64
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Render a scanline as one or more cells. */
|
|
|
|
/* */
|
2001-10-07 12:39:03 +02:00
|
|
|
static void
|
2006-09-05 21:24:34 +02:00
|
|
|
gray_render_scanline( RAS_ARG_ TCoord ey,
|
|
|
|
TPos x1,
|
|
|
|
TCoord y1,
|
|
|
|
TPos x2,
|
|
|
|
TCoord y2 )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2016-07-02 05:27:41 +02:00
|
|
|
TCoord ex1, ex2, fx1, fx2, first, delta, mod;
|
|
|
|
TPos p, dx;
|
2009-07-31 17:32:08 +02:00
|
|
|
int incr;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
|
2006-09-05 14:17:38 +02:00
|
|
|
ex1 = TRUNC( x1 );
|
|
|
|
ex2 = TRUNC( x2 );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
/* trivial case. Happens often */
|
|
|
|
if ( y1 == y2 )
|
2001-10-07 12:39:03 +02:00
|
|
|
{
|
|
|
|
gray_set_cell( RAS_VAR_ ex2, ey );
|
|
|
|
return;
|
|
|
|
}
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2016-08-06 05:36:16 +02:00
|
|
|
fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) );
|
|
|
|
fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) );
|
|
|
|
delta = y2 - y1;
|
2016-03-19 04:21:59 +01:00
|
|
|
|
2000-06-28 01:18:39 +02:00
|
|
|
/* everything is located in a single cell. That is easy! */
|
|
|
|
/* */
|
|
|
|
if ( ex1 == ex2 )
|
|
|
|
{
|
2009-07-31 17:32:08 +02:00
|
|
|
ras.area += (TArea)(( fx1 + fx2 ) * delta);
|
2000-06-28 01:18:39 +02:00
|
|
|
ras.cover += delta;
|
2001-10-07 12:39:03 +02:00
|
|
|
return;
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ok, we'll have to render a run of adjacent cells on the same */
|
|
|
|
/* scanline... */
|
|
|
|
/* */
|
2016-08-06 05:36:16 +02:00
|
|
|
dx = x2 - x1;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2016-08-06 05:36:16 +02:00
|
|
|
if ( dx > 0 )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2016-08-06 05:36:16 +02:00
|
|
|
p = ( ONE_PIXEL - fx1 ) * delta;
|
|
|
|
first = ONE_PIXEL;
|
|
|
|
incr = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
p = fx1 * delta;
|
2000-06-28 01:18:39 +02:00
|
|
|
first = 0;
|
|
|
|
incr = -1;
|
|
|
|
dx = -dx;
|
|
|
|
}
|
|
|
|
|
2013-07-16 13:36:07 +02:00
|
|
|
FT_DIV_MOD( TCoord, p, dx, delta, mod );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2009-07-31 17:32:08 +02:00
|
|
|
ras.area += (TArea)(( fx1 + first ) * delta);
|
2000-06-28 01:18:39 +02:00
|
|
|
ras.cover += delta;
|
|
|
|
|
|
|
|
ex1 += incr;
|
2001-10-07 12:39:03 +02:00
|
|
|
gray_set_cell( RAS_VAR_ ex1, ey );
|
2000-06-28 01:18:39 +02:00
|
|
|
y1 += delta;
|
|
|
|
|
|
|
|
if ( ex1 != ex2 )
|
|
|
|
{
|
2013-06-04 10:30:48 +02:00
|
|
|
TCoord lift, rem;
|
|
|
|
|
|
|
|
|
2013-07-16 13:36:07 +02:00
|
|
|
p = ONE_PIXEL * ( y2 - y1 + delta );
|
|
|
|
FT_DIV_MOD( TCoord, p, dx, lift, rem );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
* 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
|
|
|
mod -= (int)dx;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2015-09-05 05:14:46 +02:00
|
|
|
do
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
|
|
|
delta = lift;
|
|
|
|
mod += rem;
|
|
|
|
if ( mod >= 0 )
|
|
|
|
{
|
2002-09-28 18:40:57 +02:00
|
|
|
mod -= (TCoord)dx;
|
2000-06-28 01:18:39 +02:00
|
|
|
delta++;
|
|
|
|
}
|
|
|
|
|
2009-07-31 17:32:08 +02:00
|
|
|
ras.area += (TArea)(ONE_PIXEL * delta);
|
2000-06-28 01:18:39 +02:00
|
|
|
ras.cover += delta;
|
|
|
|
y1 += delta;
|
|
|
|
ex1 += incr;
|
2001-10-07 12:39:03 +02:00
|
|
|
gray_set_cell( RAS_VAR_ ex1, ey );
|
2015-09-05 05:14:46 +02:00
|
|
|
} while ( ex1 != ex2 );
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
delta = y2 - y1;
|
2009-07-31 17:32:08 +02:00
|
|
|
ras.area += (TArea)(( fx2 + ONE_PIXEL - first ) * delta);
|
2000-06-28 01:18:39 +02:00
|
|
|
ras.cover += delta;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Render a given line as a series of scanlines. */
|
|
|
|
/* */
|
2001-10-07 12:39:03 +02:00
|
|
|
static void
|
|
|
|
gray_render_line( RAS_ARG_ TPos to_x,
|
|
|
|
TPos to_y )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2016-07-02 05:27:41 +02:00
|
|
|
TCoord ey1, ey2, fy1, fy2, first, delta, mod;
|
|
|
|
TPos p, dx, dy, x, x2;
|
|
|
|
int incr;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
|
2015-10-01 05:08:53 +02:00
|
|
|
ey1 = TRUNC( ras.y );
|
2006-09-05 21:24:34 +02:00
|
|
|
ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
/* perform vertical clipping */
|
2015-09-07 19:47:36 +02:00
|
|
|
if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) ||
|
|
|
|
( ey1 < ras.min_ey && ey2 < ras.min_ey ) )
|
|
|
|
goto End;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2016-03-19 04:21:59 +01:00
|
|
|
fy1 = (TCoord)( ras.y - SUBPIXELS( ey1 ) );
|
|
|
|
fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) );
|
|
|
|
|
2000-06-28 01:18:39 +02:00
|
|
|
/* everything is on a single scanline */
|
|
|
|
if ( ey1 == ey2 )
|
|
|
|
{
|
2001-10-07 12:39:03 +02:00
|
|
|
gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, to_x, fy2 );
|
2000-06-28 01:18:39 +02:00
|
|
|
goto End;
|
|
|
|
}
|
|
|
|
|
2016-03-19 04:21:59 +01:00
|
|
|
dx = to_x - ras.x;
|
|
|
|
dy = to_y - ras.y;
|
|
|
|
|
2002-01-09 22:01:18 +01:00
|
|
|
/* vertical line - avoid calling gray_render_scanline */
|
|
|
|
if ( dx == 0 )
|
2002-01-09 11:48:25 +01:00
|
|
|
{
|
2002-10-05 08:57:53 +02:00
|
|
|
TCoord ex = TRUNC( ras.x );
|
|
|
|
TCoord two_fx = (TCoord)( ( ras.x - SUBPIXELS( ex ) ) << 1 );
|
2009-07-31 17:30:20 +02:00
|
|
|
TArea area;
|
2002-01-09 22:01:18 +01:00
|
|
|
|
2002-01-09 11:48:25 +01:00
|
|
|
|
2016-08-06 05:36:16 +02:00
|
|
|
if ( dy > 0)
|
|
|
|
{
|
|
|
|
first = ONE_PIXEL;
|
|
|
|
incr = 1;
|
|
|
|
}
|
|
|
|
else
|
2002-01-09 11:48:25 +01:00
|
|
|
{
|
|
|
|
first = 0;
|
|
|
|
incr = -1;
|
|
|
|
}
|
|
|
|
|
2016-07-02 05:27:41 +02:00
|
|
|
delta = first - fy1;
|
2002-01-09 11:48:25 +01:00
|
|
|
ras.area += (TArea)two_fx * delta;
|
|
|
|
ras.cover += delta;
|
|
|
|
ey1 += incr;
|
|
|
|
|
2009-04-26 16:32:10 +02:00
|
|
|
gray_set_cell( RAS_VAR_ ex, ey1 );
|
2002-01-09 11:48:25 +01:00
|
|
|
|
2016-07-02 05:27:41 +02:00
|
|
|
delta = first + first - ONE_PIXEL;
|
2002-01-09 11:48:25 +01:00
|
|
|
area = (TArea)two_fx * delta;
|
2002-09-28 18:40:57 +02:00
|
|
|
while ( ey1 != ey2 )
|
2002-01-09 11:48:25 +01:00
|
|
|
{
|
|
|
|
ras.area += area;
|
|
|
|
ras.cover += delta;
|
|
|
|
ey1 += incr;
|
2006-09-05 21:24:34 +02:00
|
|
|
|
2009-04-26 16:32:10 +02:00
|
|
|
gray_set_cell( RAS_VAR_ ex, ey1 );
|
2002-01-09 11:48:25 +01:00
|
|
|
}
|
|
|
|
|
2016-07-02 05:27:41 +02:00
|
|
|
delta = fy2 - ONE_PIXEL + first;
|
2002-01-09 11:48:25 +01:00
|
|
|
ras.area += (TArea)two_fx * delta;
|
|
|
|
ras.cover += delta;
|
2006-09-05 21:24:34 +02:00
|
|
|
|
2002-01-09 11:48:25 +01:00
|
|
|
goto End;
|
|
|
|
}
|
|
|
|
|
2000-07-02 02:27:53 +02:00
|
|
|
/* ok, we have to render several scanlines */
|
2016-08-06 05:36:16 +02:00
|
|
|
if ( dy > 0)
|
|
|
|
{
|
|
|
|
p = ( ONE_PIXEL - fy1 ) * dx;
|
|
|
|
first = ONE_PIXEL;
|
|
|
|
incr = 1;
|
|
|
|
}
|
|
|
|
else
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2002-10-05 08:57:53 +02:00
|
|
|
p = fy1 * dx;
|
2000-06-28 01:18:39 +02:00
|
|
|
first = 0;
|
|
|
|
incr = -1;
|
|
|
|
dy = -dy;
|
|
|
|
}
|
|
|
|
|
2016-07-02 05:27:41 +02:00
|
|
|
FT_DIV_MOD( TCoord, p, dy, delta, mod );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
x = ras.x + delta;
|
2016-07-02 05:27:41 +02:00
|
|
|
gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, first );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
ey1 += incr;
|
2002-10-05 08:57:53 +02:00
|
|
|
gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
if ( ey1 != ey2 )
|
|
|
|
{
|
2016-07-02 05:27:41 +02:00
|
|
|
TCoord lift, rem;
|
|
|
|
|
|
|
|
|
|
|
|
p = ONE_PIXEL * dx;
|
|
|
|
FT_DIV_MOD( TCoord, p, dy, lift, rem );
|
|
|
|
mod -= (TCoord)dy;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2015-09-05 05:14:46 +02:00
|
|
|
do
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
|
|
|
delta = lift;
|
|
|
|
mod += rem;
|
|
|
|
if ( mod >= 0 )
|
|
|
|
{
|
2016-07-02 05:27:41 +02:00
|
|
|
mod -= (TCoord)dy;
|
2000-06-28 01:18:39 +02:00
|
|
|
delta++;
|
|
|
|
}
|
|
|
|
|
|
|
|
x2 = x + delta;
|
2016-07-02 05:27:41 +02:00
|
|
|
gray_render_scanline( RAS_VAR_ ey1,
|
|
|
|
x, ONE_PIXEL - first,
|
|
|
|
x2, first );
|
2000-06-28 01:18:39 +02:00
|
|
|
x = x2;
|
2001-10-07 12:39:03 +02:00
|
|
|
|
2000-06-28 01:18:39 +02:00
|
|
|
ey1 += incr;
|
2001-10-07 12:39:03 +02:00
|
|
|
gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 );
|
2015-09-05 05:14:46 +02:00
|
|
|
} while ( ey1 != ey2 );
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
2016-07-02 05:27:41 +02:00
|
|
|
gray_render_scanline( RAS_VAR_ ey1,
|
|
|
|
x, ONE_PIXEL - first,
|
|
|
|
to_x, fy2 );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
End:
|
|
|
|
ras.x = to_x;
|
|
|
|
ras.y = to_y;
|
|
|
|
}
|
|
|
|
|
2015-10-07 04:39:54 +02:00
|
|
|
#else
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Render a straight line across multiple cells in any direction. */
|
|
|
|
/* */
|
|
|
|
static void
|
|
|
|
gray_render_line( RAS_ARG_ TPos to_x,
|
|
|
|
TPos to_y )
|
|
|
|
{
|
|
|
|
TPos dx, dy, fx1, fy1, fx2, fy2;
|
|
|
|
TCoord ex1, ex2, ey1, ey2;
|
|
|
|
|
|
|
|
|
|
|
|
ey1 = TRUNC( ras.y );
|
|
|
|
ey2 = TRUNC( to_y );
|
|
|
|
|
|
|
|
/* perform vertical clipping */
|
|
|
|
if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) ||
|
|
|
|
( ey1 < ras.min_ey && ey2 < ras.min_ey ) )
|
|
|
|
goto End;
|
|
|
|
|
2016-03-19 04:21:59 +01:00
|
|
|
ex1 = TRUNC( ras.x );
|
|
|
|
ex2 = TRUNC( to_x );
|
2015-10-07 04:39:54 +02:00
|
|
|
|
|
|
|
fx1 = ras.x - SUBPIXELS( ex1 );
|
|
|
|
fy1 = ras.y - SUBPIXELS( ey1 );
|
|
|
|
|
2016-03-19 04:21:59 +01:00
|
|
|
dx = to_x - ras.x;
|
|
|
|
dy = to_y - ras.y;
|
|
|
|
|
2015-10-07 04:39:54 +02:00
|
|
|
if ( ex1 == ex2 && ey1 == ey2 ) /* inside one cell */
|
|
|
|
;
|
|
|
|
else if ( dy == 0 ) /* ex1 != ex2 */ /* any horizontal line */
|
|
|
|
{
|
|
|
|
ex1 = ex2;
|
|
|
|
gray_set_cell( RAS_VAR_ ex1, ey1 );
|
|
|
|
}
|
|
|
|
else if ( dx == 0 )
|
|
|
|
{
|
|
|
|
if ( dy > 0 ) /* vertical line up */
|
|
|
|
do
|
|
|
|
{
|
|
|
|
fy2 = ONE_PIXEL;
|
|
|
|
ras.cover += ( fy2 - fy1 );
|
|
|
|
ras.area += ( fy2 - fy1 ) * fx1 * 2;
|
|
|
|
fy1 = 0;
|
|
|
|
ey1++;
|
|
|
|
gray_set_cell( RAS_VAR_ ex1, ey1 );
|
|
|
|
} while ( ey1 != ey2 );
|
|
|
|
else /* vertical line down */
|
|
|
|
do
|
|
|
|
{
|
|
|
|
fy2 = 0;
|
|
|
|
ras.cover += ( fy2 - fy1 );
|
|
|
|
ras.area += ( fy2 - fy1 ) * fx1 * 2;
|
|
|
|
fy1 = ONE_PIXEL;
|
|
|
|
ey1--;
|
|
|
|
gray_set_cell( RAS_VAR_ ex1, ey1 );
|
|
|
|
} while ( ey1 != ey2 );
|
|
|
|
}
|
|
|
|
else /* any other line */
|
|
|
|
{
|
2016-07-05 05:46:53 +02:00
|
|
|
TPos prod = dx * fy1 - dy * fx1;
|
2015-10-07 04:39:54 +02:00
|
|
|
FT_UDIVPREP( dx );
|
|
|
|
FT_UDIVPREP( dy );
|
|
|
|
|
|
|
|
|
|
|
|
/* The fundamental value `prod' determines which side and the */
|
|
|
|
/* exact coordinate where the line exits current cell. It is */
|
|
|
|
/* also easily updated when moving from one cell to the next. */
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if ( prod <= 0 &&
|
|
|
|
prod - dx * ONE_PIXEL > 0 ) /* left */
|
|
|
|
{
|
|
|
|
fx2 = 0;
|
|
|
|
fy2 = (TPos)FT_UDIV( -prod, -dx );
|
|
|
|
prod -= dy * ONE_PIXEL;
|
|
|
|
ras.cover += ( fy2 - fy1 );
|
|
|
|
ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 );
|
|
|
|
fx1 = ONE_PIXEL;
|
|
|
|
fy1 = fy2;
|
|
|
|
ex1--;
|
|
|
|
}
|
|
|
|
else if ( prod - dx * ONE_PIXEL <= 0 &&
|
|
|
|
prod - dx * ONE_PIXEL + dy * ONE_PIXEL > 0 ) /* up */
|
|
|
|
{
|
|
|
|
prod -= dx * ONE_PIXEL;
|
|
|
|
fx2 = (TPos)FT_UDIV( -prod, dy );
|
|
|
|
fy2 = ONE_PIXEL;
|
|
|
|
ras.cover += ( fy2 - fy1 );
|
|
|
|
ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 );
|
|
|
|
fx1 = fx2;
|
|
|
|
fy1 = 0;
|
|
|
|
ey1++;
|
|
|
|
}
|
|
|
|
else if ( prod - dx * ONE_PIXEL + dy * ONE_PIXEL <= 0 &&
|
|
|
|
prod + dy * ONE_PIXEL >= 0 ) /* right */
|
|
|
|
{
|
|
|
|
prod += dy * ONE_PIXEL;
|
|
|
|
fx2 = ONE_PIXEL;
|
|
|
|
fy2 = (TPos)FT_UDIV( prod, dx );
|
|
|
|
ras.cover += ( fy2 - fy1 );
|
|
|
|
ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 );
|
|
|
|
fx1 = 0;
|
|
|
|
fy1 = fy2;
|
|
|
|
ex1++;
|
|
|
|
}
|
|
|
|
else /* ( prod + dy * ONE_PIXEL < 0 &&
|
|
|
|
prod > 0 ) down */
|
|
|
|
{
|
|
|
|
fx2 = (TPos)FT_UDIV( prod, -dy );
|
|
|
|
fy2 = 0;
|
|
|
|
prod += dx * ONE_PIXEL;
|
|
|
|
ras.cover += ( fy2 - fy1 );
|
|
|
|
ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 );
|
|
|
|
fx1 = fx2;
|
|
|
|
fy1 = ONE_PIXEL;
|
|
|
|
ey1--;
|
|
|
|
}
|
|
|
|
|
|
|
|
gray_set_cell( RAS_VAR_ ex1, ey1 );
|
|
|
|
} while ( ex1 != ex2 || ey1 != ey2 );
|
|
|
|
}
|
|
|
|
|
|
|
|
fx2 = to_x - SUBPIXELS( ex2 );
|
|
|
|
fy2 = to_y - SUBPIXELS( ey2 );
|
|
|
|
|
|
|
|
ras.cover += ( fy2 - fy1 );
|
|
|
|
ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 );
|
|
|
|
|
|
|
|
End:
|
|
|
|
ras.x = to_x;
|
|
|
|
ras.y = to_y;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
2001-10-07 12:39:03 +02:00
|
|
|
gray_split_conic( FT_Vector* base )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
|
|
|
TPos 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-07 12:39:03 +02:00
|
|
|
static void
|
2016-05-27 05:46:38 +02:00
|
|
|
gray_render_conic( RAS_ARG_ const FT_Vector* control,
|
|
|
|
const FT_Vector* to )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2016-05-27 05:46:38 +02:00
|
|
|
FT_Vector bez_stack[16 * 2 + 1]; /* enough to accommodate bisections */
|
|
|
|
FT_Vector* arc = bez_stack;
|
2000-06-28 01:18:39 +02:00
|
|
|
TPos dx, dy;
|
2016-05-27 05:46:38 +02:00
|
|
|
int draw, split;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
|
2016-05-27 05:46:38 +02:00
|
|
|
arc[0].x = UPSCALE( to->x );
|
|
|
|
arc[0].y = UPSCALE( to->y );
|
|
|
|
arc[1].x = UPSCALE( control->x );
|
|
|
|
arc[1].y = UPSCALE( control->y );
|
|
|
|
arc[2].x = ras.x;
|
|
|
|
arc[2].y = ras.y;
|
|
|
|
|
|
|
|
/* short-cut the arc that crosses the current band */
|
|
|
|
if ( ( TRUNC( arc[0].y ) >= ras.max_ey &&
|
|
|
|
TRUNC( arc[1].y ) >= ras.max_ey &&
|
|
|
|
TRUNC( arc[2].y ) >= ras.max_ey ) ||
|
|
|
|
( TRUNC( arc[0].y ) < ras.min_ey &&
|
|
|
|
TRUNC( arc[1].y ) < ras.min_ey &&
|
|
|
|
TRUNC( arc[2].y ) < ras.min_ey ) )
|
|
|
|
{
|
|
|
|
ras.x = arc[0].x;
|
|
|
|
ras.y = arc[0].y;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-11-02 16:01:03 +01:00
|
|
|
dx = FT_ABS( arc[2].x + arc[0].x - 2 * arc[1].x );
|
|
|
|
dy = FT_ABS( arc[2].y + arc[0].y - 2 * arc[1].y );
|
2000-06-28 01:18:39 +02:00
|
|
|
if ( dx < dy )
|
|
|
|
dx = dy;
|
|
|
|
|
2016-05-06 05:41:03 +02:00
|
|
|
/* We can calculate the number of necessary bisections because */
|
|
|
|
/* each bisection predictably reduces deviation exactly 4-fold. */
|
2016-05-27 05:46:38 +02:00
|
|
|
/* Even 32-bit deviation would vanish after 16 bisections. */
|
|
|
|
draw = 1;
|
2016-05-06 05:41:03 +02:00
|
|
|
while ( dx > ONE_PIXEL / 4 )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2016-05-27 05:46:38 +02:00
|
|
|
dx >>= 2;
|
|
|
|
draw <<= 1;
|
2016-05-06 05:41:03 +02:00
|
|
|
}
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2016-05-06 05:41:03 +02:00
|
|
|
/* We use decrement counter to count the total number of segments */
|
|
|
|
/* to draw starting from 2^level. Before each draw we split as */
|
|
|
|
/* many times as there are trailing zeros in the counter. */
|
2011-03-17 20:24:57 +01:00
|
|
|
do
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2016-05-06 05:41:03 +02:00
|
|
|
split = 1;
|
|
|
|
while ( ( draw & split ) == 0 )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2001-10-07 12:39:03 +02:00
|
|
|
gray_split_conic( arc );
|
2000-06-28 01:18:39 +02:00
|
|
|
arc += 2;
|
2016-05-06 05:41:03 +02:00
|
|
|
split <<= 1;
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
2010-09-20 09:29:23 +02:00
|
|
|
gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
|
|
|
|
arc -= 2;
|
2006-09-05 21:24:34 +02:00
|
|
|
|
2016-05-06 05:41:03 +02:00
|
|
|
} while ( --draw );
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
2001-10-07 12:39:03 +02:00
|
|
|
gray_split_cubic( FT_Vector* base )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
|
|
|
TPos 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 ) / 2;
|
|
|
|
base[5].x = b = ( base[3].x + d ) / 2;
|
|
|
|
c = ( c + d ) / 2;
|
|
|
|
base[2].x = a = ( a + c ) / 2;
|
|
|
|
base[4].x = b = ( b + c ) / 2;
|
|
|
|
base[3].x = ( a + b ) / 2;
|
|
|
|
|
|
|
|
base[6].y = base[3].y;
|
|
|
|
c = base[1].y;
|
|
|
|
d = base[2].y;
|
|
|
|
base[1].y = a = ( base[0].y + c ) / 2;
|
|
|
|
base[5].y = b = ( base[3].y + d ) / 2;
|
|
|
|
c = ( c + d ) / 2;
|
|
|
|
base[2].y = a = ( a + c ) / 2;
|
|
|
|
base[4].y = b = ( b + c ) / 2;
|
|
|
|
base[3].y = ( a + b ) / 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-07 12:39:03 +02:00
|
|
|
static void
|
2016-05-27 05:46:38 +02:00
|
|
|
gray_render_cubic( RAS_ARG_ const FT_Vector* control1,
|
|
|
|
const FT_Vector* control2,
|
|
|
|
const FT_Vector* to )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2016-05-27 05:46:38 +02:00
|
|
|
FT_Vector bez_stack[16 * 3 + 1]; /* enough to accommodate bisections */
|
|
|
|
FT_Vector* arc = bez_stack;
|
2016-03-19 04:21:59 +01:00
|
|
|
TPos dx, dy, dx_, dy_;
|
|
|
|
TPos dx1, dy1, dx2, dy2;
|
|
|
|
TPos L, s, s_limit;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
|
2016-05-27 05:46:38 +02:00
|
|
|
arc[0].x = UPSCALE( to->x );
|
|
|
|
arc[0].y = UPSCALE( to->y );
|
|
|
|
arc[1].x = UPSCALE( control2->x );
|
|
|
|
arc[1].y = UPSCALE( control2->y );
|
|
|
|
arc[2].x = UPSCALE( control1->x );
|
|
|
|
arc[2].y = UPSCALE( control1->y );
|
|
|
|
arc[3].x = ras.x;
|
|
|
|
arc[3].y = ras.y;
|
|
|
|
|
|
|
|
/* short-cut the arc that crosses the current band */
|
|
|
|
if ( ( TRUNC( arc[0].y ) >= ras.max_ey &&
|
|
|
|
TRUNC( arc[1].y ) >= ras.max_ey &&
|
|
|
|
TRUNC( arc[2].y ) >= ras.max_ey &&
|
|
|
|
TRUNC( arc[3].y ) >= ras.max_ey ) ||
|
|
|
|
( TRUNC( arc[0].y ) < ras.min_ey &&
|
|
|
|
TRUNC( arc[1].y ) < ras.min_ey &&
|
|
|
|
TRUNC( arc[2].y ) < ras.min_ey &&
|
|
|
|
TRUNC( arc[3].y ) < ras.min_ey ) )
|
|
|
|
{
|
|
|
|
ras.x = arc[0].x;
|
|
|
|
ras.y = arc[0].y;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-09-17 09:21:25 +02:00
|
|
|
for (;;)
|
|
|
|
{
|
2010-09-20 09:29:23 +02:00
|
|
|
/* Decide whether to split or draw. See `Rapid Termination */
|
|
|
|
/* Evaluation for Recursive Subdivision of Bezier Curves' by Thomas */
|
|
|
|
/* F. Hain, at */
|
|
|
|
/* http://www.cis.southalabama.edu/~hain/general/Publications/Bezier/Camera-ready%20CISST02%202.pdf */
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2016-03-19 04:21:59 +01:00
|
|
|
/* dx and dy are x and y components of the P0-P3 chord vector. */
|
|
|
|
dx = dx_ = arc[3].x - arc[0].x;
|
|
|
|
dy = dy_ = arc[3].y - arc[0].y;
|
2010-09-20 09:29:23 +02:00
|
|
|
|
2016-03-19 04:21:59 +01:00
|
|
|
L = FT_HYPOT( dx_, dy_ );
|
2010-09-20 09:29:23 +02:00
|
|
|
|
2016-03-19 04:21:59 +01:00
|
|
|
/* Avoid possible arithmetic overflow below by splitting. */
|
|
|
|
if ( L > 32767 )
|
|
|
|
goto Split;
|
2014-10-30 03:24:24 +01:00
|
|
|
|
2016-03-19 04:21:59 +01:00
|
|
|
/* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */
|
|
|
|
s_limit = L * (TPos)( ONE_PIXEL / 6 );
|
2010-09-20 09:29:23 +02:00
|
|
|
|
2016-03-19 04:21:59 +01:00
|
|
|
/* s is L * the perpendicular distance from P1 to the line P0-P3. */
|
|
|
|
dx1 = arc[1].x - arc[0].x;
|
|
|
|
dy1 = arc[1].y - arc[0].y;
|
|
|
|
s = FT_ABS( dy * dx1 - dx * dy1 );
|
2010-09-20 09:29:23 +02:00
|
|
|
|
2016-03-19 04:21:59 +01:00
|
|
|
if ( s > s_limit )
|
|
|
|
goto Split;
|
2010-09-20 09:29:23 +02:00
|
|
|
|
2016-03-19 04:21:59 +01:00
|
|
|
/* s is L * the perpendicular distance from P2 to the line P0-P3. */
|
|
|
|
dx2 = arc[2].x - arc[0].x;
|
|
|
|
dy2 = arc[2].y - arc[0].y;
|
|
|
|
s = FT_ABS( dy * dx2 - dx * dy2 );
|
2010-09-20 09:29:23 +02:00
|
|
|
|
2016-03-19 04:21:59 +01:00
|
|
|
if ( s > s_limit )
|
|
|
|
goto Split;
|
2010-09-20 09:29:23 +02:00
|
|
|
|
2016-03-19 04:21:59 +01:00
|
|
|
/* Split super curvy segments where the off points are so far
|
|
|
|
from the chord that the angles P0-P1-P3 or P0-P2-P3 become
|
|
|
|
acute as detected by appropriate dot products. */
|
|
|
|
if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 ||
|
|
|
|
dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 )
|
|
|
|
goto Split;
|
2010-09-20 09:29:23 +02:00
|
|
|
|
|
|
|
gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
|
|
|
|
|
2016-05-27 05:46:38 +02:00
|
|
|
if ( arc == bez_stack )
|
2010-09-20 09:29:23 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
arc -= 3;
|
2016-03-19 04:21:59 +01:00
|
|
|
continue;
|
|
|
|
|
|
|
|
Split:
|
|
|
|
gray_split_cubic( arc );
|
|
|
|
arc += 3;
|
2010-09-20 09:29:23 +02:00
|
|
|
}
|
|
|
|
}
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static int
|
* 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
|
|
|
gray_move_to( const FT_Vector* to,
|
2012-02-21 09:21:19 +01:00
|
|
|
gray_PWorker worker )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
|
|
|
TPos x, y;
|
|
|
|
|
|
|
|
|
|
|
|
/* start to a new position */
|
|
|
|
x = UPSCALE( to->x );
|
|
|
|
y = UPSCALE( to->y );
|
2001-11-20 02:29:34 +01:00
|
|
|
|
2016-09-07 05:24:17 +02:00
|
|
|
gray_set_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) );
|
2001-11-20 02:29:34 +01:00
|
|
|
|
2016-05-27 05:46:38 +02:00
|
|
|
ras.x = x;
|
|
|
|
ras.y = y;
|
2000-06-28 01:18:39 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static int
|
* 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
|
|
|
gray_line_to( const FT_Vector* to,
|
2012-02-21 09:21:19 +01:00
|
|
|
gray_PWorker worker )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2009-04-26 16:32:10 +02:00
|
|
|
gray_render_line( RAS_VAR_ UPSCALE( to->x ), UPSCALE( to->y ) );
|
2001-10-07 12:39:03 +02:00
|
|
|
return 0;
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static int
|
* 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
|
|
|
gray_conic_to( const FT_Vector* control,
|
|
|
|
const FT_Vector* to,
|
2012-02-21 09:21:19 +01:00
|
|
|
gray_PWorker worker )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2016-05-27 05:46:38 +02:00
|
|
|
gray_render_conic( RAS_VAR_ control, to );
|
2001-10-07 12:39:03 +02:00
|
|
|
return 0;
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static int
|
* 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
|
|
|
gray_cubic_to( const FT_Vector* control1,
|
|
|
|
const FT_Vector* control2,
|
|
|
|
const FT_Vector* to,
|
2012-02-21 09:21:19 +01:00
|
|
|
gray_PWorker worker )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2016-05-27 05:46:38 +02:00
|
|
|
gray_render_cubic( RAS_VAR_ control1, control2, to );
|
2001-10-07 12:39:03 +02:00
|
|
|
return 0;
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
2002-04-30 16:26:49 +02:00
|
|
|
gray_hline( RAS_ARG_ TCoord x,
|
|
|
|
TCoord y,
|
2016-07-02 05:27:41 +02:00
|
|
|
TArea area,
|
2009-07-31 17:32:08 +02:00
|
|
|
TCoord acount )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2016-08-31 05:21:23 +02:00
|
|
|
int coverage;
|
|
|
|
FT_Span span;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* compute the coverage line's coverage, depending on the */
|
|
|
|
/* outline fill rule */
|
|
|
|
/* */
|
|
|
|
/* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */
|
|
|
|
/* */
|
2002-09-28 18:40:57 +02:00
|
|
|
coverage = (int)( area >> ( PIXEL_BITS * 2 + 1 - 8 ) );
|
|
|
|
/* use range 0..256 */
|
2002-04-11 16:21:16 +02:00
|
|
|
if ( coverage < 0 )
|
|
|
|
coverage = -coverage;
|
|
|
|
|
* 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 ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2002-04-11 16:21:16 +02:00
|
|
|
coverage &= 511;
|
2002-06-11 01:03:35 +02:00
|
|
|
|
2000-06-28 01:18:39 +02:00
|
|
|
if ( coverage > 256 )
|
|
|
|
coverage = 512 - coverage;
|
|
|
|
else if ( coverage == 256 )
|
|
|
|
coverage = 255;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* normal non-zero winding rule */
|
|
|
|
if ( coverage >= 256 )
|
|
|
|
coverage = 255;
|
|
|
|
}
|
|
|
|
|
2016-09-02 04:56:24 +02:00
|
|
|
if ( ras.render_span ) /* for FT_RASTER_FLAG_DIRECT only */
|
|
|
|
{
|
2016-09-07 05:59:33 +02:00
|
|
|
span.x = (short)x;
|
2016-09-02 04:56:24 +02:00
|
|
|
span.len = (unsigned short)acount;
|
|
|
|
span.coverage = (unsigned char)coverage;
|
|
|
|
|
2016-09-07 05:59:33 +02:00
|
|
|
ras.render_span( y, 1, &span, ras.render_span_data );
|
2016-09-02 04:56:24 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-09-07 05:59:33 +02:00
|
|
|
unsigned char* q = ras.target.origin - ras.target.pitch * y + x;
|
2016-09-02 22:45:14 +02:00
|
|
|
unsigned char c = (unsigned char)coverage;
|
2016-09-02 04:56:24 +02:00
|
|
|
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2016-09-02 04:56:24 +02:00
|
|
|
/* For small-spans it is faster to do it by ourselves than
|
|
|
|
* calling `memset'. This is mainly due to the cost of the
|
|
|
|
* function call.
|
|
|
|
*/
|
|
|
|
switch ( acount )
|
|
|
|
{
|
2016-09-02 22:45:14 +02:00
|
|
|
case 7: *q++ = c;
|
|
|
|
case 6: *q++ = c;
|
|
|
|
case 5: *q++ = c;
|
|
|
|
case 4: *q++ = c;
|
|
|
|
case 3: *q++ = c;
|
|
|
|
case 2: *q++ = c;
|
|
|
|
case 1: *q = c;
|
2016-09-02 04:56:24 +02:00
|
|
|
case 0: break;
|
|
|
|
default:
|
2016-09-02 22:45:14 +02:00
|
|
|
FT_MEM_SET( q, c, acount );
|
2016-09-02 04:56:24 +02:00
|
|
|
}
|
|
|
|
}
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
2016-06-28 06:30:58 +02:00
|
|
|
gray_sweep( RAS_ARG )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2016-09-07 05:59:33 +02:00
|
|
|
int y;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2006-09-03 08:18:45 +02:00
|
|
|
|
2001-02-23 18:47:41 +01:00
|
|
|
if ( ras.num_cells == 0 )
|
|
|
|
return;
|
2001-11-20 02:29:34 +01:00
|
|
|
|
2008-09-20 14:20:21 +02:00
|
|
|
FT_TRACE7(( "gray_sweep: start\n" ));
|
|
|
|
|
2016-09-07 05:59:33 +02:00
|
|
|
for ( y = ras.min_ey; y < ras.max_ey; y++ )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2016-09-07 05:59:33 +02:00
|
|
|
PCell cell = ras.ycells[y - ras.min_ey];
|
2006-09-01 21:05:24 +02:00
|
|
|
TCoord cover = 0;
|
2016-09-07 05:59:33 +02:00
|
|
|
TCoord x = ras.min_ex;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2006-09-03 08:18:45 +02:00
|
|
|
|
2006-09-01 21:05:24 +02:00
|
|
|
for ( ; cell != NULL; cell = cell->next )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2016-07-02 05:27:41 +02:00
|
|
|
TArea area;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2006-09-03 08:18:45 +02:00
|
|
|
|
2016-09-08 05:19:57 +02:00
|
|
|
if ( cover != 0 && cell->x > x )
|
2016-09-07 05:59:33 +02:00
|
|
|
gray_hline( RAS_VAR_ x, y, (TArea)cover * ( ONE_PIXEL * 2 ),
|
2006-09-03 08:18:45 +02:00
|
|
|
cell->x - x );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2006-09-01 21:05:24 +02:00
|
|
|
cover += cell->cover;
|
2016-07-02 05:27:41 +02:00
|
|
|
area = (TArea)cover * ( ONE_PIXEL * 2 ) - cell->area;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2016-09-07 05:59:33 +02:00
|
|
|
if ( area != 0 && cell->x >= ras.min_ex )
|
|
|
|
gray_hline( RAS_VAR_ cell->x, y, area, 1 );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2006-09-01 21:05:24 +02:00
|
|
|
x = cell->x + 1;
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
2006-09-01 21:05:24 +02:00
|
|
|
if ( cover != 0 )
|
2016-09-07 05:59:33 +02:00
|
|
|
gray_hline( RAS_VAR_ x, y, (TArea)cover * ( ONE_PIXEL * 2 ),
|
|
|
|
ras.max_ex - x );
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
2008-09-20 14:20:21 +02:00
|
|
|
FT_TRACE7(( "gray_sweep: end\n" ));
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
2006-09-03 08:18:45 +02:00
|
|
|
|
2016-01-12 22:27:29 +01:00
|
|
|
#ifdef STANDALONE_
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
2016-06-22 06:04:08 +02:00
|
|
|
/* The following functions should only compile in stand-alone mode, */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* i.e., when building this component without the rest of FreeType. */
|
|
|
|
/* */
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* FT_Outline_Decompose */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
2008-09-20 13:50:47 +02:00
|
|
|
/* Walk over an outline's structure to decompose it into individual */
|
|
|
|
/* segments and Bézier arcs. This function is also able to emit */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* `move to' and `close to' operations to indicate the start and end */
|
|
|
|
/* of new contours in the outline. */
|
|
|
|
/* */
|
|
|
|
/* <Input> */
|
2002-04-30 08:37:52 +02:00
|
|
|
/* outline :: A pointer to the source target. */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* */
|
2008-09-20 13:50:47 +02:00
|
|
|
/* func_interface :: A table of `emitters', i.e., function pointers */
|
2002-04-30 08:37:52 +02:00
|
|
|
/* called during decomposition to indicate path */
|
|
|
|
/* operations. */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* */
|
2008-09-20 13:50:47 +02:00
|
|
|
/* <InOut> */
|
2002-04-30 08:37:52 +02:00
|
|
|
/* user :: A typeless pointer which is passed to each */
|
|
|
|
/* emitter during the decomposition. It can be */
|
|
|
|
/* used to store the state during the */
|
|
|
|
/* decomposition. */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* */
|
|
|
|
/* <Return> */
|
2007-01-26 23:18:56 +01:00
|
|
|
/* Error code. 0 means success. */
|
2000-06-28 01:18:39 +02:00
|
|
|
/* */
|
2008-09-20 13:50:47 +02:00
|
|
|
static int
|
|
|
|
FT_Outline_Decompose( const FT_Outline* outline,
|
|
|
|
const FT_Outline_Funcs* func_interface,
|
|
|
|
void* user )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
|
|
|
#undef SCALED
|
Fixed a bug in `glnames.py' that prevented it from generating
correct glyph names tables. This resulted in the unavailability of
certain glyphs like `Cacute', `cacute' and `lslash' in Unicode
charmaps, even if these were present in the font (causing problems
for Polish users).
* src/tools/glnames.py (mac_standard_names): Fixed.
(t1_standard_strings): Some fixes and renamed to ...
(sid_standard_names): This.
(t1_expert_encoding): Fixed.
(the_adobe_glyph_list): Renamed to ...
(adobe_glyph_names): This.
(the_adobe_glyphs): Renamed to ...
(adobe_glyph_values): This.
(dump_mac_indices, dump_glyph_list, dump_unicode_values, main):
Updated.
* src/psnames/pstables.h: Regenerated.
* src/psnames/psmodule.c (PS_Unicode_Value): Fix offset.
Fix return value.
Use `sid_standard_table' and `ps_names_to_unicode' instead of
`t1_standard_glyphs' and `names_to_unicode'.
(PS_Macintosh_Name): Use `ps_glyph_names' instead of
`standard_glyph_names'.
(PS_Standard_Strings): Use `sid_standard_names' instead of
`t1_standard_glyphs'.
* doc/BUGS, doc/TODO: New documents.
* src/cache/ftlru.c (FT_Lru_Lookup_Node): Fixed a bug that prevented
correct LRU behaviour.
setjmp() and longjmp() are now used for rollback (i.e. when memory
pool overflow occurs).
Function names are now all uniformly prefixed with `gray_'.
* src/smooth/ftgrays.c: Include <setjmp.h>.
(ErrRaster_MemoryOverflow): New macro.
(TArea): New type to store area values in each cell (using `int' was
too small on 16-bit systems). <limits.h> is included to properly
get the needed data type.
(TCell, TRaster): Use it.
(TRaster): New element `jump_buffer'.
(gray_compute_cbox): Use `RAS_ARG' as the only parameter and get
`outline' from it.
(gray_record_cell): Use longjmp().
(gray_set_cell): Use gray_record_cell() for error handling.
(gray_render_line, gray_render_conic, gray_render_cubic): Simplify.
(gray_convert_glyph_inner): New function, using setjmp().
(gray_convert_glyph): Use it.
Provide a public API to manage multiple size objects for a given
FT_Face in the new header file `ftsizes.h'.
* include/freetype/ftsizes.h: New header file,
* include/freetype/internal/ftobjs.h: Use it.
Remove declarations of FT_New_Size and FT_Done_Size (moved to
ftsizes.h).
* include/freetype/config/ftheader.h (FT_SIZES_H): New macro.
* src/base/ftobjs.c (FT_Activate_Size): New function.
* src/cache/ftcmanag.c: Include ftsizes.h.
(ftc_manager_init_size, ftc_manager_flush_size): Use
FT_Activate_Size.
2001-10-10 21:56:42 +02:00
|
|
|
#define SCALED( x ) ( ( (x) << shift ) - delta )
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
FT_Vector v_last;
|
|
|
|
FT_Vector v_control;
|
|
|
|
FT_Vector v_start;
|
|
|
|
|
|
|
|
FT_Vector* point;
|
|
|
|
FT_Vector* limit;
|
|
|
|
char* tags;
|
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
int error;
|
|
|
|
|
2002-09-28 18:40:57 +02:00
|
|
|
int n; /* index of contour in outline */
|
|
|
|
int first; /* index of first point in contour */
|
|
|
|
char tag; /* current point's state */
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
int shift;
|
|
|
|
TPos delta;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
|
2014-11-25 10:22:12 +01:00
|
|
|
if ( !outline )
|
|
|
|
return FT_THROW( Invalid_Outline );
|
|
|
|
|
|
|
|
if ( !func_interface )
|
2013-03-14 10:27:35 +01:00
|
|
|
return FT_THROW( Invalid_Argument );
|
2008-09-20 13:50:47 +02:00
|
|
|
|
|
|
|
shift = func_interface->shift;
|
|
|
|
delta = func_interface->delta;
|
2000-06-28 01:18:39 +02:00
|
|
|
first = 0;
|
|
|
|
|
|
|
|
for ( n = 0; n < outline->n_contours; n++ )
|
|
|
|
{
|
|
|
|
int last; /* index of last point in contour */
|
|
|
|
|
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n ));
|
|
|
|
|
2000-06-28 01:18:39 +02:00
|
|
|
last = outline->contours[n];
|
2008-09-20 13:50:47 +02:00
|
|
|
if ( last < 0 )
|
|
|
|
goto Invalid_Outline;
|
2000-06-28 01:18:39 +02:00
|
|
|
limit = outline->points + last;
|
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
v_start = outline->points[first];
|
2006-09-05 21:24:34 +02:00
|
|
|
v_start.x = SCALED( v_start.x );
|
|
|
|
v_start.y = SCALED( v_start.y );
|
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
v_last = outline->points[last];
|
|
|
|
v_last.x = SCALED( v_last.x );
|
|
|
|
v_last.y = SCALED( v_last.y );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
v_control = v_start;
|
|
|
|
|
|
|
|
point = outline->points + first;
|
2008-09-20 13:50:47 +02:00
|
|
|
tags = outline->tags + first;
|
2000-06-28 01:18:39 +02:00
|
|
|
tag = FT_CURVE_TAG( tags[0] );
|
|
|
|
|
|
|
|
/* 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-06-28 01:18:39 +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-06-28 01:18:39 +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( outline->tags[last] ) == FT_CURVE_TAG_ON )
|
2000-06-28 01:18:39 +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--;
|
|
|
|
}
|
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
FT_TRACE5(( " move to (%.2f, %.2f)\n",
|
|
|
|
v_start.x / 64.0, v_start.y / 64.0 ));
|
2002-04-30 08:37:52 +02:00
|
|
|
error = func_interface->move_to( &v_start, user );
|
2000-06-28 01:18:39 +02:00
|
|
|
if ( error )
|
|
|
|
goto Exit;
|
|
|
|
|
|
|
|
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-06-28 01:18:39 +02:00
|
|
|
{
|
|
|
|
FT_Vector vec;
|
|
|
|
|
|
|
|
|
|
|
|
vec.x = SCALED( point->x );
|
|
|
|
vec.y = SCALED( point->y );
|
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
FT_TRACE5(( " line to (%.2f, %.2f)\n",
|
|
|
|
vec.x / 64.0, vec.y / 64.0 ));
|
2002-04-30 08:37:52 +02:00
|
|
|
error = func_interface->line_to( &vec, user );
|
2000-06-28 01:18:39 +02:00
|
|
|
if ( error )
|
|
|
|
goto Exit;
|
|
|
|
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 */
|
2008-09-20 13:50:47 +02:00
|
|
|
v_control.x = SCALED( point->x );
|
|
|
|
v_control.y = SCALED( point->y );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
Do_Conic:
|
|
|
|
if ( point < limit )
|
|
|
|
{
|
|
|
|
FT_Vector vec;
|
|
|
|
FT_Vector v_middle;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
point++;
|
|
|
|
tags++;
|
|
|
|
tag = FT_CURVE_TAG( tags[0] );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
vec.x = SCALED( point->x );
|
|
|
|
vec.y = SCALED( point->y );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
if ( tag == FT_CURVE_TAG_ON )
|
|
|
|
{
|
|
|
|
FT_TRACE5(( " conic to (%.2f, %.2f)"
|
|
|
|
" with control (%.2f, %.2f)\n",
|
|
|
|
vec.x / 64.0, vec.y / 64.0,
|
|
|
|
v_control.x / 64.0, v_control.y / 64.0 ));
|
|
|
|
error = func_interface->conic_to( &v_control, &vec, user );
|
2000-06-28 01:18:39 +02:00
|
|
|
if ( error )
|
|
|
|
goto Exit;
|
2008-09-20 13:50:47 +02:00
|
|
|
continue;
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
if ( tag != FT_CURVE_TAG_CONIC )
|
|
|
|
goto Invalid_Outline;
|
|
|
|
|
|
|
|
v_middle.x = ( v_control.x + vec.x ) / 2;
|
|
|
|
v_middle.y = ( v_control.y + vec.y ) / 2;
|
|
|
|
|
|
|
|
FT_TRACE5(( " conic to (%.2f, %.2f)"
|
|
|
|
" with control (%.2f, %.2f)\n",
|
|
|
|
v_middle.x / 64.0, v_middle.y / 64.0,
|
|
|
|
v_control.x / 64.0, v_control.y / 64.0 ));
|
|
|
|
error = func_interface->conic_to( &v_control, &v_middle, user );
|
|
|
|
if ( error )
|
|
|
|
goto Exit;
|
|
|
|
|
|
|
|
v_control = vec;
|
|
|
|
goto Do_Conic;
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
FT_TRACE5(( " conic to (%.2f, %.2f)"
|
|
|
|
" with control (%.2f, %.2f)\n",
|
|
|
|
v_start.x / 64.0, v_start.y / 64.0,
|
|
|
|
v_control.x / 64.0, v_control.y / 64.0 ));
|
|
|
|
error = func_interface->conic_to( &v_control, &v_start, user );
|
|
|
|
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-06-28 01:18:39 +02:00
|
|
|
{
|
|
|
|
FT_Vector vec1, vec2;
|
|
|
|
|
|
|
|
|
|
|
|
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-06-28 01:18:39 +02:00
|
|
|
goto Invalid_Outline;
|
|
|
|
|
|
|
|
point += 2;
|
|
|
|
tags += 2;
|
|
|
|
|
2006-09-05 21:24:34 +02:00
|
|
|
vec1.x = SCALED( point[-2].x );
|
|
|
|
vec1.y = SCALED( point[-2].y );
|
|
|
|
|
|
|
|
vec2.x = SCALED( point[-1].x );
|
|
|
|
vec2.y = SCALED( point[-1].y );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
if ( point <= limit )
|
|
|
|
{
|
|
|
|
FT_Vector vec;
|
|
|
|
|
|
|
|
|
|
|
|
vec.x = SCALED( point->x );
|
|
|
|
vec.y = SCALED( point->y );
|
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
FT_TRACE5(( " cubic to (%.2f, %.2f)"
|
|
|
|
" with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
|
|
|
|
vec.x / 64.0, vec.y / 64.0,
|
|
|
|
vec1.x / 64.0, vec1.y / 64.0,
|
|
|
|
vec2.x / 64.0, vec2.y / 64.0 ));
|
2002-04-30 08:37:52 +02:00
|
|
|
error = func_interface->cubic_to( &vec1, &vec2, &vec, user );
|
2000-06-28 01:18:39 +02:00
|
|
|
if ( error )
|
|
|
|
goto Exit;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
FT_TRACE5(( " cubic to (%.2f, %.2f)"
|
|
|
|
" with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
|
|
|
|
v_start.x / 64.0, v_start.y / 64.0,
|
|
|
|
vec1.x / 64.0, vec1.y / 64.0,
|
|
|
|
vec2.x / 64.0, vec2.y / 64.0 ));
|
2002-04-30 08:37:52 +02:00
|
|
|
error = func_interface->cubic_to( &vec1, &vec2, &v_start, user );
|
2000-06-28 01:18:39 +02:00
|
|
|
goto Close;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* close the contour with a line segment */
|
2008-09-20 13:50:47 +02:00
|
|
|
FT_TRACE5(( " line to (%.2f, %.2f)\n",
|
|
|
|
v_start.x / 64.0, v_start.y / 64.0 ));
|
2002-04-30 08:37:52 +02:00
|
|
|
error = func_interface->line_to( &v_start, user );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
Close:
|
|
|
|
if ( error )
|
|
|
|
goto Exit;
|
|
|
|
|
|
|
|
first = last + 1;
|
|
|
|
}
|
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
FT_TRACE5(( "FT_Outline_Decompose: Done\n", n ));
|
2000-06-28 01:18:39 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
Exit:
|
2008-09-20 13:50:47 +02:00
|
|
|
FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error ));
|
2000-06-28 01:18:39 +02:00
|
|
|
return error;
|
|
|
|
|
|
|
|
Invalid_Outline:
|
2013-03-14 10:27:35 +01:00
|
|
|
return FT_THROW( Invalid_Outline );
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-06-15 05:49:31 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
2016-06-22 06:04:08 +02:00
|
|
|
/* <Function> */
|
|
|
|
/* FT_Outline_Get_CBox */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
|
|
|
/* Return an outline's `control box'. The control box encloses all */
|
|
|
|
/* the outline's points, including Bézier control points. Though it */
|
|
|
|
/* coincides with the exact bounding box for most glyphs, it can be */
|
|
|
|
/* slightly larger in some situations (like when rotating an outline */
|
|
|
|
/* that contains Bézier outside arcs). */
|
|
|
|
/* */
|
|
|
|
/* Computing the control box is very fast, while getting the bounding */
|
|
|
|
/* box can take much more time as it needs to walk over all segments */
|
|
|
|
/* and arcs in the outline. To get the latter, you can use the */
|
|
|
|
/* `ftbbox' component, which is dedicated to this single task. */
|
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* outline :: A pointer to the source outline descriptor. */
|
2016-06-15 05:49:31 +02:00
|
|
|
/* */
|
2016-06-22 06:04:08 +02:00
|
|
|
/* <Output> */
|
|
|
|
/* acbox :: The outline's control box. */
|
|
|
|
/* */
|
|
|
|
/* <Note> */
|
|
|
|
/* See @FT_Glyph_Get_CBox for a discussion of tricky fonts. */
|
|
|
|
/* */
|
|
|
|
|
2016-06-15 05:49:31 +02:00
|
|
|
static void
|
2016-06-22 06:04:08 +02:00
|
|
|
FT_Outline_Get_CBox( const FT_Outline* outline,
|
|
|
|
FT_BBox *acbox )
|
2016-06-15 05:49:31 +02:00
|
|
|
{
|
2016-06-22 06:04:08 +02:00
|
|
|
TPos xMin, yMin, xMax, yMax;
|
2016-06-15 05:49:31 +02:00
|
|
|
|
|
|
|
|
2016-06-22 06:04:08 +02:00
|
|
|
if ( outline && acbox )
|
2016-06-15 05:49:31 +02:00
|
|
|
{
|
2016-06-22 06:04:08 +02:00
|
|
|
if ( outline->n_points == 0 )
|
|
|
|
{
|
|
|
|
xMin = 0;
|
|
|
|
yMin = 0;
|
|
|
|
xMax = 0;
|
|
|
|
yMax = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
FT_Vector* vec = outline->points;
|
|
|
|
FT_Vector* limit = vec + outline->n_points;
|
2016-06-15 05:49:31 +02:00
|
|
|
|
|
|
|
|
2016-06-22 06:04:08 +02:00
|
|
|
xMin = xMax = vec->x;
|
|
|
|
yMin = yMax = vec->y;
|
|
|
|
vec++;
|
2016-06-15 05:49:31 +02:00
|
|
|
|
2016-06-22 06:04:08 +02:00
|
|
|
for ( ; vec < limit; vec++ )
|
|
|
|
{
|
|
|
|
TPos x, y;
|
2016-06-15 05:49:31 +02:00
|
|
|
|
|
|
|
|
2016-06-22 06:04:08 +02:00
|
|
|
x = vec->x;
|
|
|
|
if ( x < xMin ) xMin = x;
|
|
|
|
if ( x > xMax ) xMax = x;
|
2016-06-15 05:49:31 +02:00
|
|
|
|
2016-06-22 06:04:08 +02:00
|
|
|
y = vec->y;
|
|
|
|
if ( y < yMin ) yMin = y;
|
|
|
|
if ( y > yMax ) yMax = y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
acbox->xMin = xMin;
|
|
|
|
acbox->xMax = xMax;
|
|
|
|
acbox->yMin = yMin;
|
|
|
|
acbox->yMax = yMax;
|
|
|
|
}
|
2016-06-15 05:49:31 +02:00
|
|
|
}
|
|
|
|
|
2016-06-22 06:04:08 +02:00
|
|
|
#endif /* STANDALONE_ */
|
|
|
|
|
2016-06-15 05:49:31 +02:00
|
|
|
|
2015-02-23 07:04:36 +01:00
|
|
|
FT_DEFINE_OUTLINE_FUNCS(
|
|
|
|
func_interface,
|
|
|
|
|
|
|
|
(FT_Outline_MoveTo_Func) gray_move_to,
|
|
|
|
(FT_Outline_LineTo_Func) gray_line_to,
|
|
|
|
(FT_Outline_ConicTo_Func)gray_conic_to,
|
|
|
|
(FT_Outline_CubicTo_Func)gray_cubic_to,
|
|
|
|
0,
|
|
|
|
0 )
|
|
|
|
|
2009-04-05 17:14:04 +02:00
|
|
|
|
|
|
|
static int
|
|
|
|
gray_convert_glyph_inner( RAS_ARG )
|
|
|
|
{
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2001-10-07 12:39:03 +02:00
|
|
|
volatile int error = 0;
|
2001-11-20 02:29:34 +01:00
|
|
|
|
2009-04-05 17:14:04 +02:00
|
|
|
#ifdef FT_CONFIG_OPTION_PIC
|
|
|
|
FT_Outline_Funcs func_interface;
|
|
|
|
Init_Class_func_interface(&func_interface);
|
|
|
|
#endif
|
2008-06-21 08:27:53 +02:00
|
|
|
|
2002-06-11 01:03:35 +02:00
|
|
|
if ( ft_setjmp( ras.jump_buffer ) == 0 )
|
2001-10-07 12:39:03 +02:00
|
|
|
{
|
2002-04-30 08:37:52 +02:00
|
|
|
error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras );
|
2013-07-16 13:36:07 +02:00
|
|
|
if ( !ras.invalid )
|
|
|
|
gray_record_cell( RAS_VAR );
|
2016-07-05 05:46:53 +02:00
|
|
|
|
|
|
|
FT_TRACE7(( "band [%d..%d]: %d cells\n",
|
|
|
|
ras.min_ey, ras.max_ey, ras.num_cells ));
|
2001-10-07 12:39:03 +02:00
|
|
|
}
|
|
|
|
else
|
2016-07-05 05:46:53 +02:00
|
|
|
{
|
2013-03-14 10:27:35 +01:00
|
|
|
error = FT_THROW( Memory_Overflow );
|
2001-10-07 12:39:03 +02:00
|
|
|
|
2016-07-05 05:46:53 +02:00
|
|
|
FT_TRACE7(( "band [%d..%d]: to be bisected\n",
|
|
|
|
ras.min_ey, ras.max_ey ));
|
|
|
|
}
|
|
|
|
|
2001-10-07 12:39:03 +02:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
gray_convert_glyph( RAS_ARG )
|
|
|
|
{
|
2016-08-28 05:25:54 +02:00
|
|
|
TCell buffer[FT_MAX_GRAY_POOL];
|
|
|
|
TCoord band_size = FT_MAX_GRAY_POOL / 8;
|
2016-09-07 05:59:33 +02:00
|
|
|
TCoord count = ras.max_ey - ras.min_ey;
|
2016-08-28 05:25:54 +02:00
|
|
|
int num_bands;
|
|
|
|
TCoord min, max, max_y;
|
|
|
|
TCoord bands[32]; /* enough to accommodate bisections */
|
|
|
|
TCoord* band;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
|
2008-06-21 08:27:53 +02:00
|
|
|
/* set up vertical bands */
|
2016-09-07 05:59:33 +02:00
|
|
|
if ( count > band_size )
|
2016-07-08 06:16:07 +02:00
|
|
|
{
|
|
|
|
/* two divisions rounded up */
|
2016-09-07 05:59:33 +02:00
|
|
|
num_bands = (int)( ( count + band_size - 1) / band_size );
|
|
|
|
band_size = ( count + num_bands - 1 ) / num_bands;
|
2016-07-08 06:16:07 +02:00
|
|
|
}
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
min = ras.min_ey;
|
|
|
|
max_y = ras.max_ey;
|
|
|
|
|
2016-07-08 06:59:31 +02:00
|
|
|
for ( ; min < max_y; min = max )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2016-06-24 05:17:39 +02:00
|
|
|
max = min + band_size;
|
2016-07-08 06:16:07 +02:00
|
|
|
if ( max > max_y )
|
2000-06-28 01:18:39 +02:00
|
|
|
max = max_y;
|
|
|
|
|
2016-08-28 05:25:54 +02:00
|
|
|
band = bands;
|
|
|
|
band[1] = min;
|
|
|
|
band[0] = max;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2015-09-05 05:14:46 +02:00
|
|
|
do
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2016-08-28 05:25:54 +02:00
|
|
|
TCoord width = band[0] - band[1];
|
2016-07-02 05:27:41 +02:00
|
|
|
int error;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2006-09-01 21:05:24 +02:00
|
|
|
|
2016-06-20 06:01:55 +02:00
|
|
|
/* memory management */
|
|
|
|
{
|
2016-08-28 05:25:54 +02:00
|
|
|
size_t ycount = (size_t)width;
|
2016-06-29 04:56:22 +02:00
|
|
|
size_t cell_start;
|
2006-09-01 21:05:24 +02:00
|
|
|
|
|
|
|
|
2016-06-21 11:39:34 +02:00
|
|
|
cell_start = ( ycount * sizeof ( PCell ) + sizeof ( TCell ) - 1 ) /
|
|
|
|
sizeof ( TCell );
|
2006-09-04 18:42:44 +02:00
|
|
|
|
2016-06-20 06:01:55 +02:00
|
|
|
if ( FT_MAX_GRAY_POOL - cell_start < 2 )
|
2006-09-01 21:05:24 +02:00
|
|
|
goto ReduceBands;
|
|
|
|
|
2016-06-24 05:17:39 +02:00
|
|
|
ras.cells = buffer + cell_start;
|
2016-06-21 11:39:34 +02:00
|
|
|
ras.max_cells = (FT_PtrDist)( FT_MAX_GRAY_POOL - cell_start );
|
2006-09-04 18:42:44 +02:00
|
|
|
|
2016-06-24 05:17:39 +02:00
|
|
|
ras.ycells = (PCell*)buffer;
|
2016-06-20 06:01:55 +02:00
|
|
|
while ( ycount )
|
|
|
|
ras.ycells[--ycount] = NULL;
|
2006-09-01 21:05:24 +02:00
|
|
|
}
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
ras.num_cells = 0;
|
|
|
|
ras.invalid = 1;
|
2016-08-28 05:25:54 +02:00
|
|
|
ras.min_ey = band[1];
|
2016-09-07 05:24:17 +02:00
|
|
|
ras.max_ey = ras.ey = band[0];
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2001-10-07 12:39:03 +02:00
|
|
|
error = gray_convert_glyph_inner( RAS_VAR );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
if ( !error )
|
|
|
|
{
|
2016-06-28 06:30:58 +02:00
|
|
|
gray_sweep( RAS_VAR );
|
2000-06-28 01:18:39 +02:00
|
|
|
band--;
|
|
|
|
continue;
|
|
|
|
}
|
2006-11-28 09:09:20 +01:00
|
|
|
else if ( error != ErrRaster_Memory_Overflow )
|
2001-10-07 12:39:03 +02:00
|
|
|
return 1;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2006-09-01 21:05:24 +02:00
|
|
|
ReduceBands:
|
2006-09-05 21:24:34 +02:00
|
|
|
/* render pool overflow; we will reduce the render band by half */
|
2016-08-28 05:25:54 +02:00
|
|
|
width >>= 1;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2006-09-05 21:24:34 +02:00
|
|
|
/* This is too complex for a single scanline; there must */
|
|
|
|
/* be some problems. */
|
2016-08-28 05:25:54 +02:00
|
|
|
if ( width == 0 )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2009-06-26 06:15:41 +02:00
|
|
|
FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" ));
|
2000-06-28 01:18:39 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
band++;
|
2016-08-28 05:25:54 +02:00
|
|
|
band[1] = band[0];
|
|
|
|
band[0] += width;
|
2015-09-05 05:14:46 +02:00
|
|
|
} while ( band >= bands );
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
* builds/unix/ftsystem.c, include/freetype/config/ftheader.h,
include/freetype/internal/services/svotval.h,
include/freetype/internal/services/svpfr.h,
src/base/ftsystem.c, src/bdf/bdfdrivr.c, src/cache/ftcbasic.c,
src/cff/cffcmap.c, src/gzip/ftgzip.c, src/lzw/ftlzw.c,
src/lzw/ftlzw2.c, src/psaux/t1cmap.c, src/sfnt/ttbdf.c,
src/smooth/ftgrays.c:
solved -Wmissing-prototypes warnings with GCC
2006-02-25 15:53:02 +01:00
|
|
|
static int
|
2016-03-23 06:58:20 +01:00
|
|
|
gray_raster_render( FT_Raster 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-06-28 01:18:39 +02:00
|
|
|
{
|
2015-01-14 17:54:26 +01:00
|
|
|
const FT_Outline* outline = (const FT_Outline*)params->source;
|
|
|
|
const FT_Bitmap* target_map = params->target;
|
2016-06-23 05:14:26 +02:00
|
|
|
FT_BBox cbox, clip;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2016-08-26 04:36:01 +02:00
|
|
|
#ifndef FT_STATIC_RASTER
|
2015-01-14 17:54:26 +01:00
|
|
|
gray_TWorker worker[1];
|
2016-08-26 04:36:01 +02:00
|
|
|
#endif
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2015-01-14 17:54:26 +01:00
|
|
|
|
|
|
|
if ( !raster )
|
2013-03-14 10:27:35 +01:00
|
|
|
return FT_THROW( Invalid_Argument );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2016-08-26 04:36:01 +02:00
|
|
|
/* this version does not support monochrome rendering */
|
|
|
|
if ( !( params->flags & FT_RASTER_FLAG_AA ) )
|
|
|
|
return FT_THROW( Invalid_Mode );
|
|
|
|
|
2007-12-31 00:49:14 +01:00
|
|
|
if ( !outline )
|
2013-03-14 10:27:35 +01:00
|
|
|
return FT_THROW( Invalid_Outline );
|
2007-12-31 00:49:14 +01:00
|
|
|
|
2000-06-28 01:18:39 +02:00
|
|
|
/* return immediately if the outline is empty */
|
|
|
|
if ( outline->n_points == 0 || outline->n_contours <= 0 )
|
|
|
|
return 0;
|
|
|
|
|
2007-12-31 00:49:14 +01:00
|
|
|
if ( !outline->contours || !outline->points )
|
2013-03-14 10:27:35 +01:00
|
|
|
return FT_THROW( Invalid_Outline );
|
2000-06-28 01:18:39 +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_Outline );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2016-08-26 04:36:01 +02:00
|
|
|
ras.outline = *outline;
|
|
|
|
|
|
|
|
if ( params->flags & FT_RASTER_FLAG_DIRECT )
|
2006-11-28 09:38:31 +01:00
|
|
|
{
|
2016-08-26 04:36:01 +02:00
|
|
|
if ( !params->gray_spans )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
ras.render_span = (FT_Raster_Span_Func)params->gray_spans;
|
|
|
|
ras.render_span_data = params->user;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* if direct mode is not set, we must have a target bitmap */
|
2006-12-01 09:20:47 +01:00
|
|
|
if ( !target_map )
|
2013-03-14 10:27:35 +01:00
|
|
|
return FT_THROW( Invalid_Argument );
|
2006-11-28 09:38:31 +01:00
|
|
|
|
2006-12-01 09:20:47 +01:00
|
|
|
/* nothing to do */
|
|
|
|
if ( !target_map->width || !target_map->rows )
|
|
|
|
return 0;
|
2006-11-28 09:38:31 +01:00
|
|
|
|
2006-12-01 09:20:47 +01:00
|
|
|
if ( !target_map->buffer )
|
2013-03-14 10:27:35 +01:00
|
|
|
return FT_THROW( Invalid_Argument );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2016-08-30 05:15:35 +02:00
|
|
|
if ( target_map->pitch < 0 )
|
|
|
|
ras.target.origin = target_map->buffer;
|
|
|
|
else
|
|
|
|
ras.target.origin = target_map->buffer
|
|
|
|
+ ( target_map->rows - 1 ) * (unsigned int)target_map->pitch;
|
|
|
|
|
|
|
|
ras.target.pitch = target_map->pitch;
|
|
|
|
|
2016-09-02 04:56:24 +02:00
|
|
|
ras.render_span = (FT_Raster_Span_Func)NULL;
|
|
|
|
ras.render_span_data = NULL;
|
2016-08-26 04:36:01 +02:00
|
|
|
}
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2016-06-23 05:14:26 +02:00
|
|
|
FT_Outline_Get_CBox( outline, &cbox );
|
2016-03-23 07:31:59 +01:00
|
|
|
|
2016-06-23 05:14:26 +02:00
|
|
|
/* reject too large outline coordinates */
|
|
|
|
if ( cbox.xMin < -0x1000000L || cbox.xMax > 0x1000000L ||
|
|
|
|
cbox.yMin < -0x1000000L || cbox.yMax > 0x1000000L )
|
|
|
|
return FT_THROW( Invalid_Outline );
|
2016-03-23 07:31:59 +01:00
|
|
|
|
2016-06-23 05:14:26 +02:00
|
|
|
/* truncate the bounding box to integer pixels */
|
|
|
|
cbox.xMin = cbox.xMin >> 6;
|
|
|
|
cbox.yMin = cbox.yMin >> 6;
|
|
|
|
cbox.xMax = ( cbox.xMax + 63 ) >> 6;
|
|
|
|
cbox.yMax = ( cbox.yMax + 63 ) >> 6;
|
2016-03-23 07:31:59 +01:00
|
|
|
|
2000-12-14 19:50:40 +01:00
|
|
|
/* compute clipping box */
|
2008-09-22 10:55:44 +02:00
|
|
|
if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
|
2000-12-14 19:50:40 +01:00
|
|
|
{
|
|
|
|
/* compute clip box from target pixmap */
|
2016-06-23 05:14:26 +02:00
|
|
|
clip.xMin = 0;
|
|
|
|
clip.yMin = 0;
|
|
|
|
clip.xMax = (FT_Pos)target_map->width;
|
|
|
|
clip.yMax = (FT_Pos)target_map->rows;
|
2000-12-14 19:50:40 +01:00
|
|
|
}
|
* 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
|
|
|
else if ( params->flags & FT_RASTER_FLAG_CLIP )
|
2016-06-23 05:14:26 +02:00
|
|
|
clip = params->clip_box;
|
2000-12-14 19:50:40 +01:00
|
|
|
else
|
|
|
|
{
|
2016-06-23 05:14:26 +02:00
|
|
|
clip.xMin = -32768L;
|
|
|
|
clip.yMin = -32768L;
|
|
|
|
clip.xMax = 32767L;
|
|
|
|
clip.yMax = 32767L;
|
2000-12-14 19:50:40 +01:00
|
|
|
}
|
|
|
|
|
2016-06-23 05:14:26 +02:00
|
|
|
/* clip to target bitmap, exit if nothing to do */
|
|
|
|
ras.min_ex = FT_MAX( cbox.xMin, clip.xMin );
|
|
|
|
ras.min_ey = FT_MAX( cbox.yMin, clip.yMin );
|
|
|
|
ras.max_ex = FT_MIN( cbox.xMax, clip.xMax );
|
|
|
|
ras.max_ey = FT_MIN( cbox.yMax, clip.yMax );
|
|
|
|
|
|
|
|
if ( ras.max_ex <= ras.min_ex || ras.max_ey <= ras.min_ey )
|
|
|
|
return 0;
|
|
|
|
|
2009-06-19 09:09:34 +02:00
|
|
|
return gray_convert_glyph( RAS_VAR );
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-09-20 13:50:47 +02:00
|
|
|
/**** RASTER OBJECT CREATION: In stand-alone mode, we simply use *****/
|
|
|
|
/**** a static object. *****/
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2016-01-12 22:27:29 +01:00
|
|
|
#ifdef STANDALONE_
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static int
|
2001-10-07 12:39:03 +02:00
|
|
|
gray_raster_new( void* memory,
|
|
|
|
FT_Raster* araster )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2012-02-22 07:01:35 +01:00
|
|
|
static gray_TRaster the_raster;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2000-07-04 20:12:13 +02:00
|
|
|
FT_UNUSED( memory );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
|
|
|
|
*araster = (FT_Raster)&the_raster;
|
2002-07-28 07:05:24 +02:00
|
|
|
FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) );
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
2001-10-07 12:39:03 +02:00
|
|
|
gray_raster_done( FT_Raster raster )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
|
|
|
/* nothing */
|
2000-07-04 20:12:13 +02:00
|
|
|
FT_UNUSED( raster );
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
2016-01-12 22:27:29 +01:00
|
|
|
#else /* !STANDALONE_ */
|
2000-06-28 01:18:39 +02:00
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static int
|
2001-10-07 12:39:03 +02:00
|
|
|
gray_raster_new( FT_Memory memory,
|
|
|
|
FT_Raster* araster )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2012-02-22 07:01:35 +01:00
|
|
|
FT_Error error;
|
|
|
|
gray_PRaster raster = NULL;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
|
|
|
|
*araster = 0;
|
2012-02-22 07:01:35 +01:00
|
|
|
if ( !FT_ALLOC( raster, sizeof ( gray_TRaster ) ) )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
|
|
|
raster->memory = memory;
|
2012-02-22 07:01:35 +01:00
|
|
|
*araster = (FT_Raster)raster;
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
2001-10-07 12:39:03 +02:00
|
|
|
gray_raster_done( FT_Raster raster )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2012-02-22 07:01:35 +01:00
|
|
|
FT_Memory memory = (FT_Memory)((gray_PRaster)raster)->memory;
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
|
2002-03-22 14:52:37 +01:00
|
|
|
FT_FREE( raster );
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
2016-01-12 22:27:29 +01:00
|
|
|
#endif /* !STANDALONE_ */
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
|
2001-06-28 01:25:46 +02:00
|
|
|
static void
|
2016-03-23 06:58:20 +01:00
|
|
|
gray_raster_reset( FT_Raster raster,
|
|
|
|
unsigned char* pool_base,
|
|
|
|
unsigned long pool_size )
|
2000-06-28 01:18:39 +02:00
|
|
|
{
|
2015-01-14 17:54:26 +01:00
|
|
|
FT_UNUSED( raster );
|
|
|
|
FT_UNUSED( pool_base );
|
|
|
|
FT_UNUSED( pool_size );
|
2000-06-28 01:18:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-11-25 09:01:07 +01:00
|
|
|
static int
|
|
|
|
gray_raster_set_mode( FT_Raster raster,
|
|
|
|
unsigned long mode,
|
|
|
|
void* args )
|
|
|
|
{
|
|
|
|
FT_UNUSED( raster );
|
|
|
|
FT_UNUSED( mode );
|
|
|
|
FT_UNUSED( args );
|
|
|
|
|
|
|
|
|
|
|
|
return 0; /* nothing to do */
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-23 07:04:36 +01:00
|
|
|
FT_DEFINE_RASTER_FUNCS(
|
|
|
|
ft_grays_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-06-28 01:18:39 +02:00
|
|
|
|
2002-04-01 16:25:28 +02:00
|
|
|
(FT_Raster_New_Func) gray_raster_new,
|
|
|
|
(FT_Raster_Reset_Func) gray_raster_reset,
|
2014-11-25 09:01:07 +01:00
|
|
|
(FT_Raster_Set_Mode_Func)gray_raster_set_mode,
|
2002-04-01 16:25:28 +02:00
|
|
|
(FT_Raster_Render_Func) gray_raster_render,
|
2015-02-23 07:04:36 +01:00
|
|
|
(FT_Raster_Done_Func) gray_raster_done )
|
2000-06-28 01:18:39 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* END */
|
2008-09-20 13:50:47 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* Local Variables: */
|
|
|
|
/* coding: utf-8 */
|
|
|
|
/* End: */
|