AIEPSRenderRegion Class Reference

A render region for exporting EPS files in Adobe Illustrator 7.0 EPS format. More...

#include <ai_epsrr.h>

Inheritance diagram for AIEPSRenderRegion:

EPSRenderRegion VectorFileRenderRegion RenderRegion ListItem CCObject SimpleCCObject List of all members.

Public Member Functions

 AIEPSRenderRegion (DocRect ClipRect, Matrix ConvertMatrix, FIXED16 ViewScale)
 Create and initialise a render region for exporting AI EPS. Sets up the string to put in the %Creator comment.
 ~AIEPSRenderRegion ()
BOOL ExportBitmap (NodeBitmap *pNodeBMP)
 Kicks off the NodeBitmap export process..
BOOL ExportBevel (NodeBevel *pBevel)
 Renders a bevel into a DIB, and exports this as a bitmap to the AI file.
BOOL ExportShadow (OILBitmap *pBitmap, UINT32 Darkness, DocRect &Bounds)
 Renders a shadow into a DIB, and exports this as a bitmap to the AI file.
BOOL ExportLayer (Layer *pLayer)
 If there is an existing layer, it writes the end of layer tags, before creating a new layer record.
BOOL StartLayer (Layer *pLayer)
 Writes a layer record to the file.
virtual BOOL RenderChar (WCHAR ch, Matrix *pMatrix)
 Overrides the default behaviour for rendering a single character. Used to store additional information on text blocks needed for AI text. i.e. the overflow text block ((xxxxxxxxx) TX) which occurs after the unjustified ((x) Tx
(x) Tx
) block. Both of these are needed for correct Illustrator export of text.
BOOL ExportingOnPath ()
 To determine whether this text is being exported on a path.
virtual void OverflowTextStart ()
 Start the overflow text block.
virtual void OverflowTextFinish ()
 Finish the overflow text block and write both blocks to the actual EPS file.
BOOL WriteMask (Path *MaskPath, BOOL OutputGroupToken=FALSE)
 Creates a path that defines a masking pattern. All successive paths (until the end of mask operator) will be clipped to this shape.
virtual void SetClipRegion (ClipRegionAttribute *pClipAttr, BOOL Temp)
 The Adobe Illustrator version of Karim's EPSRenderRegion::SetClipRegion, This was needed as Illustrator uses non-standard EPS commands.
virtual void RestoreClipRegion (ClipRegionAttribute *pClipAttr, BOOL Temp)
 Adobe Illustrator version of Karim's EPSRenderRegion::RestoreClipRegion. See SetClipRegion for why this was necessary.
virtual void SetTextAsShapes (BOOL shapes)
 Sets the export TextAsShapes flag.
virtual BOOL GetTextAsShapes ()
 Sets the export TextAsShapes flag.
virtual BOOL IsGradientFillValidForExport (FillGeometryAttribute *pFill)
 Determines whether a particular fill can be used through the AI export See also: AIEPSRenderRegion::WriteGradientFills, AIEPSRenderRegion::WriteGradientUsage.
virtual void IncludeGradientFill (FillGeometryAttribute *pFill, EFFECTTYPE effect)
 Stores information about a fill so that the same fill isn't declared multiple times. See also: AIEPSRenderRegion::WriteGradientFills, AIEPSRenderRegion::WriteGradientUsage, AIEPSRenderRegion::FindGradientInCache.

Protected Member Functions

virtual void Initialise ()
 Sets up render region - it outputs the AIEPS file header comments, and intialises the rendering attributes.
virtual BOOL WriteEPSVersion ()
 Writes the relevant EPS version declaration.
virtual BOOL WriteEPSProcessColours ()
 Writes the colour type used to disk.
virtual BOOL WriteEPSResources (EPSFilter *pFilter, Document *pDocument)
 This function writes out the resource inclusion string required for the AI file.
virtual BOOL WriteEPSProlog (EPSFilter *pFilter, Document *pDocument)
 This method writes out the initialisation code for the included resources.
virtual void OutputFillColour (void)
 If the fill is a gradient fill, this method will invoke the WriteGradientFillInstance method, otherwise it will call the base EPSRenderRegion OutputFillColour method. This allows Camelot to support gradient fills in the AI file format.
virtual BOOL WriteGradientFills (Document *pDocument)
 Parses through the tree, identifies any gradient fills, and writes them to the export DC's file.
virtual BOOL WriteDocumentSetup (Document *pDocument, EPSFilter *pFilter)
 Browse through the tree, and if a text story is found invoke the document setup function. By only exporting the font setup when necessary, the file size produced is smaller (which makes it easier for me to interpret :) ), and it should hopefully make the filter run a bit faster too.
virtual BOOL EndLayer (void)
 If there is an existing layer, it writes the end of layer tags, before creating a new layer record.
virtual void OutputWindingRule ()
 Output the winding rule used to AI EPS.
virtual void OutputStrokeColour ()
 Output the current stroke colour. This function will use one of the following EPS tokens K - if not separating and colour is unnamed X - if not separating and colour is named G - if separating.
virtual void OutputLineWidth ()
 Output the standard line width token and measure for AI EPS.
virtual void OutputJoinType ()
 Output the standard AI EPS join type.
virtual void OutputDashPattern ()
 Outputs EPS dash pattern values. This function currently only exists so that extra handling can be easily achieved for Illustrator EPS export of dash patterns in the future (if need be).
virtual void OutputStartCap ()
 Output the start cap setting using the usual 'J' EPS token.
virtual void OutputMitreLimit ()
 Output the current mitre limit value using the usual 'M' EPS token. Again, this is only here so that the AI export can be easily expanded or modified.
virtual void OutputFontName ()
 Output an Illustrator format fontname and pointsize token. The format is /_fontname[-Bold|-Italic|-BoldItalic] pointsize Tf. EncodeFontName will generate this format from an internal fontname. DocodeFontName will return an internal format fontname and flags where nec.
virtual void OutputTextRenderMode ()
 Output the change in the text's Render Mode (Tr) - this happens when the text's fill or line colour changes to or from blank, see-through colour.
virtual void OutputTextAspectRatio ()
 Output the change in the text's aspect ratio (Tz).
virtual void OutputTextTracking ()
 Output the change in the tracking (Tt).
virtual void OutputTextJustification ()
 Output the change in the text justification (Ta).
virtual void OutputTextLineSpacing ()
 Output the change in the line spacing (Tl).
virtual void OutputTextBaselineShift ()
 Output the change in Baseline shift (Ts).
virtual void OutputTextSubSuperScript ()
 Output the change in the Sub/Super script attribute (Ts).
virtual void OutputFillRGBColour ()
 Writes additional info to the file for RGB fill colours See also: EPSRenderRegion::OutputFillRGBColour.
virtual void OutputFillCMYKColour ()
 Writes additional info to the file for CMYK fill colours See also: EPSRenderRegion::OutputFillCMYKColour.
virtual void OutputStrokeRGBColour ()
 Writes additional info to the file for RGB stroke colours See also: EPSRenderRegion::OutputStrokeRGBColour.
virtual void OutputStrokeCMYKColour ()
 Writes additional info to the file for CMYK fill colours See also: EPSRenderRegion::OutputFillCMYKColour.
virtual void OverflowTextStartGap ()
 Starts a new gap in the Overflow text, so that attributes can be written into the overflow blocks (the TX ones).
virtual void OverflowTextFinishGap ()
 Closes a gap for writing attributes in the overflow text, so that a new line of overflow text can be started.
virtual void OverflowTextWrite (TCHAR *text)
 Write some text to the overflow body file. This will store all the text and modified attributes for the TX text block.
virtual void OverflowTextWriteSingleColour (UINT32 n)
 Output a colour value to the overflow text file. A 'single colour' is a value as used in the Camelot 'Colour' class, i.e. in the range 0 to 255. This range is converted to the range 0.0 to 1.0, and output to the file.
virtual void OverflowTextWriteColour (PColourCMYK *)
 Output a colour, as expressed by the Camelot 'Colour' class. This function takes the CMYK variation, is this is most appropriate to EPS files. Camelot colour values are converted from the 0-255 range to the 0.0-1.0 range before being output.
virtual void OverflowTextWriteNamedColour (DocColour *, ColourContext *pContext=NULL)
 Similar to OutputColour(), except it outputs the colour name and tint of the colour as well. If pCol does not reference an indexed colour, then the name "NoName" is used.
virtual void OverflowTextWriteColourName (DocColour *pCol)
 Outputs a named colour's name as a string. If pCol does not reference an indexed colour, then the name "NoName" is used. This was seperated from OutputNamedColour so that the DeviceContext will not need to worry about which ColourModel to use (CMYK, RGB, etc...), as this will be determined by the RenderRegion.
virtual BOOL RenderCharAsShape (WCHAR ch, Matrix *pMatrix)
 Allows text to be drawn as shapes, not characters, so that AI can cope with gradient filled text.
virtual BOOL WriteNewLine (void)
 Writes a new line to the output of text if text is exported as characters, does nothing if it's exported as shapes.

Private Member Functions

virtual void BuildGradientCache (Node *pStartNode)
 Builds up a 'cache' of gradient fills.
virtual void BuildGradientCacheUsingScanner (Node *pNode, AIEPSGradientScanRenderRegion *pScan)
 Builds up the gradient cache by scanning through each node under pNode for new fills.
virtual void WriteGradientCount ()
 Writes out the count of all the gradient fills in the Cache.
virtual void WriteGradientDefinitions ()
 Writes out the definitions of all the gradient fills in the Cache.
virtual void ClearGradientCache ()
 Deletes the list of stored gradient fills, that was built up using IncludeGradientFill.
virtual INT32 FindGradientInCache (FillGeometryAttribute *pFill, EFFECTTYPE effect)
 Deletes the list of stored gradient fills, that was built up using IncludeGradientFill.
BOOL WriteLinearFill (FillGeometryAttribute *pFill, EFFECTTYPE effect, INT32 id)
 Writes a linear fill to the disk file.
BOOL WriteRadialFill (FillGeometryAttribute *pFill, EFFECTTYPE effect, INT32 id)
 Writes a Radial fill to the disk file.
virtual void WriteGradientFillInstance ()
 This function identifies whether or not the current fill is a gradient fill, and writes in the appropriate values if it is. I've already created the records of the gradients themselves (see above), so this is just a case of matching the gradient with its ID, and Adobe Illustrator can then put the records together.
BOOL WriteGradientEntry (DocColour *pColour, INT32 Position, INT32 Midpoint)
 Writes a line into the definition of a gradient fill.
BOOL WriteFillEffectSteps (DocColour *pColour1, INT32 pos1, DocColour *pColour2, INT32 pos2, INT32 bias, EFFECTTYPE effect)
 Writes the additional entries required for a special fill effect (rainbow or alt-rainbow) to the gradient definition, as a series of steps. See Also: AIEPSRenderRegion::WriteGradientEntry AIEPSRenderRegion::WriteLinearFill AIEPSRenderRegion::WriteRadialFill.
BOOL LoadBitmapMatrix (NodeBitmap *pNodeBMP)
 This code generates a matrix to position and manipulate a bitmap within an AI file. Roughly, it calculates the angle of rotation, followed by the skew angle, and creates a matrix using these values. See Also: FlashExportDC::WriteBitmapFill ().
BOOL LoadTranslationMatrix (DocCoord &Translation)
 Loads the matrix with:.
BOOL WriteLoadedMatrix (void)
 Writes a pre-loaded matrix to the file. I've added a couple of functions to create a matrix first, since it'll be more efficient to store the data, and re-write it as required, than to recalculate it twice.
BOOL WriteMaskTags (void)
 Writes out the tags at the end of each block of a mask's definition.
BOOL WriteBitmapRecord (OILBitmap *pBitmap)
 Creates a kernel bitmap instance within the AI file.
BOOL WriteBitmapHeader (INT32 Width, INT32 Height)
 Writes the AI header for a bitmap record.
BOOL WriteBitmapBody (OILBitmap *pBitmap, INT32 Width, INT32 Height)
 Writes the bitmap's data to the file.
BOOL WriteContoneBody (OILBitmap *pBitmap)
 Writes a contone bitmap to the file as a 32bpp image.
BOOL WriteBitmapTail (void)
 Wraps up the bitmap instance.

Private Attributes

ListFillm_pLinearGradList
ListFillm_pRadialGradList
double m_a
double m_b
double m_c
double m_d
DocCoord m_T
BOOL m_ActiveLayer
UINT32 m_LayerColour
FILE * m_fpOverflowText
BOOL m_bInTextGap
BOOL m_bTextAsShapes

Friends

class AIEPSGradientScanRenderRegion

Detailed Description

A render region for exporting EPS files in Adobe Illustrator 7.0 EPS format.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>, extended by Graeme
Date:
08/03/94
See also:
EPSRenderRegion

Definition at line 207 of file ai_epsrr.h.


Constructor & Destructor Documentation

AIEPSRenderRegion::AIEPSRenderRegion DocRect  ClipRect,
Matrix  ConvertMatrix,
FIXED16  ViewScale
 

Create and initialise a render region for exporting AI EPS. Sets up the string to put in the %Creator comment.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/3/00
See also:
EPSRenderRegion::EPSRenderRegion ()

Definition at line 145 of file ai_epsrr.cpp.

00148     : EPSRenderRegion ( ClipRect, ConvertMatrix, ViewScale )
00149 {
00150     // Set up member variables.
00151     m_a             = 1;
00152     m_b             = 0;
00153     m_c             = 0;
00154     m_d             = 1;
00155     m_T             = DocCoord ( 0, 0 );
00156     m_ActiveLayer   = FALSE;
00157     m_LayerColour   = 0;
00158 
00159     m_fpOverflowText    = NULL;
00160 
00161     m_bInTextGap        = FALSE;
00162     m_bTextAsShapes     = FALSE;
00163     
00164     m_pLinearGradList   = NULL;
00165     m_pRadialGradList   = NULL;
00166 
00167     // Initialise the creator string to show that it's an AI file.
00168     CreatorString = _T("Adobe Illustrator(TM) 7.0 by Xara.");
00169 }

AIEPSRenderRegion::~AIEPSRenderRegion  ) 
 

Definition at line 181 of file ai_epsrr.cpp.

00182 {
00183     ClearGradientCache ();
00184 }


Member Function Documentation

void AIEPSRenderRegion::BuildGradientCache Node pStartNode  )  [private, virtual]
 

Builds up a 'cache' of gradient fills.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/3/2001
Parameters:
pStartNode - the node to start looking from. [INPUTS]
See also: AIEPSRenderRegion::WriteGradientFills, AIEPSRenderRegion::WriteGradientDefinitions

Definition at line 3601 of file ai_epsrr.cpp.

03602 {
03603 //  Node * pChild   = NULL;
03604 
03605     // Set up the gradient searching system
03606     AIEPSGradientScanRenderRegion scanRR (this);
03607     scanRR.AttachDevice (DocView::GetSelected (), RenderDC, RenderView->GetDoc()->FindFirstSpread ());
03608     scanRR.InitDevice ();
03609 
03610     // Although the counting system does return the number of fills found, it can be got from
03611     //  the scanner just as easily.
03612     BuildGradientCacheUsingScanner (pStartNode, &scanRR);
03613 }

void AIEPSRenderRegion::BuildGradientCacheUsingScanner Node pNode,
AIEPSGradientScanRenderRegion pScan
[private, virtual]
 

Builds up the gradient cache by scanning through each node under pNode for new fills.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/3/2001
Parameters:
pNode - the node to start looking from. [INPUTS] pScan - the scanner to use
See also: AIEPSRenderRegion::WriteGradientFills, AIEPSRenderRegion::WriteGradientDefinitions

Definition at line 3631 of file ai_epsrr.cpp.

03632 {
03633     // Children are rendered first, so that attributes will be applied to the right objects.
03634     Node * pChild = pNode->FindFirstChild ();
03635     while (pChild!=NULL)
03636     {
03637         BuildGradientCacheUsingScanner (pChild, pScan);
03638         pChild = pChild->FindNext ();
03639     }
03640 
03641     // "Render" the node into the scanner. Currently, rendering is the only way to access
03642     //  the intermediate steps (and their attributes) in blends, contours and some others, 
03643     //  so we need to use a special Render Region to catch the gradient (fill) information.
03644     //
03645     // NOTE: Since this uses the same system as the main render loop, it shouldn't be possible
03646     //  for the gradient cache and the main file to become out of sync. Also, bevels and 
03647     //  shadows are excluded, as they are rendered as bitmaps in AI export.
03648     if (!pNode->IsABevel () && !pNode->IsAShadow ())
03649         pNode->Render (pScan);
03650 }

void AIEPSRenderRegion::ClearGradientCache  )  [private, virtual]
 

Deletes the list of stored gradient fills, that was built up using IncludeGradientFill.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/3/2001
See also: AIEPSRenderRegion::IncludeGradientFill, AIEPSRenderRegion::FindGradientInCache

Definition at line 3495 of file ai_epsrr.cpp.

03496 {
03497     ListFill * pList = NULL;
03498 
03499     // only clear it if there is a list to clear
03500     if (m_pLinearGradList)
03501     {
03502         // Cycle through the linear list deleting each item in turn.
03503         while (m_pLinearGradList != NULL)
03504         {
03505             pList = m_pLinearGradList->pNext;
03506             delete m_pLinearGradList;
03507             m_pLinearGradList = pList;
03508         }
03509     }
03510 
03511     if (m_pRadialGradList)
03512     {
03513         // Cycle through the radial list deleting each item in turn.
03514         while (m_pRadialGradList != NULL)
03515         {
03516             pList = m_pRadialGradList->pNext;
03517             delete m_pRadialGradList;
03518             m_pRadialGradList = pList;
03519         }
03520     }
03521 }

BOOL AIEPSRenderRegion::EndLayer void   )  [protected, virtual]
 

If there is an existing layer, it writes the end of layer tags, before creating a new layer record.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/4/00
Parameters:
- [INPUTS]
Returns:
TRUE - Success. FALSE - An error occured.
See also:
AIEPSRenderRegion::ExportLayer ()

Reimplemented from EPSRenderRegion.

Definition at line 1219 of file ai_epsrr.cpp.

01220 {
01221     // Only act if there's an active layer.
01222     if ( m_ActiveLayer )
01223     {
01224         // Cast the RenderDC pointer into a useful form.
01225         KernelDC    *pDC    = static_cast<KernelDC *> ( CCDC::ConvertFromNativeDC(RenderDC) );
01226 
01227         // Write out the end of layer tag.
01228         pDC->OutputToken    ( _T("LB") );
01229         pDC->OutputNewLine  ();
01230         pDC->OutputToken    ( _T("%AI5_EndLayer") );
01231         pDC->OutputNewLine  ();
01232 
01233         // Set m_ActiveLayer to be FALSE.
01234         m_ActiveLayer = FALSE;
01235     }
01236 
01237     return TRUE;
01238 }

BOOL AIEPSRenderRegion::ExportBevel NodeBevel pBevel  ) 
 

Renders a bevel into a DIB, and exports this as a bitmap to the AI file.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
6/4/00
Parameters:
pBevel - A pointer to a bevel node. [INPUTS]
Returns:
TRUE - Success. FALSE - An error occured.
See also:
NodeBevel::ExportRender

Definition at line 228 of file ai_epsrr.cpp.

00229 {
00230     // Set up the local variables.
00231     KernelDC                *pDC            = static_cast<KernelDC *> ( CCDC::ConvertFromNativeDC(RenderDC) );
00232     RangeControl            ControlFlags    ( TRUE, TRUE );
00233     Range                   ToRender        ( pBevel, pBevel, ControlFlags );
00234     KernelBitmap            *pBitmap        = NULL;
00235     Path                    *pSourcePath    = &( pBevel->InkPath );
00236     DocRect                 Bounds          = pBevel->GetBoundingRect ();
00237     DocCoord                Position        ( Bounds.lo.x, Bounds.hi.y );
00238     double                  Width           = static_cast<double> ( Bounds.Width () );
00239     double                  Height          = static_cast<double> ( Bounds.Height () );
00240 
00241     // Create and render the bitmap.
00242     pBitmap = pBevel->CreateBitmapCopy(-1.0,FALSE);
00243 
00244     if(!pBitmap)
00245         return FALSE;
00246 
00247     // Get the width and height of the bitmap.
00248     double                  BMPWidth        = static_cast<double> ( pBitmap->GetWidth () );
00249     double                  BMPHeight       = static_cast<double> ( pBitmap->GetHeight () );
00250 
00251     // Write the path. (ChrisG 16/01/01) If we have one.
00252     if (pSourcePath->GetNumCoords () != 0)
00253     {
00254         WriteMask ( pSourcePath, TRUE );
00255     }
00256 
00257     // Set up the bitmap translation matrix.
00258     LoadTranslationMatrix ( Position );
00259 
00260     // Scale width and height to be valid value for AI co-ordinates.
00261     Width   /= 1000;
00262     Height  /= 1000;
00263     
00264     // And calcuate the scale values for placing the bitmap.
00265     m_a = Width  / BMPWidth;
00266     m_d = Height / BMPHeight;
00267 
00268     // Write the bitmap record.
00269     WriteBitmapRecord ( pBitmap->ActualBitmap );
00270 
00271     // Write the end of mask operator. (ChrisG 16/01/01) If we've written a mask.
00272     if (pSourcePath->GetNumCoords () != 0)
00273     {
00274         pDC->OutputToken    ( _T("Q") );
00275         pDC->OutputNewLine  ();
00276     }
00277 
00278     if(pBitmap)
00279     {
00280         pBitmap->DestroyGreyscaleVersion();
00281         delete pBitmap;
00282     }
00283 
00284     // Success!
00285     return TRUE;
00286 }

BOOL AIEPSRenderRegion::ExportBitmap NodeBitmap pNodeBMP  ) 
 

Kicks off the NodeBitmap export process..

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
31/3/00
Parameters:
pNodeBMP - A pointer to the NodeBitmap being exported. [INPUTS]
Returns:
TRUE - If successful. FALSE - If an error is encountered.
See also:
NodeBitmap::ExportRender ()

Definition at line 200 of file ai_epsrr.cpp.

00201 {
00202     // Set up the local variables.
00203     KernelBitmap    *pBitmap    = pNodeBMP->GetBitmap ();
00204 
00205     // Set up the bitmap's transformation matrix.
00206     LoadBitmapMatrix ( pNodeBMP );
00207 
00208     // Write out the bitmap record.
00209     WriteBitmapRecord ( pBitmap->GetActualBitmap () );
00210 
00211     return TRUE;
00212 }

BOOL AIEPSRenderRegion::ExportingOnPath  ) 
 

To determine whether this text is being exported on a path.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
2/11/00
Returns:
TRUE - yes, we are exporting on a path FALSE - no, we aren't exporting on a path
See also:

Definition at line 2578 of file ai_epsrr.cpp.

02579 {
02580     if (m_fpOverflowText)
02581         return TRUE;
02582     else
02583         return FALSE;
02584 }

BOOL AIEPSRenderRegion::ExportLayer Layer pLayer  ) 
 

If there is an existing layer, it writes the end of layer tags, before creating a new layer record.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/4/00
Parameters:
pLayer - A pointer to a layer object. [INPUTS]
Returns:
TRUE - Success. FALSE - An error occured.
See also:
AIEPSRenderRegion::EndLayer ()

Definition at line 358 of file ai_epsrr.cpp.

00359 {
00360     // Tidy up the existing layer, if it exists.
00361     EndLayer ();
00362 
00363     // And write out the next layer.
00364     return StartLayer ( static_cast<Layer*> ( pLayer->FindNext
00365                                               ( CC_RUNTIME_CLASS ( Layer ) ) ) );
00366 }

BOOL AIEPSRenderRegion::ExportShadow OILBitmap pBitmap,
UINT32  Darkness,
DocRect Bounds
 

Renders a shadow into a DIB, and exports this as a bitmap to the AI file.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/4/00
Parameters:
pShadow - A pointer to a shadow node. [INPUTS]
Returns:
TRUE - Success. FALSE - An error occured.
See also:
NodeBevel::ExportRender

Definition at line 304 of file ai_epsrr.cpp.

00307 {
00308     // Set up the local variables.
00309 //  KernelDC *pDC = (KernelDC*)CCDC::ConvertFromNativeDC(RenderDC);
00310     DocCoord    Position        ( Bounds.lo.x, Bounds.hi.y );
00311     double      Width           = static_cast<double> ( Bounds.Width () ) / 1000;
00312     double      Height          = static_cast<double> ( Bounds.Height () ) / 1000;
00313     double      BMPWidth        = static_cast<double> ( pBitmap->GetWidth () );
00314     double      BMPHeight       = static_cast<double> ( pBitmap->GetHeight () );
00315     DocColour   ShadowColour    = *( static_cast<FillGeometryAttribute*>
00316                                      ( GetCurrentAttribute ( ATTR_FILLGEOMETRY ) )
00317                                      ->GetStartColour () );
00318     DocColour   BlendedShadow   = AlphaBlend ( ShadowColour, mBackgroundColour, Darkness );
00319 
00320     // And use the shadow colour to build a contone bitmap palette.
00321     pBitmap->BuildContonePalette ( BlendedShadow, mBackgroundColour, EFFECT_RGB,
00322                                    RenderView );
00323 
00324     // Set up the bitmap translation matrix.
00325     LoadTranslationMatrix ( Position );
00326     
00327     // And calcuate the scale values for placing the bitmap.
00328     m_a = Width  / BMPWidth;
00329     m_d = Height / BMPHeight;
00330 
00331     // Write out the bitmap header.
00332     WriteBitmapHeader ( (INT32)BMPWidth, (INT32)BMPHeight );
00333 
00334     // Export the bitmap.
00335     WriteContoneBody ( pBitmap );
00336 
00337     // Finish off the bitmap record.
00338     WriteBitmapTail ();
00339 
00340     return TRUE;
00341 }

INT32 AIEPSRenderRegion::FindGradientInCache FillGeometryAttribute pFill,
EFFECTTYPE  effect
[private, virtual]
 

Deletes the list of stored gradient fills, that was built up using IncludeGradientFill.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/3/2001 Returns the identifier of the found gradient fill, or 0 if it wasn't found
See also: AIEPSRenderRegion::IncludeGradientFill,

Definition at line 3538 of file ai_epsrr.cpp.

03539 {
03540     INT32 id    = 0;
03541     ListFill * pList = NULL;
03542     FillGeometryAttribute * pStoredFill = NULL;
03543 
03544     double fillBias = 0;
03545     CProfileBiasGain fillProfile = pFill->GetProfile ();
03546     fillBias = (double) fillProfile.GetBias ();
03547 
03548     // work out which list we want to search in.
03549     if (pFill->IsARadialFill () || pFill->IsASquareFill ())
03550         pList = m_pRadialGradList;
03551     else
03552         pList = m_pLinearGradList;
03553 
03554     // Cycle through all the fills until we find the one we want, or until we run out of fills
03555     while ((pList != NULL) && (id == 0))
03556     {
03557         pStoredFill = pList->pFill;
03558 
03559         // Because the start and end points for an Illustrator fill are not included in the
03560         //  cache, we don't need to worry about them being the same.
03561         //
03562         // So, we set all the start and end points to be the same (since they would cause two
03563         //  identical fills in different places, or of different lengths to be considered as
03564         //  different otherwise).
03565         pStoredFill->SetStartPoint (pFill->GetStartPoint ());
03566         pStoredFill->SetEndPoint (pFill->GetEndPoint ());
03567         pStoredFill->SetEndPoint2 (pFill->GetEndPoint2 ());
03568         pStoredFill->SetEndPoint3 (pFill->GetEndPoint3 ());
03569 
03570         // Now that the fill coords are the same, test to see whether they're 
03571         //  the same fill, or not.
03572         if (*pStoredFill == *pFill)
03573         {
03574             double storeBias = 0;
03575             CProfileBiasGain storeProfile = pStoredFill->GetProfile ();
03576             storeBias = (double) storeProfile.GetBias ();
03577 
03578             if ((storeBias == fillBias) && (pList->effect == effect))
03579                 id = pList->id;
03580         }
03581 
03582         // Check the next fill
03583         pList = pList->pNext;
03584     }
03585 
03586     return id;
03587 }

BOOL AIEPSRenderRegion::GetTextAsShapes  )  [virtual]
 

Sets the export TextAsShapes flag.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
8th November 2000
Returns:
BOOL - whether text is exported as shapes (TRUE) or characters (FALSE)
See also: AIEPSRenderRegion::GetTextAsShapes

Definition at line 3036 of file ai_epsrr.cpp.

03037 {
03038     return m_bTextAsShapes;
03039 }

void AIEPSRenderRegion::IncludeGradientFill FillGeometryAttribute pFill,
EFFECTTYPE  effect
[virtual]
 

Stores information about a fill so that the same fill isn't declared multiple times. See also: AIEPSRenderRegion::WriteGradientFills, AIEPSRenderRegion::WriteGradientUsage, AIEPSRenderRegion::FindGradientInCache.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
5/2/2001

Definition at line 3416 of file ai_epsrr.cpp.

03417 {
03418     ERROR3IF ((pFill == NULL), "AIEPSRenderRegion::IncludeGradientFill - Attempted to include NULL fill");
03419 
03420     ListFill * pNewList = NULL;
03421     FillGeometryAttribute * pNewFill = NULL;
03422 
03423     // don't try and store the fill if it's invalid.
03424     if (pFill != NULL)
03425     {
03426         // Create a new FillGeometryAttribute, of the same type as the one passed in.
03427 
03428         //  NOTE: Four colour fills are derived from three colour fills, so they return
03429         //      TRUE for IsAThreeColFill. This means that we need to process four colour
03430         //      fills before we process three colour fills, otherwise all four colour fills
03431         //      will become represented by three colour ones and the copy won't match the
03432         //      original.
03433 
03434         if (pFill->IsALinearFill ())
03435             pNewFill = new LinearFillAttribute;
03436         else if (pFill->IsARadialFill ())
03437             pNewFill = new RadialFillAttribute;
03438         else if (pFill->IsAConicalFill ())
03439             pNewFill = new ConicalFillAttribute;
03440         else if (pFill->IsASquareFill ())
03441             pNewFill = new SquareFillAttribute;
03442         else if (pFill->IsAFourColFill ())
03443             pNewFill = new FourColFillAttribute;
03444         else if (pFill->IsAThreeColFill ())
03445             pNewFill = new ThreeColFillAttribute;
03446         else if (pFill->IsAFractalFill ())
03447             pNewFill = new FractalFillAttribute;
03448         else if (pFill->IsANoiseFill ())
03449             pNewFill = new NoiseFillAttribute;
03450         else if (pFill->IsABitmapFill ())
03451             pNewFill = new BitmapFillAttribute;
03452         else
03453         {
03454             pNewFill = NULL;
03455             ERROR3 ("AIEPSRenderRegion::IncludeGradientFill - Unrecognised fill included");
03456         }
03457 
03458         // Copy fill data if the the fill is recognised. There's no point in doing this if
03459         //  we didn't recognise the fill, as the copy is bound to be different to the original.
03460         if (pNewFill != NULL)
03461         {
03462             // Copy all the relevant info.
03463             *(pNewFill) = *pFill;
03464             ERROR3IF ( !(*pFill == *pNewFill), "AIEPSRenderRegion::IncludeGradientFill - Copied fill doesn't match original");
03465 
03466             // New Fill is built, so add it into either the radial or linear list.
03467             if (pFill->IsARadialFill () || pFill->IsASquareFill ())
03468             {
03469                 pNewList = new ListFill (pNewFill, effect, m_pRadialGradList);
03470                 m_pRadialGradList = pNewList;
03471             }
03472             else
03473             {
03474                 pNewList = new ListFill (pNewFill, effect, m_pLinearGradList);
03475                 m_pLinearGradList = pNewList;
03476             }
03477         }
03478     }
03479 }

void AIEPSRenderRegion::Initialise  )  [protected, virtual]
 

Sets up render region - it outputs the AIEPS file header comments, and intialises the rendering attributes.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/3/00
See also:
EPSRenderRegion::Initialise, EPSRenderRegion::InitAttributes

Definition at line 531 of file ai_epsrr.cpp.

00532 {
00533     // Set up member variables.
00534     m_a             = 1;
00535     m_b             = 0;
00536     m_c             = 0;
00537     m_d             = 1;
00538     m_T             = DocCoord ( 0, 0 );
00539     m_ActiveLayer   = FALSE;
00540     m_LayerColour   = 0;
00541 
00542     ClearGradientCache ();
00543 
00544     // Call the EPSRenderRegion method to re-enter the export loop.
00545     EPSRenderRegion::InitAttributes ();
00546 }

BOOL AIEPSRenderRegion::IsGradientFillValidForExport FillGeometryAttribute pFill  )  [virtual]
 

Determines whether a particular fill can be used through the AI export See also: AIEPSRenderRegion::WriteGradientFills, AIEPSRenderRegion::WriteGradientUsage.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/01/01

Definition at line 3383 of file ai_epsrr.cpp.

03384 {
03385     BOOL acceptable = FALSE;
03386 
03387     if ( pFill->IsAColourFill () &&         // Is it a colour fill?
03388          pFill->IsAGradFill () &&           // Is it a graduated fill?
03389          ! (pFill->IsAFractalFill ()) &&    // Is it not a fractal (clouds) fill?
03390          ! (pFill->IsANoiseFill ()) &&      // Is it not a fractal (plasma) fill?
03391          ! (pFill->IsABitmapFill ()) )      // Is it not a bitmap fill?
03392     {
03393         acceptable = TRUE;
03394     }
03395     else
03396     {
03397         acceptable = FALSE;
03398     }
03399 
03400     return acceptable;
03401 }

BOOL AIEPSRenderRegion::LoadBitmapMatrix NodeBitmap pNodeBMP  )  [private]
 

This code generates a matrix to position and manipulate a bitmap within an AI file. Roughly, it calculates the angle of rotation, followed by the skew angle, and creates a matrix using these values. See Also: FlashExportDC::WriteBitmapFill ().

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
4/4/00
Parameters:
pNodeBitmap - A pointer to the bitmap node being exported. [INPUTS]
Returns:
TRUE - Successful. FALSE - An error has occured.

Definition at line 1402 of file ai_epsrr.cpp.

01403 {
01404     // Step 1:  Extract the co-ordinates of three corners from the bitmap record, and store
01405     //          them as named co-ordinates within this function. The names are a historical
01406     //          reference to the original names within the FlashExportDC, and refer to the
01407     //          positions of a bitmap fill.
01408     double          Angle       = pNodeBMP->GetRotationAngle ();
01409 
01410     double          SinRotate   = sin ( Angle );
01411     double          CosRotate   = cos ( Angle );
01412 //  double          Skew        = 0;
01413 
01414     DocCoord        LowLeft     = pNodeBMP->Parallel [3];   // Low corner of the bitmap.
01415     DocCoord        TopLeft     = pNodeBMP->Parallel [0];   // Max Y corner.
01416     DocCoord        LowRight    = pNodeBMP->Parallel [2];   // Max X corner.
01417 
01418     // Step 2:  Calculate the normalised dot product of the two vectors, and this forms
01419     //          the cosine of their internal angle.
01420     double          WidthX      = static_cast<double> ( LowLeft.x - LowRight.x ) / 1000;
01421     double          WidthY      = static_cast<double> ( LowLeft.y - LowRight.y ) / 1000;
01422     double          HeightX     = static_cast<double> ( TopLeft.x - LowLeft.x  ) / 1000;
01423     double          HeightY     = static_cast<double> ( TopLeft.y - LowLeft.y  ) / 1000;
01424     
01425     // Get the lengths of these vectors to normalise the dot-product. (Necessary for the
01426     // trignometric function calculations.)
01427     double          Width       = sqrt ( ( WidthX * WidthX ) + ( WidthY * WidthY ) );
01428     double          Height      = sqrt ( ( HeightX * HeightX ) + ( HeightY * HeightY ) );
01429 /*
01430     // The dot product calculation. By normalising the result, the cosine of the angle is
01431     // calculated.
01432     double      CosSkew = ( ( WidthX * HeightX ) + ( HeightY * WidthY ) ) /
01433                               ( Height * Width );
01434     double      SinSkew = sqrt ( 1 - ( CosSkew * CosSkew ) );
01435 
01436     // Multiply the width of the shape by the sine derived from the dot product. This will
01437     // give the actual width, and not the one distorted by skewing.
01438     Width *= SinSkew;
01439 
01440     // If the DotSine value is not 0, calculate the tan value that forms the skew angle.
01441     // Since tan is undefined for 0, I'm ignoring this state.
01442     if ( SinSkew != 0 )
01443     {
01444         Skew = - CosSkew / SinSkew;
01445     }
01446 */
01447     // Grab a reference to the bitmap, and pull it's height and width from it.
01448     KernelBitmap    *pBitmap    = pNodeBMP->GetBitmap ();   // A reference to the bitmap.
01449 
01450     double          BMPWidth    = static_cast<double> ( pBitmap->GetWidth () );
01451     double          BMPHeight   = static_cast<double> ( pBitmap->GetHeight () );
01452 
01453     // Catch BMPWidth or BMPHeight set to zero. This shouldn't happen...
01454     if ( BMPWidth == 0 )
01455         BMPWidth = 1;
01456 
01457     if ( BMPHeight == 0 )
01458         BMPHeight = 1;
01459 
01460     // Step 4:  Use the above values to calculate the values with which to populate the
01461     //          transformation matrix.
01462     double          ScaleX      = Width  / BMPWidth;
01463     double          ScaleY      = Height / BMPHeight;
01464 
01465     // Step 5:  Use these to build the matrix. The variables a, b, c, d refer to the AI
01466     //          matrix entries. The form of the matrix is:
01467     //
01468     //          | SinRotate     CosRotate | | ScaleX        0       |
01469     //          | -CosRotate    SinRotate | | Skew * ScaleY ScaleY  |
01470 
01471     m_a = ( SinRotate * ScaleX );   // + ( CosRotate * Skew * ScaleY );
01472     m_b = ( - CosRotate * ScaleX ); // + ( SinRotate * Skew * ScaleY );
01473     m_c = CosRotate * ScaleY;
01474     m_d = SinRotate * ScaleY;
01475 
01476     // There's a weird bug with the AI export, in that a small (>0.0001) value is misread
01477     // by Adobe Illustrator as a monstrous value. To get around this, I'm going to set all
01478     // near zero values to zero.
01479     if ( Absol ( m_a ) < 1e-4 )
01480     {
01481         m_a = 0;
01482     }
01483 
01484     if ( Absol ( m_b ) < 1e-4 )
01485     {
01486         m_b = 0;
01487     }
01488 
01489     if ( Absol ( m_c ) < 1e-4 )
01490     {
01491         m_c = 0;
01492     }
01493 
01494     if ( Absol ( m_d ) < 1e-4 )
01495     {
01496         m_d = 0;
01497     }
01498 
01499     // Step 6:  Calculate the translation part of the matrix.
01500     m_T = TopLeft;
01501 
01502     return TRUE;
01503 }

BOOL AIEPSRenderRegion::LoadTranslationMatrix DocCoord Translation  )  [private]
 

Loads the matrix with:.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/4/00
Parameters:
- [INPUTS]
Returns:
TRUE - Success. FALSE - An error occured.
| 1 0 Translation.x | | 0 1 Translation.y |

Which can then be written with WriteLoadedMatrix.

See also:
AIESPRenderRegion::LoadBitmapMatrix, AIEPSRenderRegion::WriteLoadedMatrix

Definition at line 1524 of file ai_epsrr.cpp.

01525 {
01526     // Set the transformation part of the matrix to be the identity matrix.
01527     m_a = 1;
01528     m_b = 0;
01529     m_c = 0;
01530     m_d = 1;
01531 
01532     // And load up the translation value.
01533     m_T = Translation;
01534 
01535     return TRUE;
01536 }

void AIEPSRenderRegion::OutputDashPattern  )  [protected, virtual]
 

Outputs EPS dash pattern values. This function currently only exists so that extra handling can be easily achieved for Illustrator EPS export of dash patterns in the future (if need be).

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/11/00
See also:
EPSRenderRegion::OutputDashPattern (); EPSRenderRegion::OutputDashPatternInit();

Reimplemented from EPSRenderRegion.

Definition at line 2141 of file ai_epsrr.cpp.

02142 {
02143     EPSRenderRegion::OutputDashPattern ();
02144 }

void AIEPSRenderRegion::OutputFillCMYKColour  )  [protected, virtual]
 

Writes additional info to the file for CMYK fill colours See also: EPSRenderRegion::OutputFillCMYKColour.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/12/00

Reimplemented from EPSRenderRegion.

Definition at line 3167 of file ai_epsrr.cpp.

03168 {
03169     // NOTE: We need to export any changes to the overflow text here, 
03170     // as it's the last place we can catch the colour change.
03171     if (ExportingOnPath ())
03172     {
03173         PColourCMYK CMYK;
03174 
03175         OverflowTextStartGap ();
03176 
03177         // Assume no local context at present
03178         ColourContext* pContext;
03179         ColourPlate* pSeparation;
03180         GetOutputColourPlate(COLOURMODEL_CMYK, &pContext, &pSeparation);
03181 
03182         if (pSeparation==NULL)
03183         {
03184             // Get the current line colour in CMYK values, unless it's transparent
03185             // Print out colour component values.
03186             if (RR_FILLCOLOUR().FindParentIndexedColour() == NULL)
03187             {
03188                 // Unnamed colour
03189                 // retrieve the colour value
03190                 RR_FILLCOLOUR().GetCMYKValue(pContext, &CMYK);
03191                 OverflowTextWriteColour (&CMYK);
03192                 OverflowTextWrite (_T("k\n"));
03193             }
03194             else
03195             {
03196                 // Named colour
03197                 OverflowTextWriteNamedColour (&(RR_FILLCOLOUR()), pContext);
03198                 OverflowTextWrite (_T("x\n"));
03199             }
03200         }
03201         else
03202         {
03203             // Assume unnamed colour as 'g' grey fill operator does
03204             // not allow for custom greys.
03205             if (pSeparation->IsMonochrome())
03206             {
03207                 RR_FILLCOLOUR().GetCMYKValue(pContext, &CMYK);
03208                 BYTE c = 0xFF - CMYK.Key;
03209                 OverflowTextWriteSingleColour (c);
03210                 OverflowTextWrite (_T("g\n"));
03211             }
03212             else
03213             {
03214                 RR_FILLCOLOUR().GetCMYKValue(pContext, &CMYK);
03215                 OverflowTextWriteColour (&CMYK);
03216                 OverflowTextWrite (_T("x\n"));
03217             }
03218         }
03219     }
03220 
03221     // Call the base class to write the ordinary info out
03222     EPSRenderRegion::OutputFillCMYKColour ();
03223 }

void AIEPSRenderRegion::OutputFillColour void   )  [protected, virtual]
 

If the fill is a gradient fill, this method will invoke the WriteGradientFillInstance method, otherwise it will call the base EPSRenderRegion OutputFillColour method. This allows Camelot to support gradient fills in the AI file format.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/3/00
(ChrisG 30/3/2001) - Gradient fill instances should be exported when they are used on an object, not when a fill attribute is found. This way, fills can be applied to multiple objects.

See also:
AIEPSRenderRegion::OutputStrokeColour

Reimplemented from EPSRenderRegion.

Definition at line 1380 of file ai_epsrr.cpp.

01381 {
01382     // Output the actual fill colour.
01383     EPSRenderRegion::OutputFillColour ();
01384 }

void AIEPSRenderRegion::OutputFillRGBColour  )  [protected, virtual]
 

Writes additional info to the file for RGB fill colours See also: EPSRenderRegion::OutputFillRGBColour.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/12/00

Reimplemented from EPSRenderRegion.

Definition at line 3088 of file ai_epsrr.cpp.

03089 {
03090     // NOTE: We need to export any changes to the overflow text here, 
03091     // as it's the last place we can catch the colour change.
03092     if (ExportingOnPath ())
03093     {
03094         OverflowTextStartGap ();
03095 
03096         // Colour values.
03097         INT32 red;
03098         INT32 green;
03099         INT32 blue;
03100         PColourCMYK CMYK;
03101 
03102         // Assume no local context at present - used as a check to make sure that we 
03103         //  aren't exporting as seperations.
03104         ColourContext* pContext;
03105         ColourPlate* pSeparation;
03106         GetOutputColourPlate (COLOURMODEL_CMYK, &pContext, &pSeparation);
03107 
03108         if (pSeparation==NULL)
03109         {
03110             // As expected, we ain't using seperations, so we can output as RGB.
03111 
03112             // Get the current line colour in RGB values and print them out.
03113             RR_FILLCOLOUR().GetRGBValue (&red, &green, &blue);
03114             OverflowTextWriteSingleColour (red);
03115             OverflowTextWriteSingleColour (green);
03116             OverflowTextWriteSingleColour (blue);
03117 
03118             if (RR_FILLCOLOUR().FindParentIndexedColour() == NULL)
03119             {
03120                 // Unnamed colour - just add 'Xa' token
03121                 OverflowTextWrite (_T("Xa\n"));
03122             }
03123             else
03124             {
03125                 // Named colour - add Name, tint value, RGB flag and 'Xx' token
03126                 OverflowTextWriteColourName (&(RR_FILLCOLOUR()));
03127                 OverflowTextWrite (_T(" 0 1 Xx\n"));
03128             }
03129         }
03130         else
03131         {
03132             // Since we are seperating the colours, then use CMYK mode.
03133 
03134             // Assume unnamed colour as 'g' grey fill operator does
03135             // not allow for custom greys.
03136             if (pSeparation->IsMonochrome())
03137             {
03138                 RR_FILLCOLOUR().GetCMYKValue(pContext, &CMYK);
03139                 BYTE c = 0xFF - CMYK.Key;
03140                 OverflowTextWriteSingleColour (c);
03141                 OverflowTextWrite (_T("g\n"));
03142             }
03143             else
03144             {
03145                 RR_FILLCOLOUR().GetCMYKValue(pContext, &CMYK);
03146                 OverflowTextWriteColour (&CMYK);
03147                 OverflowTextWrite (_T("x\n"));
03148             }
03149         }
03150     }
03151 
03152     // Write out the usual EPS colour tokens.
03153     EPSRenderRegion::OutputFillRGBColour ();
03154 }

void AIEPSRenderRegion::OutputFontName void   )  [protected, virtual]
 

Output an Illustrator format fontname and pointsize token. The format is /_fontname[-Bold|-Italic|-BoldItalic] pointsize Tf. EncodeFontName will generate this format from an internal fontname. DocodeFontName will return an internal format fontname and flags where nec.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/11/00

Reimplemented from EPSRenderRegion.

Definition at line 2234 of file ai_epsrr.cpp.

02235 {
02236     if (ExportingOnPath ())
02237     {
02238         TCHAR buffer [64];
02239 
02240         OverflowTextStartGap ();
02241 
02242         String_64 FontName;
02243         String_64 EncodedFontName;
02244         String_64 Append(_T("/_"));
02245 
02246         // get information about the current font
02247         FONTMANAGER->GetFontName(RR_TXTFONTTYPEFACE(), FontName);
02248 
02249         // Graeme (31-3-00) - I've lifted this piece of code from the CamelotEPSRenderRegion. It
02250         // appears to map an existing, encoded font name onto its Postscript counterpart.
02251         FONTMANAGER->EncodeAndMapFontName(FontName, EncodedFontName, GetFontStyle());
02252         
02253         EncodedFontName.Insert(Append,0);
02254 
02255         // Output the fontsize next
02256         double PointSize = ((double)RR_TXTFONTSIZE())/1000;
02257         
02258         // finally do output the font token
02259         camSprintf (buffer, _T("%s %.1f Tf\n"), (TCHAR *)EncodedFontName, PointSize);
02260         OverflowTextWrite (buffer);
02261     }
02262     EPSRenderRegion::OutputFontName ();
02263 }

void AIEPSRenderRegion::OutputJoinType  )  [protected, virtual]
 

Output the standard AI EPS join type.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/11/00

Reimplemented from EPSRenderRegion.

Definition at line 2110 of file ai_epsrr.cpp.

02111 {
02112     TCHAR buf [64];
02113 
02114     // Set line Join Type
02115     if (ExportingOnPath ())
02116     {
02117         OverflowTextStartGap ();
02118         camSprintf (buf, _T("%d j\n"), (UINT32)RR_JOINTYPE());
02119         OverflowTextWrite (buf);
02120     }
02121 
02122     EPSRenderRegion::OutputJoinType ();
02123 }

void AIEPSRenderRegion::OutputLineWidth  )  [protected, virtual]
 

Output the standard line width token and measure for AI EPS.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/11/00

Reimplemented from EPSRenderRegion.

Definition at line 2084 of file ai_epsrr.cpp.

02085 {
02086     TCHAR buf [64];
02087 
02088     // Set line width
02089     if (ExportingOnPath ())
02090     {
02091         OverflowTextStartGap ();
02092         camSprintf (buf, _T("%.2f w\n"), ((double) RR_LINEWIDTH())/1000);
02093         OverflowTextWrite (buf);
02094     }
02095 
02096     EPSRenderRegion::OutputLineWidth ();
02097 }

void AIEPSRenderRegion::OutputMitreLimit  )  [protected, virtual]
 

Output the current mitre limit value using the usual 'M' EPS token. Again, this is only here so that the AI export can be easily expanded or modified.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/11/00

Reimplemented from EPSRenderRegion.

Definition at line 2184 of file ai_epsrr.cpp.

02185 {
02186     EPSRenderRegion::OutputMitreLimit ();
02187 }

void AIEPSRenderRegion::OutputStartCap  )  [protected, virtual]
 

Output the start cap setting using the usual 'J' EPS token.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/11/00

Reimplemented from EPSRenderRegion.

Definition at line 2157 of file ai_epsrr.cpp.

02158 {
02159     TCHAR buf [64];
02160 
02161     if (ExportingOnPath ())
02162     {
02163         OverflowTextStartGap ();
02164         camSprintf (buf, _T("%d J\n"), (UINT32)RR_STARTCAP());
02165         OverflowTextWrite (buf);
02166     }
02167 
02168     EPSRenderRegion::OutputStartCap ();
02169 }

void AIEPSRenderRegion::OutputStrokeCMYKColour  )  [protected, virtual]
 

Writes additional info to the file for CMYK fill colours See also: EPSRenderRegion::OutputFillCMYKColour.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/12/00

Reimplemented from EPSRenderRegion.

Definition at line 3316 of file ai_epsrr.cpp.

03317 {
03318     // Write out the colour to the overflow file if we're doing text on a path.
03319     if (ExportingOnPath ())
03320     {
03321         PColourCMYK CMYK;
03322         OverflowTextStartGap ();
03323 
03324         // Assume no local context at present
03325         ColourContext* pContext;
03326         ColourPlate* pSeparation;
03327         GetOutputColourPlate(COLOURMODEL_CMYK, &pContext, &pSeparation);
03328 
03329         if (pSeparation==NULL)
03330         {
03331             // Get the current line colour in CMYK values, unless it's transparent
03332             // Print out colour component values.
03333             if (RR_STROKECOLOUR().FindParentIndexedColour() == NULL)
03334             {
03335                 // Unnamed colour
03336                 // retrieve the colour value
03337                 RR_STROKECOLOUR().GetCMYKValue(pContext, &CMYK);
03338                 OverflowTextWriteColour (&CMYK);
03339                 OverflowTextWrite (_T("K\n"));
03340             }
03341             else
03342             {
03343                 // Named colour
03344                 OverflowTextWriteNamedColour (&(RR_STROKECOLOUR()), pContext);
03345                 OverflowTextWrite (_T("X\n"));
03346             }
03347         }
03348         else
03349         {
03350             // Assume unnamed colour as 'g' grey fill operator does
03351             // not allow for custom greys.
03352             if (pSeparation->IsMonochrome())
03353             {
03354                 RR_STROKECOLOUR().GetCMYKValue(pContext, &CMYK);
03355                 BYTE c = 0xFF - CMYK.Key;
03356                 OverflowTextWriteSingleColour (c);
03357                 OverflowTextWrite (_T("G\n"));
03358             }
03359             else
03360             {
03361                 RR_STROKECOLOUR().GetCMYKValue(pContext, &CMYK);
03362                 OverflowTextWriteColour (&CMYK);
03363                 OverflowTextWrite (_T("X\n"));
03364             }
03365         }
03366     }
03367 
03368     // Call the base class to write out the ordinary information
03369     EPSRenderRegion::OutputStrokeCMYKColour ();
03370 }

void AIEPSRenderRegion::OutputStrokeColour  )  [protected, virtual]
 

Output the current stroke colour. This function will use one of the following EPS tokens K - if not separating and colour is unnamed X - if not separating and colour is named G - if separating.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/11/00
See also:
AIEPSRenderRegion::OutputFillColour

Reimplemented from EPSRenderRegion.

Definition at line 2208 of file ai_epsrr.cpp.

02209 {
02210     // Write out the stroke colour
02211     EPSRenderRegion::OutputStrokeColour ();
02212 }

void AIEPSRenderRegion::OutputStrokeRGBColour  )  [protected, virtual]
 

Writes additional info to the file for RGB stroke colours See also: EPSRenderRegion::OutputStrokeRGBColour.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/12/00

Reimplemented from EPSRenderRegion.

Definition at line 3236 of file ai_epsrr.cpp.

03237 {   
03238     // NOTE: We need to export any changes to the overflow text here, 
03239     // as it's the last place we can catch the colour change.
03240     if (ExportingOnPath ())
03241     {
03242         OverflowTextStartGap ();
03243 
03244         // Colour values.
03245         INT32 red;
03246         INT32 green;
03247         INT32 blue;
03248         PColourCMYK CMYK;
03249 
03250         // Assume no local context at present - used as a check to make sure that we 
03251         //  aren't exporting as seperations.
03252         ColourContext* pContext;
03253         ColourPlate* pSeparation;
03254         GetOutputColourPlate (COLOURMODEL_CMYK, &pContext, &pSeparation);
03255 
03256         if (pSeparation==NULL)
03257         {
03258             // As expected, we ain't using seperations, so we can output as RGB.
03259 
03260             // Get the current line colour in RGB values and print them out.
03261             RR_STROKECOLOUR().GetRGBValue (&red, &green, &blue);
03262             OverflowTextWriteSingleColour (red);
03263             OverflowTextWriteSingleColour (green);
03264             OverflowTextWriteSingleColour (blue);
03265 
03266             if (RR_STROKECOLOUR().FindParentIndexedColour() == NULL)
03267             {
03268                 // Unnamed colour - just add 'XA' token
03269                 OverflowTextWrite (_T("XA\n"));
03270             }
03271             else
03272             {
03273                 // Named colour - add Name, tint value, RGB flag and 'XX' token
03274                 OverflowTextWriteColourName (&(RR_STROKECOLOUR()));
03275                 OverflowTextWrite (_T(" 0 1 XX\n"));
03276             }
03277         }
03278         else
03279         {
03280             // Since we are seperating the colours, then use CMYK mode.
03281 
03282             // Assume unnamed colour as 'g' grey fill operator does
03283             // not allow for custom greys.
03284             if (pSeparation->IsMonochrome())
03285             {
03286                 RR_STROKECOLOUR().GetCMYKValue(pContext, &CMYK);
03287                 BYTE c = 0xFF - CMYK.Key;
03288                 OverflowTextWriteSingleColour (c);
03289                 OverflowTextWrite (_T("G\n"));
03290             }
03291             else
03292             {
03293                 RR_STROKECOLOUR().GetCMYKValue(pContext, &CMYK);
03294                 OverflowTextWriteColour (&CMYK);
03295                 OverflowTextWrite (_T("X\n"));
03296             }
03297         }
03298     }
03299 
03300     // Call the base class to process the colour normally (i.e. to the EPS file itself)
03301     EPSRenderRegion::OutputStrokeRGBColour ();
03302 }

void AIEPSRenderRegion::OutputTextAspectRatio  )  [protected, virtual]
 

Output the change in the text's aspect ratio (Tz).

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/11/00

Reimplemented from EPSRenderRegion.

Definition at line 2322 of file ai_epsrr.cpp.

02323 {
02324     TCHAR buf [64];
02325 
02326     if (ExportingOnPath ())
02327     {
02328         OverflowTextStartGap ();
02329         camSprintf (buf, _T("%.0f Tz\n"), (RR_TXTASPECTRATIO().MakeDouble()*100.0));    // convert from ratio to %
02330         OverflowTextWrite (buf);
02331     }
02332 
02333     EPSRenderRegion::OutputTextAspectRatio ();
02334 }

void AIEPSRenderRegion::OutputTextBaselineShift  )  [protected, virtual]
 

Output the change in Baseline shift (Ts).

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/11/00

Reimplemented from EPSRenderRegion.

Definition at line 2475 of file ai_epsrr.cpp.

02476 {
02477     TCHAR buf [64];
02478 
02479     // Output baseline shift in points
02480     // format = rise Ts
02481     if (ExportingOnPath ())
02482     {
02483         OverflowTextStartGap ();
02484         double BaseLine = ((double)RR_TXTBASELINE())/1000;
02485         camSprintf (buf, _T("%.1f Ts\n"), BaseLine);
02486         OverflowTextWrite (buf);
02487     }
02488 
02489     EPSRenderRegion::OutputTextBaselineShift ();
02490 }

void AIEPSRenderRegion::OutputTextJustification  )  [protected, virtual]
 

Output the change in the text justification (Ta).

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/11/00

Reimplemented from EPSRenderRegion.

Definition at line 2377 of file ai_epsrr.cpp.

02378 {
02379     TCHAR buf [64];
02380 
02381     if (ExportingOnPath ())
02382     {
02383         OverflowTextStartGap ();
02384 
02385         switch (RR_TXTJUSTIFICATION())
02386         {
02387         case JLEFT: 
02388             camSprintf (buf, _T("%d Ta\n"), ((INT32)0));
02389             break;
02390         case JRIGHT: 
02391             camSprintf (buf, _T("%d Ta\n"), ((INT32)2));
02392             break;
02393         case JCENTRE: 
02394             camSprintf (buf, _T("%d Ta\n"), ((INT32)1));
02395             break;
02396         case JFULL: 
02397             camSprintf (buf, _T("%d Ta\n"), ((INT32)3));
02398             break;
02399         }
02400         OverflowTextWrite (buf);
02401     }
02402 
02403     EPSRenderRegion::OutputTextJustification ();
02404 }

void AIEPSRenderRegion::OutputTextLineSpacing  )  [protected, virtual]
 

Output the change in the line spacing (Tl).

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/11/00

Reimplemented from EPSRenderRegion.

Definition at line 2416 of file ai_epsrr.cpp.

02417 {
02418 
02419     if (ExportingOnPath ())
02420     {
02421         TCHAR buf [64];
02422 
02423         OverflowTextStartGap ();
02424 
02425         // Output line spacing in points.
02426         // format - paraspace linespace Tl
02427         double ptLineSpace;
02428         double ptParaSpace=0;
02429 
02430         TxtLineSpaceAttribute* pLineSpace = (TxtLineSpaceAttribute*)(CurrentAttrs[ATTR_TXTLINESPACE].pAttr);
02431 
02432         // There are some rules for reading the linespacing value which I shall divulge
02433         // If IsARation is true then use the proportinal linespacing value.
02434         // else use the absolute linespacing
02435         // However if the absolute linespacing is zero, then we MUST use the proportional
02436         // linespacing. Eeek!
02437         // ie it is an error if (absolute==0 && !IsARatio()) which we will check for here
02438 
02439         double FontSize = (double)RR_TXTFONTSIZE();                 // in millipoints    12pt = 12000 mp
02440         double absLineSpace = (double)pLineSpace->Value;
02441         double proLineSpace = (pLineSpace->Ratio).MakeDouble();
02442 
02443         BOOL Proportional = pLineSpace->IsARatio();
02444 
02445         if (!Proportional && absLineSpace==0)
02446         {
02447             ERROR3("Absolute line spacing is zero yet IsARatio() is FALSE, in GetValidTextAttributes()");
02448             // Make sure we use the proportional value no matter what.
02449             Proportional=TRUE;
02450         }
02451 
02452         if (Proportional)
02453             ptLineSpace = FontSize*proLineSpace/1000;
02454         else
02455             ptLineSpace = absLineSpace/1000;
02456 
02457         camSprintf (buf, _T("%.0f %.0f Tl\n"), ptLineSpace, ptParaSpace);
02458         OverflowTextWrite (buf);
02459     }
02460 
02461     EPSRenderRegion::OutputTextLineSpacing ();
02462 }

void AIEPSRenderRegion::OutputTextRenderMode  )  [protected, virtual]
 

Output the change in the text's Render Mode (Tr) - this happens when the text's fill or line colour changes to or from blank, see-through colour.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/11/00

Reimplemented from EPSRenderRegion.

Definition at line 2278 of file ai_epsrr.cpp.

02279 {
02280     INT32 Style=0;
02281 
02282     if (ExportingOnPath ())
02283     {
02284         OverflowTextStartGap ();
02285 
02286         // Is there a currently active fill colour?
02287         if (! (RR_FILLCOLOUR().IsTransparent()) )
02288             Style+=1;
02289 
02290         // Is there a currently active line colour?
02291         if (! (RR_STROKECOLOUR().IsTransparent()) )
02292             Style+=2;
02293 
02294         switch (Style)
02295         {
02296             case 0: OverflowTextWrite (_T("3 Tr\n"));   // Invisible
02297                     break;
02298             case 1: OverflowTextWrite (_T("0 Tr\n"));   // filled only
02299                     break;
02300             case 2: OverflowTextWrite (_T("1 Tr\n"));   // stroked only
02301                     break;
02302             case 3: OverflowTextWrite (_T("2 Tr")); // filled and stroked
02303                     break;
02304         }
02305     }
02306 
02307     EPSRenderRegion::OutputTextRenderMode ();
02308 }

void AIEPSRenderRegion::OutputTextSubSuperScript  )  [protected, virtual]
 

Output the change in the Sub/Super script attribute (Ts).

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/11/00

Reimplemented from EPSRenderRegion.

Definition at line 2503 of file ai_epsrr.cpp.

02504 {
02505     TCHAR buf [64];
02506     
02507     if (ExportingOnPath ())
02508     {
02509         OverflowTextStartGap ();
02510 
02511         // Output sub/superscript
02512         // in millipoints    12pt = 12000 mp
02513         double FontSize = ((double)RR_TXTFONTSIZE())/1000;
02514 
02515         TxtScriptAttribute* pScript = RR_TXTSCRIPT();
02516         double offset = (pScript->Offset).MakeDouble();
02517         double size = (pScript->Size).MakeDouble();
02518 
02519         OverflowTextWrite (_T("%%XSScript\n"));
02520 
02521         double rise = FontSize*offset;
02522 
02523         camSprintf (buf, _T("%.1f Ts\n"), rise);
02524         OverflowTextWrite (buf);
02525 
02526         double ptsize = FontSize*size;
02527 
02528         String_64 MappedFont;
02529         String_64 Append(_T("/_"));
02530 
02531         String_64 FontName;
02532         FONTMANAGER->GetFontName(RR_TXTFONTTYPEFACE(), FontName);
02533 
02534         // Graeme (31-3-00) - Map the encoded name onto the PS font name.
02535         FONTMANAGER->EncodeAndMapFontName(FontName,MappedFont,GetFontStyle());
02536 
02537         // Graeme (14-6-00) - I should add ascent and descent values, but Camelot doesn't
02538         // seem to store them anywhere.
02539         MappedFont.Insert(Append,0);
02540 
02541         camSprintf (buf, _T("%s %.1f Tf\n"),(TCHAR *)MappedFont, ptsize);
02542         // Output the ascent.
02543         // Output the descent.
02544         OverflowTextWrite (buf);
02545     }
02546 
02547     EPSRenderRegion::OutputTextSubSuperScript ();
02548 }

void AIEPSRenderRegion::OutputTextTracking  )  [protected, virtual]
 

Output the change in the tracking (Tt).

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/11/00

Reimplemented from EPSRenderRegion.

Definition at line 2348 of file ai_epsrr.cpp.

02349 {
02350     // Must be output in 1/1000 of an em.
02351     // 1 em = point size of font.
02352     // Tracking internally =millipoints.
02353     TCHAR buf [64];
02354 
02355     if (ExportingOnPath ())
02356     {
02357         OverflowTextStartGap ();
02358         camSprintf (buf, _T("%d Tt\n"), RR_TXTTRACKING());
02359         OverflowTextWrite (buf);
02360     }
02361 
02362     EPSRenderRegion::OutputTextTracking ();
02363 }

void AIEPSRenderRegion::OutputWindingRule  )  [protected, virtual]
 

Output the winding rule used to AI EPS.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/12/00

Reimplemented from EPSRenderRegion.

Definition at line 2046 of file ai_epsrr.cpp.

02047 {
02048     // Set up kernel DC up in an appropriate form.
02049     KernelDC    *pDC    = static_cast<KernelDC *> ( CCDC::ConvertFromNativeDC(RenderDC) );
02050 
02051     if (RR_WINDINGRULE() == EvenOddWinding)
02052     {
02053         // Even-Odd winding (Camelot's default)
02054         pDC->OutputValue ((INT32)1);
02055     }
02056     else if (RR_WINDINGRULE() == NonZeroWinding)
02057     {
02058         // Non-Zero winding (EPS's default)
02059         pDC->OutputValue ((INT32)0);
02060     }
02061     else
02062     {
02063         // Positive or negative winding (only Even-Odd and Non-Zero are supported in AI7),
02064         //  so assume that we're using camelot's default rule.
02065         pDC->OutputValue ((INT32)1);
02066     }
02067 
02068     pDC->OutputToken (_T("XR"));
02069     pDC->OutputNewLine ();
02070 }

void AIEPSRenderRegion::OverflowTextFinish  )  [virtual]
 

Finish the overflow text block and write both blocks to the actual EPS file.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/11/00
See also:

Definition at line 2620 of file ai_epsrr.cpp.

02621 {
02622     ASSERT (m_fpOverflowText);
02623 
02624         // write out final information.
02625     OverflowTextStartGap ();
02626 
02627         // close files.
02628     fclose (m_fpOverflowText);
02629     m_fpOverflowText = NULL;
02630 
02631     // copy info into actual EPS file.
02632     char cbuffer [1025];
02633     TCHAR buffer [1025];
02634     KernelDC *pDC = (KernelDC*)CCDC::ConvertFromNativeDC(RenderDC);
02635     FILE * fp;
02636 
02637         // Write out the Extra info.
02638     fp = fopen ("OverFlow.txt", "r+t");
02639 
02640     while (fgets (cbuffer, 1024, fp) != NULL)
02641     {
02642         char c;
02643         INT32 i=0;
02644         cbuffer[1024]=0;
02645         do
02646         {
02647             c=cbuffer[i];
02648             buffer[i]=c; // 1:1 CHAR->TCHAR conversion
02649             i++;
02650         } while (c);
02651             
02652         // deal with newlines.
02653         pDC->OutputToken (buffer);
02654         pDC->OutputNewLine ();
02655     }
02656     fclose (fp);
02657 
02658 
02659         // clean up temp. files
02660     remove ("OverFlow.txt");
02661 }

void AIEPSRenderRegion::OverflowTextFinishGap  )  [protected, virtual]
 

Closes a gap for writing attributes in the overflow text, so that a new line of overflow text can be started.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
2/11/00
See also:
AIEPSRenderRegion::OverflowTextStartGap ();

Definition at line 2699 of file ai_epsrr.cpp.

02700 {
02701     ASSERT (ExportingOnPath ());
02702 
02703     // if we're in a text gap (for changing the attributes), start writing a new TX block.
02704     if (m_bInTextGap == TRUE)
02705     {
02706         OverflowTextWrite (_T("("));
02707         m_bInTextGap = FALSE;
02708     }
02709 }

void AIEPSRenderRegion::OverflowTextStart  )  [virtual]
 

Start the overflow text block.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/11/00
See also:

Definition at line 2598 of file ai_epsrr.cpp.

02599 {
02600         // open overflow file
02601     m_fpOverflowText = fopen ("OverFlow.txt", "w");
02602 
02603     // write out start info - NOTE: we're currently in a gap from writing the initial 
02604     //  attributes, so we're going to have to close it.
02605     m_bInTextGap = TRUE;
02606 }

void AIEPSRenderRegion::OverflowTextStartGap  )  [protected, virtual]
 

Starts a new gap in the Overflow text, so that attributes can be written into the overflow blocks (the TX ones).

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
2/11/00
See also:
AIEPSRenderRegion::OverflowTextFinishGap ()

Definition at line 2675 of file ai_epsrr.cpp.

02676 {
02677     ASSERT (ExportingOnPath ());
02678 
02679     // if we're not in a gap, finish writing the old TX block and start a new gap, 
02680     if (m_bInTextGap == FALSE)
02681     {
02682         OverflowTextWrite (_T(") TX\n"));
02683         m_bInTextGap = TRUE;
02684     }
02685 }

void AIEPSRenderRegion::OverflowTextWrite TCHAR text  )  [protected, virtual]
 

Write some text to the overflow body file. This will store all the text and modified attributes for the TX text block.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/11/00
See also:

Definition at line 2724 of file ai_epsrr.cpp.

02725 {
02726     ASSERT (ExportingOnPath ());
02727     while (*text)
02728     {
02729         fprintf (m_fpOverflowText, "%c", *text++);
02730     }
02731 }

void AIEPSRenderRegion::OverflowTextWriteColour PColourCMYK pCol  )  [protected, virtual]
 

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

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/11/00
Parameters:
Col - the CMYK colour values to be output. [INPUTS]
e.g. MonoOn PColourCMYK Col = { 255, 255, 128, 0 }; pDC->OutputColour(&Col); MonoOff will give the following output: MonoOn 1.0 1.0 0.5 0.0 MonoOff
See also:
KernelDC::OutputColourValue
Returns:
Errors: Disk/file error => ERROR1

Definition at line 2784 of file ai_epsrr.cpp.

02785 {
02786     // Write each of the colour values.
02787     OverflowTextWriteSingleColour (pCol->Cyan);
02788     OverflowTextWriteSingleColour (pCol->Magenta);
02789     OverflowTextWriteSingleColour (pCol->Yellow);
02790     OverflowTextWriteSingleColour (pCol->Key);
02791 }

void AIEPSRenderRegion::OverflowTextWriteColourName DocColour pCol  )  [protected, virtual]
 

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

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/12/00
Parameters:
pCol - the colour to output. [INPUTS]
See also:
KernelDC::OutputNamedColour
Returns:
Errors: Disk/file error => ERROR1

Definition at line 2875 of file ai_epsrr.cpp.

02876 {
02877     // Get the indexed colour from the DocColour.
02878     IndexedColour *pIndCol = pCol->FindParentIndexedColour();
02879 
02880     if (pIndCol == NULL)
02881     {
02882         if (pCol->IsTransparent())
02883         {
02884             // This is a 'no colour' type colour, so output a zero-length colour name,
02885             // as this is the only way we can handle this at the moment.
02886             OverflowTextWrite (_T("()"));
02887         }
02888         else
02889         {
02890             // Otherwise make up a colour name (see epsfiltr.h).
02891             OverflowTextWrite (_T("("));
02892             OverflowTextWrite (ImmediateColourFudgeyBodgeName);
02893             OverflowTextWrite (_T(")"));
02894         }
02895     }
02896     else
02897     {
02898         // Got an indexed colour - output its name
02899         // (Pass in TRUE to get a unique-identifier for local colours rather than "Local colour")
02900         String_64 *ColName = pIndCol->GetName(TRUE);
02901         OverflowTextWrite (_T("("));
02902         OverflowTextWrite ((TCHAR *) (*ColName));
02903         OverflowTextWrite (_T(")"));
02904     }
02905 }

void AIEPSRenderRegion::OverflowTextWriteNamedColour DocColour pCol,
ColourContext pContext = NULL
[protected, virtual]
 

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

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

Definition at line 2813 of file ai_epsrr.cpp.

02814 {
02815     // Get CMYK version of this colour.
02816     PColourCMYK CMYK;
02817     pCol->GetCMYKValue(pContext, &CMYK);
02818 
02819     // Output CMYK version
02820     OverflowTextWriteColour (&CMYK);
02821         
02822     // Get the indexed colour from the DocColour.
02823     IndexedColour *pIndCol = pCol->FindParentIndexedColour();
02824 
02825     // Cope with the unexpected!
02826 //  ENSURE(pIndCol != NULL, "Named colour has no index colour!");
02827 
02828     if (pIndCol == NULL)
02829     {
02830         if (pCol->IsTransparent())
02831         {
02832             // This is a 'no colour' type colour, so output a zero-length colour name,
02833             // as this is the only way we can handle this at the moment.
02834             return;
02835         }
02836         else
02837         {
02838             // Otherwise make up a colour name (see epsfiltr.h).
02839             OverflowTextWrite (_T("("));
02840             OverflowTextWrite (ImmediateColourFudgeyBodgeName);
02841             OverflowTextWrite (_T(")"));
02842         }
02843     }
02844     else
02845     {
02846         // Got an indexed colour - output its name
02847         // (Pass in TRUE to get a unique-identifier for local colours rather than "Local colour")
02848         String_64 *ColName = pIndCol->GetName(TRUE);
02849         OverflowTextWrite (_T("("));
02850         OverflowTextWrite ((TCHAR *) (*ColName));
02851         OverflowTextWrite (_T(")"));
02852     }
02853 
02854     // Always tint 0
02855     OverflowTextWrite (_T(" 0 "));
02856 }

void AIEPSRenderRegion::OverflowTextWriteSingleColour UINT32  n  )  [protected, virtual]
 

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

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/11/00
Parameters:
n - the colour value (range 0-255) to write to the EPS file. [INPUTS]
See also:
KernelDC::OutputColourValue

Definition at line 2748 of file ai_epsrr.cpp.

02749 {
02750     // Output to string
02751     TCHAR buf[20];
02752 
02753     // Convert to points, getting integer and fractional parts
02754     camSprintf (buf, _T("%.2f "), ((double) n) / 255);
02755     OverflowTextWrite (buf);
02756 }

BOOL AIEPSRenderRegion::RenderChar WCHAR  ch,
Matrix pMatrix
[virtual]
 

Overrides the default behaviour for rendering a single character. Used to store additional information on text blocks needed for AI text. i.e. the overflow text block ((xxxxxxxxx) TX) which occurs after the unjustified ((x) Tx
(x) Tx
) block. Both of these are needed for correct Illustrator export of text.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/11/00
See also:
EPSRenderRegion::RenderChar

Reimplemented from EPSRenderRegion.

Definition at line 446 of file ai_epsrr.cpp.

00447 {
00448     TCHAR buf[20];
00449     BOOL result = FALSE;        // assume failure if nothing given.
00450 
00451     if (m_bTextAsShapes)
00452     {
00453         result = RenderCharAsShape (ch, pMatrix);
00454     }
00455     else
00456     {
00457         // Output matrix (a b c d e f Tm\n) - a,b,c and d are in the range 1.0 to -1.0
00458         // Only do this for text on paths
00459         if (ExportingOnPath ())
00460         {
00461             KernelDC *pDC = (KernelDC*)CCDC::ConvertFromNativeDC(RenderDC);
00462 
00463             pDC->OutputMatrix(pMatrix);
00464             pDC->OutputToken(_T("Tm"));
00465             pDC->OutputNewLine();
00466         }
00467 
00468         // call the base class first, so that the attributes are exported BEFORE the character
00469         result = EPSRenderRegion::RenderChar (ch, pMatrix);;
00470         
00471             // store any extra information, closing an attribute gap if one is open.
00472         if (ExportingOnPath ())
00473         {
00474             OverflowTextFinishGap ();
00475             camSprintf (buf,_T("%c"),ch);
00476             OverflowTextWrite (buf);
00477         }
00478     }
00479         // Call the base class' function to do the standard export.
00480     return result;
00481 }

BOOL AIEPSRenderRegion::RenderCharAsShape WCHAR  ch,
Matrix pMatrix
[protected, virtual]
 

Allows text to be drawn as shapes, not characters, so that AI can cope with gradient filled text.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/11/00
See also:
AIEPSRenderRegion::RenderChar, EPSRenderRegion::RenderChar

Definition at line 496 of file ai_epsrr.cpp.

00497 {
00498     BOOL result = FALSE;
00499 
00500     // create the char's path
00501     Path* pCharPath=CreateCharPath(ch,pMatrix);
00502 
00503     // if the path got created correctly, then we done good...
00504     if (pCharPath!=NULL)
00505     {
00506         // if at least one point, draw path using current attibutes in render region
00507         if (pCharPath->GetNumCoords()!=0)
00508             DrawPath(pCharPath);
00509 
00510         // clean up
00511         delete pCharPath;
00512 
00513         result = TRUE;
00514     }
00515 
00516     return result;
00517 }

void AIEPSRenderRegion::RestoreClipRegion ClipRegionAttribute pClipAttr,
BOOL  Temp
[virtual]
 

Adobe Illustrator version of Karim's EPSRenderRegion::RestoreClipRegion. See SetClipRegion for why this was necessary.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
8th November 2000
Parameters:
pClipAttr ptr to the ClipRegionAttribute to restore over the current one. [INPUTS] Temp whether the attr is temporary or not.
Postscript is told to restore its last saved context. [OUTPUTS]
Restore the RR's clipping region. We do this by recording a restore-state command.

Returns:
Errors: ERROR3 if the current ClipRegionAttribute holds a NULL clip-path ptr. This state of affairs should not happen. You can't set a ClipRegionAttribute with a NULL clip-path ptr, so the only such attr is the default one, and you should never be restoring over _that_.
See also: RenderRegion::RestoreClipRegion(), EPSRenderRegion::RestoreClipRegion()

Reimplemented from EPSRenderRegion.

Definition at line 2982 of file ai_epsrr.cpp.

02983 {
02984     // we should never be entered when the current clipattr has a NULL path, as what this
02985     // means is that either somebody somehow did a SetClipRegion() with such an attr, or
02986     // somebody is trying to Restore() over the default ClipRegionAttribute (which holds a
02987     // NULL path ptr). Neither of these actions should occur.
02988 
02989     if (RR_CLIPREGION()->GetClipPath() == NULL)
02990     {
02991         ERROR3("EPSRenderRegion::RestoreClipRegion; Current ClipRegionAttribute has a NULL path");
02992     }
02993     else
02994     {
02995         // Update the RR's table of current attributes.
02996         RenderRegion::RestoreClipRegion(pClipAttr, Temp);
02997     }
02998 }

void AIEPSRenderRegion::SetClipRegion ClipRegionAttribute pClipAttr,
BOOL  Temp
[virtual]
 

The Adobe Illustrator version of Karim's EPSRenderRegion::SetClipRegion, This was needed as Illustrator uses non-standard EPS commands.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
8th November 2000
Parameters:
pClipAttr ptr to the new ClipRegionAttribute to set as current in our RR. [INPUTS] Temp whether the attr is temporary or not.
Postscript's context is saved and the commands are output to intersect its [OUTPUTS] current clipping path with that defined by the ClipAttr. Also, the RR's current attr context is updated to use this new ClipAttr.
Shrink the RR's clipping region to the region defined by pClipAttr. We do this by: 1. Recording a save-state command. 2. Exporting a description of the clipping path in pClipAttr. 3. Recording a 'clip-to-last-path' command. 4. Recording a 'start-new-path' command, as we don't want our clip-path to get stroked or rendered in any way.

Notes: We mustn't record clipping commands when rendering the default attribute. Therefore this method does *nothing whatsoever* unless pClipAttr's ptr to its clipping-path is non-NULL. This ptr is NULL in the default attr.

See also: RenderRegion::SetClipRegion(), EPSRenderRegion::SetClipRegion()

Reimplemented from EPSRenderRegion.

Definition at line 2942 of file ai_epsrr.cpp.

02943 {
02944     if (pClipAttr->GetClipPath() != NULL)
02945     {
02946         // Update the RR's table of current attributes.
02947         RenderRegion::SetClipRegion (pClipAttr, Temp);
02948 
02949         // Write out the clipping path as a mask.
02950         WriteMask(pClipAttr->GetClipPath(), pClipAttr->IsResponsibleForGrouping ());
02951     }
02952 }

void AIEPSRenderRegion::SetTextAsShapes BOOL  shapes  )  [virtual]
 

Sets the export TextAsShapes flag.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
8th November 2000
Parameters:
shapes - whether to export text as shapes (TRUE) or characters (FALSE) [INPUTS]
See also: AIEPSRenderRegion::RenderChar(), TextStory::PreExportRender, TextStory::ExportRender

Definition at line 3016 of file ai_epsrr.cpp.

03017 {
03018     m_bTextAsShapes = shapes;
03019 }

BOOL AIEPSRenderRegion::StartLayer Layer pLayer  ) 
 

Writes a layer record to the file.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/4/00
Parameters:
pLayer - A pointer to a layer object. [INPUTS]
Returns:
TRUE - Success. FALSE - An error occured.
See also:
AIEPSRenderRegion::EndLayer ()

Definition at line 382 of file ai_epsrr.cpp.

00383 {
00384     // Catch null pointers to layers.
00385     if ( pLayer != NULL )
00386     {
00387         KernelDC    *pDC            = static_cast<KernelDC *> ( CCDC::ConvertFromNativeDC(RenderDC) );
00388         TCHAR       LayerName [258];
00389 
00390         // Set up the layer's name.
00391         camSprintf ( LayerName, _T("(%s)"), ( TCHAR* ) pLayer->GetLayerID () );
00392 
00393         // Start a layer definition.
00394         pDC->OutputToken    ( _T("%AI5_BeginLayer") );
00395         pDC->OutputNewLine  ();
00396 
00397         // Set the layer's properties.
00398         pDC->OutputValue    ( ( UINT32 ) pLayer->IsVisible () );    // Is the layer visible?
00399         pDC->OutputValue    ( ( UINT32 ) 1 );                   // Is the layer previewed?
00400         pDC->OutputValue    ( ( UINT32 ) !pLayer->IsLocked () );    // Is the layer enabled?
00401         pDC->OutputValue    ( ( UINT32 ) pLayer->IsPrintable () );//Is the layer printable?
00402         pDC->OutputValue    ( ( UINT32 ) 0 );                   // Is the layer dimmed?
00403         pDC->OutputValue    ( ( UINT32 ) 0 );                   // No multilayer masks.
00404 
00405         // The ID colour.
00406         pDC->OutputValue    ( ( UINT32 ) m_LayerColour % 27 );  // Set the layer's ID colour.
00407         m_LayerColour ++;                                       // Increment colour ID.
00408 
00409         // Colour values - I don't know what they're used for.
00410         pDC->OutputValue    ( ( UINT32 ) 0 );                   // Red intensity.
00411         pDC->OutputValue    ( ( UINT32 ) 0 );                   // Blue intensity.
00412         pDC->OutputValue    ( ( UINT32 ) 0 );                   // Green intensity.
00413 
00414         // Write out the Lb tag.
00415         pDC->OutputToken    ( _T("Lb") );
00416         pDC->OutputNewLine  ();
00417 
00418         // Set the layer's name.
00419         pDC->OutputToken    ( LayerName );
00420         pDC->OutputToken    ( _T("Ln") );
00421         pDC->OutputNewLine  ();
00422 
00423         // Tell Camelot that there is an active layer.
00424         m_ActiveLayer = TRUE;
00425     }
00426 
00427     // Success!
00428     return TRUE;
00429 }

BOOL AIEPSRenderRegion::WriteBitmapBody OILBitmap pBitmap,
INT32  Width,
INT32  Height
[private]
 

Writes the bitmap's data to the file.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/4/00
Parameters:
pBitmap - A pointer to the OIL bitmap object being rendered. [INPUTS] Width - The width of the bitmap in pixels. Height - The height of the bitmap in pixels.
Returns:
TRUE - If successful. FALSE - If an error is encountered.
See also:
NodeBitmap::ExportRender ()

Definition at line 1871 of file ai_epsrr.cpp.

01874 {
01875     // Set up the local variables.
01876     KernelDC    *pDC    = static_cast<KernelDC*> ( CCDC::ConvertFromNativeDC(RenderDC) );
01877     INT32           Count   = 0;
01878 
01879     // Write the initial %.
01880     pDC->OutputToken    ( _T("%") );
01881 
01882     // Write out the bitmap data. It's necessary to go backwards through y
01883     // otherwise the bitmap is rendered upside down.
01884     for ( INT32 y = Height - 1; y >= 0; y-- )
01885     {
01886         for ( INT32 x = 0; x < Width; x++ )
01887         {
01888             Pixel32bpp  BMPPixel    = pBitmap->ReadPixel32bpp ( x, y );
01889             TCHAR       Output [7];
01890 
01891             // Wrap the line to keep the file tidy.
01892             if ( Count >= 10 )
01893             {
01894                 pDC->OutputNewLine  ();
01895                 pDC->OutputToken    ( _T("%") );
01896                 Count = 0;
01897             }
01898 
01899             // Translate the RGB values into an ASCII string.
01900             camSprintf ( Output, _T("%.2X%.2X%.2X"), BMPPixel.Red, BMPPixel.Green, BMPPixel.Blue );
01901 
01902             // And output them. I'm writing directly to the file because the OutputToken ()
01903             // function introduces spaces between the values, which is not a good thing for
01904             // the AI file format. This way, it's much happier. :)
01905             if ( !pDC->OutputTCHARAsChar ( Output, 6 ) )
01906             {
01907                 // There's been a problem.
01908                 return FALSE;
01909             }
01910 
01911             Count ++;
01912         }
01913     }
01914 
01915     // Write a new line after the bitmap record, to keep things tidy.
01916     pDC->OutputNewLine  ();
01917 
01918     return TRUE;
01919 }

BOOL AIEPSRenderRegion::WriteBitmapHeader INT32  Width,
INT32  Height
[private]
 

Writes the AI header for a bitmap record.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/4/00
Parameters:
Width - The width (in pixels) of the bitmap image. [INPUTS] Height - The height (in pixels) of the bitmap image.
Returns:
TRUE - If successful. FALSE - If an error is encountered.
See also:
NodeBitmap::ExportRender ()

Definition at line 1791 of file ai_epsrr.cpp.

01793 {
01794     // Set up kernel DC up in an appropriate form.
01795     KernelDC    *pDC    = static_cast<KernelDC *> ( CCDC::ConvertFromNativeDC(RenderDC) );
01796 
01797     // Declare the bitmap record.
01798     pDC->OutputToken    ( _T("%AI5_File:") );
01799     pDC->OutputNewLine  ();
01800     pDC->OutputToken    ( _T("%AI5_BeginRaster") );
01801     pDC->OutputNewLine  ();
01802 
01803     // (ChrisG 23/11/00) The Xh operator has been removed, as it wasn't correct (it didn't 
01804     //  have the third, unknown, value), it isn't in the Illustrator File Format Manual, 
01805     //  and all the information in it seems to be duplicated in the standard XI operator, 
01806     //  which is written out immediately after the Xh one was.
01807 
01808     // The matrix.
01809 //  WriteLoadedMatrix ();
01810 
01811     // Height and width. (and an extra value - as there's no mention of this token in the
01812     //  Illustrator file format manual, I have no idea what it signifies, but Photoshop 
01813     //  needs it, or else it gives MPS Parser Errors).
01814 //  pDC->OutputValue    ( Width );
01815 //  pDC->OutputValue    ( Height );
01816 //  pDC->OutputValue    ( 0l );
01817 //  pDC->OutputToken    ( _T("Xh") );
01818 //  pDC->OutputNewLine  ();
01819 
01820 
01821     // Write out the XI operator.
01822 
01823     // The matrix.
01824     WriteLoadedMatrix ();
01825 
01826     // The bounds of the bitmap.
01827     pDC->OutputToken    ( _T("0 0") );
01828     pDC->OutputValue    ( Width );
01829     pDC->OutputValue    ( Height );
01830 
01831     // Height and width. Note: The AI documentation puts their order the other
01832     // way around, but the AI export from Fireworks uses this order.
01833     pDC->OutputValue    ( Width );
01834     pDC->OutputValue    ( Height );
01835 
01836     // These values are always constant, and so I don't need to worry about
01837     // them changing.
01838     pDC->OutputToken    ( _T("8 3 0 0 0 0") );
01839     pDC->OutputNewLine  ();
01840 
01841     // Write out the file size.
01842     pDC->OutputToken    ( _T("%%BeginData:") );
01843     pDC->OutputValue    ( static_cast<INT32> ( Height * Width * 3 ) );
01844     pDC->OutputNewLine  ();
01845 
01846     // Wrap out the XI operator.
01847     pDC->OutputToken    ( _T("XI") );
01848     pDC->OutputNewLine  ();
01849  
01850     return TRUE;
01851 }

BOOL AIEPSRenderRegion::WriteBitmapRecord OILBitmap pBitmap  )  [private]
 

Creates a kernel bitmap instance within the AI file.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/4/00
Parameters:
pBitmap - A pointer to the OIL bitmap object being rendered. [INPUTS]
Returns:
TRUE - If successful. FALSE - If an error is encountered.
See also:
NodeBitmap::ExportRender ()

Definition at line 1755 of file ai_epsrr.cpp.

01756 {
01757     // Set up the local variables.
01758 //  KernelDC    *pDC        = static_cast<KernelDC*> ( CCDC::ConvertFromNativeDC(RenderDC) );
01759     INT32       Width       = static_cast<INT32> ( pBitmap->GetWidth () );
01760     INT32       Height      = static_cast<INT32> ( pBitmap->GetHeight () );
01761 
01762     // Write out the bitmap header.
01763     WriteBitmapHeader ( Width, Height );
01764 
01765     // Write out the body.
01766     WriteBitmapBody ( pBitmap, Width, Height );
01767 
01768     // Finish off the bitmap record.
01769     WriteBitmapTail ();
01770 
01771     // It worked!
01772     return TRUE;
01773 }

BOOL AIEPSRenderRegion::WriteBitmapTail void   )  [private]
 

Wraps up the bitmap instance.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/4/00
Parameters:
- [INPUTS]
Returns:
TRUE - If successful. FALSE - If an error is encountered.
See also:
NodeBitmap::ExportRender ()

Definition at line 2006 of file ai_epsrr.cpp.

02007 {
02008     // Set up kernel DC up in an appropriate form.
02009     KernelDC    *pDC    = static_cast<KernelDC *> ( CCDC::ConvertFromNativeDC(RenderDC) );
02010 
02011     // Wrap up the bitmap record.
02012     pDC->OutputToken    ( _T("%%EndData") );
02013     pDC->OutputNewLine  ();
02014     pDC->OutputToken    ( _T("XH") );
02015     pDC->OutputNewLine  ();
02016     pDC->OutputToken    ( _T("%AI5_EndRaster") );
02017     pDC->OutputNewLine  ();
02018 
02019     // ChrisG (27/10/00).
02020     // This token was changed from 'N' close unfilled path, to 'F' close filled path. The  
02021     //  latter preserves information about the current line width, join type, fill colour, 
02022     //  etc... Whereas the 'N' token clears all this info, so any text objects or paths which
02023     //  follow the bitmap were picking up colour and line info for an unfilled/unstroked path,
02024     //  rather than the current attributes.
02025     pDC->OutputToken    ( _T("F") );
02026     pDC->OutputNewLine  ();
02027 
02028     // The colours are no longer valid, as the bitmap definition has invalidated them.
02029     m_bValidPathAttrs = FALSE;
02030     m_bValidTextAttrs = FALSE;
02031 
02032     return TRUE;
02033 }

BOOL AIEPSRenderRegion::WriteContoneBody OILBitmap pBitmap  )  [private]
 

Writes a contone bitmap to the file as a 32bpp image.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/4/00
Parameters:
pBitmap - A pointer to the OIL bitmap object being rendered. [INPUTS]
Returns:
TRUE - If successful. FALSE - If an error is encountered.
See also:
NodeBitmap::ExportRender ()

Definition at line 1935 of file ai_epsrr.cpp.

01936 {
01937     // Set up the local variables.
01938     KernelDC    *pDC    = static_cast<KernelDC*> ( CCDC::ConvertFromNativeDC(RenderDC) );
01939     INT32       Width   = static_cast<INT32> ( pBitmap->GetWidth () );
01940     INT32       Height  = static_cast<INT32> ( pBitmap->GetHeight () );
01941     INT32           Count   = 0;
01942 
01943     // Write the initial %.
01944     pDC->OutputToken    ( _T("%") );
01945 
01946     // Write out the bitmap data. It's necessary to go backwards through y
01947     // otherwise the bitmap is rendered upside down.
01948     for ( INT32 y = Height - 1; y >= 0; y-- )
01949     {
01950         for ( INT32 x = 0; x < Width; x++ )
01951         {
01952             UINT32          Index       = pBitmap->ReadPixelGreyscale ( x, y );
01953             DocColour       PixelColour = pBitmap->GetContonePaletteEntry ( Index );
01954             TCHAR           Output [7];
01955             INT32           lRed;
01956             INT32           lGreen;
01957             INT32           lBlue;
01958 
01959             // Extract the values from the DocColour.
01960             PixelColour.GetRGBValue ( &lRed, &lGreen, &lBlue );
01961             
01962             // Wrap the line to keep the file tidy.
01963             if ( Count >= 10 )
01964             {
01965                 pDC->OutputNewLine  ();
01966                 pDC->OutputToken    ( _T("%") );
01967                 Count = 0;
01968             }
01969 
01970             // Translate the RGB values into an ASCII string.
01971             camSprintf ( Output, _T("%.2X%.2X%.2X"), lRed, lGreen, lBlue );
01972 
01973             // And output them. I'm writing directly to the file because the OutputToken ()
01974             // function introduces spaces between the values, which is not a good thing for
01975             // the AI file format. This way, it's much happier. :)
01976             if ( !pDC->OutputTCHARAsChar ( Output, 6 ) )
01977             {
01978                 // There's been a problem.
01979                 return FALSE;
01980             }
01981 
01982             Count ++;
01983         }
01984     }
01985 
01986     // Write a new line after the bitmap record, to keep things tidy.
01987     pDC->OutputNewLine  ();
01988 
01989     return TRUE;
01990 }

BOOL AIEPSRenderRegion::WriteDocumentSetup Document pDocument,
EPSFilter pFilter
[protected, virtual]
 

Browse through the tree, and if a text story is found invoke the document setup function. By only exporting the font setup when necessary, the file size produced is smaller (which makes it easier for me to interpret :) ), and it should hopefully make the filter run a bit faster too.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/3/00
Parameters:
pDocument - The document being outputted. [INPUTS] pFilter - A pointer to the export filter.
- [OUTPUTS]
Returns:
TRUE if successful. FALSE if error (e.g. file/disk error)

Reimplemented from EPSRenderRegion.

Definition at line 1177 of file ai_epsrr.cpp.

01179 {
01180     // Get the spread from the document.
01181     Spread      *pSpread    = pDocument->FindFirstSpread ();
01182     Node        *pTextStory = NULL;
01183 
01184     // Try to find a single instance of the TextStory node.
01185     pTextStory = SliceHelper::FindNextOfClass ( pSpread, pSpread,
01186                                                 CC_RUNTIME_CLASS ( TextStory ) );
01187 
01188     // If something was found...
01189     if ( pTextStory != NULL )
01190     {
01191         // ... write out the font set-up.
01192         pDocument->WriteEPSSetup ( pFilter );
01193     }
01194     else
01195     {
01196         // Otherwise just get the relevant bits.
01197         pDocument->AIExportExtras ( pFilter->GetExportDC () );
01198     }
01199 
01200     // It worked!
01201     return TRUE;
01202 }

BOOL AIEPSRenderRegion::WriteEPSProcessColours void   )  [protected, virtual]
 

Writes the colour type used to disk.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/3/000
Parameters:
pDC - The device context to output to. [INPUTS]
Returns:
TRUE if ok; FALSE if error (e.g. file/disk error or printer driver error)
See also:
EPSRenderRegion::WriteEPSProcessColours

Reimplemented from EPSRenderRegion.

Definition at line 588 of file ai_epsrr.cpp.

00589 {
00590     // Cast a pointer to the appropriate DC.
00591     KernelDC *pDC = (KernelDC*)CCDC::ConvertFromNativeDC(RenderDC);
00592 
00593     // Output the process colours
00594     pDC->OutputToken    ( _T("%%DocumentProcessColors: Cyan Magenta Yellow Black") );
00595     pDC->OutputNewLine  ();
00596 
00597     return TRUE;
00598 }

BOOL AIEPSRenderRegion::WriteEPSProlog EPSFilter pFilter,
Document pDocument
[protected, virtual]
 

This method writes out the initialisation code for the included resources.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/3/00
Parameters:
pDC - The device context to output to. [INPUTS]
Returns:
TRUE if ok; FALSE if error (e.g. file/disk error or printer driver error)
See also:
EPSRenderRegion::WriteSetup

Reimplemented from EPSRenderRegion.

Definition at line 650 of file ai_epsrr.cpp.

00652 {
00653     // Call the export method in the document.
00654     pDocument->WriteEPSProlog ( pFilter );
00655 
00656     // All done.
00657     return TRUE;
00658 }

BOOL AIEPSRenderRegion::WriteEPSResources EPSFilter pFilter,
Document pDocument
[protected, virtual]
 

This function writes out the resource inclusion string required for the AI file.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/3/00
Parameters:
pDC - The device context to output to. [INPUTS]
Returns:
TRUE if ok; FALSE if error (e.g. file/disk error or printer driver error)
See also:
EPSRenderRegion::WriteSetup

Reimplemented from EPSRenderRegion.

Definition at line 616 of file ai_epsrr.cpp.

00618 {
00619     // Cast a pointer to the appropriate DC.
00620     KernelDC *pDC = (KernelDC*)CCDC::ConvertFromNativeDC(RenderDC);
00621     
00622     // Call the export method in the document.
00623     pDocument->WriteEPSResources ( pFilter );
00624 
00625     // Add a few things necessary for the AI file format.
00626     pDC->OutputToken    ( _T("%AI3_ColorUsage: Color") );
00627     pDC->OutputNewLine  ();
00628     pDC->OutputToken    ( _T("%AI5_FileFormat 2.0") );
00629     pDC->OutputNewLine  ();
00630 
00631     // All done.
00632     return TRUE;
00633 }

BOOL AIEPSRenderRegion::WriteEPSVersion void   )  [protected, virtual]
 

Writes the relevant EPS version declaration.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/3/000
Parameters:
pDC - The device context to output to. [INPUTS]
Returns:
TRUE if ok; FALSE if error (e.g. file/disk error or printer driver error)
See also:
EPSRenderRegion::WriteEPSVersion

Reimplemented from EPSRenderRegion.

Definition at line 562 of file ai_epsrr.cpp.

00563 {
00564     // Cast the pointer to an appropriate DC.
00565     KernelDC *pDC = static_cast<KernelDC *> ( CCDC::ConvertFromNativeDC(RenderDC) );
00566 
00567     // Output the special AIEPS header start token.
00568     pDC->OutputToken    ( _T("%!PS-Adobe-3.0") );
00569     pDC->OutputNewLine  ();
00570 
00571     return TRUE;
00572 }

BOOL AIEPSRenderRegion::WriteFillEffectSteps DocColour pColour1,
INT32  pos1,
DocColour pColour2,
INT32  pos2,
INT32  bias,
EFFECTTYPE  effect
[private]
 

Writes the additional entries required for a special fill effect (rainbow or alt-rainbow) to the gradient definition, as a series of steps. See Also: AIEPSRenderRegion::WriteGradientEntry AIEPSRenderRegion::WriteLinearFill AIEPSRenderRegion::WriteRadialFill.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
4/4/2001
Parameters:
pColour1 - The colour to start from. [INPUTS] pos1 - The position of the start colour within the fill (0-100%). pColour2 - The colour to end at. pos2 - The position of the end colour within the entire fill (0-100%) bias - The fill's bias part of any profile (0-100%). effect - The type of fill effect (EFFECT_HSV_SHORT or EFFECT_HSV_LONG)
Returns:
TRUE if successful. FALSE if error (e.g. file/disk error)

Definition at line 1077 of file ai_epsrr.cpp.

01083 {
01084     ERROR3IF (effect == EFFECT_RGB, "AIEPSRenderRegion::WriteFillEffectSteps, an attempt was made to write HSV fill effect steps on an RGB fade fill");
01085 
01086     // RGB fades are the 'standard' fill, so we don't want to do any special processing on them
01087     if (effect != EFFECT_RGB)
01088     {
01089         // Start and end colour values
01090         INT32 h1 = 0;
01091         INT32 h2 = 0;
01092         INT32 s1 = 0;
01093         INT32 s2 = 0;
01094         INT32 v1 = 0;
01095         INT32 v2 = 0;
01096 
01097         // intermediate colour values / increments
01098         DocColour midColour;
01099         double hAdd = 0;
01100         double sAdd = 0;
01101         double vAdd = 0;
01102         double posAdd = 0;
01103 
01104         // First get the start and end colour components
01105         pColour1->GetHSVValue (&h1, &s1, &v1);
01106         pColour2->GetHSVValue (&h2, &s2, &v2);
01107 
01108         // Calculate the increments  
01109         //
01110         //  NOTE: if the hue changes by more than 180 deg. in a short HSV (rainbow) fill
01111         //  (or not more than 180 deg. in a long HSV (alt-rainbow) fill), then the direction
01112         //  must be reversed. This is done by changing the hue increment value.
01113         hAdd = h2-h1;
01114         if (effect == EFFECT_HSV_SHORT)
01115         {
01116             if (hAdd > 180)
01117                 hAdd -= 360;
01118             else if (hAdd < -180)
01119                 hAdd += 360;
01120         }
01121         else
01122         {
01123             if ((hAdd > 0) && (hAdd <= 180))
01124                 hAdd -= 360;
01125             else if ((hAdd <= 0) && (hAdd >= -180))
01126                 hAdd += 360;
01127         }
01128         hAdd = hAdd / (NumFillEmulationSteps + 1);
01129         sAdd = (s2-s1) / (NumFillEmulationSteps + 1);
01130         vAdd = (v2-v1) / (NumFillEmulationSteps + 1);
01131         posAdd = ((double) pos2-pos1) / (NumFillEmulationSteps + 1);
01132 
01133         // Cycle through the stops calcuating each stop's colour and position, before 
01134         //  writing them out.
01135         for (INT32 i=1; i<NumFillEmulationSteps + 1; i++)
01136         {
01137             // increment each colour value and the position
01138             h2 = (INT32)(h1 + (i * hAdd));
01139             s2 = (INT32)(s1 + (i * sAdd));
01140             v2 = (INT32)(v1 + (i * vAdd));
01141             pos2 = (INT32)(pos1 + (i * posAdd));
01142 
01143             // wrap the hue around if it's gone past 360 deg or 0 deg.
01144             if (h2>=360)
01145                 h2 -= 360;
01146             else if (h2<0)
01147                 h2 += 360;
01148 
01149             // create the colour and export.
01150             midColour.SetHSVValue (h2, s2, v2);
01151             WriteGradientEntry (&midColour, pos2, 50);
01152         }
01153     }   // End of is fill effect not an RGB fade.
01154 
01155     return TRUE;
01156 }

void AIEPSRenderRegion::WriteGradientCount  )  [private, virtual]
 

Writes out the count of all the gradient fills in the Cache.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/3/2001
See also: AIEPSRenderRegion::WriteGradientDefinitions, AIEPSRenderRegion::BuildGradientCache

Definition at line 3664 of file ai_epsrr.cpp.

03665 {
03666     KernelDC *pDC = (KernelDC*)CCDC::ConvertFromNativeDC(RenderDC);
03667     ListFill * pList    = m_pLinearGradList;
03668     INT32 numFills      = 0;
03669 
03670     // Cycle through the gradient cache writing out fills as we go.
03671     //
03672     //  First count the linear fills
03673     while (pList != NULL)
03674     {
03675         numFills ++;
03676         pList = pList->pNext;
03677     }
03678 
03679     // Then count the radial fills.
03680     pList = m_pRadialGradList;
03681     while (pList != NULL)
03682     {
03683         numFills ++;
03684         pList = pList->pNext;
03685     }
03686 
03687     // If there are any fills, then write the count out.
03688     if (numFills)
03689     {
03690         pDC->OutputValue (numFills);
03691         pDC->OutputToken (_T("Bn"));
03692         pDC->OutputNewLine ();
03693     }
03694 }

void AIEPSRenderRegion::WriteGradientDefinitions  )  [private, virtual]
 

Writes out the definitions of all the gradient fills in the Cache.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
5/2/2001
See also: AIEPSRenderRegion::WriteGradientCount, AIEPSRenderRegion::BuildGradientCache

Definition at line 3708 of file ai_epsrr.cpp.

03709 {
03710     ListFill *              pList = NULL;
03711     FillGeometryAttribute * pFill = NULL;
03712 
03713     // Cycle through the gradient cache writing out fills as we go.
03714     //
03715     //  First do the linear list.
03716     pList = m_pLinearGradList;
03717     while (pList != NULL)
03718     {
03719         pFill = pList->pFill;
03720         WriteLinearFill ( pFill, pList->effect, pList->id );
03721         pList = pList->pNext;
03722     }
03723 
03724     // Then do the radial list.
03725     pList = m_pRadialGradList;
03726     while (pList != NULL)
03727     {
03728         pFill = pList->pFill;
03729         WriteRadialFill ( pFill, pList->effect, pList->id );
03730         pList = pList->pNext;
03731     }
03732 }

BOOL AIEPSRenderRegion::WriteGradientEntry DocColour pColour,
INT32  Position,
INT32  Midpoint
[private]
 

Writes a line into the definition of a gradient fill.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/3/00
Parameters:
pColour - A pointer to a Camelot colour. [INPUTS] Position - The position of the colour within the fill. Midpoint - The midpoint of the fill.
Returns:
TRUE if successful. FALSE if error (e.g. file/disk error)

Definition at line 1002 of file ai_epsrr.cpp.

01005 {
01006     INT32 red;                                          //
01007     INT32 green;                                            // RGB colour values
01008     INT32 blue;                                         //
01009     PColourCMYK CMYKColour;                             // The colour to be stored.
01010 
01011     KernelDC *pDC = (KernelDC*)CCDC::ConvertFromNativeDC(RenderDC);
01012     TCHAR       Line [80];                              // Contains the string to be stored.
01013 
01014     // (ChrisG 3/4/2001) 
01015     if (Midpoint < 13)
01016         Midpoint = 13;
01017     else if (Midpoint > 87)
01018         Midpoint = 87;
01019 
01020     pColour->GetCMYKValue ( &CMYKColour );              // Extract the CMYK value.
01021 
01022     if (pColour->GetColourModel () == COLOURMODEL_RGBT ||
01023         pColour->GetColourModel () == COLOURMODEL_HSVT)
01024     {
01025         // Use RGB syntax.
01026         pColour->GetRGBValue ( &red, &green, &blue );
01027 
01028         camSprintf ( Line, _T("2 %d %d%%_Bs"), Midpoint, Position );
01029         pDC->OutputColour       ( &CMYKColour );
01030         pDC->OutputColourValue  ( red );
01031         pDC->OutputColourValue  ( green );
01032         pDC->OutputColourValue  ( blue );
01033         pDC->OutputToken        ( Line );
01034         pDC->OutputNewLine      ();
01035     }
01036     else
01037     {
01038 
01039         // It is necessary to build the output line like this, so that there isn't a space
01040         // between the position of the colour, and the %_Bs operator.
01041         camSprintf ( Line, _T("1 %d %d%%_Bs"), Midpoint, Position );    // Build the output string.
01042 
01043         pDC->OutputColour   ( &CMYKColour );                // Write the colour to the file.
01044         pDC->OutputToken    ( Line );                       // Write the output string out.
01045         pDC->OutputNewLine  ();                             // And write a new-line tag.
01046     }
01047 
01048     return TRUE;                                        // All done successfully.
01049 }

void AIEPSRenderRegion::WriteGradientFillInstance  )  [private, virtual]
 

This function identifies whether or not the current fill is a gradient fill, and writes in the appropriate values if it is. I've already created the records of the gradients themselves (see above), so this is just a case of matching the gradient with its ID, and Adobe Illustrator can then put the records together.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/03/00
(ChrisG 18/12/00) - all this does now is increment the counters used for determining which gradient fill is currently being used.

See also:
EPSRenderRegion::WriteGradientFill, WriteGradientFillUsage

Reimplemented from EPSRenderRegion.

Definition at line 1259 of file ai_epsrr.cpp.

01260 {
01261     KernelDC *pDC = (KernelDC*)CCDC::ConvertFromNativeDC(RenderDC);
01262     FillGeometryAttribute   *pFillAttr  = ( FillGeometryAttribute* )
01263                                             CurrentAttrs[ATTR_FILLGEOMETRY].pAttr;
01264     DocCoord                StartPoint  = *( pFillAttr->GetStartPoint () );
01265     DocCoord                EndPoint    = *( pFillAttr->GetEndPoint () );
01266     DocCoord                Delta       = EndPoint - StartPoint;
01267     double                  Angle       = 90.0f;
01268     double                  Length      = FlashExportDC::CalculateLength ( Delta );
01269     TCHAR                   Name [80];
01270     BOOL                    IsRadial    = pFillAttr->IsARadialFill () ||
01271                                           pFillAttr->IsASquareFill ();
01272     INT32                   id          = 0;
01273 
01274     if (IsGradientFillValidForExport (pFillAttr))
01275     {
01276         id = FindGradientInCache (pFillAttr, GetFillEffect ());
01277 
01278         // If the fill is, or can be approximated by, a radial fill, set the the definition to
01279         // indicate this.
01280         if ( IsRadial )
01281         {
01282             // Set up the name to show that it's a radial gradient.
01283             camSprintf ( Name, _T("(%s %d)"), RadialGradient, id );
01284         }
01285         // Otherwise it's represented by a linear fill.
01286         else
01287         {
01288             // Set up the name to show that it's a linear gradient.
01289             camSprintf ( Name, _T("(%s %d)"), LinearGradient, id );
01290         
01291             // Reset the end point value if we're dealing with a three colour fill.
01292             if ( pFillAttr->IsAThreeColFill () )
01293             {
01294                 DocCoord    EndPoint2   = *( pFillAttr->GetEndPoint2 () );
01295 
01296                 // Complete the parallellogram of vectors.
01297                 EndPoint += EndPoint2 - StartPoint;
01298             }
01299         }
01300 
01301         // (ChrisG 16/01/01) Since all the endpoint calculations have now been done,
01302         //  we can determine Delta, length and angle. (NOTE: these cannot be done 
01303         //  before here, as we wouldn't be using the correct endpoint values.)
01304         Delta   = EndPoint - StartPoint;
01305         Length  = FlashExportDC::CalculateLength ( Delta );
01306 
01307         // The tangent of an angle is undefined for PI/2 radians. (i.e. when Delta.x
01308         // is zero.)
01309         if ( Delta.x != 0 )
01310         {
01311             Angle = atan ( ( double ) Delta.y / ( double ) Delta.x );
01312 
01313             // AI uses degrees, whereas the standard maths library uses radians, so
01314             // effect a conversion.
01315             Angle *= ( 180.0 / PI );    // Pi radians = 180 degrees.
01316 
01317             // Tan repeats itself every Pi radians, so add 180 degrees to the angle
01318             // if it's got a negative value of Delta.y. Special case: If Delta.x is
01319             // negative, and Delta.y is 0, the angle is 180 degrees.
01320             if ( Delta.x < 0 )
01321             {
01322                 // I want the angle to be in the interval ]-180, 180], and so I've
01323                 // got special case handling, depending on which quadrant it lies
01324                 // in initially. Without the if statement here, the interval would
01325                 // be ]-90, 270].
01326                 if ( Angle >= 0.0 )
01327                 {
01328                     Angle -= 180.0;
01329                 }
01330                 else
01331                 {
01332                     Angle += 180.0;
01333                 }
01334             }
01335         }
01336 
01337         // More special case stuff. If Delta.x is 0, then the angle must be either
01338         // +90 or -90 degrees. And we can get the sign of the angle from the sign
01339         // of Delta.y
01340         else if ( Delta.y < 0 )
01341         {
01342             Angle = -90.0;
01343         }
01344 
01345         // AI uses points as a co-ordinate system - we use millipoints. Dividing
01346         // the length of the fill by 1,000 will thus return it's value in points.
01347         Length /= 1000;
01348 
01349         // Write out the appropriate fill record.
01350         pDC->OutputToken    ( _T("1") );                // It is a clipped gradient.
01351         pDC->OutputToken    ( Name );               // The gradient's name.
01352         pDC->OutputCoord    ( StartPoint );         // Start point for the gradient fill.
01353         pDC->OutputReal     ( Angle );              // The angle of the fill from the X-Axis.
01354         pDC->OutputReal     ( Length );             // The length of the matrix.
01355         pDC->OutputToken    ( _T("1 0 0 1 0 0 Bg") );   // Matrix manipulating the fill. (Unused.)
01356         pDC->OutputNewLine  ();
01357 
01358     }   // End of IsGradientFillValidForExport.
01359 }

BOOL AIEPSRenderRegion::WriteGradientFills Document pDocument  )  [protected, virtual]
 

Parses through the tree, identifies any gradient fills, and writes them to the export DC's file.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/3/00
Parameters:
pDocument - The document to be written. [INPUTS]
- [OUTPUTS]
Returns:
TRUE if successful. FALSE if error (e.g. file/disk error)

Reimplemented from EPSRenderRegion.

Definition at line 675 of file ai_epsrr.cpp.

00676 {
00677     // Get the spread from the document.
00678     Spread      *pSpread        = pDocument->FindFirstSpread ();
00679 
00680     // Build the gradient cache up from all the fills under the spread, after cleaning any 
00681     //  junk out of it (there shouldn't be any there, but that ain't the point)
00682     ClearGradientCache ();
00683     BuildGradientCache (pSpread);
00684 
00685     // Write out the number of fills and their definition.
00686     WriteGradientCount ();
00687     WriteGradientDefinitions ();
00688 
00689     // The fill has been successfully saved, so return TRUE.
00690     return TRUE;
00691 }

BOOL AIEPSRenderRegion::WriteLinearFill FillGeometryAttribute pFill,
EFFECTTYPE  effect,
INT32  id
[private]
 

Writes a linear fill to the disk file.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/3/00
Parameters:
pFill - A pointer to the fill attribute record. [INPUTS] id - the id number for the fill
Returns:
TRUE - If successful. FALSE - The was an error (e.g. file/disk error).

Definition at line 707 of file ai_epsrr.cpp.

00708 {
00709     // Extract the fill attribute - this is necessary for processing the fill type.
00710     KernelDC                *pDC                = static_cast<KernelDC *> ( CCDC::ConvertFromNativeDC(RenderDC) );
00711     INT32                       Colours             = 2;
00712     TCHAR                   GradientName [32];
00713     DocColour               StartColour         = *( pFill->GetStartColour () );
00714     DocColour               EndColour;
00715     ColourRamp              *pRamp              = pFill->GetColourRamp ();
00716 
00717     // The fill is, or can be approximated by, a linear fill.
00718     camSprintf ( GradientName, _T("(%s %d)"), LinearGradient, id );
00719 
00720     // (ChrisG 16/01/01) Four colour fill MUST come first, as it's derived from Three
00721     //  colour fill, and returns valid for IsThreeColFill().
00722     if ( pFill->IsAFourColFill () )
00723     {
00724         // I'm going to use a version of the below here, but for now I'll just
00725         // set up the end colour as the most distant end colour.
00726         EndColour   = *( pFill->GetEndColour3 () );
00727     }
00728     else if ( pFill->IsAThreeColFill () )
00729     {
00730         // AI doesn't support three colour fills, so I'm going to fake it. This
00731         // code merges the two end colours to approximate the fill with a two
00732         // colour linear fill.
00733         EndColour.Mix ( pFill->GetEndColour (), pFill->GetEndColour2(),
00734                         0.5f, NULL, FALSE, NULL );
00735     }
00736     else
00737     {
00738         // Set up the end colour value appropriately.
00739         EndColour   = *( pFill->GetEndColour () );
00740     }
00741 
00742     // Count the number of colours.
00743     if ( pRamp != NULL )
00744     {
00745         UINT32  First   = 0;
00746         UINT32  Last    = 0;
00747 
00748         // Extract the indices from the colour ramp.
00749         pRamp->GetIndexRange ( &First, &Last );
00750 
00751         // And add their difference to the colour count. Note, you need to add one
00752         // to the result so that you don't register having no colours. There really
00753         // should be a count number of elements method in the ramp code, though.
00754         Colours += 1 + Last - First;
00755     }
00756 
00757     // (ChrisG 15/01/01) If this is a four colour fill, since we will be adding a mid-colour
00758     //  below, then we need to include it in the definition
00759     if (pFill->IsAFourColFill ())
00760     {
00761         Colours ++;
00762     }
00763 
00764     // (ChrisG 4/4/2001) Add in the extra colours given from the HSV fill effect emulation
00765     if (effect == EFFECT_HSV_SHORT || effect == EFFECT_HSV_LONG)
00766     {
00767         Colours += (Colours - 1) * NumFillEmulationSteps;
00768     }
00769 
00770     // Write the gradient's header.
00771     pDC->OutputToken    ( _T("%AI5_BeginGradient:") );
00772     pDC->OutputToken    ( GradientName );
00773     pDC->OutputNewLine  ();
00774 
00775     // Then the type definition.
00776     pDC->OutputToken    ( GradientName );
00777     pDC->OutputValue    ( static_cast<INT32> ( LinearFill ) );
00778     pDC->OutputValue    ( static_cast<INT32> ( Colours ) );
00779     pDC->OutputToken    ( _T("Bd") );
00780     pDC->OutputNewLine  ();
00781     pDC->OutputToken    ( _T("[") );
00782     pDC->OutputNewLine  ();
00783 
00784     // (ChrisG 3/4/2001) Get bias and convert to 0-100 range (from -1 to +1)
00785     //  This will be used later on to offset the positions
00786     CProfileBiasGain profile = pFill->GetProfile ();
00787     INT32 bias = (INT32) ((1 - (double) profile.GetBias ()) * 50);
00788 
00789     // Write out the last colour.
00790     WriteGradientEntry ( &EndColour, 100, 50 );
00791 
00792     // set up the last colour and position (for the fill effect emulation.
00793     DocColour * pLastColour = &EndColour;
00794     INT32 lastPos = 100;
00795 
00796     // Mid colour for four colour fills - this needs to be stored longer so that it can be
00797     //  re-used in the case of HSV fill effects.
00798     DocColour   MidColour;
00799 
00800     // If the fill is a four colour fill, add a mid-colour that's a blend of the
00801     // second and third colours.
00802     if ( pFill->IsAFourColFill () )
00803     {
00804 
00805         MidColour.Mix ( pFill->GetEndColour (), pFill->GetEndColour2 (),
00806                         0.5f, NULL, FALSE, NULL );
00807 
00808         // Write out the extra fill steps, if there are any.
00809         if (effect != EFFECT_RGB)
00810         {
00811             WriteFillEffectSteps (pLastColour, lastPos, &MidColour, 50, bias, effect);
00812             pLastColour = &MidColour;
00813         }
00814 
00815         // And set the value.
00816         WriteGradientEntry ( &MidColour, 50, bias);
00817     }
00818 
00819     // Otherwise, process the colour ramp.
00820     else if ( pRamp != NULL )
00821     {
00822         ColRampItem *pItem = pRamp->GetLastCol ();
00823 
00824         // Write in the ramp's colour values.
00825         while ( pItem != NULL )
00826         {
00827             // Get the position of the colour in the fill.
00828             INT32       Ratio   = static_cast <INT32> ( 100 * pItem->GetPosition () );
00829             DocColour   *pCol   = pItem->GetColourAddr ();
00830 
00831             // Write out the extra fill steps, if there are any.
00832             if (effect != EFFECT_RGB)
00833             {
00834                 WriteFillEffectSteps (pLastColour, lastPos, pCol, Ratio, bias, effect);
00835                 pLastColour = pCol;
00836                 lastPos = Ratio;
00837             }
00838 
00839             // And set the value.
00840             WriteGradientEntry ( pCol, Ratio, 50 );
00841 
00842             // Increment the pointer onto the next item.
00843             pItem = pRamp->GetPrevCol ( pItem );
00844         }
00845     }
00846 
00847     // Write out the extra fill steps, if there are any.
00848     if (effect != EFFECT_RGB)
00849     {
00850         WriteFillEffectSteps (pLastColour, lastPos, &StartColour, 0, bias, effect);
00851     }
00852 
00853     // Write out the start colour.
00854     WriteGradientEntry ( &StartColour, 0, bias );
00855 
00856     // Write out the end of gradient tokens.
00857     pDC->OutputToken    ( _T("BD") );
00858     pDC->OutputNewLine  ();
00859     pDC->OutputToken    ( _T("%AI5_EndGradient") );
00860     pDC->OutputNewLine  ();
00861 
00862     // It worked!
00863     return TRUE;
00864 }

BOOL AIEPSRenderRegion::WriteLoadedMatrix void   )  [private]
 

Writes a pre-loaded matrix to the file. I've added a couple of functions to create a matrix first, since it'll be more efficient to store the data, and re-write it as required, than to recalculate it twice.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/4/00
Parameters:
- [INPUTS]
Returns:
TRUE - Success. FALSE - An error occured.
See also:
AIESPRenderRegion::LoadBitmapMatrix, AIEPSRenderRegion::LoadTranslationMatrix

Definition at line 1554 of file ai_epsrr.cpp.

01555 {
01556     // Cast the DC pointer to be a KernelDC pointer. This allows it to access useful member
01557     // functions.
01558     KernelDC    *pDC    = static_cast<KernelDC *> ( CCDC::ConvertFromNativeDC(RenderDC) );
01559 
01560     // Write the matrix.
01561     pDC->OutputToken    ( _T("[") );
01562     pDC->OutputReal     ( m_a );
01563     pDC->OutputReal     ( m_b );
01564     pDC->OutputReal     ( m_c );
01565     pDC->OutputReal     ( m_d );
01566     pDC->OutputCoord    ( m_T );
01567     pDC->OutputToken    ( _T("]") );
01568 
01569     return TRUE;
01570 }

BOOL AIEPSRenderRegion::WriteMask Path MaskPath,
BOOL  OutputGroupToken = FALSE
 

Creates a path that defines a masking pattern. All successive paths (until the end of mask operator) will be clipped to this shape.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
7/4/00
Parameters:
DrawPath - The path to render. [INPUTS] OutputGroupToken whether or not we output a 'q' clipping group token.
I've repeated a lot of code from EPSRenderRegion::ExportPath because I'm scared of changing what is a fairly fundamental class, and then finding that there are several hundred resultant problems. A lot of the filters are pretty shakey at the moment in any case.
See also:
RenderRegion::ExportPath

Definition at line 1591 of file ai_epsrr.cpp.

01592 {
01593     KernelDC    *pDC        = static_cast<KernelDC*> ( CCDC::ConvertFromNativeDC(RenderDC) );   // DC for export file.
01594     DocCoord    *Coords     = MaskPath->GetCoordArray();
01595     PathVerb    *Verbs      = MaskPath->GetVerbArray();
01596     INT32           NumCoords   = MaskPath->GetNumCoords();
01597     INT32           ReadPos     = 1;                                    // Reading data from.
01598     BOOL        IsCompound  = FALSE;
01599 
01600     // (ChrisG 16/01/01) Only write masks/clips if there is a path to clip to.
01601     if (NumCoords != 0)
01602     {
01603         if (OutputGroupToken)
01604         {
01605             // Start the mask.
01606             pDC->OutputToken    ( _T("q") );
01607             pDC->OutputNewLine  ();
01608         }
01609 
01610         // Check to see if this is a compound path. If it is, there will be more than one
01611         // moveto command.
01612         while ( ReadPos < NumCoords )
01613         {
01614             // Find out the type of element that we are over, after the close flag has been
01615             // removed.
01616             if ( ( ( Verbs [ReadPos] ) & ( ~PT_CLOSEFIGURE ) ) == PT_MOVETO )
01617             {
01618                 // This is a compound path - stop searching for moveto's.
01619                 IsCompound = TRUE;
01620 
01621                 // Write the tag to indicate that it's a compound path.
01622                 pDC->OutputToken    ( _T("*u") );
01623                 pDC->OutputNewLine  ();
01624                 break;
01625             }
01626             else
01627             {
01628                 // Try next point
01629                 ReadPos++;
01630             }
01631         }
01632 
01633         // Reset to start of path
01634         ReadPos   = 0;
01635 
01636         // loop through the whole path
01637         while(ReadPos < NumCoords)
01638         {
01639             // Find out the type of element that we are over (after the close flag has been removed)
01640 //          Coord P[4];
01641             switch ( (Verbs[ReadPos]) & (~PT_CLOSEFIGURE) )
01642             {
01643                 case PT_MOVETO:
01644                     // If this is in the middle of the path, specify how this sub-path
01645                     // should be rendered - this is needed so that we re-import all the flags
01646                     // correctly on complex paths (e.g. PT_CLOSEFIGURE)
01647                     if (ReadPos > 0)
01648                     {
01649                         // Write out the mask definition.
01650                         WriteMaskTags ();
01651                     }
01652 
01653                     // Output the moveto command
01654                     pDC->OutputCoord(Coords[ReadPos]);
01655                     pDC->OutputToken(TEXT("m"));
01656                     pDC->OutputNewLine();
01657                     ReadPos++;
01658                     break;
01659 
01660 
01661                 case PT_LINETO:
01662                     // Output the lineto command
01663                     pDC->OutputCoord(Coords[ReadPos]);
01664                     pDC->OutputToken(TEXT("l"));
01665                     pDC->OutputNewLine();
01666                     ReadPos++;
01667                     break;
01668 
01669 
01670                 case PT_BEZIERTO:
01671                     // If this point is a bezier, then the next 2 points should be beziers to
01672                     ENSURE((Verbs[ReadPos+1]) & (~PT_CLOSEFIGURE), "Bezier found with 1 point");
01673                     ENSURE((Verbs[ReadPos+2]) & (~PT_CLOSEFIGURE), "Bezier found with 2 points");
01674                     
01675                     // Make sure that this is not at the start of the path
01676                     ENSURE(ReadPos > 0, "Broken path found while exporting EPS" );
01677 
01678                     // Output the moveto command
01679                     pDC->OutputCoord(Coords[ReadPos]);
01680                     pDC->OutputCoord(Coords[ReadPos+1]);
01681                     pDC->OutputCoord(Coords[ReadPos+2]);
01682                     pDC->OutputToken(TEXT("c"));
01683                     pDC->OutputNewLine();
01684                     ReadPos += 3;
01685                     break;
01686 
01687                 default:
01688                     ENSURE( FALSE, "We found a Path Element that does not exist!" );
01689                     break;
01690             }
01691         }
01692 
01693         // Do the final (or possibly only) render command
01694         WriteMaskTags ();
01695 
01696         if ( IsCompound )
01697         {
01698 
01699             // End compound path
01700             pDC->OutputToken(_T("*U"));
01701             pDC->OutputNewLine();
01702         }
01703 
01704         // Wrap up the mask.
01705         pDC->OutputToken    ( _T("0 O") );
01706         pDC->OutputNewLine  ();
01707 
01708     }   // End of if there is a clip path.
01709 
01710     return TRUE;
01711 }

BOOL AIEPSRenderRegion::WriteMaskTags void   )  [private]
 

Writes out the tags at the end of each block of a mask's definition.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/4/00
Returns:
TRUE - Success. FALSE - Error.
See also:
RenderRegion::ExportPath

Definition at line 1726 of file ai_epsrr.cpp.

01727 {
01728     KernelDC    *pDC    = static_cast<KernelDC*> ( CCDC::ConvertFromNativeDC(RenderDC) );   // DC for export file.
01729 
01730     // Write out the mask definition tags.
01731     pDC->OutputToken    ( _T("h") );
01732     pDC->OutputNewLine  ();
01733     pDC->OutputToken    ( _T("W") );
01734     pDC->OutputNewLine  ();
01735     pDC->OutputToken    ( _T("n") );
01736     pDC->OutputNewLine  ();
01737 
01738     return TRUE;
01739 }

BOOL AIEPSRenderRegion::WriteNewLine void   )  [protected, virtual]
 

Writes a new line to the output of text if text is exported as characters, does nothing if it's exported as shapes.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
9th November 2000
Returns:
BOOL - whether the a new line was written successfully.
See also: EPSRenderRegion::WriteNewLine

Reimplemented from EPSRenderRegion.

Definition at line 3057 of file ai_epsrr.cpp.

03058 {
03059     BOOL success;
03060 
03061     // don't write any newlines if we're exporting text as shapes (cos' it could stuff up 
03062     //  the eps).
03063     if (GetTextAsShapes () == TRUE)
03064     {
03065         success = TRUE;
03066     }
03067     else
03068     {
03069         success = EPSRenderRegion::WriteNewLine ();
03070     }
03071 
03072     return success;
03073 }

BOOL AIEPSRenderRegion::WriteRadialFill FillGeometryAttribute pFill,
EFFECTTYPE  effect,
INT32  id
[private]
 

Writes a Radial fill to the disk file.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/3/00
Parameters:
pFill - A pointer to the fill attribute record. [INPUTS] id - The fill's id number
Returns:
TRUE - If successful. FALSE - The was an error (e.g. file/disk error).

Definition at line 880 of file ai_epsrr.cpp.

00881 {
00882     // Extract the fill attribute - this is necessary for processing the fill type.
00883     KernelDC                *pDC                = static_cast<KernelDC *> ( CCDC::ConvertFromNativeDC(RenderDC) );
00884     INT32                       Colours             = 2;
00885     TCHAR                   GradientName [32];
00886     DocColour               StartColour         = *( pFill->GetStartColour () );
00887     DocColour               EndColour           = *( pFill->GetEndColour () );
00888     ColourRamp              *pRamp              = pFill->GetColourRamp ();
00889 
00890     // The fill is, or can be approximated by, a Radial fill.
00891     camSprintf ( GradientName, _T("(%s %d)"), RadialGradient, id );
00892 
00893     // Count the number of colours.
00894     if ( pRamp != NULL )
00895     {
00896         UINT32  First   = 0;
00897         UINT32  Last    = 0;
00898 
00899         // Extract the indices from the colour ramp.
00900         pRamp->GetIndexRange ( &First, &Last );
00901 
00902         // And add their difference to the colour count. Note, you need to add one
00903         // to the result so that you don't register having no colours. There really
00904         // should be a count number of elements method in the ramp code, though.
00905         Colours += 1 + Last - First;
00906 
00907         if (effect != EFFECT_RGB)
00908         {
00909             // Add in the extra steps for the fill effect (Five extra steps between each 
00910             //  pair of colours).
00911             Colours += (Colours - 1) * NumFillEmulationSteps;
00912         }
00913     }
00914 
00915     // Write the gradient's header.
00916     pDC->OutputToken    ( _T("%AI5_BeginGradient:") );
00917     pDC->OutputToken    ( GradientName );
00918     pDC->OutputNewLine  ();
00919 
00920     // Then the type definition.
00921     pDC->OutputToken    ( GradientName );
00922     pDC->OutputValue    ( static_cast<INT32> ( RadialFill ) );
00923     pDC->OutputValue    ( static_cast<INT32> ( Colours ) );
00924     pDC->OutputToken    ( _T("Bd") );
00925     pDC->OutputNewLine  ();
00926     pDC->OutputToken    ( _T("[") );
00927     pDC->OutputNewLine  ();
00928 
00929     // (ChrisG 3/4/2001) Get bias and convert to 0-100 range (from -1 to +1)
00930     CProfileBiasGain profile = pFill->GetProfile ();
00931     INT32 bias = (INT32) ((1 - (double) profile.GetBias ()) * 50);
00932         
00933     // Write out the start colour.
00934     WriteGradientEntry ( &StartColour, 0, bias );
00935 
00936     DocColour * pLastCol = &StartColour;
00937     INT32 lastPos = 0;
00938 
00939     // Process the colour ramp.
00940     if ( pRamp != NULL )
00941     {
00942         ColRampItem *pItem = pRamp->GetFirstCol ();
00943 
00944         // Write in the ramp's colour values.
00945         while ( pItem != NULL )
00946         {
00947             // Get the position of the colour in the fill.
00948             INT32       Ratio   = static_cast <INT32> ( 100 * pItem->GetPosition () );
00949             DocColour   *pCol   = pItem->GetColourAddr ();
00950 
00951             // Write out the intermediate fill steps (if there are any).
00952             if (effect != EFFECT_RGB)
00953             {
00954                 WriteFillEffectSteps (pLastCol, lastPos, pCol, Ratio, bias, effect);
00955                 pLastCol = pCol;
00956                 lastPos = Ratio;
00957             }
00958 
00959             // And set the value.
00960             WriteGradientEntry ( pCol, Ratio, 50 );
00961 
00962             // Increment the pointer onto the next item.
00963             pItem = pRamp->GetNextCol ( pItem );
00964         }
00965     }
00966 
00967     // Write out the intermediate fill steps (if there are any).
00968     if (effect != EFFECT_RGB)
00969     {
00970         WriteFillEffectSteps (pLastCol, lastPos, &EndColour, 100, bias, effect);
00971     }
00972 
00973     // Write out the last colour.
00974     WriteGradientEntry ( &EndColour, 100, 50 );
00975 
00976     // Write out the end of gradient tokens.
00977     pDC->OutputToken    ( _T("BD") );
00978     pDC->OutputNewLine  ();
00979     pDC->OutputToken    ( _T("%AI5_EndGradient") );
00980     pDC->OutputNewLine  ();
00981 
00982     // It worked!
00983     return TRUE;
00984 }


Friends And Related Function Documentation

friend class AIEPSGradientScanRenderRegion [friend]
 

Definition at line 209 of file ai_epsrr.h.


Member Data Documentation

double AIEPSRenderRegion::m_a [private]
 

Definition at line 360 of file ai_epsrr.h.

BOOL AIEPSRenderRegion::m_ActiveLayer [private]
 

Definition at line 366 of file ai_epsrr.h.

double AIEPSRenderRegion::m_b [private]
 

Definition at line 361 of file ai_epsrr.h.

BOOL AIEPSRenderRegion::m_bInTextGap [private]
 

Definition at line 370 of file ai_epsrr.h.

BOOL AIEPSRenderRegion::m_bTextAsShapes [private]
 

Definition at line 371 of file ai_epsrr.h.

double AIEPSRenderRegion::m_c [private]
 

Definition at line 362 of file ai_epsrr.h.

double AIEPSRenderRegion::m_d [private]
 

Definition at line 363 of file ai_epsrr.h.

FILE* AIEPSRenderRegion::m_fpOverflowText [private]
 

Definition at line 369 of file ai_epsrr.h.

UINT32 AIEPSRenderRegion::m_LayerColour [private]
 

Definition at line 367 of file ai_epsrr.h.

ListFill* AIEPSRenderRegion::m_pLinearGradList [private]
 

Definition at line 357 of file ai_epsrr.h.

ListFill* AIEPSRenderRegion::m_pRadialGradList [private]
 

Definition at line 358 of file ai_epsrr.h.

DocCoord AIEPSRenderRegion::m_T [private]
 

Definition at line 364 of file ai_epsrr.h.


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