00001 // $Id: ai8_eps.cpp 1314 2006-06-14 08:58:56Z builder1 $ 00002 // ai8_eps.cpp: implementation of the AI8EPSFilter class. 00003 // 00005 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00006 ================================XARAHEADERSTART=========================== 00007 00008 Xara LX, a vector drawing and manipulation program. 00009 Copyright (C) 1993-2006 Xara Group Ltd. 00010 Copyright on certain contributions may be held in joint with their 00011 respective authors. See AUTHORS file for details. 00012 00013 LICENSE TO USE AND MODIFY SOFTWARE 00014 ---------------------------------- 00015 00016 This file is part of Xara LX. 00017 00018 Xara LX is free software; you can redistribute it and/or modify it 00019 under the terms of the GNU General Public License version 2 as published 00020 by the Free Software Foundation. 00021 00022 Xara LX and its component source files are distributed in the hope 00023 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00024 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00025 See the GNU General Public License for more details. 00026 00027 You should have received a copy of the GNU General Public License along 00028 with Xara LX (see the file GPL in the root directory of the 00029 distribution); if not, write to the Free Software Foundation, Inc., 51 00030 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00031 00032 00033 ADDITIONAL RIGHTS 00034 ----------------- 00035 00036 Conditional upon your continuing compliance with the GNU General Public 00037 License described above, Xara Group Ltd grants to you certain additional 00038 rights. 00039 00040 The additional rights are to use, modify, and distribute the software 00041 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00042 library and any other such library that any version of Xara LX relased 00043 by Xara Group Ltd requires in order to compile and execute, including 00044 the static linking of that library to XaraLX. In the case of the 00045 "CDraw" library, you may satisfy obligation under the GNU General Public 00046 License to provide source code by providing a binary copy of the library 00047 concerned and a copy of the license accompanying it. 00048 00049 Nothing in this section restricts any of the rights you have under 00050 the GNU General Public License. 00051 00052 00053 SCOPE OF LICENSE 00054 ---------------- 00055 00056 This license applies to this program (XaraLX) and its constituent source 00057 files only, and does not necessarily apply to other Xara products which may 00058 in part share the same code base, and are subject to their own licensing 00059 terms. 00060 00061 This license does not apply to files in the wxXtra directory, which 00062 are built into a separate library, and are subject to the wxWindows 00063 license contained within that directory in the file "WXXTRA-LICENSE". 00064 00065 This license does not apply to the binary libraries (if any) within 00066 the "libs" directory, which are subject to a separate license contained 00067 within that directory in the file "LIBS-LICENSE". 00068 00069 00070 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00071 ---------------------------------------------- 00072 00073 Subject to the terms of the GNU Public License (see above), you are 00074 free to do whatever you like with your modifications. However, you may 00075 (at your option) wish contribute them to Xara's source tree. You can 00076 find details of how to do this at: 00077 http://www.xaraxtreme.org/developers/ 00078 00079 Prior to contributing your modifications, you will need to complete our 00080 contributor agreement. This can be found at: 00081 http://www.xaraxtreme.org/developers/contribute/ 00082 00083 Please note that Xara will not accept modifications which modify any of 00084 the text between the start and end of this header (marked 00085 XARAHEADERSTART and XARAHEADEREND). 00086 00087 00088 MARKS 00089 ----- 00090 00091 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00092 designs are registered or unregistered trademarks, design-marks, and/or 00093 service marks of Xara Group Ltd. All rights in these marks are reserved. 00094 00095 00096 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00097 http://www.xara.com/ 00098 00099 =================================XARAHEADEREND============================ 00100 */ 00101 00102 #include "camtypes.h" 00103 #include "ai8_eps.h" 00104 #include "ai_layer.h" 00105 00106 //#include "tim.h" 00107 //#include "filters.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00108 //#include "oilfltrs.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00109 00110 DECLARE_SOURCE("$Revision"); 00111 00112 00113 #define new CAM_DEBUG_NEW 00114 00115 00116 CC_IMPLEMENT_DYNAMIC(AI8EPSFilter, AI5EPSFilter) 00117 00118 00119 // Construction/Destruction 00121 00122 /******************************************************************************************** 00123 00124 > AI8EPSFilter::~AI8EPSFilter() 00125 00126 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00127 Created: 28/03/00 00128 00129 Purpose: Default constructor, which sets the class details. 00130 00131 ********************************************************************************************/ 00132 00133 AI8EPSFilter::AI8EPSFilter() 00134 { 00135 // Set up filter descriptions. 00136 FilterNameID = _R(IDT_AI8EPS_FILTERNAME); 00137 FilterInfoID = _R(IDT_AI8EPS_FILTERINFO); 00138 ImportMsgID = _R(IDT_IMPORTMSG_AI8); 00139 00140 FilterID = FILTERID_AI8EPS; 00141 00142 // This filter only supports import 00143 Flags.CanImport = TRUE; 00144 Flags.CanExport = FALSE; 00145 } 00146 00147 /******************************************************************************************** 00148 00149 > AI8EPSFilter::~AI8EPSFilter() 00150 00151 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00152 Created: 28/03/00 00153 00154 Purpose: Default destructor. Cleans up all instantiated data for the class. 00155 00156 ********************************************************************************************/ 00157 00158 AI8EPSFilter::~AI8EPSFilter() 00159 { 00160 // Currently, nothing needs to be done. 00161 } 00162 00163 /******************************************************************************************** 00164 00165 > BOOL AI8EPSFilter::Init() 00166 00167 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00168 Created: 28/03/00 00169 00170 Purpose: Since the constructor can't fail, it does things that the constructor can't 00171 do. 00172 00173 Returns: TRUE if the filter was initialised ok, FALSE otherwise. 00174 00175 ********************************************************************************************/ 00176 00177 BOOL AI8EPSFilter::Init() 00178 { 00179 // Get the OILFilter object 00180 pOILFilter = new AI8EPSOILFilter(this); 00181 if (pOILFilter == NULL) 00182 return FALSE; 00183 00184 // Load the description strings 00185 FilterName.Load(FilterNameID); 00186 FilterInfo.Load(FilterInfoID); 00187 00188 // All ok 00189 return TRUE; 00190 } 00191 00192 00195 // 00196 // Note: All import responsibility is delegated to the parent class 00197 // 00199 00200 /******************************************************************************************** 00201 00202 > virtual INT32 AI8EPSFilter::EPSHeaderIsOk(ADDR pFileHeader, UINT32 HeaderSize) 00203 00204 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00205 Created: 28/03/00 00206 00207 Purpose: Checks to see if the EPS comment headers specify that this is an AI 00208 generated EPS file, as required. 00209 00210 Returns: TRUE if the header is ok and import should proceed, FALSE if not. 00211 00212 The header for AI8.0 begins.... 00213 00214 %!PS-Adobe-3.0 00215 %%Creator: Adobe Illustrator(R) 8.0 00216 %%AI8_CreatorVersion: 8 00217 00218 ********************************************************************************************/ 00219 00220 INT32 AI8EPSFilter::EPSHeaderIsOk(ADDR pFileHeader, UINT32 HeaderSize) 00221 { 00222 UINT32 Lines = 0; 00223 TCHAR *Buffer = NULL; 00224 00225 // !PS-Adobe line is ok - check creator line... 00226 CCMemTextFile HeaderFile ( reinterpret_cast<char *> ( pFileHeader ), HeaderSize ); 00227 00228 if( HeaderFile.IsMemFileInited () == FALSE || HeaderFile.InitLexer () == FALSE ) 00229 { 00230 HeaderFile.close(); 00231 return 0; 00232 } 00233 00234 // Graeme (28/6/00) - Adobe have changed their file format, and so the first line can 00235 // now be a %PDF directive. Therefore look for this directive in the first twenty 00236 // lines. 00237 while ( ( Lines < 100 ) && !HeaderFile.eof () ) 00238 { 00239 // Get the current line from the file. 00240 HeaderFile.GetLineToken(); 00241 Buffer = const_cast<TCHAR *> ( HeaderFile.GetTokenBuf () ); 00242 00243 // Ensure that it's OK. 00244 ERROR2IF(Buffer == 0, 0, "Returned buffer from lex file == 0"); 00245 00246 // Increment the line counter. 00247 Lines++; 00248 00249 if (camStrncmp(Buffer, _T("%!PS-Adobe"), 10) == 0) 00250 { 00251 // Now find the %%Creator string. 00252 while ((Lines < 100) && !HeaderFile.eof()) 00253 { 00254 HeaderFile.GetLineToken(); 00255 Buffer = const_cast<TCHAR *> ( HeaderFile.GetTokenBuf() ); 00256 ERROR2IF(Buffer == 0, 0, "Returned buffer from lex file == 0"); 00257 Lines++; 00258 00259 // Return TRUE if this file was created by Illustrator, or has been exported in 00260 // Illustrator format. 00261 if (camStrncmp(Buffer, _T("%%Creator: Adobe Illustrator(R) 8"), 33) == 0) 00262 { 00263 // We definitely want this. 00264 HeaderFile.close(); 00265 return 10; 00266 } 00267 00268 // Check to see if it's from Illustrator 9. If you're writing a dedicated AI9 00269 // filter, then you really should remove this code. 00270 else if (camStrncmp(Buffer, _T("%%Creator: Adobe Illustrator(R) 9"), 33) == 0) 00271 { 00272 // We probably want this. Note: I'm returning 9 because a native AI9 00273 // filter would return 10, and if this code is left in, it will be 00274 // ignored. 00275 HeaderFile.close(); 00276 return 9; 00277 } 00278 00279 if (camStrncmp(Buffer, _T("%%Creator:"), 10) == 0) 00280 { 00281 // Found the creator line - does it contain the word Illustrator? 00282 if (camStrstr( (const TCHAR*)Buffer, _T("Illustrator(R) 8")) != NULL) 00283 { 00284 HeaderFile.close(); 00285 return 10; 00286 } 00287 00288 // Try to see if it's Illustrator 9. Again, remove this code when you're 00289 // writing a dedicated AI9 filter. 00290 else if (camStrstr( (const TCHAR*)Buffer, _T("Illustrator(R) 9")) != NULL) 00291 { 00292 HeaderFile.close(); 00293 return 9; 00294 } 00295 00296 // Not an AI file. 00297 else 00298 { 00299 break; 00300 } 00301 } 00302 00303 // If we find the compression token then stop the search as we don't want to 00304 // start looking in the compressed data! 00305 if (camStrncmp(Buffer, _T("%%Compression:"), 14)==0) 00306 break; 00307 } 00308 00309 // Remember to close the file before returning. 00310 HeaderFile.close(); 00311 00312 // Didn't find a suitable Creator line, but the EPS line was ok, so return 00313 // that we're interested, but not sure. 00314 return 5; 00315 } 00316 00317 // If we find the compression token then stop the search as we don't want to start 00318 // looking in the compressed data! 00319 if (camStrncmp(Buffer, _T("%%Compression:"), 14)==0) 00320 break; 00321 } 00322 00323 // Remember to close the file before returning. 00324 HeaderFile.close(); 00325 00326 // This file type isn't suitable. 00327 return 0; 00328 } 00329 00330 /******************************************************************************************** 00331 00332 > void AI8EPSFilter::LookUpToken() 00333 00334 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00335 Created: 28/03/00 00336 00337 Purpose: Compare the current token against the AI keywords to see if it is 00338 one of them. 00339 00340 Currently 8.0 checks only for its version of the layer operator which differs 00341 from previous versions. 00342 00343 ********************************************************************************************/ 00344 00345 void AI8EPSFilter::LookUpToken() 00346 { 00347 // Currently I do not have documentation for the AI 8 tokens, and so am passing the 00348 // token directly to the base class. 00349 AI5EPSFilter::LookUpToken(); 00350 } 00351 00352 /******************************************************************************************** 00353 00354 > BOOL AI5EPSFilter::ProcessToken() 00355 00356 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00357 Created: 28/03/00 00358 00359 Purpose: Checks if we're looking at the version 8.0 layer token otherwise delegates 00360 to the base class. 00361 00362 ********************************************************************************************/ 00363 00364 BOOL AI8EPSFilter::ProcessToken() 00365 { 00366 // Graeme (8/5/00) - The only AI8 token that we're handling at the moment is Lb, 00367 // which is a modified version of the AI5 Lb token. As such, all responsibility 00368 // for token processing is being passed to the base class. 00369 return AI5EPSFilter::ProcessToken(); 00370 } 00371 00372 /******************************************************************************************** 00373 00374 > BOOL AI8EPSFilter::DecodeLayer ( void ) 00375 00376 Author: Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com> 00377 Created: 8/5/00 00378 Inputs: - 00379 Returns: TRUE - The command was processed. 00380 FALSE - It wasn't used by this filter. 00381 Purpose: Inserts a layer into the tree. 00382 00383 ********************************************************************************************/ 00384 00385 BOOL AI8EPSFilter::DecodeLayer ( void ) 00386 { 00387 // If there's still an active layer, the LB token has been missed out, so throw an EPS 00388 // error message. 00389 if ( mpLayerProc != NULL ) 00390 { 00391 return FALSE; 00392 } 00393 00394 // Create the new layer processor. 00395 mpLayerProc = new AILayerProcessor; 00396 00397 ERROR2IF( mpLayerProc == NULL, FALSE, "Insufficient memory to create layer processor."); 00398 00399 // Insert the layer into the tree. 00400 return mpLayerProc->DecodeAI8Lb ( *this ); 00401 }