@armyc2.c5isr.renderer/mil-sym-ts-web 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +57 -0
  3. package/buildNode.bat +2 -0
  4. package/buildWeb.bat +2 -0
  5. package/dist/C5Ren.d.ts +6970 -0
  6. package/dist/C5Ren.js +2 -0
  7. package/dist/C5Ren.js.map +1 -0
  8. package/dist/LICENSE +201 -0
  9. package/dist/README.md +57 -0
  10. package/dist/armyc2.c5isr.renderer-mil-sym-ts-web-2.2.0.tgz +0 -0
  11. package/dist/manifest.json +4 -0
  12. package/dist/package.json +16 -0
  13. package/index.ts +169 -0
  14. package/package.bak +50 -0
  15. package/package.json +40 -0
  16. package/package.node.json +43 -0
  17. package/package.pack.json +19 -0
  18. package/package.packWeb.json +16 -0
  19. package/package.web.json +40 -0
  20. package/src/main/ts/android/graphics/Bitmap.ts +7 -0
  21. package/src/main/ts/android/graphics/Paint.ts +26 -0
  22. package/src/main/ts/android/graphics/Path.ts +78 -0
  23. package/src/main/ts/android/graphics/PointF.ts +14 -0
  24. package/src/main/ts/android/graphics/Rect.ts +18 -0
  25. package/src/main/ts/android/graphics/RectF.ts +50 -0
  26. package/src/main/ts/android/graphics/Region.ts +36 -0
  27. package/src/main/ts/android/graphics/Typeface.ts +11 -0
  28. package/src/main/ts/armyc2/c5isr/JavaLineArray/BasicShapes.ts +99 -0
  29. package/src/main/ts/armyc2/c5isr/JavaLineArray/CChannelPoints2.ts +34 -0
  30. package/src/main/ts/armyc2/c5isr/JavaLineArray/CELineArray.ts +193 -0
  31. package/src/main/ts/armyc2/c5isr/JavaLineArray/Channels.ts +2971 -0
  32. package/src/main/ts/armyc2/c5isr/JavaLineArray/DISMSupport.ts +4008 -0
  33. package/src/main/ts/armyc2/c5isr/JavaLineArray/POINT2.ts +93 -0
  34. package/src/main/ts/armyc2/c5isr/JavaLineArray/Shape2.ts +89 -0
  35. package/src/main/ts/armyc2/c5isr/JavaLineArray/TacticalLines.ts +515 -0
  36. package/src/main/ts/armyc2/c5isr/JavaLineArray/arraysupport.ts +5403 -0
  37. package/src/main/ts/armyc2/c5isr/JavaLineArray/countsupport.ts +1084 -0
  38. package/src/main/ts/armyc2/c5isr/JavaLineArray/flot.ts +2173 -0
  39. package/src/main/ts/armyc2/c5isr/JavaLineArray/lineutility.ts +4934 -0
  40. package/src/main/ts/armyc2/c5isr/JavaLineArray/ref.ts +7 -0
  41. package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/Modifier2.ts +5601 -0
  42. package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/P1.ts +14 -0
  43. package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/TGLight.ts +648 -0
  44. package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/clsChannelUtility.ts +647 -0
  45. package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/clsMETOC.ts +2994 -0
  46. package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/clsUtility.ts +2663 -0
  47. package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/mdlGeodesic.ts +669 -0
  48. package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsClipPolygon2.ts +971 -0
  49. package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsClipQuad.ts +871 -0
  50. package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsRenderer.ts +3507 -0
  51. package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsRenderer2.ts +500 -0
  52. package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsUtility.ts +1089 -0
  53. package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsUtilityCPOF.ts +2656 -0
  54. package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsUtilityGE.ts +1419 -0
  55. package/src/main/ts/armyc2/c5isr/data/genc.json +1407 -0
  56. package/src/main/ts/armyc2/c5isr/data/msd.json +17311 -0
  57. package/src/main/ts/armyc2/c5isr/data/mse.json +18500 -0
  58. package/src/main/ts/armyc2/c5isr/data/svgd.json +31214 -0
  59. package/src/main/ts/armyc2/c5isr/data/svge.json +30558 -0
  60. package/src/main/ts/armyc2/c5isr/graphics2d/AffineTransform.ts +10 -0
  61. package/src/main/ts/armyc2/c5isr/graphics2d/Area.ts +437 -0
  62. package/src/main/ts/armyc2/c5isr/graphics2d/BasicStroke.ts +429 -0
  63. package/src/main/ts/armyc2/c5isr/graphics2d/BasicTypes.ts +7 -0
  64. package/src/main/ts/armyc2/c5isr/graphics2d/BufferedImage.ts +35 -0
  65. package/src/main/ts/armyc2/c5isr/graphics2d/Font.ts +111 -0
  66. package/src/main/ts/armyc2/c5isr/graphics2d/FontMetrics.ts +29 -0
  67. package/src/main/ts/armyc2/c5isr/graphics2d/FontRenderContext.ts +18 -0
  68. package/src/main/ts/armyc2/c5isr/graphics2d/GeneralPath.ts +211 -0
  69. package/src/main/ts/armyc2/c5isr/graphics2d/Graphics2D.ts +80 -0
  70. package/src/main/ts/armyc2/c5isr/graphics2d/IPathIterator.ts +33 -0
  71. package/src/main/ts/armyc2/c5isr/graphics2d/ImageIO.ts +16 -0
  72. package/src/main/ts/armyc2/c5isr/graphics2d/Line2D.ts +726 -0
  73. package/src/main/ts/armyc2/c5isr/graphics2d/PathIterator.ts +141 -0
  74. package/src/main/ts/armyc2/c5isr/graphics2d/Point.ts +112 -0
  75. package/src/main/ts/armyc2/c5isr/graphics2d/Point2D.ts +261 -0
  76. package/src/main/ts/armyc2/c5isr/graphics2d/Polygon.ts +391 -0
  77. package/src/main/ts/armyc2/c5isr/graphics2d/Rectangle.ts +567 -0
  78. package/src/main/ts/armyc2/c5isr/graphics2d/Rectangle2D.ts +445 -0
  79. package/src/main/ts/armyc2/c5isr/graphics2d/Shape.ts +31 -0
  80. package/src/main/ts/armyc2/c5isr/graphics2d/Stroke.ts +18 -0
  81. package/src/main/ts/armyc2/c5isr/graphics2d/TextLayout.ts +45 -0
  82. package/src/main/ts/armyc2/c5isr/graphics2d/TexturePaint.ts +25 -0
  83. package/src/main/ts/armyc2/c5isr/renderer/IIconRenderer.ts +15 -0
  84. package/src/main/ts/armyc2/c5isr/renderer/IconRenderer.ts +22 -0
  85. package/src/main/ts/armyc2/c5isr/renderer/MilStdIconRenderer.ts +269 -0
  86. package/src/main/ts/armyc2/c5isr/renderer/ModifierRenderer.ts +9882 -0
  87. package/src/main/ts/armyc2/c5isr/renderer/PatternFillRenderer.ts +146 -0
  88. package/src/main/ts/armyc2/c5isr/renderer/SinglePointSVGRenderer.ts +1265 -0
  89. package/src/main/ts/armyc2/c5isr/renderer/shapes/arc.ts +64 -0
  90. package/src/main/ts/armyc2/c5isr/renderer/shapes/bcurve.ts +95 -0
  91. package/src/main/ts/armyc2/c5isr/renderer/shapes/ellipse.ts +93 -0
  92. package/src/main/ts/armyc2/c5isr/renderer/shapes/line.ts +114 -0
  93. package/src/main/ts/armyc2/c5isr/renderer/shapes/path.ts +555 -0
  94. package/src/main/ts/armyc2/c5isr/renderer/shapes/pathiterator.ts +62 -0
  95. package/src/main/ts/armyc2/c5isr/renderer/shapes/point.ts +120 -0
  96. package/src/main/ts/armyc2/c5isr/renderer/shapes/rectangle.ts +431 -0
  97. package/src/main/ts/armyc2/c5isr/renderer/shapes/roundedrectangle.ts +99 -0
  98. package/src/main/ts/armyc2/c5isr/renderer/shapes/types.ts +25 -0
  99. package/src/main/ts/armyc2/c5isr/renderer/shapes/utilities.ts +203 -0
  100. package/src/main/ts/armyc2/c5isr/renderer/utilities/AffiliationColors.ts +104 -0
  101. package/src/main/ts/armyc2/c5isr/renderer/utilities/Color.ts +481 -0
  102. package/src/main/ts/armyc2/c5isr/renderer/utilities/DistanceUnit.ts +40 -0
  103. package/src/main/ts/armyc2/c5isr/renderer/utilities/DrawRules.ts +1323 -0
  104. package/src/main/ts/armyc2/c5isr/renderer/utilities/EntityCode.ts +51 -0
  105. package/src/main/ts/armyc2/c5isr/renderer/utilities/ErrorLogger.ts +736 -0
  106. package/src/main/ts/armyc2/c5isr/renderer/utilities/GENCLookup.ts +106 -0
  107. package/src/main/ts/armyc2/c5isr/renderer/utilities/GeoPixelConversion3D.ts +84 -0
  108. package/src/main/ts/armyc2/c5isr/renderer/utilities/IMultiPointRenderer.ts +87 -0
  109. package/src/main/ts/armyc2/c5isr/renderer/utilities/IPointConversion.ts +34 -0
  110. package/src/main/ts/armyc2/c5isr/renderer/utilities/ImageInfo.ts +324 -0
  111. package/src/main/ts/armyc2/c5isr/renderer/utilities/LRUCache.ts +127 -0
  112. package/src/main/ts/armyc2/c5isr/renderer/utilities/LRUEntry.ts +18 -0
  113. package/src/main/ts/armyc2/c5isr/renderer/utilities/LogLevel.ts +111 -0
  114. package/src/main/ts/armyc2/c5isr/renderer/utilities/MODrawRules.ts +219 -0
  115. package/src/main/ts/armyc2/c5isr/renderer/utilities/MSInfo.ts +1008 -0
  116. package/src/main/ts/armyc2/c5isr/renderer/utilities/MSLookup.ts +882 -0
  117. package/src/main/ts/armyc2/c5isr/renderer/utilities/MilStdAttributes.ts +380 -0
  118. package/src/main/ts/armyc2/c5isr/renderer/utilities/MilStdSymbol.ts +797 -0
  119. package/src/main/ts/armyc2/c5isr/renderer/utilities/Modifiers.ts +1699 -0
  120. package/src/main/ts/armyc2/c5isr/renderer/utilities/PointConversion.ts +178 -0
  121. package/src/main/ts/armyc2/c5isr/renderer/utilities/PointConversionDummy.ts +45 -0
  122. package/src/main/ts/armyc2/c5isr/renderer/utilities/PointConverter3D.ts +126 -0
  123. package/src/main/ts/armyc2/c5isr/renderer/utilities/RectUtilities.ts +118 -0
  124. package/src/main/ts/armyc2/c5isr/renderer/utilities/RendererException.ts +11 -0
  125. package/src/main/ts/armyc2/c5isr/renderer/utilities/RendererSettings.ts +1201 -0
  126. package/src/main/ts/armyc2/c5isr/renderer/utilities/RendererUtilities.ts +591 -0
  127. package/src/main/ts/armyc2/c5isr/renderer/utilities/SVGInfo.ts +29 -0
  128. package/src/main/ts/armyc2/c5isr/renderer/utilities/SVGLookup.ts +753 -0
  129. package/src/main/ts/armyc2/c5isr/renderer/utilities/SVGSymbolInfo.ts +137 -0
  130. package/src/main/ts/armyc2/c5isr/renderer/utilities/SVGTextInfo.ts +438 -0
  131. package/src/main/ts/armyc2/c5isr/renderer/utilities/SettingsChangedEvent.ts +19 -0
  132. package/src/main/ts/armyc2/c5isr/renderer/utilities/SettingsChangedEventListener.ts +10 -0
  133. package/src/main/ts/armyc2/c5isr/renderer/utilities/SettingsEventListener.ts +5 -0
  134. package/src/main/ts/armyc2/c5isr/renderer/utilities/Shape2SVG.ts +404 -0
  135. package/src/main/ts/armyc2/c5isr/renderer/utilities/ShapeInfo.ts +525 -0
  136. package/src/main/ts/armyc2/c5isr/renderer/utilities/ShapeUtilities.ts +55 -0
  137. package/src/main/ts/armyc2/c5isr/renderer/utilities/SymbolDimensionInfo.ts +36 -0
  138. package/src/main/ts/armyc2/c5isr/renderer/utilities/SymbolID.ts +1055 -0
  139. package/src/main/ts/armyc2/c5isr/renderer/utilities/SymbolUtilities.ts +2085 -0
  140. package/src/main/ts/armyc2/c5isr/renderer/utilities/TextInfo.ts +157 -0
  141. package/src/main/ts/armyc2/c5isr/web/render/GeoPixelConversion.ts +86 -0
  142. package/src/main/ts/armyc2/c5isr/web/render/MultiPointHandler.ts +3798 -0
  143. package/src/main/ts/armyc2/c5isr/web/render/MultiPointHandlerSVG.ts +412 -0
  144. package/src/main/ts/armyc2/c5isr/web/render/PointConverter.ts +124 -0
  145. package/src/main/ts/armyc2/c5isr/web/render/SymbolModifiers.ts +26 -0
  146. package/src/main/ts/armyc2/c5isr/web/render/WebRenderer.ts +677 -0
  147. package/src/main/ts/armyc2/c5isr/web/render/utilities/JavaRendererUtilities.ts +484 -0
  148. package/src/main/ts/armyc2/c5isr/web/render/utilities/LineInfo.ts +62 -0
  149. package/src/main/ts/armyc2/c5isr/web/render/utilities/SymbolInfo.ts +46 -0
  150. package/src/main/ts/armyc2/c5isr/web/render/utilities/TextInfo.ts +51 -0
  151. package/src/main/ts/org/gavaghan/geodesy/Angle.ts +31 -0
  152. package/src/main/ts/org/gavaghan/geodesy/Ellipsoid.ts +71 -0
  153. package/src/main/ts/org/gavaghan/geodesy/GeodeticCalculator.ts +200 -0
  154. package/src/main/ts/org/gavaghan/geodesy/GeodeticCurve.ts +55 -0
  155. package/src/main/ts/org/gavaghan/geodesy/GeodeticMeasurement.ts +68 -0
  156. package/src/main/ts/org/gavaghan/geodesy/GlobalCoordinates.ts +103 -0
  157. package/src/main/ts/org/gavaghan/geodesy/GlobalPosition.ts +90 -0
  158. package/test/ExportSPImages.js +692 -0
  159. package/test/MPWW.html +556 -0
  160. package/test/MPWorker.js +318 -0
  161. package/test/SPWorker.js +233 -0
  162. package/test/SVGWW.html +363 -0
  163. package/test/singlePointTester3.html +751 -0
  164. package/tsconfig.json +54 -0
  165. package/typedoc.json +30 -0
  166. package/updateVersion.js +21 -0
  167. package/webpack.config.js +34 -0
  168. package/webpackn.config.js +28 -0
  169. package/webpackr.config.js +47 -0
  170. package/webpackw.config.js +23 -0
@@ -0,0 +1,591 @@
1
+ import { type float, type int } from "../../graphics2d/BasicTypes";
2
+
3
+ import { Color } from "../../renderer/utilities/Color"
4
+ import { ErrorLogger } from "../../renderer/utilities/ErrorLogger"
5
+ import { RendererSettings } from "../../renderer/utilities/RendererSettings"
6
+ import { SVGLookup } from "../../renderer/utilities/SVGLookup"
7
+ import { SymbolID } from "../../renderer/utilities/SymbolID"
8
+ import { SymbolUtilities } from "../../renderer/utilities/SymbolUtilities"
9
+ import { LogLevel } from "./LogLevel";
10
+ import { Rectangle2D } from "../../graphics2d/Rectangle2D";
11
+ import { Point2D } from "../../graphics2d/Point2D";
12
+ import { SVGInfo } from "./SVGInfo";
13
+
14
+
15
+ export class RendererUtilities {
16
+
17
+ private static readonly OUTLINE_SCALING_FACTOR: float = 2.5;
18
+
19
+ public static async imgToBase64String(img: OffscreenCanvas | any): Promise<string>
20
+ {
21
+
22
+ let ctx:OffscreenCanvasRenderingContext2D | any = img.getContext("2d");
23
+ let blob:Blob = await img.convertToBlob();
24
+ //const dataURL:any = new FileReaderSync().readAsDataURL(blob);//FileReaderSync() for web workers only
25
+ const dataURL:any = new FileReader().readAsDataURL(blob);
26
+ let strDataURL:String = new String(dataURL);
27
+ return strDataURL.toString();
28
+
29
+ }
30
+ private static pastIdealOutlineColors: Map<number, Color> = new Map<number, Color>();
31
+ /**
32
+ *
33
+ * @param color {String} color like "#FFFFFF"
34
+ * @return {String}
35
+ */
36
+ public static getIdealOutlineColor(color: Color): Color {
37
+ let idealColor: Color = Color.white;
38
+
39
+ if (color != null && RendererUtilities.pastIdealOutlineColors.has(color.toInt())) {
40
+ return RendererUtilities.pastIdealOutlineColors.get(color.toInt());
41
+ }//*/
42
+
43
+ if (color != null) {
44
+ let threshold: int = RendererSettings.getInstance().getTextBackgroundAutoColorThreshold();
45
+
46
+ let r: int = color.getRed();
47
+ let g: int = color.getGreen();
48
+ let b: int = color.getBlue();
49
+
50
+ let delta: float = ((r * 0.299) + (g * 0.587) + (b * 0.114));
51
+
52
+ if ((255 - delta < threshold)) {
53
+ idealColor = Color.black;
54
+ }
55
+ else {
56
+ idealColor = Color.white;
57
+ }
58
+ }
59
+
60
+ if (color != null) {
61
+ RendererUtilities.pastIdealOutlineColors.set(color.toInt(), idealColor);
62
+ }
63
+
64
+
65
+ return idealColor;
66
+ }
67
+
68
+ /**
69
+ * Create a copy of the {@Color} object with the passed alpha value.
70
+ * @param color {@Color} object used for RGB values
71
+ * @param alpha {@float} value between 0 and 1
72
+ * @return
73
+ */
74
+ public static setColorAlpha(color: Color, alpha: float): Color {
75
+ if (color != null) {
76
+ if (alpha >= 0 && alpha <= 1) {
77
+
78
+ return new Color(color.getRed(), color.getGreen(), color.getBlue(), Math.trunc(alpha * 255));
79
+ }
80
+
81
+ else {
82
+
83
+ return color;
84
+ }
85
+
86
+ }
87
+ else {
88
+
89
+ return null;
90
+ }
91
+
92
+ }
93
+
94
+ /**
95
+ *
96
+ * @param color
97
+ * @return 8 character hex code, will have to prepend '#' or '0x' depending on your usage
98
+ */
99
+ private static ColorToHex(color: Color): string {
100
+ //String hex = String.format("#%02x%02x%02x%02x", color.getAlpha(), color.getRed(), color.getGreen(), color.getBlue());
101
+ let hex: string = color.getAlpha().toString(16).padStart(2, '0') + color.getRed().toString(16).padStart(2, '0') + color.getGreen().toString(16).padStart(2, '0') + color.getBlue().toString(16).padStart(2, '0')
102
+ return hex;
103
+ }
104
+
105
+ /**
106
+ *
107
+ * @param color
108
+ * @param withAlpha
109
+ * @return
110
+ */
111
+ public static colorToHexString(color: Color, withAlpha: boolean): string {
112
+ if (color != null) {
113
+ return color.toHexString(withAlpha)
114
+ } else {
115
+ return "";
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Clients should use getTextBounds
121
+ * @param {String} fontName like "Arial" or "Arial, sans-serif" so a backup is
122
+ * available in case 'Arial' is not present.
123
+ * @param {Number} fontSize like 12
124
+ * @param {String} fontStyle like "bold"
125
+ * @param {String} text include if you want a width value.
126
+ * @param {OffscreenCanvasRenderingContext2D}
127
+ * @returns {Object} {width:Number,height:Number,descent:Number,fullHeight:Number}
128
+ */
129
+ public static measureText(fontName:string, fontSize:int, fontStyle:string, text:string,context:OffscreenCanvasRenderingContext2D | any | null):Rectangle2D;
130
+ public static measureText(font:string, text:string,context:OffscreenCanvasRenderingContext2D | any | null):Rectangle2D;
131
+ public static measureText(text:string,context:OffscreenCanvasRenderingContext2D | any):Rectangle2D;
132
+ public static measureText(...args: unknown[])
133
+ {
134
+ let bounds:Rectangle2D;
135
+ switch (args.length)
136
+ {
137
+ case 2: //assumes font already set to context
138
+ {
139
+ const [text, context] = args as [string, OffscreenCanvasRenderingContext2D];
140
+ if (arguments.length === 4)
141
+ {
142
+ let tm:TextMetrics = context.measureText(text);
143
+ let top:number = tm.fontBoundingBoxAscent-1;
144
+ let left = -1;
145
+ //let bottom:number = tm.fontBoundingBoxDescent;
146
+ let width = tm.width+2;
147
+ width = tm.actualBoundingBoxRight + tm.actualBoundingBoxLeft;
148
+ let height:number = tm.fontBoundingBoxDescent + tm.fontBoundingBoxAscent+2;
149
+ bounds = new Rectangle2D(top, left, width, height);
150
+ }
151
+ break;
152
+ }
153
+ case 3: //sets font to context
154
+ {
155
+ const [font, text, context] = args as [string, string, OffscreenCanvasRenderingContext2D];
156
+ if (arguments.length === 3)
157
+ {
158
+ let ctx:OffscreenCanvasRenderingContext2D
159
+ var size:Rectangle2D;
160
+ if(context == null)
161
+ {
162
+ let osc:OffscreenCanvas = new OffscreenCanvas(10,10);
163
+ ctx = osc.getContext("2d");
164
+ ctx.font = font;
165
+
166
+ bounds = this.measureText(text, ctx);
167
+ }
168
+ else
169
+ bounds = this.measureText(text, context);
170
+ }
171
+ break;
172
+ }
173
+ case 5: //sets font to context
174
+ {
175
+ const [fontName, fontSize, fontStyle, text, context] = args as [string, number, string, string, OffscreenCanvasRenderingContext2D];
176
+ if (arguments.length === 5)
177
+ {
178
+ let font:string = fontStyle + " " + fontSize + "px " + fontName;
179
+ let ctx:OffscreenCanvasRenderingContext2D
180
+ var size:Rectangle2D;
181
+ if(context == null)
182
+ {
183
+ let osc:OffscreenCanvas = new OffscreenCanvas(10,10);
184
+ ctx = osc.getContext("2d");
185
+ ctx.font = font;
186
+
187
+ bounds = this.measureText(text, ctx);
188
+ }
189
+ else
190
+ bounds = this.measureText(text, context);
191
+ }
192
+ break;
193
+ }
194
+ }
195
+ return bounds;
196
+ }
197
+
198
+ /**
199
+ *
200
+ * @param hexValue - String representing hex value (formatted "0xRRGGBB"
201
+ * i.e. "0xFFFFFF") OR formatted "0xAARRGGBB" i.e. "0x00FFFFFF" for a color
202
+ * with an alpha value I will also put up with "RRGGBB" and "AARRGGBB"
203
+ * without the starting "0x" or "#"
204
+ * @return
205
+ */
206
+ public static getColorFromHexString(hexValue: string): Color | null {
207
+
208
+ try {
209
+ if (hexValue == null || hexValue.length === 0) {
210
+
211
+ return null;
212
+ }
213
+
214
+ let hexOriginal: string = hexValue;
215
+
216
+ let hexAlphabet: string = "0123456789ABCDEF";
217
+
218
+ if (hexValue.charAt(0) === '#') {
219
+ hexValue = hexValue.substring(1);
220
+ }
221
+ if (hexValue.substring(0, 2) === "0x" || hexValue.substring(0, 2) === "0X") {
222
+ hexValue = hexValue.substring(2);
223
+ }
224
+
225
+ hexValue = hexValue.toUpperCase();
226
+
227
+ let count: int = hexValue.length;
228
+ let value: number[];
229
+ let k: int = 0;
230
+ let int1: int = 0;
231
+ let int2: int = 0;
232
+
233
+ if (count === 8 || count === 6) {
234
+ value = new Array<number>((count / 2));
235
+ for (let i: int = 0; i < count; i += 2) {
236
+ int1 = hexAlphabet.indexOf(hexValue.charAt(i));
237
+ int2 = hexAlphabet.indexOf(hexValue.charAt(i + 1));
238
+
239
+ if (int1 === -1 || int2 === -1) {
240
+ ErrorLogger.LogMessage("SymbolUtilities", "getColorFromHexString", "Bad hex value: " + hexOriginal, LogLevel.WARNING);
241
+ return null;
242
+ }
243
+
244
+ value[k] = (int1 * 16) + int2;
245
+ k++;
246
+ }
247
+
248
+ if (count === 8) {
249
+ return new Color(value[1], value[2], value[3], value[0]);
250
+ }
251
+ else {
252
+ return new Color(value[0], value[1], value[2]);
253
+ }
254
+ }
255
+ else {
256
+ ErrorLogger.LogMessage("RendererUtilities", "getColorFromHexString", "Bad hex value: " + hexOriginal, LogLevel.WARNING);
257
+ }
258
+ return null;
259
+ } catch (exc) {
260
+ if (exc instanceof Error) {
261
+ ErrorLogger.LogException("RendererUtilities", "getColorFromHexString", exc);
262
+ return null;
263
+ } else {
264
+ throw exc;
265
+ }
266
+ }
267
+ }
268
+
269
+ /**
270
+ * For Renderer Use Only
271
+ * Assumes a fresh SVG String from the SVGLookup with its default values
272
+ * @param symbolID
273
+ * @param svg
274
+ * @param strokeColor hex value like "#FF0000";
275
+ * @param fillColor hex value like "#FF0000";
276
+ * @return SVG String
277
+ */
278
+ public static setSVGFrameColors(symbolID: string, svg: string, strokeColor: Color, fillColor: Color): string {
279
+ let returnSVG: string;
280
+ let hexStrokeColor: string;
281
+ let hexFillColor: string;
282
+ let strokeAlpha: float = 1;
283
+ let fillAlpha: float = 1;
284
+ let strokeOpacity: string = "";
285
+ let fillOpacity: string = "";
286
+
287
+ let ss: int = SymbolID.getSymbolSet(symbolID);
288
+
289
+ let affiliation: int = SymbolID.getAffiliation(symbolID);
290
+ let defaultFillColor: string;
291
+ if (strokeColor != null) {
292
+ if (strokeColor.getAlpha() !== 255) {
293
+ strokeAlpha = strokeColor.getAlpha() / 255.0;
294
+ strokeOpacity = " stroke-opacity=\"" + strokeAlpha.toString() + "\"";
295
+ fillOpacity = " fill-opacity=\"" + strokeAlpha.toString() + "\"";
296
+ }
297
+
298
+ hexStrokeColor = RendererUtilities.colorToHexString(strokeColor, false);
299
+ returnSVG = svg.replaceAll("stroke=\"#000000\"", "stroke=\"" + hexStrokeColor + "\"" + strokeOpacity);
300
+ returnSVG = returnSVG.replaceAll("fill=\"#000000\"", "fill=\"" + hexStrokeColor + "\"" + fillOpacity);
301
+
302
+ if (ss === SymbolID.SymbolSet_LandInstallation ||
303
+ ss === SymbolID.SymbolSet_Space ||
304
+ ss === SymbolID.SymbolSet_CyberSpace ||
305
+ ss === SymbolID.SymbolSet_Activities) {//add group fill so the extra shapes in these frames have the new frame color
306
+ let svgStart: string = "<g id=\"" + SVGLookup.getFrameID(symbolID) + "\">";
307
+ let svgStartReplace: string = svgStart.substring(0, svgStart.length - 1) + " fill=\"" + hexStrokeColor + "\"" + fillOpacity + ">";
308
+ returnSVG = returnSVG.replace(svgStart, svgStartReplace);
309
+ }
310
+
311
+ }
312
+ if (fillColor != null) {
313
+ if (fillColor.getAlpha() !== 255) {
314
+ fillAlpha = fillColor.getAlpha() / 255.0;
315
+ fillOpacity = " fill-opacity=\"" + fillAlpha.toString() + "\"";
316
+ }
317
+
318
+ hexFillColor = RendererUtilities.colorToHexString(fillColor, false);
319
+ switch (affiliation) {
320
+ case SymbolID.StandardIdentity_Affiliation_Friend:
321
+ case SymbolID.StandardIdentity_Affiliation_AssumedFriend: {
322
+ defaultFillColor = "fill=\"#80E0FF\"";//friendly frame fill
323
+ break;
324
+ }
325
+
326
+ case SymbolID.StandardIdentity_Affiliation_Hostile_Faker: {
327
+ defaultFillColor = "fill=\"#FF8080\"";//hostile frame fill
328
+ break;
329
+ }
330
+
331
+ case SymbolID.StandardIdentity_Affiliation_Suspect_Joker: {
332
+ if (SymbolID.getVersion(symbolID) >= SymbolID.Version_2525E) {
333
+
334
+ defaultFillColor = "fill=\"#FFE599\"";
335
+ }
336
+ //suspect frame fill
337
+ else {
338
+
339
+ defaultFillColor = "fill=\"#FF8080\"";
340
+ }
341
+ //hostile frame fill
342
+ break;
343
+ }
344
+
345
+ case SymbolID.StandardIdentity_Affiliation_Unknown:
346
+ case SymbolID.StandardIdentity_Affiliation_Pending: {
347
+ defaultFillColor = "fill=\"#FFFF80\"";//unknown frame fill
348
+ break;
349
+ }
350
+
351
+ case SymbolID.StandardIdentity_Affiliation_Neutral: {
352
+ defaultFillColor = "fill=\"#AAFFAA\"";//neutral frame fill
353
+ break;
354
+ }
355
+
356
+ default: {
357
+ defaultFillColor = "fill=\"#80E0FF\"";//friendly frame fill
358
+ break;
359
+ }
360
+
361
+ }
362
+
363
+ if (returnSVG == null) {
364
+ returnSVG = svg.replace(defaultFillColor, "fill=\"" + hexFillColor + "\"" + fillOpacity);
365
+ }
366
+ else {
367
+ returnSVG = returnSVG.replace(defaultFillColor, "fill=\"" + hexFillColor + "\"" + fillOpacity);
368
+ }
369
+
370
+ }
371
+
372
+ if (returnSVG != null) {
373
+ return returnSVG;
374
+ }
375
+
376
+ else {
377
+
378
+ return svg;
379
+ }
380
+
381
+ }
382
+
383
+ // Overloaded method to return non-outline symbols as normal.
384
+ public static setSVGSPCMColors(symbolID: string, svg: string, strokeColor: Color, fillColor: Color): string;
385
+
386
+ /**
387
+ * For Renderer Use Only
388
+ * Changes colors for single point control measures
389
+ * @param symbolID
390
+ * @param svg
391
+ * @param strokeColor hex value like "#FF0000";
392
+ * @param fillColor hex value like "#FF0000";
393
+ * @param isOutline true if this represents a thicker outline to render first beneath the normal symbol (the function must be called twice)
394
+ * @return SVG String
395
+ *
396
+ */
397
+ public static setSVGSPCMColors(symbolID: string, svg: string, strokeColor: Color, fillColor: Color, isOutline: boolean): string;
398
+ public static setSVGSPCMColors(...args: unknown[]): string {
399
+ switch (args.length) {
400
+ case 4: {
401
+ const [symbolID, svg, strokeColor, fillColor] = args as [string, string, Color, Color];
402
+
403
+
404
+ return RendererUtilities.setSVGSPCMColors(symbolID, svg, strokeColor, fillColor, false);
405
+
406
+
407
+ break;
408
+ }
409
+
410
+ case 5: {
411
+ let [symbolID, svg, strokeColor, fillColor, isOutline] = args as [string, string, Color, Color, boolean];
412
+
413
+ let returnSVG: string = svg;
414
+ let hexStrokeColor: string;
415
+ let hexFillColor: string;
416
+ let strokeAlpha: float = 1;
417
+ let fillAlpha: float = 1;
418
+ let strokeOpacity: string = "";
419
+ let fillOpacity: string = "";
420
+ let strokeCapSquare: string = " stroke-linecap=\"square\"";
421
+ let strokeCapButt: string = " stroke-linecap=\"butt\"";
422
+ let strokeCapRound: string = " stroke-linecap=\"round\"";
423
+
424
+ let affiliation: int = SymbolID.getAffiliation(symbolID);
425
+ let defaultFillColor: string;
426
+ if (strokeColor != null) {
427
+ if (strokeColor.getAlpha() !== 255) {
428
+ strokeAlpha = strokeColor.getAlpha() / 255.0;
429
+ strokeOpacity = " stroke-opacity=\"" + strokeAlpha + "\"";
430
+ fillOpacity = " fill-opacity=\"" + strokeAlpha + "\"";
431
+ }
432
+
433
+ hexStrokeColor = RendererUtilities.colorToHexString(strokeColor, false);
434
+ let defaultStrokeColor: string = "#000000";
435
+ if (symbolID.length === 5) {
436
+ let mod: int = parseInt(symbolID.substring(2, 4));
437
+ if (mod >= 13) {
438
+
439
+ defaultStrokeColor = "#00A651";
440
+ }
441
+
442
+
443
+ }
444
+ //key terrain
445
+ if (symbolID.length >= 20 &&
446
+ SymbolUtilities.getBasicSymbolID(symbolID) === "25132100" &&
447
+ SymbolID.getVersion(symbolID) >= SymbolID.Version_2525E) {
448
+ defaultStrokeColor = "#800080";
449
+ }
450
+ returnSVG = returnSVG.replaceAll("stroke=\"" + defaultStrokeColor + "\"", "stroke=\"" + hexStrokeColor + "\"" + strokeOpacity);
451
+ returnSVG = returnSVG.replaceAll("fill=\"" + defaultStrokeColor + "\"", "fill=\"" + hexStrokeColor + "\"" + fillOpacity);
452
+ }
453
+ else {
454
+ strokeColor = Color.BLACK;
455
+ }
456
+
457
+ if (isOutline) {
458
+ // Capture and scale stroke-widths to create outlines. Note that some stroke-widths are not integral numbers.
459
+ let pattern = RegExp("(stroke-width=\")(\\d+\\.?\\d*)\"", "g");
460
+ let matches = [...returnSVG.matchAll(pattern)]
461
+ let strokeWidths: Set<number> = new Set();
462
+ for (let match of matches) {
463
+ // match is ["stroke-width="n"", "stroke-width="", "n"]
464
+ strokeWidths.add(parseFloat(match[2]));
465
+ }
466
+ // replace stroke width values in SVG from greatest to least to avoid unintended replacements
467
+ for (let f of Array.from(strokeWidths).sort((a, b) => b - a)) {
468
+ let replacement: string = "stroke-width=\"" + (f * RendererUtilities.OUTLINE_SCALING_FACTOR) + "\"";
469
+ returnSVG = returnSVG.replaceAll("stroke-width=\"" + f + "\"", replacement);
470
+ }
471
+
472
+ // add stroke-width and stroke (color) to all groups
473
+ let replacement: string = "<g" + strokeCapSquare + " stroke-width=\"" + (2.5 * RendererUtilities.OUTLINE_SCALING_FACTOR) + "\" stroke=\"#" + RendererUtilities.ColorToHex(strokeColor).substring(2) + "\" ";
474
+ returnSVG = returnSVG.replaceAll("<g", replacement);
475
+ }
476
+ else {
477
+ /* //this code just returned the entire svg string back. Maybe because there's no line breaks.
478
+ Pattern pattern = Pattern.compile("(font-size=\"\\d+\\.?\\d*)\"");
479
+ Matcher m = pattern.matcher(svg);
480
+ TreeSet<String> fontStrings = new TreeSet<>();
481
+ while (m.find()) {
482
+ fontStrings.push(m.group(0));
483
+ }
484
+ for (String target : fontStrings) {
485
+ String replacement = target + " fill=\"#" + ColorToHex(strokeColor).substring(2) + "\" ";
486
+ returnSVG = returnSVG.replace(target, replacement);
487
+ }
488
+ //*/
489
+ let replacement: string = " fill=\"#" + RendererUtilities.ColorToHex(strokeColor).substring(2) + "\" ";
490
+ returnSVG = returnSVG.replace("fill=\"#000000\"", replacement);//only replace black fills, leave white fills alone.
491
+
492
+ //In case there are lines that don't have stroke defined, apply stroke color to the top level group.
493
+ let topGroupTag: string = "<g id=\"" + SymbolUtilities.getBasicSymbolID(symbolID) + "\">";//<g id="25212902">
494
+ let newGroupTag: string = "<g id=\"" + SymbolUtilities.getBasicSymbolID(symbolID) + "\" stroke=\"" + hexStrokeColor + "\"" + strokeOpacity + " " + replacement + ">";
495
+ returnSVG = returnSVG.replace(topGroupTag, newGroupTag);
496
+
497
+ }
498
+
499
+ if (fillColor != null) {
500
+ if (fillColor.getAlpha() !== 255) {
501
+ fillAlpha = fillColor.getAlpha() / 255.0;
502
+ fillOpacity = " fill-opacity=\"" + fillAlpha + "\"";
503
+ }
504
+
505
+ hexFillColor = RendererUtilities.colorToHexString(fillColor, false);
506
+ defaultFillColor = "fill=\"#000000\"";
507
+
508
+ returnSVG = returnSVG.replaceAll(defaultFillColor, "fill=\"" + hexFillColor + "\"" + fillOpacity);
509
+ }
510
+
511
+ return returnSVG;
512
+ }
513
+
514
+ default: {
515
+ throw Error(`Invalid number of arguments`);
516
+ }
517
+ }
518
+ }
519
+
520
+
521
+ public static findWidestStrokeWidth(svg: string): float {
522
+ let pattern = RegExp("(stroke-width=\")(\\d+\\.?\\d*)\"", "g");
523
+ let largest: number = 4.0;
524
+
525
+ let matches = [...svg.matchAll(pattern)]
526
+ for (let match of matches) {
527
+ // match is ["stroke-width="n"", "stroke-width="", "n"]
528
+ const width = parseFloat(match[2])
529
+ if (width > largest) {
530
+ largest = width;
531
+ }
532
+ }
533
+ return largest * RendererUtilities.OUTLINE_SCALING_FACTOR;
534
+ }
535
+
536
+ public static getDistanceBetweenPoints(pt1:Point2D, pt2:Point2D):int
537
+ {
538
+ let distance:int = (Math.sqrt(Math.pow((pt2.getX() - pt1.getX()) ,2) + Math.pow((pt2.getY() - pt1.getY()) ,2))) as int;
539
+ return distance;
540
+ }
541
+
542
+ public static scaleIcon(symbolID:string, icon:SVGInfo):SVGInfo
543
+ {
544
+ let retVal:SVGInfo = icon;
545
+ //safe square inside octagon: <rect x="220" y="310" width="170" height="170"/>
546
+ let maxSize:number = 170;
547
+ let bbox = null;
548
+ if(icon !== null)
549
+ bbox = icon.getBbox();
550
+ let length:number = 0;
551
+ if(bbox != null)
552
+ length = Math.max(bbox.getWidth(),bbox.getHeight());
553
+ if(length < 100 && length > 0 &&
554
+ SymbolID.getCommonModifier1(symbolID)==0 &&
555
+ SymbolID.getCommonModifier2(symbolID)==0 &&
556
+ SymbolID.getModifier1(symbolID)==0 &&
557
+ SymbolID.getModifier2(symbolID)==0)//if largest side smaller than 100 and there are no section mods, make it bigger
558
+ {
559
+ let ratio:number = maxSize / length;
560
+ let transx:number = ((bbox.getX() + (bbox.getWidth()/2)) * ratio) - (bbox.getX() + (bbox.getWidth()/2));
561
+ let transy:number = ((bbox.getY() + (bbox.getHeight()/2)) * ratio) - (bbox.getY() + (bbox.getHeight()/2));
562
+ let transform:string = " transform=\"translate(-" + transx + ",-" + transy + ") scale(" + ratio + " " + ratio + ")\">";
563
+ let svg:string = icon.getSVG();
564
+ svg = svg.replace(">",transform);
565
+ let newBbox:Rectangle2D = new Rectangle2D(bbox.getX() - transx,bbox.getY() - transy,bbox.getWidth() * ratio, bbox.getHeight() * ratio);
566
+ retVal = new SVGInfo(icon.getID(),newBbox,svg);
567
+ }
568
+ return retVal;
569
+ }
570
+
571
+
572
+ public static async getData(path:string):Promise<any> {
573
+ const url = path;
574
+ try {
575
+ const response = await fetch(url);
576
+ if (!response.ok) {
577
+ throw new Error(`Response status: ${response.status}`);
578
+ }
579
+
580
+ const json = await response.json();
581
+ //console.log(json);
582
+ return json;
583
+ } catch (error)
584
+ {
585
+ if(console)
586
+ console.error(error.message);
587
+ else
588
+ throw error;
589
+ }
590
+ }
591
+ }
@@ -0,0 +1,29 @@
1
+
2
+ import { Rectangle2D } from "../../graphics2d/Rectangle2D"
3
+
4
+ export class SVGInfo {
5
+ private _ID: string;
6
+ private _Bbox: Rectangle2D;
7
+ private _SVG: string;
8
+ public constructor(id: string, measurements: Rectangle2D, svg: string) {
9
+ this._ID = id;
10
+ this._Bbox = measurements;
11
+ this._SVG = svg;
12
+ }
13
+
14
+ public getID(): string {
15
+ return this._ID;
16
+ }
17
+
18
+ public getBbox(): Rectangle2D {
19
+ return this._Bbox;
20
+ }
21
+
22
+ public getSVG(): string {
23
+ return this._SVG;
24
+ }
25
+
26
+ public toString(): string {
27
+ return this._ID + "\n" + this._Bbox.toString() + "\n" + this._SVG;
28
+ }
29
+ }