OSRenderRegion Class Reference

Encapsulates rendering using the OS. (GDI, RiscOS, etc). This object is created when something needs rendering using the OS calls instead of Gavins routines. This will be ALL THE TIME for the moment. See RenderRegion notes for more general details of this class. More...

#include <osrndrgn.h>

Inheritance diagram for OSRenderRegion:

RenderRegion ListItem CCObject SimpleCCObject OSRenderBitmap PaperRenderRegion List of all members.

Public Member Functions

 ~OSRenderRegion ()
 Default Destructor for OSRenderRegion Class.
 OSRenderRegion (const OSRenderRegion &other)
 Copy Constructor for OSRenderRegion. Constructs an OSRenderRegion that is a copy of another. Calls RenderRegion copy constructor to make a copy of the current ContextStack.
virtual BOOL AttachDevice (View *, wxDC *, Spread *SpreadToAttach=NULL, bool fOwned=false)
 Attach an OSRenderRegion to a particular device context. This merely remembers the information - the real work is done by [OS]RenderRegion::InitDevice().
virtual BOOL InitDevice ()
 Initialise the device specific mechanisms for this render region.
BOOL StartRender ()
 Initialises an OSRenderRegion for rendering.
BOOL StopRender ()
 Stops the rendering of a OSRenderRegion, saving it's current renderstate so that rendering can continue where it left off, later on. If the RenderState passed is NULL then the RenderRegion will be unlinked from the list and will then delete itself.
virtual void SetSolidColours (BOOL SetSolid)
 Allows the dithering of colours to be turned off so they look the same using GDraw as they do with the GDI. In OSRenderRegions, this causes any attached GBrush technology to drop into/out of solid colour mode.
void DrawPathToOutputDevice (Path *PathToDraw, PathShape shapePath=PATHSHAPE_PATH)
 Renders a path object to the GDI.
void DrawRect (DocRect *PathToDraw)
 Renders a rectangle using Ploygon instead of Rectangle. Used for BodgeRectangles devices whi cannot render rectangles correctly. Should really only be used when no fill brush has been set as solid ones with XORing on don't render correctly.Renders a Rectangle to the GDI.
void DrawDragRect (DocRect *PathToDraw)
 Renders a Rectangle to the GDI . Used to claim "without shifting it about" bit it does adjust it now for the differences in rendering models.
virtual void DrawDragBounds (DocRect *RectToRender)
 Used to draw a "rectangle" to screen (for dragging). However, the corners of the rectangle are passed through the current rendering matrix, so the rect may well be rotated or skewed by the time it reaches the screen.
virtual void DrawDashLine (const DocCoord &StartPoint, const DocCoord &EndPoint)
 Draws a dashed line between the two points. Uses the technology from DrawDragBounds().
void DrawLine (const DocCoord &StartPoint, const DocCoord &EndPoint)
 Renders a Line to the GDI.
void DrawPixel (const DocCoord &Point)
 Plot a single pixel in a render region.
void DrawCross (const DocCoord &Point, const UINT32 Size)
 Draws a cross in the render region. The cross consists of a vertical line 'Size' millipoints high, and a horizontal line 'Size' millipoints wide.
void DrawBlob (DocCoord p, BlobType type)
 Draw a blob. This is the type of blob that appear round objects to show that they have been selected.
void DrawBitmap (const DocCoord &Point, KernelBitmap *pBitmap)
 Draws an un-scaled Bitmap. Use this for drawing Icons for dialogue boxes etc. The Bitmap can be any size, but will be plotted unscaled. Note that 'Point' specifies where the bottom left of the bitmap will be.
void DrawBitmap (const DocCoord &Point, UINT32 BitmapID, UINT32 ToolID=NULL)
 Draws an un-scaled Bitmap. Use this for drawing Icons for dialogue boxes etc. The Bitmap can be any size, but will be plotted unscaled. Note that 'Point' specifies where the bottom left of the bitmap will be.
BOOL DrawTransformedBitmap (NodeBitmap *pNodeBitmap)
void DrawBitmapBlob (const DocCoord &Point, KernelBitmap *BlobShape)
 Draws a Bitmap Blob. It is used for drawing more complex blob shapes, like 'rotation' arrows etc. The Bitmap can be any size, but must be Monochrome. Black pixels are transparent. White pixels will EOR. Note that 'Point' currently specifies where the centre of the bitmap will be.
void DrawBitmapBlob (const DocCoord &Point, ResourceID resID)
virtual SlowJobResult DrawMaskedBitmap (const DocRect &Rect, KernelBitmap *pBitmap, MaskedRenderRegion *pMask, ProgressDisplay *Progress)
 Plots the bitmap using the mask supplied.
void DrawFixedSystemText (StringBase *TheText, DocRect &BoundsRect, UINT32 uFormat=DEFAULT_TEXT_FORMATTING)
 To draw simple text, using the default host-operating-system font. The size and style of this font are decided by the host OS (or oil code) and cannot be set in any way. To determine how much space is needed to display a string with this method, see the SeeAlso.
void SetFixedSystemTextColours (DocColour *TextCol, DocColour *Background)
 To set the text and background colour(s) for any FixedSystem text rendered in this render region in the future (within the current rendering pass).
void GetFixedSystemTextSize (StringBase *TheText, DocRect *BoundsRect, double *atDpi=NULL)
 To determine how much room is needed to plot a bit of text with OSRenderRegion::DrawFixedSystemText.
BOOL RenderGradFillPath (Path *, GradFillAttribute *)
 Render grad fills to GDI devices using whatever means available. Scope: Public.
BOOL RenderBitmapFill (Path *, BitmapFillAttribute *)
 Render bitmap fills clipped through a path. BODGED to simple plot the bitmap. Scope: Public.
virtual BOOL RenderChar (WCHAR ch, Matrix *pMatrix)
 Render a character, using the specified transform and current attributes in the render region.
BOOL StrokeProperly (Path *const )
virtual void GetRenderRegionCaps (RRCaps *pCaps)
 This function is used to help determine what an individual render region is capable of. A render can mark the things it can not render (eg transparancy) so that a more complex rendering of these parts of the document can be done.

Static Public Member Functions

static RenderRegionCreate (DocRect ClipRegion, Matrix ConvertMatrix, FIXED16 ViewScale, RenderType rType, View *pView=NULL, BOOL UseOSRendering=FALSE, BOOL bForce32BPP=FALSE)
 Creates an RenderRegion, allowing a invalid rectangle to be specified. The matrix passed is used to convert Document coords into device coords, taking into account scaling, scroll offsets etc. This function should be used to create all RenderRegions - it chooses the best RenderRegion subclass to use depending on the host environment. (e.g. on NT it chooses an OSRenderRegion that can use Win32 GDI calls).
static BOOL Init ()
 To be called during startup. Reads preferences. Scope: Static.
static void FlushEORCache (void)
 Flushes the EOR colour cache. Currently called when screen mode changes Scope: Public.
static wxSize GetFixedDCPPI (wxDC &dc)
 Fix up crazy wxWindows screen DPI calculation.
static void GetBlobRect (FIXED16, const DocCoord &BlobPoint, BlobType bType, DocRect *pResult)
 To determine the DocRect of a blob without access to a render region.
static WinRect DocRectToWin (View *pView, const Matrix &RenderMatrix, const DocRect &docrect, INT32 leftshift, INT32 topshift, INT32 rightshift, INT32 bottomshift, BOOL MightClip=FALSE)
 To convert a rectangle in Doc coordinates to a rectangle in Win coordinates. Scope: Static.
static WinRect DocRectToWin (const Matrix &RenderMatrix, const DocRect &docrect, const double dpi)
 To convert a rectangle in Doc coordinates to a rectangle in Win coordinates taking account of the destination dpi rather than assuming screen dpi as the above form does. Does not need the extra parameters that the above uses. INT32 dpi changed to double dpi (12/12/95) to improve the range of values allowed at the < 1000dpi settings that we will be using. Scope: Static.
static WinRect BitmapDocRectToWin (Matrix &RenderMatrix, const DocRect &docrect, const double dpi)
 To convert a rectangle in Doc coordinates to a rectangle in Win coordinates taking account of the destination dpi rather than assuming screen dpi as the above form does. Same as above but tries to create the rectangle better to try and help pixel problems. Scope: Static.
static BOOL CalculateGavinOffsetsWinRect (const Matrix &RenderMatrix, const DocRect &DRect, const double dpi, GMATRIX *GMat, BOOL bCentralise, double *pdXCentralAdjust, double *pdYCentralAdjust)
 To add in the offsets to the Gavin matrix. This is used when exporting bitmaps. There used to a lot of pixel alignements problems whereby on a rectangle with line colour of say 0.5pt width, you would seemingly randomly loose one or more of the lines on the exported bitmap. This is an attempt to fix this for the bitmap export case only, as other render regions have their own problems and perculiarities.
static DocRect WinRectToDoc (const Matrix &RenderMatrix, const WinRect &WRect, const double dpi)
 To convert a rectangle in Windows coordinates to a rectangle in Document (spread) coordinates taking account of the destination dpi. Does not need the extra parameters that the above uses. Scope: Static.
static MILLIPOINT GetHitTestRadius (DocView *pDocView)
 Allows user to adjust the sensitivity of hit-testing.

Static Public Attributes

static BOOL DoBetterLines

Protected Member Functions

virtual SlowJobResult DrawSeparatedMaskedBitmap (const DocRect &Rect, KernelBitmap *pBitmap, MaskedRenderRegion *pMask, ProgressDisplay *Progress)
 Plots the bitmap using the mask supplied. The bitmap is colour separated according to the current ColourPlate settings, and output (a scanline at a time) in an 8bpp greyscale format.
 OSRenderRegion (DocRect ClipRegion, Matrix ConvertMatrix, FIXED16 ViewScale=1)
 Constructor for OSRenderRegion, allowing a invalid rectangle to be specified. The matrix passed is used to convert Document coords into device coords, taking into account scaling, scroll offsets etc. All RFlags values default to FALSE. The creator should set them.
void InitClipping ()
 Creates a Windows CRgn object from the DocRect passed in the constructor. The CRgn is set as the current clipping region during reendering. Scope: Private.
void DeInitClipping ()
 Destroys the GDI clipping region object, and unsets the clipping region for our DC.
void InitAttributes ()
 Sets up a default GDI pen and brush for rendering, and calculates the Brush origin for aligned fill patterns. Scope: Private.
void DeInitAttributes ()
 Deletes the GDI pen and brush objects.
void SetLineAttributes (ChangeLineAttrType Type=CHANGELINEATTR_ALL)
 When a line attribute is changed, this functions is called to create a new pen to mirror the new attribute value. Scope: Private.
void SetFillAttributes (ChangeAttrType Type=CHANGEATTR_ALL)
 When a fill attribute is changed, this functions is called to create a new brush to mirror the new attribute value. Scope: Private.
void SetOSDrawingMode ()
 Sets the current drawing mode. Scope: Private.
void SetQualityLevel ()
 Called when Quality level changes. We do nothing currently.
Coord DocCoordToOS256 (const DocCoord &DocPoint)
 Converts a DocCoord to a OS256 Coord. Used during rendering.
WinCoord DocCoordToWin (const DocCoord &DocPoint)
 Converts a DocCoord to a WinCoord. Used during rendering.
WinRect DocRectToWin (const DocRect &docrect, INT32 leftshift, INT32 topshift, INT32 rightshift, INT32 bottomshift, BOOL MightClip=FALSE)
BOOL RenderRadialFill (Path *PathToDraw, RadialFillAttribute *Fill)
 Renders the path with a gradient fill.
BOOL RenderLinearFill (Path *PathToDraw, LinearFillAttribute *Fill)
 Renders the path with a gradient fill.
BOOL RenderConicalFill (Path *PathToDraw, ConicalFillAttribute *Fill)
 Renders the path with a gradient fill.
BOOL RenderSquareFill (Path *PathToDraw, SquareFillAttribute *Fill)
 Renders the path with a gradient fill.
BOOL RenderThreeColFill (Path *PathToDraw, ThreeColFillAttribute *Fill)
 Renders a three colour gradient fill to a Windows DC.
BOOL RenderFourColFill (Path *PathToDraw, FourColFillAttribute *Fill)
 Renders a four colour gradient fill to a Windows DC. This is done by breaking the fill up into a large number of tiles, and then applying these with the colour at that point of the fill. This is in common with the other fills, and much of the code in this function has been derived from the other fill rendering functions.
void CreateNewPen ()
 Creates a new Pen, based on the current line attributes. Scope: Private.
void SelectNewPen ()
void CreateNewBrush ()
 Creates a new Brush, based on the current fill attributes. Scope: Private.
void SelectNewBrush ()
 Selects RenderBrush while setting its new origin. A common operation that is in its own function to cope with things such as metafiles which cannot do this. Scope: Private.
BOOL SelectNewFont (WORD Typeface, BOOL Bold, BOOL Italic, MILLIPOINT Width, MILLIPOINT Height, ANGLE Rotation)
 Selects the specified font into the DC. Performs clever stuff to cache the font so that subsequent requests for the same font don't cause anything to happen.
void MakeDashType (DashRec &, DashType *)
void RenderPath32 (Path *DrawPath)
 Renders a path using Win32 GDI. Causes an ENSURE on Win16 as should never be called. Scope: Private.
void RenderPath (Path *DrawPath)
 Renders a path to the GDI. Can recurse in the case of arrow heads. Scope: Private.
BOOL RawRenderPath32 (Path *const )
BOOL RawRenderPath (DocCoord *const, PathVerb *const, INT32 NumCoords, INT32 *PolyCount, INT32 *Count, INT32 Flatness=0, INT32 *pActualFlatness=NULL)
 Low level primitive for rendering paths without GDI32. Note that PointArray should be freed by the caller upon completion.
BOOL SetClipToPathTemporary (Path *const)
 To set a complex clip path. This clip is pretty temporary and should be reset afterwards using OSClipRegion before anything much else is done.
BOOL Bezier (INT32 Px0, INT32 Py0, INT32 Px1, INT32 Py1, INT32 Px2, INT32 Py2, INT32 Px3, INT32 Py3, INT32 Flatness)
 Flattens bezier path into an array of POINTS (for polyline). Scope: Private.
BOOL Split (INT32 Px0, INT32 Py0, INT32 Px1, INT32 Py1, INT32 Px2, INT32 Py2, INT32 Px3, INT32 Py3, INT32 Flatness)
 Splits a bezier curve into two halves, and flattens each half. Scope: Private.
INT32 CalcPathFlattening ()
 Adjust the bezier curve flattening according to the resolution of the destination device and the view scale. Scope: Private.
INT32 MPtoLP (MILLIPOINT MPtoConvert)
 Converts a value in MilliPoints into a GDI Logical value. IT ASSUMES A MM_TEXT MAPPING MODE AT PRESENT. Scope: Private.
wxColour CalcEORColour (DocColour &Wanted, COLORREF=RGB(255, 255, 255))
 To calculate correct colours when draing in EOR mode. Intended to be called by OSRenderRegion code only (normally SetxxxColur).
void CalcLogBrush (wxBrush *, DocColour &)
 To calculate a brush object given a Colour. Normally used for brushes to fill things.
wxPoint FindBitmapOrigin (DocCoord Centre, INT32 Width, INT32 Height)
 Finds the windows origin to plot a bitmap at, so that it's centre will be at the DocCoord specified.
MILLIPOINT CalcScaledPixelWidth ()
 Calculates the size of a Pixel in MILLIPOINTS, based on the output DPI and current scale factor.
MILLIPOINT CalcPixelWidth ()
 Calculates the size of a Pixel in MILLIPOINTS, based on the output DPI but IGNORES the scale factor.
void GetValidPen ()
void GetValidBrush ()

Static Protected Member Functions

static MILLIPOINT CalcDistance (DocCoord a, DocCoord b)
static void MakeEllipticalPath (Path *pPath, DocCoord Parallel[4])

Protected Attributes

struct {
   BOOL   Metafile: 1
   BOOL   ValidPen: 1
   BOOL   ValidBrush: 1
   BOOL   UsePalette: 1
RFlags
wxRegion * OSClipRegion
wxPalette * OldPalette
GBrush GDrawBrush
INT32 InsertPos
FIXED16 PixelScale
INT32 nFillStyle
INT32 CurrentPen
INT32 CurrentBrush
wxPen RenderPen [2]
wxBrush RenderBrush [2]
wxFont * OldFont
OSRRFontInfo FontInfo
wxPoint NewBrushOrg
RRCaps Caps
BYTE * SepTables

Static Protected Attributes

static INT32 HitTestRadius = 3
 Allows the user to determine how close a mouse click can be to an object before the object is hit-tested successfully. Measured in pixels. Defaults to 3.
static wxPoint PointArray [8192]
static EORCacheClass EORCache

Detailed Description

Encapsulates rendering using the OS. (GDI, RiscOS, etc). This object is created when something needs rendering using the OS calls instead of Gavins routines. This will be ALL THE TIME for the moment. See RenderRegion notes for more general details of this class.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/5/93

Definition at line 177 of file osrndrgn.h.


Constructor & Destructor Documentation

OSRenderRegion::~OSRenderRegion  ) 
 

Default Destructor for OSRenderRegion Class.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/5/93

Definition at line 590 of file osrndrgn.cpp.

00591 {
00592     if (RenderFlags.Rendering)
00593     {
00594         TRACE( _T("StopRender() was not called before destructor\n") );
00595         StopRender();
00596     }
00597 
00598     // A bug used to cause OSClipRegion to be left undeleted when a clipping rect was set
00599     // externally.  This check is here just to make sure it doesn't creep back !!
00600     ENSURE(OSClipRegion == NULL, "Clip Region wasn't deleted");
00601 
00602     if (SepTables != NULL)
00603     {
00604         CCFree(SepTables);
00605         SepTables = NULL;
00606     }
00607 }

OSRenderRegion::OSRenderRegion const OSRenderRegion other  ) 
 

Copy Constructor for OSRenderRegion. Constructs an OSRenderRegion that is a copy of another. Calls RenderRegion copy constructor to make a copy of the current ContextStack.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/7/93
Parameters:
An OSRenderRegion to copy [INPUTS]
See also:
RenderRegion(const RenderRegion &other)

Definition at line 557 of file osrndrgn.cpp.

00558      : RenderRegion(other)
00559 {
00560     // We assume that the RenderRegion being copied is not curently rendering.
00561     CurrentPen = 0;
00562     CurrentBrush = 0;
00563 //  OldBrush = NULL;
00564 //  OldPen = NULL;
00565     OldFont = NULL;
00566     OSClipRegion = NULL;
00567     OldPalette = NULL;
00568     FontInfo.pRenderFont = NULL;
00569     FontInfo.pOldFont = NULL;
00570 
00571     RFlags = other.RFlags;
00572 
00573     // Set the render caps up
00574     GetRenderRegionCaps(&Caps);
00575 
00576     // Initialise the SepTables pointer
00577     SepTables = NULL;
00578 }

OSRenderRegion::OSRenderRegion DocRect  ClipRect,
Matrix  ConvertMatrix,
FIXED16  ViewScale = 1
[protected]
 

Constructor for OSRenderRegion, allowing a invalid rectangle to be specified. The matrix passed is used to convert Document coords into device coords, taking into account scaling, scroll offsets etc. All RFlags values default to FALSE. The creator should set them.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/5/93
Parameters:
ClipRect is a DocRect defining the invalid rectangle to be rendered. [INPUTS] ConvertMatrix is a Matrix for converting Doc coords to OS coords. ViewScale is the scale factor of the view, used to calculate how much to flatten paths etc.

Definition at line 513 of file osrndrgn.cpp.

00514     : RenderRegion(ClipRect, ConvertMatrix, ViewScale)
00515 {
00516     CurrentPen = 0;
00517     CurrentBrush = 0;
00518 //  OldBrush = NULL;
00519 //  OldPen = NULL;
00520     OldFont = NULL;
00521     OSClipRegion = NULL;
00522     OldPalette = NULL;
00523     FontInfo.pRenderFont = NULL;
00524     FontInfo.pOldFont = NULL;
00525 
00526     RFlags.Metafile   = FALSE;
00527 //  RFlags.GDI32      = FALSE;
00528     RFlags.ValidPen   = FALSE;
00529     RFlags.ValidBrush = FALSE;
00530     RFlags.UsePalette = FALSE;
00531 
00532     // We don't bother rendering paper for OSRenderRegions cos it's already been done by the
00533     // PaperRenderRegion
00534     IsPaperRendered = TRUE;
00535 
00536     // Set the render caps up
00537     GetRenderRegionCaps(&Caps);
00538 
00539     // Initialise the SepTables pointer
00540     SepTables = NULL;
00541 }


Member Function Documentation

BOOL OSRenderRegion::AttachDevice View ViewToAttach,
wxDC *  DCToAttach,
Spread SpreadToAttach = NULL,
bool  fOwned = false
[virtual]
 

Attach an OSRenderRegion to a particular device context. This merely remembers the information - the real work is done by [OS]RenderRegion::InitDevice().

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/05/94
Parameters:
A View ptr ,CDC ptr and Spread ptr to attach to the RenderRegion [INPUTS]
Returns:
TRUE if the device is attached successfully; FALSE if not.

Errors: Same as base class.

See also:
OSRenderRegion::InitDevice; RenderRegion::InitDevice

Reimplemented from RenderRegion.

Definition at line 628 of file osrndrgn.cpp.

00629 {
00630     // Call the base class first
00631     if (!RenderRegion::AttachDevice( ViewToAttach, DCToAttach, SpreadToAttach, fOwned ))
00632         return FALSE;
00633     
00634     ENSURE(RenderDC != NULL,"Attempted to attach Invalid DC to RenderRegion");
00635     // If it is a PrinterDC then set our flag to say we are Printing
00636     RenderFlags.Printing = CCDC::ConvertFromNativeDC(RenderDC)->IsPrinting();
00637 
00638     // All ok
00639     return TRUE;
00640 }

BOOL OSRenderRegion::Bezier INT32  Px0,
INT32  Py0,
INT32  Px1,
INT32  Py1,
INT32  Px2,
INT32  Py2,
INT32  Px3,
INT32  Py3,
INT32  Flatness
[protected]
 

Flattens bezier path into an array of POINTS (for polyline). Scope: Private.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/6/93
Parameters:
Many INT32s - These are the x and y coords of the 4 bezier control points [INPUTS] Flatness - the flatness of the curve
Returns:
TRUE if bezier was successfully flattened to specified flatness; FALSE if buffer overflow occurred

Definition at line 3047 of file osrndrgn.cpp.

03050 {
03051     // We can't cope with negative flatness, so return if it is
03052     if (!(Flatness > 0))
03053         return FALSE;
03054 
03055     INT32 diff;
03056 
03057     INT32 dx0 = (Px1*3 - Px0*2 - Px3);
03058     dx0 = dx0 < 0 ? -dx0 : dx0;
03059 
03060     INT32 dy0 = (Py1*3 - Py0*2 - Py3);
03061     dy0 = dy0 < 0 ? -dy0 : dy0;
03062     
03063     // Get the line's distance from the curve
03064     if (dx0 >= dy0)
03065         diff = 3*dx0 + dy0;
03066     else
03067         diff = dx0 + 3*dy0;
03068         
03069     // Is the straight line close enough to the curve ?
03070     if (diff > Flatness)
03071     {
03072         // Not close enough so split it into two and recurse for each half
03073         return Split(Px0,Py0, Px1,Py1, Px2,Py2, Px3,Py3, Flatness);
03074     }
03075     
03076     INT32 dx1 = (Px2*3 - Px0 - Px3*2);
03077     dx1 = dx1 < 0 ? -dx1 : dx1;
03078 
03079     INT32 dy1 = (Py2*3 - Py0 - Py3*2);
03080     dy1 = dy1 < 0 ? -dy1 : dy1;
03081     
03082     // Get the line's distance from the curve
03083     if (dx1 >= dy1)
03084         diff = 3*dx1 + dy1;
03085     else
03086         diff = dx1 + 3*dy1;
03087 
03088     // Is the straight line close enough to the curve ?
03089     if (diff > Flatness)
03090     {
03091         // Not close enough so split it into two and recurse for each half
03092         return Split(Px0,Py0, Px1,Py1, Px2,Py2, Px3,Py3, Flatness);
03093     }
03094 
03095     if (InsertPos >= SIZEOF_POLYLINE_BUFFER)
03096         return FALSE;                                               // stop storing points
03097 
03098     // Line is now close enough so put it into our array
03099     PointArray[InsertPos].x = INT32((Px3+128)/256);
03100     PointArray[InsertPos].y = INT32((Py3+128)/256);
03101     InsertPos++;
03102 
03103     // Successfully flattened
03104     return TRUE;
03105 }

WinRect OSRenderRegion::BitmapDocRectToWin Matrix RenderMatrix,
const DocRect DRect,
const double  dpi
[static]
 

To convert a rectangle in Doc coordinates to a rectangle in Win coordinates taking account of the destination dpi rather than assuming screen dpi as the above form does. Same as above but tries to create the rectangle better to try and help pixel problems. Scope: Static.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> and Gavin
Date:
4/10/96
Parameters:
DocRect is a rectangle on document co-ords. [INPUTS] dpi is the resolution of the device we are rendering to
Returns:
Object containing the new rectangle coordinates.

Definition at line 4081 of file osrndrgn.cpp.

04083 {
04084     // This is a version from Gavin, which should improve things
04085     OilRect OilRec;
04086     OilRec.lo.x = MatrixCalc( RenderMatrix.a, DRect.lo.x, RenderMatrix.c, DRect.lo.y ) + RenderMatrix.e;
04087     OilRec.lo.y = MatrixCalc( RenderMatrix.b, DRect.lo.x, RenderMatrix.d, DRect.lo.y ) + RenderMatrix.f;
04088     OilRec.hi.x = MatrixCalc( RenderMatrix.a, DRect.hi.x, RenderMatrix.c, DRect.hi.y ) + RenderMatrix.e;
04089     OilRec.hi.y = MatrixCalc( RenderMatrix.b, DRect.hi.x, RenderMatrix.d, DRect.hi.y ) + RenderMatrix.f;
04090 
04091     if (OilRec.lo.x > OilRec.hi.x)
04092     {
04093         MILLIPOINT Temp = OilRec.lo.x;
04094         OilRec.lo.x = OilRec.hi.x;
04095         OilRec.hi.x = Temp;
04096     }
04097     if (OilRec.lo.y > OilRec.hi.y)
04098     {
04099         MILLIPOINT Temp = OilRec.lo.y;
04100         OilRec.lo.y = OilRec.hi.y;
04101         OilRec.hi.y = Temp;
04102     }
04103 
04104     OilCoord OilSize(OilRec.hi.x-OilRec.lo.x, OilRec.hi.y-OilRec.lo.y);
04105 
04106 #if 0
04107     //
04108     // Note that this relies on ToWin performing the calculation
04109     //      +round(X*dpi/72000), -round(Y*dpi/72000)
04110     //
04111     WinCoord WinSize = OilSize.ToWin(dpi) ;         // This negates the Y.
04112 #else
04113     //
04114     // The following performs the same calculation as ToWin. Doing it here ensures
04115     // that the subsequent calculation of NewOilSize will be compatible.
04116     //
04117     WinCoord    WinSize( +(INT32)floor(OilSize.x*dpi/72000.0+0.5), -(INT32)floor(OilSize.y*dpi/72000.0+0.5) ) ;
04118 #endif
04119     // This should be the bitmap size.
04120 
04121     //
04122     // WinSize should now be the size of the export bitmap.
04123     // NewRenderMatrix.x and NewRenderMatrix.y should be the e and f
04124     // components of the new render matrix.
04125     //
04126 
04127     OilCoord OilLo = OilCoord(OilRec.lo.x,OilRec.lo.y);
04128     WinCoord WinLo = OilLo.ToWin(dpi);
04129 
04130     WinRect WinRectangle;
04131     WinRectangle.x      = WinLo.x;
04132     WinRectangle.y      = WinLo.y + WinSize.y;
04133     WinRectangle.width  = WinLo.x + WinSize.x-WinRectangle.x;
04134     WinRectangle.height = WinLo.y-WinRectangle.y;
04135 
04136     return WinRectangle;
04137 }

MILLIPOINT OSRenderRegion::CalcDistance DocCoord  a,
DocCoord  b
[static, protected]
 

Definition at line 4758 of file osrndrgn.cpp.

04759 {
04760     const double Width = (double) a.x - b.x;
04761     const double Height = (double) a.y - b.y;
04762     double Diag = Width * Width + Height * Height;
04763     const INT32 Distance = (INT32) sqrt(Diag);
04764     return Distance;
04765 }

wxColour OSRenderRegion::CalcEORColour DocColour Wanted,
COLORREF  Background = RGB(255,255,255)
[protected]
 

To calculate correct colours when draing in EOR mode. Intended to be called by OSRenderRegion code only (normally SetxxxColur).

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/11/93
Parameters:
Wanted is the colour that is finally required. Background is the colour you [INPUTS] are assumed to be drawing onto.
Returns:
The RGB value such that value XOR Background = Wanted (approx).

Errors: If cannot calculate for some reason, returns Background, which works if Wanted is black. Scope: Protected

Definition at line 971 of file osrndrgn.cpp.

00972 {
00973     // This routine caches the last EOR colour it calculated so that we don't create
00974     // a bitmap every time we e.g. draw a selection blob.
00975     INT32 R,G,B;
00976     Wanted.GetRGBValue(&R,&G,&B);
00977     return wxColour(
00978                 GetRValue(Background)^R,
00979                 GetGValue(Background)^G,
00980                 GetBValue(Background)^B
00981             );
00982 /*
00983 
00984     if (EORCache.Valid && (EORCache.SourceColour == Wanted))
00985         return(EORCache.EORColour);
00986 
00987     COLORREF Result;
00988     INT32 Red, Green, Blue;
00989     Wanted.GetRGBValue(&Red, &Green, &Blue);
00990 
00991     if (RFlags.UsePalette)
00992     {
00993         // a palette device has to be quite different - get palette indices and XOR
00994         // them together, then return that as a palette index
00995         const UINT32 BGIndex = PaletteManager::GetPalette()->GetNearestPaletteIndex( Background );
00996         const UINT32 FGIndex = PaletteManager::GetPalette()->GetNearestPaletteIndex( RGB(Red,Green,Blue) );
00997 
00998         Result = PALETTEINDEX( BGIndex ^ FGIndex );
00999     }
01000     else
01001     {
01002         // non-palette devices we XOR into a little bitmap to work it out
01003         CBitmap Tiny, *OldBitmap;
01004         CDC MemDC;
01005 
01006         BOOL bStatus;
01007 
01008         bStatus = MemDC.CreateCompatibleDC( RenderDC );
01009         ENSURE(bStatus, "cant create comp DC");
01010 
01011         bStatus = Tiny.CreateCompatibleBitmap( RenderDC, 1, 1 );        // make a tiny bitmap
01012                                                                         // compatible with screen
01013                                                                         // so colours OK
01014         ENSURE(bStatus, "cant create Tiny bitmap");
01015 
01016         OldBitmap = MemDC.SelectObject( &Tiny );
01017         if (OldBitmap == NULL)
01018         {
01019             ENSURE(FALSE, "Cant select tiny bitmap");
01020             return RGB(255,255,255);                                    // return WHITE
01021         }
01022 
01023         MemDC.SetPixel( 0,0, Background );
01024         MemDC.SetROP2( R2_XORPEN );                                     // into XOR mode
01025 
01026         MemDC.SetPixel( 0,0, RGB(Red, Green, Blue) );
01027 
01028 
01029         Result = MemDC.GetPixel( 0,0 );
01030         ENSURE( Result!=0xFFFFFFFF, "GetPixel failed");
01031 
01032         //TRACE( _T("Converted %d.%d.%d to %d.%d.%d\n"), Wanted.Red, Wanted.Green, Wanted.Blue,
01033         //                                          GetRValue(Result), GetGValue(Result), GetBValue(Result) );
01034 
01035         MemDC.SelectObject( OldBitmap );                                // restore normality
01036 
01037         // automatic destruction of HDC and Bitmaps will occur naturally
01038     }
01039 
01040 
01041     // Cache this result
01042     EORCache.SourceColour = Wanted;
01043     EORCache.EORColour = Result;
01044     EORCache.Valid = TRUE;
01045 
01046     return Result;
01047 */
01048 }

void OSRenderRegion::CalcLogBrush wxBrush *  lpBrush,
DocColour Col
[protected]
 

To calculate a brush object given a Colour. Normally used for brushes to fill things.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/4/94
Parameters:
lpBrush will be filled with a LOGBRUSH. [INPUTS] Col is used to calculate said brush.
Returns:
-

Errors: - Scope: Protected

Definition at line 1088 of file osrndrgn.cpp.

01089 {
01090     if (Col.IsTransparent())
01091     {
01092         lpBrush->SetColour(*wxBLACK);
01093         lpBrush->SetStyle(wxTRANSPARENT);
01094     }
01095     else
01096     {
01097         // VeryMono devices have everything that is not transparent as Black
01098         if (RenderFlags.VeryMono)
01099             // Unless the quality says don't fill!!!
01100             if (RRQuality.GetFillQuality() <= Quality::NoFill)
01101             {
01102                 lpBrush->SetColour(*wxBLACK);
01103                 lpBrush->SetStyle(wxTRANSPARENT);
01104             }
01105             else
01106             {
01107                 lpBrush->SetStyle(wxSOLID);
01108                 lpBrush->SetColour(*wxBLACK);
01109             }
01110         else if (DrawingMode != DM_EORPEN)
01111         {
01112             if (GDrawBrush.Available())
01113                 GDrawBrush.GetLogBrush( CurrentColContext, Col, lpBrush );
01114             else
01115             {
01116                 INT32 R,G,B;
01117                 Col.GetRGBValue(&R, &G, &B);
01118                 lpBrush->SetStyle(wxSOLID);
01119                 lpBrush->SetColour(R, G, B);
01120             }
01121         }
01122         else
01123         {
01124             lpBrush->SetStyle(wxSOLID);
01125             lpBrush->SetColour(CalcEORColour(Col));
01126         }
01127     }
01128 }

INT32 OSRenderRegion::CalcPathFlattening  )  [protected]
 

Adjust the bezier curve flattening according to the resolution of the destination device and the view scale. Scope: Private.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
31/5/93
Returns:
The max distance the lines can be away from the curve in MILLIPOINTS

Definition at line 3181 of file osrndrgn.cpp.

03182 {
03183     MILLIPOINT PixelWidth = GetScaledPixelWidth();  // The width of a pixel in DocCoords
03184     INT32 Accuracy = PixelWidth/8;                  // Accurate to 1/8 of a pixel
03185 
03186     return max(Accuracy, INT32(10));        // Ensure the value is greater than 10 MILLPOINTS
03187                                         // to avoid stack overflows.
03188 }

MILLIPOINT OSRenderRegion::CalcPixelWidth void   )  [protected, virtual]
 

Calculates the size of a Pixel in MILLIPOINTS, based on the output DPI but IGNORES the scale factor.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/7/93
Returns:
The size of a pixel in MILLIPOINTS
See also:
GetScaledPixelWidth()

Implements RenderRegion.

Definition at line 3248 of file osrndrgn.cpp.

03249 {
03250 PORTNOTE("other","Can't handle different DPIs, using X")
03251     return MILLIPOINT(double(72000) / double(OSRenderRegion::GetFixedDCPPI(*RenderDC).x)); // x
03252 }

MILLIPOINT OSRenderRegion::CalcScaledPixelWidth void   )  [protected, virtual]
 

Calculates the size of a Pixel in MILLIPOINTS, based on the output DPI and current scale factor.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/7/93
Returns:
The size of a pixel in MILLIPOINTS
See also:
CalcPixelWidth()

Implements RenderRegion.

Definition at line 3223 of file osrndrgn.cpp.

03224 {
03225 //  return (RenderView->GetPixelWidth() / ScaleFactor).MakeLong();
03226     return (MILLIPOINT)( (RenderView->GetPixelWidth().MakeDouble() / ScaleFactor.MakeDouble()) + 0.5 );
03227 /*
03228     return MILLIPOINT(double(72000) /
03229             (double(RenderDC->GetDeviceCaps(LOGPIXELSX)) * ScaleFactor.MakeDouble()));
03230 */
03231 }

BOOL OSRenderRegion::CalculateGavinOffsetsWinRect const Matrix RenderMatrix,
const DocRect DRect,
const double  dpi,
GMATRIX GMat,
BOOL  bCentralise,
double *  pdXCentralAdjust,
double *  pdYCentralAdjust
[static]
 

To add in the offsets to the Gavin matrix. This is used when exporting bitmaps. There used to a lot of pixel alignements problems whereby on a rectangle with line colour of say 0.5pt width, you would seemingly randomly loose one or more of the lines on the exported bitmap. This is an attempt to fix this for the bitmap export case only, as other render regions have their own problems and perculiarities.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> and Gavin
Date:
4/10/96
Parameters:
DocRect is a rectangle on document co-ords. [INPUTS] dpi is the resolution of the device we are rendering to RenderMatrix is the rendering matrix
An updated version of the Gavin matrix [OUTPUTS]
Returns:
Object containing the new rectangle coordinates.
See also:
OSRenderRegion::DocRectToWin;

Definition at line 4166 of file osrndrgn.cpp.

04173 {
04174     OilRect OilRec ;
04175     OilRec.lo.x = MatrixCalc( RenderMatrix.a, DRect.lo.x, RenderMatrix.c, DRect.lo.y ) + RenderMatrix.e ;
04176     OilRec.lo.y = MatrixCalc( RenderMatrix.b, DRect.lo.x, RenderMatrix.d, DRect.lo.y ) + RenderMatrix.f ;
04177     OilRec.hi.x = MatrixCalc( RenderMatrix.a, DRect.hi.x, RenderMatrix.c, DRect.hi.y ) + RenderMatrix.e ;
04178     OilRec.hi.y = MatrixCalc( RenderMatrix.b, DRect.hi.x, RenderMatrix.d, DRect.hi.y ) + RenderMatrix.f ;
04179 
04180     if (OilRec.lo.x > OilRec.hi.x)
04181     {
04182         MILLIPOINT Temp = OilRec.lo.x ;
04183         OilRec.lo.x = OilRec.hi.x ;
04184         OilRec.hi.x = Temp ;
04185     }
04186     if (OilRec.lo.y > OilRec.hi.y)
04187     {
04188         MILLIPOINT Temp = OilRec.lo.y ;
04189         OilRec.lo.y = OilRec.hi.y ;
04190         OilRec.hi.y = Temp ;
04191     }
04192     OilCoord OilSize( OilRec.hi.x-OilRec.lo.x, OilRec.hi.y-OilRec.lo.y ) ;
04193 
04194     /*  double OilXOffset = (NewOilSize.x-OilSize.x)/2.0-OilRec.lo.x ;
04195     double OilYOffset = (NewOilSize.y-OilSize.y)/2.0-OilRec.lo.y ;
04196     double Scale = (dpi/72000.0)*(1<<16)*(1<<FX) ;
04197     double WinXOffset = OilXOffset*Scale ;
04198     double WinYOffset = OilYOffset*Scale ;
04199 */
04200 
04201     double Scale = (dpi/72000.0)*(1<<16)*(1<<FX) ;
04202     double WinXOffset = -OilRec.lo.x * Scale;
04203     double WinYOffset = -OilRec.lo.y * Scale;
04204 
04205     if (bCentralise)
04206     {
04207         //
04208         // The following performs the same calculation as ToWin. Doing it here ensures
04209         // that the subsequent calculation of NewOilSize will be compatible.
04210         //
04211         WinCoord    WinSize( +(INT32)floor(OilSize.x*dpi/72000.0+0.5), -(INT32)floor(OilSize.y*dpi/72000.0+0.5) ) ;
04212         OilCoord NewOilSize( +(INT32)floor(WinSize.x*72000.0/dpi+0.5), -(INT32)floor(WinSize.y*72000.0/dpi+0.5) ) ;
04213 
04214         if (pdXCentralAdjust) *pdXCentralAdjust = ((NewOilSize.x-OilSize.x)/2.0) * Scale;
04215         if (pdYCentralAdjust) *pdYCentralAdjust = ((NewOilSize.y-OilSize.y)/2.0) * Scale;
04216 
04217     }
04218 
04219     // Adjust offsets either by calculated value or supplied value
04220     if (pdXCentralAdjust) WinXOffset += *pdXCentralAdjust;
04221     if (pdYCentralAdjust) WinYOffset += *pdYCentralAdjust;
04222 
04223     //
04224     // The matrix is modified so that the drawing is centred within the export bitmap.
04225     //
04226     GMat->CX = MakeXLong(WinXOffset) ;
04227     GMat->CY = MakeXLong(WinYOffset) ;
04228 
04229     return TRUE;
04230 }

RenderRegion * OSRenderRegion::Create DocRect  ClipRect,
Matrix  ConvertMatrix,
FIXED16  ViewScale,
RenderType  rType,
View pView = NULL,
BOOL  UseOSRendering = FALSE,
BOOL  bForce32BPP = FALSE
[static]
 

Creates an RenderRegion, allowing a invalid rectangle to be specified. The matrix passed is used to convert Document coords into device coords, taking into account scaling, scroll offsets etc. This function should be used to create all RenderRegions - it chooses the best RenderRegion subclass to use depending on the host environment. (e.g. on NT it chooses an OSRenderRegion that can use Win32 GDI calls).

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/9/93
Parameters:
ClipRect - a DocRect defining the invalid rectangle to be rendered. [INPUTS]
ConvertMatrix - a Matrix for converting Doc coords to OS coords.

ViewScale - the scale factor of the view, used to calculate how much to flatten paths etc.

rType - helps the choice of 32-bit rendering etc.

pView - The View (if any) for which the RenderRegion is to be used

UseOSRendering - TRUE to force the system to give you an OSRenderRegion, rather than diverting this call to really give you a GRenderRegion if GDraw is enabled (used by kernel-rendered dialogues which don't want transparency/grad fills, etc, and wish to render simple FixedSystem text)

Definition at line 349 of file osrndrgn.cpp.

00352 {
00353 //  const bool bCanDo32 = true;
00354 /* GAT
00355     BOOL bCanDo32 = FALSE;
00356 
00357 #if WIN32
00358     if ( IsWin32NT() || IsWin32c() )
00359     {
00360         // Running on 32-bit GDI - use special NT-only Win32 GDI functions for those devices that
00361         // make sense. Currently only 16-bit Metafiles are not done using 32-bit GDI
00362         // so that paths are manually flattened.
00363         if (rType != RENDERTYPE_METAFILE16)
00364             bCanDo32 = TRUE;
00365     }
00366 #endif
00367 */
00368     OSRenderRegion *pOS = NULL;
00369 
00370     if (rType == RENDERTYPE_MONOBITMAP || rType == RENDERTYPE_COLOURBITMAP || rType == RENDERTYPE_HITDETECT)
00371     {
00372         RenderRegion *pRender = OSRenderBitmap::Create(ClipRect, ConvertMatrix, ViewScale, rType);
00373         
00374         if (pRender)
00375         {
00376             // if its not a OSRenderRegion, then return it directly, otherwise fall through
00377             // to set the flags on it
00378             if (!pRender->IsKindOf( CC_RUNTIME_CLASS(OSRenderRegion) ))
00379                 return pRender;
00380 
00381             pOS = (OSRenderRegion*) pRender;
00382         }
00383     }
00384     else if (rType == RENDERTYPE_SCREENPAPER)
00385     {
00386         // Special render region for paper rendering.
00387 //      TRACE(_T("Creating SCREENPAPER region (%d, %d) - (%d, %d)\n"), ClipRect.lo.x, ClipRect.lo.y, ClipRect.hi.x, ClipRect.hi.y);
00388         pOS = new PaperRenderRegion(ClipRect, ConvertMatrix, ViewScale);
00389     }
00390     else if ((rType == RENDERTYPE_PRINTER) || (rType == RENDERTYPE_PRINTER_PS))
00391     {
00392 #ifndef STANDALONE
00393         // Work out what kind of printer region to get - find document's print control info.
00394         Document *pDoc = pView->GetDoc();
00395         ERROR3IF(pDoc == NULL, "No document attached to view when printing!");
00396         if (pDoc != NULL)
00397         {
00398             // Get print information for this document.
00399             PrintComponent *pPrint = 
00400                 (PrintComponent *) pDoc->GetDocComponent(CC_RUNTIME_CLASS(PrintComponent));
00401             ERROR2IF(pPrint == NULL, NULL, "Unable to find PrintComponent in document.");
00402 
00403             PrintControl *pPrintControl = pPrint->GetPrintControl();
00404             ERROR2IF(pPrintControl == NULL, NULL,
00405                      "Unable to find PrintControl object in document component.");
00406 
00407             PrintMethodType PrintType = pPrintControl->GetPrintMethod();
00408 
00409             // Work out whether or not to use straight Gavin bitmap for printing
00410             if ((PrintType == PRINTMETHOD_AABITMAP) ||
00411                 (PrintType == PRINTMETHOD_BITMAP))
00412             {
00413                 // GDraw - use GRenderPrint region.
00414                 return GRenderRegion::Create(ClipRect, ConvertMatrix, ViewScale, 
00415                                              rType, pView);
00416             }
00417         }
00418 
00419         // Is this a PostScript printer?
00420         if (rType == RENDERTYPE_PRINTER_PS)
00421         {
00422             // Yes - make a PostScript render region
00423             return new PrintPSRenderRegion(ClipRect, ConvertMatrix, ViewScale);
00424         }
00425 #endif
00426         // If we get here, then we should use normal OS rendering.
00427 //      TRACE(_T("Creating PRINTER region (%d, %d) - (%d, %d)  OSRenderRegion\n"), ClipRect.lo.x, ClipRect.lo.y, ClipRect.hi.x, ClipRect.hi.y);
00428         return new OSRenderRegion(ClipRect, ConvertMatrix, ViewScale);
00429     }
00430     else
00431     {
00432         // Always try for a GRenderRegion first - unless the caller specifically asked for
00433         // the OSRenderRegion, the whole OSRenderRegion, and nothing but the OSRenderRegion.
00434         // (But by default, we'll give 'em a GRenderRegion if we can)
00435         if ((!UseOSRendering) && (rType != RENDERTYPE_PRINTER))
00436         {
00437             RenderRegion *pRender;
00438             pRender = GRenderRegion::Create(ClipRect, ConvertMatrix, ViewScale, rType, pView, bForce32BPP);
00439             if (pRender)
00440                 return pRender;
00441         }
00442 
00443         // if failed, use normal ones
00444 //      TRACE(_T("Creating OTHER region (%d, %d) - (%d, %d)  OSRenderRegion\n"), ClipRect.lo.x, ClipRect.lo.y, ClipRect.hi.x, ClipRect.hi.y);
00445         pOS = new OSRenderRegion(ClipRect, ConvertMatrix, ViewScale);
00446     }
00447 
00448     if (!pOS)
00449         return NULL;                                // if call failed
00450 
00451     // created a new one OK - must set RFlags suitably
00452 
00453     if (
00454         (rType == RENDERTYPE_METAFILE16) ||
00455         (rType == RENDERTYPE_METAFILE32)
00456        )
00457         pOS -> RFlags.Metafile = TRUE;              // mark metafiles correctly
00458                                                     // (this fn is a friend so can get to it)
00459 
00460     if (rType == RENDERTYPE_MONOBITMAP)
00461     {
00462         pOS -> RenderFlags.VeryMono = TRUE;
00463     }
00464 
00465     if (rType == RENDERTYPE_HITDETECT)
00466     {
00467         pOS -> RenderFlags.VeryMono = FALSE;
00468         pOS -> RenderFlags.HitDetect = TRUE;
00469         pOS -> m_DoCompression = TRUE;
00470     }
00471 
00472     if (rType == RENDERTYPE_COLOURBITMAP)
00473     {
00474         pOS -> RenderFlags.VeryMono = FALSE;
00475         pOS -> m_DoCompression = TRUE;
00476     }
00477 
00478     if (
00479         (rType == RENDERTYPE_SCREEN) ||
00480         (rType == RENDERTYPE_SCREENPAPER) ||
00481         (rType == RENDERTYPE_SCREENXOR)
00482        )
00483         {
00484             // if going to the screen, might have a palette selected
00485             if (WantGDIPalette && PaletteManager::UsePalette())
00486                 pOS->RFlags.UsePalette = TRUE;
00487         }
00488 
00489 //  pOS->RFlags.GDI32 = bCanDo32;
00490 
00491     return pOS;
00492 }

void OSRenderRegion::CreateNewBrush  )  [protected]
 

Creates a new Brush, based on the current fill attributes. Scope: Private.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
31/5/93

Definition at line 1272 of file osrndrgn.cpp.

01273 {
01274     if (RRQuality.GetFillQuality() <= Quality::NoFill )
01275     {
01276         RenderBrush[CurrentBrush].SetColour(*wxBLACK);
01277         RenderBrush[CurrentBrush].SetStyle(wxTRANSPARENT);
01278     }
01279     else
01280         CalcLogBrush( &RenderBrush[CurrentBrush], RR_FILLCOLOUR() );
01281 }

void OSRenderRegion::CreateNewPen  )  [protected]
 

Creates a new Pen, based on the current line attributes. Scope: Private.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
31/5/93

Definition at line 1141 of file osrndrgn.cpp.

01142 {
01143 
01144     BOOL EmptyPen = RR_STROKECOLOUR().IsTransparent();
01145     const enum Quality::Line LineQuality = RRQuality.GetLineQuality();
01146 
01147     // if no filling going on then must have a pen
01148     if ( RRQuality.GetFillQuality() <= Quality::NoFill )
01149         EmptyPen = FALSE;
01150 
01151     if (
01152 //      RFlags.GDI32 &&                             // must be GDI32
01153         !RenderFlags.VeryMono &&                    // not to bitmaps (special colour rules)
01154         !RenderFlags.bImmediateRender &&            // not when immediate (XORing messes up)
01155         (LineQuality >= Quality::FullLine) &&       // not on simple lines
01156         !EmptyPen                                   // not on NULL pens (over complex)
01157        )
01158     {
01159 //      Windows version would have used brush calculation to set pen properties
01160 //      CalcLogBrush( &Brush, RR_STROKECOLOUR() );
01161 
01162         INT32 PenWidth = MPtoLP(RR_LINEWIDTH());
01163         if (IsPrinting())
01164         {
01165             // Make sure we don't user single pixel width pens as they won't dither.
01166             if (PenWidth < 2)
01167                 PenWidth = 2;
01168         }
01169 
01170         INT32 R,G,B;
01171         RR_STROKECOLOUR().GetRGBValue(&R,&G,&B);
01172         RenderPen[CurrentPen] = wxPen(wxColour(R,G,B), PenWidth, wxSOLID);
01173 
01174         // work out pen type
01175         switch (RR_STARTCAP())
01176         {
01177             case LineCapRound:
01178                 RenderPen[CurrentPen].SetCap(wxCAP_ROUND);
01179                 break;
01180 
01181             case LineCapSquare:
01182                 RenderPen[CurrentPen].SetCap(wxCAP_PROJECTING);
01183                 break;
01184 
01185             case LineCapButt:
01186                 RenderPen[CurrentPen].SetCap(wxCAP_BUTT);
01187                 break;
01188 
01189             default:
01190                 ENSURE(FALSE, "Bad startcap");
01191                 break;
01192         }
01193         switch (RR_JOINTYPE())
01194         {
01195             case BevelledJoin:
01196                 RenderPen[CurrentPen].SetJoin(wxJOIN_BEVEL);
01197                 break;
01198 
01199             case MitreJoin:
01200                 RenderPen[CurrentPen].SetJoin(wxJOIN_MITER);
01201                 break;
01202 
01203             case RoundJoin:
01204                 RenderPen[CurrentPen].SetJoin(wxJOIN_ROUND);
01205                 break;
01206 
01207             default:
01208                 ENSURE(FALSE, "bad jointype");
01209                 break;
01210         }
01211         return ;
01212     }
01213 
01214     // fall through to use old-fashioned 16-bit GDI pen creation if failed
01215 
01216     if (EmptyPen)
01217         RenderPen[CurrentPen] = wxPen(*wxTRANSPARENT_PEN);
01218     else
01219     {
01220         INT32 PenWidth = MPtoLP(RR_LINEWIDTH());
01221 
01222         if (RR_LINEWIDTH()==0 || LineQuality < Quality::FullLine)
01223             PenWidth = 0;
01224         else
01225         {
01226             MILLIPOINT LineWidth = RR_LINEWIDTH();
01227             if ((RenderFlags.VeryMono || RenderFlags.HitDetect) && LineWidth < GetScaledPixelWidth())
01228                 PenWidth = MPtoLP(GetScaledPixelWidth());
01229         }
01230 
01231         wxColour Colour(0,0,0);
01232         if (RenderFlags.VeryMono || LineQuality < Quality::ThinLine)
01233             Colour = *wxBLACK;
01234         else if (DrawingMode==DM_EORPEN)
01235             Colour = CalcEORColour(RR_STROKECOLOUR());
01236         else
01237         {
01238             INT32 R,G,B;
01239             RR_STROKECOLOUR().GetRGBValue(&R,&G,&B);
01240             Colour = wxColour(R, G, B);
01241         }
01242 
01243         RenderPen[CurrentPen] = wxPen(Colour, PenWidth, wxSOLID);
01244     }
01245 }

void OSRenderRegion::DeInitAttributes  )  [protected]
 

Deletes the GDI pen and brush objects.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/01/94

Definition at line 871 of file osrndrgn.cpp.

00872 {
00873     // Get rid of pen and/or brush if we used them.
00874 /*  if (OldPen != NULL)
00875     {
00876         //ENSURE(OldPen->m_hObject != NULL, "NULL object selected!");
00877         RenderDC->SetPen(*OldPen);
00878     }
00879 
00880     if (OldBrush != NULL)
00881     {
00882         //ENSURE(OldBrush->m_hObject != NULL, "NULL object selected!");
00883         RenderDC->SetBrush(*OldBrush);
00884     }
00885 */
00886 
00887     // Deselect the FixedSystem font from the DC
00888     if (OldFont != NULL)
00889     {
00890         RenderDC->SetFont(*OldFont);
00891         OldFont = NULL;
00892     }
00893 
00894     // Deselect the normal rendering font from the DC
00895     if (FontInfo.pRenderFont != NULL)
00896     {
00897         RenderDC->SetFont(*FontInfo.pOldFont);
00898         FontInfo.pOldFont = NULL;
00899         delete FontInfo.pRenderFont;
00900         FontInfo.pRenderFont = NULL;
00901     }
00902 }

void OSRenderRegion::DeInitClipping  )  [protected]
 

Destroys the GDI clipping region object, and unsets the clipping region for our DC.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/01/94

Definition at line 770 of file osrndrgn.cpp.

00771 {
00772     delete OSClipRegion;            // Delete the CRgn
00773     OSClipRegion = NULL;
00774 
00775     // unset the Clipping Region
00776     if (!RFlags.Metafile)
00777         RenderDC->DestroyClippingRegion();
00778 }

Coord OSRenderRegion::DocCoordToOS256 const DocCoord DocPoint  )  [protected]
 

Converts a DocCoord to a OS256 Coord. Used during rendering.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
5/8/93
Parameters:
Matrix elements and pixel scale. [INPUTS]
Returns:
A WinCoord

Definition at line 3819 of file osrndrgn.cpp.

03820 {
03821     OilCoord OilPoint;
03822 
03823     OilPoint.x = MatrixCalc( RenderMatrix.a, DocPoint.x, RenderMatrix.c, DocPoint.y) +
03824                  RenderMatrix.e;
03825 
03826     OilPoint.y = MatrixCalc( RenderMatrix.b, DocPoint.x, RenderMatrix.d, DocPoint.y) +
03827                  RenderMatrix.f;    // This was f1
03828 
03829     Coord OS256Point;
03830     
03831     FIXED16 PixelWidth = RenderView->GetPixelWidth();
03832     OS256Point.x = MPtoOS256(OilPoint.x, PixelWidth); 
03833 //  OS256Point.y = -(MPtoOS256(OilPoint.y, PixelWidth) + 256); 
03834 
03835 //  Above line commented out by Phil, 11/2/97
03836 //  The above "+256" is spurious (see comments for OilCoordToWin)
03837 //  Fixes a nasty printing bug.
03838     OS256Point.y = -(MPtoOS256(OilPoint.y, PixelWidth));
03839 
03840     return OS256Point;
03841 }

WinCoord OSRenderRegion::DocCoordToWin const DocCoord DocPoint  )  [protected]
 

Converts a DocCoord to a WinCoord. Used during rendering.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
5/8/93
Parameters:
Matrix elements and pixel scale. [INPUTS]
Returns:
A WinCoord

Definition at line 3794 of file osrndrgn.cpp.

03795 {
03796     OilCoord OilPoint;
03797 
03798     OilPoint.x = MatrixCalc( RenderMatrix.a, DocPoint.x, RenderMatrix.c, DocPoint.y) +
03799                  RenderMatrix.e;
03800 
03801     OilPoint.y = MatrixCalc( RenderMatrix.b, DocPoint.x, RenderMatrix.d, DocPoint.y) +
03802                  RenderMatrix.f;    // This was F1
03803 
03804     return OilPoint.ToWin(RenderView);
03805 }

WinRect OSRenderRegion::DocRectToWin const DocRect docrect,
INT32  leftshift,
INT32  topshift,
INT32  rightshift,
INT32  bottomshift,
BOOL  MightClip = FALSE
[inline, protected]
 

Definition at line 307 of file osrndrgn.h.

00309                         { return DocRectToWin(RenderView, RenderMatrix, docrect, 
00310                                               leftshift, topshift,
00311                                               rightshift, bottomshift, MightClip ); }

WinRect OSRenderRegion::DocRectToWin const Matrix RenderMatrix,
const DocRect DRect,
const double  dpi
[static]
 

To convert a rectangle in Doc coordinates to a rectangle in Win coordinates taking account of the destination dpi rather than assuming screen dpi as the above form does. Does not need the extra parameters that the above uses. INT32 dpi changed to double dpi (12/12/95) to improve the range of values allowed at the < 1000dpi settings that we will be using. Scope: Static.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/11/94
Parameters:
DocRect is a rectangle on document co-ords. [INPUTS] dpi is the resolution of the device we are rendering to
Returns:
Object containing the new rectangle coordinates.

Definition at line 3951 of file osrndrgn.cpp.

03953 {
03954     WinRect WinRect;
03955 
03956     OilCoord OilLo;
03957     OilCoord OilHi;
03958 
03959     OilLo.x = MatrixCalc( RenderMatrix.a, DRect.lo.x, RenderMatrix.c, DRect.lo.y ) + RenderMatrix.e;
03960     OilLo.y = MatrixCalc( RenderMatrix.b, DRect.lo.x, RenderMatrix.d, DRect.lo.y ) + RenderMatrix.f;    // This was f1
03961     OilHi.x = MatrixCalc( RenderMatrix.a, DRect.hi.x, RenderMatrix.c, DRect.hi.y ) + RenderMatrix.e;
03962     OilHi.y = MatrixCalc( RenderMatrix.b, DRect.hi.x, RenderMatrix.d, DRect.hi.y ) + RenderMatrix.f;    // this was f1
03963 
03964     // RenderMatrix can involve a rotation (but only multiples of 90 degrees), so we swap
03965     // the corners here if necessary
03966     MILLIPOINT Temp;
03967 
03968     if (OilLo.x > OilHi.x)
03969     {
03970         Temp = OilLo.x;
03971         OilLo.x = OilHi.x;
03972         OilHi.x = Temp;
03973     }
03974 
03975     if (OilLo.y > OilHi.y)
03976     {
03977         Temp = OilLo.y;
03978         OilLo.y = OilHi.y;
03979         OilHi.y = Temp;
03980     }
03981 
03982     WinCoord WinLo;
03983     WinCoord WinHi;
03984 
03985     WinLo = OilLo.ToWin(dpi);
03986     WinHi = OilHi.ToWin(dpi);
03987 
03988     WinRect.x      = WinLo.x;
03989     WinRect.y      = WinHi.y;
03990     WinRect.width  = WinHi.x-WinRect.x;
03991     WinRect.height = WinLo.y-WinRect.y;
03992 
03993     return WinRect;
03994 }

WinRect OSRenderRegion::DocRectToWin View pView,
const Matrix RenderMatrix,
const DocRect DRect,
INT32  leftshift,
INT32  topshift,
INT32  rightshift,
INT32  bottomshift,
BOOL  MightClip = FALSE
[static]
 

To convert a rectangle in Doc coordinates to a rectangle in Win coordinates. Scope: Static.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
8/8/93
Parameters:
pView - the view to convert in. [INPUTS] DocRect is a rectangle on document co-ords. The various shift parameters allow the resulting rectangle to be moved about a little, to allow for different rendering models etc. If MightClip is TRUE then the rectangle is clipped to fit within 16-bit GDI constraints, if running on 16-bit GDI.
Returns:
Object containing the new rectangle coordinates.

Definition at line 3864 of file osrndrgn.cpp.

03870 {
03871     WinRect WinRect;
03872 
03873     // Don't do ERROR2 as this is in redraw code.
03874     ERROR3IF(pView == NULL, "NULL view in OSRenderRegion::DocRectToWin()");
03875 
03876     OilCoord OilLo;
03877     OilCoord OilHi;
03878 
03879     OilLo.x = MatrixCalc( RenderMatrix.a, DRect.lo.x, RenderMatrix.c, DRect.lo.y ) + RenderMatrix.e;
03880     OilLo.y = MatrixCalc( RenderMatrix.b, DRect.lo.x, RenderMatrix.d, DRect.lo.y ) + RenderMatrix.f;    // This was f1
03881     OilHi.x = MatrixCalc( RenderMatrix.a, DRect.hi.x, RenderMatrix.c, DRect.hi.y ) + RenderMatrix.e;
03882     OilHi.y = MatrixCalc( RenderMatrix.b, DRect.hi.x, RenderMatrix.d, DRect.hi.y ) + RenderMatrix.f;    // this was f1
03883 
03884     // RenderMatrix can involve a rotation (but only multiples of 90 degrees), so we swap
03885     // the corners here if necessary
03886     MILLIPOINT Temp;
03887 
03888     if (OilLo.x > OilHi.x)
03889     {
03890         Temp = OilLo.x;
03891         OilLo.x = OilHi.x;
03892         OilHi.x = Temp;
03893     }
03894 
03895     if (OilLo.y > OilHi.y)
03896     {
03897         Temp = OilLo.y;
03898         OilLo.y = OilHi.y;
03899         OilHi.y = Temp;
03900     }
03901 
03902     WinCoord WinLo;
03903     WinCoord WinHi;
03904 
03905     WinLo = OilLo.ToWin(pView);
03906     WinHi = OilHi.ToWin(pView);
03907 
03908     WinRect.x      = WinLo.x + leftshift;
03909     WinRect.y      = WinHi.y + topshift;
03910     WinRect.width  = WinHi.x + rightshift -WinRect.x;
03911     WinRect.height = WinLo.y + bottomshift-WinRect.y;
03912 
03913 PORTNOTE("other", "Check this use of WIN32")
03914     if (
03915         MightClip
03916 //#if WIN32
03917 //       && IsWin32s()
03918 //#endif
03919        )
03920     {
03921         // assume MM_TEXT, clip to limits without being too close else we might effect
03922         // the actual rendering (e.g. if a line crosses the clip rect boundary)
03923         wxRect MaxRect(-100, -100, 32100, 32100 );
03924         WinRect.Intersect(MaxRect);
03925     }
03926 
03927     return WinRect;
03928 }

void OSRenderRegion::DrawBitmap const DocCoord Point,
UINT32  BitmapID,
UINT32  ToolID = NULL
[virtual]
 

Draws an un-scaled Bitmap. Use this for drawing Icons for dialogue boxes etc. The Bitmap can be any size, but will be plotted unscaled. Note that 'Point' specifies where the bottom left of the bitmap will be.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
7/2/95
Parameters:
Point - The Coord specifying the bottom left of the Bitmap. [INPUTS] BitmapID, the resource ID of the bitmap to plot. ToolID, the optional ToolID of the tool containing the Bitmap resource.

Implements RenderRegion.

Definition at line 3396 of file osrndrgn.cpp.

03397 {
03398     // If we are not drawing complex shapes and this shape is, then return
03399     if ((!RenderComplexShapes) && (TestForComplexShape(&Caps)))
03400         return;
03401 
03402     wxBitmap * pBitmap=CamArtProvider::Get()->FindBitmap((ResourceID)BitmapID);
03403 
03404     if (!pBitmap)
03405         return;
03406 
03407     // Extract the Width and Height
03408     // INT32 Width  = pBitmap->GetWidth();
03409     INT32 Height = pBitmap->GetHeight();
03410 
03411     // Convert the DocCoord into a windows coord
03412     wxPoint Origin = DocCoordToWin(Point);
03413     Origin.y = Origin.y - Height;   // Translate bottom left to top left
03414 
03415     RenderDC->DrawBitmap(*pBitmap, Origin.x, Origin.y, TRUE);
03416 
03417 }

void OSRenderRegion::DrawBitmap const DocCoord Point,
KernelBitmap pBitmap
[virtual]
 

Draws an un-scaled Bitmap. Use this for drawing Icons for dialogue boxes etc. The Bitmap can be any size, but will be plotted unscaled. Note that 'Point' specifies where the bottom left of the bitmap will be.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
7/2/95
Parameters:
Point - The Coord specifying the bottom left of the Bitmap. [INPUTS] pBitmap, the KernelBitmap to plot.

Implements RenderRegion.

Definition at line 3299 of file osrndrgn.cpp.

03300 {
03301     PORTNOTETRACE("other","OSRenderRegion::DrawBitmap - do nothing");
03302 #ifndef EXCLUDE_FROM_XARALX
03303     // If we are not drawing complex shapes and this shape is, then return
03304     if ((!RenderComplexShapes) && (TestForComplexShape(&Caps)))
03305         return;
03306 
03307     // Is there a Bitmap ??
03308     if (pBitmap == NULL || pBitmap->ActualBitmap == NULL)
03309     {
03310         ERROR3("NULL Bitmap passed to DrawBitmap");
03311         return;
03312     }
03313 
03314     // Get the 'Actual' windows Bitmap
03315     WinBitmap *WinBM = (WinBitmap*)pBitmap->ActualBitmap;
03316 
03317     // Is it valid ?
03318     if (
03319         (WinBM->BMInfo==NULL) ||
03320         (WinBM->BMBytes==NULL)
03321        )
03322         return;     // if not valid
03323 
03324     // Remember the Size of the Bitmap (in pixels)
03325     INT32 Width  = WinBM->GetWidth();
03326     INT32 Height = WinBM->GetHeight();
03327 
03328     // Convert the DocCoord into a windows coord
03329     POINT Origin = DocCoordToWin(Point);
03330     Origin.y = Origin.y - Height;   // Translate bottom left to top left
03331 
03332     CDC MemDC;
03333     // Create a memory DC based on this render region
03334     MemDC.CreateCompatibleDC(RenderDC);
03335 
03336     CBitmap Bitmap;
03337     // Create a CBitmap the same size as our one
03338     Bitmap.CreateCompatibleBitmap(RenderDC, Width, Height);
03339 
03340     // Select the CBitmap into the memory DC so that we have
03341     // a blank bitmap to copy into
03342     CBitmap* OldBmp = MemDC.SelectObject(&Bitmap);
03343 
03344     if (OldBmp == NULL) 
03345     {
03346         TRACE( _T("Couldn't select Bitmap into CDC in DrawBitmap\n"));
03347         return;
03348     }
03349 
03350     // Now copy the Bits from our Kernel Bitmap into the Memory DC
03351     SetDIBitsToDevice(          MemDC.m_hDC,
03352                                 0,0,
03353                                 Width,
03354                                 Height,
03355                                 0,0,
03356                                 0,
03357                                 Height,
03358                                 WinBM->BMBytes,
03359                                 WinBM->BMInfo,
03360                                 DIB_RGB_COLORS
03361                                 );
03362 
03363     // Copy the Bitmap onto this render region
03364     RenderDC->BitBlt(           Origin.x, Origin.y,
03365                                 Width,
03366                                 Height,
03367                                 &MemDC,
03368                                 0,0,
03369                                 SRCCOPY
03370                                 );
03371 
03372     // Unselect the bitmap and delete it
03373     MemDC.SelectObject(OldBmp);
03374     Bitmap.DeleteObject();
03375 #endif
03376 }

void OSRenderRegion::DrawBitmapBlob const DocCoord Point,
ResourceID  resID
[virtual]
 

Implements RenderRegion.

Definition at line 3591 of file osrndrgn.cpp.

03592 {
03593     wxBitmap *pBitmap = (CamArtProvider::Get())->FindBitmap( resID );
03594     if( NULL == pBitmap ) 
03595     {   
03596         TRACE( _T("wxBitmap failed to create in DrawBitmapBlob\n"));
03597         return;
03598     }
03599 
03600     // Extract the Width and Height
03601     INT32 Width  = pBitmap->GetWidth();
03602     INT32 Height = pBitmap->GetHeight();
03603 
03604     // Convert the DocCoord into a windows coord
03605     wxPoint Origin = FindBitmapOrigin(Point, Width, Height);
03606 
03607     // EOR the bitmap onto this render region
03608     wxMemoryDC  memDc;
03609     memDc.SelectObject( *pBitmap );
03610     RenderDC->Blit( Origin.x, Origin.y, Width, Height, &memDc, 0, 0, wxXOR );
03611 }

void OSRenderRegion::DrawBitmapBlob const DocCoord Point,
KernelBitmap BlobShape
[virtual]
 

Draws a Bitmap Blob. It is used for drawing more complex blob shapes, like 'rotation' arrows etc. The Bitmap can be any size, but must be Monochrome. Black pixels are transparent. White pixels will EOR. Note that 'Point' currently specifies where the centre of the bitmap will be.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
31/8/94
Parameters:
Point - The Coord specifying the centre of the Blob. [INPUTS] BlobShape - A Kernel Bitmap describing the Shape of the Blob. This is assumed to be a simple Monochrome Bitmap.
See also:
KernelBitmap

Implements RenderRegion.

Definition at line 3499 of file osrndrgn.cpp.

03500 {
03501     PORTNOTETRACE("other","OSRenderRegion::DrawBitmapBlob - do nothing");
03502 #ifndef EXCLUDE_FROM_XARALX
03503     ENSURE(BlobShape != NULL, "NULL Bitmap passed to DrawBitmapBlob");
03504 
03505     // Is there a Bitmap ??
03506     if (BlobShape->ActualBitmap == NULL)
03507         return;     // if no bitmap
03508 
03509     // Get the 'Actual' windows Bitmap
03510     WinBitmap *WinBM = (WinBitmap*)BlobShape->ActualBitmap;
03511 
03512     // Is it valid ?
03513     if (
03514         (WinBM->BMInfo==NULL) ||
03515         (WinBM->BMBytes==NULL)
03516        )
03517         return;     // if not valid
03518 
03519     // Remember the Size of the Bitmap (in pixels)
03520     INT32 Width  = WinBM->BMInfo->bmiHeader.biWidth;
03521     INT32 Height = WinBM->BMInfo->bmiHeader.biHeight;
03522 
03523     // Convert the DocCoord into a windows coord
03524     POINT Origin = FindBitmapOrigin(Point, Width, Height);
03525 
03526     CDC MemDC;
03527     // Create a memory DC based on this render region
03528     MemDC.CreateCompatibleDC(RenderDC);
03529 
03530     CBitmap Bitmap;
03531     // Create a CBitmap the same size as our one
03532     Bitmap.CreateCompatibleBitmap(RenderDC, Width, Height);
03533 
03534     // Select the CBitmap into the memory DC so that we have
03535     // a blank bitmap to copy into
03536     CBitmap* OldBmp = MemDC.SelectObject(&Bitmap);
03537 
03538     if (OldBmp == NULL) 
03539     {
03540         TRACE( _T("Couldn't select Bitmap into CDC in DrawBitmapBlob\n"));
03541         return;
03542     }
03543 
03544     // Now copy the Bits from our Kernel Bitmap into
03545     // the Memory DC
03546     SetDIBitsToDevice(          MemDC.m_hDC,
03547                                 0,0,
03548                                 Width,
03549                                 Height,
03550                                 0,0,
03551                                 0,
03552                                 Height,
03553                                 WinBM->BMBytes,
03554                                 WinBM->BMInfo,
03555                                 DIB_RGB_COLORS
03556                                 );
03557 
03558     // EOR the Bitmap onto this render region
03559     RenderDC->BitBlt(           Origin.x, Origin.y,
03560                                 Width,
03561                                 Height,
03562                                 &MemDC,
03563                                 0,0,
03564                                 SRCINVERT
03565                                 );
03566 
03567     // Unselect the bitmap and delete it
03568     MemDC.SelectObject(OldBmp);
03569     Bitmap.DeleteObject();
03570 #endif
03571 }

void OSRenderRegion::DrawBlob DocCoord  p,
BlobType  type
[virtual]
 

Draw a blob. This is the type of blob that appear round objects to show that they have been selected.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/8/93
Parameters:
p - The Coord of the point to draw a blob over [INPUTS] type - the Type of Blob to draw. It can be either BT_SELECTED for a Selected point or BT_UNSELECTED for an unselected point
See also:
BlobType

Implements RenderRegion.

Definition at line 3269 of file osrndrgn.cpp.

03270 {
03271     DocRect MyBlob;
03272 
03273     GetBlobRect( ScaleFactor, p, type, &MyBlob);
03274 
03275     // I do not need to set the colour of the rect as that
03276     // should be done before this function is called
03277     // Draw Drag Rect draws a rect without shifting the sides about, so it is what
03278     // we need.
03279     DrawDragRect( &MyBlob );
03280 }

void OSRenderRegion::DrawCross const DocCoord Point,
const UINT32  Size
[virtual]
 

Draws a cross in the render region. The cross consists of a vertical line 'Size' millipoints high, and a horizontal line 'Size' millipoints wide.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/02/94
Parameters:
Point - the centre point of the cross. [INPUTS] Size - the length of the lines used to draw the cross with.

Implements RenderRegion.

Definition at line 2137 of file osrndrgn.cpp.

02138 {
02139     GetValidPen();
02140     
02141     const MILLIPOINT Length = Size * ScaledPixelWidth;
02142 
02143     // Work out cross coordinates in documenty coords
02144     DocCoord Coords[3];
02145     Coords[0] = Point;
02146 
02147     Coords[1].x = Point.x - Length;
02148     Coords[1].y = Point.y - Length;
02149 
02150     Coords[2].x = Point.x + Length + ScaledPixelWidth;  
02151     Coords[2].y = Point.y + Length + ScaledPixelWidth;
02152 
02153     // Convert to window coordinates
02154     wxPoint Points[3];
02155     Points[0] = DocCoordToWin(Coords[0]);
02156     Points[1] = DocCoordToWin(Coords[1]);
02157     Points[2] = DocCoordToWin(Coords[2]);
02158 
02159     // Draw the horizontal line
02160     RenderDC->DrawLine(Points[1].x,Points[0].y,Points[2].x,Points[0].y);
02161     // Draw the vertical line
02162     RenderDC->DrawLine(Points[0].x,Points[1].y,Points[0].x,Points[2].y);
02163 }

void OSRenderRegion::DrawDashLine const DocCoord StartPoint,
const DocCoord EndPoint
[virtual]
 

Draws a dashed line between the two points. Uses the technology from DrawDragBounds().

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/10/95
Parameters:
StartPoint - start of the line [INPUTS] EndPoint - end of the line
See also:
OSRenderRegion::DrawDragBounds()

Reimplemented from RenderRegion.

Definition at line 2042 of file osrndrgn.cpp.

02043 {
02044     INT32 OurOldBkMode = RenderDC->GetBackgroundMode() ;
02045     INT32 OurOldDrawingMode = RenderDC->GetLogicalFunction();
02046     wxPen OurOldPen = RenderDC->GetPen() ;
02047 
02048     wxPen DotPen(CalcEORColour(RR_STROKECOLOUR()),1,wxDOT);
02049     RenderDC->SetPen(DotPen);
02050     RenderDC->SetBackgroundMode(wxTRANSPARENT);
02051     RenderDC->SetLogicalFunction(wxXOR);
02052 
02053     // Now, render the line
02054     WinCoord StartPt = DocCoordToWin(StartPoint);
02055     WinCoord EndPt   = DocCoordToWin(EndPoint  );
02056     RenderDC->DrawLine(StartPt,EndPt);
02057 
02058     // And restore the previous GDI settings
02059     RenderDC->SetLogicalFunction(OurOldDrawingMode);
02060     RenderDC->SetBackgroundMode(OurOldBkMode);
02061     RenderDC->SetPen(OurOldPen);
02062 }

void OSRenderRegion::DrawDragBounds DocRect RectToRender  )  [virtual]
 

Used to draw a "rectangle" to screen (for dragging). However, the corners of the rectangle are passed through the current rendering matrix, so the rect may well be rotated or skewed by the time it reaches the screen.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/5/95
Parameters:
RectToRender - The bounding rectangle we wish to render. [INPUTS]
The rectangle is never filled, and will be stroked in XOR mode, using the current line colour. (i.e. only line colour needs to be set before calling this method, and it'll *always* be XOR'd regardless of other settings)

This is used for XOR dragging of selected objects as they are skewed, rotated, translated, etc

Notes: DO NOT confuse this method with DrawDragRect (which will draw a rectangle without skew or rotation)

See also:
OSRenderRegion::DrawDragRect; RenderRegion::DrawDragBounds; Range::RenderXOROutlinesOn

Reimplemented from RenderRegion.

Definition at line 1998 of file osrndrgn.cpp.

01999 {
02000     INT32 OurOldBkMode = RenderDC->GetBackgroundMode() ;
02001     INT32 OurOldDrawingMode = RenderDC->GetLogicalFunction();
02002     wxPen OurOldPen = RenderDC->GetPen() ;
02003 
02004     wxPen DotPen(CalcEORColour(RR_STROKECOLOUR()),1,wxDOT);
02005     RenderDC->SetPen(DotPen);
02006     RenderDC->SetBackgroundMode(wxTRANSPARENT);
02007     RenderDC->SetLogicalFunction(wxXOR);
02008 
02009     // Now, render the 4 lines, converting the corners of the rectangle with the
02010     // current rendering matrix
02011     WinCoord Points[5];
02012     Points[0] = 
02013     Points[4] = DocCoordToWin(RectToRender->lo);
02014     Points[1] = DocCoordToWin(DocCoord(RectToRender->lo.x, RectToRender->hi.y));
02015     Points[2] = DocCoordToWin(RectToRender->hi);
02016     Points[3] = DocCoordToWin(DocCoord(RectToRender->hi.x, RectToRender->lo.y));
02017 
02018     // And close the shape
02019     RenderDC->DrawLines(5,Points);
02020 
02021     // And restore the previous GDI settings
02022     RenderDC->SetLogicalFunction(OurOldDrawingMode);
02023     RenderDC->SetBackgroundMode(OurOldBkMode);
02024     RenderDC->SetPen(OurOldPen);
02025 }

void OSRenderRegion::DrawDragRect DocRect RectToDraw  )  [virtual]
 

Renders a Rectangle to the GDI . Used to claim "without shifting it about" bit it does adjust it now for the differences in rendering models.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/5/93
Parameters:
RectToDraw is a pointer to a DocRect object to render [INPUTS]
See also:
OSRenderRegion::DrawPath()

Implements RenderRegion.

Definition at line 1944 of file osrndrgn.cpp.

01945 {
01946     GetValidPen();
01947     GetValidBrush();
01948 
01949 // NOTE
01950 // Sometimes the PasteBoard and Page rects are dissapearing at high zoom.
01951 // This seems to be because of the GDI 16 bit limit being exceeded.
01952 // We need to check for the overflow, or clip the rects ourselves.
01953 
01954     WinRect Rect = DocRectToWin(*RectToDraw, 0,0,0,0);
01955 
01956     // for some reason, all flavours of GDI can screw up when asked to render zero-width/
01957     // height rectangles when in XOR mode, as it often leaves little pixels behind. Our fix
01958     // for this is to simply not render anything if zero width or height in EOR mode
01959 
01960     if ( DrawingMode != DM_EORPEN ||                    // if not EOR then always
01961         (
01962             Rect.width !=1 &&           // else must have width
01963             Rect.height!=1              // and height
01964         ) )
01965         RenderDC->DrawRectangle(Rect);      // Draw the Rectangle
01966 }

void OSRenderRegion::DrawFixedSystemText StringBase TheText,
DocRect BoundsRect,
UINT32  uFormat = DEFAULT_TEXT_FORMATTING
[virtual]
 

To draw simple text, using the default host-operating-system font. The size and style of this font are decided by the host OS (or oil code) and cannot be set in any way. To determine how much space is needed to display a string with this method, see the SeeAlso.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/1/95
Parameters:
TheText - The string to render [INPUTS] BoundsRect - Determines where the text is to be plotted. The text will also be clipped within this bounding rectangle if it exceeds the available space.
Notes: This method is intended solely for the use of kernel-rendered dialogues, such as SuperGalleries, which need to display simple text information. It should not be confused with document rendering of arbitrary text paths etc.

Currently, the text is drawn in a default manner (left justified and centered vertically; one line of text only (no word-wrap onto subsequent lines), etc) Do not use special characters such as tab/newline -their effect is undefined

See also:
OSRenderRegion::GetFixedSystemTextSize; OSRenderRegion::SetFixedSystemTextColours

Reimplemented from RenderRegion.

Definition at line 2196 of file osrndrgn.cpp.

02197 {
02198     wxString Text = (wxString)(TCHAR *)(*TheText);
02199     wxRect Rect(0,0,0,0);
02200 
02201     wxFont SaveFont=RenderDC->GetFont();
02202 
02203     wxFont FixedFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
02204     FixedFont.SetPointSize(8);
02205     RenderDC->SetFont(FixedFont);
02206 
02207     wxDC * pDC = RenderDC;
02208     wxSize DPI = GetFixedDCPPI(*pDC);
02209     INT32 XDPI = DPI.GetWidth();
02210     INT32 YDPI = DPI.GetHeight();
02211     INT32 LineHeight = RenderDC->GetCharHeight();
02212 
02213     if (uFormat & FORMAT_CALCRECT) // just calculate the rect needed to draw the text and return
02214     {
02215         // This won't actually draw the text, instead it returns a rectangle in 'Rect'  
02216         // LineHeight = RenderDC->DrawText((TCHAR *) (*TheText), -1, &Rect, uFormat);
02217         wxCoord w, h;
02218         RenderDC->GetTextExtent(Text, &w, &h);
02219         Rect = wxRect(0, 0, w, h);
02220 
02221 
02222         if(XDPI == 0 || YDPI == 0 || LineHeight == 0)
02223         {
02224             ERROR3("Can not calculate text size");
02225             BoundsRect = DocRect(0, 0, 0, 0);
02226             RenderDC->SetFont(SaveFont);
02227             return;
02228         }
02229         // For some reason, Rect.bottom and Rect.top seem to be incorrect, so we have
02230         // to use the returned LineHeight value
02231         BoundsRect = DocRect(0, 0,
02232                               (INT32)(((double)Rect.width * IN_MP_VAL) / XDPI),
02233                               (INT32)(((double)LineHeight * IN_MP_VAL) / YDPI) );
02234         RenderDC->SetFont(SaveFont);
02235         return;
02236     }
02237     
02238     // We plot using the TOP of the rectangle supplied (that's the highest DocCoord
02239     // but we need to center it (i.e. reduce the value
02240     DocRect brect=BoundsRect;
02241 
02242     brect.hi.y -= ((brect.hi.y-brect.lo.y)-(INT32)(((double)LineHeight * IN_MP_VAL) / YDPI))/2;
02243 
02244     Rect = DocRectToWin(brect, 0,0,0,0, TRUE);
02245     // Rect = DocRectToWin(BoundsRect, 0,-1,1,0, TRUE);
02246 
02247     // Small 'fix' - If we DrawRect the 'BoundsRect' then windows draws the text 1 pixel
02248     // further to the right than the rectangle. This just ensures that the text is always
02249     // clipped inside the rectangle rather than outside (at worst, a pixel too far inside)
02250     if (Rect.width>0)       // Still a valid rectangle?
02251     {
02252 //      Rect.x--;
02253 
02254         // wxWidgets seems to corrupt the current brush here, which we need to preserve
02255         wxBrush SaveBrush=RenderDC->GetBrush();
02256         INT32 SaveBackgroundMode=RenderDC->GetBackgroundMode();
02257 
02258         // Draw the text
02259         RenderDC->SetBackgroundMode(wxTRANSPARENT);
02260         RenderDC->DrawText(Text, Rect.GetLeft(), Rect.GetTop());
02261 
02262         // Restore the brush. First we have to ensure SetBrush really works. This is
02263         // because the GTK brush is corrupted whilst the wxWidgets one is still right.
02264         // So we have to select a different brush or wxWidgets will skip the call
02265         // that would otherwise fix the GTK brush - wxWidgets bug #148096
02266         RenderDC->SetBackgroundMode(SaveBackgroundMode);
02267         RenderDC->SetBrush(*wxTRANSPARENT_BRUSH);
02268         RenderDC->SetBrush(wxNullBrush);
02269         RenderDC->SetBrush(SaveBrush);
02270 
02271 //      LineHeight = RenderDC->DrawText((TCHAR *) (*TheText), -1, &Rect, uFormat);
02272 
02273 //      ENSURE(LineHeight > 0, "OSRenderRegion::DrawFixedSystemText failed");
02274     }
02275 
02276     RenderDC->SetFont(SaveFont);
02277 }

void OSRenderRegion::DrawLine const DocCoord StartPoint,
const DocCoord EndPoint
[virtual]
 

Renders a Line to the GDI.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/6/93
Parameters:
StartPoint is the Inclusive start coordinate. [INPUTS] EndPoint is thw Exclusive end coordinate.
See also:
OSRenderRegion::DrawPath(); OSRenderRegion::DrawRect()

Implements RenderRegion.

Definition at line 2077 of file osrndrgn.cpp.

02078 {
02079     // If we are not drawing complex shapes and this shape is, then return
02080     if ((!RenderComplexShapes) && (TestForComplexShape(&Caps)))
02081         return;
02082 
02083     GetValidPen();
02084     GetValidBrush();
02085     
02086     const UINT32 LINEVERTICES = 2;
02087     wxPoint LinePoints[LINEVERTICES];
02088     LinePoints[0] = DocCoordToWin(StartPoint);  //LinePoints[0].y--;
02089     LinePoints[1] = DocCoordToWin(EndPoint);    //LinePoints[1].y--;
02090 
02091     RenderDC->DrawLine(LinePoints[0],LinePoints[1]);    // Draw the Line
02092 #if 0
02093     if (!StartArrow.IsNull)
02094         DrawLineArrow(StartArrow, StartPoint, EndPoint);
02095 
02096     if (!EndArrow.IsNull)
02097         DrawLineArrow(EndArrow, EndPoint, StartPoint);
02098 #endif
02099 }

SlowJobResult OSRenderRegion::DrawMaskedBitmap const DocRect Rect,
KernelBitmap pBitmap,
MaskedRenderRegion pMask,
ProgressDisplay Progress
[virtual]
 

Plots the bitmap using the mask supplied.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/4/95
Parameters:
Point - the position to plot the bitmap [INPUTS] pBitmap - The bitmap that needs plotting pMask - The mask render region to use to indicate which bits of pBitmap needs to be plotted

Reimplemented from RenderRegion.

Definition at line 6513 of file osrndrgn.cpp.

06515 {
06516     PORTNOTETRACE("other","OSRenderRegion::DrawMaskedBitmap - do nothing");
06517 #if !defined(STANDALONE) && !defined(EXCLUDE_FROM_XARALX)
06518     if (RenderView->GetColourPlate() != NULL &&
06519         !RenderView->GetColourPlate()->IsDisabled())
06520     {
06521         // We're colour separating. Indirect this call to the separation variant of this code
06522         // (see below)
06523         return(DrawSeparatedMaskedBitmap(Rect, pBitmap, pMask, Progress));
06524     }
06525 
06526 
06527     // Make sure the world is in one piece
06528     if ((pBitmap==NULL) || (pMask==NULL))
06529         return SLOWJOB_FAILURE;
06530 
06531     // If mask coverage is 0% we do not need to do anything. The TRUE param indicates
06532     // that we don't care about exact coverage, which makes it return as soon as it realises
06533     // that there are pixel(s) that we'll have to plot
06534     if (pMask->FindCoverage(TRUE) == 0)
06535         return SLOWJOB_SUCCESS;
06536 
06537     // Guess we will need to be doing something...
06538     if (pBitmap->ActualBitmap == NULL)
06539         return SLOWJOB_FAILURE;
06540 
06541     // Get the 'Actual' windows Bitmap
06542     WinBitmap *WinBM = (WinBitmap*)pBitmap->ActualBitmap;
06543 
06544     // Is it valid ?
06545     if ((WinBM->BMInfo==NULL) || (WinBM->BMBytes==NULL))
06546         return SLOWJOB_FAILURE;
06547 
06548     // Remember the Size of the Bitmap (in pixels)
06549     INT32 Width  = WinBM->GetWidth();
06550     INT32 Height = WinBM->GetHeight();
06551 
06552     if ((Width == 0) || (Height == 0))
06553         // Error - bitmap has no dimension
06554         return SLOWJOB_FAILURE;
06555 
06556     // Convert the bitmap from a 32bpp bitmap to a 24bpp bitmap
06557     INT32 BitmapDepth = WinBM->GetBPP();
06558     if (BitmapDepth == 32)
06559     {
06560         // Can't plot 32bpp bitmaps to GDI as 16-bit GDI doesn't understand them,
06561         // so we convert to 24bpp bitmap in-situ and render that...
06562 
06563         // How many bytes to a source scanline?
06564         const INT32 ScanlineBytes = WinBM->GetScanlineSize();
06565 
06566         // How many bytes to a destination scanline
06567         const INT32 DestlineBytes = DIBUtil::ScanlineSize(Width, 24);
06568 
06569         // Now convert the bitmap in-situ
06570         LPBYTE OriginalBuffer  = WinBM->BMBytes;
06571         LPBYTE ConvertedBuffer = WinBM->BMBytes;
06572 
06573         for (INT32 i=0; i<Height; i++)
06574         {
06575             DIBUtil::Convert32to24(Width, OriginalBuffer, ConvertedBuffer);
06576             OriginalBuffer += ScanlineBytes;
06577             ConvertedBuffer += DestlineBytes;
06578         }
06579 
06580         // Update bitmap info to show it is now a 24bpp bitmap...
06581         WinBM->BMInfo->bmiHeader.biSizeImage = DestlineBytes * Height;
06582         WinBM->BMInfo->bmiHeader.biBitCount  = 24;
06583         BitmapDepth = 24;       
06584     }
06585 
06586     // make sure we have a 24bpp bitmap
06587     ERROR3IF(BitmapDepth!=24, "Non 24bpp bitmap found in DrawMaskedBitmap");
06588 
06589     // Work out the coords to blit to, taking into acount the differnt dpis of the
06590     // source and destination bitmaps.
06591     INT32 SrcDpi = pMask->FindMaskDpi();
06592     INT32 DestDpi = SrcDpi;
06593     if (RenderDC!=NULL)
06594         DestDpi = RenderDC->GetDeviceCaps(LOGPIXELSY);
06595 
06596     // Work out the ratio between to two
06597     double Ratio = DestDpi;
06598     Ratio = Ratio/SrcDpi;
06599 
06600     // Convert the DocCoord into a windows coord
06601     DocRect ClipRect = pMask->GetClipRect();
06602     WinRect WinClipRect = DocRectToWin(RenderMatrix, ClipRect, DestDpi);
06603     POINT Origin;
06604     Origin.x = WinClipRect.left;
06605     Origin.y = WinClipRect.bottom;
06606 
06607     // Inform progress object how high this band is
06608     if (PrintMonitor::PrintMaskType==PrintMonitor::MASK_MASKED)
06609     {
06610         if (Progress!=NULL)
06611             Progress->StartBitmapPhaseBand(Height);
06612     }
06613 
06614     // We need to create a tempory bitmap that we use to render each scan line
06615     LPBITMAPINFO    TempBitmapInfo = NULL;
06616     LPBYTE          TempBitmapBytes = NULL;
06617 
06618     // Get some memory for a tempory bmp 1 pixel high
06619     TempBitmapInfo = AllocDIB(Width, 1, BitmapDepth, &TempBitmapBytes);
06620     if (TempBitmapInfo==NULL)
06621         return SLOWJOB_FAILURE;
06622 
06623     // How many bytes to a destination scanline
06624     INT32 ScanLineBytes = DIBUtil::ScanlineSize(Width, BitmapDepth);
06625     INT32  BytesPerPixel = 3;
06626 
06627     // Now convert the bitmap in-situ
06628     LPBYTE SrcBuffer  = WinBM->BMBytes;
06629     LPBYTE DestBuffer = TempBitmapBytes;
06630     
06631     // Set the blit mode
06632     INT32 OldMode = SetStretchBltMode(RenderDC->GetSafeHdc(), HALFTONE);//COLORONCOLOR);
06633 
06634     // Must call SetBrushOrgEx() after setting the stretchblt mode 
06635     // to HALFTONE (see Win32 SDK docs).
06636     POINT OldOrg;
06637     SetBrushOrgEx(RenderDC->m_hDC, 0, 0, &OldOrg);
06638 
06639     // Now copy the Bits from our Kernel Bitmap into the Memory DC - either we can
06640     // do this as a masked blit (a scan line at a time), or in one go.
06641     // We do the masked blit under NT, or if the preference has been over-ridden by the user.
06642     if (PrintMonitor::PrintMaskType!=PrintMonitor::MASK_SIMPLE)
06643     {
06644         MaskRegion MaskInfo;
06645         pMask->GetFirstMaskRegion(&MaskInfo);
06646         while (MaskInfo.Length!=0)
06647         {
06648             // Calculate the source buffer address from the x and y position
06649             SrcBuffer = WinBM->BMBytes;
06650             SrcBuffer += ScanLineBytes * MaskInfo.y;
06651             SrcBuffer += MaskInfo.x*BytesPerPixel;
06652             INT32 RegionWidth = MaskInfo.Length;
06653 
06654             // Update bitmap info to show the new scan line size
06655             TempBitmapInfo->bmiHeader.biWidth = RegionWidth;
06656             TempBitmapInfo->bmiHeader.biSizeImage = (RegionWidth*BytesPerPixel);
06657 
06658             memcpy(DestBuffer, SrcBuffer, RegionWidth*BytesPerPixel);
06659 
06660             // Work out the coords of the destination rectangle
06661             INT32 DestX = Origin.x + INT32(ceil(MaskInfo.x*Ratio));
06662             INT32 DestY = Origin.y - INT32(ceil((MaskInfo.y+1)*Ratio));
06663             INT32 DestWidth = INT32(ceil(RegionWidth*Ratio));
06664             INT32 DestHeight = INT32(ceil(1*Ratio));
06665         
06666             // Blit the data to the screen
06667             StretchDIBits(  RenderDC->GetSafeHdc(),
06668                             DestX, DestY, DestWidth, DestHeight,
06669                             0, 0,
06670                             RegionWidth, 1,
06671                             TempBitmapBytes, TempBitmapInfo,
06672                             DIB_RGB_COLORS, SRCCOPY);
06673 
06674             // Update the progress display if necessary.
06675             if (PrintMonitor::PrintMaskType==PrintMonitor::MASK_MASKED)
06676             {
06677                 if ((Progress!=NULL) && (!Progress->BitmapPhaseBandRenderedTo(MaskInfo.y)))
06678                 {
06679                     // Put the blit mode back as it was
06680                     SetStretchBltMode(RenderDC->GetSafeHdc(), OldMode);
06681                     SetBrushOrgEx(RenderDC->m_hDC, OldOrg.x, OldOrg.y, NULL);
06682 
06683                     // Free up the tempory DIB I made
06684                     FreeDIB(TempBitmapInfo, TempBitmapBytes);
06685 
06686                     return SLOWJOB_USERABORT;
06687                 }
06688             }
06689 
06690             // Find the next bit of scan line to plot
06691             pMask->GetNextMaskRegion(&MaskInfo);
06692         }
06693     }
06694     else
06695     {
06696         // Blit in one go...
06697 
06698         // Work out the coords of the destination rectangle
06699         INT32 DestX = Origin.x;
06700         INT32 DestY = Origin.y - INT32(ceil(Height * Ratio));
06701         INT32 DestWidth = INT32(ceil(Width * Ratio));
06702         INT32 DestHeight = INT32(ceil(Height * Ratio));
06703 
06704         // Blit the data to the screen
06705         StretchDIBits(  RenderDC->GetSafeHdc(),
06706                         DestX, DestY, DestWidth, DestHeight,
06707                         0, 0,
06708                         Width, Height,
06709                         WinBM->BMBytes, WinBM->BMInfo,
06710                         DIB_RGB_COLORS, SRCCOPY);
06711 
06712         // Update the progress display if necessary.
06713         if ((Progress!=NULL) && (!Progress->BitmapPhaseBandRenderedTo(Height)))
06714         {
06715             // Put the blit mode back as it was
06716             SetStretchBltMode(RenderDC->GetSafeHdc(), OldMode);
06717             SetBrushOrgEx(RenderDC->m_hDC, OldOrg.x, OldOrg.y, NULL);
06718 
06719             // Free up the tempory DIB I made
06720             FreeDIB(TempBitmapInfo, TempBitmapBytes);
06721 
06722             return SLOWJOB_USERABORT;
06723         }
06724     }
06725 
06726     // Put the blit mode back as it was
06727     SetStretchBltMode(RenderDC->GetSafeHdc(), OldMode);
06728     SetBrushOrgEx(RenderDC->m_hDC, OldOrg.x, OldOrg.y, NULL);
06729 
06730     // Update bitmap info to what it was before we started
06731     TempBitmapInfo->bmiHeader.biSizeImage = (Width*3);
06732     TempBitmapInfo->bmiHeader.biWidth = Width;
06733 
06734     // Free up the tempory DIB I made
06735     FreeDIB(TempBitmapInfo, TempBitmapBytes);
06736 
06737 #endif
06738 
06739     // All ok
06740     return SLOWJOB_SUCCESS;
06741 }

void OSRenderRegion::DrawPathToOutputDevice Path PathToDraw,
PathShape  shapePath = PATHSHAPE_PATH
[virtual]
 

Renders a path object to the GDI.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/5/93
Parameters:
PathToDraw is a pointer to a Path object to render [INPUTS]
See also:
OSRenderRegion::DrawRect()

Implements RenderRegion.

Definition at line 1808 of file osrndrgn.cpp.

01809 {
01810     // If we are not drawing complex shapes and this shape is, then return
01811     if ((!RenderComplexShapes) && (TestForComplexShape(&Caps)))
01812         return;
01813 
01814     // We want to draw it, so get pens and brushs
01815     GetValidPen();
01816     GetValidBrush();
01817 
01818     // and draw the path
01819     RenderPath(PathToDraw);                 // Render the Path
01820 
01821     // draw the arrow heads on to it.
01822     DrawPathArrowHeads(NORMALPATH(PathToDraw));
01823 }

void OSRenderRegion::DrawPixel const DocCoord Point  )  [virtual]
 

Plot a single pixel in a render region.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/02/94
Parameters:
Point - the coordinate to plot the point at. [INPUTS]

Implements RenderRegion.

Definition at line 2112 of file osrndrgn.cpp.

02113 {
02114     wxPoint LinePoint = DocCoordToWin(Point);
02115 //  RenderDC->SetPixel(LinePoint,
02116 //              ConvertColourToScreenWord(CurrentColContext, &RR_STROKECOLOUR()));
02117     INT32 R,G,B;
02118     RR_STROKECOLOUR().GetRGBValue(&R,&G,&B);
02119     RenderDC->SetPen(wxColour(R,G,B));
02120     RenderDC->DrawPoint(LinePoint);
02121 }

void OSRenderRegion::DrawRect DocRect RectToRend  )  [virtual]
 

Renders a rectangle using Ploygon instead of Rectangle. Used for BodgeRectangles devices whi cannot render rectangles correctly. Should really only be used when no fill brush has been set as solid ones with XORing on don't render correctly.Renders a Rectangle to the GDI.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/5/93
Parameters:
RectToDraw is a pointer to a DocRect object to render [INPUTS]
See also:
OSRenderRegion::DrawPath()

Implements RenderRegion.

Definition at line 1871 of file osrndrgn.cpp.

01872 {
01873     // If we are not drawing complex shapes and this shape is, then return
01874     if ((!RenderComplexShapes) && (TestForComplexShape(&Caps)))
01875         return;
01876 
01877     GetValidPen();
01878     GetValidBrush();
01879 
01880 //  TRACEUSER("Gavin",_T("RectToRend      : %08x %08x %08x %08x"),
01881 //        RectToRend->lo.x,RectToRend->lo.y,RectToRend->hi.x,RectToRend->hi.y);
01882 //  TRACEUSER("Gavin",_T("CurrentClipRect : %08x %08x %08x %08x"),
01883 //        CurrentClipRect.lo.x,CurrentClipRect.lo.y,CurrentClipRect.hi.x,CurrentClipRect.hi.y);
01884 
01885     // First see if the rect intersects with the clip rect
01886     if (!RectToRend->IsIntersectedWith(CurrentClipRect))
01887         return;
01888 
01889     // OK, it intersects, but we should try to clip it with the inner rect
01890     DocRect DrawRect = RectToRend->Intersection(InnerRect);
01891 
01892 //  TRACEUSER("Gavin",_T("DrawRect        : %08x %08x %08x %08x *"),
01893 //        DrawRect.lo.x,DrawRect.lo.y,DrawRect.hi.x,DrawRect.hi.y);
01894 
01895 // NOTE
01896 // Sometimes the PasteBoard and Page rects are dissapearing at high zoom.
01897 // This seems to be because of the GDI 16 bit limit being exceeded.
01898 // We need to check for the overflow, or clip the rects ourselves. Hence the
01899 // TRUE args on the end of DocRectToWin
01900     WinRect Rect;
01901 
01902     // Ok, all the Fuzzy clipping has been taken care of, now convert and draw the rectangle we have left
01903 /*  if (BodgeRectangles)
01904     {
01905         // if using Ploygon to draw rectangles, no bodging of co-ords is required at all
01906         // (as you would expect)
01907 */      Rect = DocRectToWin(DrawRect, 0,0,0,0, TRUE);
01908 /*  }
01909     else if (RR_STROKECOLOUR().IsTransparent())
01910     {
01911         Rect = DocRectToWin(DrawRect, 0,0,1,1, TRUE);
01912     }
01913     else
01914     {
01915         Rect = DocRectToWin(DrawRect, 0,-1,1,0, TRUE);
01916     }
01917 
01918     BOOL RectOK;
01919 
01920     // Draw the Rectangle
01921     if (BodgeRectangles)
01922     {
01923         RectOK = SlowRectangle(RenderDC, Rect);
01924         ENSURE(RectOK,"CDC::Rectangle failed in DrawRect");
01925     }
01926     else
01927 */      RenderDC->DrawRectangle(Rect);
01928 
01929 }

SlowJobResult OSRenderRegion::DrawSeparatedMaskedBitmap const DocRect Rect,
KernelBitmap pBitmap,
MaskedRenderRegion pMask,
ProgressDisplay Progress
[protected, virtual]
 

Plots the bitmap using the mask supplied. The bitmap is colour separated according to the current ColourPlate settings, and output (a scanline at a time) in an 8bpp greyscale format.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/7/96
Parameters:
Point - the position to plot the bitmap [INPUTS] pBitmap - The bitmap that needs plotting pMask - The mask render region to use to indicate which bits of pBitmap needs to be plotted Progress - The progress object to be kept informed of progress
Notes: This function is autoamtically called by DrawMaskedBitmap() if it is called while we are rendering a colour separation plate. It is essentially a copy of DrawMaskedBitmap which has been rejigged to colour separate the bitmap.

Definition at line 6769 of file osrndrgn.cpp.

06771 {
06772     PORTNOTETRACE("other","OSRenderRegion::DrawSeparatedMaskedBitmap - do nothing");
06773 #ifndef EXCLUDE_FROM_XARALX
06774 #ifndef STANDALONE
06775     SlowJobResult Result = SLOWJOB_SUCCESS;
06776     
06777     // Make sure the world is in one piece
06778     if ((pBitmap==NULL) || (pMask==NULL))
06779         return SLOWJOB_FAILURE;
06780 
06781     // If mask coverage is 0% we do not need to do anything. The TRUE param indicates
06782     // that we don't care about exact coverage, which makes it return as soon as it realises
06783     // that there are pixel(s) that we'll have to plot
06784     if (pMask->FindCoverage(TRUE) == 0)
06785         return SLOWJOB_SUCCESS;
06786 
06787     // Get the 'Actual' windows Bitmap
06788     WinBitmap *WinBM = (WinBitmap*)pBitmap->ActualBitmap;
06789 
06790     // Is it valid ?
06791     if (WinBM == NULL || WinBM->BMInfo == NULL || WinBM->BMBytes == NULL)
06792         return SLOWJOB_FAILURE;
06793 
06794     // We're colour separating, so make sure we've got some sep tables to work with.
06795     // We cache them once we've used them. I would do this sort of set-up in StartRender
06796     // but of course all the derived classes just override that behaviour and we're stuffed
06797     if (SepTables == NULL && RenderView->GetColourPlate() != NULL)
06798     {
06799         ColourContextCMYK *cc = (ColourContextCMYK *)RenderView->GetColourContext(COLOURMODEL_CMYK);
06800         if (cc != NULL)
06801         {
06802             SepTables = (BYTE *) CCMalloc(5 * 256 * sizeof(BYTE));
06803             if (SepTables != NULL)
06804             {
06805                 if (!cc->GetProfileTables(SepTables))
06806                 {
06807                     CCFree(SepTables);
06808                     SepTables = NULL;
06809                 }
06810             }
06811         }
06812 
06813         ERROR3IF(SepTables == NULL, "Can't generate separation tables in OSRenderRegion");
06814         if (SepTables == NULL)
06815             return(SLOWJOB_FAILURE);
06816     }
06817 
06818 
06819     // Remember the Size of the Bitmap (in pixels)
06820     INT32 Width  = WinBM->GetWidth();
06821     INT32 Height = WinBM->GetHeight();
06822     INT32 BitmapDepth = WinBM->GetBPP();
06823 
06824     if (Width == 0 || Height == 0)
06825         return SLOWJOB_FAILURE;
06826 
06827     // Work out the coords to blit to, taking into acount the differnt dpis of the
06828     // source and destination bitmaps.
06829     INT32 SrcDpi = pMask->FindMaskDpi();
06830     INT32 DestDpi = SrcDpi;
06831     if (RenderDC!=NULL)
06832         DestDpi = RenderDC->GetDeviceCaps(LOGPIXELSY);
06833 
06834     // Work out the ratio between to two
06835     double Ratio = DestDpi;
06836     Ratio = Ratio/SrcDpi;
06837 
06838     // Convert the DocCoord into a windows coord
06839     DocRect ClipRect = pMask->GetClipRect();
06840     WinRect WinClipRect = DocRectToWin(RenderMatrix, ClipRect, DestDpi);
06841     POINT Origin;
06842     Origin.x = WinClipRect.left;
06843     Origin.y = WinClipRect.bottom;
06844 
06845     // Inform progress object how high this band is
06846     if (PrintMonitor::PrintMaskType==PrintMonitor::MASK_MASKED)
06847     {
06848         if (Progress!=NULL)
06849             Progress->StartBitmapPhaseBand(Height);
06850     }
06851 
06852     // Allocate a 32bpp scanline buffer
06853     Pixel32bpp *pScanline = (Pixel32bpp *) CCMalloc(Width * sizeof(Pixel32bpp));
06854     if (pScanline == NULL)
06855         return(SLOWJOB_FAILURE);
06856 
06857     // Create a bitmap header structure to use with our temporary scanline. As all output data
06858     // will be 8bpp, we set the header up as an 8bpp bitmap.
06859     LPBITMAPINFO pScanlineInfo = AllocDIB(Width, 1, 8, NULL);
06860     if (pScanlineInfo == NULL)
06861         return SLOWJOB_FAILURE;
06862 
06863     // Set up a simple greyscale palette for the bitmap
06864     for (INT32 i = 0; i < 256; i++)
06865     {
06866         pScanlineInfo->bmiColors[i].rgbRed = 
06867             pScanlineInfo->bmiColors[i].rgbGreen = 
06868                 pScanlineInfo->bmiColors[i].rgbBlue = i;
06869         pScanlineInfo->bmiColors[i].rgbReserved = 0;
06870     }
06871 
06872     // Set the blit mode
06873     INT32 OldMode = SetStretchBltMode(RenderDC->GetSafeHdc(), HALFTONE);//COLORONCOLOR);
06874 
06875     // Must call SetBrushOrgEx() after setting the stretchblt mode 
06876     // to HALFTONE (see Win32 SDK docs).
06877     POINT OldOrg;
06878     SetBrushOrgEx(RenderDC->m_hDC, 0, 0, &OldOrg);
06879 
06880     ColourContext *OutputContext = RenderView->GetColourContext(COLOURMODEL_RGBT);
06881     ERROR3IF(OutputContext == NULL, "Where's me RGB colour context gone then?");
06882 
06883     // Now copy the Bits from our Kernel Bitmap into the Memory DC
06884     // as a masked blit (a scan line at a time, so we can colour separate it)
06885     MaskRegion MaskInfo;
06886     pMask->GetFirstMaskRegion(&MaskInfo);
06887     while (MaskInfo.Length != 0)
06888     {
06889         // Update bitmap info to show the new scan line size
06890         pScanlineInfo->bmiHeader.biWidth     = MaskInfo.Length;
06891         pScanlineInfo->bmiHeader.biSizeImage = MaskInfo.Length * sizeof(BYTE);
06892 
06893         // Read out the scanline into our pScanline buffer, converting it to a generic
06894         // 32bpp format as we go. This is 
06895         WinBM->GetScanline32bpp(MaskInfo.y, TRUE, pScanline);
06896 
06897         // Now colour separate it. We only bother separating the unmasked portion of the scanline
06898         // which we place back in the left end of the scanline
06899         WinBM->ColourSeparateScanline32to8(OutputContext, SepTables,
06900                                             (BYTE *) pScanline,     // Output buffer (shared!)
06901                                             pScanline + MaskInfo.x, // Input buffer - !pointer arithmetic!
06902                                             MaskInfo.Length);
06903 
06904         // Work out the coords of the destination rectangle
06905         const INT32 DestX = Origin.x + INT32(ceil(MaskInfo.x * Ratio));
06906         const INT32 DestY = Origin.y - INT32(ceil((MaskInfo.y + 1) * Ratio));
06907         const INT32 DestWidth = INT32(ceil(MaskInfo.Length * Ratio));
06908         const INT32 DestHeight = INT32(ceil(1 * Ratio));
06909     
06910         // Blit the data to the screen
06911         StretchDIBits(  RenderDC->GetSafeHdc(),
06912                         DestX, DestY, DestWidth, DestHeight,
06913                         0, 0,
06914                         MaskInfo.Length, 1,
06915                         (BYTE *) pScanline, pScanlineInfo,
06916                         DIB_RGB_COLORS, SRCCOPY);
06917 
06918         // Update the progress display if necessary.
06919         if (PrintMonitor::PrintMaskType == PrintMonitor::MASK_MASKED &&
06920             Progress != NULL && !Progress->BitmapPhaseBandRenderedTo(MaskInfo.y))
06921         {
06922             Result = SLOWJOB_USERABORT;
06923             break;      // User aborted, so quit rendering, and return USERABORT
06924         }
06925 
06926         // Find the next bit of scan line to plot
06927         pMask->GetNextMaskRegion(&MaskInfo);
06928     }
06929 
06930     // Put the blit mode back as it was
06931     SetStretchBltMode(RenderDC->GetSafeHdc(), OldMode);
06932     SetBrushOrgEx(RenderDC->m_hDC, OldOrg.x, OldOrg.y, NULL);
06933 
06934     // Free up the tempory DIB I made
06935     FreeDIB(pScanlineInfo, NULL);
06936     CCFree(pScanline);
06937 
06938     return(Result);
06939 #else
06940     return SLOWJOB_FAILURE;
06941 #endif
06942 #else
06943     return SLOWJOB_SUCCESS;
06944 #endif
06945 }

BOOL OSRenderRegion::DrawTransformedBitmap NodeBitmap pNodeBitmap  )  [virtual]
 

Reimplemented from RenderRegion.

Definition at line 3419 of file osrndrgn.cpp.

03420 {
03421     // If we are not printing, then we'll always render as a bitmap fill
03422     // (eg. Gallery items).
03423     if (IsPrinting())
03424     {
03425         // If we are not drawing complex shapes and this shape is, then return
03426         if ((!RenderComplexShapes) && (TestForComplexShape(&Caps)))
03427             return TRUE;
03428 
03429         if ((!RenderComplexShapes) && (pNodeBitmap->NeedsTransparency()))
03430             return TRUE;
03431 
03432         // If we've not got a valid colour plate or it is disabled
03433         if (CurrentColContext->GetColourPlate() == NULL ||
03434             CurrentColContext->GetColourPlate()->IsDisabled())
03435         {
03436             // If it is a simple rectangular shape then 
03437             // we can use GDI to render it
03438             if (pNodeBitmap->HasSimpleOrientation(this))
03439             {                            
03440                 // Get hold of the coord array for the bitmap.
03441                 DocCoord *Coords = pNodeBitmap->InkPath.GetCoordArray();
03442 
03443                 // Work out where to render the bitmap on the device context - find top left corner
03444                 OilCoord TopLeft(Coords[0].x, Coords[0].y);
03445                 RenderMatrix.transform(&TopLeft);
03446                 WinCoord DestTopLeft = TopLeft.ToWin(RenderView);
03447 
03448                 // Find required size of bitmap on device context.
03449                 MILLIPOINT Width  = Coords[1].x - Coords[0].x;
03450                 MILLIPOINT Height = Coords[0].y - Coords[3].y;
03451 
03452                 FIXED16 fxPixelSize = 0;
03453                 RenderView->GetScaledPixelSize(&fxPixelSize, &fxPixelSize);
03454                 double dPixelSize = fxPixelSize.MakeDouble();
03455                 INT32 DestWidth = (INT32) ((((double) Width) / dPixelSize) + 0.5);
03456                 INT32 DestHeight = (INT32) ((((double) Height) / dPixelSize) + 0.5);
03457 
03458                 // Get handle to bitmap (must be a WinBitmap as we are in winoil!)
03459                 CWxBitmap *WxBM = (CWxBitmap *) pNodeBitmap->GetBitmap()->ActualBitmap;
03460 
03461                 wxImage *pwxImage=WxBM->MakewxImage(DestWidth, DestHeight);
03462 
03463                 if (pwxImage)
03464                 {
03465                     wxBitmap TheBitmap(*pwxImage);
03466                     RenderDC->DrawBitmap(TheBitmap, DestTopLeft.x, DestTopLeft.y, TRUE);
03467                     delete pwxImage;
03468                 }
03469             }
03470         }
03471     }
03472 
03473     // We can't do arbitrarily transformed bitmaps - use a bitmap fill.
03474     RenderComplexShapes = TRUE;
03475     BOOL bOk = RenderRegion::DrawTransformedBitmap(pNodeBitmap);
03476     RenderComplexShapes = FALSE;
03477 
03478     return bOk;
03479 }

wxPoint OSRenderRegion::FindBitmapOrigin DocCoord  Centre,
INT32  Width,
INT32  Height
[protected]
 

Finds the windows origin to plot a bitmap at, so that it's centre will be at the DocCoord specified.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/9/94
Parameters:
Centre - The DocCoord specifying the centre of the Bitmap. [INPUTS] Width & Height of the bitmap in Pixels.
Rewritten 20/06/95 by Phil: This routine now uses high-res coords until the final return command so that the centre of the bitmap can be matched to the centre of the pixel at the specified point. This allows these bitmap plots to be centered accurately using the same rules as thin lines and grid points.

Karim 11/09/2000 This method no longer uses GetScaledPixelWidth() or an integer pixel size, as these are inaccurate at high magnifications. Instead, it calculates its own floating-point pixel width, and converts to integer arithmetic as late as possible, for max. accuracy.

Scope: Protected

See also:
-

Definition at line 3640 of file osrndrgn.cpp.

03641 {
03642     DocCoord Origin;
03643     double PelSize;
03644 
03645     DocView *pDocView = DocView::GetSelected();
03646     ERROR3IF(pDocView == NULL, "OSRenderRegion::FindBitmapOrigin() when no view is selected!");
03647     if (pDocView)
03648         PelSize = (pDocView->GetPixelWidth() / pDocView->GetViewScale()).MakeDouble();
03649     else
03650         PelSize = 750;
03651 
03652     // Subract half the Width and Height
03653     Origin.x = Centre.x - (MILLIPOINT)(0.5 + (((double)Width * PelSize)/2));
03654     Origin.y = Centre.y + (MILLIPOINT)(0.5 + (((double)Height * PelSize)/2));
03655     
03656     return DocCoordToWin(Origin);
03657 }

void OSRenderRegion::FlushEORCache void   )  [static]
 

Flushes the EOR colour cache. Currently called when screen mode changes Scope: Public.

Author:
Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/5/95
Parameters:
- [INPUTS]
Returns:
-

Definition at line 1065 of file osrndrgn.cpp.

01066 {
01067     EORCache.Valid = FALSE;
01068 }

void OSRenderRegion::GetBlobRect FIXED16  Scale,
const DocCoord BlobPoint,
BlobType  bType,
DocRect pResult
[static]
 

To determine the DocRect of a blob without access to a render region.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/11/93
Parameters:
Scale - scale of view, normally DocView->GetViewScale() [INPUTS] BlobPoint - The Coord of the centre of the blob bType - the Type of Blob to draw. It can be either BT_SELECTED for a Selected point or BT_UNSELECTED for an unselected point or BT_CLICKME for the click rectangle or BT_SELECTEDLARGEST for the larger of the two selected options.
pResult - pointer to DocRect that will contain result [OUTPUTS]
Karim 22/05/2000 - added BT_CLIPVIEW blobtype, which lets me return the correct size for ClipView ToolObject blobs.

See also:
BlobType Scope: Public

Definition at line 3681 of file osrndrgn.cpp.

03682 {
03683     // ideally we would call GetScaledPixelWidth(), but that is a member fn of
03684     // OSRenderRegion as we don't have a render region, so we do similar code but
03685     // here instead. (Andy's understanding is that this only works for square pixels BTW)
03686 
03687     // Note from Tim: this function is a problem because it used to use the now defunct
03688     // OilCoord::PixelWidth() - hence we need to get a view from somewhere.  We assume
03689     // that the selected DocView is a safe view to use because:
03690     //  (a) Hopefully we only draw blobs into the selected view
03691     //  (b) All DocViews will share the same pixel size... until we port to the Mac(!)
03692     MILLIPOINT BlobSize;
03693     DocView *pDocView = DocView::GetSelected();
03694     ERROR3IF(pDocView == NULL, "OSRenderRegion::GetBlobRect() when no view is selected!");
03695 
03696     // Karim 22/06/2000 - we're gonna use a double instead. Not much accuracy
03697     // is needed for PelSize, but a MILLIPOINT gives us far too little!
03698 //  const MILLIPOINT PelSize = (pDocView->GetPixelWidth() / Scale).MakeLong();
03699     const double PelSize = (pDocView->GetPixelWidth() / Scale).MakeDouble();
03700 
03701     // All of the sizes extracted by this Switch statement are RADII.
03702     // So, for the blob to be centered correctly, the diameter of the blob will be
03703     //      PIXEL_DIAMETER = 2 * RADIUS + 1 Pixel!!!!!
03704     //
03705     switch (bType)
03706     {
03707         case BT_UNSELECTED:
03708             BlobSize = (MILLIPOINT)((double)UnSelectedBlobSize * PelSize);
03709             break;
03710 
03711         case BT_SELECTED:
03712             BlobSize = (MILLIPOINT)((double)SelectedBlobSize * PelSize);
03713             break;
03714 
03715         case BT_CLICKME:
03716             BlobSize = (MILLIPOINT)((double)HitTestRadius * PelSize);
03717             break;
03718 
03719         case BT_SELECTEDLARGEST:
03720             BlobSize = max( (MILLIPOINT)((double)UnSelectedBlobSize * PelSize),
03721                             (MILLIPOINT)((double)SelectedBlobSize * PelSize) );
03722             break;
03723 
03724         case BT_MSTAGEFILLUNSELECTED:
03725             BlobSize = (MILLIPOINT)((double)MultiStageUnSelectedBlobSize * PelSize);
03726             break;
03727 
03728         case BT_MSTAGEFILLSELECTED:
03729             BlobSize = (MILLIPOINT)((double)MultiStageSelectedBlobSize * PelSize);
03730             break;
03731 
03732         case BT_MSTAGESELECTEDLARGEST:
03733             BlobSize = max( (MILLIPOINT)((double)MultiStageSelectedBlobSize * PelSize),
03734                             (MILLIPOINT)((double)MultiStageUnSelectedBlobSize * PelSize) );
03735             break;
03736 
03737         case BT_CLIPVIEW:
03738             BlobSize = (MILLIPOINT)((double)ClipViewBlobSize * PelSize);
03739             break;
03740 
03741         default:
03742             ENSURE( FALSE, "GetBlobRect() was called with an invalid BlobType" );
03743             BlobSize = 0;                           // so we get an empty rectangle
03744             break;
03745     }
03746 
03747     // Build the rectangle of the appropriate size and centre it on the DocCoord given
03748     pResult->lo.x = BlobPoint.x - BlobSize - (MILLIPOINT)(PelSize/2.0);
03749     pResult->lo.y = BlobPoint.y - BlobSize - (MILLIPOINT)(PelSize/2.0);
03750     pResult->hi.x = BlobPoint.x + BlobSize + (MILLIPOINT)(PelSize/2.0);
03751     pResult->hi.y = BlobPoint.y + BlobSize + (MILLIPOINT)(PelSize/2.0);
03752 
03753 }

wxSize OSRenderRegion::GetFixedDCPPI wxDC &  DC  )  [static]
 

Fix up crazy wxWindows screen DPI calculation.

Author:
Alex Bligh
Date:
07/01/2006
Returns:
DPI in both directions as a wxSize
Notes: wxWindows REALLY tries to calculate the screen DPI. By that I mean it takes the width and depth of the screen (as specified somehow to gdk by the user) in millimeters, and then divides by the pixels. Camelot needs a fixed view of the world, so on any system 100% is the same number of pixels. We use a FIXED 96dpi on Windows & Linux and, presently, on the Mac too so that documents look identical on all platforms (render same area of pixels so that comparative timings make sense).

Returns:
Errors: -
See also:
wxDC::GetPPI

Definition at line 7283 of file osrndrgn.cpp.

07284 {
07285     // Set system defaults
07286 PORTNOTE("MacPort", "We should allow the user to configure this value on the mac, maybe on all platforms")
07287 #ifdef __WXMAC__
07288     wxSize PPI(96,96);
07289 #else
07290     wxSize PPI(96,96);
07291 #endif
07292 
07293     // If it's not a Screen DC or a PaintDC we MIGHT just believe it!   
07294     if (! ( DC.IsKindOf(CLASSINFO(wxScreenDC)) || DC.IsKindOf(CLASSINFO(wxPaintDC)) ))
07295         PPI=DC.GetPPI();
07296 
07297     return PPI;
07298 }

void OSRenderRegion::GetFixedSystemTextSize StringBase TheText,
DocRect BoundsRect,
double *  atDpi = NULL
[virtual]
 

To determine how much room is needed to plot a bit of text with OSRenderRegion::DrawFixedSystemText.

Author:
Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/3/95
Parameters:
TheText - The string to obtain the rendered size from [INPUTS]
BoundsRect - Returned with the size of the rectangle needed to display [OUTPUTS] said text string. This rect always has one corner at (0,0)
Returns:
-
Notes: If for any reason the call fails, an origin based rectangle with zero height and width will be returned.

See also:
OSRenderRegion::DrawFixedSystemText

Reimplemented from RenderRegion.

Definition at line 2359 of file osrndrgn.cpp.

02360 {
02361     wxString Text = (wxString)(TCHAR *)(*TheText);
02362 
02363     ERROR3IF(TheText == NULL, "OSRenderRegion::GetFixedSystemTextSize given a null text pointer");
02364     ERROR3IF(BoundsRect == NULL, "OSRenderRegion::GetFixedSystemTextSize given a null bounds rect pointer");
02365     if(TheText == NULL || BoundsRect == NULL)
02366         return;
02367 
02368     wxFont SaveFont=RenderDC->GetFont();
02369 
02370     wxFont FixedFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
02371     FixedFont.SetPointSize(8);
02372     RenderDC->SetFont(FixedFont);
02373 
02374     INT32 LineHeight = 0;
02375     // This won't actually draw the text, instead it returns a rectangle in 'Rect'  
02376     // LineHeight = RenderDC->DrawText((TCHAR *) (*TheText), -1, &Rect, uFormat);
02377     LineHeight = RenderDC->GetCharHeight();
02378     wxCoord w, h;
02379     RenderDC->GetTextExtent(Text, &w, &h);
02380     wxRect Rect(0, 0, w, h);
02381 
02382     RenderDC->SetFont(SaveFont);
02383 
02384     wxDC * pDC = RenderDC;
02385     wxSize DPI = GetFixedDCPPI(*pDC);
02386     INT32 XDPI = DPI.GetWidth();
02387     INT32 YDPI = DPI.GetHeight();
02388 
02389     if(XDPI == 0 || YDPI == 0 || LineHeight == 0)
02390     {
02391         ERROR3("Can not calculate text size");
02392         *BoundsRect = DocRect(0, 0, 0, 0);
02393         return;
02394     }
02395     // For some reason, Rect.bottom and Rect.top seem to be incorrect, so we have
02396     // to use the returned LineHeight value
02397     *BoundsRect = DocRect(0, 0,
02398                             (INT32)(((double)Rect.width * IN_MP_VAL) / XDPI),
02399                             (INT32)(((double)LineHeight * IN_MP_VAL) / YDPI) );
02400     return;
02401 
02402 }

MILLIPOINT OSRenderRegion::GetHitTestRadius DocView pDocView  )  [static]
 

Allows user to adjust the sensitivity of hit-testing.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/6/94
Parameters:
The DocView that we are doing hit-testing in. [INPUTS]
- [OUTPUTS]
Returns:
The hit-test sensitivity measured in millipoints. An object with given document coordinates is considered to be clicked upon if it lies within this radius of the click position.

Errors: -

See also:
OSRenderRegion::GetBlobRect; NodeRenderableInk::FindFirstAtPoint

Definition at line 3772 of file osrndrgn.cpp.

03774 {
03775     FIXED16 fxViewScale = pDocView->GetViewScale();
03776     FIXED16 fxPelSize = ((FIXED16) HitTestRadius) * pDocView->GetPixelWidth();
03777     return (MILLIPOINT) (fxPelSize / fxViewScale).MakeLong();
03778 }

void OSRenderRegion::GetRenderRegionCaps RRCaps pCaps  )  [virtual]
 

This function is used to help determine what an individual render region is capable of. A render can mark the things it can not render (eg transparancy) so that a more complex rendering of these parts of the document can be done.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/4/95
Parameters:
pCaps - the render region marks all the things it can not do into the pCaps [OUTPUTS] param

Reimplemented from RenderRegion.

Definition at line 6479 of file osrndrgn.cpp.

06480 {
06481     // Start off by saying I can't do anything
06482     pCaps->CanDoNothing();
06483 
06484     // but actually I can do these things
06485     pCaps->GradFills = TRUE;
06486     pCaps->LineAttrs = TRUE;
06487     pCaps->ArrowHeads = TRUE;
06488     pCaps->DashPatterns = TRUE;
06489 
06490     // We only try simple bitmaps with GDI if printing
06491     pCaps->SimpleBitmaps = IsPrinting();
06492 
06493 //  pCaps->CanDoAll();
06494 }

void OSRenderRegion::GetValidBrush  )  [protected]
 

Definition at line 1334 of file osrndrgn.cpp.

01335 {
01336     if (!RFlags.ValidBrush)
01337         SelectNewBrush();
01338 }

void OSRenderRegion::GetValidPen  )  [protected]
 

Definition at line 1328 of file osrndrgn.cpp.

01329 {
01330     if (!RFlags.ValidPen)
01331         SelectNewPen();
01332 }

BOOL OSRenderRegion::Init void   )  [static]
 

To be called during startup. Reads preferences. Scope: Static.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/3/94
Parameters:
- [INPUTS]
Returns:
TRUE if worked, FALSE if didnt (cannot fail at present)

Reimplemented from RenderRegion.

Definition at line 270 of file osrndrgn.cpp.

00271 {
00272     if (Camelot.DeclareSection(TEXT("DisplayKludges"), 10))
00273     {
00274         Camelot.DeclarePref( NULL, TEXT("SlowRectangles"), &BodgeRectangles, FALSE, TRUE );
00275     }
00276 
00277     if (Camelot.DeclareSection(TEXT("Printing"), 10))
00278     {
00279         Camelot.DeclarePref( NULL, TEXT("PrintRotatedTextAsShapes"), &PrintRotatedTextAsPaths, FALSE, TRUE );
00280     }
00281 
00282     if (Camelot.DeclareSection(TEXT("Screen"), 10))
00283     {
00284         Camelot.DeclarePref(NULL, TEXT("GDIPalette"), &WantGDIPalette, FALSE, TRUE );
00285         Camelot.DeclarePref(NULL, TEXT("BetterLines"), &WantBetterLines, 0, 2 );
00286         
00287         switch (WantBetterLines)
00288         {
00289             case 0:
00290                 DoBetterLines = TRUE;
00291                 break;
00292 
00293             case 1:
00294                 DoBetterLines = TRUE;
00295                 break;
00296 
00297             case 2:
00298                 DoBetterLines = FALSE;
00299                 break;
00300         }
00301     }
00302 
00303     if (Camelot.DeclareSection(TEXT("Mouse"), 10))
00304     {
00305         Camelot.DeclarePref(NULL, TEXT("HitTestRadius"), &HitTestRadius, 0, 10);
00306     }
00307 
00308     return TRUE;
00309 }

void OSRenderRegion::InitAttributes void   )  [protected, virtual]
 

Sets up a default GDI pen and brush for rendering, and calculates the Brush origin for aligned fill patterns. Scope: Private.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
31/5/93

Implements RenderRegion.

Definition at line 792 of file osrndrgn.cpp.

00793 {
00794     CurrentPen = 0;
00795     CurrentBrush = 0;
00796 //  OldBrush = NULL;
00797 //  OldPen = NULL;
00798     OldFont = NULL;
00799 
00800     if (!RFlags.Metafile)
00801     {
00802         // Set the default font (intended for kernel-rendered dialogues)
00803         // Don't bother for metafiles (because we can't read text from them anyhow)
00804     PORTNOTE("other","OSRenderRegion::InitAttributes - removed setting of default font");
00805 #if !defined(EXCLUDE_FROM_XARALX)
00806         wxFont* FixedSystemFont = FontFactory::GetCFont(STOCKFONT_RNDRGNFIXEDTEXT);
00807         if (FixedSystemFont != NULL)
00808             OldFont = RenderDC->SetFont(*FixedSystemFont);
00809 #endif
00810     }
00811 
00812     SetOSDrawingMode();
00813     SetLineAttributes();    // Create a default Pen
00814     SetFillAttributes();    // Create a default Brush
00815 
00816     if (!RFlags.Metafile)
00817     {
00818         // Metafiles don't need brush origin calculations
00819 
00820         // Now we calculate the Origin for the Brush fill pattern, so that fill patterns
00821         // are always aligned as we scroll around the page.
00822     
00823         // (First we get the Origin of the Document in DocCoords)
00824         // Actually, at Jim's suggestion Andy now bases this on (0,0).
00825         DocCoord DocOrigin;
00826         DocOrigin.x = 0;                    //was MinDocCoord+0x20000;
00827         DocOrigin.y = 0;                    //was MaxDocCoord-0x20000;
00828         
00829 //      f1 = f;
00830         // Then we transform it into OSCoords
00831         WinCoord OSOrigin;
00832         OSOrigin = DocCoordToWin(DocOrigin);
00833     
00834         // when running on some machine combinations, we need to further adjust the point
00835         // relative to the screen. The only combination that works is a 32-bit version
00836         // running on NT. Everyone else has to fix it up.
00837 PORTNOTE("other", "Check this");
00838 //      if (IsWin32s())
00839         {
00840             if (RenderView)
00841             {
00842                 // Get the OIL window and get it to do the conversion for us.
00843                 CCamView* RenderWindow = RenderView->GetConnectionToOilView();
00844                 if ( RenderWindow!=NULL && RenderWindow->GetFrame()!=NULL )
00845                     RenderWindow->GetFrame()->ClientToScreen(OSOrigin);
00846                 // In galleries, RenderView used to be NULL, so this code was never called.
00847                 // This has changed, so suddenly this ensure was going off. Now it won't.
00848                 //else
00849                 //  ERROR2RAW("No render window in OSRenderRegion::InitAttributes()");
00850             }
00851         }
00852     
00853         // The Brush Origin is set to a value between 0 and 7 calculated from the position of the
00854         // transformed origin.
00855         NewBrushOrg.x = OSOrigin.x & 7;
00856         NewBrushOrg.y = OSOrigin.y & 7;
00857     } 
00858 
00859 }

void OSRenderRegion::InitClipping void   )  [protected, virtual]
 

Creates a Windows CRgn object from the DocRect passed in the constructor. The CRgn is set as the current clipping region during reendering. Scope: Private.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
02/6/93

Implements RenderRegion.

Definition at line 726 of file osrndrgn.cpp.

00727 {
00728 
00729     // OLD COMMENT and CODE:
00730     // Windows rects are slightly differnt to DocView rects so we expand them by 1 pixel
00731     //WinRect OSClipRect = DocRectToWin(CurrentClipRect, 0,0,1,1);
00732 
00733     // now the seemingly spurious 1,1s have been removed as they are indeed spurious
00734     WinRect OSClipRect = DocRectToWin(CurrentClipRect, 0,0,0,0);
00735 
00736 //  ENSURE(OSClipRect.top >= 0, "Blobby!");
00737 
00738 //  This line commented out by Alex, to fix Bugzilla #991, per Neil, Gavin
00739 //  ERROR3IF((OSClipRect.x < 0) || (OSClipRect.y < 0), "OSRenderRegion::InitClipping bad clip");
00740 
00741     // we can't clip within a metafile, but we can set the origin & extent based on it
00742 //  if (RFlags.Metafile)
00743 //  {
00744 //      RenderDC->SetWindowOrg( OSClipRect.x, OSClipRect.y );
00745 //      RenderDC->SetWindowExt( OSClipRect.width, OSClipRect.height );
00746 //  }
00747 //  else
00748     {
00749         delete OSClipRegion;    // This will be NULL if no previous CRgn defined.
00750         OSClipRegion = new wxRegion(OSClipRect);
00751         ENSURE(OSClipRegion != NULL,"'new' failed when creating OSClipRegion");
00752 
00753         // Set the Clipping Region
00754         if (OSClipRegion)
00755             RenderDC->SetClippingRegion(*OSClipRegion);
00756     }
00757 }

BOOL OSRenderRegion::InitDevice  )  [virtual]
 

Initialise the device specific mechanisms for this render region.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/05/94
Returns:
TRUE if the device context is initialised ok; FALSE if not.

Errors: Same as base class.

See also:
RenderRegion::InitDevice

Reimplemented from RenderRegion.

Reimplemented in PaperRenderRegion.

Definition at line 656 of file osrndrgn.cpp.

00657 {
00658     // Call base class
00659     if (!RenderRegion::InitDevice())
00660         return FALSE;
00661 
00662     // Get the HDC so we can reconstruct the CDC later.
00663 //  DCHandle = RenderDC->GetSafeHdc();
00664 
00665     // Ignore any error from GBrush initialisation - we can live without GBrush.
00666     // However, we only want GBrush on the screen thanks
00667     if (IsPrinting())
00668     {
00669         // if we don't do this, bitmaps printed at the same DPI as the printer come
00670         // out wrong on NT drivers
00671         // Note: although this is claimed to be a Win32s-compatible function,
00672         // GDI16 generates an error for it (invalid value 4)
00673         // Note2: The MFC version of this function looks like the 16-bit API call,
00674         // so we call the API directly here
00675         //::SetStretchBltMode( RenderDC->m_hDC, HALFTONE );
00676     }
00677     else
00678     {
00679         GDrawBrush.Init( RenderDC );
00680     }
00681 
00682     // Find out what grad fill quality to use.
00683     PrintControl *pPrintControl = RenderView->GetPrintControl();
00684     PrintFillQuality FillQuality;
00685 
00686     if (pPrintControl != NULL)
00687         FillQuality = pPrintControl->GetFillQuality();
00688     else
00689         FillQuality = PRINTFILLQUALITY_MEDIUM;
00690 
00691     switch (FillQuality)
00692     {
00693         case PRINTFILLQUALITY_LOW:
00694             GradFillQuality = 2;
00695             break;
00696 
00697         case PRINTFILLQUALITY_HIGH:
00698             GradFillQuality = 0;
00699             break;
00700 
00701         case PRINTFILLQUALITY_MEDIUM:
00702         default:
00703             GradFillQuality = 1;
00704             break;
00705     }
00706 
00707 
00708     // All ok
00709     return TRUE;
00710 }

void OSRenderRegion::MakeDashType DashRec ,
DashType
[protected]
 

Definition at line 2829 of file osrndrgn.cpp.

02830 {
02831     INT32 Length = KernelDash.Elements;
02832 
02833     if (Length > 8) Length = 8;
02834         
02835     GavinDash->Length = Length;
02836     GavinDash->Offset = KernelDash.DashStart;
02837 
02838     for (INT32 el = 0; el < Length; el++)
02839     {
02840         GavinDash->Array[el] = KernelDash.ElementData[el];
02841     }
02842 }

void OSRenderRegion::MakeEllipticalPath Path pPath,
DocCoord  Parallel[4]
[static, protected]
 

Definition at line 4767 of file osrndrgn.cpp.

04768 {
04769     // Get an array to put the 12 different coords needed to specify an ellipse
04770     DocCoord NewCoords[12];
04771 
04772     // Calculate the 3 coordinates along each side of the parallelogram
04773     NodeEllipse::CalcEllipseEdge(Parallel[0], Parallel[1], &NewCoords[11], &NewCoords[0], &NewCoords[1]);
04774     NodeEllipse::CalcEllipseEdge(Parallel[1], Parallel[2], &NewCoords[2], &NewCoords[3], &NewCoords[4]);
04775     NodeEllipse::CalcEllipseEdge(Parallel[2], Parallel[3], &NewCoords[5], &NewCoords[6], &NewCoords[7]);
04776     NodeEllipse::CalcEllipseEdge(Parallel[3], Parallel[0], &NewCoords[8], &NewCoords[9], &NewCoords[10]);
04777 
04778     // build a path
04779     pPath->ClearPath();
04780     pPath->FindStartOfPath();
04781 
04782     // Start at bottom left corner
04783     PathFlags NewFlags;
04784     NewFlags.IsRotate = TRUE;
04785     pPath->InsertMoveTo(NewCoords[0], &NewFlags);
04786     pPath->InsertCurveTo(NewCoords[1], NewCoords[2], NewCoords[3], &NewFlags);
04787     pPath->InsertCurveTo(NewCoords[4], NewCoords[5], NewCoords[6], &NewFlags);
04788     pPath->InsertCurveTo(NewCoords[7], NewCoords[8], NewCoords[9], &NewFlags);
04789     pPath->InsertCurveTo(NewCoords[10], NewCoords[11], NewCoords[0], &NewFlags);
04790 
04791     // Close the path properly
04792     pPath->CloseSubPath();
04793 }

INT32 OSRenderRegion::MPtoLP MILLIPOINT  MPtoConvert  )  [protected]
 

Converts a value in MilliPoints into a GDI Logical value. IT ASSUMES A MM_TEXT MAPPING MODE AT PRESENT. Scope: Private.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/5/93
Parameters:
MPtoConvert is a value in MILLIPOINTS [INPUTS]
Returns:
The size in logical units

Definition at line 3204 of file osrndrgn.cpp.

03205 {
03206     MILLIPOINT PixelWidth = GetScaledPixelWidth();
03207     return INT32(MPtoConvert/PixelWidth);   // Note this assumes MM_TEXT mapping mode   
03208 }

INT32 OSRenderRegion::RawRenderPath DocCoord * const  Coords,
PathVerb * const  Verbs,
INT32  NumCoords,
INT32 *  PolyCounts,
INT32 *  ResCount,
INT32  Flatness = 0,
INT32 *  pActualFlatness = NULL
[protected]
 

Low level primitive for rendering paths without GDI32. Note that PointArray should be freed by the caller upon completion.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/4/94
Parameters:
A path to be drawn (in DocCoords). [INPUTS] Flatness - the value to use when flattening a curve. pActualFlatness - if the caller wants to know what flatness was eventually reached while flattening the path, it passes in a pointer here to be filled in. If the path could not be flattened, this contains the last flatness level that was tried before giving up.
PolyCounts must point to an array of MAX_POLYGONS ints which will be filled [OUTPUTS] in with a list of polygon sizes (can be just 1 big if ResCount is NULL). ResCount will be updated with the number of polygons. If it is NULL then the routine returns after the end of the first sub-path has been found. The points calculated from this will be in the PointArray variable.
Returns:
Number of points read, 0 if failed (e.g. not enough memory or too complex).

Errors: - Scope: Private

See also:
RawRenderPath32

Definition at line 2438 of file osrndrgn.cpp.

02441 {
02442     // Flatness less than 0 will screw up, so let's ignore it
02443     if (Flatness < 0)
02444         return 0;
02445 
02446     // We have to manually flatten the beziers in the curve and decide when to draw them.
02447     INT32 MaxFlatness;
02448 
02449     // Decide how flat we are going to make this curve, if the caller has not specified
02450     if (Flatness == 0)
02451     {
02452         // (Tim says: these figures are a bit arbitrary, especially the MaxFlatness ones)
02453         if (RFlags.Metafile)
02454         {
02455 #if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX)
02456             // If this is a Metafile view then go and find out the flatness
02457             if (RenderView->IS_KIND_OF(MetafileView))
02458                 Flatness = ((MetafileView*)RenderView)->GetMetafileFlatness();
02459             else
02460 #endif
02461                 Flatness = 512;
02462         }
02463         else
02464         {
02465             Flatness = CalcPathFlattening();
02466         }
02467     }
02468 
02469     MaxFlatness = Flatness * 8;
02470 
02471     // The number of polygons found so far
02472     INT32 Count = 0;
02473 
02474     // The number of points that have been placed in complete polygons
02475     INT32 PointsSoFar = 0;
02476 
02477     // Position we are reading points from
02478     INT32 ReadPos = 0;
02479 
02480     // Flatten curve until it works or flatness becomes too inaccurate.
02481     BOOL Worked = FALSE;
02482     while (!Worked && (Flatness <= MaxFlatness) &&(Flatness > 0))
02483     {
02484         // Position we are adding points at
02485         InsertPos = 0;
02486 
02487         ReadPos = 0;
02488         Count = 0;
02489         PointsSoFar = 0;
02490 
02491         Worked = TRUE;
02492         BOOL KeepGoing = TRUE;
02493 
02494         // loop through the whole path
02495         while (
02496                 KeepGoing &&
02497                 (ReadPos < NumCoords) &&
02498                 Worked
02499               )
02500         {
02501             if ( InsertPos >= SIZEOF_POLYLINE_BUFFER )
02502             {
02503                 // this check is enough for those times when CurrentPoint is simply incrememented,
02504                 // but is insufficient when it is increased by more than one, so additional checks
02505                 // are needed elsewhere
02506                 TRACE( _T("Path too complex to flatten\n"));
02507                 InsertPos = 0;
02508                 Worked = FALSE;
02509                 break;
02510             }
02511 
02512             // Find out the type of element that we are over (after the close flag has been removed)
02513             Coord P[4];
02514             INT32 OldInsertPos;
02515 
02516             switch ( (Verbs[ReadPos]) & (~PT_CLOSEFIGURE) )
02517             {
02518                 case PT_MOVETO:
02519                     // This represents the start of a new polygon, so finish the last one
02520                     if (InsertPos>0)
02521                     {
02522                         // We have put points into the polygon, so this is not the first one
02523                         PolyCounts[Count] = InsertPos - PointsSoFar;
02524 
02525                         // Keep tabs on how many points have been put in polygons so far
02526                         PointsSoFar = InsertPos;
02527 
02528                         // Count the number of polygons
02529                         Count++;
02530 
02531                         // Make sure its not too many
02532                         if (Count == MAX_POLYGONS)
02533                         {
02534                             TRACE( _T("Too many polygons in path to render\n") );
02535                             InsertPos = 0;
02536                             Worked = FALSE;
02537                             break;
02538                         }
02539 
02540                         if (ResCount==NULL)
02541                         {
02542                             // sub-path has ended, stop the loop now
02543                             KeepGoing = FALSE;
02544                             break;
02545                         }
02546                     }
02547 
02548                     // Put the MoveTo into the point array
02549                     PointArray[InsertPos] = DocCoordToWin(Coords[ReadPos]);
02550                     InsertPos++;
02551                     ReadPos++;
02552                     break;
02553 
02554 
02555                 case PT_LINETO:
02556                     // Put the LineTo into the point array
02557                     PointArray[InsertPos] = DocCoordToWin(Coords[ReadPos]);
02558                     InsertPos++;
02559                     ReadPos++;
02560                     break;
02561 
02562 
02563                 case PT_BEZIERTO:
02564                     // If this point is a bezier, then the next 2 points should be beziers to
02565                     ENSURE((Verbs[ReadPos+1]) & (~PT_CLOSEFIGURE), "Bezier found with 1 point");
02566                     ENSURE((Verbs[ReadPos+2]) & (~PT_CLOSEFIGURE), "Bezier found with 2 points");
02567                 
02568                     // Make sure that this is not at the start of the path
02569                     ENSURE(ReadPos>0, "Broken path found while flattening" );
02570                     OldInsertPos = InsertPos;
02571 
02572                     // Flatten the bezier out
02573                     P[0] = DocCoordToOS256(Coords[ReadPos-1]);
02574                     P[1] = DocCoordToOS256(Coords[ReadPos]);
02575                     P[2] = DocCoordToOS256(Coords[ReadPos+1]);
02576                     P[3] = DocCoordToOS256(Coords[ReadPos+2]);
02577 
02578                     if (!Bezier(P[0].x,P[0].y, P[1].x,P[1].y, P[2].x,P[2].y, P[3].x,P[3].y, Flatness))
02579                     {
02580                         // Not enough room to flatten bezier.
02581                         Worked = FALSE;
02582                         break;
02583                     }
02584 
02585                     // If the curve was already flat then check to see if the curve was a vertical
02586                     // or horizontal line.  If it was then ensure the coords are the same to avoid kinks.
02587                     if (InsertPos == OldInsertPos+1)
02588                     {
02589                         if (Coords[ReadPos-1].x == Coords[ReadPos+2].x)
02590                             PointArray[OldInsertPos].x = PointArray[OldInsertPos-1].x;
02591                         if (Coords[ReadPos-1].y == Coords[ReadPos+2].y)
02592                             PointArray[OldInsertPos].y = PointArray[OldInsertPos-1].y;
02593                     }
02594 
02595                     // Update the positions and break
02596                     // InsertPos is updated by the bezier functions as the number of points
02597                     // that they add depends on the curve
02598                     ReadPos+=3;
02599                     break;
02600 
02601                 default:
02602                     ENSURE( FALSE, "We found a Path Element that does not exist!" );
02603                     break;
02604             }
02605 
02606             if (ResCount==NULL)
02607             {
02608                 // caller wants sub-paths, better check for close markers
02609                 if (Verbs[ReadPos-1] & PT_CLOSEFIGURE)
02610                     KeepGoing = FALSE;
02611             }
02612         }
02613 
02614         // Increase flatness in case we need to try again.
02615         Flatness *= 2;
02616     }
02617     
02618     if (!Worked)
02619     {
02620         // oops - didn't work
02621     }
02622     // complete the information about the last polygon in the list
02623     else if (InsertPos>0)
02624     {
02625         PolyCounts[Count] = InsertPos - PointsSoFar;
02626         Count++;
02627 
02628         if (ResCount)
02629             *ResCount = Count;
02630     }
02631     else
02632     {
02633         if (ResCount)
02634             *ResCount = 0;
02635         else
02636         {
02637             ENSURE(FALSE, "strange short path");
02638             Worked = FALSE;                                     // don't use incomplete data
02639         }
02640     }
02641 
02642     // Tell the caller what flatness we used if necessary
02643     if (pActualFlatness != NULL)
02644         *pActualFlatness = Flatness;
02645 
02646     // return value is number of verb/coord pairs read.
02647     return Worked ? ReadPos : 0;
02648 }

BOOL OSRenderRegion::RawRenderPath32 Path const  )  [protected]
 

Definition at line 6347 of file osrndrgn.cpp.

06348 {
06349     PORTNOTETRACE("other","OSRenderRegion::RawRenderPath32 - do nothing");
06350 #ifndef EXCLUDE_FROM_XARALX
06351     BOOL Worked;
06352 
06353     // Find out some details about the path and fail if it is not valid
06354     INT32 NumCoords = DrawPath->GetNumCoords();
06355     ENSURE(NumCoords>0, "Tried to draw a path with no elements in it in OSRenderRegion::RawRenderPath32");
06356     if (NumCoords==0)
06357         return FALSE;
06358 
06359     // Find out about the coords
06360     DocCoord* Coords = DrawPath->GetCoordArray();
06361 
06362     // ideally this would be new POINT[NumCoords] but it can't be because that throws an exception
06363     POINT* NTCoords = (POINT*)CCMalloc( sizeof(POINT)*NumCoords );
06364 
06365     if (NTCoords==NULL)
06366     {
06367         TRACE( _T("No memory to convert curve\n") );
06368         return FALSE;
06369     }
06370 
06371     // Convert the points to windows coords
06372     for (INT32 i=0; i<NumCoords; i++)
06373         NTCoords[i] = DocCoordToWin(Coords[i]);
06374 
06375     // render them
06376     Worked = BeginPath( RenderDC );
06377     if (Worked)
06378     {
06379         Worked = NewPolyDraw( NTCoords, DrawPath->GetVerbArray(), NumCoords );
06380         if (Worked)
06381             Worked = EndPath( RenderDC );
06382     }
06383 
06384     CCFree( NTCoords );
06385 
06386     if (!Worked)
06387         TRACE( _T("Raw render32 failed"));
06388 
06389     return Worked;
06390 #else
06391     ENSURE(FALSE, "Raw32 cannot work on win16");
06392     return FALSE;
06393 #endif
06394 }

BOOL OSRenderRegion::RenderBitmapFill Path PathToDraw,
BitmapFillAttribute Fill
 

Render bitmap fills clipped through a path. BODGED to simple plot the bitmap. Scope: Public.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/8/94
Parameters:
A path to render and a bitmap fill attribute. [INPUTS]
- [OUTPUTS]
Returns:
Errors: -

TRUE if worked, FALSE if failed.

Definition at line 4321 of file osrndrgn.cpp.

04322 {
04323     if (Fill->GetBitmap() == NULL || Fill->GetBitmap()->ActualBitmap == NULL)
04324         return FALSE;                                   // if no bitmap
04325 
04326     // if rendering to a bitmap, return FALSE so it is rendered solid. Test should be in
04327     // caller code in RenderBitmapFillAttribute but here is OK for now.
04328     if ((RenderFlags.VeryMono) || (RFlags.Metafile))
04329         return FALSE;
04330 
04331     ENSURE( Fill->GetBitmap()->ActualBitmap->IsKindOf( CC_RUNTIME_CLASS( CWxBitmap ) ), "Strange bitmapfill");
04332 
04333 // Since the GDI cannot cope with anything other than very simple bitmaps,
04334 // we will get GDraw to render the bitmap into a screen compatible DIB, and
04335 // then get the GDI to plot that
04336 
04337     GDrawContext* GD = GRenderRegion::GetStaticDrawContext();
04338     CWxBitmap *WxBM = NULL;
04339     CWxBitmap *OrigWxBM = NULL;
04340 
04341     const INT32 bpp = Fill->GetBitmap()->GetBPP();
04342     BYTE *pGreyTable = NULL;
04343 
04344     if (Fill->GetStartColour() != NULL && Fill->GetEndColour() != NULL)
04345     {
04346         // The bitmap is contoned ... so we need to use the greyscale version
04347         WxBM = (CWxBitmap*)Fill->GetBitmap()->GetGreyscaleVersion();
04348 
04349         if (WxBM == NULL && bpp == 8)
04350         {
04351             // Aha, we're gunna do some clever palette jiggery pokery
04352             pGreyTable = Fill->GetBitmap()->ActualBitmap->GetGreyscaleTable();
04353         }
04354     }   
04355 
04356     // Now make sure that if the WinBitmap is 32 that we RENDER it into a tempory FULLY TRANSPARENT WHITE BMP.
04357     // This stops the CONVERT function later on stripping the alpha channel off producing solid, non-transparent
04358     // coloured objects on black black backgrounds! - MarkH 20/7/99.
04359     if (WxBM == NULL)
04360     {
04361         if (bpp != 32)
04362         {
04363             WxBM = (CWxBitmap*)Fill->GetBitmap()->ActualBitmap;
04364         }
04365         else
04366         {
04367             WxBM = (CWxBitmap*)CBMPBits::RenderBMPFillAttrToTransparentWhiteRect(Fill);
04368         }
04369     }
04370 
04371     if (!WxBM)              // we really should check this pointer!
04372     {
04373         return (FALSE);
04374     }
04375 
04376     if( (WxBM->BMInfo==NULL) || (WxBM->BMBytes==NULL) )
04377         return FALSE;
04378 
04379     // Work out what Tempory bitmap we need
04380 
04381 // Note we are forcing the bitmap to be a horizontal rectangular bitmap, 
04382 // as the GDI can't cope with rotating them
04383 
04384     wxPoint BottomLeft  = DocCoordToWin( Fill->StartPoint );
04385     wxPoint BottomRight = DocCoordToWin( Fill->EndPoint   );
04386     wxPoint TopLeft     = DocCoordToWin( Fill->EndPoint2  );
04387 
04388     INT32 DestWidth  = BottomRight.x - BottomLeft.x;
04389     INT32 DestHeight = BottomLeft.y  - TopLeft.y;
04390     if (DestWidth==0 || DestHeight==0)
04391     {
04392         return TRUE;
04393     }
04394 
04395     if (IsPrinting())
04396     {
04397         if (CurrentColContext->GetColourPlate() == NULL ||
04398             CurrentColContext->GetColourPlate()->IsDisabled())
04399         {
04400 PORTNOTE("other", "No StretchDIBits call in OSRenderRegion::RenderBitmapFill")
04401 #ifndef EXCLUDE_FROM_XARALX
04402             // going to a printer? - let its driver stretch it about etc
04403             const LPBITMAPINFO bmInfo = WxBM->BMInfo;
04404 
04405             #if 1
04406             // this is the correct legit code
04407             const BOOL SendDirectToPrinter = true;
04408             #else
04409             // test code
04410             const BOOL SendDirectToPrinter = RFlags.Metafile;           // only metafiles
04411             #endif
04412 
04413             if (SendDirectToPrinter)
04414             {
04415                 // pass bitmap straight to driver. Might have to band this call
04416                 // up on low-capacity machines at some point. Also does this for
04417                 // metafiles too.
04418                 StretchDIBits( RenderDC->m_hDC, 
04419                                     BottomLeft.x, TopLeft.y,                // dest XY
04420                                     DestWidth, DestHeight,                  // dest WH
04421                                     0,0,                                    // source 0,0
04422                                     bmInfo->bmiHeader.biWidth,          // source W
04423                                     bmInfo->bmiHeader.biHeight,         // source H
04424                                     WinBM->BMBytes,
04425                                     bmInfo,
04426                                     DIB_RGB_COLORS,
04427                                     SRCCOPY );
04428 
04429                 return TRUE;
04430             }
04431 #endif
04432 
04433             // if 16- or 32-bit, leave for later. We get Gavin to scale it to an output bitmap
04434             // then PlotDeepDIB it. Sadly, this requires serious amounts of RAM, so is prone
04435             // to failure. The solution would be a ScaleDeepDIB call, like PlotDeepDIB but
04436             // that can scale appropriately. Such a function would then be called here, avoiding
04437             // the need for a huge intermediate bitmap
04438         }
04439     }
04440 
04441 // Setup a default matrix (we'll do everything in pixel-speak)
04442 
04443     GMATRIX GMatrix;
04444 
04445     GMatrix.AX = 1<<(16 + FX);
04446     GMatrix.AY = 0;
04447     GMatrix.BX = 0;
04448     GMatrix.BY = 1<<(16 + FX);
04449 
04450     GMatrix.CX = 0;
04451     GMatrix.CY = 0;
04452 
04453 // Create a Tempory bitmap compatible with the output device
04454 
04455     LPBITMAPINFO TempInfo;
04456     LPBYTE TempBits;
04457     INT32 DeviceDepth;
04458 
04459     if (IsPrinting())
04460     {
04461         // if printing, always convert to 24-bit (which as Gavin can't do 24- means 32-bit)
04462         // as all drivers can handle those (source bitmap only 16- or 32-bit anyway)
04463         DeviceDepth = 32;
04464     }
04465     else
04466     {
04467 PORTNOTE("other", "Assume 24 bit output device in OSRenderRegion::RenderBitmapFill")
04468 #ifndef EXCLUDE_FROM_XARALX
04469         DeviceDepth = GetDeviceCaps( RenderDC->m_hDC, BITSPIXEL ) * 
04470                                         GetDeviceCaps( RenderDC->m_hDC, PLANES );
04471 #else
04472         DeviceDepth=24; // assume true colour
04473 #endif
04474 
04475         if (DeviceDepth ==24)
04476             DeviceDepth = 32;   // GDraw cannot plot to 24-bit bitmaps
04477     }
04478 
04479     TempInfo = AllocDIB(DestWidth, DestHeight, DeviceDepth, &TempBits);
04480 
04481     if (TempInfo==NULL)
04482     {
04483         TRACEALL( _T("Out of memory during OSRenderRegion::RenderBitmapFill") );
04484         return FALSE;
04485     }
04486 
04487 // We may need to get a palette for the DIB.
04488 
04489     UINT32 DIBPal = DIB_RGB_COLORS;
04490 
04491     if (DeviceDepth <= 8)   // We only need a palette for 256 colours or less.
04492     {
04493         DIBPal = GRenderRegion::SetPaletteEntries( TempInfo, RenderDC );
04494     }
04495 
04496 // Setup GDraw with our Tempory Bitmap and Identity Matrix
04497 
04498     GD->SetupBitmap(TempInfo->bmiHeader.biWidth,
04499                     TempInfo->bmiHeader.biHeight,
04500                     TempInfo->bmiHeader.biBitCount, 
04501                     TempBits );
04502 
04503     GD->SetMatrix( &GMatrix );
04504 
04505     COLORREF DefaultColour = 0xFFFFFFFF;
04506 
04507     // --- Colour-correct and/or Contone the bitmap as necessary
04508     RGBQUAD *Palette = NULL;
04509 
04510     // Do the colour correction. This may produce a new pointer in Palette or BitmapBits,
04511     // which we should CCFree() when we are done with it - see the end of this function
04512     ColourCorrectBitmap(Fill, WxBM->BMInfo, &Palette);
04513 
04514     // Now see if we need to muck around with the palette for the contoning
04515     if (pGreyTable != NULL)
04516     {
04517         ERROR3IF(bpp != 8, "Greytable should only be here when rendering an 8bpp bitmap");
04518         RGBQUAD *OldPalette = Palette;
04519 
04520         // Create a new palette
04521         Palette = (RGBQUAD *) CCMalloc(256 * sizeof(RGBQUAD));
04522         if (Palette == NULL)
04523         {
04524             ERROR3("No memory for palette");
04525             return FALSE;
04526         }
04527         
04528         // Copy the entries from the contone palette into the new one,
04529         // using the Grey table as a guide
04530         for (INT32 i=0; i<256; i++)
04531         {
04532             Palette[i] = OldPalette[pGreyTable[i]];
04533         }
04534 
04535         if (OldPalette != WxBM->BMInfo->bmiColors)
04536             CCFree(OldPalette);         // Don't need the contone palette any more
04537     }
04538 
04539     // If we didn't create a temporary palette, then we'll use the original bitmap
04540     if (Palette == NULL)
04541         Palette = WxBM->BMInfo->bmiColors;
04542 
04543     // Search for a transparent colour setting the Style flags if necessary...
04544     if (bpp <= 8)
04545     {
04546         INT32 NumCols;
04547         switch (bpp)
04548         {
04549             case 1:
04550                 NumCols = 2;
04551                 break;
04552 
04553             case 2:
04554                 NumCols = 4;
04555                 break;
04556 
04557             case 4:
04558                 NumCols = 16;
04559                 break;
04560 
04561             case 8:
04562                 NumCols = 256;
04563                 break;
04564 
04565             default:
04566                 NumCols = 256;
04567                 break;
04568         }
04569 
04570         for (INT32 i=0; i<NumCols; i++)
04571         {
04572             if (Palette[i].rgbReserved == 0xFF)
04573             {
04574                 RGBQUAD* TempPalette = (RGBQUAD*)CCMalloc(NumCols * sizeof(RGBQUAD));
04575                 if (TempPalette)
04576                 {
04577                     // We'll use a copy of the palette ...
04578                     memcpy(TempPalette, Palette, NumCols*sizeof(RGBQUAD));
04579 
04580                     // so we can force this entry to be white
04581                     TempPalette[i].rgbRed       = 0xFF;
04582                     TempPalette[i].rgbGreen     = 0xFF;
04583                     TempPalette[i].rgbBlue      = 0xFF;
04584 
04585                     Palette = TempPalette;
04586                     break;
04587                 }
04588             }
04589         }
04590     }
04591 
04592 // Now set the bitmap fill
04593 
04594     POINT PGram[3];
04595     PGram[0].x = 0;             PGram[0].y = 0;
04596     PGram[1].x = DestWidth;     PGram[1].y = 0;
04597     PGram[2].x = 0;             PGram[2].y = DestHeight;
04598 
04599     DWORD Style = 1;
04600     BOOL bDoBitmapFill = TRUE;
04601     BYTE* pSepTables = NULL;
04602     BGR *pCyanSepTable = NULL;
04603     BGR *pMagentaSepTable = NULL;
04604     BGR *pYellowSepTable = NULL;
04605     BGR *pBlackSepTable = NULL;
04606     BYTE *pUnderColourRemovalTable = NULL;
04607     BYTE *pBlackGenerationTable = NULL;
04608     CWxBitmap* pNewBitmap = NULL;
04609     
04610 PORTNOTE("other", "No colour separation OSRenderRegion::RenderBitmapFill")
04611 #ifndef EXCLUDE_FROM_XARALX
04612     // --- Add Separation Style bits as approriate to the current colour separation mode
04613     if (bpp > 8)    // Only needed for deep bitmaps
04614     {
04615         // If we've got a valid colour plate and it is a composite preview
04616         if (CurrentColContext->GetColourPlate() != NULL &&
04617             !CurrentColContext->GetColourPlate()->IsDisabled())
04618         {
04619             if (CurrentColContext->GetColourPlate()->GetType() == COLOURPLATE_COMPOSITE)
04620             {
04621                 // Fall through (shouldn't be used at the moment)
04622             }
04623             else if (CurrentColContext->GetColourPlate()->GetType() == COLOURPLATE_SPOT)
04624             {
04625                 GD->SetColour(0xFFFFFF);
04626                 bDoBitmapFill = FALSE;
04627             }
04628             else if (CurrentColContext->GetColourPlate()->GetType() != COLOURPLATE_NONE)
04629             {
04630                 // Create a colour separated copy of the bitmap and render that instead
04631                 pSepTables = (BYTE *) CCMalloc(5 * 256 * sizeof(BYTE));
04632                 if (pSepTables != NULL)
04633                 {
04634                     XaraCMS* lpCMSMan = GetApplication()->GetCMSManager();
04635                     String_256 PrintProfile;
04636                     if (lpCMSMan)
04637                         lpCMSMan->GetPrinterProfile(&PrintProfile);
04638                     ColourContextCMYK *cc = new ColourContextCMYK(RenderView, &PrintProfile);
04639                     if (cc->GetProfileTables(pSepTables))
04640                     {
04641                         // Make a copy of the bitmap
04642                         pNewBitmap = (CWxBitmap*)WxBM->MakeSeparatedCopy(RenderView->GetColourPlate(), pSepTables);
04643                         OrigWxBM = WxBM;                    // Save original bitmap pointer
04644                         WxBM = pNewBitmap;                  // Use this bitmap instead
04645                     }
04646                     delete cc;
04647                 }
04648             }
04649         }
04650     }
04651 #endif
04652 
04653     // Set the context to the default values
04654 
04655     GD->SetDefaultBitmapParameters();
04656 
04657     GD->SetTileSmoothingFlag(TRUE/*FALSE*/);
04658     GD->SetTileFilteringFlag(TRUE/*FALSE*/);
04659 
04660     if (bDoBitmapFill)
04661     {
04662         GD->SetBitmapFill(  &(WxBM->BMInfo->bmiHeader),
04663                             WxBM->BMBytes,
04664                             Style,
04665                             PGram,
04666                             DefaultColour,
04667                             Palette,
04668                             NULL, NULL, NULL,
04669                             NULL,
04670                             0
04671                             );
04672     }
04673 
04674 // Now plot a filled rectangle
04675 
04676     RECT BmpRect;
04677     BmpRect.left    =  0;
04678     BmpRect.top     =  DestHeight;
04679     BmpRect.right   =  DestWidth;
04680     BmpRect.bottom  =  0;
04681 
04682     GD->FillRectangle(&BmpRect);
04683 
04684 
04685     if (IsPrinting())
04686     {
04687         // we are going to the printer. We had a 16- or 32-bit DIB which we have now converted
04688         // into a 32-bit one, so send it out
04689 
04690         // PlotDeepDIB ends up doing a SetDIBitsToDevice in 24-bit slices
04691         DIBUtil::PlotDeepDIB( RenderDC, TempInfo, TempBits, 
04692                             BottomLeft.x, TopLeft.y,
04693                             DestWidth,DestHeight,
04694                             0,0, 
04695                             CONVHINT_PRINTER );
04696     }
04697     else
04698     {
04699         // get the HPALETTE to pass to the plot bitmap call - crucial for quality Win32s DDB plotting
04700         wxPalette * hPal = NULL;
04701         if (RFlags.UsePalette)
04702             hPal = PaletteManager::GetPalette();
04703 
04704         // Finally call PlotBitmap, to render the DIB using the GDI.
04705         // If the screen cannot cope with the depth of the bitmap, it will be converted
04706         // for us. Isn't PlotBitmap wonderful?
04707 
04708         GRenderRegion::StaticPlotBitmap( RenderDC, 
04709                                 DIBPal, 
04710                                 TempInfo, 
04711                                 TempBits,
04712                                 BottomLeft.x, 
04713                                 TopLeft.y, 
04714                                 DestWidth, 
04715                                 DestHeight, 
04716                                 hPal,
04717                                 0,0
04718                              );
04719     }
04720 
04721     FreeDIB(TempInfo, TempBits);
04722 
04723     if (pNewBitmap)
04724     {
04725         WxBM = OrigWxBM;
04726         delete pNewBitmap;
04727     }
04728 
04729     // Free any memory used for colour-corrected bitmap palettes.
04730     // If this pointer doesn't point at the original palette, then it has
04731     // been temporarily allocated by ColourCorrectBitmap, above.
04732     if (Palette != WxBM->BMInfo->bmiColors)
04733         CCFree(Palette);
04734     
04735     if (pSepTables)
04736     {
04737         GD->SetSeparationTables();  // Defaults to setting everything to NULL
04738         CCFree(pSepTables);
04739     }
04740 
04741     if (pCyanSepTable)
04742         CCFree(pCyanSepTable);
04743     if (pMagentaSepTable)
04744         CCFree(pMagentaSepTable);
04745     if (pYellowSepTable)
04746         CCFree(pYellowSepTable);
04747     if (pBlackSepTable)
04748         CCFree(pBlackSepTable);
04749     if (pUnderColourRemovalTable)
04750         CCFree(pUnderColourRemovalTable);
04751     if (pBlackGenerationTable)
04752         CCFree(pBlackGenerationTable);
04753 
04754     return TRUE;
04755 }

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

Render a character, using the specified transform and current attributes in the render region.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/4/95
Parameters:
ch - unicode value of char [INPUTS] pMatrix - matrix specifying transforms to place char correctly in document
Returns:
FALSE if fails

Reimplemented from RenderRegion.

Definition at line 6963 of file osrndrgn.cpp.

06964 {
06965     PORTNOTETRACE("text","OSRenderRegion::RenderChar - do nothing");
06966 #ifndef EXCLUDE_FROM_XARALX
06967     // If it is stroked or not simple flat fill, or not a standard ASCII character then we 
06968     //  must do this as paths. Graham 8/8/96: And now UNICODE works too.
06969     BOOL FlatFill = IS_A(CurrentAttrs[ATTR_FILLGEOMETRY].pAttr, FlatFillAttribute);
06970 
06971     if (!FlatFill || 
06972         !RR_STROKECOLOUR().IsTransparent() || 
06973         (FlatFill & RR_FILLCOLOUR().IsTransparent()))
06974         return RenderRegion::RenderChar(ch, pMatrix);
06975 
06976     if (IsPrinting())
06977     {
06978         // Check for emulsion down printing, GDI cannot render text backwards
06979         PrintControl *pPrintCtl;
06980         View *pView = GetRenderView();
06981         if (pView && (pPrintCtl=pView->GetPrintControl())) 
06982         { 
06983             if (pPrintCtl->GetTypesetInfo()->PrintEmulsionDown())
06984             return RenderRegion::RenderChar(ch, pMatrix);
06985         }
06986     }
06987 
06988     // get overall matrix - attribute matrix concatenated with given matrix if supplied
06989     Matrix matrix;
06990     if (GetCharAttributeMatrix(&matrix)==FALSE)
06991         return NULL;
06992     if (pMatrix)
06993         matrix*=*pMatrix;
06994 
06995     // Can we do this using a GDI font?
06996     // We can if the matrix only specifies scaling and translation
06997     FIXED16 abcd[4];
06998     INT32   ef[2];
06999     matrix.GetComponents(abcd, ef);
07000 
07001     // GDI can't do y-axis flips, so we do it as shapes if this is detected (and x-axis
07002     // flips, for consistency).
07003     if ((abcd[0] < FIXED16(0)) || (abcd[3] < FIXED16(0)))
07004     {
07005         // Flipped in one or both axes - render as a path.
07006         return RenderRegion::RenderChar(ch, pMatrix);
07007     }
07008 
07009     // Work out how complex the transformation is.
07010     FIXED16 ScaleX = 0;
07011     FIXED16 ScaleY = 0;
07012     ANGLE   Rotation = 0;
07013     ANGLE   Shear = 0;
07014 
07015     if ((abcd[1] == FIXED16(0)) && (abcd[2] == FIXED16(0)) && 
07016         (abcd[0] >= FIXED16(0)) && (abcd[3] >= FIXED16(0)))
07017     {
07018         // Simple scaling transformation.
07019         ScaleX   = abcd[0];
07020         ScaleY   = abcd[3];
07021         Rotation = FIXED16(0);
07022         Shear    = FIXED16(0);
07023     }
07024     else
07025     {
07026         // Decompose the matrix to find out how complex it is.
07027         // Pass in NULL for translation as we already know it is in 'ef'.
07028         FIXED16 Aspect;
07029         BOOL Result = matrix.Decompose(&ScaleY, &Aspect, &Rotation, &Shear, NULL);
07030 
07031         if (!Result || (Shear != FIXED16(0)))
07032             // Either there was a problem, or the character is sheared, in which case
07033             // we can't do it with GDI.
07034             return RenderRegion::RenderChar(ch, pMatrix);
07035 
07036         // Set up the ScaleX based on the aspect ratio
07037         ScaleX = ScaleY * Aspect;
07038     }
07039 
07040     // Check for sideways printing - if the render matrix has rotation, then we are
07041     // printing at 270 degrees rotation, so adjust the rotation accordingly.
07042     FIXED16 RenderABCD[4];
07043     INT32   RenderEF[2];
07044     RenderMatrix.GetComponents(RenderABCD, RenderEF);
07045     if ((RenderABCD[1] != FIXED16(0)) || (RenderABCD[2] != FIXED16(0)))
07046         // Rotate by 270 degrees (angle is in radians)
07047         Rotation += FIXED16(1.5 * PI);
07048 
07049     // Work out required width and height of the font
07050     MILLIPOINT ReferenceSize = TextManager::GetDefaultHeight();
07051     MILLIPOINT Width  = ReferenceSize * ScaleX;
07052     MILLIPOINT Height = ReferenceSize * ScaleY;
07053 
07054     if (!SelectNewFont(RR_TXTFONTTYPEFACE(), RR_TXTBOLD(), RR_TXTITALIC(),
07055                        Width, Height, Rotation))
07056     {
07057         // Could not select font (maybe because device can't rotate fonts)
07058         return RenderRegion::RenderChar(ch, pMatrix);
07059     }
07060 
07061     // First, set up the text attributes that are not encoded in the font.
07062     UINT32 OldTextAlign = RenderDC->SetTextAlign(TA_BASELINE);
07063     INT32 OldBKMode = RenderDC->SetBkMode(TRANSPARENT);
07064     COLORREF OldTextColor = 
07065         RenderDC->SetTextColor(ConvertColourToScreenWord(CurrentColContext, &RR_FILLCOLOUR()));
07066 
07067     // Render the character in the specified position
07068     DocCoord DocPos(ef[0], ef[1]);
07069     WinCoord WinPos = DocCoordToWin(DocPos);
07070 
07071 
07072     // Graham 5/8/96: "ch" is presently in UNICODE or ASCII
07073     // We need to convert it over to MBCS to deal with Japanese strings
07074     //So convert ch, which is of form WCHAR, over to a MBCS UINT32 character index
07075 
07076     UINT32 uiCharNumber = UnicodeManager::UnicodeToMultiByte(ch);
07077 
07078     //Now we want to put that UINT32 value into an array of char ready to pass to
07079     //RenderDC->TextOut. We do this using UnicodeManager::DecomposeMultiBytes
07080 
07081     BYTE bCharArray[2];
07082 
07083     UnicodeManager::DecomposeMultiBytes(uiCharNumber, &bCharArray[0], &bCharArray[1]);
07084 
07085     //Now, is the character in bCharArray one or two bytes long?
07086     //If it is one byte long, the first byte in bCharArray will be zero.
07087     if (bCharArray[0]==0)
07088         //It's a standard ASCII character, one byte long
07089         //So pass that character (bCharArray[1]) to the TextOut function.
07090         //The last parameter in text out is the number of bytes - in this case 1.
07091         RenderDC->TextOut(WinPos.x, WinPos.y, (CHAR*) &bCharArray[1], 1);
07092     else
07093         //The character is two bytes long (that is, it's a foreign character)
07094         //So we pass bCharArray[0] to TextOut and tell TextOut that it should
07095         //use two bytes from that address. We do this by setting the last
07096         //parameter to 2.
07097         RenderDC->TextOut(WinPos.x, WinPos.y, (CHAR*) &bCharArray[0], 2);
07098 
07099     // Clean up text attributes
07100     RenderDC->SetTextAlign(OldTextAlign);
07101     RenderDC->SetBkMode(OldBKMode);
07102     RenderDC->SetTextColor(OldTextColor);
07103 #elif !defined(DISABLE_TEXT_RENDERING)
07104     return RenderRegion::RenderChar(ch, pMatrix);
07105 #endif
07106     return TRUE;
07107 }

BOOL OSRenderRegion::RenderConicalFill Path PathToDraw,
ConicalFillAttribute Fill
[protected]
 

Renders the path with a gradient fill.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>? Rik? Tim?
Date:
?
Parameters:
PathToDraw - A pointer to the path to be rendered. [INPUTS] Fill - A pointer to the radial fill applied.
Returns:
TRUE - Success. FALSE - An error occured.

Definition at line 5542 of file osrndrgn.cpp.

05543 {
05544     GradFillMethodType RenderMethod = GF_USE_GDICLIPPING;
05545 
05546     // First, we need to find out the minimum radius of the circle we can
05547     // plot and still fill the entire shape.
05548     // To do this we find the maxiumum distance between the start point and all four
05549     // corners of the bounding box.
05550     DocRect BoundsRect = PathToDraw->GetBoundingRect();
05551 
05552     DocCoord TestPoint = BoundsRect.lo;
05553     INT32 Radius = CalcDistance(Fill->StartPoint, TestPoint);
05554     TestPoint.x = BoundsRect.hi.x;
05555     INT32 NewRadius = CalcDistance(Fill->StartPoint, TestPoint);
05556     Radius = max(Radius, NewRadius);
05557     TestPoint = BoundsRect.hi;
05558     NewRadius = CalcDistance(Fill->StartPoint, TestPoint);
05559     Radius = max(Radius, NewRadius);
05560     TestPoint.x = BoundsRect.lo.x;
05561     NewRadius = CalcDistance(Fill->StartPoint, TestPoint);
05562     Radius = max(Radius, NewRadius);
05563 
05564     // Radius now holds the minimum radius we can use.
05565 
05566     // We want to change the rendering context, so we save it.
05567     SaveContext();
05568 
05569     // No stroking while rendering the fill.
05570     SetLineColour(COLOUR_TRANS);
05571 
05572     // Use device pixel size to work out how many steps to do.
05573     FIXED16 PixelSize = 0;
05574     GetRenderView()->GetScaledPixelSize(&PixelSize,&PixelSize);
05575     INT32 FillSteps = (INT32) ((Radius * 2 * PI) / PixelSize.MakeDouble());
05576 
05577     // Do a slice every 4 pixels (arbitrary!)
05578     FillSteps /= 4;
05579 
05580     // Also base it on distance between colours
05581     EFFECTTYPE EffectType = GetFillEffect();
05582     FillSteps = min(ColDifference(Fill->Colour, Fill->EndColour, 
05583                                   IsPrinting() ? 24 : 8,            // Colour depth
05584                                   EffectType), 
05585                                   FillSteps);
05586 
05587     // Limit fill steps to a maximum
05588     FillSteps = min( FillSteps, INT32(MAX_FILL_STEPS) );
05589 
05590     // Use global Quality setting
05591     FillSteps = FillSteps / (1 << GradFillQuality);
05592 
05593     // Note that with a conical fill we fade from the start colour to the end colour
05594     // and then back to the start colour, so we only need half as many fill steps as you
05595     // might think.
05596     FillSteps /= 2;
05597 
05598     // Limit to minimum of 10 steps
05599     FillSteps = max(FillSteps, 10);
05600 
05601     // Work out what flatness and accuracy to use for Gavin's clipping functions.
05602     // Gavin recommends 1/2 pixel for flattening, and 1/4 pixel for tolerance
05603     // (but these were kind of off the top of his head - Tim).
05604     // PS. It seems we need maximum tolerance (i.e. 0) for accurate grad-fill rendering.
05605     INT32 ClipFlatness = PixelSize.MakeLong() / 16;
05606     INT32 ClipTolerance = 0;
05607 
05608     RGBQUAD ColourSteps[MAX_FILL_STEPS];
05609     GradTable32::BuildGraduatedPalette(Fill->Colour, Fill->EndColour,
05610                                         GetRenderView(), EffectType,
05611                                         FillSteps, ColourSteps);
05612 
05613 
05614     // If we are rendering into a metafile, clip the path ourselves
05615     if (RFlags.Metafile)
05616     {
05617         RenderMethod = GF_USE_GAVINCLIPPING;
05618     }
05619     else
05620     {
05621         if (!SetClipToPathTemporary(PathToDraw))
05622         {
05623             // Can't use clipping - fall back to EOR.
05624             RenderMethod = GF_USE_GDIEOR;
05625         }
05626     }
05627 
05628     INT32 RenderCount = 1;
05629 
05630     if (RenderMethod == GF_USE_GDIEOR)
05631     {
05632         SetDrawingMode(DM_EORDITHER);
05633         RenderCount = 2;
05634     }
05635 
05636     DocColour TempFillColour;
05637 
05638     while (RenderCount > 0)
05639     {
05640         COLORREF CurrentCol = RGB(ColourSteps[FillSteps - 1].rgbRed, 
05641                                     ColourSteps[FillSteps - 1].rgbGreen, 
05642                                     ColourSteps[FillSteps - 1].rgbBlue);
05643 
05644         // Put the RGB value back into a DocColour so we can set it as the fill colour. We set it
05645         // as non-separable, as it will have already been colour-separated by BuildGraduatedPalette
05646         TempFillColour.SetRGBValue(ColourSteps[FillSteps - 1].rgbRed, 
05647                                     ColourSteps[FillSteps - 1].rgbGreen, 
05648                                     ColourSteps[FillSteps - 1].rgbBlue);
05649         TempFillColour.SetSeparable(FALSE);
05650 
05651         SetFillColour(TempFillColour);
05652         GetValidBrush();
05653         GetValidPen();
05654 
05655         // This is the path we will use to create conical fills.
05656         Path ConicalFill;
05657         ConicalFill.Initialise(12,12);
05658 
05659         // This is the path we use for all clipped rendering.
05660         Path ClippedPath;
05661         ClippedPath.Initialise(12, 12);
05662 
05663         double FillAngle = atan2((double)(Fill->EndPoint.x - Fill->StartPoint.x),
05664                                  (double)(Fill->EndPoint.y - Fill->StartPoint.y));
05665 
05666         double AngleInc = PI / FillSteps; // Actually (2 * PI) / (2 * FillSteps)
05667 
05668         TestPoint.x = Fill->StartPoint.x + (INT32) (((double) Radius) * sin(FillAngle));
05669         TestPoint.y = Fill->StartPoint.y + (INT32) (((double) Radius) * cos(FillAngle));
05670 
05671         // Now render the fill using radiating triangles.
05672         INT32 FillInc = -1;
05673 
05674         // NB. This loop is unusual because we loop from FillSteps down to 0 and back 
05675         // up to FillSteps - because that's how conical fills work.
05676         for (INT32 i = FillSteps - 1; i <= FillSteps; i += FillInc)
05677         {
05678             ConicalFill.ClearPath();
05679             ConicalFill.FindStartOfPath();
05680 
05681             // Create a triangle
05682             PathFlags NewFlags;
05683             NewFlags.IsRotate = TRUE;
05684             ConicalFill.InsertMoveTo(Fill->StartPoint, &NewFlags);
05685             ConicalFill.InsertLineTo(TestPoint, &NewFlags);
05686             FillAngle += AngleInc;
05687             TestPoint.x = Fill->StartPoint.x + (INT32) (((double) Radius) * sin(FillAngle));
05688             TestPoint.y = Fill->StartPoint.y + (INT32) (((double) Radius) * cos(FillAngle));
05689             ConicalFill.InsertLineTo(TestPoint, &NewFlags);
05690 
05691             // Close the path properly
05692             ConicalFill.CloseSubPath();
05693 
05694             ConicalFill.IsFilled = TRUE;
05695 
05696             if (RenderMethod != GF_USE_GAVINCLIPPING)
05697             {
05698                 RenderPath(&ConicalFill);
05699             }
05700             else
05701             {
05702                 PathToDraw->ClipPathToPath(ConicalFill, &ClippedPath, 2,
05703                                            ClipTolerance, ClipFlatness, ClipFlatness);
05704                 ClippedPath.IsFilled = TRUE;
05705                 RenderPath(&ClippedPath);
05706             }
05707 
05708             // decrement loop counter here so that the next colour can be calculated
05709 
05710             if (i <= 0)
05711                 // We need to start going the other way!
05712                 FillInc = 1;
05713 
05714             // Calculate next brush
05715             if (i != FillSteps)
05716             {
05717                 const COLORREF NewFill = RGB(ColourSteps[i].rgbRed,
05718                                                 ColourSteps[i].rgbGreen,
05719                                                 ColourSteps[i].rgbBlue);
05720                 if (NewFill != CurrentCol)
05721                 {
05722                     // colour changed, make new brush
05723                     CurrentCol = NewFill;
05724 
05725                     // Put the RGB value back into a DocColour so we can set it as the fill colour. We set it
05726                     // as non-separable, as it will have already been colour-separated by BuildGraduatedPalette
05727                     TempFillColour.SetRGBValue(ColourSteps[i].rgbRed, 
05728                                                 ColourSteps[i].rgbGreen, 
05729                                                 ColourSteps[i].rgbBlue);
05730                     TempFillColour.SetSeparable(FALSE);
05731 
05732                     SetFillColour(TempFillColour);
05733                     GetValidBrush();
05734                     GetValidPen();
05735                 }
05736             }
05737         }
05738 
05739         if ((RenderMethod == GF_USE_GDIEOR) && (RenderCount > 1))
05740         {
05741             // Render the path in white
05742             SetDrawingMode(DM_COPYPEN);
05743             SetFillColour(COLOUR_BLACK);
05744             SetLineColour(COLOUR_TRANS);
05745             GetValidBrush();
05746             GetValidPen();
05747             RenderPath(PathToDraw);
05748 
05749             // Set back to mode required for grad fill rendering
05750             SetDrawingMode(DM_EORDITHER);
05751         }
05752 
05753         RenderCount--;
05754     }
05755 
05756     // now tidy up
05757     RestoreContext();
05758     GetValidBrush();
05759     GetValidPen();
05760 
05761     // Lose the clipping region if we are using one.
05762     if (RenderMethod == GF_USE_GDICLIPPING)
05763         RenderDC->SetClippingRegion(*OSClipRegion);
05764 
05765     return TRUE;
05766 }

BOOL OSRenderRegion::RenderFourColFill Path PathToDraw,
FourColFillAttribute Fill
[protected]
 

Renders a four colour gradient fill to a Windows DC. This is done by breaking the fill up into a large number of tiles, and then applying these with the colour at that point of the fill. This is in common with the other fills, and much of the code in this function has been derived from the other fill rendering functions.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
7/6/00
Parameters:
PathToDraw - A pointer to the path to be rendered. [INPUTS] Fill - A pointer to the radial fill applied.
Returns:
TRUE - Success. FALSE - An error occured.

Definition at line 6079 of file osrndrgn.cpp.

06081 {
06082     // Create a linear fill attribute.
06083     LinearFillAttribute LinearFill;
06084 
06085     // Set it up.
06086     LinearFill.SetStartPoint    ( Fill->GetStartPoint () );
06087     LinearFill.SetEndPoint      ( Fill->GetEndPoint3 () );
06088     LinearFill.SetStartColour   ( Fill->GetStartColour () );
06089     LinearFill.SetEndColour     ( Fill->GetEndColour3 () );
06090 
06091     // Export the fill as a two colour linear fill.
06092     RenderLinearFill ( PathToDraw, &LinearFill );
06093 
06094     // Graeme (11-6-00) - Mark has asked me to drop everything, and concentrate on getting a
06095     // Photoshop file format export / import filter going. As a consequence, I'm expected to
06096     // drop everything, and follow his commands, and so I've replacing this partially
06097     // complete four colour fill function with a call to the linear fill rendering function.
06098     // Normally I'd remove a piece of commented out code, but in this case I'm leaving it in
06099     // so that either I can get back to it later, or someone else can fix it.
06100     //
06101     // At the present time, all the function needs is some way of extending the fill pattern
06102     // out to the edges of the space being filled. There might be some way of spoofing this
06103     // using a linear gradient fill, and some kind of clipping region, or just rolling your
06104     // own code, and putting it in here.
06105 /*
06106     DocCoord            HeightVector    = Fill->EndPoint  - Fill->StartPoint;
06107     DocCoord            WidthVector     = Fill->EndPoint2 - Fill->StartPoint;
06108     INT32                   FillHeight      = CalcDistance ( Fill->StartPoint, Fill->EndPoint );
06109     INT32                   FillWidth       = CalcDistance ( Fill->StartPoint, Fill->EndPoint2 );
06110     INT32                   HeightSteps     = 0;
06111     INT32                   WidthSteps      = 0;
06112     INT32                   HeightColDiff   = 0;
06113     INT32                   WidthColDiff    = 0;
06114     FIXED16             PixelSize       = 0;
06115     GradFillMethodType  RenderMethod    = GF_USE_GDICLIPPING;
06116     EFFECTTYPE          EffectType      = GetFillEffect();
06117     INT32               ClipFlatness    = 0;
06118     INT32               ClipTolerance   = 0;
06119     INT32                   RenderCount     = 1;
06120     RGBQUAD             StartColours    [MAX_FILL_STEPS];
06121     RGBQUAD             EndColours      [MAX_FILL_STEPS];
06122     DocCoord            RowOffsets      [MAX_FILL_STEPS + 1];
06123     DocCoord            ColumnOffsets   [MAX_FILL_STEPS + 1];
06124 
06125     // We want to change the rendering context, so we save it.
06126     SaveContext ();
06127 
06128     // No stroking while rendering the fill.
06129     SetLineColour ( COLOUR_TRANS );
06130 
06131     // Use device pixel size to work out how many steps to do.
06132     GetRenderView ()->GetScaledPixelSize ( &PixelSize, &PixelSize );
06133 
06134     // Calculate the number of steps to be made for the fill in each direction, making a
06135     // slice every four pixels.
06136     HeightSteps     = FillHeight / ( PixelSize.MakeLong () * 4);
06137     WidthSteps      = FillWidth  / ( PixelSize.MakeLong () * 4);
06138 
06139     // Calculate the distance between colours.
06140     HeightColDiff   = min ( ColDifference ( Fill->Colour, Fill->EndColour,
06141                                             IsPrinting () ? 24 : 8, EffectType ), 
06142                             ColDifference ( Fill->EndColour2, Fill->EndColour3,
06143                                             IsPrinting () ? 24 : 8, EffectType ) );
06144 
06145     WidthColDiff    = min ( ColDifference ( Fill->Colour, Fill->EndColour2,
06146                                             IsPrinting () ? 24 : 8, EffectType ), 
06147                             ColDifference ( Fill->EndColour, Fill->EndColour3,
06148                                             IsPrinting () ? 24 : 8, EffectType ) );
06149 
06150     // Use the number of discrete steps between colours, and the number of slices to
06151     // determine just how many colours are needed.
06152     HeightSteps     = min ( HeightSteps, HeightColDiff );
06153     WidthSteps      = min ( WidthSteps,  WidthColDiff  );
06154 
06155     // Limit fill steps to a maximum value.
06156     HeightSteps     = min ( HeightSteps, MAX_FILL_STEPS );
06157     WidthSteps      = min ( WidthSteps,  MAX_FILL_STEPS );
06158 
06159     // Use global Quality setting.
06160     HeightSteps     = max ( HeightSteps / (1 << GradFillQuality), 10 );
06161     WidthSteps      = max ( WidthSteps  / (1 << GradFillQuality), 10 );
06162 
06163     // Work out what flatness and accuracy to use for Gavin's clipping functions.
06164     // Gavin recommends 1/2 pixel for flattening, and 1/4 pixel for tolerance.
06165     // (But these were kind of off the top of his head - Tim).
06166     // PS. It seems we need maximum tolerance (i.e. 0) for accurate grad-fill rendering.
06167     ClipFlatness = PixelSize.MakeLong () / 16;
06168 
06169     // Build the gradient table. In the other gradient fills, they call the
06170     // GradTable32::BuildGraduatedPalette () function. Unfortunately I need to operate
06171     // in two dimensions...
06172 
06173     // The first thing to do is to get a pair of gradient tables to act as the start and
06174     // end colours for each row of the fill.
06175     GradTable32::BuildGraduatedPalette ( Fill->Colour,
06176                                          Fill->EndColour,
06177                                          GetRenderView (),
06178                                          EffectType,
06179                                          HeightSteps,
06180                                          StartColours );
06181 
06182     GradTable32::BuildGraduatedPalette ( Fill->EndColour2,
06183                                          Fill->EndColour3,
06184                                          GetRenderView (),
06185                                          EffectType,
06186                                          HeightSteps,
06187                                          EndColours );
06188 
06189     // If we are rendering into a metafile, clip the path ourselves.
06190     if ( RFlags.Metafile )
06191     {
06192         RenderMethod = GF_USE_GAVINCLIPPING;
06193     }
06194     else
06195     {
06196         if ( !SetClipToPathTemporary ( PathToDraw ) )
06197         {
06198             // Can't use clipping - fall back to EOR.
06199             RenderMethod = GF_USE_GDIEOR;
06200         }
06201     }
06202 
06203     // Set the drawing mode up.
06204     if ( RenderMethod == GF_USE_GDIEOR )
06205     {
06206         SetDrawingMode ( DM_EORDITHER );
06207         RenderCount = 2;
06208     }
06209 
06210     // Pre-calculate the vectors between the various rows of tiles.
06211     for ( INT32 i = 0; i <= HeightSteps; i++ )
06212     {
06213         DocCoord Temp ( ( HeightVector.x * i ) / HeightSteps,
06214                         ( HeightVector.y * i ) / HeightSteps);
06215 
06216         RowOffsets [i] = Temp + Fill->StartPoint;
06217     }
06218 
06219     // And between the various columns of tiles.
06220     for ( INT32 j = 0; j <= WidthSteps; j++ )
06221     {
06222         ColumnOffsets [j] = DocCoord ( ( WidthVector.x * j ) / HeightSteps,
06223                                        ( WidthVector.y * j ) / HeightSteps );
06224     }
06225 
06226     // Create the fill pattern.
06227     while ( RenderCount > 0 )
06228     {
06229         // Loop through the colour table, and create the necessary tiles to emulate the fill.
06230         for ( INT32 y = 0; y < HeightSteps; y++ )
06231         {
06232             RGBQUAD     RowColours  [MAX_FILL_STEPS];
06233             DocColour   FirstColour;
06234             DocColour   LastColour;
06235             DocCoord    TileHeight  = RowOffsets [y+1] - RowOffsets [y];
06236 
06237             // Initialise the start and end colours with values from the RGB quad. I need to
06238             // do this because the BuildGraduatePalette method only takes DocColors, and only
06239             // returns RGBQuads.
06240             FirstColour.SetRGBValue ( StartColours [y].rgbRed,
06241                                       StartColours [y].rgbGreen,
06242                                       StartColours [y].rgbBlue );
06243 
06244             LastColour.SetRGBValue  ( EndColours [y].rgbRed,
06245                                       EndColours [y].rgbGreen,
06246                                       EndColours [y].rgbBlue );
06247 
06248             // Create a new palette for this row of the fill.
06249             GradTable32::BuildGraduatedPalette ( FirstColour,
06250                                                  LastColour,
06251                                                  GetRenderView (),
06252                                                  EffectType,
06253                                                  WidthSteps,
06254                                                  RowColours );
06255 
06256             // Now write out the row.
06257             for ( INT32 x = 0; x < WidthSteps; x++ )
06258             {
06259                 // Create the path for the tile to be rendered.
06260                 Path        TilePath;
06261                 PathFlags   TileFlags;
06262                 DocColour   FillColour;
06263 
06264                 // Initialise the path.
06265                 TilePath.Initialise ( 12, 12 );
06266 
06267                 // Set up the path.
06268                 TilePath.InsertMoveTo ( RowOffsets [y]   + ColumnOffsets [x],   &TileFlags );
06269                 TilePath.InsertLineTo ( RowOffsets [y+1] + ColumnOffsets [x],   &TileFlags );
06270                 TilePath.InsertLineTo ( RowOffsets [y+1] + ColumnOffsets [x+1], &TileFlags );
06271                 TilePath.InsertLineTo ( RowOffsets [y]   + ColumnOffsets [x+1], &TileFlags );
06272 
06273                 // Mark the path as closed and filled.
06274                 TilePath.CloseSubPath ();
06275                 TilePath.IsFilled = TRUE;
06276 
06277                 // Set up the fill colour.
06278                 FillColour.SetRGBValue ( RowColours [x].rgbRed,
06279                                          RowColours [x].rgbGreen,
06280                                          RowColours [x].rgbBlue );
06281 
06282                 FillColour.SetSeparable ( FALSE );
06283 
06284                 // Set it as the rendering colour.
06285                 SetFillColour   ( FillColour );
06286                 GetValidBrush   ();
06287                 GetValidPen     ();
06288 
06289                 // And write it out.
06290                 if ( RenderMethod != GF_USE_GAVINCLIPPING )
06291                 {
06292                     RenderPath ( &TilePath );
06293                 }
06294                 else
06295                 {
06296                     // Create a new path.
06297                     Path        ClippedPath;
06298 
06299                     // Initialise the path.
06300                     ClippedPath.Initialise ( 12, 12 );
06301 
06302                     // Clip the tile path to the drawing path to ensure that it fits into the
06303                     // shape being rendered.
06304                     PathToDraw->ClipPathToPath ( TilePath, &ClippedPath, 2, ClipTolerance,
06305                                                  ClipFlatness, ClipFlatness);
06306 
06307                     // Set the IsFilled flag.
06308                     ClippedPath.IsFilled = TRUE;
06309 
06310                     // And render the path.
06311                     RenderPath ( &ClippedPath );
06312                 }
06313             }
06314         }
06315 
06316         // This comes at the end of the rendering loop.
06317         if ( ( RenderMethod == GF_USE_GDIEOR ) && ( RenderCount > 1 ) )
06318         {
06319             // Render the path in white
06320             SetDrawingMode  ( DM_COPYPEN );
06321             SetFillColour   ( COLOUR_BLACK );
06322             SetLineColour   ( COLOUR_TRANS );
06323             GetValidBrush   ();
06324             GetValidPen     ();
06325             RenderPath      ( PathToDraw );
06326 
06327             // Set back to mode required for grad fill rendering
06328             SetDrawingMode  ( DM_EORDITHER );
06329         }
06330 
06331         RenderCount--;
06332     }
06333 
06334     // Restore the original rendering state.
06335     RestoreContext  ();
06336     GetValidBrush   ();
06337     GetValidPen     ();
06338 
06339     // Lose the clipping region if we are using one.
06340     if ( RenderMethod == GF_USE_GDICLIPPING )
06341         RenderDC->SelectClipRgn ( OSClipRegion );
06342 */
06343     // Success.
06344     return TRUE;
06345 }

BOOL OSRenderRegion::RenderGradFillPath Path PathToDraw,
GradFillAttribute Fill
 

Render grad fills to GDI devices using whatever means available. Scope: Public.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/4/94
Parameters:
A path to render and a fill attribute. [INPUTS]
- [OUTPUTS]
Returns:
Errors: -

TRUE if worked, FALSE if failed.

Definition at line 4810 of file osrndrgn.cpp.

04811 {
04812     CCRuntimeClass *FillType = Fill->GetRuntimeClass();
04813 
04814     if (FillType == CC_RUNTIME_CLASS(RadialFillAttribute))
04815         return RenderRadialFill(PathToDraw, (RadialFillAttribute *) Fill);
04816     else if (FillType == CC_RUNTIME_CLASS(LinearFillAttribute))
04817         return RenderLinearFill(PathToDraw, (LinearFillAttribute *) Fill); 
04818     else if (FillType == CC_RUNTIME_CLASS(ConicalFillAttribute))
04819         return RenderConicalFill(PathToDraw, (ConicalFillAttribute *) Fill); 
04820     else if (FillType == CC_RUNTIME_CLASS(SquareFillAttribute))
04821         return RenderSquareFill(PathToDraw, (SquareFillAttribute *) Fill); 
04822     else if (FillType == CC_RUNTIME_CLASS(FourColFillAttribute))
04823         return RenderFourColFill(PathToDraw, (FourColFillAttribute *) Fill); 
04824     else
04825         return FALSE;
04826 }

BOOL OSRenderRegion::RenderLinearFill Path PathToDraw,
LinearFillAttribute Fill
[protected]
 

Renders the path with a gradient fill.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>? Rik? Tim?
Date:
?
Parameters:
PathToDraw - A pointer to the path to be rendered. [INPUTS] Fill - A pointer to the radial fill applied.
Returns:
TRUE - Success. FALSE - An error occured.

Definition at line 5183 of file osrndrgn.cpp.

05184 {
05185     GradFillMethodType RenderMethod = GF_USE_GDICLIPPING;
05186 
05187     // First, we need to find out the minimum width of rectangles we can
05188     // plot and still fill the entire shape.
05189     // To do this we find the maxiumum distance between the start point and all four
05190     // corners of the bounding box.
05191     // NB. This actually gives us *half* the minimum width we need.
05192     DocRect BoundsRect = PathToDraw->GetBoundingRect();
05193 
05194     DocCoord TestPoint = BoundsRect.lo;
05195     INT32 Distance = CalcDistance(Fill->StartPoint, TestPoint);
05196     TestPoint.x = BoundsRect.hi.x;
05197     INT32 NewDistance = CalcDistance(Fill->StartPoint, TestPoint);
05198     Distance = max(Distance, NewDistance);
05199     TestPoint = BoundsRect.hi;
05200     NewDistance = CalcDistance(Fill->StartPoint, TestPoint);
05201     Distance = max(Distance, NewDistance);
05202     TestPoint.x = BoundsRect.lo.x;
05203     NewDistance = CalcDistance(Fill->StartPoint, TestPoint);
05204     Distance = max(Distance, NewDistance);
05205 
05206     // Distance now holds the minimum distance either side of the line that we should
05207     // render.
05208 
05209     // We want to change the rendering context, so we save it.
05210     SaveContext();
05211 
05212     // No stroking while rendering the fill.
05213     SetLineColour(COLOUR_TRANS);
05214 
05215     // Use device pixel size to work out how many steps to do.
05216     FIXED16 PixelSize = 0;
05217     GetRenderView()->GetScaledPixelSize(&PixelSize,&PixelSize);
05218 
05219     // Work out how long the fill arrow is in millipoints.
05220     INT32 FillLength = CalcDistance(Fill->StartPoint, Fill->EndPoint);
05221 
05222     // Do a slice every 4 pixels (arbitrary!)
05223     INT32 FillSteps = (INT32) ((FillLength / PixelSize.MakeDouble()) / 4);
05224 
05225     // Also base it on distance between colours
05226     EFFECTTYPE EffectType = GetFillEffect();
05227     FillSteps = min(ColDifference(Fill->Colour, Fill->EndColour,
05228                                   IsPrinting() ? 24 : 8,                // Colour depth
05229                                   EffectType), 
05230                                   FillSteps);
05231 
05232     // Limit fill steps to a maximum
05233     FillSteps = min( FillSteps, INT32(MAX_FILL_STEPS) );
05234 
05235     // Use global Quality setting
05236     FillSteps = FillSteps / (1 << GradFillQuality);
05237 
05238     FillSteps = max(FillSteps, 10);
05239 
05240     // Work out what flatness and accuracy to use for Gavin's clipping functions.
05241     // Gavin recommends 1/2 pixel for flattening, and 1/4 pixel for tolerance
05242     // (but these were kind of off the top of his head - Tim).
05243     // PS. It seems we need maximum tolerance (i.e. 0) for accurate grad-fill rendering.
05244     INT32 ClipFlatness = PixelSize.MakeLong() / 16;
05245     INT32 ClipTolerance = 0;
05246 
05247     RGBQUAD ColourSteps[MAX_FILL_STEPS];
05248     GradTable32::BuildGraduatedPalette(Fill->Colour, Fill->EndColour,
05249                                         GetRenderView(), EffectType,
05250                                         FillSteps, ColourSteps);
05251     INT32 RenderCount = 1;
05252 
05253     // If we are rendering into a metafile, clip the path ourselves
05254     if (RFlags.Metafile)
05255     {
05256         RenderMethod = GF_USE_GAVINCLIPPING;
05257     }
05258     else
05259     {
05260         if (!SetClipToPathTemporary(PathToDraw))
05261         {
05262             // Can't use clipping - fall back to EOR.
05263             RenderMethod = GF_USE_GDIEOR;
05264             SetDrawingMode(DM_EORDITHER);
05265             RenderCount = 2;
05266         }
05267     }
05268 
05269     DocColour TempFillColour;
05270 
05271     while (RenderCount > 0)
05272     {
05273         COLORREF CurrentCol = RGB(ColourSteps[0].rgbRed, ColourSteps[0].rgbGreen, ColourSteps[0].rgbBlue);
05274 
05275         // Put the RGB value back into a DocColour so we can set it as the fill colour. We set it
05276         // as non-separable, as it will have already been colour-separated by BuildGraduatedPalette
05277         TempFillColour.SetRGBValue(ColourSteps[0].rgbRed, 
05278                                     ColourSteps[0].rgbGreen, 
05279                                     ColourSteps[0].rgbBlue);
05280         TempFillColour.SetSeparable(FALSE);
05281 
05282         SetFillColour(TempFillColour);
05283         GetValidBrush();
05284         GetValidPen();
05285 
05286         // This is the path we will use to create linear fills.
05287         Path LinearFill;
05288         LinearFill.Initialise(12,12);
05289 
05290         // This is the path we use for all clipped rendering.
05291         Path ClippedPath;
05292         ClippedPath.Initialise(12, 12);
05293 
05294         // Work out differences in x and y coords for fill arrow.
05295         double FillStepX = ((double) (Fill->EndPoint.x - Fill->StartPoint.x)) / (double) FillSteps;
05296         double FillStepY = ((double) (Fill->EndPoint.y - Fill->StartPoint.y)) / (double) FillSteps;
05297 
05298         double FillAngle = atan2((double)(Fill->EndPoint.x - Fill->StartPoint.x),
05299                                  (double)(Fill->EndPoint.y - Fill->StartPoint.y));
05300 
05301         // Used to find perpendicular angles.
05302         const double HalfPI = PI/2.0;
05303 
05304         DocCoord FillPoint = Fill->StartPoint;
05305         DocCoord RectPoint[2];
05306 
05307         // Find first two corners of rectangle
05308         RectPoint[0].x = FillPoint.x + (INT32) (((double) Distance) * sin(FillAngle - HalfPI));
05309         RectPoint[0].y = FillPoint.y + (INT32) (((double) Distance) * cos(FillAngle - HalfPI));
05310         RectPoint[1].x = FillPoint.x + (INT32) (((double) Distance) * sin(FillAngle + HalfPI));
05311         RectPoint[1].y = FillPoint.y + (INT32) (((double) Distance) * cos(FillAngle + HalfPI));
05312 
05313 
05314 
05315         // Do the start colour shape - we need to find out how far we need 
05316         // to extend beyond the fill arrow.
05317         TestPoint = BoundsRect.lo;
05318         INT32 LastDistance = CalcDistance(Fill->EndPoint, TestPoint);
05319         TestPoint.x = BoundsRect.hi.x;
05320         NewDistance = CalcDistance(Fill->EndPoint, TestPoint);
05321         LastDistance = max(LastDistance, NewDistance);
05322         TestPoint = BoundsRect.hi;
05323         NewDistance = CalcDistance(Fill->EndPoint, TestPoint);
05324         LastDistance = max(LastDistance, NewDistance);
05325         TestPoint.x = BoundsRect.lo.x;
05326         NewDistance = CalcDistance(Fill->EndPoint, TestPoint);
05327         LastDistance = max(LastDistance, NewDistance);
05328 
05329         // Make the last (big) rectangle.   
05330         LinearFill.ClearPath();
05331         LinearFill.FindStartOfPath();
05332 
05333         // Create a rectangle
05334         PathFlags NewFlags;
05335         NewFlags.IsRotate = TRUE;
05336 
05337         // Insert first two corners of rectangle.
05338         LinearFill.InsertMoveTo(RectPoint[0], &NewFlags);
05339         LinearFill.InsertLineTo(RectPoint[1], &NewFlags);
05340 
05341         // Move past the fill arrow far enough to cover last bit of shape.
05342         FillPoint.x = Fill->EndPoint.x - (MILLIPOINT) (LastDistance * sin(FillAngle));
05343         FillPoint.y = Fill->EndPoint.y - (MILLIPOINT) (LastDistance * cos(FillAngle));
05344 
05345         // Find other two corners of rectangle.
05346         DocCoord EndPoint[2];
05347         EndPoint[0].x = FillPoint.x + (INT32) (((double) Distance) * sin(FillAngle - HalfPI));
05348         EndPoint[0].y = FillPoint.y + (INT32) (((double) Distance) * cos(FillAngle - HalfPI));
05349         EndPoint[1].x = FillPoint.x + (INT32) (((double) Distance) * sin(FillAngle + HalfPI));
05350         EndPoint[1].y = FillPoint.y + (INT32) (((double) Distance) * cos(FillAngle + HalfPI));
05351 
05352         // Insert last two corners of rectangle.
05353         LinearFill.InsertLineTo(EndPoint[1], &NewFlags);
05354         LinearFill.InsertLineTo(EndPoint[0], &NewFlags);
05355 
05356         // Close the path properly
05357         LinearFill.CloseSubPath();
05358 
05359         LinearFill.IsFilled = TRUE;
05360         if (RenderMethod != GF_USE_GAVINCLIPPING)
05361         {
05362             RenderPath(&LinearFill);
05363         }
05364         else
05365         {
05366             PathToDraw->ClipPathToPath(LinearFill, &ClippedPath, 2,
05367                                        ClipTolerance, ClipFlatness, ClipFlatness);
05368             ClippedPath.IsFilled = TRUE;
05369             RenderPath(&ClippedPath);
05370         }
05371 
05372 
05373         // Now render the fill using rectangles.
05374         for (INT32 i = 0; i < FillSteps;)
05375         {
05376             LinearFill.ClearPath();
05377             LinearFill.FindStartOfPath();
05378 
05379             // Create a rectangle
05380             PathFlags NewFlags;
05381             NewFlags.IsRotate = TRUE;
05382 
05383             // Insert first two corners of rectangle.
05384             LinearFill.InsertMoveTo(RectPoint[0], &NewFlags);
05385             LinearFill.InsertLineTo(RectPoint[1], &NewFlags);
05386 
05387             // increment loop counter here so that the next colour can be calculated
05388             i++;
05389 
05390             // Move along the arrow one step
05391             FillPoint.x = Fill->StartPoint.x + (MILLIPOINT) (i * FillStepX);
05392             FillPoint.y = Fill->StartPoint.y + (MILLIPOINT) (i * FillStepY);
05393 
05394             // Find other two corners of rectangle.
05395             RectPoint[0].x = FillPoint.x + (INT32) (((double) Distance) * sin(FillAngle - HalfPI));
05396             RectPoint[0].y = FillPoint.y + (INT32) (((double) Distance) * cos(FillAngle - HalfPI));
05397             RectPoint[1].x = FillPoint.x + (INT32) (((double) Distance) * sin(FillAngle + HalfPI));
05398             RectPoint[1].y = FillPoint.y + (INT32) (((double) Distance) * cos(FillAngle + HalfPI));
05399 
05400             // Insert last two corners of rectangle.
05401             LinearFill.InsertLineTo(RectPoint[1], &NewFlags);
05402             LinearFill.InsertLineTo(RectPoint[0], &NewFlags);
05403 
05404             // Close the path properly
05405             LinearFill.CloseSubPath();
05406 
05407             LinearFill.IsFilled = TRUE;
05408             if (RenderMethod != GF_USE_GAVINCLIPPING)
05409             {
05410                 RenderPath(&LinearFill);
05411             }
05412             else
05413             {
05414                 PathToDraw->ClipPathToPath(LinearFill, &ClippedPath, 2,
05415                                            ClipTolerance, ClipFlatness, ClipFlatness);
05416                 ClippedPath.IsFilled = TRUE;
05417                 RenderPath(&ClippedPath);
05418             }
05419 
05420             if (i != FillSteps)
05421             {
05422                 // Calculate next brush
05423                 const COLORREF NewFill = RGB(ColourSteps[i].rgbRed, ColourSteps[i].rgbGreen,
05424                                                 ColourSteps[i].rgbBlue);
05425                 if (NewFill != CurrentCol)
05426                 {
05427                     // colour changed, make new brush
05428                     CurrentCol = NewFill;
05429 
05430                     // Put the RGB value back into a DocColour so we can set it as the fill colour. We set it
05431                     // as non-separable, as it will have already been colour-separated by BuildGraduatedPalette
05432                     TempFillColour.SetRGBValue(ColourSteps[i].rgbRed, 
05433                                                 ColourSteps[i].rgbGreen, 
05434                                                 ColourSteps[i].rgbBlue);
05435                     TempFillColour.SetSeparable(FALSE);
05436 
05437                     SetFillColour(TempFillColour);
05438                     GetValidBrush();
05439                     GetValidPen();
05440                 }
05441             }
05442         }
05443 
05444         // Do the end colour shape - we need to find out how far we need 
05445         // to extend beyond the fill arrow.
05446         TestPoint = BoundsRect.lo;
05447         LastDistance = CalcDistance(Fill->EndPoint, TestPoint);
05448         TestPoint.x = BoundsRect.hi.x;
05449         NewDistance = CalcDistance(Fill->EndPoint, TestPoint);
05450         LastDistance = max(LastDistance, NewDistance);
05451         TestPoint = BoundsRect.hi;
05452         NewDistance = CalcDistance(Fill->EndPoint, TestPoint);
05453         LastDistance = max(LastDistance, NewDistance);
05454         TestPoint.x = BoundsRect.lo.x;
05455         NewDistance = CalcDistance(Fill->EndPoint, TestPoint);
05456         LastDistance = max(LastDistance, NewDistance);
05457 
05458         // Make the last (big) rectangle.   
05459         LinearFill.ClearPath();
05460         LinearFill.FindStartOfPath();
05461 
05462         // Create a rectangle
05463         NewFlags.IsRotate = TRUE;
05464 
05465         // Insert first two corners of rectangle.
05466         LinearFill.InsertMoveTo(RectPoint[0], &NewFlags);
05467         LinearFill.InsertLineTo(RectPoint[1], &NewFlags);
05468 
05469         // Move past the fill arrow far enough to cover last bit of shape.
05470         FillPoint.x = Fill->EndPoint.x + (MILLIPOINT) (LastDistance * sin(FillAngle));
05471         FillPoint.y = Fill->EndPoint.y + (MILLIPOINT) (LastDistance * cos(FillAngle));
05472 
05473         // Find other two corners of rectangle.
05474         RectPoint[0].x = FillPoint.x + (INT32) (((double) Distance) * sin(FillAngle - HalfPI));
05475         RectPoint[0].y = FillPoint.y + (INT32) (((double) Distance) * cos(FillAngle - HalfPI));
05476         RectPoint[1].x = FillPoint.x + (INT32) (((double) Distance) * sin(FillAngle + HalfPI));
05477         RectPoint[1].y = FillPoint.y + (INT32) (((double) Distance) * cos(FillAngle + HalfPI));
05478 
05479         // Insert last two corners of rectangle.
05480         LinearFill.InsertLineTo(RectPoint[1], &NewFlags);
05481         LinearFill.InsertLineTo(RectPoint[0], &NewFlags);
05482 
05483         // Close the path properly
05484         LinearFill.CloseSubPath();
05485 
05486         LinearFill.IsFilled = TRUE;
05487         if (RenderMethod != GF_USE_GAVINCLIPPING)
05488         {
05489             RenderPath(&LinearFill);
05490         }
05491         else
05492         {
05493             PathToDraw->ClipPathToPath(LinearFill, &ClippedPath, 2,
05494                                        ClipTolerance, ClipFlatness, ClipFlatness);
05495             ClippedPath.IsFilled = TRUE;
05496             RenderPath(&ClippedPath);
05497         }
05498 
05499         if ((RenderMethod == GF_USE_GDIEOR) && (RenderCount > 1))
05500         {
05501             // Render the path in white
05502             SetDrawingMode(DM_COPYPEN);
05503             SetFillColour(COLOUR_BLACK);
05504             SetLineColour(COLOUR_TRANS);
05505             GetValidBrush();
05506             GetValidPen();
05507             RenderPath(PathToDraw);
05508 
05509             // Set back to mode required for grad fill rendering
05510             SetDrawingMode(DM_EORDITHER);
05511         }
05512 
05513         RenderCount--;
05514     }
05515 
05516     // now tidy up
05517     RestoreContext();
05518     GetValidBrush();
05519     GetValidPen();
05520 
05521     // Lose the clipping region if we are using one.
05522     if (RenderMethod == GF_USE_GDICLIPPING)
05523         RenderDC->SetClippingRegion(*OSClipRegion);
05524 
05525     return TRUE;
05526 }

void OSRenderRegion::RenderPath Path DrawPath  )  [protected]
 

Renders a path to the GDI. Can recurse in the case of arrow heads. Scope: Private.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/6/93

Definition at line 2856 of file osrndrgn.cpp.

02857 {
02858     /*
02859     26/9/94. Will. 
02860 
02861     Changed RFlag test, because of problems with NT bezier flattening.
02862 
02863     if (RFlags.GDI32 && (RR_DASHPATTERN().Elements == 0))
02864     {
02865         RenderPath32( DrawPath );
02866         return;
02867     }
02868     */
02869 
02870     // Flags to indicate whether fill-providers or stroke-providers have filled or stroke
02871     // the path yet.
02872     BOOL ExtendedFill = FALSE;
02873 
02874     // If this is not a simple fill, set the flag to indicate this.
02875     FillGeometryAttribute *pFillProvider = 
02876         (FillGeometryAttribute *) CurrentAttrs[ATTR_FILLGEOMETRY].pAttr;
02877 
02878     if (pFillProvider->GetRuntimeClass() != CC_RUNTIME_CLASS(FlatFillAttribute))
02879         ExtendedFill = TRUE;
02880 
02881     // we can't do fancy fills if quality is low
02882     if (RRQuality.GetFillQuality() < Quality::Graduated)
02883         ExtendedFill = FALSE;
02884 
02885     //
02886     // We ought to check for stroke-providers in here, when the great day comes that
02887     // we actually have them...
02888     //
02889     // DY - 27/11/2000 The Great Day has arrived!!! If we have an AttrStrokeType
02890     // AND an AttrVariableWidth then we don't want Gavin to mess with our line widths
02891     
02892     BOOL StrokeProvided = FALSE;
02893     StrokeTypeAttrValue* pStroke = (StrokeTypeAttrValue*) GetCurrentAttribute(ATTR_STROKETYPE);
02894     VariableWidthAttrValue* pVarWidth = (VariableWidthAttrValue*) GetCurrentAttribute(ATTR_VARWIDTH);
02895     if (pVarWidth && pStroke)
02896     {
02897         // Test that these attrs are active and not just defaults that don't do anything
02898         if (pStroke->GetPathProcessor() != NULL && pVarWidth->GetWidthFunction() != NULL)
02899             StrokeProvided = TRUE;
02900     }
02901 
02902     // Get the fill provider to fill the path - if it can't handle this sort of render
02903     // region, then we fill the path for it.
02904     if (ExtendedFill)
02905     {
02906         if (!pFillProvider->RenderFill(this, DrawPath))
02907             // Unable to render fill for this render region - default to simple fill.
02908             ExtendedFill = FALSE;
02909     }
02910 
02911     wxPen NewPen,OldPen;
02912 
02913     // can ge get Gavin to manually flatten the path? Is it worth it?
02914     // Note that if we have already had a stroke provided (above then we don't want Gavin, 
02915     // and we also don't want GDI having a go either
02916     BOOL ManualStroke = !StrokeProvided;
02917     if (ManualStroke)
02918         ManualStroke = GRenderRegion::StrokePathAvailable();
02919     
02920     if (ManualStroke)
02921     {
02922         // is it worth it for this line? Must be wider than 1 pixel and high enough quality
02923 
02924         // First, is it disabled?
02925         if (!DoBetterLines)
02926         {
02927             ManualStroke = FALSE;
02928         }
02929         // We have to stroke for Dash patterns
02930         else if ((RR_DASHPATTERN().Elements != 0) && (RR_LINEWIDTH() > 0))
02931         {
02932             // Keep manual stroke as being TRUE...
02933         }
02934         else
02935         {
02936             INT32 dpLineWidth  = MPtoLP(RR_LINEWIDTH());
02937 
02938             // If no 32-bit GDI then we have to stroke via Gavin if the line is wider than 
02939             // a few device pixels, because 16-bit GDI can't do end-caps/joins for toffee.
02940             if (dpLineWidth > 0) //(!RFlags.GDI32 && (dpLineWidth > 3))
02941             {
02942                 // Keep manual stroke as being TRUE...
02943             }
02944             // Don't bother with 0-width lines, or for very thin lines
02945             else if ((RR_LINEWIDTH() == 0) || (dpLineWidth <= 3))
02946             {
02947                 ManualStroke = FALSE;
02948             }
02949             else if (RR_STROKECOLOUR().IsTransparent() ||               // if no line, don't bother
02950                      (RRQuality.GetLineQuality() < Quality::FullLine)   // if low quality, don't bother
02951                      )
02952             {
02953                 ManualStroke = FALSE;
02954             }
02955         }
02956     }
02957 
02958     if (ManualStroke || StrokeProvided)
02959     {
02960         // if we're going to use Gavin for path stroking, or a stroke attribute has
02961         // already stroked the path then better stop GDI from outlining
02962         // the Polygons
02963 //      NewPen.CreateStockObject( NULL_PEN );
02964         OldPen = RenderDC->GetPen();
02965 
02966         // AMB thinks (15-Mar-05) the following will cause problems, because wx on GTK doesn't
02967         // like drawing with the NULL pen. Use a transparent pen instead
02968         // RenderDC->SetPen(wxNullPen);
02969         RenderDC->SetPen(*wxTRANSPARENT_PEN);
02970     }
02971 
02972     INT32 Count;
02973 
02974     // An array of the number of points in each polygon
02975     INT32 PolyCounts[MAX_POLYGONS];
02976 
02977     // Use default flattening
02978     INT32 Flatness = 0;
02979 
02980     // In all, we reduce flattening 8 times before giving up (arbitrary number)
02981     INT32 Attempts = 8;
02982 
02983     BOOL Worked = FALSE;
02984     
02985     // Keep flattening until it works (or we have tried 8 times)
02986     while (!Worked && (Attempts > 0))
02987     {
02988         Worked = RawRenderPath( NORMALPATH(DrawPath), PolyCounts, &Count, Flatness, &Flatness );
02989         Attempts--;
02990     }
02991 
02992     if (Worked)
02993     {
02994         if (Count)
02995         {
02996 #ifndef _MAC
02997             if (DrawPath->IsFilled && !ExtendedFill)
02998                 RenderDC->DrawPolyPolygon(Count,PolyCounts,PointArray,0,0,nFillStyle);
02999             else
03000 #endif
03001             {
03002                 // render the little sub-paths. Win16 doesn't have Polypolyline
03003                 wxPoint* PointList = PointArray;
03004                 INT32 *CountList = PolyCounts;
03005                 INT32 count;
03006 
03007                 while (Count--)
03008                 {
03009                     count = *CountList++;
03010                     RenderDC->DrawLines(count,PointList);
03011                     PointList += count;
03012                 }
03013             }
03014         }
03015     }
03016     else
03017     {
03018         TRACE( _T("Unable to flatten path into out buffer\n"));
03019     }
03020 
03021     // Let Gavin have a go at the lines now
03022     if (ManualStroke)
03023     {
03024         StrokeProperly( DrawPath );
03025         RenderDC->SetPen( OldPen );
03026     }
03027 }

void OSRenderRegion::RenderPath32 Path DrawPath  )  [protected]
 

Renders a path using Win32 GDI. Causes an ENSURE on Win16 as should never be called. Scope: Private.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/9/93

Definition at line 6409 of file osrndrgn.cpp.

06410 {
06411     PORTNOTETRACE("other","OSRenderRegion::RenderPath32 - do nothing");
06412 #ifndef EXCLUDE_FROM_XARALX
06413     const wxDC* dc = RenderDC;
06414 
06415     // Flags to indicate whether fill-providers or stroke-providers have filled or stroked
06416     // the path yet.
06417     BOOL ExtendedFill = FALSE;
06418 
06419     // If this is not a simple fill, set the flag to indicate this.
06420     FillGeometryAttribute *pFillProvider = 
06421         (FillGeometryAttribute *) CurrentAttrs[ATTR_FILLGEOMETRY].pAttr;
06422 
06423     if (pFillProvider->GetRuntimeClass() != CC_RUNTIME_CLASS(FlatFillAttribute))
06424         ExtendedFill = TRUE;
06425 
06426     // low quality displays can't do fancy fills
06427     if (RRQuality.GetFillQuality() < Quality::Graduated)
06428         ExtendedFill = FALSE;
06429 
06430     //
06431     // We ought to check for stroke-providers in here, when the great day comes that
06432     // we actually have them...
06433     //
06434 
06435     // Get the fill provider to fill the path - if it can't handle this sort of render
06436     // region, then we fill the path for it.
06437     if (ExtendedFill)
06438     {
06439         if (!pFillProvider->RenderFill(this, DrawPath))
06440             // Unable to render fill for this render region - default to simple fill.
06441             ExtendedFill = FALSE;
06442     }
06443 
06444     // actually do the rendering
06445     BOOL Result = RawRenderPath32( DrawPath );
06446 
06447     if (!Result)
06448     {
06449         TRACE( _T("RawRenderPath failed"));
06450         return;
06451     }
06452 
06453     // Draw it either filled or not.
06454     // NB. If the fill-provider has already filled this path then we don't bother.
06455     if (DrawPath->IsFilled && !ExtendedFill)
06456         StrokeAndFillPath( dc );
06457     else
06458         StrokePath( dc );
06459 
06460 #endif
06461 }

BOOL OSRenderRegion::RenderRadialFill Path PathToDraw,
RadialFillAttribute Fill
[protected]
 

Renders the path with a gradient fill.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>? Rik? Tim?
Date:
?
Parameters:
PathToDraw - A pointer to the path to be rendered. [INPUTS] Fill - A pointer to the radial fill applied.
Returns:
TRUE - Success. FALSE - An error occured.

Definition at line 4936 of file osrndrgn.cpp.

04937 {
04938     GradFillMethodType RenderMethod = GF_USE_GDICLIPPING;
04939 
04940     INT32 Radius1 = CalcDistance(Fill->StartPoint, Fill->EndPoint);
04941     INT32 Radius2 = CalcDistance(Fill->StartPoint, Fill->EndPoint2);
04942 
04943     // We want to change the rendering context, so we save it.
04944     SaveContext();
04945 
04946     // No stroking while rendering the fill.
04947     SetLineColour(COLOUR_TRANS);
04948 
04949     // Use device pixel size to work out how many steps to do.
04950     FIXED16 PixelSize = 0;
04951     GetRenderView()->GetScaledPixelSize(&PixelSize,&PixelSize);
04952     INT32 FillSteps = INT32( max( Radius1, Radius2 ) / PixelSize.MakeDouble() );
04953 
04954     // Do a slice every 4 pixels (arbitrary!)
04955     FillSteps /= 4;
04956 
04957     // Also base it on distance between colours
04958     EFFECTTYPE EffectType = GetFillEffect();
04959     FillSteps = min(ColDifference(Fill->Colour, Fill->EndColour, 
04960                                   IsPrinting() ? 24 : 8,    // Colour depth
04961                                   EffectType ), 
04962                                   FillSteps);
04963 
04964     // Limit fill steps to a maximum
04965     FillSteps = min(FillSteps, INT32(MAX_FILL_STEPS));
04966 
04967     // Use global Quality setting
04968     FillSteps = FillSteps / (1 << GradFillQuality);
04969     FillSteps = max(FillSteps, 10);
04970 
04971     // Work out what flatness and accuracy to use for Gavin's clipping functions.
04972     // Gavin recommends 1/2 pixel for flattening, and 1/4 pixel for tolerance
04973     // (but these were kind of off the top of his head - Tim).
04974     // PS. It seems we need maximum tolerance (i.e. 0) for accurate grad-fill rendering.
04975     INT32 ClipFlatness = PixelSize.MakeLong() / 16;
04976     INT32 ClipTolerance = 0;
04977 
04978     RGBQUAD ColourSteps[MAX_FILL_STEPS];
04979     GradTable32::BuildGraduatedPalette(Fill->Colour, Fill->EndColour,
04980                                         GetRenderView(), EffectType,
04981                                         FillSteps, ColourSteps);
04982 
04983     // If we are rendering into a metafile, clip the path ourselves
04984     if (RFlags.Metafile)
04985     {
04986         RenderMethod = GF_USE_GAVINCLIPPING;
04987     }
04988     else
04989     {
04990         if (!SetClipToPathTemporary(PathToDraw))
04991         {
04992             // Can't use clipping - fall back to EOR.
04993             RenderMethod = GF_USE_GDIEOR;
04994         }
04995     }
04996 
04997     INT32 RenderCount = 1;
04998 
04999     if (RenderMethod == GF_USE_GDIEOR)
05000     {
05001         SetDrawingMode(DM_EORDITHER);
05002         RenderCount = 2;
05003     }
05004 
05005     DocColour TempFillColour;
05006 
05007     while (RenderCount > 0)
05008     {
05009         COLORREF CurrentCol = RGB(ColourSteps[FillSteps - 1].rgbRed, 
05010                                     ColourSteps[FillSteps - 1].rgbGreen, 
05011                                     ColourSteps[FillSteps - 1].rgbBlue);
05012 
05013         // Put the RGB value back into a DocColour so we can set it as the fill colour. We set it
05014         // as non-separable, as it will have already been colour-separated by BuildGraduatedPalette
05015         TempFillColour.SetRGBValue(ColourSteps[FillSteps - 1].rgbRed, 
05016                                     ColourSteps[FillSteps - 1].rgbGreen, 
05017                                     ColourSteps[FillSteps - 1].rgbBlue);
05018         TempFillColour.SetSeparable(FALSE);
05019 
05020         SetFillColour(TempFillColour);
05021 
05022         GetValidBrush();
05023         GetValidPen();
05024 
05025         // First, fill in whole path with end colour
05026         //RenderPath(PathToDraw);
05027         Path PreviousPath;
05028         PreviousPath.Initialise(PathToDraw->GetNumCoords() + 2, 12);
05029         PreviousPath.CopyPathDataFrom(PathToDraw);
05030 
05031         // Work out relative positions of start and end points.
05032         DocCoord Steps[2];
05033         Steps[0].x = Fill->StartPoint.x - Fill->EndPoint.x;
05034         Steps[0].y = Fill->StartPoint.y - Fill->EndPoint.y;
05035         Steps[1].x = Fill->StartPoint.x - Fill->EndPoint2.x;
05036         Steps[1].y = Fill->StartPoint.y - Fill->EndPoint2.y;
05037 
05038         // Construct the parallelogram that describes the biggest ellipse.
05039         // (If I could draw a picture here, I would!)
05040         DocCoord Parallel[4];
05041         Parallel[0].x = Fill->StartPoint.x + (Steps[0].x + Steps[1].x);
05042         Parallel[0].y = Fill->StartPoint.y + (Steps[0].y + Steps[1].y);
05043         Parallel[1].x = Fill->StartPoint.x + (Steps[0].x - Steps[1].x);
05044         Parallel[1].y = Fill->StartPoint.y + (Steps[0].y - Steps[1].y);
05045         Parallel[2].x = Fill->StartPoint.x - (Steps[0].x + Steps[1].x);
05046         Parallel[2].y = Fill->StartPoint.y - (Steps[0].y + Steps[1].y);
05047         Parallel[3].x = Fill->StartPoint.x + (Steps[1].x - Steps[0].x);
05048         Parallel[3].y = Fill->StartPoint.y + (Steps[1].y - Steps[0].y);
05049 
05050         // Now convert the steps into the steps we should use to adjust the
05051         // parallelogram after each fill step
05052         Steps[0].x /= (FillSteps + 1);
05053         Steps[0].y /= (FillSteps + 1);
05054         Steps[1].x /= (FillSteps + 1);
05055         Steps[1].y /= (FillSteps + 1);
05056 
05057         // This are the paths we will use to create radial fills.
05058         Path RadialFill;
05059         RadialFill.Initialise(50,12);
05060         Path EllipsePath;
05061         EllipsePath.Initialise(15,12);
05062 
05063         // This is the path we use for all clipped rendering.
05064         Path ClippedPath;
05065         ClippedPath.Initialise(12, 12);
05066 
05067 
05068         // Now render the fill using concentric ellipses, starting with the biggest.
05069         for (INT32 i = FillSteps; i > 0;)
05070         {
05071             MakeEllipticalPath(&EllipsePath, Parallel);
05072             EllipsePath.IsFilled = TRUE;
05073 
05074             // Use this and the previous path to make an elliptical disc.
05075             RadialFill.ClearPath(FALSE);
05076             RadialFill.MakeSpaceInPath(PreviousPath.GetNumCoords() + EllipsePath.GetNumCoords() + 2);
05077             RadialFill.CopyPathDataFrom(&PreviousPath);
05078             RadialFill.IsFilled = TRUE;
05079             if (i > 1)
05080             {
05081                 // For all except the last step, make a complex path (which is
05082                 // usually an elliptical disc).
05083                 ERROR2IF(!RadialFill.MergeTwoPaths(EllipsePath), FALSE, "could not merge paths");
05084             }
05085 
05086             // Remember the elliptical path for next time
05087             PreviousPath.ClearPath(FALSE);
05088             PreviousPath.MakeSpaceInPath(EllipsePath.GetNumCoords() + 2);
05089             PreviousPath.CopyPathDataFrom(&EllipsePath);
05090 
05091             if (RenderMethod != GF_USE_GAVINCLIPPING)
05092             {
05093                 RenderPath(&RadialFill);
05094             }
05095             else
05096             {
05097                 PathToDraw->ClipPathToPath(RadialFill, &ClippedPath, 2,
05098                                            ClipTolerance, ClipFlatness, ClipFlatness);
05099                 ClippedPath.IsFilled = TRUE;
05100                 RenderPath(&ClippedPath);
05101             }
05102 
05103             // decrement loop counter here so that the next colour can be calculated
05104             i--;
05105 
05106             if (i > 0)
05107             {
05108                 // Calculate next brush (except at the end of the loop)
05109                 const COLORREF NewFill = RGB(ColourSteps[i].rgbRed, ColourSteps[i].rgbGreen,
05110                                                 ColourSteps[i].rgbBlue);
05111                 if (NewFill != CurrentCol)
05112                 {
05113                     // colour changed, make new brush
05114                     CurrentCol = NewFill;
05115 
05116                     // Put the RGB value back into a DocColour so we can set it as the fill colour. We set it
05117                     // as non-separable, as it will have already been colour-separated by BuildGraduatedPalette
05118                     TempFillColour.SetRGBValue(ColourSteps[i].rgbRed, 
05119                                                 ColourSteps[i].rgbGreen, 
05120                                                 ColourSteps[i].rgbBlue);
05121                     TempFillColour.SetSeparable(FALSE);
05122 
05123                     SetFillColour(TempFillColour);
05124                     GetValidBrush();
05125                     GetValidPen();
05126                 }
05127 
05128                 // Reduce size of paralleogram
05129                 Parallel[0].x -= (Steps[0].x + Steps[1].x);
05130                 Parallel[0].y -= (Steps[0].y + Steps[1].y);
05131                 Parallel[1].x -= (Steps[0].x - Steps[1].x);
05132                 Parallel[1].y -= (Steps[0].y - Steps[1].y);
05133                 Parallel[2].x += (Steps[0].x + Steps[1].x);
05134                 Parallel[2].y += (Steps[0].y + Steps[1].y);
05135                 Parallel[3].x -= (Steps[1].x - Steps[0].x);
05136                 Parallel[3].y -= (Steps[1].y - Steps[0].y);
05137             }
05138         }
05139 
05140         if ((RenderMethod == GF_USE_GDIEOR) && (RenderCount > 1))
05141         {
05142             // Render the path in white
05143             SetDrawingMode(DM_COPYPEN);
05144             SetFillColour(COLOUR_BLACK);
05145             SetLineColour(COLOUR_TRANS);
05146             GetValidBrush();
05147             GetValidPen();
05148             RenderPath(PathToDraw);
05149 
05150             // Set back to mode required for grad fill rendering
05151             SetDrawingMode(DM_EORDITHER);
05152         }
05153 
05154         RenderCount--;
05155     }
05156 
05157     // now tidy up
05158     RestoreContext();
05159     GetValidBrush();
05160     GetValidPen();
05161 
05162     // Lose the clipping region if we are using one.
05163     if (RenderMethod == GF_USE_GDICLIPPING)
05164         RenderDC->SetClippingRegion( *OSClipRegion );
05165 
05166     return TRUE;
05167 }

BOOL OSRenderRegion::RenderSquareFill Path PathToDraw,
SquareFillAttribute Fill
[protected]
 

Renders the path with a gradient fill.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>? Rik? Tim?
Date:
?
Parameters:
PathToDraw - A pointer to the path to be rendered. [INPUTS] Fill - A pointer to the radial fill applied.
Returns:
TRUE - Success. FALSE - An error occured.

Definition at line 5782 of file osrndrgn.cpp.

05783 {
05784     GradFillMethodType RenderMethod = GF_USE_GDICLIPPING;
05785 
05786     INT32 Radius1 = CalcDistance(Fill->StartPoint, Fill->EndPoint);
05787     INT32 Radius2 = CalcDistance(Fill->StartPoint, Fill->EndPoint2);
05788 
05789     // We want to change the rendering context, so we save it.
05790     SaveContext();
05791 
05792     // No stroking while rendering the fill.
05793     SetLineColour(COLOUR_TRANS);
05794 
05795     // Use device pixel size to work out how many steps to do.
05796     FIXED16 PixelSize = 0;
05797     GetRenderView()->GetScaledPixelSize(&PixelSize,&PixelSize);
05798     INT32 FillSteps = (INT32) (max(Radius1, Radius2) / PixelSize.MakeDouble());
05799 
05800     // Do a slice every 4 pixels (arbitrary!)
05801     FillSteps /= 4;
05802 
05803     // Also base it on distance between colours
05804     EFFECTTYPE EffectType = GetFillEffect();
05805     FillSteps = min(ColDifference(Fill->Colour, Fill->EndColour, 
05806                                   IsPrinting() ? 24 : 8,    // Colour depth
05807                                   EffectType), 
05808                                   FillSteps);
05809 
05810     // Limit fill steps to a maximum
05811     FillSteps = min( FillSteps, INT32(MAX_FILL_STEPS) );
05812 
05813     // Use global Quality setting
05814     FillSteps = FillSteps / (1 << GradFillQuality);
05815     FillSteps = max(FillSteps, 10);
05816 
05817     // Work out what flatness and accuracy to use for Gavin's clipping functions.
05818     // Gavin recommends 1/2 pixel for flattening, and 1/4 pixel for tolerance
05819     // (but these were kind of off the top of his head - Tim).
05820     // PS. It seems we need maximum tolerance (i.e. 0) for accurate grad-fill rendering.
05821     INT32 ClipFlatness = PixelSize.MakeLong() / 16;
05822     INT32 ClipTolerance = 0;
05823 
05824     RGBQUAD ColourSteps[MAX_FILL_STEPS];
05825     GradTable32::BuildGraduatedPalette(Fill->Colour, Fill->EndColour,
05826                                         GetRenderView(), EffectType,
05827                                         FillSteps, ColourSteps);
05828 
05829     // If we are rendering into a metafile, clip the path ourselves
05830     if (RFlags.Metafile)
05831     {
05832         RenderMethod = GF_USE_GAVINCLIPPING;
05833     }
05834     else
05835     {
05836         if (!SetClipToPathTemporary(PathToDraw))
05837         {
05838             // Can't use clipping - fall back to EOR.
05839             RenderMethod = GF_USE_GDIEOR;
05840         }
05841     }
05842 
05843     INT32 RenderCount = 1;
05844 
05845     if (RenderMethod == GF_USE_GDIEOR)
05846     {
05847         SetDrawingMode(DM_EORDITHER);
05848         RenderCount = 2;
05849     }
05850 
05851     DocColour TempFillColour;
05852 
05853     while (RenderCount > 0)
05854     {
05855         COLORREF CurrentCol = RGB(ColourSteps[FillSteps - 1].rgbRed, 
05856                                     ColourSteps[FillSteps - 1].rgbGreen, 
05857                                     ColourSteps[FillSteps - 1].rgbBlue);
05858 
05859         // Put the RGB value back into a DocColour so we can set it as the fill colour. We set it
05860         // as non-separable, as it will have already been colour-separated by BuildGraduatedPalette
05861         TempFillColour.SetRGBValue(ColourSteps[FillSteps - 1].rgbRed, 
05862                                     ColourSteps[FillSteps - 1].rgbGreen, 
05863                                     ColourSteps[FillSteps - 1].rgbBlue);
05864         TempFillColour.SetSeparable(FALSE);
05865 
05866         SetFillColour(TempFillColour);
05867 
05868         GetValidBrush();
05869         GetValidPen();
05870 
05871         // First, fill in whole path with end colour
05872         //RenderPath(PathToDraw);
05873         Path PreviousPath;
05874         PreviousPath.Initialise(PathToDraw->GetNumCoords() + 2, 12);
05875         PreviousPath.CopyPathDataFrom(PathToDraw);
05876 
05877         // Work out relative positions of start and end points.
05878         DocCoord Steps[2];
05879         Steps[0].x = Fill->StartPoint.x - Fill->EndPoint.x;
05880         Steps[0].y = Fill->StartPoint.y - Fill->EndPoint.y;
05881         Steps[1].x = Fill->StartPoint.x - Fill->EndPoint2.x;
05882         Steps[1].y = Fill->StartPoint.y - Fill->EndPoint2.y;
05883 
05884         // Construct the parallelogram that describes the extent of the fill
05885         DocCoord Parallel[4];
05886         Parallel[0].x = Fill->StartPoint.x + (Steps[0].x + Steps[1].x);
05887         Parallel[0].y = Fill->StartPoint.y + (Steps[0].y + Steps[1].y);
05888         Parallel[1].x = Fill->StartPoint.x + (Steps[0].x - Steps[1].x);
05889         Parallel[1].y = Fill->StartPoint.y + (Steps[0].y - Steps[1].y);
05890         Parallel[2].x = Fill->StartPoint.x - (Steps[0].x + Steps[1].x);
05891         Parallel[2].y = Fill->StartPoint.y - (Steps[0].y + Steps[1].y);
05892         Parallel[3].x = Fill->StartPoint.x + (Steps[1].x - Steps[0].x);
05893         Parallel[3].y = Fill->StartPoint.y + (Steps[1].y - Steps[0].y);
05894 
05895         // Now convert the steps into the steps we should use to adjust the
05896         // parallelogram after each fill step
05897         Steps[0].x /= (FillSteps + 1);
05898         Steps[0].y /= (FillSteps + 1);
05899         Steps[1].x /= (FillSteps + 1);
05900         Steps[1].y /= (FillSteps + 1);
05901 
05902         // These are the paths we will use to create square fills.
05903         Path SquareFill;
05904         SquareFill.Initialise(50,12);
05905         Path ParallelogramPath;
05906         ParallelogramPath.Initialise(15,12);
05907 
05908         // This is the path we use for all clipped rendering.
05909         Path ClippedPath;
05910         ClippedPath.Initialise(12, 12);
05911 
05912         // Now render the fill using concentric parallelograms, starting with the biggest.
05913         for (INT32 i = FillSteps; i > 0;)
05914         {
05915             // build a path
05916             ParallelogramPath.ClearPath();
05917             ParallelogramPath.FindStartOfPath();
05918             ParallelogramPath.InsertMoveTo(Parallel[0]);
05919             ParallelogramPath.InsertLineTo(Parallel[1]);
05920             ParallelogramPath.InsertLineTo(Parallel[2]);
05921             ParallelogramPath.InsertLineTo(Parallel[3]);
05922             ParallelogramPath.InsertLineTo(Parallel[0]);
05923             ParallelogramPath.IsFilled = TRUE;
05924 
05925             // Use this and the previous path to make a parallelogram shaped 'washer'
05926             SquareFill.ClearPath(FALSE);
05927             SquareFill.MakeSpaceInPath(PreviousPath.GetNumCoords() + ParallelogramPath.GetNumCoords() + 2);
05928             SquareFill.CopyPathDataFrom(&PreviousPath);
05929             SquareFill.IsFilled = TRUE;
05930             if (i > 1)
05931             {
05932                 // For all except the last step, make a complex path (which is
05933                 // usually a parallelogram).
05934                 ERROR2IF(!SquareFill.MergeTwoPaths(ParallelogramPath), FALSE, "could not merge paths");
05935             }
05936 
05937             // Remember the parallelogram path for next time
05938             PreviousPath.ClearPath(FALSE);
05939             PreviousPath.MakeSpaceInPath(ParallelogramPath.GetNumCoords() + 2);
05940             PreviousPath.CopyPathDataFrom(&ParallelogramPath);
05941 
05942             if (RenderMethod != GF_USE_GAVINCLIPPING)
05943             {
05944                 RenderPath(&SquareFill);
05945             }
05946             else
05947             {
05948                 PathToDraw->ClipPathToPath(SquareFill, &ClippedPath, 2,
05949                                            ClipTolerance, ClipFlatness, ClipFlatness);
05950                 ClippedPath.IsFilled = TRUE;
05951                 RenderPath(&ClippedPath);
05952             }
05953 
05954             // decrement loop counter here so that the next colour can be calculated
05955             i--;
05956 
05957             if (i > 0)
05958             {
05959                 // Calculate next brush (except at the end of the loop)
05960                 const COLORREF NewFill = RGB(ColourSteps[i].rgbRed, ColourSteps[i].rgbGreen,
05961                                                 ColourSteps[i].rgbBlue);
05962                 if (NewFill != CurrentCol)
05963                 {
05964                     // colour changed, make new brush
05965                     CurrentCol = NewFill;
05966 
05967                     // Put the RGB value back into a DocColour so we can set it as the fill colour. We set it
05968                     // as non-separable, as it will have already been colour-separated by BuildGraduatedPalette
05969                     TempFillColour.SetRGBValue(ColourSteps[i].rgbRed, 
05970                                                 ColourSteps[i].rgbGreen, 
05971                                                 ColourSteps[i].rgbBlue);
05972                     TempFillColour.SetSeparable(FALSE);
05973 
05974                     SetFillColour(TempFillColour);
05975                     GetValidBrush();
05976                     GetValidPen();
05977                 }
05978 
05979                 // Reduce size of paralleogram
05980                 Parallel[0].x -= (Steps[0].x + Steps[1].x);
05981                 Parallel[0].y -= (Steps[0].y + Steps[1].y);
05982                 Parallel[1].x -= (Steps[0].x - Steps[1].x);
05983                 Parallel[1].y -= (Steps[0].y - Steps[1].y);
05984                 Parallel[2].x += (Steps[0].x + Steps[1].x);
05985                 Parallel[2].y += (Steps[0].y + Steps[1].y);
05986                 Parallel[3].x -= (Steps[1].x - Steps[0].x);
05987                 Parallel[3].y -= (Steps[1].y - Steps[0].y);
05988             }
05989         }
05990 
05991         if ((RenderMethod == GF_USE_GDIEOR) && (RenderCount > 1))
05992         {
05993             // Render the path in white
05994             SetDrawingMode(DM_COPYPEN);
05995             SetFillColour(COLOUR_BLACK);
05996             SetLineColour(COLOUR_TRANS);
05997             GetValidBrush();
05998             GetValidPen();
05999             RenderPath(PathToDraw);
06000 
06001             // Set back to mode required for grad fill rendering
06002             SetDrawingMode(DM_EORDITHER);
06003         }
06004 
06005         RenderCount--;
06006     }
06007 
06008     // now tidy up
06009     RestoreContext();
06010     GetValidBrush();
06011     GetValidPen();
06012 
06013     // Lose the clipping region if we are using one.
06014     if (RenderMethod == GF_USE_GDICLIPPING)
06015         RenderDC->SetClippingRegion(*OSClipRegion);
06016 
06017     return TRUE;
06018 }

BOOL OSRenderRegion::RenderThreeColFill Path PathToDraw,
ThreeColFillAttribute Fill
[protected]
 

Renders a three colour gradient fill to a Windows DC.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
7/6/00
Parameters:
PathToDraw - A pointer to the path to be rendered. [INPUTS] Fill - A pointer to the radial fill applied.
Returns:
TRUE - Success. FALSE - An error occured.

Definition at line 6035 of file osrndrgn.cpp.

06037 {
06038     // Create a new end point for the fill.
06039     DocCoord            EndPoint     ( *( Fill->GetEndPoint () ) + *( Fill->GetEndPoint2 () )
06040                                        - *( Fill->GetStartPoint () ) );
06041     DocColour           EndColour;
06042     LinearFillAttribute LinearFill;
06043 
06044     // Mix the two end colours together to make a blend suitable for the end point.
06045     EndColour.Mix ( Fill->GetEndColour (), Fill->GetEndColour2 (),
06046                     0.5f, NULL, FALSE, NULL );
06047 
06048     // Set up the fill attribute.
06049     LinearFill.SetStartPoint    ( Fill->GetStartPoint () );
06050     LinearFill.SetEndPoint      ( &EndPoint );
06051     LinearFill.SetStartColour   ( Fill->GetStartColour () );
06052     LinearFill.SetEndColour     ( &EndColour );
06053 
06054     // Export the fill as a two colour linear fill.
06055     RenderLinearFill ( PathToDraw, &LinearFill );
06056 
06057     return TRUE;
06058 }

void OSRenderRegion::SelectNewBrush  )  [protected]
 

Selects RenderBrush while setting its new origin. A common operation that is in its own function to cope with things such as metafiles which cannot do this. Scope: Private.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/10/93

Definition at line 1295 of file osrndrgn.cpp.

01296 {
01297     // Swap brushes
01298     CurrentBrush = 1 - CurrentBrush;
01299 
01300     // Make the new brush
01301     CreateNewBrush();
01302 
01303     // Set up the brush origin
01304     if (!RFlags.Metafile)
01305     {
01306 //      RenderBrush[CurrentBrush]->UnrealizeObject();
01307         // this fn will assert if done on a metafile
01308     PORTNOTE("other","OSRenderRegion::SelectNewBrush - removed setting of brush origin");
01309 #if !defined(EXCLUDE_FROM_XARALX)
01310         RenderDC->SetBrushOrg(NewBrushOrg);
01311 #endif
01312     }
01313 
01314     // And select the new brush
01315     RenderDC->SetBrush(RenderBrush[CurrentBrush]);
01316 
01317     // Set winding rule as required
01318     if (RR_WINDINGRULE() == EvenOddWinding)
01319         nFillStyle = wxODDEVEN_RULE;
01320     else
01321         nFillStyle = wxWINDING_RULE;
01322 
01323     // We've now got a valid brush
01324     RFlags.ValidBrush = TRUE;
01325 }

BOOL OSRenderRegion::SelectNewFont WORD  Typeface,
BOOL  Bold,
BOOL  Italic,
MILLIPOINT  Width,
MILLIPOINT  Height,
ANGLE  Rotation
[protected]
 

Selects the specified font into the DC. Performs clever stuff to cache the font so that subsequent requests for the same font don't cause anything to happen.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
05/28/95
Parameters:
Details of the font to select. [INPUTS] NB. Width is not the actual width; it expresses the aspect ratio required. So, e.g. if Width == Height/2 then the aspect ratio is 50%, and so on.
Returns:
TRUE if the font was selected ok; FALSE if not.

Definition at line 1359 of file osrndrgn.cpp.

01361 {
01362     PORTNOTETRACE("text","OSRenderRegion::SelectNewFont - do nothing");
01363 #ifndef EXCLUDE_FROM_XARALX
01364     // Check to see if it is cached
01365     if ((FontInfo.pRenderFont != NULL) &&
01366         (FontInfo.Typeface == Typeface) &&
01367         (FontInfo.Bold == Bold) &&
01368         (FontInfo.Italic == Italic) &&
01369         (FontInfo.Width == Width) &&
01370         (FontInfo.Height == Height) &&
01371         (FontInfo.Rotation == Rotation))
01372     {
01373         // It is the same as the currently selected/cached font
01374         TRACEUSER( "Tim", _T("Using the cached font\n"));
01375         return TRUE;
01376     }
01377 
01378     // Is it rotated, and if so, can this DC do rotated fonts?
01379     if (Rotation != FIXED16(0))
01380     {
01381         // Don't use GetDeviceCaps to ask printers about their capabilities!
01382         // It tells lies.
01383         // Even Worse - many printers claim to be unable to render rotated
01384         // text, when they are actually perfectly cpaable of doing so!
01385         //
01386         // So, to maintain compatibility with previous versions just test
01387         // a Preference here and if it's set return FALSE like 1.5 and all
01388         // previous versions did.
01389         if (PrintRotatedTextAsPaths)
01390             return FALSE;
01391     }
01392 
01393     TRACEUSER( "Tim", _T("Font cache invalid - generating font to use\n"));
01394 
01395     // Not the cached font - ok, deselect and delete the cached font.
01396     if (FontInfo.pOldFont != NULL)
01397     {
01398         RenderDC->SelectObject(FontInfo.pOldFont);
01399         FontInfo.pOldFont = NULL;
01400     }
01401 
01402     if (FontInfo.pRenderFont != NULL)
01403     {
01404         delete FontInfo.pRenderFont;
01405         FontInfo.pRenderFont = NULL;
01406     }
01407 
01408 
01409     ENUMLOGFONT *pEnumLogFont = FONTMANAGER->GetEnumLogFont(Typeface);
01410     if (pEnumLogFont == NULL)
01411         // Error
01412         return FALSE;
01413 
01414     // Create the font and select it into the DC
01415     TRY
01416     {
01417         FontInfo.pRenderFont = new wxFont;
01418     }
01419     CATCH (CMemoryException, e)
01420     {
01421         return FALSE;
01422     }
01423     END_CATCH
01424 
01425     // Work out the font weight - bold or normal?
01426     INT32 FontWeight = Bold ? FW_BOLD : FW_NORMAL;
01427 
01428 
01429     // Work out how big the font is, in logical pixels
01430     FIXED16 fxPixWidth = 0;
01431     FIXED16 fxPixHeight = 0;
01432 
01433 //  if (RFlags.Metafile)
01434 //  {
01435         // Metafile - don't care about the view scale
01436 //      RenderView->GetPixelSize(&fxPixWidth, &fxPixHeight);
01437 //  }
01438 //  else
01439 //  {
01440         RenderView->GetScaledPixelSize(&fxPixWidth, &fxPixHeight);
01441 //  }
01442 
01443     INT32 FontWidth = (INT32) (Width / fxPixWidth.MakeDouble());
01444     INT32 FontHeight = (INT32) (Height / fxPixHeight.MakeDouble());
01445 
01446     if (FontHeight == FontWidth)
01447     {
01448         // Aspect ratio is 100% - use width of 0, and the GDI font engine gives us 100%
01449         // ratio automatically
01450         FontWidth = 0;
01451     }
01452     else
01453     {
01454         // Aspect ratio is not 100% - we need to do some clever stuff to work out
01455         // how wide we want the font to be.  Because fonts are generally much taller
01456         // than they are wide, we can't just pass in FontWidth directly - we must
01457         // transform it to the correct width.
01458 
01459         // BODGETEXT: ideally, we should use a NEWTEXTMETRIC structure here, to work out
01460         //            the correct width, but this involves calling EnumLogFontFamily() or
01461         //            whatever, which is too slow.  As the text code caches the LOGFONT
01462         //            for each font, it could also cache the NEWTEXTMETRIC structure,
01463         //            which this routine could then use.
01464         //            Having said all that, this code seems to work!
01465 
01466         //            Indeed the font manager code to cache the LOGFONTS could also
01467         //            cache the NEWTEXTMETRIC structures (or the TEXTMETRIC structures
01468         //            since NEWTEXTMETRIC structures only exist for TrueType fonts.)
01469         //            But at the moment it doesn't - the whole of the font system
01470         //            needs thinking through and rewriting.
01471         //                                                                  ach - 15/08/96
01472 
01473         // Create the font - the first time is to find out how wide the characters are,
01474         // so we can scale the width correctly. (So we give a width of 0 to get the normal
01475         // width for the given height)
01476         // (We do it at 100 units high so we get decent accuracy for the aspect ratio.)
01477         if (FontInfo.pRenderFont->CreateFont(-100, 0, 0, 0, FontWeight, Italic, 
01478                                              FALSE, FALSE, DEFAULT_CHARSET, 
01479                                              OUT_TT_PRECIS, CLIP_TT_ALWAYS,
01480                                              PROOF_QUALITY, DEFAULT_PITCH | FF_DONTCARE, 
01481                                              pEnumLogFont->elfLogFont.lfFaceName) == 0)
01482         {
01483             // Unable to select the font.
01484             delete FontInfo.pRenderFont;
01485             FontInfo.pRenderFont = NULL;
01486             return FALSE;
01487         }
01488 
01489         // Used to hold information about the font
01490         TEXTMETRIC Metrics;
01491 
01492         if (TRUE) //RFlags.Metafile)
01493         {
01494             // Metafile - we need to use the screen DC to do this
01495             wxDC* pDesktopDC = CWnd::GetDesktopWindow()->GetDC();
01496 
01497             // Get the metrics
01498             FontInfo.pOldFont = pDesktopDC->SetFont(FontInfo.pRenderFont);
01499             pDesktopDC->GetTextMetrics(&Metrics);
01500 
01501             // Select old font back into screen DC
01502             pDesktopDC->SetFont(FontInfo.pOldFont);
01503             CWnd::GetDesktopWindow()->ReleaseDC(pDesktopDC);
01504         }
01505         else
01506         {
01507             // Normal rendering - use the DC as we can use 'Getxxx' functions on it
01508             // because it is not a metafile DC.
01509             FontInfo.pOldFont = RenderDC->SelectObject(FontInfo.pRenderFont);
01510 
01511             // Get the metrics
01512             RenderDC->GetTextMetrics(&Metrics);
01513 
01514             // Select old font back into screen DC
01515             RenderDC->SelectObject(FontInfo.pOldFont);
01516         }
01517 
01518         // Scale the width by the font's aspect ratio: 
01519         // ActualWidth = (RealWidth / Height) * Width
01520         FontWidth = MulDiv(Metrics.tmAveCharWidth, FontWidth, 100);
01521 
01522         // Delete the font
01523         delete FontInfo.pRenderFont;
01524 
01525         // Create the 'proper' font and select it into the DC
01526         TRY
01527         {
01528             FontInfo.pRenderFont = new CFont;
01529         }
01530         CATCH (CMemoryException, e)
01531         {
01532             return FALSE;
01533         }
01534         END_CATCH
01535     }
01536 
01537     // Work out the rotation of the font, in tenths of degrees.
01538     INT32 lfRotation;
01539     if (Rotation == FIXED16(0))
01540         lfRotation = 0;
01541     else
01542         lfRotation = (INT32) ( (Rotation.MakeDouble() * 360.0 * 10.0) / (2 * PI) );
01543 
01544     // Create the font with the correct width   
01545     if (FontInfo.pRenderFont->CreateFont(-FontHeight, FontWidth, lfRotation, 0, FontWeight, Italic, 
01546                                          FALSE, FALSE, DEFAULT_CHARSET, 
01547                                          OUT_TT_PRECIS, CLIP_TT_ALWAYS,
01548                                          PROOF_QUALITY, DEFAULT_PITCH | FF_DONTCARE, 
01549                                          pEnumLogFont->elfLogFont.lfFaceName) == 0)
01550     {
01551         // Unable to select the font - probably because device cannot rotate fonts
01552         // arbitrarily.
01553         delete FontInfo.pRenderFont;
01554         FontInfo.pRenderFont = NULL;
01555         return FALSE;
01556     }
01557 
01558     // Select the real font into the DC.
01559     FontInfo.pOldFont = RenderDC->SetFont(FontInfo.pRenderFont);
01560 
01561     // Validate the cache
01562     FontInfo.Typeface = Typeface;
01563     FontInfo.Bold     = Bold;
01564     FontInfo.Italic   = Italic;
01565     FontInfo.Width    = Width;
01566     FontInfo.Height   = Height;
01567     FontInfo.Rotation = Rotation;
01568 #endif
01569     // Font created and selected ok
01570     return TRUE;
01571 }

void OSRenderRegion::SelectNewPen  )  [protected]
 

Definition at line 1247 of file osrndrgn.cpp.

01248 {
01249     // Swap pens
01250     CurrentPen = 1 - CurrentPen;
01251 
01252     // Create and select the new pen
01253     CreateNewPen();
01254 
01255     RenderDC->SetPen(RenderPen[CurrentPen]);
01256 
01257     RFlags.ValidPen = TRUE;
01258 }

BOOL OSRenderRegion::SetClipToPathTemporary Path * const  PathToDraw  )  [protected]
 

To set a complex clip path. This clip is pretty temporary and should be reset afterwards using OSClipRegion before anything much else is done.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/4/94
Parameters:
A path to be clipped to (in DocCoords). [INPUTS]
- [OUTPUTS]
Returns:
TRUE if worked, FALSE if failed (e.g. not enough memory or cannot do it).

Errors: - Scope: Private

Definition at line 2666 of file osrndrgn.cpp.

02667 {
02668     PORTNOTETRACE("other","OSRenderRegion::SetClipToPathTemporary - do nothing");
02669 #ifndef EXCLUDE_FROM_XARALX
02670     BOOL Worked;
02671     Worked = RawRenderPath32( PathToDraw );
02672     if (Worked)
02673     {
02674 //      Worked = ::SelectClipPath( RenderDC, RGN_AND );
02675         if (!Worked)
02676             TRACE( _T("SelectClipPath failed"));
02677     }
02678     else
02679         TRACE( _T("RawPath32 failed in Clip"));
02680     return Worked;
02681 #else
02682     return FALSE;
02683 #endif
02684 }

void OSRenderRegion::SetFillAttributes ChangeAttrType  Type = CHANGEATTR_ALL  )  [protected, virtual]
 

When a fill attribute is changed, this functions is called to create a new brush to mirror the new attribute value. Scope: Private.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
31/5/93
Parameters:
Ignored for OSRenderRegion. [INPUTS]

Reimplemented from RenderRegion.

Definition at line 935 of file osrndrgn.cpp.

00936 {
00937     RFlags.ValidBrush = FALSE;
00938 }

void OSRenderRegion::SetFixedSystemTextColours DocColour TextCol,
DocColour Background
[virtual]
 

To set the text and background colour(s) for any FixedSystem text rendered in this render region in the future (within the current rendering pass).

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/1/95
Parameters:
TextCol - The foreground (text) colour (may be NULL) [INPUTS] Background - The background colour (may be NULL)
Notes: If either of the colours is passed in as a NULL pointer, that colour will not be set, and will remain at the previous setting.

Note that these values are passed directly to the host OS at the point of calling, so you must call this method every time the colour is changed (i.e. don't rely on just changing the DocColours that you passed in originally, as they aren't remembered in any way). Note also that if you call DrawFixedSystemText without a prior call to this method, the colours used are undefined.

The colour chosen may not exactly match the colour requested - under Windows, for example, the nearest solid (non-dithered) colour to that requested will be used. Thus, it is best to stick to 'simple' colour schemes.

This method may or may not affect some other rendering processes (for example, under Windows, plotting of bitmaps may be affected by the settings used here...)

See also:
OSRenderRegion::DrawFixedSystemText

Reimplemented from RenderRegion.

Definition at line 2317 of file osrndrgn.cpp.

02318 {
02319     if (TextCol != NULL)
02320     {
02321         COLORREF Clr = ConvertColourToScreenWord(CurrentColContext, TextCol);
02322         RenderDC->SetTextForeground(Clr);
02323     }
02324 
02325     if (Background != NULL)
02326     {
02327         COLORREF Clr = ConvertColourToScreenWord(CurrentColContext, Background);
02328         RenderDC->SetTextBackground(Clr);
02329     }
02330 }

void OSRenderRegion::SetLineAttributes ChangeLineAttrType  Type = CHANGELINEATTR_ALL  )  [protected, virtual]
 

When a line attribute is changed, this functions is called to create a new pen to mirror the new attribute value. Scope: Private.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
31/5/93

Reimplemented from RenderRegion.

Definition at line 917 of file osrndrgn.cpp.

00918 {
00919     RFlags.ValidPen = FALSE;
00920 }

void OSRenderRegion::SetOSDrawingMode void   )  [protected, virtual]
 

Sets the current drawing mode. Scope: Private.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
31/5/93

Implements RenderRegion.

Definition at line 1584 of file osrndrgn.cpp.

01585 {
01586     // Set ROP2 code accordingly.
01587     switch (DrawingMode)
01588     {
01589         case DM_COPYPEN:
01590             if (!RenderDC->IsKindOf(CLASSINFO(wxPostScriptDC))) // ignore for PS as it is the only option and
01591                 RenderDC->SetLogicalFunction(wxCOPY);// it asserts (ridiculous but true)
01592             break;
01593         case DM_EORPEN:
01594         case DM_EORDITHER:
01595             // Same as EORPEN, except we want the brush to be set to what we ask for,
01596             // and not messed about with, so we use this enum value instead.
01597             // The ROP2 code is the same as we use for DM_EORPEN - it is CalcLogBrush()
01598             // that behaves differently with DM_EORDITHER.
01599             RenderDC->SetLogicalFunction(wxXOR);
01600             break;
01601 
01602         default:
01603             ERROR3("Bad drawing mode in OSRenderRegion::SetOSDrawingMode()");
01604     }
01605 
01606     // When we change the ROP2 code, we also have to recreate the pen and brush objects,
01607     // otherwise we don't get an awful lot happening.  This was found out by trial and
01608     // error, and not by any of Microsoft's manuals telling us this...(Tim)
01609     SetLineAttributes();
01610     SetFillAttributes();
01611 }

void OSRenderRegion::SetQualityLevel void   )  [protected, virtual]
 

Called when Quality level changes. We do nothing currently.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/4/93

Reimplemented from RenderRegion.

Definition at line 950 of file osrndrgn.cpp.

00951 {
00952 }

void OSRenderRegion::SetSolidColours BOOL  SetSolid  )  [virtual]
 

Allows the dithering of colours to be turned off so they look the same using GDraw as they do with the GDI. In OSRenderRegions, this causes any attached GBrush technology to drop into/out of solid colour mode.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/5/95
Parameters:
SetSolid - TRUE to turn off dithering of colours [INPUTS]

Reimplemented from RenderRegion.

Definition at line 1788 of file osrndrgn.cpp.

01789 {
01790     if (GDrawBrush.Available())
01791         GDrawBrush.SetSolidColours(SetSolid);
01792 }

BOOL OSRenderRegion::Split INT32  Px0,
INT32  Py0,
INT32  Px1,
INT32  Py1,
INT32  Px2,
INT32  Py2,
INT32  Px3,
INT32  Py3,
INT32  Flatness
[protected]
 

Splits a bezier curve into two halves, and flattens each half. Scope: Private.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/6/93
Parameters:
Many INT32s - These are the x and y coords for the 4 control points of [INPUTS] a bezier Flatness - the flatness of the curve
Returns:
TRUE if bezier was successfully split and flattened to specified flatness; FALSE if buffer overflow occurred

Definition at line 3126 of file osrndrgn.cpp.

03129 {
03130 
03131     // Calculate the first half of the curve
03132     INT32 lx0 = Px0;
03133     INT32 ly0 = Py0;
03134     INT32 lx1 = (Px0 + Px1)/2;
03135     INT32 ly1 = (Py0 + Py1)/2;
03136     INT32 lx2 = (Px0 + 2*Px1 + Px2)/4;
03137     INT32 ly2 = (Py0 + 2*Py1 + Py2)/4;
03138     INT32 lx3 = (Px0 + 3*Px1 + 3*Px2 + Px3)/8;
03139     INT32 ly3 = (Py0 + 3*Py1 + 3*Py2 + Py3)/8;
03140 
03141     // Calculate the second half of the curve
03142     INT32 rx0 = lx3;
03143     INT32 ry0 = ly3;
03144     INT32 rx1 = (Px1 + 2*Px2 + Px3)/4;
03145     INT32 ry1 = (Py1 + 2*Py2 + Py3)/4;
03146     INT32 rx2 = (Px2 + Px3)/2;
03147     INT32 ry2 = (Py2 + Py3)/2;
03148     INT32 rx3 = Px3;
03149     INT32 ry3 = Py3;
03150 
03151     if (InsertPos >= SIZEOF_POLYLINE_BUFFER)
03152         return FALSE;                                       // stop recursion when buffer fills
03153 
03154     // Recurse for first half of curve
03155     if (!Bezier(lx0,ly0, lx1,ly1, lx2,ly2, lx3,ly3, Flatness))
03156         // Failure - buffer overflow
03157         return FALSE;
03158 
03159     if (InsertPos >= SIZEOF_POLYLINE_BUFFER)
03160         return FALSE;                                       // stop recursion when buffer fills
03161 
03162     // Recurse for second half of curve
03163     return Bezier(rx0,ry0, rx1,ry1, rx2,ry2, rx3,ry3, Flatness);
03164 }

BOOL OSRenderRegion::StartRender void   )  [virtual]
 

Initialises an OSRenderRegion for rendering.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/5/93
See also:
OSRenderRegion::StopRender()

Reimplemented from RenderRegion.

Definition at line 1624 of file osrndrgn.cpp.

01625 {
01626     // Call base class first
01627     if (!RenderRegion::StartRender())
01628         return FALSE;
01629 
01630     ENSURE(RenderDC != NULL,"StartRender Called when DC was Invalid");
01631 
01632     // Check that Initialise hasn't been called already
01633     ENSURE(RenderFlags.Rendering == FALSE, "Initialise called whilst already rendering");
01634     TRACEUSER("Gavin",_T("OSRenderRegion::StartRender - RenderFlags.Rendering = TRUE;\n"));
01635     RenderFlags.Rendering = TRUE;
01636 
01637     PixelScale = RenderView->GetPixelWidth();
01638 
01639     InitClipping();
01640     InitAttributes();
01641 
01642     if (RFlags.UsePalette)
01643         OldPalette = PaletteManager::StartPaintPalette(RenderDC);
01644 
01645     GDrawBrush.Start();
01646 
01647 #if defined(_DEBUG) && defined(__WXMSW__)
01648 // **** DEBUG BODGE - Make GDI redraw everything immediately
01649 // instead of buffering stuff, so we can see exactly when stuff goes wrong
01650 GdiSetBatchLimit(1);
01651 #endif
01652 
01653     return TRUE;
01654 }

BOOL OSRenderRegion::StopRender void   )  [virtual]
 

Stops the rendering of a OSRenderRegion, saving it's current renderstate so that rendering can continue where it left off, later on. If the RenderState passed is NULL then the RenderRegion will be unlinked from the list and will then delete itself.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/5/93
Parameters:
RenderState is a Node* pointing at the current rendering node in the tree, [INPUTS] or NULL if all objects rendered.
See also:
OSRenderRegion::StartRender()

Implements RenderRegion.

Definition at line 1672 of file osrndrgn.cpp.

01673 {
01674 // ************************************************************
01675 // Some Debug code to plot the clipping rectangle
01676 #if 0
01677     {
01678         TRACE( _T("OSRR# DebugClipRect = (%d, %d) - (%d, %d)\n"), CurrentClipRect.lo.x, CurrentClipRect.lo.y, CurrentClipRect.hi.x, CurrentClipRect.hi.y);
01679         DocRect TempRect(CurrentClipRect);
01680         TempRect.Inflate(-GetScaledPixelWidth());
01681         TRACE( _T("OSRR# Filling = (%d, %d) - (%d, %d)\n"), TempRect.lo.x, TempRect.lo.y, TempRect.hi.x, TempRect.hi.y);
01682         Path ClipPath;
01683         ClipPath.Initialise();
01684         ClipPath.CreatePathFromDocRect(&TempRect);
01685 
01686         SaveContext();
01687         SetLineColour(COLOUR_TRANS);
01688         SetFillColour(COLOUR_RED);
01689         DrawPath(&ClipPath);
01690         RestoreContext();
01691     }
01692 #endif
01693 #if 0
01694     {
01695         SaveContext();
01696         SetLineColour(COLOUR_TRANS);
01697         SetFillColour(COLOUR_BLUE);
01698 
01699         DocRect SmallRect(750, 750, 1500, 1500);
01700         Path ThePath;
01701         ThePath.Initialise();
01702         ThePath.CreatePathFromDocRect(&SmallRect);
01703 
01704         DrawPath(&ThePath);
01705         ThePath.Translate(50, 1500);
01706         DrawPath(&ThePath);
01707         ThePath.Translate(50, 1500);
01708         DrawPath(&ThePath);
01709         ThePath.Translate(50, 1500);
01710         DrawPath(&ThePath);
01711         ThePath.Translate(50, 1500);
01712         DrawPath(&ThePath);
01713         ThePath.Translate(50, 1500);
01714         DrawPath(&ThePath);
01715         ThePath.Translate(50, 1500);
01716         DrawPath(&ThePath);
01717         ThePath.Translate(50, 1500);
01718         DrawPath(&ThePath);
01719         ThePath.Translate(50, 1500);
01720         DrawPath(&ThePath);
01721         ThePath.Translate(50, 1500);
01722         DrawPath(&ThePath);
01723         ThePath.Translate(50, 1500);
01724         DrawPath(&ThePath);
01725         ThePath.Translate(50, 1500);
01726         DrawPath(&ThePath);
01727         ThePath.Translate(50, 1500);
01728         DrawPath(&ThePath);
01729         ThePath.Translate(50, 1500);
01730         DrawPath(&ThePath);
01731         ThePath.Translate(50, 1500);
01732         DrawPath(&ThePath);
01733         ThePath.Translate(50, 1500);
01734         DrawPath(&ThePath);
01735 
01736         RestoreContext();
01737     }
01738 #endif
01739 // ************************************************************
01740 
01741     // Check that Initialise was called
01742     ENSURE(RenderFlags.Rendering, "DeInitialise called before Initialise");
01743 
01744     DeInitClipping();
01745     DeInitAttributes();
01746 
01747     if (OldPalette)
01748     {
01749         PaletteManager::StopPaintPalette(RenderDC, OldPalette);
01750         OldPalette = NULL;
01751     }
01752 
01753     // Clean out the Fuzzy Rectangles
01754     InnerRect.MakeEmpty();
01755     OuterRect.MakeEmpty();
01756 
01757     TRACEUSER("Gavin",_T("OSRenderRegion::StopRender - RenderFlags.Rendering = FALSE;\n"));
01758     RenderFlags.Rendering = FALSE;
01759 
01760     GDrawBrush.Stop();
01761 
01762     if (SepTables != NULL)
01763     {
01764         CCFree(SepTables);
01765         SepTables = NULL;
01766     }
01767 
01768     return TRUE;
01769 }

BOOL OSRenderRegion::StrokeProperly Path const  ) 
 

Definition at line 2700 of file osrndrgn.cpp.

02701 {
02702 
02703     const INT32 Flatten = ScaledPixelWidth/2;
02704 
02705     DashType* pDashRec = NULL;
02706     DashType GavinDash;
02707 
02708     // Don't do it if we have transparent stroke colour
02709     DocColour Col = RR_STROKECOLOUR();
02710     if (Col.IsTransparent())
02711         return TRUE;
02712 
02713     // Don't do dash patten if there isn't one, or if the line has zero width.
02714     if ((RR_DASHPATTERN().Elements == 0) || (RR_LINEWIDTH() == 0))
02715     {
02716         // No dash pattern
02717         pDashRec = &GavinDash;
02718         MakeDashType(RR_DASHPATTERN(), pDashRec);
02719     }
02720     else
02721     {
02722         // Dash pattern - convert to Gavin-ness...
02723         MILLIPOINT Width = RR_LINEWIDTH();
02724         DashRec &DashPattern = RR_DASHPATTERN();
02725 
02726         if ((RRQuality.GetLineQuality() >= Quality::FullLine) && DashPattern.Elements > 0)
02727         {
02728             INT32 Length = DashPattern.Elements;
02729 
02730             if (Length > 8) Length = 8;
02731 
02732             BOOL DoScale = DashPattern.ScaleWithLineWidth;
02733             FIXED16 Scale = DoScale ? (double(Width) / double(DashPattern.LineWidth)) : 1;
02734 
02735             GavinDash.Length = Length;
02736             GavinDash.Offset = LongMulFixed16(DashPattern.DashStart, Scale);
02737 
02738             for (INT32 el = 0; el < Length; el++)
02739             {
02740                 GavinDash.Array[el] = LongMulFixed16(DashPattern.ElementData[el], Scale);
02741             }
02742 
02743             pDashRec = &GavinDash;
02744         }
02745     }
02746 
02747     INT32 Result = GRenderRegion::StrokePathToPath( DrawPath->GetCoordArray(),
02748                                     DrawPath->GetVerbArray(),
02749                                     DrawPath->GetNumCoords(),
02750                                     ConvPoints,
02751                                     ConvVerbs,
02752                                     sizeof(ConvVerbs),
02753                                     FALSE,
02754                                     RR_LINEWIDTH(),
02755                                     Flatten,
02756                                     RR_STARTCAP(),
02757                                     RR_JOINTYPE(),
02758                                     pDashRec );
02759     if (Result>0)
02760     {
02761         // Gavin has converted to another path - lets flatten & render that
02762 
02763         // switch filling colour to lines
02764         wxBrush NewBrush;
02765         #if TEST_MANUAL_LINES
02766         // for debugging, lets have a nice red pen and no fill
02767         NewBrush.CreateStockObject( NULL_BRUSH );
02768         wxPen DPen(wxBLACK,0);
02769         wxPen DOldPen = GetPen();
02770         RenderDC->SetPen( &DPen );
02771         #else
02772         // no quality checks here cos we only do this for high quality
02773 //      LOGBRUSH BrushType;
02774 //      CalcLogBrush( &BrushType, RR_STROKECOLOUR() );
02775 //      NewBrush.CreateBrushIndirect( &BrushType );
02776         CalcLogBrush(&NewBrush,RR_STROKECOLOUR());
02777         #endif
02778         wxBrush OldBrush = RenderDC->GetBrush();
02779         RenderDC->SetBrush(NewBrush);
02780 
02781         // we whip through Gavin's sub-paths manually so we are less likely to
02782         // run out of memory when flattening them. It also stops PolyPolygon from
02783         // rampantly filling them wrongly. The PointArray will be allocated the first
02784         // time and we leave it alone
02785 
02786         INT32 PathSizeLeft = Result;                        // items in Gavins path
02787         DocCoord* PathSoFar = ConvPoints;
02788         PathVerb* VerbSoFar = ConvVerbs;
02789         INT32 PolySize;                                 // size of this chunk
02790 
02791         while (PathSizeLeft > 0)
02792         {
02793             // flatten little sub-path              
02794             INT32 Read = RawRenderPath( PathSoFar, VerbSoFar, PathSizeLeft, &PolySize, NULL );
02795 
02796             if (Read)
02797             {
02798                 // (We don't bother to try again if GDI fails, as it is extremely unlikely as
02799                 // we are only doing small Gavin sub-paths from the path stroking routines).
02800                 RenderDC->DrawPolygon(PolySize,PointArray,0,0,nFillStyle);      // render it
02801                 PathSoFar += Read;                              // inc pointers etc
02802                 VerbSoFar += Read;
02803                 PathSizeLeft -= Read;
02804                 ENSURE(PathSizeLeft>=0, "Path backwards too far");
02805             }
02806             else
02807             {
02808                 TRACE( _T("RawRenderPath failed\n"));
02809                 break;                      // stop as we don't know how far to continue
02810             }
02811         }
02812         RenderDC->SetBrush( OldBrush );
02813 
02814         #if TEST_MANUAL_LINES
02815         RenderDC->SetPen( DOldPen );
02816         DPen.DeleteObject();
02817         #endif
02818 
02819         return TRUE;
02820     }
02821     else if (Result<0)
02822     {
02823         return FALSE;                               // as Gavin couldn't do it
02824     }
02825     else
02826         return TRUE;                                // no points is not an error
02827 }

DocRect OSRenderRegion::WinRectToDoc const Matrix RenderMatrix,
const WinRect WRect,
const double  dpi
[static]
 

To convert a rectangle in Windows coordinates to a rectangle in Document (spread) coordinates taking account of the destination dpi. Does not need the extra parameters that the above uses. Scope: Static.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
31/08/2004
Parameters:
WinRect is a rectangle in Windows co-ords. [INPUTS] dpi is the resolution of the device we are rendering to
Returns:
Object containing the new rectangle coordinates.

Definition at line 4016 of file osrndrgn.cpp.

04018 {
04019     DocRect dr;
04020 
04021     WinCoord WinLo(WRect.x, WRect.GetBottomEx());
04022     WinCoord WinHi(WRect.GetRightEx(), WRect.y);
04023     OilCoord OilLo = OilCoord(  LongMulFixed16(WinLo.x, 72000L / dpi),
04024                                 -LongMulFixed16(WinLo.y, 72000L / dpi)
04025                                 );
04026     OilCoord OilHi = OilCoord(  LongMulFixed16(WinHi.x, 72000L / dpi),
04027                                 -LongMulFixed16(WinHi.y, 72000L / dpi)
04028                                 );
04029 
04030     Matrix inv = RenderMatrix.Inverse();
04031 
04032     dr.lo.x = MatrixCalc( inv.a, OilLo.x, inv.c, OilLo.y ) + inv.e;
04033     dr.lo.y = MatrixCalc( inv.b, OilLo.x, inv.d, OilLo.y ) + inv.f;
04034     dr.hi.x = MatrixCalc( inv.a, OilHi.x, inv.c, OilHi.y ) + inv.e;
04035     dr.hi.y = MatrixCalc( inv.b, OilHi.x, inv.d, OilHi.y ) + inv.f;
04036 
04037     // RenderMatrix can involve a rotation (but only multiples of 90 degrees), so we swap
04038     // the corners here if necessary
04039     MILLIPOINT Temp;
04040 
04041     if (dr.lo.x > dr.hi.x)
04042     {
04043         Temp = dr.lo.x;
04044         dr.lo.x = dr.hi.x;
04045         dr.hi.x = Temp;
04046     }
04047 
04048     if (dr.lo.y > dr.hi.y)
04049     {
04050         Temp = dr.lo.y;
04051         dr.lo.y = dr.hi.y;
04052         dr.hi.y = Temp;
04053     }
04054 
04055     return dr;
04056 }


Member Data Documentation

RRCaps OSRenderRegion::Caps [protected]
 

Definition at line 420 of file osrndrgn.h.

INT32 OSRenderRegion::CurrentBrush [protected]
 

Definition at line 407 of file osrndrgn.h.

INT32 OSRenderRegion::CurrentPen [protected]
 

Definition at line 406 of file osrndrgn.h.

BOOL OSRenderRegion::DoBetterLines [static]
 

Definition at line 274 of file osrndrgn.h.

EORCacheClass OSRenderRegion::EORCache [static, protected]
 

Definition at line 396 of file osrndrgn.h.

OSRRFontInfo OSRenderRegion::FontInfo [protected]
 

Definition at line 414 of file osrndrgn.h.

GBrush OSRenderRegion::GDrawBrush [protected]
 

Definition at line 386 of file osrndrgn.h.

INT32 OSRenderRegion::HitTestRadius = 3 [static, protected]
 

Allows the user to determine how close a mouse click can be to an object before the object is hit-tested successfully. Measured in pixels. Defaults to 3.

Preference: HitTestRadius Section: Mouse Range: 0 to 10

Definition at line 285 of file osrndrgn.h.

INT32 OSRenderRegion::InsertPos [protected]
 

Definition at line 398 of file osrndrgn.h.

BOOL OSRenderRegion::Metafile [protected]
 

Definition at line 375 of file osrndrgn.h.

wxPoint OSRenderRegion::NewBrushOrg [protected]
 

Definition at line 417 of file osrndrgn.h.

INT32 OSRenderRegion::nFillStyle [protected]
 

Definition at line 403 of file osrndrgn.h.

wxFont* OSRenderRegion::OldFont [protected]
 

Definition at line 412 of file osrndrgn.h.

wxPalette* OSRenderRegion::OldPalette [protected]
 

Definition at line 384 of file osrndrgn.h.

wxRegion* OSRenderRegion::OSClipRegion [protected]
 

Definition at line 383 of file osrndrgn.h.

FIXED16 OSRenderRegion::PixelScale [protected]
 

Definition at line 401 of file osrndrgn.h.

wxPoint OSRenderRegion::PointArray [static, protected]
 

Definition at line 393 of file osrndrgn.h.

wxBrush OSRenderRegion::RenderBrush[2] [protected]
 

Definition at line 409 of file osrndrgn.h.

wxPen OSRenderRegion::RenderPen[2] [protected]
 

Definition at line 408 of file osrndrgn.h.

struct { ... } OSRenderRegion::RFlags [protected]
 

BYTE* OSRenderRegion::SepTables [protected]
 

Definition at line 423 of file osrndrgn.h.

BOOL OSRenderRegion::UsePalette [protected]
 

Definition at line 379 of file osrndrgn.h.

BOOL OSRenderRegion::ValidBrush [protected]
 

Definition at line 378 of file osrndrgn.h.

BOOL OSRenderRegion::ValidPen [protected]
 

Definition at line 377 of file osrndrgn.h.


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