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]