memory.txt、、、、、、、、、、、、、、、、、、、、、、
/*
* Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved.
*/
/* $Header: I:/BULL/URIP/RTS/rac/MEMORY.C_V 1.17 Aug 22 2003 09:22:06 LynchR $ */
/* $Log: I:/BULL/URIP/RTS/rac/MEMORY.C_V $
*
* Rev 1.17 Aug 22 2003 09:22:06 LynchR
* Updated copyright notice.
*
* Rev 1.16 Jun 20 2003 14:22:02 Galejs
* get rid of asserts; clean up debug; size_t becomes UL32
*
* Rev 1.15 Sep 09 2002 18:49:22 Galejs
* extra chars after #endif (part of bug # 76)
*
* Rev 1.14 Jun 29 2001 17:37:44 Galejs
* const should be CONST (for portability)
*
* Rev 1.13 May 03 2001 20:43:34 Galejs
* data-type cleanup
*
* Rev 1.12 Oct 16 2000 15:46:36 Al
*
* Rev 1.11 Sep 21 2000 14:01:38 galejs
* change ACT error handling (no setjmp / longjmp)
*
* Rev 1.10 Feb 07 2000 15:52:50 galejs
* unsigned long -> UL32, long ->SL32
*
* Rev 1.9 Jan 27 2000 18:17:28 galejs
* use act_alloc/realloc/freemem() directly in code
*
* Rev 1.8 Jan 24 2000 15:52:30 galejs
* remove unused field "mem_numNewCalls"
*
* Rev 1.7 May 24 1999 15:10:16 galejs
* make ACT reentrant
*
* Rev 1.6 13 Oct 1997 15:36:54 MARTIN
* Renamed memory.h to ra_mem.h to fix name conflict on some compilers.
*
* Rev 1.5 04 Sep 1997 17:04:50 MARTIN
* Modified references to AGFA Compressed TrueType (ACT).
*
* Rev 1.4 29 Aug 1997 09:05:42 JOE
* Revised last change to assert() calls for portability.
*
* Rev 1.3 28 Aug 1997 15:11:00 JOE
* In ACT_mem_malloc() and ACT_mem_realloc(), removed "return" statements
* at end of each function because it was unreachable code.
*
* Rev 1.2 15 Aug 1997 15:02:32 JOE
* Added non-ANSI function declarations.
* Changed the include filenames to lowercase.
* Moved compiler directives to column 1.
*
* Rev 1.1 30 Jun 1997 20:17:42 MIKE
* Fixed line endings with unix2dos utility
*
* Rev 1.0 04 Jun 1997 11:05:44 MARTIN
* Initial revision.
*/
/*
* File: MEMORY.CPP
* First Version: March 8, 1996
* Added mem_realloc: September 29, 1996
* First pure ANSI C version: October 28, 1996
*
* 07-Feb-00 slg Don't use "long" dcls (incorrect if 64-bit platform).
*
*/
#include "cgconfig.h"
#if TT_ROM_ACT /* conditional compile entire module */
#include <stdio.h>
#include <stdlib.h> /* 08-07-97 jfd */
#include "ufstport.h"
#include "shareinc.h"
#include "ra_mem.h"
#ifdef CHECK_MEMORY_ACT /* 08-07-97 jfd */
CONST SL32 overWriteExtraSpace = sizeof(SL32) + sizeof(SL32) + sizeof(SB8); /* 4-byte Stamp, length, data, 1-byte Stamp */
CONST SL32 overWriteOffsetToData = sizeof(SL32) + sizeof(SL32); /* 4-byte Stamp, length */
#endif /* 08-07-97 jfd */
#ifdef CHECK_MEMORY_ACT
#if defined (ANSI_DEFS) /* 08-07-97 jfd */
static void validateAllMemory( ACT_MemHandler *t )
#else
static void validateAllMemory(t)
ACT_Memhandler *t;
#endif
{
register SL32 i, limit;
register void **pointers = t->mem_pointers;
void *object;
limit = t->mem_maxPointers;
for ( i = 0; i < limit; i++ ) {
if ( (object = pointers[i]) != NULL ) {
if ( ((SL32 *)object)[0] != 0x12345678 )
{
t->err = ERR_array_start_thrashed;
return;
}
if ( ((UB8 *)object)[((SL32 *)object)[1]-1] != 0xa5 )
{
t->err = ERR_array_end_thrashed;
return;
}
}
}
}
#endif
/* Our malloc */
#if defined (ANSI_DEFS) /* 08-07-97 jfd */
void *ACT_mem_malloc(FSP ACT_MemHandler *t, UL32 size)
#else
void *ACT_mem_malloc(t, size)
ACT_MemHandler *t;
UL32 size;
#endif
{
register SL32 i, limit;
void *babyObject;
register void **pointers;
if ( size == 0 )
return NULL; /****** Added September 23, 1996 */
#ifdef CHECK_MEMORY_ACT
size += overWriteExtraSpace;
babyObject = act_allocmem( FSA size );
((SL32 *)babyObject)[0] = 0x12345678;
((SL32 *)babyObject)[1] = size;
((UB8 *)babyObject)[size-1] = 0xa5;
#else
babyObject = act_allocmem ( FSA size );
#endif
if ( babyObject == NULL )
{
t->err = ERR_no_more_memory;
return NULL;
}
if ( t->mem_numPointers >= t->mem_maxPointers ) {
SL32 oldMaxPointers = t->mem_maxPointers;
/* We need to allocate more space for pointers */
t->mem_maxPointers = t->mem_maxPointers + t->mem_maxPointers/4 + 128;
if ( t->mem_pointers != NULL ) {
t->mem_pointers = (void **)act_reallocmem( FSA t->mem_pointers, t->mem_maxPointers * sizeof( void *) );
} else {
t->mem_pointers = (void **)act_allocmem( FSA t->mem_maxPointers * sizeof( void *) );
}
if ( t->mem_pointers == NULL )
{
t->err = ERR_no_more_memory;
return NULL;
}
/* Zero out the new entries; */
for ( i = oldMaxPointers; i < t->mem_maxPointers; i++ ) {
t->mem_pointers[i] = NULL;
}
}
/* OK, now we have a space to store the pointers, so go find it ! */
limit = t->mem_maxPointers;
pointers = t->mem_pointers;
for ( i = 0; i < limit; i++ ) {
if ( pointers[i] == NULL ) {
pointers[i] = babyObject;
/*callNumber[i] = t->mem_numPointers; */
t->mem_numPointers++;
#ifdef CHECK_MEMORY_ACT
validateAllMemory(t);
if (t->err)
return NULL;
return (void *)((SB8 *)babyObject + overWriteOffsetToData); /******/
#else
return babyObject; /******/
#endif
}
}
t->err = ERR_new_logical;
return NULL;
}
/* Added September 29, 1996 */
/* Our realloc */
#if defined (ANSI_DEFS) /* 08-07-97 jfd */
void *ACT_mem_realloc(FSP ACT_MemHandler *t, void *p, UL32 size)
#else
void *ACT_mem_realloc(t, p, size)
ACT_MemHandler *t;
void *p;
UL32 size;
#endif
{
register SL32 i, limit;
register void **pointers = t->mem_pointers;
void *new_p;
if ( p == NULL ) {
return ACT_mem_malloc( FSA t, size ); /******/
}
if ( size == 0 ) {
ACT_mem_free( FSA t, p );
return NULL; /****** Added October 7, 1996 */
}
#ifdef CHECK_MEMORY_ACT
size += overWriteExtraSpace;
p = (void *)((SB8 *)p - overWriteOffsetToData);
#endif
/* See if we can find it */
limit = t->mem_maxPointers;
for ( i = 0; i < limit; i++ ) {
if ( pointers[i] == p ) {
#ifdef CHECK_MEMORY_ACT
if ( ((SL32 *)p)[0] != 0x12345678 )
{
t->err = ERR_array_start_thrashed;
return NULL;
}
if ( ((UB8 *)p)[((SL32 *)p)[1]-1] != 0xa5 )
{
t->err = ERR_array_end_thrashed;
return NULL;
}
#endif
new_p = act_reallocmem( FSA p, size );
if ( new_p == NULL )
{
t->err = ERR_realloc_failed;
return NULL;
}
pointers[i] = new_p;
#ifdef CHECK_MEMORY_ACT
if ( ((SL32 *)new_p)[0] != 0x12345678 )
{
t->err = ERR_array_start_thrashed;
return NULL;
}
((SL32 *)new_p)[1] = size;
((UB8 *)new_p)[size-1] = 0xa5;
validateAllMemory(t);
if (t->err)
return NULL;
return (void *)((SB8 *)new_p + overWriteOffsetToData); /******/
#else
return new_p; /******/
#endif
}
}
t->err = ERR_realloc_bad_pointer;
return NULL;
}
/* Our free */
#if defined (ANSI_DEFS) /* 08-07-97 jfd */
void ACT_mem_free(FSP ACT_MemHandler *t, void *deadObject)
#else
void ACT_mem_free(t, deadObject)
ACT_MemHandler *t;
void *deadObject;
#endif
{
register SL32 i, limit;
register void **pointers = t->mem_pointers;
if ( deadObject == NULL )
return; /*****/ /* This is OK by definition */
#ifdef CHECK_MEMORY_ACT /* 08-07-97 jfd */
deadObject = (void *)((SB8 *)deadObject - overWriteOffsetToData);
#endif /* 08-07-97 jfd */
/* See if we can find it */
limit = t->mem_maxPointers;
for ( i = 0; i < limit; i++ ) {
if ( pointers[i] == deadObject ) {
#ifdef CHECK_MEMORY_ACT /* 08-07-97 jfd */
if ( ((SL32 *)deadObject)[0] != 0x12345678 )
{
t->err = ERR_array_start_thrashed;
return;
}
if ( ((UB8 *)deadObject)[((SL32 *)deadObject)[1]-1] != 0xa5 )
{
t->err = ERR_array_end_thrashed;
return;
}
validateAllMemory(t);
if (t->err)
return;
#endif /* 08-07-97 jfd */
act_freemem( FSA deadObject );
pointers[i] = NULL;
t->mem_numPointers--;
return; /******/
}
}
t->err = ERR_delete_bad_pointer;
}
/* Call mem_FreeAllMemory insted on an abnormal (exception) exit */
#if defined (ANSI_DEFS) /* 08-07-97 jfd */
void ACT_mem_FreeAllMemory( FSP ACT_MemHandler *t )
#else
void ACT_mem_FreeAllMemory(t)
ACT_MemHandler *t;
#endif
{
register SL32 i;
if ( t->mem_pointers != NULL ) {
for ( i = 0; i < t->mem_maxPointers; i++ ) {
if ( t->mem_pointers[i] != NULL ) {
#ifdef CHECK_MEMORY_ACT /* 08-07-97 jfd */
void *deadObject = t->mem_pointers[i];
if ( ((SL32 *)deadObject)[0] != 0x12345678 ) printf("%s\n", "ERR_array_start_thrashed ");
if ( ((UB8 *)deadObject)[((SL32 *)deadObject)[1]-1] != 0xa5 ) printf("%s\n", "ERR_array_end_thrashed ");
#endif /* 08-07-97 jfd */
act_freemem( FSA t->mem_pointers[i] );
t->mem_pointers[i] = NULL;
t->mem_numPointers--;
}
}
act_freemem( FSA t->mem_pointers );
t->mem_pointers = NULL;
}
}
/* Call mem_CloseMemory on normal exit */
#if defined (ANSI_DEFS) /* 08-07-97 jfd */
void ACT_mem_CloseMemory( FSP ACT_MemHandler *t )
#else
void ACT_mem_CloseMemory(t)
ACT_MemHandler *t;
#endif
{
if ( t->mem_numPointers != 0 )
{
t->err = ERR_mem_dangling_pointers;
return;
}
if ( t->mem_pointers != NULL )
{
act_freemem( FSA t->mem_pointers );
t->mem_pointers = NULL;
}
}
/* Constructor */
#if defined (ANSI_DEFS) /* 08-07-97 jfd */
ACT_MemHandler *ACT_mem_Create(FSP0)
#else
ACT_MemHandler *ACT_mem_Create()
#endif
{
ACT_MemHandler *t = (ACT_MemHandler *)act_allocmem( FSA sizeof( ACT_MemHandler ) );
if ( t == NULL )
return NULL; /*****/
t->mem_pointers = NULL;
t->mem_maxPointers = 0;
t->mem_numPointers = 0; /* Number of non-zero pointers */
t->err = 0; /* no errors yet */
return t; /******/
}
/* Destructor */
#if defined (ANSI_DEFS) /* 08-07-97 jfd */
void ACT_mem_Destroy(FSP ACT_MemHandler *t)
#else
void ACT_mem_Destroy(t)
ACT_MemHandler *t;
#endif
{
act_freemem( FSA t );
}
#endif /* TT_ROM_ACT */
merge.txt 、、、、、、、、、、、、、、、、、、、、、、、
/* Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved. */
/* $Header: I:/BULL/URIP/RTS/BMP/MERGE.C_V 1.15 Aug 21 2003 16:47:46 Galejs $ */
/* $Log: I:/BULL/URIP/RTS/BMP/MERGE.C_V $
*
* Rev 1.15 Aug 21 2003 16:47:46 Galejs
* update copyright notice
*
* Rev 1.14 Jul 21 2003 17:13:54 Galejs
* reentrancy / debug fixes
*
* Rev 1.13 Jun 23 2003 14:27:20 Galejs
* ufstport.h
*
* Rev 1.12 Aug 10 1999 14:41:20 galejs
* include-file changes
*
* Rev 1.11 22 Jun 1998 18:49:48 GALEJS
* tidying - remove unused defines / includes
*
* Rev 1.10 24 Mar 1998 14:48:28 GALEJS
* include-file changes
*
* Rev 1.9 06 Apr 1995 15:08:26 LISA
* Changed copyright from Miles Inc. to Bayer Corp.
*
* Rev 1.8 22 Apr 1994 09:20:44 LISA
* Modified copyright/disclaimer notice.
*
* Rev 1.7 07 Jan 1994 10:57:28 JOE
* In merge(), fixed shifting process if !LEFT_TO_RIGHT_BIT_ORDER.
*
* Rev 1.6 19 May 1993 14:53:56 JOE
* More changes for RASTER_ORG support.
*
* Rev 1.5 18 May 1993 17:50:34 JOE
* Added support for RASTER_ORG != EIGHT_BIT_CHUNK.
*
* Rev 1.4 17 May 1993 18:03:30 JOE
* In merge(), when calculating "ps" and "pd", cast "src->bm" and "dst->bm"
* as LPUB8 due to change made in IFBITMAP structure.
*
* Rev 1.3 12 Feb 1993 11:14:22 JOE
* VXWorks support.
*
* Rev 1.2 05 Jan 1993 16:06:42 JOE
* ANSI C function declaration changes.
*
* Rev 1.1 14 Dec 1992 09:30:10 LISA
* Made change to Log keyword
*
* Rev 1.0 10 Dec 1992 08:33:08 LISA
* Initial revision.
*/
/* $Date: Aug 21 2003 16:47:46 $ */
/* merge.c */
/*---------------------------------------------------------------------
11-22-90 awr Fixed bug in merge, rewrote bitblt portion based
on bg's if2.2 version.
4-Feb-91 awr Split off from maker.c
9-Jun-91 awr changed merge() parameter types to WORDVECTOR
25-Jun-91 awr changed merge() parameters
17-Jun-91 jfd Moved "debug.h" after "port.h".
Moved "cgconfig.h" before "port.h".
1-Sep-91 awr Included "bitmap.h"
25-Oct-91 jfd Conditionally compiling entire module based on
(CACHE | CHAR_HANDLE | CHAR_SIZE) instead of CGBITMAP.
03-Apr-92 rs Portability cleanup (see port.h).
17-Apr-92 awr Improved comments
21-Jun-92 awr Conditionally compile on IF_RDR
05-Jan-93 jfd ANSI C function declaration changes.
08-Feb-93 jfd VXWorks support.
17-May-93 jfd In merge(), when calculating "ps" and "pd", cast
"src->bm" and "dst->bm" as LPUB8 due to change made
in IFBITMAP structure.
18-May-93 jfd Added support for RASTER_ORG !== EIGHT_BIT_CHUNK.
19-May-93 jfd More changes for RASTER_ORG support.
07-Jan-94 jfd In merge(), fixed shifting process if
!LEFT_TO_RIGHT_BIT_ORDER.
-----------------------------------------------------------------------*/
#include "cgconfig.h"
#if IF_RDR
#ifdef VXWORKS
#include "vxWorks.h"
#endif
#include <stdio.h>
#include "ufstport.h"
#include "dbg_ufst.h"
#include "shareinc.h"
/*----------------------*/
/* merge */
/*----------------------*/
/* Merge the bitmap in the source buffer into the destination buffer
* so that the two origins coincide. It is assumed that the src bitmap
* will fit in the destination. There is no error checking.
*
* Fields in the IFBITMAP structure that must be valid:
*
* src dst
* _________________________
* width width
* depth
* left_indent
* top_indent
* black_width
* black_depth
*
*/
#if defined (ANSI_DEFS)
GLOBAL VOID merge(FSP PIFBITMAP src, PIFBITMAP dst, SW16VECTOR org)
#else
GLOBAL VOID
merge(src, dst, org)
PIFBITMAP src; /* Source buffer */
PIFBITMAP dst; /* Destination buffer */
SW16VECTOR org; /* source pixel origin (0,0) in destination bitmap */
#endif
{
SW16 ddx, ddy; /* pixel address of blackbox in destination bitmap */
LPCHUNK ps, pd; /* pointers used to merge the bitmaps. */
SW16 sstart; /* SB8 offset to starting SB8 of src blackbox */
SW16 dstart; /* SB8 offset to starting SB8 of dst blackbox */
SW16 sw; /* SB8 width of src blackbox */
SW16 dw; /* SB8 width of dst blackbox */
UW16 i,j;
UW16 mid_src_ct;
UW16 sbit0, dbit0;
UW16 sbit1, dbit1;
SW16 n, nb;
SW16 num_bytes;
DBG2("\nmerge(org in destination = (%d, %d)", org.x, org.y);
/* Compute pixel address of blackbox in destination space. Address
* is upper left corner of pixel with origin at upper left of bitmap.
*/
ddx = org.x;
ddy = dst->depth - (org.y + src->black_depth);
DBG2(" ddx, ddy %d, %d\n", ddx, ddy);
/* Compute overhangs. Sbit0 and dbit0 are the number of white chunks
* to the left of the black box in the left most chunks that intersect
* the black box.
* Sbit1 and dbit1 are the number of black bits in the right most
* chunks that intersect the black box.
*/
sbit0 = src->left_indent & (UW16)CHUNK_MASK;
dbit0 = ddx & (UW16)CHUNK_MASK;
sbit1 = (sbit0 + src->black_width) & (UW16)CHUNK_MASK; if(!sbit1) sbit1 = (UW16)CHUNK_MASK + 1;
dbit1 = (dbit0 + src->black_width) & (UW16)CHUNK_MASK; if(!dbit1) dbit1 = (UW16)CHUNK_MASK + 1;
DBG2(" sbit0 = %d dbit0 = %d\n", sbit0, dbit0);
DBG2(" sbit1 = %d dbit1 = %d\n", sbit1, dbit1);
/* Compute starting chunk offset along a raster and the number
* of chunks that covers the black width in a raster. Note that
* sw and dw can vary from each other by as much as 1 depending
* on overhangs.
*/
sstart = src->left_indent >> CHUNK_SHIFT;
dstart = ddx >> CHUNK_SHIFT;
sw = ((src->left_indent + src->black_width + (UW16)CHUNK_MASK) >> CHUNK_SHIFT) - sstart;
dw = ((ddx + src->black_width + (UW16)CHUNK_MASK) >> CHUNK_SHIFT) - dstart;
/* Set pointers */
ps = (LPCHUNK)((LPUB8)src->bm + (src->top_indent * src->width)) + sstart; /* 5-17-93 */
pd = (LPCHUNK)((LPUB8)dst->bm + (ddy * dst->width)) + dstart; /* 5-17-93 */
/* Special case if no shifting is required */
if(sbit0 == dbit0)
{
for(i=0; i<src->black_depth; i++)
{
for(j=0; j<sw; j++)
*pd++ |= *ps++;
ps += (src->width >> (CHUNK_SHIFT - 3)) - sw;
pd += (dst->width >> (CHUNK_SHIFT - 3)) - dw;
}
return;
}
/* Shifting case. Transfer each raster in (up to) three steps:
* 1. If src overhangs on left, then shift src and or into dst.
* 2. Transfer all "middle" src chunks that overlap two dst
* chunks (if any).
* 3. If src overhangs on right, then shift src and or into dst.
*/
/* number of source chunks to transfer in the middle loop, step 2 */
mid_src_ct = sw; /* Assume no overhangs, all src chunks are in step 2 */
if(sbit0 > dbit0) /* Source overhangs on left */
mid_src_ct--;
if(sbit1 < dbit1) /* Source overhangs on right */
mid_src_ct--;
DBG1(" mid_src_ct = %u\n", mid_src_ct);
/* Shifting values. Each source overlaps two dst chunks.
* Shift src chunk >> n before oring into left dst chunk
* Shift src chunk << nb before oring into right dst chunk
*/
n = dbit0 - sbit0; /* calculate n. Assume no left overhang */
if(n<0) /* If n < 0, then left overhnag and we really */
n = (SW16)CHUNK_MASK + 1 + n; /* calculated -nb, so convert to n. */
nb = (SW16)CHUNK_MASK + 1 - n;
DBG2(" n = %u nb = %u\n", n, nb);
/* For each raster in the black box shift and transfer the data from
* the source to the destination
*/
for(i=0; i<src->black_depth; i++)
{
/* Step 1. Take care of the case that the source overhangs the
* destination on the left. In this case, this first source chunk only
* contributes to one destination chunk.
*/
if(sbit0 > dbit0)
#if LEFT_TO_RIGHT_BIT_ORDER
*pd |= *ps++ << nb;
#else
*pd |= *ps++ >> nb;
#endif
/* Step 2. Transfer the middle data. For each source chunk, put
* a piece in each of the two destination chunk that it overlaps.
*/
for(j=0; j<mid_src_ct; j++)
{
#if LEFT_TO_RIGHT_BIT_ORDER
*pd++ |= *ps >> n;
*pd |= *ps++ << nb;
#else
*pd++ |= *ps << n;
*pd |= *ps++ >> nb;
#endif
}
/* Rule for pointers after each of these three steps:
* ps now points to the next src chunk to be processed.
* pd now points to the last dest chunk processed.
*/
/* Step 3. Take care of the case that the source overhangs the
* destination on the right. In this case, this last source chunk only
* contributes to one destination chunk.
*/
if(sbit1 < dbit1)
#if LEFT_TO_RIGHT_BIT_ORDER
*pd |= *ps++ >> n;
#else
*pd |= *ps++ << n;
#endif
/* On to the next raster */
num_bytes = src->width - (sw * sizeof(CHUNK));
ps += (num_bytes / sizeof(CHUNK));
num_bytes = sizeof(CHUNK) + dst->width - (dw * sizeof(CHUNK));
pd += (num_bytes / sizeof(CHUNK));
}
}
#endif /* IF_RDR */
metrics.c 、、、、、、、、、、、、、、、、、、、、、、、、
/* Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved. */
/* $Header: I:/BULL/URIP/RTS/BMP/METRICS.C_V 1.52 Aug 26 2004 14:33:06 wuq $ */
/* $Log: I:/BULL/URIP/RTS/BMP/METRICS.C_V $
*
* Rev 1.52 Aug 26 2004 14:33:06 wuq
* Removed GET_VERTICAL_METRICS conditional
* from non output structure.
*
* Rev 1.51 Oct 09 2003 12:57:38 IndrelR
* Changes for Vertical Writing
*
* Rev 1.50 Aug 21 2003 16:47:48 Galejs
* update copyright notice
*
* Rev 1.49 Jun 19 2003 18:26:34 Galejs
* get rid of NON_IF_FONT
*
* Rev 1.48 Jun 28 2001 19:01:16 Galejs
* fix minor compiler warning
*
* Rev 1.47 10 Jul 2000 09:41:14 JOE
* Modified calculation of vertical_metric (no /2) for TT Disk/ROM (by keb).
*
* Rev 1.46 19 Apr 2000 11:11:54 JOE
* For TT_ROM or TT_DISK, added code to metrics() to replace escapement
* with advanceHeight, if advanceHeight exists and is different from
* escapement, and vertical writing is enabled (by keb).
*
* Rev 1.45 Mar 24 2000 17:10:48 galejs
* fix unused-vbl compiler warnings
*
* Rev 1.44 Mar 22 2000 15:22:26 galejs
* more vertical-writing changes (for keb)
*
* Rev 1.43 Jan 24 2000 12:44:14 galejs
* vertical-writing changes (for keb)
*
* Rev 1.42 Dec 10 1999 16:29:12 galejs
* remove redundant define MASK_ASIAN_ENC
*
* Rev 1.41 Aug 17 1999 17:59:04 galejs
* fix compiler warnings about unknown #pragmas
*
* Rev 1.40 Aug 10 1999 14:50:20 galejs
* include-file changes
*
* Rev 1.39 24 Feb 1999 13:12:28 JOE
* Conditionally compiled test to set 'mkchg' in metrics() (by keb).
*
* Rev 1.38 11 Feb 1999 13:45:16 JOE
* Modified the code in metrics() that adjusts the x and y origin for
* vertical writing with XL soft fonts (by keb).
*
* Rev 1.37 13 Jan 1999 14:19:10 MARTIN
* Removed declarations for rot_in_deg and rot_in_rad.
*
* Rev 1.36 15 Dec 1998 14:36:14 JOE
* Modified metrics(). No divide by 2 for "adjx" and "adjy" (by keb)
*
* Rev 1.35 15 Dec 1998 10:44:24 JOE
* Fixed comment delimiters (by ks).
*
* Rev 1.34 15 Dec 1998 09:44:46 JOE
* In metrics(), conditionally compiled code which referenced "XLfont",
* "yDescender" and "top_bearing" based on TT_PCLEOI to resolve
* compiler errors.
*
* Rev 1.33 14 Dec 1998 08:37:24 JOE
* Removed extra tabs (by keb).
*
* Rev 1.32 11 Dec 1998 11:42:40 JOE
* Added code to support ASIANVERT for XLfonts (by keb).
*
* Rev 1.31 22 Jun 1998 18:51:06 GALEJS
* mkae Intellifont reentrant too
*
* Rev 1.30 15 Jun 1998 16:47:50 GALEJS
* reentrancy parameter-passing changes
*
* Rev 1.29 15 Apr 1998 16:54:34 GALEJS
* move chr_def_hdr to IF_STATE
*
* Rev 1.28 14 Apr 1998 18:57:50 GALEJS
* move "special_case" to IF_STATE
*
* Rev 1.27 02 Apr 1998 18:47:10 GALEJS
* move externs to if_state
*
* Rev 1.26 24 Mar 1998 14:50:08 GALEJS
* include-file changes
*
* Rev 1.25 03 Mar 1998 16:10:10 JOE
* Added ASIANVERT metrics adjustments (by dah).
*
* Rev 1.24 23 Feb 1998 15:03:50 AL
* Added ASIANVERT
*
* Rev 1.23 13 Jan 1997 16:25:58 DAVID
* Removed CONVERGENT_FONTS option as part of project to
* trim ufst.
*
* Rev 1.22 10 Jan 1997 14:01:32 DAVID
* Removed ELASTIC_X and ELASTIC_Y as part of project to trim ufst.
*
* Rev 1.21 20 Mar 1996 12:10:10 MERRILL
* quiet sig warns
*
* Rev 1.20 05 Jan 1996 09:42:18 MERRILL
* consolidate pixelwidth, disc
*
* Rev 1.19 15 Dec 1995 13:14:40 MERRILL
* remove cast to 32 of shift amount in calls to fp_to_16
*
* Rev 1.18 04 Dec 1995 13:03:02 MERRILL
*
* added conditionalon IF_RDR to variable definitions.
*
* Rev 1.17 06 Apr 1995 15:08:16 LISA
*
* Changed copyright from Miles Inc. to Bayer Corp.
*
* Rev 1.16 11 Dec 1994 17:31:26 MIKE
*
* Changed if_state.cs.origin to "origin_cs".
*
* Rev 1.15 02 May 1994 11:49:04 MIKE
* Conditionally compile 1.14 change based on SLIM_FONTS.
*
* Rev 1.14 27 Apr 1994 17:08:04 MIKE
* Add new special case for mirror, oblique for rotation 90.
*
* Rev 1.13 27 Apr 1994 10:58:02 MIKE
* In metrics(), handle special case of mirrored, obliqued characters.
*
* Rev 1.12 22 Apr 1994 10:31:14 JOE
* Added missing comment delimiter at start of line prior to "History".
*
* Rev 1.11 22 Apr 1994 09:20:44 LISA
*
* Modified copyright/disclaimer notice.
*
* Rev 1.10 08 Mar 1994 15:52:06 JOE
* Corrected external declaration for variable "special_case".
* Was missing type "SW16".
*
* Rev 1.9 06 Mar 1994 14:11:18 MIKE
*
* Adjust character's horizontal position only if CONVERGENT_FONTS == 1.
*
* Rev 1.8 03 Feb 1994 14:22:48 MIKE
* Adjust character horizontal position for Convergent Fonts.
*
* Rev 1.7 22 Sep 1993 16:06:10 JOE
* In metrics(), conditionally compiled block of code which checks for
* mirrored character before distributing alternate width based on
* SLIM_FONTS.
*
* Rev 1.6 07 Sep 1993 17:15:34 MIKE
*
* Fix bug in x-origin for mirrored characters using alternate widths.
*
* Rev 1.5 14 Jun 1993 09:17:54 JOE
* In metrics(), in calls to fp_to_16() for calculating bm->yorigin, cast each
* member of expression for first argument to SL32 to prevent SW16 calculation.
*
* Rev 1.4 12 Feb 1993 11:16:34 JOE
* VXWorks support.
*
* Rev 1.3 29 Jan 1993 09:25:24 JOE
* In metrics(), saved em box size in IFBITMAP structure for IF, PS and TT.
*
* Rev 1.2 05 Jan 1993 16:10:00 JOE
* ANSI C function declaration changes.
*
* Rev 1.1 14 Dec 1992 09:29:58 LISA
* Made change to Log keyword
*
* Rev 1.0 10 Dec 1992 08:32:56 LISA
* Initial revision.
*/
/* $Date: Aug 26 2004 14:33:06 $ */
/* metrics.c */
/*
* History
*
* 03-27-90 jfd In "metrics()", instead of splitting the difference
* between the alternate width and the real width
* and applying that value to both "x0" and "x1",
* apply it only to "x0" and set "x1" equal to "x0"
* plus the alternate width. This will ensure the
* proper escapement. It was off by 1 design unit
* in some cases.
* 05-22-90 awr Corrected yorigin calculation to use the grid
* alligned baseline (d.aBaselnVal) instead of the
* the unaligned version.
* 05-22-90 awr Added metric calculations for quadrant rotations
* 09-04-90 awr Declared des2wrkbm() to fix compiler warning,
* removed rot90() declaration.
* 05-Oct-90 awr Added connecting character side bearing calculation
* 28-Jan-91 jfd Conditionally compiling fp_to_16() based on
* (MAX_BM_BITS > 16)
* Including "cgconfig.h".
* 30-Jan-91 dET Added function prototyping for MSC
* 31-Jan-91 dET Added support for multi-model MSC compilation
* 3-Feb-91 awr Removed include imath.h- not needed,
* updated copyright.
* 8-Feb-91 awr Moved inv_des2wrkbm() to scale.c
* Changed name des2wrkbm() to des2bm()
* and inv_des2wrkbm() to inv_des2bm().
* 11-Mar-91 awr Changed return value of des2bm() and inv_des2bm
* to PWORDVECTOR
* 05-Jun-91 jfd In metrics(), in case of 90 or 270 degree rotation,
* when calculatin lb.y, use bm->depth instead of
* d.bmdepth (FIX FROM EARLIER VERSION)
* 9-Jun-91 awr changed metrics() parameters
* 17-Jun-91 jfd Moved "debug.h" after "port.h".
* 4-Jul-91 awr Removed SCALE fields "px" and "py".
* 8-Jul-91 bjg Added Elasticity.
* 5-Aug-91 tbh Cleaned up Elasticity.
* 10 Aug 91 ss Added code to support mirrored chars and -ROTs.
* 24-Aug-91 awr Changed calling sequence of des2bm()
* 27-Aug-91 bjg Add special case handling for mirrored chars
* 1-Sep-91 awr Included "bitmap.h"
* 17-Sep-91 jfd Changed fp_to_16() to LONG instead of WORD.
* In metrics(), calling DBG2() unconditionally now.
* 20-Sep-91 jfd In metrics(), when calculating xorigin and yorigin,
* cast operands as LONG due to change in type to LONG
* for xorigin and yorigin.
* 30-Oct-91 awr Corrected lsb calculations for connecting chars.
* 5-Feb-92 awr In short_metrics(), changed the way x and y origins
* are calculated.
* 7-Mar-92 awr Changed metrics() to read design bounding box from
* if_state
* 03-Apr-92 rs Portability cleanup (see port.h).
* 10 Apr 92 ss Don't reset special_case flag here any more.
* 09-Jun-92 jfd In metrics(), load "org" with contents of
* "if_state.cs.dorigin", not "if_state.cs.origin".
* 21-Jun-92 awr Conditionally compiled
* 28-Jun-92 awr Changed TT & PS for 16bit scan conversion
* 08-Jul-92 rs Code cleanup.
* 21-Jul-92 awr Conditional compile changes
* 11-Aug-92 jfd Trying macro MDES2BM for optimization.
* Included imath.h.
* 05-Jan-93 jfd ANSI C function declaration changes.
* 25-Jan-93 jfd In metrics(), store size of em box ("du_emx" and
* "du_emy") into IFBITMAP structure for IF, PS and TT.
* 08-Feb-93 jfd VXWorrks support.
* 14-Jun-93 jfd In metrics(), in calls to fp_to_16() for calculating
* bm->yorigin, cast each member of expression for first
* argument to SL32 to prevent truncation to SW16.
* 01-Sep-03 mby In metrics() if if_state.alt_width is on and the character
* is mirrored in X, adjust the x-origin in the opposite
* direction, because of a previous reflection.
* 22-Sep-93 jfd In metrics(), conditionally compiled block of code
* which checks for mirrored character before distribu-
* ting alternate width based on SLIM_FONTS.
* 25-Jan-94 mby Adjust character position by lsb_adj in metrics()
* for Convergent Fonts.
* 06-Mar-94 mby Use lsb_adj only if CONVERGENT_FONTS == 1.
* 08-Mar-94 jfd Corrected external declaration for variable
* "special_case". Was missing type "SW16".
* 22-Apr-94 jfd Added missing comment delimiter at start of line
* prior to "History".
* 26-Apr-94 mby/ In metrics() for special_case of mirrored, obliqued
* bjg characters, (1) set origin to character baseline;
* (2) adjust bm->xorigin,yorigin.
* 27-Apr-94 mby/ In metrics() add new special case for p0 for
* bjg rotation of 0 and rotation of 90.
* 02-May-94 mby Conditionally compile above change to SLIM_FONTS.
* 11-Dec-94 mby Change if_state.cs.origin to "origin_cs".
* 10-Jan-97 dlk Removed ELASTIC_X and ELASTIC_Y as part of project
* to trim ufst.
* 13-Jan-97 dlk Removed CONVERGENT_FONTS option as part of project to
* trim ufst.
* 02-Mar-98 dah Added ASIANVERT metric adjustments
* 11-Dec-98 keb Added code to support ASIANVERT for XLfonts
* 15-Dec-98 jfd In metrics(), conditionally compiled code which
* references the fields "XLfont", "yDescender" and
* "top_bearing" based on TT_PCLEOI to resolve compiler
* error.
* 15-Dec-98 keb Modified metrics(). No divide by 2 for "adjx" and
* adjy.
* 11-Feb-99 keb Modified the code in metrics() that adjusts the x and y origin
* for vertical writing with XL soft fonts
* 24-Feb-99 keb Conditionally compile the test to set mkchg in metrics()
* 18-Jan-00 slg Vertical-writing changes (for keb) - replace big
* #if-ASIANVERT section with if-FC_ISUFSTVERT() section.
* 21-Mar-00 keb added back code to process format16 fonts in vertwrit mode
* 14-Apr-00 keb For TT_ROM or TT_DISK added code to metrics() to replace escapement
* with advanceHeight, if advanceHeight exists and is different from
* escapement, and vertical writing is enabled
* 06-Jul-00 keb modified calculation of vertical_metric (no /2) for TT Disk/Rom
*/
#ifdef VXWORKS
#include "vxWorks.h"
#endif
#include <stdio.h>
#include <math.h>
#include "cgconfig.h"
#include "ufstport.h"
#include "dbg_ufst.h"
#include "shareinc.h"
#include "imath.h"
#ifdef LINT_ARGS
MLOCAL SL32 fp_to_16(SL32, PCOORD_DATA);
#else /* no LINT_ARGS */
MLOCAL SL32 fp_to_16();
#endif /* LINT_ARGS */
/*----------------------*/
/* fp_to_16() */
/*----------------------*/
/* Convert working bitmap space fractional pixels to 16ths of a pixel */
#if defined (ANSI_DEFS)
MLOCAL SL32 fp_to_16(SL32 v, PCOORD_DATA xy)
#else
MLOCAL SL32
fp_to_16(v, xy)
SL32 v;
PCOORD_DATA xy;
#endif
{
SL32 val;
val = LABS(v);
val = (val * 16 + xy->half_pixel) >> xy->grid_shift;
if(v<0)
return -val;
else
return val;
}
/*----------------------*/
/* metrics */
/*----------------------*/
#if defined (ANSI_DEFS)
GLOBAL VOID metrics(FSP PIFBITMAP bm)
#else
GLOBAL VOID
metrics(bm)
PIFBITMAP bm;
#endif
{
SW16VECTOR org;
SW16 escx;
SW16 adj_width;
#if IF_RDR
SW16 orig_black_width;
SW16 new_black_width;
SW16 orig_lsb;
SW16 new_lsb;
SW16VECTOR lb, rb; /* left & right bound (fractional pixels) */
SW16VECTOR dlb, drb; /* left & right bound (design units) */
SW16VECTOR new_org; /* character origin (design units) */
SW16VECTOR p0; /* character origin (fractional pixels) */
#endif
SL32VECTOR p;
DBG("metrics()\n");
org = if_state.cs.dorigin; /* 6-9-92 */
escx = if_state.cs.escapement;
/* Adjust escape box for alternate width (if any) */
if(if_state.alt_width > 0) /* not supposed to be negative, ignore if < 0 */
{
/* Distribute the alternate width change equally (not proportionately)
* over each side bearing.
*/
DBG1(" alternate width = %d\n", if_state.alt_width);
adj_width = (if_state.alt_width - escx) / 2;
#if SLIM_FONTS
if (if_state.chr_def_hdr.mirror_flags & MIRROR_X_MASK) /* mby 9-01-93 */
org.x += adj_width;
else
#endif
org.x -= adj_width;
escx = if_state.alt_width;
DBG3(" alt origin (%d, %d) escapement %d\n",
org.x, org.y, escx);
}
bm->escapement = escx;
if(if_state.fst_type != FC_IF_TYPE)
{
DBG("short_metrics()\n");
p.x = ((SL32)if_state.cs.origin_cs.x + (SL32)if_state.xlate.x)
>>if_state.right_shift;
p.y = ((SL32)if_state.cs.origin_cs.y + (SL32)if_state.xlate.y)
>>if_state.right_shift;
bm->xorigin = - fp_to_16(p.x, &if_state.x);
bm->yorigin = fp_to_16((SL32)((SL32)bm->depth << log_ypix) - p.y, &if_state.y);
/* keb */
if ( FC_ISUFSTVERT(&if_state.fcCur) )
{
if ( if_state.CharVertWrit )
{
#if TT_RDR
SW16 dx, dy, vertical_metric;
FPNUM fdx, fdy, em;
#endif
SL32 adjx, adjy;
adjx = 0;
adjy = 0;
#if TT_RDR
if(FC_ISXLFONT(&if_state.fcCur))
{
vertical_metric = if_state.pbucket->p.tt.FontBBox[1];
dx = vertical_metric;
dy = -(if_state.cs.du_emx + vertical_metric);
em = fpint2fp ((SL32) if_state.cs.du_emx);
fdx = fpint2fp((SL32)dx);
fdy = fpint2fp((SL32)dy);
fdx = fpdiv (fdx, em);
fdy = fpdiv (fdy, em);
adjx = fp2long( fpadd ( fpmul (fdx, if_state.m[0] ),
fpmul (fdy, if_state.m[2] ) ) );
adjy = fp2long( fpadd ( fpmul (fdx, if_state.m[1] ),
fpmul (fdy, if_state.m[3] ) ) );
adjx = (adjx << 4) ;
adjy = (adjy << 4) ;
}
if ((FC_ISTT(&if_state.fcCur)) & (if_state.pbucket->extern_font == 0))
{
/* #if GET_VERTICAL_METRICS 08-20-04 qwu */
/* keb 4/00 */
if ((if_state.cs.escapement != if_state.cs.advanceHeight) & (if_state.cs.advanceHeight != 0))
{
if_state.cs.escapement = if_state.cs.advanceHeight;
bm->escapement = if_state.cs.advanceHeight;
}
/* #endif 08-20-04 qwu */
vertical_metric = if_state.cs.yDescender;
dx = vertical_metric;
dy = -(if_state.cs.du_emx + vertical_metric);
em = fpint2fp ((SL32) if_state.cs.du_emx);
fdx = fpint2fp((SL32)dx);
fdy = fpint2fp((SL32)dy);
fdx = fpdiv (fdx, em);
fdy = fpdiv (fdy, em);
adjx = fp2long( fpadd ( fpmul (fdx, if_state.m[0] ),
fpmul (fdy, if_state.m[2] ) ) );
adjy = fp2long( fpadd ( fpmul (fdx, if_state.m[1] ),
fpmul (fdy, if_state.m[3] ) ) );
adjx = (adjx << 4) ;
adjy = (adjy << 4) ;
}
if (FC_ISTTFMT16(&if_state.fcCur))
{
vertical_metric = if_state.cs.yDescender;
dx = vertical_metric;
dy = -(if_state.cs.du_emx + vertical_metric);
em = fpint2fp ((SL32) if_state.cs.du_emx);
fdx = fpint2fp((SL32)dx);
fdy = fpint2fp((SL32)dy);
fdx = fpdiv (fdx, em);
fdy = fpdiv (fdy, em);
adjx = fp2long( fpadd ( fpmul (fdx, if_state.m[0] ),
fpmul (fdy, if_state.m[2] ) ) );
adjy = fp2long( fpadd ( fpmul (fdx, if_state.m[1] ),
fpmul (fdy, if_state.m[3] ) ) );
adjx = (adjx << 4) ;
adjy = (adjy << 4) ;
}
#endif
bm->xorigin += adjx;
bm->yorigin += adjy;
}
}/* if ISUFSTVERT end */
/* Store size of em box */
bm->du_emx = if_state.cs.du_emx;
bm->du_emy = if_state.cs.du_emy;
return;
}
#if IF_RDR
/* Compute vector (xorigin, yorign) in 16ths of an output pixel.
* step 1. Compute (p0.x, p0.y) the character origin in working
* bitmap space.
* step 2. Compute (xorigin, yorigin).
*/
/*---------step 1-------------------------*/
/* If arbitrary rotation, simply transfer the design origin to
* working bitmap space. If special 90 degree rotation, then we
* take into account the change in the character's black width
* and distribute this change equally over both side bearings.
*/
if(!if_state.quadrant) /* arbitrary rotation */
{
DBG(" Arbitrary rotate: ");
/* Transform character origin to working bitmap space */
#if defined MDES2BM
p0 = MDES2BM(org);
#else
p0 = des2bm(FSA org);
#endif /* defined MDES2BM */
#if SLIM_FONTS /* mby, 4/26 - 5/1/94 */
if (if_state.special_case && if_state.shear == ROT0)
{ /* rotation is 0/180 and shear is nonzero */
SW16 savex = p0.x;
org.y = if_state.escape_box.ll.y;
#if defined MDES2BM
p0 = MDES2BM(org); /* p0 is the transform of the character */
#else /* origin in X, and the character baseline */
p0 = des2bm(FSA org); /* in Y. */
#endif /* defined MDES2BM */
p0.x = savex;
}
else if (if_state.special_case && if_state.shear == ROT90)
{
SW16 savey = p0.y;
org = if_state.escape_box.ll; /* x and y */
#if defined MDES2BM
p0 = MDES2BM(org);
#else
p0 = des2bm(FSA org);
#endif /* defined MDES2BM */
p0.y = savey;
}
#endif /* SLIM_FONTS */
}
else /* special 0, 90, 180, or 270 degree rotation */
{
/* Intellifont is on.
*/
SW16 tmp;
if(if_state.quadrant==ROT0 || if_state.quadrant==ROT180
/* added -ss */
|| if_state.quadrant == -ROT0 || if_state.quadrant == -ROT180)
{
lb.y = rb.y = 0;
/* assume ROT0, swap if ROT180 */
lb.x = bm->left_indent << log_xpix;
rb.x = lb.x + (bm->black_width << log_xpix);
if( if_state.quadrant == ROT180
|| if_state.quadrant == -ROT0 )
{
tmp = lb.x;
lb.x = rb.x;
rb.x = tmp;
}
}
else
{
lb.x = rb.x = 0;
/* Assume ROT270, swap if ROT90 */
lb.y = (bm->depth - bm->top_indent) << log_ypix;
rb.y = lb.y - (bm->black_depth << log_ypix);
if( if_state.quadrant == ROT90
|| if_state.quadrant == -ROT270 )
{
tmp = lb.y;
lb.y = rb.y;
rb.y = tmp;
}
}
dlb = inv_des2bm(FSA lb);
drb = inv_des2bm(FSA rb);
DBG2("lb = (%d, %d)\n", lb.x, lb.y);
DBG2("rb = (%d, %d)\n", rb.x, rb.y);
DBG2("dlb = (%d, %d)\n", dlb.x, dlb.y);
DBG2("drb = (%d, %d)\n", drb.x, drb.y);
orig_lsb = if_state.cs.dxmin - org.x;
if(if_state.ConnectingChar)
{
pixel_align (FSAvoid org.x, &if_state.x, R_TWO_I);
new_lsb = dlb.x - if_state.value;
DBG(" ConnectingChar:\n");
DBG2(" orig_lsb %d new_lsb %d\n", orig_lsb, new_lsb);
}
else
{
orig_black_width = if_state.cs.dxmax - if_state.cs.dxmin;
new_black_width = drb.x - dlb.x;
new_lsb = orig_lsb + (orig_black_width - new_black_width)/2;
DBG2(" orig_lsb %d new_lsb %d\n", orig_lsb, new_lsb);
}
new_org.x = dlb.x - new_lsb;
new_org.y = if_state.aBaselnVal;
/* Fix for one part compound char with nonzero offset. */
/* There may still be a bug for multiple part chars with nonzero */
/* offset in first part. -ss,bjg 7/23/91 */
if( if_state.chr_def[0].offset.y )
new_org.y -= if_state.chr_def[0].offset.y;
DBG2("new_org = (%d, %d)\n", new_org.x, new_org.y);
#if defined MDES2BM
p0 = MDES2BM(new_org);
#else
p0 = des2bm(FSA new_org);
#endif /* defined MDES2BM */
}
DBG2(" (p0.x, p0.y) = (%d, %d)\n", p0.x, p0.y);
/*---------step 2-------------------------*/
bm->xorigin = - fp_to_16((SL32)p0.x, &if_state.x);
/* IF_RDR dependent */
bm->yorigin = fp_to_16((SL32)(((SL32)bm->depth << log_ypix) - p0.y),
&if_state.y);
#if SLIM_FONTS
#if defined(__BORLANDC__)
#pragma warn -sig /* Conversion may lose significant digits */
#endif
/* handle special case of mirrored characters */
if( if_state.special_case &&
(if_state.quadrant==ROT0 || if_state.quadrant==ROT180
|| if_state.quadrant == -ROT0 || if_state.quadrant == -ROT180
|| if_state.shear == ROT0) ) /* test for shear -mby 4-26-94 */
bm->yorigin = (SL32)((SL32)bm->top_indent<<5L) +
(SL32)((SL32)bm->black_depth<<4L) -
bm->yorigin;
if( if_state.special_case &&
(if_state.quadrant==ROT90 || if_state.quadrant==ROT270
|| if_state.quadrant == -ROT90 || if_state.quadrant == -ROT270
|| if_state.shear == ROT90) ) /* test for shear */
bm->xorigin = - (SL32)((SL32)bm->left_indent<<5L) -
(SL32)((SL32)bm->black_width<<4L) -
bm->xorigin;
/** don't reset this here, its used again later. -ss 4/10/92 **
if_state.special_case = 0;
**/
#ifdef __BORLANDC__
#pragma warn +sig
#endif
#endif /* SLIM_FONTS */
/* Store size of em box */
bm->du_emx = if_state.cs.du_emx;
bm->du_emy = if_state.cs.du_emy;
#endif /* IF_RDR */
}
mixmodel.h 、、、、、、、、、、、、、、、、、、、、、、、、、、
/* Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved. */
/* $Header: I:/BULL/URIP/RTS/INC/MIXMODEL.H_V 1.20 Aug 21 2003 17:10:20 Galejs $ */
/* $Log: I:/BULL/URIP/RTS/INC/MIXMODEL.H_V $
*
* Rev 1.20 Aug 21 2003 17:10:20 Galejs
* update copyright notice
*
* Rev 1.19 Sep 20 2002 20:14:50 Galejs
* test for multiple includes (part of bug # 76)
*
* Rev 1.18 Jun 12 2001 17:40:26 Galejs
* data-type cleanup - use INTG type for int, for safety's sake
*
* Rev 1.17 17 Mar 2000 11:55:50 JOE
* Added '#define MEMSET ulongmemset' (by ks).
*
* Rev 1.16 Aug 12 1999 15:58:28 galejs
* add GCCx86 case (for GNU compiler under Windows)
*
* Rev 1.15 06 Aug 1998 15:56:18 AL
* CFF_ROM support
*
* Rev 1.14 30 Mar 1998 11:36:30 GALEJS
* add O_RDONLY define for OS-9000 compile
*
* Rev 1.13 20 Mar 1998 12:00:08 GALEJS
* 64-bit port
*
* Rev 1.12 02 Jan 1997 14:42:20 DAVID
* No change.
*
* Rev 1.11 23 Sep 1996 14:01:32 PVCSADMN
* Provided change for MicroSoft Visual C 4.x MSVC.
*
* Rev 1.10 20 Mar 1996 10:28:22 MERRILL
* included <mem.h> @ln 160 for memset prototypes
*
* Rev 1.9 07 Apr 1995 08:45:18 LISA
* Changed copyright from Miles Inc. to Bayer Corp.
*
* Rev 1.8 21 Apr 1994 15:48:44 LISA
* Made modifications to copyright/disclaimer notice.
*
* Rev 1.7 09 Feb 1994 13:34:16 JOE
* _AM29K changes.
*
* Rev 1.6 08 Dec 1993 18:58:02 ROB
* General cleanup for MSDOS, FLAT, OS2.
*
* Rev 1.5 09 Jun 1993 16:47:06 JOE
* Changed all references to "char" to "SB8" for transportability.
*
* Rev 1.4 22 Feb 1993 11:04:52 JOE
* Added conditional compile for O_READFLAGS define (VXWORKS) to resolve
* compiler error for OPEN call.
*
* Rev 1.3 12 Feb 1993 14:33:30 JOE
* VXWorks support.
*
* Rev 1.2 15 Jan 1993 09:35:28 LISA
* Removed CtrlZ character from end of file
*
* Rev 1.1 14 Dec 1992 09:42:16 LISA
* Made change to Log keyword
*
* Rev 1.0 10 Dec 1992 09:11:32 LISA
* Initial revision.
*/
/* $Date: Aug 21 2003 17:10:20 $ */
/************************************************************************/
/*
* Function definitions
*
*
*/
/************************************************************************/
/* special Borland C++ version - 3-7-92 - rs */
/*
* History:
*
* 03-DEC-90 dET - original
*
*
* The common problem of mapping various I/O and string functions to the
* respective operating system/compilers is partialy addressed forthwith.
* Three cases exist. MSDOS, MS WINDOWS, and standard 'C'. We map various
* functions to other functions because of the stdio differences. In the
* SMALL, MEDIUM, and TINY models of the MSC and MS WINDOWS compilation,
* these functions take far pointers to arguments rather than near pointers.
*
*
* 24 Jun 91 ss Deleted O_BINARY from default O_READFLAGS & O_WRITEFLAGS.
* Changed define SEEK to LSEEK for default.
* 19-Jul-91 jfd Changed "MSWINDOWS" to "_WINDOWS".
* 26-Jul-91 jfd Added STRCAT and SPRINTF.
* 07-Aug-91 jfd Added function prototype for _fstrcat() and wsprintf().
* Changed conditional compile statement so that the
* section of code that was meant to be run only if
* !MSC && !_WINDOWS does not run if MSC.
* 24-Sep-91 jfd Added #define for QSORT.
* 03-Mar-92 rs Add '_fstrcmp()'.
* 04-Mar-92 rs Add STRSTR = '_fstrstr()'.
* 07-Mar-92 rs Add support for Borland C++ compiler. Make 'MSC'
* more like 'MSDOS' where appropriate.
* 15-Mar-92 rs Move Borland specific things to 'port.h'.
* 03-Apr-92 rs Portability cleanup (see port.h).
* 11-Jun-92 rs wsprintf fix for Borland C++.
* 05-Aug-92 jfd Added MEMCMP and MEMSET.
* 08-Aug-92 rs Changes for Watcom C386 compiler.
* 08-Feb-93 jfdf Changed READ to READF and WRITE to WRITEF due to
* conflict with VXWorks.
* 17-Feb-93 jfd Resolve VXWORKS compiler error when calling OPEN by
* changing #define for O_READFLAGS to "O_RDONLY, 0x644".
* 09-Jun-93 jfd Changed all references to "char" to "SB8" for
* transportability.
* 08-Dec-93 rs General cleanup - MSDOS & WATCOMC -> CGFLAT32.
* 09-Feb-94 jfd/dbk _AM29K changes.
* 12-Sep-96 dbk Provided change for MicroSoft Visual C 4.x(MSVC)
* 09-Mar-98 slg Don't use "long" dcls (incorrect if 64-bit platform)
* 30-Mar-98 slg Add O_RDONLY define for OS-9000 compile
* 05-Aug-98 awr Changed !ROM to DISK_FONTS
* 12-Aug-99 slg Add GCCx86 case, to fix premature end-of-read problem
* when using GNU compiler in a Windows environment.
* 16-Mar-00 ks Add #define MEMSET ulongmemset() to handle sizes > 64K
* on system with 16 bit ints.
*
*/
#ifndef __MIXMODEL__
#define __MIXMODEL__
/*
Borland compiler decisions depend upon the following manifest constants:
__BORLANDC__
_Windows
if Borland C++ compiler - fake out the system to make it appear as
if we are running the Microsoft 6.0 compiler as follows:
NON-WINDOWS
MODEL \ MSC _WINDOWS M_I86TM M_I86SM M_I86MM M_I86CM M_I86LM _MSC_VER
-----------------------------------------------------------------------------
SMALL + - - + - - - 600
MEDIUM + - - - + - - 600
COMPACT + - - - - + - 600
LARGE + - - - - - + 600
WINDOWS
MODEL \ MSC _WINDOWS M_I86TM M_I86SM M_I86MM M_I86CM M_I86LM _MSC_VER
-----------------------------------------------------------------------------
SMALL - + - + - - - 600
MEDIUM - + - - + - - 600
COMPACT - + - - - + - 600
LARGE - + - - - - + 600
These definitions are taken care of in 'port.h'
*/
/* if small or medium (tiny?) MS `C' model then define pointers as far */
#if USING_16_BIT_DOS
#if (defined(UFST_MSDOS) && !defined(_WINDOWS))
#define O_READFLAGS O_BINARY | O_RDONLY
#define O_WRITEFLAGS O_BINARY | O_WRONLY| O_CREAT
#if (defined(M_I86SM) || defined(M_I86MM) || defined(M_I86TM))
#define STRLEN _fstrlen
#define STRCPY _fstrcpy
#define STRNCPY _fstrncpy
#define STRNCMP _fstrncmp
#define STRCMP _fstrcmp
#define MEMCPY _fmemcpy
#define STRCAT _fstrcat
#define OPEN open
#define READF MMread
#define LSEEK lseek
#define WRITEF MMwrite
#define CLOSE close
#define SPRINTF sprintf
#define QSORT _fqsort
#define STRSTR _fstrstr
#define MEMCMP _fmemcmp
#define MEMSET _fmemset
#else /* large model (all pointers are far) */
//#include <mem.h>
#define STRLEN strlen
#define STRCPY strcpy
#define STRNCPY strncpy
#define STRNCMP strncmp
#define STRCMP strcmp
#define STRCAT strcat
#define MEMCPY memcpy
#define OPEN open
#define READF read
#define LSEEK lseek
#define WRITEF write
#define CLOSE close
#define SPRINTF sprintf
#define QSORT qsort
#define STRSTR strstr
#define MEMCMP memcmp
#define MEMSET memset
#endif /* defined(M_I86SM) || defined(M_I86MM) || defined(M_I86TM) */
#else /* defined(UFST_MSDOS) && !defined(_WINDOWS) */
#define O_READFLAGS 0 /* OF_READ as defined in windows.h */
#define O_WRITEFLAGS 1 /* OF_WRITE */
#if (defined(M_I86LM))
#define STRNCPY strncpy
#define STRNCMP strncmp
#define MEMCPY memcpy
#define QSORT qsort
#define STRSTR strstr
#define MEMCMP memcmp
#define MEMSET memset
#else /* WINDOWS, not large model */
#define STRNCPY _fstrncpy
#define STRNCMP _fstrncmp
#define MEMCPY _fmemcpy
#define QSORT _fqsort
#define STRSTR _fstrstr
#define MEMCMP _fmemcmp
#define MEMSET _fmemset
#endif /* WINDOWS & M_I86LM */
/*
Windows, all models
*/
#define STRLEN lstrlen
#define STRCPY lstrcpy
#define STRCMP lstrcmp
#define STRCAT lstrcat
#define OPEN _lopen
#define READF _lread
#define LSEEK _llseek
#define WRITEF _lwrite
#define CLOSE _lclose
#if defined (__BORLANDC__) /* add 6/11/92 - rs */
#define wsprintf WSPRINTF
#endif /* __BORLANDC__ */
#define SPRINTF wsprintf
#endif
#else /* not USING_16_BIT_DOS, i.e. the code we actually use now... */
#if defined (MSVC)
#define O_READFLAGS O_BINARY | O_RDONLY
#define O_WRITEFLAGS O_BINARY | O_WRONLY| O_CREAT
#elif defined (GCCx86)
#define O_READFLAGS O_BINARY | O_RDONLY
#define O_WRITEFLAGS O_BINARY | O_WRONLY| O_CREAT
#elif defined (__WATCOMC__)
#define O_READFLAGS O_BINARY | O_RDONLY
#define O_WRITEFLAGS O_BINARY | O_WRONLY| O_CREAT
#elif defined (__i960)
#define O_READFLAGS O_BINARY | O_RDONLY
#define O_WRITEFLAGS O_BINARY | O_WRONLY| O_CREAT
#elif defined (VXWORKS)
#define O_READFLAGS O_RDONLY,0x644
#define O_WRITEFLAGS WRITE
#else
/*** This default case won't work if your environment's file system has the
Text/Binary distinction (e.g. Windows/DOS). If this is the case, you will need
to clone a new case using BINARY, to prevent premature end-of-read. ***/
#define O_READFLAGS O_RDONLY /* deleted O_BINARY -ss 6/24/91 */
#define O_WRITEFLAGS O_WRONLY | O_CREAT /* deleted O_BINARY -ss 6/24/91 */
#endif /* MSVC */
#if defined _AM29K /* 2-7-94 jfd,dbk */
#define OPEN _open
#define CLOSE _close
#define LSEEK _lseek
#define READF _read
#else
#define OPEN open
#define CLOSE close
#define LSEEK lseek /* correct define from SEEK to LSEEK -ss 6/24/91 */
#define READF read
#endif /* AM29K*/
#define STRLEN strlen
#define STRCPY strcpy
#define STRNCPY strncpy
#define STRNCMP strncmp
#define STRCMP strcmp
#define MEMCPY memcpy
#define STRCAT strcat
#define WRITEF write
#define SPRINTF sprintf
#define QSORT qsort
#define STRSTR strstr
#define MEMCMP memcmp
#define MEMSET memset
#endif /* USING_16_BIT_DOS */
/* function prototypes for MSC */
#if (USING_16_BIT_DOS && !defined(_WINDOWS))
#if (defined(M_I86SM) || defined(M_I86MM) || defined(M_I86TM))
#if (defined(_MSC_VER) && (_MSC_VER >= 600)) /* includes Borland */
/* nothing */
#else /* MSC 5.10, etc */
EXTERN SW16 _fstrlen(LPSB8);
EXTERN LPSB8 _fstrcpy(LPSB8, LPSB8);
EXTERN LPSB8 _fstrncpy(LPSB8, LPSB8, SW16);
EXTERN SW16 _fstrncmp(LPSB8, LPSB8, SW16);
EXTERN SW16 _fstrcmp(LPSB8, LPSB8);
EXTERN LPSB8 _fmemcpy(LPSB8, LPSB8, SW16);
EXTERN LPSB8 _fstrcat(LPSB8, LPSB8);
EXTERN LPSB8 _fstrstr(LPSB8, LPSB8);
EXTERN SW16 _fmemcmp(LPSB8, LPSB8, UW16);
EXTERN LPSB8 _fmemset(LPSB8, SB8, INTG);
#endif
EXTERN SW16 MMread(SW16, LPSB8, SW16);
EXTERN SW16 MMwrite(SW16, LPSB8, SW16);
#endif
#endif /* USING_16_BIT_DOS && !defined(_WINDOWS) */
/* Added ulongmemset() to handle sizes > 64K on system
with 16 bit ints. - Mar 16, 2000 */
#if defined( _OSK )
#ifdef MEMSET
#undef MEMSET
#endif
#define MEMSET _ulongmemset
#endif /* _OSK */
#ifdef _WINDOWS
EXTERN SW16 far pascal lstrlen( LPSB8 );
EXTERN LPSB8 far pascal lstrcpy( LPSB8, LPSB8);
EXTERN LPSB8 far pascal lstrcat( LPSB8, LPSB8);
EXTERN INTG far pascal lstrcmp(LPSB8, LPSB8); /* add 3/4/92 rs */
INTG far pascal _lopen( SB8 far *, INTG );
SL32 far pascal _llseek( INTG, SL32, INTG );
SW16 far pascal _lread( INTG, SB8 far *, INTG );
INTG far pascal _lclose( INTG );
SW16 far pascal _lwrite( INTG, SB8 far *, INTG );
INTG far cdecl wsprintf(SB8 far *, SB8 far *,...);
#endif /* _WINDOWS */
#if defined(_OS9000) && DISK_FONTS
/* just for compilation purposes...*/
#define O_RDONLY 0x0001
#endif
#if defined(AGFA_FS) && DISK_FONTS
#define O_RDONLY (1 << 0)
EXTERN INTG open(FILECHAR *, INTG);
EXTERN INTG close(INTG);
EXTERN SL32 lseek(INTG, SL32, INTG);
EXTERN INTG read(INTG, VOID *, UINTG);
#else
#define open(path, access) (-1)
#define close(handle) (-1)
#define lseek(handle, offset, fromwhere) (-1)
#define read(handle, buf, len) (-1)
#endif
#endif /* __MIXMODEL__ */
mmdebug.h 、、、、、、、、、、、、、、、、、、、、、、、、、
/*
* Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved.
*/
#ifndef __MMDEBUG__
#define __MMDEBUG__
#ifdef MMDECODE_DEBUG
GLOBAL_EXTERN FILE *OUFILE;
#define GENERATE_STATEMENTS(statements) statements
#else
#define GENERATE_STATEMENTS(statements) ;
#endif
#define MMDBG(user_text) \
GENERATE_STATEMENTS(if (mmdecode_trace_sw) fprintf(OUFILE, user_text))
#define MMDBG1(user_text,a1) \
GENERATE_STATEMENTS(if (mmdecode_trace_sw) fprintf(OUFILE, user_text,a1))
#define MMDBG2(user_text,a1,a2) \
GENERATE_STATEMENTS(if (mmdecode_trace_sw) fprintf(OUFILE, user_text,a1,a2))
#define MMDBG3(user_text,a1,a2,a3) \
GENERATE_STATEMENTS(if (mmdecode_trace_sw) fprintf(OUFILE, user_text,a1,a2,a3))
#define MMDBG4(user_text,a1,a2,a3,a4) \
GENERATE_STATEMENTS(if (mmdecode_trace_sw) fprintf(OUFILE, user_text,a1,a2,a3,a4))
#define MMDBG5(user_text,a1,a2,a3,a4,a5) \
GENERATE_STATEMENTS(if (mmdecode_trace_sw) fprintf(OUFILE, user_text,a1,a2,a3,a4,a5))
#define MMDBG6(user_text,a1,a2,a3,a4,a5,a6) \
GENERATE_STATEMENTS(if (mmdecode_trace_sw) fprintf(OUFILE, user_text,a1,a2,a3,a4,a5,a6))
#define MMDBG8(user_text,a1,a2,a3,a4,a5,a6,a7,a8) \
GENERATE_STATEMENTS(if (mmdecode_trace_sw) fprintf(OUFILE, user_text,a1,a2,a3,a4,a5,a6,a7,a8))
#if defined(MMDECODE_DEBUG) || ( ( FCO_STANDALONE == 1 ) && defined(MERGER_ON) )
UB8 *
printIntellNodes( MODELTYPE *LBmodel, UB8 *local, SL32 *Ysyntell, SL32 *Xsyntell );
#endif
#endif /* __MMDEBUG__ */
modes.h 、、、、、、、、、、、、、、、、、、、、、、、、、、
空文件
nzwind.c 、、、、、、、、、、、、、、、、、、、、、、、
/* Copyright (C) 2004 Agfa Monotype Corporation. All rights reserved. */
/* $Header: I:/BULL/URIP/RTS/BMP/NZWIND.C_V 1.38 Sep 09 2004 17:02:42 galejss $ */
/* $Log: I:/BULL/URIP/RTS/BMP/NZWIND.C_V $
*
* Rev 1.38 Sep 09 2004 17:02:42 galejss
* allocate temporary areas for FIX_CONTOURS and WINDCOMP from 3rd memory pool
*
* Rev 1.37 Jun 04 2004 15:33:18 GalejsS
* 16-bit-fix in nz_open_run(); undo experimental TT_SCREENRES code
*
* Rev 1.36 Oct 17 2003 16:29:08 Galejs
* reentrant fixes for NZ_WIND option
*
* Rev 1.35 Sep 25 2003 13:40:08 Joe
* Replaced "memset" with "MEMSET".
* Replaced "memcpy" with "MEMCPY".
*
* Rev 1.34 Aug 21 2003 16:47:48 Galejs
* update copyright notice
*
* Rev 1.33 Jul 21 2003 17:16:00 Galejs
* reentrancy / debugs fixes
*
* Rev 1.32 Jun 23 2003 14:41:00 Galejs
* debug cleanup; VOID
*
* Rev 1.31 Sep 25 2002 14:39:40 Galejs
* FIX_CONTOURS changes (bug # 73) (for awr)
*
* Rev 1.30 Sep 23 2002 15:26:56 Galejs
* fix possibly-uninitialized-vbl warnings (part of bug # 76)
*
* Rev 1.29 Aug 15 2002 10:51:06 Joe
* In nz_set_trans(), for !NATORDER case, change last
* "chunkcount" test from default case to (chunkcount > 0)
* to resolve stroke font stray lines bug.
*
* Rev 1.28 25 Jul 2001 16:37:08 JOE
* In nz_set_trans(), resolved stray run bug (by swp).
*
* Rev 1.27 Jul 06 2001 15:21:32 Al
* Added larger chunk sizes to fast fill
*
* Rev 1.26 Jun 14 2001 16:27:44 Al
* Added fast fill
*
* Rev 1.25 Jun 11 2001 20:00:06 Galejs
* use UFST types rather than SHORT, CHAR, etc
*
* Rev 1.24 May 09 2001 19:50:12 Galejs
* data-type cleanup
*
* Rev 1.23 Apr 23 2001 15:58:28 Al
* Fixed bug in contour checking code
*
* Rev 1.22 Apr 19 2001 16:05:48 Al
* Added logic to detect badly wound contours
*
* Rev 1.21 Nov 09 2000 18:48:44 Galejs
* fix reentrant build for WINDCOMP with CHARalloc()
*
* Rev 1.20 17 Mar 2000 11:51:36 JOE
* Fixed comment (by ks).
*
* Rev 1.19 15 Feb 2000 10:21:54 AL
* Hooked CHARalloc() into WINDCOMP's nzwinding code
*
* Rev 1.18 Feb 03 2000 16:08:22 galejs
* remove use of "long" type
*
* Rev 1.17 03 Feb 2000 15:34:38 AL
* Changed SWP799 to WINDCOMP
*
* Rev 1.16 04 Oct 1999 08:35:02 JOE
* Conditionally compiled two functions based on GRAYSCALING (by swp).
*
* Rev 1.15 17 Sep 1999 08:44:42 JOE
* Replaced all nzwinding code, enabled with SWP799 (by swp).
*
* Rev 1.14 23 Aug 1999 15:39:14 JOE
* Removed 'size_t' cast - fixes truncation of int from 32 bit to 16 bit (ks).
*
* Rev 1.13 Aug 10 1999 15:12:08 galejs
* include-file changes
*
* Rev 1.12 Jun 29 1999 14:28:56 galejs
* add missing-pixel recovery code (experimental)
*
* Rev 1.11 21 Jan 1999 14:03:18 GALEJS
* fix compiler warning (add CGBITMAP || GRAYSCALING condition)
*
* Rev 1.10 15 Jun 1998 17:02:08 GALEJS
* reentrancy parm-passing changes
*
* Rev 1.9 02 Apr 1998 18:49:38 GALEJS
* move externs to if_state
*
* Rev 1.8 24 Mar 1998 14:52:02 GALEJS
* include-file changes
*
* Rev 1.7 22 Jan 1998 17:57:38 GALEJS
* fix for GAGP/GAHP grayscale alignment modes
*
* Rev 1.6 09 Dec 1997 15:10:54 GALEJS
* change special-case test from obsolete GASUB to GAPP
*
* Rev 1.5 24 Jul 1997 16:19:16 JOE
* Removed two unreferenced local variables (by Jimmy).
*
* Rev 1.4 15 Jul 1997 15:06:24 GALEJS
* fix bug in nz_set_trans() when CGBITMAP=off
*
* Rev 1.3 15 Jul 1997 12:34:58 AL
* removed debug dump
*
* Rev 1.2 15 Jul 1997 12:25:30 AL
* Better error handling if too many tran runs
*
* Rev 1.1 23 Jun 1997 16:05:32 MIKE
* Fixed 16-bit code warnings w/ (size_t) casts
*
* Rev 1.0 16 Jun 1997 15:19:50 AL
* Initial revision.
* This code broken off from raster.c to enable grayscaling with cgbitmap off.
*
*/
/* $Date: Sep 09 2004 17:02:42 $ */
/* Change History
*
* 16-Jun-97 awr This code broken off from raster.c to enable grayscaling
* with cgbitmap off.
* 23-Jun-97 mby Fixed 16-bit code warning with (size_t) casts.
* 15-Jul-97 awr Better error handling if tran_run_ct is overflowed
* 15-Jul-97 slg Outlines-have-crossed case in nz_set_trans() wasn't quite
* right when CGBITMAP=off (if-then-else mismatch)
* 09-Dec-97 slg Change test of obsolete alignment mode (GASUB => GAPP)
* 22-Jan-98 slg Extend above test to GAGP & GAHP modes
* 29-Jun-99 slg Put Steven's missing-pixel-recovery code into nz_set_trans():
* experimental, so only enabled if TT_SCREENRES set in cgconfig.h
* 23-Aug-99 ks Removed (size_t) cast - Fix truncation of int from 32 bit to 16 bit
* Jul-99 swp replaced all nzwinding code, enabled with existance of SWP799
* 03-Feb-00 awr Changed SWP799 to WINDCOMP
* 15-Feb-00 awr Hooked CHARalloc() into WINDCOMP nzwinding code
* 19-Apr-01 awr Added check for badly wound contours in nz_set_trans()
* 23-Apr-01 awr Fixed bug in above.
* 12-Sep-02 awr FIX_CONTOUR changes for CHAR_SIZE
*/
#include "cgconfig.h"
#if NON_Z_WIND && (CGBITMAP || GRAYSCALING) /* conditionally-compile entire file */
#ifdef VXWORKS
#include "vxWorks.h"
#endif
#include <stdio.h>
#include <string.h>
#include "ufstport.h"
#include "dbg_ufst.h"
#include "shareinc.h"
#include "mixmodel.h"
#ifdef WINDCOMP
/****************************************************************/
/****************************************************************/
/****************************************************************/
/* forward declaration */
VOID dump_trans(FILECHAR *, NZTRANS *);
/****************************************************************/
/* allocate a NZTRANS object with <num+1> slots */
NZTRANS *new_trans(FSP SW16 num)
{
MEM_HANDLE htrans;
NZTRANS *trans;
SL32 i,n;
n = sizeof(NZTRANS);
htrans = TEMPCHARalloc(FSA n);
if (0 == htrans)
return 0;
trans = (NZTRANS*)MEMptr(htrans);
MEMSET(trans,0,n);
trans->htrans = htrans;
/* there are <num+1> slots: <0...num> -- only use <1..num> (I think) */
trans->num = ++num;
n = (SL32)num * sizeof(SL32);
trans->hindices = TEMPCHARalloc(FSA n);
if (0 == trans->hindices)
{
delete_trans(FSA trans);
return 0;
}
trans->indices = (SL32*)MEMptr(trans->hindices);
/* all slots initially unused */
for (i=0; i<num; i++)
trans->indices[i] = -1;
/* start with 4 nodes per slot */
n = (SL32)num << 2;
trans->stop_index = n;
trans->next_index = 0;
trans->hnodes = TEMPCHARalloc(FSA n* sizeof(NZNODE));
if (trans->hnodes == 0)
{
delete_trans(FSA trans);
return 0;
}
trans->nodes = (NZNODE*)MEMptr(trans->hnodes);
return trans;
}
/****************************************************************/
/* add a transition coordinate x to the y-th row */
/* nznodes are maintained in increasing order within a row */
UW16 add_trans(FSP NZTRANS *trans, FS_FIXED x, SW16 y)
{
SL32 index,next;
NZNODE *nodes = trans->nodes;
/* starting index is */
if (y<0 || y>=trans->num)
{
/* printf("add_trans: y=%d trans->num=%d\n",y,trans->num); */
/*** might be more usefull to simply IGNORE this error ***/
return SUCCESS;
/*** return ERR_nz_bad_slot; ***/
}
index = trans->indices[y];
/* out of NZNODES? ... get more */
if (trans->next_index == trans->stop_index)
{
MEM_HANDLE h;
trans->stop_index += trans->num;
h = TEMPCHARalloc(FSA sizeof(NZNODE)*trans->stop_index);
if (0 == h)
{
/***/ /* printf("add_trans: reallocation failed\n"); */
return ERR_nz_realloc;
}
nodes = (NZNODE*)MEMptr(h);
MEMCPY(nodes, trans->nodes, trans->next_index* sizeof(NZNODE));
TEMPCHARfree(FSA trans->hnodes);
trans->hnodes = h;
trans->nodes = nodes;
}
/* add the element to the list */
if (index<0 || nodes[index].x > x)
{
/* prepend new node to list, store new head */
nodes[trans->next_index].x = x;
nodes[trans->next_index].next = index;
trans->indices[y] = trans->next_index++;
}
else
{
/* move to the proper <index> */
while ((next=nodes[index].next) >= 0 && nodes[next].x <= x)
index = next;
/* insert new node after <index> */
nodes[index].next = trans->next_index;
nodes[trans->next_index].x = x;
nodes[trans->next_index].next = next;
trans->next_index++;
}
return SUCCESS;
}
/****************************************************************/
VOID delete_trans(FSP NZTRANS *trans)
{
if (trans)
{
TEMPCHARfree(FSA trans->hindices);
TEMPCHARfree(FSA trans->hnodes);
TEMPCHARfree(FSA trans->htrans);
trans = 0;
}
}
/****************************************************************/
/* print the TRANS in ASCII */
#if 0
VOID dump_trans(FILECHAR *s, NZTRANS *trans)
{
SL32 i,index,x;
printf("dump_trans: %s\n",s);
printf("next_index=%d stop_index=%d num=%d\n",trans->next_index, trans->stop_index, trans->num);
for (i=0; i<trans->num; i++)
{
printf("%d:",i);
index = trans->indices[i];
while (index >= 0)
{
x = trans->nodes[index].x;
printf("%c%f ",(x & 1)?'U':'D',(x >> 1) / 65536.0);
index = trans->nodes[index].next;
}
printf("\n");
}
fflush(stdout);
}
#endif
/****************************************************************/
#if GRAYSCALING
/* grab a row of transitions, send off to the GRAY machinery */
static VOID grab_trans_i(FSP SW16 i)
{
NZTRANS *trans = if_state.ras.trans;
NZNODE *nodes = trans->nodes;
SL32 *indices = trans->indices;
SL32 winding = 0;
SL32 index;
FS_FIXED t,x0,x1;
SW16 on,off,num,*p;
index = indices[i];
num = 0;
p = (SW16 *) &if_state.grayfilter.transition;
while (index >= 0)
{
x0 = x1 = 0x7FFFFFFF;
if (if_state.non_z_wind)
{
/* get the nzw pair */
while (winding==0 && index>=0)
{
t = nodes[index].x;
index = nodes[index].next;
x0 = t >> 1;
winding += (t & 1) ? 1 : -1;
}
while (winding!=0 && index>=0)
{
t = nodes[index].x;
index = nodes[index].next;
x1 = t >> 1;
winding += (t & 1) ? 1 : -1;
}
}
else
{
/* get the parity pair */
x0 = nodes[index].x >> 1;
index = nodes[index].next;
if (index >= 0)
{
x1 = nodes[index].x >> 1;
index = nodes[index].next;
}
}
/* add a matched pair of integer subpixels */
if (x0 != 0x7FFFFFFF && x1 != 0x7FFFFFFF)
{
/* round to nearest int */
on = (x0 + 0x00008000) >> 16;
off = (x1 + 0x00008000) >> 16;
/* crude dropout protection */
if (on==off)
{
if (on>0)
on--;
else
off++;
}
*p++ = on;
*p++ = off;
num+=2;
}
}
/* hand them off to GRAY machinery */
if_state.grayfilter.numtrans = num;
gs_endsubrast(FSA &if_state.grayfilter);
}
/****************************************************************/
/* package transitions for GRAY machinery */
VOID grab_trans(FSP0)
{
SW16 row,a = if_state.grayfilter.alignment;
NZTRANS *trans = if_state.ras.trans;
/*** again ... don't seem to use row 0 ??? ***/
if (a==GAPP || a==GAGP || a==GAHP)
row = 1;
else
row = 1+if_state.grayfilter.startoffset.y;
for (/**/; row < trans->num; row++)
grab_trans_i(FSA row);
/* we're done with this now */
delete_trans(FSA if_state.ras.trans);
}
#endif /* GRAYSCALING */
/****************************************************************/
/****************************************************************/
/****************************************************************/
#else /* ! WINDCOMP */
/*==================================================================*/
/* Non zero winding */
#if CGBITMAP
#define nz_raster_bot_row() if_state.ras.toff = if_state.ras.tsize - (SL32)if_state.ras.bmdim.x;
/* bottom row in bitmap */
#define nz_raster_next_row() if_state.ras.toff -= if_state.ras.bmdim.x;
#endif
#ifdef LINT_ARGS
#if NZ_DUMP
MLOCAL VOID nz_dump_list(FSP PNZ_NODE);
#endif
MLOCAL UW16 analyzeContours( FSP PNZ_INSTANCE nz );
MLOCAL VOID nz_insert_pending( FSP PNZ_NODE, PNZ_NODE);
MLOCAL VOID nz_insert_active(FSP PNZ_NODE, PNZ_NODE);
MLOCAL VOID nz_sort(FSP PNZ_NODE);
#else
#if NZ_DUMP
MLOCAL VOID nz_dump_list();
#endif
MLOCAL UW16 analyzeContours( );
MLOCAL VOID nz_insert_pending( );
MLOCAL VOID nz_insert_active();
MLOCAL VOID nz_sort();
#endif
#if GRAYSCALING
#define writetran(xx) if(if_state.grayfilter.numtrans >= MAXTRANS) \
if_state.grayfilter.error = TRUE; \
else \
if_state.grayfilter.transition[if_state.grayfilter.numtrans++] = xx;
#endif /* GRAYSCALING */
#if NZ_DUMP
#if defined (ANSI_DEFS)
MLOCAL VOID nz_dump_list( FSP PNZ_NODE list )
#else
MLOCAL VOID nz_dump_list( list )
PNZ_NODE list;
#endif
{
PNZ_NODE p;
PNZCOUNTER pv;
NZCOUNTER i,j;
DBG("nz_dump_list()\n");
for(j=0; j<if_state.ras.nz_instance.cur_node; j++)
{
p = &if_state.ras.nz_instance.nodes[j];
DBG1("%d -------next NZ_NODE--------\n", j);
DBG1("Node address: %lx\n", p);
#if FIX_CONTOURS
DBG1("Contour %d\n", p->contourNum);
#endif
DBG1("lowRow %d\n", p->lowRow);
DBG1("onoff %d\n", p->onoff);
DBG1("valCount %d\n", p->valCount);
pv = p->pval;
DBG1("value list address: %lx\n", pv);
for(i=0; i<p->valCount; i++)
{
DBG1(" %d\n", *pv++);
}
p = p->link;
}
}
#endif
/*-------------------*/
/* nz_init */
/*-------------------*/
#if defined (ANSI_DEFS)
GLOBAL VOID nz_init( FSP PNZ_INSTANCE nz, LPUB8 nzw_buf,
NZCOUNTER tran_run_ct, SW16 blackdepth)
#else
GLOBAL VOID nz_init( nz, nzw_buf, tran_run_ct, blackdepth )
PNZ_INSTANCE nz;
LPUB8 nzw_buf;
NZCOUNTER tran_run_ct;
SW16 blackdepth;
#endif
{
DBG("nz_init()\n");
nz->nodes = (PNZ_NODE)nzw_buf;
nz->transition = (PNZCOUNTER)(&nz->nodes[tran_run_ct]); /* transition row buffer */
nz->pvalues = &nz->transition[tran_run_ct];
nz->tran_run_ct = tran_run_ct;
nz->blackdepth = blackdepth;
nz->cur_node = 0;
nz->pend_list.link = NULL;
nz->overflow = 0;
nz->done = 0;
#if FIX_CONTOURS
nz->contourNum = 0; /* For contour winding check to know what contour this run belongs to. */
#endif
}
/*-------------------*/
/* nz_insert_pending */
/*-------------------*/
#if defined (ANSI_DEFS)
MLOCAL VOID nz_insert_pending ( FSP PNZ_NODE list, PNZ_NODE p )
#else
MLOCAL VOID nz_insert_pending( list, p )
PNZ_NODE list;
PNZ_NODE p;
#endif
{
PNZ_NODE pprev, pnext;
NZCOUNTER lowRow;
DBG("nz_insert_pending()\n");
lowRow = p->lowRow;
pprev = list;
pnext = pprev->link;
while(pnext)
{
if(lowRow <= pnext->lowRow) break;
pprev = pnext;
pnext = pprev->link;
}
p->link = pnext; /* link p after pprev */
pprev->link = p;
}
/*-------------------*/
/* nz_open_run */
/*-------------------*/
#if defined (ANSI_DEFS)
GLOBAL VOID nz_open_run( PNZ_INSTANCE nz, NZCOUNTER start_row , SL32 ydir )
#else
GLOBAL VOID nz_open_run ( nz, start_row, ydir )
PNZ_INSTANCE nz;
NZCOUNTER start_row;
SL32 ydir;
#endif
{
nz->start_row = start_row;
if ( nz->cur_node >= nz->tran_run_ct )
{
/* Arm for potential error. We've already produced as many tran runs
as we allocated. We can still fool around a bit with non
transition producing curve elements... but if we do produce
transitions (detecteed at nz_close_run()) then we throw the error
*/
nz->done = 1; /* any more transitions set will flag error */
/* overwrite last node if we overflow */
nz->cur_node = nz->tran_run_ct - 1;
}
nz->valCount = 0;
nz->pval = nz->pvalues + (UL32)((UL32)nz->cur_node * (UL32)nz->blackdepth);
if ( ydir == -1 ) /* going down; point at end of array */
nz->pval += nz->blackdepth - 1;
}
/*-------------------*/
/* nz_close_run */
/*-------------------*/
/* Scan conversion has changed y direction.
*
* Close out current run of transitions (if any) by creating an NZ_NODE
* to hold the just written transitions and link this new NZ_NODE into
* the list of pending transition lists.
*/
#if defined (ANSI_DEFS)
GLOBAL VOID nz_close_run ( FSP PNZ_INSTANCE nz, SL32 newydir, BOOLEAN beam )
#else
GLOBAL VOID nz_close_run ( nz, newydir, beam )
PNZ_INSTANCE nz;
SL32 newydir;
BOOLEAN beam;
#endif
{
PNZ_NODE pnew;
DBG("nz_close_run()\n");
if ( !nz->valCount ) /* haven't written any transitions yet */
{
DBG(" no transitions written- no node created\n");
/* We changed direction without writing any transitions. */
nz->start_row += newydir;
nz->pval -= newydir * (nz->blackdepth - 1); /* pt to other end */
return;
}
/* else we have produced transitions. */
/* Close off current NZ_NODE */
pnew = &nz->nodes[nz->cur_node];
pnew->valCount = nz->valCount;
if(beam) pnew->onoff = -1; /* we were making OFF trans */
else pnew->onoff = 1; /* we were making ON trans */
if ( newydir == 1 ) /* already changed- we were going down */
{
nz->start_row -= nz->valCount - 1;
pnew->lowRow = nz->start_row;
pnew->pval = nz->pval + 1;
}
else /* We were going up */
{
pnew->lowRow = nz->start_row;
nz->start_row += nz->valCount - 1;
pnew->pval = nz->pval - nz->valCount;
}
DBG4("Node %d onoff = %d lowRow = %d valCount = %d\n",
nz->cur_node, pnew->onoff, pnew->lowRow, pnew->valCount);
#if FIX_CONTOURS
pnew->contourNum = nz->contourNum;
pnew->right = pnew->wrong = 0;
#endif
/* Link new node into the list; list is sorted by nz_start_row */
if ( nz->done )
{
nz->overflow = 1; /* we made an extra transition run */
DBG(" overflow is set\n");
}
else
nz_insert_pending ( FSA &nz->pend_list, pnew );
nz->cur_node++; /* set up for next node */
nz_open_run ( nz, nz->start_row , newydir );
}
/*-------------------*/
/* nz_insert_active */
/*-------------------*/
/* Insert node p into list maintining sort from low to high
* of *pval
*/
#if defined (ANSI_DEFS)
MLOCAL VOID nz_insert_active ( FSP PNZ_NODE list, PNZ_NODE p )
#else
MLOCAL VOID nz_insert_active ( list, p )
PNZ_NODE list;
PNZ_NODE p;
#endif
{
PNZ_NODE pprev, pnext;
NZCOUNTER val;
DBG("nz_insert_active()\n");
val = *(p->pval);
pprev = list;
pnext = pprev->link;
while(pnext)
{
if(val <= *(pnext->pval)) break;
pprev = pnext;
pnext = pprev->link;
}
p->link = pnext; /* link p after pprev */
pprev->link = p;
}
/*-------------------*/
/* nz_sort */
/*-------------------*/
/* Sort list on *pval fields low to high */
#if defined (ANSI_DEFS)
MLOCAL VOID nz_sort( FSP PNZ_NODE activelist )
#else
MLOCAL VOID nz_sort( activelist )
PNZ_NODE activelist;
#endif
{
PNZ_NODE pcur, pnext;
DBG("nz_sort()\n");
pcur = activelist->link;
activelist->link = NULL;
while(pcur)
{
pnext = pcur->link;
nz_insert_active ( FSA activelist, pcur );
pcur = pnext;
}
}
#if CGBITMAP
#if NATORDER
#if LEFT_TO_RIGHT_BIT_ORDER
CONST UB8 Lbits[8] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01};
CONST UB8 Rbits[8] = {0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF};
#else
CONST UB8 Lbits[8] = {0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80};
CONST UB8 Rbits[8] = {0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
#endif
#else /* not NATORDER, we need to process the chunks */
#if RASTER_ORG == SIXTEEN_BIT_CHUNK
#if LEFT_TO_RIGHT_BIT_ORDER
CONST UW16 Lbits[16] = {0xFFFF, 0x7FFF, 0x3FFF, 0x1FFF, 0x0FFF, 0x07FF, 0x03FF, 0x01FF,
0x00FF, 0x007F, 0x003F, 0x001F, 0x000F, 0x0007, 0x0003, 0x0001};
CONST UW16 Rbits[16] = {0x8000, 0xC000, 0xE000, 0xF000, 0xF800, 0xFC00, 0xFE00, 0xFF00,
0xFF80, 0xFFC0, 0xFFE0, 0xFFF0, 0xFFF8, 0xFFFC, 0xFFFE, 0xFFFF};
#else
CONST UW16 Lbits[16] = {0xFFFF, 0xFFFE, 0xFFFC, 0xFFF8, 0xFFF0, 0xFFE0, 0xFFC0, 0xFF80,
0xFF00, 0xFE00, 0xFC00, 0xF800, 0xF000, 0xE000, 0xC000, 0x8000};
CONST UW16 Rbits[16] = {0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF,
0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF};
#endif
#endif
#if RASTER_ORG == THIRTYTWO_BIT_CHUNK
#if LEFT_TO_RIGHT_BIT_ORDER
CONST UL32 Lbits[32] = {0xFFFFFFFF, 0x7FFFFFFF, 0x3FFFFFFF, 0x1FFFFFFF,
0x0FFFFFFF, 0x07FFFFFF, 0x03FFFFFF, 0x01FFFFFF,
0x00FFFFFF, 0x007FFFFF, 0x003FFFFF, 0x001FFFFF,
0x000FFFFF, 0x0007FFFF, 0x0003FFFF, 0x0001FFFF,
0x0000FFFF, 0x00007FFF, 0x00003FFF, 0x00001FFF,
0x00000FFF, 0x000007FF, 0x000003FF, 0x000001FF,
0x000000FF, 0x0000007F, 0x0000003F, 0x0000001F,
0x0000000F, 0x00000007, 0x00000003, 0x00000001};
CONST UL32 Rbits[32] = {0x80000000, 0xC0000000, 0xE0000000, 0xF0000000,
0xF8000000, 0xFC000000, 0xFE000000, 0xFF000000,
0xFF800000, 0xFFC00000, 0xFFE00000, 0xFFF00000,
0xFFF80000, 0xFFFC0000, 0xFFFE0000, 0xFFFF0000,
0xFFFF8000, 0xFFFFC000, 0xFFFFE000, 0xFFFFF000,
0xFFFFF800, 0xFFFFFC00, 0xFFFFFE00, 0xFFFFFF00,
0xFFFFFF80, 0xFFFFFFC0, 0xFFFFFFE0, 0xFFFFFFF0,
0xFFFFFFF8, 0xFFFFFFFC, 0xFFFFFFFE, 0xFFFFFFFF};
#else
CONST UL32 Lbits[32] = {0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFC, 0xFFFFFFF8,
0xFFFFFFF0, 0xFFFFFFE0, 0xFFFFFFC0, 0xFFFFFF80,
0xFFFFFF00, 0xFFFFFE00, 0xFFFFFC00, 0xFFFFF800,
0xFFFFF000, 0xFFFFE000, 0xFFFFC000, 0xFFFF8000,
0xFFFF0000, 0xFFFE0000, 0xFFFC0000, 0xFFF80000,
0xFFF00000, 0xFFE00000, 0xFFC00000, 0xFF800000,
0xFF000000, 0xFE000000, 0xFC000000, 0xF8000000,
0xF0000000, 0xE0000000, 0xC0000000, 0x80000000};
CONST UW16 Rbits[32] = {0x00000001, 0x00000003, 0x00000007, 0x0000000F,
0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF};
#endif
#endif
#endif /* not NATORDER */
#endif /* CGBITMAP */
/*-------------------*/
/* nz_set_trans */
/*-------------------*/
/* Set simple, even-odd transitions in the transition array according
* to the transition list.
*/
#if defined (ANSI_DEFS)
GLOBAL UW16 nz_set_trans( FSP PNZ_INSTANCE nz )
#else
GLOBAL UW16 nz_set_trans( nz )
PNZ_INSTANCE nz;
#endif
{
PNZ_NODE pprev, pnext;
NZCOUNTER row=0, hirow=0, pendRow, onCount, val, prevVal, beamIsOn;
SW16 isgray;
#if CGBITMAP
INTG tranct=0;
#endif
DBG("nz_set_trans()\n");
#if NZ_DUMP
nz_dump_list(FSA &nz->pend_list);
#endif
#if FIX_CONTOURS
if(if_state.ras.nz_instance.checkingContours)
return checkContours(FSA nz);
#endif
if(nz->overflow) return ERRnzw_mem_overflow;
isgray = FC_ISGRAY(&if_state.cur_loc_fc);
/* Set starting row and hi row --------------------------------*/
#if GRAYSCALING
if(isgray)
{
if_state.grayfilter.numtrans = 0;
/* following test is OBSOLETE - needs to be updated for new alignment modes */
/* if(if_state.grayfilter.alignment == GASUB) */
/* the following three cases are NECESSARY (otherwise, lots of extraneous
lines/gaps in glyphs with those alignment modes) - however, there still might
be other cases that need special treatment... (Sandra, 22 Jan 98) */
if((if_state.grayfilter.alignment == GAPP) ||
(if_state.grayfilter.alignment == GAGP) ||
(if_state.grayfilter.alignment == GAHP))
row = 0;
else
row = if_state.grayfilter.startoffset.y;
hirow = row + nz->blackdepth;
}
#endif
#if CGBITMAP
if(!isgray)
{
nz_raster_bot_row(); /* bottom row in bitmap */
row = 0;
hirow = nz->blackdepth;
tranct = 0; /* for fast fill */
}
#endif
nz->active_list.link = NULL;
pnext = nz->pend_list.link;
if(!pnext) return SUCCESS; /* no transitions produced */
pendRow = pnext->lowRow;
for( ; row < hirow ; row++)
{
DBG1 ("\nrow: %d\n", row);
/* Add any pending nodes ------------------------------------*/
if(pendRow <= row)
{
pprev = &nz->pend_list;
pnext = nz->pend_list.link;
while(pnext)
{
pendRow = pnext->lowRow;
if(pendRow <= row)
{
pprev->link = pnext->link; /* remove from pending list */
nz_insert_active ( FSA &nz->active_list, pnext);
pnext = pprev->link;
}
else
break;
}
if(!pnext) pendRow = 32767;
}
/* Set transitions -----------------------------------------*/
settrans:
beamIsOn = 0;
pnext = nz->active_list.link;
if(pnext)
{
prevVal = *(pnext->pval);
onCount = pnext->onoff;
pnext = pnext->link;
while(pnext)
{
val = *(pnext->pval);
if(val < prevVal)
{
/* Outlines have crossed, re-sort, and clear bitmap row */
nz_sort( FSA &nz->active_list );
#if GRAYSCALING
if(isgray)
{
if_state.grayfilter.numtrans = 0;
}
#endif
#if CGBITMAP
if(!isgray)
{
MEMSET(if_state.ras.tran_buffer+if_state.ras.toff, (INTG)0, (INTG)if_state.ras.bmdim.x);
tranct = 0; /* for fast fill */
}
#endif
goto settrans; /* try again */
}
/**** #if TT_SCREENRES ***/
/*** not a good idea after all - delete before 4.7 release ***/
/*** swp - missing-pixel recovery (experimental) ***/
/*** part 2 of change is in graymap.c ***/
/*** else if(val >= prevVal) ***/
/*** #else ***/
else if(val > prevVal)
/*** #endif ***/
{
if((beamIsOn && onCount == 0) || (!beamIsOn && onCount != 0))
{
#if GRAYSCALING /* 10-27-95, mby */
if(isgray)
{
writetran ( prevVal );
}
#endif
#if CGBITMAP
if(!isgray)
nz->transition[tranct++] = prevVal;
#endif
beamIsOn = 1 - beamIsOn;
}
prevVal = val;
}
onCount += pnext->onoff;
pnext = pnext->link;
} /* for each NZ_NODE in the active list */
if((beamIsOn && onCount == 0) || (!beamIsOn && onCount != 0))
{
#if GRAYSCALING /* 10-27-95, mby */
if(isgray)
{
writetran ( prevVal );
}
#endif
#if CGBITMAP
if(!isgray)
nz->transition[tranct++] = prevVal;
#endif
}
} /* endif (pnext) */
#if GRAYSCALING
if(isgray)
{
UW16 status = gs_endsubrast(FSA &if_state.grayfilter);
if(status)
return status;
}
#endif
#if CGBITMAP
if(!isgray)
{
INTG i;
/* Write a row of pixels in the output bitmap */
if(tranct & 1) /* gotta have an even number of pixels */
return ERR_odd_transitions;
#if NATORDER
{
UB8 *rasStart, *p;
rasStart = if_state.ras.tran_buffer+if_state.ras.toff;
for(i=0; i<tranct;)
{
INTG c0, c1, byte0, ct;
c0 = nz->transition[i++]; /* first bit on */
c1 = nz->transition[i++] - 1; /* last bit on */
byte0 = c0 >> 3;
p = rasStart + byte0; /* point to 1st changed byte */
ct = (c1>>3) - byte0 + 1; /* number of bytes to change */
if(ct>2)
{
*p++ |= Lbits[c0 & 7];
MEMSET(p, 0xff, ct-2);
*(p+ct-2) |= Rbits[c1 & 7];
}
else if(ct>1)
{
*p++ |= Lbits[c0 & 7];
*p |= Rbits[c1 & 7];
}
else if (ct > 0)
*p |= Lbits[c0 & 7] & Rbits[c1 & 7];
}
}
#else
{
LPCHUNK rasStart, p;
rasStart = (LPCHUNK)(if_state.ras.tran_buffer+if_state.ras.toff);
for(i=0; i<tranct;)
{
INTG c0, c1, chunk0, chunkcount;
c0 = nz->transition[i++]; /* first bit on */
c1 = nz->transition[i++] - 1; /* last bit on */
chunk0 = c0 >> CHUNK_SHIFT;
p = rasStart + chunk0; /* point to 1st changed chunk */
chunkcount = (c1>>CHUNK_SHIFT) - chunk0 + 1; /* number of chunks to change */
if(chunkcount>2)
{
*p++ |= Lbits[c0 & CHUNK_MASK];
MEMSET((UB8*)p, 0xff, (chunkcount-2)<<(CHUNK_SHIFT-3));
*(p+chunkcount-2) |= Rbits[c1 & CHUNK_MASK];
}
else if(chunkcount>1)
{
*p++ |= Lbits[c0 & CHUNK_MASK];
*p |= Rbits[c1 & CHUNK_MASK];
}
else if (chunkcount > 0)
*p |= Lbits[c0 & CHUNK_MASK] & Rbits[c1 & CHUNK_MASK];
}
}
#endif
tranct = 0;
/* move to next raster line in transition buffer */
nz_raster_next_row();
}
#endif
/* Bump list to next row --------------------------------*/
pprev = &nz->active_list;
pnext = pprev->link;
while(pnext)
{
if(--(pnext->valCount)) /* if any transitions left */
{
pnext->pval++; /* bump to next transition value */
pprev = pnext;
}
else
pprev->link = pnext->link; /* remove from active list */
pnext = pprev->link;
}
} /* for(each raster row of the bitmap */
#if FIX_CONTOURS
if(if_state.ras.nz_instance.isWrong) /* not NULL means 2nd time, need to free */
{
TEMPCHARfree(FSA if_state.ras.nz_instance.hisWrong);
if_state.ras.nz_instance.isWrong = NULL;
if_state.ras.nz_instance.hisWrong = NIL_MH;
}
#endif
return SUCCESS;
}
#if FIX_CONTOURS
/*-------------------*/
/* analyzeContours */
/*-------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16 analyzeContours( FSP PNZ_INSTANCE nz )
#else
MLOCAL UW16 analyzeContours( nz )
PNZ_INSTANCE nz;
#endif
{
SL32 wrong, right;
PNZ_NODE node;
SW16 numContours, curCn, i;
DBG("\nanalyzeContours\n");
/* Allocate array of flags indicating if a contour is wound wrong. */
numContours = nz->contourNum + 1;
nz->hisWrong = TEMPCHARalloc(FSA numContours);
if(nz->hisWrong == NIL_MH)
return ERRmem;
nz->isWrong = (LPUB8)MEMptr(nz->hisWrong);
/* Go through all the nzw nodes and add up how many transitions were right and wrong
* Based on this "vote" set the isWrong flags. The reason we have to vote is that
* little loops caused by emboldening or hint processing can cause some of the
* contours in a transition run to be right and some to be wrong. The fact that these
* loops are little means that they will not contribute much to the vote.
*/
node = nz->nodes;
curCn = 0;
wrong = right = 0;
for(i=0; i<nz->cur_node; i++)
{
/* Note that all nzw runs from a single contour are consecutive in nz->nodes. */
if(node[i].contourNum !=curCn)
{
DBG3("contourNum %d right %ld wrong %ld\n", curCn, right, wrong);
nz->isWrong[curCn] = wrong>right?1:0;
curCn = node[i].contourNum;
wrong = right = 0;
}
wrong += node[i].wrong;
right += node[i].right;
}
nz->isWrong[curCn] = wrong>right?1:0;
return SUCCESS;
}
/*-------------------*/
/* checkContours */
/*-------------------*/
#if defined (ANSI_DEFS)
GLOBAL UW16 checkContours( FSP PNZ_INSTANCE nz )
#else
GLOBAL UW16 checkContours( nz )
PNZ_INSTANCE nz;
#endif
{
PNZ_NODE pprev, pnext;
NZCOUNTER row, hirow, pendRow, onCount, val, prevVal, beamIsOn;
UW16 status;
DBG("nz_set_trans()\n");
if(nz->overflow) return ERRnzw_mem_overflow;
/* Set starting row and hi row --------------------------------*/
#if CGBITMAP
nz_raster_bot_row(); /* bottom row in bitmap */
row = 0;
hirow = nz->blackdepth;
#endif
nz->active_list.link = NULL;
pnext = nz->pend_list.link;
if(!pnext) return SUCCESS; /* no transitions produced */
pendRow = pnext->lowRow;
for( ; row < hirow ; row++)
{
DBG1 ("\nrow: %d\n", row);
/* Add any pending nodes ------------------------------------*/
if(pendRow <= row)
{
pprev = &nz->pend_list;
pnext = nz->pend_list.link;
while(pnext)
{
pendRow = pnext->lowRow;
if(pendRow <= row)
{
pprev->link = pnext->link; /* remove from pending list */
nz_insert_active ( FSA &nz->active_list, pnext);
pnext = pprev->link;
}
else
break;
}
if(!pnext) pendRow = 32767;
}
/* Set transitions -----------------------------------------*/
settrans:
beamIsOn = 0;
pnext = nz->active_list.link;
if(pnext)
{
prevVal = *(pnext->pval);
onCount = pnext->onoff;
pprev = pnext;
pnext = pnext->link;
if(if_state.ras.nz_instance.checkingContours)
{
while(pnext)
{
val = *(pnext->pval);
if(val < prevVal)
{
/* Outlines have crossed, re-sort, and clear bitmap row */
nz_sort( FSA &nz->active_list );
goto settrans; /* try again */
}
else if(val > prevVal)
{
if(beamIsOn && onCount == 0)
{
/* Writing an off transition */
if(pprev->onoff == 1)
pprev->wrong++;
else
pprev->right++;
beamIsOn = 1 - beamIsOn;
}
if(!beamIsOn && onCount != 0)
{
/* Writing an on transition */
if(pprev->onoff == 1)
pprev->right++;
else
pprev->wrong++;
beamIsOn = 1 - beamIsOn;
}
prevVal = val;
}
onCount += pnext->onoff;
pprev = pnext;
pnext = pnext->link;
} /* for each NZ_NODE in the active list */
if(beamIsOn && onCount == 0)
{
if(pprev->onoff == 1)
pprev->wrong++;
else
pprev->right++;
}
if(!beamIsOn && onCount !=0)
{
if(pprev->onoff == 1)
pprev->right++;
else
pprev->wrong++;
}
}
} /* endif (pnext) */
/* Bump list to next row --------------------------------*/
pprev = &nz->active_list;
pnext = pprev->link;
while(pnext)
{
if(--(pnext->valCount)) /* if any transitions left */
{
pnext->pval++; /* bump to next transition value */
pprev = pnext;
}
else
pprev->link = pnext->link; /* remove from active list */
pnext = pprev->link;
}
} /* for(each raster row of the bitmap */
status = analyzeContours(FSA nz);
if(status)
return status;
else
return ERR_nz_contours_wrong;
}
#endif /* FIX_CONTOURS */
#endif /* WINDCOMP */
#endif /* NON_Z_WIND && (CGBITMAP || GRAYSCALING) */
outdata.txt 、、、、、、、、、、、、、、、、、、、、、、、、、、
/*
* Copyright (C) 2005 Monotype Imaging Inc. All rights reserved.
*/
/* $Header: I:/BULL/URIP/RTS/OUT/OUTDATA.C_V 1.46 Dec 15 2004 12:22:42 galejss $ */
/* $Log: I:/BULL/URIP/RTS/OUT/OUTDATA.C_V $
*
* Rev 1.46 Dec 15 2004 12:22:42 galejss
* make all DBG calls 16-bit-compatible
*
* Rev 1.45 Sep 27 2004 15:16:22 galejss
* "hisWrong" now allocated from NEW_POOL - needs TEMPCHARfree()
*
* Rev 1.44 Oct 09 2003 13:22:54 IndrelR
* Changes for Vertical Writing .
*
* Rev 1.43 Oct 09 2003 13:21:26 IndrelR
*
*
* Rev 1.42 Aug 22 2003 09:09:58 LynchR
* Updated copyright notice.
*
* Rev 1.41 Aug 13 2003 15:42:54 LynchR
* Added error checking for memory allocation.
*
* Rev 1.40 Jul 21 2003 18:24:16 Galejs
* reentrancy / debug fixes
*
* Rev 1.39 Jun 23 2003 14:59:40 Galejs
* ufstport.h
*
* Rev 1.38 Dec 02 2002 18:05:50 Galejs
* cast all calls to MEMptr()
*
* Rev 1.37 Sep 27 2002 18:33:50 Doolittl
* Changes for TT_SCREENRES to return fractional pixel advance information.
*
* Rev 1.36 Sep 25 2002 15:32:20 Galejs
* FIX_CONTOURS changes (bug # 73) (for awr)
*
* Rev 1.35 04 Jun 2001 10:12:44 JOE
*
* OpenType changes.
*
* Rev 1.34 Nov 28 2000 18:31:46 Galejs
* remove code for obsolete PST1 option
*
* Rev 1.33 Mar 22 2000 15:26:26 galejs
* vertical-writing changes (for keb)
*
* Rev 1.32 Aug 09 1999 18:37:18 galejs
* include-file changes
*
* Rev 1.31 29 Jul 1999 17:11:24 JOE
* Changed DEBUG directive to AGFADEBUG (by ks).
*
* Rev 1.30 21 Jan 1999 17:04:26 GALEJS
* standardize #include tests
*
* Rev 1.29 19 Jan 1999 18:39:16 GALEJS
* LONGALIGN macro needs to handle 64-bit pointers correctly
*
* Rev 1.28 12 Jan 1999 17:34:48 GALEJS
* use CONST for read-only data; move EXTERN dcls
*
* Rev 1.27 02 Sep 1998 17:30:44 GALEJS
* "olcubeto" element of OUT_TBL not conditional on CUBIC now
*
* Rev 1.26 13 Aug 1998 15:10:02 GALEJS
* undo my mistake
*
* Rev 1.24 22 Jun 1998 18:42:24 GALEJS
* make Outline fully reentrant
*
* Rev 1.23 15 Jun 1998 11:12:16 GALEJS
* reentrancy parm-passing changes
*
* Rev 1.22 16 Apr 1998 18:42:36 GALEJS
* oops - put back q3.h include
*
* Rev 1.21 02 Apr 1998 19:24:00 GALEJS
* move GLOBAL odata structure to IF_STATE
*
* Rev 1.20 25 Mar 1998 14:57:08 JOE
* In odifbb(), changed reference to "origin.x" and "origin.y" to
* "origin_cs.x" and "origin_cs.y" respectively.
*
* Rev 1.19 24 Mar 1998 16:55:14 GALEJS
* include-file changes
*
* Rev 1.18 24 Mar 1998 16:01:48 JOE
* In olstartchar(), if processing IF outlines, adjust "VLCpower"
* by "powincr" since we bypass ifrender().
*
* Rev 1.17 04 Mar 1998 11:53:42 AL
* Fixed VLCpower calculation
*
* Rev 1.16 13 Feb 1998 12:38:40 AL
* Changed meaning of VLCpower to support CGIFbound_box()
*
* Rev 1.15 03 Feb 1998 09:35:20 AL
* Conditional compile mixup in olquadto()
*
* Rev 1.14 30 Jan 1998 16:35:50 GALEJS
* gaso_pn is in if_state now
*
* Rev 1.13 28 Jan 1998 11:46:20 AL
* Moved towards re-entrant
*
* Rev 1.12 05 Dec 1997 11:42:36 MIKE
* (1) VLC change in fix_cubic_ol (2) Fixed cubic output bug in olcubeto()
*
* Rev 1.11 30 Jul 1997 08:33:32 KEB
* Conditionally compiled calls to quadvectorize() and cubevectorize()
*
* Rev 1.10 24 Jul 1997 16:21:14 JIMMY
* Added prototypes for quadvectorize() and cubevectorize() to
* resolve warning messages.
*
* Rev 1.9 15 Jul 1997 10:35:26 AL
* Pseudo bold via outlines
*
* Rev 1.8 07 Apr 1995 09:17:36 LISA
* Changed copyright from Miles Inc. to Bayer Corp.
*
* Rev 1.7 15 Feb 1995 16:36:00 MAC
* Fixed printf's format specifiers in print_outline_data().
*
* Rev 1.6 22 Apr 1994 14:23:32 LISA
* Made modifications to copyright/disclaimer notice.
*
* Rev 1.5 02 Feb 1994 08:43:14 JOE
* Removed #include statement for "memory.h".
*
* Rev 1.4 12 Feb 1993 14:44:54 JOE
* VXWorks support.
*
* Rev 1.3 29 Jan 1993 09:20:24 JOE
* In olstartchar(), saved em box size in "odata.pol".
*
* Rev 1.2 05 Jan 1993 15:03:58 JOE
* ANSI C function declaration changes.
*
* Rev 1.1 14 Dec 1992 09:25:24 LISA
* Made change to Log keyword
*
* Rev 1.0 10 Dec 1992 08:28:36 LISA
* Initial revision.
*/
/* $Date: Dec 15 2004 12:22:42 $ */
/* outdata.c */
/*---------------------------------------------------------------------
09-11-90 bjg Added quadratic outline support.
12-01-90 awr split off from maker.c. Removed unused parameters
from linear() and quadra().
02-04-91 awr Changed name des2wrkbm() to des2bm()
02-04-91 tnc In outline_metrics(), if compound character, store
"h_esc" as escapement instead of calculating it
from bounding box.
dET In outline_metrics(), "is_compound" and "h_esc"
are part of structure "chr_def_hdr".
03-06-91 jfd In make_char_part(), corrected typeo in conditional
compile (#if QUADRA was #if QUADdRA)
In outline(), loaded "*phol" prior to calling
outline_metrics().
03-10-91 awr Corrected size calculations for outline memory
19-May-91 awr LOOP structure changed
1-Jun-91 awr HQ4 changes
9-Jun-91 awr added more output to print_outline_data()
changed chr_def_hdr structure
17-Jun-91 jfd Moved "debug.h" after "port.h".
Moved "profile.h" after "port.h".
Moved "cgconfig.h" before "port.h".
29-Jun-91 awr Removed d.tt- not needed.
23-Aug-91 rs make_char_part() & outline_metrics() -> GLOBAL
24-Aug-91 awr Moved function decls to include file
6-Sep-91 awr Changed HEADERSIZE to OLHEADERSIZE
9-Sep-91 jfd Changed routine names as follows:
OUTstartchar() --> odstartchar()
OUTendchar()--> odendchar()
OUTstartloop() --> odstartloop()
OUTendloop() --> odendloop()
OUTmoveto() --> odmoveto()
OUTlineto() --> odlineto()
OUTquadto() --> odquadto()
OUTcurveto() --> odcurveto()
In odstartloop(), was not declaring argument
"polarity".
Added function prototype for outdata().
10-Sep-91 jfd Changed naming convention of outline functions:
odstartchar() --> _olstartchar()
odendchar() --> _olendchar()
odstartloop() --> _olstartloop()
odendloop() --> _olendloop()
odmoveto() --> _olmoveto()
odlineto() --> _ollineto()
odquadto() --> _olquadto()
odcurveto() --> _olcurveto()
Added PWORDVECTOR argument to _olifbb.
11-Sep-91 jfd In _olendchar(), reduce size of outline by removing
unused space and update appropriate offsets and sizes.
Including "mixmodel.h" and <memory.h>.
12-Sep-91 jfd In _olendchar(), check if unused space exists before
trying to reclaim it.
Changed name of _olcurveto() to _olcubeto().
8 Oct 91 ss Added prototype for cpymem() in !LINT_ARGS case.
12-Oct-91 awr Removed unused #include "bitmap.h"
07-Nov-91 jfd In _olstartchar(), when calculating "odata.pntptr",
add 8 instead of 4 to accomodate changes in
OUTLINE_CHAR structure.
12-Nov-91 jfd In _olstartchar(), replaced constants with sizeof
operations for SUN/SPARC compatability.
In _olendchar(), did the same thing.
22-Nov-91 rs Modify odifbb() to not add translation to get bbox.
This bbox is NOT same as from CGIFCHAR_handle() - error
equals 1/2 of translation vector.
03-Apr-92 rs Portability cleanup (see port.h).
#ifdef'd out 'OLrealloc()', not used?
10-Apr-92 jfd In _olendchar(), applying translation to coordinates.
21-May-92 jfd In order to use the function table, the following
outline functions' argument lists were changed to
match those of the corresponding bitmap functions:
olmoveto: (SW16VECTOR) --> (SL32, SL32)
ollineto: (SW16VECTOR) --> (SL32, SL32)
olquadto: (SW16VECTOR, SW16VECTOR) -->
(SL32, SL32, SL32, SL32)
olcubeto: (SW16VECTOR, SW16VECTOR, SW16VECTOR) -->
(SL32, SL32, SL32, SL32, SL32, SL32)
The argument for olstartchar() was changed from
OLSTATS to PVOID.
22-May-92 jfd In _olendchar(), removed code which applied translation
to coordinates. Will do it in make_char_part().
29-May-92 jfd In "odata" structure and in _olstartchar(), changed
type "OLSTATS" to "CHAR_STATS" due to change in
"ix.h".
19-Jun-92 jfd In outdata(), if processing space character, set
"est_size" to 0.
If outline() returns ERR_fixed_space, save handle
to outline and return.
In _olstartchar(), if processing a space character,
return ERR_fixed_space.
1 Jul 92 ss Added !LINT_ARGS prototypes.
2-Jul-92 jfd Added olcubequadto() for generating TT cubic outlines
from quadratic outlines.
7-Jul-92 jfd Re-enabled POSTSCRIPCONTOUR so that fix_cubic_ol()
is called to reverse contours if necessary.
10 Jul 92 ss,awr Changed refs from OUTLINE_CHAR.bm to new item ol.
Long align beginning of vectors before setting.
14-Jul-92 awr Changed call to make_gaso().
16-Jul-92 rs/jfd Fixed "fix_cubic_ol()" bug by making "temppnt"
(data at beginning of coordinate data section)
an MLOCAL instead of frame variable due to potential
compiler bug in MSC.
09-Aug-92 rs Changes for Watcom C386 (string.h).
15-Sep-92 jfd COnditionally compiled odifbb() based on IF_RDR &&
PST1.
23-Sep-92 jfd INTEL960 conditional compile changes.
15-Nov-92 rs Port to Mac - rename outline() to cgoutline().
05-Jan-93 jfd ANSI C function declaration changes.
27-Jan-93 jfd In olstartchar(), store em box size in "odata.pol".
08-Feb-93 jfd VXWorks support.
26-Jan-94 jfd Removed #include statement for "memory.h".
15-Feb-95 mac Fixed printf's format specifiers in print_outline_data()
30-Jul-97 keb Conditionally compiled calls to quadvectorize()
and cubevectorize().
01-Dec-97 mby VLC support - in fix_cubic_ol() declare "UL32 i".
04-Dec-97 mby Fixed bug - conditional code in olcubeto() messed up
num_segmts if you wanted CUBIC output on a TRUETYPE
or MICROTYPE font.
16-Jan-98 awr Removed
EXTERN CHR_DEF_HDR chr_def_hdr;
EXTERN CHR_DEF chr_def[];
OUTDATA outdata; on the way towards re-entrant
30-Jan-98 slg "gaso_pn" is now an element of "if_state"
3-Feb-98 awr fixed "PODATA p = (POUDATA)s;" conditional compile
mixup in olquadto()
7-Feb-98 awr Changed meaning of VLCpower to support CGIFbound_box()
24-Mar-98 jfd In olstartchar(), if processing IF outlines,
adjust "VLCpower" by "powincr" since we are
bypassing ifrender().
25-Mar-98 jfd In odifbb(), changed reference to "origin.x" and
"origin.y" to "origin_cs.x" and "origin_cs.y"
respectively.
02-Apr-98 slg Move GLOBAL odata structure to if_state.
02-Sep-98 slg "olcubeto" element of OUT_TBL should not be conditionally
compiled #if-CUBIC - this causes stack-fault crashes when
using PostScript and LINEAR outlines with !CUBIC
19-Jan-99 slg LONGALIGN definition now conditional for 32-bit / 64-bit
longs (so that 64-bit pointers not truncated).
Also fix compiler warning in fix_cubic_ol().
28-July-99 ks Changed DEBUG compiler directive to AGFADEBUG.
22-Mar-00 keb changed char bbox calc. if vert writ is enabled
28-Nov-00 slg Remove odifbb() - only used with obsolete PST1 option.
23-May-01 jfd OpenType changes:
in out_setRender(), point to correct bucket.
12-Sep-02 awr Added logic to free the isWrong[] array to fix badly wound contours
-----------------------------------------------------------------------*/
#include "cgconfig.h"
#if OUTLINE && OLDATA /* Entire module is conditionally compiled */
#ifdef VXWORKS
#include "vxWorks.h"
#endif
#include <stdio.h>
#include <string.h>
#include "ufstport.h"
#include "dbg_ufst.h"
#include "shareinc.h"
#include "q3.h"
#include "mixmodel.h"
#ifdef LINT_ARGS
MLOCAL VOID cpymem(LPSB8, LPSB8, UW16);
MLOCAL VOID fix_cubic_ol(POUTLINE_CHAR);
#ifdef AGFADEBUG
MLOCAL VOID print_outline_data(FSP PIFOUTLINE);
#endif
MLOCAL UW16 olstartchar(FSPvoid PVOID, PVOID); /* 5-21-92 !!! */
MLOCAL UW16 olendchar(FSPvoid PVOID);
MLOCAL UW16 olstartloop(FSPvoid PVOID, UW16);
MLOCAL UW16 olendloop(FSPvoid PVOID);
MLOCAL UW16 olmoveto(FSPvoid PVOID, INTR, INTR);
MLOCAL UW16 ollineto(FSPvoid PVOID, INTR, INTR);
MLOCAL UW16 olquadto(FSPvoid PVOID, INTR, INTR, INTR, INTR);
MLOCAL UW16 olcubeto(FSPvoid PVOID, INTR, INTR, INTR, INTR, INTR, INTR);
MLOCAL UW16 olcubequadto(FSPvoid PVOID, INTR, INTR, INTR, INTR);
#else /* !LINT_ARGS */
MLOCAL VOID cpymem();
MLOCAL VOID fix_cubic_ol();
#ifdef AGFADEBUG
MLOCAL VOID print_outline_data();
#endif
MLOCAL UW16 olstartchar(); /* 5-21-92 !!! */
MLOCAL UW16 olendchar();
MLOCAL UW16 olstartloop();
MLOCAL UW16 olendloop();
MLOCAL UW16 olmoveto();
MLOCAL UW16 ollineto();
MLOCAL UW16 olquadto();
MLOCAL UW16 olcubeto();
MLOCAL UW16 olcubequadto();
#endif /* LINT_ARGS */
#if (NAT_ALIGN == 8) /* make sure not to truncate 64-bit pointers */
#define LONGALIGN( v ) (((SL64)(v)+7)&0xFFFFFFFFFFFFFFF8)
#else
#define LONGALIGN( v ) (((SL32)(v)+3)&0xFFFFFFFC)
#endif
#define POSTSCRIPTCONTOUR 1 /* use to reverse cubic outlines for PST1 */
#ifdef AGFADEBUG
#if defined (ANSI_DEFS)
MLOCAL VOID print_outline_data(FSP PIFOUTLINE pol)
#else
MLOCAL VOID
print_outline_data(pol)
PIFOUTLINE pol;
#endif
{
POUTLINE_CHAR outchar;
INTR x0,y0,x1,y1,x2,y2,x3,y3;
SW16 num_contrs,num_segmts;
LPSB8 segment;
PINTRVECTOR points;
SW16 i,j;
DBG("\n\nprint_outline_data()\n");
DBG1(" size\t%ld\n", pol->size); /* size of header w/out metrics */
DBG1(" depth\t%d\n", pol->depth); /* always 1 */
#if INTR_SIZE == 16
DBG1(" left\t%d\n", pol->left);
DBG1(" top\t\t%d\n", pol->top);
DBG1(" right\t%d\n", pol->right);
DBG1(" bottom\t%d\n", pol->bottom);
#else
DBG1(" left\t%ld\n", pol->left);
DBG1(" top\t\t%ld\n", pol->top);
DBG1(" right\t%ld\n", pol->right);
DBG1(" bottom\t%ld\n", pol->bottom);
#endif
#if VLCOUTPUT
DBG1(" VLCpower\t%d\n", pol->VLCpower);
#else
DBG1(" xscale\t%d\n", pol->xscale);
DBG1(" yscale\t%d\n", pol->yscale);
#endif
DBG1(" escapement\t%d\n", pol->escapement);
outchar = &pol->ol;
num_contrs = outchar->num_loops;
DBG1("\nNumber of loops %d\n", num_contrs);
for(i=0; i<num_contrs; i++)
{
num_segmts = outchar->loop[i].num_segmts;
segment = (LPSB8)((LPSB8)(outchar->loop)
+ outchar->loop[i].segmt_offset);
points = (PINTRVECTOR)((LPSB8)(outchar->loop)
+ outchar->loop[i].coord_offset);
DBG1("Next Contour num_segmts = %d\n", num_segmts);
DBG1(" polarity = %d\n", outchar->loop[i].polarity);
for(j=0; j<num_segmts; j++)
{
if(*segment == 0x00)
{
x0 = points->x;
y0 = points->y; points++;
#if INTR_SIZE == 16
DBG2(" MoveTo %6d %6d\n", x0, y0);
#else
DBG2(" MoveTo %6ld %6ld\n", x0, y0);
#endif
}
else if (*segment == 0x01)
{
x1 = points->x;
y1 = points->y; points++;
#if INTR_SIZE == 16
DBG2(" LineTo %6d %6d\n", x1, y1);
#else
DBG2(" LineTo %6ld %6ld\n", x1, y1);
#endif
}
else if (*segment == 0x02)
{
x1 = points->x;
y1 = points->y; points++;
x2 = points->x;
y2 = points->y; points++;
#if INTR_SIZE == 16
DBG4(" QuadTo %6d %6d %6d %6d\n", x1, y1, x2, y2);
#else
DBG4(" QuadTo %6ld %6ld %6ld %6ld\n", x1, y1, x2, y2);
#endif
}
else if (*segment == 0x03)
{
x1 = points->x;
y1 = points->y; points++;
x2 = points->x;
y2 = points->y; points++;
x3 = points->x;
y3 = points->y; points++;
#if INTR_SIZE == 16
DBG6(" CurvTo %6d %6d %6d %6d %6d %6d\n",
x1, y1, x2, y2, x3, y3);
#else
DBG6(" CurvTo %6ld %6ld %6ld %6ld %6ld %6ld\n",
x1, y1, x2, y2, x3, y3);
#endif
}
else
DBG1(" INVALID SEGMENT CODE %d\n", *segment);
segment++;
}
}
}
#endif
#define MOVETO 0
#define LINETO 1
#define QUADTO 2
#define CURVETO 3
#if POSTSCRIPTCONTOUR
/*----------------------*/
/* fix_cubic_ol */
/*----------------------*/
/* reverse outline depending on fill rule and polarity */
/*
Reverse outline depending on fill rule and polarity. PostScript
follows a "fill to the left" rule. Outside contours are counter-clockwise
and inside contours are clockwise.
NOTE: This algorithm will only work if there are NO open paths within
contours. The final point must end up at the start point.
Only newly made loops in case of a compound character are reversed.
*/
#if defined (ANSI_DEFS)
MLOCAL VOID fix_cubic_ol(POUTLINE_CHAR outcharptr)
#else
MLOCAL VOID
fix_cubic_ol(outcharptr)
POUTLINE_CHAR outcharptr;
#endif
{
INTRVECTOR temppnt;
POUTLINE_LOOP oloop;
LPSB8 segptr, bsegptr;
PINTRVECTOR pntptr, bpntptr;
SW16 k;
SB8 tempseg;
oloop = outcharptr->loop;
for (k = 0; k<outcharptr->num_loops; k++, oloop++ )
{
/* Only reverse the points for polarity == 0 */
if(!oloop->polarity)
{
SL32 i; /* for a VLC, num_segmts could be > 64K */
oloop->polarity = 1;
/* Reverse order of segments. Leave 1st moveto where it is.
* Point segptr just after the MOVETO segment. Point bsegptr
* to the bottom segment
*/
segptr = (LPSB8)(outcharptr->loop) + oloop->segmt_offset + 1;
bsegptr = (LPSB8)segptr + oloop->num_segmts - 2;
for (i = 0; i < ((oloop->num_segmts - 1) >> 1); i++)
{
tempseg = *segptr;
*segptr++ = *bsegptr;
*bsegptr-- = tempseg;
}
/* Reverse order of points using the same idea. */
pntptr = (PINTRVECTOR)((LPSB8)(outcharptr->loop)
+ oloop->coord_offset);
bpntptr = pntptr + oloop->num_coords - 1;
for (i = 0; i < (oloop->num_coords >> 1); i++)
{
temppnt = *pntptr;
*pntptr++ = *bpntptr;
*bpntptr-- = temppnt;
}
} /* if (polarity == 0) */
}
}
#endif /* POSTSCRIPTCONTOUR */
/*----------------------*/
/* olstartchar */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16 olstartchar(FSPvoid PVOID s, PVOID pstats)
#else
MLOCAL UW16
olstartchar(s, pstats)
PVOID s;
PVOID pstats; /* 5-21-92 !!! */
#endif
{
PODATA p = (PODATA)s;
FSPusevoid /* converts optional PVOID parm to PIF_STATE */
p->s = *(PCHAR_STATS)pstats; /* keep copy of input CHAR_STATS */
DBG("olstartchar()\n");
DBG1(" p->s.format %d\n", p->s.format );
DBG1(" .nloop %d\n", p->s.nloop );
DBG1(" .est_pnts %d\n", p->s.est_pnts);
DBG1(" .est_segs %d\n", p->s.est_segs);
DBG1(" .est_size %ld\n", p->s.est_size);
/* Get memory for IFOUTLINE */
if(p->pol) /* If using apps buffer */
p->hol = (HIFOUTLINE)NIL_MH; /* set to nil so we don't realloc */
else /* else alloc and realloc at end */
{
p->hol = CHARalloc(FSA (SL32)(OLHEADERSIZE+p->s.est_size));
if(p->hol == (HIFOUTLINE)NIL_MH)
return ERRoutline_mem;
p->pol = (PIFOUTLINE)MEMptr(p->hol);
}
/* Special case:
* if space character, return ERR_fixed_space
*/
if (!if_state.num_loops) /* 6-19-92 */
return ERR_fixed_space;
/* Fill in IFOUTLINE header */
p->pol->size = p->s.est_size;
p->pol->depth = 1;
p->pol->left = p->s.olbox.ll.x;
p->pol->bottom = p->s.olbox.ll.y;
p->pol->right = p->s.olbox.ur.x;
p->pol->top = p->s.olbox.ur.y;
/* keb 2/00 */
if (FC_ISUFSTVERT(&if_state.fcCur))
{
if ( if_state.CharVertWrit )
{
p->pol->left = p->pol->left + if_state.cs.origin_cs.x;
p->pol->bottom = p->pol->bottom + if_state.cs.origin_cs.y;
p->pol->right = p->pol->right + if_state.cs.origin_cs.x;
p->pol->top = p->pol->top + if_state.cs.origin_cs.y;
}
}
#if VLCOUTPUT
/* Set VLCpower to the power of two to multiply the coordinates by
* as they come out of the fst render() functions to convert them into
* output pixels.
*/
p->pol->VLCpower = if_state.cs.VLCpower - if_state.x.grid_shift;
#if IF_RDR
if(if_state.fst_type == FC_IF_TYPE)
p->pol->VLCpower -= (SW16)powincr;
#endif
#else
p->pol->xscale = p->s.xscale;
p->pol->yscale = p->s.yscale;
#endif
p->pol->escapement = p->s.escapement;
#if GET_VERTICAL_METRICS
p->pol->topSideBearing = p->s.topSideBearing;
p->pol->advanceHeight = p->s.advanceHeight;
#endif /* R.I. 07/10/03 */
#if TT_SCREENRES
p->pol->pixelWidth = p->s.pixelWidth; /* jwd, 07/24/02 */
p->pol->advanceWidth.x = p->s.advanceWidth.x; /* jwd, 08/18/02 */
p->pol->advanceWidth.y = p->s.advanceWidth.y;
#endif
/* Store em box size - 01/27/93 jfd */
p->pol->du_emx = p->s.du_emx;
p->pol->du_emy = p->s.du_emy;
p->outcharptr = &p->pol->ol;
p->outcharptr->size = p->s.est_size;
p->outcharptr->num_loops = p->s.nloop;
/* point to first loop and start of data area */
p->oloop = p->outcharptr->loop;
p->pntptr = (PINTRVECTOR)
((LPSB8)p->outcharptr
/* VVV only have one now */
+ (sizeof(OUTLINE_CHAR) - sizeof(OUTLINE_LOOP))
+ sizeof(OUTLINE_LOOP) * p->s.nloop);
/* make sure vectors start on long aligned address -ss,awr 7/10/92 */
p->pntptr = (PINTRVECTOR)LONGALIGN( p->pntptr );
p->segptr = (LPSB8)(p->pntptr + p->s.est_pnts);
p->tot_segs = 0;
p->tot_pnts = 0;
return SUCCESS;
}
/*----------------------*/
/* olendchar */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16 olendchar(FSPvoid PVOID s)
#else
MLOCAL UW16
olendchar(s)
PVOID s;
#endif
{
PIFOUTLINE pol;
POUTLINE_CHAR outchar;
SW16 i;
SW16 wasted_point_space;
SW16 wasted_segmt_space;
SW16 wasted_total_space;
LPSB8 segment;
LPSB8 src;
LPSB8 dst;
MEM_HANDLE nh;
SW16 new_size;
PIFOUTLINE dol;
PODATA p = (PODATA)s;
FSPusevoid /* converts optional PVOID parm to PIF_STATE */
#ifdef AGFADEBUG
print_outline_data(FSA p->pol);
#endif
DBG2("est_segs = %d actual segs = %d\n",
p->s.est_segs, p->tot_segs);
DBG2("est_pnts = %d actual pnts = %d\n",
p->s.est_pnts, p->tot_pnts);
DBG1(" wasted space = %d\n", 4*(p->s.est_pnts-p->tot_pnts)
+ p->s.est_segs-p->tot_segs);
#if POSTSCRIPTCONTOUR
/*
changed from '=' to '==' - 4/3/92 - rs
*/
if(p->s.format == FC_CUBIC_TYPE)
fix_cubic_ol(p->outcharptr);
#endif /* POSTSCRIPTCONTOUR */
if(p->hol != (HIFOUTLINE)NIL_MH)
{
/* if linear or cubic, quality level == 3 and */
/* unused space exists, remove unused space */
wasted_point_space = sizeof(INTRVECTOR) *
(p->s.est_pnts - p->tot_pnts); /* 11-12-91 jfd */
wasted_segmt_space = p->s.est_segs - p->tot_segs;
wasted_total_space = wasted_point_space + wasted_segmt_space;
if ((if_state.quality == 3)
&& (p->s.format == (SW16)FC_LINEAR_TYPE ||
p->s.format == (SW16)FC_CUBIC_TYPE) && (wasted_total_space > 0))
{
pol = p->pol;
outchar = &pol->ol;
new_size = OLHEADERSIZE + (SW16)(pol->size - (SL32)wasted_total_space);
/* 11-07-91 jfd */
/* try to allocate new smaller block */
nh = CHARalloc(FSA (SL32)new_size); /* else leave big one */
if (nh != NIL_MH)
{
src = (SB8*)MEMptr(p->hol); /* de-reference source outline */
dst = (SB8*)MEMptr(nh); /* de-reference reduced outline */
dol = (PIFOUTLINE)dst;
/* get rid of unused space in source outline */
segment = (LPSB8)((LPSB8)(outchar->loop) +
outchar->loop[0].segmt_offset);
cpymem(segment - wasted_point_space, segment, p->tot_segs);
for (i=0; i<outchar->num_loops; i++)
outchar->loop[i].segmt_offset -= wasted_point_space;
/* copy into smaller outline */
cpymem(dst, src, new_size);
/* update appropiate sizes */
dol->size -= wasted_total_space;
outchar = &dol->ol;
outchar->size -= wasted_total_space;
/* free old outline */
CHARfree(FSA p->hol); /* free old outline */
/* update odata pointers */
p->hol = nh;
p->pol = (PIFOUTLINE)MEMptr(p->hol);
}
else /* Added error handling */ /* rjl 8/4/2003 - */
{
CHARfree(FSA p->hol); /* free old outline */
return ERRoutline_mem;
}
}
}
#if FIX_CONTOURS
if(if_state.ras.nz_instance.isWrong) /* not NULL means 2nd time, need to free */
{
TEMPCHARfree(FSA if_state.ras.nz_instance.hisWrong);
if_state.ras.nz_instance.isWrong = NULL;
if_state.ras.nz_instance.hisWrong = NIL_MH;
}
#endif
return SUCCESS;
}
/*----------------------*/
/* olstartloop */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16 olstartloop(FSPvoid PVOID s, UW16 polarity)
#else
MLOCAL UW16
olstartloop(s, polarity)
PVOID s;
UW16 polarity;
#endif
{
PODATA p = (PODATA)s;
p->oloop->num_segmts = 0;
p->oloop->num_coords = 0;
p->oloop->segmt_offset =
(LPSB8)p->segptr - (LPSB8)p->outcharptr->loop;
p->oloop->coord_offset =
(LPSB8)p->pntptr - (LPSB8)p->outcharptr->loop;
p->oloop->polarity = polarity;
return SUCCESS;
}
/*----------------------*/
/* olendloop */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16 olendloop(FSPvoid PVOID s)
#else
MLOCAL UW16
olendloop(s)
PVOID s;
#endif
{
PODATA p = (PODATA)s;
p->oloop++;
return SUCCESS;
}
/*----------------------*/
/* olmoveto */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16 olmoveto(FSPvoid PVOID s, INTR vx, INTR vy)
#else
MLOCAL UW16
olmoveto(s, vx, vy)
PVOID s;
INTR vx;
INTR vy;
#endif
{
PODATA p = (PODATA)s;
p->oloop->num_segmts++;
p->oloop->num_coords++;
p->tot_segs++;
p->tot_pnts++;
if((p->tot_segs > p->s.est_segs)
|| (p->tot_pnts > p->s.est_pnts))
return ERRoutline_mem;
*p->segptr++ = MOVETO;
p->pntptr->x = vx;
p->pntptr->y = vy;
p->pntptr++;
p->p0x = vx;
p->p0y = vy;
return SUCCESS;
}
/*----------------------*/
/* ollineto */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16 ollineto(FSPvoid PVOID s, INTR vx, INTR vy)
#else
MLOCAL UW16
ollineto(s, vx, vy)
PVOID s;
INTR vx;
INTR vy;
#endif
{
PODATA p = (PODATA)s;
p->oloop->num_segmts++;
p->oloop->num_coords++;
p->tot_segs++;
p->tot_pnts++;
if((p->tot_segs > p->s.est_segs)
|| (p->tot_pnts > p->s.est_pnts))
return ERRoutline_mem;
*p->segptr++ = LINETO;
p->pntptr->x = vx;
p->pntptr->y = vy;
p->pntptr++; /* 5-21-92 !!! */
p->p0x = vx;
p->p0y = vy;
return SUCCESS;
}
/*----------------------*/
/* olquadto */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16 olquadto(FSPvoid PVOID s, INTR cx, INTR cy, INTR vx, INTR vy)
#else
MLOCAL UW16
olquadto(s, cx, cy, vx, vy)
PVOID s;
INTR cx, cy, vx, vy;
#endif
{
PODATA p = (PODATA)s;
FSPusevoid /* converts optional PVOID parm to PIF_STATE */
#if LINEAR
if(if_state.cs.format == FC_LINEAR_TYPE)
/*keb*/
#if ((TT_RDR || FCO_RDR) && (CGBITMAP || LINEAR || SMEAR_BOLD || GRAYSCALING))
return quadvectorize ( FSA s, ollineto, p->p0x, p->p0y,
cx, cy, vx, vy );
#endif
#endif /* LINEAR */
p->oloop->num_segmts++;
p->oloop->num_coords += 2;
p->tot_segs++;
p->tot_pnts += 2;
if((p->tot_segs > p->s.est_segs)
|| (p->tot_pnts > p->s.est_pnts))
return ERRoutline_mem;
*p->segptr++ = QUADTO;
p->pntptr->x = cx;
p->pntptr->y = cy;
p->pntptr++;
p->pntptr->x = vx;
p->pntptr->y = vy;
p->pntptr++;
p->p0x = vx;
p->p0y = vy;
return SUCCESS;
}
/*----------------------*/
/* olcubeto */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16 olcubeto(FSPvoid PVOID s, INTR c0x, INTR c0y, INTR c1x, INTR c1y,
INTR vx, INTR vy)
#else
MLOCAL UW16
olcubeto(s, c0x, c0y, c1x, c1y, vx, vy)
PVOID s;
INTR c0x, c0y, c1x, c1y, vx, vy;
#endif
{
PODATA p = (PODATA)s;
FSPusevoid /* converts optional PVOID parm to PIF_STATE */
#if ((PST1_RDR) && (CGBITMAP || LINEAR || SMEAR_BOLD || GRAYSCALING))
if(if_state.cs.format == FC_LINEAR_TYPE)
return cubevectorize ( FSA s, ollineto, p->p0x, p->p0y,
c0x, c0y, c1x, c1y, vx, vy );
#endif
p->oloop->num_segmts++;
p->oloop->num_coords += 3;
p->tot_segs++;
p->tot_pnts +=3;
if((p->tot_segs > p->s.est_segs)
|| (p->tot_pnts > p->s.est_pnts))
return ERRoutline_mem;
*p->segptr++ = CURVETO;
p->pntptr->x = c0x;
p->pntptr->y = c0y;
p->pntptr++;
p->pntptr->x = c1x;
p->pntptr->y = c1y;
p->pntptr++;
p->pntptr->x = vx;
p->pntptr->y = vy;
p->pntptr++;
p->p0x = vx;
p->p0y = vy;
return SUCCESS;
}
/*----------------------*/
/* olcubequadto */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16 olcubequadto(FSPvoid PVOID s, INTR cx, INTR cy, INTR vx, INTR vy)
#else
MLOCAL UW16
olcubequadto(s, cx, cy, vx, vy)
PVOID s;
INTR cx, cy, vx, vy;
#endif
{
INTR cx0, cy0, cx1, cy1;
UW16 status;
PODATA p = (PODATA)s;
FSPusevoid /* converts optional PVOID parm to PIF_STATE */
cx0 = (INTR)(((SL32)p->p0x + ((SL32)cx << 1)) / 3L);
cy0 = (INTR)(((SL32)p->p0y + ((SL32)cy << 1)) / 3L);
cx1 = (INTR)((((SL32)cx << 1) + (SL32)vx) / 3L);
cy1 = (INTR)((((SL32)cy << 1) + (SL32)vy) / 3L);
status = olcubeto ( FSAvoid s, cx0, cy0, cx1, cy1, vx, vy );
return status;
}
/*----------------------*/
/* cpymem */
/*----------------------*/
/* Like memcpy() only copies from front to back (for sure). It's here so we
* don't have to use memmove()
*/
#if defined (ANSI_DEFS)
MLOCAL VOID cpymem(LPSB8 dest, LPSB8 src, UW16 count)
#else
MLOCAL VOID
cpymem(dest, src, count)
LPSB8 dest;
LPSB8 src;
UW16 count;
#endif
{
while(count--)
*dest++ = *src++;
}
/*----------------------*/
/* outdata */
/*----------------------*/
#if defined (ANSI_DEFS)
GLOBAL UW16 outdata(FSP PHIFOUTLINE phol)
#else
GLOBAL UW16
outdata(phol)
PHIFOUTLINE phol; /* Final result goes here */
#endif
{
UW16 status;
DBG("\n\n\n\no u t d a t a()\n");
if_state.odata.pol = (PIFOUTLINE)0; /* to signal no outline memory buffer */
/* Special case:
* if space character, set "est_size" to 0 because
* "make_gaso_and_stats()" has not been called to
* calculate this value
*/
if (!if_state.num_loops) /* 6-19-92 */
if_state.odata.s.est_size = 0L;
status = cgoutline(FSA0);
/* Special case:
* if space character, store handle before returning
*/
if (status == ERR_fixed_space) /* 6-19-92 */
*phol = if_state.odata.hol;
if (status)
return status;
*phol = if_state.odata.hol;
return SUCCESS;
}
/*----------------------*/
/* outbuffer */
/*----------------------*/
#if defined (ANSI_DEFS)
GLOBAL UW16 outbuffer(FSP PIFOUTLINE pol)
#else
GLOBAL UW16
outbuffer(pol)
PIFOUTLINE pol; /* Final result goes here */
#endif
{
if_state.odata.pol = pol;
return cgoutline(FSA0);
}
CONST OUT_TBL olout_tbl = {
olstartchar,
olendchar,
olstartloop,
olendloop,
olmoveto,
ollineto,
olquadto,
olcubeto
};
/*----------------------*/
/* out_setRender */
/*----------------------*/
#if defined (ANSI_DEFS)
GLOBAL VOID out_setRender( FSP0 )
#else
GLOBAL VOID
out_setRender()
#endif
{
PBUCKET pb; /* 05-23-01 jfd */
if_state.out_instance = &if_state.odata;
if_state.out = olout_tbl;
pb = GET_pBUCKET(if_state.pbucket); /* 05-23-01 jfd */
#if (TT_RDR || FCO_RDR)
/* Substitute TT cubequadto() function for cubeto() */
if ((pb->fst_type == FC_TT_TYPE || /* changed 'if_state.pbucket' to 'pb' 05-23-01 jfd */
pb->fst_type == FC_FCO_TYPE) && /* changed 'if_state.pbucket' to 'pb' 05-23-01 jfd */
(if_state.cs.format == FC_CUBIC_TYPE))
{
#if OLDATA
if_state.out.quadto = olcubequadto;
#endif
}
#endif /* TT_RDR || FCO_RDR */
}
#endif /* OUTLINE && OLDATA */
outline.txt 、、、、、、、、、、、、、、、、、、、、、、、、、、
/*
* Copyright (C) 2004 Agfa Monotype Corporation. All rights reserved.
*/
/* $Header: I:/BULL/URIP/RTS/OUT/OUTLINE.C_V 1.39 Aug 26 2004 14:40:26 wuq $ */
/* $Log: I:/BULL/URIP/RTS/OUT/OUTLINE.C_V $
*
* Rev 1.39 Aug 26 2004 14:40:26 wuq
* Removed GET_VERTICAL_METRICS conditional
* from non output structure.
*
*
* Rev 1.38 Jun 08 2004 18:34:54 GalejsS
* fix positioning of outlines in vertical writing (make consistent with bitmaps)
*
* Rev 1.37 Oct 09 2003 13:25:46 IndrelR
* Changes for Vertical Writing .
*
* Rev 1.36 Aug 22 2003 09:09:58 LynchR
* Updated copyright notice.
*
* Rev 1.35 Jun 20 2003 14:02:22 Galejs
* get rid of NON_IF_FONT
*
* Rev 1.34 Dec 02 2002 18:06:28 Galejs
* fix uninit-vbl warnings
*
* Rev 1.33 04 Jun 2001 10:14:04 JOE
* OpenType changes.
*
* Rev 1.32 May 03 2001 20:37:46 Galejs
* data-type cleanup
*
* Rev 1.31 19 Apr 2000 11:14:10 JOE
* For TT_ROM or TT_DISK, added code to metrics() to replace escapement
* with advanceHeight, if advanceHeight exists and is different from
* escapemenet, and vertical writing is enabled (by keb).
*
* Rev 1.30 Jan 24 2000 14:52:58 galejs
* vertical-writing changes (for keb), edited to remove FCO-specific code
*
* Rev 1.29 Aug 09 1999 18:37:18 galejs
* include-file changes
*
* Rev 1.28 22 Apr 1999 13:40:10 BEHRINGE
* Modified so Vert Writ works with pseudo bolds
*
* Rev 1.27 31 Mar 1999 11:49:50 JOE
* Added code to support Vertical Writing feature (by keb).
*
* Rev 1.26 12 Jan 1999 18:16:42 GALEJS
* move EXTERN dcls
*
* Rev 1.25 22 Jun 1998 18:43:46 GALEJS
* make Intellifont reentrant too
*
* Rev 1.24 15 Jun 1998 11:15:38 GALEJS
* reentrancy parm-passing changes
*
* Rev 1.23 15 Apr 1998 17:00:28 GALEJS
* move chr_def_hdr to IF_STATE
*
* Rev 1.22 24 Mar 1998 16:56:44 GALEJS
* include-file changes
*
* Rev 1.21 28 Jul 1997 13:58:34 JOE
* In make_char_part(), calling quadra() if LINEAR || QUADRA || CGBITMAP ||
* GRAYSCALING to resolve "ERRinvalid_outproc_type" error when emboldening
* IF bitmap using BOLD_P6.
*
* Rev 1.19 22 Jul 1997 14:54:08 AL
* Also conditionally compile on non zero winding with bold
*
* Rev 1.18 22 Jul 1997 08:22:30 AL
* Also conditionally compile on non zero winding and bold
*
* Rev 1.17 21 Jul 1997 15:12:12 JOE
* Removed PVOID as first argument for quadra() and cubic() (prototypes
* and calls).
*
* Rev 1.16 15 Jul 1997 10:40:20 AL
* Pseudo bold via outlines
*
* Rev 1.15 14 Jan 1997 21:40:28 DAVID
* Removed DRAS_QUAD option as part of project to trim ufst.
*
* Rev 1.14 25 Aug 1995 11:18:04 MIKE
* Changed last 2 args of ttrender() call (can be nonzero).
*
* Rev 1.13 07 Apr 1995 09:17:34 LISA
* Changed copyright from Miles Inc. to Bayer Corp.
*
* Rev 1.12 02 Feb 1995 13:36:32 JOE
* In make_char_part(), fixed computation of "half pixel" sizes (by mac).
*
* Rev 1.11 12 Dec 1994 08:12:58 JOE
* Conditionally compiled prototype for bmras_quad_flat() based on FCO_RDR.
* In outline(), corrected typo in conditional compile statement
* (FC_RDR is changed to FCO_RDR) (by dbk)
*
* Rev 1.10 11 Dec 1994 17:24:18 MIKE
* Replace "cs.origin" with "cs.origin_cs".
*
* Rev 1.9 17 Nov 1994 13:38:52 JOE
* More FCO outline changes (by bjg).
*
* Rev 1.8 15 Nov 1994 14:19:48 JOE
* In outline(), added FCO support (by bjg).
*
* Rev 1.7 03 Aug 1994 16:01:42 MIKE
* Added FCO changes for 1.5.1.1
*
* Rev 1.6 22 Apr 1994 14:23:30 LISA
* Made modifications to copyright/disclaimer notice.
*
* Rev 1.5 03 Sep 1993 11:06:28 JOE
* In cgoutline(), substitute proper "...quadto()" function in
* "if_state.out" table.
* Added function prototype for "bmras_quad_flat()".
*
* Rev 1.4 13 Apr 1993 13:19:16 JOE
* In cgoutline(), conditionally compiled calls to psrender() and ttrender()
* if !USE_JUMP_TABLES.
*
* Rev 1.3 12 Feb 1993 14:57:24 JOE
* VXWorks support.
*
* Rev 1.2 05 Jan 1993 14:23:58 JOE
* ANSI C function declaration changes.
*
* Rev 1.1 14 Dec 1992 09:24:48 LISA
* Made change to Log keyword
*
* Rev 1.0 10 Dec 1992 08:28:40 LISA
* Initial revision.
*/
/* $Date: Aug 26 2004 14:40:26 $ */
/* outline.c */
/*---------------------------------------------------------------------
09-11-90 bjg Added quadratic outline support.
12-01-90 awr split off from maker.c. Removed unused parameters
from linear() and quadra().
02-04-91 awr Changed name des2wrkbm() to des2bm()
02-04-91 tnc In outline_metrics(), if compound character, store
"h_esc" as escapement instead of calculating it
from bounding box.
dET In outline_metrics(), "is_compound" and "h_esc"
are part of structure "chr_def_hdr".
03-06-91 jfd In make_char_part(), corrected typeo in conditional
compile (#if QUADRA was #if QUADdRA)
In outline(), loaded "*phol" prior to calling
outline_metrics().
03-10-91 awr Corrected size calculations for outline memory
19-May-91 awr LOOP structure changed
1-Jun-91 awr HQ4 changes
9-Jun-91 awr added more output to print_outline_data()
changed chr_def_hdr structure
17-Jun-91 jfd Moved "debug.h" after "port.h".
Moved "profile.h" after "port.h".
Moved "cgconfig.h" before "port.h".
29-Jun-91 awr Removed d.tt- not needed.
24-Aug-91 awr Moved function decls to include file
6-Sep-91 awr Changed HEADERSIZE to OLHEADERSIZE
10-Sep-91 jfd Changed naming convention of outline functions.
12-Oct-91 awr Removed unused #include "bitmap.h"
03-Apr-92 rs Portability cleanup (see port.h).
13-Apr-92 awr In outline(), added braces inside "for" loop.
21-May-92 jfd In outline(), replaced direct outline function calls
with calls via the function table. Cast argument
for ras_start_char() to PVOID.
Added pointer to font function table "pras".
27-May-92 jfd In make_char_part(), when passing translations "xt"
and "yt" to quadra() and cubic(), add additional
translation "if_state.xlate.x" and "if_state.xlate.y".
29-May-92 jfd Changed type "OLSTATS" to "CHAR_STATS" due to change
in "ix.h".
4 Jun 92 jfd In outline(), if PS or TT, call "render()" with
zero translation.
8-Jun-92 jfd Replaced all references to "olstats" with
"if_state.cs".
9-Jun-92 jfd In outline(), call "render()" if requested character
is in PS or TT bucket (i.e., check "pbucket->fst_type"
rather than "format").
23-Jun-92 jfd In outline(), moved statement which copied "olout_tbl"
into "if_state.out" from beginning of routine to
two different places: after check for linear and
at end of routine.
24-Jun-92 jfd In make_char_part(), restore "if_state.tbound"
before returning.
6-Jul-92 jfd In outline(), if generating a TT cubic outline,
substitute "olcubequadto()" function for "olquadto()".
14-Jul-92 awr Changed call to make_gaso().
21-Jul-92 awr Conditional compile changes.
14-Sep-92 jfd In outline(), moved braces outside of #if IF_RDR
conditional compile.
10-Oct-92 rs Implement USE_JUMP_TABLES feature for overlays.
15-Nov-92 rs Port to Mac -> rename outline() to cgoutline().
05-Jan-93 jfd ANSI C function declaration changes.
08-Feb-93 jfd VXWorks support.
13-Apr-93 jfd In cgoutline(), conditionally compiled calls to
psrender() and ttrender() if !USE_JUMP_TABLES.
31-Aug-93 jfd In cgoutline(), substitute proper "...quadto()"
function in if_state.out table.
Added function prototypes for "bmras_quad_flat()".
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FCO Changes from 1.5.1.1:
14-Mar-94 mby If FCO is enabled, cgoutline() calls fco_render().
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
15-Nov-94 bjg In outline(), added FCO support.
11-Dec-94 mby Replace "cs.origin" with "cs.origin_cs".
12-Dec-94 dbk Conditionally compiled prototype for bmras_quad_flat()
based on FCO_RDR.
In outline(), corrected typo in conditional compile
statement (FC_RDR is changed to FCO_RDR).
02-Feb-95 mac In make_char_part(), fixed computation of "half pixel"
sizes.
24-Aug-95 mby In cgoutline, last two args to ttrender() are nonzero if
the character's LSB != xmin. This caused the outline to
lie in the wrong position. Disabled USE_JUMP_TABLES.
14-Jan-97 dlk Removed DRAS_QUAD option as part of project to trim ufst.
21-Jul-97 jfd Removed PVOID argument as first argument in quadra()
and cubic() (prototypes and calls).
22-Jul-97 awr Conditionally compiled entire file also on NON_Z_WIND
and BOLD_P6 or BOLD_HORIZONTAL
28-Jul-97 jfd In make_char_part(), calling quadra() if
LINEAR || QUADRA || CGBITMAP || GRAYSCALING to resolve
"ERRinvalid_outproc_type" error when emboldening
IF bitmap using BOLD_P6.
31-Mar-99 keb Added code to support Vertical Writing Feature. It adjusts
outline's origin (TrueType data only
22-Apr-99 keb Modified ASIANVERT code for Pseudo Bold Bitmaps
18-Jan-00 slg Vertical-writing changes (for keb) - pretty much a
rewrite of cgoutline(), for TT and FCO cases. Note that
the FCO_RDR-specific changes have NOT been checked in.
14-Apr-00 keb For TT_ROM or TT_DISK added code to metrics() to replace escapement
with advanceHeight, if advanceHeight exists and is different from
escapement, and vertical writing is enabled
23-May-01 jfd OpenType changes:
In cgoutline(), point to correct bucket.
-----------------------------------------------------------------------*/
#include "cgconfig.h"
#if OUTLINE || (NON_Z_WIND && (BOLD_P6 || BOLD_HORIZONTAL))
#ifdef VXWORKS
#include "vxWorks.h"
#endif
#include <stdio.h>
#include "ufstport.h"
#include "dbg_ufst.h"
#include "shareinc.h"
#include "q3.h"
#if IF_RDR
#ifdef LINT_ARGS
MLOCAL UW16 make_char_part(FSP UW16, PCHR_DEF);
#else
MLOCAL UW16 make_char_part();
#endif
#endif
#if IF_RDR
/*----------------------*/
/* make_char_part */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16 make_char_part(FSP UW16 pn, PCHR_DEF cd)
#else
MLOCAL UW16
make_char_part(pn, cd)
UW16 pn;
PCHR_DEF cd;
#endif
{
UW16 status;
INTR xt, yt;
DBG("make_char_part()\n");
/* Grid aligned scaled outline */
status = make_gaso(FSA (SL32)pn, cd);
if (status)
return status;
/* Translate outline: 1. to postion this part within the whole
* 2. Position the whole so origin is at (0,0)
*/
xt = (INTR)cd->bmorigin.x * (INTR)xpix - (INTR)if_state.cs.origin_cs.x;
yt = (INTR)cd->bmorigin.y * (INTR)ypix - (INTR)if_state.cs.origin_cs.y;
if_state.tbound.ll.x += xt;
if_state.tbound.ll.y += yt - half_ypix;
if_state.tbound.ur.x += xt;
if_state.tbound.ur.y += yt - half_ypix;
/* Increase the fractional output pixel by powincr bits. These values
* will be restored at the end of this function. All coordinates
* will be multiplied by 2**powincr.
*/
log_xpix += powincr;
log_ypix += powincr;
xpix <<= powincr;
ypix <<= powincr;
half_xpix = xpix >> 1;
half_ypix = ypix >> 1;
if_state.tbound.ll.x <<= powincr;
if_state.tbound.ll.y <<= powincr;
if_state.tbound.ur.x <<= powincr;
if_state.tbound.ur.y <<= powincr;
/* draw the character outline */
switch(if_state.cs.format)
{
#if (CGBITMAP || GRAYSCALING) /* 07-28-97 jfd */
case FC_BITMAP_TYPE: /* 07-28-97 jfd */
#endif /* 07-28-97 jfd */
#if LINEAR
case FC_LINEAR_TYPE: /* quadra() also makes linear outlines */
#endif
#if QUADRA
case FC_QUAD_TYPE:
#endif
#if (LINEAR || QUADRA || CGBITMAP || GRAYSCALING) /* 07-28-97 jfd */
status = quadra(FSA if_state.cs.format,
xt + if_state.xlate.x,
yt + if_state.xlate.y);
break;
#endif
#if CUBIC
case FC_CUBIC_TYPE: status = cubic(FSA xt + if_state.xlate.x,
yt + if_state.xlate.y);
break;
#endif
default: status = ERRinvalid_outproc_type;
}
/* Restore original fractional output pixel size */
log_xpix -= powincr;
log_ypix -= powincr;
xpix >>= powincr;
ypix >>= powincr;
half_xpix = xpix >> 1;
half_ypix = ypix >> 1;
if_state.tbound.ll.x >>= powincr;
if_state.tbound.ll.y >>= powincr;
if_state.tbound.ur.x >>= powincr;
if_state.tbound.ur.y >>= powincr;
if_state.tbound.ll.x -= xt;
if_state.tbound.ll.y -= yt - half_ypix;
if_state.tbound.ur.x -= xt;
if_state.tbound.ur.y -= yt - half_ypix;
return status;
}
#endif /* IF_RDR */
/*----------------------*/
/* cgoutline */
/*----------------------*/
#if defined (ANSI_DEFS)
GLOBAL UW16 cgoutline(FSP0)
#else
GLOBAL UW16
cgoutline()
#endif
{
#if IF_RDR
UW16 status, pn;
PCHR_DEF cd;
#endif
PBUCKET pb; /* 05-23-01 jfd */
DBG("\n\n\n\no u t l i n e()\n");
pb = GET_pBUCKET(if_state.pbucket); /* 05-23-01 jfd */
if (pb->fst_type == FC_PST1_TYPE || /* changed 'if_state.pbucket' to 'pb' 05-23-01 jfd */
pb->fst_type == FC_TT_TYPE || /* changed 'if_state.pbucket' to 'pb' 05-23-01 jfd */
pb->fst_type == FC_FCO_TYPE) /* changed 'if_state.pbucket' to 'pb' 05-23-01 jfd */
{
switch (pb->fst_type) /* changed 'if_state.pbucket' to 'pb' 05-23-01 jfd */
{
#if PST1_RDR
case FC_PST1_TYPE:
return (psrender ( FSA if_state.out_instance,
pb, 0L, 0L)); /* changed 'if_state.pbucket' to 'pb' 05-23-01 jfd */
break;
#endif
/* keb 12/99 (modified heavily by sandra - vertical FCO case removed) */
#if TT_RDR
case FC_TT_TYPE:
if ( FC_ISOUTLINE(&if_state.fcCur)
&& FC_ISUFSTVERT(&if_state.fcCur)
&& if_state.CharVertWrit )
{
SL32 adjx, adjy;
SW16 dx, dy, vertical_metric;
FPNUM fdx, fdy, em;
fdx = fpint2fp(0);
fdy = fpint2fp(0);
adjx = 0;
adjy = 0;
if (FC_ISXLFONT(&if_state.fcCur))
{
vertical_metric = if_state.pbucket->p.tt.FontBBox[1];
dx = vertical_metric;
dy = -(if_state.cs.du_emx + vertical_metric);
em = fpint2fp ((SL32) if_state.cs.du_emx);
fdx = fpint2fp((SL32)dx);
fdy = fpint2fp((SL32)dy);
fdx = fpdiv (fdx, em);
fdy = fpdiv (fdy, em);
}
if ((FC_ISTT(&if_state.fcCur)) & (if_state.pbucket->extern_font == 0))
{
/* keb 4/00 */
/*#if GET_VERTICAL_METRICS 08-20-04 qwu */
if ((if_state.cs.escapement != if_state.cs.advanceHeight) & (if_state.cs.advanceHeight != 0))
if_state.cs.escapement = if_state.cs.advanceHeight;
/*#endif 08-20-04 qwu */
vertical_metric = if_state.cs.yDescender;
/* dx = vertical_metric/2; */
/* dy = -(if_state.cs.du_emx + vertical_metric/2); */ /* keb 4/14/04 */
dx = vertical_metric;
dy = -(if_state.cs.du_emx + vertical_metric);
em = fpint2fp ((SL32) if_state.cs.du_emx);
fdx = fpint2fp((SL32)dx);
fdy = fpint2fp((SL32)dy);
fdx = fpdiv (fdx, em);
fdy = fpdiv (fdy, em);
}
if (FC_ISTTFMT16(&if_state.fcCur))
{
vertical_metric = if_state.cs.yDescender;
dx = vertical_metric;
dy = -(if_state.cs.du_emx + vertical_metric);
em = fpint2fp ((SL32) if_state.cs.du_emx);
fdx = fpint2fp((SL32)dx);
fdy = fpint2fp((SL32)dy);
fdx = fpdiv (fdx, em);
fdy = fpdiv (fdy, em);
}
adjx = fp2long( fpadd ( fpmul (fdx, if_state.m[0] ),
fpmul (fdy, if_state.m[2] ) ) );
adjy = fp2long( fpadd ( fpmul (fdx, if_state.m[1] ),
fpmul (fdy, if_state.m[3] ) ) );
if_state.cs.origin_cs.x = (adjx * 64);
if_state.cs.origin_cs.y = (adjy * 64);
return (ttrender ( FSA if_state.out_instance,if_state.pbucket,
if_state.cs.origin_cs.x, if_state.cs.origin_cs.y));
} /* ISOUTLINE && ISUFSTVERT && CharVertWrit */
/* default case */
return (ttrender ( FSA if_state.out_instance, if_state.pbucket,
-if_state.cs.origin_cs.x, -if_state.cs.origin_cs.y));
break;
#endif /* TT_RDR */
/* keb 12/99 end */
#if FCO_RDR
case FC_FCO_TYPE:
return (fco_render ( FSA if_state.out_instance,
if_state.pbucket, 0L, 0L));
break;
#endif
default:
return (ERR_fst_type);
}
}
else
{
#if IF_RDR
status = if_state.out.start_char ( FSA if_state.out_instance,
(PVOID)&if_state.cs );
if (status)
return status;
for(pn=0, cd=if_state.chr_def; pn<if_state.chr_def_hdr.num_parts; pn++, cd++)
{
status = make_char_part(FSA pn, cd);
if (status)
return status;
}
return if_state.out.end_char ( FSA if_state.out_instance );
#endif
}
return SUCCESS;
}
#endif /* OUTLINE || (NON_Z_WIND && (BOLD_P6 || BOLD_HORIZONTAL)) */
path.c 、、、、、、、、、、、、、、、、、、、、、、、、、、、
/*
* Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved.
*/
/* $Header: I:/BULL/URIP/RTS/DA/PATH.C_V 1.18 Aug 22 2003 08:53:40 LynchR $ */
/* $Log: I:/BULL/URIP/RTS/DA/PATH.C_V $
*
* Rev 1.18 Aug 22 2003 08:53:40 LynchR
* Updated copyright notice.
*
* Rev 1.17 Jul 03 2003 18:33:30 Galejs
* after all these years, you'd think I'd be able to copy a string on the first try...
*
* Rev 1.16 Jun 23 2003 16:25:52 Galejs
* fix compiler warning; ufstport.h
*
* Rev 1.15 03 Mar 2000 11:50:48 JOE
* Make PATH_DELIM '\\' and PATH_DELIM2 '\0' when _OSK is defined (by ks).
*
* Rev 1.14 Jan 28 2000 15:08:14 galejs
* test for DISK_FONTS rather than !ROM
*
* Rev 1.13 Aug 16 1999 12:04:50 galejs
* include-file changes
*
* Rev 1.12 20 Jan 1999 13:56:52 GALEJS
* ALPHA becomes UFST_ALPHA_UNIX
*
* Rev 1.11 02 Apr 1998 18:26:52 GALEJS
* ufst_path, type_path now in if_state
*
* Rev 1.10 20 Mar 1998 12:01:18 GALEJS
* 64-bit port
*
* Rev 1.9 03 Sep 1997 17:37:36 GALEJS
* paths are irrelevant if not DISK mode
*
* Rev 1.8 24 Oct 1996 15:24:28 PVCSADMN
* DBK Cleaned up annoying MIPS compiler warnings.
*
* Rev 1.7 07 Dec 1995 14:36:02 MERRILL
* wipe warnings
*
* Rev 1.6 27 Nov 1995 11:44:42 MIKE
* _OSK & _OS9000 support
*
* Rev 1.5 06 Apr 1995 15:14:42 LISA
* Changed copyright from Miles Inc. to Bayer Corp.
*
* Rev 1.4 22 Apr 1994 13:55:08 LISA
* Made modifications to copyright/disclaimer notice.
*
* Rev 1.3 12 Feb 1993 13:15:22 JOE
* VXWorks support.
*
* Rev 1.2 06 Jan 1993 14:59:28 JOE
* ANSI C function declaration changes.
*
* Rev 1.1 14 Dec 1992 15:57:46 LISA
* Made change to Log keyword
*
* Rev 1.0 09 Dec 1992 15:38:36 LISA
* Initial revision.
*/
/* $Date: Aug 22 2003 08:53:40 $ */
/* path.c */
/*
*
*
* HISTORY:
*
* 22-Jul-90 awr Initialized ufstPath = "" for multicaller.
* 23-Jul-90 awr Merged Blake's default typeface path code in
* 18-Aug-90 awr Correct buildpath() to not insert a "\" at the
* beginning if source1 is null.
* 4-Feb-91 awr Split off from ix.c
* 17-Jun-91 jfd Moved "debug.h" after "port.h".
* Moved "cgconfig.h" before "port.h".
* 03-Apr-92 rs Portability cleanup (see port.h).
* 20-May-92 jfd Changed buildpath() by adding a second delimiter
* (":" if LAMIGA) to prevent an invalid path from being
* returned.
* 1 Jul 92 ss Changed conditional on SUN to UNIX to be more general.
* Changed conditional order of PATH_DELIM to resolve
* problem on MIPS which is confused by #elif.
* (? Bug in the preprocessor? )
* 08-Jul-92 rs Code cleanup.
* 19-Nov-92 rs Port to Macintosh -> path delimiters ":".
* 06-Jan-93 jfd ANSI C function declaration changes.
* 08-Feb-93 jfd VXWorks support.
* 27-Nov-95 mby _OSK and _OS9000 support.
* 24-Oct-96 dbk Cleaned up annoying MIPS Compiler Warnings.
* 03-Sep-97 slg Paths are irrelevant if ROM (spacesaving)
* 11-Mar-98 slg Integrate Jim's Alpha-port change
* 02-Apr-98 slg Move GLOBALs ufst_path[], type_path[] into IF_STATE.
* 18-Jan-99 slg ALPHA case becomes UFST_ALPHA_UNIX.
* 01-Mar-00 ks Make PATH_DELIM '\\' and PATH_DELIM2 '\0' when _OSK
* is defined, for printronix.
*/
#include <stdio.h>
#include "cgconfig.h"
/* this file is only needed for disk-based code */
#if DISK_FONTS
#ifdef VXWORKS
#include "vxWorks.h"
#endif
#include "ufstport.h"
#include "dbg_ufst.h"
#include "shareinc.h"
#include "mixmodel.h"
/* UNIX-style paths */
#if defined (UFST_UNIX) || defined (UFST_ALPHA_UNIX) || defined (_OS9000) || defined(MIPS) /* 03-11-98 */
#define PATH_DELIM '/'
#define PATH_DELIM2 '\0'
/* DOS-style paths */
#else
#define PATH_DELIM '\\'
#define PATH_DELIM2 '\0'
#endif
/*------------------*/
/* buildpath */
/*------------------*/
/* Build the a full pathname in dest. Assume source2 is either a simple
* filename or already the full pathname. Use the presence of a "\" to
* determine. source1 if the default directory path.
* If source1 is null or source2 contains a slash, copy source2 to dest.
* Otherwise, concatinate source1 and source2 in dest making sure that
* there is a "\" between them.
*/
#if defined (ANSI_DEFS)
GLOBAL VOID buildpath(LPSB8 dest, LPSB8 source1, LPSB8 source2)
#else
GLOBAL VOID
buildpath(dest, source1, source2)
LPSB8 dest, source1, source2;
#endif
{
LPSB8 p, q;
/* See if source2 contains "\" */
q = source2;
while ((*q) && ((*q) != PATH_DELIM) && ((*q) != PATH_DELIM2) )
++q;
p = dest;
if(! *q) /* It doesn't, so assume source2 filename only */
{
if(*source1) /* copy default directory path */
{
while(*source1)
*p++ = *source1++;
--p; /* make sure a '\' seperates */
if(*p != PATH_DELIM && (*p != PATH_DELIM2) ) {
p++;
*p++ = PATH_DELIM;
}
else ++p;
}
}
while(*source2)
*p++ = *source2++;
*p = 0; /* null-terminated strings work better... */
}
#endif /* DISK_FONTS */