#include <kerneldc.h>
Inheritance diagram for KernelDC:
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 Filter * | GetParentFilter () |
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 |
Definition at line 143 of file kerneldc.h.
|
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).
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 }
|
|
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).
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 }
|
|
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 }
|
|
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 }
|
|
Convert a block of bytes to a hexadecimal ASCII stroing representation of the data.
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 }
|
|
|
|
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 }
|
|
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 }
|
|
Definition at line 162 of file kerneldc.h. 00162 { return Origin; }
|
|
Reimplemented in ExportDC. Definition at line 187 of file kerneldc.h. 00187 { return NULL; }
|
|
Output an Array to the EPS stream.
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 }
|
|
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).
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
Send bytes directly to the PostScript stream with no alteration or padding. Used for sending binary/hex data to stream.
Reimplemented in EPSExportDC, and PSPrintDC. Definition at line 1662 of file kerneldc.cpp.
|
|
Output a real (floating point) number to the EPS stream.
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 }
|
|
Output a Matrix to the EPS stream.
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 }
|
|
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.
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 }
|
|
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.
Reimplemented in EPSExportDC, and PSPrintDC. Definition at line 1599 of file kerneldc.cpp.
|
|
Outputs a sequence of bytes as raw hex data, as used by PostScript operators such as readhexstring.
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 }
|
|
Output a real (floating point) number to the EPS stream.
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
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.
Reimplemented in EPSExportDC, and PSPrintDC. Definition at line 1635 of file kerneldc.cpp.
|
|
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!).
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 }
|
|
Output an unsigned integer to the EPS stream.
Definition at line 650 of file kerneldc.cpp. 00651 { 00652 TCHAR buf[30]; 00653 camSprintf(buf, _T("%u"), Value); 00654 return OutputToken(buf); 00655 }
|
|
Output a signed integer to the EPS stream.
Definition at line 629 of file kerneldc.cpp. 00630 { 00631 TCHAR buf[30]; 00632 camSprintf(buf, _T("%d"), Value); 00633 return OutputToken(buf); 00634 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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.
Definition at line 1573 of file kerneldc.cpp. 01574 { 01575 FullAccuracy = Full; 01576 }
|
|
Set the user space origin to the specified position in spread coordinates.
Definition at line 193 of file kerneldc.cpp. 00194 { 00195 Origin = NewOrigin; 00196 }
|
|
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 }
|
|
Definition at line 214 of file kerneldc.h. |
|
Definition at line 208 of file kerneldc.h. |
|
Definition at line 202 of file kerneldc.h. |
|
Definition at line 205 of file kerneldc.h. |
|
Definition at line 214 of file kerneldc.h. |
|
Definition at line 215 of file kerneldc.h. |
|
Definition at line 216 of file kerneldc.h. |