// Created on: 2011-07-14 // Created by: Sergey ZERCHANINOV // Copyright (c) 2011-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #include #include #include #include #include #include #include #include #include #include #include #include namespace { static const TEL_COLOUR myDefaultColor = {{ 1.0F, 1.0F, 1.0F, 1.0F }}; static const TCollection_AsciiString THE_EMPTY_KEY; //! Draw inner point as filled rectangle static Handle(TColStd_HArray1OfByte) fillPointBitmap (const Standard_Integer theSize) { // draw inner point as filled rectangle const Standard_Integer aNumOfBytes = (theSize / 8 + (theSize % 8 ? 1 : 0)) * theSize; Handle(TColStd_HArray1OfByte) aBitMap = new TColStd_HArray1OfByte (0, aNumOfBytes - 1); for (Standard_Integer anIter = 0; anIter < aBitMap->Length(); ++anIter) { aBitMap->SetValue (anIter, 255); } return aBitMap; } } // Following Section relates to default markers #define TEL_NO_OF_SIZES 13 #define TEL_PM_START_SIZE 1.0 #define TEL_PM_END_SIZE 7.0 struct PM_FONT_INFO { Tfloat width, height; Tint offset; }; typedef PM_FONT_INFO* pm_font_info; #define PM_PLUS_10_NUM 9*2 #define PM_PLUS_15_NUM 11*2 #define PM_PLUS_20_NUM 13*2 #define PM_PLUS_25_NUM 15*2 #define PM_PLUS_30_NUM 17*3 #define PM_PLUS_35_NUM 19*3 #define PM_PLUS_40_NUM 21*3 #define PM_PLUS_45_NUM 23*3 #define PM_PLUS_50_NUM 25*4 #define PM_PLUS_55_NUM 27*4 #define PM_PLUS_60_NUM 29*4 #define PM_PLUS_65_NUM 31*4 #define PM_PLUS_70_NUM 32*4 #define PM_STAR_10_NUM 9 #define PM_STAR_15_NUM 11*2 #define PM_STAR_20_NUM 13*2 #define PM_STAR_25_NUM 15*2 #define PM_STAR_30_NUM 17*2 #define PM_STAR_35_NUM 19*2 #define PM_STAR_40_NUM 21*3 #define PM_STAR_45_NUM 23*3 #define PM_STAR_50_NUM 25*3 #define PM_STAR_55_NUM 27*3 #define PM_STAR_60_NUM 29*4 #define PM_STAR_65_NUM 32*4 #define PM_STAR_70_NUM 32*4 #define PM_CIRC_10_NUM 7 #define PM_CIRC_15_NUM 9*2 #define PM_CIRC_20_NUM 9*2 #define PM_CIRC_25_NUM 11*2 #define PM_CIRC_30_NUM 13*2 #define PM_CIRC_35_NUM 15*2 #define PM_CIRC_40_NUM 17*3 #define PM_CIRC_45_NUM 19*3 #define PM_CIRC_50_NUM 21*3 #define PM_CIRC_55_NUM 23*3 #define PM_CIRC_60_NUM 25*4 #define PM_CIRC_65_NUM 27*4 #define PM_CIRC_70_NUM 29*4 #define PM_CROSS_10_NUM 7 #define PM_CROSS_15_NUM 9*2 #define PM_CROSS_20_NUM 11*2 #define PM_CROSS_25_NUM 13*2 #define PM_CROSS_30_NUM 15*2 #define PM_CROSS_35_NUM 17*3 #define PM_CROSS_40_NUM 19*3 #define PM_CROSS_45_NUM 21*3 #define PM_CROSS_50_NUM 23*3 #define PM_CROSS_55_NUM 25*4 #define PM_CROSS_60_NUM 27*4 #define PM_CROSS_65_NUM 32*4 #define PM_CROSS_70_NUM 32*4 #define PM_PLUS_10_OFT 0 #define PM_PLUS_15_OFT PM_PLUS_10_OFT + PM_PLUS_10_NUM #define PM_PLUS_20_OFT PM_PLUS_15_OFT + PM_PLUS_15_NUM #define PM_PLUS_25_OFT PM_PLUS_20_OFT + PM_PLUS_20_NUM #define PM_PLUS_30_OFT PM_PLUS_25_OFT + PM_PLUS_25_NUM #define PM_PLUS_35_OFT PM_PLUS_30_OFT + PM_PLUS_30_NUM #define PM_PLUS_40_OFT PM_PLUS_35_OFT + PM_PLUS_35_NUM #define PM_PLUS_45_OFT PM_PLUS_40_OFT + PM_PLUS_40_NUM #define PM_PLUS_50_OFT PM_PLUS_45_OFT + PM_PLUS_45_NUM #define PM_PLUS_55_OFT PM_PLUS_50_OFT + PM_PLUS_50_NUM #define PM_PLUS_60_OFT PM_PLUS_55_OFT + PM_PLUS_55_NUM #define PM_PLUS_65_OFT PM_PLUS_60_OFT + PM_PLUS_60_NUM #define PM_PLUS_70_OFT PM_PLUS_65_OFT + PM_PLUS_65_NUM #define PM_STAR_10_OFT PM_PLUS_70_OFT + PM_PLUS_70_NUM #define PM_STAR_15_OFT PM_STAR_10_OFT + PM_STAR_10_NUM #define PM_STAR_20_OFT PM_STAR_15_OFT + PM_STAR_15_NUM #define PM_STAR_25_OFT PM_STAR_20_OFT + PM_STAR_20_NUM #define PM_STAR_30_OFT PM_STAR_25_OFT + PM_STAR_25_NUM #define PM_STAR_35_OFT PM_STAR_30_OFT + PM_STAR_30_NUM #define PM_STAR_40_OFT PM_STAR_35_OFT + PM_STAR_35_NUM #define PM_STAR_45_OFT PM_STAR_40_OFT + PM_STAR_40_NUM #define PM_STAR_50_OFT PM_STAR_45_OFT + PM_STAR_45_NUM #define PM_STAR_55_OFT PM_STAR_50_OFT + PM_STAR_50_NUM #define PM_STAR_60_OFT PM_STAR_55_OFT + PM_STAR_55_NUM #define PM_STAR_65_OFT PM_STAR_60_OFT + PM_STAR_60_NUM #define PM_STAR_70_OFT PM_STAR_65_OFT + PM_STAR_65_NUM #define PM_CIRC_10_OFT PM_STAR_70_OFT + PM_STAR_70_NUM #define PM_CIRC_15_OFT PM_CIRC_10_OFT + PM_CIRC_10_NUM #define PM_CIRC_20_OFT PM_CIRC_15_OFT + PM_CIRC_15_NUM #define PM_CIRC_25_OFT PM_CIRC_20_OFT + PM_CIRC_20_NUM #define PM_CIRC_30_OFT PM_CIRC_25_OFT + PM_CIRC_25_NUM #define PM_CIRC_35_OFT PM_CIRC_30_OFT + PM_CIRC_30_NUM #define PM_CIRC_40_OFT PM_CIRC_35_OFT + PM_CIRC_35_NUM #define PM_CIRC_45_OFT PM_CIRC_40_OFT + PM_CIRC_40_NUM #define PM_CIRC_50_OFT PM_CIRC_45_OFT + PM_CIRC_45_NUM #define PM_CIRC_55_OFT PM_CIRC_50_OFT + PM_CIRC_50_NUM #define PM_CIRC_60_OFT PM_CIRC_55_OFT + PM_CIRC_55_NUM #define PM_CIRC_65_OFT PM_CIRC_60_OFT + PM_CIRC_60_NUM #define PM_CIRC_70_OFT PM_CIRC_65_OFT + PM_CIRC_65_NUM #define PM_CROSS_10_OFT PM_CIRC_70_OFT + PM_CIRC_70_NUM #define PM_CROSS_15_OFT PM_CROSS_10_OFT + PM_CROSS_10_NUM #define PM_CROSS_20_OFT PM_CROSS_15_OFT + PM_CROSS_15_NUM #define PM_CROSS_25_OFT PM_CROSS_20_OFT + PM_CROSS_20_NUM #define PM_CROSS_30_OFT PM_CROSS_25_OFT + PM_CROSS_25_NUM #define PM_CROSS_35_OFT PM_CROSS_30_OFT + PM_CROSS_30_NUM #define PM_CROSS_40_OFT PM_CROSS_35_OFT + PM_CROSS_35_NUM #define PM_CROSS_45_OFT PM_CROSS_40_OFT + PM_CROSS_40_NUM #define PM_CROSS_50_OFT PM_CROSS_45_OFT + PM_CROSS_45_NUM #define PM_CROSS_55_OFT PM_CROSS_50_OFT + PM_CROSS_50_NUM #define PM_CROSS_60_OFT PM_CROSS_55_OFT + PM_CROSS_55_NUM #define PM_CROSS_65_OFT PM_CROSS_60_OFT + PM_CROSS_60_NUM #define PM_CROSS_70_OFT PM_CROSS_65_OFT + PM_CROSS_65_NUM static const PM_FONT_INFO arrPMFontInfo[][TEL_NO_OF_SIZES] = { // TOM_POINT - not used {{0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}, // TOM_PLUS {{ 9.f, 9.f, PM_PLUS_10_OFT}, {11.f, 11.f, PM_PLUS_15_OFT}, {13.f, 13.f, PM_PLUS_20_OFT}, {15.f, 15.f, PM_PLUS_25_OFT}, {17.f, 17.f, PM_PLUS_30_OFT}, {19.f, 19.f, PM_PLUS_35_OFT}, {21.f, 21.f, PM_PLUS_40_OFT}, {23.f, 23.f, PM_PLUS_45_OFT}, {25.f, 25.f, PM_PLUS_50_OFT}, {27.f, 27.f, PM_PLUS_55_OFT}, {29.f, 29.f, PM_PLUS_60_OFT}, {31.f, 31.f, PM_PLUS_65_OFT}, {32.f, 32.f, PM_PLUS_70_OFT}}, // TOM_STAR {{ 7.f, 9.f, PM_STAR_10_OFT}, {9.f, 11.f, PM_STAR_15_OFT}, {11.f, 13.f, PM_STAR_20_OFT}, {13.f, 15.f, PM_STAR_25_OFT}, {13.f, 17.f, PM_STAR_30_OFT}, {15.f, 19.f, PM_STAR_35_OFT}, {17.f, 21.f, PM_STAR_40_OFT}, {19.f, 23.f, PM_STAR_45_OFT}, {21.f, 25.f, PM_STAR_50_OFT}, {23.f, 27.f, PM_STAR_55_OFT}, {25.f, 29.f, PM_STAR_60_OFT}, {32.f, 32.f, PM_STAR_65_OFT}, {32.f, 32.f, PM_STAR_70_OFT}}, // TOM_X {{ 7.f, 7.f, PM_CROSS_10_OFT}, { 9.f, 9.f, PM_CROSS_15_OFT}, {11.f, 11.f, PM_CROSS_20_OFT}, {13.f, 13.f, PM_CROSS_25_OFT}, {15.f, 15.f, PM_CROSS_30_OFT}, {17.f, 17.f, PM_CROSS_35_OFT}, {19.f, 19.f, PM_CROSS_40_OFT}, {21.f, 21.f, PM_CROSS_45_OFT}, {23.f, 23.f, PM_CROSS_50_OFT}, {25.f, 25.f, PM_CROSS_55_OFT}, {27.f, 27.f, PM_CROSS_60_OFT}, {32.f, 32.f, PM_CROSS_65_OFT}, {32.f, 32.f, PM_CROSS_70_OFT}}, // TOM_O {{ 7.f, 7.f, PM_CIRC_10_OFT}, { 9.f, 9.f, PM_CIRC_15_OFT}, { 9.f, 9.f, PM_CIRC_20_OFT}, {11.f, 11.f, PM_CIRC_25_OFT}, {13.f, 13.f, PM_CIRC_30_OFT}, {15.f, 15.f, PM_CIRC_35_OFT}, {17.f, 17.f, PM_CIRC_40_OFT}, {19.f, 19.f, PM_CIRC_45_OFT}, {21.f, 21.f, PM_CIRC_50_OFT}, {23.f, 23.f, PM_CIRC_55_OFT}, {25.f, 25.f, PM_CIRC_60_OFT}, {27.f, 27.f, PM_CIRC_65_OFT}, {29.f, 29.f, PM_CIRC_70_OFT}} }; static const Standard_Byte OpenGl_AspectMarker_myMarkerRaster[] = { // TYPE = PLUS 0x08,0x00, 0x08,0x00, 0x08,0x00, 0x08,0x00, 0xff,0x80, 0x08,0x00, 0x08,0x00, 0x08,0x00, 0x08,0x00, // PLUS 9x9 = 1.0 0x04,0x00, 0x04,0x00, 0x04,0x00, 0x04,0x00, 0x04,0x00, 0xff,0xe0, 0x04,0x00, 0x04,0x00, 0x04,0x00, 0x04,0x00, 0x04,0x00, // PLUS 11x11 = 1.5 0x02,0x00, 0x02,0x00, 0x02,0x00, 0x02,0x00, 0x02,0x00, 0x02,0x00, 0xff,0xf8, 0x02,0x00, 0x02,0x00, 0x02,0x00, 0x02,0x00, 0x02,0x00, 0x02,0x00, // PLUS 13x13 = 2.0 0x01,0x00, 0x01,0x00, 0x01,0x00, 0x01,0x00, 0x01,0x00, 0x01,0x00, 0x01,0x00, 0xff,0xfe, 0x01,0x00, 0x01,0x00, 0x01,0x00, 0x01,0x00, 0x01,0x00, 0x01,0x00, 0x01,0x00, // PLUS 15x15 = 2.5 0x00,0x80, 0x00, 0x00,0x80, 0x00, 0x00,0x80, 0x00, 0x00,0x80, 0x00, 0x00,0x80, 0x00, 0x00,0x80, 0x00, 0x00,0x80, 0x00, 0x00,0x80, 0x00, 0xff,0xff, 0x80, 0x00,0x80, 0x00, 0x00,0x80, 0x00, 0x00,0x80, 0x00, 0x00,0x80, 0x00, 0x00,0x80, 0x00, 0x00,0x80, 0x00, 0x00,0x80, 0x00, 0x00,0x80, 0x00, // PLUS 17x17 = 3.0 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0xff,0xff, 0xe0, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, // PLUS 19x19 = 3.5 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0xff,0xff, 0xf8, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, // PLUS 21x21 = 4.0 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0xff,0xff, 0xfe, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, // PLUS 23x23 = 4.5 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0xff,0xff, 0xff,0x80, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, // PLUS 25x25 = 5.0 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0xff,0xff, 0xff,0xe0, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x04, 0x00,0x00, // PLUS 27x27 = 5.5 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0xff,0xff, 0xff,0xf8, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x02, 0x00,0x00, // PLUS 29x29 = 6.0 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0xff,0xff, 0xff,0xfd, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00, // PLUS 31x31 = 6.5 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0xff,0xff, 0xff,0xff, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, // PLUS 32x32 = 7.0 // TYPE = STAR 0x10, 0x10, 0xd6, 0x38, 0x10, 0x38, 0xd6, 0x10, 0x10, // STAR 7x9 = 1.0 0x08,0x00, 0x08,0x00, 0x08,0x00, 0xc9,0x80, 0x3e,0x00, 0x08,0x00, 0x3e,0x00, 0xc9,0x80, 0x08,0x00, 0x08,0x00, 0x08,0x00, // STAR 9x11 = 1.5 0x04,0x00, 0x04,0x00, 0x04,0x00, 0x84,0x20, 0x64,0xc0, 0x1f,0x00, 0x04,0x00, 0x1f,0x00, 0x64,0xc0, 0x84,0x20, 0x04,0x00, 0x04,0x00, 0x04,0x00, // STAR 11x13 = 2.0 0x02,0x00, 0x02,0x00, 0x02,0x00, 0x02,0x00, 0x82,0x18, 0x62,0x60, 0x1b,0x80, 0x06,0x00, 0x1b,0x80, 0x62,0x60, 0x82,0x18, 0x02,0x00, 0x02,0x00, 0x02,0x00, 0x02,0x00, // STAR 13x15 = 2.5 0x02,0x00, 0x02,0x00, 0x02,0x00, 0x02,0x00, 0x82,0x08, 0x62,0x30, 0x12,0x40, 0x0f,0x80, 0x02,0x00, 0x0f,0x80, 0x12,0x40, 0x62,0x30, 0x82,0x08, 0x02,0x00, 0x02,0x00, 0x02,0x00, 0x02,0x00, // STAR 13x17 = 3.0 0x01,0x00, 0x01,0x00, 0x01,0x00, 0x01,0x00, 0x01,0x00, 0xc1,0x06, 0x21,0x18, 0x19,0x20, 0x07,0xc0, 0x01,0x00, 0x07,0xc0, 0x19,0x20, 0x21,0x18, 0xc1,0x06, 0x01,0x00, 0x01,0x00, 0x01,0x00, 0x01,0x00, 0x01,0x00, // STAR 15x19 = 3.5 0x00,0x80, 0x00, 0x00,0x80, 0x00, 0x00,0x80, 0x00, 0x00,0x80, 0x00, 0x00,0x80, 0x00, 0x80,0x80, 0x80, 0x60,0x83, 0x00, 0x10,0x8c, 0x00, 0x0c,0x90, 0x00, 0x03,0xe0, 0x00, 0x00,0x80, 0x00, 0x03,0xe0, 0x00, 0x0c,0x90, 0x00, 0x10,0x8c, 0x00, 0x60,0x83, 0x00, 0x80,0x80, 0x80, 0x00,0x80, 0x00, 0x00,0x80, 0x00, 0x00,0x80, 0x00, 0x00,0x80, 0x00, 0x00,0x80, 0x00, // STAR 17x21 = 4.0 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0xc0,0x40, 0x60, 0x30,0x41, 0x80, 0x08,0x42, 0x00, 0x06,0x4c, 0x00, 0x01,0xf0, 0x00, 0x00,0x40, 0x00, 0x01,0xf0, 0x00, 0x06,0x4c, 0x00, 0x08,0x42, 0x00, 0x30,0x41, 0x80, 0xc0,0x40, 0x60, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, 0x00,0x40, 0x00, // STAR 19x23 = 4.5 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x80,0x20, 0x08, 0x60,0x20, 0x30, 0x18,0x20, 0xc0, 0x04,0x21, 0x00, 0x03,0x26, 0x00, 0x00,0xf8, 0x00, 0x00,0x20, 0x00, 0x00,0xf8, 0x00, 0x03,0x26, 0x00, 0x04,0x21, 0x00, 0x18,0x20, 0xc0, 0x60,0x20, 0x30, 0x80,0x20, 0x08, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, 0x00,0x20, 0x00, // STAR 21x25 = 5.0 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0xc0,0x10, 0x06, 0x30,0x10, 0x18, 0x08,0x10, 0x60, 0x06,0x10, 0x80, 0x01,0x93, 0x00, 0x00,0x7c, 0x00, 0x00,0x10, 0x00, 0x00,0x7c, 0x00, 0x01,0x93, 0x00, 0x06,0x10, 0x80, 0x08,0x10, 0x60, 0x30,0x10, 0x18, 0xc0,0x10, 0x06, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, 0x00,0x10, 0x00, // STAR 23x27 = 5.5 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x80,0x08, 0x00,0x80, 0x60,0x08, 0x03,0x00, 0x18,0x08, 0x0c,0x00, 0x04,0x08, 0x30,0x00, 0x03,0x08, 0x40,0x00, 0x00,0xc9, 0x80,0x00, 0x00,0x3e, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x3e, 0x00,0x00, 0x00,0xc9, 0x80,0x00, 0x03,0x08, 0x40,0x00, 0x04,0x08, 0x30,0x00, 0x18,0x08, 0x0c,0x00, 0x60,0x08, 0x03,0x00, 0x80,0x08, 0x00,0x80, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x08, 0x00,0x00, // STAR 25x29 = 6.0 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x30,0x00, 0x80,0x06, 0x0c,0x00, 0x80,0x18, 0x03,0x00, 0x80,0x60, 0x00,0xc0, 0x81,0x80, 0x00,0x30, 0x86,0x00, 0x00,0x0c, 0x98,0x00, 0x00,0x03, 0xe0,0x00, 0x00,0x03, 0xe0,0x00, 0x00,0x0c, 0x98,0x00, 0x00,0x30, 0x86,0x00, 0x00,0xc0, 0x81,0x80, 0x03,0x00, 0x80,0x60, 0x0c,0x00, 0x80,0x18, 0x30,0x00, 0x80,0x06, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, // STAR 32x32 = 6.5 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x80, 0x04, 0x0c, 0x00, 0x80, 0x18, 0x02, 0x00, 0x80, 0x20, 0x01, 0x80, 0x80, 0xc0, 0x00, 0x40, 0x81, 0x00, 0x00, 0x30, 0x86, 0x00, 0x00, 0x08, 0x88, 0x00, 0x00, 0x06, 0xb0, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x06, 0xb0, 0x00, 0x00, 0x08, 0x88, 0x00, 0x00, 0x30, 0x86, 0x00, 0x00, 0x40, 0x81, 0x00, 0x01, 0x80, 0x80, 0xc0, 0x02, 0x00, 0x80, 0x20, 0x0c, 0x00, 0x80, 0x18, 0x10, 0x00, 0x80, 0x04, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, // STAR 32x32 = 7.0 // TYPE = CIRC 0x38, 0x44, 0x82, 0x82, 0x82, 0x44, 0x38, // CIRC 7x7 = 1.0 0x3c,0x00, 0x42,0x00, 0x81,0x00, 0x81,0x00, 0x81,0x00, 0x81,0x00, 0x42,0x00, 0x3c,0x00, 0x00,0x00, //CIRC 9x9 = 1.5 0x3e,0x00, 0x41,0x00, 0x81,0x80, 0x80,0x80, 0x80,0x80, 0x80,0x80, 0x81,0x80, 0x41,0x00, 0x3e,0x00, // CIRC 9x9 = 2.0 0x1f,0x00, 0x20,0x80, 0x40,0x40, 0x80,0x20, 0x80,0x20, 0x80,0x20, 0x80,0x20, 0x80,0x20, 0x40,0x40, 0x20,0x80, 0x1f,0x00, // CIRC 11x11 = 2.5 0x0f,0x80, 0x10,0x40, 0x20,0x20, 0x40,0x10, 0x80,0x08, 0x80,0x08, 0x80,0x08, 0x80,0x08, 0x80,0x08, 0x40,0x10, 0x20,0x20, 0x10,0x40, 0x0f,0x80, // CIRC 13x13 = 3.0 0x07,0xc0, 0x18,0x30, 0x20,0x08, 0x40,0x04, 0x40,0x04, 0x80,0x02, 0x80,0x02, 0x80,0x02, 0x80,0x02, 0x80,0x02, 0x40,0x04, 0x40,0x04, 0x20,0x08, 0x18,0x30, 0x07,0xc0, // CIRC 15x15 = 3.5 0x03,0xe0, 0x00, 0x0c,0x18, 0x00, 0x10,0x04, 0x00, 0x20,0x02, 0x00, 0x40,0x01, 0x00, 0x40,0x01, 0x00, 0x80,0x00, 0x80, 0x80,0x00, 0x80, 0x80,0x00, 0x80, 0x80,0x00, 0x80, 0x80,0x00, 0x80, 0x40,0x01, 0x00, 0x40,0x01, 0x00, 0x20,0x02, 0x00, 0x10,0x04, 0x00, 0x0c,0x18, 0x00, 0x03,0xe0, 0x00, // CIRC 17x17 = 4.0 0x03,0xf8, 0x00, 0x0e,0x0e, 0x00, 0x18,0x03, 0x00, 0x20,0x00, 0x80, 0x60,0x00, 0xc0, 0x40,0x00, 0x40, 0xc0,0x00, 0x60, 0x80,0x00, 0x20, 0x80,0x00, 0x20, 0x80,0x00, 0x20, 0x80,0x00, 0x20, 0x80,0x00, 0x20, 0xc0,0x00, 0x60, 0x40,0x00, 0x40, 0x60,0x00, 0xc0, 0x20,0x00, 0x80, 0x18,0x03, 0x00, 0x0e,0x0e, 0x00, 0x03,0xf8, 0x00, // CIRC 19x19 = 4.5 0x01,0xfc, 0x00, 0x06,0x03, 0x00, 0x08,0x00, 0x80, 0x10,0x00, 0x40, 0x20,0x00, 0x20, 0x40,0x00, 0x10, 0x40,0x00, 0x10, 0x80,0x00, 0x08, 0x80,0x00, 0x08, 0x80,0x00, 0x08, 0x80,0x00, 0x08, 0x80,0x00, 0x08, 0x80,0x00, 0x08, 0x80,0x00, 0x08, 0x40,0x00, 0x10, 0x40,0x00, 0x10, 0x20,0x00, 0x20, 0x10,0x00, 0x40, 0x08,0x00, 0x80, 0x06,0x03, 0x00, 0x01,0xfc, 0x00, // CIRC 21x21 = 5.0 0x00,0xfe, 0x00, 0x03,0x01, 0x80, 0x0c,0x00, 0x60, 0x18,0x00, 0x30, 0x30,0x00, 0x18, 0x20,0x00, 0x08, 0x40,0x00, 0x04, 0x40,0x00, 0x04, 0x80,0x00, 0x02, 0x80,0x00, 0x02, 0x80,0x00, 0x02, 0x80,0x00, 0x02, 0x80,0x00, 0x02, 0x80,0x00, 0x02, 0x80,0x00, 0x02, 0x40,0x00, 0x04, 0x40,0x00, 0x04, 0x20,0x00, 0x08, 0x30,0x00, 0x18, 0x18,0x00, 0x30, 0x0c,0x00, 0x60, 0x03,0x01, 0x80, 0x00,0xfe, 0x00, // CIRC 23x23 = 5.5 0x00,0x7f, 0x00,0x00, 0x01,0x80, 0xc0,0x00, 0x06,0x00, 0x30,0x00, 0x08,0x00, 0x08,0x00, 0x10,0x00, 0x04,0x00, 0x20,0x00, 0x02,0x00, 0x20,0x00, 0x02,0x00, 0x40,0x00, 0x01,0x00, 0x40,0x00, 0x01,0x00, 0x80,0x00, 0x00,0x80, 0x80,0x00, 0x00,0x80, 0x80,0x00, 0x00,0x80, 0x80,0x00, 0x00,0x80, 0x80,0x00, 0x00,0x80, 0x80,0x00, 0x00,0x80, 0x80,0x00, 0x00,0x80, 0x40,0x00, 0x01,0x00, 0x40,0x00, 0x01,0x00, 0x20,0x00, 0x02,0x00, 0x20,0x00, 0x02,0x00, 0x10,0x00, 0x04,0x00, 0x08,0x00, 0x08,0x00, 0x06,0x00, 0x30,0x00, 0x01,0x80, 0xc0,0x00, 0x00,0x7f, 0x00,0x00, // CIRC 25x25 = 6.0 0x00,0x3f, 0x80,0x00, 0x01,0xc0, 0x70,0x00, 0x03,0x00, 0x18,0x00, 0x0c,0x00, 0x06,0x00, 0x18,0x00, 0x03,0x00, 0x10,0x00, 0x01,0x00, 0x20,0x00, 0x00,0x80, 0x60,0x00, 0x00,0xc0, 0x40,0x00, 0x00,0x40, 0x40,0x00, 0x00,0x40, 0x80,0x00, 0x00,0x20, 0x80,0x00, 0x00,0x20, 0x80,0x00, 0x00,0x20, 0x80,0x00, 0x00,0x20, 0x80,0x00, 0x00,0x20, 0x80,0x00, 0x00,0x20, 0x80,0x00, 0x00,0x20, 0x40,0x00, 0x00,0x40, 0x40,0x00, 0x00,0x40, 0x60,0x00, 0x00,0xc0, 0x20,0x00, 0x00,0x80, 0x10,0x00, 0x01,0x00, 0x18,0x00, 0x03,0x00, 0x0c,0x00, 0x06,0x00, 0x03,0x00, 0x18,0x00, 0x01,0xc0, 0x70,0x00, 0x00,0x3f, 0x80,0x00, // CIRC 27x27 = 6.5 0x00,0x1f, 0xc0,0x00, 0x00,0xe0, 0x38,0x00, 0x01,0x00, 0x04,0x00, 0x06,0x00, 0x03,0x00, 0x08,0x00, 0x00,0x80, 0x10,0x00, 0x00,0x40, 0x10,0x00, 0x00,0x40, 0x20,0x00, 0x00,0x20, 0x40,0x00, 0x00,0x10, 0x40,0x00, 0x00,0x10, 0x40,0x00, 0x00,0x10, 0x80,0x00, 0x00,0x08, 0x80,0x00, 0x00,0x08, 0x80,0x00, 0x00,0x08, 0x80,0x00, 0x00,0x08, 0x80,0x00, 0x00,0x08, 0x80,0x00, 0x00,0x08, 0x80,0x00, 0x00,0x08, 0x40,0x00, 0x00,0x10, 0x40,0x00, 0x00,0x10, 0x40,0x00, 0x00,0x10, 0x20,0x00, 0x00,0x20, 0x10,0x00, 0x00,0x40, 0x10,0x00, 0x00,0x40, 0x08,0x00, 0x00,0x80, 0x06,0x00, 0x03,0x00, 0x01,0x00, 0x04,0x00, 0x00,0xe0, 0x38,0x00, 0x00,0x1f, 0xc0,0x00, // CIRC 29x29 = 7.0 // TYPE = CROSS 0x82, 0x44, 0x28, 0x10, 0x28, 0x44, 0x82, // CROSS 7x7 = 1.0 0x80,0x80, 0x41,0x00, 0x22,0x00, 0x14,0x00, 0x08,0x00, 0x14,0x00, 0x22,0x00, 0x41,0x00, 0x80,0x80, // CROSS 9x9 = 1.5 0x80,0x20, 0x40,0x40, 0x20,0x80, 0x11,0x00, 0x0a,0x00, 0x04,0x00, 0x0a,0x00, 0x11,0x00, 0x20,0x80, 0x40,0x40, 0x80,0x20, // CROSS 11x11 = 2.0 0x80,0x08, 0x40,0x10, 0x20,0x20, 0x10,0x40, 0x08,0x80, 0x05,0x00, 0x02,0x00, 0x05,0x00, 0x08,0x80, 0x10,0x40, 0x20,0x20, 0x40,0x10, 0x80,0x08, // CROSS 13x13 = 2.5 0x80,0x02, 0x40,0x04, 0x20,0x08, 0x10,0x10, 0x08,0x20, 0x04,0x40, 0x02,0x80, 0x01,0x00, 0x02,0x80, 0x04,0x40, 0x08,0x20, 0x10,0x10, 0x20,0x08, 0x40,0x04, 0x80,0x02, // CROSS 15x15 = 3.0 0x80,0x00, 0x80, 0x40,0x01, 0x00, 0x20,0x02, 0x00, 0x10,0x04, 0x00, 0x08,0x08, 0x00, 0x04,0x10, 0x00, 0x02,0x20, 0x00, 0x01,0x40, 0x00, 0x00,0x80, 0x00, 0x01,0x40, 0x00, 0x02,0x20, 0x00, 0x04,0x10, 0x00, 0x08,0x08, 0x00, 0x10,0x04, 0x00, 0x20,0x02, 0x00, 0x40,0x01, 0x00, 0x80,0x00, 0x80, // CROSS 17x17 = 3.5 0x80,0x00, 0x20, 0x40,0x00, 0x40, 0x20,0x00, 0x80, 0x10,0x01, 0x00, 0x08,0x02, 0x00, 0x04,0x04, 0x00, 0x02,0x08, 0x00, 0x01,0x10, 0x00, 0x00,0xa0, 0x00, 0x00,0x40, 0x00, 0x00,0xa0, 0x00, 0x01,0x10, 0x00, 0x02,0x08, 0x00, 0x04,0x04, 0x00, 0x08,0x02, 0x00, 0x10,0x01, 0x00, 0x20,0x00, 0x80, 0x40,0x00, 0x40, 0x80,0x00, 0x20, // CROSS 19x19 = 4.0 0x80,0x00, 0x08, 0x40,0x00, 0x10, 0x20,0x00, 0x20, 0x10,0x00, 0x40, 0x08,0x00, 0x80, 0x04,0x01, 0x00, 0x02,0x02, 0x00, 0x01,0x04, 0x00, 0x00,0x88, 0x00, 0x00,0x50, 0x00, 0x00,0x20, 0x00, 0x00,0x50, 0x00, 0x00,0x88, 0x00, 0x01,0x04, 0x00, 0x02,0x02, 0x00, 0x04,0x01, 0x00, 0x08,0x00, 0x80, 0x10,0x00, 0x40, 0x20,0x00, 0x20, 0x40,0x00, 0x10, 0x80,0x00, 0x08,/* CROSS 21x21 = 4.5 */ 0x80,0x00, 0x02, 0x40,0x00, 0x04, 0x20,0x00, 0x08, 0x10,0x00, 0x10, 0x08,0x00, 0x20, 0x04,0x00, 0x40, 0x02,0x00, 0x80, 0x01,0x01, 0x00, 0x00,0x82, 0x00, 0x00,0x44, 0x00, 0x00,0x28, 0x00, 0x00,0x10, 0x00, 0x00,0x28, 0x00, 0x00,0x44, 0x00, 0x00,0x82, 0x00, 0x01,0x01, 0x00, 0x02,0x00, 0x80, 0x04,0x00, 0x40, 0x08,0x00, 0x20, 0x10,0x00, 0x10, 0x20,0x00, 0x08, 0x40,0x00, 0x04, 0x80,0x00, 0x02, // CROSS 23x23 = 5.0 0x80,0x00, 0x00,0x80, 0x40,0x00, 0x01,0x00, 0x20,0x00, 0x02,0x00, 0x10,0x00, 0x04,0x00, 0x08,0x00, 0x08,0x00, 0x04,0x00, 0x10,0x00, 0x02,0x00, 0x20,0x00, 0x01,0x00, 0x40,0x00, 0x00,0x80, 0x80,0x00, 0x00,0x41, 0x00,0x00, 0x00,0x22, 0x00,0x00, 0x00,0x14, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x14, 0x00,0x00, 0x00,0x22, 0x00,0x00, 0x00,0x41, 0x00,0x00, 0x00,0x80, 0x80,0x00, 0x01,0x00, 0x40,0x00, 0x02,0x00, 0x20,0x00, 0x04,0x00, 0x10,0x00, 0x08,0x00, 0x08,0x00, 0x10,0x00, 0x04,0x00, 0x20,0x00, 0x02,0x00, 0x40,0x00, 0x01,0x00, 0x80,0x00, 0x00,0x80, // CROSS 25x25 = 5.5 0x80,0x00, 0x00,0x20, 0x40,0x00, 0x00,0x40, 0x20,0x00, 0x00,0x80, 0x10,0x00, 0x01,0x00, 0x08,0x00, 0x02,0x00, 0x04,0x00, 0x04,0x00, 0x02,0x00, 0x08,0x00, 0x01,0x00, 0x10,0x00, 0x00,0x80, 0x20,0x00, 0x00,0x40, 0x40,0x00, 0x00,0x20, 0x80,0x00, 0x00,0x11, 0x00,0x00, 0x00,0x0a, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x0a, 0x00,0x00, 0x00,0x11, 0x00,0x00, 0x00,0x20, 0x80,0x00, 0x00,0x40, 0x40,0x00, 0x00,0x80, 0x20,0x00, 0x01,0x00, 0x10,0x00, 0x02,0x00, 0x08,0x00, 0x04,0x00, 0x04,0x00, 0x08,0x00, 0x02,0x00, 0x10,0x00, 0x01,0x00, 0x20,0x00, 0x00,0x80, 0x40,0x00, 0x00,0x40, 0x80,0x00, 0x00,0x20, // CROSS 27x27 = 6.0 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x20,0x00, 0x00,0x04, 0x10,0x00, 0x00,0x08, 0x08,0x00, 0x00,0x10, 0x04,0x00, 0x00,0x20, 0x02,0x00, 0x00,0x40, 0x01,0x00, 0x00,0x80, 0x00,0x80, 0x01,0x00, 0x00,0x40, 0x02,0x00, 0x00,0x20, 0x04,0x00, 0x00,0x10, 0x08,0x00, 0x00,0x08, 0x10,0x00, 0x00,0x04, 0x20,0x00, 0x00,0x02, 0x40,0x00, 0x00,0x01, 0x80,0x00, 0x00,0x01, 0x80,0x00, 0x00,0x02, 0x40,0x00, 0x00,0x04, 0x20,0x00, 0x00,0x08, 0x10,0x00, 0x00,0x10, 0x08,0x00, 0x00,0x20, 0x04,0x00, 0x00,0x40, 0x02,0x00, 0x00,0x80, 0x01,0x00, 0x01,0x00, 0x00,0x80, 0x02,0x00, 0x00,0x40, 0x04,0x00, 0x00,0x20, 0x08,0x00, 0x00,0x10, 0x10,0x00, 0x00,0x08, 0x20,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, // CROSS 32x32 = 6.5 0x00,0x00, 0x00,0x00, 0x40,0x00, 0x00,0x02, 0x20,0x00, 0x00,0x04, 0x10,0x00, 0x00,0x08, 0x08,0x00, 0x00,0x10, 0x04,0x00, 0x00,0x20, 0x02,0x00, 0x00,0x40, 0x01,0x00, 0x00,0x80, 0x00,0x80, 0x01,0x00, 0x00,0x40, 0x02,0x00, 0x00,0x20, 0x04,0x00, 0x00,0x10, 0x08,0x00, 0x00,0x08, 0x10,0x00, 0x00,0x04, 0x20,0x00, 0x00,0x02, 0x40,0x00, 0x00,0x01, 0x80,0x00, 0x00,0x01, 0x80,0x00, 0x00,0x02, 0x40,0x00, 0x00,0x04, 0x20,0x00, 0x00,0x08, 0x10,0x00, 0x00,0x10, 0x08,0x00, 0x00,0x20, 0x04,0x00, 0x00,0x40, 0x02,0x00, 0x00,0x80, 0x01,0x00, 0x01,0x00, 0x00,0x80, 0x02,0x00, 0x00,0x40, 0x04,0x00, 0x00,0x20, 0x08,0x00, 0x00,0x10, 0x10,0x00, 0x00,0x08, 0x20,0x00, 0x00,0x04, 0x40,0x00, 0x00,0x02, 0x00,0x00, 0x00,0x00 // CROSS 32x32 = 7.0 }; // ======================================================================= // function : GetMarkerBitMapArray // purpose : Returns a parameters for the marker of the specified // type and scale. // ======================================================================= void GetMarkerBitMapParam (const Aspect_TypeOfMarker theMarkerType, const Standard_ShortReal& theScale, Standard_Integer& theWidth, Standard_Integer& theHeight, Standard_Integer& theOffset, Standard_Integer& theNumOfBytes) { const Standard_Integer aType = (Standard_Integer )((theMarkerType > Aspect_TOM_O) ? Aspect_TOM_O : theMarkerType); const Standard_Real anIndex = (Standard_Real )(TEL_NO_OF_SIZES - 1) * (theScale - (Standard_Real )TEL_PM_START_SIZE) / (Standard_Real )(TEL_PM_END_SIZE - TEL_PM_START_SIZE); Standard_Integer anId = (Standard_Integer )(anIndex + 0.5); if (anId < 0) { anId = 0; } else if (anId >= TEL_NO_OF_SIZES) { anId = TEL_NO_OF_SIZES - 1; } theWidth = (Standard_Integer )arrPMFontInfo[aType][anId].width; theHeight = (Standard_Integer )arrPMFontInfo[aType][anId].height; theOffset = arrPMFontInfo[aType][anId].offset; const Standard_Integer aNumOfBytesInRow = theWidth / 8 + (theWidth % 8 ? 1 : 0); theNumOfBytes = theHeight * aNumOfBytesInRow; } // ======================================================================= // function : GetTextureImage // purpose : Returns a marker image for the marker of the specified // type and scale. // ======================================================================= Handle(Graphic3d_MarkerImage) GetTextureImage (const Aspect_TypeOfMarker theMarkerType, const Standard_ShortReal& theScale) { Standard_Integer aWidth, aHeight, anOffset, aNumOfBytes; GetMarkerBitMapParam (theMarkerType, theScale, aWidth, aHeight, anOffset, aNumOfBytes); Handle(TColStd_HArray1OfByte) aBitMap = new TColStd_HArray1OfByte (0, aNumOfBytes - 1); for (Standard_Integer anIter = 0; anIter < aNumOfBytes; anIter++) { aBitMap->ChangeValue (anIter) = OpenGl_AspectMarker_myMarkerRaster[anOffset + anIter]; } Handle(Graphic3d_MarkerImage) aTexture = new Graphic3d_MarkerImage (aBitMap, aWidth, aHeight); return aTexture; } // ======================================================================= // function : MergeImages // purpose : Merge two image pixmap into one. Used for creating image for // following markers: 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 // ======================================================================= Handle(Image_PixMap) MergeImages (const Handle(Image_PixMap)& theImage1, const Handle(Image_PixMap)& theImage2) { if (theImage1.IsNull() && theImage2.IsNull()) { return Handle(Image_PixMap)(); } Handle(Image_PixMap) aResultImage = new Image_PixMap(); Standard_Integer aWidth1 (0), aHeight1 (0); if (!theImage1.IsNull()) { aWidth1 = (Standard_Integer )theImage1->Width(); aHeight1 = (Standard_Integer )theImage1->Height(); } Standard_Integer aWidth2 (0), aHeight2 (0); if (!theImage2.IsNull()) { aWidth2 = (Standard_Integer )theImage2->Width(); aHeight2 = (Standard_Integer )theImage2->Height(); } const Standard_Integer aMaxWidth = Max (aWidth1, aWidth2); const Standard_Integer aMaxHeight = Max (aHeight1, aHeight2); const Standard_Integer aSize = Max (aMaxWidth, aMaxHeight); aResultImage->InitZero (Image_PixMap::ImgAlpha, aSize, aSize); if (!theImage1.IsNull()) { const Standard_Integer aXOffset1 = Abs (aWidth1 - aMaxWidth) / 2; const Standard_Integer anYOffset1 = Abs (aHeight1 - aMaxHeight) / 2; for (Standard_Integer anY = 0; anY < aHeight1; anY++) { Standard_Byte* anImageLine = theImage1->ChangeRow (anY); Standard_Byte* aResultImageLine = aResultImage->ChangeRow (anYOffset1 + anY); for (Standard_Integer aX = 0; aX < aWidth1; aX++) { aResultImageLine[aXOffset1 + aX] |= anImageLine[aX]; } } } if (!theImage2.IsNull()) { const Standard_Integer aXOffset2 = Abs (aWidth2 - aMaxWidth) / 2; const Standard_Integer anYOffset2 = Abs (aHeight2 - aMaxHeight) / 2; for (Standard_Integer anY = 0; anY < aHeight2; anY++) { Standard_Byte* anImageLine = theImage2->ChangeRow (anY); Standard_Byte* aResultImageLine = aResultImage->ChangeRow (anYOffset2 + anY); for (Standard_Integer aX = 0; aX < aWidth2; aX++) { aResultImageLine[aXOffset2 + aX] |= anImageLine[aX]; } } } return aResultImage; } // ======================================================================= // function : OpenGl_AspectMarker // purpose : // ======================================================================= OpenGl_AspectMarker::OpenGl_AspectMarker() : myColor (myDefaultColor), myType (Aspect_TOM_PLUS), myScale (1.0f), myMarkerSize (1.0f), myMarkerImage(), myShaderProgram() {} // ======================================================================= // function : SetAspect // purpose : // ======================================================================= void OpenGl_AspectMarker::SetAspect (const CALL_DEF_CONTEXTMARKER& theAspect) { myColor.rgb[0] = (float )theAspect.Color.r; myColor.rgb[1] = (float )theAspect.Color.g; myColor.rgb[2] = (float )theAspect.Color.b; myColor.rgb[3] = 1.0f; myMarkerImage = theAspect.MarkerImage; myType = theAspect.MarkerType; myScale = theAspect.Scale; myShaderProgram = theAspect.ShaderProgram; // update sprite resource bindings TCollection_AsciiString aSpriteKey = THE_EMPTY_KEY; TCollection_AsciiString aSpriteAKey = THE_EMPTY_KEY; myResources.SpriteKeys (myMarkerImage, myType, myScale, myColor, aSpriteKey, aSpriteAKey); if (aSpriteKey.IsEmpty() || myResources.SpriteKey != aSpriteKey || aSpriteAKey.IsEmpty() || myResources.SpriteAKey != aSpriteAKey) { myResources.ResetSpriteReadiness(); myMarkerSize = theAspect.Scale; } // update shader program resource bindings const TCollection_AsciiString& aShaderKey = myShaderProgram.IsNull() ? THE_EMPTY_KEY : myShaderProgram->GetId(); if (aShaderKey.IsEmpty() || myResources.ShaderProgramId != aShaderKey) { myResources.ResetShaderReadiness(); } } // ======================================================================= // function : Render // purpose : // ======================================================================= void OpenGl_AspectMarker::Render (const Handle(OpenGl_Workspace)& theWorkspace) const { theWorkspace->SetAspectMarker (this); } // ======================================================================= // function : Release // purpose : // ======================================================================= void OpenGl_AspectMarker::Release (OpenGl_Context* theCtx) { if (!myResources.Sprite.IsNull()) { if (theCtx) { if (myResources.SpriteKey.IsEmpty()) { theCtx->DelayedRelease (myResources.Sprite); theCtx->DelayedRelease (myResources.SpriteA); } else { myResources.Sprite.Nullify(); // we need nullify all handles before ReleaseResource() call myResources.SpriteA.Nullify(); theCtx->ReleaseResource (myResources.SpriteKey, Standard_True); theCtx->ReleaseResource (myResources.SpriteAKey, Standard_True); } } myResources.Sprite.Nullify(); myResources.SpriteA.Nullify(); } myResources.SpriteKey.Clear(); myResources.SpriteAKey.Clear(); myResources.ResetSpriteReadiness(); if (!myResources.ShaderProgram.IsNull() && theCtx) { theCtx->ShaderManager()->Unregister (myResources.ShaderProgramId, myResources.ShaderProgram); } myResources.ShaderProgramId.Clear(); myResources.ResetShaderReadiness(); } // ======================================================================= // function : BuildSprites // purpose : // ======================================================================= void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Context)& theCtx, const Handle(Graphic3d_MarkerImage)& theMarkerImage, const Aspect_TypeOfMarker theType, const Standard_ShortReal theScale, const TEL_COLOUR& theColor, Standard_ShortReal& theMarkerSize) { // generate key for shared resource TCollection_AsciiString aNewKey = THE_EMPTY_KEY; TCollection_AsciiString aNewKeyA = THE_EMPTY_KEY; SpriteKeys (theMarkerImage, theType, theScale, theColor, aNewKey, aNewKeyA); // release old shared resources const Standard_Boolean aNewResource = aNewKey.IsEmpty() || SpriteKey != aNewKey; if (aNewResource) { if (!Sprite.IsNull()) { if (SpriteKey.IsEmpty()) { theCtx->DelayedRelease (Sprite); Sprite.Nullify(); } else { Sprite.Nullify(); // we need nullify all handles before ReleaseResource() call theCtx->ReleaseResource (SpriteKey, Standard_True); } } SpriteKey = aNewKey; } if (aNewKeyA.IsEmpty() || SpriteAKey != aNewKeyA) { if (!SpriteA.IsNull()) { if (SpriteAKey.IsEmpty()) { theCtx->DelayedRelease (SpriteA); SpriteA.Nullify(); } else { SpriteA.Nullify(); // we need nullify all handles before ReleaseResource() call theCtx->ReleaseResource (SpriteAKey, Standard_True); } } SpriteAKey = aNewKeyA; } if (theType == Aspect_TOM_POINT || !aNewResource || (theType == Aspect_TOM_USERDEFINED && theMarkerImage.IsNull())) { // nothing to do - just simple point return; } if (!aNewKey.IsEmpty() && theCtx->GetResource (aNewKeyA, SpriteA) // alpha sprite could be shared && theCtx->GetResource (aNewKey, Sprite)) { // reuse shared resource if (!Sprite->IsDisplayList()) { theMarkerSize = Standard_ShortReal (Max (Sprite->SizeX(), Sprite->SizeY())); } return; } const bool hadAlreadyAlpha = !SpriteA.IsNull(); if (!hadAlreadyAlpha) { SpriteA = new OpenGl_PointSprite(); } Sprite = new OpenGl_PointSprite(); if (!aNewKey.IsEmpty()) { theCtx->ShareResource (aNewKey, Sprite); if (!hadAlreadyAlpha) { theCtx->ShareResource (aNewKeyA, SpriteA); } } if (!theCtx.IsNull() && theCtx->core20fwd != NULL && !theCtx->caps->pntSpritesDisable) { // Creating texture resource for using it with point sprites Handle(Graphic3d_MarkerImage) aNewMarkerImage; Handle(Image_PixMap) anImage, anImageA; if (theType == Aspect_TOM_USERDEFINED && !theMarkerImage.IsNull()) { aNewMarkerImage = theMarkerImage; anImage = aNewMarkerImage->GetImage(); } else { // Creating image from default bitmap Handle(Graphic3d_MarkerImage) aMarkerImage1, aMarkerImage2; const Standard_ShortReal aDelta = 0.1F; Standard_ShortReal aScale = theScale; Standard_ShortReal aLimit = 0.0F; switch (theType) { case Aspect_TOM_O_POINT: { // draw inner point as filled rectangle const Standard_Integer aSize = theScale > 7 ? 7 : (Standard_Integer )(theScale + 0.5F); Handle(TColStd_HArray1OfByte) aBitMap = fillPointBitmap (aSize); aMarkerImage2 = new Graphic3d_MarkerImage (aBitMap, aSize, aSize); } case Aspect_TOM_O_PLUS: case Aspect_TOM_O_STAR: case Aspect_TOM_O_X: { // For this type of markers we merge two base bitmaps into one // For example Aspect_TOM_O_PLUS = Aspect_TOM_O + Aspect_TOM_PLUS aMarkerImage1 = GetTextureImage (Aspect_TOM_O, theScale); if (theType != Aspect_TOM_O_POINT) { aMarkerImage2 = GetTextureImage (Aspect_TypeOfMarker (theType - Aspect_TOM_O_POINT), theScale); } anImage = MergeImages (aMarkerImage1->GetImage(), aMarkerImage2->GetImage()); aNewMarkerImage = new Graphic3d_MarkerImage (anImage); break; } case Aspect_TOM_RING1: if (aLimit == 0.0f) aLimit = aScale * 0.2f; case Aspect_TOM_RING2: if (aLimit == 0.0f) aLimit = aScale * 0.5f; case Aspect_TOM_RING3: { if (aLimit == 0.0f) aLimit = aScale * 0.8f; for (; aScale > aLimit && aScale >= 1.0f; aScale -= aDelta) { anImage = MergeImages (anImage, GetTextureImage (Aspect_TOM_O, aScale)->GetImage()); } aNewMarkerImage = new Graphic3d_MarkerImage (anImage); break; } case Aspect_TOM_BALL: { Standard_Integer aWidth, aHeight, anOffset, aNumOfBytes; GetMarkerBitMapParam (Aspect_TOM_O, aScale, aWidth, aHeight, anOffset, aNumOfBytes); NCollection_Vec4 aColor (Standard_Real (theColor.rgb[0]), Standard_Real (theColor.rgb[1]), Standard_Real (theColor.rgb[2]), Standard_Real (theColor.rgb[3])); const Standard_Integer aSize = Max (aWidth + 2, aHeight + 2); // includes extra margin anImage = new Image_PixMap(); anImageA = new Image_PixMap(); anImage ->InitZero (Image_PixMap::ImgBGRA, aSize, aSize); anImageA->InitZero (Image_PixMap::ImgAlpha, aSize, aSize); // we draw a set of circles Image_ColorBGRA aColor32; aColor32.a() = 255; Standard_Real aHLS[3]; while (aScale >= 1.0f) { Quantity_Color::RgbHls (aColor.r(), aColor.g(), aColor.b(), aHLS[0], aHLS[1], aHLS[2]); aHLS[2] *= 0.95; // 5% saturation change Quantity_Color::HlsRgb (aHLS[0], aHLS[1], aHLS[2], aColor.r(), aColor.g(), aColor.b()); aColor32.r() = Standard_Byte(255.0 * aColor.r()); aColor32.g() = Standard_Byte(255.0 * aColor.g()); aColor32.b() = Standard_Byte(255.0 * aColor.b()); const Handle(Graphic3d_MarkerImage) aMarker = GetTextureImage (Aspect_TOM_O, aScale); const Handle(Image_PixMap)& aCircle = aMarker->GetImage(); const Standard_Size aDiffX = (anImage->SizeX() - aCircle->SizeX()) / 2; const Standard_Size aDiffY = (anImage->SizeY() - aCircle->SizeY()) / 2; for (Standard_Size aRow = 0; aRow < aCircle->SizeY(); ++aRow) { const Standard_Byte* aRowData = aCircle->Row (aRow); for (Standard_Size aCol = 0; aCol < aCircle->SizeX(); ++aCol) { if (aRowData[aCol] != 0) { anImage ->ChangeValue (aDiffX + aRow, aDiffY + aCol) = aColor32; anImageA->ChangeValue (aDiffX + aRow, aDiffY + aCol) = 255; } } } aScale -= aDelta; } break; } default: { aNewMarkerImage = GetTextureImage (theType, theScale); anImage = aNewMarkerImage->GetImage(); break; } } } theMarkerSize = Max ((Standard_ShortReal )anImage->Width(),(Standard_ShortReal )anImage->Height()); Sprite->Init (theCtx, *anImage.operator->(), Graphic3d_TOT_2D); if (!hadAlreadyAlpha) { if (anImageA.IsNull() && Sprite->GetFormat() != GL_ALPHA && !aNewMarkerImage.IsNull()) { anImageA = aNewMarkerImage->GetImageAlpha(); } if (!anImageA.IsNull()) { SpriteA->Init (theCtx, *anImageA.operator->(), Graphic3d_TOT_2D); } } } else { #if !defined(GL_ES_VERSION_2_0) // Creating list with bitmap for using it in compatibility mode GLuint aBitmapList = glGenLists (1); Sprite->SetDisplayList (theCtx, aBitmapList); Standard_Integer aWidth, aHeight, anOffset, aNumOfBytes; if (theType == Aspect_TOM_USERDEFINED && !theMarkerImage.IsNull()) { // Reading user defined marker Handle(TColStd_HArray1OfByte) aBitMap = theMarkerImage->GetBitMapArray(); Standard_Byte* aBitMapArray = new Standard_Byte[aBitMap->Length()]; theMarkerImage->GetTextureSize (aWidth, aHeight); // We should pass bitmap to glBitmap with reversed line order as it draws it from // bottom to top const Standard_Integer aNumOfBytesInRow = aWidth / 8 + (aWidth % 8 ? 1 : 0); const Standard_Integer anUpperIndex = aBitMap->Upper(); for (Standard_Integer aRow = 0; aRow < aHeight; aRow++) { for (Standard_Integer aByteIter = 0; aByteIter < aNumOfBytesInRow; aByteIter++) { aBitMapArray[aRow * aNumOfBytesInRow + aByteIter] = aBitMap->Value (anUpperIndex + 1 - (aRow + 1) * aNumOfBytesInRow + aByteIter); } } if (aBitMapArray != NULL) { glNewList (aBitmapList, GL_COMPILE); glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, (GLfloat )(0.5f * aWidth), (GLfloat )(0.5f * aHeight), 0.f, 0.f, (const GLubyte* )aBitMapArray); glEndList(); } } else { // Creating list for default marker const Standard_ShortReal aDelta = 0.1f; Standard_ShortReal aScale = theScale; Standard_ShortReal aLimit = 0.0f; glNewList (aBitmapList, GL_COMPILE); switch (theType) { case Aspect_TOM_O_POINT: { // draw inner point as filled rectangle const Standard_Integer aSize = theScale > 7 ? 7 : (Standard_Integer )(theScale + 0.5F); Handle(TColStd_HArray1OfByte) aBitMap = fillPointBitmap (aSize); glBitmap (aSize, aSize, (GLfloat )(0.5f * aSize), (GLfloat )(0.5f * aSize), 0.0f, 0.0f, &aBitMap->Array1().Value (aBitMap->Lower())); } case Aspect_TOM_O_PLUS: case Aspect_TOM_O_STAR: case Aspect_TOM_O_X: { // For this type of markers we merge two base bitmaps into one // For example Aspect_TOM_O_PLUS = Aspect_TOM_O + Aspect_TOM_PLUS GetMarkerBitMapParam (Aspect_TOM_O, theScale, aWidth, aHeight, anOffset, aNumOfBytes); glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, (GLfloat )(0.5f * aWidth), (GLfloat )(0.5f * aHeight), 0.f, 0.f, (const GLubyte* )&OpenGl_AspectMarker_myMarkerRaster[anOffset]); if (theType != Aspect_TOM_O_POINT) { GetMarkerBitMapParam (Aspect_TypeOfMarker (theType - Aspect_TOM_O_POINT), theScale, aWidth, aHeight, anOffset, aNumOfBytes); glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, (GLfloat )(0.5f * aWidth), (GLfloat )(0.5f * aHeight), 0.f, 0.f, (const GLubyte* )&OpenGl_AspectMarker_myMarkerRaster[anOffset]); } break; } case Aspect_TOM_BALL: { NCollection_Vec4 aColor (Standard_Real (theColor.rgb[0]), Standard_Real (theColor.rgb[1]), Standard_Real (theColor.rgb[2]), Standard_Real (theColor.rgb[3])); // we draw a set of circles while (aScale >= 1.0f) { Standard_Real aHLS[3]; Quantity_Color::RgbHls (aColor.r(), aColor.g(), aColor.b(), aHLS[0], aHLS[1], aHLS[2]); // 5% saturation change aHLS[2] *= 0.95; Quantity_Color::HlsRgb (aHLS[0], aHLS[1], aHLS[2], aColor.r(), aColor.g(), aColor.b()); glColor4dv (aColor); GetMarkerBitMapParam (Aspect_TOM_O, aScale, aWidth, aHeight, anOffset, aNumOfBytes); glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, 0.5f * GLfloat(aWidth), 0.5f * GLfloat(aHeight), 0.0f, 0.0f, (const GLubyte* )&OpenGl_AspectMarker_myMarkerRaster[anOffset]); aScale -= aDelta; } break; } case Aspect_TOM_RING1: if (aLimit == 0.0f) aLimit = aScale * 0.2f; case Aspect_TOM_RING2: if (aLimit == 0.0f) aLimit = aScale * 0.5f; case Aspect_TOM_RING3: { if (aLimit == 0.0f) aLimit = aScale * 0.8f; for (; aScale > aLimit && aScale >= 1.0f; aScale -= aDelta) { GetMarkerBitMapParam (Aspect_TOM_O, aScale, aWidth, aHeight, anOffset, aNumOfBytes); glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, 0.5f * GLfloat(aWidth), 0.5f * GLfloat(aHeight), 0.0f, 0.0f, (const GLubyte* )&OpenGl_AspectMarker_myMarkerRaster[anOffset]); } break; } default: { GetMarkerBitMapParam (theType, theScale, aWidth, aHeight, anOffset, aNumOfBytes); glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, 0.5f * GLfloat(aWidth), 0.5f * GLfloat(aHeight), 0.0f, 0.0f, (const GLubyte* )&OpenGl_AspectMarker_myMarkerRaster[anOffset]); break; } } glEndList(); } #endif } } // ======================================================================= // function : BuildShader // purpose : // ======================================================================= void OpenGl_AspectMarker::Resources::BuildShader (const Handle(OpenGl_Context)& theCtx, const Handle(Graphic3d_ShaderProgram)& theShader) { if (theCtx->core20fwd == NULL) { return; } // release old shader program resources if (!ShaderProgram.IsNull()) { theCtx->ShaderManager()->Unregister (ShaderProgramId, ShaderProgram); ShaderProgramId.Clear(); ShaderProgram.Nullify(); } if (theShader.IsNull()) { return; } theCtx->ShaderManager()->Create (theShader, ShaderProgramId, ShaderProgram); } // ======================================================================= // function : resourceKeys // purpose : // ======================================================================= void OpenGl_AspectMarker::Resources::SpriteKeys (const Handle(Graphic3d_MarkerImage)& theMarkerImage, const Aspect_TypeOfMarker theType, const Standard_ShortReal theScale, const TEL_COLOUR& theColor, TCollection_AsciiString& theKey, TCollection_AsciiString& theKeyA) { // generate key for shared resource if (theType == Aspect_TOM_USERDEFINED) { if (!theMarkerImage.IsNull()) { theKey = theMarkerImage->GetImageId(); theKeyA = theMarkerImage->GetImageAlphaId(); } } else if (theType != Aspect_TOM_POINT) { // predefined markers const Standard_Integer aScale = Standard_Integer(theScale + 0.5f); theKey = TCollection_AsciiString ("OpenGl_AspectMarker") + theType + "_" + aScale; theKeyA = theKey + "A"; if (theType == Aspect_TOM_BALL) { unsigned int aColor[3] = { (unsigned int )(255.0f * theColor.rgb[0]), (unsigned int )(255.0f * theColor.rgb[1]), (unsigned int )(255.0f * theColor.rgb[2]) }; char aBytes[8]; sprintf (aBytes, "%02X%02X%02X", aColor[0], aColor[1], aColor[2]); theKey += aBytes; } } }