Integration of OCCT 6.5.0 from SVN
[occt.git] / src / CGM / CGM_Driver.cxx
CommitLineData
7fd59977 1// File: CGM_Driver.cxx
2// Created: Fri Sep 13 12:04:31 1996
3// Author: DCB
4// Copyright: MatraDatavision 1998
5
6#define xBUG // GG 140699
7// Ascendante compatibillity using OLD driver constructor
8// must generates directly a file.
9
10#define IMP020701 //GG
11// Don't creates an external reference named error please ...
12// Thanks to SAMTECH
13
14#include <CGM_Driver.ixx>
15#include <MFT_FontManager.hxx>
16#include <PlotMgt_TextManager.hxx>
17#include <PlotMgt_HListOfMFTFonts.hxx>
18#include <TShort_HArray1OfShortReal.hxx>
19#include <Aspect_Units.hxx>
20#include <Aspect_ColorMapEntry.hxx>
21#include <Aspect_TypeMapEntry.hxx>
22#include <Aspect_WidthMapEntry.hxx>
23#include <Aspect_GenericColorMap.hxx>
24#include <Aspect_RGBPixel.hxx>
25#include <Aspect_DriverError.hxx>
26#include <TColStd_DataMapOfIntegerInteger.hxx>
27#include <OSD_Environment.hxx>
28#include <cgmlib.hxx>
29
30#include <AlienImage.hxx>
31#include <Image_Image.hxx>
32static Handle(Image_Image) myImage;
33
34/////////////////////////////////////////////////////////////////////////*/
35#define TRACE 0
36#define PPI (float)(72.F/(0.0254005F METER))
37#define MAXPARAM 1024
38#define TRANSFORMCOLOR(c) \
39 { if (TypeOfCgm == CgmCharEncoding) c = (((c+1) << 2) - 1); }
40
41#define DRAD (PI/180.)
42#define DEFPLOTTER "DIRECT_CGM"
43
44//-----------------------------------------------------------------
45// Standard CGM settings.
46//-----------------------------------------------------------------
47#define CGMVER 1
48#define INTBITS 32
49#define MAXREAL 32767.0000F // Clear text
50#define MINREAL -32768.0000F
51#define REALBITS 15 // Character encoding
52#define REALPLACES -5
53#define REALDEFEXP 0
54#define REALEXP 0
55#define REALFORM 0 // Binary encoding
56#define REALWHOLE 15
57#define REALFRACTION 20
58
59#define INDEXBITS 8
60#define CLRBITS 16
61#define CLRINDBITS 8
62#define SCALEMOD ABSTRACT
63#define SCALFACT 1
64#define IMCOLRPREC 65536
65#define BACKRED 255
66#define BACKGREEN 255
67#define BACKBLUE 255
68
69//-----------------------------------------------------------------
70// CGM states.
71//-----------------------------------------------------------------
72typedef enum {
73 CgmBinary,
74 CgmCharEncoding,
75 CgmClearText
76} CgmType;
77
78typedef enum {
79 mfDesc,
80 picDesc,
81 picBody,
82 imgDraw
83} CGMstate;
84static CGMstate myState;
85
86static TColStd_DataMapOfIntegerInteger aTypeIndex;
87static CgmType TypeOfCgm;
88
89//Definition of the C handle who handles the CGM metafile
90FILE* cgmo;
91
92//Those C arrays are the parameters used by the CGM library.
93long ptablong[MAXPARAM];
94float ptabreal[MAXPARAM];
95char ptabchar[MAXPARAM];
96
97//Declare the array in wich WIDTHS will be put (an internal widthmap).
98float* WIDTHMAP = NULL;
99
100// Error string
101#ifndef IMP020701
102char error[1024];
103#endif
104
105//=============================================================
106CGM_Driver::CGM_Driver (const Handle(PlotMgt_Plotter)& aPlotter,
107 const Standard_CString aName,
108 const Quantity_Length aDX,
109 const Quantity_Length aDY,
110 const Aspect_TypeOfColorSpace aTypeOfColorSpace)
111 : PlotMgt_PlotterDriver (aPlotter, aName)
112{
113 BeginFile (aPlotter, aDX, aDY, aTypeOfColorSpace);
114}
115
116//=============================================================
117CGM_Driver::CGM_Driver (const Standard_CString aName,
118 const Quantity_Length aDX,
119 const Quantity_Length aDY,
120 const Aspect_TypeOfColorSpace aTypeOfColorSpace)
121 : PlotMgt_PlotterDriver (aName)
122{
123 Handle(PlotMgt_Plotter) thePlotter =
124#ifdef BUG
125 new PlotMgt_Plotter(TCollection_AsciiString(DEFPLOTTER));
126#else
127 new PlotMgt_Plotter(TCollection_AsciiString(DEFPLOTTER),Standard_True);
128#endif
129 BeginFile (thePlotter, aDX, aDY, aTypeOfColorSpace);
130}
131
132//=============================================================
133void CGM_Driver::BeginFile (const Handle(PlotMgt_Plotter)& aPlotter,
134 const Quantity_Length aDX,
135 const Quantity_Length aDY,
136 const Aspect_TypeOfColorSpace aTypeOfColorSpace)
137{
138 SetPlotter (aPlotter);
139 // Initialization of buffers
140 memset (ptablong, 0, sizeof(ptablong));
141 memset (ptabreal, 0, sizeof(ptabreal));
142 memset (ptabchar, 0, sizeof(ptabchar));
143
144 myWidth = Standard_ShortReal(aDX - 2*myPaperMargin);
145 myHeight = Standard_ShortReal(aDY - 2*myPaperMargin);
146 myTypeOfColorSpace = aTypeOfColorSpace;
147
148 // Set the type of CGM file by reading the environment variable "CSF_CGM_Type".
149 OSD_Environment cgmType = OSD_Environment ( "CSF_CGM_Type" );
150 if (cgmType.Value().IsEmpty()) TypeOfCgm = CgmClearText;
151 else {
152 if (cgmType.Value().IsEqual("BIN")) {
153 TypeOfCgm = CgmBinary;
154 } else if (cgmType.Value().IsEqual("CAR")) {
155 TypeOfCgm = CgmCharEncoding;
156 } else if (cgmType.Value().IsEqual("TEX")) {
157 TypeOfCgm = CgmClearText;
158 } else TypeOfCgm = CgmClearText;
159 }
160
161 // Open the CGM metafile
162 cgmo = OPEN_FILE ((Standard_PCharacter)myFileName.ToCString(), TypeOfCgm + 1);
163 if (!cgmo) {
164#ifdef IMP020701
165 char error[1024];
166#endif
167 sprintf (error, "****** CGM_Driver ERROR, unable to open file '%s'\n",
168 myFileName.ToCString());
169 Aspect_DriverError::Raise(error);
170 }
171 // Write the metafile descriptor
172 myFileIsOpened = Standard_True;
173 myState = mfDesc;
174 InitializeDriver (myFileName.ToCString());
175}
176
177//=============================================================
178void CGM_Driver::Close()
179{
180 if (myFileIsOpened) {
181 // Declare the end of the CGM metafile
182 WriteData (ENDMF, ptablong, ptabreal, ptabchar);
183 // Free memory allocated for WIDTHS
184 if (WIDTHMAP)
185 delete[] WIDTHMAP;
186 // Close the CGM metafile
187 CLOSE_FILE ();
188 myFileIsOpened = Standard_False;
189 }
190 aTypeIndex.Clear ();
191}
192
193//=============================================================
194void CGM_Driver::BeginDraw ()
195{
196 // Create TextManager
197 myTextManager = new PlotMgt_TextManager(this);
198 //============================================
199 if (myCurrentPage <= 0) myCurrentPage = 1;
200 else myCurrentPage++;
201 // Write the picture descriptor in the CGM metafile
202 myState = picDesc;
203 // Declare the new image
204 ptablong[0] = myCurrentPage;
205 WriteData (BEGPIC, ptablong, ptabreal, ptabchar);
206 // Set the color selection mode (always index)
207 old.color_mode = DIRECT;
208 cur.color_mode = INDEXED;
209 WriteData (COLRMODE, ptablong, ptabreal, ptabchar);
210 // Set the scale mode
211 cur.scale_mode = SCALEMOD;
212 cur.scale_factor = (float)SCALFACT;
213 WriteData (SCALEMODE, ptablong, ptabreal, ptabchar);
214 // Set the method to compute line width
215 old.linewidth_mode = SCALED;
216 cur.linewidth_mode = ABS;
217 WriteData (LINEWIDTHMODE, ptablong, ptabreal, ptabchar);
218 //Set the method to compute edge width
219 old.edgewidth_mode = SCALED;
220 cur.edgewidth_mode = ABS;
221 WriteData (EDGEWIDTHMODE, ptablong, ptabreal, ptabchar);
222 // Declare the window in which the picture will be drawn
223 cur.vdc_extent.a.x.real = (float)0;
224 cur.vdc_extent.a.y.real = (float)0;
225 cur.vdc_extent.b.x.real = myWidth;
226 cur.vdc_extent.b.y.real = myHeight;
227 WriteData (VDCEXT, ptablong, ptabreal, ptabchar);
228 // set the background color
229 cur.back.red = BACKRED; TRANSFORMCOLOR (cur.back.red);
230 cur.back.green = BACKGREEN; TRANSFORMCOLOR (cur.back.green);
231 cur.back.blue = BACKBLUE; TRANSFORMCOLOR (cur.back.blue);
232 WriteData (BACKCOLR, ptablong, ptabreal, ptabchar);
233 // Declare the body of the picture
234 WriteData (BEGPICBODY, ptablong, ptabreal, ptabchar);
235 myState = picBody;
236 // Write color map in the picture body
237 InitializeColorMap(ColorMap ());
238 // Set clipping rectangle
239 cur.clip_rect.a.x.real = (float)0;
240 cur.clip_rect.a.y.real = (float)0;
241 cur.clip_rect.b.x.real = myWidth;
242 cur.clip_rect.b.y.real = myHeight;
243 WriteData (CLIPRECT, ptablong, ptabreal, ptabchar);
244 // Set clip indicator to ON
245 cur.clip_ind = ON;
246 WriteData (CLIP, ptablong, ptabreal, ptabchar);
247 // Reset default values for line & fill color and type of line
248 oldatt.line.index = -1;
249 oldatt.fill.index = -1;
250 oldatt.edge.index = -1;
251 oldatt.line_type = -1;
252 oldatt.edge_type = -1;
253}
254
255//=============================================================
256void CGM_Driver::EndDraw (const Standard_Boolean )//dontFlush)
257{
258 // Close the current picture
259 WriteData (ENDPIC, ptablong, ptabreal, ptabchar);
260 myImage.Nullify ();
261}
262
263//=============================================================
264void CGM_Driver::InitializeColorMap (const Handle(Aspect_ColorMap)& aColorMap)
265{
266 // CGM version 1 allows the COLOR MAP setting only in the body of a picture.
267 if (myState == picBody || myState == imgDraw) {
268 Standard_Real r,g,b;
269 Standard_Integer index,cpt,tab=2,Size = aColorMap->Size();
270 Aspect_ColorMapEntry entry;
271 Quantity_Color color;
272 ptablong[0] = Size;
273 ptablong[1] = cpt = aColorMap->Entry(1).Index();
274 for (Standard_Integer i=1; i<= Size; i++) {
275 entry = aColorMap->Entry(i);
276 index = entry.Index();
277 color = entry.Color();
278 color.Values(r, g, b, Quantity_TOC_RGB);
279 if (myTypeOfColorSpace != Aspect_TOCS_BlackAndWhite) {
280 ptablong[tab ] = Standard_Integer(255*r); TRANSFORMCOLOR(ptablong[tab ]);
281 ptablong[tab+1] = Standard_Integer(255*g); TRANSFORMCOLOR(ptablong[tab+1]);
282 ptablong[tab+2] = Standard_Integer(255*b); TRANSFORMCOLOR(ptablong[tab+2]);
283 } else {
284 ptablong[tab ] = 0; TRANSFORMCOLOR(ptablong[tab ]);
285 ptablong[tab+1] = 0; TRANSFORMCOLOR(ptablong[tab+1]);
286 ptablong[tab+2] = 0; TRANSFORMCOLOR(ptablong[tab+2]);
287 }
288 tab += 3;
289 if (cpt != index)
290 break;
291 cpt++;
292 }
293 // Put backgrount color at the end of ColorMap
294 ptablong[0]++;
295 ptablong[tab ] = BACKRED; TRANSFORMCOLOR(ptablong[tab ]);
296 ptablong[tab+1] = BACKGREEN; TRANSFORMCOLOR(ptablong[tab+1]);
297 ptablong[tab+2] = BACKBLUE; TRANSFORMCOLOR(ptablong[tab+2]);
298 myBKIndex = cpt;
299 // Write ColorMap to the CGM file
300 WriteData (COLRTABLE, ptablong, ptabreal, ptabchar);
301 if (myTypeOfColorSpace == Aspect_TOCS_BlackAndWhite)
302 myTypeOfColorSpace = Aspect_TOCS_RGB;
303 }
304}
305
306//=============================================================
307void CGM_Driver::InitializeTypeMap (const Handle(Aspect_TypeMap)& aTypeMap)
308{
309/*
310In CGM File:
311 LINEEDGETYPEDEF - code
312 LONG [0] - linetype (negative)
313 LING [1] - repeat length
314 for (i=0; i < LONG[1]; i++)
315 REAL [i] - line description element
316 it's necessary to put all line description elements as integers
317*/
318/*
319 if (CGMstates == picdes) {
320 Standard_Integer Size = aTypeMap->Size();
321 switch (TypeOfCgm) {
322 case (CgmBinary):
323 Aspect_DriverError::Raise("CGM BINARY ENCODING not implemented yet");
324 break;
325 case (CgmCharEncoding):
326 Aspect_DriverError::Raise("CGM CHARACTER ENCODING not implemented yet");
327 break;
328 case (CgmClearText):
329 for (Standard_Integer i=1; i<= Size; i++) {
330 fprintf(cgmo, "LINEEDGETYPEDEF");
331 const TColQuantity_Array1OfLength& asr = aTypeMap->Entry(i).Type().Values();
332 fprintf (cgmo," (%ld), ", -aTypeMap->Entry(i).Index());
333 fprintf (cgmo,"%ld", asr.Upper()-asr.Lower()+1);
334 if ( (asr.Upper()-asr.Lower()+1) > 1 ) {
335 fprintf(cgmo,",");
336 }
337 for (Standard_Integer j = asr.Lower(); j < asr.Upper(); j += 2) {
338 fprintf(cgmo, "%.*f, %.*f", 5, asr(j+1), 5, asr(j));
339 if (j+2 < asr.Upper()) {
340 fprintf(cgmo,",");
341 }
342 }
343 fprintf(cgmo,";\n");
344 }
345 break;
346 }
347 } else {
348 CGMTypeMap = aTypeMap;
349 }
350*/
351 Standard_Integer Size = aTypeMap->Size(), i;
352 aTypeIndex.Clear();
353 for (i = 1; i <= Size; i++) {
354 Standard_Integer index = aTypeMap->Entry(i).Index();
355 if (aTypeMap->Entry(i).Type().Style() == Aspect_TOL_USERDEFINED)
356 aTypeIndex.Bind (index, 1);
357 else
358 aTypeIndex.Bind (index, aTypeMap->Entry(i).Type().Style()+1);
359 }
360}
361
362//=============================================================
363void CGM_Driver::InitializeWidthMap (const Handle(Aspect_WidthMap)& aWidthMap)
364{
365 Standard_Integer Size = aWidthMap->Size();
366 if (WIDTHMAP)
367 delete[] WIDTHMAP;
368 WIDTHMAP = new float[Size];
369 memset (WIDTHMAP, 0, sizeof(WIDTHMAP));
370 for (Standard_Integer i=1; i<= Size; i++) {
371 Standard_Real w = aWidthMap->Entry(i).Width();
372 WIDTHMAP[aWidthMap->Entry(i).Index()] = (float)w;
373 }
374}
375
376//=================================================================================
377Standard_Boolean CGM_Driver::SizeOfImageFile (const Standard_CString anImageFile,
378 Standard_Integer& aWidth,
379 Standard_Integer& aHeight) const
380{
381 return AlienImage::LoadImageFile (anImageFile, myImage, aWidth, aHeight);
382}
383
384//=============================================================
385// Category: Methods to write attributes
386//=============================================================
387void CGM_Driver::PlotLineAttrib (const Standard_Integer ColorIndex,
388 const Standard_Integer TypeIndex,
389 const Standard_Integer WidthIndex)
390{
391 // Set color of the line
392 if (myColorIndex != ColorIndex) {
393 curatt.line.index = myColorIndex = ColorIndex;
394 WriteData (LINECOLR, ptablong, ptabreal, ptabchar);
395 }
396 // Set type of the line
397 if (myTypeIndex != TypeIndex) {
398 curatt.line_type = myTypeIndex = TypeIndex;
399 WriteData (LINETYPE, ptablong, ptabreal, ptabchar);
400 }
401 // Set width of the line
402 if (myWidthIndex != WidthIndex) {
403 curatt.line_width.real = WIDTHMAP[(myWidthIndex = WidthIndex)];
404 WriteData (LINEWIDTH, ptablong, ptabreal, ptabchar);
405 }
406 // Set the color of the edge of polygon
407 if (myEdgeColor != ColorIndex) {
408 curatt.edge.index = myEdgeColor = ColorIndex;
409 WriteData (EDGECOLR, ptablong, ptabreal, ptabchar);
410 }
411 // Set the type of the edge of polygon
412 if (myEdgeType != TypeIndex) {
413 curatt.edge_type = myEdgeType = TypeIndex;
414 WriteData (EDGETYPE, ptablong, ptabreal, ptabchar);
415 }
416 // Set the width of the edge of polygon
417 if (myEdgeWidth != WidthIndex) {
418 curatt.edge_width.real = WIDTHMAP[(myEdgeWidth = WidthIndex)];
419 WriteData (EDGEWIDTH, ptablong, ptabreal, ptabchar);
420 }
421}
422
423//===============================================================================
424void CGM_Driver::PlotPolyAttrib (const Standard_Integer ColorIndex,
425 const Standard_Integer TileIndex,
426 const Standard_Boolean DrawEdge)
427{
428 // Set the edge visibility to the corresponding value
429 if (myEdgeVisibility != (DrawEdge ? ON : OFF)) {
430 curatt.edge_vis = myEdgeVisibility = (DrawEdge ? ON : OFF);
431 WriteData (EDGEVIS, ptablong, ptabreal, ptabchar);
432 }
433 // Set the interior style to fill by solid
434 if (myInteriorStyle != (TileIndex < 0 ? EMPTY : SOLID)) {
435 curatt.int_style = myInteriorStyle = (TileIndex < 0 ? EMPTY : SOLID);
436 WriteData (INTSTYLE, ptablong, ptabreal, ptabchar);
437 }
438 // Set the fill color for drawing
439 if (myFillIndex != ColorIndex) {
440 if (ColorIndex > 0) curatt.fill.index = myFillIndex = ColorIndex;
441 else curatt.fill.index = myFillIndex = myBKIndex;
442 WriteData (FILLCOLR, ptablong, ptabreal, ptabchar);
443 }
444}
445
446//=============================================================
447// Category: Methods to draw primitives
448//=============================================================
449
450//=============================================================
451Standard_Boolean CGM_Driver::PlotPoint (const Standard_ShortReal X,
452 const Standard_ShortReal Y)
453{
454 ptablong[0] = 2;
455 ptabreal[0] = X; ptabreal[1] = Y;
456 ptabreal[2] = X + 0.1F; ptabreal[3] = Y + 0.1F;
457 WriteData (LINE, ptablong, ptabreal, ptabchar);
458 return Standard_True;
459}
460
461//=============================================================
462Standard_Boolean CGM_Driver::PlotSegment (const Standard_ShortReal X1,
463 const Standard_ShortReal Y1,
464 const Standard_ShortReal X2,
465 const Standard_ShortReal Y2)
466{
467 ptablong[0] = 2;
468 ptabreal[0] = X1; ptabreal[1] = Y1;
469 ptabreal[2] = X2; ptabreal[3] = Y2;
470 WriteData (LINE, ptablong, ptabreal, ptabchar);
471 return Standard_True;
472}
473
474//=============================================================
475#define _XP(idx) ((float*)xArray)[(idx)]
476#define _YP(idx) ((float*)yArray)[(idx)]
477//=============================================================
478Standard_Boolean CGM_Driver::PlotPolyline (const Standard_Address xArray,
479 const Standard_Address yArray,
480 const Standard_Address nPts,
481 const Standard_Integer nParts)
482{
483 // Multipart drawing can only be used for text drawing
484 // (called from PlotMgt_TextManager::EndChar()
485 int Tab, N = 0;
486 for (int i = 0; i < nParts; i++) {
487 Tab = 0;
488 ptablong[0] = ((int*)nPts)[i];
489 for (int j = N; j < N + ptablong[0]; j++) {
490 ptabreal[Tab++] = _XP(j); ptabreal[Tab++] = _YP(j);
491 }
492 WriteData (LINE, ptablong, ptabreal, ptabchar);
493 N += ptablong[0];
494 }
495 return Standard_True;
496}
497
498//=============================================================
499Standard_Boolean CGM_Driver::PlotPolygon (const Standard_Address xArray,
500 const Standard_Address yArray,
501 const Standard_Address nPts,
502 const Standard_Integer nParts)
503{
504 if (nParts == 1) {
505 int Tab = 0;
506 ptablong[0] = ((int*)nPts)[0];
507 for (int i=0; i < ptablong[0]; i++) {
508 ptabreal[Tab++] = _XP(i); ptabreal[Tab++] = _YP(i);
509 }
510 WriteData (POLYGON, ptablong, ptabreal, ptabchar);
511 } else {
512 // This can only be used for text drawing
513 // (called from PlotMgt_TextManager::EndChar()
514 int Tab = 0, Vis = 1, N = 0, cpN;
515 ptablong[0] = 0;
516 for (int i = 0; i < nParts; i++) {
517 cpN = ((int*)nPts)[i];
518 for (int j = N; j < N + cpN - 1; j++) {
519 ptabreal[Tab++] = _XP(j); ptabreal[Tab++] = _YP(j);
520 ptablong[Vis++] = VIS; ptablong[0]++;
521 }
522 N += cpN;
523 ptabreal[Tab++] = _XP(N-1); ptabreal[Tab++] = _YP(N-1);
524 ptablong[Vis++] = CLOSEVIS; ptablong[0]++;
525 }
526 WriteData (POLYGONSET, ptablong, ptabreal, ptabchar);
527 }
528 return Standard_True;
529}
530//=============================================================
531#undef _XP
532#undef _YP
533
534//=============================================================
535Standard_Boolean CGM_Driver::PlotArc (const Standard_ShortReal Xpos,
536 const Standard_ShortReal Ypos,
537 const Standard_ShortReal aXradius,
538 const Standard_ShortReal aYradius,
539 const Standard_ShortReal sAngle,
540 const Standard_ShortReal oAngle)
541{
542 Standard_ShortReal san = sAngle;
543 Standard_ShortReal fan = sAngle + oAngle;
544 if (oAngle >= 2*PI) {
545 PlotPolyAttrib (myLineColorIndex, -1, Standard_True);
546 if (aXradius == aYradius) {
547 ptabreal[0] = (float)Xpos; ptabreal[1] = (float)Ypos;
548 ptabreal[2] = (float)aXradius;
549 WriteData (CIRCLE, ptablong, ptabreal, ptabchar);
550 } else {
551 ptabreal[0] = (float)Xpos; ptabreal[1] = (float)Ypos;
552 ptabreal[2] = (float)(Xpos + aXradius); ptabreal[3] = (float)Ypos;
553 ptabreal[4] = (float)Xpos; ptabreal[5] = (float)(Ypos + aYradius);
554 WriteData (ELLIPSE, ptablong, ptabreal, ptabchar);
555 }
556 } else {
557 if (aXradius == aYradius) {
558 ptabreal[0] = (float)Xpos; ptabreal[1] = (float)Ypos;
559 ptabreal[2] = (float)cos(san); ptabreal[3] = (float)sin(san);
560 ptabreal[4] = (float)cos(fan); ptabreal[5] = (float)sin(fan);
561 ptabreal[6] = (float)aXradius;
562 WriteData (ARCCTR, ptablong, ptabreal, ptabchar);
563 } else {
564 ptabreal[0] = (float)Xpos; ptabreal[1] = (float)Ypos;
565 ptabreal[2] = (float)(Xpos + aXradius); ptabreal[3] = (float)Ypos;
566 ptabreal[4] = (float)Xpos; ptabreal[5] = (float)(Ypos + aYradius);
567 ptabreal[6] = (float)cos(san); ptabreal[7] = (float)sin(san);
568 ptabreal[8] = (float)cos(fan); ptabreal[9] = (float)sin(fan);
569 WriteData (ELLIPARC, ptablong, ptabreal, ptabchar);
570 }
571 }
572 return Standard_True;
573}
574
575//=============================================================
576Standard_Boolean CGM_Driver::PlotPolyArc (const Standard_ShortReal Xpos,
577 const Standard_ShortReal Ypos,
578 const Standard_ShortReal aXradius,
579 const Standard_ShortReal aYradius,
580 const Standard_ShortReal sAngle,
581 const Standard_ShortReal oAngle)
582{
583 Standard_ShortReal san = sAngle;
584 Standard_ShortReal fan = sAngle + oAngle;
585 if (oAngle >= 2.*PI) {
586 if (aXradius == aYradius) {
587 ptabreal[0] = (float)Xpos; ptabreal[1] = (float)Ypos;
588 ptabreal[2] = (float)aXradius;
589 WriteData (CIRCLE, ptablong, ptabreal, ptabchar);
590 } else {
591 ptabreal[0] = (float)Xpos; ptabreal[1] = (float)Ypos;
592 ptabreal[2] = (float)(Xpos + aXradius); ptabreal[3] = (float)aYradius;
593 ptabreal[4] = (float)Xpos; ptabreal[5] = (float)(Ypos + aYradius);
594 WriteData (ELLIPSE, ptablong, ptabreal, ptabchar);
595 }
596 } else {
597 if (aXradius == aYradius) {
598 ptabreal[0] = (float)Xpos; ptabreal[1] = (float)Ypos;
599 ptabreal[2] = (float)cos(san); ptabreal[3] = (float)sin(san);
600 ptabreal[4] = (float)cos(fan); ptabreal[5] = (float)sin(fan);
601 ptabreal[6] = (float)aXradius; ptablong[8] = 0;
602 WriteData (ARCCTRCLOSE, ptablong, ptabreal, ptabchar);
603 } else {
604 ptabreal[0] = (float)Xpos; ptabreal[1] = (float)Ypos;
605 ptabreal[2] = (float)(Xpos + aXradius); ptabreal[3] = (float)Ypos;
606 ptabreal[4] = (float)Xpos; ptabreal[5] = (float)(Ypos + aYradius);
607 ptabreal[6] = (float)cos(san); ptabreal[7] = (float)sin(san);
608 ptabreal[8] = (float)(aXradius*cos(fan)); ptabreal[9] = (float)(aYradius*sin(fan));
609 ptablong[11] = 0;
610 WriteData (ELLIPARCCLOSE, ptablong, ptabreal, ptabchar);
611 }
612 }
613 return Standard_True;
614}
615
616//=============================================================
617// Private methods
618//=============================================================
619void CGM_Driver::InitializeDriver (const Standard_CString aName)
620{
621 //declare the Metafile
622 strcpy(ptabchar,aName);
623 WriteData (BEGMF, ptablong, ptabreal, ptabchar);
624 //Set the CGM's version
625 ptablong[0] = CGMVER;
626 WriteData (MFVERSION, ptablong, ptabreal, ptabchar);
627 //Put in the metafile a string whose content is free
628 strcpy(ptabchar,"Generated with CGM_Driver from MATRA-DATAVISION");
629 WriteData (MFDESC, ptablong, ptabreal, ptabchar);
630 //Set the element list (always 'DRAWINGPLUS')
631 ptablong[1]=1;
632 WriteData (MFELEMLIST, ptablong, ptabreal, ptabchar);
633 //Set the type of value (integer or real)
634 cur.vdc_type = REAL;
635 WriteData (VDCTYPE, ptablong, ptabreal, ptabchar);
636 //Set the integer precision
637 cur.int_bits = INTBITS;
638 WriteData (INTEGERPREC, ptablong, ptabreal, ptabchar);
639 //Set the real precision
640 cur.max_real = MAXREAL; // Clear text
641 cur.min_real = MINREAL;
642 cur.real_bits = REALBITS; // Character encoding
643 cur.real_places = REALPLACES;
644 cur.real_defexp = REALDEFEXP;
645 cur.real_expald = REALEXP;
646 curbin.real_type = REALFORM; // Binary encoding
647 curbin.real_whole = REALWHOLE;
648 curbin.real_fraction = REALFRACTION;
649 WriteData (REALPREC, ptablong, ptabreal, ptabchar);
650 //Set the index precision
651 cur.index_bits = INDEXBITS;
652 WriteData (INDEXPREC, ptablong, ptabreal, ptabchar);
653 //Set the color precision
654 cur.col_bits = CLRBITS;
655 WriteData (COLRPREC, ptablong, ptabreal, ptabchar);
656 //Set the Color Index precision
657 cur.colind_bits = CLRINDBITS;
658 WriteData (COLRINDEXPREC, ptablong, ptabreal, ptabchar);
659 //set the max color index
660 cur.max_colind = 255;
661 WriteData (MAXCOLRINDEX, ptablong, ptabreal, ptabchar);
662 //Set the minimum color and the maximum color
663 cur.min_rgb.red = cur.min_rgb.green = cur.min_rgb.blue = 0;
664 cur.max_rgb.red = cur.max_rgb.green = cur.max_rgb.blue = 255;
665 TRANSFORMCOLOR(cur.max_rgb.red);
666 TRANSFORMCOLOR(cur.max_rgb.green);
667 TRANSFORMCOLOR(cur.max_rgb.blue);
668 WriteData (COLRVALUEEXT, ptablong, ptabreal, ptabchar);
669 //Set the internal variables
670 myBKIndex = 0;
671 myCurrentPage = 0;
672 myFillIndex = -9;
673 myEdgeColor = -9;
674 myEdgeType = -9;
675 myEdgeWidth = -9;
676 myInteriorStyle = -9;
677 myEdgeVisibility = -9;
678 myImage.Nullify ();
679}
680
681//=============================================================
682void CGM_Driver::WriteData (const Standard_Integer aCode,
683 const Standard_Address pLongData,
684 const Standard_Address pFloatData,
685 const Standard_Address pCharData)
686{
687 short code = (short) aCode;
688 long* aLong = (long*) pLongData;
689 float* aFloat = (float*)pFloatData;
690 char* aChar = (char*) pCharData;
691 if (code == LINETYPE) {
692 curatt.line_type = aTypeIndex.Find(curatt.line_type);
693 } else if (code == EDGETYPE) {
694 curatt.edge_type = aTypeIndex.Find(curatt.edge_type);
695 }
696 switch (TypeOfCgm) {
697 case (CgmBinary):
698 CGMObin (cgmo, code, aLong, aFloat, aChar);
699 break;
700 case (CgmCharEncoding):
701 CGMOchar (cgmo, code, aLong, aFloat, aChar);
702 break;
703 case (CgmClearText):
704 CGMOtext (cgmo, code, aLong, aFloat, aChar);
705 break;
706 }
707}
708
709//=============================================================
710Standard_Boolean CGM_Driver::PlotImage (const Standard_ShortReal aX,
711 const Standard_ShortReal aY,
712 const Standard_ShortReal aWidth,
713 const Standard_ShortReal aHeight,
714 const Standard_ShortReal aScale,
715 const Standard_CString anImageFile,
716 const Standard_Address anArrayOfPixels,
717 const Standard_Integer aLineIndex)
718{
719 Aspect_ColorMapEntry anEntry;
720 Handle(Aspect_GenericColorMap) aColorMap = new Aspect_GenericColorMap;
721 // We'll create new colormap here and will set it
722 Standard_Boolean status;
723 Standard_Integer idx = 0, found = 0, fidx = 0, LowX = 0, LowY = 0;
724 Standard_Integer width = Standard_Integer(aWidth),
725 height = Standard_Integer(aHeight);
726 Standard_Integer x, y;
727 Standard_Real r, g, b;
728 Aspect_RGBPixel* g2dp = (Aspect_RGBPixel*) anArrayOfPixels;
729 Quantity_Color color;
730 // Load image if necessary
731 if (anImageFile) {
732 status = SizeOfImageFile (anImageFile, width, height);
733 if (status) {
734 LowX = myImage -> LowerX ();
735 LowY = myImage -> LowerY ();
736 }
737 } else {
738 status = Standard_True;
739 }
740
741 // Put image colormap and pixels to the file
742 if (status) {
743 Standard_ShortReal wscale, hscale;
744 wscale = hscale = (float)(aScale * myPixelSize * PPI / 2.F);
745 // Put image in the file
746 float a2X = (float)(aX - wscale * width/2.F);
747 float a2Y = (float)(aY + hscale * (height/2.F - (aLineIndex == -1 ? 0:aLineIndex)));
748 if (aLineIndex != -1) height = 1;
749 int cellsSize = sizeof(long)*(width*height + 10);
750
751 Aspect_RGBPixel* pixels =
752 (Aspect_RGBPixel*) malloc (IMCOLRPREC*sizeof(Aspect_RGBPixel));
753 if (pixels == NULL) return Standard_False;
754 long* cells = (long*) malloc (cellsSize);
755 if (cells == NULL) { free (pixels); return Standard_False; }
756
757 //Initialize the array
758 memset (pixels, 0, IMCOLRPREC*sizeof(Aspect_RGBPixel));
759 int pixidx = 10; // Pixel description begins with index 10
760 // Put cellarray entry data
761 ptabreal[0] = a2X; ptabreal[1] = a2Y; // P
762 ptabreal[2] = a2X+(width*wscale); ptabreal[3] = a2Y-(height*hscale); // Q
763 ptabreal[4] = a2X+(width*wscale); ptabreal[5] = a2Y; // R
764 cells[0] = width*height; cells[7] = width;
765 cells[8] = height;
766 // For all pixels of an Image
767 for (y=0; y < height; y++) {
768 for (x=0; x < width; x++) {
769 // Get pixel of image at (x,y) position
770 if (anImageFile) {
771 color = myImage -> PixelColor (x + LowX, y + LowY);
772 color.Values (r, g, b, Quantity_TOC_RGB);
773 } else {
774 r = g2dp -> red;
775 g = g2dp -> green;
776 b = g2dp -> blue;
777 g2dp++;
778 }
779 // Try to find the pixel
780 for (int c = 0; c < idx; c++) {
781 if (pixels[c].red == r && pixels[c].green == g && pixels[c].blue == b) {
782 found = 1;
783 fidx = c;
784 }
785 if (found) break;
786 }
787 if (!found) {
788 // It's necessary to add new color to colormap
789 pixels[idx].red = (float)r;
790 pixels[idx].green = (float)g;
791 pixels[idx].blue = (float)b;
792 color.SetValues (r, g, b, Quantity_TOC_RGB);
793 anEntry = Aspect_ColorMapEntry (idx, color);
794 anEntry.SetIndex (idx);
795 aColorMap->AddEntry (anEntry);
796 cells[pixidx++] = idx;
797 idx++;
798 } else {
799 cells[pixidx++] = fidx;
800 }
801 if (idx > IMCOLRPREC) {
802 free (pixels);
803 free (cells);
804 return Standard_False;
805 }
806 found = 0;
807 } // for (x=0; x < width; x++)
808 } // for (y=0; y < height; y++)
809 free (pixels);
810 // Calculate image color precision
811 int imcolprec = 0, tmp = 1L;
812 while (tmp < aColorMap->Size()) { tmp <<= 1L; imcolprec++; }
813 cells[9] = imcolprec;
814 // Write image data to file (colormap and image data).
815 myState = imgDraw;
816 InitializeColorMap (aColorMap);
817 WriteData (CELLARRAY, cells, ptabreal, ptabchar);
818 // Restore old colormap
819 myState = picBody;
820 InitializeColorMap (ColorMap ());
821 free (cells);
822 return Standard_True;
823 } // IF STATUS
824 return Standard_False;
825}