KernelDC Class Reference

Provide a base device context for rendering to something other than the screen. This includes printers, files, and PostScript devices. More...

#include <kerneldc.h>

Inheritance diagram for KernelDC:

CCDummyDC CCDC ListItem CCObject SimpleCCObject ExportDC PSPrintDC CMXExportDC EPSExportDC FlashExportDC NativeExportDC List of all members.

Public Member Functions

 KernelDC (RenderType Type)
 Initialise a kernel DC. This initialises the user space origin to (0,0) by default (only relevant for DCs that use the PostScript stream functions).
 KernelDC (CNativeDC *pDC, RenderType Type)
 Initialise a kernel DC. This initialises the user space origin to (0,0) by default (only relevant for DCs that use the PostScript stream functions).
virtual BOOL OutputNewLine ()
 Causes a new line to be started in the EPS/PS output. This is used to give a pleasant appearance to the file - most EPS/PS commands (as opposed to operands) are followed by a new line.
virtual BOOL OutputToken (TCHAR *)
 Outputs a string token to the EPS/PS stream. This is the central routine through which the other high-level routines eventually come. The other routines convert their output to a string, which they then pass on to this routine. A record is kept of the current line width - if it is over 70 characters wide before the token is output, then a new line is output to keep the lines in the EPS file reasonably short. For this reason, it is important not to output strings that contain newline characters, because this routine will not notice, and hence the LineWidth count will be wrong. This routine also ensures that tokens are separated by either a space or a newline, so it is not necessary to output spaces directly to keep the tokens separate - it happens automatically.
virtual BOOL OutputDirect (BYTE *, INT32)
 Send bytes directly to the PostScript stream with no alteration or padding. Used for sending binary/hex data to stream.
virtual BOOL OutputTCHARAsChar (TCHAR *Buf, INT32 nBytes)
 Send bytes directly to the PostScript stream with no alteration or padding. Used for sending binary/hex data to stream. We send the BYTE equal to the TCHAR with no conversion.
void SetOrigin (DocCoord &)
 Set the user space origin to the specified position in spread coordinates.
DocCoord GetOrigin ()
virtual BOOL OutputCoord (DocCoord &, EPSAccuracy Accuracy=ACCURACY_NORMAL)
 Write out a coordinate x,y pair to the export file, automatically converting from spread coordinates to the EPS user space coordinate system, including adjusting the origin.
virtual BOOL OutputUserSpaceValue (MILLIPOINT, EPSAccuracy Accuracy=ACCURACY_NORMAL)
 Output a 'user space' value to the export file. User space is the coordinate system used for EPS files (and more generally, PostScript programs). For Illustrator-based EPS, the user space is expressed in units of points, and usually has the origin at (0.0). By default, we follow the Illustrator convention of truncating values to 2dp (so we can generate files compatible with Illustrator etc), but Camelot EPS uses the full 3dp accuracy (we don't store more any accuracy than this internally). The accuracy can be changed by calling KernelDC::SetFullAccuracy Note that this routine does not do origin translation, because it may be used for dimensions such as line widths, which have no earthly use for origins (and anyway, it's a bit tricky to do origin translation with only one dimension!).
BOOL OutputColour (PColourCMYK *)
 Output a colour, as expressed by the Camelot 'Colour' class. This function takes the CMYK variation, is this is most appropriate to EPS files. Camelot colour values are converted from the 0-255 range to the 0.0-1.0 range before being output.
BOOL OutputNamedColour (DocColour *, ColourContext *pContext=NULL)
 Similar to OutputColour(), except it outputs the colour name and tint of the colour as well. If pCol does not reference an indexed colour, then the name "NoName" is used.
BOOL OutputColourValue (UINT32 n)
 Output a colour value to the export file. A 'colour value' is a value as used in the Camelot 'Colour' class, i.e. in the range 0 to 255. This range is converted to the range 0.0 to 1.0, and output to the file.
BOOL OutputString (TCHAR *)
 Output a string in PostScript format, i.e. delimited by '(' and ')', and escaping any parentheses so the string is syntactically correct. e.g. "String" is output as "(String)", and "Hello (there)" is output as "(Hello \(there\))" and so on.
BOOL OutputValue (INT32)
 Output a signed integer to the EPS stream.
BOOL OutputValue (UINT32)
 Output an unsigned integer to the EPS stream.
BOOL OutputReal (double)
 Output a real (floating point) number to the EPS stream.
BOOL OutputFloat (const double Value, const UINT32 DecPl)
 Output a real (floating point) number to the EPS stream.
BOOL OutputMatrix (Matrix *M)
 Output a Matrix to the EPS stream.
BOOL OutputArray (INT32 *, INT32)
 Output an Array to the EPS stream.
BOOL OutputColourName (DocColour *pCol)
 Outputs a named colour's name as a string. If pCol does not reference an indexed colour, then the name "NoName" is used. This was seperated from OutputNamedColour so that the DeviceContext will not need to worry about which ColourModel to use (CMYK, RGB, etc...), as this will be determined by the RenderRegion.
virtual INT32 OutputRawBinary (BYTE *Data, UINT32 Length, UINT32 Alignment=1)
 Outputs a sequence of bytes as raw hex data, as used by PostScript operators such as readhexstring.
BOOL StartASCII85Output (BOOL RunLengthEncode=FALSE)
INT32 OutputASCII85 (BYTE *Data, UINT32 Length)
 Outputs a sequence of bytes as ASCII85 hex data, as used by PostScript Level 2. (This encoding should not be used when generating PostScript that must be compatible with Level 1 interpreters).
INT32 EndASCII85Output ()
void SetFullAccuracy (BOOL)
 Change the accuracy used when saving out user space values to the EPS file. This defaults to 2dp, but can be enabled to full accuracy (3dp) by passing in TRUE. We still do 2dp because that is what Illustrator and most of the other mediocre programs use and we don't want to generate files that might upset them. Camelot EPS uses the full 3dp accuracy though.
virtual FilterGetParentFilter ()

Protected Member Functions

void ConvertToHex (BYTE *Data, UINT32 Length, TCHAR *Buf)
 Convert a block of bytes to a hexadecimal ASCII stroing representation of the data.
BYTE * RunLengthEncode (BYTE *Data, INT32 *Length)
BYTE * RunLengthDecode (BYTE *Data, INT32 *Length)
BOOL QueueASCII85Data (BYTE *Data, UINT32 Length)
INT32 FlushASCII85Buffer ()
INT32 ConvertToASCII85 (BYTE *Src, UINT32 Length, BYTE *Dest)
INT32 ConvertFromASCII85 (BYTE *Src, UINT32 Length, BYTE *Dest)
void ConvertToPoints (MILLIPOINT, TCHAR *)

Protected Attributes

UINT32 LineWidth
DocCoord Origin
BOOL FullAccuracy
LPBYTE RawBuf
LPBYTE A85Buf
UINT32 RawBufSize
BOOL RLEtheASCII85Data

Detailed Description

Provide a base device context for rendering to something other than the screen. This includes printers, files, and PostScript devices.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/04/95
The main purpose of this class is to provide a repository for our bespoke PostScript procedures. This base class cannot use them as the centralised output routines are unimplemented and will error if called. Derived classes such as EPSExportDC and PrintPSDC will override these output functions, so the PostScript output routines can be used. This class provides basic primitives for writing out EPS/PS tokens such as commands, colours, and user space values (line-widths, co-ordinates etc). The DC takes care of handling formatting such as separating tokens with a space or newline, and limits line widths to a reasonable size.

See also:
EPSExportDC; ExportDC; PrintPSDC

Definition at line 143 of file kerneldc.h.


Constructor & Destructor Documentation

KernelDC::KernelDC RenderType  rType  ) 
 

Initialise a kernel DC. This initialises the user space origin to (0,0) by default (only relevant for DCs that use the PostScript stream functions).

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/04/95
Parameters:
The type of DC being made. [INPUTS]
See also:
KernelDC::SetOrigin; KernelDC::OutputUserSpaceValue; KernelDC::OutputCoord

Definition at line 132 of file kerneldc.cpp.

00132                                    : CCDummyDC(rType)
00133 {
00134     // Initialise other fields.
00135     LineWidth = 0;
00136     Origin.x = 0;
00137     Origin.y = 0;
00138 
00139     // Default to 2dp accuracy for user space values.
00140     FullAccuracy = FALSE;
00141 
00142     // No ASCII85 conversion by default.
00143     RawBuf = NULL;
00144     A85Buf = NULL;
00145     RawBufSize = 0;
00146     RLEtheASCII85Data = FALSE;
00147 }

KernelDC::KernelDC CNativeDC pDC,
RenderType  rType
 

Initialise a kernel DC. This initialises the user space origin to (0,0) by default (only relevant for DCs that use the PostScript stream functions).

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/04/95
Parameters:
The OIL DC pointer, and the type of DC being made. [INPUTS]
See also:
KernelDC::SetOrigin; KernelDC::OutputUserSpaceValue; KernelDC::OutputCoord

Definition at line 164 of file kerneldc.cpp.

00164                                                    : CCDummyDC(pDC, rType)
00165 {
00166     // Initialise other fields.
00167     LineWidth = 0;
00168     Origin.x = 0;
00169     Origin.y = 0;
00170 
00171     // Default to 2dp accuracy for user space values.
00172     FullAccuracy = FALSE;
00173 
00174     // No ASCII85 conversion by default.
00175     RawBuf = NULL;
00176     A85Buf = NULL;
00177     RawBufSize = 0;
00178     RLEtheASCII85Data = FALSE;
00179 }


Member Function Documentation

INT32 KernelDC::ConvertFromASCII85 BYTE *  Src,
UINT32  Length,
BYTE *  Dest
[protected]
 

Definition at line 1230 of file kerneldc.cpp.

01231 {
01232     // Precompute the powers of 85 to use when encoding.
01233     static const INT32 Power85[5] = { 1, 
01234                                      85, 
01235                                      85 * 85, 
01236                                      85 * 85 * 85, 
01237                                      85 * 85 * 85 * 85 };
01238 
01239     // Start at the beginning of the buffer
01240 //  INT32 SrcOfs = 0;
01241     INT32 DstOfs = 0;
01242     BOOL FoundEOD = FALSE;
01243 
01244     while ((Length > 0) && (!FoundEOD))
01245     {
01246         // Decode five characters into four bytes.
01247         UINT32 n = 0;
01248         UINT32 TupleLength = (Length >= 5) ? 5 : Length;
01249 
01250         // Look for the EOD marker
01251         for (UINT32 i = 0; i < 5; i++)
01252         {
01253             if ((Src[i] == '~') && ((i + 1) < Length) && (Src[i + 1] == '>'))
01254             {
01255                 // Found the EOD marker in the data
01256                 FoundEOD = TRUE;
01257 
01258                 // Shorten the tuple
01259                 TupleLength = i;
01260             }
01261         }
01262 
01263         if (Src[0] == 'z')
01264         {
01265             // Skip the 'z' character
01266             TupleLength = 1;
01267         }
01268         else
01269         {           
01270             // Decode base-85 numbers.
01271             for (UINT32 i = 0; i < 5; i++)
01272             {
01273                 if (i < TupleLength)
01274                     n += ((Src[i] - '!') * Power85[4 - i]);
01275                 else if (i == TupleLength)
01276                     // Round up fractional part
01277                     n += 0x80 << ((4 - i) * 8);
01278 
01279                 // 'z' is not allowed within a tuple
01280                 ERROR2IF(Src[i] == 'z', -1, "Illegal 'z' in ASCII85 stream");
01281             }
01282         }
01283 
01284         // Find out how many bytes we just decoded.
01285         UINT32 nBytesDecoded = TupleLength - 1;
01286 
01287         // Copy the decoded data into the buffer.
01288         UINT32 Shift = 24;
01289         while (nBytesDecoded > 0)
01290         {
01291             Dest[DstOfs++] = (BYTE) ((n >> Shift) & 0xFF);
01292             nBytesDecoded--;
01293             Shift -= 8;
01294         }
01295 
01296         // Move on to the next tuple.
01297         Src += TupleLength;
01298         Length -= TupleLength;
01299     }
01300 
01301     // Check the lengths match
01302     ERROR2IF(Length != 0, -1, "Incorrect length while decoding ASCII85 data");
01303     //ERROR2IF(!FoundEOD,   -1, "No EOD found while decoding ASCII85 data");
01304 
01305     // Finished encoding - terminate the string (not strictly necessary but what the hell).
01306     Dest[DstOfs] = 0;
01307 
01308     // Return how many bytes this decoded ASCII85 data takes up
01309     return DstOfs;
01310 }

INT32 KernelDC::ConvertToASCII85 BYTE *  Src,
UINT32  Length,
BYTE *  Dest
[protected]
 

Definition at line 1122 of file kerneldc.cpp.

01123 {
01124     // Precompute the powers of 85 to use when encoding.
01125 /*
01126     static const INT32 Power85[5] = { 1, 
01127                                      85, 
01128                                      85 * 85, 
01129                                      85 * 85 * 85, 
01130                                      85 * 85 * 85 * 85 };
01131 */
01132 
01133     // Start at the beginning of the buffer
01134 //  INT32 SrcOfs = 0;
01135     INT32 DstOfs = 0;
01136 
01137     while (Length > 0)
01138     {
01139         // Encode four bytes as five characters.
01140         UINT32 n=0;
01141         
01142         if (Length >= 4)
01143         {
01144             // Normal 4 bytes of data
01145             n = Src[0];
01146             n = (n << 8) | Src[1];
01147             n = (n << 8) | Src[2];
01148             n = (n << 8) | Src[3];
01149         }
01150         else
01151         {
01152             // Pad with zeros...
01153             switch (Length)
01154             {
01155                 case 3:
01156                     n = Src[0];
01157                     n = (n << 8) | Src[1];
01158                     n = (n << 8) | Src[2];
01159                     n <<= 8;
01160                     break;
01161 
01162                 case 2:
01163                     n = Src[0];
01164                     n = (n << 8) | Src[1];
01165                     n <<= 16;
01166                     break;
01167 
01168                 case 1:
01169                     n = Src[0];
01170                     n <<= 24;
01171                     break;
01172 
01173             }
01174         }
01175 
01176         if ((n == 0) && (Length >= 4))
01177         {
01178             // Special case - use "z" instead of "!!!!!"
01179             Dest[DstOfs++] = 'z';
01180         }
01181         else
01182         {
01183         #if 1
01184             register UINT32 q = n/7225;
01185             register unsigned r = (unsigned)n-7225*(unsigned)q;
01186             register unsigned t;
01187             Dest[DstOfs+3] = (t = r/85) + '!';
01188             Dest[DstOfs+4] = r - 85*t + '!';
01189             Dest[DstOfs+0] = (t = q/7225) + '!';
01190             r = (unsigned)q - 7225*t;
01191             Dest[DstOfs+1] = (t = r/85) + '!';
01192             Dest[DstOfs+2] = r - 85*t + '!';
01193 
01194             if (Length >= 4)
01195                 DstOfs += 5;
01196             else
01197                 // Special case for last 5-tuple - see Red Book, bottom of p129 
01198                 DstOfs += (Length + 1);
01199         #else
01200 /*
01201             for (INT32 i = 4; i >= 0; i--)
01202             {
01203                 // Reduce the number to a 5 digit base-85 number.
01204                 UINT32 m = n / Power85[i];
01205                 n -= m * Power85[i];
01206                 Dest[DstOfs++] = (TCHAR) (m + 33);
01207             }
01208 */
01209         #endif
01210         }
01211 
01212         // Move on to the next four bytes
01213         Src += 4;
01214         if (Length < 4)
01215             Length = 0;
01216         else
01217             Length -= 4;
01218     }
01219 
01220     // Finished encoding - terminate the string (not strictly necessary but what the hell).
01221     // (Jason here... What do you mean "What the hell?" - you've just written one byte off the
01222     // end of the buffer, and corrupted the heap! I've now added 4 bytes padding
01223     // on our buffers (in StartASCII85Output) to make sure this is safe)
01224     Dest[DstOfs] = 0;
01225 
01226     // Return how many bytes this ASCII85 data takes up
01227     return DstOfs;
01228 }

void KernelDC::ConvertToHex BYTE *  Data,
UINT32  Length,
TCHAR Buf
[protected]
 

Convert a block of bytes to a hexadecimal ASCII stroing representation of the data.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/08/94
Parameters:
Data - pointer to the data to convert [INPUTS] Length - the number of bytes to convert.
Buf - the buffer to place the hex string into. [OUTPUTS] NB. must be big enough to hold the 0-terminator!
See also:
KernelDC::OutputRawBinary

Definition at line 887 of file kerneldc.cpp.

00888 {   
00889     UINT32 DataOfs = 0, 
00890           DestOfs = 0;
00891 
00892     while (DataOfs < Length)
00893     {
00894         // Extract each 4-bit set and encode as hex
00895         INT32 Nybble = (Data[DataOfs] & 0xF0) >> 4;
00896         ENSURE(Nybble < 16, "Bad hex digit in KernelDC::ConvertToHex");
00897 
00898         TCHAR Ch;
00899         if (Nybble < 10)
00900             Ch = '0' + (TCHAR) Nybble;
00901         else
00902             Ch = 'A' + (TCHAR) (Nybble - 10);
00903 
00904         Buf[DestOfs++] = Ch;
00905 
00906         Nybble = Data[DataOfs] & 0xF;
00907         ENSURE(Nybble < 16, "Bad hex digit in KernelDC::ConvertToHex");
00908 
00909         if (Nybble < 10)
00910             Ch = '0' + (TCHAR) Nybble;
00911         else
00912             Ch = 'A' + (TCHAR) (Nybble - 10);
00913 
00914         Buf[DestOfs++] = Ch;
00915 
00916         // Do the next byte...
00917         DataOfs++;
00918     }
00919 
00920     // Terminate the string
00921     Buf[DestOfs] = 0;
00922 }

void KernelDC::ConvertToPoints MILLIPOINT  ,
TCHAR
[protected]
 

INT32 KernelDC::EndASCII85Output  ) 
 

Definition at line 958 of file kerneldc.cpp.

00959 {
00960     // Are we useing RLE compression?
00961     if (RLEtheASCII85Data)
00962     {
00963         // Ok - end of data, so we add the RLE EOD marker to the buffer (byte value 128)
00964         BYTE EOD[2];
00965         EOD[0] = (BYTE) 128;
00966         if (!QueueASCII85Data(EOD, 1))
00967             // An error occured
00968             return -1;
00969     }
00970 
00971     // Flush out the buffer, padding with zeroes if necessary.
00972     INT32 nBytes = FlushASCII85Buffer();
00973 
00974     // End of ASCII85 data, so output the ASCII85 EOD marker.
00975     TCHAR EOD[] = _T("~>");
00976     OutputTCHARAsChar(EOD, 2);
00977     OutputNewLine();
00978 
00979     // Free up the buffers
00980     CCFree(RawBuf);
00981     CCFree(A85Buf);
00982     RawBuf = NULL;
00983     A85Buf = NULL;
00984     RawBufSize = 0;
00985     RLEtheASCII85Data = FALSE;
00986 
00987     // Tell caller how many byts we saved
00988     return nBytes;
00989 }

INT32 KernelDC::FlushASCII85Buffer  )  [protected]
 

Definition at line 1312 of file kerneldc.cpp.

01313 {
01314     INT32 ConvertedLength = ConvertToASCII85(RawBuf, RawBufSize, A85Buf);
01315 
01316     #ifdef _DEBUG
01317 
01318         // Let's just check that it was encoded corrrectly.
01319         // (NOTE: I allocate 4 bytes more than necessary because ConvertFromASCII85 may
01320         // write an extra terminator byte past the end of the buffer memory)
01321         BYTE *Dest = (BYTE *) CCMalloc(RawBufSize + 4);
01322         if (Dest == NULL)
01323             // Error - no more memory
01324             return -1;
01325 
01326         INT32 nBytes = KernelDC::ConvertFromASCII85(A85Buf, ConvertedLength, Dest);
01327         ERROR2IF(nBytes < 0, -1, "Error in decoding ASCII85 data");
01328 
01329         // Length check
01330         if (nBytes != (INT32) RawBufSize)
01331             ERROR3("Length of decoded ASCII85 data does not match original! Output may be corrupt");
01332 
01333         // Binary comparison
01334         if (memcmp(RawBuf, Dest, RawBufSize) != 0)
01335             ERROR3("Decoded ASCII85 data does not match original! Output may be corrupt");
01336 
01337         // Clean up.
01338         CCFree(Dest);
01339 
01340     #endif
01341 
01342     RawBufSize = 0;
01343     if (!OutputDirect(A85Buf, ConvertedLength))
01344     {
01345         // Error
01346         return -1;
01347     }
01348 
01349     // All ok
01350     return ConvertedLength;
01351 }

DocCoord KernelDC::GetOrigin  )  [inline]
 

Definition at line 162 of file kerneldc.h.

00162 { return Origin; }

virtual Filter* KernelDC::GetParentFilter  )  [inline, virtual]
 

Reimplemented in ExportDC.

Definition at line 187 of file kerneldc.h.

00187 { return NULL; }

BOOL KernelDC::OutputArray INT32 *  Array,
INT32  ArraySize
 

Output an Array to the EPS stream.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/04/95
Parameters:
Array,pointer to the array data. [INPUTS] ArraySize, the number of elements in the array.
Returns:
TRUE if the data was written ok; FALSE if not => ERROR1

Errors: Disk/file error => ERROR1

Definition at line 762 of file kerneldc.cpp.

00763 {
00764     // Output the 'ArrayStart'
00765     if (!OutputToken(_T("[")))
00766         return FALSE;
00767 
00768     // Output the actual array elements
00769     for (INT32 el = 0; el < ArraySize; el++)
00770     {
00771         if(!OutputUserSpaceValue(Array[el]))
00772             return FALSE;
00773     }
00774 
00775     // Output the 'ArrayEnd'
00776     if (!OutputToken(_T("]")))
00777         return FALSE;
00778 
00779     return TRUE;
00780 }

INT32 KernelDC::OutputASCII85 BYTE *  Data,
UINT32  Length
 

Outputs a sequence of bytes as ASCII85 hex data, as used by PostScript Level 2. (This encoding should not be used when generating PostScript that must be compatible with Level 1 interpreters).

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/7/95
Parameters:
Data - pointer to the data to output. [INPUTS] Length - the number of bytes to output. RunLengthEncode - if TRUE then run length encode the data before encoding it to ASCII85 format (see Red Book for RLE spec).
Returns:
The number of bytes output to the file, in terms of the source data, not in terms of the number of ASCII characters used to represent them. -1 => error occured while writing => ERROR1

Errors: Disk/file error => ERROR1

Definition at line 1011 of file kerneldc.cpp.

01012 {
01013     // Sanity check
01014     ERROR2IF(RawBuf == NULL, FALSE, "ASCII85 output not initialised correctly!");
01015 
01016     // Run length encode the data first if required by the caller.
01017     BYTE *pRLLBuf = NULL;
01018 
01019     if (RLEtheASCII85Data)
01020     {
01021         // Encode this data using run length encoding.
01022         INT32 NewLength = Length;
01023         pRLLBuf = KernelDC::RunLengthEncode(Data, &NewLength);
01024         if (pRLLBuf == NULL)
01025             // Error encoding data
01026             return -1;
01027 
01028         #ifdef _DEBUG
01029 
01030             // Debug check - let's just decompress that data to make sure it was encoded ok!
01031             INT32 DecodedLength = NewLength;
01032             BYTE *Decoded = RunLengthDecode(pRLLBuf, &DecodedLength);
01033 
01034             // Check for data equality
01035             BOOL ValidEncoding = (DecodedLength == (INT32) Length);
01036 
01037             if (ValidEncoding)
01038                 // Perform byte-wise comparison of data
01039                 ValidEncoding = (memcmp(Data, Decoded, Length) == 0);
01040 
01041             // De-allocate the decoding buffer
01042             CCFree(Decoded);
01043 
01044             ERROR2IF(!ValidEncoding, -1, "Error in RunLengthEncoding integrity check!");
01045 
01046         #endif
01047 
01048         // Point ASCII85 routine to the RLL encoded data
01049         Data = pRLLBuf;
01050         Length = NewLength;
01051     }
01052 
01053 
01054     INT32 nBytes = -1;
01055 
01056     // Start this chunk on a new line.
01057     if (LineWidth > 0)
01058     {
01059         if (!OutputNewLine())
01060         {
01061             // Error encountered
01062             if (RLEtheASCII85Data)
01063                 CCFree(pRLLBuf);
01064             return -1;
01065         }
01066     }
01067 
01068     // Queue up the data (which may or may not be RLL encoded).
01069     if (QueueASCII85Data(Data, Length))
01070         // Data queued successfully.
01071         nBytes = Length;
01072 
01073     // Free up the buffer used for run length encoding.
01074     if (RLEtheASCII85Data)
01075         CCFree(pRLLBuf);
01076 
01077     // All done
01078     return nBytes;
01079 }

BOOL KernelDC::OutputColour PColourCMYK pCol  ) 
 

Output a colour, as expressed by the Camelot 'Colour' class. This function takes the CMYK variation, is this is most appropriate to EPS files. Camelot colour values are converted from the 0-255 range to the 0.0-1.0 range before being output.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/03/94
Parameters:
Col - the CMYK colour values to be output. [INPUTS]
Returns:
TRUE if the data was written ok; FALSE if not => ERROR1
e.g. MonoOn PColourCMYK Col = { 255, 255, 128, 0 }; pDC->OutputColour(&Col); MonoOff will give the following output: MonoOn 1.0 1.0 0.5 0.0 MonoOff
See also:
KernelDC::OutputColourValue
Returns:
Errors: Disk/file error => ERROR1

Definition at line 395 of file kerneldc.cpp.

00396 {
00397     // Output each of the colour values.
00398     BOOL Ok = (OutputColourValue(pCol->Cyan)    &&
00399                OutputColourValue(pCol->Magenta) &&
00400                OutputColourValue(pCol->Yellow)  &&
00401                OutputColourValue(pCol->Key));
00402 
00403     // Return success or failure.
00404     return Ok;
00405 }

BOOL KernelDC::OutputColourName DocColour pCol  ) 
 

Outputs a named colour's name as a string. If pCol does not reference an indexed colour, then the name "NoName" is used. This was seperated from OutputNamedColour so that the DeviceContext will not need to worry about which ColourModel to use (CMYK, RGB, etc...), as this will be determined by the RenderRegion.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/11/00
Parameters:
pCol - the colour to output. [INPUTS]
Returns:
TRUE if the data was written ok; FALSE if not => ERROR1
See also:
KernelDC::OutputNamedColour
Returns:
Errors: Disk/file error => ERROR1

Definition at line 491 of file kerneldc.cpp.

00492 {
00493     // Success / Failure flag for the export of this colour's name.
00494     BOOL ok = TRUE;
00495         
00496     // Get the indexed colour from the DocColour.
00497     IndexedColour *pIndCol = pCol->FindParentIndexedColour();
00498 
00499     if (pIndCol == NULL)
00500     {
00501         if (pCol->IsTransparent())
00502         {
00503             // This is a 'no colour' type colour, so output a zero-length colour name,
00504             // as this is the only way we can handle this at the moment.
00505             ok = OutputString(_T(""));
00506         }
00507         else
00508         {
00509             // Otherwise make up a colour name (see epsfiltr.h).
00510             ok = OutputString(ImmediateColourFudgeyBodgeName);
00511         }
00512     }
00513     else
00514     {
00515         // Got an indexed colour - output its name
00516         // (Pass in TRUE to get a unique-identifier for local colours rather than "Local colour")
00517         String_64 *ColName = pIndCol->GetName(TRUE);
00518         ok = OutputString((TCHAR *) (*ColName));
00519     }
00520 
00521     return ok;
00522 }

BOOL KernelDC::OutputColourValue UINT32  n  ) 
 

Output a colour value to the export file. A 'colour value' is a value as used in the Camelot 'Colour' class, i.e. in the range 0 to 255. This range is converted to the range 0.0 to 1.0, and output to the file.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/03/94
Parameters:
n - the colour value (range 0-255) to write to the EPS file. [INPUTS]
Returns:
TRUE if the data was written ok; FALSE if not => ERROR1
See also:
KernelDC::OutputColour
Returns:
Errors: Disk/file error => ERROR1

Definition at line 354 of file kerneldc.cpp.

00355 {
00356     // Convert to points, getting integer and fractional parts
00357     INT32 Integer  = n / 255;
00358     INT32 Fraction = ((n % 255) * 100) / 255;
00359 
00360     // Output to string
00361     TCHAR Buf[20];
00362     // Ensure we always get at least 2 decimal figures with %.2d
00363     camSprintf(Buf, _T("%d.%.2d"), Integer, Abs(Fraction));
00364     return OutputToken(Buf);
00365 }

BOOL KernelDC::OutputCoord DocCoord Coord,
EPSAccuracy  Accuracy = ACCURACY_NORMAL
[virtual]
 

Write out a coordinate x,y pair to the export file, automatically converting from spread coordinates to the EPS user space coordinate system, including adjusting the origin.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/03/94
Parameters:
Coord - the coordinate to write out to the file. [INPUTS] Accuracy - optional parameter - specifies how numbers should be output: ACCURACY_NORMAL: 2dp ACCURACY_ROUNDUP: 0dp, rounded up ACCURACY_ROUNDDOWN: 0dp, rounded down.
Returns:
TRUE if the data was written ok; FALSE if not => ERROR1
See also:
KernelDC::OutputUserSpaceValue
Returns:
Errors: File/disk error => ERROR1

Reimplemented in PSPrintDC.

Definition at line 219 of file kerneldc.cpp.

00220 {
00221     BOOL Ok = (OutputUserSpaceValue(Coord.x - Origin.x, Accuracy) &&
00222                OutputUserSpaceValue(Coord.y - Origin.y, Accuracy));
00223 
00224     return Ok;
00225 }

BOOL KernelDC::OutputDirect BYTE *  ,
INT32 
[virtual]
 

Send bytes directly to the PostScript stream with no alteration or padding. Used for sending binary/hex data to stream.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
04/23/95
Parameters:
Buf - the bytes to send to the stream. [INPUTS] nBytes - the number of bytes to send to the stream.
Returns:
FALSE (see Purpose)
NB. This base class version will always raise an ERROR2 and return FALSE because this function must be over-ridden in order to use the output functions.

See also:
KernelDC::OutputNewLine; KernelDC::OutputToken
Returns:
Errors: Always => ERROR2

Reimplemented in EPSExportDC, and PSPrintDC.

Definition at line 1662 of file kerneldc.cpp.

01663 {
01664     ERROR2(FALSE, "OutputDirect() called for base class KernelDC");
01665 }

BOOL KernelDC::OutputFloat const double  Value,
const UINT32  DecPl
 

Output a real (floating point) number to the EPS stream.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/04/95
Parameters:
Value - the number to write to the EPS stream. [INPUTS] DecPl - the number of decimal places to output. (1..8)
Returns:
TRUE if the data was written ok; FALSE if not => ERROR1

Errors: Disk/file error => ERROR1

Definition at line 700 of file kerneldc.cpp.

00701 {
00702     TCHAR buf[100];
00703     TCHAR *pch=buf;
00704     INT32 len=0, dp=-1;
00705 
00706     switch (DecPl)
00707     {
00708         case 1: camSprintf(buf,_T("%.1f"),Value); break;
00709         case 2: camSprintf(buf,_T("%.2f"),Value); break;
00710         case 4: camSprintf(buf,_T("%.4f"),Value); break;
00711         case 5: camSprintf(buf,_T("%.5f"),Value); break;
00712         case 6: camSprintf(buf,_T("%.6f"),Value); break;
00713         case 7: camSprintf(buf,_T("%.7f"),Value); break;
00714         case 8: camSprintf(buf,_T("%.8f"),Value); break;
00715         default:camSprintf(buf,_T("%.3f"),Value); break;
00716     }
00717 
00718     // supress a few trailing zero's
00719     while (*pch != '\0')
00720     {
00721         if (*pch=='.')
00722             dp=len;
00723         len++;
00724         pch++;
00725     }
00726 
00727     // check no decimal place
00728     if (dp==-1)
00729         return OutputToken(buf);
00730 
00731     pch--;
00732     while ((len>0) && (*pch=='0'))
00733     {
00734         pch--;
00735         len--;
00736     }
00737 
00738     if ((len==0) || (*pch=='.'))
00739         pch++;
00740 
00741     pch++;
00742     *pch='\0';
00743 
00744     return OutputToken(buf);
00745 }

BOOL KernelDC::OutputMatrix Matrix M  ) 
 

Output a Matrix to the EPS stream.

Author:
Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/08/94
Parameters:
M- pointer to the matrix to output to the EPS stream. [INPUTS]
Returns:
TRUE if the data was written ok; FALSE if not => ERROR1

Errors: Disk/file error => ERROR1

Definition at line 591 of file kerneldc.cpp.

00592 {
00593     FIXED16 abcd[4];
00594     INT32 ef[2];
00595     M->GetComponents(abcd, ef);
00596 
00597     if(!OutputReal(abcd[0].MakeDouble()))
00598         return FALSE;
00599     if(!OutputReal(abcd[1].MakeDouble()))
00600         return FALSE;
00601     if(!OutputReal(abcd[2].MakeDouble()))
00602         return FALSE;
00603     if(!OutputReal(abcd[3].MakeDouble()))
00604         return FALSE;
00605     if(!OutputUserSpaceValue(ef[0]))
00606         return FALSE;
00607     if(!OutputUserSpaceValue(ef[1]))
00608         return FALSE;
00609     return TRUE;
00610 
00611 
00612 }

BOOL KernelDC::OutputNamedColour DocColour pCol,
ColourContext pContext = NULL
 

Similar to OutputColour(), except it outputs the colour name and tint of the colour as well. If pCol does not reference an indexed colour, then the name "NoName" is used.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
09/08/94
Parameters:
pCol - the colour to output. [INPUTS] pContext - the context to use to convert the colour before output. if this is NULL the default CMYK context will be used.
Returns:
TRUE if the data was written ok; FALSE if not => ERROR1
See also:
KernelDC::OutputColour
Returns:
Errors: Disk/file error => ERROR1

Definition at line 426 of file kerneldc.cpp.

00427 {
00428     // Get CMYK version of this colour.
00429     PColourCMYK CMYK;
00430     pCol->GetCMYKValue(pContext, &CMYK);
00431 
00432     // Output CMYK version
00433     if (!OutputColour(&CMYK))
00434         return FALSE;
00435         
00436     // Get the indexed colour from the DocColour.
00437     IndexedColour *pIndCol = pCol->FindParentIndexedColour();
00438 
00439     // Cope with the unexpected!
00440 //  ENSURE(pIndCol != NULL, "Named colour has no index colour!");
00441 
00442     if (pIndCol == NULL)
00443     {
00444         if (pCol->IsTransparent())
00445         {
00446             // This is a 'no colour' type colour, so output a zero-length colour name,
00447             // as this is the only way we can handle this at the moment.
00448             if (!OutputString(_T("")))
00449                 return FALSE;
00450         }
00451         else
00452         {
00453             // Otherwise make up a colour name (see epsfiltr.h).
00454             if (!OutputString(ImmediateColourFudgeyBodgeName))
00455                 return FALSE;
00456         }
00457     }
00458     else
00459     {
00460         // Got an indexed colour - output its name
00461         // (Pass in TRUE to get a unique-identifier for local colours rather than "Local colour")
00462         String_64 *ColName = pIndCol->GetName(TRUE);
00463         if (!OutputString((TCHAR *) (*ColName)))
00464             return FALSE;
00465     }
00466 
00467     // Always tint 0
00468     return OutputToken(_T("0"));
00469 }

BOOL KernelDC::OutputNewLine  )  [virtual]
 

Causes a new line to be started in the EPS/PS output. This is used to give a pleasant appearance to the file - most EPS/PS commands (as opposed to operands) are followed by a new line.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/03/94
Returns:
FALSE (see Purpose)
NB. This base class version will always raise an ERROR2 and return FALSE because this function must be over-ridden in order to use the output functions.

See also:
KernelDC; KernelDC::OutputToken
Returns:
Errors: Always => ERROR2

Reimplemented in EPSExportDC, and PSPrintDC.

Definition at line 1599 of file kerneldc.cpp.

01600 {
01601     ERROR2(FALSE, "OutputNewLine() called for base class KernelDC");
01602 }

INT32 KernelDC::OutputRawBinary BYTE *  Data,
UINT32  Length,
UINT32  Alignment = 1
[virtual]
 

Outputs a sequence of bytes as raw hex data, as used by PostScript operators such as readhexstring.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/08/94
Parameters:
Data - pointer to the data to output. [INPUTS] Length - the number of bytes to output. Alignment - the byte alignment to use - it will pad the end of the data with 0 bytes if Length is not divisible by this parameter. Hence use 1 for no padding.
Returns:
The number of bytes output to the file, in terms of the source data, not in terms of the number of ASCII characters used to represent them. -1 => error occured while writing => ERROR1

Errors: Disk/file error => ERROR1

Reimplemented in NativeExportDC.

Definition at line 802 of file kerneldc.cpp.

00803 {
00804     INT32 nBytes = 0;
00805 
00806     // Do 30 bytes at a time so we get lines with 60 characters on each.
00807     if (LineWidth > 0)
00808     {
00809         if (!OutputNewLine())
00810             // Error encountered
00811             return -1;
00812     }
00813 
00814     // Work out the padding needed
00815     ENSURE(Alignment != 0, "Bad alignment in OutputRawBinary!");
00816     UINT32 Padding = Alignment - (Length % Alignment);
00817     if (Padding == Alignment)
00818         Padding = 0;
00819 
00820     while (Length > 0)
00821     {
00822         // Work out how much data to output
00823         UINT32 ChunkLength = 32;
00824         if (Length < ChunkLength)
00825             ChunkLength = Length;
00826 
00827         // Convert the next chunk to hex and write it out
00828         TCHAR HexBuf[80];
00829         ConvertToHex(Data, ChunkLength, HexBuf);
00830         if (!OutputTCHARAsChar(HexBuf, ChunkLength * 2))
00831         {
00832             // Error
00833             return -1;
00834         }
00835         
00836         nBytes += ChunkLength;
00837 
00838         // Adjust length and check for padding requirements
00839         Length -= ChunkLength;
00840         Data += ChunkLength;
00841 
00842         if ((Length == 0) && (Padding > 0))
00843         {
00844             // Put the string "00" into HexBuf
00845             HexBuf[0] = '0';
00846             HexBuf[1] = '0';
00847             HexBuf[2] = 0;
00848 
00849             // Output it however many times we need to
00850             while (Padding > 0)
00851             {
00852                 if (!OutputTCHARAsChar(HexBuf, 2))
00853                     // Error
00854                     return -1;
00855 
00856                 nBytes++;
00857                 Padding--;
00858             }
00859         }
00860 
00861         if (!OutputNewLine())
00862             // Error encountered
00863             return -1;
00864     }
00865     
00866     // All done
00867     return nBytes;
00868 }

BOOL KernelDC::OutputReal double  Value  ) 
 

Output a real (floating point) number to the EPS stream.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/11/94
Parameters:
Value - the number to write to the EPS stream. [INPUTS]
Returns:
TRUE if the data was written ok; FALSE if not => ERROR1

Errors: Disk/file error => ERROR1

Definition at line 672 of file kerneldc.cpp.

00673 {
00674     TCHAR buf[100]; // 100 should be enough for a floating point number!
00675     // Save floating point in scientific notation (because otherwise the number output
00676     // could be very long, e.g. 6.2e66 or similar would be very long if we didn't use
00677     // the exponent syntax).
00678     camSprintf(buf, _T("%g"), Value);
00679     return OutputToken(buf);
00680 }

BOOL KernelDC::OutputString TCHAR pString  ) 
 

Output a string in PostScript format, i.e. delimited by '(' and ')', and escaping any parentheses so the string is syntactically correct. e.g. "String" is output as "(String)", and "Hello (there)" is output as "(Hello \(there\))" and so on.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/08/94
Parameters:
pString - the string token to output. [INPUTS]
Returns:
TRUE if the data was written ok; FALSE if not => ERROR1
See also:
KernelDC
Returns:
Errors: Disk/file error => ERROR1

Definition at line 544 of file kerneldc.cpp.

00545 {
00546     TCHAR Buf[128];
00547 
00548     // Open string delimiter
00549     Buf[0] = '(';
00550 
00551     // Copy the string, looking for embedded delimiters.
00552     INT32 src = 0,
00553         dst = 1;
00554     while ( (pString[src]) && (dst < 120 ) )    //while ((pString[src] != 0) && (dst < 120))-adapted for DBCS
00555     {
00556         if( (pString[src]== _T('(')) || (pString[src]==_T(')')) || (pString[src]== _T('\\')) )
00557       //if( (pString[src] == '(')    || (pString[src] == ')')      || (pString[src] == '\\') )-adapted for DBCS
00558         {
00559             // escape this delimiter
00560             Buf[dst++] = '\\';
00561         }
00562 
00563         // Copy this character
00564         Buf[dst++] = pString[src++];
00565     }
00566 
00567     ERROR3IF(dst > 120, "String too long in KernelDC::OutputString");
00568 
00569     // Terminate the string token
00570     Buf[dst++] = ')';
00571     Buf[dst] = 0;
00572 
00573     // Output it
00574     return OutputToken(Buf);
00575 }

BOOL KernelDC::OutputTCHARAsChar TCHAR Buf,
INT32  nBytes
[virtual]
 

Send bytes directly to the PostScript stream with no alteration or padding. Used for sending binary/hex data to stream. We send the BYTE equal to the TCHAR with no conversion.

Author:
Alex Bligh
Date:
13/06/2006
Parameters:
Buf - the bytes to send to the stream. [INPUTS] nBytes - the number of bytes to send to the stream (i.e the number of TCHARs to read)
Returns:
TRUE if all the bytes were sent ok; FALSE if not.
See also:
KernelDC::OutputNewLine; KernelDC::OutputToken

Definition at line 1687 of file kerneldc.cpp.

01688 {
01689     if (sizeof(TCHAR) == sizeof(char))
01690         return OutputDirect((BYTE *)Buf, nBytes);
01691 
01692     BYTE * pByte=new BYTE[nBytes];
01693     if (!pByte)
01694         return FALSE;
01695 
01696     INT32 i;
01697     for (i=0; i<nBytes; i++)
01698         pByte[i]=Buf[i]; // 1:1 copy
01699 
01700     BOOL ok=OutputDirect(pByte, nBytes);
01701 
01702     delete (pByte);
01703     return ok;
01704 }

BOOL KernelDC::OutputToken TCHAR Str  )  [virtual]
 

Outputs a string token to the EPS/PS stream. This is the central routine through which the other high-level routines eventually come. The other routines convert their output to a string, which they then pass on to this routine. A record is kept of the current line width - if it is over 70 characters wide before the token is output, then a new line is output to keep the lines in the EPS file reasonably short. For this reason, it is important not to output strings that contain newline characters, because this routine will not notice, and hence the LineWidth count will be wrong. This routine also ensures that tokens are separated by either a space or a newline, so it is not necessary to output spaces directly to keep the tokens separate - it happens automatically.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/03/94
Parameters:
Str - the character string to write to the stream. [INPUTS]
Returns:
FALSE (see Purpose)
NB. This base class version will always raise an ERROR2 and return FALSE because this function must be over-ridden in order to use the output functions.

See also:
KernelDC; KernelDC::OutputNewLine; KernelDC::OutputDirect
Returns:
Errors: Always => ERROR2

Reimplemented in EPSExportDC, and PSPrintDC.

Definition at line 1635 of file kerneldc.cpp.

01636 {
01637     ERROR2(FALSE, "OutputToken() called for base class KernelDC");
01638 }

BOOL KernelDC::OutputUserSpaceValue MILLIPOINT  n,
EPSAccuracy  Accuracy = ACCURACY_NORMAL
[virtual]
 

Output a 'user space' value to the export file. User space is the coordinate system used for EPS files (and more generally, PostScript programs). For Illustrator-based EPS, the user space is expressed in units of points, and usually has the origin at (0.0). By default, we follow the Illustrator convention of truncating values to 2dp (so we can generate files compatible with Illustrator etc), but Camelot EPS uses the full 3dp accuracy (we don't store more any accuracy than this internally). The accuracy can be changed by calling KernelDC::SetFullAccuracy Note that this routine does not do origin translation, because it may be used for dimensions such as line widths, which have no earthly use for origins (and anyway, it's a bit tricky to do origin translation with only one dimension!).

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/03/94
Parameters:
n - the value (in millipoints) to output. [INPUTS] Accuracy - optional parameter - specifies how numbers should be output: ACCURACY_NORMAL: 2dp, or 3dp (see KernelDC::SetFullAccuracy) ACCURACY_ROUNDUP: 0dp, rounded up ACCURACY_ROUNDDOWN: 0dp, rounded down.
Returns:
TRUE if the data was written ok; FALSE if not => ERROR1
e.g. OutputUserSpaceValue(31465) will output "3.147" to the export file.

See also:
KernelDC::OutputCoord; KernelDC::OutputToken; KernelDC::SetFullAccuracy
Returns:
Errors: Disk/file error => ERROR1

Reimplemented in PSPrintDC.

Definition at line 265 of file kerneldc.cpp.

00266 {
00267     TCHAR Buf[20];
00268     INT32 Integer;
00269     INT32 Fraction;
00270 
00271     const TCHAR * negative=_T("-");
00272     const TCHAR * positive=_T("");
00273     const TCHAR * sign = positive;
00274 
00275     // Convert millipoint to EPS user space value in desired format.
00276     switch (Accuracy)
00277     {
00278         case ACCURACY_NORMAL:
00279             // Convert to points, getting integer and fractional parts
00280             // invert the sign if necessary
00281             if (n<0)
00282             {
00283                 sign=negative;
00284                 n=-n;
00285             }
00286 
00287             // as n is positive (or zero), this works in the way expected. Both
00288             // Integer and fraction are >=0 too.    
00289             Integer  = n / 1000;
00290             Fraction = n % 1000;
00291 
00292             // Output to string (accurate to 2/3dp)
00293 
00294             // If fraction is 0, just output integer value.
00295             if (Fraction == 0)
00296             {
00297                 camSprintf(Buf, _T("%d"), Integer);
00298             }
00299             else if (FullAccuracy)
00300             {
00301                 camSprintf(Buf, _T("%s%d.%.3d"), sign, Integer, Fraction);
00302             }
00303             else
00304             {
00305                 // Normal 2dp accuracy
00306                 Fraction=(Fraction+5)/10;
00307                 camSprintf(Buf, _T("%s%d.%.2d"), sign, Integer, Fraction);
00308             }
00309             break;
00310 
00311         case ACCURACY_ROUNDDOWN:
00312             // Convert to points, getting integer part.
00313             if (n < 0)
00314                 Integer = (n - 999)/ 1000;
00315             else
00316                 Integer = (n) / 1000;
00317 
00318             // Output to string (accurate to 0dp)
00319             camSprintf(Buf, _T("%d"), Integer);
00320             break;
00321 
00322         case ACCURACY_ROUNDUP:
00323             // Convert to points, getting integer part.
00324             if (n < 0)
00325                 Integer = (n) / 1000;
00326             else
00327                 Integer = (n + 999) / 1000;
00328 
00329             // Output to string (accurate to 0dp)
00330             camSprintf(Buf, _T("%d"), Integer);
00331             break;
00332     }
00333 
00334     return OutputToken(Buf);
00335 }

BOOL KernelDC::OutputValue UINT32  Value  ) 
 

Output an unsigned integer to the EPS stream.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/08/94
Parameters:
Value - the number to write to the EPS stream. [INPUTS]
Returns:
TRUE if the data was written ok; FALSE if not => ERROR1

Errors: Disk/file error => ERROR1

Definition at line 650 of file kerneldc.cpp.

00651 {
00652     TCHAR buf[30];
00653     camSprintf(buf, _T("%u"), Value);
00654     return OutputToken(buf);
00655 }

BOOL KernelDC::OutputValue INT32  Value  ) 
 

Output a signed integer to the EPS stream.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/08/94
Parameters:
Value - the number to write to the EPS stream. [INPUTS]
Returns:
TRUE if the data was written ok; FALSE if not => ERROR1

Errors: Disk/file error => ERROR1

Definition at line 629 of file kerneldc.cpp.

00630 {
00631     TCHAR buf[30];
00632     camSprintf(buf, _T("%d"), Value);
00633     return OutputToken(buf);
00634 }

BOOL KernelDC::QueueASCII85Data BYTE *  Data,
UINT32  Length
[protected]
 

Definition at line 1082 of file kerneldc.cpp.

01083 {
01084     INT32 MaxData = A85DataSize * 4;
01085 
01086     // Keep filling and flushing the buffer until we are out of data to send.
01087     INT32 nBytes = Length;
01088     while (nBytes > 0)
01089     {
01090         ERROR2IF((INT32) RawBufSize > MaxData, FALSE, "ASCII85 buffer overflow!");
01091 
01092         if ((INT32) RawBufSize == MaxData)
01093         {
01094             // Buffer is full - encode it and write it to disk.
01095             if (FlushASCII85Buffer() == -1)
01096                 return FALSE;
01097         }
01098 
01099         // Put as much data into the buffer as possible
01100         INT32 SpaceLeft = MaxData - RawBufSize;
01101         if (nBytes > SpaceLeft)
01102         {
01103             // Not enough room to put it all in, so fill up the buffer
01104             memcpy(RawBuf + RawBufSize, Data, SpaceLeft);
01105             RawBufSize += SpaceLeft;
01106             Data += SpaceLeft;
01107             nBytes -= SpaceLeft;
01108         }
01109         else
01110         {
01111             // Enough room in buffer to put all the data in, so do it.
01112             memcpy(RawBuf + RawBufSize, Data, nBytes);
01113             RawBufSize += nBytes;
01114             nBytes = 0;
01115         }
01116     }
01117 
01118     // All ok
01119     return TRUE;
01120 }

BYTE * KernelDC::RunLengthDecode BYTE *  Data,
INT32 *  Length
[protected]
 

Definition at line 1459 of file kerneldc.cpp.

01460 {
01461     // Ok, scan the data to see how large it will expand to.
01462     INT32 i = 0;
01463     INT32 Length = *pLength;
01464     INT32 Size = 0;
01465     BOOL FoundEOD = FALSE;
01466 
01467     while (i < Length)
01468     {
01469         if (Data[i] <= 127)
01470         {
01471             // Straight copying of data
01472             Size += (Data[i] + 1);
01473 
01474             // Skip past the data
01475             i += (Data[i] + 2);
01476         }
01477         else if (Data[i] > 128)
01478         {
01479             // Repeated data
01480             Size += (257 - Data[i]);
01481 
01482             // Skip past repeat count and byte to repeat.
01483             i += 2;
01484         }
01485         else
01486         {
01487             // 128 == End of stream
01488             FoundEOD = TRUE;
01489             break;
01490         }
01491     }
01492 
01493     // Got the size of data stream - allocate a buffer.
01494     if (Size == 0)
01495     {
01496         // Something not right here - cope with it gracefully
01497         *pLength = 0;
01498         return NULL;
01499     }
01500 
01501     // Allocate a buffer. Allocate 4 bytes extra just in case of slight buffer overruns
01502     BYTE *pRLLBuf = (BYTE *) CCMalloc(Size + 1 + 4);
01503     if (pRLLBuf == NULL)
01504     {
01505         // Error - no memory
01506         *pLength = 0;
01507         return NULL;
01508     }
01509 
01510     // Ok, actually decode it now.
01511     INT32 j = 0;
01512     i = 0;
01513     FoundEOD = FALSE;
01514 
01515     while (i < Length)
01516     {
01517         if (Data[i] <= 127)
01518         {
01519             // Straight copying of data
01520             memcpy(pRLLBuf + j, Data + i + 1, Data[i] + 1);
01521 
01522             // Skip past the data
01523             j += (Data[i] + 1);
01524             i += (Data[i] + 2);
01525         }
01526         else if (Data[i] > 128)
01527         {
01528             // Repeated data
01529             memset(pRLLBuf + j, Data[i + 1], 257 - Data[i]);
01530 
01531             // Skip past repeat count and byte to repeat.
01532             j += (257 - Data[i]);
01533             i += 2;
01534         }
01535         else
01536         {
01537             // 128 == End of stream
01538             FoundEOD = TRUE;
01539             break;
01540         }
01541     }
01542 
01543     // Sanity checks
01544     if (j!=Size)
01545     {
01546         *pLength=0;
01547         ERROR2(NULL, "Incorrect decoding of Run length data");
01548     }
01549 
01550     // Ok, we've decoded it.
01551     *pLength = j;
01552     return pRLLBuf;
01553 }

BYTE * KernelDC::RunLengthEncode BYTE *  Data,
INT32 *  Length
[protected]
 

Definition at line 1354 of file kerneldc.cpp.

01355 {
01356     // Run length encode the data first if required by the caller.
01357     BYTE *pRLLBuf = NULL;
01358 
01359     // Work out how much space we will need (i.e. work out the worst case overhead for
01360     // run length encoding).
01361     // This is based on no repetition at all, i.e. no opportunity for compression.
01362     // This results in a one byte overhead per 128 bytes.
01363 
01364     INT32 Length = *pLength;
01365     INT32 Overhead = (Length / 128) + 10;  // Add 10 for good measure!  No GPFs here...
01366 
01367     // Get a buffer to convert the data in. Allocate 4 byes extra just to be safe
01368     INT32 RLLSize = Length + Overhead;
01369     pRLLBuf = (LPBYTE) CCMalloc(RLLSize + 4);
01370     if (pRLLBuf == NULL)
01371         // Error;
01372         return NULL;
01373 
01374     // Ok - we've got the buffer, so encode the data.
01375     // We don't bother to RLL unless we get a gain, i.e. 3 or more repeating characters.
01376     // (2 repeating bytes gives the same space usage, and can interrupt the stream so
01377     // actually uses more space).
01378     INT32 SeqLength = 0;
01379     INT32 DestOfs = 0;
01380     INT32 SrcOfs = 0;
01381     INT32 Ofs = 0;
01382     INT32 Len = Length;
01383 
01384     while (Len > 0)
01385     {
01386         // Check for limit on sequence length.
01387         ERROR2IF(SeqLength > 128, NULL, "Sequence too long in RLE encoding!");
01388 
01389         if (SeqLength == 128)
01390         {
01391             // Got a full sequence - copy it to the destination buffer.
01392             ERROR2IF(DestOfs + SeqLength >= RLLSize, NULL, "RLE buffer over-run!");
01393             pRLLBuf[DestOfs++] = SeqLength - 1;
01394             memcpy(pRLLBuf + DestOfs, Data + SrcOfs, SeqLength);
01395             DestOfs += SeqLength;
01396             SrcOfs += SeqLength;
01397             SeqLength = 0;
01398         }
01399 
01400         // Look for repeating characters
01401         if ((Len > 2) && (Data[Ofs] == Data[Ofs + 1]) && (Data[Ofs] == Data[Ofs + 2]))
01402         {
01403             // Ooh - found 3 repeating characters - see if there are any more.
01404 
01405             // First flush out any previous bytes.
01406             if (SeqLength > 0)
01407             {
01408                 ERROR2IF(DestOfs + SeqLength >= RLLSize, NULL, "RLE buffer over-run!");
01409                 pRLLBuf[DestOfs++] = SeqLength - 1;
01410                 memcpy(pRLLBuf + DestOfs, Data + SrcOfs, SeqLength);
01411                 DestOfs += SeqLength;
01412             }
01413 
01414             // Sequence starts at this character.
01415             SrcOfs = Ofs;
01416             SeqLength = 0;
01417 
01418             while ((Len > 0) && (SeqLength < 128) && (Data[Ofs] == Data[SrcOfs]))
01419             {
01420                 // Try next character
01421                 Len--;
01422                 Ofs++;
01423                 SeqLength++;
01424             }
01425 
01426             // End of sequence of repeating characters - place it into buffer.
01427             ERROR2IF(DestOfs + 2 > RLLSize, NULL, "RLE buffer over-run!");
01428             pRLLBuf[DestOfs++] = 257 - SeqLength;
01429             pRLLBuf[DestOfs++] = Data[SrcOfs];
01430 
01431             // Move to next character
01432             //Ofs++;
01433             SeqLength = 0;
01434             SrcOfs = Ofs;
01435         }
01436         else
01437         {
01438             // Add this character to the current sequence.
01439             Len--;
01440             Ofs++;
01441             SeqLength++;
01442         }
01443     }
01444 
01445     // Flush remaining sequence, if there is one.
01446     if (SeqLength > 0)
01447     {
01448         ERROR2IF(DestOfs + SeqLength >= RLLSize, NULL, "RLE buffer over-run!");
01449         pRLLBuf[DestOfs++] = SeqLength - 1;
01450         memcpy(pRLLBuf + DestOfs, Data + SrcOfs, SeqLength);
01451         DestOfs += SeqLength;
01452     }
01453 
01454     // Return the pointer to the RLL encoded data, and tell caller how long the data is.
01455     *pLength = DestOfs;
01456     return pRLLBuf;
01457 }

void KernelDC::SetFullAccuracy BOOL  Full  ) 
 

Change the accuracy used when saving out user space values to the EPS file. This defaults to 2dp, but can be enabled to full accuracy (3dp) by passing in TRUE. We still do 2dp because that is what Illustrator and most of the other mediocre programs use and we don't want to generate files that might upset them. Camelot EPS uses the full 3dp accuracy though.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/11/94
Parameters:
Full,: TRUE => Use 3dp when saving user space values [INPUTS] FALSE => Use 2dp when saving user space values

Definition at line 1573 of file kerneldc.cpp.

01574 {
01575     FullAccuracy = Full;
01576 }

void KernelDC::SetOrigin DocCoord NewOrigin  ) 
 

Set the user space origin to the specified position in spread coordinates.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/03/94
Parameters:
NewOrigin - the desired origin (in spread coords) [INPUTS]
See also:
KernelDC::OutputUserSpaceValue; KernelDC::OutputCoord

Definition at line 193 of file kerneldc.cpp.

00194 {
00195     Origin = NewOrigin;
00196 }

BOOL KernelDC::StartASCII85Output BOOL  RunLengthEncode = FALSE  ) 
 

Definition at line 928 of file kerneldc.cpp.

00929 {
00930     // Sanity check
00931     ERROR2IF(A85Buf != NULL, FALSE, "Unfinished ASCII85 output!");
00932 
00933     // Remember whether or not we need to RLE the data.
00934     RLEtheASCII85Data = RunLengthEncode;
00935 
00936     // Allocate buffers
00937     // (Jason here - NOTE that I add a 4 byte padding to the end of both buffers in case
00938     // of small overflow. Otherwise, the ConvertToASCII85 routine fills the buffer to the
00939     // brim and then slaps a 0 terminator on the end, corrupting the heap)
00940     RawBuf = (LPBYTE) CCMalloc((A85DataSize * 4) + 4);
00941     if (RawBuf == NULL)
00942         return(FALSE);
00943     
00944     A85Buf = (LPBYTE) CCMalloc((A85DataSize * 5) + 4);
00945     if (A85Buf == NULL)
00946     { 
00947         CCFree(RawBuf);
00948         return(FALSE);
00949     }
00950 
00951     // No characters in buffer yet.
00952     RawBufSize = 0;
00953 
00954     // Ok
00955     return TRUE;
00956 }


Member Data Documentation

LPBYTE KernelDC::A85Buf [protected]
 

Definition at line 214 of file kerneldc.h.

BOOL KernelDC::FullAccuracy [protected]
 

Definition at line 208 of file kerneldc.h.

UINT32 KernelDC::LineWidth [protected]
 

Definition at line 202 of file kerneldc.h.

DocCoord KernelDC::Origin [protected]
 

Definition at line 205 of file kerneldc.h.

LPBYTE KernelDC::RawBuf [protected]
 

Definition at line 214 of file kerneldc.h.

UINT32 KernelDC::RawBufSize [protected]
 

Definition at line 215 of file kerneldc.h.

BOOL KernelDC::RLEtheASCII85Data [protected]
 

Definition at line 216 of file kerneldc.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:55:41 2007 for Camelot by  doxygen 1.4.4