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> |
32 | static 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 | //----------------------------------------------------------------- |
72 | typedef enum { |
73 | CgmBinary, |
74 | CgmCharEncoding, |
75 | CgmClearText |
76 | } CgmType; |
77 | |
78 | typedef enum { |
79 | mfDesc, |
80 | picDesc, |
81 | picBody, |
82 | imgDraw |
83 | } CGMstate; |
84 | static CGMstate myState; |
85 | |
86 | static TColStd_DataMapOfIntegerInteger aTypeIndex; |
87 | static CgmType TypeOfCgm; |
88 | |
89 | //Definition of the C handle who handles the CGM metafile |
90 | FILE* cgmo; |
91 | |
92 | //Those C arrays are the parameters used by the CGM library. |
93 | long ptablong[MAXPARAM]; |
94 | float ptabreal[MAXPARAM]; |
95 | char ptabchar[MAXPARAM]; |
96 | |
97 | //Declare the array in wich WIDTHS will be put (an internal widthmap). |
98 | float* WIDTHMAP = NULL; |
99 | |
100 | // Error string |
101 | #ifndef IMP020701 |
102 | char error[1024]; |
103 | #endif |
104 | |
105 | //============================================================= |
106 | CGM_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 | //============================================================= |
117 | CGM_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 | //============================================================= |
133 | void 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 | //============================================================= |
178 | void 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 | //============================================================= |
194 | void 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 | //============================================================= |
256 | void 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 | //============================================================= |
264 | void 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 | //============================================================= |
307 | void CGM_Driver::InitializeTypeMap (const Handle(Aspect_TypeMap)& aTypeMap) |
308 | { |
309 | /* |
310 | In 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 | //============================================================= |
363 | void 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 | //================================================================================= |
377 | Standard_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 | //============================================================= |
387 | void 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 | //=============================================================================== |
424 | void 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 | //============================================================= |
451 | Standard_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 | //============================================================= |
462 | Standard_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 | //============================================================= |
478 | Standard_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 | //============================================================= |
499 | Standard_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 | //============================================================= |
535 | Standard_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 | //============================================================= |
576 | Standard_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 | //============================================================= |
619 | void 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 | //============================================================= |
682 | void 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 | //============================================================= |
710 | Standard_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 | } |