1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-21 10:13:43 +03:00

0022337: V3d_View::Print crashes in OCCT 6.5.0

This commit is contained in:
APL 2011-09-07 07:16:18 +00:00 committed by bugmaster
parent 31b8106853
commit 7edf74fd3d
18 changed files with 1360 additions and 419 deletions

View File

@ -844,6 +844,29 @@ is
end TypeOfColorScaleOrientation; end TypeOfColorScaleOrientation;
---Purpose: Defines the type of color scale orientation ---Purpose: Defines the type of color scale orientation
enumeration PrintAlgo is
PA_STRETCH,
PA_TILE
end PrintAlgo;
---Purpose: Defines print algorithm
-- Aspect_PrintAlgo:
-- 1) PA_STRETCH - Stretch offscreen printing frame
-- if its dimensions are smaller than
-- the printer's printing area dimensions;
-- This algorithm is more reliable as it
-- works on any hardware and is recommended
-- to be used with average printing resolutions,
-- as it more RAM memory dependent than PA_TILE;
-- Stretching is performend using bicubic interpolation
-- algorithm from FreeImage library if OCCT is built
-- with FreeImage support, otherwise Windows API
-- StretchBlt() function in STRETCH_HALFTONE mode
-- is used;
-- 2) PA_TILE - If the offscreen printing frame dimensions
-- are smaller than the printer's printing
-- area dimensions - use multiple printing
-- frames to cover the whole printing area
--------------------------------- ---------------------------------
-- Category: Instantiated classes -- Category: Instantiated classes
--------------------------------- ---------------------------------

View File

@ -66,6 +66,7 @@ uses
TypeOfTriedronPosition from Aspect, TypeOfTriedronPosition from Aspect,
Handle from Aspect, Handle from Aspect,
Display from Aspect, Display from Aspect,
PrintAlgo from Aspect,
AspectLine3d from Graphic3d, AspectLine3d from Graphic3d,
AspectMarker3d from Graphic3d, AspectMarker3d from Graphic3d,
@ -1300,8 +1301,10 @@ is
ACOverLayer : CLayer2d from Aspect; ACOverLayer : CLayer2d from Aspect;
hPrnDC : Handle from Aspect; hPrnDC : Handle from Aspect;
showBackground : Boolean; showBackground : Boolean;
filename : CString) filename : CString;
is deferred; printAlgorithm : PrintAlgo from Aspect = Aspect_PA_STRETCH;
theScaleFactor : Real from Standard = 1.0 )
returns Boolean from Standard is deferred;
---Level: Internal ---Level: Internal
---Purpose: print the contents of all layers of the view to the printer. ---Purpose: print the contents of all layers of the view to the printer.
-- <hPrnDC> : Pass the PrinterDeviceContext (HDC), -- <hPrnDC> : Pass the PrinterDeviceContext (HDC),
@ -1309,6 +1312,13 @@ is
-- (background is white) -- (background is white)
-- else set to TRUE for printing with current background color. -- else set to TRUE for printing with current background color.
-- <filename>: If != NULL, then the view will be printed to a file. -- <filename>: If != NULL, then the view will be printed to a file.
-- <printAlgorithm>: Select print algorithm: stretch, tile.
-- <theScaleFactor>: Scaling coefficient, used internally to scale the
-- printings accordingly to the scale factor selected in the printer
-- properties dialog.
-- Returns Standard_True if the data is passed to the printer, otherwise
-- Standard_False if the print operation failed due to the printer errors,
-- or insufficient system memory available.
---Warning: Works only under Windows. ---Warning: Works only under Windows.

View File

@ -14,10 +14,14 @@
/* Print Methods */ /* Print Methods */
/************************************************************************/ /************************************************************************/
void Graphic3d_GraphicDriver::Print (const Graphic3d_CView& , Standard_Boolean Graphic3d_GraphicDriver::Print (const Graphic3d_CView& ,
const Aspect_CLayer2d& , const Aspect_CLayer2d& ,
const Aspect_CLayer2d& , const Aspect_CLayer2d& ,
const Aspect_Handle , const Aspect_Handle ,
const Standard_Boolean , const Standard_Boolean ,
const Standard_CString ) const { const Standard_CString ,
const Aspect_PrintAlgo ,
const Standard_Real ) const
{
return Standard_False;
} }

View File

@ -247,3 +247,5 @@ OpenGl_ResourceVBO.cxx
OpenGl_ResourceVBO.hxx OpenGl_ResourceVBO.hxx
OpenGl_ResourceTexture.cxx OpenGl_ResourceTexture.cxx
OpenGl_ResourceTexture.hxx OpenGl_ResourceTexture.hxx
OpenGl_PrinterContext.cxx
OpenGl_PrinterContext.hxx

View File

@ -49,6 +49,7 @@ uses
TypeOfTriedronPosition from Aspect, TypeOfTriedronPosition from Aspect,
Handle from Aspect, Handle from Aspect,
Display from Aspect, Display from Aspect,
PrintAlgo from Aspect,
AspectLine3d from Graphic3d, AspectLine3d from Graphic3d,
AspectMarker3d from Graphic3d, AspectMarker3d from Graphic3d,
@ -1208,8 +1209,10 @@ is
ACOverLayer : CLayer2d from Aspect; ACOverLayer : CLayer2d from Aspect;
hPrnDC : Handle from Aspect; hPrnDC : Handle from Aspect;
showBackground : Boolean; showBackground : Boolean;
filename : CString) filename : CString;
is redefined static; printAlgorithm : PrintAlgo from Aspect = Aspect_PA_STRETCH;
theScaleFactor : Real from Standard = 1.0 )
returns Boolean from Standard is redefined static;
---Level: Internal ---Level: Internal
---Purpose: print the contents of all layers of the view to the printer. ---Purpose: print the contents of all layers of the view to the printer.
-- <hPrnDC> : Pass the PrinterDeviceContext (HDC), -- <hPrnDC> : Pass the PrinterDeviceContext (HDC),
@ -1217,6 +1220,17 @@ is
-- (background is white) -- (background is white)
-- else set to TRUE for printing with current background color. -- else set to TRUE for printing with current background color.
-- <filename>: If != NULL, then the view will be printed to a file. -- <filename>: If != NULL, then the view will be printed to a file.
-- <printAlgorithm>: Select print algorithm: stretch, tile.
-- <theScaleFactor>: Scaling coefficient, used internally to scale the
-- printings accordingly to the scale factor selected in the printer
-- properties dialog.
-- Returns Standard_True if the data is passed to the printer, otherwise
-- Standard_False if the print operation failed due to the printer errors,
-- or lack of system memory. This might be related to insufficient memory
-- or some internal errors. All this errors are indicated by the message
-- boxes (on level of OpenGl_GraphicDriver).
-- Warning: This function can reuse FBO assigned to the view
-- Please take it into account if you use it for your purposes;
---Warning: Works only under Windows. ---Warning: Works only under Windows.

View File

@ -18,12 +18,15 @@
/* Print Methods */ /* Print Methods */
/************************************************************************/ /************************************************************************/
void OpenGl_GraphicDriver::Print (const Graphic3d_CView& ACView, Standard_Boolean OpenGl_GraphicDriver::Print
(const Graphic3d_CView& ACView,
const Aspect_CLayer2d& ACUnderLayer, const Aspect_CLayer2d& ACUnderLayer,
const Aspect_CLayer2d& ACOverLayer, const Aspect_CLayer2d& ACOverLayer,
const Aspect_Handle hPrintDC, const Aspect_Handle hPrintDC,
const Standard_Boolean showBackground, const Standard_Boolean showBackground,
const Standard_CString filename ) const const Standard_CString filename,
const Aspect_PrintAlgo printAlgorithm,
const Standard_Real theScaleFactor) const
{ {
#ifdef WNT #ifdef WNT
@ -35,11 +38,12 @@ void OpenGl_GraphicDriver::Print (const Graphic3d_CView& ACView,
PrintFunction ("call_togl_print"); PrintFunction ("call_togl_print");
PrintCView (MyCView, 1); PrintCView (MyCView, 1);
} }
call_togl_print (&MyCView, &MyCUnderLayer, &MyCOverLayer, return call_togl_print (&MyCView, &MyCUnderLayer, &MyCOverLayer,
hPrintDC, (int)showBackground, filename); hPrintDC, (int)showBackground, filename,
(int)printAlgorithm, (float)theScaleFactor);
#else #else
Standard_NotImplemented::Raise ("OpenGl_GraphicDriver::Print is implemented " Standard_NotImplemented::Raise ("OpenGl_GraphicDriver::Print is implemented "
"only on Windows"); "only on Windows");
return Standard_False;
#endif #endif
} }

View File

@ -0,0 +1,110 @@
// File: OpenGl_PrinterContext.cxx
// Created: 20.05.11 10:00:00
// Author: Anton POLETAEV
#include <OpenGl_PrinterContext.hxx>
OpenGl_PrinterContext* OpenGl_PrinterContext::g_PrinterContext = NULL;
GLCONTEXT OpenGl_PrinterContext::g_ContextId = NULL;
//=======================================================================
//function : OpenGl_PrinterContext
//purpose : Constructor
//=======================================================================
OpenGl_PrinterContext::OpenGl_PrinterContext (GLCONTEXT theCtx) :
myCtx (theCtx), myProjTransform (0, 3, 0, 3), myLayerViewportX (0),
myLayerViewportY (0), myScaleX (1.0f), myScaleY (1.0f)
{
// assign global instance to the current object
if (myCtx != NULL)
{
g_PrinterContext = this;
g_ContextId = myCtx;
}
// init projection matrix
Standard_Real anInitValue = 0.0;
myProjTransform.Init (anInitValue);
myProjTransform (0,0) = 1.0f;
myProjTransform (1,1) = 1.0f;
myProjTransform (2,2) = 1.0f;
myProjTransform (3,3) = 1.0f;
}
//=======================================================================
//function : ~OpenGl_PrinterContext
//purpose : Destructor
//=======================================================================
OpenGl_PrinterContext::~OpenGl_PrinterContext ()
{
// unassign global instance
if (g_PrinterContext == this)
{
g_ContextId = NULL;
g_PrinterContext = NULL;
}
}
//=======================================================================
//function : GetProjTransformation
//purpose : Get view projection transformation matrix.
//=======================================================================
void OpenGl_PrinterContext::GetProjTransformation (GLfloat theMatrix[16])
{
for (int i = 0, k = 0; i < 4; i++)
for (int j = 0; j < 4; j++, k++)
theMatrix[k] = (GLfloat)myProjTransform (i,j);
}
//=======================================================================
//function : SetProjTransformation
//purpose : Set view projection transformation matrix for printing purposes.
// theProjTransform parameter should be an 4x4 array.
//=======================================================================
bool OpenGl_PrinterContext::SetProjTransformation (TColStd_Array2OfReal& thePrj)
{
if (thePrj.RowLength () != 4 || thePrj.ColLength () != 4)
return false;
myProjTransform = thePrj;
return true;
}
//=======================================================================
//function : Deactivate
//purpose : Deactivate PrinterContext object.
// Useful when you need to redraw in usual mode the same
// OpenGl context that you used for printing right after printing,
// before the OpenGl_PrinterContext instance destroyed
//=======================================================================
void OpenGl_PrinterContext::Deactivate ()
{
// unassign global instance
if (g_PrinterContext == this)
{
g_ContextId = NULL;
g_PrinterContext = NULL;
}
}
//=======================================================================
//function : GetInstance
//purpose : Get the PrinterContext instance assigned for OpenGl context.
// Return NULL, if there is no current printing operation and
// there is no assigned instance for "theCtx" OpenGl context.
//=======================================================================
OpenGl_PrinterContext* OpenGl_PrinterContext::GetPrinterContext (GLCONTEXT theCtx)
{
if (g_ContextId == theCtx)
return g_PrinterContext;
else
return NULL;
}

View File

@ -0,0 +1,116 @@
// File: OpenGl_PrinterContext.hxx
// Created: 20.05.11 10:00:00
// Author: Anton POLETAEV
#ifndef _OPENGL_PRINTERCONTEXT_H
#define _OPENGL_PRINTERCONTEXT_H
#include <MMgt_TShared.hxx>
#include <Standard.hxx>
#include <Standard_DefineHandle.hxx>
#include <Handle_MMgt_TShared.hxx>
#include <OpenGl_tgl_all.hxx>
#include <NCollection_DataMap.hxx>
#include <InterfaceGraphic_Graphic3d.hxx>
#include <InterfaceGraphic_Visual3d.hxx>
#include <TColStd_Array2OfReal.hxx>
class Standard_Transient;
class Handle(Standard_Type);
class Handle(MMgt_TShared);
class OpenGl_PrinterContext;
DEFINE_STANDARD_HANDLE(OpenGl_PrinterContext,MMgt_TShared)
//! Class provides specific information for redrawing view to offscreen buffer
//! on printing. The information is: projection matrixes for tiling,
//! scaling factors for text/markers and layer viewport dimensions.
//! The OpenGl_PrinterContext class allows to have only one global instance
//! that can be accessed by GetPrinterContext() during printing operation.
//! The class instance can be created only by call_togl_print().
class OpenGl_PrinterContext : public MMgt_TShared
{
public:
//! Get the PrinterContext instance assigned for OpenGl context.
//! Return NULL, if there is no current printing operation and
//! there is no assigned instance for "theCtx" OpenGl context.
static OpenGl_PrinterContext* GetPrinterContext(GLCONTEXT theCtx);
//! Get view projection transformation matrix.
const TColStd_Array2OfReal& GetProjTransformation ()
{
return myProjTransform;
}
//! Get view projection transformation matrix.
void GetProjTransformation (GLfloat theMatrix[16]);
//! Get text/markers scale factor
void GetScale (GLfloat& theScaleX, GLfloat& theScaleY)
{
theScaleX = myScaleX;
theScaleY = myScaleY;
}
//! Get layer viewport dimensions
void GetLayerViewport (GLsizei& theViewportX,
GLsizei& theViewportY)
{
theViewportX = myLayerViewportX;
theViewportY = myLayerViewportY;
}
private:
//! Constructor
OpenGl_PrinterContext (GLCONTEXT theCtx);
//! Destructor
virtual ~OpenGl_PrinterContext ();
//! Deactivate current printing context.
//! Useful when you need to redraw in usual mode the same OpenGl context
//! that you used for printing right after printing, before the
//! OpenGl_PrinterContext instance destroyed.
void Deactivate ();
//! Set view projection transformation matrix for printing/tiling purposes
//! theProjTransform parameter should be an 4x4 array.
bool SetProjTransformation (TColStd_Array2OfReal& theProjTransform);
//! Set text scale factor
void SetScale (GLfloat theScaleX, GLfloat theScaleY)
{
myScaleX = theScaleX;
myScaleY = theScaleY;
}
//! Set layer viewport dimensions
void SetLayerViewport (GLsizei theViewportX,
GLsizei theViewportY)
{
myLayerViewportX = theViewportX;
myLayerViewportY = theViewportY;
}
private:
static OpenGl_PrinterContext* g_PrinterContext;
static GLCONTEXT g_ContextId;
TColStd_Array2OfReal myProjTransform;
GLfloat myScaleX;
GLfloat myScaleY;
GLsizei myLayerViewportX;
GLsizei myLayerViewportY;
GLCONTEXT myCtx;
// the printer context could be created only in method call_togl_print
friend Standard_Boolean call_togl_print (CALL_DEF_VIEW *, CALL_DEF_LAYER *,
CALL_DEF_LAYER *,
const Aspect_Drawable, const int,
const char*, const int, const float);
};
#endif

View File

@ -4,16 +4,16 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <TCollection_AsciiString.hxx> #include <OpenGl_tgl_all.hxx>
#include <TCollection_HAsciiString.hxx>
#include <Standard_Stream.hxx>
#include <OpenGl_FontMgr.hxx> #include <OpenGl_FontMgr.hxx>
#include <OpenGl_tgl_funcs.hxx> #include <OpenGl_tgl_funcs.hxx>
#include <OpenGl_TextRender.hxx> #include <OpenGl_TextRender.hxx>
#include <OpenGl_telem_attri.hxx> #include <OpenGl_telem_attri.hxx>
#include <OpenGl_cmn_varargs.hxx> #include <OpenGl_cmn_varargs.hxx>
#include <OpenGl_PrinterContext.hxx>
#include <Standard_Stream.hxx>
#include <TCollection_AsciiString.hxx>
#include <TCollection_HAsciiString.hxx>
#include <OSD_Environment.hxx> #include <OSD_Environment.hxx>
#include <Quantity_NameOfColor.hxx> #include <Quantity_NameOfColor.hxx>
@ -384,6 +384,22 @@ void OpenGl_TextRender::RenderText ( const wchar_t* str, GLuint base, int is2d,
if( ! zoom ) if( ! zoom )
{ {
#ifdef WNT
// if the context has assigned printer context, use it's parameters
OpenGl_PrinterContext* aPrinterContext =
OpenGl_PrinterContext::GetPrinterContext( GET_GL_CONTEXT() );
if( aPrinterContext )
{
// get printing scaling in x and y dimensions
GLfloat aTextScalex = 1, aTextScaley = 1;
aPrinterContext->GetScale( aTextScalex, aTextScaley );
// text should be scaled in all directions with same
// factor to save its proportions, so use height (y) scaling
// as it is better for keeping text/3d graphics proportions
glScalef( aTextScaley, aTextScaley, aTextScaley );
}
#endif
glScaled( h, h, h ); glScaled( h, h, h );
} }
else else

View File

@ -1334,14 +1334,16 @@ void EXPORT call_togl_userdraw (
); );
/* ------------------------- */ /* ------------------------- */
void EXPORT call_togl_print ( Standard_Boolean EXPORT call_togl_print (
CALL_DEF_VIEW *aview, CALL_DEF_VIEW *aview,
CALL_DEF_LAYER *anunderlayer, CALL_DEF_LAYER *anunderlayer,
CALL_DEF_LAYER *anoverlayer, CALL_DEF_LAYER *anoverlayer,
const Aspect_Drawable hPrintDC, const Aspect_Drawable hPrintDC,
const int background, const int background,
const char* filename const char* filename,
const int printalgo = 0,
const float theScaleFactor = 1.0
); );

View File

@ -57,6 +57,7 @@ HISTORIQUE DES MODIFICATIONS :
#include <Visual3d_Layer.hxx> #include <Visual3d_Layer.hxx>
#include <OpenGl_Extension.hxx> #include <OpenGl_Extension.hxx>
#include <OpenGl_PrinterContext.hxx>
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
/* /*
@ -297,6 +298,35 @@ call_togl_redraw_layer2d (
printf ("\tratio %f new ortho %f %f %f %f\n", printf ("\tratio %f new ortho %f %f %f %f\n",
ratio, left, right, bottom, top); ratio, left, right, bottom, top);
#endif #endif
#ifdef WNT
// Check printer context that exists only for print operation
OpenGl_PrinterContext* aPrinterContext =
OpenGl_PrinterContext::GetPrinterContext (GET_GL_CONTEXT());
if (aPrinterContext)
{
// additional transformation matrix could be applied to
// render only those parts of viewport that will be
// passed to a printer as a current "frame" to provide
// tiling; scaling of graphics by matrix helps render a
// part of a view (frame) in same viewport, but with higher
// resolution
GLfloat aProjMatrix[16];
aPrinterContext->GetProjTransformation (aProjMatrix);
glLoadMatrixf ((GLfloat*) aProjMatrix);
// printing operation also assumes other viewport dimension
// to comply with transformation matrix or graphics scaling
// factors for tiling for layer redraw
GLsizei anViewportX = 0;
GLsizei anViewportY = 0;
aPrinterContext->GetLayerViewport (anViewportX, anViewportY);
if (anViewportX != 0 && anViewportY != 0)
glViewport (0, 0, anViewportX, anViewportY);
}
#endif
glOrtho (left, right, bottom, top, -1.0, 1.0); glOrtho (left, right, bottom, top, -1.0, 1.0);
#ifdef TRACE_MAT #ifdef TRACE_MAT

File diff suppressed because it is too large Load Diff

View File

@ -87,6 +87,7 @@ if any was defined
#include <OpenGl_txgl.hxx> #include <OpenGl_txgl.hxx>
#include <OpenGl_Memory.hxx> #include <OpenGl_Memory.hxx>
#include <Standard_TypeDef.hxx> #include <Standard_TypeDef.hxx>
#include <OpenGl_PrinterContext.hxx>
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
/* /*
@ -842,7 +843,22 @@ TelSetViewIndex( Tint Wsid /* Workstation id */,
printf("OpenGl_view.c::TelSetViewIndex::glMatrixMode(GL_PROJECTION) \n"); printf("OpenGl_view.c::TelSetViewIndex::glMatrixMode(GL_PROJECTION) \n");
#endif #endif
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadMatrixf((GLfloat *) vptr->vrep.mapping_matrix ); glLoadIdentity();
#ifdef WNT
// add printing scale/tiling transformation
OpenGl_PrinterContext* aPrinterContext =
OpenGl_PrinterContext::GetPrinterContext(GET_GL_CONTEXT());
if (aPrinterContext)
{
GLfloat aProjMatrix[16];
aPrinterContext->GetProjTransformation(aProjMatrix);
glLoadMatrixf((GLfloat*) aProjMatrix);
}
#endif
glMultMatrixf((GLfloat *) vptr->vrep.mapping_matrix );
#ifdef TRACE_MAT #ifdef TRACE_MAT
printf( "\nTelSetViewIndex WS : %d, view : %d", Wsid, Vid ); printf( "\nTelSetViewIndex WS : %d, view : %d", Wsid, Vid );

View File

@ -144,7 +144,8 @@ uses
GradientFillMethod from Aspect, GradientFillMethod from Aspect,
FontAspect from OSD, FontAspect from OSD,
AsciiString from TCollection, AsciiString from TCollection,
ExtendedString from TCollection ExtendedString from TCollection,
PrintAlgo from Aspect
raises raises
@ -1607,8 +1608,9 @@ is
Print (me; hPrnDC: Handle from Aspect = NULL; Print (me; hPrnDC: Handle from Aspect = NULL;
showDialog: Boolean = Standard_True; showDialog: Boolean = Standard_True;
showBackground : Boolean = Standard_True; showBackground : Boolean = Standard_True;
filename: CString = NULL) filename: CString = NULL;
is static; printAlgorithm : PrintAlgo from Aspect = Aspect_PA_STRETCH)
returns Boolean from Standard is static;
---Level: Public ---Level: Public
---Purpose: print the contents of the view to printer with preview. ---Purpose: print the contents of the view to printer with preview.
@ -1625,6 +1627,15 @@ is
-- (background is white) -- (background is white)
-- else set to TRUE for printing with current background color. -- else set to TRUE for printing with current background color.
-- <filename>: If != NULL, then the view will be printed to a file. -- <filename>: If != NULL, then the view will be printed to a file.
-- <printAlgorithm>: If you want to select the print algorithm, then you can
-- specify one of existing algorithms: Aspect_PA_STRETCH, Aspect_PA_TILE.
-- Returns Standard_True if the data is passed to the printer, otherwise
-- Standard_False if the print operation failed. This might be related to
-- insufficient memory or some internal errors. All this errors are
-- indicated by the message boxes (on level of OpenGl_GraphicDriver).
-- Warning: This function can reuse FBO assigned to the
-- view on level of OpenGl_GraphicDriver; Please take it into account if
-- you use it for your purposes;
-- Warning: Works only under Windows. -- Warning: Works only under Windows.
ToPixMap ( me : mutable; ToPixMap ( me : mutable;

View File

@ -53,18 +53,20 @@ Device::~Device()
/* Print Method */ /* Print Method */
/************************************************************************/ /************************************************************************/
void V3d_View::Print (const Aspect_Handle hPrnDC, Standard_Boolean V3d_View::Print (const Aspect_Handle hPrnDC,
const Standard_Boolean showDialog, const Standard_Boolean showDialog,
const Standard_Boolean showBackground, const Standard_Boolean showBackground,
const Standard_CString filename) const const Standard_CString filename,
const Aspect_PrintAlgo printAlgorithm) const
{ {
#ifdef WNT #ifdef WNT
if( MyView->IsDefined() ) if( MyView->IsDefined() )
{ {
if (hPrnDC != NULL) if (hPrnDC != NULL)
{ {
MyView->Print(hPrnDC, showBackground, filename) ; return MyView->Print(hPrnDC, showBackground,
return; filename, printAlgorithm) ;
} }
if (device._pd.hDC == NULL || showDialog ) if (device._pd.hDC == NULL || showDialog )
@ -85,7 +87,7 @@ void V3d_View::Print (const Aspect_Handle hPrnDC,
if (!ispd) if (!ispd)
{ {
return; return Standard_False;
} }
if (!(device._pd.hDC)) if (!(device._pd.hDC))
@ -101,12 +103,21 @@ void V3d_View::Print (const Aspect_Handle hPrnDC,
device._pd.hDevMode = NULL; device._pd.hDevMode = NULL;
} }
MessageBox(0, "Couldn't create Printer Device Context", "Error", MB_OK | MB_ICONSTOP); MessageBox(0, "Couldn't create Printer Device Context", "Error", MB_OK | MB_ICONSTOP);
return; return Standard_False;
} }
} }
MyView->Print(device._pd.hDC, showBackground, filename) ;
// process scale factor accordingly to the new printing approach
DEVMODE* aMode = (LPDEVMODE)GlobalLock(device._pd.hDevMode);
// convert percents to multiplication factor, 100% = 1.0
Standard_Real aScaleFactor = (Standard_Real) aMode->dmScale / 100.0;
GlobalUnlock (device._pd.hDevMode);
return MyView->Print(device._pd.hDC, showBackground,
filename, printAlgorithm, aScaleFactor) ;
} }
#else #else
Standard_NotImplemented::Raise ("V3d_View::Print is implemented only on Windows"); Standard_NotImplemented::Raise ("V3d_View::Print is implemented only on Windows");
#endif #endif
return Standard_False;
} }

View File

@ -24,6 +24,8 @@
#include <Draw_Interpretor.hxx> #include <Draw_Interpretor.hxx>
#include <Draw.hxx> #include <Draw.hxx>
#include <Draw_Appli.hxx> #include <Draw_Appli.hxx>
#include <Aspect_PrintAlgo.hxx>
#include <Image_PixMap.hxx>
#ifndef WNT #ifndef WNT
#include <Graphic3d_GraphicDevice.hxx> #include <Graphic3d_GraphicDevice.hxx>
@ -1760,6 +1762,141 @@ static int VGraduatedTrihedron(Draw_Interpretor& di, Standard_Integer argc, cons
return 0; return 0;
} }
//==============================================================================
//function : VPrintView
//purpose : Test printing algorithm, print the view to image file with given
// width and height. Printing implemented only for WNT.
//==============================================================================
static int VPrintView (Draw_Interpretor& di, Standard_Integer argc,
const char** argv)
{
#ifndef WNT
di << "Printing implemented only for wnt!\n";
return 1;
#else
Handle(AIS_InteractiveContext) aContextAIS = NULL;
Handle(V3d_View) aView = NULL;
aContextAIS = ViewerTest::GetAISContext();
if (!aContextAIS.IsNull())
{
const Handle(V3d_Viewer)& Vwr = aContextAIS->CurrentViewer();
Vwr->InitActiveViews();
if(Vwr->MoreActiveViews())
aView = Vwr->ActiveView();
}
// check for errors
if (aView.IsNull())
{
di << "Call vinit before!\n";
return 1;
}
else if (argc < 4)
{
di << "Use: " << argv[0];
di << " width height filename [print algo=0]\n";
di << "width, height of the intermediate buffer for operation\n";
di << "algo : {0|1}\n";
di << " 0 - stretch algorithm\n";
di << " 1 - tile algorithm\n";
di << "test printing algorithms into an intermediate buffer\n";
di << "with saving output to an image file\n";
return 1;
}
// get the input params
Standard_Integer aWidth = atoi (argv[1]);
Standard_Integer aHeight = atoi (argv[2]);
Standard_Integer aMode = 0;
TCollection_AsciiString aFileName = TCollection_AsciiString (argv[3]);
if (argc==5)
aMode = atoi (argv[4]);
// check the input parameters
if (aWidth <= 0 || aHeight <= 0)
{
di << "Width and height must be positive values!\n";
return 1;
}
if (aMode != 0 && aMode != 1)
aMode = 0;
Image_CRawBufferData aRawBuffer;
HDC anDC = CreateCompatibleDC(0);
// define compatible bitmap
BITMAPINFO aBitmapData;
memset (&aBitmapData, 0, sizeof (BITMAPINFOHEADER));
aBitmapData.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
aBitmapData.bmiHeader.biWidth = aWidth ;
aBitmapData.bmiHeader.biHeight = aHeight;
aBitmapData.bmiHeader.biPlanes = 1;
aBitmapData.bmiHeader.biBitCount = 24;
aBitmapData.bmiHeader.biXPelsPerMeter = 0;
aBitmapData.bmiHeader.biYPelsPerMeter = 0;
aBitmapData.bmiHeader.biClrUsed = 0;
aBitmapData.bmiHeader.biClrImportant = 0;
aBitmapData.bmiHeader.biCompression = BI_RGB;
aBitmapData.bmiHeader.biSizeImage = 0;
// Create Device Independent Bitmap
HBITMAP aMemoryBitmap = CreateDIBSection (anDC, &aBitmapData, DIB_RGB_COLORS,
&aRawBuffer.dataPtr, NULL, 0);
HGDIOBJ anOldBitmap = SelectObject(anDC, aMemoryBitmap);
Standard_Boolean isSaved = Standard_False, isPrinted = Standard_False;
if (aRawBuffer.dataPtr != 0)
{
if (aMode == 0)
isPrinted = aView->Print(anDC,1,1,0,Aspect_PA_STRETCH);
else
isPrinted = aView->Print(anDC,1,1,0,Aspect_PA_TILE);
// succesfully printed into an intermediate buffer
if (isPrinted)
{
Handle(Image_PixMap) anImageBitmap =
new Image_PixMap ((Standard_PByte)aRawBuffer.dataPtr,
aWidth, aHeight,
aWidth*3 + aWidth%4, 24, 0);
isSaved = anImageBitmap->Dump(aFileName.ToCString());
}
else
{
di << "Print operation failed due to printing errors or\n";
di << "insufficient memory available\n";
di << "Please, try to use smaller dimensions for this test\n";
di << "command, as it allocates intermediate buffer for storing\n";
di << "the result\n";
}
}
else
{
di << "Can't allocate memory for intermediate buffer\n";
di << "Please use smaller dimensions\n";
}
if (aMemoryBitmap)
{
SelectObject (anDC, anOldBitmap);
DeleteObject (aMemoryBitmap);
DeleteDC(anDC);
}
if (!isSaved)
{
di << "Save to file operation failed. This operation may fail\n";
di << "if you don't have enough available memory, then you can\n";
di << "use smaller dimensions for the output file\n";
return 1;
}
return 0;
#endif
}
//======================================================================= //=======================================================================
//function : ViewerCommands //function : ViewerCommands
//purpose : //purpose :
@ -1826,4 +1963,8 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
theCommands.Add("vgraduatedtrihedron", theCommands.Add("vgraduatedtrihedron",
"vgraduatedtrihedron : 1/0 (display/erase) [Xname Yname Zname [Font [isMultibyte]]]", "vgraduatedtrihedron : 1/0 (display/erase) [Xname Yname Zname [Font [isMultibyte]]]",
__FILE__,VGraduatedTrihedron,group); __FILE__,VGraduatedTrihedron,group);
theCommands.Add("vprintview" ,
"vprintview : width height filename [algo=0] : Test print algorithm: algo = 0 - stretch, algo = 1 - tile",
__FILE__,VPrintView,group);
} }

View File

@ -74,6 +74,7 @@ uses
RenderingContext from Aspect, RenderingContext from Aspect,
GraphicCallbackProc from Aspect, GraphicCallbackProc from Aspect,
ColorScale from Aspect, ColorScale from Aspect,
PrintAlgo from Aspect,
CRawBufferData from Image, CRawBufferData from Image,
@ -1079,8 +1080,10 @@ is
AnOverLayer : Layer from Visual3d; AnOverLayer : Layer from Visual3d;
hPrnDC : Handle from Aspect; hPrnDC : Handle from Aspect;
showBackground : Boolean; showBackground : Boolean;
filename: CString) filename : CString;
is static; printAlgorithm : PrintAlgo from Aspect = Aspect_PA_STRETCH;
theScaleFactor : Real from Standard = 1.0)
returns Boolean from Standard is static;
---Level: Internal ---Level: Internal
---Purpose: print the contents of all layers of the view to the printer. ---Purpose: print the contents of all layers of the view to the printer.
@ -1089,12 +1092,21 @@ is
-- (background is white) -- (background is white)
-- else set to TRUE for printing with current background color. -- else set to TRUE for printing with current background color.
-- <filename>: If != NULL, then the view will be printed to a file. -- <filename>: If != NULL, then the view will be printed to a file.
-- <printAlgo>: Select print algorithm: stretch, tile.
-- <theScaleFactor>: Scaling coefficient, used internally to scale the
-- printings accordingly to the scale factor selected in the printer
-- properties dialog.
-- Returns Standard_True if the data is passed to the printer, otherwise
-- Standard_False if the print operation failed due to printer error
-- or insufficient memory.
-- Warning: Works only under Windows. -- Warning: Works only under Windows.
Print (me; hPrnDC : Handle from Aspect; Print (me; hPrnDC : Handle from Aspect;
showBackground : Boolean; showBackground : Boolean;
filename: CString) filename : CString;
is static; printAlgorithm : PrintAlgo from Aspect = Aspect_PA_STRETCH;
theScaleFactor : Real from Standard = 1.0 )
returns Boolean from Standard is static;
---Level: Internal ---Level: Internal
---Purpose: print the contents of the view to printer. ---Purpose: print the contents of the view to printer.
@ -1103,6 +1115,13 @@ is
-- (background is white) -- (background is white)
-- else set to TRUE for printing with current background color. -- else set to TRUE for printing with current background color.
-- <filename>: If != NULL, then the view will be printed to a file. -- <filename>: If != NULL, then the view will be printed to a file.
-- <printAlgo>: Select print algorithm: stretch, tile.
-- <theScaleFactor>: Scaling coefficient, used internally to scale the
-- printings accordingly to the scale factor selected in the printer
-- properties dialog.
-- Returns Standard_True if the data is passed to the printer, otherwise
-- Standard_False if the print operation failed due to printer error
-- or insufficient memory.
-- Warning: Works only under Windows. -- Warning: Works only under Windows.
SetTransparency ( me : mutable; SetTransparency ( me : mutable;

View File

@ -14,28 +14,34 @@
/* Print Methods */ /* Print Methods */
/************************************************************************/ /************************************************************************/
void Visual3d_View::Print (const Aspect_Handle hPrintDC, Standard_Boolean Visual3d_View::Print
(const Aspect_Handle hPrintDC,
const Standard_Boolean showBackground, const Standard_Boolean showBackground,
const Standard_CString filename) const const Standard_CString filename,
const Aspect_PrintAlgo printAlgorithm,
const Standard_Real theScaleFactor) const
{ {
Print (MyViewManager->UnderLayer (), return Print (MyViewManager->UnderLayer (),
MyViewManager->OverLayer (), MyViewManager->OverLayer (),
hPrintDC, hPrintDC, showBackground,
showBackground, filename, printAlgorithm,
filename); theScaleFactor);
} }
void Visual3d_View::Print (const Handle(Visual3d_Layer)& AnUnderLayer, Standard_Boolean Visual3d_View::Print
(const Handle(Visual3d_Layer)& AnUnderLayer,
const Handle(Visual3d_Layer)& AnOverLayer, const Handle(Visual3d_Layer)& AnOverLayer,
const Aspect_Handle hPrintDC, const Aspect_Handle hPrintDC,
const Standard_Boolean showBackground, const Standard_Boolean showBackground,
const Standard_CString aFilename) const const Standard_CString aFilename,
const Aspect_PrintAlgo printAlgorithm,
const Standard_Real theScaleFactor) const
{ {
if (IsDeleted ()) return; if (IsDeleted ()) return Standard_False;
if ((! IsDefined ()) || (! IsActive ())) return; if ((! IsDefined ()) || (! IsActive ())) return Standard_False;
if (! MyWindow->IsMapped ()) return; if (! MyWindow->IsMapped ()) return Standard_False;
Aspect_CLayer2d OverCLayer; Aspect_CLayer2d OverCLayer;
Aspect_CLayer2d UnderCLayer; Aspect_CLayer2d UnderCLayer;
@ -44,6 +50,7 @@ void Visual3d_View::Print (const Handle(Visual3d_Layer)& AnUnderLayer,
if (! AnOverLayer.IsNull ()) OverCLayer = AnOverLayer->CLayer (); if (! AnOverLayer.IsNull ()) OverCLayer = AnOverLayer->CLayer ();
if (! AnUnderLayer.IsNull ()) UnderCLayer = AnUnderLayer->CLayer (); if (! AnUnderLayer.IsNull ()) UnderCLayer = AnUnderLayer->CLayer ();
MyGraphicDriver->Print (MyCView, UnderCLayer, OverCLayer, return MyGraphicDriver->Print (MyCView, UnderCLayer, OverCLayer,
hPrintDC, showBackground, aFilename); hPrintDC, showBackground, aFilename,
printAlgorithm, theScaleFactor);
} }