nativeps.cpp

Go to the documentation of this file.
00001 // $Id: nativeps.cpp 1668 2006-08-04 11:45:17Z alex $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 // The Native file format for Camelot first version.
00099 
00100 /*
00101 */
00102 
00103 #include "camtypes.h"
00104 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00105 #include "nativeps.h"
00106 //#include "filtrres.h"
00107 //#include "rik.h"
00108 //#include "tim.h"
00109 //#include "oilfltrs.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00110 #include "cversion.h"
00111 #include "progress.h"
00112 //#include "bitmap.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00113 #include "bmpcomp.h"
00114 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00115 //#include "fillval.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00116 #include "opgrad.h"
00117 #include "nodetext.h"
00118 //#include "nev.h"
00119 #include "zstream.h"    // zipping stream class
00120 #include <sstream>
00121 #include "fontman.h"
00122 #include "expbmp.h"
00123 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00124 //#include "colormgr.h" // for ColourManager (see NativeRenderRegion::OutputGradFillColours)
00125 
00126 // An implement to match the Declare in the .h file.
00127 CC_IMPLEMENT_DYNAMIC(CamelotNativeEPSFilter, CamelotEPSFilter);
00128 #if !defined(EXCLUDE_FROM_RALPH)
00129 CC_IMPLEMENT_DYNAMIC(NativeRenderRegion, CamelotEPSRenderRegion);
00130 #endif
00131 
00132 // This will get Camelot to display the filename and linenumber of any memory allocations
00133 // that are not released at program exit
00134 #define new CAM_DEBUG_NEW
00135 
00136 typedef enum
00137 {
00138     TRANSPFILL_NONE,
00139     TRANSPFILL_FLAT,
00140     TRANSPFILL_LINEAR,
00141     TRANSPFILL_CIRCULAR,
00142     TRANSPFILL_ELLIPTICAL,
00143     TRANSPFILL_CONICAL,
00144     TRANSPFILL_TEXTURE,
00145     TRANSPFILL_FRACTAL,
00146     TRANSPFILL_NEWLINEAR,
00147     TRANSPFILL_NEWTEXTURE,
00148     TRANSPFILL_NEWFRACTAL
00149 } TranspFillGeometryType;
00150 
00151 
00152 // This is the array of Camelot EPS command/keyword names.
00153 CommandMap CamelotNativeEPSFilter::NativeCommands[] =
00154 {
00155     // Bitmap Pool Tokens
00156     { EPSC_cbmp,    _T("cbmp") },
00157 
00158     // Sentinel
00159     { EPSC_Invalid, _T("Invalid") }
00160 };
00161 
00162 
00163 
00164 
00165 // The native file version numbers and some comments about what they can cope with
00166 typedef enum
00167 {
00168     // First version number
00169     // Created: 29/5/95
00170     // Copes with:
00171     // - File compression
00172     // Does not cope with:  
00173     FIRSTVERSION = 100
00174     
00175 } NativeFileVersion;    
00176 
00177 // Define what the current read and write versions are
00178 const NativeFileVersion     ReadNativeVersion100        = FIRSTVERSION;
00179 const NativeFileVersion     WriteNativeVersion100       = FIRSTVERSION;
00180 const double    ReadNativeVersion       = (ReadNativeVersion100/100);
00181 const double    WriteNativeVersion      = (WriteNativeVersion100/100);
00182 
00183 
00184 /********************************************************************************************
00185 
00186     Preference:     CompressNative
00187     Section:        Filters
00188     Range:          0 to 1
00189     Purpose:        Flag for whether we compress the native files saved from Xara Studio.
00190                     True means do compress the files.
00191     SeeAlso:        -
00192 
00193 ********************************************************************************************/
00194 
00195 BOOL CamelotNativeEPSFilter::CompressNative = TRUE;
00196 
00197 
00198 /********************************************************************************************
00199 
00200 >   CamelotNativeEPSFilter::CamelotNativeEPSFilter()
00201 
00202     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
00203     Created:    15/12/94
00204     Purpose:    Constructor for the Native save/load filter.
00205 
00206 ********************************************************************************************/
00207 
00208 CamelotNativeEPSFilter::CamelotNativeEPSFilter()
00209 {
00210     // Set up filter descriptions.
00211     FilterNameID = _R(IDS_NATIVE_EPS_FILTERNAME);
00212     FilterInfoID = _R(IDS_NATIVE_EPS_FILTERINFO);
00213     ImportMsgID  = _R(IDS_IMPORTMSG_NATIVE_EPS);
00214     ExportMsgID  = _R(IDS_EXPORTMSG_NATIVE_EPS);
00215 
00216     FilterID = FILTERID_NATIVE_EPS;
00217 
00218 #ifndef STANDALONE
00219     Flags.CanImport = TRUE;
00220     //WEBSTER-Martin-27/01/97
00221 #ifdef WEBSTER
00222     Flags.CanExport = FALSE;
00223 #else
00224     Flags.CanExport = FALSE;
00225 #endif //WEBSTER
00226 #else
00227     Flags.CanImport = TRUE;
00228     Flags.CanExport = FALSE;
00229 #endif
00230 
00231     // We don't want to re-position Camelot files because they should be ok and
00232     // Charles gets upset if his drawings move.
00233     AdjustOrigin = FALSE;
00234 
00235     // Prepare the bitmap pool data
00236     IsSavingBitmapPool = FALSE;
00237     BitmapCount = 0;
00238     BitmapPoolRefs = NULL;
00239     PendingBitmapNum = 0;
00240 
00241     // A flag to store the Value of the ImportWithLayers flag in
00242     OldImportWithLayers = TRUE;
00243     OldOpenWithLayers = TRUE;
00244 
00245     // Items to handle the file compression
00246     CompressionType = 0;    // type of compression in use (0 at present)
00247     CompressionOn = FALSE;  // on/off flag
00248 
00249     FileVersionNumber = 0.0;
00250     BuildVersionNumber = 0.0;
00251 }
00252 
00253 
00254 
00255 
00256 /********************************************************************************************
00257 
00258 >   CamelotNativeEPSFilter::~CamelotNativeEPSFilter()
00259 
00260     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
00261     Created:    20/1/95
00262     Purpose:    Tidies up when the filter is destroyed. Mostly takes care of the bitmap pool
00263                 references that may have been built during the import.
00264 
00265 ********************************************************************************************/
00266 
00267 CamelotNativeEPSFilter::~CamelotNativeEPSFilter()
00268 {
00269     // Get rid of the bitmap references if we have any
00270     if (BitmapPoolRefs != NULL)
00271         delete [] BitmapPoolRefs;
00272 }
00273 
00274 
00275 
00276 
00277 /********************************************************************************************
00278 
00279 >   BOOL CamelotNativeEPSFilter::Init()
00280 
00281     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
00282     Created:    15/12/94
00283     Returns:    TRUE if it worked, FALSE if it failed
00284     Purpose:    Initalises the Filter ready for use. Will fail if it can not get enough
00285                 memory to work with.
00286 
00287 ********************************************************************************************/
00288 
00289 BOOL CamelotNativeEPSFilter::Init()
00290 {
00291     // Get the OILFilter object
00292     pOILFilter = new NativeEPSOILFilter(this);
00293     if (pOILFilter == NULL)
00294         return FALSE;
00295 
00296     // Load the description strings
00297     FilterName.Load(FilterNameID);
00298     FilterInfo.Load(FilterInfoID);
00299 
00300     // Preference to turn native file compression on or off
00301     if (Camelot.DeclareSection(_T("Filters"), 10))
00302     {
00303         Camelot.DeclarePref( NULL, _T("CompressNative"), &CompressNative, 0, 1 );
00304     }
00305 
00306     // All ok
00307     return TRUE;
00308 }
00309 
00310 /********************************************************************************************
00311 
00312 >   static BOOL CamelotNativeEPSFilter::SetNativeCompression(BOOL NewState)
00313 
00314     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00315     Created:    27/5/95
00316     Inputs:     New state for native file compression, TRUE if want on, FALSE if want off.
00317     Returns:    The old state of the compression.
00318     Purpose:    Set the prefernece as to whether we are to compress the native files or not.
00319 
00320 ********************************************************************************************/
00321 
00322 BOOL CamelotNativeEPSFilter::SetNativeCompression(BOOL NewState)
00323 {
00324 //  BOOL OldState = CompressNative;
00325     CompressNative = NewState;
00326     return CompressNative;
00327 }
00328 
00329 
00330 /********************************************************************************************
00331 
00332 >   static BOOL CamelotNativeEPSFilter::GetNativeCompression(BOOL NewState)
00333 
00334     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00335     Created:    27/5/95
00336     Inputs:     New state for native file compression, TRUE if want on, FALSE if want off.
00337     Returns:    The old state of the compression.
00338     Purpose:    Set the prefernece as to whether we are to compress the native files or not.
00339 
00340 ********************************************************************************************/
00341 
00342 BOOL CamelotNativeEPSFilter::GetNativeCompression()
00343 {
00344     return CompressNative;
00345 }   
00346 
00347 /********************************************************************************************
00348 
00349 >   virtual BOOL CamelotNativeEPSFilter::SetFileCompressionState(BOOL NewState)
00350 
00351     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00352     Created:    19/5/95
00353     Inputs:     New state for file compression, TRUE if want on, FALSE if want off.
00354     Returns:    True if succesful or False if not.
00355     Purpose:    Set a new file compression status into action.
00356 
00357 ********************************************************************************************/
00358 
00359 BOOL CamelotNativeEPSFilter::SetFileCompressionState(BOOL NewState)
00360 {
00361     TRACEUSER( "Neville", _T("CamelotNativeEPSFilter::SetFileCompressionState new state= %d\n"),NewState);
00362 
00363     CompressionOn = NewState;
00364 
00365     return TRUE;
00366 }
00367 
00368 /********************************************************************************************
00369 
00370 >   virtual BOOL CamelotNativeEPSFilter::GetFileCompressionState()
00371 
00372     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00373     Created:    19/5/95
00374     Returns:    The current state of the file compression.
00375     Purpose:    Get the current file compression state. True if compressing.
00376 
00377 ********************************************************************************************/
00378 
00379 BOOL CamelotNativeEPSFilter::GetFileCompressionState()
00380 {
00381     return CompressionOn;
00382 }
00383 
00384 
00385 /********************************************************************************************
00386 
00387 >   virtual void CamelotNativeEPSFilter::LookUpToken()
00388 
00389     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
00390     Created:    6/1/95
00391     Purpose:    Look up one of the tokens used by the Camelot Native EPS file format.
00392 
00393 ********************************************************************************************/
00394 
00395 void CamelotNativeEPSFilter::LookUpToken()
00396 {
00397     // Not interested in comments
00398     if (Token == EPSC_Comment)
00399         return;
00400 
00401     // Check to see if it is a keyword - cycle through the array of keyword names and
00402     // compare against our token (could use a hash table?)
00403     INT32 i = 0;
00404     while (NativeCommands[i].Cmd != EPSC_Invalid)
00405     {
00406         if (camStrcmp(TokenBuf, NativeCommands[i].CmdStr) == 0)
00407         {
00408             // Found the token - set the token variable and return success
00409             Token = NativeCommands[i].Cmd;
00410             return;
00411         }
00412         
00413         // Try next command
00414         i++;
00415     }
00416 
00417     // Did not find this token - pass on to base class.
00418     CamelotEPSFilter::LookUpToken();
00419 }
00420 
00421 
00422 /********************************************************************************************
00423 
00424 >   virtual BOOL CamelotNativeEPSFilter::ProcessToken()
00425 
00426     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
00427     Created:    6/1/95
00428     Returns:    TRUE if it was able to process the token, FALSE if not.
00429     Purpose:    Deals with the current token. This function deals with tokens that are specific
00430                 to the Camelot Native EPS format, or different from Camelot EPS.
00431 
00432 ********************************************************************************************/
00433 
00434 BOOL CamelotNativeEPSFilter::ProcessToken()
00435 {
00436     ArrowRec    Arrow;
00437     double      ArrowWidth;
00438     double      ArrowHeight;
00439     INT32       ArrowID;
00440 
00441     DashRec     Dash;
00442     INT32       DashID;
00443     DashPatternAttribute* pDash;
00444 
00445     // Decode the command, and execute it...
00446     switch (Token)
00447     {
00448         // Bitmap Pool Token
00449         case EPSC_cbmp:
00450         {
00451             INT32 PoolType;
00452 
00453             // Find out what type of bitmap pool thing this is (currently 0 is only valid option)
00454             if ((!Stack.Pop(&PoolType)) || (PoolType!=0))
00455                 goto EPSError;
00456 
00457             // get the bitmap number
00458             if (!Stack.Pop(&PendingBitmapNum))
00459                 goto EPSError;
00460 
00461             // Next thing will be a pool item
00462             TRACEUSER( "Rik", _T("Got a Bitmap pool item....\n"));
00463             m_PendingBitmap = PENDING_BITMAP_POOLITEM;
00464             break;
00465         }
00466 
00467         // Stroke transparency
00468         case EPSC_cst:
00469             INT32 TranspType, Transp;
00470 
00471             // Get transparency type...
00472             if (!Stack.Pop(&TranspType))
00473                 goto EPSError;
00474 
00475             // Get line transparency value
00476             if (!Stack.Pop(&Transp))
00477                 goto EPSError;
00478 
00479             TRACEUSER( "Will", _T("Importing Line transp, Val=%d, Type=%d\n"),Transp, TranspType);
00480 
00481             if (!SetLineTransp((UINT32)TranspType, (UINT32)Transp))
00482                 goto NoMemory;
00483             break;
00484                               
00485         // Start Arrow head
00486         case EPSC_csah:
00487             if (!Stack.Pop(&ArrowHeight))
00488                 goto EPSError;
00489 
00490             if (!Stack.Pop(&ArrowWidth))
00491                 goto EPSError;
00492 
00493             if (!Stack.Pop(&ArrowID))
00494                 goto EPSError;
00495 
00496             TRACEUSER( "Will", _T("Importing StartArrow, ID=%d\n"),ArrowID);
00497             
00498             if (!Arrow.CreateStockArrow((StockArrow)ArrowID))
00499                 goto NoMemory;
00500 
00501             Arrow.SetArrowSize(FIXED16(ArrowWidth), FIXED16(ArrowHeight));
00502 
00503             if (!SetStartArrow(Arrow))
00504                 goto NoMemory;
00505             break;
00506 
00507         // End Arrow head
00508         case EPSC_ceah:
00509             if (!Stack.Pop(&ArrowHeight))
00510                 goto EPSError;
00511 
00512             if (!Stack.Pop(&ArrowWidth))
00513                 goto EPSError;
00514 
00515             if (!Stack.Pop(&ArrowID))
00516                 goto EPSError;
00517 
00518             TRACEUSER( "Will", _T("Importing EndArrow, ID=%d\n"),ArrowID);
00519             
00520             if (!Arrow.CreateStockArrow((StockArrow)ArrowID))
00521                 goto NoMemory;
00522 
00523             Arrow.SetArrowSize(FIXED16(ArrowWidth), FIXED16(ArrowHeight));
00524 
00525             if (!SetEndArrow(Arrow))
00526                 goto NoMemory;
00527             break;
00528 
00529         // Dash Patterns
00530         case EPSC_cdp:
00531             if (!Stack.Pop(&DashID))
00532                 goto EPSError;
00533 
00534             TRACEUSER( "Will", _T("Importing Dash Pattern, ID=%d\n"),DashID);
00535             
00536             pDash = new DashPatternAttribute;
00537             if (pDash == NULL)
00538                 goto NoMemory;
00539 
00540             if (!pDash->SetStockDashPattern((StockDash)DashID))
00541                 goto NoMemory;
00542 
00543             Dash = pDash->DashPattern;
00544             delete pDash;
00545 
00546             if (!SetDashPattern(Dash))
00547                 goto NoMemory;
00548             break;
00549 
00550         // Transparency fills.
00551         case EPSC_cxt:
00552         {
00553             DocCoord StartPoint, EndPoint, EndPoint2;
00554             INT32 StartTransp, EndTransp, TranspType;
00555             INT32 FillType;
00556             INT32 Tileable;
00557 
00558             // Used for fractal fills
00559             INT32 Seed;
00560             double Graininess, Gravity, Squash;
00561             UINT32 DPI;
00562 
00563             // Get fill type
00564             if (!Stack.Pop(&FillType))
00565                 goto EPSError;
00566 
00567             TRACEUSER( "Will", _T("Importing Transp Fill, Type=%d\n"),FillType);
00568 
00569             // Read in transparency type and levels...
00570             if (FillType != TRANSPFILL_NONE)
00571             {
00572                 // Get transparency type...
00573                 if (!Stack.Pop(&TranspType))
00574                     goto EPSError;
00575 
00576                 if ((FillType != TRANSPFILL_TEXTURE) && (FillType != TRANSPFILL_FRACTAL))
00577                 {           
00578                     // Get second transparency level if there is one.
00579                     switch (FillType)
00580                     {
00581                         case TRANSPFILL_LINEAR:
00582                         case TRANSPFILL_ELLIPTICAL:
00583                         case TRANSPFILL_CIRCULAR:
00584                         case TRANSPFILL_CONICAL:
00585                         case TRANSPFILL_NEWLINEAR:
00586                         case TRANSPFILL_NEWTEXTURE:
00587                         case TRANSPFILL_NEWFRACTAL:
00588                             if (!Stack.Pop(&EndTransp))
00589                                 goto EPSError;
00590                             break;
00591                     
00592                         default:
00593                             // This is a valid situation - no second transparency level.
00594                             break;
00595                     }
00596 
00597                     // Get first transparency level
00598                     if (!Stack.Pop(&StartTransp))
00599                         goto EPSError;
00600                 }
00601                 
00602             }
00603 
00604 
00605             if (FillType == TRANSPFILL_FRACTAL || FillType == TRANSPFILL_NEWFRACTAL)
00606             {
00607                 // If it's a fractal fill type, discard the 'sub-type' parameter (should 
00608                 // always be zero or one currently!)
00609                 INT32 SubType;
00610 
00611                 if (!Stack.Pop(&SubType))
00612                     goto EPSError;
00613 
00614                 // Default to no tiling
00615                 Tileable = FALSE;
00616 
00617                 // Work out the sub-type, either it has no tileable flag, or it does,
00618                 // or it's a type that is not supported.
00619                 if (SubType != 0)
00620                 {
00621                     if (SubType == 1)
00622                     {
00623                         // Get the tileable flag
00624                         if (!Stack.Pop(&Tileable))
00625                             goto EPSError;
00626                     }
00627                     else
00628                     {
00629                         ERROR2RAW("Bad fractal fill sub-type");
00630                         goto EPSError;
00631                     }
00632                 }
00633 
00634                 // Now get the fractal parameters:
00635                 if (!Stack.Pop(&DPI) ||
00636                     !Stack.Pop(&Squash) ||
00637                     !Stack.Pop(&Gravity) ||
00638                     !Stack.Pop(&Graininess) ||
00639                     !Stack.Pop(&Seed))
00640                 {
00641                     // Error in fractal parameteres
00642                     goto EPSError;
00643                 }
00644             }
00645 
00646             // For elliptical & texture/fractal fills, get the second end-point of the fill
00647             if ((FillType == TRANSPFILL_ELLIPTICAL) || 
00648                 (FillType == TRANSPFILL_TEXTURE) ||
00649                 (FillType == TRANSPFILL_FRACTAL) ||
00650                 (FillType == TRANSPFILL_NEWTEXTURE) ||
00651                 (FillType == TRANSPFILL_NEWFRACTAL) ||
00652                 (FillType == TRANSPFILL_NEWLINEAR))
00653             {
00654                 if (!Stack.PopCoordPair(&EndPoint2))
00655                     goto EPSError;
00656             }
00657             
00658             // Get start and end positions for variable transparency fills
00659             if ((FillType == TRANSPFILL_ELLIPTICAL) || 
00660                 (FillType == TRANSPFILL_CIRCULAR)   ||
00661                 (FillType == TRANSPFILL_LINEAR) ||
00662                 (FillType == TRANSPFILL_CONICAL)    ||
00663                 (FillType == TRANSPFILL_TEXTURE)    ||
00664                 (FillType == TRANSPFILL_FRACTAL)    ||
00665                 (FillType == TRANSPFILL_NEWLINEAR)  ||
00666                 (FillType == TRANSPFILL_NEWFRACTAL) ||
00667                 (FillType == TRANSPFILL_NEWTEXTURE))
00668             {
00669                 if (!Stack.PopCoordPair(&EndPoint) || !Stack.PopCoordPair(&StartPoint))
00670                     goto EPSError;
00671             }
00672 
00673             switch (FillType)
00674             {
00675                 // Decode Camelot EPS transparency fill codes
00676                 case TRANSPFILL_NONE:
00677                     if (!SetNoTranspFill())
00678                         goto NoMemory;
00679                     break;
00680 
00681                 case TRANSPFILL_FLAT:
00682                     if (!SetFlatTranspFill(TranspType, StartTransp))
00683                         goto NoMemory;
00684                     break;
00685 
00686                 case TRANSPFILL_LINEAR:
00687                     if (!SetLinearTranspFill(TranspType, StartTransp, EndTransp,
00688                                              StartPoint, EndPoint))
00689                         goto NoMemory;
00690                     break;
00691 
00692                 case TRANSPFILL_NEWLINEAR:
00693                     if (!SetLinearTranspFill(TranspType, StartTransp, EndTransp,
00694                                              StartPoint, EndPoint, &EndPoint2))
00695                         goto NoMemory;
00696                     break;
00697 
00698                 case TRANSPFILL_ELLIPTICAL:
00699                     if (!SetRadialTranspFill(TranspType, StartTransp, EndTransp,
00700                                              StartPoint, EndPoint, EndPoint2))
00701                         goto NoMemory;
00702                     break;
00703 
00704                 case TRANSPFILL_CIRCULAR:
00705                     if (!SetRadialTranspFill(TranspType, StartTransp, EndTransp,
00706                                              StartPoint, EndPoint))
00707                         goto NoMemory;
00708                     break;
00709 
00710                 case TRANSPFILL_CONICAL:
00711                     if (!SetConicalTranspFill(TranspType, StartTransp, EndTransp,
00712                                               StartPoint, EndPoint))
00713                         goto NoMemory;
00714                     break;
00715 
00716                 case TRANSPFILL_TEXTURE:
00717                     m_PendingBitmap = PENDING_BITMAP_TRANSPFILL;
00718                     BitmapAttrs.Coords[0] = StartPoint;
00719                     BitmapAttrs.Coords[1] = EndPoint;
00720                     BitmapAttrs.Coords[2] = EndPoint2;
00721                     BitmapAttrs.TranspType = TranspType;
00722                     BitmapAttrs.Transp      = 0;
00723                     BitmapAttrs.EndTransp   = 255;
00724                     break;
00725 
00726                 case TRANSPFILL_NEWTEXTURE:
00727                     m_PendingBitmap = PENDING_BITMAP_TRANSPFILL;
00728                     BitmapAttrs.Coords[0] = StartPoint;
00729                     BitmapAttrs.Coords[1] = EndPoint;
00730                     BitmapAttrs.Coords[2] = EndPoint2;
00731                     BitmapAttrs.TranspType = TranspType;
00732                     BitmapAttrs.Transp      = StartTransp;
00733                     BitmapAttrs.EndTransp   = EndTransp;
00734                     break;
00735 
00736                 case TRANSPFILL_FRACTAL:
00737                     if (!SetFractalTranspFill(TranspType, StartPoint, EndPoint, EndPoint2,
00738                                               Seed, Graininess, Gravity, Squash, DPI, 
00739                                               Tileable))
00740                         goto NoMemory;
00741                     break;
00742 
00743                 case TRANSPFILL_NEWFRACTAL:
00744                     if (!SetFractalTranspFill(TranspType, StartPoint, EndPoint, EndPoint2,
00745                                               Seed, Graininess, Gravity, Squash, DPI, 
00746                                               Tileable, StartTransp, EndTransp))
00747                         goto NoMemory;
00748                     break;
00749 
00750                 default:
00751                     ENSURE(FALSE, "Unknown fill type found!");
00752                     break;  // Don't know this fill type
00753             }
00754 
00755             break;
00756         }
00757 
00758         case EPSC_cxmt:
00759         {
00760             INT32 MappingType;
00761             INT32 Repeat;
00762 
00763             // Get fill mapping type (should always be 0)
00764             if (!Stack.Pop(&MappingType))
00765                 goto EPSError;
00766 
00767             if (MappingType != 0)
00768             {
00769                 ERROR2RAW("Bad mapping type in EPS");
00770                 goto EPSError;
00771             }
00772 
00773             // Get proper fill mapping type (should be 1, 2 or 3)
00774             if (!Stack.Pop(&Repeat))
00775                 goto EPSError;
00776 
00777             if ((Repeat < 1) || (Repeat > 3))
00778             {
00779                 ERROR2RAW("Bad mapping type in EPS");
00780                 goto EPSError;
00781             }
00782 
00783             // Call base class to use it
00784             if (Token == EPSC_cxm)
00785             {
00786                 if (!SetLinearFillMapping(Repeat))
00787                     goto NoMemory;
00788             }
00789             else
00790             {
00791                 if (!SetLinearTranspFillMapping(Repeat))
00792                     goto NoMemory;
00793             }
00794 
00795             break;
00796         }
00797 
00798         case EPSC_ctf:
00799         {
00800             // <FontName> ctf
00801             String_64 FName;
00802 
00803             if (!Stack.Pop(&FName))
00804                 goto EPSError;
00805             FName.SwapChar('-',' ');
00806 
00807             if ((FONTMANAGER->CacheNamedFont(&FName, EPSFilter::ClassOfFont) == ILLEGALFHANDLE))
00808                 goto EPSError;
00809 
00810             if (!SetTextTypeFace(&FName, EPSFilter::ClassOfFont))
00811                 goto EPSError;
00812 
00813             // Reset the font class to true type.
00814             EPSFilter::ClassOfFont = FC_TRUETYPE;
00815 
00816             break;
00817         }
00818 
00819         case EPSC_ctb:
00820         {
00821             // <0|1> ctb
00822             INT32 Bold;
00823             if (!Stack.Pop(&Bold))
00824                 goto EPSError;
00825 
00826             BOOL Boldon = (Bold==1);
00827             // Build any style definitions we need
00828             if (FontFlags.Bold)
00829             {
00830                 if (!SetTextBoldFont(Boldon))
00831                     goto EPSError;
00832             }
00833             else
00834             {
00835                 if (!SetTextBold(Boldon))
00836                     goto EPSError;
00837             }
00838             // Turn it off again
00839             FontFlags.Bold = FALSE;
00840             break;
00841         }           
00842 
00843         case EPSC_cti:
00844         {
00845             // <0|1> cti
00846             INT32 Italic;
00847             if (!Stack.Pop(&Italic))
00848                 goto EPSError;
00849 
00850             BOOL ItalicOn = (Italic==1);
00851             // Build any style definitions we need
00852             if (FontFlags.Italic)
00853             {
00854                 if (!SetTextItalicFont(ItalicOn))
00855                     goto EPSError;
00856             }
00857             else
00858             {
00859                 if (!SetTextItalic(ItalicOn))
00860                     goto EPSError;
00861             }
00862             FontFlags.Italic = FALSE;
00863             break;
00864         }           
00865 
00866         case EPSC_cts:
00867         {
00868             // <absolute millipoint rise> <absolute millipoint pointsize> cts
00869             INT32 rise,ptsize;
00870 
00871             if (!Stack.Pop(&ptsize))
00872                 goto EPSError;
00873                 
00874             if (!Stack.Pop(&rise))
00875                 goto EPSError;
00876 
00877             if (!SetTextScript(rise,ptsize))
00878                 goto EPSError;
00879 
00880             break;
00881         }
00882 
00883 
00884         case EPSC_ctp:
00885         {
00886             // <absolute millipoint size> ctp
00887             INT32 ptsize;
00888 
00889             if (!Stack.Pop(&ptsize))
00890                 goto EPSError;
00891 
00892             if (!SetTextSize(ptsize))
00893                 goto EPSError;
00894 
00895             break;
00896         }
00897 
00898         case EPSC_ctls:
00899         {
00900             INT32 type;
00901             if (!Stack.Pop(&type))
00902                 goto EPSError;
00903 
00904             switch (type)
00905             {
00906                 case 0:
00907                 {   
00908                     MILLIPOINT linespace;
00909                     if (!Stack.Pop(&linespace))
00910                         goto EPSError;
00911                     
00912                     if (!SetTextLineSpacing(1,0,linespace,0))
00913                         goto EPSError;
00914                     break;
00915                 }
00916 
00917                 case 1:
00918                 {
00919                     double proportional;
00920                     if (!Stack.Pop(&proportional))
00921                         goto EPSError;
00922 
00923                     if (!SetTextLineSpacing(2,0,0,proportional))
00924                         goto EPSError;
00925                     break;
00926                 }
00927             }
00928             break;
00929         }
00930 
00931         default:
00932             // Token not understood - pass on to base class
00933             return CamelotEPSFilter::ProcessToken();
00934     }
00935 
00936     // All seemed to work OK
00937     return TRUE;
00938 
00939 // Error handlers
00940 EPSError:
00941     HandleEPSError();
00942     return FALSE;
00943 
00944 NoMemory:
00945     HandleNoMemory();
00946     return FALSE;
00947 }
00948 
00949 
00950 /********************************************************************************************
00951 
00952 >   INT32 CamelotNativeEPSFilter::EPSHeaderIsOk(ADDR pFileHeader, UINT32 HeaderSize)
00953 
00954     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
00955     Created:    16/12/94
00956     Returns:    0 - 10. 0 means not interested in this file, 10 means I know all about this
00957                 file.
00958     Purpose:    Checks to see if the EPS comment headers specify that this is an Camelot
00959                 Native file, as required.
00960 
00961 ********************************************************************************************/
00962 
00963 INT32 CamelotNativeEPSFilter::EPSHeaderIsOk(ADDR pFileHeader, UINT32 HeaderSize)
00964 {
00965     // This function is NOT unicode
00966 
00967     // Check the first line in EPS file
00968     if (strncmp((char *) pFileHeader, "%!PS-Adobe-2.0 EPSF-1.2", 23) != 0)
00969     {
00970         // Incorrect version of EPS header line - we don't want this
00971         return 0;
00972     }
00973 
00974     // !PS-Adobe line is ok - check creator line...
00975     std::istringstream HeaderFile((char *) pFileHeader, ios_base::in /* HeaderSize*/);
00976     char Buffer[200];
00977 
00978     UINT32 Lines = 0;
00979     while ((Lines < 20) && !HeaderFile.eof())
00980     {
00981         HeaderFile.getline(Buffer, 200);
00982         Lines++;
00983 
00984         // if the file is native camelot, return indicating strong 'interest'!
00985         if (strncmp(Buffer, "%%Creator: Xara Studio (Native)", 31) == 0)
00986             return 10;
00987 
00988         // If we find the compression token then stop the search as we don't want to start
00989         // looking in the compressed data!
00990         if (strncmp(Buffer, "%%Compression:", 14)==0)
00991             break;
00992     }
00993 
00994     // Didn't find a suitable Creator line. Since this is not really an eps filter it
00995     // will claim to know nothing about it. Camelot EPS will have a go at this file
00996     // but we can not really try.
00997     return 0;
00998 }
00999 
01000 /********************************************************************************************
01001 
01002 >   BOOL CamelotNativeEPSFilter::PrepareToImport()
01003 
01004     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
01005     Created:    16/12/94
01006     Returns:    TRUE if filter initialised ok;
01007                 FALSE if not.
01008     Purpose:    See base class.
01009     Errors:     See base class.
01010     SeeAlso:    EPSFilter::PrepareToImport;
01011 
01012 ********************************************************************************************/
01013 
01014 BOOL CamelotNativeEPSFilter::PrepareToImport()
01015 {
01016     // Note the old state so we can put it back at the end
01017     OldImportWithLayers = Filter::ImportWithLayers;
01018     OldOpenWithLayers = Filter::OpenWithLayers;
01019 
01020     // Neville 7/8/97 - Layers are bad in Webster as they conflict with frames
01021 #ifndef WEBSTER
01022     // We always wanted to import with layers in the native filter
01023     // Nowadays, its a bit more complicated
01024     // If we are during template loading then always load the layers
01025     if (TheDocument->IsTemplateLoading())
01026     {
01027         ImportWithLayers = TRUE;
01028         OpenWithLayers = TRUE;
01029     }
01030     else
01031     {
01032         // Otherwise if we are in:-
01033         // - a framed document then remove all layers from importing
01034         // - a layered document then import with layers
01035         if (TheDocument->IsImporting())
01036         {
01037             ERROR2IF(ImportInfo.pSpread == NULL,FALSE,"CamelotNativeEPSFilter::PrepareToImport No spread");
01038             Layer * pFrame = ImportInfo.pSpread->FindFirstFrameLayer();
01039             if (pFrame == NULL)
01040                 ImportWithLayers = TRUE;    // Layered = allow layers
01041             else
01042                 ImportWithLayers = FALSE;   // Framed = disallow layers
01043         }
01044         else
01045             ImportWithLayers = TRUE;
01046         OpenWithLayers = TRUE;          // Always open with layers
01047     }
01048 #else
01049     // If we are during template loading then always load the layers
01050     if (TheDocument->IsTemplateLoading())
01051     {
01052         ImportWithLayers = TRUE;
01053         OpenWithLayers = TRUE;
01054     }
01055     else    // Otherwise remove all layers from importing
01056     {
01057         ImportWithLayers = FALSE;
01058         OpenWithLayers = FALSE;
01059     }
01060 #endif // WEBSTER */
01061 
01062     // reset version numbers so files without this info have numbers 0.0
01063     FileVersionNumber  = 0.0;
01064     BuildVersionNumber = 0.0;
01065 
01066     // Initialise base class first.
01067     if (!CamelotEPSFilter::PrepareToImport())
01068         return FALSE;
01069 
01070     // set min line width to zero and store old value
01071     OldMinLineWidth = MinLineWidth;
01072     MinLineWidth = 0;
01073     
01074     return TRUE;
01075 }
01076 
01077 
01078 
01079 /********************************************************************************************
01080 
01081 >   virtual void CamelotNativeEPSFilter::CleanUpAfterImport(BOOL Successful)
01082 
01083     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
01084     Created:    20/1/95
01085     Inputs:     Successful - TRUE if the import went OK, FALSE if it failed
01086     Purpose:    Happens at the end of the import to allow the filters to clean up after
01087                 themselves
01088 
01089 ********************************************************************************************/
01090 
01091 void CamelotNativeEPSFilter::CleanUpAfterImport(BOOL Successful)
01092 {
01093     // Call the base class
01094     CamelotEPSFilter::CleanUpAfterImport(Successful);
01095 
01096     // restore the old min line width
01097     MinLineWidth = OldMinLineWidth;
01098 
01099     // Get rid of the bitmap references if we have any
01100     // This will cause all bitmaps that were loaded, but are not used to be thrown away
01101     if (BitmapPoolRefs != NULL)
01102         delete [] BitmapPoolRefs;
01103 
01104     // Ready for the next one
01105     BitmapPoolRefs = NULL;
01106 
01107     // Put the Import with layers flag back as it was
01108     ImportWithLayers = OldImportWithLayers;
01109     OpenWithLayers = OldOpenWithLayers;
01110 
01111     // Flag this as an old format document
01112     if (TheDocument && Successful)
01113     {
01114         // But only flag it if we are opening the document rather than importing into an exisiting one
01115         if (!TheDocument->IsImporting())
01116             TheDocument->SetLoadedAsVersion1File(TRUE);
01117     }
01118 }
01119 
01120 
01121 
01122 /********************************************************************************************
01123 
01124 >   virtual void CamelotNativeEPSFilter::BitmapPoolAttach(KernelBitmap* pBitmap)
01125 
01126     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
01127     Created:    20/1/95
01128     Inputs:     pBitmap - The bitmap to attach
01129     Purpose:    Makes a reference to the bitmap so that it can be used throughout the eps
01130                 file with repeating the data.
01131 
01132 ********************************************************************************************/
01133 
01134 void CamelotNativeEPSFilter::BitmapPoolAttach(KernelBitmap* pBitmap)
01135 {
01136     // Make sure we have some refs and its in range
01137     if ((BitmapPoolRefs!=NULL) && (PendingBitmapNum < BitmapCount))
01138     {
01139         // yep, so attach the bitmap to the reference
01140         BitmapPoolRefs[PendingBitmapNum].Attach(pBitmap, GetDocument());
01141 
01142         if (BitmapPoolRefs[PendingBitmapNum].GetBitmap() != pBitmap)
01143         {
01144             // It didn't use the bitmap we gave it, so we can delete it
01145             delete pBitmap;
01146         }
01147 
01148     }
01149 }
01150 
01151 
01152 
01153 /********************************************************************************************
01154 
01155 >   virtual BOOL CamelotNativeEPSFilter::ReadBitmap()
01156 
01157     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
01158     Created:    20/1/95
01159     Returns:    TRUE if it worked, FALSE if it found an error
01160     Purpose:    Reads in a bitmap. If it is a Type 0 bitmap (ie one with all its data) it
01161                 will ask the base class to import it. If it is a Type 1 bitmap it will look
01162                 up the reference in the bitmap pool and use that.
01163 
01164 ********************************************************************************************/
01165 
01166 BOOL CamelotNativeEPSFilter::ReadBitmap()
01167 {
01168     TRACEUSER( "Rik", _T("ReadBitmap...\n"));
01169     // Find out what kind of bitmap it is - always type 0 or 1 at present.
01170     INT32 BitmapType;
01171     if (!Stack.Pop(&BitmapType))
01172     {
01173         // Error - not enough operands
01174         HandleEPSError();
01175         return FALSE;
01176     }
01177 
01178     // if it is the old type 0 bitmap get the base class to do all the work
01179     if (BitmapType == 0)
01180     {
01181         // Need to push the type back on the stack again ready for the base class to read it
01182         TRACEUSER( "Rik", _T("Bitmap with data (in the pool I hope)\n"));
01183         Stack.Push(BitmapType);
01184         return CamelotEPSFilter::ReadBitmap();
01185     }
01186 
01187     // OK, see if we have a type we do not know about
01188     if (BitmapType != 1)
01189     {
01190         // Error - Bad Type
01191         HandleEPSError();
01192         return FALSE;
01193     }
01194     
01195     // Right, we have a type 1 bitmap....
01196     INT32 BitmapIndex = 0;
01197     
01198     // Read in info on the bitmap (ie, which bitmap from the pool do we want) ...
01199     if ((!Stack.Pop(&BitmapIndex)) /*|| (BitmapIndex >= BitmapCount)*/)
01200     {
01201         // Error - not enough operands
01202         HandleEPSError();
01203         return FALSE;
01204     }
01205 
01206     // ... and make sure that is in the range of bitmaps we have.
01207     // If the Index is out of range then use the Last one rather than just erroring.
01208     if (BitmapIndex >= BitmapCount)
01209         BitmapIndex = (BitmapCount-1);
01210 
01211     TRACEUSER( "Rik", _T("Bitmap reference found - refers to bitmap %d\n"), BitmapIndex);
01212 
01213     // Want to find bitmap 'BitmapIndex' and set pBitmap to point at it
01214     pBitmap = BitmapPoolRefs[BitmapIndex].GetBitmap();
01215     return TRUE;
01216 }
01217 
01218 
01219 
01220 /********************************************************************************************
01221 
01222 >   virtual INT32 CamelotNativeEPSFilter::ImportBinary(ADDR pData, INT32 Length)
01223 
01224     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
01225     Created:    19/12/94
01226     Inputs:     Length - the number of bytes to read, in terms of binary data imported, as
01227                          opposed to how many bytes the file format takes to represent this
01228                          binary data.
01229     Outputs:    pData - the buffer to put the data into.
01230     Returns:    TRUE if it imported the specified number of bytes correctly;
01231                 FALSE if not.
01232     Purpose:    Reads the binary data out of the file and puts it into the buffer supplied.
01233                 It also makes checks to see if the appropriate chars are found surounding
01234                 the Binary stream.
01235     Errors:     File input errors; EOF
01236     SeeAlso:    Filter::ImportBinary
01237 
01238 ********************************************************************************************/
01239 
01240 INT32 CamelotNativeEPSFilter::ImportBinary(ADDR pData, INT32 Length)
01241 {
01242     // read chars until we get a >
01243     INT32 CountDown = 50;
01244     TCHAR Ch;
01245     do {
01246         // Read a TCHAR
01247         if (EPSFile->read(&Ch, 1).fail())
01248         {
01249             HandleEPSError();
01250             return FALSE;
01251         }
01252 
01253         // Count it
01254         CountDown--;
01255     } while ((CountDown>0) && (Ch!='>'));
01256 
01257     // See if we found it
01258     if (CountDown==0)
01259     {
01260         HandleEPSError();
01261         return FALSE;
01262     }
01263     
01264     // Read binary section
01265     if (EPSFile->read(pData, Length).fail())
01266     {
01267         HandleEPSError();
01268         return FALSE;
01269     }
01270 
01271     // Read TCHAR and check that it is a <
01272     if (EPSFile->read(&Ch, 1).fail())
01273     {
01274         HandleEPSError();
01275         return FALSE;
01276     }
01277 
01278     if (Ch!='<')
01279     {
01280         HandleEPSError();
01281         return FALSE;       
01282     }
01283 
01284     // Find out how much of the file we have read
01285     INT32 CharsRead = EPSFile->GetCharsRead();
01286     if (CharsRead > (LastProgressUpdate + 2048))
01287     {
01288         if (!ContinueSlowJob(CharsRead))
01289         {
01290             // Abort operation - make sure nodes are deleted and not added to the tree.
01291             ERROR(_R(IDT_IMPORT_USERABORT), FALSE);
01292         }
01293         else
01294         {
01295             LastProgressUpdate = CharsRead;
01296         }
01297     }
01298 
01299     // Re-sync the tokeniser
01300     EPSFile->GetLine();
01301     EPSFile->GetCh();
01302 
01303     // Must have worked
01304     return TRUE;
01305 }
01306 
01307 
01308 /********************************************************************************************
01309 
01310 >   virtual BOOL CamelotNativeEPSFilter::ProcessFilterComment()
01311 
01312     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
01313     Created:    23/12/94
01314     Returns:    TRUE if it finds something it likes, FALSE if not
01315     Purpose:    This deals with the page info held in comments in the EPS stream
01316 
01317 ********************************************************************************************/
01318 
01319 BOOL CamelotNativeEPSFilter::ProcessFilterComment()
01320 {
01321     // read the build version number of the app which saved this file
01322     if (camStrncmp(TokenBuf, _T("%%Creator: Xara Studio (Native)"), 31) == 0)
01323     {
01324         return TRUE;
01325     }
01326 
01327     // Go and have a look at the token buffer and see if it is our special
01328     // file version comment. If so, then extract the version number from it. 
01329     if (camStrncmp(TokenBuf, _T("%%File version:"), 15)==0)
01330     {
01331         TCHAR* pVersion = &(((TCHAR*)TokenBuf)[15]);
01332         double Version=0.0;
01333         camSscanf(pVersion, _T("%lf"), &Version);
01334         TRACEUSER( "Neville", _T("Native file version = %f\n"), Version);
01335         FileVersionNumber = Version;
01336         // Must stop later file versions loading back into this version.
01337         if (Version > ReadNativeVersion)
01338         {
01339             InformWarning(_R(IDW_FILEISWRONGVERSION));
01340             // flag the error state
01341             EPSFlags.EPSErrorEncountered = TRUE;
01342             // set the user has cancelled the error message so that this one is not reported
01343             Error::SetError(_R(IDN_USER_CANCELLED), 0);
01344 
01345             // We recokonised the token but it is invalid
01346             return TRUE;
01347         }
01348     }
01349     
01350     // Go and have a look at the token buffer and see if it is our special
01351     // compression comment
01352     if (camStrncmp(TokenBuf, _T("%%Compression:"), 14)==0)
01353     {
01354 //#ifdef STANDALONE
01355 //      // First release of the file viewer will not have the native file compression
01356 //      // loading code in. Therefore, we must abort if the compression tokens are
01357 //      // encountered.
01358 //      //if (FileVersionNumber < 0.500)
01359 //      InformWarning(_R(IDW_FILEISCOMPRESSED));
01360 //      // flag the error state
01361 //      EPSFlags.EPSErrorEncountered = TRUE;
01362 //      // set the user has cancelled the error message so that this one is not reported
01363 //      Error::SetError(_R(IDN_USER_CANCELLED), 0);
01364 //
01365 //      // We recokonised the token but it is invalid
01366 //      return TRUE;
01367 //#endif
01368         TCHAR* pType = &(((TCHAR*)TokenBuf)[14]);
01369         camSscanf(pType, _T("%d"), &CompressionType);
01370         TRACEUSER( "Neville", _T("CamelotNativeEPSFilter::ProcessFilterComment compression type %d\n"), CompressionType);
01371 
01372         // We have found our compression token so turn compression on
01373         BOOL ok = EPSFile->SetCompression(TRUE);
01374         if (!ok)
01375         {
01376             // We had a problem starting up the decompressor
01377             // flag the error state
01378             EPSFlags.EPSErrorEncountered = TRUE;
01379             // set up a useful error message, this one seems to say that we ran out of memory
01380             // and this is the most likely reason why
01381             Error::SetError(_R(IDT_EPS_NOMEMORY), 0);
01382             // We recokonised the token but it is invalid
01383             return TRUE;
01384         }
01385 
01386         return TRUE;
01387     }
01388     if (camStrncmp(TokenBuf, _T("%%Compression info:"), 19)==0)
01389     {
01390         TCHAR* pVersion = &(((TCHAR*)TokenBuf)[19]);
01391         double CompVersion=0.0;
01392         camSscanf(pVersion, _T("%lf"), &CompVersion);
01393         TRACEUSER( "Neville", _T("Compression version = %f\n"), CompVersion);
01394         double StreamVersion = GZipFile::GetStreamVersionNo();
01395         // If the version stored in the file is later than the one in the stream class
01396         // then we cannot cope with this data, so error.
01397         if (CompVersion > StreamVersion)
01398         {
01399             InformWarning(_R(IDW_FILEISCOMPRESSED));
01400             // flag the error state
01401             EPSFlags.EPSErrorEncountered = TRUE;
01402             // set the user has cancelled the error message so that this one is not reported
01403             Error::SetError(_R(IDN_USER_CANCELLED), 0);
01404             // We recokonised the token but it is invalid
01405             return TRUE;
01406         }
01407 
01408         return TRUE;
01409     }
01410     if (camStrncmp(TokenBuf, _T("%%EndCompression:"), 17)==0)
01411     {
01412         // We have found our compression token so turn compression on
01413         BOOL ok = EPSFile->SetCompression(FALSE);
01414         if (!ok)
01415         {
01416             // We had a problem stoping up the decompressor
01417             // flag the error state
01418             EPSFlags.EPSErrorEncountered = TRUE;
01419             // We will assume that an error has been set up. At present, the only one
01420             // most likely is a CRC error.
01421             // We recokonised the token but it is invalid
01422             return TRUE;
01423         }
01424 
01425         return TRUE;
01426     }
01427     if (camStrncmp(TokenBuf, _T("%%EndCompressionInfo:"), 21)==0)
01428     {
01429         return TRUE;
01430     }
01431       
01432     // Go and have a look at the token buffer and see if it looks like bitmap count
01433     if (camStrncmp(TokenBuf, _T("%%BitmapPoolCount"), 17)==0)
01434     {
01435         TCHAR* pCount = &(((TCHAR*)TokenBuf)[17]);
01436         camSscanf(pCount, _T("%d"), &BitmapCount);
01437         TRACEUSER( "Rik", _T("%d\n"), BitmapCount);
01438 
01439         // There are no bitmaps in this file
01440         if (BitmapCount==0)
01441             return TRUE;
01442 
01443         // Make sure that we have not already found one of these
01444         if (BitmapPoolRefs!=NULL)
01445             ERROR3("Bitmap Pool already in use!");
01446 
01447         // Allocate a few references to bitmaps
01448         BitmapPoolRefs = new KernelBitmapRef[BitmapCount];
01449         return TRUE;
01450     }
01451 
01452     // Check for any text comments
01453     if (camStrncmp(TokenBuf, _T("%%XSScript"), 10)==0)
01454     {
01455         TextComment[0]=2;
01456         return TRUE;
01457     }
01458 
01459     return FALSE;
01460 }
01461 
01462 
01463 /********************************************************************************************
01464 
01465 >   virtual EPSExportDC* CamelotNativeEPSFilter::CreateExportDC()
01466 
01467     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
01468     Created:    19/12/94
01469     Returns:    Pointer to a new ExportDC.
01470     Purpose:    Creates a new export DC (NativeExportDC) ready to export the Native file to.
01471 
01472 ********************************************************************************************/
01473 
01474 EPSExportDC* CamelotNativeEPSFilter::CreateExportDC()
01475 {
01476 #if !defined(EXCLUDE_FROM_RALPH)
01477     return new NativeExportDC(this);
01478 #else
01479     return NULL;
01480 #endif
01481 }
01482 
01483 
01484 /********************************************************************************************
01485 
01486 >   virtual BOOL CamelotNativeEPSFilter::GetExportOptions( )
01487 
01488     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> HUmphrys
01489     Created:    22/12/95
01490     Inputs:     -
01491     Returns:    TRUE if OK, FALSE if user pressed Cancel.
01492     Purpose:    Allows the user to be prompted to get information for export.
01493                 This overriden version returns True so that nothing happens.
01494     Scope:      Protected.
01495 
01496 ********************************************************************************************/
01497 
01498 BOOL CamelotNativeEPSFilter::GetExportOptions( )
01499 {
01500     // Overide the CamelotEPS form so that we do nothing again i.e. just return TRUE
01501     return TRUE;
01502 }
01503 
01504 
01505 /********************************************************************************************
01506 
01507 >   BOOL CamelotNativeEPSFilter::PrepareToExport(CCLexFile* pFile, Spread* pSpread)
01508 
01509     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
01510     Created:    15/12/94
01511     Inputs:     pFile - the path name
01512                 pSpread - The spread to save
01513     Returns:    TRUE if it worked, FALSE if it failed
01514     Purpose:    Gets things ready for the export. Creates the render region to do all the
01515                 exporting with.
01516 
01517 ********************************************************************************************/
01518 
01519 BOOL CamelotNativeEPSFilter::PrepareToExport(CCLexFile* pFile, Spread* pSpread)
01520 {
01521 #if !defined(EXCLUDE_FROM_RALPH)
01522     // Use base class to do most of it
01523     if (!CamelotEPSFilter::PrepareToExport(pFile, pSpread)) return FALSE;
01524 
01525     // Try and create a render region if we are really a
01526     // Native filter and not something derived from it
01527     if (IS_A(this, CamelotNativeEPSFilter))
01528     {
01529         // Don't care about clip regions when exporting - create a null region.
01530         DocRect NullClipRect;
01531         NullClipRect.MakeEmpty();
01532 
01533         // Don't use rendering matrix when exporting EPS as it uses fractional coordinates.
01534         Matrix Identity;
01535 
01536         // Don't use view scale; set to 1
01537         FIXED16 Scale(1);
01538 
01539         // Create the render region
01540         ExportRegion = new NativeRenderRegion(NullClipRect, Identity, Scale);
01541         if (ExportRegion == NULL) return FALSE;
01542 
01543         // use the first docview
01544         DocView * pDocView = TheDocument->GetFirstDocView();
01545         // fallback - help no docviews
01546         if ((!pDocView) || (!pDocView->IsKindOf(CC_RUNTIME_CLASS(DocView))))
01547             pDocView = DocView::GetSelected(); // help! use selected docview
01548 
01549         // Attach to the right device.
01550         ExportRegion->AttachDevice(pDocView, ExportDCPtr->GetDC(), pSpread);
01551     }
01552 #endif
01553     // Thats it
01554     return TRUE;
01555 }
01556 
01557 
01558 /********************************************************************************************
01559 
01560 >   BOOL CamelotNativeEPSFilter::ExportBitmap(KernelBitmap& TheBitmap)
01561 
01562     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
01563     Created:    20/1/95
01564     Inputs:     TheBitmap - the bitmap to export
01565     Returns:    TRUE if the bitmap was exported ok (or if it wasn't exported because the
01566                      file format does not support it;
01567                 FALSE if an error occured.
01568     Purpose:    Export a bitmap to a Camelot EPS file.  This does one of 2 things.
01569                 If we are in the middle of exporting the bitmap pool it will save out
01570                 all the bitmap data, just as CamelotEPS does. If we are not in the bitmap
01571                 pool it will simply save out a reference to the bitmap in the pool
01572     Errors:     Usual disk/file errors.
01573     SeeAlso:    Filter::ExportBitmap
01574 
01575 ********************************************************************************************/
01576 
01577 BOOL CamelotNativeEPSFilter::ExportBitmap(KernelBitmap& TheBitmap)
01578 {
01579 #if !defined(EXCLUDE_FROM_RALPH)
01580     // If this is the bitmap pool, then save out some data
01581     if (IsSavingBitmapPool)
01582     {
01583         TRACEUSER( "Rik", _T("In the bitmap pool, so saving out real data\n"));
01584         return CamelotEPSFilter::ExportBitmap(TheBitmap);
01585     }
01586 
01587     // If we get here then we must be saving out a reference to a bitmap saved earlier in the pool
01588     TRACEUSER( "Rik", _T("Trying to save a reference to a bitmap\n"));
01589     
01590     // Try and find the bitmap in the bitmap pool
01591     // Get the document that we are saving
01592     Document* pDoc = GetDocument();
01593     if (pDoc==NULL)
01594         return FALSE;
01595 
01596     // Find the doccomponent with the list of bitmaps in it
01597     DocComponent* DocBitmapList = pDoc->GetDocComponent(CC_RUNTIME_CLASS(BitmapListComponent));
01598     if (DocBitmapList==NULL)
01599         return FALSE;
01600 
01601     ExportedBitmaps* pBitmapExportPool = ((BitmapListComponent*)DocBitmapList)->GetBitmapExportPool();
01602     ERROR3IF(pBitmapExportPool == NULL, "No BitmapExportPool in CamelotNativeEPSFilter::ExportBitmap");
01603     if (pBitmapExportPool==NULL)
01604         return FALSE;
01605 
01606     INT32 BitmapPoolNum = -1;
01607 
01608     // Get ready to look for our bitmap
01609     class ExportBitmap* pExportBitmap = pBitmapExportPool->GetBitmap(&TheBitmap);
01610     // The 'class' statement is because this filter has a function called 'ExportBitmap'
01611 
01612     ERROR3IF(pExportBitmap == NULL, "Couldn't find the bitmap in the pool in CamelotNativeEPSFilter::ExportBitmap");
01613 
01614     if (pExportBitmap)
01615     {
01616         BitmapPoolNum = pExportBitmap->RecordNumber;
01617     }
01618     
01619     // Did we find it
01620     if (BitmapPoolNum >= 0)
01621     {
01622         // Export the number of the bitmap
01623         ExportDCPtr->OutputValue((UINT32) BitmapPoolNum);
01624 
01625         // Bitmap type is always 1 to represent a reference (0 is an actual bitmap)
01626         ExportDCPtr->OutputToken(_T("1"));
01627 
01628         // Write out the bitmap start token
01629         ExportDCPtr->OutputToken(_T("csbm"));
01630         ExportDCPtr->OutputNewLine();
01631 
01632         // Write out the bitmap end token
01633         ExportDCPtr->OutputToken(_T("cebm"));
01634         ExportDCPtr->OutputNewLine();
01635 
01636         // All ok
01637         return TRUE;
01638     }
01639 #endif
01640     // Did not find the bitmap
01641     return FALSE;
01642 }
01643 
01644 
01645 /********************************************************************************************
01646 
01647 >   BitmapFilterSupport CamelotNativeEPSFilter::GetBitmapSupportLevel()
01648 
01649     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
01650     Created:    30/01/95
01651     Returns:    IndirectedBitmapSupport - This filter supports bitmap indirection; i.e. a
01652                                           bitmap pool of some type is saved and then this
01653                                           can be referenced in the file.
01654     Purpose:    Determine how well this filter supports bitmaps when exporting.
01655 
01656 ********************************************************************************************/
01657 
01658 BitmapFilterSupport CamelotNativeEPSFilter::GetBitmapSupportLevel()
01659 {
01660     return IndirectedBitmapSupport;
01661 }
01662 
01663 
01664 /********************************************************************************************
01665 >   double CamelotNativeEPSFilter::SmartGetBuildNumber()
01666 
01667     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
01668     Created:    17/10/95
01669     Returns:    Build version number
01670     Purpose:    Determines a monotomic build version number based on BuildVersionNumber which
01671                 unfortunately jumps to v1.00/a/b/c/d but these are mapped back to real build
01672                 numbers. v1.00/a/b/c/d all have BuildVersionNumbers of 1.00 and are all
01673                 descended from an isolated liniage based on 0.586 so all map to this number
01674     Note:       Only guaranteed for build versions greater than 0.586!
01675 ********************************************************************************************/
01676 
01677 double CamelotNativeEPSFilter::SmartGetBuildNumber()
01678 {
01679     double BuildNumber = GetBuildNumber();
01680     if (BuildNumber==1.00)
01681         BuildNumber = 0.586;
01682     return BuildNumber;
01683 }
01684 
01685 #if !defined(EXCLUDE_FROM_RALPH)
01686 
01688 // NativeRenderRegion
01689 
01690 /********************************************************************************************
01691 
01692 >   NativeRenderRegion::NativeRenderRegion(DocRect ClipRect, Matrix ConvertMatrix,
01693                                            FIXED16 ViewScale)
01694 
01695     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
01696     Created:    15/12/94
01697     Inputs:     ClipRect - The rectangle to use as the clip rect for the rendering
01698                 ConvertMatrix - the rendering matrix
01699                 ViewScale - the scale to render at
01700     Purpose:    Constructor for the Native Save/Load filter render region.
01701 
01702 ********************************************************************************************/
01703 
01704 NativeRenderRegion::NativeRenderRegion(DocRect ClipRect, Matrix ConvertMatrix, FIXED16 ViewScale) :
01705                     CamelotEPSRenderRegion(ClipRect, ConvertMatrix, ViewScale)
01706 {
01707     CreatorString = _T("Xara Studio (Native) ") CAMELOT_VERSION_STRING;
01708 
01709     // Flag that we have not started up the compressor ok by default.
01710     CompressionInitedOk = FALSE;
01711 }
01712 
01713 /********************************************************************************************
01714 
01715 >   virtual void NativeRenderRegion::ConditionalSuicide ( void )
01716 
01717     Author:     Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
01718     Created:    24/2/00
01719     Inputs:     -
01720     Returns:    -
01721     Purpose:    Causes the object to commit suicide. This is to get around using a few
01722                 if IS_A calls elsewhere in Camelot.
01723 
01724 ********************************************************************************************/
01725 
01726 void NativeRenderRegion::ConditionalSuicide ( void )
01727 {
01728     // Delete the object.
01729     delete this;
01730 }
01731 
01732 /********************************************************************************************
01733 
01734 >   virtual void NativeRenderRegion::GetRenderRegionCaps(RRCaps* pCaps)
01735 
01736     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
01737     Created:    10/4/95
01738     Outputs:    pCaps - The details about what types of thing this render region can render
01739     Purpose:    This function allows render regions to admit to what they can and can not
01740                 render. This allows other areas of the program to come in and help render
01741                 regions out in some situations, if they are unable to render everything.
01742                 eg. an OSRenderRegion can not render transparancy.
01743 
01744 ********************************************************************************************/
01745 
01746 void NativeRenderRegion::GetRenderRegionCaps(RRCaps* pCaps)
01747 {
01748     // We can do everything mate cos we're fabby.
01749     pCaps->CanDoAll();
01750 }
01751 
01752 
01753 /********************************************************************************************
01754 
01755 >   BOOL NativeRenderRegion::WriteProlog(KernelDC *pDC)
01756 
01757     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
01758     Created:    24/04/95
01759     Inputs:     pDC - the device context to output to.
01760     Outputs:    -
01761     Returns:    TRUE if ok;
01762                 FALSE if error (e.g. file/disk error or printer driver error)
01763     Purpose:    Over-ride the routines defined by CamelotEPSRenderRegion - we don't need
01764                 any PostScript prolog in ART files.
01765     SeeAlso:    EPSRenderRegion::WriteSetup
01766 
01767 ********************************************************************************************/
01768 
01769 BOOL NativeRenderRegion::WriteProlog(KernelDC *pDC)
01770 {
01771     // No PostScript procedure defns here...
01772     return TRUE;
01773 }
01774 
01775 /********************************************************************************************
01776 
01777 >   BOOL NativeRenderRegion::WriteSetup(KernelDC *pDC)
01778 
01779     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
01780     Created:    24/04/95
01781     Inputs:     pDC - the device context to output to.
01782     Outputs:    -
01783     Returns:    TRUE if ok;
01784                 FALSE if error (e.g. file/disk error or printer driver error)
01785     Purpose:    Over-ride the routines defined by CamelotEPSRenderRegion - we don't need
01786                 any PostScript setup in ART files.
01787     SeeAlso:    NativeRenderRegion::WriteSetup
01788 
01789 ********************************************************************************************/
01790 
01791 BOOL NativeRenderRegion::WriteSetup(KernelDC *pDC)
01792 {
01793     // No PostScript setup code here...
01794     return TRUE;
01795 }
01796 
01797 
01798 /********************************************************************************************
01799 
01800 >   void NativeRenderRegion::GetValidPathAttributes()
01801 
01802     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
01803     Created:    5/5/95
01804     Purpose:    See CamelotEPSRenderRegion::GetValidPathAttributes.
01805                 This version checks and handles special native features.
01806     SeeAlso:    EPSRenderRegion::GetValidPathAttributes
01807 
01808 ********************************************************************************************/
01809 
01810 void NativeRenderRegion::GetValidPathAttributes()
01811 {
01812     KernelDC *pDC = (KernelDC*)CCDC::ConvertFromNativeDC(RenderDC);
01813 
01814     // Find out what this render region can do.
01815     RRCaps Caps;
01816     GetRenderRegionCaps(&Caps);
01817 
01818     if (SetLastOutputAttribute(ATTR_STARTARROW))
01819     {
01820         // Start arrow head
01821         StartArrowAttribute *pArrow =           
01822             (StartArrowAttribute *) CurrentAttrs[ATTR_STARTARROW].pAttr;
01823 
01824         TRACEUSER( "Will", _T("Outputing Start Arrow, ID=%d\n"),pArrow->StartArrow.GetArrowID());
01825 
01826         if (pArrow->StartArrow.GetArrowID() >= 0)
01827         {
01828             pDC->OutputValue((INT32)pArrow->StartArrow.GetArrowID());
01829             pDC->OutputReal((pArrow->StartArrow.GetArrowWidth()).MakeDouble());
01830             pDC->OutputReal((pArrow->StartArrow.GetArrowHeight()).MakeDouble());
01831 
01832             pDC->OutputToken(_T("csah"));
01833             pDC->OutputNewLine();
01834         }
01835     }
01836 
01837     if (SetLastOutputAttribute(ATTR_ENDARROW))
01838     {
01839         // End arrow head
01840         EndArrowAttribute *pArrow =             
01841             (EndArrowAttribute *) CurrentAttrs[ATTR_ENDARROW].pAttr;
01842 
01843         TRACEUSER( "Will", _T("Outputing End Arrow, ID=%d\n"),pArrow->EndArrow.GetArrowID());
01844 
01845         if (pArrow->EndArrow.GetArrowID() >= 0)
01846         {
01847             pDC->OutputValue((INT32)pArrow->EndArrow.GetArrowID());
01848             pDC->OutputReal((pArrow->EndArrow.GetArrowWidth()).MakeDouble());
01849             pDC->OutputReal((pArrow->EndArrow.GetArrowHeight()).MakeDouble());
01850 
01851             pDC->OutputToken(_T("ceah"));
01852             pDC->OutputNewLine();
01853         }
01854     }
01855 
01856     if (SetLastOutputAttribute(ATTR_DASHPATTERN))
01857     {
01858         // Get dash pattern
01859         DashPatternAttribute *pDash =           
01860             (DashPatternAttribute *) CurrentAttrs[ATTR_DASHPATTERN].pAttr;
01861 
01862         TRACEUSER( "Will", _T("Outputing Dash Pattern, ID=%d\n"),pDash->DashPattern.GetDashID());
01863 
01864         pDC->OutputValue((INT32)pDash->DashPattern.GetDashID());
01865         pDC->OutputToken(_T("cdp"));
01866         pDC->OutputNewLine();
01867     }
01868 
01869     // Now do transparency fills
01870     GetValidTransparencyAttributes();
01871 
01872     // Handle usual pens/brushes
01873     CamelotEPSRenderRegion::GetValidPathAttributes();
01874 }
01875 
01876 
01877 void NativeRenderRegion::GetValidTransparencyAttributes()
01878 {
01879     // Find out what this render region can do.
01880     RRCaps Caps;
01881     GetRenderRegionCaps(&Caps);
01882 
01883     // Can we do transparency?
01884     if (!Caps.Transparency)
01885         // No - so don't do anything
01886         return;
01887 
01888     KernelDC *pDC = (KernelDC*)CCDC::ConvertFromNativeDC(RenderDC);
01889 
01890     if (SetLastOutputAttribute(ATTR_STROKETRANSP))
01891     {
01892         // Now do the line transparency
01893         StrokeTranspAttribute *pAttr = 
01894             (StrokeTranspAttribute *) CurrentAttrs[ATTR_STROKETRANSP].pAttr;
01895 
01896         UINT32 Transp = *pAttr->GetStartTransp();
01897         UINT32 TranspType = pAttr->GetTranspType();
01898         
01899         TRACEUSER( "Will", _T("Outputing Line transp, Val=%d, Type=%d\n"),Transp, TranspType);
01900 
01901         // Output transparency level
01902         pDC->OutputValue((UINT32) Transp);
01903         // Output transparency type...
01904         pDC->OutputValue((UINT32) TranspType);
01905 
01906         pDC->OutputToken(_T("cst"));
01907         pDC->OutputNewLine();
01908     }
01909 
01910     if (SetLastOutputAttribute(ATTR_TRANSPFILLGEOMETRY))
01911     {
01912         // Now do the transparent fill geometry
01913         TranspFillAttribute *pFillAttr = 
01914             (TranspFillAttribute *) CurrentAttrs[ATTR_TRANSPFILLGEOMETRY].pAttr;
01915 
01916         // Get the transparency information
01917         UINT32 *StartTransp,
01918              *EndTransp,
01919              TranspType,
01920              FillType = TRANSPFILL_NONE;
01921 
01922         TranspType = pFillAttr->GetTranspType();        //pPaintMode->m_PaintingMode;
01923         ENSURE((TranspType >= 1) && (TranspType <= 3), "Bad transparency type!");       // Deliberately restrictive?
01924 
01925         StartTransp = pFillAttr->GetStartTransp();
01926         ENSURE((StartTransp == NULL) || ((*StartTransp >= 0) && (*StartTransp <= 255)), 
01927                "Bad start transparency level!");
01928 
01929         // Get the correct brush - may be a grad fill.
01930         if (pFillAttr->IsKindOf(CC_RUNTIME_CLASS(FlatTranspFillAttribute)))
01931         {
01932             // Check special case for 'no transparency' (0% transparent and type 1)
01933             if (((*StartTransp) != 0) || (TranspType != TT_Mix))
01934                 FillType = TRANSPFILL_FLAT;
01935         }
01936         else if (pFillAttr->IsKindOf(CC_RUNTIME_CLASS(GradTranspFillAttribute)) && 
01937                  !pFillAttr->IsKindOf(CC_RUNTIME_CLASS(BitmapTranspFillAttribute)) )
01938         {
01939             // Output the start and end points of the grad fill
01940             DocCoord *Point;
01941             Point = pFillAttr->GetStartPoint();
01942             pDC->OutputCoord(*Point);
01943             Point = pFillAttr->GetEndPoint();
01944             pDC->OutputCoord(*Point);
01945 
01946             // Output the fill type
01947             if (pFillAttr->IsKindOf(CC_RUNTIME_CLASS(LinearTranspFillAttribute)))
01948             {
01949                 DocCoord* Start = pFillAttr->GetStartPoint();
01950                 DocCoord* End   = pFillAttr->GetEndPoint();
01951                 DocCoord* End2  = pFillAttr->GetEndPoint2();
01952 
01953                 if (AreLinesPerpendicular(Start, End, End2))
01954                 {
01955                     TRACEUSER( "Will", _T("Exporting Simple Transp Linear Fill\n"));
01956                     FillType = TRANSPFILL_LINEAR;
01957                 }
01958                 else
01959                 {
01960                     TRACEUSER( "Will", _T("Exporting New Style Transp Linear Fill\n"));
01961                     pDC->OutputCoord(*pFillAttr->GetEndPoint2());
01962                     FillType = TRANSPFILL_NEWLINEAR;
01963                 }
01964             }
01965             else if (pFillAttr->IsKindOf(CC_RUNTIME_CLASS(RadialTranspFillAttribute)))
01966             {
01967                 // Is it circular or elliptical?
01968                 RadialTranspFillAttribute *pRadialFillAttr = 
01969                     (RadialTranspFillAttribute *) pFillAttr;
01970 
01971                 if (pRadialFillAttr->IsElliptical())
01972                 {
01973                     // Elliptical fill - output the second end point.
01974                     Point = pRadialFillAttr->GetEndPoint2();
01975                     pDC->OutputCoord(*Point);
01976                     FillType = TRANSPFILL_ELLIPTICAL;
01977                 }
01978                 else
01979                 {
01980                     // Circular fill
01981                     FillType = TRANSPFILL_CIRCULAR;
01982                 }
01983             }
01984             else if (pFillAttr->IsKindOf(CC_RUNTIME_CLASS(ConicalTranspFillAttribute)))
01985             {
01986                 FillType = TRANSPFILL_CONICAL;
01987             }
01988             else
01989             {
01990                 // Unknown fill type - fall back to basic attributes.
01991                 ERROR3("Unsupported grad fill encountered while exporting");
01992                 EPSRenderRegion::GetValidPathAttributes();
01993                 return;
01994             }
01995 
01996         }
01997         else if (pFillAttr->IsKindOf(CC_RUNTIME_CLASS(FractalTranspFillAttribute)) &&
01998                  Caps.BitmapFills)
01999         {
02000             // Fractal fill - output fractal fill command...
02001             FractalTranspFillAttribute *pFractalFill = (FractalTranspFillAttribute *) pFillAttr;
02002 
02003             // Save the coords of the fill mesh
02004             pDC->OutputCoord(pFractalFill->StartPoint);
02005             pDC->OutputCoord(pFractalFill->EndPoint);
02006             pDC->OutputCoord(pFractalFill->EndPoint2);
02007 
02008             // Save the fractal parameters out.
02009             pDC->OutputValue(pFractalFill->Seed);
02010             pDC->OutputReal(pFractalFill->Graininess.MakeDouble());
02011             pDC->OutputReal(pFractalFill->Gravity.MakeDouble());
02012             pDC->OutputReal(pFractalFill->Squash.MakeDouble());
02013 
02014             // And now the DPI of the fractal bitmap
02015             UINT32 DPI = pFractalFill->GetFractalDPI();
02016             pDC->OutputValue(DPI);
02017 
02018             // And now the 'tileable' flag
02019             pDC->OutputValue((INT32) (pFractalFill->GetTileable()));
02020 
02021             // Always Fractal type 1 at present
02022             pDC->OutputToken(_T("1"));
02023 
02024             TRACEUSER( "Will", _T("Exporting new fractal transp\n"));
02025             
02026             // This is a fractal fill
02027             FillType = TRANSPFILL_NEWFRACTAL;
02028         }
02029         else if (pFillAttr->IsKindOf(CC_RUNTIME_CLASS(NoiseTranspFillAttribute)))
02030         {
02031             FillType = TRANSPFILL_NONE;
02032         }
02033         else if (pFillAttr->IsKindOf(CC_RUNTIME_CLASS(BitmapTranspFillAttribute)) &&
02034                  Caps.BitmapFills)
02035         {
02036             // Texture fill - output texture fill command:
02037 //          BitmapFillAttribute *pBitmapFill = (BitmapFillAttribute *) pFillAttr;
02038 
02039             // Output the 3 fill points...
02040             DocCoord *Point;
02041             Point = pFillAttr->GetStartPoint();
02042             pDC->OutputCoord(*Point);
02043             Point = pFillAttr->GetEndPoint();
02044             pDC->OutputCoord(*Point);
02045             Point = pFillAttr->GetEndPoint2();
02046             pDC->OutputCoord(*Point);
02047 
02048             TRACEUSER( "Will", _T("Exporting new bitmap transp\n"));
02049 
02050             // This is a texture fill
02051             FillType = TRANSPFILL_NEWTEXTURE;
02052         }
02053         else
02054         {
02055             ERROR3("Illegal transparency fill type!");
02056         }
02057 
02058         // Output transparency levels...
02059         if (FillType != TRANSPFILL_NONE)
02060         {
02061             if ((FillType != TRANSPFILL_TEXTURE) && (FillType != TRANSPFILL_FRACTAL))
02062             {
02063                 // Output first transparency level
02064                 pDC->OutputValue((UINT32) (*StartTransp));
02065 
02066                 // Output second transparency level if there is one.
02067                 switch (FillType)
02068                 {
02069                     case TRANSPFILL_LINEAR:
02070                     case TRANSPFILL_ELLIPTICAL:
02071                     case TRANSPFILL_CIRCULAR:
02072                     case TRANSPFILL_CONICAL:
02073                     case TRANSPFILL_NEWLINEAR:
02074                     case TRANSPFILL_NEWTEXTURE:
02075                     case TRANSPFILL_NEWFRACTAL:
02076                         EndTransp = pFillAttr->GetEndTransp();
02077                         ENSURE((*EndTransp >= 0) && (*EndTransp <= 255), 
02078                                "Bad end transparency level!");
02079                         pDC->OutputValue((UINT32) (*EndTransp));
02080                         break;
02081 
02082                     default:
02083                         // This is a valid situation - no second transparency level.
02084                         break;
02085                 }
02086             }
02087 
02088             // Output transparency type...
02089             pDC->OutputValue((UINT32) TranspType);
02090         
02091         }
02092         
02093         // Output transparency fill type
02094         pDC->OutputValue((UINT32) FillType);
02095     
02096         // Output the transparent fill token
02097         pDC->OutputToken(_T("cxt"));
02098         pDC->OutputNewLine();
02099 
02100         // If this is a bitmap-based transprency fill, output the bitmap
02101         if ((FillType == TRANSPFILL_TEXTURE || FillType == TRANSPFILL_NEWTEXTURE) &&
02102              Caps.BitmapFills)
02103         {
02104             BitmapTranspFillAttribute *pBitmapFill = (BitmapTranspFillAttribute *) pFillAttr;
02105             ExportDC *pExportDC = (ExportDC *) pDC;
02106 
02107             if (pBitmapFill->GetBitmap())
02108                 pExportDC->GetParentFilter()->ExportBitmap(*pBitmapFill->GetBitmap());
02109         }
02110     }
02111 
02112     if (SetLastOutputAttribute(ATTR_TRANSPFILLMAPPING))
02113     {
02114         // Now do the chromatic fill mapping
02115         TranspFillMappingAttribute *pFillAttr = 
02116             (TranspFillMappingAttribute *) CurrentAttrs[ATTR_TRANSPFILLMAPPING].pAttr;
02117 
02118         // Get the correct mapping
02119         INT32 MappingType = pFillAttr->Repeat;
02120         ERROR3IF((MappingType < 1) || (MappingType > 3), "Illegal fill mapping value!");
02121         
02122         // Output fill mapping
02123         pDC->OutputValue((UINT32) MappingType);
02124 
02125         // Allow for future extension of fill mappings. 
02126         pDC->OutputToken(_T("0"));
02127 
02128         // Output the fill mapping token
02129         pDC->OutputToken(_T("cxmt"));
02130         pDC->OutputNewLine();
02131     }
02132 }
02133 
02134 
02135 
02136 
02137 
02138 /********************************************************************************************
02139 
02140 >   void NativeRenderRegion::GetValidTextAttributes()
02141 
02142     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
02143     Created:    18/05/95
02144     Purpose:    Output Native file compatible text attribute tokens.
02145 
02146 ********************************************************************************************/
02147 
02148 void NativeRenderRegion::GetValidTextAttributes()
02149 {
02150     KernelDC *pDC = (KernelDC*)CCDC::ConvertFromNativeDC(RenderDC);
02151 
02152     /* In native format documents we output 
02153         fontname            = <fontname> ctf
02154         fontsize            = <mp size> ctp
02155         bold                = <0|1> ctb
02156         italic              = <0|1> cti
02157         sub/superscript     = <abs mp rise> <abs mp pointsize> cts
02158         linespacing         = <absolute linespace> <0> ctls
02159                               <proportional linespace> <1> ctls
02160         
02161         all other styles are output by the baseclass
02162     */
02163 
02164     if (SetLastOutputAttribute(ATTR_TXTFONTTYPEFACE))
02165     {
02166         TxtFontTypefaceAttribute* pFontAttr = (TxtFontTypefaceAttribute*)CurrentAttrs[ATTR_TXTFONTTYPEFACE].pAttr;
02167         if (pFontAttr)
02168         {
02169             String_64 OutputFont;
02170             FontClass Class;
02171 
02172             CachedFontItem* pItem = FONTMANAGER->GetCachedFont(pFontAttr->HTypeface);
02173             ERROR3IF(pItem==NULL,"Cannot find the cached font in GetValidTextAttributes");
02174             OutputFont = *(pItem->GetFontName());
02175             Class = pItem->GetFontClass();
02176 
02177             // If we are not outputting true type fonts we need to output an
02178             // extension token to say, the next ctf on the input stream should be
02179             // treated as a FontClass type of font. This allows us to load back
02180             // ATM fonts which have the same name as true type fonts.
02181             if (Class!=FC_TRUETYPE)
02182             {
02183                 pDC->OutputValue((INT32)EOTAG_FONTTYPE);
02184                 pDC->OutputToken(_T("cso"));
02185                 pDC->OutputValue((INT32)Class);
02186                 pDC->OutputToken(_T("cftf"));
02187                 pDC->OutputToken(_T("ceo"));
02188                 pDC->OutputNewLine();
02189             }
02190 
02191             /*BOOL ok =*/ FONTMANAGER->GetFontName(pFontAttr->HTypeface, OutputFont);
02192             OutputFont.SwapChar(' ','-');
02193 
02194             pDC->OutputToken((TCHAR *)OutputFont);
02195             pDC->OutputToken(_T("ctf"));
02196             pDC->OutputNewLine();
02197 
02198             if ((pFontAttr->IsBold) || (pFontAttr->IsItalic))
02199             {
02200                 // font flags a bold or italic substyle.
02201 
02202                 pDC->OutputValue((INT32)EOTAG_FONTFLAGS);
02203                 pDC->OutputToken(_T("cso"));
02204                 pDC->OutputNewLine();
02205                 pDC->OutputToken(_T("cfft"));
02206                 pDC->OutputNewLine();
02207                 pDC->OutputToken(_T("ceo"));
02208                 pDC->OutputNewLine();
02209 
02210                 pDC->OutputValue((INT32) pFontAttr->IsBold);
02211                 pDC->OutputToken(_T("ctb"));
02212                 pDC->OutputNewLine();
02213 
02214                 pDC->OutputValue((INT32) pFontAttr->IsItalic);
02215                 pDC->OutputToken(_T("cti"));
02216                 pDC->OutputNewLine();
02217             }
02218         }
02219     }
02220 
02221     if (SetLastOutputAttribute(ATTR_TXTFONTSIZE))
02222     {
02223         // Output the fontsize next
02224         pDC->OutputValue(RR_TXTFONTSIZE());
02225         pDC->OutputToken(_T("ctp"));
02226         pDC->OutputNewLine();
02227     }        
02228 
02229     if (SetLastOutputAttribute(ATTR_TXTBOLD))
02230     {
02231         // read the bold attribute value explicitly (dont use RR_TXTBOLD)
02232         BOOL Bold = ( (TxtBoldAttribute*)(CurrentAttrs[ATTR_TXTBOLD].pAttr) )->BoldOn; 
02233         pDC->OutputValue((INT32)Bold);
02234         pDC->OutputToken(_T("ctb"));
02235         pDC->OutputNewLine();
02236     }        
02237 
02238     if (SetLastOutputAttribute(ATTR_TXTITALIC))
02239     {
02240         // read the italic attribute value explicitly (dont use RR_TXTITALIC)
02241         BOOL Italic =  ( (TxtItalicAttribute*)(CurrentAttrs[ATTR_TXTITALIC].pAttr) )->ItalicOn;
02242         pDC->OutputValue((INT32)Italic);
02243         pDC->OutputToken(_T("cti"));
02244         pDC->OutputNewLine();
02245     }       
02246 
02247     if (SetLastOutputAttribute(ATTR_TXTSCRIPT))
02248     {
02249         TxtScriptAttribute* pScript = RR_TXTSCRIPT();
02250 
02251         double FontSize = (double)RR_TXTFONTSIZE();         // in millipoints
02252         double offset = (pScript->Offset).MakeDouble();
02253         double size = (pScript->Size).MakeDouble();
02254 
02255         MILLIPOINT rise = (MILLIPOINT)(FontSize*offset);    // rise in millipoints
02256         MILLIPOINT ptsize = (MILLIPOINT)(FontSize*size);    // pointsize in millipoints
02257         pDC->OutputValue(rise);
02258         pDC->OutputValue(ptsize);
02259         pDC->OutputToken(_T("cts"));
02260         pDC->OutputNewLine();
02261     }
02262 
02263     // output proportional or none proportional line spacing
02264     if (SetLastOutputAttribute(ATTR_TXTLINESPACE))
02265     {
02266         TxtLineSpaceAttribute* pLineSpace = (TxtLineSpaceAttribute*)(CurrentAttrs[ATTR_TXTLINESPACE].pAttr);
02267 
02268         // There are some rules for reading the linespacing value which I shall divulge
02269         // If IsARatio is true then use the proportinal linespacing value.
02270         // else use the absolute linespacing
02271         // However if the absolute linespacing is zero, then we MUST use the proportional
02272         // linespacing. Eeek!
02273         // ie it is an error if (absolute==0 && !IsARatio()) which we will check for here
02274 
02275         if (!pLineSpace->IsARatio())
02276         {
02277             INT32 LineSpace = pLineSpace->Value;
02278             ERROR3IF(LineSpace==0, "Absolute line spacing is zero yet IsARatio() is FALSE, in GetValidTextAttributes()");
02279             pDC->OutputValue(LineSpace);
02280             pDC->OutputValue((INT32)0);
02281         }
02282         else
02283         {
02284             double Ratio = (pLineSpace->Ratio).MakeDouble();
02285             pDC->OutputFloat(Ratio,4);
02286             pDC->OutputValue((INT32)1);      
02287         }
02288 
02289         pDC->OutputToken(_T("ctls"));
02290         pDC->OutputNewLine();
02291     }
02292 
02293 
02294     // Handle all other types
02295     EPSRenderRegion::GetValidTextAttributes();
02296 }
02297 
02298 
02299 /********************************************************************************************
02300 
02301 >   BOOL NativeRenderRegion::RenderChar(WCHAR ch, Matrix* pMatrix)
02302 
02303     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
02304     Created:    25/05/95
02305     Inputs:     ch      - unicode value of TCHAR
02306                 pMatrix - matrix specifying transforms to place TCHAR correctly in document
02307     Returns:    FALSE if fails
02308     Purpose:    
02309 
02310 ********************************************************************************************/
02311 
02312 BOOL NativeRenderRegion::RenderChar(WCHAR ch, Matrix* pMatrix)
02313 {
02314     // If we are not drawing complex shapes and this shape is, then return
02315     if ((!RenderComplexShapes) && (TestForComplexShape(&Caps)))
02316         return TRUE;
02317 
02318     ERROR2IF(   this==NULL,FALSE,"RenderRegion::RenderChar() - this==NULL");
02319     ERROR2IF(pMatrix==NULL,FALSE,"RenderRegion::RenderChar() - pMatrix==NULL");
02320 
02321 #if EXPORT_TEXT
02322     // Check for changed attributes
02323     GetValidPathAttributes();
02324     GetValidTextAttributes();
02325 
02326     KernelDC *pDC = (KernelDC*)CCDC::ConvertFromNativeDC(RenderDC);
02327 
02328     INT32 CharOut = (INT32)ch;
02329     INT32 NumCodes = 1;
02330     pDC->OutputValue(CharOut);
02331     pDC->OutputValue(NumCodes);
02332     pDC->OutputToken(_T("ctx"));
02333     pDC->OutputNewLine();
02334 
02335 #else
02336     // just do what RenderRegion::RenderChar() would do!
02337 
02338     // create the TCHAR's path
02339     Path* pCharPath=CreateCharPath(ch,pMatrix);
02340     if (pCharPath==NULL)
02341         return FALSE;
02342 
02343     // draw path using current attibutes in render region
02344     if (pCharPath->GetNumCoords()!=0)
02345         DrawPath(pCharPath);
02346 
02347     // clean up
02348     delete pCharPath;
02349 #endif
02350 
02351     return TRUE;
02352 }
02353 
02354 
02355 /********************************************************************************************
02356 
02357 >   virtual BOOL NativeRenderRegion::WriteFileVersion(KernelDC *pDC)
02358 
02359     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
02360     Created:    29/05/95
02361     Inputs:     pDC - the device context to output to.
02362     Outputs:    -
02363     Returns:    TRUE if ok;
02364                 FALSE if error (e.g. file/disk error)
02365     Purpose:    This allows the filter to save out a comment line giving file version
02366                 information. In this Native format version we actually write out the current
02367                 file version information.
02368     SeeAlso:    EPSRenderRegion::WriteSetup
02369 
02370 ********************************************************************************************/
02371 BOOL NativeRenderRegion::WriteFileVersion(KernelDC *pDC)
02372 {
02373     // Buffer used to build up the file version comment.
02374     TCHAR buf[50];
02375 
02376     // Output the current file version in the format 1.00 for NativeFileVersion 100
02377     camSprintf(buf, _T("%%%%File version: %.2f"), WriteNativeVersion);
02378     pDC->OutputToken(buf);
02379     pDC->OutputNewLine();
02380 
02381     return TRUE;
02382 }
02383     
02384 /********************************************************************************************
02385 
02386 >   BOOL NativeRenderRegion::WriteCompressionState(KernelDC *pDC)
02387 
02388     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
02389     Created:    19/05/95
02390     Inputs:     pDC - the device context to output to.
02391     Outputs:    -
02392     Returns:    TRUE if ok;
02393                 FALSE if error (e.g. file/disk error or printer driver error)
02394     Purpose:    In this native file saving class version we save out the compression status
02395                 of this file with other useful compression type information. We also start
02396                 compressing the data from this point onwards.
02397     SeeAlso:    EPSRenderRegion::WriteSetup
02398 
02399 ********************************************************************************************/
02400 
02401 BOOL NativeRenderRegion::WriteCompressionState(KernelDC *pDC)
02402 {
02403 TRACEUSER( "Neville", _T("WriteCompressionState\n"));
02404 
02405     // If the preference is set then compress the file, otherwise do nothing
02406     if (CamelotNativeEPSFilter::GetNativeCompression())
02407     {
02408         // Get a pointer to the CCDiskFile object
02409         EPSExportDC *pEPSDC = (EPSExportDC *) pDC;
02410         if (pEPSDC == NULL || ExportFile == NULL)
02411             return FALSE;
02412 
02413         // First, see if we have enough memory to start up the compression system
02414         BOOL Ok = pEPSDC->ExportFile->InitCompression();
02415         // If this fails then don't try anything
02416         if (!Ok)
02417         {
02418             // Flag that we have not started up the compressor ok.
02419             // Do not try and save out the end compression tokens.
02420             CompressionInitedOk = FALSE;
02421 
02422             return FALSE;
02423         }
02424 
02425         // Flag that we have started up the compressor ok.
02426         // We can write out the end compression bits
02427         CompressionInitedOk = TRUE;
02428 
02429         // Could require some compression here...
02430         pDC->OutputToken(_T("%%Compression: "));
02431         // The compression type that we are using.
02432         pDC->OutputToken(_T("0 "));
02433         pDC->OutputNewLine();
02434         // Output an extra line to sync to 
02435         pDC->OutputToken(_T("%%Compression info:"));
02436 
02437         // Write a very simple .gz header:
02438         // Just output the two magic numbers plus a status word plus a flags word
02439         // We must output text rather than numbers and must never output LF or CR in the
02440         // middle as this will screw the lexer
02441         double StreamVersion = GZipFile::GetStreamVersionNo();
02442         TCHAR buf[300];
02443         camSprintf(buf, _T(" %.2fD"), StreamVersion);   // version in form 0.92 followed by D for deflated
02444         pDC->OutputToken(buf);
02445 TRACEUSER( "Neville", _T("WriteCompressionState wrote version %.2f\n"),StreamVersion); 
02446         pDC->OutputNewLine();
02447 
02448         // Now that we have written out compression token to say that this is a compressed file,
02449         // start up the file compression.
02450         // This will write out some useful data such as compressed file version
02451         pEPSDC->ExportFile->SetCompression(TRUE);
02452     }
02453 
02454     return TRUE;
02455 }
02456 
02457 /********************************************************************************************
02458 
02459 >   virtual BOOL NativeRenderRegion::WriteEndCompressionState(KernelDC *pDC)
02460 
02461     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
02462     Created:    22/05/95
02463     Inputs:     pDC - the device context to output to.
02464     Outputs:    -
02465     Returns:    TRUE if ok;
02466                 FALSE if error (e.g. file/disk error or printer driver error)
02467     Purpose:    This is called once everything has been output and before we fix the EPS
02468                 header.
02469                 In this baseclass version we do nothing as compression would be a very bad
02470                 thing.
02471     SeeAlso:    EPSRenderRegion::WriteSetup
02472 
02473 ********************************************************************************************/
02474 
02475 BOOL NativeRenderRegion::WriteEndCompressionState(KernelDC* pDC)
02476 {
02477 TRACEUSER( "Neville", _T("WriteEndCompressionState\n"));
02478 
02479     // If the preference is set then compress the file, otherwise do nothing
02480     // Check though that the compressor started up ok.
02481     if (CamelotNativeEPSFilter::GetNativeCompression() && CompressionInitedOk)
02482     {
02483         // Could require some compression ending here...
02484         pDC->OutputToken(_T("%%EndCompression: "));
02485         pDC->OutputNewLine();
02486         // Output an extra line to sync to 
02487         pDC->OutputToken(_T("%%EndCompressionInfo: "));
02488         pDC->OutputNewLine();
02489 
02490         // Now that we have written out compression token to say that this is a compressed file,
02491         // start up the file compression.
02492         // This will output some useful data such as a crc check and amoutn written
02493         // Get a pointer to the CCDiskFile object
02494         EPSExportDC *pEPSDC = (EPSExportDC *) pDC;
02495         if (pEPSDC && ExportFile)
02496             pEPSDC->ExportFile->SetCompression(FALSE);
02497     }
02498     
02499     return TRUE;
02500 }
02501 
02502 
02503 
02504 
02505 
02506 /********************************************************************************************
02507 
02508 >   virtual BOOL NativeRenderRegion::WantsGrids()
02509 
02510     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
02511     Created:    12/12/95
02512     Returns:    TRUE
02513     Purpose:    This function is designed to help with the rendering of grids, as they are
02514                 not always wanted (eg xara eps). If your class of render region does not
02515                 want grids to appear, then overide this function and get it to return FALSE.
02516                 The default behaviour is to return TRUE, which will allow grids to render
02517                 if they want to.
02518 
02519 ********************************************************************************************/
02520 
02521 BOOL NativeRenderRegion::WantsGrids()
02522 {
02523     return TRUE;
02524 }
02525 
02526 
02527 /********************************************************************************************
02528 
02529 >   virtual void NativeRenderRegion::OutputFillColour()
02530 
02531     Author:     Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
02532     Created:    30/01/01
02533     Purpose:    Used to output fill colours (in any colour model). Since the CorelXara 
02534                 pre-1.5 format can only cope with CMYK colours (not RGB ones), we export 
02535                 the colour as CMYK, regardless of the colour model used.
02536 
02537 ********************************************************************************************/
02538 
02539 void NativeRenderRegion::OutputFillColour ()
02540 {
02541     OutputFillCMYKColour ();
02542 }
02543 
02544 
02545 /********************************************************************************************
02546 
02547 >   virtual void NativeRenderRegion::OutputStrokeColour()
02548 
02549     Author:     Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
02550     Created:    30/01/01
02551     Purpose:    Used to output stroke colours (in any colour model). Since the CorelXara 
02552                 pre-1.5 format can only cope with CMYK colours (not RGB ones), we export 
02553                 the colour in CMYK format, regardless of the colour model used..
02554 
02555 ********************************************************************************************/
02556 
02557 void NativeRenderRegion::OutputStrokeColour ()
02558 {
02559     OutputStrokeCMYKColour ();
02560 }
02561 
02562 
02563 /********************************************************************************************
02564 
02565 >   virtual BOOL NativeRenderRegion::OutputGradFillColours (DocColour* StartCol, DocColour* EndCol, ColourContext* pContext)
02566 
02567     Author:     Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
02568     Created:    30/01/01
02569     Inputs:     See CamelotEPSRenderRegion (they're identical)
02570     Purpose:    Used to output gradient fill colours, using the CMYK clour model. This is
02571                 necessary, as the standard EPS export uses RGB colours for gradient fills,
02572                 which pre-1.5 CorelXara doesn't understand.
02573 
02574 ********************************************************************************************/
02575 
02576 BOOL NativeRenderRegion::OutputGradFillColours(DocColour* StartCol, DocColour* EndCol, ColourContext* pContext)
02577 {
02578     KernelDC *pDC = (KernelDC*)CCDC::ConvertFromNativeDC(RenderDC);
02579     bool outputNames = FALSE;
02580 
02581     if ((StartCol->FindParentIndexedColour() == NULL) &&
02582         (EndCol->FindParentIndexedColour() == NULL))
02583     {
02584         // Neither colour is named...use unnamed colour syntax.
02585         outputNames = FALSE;
02586     }
02587     else
02588     {
02589         // One or two of the colours are named, so use the named colour syntax.
02590         outputNames = TRUE;
02591     }
02592 
02593     // Start writing stuff to the EPS file.
02594     PColourCMYK CMYK;
02595 
02596     // Write out the start colour
02597     StartCol->GetCMYKValue (pContext, &CMYK);
02598     pDC->OutputColour (&CMYK);
02599 
02600     if (outputNames)
02601     {
02602         // Write out the name
02603         pDC->OutputColourName (StartCol);
02604 
02605         // Write out the tint value. This isn't actually used at the moment, but is left 
02606         //  for possible future expansion
02607         pDC->OutputValue ((INT32)0);
02608     }
02609 
02610     // And the End colour.
02611     EndCol->GetCMYKValue (pContext, &CMYK);
02612     pDC->OutputColour (&CMYK);
02613 
02614     if (outputNames)
02615     {
02616         // Write out the name
02617         pDC->OutputColourName (EndCol);
02618 
02619         // Write out the tint value. This isn't actually used at the moment, but is left 
02620         //  for possible future expansion
02621         pDC->OutputValue ((INT32)0);
02622     }
02623 
02624     // Return TRUE for no names used, FALSE for names used.
02625     return (!outputNames);
02626 }
02627 
02628 
02629 
02630 
02631 /********************************************************************************************
02632 
02633 >   NativeExportDC::NativeExportDC(Filter* pFilter)
02634 
02635     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
02636     Created:    19/12/94
02637     Inputs:     pFilter
02638     Purpose:    Constructor for the NativeExportDC. This does nothing, except call the base
02639                 class constructor.
02640 
02641 ********************************************************************************************/
02642 
02643 NativeExportDC::NativeExportDC(Filter* pFilter) : EPSExportDC(pFilter)
02644 {
02645 }
02646 
02647 
02648 
02649 /********************************************************************************************
02650 
02651 >   virtual INT32 NativeExportDC::OutputRawBinary(BYTE* Data, UINT32 Length, UINT32 Alignment=1)
02652 
02653     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
02654     Created:    19/12/94
02655     Inputs:     Data - pointer to the data to output.
02656                 Length - the number of bytes to output.
02657                 Alignment - the byte alignment to use - it will pad the end of
02658                             the data with 0 bytes if Length is not divisible by
02659                             this parameter.  Hence use 1 for no padding.
02660     Returns:    The number of bytes output to the file, in terms of the source data, not
02661                 in terms of the number of ASCII characters used to represent them.
02662                 -1 => error occured while writing => ERROR1
02663     Purpose:    Outputs a sequence of bytes as raw data
02664     Errors:     Disk/file error => ERROR1
02665 
02666 ********************************************************************************************/
02667 
02668 INT32 NativeExportDC::OutputRawBinary(BYTE* Data, UINT32 Length, UINT32 Alignment)
02669 {
02670     // Param to note how many bytes we are writing out to the file
02671     INT32 nBytes = 0;
02672 
02673     // Start off with a blank line
02674     if (!OutputNewLine())
02675         // Error encountered
02676         return -1;
02677 
02678     // Set the mode to binary
02679     //ExportFile.setMode(filebuf::binary);
02680 
02681     // Output a character to mark the begining of the binary section
02682     static TCHAR Begin = _T('>');
02683     if (!OutputTCHARAsChar(&Begin, 1))
02684         // Error
02685         return -1;
02686 
02687     // Output the line of binary data
02688     if (!OutputDirect(Data, Length))
02689     {
02690         // Error
02691         return -1;
02692     }
02693     
02694     // We saved out 'Length' bytes there
02695     nBytes += Length;
02696 
02697     // Work out the padding needed
02698     ENSURE(Alignment != 0, "Bad alignment in OutputRawBinary!");
02699     UINT32 Padding = Alignment - (Length % Alignment);
02700     if (Padding == Alignment)
02701         Padding = 0;
02702 
02703     if (Padding > 0)
02704     {
02705         // Put the string  into a Buffer
02706         TCHAR Buffer[2];
02707         Buffer[0] = 0;
02708         Buffer[1] = 0;
02709 
02710         // Output it however many times we need to
02711         while (Padding > 0)
02712         {
02713             if (OutputTCHARAsChar(Buffer, 1))
02714                 // Error
02715                 return -1;
02716 
02717             nBytes++;
02718             Padding--;
02719         }
02720     }
02721 
02722     //output an end marker
02723     static TCHAR End = _T('<');
02724     if (!OutputTCHARAsChar(&End, 1))
02725         // Error
02726         return -1;
02727         
02728     // Set the mode to binary
02729     //ExportFile.setMode(filebuf::text);
02730 
02731     // All done
02732     return nBytes;
02733 }
02734 
02735 #endif // EXCLUDE_FROM_RALPH

Generated on Sat Nov 10 03:45:45 2007 for Camelot by  doxygen 1.4.4