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