#include <osrndrgn.h>
Inheritance diagram for OSRenderRegion:
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 RenderRegion * | Create (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 |
Definition at line 177 of file osrndrgn.h.
|
Default Destructor for OSRenderRegion Class.
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
Attach an OSRenderRegion to a particular device context. This merely remembers the information - the real work is done by [OS]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 }
|
|
Flattens bezier path into an array of POINTS (for polyline). Scope: Private.
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 }
|
|
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.
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 }
|
|
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 }
|
|
To calculate correct colours when draing in EOR mode. Intended to be called by OSRenderRegion code only (normally SetxxxColur).
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 }
|
|
To calculate a brush object given a Colour. Normally used for brushes to fill things.
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 }
|
|
Adjust the bezier curve flattening according to the resolution of the destination device and the view scale. Scope: Private.
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 }
|
|
Calculates the size of a Pixel in MILLIPOINTS, based on the output DPI but IGNORES the scale factor.
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 }
|
|
Calculates the size of a Pixel in MILLIPOINTS, based on the output DPI and current scale factor.
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 }
|
|
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.
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 }
|
|
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).
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 }
|
|
Creates a new Brush, based on the current fill attributes. Scope: Private.
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 }
|
|
Creates a new Pen, based on the current line attributes. Scope: Private.
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 }
|
|
Deletes the GDI pen and brush objects.
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 }
|
|
Destroys the GDI clipping region object, and unsets the clipping region for our DC.
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 }
|
|
Converts a DocCoord to a OS256 Coord. Used during rendering.
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 }
|
|
Converts a DocCoord to a WinCoord. Used during rendering.
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 }
|
|
Definition at line 307 of file osrndrgn.h. 00309 { return DocRectToWin(RenderView, RenderMatrix, docrect, 00310 leftshift, topshift, 00311 rightshift, bottomshift, MightClip ); }
|
|
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.
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 }
|
|
To convert a rectangle in Doc coordinates to a rectangle in Win coordinates. Scope: Static.
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
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 }
|
|
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.
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 }
|
|
Draw a blob. This is the type of blob that appear round objects to show that they have been selected.
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 }
|
|
Draws a cross in the render region. The cross consists of a vertical line 'Size' millipoints high, and a horizontal line 'Size' millipoints wide.
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 }
|
|
Draws a dashed line between the two points. Uses the technology from 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 }
|
|
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.
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)
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 }
|
|
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.
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 }
|
|
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.
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
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 }
|
|
Renders a Line to the GDI.
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 }
|
|
Plots the bitmap using the mask supplied.
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 }
|
|
Renders a path object to the GDI.
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 }
|
|
Plot a single pixel in a render region.
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
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 }
|
|
Finds the windows origin to plot a bitmap at, so that it's centre will be at the DocCoord specified.
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
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 }
|
|
Flushes the EOR colour cache. Currently called when screen mode changes Scope: Public.
Definition at line 1065 of file osrndrgn.cpp.
|
|
To determine the DocRect of a blob without access to a render region.
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 }
|
|
Fix up crazy wxWindows screen DPI calculation.
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 }
|
|
To determine how much room is needed to plot a bit of text with 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 }
|
|
Allows user to adjust the sensitivity of hit-testing.
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 }
|
|
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.
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 }
|
|
Definition at line 1334 of file osrndrgn.cpp. 01335 { 01336 if (!RFlags.ValidBrush) 01337 SelectNewBrush(); 01338 }
|
|
Definition at line 1328 of file osrndrgn.cpp. 01329 { 01330 if (!RFlags.ValidPen) 01331 SelectNewPen(); 01332 }
|
|
To be called during startup. Reads preferences. Scope: Static.
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 }
|
|
Sets up a default GDI pen and brush for rendering, and calculates the Brush origin for aligned fill patterns. Scope: Private.
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 }
|
|
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.
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 }
|
|
Initialise the device specific mechanisms for this render region.
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 }
|
|
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 }
|
|
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 }
|
|
Converts a value in MilliPoints into a GDI Logical value. IT ASSUMES A MM_TEXT MAPPING MODE AT PRESENT. Scope: Private.
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 }
|
|
Low level primitive for rendering paths without GDI32. Note that PointArray should be freed by the caller upon completion.
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 }
|
|
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 }
|
|
Render bitmap fills clipped through a path. BODGED to simple plot the bitmap. Scope: Public.
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 }
|
|
Render a character, using the specified transform and current attributes in the render region.
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 }
|
|
Renders the path with a gradient fill.
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 }
|
|
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.
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 }
|
|
Render grad fills to GDI devices using whatever means available. Scope: Public.
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 }
|
|
Renders the path with a gradient fill.
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 }
|
|
Renders a path to the GDI. Can recurse in the case of arrow heads. Scope: Private.
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 }
|
|
Renders a path using Win32 GDI. Causes an ENSURE on Win16 as should never be called. Scope: Private.
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 }
|
|
Renders the path with a gradient fill.
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 }
|
|
Renders the path with a gradient fill.
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 }
|
|
Renders a three colour gradient fill to a Windows DC.
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
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 }
|
|
To set a complex clip path. This clip is pretty temporary and should be reset afterwards using OSClipRegion before anything much else is done.
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 }
|
|
When a fill attribute is changed, this functions is called to create a new brush to mirror the new attribute value. Scope: Private.
Reimplemented from RenderRegion. Definition at line 935 of file osrndrgn.cpp.
|
|
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).
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...)
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 }
|
|
When a line attribute is changed, this functions is called to create a new pen to mirror the new attribute value. Scope: Private.
Reimplemented from RenderRegion. Definition at line 917 of file osrndrgn.cpp.
|
|
Sets the current drawing mode. Scope: Private.
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 }
|
|
Called when Quality level changes. We do nothing currently.
Reimplemented from RenderRegion. Definition at line 950 of file osrndrgn.cpp.
|
|
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.
Reimplemented from RenderRegion. Definition at line 1788 of file osrndrgn.cpp. 01789 { 01790 if (GDrawBrush.Available()) 01791 GDrawBrush.SetSolidColours(SetSolid); 01792 }
|
|
Splits a bezier curve into two halves, and flattens each half. Scope: Private.
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 }
|
|
Initialises an OSRenderRegion for rendering.
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 }
|
|
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.
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 }
|
|
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 }
|
|
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.
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 }
|
|
Definition at line 420 of file osrndrgn.h. |
|
Definition at line 407 of file osrndrgn.h. |
|
Definition at line 406 of file osrndrgn.h. |
|
Definition at line 274 of file osrndrgn.h. |
|
Definition at line 396 of file osrndrgn.h. |
|
Definition at line 414 of file osrndrgn.h. |
|
Definition at line 386 of file osrndrgn.h. |
|
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. |
|
Definition at line 398 of file osrndrgn.h. |
|
Definition at line 375 of file osrndrgn.h. |
|
Definition at line 417 of file osrndrgn.h. |
|
Definition at line 403 of file osrndrgn.h. |
|
Definition at line 412 of file osrndrgn.h. |
|
Definition at line 384 of file osrndrgn.h. |
|
Definition at line 383 of file osrndrgn.h. |
|
Definition at line 401 of file osrndrgn.h. |
|
Definition at line 393 of file osrndrgn.h. |
|
Definition at line 409 of file osrndrgn.h. |
|
Definition at line 408 of file osrndrgn.h. |
|
|
|
Definition at line 423 of file osrndrgn.h. |
|
Definition at line 379 of file osrndrgn.h. |
|
Definition at line 378 of file osrndrgn.h. |
|
Definition at line 377 of file osrndrgn.h. |