#include <psdc.h>
Inheritance diagram for PSPrintDC:
Public Member Functions | |
PSPrintDC (CNativeDC *pDC) | |
Initialise a DC for printing PostScript. | |
~PSPrintDC () | |
Clean up the fonts in the DC. | |
virtual BOOL | OutputNewLine () |
Causes a new line to be started in the PostScript stream. | |
virtual BOOL | OutputToken (TCHAR *) |
Outputs a string token to the EPS file. | |
virtual BOOL | OutputDirect (BYTE *, INT32) |
Send bytes directly to the PostScript stream with no alteration or padding. Used for sending binary/hex data to stream. NB. The data output must NOT affect the rendering context set up by GDI in any way, as this function does not preserve that context (it cannot because it does not change the data passed in in any way). | |
virtual BOOL | OutputCoord (DocCoord &, EPSAccuracy Accuracy=ACCURACY_NORMAL) |
Write out a coordinate x,y pair to the export file, automatically converting from spread coordinates to the user space coordinate system. User space is the coordinate system used for PostScript files. GDI sets up the CTM so that 1 user space unit = 1 device unit, so all we do is use the rendering matrix to convert to Windows co-ordinates and output this directly at 0dp accuracy (because a fractional user space value would equate to a fractional device pixel, which has no effect on output). | |
virtual BOOL | OutputUserSpaceValue (MILLIPOINT, EPSAccuracy Accuracy=ACCURACY_NORMAL) |
Output a 'user space' value to the device context. User space is the coordinate system used for PostScript files. GDI sets up the CTM so that 1 user space unit = 1 device unit, so all we do is use the rendering matrix to convert to Windows co-ordinates and output this directly at 0dp accuracy (because a fractional user space value would equate to a fractional device pixel, which has no effect on output). | |
void | SetDCTransforms (Matrix RenderMatrix, View *pView) |
Inform the DC how to transform user space values when performing output via OutputCoord. and OutputUserSpaceValue(). | |
WinCoord | TransformCoord (const DocCoord &) |
Transform a DocCoord to a WinCoord, using this DC's transformations, as set up by SetDCTransforms(). | |
void | AttachRenderRegion (PrintPSRenderRegion *pRegion) |
void | DetachRenderRegion () |
BOOL | StartOSOutput () |
Restore the PostScript DC to the context expected by the host OS (GDI), so we can use OS (GDI) functions. You must call EndOSOutput() before calling any Camelot rendering functions. There may be nested calls to this function. | |
BOOL | EndOSOutput () |
Inform the DC that we have finished doing GDI output, and so we should prepare the DC for Camelot PS commands (this is deferred until we actually do some output on the stream). | |
BOOL | FlushDC () |
Tidy up the PostScript DC and reinstate the GDI context if necessary. Should be called when printing is finished. (Won't cause problems if called more often - just more output). | |
BOOL | FlushPSBuffer () |
Flushes the buffer of pending PostScript data to the PostScript device. | |
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. | |
BOOL | SetClipping (BOOL NewState) |
Set the use of a clip region. | |
BOOL | OutputPSClipping () |
Set the use of a clip region. | |
Protected Member Functions | |
BOOL | MakeRoomInBuffer (INT32) |
Make sure there is enough room in the PostScript buffer to add the specified number of bytes to the stream. If not, the buffer is flushed to the device. | |
void | WritePSchar (char *pBuf, INT32 nBytes) |
Writes nBytes of TCHAR to the output stream. Uses Buffer.chardata as a scratch area. Max of MAX_PSBUF can be written at a time. | |
void | WritePSTCHAR (TCHAR *pBuf, INT32 nBytes) |
Writes nBytes of TCHAR to the output stream. Uses Buffer.chardata as a scratch area. Max of MAX_PSBUF can be written at a time. | |
Protected Attributes | |
PassThruBuffer | Buffer |
Matrix | RenderMatrix |
MILLIPOINT | PixelSize |
View * | pView |
INT32 | SafeToUseGDI |
BOOL | StartOfPage |
BOOL | GDIContextIsCurrent |
BOOL | UsePSLevelClipping |
PSDCFontInfo | FontInfo |
PrintPSRenderRegion * | pPSRegion |
Definition at line 162 of file psdc.h.
|
Initialise a DC for printing PostScript.
Definition at line 149 of file psdc.cpp. 00149 : KernelDC(pDC, RENDERTYPE_PRINTER_PS) 00150 { 00151 // Initialise the buffer to being empty. 00152 Buffer.nCount = 0; 00153 Buffer.Data[0] = 0; 00154 00155 // No view yet 00156 pView = NULL; 00157 00158 // We haven't set up the Camelot context yet, and no-one has asked to do any GDI 00159 // output yet. 00160 GDIContextIsCurrent = TRUE; 00161 SafeToUseGDI = 0; 00162 00163 // Once per page 00164 StartOfPage = TRUE; 00165 00166 // No fonts yet 00167 FontInfo.pRenderFont = NULL; 00168 FontInfo.pOldFont = NULL; 00169 00170 // No render region yet. 00171 pPSRegion = NULL; 00172 00173 // Suppress the output of a postscript clipping region 00174 UsePSLevelClipping = FALSE; 00175 00176 }
|
|
Clean up the fonts in the DC.
Definition at line 189 of file psdc.cpp. 00190 { 00191 // Deselect the normal rendering font from the DC 00192 if (FontInfo.pRenderFont != NULL) 00193 { 00194 GetDC()->SetFont(*FontInfo.pOldFont); 00195 FontInfo.pOldFont = NULL; 00196 delete FontInfo.pRenderFont; 00197 FontInfo.pRenderFont = NULL; 00198 } 00199 }
|
|
Definition at line 181 of file psdc.h. 00182 { pPSRegion = pRegion; }
|
|
Definition at line 183 of file psdc.h.
|
|
Inform the DC that we have finished doing GDI output, and so we should prepare the DC for Camelot PS commands (this is deferred until we actually do some output on the stream).
Definition at line 831 of file psdc.cpp. 00832 { 00833 // Just decrement counter - we do the other stuff in OutputToken(). 00834 SafeToUseGDI--; 00835 ERROR2IF(SafeToUseGDI < 0, FALSE, "Unbalanced call to Start/EndOSOutput() functions!"); 00836 00837 // All ok 00838 return TRUE; 00839 }
|
|
Tidy up the PostScript DC and reinstate the GDI context if necessary. Should be called when printing is finished. (Won't cause problems if called more often - just more output).
Definition at line 622 of file psdc.cpp. 00623 { 00624 // Restore OS context - just pretend we want to do some OS output 00625 //if (!StartOSOutput()) 00626 // Error 00627 // return FALSE; 00628 00629 // Clear out the buffer. 00630 if (!FlushPSBuffer()) 00631 // Error 00632 return FALSE; 00633 00634 // Go back to using Camelot context 00635 // (NB this is deferred - it will only be reinstated if we do Camelot output) 00636 //return EndOSOutput(); 00637 return TRUE; 00638 }
|
|
Flushes the buffer of pending PostScript data to the PostScript device.
Definition at line 468 of file psdc.cpp. 00469 { 00470 if (Buffer.nCount <= 0) 00471 // Nothing to flush 00472 return TRUE; 00473 00474 // Get system to flush any of its data first. 00475 // (don't have to do anything here) 00476 00477 if (Buffer.nCount>MAX_PSBUF) // MAX_PSBUF itself is legal 00478 { 00479 Buffer.nCount=MAX_PSBUF; 00480 ERROR3("Postscript buffer overrun"); 00481 } 00482 00483 // Ensure the buffer is zero terminated 00484 WritePSTCHAR(Buffer.Data, Buffer.nCount); 00485 00486 // Clear out buffer 00487 Buffer.nCount = 0; 00488 Buffer.Data[0] = 0; 00489 00490 return TRUE; 00491 }
|
|
Make sure there is enough room in the PostScript buffer to add the specified number of bytes to the stream. If not, the buffer is flushed to the device.
Definition at line 589 of file psdc.cpp. 00590 { 00591 if (nBytesRequired >= MAX_PSBUF) 00592 { 00593 // Can't ever do that many bytes! 00594 ERROR2(FALSE, "Too many bytes asked for in PSPrintDC::MakeRoomInBuffer()"); 00595 } 00596 00597 // Do we need to flush? 00598 if (nBytesRequired > (MAX_PSBUF - Buffer.nCount)) 00599 // Yes 00600 return FlushPSBuffer(); 00601 00602 // All ok if we get here 00603 return TRUE; 00604 }
|
|
Write out a coordinate x,y pair to the export file, automatically converting from spread coordinates to the user space coordinate system. User space is the coordinate system used for PostScript files. GDI sets up the CTM so that 1 user space unit = 1 device unit, so all we do is use the rendering matrix to convert to Windows co-ordinates and output this directly at 0dp accuracy (because a fractional user space value would equate to a fractional device pixel, which has no effect on output).
Reimplemented from KernelDC. Definition at line 705 of file psdc.cpp. 00706 { 00707 // We need a view to scale the coords. 00708 ERROR2IF(pView == NULL, FALSE, "No view attached to PostScript DC!"); 00709 00710 WinCoord PSCoord = TransformCoord(Coord); 00711 00712 // Output to PostScript stream. 00713 BOOL Ok = (OutputValue(PSCoord.x) && OutputValue(PSCoord.y)); 00714 00715 return Ok; 00716 }
|
|
Send bytes directly to the PostScript stream with no alteration or padding. Used for sending binary/hex data to stream. NB. The data output must NOT affect the rendering context set up by GDI in any way, as this function does not preserve that context (it cannot because it does not change the data passed in in any way).
Reimplemented from KernelDC. Definition at line 429 of file psdc.cpp. 00430 { 00431 // This could be anything, so we flush the buffer first, and then write directly 00432 // to stream. 00433 if (!FlushPSBuffer()) 00434 // Error occured in buffer handling 00435 return FALSE; 00436 00437 // Copy data to our buffer - do it in stages if necessary 00438 while (nBytes > 0) 00439 { 00440 // Work out how much we can send this time around. 00441 INT32 nBytesToSend = min(nBytes, MAX_PSBUF); 00442 00443 WritePSchar((char *)Buf, nBytesToSend); 00444 00445 // Update variables to reflect sending this number of bytes 00446 nBytes -= nBytesToSend; 00447 Buf += nBytesToSend; 00448 } 00449 00450 // All ok 00451 return TRUE; 00452 }
|
|
Causes a new line to be started in the PostScript stream.
Reimplemented from KernelDC. Definition at line 217 of file psdc.cpp. 00218 { 00219 static TCHAR NewLine[] = _T("\n"); 00220 00221 // Make sure we have enough room in the buffer 00222 if (!MakeRoomInBuffer(camStrlen(NewLine))) 00223 // Error occured in buffer handling. 00224 return FALSE; 00225 00226 // Add newline to buffer 00227 camStrcat(Buffer.Data, NewLine); 00228 Buffer.nCount += camStrlen(NewLine); 00229 00230 // Update line width record. 00231 LineWidth = 0; 00232 00233 // Success 00234 return TRUE; 00235 }
|
|
Set the use of a clip region.
Definition at line 1109 of file psdc.cpp. 01110 { 01111 if (UsePSLevelClipping) 01112 { 01113 // DocRect theRect = pPSRegion->CurrentClipRect; 01114 01115 // BODGE - Currently need to deflate this clip region 01116 // by the bleed size. This only works because we know we are not 01117 // stripping but rendering complete pages. Hence this clip rectangle represents 01118 // the page with bleed applied in the document area. We need to output a clip 01119 // rectangle which will clip all objects beyond the bleed. This is quite a complex process. 01120 01121 PrintView* pView = (PrintView*)(pPSRegion->GetRenderView()); 01122 ERROR2IF(pView==NULL,FALSE,"No printview in this PS render region"); 01123 ERROR3IF(!pView->IsKindOf(CC_RUNTIME_CLASS(PrintView)), "Not a PrintView in PSPrintDC output token"); 01124 01125 // Get the current patch clip rectangle 01126 DocRect theRect = pView->PatchInfo.GetClipRect(FALSE,FALSE); 01127 01128 // read the regions render matrix. 01129 Matrix RMatrix = pPSRegion->GetMatrix(); 01130 Matrix IMatrix = RMatrix.Inverse(); 01131 RMatrix.transform(&theRect.lo); 01132 RMatrix.transform(&theRect.hi); 01133 PrintView::CorrectRotatedRectangle((Rect*)&theRect); 01134 pView->PatchInfo.InflateRectBy(&theRect,TRUE,FALSE); 01135 IMatrix.transform(&theRect.lo); 01136 IMatrix.transform(&theRect.hi); 01137 PrintView::CorrectRotatedRectangle((Rect*)&theRect); 01138 01139 // And finally write the clip region out 01140 if (!pPSRegion->WriteClipRegion(this, theRect)) 01141 return FALSE; 01142 } 01143 return TRUE; 01144 }
|
|
Outputs a string token to the EPS file.
Reimplemented from KernelDC. Definition at line 252 of file psdc.cpp. 00253 { 00254 #ifndef STANDALONE 00255 // Should we re-instate the Camelot context? 00256 if (!SafeToUseGDI && GDIContextIsCurrent) 00257 { 00258 // Yes - just save the context (so we can restore GDI's context) and put our 00259 // dictionary on the dict stack. 00260 // Must do this first or else we get an infinite loop! 00261 GDIContextIsCurrent = FALSE; 00262 00263 // Code by Mike 00264 // We need to work out where we are in order to render the correct bits of postscript header. 00265 BOOL AtStartOfPaper = FALSE; 00266 BOOL AtStartOfPatch = StartOfPage; 00267 StartOfPage=FALSE; 00268 00269 // Work out whether this is the first call to output token for this page 00270 if (AtStartOfPatch) 00271 { 00272 PrintView* pView = (PrintView*)(pPSRegion->GetRenderView()); 00273 ERROR2IF(pView==NULL,FALSE,"No printview in this PS render region"); 00274 ERROR3IF(!pView->IsKindOf(CC_RUNTIME_CLASS(PrintView)), "Not a PrintView in PSPrintDC output token"); 00275 AtStartOfPaper = ((pView->PatchInfo.PatchNumber)==1); 00276 } 00277 00278 OutputNewLine(); 00279 00280 // ok now check our flag. This may be the first time we've 00281 // been called from this PSPrintDC construction. If so we 00282 // need to output page header stuff. 00283 if (AtStartOfPaper) 00284 { 00285 // We need to get the name of the output plate here 00286 // this might be a bit tricky! Na easy... 00287 if (!pPSRegion->WritePlateName(this)) 00288 return FALSE; 00289 } 00290 00291 // save the graphics state 00292 OutputToken(_T("save")); 00293 OutputNewLine(); 00294 00295 // wxWidgets and Windows both use (0,0) to mean the top left hand origin of the 00296 // paper in logical coordinates. However, they do something rather different in 00297 // terms of physical coordinates. What windows printer drivers do (and thus what 00298 // Camelot expects) is use a postcript page transformation matrix to invert the 00299 // page, and for the postscript to be written in native DPI coordinates with the 00300 // origin at the TOP left of the page. What wxWidgets does is write its postscript 00301 // in the more natural way with the origin at the BOTTOM of the page, and handle 00302 // the coordinate inversion wihin wxWidgets. 00303 // 00304 // Note that this means while our internally generated PS expects a transformation 00305 // matrix that flips the Y coordinate (as the windows drivers produce). We 00306 // can't change the transformation matrix in the prologue because this would 00307 // affect wxWidgets output (and also it's technically difficult to do). We can't 00308 // change our own rendering matrix (so we produce the right coordinates) because 00309 // lots of things seem to explode with a matrix which flips the Y access (negative 00310 // scale factors etc.). We can't just change the coordinates we write because 00311 // other things (e.g. bitmaps) use the native render matrix. So what we do is 00312 // temporarily invert the PS transformation matrix during the period of our output. 00313 // This seems arcane but reasonably extensive research suggests it is the best 00314 // way forward. It's restored before we do any OS output. 00315 00316 TCHAR flipbuf[256]; 00317 INT32 translate = GetDC()->GetSize().GetHeight(); 00318 camSprintf(flipbuf, _T("0 %d translate 1 -1 scale"), translate); 00319 OutputToken(flipbuf); 00320 OutputNewLine(); 00321 00322 // Now start plate writing etc. 00323 00324 if (!pPSRegion->WritePhotoNegative(this)) 00325 return FALSE; 00326 00327 if (AtStartOfPaper) 00328 { 00329 // We need to fill the page with black if the plate says we 00330 // need to negate everything. 00331 if (!pPSRegion->WriteRenderPaper(this)) 00332 return FALSE; 00333 } 00334 00335 // Write out our procset. 00336 if (!pPSRegion->WriteProlog(this)) 00337 // Error 00338 return FALSE; 00339 00340 OutputNewLine(); 00341 OutputToken(_T("XaraStudio1Dict begin")); 00342 OutputNewLine(); 00343 00344 // Now output the setscreen function for this plate 00345 if (!pPSRegion->WritePlateScreen(this)) 00346 return FALSE; 00347 00348 // try to write out the sep tables if we need them 00349 if (!pPSRegion->WriteSepTables(this)) 00350 return FALSE; 00351 00352 // export any clip region we might need. 00353 if (!OutputPSClipping()) 00354 return FALSE; 00355 } 00356 00357 // Special tokens 00358 // static TCHAR Space = _T(' '); 00359 // static TCHAR NewLine[] = _T("\n"); 00360 00361 if (LineWidth > 70) 00362 { 00363 // Line is getting INT32 - wrap around 00364 OutputNewLine(); 00365 } 00366 00367 // Pad with a space (unless at the beginning of the line) 00368 if (LineWidth > 0) 00369 { 00370 // Make sure we have enough room in the buffer 00371 if (!MakeRoomInBuffer(1)) 00372 // Error occured in buffer handling. 00373 return FALSE; 00374 00375 // Add space to buffer 00376 camStrcat(Buffer.Data, _T(" ")); 00377 Buffer.nCount++; 00378 00379 // Update line width record. 00380 LineWidth++; 00381 } 00382 00383 // Write the token out to the file 00384 INT32 Len = camStrlen(Str); 00385 00386 // Make sure we have enough room in the buffer 00387 if (!MakeRoomInBuffer(Len)) 00388 // Error occured in buffer handling. 00389 return FALSE; 00390 00391 // Add space to buffer 00392 camStrcat(Buffer.Data, Str); 00393 Buffer.nCount += Len; 00394 00395 // Update line width record. 00396 LineWidth += Len; 00397 00398 // Success 00399 return TRUE; 00400 #else 00401 return FALSE; 00402 #endif 00403 }
|
|
Output a 'user space' value to the device context. User space is the coordinate system used for PostScript files. GDI sets up the CTM so that 1 user space unit = 1 device unit, so all we do is use the rendering matrix to convert to Windows co-ordinates and output this directly at 0dp accuracy (because a fractional user space value would equate to a fractional device pixel, which has no effect on output).
Reimplemented from KernelDC. Definition at line 668 of file psdc.cpp. 00669 { 00670 // We need a view to scale the value. 00671 ERROR2IF(pView == NULL, FALSE, "No view attached to PostScript DC!"); 00672 00673 // Use pixel size to scale to device units. 00674 n /= PixelSize; 00675 00676 // Output as device units 00677 return OutputValue(n); 00678 }
|
|
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 860 of file psdc.cpp. 00862 { 00863 PORTNOTE("printing", "Removed postscript printing of text") 00864 #ifndef EXCLUDE_FROM_XARALX 00865 00866 // Check to see if it is cached 00867 if ((FontInfo.pRenderFont != NULL) && 00868 (FontInfo.Typeface == Typeface) && 00869 (FontInfo.Bold == Bold) && 00870 (FontInfo.Italic == Italic) && 00871 (FontInfo.Width == Width) && 00872 (FontInfo.Height == Height) && 00873 (FontInfo.Rotation == Rotation)) 00874 { 00875 // It is the same as the currently selected/cached font 00876 TRACEUSER( "Tim", _T("Using the cached font\n")); 00877 return TRUE; 00878 } 00879 00880 TRACEUSER( "Tim", _T("Font cache invalid - generating font to use\n")); 00881 00882 // Get ready for GDI operations 00883 if (!StartOSOutput()) 00884 return FALSE; 00885 00886 // Not the cached font - ok, deselect and delete the cached font. 00887 if (FontInfo.pOldFont != NULL) 00888 { 00889 GetDC->SetFont(*FontInfo.pOldFont); 00890 FontInfo.pOldFont = NULL; 00891 } 00892 00893 if (FontInfo.pRenderFont != NULL) 00894 { 00895 delete FontInfo.pRenderFont; 00896 FontInfo.pRenderFont = NULL; 00897 } 00898 00899 // Create the font and select it into the DC 00900 FontInfo.pRenderFont = new wxFont; 00901 if (!FontInfo.pRenderFont) 00902 return FALSE; 00903 00904 // Work out the font weight - bold or normal? 00905 INT32 FontWeight = Bold ? FW_BOLD : FW_NORMAL; 00906 00907 // Get the typeface name of the font 00908 00909 ENUMLOGFONT *pEnumLogFont = FONTMANAGER->GetEnumLogFont(Typeface); 00910 if (pEnumLogFont == NULL) 00911 // Error 00912 return FALSE; 00913 00914 // Work out how big the font is, in logical pixels 00915 FIXED16 fxPixWidth, fxPixHeight; 00916 pView->GetScaledPixelSize(&fxPixWidth, &fxPixHeight); 00917 INT32 FontWidth = (INT32) (Width / fxPixWidth.MakeDouble()); 00918 INT32 FontHeight = (INT32) (Height / fxPixHeight.MakeDouble()); 00919 00920 if (FontHeight == FontWidth) 00921 { 00922 // Aspect ratio is 100% - use width of 0, and the GDI font engine gives us 100% 00923 // ratio automatically 00924 FontWidth = 0; 00925 } 00926 else 00927 { 00928 // Aspect ratio is not 100% - we need to do some clever stuff to work out 00929 // how wide we want the font to be. Because fonts are generally much taller 00930 // than they are wide, we can't just pass in FontWidth directly - we must 00931 // transform it to the correct width. 00932 00933 // BODGETEXT: ideally, we should use a NEWTEXTMETRIC structure here, to work out 00934 // the correct width, but this involves calling EnumLogFontFamily() or 00935 // whatever, which is too slow. As the text code caches the LOGFONT 00936 // for each font, it could also cache the NEWTEXTMETRIC structure, 00937 // which this routine could then use. 00938 // Having said all that, this code seems to work! 00939 00940 // Create the font - the first time is to find out how wide the characters are, 00941 // so we can scale the width correctly. (So we give a width of 0 to get the normal 00942 // width for the given height) 00943 if (FontInfo.pRenderFont->CreateFont(-100, 0, 0, 0, FontWeight, Italic, 00944 FALSE, FALSE, DEFAULT_CHARSET, 00945 OUT_TT_PRECIS, CLIP_TT_ALWAYS, 00946 PROOF_QUALITY, DEFAULT_PITCH | FF_DONTCARE, 00947 pEnumLogFont->elfLogFont.lfFaceName) == 0) 00948 { 00949 // Can't create font - do it as curves 00950 delete FontInfo.pRenderFont; 00951 FontInfo.pRenderFont = NULL; 00952 EndOSOutput(); 00953 return FALSE; 00954 } 00955 00956 if (FALSE)//TRUE) 00957 { 00958 FontInfo.pOldFont = SelectObject(FontInfo.pRenderFont); 00959 00960 // Get the outlines to see how big the font should be... 00961 INT32 Widths[30]; 00962 00963 // First for lower case 00964 GetOutputCharWidth('a', 'z', Widths); 00965 INT32 AveCharWidth = 0; 00966 for (INT32 i = 0; i < 26; i++) 00967 AveCharWidth += Widths[i]; 00968 00969 // Now for upper case 00970 GetOutputCharWidth('A', 'Z', Widths); 00971 for (i = 0; i < 26; i++) 00972 AveCharWidth += Widths[i]; 00973 00974 // Ok, get average width 00975 AveCharWidth /= 52; 00976 00977 // Scale the width by the font's aspect ratio: 00978 00979 // ActualWidth = (RealWidth / Height) * Width 00980 FontWidth = MulDiv(AveCharWidth, FontWidth, 100); 00981 00982 // Select old font back into DC 00983 SelectObject(FontInfo.pOldFont); 00984 } 00985 else 00986 { 00987 // Get the metrics 00988 TEXTMETRIC Metrics; 00989 00990 if (TRUE) //RFlags.Metafile) 00991 { 00992 // Metafile - we need to use the screen DC to do this 00993 CNativeDC *pDesktopDC = CWnd::GetDesktopWindow()->GetDC(); 00994 00995 // Get the metrics 00996 FontInfo.pOldFont = pDesktopDC->SelectObject(FontInfo.pRenderFont); 00997 pDesktopDC->GetTextMetrics(&Metrics); 00998 00999 // Select old font back into screen DC 01000 pDesktopDC->SelectObject(FontInfo.pOldFont); 01001 CWnd::GetDesktopWindow()->ReleaseDC(pDesktopDC); 01002 } 01003 else 01004 { 01005 FontInfo.pOldFont = SelectObject(FontInfo.pRenderFont); 01006 01007 GetTextMetrics(&Metrics); 01008 01009 // Select old font back into DC 01010 SelectObject(FontInfo.pOldFont); 01011 } 01012 01013 // Scale the width by the font's aspect ratio: 01014 01015 // ActualWidth = (RealWidth / Height) * Width 01016 FontWidth = MulDiv(Metrics.tmAveCharWidth, FontWidth, 100); 01017 } 01018 01019 // Delete the font 01020 delete FontInfo.pRenderFont; 01021 01022 // Create the 'proper' font and select it into the DC 01023 TRY 01024 { 01025 FontInfo.pRenderFont = new CFont; 01026 } 01027 CATCH (CMemoryException, e) 01028 { 01029 return FALSE; 01030 } 01031 END_CATCH 01032 } 01033 01034 // Work out the rotation of the font, in tenths of degrees. 01035 INT32 lfRotation; 01036 if (Rotation == FIXED16(0)) 01037 lfRotation = 0; 01038 else 01039 lfRotation = (INT32) ( (Rotation.MakeDouble() * 360.0 * 10.0) / (2 * PI) ); 01040 01041 // Create the font with the correct width and rotation 01042 if (FontInfo.pRenderFont->CreateFont(-FontHeight, FontWidth, lfRotation, 0, 01043 FontWeight, Italic, 01044 FALSE, FALSE, DEFAULT_CHARSET, 01045 OUT_TT_PRECIS, CLIP_TT_ALWAYS, 01046 PROOF_QUALITY, DEFAULT_PITCH | FF_DONTCARE, 01047 pEnumLogFont->elfLogFont.lfFaceName) == 0) 01048 { 01049 // Can't create font (device may not support rotation). 01050 delete FontInfo.pRenderFont; 01051 FontInfo.pRenderFont = NULL; 01052 EndOSOutput(); 01053 return FALSE; 01054 } 01055 01056 // Select the real font into the DC. 01057 FontInfo.pOldFont = SelectObject(FontInfo.pRenderFont); 01058 01059 // Validate the cache 01060 FontInfo.Typeface = Typeface; 01061 FontInfo.Bold = Bold; 01062 FontInfo.Italic = Italic; 01063 FontInfo.Width = Width; 01064 FontInfo.Height = Height; 01065 FontInfo.Rotation = Rotation; 01066 01067 // End of GDI operations 01068 if (!EndOSOutput()) 01069 return FALSE; 01070 01071 // Font created and selected ok 01072 return TRUE; 01073 #else 01074 return FALSE; // hopefully it will print as curves 01075 #endif 01076 }
|
|
Set the use of a clip region.
Definition at line 1090 of file psdc.cpp. 01091 { 01092 BOOL oldstate = UsePSLevelClipping; 01093 UsePSLevelClipping = newstate; 01094 return oldstate; 01095 }
|
|
Inform the DC how to transform user space values when performing output via OutputCoord. and OutputUserSpaceValue().
Definition at line 732 of file psdc.cpp. 00733 { 00734 // Remember these values 00735 RenderMatrix = NewRenderMatrix; 00736 pView = pNewView; 00737 00738 // Get the pixel size from the view 00739 FIXED16 fxPixelWidth, fxPixelHeight; 00740 pView->GetScaledPixelSize(&fxPixelWidth, &fxPixelHeight); 00741 PixelSize = (MILLIPOINT) fxPixelWidth.MakeLong(); 00742 }
|
|
Restore the PostScript DC to the context expected by the host OS (GDI), so we can use OS (GDI) functions. You must call EndOSOutput() before calling any Camelot rendering functions. There may be nested calls to this function.
Definition at line 791 of file psdc.cpp. 00792 { 00793 if ((SafeToUseGDI == 0) && !GDIContextIsCurrent) 00794 { 00795 // We need to restore the GDI context - this involves removing our dictionary 00796 // from the dictionary stack, and calling restore. 00797 if (!OutputToken(_T("end restore")) || !OutputNewLine()) 00798 // Error 00799 return FALSE; 00800 00801 // Flush our buffer so Camelot PS syncs correctly with GDI PS. 00802 if (!FlushPSBuffer()) 00803 // Error 00804 return FALSE; 00805 00806 GDIContextIsCurrent = TRUE; 00807 } 00808 00809 // Increment GDI count 00810 SafeToUseGDI++; 00811 00812 // Ok to use GDI now 00813 return TRUE; 00814 }
|
|
Transform a DocCoord to a WinCoord, using this DC's transformations, as set up by SetDCTransforms().
Definition at line 759 of file psdc.cpp. 00760 { 00761 // Use the rendering matrix of our parent render region to transform 00762 // the co-ordinate to device units before proceeding. 00763 OilCoord NewCoord(Coord.x, Coord.y); 00764 RenderMatrix.transform(&NewCoord); 00765 00766 // Convert to Windows device units. 00767 WinCoord PSCoord = NewCoord.ToWin(pView); 00768 00769 // Return to caller 00770 return PSCoord; 00771 }
|
|
Writes nBytes of TCHAR to the output stream. Uses Buffer.chardata as a scratch area. Max of MAX_PSBUF can be written at a time.
Definition at line 545 of file psdc.cpp. 00546 { 00547 if ((nBytes>MAX_PSBUF) || (nBytes<=0)) 00548 { 00549 ERROR3("Bad PSPrintDC write"); 00550 return; 00551 } 00552 00553 #ifdef _DEBUG 00554 INT32 i; 00555 for (i=0; i<nBytes; i++) 00556 { 00557 if (!pBuf[i]) 00558 { 00559 ERROR3("Zero byte in PS Buffer!"); 00560 break; 00561 } 00562 } 00563 #endif 00564 00565 // Need to copy it so we can safely zero terminate it 00566 memcpy(Buffer.CharData, pBuf, nBytes); 00567 Buffer.CharData[nBytes]=0; // safe as chardata one larger than MAX_PSBUF 00568 ((wxPostScriptDC *)GetDC())->PsPrint(Buffer.CharData); 00569 }
|
|
Writes nBytes of TCHAR to the output stream. Uses Buffer.chardata as a scratch area. Max of MAX_PSBUF can be written at a time.
Definition at line 507 of file psdc.cpp. 00508 { 00509 if ((nBytes>MAX_PSBUF) || (nBytes<=0)) 00510 { 00511 ERROR3("Bad PSPrintDC write"); 00512 return; 00513 } 00514 00515 if (sizeof(TCHAR) == sizeof(char)) 00516 { 00517 WritePSchar((char *)pBuf, nBytes); 00518 return; 00519 } 00520 00521 INT32 i; 00522 for (i=0; i<nBytes; i++) 00523 { 00524 ERROR3IF(!pBuf[i], "Zero byte in PS buffer"); 00525 Buffer.CharData[i]=pBuf[i]; // 1:1 copy 00526 } 00527 00528 Buffer.CharData[nBytes]=0; // safe as chardata one larger than MAX_PSBUF 00529 ((wxPostScriptDC *)GetDC())->PsPrint(Buffer.CharData); 00530 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|