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