0028215: Visualization - define EMPTY type line for consistenct with Interior Style
[occt.git] / src / OpenGl / OpenGl_AspectMarker.cxx
1 // Created on: 2011-07-14
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <OpenGl_AspectMarker.hxx>
17 #include <OpenGl_Context.hxx>
18 #include <OpenGl_GraphicDriver.hxx>
19 #include <OpenGl_PointSprite.hxx>
20 #include <OpenGl_ShaderManager.hxx>
21 #include <OpenGl_ShaderProgram.hxx>
22 #include <OpenGl_Workspace.hxx>
23
24 #include <Image_PixMap.hxx>
25 #include <Graphic3d_MarkerImage.hxx>
26 #include <Graphic3d_ShaderProgram.hxx>
27 #include <NCollection_Vec4.hxx>
28 #include <TColStd_HArray1OfByte.hxx>
29
30 namespace
31 {
32   static const TCollection_AsciiString THE_EMPTY_KEY;
33
34   //! Draw inner point as filled rectangle
35   static Handle(TColStd_HArray1OfByte) fillPointBitmap (const Standard_Integer theSize)
36   {
37     // draw inner point as filled rectangle
38     const Standard_Integer        aNumOfBytes = (theSize / 8 + (theSize % 8 ? 1 : 0)) * theSize;
39     Handle(TColStd_HArray1OfByte) aBitMap     = new TColStd_HArray1OfByte (0, aNumOfBytes - 1);
40     for (Standard_Integer anIter = 0; anIter < aBitMap->Length(); ++anIter)
41     {
42       aBitMap->SetValue (anIter, 255);
43     }
44     return aBitMap;
45   }
46 }
47
48 // Following Section relates to default markers
49
50 #define TEL_NO_OF_SIZES 13
51 #define TEL_PM_START_SIZE 1.0
52 #define TEL_PM_END_SIZE   7.0
53
54 struct PM_FONT_INFO
55 {
56   float width, height;
57   int   offset;
58 };
59 typedef PM_FONT_INFO* pm_font_info;
60
61 #define PM_PLUS_10_NUM  9*2
62 #define PM_PLUS_15_NUM  11*2
63 #define PM_PLUS_20_NUM  13*2
64 #define PM_PLUS_25_NUM  15*2
65 #define PM_PLUS_30_NUM  17*3
66 #define PM_PLUS_35_NUM  19*3
67 #define PM_PLUS_40_NUM  21*3
68 #define PM_PLUS_45_NUM  23*3
69 #define PM_PLUS_50_NUM  25*4
70 #define PM_PLUS_55_NUM  27*4
71 #define PM_PLUS_60_NUM  29*4
72 #define PM_PLUS_65_NUM  31*4
73 #define PM_PLUS_70_NUM  32*4
74
75 #define PM_STAR_10_NUM  9
76 #define PM_STAR_15_NUM  11*2
77 #define PM_STAR_20_NUM  13*2
78 #define PM_STAR_25_NUM  15*2
79 #define PM_STAR_30_NUM  17*2
80 #define PM_STAR_35_NUM  19*2
81 #define PM_STAR_40_NUM  21*3
82 #define PM_STAR_45_NUM  23*3
83 #define PM_STAR_50_NUM  25*3
84 #define PM_STAR_55_NUM  27*3
85 #define PM_STAR_60_NUM  29*4
86 #define PM_STAR_65_NUM  32*4
87 #define PM_STAR_70_NUM  32*4
88
89 #define PM_CIRC_10_NUM  7
90 #define PM_CIRC_15_NUM  9*2
91 #define PM_CIRC_20_NUM  9*2
92 #define PM_CIRC_25_NUM  11*2
93 #define PM_CIRC_30_NUM  13*2
94 #define PM_CIRC_35_NUM  15*2
95 #define PM_CIRC_40_NUM  17*3
96 #define PM_CIRC_45_NUM  19*3
97 #define PM_CIRC_50_NUM  21*3
98 #define PM_CIRC_55_NUM  23*3
99 #define PM_CIRC_60_NUM  25*4
100 #define PM_CIRC_65_NUM  27*4
101 #define PM_CIRC_70_NUM  29*4
102
103 #define PM_CROSS_10_NUM 7
104 #define PM_CROSS_15_NUM 9*2
105 #define PM_CROSS_20_NUM 11*2
106 #define PM_CROSS_25_NUM 13*2
107 #define PM_CROSS_30_NUM 15*2
108 #define PM_CROSS_35_NUM 17*3
109 #define PM_CROSS_40_NUM 19*3
110 #define PM_CROSS_45_NUM 21*3
111 #define PM_CROSS_50_NUM 23*3
112 #define PM_CROSS_55_NUM 25*4
113 #define PM_CROSS_60_NUM 27*4
114 #define PM_CROSS_65_NUM 32*4
115 #define PM_CROSS_70_NUM 32*4
116
117 #define PM_PLUS_10_OFT  0
118 #define PM_PLUS_15_OFT  PM_PLUS_10_OFT + PM_PLUS_10_NUM
119 #define PM_PLUS_20_OFT  PM_PLUS_15_OFT + PM_PLUS_15_NUM
120 #define PM_PLUS_25_OFT  PM_PLUS_20_OFT + PM_PLUS_20_NUM
121 #define PM_PLUS_30_OFT  PM_PLUS_25_OFT + PM_PLUS_25_NUM
122 #define PM_PLUS_35_OFT  PM_PLUS_30_OFT + PM_PLUS_30_NUM
123 #define PM_PLUS_40_OFT  PM_PLUS_35_OFT + PM_PLUS_35_NUM
124 #define PM_PLUS_45_OFT  PM_PLUS_40_OFT + PM_PLUS_40_NUM
125 #define PM_PLUS_50_OFT  PM_PLUS_45_OFT + PM_PLUS_45_NUM
126 #define PM_PLUS_55_OFT  PM_PLUS_50_OFT + PM_PLUS_50_NUM
127 #define PM_PLUS_60_OFT  PM_PLUS_55_OFT + PM_PLUS_55_NUM
128 #define PM_PLUS_65_OFT  PM_PLUS_60_OFT + PM_PLUS_60_NUM
129 #define PM_PLUS_70_OFT  PM_PLUS_65_OFT + PM_PLUS_65_NUM
130
131 #define PM_STAR_10_OFT  PM_PLUS_70_OFT + PM_PLUS_70_NUM
132 #define PM_STAR_15_OFT  PM_STAR_10_OFT + PM_STAR_10_NUM
133 #define PM_STAR_20_OFT  PM_STAR_15_OFT + PM_STAR_15_NUM
134 #define PM_STAR_25_OFT  PM_STAR_20_OFT + PM_STAR_20_NUM
135 #define PM_STAR_30_OFT  PM_STAR_25_OFT + PM_STAR_25_NUM
136 #define PM_STAR_35_OFT  PM_STAR_30_OFT + PM_STAR_30_NUM
137 #define PM_STAR_40_OFT  PM_STAR_35_OFT + PM_STAR_35_NUM
138 #define PM_STAR_45_OFT  PM_STAR_40_OFT + PM_STAR_40_NUM
139 #define PM_STAR_50_OFT  PM_STAR_45_OFT + PM_STAR_45_NUM
140 #define PM_STAR_55_OFT  PM_STAR_50_OFT + PM_STAR_50_NUM
141 #define PM_STAR_60_OFT  PM_STAR_55_OFT + PM_STAR_55_NUM
142 #define PM_STAR_65_OFT  PM_STAR_60_OFT + PM_STAR_60_NUM
143 #define PM_STAR_70_OFT  PM_STAR_65_OFT + PM_STAR_65_NUM
144
145 #define PM_CIRC_10_OFT  PM_STAR_70_OFT + PM_STAR_70_NUM
146 #define PM_CIRC_15_OFT  PM_CIRC_10_OFT + PM_CIRC_10_NUM
147 #define PM_CIRC_20_OFT  PM_CIRC_15_OFT + PM_CIRC_15_NUM
148 #define PM_CIRC_25_OFT  PM_CIRC_20_OFT + PM_CIRC_20_NUM
149 #define PM_CIRC_30_OFT  PM_CIRC_25_OFT + PM_CIRC_25_NUM
150 #define PM_CIRC_35_OFT  PM_CIRC_30_OFT + PM_CIRC_30_NUM
151 #define PM_CIRC_40_OFT  PM_CIRC_35_OFT + PM_CIRC_35_NUM
152 #define PM_CIRC_45_OFT  PM_CIRC_40_OFT + PM_CIRC_40_NUM
153 #define PM_CIRC_50_OFT  PM_CIRC_45_OFT + PM_CIRC_45_NUM
154 #define PM_CIRC_55_OFT  PM_CIRC_50_OFT + PM_CIRC_50_NUM
155 #define PM_CIRC_60_OFT  PM_CIRC_55_OFT + PM_CIRC_55_NUM
156 #define PM_CIRC_65_OFT  PM_CIRC_60_OFT + PM_CIRC_60_NUM
157 #define PM_CIRC_70_OFT  PM_CIRC_65_OFT + PM_CIRC_65_NUM
158
159 #define PM_CROSS_10_OFT  PM_CIRC_70_OFT + PM_CIRC_70_NUM
160 #define PM_CROSS_15_OFT  PM_CROSS_10_OFT + PM_CROSS_10_NUM
161 #define PM_CROSS_20_OFT  PM_CROSS_15_OFT + PM_CROSS_15_NUM
162 #define PM_CROSS_25_OFT  PM_CROSS_20_OFT + PM_CROSS_20_NUM
163 #define PM_CROSS_30_OFT  PM_CROSS_25_OFT + PM_CROSS_25_NUM
164 #define PM_CROSS_35_OFT  PM_CROSS_30_OFT + PM_CROSS_30_NUM
165 #define PM_CROSS_40_OFT  PM_CROSS_35_OFT + PM_CROSS_35_NUM
166 #define PM_CROSS_45_OFT  PM_CROSS_40_OFT + PM_CROSS_40_NUM
167 #define PM_CROSS_50_OFT  PM_CROSS_45_OFT + PM_CROSS_45_NUM
168 #define PM_CROSS_55_OFT  PM_CROSS_50_OFT + PM_CROSS_50_NUM
169 #define PM_CROSS_60_OFT  PM_CROSS_55_OFT + PM_CROSS_55_NUM
170 #define PM_CROSS_65_OFT  PM_CROSS_60_OFT + PM_CROSS_60_NUM
171 #define PM_CROSS_70_OFT  PM_CROSS_65_OFT + PM_CROSS_65_NUM
172
173 static const PM_FONT_INFO arrPMFontInfo[][TEL_NO_OF_SIZES] =
174 {
175  // TOM_POINT - not used
176  {{0, 0, 0},
177   {0, 0, 0},
178   {0, 0, 0},
179   {0, 0, 0},
180   {0, 0, 0},
181   {0, 0, 0},
182   {0, 0, 0},
183   {0, 0, 0},
184   {0, 0, 0},
185   {0, 0, 0},
186   {0, 0, 0},
187   {0, 0, 0},
188   {0, 0, 0}},
189
190  // TOM_PLUS
191  {{ 9.f,  9.f, PM_PLUS_10_OFT},
192   {11.f, 11.f, PM_PLUS_15_OFT},
193   {13.f, 13.f, PM_PLUS_20_OFT},
194   {15.f, 15.f, PM_PLUS_25_OFT},
195   {17.f, 17.f, PM_PLUS_30_OFT},
196   {19.f, 19.f, PM_PLUS_35_OFT},
197   {21.f, 21.f, PM_PLUS_40_OFT},
198   {23.f, 23.f, PM_PLUS_45_OFT},
199   {25.f, 25.f, PM_PLUS_50_OFT},
200   {27.f, 27.f, PM_PLUS_55_OFT},
201   {29.f, 29.f, PM_PLUS_60_OFT},
202   {31.f, 31.f, PM_PLUS_65_OFT},
203   {32.f, 32.f, PM_PLUS_70_OFT}},
204
205  // TOM_STAR
206  {{ 7.f,  9.f, PM_STAR_10_OFT},
207   {9.f,  11.f, PM_STAR_15_OFT},
208   {11.f, 13.f, PM_STAR_20_OFT},
209   {13.f, 15.f, PM_STAR_25_OFT},
210   {13.f, 17.f, PM_STAR_30_OFT},
211   {15.f, 19.f, PM_STAR_35_OFT},
212   {17.f, 21.f, PM_STAR_40_OFT},
213   {19.f, 23.f, PM_STAR_45_OFT},
214   {21.f, 25.f, PM_STAR_50_OFT},
215   {23.f, 27.f, PM_STAR_55_OFT},
216   {25.f, 29.f, PM_STAR_60_OFT},
217   {32.f, 32.f, PM_STAR_65_OFT},
218   {32.f, 32.f, PM_STAR_70_OFT}},
219
220  // TOM_X
221  {{ 7.f,  7.f, PM_CROSS_10_OFT},
222   { 9.f,  9.f, PM_CROSS_15_OFT},
223   {11.f, 11.f, PM_CROSS_20_OFT},
224   {13.f, 13.f, PM_CROSS_25_OFT},
225   {15.f, 15.f, PM_CROSS_30_OFT},
226   {17.f, 17.f, PM_CROSS_35_OFT},
227   {19.f, 19.f, PM_CROSS_40_OFT},
228   {21.f, 21.f, PM_CROSS_45_OFT},
229   {23.f, 23.f, PM_CROSS_50_OFT},
230   {25.f, 25.f, PM_CROSS_55_OFT},
231   {27.f, 27.f, PM_CROSS_60_OFT},
232   {32.f, 32.f, PM_CROSS_65_OFT},
233   {32.f, 32.f, PM_CROSS_70_OFT}},
234
235  // TOM_O
236  {{ 7.f,  7.f, PM_CIRC_10_OFT},
237   { 9.f,  9.f, PM_CIRC_15_OFT},
238   { 9.f,  9.f, PM_CIRC_20_OFT},
239   {11.f, 11.f, PM_CIRC_25_OFT},
240   {13.f, 13.f, PM_CIRC_30_OFT},
241   {15.f, 15.f, PM_CIRC_35_OFT},
242   {17.f, 17.f, PM_CIRC_40_OFT},
243   {19.f, 19.f, PM_CIRC_45_OFT},
244   {21.f, 21.f, PM_CIRC_50_OFT},
245   {23.f, 23.f, PM_CIRC_55_OFT},
246   {25.f, 25.f, PM_CIRC_60_OFT},
247   {27.f, 27.f, PM_CIRC_65_OFT},
248   {29.f, 29.f, PM_CIRC_70_OFT}}
249 };
250
251 static const Standard_Byte OpenGl_AspectMarker_myMarkerRaster[] =
252 {
253     // TYPE = PLUS
254
255     0x08,0x00,
256     0x08,0x00,
257     0x08,0x00,
258     0x08,0x00,
259     0xff,0x80,
260     0x08,0x00,
261     0x08,0x00,
262     0x08,0x00,
263     0x08,0x00, // PLUS 9x9 = 1.0
264
265     0x04,0x00,
266     0x04,0x00,
267     0x04,0x00,
268     0x04,0x00,
269     0x04,0x00,
270     0xff,0xe0,
271     0x04,0x00,
272     0x04,0x00,
273     0x04,0x00,
274     0x04,0x00,
275     0x04,0x00, // PLUS 11x11 = 1.5
276
277     0x02,0x00,
278     0x02,0x00,
279     0x02,0x00,
280     0x02,0x00,
281     0x02,0x00,
282     0x02,0x00,
283     0xff,0xf8,
284     0x02,0x00,
285     0x02,0x00,
286     0x02,0x00,
287     0x02,0x00,
288     0x02,0x00,
289     0x02,0x00, // PLUS 13x13 = 2.0
290
291     0x01,0x00,
292     0x01,0x00,
293     0x01,0x00,
294     0x01,0x00,
295     0x01,0x00,
296     0x01,0x00,
297     0x01,0x00,
298     0xff,0xfe,
299     0x01,0x00,
300     0x01,0x00,
301     0x01,0x00,
302     0x01,0x00,
303     0x01,0x00,
304     0x01,0x00,
305     0x01,0x00, // PLUS 15x15 = 2.5
306
307     0x00,0x80, 0x00,
308     0x00,0x80, 0x00,
309     0x00,0x80, 0x00,
310     0x00,0x80, 0x00,
311     0x00,0x80, 0x00,
312     0x00,0x80, 0x00,
313     0x00,0x80, 0x00,
314     0x00,0x80, 0x00,
315     0xff,0xff, 0x80,
316     0x00,0x80, 0x00,
317     0x00,0x80, 0x00,
318     0x00,0x80, 0x00,
319     0x00,0x80, 0x00,
320     0x00,0x80, 0x00,
321     0x00,0x80, 0x00,
322     0x00,0x80, 0x00,
323     0x00,0x80, 0x00, // PLUS 17x17 = 3.0
324
325     0x00,0x40, 0x00,
326     0x00,0x40, 0x00,
327     0x00,0x40, 0x00,
328     0x00,0x40, 0x00,
329     0x00,0x40, 0x00,
330     0x00,0x40, 0x00,
331     0x00,0x40, 0x00,
332     0x00,0x40, 0x00,
333     0x00,0x40, 0x00,
334     0xff,0xff, 0xe0,
335     0x00,0x40, 0x00,
336     0x00,0x40, 0x00,
337     0x00,0x40, 0x00,
338     0x00,0x40, 0x00,
339     0x00,0x40, 0x00,
340     0x00,0x40, 0x00,
341     0x00,0x40, 0x00,
342     0x00,0x40, 0x00,
343     0x00,0x40, 0x00, // PLUS 19x19 = 3.5
344
345     0x00,0x20, 0x00,
346     0x00,0x20, 0x00,
347     0x00,0x20, 0x00,
348     0x00,0x20, 0x00,
349     0x00,0x20, 0x00,
350     0x00,0x20, 0x00,
351     0x00,0x20, 0x00,
352     0x00,0x20, 0x00,
353     0x00,0x20, 0x00,
354     0x00,0x20, 0x00,
355     0xff,0xff, 0xf8,
356     0x00,0x20, 0x00,
357     0x00,0x20, 0x00,
358     0x00,0x20, 0x00,
359     0x00,0x20, 0x00,
360     0x00,0x20, 0x00,
361     0x00,0x20, 0x00,
362     0x00,0x20, 0x00,
363     0x00,0x20, 0x00,
364     0x00,0x20, 0x00,
365     0x00,0x20, 0x00, // PLUS 21x21 = 4.0
366
367     0x00,0x10, 0x00,
368     0x00,0x10, 0x00,
369     0x00,0x10, 0x00,
370     0x00,0x10, 0x00,
371     0x00,0x10, 0x00,
372     0x00,0x10, 0x00,
373     0x00,0x10, 0x00,
374     0x00,0x10, 0x00,
375     0x00,0x10, 0x00,
376     0x00,0x10, 0x00,
377     0x00,0x10, 0x00,
378     0xff,0xff, 0xfe,
379     0x00,0x10, 0x00,
380     0x00,0x10, 0x00,
381     0x00,0x10, 0x00,
382     0x00,0x10, 0x00,
383     0x00,0x10, 0x00,
384     0x00,0x10, 0x00,
385     0x00,0x10, 0x00,
386     0x00,0x10, 0x00,
387     0x00,0x10, 0x00,
388     0x00,0x10, 0x00,
389     0x00,0x10, 0x00, // PLUS 23x23 = 4.5
390
391     0x00,0x08, 0x00,0x00,
392     0x00,0x08, 0x00,0x00,
393     0x00,0x08, 0x00,0x00,
394     0x00,0x08, 0x00,0x00,
395     0x00,0x08, 0x00,0x00,
396     0x00,0x08, 0x00,0x00,
397     0x00,0x08, 0x00,0x00,
398     0x00,0x08, 0x00,0x00,
399     0x00,0x08, 0x00,0x00,
400     0x00,0x08, 0x00,0x00,
401     0x00,0x08, 0x00,0x00,
402     0x00,0x08, 0x00,0x00,
403     0xff,0xff, 0xff,0x80,
404     0x00,0x08, 0x00,0x00,
405     0x00,0x08, 0x00,0x00,
406     0x00,0x08, 0x00,0x00,
407     0x00,0x08, 0x00,0x00,
408     0x00,0x08, 0x00,0x00,
409     0x00,0x08, 0x00,0x00,
410     0x00,0x08, 0x00,0x00,
411     0x00,0x08, 0x00,0x00,
412     0x00,0x08, 0x00,0x00,
413     0x00,0x08, 0x00,0x00,
414     0x00,0x08, 0x00,0x00,
415     0x00,0x08, 0x00,0x00, // PLUS 25x25 = 5.0
416
417     0x00,0x04, 0x00,0x00,
418     0x00,0x04, 0x00,0x00,
419     0x00,0x04, 0x00,0x00,
420     0x00,0x04, 0x00,0x00,
421     0x00,0x04, 0x00,0x00,
422     0x00,0x04, 0x00,0x00,
423     0x00,0x04, 0x00,0x00,
424     0x00,0x04, 0x00,0x00,
425     0x00,0x04, 0x00,0x00,
426     0x00,0x04, 0x00,0x00,
427     0x00,0x04, 0x00,0x00,
428     0x00,0x04, 0x00,0x00,
429     0x00,0x04, 0x00,0x00,
430     0xff,0xff, 0xff,0xe0,
431     0x00,0x04, 0x00,0x00,
432     0x00,0x04, 0x00,0x00,
433     0x00,0x04, 0x00,0x00,
434     0x00,0x04, 0x00,0x00,
435     0x00,0x04, 0x00,0x00,
436     0x00,0x04, 0x00,0x00,
437     0x00,0x04, 0x00,0x00,
438     0x00,0x04, 0x00,0x00,
439     0x00,0x04, 0x00,0x00,
440     0x00,0x04, 0x00,0x00,
441     0x00,0x04, 0x00,0x00,
442     0x00,0x04, 0x00,0x00,
443     0x00,0x04, 0x00,0x00, // PLUS 27x27 = 5.5
444
445     0x00,0x02, 0x00,0x00,
446     0x00,0x02, 0x00,0x00,
447     0x00,0x02, 0x00,0x00,
448     0x00,0x02, 0x00,0x00,
449     0x00,0x02, 0x00,0x00,
450     0x00,0x02, 0x00,0x00,
451     0x00,0x02, 0x00,0x00,
452     0x00,0x02, 0x00,0x00,
453     0x00,0x02, 0x00,0x00,
454     0x00,0x02, 0x00,0x00,
455     0x00,0x02, 0x00,0x00,
456     0x00,0x02, 0x00,0x00,
457     0x00,0x02, 0x00,0x00,
458     0x00,0x02, 0x00,0x00,
459     0xff,0xff, 0xff,0xf8,
460     0x00,0x02, 0x00,0x00,
461     0x00,0x02, 0x00,0x00,
462     0x00,0x02, 0x00,0x00,
463     0x00,0x02, 0x00,0x00,
464     0x00,0x02, 0x00,0x00,
465     0x00,0x02, 0x00,0x00,
466     0x00,0x02, 0x00,0x00,
467     0x00,0x02, 0x00,0x00,
468     0x00,0x02, 0x00,0x00,
469     0x00,0x02, 0x00,0x00,
470     0x00,0x02, 0x00,0x00,
471     0x00,0x02, 0x00,0x00,
472     0x00,0x02, 0x00,0x00,
473     0x00,0x02, 0x00,0x00, // PLUS 29x29 = 6.0
474
475     0x00,0x01, 0x00,0x00,
476     0x00,0x01, 0x00,0x00,
477     0x00,0x01, 0x00,0x00,
478     0x00,0x01, 0x00,0x00,
479     0x00,0x01, 0x00,0x00,
480     0x00,0x01, 0x00,0x00,
481     0x00,0x01, 0x00,0x00,
482     0x00,0x01, 0x00,0x00,
483     0x00,0x01, 0x00,0x00,
484     0x00,0x01, 0x00,0x00,
485     0x00,0x01, 0x00,0x00,
486     0x00,0x01, 0x00,0x00,
487     0x00,0x01, 0x00,0x00,
488     0x00,0x01, 0x00,0x00,
489     0x00,0x01, 0x00,0x00,
490     0xff,0xff, 0xff,0xfd,
491     0x00,0x01, 0x00,0x00,
492     0x00,0x01, 0x00,0x00,
493     0x00,0x01, 0x00,0x00,
494     0x00,0x01, 0x00,0x00,
495     0x00,0x01, 0x00,0x00,
496     0x00,0x01, 0x00,0x00,
497     0x00,0x01, 0x00,0x00,
498     0x00,0x01, 0x00,0x00,
499     0x00,0x01, 0x00,0x00,
500     0x00,0x01, 0x00,0x00,
501     0x00,0x01, 0x00,0x00,
502     0x00,0x01, 0x00,0x00,
503     0x00,0x01, 0x00,0x00,
504     0x00,0x01, 0x00,0x00,
505     0x00,0x01, 0x00,0x00, // PLUS 31x31 = 6.5
506
507     0x00,0x00, 0x80,0x00,
508     0x00,0x00, 0x80,0x00,
509     0x00,0x00, 0x80,0x00,
510     0x00,0x00, 0x80,0x00,
511     0x00,0x00, 0x80,0x00,
512     0x00,0x00, 0x80,0x00,
513     0x00,0x00, 0x80,0x00,
514     0x00,0x00, 0x80,0x00,
515     0x00,0x00, 0x80,0x00,
516     0x00,0x00, 0x80,0x00,
517     0x00,0x00, 0x80,0x00,
518     0x00,0x00, 0x80,0x00,
519     0x00,0x00, 0x80,0x00,
520     0x00,0x00, 0x80,0x00,
521     0x00,0x00, 0x80,0x00,
522     0x00,0x00, 0x80,0x00,
523     0xff,0xff, 0xff,0xff,
524     0x00,0x00, 0x80,0x00,
525     0x00,0x00, 0x80,0x00,
526     0x00,0x00, 0x80,0x00,
527     0x00,0x00, 0x80,0x00,
528     0x00,0x00, 0x80,0x00,
529     0x00,0x00, 0x80,0x00,
530     0x00,0x00, 0x80,0x00,
531     0x00,0x00, 0x80,0x00,
532     0x00,0x00, 0x80,0x00,
533     0x00,0x00, 0x80,0x00,
534     0x00,0x00, 0x80,0x00,
535     0x00,0x00, 0x80,0x00,
536     0x00,0x00, 0x80,0x00,
537     0x00,0x00, 0x80,0x00,
538     0x00,0x00, 0x80,0x00, // PLUS 32x32 = 7.0
539
540     // TYPE = STAR
541
542     0x10,
543     0x10,
544     0xd6,
545     0x38,
546     0x10,
547     0x38,
548     0xd6,
549     0x10,
550     0x10, // STAR 7x9 = 1.0
551
552     0x08,0x00,
553     0x08,0x00,
554     0x08,0x00,
555     0xc9,0x80,
556     0x3e,0x00,
557     0x08,0x00,
558     0x3e,0x00,
559     0xc9,0x80,
560     0x08,0x00,
561     0x08,0x00,
562     0x08,0x00, // STAR 9x11 = 1.5
563
564     0x04,0x00,
565     0x04,0x00,
566     0x04,0x00,
567     0x84,0x20,
568     0x64,0xc0,
569     0x1f,0x00,
570     0x04,0x00,
571     0x1f,0x00,
572     0x64,0xc0,
573     0x84,0x20,
574     0x04,0x00,
575     0x04,0x00,
576     0x04,0x00, // STAR 11x13 = 2.0
577
578     0x02,0x00,
579     0x02,0x00,
580     0x02,0x00,
581     0x02,0x00,
582     0x82,0x18,
583     0x62,0x60,
584     0x1b,0x80,
585     0x06,0x00,
586     0x1b,0x80,
587     0x62,0x60,
588     0x82,0x18,
589     0x02,0x00,
590     0x02,0x00,
591     0x02,0x00,
592     0x02,0x00, // STAR 13x15 = 2.5
593
594     0x02,0x00,
595     0x02,0x00,
596     0x02,0x00,
597     0x02,0x00,
598     0x82,0x08,
599     0x62,0x30,
600     0x12,0x40,
601     0x0f,0x80,
602     0x02,0x00,
603     0x0f,0x80,
604     0x12,0x40,
605     0x62,0x30,
606     0x82,0x08,
607     0x02,0x00,
608     0x02,0x00,
609     0x02,0x00,
610     0x02,0x00, // STAR 13x17 = 3.0
611
612     0x01,0x00,
613     0x01,0x00,
614     0x01,0x00,
615     0x01,0x00,
616     0x01,0x00,
617     0xc1,0x06,
618     0x21,0x18,
619     0x19,0x20,
620     0x07,0xc0,
621     0x01,0x00,
622     0x07,0xc0,
623     0x19,0x20,
624     0x21,0x18,
625     0xc1,0x06,
626     0x01,0x00,
627     0x01,0x00,
628     0x01,0x00,
629     0x01,0x00,
630     0x01,0x00, // STAR 15x19 = 3.5
631
632     0x00,0x80, 0x00,
633     0x00,0x80, 0x00,
634     0x00,0x80, 0x00,
635     0x00,0x80, 0x00,
636     0x00,0x80, 0x00,
637     0x80,0x80, 0x80,
638     0x60,0x83, 0x00,
639     0x10,0x8c, 0x00,
640     0x0c,0x90, 0x00,
641     0x03,0xe0, 0x00,
642     0x00,0x80, 0x00,
643     0x03,0xe0, 0x00,
644     0x0c,0x90, 0x00,
645     0x10,0x8c, 0x00,
646     0x60,0x83, 0x00,
647     0x80,0x80, 0x80,
648     0x00,0x80, 0x00,
649     0x00,0x80, 0x00,
650     0x00,0x80, 0x00,
651     0x00,0x80, 0x00,
652     0x00,0x80, 0x00, // STAR 17x21 = 4.0
653
654     0x00,0x40, 0x00,
655     0x00,0x40, 0x00,
656     0x00,0x40, 0x00,
657     0x00,0x40, 0x00,
658     0x00,0x40, 0x00,
659     0x00,0x40, 0x00,
660     0xc0,0x40, 0x60,
661     0x30,0x41, 0x80,
662     0x08,0x42, 0x00,
663     0x06,0x4c, 0x00,
664     0x01,0xf0, 0x00,
665     0x00,0x40, 0x00,
666     0x01,0xf0, 0x00,
667     0x06,0x4c, 0x00,
668     0x08,0x42, 0x00,
669     0x30,0x41, 0x80,
670     0xc0,0x40, 0x60,
671     0x00,0x40, 0x00,
672     0x00,0x40, 0x00,
673     0x00,0x40, 0x00,
674     0x00,0x40, 0x00,
675     0x00,0x40, 0x00,
676     0x00,0x40, 0x00, // STAR 19x23 = 4.5
677
678     0x00,0x20, 0x00,
679     0x00,0x20, 0x00,
680     0x00,0x20, 0x00,
681     0x00,0x20, 0x00,
682     0x00,0x20, 0x00,
683     0x00,0x20, 0x00,
684     0x80,0x20, 0x08,
685     0x60,0x20, 0x30,
686     0x18,0x20, 0xc0,
687     0x04,0x21, 0x00,
688     0x03,0x26, 0x00,
689     0x00,0xf8, 0x00,
690     0x00,0x20, 0x00,
691     0x00,0xf8, 0x00,
692     0x03,0x26, 0x00,
693     0x04,0x21, 0x00,
694     0x18,0x20, 0xc0,
695     0x60,0x20, 0x30,
696     0x80,0x20, 0x08,
697     0x00,0x20, 0x00,
698     0x00,0x20, 0x00,
699     0x00,0x20, 0x00,
700     0x00,0x20, 0x00,
701     0x00,0x20, 0x00,
702     0x00,0x20, 0x00, // STAR 21x25 = 5.0
703
704     0x00,0x10, 0x00,
705     0x00,0x10, 0x00,
706     0x00,0x10, 0x00,
707     0x00,0x10, 0x00,
708     0x00,0x10, 0x00,
709     0x00,0x10, 0x00,
710     0x00,0x10, 0x00,
711     0xc0,0x10, 0x06,
712     0x30,0x10, 0x18,
713     0x08,0x10, 0x60,
714     0x06,0x10, 0x80,
715     0x01,0x93, 0x00,
716     0x00,0x7c, 0x00,
717     0x00,0x10, 0x00,
718     0x00,0x7c, 0x00,
719     0x01,0x93, 0x00,
720     0x06,0x10, 0x80,
721     0x08,0x10, 0x60,
722     0x30,0x10, 0x18,
723     0xc0,0x10, 0x06,
724     0x00,0x10, 0x00,
725     0x00,0x10, 0x00,
726     0x00,0x10, 0x00,
727     0x00,0x10, 0x00,
728     0x00,0x10, 0x00,
729     0x00,0x10, 0x00,
730     0x00,0x10, 0x00, // STAR 23x27 = 5.5
731
732     0x00,0x08, 0x00,0x00,
733     0x00,0x08, 0x00,0x00,
734     0x00,0x08, 0x00,0x00,
735     0x00,0x08, 0x00,0x00,
736     0x00,0x08, 0x00,0x00,
737     0x00,0x08, 0x00,0x00,
738     0x00,0x08, 0x00,0x00,
739     0x80,0x08, 0x00,0x80,
740     0x60,0x08, 0x03,0x00,
741     0x18,0x08, 0x0c,0x00,
742     0x04,0x08, 0x30,0x00,
743     0x03,0x08, 0x40,0x00,
744     0x00,0xc9, 0x80,0x00,
745     0x00,0x3e, 0x00,0x00,
746     0x00,0x08, 0x00,0x00,
747     0x00,0x3e, 0x00,0x00,
748     0x00,0xc9, 0x80,0x00,
749     0x03,0x08, 0x40,0x00,
750     0x04,0x08, 0x30,0x00,
751     0x18,0x08, 0x0c,0x00,
752     0x60,0x08, 0x03,0x00,
753     0x80,0x08, 0x00,0x80,
754     0x00,0x08, 0x00,0x00,
755     0x00,0x08, 0x00,0x00,
756     0x00,0x08, 0x00,0x00,
757     0x00,0x08, 0x00,0x00,
758     0x00,0x08, 0x00,0x00,
759     0x00,0x08, 0x00,0x00,
760     0x00,0x08, 0x00,0x00, // STAR 25x29 = 6.0
761
762     0x00,0x00, 0x80,0x00,
763     0x00,0x00, 0x80,0x00,
764     0x00,0x00, 0x80,0x00,
765     0x00,0x00, 0x80,0x00,
766     0x00,0x00, 0x80,0x00,
767     0x00,0x00, 0x80,0x00,
768     0x00,0x00, 0x80,0x00,
769     0x00,0x00, 0x80,0x00,
770     0x00,0x00, 0x80,0x00,
771     0x30,0x00, 0x80,0x06,
772     0x0c,0x00, 0x80,0x18,
773     0x03,0x00, 0x80,0x60,
774     0x00,0xc0, 0x81,0x80,
775     0x00,0x30, 0x86,0x00,
776     0x00,0x0c, 0x98,0x00,
777     0x00,0x03, 0xe0,0x00,
778     0x00,0x03, 0xe0,0x00,
779     0x00,0x0c, 0x98,0x00,
780     0x00,0x30, 0x86,0x00,
781     0x00,0xc0, 0x81,0x80,
782     0x03,0x00, 0x80,0x60,
783     0x0c,0x00, 0x80,0x18,
784     0x30,0x00, 0x80,0x06,
785     0x00,0x00, 0x80,0x00,
786     0x00,0x00, 0x80,0x00,
787     0x00,0x00, 0x80,0x00,
788     0x00,0x00, 0x80,0x00,
789     0x00,0x00, 0x80,0x00,
790     0x00,0x00, 0x80,0x00,
791     0x00,0x00, 0x80,0x00,
792     0x00,0x00, 0x00,0x00,
793     0x00,0x00, 0x00,0x00, // STAR 32x32 = 6.5
794
795     0x00, 0x00, 0x80, 0x00,
796     0x00, 0x00, 0x80, 0x00,
797     0x00, 0x00, 0x80, 0x00,
798     0x00, 0x00, 0x80, 0x00,
799     0x00, 0x00, 0x80, 0x00,
800     0x00, 0x00, 0x80, 0x00,
801     0x00, 0x00, 0x80, 0x00,
802     0x00, 0x00, 0x80, 0x00,
803     0x10, 0x00, 0x80, 0x04,
804     0x0c, 0x00, 0x80, 0x18,
805     0x02, 0x00, 0x80, 0x20,
806     0x01, 0x80, 0x80, 0xc0,
807     0x00, 0x40, 0x81, 0x00,
808     0x00, 0x30, 0x86, 0x00,
809     0x00, 0x08, 0x88, 0x00,
810     0x00, 0x06, 0xb0, 0x00,
811     0x00, 0x01, 0xc0, 0x00,
812     0x00, 0x06, 0xb0, 0x00,
813     0x00, 0x08, 0x88, 0x00,
814     0x00, 0x30, 0x86, 0x00,
815     0x00, 0x40, 0x81, 0x00,
816     0x01, 0x80, 0x80, 0xc0,
817     0x02, 0x00, 0x80, 0x20,
818     0x0c, 0x00, 0x80, 0x18,
819     0x10, 0x00, 0x80, 0x04,
820     0x00, 0x00, 0x80, 0x00,
821     0x00, 0x00, 0x80, 0x00,
822     0x00, 0x00, 0x80, 0x00,
823     0x00, 0x00, 0x80, 0x00,
824     0x00, 0x00, 0x80, 0x00,
825     0x00, 0x00, 0x80, 0x00,
826     0x00, 0x00, 0x80, 0x00, // STAR 32x32 = 7.0
827
828     // TYPE = CIRC
829
830     0x38,
831     0x44,
832     0x82,
833     0x82,
834     0x82,
835     0x44,
836     0x38, // CIRC 7x7 = 1.0
837
838     0x3c,0x00,
839     0x42,0x00,
840     0x81,0x00,
841     0x81,0x00,
842     0x81,0x00,
843     0x81,0x00,
844     0x42,0x00,
845     0x3c,0x00,
846     0x00,0x00, //CIRC 9x9 = 1.5
847
848     0x3e,0x00,
849     0x41,0x00,
850     0x81,0x80,
851     0x80,0x80,
852     0x80,0x80,
853     0x80,0x80,
854     0x81,0x80,
855     0x41,0x00,
856     0x3e,0x00, // CIRC 9x9 = 2.0
857
858     0x1f,0x00,
859     0x20,0x80,
860     0x40,0x40,
861     0x80,0x20,
862     0x80,0x20,
863     0x80,0x20,
864     0x80,0x20,
865     0x80,0x20,
866     0x40,0x40,
867     0x20,0x80,
868     0x1f,0x00, // CIRC 11x11 = 2.5
869
870     0x0f,0x80,
871     0x10,0x40,
872     0x20,0x20,
873     0x40,0x10,
874     0x80,0x08,
875     0x80,0x08,
876     0x80,0x08,
877     0x80,0x08,
878     0x80,0x08,
879     0x40,0x10,
880     0x20,0x20,
881     0x10,0x40,
882     0x0f,0x80, // CIRC 13x13 = 3.0
883
884     0x07,0xc0,
885     0x18,0x30,
886     0x20,0x08,
887     0x40,0x04,
888     0x40,0x04,
889     0x80,0x02,
890     0x80,0x02,
891     0x80,0x02,
892     0x80,0x02,
893     0x80,0x02,
894     0x40,0x04,
895     0x40,0x04,
896     0x20,0x08,
897     0x18,0x30,
898     0x07,0xc0, // CIRC 15x15 = 3.5
899
900     0x03,0xe0, 0x00,
901     0x0c,0x18, 0x00,
902     0x10,0x04, 0x00,
903     0x20,0x02, 0x00,
904     0x40,0x01, 0x00,
905     0x40,0x01, 0x00,
906     0x80,0x00, 0x80,
907     0x80,0x00, 0x80,
908     0x80,0x00, 0x80,
909     0x80,0x00, 0x80,
910     0x80,0x00, 0x80,
911     0x40,0x01, 0x00,
912     0x40,0x01, 0x00,
913     0x20,0x02, 0x00,
914     0x10,0x04, 0x00,
915     0x0c,0x18, 0x00,
916     0x03,0xe0, 0x00, // CIRC 17x17 = 4.0
917
918     0x03,0xf8, 0x00,
919     0x0e,0x0e, 0x00,
920     0x18,0x03, 0x00,
921     0x20,0x00, 0x80,
922     0x60,0x00, 0xc0,
923     0x40,0x00, 0x40,
924     0xc0,0x00, 0x60,
925     0x80,0x00, 0x20,
926     0x80,0x00, 0x20,
927     0x80,0x00, 0x20,
928     0x80,0x00, 0x20,
929     0x80,0x00, 0x20,
930     0xc0,0x00, 0x60,
931     0x40,0x00, 0x40,
932     0x60,0x00, 0xc0,
933     0x20,0x00, 0x80,
934     0x18,0x03, 0x00,
935     0x0e,0x0e, 0x00,
936     0x03,0xf8, 0x00, // CIRC 19x19 = 4.5
937
938     0x01,0xfc, 0x00,
939     0x06,0x03, 0x00,
940     0x08,0x00, 0x80,
941     0x10,0x00, 0x40,
942     0x20,0x00, 0x20,
943     0x40,0x00, 0x10,
944     0x40,0x00, 0x10,
945     0x80,0x00, 0x08,
946     0x80,0x00, 0x08,
947     0x80,0x00, 0x08,
948     0x80,0x00, 0x08,
949     0x80,0x00, 0x08,
950     0x80,0x00, 0x08,
951     0x80,0x00, 0x08,
952     0x40,0x00, 0x10,
953     0x40,0x00, 0x10,
954     0x20,0x00, 0x20,
955     0x10,0x00, 0x40,
956     0x08,0x00, 0x80,
957     0x06,0x03, 0x00,
958     0x01,0xfc, 0x00, // CIRC 21x21 = 5.0
959
960     0x00,0xfe, 0x00,
961     0x03,0x01, 0x80,
962     0x0c,0x00, 0x60,
963     0x18,0x00, 0x30,
964     0x30,0x00, 0x18,
965     0x20,0x00, 0x08,
966     0x40,0x00, 0x04,
967     0x40,0x00, 0x04,
968     0x80,0x00, 0x02,
969     0x80,0x00, 0x02,
970     0x80,0x00, 0x02,
971     0x80,0x00, 0x02,
972     0x80,0x00, 0x02,
973     0x80,0x00, 0x02,
974     0x80,0x00, 0x02,
975     0x40,0x00, 0x04,
976     0x40,0x00, 0x04,
977     0x20,0x00, 0x08,
978     0x30,0x00, 0x18,
979     0x18,0x00, 0x30,
980     0x0c,0x00, 0x60,
981     0x03,0x01, 0x80,
982     0x00,0xfe, 0x00, // CIRC 23x23 = 5.5
983
984     0x00,0x7f, 0x00,0x00,
985     0x01,0x80, 0xc0,0x00,
986     0x06,0x00, 0x30,0x00,
987     0x08,0x00, 0x08,0x00,
988     0x10,0x00, 0x04,0x00,
989     0x20,0x00, 0x02,0x00,
990     0x20,0x00, 0x02,0x00,
991     0x40,0x00, 0x01,0x00,
992     0x40,0x00, 0x01,0x00,
993     0x80,0x00, 0x00,0x80,
994     0x80,0x00, 0x00,0x80,
995     0x80,0x00, 0x00,0x80,
996     0x80,0x00, 0x00,0x80,
997     0x80,0x00, 0x00,0x80,
998     0x80,0x00, 0x00,0x80,
999     0x80,0x00, 0x00,0x80,
1000     0x40,0x00, 0x01,0x00,
1001     0x40,0x00, 0x01,0x00,
1002     0x20,0x00, 0x02,0x00,
1003     0x20,0x00, 0x02,0x00,
1004     0x10,0x00, 0x04,0x00,
1005     0x08,0x00, 0x08,0x00,
1006     0x06,0x00, 0x30,0x00,
1007     0x01,0x80, 0xc0,0x00,
1008     0x00,0x7f, 0x00,0x00, // CIRC 25x25 = 6.0
1009
1010     0x00,0x3f, 0x80,0x00,
1011     0x01,0xc0, 0x70,0x00,
1012     0x03,0x00, 0x18,0x00,
1013     0x0c,0x00, 0x06,0x00,
1014     0x18,0x00, 0x03,0x00,
1015     0x10,0x00, 0x01,0x00,
1016     0x20,0x00, 0x00,0x80,
1017     0x60,0x00, 0x00,0xc0,
1018     0x40,0x00, 0x00,0x40,
1019     0x40,0x00, 0x00,0x40,
1020     0x80,0x00, 0x00,0x20,
1021     0x80,0x00, 0x00,0x20,
1022     0x80,0x00, 0x00,0x20,
1023     0x80,0x00, 0x00,0x20,
1024     0x80,0x00, 0x00,0x20,
1025     0x80,0x00, 0x00,0x20,
1026     0x80,0x00, 0x00,0x20,
1027     0x40,0x00, 0x00,0x40,
1028     0x40,0x00, 0x00,0x40,
1029     0x60,0x00, 0x00,0xc0,
1030     0x20,0x00, 0x00,0x80,
1031     0x10,0x00, 0x01,0x00,
1032     0x18,0x00, 0x03,0x00,
1033     0x0c,0x00, 0x06,0x00,
1034     0x03,0x00, 0x18,0x00,
1035     0x01,0xc0, 0x70,0x00,
1036     0x00,0x3f, 0x80,0x00, // CIRC 27x27 = 6.5
1037
1038     0x00,0x1f, 0xc0,0x00,
1039     0x00,0xe0, 0x38,0x00,
1040     0x01,0x00, 0x04,0x00,
1041     0x06,0x00, 0x03,0x00,
1042     0x08,0x00, 0x00,0x80,
1043     0x10,0x00, 0x00,0x40,
1044     0x10,0x00, 0x00,0x40,
1045     0x20,0x00, 0x00,0x20,
1046     0x40,0x00, 0x00,0x10,
1047     0x40,0x00, 0x00,0x10,
1048     0x40,0x00, 0x00,0x10,
1049     0x80,0x00, 0x00,0x08,
1050     0x80,0x00, 0x00,0x08,
1051     0x80,0x00, 0x00,0x08,
1052     0x80,0x00, 0x00,0x08,
1053     0x80,0x00, 0x00,0x08,
1054     0x80,0x00, 0x00,0x08,
1055     0x80,0x00, 0x00,0x08,
1056     0x40,0x00, 0x00,0x10,
1057     0x40,0x00, 0x00,0x10,
1058     0x40,0x00, 0x00,0x10,
1059     0x20,0x00, 0x00,0x20,
1060     0x10,0x00, 0x00,0x40,
1061     0x10,0x00, 0x00,0x40,
1062     0x08,0x00, 0x00,0x80,
1063     0x06,0x00, 0x03,0x00,
1064     0x01,0x00, 0x04,0x00,
1065     0x00,0xe0, 0x38,0x00,
1066     0x00,0x1f, 0xc0,0x00, // CIRC 29x29 = 7.0
1067
1068     // TYPE = CROSS
1069
1070     0x82,
1071     0x44,
1072     0x28,
1073     0x10,
1074     0x28,
1075     0x44,
1076     0x82, // CROSS 7x7 = 1.0
1077
1078     0x80,0x80,
1079     0x41,0x00,
1080     0x22,0x00,
1081     0x14,0x00,
1082     0x08,0x00,
1083     0x14,0x00,
1084     0x22,0x00,
1085     0x41,0x00,
1086     0x80,0x80, // CROSS 9x9 = 1.5
1087
1088     0x80,0x20,
1089     0x40,0x40,
1090     0x20,0x80,
1091     0x11,0x00,
1092     0x0a,0x00,
1093     0x04,0x00,
1094     0x0a,0x00,
1095     0x11,0x00,
1096     0x20,0x80,
1097     0x40,0x40,
1098     0x80,0x20, // CROSS 11x11 = 2.0
1099
1100     0x80,0x08,
1101     0x40,0x10,
1102     0x20,0x20,
1103     0x10,0x40,
1104     0x08,0x80,
1105     0x05,0x00,
1106     0x02,0x00,
1107     0x05,0x00,
1108     0x08,0x80,
1109     0x10,0x40,
1110     0x20,0x20,
1111     0x40,0x10,
1112     0x80,0x08, // CROSS 13x13 = 2.5
1113
1114     0x80,0x02,
1115     0x40,0x04,
1116     0x20,0x08,
1117     0x10,0x10,
1118     0x08,0x20,
1119     0x04,0x40,
1120     0x02,0x80,
1121     0x01,0x00,
1122     0x02,0x80,
1123     0x04,0x40,
1124     0x08,0x20,
1125     0x10,0x10,
1126     0x20,0x08,
1127     0x40,0x04,
1128     0x80,0x02, // CROSS 15x15 = 3.0
1129
1130     0x80,0x00, 0x80,
1131     0x40,0x01, 0x00,
1132     0x20,0x02, 0x00,
1133     0x10,0x04, 0x00,
1134     0x08,0x08, 0x00,
1135     0x04,0x10, 0x00,
1136     0x02,0x20, 0x00,
1137     0x01,0x40, 0x00,
1138     0x00,0x80, 0x00,
1139     0x01,0x40, 0x00,
1140     0x02,0x20, 0x00,
1141     0x04,0x10, 0x00,
1142     0x08,0x08, 0x00,
1143     0x10,0x04, 0x00,
1144     0x20,0x02, 0x00,
1145     0x40,0x01, 0x00,
1146     0x80,0x00, 0x80, // CROSS 17x17 = 3.5
1147
1148     0x80,0x00, 0x20,
1149     0x40,0x00, 0x40,
1150     0x20,0x00, 0x80,
1151     0x10,0x01, 0x00,
1152     0x08,0x02, 0x00,
1153     0x04,0x04, 0x00,
1154     0x02,0x08, 0x00,
1155     0x01,0x10, 0x00,
1156     0x00,0xa0, 0x00,
1157     0x00,0x40, 0x00,
1158     0x00,0xa0, 0x00,
1159     0x01,0x10, 0x00,
1160     0x02,0x08, 0x00,
1161     0x04,0x04, 0x00,
1162     0x08,0x02, 0x00,
1163     0x10,0x01, 0x00,
1164     0x20,0x00, 0x80,
1165     0x40,0x00, 0x40,
1166     0x80,0x00, 0x20, // CROSS 19x19 = 4.0
1167
1168     0x80,0x00, 0x08,
1169     0x40,0x00, 0x10,
1170     0x20,0x00, 0x20,
1171     0x10,0x00, 0x40,
1172     0x08,0x00, 0x80,
1173     0x04,0x01, 0x00,
1174     0x02,0x02, 0x00,
1175     0x01,0x04, 0x00,
1176     0x00,0x88, 0x00,
1177     0x00,0x50, 0x00,
1178     0x00,0x20, 0x00,
1179     0x00,0x50, 0x00,
1180     0x00,0x88, 0x00,
1181     0x01,0x04, 0x00,
1182     0x02,0x02, 0x00,
1183     0x04,0x01, 0x00,
1184     0x08,0x00, 0x80,
1185     0x10,0x00, 0x40,
1186     0x20,0x00, 0x20,
1187     0x40,0x00, 0x10,
1188     0x80,0x00, 0x08,/* CROSS 21x21 = 4.5 */
1189
1190     0x80,0x00, 0x02,
1191     0x40,0x00, 0x04,
1192     0x20,0x00, 0x08,
1193     0x10,0x00, 0x10,
1194     0x08,0x00, 0x20,
1195     0x04,0x00, 0x40,
1196     0x02,0x00, 0x80,
1197     0x01,0x01, 0x00,
1198     0x00,0x82, 0x00,
1199     0x00,0x44, 0x00,
1200     0x00,0x28, 0x00,
1201     0x00,0x10, 0x00,
1202     0x00,0x28, 0x00,
1203     0x00,0x44, 0x00,
1204     0x00,0x82, 0x00,
1205     0x01,0x01, 0x00,
1206     0x02,0x00, 0x80,
1207     0x04,0x00, 0x40,
1208     0x08,0x00, 0x20,
1209     0x10,0x00, 0x10,
1210     0x20,0x00, 0x08,
1211     0x40,0x00, 0x04,
1212     0x80,0x00, 0x02, // CROSS 23x23 = 5.0
1213
1214     0x80,0x00, 0x00,0x80,
1215     0x40,0x00, 0x01,0x00,
1216     0x20,0x00, 0x02,0x00,
1217     0x10,0x00, 0x04,0x00,
1218     0x08,0x00, 0x08,0x00,
1219     0x04,0x00, 0x10,0x00,
1220     0x02,0x00, 0x20,0x00,
1221     0x01,0x00, 0x40,0x00,
1222     0x00,0x80, 0x80,0x00,
1223     0x00,0x41, 0x00,0x00,
1224     0x00,0x22, 0x00,0x00,
1225     0x00,0x14, 0x00,0x00,
1226     0x00,0x08, 0x00,0x00,
1227     0x00,0x14, 0x00,0x00,
1228     0x00,0x22, 0x00,0x00,
1229     0x00,0x41, 0x00,0x00,
1230     0x00,0x80, 0x80,0x00,
1231     0x01,0x00, 0x40,0x00,
1232     0x02,0x00, 0x20,0x00,
1233     0x04,0x00, 0x10,0x00,
1234     0x08,0x00, 0x08,0x00,
1235     0x10,0x00, 0x04,0x00,
1236     0x20,0x00, 0x02,0x00,
1237     0x40,0x00, 0x01,0x00,
1238     0x80,0x00, 0x00,0x80, // CROSS 25x25 = 5.5
1239
1240     0x80,0x00, 0x00,0x20,
1241     0x40,0x00, 0x00,0x40,
1242     0x20,0x00, 0x00,0x80,
1243     0x10,0x00, 0x01,0x00,
1244     0x08,0x00, 0x02,0x00,
1245     0x04,0x00, 0x04,0x00,
1246     0x02,0x00, 0x08,0x00,
1247     0x01,0x00, 0x10,0x00,
1248     0x00,0x80, 0x20,0x00,
1249     0x00,0x40, 0x40,0x00,
1250     0x00,0x20, 0x80,0x00,
1251     0x00,0x11, 0x00,0x00,
1252     0x00,0x0a, 0x00,0x00,
1253     0x00,0x04, 0x00,0x00,
1254     0x00,0x0a, 0x00,0x00,
1255     0x00,0x11, 0x00,0x00,
1256     0x00,0x20, 0x80,0x00,
1257     0x00,0x40, 0x40,0x00,
1258     0x00,0x80, 0x20,0x00,
1259     0x01,0x00, 0x10,0x00,
1260     0x02,0x00, 0x08,0x00,
1261     0x04,0x00, 0x04,0x00,
1262     0x08,0x00, 0x02,0x00,
1263     0x10,0x00, 0x01,0x00,
1264     0x20,0x00, 0x00,0x80,
1265     0x40,0x00, 0x00,0x40,
1266     0x80,0x00, 0x00,0x20, // CROSS 27x27 = 6.0
1267
1268     0x00,0x00, 0x00,0x00,
1269     0x00,0x00, 0x00,0x00,
1270     0x20,0x00, 0x00,0x04,
1271     0x10,0x00, 0x00,0x08,
1272     0x08,0x00, 0x00,0x10,
1273     0x04,0x00, 0x00,0x20,
1274     0x02,0x00, 0x00,0x40,
1275     0x01,0x00, 0x00,0x80,
1276     0x00,0x80, 0x01,0x00,
1277     0x00,0x40, 0x02,0x00,
1278     0x00,0x20, 0x04,0x00,
1279     0x00,0x10, 0x08,0x00,
1280     0x00,0x08, 0x10,0x00,
1281     0x00,0x04, 0x20,0x00,
1282     0x00,0x02, 0x40,0x00,
1283     0x00,0x01, 0x80,0x00,
1284     0x00,0x01, 0x80,0x00,
1285     0x00,0x02, 0x40,0x00,
1286     0x00,0x04, 0x20,0x00,
1287     0x00,0x08, 0x10,0x00,
1288     0x00,0x10, 0x08,0x00,
1289     0x00,0x20, 0x04,0x00,
1290     0x00,0x40, 0x02,0x00,
1291     0x00,0x80, 0x01,0x00,
1292     0x01,0x00, 0x00,0x80,
1293     0x02,0x00, 0x00,0x40,
1294     0x04,0x00, 0x00,0x20,
1295     0x08,0x00, 0x00,0x10,
1296     0x10,0x00, 0x00,0x08,
1297     0x20,0x00, 0x00,0x04,
1298     0x00,0x00, 0x00,0x00,
1299     0x00,0x00, 0x00,0x00, // CROSS 32x32 = 6.5
1300
1301     0x00,0x00, 0x00,0x00,
1302     0x40,0x00, 0x00,0x02,
1303     0x20,0x00, 0x00,0x04,
1304     0x10,0x00, 0x00,0x08,
1305     0x08,0x00, 0x00,0x10,
1306     0x04,0x00, 0x00,0x20,
1307     0x02,0x00, 0x00,0x40,
1308     0x01,0x00, 0x00,0x80,
1309     0x00,0x80, 0x01,0x00,
1310     0x00,0x40, 0x02,0x00,
1311     0x00,0x20, 0x04,0x00,
1312     0x00,0x10, 0x08,0x00,
1313     0x00,0x08, 0x10,0x00,
1314     0x00,0x04, 0x20,0x00,
1315     0x00,0x02, 0x40,0x00,
1316     0x00,0x01, 0x80,0x00,
1317     0x00,0x01, 0x80,0x00,
1318     0x00,0x02, 0x40,0x00,
1319     0x00,0x04, 0x20,0x00,
1320     0x00,0x08, 0x10,0x00,
1321     0x00,0x10, 0x08,0x00,
1322     0x00,0x20, 0x04,0x00,
1323     0x00,0x40, 0x02,0x00,
1324     0x00,0x80, 0x01,0x00,
1325     0x01,0x00, 0x00,0x80,
1326     0x02,0x00, 0x00,0x40,
1327     0x04,0x00, 0x00,0x20,
1328     0x08,0x00, 0x00,0x10,
1329     0x10,0x00, 0x00,0x08,
1330     0x20,0x00, 0x00,0x04,
1331     0x40,0x00, 0x00,0x02,
1332     0x00,0x00, 0x00,0x00  // CROSS 32x32 = 7.0
1333 };
1334
1335 // =======================================================================
1336 // function : GetMarkerBitMapArray
1337 // purpose  : Returns a parameters for the marker of the specified
1338 //            type and scale.
1339 // =======================================================================
1340 void GetMarkerBitMapParam (const Aspect_TypeOfMarker theMarkerType,
1341                            const Standard_ShortReal& theScale,
1342                            Standard_Integer& theWidth,
1343                            Standard_Integer& theHeight,
1344                            Standard_Integer& theOffset,
1345                            Standard_Integer& theNumOfBytes)
1346 {
1347   const Standard_Integer aType = (Standard_Integer )((theMarkerType > Aspect_TOM_O) ? Aspect_TOM_O : theMarkerType);
1348   const Standard_Real anIndex = (Standard_Real )(TEL_NO_OF_SIZES - 1) * (theScale - (Standard_Real )TEL_PM_START_SIZE)
1349                               / (Standard_Real )(TEL_PM_END_SIZE - TEL_PM_START_SIZE);
1350   Standard_Integer anId = (Standard_Integer )(anIndex + 0.5);
1351   if (anId < 0)
1352   {
1353     anId = 0;
1354   }
1355   else if (anId >= TEL_NO_OF_SIZES)
1356   {
1357     anId = TEL_NO_OF_SIZES - 1;
1358   }
1359
1360   theWidth  = (Standard_Integer )arrPMFontInfo[aType][anId].width;
1361   theHeight = (Standard_Integer )arrPMFontInfo[aType][anId].height;
1362   theOffset = arrPMFontInfo[aType][anId].offset;
1363   const Standard_Integer aNumOfBytesInRow = theWidth / 8 + (theWidth % 8 ? 1 : 0);
1364   theNumOfBytes = theHeight * aNumOfBytesInRow;
1365 }
1366
1367 // =======================================================================
1368 // function : GetTextureImage
1369 // purpose  : Returns a marker image for the marker of the specified
1370 //            type and scale.
1371 // =======================================================================
1372 Handle(Graphic3d_MarkerImage) GetTextureImage (const Aspect_TypeOfMarker theMarkerType,
1373                                                const Standard_ShortReal& theScale)
1374 {
1375   Standard_Integer aWidth, aHeight, anOffset, aNumOfBytes;
1376   GetMarkerBitMapParam (theMarkerType, theScale, aWidth, aHeight, anOffset, aNumOfBytes);
1377
1378   Handle(TColStd_HArray1OfByte) aBitMap = new TColStd_HArray1OfByte (0, aNumOfBytes - 1);
1379   for (Standard_Integer anIter = 0; anIter < aNumOfBytes; anIter++)
1380   {
1381     aBitMap->ChangeValue (anIter) = OpenGl_AspectMarker_myMarkerRaster[anOffset + anIter];
1382   }
1383
1384   Handle(Graphic3d_MarkerImage) aTexture = new Graphic3d_MarkerImage (aBitMap, aWidth, aHeight);
1385   return aTexture;
1386 }
1387
1388 // =======================================================================
1389 // function : MergeImages
1390 // purpose  : Merge two image pixmap into one. Used for creating image for
1391 //            following markers: Aspect_TOM_O_POINT, Aspect_TOM_O_PLUS,
1392 //            Aspect_TOM_O_STAR, Aspect_TOM_O_X, Aspect_TOM_RING1,
1393 //            Aspect_TOM_RING2, Aspect_TOM_RING3
1394 // =======================================================================
1395 Handle(Image_PixMap) MergeImages (const Handle(Image_PixMap)& theImage1,
1396                                   const Handle(Image_PixMap)& theImage2)
1397 {
1398   if (theImage1.IsNull() && theImage2.IsNull())
1399   {
1400     return Handle(Image_PixMap)();
1401   }
1402
1403   Handle(Image_PixMap) aResultImage = new Image_PixMap();
1404
1405   Standard_Integer aWidth1 (0), aHeight1 (0);
1406   if (!theImage1.IsNull())
1407   {
1408     aWidth1  = (Standard_Integer )theImage1->Width();
1409     aHeight1 = (Standard_Integer )theImage1->Height();
1410   }
1411
1412   Standard_Integer aWidth2 (0), aHeight2 (0);
1413   if (!theImage2.IsNull())
1414   {
1415     aWidth2  = (Standard_Integer )theImage2->Width();
1416     aHeight2 = (Standard_Integer )theImage2->Height();
1417   }
1418
1419   const Standard_Integer aMaxWidth  = Max (aWidth1,   aWidth2);
1420   const Standard_Integer aMaxHeight = Max (aHeight1,  aHeight2);
1421   const Standard_Integer aSize      = Max (aMaxWidth, aMaxHeight);
1422
1423   aResultImage->InitZero (Image_PixMap::ImgAlpha, aSize, aSize);
1424
1425   if (!theImage1.IsNull())
1426   {
1427     const Standard_Integer aXOffset1  = Abs (aWidth1  - aMaxWidth)  / 2;
1428     const Standard_Integer anYOffset1 = Abs (aHeight1 - aMaxHeight) / 2;
1429     for (Standard_Integer anY = 0; anY < aHeight1; anY++)
1430     {
1431       Standard_Byte* anImageLine = theImage1->ChangeRow (anY);
1432       Standard_Byte* aResultImageLine = aResultImage->ChangeRow (anYOffset1 + anY);
1433       for (Standard_Integer aX = 0; aX < aWidth1; aX++)
1434       {
1435         aResultImageLine[aXOffset1 + aX] |= anImageLine[aX];
1436       }
1437     }
1438   }
1439
1440   if (!theImage2.IsNull())
1441   {
1442     const Standard_Integer aXOffset2  = Abs (aWidth2  - aMaxWidth)  / 2;
1443     const Standard_Integer anYOffset2 = Abs (aHeight2 - aMaxHeight) / 2;
1444     for (Standard_Integer anY = 0; anY < aHeight2; anY++)
1445     {
1446       Standard_Byte* anImageLine = theImage2->ChangeRow (anY);
1447       Standard_Byte* aResultImageLine = aResultImage->ChangeRow (anYOffset2 + anY);
1448       for (Standard_Integer aX = 0; aX < aWidth2; aX++)
1449       {
1450         aResultImageLine[aXOffset2 + aX] |= anImageLine[aX];
1451       }
1452     }
1453   }
1454
1455   return aResultImage;
1456 }
1457
1458 // =======================================================================
1459 // function : OpenGl_AspectMarker
1460 // purpose  :
1461 // =======================================================================
1462 OpenGl_AspectMarker::OpenGl_AspectMarker()
1463 : myAspect (new Graphic3d_AspectMarker3d (Aspect_TOM_PLUS, Quantity_Color (Quantity_NOC_WHITE), 1.0f)),
1464   myMarkerSize (1.0f)
1465 {
1466   //
1467 }
1468
1469 // =======================================================================
1470 // function : OpenGl_AspectMarker
1471 // purpose  :
1472 // =======================================================================
1473 OpenGl_AspectMarker::OpenGl_AspectMarker (const Handle(Graphic3d_AspectMarker3d)& theAspect)
1474 : myMarkerSize (1.0f)
1475 {
1476   SetAspect (theAspect);
1477 }
1478
1479 // =======================================================================
1480 // function : SetAspect
1481 // purpose  :
1482 // =======================================================================
1483 void OpenGl_AspectMarker::SetAspect (const Handle(Graphic3d_AspectMarker3d)& theAspect)
1484 {
1485   myAspect = theAspect;
1486
1487   // update sprite resource bindings
1488   TCollection_AsciiString aSpriteKey  = THE_EMPTY_KEY;
1489   TCollection_AsciiString aSpriteAKey = THE_EMPTY_KEY;
1490   myResources.SpriteKeys (theAspect->GetMarkerImage(), theAspect->Type(), theAspect->Scale(), theAspect->ColorRGBA(), aSpriteKey, aSpriteAKey);
1491
1492   if (aSpriteKey.IsEmpty()  || myResources.SpriteKey  != aSpriteKey
1493    || aSpriteAKey.IsEmpty() || myResources.SpriteAKey != aSpriteAKey)
1494   {
1495     myResources.ResetSpriteReadiness();
1496     myMarkerSize = theAspect->Scale();
1497   }
1498
1499   // update shader program resource bindings
1500   const TCollection_AsciiString& aShaderKey = myAspect->ShaderProgram().IsNull() ? THE_EMPTY_KEY : myAspect->ShaderProgram()->GetId();
1501
1502   if (aShaderKey.IsEmpty() || myResources.ShaderProgramId != aShaderKey)
1503   {
1504     myResources.ResetShaderReadiness();
1505   }
1506 }
1507
1508 // =======================================================================
1509 // function : Render
1510 // purpose  :
1511 // =======================================================================
1512 void OpenGl_AspectMarker::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
1513 {
1514   theWorkspace->SetAspectMarker (this);
1515 }
1516
1517 // =======================================================================
1518 // function : Release
1519 // purpose  :
1520 // =======================================================================
1521 void OpenGl_AspectMarker::Release (OpenGl_Context* theCtx)
1522 {
1523   if (!myResources.Sprite.IsNull())
1524   {
1525     if (theCtx)
1526     {
1527       if (myResources.SpriteKey.IsEmpty())
1528       {
1529         theCtx->DelayedRelease (myResources.Sprite);
1530         theCtx->DelayedRelease (myResources.SpriteA);
1531       }
1532       else
1533       {
1534         myResources.Sprite.Nullify(); // we need nullify all handles before ReleaseResource() call
1535         myResources.SpriteA.Nullify();
1536         theCtx->ReleaseResource (myResources.SpriteKey,  Standard_True);
1537         theCtx->ReleaseResource (myResources.SpriteAKey, Standard_True);
1538       }
1539     }
1540     myResources.Sprite.Nullify();
1541     myResources.SpriteA.Nullify();
1542   }
1543   myResources.SpriteKey.Clear();
1544   myResources.SpriteAKey.Clear();
1545   myResources.ResetSpriteReadiness();
1546
1547   if (!myResources.ShaderProgram.IsNull() && theCtx)
1548   {
1549     theCtx->ShaderManager()->Unregister (myResources.ShaderProgramId,
1550                                          myResources.ShaderProgram);
1551   }
1552   myResources.ShaderProgramId.Clear();
1553   myResources.ResetShaderReadiness();
1554 }
1555
1556 // =======================================================================
1557 // function : BuildSprites
1558 // purpose  :
1559 // =======================================================================
1560 void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Context)&        theCtx,
1561                                                    const Handle(Graphic3d_MarkerImage)& theMarkerImage,
1562                                                    const Aspect_TypeOfMarker theType,
1563                                                    const Standard_ShortReal theScale,
1564                                                    const Graphic3d_Vec4& theColor,
1565                                                    Standard_ShortReal& theMarkerSize)
1566 {
1567   // generate key for shared resource
1568   TCollection_AsciiString aNewKey  = THE_EMPTY_KEY;
1569   TCollection_AsciiString aNewKeyA = THE_EMPTY_KEY;
1570   SpriteKeys (theMarkerImage, theType, theScale, theColor, aNewKey, aNewKeyA);
1571
1572   // release old shared resources
1573   const Standard_Boolean aNewResource = aNewKey.IsEmpty() || SpriteKey != aNewKey;
1574   if (aNewResource)
1575   {
1576     if (!Sprite.IsNull())
1577     {
1578       if (SpriteKey.IsEmpty())
1579       {
1580         theCtx->DelayedRelease (Sprite);
1581         Sprite.Nullify();
1582       }
1583       else
1584       {
1585         Sprite.Nullify(); // we need nullify all handles before ReleaseResource() call
1586         theCtx->ReleaseResource (SpriteKey, Standard_True);
1587       }
1588     }
1589     SpriteKey = aNewKey;
1590   }
1591   if (aNewKeyA.IsEmpty() || SpriteAKey != aNewKeyA)
1592   {
1593     if (!SpriteA.IsNull())
1594     {
1595       if (SpriteAKey.IsEmpty())
1596       {
1597         theCtx->DelayedRelease (SpriteA);
1598         SpriteA.Nullify();
1599       }
1600       else
1601       {
1602         SpriteA.Nullify(); // we need nullify all handles before ReleaseResource() call
1603         theCtx->ReleaseResource (SpriteAKey, Standard_True);
1604       }
1605     }
1606     SpriteAKey = aNewKeyA;
1607   }
1608   if (theType == Aspect_TOM_POINT
1609    || theType == Aspect_TOM_EMPTY
1610    || !aNewResource
1611    || (theType == Aspect_TOM_USERDEFINED && theMarkerImage.IsNull()))
1612   {
1613     // nothing to do - just simple point
1614     return;
1615   }
1616
1617   if (!aNewKey.IsEmpty()
1618    && theCtx->GetResource<Handle(OpenGl_PointSprite)> (aNewKeyA, SpriteA) // alpha sprite could be shared
1619    && theCtx->GetResource<Handle(OpenGl_PointSprite)> (aNewKey,  Sprite))
1620   {
1621     // reuse shared resource
1622     if (!Sprite->IsDisplayList())
1623     {
1624       theMarkerSize = Standard_ShortReal (Max (Sprite->SizeX(), Sprite->SizeY()));
1625     }
1626     return;
1627   }
1628
1629   const bool hadAlreadyAlpha = !SpriteA.IsNull();
1630   if (!hadAlreadyAlpha)
1631   {
1632     SpriteA = new OpenGl_PointSprite();
1633   }
1634   Sprite  = new OpenGl_PointSprite();
1635   if (!aNewKey.IsEmpty())
1636   {
1637     theCtx->ShareResource (aNewKey,  Sprite);
1638     if (!hadAlreadyAlpha)
1639     {
1640       theCtx->ShareResource (aNewKeyA, SpriteA);
1641     }
1642   }
1643
1644   if (!theCtx.IsNull()
1645    &&  theCtx->core20fwd != NULL
1646    && !theCtx->caps->pntSpritesDisable)
1647   {
1648     // Creating texture resource for using it with point sprites
1649     Handle(Graphic3d_MarkerImage) aNewMarkerImage;
1650     Handle(Image_PixMap) anImage, anImageA;
1651
1652     if (theType == Aspect_TOM_USERDEFINED && !theMarkerImage.IsNull())
1653     {
1654       aNewMarkerImage = theMarkerImage;
1655       anImage = aNewMarkerImage->GetImage();
1656     }
1657     else
1658     {
1659       // Creating image from default bitmap
1660       Handle(Graphic3d_MarkerImage) aMarkerImage1, aMarkerImage2;
1661
1662       const Standard_ShortReal aDelta = 0.1F;
1663       Standard_ShortReal aScale = theScale;
1664       Standard_ShortReal aLimit = 0.0F;
1665
1666       switch (theType)
1667       {
1668         case Aspect_TOM_O_POINT:
1669         {
1670           // draw inner point as filled rectangle
1671           const Standard_Integer        aSize   = theScale > 7 ? 7 : (Standard_Integer )(theScale + 0.5F);
1672           Handle(TColStd_HArray1OfByte) aBitMap = fillPointBitmap (aSize);
1673           aMarkerImage2 = new Graphic3d_MarkerImage (aBitMap, aSize, aSize);
1674         }
1675         case Aspect_TOM_O_PLUS:
1676         case Aspect_TOM_O_STAR:
1677         case Aspect_TOM_O_X:
1678         {
1679           // For this type of markers we merge two base bitmaps into one
1680           // For example Aspect_TOM_O_PLUS = Aspect_TOM_O + Aspect_TOM_PLUS
1681           aMarkerImage1 = GetTextureImage (Aspect_TOM_O, theScale);
1682           if (theType != Aspect_TOM_O_POINT)
1683           {
1684             aMarkerImage2 = GetTextureImage (Aspect_TypeOfMarker (theType - Aspect_TOM_O_POINT), theScale);
1685           }
1686           anImage = MergeImages (aMarkerImage1->GetImage(), aMarkerImage2->GetImage());
1687           aNewMarkerImage = new Graphic3d_MarkerImage (anImage);
1688           break;
1689         }
1690         case Aspect_TOM_RING1:
1691           if (aLimit == 0.0f) aLimit = aScale * 0.2f;
1692         case Aspect_TOM_RING2:
1693           if (aLimit == 0.0f) aLimit = aScale * 0.5f;
1694         case Aspect_TOM_RING3:
1695         {
1696           if (aLimit == 0.0f) aLimit = aScale * 0.8f;
1697           for (; aScale > aLimit && aScale >= 1.0f; aScale -= aDelta)
1698           {
1699             anImage = MergeImages (anImage, GetTextureImage (Aspect_TOM_O, aScale)->GetImage());
1700           }
1701           aNewMarkerImage = new Graphic3d_MarkerImage (anImage);
1702           break;
1703         }
1704         case Aspect_TOM_BALL:
1705         {
1706           Standard_Integer aWidth, aHeight, anOffset, aNumOfBytes;
1707           GetMarkerBitMapParam (Aspect_TOM_O, aScale, aWidth, aHeight, anOffset, aNumOfBytes);
1708
1709           NCollection_Vec4<Standard_Real> aColor (Standard_Real (theColor.r()),
1710                                                   Standard_Real (theColor.g()),
1711                                                   Standard_Real (theColor.b()),
1712                                                   Standard_Real (theColor.a()));
1713
1714           const Standard_Integer aSize = Max (aWidth + 2, aHeight + 2); // includes extra margin
1715           anImage  = new Image_PixMap();
1716           anImageA = new Image_PixMap();
1717           anImage ->InitZero (Image_PixMap::ImgBGRA,  aSize, aSize);
1718           anImageA->InitZero (Image_PixMap::ImgAlpha, aSize, aSize);
1719
1720           // we draw a set of circles
1721           Image_ColorBGRA aColor32;
1722           aColor32.a() = 255;
1723           Standard_Real aHLS[3];
1724           while (aScale >= 1.0f)
1725           {
1726             Quantity_Color::RgbHls (aColor.r(), aColor.g(), aColor.b(), aHLS[0], aHLS[1], aHLS[2]);
1727             aHLS[2] *= 0.95; // 5% saturation change
1728             Quantity_Color::HlsRgb (aHLS[0], aHLS[1], aHLS[2], aColor.r(), aColor.g(), aColor.b());
1729             aColor32.r() = Standard_Byte(255.0 * aColor.r());
1730             aColor32.g() = Standard_Byte(255.0 * aColor.g());
1731             aColor32.b() = Standard_Byte(255.0 * aColor.b());
1732
1733             const Handle(Graphic3d_MarkerImage) aMarker = GetTextureImage (Aspect_TOM_O, aScale);
1734             const Handle(Image_PixMap)& aCircle = aMarker->GetImage();
1735
1736             const Standard_Size aDiffX = (anImage->SizeX() - aCircle->SizeX()) / 2;
1737             const Standard_Size aDiffY = (anImage->SizeY() - aCircle->SizeY()) / 2;
1738             for (Standard_Size aRow = 0; aRow < aCircle->SizeY(); ++aRow)
1739             {
1740               const Standard_Byte* aRowData = aCircle->Row (aRow);
1741               for (Standard_Size aCol = 0; aCol < aCircle->SizeX(); ++aCol)
1742               {
1743                 if (aRowData[aCol] != 0)
1744                 {
1745                   anImage ->ChangeValue<Image_ColorBGRA> (aDiffX + aRow, aDiffY + aCol) = aColor32;
1746                   anImageA->ChangeValue<Standard_Byte>   (aDiffX + aRow, aDiffY + aCol) = 255;
1747                 }
1748               }
1749             }
1750             aScale -= aDelta;
1751           }
1752           break;
1753         }
1754         default:
1755         {
1756           aNewMarkerImage = GetTextureImage (theType, theScale);
1757           anImage = aNewMarkerImage->GetImage();
1758           break;
1759         }
1760       }
1761     }
1762
1763     theMarkerSize = Max ((Standard_ShortReal )anImage->Width(),(Standard_ShortReal )anImage->Height());
1764
1765     Sprite->Init (theCtx, *anImage.operator->(), Graphic3d_TOT_2D);
1766     if (!hadAlreadyAlpha)
1767     {
1768       if (anImageA.IsNull()
1769        && Sprite->GetFormat() != GL_ALPHA
1770        && !aNewMarkerImage.IsNull())
1771       {
1772         anImageA = aNewMarkerImage->GetImageAlpha();
1773       }
1774       if (!anImageA.IsNull())
1775       {
1776         SpriteA->Init (theCtx, *anImageA.operator->(), Graphic3d_TOT_2D);
1777       }
1778     }
1779   }
1780   else
1781   {
1782   #if !defined(GL_ES_VERSION_2_0)
1783     // Creating list with bitmap for using it in compatibility mode
1784     GLuint aBitmapList = glGenLists (1);
1785     Sprite->SetDisplayList (theCtx, aBitmapList);
1786
1787     Standard_Integer aWidth, aHeight, anOffset, aNumOfBytes;
1788     if (theType == Aspect_TOM_USERDEFINED && !theMarkerImage.IsNull())
1789     {
1790       // Reading user defined marker
1791       Handle(TColStd_HArray1OfByte) aBitMap = theMarkerImage->GetBitMapArray();
1792       Standard_Byte* aBitMapArray = new Standard_Byte[aBitMap->Length()];
1793       theMarkerImage->GetTextureSize (aWidth, aHeight);
1794
1795       // We should pass bitmap to glBitmap with reversed line order as it draws it from
1796       // bottom to top
1797       const Standard_Integer aNumOfBytesInRow = aWidth / 8 + (aWidth % 8 ? 1 : 0);
1798       const Standard_Integer anUpperIndex = aBitMap->Upper();
1799       for (Standard_Integer aRow = 0; aRow < aHeight; aRow++)
1800       {
1801         for (Standard_Integer aByteIter = 0; aByteIter < aNumOfBytesInRow; aByteIter++)
1802         {
1803           aBitMapArray[aRow * aNumOfBytesInRow + aByteIter] =
1804             aBitMap->Value (anUpperIndex + 1 - (aRow + 1) * aNumOfBytesInRow + aByteIter);
1805         }
1806       }
1807
1808       if (aBitMapArray != NULL)
1809       {
1810         glNewList (aBitmapList, GL_COMPILE);
1811         glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, (GLfloat )(0.5f * aWidth), (GLfloat )(0.5f * aHeight),
1812                   0.f, 0.f, (const GLubyte* )aBitMapArray);
1813         glEndList();
1814       }
1815     }
1816     else
1817     {
1818       // Creating list for default marker
1819       const Standard_ShortReal aDelta = 0.1f;
1820       Standard_ShortReal aScale = theScale;
1821       Standard_ShortReal aLimit = 0.0f;
1822
1823       glNewList (aBitmapList, GL_COMPILE);
1824       switch (theType)
1825       {
1826         case Aspect_TOM_O_POINT:
1827         {
1828           // draw inner point as filled rectangle
1829           const Standard_Integer        aSize   = theScale > 7 ? 7 : (Standard_Integer )(theScale + 0.5F);
1830           Handle(TColStd_HArray1OfByte) aBitMap = fillPointBitmap (aSize);
1831           glBitmap (aSize, aSize, (GLfloat )(0.5f * aSize), (GLfloat )(0.5f * aSize),
1832                     0.0f, 0.0f, &aBitMap->Array1().Value (aBitMap->Lower()));
1833         }
1834         case Aspect_TOM_O_PLUS:
1835         case Aspect_TOM_O_STAR:
1836         case Aspect_TOM_O_X:
1837         {
1838           // For this type of markers we merge two base bitmaps into one
1839           // For example Aspect_TOM_O_PLUS = Aspect_TOM_O + Aspect_TOM_PLUS
1840           GetMarkerBitMapParam (Aspect_TOM_O, theScale, aWidth, aHeight, anOffset, aNumOfBytes);
1841           glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, (GLfloat )(0.5f * aWidth), (GLfloat )(0.5f * aHeight),
1842                     0.f, 0.f, (const GLubyte* )&OpenGl_AspectMarker_myMarkerRaster[anOffset]);
1843           if (theType != Aspect_TOM_O_POINT)
1844           {
1845             GetMarkerBitMapParam (Aspect_TypeOfMarker (theType - Aspect_TOM_O_POINT), theScale, aWidth, aHeight, anOffset, aNumOfBytes);
1846             glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, (GLfloat )(0.5f * aWidth), (GLfloat )(0.5f * aHeight),
1847                       0.f, 0.f, (const GLubyte* )&OpenGl_AspectMarker_myMarkerRaster[anOffset]);
1848           }
1849           break;
1850         }
1851         case Aspect_TOM_BALL:
1852         {
1853           NCollection_Vec4<Standard_Real> aColor (Standard_Real (theColor.r()),
1854                                                   Standard_Real (theColor.g()),
1855                                                   Standard_Real (theColor.b()),
1856                                                   Standard_Real (theColor.a()));
1857
1858           // we draw a set of circles
1859           while (aScale >= 1.0f)
1860           {
1861             Standard_Real aHLS[3];
1862             Quantity_Color::RgbHls (aColor.r(), aColor.g(), aColor.b(), aHLS[0], aHLS[1], aHLS[2]);
1863             // 5% saturation change
1864             aHLS[2] *= 0.95;
1865             Quantity_Color::HlsRgb (aHLS[0], aHLS[1], aHLS[2], aColor.r(), aColor.g(), aColor.b());
1866
1867             glColor4dv (aColor);
1868             GetMarkerBitMapParam (Aspect_TOM_O, aScale, aWidth, aHeight, anOffset, aNumOfBytes);
1869             glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, 0.5f * GLfloat(aWidth), 0.5f * GLfloat(aHeight),
1870                       0.0f, 0.0f, (const GLubyte* )&OpenGl_AspectMarker_myMarkerRaster[anOffset]);
1871
1872             aScale -= aDelta;
1873           }
1874           break;
1875         }
1876         case Aspect_TOM_RING1:
1877           if (aLimit == 0.0f) aLimit = aScale * 0.2f;
1878         case Aspect_TOM_RING2:
1879           if (aLimit == 0.0f) aLimit = aScale * 0.5f;
1880         case Aspect_TOM_RING3:
1881         {
1882           if (aLimit == 0.0f) aLimit = aScale * 0.8f;
1883           for (; aScale > aLimit && aScale >= 1.0f; aScale -= aDelta)
1884           {
1885             GetMarkerBitMapParam (Aspect_TOM_O, aScale, aWidth, aHeight, anOffset, aNumOfBytes);
1886             glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, 0.5f * GLfloat(aWidth), 0.5f * GLfloat(aHeight),
1887                       0.0f, 0.0f, (const GLubyte* )&OpenGl_AspectMarker_myMarkerRaster[anOffset]);
1888           }
1889           break;
1890         }
1891         default:
1892         {
1893           GetMarkerBitMapParam (theType, theScale, aWidth, aHeight, anOffset, aNumOfBytes);
1894           glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, 0.5f * GLfloat(aWidth), 0.5f * GLfloat(aHeight),
1895                     0.0f, 0.0f, (const GLubyte* )&OpenGl_AspectMarker_myMarkerRaster[anOffset]);
1896           break;
1897         }
1898       }
1899       glEndList();
1900     }
1901   #endif
1902   }
1903 }
1904
1905 // =======================================================================
1906 // function : BuildShader
1907 // purpose  :
1908 // =======================================================================
1909 void OpenGl_AspectMarker::Resources::BuildShader (const Handle(OpenGl_Context)&          theCtx,
1910                                                   const Handle(Graphic3d_ShaderProgram)& theShader)
1911 {
1912   if (theCtx->core20fwd == NULL)
1913   {
1914     return;
1915   }
1916
1917   // release old shader program resources
1918   if (!ShaderProgram.IsNull())
1919   {
1920     theCtx->ShaderManager()->Unregister (ShaderProgramId, ShaderProgram);
1921     ShaderProgramId.Clear();
1922     ShaderProgram.Nullify();
1923   }
1924   if (theShader.IsNull())
1925   {
1926     return;
1927   }
1928
1929   theCtx->ShaderManager()->Create (theShader, ShaderProgramId, ShaderProgram);
1930 }
1931
1932 // =======================================================================
1933 // function : resourceKeys
1934 // purpose  :
1935 // =======================================================================
1936 void OpenGl_AspectMarker::Resources::SpriteKeys (const Handle(Graphic3d_MarkerImage)& theMarkerImage,
1937                                                  const Aspect_TypeOfMarker theType,
1938                                                  const Standard_ShortReal theScale,
1939                                                  const Graphic3d_Vec4& theColor,
1940                                                  TCollection_AsciiString& theKey,
1941                                                  TCollection_AsciiString& theKeyA)
1942 {
1943   // generate key for shared resource
1944   if (theType == Aspect_TOM_USERDEFINED)
1945   {
1946     if (!theMarkerImage.IsNull())
1947     {
1948       theKey  = theMarkerImage->GetImageId();
1949       theKeyA = theMarkerImage->GetImageAlphaId();
1950     }
1951   }
1952   else if (theType != Aspect_TOM_POINT
1953         && theType != Aspect_TOM_EMPTY)
1954   {
1955     // predefined markers are defined with 0.5 step
1956     const Standard_Integer aScale = Standard_Integer(theScale * 10.0f + 0.5f);
1957     theKey  = TCollection_AsciiString ("OpenGl_AspectMarker") + theType + "_" + aScale;
1958     theKeyA = theKey + "A";
1959     if (theType == Aspect_TOM_BALL)
1960     {
1961       unsigned int aColor[3] =
1962       {
1963         (unsigned int )(255.0f * theColor.r()),
1964         (unsigned int )(255.0f * theColor.g()),
1965         (unsigned int )(255.0f * theColor.b())
1966       };
1967       char aBytes[8];
1968       sprintf (aBytes, "%02X%02X%02X", aColor[0], aColor[1], aColor[2]);
1969       theKey += aBytes;
1970     }
1971   }
1972 }